FlagDuplicates

CA1510
Complete
This commit is contained in:
2024-11-18 16:58:26 -07:00
parent aaefffd3d2
commit 8ff877156d
20 changed files with 726 additions and 100 deletions

View File

@ -0,0 +1,45 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text.Json.Serialization;
namespace Adaptation.FileHandlers.pcl;
#nullable enable
internal class Complete
{
public Complete(Header header, Wafer[] wafers)
{
Header = header;
Wafers = wafers;
}
public Header Header { get; }
public Wafer[] Wafers { get; }
internal static Complete? Get(string headerFileName, Dictionary<string, string> pages, Dictionary<string, List<Detail>> slots, Constant constant)
{
Complete? result;
Header? header = Header.Get(headerFileName, pages, slots, constant);
if (header is null)
result = null;
else
{
ReadOnlyCollection<Wafer> wafers = Wafer.Get(headerFileName, pages, constant);
if (wafers.Count == 0)
result = null;
else
result = new(header, wafers.ToArray());
}
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Complete))]
internal partial class CompleteSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,12 @@
namespace Adaptation.FileHandlers.pcl;
internal class Constant
{
public string Max { get; } = "Max:";
public string Min { get; } = "Min:";
public string Date { get; } = "Date:";
public string StdDev { get; } = "Std Dev:";
public string Average { get; } = "Average:";
}

View File

