279 lines
12 KiB
C#
279 lines
12 KiB
C#
using Adaptation.Shared;
|
|
using Adaptation.Shared.Methods;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace Adaptation.FileHandlers.RsM
|
|
{
|
|
|
|
public class ProcessData : IProcessData
|
|
{
|
|
|
|
private readonly List<object> _Details;
|
|
|
|
public string JobID { get; set; }
|
|
public string MesEntity { get; set; }
|
|
public string AutoOptimizeGain { get; set; }
|
|
public string AutoProbeHeightSet { get; set; }
|
|
public string Avg { get; set; }
|
|
public string DLRatio { get; set; }
|
|
public string DataReject { get; set; }
|
|
public string Date { get; set; }
|
|
public DateTime DateTime { get; set; }
|
|
public string Employee { get; set; }
|
|
public string EquipId { get; set; }
|
|
public string Engineer { get; set; }
|
|
public string FileName { get; set; }
|
|
public string Layer { get; set; }
|
|
public string Lot { get; set; }
|
|
public string LogBody { get; set; }
|
|
public string PSN { get; set; }
|
|
public string Project { get; set; }
|
|
public string RDS { get; set; }
|
|
public string Reactor { get; set; }
|
|
public string Recipe { get; set; }
|
|
public string RecipeName { get; set; }
|
|
public string ResistivitySpec { get; set; }
|
|
public string Run { get; set; }
|
|
public string SemiRadial { get; set; }
|
|
public string StandardDeviation { get; set; }
|
|
public string StandardDeviationPercentage { get; set; }
|
|
public string Temp { get; set; }
|
|
public string Title { get; set; }
|
|
public string UniqueId { get; set; }
|
|
public string Zone { get; set; }
|
|
|
|
List<object> Shared.Properties.IProcessData.Details => _Details;
|
|
|
|
public ProcessData(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection)
|
|
{
|
|
JobID = logistics.JobID;
|
|
fileInfoCollection.Clear();
|
|
_Details = new List<object>();
|
|
MesEntity = logistics.MesEntity;
|
|
Parse(fileRead, logistics, fileInfoCollection);
|
|
}
|
|
|
|
string IProcessData.GetCurrentReactor(IFileRead fileRead, Logistics logistics, Dictionary<string, string> reactors)
|
|
{
|
|
throw new Exception(string.Concat("See ", nameof(Parse)));
|
|
}
|
|
|
|
Tuple<string, Test[], JsonElement[], List<FileInfo>> IProcessData.GetResults(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection)
|
|
{
|
|
Tuple<string, Test[], JsonElement[], List<FileInfo>> results;
|
|
List<Test> tests = new();
|
|
foreach (object item in _Details)
|
|
tests.Add(Test.CDE);
|
|
List<IDescription> descriptions = fileRead.GetDescriptions(fileRead, tests, this);
|
|
if (tests.Count != descriptions.Count)
|
|
throw new Exception();
|
|
for (int i = 0; i < tests.Count; i++)
|
|
{
|
|
if (descriptions[i] is not Description description)
|
|
throw new Exception();
|
|
if (description.Test != (int)tests[i])
|
|
throw new Exception();
|
|
}
|
|
List<Description> fileReadDescriptions = (from l in descriptions select (Description)l).ToList();
|
|
string json = JsonSerializer.Serialize(fileReadDescriptions, fileReadDescriptions.GetType());
|
|
JsonElement[] jsonElements = JsonSerializer.Deserialize<JsonElement[]>(json);
|
|
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(logistics.Logistics1[0], tests.ToArray(), jsonElements, fileInfoCollection);
|
|
return results;
|
|
}
|
|
|
|
private void SetTitleData(string[] segments)
|
|
{
|
|
if (segments.Length > 0)
|
|
{
|
|
Title = segments[0];
|
|
// Remove illegal characters \/:*?"<>| found in the Run.
|
|
Run = Regex.Replace(segments[0], @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]", "_").Split('\r')[0].Split('\n')[0];
|
|
string[] parsedBatch = segments[0].Split('-');
|
|
if (parsedBatch.Length > 0)
|
|
Reactor = parsedBatch[0];
|
|
if (parsedBatch.Length > 1)
|
|
RDS = parsedBatch[1];
|
|
if (parsedBatch.Length > 2)
|
|
{
|
|
string[] parsedPSN = parsedBatch[2].Split('.');
|
|
if (parsedPSN.Length > 0)
|
|
PSN = parsedPSN[0];
|
|
if (parsedPSN.Length > 1)
|
|
Layer = parsedPSN[1];
|
|
}
|
|
if (parsedBatch.Length > 3)
|
|
Zone = parsedBatch[3];
|
|
}
|
|
}
|
|
|
|
private void SetFileNameData(string[] segments)
|
|
{
|
|
if (segments.Length > 1)
|
|
FileName = segments[0];
|
|
if (segments.Length > 2)
|
|
{
|
|
Project = segments[1];
|
|
RecipeName = segments[2];
|
|
Recipe = string.Concat(segments[1], " \\ ", segments[2]);
|
|
}
|
|
}
|
|
|
|
internal static DateTime GetDateTime(Logistics logistics, string dateTimeText)
|
|
{
|
|
DateTime result;
|
|
string inputDateFormat = "HH:mm MM/dd/yy";
|
|
if (dateTimeText.Length != inputDateFormat.Length)
|
|
result = logistics.DateTimeFromSequence;
|
|
else
|
|
{
|
|
if (!DateTime.TryParseExact(dateTimeText, inputDateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime dateTimeParsed))
|
|
result = logistics.DateTimeFromSequence;
|
|
else
|
|
{
|
|
if (dateTimeParsed < logistics.DateTimeFromSequence.AddDays(1) && dateTimeParsed > logistics.DateTimeFromSequence.AddDays(-1))
|
|
result = dateTimeParsed;
|
|
else
|
|
result = logistics.DateTimeFromSequence;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private void SetDateTimeData(Logistics logistics, string[] segments)
|
|
{
|
|
DateTime dateTime;
|
|
if (segments.Length < 2)
|
|
dateTime = logistics.DateTimeFromSequence;
|
|
else
|
|
{
|
|
string dateTimeText = string.Concat(segments[0], ' ', segments[1]);
|
|
dateTime = GetDateTime(logistics, dateTimeText);
|
|
}
|
|
DateTime = dateTime;
|
|
Date = dateTime.ToString();
|
|
if (segments.Length > 3 && float.TryParse(segments[2], out float temp))
|
|
Temp = temp.ToString("0.0");
|
|
if (segments.Length > 7 && segments[6] == "Avg=")
|
|
Avg = segments[7];
|
|
if (segments.Length > 7 && segments[8] == "Dev=")
|
|
StandardDeviation = segments[9];
|
|
if (!string.IsNullOrEmpty(Avg) && !string.IsNullOrEmpty(StandardDeviation) && float.TryParse(Avg, out float average) && float.TryParse(StandardDeviation, out float standardDeviation))
|
|
StandardDeviationPercentage = Math.Round(standardDeviation / average, 4).ToString("0.00%");
|
|
}
|
|
|
|
private void SetOperatorData(string[] segments)
|
|
{
|
|
if (segments.Length > 1)
|
|
Employee = segments[0];
|
|
if (segments.Length > 2)
|
|
EquipId = segments[1];
|
|
}
|
|
|
|
private void SetEngineerData(string[] segments)
|
|
{
|
|
if (segments.Length > 1)
|
|
Engineer = segments[0];
|
|
}
|
|
|
|
private void SetNumProbePointsData(string[] segments)
|
|
{
|
|
if (segments.Length > 6)
|
|
DataReject = segments[6];
|
|
}
|
|
|
|
private Detail GetRData(string[] segments)
|
|
{
|
|
Detail result = new();
|
|
if (segments.Length > 0 && float.TryParse(segments[0], out float r))
|
|
result.R = r.ToString("0.0");
|
|
if (segments.Length > 1 && float.TryParse(segments[1], out float t))
|
|
result.T = t.ToString("0.0");
|
|
if (segments.Length > 2 && float.TryParse(segments[2], out float rs))
|
|
result.Rs = rs.ToString("0.0000");
|
|
if (segments.Length > 12 && float.TryParse(segments[12], out float merit))
|
|
result.Merit = merit.ToString("0.00");
|
|
result.Pt = "-1";
|
|
result.UniqueId = string.Empty;
|
|
return result;
|
|
}
|
|
|
|
private void Parse(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection)
|
|
{
|
|
if (fileRead is null)
|
|
{ }
|
|
Lot = "LotID";
|
|
Detail detail;
|
|
if (fileInfoCollection is null)
|
|
{ }
|
|
string timeFormat = "yyyyMMddHHmmss";
|
|
string[] separator = new string[] { " " };
|
|
string[] lines = File.ReadAllLines(logistics.ReportFullPath);
|
|
for (int i = 0; i < lines.Length; i++)
|
|
{
|
|
if (lines[i].Contains(",<Title>"))
|
|
SetTitleData(lines[i].Split(separator, StringSplitOptions.RemoveEmptyEntries));
|
|
else if (lines[i].Contains(",<FileName, Proj,Rcpe, LotID,WfrID>"))
|
|
SetFileNameData(lines[i].Split(separator, StringSplitOptions.RemoveEmptyEntries));
|
|
else if (lines[i].Contains(",<DateTime,Temp,TCR%,N|P>"))
|
|
SetDateTimeData(logistics, lines[i].Split(separator, StringSplitOptions.RemoveEmptyEntries));
|
|
else if (lines[i].Contains(",<Operator, Epuipment>"))
|
|
SetOperatorData(lines[i].Split(separator, StringSplitOptions.RemoveEmptyEntries));
|
|
else if (lines[i].Contains(",<Engineer>"))
|
|
SetEngineerData(lines[i].Split(separator, StringSplitOptions.RemoveEmptyEntries));
|
|
else if (lines[i].Contains(",<NumProbePoints, SingleOrDualProbeConfig, #ActPrbPts, Rsens,IdrvMx,VinGain, DataRejectSigma, MeritThreshold>"))
|
|
SetNumProbePointsData(lines[i].Split(separator, StringSplitOptions.RemoveEmptyEntries));
|
|
else if (lines[i].Contains(",<R,Th,Data, Rs,RsA,RsB, #Smpl, x,y, Irng,Vrng,ChiSq,merit,DataIntegrity>"))
|
|
{
|
|
for (int z = i; z < lines.Length; z++)
|
|
{
|
|
i = z;
|
|
if (string.IsNullOrEmpty(lines[z]))
|
|
continue;
|
|
detail = GetRData(lines[z].Split(separator, StringSplitOptions.RemoveEmptyEntries));
|
|
_Details.Add(detail);
|
|
}
|
|
}
|
|
}
|
|
UniqueId = string.Concat(EquipId, "_", Run, "_", logistics.DateTimeFromSequence.ToString(timeFormat));
|
|
for (int i = 0; i < _Details.Count; i++)
|
|
{
|
|
if (_Details[i] is not Detail item)
|
|
continue;
|
|
item.HeaderUniqueId = UniqueId;
|
|
item.Pt = (i + 1).ToString();
|
|
item.UniqueId = string.Concat(item, "_Point-", item.Pt);
|
|
}
|
|
// Remove illegal characters \/:*?"<>| found in the Lot.
|
|
Lot = Regex.Replace(Lot, @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]", "_").Split('\r')[0].Split('\n')[0];
|
|
StringBuilder stringBuilder = new();
|
|
string reportFileName = Path.GetFileName(logistics.ReportFullPath);
|
|
stringBuilder.AppendLine($"RUN [{Title}]");
|
|
stringBuilder.AppendLine($"Recipe {Project} \\ {RecipeName} RESISTIVITY {"####"}");
|
|
stringBuilder.AppendLine($"EQUIP# {EquipId} Engineer {Engineer}");
|
|
stringBuilder.AppendLine($"LotID {Lot} D.L.RATIO {"#.####"}");
|
|
stringBuilder.AppendLine($"OPERATOR {Employee} TEMP {Temp} {DateTime:HH:mm MM/dd/yy}");
|
|
stringBuilder.AppendLine($"AutoOptimizeGain = {"###"} AutoProbeHeightSet = {"##"}");
|
|
stringBuilder.AppendLine($"DataReject > {"#.#"}Sigma");
|
|
stringBuilder.AppendLine($"0 ..\\{Project}.prj\\{RecipeName}.rcp\\{reportFileName} {DateTime:HH:mm MM/dd/yy}");
|
|
stringBuilder.AppendLine($"pt# R Th Rs[Ohm/sq@T] Merit");
|
|
for (int i = 0; i < _Details.Count; i++)
|
|
{
|
|
if (_Details[i] is not Detail item)
|
|
continue;
|
|
stringBuilder.AppendLine($"{item.Pt} {item.R} {item.T} {item.Rs} {item.Merit}");
|
|
}
|
|
stringBuilder.AppendLine($"Avg = {Avg} {StandardDeviationPercentage} SEMI Radial= {"#.##%"}");
|
|
LogBody = stringBuilder.ToString();
|
|
}
|
|
|
|
}
|
|
|
|
} |