using Adaptation.Shared; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; namespace Adaptation.FileHandlers.RsM; #nullable enable internal class Run { public Run(Line1 line1, Line2 line2, Line3 line3, Line4 line4, Line4B line4B, Line5 line5, Line6 line6, Line7 line7, Line8 line8, Line9 line9, Line10 line10, Line11 line11, Line12 line12, Line13 line13, ReadOnlyCollection points) { Line1 = line1; Line2 = line2; Line3 = line3; Line4 = line4; Line4B = line4B; Line5 = line5; Line6 = line6; Line7 = line7; Line8 = line8; Line9 = line9; Line10 = line10; Line11 = line11; Line12 = line12; Line13 = line13; Points = points; } public Line1 Line1 { get; } public Line2 Line2 { get; } public Line3 Line3 { get; } public Line4 Line4 { get; } public Line4B Line4B { get; } public Line5 Line5 { get; } public Line6 Line6 { get; } public Line7 Line7 { get; } public Line8 Line8 { get; } public Line9 Line9 { get; } public Line10 Line10 { get; } public Line11 Line11 { get; } public Line12 Line12 { get; } public Line13 Line13 { get; } public ReadOnlyCollection Points { get; } internal static ReadOnlyCollection GetCollection(string[] segments) { List results = new(); foreach (string segment in segments) { if (segment[0] == ',') break; results.Add(segment); } return new(results); } private static void WriteJson(Logistics logistics, List fileInfoCollection, Run? result) { FileInfo fileInfo = new($"{logistics.ReportFullPath}.json"); string json = JsonSerializer.Serialize(result, RunSourceGenerationContext.Default.Run); File.WriteAllText(fileInfo.FullName, json); File.SetLastWriteTime(fileInfo.FullName, logistics.DateTimeFromSequence); fileInfoCollection.Add(fileInfo); } private static ReadOnlyCollection GetLines(JsonElement[]? jsonElements) { List results = new(); int columns = 0; StringBuilder stringBuilder = new(); for (int i = 0; i < jsonElements?.Length;) { foreach (JsonProperty jsonProperty in jsonElements[0].EnumerateObject()) { columns += 1; _ = stringBuilder.Append('"').Append(jsonProperty.Name).Append('"').Append('\t'); } break; } if (jsonElements?.Length != 0) _ = stringBuilder.Remove(stringBuilder.Length - 1, 1); results.Add(stringBuilder.ToString()); for (int i = 0; i < jsonElements?.Length; i++) { _ = stringBuilder.Clear(); foreach (JsonProperty jsonProperty in jsonElements[i].EnumerateObject()) { if (jsonProperty.Value.ValueKind == JsonValueKind.Object) _ = stringBuilder.Append('\t'); else if (jsonProperty.Value.ValueKind != JsonValueKind.String) _ = stringBuilder.Append(jsonProperty.Value).Append('\t'); else _ = stringBuilder.Append('"').Append(jsonProperty.Value).Append('"').Append('\t'); } _ = stringBuilder.Remove(stringBuilder.Length - 1, 1); results.Add(stringBuilder.ToString()); } return results.AsReadOnly(); } private static ReadOnlyCollection GetLines(JsonElement jsonElement) => GetLines(new JsonElement[] { jsonElement }); private static void WriteTabSeparatedValues(Logistics logistics, List fileInfoCollection, Run run) { List results = new(); Row row; FileInfo fileInfo = new($"{logistics.ReportFullPath}.tsv"); for (int i = 0; i < run.Points.Count; i++) { row = new(run, i); results.Add(row); } string json = JsonSerializer.Serialize(results); JsonElement[]? jsonElements = JsonSerializer.Deserialize(json); ReadOnlyCollection lines = GetLines(jsonElements); File.WriteAllText(fileInfo.FullName, string.Join(Environment.NewLine, lines)); File.SetLastWriteTime(fileInfo.FullName, logistics.DateTimeFromSequence); fileInfoCollection.Add(fileInfo); } private static void WriteException(Logistics logistics, Exception ex) { FileInfo fileInfo = new($"{logistics.ReportFullPath}.{nameof(Exception)}.txt"); File.WriteAllText(fileInfo.FullName, $"{ex.Message}{Environment.NewLine}{ex.StackTrace}"); } internal static Run? Get(Logistics logistics, List fileInfoCollection) { Run? result; int take = 14; string[] lines = File.ReadAllLines(logistics.ReportFullPath); ReadOnlyCollection collection = new(lines); if (collection.Count < take) result = null; else { string[] separator = new string[] { " ", "\t" }; // Line1 line1 = Line1.Get(collection[0].Split(separator, StringSplitOptions.RemoveEmptyEntries)); // <FileName, Proj,Rcpe, LotID,WfrID, Is_TF_DataFile> Line2 line2 = Line2.Get(collection[1].Split(separator, StringSplitOptions.RemoveEmptyEntries)); // <Directory> Line3 line3 = Line3.Get(collection[2].Split(separator, StringSplitOptions.RemoveEmptyEntries)); // <DateTime,Temp,TCR%,N|P> Line4 line4 = Line4.Get(collection[3].Split(separator, StringSplitOptions.RemoveEmptyEntries)); // <Avg,Dev,Min,Max> Line4B? line4B = Line4B.Get(collection[3].Split(new string[] { ">" }, StringSplitOptions.RemoveEmptyEntries)); if (line4B is null) result = null; else { // <Operator, Epuipment> Line5 line5 = Line5.Get(collection[4].Split(separator, StringSplitOptions.RemoveEmptyEntries)); // <Engineer> Line6 line6 = Line6.Get(collection[5].Split(separator, StringSplitOptions.RemoveEmptyEntries)); // <AreaOrDiamScan, WaferShape, dNBand, TemplateFile, xsize,ysize, CalibFactor, MsmtMode, DataType, DataUnit> Line7 line7 = Line7.Get(collection[6].Split(separator, StringSplitOptions.RemoveEmptyEntries)); // <NumProbePoints, SingleOrDualProbeConfig, #ActPrbPts, Rsens,IdrvMx,VinGain, DataRejectSigma, MeritThreshold, PrbChg#, PrbName> Line8 line8 = Line8.Get(collection[7].Split(separator, StringSplitOptions.RemoveEmptyEntries)); // <WaferSize,EdgeEx, x,yll, x,yur, #x,y, CutCorners> Line9 line9 = Line9.Get(collection[8].Split(separator, StringSplitOptions.RemoveEmptyEntries)); // <Diam: ThScan Start End Step> Line10 line10 = Line10.Get(collection[9].Split(separator, StringSplitOptions.RemoveEmptyEntries)); // <FlatOrNotch FollowMajorFlat AutoOrManualLoad RangeOrIndvdual PauseAfterEveryRun, AutoPrint,Plot, BulkSmplThk & Unit> Line11 line11 = Line11.Get(collection[10].Split(separator, StringSplitOptions.RemoveEmptyEntries)); // <RangeFrom, RangeTo> Line12 line12 = Line12.Get(collection[11].Split(separator, StringSplitOptions.RemoveEmptyEntries)); // <CassSlotSelected> Line13 line13 = Line13.Get(collection[12].Split(separator, StringSplitOptions.RemoveEmptyEntries)); // <R,Th,Data, Rs,RsA,RsB, #Smpl, x,y, Irng,Vrng, ChiSq,merit/GOF, DataIntegrity> ReadOnlyCollection<Point> points = Point.Get(take, collection, separator); if (points.Count == 0) result = null; else { result = new(line1, line2, line3, line4, line4B, line5, line6, line7, line8, line9, line10, line11, line12, line13, points); WriteJson(logistics, fileInfoCollection, result); try { WriteTabSeparatedValues(logistics, fileInfoCollection, result); } catch (Exception ex) { WriteException(logistics, ex); } } } } return result; } } [JsonSourceGenerationOptions(WriteIndented = true)] [JsonSerializable(typeof(Run))] internal partial class RunSourceGenerationContext : JsonSerializerContext { }