819 lines
41 KiB
C#
819 lines
41 KiB
C#
using Adaptation.Shared;
|
|
using Adaptation.Shared.Metrology;
|
|
using log4net;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace Adaptation.Helpers
|
|
{
|
|
|
|
public partial class ProcessData : IProcessData
|
|
{
|
|
|
|
public HeaderFile Header { get; private set; }
|
|
public List<DataFile> Details { get; private set; }
|
|
|
|
private int _I;
|
|
private readonly ILog _Log;
|
|
private string _Data;
|
|
|
|
public ProcessData(ILogic logic, ConfigData configData, List<FileInfo> fileInfoCollection)
|
|
{
|
|
Header = null;
|
|
fileInfoCollection.Clear();
|
|
_I = 0;
|
|
_Data = string.Empty;
|
|
_Log = LogManager.GetLogger(typeof(ProcessData));
|
|
Details = new List<DataFile>();
|
|
Tuple<HeaderFile, List<DataFile>> tuple = Parse(logic, fileInfoCollection);
|
|
Details.AddRange(tuple.Item2);
|
|
Header = tuple.Item1;
|
|
}
|
|
|
|
public Tuple<string, JsonElement?, List<FileInfo>> GetResults(ILogic logic, ConfigDataBase configDataBase, List<FileInfo> fileInfoCollection)
|
|
{
|
|
Tuple<string, JsonElement?, List<FileInfo>> results;
|
|
if (!(configDataBase is ConfigData configData))
|
|
throw new Exception();
|
|
List<Test> tests = new List<Test>();
|
|
List<IProcessDataDescription> descriptions;
|
|
EventName eventName = configData.GetEventNameValue();
|
|
if (eventName == EventName.FileRead && Details.Any())
|
|
{
|
|
foreach (var item in Details)
|
|
tests.Add(Test.SP1);
|
|
descriptions = configData.GetDescription(logic, tests, this);
|
|
}
|
|
else
|
|
throw new Exception();
|
|
if (!configData.EafHosted)
|
|
{
|
|
new FileRead.Description().GetDescription(logic, configData, tests, this);
|
|
}
|
|
if (tests.Count != descriptions.Count)
|
|
throw new Exception();
|
|
for (int i = 0; i < tests.Count; i++)
|
|
{
|
|
if (descriptions[i].Test != (int)tests[i])
|
|
throw new Exception();
|
|
}
|
|
string json;
|
|
if (descriptions[0] is Duplicator.Description)
|
|
{
|
|
List<Duplicator.Description> duplicatorDescriptions = (from l in descriptions select (Duplicator.Description)l).ToList();
|
|
json = JsonSerializer.Serialize(duplicatorDescriptions, duplicatorDescriptions.GetType());
|
|
}
|
|
else if (descriptions[0] is FileRead.Description)
|
|
{
|
|
List<FileRead.Description> fileReadDescriptions = (from l in descriptions select (FileRead.Description)l).ToList();
|
|
json = JsonSerializer.Serialize(fileReadDescriptions, fileReadDescriptions.GetType());
|
|
}
|
|
else
|
|
throw new Exception();
|
|
object @object = JsonSerializer.Deserialize<object>(json);
|
|
if (!(@object is JsonElement jsonElement))
|
|
throw new Exception();
|
|
results = new Tuple<string, JsonElement?, List<FileInfo>>(logic.Logistics.Logistics1[0], jsonElement, fileInfoCollection);
|
|
return results;
|
|
}
|
|
|
|
public static Dictionary<Test, List<Duplicator.Description>> GetKeyValuePairs(ConfigData configData, JsonElement jsonElement, List<Duplicator.Description> processDataDescriptions, bool extra = false)
|
|
{
|
|
Dictionary<Test, List<Duplicator.Description>> results = configData.GetKeyValuePairs(processDataDescriptions);
|
|
configData.CheckProcessDataDescription(results, extra);
|
|
return results;
|
|
}
|
|
|
|
public static List<FileRead.Description> GetProcessDataFileReadDescriptions(ConfigData configData, JsonElement jsonElement)
|
|
{
|
|
List<FileRead.Description> results = new List<FileRead.Description>();
|
|
List<IProcessDataDescription> processDataDescriptions = configData.GetIProcessDataDescriptions(jsonElement);
|
|
foreach (IProcessDataDescription processDataDescription in processDataDescriptions)
|
|
{
|
|
if (!(processDataDescription is FileRead.Description description))
|
|
continue;
|
|
results.Add(description);
|
|
}
|
|
return results;
|
|
}
|
|
|
|
public static Tuple<string, string> GetLines(ILogic logic, List<FileRead.Description> descriptions)
|
|
{
|
|
char del = '\t';
|
|
StringBuilder result = new StringBuilder();
|
|
FileRead.Description x = descriptions[0];
|
|
result.Append(x.DcnLpdMin).Append(del). // 001 -
|
|
Append(x.DcnLpdMax).Append(del). // 002 -
|
|
Append(x.DcnLpdMean).Append(del). // 003 - DCN LPD
|
|
Append(x.DcnAreaCountMin).Append(del). // 004 -
|
|
Append(x.DcnAreaCountMax).Append(del). // 005 -
|
|
Append(x.DcnAreaCountMean).Append(del).// 006 - DCN Area
|
|
Append(x.DcnAreaMin).Append(del). // 007 -
|
|
Append(x.DcnAreaMax).Append(del). // 008 -
|
|
Append(x.Date).Append(del). // 009 -
|
|
Append(x.DcnHazeAvgMean).Append(del). // 010 - Haze Average
|
|
Append(string.Empty).Append(del). // 011 -
|
|
Append(string.Empty).Append(del). // 012 -
|
|
Append(string.Empty).Append(del). // 013 -
|
|
Append(string.Empty).Append(del). // 014 -
|
|
Append(string.Empty).Append(del). // 015 -
|
|
Append(string.Empty).Append(del). // 016 -
|
|
Append(string.Empty).Append(del). // 017 -
|
|
Append(string.Empty).Append(del). // 018 -
|
|
Append(string.Empty).Append(del). // 019 -
|
|
Append(string.Empty).Append(del). // 020 -
|
|
Append(string.Empty).Append(del). // 021 -
|
|
Append(string.Empty).Append(del). // 022 -
|
|
Append(string.Empty).Append(del). // 023 -
|
|
Append(string.Empty).Append(del). // 024 -
|
|
Append(string.Empty).Append(del). // 025 -
|
|
Append(string.Empty).Append(del). // 026 -
|
|
Append(string.Empty).Append(del). // 027 -
|
|
Append(x.RDS).Append(del). // 028 - Lot
|
|
Append(x.Reactor).Append(del). // 029 - Process
|
|
Append(x.Recipe).Append(del). // 030 - Part
|
|
Append(x.DcnScrMean).Append(del). // 031 - Scratch Count
|
|
Append(string.Empty).Append(del). // 032 -
|
|
Append(string.Empty).Append(del). // 033 -
|
|
Append(string.Empty).Append(del). // 034 -
|
|
Append(x.DcnMicroScrMean).Append(del). // 035 - Scratch Length
|
|
Append(string.Empty).Append(del). // 036 -
|
|
Append(string.Empty).Append(del). // 037 -
|
|
Append(string.Empty).Append(del). // 038 -
|
|
Append(x.DcnAllMean).Append(del). // 039 - Average Sum of Defects
|
|
Append(x.DcnAllMax).Append(del). // 040 - Max Sum of defects
|
|
Append(x.DcnAllMin).Append(del). // 041 - Min Sum of Defects
|
|
Append(string.Empty).Append(del). // 042 -
|
|
Append(logic.Logistics.MesEntity).Append(del). // 043 -
|
|
Append(x.DcnAreaMean).Append(del). // 044 - DCN MM2
|
|
AppendLine();
|
|
return new Tuple<string, string>(result.ToString(), x.Date);
|
|
}
|
|
|
|
internal static void PostOpenInsightMetrologyViewerAttachments(ILog log, ConfigData configData, Logistics logistics, DateTime dateTime, string logisticsSequenceMemoryDirectory, List<FileRead.Description> descriptions, string matchDirectory)
|
|
{
|
|
string[] summaryFiles = Directory.GetFiles(matchDirectory, "*.txt", SearchOption.TopDirectoryOnly);
|
|
if (summaryFiles.Length != 1)
|
|
throw new Exception("Invalid summary file count!");
|
|
string wsResultsMemoryFile = string.Concat(logisticsSequenceMemoryDirectory, @"\", nameof(WS.Results), ".json");
|
|
if (!File.Exists(wsResultsMemoryFile))
|
|
throw new Exception(string.Concat("Memory file <", wsResultsMemoryFile, "> doesn't exist!"));
|
|
string json = File.ReadAllText(wsResultsMemoryFile);
|
|
WS.Results metrologyWSRequest = JsonSerializer.Deserialize<WS.Results>(json);
|
|
long wsResultsHeaderID = metrologyWSRequest.HeaderID;
|
|
string[] prnFiles = Directory.GetFiles(matchDirectory, "WaferMap*.prn", SearchOption.TopDirectoryOnly);
|
|
if (prnFiles.Length == 0 || prnFiles.Length != descriptions.Count)
|
|
log.Debug("Invalid WaferMap*.prn file count!");
|
|
List<string> pdfFiles = new List<string>();
|
|
foreach (string prnFile in prnFiles.OrderBy(l => l))
|
|
pdfFiles.Add(ConvertSourceFileToPdf(configData, prnFile));
|
|
if (pdfFiles.Count == 0 || pdfFiles.Count != descriptions.Count)
|
|
log.Debug("Invalid *.pdf file count!");
|
|
List<WS.Attachment> dataAttachments = new List<WS.Attachment>();
|
|
List<WS.Attachment> headerAttachments = new List<WS.Attachment> { new WS.Attachment(descriptions[0].HeaderUniqueId, "Data.txt", summaryFiles[0]) };
|
|
int count;
|
|
if (pdfFiles.Count < descriptions.Count)
|
|
count = pdfFiles.Count;
|
|
else
|
|
count = descriptions.Count;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
if (!string.IsNullOrEmpty(pdfFiles[i]))
|
|
dataAttachments.Add(new WS.Attachment(descriptions[i].UniqueId, "Image.pdf", pdfFiles[i]));
|
|
}
|
|
if (dataAttachments.Count == 0 || dataAttachments.Count != descriptions.Count)
|
|
log.Debug("Invalid attachment count!");
|
|
WS.AttachFiles(configData.OpenInsightMetrogyViewerAPI, wsResultsHeaderID, headerAttachments, dataAttachments);
|
|
}
|
|
|
|
private void ScanPast(string text)
|
|
{
|
|
int num = _Data.IndexOf(text, _I);
|
|
if (num > -1)
|
|
_I = num + text.Length;
|
|
else
|
|
_I = _Data.Length;
|
|
}
|
|
|
|
private string GetBefore(string text)
|
|
{
|
|
int num = _Data.IndexOf(text, _I);
|
|
if (num > -1)
|
|
{
|
|
string str = _Data.Substring(_I, num - _I);
|
|
_I = num + text.Length;
|
|
return str.Trim();
|
|
}
|
|
string str1 = _Data.Substring(_I);
|
|
_I = _Data.Length;
|
|
return str1.Trim();
|
|
}
|
|
|
|
private string GetBefore(string text, bool trim)
|
|
{
|
|
if (trim)
|
|
return GetBefore(text);
|
|
int num = _Data.IndexOf(text, _I);
|
|
if (num > -1)
|
|
{
|
|
string str = _Data.Substring(_I, num - _I);
|
|
_I = num + text.Length;
|
|
return str;
|
|
}
|
|
string str1 = _Data.Substring(_I);
|
|
_I = _Data.Length;
|
|
return str1;
|
|
}
|
|
|
|
private bool IsNullOrWhiteSpace(string text)
|
|
{
|
|
for (int index = 0; index < text.Length; ++index)
|
|
{
|
|
if (!char.IsWhiteSpace(text[index]))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private bool IsBlankLine()
|
|
{
|
|
int num = _Data.IndexOf("\n", _I);
|
|
return IsNullOrWhiteSpace(num > -1 ? _Data.Substring(_I, num - _I) : _Data.Substring(_I));
|
|
}
|
|
|
|
private string GetToEOL()
|
|
{
|
|
return GetBefore("\n");
|
|
}
|
|
|
|
private string GetToEOL(bool trim)
|
|
{
|
|
if (trim)
|
|
return GetToEOL();
|
|
return GetBefore("\n", false);
|
|
}
|
|
|
|
private string GetToText(string text)
|
|
{
|
|
return _Data.Substring(_I, _Data.IndexOf(text, _I) - _I).Trim();
|
|
}
|
|
|
|
private string GetToken()
|
|
{
|
|
while (_I < _Data.Length && IsNullOrWhiteSpace(_Data.Substring(_I, 1)))
|
|
++_I;
|
|
int j = _I;
|
|
while (j < _Data.Length && !IsNullOrWhiteSpace(_Data.Substring(j, 1)))
|
|
++j;
|
|
string str = _Data.Substring(_I, j - _I);
|
|
_I = j;
|
|
return str.Trim();
|
|
}
|
|
|
|
private string PeekNextLine()
|
|
{
|
|
int j = _I;
|
|
string toEol = GetToEOL();
|
|
_I = j;
|
|
return toEol;
|
|
}
|
|
|
|
private void GetWaferSummaryInfo(List<WaferSummaryInfo> waferSummaryInfos, string whichInfo)
|
|
{
|
|
ScanPast(whichInfo);
|
|
GetToEOL();
|
|
GetToEOL();
|
|
GetToEOL();
|
|
GetToEOL();
|
|
string[] segments;
|
|
WaferSummaryInfo waferSummaryInfo;
|
|
const string grade = "F Grade";
|
|
const string rejct = "F Reject";
|
|
const string overLoad = "F OverLoad";
|
|
for (string line = PeekNextLine(); line[0] != '-'; line = PeekNextLine())
|
|
{
|
|
line = GetToEOL();
|
|
waferSummaryInfo = new WaferSummaryInfo();
|
|
if (line.StartsWith(grade))
|
|
line = line.Replace(grade, string.Concat("F -1", grade.Substring(4)));
|
|
else if (line.StartsWith(rejct))
|
|
line = line.Replace(rejct, string.Concat("F -1", rejct.Substring(4)));
|
|
else if (line.StartsWith(overLoad))
|
|
line = line.Replace(overLoad, string.Concat("F -1", overLoad.Substring(4)));
|
|
segments = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
waferSummaryInfo.Side = segments[0];
|
|
waferSummaryInfo.WaferID = segments[1];
|
|
waferSummaryInfo.Grade = segments[2];
|
|
waferSummaryInfo.SrcDest = segments[3];
|
|
if (segments.Length > 4)
|
|
{
|
|
waferSummaryInfo.Lpd = segments[5];
|
|
waferSummaryInfo.LpdN = segments[6];
|
|
waferSummaryInfo.LpdES = segments[7];
|
|
waferSummaryInfo.MicroScr = segments[8];
|
|
waferSummaryInfo.Scr = segments[9];
|
|
waferSummaryInfo.Slip = segments[10];
|
|
waferSummaryInfo.AreaNum = segments[11];
|
|
waferSummaryInfo.Area = segments[12];
|
|
waferSummaryInfo.HazeAvg = segments[13];
|
|
waferSummaryInfo.HazeMedian = segments[14];
|
|
waferSummaryInfo.HazeStdDev = segments[15];
|
|
waferSummaryInfo.Bin1 = segments[16];
|
|
waferSummaryInfo.Bin2 = segments[17];
|
|
waferSummaryInfo.Bin3 = segments[18];
|
|
waferSummaryInfo.Bin4 = segments[19];
|
|
waferSummaryInfo.Bin5 = segments[20];
|
|
waferSummaryInfo.Bin6 = segments[21];
|
|
waferSummaryInfo.Bin7 = segments[22];
|
|
waferSummaryInfo.Bin8 = segments[23];
|
|
}
|
|
if (waferSummaryInfo.WaferID == "-1")
|
|
{
|
|
segments = waferSummaryInfo.SrcDest.Split('-')[0].Split('/');
|
|
waferSummaryInfo.WaferID = segments[segments.Length - 1];
|
|
}
|
|
waferSummaryInfos.Add(waferSummaryInfo);
|
|
}
|
|
}
|
|
|
|
private HeaderFile ParseHeader(ILogic logic, List<WaferSummaryInfo> dcnTotals, List<WaferSummaryInfo> dwnTotals, List<WaferSummaryInfo> dnnTotals)
|
|
{
|
|
HeaderFile result = new HeaderFile { JobID = logic.Logistics.JobID, MesEntity = logic.Logistics.MesEntity, Date = DateTime.Now.ToString() };
|
|
_I = 0;
|
|
_Data = string.Empty;
|
|
string h = string.Empty;
|
|
string summaryReportText = File.ReadAllText(logic.Logistics.ReportFullPath);
|
|
if (!string.IsNullOrEmpty(summaryReportText))
|
|
{
|
|
_Log.Debug("HeaderFile() - Beginning");
|
|
_I = 0;
|
|
_Data = summaryReportText;
|
|
ScanPast("Long Wafer Summary");
|
|
GetToEOL();
|
|
ScanPast("Session:");
|
|
string toEOL = GetToEOL(true);
|
|
string str = toEOL;
|
|
result.Recipe = toEOL;
|
|
result.Session = str;
|
|
ScanPast("Lot ID:");
|
|
result.Lot = GetToEOL(true);
|
|
// Remove illegal characters \/:*?"<>| found in the Lot.
|
|
result.Lot = Regex.Replace(result.Lot, @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]", "_").Split('\r')[0].Split('\n')[0];
|
|
string[] segments = result.Lot.Split(new char[] { '-' });
|
|
_Log.Debug("HeaderFile() - Debug A");
|
|
if (segments.Length > 1)
|
|
{
|
|
result.Reactor = segments[0];
|
|
result.RDS = segments[1];
|
|
if (segments.Length > 2)
|
|
{
|
|
result.PSN = segments[2];
|
|
if (segments.Length > 3)
|
|
result.Operator = segments[3];
|
|
}
|
|
}
|
|
_Log.Debug("HeaderFile() - Debug B");
|
|
_I = 0;
|
|
_Data = summaryReportText;
|
|
GetWaferSummaryInfo(dcnTotals, "DCN Totals");
|
|
ScanPast("Min");
|
|
segments = GetToEOL().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
result.DcnAllMin = segments[0];
|
|
result.DcnLpdMin = segments[1];
|
|
result.DcnLpdNMin = segments[2];
|
|
result.DcnLpdESMin = segments[3];
|
|
result.DcnMicroScrMin = segments[4];
|
|
result.DcnScrMin = segments[5];
|
|
result.DcnSlipMin = segments[6];
|
|
result.DcnAreaCountMin = segments[7];
|
|
result.DcnAreaMin = segments[8];
|
|
result.DcnHazeAvgMin = segments[9];
|
|
result.DcnHazeMedianMin = segments[10];
|
|
result.DcnHazeStdDevMin = segments[11];
|
|
result.DcnBin1Min = segments[12];
|
|
result.DcnBin2Min = segments[13];
|
|
result.DcnBin3Min = segments[14];
|
|
result.DcnBin4Min = segments[15];
|
|
result.DcnBin5Min = segments[16];
|
|
result.DcnBin6Min = segments[17];
|
|
result.DcnBin7Min = segments[18];
|
|
result.DcnBin8Min = segments[19];
|
|
ScanPast("Max");
|
|
segments = GetToEOL().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
result.DcnAllMax = segments[0];
|
|
result.DcnLpdMax = segments[1];
|
|
result.DcnLpdNMax = segments[2];
|
|
result.DcnLpdESMax = segments[3];
|
|
result.DcnMicroScrMax = segments[4];
|
|
result.DcnScrMax = segments[5];
|
|
result.DcnSlipMax = segments[6];
|
|
result.DcnAreaCountMax = segments[7];
|
|
result.DcnAreaMax = segments[8];
|
|
result.DcnHazeAvgMax = segments[9];
|
|
result.DcnHazeMedianMax = segments[10];
|
|
result.DcnHazeStdDevMax = segments[11];
|
|
result.DcnBin1Max = segments[12];
|
|
result.DcnBin2Max = segments[13];
|
|
result.DcnBin3Max = segments[14];
|
|
result.DcnBin4Max = segments[15];
|
|
result.DcnBin5Max = segments[16];
|
|
result.DcnBin6Max = segments[17];
|
|
result.DcnBin7Max = segments[18];
|
|
result.DcnBin8Max = segments[19];
|
|
ScanPast("Mean");
|
|
segments = GetToEOL().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
result.DcnAllMean = segments[0];
|
|
result.DcnLpdMean = segments[1];
|
|
result.DcnLpdNMean = segments[2];
|
|
result.DcnLpdESMean = segments[3];
|
|
result.DcnMicroScrMean = segments[4];
|
|
result.DcnScrMean = segments[5];
|
|
result.DcnSlipMean = segments[6];
|
|
result.DcnAreaCountMean = segments[7];
|
|
result.DcnAreaMean = segments[8];
|
|
result.DcnHazeAvgMean = segments[9];
|
|
result.DcnHazeMedianMean = segments[10];
|
|
result.DcnHazeStdDevMean = segments[11];
|
|
result.DcnBin1Mean = segments[12];
|
|
result.DcnBin2Mean = segments[13];
|
|
result.DcnBin3Mean = segments[14];
|
|
result.DcnBin4Mean = segments[15];
|
|
result.DcnBin5Mean = segments[16];
|
|
result.DcnBin6Mean = segments[17];
|
|
result.DcnBin7Mean = segments[18];
|
|
result.DcnBin8Mean = segments[19];
|
|
ScanPast("Std. Dev.");
|
|
segments = GetToEOL().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
result.DcnAllStdDev = segments[0];
|
|
result.DcnLpdStdDev = segments[1];
|
|
result.DcnLpdNStdDev = segments[2];
|
|
result.DcnLpdESStdDev = segments[3];
|
|
result.DcnMicroScrStdDev = segments[4];
|
|
result.DcnScrStdDev = segments[5];
|
|
result.DcnSlipStdDev = segments[6];
|
|
result.DcnAreaCountStdDev = segments[7];
|
|
result.DcnAreaStdDev = segments[8];
|
|
result.DcnHazeAvgStdDev = segments[9];
|
|
result.DcnHazeMedianStdDev = segments[10];
|
|
result.DcnHazeStdDevStdDev = segments[11];
|
|
result.DcnBin1StdDev = segments[12];
|
|
result.DcnBin2StdDev = segments[13];
|
|
result.DcnBin3StdDev = segments[14];
|
|
result.DcnBin4StdDev = segments[15];
|
|
result.DcnBin5StdDev = segments[16];
|
|
result.DcnBin6StdDev = segments[17];
|
|
result.DcnBin7StdDev = segments[18];
|
|
result.DcnBin8StdDev = segments[19];
|
|
_I = 0;
|
|
_Data = summaryReportText;
|
|
_Log.Debug("HeaderFile() - Debug C");
|
|
if (!_Data.Contains("DWN Totals"))
|
|
{
|
|
foreach (WaferSummaryInfo dcnTotal in dcnTotals)
|
|
dwnTotals.Add(new WaferSummaryInfo());
|
|
}
|
|
else
|
|
{
|
|
GetWaferSummaryInfo(dwnTotals, "DWN Totals");
|
|
ScanPast("Min");
|
|
segments = GetToEOL().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
result.DwnAllMin = segments[0];
|
|
result.DwnLpdMin = segments[1];
|
|
result.DwnLpdNMin = segments[2];
|
|
result.DwnLpdESMin = segments[3];
|
|
result.DwnMicroScrMin = segments[4];
|
|
result.DwnScrMin = segments[5];
|
|
result.DwnSlipMin = segments[6];
|
|
result.DwnAreaCountMin = segments[7];
|
|
result.DwnAreaMin = segments[8];
|
|
result.DwnHazeAvgMin = segments[9];
|
|
result.DwnHazeMedianMin = segments[10];
|
|
result.DwnHazeStdDevMin = segments[11];
|
|
result.DwnBin1Min = segments[12];
|
|
result.DwnBin2Min = segments[13];
|
|
result.DwnBin3Min = segments[14];
|
|
result.DwnBin4Min = segments[15];
|
|
result.DwnBin5Min = segments[16];
|
|
result.DwnBin6Min = segments[17];
|
|
result.DwnBin7Min = segments[18];
|
|
result.DwnBin8Min = segments[19];
|
|
ScanPast("Max");
|
|
segments = GetToEOL().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
result.DwnAllMax = segments[0];
|
|
result.DwnLpdMax = segments[1];
|
|
result.DwnLpdNMax = segments[2];
|
|
result.DwnLpdESMax = segments[3];
|
|
result.DwnMicroScrMax = segments[4];
|
|
result.DwnScrMax = segments[5];
|
|
result.DwnSlipMax = segments[6];
|
|
result.DwnAreaCountMax = segments[7];
|
|
result.DwnAreaMax = segments[8];
|
|
result.DwnHazeAvgMax = segments[9];
|
|
result.DwnHazeMedianMax = segments[10];
|
|
result.DwnHazeStdDevMax = segments[11];
|
|
result.DwnBin1Max = segments[12];
|
|
result.DwnBin2Max = segments[13];
|
|
result.DwnBin3Max = segments[14];
|
|
result.DwnBin4Max = segments[15];
|
|
result.DwnBin5Max = segments[16];
|
|
result.DwnBin6Max = segments[17];
|
|
result.DwnBin7Max = segments[18];
|
|
result.DwnBin8Max = segments[19];
|
|
ScanPast("Mean");
|
|
segments = GetToEOL().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
result.DwnAllMean = segments[0];
|
|
result.DwnLpdMean = segments[1];
|
|
result.DwnLpdNMean = segments[2];
|
|
result.DwnLpdESMean = segments[3];
|
|
result.DwnMicroScrMean = segments[4];
|
|
result.DwnScrMean = segments[5];
|
|
result.DwnSlipMean = segments[6];
|
|
result.DwnAreaCountMean = segments[7];
|
|
result.DwnAreaMean = segments[8];
|
|
result.DwnHazeAvgMean = segments[9];
|
|
result.DwnHazeMedianMean = segments[10];
|
|
result.DwnHazeStdDevMean = segments[11];
|
|
result.DwnBin1Mean = segments[12];
|
|
result.DwnBin2Mean = segments[13];
|
|
result.DwnBin3Mean = segments[14];
|
|
result.DwnBin4Mean = segments[15];
|
|
result.DwnBin5Mean = segments[16];
|
|
result.DwnBin6Mean = segments[17];
|
|
result.DwnBin7Mean = segments[18];
|
|
result.DwnBin8Mean = segments[19];
|
|
ScanPast("Std. Dev.");
|
|
segments = GetToEOL().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
result.DwnAllStdDev = segments[0];
|
|
result.DwnLpdStdDev = segments[1];
|
|
result.DwnLpdNStdDev = segments[2];
|
|
result.DwnLpdESStdDev = segments[3];
|
|
result.DwnMicroScrStdDev = segments[4];
|
|
result.DwnScrStdDev = segments[5];
|
|
result.DwnSlipStdDev = segments[6];
|
|
result.DwnAreaCountStdDev = segments[7];
|
|
result.DwnAreaStdDev = segments[8];
|
|
result.DwnHazeAvgStdDev = segments[9];
|
|
result.DwnHazeMedianStdDev = segments[10];
|
|
result.DwnHazeStdDevStdDev = segments[11];
|
|
result.DwnBin1StdDev = segments[12];
|
|
result.DwnBin2StdDev = segments[13];
|
|
result.DwnBin3StdDev = segments[14];
|
|
result.DwnBin4StdDev = segments[15];
|
|
result.DwnBin5StdDev = segments[16];
|
|
result.DwnBin6StdDev = segments[17];
|
|
result.DwnBin7StdDev = segments[18];
|
|
result.DwnBin8StdDev = segments[19];
|
|
}
|
|
_I = 0;
|
|
_Data = summaryReportText;
|
|
_Log.Debug("HeaderFile() - Debug D");
|
|
if (!_Data.Contains("DNN Totals"))
|
|
{
|
|
foreach (WaferSummaryInfo waferSummaryInfo in dcnTotals)
|
|
dnnTotals.Add(new WaferSummaryInfo());
|
|
}
|
|
else
|
|
{
|
|
GetWaferSummaryInfo(dnnTotals, "DNN Totals");
|
|
ScanPast("Min");
|
|
segments = GetToEOL().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
result.DnnAllMin = segments[0];
|
|
result.DnnLpdMin = segments[1];
|
|
result.DnnLpdNMin = segments[2];
|
|
result.DnnLpdESMin = segments[3];
|
|
result.DnnMicroScrMin = segments[4];
|
|
result.DnnScrMin = segments[5];
|
|
result.DnnSlipMin = segments[6];
|
|
result.DnnAreaCountMin = segments[7];
|
|
result.DnnAreaMin = segments[8];
|
|
result.DnnHazeAvgMin = segments[9];
|
|
result.DnnHazeMedianMin = segments[10];
|
|
result.DnnHazeStdDevMin = segments[11];
|
|
result.DnnBin1Min = segments[12];
|
|
result.DnnBin2Min = segments[13];
|
|
result.DnnBin3Min = segments[14];
|
|
result.DnnBin4Min = segments[15];
|
|
result.DnnBin5Min = segments[16];
|
|
result.DnnBin6Min = segments[17];
|
|
result.DnnBin7Min = segments[18];
|
|
result.DnnBin8Min = segments[19];
|
|
ScanPast("Max");
|
|
segments = GetToEOL().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
result.DnnAllMax = segments[0];
|
|
result.DnnLpdMax = segments[1];
|
|
result.DnnLpdNMax = segments[2];
|
|
result.DnnLpdESMax = segments[3];
|
|
result.DnnMicroScrMax = segments[4];
|
|
result.DnnScrMax = segments[5];
|
|
result.DnnSlipMax = segments[6];
|
|
result.DnnAreaCountMax = segments[7];
|
|
result.DnnAreaMax = segments[8];
|
|
result.DnnHazeAvgMax = segments[9];
|
|
result.DnnHazeMedianMax = segments[10];
|
|
result.DnnHazeStdDevMax = segments[11];
|
|
result.DnnBin1Max = segments[12];
|
|
result.DnnBin2Max = segments[13];
|
|
result.DnnBin3Max = segments[14];
|
|
result.DnnBin4Max = segments[15];
|
|
result.DnnBin5Max = segments[16];
|
|
result.DnnBin6Max = segments[17];
|
|
result.DnnBin7Max = segments[18];
|
|
result.DnnBin8Max = segments[19];
|
|
ScanPast("Mean");
|
|
segments = GetToEOL().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
result.DnnAllMean = segments[0];
|
|
result.DnnLpdMean = segments[1];
|
|
result.DnnLpdNMean = segments[2];
|
|
result.DnnLpdESMean = segments[3];
|
|
result.DnnMicroScrMean = segments[4];
|
|
result.DnnScrMean = segments[5];
|
|
result.DnnSlipMean = segments[6];
|
|
result.DnnAreaCountMean = segments[7];
|
|
result.DnnAreaMean = segments[8];
|
|
result.DnnHazeAvgMean = segments[9];
|
|
result.DnnHazeMedianMean = segments[10];
|
|
result.DnnHazeStdDevMean = segments[11];
|
|
result.DnnBin1Mean = segments[12];
|
|
result.DnnBin2Mean = segments[13];
|
|
result.DnnBin3Mean = segments[14];
|
|
result.DnnBin4Mean = segments[15];
|
|
result.DnnBin5Mean = segments[16];
|
|
result.DnnBin6Mean = segments[17];
|
|
result.DnnBin7Mean = segments[18];
|
|
result.DnnBin8Mean = segments[19];
|
|
ScanPast("Std. Dev.");
|
|
segments = GetToEOL().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
result.DnnAllStdDev = segments[0];
|
|
result.DnnLpdStdDev = segments[1];
|
|
result.DnnLpdNStdDev = segments[2];
|
|
result.DnnLpdESStdDev = segments[3];
|
|
result.DnnMicroScrStdDev = segments[4];
|
|
result.DnnScrStdDev = segments[5];
|
|
result.DnnSlipStdDev = segments[6];
|
|
result.DnnAreaCountStdDev = segments[7];
|
|
result.DnnAreaStdDev = segments[8];
|
|
result.DnnHazeAvgStdDev = segments[9];
|
|
result.DnnHazeMedianStdDev = segments[10];
|
|
result.DnnHazeStdDevStdDev = segments[11];
|
|
result.DnnBin1StdDev = segments[12];
|
|
result.DnnBin2StdDev = segments[13];
|
|
result.DnnBin3StdDev = segments[14];
|
|
result.DnnBin4StdDev = segments[15];
|
|
result.DnnBin5StdDev = segments[16];
|
|
result.DnnBin6StdDev = segments[17];
|
|
result.DnnBin7StdDev = segments[18];
|
|
result.DnnBin8StdDev = segments[19];
|
|
}
|
|
}
|
|
//result.UniqueID = string.Format("{0}_{1}_Summary_{2}", logic.Logistics.JobID, result.Lot, result.Date);
|
|
result.UniqueID = string.Format("{0}_{1}_{2}", logic.Logistics.JobID, result.Lot, Path.GetFileNameWithoutExtension(logic.Logistics.ReportFullPath));
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parse the wafer summary data
|
|
/// </summary>
|
|
/// <param name="headerFile">wafer data</param>
|
|
/// <param name="i">wafer index</param>
|
|
/// <returns></returns>
|
|
private DataFile ParseWaferSummary(HeaderFile headerFile, int i, List<WaferSummaryInfo> dcnTotals, List<WaferSummaryInfo> dwnTotals, List<WaferSummaryInfo> dnnTotals)
|
|
{
|
|
DataFile result = new DataFile()
|
|
{
|
|
// NOTE: get the UniqueID during DataCalculation in order to retrieve the SPCToolID from the cell component Tag field.
|
|
// id
|
|
//runData.UniqueID = string.Format("{0}_{1}", sp1Header.UniqueId, i + 1);
|
|
//runData.HeaderUniqueID = sp1Header.UniqueId;
|
|
|
|
// General Wafer Info
|
|
Side = dcnTotals[i].Side,
|
|
WaferID = dcnTotals[i].WaferID,
|
|
Grade = dcnTotals[i].Grade,
|
|
SrcDest = dcnTotals[i].SrcDest,
|
|
|
|
// Dcn Info
|
|
DcnAll = dcnTotals[i].All ?? string.Empty,
|
|
DcnLpd = dcnTotals[i].Lpd ?? string.Empty,
|
|
DcnLpdN = dcnTotals[i].LpdN ?? string.Empty,
|
|
DcnLpdES = dcnTotals[i].LpdES ?? string.Empty,
|
|
DcnMicroScr = dcnTotals[i].MicroScr ?? string.Empty,
|
|
DcnScr = dcnTotals[i].Scr ?? string.Empty,
|
|
DcnSlip = dcnTotals[i].Slip ?? string.Empty,
|
|
DcnAreaCount = dcnTotals[i].AreaNum ?? string.Empty,
|
|
DcnArea = dcnTotals[i].Area ?? string.Empty,
|
|
DcnHazeAvg = dcnTotals[i].HazeAvg ?? string.Empty,
|
|
DcnHazeMedian = dcnTotals[i].HazeMedian ?? string.Empty,
|
|
DcnHazeStdDev = dcnTotals[i].HazeStdDev ?? string.Empty,
|
|
DcnBin1 = dcnTotals[i].Bin1 ?? string.Empty,
|
|
DcnBin2 = dcnTotals[i].Bin2 ?? string.Empty,
|
|
DcnBin3 = dcnTotals[i].Bin3 ?? string.Empty,
|
|
DcnBin4 = dcnTotals[i].Bin4 ?? string.Empty,
|
|
DcnBin5 = dcnTotals[i].Bin5 ?? string.Empty,
|
|
DcnBin6 = dcnTotals[i].Bin6 ?? string.Empty,
|
|
DcnBin7 = dcnTotals[i].Bin7 ?? string.Empty,
|
|
DcnBin8 = dcnTotals[i].Bin8 ?? string.Empty,
|
|
|
|
// Dwn Info
|
|
DwnAll = dwnTotals[i].All ?? string.Empty,
|
|
DwnLpd = dwnTotals[i].Lpd ?? string.Empty,
|
|
DwnLpdN = dwnTotals[i].LpdN ?? string.Empty,
|
|
DwnLpdES = dwnTotals[i].LpdES ?? string.Empty,
|
|
DwnMicroScr = dwnTotals[i].MicroScr ?? string.Empty,
|
|
DwnScr = dwnTotals[i].Scr ?? string.Empty,
|
|
DwnSlip = dwnTotals[i].Slip ?? string.Empty,
|
|
DwnAreaCount = dwnTotals[i].AreaNum ?? string.Empty,
|
|
DwnArea = dwnTotals[i].Area ?? string.Empty,
|
|
DwnHazeAvg = dwnTotals[i].HazeAvg ?? string.Empty,
|
|
DwnHazeMedian = dwnTotals[i].HazeMedian ?? string.Empty,
|
|
DwnHazeStdDev = dwnTotals[i].HazeStdDev ?? string.Empty,
|
|
DwnBin1 = dwnTotals[i].Bin1 ?? string.Empty,
|
|
DwnBin2 = dwnTotals[i].Bin2 ?? string.Empty,
|
|
DwnBin3 = dwnTotals[i].Bin3 ?? string.Empty,
|
|
DwnBin4 = dwnTotals[i].Bin4 ?? string.Empty,
|
|
DwnBin5 = dwnTotals[i].Bin5 ?? string.Empty,
|
|
DwnBin6 = dwnTotals[i].Bin6 ?? string.Empty,
|
|
DwnBin7 = dwnTotals[i].Bin7 ?? string.Empty,
|
|
DwnBin8 = dwnTotals[i].Bin8 ?? string.Empty,
|
|
|
|
// Dnn Info
|
|
DnnAll = dnnTotals[i].All ?? string.Empty,
|
|
DnnLpd = dnnTotals[i].Lpd ?? string.Empty,
|
|
DnnLpdN = dnnTotals[i].LpdN ?? string.Empty,
|
|
DnnLpdES = dnnTotals[i].LpdES ?? string.Empty,
|
|
DnnMicroScr = dnnTotals[i].MicroScr ?? string.Empty,
|
|
DnnScr = dnnTotals[i].Scr ?? string.Empty,
|
|
DnnSlip = dnnTotals[i].Slip ?? string.Empty,
|
|
DnnAreaCount = dnnTotals[i].AreaNum ?? string.Empty,
|
|
DnnArea = dnnTotals[i].Area ?? string.Empty,
|
|
DnnHazeAvg = dnnTotals[i].HazeAvg ?? string.Empty,
|
|
DnnHazeMedian = dnnTotals[i].HazeMedian ?? string.Empty,
|
|
DnnHazeStdDev = dnnTotals[i].HazeStdDev ?? string.Empty,
|
|
DnnBin1 = dnnTotals[i].Bin1 ?? string.Empty,
|
|
DnnBin2 = dnnTotals[i].Bin2 ?? string.Empty,
|
|
DnnBin3 = dnnTotals[i].Bin3 ?? string.Empty,
|
|
DnnBin4 = dnnTotals[i].Bin4 ?? string.Empty,
|
|
DnnBin5 = dnnTotals[i].Bin5 ?? string.Empty,
|
|
DnnBin6 = dnnTotals[i].Bin6 ?? string.Empty,
|
|
DnnBin7 = dnnTotals[i].Bin7 ?? string.Empty,
|
|
DnnBin8 = dnnTotals[i].Bin8 ?? string.Empty
|
|
};
|
|
//result.HeaderUniqueID = string.Concat(headerFile.MesEntity, "_", headerFile.Lot, "_Summary_", headerFile.Date);
|
|
result.HeaderUniqueID = headerFile.UniqueID;
|
|
result.UniqueID = string.Concat(result.HeaderUniqueID, "_", result.WaferID.PadLeft(2, '0'));
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert the raw data file to parsable file format - in this case from PRN to PDF
|
|
/// </summary>
|
|
/// <param name="sourceFile">source file to be converted to PDF</param>
|
|
/// <returns></returns>
|
|
private static string ConvertSourceFileToPdf(ConfigData configData, string sourceFile)
|
|
{
|
|
string result = Path.ChangeExtension(sourceFile, ".pdf");
|
|
if (!File.Exists(result))
|
|
{
|
|
//string arguments = string.Concat("-i \"", sourceFile, "\" -o \"", result, "\"");
|
|
string arguments = string.Concat("-dSAFER -dBATCH -dNOPAUSE -sOutputFile=\"", result, "\" -sDEVICE=pdfwrite \"", sourceFile, "\"");
|
|
//Process process = Process.Start(configData.LincPDFCFileName, arguments);
|
|
Process process = Process.Start(configData.GhostPCLFileName, arguments);
|
|
process.WaitForExit(30000);
|
|
if (!File.Exists(result))
|
|
throw new Exception("PDF file wasn't created");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private Tuple<HeaderFile, List<DataFile>> Parse(ILogic logic, List<FileInfo> fileInfoCollection)
|
|
{
|
|
Tuple<HeaderFile, List<DataFile>> result;
|
|
DataFile dataFile;
|
|
HeaderFile headerFile;
|
|
foreach (string file in Directory.GetFiles(Path.GetDirectoryName(logic.Logistics.ReportFullPath), "WaferMap*.prn", SearchOption.TopDirectoryOnly))
|
|
fileInfoCollection.Add(new FileInfo(file));
|
|
List<WaferSummaryInfo> dcnTotals = new List<WaferSummaryInfo>();
|
|
List<WaferSummaryInfo> dwnTotals = new List<WaferSummaryInfo>();
|
|
List<WaferSummaryInfo> dnnTotals = new List<WaferSummaryInfo>();
|
|
headerFile = ParseHeader(logic, dcnTotals, dwnTotals, dnnTotals);
|
|
List<DataFile> details = new List<DataFile>();
|
|
_Log.Debug($"Number of wafers: {dcnTotals.Count}");
|
|
for (int i = 0; i < dcnTotals.Count; i++)
|
|
{
|
|
_Log.Debug($"****ParseData - Parsing wafer summary: {i}");
|
|
dataFile = ParseWaferSummary(headerFile, i, dcnTotals, dwnTotals, dnnTotals);
|
|
details.Add(dataFile);
|
|
}
|
|
fileInfoCollection.Add(new FileInfo(logic.Logistics.ReportFullPath));
|
|
result = new Tuple<HeaderFile, List<DataFile>>(headerFile, details);
|
|
return result;
|
|
}
|
|
|
|
}
|
|
|
|
} |