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 Details { get; private set; } private int _I; private readonly ILog _Log; private string _Data; public ProcessData(ILogic logic, ConfigData configData, List fileInfoCollection) { Header = null; fileInfoCollection.Clear(); _I = 0; _Data = string.Empty; _Log = LogManager.GetLogger(typeof(ProcessData)); Details = new List(); Tuple> tuple = Parse(logic, fileInfoCollection); Details.AddRange(tuple.Item2); Header = tuple.Item1; } public Tuple> GetResults(ILogic logic, ConfigDataBase configDataBase, List fileInfoCollection) { Tuple> results; if (!(configDataBase is ConfigData configData)) throw new Exception(); List tests = new List(); List 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 duplicatorDescriptions = (from l in descriptions select (Duplicator.Description)l).ToList(); json = JsonSerializer.Serialize(duplicatorDescriptions, duplicatorDescriptions.GetType()); } else if (descriptions[0] is FileRead.Description) { List fileReadDescriptions = (from l in descriptions select (FileRead.Description)l).ToList(); json = JsonSerializer.Serialize(fileReadDescriptions, fileReadDescriptions.GetType()); } else throw new Exception(); object @object = JsonSerializer.Deserialize(json); if (!(@object is JsonElement jsonElement)) throw new Exception(); results = new Tuple>(logic.Logistics.Logistics1[0], jsonElement, fileInfoCollection); return results; } public static Dictionary> GetKeyValuePairs(ConfigData configData, JsonElement jsonElement, List processDataDescriptions, bool extra = false) { Dictionary> results = configData.GetKeyValuePairs(processDataDescriptions); configData.CheckProcessDataDescription(results, extra); return results; } public static List GetProcessDataFileReadDescriptions(ConfigData configData, JsonElement jsonElement) { List results = new List(); List processDataDescriptions = configData.GetIProcessDataDescriptions(jsonElement); foreach (IProcessDataDescription processDataDescription in processDataDescriptions) { if (!(processDataDescription is FileRead.Description description)) continue; results.Add(description); } return results; } public static Tuple GetLines(ILogic logic, List 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(result.ToString(), x.Date); } internal static void PostOpenInsightMetrologyViewerAttachments(ILog log, ConfigData configData, Logistics logistics, DateTime dateTime, string logisticsSequenceMemoryDirectory, List 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(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 pdfFiles = new List(); 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 dataAttachments = new List(); List headerAttachments = new List { 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 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 dcnTotals, List dwnTotals, List 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; } /// /// Parse the wafer summary data /// /// wafer data /// wafer index /// private DataFile ParseWaferSummary(HeaderFile headerFile, int i, List dcnTotals, List dwnTotals, List 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; } /// /// Convert the raw data file to parsable file format - in this case from PRN to PDF /// /// source file to be converted to PDF /// 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> Parse(ILogic logic, List fileInfoCollection) { Tuple> 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 dcnTotals = new List(); List dwnTotals = new List(); List dnnTotals = new List(); headerFile = ParseHeader(logic, dcnTotals, dwnTotals, dnnTotals); List details = new List(); _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, details); return result; } } }