Match TFS Changeset 303361

This commit is contained in:
2022-02-01 19:49:09 -07:00
parent 6b4180dd68
commit a6abe8fdbd
115 changed files with 8097 additions and 13 deletions

View File

@ -0,0 +1,192 @@
using Library.Eaf.Core;
using Library.Eaf.EquipmentCore.Control;
using Library.Eaf.EquipmentCore.DataCollection.Reporting;
using Library.Eaf.EquipmentCore.SelfDescription.ElementDescription;
using Library.Eaf.EquipmentCore.SelfDescription.ParameterTypes;
using Library.Ifx.Eaf.EquipmentConnector.File.SelfDescription;
using Shared.Metrology;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
namespace Shared
{
public class Description
{
public enum RowColumn
{
Test = 1000,
Count,
Index
}
public enum LogisticsColumn
{
EventName = 2000,
NullData,
JobID,
Sequence,
MesEntity,
ReportFullPath,
ProcessJobID,
MID
}
public enum Param
{
String = 0,
Integer = 2,
Double = 3,
Boolean = 4,
StructuredType = 5
}
internal const string FileFound = "FileFound";
public List<EquipmentParameter> EquipmentParameters { get; private set; }
public List<ParameterTypeDefinition> ParameterTypeDefinitions { get; private set; }
private readonly bool _UseCyclical;
private readonly List<string> _HeaderNames;
private readonly Dictionary<string, int> _KeyIndexPairs;
private readonly ParameterTypeDefinition _StructuredType;
private readonly FileConnectorParameterTypeDefinitionProvider _FileConnectorParameterTypeDefinitionProvider;
public Description(ILogic logic, ConfigDataBase configDataBase, IEquipmentControl equipmentControl)
{
_KeyIndexPairs = new Dictionary<string, int>();
_HeaderNames = configDataBase.GetHeaderNames(logic);
_UseCyclical = configDataBase.UseCyclicalForDescription;
_StructuredType = new StructuredType(nameof(StructuredType), string.Empty, new List<Field>());
_FileConnectorParameterTypeDefinitionProvider = new FileConnectorParameterTypeDefinitionProvider();
EquipmentParameters = new List<EquipmentParameter>();
ParameterTypeDefinitions = new List<ParameterTypeDefinition> { _StructuredType };
Dictionary<string, List<Tuple<Enum, string, string, object>>> keyValuePairsCollection = configDataBase.GetParameterInfo(logic, allowNull: false);
List<ParameterValue> results = GetParameterValues(equipmentControl, keyValuePairsCollection);
}
private List<ParameterValue> GetParameterValues(IEquipmentControl equipmentControl, Dictionary<string, List<Tuple<Enum, string, string, object>>> keyValuePairsCollection)
{
List<ParameterValue> results = new List<ParameterValue>();
Enum param;
object value;
Enum[] @params;
string description;
List<object[]> list;
EquipmentParameter equipmentParameter;
ParameterTypeDefinition parameterTypeDefinition;
bool addToEquipmentParameters = !EquipmentParameters.Any();
foreach (KeyValuePair<string, List<Tuple<Enum, string, string, object>>> keyValuePair in keyValuePairsCollection)
{
if (!addToEquipmentParameters && !_KeyIndexPairs.ContainsKey(keyValuePair.Key))
continue;
@params = (from l in keyValuePair.Value select l.Item1).Distinct().ToArray();
if (@params.Length != 1)
throw new Exception();
if (keyValuePair.Value[0].Item2 != keyValuePair.Key)
throw new Exception();
param = @params[0];
if (!addToEquipmentParameters)
equipmentParameter = EquipmentParameters[_KeyIndexPairs[keyValuePair.Key]];
else
{
description = keyValuePair.Value[0].Item3;
_KeyIndexPairs.Add(keyValuePair.Key, EquipmentParameters.Count());
if (param is Param.StructuredType || (_UseCyclical && !_HeaderNames.Contains(keyValuePair.Key)))
parameterTypeDefinition = _StructuredType;
else
parameterTypeDefinition = _FileConnectorParameterTypeDefinitionProvider.GetParameterTypeDefinition(param.ToString());
equipmentParameter = new EquipmentParameter(keyValuePair.Key, parameterTypeDefinition, description);
EquipmentParameters.Add(equipmentParameter);
}
if (!_UseCyclical || _HeaderNames.Contains(keyValuePair.Key))
value = keyValuePair.Value[0].Item4;
else
{
list = new List<object[]>();
for (int i = 0; i < keyValuePair.Value.Count; i++)
list.Add(new object[] { i, keyValuePair.Value[i].Item4 });
value = list;
}
if (equipmentControl is null || !(param is Param.StructuredType))
results.Add(new ParameterValue(equipmentParameter, value, DateTime.Now));
else
results.Add(equipmentControl.DataCollection.CreateParameterValue(equipmentParameter, value));
}
return results;
}
public List<ParameterValue> GetParameterValues(ILogic logic, IEquipmentControl equipmentControl, JsonElement jsonElement, int? i = null, Dictionary<string, object> keyValuePairs = null)
{
List<ParameterValue> results = new List<ParameterValue>();
if (_UseCyclical && (i is null || i.Value > 0))
throw new Exception();
if (jsonElement.ValueKind != JsonValueKind.Array)
throw new Exception();
Enum param;
Tuple<Enum, string, string, object> tuple;
JsonElement[] jsonElements = jsonElement.EnumerateArray().ToArray();
Dictionary<string, List<Tuple<Enum, string, string, object>>> keyValuePairsCollection = new Dictionary<string, List<Tuple<Enum, string, string, object>>>();
for (int r = i.Value; r < jsonElements.Length; r++)
{
foreach (JsonProperty jsonProperty in jsonElement[r].EnumerateObject())
{
if (jsonProperty.Value.ValueKind == JsonValueKind.Object || jsonProperty.Value.ValueKind == JsonValueKind.Array)
{
param = Param.StructuredType;
//jValue = jObject.Value<JValue>("Item1");
throw new NotImplementedException("Item1");
}
else
{
switch (jsonProperty.Value.ValueKind)
{
case JsonValueKind.String:
param = Param.String;
break;
case JsonValueKind.Number:
param = Param.Double;
break;
case JsonValueKind.True:
case JsonValueKind.False:
param = Param.Boolean;
break;
case JsonValueKind.Null:
param = Param.String;
break;
default:
param = Param.StructuredType;
break;
}
}
tuple = new Tuple<Enum, string, string, object>(param, jsonProperty.Name, string.Empty, jsonProperty.Value.ToString());
if (!keyValuePairsCollection.ContainsKey(jsonProperty.Name))
keyValuePairsCollection.Add(jsonProperty.Name, new List<Tuple<Enum, string, string, object>>());
keyValuePairsCollection[jsonProperty.Name].Add(tuple);
}
if (!_UseCyclical)
break;
}
results = GetParameterValues(equipmentControl, keyValuePairsCollection);
return results;
}
public static string GetCellName()
{
string result;
if (Backbone.Instance?.CellName is null)
result = string.Empty;
else
result = Backbone.Instance.CellName;
if (result.Contains("-IO"))
result = result.Replace("-IO", string.Empty);
return result;
}
}
}

View File

@ -0,0 +1,53 @@
namespace Shared
{
public enum EquipmentType
{
FileEquipment,
SemiEquipment,
//
DEP08EGANAIXG5,
//
MET08ANLYSDIFAAST230_Semi,
MET08DDUPSFS6420,
MET08DDUPSP1TBI,
MET08RESIHGCV,
MET08RESIMAPCDE,
MET08THFTIRQS408M,
MET08THFTIRSTRATUS,
//
MET08AFMD3100,
MET08BVHGPROBE,
MET08CVHGPROBE802B150,
MET08CVHGPROBE802B150_Monthly,
MET08CVHGPROBE802B150_Weekly,
MET08DDINCAN8620,
MET08DDINCAN8620_Daily,
MET08EBEAMINTEGRITY26,
MET08HALLHL5580,
MET08HALLHL5580_Monthly,
MET08HALLHL5580_Weekly,
MET08MESMICROSCOPE,
MET08NDFRESIMAP151C,
MET08NDFRESIMAP151C_Verification,
MET08PLMAPRPM,
MET08PLMAPRPM_Daily,
MET08PLMAPRPM_Verification,
MET08PLMPPLATO,
MET08PRFUSB4000,
MET08PRFUSB4000_Daily,
MET08PRFUSB4000_Monthly,
MET08PRFUSB4000_Weekly,
MET08PRFUSB4000_Verification,
MET08PRFUSB4000_Villach,
MET08UVH44GS100M,
MET08VPDSUBCON,
MET08WGEOMX203641Q,
MET08WGEOMX203641Q_Verification,
MET08XRDXPERTPROMRDXL,
MET08XRDXPERTPROMRDXL_Monthly,
MET08XRDXPERTPROMRDXL_Weekly,
METBRXRAYJV7300L
}
}

View File

@ -0,0 +1,16 @@
using Shared.Metrology;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
namespace Shared
{
public interface IProcessData
{
Tuple<string, JsonElement?, List<FileInfo>> GetResults(ILogic logic, ConfigDataBase configData, List<FileInfo> fileInfoCollection);
}
}

View File

