Match TFS Changeset 303361
This commit is contained in:
1605
APC Viewer/Shared/Metrology/Column.cs
Normal file
1605
APC Viewer/Shared/Metrology/Column.cs
Normal file
File diff suppressed because it is too large
Load Diff
410
APC Viewer/Shared/Metrology/ConfigDataBase.cs
Normal file
410
APC Viewer/Shared/Metrology/ConfigDataBase.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
13
APC Viewer/Shared/Metrology/EventName.cs
Normal file
13
APC Viewer/Shared/Metrology/EventName.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public enum EventName
|
||||
{
|
||||
FileRead,
|
||||
FileReadDaily,
|
||||
FileReadMonthly,
|
||||
FileReadVerification,
|
||||
FileReadWeekly
|
||||
}
|
||||
|
||||
}
|
48
APC Viewer/Shared/Metrology/ILogic.cs
Normal file
48
APC Viewer/Shared/Metrology/ILogic.cs
Normal 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);
|
||||
|
||||
}
|
||||
|
||||
}
|
14
APC Viewer/Shared/Metrology/MET08AFMD3100.cs
Normal file
14
APC Viewer/Shared/Metrology/MET08AFMD3100.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08AFMD3100
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
AFMRoughness = Metrology.Test.AFMRoughness
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
16
APC Viewer/Shared/Metrology/MET08BVHGPROBE.cs
Normal file
16
APC Viewer/Shared/Metrology/MET08BVHGPROBE.cs
Normal 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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
16
APC Viewer/Shared/Metrology/MET08CVHGPROBE802B150.cs
Normal file
16
APC Viewer/Shared/Metrology/MET08CVHGPROBE802B150.cs
Normal 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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
18
APC Viewer/Shared/Metrology/MET08DDINCAN8620.cs
Normal file
18
APC Viewer/Shared/Metrology/MET08DDINCAN8620.cs
Normal 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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
APC Viewer/Shared/Metrology/MET08DDUPSFS6420.cs
Normal file
14
APC Viewer/Shared/Metrology/MET08DDUPSFS6420.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08DDUPSFS6420
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
Tencor = Metrology.Test.Tencor
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
APC Viewer/Shared/Metrology/MET08DDUPSP1TBI.cs
Normal file
14
APC Viewer/Shared/Metrology/MET08DDUPSP1TBI.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08DDUPSP1TBI
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
SP1 = Metrology.Test.SP1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
APC Viewer/Shared/Metrology/MET08EBEAMINTEGRITY26.cs
Normal file
14
APC Viewer/Shared/Metrology/MET08EBEAMINTEGRITY26.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08EBEAMINTEGRITY26
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
Denton = Metrology.Test.Denton
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
16
APC Viewer/Shared/Metrology/MET08HALLHL5580.cs
Normal file
16
APC Viewer/Shared/Metrology/MET08HALLHL5580.cs
Normal 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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
APC Viewer/Shared/Metrology/MET08MESMICROSCOPE.cs
Normal file
14
APC Viewer/Shared/Metrology/MET08MESMICROSCOPE.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08MESMICROSCOPE
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
Microscope = Metrology.Test.Microscope
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
15
APC Viewer/Shared/Metrology/MET08NDFRESIMAP151C.cs
Normal file
15
APC Viewer/Shared/Metrology/MET08NDFRESIMAP151C.cs
Normal file
@ -0,0 +1,15 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08NDFRESIMAP151C
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
Lehighton = Metrology.Test.Lehighton,
|
||||
VerificationLehighton = Metrology.Test.VerificationLehighton
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
20
APC Viewer/Shared/Metrology/MET08PLMAPRPM.cs
Normal file
20
APC Viewer/Shared/Metrology/MET08PLMAPRPM.cs
Normal 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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
APC Viewer/Shared/Metrology/MET08PRFUSB4000.cs
Normal file
14
APC Viewer/Shared/Metrology/MET08PRFUSB4000.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08PRFUSB4000
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
Photoreflectance = Metrology.Test.Photoreflectance
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
APC Viewer/Shared/Metrology/MET08RESIHGCV.cs
Normal file
14
APC Viewer/Shared/Metrology/MET08RESIHGCV.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08RESIHGCV
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
HgCV = Metrology.Test.HgCV
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
APC Viewer/Shared/Metrology/MET08RESIMAPCDE.cs
Normal file
14
APC Viewer/Shared/Metrology/MET08RESIMAPCDE.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08RESIMAPCDE
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
CDE = Metrology.Test.CDE
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
APC Viewer/Shared/Metrology/MET08THFTIRQS408M.cs
Normal file
14
APC Viewer/Shared/Metrology/MET08THFTIRQS408M.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08THFTIRQS408M
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
BioRadQS408M = Metrology.Test.BioRadQS408M
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
APC Viewer/Shared/Metrology/MET08THFTIRSTRATUS.cs
Normal file
14
APC Viewer/Shared/Metrology/MET08THFTIRSTRATUS.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08THFTIRSTRATUS
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
BioRadStratus = Metrology.Test.BioRadStratus
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
APC Viewer/Shared/Metrology/MET08UVH44GS100M.cs
Normal file
14
APC Viewer/Shared/Metrology/MET08UVH44GS100M.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08UVH44GS100M
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
UV = Metrology.Test.UV
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
APC Viewer/Shared/Metrology/MET08VPDSUBCON.cs
Normal file
14
APC Viewer/Shared/Metrology/MET08VPDSUBCON.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08VPDSUBCON
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
VpdIcpmsAnalyte = Metrology.Test.VpdIcpmsAnalyte
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
15
APC Viewer/Shared/Metrology/MET08WGEOMX203641Q.cs
Normal file
15
APC Viewer/Shared/Metrology/MET08WGEOMX203641Q.cs
Normal file
@ -0,0 +1,15 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08WGEOMX203641Q
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
WarpAndBow = Metrology.Test.WarpAndBow,
|
||||
VerificationWarpAndBow = Metrology.Test.VerificationWarpAndBow
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
23
APC Viewer/Shared/Metrology/MET08XRDXPERTPROMRDXL.cs
Normal file
23
APC Viewer/Shared/Metrology/MET08XRDXPERTPROMRDXL.cs
Normal 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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
110
APC Viewer/Shared/Metrology/ProcessData.Duplicator.cs
Normal file
110
APC Viewer/Shared/Metrology/ProcessData.Duplicator.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
527
APC Viewer/Shared/Metrology/ProcessDataStandardFormat.cs
Normal file
527
APC Viewer/Shared/Metrology/ProcessDataStandardFormat.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
57
APC Viewer/Shared/Metrology/Test.cs
Normal file
57
APC Viewer/Shared/Metrology/Test.cs
Normal 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
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user