@ -0,0 +1,297 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Adaptation.FileHandlers.pcl;
#nullable enable
public class Header
{
public Header(string date,
string recipe,
string id,
string lPDCountMin,
string lPDCM2Min,
string areaCountMin,
string areaTotalMin,
string scratchCountMin,
string scratchTotalMin,
string sumOfDefectsMin,
string hazeRegionMin,
string hazeAverageMin,
string lPDCountMax,
string lPDCM2Max,
string areaCountMax,
string areaTotalMax,
string scratchCountMax,
string scratchTotalMax,
string sumOfDefectsMax,
string hazeRegionMax,
string hazeAverageMax,
string lPDCountAvg,
string lPDCM2Avg,
string areaCountAvg,
string areaTotalAvg,
string scratchCountAvg,
string scratchTotalAvg,
string sumOfDefectsAvg,
string hazeRegionAvg,
string hazeAverageAvg,
string lPDCountStdDev,
string lPDCM2StdDev,
string areaCountStdDev,
string areaTotalStdDev,
string scratchCountStdDev,
string scratchTotalStdDev,
string sumOfDefectsStdDev,
string hazeRegionStdDev,
string hazeAverageStdDev)
{
Date = date;
Recipe = recipe;
Id = id;
LPDCountMin = lPDCountMin;
LPDCM2Min = lPDCM2Min;
AreaCountMin = areaCountMin;
AreaTotalMin = areaTotalMin;
ScratchCountMin = scratchCountMin;
ScratchTotalMin = scratchTotalMin;
SumOfDefectsMin = sumOfDefectsMin;
HazeRegionMin = hazeRegionMin;
HazeAverageMin = hazeAverageMin;
LPDCountMax = lPDCountMax;
LPDCM2Max = lPDCM2Max;
AreaCountMax = areaCountMax;
AreaTotalMax = areaTotalMax;
ScratchCountMax = scratchCountMax;
ScratchTotalMax = scratchTotalMax;
SumOfDefectsMax = sumOfDefectsMax;
HazeRegionMax = hazeRegionMax;
HazeAverageMax = hazeAverageMax;
LPDCountAvg = lPDCountAvg;
LPDCM2Avg = lPDCM2Avg;
AreaCountAvg = areaCountAvg;
AreaTotalAvg = areaTotalAvg;
ScratchCountAvg = scratchCountAvg;
ScratchTotalAvg = scratchTotalAvg;
SumOfDefectsAvg = sumOfDefectsAvg;
HazeRegionAvg = hazeRegionAvg;
HazeAverageAvg = hazeAverageAvg;
LPDCountStdDev = lPDCountStdDev;
LPDCM2StdDev = lPDCM2StdDev;
AreaCountStdDev = areaCountStdDev;
AreaTotalStdDev = areaTotalStdDev;
ScratchCountStdDev = scratchCountStdDev;
ScratchTotalStdDev = scratchTotalStdDev;
SumOfDefectsStdDev = sumOfDefectsStdDev;
HazeRegionStdDev = hazeRegionStdDev;
HazeAverageStdDev = hazeAverageStdDev;
}
public string Date { get; }
public string Recipe { get; }
public string Id { get; }
public string LPDCountMin { get; }
public string LPDCM2Min { get; }
public string AreaCountMin { get; }
public string AreaTotalMin { get; }
public string ScratchCountMin { get; }
public string ScratchTotalMin { get; }
public string SumOfDefectsMin { get; }
public string HazeRegionMin { get; }
public string HazeAverageMin { get; }
public string LPDCountMax { get; }
public string LPDCM2Max { get; }
public string AreaCountMax { get; }
public string AreaTotalMax { get; }
public string ScratchCountMax { get; }
public string ScratchTotalMax { get; }
public string SumOfDefectsMax { get; }
public string HazeRegionMax { get; }
public string HazeAverageMax { get; }
public string LPDCountAvg { get; }
public string LPDCM2Avg { get; }
public string AreaCountAvg { get; }
public string AreaTotalAvg { get; }
public string ScratchCountAvg { get; }
public string ScratchTotalAvg { get; }
public string SumOfDefectsAvg { get; }
public string HazeRegionAvg { get; }
public string HazeAverageAvg { get; }
public string LPDCountStdDev { get; }
public string LPDCM2StdDev { get; }
public string AreaCountStdDev { get; }
public string AreaTotalStdDev { get; }
public string ScratchCountStdDev { get; }
public string ScratchTotalStdDev { get; }
public string SumOfDefectsStdDev { get; }
public string HazeRegionStdDev { get; }
public string HazeAverageStdDev { get; }
private static ReadOnlyCollection<string> FixToEolArray(string[] toEol)
{
List<string> results = new();
const int MAX_COLUMNS = 9;
int[] mColumnWidths = new int[MAX_COLUMNS] { 8, 6, 6, 6, 6, 7, 7, 5, 7 };
if (toEol.Length < MAX_COLUMNS)
{
string leftVal, rightVal;
List<string> toEolList = new(toEol);
if (string.IsNullOrEmpty(toEolList[toEolList.Count - 1]))
toEolList.RemoveAt(toEolList.Count - 1);
for (int i = toEolList.Count; i < MAX_COLUMNS; i++)
toEolList.Insert(0, "");
for (int i = MAX_COLUMNS - 1; i >= 0; i--)
{
if (toEolList[i].Length > mColumnWidths[i])
{
leftVal = toEolList[i].Substring(0, toEolList[i].Length - mColumnWidths[i]);
rightVal = toEolList[i].Substring(leftVal.Length);
toEolList[i] = rightVal;
toEolList.Insert(i, leftVal);
if (string.IsNullOrEmpty(toEolList[0]))
toEolList.RemoveAt(0);
}
}
results.AddRange(toEolList);
}
return results.AsReadOnly();
}
internal static void ScanPast(string text, int[] i, string search)
{
int num = text.IndexOf(search, i[0]);
if (num > -1)
i[0] = num + search.Length;
else
i[0] = text.Length;
}
internal static string GetBefore(string text, int[] i, string search)
{
int num = text.IndexOf(search, i[0]);
if (num > -1)
{
string str = text.Substring(i[0], num - i[0]);
i[0] = num + search.Length;
return str.Trim();
}
string str1 = text.Substring(i[0]);
i[0] = text.Length;
return str1.Trim();
}
private static string GetBefore(string text, int[] i, string search, bool trim)
{
if (trim)
return GetBefore(text, i, search);
int num = text.IndexOf(search, i[0]);
if (num > -1)
{
string str = text.Substring(i[0], num - i[0]);
i[0] = num + search.Length;
return str;
}
string str1 = text.Substring(i[0]);
i[0] = text.Length;
return str1;
}
internal static string GetToEOL(string text, int[] i) =>
GetBefore(text, i, "\n");
private static string GetToEOL(string text, int[] i, bool trim)
{
if (trim)
return GetToEOL(text, i);
return GetBefore(text, i, "\n", false);
}
internal static Header Get(string headerFileName, Dictionary<string, string> pages, Dictionary<string, List<Detail>> slots, Constant constant)
{
Header? result;
string id;
string slot;
string toEOL;
string? text;
int[] i = new int[] { 0 };
if (!pages.TryGetValue(headerFileName, out text))
throw new Exception();
ScanPast(text, i, constant.Date);
string date = GetToEOL(text, i);
ScanPast(text, i, "Recipe ID:");
string recipe = GetBefore(text, i, "LotID:");
recipe = recipe.Replace(";", "");
if (text.Contains("[]"))
id = GetBefore(text, i, "[]");
else if (text.Contains("[7]"))
id = GetBefore(text, i, "[7]");
else
id = GetBefore(text, i, "[");
int slotCount = text.Substring(i[0]).Split('*').Length - 1;
for (int j = 0; j < slotCount; j++)
{
i[0] = j;
ScanPast(text, i, "*");
toEOL = GetToEOL(text, i, false);
slot = string.Concat("*", toEOL.Substring(0, 2));
if (!slots.ContainsKey(slot))
slots.Add(slot, new List<Detail>());
}
ScanPast(text, i, constant.Min);
string[] preToEol1 = GetToEOL(text, i, false).Trim().Split(' ');
ReadOnlyCollection<string> toEol1 = FixToEolArray(preToEol1);
ScanPast(text, i, constant.Max);
string[] preToEol2 = GetToEOL(text, i, false).Trim().Split(' ');
ReadOnlyCollection<string> toEol2 = FixToEolArray(preToEol2);
ScanPast(text, i, constant.Average);
string[] preToEol3 = GetToEOL(text, i, false).Trim().Split(' ');
ReadOnlyCollection<string> toEol3 = FixToEolArray(preToEol3);
ScanPast(text, i, constant.StdDev);
string[] preToEol4 = GetToEOL(text, i, false).Trim().Split(' ');
ReadOnlyCollection<string> toEol4 = FixToEolArray(preToEol4);
result = new(date: date,
recipe: recipe,
id: id,
lPDCountMin: toEol1[0].Trim(),
lPDCM2Min: toEol1[1].Trim(),
areaCountMin: toEol1[2].Trim(),
areaTotalMin: toEol1[3].Trim(),
scratchCountMin: toEol1[4].Trim(),
scratchTotalMin: toEol1[5].Trim(),
sumOfDefectsMin: toEol1[6].Trim(),
hazeRegionMin: toEol1[7].Trim(),
hazeAverageMin: toEol1[8].Trim(),
lPDCountMax: toEol2[0].Trim(),
lPDCM2Max: toEol2[1].Trim(),
areaCountMax: toEol2[2].Trim(),
areaTotalMax: toEol2[3].Trim(),
scratchCountMax: toEol2[4].Trim(),
scratchTotalMax: toEol2[5].Trim(),
sumOfDefectsMax: toEol2[6].Trim(),
hazeRegionMax: toEol2[7].Trim(),
hazeAverageMax: toEol2[8].Trim(),
lPDCountAvg: toEol3[0].Trim(),
lPDCM2Avg: toEol3[1].Trim(),
areaCountAvg: toEol3[2].Trim(),
areaTotalAvg: toEol3[3].Trim(),
scratchCountAvg: toEol3[4].Trim(),
scratchTotalAvg: toEol3[5].Trim(),
sumOfDefectsAvg: toEol3[6].Trim(),
hazeRegionAvg: toEol3[7].Trim(),
hazeAverageAvg: toEol3[8].Trim(),
lPDCountStdDev: toEol4[0].Trim(),
lPDCM2StdDev: toEol4[1].Trim(),
areaCountStdDev: toEol4[2].Trim(),
areaTotalStdDev: toEol4[3].Trim(),
scratchCountStdDev: toEol4[4].Trim(),
scratchTotalStdDev: toEol4[5].Trim(),
sumOfDefectsStdDev: toEol4[6].Trim(),
hazeRegionStdDev: toEol4[7].Trim(),
hazeAverageStdDev: toEol4[8].Trim());
return result;
}
}