@ -0,0 +1,26 @@
using Shared.Metrology;
using System.Collections.Generic;
namespace Shared
{
public interface IProcessDataDescription
{
int Test { get; set; }
int Count { get; set; }
int Index { get; set; }
IProcessDataDescription GetDefault(ILogic logic, ConfigDataBase configDataBase);
IProcessDataDescription GetDisplayNames(ILogic logic, ConfigDataBase configDataBase);
List<IProcessDataDescription> GetDescription(ILogic logic, ConfigDataBase configDataBase, List<Test> tests, IProcessData iProcessData);
List<string> GetDetailNames(ILogic logic, ConfigDataBase configDataBase);
List<string> GetHeaderNames(ILogic logic, ConfigDataBase configDataBase);
List<string> GetIgnoreParameterNames(ILogic logic, ConfigDataBase configDataBase, Test test);
List<string> GetNames(ILogic logic, ConfigDataBase configDataBase);
List<string> GetPairedParameterNames(ILogic logic, ConfigDataBase configDataBase);
List<string> GetParameterNames(ILogic logic, ConfigDataBase configDataBase);
string GetEventDescription();
}
}

View File

@ -0,0 +1,21 @@
using System;
namespace Shared
{
public interface IScopeInfo
{
Enum Enum { get; }
string HTML { get; }
string Title { get; }
string FileName { get; }
int TestValue { get; }
string Header { get; }
string QueryFilter { get; }
string FileNameWithoutExtension { get; }
EquipmentType EquipmentType { get; }
}
}

View File

@ -0,0 +1,171 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace Shared
{
public class IsEnvironment
{
public enum Name
{
LinuxDevelopment,
LinuxProduction,
LinuxStaging,
OSXDevelopment,
OSXProduction,
OSXStaging,
WindowsDevelopment,
WindowsProduction,
WindowsStaging
}
public bool DebuggerWasAttachedDuringConstructor { get; private set; }
public bool Development { get; private set; }
public bool Linux { get; private set; }
public bool OSX { get; private set; }
public bool Production { get; private set; }
public bool Staging { get; private set; }
public bool Windows { get; private set; }
public string Profile { get; private set; }
public string AppSettingsFileName { get; private set; }
public string ASPNetCoreEnvironment { get; private set; }
public IsEnvironment(string testCategory)
{
if (testCategory.EndsWith(".json"))
{
Production = testCategory == "appsettings.json";
Staging = testCategory.EndsWith(nameof(Staging));
OSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
Development = testCategory.EndsWith(nameof(Development));
Linux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
DebuggerWasAttachedDuringConstructor = Debugger.IsAttached;
Windows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
ASPNetCoreEnvironment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
}
else
{
DebuggerWasAttachedDuringConstructor = Debugger.IsAttached;
OSX = !string.IsNullOrEmpty(testCategory) && testCategory.StartsWith(nameof(OSX));
ASPNetCoreEnvironment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
Linux = !string.IsNullOrEmpty(testCategory) && testCategory.StartsWith(nameof(Linux));
Staging = !string.IsNullOrEmpty(testCategory) && testCategory.EndsWith(nameof(Staging));
Windows = !string.IsNullOrEmpty(testCategory) && testCategory.StartsWith(nameof(Windows));
Production = !string.IsNullOrEmpty(testCategory) && testCategory.EndsWith(nameof(Production));
Development = !string.IsNullOrEmpty(testCategory) && testCategory.EndsWith(nameof(Development));
}
Profile = GetProfile();
AppSettingsFileName = GetAppSettingsFileName(processesCount: null);
}
public IsEnvironment(bool isDevelopment, bool isStaging, bool isProduction)
{
Staging = isStaging;
Production = isProduction;
Development = isDevelopment;
OSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
Linux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
DebuggerWasAttachedDuringConstructor = Debugger.IsAttached;
Windows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
ASPNetCoreEnvironment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
Profile = GetProfile();
AppSettingsFileName = GetAppSettingsFileName(processesCount: null);
}
public IsEnvironment(int? processesCount, bool nullASPNetCoreEnvironmentIsDevelopment, bool nullASPNetCoreEnvironmentIsProduction)
{
OSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
Linux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
DebuggerWasAttachedDuringConstructor = Debugger.IsAttached;
Windows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
ASPNetCoreEnvironment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
if (nullASPNetCoreEnvironmentIsDevelopment && nullASPNetCoreEnvironmentIsProduction)
throw new Exception();
else if (string.IsNullOrEmpty(ASPNetCoreEnvironment) && nullASPNetCoreEnvironmentIsProduction)
Production = true;
else if (string.IsNullOrEmpty(ASPNetCoreEnvironment) && nullASPNetCoreEnvironmentIsDevelopment)
Development = true;
else if (string.IsNullOrEmpty(ASPNetCoreEnvironment) && !nullASPNetCoreEnvironmentIsDevelopment && !nullASPNetCoreEnvironmentIsProduction)
throw new Exception();
else
{
Staging = ASPNetCoreEnvironment is not null && ASPNetCoreEnvironment.EndsWith(nameof(Staging));
Production = ASPNetCoreEnvironment is not null && ASPNetCoreEnvironment.EndsWith(nameof(Production));
Development = ASPNetCoreEnvironment is not null && ASPNetCoreEnvironment.EndsWith(nameof(Development));
}
Profile = GetProfile();
AppSettingsFileName = GetAppSettingsFileName(processesCount);
}
private string GetProfile()
{
string result;
if (Windows && Production)
result = nameof(Production);
else if (Windows && Staging)
result = nameof(Staging);
else if (Windows && Development)
result = nameof(Development);
else if (Linux && Production)
result = nameof(Name.LinuxProduction);
else if (Linux && Staging)
result = nameof(Name.LinuxStaging);
else if (Linux && Development)
result = nameof(Name.LinuxDevelopment);
else if (OSX && Production)
result = nameof(Name.OSXProduction);
else if (OSX && Staging)
result = nameof(Name.OSXStaging);
else if (OSX && Development)
result = nameof(Name.OSXDevelopment);
else
throw new Exception();
return result;
}
private string GetAppSettingsFileName(int? processesCount)
{
string result;
if (Production)
{
if (processesCount is null)
result = "appsettings.json";
else
result = $"appsettings.{processesCount}.json";
}
else
{
string environment;
if (Staging)
environment = nameof(Staging);
else if (Development)
environment = nameof(Development);
else
throw new Exception();
if (processesCount is null)
result = $"appsettings.{environment}.json";
else
result = $"appsettings.{environment}.{processesCount}.json";
}
return result;
}
public static string GetEnvironmentName(IsEnvironment isEnvironment)
{
string result;
if (isEnvironment.Windows)
result = nameof(IsEnvironment.Windows);
else if (isEnvironment.Linux)
result = nameof(IsEnvironment.Linux);
else if (isEnvironment.OSX)
result = nameof(IsEnvironment.OSX);
else
throw new Exception();
return result;
}
}
}

View File

