From 8e99879acdbaadd80b91f8b5ee5f87b85995c8c3 Mon Sep 17 00:00:00 2001 From: Mike Phares Date: Tue, 2 May 2023 10:46:36 -0700 Subject: [PATCH] FourteenPoint and json tool file --- Adaptation/FileHandlers/QS408M/Body.cs | 28 ++ Adaptation/FileHandlers/QS408M/Description.cs | 50 ++- Adaptation/FileHandlers/QS408M/FileRead.cs | 4 +- Adaptation/FileHandlers/QS408M/Footer.cs | 24 ++ Adaptation/FileHandlers/QS408M/Header.cs | 29 ++ Adaptation/FileHandlers/QS408M/ProcessData.cs | 372 ++++++------------ Adaptation/FileHandlers/QS408M/Site.cs | 24 ++ Adaptation/FileHandlers/QS408M/TXT.cs | 252 ++++++++++++ Adaptation/Shared/Test.cs | 3 +- .../_Tests/Extract/Staging/v2.49.0/BIORAD2.cs | 56 +++ Adaptation/_Tests/Static/MET08THFTIRQS408M.cs | 2 + Adaptation/_Tests/Static/QS408M.cs | 18 +- MET08THFTIRQS408M.csproj | 5 + 13 files changed, 589 insertions(+), 278 deletions(-) create mode 100644 Adaptation/FileHandlers/QS408M/Body.cs create mode 100644 Adaptation/FileHandlers/QS408M/Footer.cs create mode 100644 Adaptation/FileHandlers/QS408M/Header.cs create mode 100644 Adaptation/FileHandlers/QS408M/Site.cs create mode 100644 Adaptation/FileHandlers/QS408M/TXT.cs diff --git a/Adaptation/FileHandlers/QS408M/Body.cs b/Adaptation/FileHandlers/QS408M/Body.cs new file mode 100644 index 0000000..0deb2a7 --- /dev/null +++ b/Adaptation/FileHandlers/QS408M/Body.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; + +namespace Adaptation.FileHandlers.QS408M; + +public class Body +{ + + public List Sites { get; set; } + public string WaferMeanThickness { get; set; } + public string StdDev { get; set; } + public string PassFail { get; set; } + +} + +// Bio-Rad QS400MEPI Recipe: EP_8IN9PT Thu Apr 30 11:29:10 1970 +// operator: J batch: BIORAD#2 +// cassette: wafer: 52-589368-4445 +// -------------------------------------------------------------------------------- +// position thickness position thickness position thickness +// 1 45.735 2 46.536 3 46.742 +// 4 46.015 5 46.648 6 45.366 +// 7 46.263 8 46.512 9 46.373 +// wafer mean thickness = 46.2433, std. dev = 0.4564 PASS +// ================================================================================ + +// Radial variation (computation B) PASS: + +// thickness -2.7474 diff --git a/Adaptation/FileHandlers/QS408M/Description.cs b/Adaptation/FileHandlers/QS408M/Description.cs index 9104295..d304c29 100644 --- a/Adaptation/FileHandlers/QS408M/Description.cs +++ b/Adaptation/FileHandlers/QS408M/Description.cs @@ -46,9 +46,16 @@ public class Description : IDescription, Shared.Properties.IDescription public string StdDev { get; set; } public string Thickness { get; set; } // - public string CriticalPointsAverage { get; set; } - public string ThicknessSmile { get; set; } - public string CriticalPointsStdDev { get; set; } + public string SlotNumber { get; set; } + public string ThicknessFourteen3mmEdgeMean { get; set; } + public string ThicknessFourteen3mmEdgePercent { get; set; } + public string ThicknessFourteen5mmEdgeMean { get; set; } + public string ThicknessFourteen5mmEdgePercent { get; set; } + public string ThicknessFourteenCenterMean { get; set; } + public string ThicknessFourteenCriticalPointsAverage { get; set; } + public string ThicknessFourteenCriticalPointsStdDev { get; set; } + public string ThicknessFourteenMeanFrom { get; set; } + public string ThicknessFourteenPoints { get; set; } string IDescription.GetEventDescription() => "File Has been read and parsed"; @@ -111,9 +118,15 @@ public class Description : IDescription, Shared.Properties.IDescription nameof(RVThickness), nameof(StdDev), nameof(Thickness), - nameof(CriticalPointsAverage), - nameof(ThicknessSmile), - nameof(CriticalPointsStdDev), + nameof(ThicknessFourteen3mmEdgeMean), + nameof(ThicknessFourteen3mmEdgePercent), + nameof(ThicknessFourteen5mmEdgeMean), + nameof(ThicknessFourteen5mmEdgePercent), + nameof(ThicknessFourteenCenterMean), + nameof(ThicknessFourteenCriticalPointsAverage), + nameof(ThicknessFourteenCriticalPointsStdDev), + nameof(ThicknessFourteenMeanFrom), + nameof(ThicknessFourteenPoints), }; return results; } @@ -218,9 +231,16 @@ public class Description : IDescription, Shared.Properties.IDescription StdDev = processData.StdDev, Thickness = detail.Thickness, // - CriticalPointsAverage = string.Empty, - ThicknessSmile = string.Empty, - CriticalPointsStdDev = string.Empty, + SlotNumber = processData.SlotNumber, + ThicknessFourteen3mmEdgeMean = processData.ThicknessFourteen3mmEdgeMean, + ThicknessFourteen3mmEdgePercent = processData.ThicknessFourteen3mmEdgePercent, + ThicknessFourteen5mmEdgeMean = processData.ThicknessFourteen5mmEdgeMean, + ThicknessFourteen5mmEdgePercent = processData.ThicknessFourteen5mmEdgePercent, + ThicknessFourteenCenterMean = processData.ThicknessFourteenCenterMean, + ThicknessFourteenCriticalPointsAverage = processData.ThicknessFourteenCriticalPointsAverage, + ThicknessFourteenCriticalPointsStdDev = processData.ThicknessFourteenCriticalPointsStdDev, + ThicknessFourteenMeanFrom = processData.ThicknessFourteenMeanFrom, + ThicknessFourteenPoints = processData.ThicknessFourteenPoints, }; results.Add(description); } @@ -274,9 +294,15 @@ public class Description : IDescription, Shared.Properties.IDescription StdDev = nameof(StdDev), Thickness = nameof(Thickness), // - CriticalPointsAverage = nameof(CriticalPointsAverage), - ThicknessSmile = nameof(ThicknessSmile), - CriticalPointsStdDev = nameof(CriticalPointsStdDev), + ThicknessFourteen3mmEdgeMean = nameof(ThicknessFourteen3mmEdgeMean), + ThicknessFourteen3mmEdgePercent = nameof(ThicknessFourteen3mmEdgePercent), + ThicknessFourteen5mmEdgeMean = nameof(ThicknessFourteen5mmEdgeMean), + ThicknessFourteen5mmEdgePercent = nameof(ThicknessFourteen5mmEdgePercent), + ThicknessFourteenCenterMean = nameof(ThicknessFourteenCenterMean), + ThicknessFourteenCriticalPointsAverage = nameof(ThicknessFourteenCriticalPointsAverage), + ThicknessFourteenCriticalPointsStdDev = nameof(ThicknessFourteenCriticalPointsStdDev), + ThicknessFourteenMeanFrom = nameof(ThicknessFourteenMeanFrom), + ThicknessFourteenPoints = nameof(ThicknessFourteenPoints), }; return result; } diff --git a/Adaptation/FileHandlers/QS408M/FileRead.cs b/Adaptation/FileHandlers/QS408M/FileRead.cs index 51c494c..9692148 100644 --- a/Adaptation/FileHandlers/QS408M/FileRead.cs +++ b/Adaptation/FileHandlers/QS408M/FileRead.cs @@ -113,7 +113,9 @@ public class FileRead : Shared.FileRead, IFileRead if (iProcessData is not ProcessData processData) throw new Exception(string.Concat("A) No Data - ", dateTime.Ticks)); string mid; - if (!string.IsNullOrEmpty(processData.Employee) && string.IsNullOrEmpty(processData.Reactor) && string.IsNullOrEmpty(processData.RDS) && string.IsNullOrEmpty(processData.PSN)) + if (!string.IsNullOrEmpty(processData.Wafer) && string.IsNullOrEmpty(processData.Reactor) && string.IsNullOrEmpty(processData.RDS) && string.IsNullOrEmpty(processData.PSN)) + mid = processData.Wafer; + else if (!string.IsNullOrEmpty(processData.Employee) && string.IsNullOrEmpty(processData.Reactor) && string.IsNullOrEmpty(processData.RDS) && string.IsNullOrEmpty(processData.PSN)) mid = processData.Employee; else { diff --git a/Adaptation/FileHandlers/QS408M/Footer.cs b/Adaptation/FileHandlers/QS408M/Footer.cs new file mode 100644 index 0000000..b1e4cc8 --- /dev/null +++ b/Adaptation/FileHandlers/QS408M/Footer.cs @@ -0,0 +1,24 @@ +namespace Adaptation.FileHandlers.QS408M; + +public class Footer +{ + + public string Line { get; set; } + public string RadialVariationThickness { get; set; } + +} + +// Bio-Rad QS400MEPI Recipe: EP_8IN9PT Thu Apr 30 11:29:10 1970 +// operator: J batch: BIORAD#2 +// cassette: wafer: 52-589368-4445 +// -------------------------------------------------------------------------------- +// position thickness position thickness position thickness +// 1 45.735 2 46.536 3 46.742 +// 4 46.015 5 46.648 6 45.366 +// 7 46.263 8 46.512 9 46.373 +// wafer mean thickness = 46.2433, std. dev = 0.4564 PASS +// ================================================================================ + +// Radial variation (computation B) PASS: + +// thickness -2.7474 diff --git a/Adaptation/FileHandlers/QS408M/Header.cs b/Adaptation/FileHandlers/QS408M/Header.cs new file mode 100644 index 0000000..e84c145 --- /dev/null +++ b/Adaptation/FileHandlers/QS408M/Header.cs @@ -0,0 +1,29 @@ +namespace Adaptation.FileHandlers.QS408M; + +public class Header +{ + + public string Title { get; set; } + public string Recipe { get; set; } + public string DateTime { get; set; } + public string Operator { get; set; } + public string Batch { get; set; } + public string Cassette { get; set; } + public string Wafer { get; set; } + +} + +// Bio-Rad QS400MEPI Recipe: EP_8IN9PT Thu Apr 30 11:29:10 1970 +// operator: J batch: BIORAD#2 +// cassette: wafer: 52-589368-4445 +// -------------------------------------------------------------------------------- +// position thickness position thickness position thickness +// 1 45.735 2 46.536 3 46.742 +// 4 46.015 5 46.648 6 45.366 +// 7 46.263 8 46.512 9 46.373 +// wafer mean thickness = 46.2433, std. dev = 0.4564 PASS +// ================================================================================ + +// Radial variation (computation B) PASS: + +// thickness -2.7474 diff --git a/Adaptation/FileHandlers/QS408M/ProcessData.cs b/Adaptation/FileHandlers/QS408M/ProcessData.cs index 3ad8ca8..7464c48 100644 --- a/Adaptation/FileHandlers/QS408M/ProcessData.cs +++ b/Adaptation/FileHandlers/QS408M/ProcessData.cs @@ -38,11 +38,20 @@ public partial class ProcessData : IProcessData public string UniqueId { get; set; } public string Wafer { get; set; } public string Zone { get; set; } + // + public string SlotNumber { get; set; } + public string ThicknessFourteen3mmEdgeMean { get; set; } + public string ThicknessFourteen3mmEdgePercent { get; set; } + public string ThicknessFourteen5mmEdgeMean { get; set; } + public string ThicknessFourteen5mmEdgePercent { get; set; } + public string ThicknessFourteenCenterMean { get; set; } + public string ThicknessFourteenCriticalPointsAverage { get; set; } + public string ThicknessFourteenCriticalPointsStdDev { get; set; } + public string ThicknessFourteenMeanFrom { get; set; } + public string ThicknessFourteenPoints { get; set; } List Shared.Properties.IProcessData.Details => _Details; - private int _I; - private string _Data; private readonly ILog _Log; public ProcessData() @@ -56,7 +65,9 @@ public partial class ProcessData : IProcessData _Details = new List(); MesEntity = logistics.MesEntity; _Log = LogManager.GetLogger(typeof(ProcessData)); - Parse(fileRead, logistics, fileInfoCollection, originalDataBioRad, lastProcessData, tickOffset); + TXT txt = Parse(fileRead, logistics, fileInfoCollection, originalDataBioRad); + if (txt is not null) + SetValues(fileRead, logistics, fileInfoCollection, originalDataBioRad, lastProcessData, tickOffset, txt); } string IProcessData.GetCurrentReactor(IFileRead fileRead, Logistics logistics, Dictionary reactors) => throw new Exception(string.Concat("See ", nameof(Parse))); @@ -84,154 +95,6 @@ public partial class ProcessData : IProcessData return results; } - private string GetBefore(string text) - { - string str; - string str1; - int num = _Data.IndexOf(text, _I); - if (num <= -1) - { - str = _Data.Substring(_I); - _I = _Data.Length; - str1 = str.Trim(); - } - else - { - str = _Data.Substring(_I, num - _I); - _I = num + text.Length; - str1 = str.Trim(); - } - return str1; - } - - private string GetBefore(string text, bool trim) - { - string str; - string before; - if (!trim) - { - int num = _Data.IndexOf(text, _I); - if (num <= -1) - { - str = _Data.Substring(_I); - _I = _Data.Length; - before = str; - } - else - { - str = _Data.Substring(_I, num - _I); - _I = num + text.Length; - before = str; - } - } - else - { - before = GetBefore(text); - } - return before; - } - - private string GetToEOL() - { - string result; - if (_Data.IndexOf("\n", _I) > -1) - result = GetBefore("\n"); - else - result = GetBefore(Environment.NewLine); - return result; - } - - private string GetToEOL(bool trim) - { - string str; - if (_Data.IndexOf("\n", _I) > -1) - str = !trim ? GetBefore("\n", false) : GetToEOL(); - else - str = !trim ? GetBefore(Environment.NewLine, false) : GetToEOL(); - return str; - } - - private string GetToken() - { - while (true) - { - if (_I >= _Data.Length || !IsNullOrWhiteSpace(_Data.Substring(_I, 1))) - { - break; - } - _I++; - } - int num = _I; - while (true) - { - if (num >= _Data.Length || IsNullOrWhiteSpace(_Data.Substring(num, 1))) - { - break; - } - num++; - } - string str = _Data.Substring(_I, num - _I); - _I = num; - return str.Trim(); - } - - private string GetToText(string text) - { - string str = _Data.Substring(_I, _Data.IndexOf(text, _I) - _I).Trim(); - return str; - } - - private bool IsBlankLine() - { - int num = _Data.IndexOf("\n", _I); - return IsNullOrWhiteSpace(num > -1 ? _Data.Substring(_I, num - _I) : _Data.Substring(_I)); - } - - private static bool IsNullOrWhiteSpace(string text) - { - bool flag; - int num = 0; - while (true) - { - if (num >= text.Length) - { - flag = true; - break; - } - else if (char.IsWhiteSpace(text[num])) - { - num++; - } - else - { - flag = false; - break; - } - } - return flag; - } - - private string PeekNextLine() - { - int num = _I; - string toEOL = GetToEOL(); - _I = num; - return toEOL; - } - - private void ScanPast(string text) - { - int num = _Data.IndexOf(text, _I); - if (num <= -1) - { - _I = _Data.Length; - } - else - { - _I = num + text.Length; - } - } - internal static DateTime GetDateTime(Logistics logistics, long tickOffset, string dateTimeText) { DateTime result; @@ -328,7 +191,7 @@ public partial class ProcessData : IProcessData string defaultLayer = string.Empty; string defaultReactor = string.Empty; string defaultEmployee = string.Empty; - if (Regex.IsMatch(text, @"^[a-zA-z][0-9]{4}$")) + if (Regex.IsMatch(text, @"^[a-zA-z][0-9]{2,4}$")) { wafer = text.ToUpper(); psn = defaultPSN; @@ -382,45 +245,30 @@ public partial class ProcessData : IProcessData return result; } - private void Set(Logistics logistics, ProcessData lastProcessData, long tickOffset, string receivedData) +#pragma warning disable IDE0060 + private void SetValues(IFileRead fileRead, Logistics logistics, List fileInfoCollection, string originalDataBioRad, ProcessData lastProcessData, long tickOffset, TXT txt) +#pragma warning restore IDE0060 { string psn; string rds; string zone; - string batch; string layer; - string title; string wafer; - DateTime date; - string recipe; + Detail detail; string reactor; - string cassette; - string employee; - title = GetBefore("Recipe:"); - recipe = GetToken(); - string dateTimeText = GetToEOL(); - if (dateTimeText.EndsWith(".")) - dateTimeText = dateTimeText.Remove(dateTimeText.Length - 1, 1); - date = GetDateTime(logistics, tickOffset, dateTimeText); - ScanPast("operator:"); - employee = GetBefore("batch:"); - batch = GetToEOL(); + int counter = 1; + int slotNumber = 0; + List details = new(); + StringBuilder titleFixed = new(); + StringBuilder waferFixed = new(); + string recipe = txt.Header.Recipe; + string cassette = txt.Header.Cassette; + string employee = txt.Header.Operator; + DateTime dateTime = GetDateTime(logistics, tickOffset, txt.Header.DateTime); // Remove illegal characters \/:*?"<>| found in the Batch - batch = Regex.Replace(batch, @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]", "_").Split('\r')[0].Split('\n')[0]; - ScanPast("cassette:"); - cassette = GetBefore("wafer:"); - if (string.IsNullOrEmpty(batch)) - { - _I = 0; - _Data = receivedData; - ScanPast("wafer:"); - } - wafer = GetToEOL(); - _ = GetToEOL(); - _ = GetToEOL(); - if (string.IsNullOrEmpty(wafer)) - throw new Exception("Wafer field is missing."); - Descriptor descriptor = GetDescriptor(wafer); + string batch = Regex.Replace(txt.Header.Batch, @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]", "_").Split('\r')[0].Split('\n')[0]; + bool isWaferSlot = !string.IsNullOrEmpty(txt.Header.Wafer) && txt.Header.Wafer.Length is 1 or 2 && int.TryParse(txt.Header.Wafer, out slotNumber); + Descriptor descriptor = isWaferSlot ? GetDescriptor(txt.Header.Batch) : GetDescriptor(txt.Header.Wafer); psn = descriptor.PSN; rds = descriptor.RDS; zone = descriptor.Zone; @@ -429,6 +277,16 @@ public partial class ProcessData : IProcessData reactor = descriptor.Reactor; if (string.IsNullOrEmpty(employee)) employee = descriptor.Employee; + foreach (char c in txt.Header.Title) + { + if (char.IsLetterOrDigit(c) || c == '-' || c == '.') + _ = titleFixed.Append(c); + } + foreach (char c in wafer) + { + if (char.IsLetterOrDigit(c) || c == '-' || c == '.') + _ = waferFixed.Append(c); + } if (string.IsNullOrEmpty(lastProcessData.Wafer)) { lastProcessData.Batch = JobID; @@ -457,27 +315,14 @@ public partial class ProcessData : IProcessData recipe = lastProcessData.Recipe; else lastProcessData.Recipe = recipe; - if (string.IsNullOrEmpty(title) || title.Contains(check)) - title = lastProcessData.Title; + if (string.IsNullOrEmpty(txt.Header.Title) || txt.Header.Title.Contains(check)) + titleFixed = new(lastProcessData.Title); else - lastProcessData.Title = title; - //fix title - StringBuilder titleFixed = new(); - foreach (char c in title) - { - if (char.IsLetterOrDigit(c) || c == '-' || c == '.') - _ = titleFixed.Append(c); - } - //fix wafer - StringBuilder waferFixed = new(); - foreach (char c in wafer) - { - if (char.IsLetterOrDigit(c) || c == '-' || c == '.') - _ = waferFixed.Append(c); - } + lastProcessData.Title = titleFixed.ToString(); + string uniqueId = string.Concat(titleFixed, '_', waferFixed, '_', logistics.DateTimeFromSequence.ToString("yyyyMMddHHmmssffff"), '_', logistics.TotalSecondsSinceLastWriteTimeFromSequence); PSN = psn; RDS = rds; - Date = date; + Date = dateTime; Zone = zone; Batch = batch; Layer = layer; @@ -486,81 +331,52 @@ public partial class ProcessData : IProcessData Cassette = cassette; Employee = employee; JobID = logistics.JobID; + UniqueId = uniqueId; Title = titleFixed.ToString(); Wafer = waferFixed.ToString(); - UniqueId = string.Concat(title, '_', wafer, '_', logistics.DateTimeFromSequence.ToString("yyyyMMddHHmmssffff"), '_', logistics.TotalSecondsSinceLastWriteTimeFromSequence); + SlotNumber = slotNumber.ToString("00"); + foreach (Site site in txt.Body.Sites) + { + detail = new() + { + Position = site.Position, + HeaderUniqueId = uniqueId, + Thickness = site.Thickness, + UniqueId = string.Concat(uniqueId, "_Point-", counter) + }; + details.Add(detail); + counter++; + } + PopulateCalculated(details); + _Details.AddRange(details); } #pragma warning disable IDE0060 - private void Parse(IFileRead fileRead, Logistics logistics, List fileInfoCollection, string originalDataBioRad, ProcessData lastProcessData, long tickOffset) + private static TXT Parse(IFileRead fileRead, Logistics logistics, List fileInfoCollection, string originalDataBioRad) #pragma warning restore IDE0060 { - _I = 0; - _Data = string.Empty; - List details = new(); - string receivedData = File.ReadAllText(logistics.ReportFullPath); - _Log.Debug($"****ParseData - Source file contents:"); - _Log.Debug(receivedData); + TXT result; string[] files = Directory.GetFiles(Path.GetDirectoryName(logistics.ReportFullPath), string.Concat(originalDataBioRad, logistics.Sequence, "*"), SearchOption.TopDirectoryOnly); foreach (string file in files) fileInfoCollection.Add(new FileInfo(file)); - // occasionally there are multiple blocks of results, get the last one as earlier ones may be aborted runs. + string receivedData = File.ReadAllText(logistics.ReportFullPath); + // occasionally there are multiple blocks of details, get the last one as earlier ones may be aborted runs. int index = receivedData.LastIndexOf("Bio-Rad"); if (index > -1) receivedData = receivedData.Substring(index); - _Log.Debug($"****ParseData - Source file contents to be parsed:"); - _Log.Debug(receivedData); - if (!string.IsNullOrEmpty(receivedData)) + if (string.IsNullOrEmpty(receivedData)) + result = null; + else { - _I = 0; - _Data = receivedData; - Set(logistics, lastProcessData, tickOffset, receivedData); - string token = GetToken(); - int counter = 1; - while (true) - { - if (string.IsNullOrEmpty(token) || !char.IsDigit(token[0])) - break; - Detail detail = new() - { - Position = token, - Thickness = GetToken(), - UniqueId = string.Concat("_Point-", counter) - }; - details.Add(detail); - token = GetToken(); - counter++; - } - ScanPast("mean thickness ="); - MeanThickness = GetBefore(", std. dev ="); - StdDev = GetToken(); - PassFail = GetToEOL(); - ScanPast("thickness"); - RVThickness = GetToEOL(); + result = new TXT(receivedData); + string directory = Path.GetDirectoryName(logistics.ReportFullPath); + string fileName = Path.Combine(directory, $"{Path.GetFileNameWithoutExtension(logistics.ReportFullPath)}.json"); + string json = JsonSerializer.Serialize(result, new JsonSerializerOptions { WriteIndented = true }); + File.WriteAllText(fileName, json); + fileInfoCollection.Add(new(fileName)); } - foreach (Detail detail in details) - { - detail.HeaderUniqueId = UniqueId; - detail.UniqueId = string.Concat(UniqueId, detail.UniqueId); - } - - //trace datatype - _Log.Debug("BioRad parsed information:"); - _Log.Debug(string.Format("Batch: {0}", Batch)); - _Log.Debug(string.Format("Cassette: {0}", Cassette)); - _Log.Debug(string.Format("Date: {0}", Date)); - foreach (Detail bioRadDetail in details) - _Log.Debug(string.Format("Details: {0} - {1}", bioRadDetail.Position, bioRadDetail.Thickness)); - _Log.Debug(string.Format("Mean Thickness: {0}", MeanThickness)); - _Log.Debug(string.Format("Operator: {0}", Employee)); - _Log.Debug(string.Format("Pass/Fail: {0}", PassFail)); - _Log.Debug(string.Format("Recipe: {0}", Recipe)); - _Log.Debug(string.Format("RV Thickness: {0}", RVThickness)); - _Log.Debug(string.Format("Std Dev: {0}", StdDev)); - _Log.Debug(string.Format("Title: {0}", Title)); - _Log.Debug(string.Format("Wafer: {0}", Wafer)); fileInfoCollection.Add(logistics.FileInfo); - _Details.AddRange(details); + return result; } #nullable enable @@ -582,4 +398,40 @@ public partial class ProcessData : IProcessData return results; } + private void PopulateCalculated(List details) + { + List thicknessPoints = new(); + foreach (Detail bioRadDetail in details) + { + if (!double.TryParse(bioRadDetail.Thickness, out double thickness)) + thicknessPoints.Add(0); + else + thicknessPoints.Add(thickness); + } + if (thicknessPoints.Count != 14) + { + ThicknessFourteenPoints = string.Empty; + ThicknessFourteenMeanFrom = string.Empty; + ThicknessFourteenCenterMean = string.Empty; + ThicknessFourteen3mmEdgeMean = string.Empty; + ThicknessFourteen5mmEdgeMean = string.Empty; + ThicknessFourteen3mmEdgePercent = string.Empty; + ThicknessFourteen5mmEdgePercent = string.Empty; + ThicknessFourteenCriticalPointsStdDev = string.Empty; + ThicknessFourteenCriticalPointsAverage = string.Empty; + } + else + { + ThicknessFourteenPoints = string.Join(",", thicknessPoints); + ThicknessFourteenCenterMean = thicknessPoints[4].ToString("0.0000000"); + ThicknessFourteen5mmEdgeMean = ((thicknessPoints[0] + thicknessPoints[9]) / 2.0).ToString("0.0000000"); + ThicknessFourteenMeanFrom = ((thicknessPoints[1] + thicknessPoints[2] + thicknessPoints[7]) / 3.0).ToString("0.0000000"); + ThicknessFourteen3mmEdgeMean = ((thicknessPoints[10] + thicknessPoints[11] + thicknessPoints[12] + thicknessPoints[13]) / 4).ToString("0.0000000"); + ThicknessFourteen5mmEdgePercent = ((((thicknessPoints[0] + thicknessPoints[9]) / 2.0) - ((thicknessPoints[1] + thicknessPoints[2] + thicknessPoints[7]) / 3.0)) / ((thicknessPoints[1] + thicknessPoints[2] + thicknessPoints[7]) / 3.0) * 100.0).ToString("0.0000000"); + ThicknessFourteenCriticalPointsAverage = ((thicknessPoints[0] + thicknessPoints[1] + thicknessPoints[2] + thicknessPoints[3] + thicknessPoints[4] + thicknessPoints[5] + thicknessPoints[6] + thicknessPoints[7] + thicknessPoints[8] + thicknessPoints[9]) / 10.0).ToString("0.0000000"); + ThicknessFourteen3mmEdgePercent = ((((thicknessPoints[10] + thicknessPoints[11] + thicknessPoints[12] + thicknessPoints[13]) / 4.0) - ((thicknessPoints[1] + thicknessPoints[2] + thicknessPoints[7]) / 3.0)) / ((thicknessPoints[1] + thicknessPoints[2] + thicknessPoints[7]) / 3.0) * 100.0).ToString("0.0000000"); + ThicknessFourteenCriticalPointsStdDev = Math.Sqrt((Math.Pow(thicknessPoints[0] - ((thicknessPoints[0] + thicknessPoints[1] + thicknessPoints[2] + thicknessPoints[3] + thicknessPoints[4] + thicknessPoints[5] + thicknessPoints[6] + thicknessPoints[7] + thicknessPoints[8] + thicknessPoints[9]) / 10.0), 2) + Math.Pow(thicknessPoints[1] - ((thicknessPoints[0] + thicknessPoints[1] + thicknessPoints[2] + thicknessPoints[3] + thicknessPoints[4] + thicknessPoints[5] + thicknessPoints[6] + thicknessPoints[7] + thicknessPoints[8] + thicknessPoints[9]) / 10.0), 2) + Math.Pow(thicknessPoints[2] - ((thicknessPoints[0] + thicknessPoints[1] + thicknessPoints[2] + thicknessPoints[3] + thicknessPoints[4] + thicknessPoints[5] + thicknessPoints[6] + thicknessPoints[7] + thicknessPoints[8] + thicknessPoints[9]) / 10.0), 2) + Math.Pow(thicknessPoints[3] - ((thicknessPoints[0] + thicknessPoints[1] + thicknessPoints[2] + thicknessPoints[3] + thicknessPoints[4] + thicknessPoints[5] + thicknessPoints[6] + thicknessPoints[7] + thicknessPoints[8] + thicknessPoints[9]) / 10.0), 2) + Math.Pow(thicknessPoints[4] - ((thicknessPoints[0] + thicknessPoints[1] + thicknessPoints[2] + thicknessPoints[3] + thicknessPoints[4] + thicknessPoints[5] + thicknessPoints[6] + thicknessPoints[7] + thicknessPoints[8] + thicknessPoints[9]) / 10.0), 2) + Math.Pow(thicknessPoints[5] - ((thicknessPoints[0] + thicknessPoints[1] + thicknessPoints[2] + thicknessPoints[3] + thicknessPoints[4] + thicknessPoints[5] + thicknessPoints[6] + thicknessPoints[7] + thicknessPoints[8] + thicknessPoints[9]) / 10.0), 2) + Math.Pow(thicknessPoints[6] - ((thicknessPoints[0] + thicknessPoints[1] + thicknessPoints[2] + thicknessPoints[3] + thicknessPoints[4] + thicknessPoints[5] + thicknessPoints[6] + thicknessPoints[7] + thicknessPoints[8] + thicknessPoints[9]) / 10.0), 2) + Math.Pow(thicknessPoints[7] - ((thicknessPoints[0] + thicknessPoints[1] + thicknessPoints[2] + thicknessPoints[3] + thicknessPoints[4] + thicknessPoints[5] + thicknessPoints[6] + thicknessPoints[7] + thicknessPoints[8] + thicknessPoints[9]) / 10.0), 2) + Math.Pow(thicknessPoints[8] - ((thicknessPoints[0] + thicknessPoints[1] + thicknessPoints[2] + thicknessPoints[3] + thicknessPoints[4] + thicknessPoints[5] + thicknessPoints[6] + thicknessPoints[7] + thicknessPoints[8] + thicknessPoints[9]) / 10.0), 2) + Math.Pow(thicknessPoints[9] - ((thicknessPoints[0] + thicknessPoints[1] + thicknessPoints[2] + thicknessPoints[3] + thicknessPoints[4] + thicknessPoints[5] + thicknessPoints[6] + thicknessPoints[7] + thicknessPoints[8] + thicknessPoints[9]) / 10.0), 2)) / 9.0).ToString("0.0000000"); + } + } + } \ No newline at end of file diff --git a/Adaptation/FileHandlers/QS408M/Site.cs b/Adaptation/FileHandlers/QS408M/Site.cs new file mode 100644 index 0000000..fd2ac64 --- /dev/null +++ b/Adaptation/FileHandlers/QS408M/Site.cs @@ -0,0 +1,24 @@ +namespace Adaptation.FileHandlers.QS408M; + +public class Site +{ + + public string Position { get; set; } + public string Thickness { get; set; } + +} + +// Bio-Rad QS400MEPI Recipe: EP_8IN9PT Thu Apr 30 11:29:10 1970 +// operator: J batch: BIORAD#2 +// cassette: wafer: 52-589368-4445 +// -------------------------------------------------------------------------------- +// position thickness position thickness position thickness +// 1 45.735 2 46.536 3 46.742 +// 4 46.015 5 46.648 6 45.366 +// 7 46.263 8 46.512 9 46.373 +// wafer mean thickness = 46.2433, std. dev = 0.4564 PASS +// ================================================================================ + +// Radial variation (computation B) PASS: + +// thickness -2.7474 diff --git a/Adaptation/FileHandlers/QS408M/TXT.cs b/Adaptation/FileHandlers/QS408M/TXT.cs new file mode 100644 index 0000000..f31d2e3 --- /dev/null +++ b/Adaptation/FileHandlers/QS408M/TXT.cs @@ -0,0 +1,252 @@ +using System; +using System.Collections.Generic; + +namespace Adaptation.FileHandlers.QS408M; + +public class TXT +{ + + public Header Header { get; set; } + public Body Body { get; set; } + public Footer Footer { get; set; } + + private int _I; + private readonly string _Data; + + public TXT(string receivedData) + { + _I = 0; + Site site; + _Data = receivedData; + List sites = new(); + string title = GetBefore("Recipe:"); + string recipe = GetToken(); + string dateTime = GetToEOL(); + if (dateTime.EndsWith(".")) + dateTime = dateTime.Remove(dateTime.Length - 1, 1); + ScanPast("operator:"); + string @operator = GetBefore("batch:"); + string batch = GetToEOL(); + ScanPast("cassette:"); + string cassette = GetBefore("wafer:"); + if (string.IsNullOrEmpty(batch)) + { + _I = 0; + _Data = receivedData; + ScanPast("wafer:"); + } + string wafer = GetToEOL(); + _ = GetToEOL(); + _ = GetToEOL(); + if (string.IsNullOrEmpty(wafer)) + throw new Exception("Wafer field is missing."); + string token = GetToken(); + while (true) + { + if (string.IsNullOrEmpty(token) || !char.IsDigit(token[0])) + break; + site = new() + { + Position = token, + Thickness = GetToken(), + }; + sites.Add(site); + token = GetToken(); + } + ScanPast("mean thickness ="); + string meanThickness = GetBefore(", std. dev ="); + string stdDev = GetToken(); + string passFail = GetToEOL(); + _ = GetToEOL(); + _ = GetToEOL(); + string line = GetToEOL(); + ScanPast("thickness"); + string radialVariationThickness = GetToEOL(); + Header = new() + { + Title = title, + Recipe = recipe, + DateTime = dateTime, + Operator = @operator, + Batch = batch, + Cassette = cassette, + Wafer = wafer, + }; + Body = new() + { + Sites = sites, + WaferMeanThickness = meanThickness, + StdDev = stdDev, + PassFail = passFail, + }; + Footer = new() + { + Line = line, + RadialVariationThickness = radialVariationThickness, + }; + } + + private string GetBefore(string text) + { + string str; + string str1; + int num = _Data.IndexOf(text, _I); + if (num <= -1) + { + str = _Data.Substring(_I); + _I = _Data.Length; + str1 = str.Trim(); + } + else + { + str = _Data.Substring(_I, num - _I); + _I = num + text.Length; + str1 = str.Trim(); + } + return str1; + } + + private string GetBefore(string text, bool trim) + { + string str; + string before; + if (!trim) + { + int num = _Data.IndexOf(text, _I); + if (num <= -1) + { + str = _Data.Substring(_I); + _I = _Data.Length; + before = str; + } + else + { + str = _Data.Substring(_I, num - _I); + _I = num + text.Length; + before = str; + } + } + else + { + before = GetBefore(text); + } + return before; + } + + private string GetToEOL() + { + string result; + if (_Data.IndexOf("\n", _I) > -1) + result = GetBefore("\n"); + else + result = GetBefore(Environment.NewLine); + return result; + } + + private string GetToEOL(bool trim) + { + string str; + if (_Data.IndexOf("\n", _I) > -1) + str = !trim ? GetBefore("\n", false) : GetToEOL(); + else + str = !trim ? GetBefore(Environment.NewLine, false) : GetToEOL(); + return str; + } + + private string GetToken() + { + while (true) + { + if (_I >= _Data.Length || !IsNullOrWhiteSpace(_Data.Substring(_I, 1))) + { + break; + } + _I++; + } + int num = _I; + while (true) + { + if (num >= _Data.Length || IsNullOrWhiteSpace(_Data.Substring(num, 1))) + { + break; + } + num++; + } + string str = _Data.Substring(_I, num - _I); + _I = num; + return str.Trim(); + } + + private string GetToText(string text) + { + string str = _Data.Substring(_I, _Data.IndexOf(text, _I) - _I).Trim(); + return str; + } + + private bool IsBlankLine() + { + int num = _Data.IndexOf("\n", _I); + return IsNullOrWhiteSpace(num > -1 ? _Data.Substring(_I, num - _I) : _Data.Substring(_I)); + } + + private static bool IsNullOrWhiteSpace(string text) + { + bool flag; + int num = 0; + while (true) + { + if (num >= text.Length) + { + flag = true; + break; + } + else if (char.IsWhiteSpace(text[num])) + { + num++; + } + else + { + flag = false; + break; + } + } + return flag; + } + + private string PeekNextLine() + { + int num = _I; + string toEOL = GetToEOL(); + _I = num; + return toEOL; + } + + private void ScanPast(string text) + { + int num = _Data.IndexOf(text, _I); + if (num <= -1) + { + _I = _Data.Length; + } + else + { + _I = num + text.Length; + } + } + +} + +// Bio-Rad QS400MEPI Recipe: EP_8IN9PT Thu Apr 30 11:29:10 1970 +// operator: J batch: BIORAD#2 +// cassette: wafer: 52-589368-4445 +// -------------------------------------------------------------------------------- +// position thickness position thickness position thickness +// 1 45.735 2 46.536 3 46.742 +// 4 46.015 5 46.648 6 45.366 +// 7 46.263 8 46.512 9 46.373 +// wafer mean thickness = 46.2433, std. dev = 0.4564 PASS +// ================================================================================ + +// Radial variation (computation B) PASS: + +// thickness -2.7474 diff --git a/Adaptation/Shared/Test.cs b/Adaptation/Shared/Test.cs index aeb4bea..3aa3552 100644 --- a/Adaptation/Shared/Test.cs +++ b/Adaptation/Shared/Test.cs @@ -21,7 +21,7 @@ public enum Test Denton = 9, DiffusionLength = 45, GRATXTCenter = 51, - GRATXTEdge = 52, //Largest + GRATXTEdge = 52, GrowthRateXML = 50, Hall = 10, HgCV = 23, @@ -38,6 +38,7 @@ public enum Test RPMPLRatio = 17, RPMXY = 15, SP1 = 8, + SRP2100 = 53, //Largest Tencor = 7, UV = 35, VerificationLehighton = 14, diff --git a/Adaptation/_Tests/Extract/Staging/v2.49.0/BIORAD2.cs b/Adaptation/_Tests/Extract/Staging/v2.49.0/BIORAD2.cs index 102eb2f..f020ac6 100644 --- a/Adaptation/_Tests/Extract/Staging/v2.49.0/BIORAD2.cs +++ b/Adaptation/_Tests/Extract/Staging/v2.49.0/BIORAD2.cs @@ -1,4 +1,9 @@ +using Adaptation.Shared; +using Adaptation.Shared.Methods; using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Diagnostics; +using System.Reflection; namespace Adaptation._Tests.Extract.Staging.v2_49_0; @@ -18,10 +23,61 @@ public class BIORAD2 _BIORAD2 = CreateSelfDescription.Staging.v2_49_0.BIORAD2.EAFLoggingUnitTesting; } + private static void NonThrowTryCatch() + { + try + { throw new Exception(); } + catch (Exception) { } + } + #if DEBUG [Ignore] #endif [TestMethod] public void Staging__v2_49_0__BIORAD2__QS408M() => _BIORAD2.Staging__v2_49_0__BIORAD2__QS408M(); +#if DEBUG + [Ignore] +#endif + [TestMethod] + public void Staging__v2_49_0__BIORAD2__QS408M638185231662401081__NinePoint() + { + DateTime dateTime; + string check = "*.txt"; + bool validatePDSF = false; + _BIORAD2.Staging__v2_49_0__BIORAD2__QS408M(); + MethodBase methodBase = new StackFrame().GetMethod(); + string[] variables = _BIORAD2.AdaptationTesting.GetVariables(methodBase, check, validatePDSF); + IFileRead fileRead = _BIORAD2.AdaptationTesting.Get(methodBase, sourceFileLocation: variables[2], sourceFileFilter: variables[3], useCyclicalForDescription: false); + Logistics logistics = new(fileRead); + dateTime = FileHandlers.QS408M.ProcessData.GetDateTime(logistics, tickOffset: 0, dateTimeText: string.Empty); + Assert.IsTrue(dateTime == logistics.DateTimeFromSequence); + dateTime = FileHandlers.QS408M.ProcessData.GetDateTime(logistics, tickOffset: 0, dateTimeText: "Tue Nov 10 12:03:56 1970"); + Assert.IsTrue(dateTime == logistics.DateTimeFromSequence); + _ = Shared.AdaptationTesting.ReExtractCompareUpdatePassDirectory(variables, fileRead, logistics, validatePDSF); + NonThrowTryCatch(); + } + +#if DEBUG + [Ignore] +#endif + [TestMethod] + public void Staging__v2_49_0__BIORAD2__QS408M638185291035612698__FourteenPoint() + { + DateTime dateTime; + string check = "*.txt"; + bool validatePDSF = false; + _BIORAD2.Staging__v2_49_0__BIORAD2__QS408M(); + MethodBase methodBase = new StackFrame().GetMethod(); + string[] variables = _BIORAD2.AdaptationTesting.GetVariables(methodBase, check, validatePDSF); + IFileRead fileRead = _BIORAD2.AdaptationTesting.Get(methodBase, sourceFileLocation: variables[2], sourceFileFilter: variables[3], useCyclicalForDescription: false); + Logistics logistics = new(fileRead); + dateTime = FileHandlers.QS408M.ProcessData.GetDateTime(logistics, tickOffset: 0, dateTimeText: string.Empty); + Assert.IsTrue(dateTime == logistics.DateTimeFromSequence); + dateTime = FileHandlers.QS408M.ProcessData.GetDateTime(logistics, tickOffset: 0, dateTimeText: "Tue Nov 10 12:03:56 1970"); + Assert.IsTrue(dateTime == logistics.DateTimeFromSequence); + _ = Shared.AdaptationTesting.ReExtractCompareUpdatePassDirectory(variables, fileRead, logistics, validatePDSF); + NonThrowTryCatch(); + } + } \ No newline at end of file diff --git a/Adaptation/_Tests/Static/MET08THFTIRQS408M.cs b/Adaptation/_Tests/Static/MET08THFTIRQS408M.cs index ab225f9..a296087 100644 --- a/Adaptation/_Tests/Static/MET08THFTIRQS408M.cs +++ b/Adaptation/_Tests/Static/MET08THFTIRQS408M.cs @@ -45,7 +45,9 @@ public class MET08THFTIRQS408M : LoggingUnitTesting, IDisposable Assert.IsTrue(dateTime.ToString("M/d/yyyy h:mm:ss tt") == dateTime.ToString()); } +#if DEBUG [Ignore] +#endif [TestMethod] public void Staging() { diff --git a/Adaptation/_Tests/Static/QS408M.cs b/Adaptation/_Tests/Static/QS408M.cs index ef12ea5..fc794bf 100644 --- a/Adaptation/_Tests/Static/QS408M.cs +++ b/Adaptation/_Tests/Static/QS408M.cs @@ -38,6 +38,13 @@ public class QS408M : LoggingUnitTesting, IDisposable LoggingUnitTesting?.Dispose(); } + private static void NonThrowTryCatch() + { + try + { throw new Exception(); } + catch (Exception) { } + } + [TestMethod] public void TestDateTime() { @@ -174,10 +181,10 @@ public class QS408M : LoggingUnitTesting, IDisposable Assert.IsTrue(descriptor.Reactor is "75"); Assert.IsTrue(string.IsNullOrEmpty(descriptor.Zone)); Assert.IsTrue(string.IsNullOrEmpty(descriptor.Employee)); - descriptor = FileHandlers.QS408M.ProcessData.GetDescriptor("p5801"); - Assert.IsTrue(descriptor.Wafer == "P5801"); - descriptor = FileHandlers.QS408M.ProcessData.GetDescriptor("P5801"); - Assert.IsTrue(descriptor.Wafer == "P5801"); + descriptor = FileHandlers.QS408M.ProcessData.GetDescriptor("B48"); + Assert.IsTrue(descriptor.Wafer == "B48"); + descriptor = FileHandlers.QS408M.ProcessData.GetDescriptor("B48"); + Assert.IsTrue(descriptor.Wafer == "B48"); Assert.IsTrue(string.IsNullOrEmpty(descriptor.Layer)); Assert.IsTrue(string.IsNullOrEmpty(descriptor.PSN)); Assert.IsTrue(string.IsNullOrEmpty(descriptor.PSN)); @@ -185,9 +192,12 @@ public class QS408M : LoggingUnitTesting, IDisposable Assert.IsTrue(string.IsNullOrEmpty(descriptor.Zone)); Assert.IsTrue(string.IsNullOrEmpty(descriptor.Employee)); LoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Exit")); + NonThrowTryCatch(); } +#if DEBUG [Ignore] +#endif [TestMethod] public void Staging() { diff --git a/MET08THFTIRQS408M.csproj b/MET08THFTIRQS408M.csproj index 9695a5d..d4d9df8 100644 --- a/MET08THFTIRQS408M.csproj +++ b/MET08THFTIRQS408M.csproj @@ -109,11 +109,16 @@ + + + + +