From ca0e7d2030cc9777e65f0b48e091099e39a7bef8 Mon Sep 17 00:00:00 2001 From: Mike Phares Date: Mon, 18 Nov 2024 14:31:39 -0700 Subject: [PATCH] FlagDuplicates CA1510 Complete --- Adaptation/.editorconfig | 3 +- Adaptation/.vscode/settings.json | 2 + Adaptation/.vscode/tasks.json | 12 +- .../FileHandlers/OpenInsight/FromIQS.cs | 18 +- Adaptation/FileHandlers/QS408M/Body.cs | 104 +++++++-- Adaptation/FileHandlers/QS408M/Complete.cs | 108 +++++++++ Adaptation/FileHandlers/QS408M/FileRead.cs | 13 +- Adaptation/FileHandlers/QS408M/Footer.cs | 32 ++- Adaptation/FileHandlers/QS408M/Header.cs | 112 +++++++-- .../FileHandlers/QS408M/LastProcessData.cs | 13 -- Adaptation/FileHandlers/QS408M/ProcessData.cs | 73 +++--- Adaptation/FileHandlers/QS408M/Site.cs | 25 +- Adaptation/FileHandlers/QS408M/TXT.cs | 221 ------------------ Adaptation/MET08THFTIRQS408M.Tests.csproj | 24 +- Adaptation/Shared/FileRead.cs | 2 +- .../Production/v2.57.0/MET08THFTIRQS408M.cs | 21 ++ Adaptation/_Tests/Shared/AdaptationTesting.cs | 4 +- MET08THFTIRQS408M.csproj | 3 +- 18 files changed, 429 insertions(+), 361 deletions(-) create mode 100644 Adaptation/FileHandlers/QS408M/Complete.cs delete mode 100644 Adaptation/FileHandlers/QS408M/LastProcessData.cs delete mode 100644 Adaptation/FileHandlers/QS408M/TXT.cs diff --git a/Adaptation/.editorconfig b/Adaptation/.editorconfig index 69ecc38..d6755a0 100644 --- a/Adaptation/.editorconfig +++ b/Adaptation/.editorconfig @@ -92,8 +92,9 @@ csharp_using_directive_placement = outside_namespace dotnet_code_quality_unused_parameters = all dotnet_code_quality_unused_parameters = non_public # IDE0060: Remove unused parameter dotnet_code_quality.CAXXXX.api_surface = private, internal +dotnet_diagnostic.CA1510.severity = none # CA1510: Use 'ArgumentNullException.ThrowIfNull' instead of explicitly throwing a new exception instance dotnet_diagnostic.CA1816.severity = none # CA1816: Call GC.SuppressFinalize correctly -dotnet_diagnostic.CA1825.severity = warning # CA1823: Avoid zero-length array allocations +dotnet_diagnostic.CA1825.severity = warning # CA1825: Avoid zero-length array allocations dotnet_diagnostic.CA1829.severity = warning # CA1829: Use Length/Count property instead of Count() when available dotnet_diagnostic.CA1834.severity = warning # CA1834: Consider using 'StringBuilder.Append(char)' when applicable dotnet_diagnostic.CA1846.severity = none # CA1846: Prefer AsSpan over Substring diff --git a/Adaptation/.vscode/settings.json b/Adaptation/.vscode/settings.json index b9d0502..052c51a 100644 --- a/Adaptation/.vscode/settings.json +++ b/Adaptation/.vscode/settings.json @@ -6,11 +6,13 @@ "BIORAD", "CICN", "datauniqueid", + "EPI", "EQPT", "headerid", "Hmmssffff", "ipdsf", "ISMTP", + "MEPI", "messa", "ntities", "PDSF", diff --git a/Adaptation/.vscode/tasks.json b/Adaptation/.vscode/tasks.json index c97e0e2..d64119b 100644 --- a/Adaptation/.vscode/tasks.json +++ b/Adaptation/.vscode/tasks.json @@ -49,6 +49,16 @@ ], "problemMatcher": "$msCompile" }, + { + "label": "Format-Whitespaces", + "command": "dotnet", + "type": "process", + "args": [ + "format", + "whitespace" + ], + "problemMatcher": "$msCompile" + }, { "label": "Nuget Clear", "command": "dotnet", @@ -68,7 +78,7 @@ "args": [ "/target:Build", "/restore:True", - "/p:RestoreSources=https://artifactory.intra.infineon.com/artifactory/api/nuget/ngt-fi-package-main-vir/%3Bhttps://packagemanagement.eu.infineon.com:4430/api/v2/%3Bhttps://tfs.intra.infineon.com/tfs/ManufacturingIT/_packaging/eaf/nuget/v3/index.json%3Bhttps://tfs.intra.infineon.com/tfs/FactoryIntegration/_packaging/EAF%40Local/nuget/v3/index.json%3Bhttps://api.nuget.org/v3/index.json", + "/p:RestoreSources=https://artifactory.intra.infineon.com/artifactory/api/nuget/ngt-fi-package-main-vir/%3Bhttps://packagemanagement.eu.infineon.com:4430/api/v2/%3Bhttps://tfs.intra.infineon.com/tfs/FactoryIntegration/_packaging/EAF/nuget/v3/index.json%3Bhttps://tfs.intra.infineon.com/tfs/FactoryIntegration/_packaging/EAF%40Local/nuget/v3/index.json%3Bhttps://api.nuget.org/v3/index.json", "/detailedsummary", "/consoleloggerparameters:PerformanceSummary;ErrorsOnly;", "/property:Configuration=Debug;TargetFrameworkVersion=v4.8", diff --git a/Adaptation/FileHandlers/OpenInsight/FromIQS.cs b/Adaptation/FileHandlers/OpenInsight/FromIQS.cs index 8e72554..56873c1 100644 --- a/Adaptation/FileHandlers/OpenInsight/FromIQS.cs +++ b/Adaptation/FileHandlers/OpenInsight/FromIQS.cs @@ -227,7 +227,7 @@ public class FromIQS private static void FlagDuplicates(string connectionString, string json) { JsonElement[]? jsonElements = JsonSerializer.Deserialize(json); - JsonSerializerOptions jsonSerializerOptions = new() { PropertyNameCaseInsensitive = true}; + JsonSerializerOptions jsonSerializerOptions = new() { PropertyNameCaseInsensitive = true }; if (jsonElements is not null && jsonElements.Length != 0 && jsonElements[0].ValueKind == JsonValueKind.Object) { Root? root; @@ -242,14 +242,12 @@ public class FromIQS break; collection.Add(root.MaxSeSgrp); } - try + if (collection.Count > 0) { string commandText = GetCommandText(collection); File.WriteAllText("D:/.sql", commandText); _ = ExecuteNonQuery(connectionString, commandText); } - catch (Exception) - { } } } @@ -268,9 +266,15 @@ public class FromIQS else dateTime = logistics.DateTimeFromSequence; commandText = GetCommandText(dateTime); - stringBuilder = GetForJsonPath(connectionString, commandText); - if (stringBuilder.Length > 0) - FlagDuplicates(connectionString, stringBuilder.ToString()); + try + { + stringBuilder = GetForJsonPath(connectionString, commandText); + if (stringBuilder.Length > 0) + FlagDuplicates(connectionString, stringBuilder.ToString()); + } + catch (Exception) + { stringBuilder = new(); } + _ = stringBuilder.Clear(); commandText = GetCommandText(logistics, description, dateTime.ToString("yyyy-MM-dd HH:mm:ss"), subGroupId: null); for (short i = 0; i < short.MaxValue; i++) { diff --git a/Adaptation/FileHandlers/QS408M/Body.cs b/Adaptation/FileHandlers/QS408M/Body.cs index d0ed230..8db8748 100644 --- a/Adaptation/FileHandlers/QS408M/Body.cs +++ b/Adaptation/FileHandlers/QS408M/Body.cs @@ -2,27 +2,97 @@ using System.Collections.Generic; namespace Adaptation.FileHandlers.QS408M; +#nullable enable + public class Body { - public List Sites { get; set; } - public string WaferMeanThickness { get; set; } - public string StdDev { get; set; } - public string PassFail { get; set; } + public Body(List sites, string waferMeanThickness, string stdDev, string passFail) + { + Sites = sites; + WaferMeanThickness = waferMeanThickness; + StdDev = stdDev; + PassFail = passFail; + } -} + public List Sites { get; } + public string WaferMeanThickness { get; } + public string StdDev { get; } + public string PassFail { get; } -// 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 -// ================================================================================ + 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; + } -// Radial variation (computation B) PASS: + private static string GetToken(string text, int[] i) + { + while (true) + { + if (i[0] >= text.Length || !IsNullOrWhiteSpace(text.Substring(i[0], 1))) + { + break; + } + i[0]++; + } + int num = i[0]; + while (true) + { + if (num >= text.Length || IsNullOrWhiteSpace(text.Substring(num, 1))) + { + break; + } + num++; + } + string str = text.Substring(i[0], num - i[0]); + i[0] = num; + return str.Trim(); + } -// thickness -2.7474 \ No newline at end of file + internal static Body? Get(string text, int[] i) + { + Body? result; + Site site; + string thickness; + List sites = new(); + string position = GetToken(text, i); + while (true) + { + if (string.IsNullOrEmpty(position) || !char.IsDigit(position[0])) + break; + thickness = GetToken(text, i); + site = new(position, thickness); + sites.Add(site); + position = GetToken(text, i); + } + i[0] = Complete.ScanPast(text, i, "mean thickness ="); + string meanThickness = Complete.GetBefore(text, i, ", std. dev ="); + string stdDev = GetToken(text, i); + string passFail = Complete.GetToEOL(text, i); + result = new(sites, + meanThickness, + stdDev, + passFail); + return result; + } + +} \ No newline at end of file diff --git a/Adaptation/FileHandlers/QS408M/Complete.cs b/Adaptation/FileHandlers/QS408M/Complete.cs new file mode 100644 index 0000000..e574a49 --- /dev/null +++ b/Adaptation/FileHandlers/QS408M/Complete.cs @@ -0,0 +1,108 @@ +using System; +using System.Text.Json.Serialization; + +namespace Adaptation.FileHandlers.QS408M; + +#nullable enable + +internal class Complete +{ + + public Complete(Header header, Body body, Footer footer) + { + Header = header; + Body = body; + Footer = footer; + } + + public Header Header { get; } + public Body Body { get; } + public Footer Footer { get; } + + internal static string GetBefore(string text, int[] i, string search) + { + string str; + string str1; + int num = text.IndexOf(search, i[0]); + if (num <= -1) + { + str = text.Substring(i[0]); + i[0] = text.Length; + str1 = str.Trim(); + } + else + { + str = text.Substring(i[0], num - i[0]); + i[0] = num + search.Length; + str1 = str.Trim(); + } + return str1; + } + + internal static string GetToEOL(string text, int[] i) + { + string result; + if (text.IndexOf("\n", i[0]) > -1) + result = GetBefore(text, i, "\n"); + else + result = GetBefore(text, i, Environment.NewLine); + return result; + } + + internal static int ScanPast(string text, int[] i, string search) + { + int result; + int num = text.IndexOf(search, i[0]); + if (num <= -1) + result = text.Length; + else + result = num + search.Length; + return result; + } + + internal static Complete? Get(Header lastHeader, string text) + { + Complete? result; + int[] i = new int[] { 0 }; + Header? header = Header.Get(lastHeader, text, i); + if (header is null) + result = null; + else + { + Body? body = Body.Get(text, i); + if (body is null) + result = null; + else + { + Footer? footer = Footer.Get(text, i); + if (footer is null) + result = null; + else + result = new(header, body, footer); + } + } + return result; + } + +} + +// 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 + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(Complete))] +internal partial class CompleteSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Adaptation/FileHandlers/QS408M/FileRead.cs b/Adaptation/FileHandlers/QS408M/FileRead.cs index 217a74d..7f36eca 100644 --- a/Adaptation/FileHandlers/QS408M/FileRead.cs +++ b/Adaptation/FileHandlers/QS408M/FileRead.cs @@ -14,8 +14,8 @@ public class FileRead : Shared.FileRead, IFileRead { private long? _TickOffset; + private readonly Header[] _LastHeader; private readonly string _OriginalDataBioRad; - private readonly LastProcessData _LastProcessData; public FileRead(ISMTP smtp, Dictionary fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList modelObjectParameters, string equipmentDictionaryName, Dictionary> dummyRuns, Dictionary> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : base(new Description(), true, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) @@ -30,8 +30,9 @@ public class FileRead : Shared.FileRead, IFileRead if (_IsDuplicator) throw new Exception(cellInstanceConnectionName); _OriginalDataBioRad = "OriginalDataBioRad_"; - _LastProcessData = new(); - NestExistingFiles(_FileConnectorConfiguration); + _LastHeader = new Header[] { Header.Get() }; + if (_IsEAFHosted) + NestExistingFiles(_FileConnectorConfiguration); } void IFileRead.Move(Tuple> extractResults, Exception exception) => Move(extractResults); @@ -83,7 +84,7 @@ public class FileRead : Shared.FileRead, IFileRead DateTime dateTime = DateTime.Now; results = GetExtractResult(reportFullPath, dateTime); if (results.Item3 is null) - results = new Tuple>(results.Item1, Array.Empty(), JsonSerializer.Deserialize("[]"), results.Item4); + results = new Tuple>(results.Item1, Array.Empty(), JsonSerializer.Deserialize("[]") ?? throw new Exception(), results.Item4); if (results.Item3.Length > 0 && _IsEAFHosted) WritePDSF(this, results.Item3); UpdateLastTicksDuration(DateTime.Now.Ticks - dateTime.Ticks); @@ -101,7 +102,7 @@ public class FileRead : Shared.FileRead, IFileRead private Tuple> GetExtractResult(string reportFullPath, DateTime dateTime) { - Tuple> results = new(string.Empty, null, null, new List()); + Tuple> results = new(string.Empty, Array.Empty(), JsonSerializer.Deserialize("[]") ?? throw new Exception(), new List()); _TickOffset ??= new FileInfo(reportFullPath).LastWriteTime.Ticks - dateTime.Ticks; _Logistics = new Logistics(this, _TickOffset.Value, reportFullPath, useSplitForMID: true); SetFileParameterLotIDToLogisticsMID(); @@ -109,7 +110,7 @@ public class FileRead : Shared.FileRead, IFileRead results.Item4.Add(_Logistics.FileInfo); else { - IProcessData iProcessData = new ProcessData(this, _Logistics, results.Item4, _OriginalDataBioRad, lastProcessData: _LastProcessData, tickOffset: _TickOffset.Value); + IProcessData iProcessData = new ProcessData(this, _Logistics, results.Item4, _OriginalDataBioRad, lastHeader: _LastHeader, tickOffset: _TickOffset.Value); if (iProcessData is not ProcessData processData) throw new Exception(string.Concat("A) No Data - ", dateTime.Ticks)); string mid; diff --git a/Adaptation/FileHandlers/QS408M/Footer.cs b/Adaptation/FileHandlers/QS408M/Footer.cs index db1e6a2..082fda1 100644 --- a/Adaptation/FileHandlers/QS408M/Footer.cs +++ b/Adaptation/FileHandlers/QS408M/Footer.cs @@ -1,10 +1,36 @@ namespace Adaptation.FileHandlers.QS408M; +#nullable enable + public class Footer { - public string Line { get; set; } - public string RadialVariationThickness { get; set; } - public string Slot { get; set; } + public Footer(string line, string radialVariationThickness, string slot) + { + Line = line; + RadialVariationThickness = radialVariationThickness; + Slot = slot; + } + + public string Line { get; } + public string RadialVariationThickness { get; } + public string Slot { get; } + + internal static Footer? Get(string text, int[] i) + { + Footer? result; + _ = Complete.GetToEOL(text, i); + _ = Complete.GetToEOL(text, i); + string line = Complete.GetToEOL(text, i); + i[0] = Complete.ScanPast(text, i, "thickness"); + string radialVariationThickness = Complete.GetToEOL(text, i); + _ = Complete.GetToEOL(text, i); + i[0] = Complete.ScanPast(text, i, "Slot:"); + string slot = Complete.GetBefore(text, i, ";"); + result = new(line, + radialVariationThickness, + slot); + return result; + } } \ No newline at end of file diff --git a/Adaptation/FileHandlers/QS408M/Header.cs b/Adaptation/FileHandlers/QS408M/Header.cs index f8d4e23..2cd1ea3 100644 --- a/Adaptation/FileHandlers/QS408M/Header.cs +++ b/Adaptation/FileHandlers/QS408M/Header.cs @@ -1,30 +1,100 @@ +using System; + namespace Adaptation.FileHandlers.QS408M; +#nullable enable + 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 bool UsedLast { get; set; } - public string Wafer { get; set; } + public Header(string title, string recipe, string dateTime, string @operator, string batch, string cassette, bool usedLast, string wafer) + { + Title = title; + Recipe = recipe; + DateTime = dateTime; + Operator = @operator; + Batch = batch; + Cassette = cassette; + UsedLast = usedLast; + Wafer = wafer; + } -} + public string Title { get; } + public string Recipe { get; } + public string DateTime { get; } + public string Operator { get; } + public string Batch { get; } + public string Cassette { get; } + public bool UsedLast { get; } + public string Wafer { get; } -// 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 -// ================================================================================ + internal static Header Get() => + new(string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + false, + string.Empty); -// Radial variation (computation B) PASS: + internal static Header? Get(Header lastHeader, string text, int[] i) + { + Header? result; + // occasionally there are multiple blocks of details, get the last one as earlier ones may be aborted runs. + int index = text.LastIndexOf("Bio-Rad"); + if (index > -1) + text = text.Substring(index); + if (string.IsNullOrEmpty(text)) + result = null; + else + { + bool usedLast; + const string twoSpaces = " "; + string title = Complete.GetBefore(text, i, "Recipe:"); + string recipeAndDateTime = Complete.GetToEOL(text, i); + string recipe = recipeAndDateTime.Length < twoSpaces.Length ? recipeAndDateTime.Trim() : !recipeAndDateTime.Contains(twoSpaces) ? recipeAndDateTime.Substring(0, 25).Trim() : recipeAndDateTime.Split(new string[] { twoSpaces }, StringSplitOptions.None)[0].Trim(); + string dateTime = recipeAndDateTime.Substring(recipe.Length).Trim(); + if (dateTime.EndsWith(".")) + dateTime = dateTime.Remove(dateTime.Length - 1, 1); + i[0] = Complete.ScanPast(text, i, "operator:"); + string @operator = Complete.GetBefore(text, i, "batch:"); + string batch = Complete.GetToEOL(text, i); + i[0] = Complete.ScanPast(text, i, "cassette:"); + if (!text.Contains("cassette:")) + title = string.Empty; + string cassette = Complete.GetBefore(text, i, "wafer:"); + if (string.IsNullOrEmpty(batch)) + { + i[0] = 0; + i[0] = Complete.ScanPast(text, i, "wafer:"); + } + string wafer = Complete.GetToEOL(text, i); + _ = Complete.GetToEOL(text, i); + _ = Complete.GetToEOL(text, i); + if (string.IsNullOrEmpty(wafer)) + throw new Exception("Wafer field is missing."); + if (!string.IsNullOrEmpty(title)) + usedLast = false; + else + { + title = lastHeader.Title; + recipe = lastHeader.Recipe; + @operator = lastHeader.Operator; + batch = lastHeader.Batch; + cassette = lastHeader.Cassette; + usedLast = true; + } + result = new(title: title, + recipe: recipe, + dateTime: dateTime, + @operator: @operator, + batch: batch, + cassette: cassette, + usedLast: usedLast, + wafer: wafer); + } + return result; + } -// thickness -2.7474 \ No newline at end of file +} \ No newline at end of file diff --git a/Adaptation/FileHandlers/QS408M/LastProcessData.cs b/Adaptation/FileHandlers/QS408M/LastProcessData.cs deleted file mode 100644 index c7a64dc..0000000 --- a/Adaptation/FileHandlers/QS408M/LastProcessData.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Adaptation.FileHandlers.QS408M; - -public class LastProcessData -{ - - public string Title { get; set; } - public string Recipe { get; set; } - public string Date { get; set; } - public string Operator { get; set; } - public string Batch { get; set; } - public string Cassette { get; set; } - -} \ No newline at end of file diff --git a/Adaptation/FileHandlers/QS408M/ProcessData.cs b/Adaptation/FileHandlers/QS408M/ProcessData.cs index e5d2c9b..99461b6 100644 --- a/Adaptation/FileHandlers/QS408M/ProcessData.cs +++ b/Adaptation/FileHandlers/QS408M/ProcessData.cs @@ -58,16 +58,18 @@ public partial class ProcessData : IProcessData { } - public ProcessData(IFileRead fileRead, Logistics logistics, List fileInfoCollection, string originalDataBioRad, LastProcessData lastProcessData, long tickOffset) +#nullable enable + + public ProcessData(IFileRead fileRead, Logistics logistics, List fileInfoCollection, string originalDataBioRad, Header[] lastHeader, long tickOffset) { JobID = logistics.JobID; fileInfoCollection.Clear(); _Details = new List(); MesEntity = logistics.MesEntity; _Log = LogManager.GetLogger(typeof(ProcessData)); - TXT txt = Parse(fileRead, logistics, fileInfoCollection, originalDataBioRad, lastProcessData); - if (txt is not null) - SetValues(logistics, tickOffset, txt); + Complete? complete = Parse(fileRead, logistics, fileInfoCollection, originalDataBioRad, lastHeader); + if (complete is not null) + SetValues(logistics, tickOffset, complete); } string IProcessData.GetCurrentReactor(IFileRead fileRead, Logistics logistics, Dictionary reactors) => throw new Exception(string.Concat("See ", nameof(Parse))); @@ -90,7 +92,7 @@ public partial class ProcessData : IProcessData } List fileReadDescriptions = (from l in descriptions select (Description)l).ToList(); string json = JsonSerializer.Serialize(fileReadDescriptions, fileReadDescriptions.GetType()); - JsonElement[] jsonElements = JsonSerializer.Deserialize(json); + JsonElement[] jsonElements = JsonSerializer.Deserialize(json) ?? throw new Exception(); results = new Tuple>(logistics.Logistics1[0], tests.ToArray(), jsonElements, fileInfoCollection); return results; } @@ -245,49 +247,46 @@ public partial class ProcessData : IProcessData return result; } -#pragma warning disable IDE0060 - private static TXT Parse(IFileRead fileRead, Logistics logistics, List fileInfoCollection, string originalDataBioRad, LastProcessData lastProcessData) -#pragma warning restore IDE0060 + private Complete? Parse(IFileRead fileRead, Logistics logistics, List fileInfoCollection, string originalDataBioRad, Header[] lastHeader) { - TXT result; + if (fileRead is null) + throw new ArgumentNullException(nameof(fileRead)); + Complete? result; List moveFiles = new(); - string directoryName = Path.GetDirectoryName(logistics.ReportFullPath); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(logistics.ReportFullPath); + string directoryName = Path.GetDirectoryName(logistics.ReportFullPath) ?? throw new Exception(); moveFiles.AddRange(Directory.GetFiles(directoryName, string.Concat(originalDataBioRad, "*", logistics.Sequence, "*"), SearchOption.TopDirectoryOnly)); moveFiles.AddRange(Directory.GetFiles(directoryName, string.Concat(originalDataBioRad, "*", fileNameWithoutExtension.Split('_').Last(), "*"), SearchOption.TopDirectoryOnly)); foreach (string moveFile in moveFiles.Distinct()) fileInfoCollection.Add(new FileInfo(moveFile)); 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); - if (string.IsNullOrEmpty(receivedData)) - result = null; + result = Complete.Get(lastHeader[0], receivedData); + if (result is null) + _Log.Warn($"Could not get Complete from {fileNameWithoutExtension}"); else { - result = new TXT(lastProcessData, receivedData); - string fileName = Path.Combine(directoryName, $"{Path.GetFileNameWithoutExtension(logistics.ReportFullPath)}.json"); - string json = JsonSerializer.Serialize(result, new JsonSerializerOptions { WriteIndented = true }); - File.WriteAllText(fileName, json); - fileInfoCollection.Add(new(fileName)); + FileInfo fileInfo = new($"{fileNameWithoutExtension}.json"); + string json = JsonSerializer.Serialize(result, CompleteSourceGenerationContext.Default.Complete); + File.WriteAllText(fileInfo.FullName, json); + fileInfoCollection.Add(fileInfo); + lastHeader[0] = result.Header; } fileInfoCollection.Add(logistics.FileInfo); return result; } - private void SetValues(Logistics logistics, long tickOffset, TXT txt) + private void SetValues(Logistics logistics, long tickOffset, Complete complete) { int slot = 0; Detail detail; int counter = 1; List details = new(); - DateTime dateTime = GetDateTime(logistics, tickOffset, txt.Header.DateTime); - bool isWaferSlot = !string.IsNullOrEmpty(txt.Header.Wafer) && txt.Header.Wafer.Length is 1 or 2 && int.TryParse(txt.Header.Wafer, out slot) && slot < 27; - string batch = !isWaferSlot ? logistics.JobID : Regex.Replace(txt.Header.Batch, @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]", "_").Split('\r')[0].Split('\n')[0]; - Descriptor descriptor = isWaferSlot ? GetDescriptor(txt.Header.Batch) : GetDescriptor(txt.Header.Wafer); + DateTime dateTime = GetDateTime(logistics, tickOffset, complete.Header.DateTime); + bool isWaferSlot = !string.IsNullOrEmpty(complete.Header.Wafer) && complete.Header.Wafer.Length is 1 or 2 && int.TryParse(complete.Header.Wafer, out slot) && slot < 27; + string batch = !isWaferSlot ? logistics.JobID : Regex.Replace(complete.Header.Batch, @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]", "_").Split('\r')[0].Split('\n')[0]; + Descriptor descriptor = isWaferSlot ? GetDescriptor(complete.Header.Batch) : GetDescriptor(complete.Header.Wafer); string wafer = isWaferSlot ? slot.ToString("00") : descriptor.Wafer; - string uniqueId = string.Concat(txt.Header.Title, '_', wafer, '_', logistics.DateTimeFromSequence.ToString("yyyyMMddHHmmssffff"), '_', logistics.TotalSecondsSinceLastWriteTimeFromSequence); + string uniqueId = string.Concat(complete.Header.Title, '_', wafer, '_', logistics.DateTimeFromSequence.ToString("yyyyMMddHHmmssffff"), '_', logistics.TotalSecondsSinceLastWriteTimeFromSequence); Batch = batch; Wafer = wafer; Date = dateTime; @@ -297,17 +296,17 @@ public partial class ProcessData : IProcessData Zone = descriptor.Zone; JobID = logistics.JobID; Layer = descriptor.Layer; - StdDev = txt.Body.StdDev; - Title = txt.Header.Title; - Recipe = txt.Header.Recipe; - PassFail = txt.Body.PassFail; Reactor = descriptor.Reactor; - Cassette = txt.Header.Cassette; - RVThickness = txt.Footer.RadialVariationThickness; - Slot = string.IsNullOrEmpty(txt.Footer.Slot) ? slot.ToString("00") : txt.Footer.Slot; - Employee = string.IsNullOrEmpty(txt.Header.Operator) ? Employee : txt.Header.Operator; - MeanThickness = string.IsNullOrEmpty(txt.Body.WaferMeanThickness) && txt.Body.Sites.Count == 1 ? txt.Body.Sites.First().Thickness : txt.Body.WaferMeanThickness; - foreach (Site site in txt.Body.Sites) + StdDev = complete.Body.StdDev; + Title = complete.Header.Title; + Recipe = complete.Header.Recipe; + PassFail = complete.Body.PassFail; + Cassette = complete.Header.Cassette; + RVThickness = complete.Footer.RadialVariationThickness; + Slot = string.IsNullOrEmpty(complete.Footer.Slot) ? slot.ToString("00") : complete.Footer.Slot; + Employee = string.IsNullOrEmpty(complete.Header.Operator) ? Employee : complete.Header.Operator; + MeanThickness = string.IsNullOrEmpty(complete.Body.WaferMeanThickness) && complete.Body.Sites.Count == 1 ? complete.Body.Sites.First().Thickness : complete.Body.WaferMeanThickness; + foreach (Site site in complete.Body.Sites) { detail = new() { diff --git a/Adaptation/FileHandlers/QS408M/Site.cs b/Adaptation/FileHandlers/QS408M/Site.cs index 82b6969..8f447a5 100644 --- a/Adaptation/FileHandlers/QS408M/Site.cs +++ b/Adaptation/FileHandlers/QS408M/Site.cs @@ -3,22 +3,13 @@ namespace Adaptation.FileHandlers.QS408M; public class Site { - public string Position { get; set; } - public string Thickness { get; set; } + public Site(string position, string thickness) + { + Position = position; + Thickness = thickness; + } -} + public string Position { get; } + public string Thickness { get; } -// 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 \ No newline at end of file +} \ No newline at end of file diff --git a/Adaptation/FileHandlers/QS408M/TXT.cs b/Adaptation/FileHandlers/QS408M/TXT.cs deleted file mode 100644 index ada879d..0000000 --- a/Adaptation/FileHandlers/QS408M/TXT.cs +++ /dev/null @@ -1,221 +0,0 @@ -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(LastProcessData lastProcessData, string receivedData) - { - _I = 0; - Site site; - bool usedLast; - _Data = receivedData; - List sites = new(); - const string twoSpaces = " "; - string title = GetBefore("Recipe:"); - string recipeAndDateTime = GetToEOL(); - string recipe = recipeAndDateTime.Length < twoSpaces.Length ? recipeAndDateTime.Trim() : !recipeAndDateTime.Contains(twoSpaces) ? recipeAndDateTime.Substring(0, 25).Trim() : recipeAndDateTime.Split(new string[] { twoSpaces }, StringSplitOptions.None)[0].Trim(); - string dateTime = recipeAndDateTime.Substring(recipe.Length).Trim(); - if (dateTime.EndsWith(".")) - dateTime = dateTime.Remove(dateTime.Length - 1, 1); - ScanPast("operator:"); - string @operator = GetBefore("batch:"); - string batch = GetToEOL(); - ScanPast("cassette:"); - if (!receivedData.Contains("cassette:")) - title = string.Empty; - 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."); - if (!string.IsNullOrEmpty(title)) - usedLast = false; - else - { - title = lastProcessData.Title; - recipe = lastProcessData.Recipe; - @operator = lastProcessData.Operator; - batch = lastProcessData.Batch; - cassette = lastProcessData.Cassette; - usedLast = true; - } - 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(); - _ = GetToEOL(); - ScanPast("Slot:"); - string slot = GetBefore(";"); - Header = new() - { - Title = title, - Recipe = recipe, - DateTime = dateTime, - Operator = @operator, - Batch = batch, - Cassette = cassette, - UsedLast = usedLast, - Wafer = wafer, - }; - Body = new() - { - Sites = sites, - WaferMeanThickness = meanThickness, - StdDev = stdDev, - PassFail = passFail, - }; - Footer = new() - { - Line = line, - RadialVariationThickness = radialVariationThickness, - Slot = slot, - }; - lastProcessData.Title = title; - lastProcessData.Recipe = recipe; - lastProcessData.Operator = @operator; - lastProcessData.Batch = batch; - lastProcessData.Cassette = cassette; - } - - 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 GetToEOL() - { - string result; - if (_Data.IndexOf("\n", _I) > -1) - result = GetBefore("\n"); - else - result = GetBefore(Environment.NewLine); - return result; - } - - 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 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 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 \ No newline at end of file diff --git a/Adaptation/MET08THFTIRQS408M.Tests.csproj b/Adaptation/MET08THFTIRQS408M.Tests.csproj index ead3089..4bba09c 100644 --- a/Adaptation/MET08THFTIRQS408M.Tests.csproj +++ b/Adaptation/MET08THFTIRQS408M.Tests.csproj @@ -49,23 +49,23 @@ - + - - - - - + + + + + - - + + NU1701 - - + + - - + + diff --git a/Adaptation/Shared/FileRead.cs b/Adaptation/Shared/FileRead.cs index 23a9afb..a36b127 100644 --- a/Adaptation/Shared/FileRead.cs +++ b/Adaptation/Shared/FileRead.cs @@ -503,7 +503,7 @@ public class FileRead : Properties.IFileRead foreach (string match in matches) { fileName = Path.GetFileName(match); - File.Move(match, Path.Combine(fileConnectorConfiguration.SourceFileLocation, fileName)); + File.Move(match, Path.Combine(nestedDirectory, fileName)); } } } diff --git a/Adaptation/_Tests/Extract/Production/v2.57.0/MET08THFTIRQS408M.cs b/Adaptation/_Tests/Extract/Production/v2.57.0/MET08THFTIRQS408M.cs index 65202b8..1450295 100644 --- a/Adaptation/_Tests/Extract/Production/v2.57.0/MET08THFTIRQS408M.cs +++ b/Adaptation/_Tests/Extract/Production/v2.57.0/MET08THFTIRQS408M.cs @@ -96,6 +96,27 @@ public class MET08THFTIRQS408M _ = Shared.AdaptationTesting.ReExtractCompareUpdatePassDirectory(variables, fileRead, logistics); NonThrowTryCatch(); } + +#if DEBUG + [Ignore] +#endif + [TestMethod] + public void Production__v2_57_0__MET08THFTIRQS408M__OpenInsight638662107339513927__Long() + { + DateTime dateTime; + string check = "*.pdsf"; + MethodBase methodBase = new StackFrame().GetMethod(); + _MET08THFTIRQS408M.Production__v2_57_0__MET08THFTIRQS408M__OpenInsight(); + string[] variables = _MET08THFTIRQS408M.AdaptationTesting.GetVariables(methodBase, check, validatePDSF: false); + IFileRead fileRead = _MET08THFTIRQS408M.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); + NonThrowTryCatch(); + } #if DEBUG [Ignore] diff --git a/Adaptation/_Tests/Shared/AdaptationTesting.cs b/Adaptation/_Tests/Shared/AdaptationTesting.cs index dad8ffe..8a341d4 100644 --- a/Adaptation/_Tests/Shared/AdaptationTesting.cs +++ b/Adaptation/_Tests/Shared/AdaptationTesting.cs @@ -974,8 +974,8 @@ public class AdaptationTesting : ISMTP } if (!string.IsNullOrEmpty(fileConnectorConfigurationTuple.Item2.AlternateTargetFolder)) { - if (!Directory.Exists(fileConnectorConfigurationTuple.Item2.AlternateTargetFolder)) - _ = Directory.CreateDirectory(fileConnectorConfigurationTuple.Item2.AlternateTargetFolder); + if (!Directory.Exists(fileConnectorConfigurationTuple.Item2.AlternateTargetFolder.Split('|')[0])) + _ = Directory.CreateDirectory(fileConnectorConfigurationTuple.Item2.AlternateTargetFolder.Split('|')[0]); } } catch (IOException ex) diff --git a/MET08THFTIRQS408M.csproj b/MET08THFTIRQS408M.csproj index 059b844..7eba3c4 100644 --- a/MET08THFTIRQS408M.csproj +++ b/MET08THFTIRQS408M.csproj @@ -117,16 +117,15 @@ + - -