@ -0,0 +1,245 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Shared
{
public class Logistics
{
public object NullData { get; private set; }
public string JobID { get; private set; } //CellName
public long Sequence { get; private set; } //Ticks
public DateTime DateTimeFromSequence { get; private set; }
public double TotalSecondsSinceLastWriteTimeFromSequence { get; private set; }
public string MesEntity { get; private set; } //SPC
public string ReportFullPath { get; private set; } //Extract file
public string ProcessJobID { get; internal set; } //Reactor (duplicate but I want it in the logistics)
public string MID { get; internal set; } //Lot & Pocket || Lot
public List<string> Tags { get; internal set; }
public List<string> Logistics1 { get; internal set; }
public List<Logistics2> Logistics2 { get; internal set; }
public Logistics()
{
DateTime dateTime = DateTime.Now;
NullData = null;
JobID = Description.GetCellName();
Sequence = dateTime.Ticks;
DateTimeFromSequence = dateTime;
TotalSecondsSinceLastWriteTimeFromSequence = (DateTime.Now - dateTime).TotalSeconds;
MesEntity = DefaultMesEntity(dateTime);
ReportFullPath = string.Empty;
ProcessJobID = nameof(ProcessJobID);
MID = nameof(MID);
Tags = new List<string>();
Logistics1 = new string[] { string.Concat("LOGISTICS_1", '\t', "A_JOBID=", JobID, ";A_MES_ENTITY=", MesEntity, ";") }.ToList();
Logistics2 = new List<Logistics2>();
}
public Logistics(object nullData, Dictionary<string, string> cellNames, Dictionary<string, string> mesEntities, FileInfo fileInfo, bool useSplitForMID, int? fileInfoLength = null)
{
NullData = nullData;
string mesEntity = string.Empty;
string jobID = Description.GetCellName();
DateTime dateTime = fileInfo.LastWriteTime;
if (fileInfoLength.HasValue && fileInfo.Length < fileInfoLength.Value)
dateTime = dateTime.AddTicks(-1);
if (string.IsNullOrEmpty(jobID))
{
if (cellNames.Count == 1)
jobID = cellNames.ElementAt(0).Key;
else
{
string reportFullPathLower = fileInfo.FullName.ToLower();
foreach (var element in cellNames)
{
if (reportFullPathLower.Contains(element.Key) || reportFullPathLower.Contains(element.Value))
{
jobID = element.Key;
break;
}
}
}
}
if (string.IsNullOrEmpty(jobID))
throw new Exception();
if (mesEntities.ContainsKey(jobID))
mesEntity = mesEntities[jobID];
else if (mesEntities.Count == 1)
mesEntity = mesEntities.ElementAt(0).Value;
//
if (string.IsNullOrEmpty(mesEntity))
throw new Exception();
JobID = jobID;
Sequence = dateTime.Ticks;
DateTimeFromSequence = dateTime;
TotalSecondsSinceLastWriteTimeFromSequence = (DateTime.Now - dateTime).TotalSeconds;
MesEntity = mesEntity;
ReportFullPath = fileInfo.FullName;
ProcessJobID = nameof(ProcessJobID);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
if (useSplitForMID)
{
if (fileNameWithoutExtension.IndexOf(".") > -1)
fileNameWithoutExtension = fileNameWithoutExtension.Split('.')[0].Trim();
if (fileNameWithoutExtension.IndexOf("_") > -1)
fileNameWithoutExtension = fileNameWithoutExtension.Split('_')[0].Trim();
if (fileNameWithoutExtension.IndexOf("-") > -1)
fileNameWithoutExtension = fileNameWithoutExtension.Split('-')[0].Trim();
}
MID = string.Concat(fileNameWithoutExtension.Substring(0, 1).ToUpper(), fileNameWithoutExtension.Substring(1).ToLower());
Tags = new List<string>();
Logistics1 = new string[] { string.Concat("LOGISTICS_1", '\t', "A_JOBID=", JobID, ";A_MES_ENTITY=", MesEntity, ";") }.ToList();
Logistics2 = new List<Logistics2>();
}
public Logistics(string reportFullPath, string logistics)
{
string key;
DateTime dateTime;
string[] segments;
Logistics1 = logistics.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).ToList();
if (!Logistics1.Any() || !Logistics1[0].StartsWith("LOGISTICS_1"))
{
NullData = null;
JobID = "null";
dateTime = new FileInfo(reportFullPath).LastWriteTime;
Sequence = dateTime.Ticks;
DateTimeFromSequence = dateTime;
TotalSecondsSinceLastWriteTimeFromSequence = (DateTime.Now - dateTime).TotalSeconds;
MesEntity = DefaultMesEntity(dateTime);
ReportFullPath = reportFullPath;
ProcessJobID = "R##";
MID = "null";
Tags = new List<string>();
Logistics1 = new string[] { string.Concat("LOGISTICS_1", '\t', "A_JOBID=", JobID, ";A_MES_ENTITY=", MesEntity, ";") }.ToList();
Logistics2 = new List<Logistics2>();
}
else
{
string logistics1Line1 = Logistics1[0];
key = "NULL_DATA=";
if (!logistics1Line1.Contains(key))
NullData = null;
else
{
segments = logistics1Line1.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
NullData = segments[1].Split(';')[0];
}
key = "JOBID=";
if (!logistics1Line1.Contains(key))
JobID = "null";
else
{
segments = logistics1Line1.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
JobID = segments[1].Split(';')[0];
}
key = "SEQUENCE=";
if (!logistics1Line1.Contains(key))
dateTime = new FileInfo(reportFullPath).LastWriteTime;
else
{
segments = logistics1Line1.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
if (!long.TryParse(segments[1].Split(';')[0].Split('.')[0], out long sequence) || sequence < new DateTime(1999, 1, 1).Ticks)
dateTime = new FileInfo(reportFullPath).LastWriteTime;
else
dateTime = new DateTime(sequence);
}
Sequence = dateTime.Ticks;
DateTimeFromSequence = dateTime;
TotalSecondsSinceLastWriteTimeFromSequence = (DateTime.Now - dateTime).TotalSeconds;
DateTime lastWriteTime = new FileInfo(reportFullPath).LastWriteTime;
if (TotalSecondsSinceLastWriteTimeFromSequence > 600)
{
if (lastWriteTime != dateTime)
try
{ File.SetLastWriteTime(reportFullPath, dateTime); }
catch (Exception) { }
}
key = "MES_ENTITY=";
if (!logistics1Line1.Contains(key))
MesEntity = DefaultMesEntity(dateTime);
else
{
segments = logistics1Line1.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
MesEntity = segments[1].Split(';')[0];
}
ReportFullPath = reportFullPath;
key = "PROCESS_JOBID=";
if (!logistics1Line1.Contains(key))
ProcessJobID = "R##";
else
{
segments = logistics1Line1.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
ProcessJobID = segments[1].Split(';')[0];
}
key = "MID=";
if (!logistics1Line1.Contains(key))
MID = "null";
else
{
segments = logistics1Line1.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
MID = segments[1].Split(';')[0];
}
}
Logistics2 logistics2;
Tags = new List<string>();
Logistics2 = new List<Logistics2>();
for (int i = 1; i < Logistics1.Count(); i++)
{
if (Logistics1[i].StartsWith("LOGISTICS_2"))
{
logistics2 = new Logistics2(Logistics1[i]);
Logistics2.Add(logistics2);
}
}
for (int i = Logistics1.Count() - 1; i > -1; i--)
{
if (Logistics1[i].StartsWith("LOGISTICS_2"))
Logistics1.RemoveAt(i);
}
}
public Logistics ShallowCopy()
{
return (Logistics)MemberwiseClone();
}
private string DefaultMesEntity(DateTime dateTime)
{
return string.Concat(dateTime.Ticks, "_MES_ENTITY");
}
internal string GetLotViaMostCommonMethod()
{
return MID.Substring(0, MID.Length - 2);
}
internal string GetPocketNumberViaMostCommonMethod()
{
return MID.Substring(MID.Length - 2);
}
internal void Update(string dateTime, string processJobID, string mid)
{
if (!DateTime.TryParse(dateTime, out DateTime dateTimeCasted))
dateTimeCasted = DateTime.Now;
NullData = null;
//JobID = Description.GetCellName();
Sequence = dateTimeCasted.Ticks;
DateTimeFromSequence = dateTimeCasted;
TotalSecondsSinceLastWriteTimeFromSequence = (DateTime.Now - dateTimeCasted).TotalSeconds;
//MesEntity = DefaultMesEntity(dateTime);
//ReportFullPath = string.Empty;
ProcessJobID = processJobID;
MID = mid;
Tags = new List<string>();
Logistics1 = new string[] { string.Concat("LOGISTICS_1", '\t', "A_JOBID=", JobID, ";A_MES_ENTITY=", MesEntity, ";") }.ToList();
Logistics2 = new List<Logistics2>();
}
}
}

View File

