Dual write PDSF for Metrology Viewer Version Error Message Tests passed net8.0 v2_52_0-Tests v2_52_0-Tests editorconfig editorconfig yml ec fix yaml explicit contents Delete File if Exists dotnet_diagnostic Removed Open Insight API IFX Directory Removed Open Insight API IFX Directory from Save CA1862 and GetWeekOfYear for WritePDSF gitignore cellInstanceVersion.EdaConnection.PortNumber Added Climatec to Test.cs NETFRAMEWORK GetJobIdDirectory Remove and
308 lines
11 KiB
C#
308 lines
11 KiB
C#
using Adaptation.Shared;
|
|
using Adaptation.Shared.Methods;
|
|
using log4net;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace Adaptation.FileHandlers.json;
|
|
|
|
public partial class ProcessData : IProcessData
|
|
{
|
|
|
|
private readonly List<object> _Details;
|
|
|
|
public DateTime Date { get; set; }
|
|
public string Employee { get; set; }
|
|
public string JobID { get; set; }
|
|
public string Layer { get; set; }
|
|
public string MesEntity { get; set; }
|
|
public string PSN { get; set; }
|
|
public string RDS { get; set; }
|
|
public string Reactor { get; set; }
|
|
public string Recipe { get; set; }
|
|
public string Zone { get; set; }
|
|
//
|
|
public string SineBevelAngle { get; set; }
|
|
public string XStep { get; set; }
|
|
|
|
List<object> Shared.Properties.IProcessData.Details => _Details;
|
|
|
|
private readonly ILog _Log;
|
|
|
|
public ProcessData()
|
|
{
|
|
}
|
|
|
|
public ProcessData(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection, long tickOffset)
|
|
{
|
|
JobID = logistics.JobID;
|
|
fileInfoCollection.Clear();
|
|
_Details = new List<object>();
|
|
MesEntity = logistics.MesEntity;
|
|
_Log = LogManager.GetLogger(typeof(ProcessData));
|
|
CSV csv = Parse(fileRead, logistics, fileInfoCollection);
|
|
if (!string.IsNullOrEmpty(csv.Info?.SampleName) && csv.ProfileHeader.ProfilePoints.Count != 0)
|
|
SetValues(logistics, tickOffset, csv);
|
|
}
|
|
|
|
string IProcessData.GetCurrentReactor(IFileRead fileRead, Logistics logistics, Dictionary<string, string> reactors) => throw new Exception(string.Concat("See ", nameof(Parse)));
|
|
|
|
Tuple<string, Test[], JsonElement[], List<FileInfo>> IProcessData.GetResults(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection)
|
|
{
|
|
Tuple<string, Test[], JsonElement[], List<FileInfo>> results;
|
|
List<Test> tests = new();
|
|
foreach (object item in _Details)
|
|
tests.Add(Test.SRP2100);
|
|
List<IDescription> descriptions = fileRead.GetDescriptions(fileRead, tests, this);
|
|
if (tests.Count != descriptions.Count)
|
|
throw new Exception();
|
|
for (int i = 0; i < tests.Count; i++)
|
|
{
|
|
if (descriptions[i] is not Description description)
|
|
throw new Exception();
|
|
if (description.Test != (int)tests[i])
|
|
throw new Exception();
|
|
}
|
|
List<Description> fileReadDescriptions = (from l in descriptions select (Description)l).ToList();
|
|
string json = JsonSerializer.Serialize(fileReadDescriptions, fileReadDescriptions.GetType());
|
|
JsonElement[] jsonElements = JsonSerializer.Deserialize<JsonElement[]>(json);
|
|
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(logistics.Logistics1[0], tests.ToArray(), jsonElements, fileInfoCollection);
|
|
return results;
|
|
}
|
|
|
|
internal static DateTime GetDateTime(Logistics logistics, long tickOffset, DateTime dateTime)
|
|
{
|
|
DateTime result;
|
|
if (dateTime < logistics.DateTimeFromSequence.AddDays(1) && dateTime > logistics.DateTimeFromSequence.AddDays(-1))
|
|
result = new(dateTime.Ticks + tickOffset);
|
|
else
|
|
result = logistics.DateTimeFromSequence;
|
|
return result;
|
|
}
|
|
|
|
private static (string, string) GetReactorAndRDS(string defaultReactor, string defaultRDS, string text, string formattedText, string[] segments)
|
|
{
|
|
string rds;
|
|
string reactor;
|
|
if (string.IsNullOrEmpty(text) || segments.Length == 0 || string.IsNullOrEmpty(formattedText))
|
|
reactor = defaultReactor;
|
|
else
|
|
reactor = segments[0];
|
|
if (segments.Length <= 1 || !int.TryParse(segments[1], out int rdsValue) || rdsValue < 99)
|
|
rds = defaultRDS;
|
|
else
|
|
rds = segments[1];
|
|
if (reactor.Length > 3)
|
|
{
|
|
rds = reactor;
|
|
reactor = defaultReactor;
|
|
}
|
|
return new(reactor, rds);
|
|
}
|
|
|
|
private static (string, string) GetLayerAndPSN(string defaultLayer, string defaultPSN, string[] segments)
|
|
{
|
|
string psn;
|
|
string layer;
|
|
if (segments.Length <= 2)
|
|
{
|
|
psn = defaultPSN;
|
|
layer = defaultLayer;
|
|
}
|
|
else
|
|
{
|
|
string[] segmentsB = segments[2].Split('.');
|
|
psn = segmentsB[0];
|
|
if (segmentsB.Length <= 1)
|
|
layer = defaultLayer;
|
|
else
|
|
{
|
|
layer = segmentsB[1];
|
|
if (layer.Length > 1 && layer[0] == '0')
|
|
layer = layer.Substring(1);
|
|
}
|
|
}
|
|
return (layer, psn);
|
|
}
|
|
|
|
private static string GetZone(string[] segments)
|
|
{
|
|
string result;
|
|
if (segments.Length <= 3)
|
|
result = string.Empty;
|
|
else
|
|
{
|
|
result = segments[3];
|
|
if (result.Length > 1 && result[0] == '0')
|
|
result = result.Substring(1);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static Descriptor GetDescriptor(string text)
|
|
{
|
|
Descriptor result;
|
|
string psn;
|
|
string rds;
|
|
string zone;
|
|
string layer;
|
|
string wafer;
|
|
string reactor;
|
|
string employee;
|
|
string defaultPSN = string.Empty;
|
|
string defaultRDS = string.Empty;
|
|
string defaultZone = string.Empty;
|
|
string defaultLayer = string.Empty;
|
|
string defaultReactor = string.Empty;
|
|
string defaultEmployee = string.Empty;
|
|
if (Regex.IsMatch(text, @"^[a-zA-z][0-9]{2,4}$"))
|
|
{
|
|
wafer = text.ToUpper();
|
|
psn = defaultPSN;
|
|
rds = defaultRDS;
|
|
zone = defaultZone;
|
|
layer = defaultLayer;
|
|
reactor = defaultReactor;
|
|
employee = defaultEmployee;
|
|
}
|
|
else if (string.IsNullOrEmpty(text) || (text.Length is 2 or 3 && Regex.IsMatch(text, "^[a-zA-z]{2,3}")))
|
|
{
|
|
wafer = text;
|
|
employee = text;
|
|
psn = defaultPSN;
|
|
rds = defaultRDS;
|
|
zone = defaultZone;
|
|
layer = defaultLayer;
|
|
reactor = defaultReactor;
|
|
}
|
|
else if (Regex.IsMatch(text, @"^[0-9]{2}[.][0-9]{1}[.]?[0-9]{0,1}"))
|
|
{
|
|
string[] segments = text.Split('.');
|
|
wafer = text;
|
|
psn = defaultPSN;
|
|
rds = defaultRDS;
|
|
layer = segments[1];
|
|
reactor = segments[0];
|
|
employee = defaultEmployee;
|
|
if (segments.Length <= 2)
|
|
zone = defaultZone;
|
|
else
|
|
zone = segments[2];
|
|
}
|
|
else
|
|
{
|
|
// Remove illegal characters \/:*?"<>| found in the Batch
|
|
wafer = Regex.Replace(text, @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]", "_").Split('\r')[0].Split('\n')[0];
|
|
if (wafer.Length > 2 && wafer[0] == '1' && (wafer[1] == 'T' || wafer[1] == 't'))
|
|
wafer = wafer.Substring(2);
|
|
string[] segments = wafer.Split('-');
|
|
// bool hasRDS = Regex.IsMatch(wafer, "[-]?([QP][0-9]{4,}|[0-9]{5,})[-]?");
|
|
(reactor, rds) = GetReactorAndRDS(defaultReactor, defaultRDS, text, wafer, segments);
|
|
(layer, psn) = GetLayerAndPSN(defaultLayer, defaultPSN, segments);
|
|
zone = GetZone(segments);
|
|
if (segments.Length <= 4)
|
|
employee = defaultEmployee;
|
|
else
|
|
employee = segments[4];
|
|
}
|
|
result = new(employee, layer, psn, rds, reactor, wafer, zone);
|
|
return result;
|
|
}
|
|
|
|
#pragma warning disable IDE0060
|
|
private static CSV Parse(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection)
|
|
#pragma warning restore IDE0060
|
|
{
|
|
CSV result;
|
|
string json = File.ReadAllText(logistics.ReportFullPath);
|
|
string directory = Path.GetDirectoryName(logistics.ReportFullPath);
|
|
string fileName = Path.Combine(directory, $"{Path.GetFileNameWithoutExtension(logistics.ReportFullPath)}.csv");
|
|
csv.CSV csv = JsonSerializer.Deserialize<csv.CSV>(json);
|
|
if (csv is null)
|
|
throw new NullReferenceException(nameof(csv));
|
|
result = new(csv);
|
|
if (File.Exists(fileName))
|
|
fileInfoCollection.Add(new(fileName));
|
|
fileInfoCollection.Add(logistics.FileInfo);
|
|
return result;
|
|
}
|
|
|
|
private void SetValues(Logistics logistics, long tickOffset, CSV csv)
|
|
{
|
|
string psn;
|
|
string rds;
|
|
string zone;
|
|
string layer;
|
|
Detail detail;
|
|
string reactor;
|
|
List<Detail> details = new();
|
|
string recipe = csv.Info.SampleName;
|
|
string employee = csv.Info.Operator;
|
|
string timeFormat = "yyyyMMddHHmmss";
|
|
DateTime dateTime = GetDateTime(logistics, tickOffset, csv.Info.DateTime);
|
|
string uniqueId = string.Concat(logistics.MesEntity, "_", logistics.DateTimeFromSequence.ToString(timeFormat));
|
|
// Remove illegal characters \/:*?"<>| found in the Batch
|
|
Descriptor descriptor = GetDescriptor(csv.Info.SampleName);
|
|
psn = descriptor.PSN;
|
|
rds = descriptor.RDS;
|
|
zone = descriptor.Zone;
|
|
layer = descriptor.Layer;
|
|
reactor = descriptor.Reactor;
|
|
if (string.IsNullOrEmpty(employee))
|
|
employee = descriptor.Employee;
|
|
PSN = psn;
|
|
RDS = rds;
|
|
Zone = zone;
|
|
Layer = layer;
|
|
Date = dateTime;
|
|
Recipe = recipe;
|
|
Reactor = reactor;
|
|
Employee = employee;
|
|
JobID = logistics.JobID;
|
|
SineBevelAngle = csv.Setup.SineBevelAngle.ToString();
|
|
XStep = csv.Setup.Steps.Count == 0 ? string.Empty : csv.Setup.Steps.First().X.ToString();
|
|
foreach (ProfilePoint profilePoint in csv.ProfileHeader.ProfilePoints)
|
|
{
|
|
detail = new()
|
|
{
|
|
HeaderUniqueId = uniqueId,
|
|
UniqueId = string.Concat(uniqueId, "_Point-", profilePoint.Number),
|
|
Number = profilePoint.Number.ToString(),
|
|
Depth = profilePoint.Depth.ToString(),
|
|
Raw = profilePoint.ResistanceRaw.ToString(),
|
|
Edited = string.Concat(profilePoint.ResistanceEdited),
|
|
Resistivity = string.Concat(profilePoint.Resistivity),
|
|
CD = string.Concat(profilePoint.Concentration),
|
|
};
|
|
details.Add(detail);
|
|
}
|
|
_Details.AddRange(details);
|
|
}
|
|
|
|
#nullable enable
|
|
#pragma warning disable CA1416
|
|
|
|
internal static List<Description> GetDescriptions(JsonElement[] jsonElements)
|
|
{
|
|
List<Description> results = new();
|
|
Description? description;
|
|
JsonSerializerOptions jsonSerializerOptions = new() { NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString };
|
|
foreach (JsonElement jsonElement in jsonElements)
|
|
{
|
|
if (jsonElement.ValueKind != JsonValueKind.Object)
|
|
throw new Exception();
|
|
description = JsonSerializer.Deserialize<Description>(jsonElement.ToString(), jsonSerializerOptions);
|
|
if (description is null)
|
|
continue;
|
|
results.Add(description);
|
|
}
|
|
return results;
|
|
}
|
|
|
|
} |