Match TFS Changeset 303335
This commit is contained in:
1
Adaptation/Shared/CellInstance.cs
Normal file
1
Adaptation/Shared/CellInstance.cs
Normal file
@ -0,0 +1 @@
|
||||
|
20
Adaptation/Shared/Deposition/DEP08EGANAIXG5H.cs
Normal file
20
Adaptation/Shared/Deposition/DEP08EGANAIXG5H.cs
Normal file
@ -0,0 +1,20 @@
|
||||
namespace Adaptation.Shared.Deposition
|
||||
{
|
||||
|
||||
public class DEP08EGANAIXG5
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
GRATXTCenter = Deposition.Test.GRATXTCenter,
|
||||
GRATXTEdge = Deposition.Test.GRATXTEdge,
|
||||
GRAXMLCenter = Deposition.Test.GRAXMLCenter,
|
||||
GRAXMLEdgeN = Deposition.Test.GRAXMLEdgeN,
|
||||
Health = Deposition.Test.Health,
|
||||
Temps = Deposition.Test.Temps,
|
||||
ToolTime = Deposition.Test.ToolTime
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
16
Adaptation/Shared/Deposition/Test.cs
Normal file
16
Adaptation/Shared/Deposition/Test.cs
Normal file
@ -0,0 +1,16 @@
|
||||
namespace Adaptation.Shared.Deposition
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
AFMRoughness = -1,
|
||||
GRATXTCenter = 0,
|
||||
GRATXTEdge = 1,
|
||||
GRAXMLCenter = 2,
|
||||
GRAXMLEdgeN = 3,
|
||||
Health = 4,
|
||||
Temps = 5,
|
||||
ToolTime = 6
|
||||
}
|
||||
|
||||
}
|
192
Adaptation/Shared/Description.cs
Normal file
192
Adaptation/Shared/Description.cs
Normal file
@ -0,0 +1,192 @@
|
||||
using Adaptation.Eaf.Core;
|
||||
using Adaptation.Eaf.EquipmentCore.Control;
|
||||
using Adaptation.Eaf.EquipmentCore.DataCollection.Reporting;
|
||||
using Adaptation.Eaf.EquipmentCore.SelfDescription.ElementDescription;
|
||||
using Adaptation.Eaf.EquipmentCore.SelfDescription.ParameterTypes;
|
||||
using Adaptation.Ifx.Eaf.EquipmentConnector.File.SelfDescription;
|
||||
using Adaptation.Shared.Metrology;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Adaptation.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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
53
Adaptation/Shared/EquipmentType.cs
Normal file
53
Adaptation/Shared/EquipmentType.cs
Normal file
@ -0,0 +1,53 @@
|
||||
namespace Adaptation.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
|
||||
}
|
||||
|
||||
}
|
178
Adaptation/Shared/ExtendedParameter.cs
Normal file
178
Adaptation/Shared/ExtendedParameter.cs
Normal file
@ -0,0 +1,178 @@
|
||||
using Adaptation.Shared.Metrology;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Adaptation.Shared
|
||||
{
|
||||
|
||||
public class ExtendedParameter
|
||||
{
|
||||
|
||||
public string DiplayName { get; set; }
|
||||
public string ControlPlanName { get; set; }
|
||||
public bool? CriticalToShip { get; set; }
|
||||
public string Unit { get; set; }
|
||||
public double? LSL { get; set; }
|
||||
public double? TSL { get; set; }
|
||||
public double? USL { get; set; }
|
||||
public string Value { get; set; }
|
||||
public bool? Ignore { get; set; }
|
||||
|
||||
//public class ExtractorKeys
|
||||
public string Lot { get; set; } //1
|
||||
public string ToolID { get; set; } //2
|
||||
public string Process { get; set; } //3
|
||||
public string WaferID { get; set; } //4
|
||||
public string Part { get; set; } //5
|
||||
public string Recipe { get; set; } //6
|
||||
public string ProcessFlow { get; set; } //7
|
||||
|
||||
//public class DataKeys
|
||||
public string Employee { get; set; } //1
|
||||
public string SID { get; set; } //2
|
||||
public string WaferRegion { get; set; } //3
|
||||
public string WaferScribe { get; set; } //4
|
||||
public string WaferPosition { get; set; } //5
|
||||
public string X { get; set; } //6
|
||||
public string Y { get; set; } //7
|
||||
public string EAFCellInstance { get; set; } //8
|
||||
public string EAFReference { get; set; } //9
|
||||
public string IQSReference { get; set; } //10
|
||||
|
||||
public ExtendedParameter(Logistics logistics, string diplayName, string controlPlanName)
|
||||
{
|
||||
DiplayName = diplayName;
|
||||
ControlPlanName = controlPlanName;
|
||||
CriticalToShip = null;
|
||||
Unit = string.Empty;
|
||||
LSL = null;
|
||||
TSL = null;
|
||||
USL = null;
|
||||
Ignore = null;
|
||||
Value = string.Empty;
|
||||
//public class ExtractorKeys
|
||||
Lot = string.Empty; //1
|
||||
ToolID = string.Empty; //2
|
||||
Process = string.Empty; //3
|
||||
WaferID = string.Empty; //4
|
||||
Part = string.Empty; //5
|
||||
Recipe = string.Empty; //6
|
||||
ProcessFlow = string.Empty; //7
|
||||
//public class DataKeys
|
||||
Employee = string.Empty; //1
|
||||
SID = string.Empty; //2
|
||||
WaferRegion = string.Empty; //3
|
||||
WaferScribe = string.Empty; //4
|
||||
WaferPosition = string.Empty; //5
|
||||
X = string.Empty; //6
|
||||
Y = string.Empty; //7
|
||||
EAFCellInstance = string.Empty; //8
|
||||
EAFReference = string.Empty; //9
|
||||
IQSReference = string.Empty; //10
|
||||
//
|
||||
Lot = "-";
|
||||
SID = "-";
|
||||
Part = "-";
|
||||
if (!(logistics is null))
|
||||
{
|
||||
ToolID = logistics.MesEntity;
|
||||
EAFCellInstance = logistics.JobID;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Value;
|
||||
}
|
||||
|
||||
internal void Set(EquipmentType equipmentType, string queryFilter, Dictionary<Enum, string> allColumnCollection)
|
||||
{
|
||||
Column key;
|
||||
EAFReference = equipmentType.ToString();
|
||||
if (string.IsNullOrEmpty(queryFilter))
|
||||
IQSReference = null;
|
||||
else
|
||||
IQSReference = queryFilter;
|
||||
//
|
||||
key = Column.SID;
|
||||
if (!allColumnCollection.ContainsKey(key))
|
||||
SID = "-";
|
||||
else
|
||||
SID = allColumnCollection[key];
|
||||
key = Column.Employee;
|
||||
if (!allColumnCollection.ContainsKey(key))
|
||||
Employee = "AUTO";
|
||||
else
|
||||
Employee = allColumnCollection[key];
|
||||
//
|
||||
key = Column.Lot;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
Lot = allColumnCollection[key];
|
||||
//
|
||||
key = Column.Part;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
Part = allColumnCollection[key];
|
||||
//
|
||||
key = Column.Process;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
Process = allColumnCollection[key];
|
||||
//
|
||||
key = Column.Recipe;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
Recipe = allColumnCollection[key];
|
||||
//
|
||||
key = Column.Wafer_ID;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
WaferID = allColumnCollection[key];
|
||||
key = Column.Denton_Gun_Pocket;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
WaferID = allColumnCollection[key];
|
||||
key = Column.WaferPocket_Candela;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
WaferID = allColumnCollection[key];
|
||||
key = Column.WaferPocket_Warp;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
WaferID = allColumnCollection[key];
|
||||
//
|
||||
key = Column.Wafer_ID;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
WaferID = allColumnCollection[key];
|
||||
key = Column.Denton_Gun_Pocket;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
WaferID = allColumnCollection[key];
|
||||
key = Column.WaferPocket_Candela;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
WaferID = allColumnCollection[key];
|
||||
key = Column.WaferPocket_Warp;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
WaferID = allColumnCollection[key];
|
||||
//
|
||||
key = Column.Wafer_Region;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
WaferRegion = allColumnCollection[key];
|
||||
key = Column.Wafer_Scribe;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
WaferScribe = allColumnCollection[key];
|
||||
key = Column.WaferPosition_BV;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
WaferPosition = allColumnCollection[key];
|
||||
key = Column.WaferPosition_CV;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
WaferPosition = allColumnCollection[key];
|
||||
key = Column.WaferPosition_Hall;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
WaferPosition = allColumnCollection[key];
|
||||
key = Column.WaferPosition_PR;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
WaferPosition = allColumnCollection[key];
|
||||
key = Column.X_Coord;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
X = allColumnCollection[key];
|
||||
key = Column.Y_Coord;
|
||||
if (allColumnCollection.ContainsKey(key))
|
||||
Y = allColumnCollection[key];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
652
Adaptation/Shared/ExtractResult.cs
Normal file
652
Adaptation/Shared/ExtractResult.cs
Normal file
@ -0,0 +1,652 @@
|
||||
using Adaptation.Shared.Metrology;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Adaptation.Shared
|
||||
{
|
||||
|
||||
public class ExtractResult
|
||||
{
|
||||
|
||||
public object ProcessData { get; internal set; }
|
||||
public long LastTicksDuration { get; private set; }
|
||||
public long BreakAfterSeconds { get; private set; }
|
||||
public Enum[] EnumColumns { get; protected set; }
|
||||
public List<string> SourceFiles { get; private set; }
|
||||
public Column[] PairedColumns { get; protected set; }
|
||||
public Dictionary<Enum, List<string>> Headers { get; protected set; }
|
||||
public Dictionary<Enum, List<string>> Details { get; protected set; }
|
||||
public Dictionary<Enum, List<string>> Parameters { get; protected set; }
|
||||
public Dictionary<Enum, List<ExtendedParameter>> ExtendedParameters { get; protected set; }
|
||||
public Dictionary<Enum, List<string>> DatabaseHeaders { get; protected set; }
|
||||
public Dictionary<Enum, List<string>> DatabaseDetails { get; protected set; }
|
||||
public Dictionary<Description.RowColumn, List<int>> RowColumns { get; protected set; }
|
||||
public Dictionary<Test, Dictionary<Enum, List<int>>> IgnoreIndeices { get; protected set; }
|
||||
public Dictionary<Description.LogisticsColumn, List<string>> LogisticsColumns { get; protected set; }
|
||||
|
||||
public ExtractResult(ExtractResult extractResult, long breakAfterSeconds, Enum[] enumColumns, Column[] pairedColumns)
|
||||
{
|
||||
if (enumColumns is null)
|
||||
enumColumns = new Enum[] { };
|
||||
if (pairedColumns is null)
|
||||
pairedColumns = new Column[] { };
|
||||
ProcessData = null;
|
||||
EnumColumns = enumColumns;
|
||||
PairedColumns = pairedColumns;
|
||||
SourceFiles = new List<string>();
|
||||
if (!(extractResult is null) && !(extractResult.SourceFiles is null))
|
||||
SourceFiles.AddRange(extractResult.SourceFiles);
|
||||
BreakAfterSeconds = breakAfterSeconds;
|
||||
List<Enum> headers = new List<Enum>();
|
||||
List<Enum> details = new List<Enum>();
|
||||
List<Enum> parameters = new List<Enum>();
|
||||
List<Enum> databaseHeaders = new List<Enum>();
|
||||
List<Enum> databaseDetails = new List<Enum>();
|
||||
UpdateLastTicksDuration(breakAfterSeconds * 10000000);
|
||||
Common(headers, details, parameters, databaseHeaders, databaseDetails);
|
||||
}
|
||||
|
||||
private void Common(List<Enum> headers, List<Enum> details, List<Enum> parameters, List<Enum> databaseHeaders, List<Enum> databaseDetails)
|
||||
{
|
||||
Headers = new Dictionary<Enum, List<string>>();
|
||||
Details = new Dictionary<Enum, List<string>>();
|
||||
Parameters = new Dictionary<Enum, List<string>>();
|
||||
ExtendedParameters = new Dictionary<Enum, List<ExtendedParameter>>();
|
||||
DatabaseHeaders = new Dictionary<Enum, List<string>>();
|
||||
DatabaseDetails = new Dictionary<Enum, List<string>>();
|
||||
IgnoreIndeices = new Dictionary<Test, Dictionary<Enum, List<int>>>();
|
||||
LogisticsColumns = new Dictionary<Description.LogisticsColumn, List<string>>();
|
||||
foreach (var item in headers)
|
||||
Headers.Add(item, new List<string>());
|
||||
foreach (var item in details)
|
||||
Details.Add(item, new List<string>());
|
||||
foreach (var item in parameters)
|
||||
Parameters.Add(item, new List<string>());
|
||||
foreach (var item in parameters)
|
||||
ExtendedParameters.Add(item, new List<ExtendedParameter>());
|
||||
foreach (var item in databaseHeaders)
|
||||
DatabaseHeaders.Add(item, new List<string>());
|
||||
foreach (var item in databaseDetails)
|
||||
DatabaseDetails.Add(item, new List<string>());
|
||||
Array array;
|
||||
array = Enum.GetValues(typeof(Description.RowColumn));
|
||||
RowColumns = new Dictionary<Description.RowColumn, List<int>>();
|
||||
foreach (Description.RowColumn item in array)
|
||||
RowColumns.Add(item, new List<int>());
|
||||
array = Enum.GetValues(typeof(Description.LogisticsColumn));
|
||||
foreach (Description.LogisticsColumn item in array)
|
||||
LogisticsColumns.Add(item, new List<string>());
|
||||
}
|
||||
|
||||
internal void Reset()
|
||||
{
|
||||
ProcessData = null;
|
||||
SourceFiles.Clear();
|
||||
List<Enum> headers = new List<Enum>();
|
||||
List<Enum> details = new List<Enum>();
|
||||
List<Enum> parameters = new List<Enum>();
|
||||
List<Enum> databaseHeaders = new List<Enum>();
|
||||
List<Enum> databaseDetails = new List<Enum>();
|
||||
foreach (var item in Headers)
|
||||
headers.Add(item.Key);
|
||||
foreach (var item in Details)
|
||||
details.Add(item.Key);
|
||||
foreach (var item in Parameters)
|
||||
parameters.Add(item.Key);
|
||||
foreach (var item in DatabaseHeaders)
|
||||
databaseHeaders.Add(item.Key);
|
||||
foreach (var item in DatabaseDetails)
|
||||
databaseDetails.Add(item.Key);
|
||||
Common(headers, details, parameters, databaseHeaders, databaseDetails);
|
||||
}
|
||||
|
||||
public ExtractResult ShallowCopy()
|
||||
{
|
||||
return (ExtractResult)MemberwiseClone();
|
||||
}
|
||||
|
||||
internal void HeadersAddRange(Enum column)
|
||||
{
|
||||
Headers.Add(column, new List<string>());
|
||||
}
|
||||
|
||||
internal void HeadersAddRange(params Enum[] columns)
|
||||
{
|
||||
foreach (var item in columns)
|
||||
Headers.Add(item, new List<string>());
|
||||
}
|
||||
|
||||
internal void HeadersAddRange(List<Enum> columns)
|
||||
{
|
||||
foreach (var item in columns)
|
||||
Headers.Add(item, new List<string>());
|
||||
}
|
||||
|
||||
internal void DetailsAddRange(Enum column)
|
||||
{
|
||||
Details.Add(column, new List<string>());
|
||||
}
|
||||
|
||||
internal void DetailsAddRange(params Enum[] columns)
|
||||
{
|
||||
foreach (var item in columns)
|
||||
Details.Add(item, new List<string>());
|
||||
}
|
||||
|
||||
internal void DetailsAddRange(List<Enum> columns)
|
||||
{
|
||||
foreach (var item in columns)
|
||||
Details.Add(item, new List<string>());
|
||||
}
|
||||
|
||||
internal void ParametersAddRange(Enum column)
|
||||
{
|
||||
Parameters.Add(column, new List<string>());
|
||||
}
|
||||
|
||||
internal void ParametersAddRange(params Enum[] columns)
|
||||
{
|
||||
foreach (var item in columns)
|
||||
Parameters.Add(item, new List<string>());
|
||||
}
|
||||
|
||||
internal void ParametersAddRange(List<Enum> columns)
|
||||
{
|
||||
foreach (var item in columns)
|
||||
Parameters.Add(item, new List<string>());
|
||||
}
|
||||
|
||||
internal void DatabaseHeadersAddRange(Enum column)
|
||||
{
|
||||
DatabaseHeaders.Add(column, new List<string>());
|
||||
}
|
||||
|
||||
internal void DatabaseHeadersAddRange(params Enum[] columns)
|
||||
{
|
||||
foreach (var item in columns)
|
||||
DatabaseHeaders.Add(item, new List<string>());
|
||||
}
|
||||
|
||||
internal void DatabaseHeadersAddRange(List<Enum> columns)
|
||||
{
|
||||
foreach (var item in columns)
|
||||
DatabaseHeaders.Add(item, new List<string>());
|
||||
}
|
||||
|
||||
internal void DatabaseDetailsAddRange(Enum column)
|
||||
{
|
||||
DatabaseDetails.Add(column, new List<string>());
|
||||
}
|
||||
|
||||
internal void DatabaseDetailsAddRange(params Enum[] columns)
|
||||
{
|
||||
foreach (var item in columns)
|
||||
DatabaseDetails.Add(item, new List<string>());
|
||||
}
|
||||
|
||||
internal void DatabaseDetailsAddRange(List<Enum> columns)
|
||||
{
|
||||
foreach (var item in columns)
|
||||
DatabaseDetails.Add(item, new List<string>());
|
||||
}
|
||||
|
||||
internal int GetCount()
|
||||
{
|
||||
int result = 0;
|
||||
List<int> counts = new List<int>
|
||||
{
|
||||
RowColumns[Description.RowColumn.Test].Count()
|
||||
};
|
||||
foreach (var item in Headers)
|
||||
counts.Add(item.Value.Count());
|
||||
foreach (var item in Details)
|
||||
counts.Add(item.Value.Count());
|
||||
foreach (var item in Parameters)
|
||||
counts.Add(item.Value.Count());
|
||||
foreach (var item in DatabaseHeaders)
|
||||
counts.Add(item.Value.Count());
|
||||
foreach (var item in DatabaseDetails)
|
||||
counts.Add(item.Value.Count());
|
||||
result = counts.Max();
|
||||
if (counts.Distinct().Count() != 1)
|
||||
throw new Exception();
|
||||
return result;
|
||||
}
|
||||
|
||||
private Dictionary<Enum, List<string>> Merge(List<KeyValuePair<Enum, List<string>>> keyValuePairs)
|
||||
{
|
||||
Dictionary<Enum, List<string>> results = new Dictionary<Enum, List<string>>();
|
||||
foreach (var element in keyValuePairs)
|
||||
results.Add(element.Key, element.Value);
|
||||
return results;
|
||||
}
|
||||
|
||||
private List<KeyValuePair<Enum, List<string>>> GetAllColumnKeyValuePairs()
|
||||
{
|
||||
List<KeyValuePair<Enum, List<string>>> results = new List<KeyValuePair<Enum, List<string>>>();
|
||||
foreach (var item in Headers)
|
||||
results.Add(new KeyValuePair<Enum, List<string>>(item.Key, item.Value));
|
||||
foreach (var item in Details)
|
||||
results.Add(new KeyValuePair<Enum, List<string>>(item.Key, item.Value));
|
||||
foreach (var item in Parameters)
|
||||
results.Add(new KeyValuePair<Enum, List<string>>(item.Key, item.Value));
|
||||
foreach (var item in DatabaseHeaders)
|
||||
results.Add(new KeyValuePair<Enum, List<string>>(item.Key, item.Value));
|
||||
foreach (var item in DatabaseDetails)
|
||||
results.Add(new KeyValuePair<Enum, List<string>>(item.Key, item.Value));
|
||||
return results;
|
||||
}
|
||||
|
||||
internal Dictionary<Enum, List<string>> GetAllColumnCollection()
|
||||
{
|
||||
Dictionary<Enum, List<string>> results;
|
||||
if (!EnumColumns.Any())
|
||||
{
|
||||
List<KeyValuePair<Enum, List<string>>> keyValuePairs = GetAllColumnKeyValuePairs();
|
||||
results = Merge(keyValuePairs);
|
||||
}
|
||||
else
|
||||
{
|
||||
results = new Dictionary<Enum, List<string>>();
|
||||
foreach (var item in EnumColumns)
|
||||
results.Add(item, new List<string>());
|
||||
foreach (var item in PairedColumns)
|
||||
results.Add(item, new List<string>());
|
||||
foreach (var item in Headers)
|
||||
results[item.Key].AddRange(item.Value);
|
||||
foreach (var item in Details)
|
||||
results[item.Key].AddRange(item.Value);
|
||||
foreach (var item in Parameters)
|
||||
results[item.Key].AddRange(item.Value);
|
||||
foreach (var item in DatabaseHeaders)
|
||||
results[item.Key].AddRange(item.Value);
|
||||
foreach (var item in DatabaseDetails)
|
||||
results[item.Key].AddRange(item.Value);
|
||||
int count = GetCount();
|
||||
foreach (var keyValuePair in results)
|
||||
{
|
||||
for (int i = keyValuePair.Value.Count; i < count; i++)
|
||||
results[keyValuePair.Key].Add(string.Empty);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private Dictionary<Enum, string> Merge(List<KeyValuePair<Enum, string>> keyValuePairs)
|
||||
{
|
||||
Dictionary<Enum, string> results = new Dictionary<Enum, string>();
|
||||
foreach (var element in keyValuePairs)
|
||||
results.Add(element.Key, element.Value);
|
||||
return results;
|
||||
}
|
||||
|
||||
private List<KeyValuePair<Enum, string>> GetAllColumnKeyValuePairs(int? i)
|
||||
{
|
||||
List<KeyValuePair<Enum, string>> results = new List<KeyValuePair<Enum, string>>();
|
||||
if (i.HasValue)
|
||||
{
|
||||
foreach (var item in Headers)
|
||||
results.Add(new KeyValuePair<Enum, string>(item.Key, item.Value[i.Value]));
|
||||
foreach (var item in Details)
|
||||
results.Add(new KeyValuePair<Enum, string>(item.Key, item.Value[i.Value]));
|
||||
foreach (var item in Parameters)
|
||||
results.Add(new KeyValuePair<Enum, string>(item.Key, item.Value[i.Value]));
|
||||
foreach (var item in DatabaseHeaders)
|
||||
results.Add(new KeyValuePair<Enum, string>(item.Key, item.Value[i.Value]));
|
||||
foreach (var item in DatabaseDetails)
|
||||
results.Add(new KeyValuePair<Enum, string>(item.Key, item.Value[i.Value]));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
internal Dictionary<Enum, string> GetAllColumnCollection(int? i)
|
||||
{
|
||||
Dictionary<Enum, string> results;
|
||||
List<KeyValuePair<Enum, string>> keyValuePairs = GetAllColumnKeyValuePairs(i);
|
||||
results = Merge(keyValuePairs);
|
||||
return results;
|
||||
}
|
||||
|
||||
private List<KeyValuePair<Enum, List<string>>> GetToolHeadersAndDatabaseHeadersColumnKeyValuePairs()
|
||||
{
|
||||
List<KeyValuePair<Enum, List<string>>> results = new List<KeyValuePair<Enum, List<string>>>();
|
||||
foreach (var item in Headers)
|
||||
results.Add(new KeyValuePair<Enum, List<string>>(item.Key, item.Value));
|
||||
foreach (var item in DatabaseHeaders)
|
||||
results.Add(new KeyValuePair<Enum, List<string>>(item.Key, item.Value));
|
||||
return results;
|
||||
}
|
||||
|
||||
internal Dictionary<Enum, List<string>> GetToolHeadersAndDatabaseHeadersCollection()
|
||||
{
|
||||
Dictionary<Enum, List<string>> results;
|
||||
List<KeyValuePair<Enum, List<string>>> keyValuePairs = GetToolHeadersAndDatabaseHeadersColumnKeyValuePairs();
|
||||
results = Merge(keyValuePairs);
|
||||
return results;
|
||||
}
|
||||
|
||||
private List<KeyValuePair<Enum, List<string>>> GetToolDetailsAndDatabaseDetailsColumnKeyValuePairs()
|
||||
{
|
||||
List<KeyValuePair<Enum, List<string>>> results = new List<KeyValuePair<Enum, List<string>>>();
|
||||
foreach (var item in Details)
|
||||
results.Add(new KeyValuePair<Enum, List<string>>(item.Key, item.Value));
|
||||
foreach (var item in Parameters)
|
||||
results.Add(new KeyValuePair<Enum, List<string>>(item.Key, item.Value));
|
||||
foreach (var item in DatabaseDetails)
|
||||
results.Add(new KeyValuePair<Enum, List<string>>(item.Key, item.Value));
|
||||
return results;
|
||||
}
|
||||
|
||||
internal Dictionary<Enum, List<string>> GetToolDetailsAndDatabaseDetailsCollection()
|
||||
{
|
||||
Dictionary<Enum, List<string>> results;
|
||||
List<KeyValuePair<Enum, List<string>>> keyValuePairs = GetToolDetailsAndDatabaseDetailsColumnKeyValuePairs();
|
||||
results = Merge(keyValuePairs);
|
||||
return results;
|
||||
}
|
||||
|
||||
internal Dictionary<Test, List<int>> GetTests()
|
||||
{
|
||||
Dictionary<Test, List<int>> results = new Dictionary<Test, List<int>>();
|
||||
Test test;
|
||||
for (int i = 0; i < RowColumns[Description.RowColumn.Test].Count; i++)
|
||||
{
|
||||
test = (Test)RowColumns[Description.RowColumn.Test][i];
|
||||
if (!results.ContainsKey(test))
|
||||
results.Add(test, new List<int>());
|
||||
results[test].Add(i);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
internal void FillIn(string nullData, int count, Enum[] currentColumns)
|
||||
{
|
||||
foreach (Enum column in Headers.Keys)
|
||||
{
|
||||
for (int i = Headers[column].Count(); i < count; i++)
|
||||
Headers[column].Add(nullData);
|
||||
}
|
||||
foreach (Enum column in Details.Keys)
|
||||
{
|
||||
for (int i = Details[column].Count(); i < count; i++)
|
||||
Details[column].Add(nullData);
|
||||
}
|
||||
if (!(currentColumns is null))
|
||||
{
|
||||
foreach (Enum column in currentColumns)
|
||||
{
|
||||
for (int i = Parameters[column].Count(); i < count; i++)
|
||||
Parameters[column].Add(nullData);
|
||||
}
|
||||
}
|
||||
foreach (Enum column in Parameters.Keys)
|
||||
{
|
||||
for (int i = Parameters[column].Count(); i < count; i++)
|
||||
Parameters[column].Add(string.Empty);
|
||||
}
|
||||
foreach (Enum column in DatabaseHeaders.Keys)
|
||||
{
|
||||
for (int i = DatabaseHeaders[column].Count(); i < count; i++)
|
||||
DatabaseHeaders[column].Add(string.Empty);
|
||||
}
|
||||
foreach (Enum column in DatabaseDetails.Keys)
|
||||
{
|
||||
for (int i = DatabaseDetails[column].Count(); i < count; i++)
|
||||
DatabaseDetails[column].Add(string.Empty);
|
||||
}
|
||||
if (RowColumns[Description.RowColumn.Count].Count() != RowColumns[Description.RowColumn.Test].Count())
|
||||
{
|
||||
count = RowColumns[Description.RowColumn.Test].Count();
|
||||
RowColumns[Description.RowColumn.Count].Clear();
|
||||
for (int i = 0; i < count; i++)
|
||||
RowColumns[Description.RowColumn.Count].Add(count);
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetCollections(Logistics logistics, Dictionary<Test, Dictionary<string, List<string>>> rawData)
|
||||
{
|
||||
Array array;
|
||||
Column? column;
|
||||
bool recordStartPresent = false;
|
||||
Description.RowColumn? rowColumn;
|
||||
Description.LogisticsColumn? logisticsColumn;
|
||||
array = Enum.GetValues(typeof(Description.RowColumn));
|
||||
Dictionary<string, Enum> headers = new Dictionary<string, Enum>();
|
||||
Dictionary<string, Enum> details = new Dictionary<string, Enum>();
|
||||
Dictionary<string, Enum> parameters = new Dictionary<string, Enum>();
|
||||
Dictionary<string, Enum> databaseHeaders = new Dictionary<string, Enum>();
|
||||
Dictionary<string, Enum> databaseDetails = new Dictionary<string, Enum>();
|
||||
Dictionary<Description.RowColumn, List<string>> rowColumns = new Dictionary<Description.RowColumn, List<string>>();
|
||||
foreach (var item in Headers)
|
||||
headers.Add(item.Key.ToString(), item.Key);
|
||||
foreach (var item in Details)
|
||||
headers.Add(item.Key.ToString(), item.Key);
|
||||
foreach (var item in Parameters)
|
||||
headers.Add(item.Key.ToString(), item.Key);
|
||||
foreach (var item in DatabaseHeaders)
|
||||
headers.Add(item.Key.ToString(), item.Key);
|
||||
foreach (var item in DatabaseDetails)
|
||||
headers.Add(item.Key.ToString(), item.Key);
|
||||
foreach (Description.RowColumn item in array)
|
||||
rowColumns.Add(item, new List<string>());
|
||||
foreach (var element in rawData)
|
||||
{
|
||||
foreach (var item in element.Value)
|
||||
{
|
||||
column = null;
|
||||
rowColumn = null;
|
||||
logisticsColumn = null;
|
||||
if (item.Key == "Time")
|
||||
continue;
|
||||
else if (item.Key == "A_LOGISTICS")
|
||||
continue;
|
||||
else if (item.Key == "B_LOGISTICS")
|
||||
continue;
|
||||
else if (item.Key == "EventId")
|
||||
continue;
|
||||
else if (item.Key == ProcessDataStandardFormat.RecordStart)
|
||||
{
|
||||
recordStartPresent = true;
|
||||
continue;
|
||||
}
|
||||
if (Enum.TryParse(item.Key, out Column columnTry))
|
||||
column = columnTry;
|
||||
else
|
||||
{
|
||||
if (Enum.TryParse(item.Key, out Description.LogisticsColumn logisticsColumnTry))
|
||||
logisticsColumn = logisticsColumnTry;
|
||||
else
|
||||
{
|
||||
if (Enum.TryParse(item.Key, out Description.RowColumn rowColumnTry))
|
||||
rowColumn = rowColumnTry;
|
||||
}
|
||||
}
|
||||
if (rowColumn.HasValue)
|
||||
rowColumns[rowColumn.Value].AddRange(item.Value);
|
||||
else if (logisticsColumn.HasValue)
|
||||
LogisticsColumns[logisticsColumn.Value].AddRange(item.Value);
|
||||
else if (column.HasValue)
|
||||
{
|
||||
if (Headers.ContainsKey(column.Value))
|
||||
Headers[column.Value].AddRange(item.Value);
|
||||
else if (Details.ContainsKey(column.Value))
|
||||
Details[column.Value].AddRange(item.Value);
|
||||
else if (Parameters.ContainsKey(column.Value))
|
||||
Parameters[column.Value].AddRange(item.Value);
|
||||
else if (DatabaseHeaders.ContainsKey(column.Value))
|
||||
DatabaseHeaders[column.Value].AddRange(item.Value);
|
||||
else if (DatabaseDetails.ContainsKey(column.Value))
|
||||
DatabaseDetails[column.Value].AddRange(item.Value);
|
||||
else
|
||||
{
|
||||
if (!recordStartPresent)
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (headers.ContainsKey(item.Key))
|
||||
Headers[headers[item.Key]].AddRange(item.Value);
|
||||
else if (details.ContainsKey(item.Key))
|
||||
Details[details[item.Key]].AddRange(item.Value);
|
||||
else if (parameters.ContainsKey(item.Key))
|
||||
Parameters[parameters[item.Key]].AddRange(item.Value);
|
||||
else if (databaseHeaders.ContainsKey(item.Key))
|
||||
DatabaseHeaders[databaseHeaders[item.Key]].AddRange(item.Value);
|
||||
else if (databaseDetails.ContainsKey(item.Key))
|
||||
DatabaseDetails[databaseDetails[item.Key]].AddRange(item.Value);
|
||||
else
|
||||
{
|
||||
if (!recordStartPresent)
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var element in rowColumns)
|
||||
{
|
||||
for (int i = 0; i < element.Value.Count(); i++)
|
||||
{
|
||||
int.TryParse(element.Value[i], out int rowColumnTry);
|
||||
RowColumns[element.Key].Add(rowColumnTry);
|
||||
}
|
||||
}
|
||||
array = Enum.GetValues(typeof(Description.RowColumn));
|
||||
foreach (Description.RowColumn item in array)
|
||||
{
|
||||
if (!RowColumns.ContainsKey(item))
|
||||
throw new Exception();
|
||||
}
|
||||
array = Enum.GetValues(typeof(Description.LogisticsColumn));
|
||||
foreach (Description.LogisticsColumn item in array)
|
||||
{
|
||||
if (!LogisticsColumns.ContainsKey(item))
|
||||
throw new Exception();
|
||||
}
|
||||
int count = rowColumns[Description.RowColumn.Test].Count();
|
||||
foreach (var element in DatabaseHeaders)
|
||||
{
|
||||
for (int i = element.Value.Count(); i < count; i++)
|
||||
element.Value.Add(string.Empty);
|
||||
}
|
||||
foreach (var element in DatabaseDetails)
|
||||
{
|
||||
for (int i = element.Value.Count(); i < count; i++)
|
||||
element.Value.Add(string.Empty);
|
||||
}
|
||||
string nullData;
|
||||
if (logistics.NullData is null)
|
||||
nullData = string.Empty;
|
||||
else
|
||||
nullData = logistics.NullData.ToString();
|
||||
Dictionary<Enum, List<string>> keyValuePairs;
|
||||
foreach (Test key in rawData.Keys)
|
||||
{
|
||||
IgnoreIndeices.Add(key, new Dictionary<Enum, List<int>>());
|
||||
for (int g = 1; g < 4; g++)
|
||||
{
|
||||
switch (g)
|
||||
{
|
||||
case 1:
|
||||
keyValuePairs = Details;
|
||||
break;
|
||||
case 2:
|
||||
keyValuePairs = Parameters;
|
||||
break;
|
||||
case 3:
|
||||
keyValuePairs = DatabaseDetails;
|
||||
break;
|
||||
default:
|
||||
throw new Exception();
|
||||
}
|
||||
foreach (var element in keyValuePairs)
|
||||
{
|
||||
IgnoreIndeices[key].Add(element.Key, new List<int>());
|
||||
if (!element.Value.Any())
|
||||
{
|
||||
for (int i = 0; i < RowColumns[Description.RowColumn.Test].Count(); i++)
|
||||
{
|
||||
IgnoreIndeices[key][element.Key].Add(i);
|
||||
element.Value.Add(string.Empty);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < element.Value.Count(); i++)
|
||||
{
|
||||
if (RowColumns[Description.RowColumn.Test][i] == (int)key)
|
||||
{
|
||||
if (string.IsNullOrEmpty(element.Value[i]))
|
||||
IgnoreIndeices[key][element.Key].Add(i);
|
||||
else if (!(logistics.NullData is null) && element.Value[i] == nullData)
|
||||
IgnoreIndeices[key][element.Key].Add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (recordStartPresent)
|
||||
FillIn(string.Empty, RowColumns[Description.RowColumn.Test].Count(), currentColumns: null);
|
||||
GetCount();
|
||||
}
|
||||
|
||||
internal void UpdateLastTicksDuration(long ticksDuration)
|
||||
{
|
||||
if (ticksDuration < 50000000)
|
||||
ticksDuration = 50000000;
|
||||
LastTicksDuration = (long)Math.Ceiling(ticksDuration * .667);
|
||||
}
|
||||
|
||||
private string GetTupleFile(Logistics logistics, ScopeInfo scopeInfo, string duplicateDirectory)
|
||||
{
|
||||
string result;
|
||||
string rds;
|
||||
string dateValue;
|
||||
string datePlaceholder;
|
||||
string[] segments = logistics.MID.Split('-');
|
||||
if (segments.Length < 2)
|
||||
rds = "%RDS%";
|
||||
else
|
||||
rds = segments[1];
|
||||
segments = scopeInfo.FileName.Split(new string[] { "DateTime:" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (segments.Length == 0)
|
||||
result = string.Concat(duplicateDirectory, @"\", scopeInfo.FileNameWithoutExtension.Replace("%RDS%", rds));
|
||||
else
|
||||
{
|
||||
datePlaceholder = "%DateTime%";
|
||||
segments = segments[1].Split('%');
|
||||
dateValue = logistics.DateTimeFromSequence.ToString(segments[0]);
|
||||
foreach (string segment in scopeInfo.FileName.Split('%'))
|
||||
{
|
||||
if (!segment.Contains(segments[0]))
|
||||
continue;
|
||||
datePlaceholder = string.Concat('%', segment, '%');
|
||||
}
|
||||
result = string.Concat(duplicateDirectory, @"\", scopeInfo.FileName.Replace("%RDS%", rds).Replace(datePlaceholder, dateValue));
|
||||
}
|
||||
if (result.Contains('%'))
|
||||
throw new Exception("Placeholder exists!");
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void AutoAdd(Enum key, string value)
|
||||
{
|
||||
if (Headers.ContainsKey(key))
|
||||
Headers[key].Add(value);
|
||||
else if (Details.ContainsKey(key))
|
||||
Details[key].Add(value);
|
||||
else if (Parameters.ContainsKey(key))
|
||||
Parameters[key].Add(value);
|
||||
else if (DatabaseHeaders.ContainsKey(key))
|
||||
DatabaseHeaders[key].Add(value);
|
||||
else if (DatabaseDetails.ContainsKey(key))
|
||||
DatabaseDetails[key].Add(value);
|
||||
else
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
16
Adaptation/Shared/IProcessData.cs
Normal file
16
Adaptation/Shared/IProcessData.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using Adaptation.Shared.Metrology;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Adaptation.Shared
|
||||
{
|
||||
public interface IProcessData
|
||||
{
|
||||
|
||||
Tuple<string, JsonElement?, List<FileInfo>> GetResults(ILogic logic, ConfigDataBase configData, List<FileInfo> fileInfoCollection);
|
||||
|
||||
}
|
||||
|
||||
}
|
26
Adaptation/Shared/IProcessDataDescription.cs
Normal file
26
Adaptation/Shared/IProcessDataDescription.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using Adaptation.Shared.Metrology;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Adaptation.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();
|
||||
|
||||
}
|
||||
|
||||
}
|
239
Adaptation/Shared/IQSRecord.cs
Normal file
239
Adaptation/Shared/IQSRecord.cs
Normal file
@ -0,0 +1,239 @@
|
||||
using Adaptation.Shared.Metrology;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Adaptation.Shared
|
||||
{
|
||||
|
||||
public class IQSRecord
|
||||
{
|
||||
|
||||
public string SID { get; protected set; }
|
||||
public string Part { get; protected set; }
|
||||
public string Process { get; protected set; }
|
||||
public string Lot { get; protected set; }
|
||||
public string SampleSize { get; protected set; }
|
||||
public string ParameterName { get; protected set; }
|
||||
public string TestNumber { get; protected set; }
|
||||
public string ParameterValue { get; protected set; }
|
||||
public string WaferID { get; protected set; }
|
||||
public string WaferScribe { get; protected set; }
|
||||
public string Pocket { get; protected set; }
|
||||
public string EpiThicknessMean { get; protected set; }
|
||||
public string WaferRegion { get; protected set; }
|
||||
public string ToolID { get; protected set; }
|
||||
public string EmployeeID { get; protected set; }
|
||||
public string EmployeeName { get; protected set; }
|
||||
public string Date { get; protected set; }
|
||||
public Column Column { get; protected set; }
|
||||
|
||||
public IQSRecord(object sID, object part, object process, object lot, object sampleSize, object parameterName, object testNumber, object parameterValue, object waferID, object waferScribe, object pocket, object epiThicknessMean, object waferRegion, object toolID, object employeeID, object employeeName, object date, Dictionary<string, Column> keyValuePairs)
|
||||
{
|
||||
if (sID is null)
|
||||
SID = string.Empty;
|
||||
else
|
||||
SID = sID.ToString();
|
||||
if (part is null)
|
||||
Part = string.Empty;
|
||||
else
|
||||
Part = part.ToString();
|
||||
if (process is null)
|
||||
Process = string.Empty;
|
||||
else
|
||||
Process = process.ToString();
|
||||
if (lot is null)
|
||||
Lot = string.Empty;
|
||||
else
|
||||
Lot = lot.ToString();
|
||||
if (sampleSize is null)
|
||||
SampleSize = string.Empty;
|
||||
else
|
||||
SampleSize = sampleSize.ToString();
|
||||
if (parameterName is null)
|
||||
ParameterName = string.Empty;
|
||||
else
|
||||
ParameterName = parameterName.ToString();
|
||||
if (testNumber is null)
|
||||
TestNumber = string.Empty;
|
||||
else
|
||||
TestNumber = testNumber.ToString();
|
||||
if (parameterValue is null)
|
||||
ParameterValue = string.Empty;
|
||||
else
|
||||
ParameterValue = parameterValue.ToString();
|
||||
if (waferID is null)
|
||||
WaferID = string.Empty;
|
||||
else
|
||||
WaferID = waferID.ToString();
|
||||
if (waferScribe is null)
|
||||
WaferScribe = string.Empty;
|
||||
else
|
||||
WaferScribe = waferScribe.ToString();
|
||||
if (pocket is null)
|
||||
Pocket = string.Empty;
|
||||
else
|
||||
Pocket = pocket.ToString();
|
||||
if (epiThicknessMean is null)
|
||||
EpiThicknessMean = string.Empty;
|
||||
else
|
||||
EpiThicknessMean = epiThicknessMean.ToString();
|
||||
if (waferRegion is null)
|
||||
WaferRegion = string.Empty;
|
||||
else
|
||||
WaferRegion = waferRegion.ToString();
|
||||
if (toolID is null)
|
||||
ToolID = string.Empty;
|
||||
else
|
||||
ToolID = toolID.ToString();
|
||||
if (employeeID is null)
|
||||
EmployeeID = string.Empty;
|
||||
else
|
||||
EmployeeID = employeeID.ToString();
|
||||
if (employeeName is null)
|
||||
EmployeeName = string.Empty;
|
||||
else
|
||||
EmployeeName = employeeName.ToString();
|
||||
if (date is null)
|
||||
Date = string.Empty;
|
||||
else
|
||||
Date = date.ToString();
|
||||
if (parameterName is null || !keyValuePairs.ContainsKey(parameterName.ToString()))
|
||||
Column = Column.AFM_Roughness;
|
||||
else
|
||||
Column = keyValuePairs[parameterName.ToString()];
|
||||
}
|
||||
|
||||
private static string GetBaseTableJoins()
|
||||
{
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.Append(" from [irmnspc].[dbo].sgrp_ext se ").
|
||||
Append(" join [irmnspc].[dbo].test_dat td on se.f_test = td.f_test ").
|
||||
Append(" join [irmnspc].[dbo].part_dat pd on se.f_part = pd.f_part ").
|
||||
Append(" join [irmnspc].[dbo].part_lot pl on se.f_lot = pl.f_lot ").
|
||||
Append(" join [irmnspc].[dbo].prcs_dat pr on se.f_prcs = pr.f_prcs ").
|
||||
Append(" join [irmnspc].[dbo].empl_inf em on se.f_empl = em.f_empl ");
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
internal static StringBuilder GetIqsRecordsSinceSql()
|
||||
{
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.Append(" select ").
|
||||
Append(" se.f_sgrp [sid], concat(se.f_sgrp, ', ', td.f_name, ', ', pd.f_name, ', ', pl.f_name, ', ', pr.f_name, ', ', em.f_name, ', ', se.f_sgtm) [csv] ").
|
||||
Append(GetBaseTableJoins()).
|
||||
Append(" where se.f_sgrp >= 1543459064 ").
|
||||
Append(" and se.f_sgrp > ( @lastSID - 20 ) ").
|
||||
Append(" /* and dateadd(hh, -7, (dateadd(ss, convert(bigint, se.f_sgtm), '19700101'))) >= '2019-08-25 00:00:00.000' */ ").
|
||||
Append(" and td.f_name = @key ").
|
||||
Append(" group by se.f_sgrp, td.f_name, pd.f_name, pl.f_name, pr.f_name, em.f_name, se.f_sgtm ").
|
||||
Append(" order by se.f_sgrp, pd.f_name, td.f_name ");
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static StringBuilder GetIqsRecordsSql()
|
||||
{
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.Append(" select ").
|
||||
Append(" ta.id [SID], ").
|
||||
Append(" ta.ms [Part], ").
|
||||
Append(" ta.pr [Process], ").
|
||||
Append(" ta.lt [Lot], ").
|
||||
Append(" ta.sz [Sample Size], ").
|
||||
Append(" ta.pn [Parameter Name], ").
|
||||
Append(" ta.tn [Test Number], ").
|
||||
Append(" ta.pv [Parameter Value], ").
|
||||
Append(" tb.v1337859646 [Wafer ID], ").
|
||||
Append(" tb.v1337859592 [Wafer Scribe], ").
|
||||
Append(" tb.v1342510661 [Pocket], ").
|
||||
Append(" tb.v1340294286 [Epi Thickness Mean], ").
|
||||
Append(" tb.v1345566180 [Wafer Region], ").
|
||||
Append(" tb.v1363881711 [Tool ID], ").
|
||||
Append(" ta.em [Employee ID], ").
|
||||
Append(" ta.en [Employee Name], ").
|
||||
Append(" ta.dt [Date] ").
|
||||
Append(" from ( ").
|
||||
Append(" select ").
|
||||
Append(" se.f_sgrp id, ").
|
||||
Append(" se.f_sgsz sz, ").
|
||||
Append(" concat(se.f_tsno, '.', se.f_sbno) tn, ").
|
||||
Append(" se.f_val pv, ").
|
||||
Append(" se.f_empl em, ").
|
||||
Append(" dateadd(hh, -7, (dateadd(ss, convert(bigint, se.f_sgtm), '19700101'))) dt, ").
|
||||
Append(" td.f_name pn, ").
|
||||
Append(" pd.f_name as ms, ").
|
||||
Append(" pl.f_name lt, ").
|
||||
Append(" pr.f_name pr, ").
|
||||
Append(" em.f_name en ").
|
||||
Append(GetBaseTableJoins()).
|
||||
Append(" where se.f_sgrp = @sid ").
|
||||
Append(" ) as ta ").
|
||||
Append(" join ( ").
|
||||
Append(" select ").
|
||||
Append(" se.f_sgrp id, ").
|
||||
Append(" max(case when dd.f_dsgp = 1337859646 then dd.f_name end) as v1337859646, ").
|
||||
Append(" max(case when dd.f_dsgp = 1337859592 then dd.f_name end) as v1337859592, ").
|
||||
Append(" max(case when dd.f_dsgp = 1342510661 then dd.f_name end) as v1342510661, ").
|
||||
Append(" max(case when dd.f_dsgp = 1340294286 then dd.f_name end) as v1340294286, ").
|
||||
Append(" max(case when dd.f_dsgp = 1345566180 then dd.f_name end) as v1345566180, ").
|
||||
Append(" max(case when dd.f_dsgp = 1363881711 then dd.f_name end) as v1363881711 ").
|
||||
Append(" from [irmnspc].[dbo].sgrp_ext se ").
|
||||
Append(" join [irmnspc].[dbo].test_dat td on se.f_test = td.f_test ").
|
||||
Append(" join [irmnspc].[dbo].sgrp_dsc sd on se.f_sgrp = sd.f_sgrp ").
|
||||
Append(" join [irmnspc].[dbo].desc_dat dd on sd.f_desc = dd.f_desc ").
|
||||
Append(" and isnull(dd.f_name, '') <> '' ").
|
||||
Append(" where se.f_sgrp = @sid ").
|
||||
Append(" and dd.f_dsgp in (1337859646 /* Wafer ID */, 1337859592 /* Wafer Scribe */, 1342510661 /* Pocket */, 1340294286 /* Epi Thickness Mean */, 1345566180 /* Wafer Region */, 1363881711 /* Tool ID */) ").
|
||||
Append(" group by se.f_sgrp ").
|
||||
Append(" ) tb on ta.id = tb.id ").
|
||||
Append(" order by ta.id desc, ta.ms, ta.pr, ta.lt, ta.sz, ta.tn, ta.dt, ta.pn ");
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static List<IQSRecord> GetIqsRecords(Dictionary<int, List<object>> rawData, int count)
|
||||
{
|
||||
List<IQSRecord> results = new List<IQSRecord>();
|
||||
IQSRecord iqsRecord;
|
||||
List<object> c0 = rawData[0];
|
||||
List<object> c1 = rawData[1];
|
||||
List<object> c2 = rawData[2];
|
||||
List<object> c3 = rawData[3];
|
||||
List<object> c4 = rawData[4];
|
||||
List<object> c5 = rawData[5];
|
||||
List<object> c6 = rawData[6];
|
||||
List<object> c7 = rawData[7];
|
||||
List<object> c8 = rawData[8];
|
||||
List<object> c9 = rawData[9];
|
||||
List<object> cA = rawData[10];
|
||||
List<object> cB = rawData[11];
|
||||
List<object> cC = rawData[12];
|
||||
List<object> cD = rawData[13];
|
||||
List<object> cE = rawData[14];
|
||||
List<object> cF = rawData[15];
|
||||
List<object> cG = rawData[16];
|
||||
if (c0.Any())
|
||||
{
|
||||
Array array = Enum.GetValues(typeof(Column));
|
||||
Dictionary<string, Column> keyValuePairs = new Dictionary<string, Column>();
|
||||
foreach (Column column in array)
|
||||
keyValuePairs.Add(column.GetDiplayName(), column);
|
||||
for (int i = 0; i < c0.Count; i++)
|
||||
{
|
||||
iqsRecord = new IQSRecord(c0[i], c1[i], c2[i], c3[i], c4[i], c5[i], c6[i], c7[i], c8[i], c9[i], cA[i], cB[i], cC[i], cD[i], cE[i], cF[i], cG[i], keyValuePairs);
|
||||
results.Add(iqsRecord);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
//(1337859646 /* Wafer ID */, 1337859592 /* Wafer Scribe */, 1342510661 /* Pocket */, 1340294286 /* Epi Thickness Mean */, 1345566180 /* Wafer Region */, 1363881711 /* Tool ID */) ").
|
||||
//return string.Concat(SID, Part, Process, Lot, SampleSize, TestNumber, WaferID, WaferScribe, Pocket, EpiThicknessMean, WaferRegion, ToolID, EmployeeID, EmployeeName, Date);
|
||||
return string.Concat(SID, Part, Process, Lot, SampleSize, TestNumber, EmployeeID, EmployeeName, Date);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
21
Adaptation/Shared/IScopeInfo.cs
Normal file
21
Adaptation/Shared/IScopeInfo.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace Adaptation.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; }
|
||||
|
||||
}
|
||||
|
||||
}
|
171
Adaptation/Shared/IsEnvironment.cs
Normal file
171
Adaptation/Shared/IsEnvironment.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
244
Adaptation/Shared/Logistics.cs
Normal file
244
Adaptation/Shared/Logistics.cs
Normal file
@ -0,0 +1,244 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Adaptation.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
|
||||
{
|
||||
foreach (var element in cellNames)
|
||||
{
|
||||
if (fileInfo.FullName.IndexOf(element.Key, StringComparison.OrdinalIgnoreCase) > -1 || fileInfo.FullName.IndexOf(element.Value, StringComparison.OrdinalIgnoreCase) > -1)
|
||||
{
|
||||
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>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
80
Adaptation/Shared/Logistics2.cs
Normal file
80
Adaptation/Shared/Logistics2.cs
Normal file
@ -0,0 +1,80 @@
|
||||
using System;
|
||||
|
||||
namespace Adaptation.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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
1605
Adaptation/Shared/Metrology/Column.cs
Normal file
1605
Adaptation/Shared/Metrology/Column.cs
Normal file
File diff suppressed because it is too large
Load Diff
419
Adaptation/Shared/Metrology/ConfigDataBase.cs
Normal file
419
Adaptation/Shared/Metrology/ConfigDataBase.cs
Normal file
@ -0,0 +1,419 @@
|
||||
using Adaptation.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 Adaptation.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 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 EventName GetEventNameValue()
|
||||
{
|
||||
EventName result = _EventName;
|
||||
return result;
|
||||
}
|
||||
|
||||
public string GetEquipmentType()
|
||||
{
|
||||
string result;
|
||||
if (_EquipmentConnection is null)
|
||||
result = _EquipmentType.ToString();
|
||||
else
|
||||
result = _EquipmentConnection.Value.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
Adaptation/Shared/Metrology/EventName.cs
Normal file
13
Adaptation/Shared/Metrology/EventName.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace Adaptation.Shared.Metrology
|
||||
{
|
||||
|
||||
public enum EventName
|
||||
{
|
||||
FileRead,
|
||||
FileReadDaily,
|
||||
FileReadMonthly,
|
||||
FileReadVerification,
|
||||
FileReadWeekly
|
||||
}
|
||||
|
||||
}
|
45
Adaptation/Shared/Metrology/ILogic.cs
Normal file
45
Adaptation/Shared/Metrology/ILogic.cs
Normal file
@ -0,0 +1,45 @@
|
||||
using Adaptation.Eaf.Management.ConfigurationData.CellAutomation;
|
||||
using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Adaptation.Shared.Metrology
|
||||
{
|
||||
|
||||
public interface ILogic
|
||||
{
|
||||
|
||||
ILogic ShallowCopy();
|
||||
Logistics Logistics { get; }
|
||||
|
||||
void ConfigurationRestore();
|
||||
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);
|
||||
Tuple<string, JsonElement?, List<FileInfo>> 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
Adaptation/Shared/Metrology/MET08DDUPSFS6420.cs
Normal file
14
Adaptation/Shared/Metrology/MET08DDUPSFS6420.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Adaptation.Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08DDUPSFS6420
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
Tencor = Metrology.Test.Tencor
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
Adaptation/Shared/Metrology/MET08DDUPSP1TBI.cs
Normal file
14
Adaptation/Shared/Metrology/MET08DDUPSP1TBI.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Adaptation.Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08DDUPSP1TBI
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
SP1 = Metrology.Test.SP1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
Adaptation/Shared/Metrology/MET08RESIHGCV.cs
Normal file
14
Adaptation/Shared/Metrology/MET08RESIHGCV.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Adaptation.Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08RESIHGCV
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
HgCV = Metrology.Test.HgCV
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
Adaptation/Shared/Metrology/MET08RESIMAPCDE.cs
Normal file
14
Adaptation/Shared/Metrology/MET08RESIMAPCDE.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Adaptation.Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08RESIMAPCDE
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
CDE = Metrology.Test.CDE
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
Adaptation/Shared/Metrology/MET08THFTIRQS408M.cs
Normal file
14
Adaptation/Shared/Metrology/MET08THFTIRQS408M.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Adaptation.Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08THFTIRQS408M
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
BioRadQS408M = Metrology.Test.BioRadQS408M
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
Adaptation/Shared/Metrology/MET08THFTIRSTRATUS.cs
Normal file
14
Adaptation/Shared/Metrology/MET08THFTIRSTRATUS.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Adaptation.Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08THFTIRSTRATUS
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
BioRadStratus = Metrology.Test.BioRadStratus
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
23
Adaptation/Shared/Metrology/MET08XRDXPERTPROMRDXL.cs
Normal file
23
Adaptation/Shared/Metrology/MET08XRDXPERTPROMRDXL.cs
Normal file
@ -0,0 +1,23 @@
|
||||
namespace Adaptation.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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
36
Adaptation/Shared/Metrology/OISiViewer.cs
Normal file
36
Adaptation/Shared/Metrology/OISiViewer.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System;
|
||||
|
||||
namespace Adaptation.Shared.Metrology
|
||||
{
|
||||
|
||||
internal class OISiViewer
|
||||
{
|
||||
|
||||
private static System.Net.WebClient _WebClient;
|
||||
|
||||
internal static string WebClientDownloadString(string baseAddress, ConfigDataBase configDataBase, string reportFullPath, bool isErrorFile, string target)
|
||||
{
|
||||
string result = string.Empty;
|
||||
if (System.Diagnostics.Debugger.IsAttached)
|
||||
result = DateTime.Now.ToString();
|
||||
else
|
||||
{
|
||||
if (string.IsNullOrEmpty(baseAddress) || !baseAddress.Contains(":") || !baseAddress.Contains("."))
|
||||
throw new Exception("Invalid URL");
|
||||
try
|
||||
{
|
||||
if (_WebClient is null)
|
||||
_WebClient = new System.Net.WebClient();
|
||||
string address = string.Concat(baseAddress, "/Home/ExtractMove/?equipment_connection=", configDataBase.GetEquipmentType(), "&is_error_file=", isErrorFile);
|
||||
_WebClient.OpenRead(address);
|
||||
result = _WebClient.ResponseHeaders["Date"];
|
||||
_WebClient.CancelAsync();
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
110
Adaptation/Shared/Metrology/ProcessData.Duplicator.cs
Normal file
110
Adaptation/Shared/Metrology/ProcessData.Duplicator.cs
Normal file
@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Adaptation.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
Adaptation/Shared/Metrology/ProcessDataStandardFormat.cs
Normal file
527
Adaptation/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 Adaptation.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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
409
Adaptation/Shared/Metrology/ScopeInfo.cs
Normal file
409
Adaptation/Shared/Metrology/ScopeInfo.cs
Normal file
@ -0,0 +1,409 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Adaptation.Shared.Metrology
|
||||
{
|
||||
|
||||
public class ScopeInfo : IScopeInfo
|
||||
{
|
||||
|
||||
public Test Test { get; private set; }
|
||||
public Enum Enum { get; private set; }
|
||||
public string HTML { get; private set; }
|
||||
public string Title { get; private set; }
|
||||
public string FileName { get; private set; }
|
||||
public int TestValue { get; private set; }
|
||||
public string Header { get; private set; }
|
||||
public string QueryFilter { get; private set; }
|
||||
public string FileNameWithoutExtension { get; private set; }
|
||||
public EquipmentType EquipmentType { get; private set; }
|
||||
|
||||
public ScopeInfo(ILogic logic, ConfigDataBase configDataBase, Test test)
|
||||
{
|
||||
Enum = test;
|
||||
Test = test;
|
||||
TestValue = (int)test;
|
||||
if (configDataBase.EquipmentConnection is null)
|
||||
EquipmentType = configDataBase.EquipmentType;
|
||||
else
|
||||
EquipmentType = configDataBase.EquipmentConnection.Value;
|
||||
string eventName = GetEventNameAndSetRemaining();
|
||||
if (eventName != configDataBase.GetEventName())
|
||||
{
|
||||
File.Move(logic.Logistics.ReportFullPath, Path.ChangeExtension(logic.Logistics.ReportFullPath, eventName));
|
||||
throw new Exception();
|
||||
}
|
||||
else if (EquipmentType != configDataBase.EquipmentType && EquipmentType != configDataBase.EquipmentConnection)
|
||||
{
|
||||
File.Move(logic.Logistics.ReportFullPath, Path.ChangeExtension(logic.Logistics.ReportFullPath, EquipmentType.ToString()));
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
|
||||
public ScopeInfo(ILogic logic, ConfigDataBase configDataBase, Test test, string fileName, string queryFilter, string title = "", string html = "")
|
||||
{
|
||||
Enum = test;
|
||||
Test = test;
|
||||
TestValue = (int)test;
|
||||
if (configDataBase.EquipmentConnection is null)
|
||||
EquipmentType = configDataBase.EquipmentType;
|
||||
else
|
||||
EquipmentType = configDataBase.EquipmentConnection.Value;
|
||||
FileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
|
||||
Header = string.Empty;
|
||||
QueryFilter = queryFilter;
|
||||
Title = title;
|
||||
HTML = html;
|
||||
FileName = fileName;
|
||||
}
|
||||
|
||||
public ScopeInfo ShallowCopy()
|
||||
{
|
||||
return (ScopeInfo)MemberwiseClone();
|
||||
}
|
||||
|
||||
private string GetEventNameAndSetRemaining()
|
||||
{
|
||||
EventName eventName;
|
||||
switch (Test)
|
||||
{
|
||||
case Test.AFMRoughness:
|
||||
EquipmentType = EquipmentType.MET08AFMD3100;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "afm_iqs_01";
|
||||
Header = string.Empty;
|
||||
QueryFilter = "AFM Roughness";
|
||||
Title = "AFM";
|
||||
HTML = @"GaN Epi Data\10 - afm.html";
|
||||
break;
|
||||
case Test.BreakdownVoltageCenter:
|
||||
EquipmentType = EquipmentType.MET08BVHGPROBE;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "bv_iqs_01";
|
||||
Header = "Reactor;fDate;fRecipeName;Lot;fPocketNumber;g4Scribe;BV Position;BV Value;Tool";
|
||||
QueryFilter = "Breakdown Voltage";
|
||||
Title = "Breakdown Voltage-Center";
|
||||
HTML = @"GaN Epi Data\03 - bv-production.html";
|
||||
break;
|
||||
case Test.BreakdownVoltageEdge:
|
||||
EquipmentType = EquipmentType.MET08BVHGPROBE;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "bv_iqs_01_Edge";
|
||||
Header = "Reactor;fDate;fRecipeName;Lot;fPocketNumber;g4Scribe;BV Position;BV Value;Tool";
|
||||
QueryFilter = "Breakdown Voltage - Edge";
|
||||
Title = "Breakdown Voltage-Edge";
|
||||
HTML = @"GaN Epi Data\03 - bv-production.html";
|
||||
break;
|
||||
case Test.BreakdownVoltageMiddle8in:
|
||||
EquipmentType = EquipmentType.MET08BVHGPROBE;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "bv_iqs_01_Middle";
|
||||
Header = "Reactor;fDate;fRecipeName;Lot;fPocketNumber;g4Scribe;BV Position;BV Value;Tool";
|
||||
QueryFilter = "Breakdown Voltage - Middle";
|
||||
Title = "Breakdown Voltage-Middle (8 in)";
|
||||
HTML = @"GaN Epi Data\03 - bv-production.html";
|
||||
break;
|
||||
case Test.CV:
|
||||
EquipmentType = EquipmentType.MET08CVHGPROBE802B150;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "cv_iqs_01";
|
||||
Header = "Reactor;fDate;fPart;Lot;pocketNumber;g4Scribe;Position;Vp;NdMin;Tool ID;CV Ns;CV Cap";
|
||||
QueryFilter = "CV_Ns";
|
||||
Title = "CV";
|
||||
HTML = @"GaN Epi Data\05 - cv.html";
|
||||
break;
|
||||
case Test.MonthlyCV:
|
||||
EquipmentType = EquipmentType.MET08CVHGPROBE802B150_Monthly;
|
||||
eventName = EventName.FileReadMonthly;
|
||||
FileNameWithoutExtension = "cv_iqs_01";
|
||||
Header = "Reactor;fDate;fPart;Lot;pocketNumber;g4Scribe;Position;Vp;NdMin;Tool ID;CV Ns;CV Cap";
|
||||
QueryFilter = "CV_Ns";
|
||||
Title = "CV Monthly Verification";
|
||||
HTML = @"Metrology\07 - cv_verif_monthly.html";
|
||||
break;
|
||||
case Test.WeeklyCV:
|
||||
EquipmentType = EquipmentType.MET08CVHGPROBE802B150_Weekly;
|
||||
eventName = EventName.FileReadWeekly;
|
||||
FileNameWithoutExtension = "cv_iqs_01";
|
||||
Header = "Reactor;fDate;fPart;Lot;pocketNumber;g4Scribe;Position;Vp;NdMin;Tool ID;CV Ns;CV Cap";
|
||||
QueryFilter = "CV_Ns";
|
||||
Title = "CV Weekly Verification";
|
||||
HTML = @"Metrology\16 - cv_verif_weekly.html";
|
||||
break;
|
||||
case Test.CandelaKlarfDC:
|
||||
EquipmentType = EquipmentType.MET08DDINCAN8620;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "candela_iqs_01";
|
||||
Header = "LotID;OperatorID;RecipeName;CandelaRecipe;WaferID;PocketNumber;RunDate;Epi;SlipLines;Cracks;EpiDef;HazeSpot;SmallLpd;MediumLpd;LargeLpd;Cracks_A;Spirals;Craters;8620 Small;Pits;Tool ID;Defect Count";
|
||||
QueryFilter = "Candela Cracking";
|
||||
Title = "Candela";
|
||||
HTML = @"GaN Epi Data\12 - candela.html";
|
||||
break;
|
||||
case Test.CandelaLaser:
|
||||
EquipmentType = EquipmentType.MET08DDINCAN8620;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "candela_iqs_01";
|
||||
Header = "LotID;OperatorID;RecipeName;CandelaRecipe;WaferID;PocketNumber;RunDate;Epi;SlipLines;Cracks;EpiDef;HazeSpot;SmallLpd;MediumLpd;LargeLpd;Cracks_A;Spirals;Craters;Pits;Tool ID;Defect Count";
|
||||
QueryFilter = "Candela Cracking";
|
||||
Title = "Candela";
|
||||
HTML = @"GaN Epi Data\12 - candela.html";
|
||||
break;
|
||||
case Test.CandelaVerify:
|
||||
EquipmentType = EquipmentType.MET08DDINCAN8620;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "candela_iqs_01";
|
||||
Header = string.Concat("LotID;OperatorID;RecipeName;CandelaRecipe;WaferID;PocketNumber;RunDate;RunID;Reactor;", "Slip Lines;Cracks;Epi Def;Haze Spot;Small LPD;Medium LPD;Large LPD;Cracks_A;Spirals;Craters;8620 Small;Pits;Tool ID;Defect Count");
|
||||
QueryFilter = "Candela Cracking";
|
||||
Title = "Candela";
|
||||
HTML = @"GaN Epi Data\12 - candela.html";
|
||||
break;
|
||||
case Test.CandelaPSL:
|
||||
EquipmentType = EquipmentType.MET08DDINCAN8620_Daily;
|
||||
eventName = EventName.FileReadDaily;
|
||||
FileNameWithoutExtension = "candela_iqs_01";
|
||||
Header = string.Empty;
|
||||
QueryFilter = "102-83nm";
|
||||
Title = "Candela";
|
||||
HTML = @"GaN Epi Data\12 - candela.html";
|
||||
break;
|
||||
case Test.CandelaProdU:
|
||||
EquipmentType = EquipmentType.MET08DDINCAN8620_Daily;
|
||||
eventName = EventName.FileReadDaily;
|
||||
FileNameWithoutExtension = "candela_iqs_01";
|
||||
Header = string.Empty;
|
||||
QueryFilter = "SPE verification";
|
||||
Title = "Candela";
|
||||
HTML = @"GaN Epi Data\12 - candela.html";
|
||||
break;
|
||||
case Test.Denton:
|
||||
EquipmentType = EquipmentType.MET08EBEAMINTEGRITY26;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "denton_iqs_01";
|
||||
Header = "Tool;fDate;Run;Recipe;Operator;Name;Value";
|
||||
QueryFilter = "Denton_Voltage_AVG";
|
||||
Title = "Denton Data";
|
||||
HTML = @"Support Process\03 - ebeam02_denton_v1.html";
|
||||
break;
|
||||
case Test.Hall:
|
||||
EquipmentType = EquipmentType.MET08HALLHL5580;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "hall_iqs_01";
|
||||
Header = "Lot;Tool;TimeDate;RunDate;RunID;Part;Reactor;Scribe;PocketNumber;Tool ID;Name;Value";
|
||||
QueryFilter = "Hall Rs";
|
||||
Title = "Hall Data";
|
||||
HTML = @"GaN Epi Data\04 - hall.html";
|
||||
break;
|
||||
case Test.MonthlyHall:
|
||||
EquipmentType = EquipmentType.MET08HALLHL5580_Monthly;
|
||||
eventName = EventName.FileReadMonthly;
|
||||
FileNameWithoutExtension = "hall_iqs_01";
|
||||
Header = "Lot;Tool;TimeDate;RunDate;RunID;Part;Reactor;Scribe;PocketNumber;Tool ID;Name;Value";
|
||||
QueryFilter = "Hall Rs";
|
||||
Title = "Hall Monthly Verification";
|
||||
HTML = @"Metrology\06 - hall_verif_monthly.html";
|
||||
break;
|
||||
case Test.WeeklyHall:
|
||||
EquipmentType = EquipmentType.MET08HALLHL5580_Weekly;
|
||||
eventName = EventName.FileReadWeekly;
|
||||
FileNameWithoutExtension = "hall_iqs_01";
|
||||
Header = "Lot;Tool;TimeDate;RunDate;RunID;Part;Reactor;Scribe;PocketNumber;Tool ID;Name;Value";
|
||||
QueryFilter = "Hall Rs";
|
||||
Title = "Hall Weekly Verification";
|
||||
HTML = @"Metrology\15 - hall_verif_weekly.html";
|
||||
break;
|
||||
case Test.Lehighton:
|
||||
EquipmentType = EquipmentType.MET08NDFRESIMAP151C;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "lei_iqs_01";
|
||||
Header = "Reactor;Date;Recipe;Lot;Pocket;Scribe;Tool;Name;Value";
|
||||
QueryFilter = "LEI RS Average value";
|
||||
Title = "Lehighton";
|
||||
HTML = @"GaN Epi Data\13 - lehighton.html";
|
||||
break;
|
||||
case Test.VerificationLehighton:
|
||||
EquipmentType = EquipmentType.MET08NDFRESIMAP151C_Verification;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "___";
|
||||
Header = "Reactor;Date;Recipe;Lot;Pocket;Scribe;Tool;Name;Value";
|
||||
QueryFilter = "___";
|
||||
Title = "LEI Weekly Verification 2 Ohm cm";
|
||||
HTML = @"Metrology\14 - lei_verif_weekly.html.html";
|
||||
break;
|
||||
case Test.Microscope:
|
||||
EquipmentType = EquipmentType.MET08MESMICROSCOPE;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = string.Empty;
|
||||
Header = string.Empty;
|
||||
QueryFilter = "Microscope Center 5x";
|
||||
Title = "Total Microscope Defects";
|
||||
HTML = string.Empty;
|
||||
break;
|
||||
case Test.RPMXY:
|
||||
EquipmentType = EquipmentType.MET08PLMAPRPM;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "RPM_Data";
|
||||
Header = "Lot;Date;Recipe;Reactor;Scribe;Pocket;Tool;Name;Value";
|
||||
QueryFilter = "Barrier_Composition_RPM_XY";
|
||||
Title = "RPM XY Data ***&*** View Data";
|
||||
HTML = @"GaN Epi Data\09 - rpm --- 08 - photoluminescence.html";
|
||||
break;
|
||||
case Test.RPMAverage:
|
||||
EquipmentType = EquipmentType.MET08PLMAPRPM;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "RPMdata-short";
|
||||
Header = "fProductId;fDate;average;stdDev;fRecipeName;Reactor;g4Scribe;Pocket Number;Tool ID;Recipe From Rpm File";
|
||||
QueryFilter = "Epi Thickness Mean";
|
||||
Title = "RPM Average Data";
|
||||
HTML = @"GaN Epi Data\09 - rpm.html";
|
||||
break;
|
||||
case Test.RPMPLRatio:
|
||||
EquipmentType = EquipmentType.MET08PLMAPRPM;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "PHOTOLUMINESCENCE_data-short";
|
||||
Header = "fProductId;fDate;g4Scribe;fRecipeName;bandEdge_nm;bandEdge_V;yellowBand_Pmw;yellowBand_nm;yellowBand_V;Reactor;Pocket Number;Tool ID";
|
||||
QueryFilter = "PL Ratio";
|
||||
Title = "Photoluminescence: PL Ratio";
|
||||
HTML = @"GaN Epi Data\08 - photoluminescence.html";
|
||||
break;
|
||||
case Test.DailyRPMXY:
|
||||
EquipmentType = EquipmentType.MET08PLMAPRPM_Daily;
|
||||
eventName = EventName.FileReadDaily;
|
||||
FileNameWithoutExtension = "RPM_Data";
|
||||
Header = "Lot;Date;Recipe;Reactor;Scribe;Pocket;Tool;Name;Value";
|
||||
QueryFilter = "Barrier_Composition_RPM_XY";
|
||||
Title = "";
|
||||
HTML = @"Metrology\?";
|
||||
break;
|
||||
case Test.DailyRPMAverage:
|
||||
EquipmentType = EquipmentType.MET08PLMAPRPM_Daily;
|
||||
eventName = EventName.FileReadDaily;
|
||||
FileNameWithoutExtension = "RPMdata-short";
|
||||
Header = "fProductId;fDate;average;stdDev;fRecipeName;Reactor;g4Scribe;Pocket Number;Tool ID;Recipe From Rpm File";
|
||||
QueryFilter = "Epi Thickness Mean";
|
||||
Title = "";
|
||||
HTML = @"Metrology\?";
|
||||
break;
|
||||
case Test.DailyRPMPLRatio:
|
||||
EquipmentType = EquipmentType.MET08PLMAPRPM_Daily;
|
||||
eventName = EventName.FileReadDaily;
|
||||
FileNameWithoutExtension = "PHOTOLUMINESCENCE_data-short";
|
||||
Header = "fProductId;fDate;g4Scribe;fRecipeName;bandEdge_nm;bandEdge_V;yellowBand_Pmw;yellowBand_nm;yellowBand_V;Reactor;Pocket Number;Tool ID";
|
||||
QueryFilter = "PL Ratio";
|
||||
Title = "RPM Daily Verification";
|
||||
HTML = @"Metrology\17 - rpm_verif_daily.html";
|
||||
break;
|
||||
case Test.VerificationRPM:
|
||||
EquipmentType = EquipmentType.MET08PLMAPRPM_Verification;
|
||||
eventName = EventName.FileReadVerification;
|
||||
FileNameWithoutExtension = "PhotoLuminescence_Ver";
|
||||
Header = "Part;Process;Date;Test;Value";
|
||||
QueryFilter = "PL Edge Wavelength";
|
||||
Title = "PL Daily Verification - [PL Edge Wavelength]";
|
||||
HTML = @"Metrology\18 - photoluminescence_verif_daily.html";
|
||||
break;
|
||||
case Test.Photoreflectance:
|
||||
EquipmentType = EquipmentType.MET08PRFUSB4000;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "photoreflect_iqs_01";
|
||||
Header = "Lot;Date;Part;Reactor;Scribe;Pocket;Tool;Point;WaferPosition_PR;PR_Peak";
|
||||
QueryFilter = "PR Barrier Composition";
|
||||
Title = "Photoreflectance 6 in, Photoreflectance 8 in";
|
||||
HTML = @"GaN Epi Data\07 - photoreflectance.html";
|
||||
break;
|
||||
case Test.UV:
|
||||
EquipmentType = EquipmentType.MET08UVH44GS100M;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "uv_iqs_01";
|
||||
Header = string.Empty;
|
||||
QueryFilter = "UV Broken";
|
||||
Title = "UV";
|
||||
HTML = @"GaN Epi Data\15 - uv 2.1.html";
|
||||
break;
|
||||
case Test.VpdIcpmsAnalyte:
|
||||
EquipmentType = EquipmentType.MET08VPDSUBCON;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "VPD_iqs_01";
|
||||
Header = "Reactor;RunID;RunDate;PartNumber;PocketNumber;WaferScribe;Analyte;Value";
|
||||
QueryFilter = "Mg";
|
||||
Title = "VpdIcpmsAnalyteData";
|
||||
HTML = @"";
|
||||
break;
|
||||
case Test.WarpAndBow:
|
||||
EquipmentType = EquipmentType.MET08WGEOMX203641Q;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "warp_iqs_01";
|
||||
Header = "fDate;fRecipeName;fProductId;g4Scribe;warp;bow;tool;Reactor;Pocket ID;bow_range;BowX;BowY;CenterBow";
|
||||
QueryFilter = "BowCenter";
|
||||
Title = "Warp and Bow";
|
||||
HTML = @"GaN Epi Data\14 - warp.html";
|
||||
break;
|
||||
case Test.VerificationWarpAndBow:
|
||||
EquipmentType = EquipmentType.MET08WGEOMX203641Q_Verification;
|
||||
eventName = EventName.FileReadVerification;
|
||||
FileNameWithoutExtension = "warp_ver_iqs_01";
|
||||
Header = "Part;Process;Date;WaferScribe;totWarp;bow";
|
||||
QueryFilter = "Bow Calibration";
|
||||
Title = "6 Inch Warp/Bow Daily Verification, 8 Inch Warp/Bow Daily Verification";
|
||||
HTML = @"Metrology\19 - warp_cal_daily.html";
|
||||
break;
|
||||
case Test.XRDXY:
|
||||
EquipmentType = EquipmentType.MET08XRDXPERTPROMRDXL;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "xrd_iqs_NEW_01";
|
||||
Header = "Reactor;fDate;fRecipeName;Lot;pocketNumber;g4Scribe;ToolID;Name;Value;Group";
|
||||
QueryFilter = "SL Period";
|
||||
Title = "XRD XY Raw Data Viewer";
|
||||
HTML = @"GaN Epi Data\11 - xrd.html";
|
||||
break;
|
||||
case Test.XRDWeightedAverage:
|
||||
EquipmentType = EquipmentType.MET08XRDXPERTPROMRDXL;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "xrd_iqs_NEW_01_WtAVG";
|
||||
Header = "Reactor;fDate;fRecipeName;Lot;pocketNumber;g4Scribe;Name;Value;Group";
|
||||
//QueryFilter = "Al% Barrier WTAVG";
|
||||
QueryFilter = "SL Period WTAVG";
|
||||
Title = "XRD Weighted Average Data";
|
||||
HTML = @"GaN Epi Data\11 - xrd.html";
|
||||
break;
|
||||
case Test.MonthlyXRD:
|
||||
EquipmentType = EquipmentType.MET08XRDXPERTPROMRDXL_Monthly;
|
||||
eventName = EventName.FileReadMonthly;
|
||||
FileNameWithoutExtension = "xrd_monthly_ver_iqs_01";
|
||||
Header = "Part;Process;Date;TestName;Value";
|
||||
QueryFilter = "XRD 2-Theta Position";
|
||||
Title = "XRD Monthly Verification";
|
||||
HTML = @"Metrology\03 - xrd_verif_monthly.html";
|
||||
break;
|
||||
case Test.WeeklyXRD:
|
||||
EquipmentType = EquipmentType.MET08XRDXPERTPROMRDXL_Weekly;
|
||||
eventName = EventName.FileReadWeekly;
|
||||
FileNameWithoutExtension = "xrd_weekly_ver_iqs_01";
|
||||
Header = "Part;Process;Lot;Date;TestName;Value";
|
||||
QueryFilter = "XRD Weekly AL% Center";
|
||||
Title = "XRD Weekly Verification";
|
||||
HTML = @"Metrology\12 - xrd_verif_weekly.html";
|
||||
break;
|
||||
case Test.JVXRD:
|
||||
EquipmentType = EquipmentType.METBRXRAYJV7300L;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "xrd_iqs_NEW_01";
|
||||
Header = "Reactor;fDate;fRecipeName;Lot;pocketNumber;g4Scribe;ToolID;Name;Value;Group";
|
||||
QueryFilter = "SL Period";
|
||||
Title = "XRD XY Raw Data Viewer";
|
||||
HTML = @"GaN Epi Data\11 - xrd.html";
|
||||
break;
|
||||
default:
|
||||
throw new Exception();
|
||||
}
|
||||
FileName = string.Concat(FileNameWithoutExtension, ".txt");
|
||||
return eventName.ToString();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Concat(EquipmentType, " - (", Enum, "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
57
Adaptation/Shared/Metrology/Test.cs
Normal file
57
Adaptation/Shared/Metrology/Test.cs
Normal file
@ -0,0 +1,57 @@
|
||||
namespace Adaptation.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
|
||||
}
|
||||
|
||||
}
|
24
Adaptation/Shared/Metrology/WS.Attachment.cs
Normal file
24
Adaptation/Shared/Metrology/WS.Attachment.cs
Normal file
@ -0,0 +1,24 @@
|
||||
namespace Adaptation.Shared.Metrology
|
||||
{
|
||||
|
||||
public partial class WS
|
||||
{
|
||||
public class Attachment
|
||||
{
|
||||
|
||||
public string UniqueId { get; set; }
|
||||
public string DestinationFileName { get; set; }
|
||||
public string SourceFileName { get; set; }
|
||||
|
||||
public Attachment(string uniqueId, string destinationFileName, string sourceFileName)
|
||||
{
|
||||
UniqueId = uniqueId;
|
||||
DestinationFileName = destinationFileName;
|
||||
SourceFileName = sourceFileName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
33
Adaptation/Shared/Metrology/WS.Results.cs
Normal file
33
Adaptation/Shared/Metrology/WS.Results.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Adaptation.Shared.Metrology
|
||||
{
|
||||
|
||||
public partial class WS
|
||||
{
|
||||
// this class represents the response from the Inbound API endpoint
|
||||
public class Results
|
||||
{
|
||||
// true or false if data was written to the database
|
||||
public bool Success { get; set; }
|
||||
|
||||
// if true, contains ID of the Header record in the database
|
||||
public long HeaderID { get; set; }
|
||||
|
||||
// if false, this collection will contain a list of errors
|
||||
public List<string> Errors { get; set; }
|
||||
|
||||
// this collection will contain a list of warnings, they will not prevent data from being saved
|
||||
public List<string> Warnings { get; set; }
|
||||
|
||||
// this is just a helper function to make displaying the results easier
|
||||
public override string ToString()
|
||||
{
|
||||
return JsonSerializer.Serialize(this, GetType());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
127
Adaptation/Shared/Metrology/WS.cs
Normal file
127
Adaptation/Shared/Metrology/WS.cs
Normal file
@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Adaptation.Shared.Metrology
|
||||
{
|
||||
|
||||
public partial class WS
|
||||
{
|
||||
|
||||
public static Tuple<string, Results> SendData(string url, object payload, int timeoutSeconds = 120)
|
||||
{
|
||||
Results results = new Results();
|
||||
string resultsJson = string.Empty;
|
||||
try
|
||||
{
|
||||
string json = JsonSerializer.Serialize(payload, payload.GetType());
|
||||
if (string.IsNullOrEmpty(url) || !url.Contains(":") || !url.Contains("."))
|
||||
throw new Exception("Invalid URL");
|
||||
using (HttpClient httpClient = new HttpClient())
|
||||
{
|
||||
httpClient.Timeout = new TimeSpan(0, 0, 0, timeoutSeconds, 0);
|
||||
HttpRequestMessage httpRequestMessage = new HttpRequestMessage
|
||||
{
|
||||
RequestUri = new Uri(url),
|
||||
Method = HttpMethod.Post,
|
||||
Content = new StringContent(json, Encoding.UTF8, "application/json")
|
||||
};
|
||||
HttpResponseMessage httpResponseMessage = httpClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead).Result;
|
||||
resultsJson = httpResponseMessage.Content.ReadAsStringAsync().Result;
|
||||
results = JsonSerializer.Deserialize<Results>(resultsJson);
|
||||
}
|
||||
if (!results.Success)
|
||||
results.Errors.Add(results.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Exception exception = e;
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
while (!(exception is null))
|
||||
{
|
||||
stringBuilder.AppendLine(exception.Message);
|
||||
exception = exception.InnerException;
|
||||
}
|
||||
if (results.Errors is null)
|
||||
results.Errors = new List<string>();
|
||||
results.Errors.Add(stringBuilder.ToString());
|
||||
}
|
||||
return new Tuple<string, Results>(resultsJson, results);
|
||||
}
|
||||
|
||||
// this method is a wrapper for attaching a file to either a header or data record
|
||||
// URL is the same URL used for SendData, ex: http://localhost/api/inbound/CDE
|
||||
// attachToHeaderId is the ID returned by SendData
|
||||
// attachToDataUniqueId is the string unique ID for the data record, aka the Title of the Sharepoint list entry
|
||||
// fileContents is a byte array with the contents of the file
|
||||
// fileName is which attachment this is, image.pdf, data.pdf, data.txt, header.pdf, etc
|
||||
// timeoutSeconds is configured as the request timeout
|
||||
// this method will either succeed or throw an exception
|
||||
// also, this has been made synchronous
|
||||
public static void AttachFile(string url, long attachToHeaderId, string attachToDataUniqueId, byte[] fileContents, string fileName, int timeoutSeconds = 60)
|
||||
{
|
||||
using (HttpClient httpClient = new HttpClient())
|
||||
{
|
||||
string requestUrl = url + "/attachment?headerid=" + attachToHeaderId.ToString();
|
||||
if (!string.IsNullOrWhiteSpace(attachToDataUniqueId))
|
||||
{
|
||||
requestUrl += "&datauniqueid=";
|
||||
requestUrl += System.Net.WebUtility.UrlEncode(attachToDataUniqueId);
|
||||
}
|
||||
requestUrl += "&filename="; // this is just so the web server log shows the filename
|
||||
requestUrl += System.Net.WebUtility.UrlEncode(fileName);
|
||||
|
||||
httpClient.Timeout = new TimeSpan(0, 0, 0, timeoutSeconds, 0);
|
||||
|
||||
MultipartFormDataContent multipartFormDataContent = new MultipartFormDataContent();
|
||||
ByteArrayContent byteArrayContent = new ByteArrayContent(fileContents);
|
||||
byteArrayContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
|
||||
|
||||
multipartFormDataContent.Add(byteArrayContent, "attachment", fileName);
|
||||
|
||||
HttpResponseMessage httpResponseMessage = httpClient.PostAsync(requestUrl, multipartFormDataContent).Result;
|
||||
|
||||
if (httpResponseMessage.IsSuccessStatusCode)
|
||||
return;
|
||||
|
||||
string resultBody = httpResponseMessage.Content.ReadAsStringAsync().Result;
|
||||
|
||||
throw new Exception("Attachment failed: " + resultBody);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AttachFiles(string url, long headerID, List<Attachment> headerAttachments = null, List<Attachment> dataAttachments = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!(headerAttachments is null))
|
||||
{
|
||||
foreach (Attachment attachment in headerAttachments)
|
||||
AttachFile(url, headerID, "", System.IO.File.ReadAllBytes(attachment.SourceFileName), attachment.DestinationFileName);
|
||||
}
|
||||
if (!(dataAttachments is null))
|
||||
{
|
||||
foreach (Attachment attachment in dataAttachments)
|
||||
AttachFile(url, headerID, attachment.UniqueId, System.IO.File.ReadAllBytes(attachment.SourceFileName), attachment.DestinationFileName);
|
||||
}
|
||||
//MessageBox.Show(r.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Exception exception = e;
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
while (!(exception is null))
|
||||
{
|
||||
stringBuilder.AppendLine(exception.Message);
|
||||
exception = exception.InnerException;
|
||||
}
|
||||
//MessageBox.Show(msgs.ToString(), "Exception", //MessageBoxButtons.OK, //MessageBoxIcon.Error);
|
||||
throw new Exception(stringBuilder.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user