View File

@ -232,7 +232,8 @@ public class ProcessData : IProcessData
return GetBefore("\n", false);
}
private string GetToText(string text) => _Data.Substring(_I, _Data.IndexOf(text, _I) - _I).Trim();
private string GetToText(string text) =>
_Data.Substring(_I, _Data.IndexOf(text, _I) - _I).Trim();
private string GetToken()
{
@ -412,10 +413,10 @@ public class ProcessData : IProcessData
UniqueId = string.Format("{0}_{1}_{2}", logistics.JobID, lot, Path.GetFileNameWithoutExtension(logistics.ReportFullPath));
}
#pragma warning disable IDE0060
private void ParseLotSummary(IFileRead fileRead, ILogistics logistics, string headerFileName, Dictionary<string, string> pages, Dictionary<string, List<Detail>> slots)
#pragma warning restore IDE0060
{
if (fileRead is null)
throw new ArgumentNullException(nameof(fileRead));
_I = 0;
ParseErrorText = string.Empty;
if (!pages.TryGetValue(headerFileName, out string value))
@ -601,6 +602,16 @@ public class ProcessData : IProcessData
return result;
}
#nullable enable
private static Complete? GetComplete(string headerFileName, Dictionary<string, string> pages, Dictionary<string, List<Detail>> slots)
{
Complete? result;
Constant constant = new();
result = Complete.Get(headerFileName, pages, slots, constant);
return result;
}
private void Parse(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection, string ghostPCLFileName)
{
object item;
@ -611,9 +622,9 @@ public class ProcessData : IProcessData
List<string> missingSlots = new();
Dictionary<string, string> pages = new();
Dictionary<string, List<Detail>> slots = new();
string sourcePath = Path.GetDirectoryName(logistics.ReportFullPath);
string sourceFileNamePdf = ConvertSourceFileToPdf(ghostPCLFileName, logistics);
sourceFiles.Add(sourceFileNamePdf);
string sourcePath = Path.GetDirectoryName(logistics.ReportFullPath) ?? throw new Exception();
string sourceFileNameWithoutExtension = Path.GetFileNameWithoutExtension(logistics.ReportFullPath);
string[] txtFiles = Directory.GetFiles(sourcePath, $"{sourceFileNameWithoutExtension}_*.txt", SearchOption.TopDirectoryOnly);
if (txtFiles.Length != 0)
@ -676,7 +687,6 @@ public class ProcessData : IProcessData
}
pdDocument.close();
}
// parse lot summary
_Log.Debug($"****ParseData - Parsing lot summary");
List<Tuple<string, string>> pageMapping = new();
string headerFileName = string.Concat(sourcePath, @"\", sourceFileNameWithoutExtension, "_", pages.Count, ".pdf");
@ -764,6 +774,23 @@ public class ProcessData : IProcessData
foreach (string sourceFile in sourceFiles)
fileInfoCollection.Add(new FileInfo(sourceFile));
fileInfoCollection.Add(logistics.FileInfo);
try
{
Complete? complete = GetComplete(headerFileName, pages, slots);
if (complete is null)
_Log.Warn($"Could not get Complete from {sourceFileNameWithoutExtension}");
else
{
FileInfo fileInfo = new($"{sourceFileNameWithoutExtension}.json");
string json = JsonSerializer.Serialize(complete, CompleteSourceGenerationContext.Default.Complete);
File.WriteAllText(fileInfo.FullName, json);
fileInfoCollection.Add(fileInfo);
}
}
catch (Exception ex)
{
_Log.Error($"Error in {nameof(GetComplete)}", ex);
}
}
#nullable enable