@ -0,0 +1,80 @@
using System;
namespace Shared
{
public class Logistics2
{
public string MID { get; private set; }
public string RunNumber { get; private set; }
public string SatelliteGroup { get; private set; }
public string PartNumber { get; private set; }
public string PocketNumber { get; private set; }
public string WaferLot { get; private set; }
public string Recipe { get; private set; }
public Logistics2(string logistics2)
{
string key;
string[] segments;
key = "JOBID=";
if (!logistics2.Contains(key))
MID = "null";
else
{
segments = logistics2.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
MID = segments[1].Split(';')[0];
}
key = "MID=";
if (!logistics2.Contains(key))
RunNumber = "null";
else
{
segments = logistics2.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
RunNumber = segments[1].Split(';')[0];
}
key = "INFO=";
if (!logistics2.Contains(key))
SatelliteGroup = "null";
else
{
segments = logistics2.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
SatelliteGroup = segments[1].Split(';')[0];
}
key = "PRODUCT=";
if (!logistics2.Contains(key))
PartNumber = "null";
else
{
segments = logistics2.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
PartNumber = segments[1].Split(';')[0];
}
key = "CHAMBER=";
if (!logistics2.Contains(key))
PocketNumber = "null";
else
{
segments = logistics2.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
PocketNumber = segments[1].Split(';')[0];
}
key = "WAFER_ID=";
if (!logistics2.Contains(key))
WaferLot = "null";
else
{
segments = logistics2.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
WaferLot = segments[1].Split(';')[0];
}
key = "PPID=";
if (!logistics2.Contains(key))
Recipe = "null";
else
{
segments = logistics2.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
Recipe = segments[1].Split(';')[0];
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,410 @@
using Library.Ifx.Eaf.EquipmentConnector.File.Configuration;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Shared.Metrology
{
public class ConfigDataBase
{
public bool UseCyclicalForDescription { get; protected set; }
public Dictionary<string, string> CellNames { get; protected set; }
public Dictionary<string, string> MesEntities { get; protected set; }
public IProcessDataDescription ProcessDataDescription { get; protected set; }
public bool IsEvent { get; private set; }
public EventName EventName => _EventName;
public bool EafHosted { get; private set; }
public string CellName { get; private set; }
public bool IsSourceTimer { get; private set; }
public EquipmentType EquipmentType => _EquipmentType;
public string EquipmentElementName { get; private set; }
public bool IsDatabaseExportToIPDSF { get; private set; }
public EquipmentType? EquipmentConnection => _EquipmentConnection;
public FileConnectorConfiguration FileConnectorConfiguration { get; private set; }
protected readonly EventName _EventName;
protected readonly EquipmentType _EquipmentType;
protected readonly EquipmentType? _EquipmentConnection;
protected readonly Dictionary<string, string> _Reactors;
public ConfigDataBase(string cellName, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, bool isEAFHosted)
{
CellName = cellName;
EafHosted = isEAFHosted;
EquipmentType equipmentTypeValue;
_Reactors = new Dictionary<string, string>();
CellNames = new Dictionary<string, string>();
MesEntities = new Dictionary<string, string>();
EquipmentElementName = cellInstanceConnectionName;
FileConnectorConfiguration = fileConnectorConfiguration;
string[] segments = parameterizedModelObjectDefinitionType.Split('.');
IsSourceTimer = (fileConnectorConfiguration.SourceFileFilter.StartsWith("*Timer.txt"));
string cellInstanceConnectionNameBase = cellInstanceConnectionName.Replace("-", string.Empty);
IsDatabaseExportToIPDSF = (fileConnectorConfiguration.SourceFileLocation.Contains("DatabaseExport"));
if (!Enum.TryParse(segments[segments.Length - 1], out EventName eventNameValue))
throw new Exception(cellInstanceConnectionName);
if (!Enum.TryParse(cellInstanceConnectionNameBase, out equipmentTypeValue))
_EquipmentConnection = null;
else
_EquipmentConnection = equipmentTypeValue;
string suffix;
switch (eventNameValue)
{
case EventName.FileRead:
suffix = string.Empty;
break;
case EventName.FileReadDaily:
suffix = "_Daily";
break;
case EventName.FileReadWeekly:
suffix = "_Weekly";
break;
case EventName.FileReadMonthly:
suffix = "_Monthly";
break;
case EventName.FileReadVerification:
suffix = "_Verification";
break;
default:
throw new Exception(cellInstanceConnectionName);
}
string parameterizedModelObjectDefinitionTypeAppended = string.Concat(segments[0], suffix);
IsEvent = cellInstanceConnectionNameBase != parameterizedModelObjectDefinitionTypeAppended;
_EventName = eventNameValue;
if (!Enum.TryParse(parameterizedModelObjectDefinitionTypeAppended, out equipmentTypeValue))
throw new Exception(cellInstanceConnectionName);
_EquipmentType = equipmentTypeValue;
if (!isEAFHosted && equipmentTypeName != parameterizedModelObjectDefinitionTypeAppended)
throw new Exception(cellInstanceConnectionName);
}
public string GetEventName()
{
string result = EventName.ToString();
return result;
}
public string GetEquipmentType()
{
string result = EquipmentConnection.ToString();
return result;
}
public string GetEventDescription()
{
string result = ProcessDataDescription.GetEventDescription();
return result;
}
public IProcessDataDescription GetDefault(ILogic logic)
{
IProcessDataDescription result = ProcessDataDescription.GetDefault(logic, this);
return result;
}
public IProcessDataDescription GetDisplayNames(ILogic logic)
{
IProcessDataDescription result = ProcessDataDescription.GetDisplayNames(logic, this);
return result;
}
public List<string> GetDetailNames(ILogic logic)
{
List<string> results = ProcessDataDescription.GetDetailNames(logic, this);
return results;
}
public List<string> GetHeaderNames(ILogic logic)
{
List<string> results = ProcessDataDescription.GetHeaderNames(logic, this);
return results;
}
public List<string> GetNames(ILogic logic)
{
List<string> results = ProcessDataDescription.GetNames(logic, this);
return results;
}
public List<string> GetPairedParameterNames(ILogic logic)
{
List<string> results = ProcessDataDescription.GetPairedParameterNames(logic, this);
return results;
}
public List<string> GetParameterNames(ILogic logic)
{
List<string> results = ProcessDataDescription.GetParameterNames(logic, this);
return results;
}
public List<IProcessDataDescription> GetDescription(ILogic logic, List<Test> tests, IProcessData iProcessData)
{
List<IProcessDataDescription> results = ProcessDataDescription.GetDescription(logic, this, tests, iProcessData);
return results;
}
public string GetCurrentReactor(ILogic logic)
{
string result = string.Empty;
foreach (KeyValuePair<string, string> keyValuePair in _Reactors)
{
foreach (string filePrefix in keyValuePair.Value.Split('|'))
{
if (logic.Logistics.MID.StartsWith(filePrefix) || (EventName != EventName.FileRead && MesEntities.ContainsKey(logic.Logistics.JobID) && keyValuePair.Value == MesEntities[logic.Logistics.JobID]))
{
result = keyValuePair.Key;
break;
}
}
}
if (string.IsNullOrEmpty(result) && _Reactors.Count == 1)
result = _Reactors.ElementAt(0).Key;
return result;
}
protected JsonElement GetDefaultJsonElement(ILogic logic)
{
JsonElement result;
IProcessDataDescription processDataDescription = ProcessDataDescription.GetDefault(logic, this);
string json = JsonSerializer.Serialize(processDataDescription, processDataDescription.GetType());
object @object = JsonSerializer.Deserialize<object>(json);
result = (JsonElement)@object;
return result;
}
public Dictionary<string, List<Tuple<Enum, string, string, object>>> GetParameterInfo(ILogic logic, bool allowNull)
{
Dictionary<string, List<Tuple<Enum, string, string, object>>> results = new Dictionary<string, List<Tuple<Enum, string, string, object>>>();
string description;
Enum param;
Tuple<Enum, string, string, object> tuple;
JsonElement defaultJsonElement = GetDefaultJsonElement(logic);
Dictionary<string, string> keyValuePairs = GetDisplayNamesJsonElement(logic);
foreach (JsonProperty jsonProperty in defaultJsonElement.EnumerateObject())
{
if (jsonProperty.Value.ValueKind == JsonValueKind.Null && !allowNull)
throw new Exception();
if (jsonProperty.Value.ValueKind == JsonValueKind.Object || jsonProperty.Value.ValueKind == JsonValueKind.Array)
{
description = string.Empty;
param = Description.Param.StructuredType;
//jValue = jObject.Value<JValue>("Item1");
throw new NotImplementedException("Item1");
}
else
{
switch (jsonProperty.Value.ValueKind)
{
case JsonValueKind.String:
param = Description.Param.String;
break;
case JsonValueKind.Number:
param = Description.Param.Double;
break;
case JsonValueKind.True:
case JsonValueKind.False:
param = Description.Param.Boolean;
break;
case JsonValueKind.Null:
param = Description.Param.String;
break;
default:
param = Description.Param.StructuredType;
break;
}
}
if (!keyValuePairs.ContainsKey(jsonProperty.Name))
description = string.Empty;
else
description = keyValuePairs[jsonProperty.Name];
tuple = new Tuple<Enum, string, string, object>(param, jsonProperty.Name, description, jsonProperty.Value.ToString());
if (!results.ContainsKey(jsonProperty.Name))
results.Add(jsonProperty.Name, new List<Tuple<Enum, string, string, object>>());
results[jsonProperty.Name].Add(tuple);
}
return results;
}
protected void WriteExportAliases(ILogic logic, string cellName, string equipmentElementName)
{
int i = 0;
Enum param;
object value;
Enum[] @params;
string description;
StringBuilder stringBuilder = new StringBuilder();
string shareRoot = @"\\messv02ecc1.ec.local\EC_EDA";
string shareDirectory = string.Concat(shareRoot, @"\Staging\Pdsf\", cellName, @"\ExportAliases\", equipmentElementName);
Dictionary<string, List<Tuple<Enum, string, string, object>>> keyValuePairs;
if (!(logic is null))
keyValuePairs = GetParameterInfo(logic, allowNull: false);
else
keyValuePairs = new Dictionary<string, List<Tuple<Enum, string, string, object>>>();
stringBuilder.AppendLine("\"AliasName\";\"Condition\";\"EventId\";\"ExceptionId\";\"Formula\";\"HardwareId\";\"OrderId\";\"ParameterName\";\"Remark\";\"ReportName\";\"SourceId\";\"Use\"");
if (!Directory.Exists(shareRoot))
return;
if (!Directory.Exists(shareDirectory))
Directory.CreateDirectory(shareDirectory);
string shareFile = string.Concat(shareDirectory, @"\", DateTime.Now.Ticks, ".csv");
foreach (KeyValuePair<string, List<Tuple<Enum, string, string, object>>> keyValuePair in keyValuePairs)
{
i += 1;
@params = (from l in keyValuePair.Value select l.Item1).Distinct().ToArray();
if (@params.Length != 1)
throw new Exception();
if (keyValuePair.Value[0].Item2 != keyValuePair.Key)
throw new Exception();
param = @params[0];
if (!(param is Description.Param.String))
stringBuilder.AppendLine($"\"{keyValuePair.Key}\";\"\";\"\";\"\";\"\";\"\";\"{i}\";\"{cellName}/{EquipmentElementName}/{keyValuePair.Key}\";\"\";\"{cellName}/{EquipmentElementName}/{EventName}\";\"\";\"True\"");
else
{
description = keyValuePair.Value[0].Item3.Split('|')[0];
if (string.IsNullOrEmpty(description))
continue;
value = keyValuePair.Value[0].Item4;
stringBuilder.AppendLine($"\"'{description}'\";\"\";\"\";\"\";\"\";\"\";\"{i}\";\"{cellName}/{EquipmentElementName}/{value}\";\"\";\"{cellName}/{EquipmentElementName}/{EventName}\";\"\";\"True\"");
}
}
if (keyValuePairs.Any())
File.WriteAllText(shareFile, stringBuilder.ToString());
}
public Dictionary<string, string> GetDisplayNamesJsonElement(ILogic logic)
{
Dictionary<string, string> results = new Dictionary<string, string>();
IProcessDataDescription processDataDescription = ProcessDataDescription.GetDisplayNames(logic, this);
string json = JsonSerializer.Serialize(processDataDescription, processDataDescription.GetType());
JsonElement jsonElement = JsonSerializer.Deserialize<JsonElement>(json);
foreach (JsonProperty jsonProperty in jsonElement.EnumerateObject())
{
if (!results.ContainsKey(jsonProperty.Name))
results.Add(jsonProperty.Name, string.Empty);
if (jsonProperty.Value is JsonElement jsonPropertyValue)
results[jsonProperty.Name] = jsonPropertyValue.ToString();
}
return results;
}
public List<string> GetIgnoreParameterNames(ILogic logic, Test test, bool includePairedParameterNames)
{
List<string> results = ProcessDataDescription.GetIgnoreParameterNames(logic, this, test);
if (includePairedParameterNames)
{
string value;
List<string> pairedParameterNames = ProcessDataDescription.GetPairedParameterNames(logic, this);
IProcessDataDescription processDataDescription = ProcessDataDescription.GetDisplayNames(logic, this);
string json = JsonSerializer.Serialize(processDataDescription, processDataDescription.GetType());
object @object = JsonSerializer.Deserialize<object>(json);
if (!(@object is JsonElement jsonElement))
throw new Exception();
foreach (JsonProperty jsonProperty in jsonElement.EnumerateObject())
{
if (jsonProperty.Value.ValueKind == JsonValueKind.Object || jsonProperty.Value.ValueKind == JsonValueKind.Array)
throw new Exception();
value = jsonProperty.Value.ToString();
if (!results.Contains(jsonProperty.Name) && pairedParameterNames.Contains(jsonProperty.Name) && (string.IsNullOrEmpty(value) || value[0] == '|'))
results.Add(jsonProperty.Name);
}
}
return results;
}
public List<Duplicator.Description> GetProcessDataDescriptions(JsonElement jsonElement)
{
List<Duplicator.Description> results;
if (jsonElement.ValueKind != JsonValueKind.Array)
throw new Exception();
JsonSerializerOptions jsonSerializerOptions = new JsonSerializerOptions { NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString };
results = JsonSerializer.Deserialize<List<Duplicator.Description>>(jsonElement.ToString(), jsonSerializerOptions);
return results;
}
public Dictionary<Test, List<Duplicator.Description>> GetKeyValuePairs(List<Duplicator.Description> processDataDescriptions)
{
Dictionary<Test, List<Duplicator.Description>> results = new Dictionary<Test, List<Duplicator.Description>>();
Test testKey;
for (int i = 0; i < processDataDescriptions.Count; i++)
{
testKey = (Test)processDataDescriptions[i].Test;
if (!results.ContainsKey(testKey))
results.Add(testKey, new List<Duplicator.Description>());
results[testKey].Add(processDataDescriptions[i]);
}
return results;
}
public Dictionary<string, List<string>> GetKeyValuePairs(JsonElement jsonElement, List<Duplicator.Description> processDataDescriptions, Test test)
{
Dictionary<string, List<string>> results = new Dictionary<string, List<string>>();
Test testKey;
if (jsonElement.ValueKind != JsonValueKind.Array)
throw new Exception();
JsonElement[] jsonElements = jsonElement.EnumerateArray().ToArray();
if (processDataDescriptions.Count != jsonElements.Length)
throw new Exception();
for (int i = 0; i < processDataDescriptions.Count; i++)
{
testKey = (Test)processDataDescriptions[i].Test;
if (testKey != test)
continue;
foreach (JsonProperty jsonProperty in jsonElements[i].EnumerateObject())
{
if (jsonProperty.Value.ValueKind == JsonValueKind.Object || jsonProperty.Value.ValueKind == JsonValueKind.Array)
throw new Exception();
if (!results.ContainsKey(jsonProperty.Name))
results.Add(jsonProperty.Name, new List<string>());
results[jsonProperty.Name].Add(jsonProperty.Value.ToString());
}
}
return results;
}
protected void VerifyProcessDataDescription(ILogic logic)
{
string description;
bool allowNull = false;
JsonElement defaultJsonElement = GetDefaultJsonElement(logic);
Dictionary<string, string> keyValuePairs = GetDisplayNamesJsonElement(logic);
JsonProperty[] jsonProperties = defaultJsonElement.EnumerateObject().ToArray();
foreach (JsonProperty jsonProperty in jsonProperties)
{
if (jsonProperty.Value.ValueKind == JsonValueKind.Null && !allowNull)
throw new Exception();
if (!(jsonProperty.Value.ValueKind is JsonValueKind.String) || !keyValuePairs.ContainsKey(jsonProperty.Name))
description = string.Empty;
else
description = keyValuePairs[jsonProperty.Name].Split('|')[0];
}
}
public List<IProcessDataDescription> GetIProcessDataDescriptions(JsonElement jsonElement)
{
List<IProcessDataDescription> results = new List<IProcessDataDescription>();
if (jsonElement.ValueKind != JsonValueKind.Array)
throw new Exception();
object @object;
Type type = ProcessDataDescription.GetType();
JsonElement[] jsonElements = jsonElement.EnumerateArray().ToArray();
JsonSerializerOptions jsonSerializerOptions = new JsonSerializerOptions { NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString };
for (int i = 0; i < jsonElements.Length; i++)
{
@object = JsonSerializer.Deserialize(jsonElements[i].ToString(), type, jsonSerializerOptions);
if (!(@object is IProcessDataDescription processDataDescription))
continue;
results.Add(processDataDescription);
}
return results;
}
}
}

View File

@ -0,0 +1,13 @@
namespace Shared.Metrology
{
public enum EventName
{
FileRead,
FileReadDaily,
FileReadMonthly,
FileReadVerification,
FileReadWeekly
}
}

View File

@ -0,0 +1,48 @@
using Library.Eaf.EquipmentCore.Control;
using Library.Eaf.Management.ConfigurationData.CellAutomation;
using Library.Ifx.Eaf.EquipmentConnector.File.Configuration;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
namespace Shared.Metrology
{
public interface ILogic
{
ILogic ShallowCopy();
Logistics Logistics { get; }
void ConfigurationRestore();
void CreateSelfDescription();
void CreateSelfDescription(IEquipmentControl equipment, string cellInstanceName, string cellInstanceConnectionName, FileConnectorConfiguration configuration, IList<ModelObjectParameterDefinition> modelObjectParameterDefinitions, EquipmentType? equipmentType, EventName? eventName);
bool Extract(string reportFullPath, string eventName);
string GetConfigurationErrorTargetFileLocation();
string GetConfigurationSourceFileLocation();
string GetConfigurationTarget2FileLocation();
string GetConfigurationTargetFileLocation();
string GetConfigurationTargetFileName();
Tuple<string, JsonElement?, List<FileInfo>> GetExtractResult(string reportFullPath, string eventName);
object GetFilePathGeneratorInfo(string reportFullPath, bool isErrorFile);
string GetReportFullPath(Dictionary<string, object> keyValuePairs);
string GetTarget2FileLocation();
void Move(string reportFullPath, Tuple<string, JsonElement?, List<FileInfo>> extractResults, Exception exception = null);
string ReExtract(string searchDirectory, string sourceFileFilter);
void ReflectionCreateSelfDescription(string equipmentElementName, int? input, string cellName, string debugConfig, string[] strings, bool[] booleans, long[] numbers, string[] enums);
ConfigDataBase ReflectionCreateSelfDescriptionV2(string json);
string ResolveErrorTargetPlaceHolders(string reportFullPath, bool createDirectory = true, string fileFoundPath = "");
string ResolveSourcePlaceHolders(string reportFullPath, bool createDirectory = true);
string ResolveTarget2PlaceHolders(string reportFullPath, bool createDirectory = true, string fileFoundPath = "");
string ResolveTargetPlaceHolders(string reportFullPath, bool createDirectory = true, string fileFoundPath = "");
void SetFileParameter(string key, string value);
void SetFileParameterLotID(string value, bool includeLogisticsSequence = false);
void SetFileParameterLotIDToLogisticsMID(bool includeLogisticsSequence = true);
void SetFileParameterSystemDateTimeToLogisticsSequence();
void SetPlaceHolder(string reportFullPath, string key, string value);
void SetTarget2FileLocation(string value);
}
}

View File

@ -0,0 +1,14 @@
namespace Shared.Metrology
{
public class MET08AFMD3100
{
public enum Test
{
AFMRoughness = Metrology.Test.AFMRoughness
}
}
}

View File

@ -0,0 +1,16 @@
namespace Shared.Metrology
{
public class MET08BVHGPROBE
{
public enum Test
{
BreakdownVoltageCenter = Metrology.Test.BreakdownVoltageCenter,
BreakdownVoltageEdge = Metrology.Test.BreakdownVoltageEdge,
BreakdownVoltageMiddle8in = Metrology.Test.BreakdownVoltageMiddle8in
}
}
}

View File

@ -0,0 +1,16 @@
namespace Shared.Metrology
{
public class MET08CVHGPROBE802B150
{
public enum Test
{
CV = Metrology.Test.CV,
MonthlyCV = Metrology.Test.MonthlyCV,
WeeklyCV = Metrology.Test.WeeklyCV
}
}
}

View File

@ -0,0 +1,18 @@
namespace Shared.Metrology
{
public class MET08DDINCAN8620
{
public enum Test
{
CandelaKlarfDC = Metrology.Test.CandelaKlarfDC,
CandelaLaser = Metrology.Test.CandelaLaser,
CandelaVerify = Metrology.Test.CandelaVerify,
CandelaPSL = Metrology.Test.CandelaPSL,
CandelaProdU = Metrology.Test.CandelaProdU
}
}
}

View File

@ -0,0 +1,14 @@
namespace Shared.Metrology
{
public class MET08DDUPSFS6420
{
public enum Test
{
Tencor = Metrology.Test.Tencor
}
}
}

View File

@ -0,0 +1,14 @@
namespace Shared.Metrology
{
public class MET08DDUPSP1TBI
{
public enum Test
{
SP1 = Metrology.Test.SP1
}
}
}

View File

@ -0,0 +1,14 @@
namespace Shared.Metrology
{
public class MET08EBEAMINTEGRITY26
{
public enum Test
{
Denton = Metrology.Test.Denton
}
}
}

View File

@ -0,0 +1,16 @@
namespace Shared.Metrology
{
public class MET08HALLHL5580
{
public enum Test
{
Hall = Metrology.Test.Hall,
MonthlyHall = Metrology.Test.MonthlyHall,
WeeklyHall = Metrology.Test.WeeklyHall
}
}
}

View File

@ -0,0 +1,14 @@
namespace Shared.Metrology
{
public class MET08MESMICROSCOPE
{
public enum Test
{
Microscope = Metrology.Test.Microscope
}
}
}

View File

@ -0,0 +1,15 @@
namespace Shared.Metrology
{
public class MET08NDFRESIMAP151C
{
public enum Test
{
Lehighton = Metrology.Test.Lehighton,
VerificationLehighton = Metrology.Test.VerificationLehighton
}
}
}

View File

@ -0,0 +1,20 @@
namespace Shared.Metrology
{
public class MET08PLMAPRPM
{
public enum Test
{
RPMXY = Metrology.Test.RPMXY,
RPMAverage = Metrology.Test.RPMAverage,
RPMPLRatio = Metrology.Test.RPMPLRatio,
DailyRPMXY = Metrology.Test.DailyRPMXY,
DailyRPMAverage = Metrology.Test.DailyRPMAverage,
DailyRPMPLRatio = Metrology.Test.DailyRPMPLRatio,
VerificationRPM = Metrology.Test.VerificationRPM
}
}
}

View File

@ -0,0 +1,14 @@
namespace Shared.Metrology
{
public class MET08PRFUSB4000
{
public enum Test
{
Photoreflectance = Metrology.Test.Photoreflectance
}
}
}

View File

@ -0,0 +1,14 @@
namespace Shared.Metrology
{
public class MET08RESIHGCV
{
public enum Test
{
HgCV = Metrology.Test.HgCV
}
}
}

View File

@ -0,0 +1,14 @@
namespace Shared.Metrology
{
public class MET08RESIMAPCDE
{
public enum Test
{
CDE = Metrology.Test.CDE
}
}
}

View File

@ -0,0 +1,14 @@
namespace Shared.Metrology
{
public class MET08THFTIRQS408M
{
public enum Test
{
BioRadQS408M = Metrology.Test.BioRadQS408M
}
}
}

View File

@ -0,0 +1,14 @@
namespace Shared.Metrology
{
public class MET08THFTIRSTRATUS
{
public enum Test
{
BioRadStratus = Metrology.Test.BioRadStratus
}
}
}

View File

@ -0,0 +1,14 @@
namespace Shared.Metrology
{
public class MET08UVH44GS100M
{
public enum Test
{
UV = Metrology.Test.UV
}
}
}

View File

@ -0,0 +1,14 @@
namespace Shared.Metrology
{
public class MET08VPDSUBCON
{
public enum Test
{
VpdIcpmsAnalyte = Metrology.Test.VpdIcpmsAnalyte
}
}
}

View File

@ -0,0 +1,15 @@
namespace Shared.Metrology
{
public class MET08WGEOMX203641Q
{
public enum Test
{
WarpAndBow = Metrology.Test.WarpAndBow,
VerificationWarpAndBow = Metrology.Test.VerificationWarpAndBow
}
}
}

View File

@ -0,0 +1,23 @@
namespace Shared.Metrology
{
public class MET08XRDXPERTPROMRDXL
{
public enum Test
{
XRDXY = Metrology.Test.XRDXY,
XRDWeightedAverage = Metrology.Test.XRDWeightedAverage,
MonthlyXRD = Metrology.Test.MonthlyXRD,
WeeklyXRD = Metrology.Test.WeeklyXRD,
WeeklyXRDAIcomp = Metrology.Test.WeeklyXRDAIcomp,
WeeklyXRDFWHM002 = Metrology.Test.WeeklyXRDFWHM002,
WeeklyXRDFWHM105 = Metrology.Test.WeeklyXRDFWHM105,
WeeklyXRDSLStks = Metrology.Test.WeeklyXRDSLStks,
WeeklyXRDXRR = Metrology.Test.WeeklyXRDXRR,
JVXRD = Metrology.Test.JVXRD
}
}
}

View File

@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
namespace Shared.Metrology
{
public class Duplicator
{
public class Description : IProcessDataDescription
{
public int Test { get; set; }
public int Count { get; set; }
public int Index { get; set; }
//
public string EventName { get; set; }
public string NullData { get; set; }
public string JobID { get; set; }
public string Sequence { get; set; }
public string MesEntity { get; set; }
public string ReportFullPath { get; set; }
public string ProcessJobID { get; set; }
public string MID { get; set; }
public string Date { get; set; } //2021-02-22
public string GetEventDescription() { return "File Has been read and parsed"; }
public List<string> GetHeaderNames(ILogic logic, ConfigDataBase configDataBase)
{
List<string> results = new List<string>();
return results;
}
public List<string> GetDetailNames(ILogic logic, ConfigDataBase configDataBase)
{
List<string> results = new List<string>();
return results;
}
public List<string> GetParameterNames(ILogic logic, ConfigDataBase configDataBase)
{
List<string> results = new List<string>();
return results;
}
public List<string> GetPairedParameterNames(ILogic logic, ConfigDataBase configDataBase)
{
List<string> results = new List<string>();
return results;
}
public List<string> GetIgnoreParameterNames(ILogic logic, ConfigDataBase configDataBase, Test test)
{
List<string> results = new List<string>();
return results;
}
public List<string> GetNames(ILogic logic, ConfigDataBase configDataBase)
{
List<string> results = new List<string>();
IProcessDataDescription processDataDescription = GetDefault(logic, configDataBase);
string json = JsonSerializer.Serialize(processDataDescription, processDataDescription.GetType());
object @object = JsonSerializer.Deserialize<object>(json);
if (!(@object is JsonElement jsonElement))
throw new Exception();
foreach (JsonProperty jsonProperty in jsonElement.EnumerateObject())
results.Add(jsonProperty.Name);
return results;
}
public IProcessDataDescription GetDisplayNames(ILogic logic, ConfigDataBase configDataBase)
{
Description result = new Description();
return result;
}
public IProcessDataDescription GetDefault(ILogic logic, ConfigDataBase configDataBase)
{
Description result = new Description
{
Test = -1,
Count = 0,
Index = -1,
//
EventName = configDataBase.GetEventName(),
NullData = string.Empty,
JobID = logic.Logistics.JobID,
Sequence = logic.Logistics.Sequence.ToString(),
MesEntity = logic.Logistics.MesEntity,
ReportFullPath = logic.Logistics.ReportFullPath,
ProcessJobID = logic.Logistics.ProcessJobID,
MID = logic.Logistics.MID,
Date = logic.Logistics.DateTimeFromSequence.ToUniversalTime().ToString("MM/dd/yyyy HH:mm:ss"),
};
return result;
}
public List<IProcessDataDescription> GetDescription(ILogic logic, ConfigDataBase configDataBase, List<Test> tests, IProcessData iProcessData)
{
List<IProcessDataDescription> results = new List<IProcessDataDescription>();
return results;
}
}
}
}

View File

@ -0,0 +1,527 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
namespace Shared.Metrology
{
public class ProcessDataStandardFormat
{
public const string RecordStart = "RECORD_START";
public enum SearchFor
{
EquipmentIntegration = 1,
BusinessIntegration = 2,
SystemExport = 3,
Archive = 4
}
public static string GetPDSFText(ILogic logic, string eventName, string equipmentType, JsonElement jsonElement, string logisticsText)
{
string result;
if (jsonElement.ValueKind != JsonValueKind.Array)
result = string.Empty;
else
{
int columns = 0;
List<string> lines;
string endOffset = "E#######T";
string dataOffset = "D#######T";
string headerOffset = "H#######T";
string format = "MM/dd/yyyy HH:mm:ss";
StringBuilder stringBuilder = new StringBuilder();
lines = new string[] { "HEADER_TAG\tHEADER_VALUE", "FORMAT\t2.00", "NUMBER_PASSES\t0001", string.Concat("HEADER_OFFSET\t", headerOffset), string.Concat("DATA_OFFSET\t", dataOffset), string.Concat("END_OFFSET\t", endOffset) }.ToList();
stringBuilder.Append("\"Time\"").Append('\t');
stringBuilder.Append("\"A_LOGISTICS\"").Append('\t');
stringBuilder.Append("\"B_LOGISTICS\"").Append('\t');
JsonElement[] jsonElements = jsonElement.EnumerateArray().ToArray();
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;
}
stringBuilder.Remove(stringBuilder.Length - 1, 1);
lines.Add(stringBuilder.ToString());
for (int i = 0; i < jsonElements.Length; i++)
{
stringBuilder.Clear();
stringBuilder.Append("0.1").Append('\t');
stringBuilder.Append("1").Append('\t');
stringBuilder.Append("2").Append('\t');
foreach (JsonProperty jsonProperty in jsonElements[i].EnumerateObject())
stringBuilder.Append(jsonProperty.Value).Append('\t');
stringBuilder.Remove(stringBuilder.Length - 1, 1);
lines.Add(stringBuilder.ToString());
}
lines.Add(string.Concat("NUM_DATA_ROWS ", jsonElements.Length.ToString().PadLeft(9, '0')));
lines.Add(string.Concat("NUM_DATA_COLUMNS ", (columns + 3).ToString().PadLeft(9, '0')));
lines.Add("DELIMITER ;");
lines.Add(string.Concat("START_TIME_FORMAT ", format));
lines.Add(string.Concat("START_TIME ", logic.Logistics.DateTimeFromSequence.ToString(format))); //12/26/2019 15:22:44
lines.Add(string.Concat("LOGISTICS_COLUMN", '\t', "A_LOGISTICS"));
lines.Add(string.Concat("LOGISTICS_COLUMN", '\t', "B_LOGISTICS"));
if (!string.IsNullOrEmpty(logisticsText))
lines.Add(logisticsText);
else
{
lines.Add(string.Concat("LOGISTICS_1", '\t', "A_CHAMBER=;A_INFO=", eventName, ";A_INFO2=", equipmentType, ";A_JOBID=", logic.Logistics.JobID, ";A_MES_ENTITY=", logic.Logistics.MesEntity, ";A_MID=", logic.Logistics.MID, ";A_NULL_DATA=", logic.Logistics.NullData, ";A_PPID=NO_PPID;A_PROCESS_JOBID=", logic.Logistics.ProcessJobID, ";A_PRODUCT=;A_SEQUENCE=", logic.Logistics.Sequence, ";A_WAFER_ID=;"));
lines.Add(string.Concat("LOGISTICS_2", '\t', "B_CHAMBER=;B_INFO=", eventName, ";B_INFO2=", equipmentType, ";B_JOBID=", logic.Logistics.JobID, ";B_MES_ENTITY=", logic.Logistics.MesEntity, ";B_MID=", logic.Logistics.MID, ";B_NULL_DATA=", logic.Logistics.NullData, ";B_PPID=NO_PPID;B_PROCESS_JOBID=", logic.Logistics.ProcessJobID, ";B_PRODUCT=;B_SEQUENCE=", logic.Logistics.Sequence, ";B_WAFER_ID=;"));
lines.Add("END_HEADER");
}
stringBuilder.Clear();
foreach (string line in lines)
stringBuilder.AppendLine(line);
result = stringBuilder.ToString();
result = result.Replace(headerOffset, result.IndexOf("NUM_DATA_ROWS").ToString().PadLeft(9, '0')).
Replace(dataOffset, result.IndexOf('"').ToString().PadLeft(9, '0')).
Replace(endOffset, result.Length.ToString().PadLeft(9, '0'));
}
return result;
}
public static Tuple<string, string[], string[]> GetLogisticsColumnsAndBody(string reportFullPath, string[] lines = null)
{
string segment;
List<string> body = new List<string>();
StringBuilder logistics = new StringBuilder();
if (lines is null)
lines = File.ReadAllLines(reportFullPath);
string[] segments;
if (lines.Length < 7)
segments = new string[] { };
else
segments = lines[6].Trim().Split('\t');
List<string> columns = new List<string>();
for (int c = 0; c < segments.Length; c++)
{
segment = segments[c].Substring(1, segments[c].Length - 2);
if (!columns.Contains(segment))
columns.Add(segment);
else
{
for (short i = 1; i < short.MaxValue; i++)
{
segment = string.Concat(segment, "_", i);
if (!columns.Contains(segment))
{
columns.Add(segment);
break;
}
}
}
}
bool lookForLogistics = false;
for (int r = 7; r < lines.Count(); r++)
{
if (lines[r].StartsWith("NUM_DATA_ROWS"))
lookForLogistics = true;
if (!lookForLogistics)
{
body.Add(lines[r]);
continue;
}
if (lines[r].StartsWith("LOGISTICS_1"))
{
for (int i = r; i < lines.Count(); i++)
{
if (lines[r].StartsWith("END_HEADER"))
break;
logistics.AppendLine(lines[i]);
}
break;
}
}
return new Tuple<string, string[], string[]>(logistics.ToString(), columns.ToArray(), body.ToArray());
}
public static JsonElement GetArray(Tuple<string, string[], string[]> pdsf, bool lookForNumbers = false)
{
JsonElement result;
string logistics = pdsf.Item1;
string[] columns = pdsf.Item2;
string[] bodyLines = pdsf.Item3;
if (!bodyLines.Any() || !bodyLines[0].Contains('\t'))
result = JsonSerializer.Deserialize<JsonElement>("[]");
else
{
string value;
string[] segments;
StringBuilder stringBuilder = new StringBuilder();
foreach (string bodyLine in bodyLines)
{
stringBuilder.Append('{');
segments = bodyLine.Trim().Split('\t');
if (!lookForNumbers)
{
for (int c = 1; c < segments.Length; c++)
{
value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\");
stringBuilder.Append('"').Append(columns[c]).Append("\":\"").Append(value).Append("\",");
}
}
else
{
for (int c = 1; c < segments.Length; c++)
{
value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\");
if (string.IsNullOrEmpty(value))
stringBuilder.Append('"').Append(columns[c]).Append("\":").Append(value).Append("null,");
else if (value.All(char.IsDigit))
stringBuilder.Append('"').Append(columns[c]).Append("\":").Append(value).Append(",");
else
stringBuilder.Append('"').Append(columns[c]).Append("\":\"").Append(value).Append("\",");
}
}
stringBuilder.Remove(stringBuilder.Length - 1, 1);
stringBuilder.AppendLine("},");
}
stringBuilder.Remove(stringBuilder.Length - 3, 3);
result = JsonSerializer.Deserialize<JsonElement>(string.Concat("[", stringBuilder, "]"));
}
return result;
}
public static Dictionary<string, List<string>> GetDictionary(Tuple<string, string[], string[]> pdsf)
{
Dictionary<string, List<string>> results = new Dictionary<string, List<string>>();
string[] segments;
string[] columns = pdsf.Item2;
string[] bodyLines = pdsf.Item3;
foreach (string column in columns)
results.Add(column, new List<string>());
foreach (string bodyLine in bodyLines)
{
segments = bodyLine.Split('\t');
for (int c = 1; c < segments.Length; c++)
{
if (c >= columns.Length)
continue;
results[columns[c]].Add(segments[c]);
}
}
return results;
}
public static Tuple<string, Dictionary<Test, Dictionary<string, List<string>>>> GetTestDictionary(Tuple<string, string[], string[]> pdsf)
{
Dictionary<Test, Dictionary<string, List<string>>> results = new Dictionary<Test, Dictionary<string, List<string>>>();
string testColumn = Description.RowColumn.Test.ToString();
Dictionary<string, List<string>> keyValuePairs = GetDictionary(pdsf);
if (!keyValuePairs.ContainsKey(testColumn))
throw new Exception();
int min;
int max;
Test testKey;
List<string> vs;
string columnKey;
Dictionary<Test, List<int>> tests = new Dictionary<Test, List<int>>();
for (int i = 0; i < keyValuePairs[testColumn].Count; i++)
{
if (Enum.TryParse(keyValuePairs[testColumn][i], out Test test))
{
if (!results.ContainsKey(test))
{
tests.Add(test, new List<int>());
results.Add(test, new Dictionary<string, List<string>>());
}
tests[test].Add(i);
}
}
foreach (KeyValuePair<Test, List<int>> testKeyValuePair in tests)
{
testKey = testKeyValuePair.Key;
min = testKeyValuePair.Value.Min();
max = testKeyValuePair.Value.Max() + 1;
foreach (KeyValuePair<string, List<string>> keyValuePair in keyValuePairs)
results[testKey].Add(keyValuePair.Key, new List<string>());
foreach (KeyValuePair<string, List<string>> keyValuePair in keyValuePairs)
{
vs = keyValuePair.Value;
columnKey = keyValuePair.Key;
for (int i = min; i < max; i++)
{
if (vs.Count > i)
results[testKey][columnKey].Add(vs[i]);
else
results[testKey][columnKey].Add(string.Empty);
}
}
}
return new Tuple<string, Dictionary<Test, Dictionary<string, List<string>>>>(pdsf.Item1, results);
}
private static string GetString(SearchFor searchFor, bool addSpaces, char separator = ' ')
{
if (!addSpaces)
return string.Concat(((int)searchFor).ToString().PadLeft(2, '0'), searchFor);
else
return string.Concat(((int)searchFor).ToString().PadLeft(2, '0'), separator, searchFor.ToString().Replace("In", string.Concat(separator, "In")).Replace("Ex", string.Concat(separator, "Ex")));
}
public static string EquipmentIntegration(bool addSpaces = true, char separator = ' ')
{
return GetString(SearchFor.EquipmentIntegration, addSpaces, separator);
}
public static string BusinessIntegration(bool addSpaces = true, char separator = ' ')
{
return GetString(SearchFor.BusinessIntegration, addSpaces, separator);
}
public static string SystemExport(bool addSpaces = true, char separator = ' ')
{
return GetString(SearchFor.SystemExport, addSpaces, separator);
}
public static string Archive(bool addSpaces = true, char separator = ' ')
{
return GetString(SearchFor.Archive, addSpaces, separator);
}
public static string GetLines(Logistics logistics, IScopeInfo scopeInfo, Dictionary<string, List<string>> keyValuePairs, Enum[] enumColumns, string dateFormat, string timeFormat, Column[] pairedColumns, bool useDateTimeFromSequence = true, string format = "", Dictionary<Column, string> alternateDisplayName = null, Enum[] ignoreColumns = null)
{
StringBuilder result = new StringBuilder();
if (useDateTimeFromSequence && !string.IsNullOrEmpty(format))
throw new Exception();
else if (!useDateTimeFromSequence && string.IsNullOrEmpty(format))
throw new Exception();
int start;
string ckey;
string pKey;
int pairedColumnsCount;
string firstDuplicate = "_1";
if (ignoreColumns is null)
ignoreColumns = new Enum[] { };
if (alternateDisplayName is null)
alternateDisplayName = new Dictionary<Column, string>();
string columnDate = Column.Date.ToString();
string columnTime = Column.Time.ToString();
List<string> columnKeys = new List<string>();
foreach (Enum item in enumColumns)
{
if (ignoreColumns.Contains(item))
continue;
columnKeys.Add(item.ToString());
}
result.AppendLine(scopeInfo.Header);
StringBuilder line = new StringBuilder();
int count = keyValuePairs[Description.RowColumn.Count.ToString()].Count();
string nullData;
if (logistics.NullData is null)
nullData = string.Empty;
else
nullData = logistics.NullData.ToString();
if (pairedColumns is null)
{
start = -1;
pairedColumnsCount = 0;
}
else
{
start = 0;
pairedColumnsCount = pairedColumns.Length;
}
for (int r = 0; r < count; r++)
{
for (int p = start; p < pairedColumnsCount; p++)
{
if (pairedColumnsCount == 0)
pKey = string.Empty;
else if (!(ignoreColumns is null) && ignoreColumns.Contains(pairedColumns[p]))
continue;
else
{
pKey = pairedColumns[p].ToString();
if (!keyValuePairs.ContainsKey(pKey))
continue;
else if (keyValuePairs[pKey][r] == nullData)
continue;
}
if (pairedColumnsCount == 0 || !string.IsNullOrEmpty(pKey))
{
line.Clear();
line.Append("!");
for (int i = 0; i < columnKeys.Count; i++)
{
ckey = columnKeys[i];
if (!keyValuePairs.ContainsKey(ckey))
line.Append(string.Empty);
else
{
if (useDateTimeFromSequence && ckey == columnDate)
line.Append(logistics.DateTimeFromSequence.ToString(dateFormat));
else if (useDateTimeFromSequence && ckey == columnTime)
line.Append(logistics.DateTimeFromSequence.ToString(timeFormat));
else if (!useDateTimeFromSequence && ckey == columnDate && keyValuePairs[ckey][r].Length == format.Length)
line.Append(DateTime.ParseExact(keyValuePairs[ckey][r], format, CultureInfo.InvariantCulture).ToString(dateFormat));
else if (!useDateTimeFromSequence && ckey == columnTime && keyValuePairs.ContainsKey(string.Concat(ckey, firstDuplicate)) && keyValuePairs[string.Concat(ckey, firstDuplicate)][r].Length == format.Length)
line.Append(DateTime.ParseExact(keyValuePairs[string.Concat(ckey, firstDuplicate)][r], format, CultureInfo.InvariantCulture).ToString(timeFormat));
else
line.Append(keyValuePairs[ckey][r]);
}
line.Append(';');
}
if (pairedColumnsCount > 0)
{
if (!alternateDisplayName.ContainsKey(pairedColumns[p]))
line.Append(pairedColumns[p].GetDiplayName());
else
line.Append(alternateDisplayName[pairedColumns[p]]);
line.Append(';');
line.Append(keyValuePairs[pKey][r]);
line.Append(';');
}
line.Remove(line.Length - 1, 1);
result.AppendLine(line.ToString());
}
}
}
return result.ToString();
}
public static string GetLines(Logistics logistics, IScopeInfo scopeInfo, List<string> names, Dictionary<string, List<string>> keyValuePairs, string dateFormat, string timeFormat, List<string> pairedParameterNames, bool useDateTimeFromSequence = true, string format = "", List<string> ignoreParameterNames = null)
{
StringBuilder result = new StringBuilder();
if (ignoreParameterNames is null)
ignoreParameterNames = new List<string>();
if (useDateTimeFromSequence && !string.IsNullOrEmpty(format))
throw new Exception();
else if (!useDateTimeFromSequence && string.IsNullOrEmpty(format))
throw new Exception();
string nullData;
const string columnDate = "Date";
const string columnTime = "Time";
const string firstDuplicate = "_1";
result.AppendLine(scopeInfo.Header);
StringBuilder line = new StringBuilder();
if (logistics.NullData is null)
nullData = string.Empty;
else
nullData = logistics.NullData.ToString();
int count = (from l in keyValuePairs select l.Value.Count).Min();
for (int r = 0; r < count; r++)
{
line.Clear();
line.Append("!");
foreach (KeyValuePair<string, List<string>> keyValuePair in keyValuePairs)
{
if (!names.Contains(keyValuePair.Key))
continue;
if (ignoreParameterNames.Contains(keyValuePair.Key))
continue;
if (pairedParameterNames.Contains(keyValuePair.Key))
{
if (string.IsNullOrEmpty(keyValuePair.Value[r]) || keyValuePair.Value[r] == nullData)
continue;
else
result.Append(line).Append(keyValuePair.Key).Append(';').AppendLine(keyValuePair.Value[r]);
}
else
{
if (useDateTimeFromSequence && keyValuePair.Key == columnDate)
line.Append(logistics.DateTimeFromSequence.ToString(dateFormat));
else if (useDateTimeFromSequence && keyValuePair.Key == columnTime)
line.Append(logistics.DateTimeFromSequence.ToString(timeFormat));
else if (!useDateTimeFromSequence && keyValuePair.Key == columnDate && keyValuePair.Value[r].Length == format.Length)
line.Append(DateTime.ParseExact(keyValuePair.Value[r], format, CultureInfo.InvariantCulture).ToString(dateFormat));
else if (!useDateTimeFromSequence && keyValuePair.Key == columnTime && keyValuePairs.ContainsKey(string.Concat(keyValuePair.Key, firstDuplicate)) && keyValuePairs[string.Concat(keyValuePair.Key, firstDuplicate)][r].Length == format.Length)
line.Append(DateTime.ParseExact(keyValuePairs[string.Concat(keyValuePair.Key, firstDuplicate)][r], format, CultureInfo.InvariantCulture).ToString(timeFormat));
else if (string.IsNullOrEmpty(keyValuePair.Value[r]) || keyValuePair.Value[r] == nullData)
line.Append(nullData);
else
line.Append(keyValuePair.Value[r]);
line.Append(';');
}
}
if (!pairedParameterNames.Any())
{
line.Remove(line.Length - 1, 1);
result.AppendLine(line.ToString());
}
}
return result.ToString();
}
public static List<string> PDSFToFixedWidth(string reportFullPath)
{
List<string> results = new List<string>();
if (!File.Exists(reportFullPath))
throw new Exception();
int[] group;
string line;
int startsAt = 0;
string[] segments;
int? currentGroup = null;
char inputSeperator = '\t';
char outputSeperator = '\t';
List<int> vs = new List<int>();
List<int[]> groups = new List<int[]>();
string[] lines = File.ReadAllLines(reportFullPath);
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < lines.Length; i++)
{
if (string.IsNullOrEmpty(lines[i]))
continue;
segments = lines[i].Split(inputSeperator);
if (currentGroup is null)
currentGroup = segments.Length;
if (segments.Length != currentGroup)
{
currentGroup = segments.Length;
groups.Add(new int[] { startsAt, i - 1 });
startsAt = i;
}
}
if (startsAt == lines.Length - 1 && lines[0].Split(inputSeperator).Length != currentGroup)
groups.Add(new int[] { lines.Length - 1, lines.Length - 1 });
for (int g = 0; g < groups.Count; g++)
{
vs.Clear();
group = groups[g];
line = lines[group[0]];
segments = line.Split(inputSeperator);
for (int s = 0; s < segments.Length; s++)
vs.Add(segments[s].Length);
for (int i = group[0]; i <= group[1]; i++)
{
line = lines[i];
segments = line.Split(inputSeperator);
for (int s = 0; s < segments.Length; s++)
{
if (vs[s] < segments[s].Length)
vs[s] = segments[s].Length;
}
}
stringBuilder.Clear();
for (int s = 0; s < segments.Length; s++)
stringBuilder.Append((s + 1).ToString().PadLeft(vs[s], ' ')).Append(outputSeperator);
stringBuilder.Remove(stringBuilder.Length - 1, 1);
results.Add(stringBuilder.ToString());
for (int i = group[0]; i <= group[1]; i++)
{
line = lines[i];
stringBuilder.Clear();
segments = line.Split(inputSeperator);
for (int s = 0; s < segments.Length; s++)
stringBuilder.Append(segments[s].PadLeft(vs[s], ' ')).Append(outputSeperator);
stringBuilder.Remove(stringBuilder.Length - 1, 1);
results.Add(stringBuilder.ToString());
}
results.Add(string.Empty);
}
return results;
}
}
}

View File

@ -0,0 +1,57 @@
namespace Shared.Metrology
{
public enum Test
{
AFMRoughness = 34,
BioRadQS408M = 25,
BioRadStratus = 26,
BreakdownVoltageCenter = 0,
BreakdownVoltageEdge = 1,
BreakdownVoltageMiddle8in = 2,
CandelaKlarfDC = 6,
CandelaLaser = 36,
CandelaProdU = 39,
CandelaPSL = 38,
CandelaVerify = 37,
CDE = 24,
CV = 3,
DailyRPMAverage = 19,
DailyRPMPLRatio = 20,
DailyRPMXY = 18,
Denton = 9,
DiffusionLength = 45,
Hall = 10,
HgCV = 23,
Lehighton = 13,
Microscope = 46,
MonthlyCV = 4,
MonthlyHall = 11,
MonthlyXRD = 32,
Photoreflectance = 22,
PlatoA = 48, //Largest
RPMAverage = 16,
RPMPLRatio = 17,
RPMXY = 15,
SP1 = 8,
Tencor = 7,
UV = 35,
VerificationLehighton = 14,
VerificationRPM = 21,
VerificationWarpAndBow = 29,
VpdIcpmsAnalyte = 27,
WarpAndBow = 28,
WeeklyCV = 5,
WeeklyHall = 12,
WeeklyXRD = 33,
WeeklyXRDAIcomp = 40,
WeeklyXRDFWHM002 = 41,
WeeklyXRDFWHM105 = 42,
WeeklyXRDSLStks = 43,
WeeklyXRDXRR = 44,
XRDWeightedAverage = 31,
JVXRD = 47,
XRDXY = 30
}
}