View File

@ -0,0 +1,229 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Adaptation.FileHandlers.pcl;
#nullable enable
public class Wafer
{
public Wafer(string date, string id, string comments, string sort, string lPDCount, string lPDCM2, string bin1, string bin2, string bin3, string bin4, string bin5, string bin6, string bin7, string bin8, string mean, string stdDev, string areaCount, string areaTotal, string scratchCount, string scratchTotal, string sumOfDefects, string hazeRegion, string hazeAverage, string hazePeak, string laser, string gain, string diameter, string thresh, string exclusion, string hazeRng, string thruput, string recipe)
{
Date = date;
Id = id;
Comments = comments;
Sort = sort;
LPDCount = lPDCount;
LPDCM2 = lPDCM2;
Bin1 = bin1;
Bin2 = bin2;
Bin3 = bin3;
Bin4 = bin4;
Bin5 = bin5;
Bin6 = bin6;
Bin7 = bin7;
Bin8 = bin8;
Mean = mean;
StdDev = stdDev;
AreaCount = areaCount;
AreaTotal = areaTotal;
ScratchCount = scratchCount;
ScratchTotal = scratchTotal;
SumOfDefects = sumOfDefects;
HazeRegion = hazeRegion;
HazeAverage = hazeAverage;
HazePeak = hazePeak;
Laser = laser;
Gain = gain;
Diameter = diameter;
Thresh = thresh;
Exclusion = exclusion;
HazeRng = hazeRng;
Thruput = thruput;
Recipe = recipe;
}
public string Date { get; }
public string Id { get; }
public string Comments { get; }
public string Sort { get; }
public string LPDCount { get; }
public string LPDCM2 { get; }
public string Bin1 { get; }
public string Bin2 { get; }
public string Bin3 { get; }
public string Bin4 { get; }
public string Bin5 { get; }
public string Bin6 { get; }
public string Bin7 { get; }
public string Bin8 { get; }
public string Mean { get; }
public string StdDev { get; }
public string AreaCount { get; }
public string AreaTotal { get; }
public string ScratchCount { get; }
public string ScratchTotal { get; }
public string SumOfDefects { get; }
public string HazeRegion { get; }
public string HazeAverage { get; }
public string HazePeak { get; }
public string Laser { get; }
public string Gain { get; }
public string Diameter { get; }
public string Thresh { get; }
public string Exclusion { get; }
public string HazeRng { get; }
public string Thruput { get; }
public string Recipe { get; }
// private static bool IsNullOrWhiteSpace(string search)
// {
// for (int index = 0; index < search.Length; ++index)
// {
// if (!char.IsWhiteSpace(search[index]))
// return false;
// }
// return true;
// }
// private static bool IsBlankLine(string text, int[] i)
// {
// int num = text.IndexOf("\n", i[0]);
// return IsNullOrWhiteSpace(num > -1 ? text.Substring(i[0], num - i[0]) : text.Substring(i[0]));
// }
// private static string GetToText(string text, int[] i, string search) =>
// text.Substring(i[0], text.IndexOf(search, i[0]) - i[0]).Trim();
// private static string GetToken(string text, int[] i)
// {
// while (i[0] < text.Length && IsNullOrWhiteSpace(text.Substring(i[0], 1)))
// ++i[0];
// int j = i[0];
// while (j < text.Length && !IsNullOrWhiteSpace(text.Substring(j, 1)))
// ++j;
// string str = text.Substring(i[0], j - i[0]);
// i[0] = j;
// return str.Trim();
// }
// private static string PeekNextLine(string text, int[] i)
// {
// int j = i[0];
// string result = Header.GetToEOL(text, i);
// i[0] = j;
// return result;
// }
internal static ReadOnlyCollection<Wafer> Get(string headerFileName, Dictionary<string, string> pages, Constant constant)
{
List<Wafer> results = new();
Wafer wafer;
string? text;
List<string> stringList;
int[] i = new int[] { 0 };
foreach (KeyValuePair<string, string> keyValuePair in pages)
{
if (keyValuePair.Key == headerFileName)
continue;
if (!pages.ContainsKey(keyValuePair.Key))
throw new Exception();
i[0] = 0;
stringList = new();
if (!pages.TryGetValue(keyValuePair.Key, out text))
throw new Exception();
Header.ScanPast(text, i, constant.Date);
string date = Header.GetToEOL(text, i);
Header.ScanPast(text, i, "ID#");
string id = Header.GetToEOL(text, i);
if (id.Length > 5)
id = string.Concat(id.Substring(0, 5), "... - ***");
id = id.Replace("*", "");
Header.ScanPast(text, i, "Comments:");
string comments = Header.GetToEOL(text, i);
Header.ScanPast(text, i, "Sort:");
string sort = Header.GetToEOL(text, i);
Header.ScanPast(text, i, "LPD Count:");
string lPDCount = Header.GetToEOL(text, i);
Header.ScanPast(text, i, "LPD / cm2:");
string lPDCM2 = Header.GetToEOL(text, i);
while (Header.GetBefore(text, i, ":").Contains("Bin"))
stringList.Add(Header.GetToEOL(text, i));
string bin1 = stringList.Count >= 1 ? stringList[0] : string.Empty;
string bin2 = stringList.Count >= 2 ? stringList[1] : string.Empty;
string bin3 = stringList.Count >= 3 ? stringList[2] : string.Empty;
string bin4 = stringList.Count >= 4 ? stringList[3] : string.Empty;
string bin5 = stringList.Count >= 5 ? stringList[4] : string.Empty;
string bin6 = stringList.Count >= 6 ? stringList[5] : string.Empty;
string bin7 = stringList.Count >= 7 ? stringList[6] : string.Empty;
string bin8 = stringList.Count >= 8 ? stringList[7] : string.Empty;
string mean = Header.GetToEOL(text, i);
Header.ScanPast(text, i, "Std Dev:");
string stdDev = Header.GetToEOL(text, i);
Header.ScanPast(text, i, "Area Count:");
string areaCount = Header.GetToEOL(text, i);
Header.ScanPast(text, i, "Area Total:");
string areaTotal = Header.GetToEOL(text, i);
Header.ScanPast(text, i, "Scratch Count:");
string scratchCount = Header.GetToEOL(text, i);
Header.ScanPast(text, i, "Scratch Total:");
string scratchTotal = Header.GetToEOL(text, i);
Header.ScanPast(text, i, "Sum of All Defects:");
string sumOfDefects = Header.GetToEOL(text, i);
Header.ScanPast(text, i, "Haze Region:");
string hazeRegion = Header.GetToEOL(text, i);
Header.ScanPast(text, i, "Haze Average:");
string hazeAverage = Header.GetToEOL(text, i);
Header.ScanPast(text, i, "Haze Peak:");
string hazePeak = Header.GetToEOL(text, i);
Header.ScanPast(text, i, "Laser:");
string laser = Header.GetBefore(text, i, "Gain:");
string gain = Header.GetBefore(text, i, "Diameter:");
string diameter = Header.GetToEOL(text, i);
Header.ScanPast(text, i, "Thresh:");
string thresh = Header.GetBefore(text, i, "Exclusion:");
string exclusion = Header.GetToEOL(text, i);
Header.ScanPast(text, i, "Haze Rng:");
string hazeRng = Header.GetBefore(text, i, "Thruput:");
string thruput = Header.GetToEOL(text, i);
Header.ScanPast(text, i, "Recipe ID:");
string recipe = Header.GetToEOL(text, i);
wafer = new(date: date,
id: id,
comments: comments,
sort: sort,
lPDCount: lPDCount,
lPDCM2: lPDCM2,
bin1: bin1,
bin2: bin2,
bin3: bin3,
bin4: bin4,
bin5: bin5,
bin6: bin6,
bin7: bin7,
bin8: bin8,
mean: mean,
stdDev: stdDev,
areaCount: areaCount,
areaTotal: areaTotal,
scratchCount: scratchCount,
scratchTotal: scratchTotal,
sumOfDefects: sumOfDefects,
hazeRegion: hazeRegion,
hazeAverage: hazeAverage,
hazePeak: hazePeak,
laser: laser,
gain: gain,
diameter: diameter,
thresh: thresh,
exclusion: exclusion,
hazeRng: hazeRng,
thruput: thruput,
recipe: recipe);
results.Add(wafer);
}
return results.AsReadOnly();
}
}