Match TFS Changeset 303335
This commit is contained in:
16
Shared/Deposition/Test.cs
Normal file
16
Shared/Deposition/Test.cs
Normal file
@ -0,0 +1,16 @@
|
||||
namespace Shared.Deposition
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
AFMRoughness = -1,
|
||||
GRATXTCenter = 0,
|
||||
GRATXTEdge = 1,
|
||||
GRAXMLCenter = 2,
|
||||
GRAXMLEdgeN = 3,
|
||||
Health = 4,
|
||||
Temps = 5,
|
||||
ToolTime = 6
|
||||
}
|
||||
|
||||
}
|
182
Shared/Description.cs
Normal file
182
Shared/Description.cs
Normal file
@ -0,0 +1,182 @@
|
||||
using Adaptation.Shared.Metrology;
|
||||
using Eaf.Core;
|
||||
using Eaf.EquipmentCore.Control;
|
||||
using Eaf.EquipmentCore.DataCollection.Reporting;
|
||||
using Eaf.EquipmentCore.SelfDescription.ElementDescription;
|
||||
using Eaf.EquipmentCore.SelfDescription.ParameterTypes;
|
||||
using Ifx.Eaf.EquipmentConnector.File.SelfDescription;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Shared
|
||||
{
|
||||
|
||||
public class Description
|
||||
{
|
||||
|
||||
public enum RowColumn
|
||||
{
|
||||
Test = 1000,
|
||||
Count,
|
||||
Index
|
||||
}
|
||||
|
||||
public enum LogisticsColumn
|
||||
{
|
||||
EventName = 2000,
|
||||
NullData,
|
||||
JobID,
|
||||
Sequence,
|
||||
MesEntity,
|
||||
ReportFullPath,
|
||||
ProcessJobID,
|
||||
MID
|
||||
}
|
||||
|
||||
public enum Param
|
||||
{
|
||||
String = 0,
|
||||
Integer = 2,
|
||||
Double = 3,
|
||||
Boolean = 4,
|
||||
StructuredType = 5
|
||||
}
|
||||
|
||||
internal const string FileFound = "FileFound";
|
||||
|
||||
|
||||
public List<EquipmentParameter> EquipmentParameters { get; private set; }
|
||||
public List<ParameterTypeDefinition> ParameterTypeDefinitions { get; private set; }
|
||||
|
||||
private readonly bool _UseCyclical;
|
||||
private readonly List<string> _HeaderNames;
|
||||
private readonly Dictionary<string, int> _KeyIndexPairs;
|
||||
private readonly ParameterTypeDefinition _StructuredType;
|
||||
private readonly FileConnectorParameterTypeDefinitionProvider _FileConnectorParameterTypeDefinitionProvider;
|
||||
|
||||
public Description(ILogic logic, ConfigDataBase configDataBase, IEquipmentControl equipmentControl)
|
||||
{
|
||||
_KeyIndexPairs = new Dictionary<string, int>();
|
||||
_HeaderNames = configDataBase.GetHeaderNames(logic);
|
||||
_UseCyclical = configDataBase.UseCyclicalForDescription;
|
||||
_StructuredType = new StructuredType(nameof(StructuredType), string.Empty, new List<Field>());
|
||||
_FileConnectorParameterTypeDefinitionProvider = new FileConnectorParameterTypeDefinitionProvider();
|
||||
EquipmentParameters = new List<EquipmentParameter>();
|
||||
ParameterTypeDefinitions = new List<ParameterTypeDefinition> { _StructuredType };
|
||||
Dictionary<string, List<Tuple<Enum, string, string, object>>> keyValuePairsCollection = configDataBase.GetParameterInfo(logic, allowNull: false);
|
||||
List<ParameterValue> results = GetParameterValues(equipmentControl, keyValuePairsCollection);
|
||||
}
|
||||
|
||||
private List<ParameterValue> GetParameterValues(IEquipmentControl equipmentControl, Dictionary<string, List<Tuple<Enum, string, string, object>>> keyValuePairsCollection)
|
||||
{
|
||||
List<ParameterValue> results = new List<ParameterValue>();
|
||||
Enum param;
|
||||
object value;
|
||||
Enum[] @params;
|
||||
string description;
|
||||
List<object[]> list;
|
||||
EquipmentParameter equipmentParameter;
|
||||
ParameterTypeDefinition parameterTypeDefinition;
|
||||
bool addToEquipmentParameters = !EquipmentParameters.Any();
|
||||
foreach (KeyValuePair<string, List<Tuple<Enum, string, string, object>>> keyValuePair in keyValuePairsCollection)
|
||||
{
|
||||
if (!addToEquipmentParameters && !_KeyIndexPairs.ContainsKey(keyValuePair.Key))
|
||||
continue;
|
||||
@params = (from l in keyValuePair.Value select l.Item1).Distinct().ToArray();
|
||||
if (@params.Length != 1)
|
||||
throw new Exception();
|
||||
if (keyValuePair.Value[0].Item2 != keyValuePair.Key)
|
||||
throw new Exception();
|
||||
param = @params[0];
|
||||
if (!addToEquipmentParameters)
|
||||
equipmentParameter = EquipmentParameters[_KeyIndexPairs[keyValuePair.Key]];
|
||||
else
|
||||
{
|
||||
description = keyValuePair.Value[0].Item3;
|
||||
_KeyIndexPairs.Add(keyValuePair.Key, EquipmentParameters.Count());
|
||||
if (param is Param.StructuredType || (_UseCyclical && !_HeaderNames.Contains(keyValuePair.Key)))
|
||||
parameterTypeDefinition = _StructuredType;
|
||||
else
|
||||
parameterTypeDefinition = _FileConnectorParameterTypeDefinitionProvider.GetParameterTypeDefinition(param.ToString());
|
||||
equipmentParameter = new EquipmentParameter(keyValuePair.Key, parameterTypeDefinition, description);
|
||||
EquipmentParameters.Add(equipmentParameter);
|
||||
}
|
||||
if (!_UseCyclical || _HeaderNames.Contains(keyValuePair.Key))
|
||||
value = keyValuePair.Value[0].Item4;
|
||||
else
|
||||
{
|
||||
list = new List<object[]>();
|
||||
for (int i = 0; i < keyValuePair.Value.Count; i++)
|
||||
list.Add(new object[] { i, keyValuePair.Value[i].Item4 });
|
||||
value = list;
|
||||
}
|
||||
if (equipmentControl is null || !(param is Param.StructuredType))
|
||||
results.Add(new ParameterValue(equipmentParameter, value, DateTime.Now));
|
||||
else
|
||||
results.Add(equipmentControl.DataCollection.CreateParameterValue(equipmentParameter, value));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public List<ParameterValue> GetParameterValues(ILogic logic, IEquipmentControl equipmentControl, JsonElement jsonElement, int? i = null, Dictionary<string, object> keyValuePairs = null)
|
||||
{
|
||||
List<ParameterValue> results = new List<ParameterValue>();
|
||||
if (_UseCyclical && (i is null || i.Value > 0))
|
||||
throw new Exception();
|
||||
if (jsonElement.ValueKind != JsonValueKind.Array)
|
||||
throw new Exception();
|
||||
Enum param;
|
||||
Tuple<Enum, string, string, object> tuple;
|
||||
JsonElement[] jsonElements = jsonElement.EnumerateArray().ToArray();
|
||||
Dictionary<string, List<Tuple<Enum, string, string, object>>> keyValuePairsCollection = new Dictionary<string, List<Tuple<Enum, string, string, object>>>();
|
||||
for (int r = i.Value; r < jsonElements.Length; r++)
|
||||
{
|
||||
foreach (JsonProperty jsonProperty in jsonElement[r].EnumerateObject())
|
||||
{
|
||||
if (jsonProperty.Value.ValueKind == JsonValueKind.Object || jsonProperty.Value.ValueKind == JsonValueKind.Array)
|
||||
{
|
||||
param = Param.StructuredType;
|
||||
//jValue = jObject.Value<JValue>("Item1");
|
||||
throw new NotImplementedException("Item1");
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (jsonProperty.Value.ValueKind)
|
||||
{
|
||||
case JsonValueKind.String: param = Param.String; break;
|
||||
case JsonValueKind.Number: param = Param.Double; break;
|
||||
case JsonValueKind.True:
|
||||
case JsonValueKind.False: param = Param.Boolean; break;
|
||||
case JsonValueKind.Null: param = Param.String; break;
|
||||
default: param = Param.StructuredType; break;
|
||||
}
|
||||
}
|
||||
tuple = new Tuple<Enum, string, string, object>(param, jsonProperty.Name, string.Empty, jsonProperty.Value.ToString());
|
||||
if (!keyValuePairsCollection.ContainsKey(jsonProperty.Name))
|
||||
keyValuePairsCollection.Add(jsonProperty.Name, new List<Tuple<Enum, string, string, object>>());
|
||||
keyValuePairsCollection[jsonProperty.Name].Add(tuple);
|
||||
}
|
||||
if (!_UseCyclical)
|
||||
break;
|
||||
}
|
||||
results = GetParameterValues(equipmentControl, keyValuePairsCollection);
|
||||
return results;
|
||||
}
|
||||
|
||||
public static string GetCellName()
|
||||
{
|
||||
string result;
|
||||
if (Backbone.Instance?.CellName is null)
|
||||
result = string.Empty;
|
||||
else
|
||||
result = Backbone.Instance.CellName;
|
||||
if (result.Contains("-IO"))
|
||||
result = result.Replace("-IO", string.Empty);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
53
Shared/EquipmentConnection.cs
Normal file
53
Shared/EquipmentConnection.cs
Normal file
@ -0,0 +1,53 @@
|
||||
namespace Shared
|
||||
{
|
||||
|
||||
public enum EquipmentConnection
|
||||
{
|
||||
FileEquipment,
|
||||
SemiEquipment,
|
||||
//
|
||||
DEP08EGANAIXG5,
|
||||
FileReaderGRATXT,
|
||||
FileReaderGRATXTDiff,
|
||||
FileReaderGRAXML,
|
||||
FileReaderToolTime,
|
||||
FileReaderTemps,
|
||||
FileReaderHealth,
|
||||
//
|
||||
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,
|
||||
MET08PRFUSB4000,
|
||||
MET08UVH44GS100M,
|
||||
MET08VPDSUBCON,
|
||||
MET08WGEOMX203641Q,
|
||||
MET08WGEOMX203641Q_Verification,
|
||||
MET08XRDXPERTPROMRDXL,
|
||||
MET08XRDXPERTPROMRDXL_Monthly,
|
||||
MET08XRDXPERTPROMRDXL_Weekly,
|
||||
METBRXRAYJV7300L
|
||||
}
|
||||
|
||||
}
|
178
Shared/ExtendedParameter.cs
Normal file
178
Shared/ExtendedParameter.cs
Normal file
@ -0,0 +1,178 @@
|
||||
using Shared.Metrology;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace 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(EquipmentConnection equipmentConnection, string queryFilter, Dictionary<Enum, string> allColumnCollection)
|
||||
{
|
||||
Column key;
|
||||
EAFReference = equipmentConnection.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];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
35
Shared/FilePathGenerator.cs
Normal file
35
Shared/FilePathGenerator.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using Ifx.Eaf.EquipmentConnector.File.Component;
|
||||
using Ifx.Eaf.EquipmentConnector.File.Configuration;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Shared
|
||||
{
|
||||
|
||||
public class FilePathGenerator : Ifx.Eaf.EquipmentConnector.File.Component.FilePathGenerator
|
||||
{
|
||||
|
||||
public FileConnectorConfiguration FileConnectorConfiguration { get; private set; }
|
||||
|
||||
public FilePathGenerator(FileConnectorConfiguration config, Dictionary<string, string> customPattern = null) : base(config, customPattern)
|
||||
{
|
||||
FileConnectorConfiguration = config;
|
||||
}
|
||||
|
||||
public FilePathGenerator(FileConnectorConfiguration config, File file, bool isErrorFile = false, Dictionary<string, string> customPattern = null) : base(config, file, isErrorFile, customPattern)
|
||||
{
|
||||
FileConnectorConfiguration = config;
|
||||
}
|
||||
|
||||
public FilePathGenerator(FileConnectorConfiguration config, string sourceFilePath, bool isErrorFile = false, Dictionary<string, string> customPattern = null) : base(config, sourceFilePath, isErrorFile, customPattern)
|
||||
{
|
||||
FileConnectorConfiguration = config;
|
||||
}
|
||||
|
||||
public string GetSubFolderPath()
|
||||
{
|
||||
return SubFolderPath;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
67
Shared/FilePathGeneratorInfo.cs
Normal file
67
Shared/FilePathGeneratorInfo.cs
Normal file
@ -0,0 +1,67 @@
|
||||
using System.IO;
|
||||
|
||||
namespace Shared
|
||||
{
|
||||
|
||||
public class FilePathGeneratorInfo
|
||||
{
|
||||
|
||||
public string To { get; protected set; }
|
||||
public string From { get; protected set; }
|
||||
public bool IsErrorFile { get; protected set; }
|
||||
public string SubFolderPath { get; protected set; }
|
||||
public string FirstDirectory { get; protected set; }
|
||||
public string ReportFullPath { get; protected set; }
|
||||
public string ResolvedFileLocation { get; protected set; }
|
||||
|
||||
public FilePathGeneratorInfo(object originalFilePathGenerator, string reportFullPath, bool isErrorFile, System.Collections.Generic.Dictionary<string, string> fileParameter)
|
||||
{
|
||||
ReportFullPath = reportFullPath;
|
||||
IsErrorFile = isErrorFile;
|
||||
if (originalFilePathGenerator is null || !(originalFilePathGenerator is FilePathGenerator))
|
||||
{
|
||||
FirstDirectory = string.Empty;
|
||||
ResolvedFileLocation = string.Empty;
|
||||
To = string.Empty;
|
||||
From = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
string directorySeparatorChar = Path.DirectorySeparatorChar.ToString();
|
||||
FilePathGenerator original = (FilePathGenerator)originalFilePathGenerator;
|
||||
FilePathGenerator filePathGenerator = new FilePathGenerator(original.FileConnectorConfiguration, reportFullPath, isErrorFile);
|
||||
SubFolderPath = filePathGenerator.GetSubFolderPath();
|
||||
if (string.IsNullOrEmpty(SubFolderPath))
|
||||
FirstDirectory = SubFolderPath;
|
||||
else
|
||||
FirstDirectory = SubFolderPath.Split(Path.DirectorySeparatorChar)[0];
|
||||
ResolvedFileLocation = filePathGenerator.GetTargetFolder();
|
||||
if (string.IsNullOrEmpty(ResolvedFileLocation) && string.IsNullOrEmpty(SubFolderPath))
|
||||
To = string.Empty;
|
||||
else if (string.IsNullOrEmpty(SubFolderPath))
|
||||
To = ResolvedFileLocation;
|
||||
else
|
||||
To = string.Concat(ResolvedFileLocation.Replace(SubFolderPath, string.Empty), Path.DirectorySeparatorChar, FirstDirectory);
|
||||
#if (true)
|
||||
if (string.IsNullOrEmpty(original.FileConnectorConfiguration.DefaultPlaceHolderValue))
|
||||
original.FileConnectorConfiguration.DefaultPlaceHolderValue = "NA";
|
||||
if (!(fileParameter is null) && fileParameter.Count == 1 && To.Contains(original.FileConnectorConfiguration.DefaultPlaceHolderValue))
|
||||
{
|
||||
foreach (var keyValuePair in fileParameter)
|
||||
To = To.Replace(string.Concat(original.FileConnectorConfiguration.DefaultPlaceHolderValue), keyValuePair.Value);
|
||||
}
|
||||
#endif
|
||||
if (original.FileConnectorConfiguration.SourceFileLocation.EndsWith(directorySeparatorChar))
|
||||
From = string.Concat(original.FileConnectorConfiguration.SourceFileLocation, FirstDirectory);
|
||||
else
|
||||
From = string.Concat(original.FileConnectorConfiguration.SourceFileLocation, Path.DirectorySeparatorChar, FirstDirectory);
|
||||
if (From.EndsWith(directorySeparatorChar) && !To.EndsWith(directorySeparatorChar))
|
||||
To = string.Concat(To, Path.DirectorySeparatorChar);
|
||||
else if (To.EndsWith(directorySeparatorChar) && !From.EndsWith(directorySeparatorChar))
|
||||
To = To.Remove(To.Length - 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
26
Shared/IProcessDataDescription.cs
Normal file
26
Shared/IProcessDataDescription.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using Shared.Metrology;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Shared
|
||||
{
|
||||
|
||||
public interface IProcessDataDescription
|
||||
{
|
||||
|
||||
int Test { get; set; }
|
||||
int Count { get; set; }
|
||||
int Index { get; set; }
|
||||
IProcessDataDescription GetDefault(ILogic logic, ConfigDataBase configDataBase);
|
||||
IProcessDataDescription GetDisplayNames(ILogic logic, ConfigDataBase configDataBase);
|
||||
List<IProcessDataDescription> GetDescription(ILogic logic, ConfigDataBase configDataBase, List<Test> tests, object payload);
|
||||
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();
|
||||
|
||||
}
|
||||
|
||||
}
|
22
Shared/IScopeInfo.cs
Normal file
22
Shared/IScopeInfo.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System;
|
||||
|
||||
namespace Shared
|
||||
{
|
||||
|
||||
public interface IScopeInfo
|
||||
{
|
||||
|
||||
Enum Enum { get; }
|
||||
string HTML { get; }
|
||||
string Title { get; }
|
||||
string FileName { get; }
|
||||
int TestValue { get; }
|
||||
string Header { get; }
|
||||
string QueryFilter { get; }
|
||||
string FileNameWithoutExtension { get; }
|
||||
string EquipmentElementName { get; }
|
||||
EquipmentConnection EquipmentConnection { get; }
|
||||
|
||||
}
|
||||
|
||||
}
|
243
Shared/Logistics.cs
Normal file
243
Shared/Logistics.cs
Normal file
@ -0,0 +1,243 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Shared
|
||||
{
|
||||
|
||||
public class Logistics
|
||||
{
|
||||
|
||||
public object NullData { get; private set; }
|
||||
public string JobID { get; private set; } //CellName
|
||||
public long Sequence { get; private set; } //Ticks
|
||||
public DateTime DateTimeFromSequence { get; private set; }
|
||||
public double TotalSecondsSinceLastWriteTimeFromSequence { get; private set; }
|
||||
public string MesEntity { get; private set; } //SPC
|
||||
public string ReportFullPath { get; private set; } //Extract file
|
||||
public string ProcessJobID { get; internal set; } //Reactor (duplicate but I want it in the logistics)
|
||||
public string MID { get; internal set; } //Lot & Pocket || Lot
|
||||
public List<string> Tags { get; internal set; }
|
||||
public List<string> Logistics1 { get; internal set; }
|
||||
public List<Logistics2> Logistics2 { get; internal set; }
|
||||
|
||||
public Logistics()
|
||||
{
|
||||
DateTime dateTime = DateTime.Now;
|
||||
NullData = null;
|
||||
JobID = Description.GetCellName();
|
||||
Sequence = dateTime.Ticks;
|
||||
DateTimeFromSequence = dateTime;
|
||||
TotalSecondsSinceLastWriteTimeFromSequence = (DateTime.Now - dateTime).TotalSeconds;
|
||||
MesEntity = DefaultMesEntity(dateTime);
|
||||
ReportFullPath = string.Empty;
|
||||
ProcessJobID = nameof(ProcessJobID);
|
||||
MID = nameof(MID);
|
||||
Tags = new List<string>();
|
||||
Logistics1 = new string[] { string.Concat("LOGISTICS_1", '\t', "A_JOBID=", JobID, ";A_MES_ENTITY=", MesEntity, ";") }.ToList();
|
||||
Logistics2 = new List<Logistics2>();
|
||||
}
|
||||
|
||||
public Logistics(object nullData, Dictionary<string, string> cellNames, Dictionary<string, string> mesEntities, FileInfo fileInfo, bool useSplitForMID, int? fileInfoLength = null)
|
||||
{
|
||||
NullData = nullData;
|
||||
string mesEntity = string.Empty;
|
||||
string jobID = Description.GetCellName();
|
||||
DateTime dateTime = fileInfo.LastWriteTime;
|
||||
if (fileInfoLength.HasValue && fileInfo.Length < fileInfoLength.Value)
|
||||
dateTime = dateTime.AddTicks(-1);
|
||||
if (string.IsNullOrEmpty(jobID))
|
||||
{
|
||||
if (cellNames.Count == 1)
|
||||
jobID = cellNames.ElementAt(0).Key;
|
||||
else
|
||||
{
|
||||
string reportFullPathLower = fileInfo.FullName.ToLower();
|
||||
foreach (var element in cellNames)
|
||||
{
|
||||
if (reportFullPathLower.Contains(element.Key) || reportFullPathLower.Contains(element.Value))
|
||||
{
|
||||
jobID = element.Key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (string.IsNullOrEmpty(jobID))
|
||||
throw new Exception();
|
||||
if (mesEntities.ContainsKey(jobID))
|
||||
mesEntity = mesEntities[jobID];
|
||||
else if (mesEntities.Count == 1)
|
||||
mesEntity = mesEntities.ElementAt(0).Value;
|
||||
//
|
||||
if (string.IsNullOrEmpty(mesEntity))
|
||||
throw new Exception();
|
||||
JobID = jobID;
|
||||
Sequence = dateTime.Ticks;
|
||||
DateTimeFromSequence = dateTime;
|
||||
TotalSecondsSinceLastWriteTimeFromSequence = (DateTime.Now - dateTime).TotalSeconds;
|
||||
MesEntity = mesEntity;
|
||||
ReportFullPath = fileInfo.FullName;
|
||||
ProcessJobID = nameof(ProcessJobID);
|
||||
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
|
||||
if (useSplitForMID)
|
||||
{
|
||||
if (fileNameWithoutExtension.IndexOf(".") > -1)
|
||||
fileNameWithoutExtension = fileNameWithoutExtension.Split('.')[0].Trim();
|
||||
if (fileNameWithoutExtension.IndexOf("_") > -1)
|
||||
fileNameWithoutExtension = fileNameWithoutExtension.Split('_')[0].Trim();
|
||||
if (fileNameWithoutExtension.IndexOf("-") > -1)
|
||||
fileNameWithoutExtension = fileNameWithoutExtension.Split('-')[0].Trim();
|
||||
}
|
||||
MID = string.Concat(fileNameWithoutExtension.Substring(0, 1).ToUpper(), fileNameWithoutExtension.Substring(1).ToLower());
|
||||
Tags = new List<string>();
|
||||
Logistics1 = new string[] { string.Concat("LOGISTICS_1", '\t', "A_JOBID=", JobID, ";A_MES_ENTITY=", MesEntity, ";") }.ToList();
|
||||
Logistics2 = new List<Logistics2>();
|
||||
}
|
||||
|
||||
public Logistics(string reportFullPath, string logistics)
|
||||
{
|
||||
string key;
|
||||
DateTime dateTime;
|
||||
string[] segments;
|
||||
Logistics1 = logistics.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
if (!Logistics1.Any() || !Logistics1[0].StartsWith("LOGISTICS_1"))
|
||||
{
|
||||
NullData = null;
|
||||
JobID = "null";
|
||||
dateTime = new FileInfo(reportFullPath).LastWriteTime;
|
||||
Sequence = dateTime.Ticks;
|
||||
DateTimeFromSequence = dateTime;
|
||||
TotalSecondsSinceLastWriteTimeFromSequence = (DateTime.Now - dateTime).TotalSeconds;
|
||||
MesEntity = DefaultMesEntity(dateTime);
|
||||
ReportFullPath = reportFullPath;
|
||||
ProcessJobID = "R##";
|
||||
MID = "null";
|
||||
Tags = new List<string>();
|
||||
Logistics1 = new string[] { string.Concat("LOGISTICS_1", '\t', "A_JOBID=", JobID, ";A_MES_ENTITY=", MesEntity, ";") }.ToList();
|
||||
Logistics2 = new List<Logistics2>();
|
||||
}
|
||||
else
|
||||
{
|
||||
string logistics1Line1 = Logistics1[0];
|
||||
key = "NULL_DATA=";
|
||||
if (!logistics1Line1.Contains(key))
|
||||
NullData = null;
|
||||
else
|
||||
{
|
||||
segments = logistics1Line1.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
|
||||
NullData = segments[1].Split(';')[0];
|
||||
}
|
||||
key = "JOBID=";
|
||||
if (!logistics1Line1.Contains(key))
|
||||
JobID = "null";
|
||||
else
|
||||
{
|
||||
segments = logistics1Line1.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
|
||||
JobID = segments[1].Split(';')[0];
|
||||
}
|
||||
key = "SEQUENCE=";
|
||||
if (!logistics1Line1.Contains(key))
|
||||
dateTime = new FileInfo(reportFullPath).LastWriteTime;
|
||||
else
|
||||
{
|
||||
segments = logistics1Line1.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (!long.TryParse(segments[1].Split(';')[0], 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 >= 0; i--)
|
||||
{
|
||||
if (Logistics1[i].StartsWith("LOGISTICS_2"))
|
||||
Logistics1.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
public Logistics ShallowCopy()
|
||||
{
|
||||
return (Logistics)this.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
Shared/Logistics2.cs
Normal file
80
Shared/Logistics2.cs
Normal file
@ -0,0 +1,80 @@
|
||||
using System;
|
||||
|
||||
namespace Shared
|
||||
{
|
||||
public class Logistics2
|
||||
{
|
||||
|
||||
public string MID { get; private set; }
|
||||
public string RunNumber { get; private set; }
|
||||
public string SatelliteGroup { get; private set; }
|
||||
public string PartNumber { get; private set; }
|
||||
public string PocketNumber { get; private set; }
|
||||
public string WaferLot { get; private set; }
|
||||
public string Recipe { get; private set; }
|
||||
|
||||
public Logistics2(string logistics2)
|
||||
{
|
||||
string key;
|
||||
string[] segments;
|
||||
key = "JOBID=";
|
||||
if (!logistics2.Contains(key))
|
||||
MID = "null";
|
||||
else
|
||||
{
|
||||
segments = logistics2.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
|
||||
MID = segments[1].Split(';')[0];
|
||||
}
|
||||
key = "MID=";
|
||||
if (!logistics2.Contains(key))
|
||||
RunNumber = "null";
|
||||
else
|
||||
{
|
||||
segments = logistics2.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
|
||||
RunNumber = segments[1].Split(';')[0];
|
||||
}
|
||||
key = "INFO=";
|
||||
if (!logistics2.Contains(key))
|
||||
SatelliteGroup = "null";
|
||||
else
|
||||
{
|
||||
segments = logistics2.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
|
||||
SatelliteGroup = segments[1].Split(';')[0];
|
||||
}
|
||||
key = "PRODUCT=";
|
||||
if (!logistics2.Contains(key))
|
||||
PartNumber = "null";
|
||||
else
|
||||
{
|
||||
segments = logistics2.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
|
||||
PartNumber = segments[1].Split(';')[0];
|
||||
}
|
||||
key = "CHAMBER=";
|
||||
if (!logistics2.Contains(key))
|
||||
PocketNumber = "null";
|
||||
else
|
||||
{
|
||||
segments = logistics2.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
|
||||
PocketNumber = segments[1].Split(';')[0];
|
||||
}
|
||||
key = "WAFER_ID=";
|
||||
if (!logistics2.Contains(key))
|
||||
WaferLot = "null";
|
||||
else
|
||||
{
|
||||
segments = logistics2.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
|
||||
WaferLot = segments[1].Split(';')[0];
|
||||
}
|
||||
key = "PPID=";
|
||||
if (!logistics2.Contains(key))
|
||||
Recipe = "null";
|
||||
else
|
||||
{
|
||||
segments = logistics2.Split(new string[] { key }, StringSplitOptions.RemoveEmptyEntries);
|
||||
Recipe = segments[1].Split(';')[0];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
803
Shared/Metrology/Column.cs
Normal file
803
Shared/Metrology/Column.cs
Normal file
@ -0,0 +1,803 @@
|
||||
using System;
|
||||
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public static class ColumnGet
|
||||
{
|
||||
|
||||
public static string GetDiplayName(this Column column)
|
||||
{
|
||||
string results;
|
||||
switch (column)
|
||||
{
|
||||
//case Column._8in_Total_Warp_Verification: results = "8in Total Warp Verification"; break;
|
||||
//case Column.AFM_Monthly_Y: results = "AFM-Monthly Y"; break;
|
||||
//case Column.AFM_Monthly: results = "AFM_Monthly"; break;
|
||||
case Column.AFM_Pit_Count: results = "AFM Pit Count"; break;
|
||||
case Column.AFM_Roughness: results = "AFM Roughness"; break;
|
||||
//case Column.Adder_Bin_1: results = "Adder Bin 1"; break;
|
||||
//case Column.Adder_Bin_2: results = "Adder Bin 2"; break;
|
||||
//case Column.Adder_Bin_3: results = "Adder Bin 3"; break;
|
||||
//case Column.Adder_Bin_4: results = "Adder Bin 4"; break;
|
||||
//case Column.Adder_Bin_5: results = "Adder Bin 5"; break;
|
||||
//case Column.Adder_Bin_6: results = "Adder Bin 6"; break;
|
||||
//case Column.Adder_Bin_9: results = "Adder Bin 9"; break;
|
||||
case Column.Al_B_B_WTAVG: results = "Al% B.B. WTAVG"; break;
|
||||
case Column.Al_B_B_: results = "Al% B.B."; break;
|
||||
case Column.Al_Barrier_WTAVG: results = "Al% Barrier WTAVG"; break;
|
||||
case Column.Al_Barrier: results = "Al% Barrier"; break;
|
||||
case Column.Al_SLS_WTAVG: results = "Al% SLS WTAVG"; break;
|
||||
case Column.Al_SLS: results = "Al% SLS"; break;
|
||||
case Column.Al_TL1_WTAVG: results = "Al% TL1 WTAVG"; break;
|
||||
case Column.Al_TL1: results = "Al% TL1"; break;
|
||||
case Column.Al_TL2_WTAVG: results = "Al% TL2 WTAVG"; break;
|
||||
//case Column.BV_Resistance: results = "BV Resistance"; break; //BV Monthly Verification
|
||||
case Column.BandEdge_V: results = "BandEdge_V"; break;
|
||||
case Column.BandEdge_V_XY: results = "BandEdge_V_XY"; break;
|
||||
case Column.BandEdge_nm: results = "BandEdge_nm"; break;
|
||||
case Column.Barrier_Composition_RPM_XY: results = "Barrier_Composition_RPM_XY"; break;
|
||||
case Column.Bow_Calibration: results = "Bow Calibration"; break;
|
||||
case Column.Bow_Range: results = "Bow Range"; break;
|
||||
case Column.Bow: results = "Bow"; break;
|
||||
case Column.BowCenter: results = "BowCenter"; break;
|
||||
case Column.BowX: results = "BowX"; break;
|
||||
case Column.BowY: results = "BowY"; break;
|
||||
case Column.Breakdown_Voltage_Edge: results = "Breakdown Voltage - Edge"; break;
|
||||
case Column.Breakdown_VoltageMiddle: results = "Breakdown Voltage - Middle"; break;
|
||||
case Column.Breakdown_Voltage: results = "Breakdown Voltage"; break;
|
||||
case Column.CV_C_at_10V: results = "CV C at -10V"; break;
|
||||
case Column.CV_Nd_Min: results = "CV Nd Min"; break;
|
||||
//case Column.Candela_Large_LPD_Quarterly: results = "Candela Large LPD Quarterly"; break;
|
||||
//case Column.Candela_Medium_LPD_Quarterly: results = "Candela Medium LPD Quarterly"; break;
|
||||
//case Column.Candela_Small_LPD_Quarterly: results = "Candela Small LPD Quarterly"; break;
|
||||
//case Column.Candela_Total_Quarterly: results = "Candela Total Quarterly"; break;
|
||||
case Column.Candela_102_83nm: results = "102-83nm"; break;
|
||||
case Column.Candela_1_1um: results = "1.1um"; break;
|
||||
case Column.Candela_496nm: results = "496nm"; break;
|
||||
case Column.Candela_600nm: results = "600nm"; break;
|
||||
case Column.Candela_8620_Small: results = "Candela 8620 Small"; break;
|
||||
case Column.Candela_Crack_Verification: results = "Crack Verification"; break;
|
||||
case Column.Candela_Cracking: results = "Candela Cracking"; break;
|
||||
case Column.Candela_Cracking_Acceptable: results = "Candela Cracking Acceptable"; break;
|
||||
case Column.Candela_Crater: results = "Candela Crater"; break;
|
||||
case Column.Candela_Crater_Verification: results = "Crater verification"; break;
|
||||
case Column.Candela_Haze: results = "Candela Haze"; break;
|
||||
case Column.Candela_LPD_Large: results = "Candela LPD Large"; break;
|
||||
case Column.Candela_LPD_Medium: results = "Candela LPD Medium"; break;
|
||||
case Column.Candela_LPD_Small: results = "Candela LPD Small"; break;
|
||||
case Column.Candela_Large_Verification: results = "Large Verification"; break;
|
||||
case Column.Candela_Medium_Verification: results = "Medium Verification"; break;
|
||||
case Column.Candela_Pits: results = "Candela Pits"; break;
|
||||
case Column.Candela_Pits_Verification: results = "Pits verification"; break;
|
||||
case Column.Candela_SPE: results = "Candela SPE"; break;
|
||||
case Column.Candela_SPE_Verification: results = "SPE verification"; break;
|
||||
case Column.Candela_Slip: results = "Candela Slip"; break;
|
||||
case Column.Candela_Small_Verification: results = "Small Verification"; break;
|
||||
case Column.Candela_Spirals: results = "Candela Spirals"; break;
|
||||
case Column.Candela_Spirals_Verification: results = "Candela Spirals Verification"; break;
|
||||
case Column.Candela_Total_Defects: results = "Candela Total Defects"; break;
|
||||
case Column.Candela_Total_PSL: results = "Candela Total PSL"; break;
|
||||
case Column.Candela__1_1um: results = ">1.1um"; break;
|
||||
//case Column.Comment: results = "Comment"; break;
|
||||
//case Column.Conductivity: results = "Conductivity"; break;
|
||||
case Column.Contact_Symmetry: results = "Contact Symmetry"; break;
|
||||
//case Column.Cracking_verification: results = "Cracking verification"; break;
|
||||
//case Column.Crater_verification: results = "Crater verification"; break;
|
||||
case Column.Date: results = "Date"; break;
|
||||
case Column.Denton_Crystal_Life: results = "Denton_Crystal_Life"; break;
|
||||
case Column.Denton_Current_AVG: results = "Denton_Current_AVG"; break;
|
||||
case Column.Denton_Current_STDEV: results = "Denton_Current_STDEV"; break;
|
||||
case Column.Denton_Deposition_Power_AVG: results = "Denton_Deposition_Power_AVG"; break;
|
||||
case Column.Denton_Deposition_Power_STDEV: results = "Denton_Deposition_Power_STDEV"; break;
|
||||
case Column.Denton_Deposition_Rate_AVG: results = "Denton_Deposition_Rate_AVG"; break;
|
||||
case Column.Denton_Deposition_Rate_STDEV: results = "Denton_Deposition_Rate_STDEV"; break;
|
||||
case Column.Denton_Gun_Pocket: results = "Denton_Gun_Pocket"; break;
|
||||
case Column.Denton_Pumpdown_Time: results = "Denton_Pumpdown_Time"; break;
|
||||
case Column.Denton_Voltage_AVG: results = "Denton_Voltage_AVG"; break;
|
||||
case Column.Denton_Voltage_STDEV: results = "Denton_Voltage_STDEV"; break;
|
||||
case Column.Employee: results = "Employee"; break;
|
||||
case Column.Epi_Thickness_Mean: results = "Epi Thickness Mean"; break;
|
||||
case Column.Epi_Thickness_Mean_XY: results = "Epi Thickness Mean_XY"; break;
|
||||
case Column.Epi_Thickness_Std_Dev_: results = "Epi Thickness Std Dev %"; break;
|
||||
case Column.FWHM_006_WTAVG: results = "FWHM 006 WTAVG"; break;
|
||||
case Column.FWHM_006: results = "FWHM 006"; break;
|
||||
case Column.FWHM_105_WTAVG: results = "FWHM 105 WTAVG"; break;
|
||||
case Column.FWHM_105: results = "FWHM 105"; break;
|
||||
case Column.Hall_Rs: results = "Hall Rs"; break;
|
||||
case Column.Hall_Mobility_verif_sample: results = "Hall_Mobility_verif_sample"; break;
|
||||
case Column.Hall_Ns_verif_sample: results = "Hall_Ns_verif_sample"; break;
|
||||
case Column.Hall_Rs_verif_sample: results = "Hall_Rs_verif_sample"; break;
|
||||
case Column.Job: results = "Job"; break;
|
||||
case Column.LEI_RS_Average_value: results = "LEI RS Average value"; break;
|
||||
case Column.LEI_RS_Maximum_value: results = "LEI RS Maximum value"; break;
|
||||
case Column.LEI_RS_Minimum_value: results = "LEI RS Minimum value"; break;
|
||||
case Column.LEI_RS_STDEV: results = "LEI RS STDEV"; break;
|
||||
case Column.LEI_RS_STDEV_: results = "LEI RS STDEV%"; break;
|
||||
//case Column.Large_Adder_Sum: results = "Large Adder Sum"; break;
|
||||
case Column.Lot: results = "Lot"; break;
|
||||
//case Column.Medium_Adder_Sum: results = "Medium Adder Sum"; break;
|
||||
case Column.Microscope_Center_5x: results = "Microscope Center 5x"; break;
|
||||
case Column.Microscope_Center_50x: results = "Microscope Center 50x"; break;
|
||||
case Column.Microscope_Middle_5x: results = "Microscope Middle 5x"; break;
|
||||
case Column.Microscope_Middle_50x: results = "Microscope Middle 50x"; break;
|
||||
case Column.Microscope_Edge_5x: results = "Microscope Edge 5x"; break;
|
||||
case Column.Microscope_Edge_50x: results = "Microscope Edge 50x"; break;
|
||||
case Column.Mobility_Verification: results = "Mobility Verification"; break;
|
||||
case Column.Mobility: results = "Mobility"; break;
|
||||
case Column.Ns_Verification: results = "Ns Verification"; break;
|
||||
case Column.PL_Edge_Wavelength: results = "PL Edge Wavelength"; break;
|
||||
case Column.PL_Ratio: results = "PL Ratio"; break;
|
||||
case Column.PR_Barrier_Composition: results = "PR Barrier Composition"; break;
|
||||
case Column.PR_Peak: results = "PR Peak"; break;
|
||||
case Column.Part: results = "Part"; break;
|
||||
//case Column.Particles_verification: results = "Particles verification"; break;
|
||||
//case Column.Pits_verification: results = "Pits verification"; break;
|
||||
//case Column.Pocket: results = "Pocket"; break;
|
||||
//case Column.Post_Bin_1: results = "Post Bin 1"; break;
|
||||
//case Column.Post_Bin_2: results = "Post Bin 2"; break;
|
||||
//case Column.Post_Bin_3: results = "Post Bin 3"; break;
|
||||
//case Column.Post_Bin_4: results = "Post Bin 4"; break;
|
||||
//case Column.Post_Bin_5: results = "Post Bin 5"; break;
|
||||
//case Column.Post_Bin_6: results = "Post Bin 6"; break;
|
||||
//case Column.Post_Bin_9: results = "Post Bin 9"; break;
|
||||
//case Column.Pre_Bin_1: results = "Pre Bin 1"; break;
|
||||
//case Column.Pre_Bin_2: results = "Pre Bin 2"; break;
|
||||
//case Column.Pre_Bin_3: results = "Pre Bin 3"; break;
|
||||
//case Column.Pre_Bin_4: results = "Pre Bin 4"; break;
|
||||
//case Column.Pre_Bin_5: results = "Pre Bin 5"; break;
|
||||
//case Column.Pre_Bin_6: results = "Pre Bin 6"; break;
|
||||
//case Column.Pre_Bin_9: results = "Pre Bin 9"; break;
|
||||
case Column.Process: results = "Process"; break;
|
||||
//case Column.RPM_verif_Thickness_1: results = "RPM_verif_Thickness_1"; break;
|
||||
//case Column.RPM_verif_Thickness_2: results = "RPM_verif_Thickness_2"; break;
|
||||
//case Column.RPM_verif_Thickness_3: results = "RPM_verif_Thickness_3"; break;
|
||||
//case Column.RPM_verif_Thickness_Average: results = "RPM_verif_Thickness_Average"; break;
|
||||
//case Column.RTA_oxide_Thk_Change: results = "RTA oxide Thk Change"; break;
|
||||
//case Column.RTA_oxide_post_anneal_Thk: results = "RTA oxide post-anneal Thk"; break;
|
||||
//case Column.RTA_oxide_pre_anneal_Thk: results = "RTA oxide pre-anneal Thk"; break;
|
||||
case Column.Recipe: results = "Recipe"; break;
|
||||
//case Column.Resistivity_2_ohm_cm: results = "Resistivity 2 ohm cm"; break; //LEI Weekly Verification
|
||||
//case Column.Resistivity_600_ohm_cm: results = "Resistivity 600 ohm cm"; break; //LEI Weekly Verification
|
||||
case Column.Rs_verification: results = "Rs verification"; break;
|
||||
case Column.Rs_verif_100kohm: results = "Rs_verif_100kohm"; break;
|
||||
case Column.Rs_verif_10ohm: results = "Rs_verif_10ohm"; break;
|
||||
case Column.Rs_verif_1kohm: results = "Rs_verif_1kohm"; break;
|
||||
case Column.SID: results = "SID"; break;
|
||||
case Column.SL_Period_WTAVG: results = "SL Period WTAVG"; break;
|
||||
case Column.SL_Period: results = "SL Period"; break;
|
||||
//case Column.SPE_verification: results = "SPE verification"; break;
|
||||
//case Column.Sample_ID: results = "Sample ID"; break;
|
||||
case Column.Sheet_Concentration: results = "Sheet Concentration"; break;
|
||||
//case Column.Size: results = "Size"; break;
|
||||
//case Column.Small_Adder_Sum: results = "Small Adder Sum"; break;
|
||||
//case Column.Spirals_verification: results = "Spirals verification"; break;
|
||||
case Column.Time: results = "Time"; break;
|
||||
case Column.Tool_ID: results = "Tool ID"; break;
|
||||
//case Column.Total_LPD_Adder: results = "Total LPD Adder"; break;
|
||||
//case Column.Total_Verification: results = "Total Verification"; break;
|
||||
case Column.Total_Warp_Calibration: results = "Total Warp Calibration"; break;
|
||||
case Column.UV_Broken: results = "UV Broken"; break;
|
||||
case Column.UV_Chipping: results = "UV Chipping"; break;
|
||||
case Column.UV_Cracking_0_3mm_: results = "UV Cracking (0-3mm)"; break;
|
||||
case Column.UV_Cracking_3_7mm_: results = "UV Cracking (3-7mm)"; break;
|
||||
case Column.UV_Cracking_7mm_: results = "UV Cracking (>7mm)"; break;
|
||||
case Column.UV_Crazing: results = "UV Crazing"; break;
|
||||
case Column.UV_Crazing_Acceptable: results = "UV Crazing Acceptable"; break;
|
||||
case Column.UV_FULL_Characterization_Wafer: results = "UV FULL Characterization Wafer"; break;
|
||||
case Column.UV_Haze_count_: results = "UV Haze (count)"; break;
|
||||
case Column.UV_LIGHT_Characterization_Wafer: results = "UV LIGHT Characterization Wafer"; break;
|
||||
case Column.UV_Non_rotation: results = "UV Non-rotation"; break;
|
||||
case Column.UV_Other: results = "UV Other"; break;
|
||||
case Column.UV_Scratch_count_: results = "UV Scratch (count)"; break;
|
||||
case Column.UV_Slip_count_: results = "UV Slip (count)"; break;
|
||||
case Column.UV_True_Haze: results = "UV True Haze"; break;
|
||||
case Column.UV_True_Haze_Acceptable: results = "UV True Haze Acceptable"; break;
|
||||
case Column.UV_SPE_1mm_count: results = "UV-SPE (>1mm) count"; break;
|
||||
case Column.UV_SPE_count_: results = "UV-SPE (count)"; break;
|
||||
case Column.Verification_Contact_Symmetry: results = "Verification Contact Symmetry"; break;
|
||||
case Column.Vp_Pinch_Off_Voltage: results = "Vp Pinch Off Voltage"; break;
|
||||
case Column.Wafer_ID: results = "Wafer ID"; break;
|
||||
//case Column.Wafer_Pocket: results = "Wafer Pocket"; break;
|
||||
case Column.Wafer_Region: results = "Wafer Region"; break;
|
||||
case Column.Wafer_Scribe: results = "Wafer Scribe"; break;
|
||||
case Column.WaferPocket_Candela: results = "WaferPocket_Candela"; break;
|
||||
case Column.WaferPocket_Warp: results = "WaferPocket_Warp"; break;
|
||||
case Column.WaferPosition_CV: results = "WaferPosition_CV"; break;
|
||||
case Column.WaferPosition_BV: results = "WaferPosition_BV"; break;
|
||||
case Column.WaferPosition_Hall: results = "WaferPosition_Hall"; break;
|
||||
case Column.WaferPosition_PR: results = "WaferPosition_PR"; break;
|
||||
case Column.Warp: results = "Warp"; break;
|
||||
case Column.X_Coord: results = "X-Coord"; break;
|
||||
case Column.XRD_2_Theta_Peak_002: results = "XRD 2 Theta Peak 002"; break;
|
||||
case Column.XRD_2_Theta_Peak_101: results = "XRD 2 Theta Peak 101"; break;
|
||||
case Column.XRD_2_Theta_Position: results = "XRD 2-Theta Position"; break;
|
||||
case Column.XRD_2_Theta_Position_Si_1: results = "XRD 2-Theta Position Si 1"; break;
|
||||
case Column.XRD_2_Theta_Position_Si_2: results = "XRD 2-Theta Position Si 2"; break;
|
||||
case Column.XRD_2_Theta_Position_Si_3: results = "XRD 2-Theta Position Si 3"; break;
|
||||
case Column.XRD_Peak_002_Intensity: results = "XRD Peak 002 Intensity"; break;
|
||||
case Column.XRD_Peak_101_Intensity: results = "XRD Peak 101 Intensity"; break;
|
||||
case Column.XRD_Weekly_AL_Center: results = "XRD Weekly AL% Center"; break;
|
||||
case Column.XRD_Weekly_Back_Barrier_Al_: results = "Back Barrier Al%"; break;
|
||||
case Column.XRD_Weekly_Barrier_Al_: results = "Barrier Al%"; break;
|
||||
case Column.XRD_Weekly_FWHM_002: results = "XRD Weekly FWHM 002"; break;
|
||||
case Column.XRD_Weekly_FWHM_101: results = "XRD Weekly FWHM 101"; break;
|
||||
case Column.XRD_Weekly_FWHM_105: results = "XRD Weekly FWHM 105"; break;
|
||||
case Column.XRD_Weekly_Fringe_thick_0_0_: results = "XRD Weekly Fringe thick (0,0)"; break;
|
||||
case Column.XRD_Weekly_Fringe_thick_48_48_: results = "XRD Weekly Fringe thick (48,48)"; break;
|
||||
case Column.XRD_Weekly_Intensity: results = "XRD Weekly Intensity"; break;
|
||||
case Column.XRD_Weekly_Super_Lattice_Al_: results = "Super Lattice Al%"; break;
|
||||
case Column.XRD_Weekly_Super_Lattice_period: results = "Super Lattice period"; break;
|
||||
case Column.XRD_Weekly_Super_Lattice_tks: results = "Super Lattice tks"; break;
|
||||
case Column.XRR_Thickness_nm_WTAVG: results = "XRR Thickness (nm) WTAVG"; break;
|
||||
case Column.XRR_Thickness_nm_: results = "XRR Thickness (nm)"; break;
|
||||
case Column.Y_Coord: results = "Y-Coord"; break;
|
||||
case Column.YellowBand_Power_mW_: results = "YellowBand_Power (mW)"; break;
|
||||
case Column.YellowBand_V: results = "YellowBand_V"; break;
|
||||
case Column.YellowBand_V_XY: results = "YellowBand_V_XY"; break;
|
||||
case Column.YellowBand_nm: results = "YellowBand_nm"; break;
|
||||
//case Column.pH: results = "pH"; break;
|
||||
case Column.Ag: results = "Ag"; break;
|
||||
case Column.Al: results = "Al"; break;
|
||||
case Column.As: results = "As"; break;
|
||||
case Column.Au: results = "Au"; break;
|
||||
case Column.B: results = "B"; break;
|
||||
case Column.Ba: results = "Ba"; break;
|
||||
case Column.Ca: results = "Ca"; break;
|
||||
case Column.Ce: results = "Ce"; break;
|
||||
case Column.Co: results = "Co"; break;
|
||||
case Column.Cr: results = "Cr"; break;
|
||||
case Column.Cu: results = "Cu"; break;
|
||||
case Column.Fe: results = "Fe"; break;
|
||||
case Column.Ga: results = "Ga"; break;
|
||||
case Column.Ge: results = "Ge"; break;
|
||||
case Column.Hf: results = "Hf"; break;
|
||||
case Column.K: results = "K"; break;
|
||||
case Column.Li: results = "Li"; break;
|
||||
case Column.Mg: results = "Mg"; break;
|
||||
case Column.Mn: results = "Mn"; break;
|
||||
case Column.Mo: results = "Mo"; break;
|
||||
case Column.Na: results = "Na"; break;
|
||||
case Column.Ni: results = "Ni"; break;
|
||||
case Column.P: results = "P"; break;
|
||||
case Column.Pb: results = "Pb"; break;
|
||||
case Column.Sn: results = "Sn"; break;
|
||||
case Column.Ta: results = "Ta"; break;
|
||||
case Column.Ti: results = "Ti"; break;
|
||||
case Column.W: results = "W"; break;
|
||||
case Column.Y: results = "Y"; break;
|
||||
case Column.Zn: results = "Zn"; break;
|
||||
default: throw new Exception();
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static Description.Param GetParam(this Column column)
|
||||
{
|
||||
Description.Param results;
|
||||
switch (column)
|
||||
{
|
||||
//case Column._8in_Total_Warp_Verification: results = Description.Param.String; break;
|
||||
//case Column.AFM_Monthly_Y: results = Description.Param.String; break;
|
||||
//case Column.AFM_Monthly: results = Description.Param.String; break;
|
||||
case Column.AFM_Pit_Count: results = Description.Param.String; break;
|
||||
case Column.AFM_Roughness: results = Description.Param.String; break;
|
||||
//case Column.Adder_Bin_1: results = Description.Param.String; break;
|
||||
//case Column.Adder_Bin_2: results = Description.Param.String; break;
|
||||
//case Column.Adder_Bin_3: results = Description.Param.String; break;
|
||||
//case Column.Adder_Bin_4: results = Description.Param.String; break;
|
||||
//case Column.Adder_Bin_5: results = Description.Param.String; break;
|
||||
//case Column.Adder_Bin_6: results = Description.Param.String; break;
|
||||
//case Column.Adder_Bin_9: results = Description.Param.String; break;
|
||||
case Column.Al_B_B_WTAVG: results = Description.Param.String; break;
|
||||
case Column.Al_B_B_: results = Description.Param.String; break;
|
||||
case Column.Al_Barrier_WTAVG: results = Description.Param.String; break;
|
||||
case Column.Al_Barrier: results = Description.Param.String; break;
|
||||
case Column.Al_SLS_WTAVG: results = Description.Param.String; break;
|
||||
case Column.Al_SLS: results = Description.Param.String; break;
|
||||
case Column.Al_TL1_WTAVG: results = Description.Param.String; break;
|
||||
case Column.Al_TL1: results = Description.Param.String; break;
|
||||
case Column.Al_TL2_WTAVG: results = Description.Param.String; break;
|
||||
//case Column.BV_Resistance: results = Description.Param.String; break;
|
||||
case Column.BandEdge_V: results = Description.Param.String; break;
|
||||
case Column.BandEdge_V_XY: results = Description.Param.String; break;
|
||||
case Column.BandEdge_nm: results = Description.Param.String; break;
|
||||
case Column.Barrier_Composition_RPM_XY: results = Description.Param.String; break;
|
||||
case Column.Bow_Calibration: results = Description.Param.String; break;
|
||||
case Column.Bow_Range: results = Description.Param.String; break;
|
||||
case Column.Bow: results = Description.Param.String; break;
|
||||
case Column.BowCenter: results = Description.Param.String; break;
|
||||
case Column.BowX: results = Description.Param.String; break;
|
||||
case Column.BowY: results = Description.Param.String; break;
|
||||
case Column.Breakdown_Voltage_Edge: results = Description.Param.String; break;
|
||||
case Column.Breakdown_VoltageMiddle: results = Description.Param.String; break;
|
||||
case Column.Breakdown_Voltage: results = Description.Param.String; break;
|
||||
case Column.CV_C_at_10V: results = Description.Param.String; break;
|
||||
case Column.CV_Nd_Min: results = Description.Param.String; break;
|
||||
//case Column.Candela_Large_LPD_Quarterly: results = Description.Param.String; break;
|
||||
//case Column.Candela_Medium_LPD_Quarterly: results = Description.Param.String; break;
|
||||
//case Column.Candela_Small_LPD_Quarterly: results = Description.Param.String; break;
|
||||
//case Column.Candela_Total_Quarterly: results = Description.Param.String; break;
|
||||
case Column.Candela_102_83nm: results = Description.Param.String; break;
|
||||
case Column.Candela_1_1um: results = Description.Param.String; break;
|
||||
case Column.Candela_496nm: results = Description.Param.String; break;
|
||||
case Column.Candela_600nm: results = Description.Param.String; break;
|
||||
case Column.Candela_8620_Small: results = Description.Param.String; break;
|
||||
case Column.Candela_Crack_Verification: results = Description.Param.String; break;
|
||||
case Column.Candela_Cracking: results = Description.Param.String; break;
|
||||
case Column.Candela_Cracking_Acceptable: results = Description.Param.String; break;
|
||||
case Column.Candela_Crater: results = Description.Param.String; break;
|
||||
case Column.Candela_Crater_Verification: results = Description.Param.String; break;
|
||||
case Column.Candela_Haze: results = Description.Param.String; break;
|
||||
case Column.Candela_LPD_Large: results = Description.Param.String; break;
|
||||
case Column.Candela_LPD_Medium: results = Description.Param.String; break;
|
||||
case Column.Candela_LPD_Small: results = Description.Param.String; break;
|
||||
case Column.Candela_Large_Verification: results = Description.Param.String; break;
|
||||
case Column.Candela_Medium_Verification: results = Description.Param.String; break;
|
||||
case Column.Candela_Pits: results = Description.Param.String; break;
|
||||
case Column.Candela_Pits_Verification: results = Description.Param.String; break;
|
||||
case Column.Candela_SPE: results = Description.Param.String; break;
|
||||
case Column.Candela_SPE_Verification: results = Description.Param.String; break;
|
||||
case Column.Candela_Slip: results = Description.Param.String; break;
|
||||
case Column.Candela_Small_Verification: results = Description.Param.String; break;
|
||||
case Column.Candela_Spirals: results = Description.Param.String; break;
|
||||
case Column.Candela_Spirals_Verification: results = Description.Param.String; break;
|
||||
case Column.Candela_Total_Defects: results = Description.Param.String; break;
|
||||
case Column.Candela_Total_PSL: results = Description.Param.String; break;
|
||||
case Column.Candela__1_1um: results = Description.Param.String; break;
|
||||
//case Column.Comment: results = Description.Param.String; break;
|
||||
//case Column.Conductivity: results = Description.Param.String; break;
|
||||
case Column.Contact_Symmetry: results = Description.Param.String; break;
|
||||
//case Column.Cracking_verification: results = Description.Param.String; break;
|
||||
//case Column.Crater_verification: results = Description.Param.String; break;
|
||||
case Column.Date: results = Description.Param.String; break;
|
||||
case Column.Denton_Crystal_Life: results = Description.Param.String; break;
|
||||
case Column.Denton_Current_AVG: results = Description.Param.String; break;
|
||||
case Column.Denton_Current_STDEV: results = Description.Param.String; break;
|
||||
case Column.Denton_Deposition_Power_AVG: results = Description.Param.String; break;
|
||||
case Column.Denton_Deposition_Power_STDEV: results = Description.Param.String; break;
|
||||
case Column.Denton_Deposition_Rate_AVG: results = Description.Param.String; break;
|
||||
case Column.Denton_Deposition_Rate_STDEV: results = Description.Param.String; break;
|
||||
case Column.Denton_Gun_Pocket: results = Description.Param.String; break;
|
||||
case Column.Denton_Pumpdown_Time: results = Description.Param.String; break;
|
||||
case Column.Denton_Voltage_AVG: results = Description.Param.String; break;
|
||||
case Column.Denton_Voltage_STDEV: results = Description.Param.String; break;
|
||||
case Column.Employee: results = Description.Param.String; break;
|
||||
case Column.Epi_Thickness_Mean: results = Description.Param.String; break;
|
||||
case Column.Epi_Thickness_Mean_XY: results = Description.Param.String; break;
|
||||
case Column.Epi_Thickness_Std_Dev_: results = Description.Param.String; break;
|
||||
case Column.FWHM_006_WTAVG: results = Description.Param.String; break;
|
||||
case Column.FWHM_006: results = Description.Param.String; break;
|
||||
case Column.FWHM_105_WTAVG: results = Description.Param.String; break;
|
||||
case Column.FWHM_105: results = Description.Param.String; break;
|
||||
case Column.Hall_Rs: results = Description.Param.String; break;
|
||||
case Column.Hall_Mobility_verif_sample: results = Description.Param.String; break;
|
||||
case Column.Hall_Ns_verif_sample: results = Description.Param.String; break;
|
||||
case Column.Hall_Rs_verif_sample: results = Description.Param.String; break;
|
||||
case Column.Job: results = Description.Param.String; break;
|
||||
case Column.LEI_RS_Average_value: results = Description.Param.String; break;
|
||||
case Column.LEI_RS_Maximum_value: results = Description.Param.String; break;
|
||||
case Column.LEI_RS_Minimum_value: results = Description.Param.String; break;
|
||||
case Column.LEI_RS_STDEV: results = Description.Param.String; break;
|
||||
case Column.LEI_RS_STDEV_: results = Description.Param.String; break;
|
||||
//case Column.Large_Adder_Sum: results = Description.Param.String; break;
|
||||
case Column.Lot: results = Description.Param.String; break;
|
||||
//case Column.Medium_Adder_Sum: results = Description.Param.String; break;
|
||||
case Column.Microscope_Center_5x: results = Description.Param.String; break;
|
||||
case Column.Microscope_Center_50x: results = Description.Param.String; break;
|
||||
case Column.Microscope_Middle_5x: results = Description.Param.String; break;
|
||||
case Column.Microscope_Middle_50x: results = Description.Param.String; break;
|
||||
case Column.Microscope_Edge_5x: results = Description.Param.String; break;
|
||||
case Column.Microscope_Edge_50x: results = Description.Param.String; break;
|
||||
case Column.Mobility_Verification: results = Description.Param.String; break;
|
||||
case Column.Mobility: results = Description.Param.String; break;
|
||||
case Column.Ns_Verification: results = Description.Param.String; break;
|
||||
case Column.PL_Edge_Wavelength: results = Description.Param.String; break;
|
||||
case Column.PL_Ratio: results = Description.Param.String; break;
|
||||
case Column.PR_Barrier_Composition: results = Description.Param.String; break;
|
||||
case Column.PR_Peak: results = Description.Param.String; break;
|
||||
case Column.Part: results = Description.Param.String; break;
|
||||
//case Column.Particles_verification: results = Description.Param.String; break;
|
||||
//case Column.Pits_verification: results = Description.Param.String; break;
|
||||
//case Column.Pocket: results = Description.Param.String; break;
|
||||
//case Column.Post_Bin_1: results = Description.Param.String; break;
|
||||
//case Column.Post_Bin_2: results = Description.Param.String; break;
|
||||
//case Column.Post_Bin_3: results = Description.Param.String; break;
|
||||
//case Column.Post_Bin_4: results = Description.Param.String; break;
|
||||
//case Column.Post_Bin_5: results = Description.Param.String; break;
|
||||
//case Column.Post_Bin_6: results = Description.Param.String; break;
|
||||
//case Column.Post_Bin_9: results = Description.Param.String; break;
|
||||
//case Column.Pre_Bin_1: results = Description.Param.String; break;
|
||||
//case Column.Pre_Bin_2: results = Description.Param.String; break;
|
||||
//case Column.Pre_Bin_3: results = Description.Param.String; break;
|
||||
//case Column.Pre_Bin_4: results = Description.Param.String; break;
|
||||
//case Column.Pre_Bin_5: results = Description.Param.String; break;
|
||||
//case Column.Pre_Bin_6: results = Description.Param.String; break;
|
||||
//case Column.Pre_Bin_9: results = Description.Param.String; break;
|
||||
case Column.Process: results = Description.Param.String; break;
|
||||
//case Column.RPM_verif_Thickness_1: results = Description.Param.String; break;
|
||||
//case Column.RPM_verif_Thickness_2: results = Description.Param.String; break;
|
||||
//case Column.RPM_verif_Thickness_3: results = Description.Param.String; break;
|
||||
//case Column.RPM_verif_Thickness_Average: results = Description.Param.String; break;
|
||||
//case Column.RTA_oxide_Thk_Change: results = Description.Param.String; break;
|
||||
//case Column.RTA_oxide_post_anneal_Thk: results = Description.Param.String; break;
|
||||
//case Column.RTA_oxide_pre_anneal_Thk: results = Description.Param.String; break;
|
||||
case Column.Recipe: results = Description.Param.String; break;
|
||||
//case Column.Resistivity_2_ohm_cm: results = Description.Param.String; break;
|
||||
//case Column.Resistivity_600_ohm_cm: results = Description.Param.String; break;
|
||||
case Column.Rs_verification: results = Description.Param.String; break;
|
||||
case Column.Rs_verif_100kohm: results = Description.Param.String; break;
|
||||
case Column.Rs_verif_10ohm: results = Description.Param.String; break;
|
||||
case Column.Rs_verif_1kohm: results = Description.Param.String; break;
|
||||
case Column.SID: results = Description.Param.String; break;
|
||||
case Column.SL_Period_WTAVG: results = Description.Param.String; break;
|
||||
case Column.SL_Period: results = Description.Param.String; break;
|
||||
//case Column.SPE_verification: results = Description.Param.String; break;
|
||||
//case Column.Sample_ID: results = Description.Param.String; break;
|
||||
case Column.Sheet_Concentration: results = Description.Param.String; break;
|
||||
//case Column.Size: results = Description.Param.String; break;
|
||||
//case Column.Small_Adder_Sum: results = Description.Param.String; break;
|
||||
//case Column.Spirals_verification: results = Description.Param.String; break;
|
||||
case Column.Time: results = Description.Param.String; break;
|
||||
case Column.Tool_ID: results = Description.Param.String; break;
|
||||
//case Column.Total_LPD_Adder: results = Description.Param.String; break;
|
||||
//case Column.Total_Verification: results = Description.Param.String; break;
|
||||
case Column.Total_Warp_Calibration: results = Description.Param.String; break;
|
||||
case Column.UV_Broken: results = Description.Param.String; break;
|
||||
case Column.UV_Chipping: results = Description.Param.String; break;
|
||||
case Column.UV_Cracking_0_3mm_: results = Description.Param.String; break;
|
||||
case Column.UV_Cracking_3_7mm_: results = Description.Param.String; break;
|
||||
case Column.UV_Cracking_7mm_: results = Description.Param.String; break;
|
||||
case Column.UV_Crazing: results = Description.Param.String; break;
|
||||
case Column.UV_Crazing_Acceptable: results = Description.Param.String; break;
|
||||
case Column.UV_FULL_Characterization_Wafer: results = Description.Param.String; break;
|
||||
case Column.UV_Haze_count_: results = Description.Param.String; break;
|
||||
case Column.UV_LIGHT_Characterization_Wafer: results = Description.Param.String; break;
|
||||
case Column.UV_Non_rotation: results = Description.Param.String; break;
|
||||
case Column.UV_Other: results = Description.Param.String; break;
|
||||
case Column.UV_Scratch_count_: results = Description.Param.String; break;
|
||||
case Column.UV_Slip_count_: results = Description.Param.String; break;
|
||||
case Column.UV_True_Haze: results = Description.Param.String; break;
|
||||
case Column.UV_True_Haze_Acceptable: results = Description.Param.String; break;
|
||||
case Column.UV_SPE_1mm_count: results = Description.Param.String; break;
|
||||
case Column.UV_SPE_count_: results = Description.Param.String; break;
|
||||
case Column.Verification_Contact_Symmetry: results = Description.Param.String; break;
|
||||
case Column.Vp_Pinch_Off_Voltage: results = Description.Param.String; break;
|
||||
case Column.Wafer_ID: results = Description.Param.String; break;
|
||||
//case Column.Wafer_Pocket: results = Description.Param.String; break;
|
||||
case Column.Wafer_Region: results = Description.Param.String; break;
|
||||
case Column.Wafer_Scribe: results = Description.Param.String; break;
|
||||
case Column.WaferPocket_Candela: results = Description.Param.String; break;
|
||||
case Column.WaferPocket_Warp: results = Description.Param.String; break;
|
||||
case Column.WaferPosition_CV: results = Description.Param.String; break;
|
||||
case Column.WaferPosition_BV: results = Description.Param.String; break;
|
||||
case Column.WaferPosition_Hall: results = Description.Param.String; break;
|
||||
case Column.WaferPosition_PR: results = Description.Param.String; break;
|
||||
case Column.Warp: results = Description.Param.String; break;
|
||||
case Column.X_Coord: results = Description.Param.String; break;
|
||||
case Column.XRD_2_Theta_Peak_002: results = Description.Param.String; break;
|
||||
case Column.XRD_2_Theta_Peak_101: results = Description.Param.String; break;
|
||||
case Column.XRD_2_Theta_Position: results = Description.Param.String; break;
|
||||
case Column.XRD_2_Theta_Position_Si_1: results = Description.Param.String; break;
|
||||
case Column.XRD_2_Theta_Position_Si_2: results = Description.Param.String; break;
|
||||
case Column.XRD_2_Theta_Position_Si_3: results = Description.Param.String; break;
|
||||
case Column.XRD_Peak_002_Intensity: results = Description.Param.String; break;
|
||||
case Column.XRD_Peak_101_Intensity: results = Description.Param.String; break;
|
||||
case Column.XRD_Weekly_AL_Center: results = Description.Param.String; break;
|
||||
case Column.XRD_Weekly_Back_Barrier_Al_: results = Description.Param.String; break;
|
||||
case Column.XRD_Weekly_Barrier_Al_: results = Description.Param.String; break;
|
||||
case Column.XRD_Weekly_FWHM_002: results = Description.Param.String; break;
|
||||
case Column.XRD_Weekly_FWHM_101: results = Description.Param.String; break;
|
||||
case Column.XRD_Weekly_FWHM_105: results = Description.Param.String; break;
|
||||
case Column.XRD_Weekly_Fringe_thick_0_0_: results = Description.Param.String; break;
|
||||
case Column.XRD_Weekly_Fringe_thick_48_48_: results = Description.Param.String; break;
|
||||
case Column.XRD_Weekly_Intensity: results = Description.Param.String; break;
|
||||
case Column.XRD_Weekly_Super_Lattice_Al_: results = Description.Param.String; break;
|
||||
case Column.XRD_Weekly_Super_Lattice_period: results = Description.Param.String; break;
|
||||
case Column.XRD_Weekly_Super_Lattice_tks: results = Description.Param.String; break;
|
||||
case Column.XRR_Thickness_nm_WTAVG: results = Description.Param.String; break;
|
||||
case Column.XRR_Thickness_nm_: results = Description.Param.String; break;
|
||||
case Column.Y_Coord: results = Description.Param.String; break;
|
||||
case Column.YellowBand_Power_mW_: results = Description.Param.String; break;
|
||||
case Column.YellowBand_V: results = Description.Param.String; break;
|
||||
case Column.YellowBand_V_XY: results = Description.Param.String; break;
|
||||
case Column.YellowBand_nm: results = Description.Param.String; break;
|
||||
//case Column.pH: results = Description.Param.String; break;
|
||||
case Column.Ag: results = Description.Param.String; break;
|
||||
case Column.Al: results = Description.Param.String; break;
|
||||
case Column.As: results = Description.Param.String; break;
|
||||
case Column.Au: results = Description.Param.String; break;
|
||||
case Column.B: results = Description.Param.String; break;
|
||||
case Column.Ba: results = Description.Param.String; break;
|
||||
case Column.Ca: results = Description.Param.String; break;
|
||||
case Column.Ce: results = Description.Param.String; break;
|
||||
case Column.Co: results = Description.Param.String; break;
|
||||
case Column.Cr: results = Description.Param.String; break;
|
||||
case Column.Cu: results = Description.Param.String; break;
|
||||
case Column.Fe: results = Description.Param.String; break;
|
||||
case Column.Ga: results = Description.Param.String; break;
|
||||
case Column.Ge: results = Description.Param.String; break;
|
||||
case Column.Hf: results = Description.Param.String; break;
|
||||
case Column.K: results = Description.Param.String; break;
|
||||
case Column.Li: results = Description.Param.String; break;
|
||||
case Column.Mg: results = Description.Param.String; break;
|
||||
case Column.Mn: results = Description.Param.String; break;
|
||||
case Column.Mo: results = Description.Param.String; break;
|
||||
case Column.Na: results = Description.Param.String; break;
|
||||
case Column.Ni: results = Description.Param.String; break;
|
||||
case Column.P: results = Description.Param.String; break;
|
||||
case Column.Pb: results = Description.Param.String; break;
|
||||
case Column.Sn: results = Description.Param.String; break;
|
||||
case Column.Ta: results = Description.Param.String; break;
|
||||
case Column.Ti: results = Description.Param.String; break;
|
||||
case Column.W: results = Description.Param.String; break;
|
||||
case Column.Y: results = Description.Param.String; break;
|
||||
case Column.Zn: results = Description.Param.String; break;
|
||||
default: throw new Exception();
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum Column
|
||||
{
|
||||
//_8in_Total_Warp_Verification,
|
||||
//AFM_Monthly_Y,
|
||||
//AFM_Monthly,
|
||||
AFM_Pit_Count,
|
||||
AFM_Roughness,
|
||||
//Adder_Bin_1,
|
||||
//Adder_Bin_2,
|
||||
//Adder_Bin_3,
|
||||
//Adder_Bin_4,
|
||||
//Adder_Bin_5,
|
||||
//Adder_Bin_6,
|
||||
//Adder_Bin_9,
|
||||
Al_B_B_WTAVG,
|
||||
Al_B_B_,
|
||||
Al_Barrier_WTAVG,
|
||||
Al_Barrier,
|
||||
Al_SLS_WTAVG,
|
||||
Al_SLS,
|
||||
Al_TL1_WTAVG,
|
||||
Al_TL1,
|
||||
Al_TL2_WTAVG,
|
||||
//BV_Resistance,
|
||||
BandEdge_V,
|
||||
BandEdge_V_XY,
|
||||
BandEdge_nm,
|
||||
Barrier_Composition_RPM_XY,
|
||||
Bow_Calibration,
|
||||
Bow_Range,
|
||||
Bow,
|
||||
BowCenter,
|
||||
BowX,
|
||||
BowY,
|
||||
Breakdown_Voltage_Edge,
|
||||
Breakdown_VoltageMiddle,
|
||||
Breakdown_Voltage,
|
||||
CV_C_at_10V,
|
||||
CV_Nd_Min,
|
||||
//Candela_Large_LPD_Quarterly,
|
||||
//Candela_Medium_LPD_Quarterly,
|
||||
//Candela_Small_LPD_Quarterly,
|
||||
//Candela_Total_Quarterly,
|
||||
Candela_102_83nm,
|
||||
Candela_1_1um,
|
||||
Candela_496nm,
|
||||
Candela_600nm,
|
||||
Candela_8620_Small,
|
||||
Candela_Crack_Verification,
|
||||
Candela_Cracking,
|
||||
Candela_Cracking_Acceptable,
|
||||
Candela_Crater,
|
||||
Candela_Crater_Verification,
|
||||
Candela_Haze,
|
||||
Candela_LPD_Large,
|
||||
Candela_LPD_Medium,
|
||||
Candela_LPD_Small,
|
||||
Candela_Large_Verification,
|
||||
Candela_Medium_Verification,
|
||||
Candela_Pits,
|
||||
Candela_Pits_Verification,
|
||||
Candela_SPE,
|
||||
Candela_SPE_Verification,
|
||||
Candela_Slip,
|
||||
Candela_Small_Verification,
|
||||
Candela_Spirals,
|
||||
Candela_Spirals_Verification,
|
||||
Candela_Total_Defects,
|
||||
Candela_Total_PSL,
|
||||
Candela__1_1um,
|
||||
//Comment,
|
||||
//Conductivity,
|
||||
Contact_Symmetry,
|
||||
//Cracking_verification,
|
||||
//Crater_verification,
|
||||
Date,
|
||||
Denton_Crystal_Life,
|
||||
Denton_Current_AVG,
|
||||
Denton_Current_STDEV,
|
||||
Denton_Deposition_Power_AVG,
|
||||
Denton_Deposition_Power_STDEV,
|
||||
Denton_Deposition_Rate_AVG,
|
||||
Denton_Deposition_Rate_STDEV,
|
||||
Denton_Gun_Pocket,
|
||||
Denton_Pumpdown_Time,
|
||||
Denton_Voltage_AVG,
|
||||
Denton_Voltage_STDEV,
|
||||
Employee,
|
||||
Epi_Thickness_Mean,
|
||||
Epi_Thickness_Mean_XY,
|
||||
Epi_Thickness_Std_Dev_,
|
||||
FWHM_006_WTAVG,
|
||||
FWHM_006,
|
||||
FWHM_105_WTAVG,
|
||||
FWHM_105,
|
||||
Hall_Rs,
|
||||
Hall_Mobility_verif_sample,
|
||||
Hall_Ns_verif_sample,
|
||||
Hall_Rs_verif_sample,
|
||||
Job,
|
||||
LEI_RS_Average_value,
|
||||
LEI_RS_Maximum_value,
|
||||
LEI_RS_Minimum_value,
|
||||
LEI_RS_STDEV,
|
||||
LEI_RS_STDEV_,
|
||||
//Large_Adder_Sum,
|
||||
Lot,
|
||||
//Medium_Adder_Sum,
|
||||
Microscope_Center_50x,
|
||||
Microscope_Center_5x,
|
||||
Microscope_Edge_50x,
|
||||
Microscope_Edge_5x,
|
||||
Microscope_Middle_50x,
|
||||
Microscope_Middle_5x,
|
||||
Mobility_Verification,
|
||||
Mobility,
|
||||
Ns_Verification,
|
||||
PL_Edge_Wavelength,
|
||||
PL_Ratio,
|
||||
PR_Barrier_Composition,
|
||||
PR_Peak,
|
||||
Part,
|
||||
//Particles_verification,
|
||||
//Pits_verification,
|
||||
//Pocket,
|
||||
//Post_Bin_1,
|
||||
//Post_Bin_2,
|
||||
//Post_Bin_3,
|
||||
//Post_Bin_4,
|
||||
//Post_Bin_5,
|
||||
//Post_Bin_6,
|
||||
//Post_Bin_9,
|
||||
//Pre_Bin_1,
|
||||
//Pre_Bin_2,
|
||||
//Pre_Bin_3,
|
||||
//Pre_Bin_4,
|
||||
//Pre_Bin_5,
|
||||
//Pre_Bin_6,
|
||||
//Pre_Bin_9,
|
||||
Process,
|
||||
//RPM_verif_Thickness_1,
|
||||
//RPM_verif_Thickness_2,
|
||||
//RPM_verif_Thickness_3,
|
||||
//RPM_verif_Thickness_Average,
|
||||
//RTA_oxide_Thk_Change,
|
||||
//RTA_oxide_post_anneal_Thk,
|
||||
//RTA_oxide_pre_anneal_Thk,
|
||||
Recipe,
|
||||
//Resistivity_2_ohm_cm,
|
||||
//Resistivity_600_ohm_cm,
|
||||
Rs_verification,
|
||||
Rs_verif_100kohm,
|
||||
Rs_verif_10ohm,
|
||||
Rs_verif_1kohm,
|
||||
SID,
|
||||
SL_Period_WTAVG,
|
||||
SL_Period,
|
||||
//SPE_verification,
|
||||
//Sample_ID,
|
||||
Sheet_Concentration,
|
||||
//Size,
|
||||
//Small_Adder_Sum,
|
||||
//Spirals_verification,
|
||||
Time,
|
||||
Tool_ID,
|
||||
//Total_LPD_Adder,
|
||||
//Total_Verification,
|
||||
Total_Warp_Calibration,
|
||||
UV_Broken,
|
||||
UV_Chipping,
|
||||
UV_Cracking_0_3mm_,
|
||||
UV_Cracking_3_7mm_,
|
||||
UV_Cracking_7mm_,
|
||||
UV_Crazing,
|
||||
UV_Crazing_Acceptable,
|
||||
UV_FULL_Characterization_Wafer,
|
||||
UV_Haze_count_,
|
||||
UV_LIGHT_Characterization_Wafer,
|
||||
UV_Non_rotation,
|
||||
UV_Other,
|
||||
UV_Scratch_count_,
|
||||
UV_Slip_count_,
|
||||
UV_True_Haze,
|
||||
UV_True_Haze_Acceptable,
|
||||
UV_SPE_1mm_count,
|
||||
UV_SPE_count_,
|
||||
Verification_Contact_Symmetry,
|
||||
Vp_Pinch_Off_Voltage,
|
||||
Wafer_ID,
|
||||
//Wafer_Pocket,
|
||||
Wafer_Region,
|
||||
Wafer_Scribe,
|
||||
WaferPocket_Candela,
|
||||
WaferPocket_Warp,
|
||||
WaferPosition_CV,
|
||||
WaferPosition_BV,
|
||||
WaferPosition_Hall,
|
||||
WaferPosition_PR,
|
||||
Warp,
|
||||
X_Coord,
|
||||
XRD_2_Theta_Peak_002,
|
||||
XRD_2_Theta_Peak_101,
|
||||
XRD_2_Theta_Position,
|
||||
XRD_2_Theta_Position_Si_1,
|
||||
XRD_2_Theta_Position_Si_2,
|
||||
XRD_2_Theta_Position_Si_3,
|
||||
XRD_Peak_002_Intensity,
|
||||
XRD_Peak_101_Intensity,
|
||||
XRD_Weekly_AL_Center,
|
||||
XRD_Weekly_Back_Barrier_Al_,
|
||||
XRD_Weekly_Barrier_Al_,
|
||||
XRD_Weekly_FWHM_002,
|
||||
XRD_Weekly_FWHM_101,
|
||||
XRD_Weekly_FWHM_105,
|
||||
XRD_Weekly_Fringe_thick_0_0_,
|
||||
XRD_Weekly_Fringe_thick_48_48_,
|
||||
XRD_Weekly_Intensity,
|
||||
XRD_Weekly_Super_Lattice_Al_,
|
||||
XRD_Weekly_Super_Lattice_period,
|
||||
XRD_Weekly_Super_Lattice_tks,
|
||||
XRR_Thickness_nm_,
|
||||
XRR_Thickness_nm_WTAVG,
|
||||
Y_Coord,
|
||||
YellowBand_Power_mW_,
|
||||
YellowBand_V,
|
||||
YellowBand_V_XY,
|
||||
YellowBand_nm,
|
||||
//pH,
|
||||
Ag,
|
||||
Al,
|
||||
As,
|
||||
Au,
|
||||
B,
|
||||
Ba,
|
||||
Ca,
|
||||
Ce,
|
||||
Co,
|
||||
Cr,
|
||||
Cu,
|
||||
Fe,
|
||||
Ga,
|
||||
Ge,
|
||||
Hf,
|
||||
K,
|
||||
Li,
|
||||
Mg,
|
||||
Mn,
|
||||
Mo,
|
||||
Na,
|
||||
Ni,
|
||||
P,
|
||||
Pb,
|
||||
Sn,
|
||||
Ta,
|
||||
Ti,
|
||||
W,
|
||||
Y,
|
||||
Zn
|
||||
}
|
||||
|
||||
}
|
321
Shared/Metrology/ConfigDataBase.cs
Normal file
321
Shared/Metrology/ConfigDataBase.cs
Normal file
@ -0,0 +1,321 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class ConfigDataBase
|
||||
{
|
||||
|
||||
public bool EafHosted { get; protected set; }
|
||||
public string EquipmentElementName { get; protected set; }
|
||||
public bool UseCyclicalForDescription { get; protected set; }
|
||||
public Dictionary<string, string> CellNames { get; protected set; }
|
||||
public Dictionary<string, string> MesEntities { get; protected set; }
|
||||
public EquipmentConnection? EquipmentConnection { get; protected set; }
|
||||
|
||||
protected readonly string _CellName;
|
||||
protected readonly EventName? _EventName;
|
||||
protected readonly Dictionary<string, string> _Reactors;
|
||||
protected IProcessDataDescription _ProcessDataDescription;
|
||||
|
||||
public ConfigDataBase(string equipmentElementName, EquipmentConnection? equipmentConnection, string cellName, EventName? eventName, bool eafHosted)
|
||||
{
|
||||
_CellName = cellName;
|
||||
EafHosted = eafHosted;
|
||||
_EventName = eventName;
|
||||
EquipmentConnection = equipmentConnection;
|
||||
EquipmentElementName = equipmentElementName;
|
||||
_Reactors = new Dictionary<string, string>();
|
||||
CellNames = new Dictionary<string, string>();
|
||||
MesEntities = new Dictionary<string, string>();
|
||||
if (equipmentConnection is null && Enum.TryParse(equipmentElementName.Replace("-", string.Empty), out EquipmentConnection equipmentConnectionValue))
|
||||
EquipmentConnection = equipmentConnectionValue;
|
||||
}
|
||||
|
||||
public string GetEventName()
|
||||
{
|
||||
string result = string.Concat(_EventName);
|
||||
return result;
|
||||
}
|
||||
|
||||
public EventName GetEventNameValue()
|
||||
{
|
||||
EventName result = _EventName.Value;
|
||||
return result;
|
||||
}
|
||||
|
||||
public string GetEventDescription()
|
||||
{
|
||||
string result = _ProcessDataDescription.GetEventDescription();
|
||||
return result;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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<Description.Param, string, string, object>>> GetParameterInfo(ILogic logic, bool allowNull)
|
||||
{
|
||||
Dictionary<string, List<Tuple<Description.Param, string, string, object>>> results = new Dictionary<string, List<Tuple<Description.Param, string, string, object>>>();
|
||||
string description;
|
||||
Description.Param param;
|
||||
Tuple<Description.Param, 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<Description.Param, string, string, object>(param, jsonProperty.Name, description, jsonProperty.Value.ToString());
|
||||
if (!results.ContainsKey(jsonProperty.Name))
|
||||
results.Add(jsonProperty.Name, new List<Tuple<Description.Param, string, string, object>>());
|
||||
results[jsonProperty.Name].Add(tuple);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
protected void WriteExportAliases(ILogic logic, string cellName)
|
||||
{
|
||||
int i = 0;
|
||||
object value;
|
||||
string description;
|
||||
Description.Param param;
|
||||
Description.Param[] @params;
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
string shareRoot = @"\\messv02ecc1.ec.local\EC_EDA";
|
||||
string shareDirectory = string.Concat(shareRoot, @"\Staging\Pdsf\", cellName, @"\ExportAliases");
|
||||
Dictionary<string, List<Tuple<Description.Param, string, string, object>>> keyValuePairs = GetParameterInfo(logic, allowNull: false);
|
||||
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<Description.Param, 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 != Description.Param.String)
|
||||
stringBuilder.AppendLine($"\"{keyValuePair.Key}\";\"\";\"\";\"\";\"\";\"\";\"{i}\";\"{cellName}/{EquipmentElementName}/{keyValuePair.Key}\";\"\";\"{cellName}/{EquipmentElementName}/{_EventName.Value}\";\"\";\"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.Value}\";\"\";\"True\"");
|
||||
}
|
||||
}
|
||||
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> 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> GetIgnoreParameterNames(ILogic logic, Test test)
|
||||
{
|
||||
List<string> results = _ProcessDataDescription.GetIgnoreParameterNames(logic, this, test);
|
||||
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<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<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[0].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;
|
||||
}
|
||||
|
||||
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
Shared/Metrology/EventName.cs
Normal file
13
Shared/Metrology/EventName.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public enum EventName
|
||||
{
|
||||
FileRead,
|
||||
FileReadDaily,
|
||||
FileReadMonthly,
|
||||
FileReadVerification,
|
||||
FileReadWeekly
|
||||
}
|
||||
|
||||
}
|
46
Shared/Metrology/ILogic.cs
Normal file
46
Shared/Metrology/ILogic.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using Ifx.Eaf.EquipmentConnector.File.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public interface ILogic
|
||||
{
|
||||
|
||||
ILogic ShallowCopy();
|
||||
Logistics Logistics { get; }
|
||||
|
||||
void ConfigurationRestore();
|
||||
void CreateSelfDescription();
|
||||
void CreateSelfDescription(Dictionary<string, string> fileParameter, FileConnectorConfiguration configuration, ConfigDataBase configDataBase);
|
||||
void CreateSelfDescription(string equipmentElementName, EquipmentConnection? equipmentConnection, string cellName, string debugConfig, FileConnectorConfiguration configuration);
|
||||
bool Extract(string reportFullPath, string eventName);
|
||||
string GetConfigurationErrorTargetFileLocation();
|
||||
string GetConfigurationSourceFileLocation();
|
||||
string GetConfigurationTarget2FileLocation();
|
||||
string GetConfigurationTargetFileLocation();
|
||||
string GetConfigurationTargetFileName();
|
||||
Tuple<string, JsonElement?, List<FileInfo>> GetExtractResult(string reportFullPath, string eventName);
|
||||
object GetFilePathGeneratorInfo(string reportFullPath, bool isErrorFile);
|
||||
string GetReportFullPath(Dictionary<string, object> keyValuePairs);
|
||||
string GetTarget2FileLocation();
|
||||
void Move(string reportFullPath, Tuple<string, JsonElement?, List<FileInfo>> extractResults, Exception exception = null);
|
||||
string ReExtract(string searchDirectory, string sourceFileFilter);
|
||||
void ReflectionCreateSelfDescription(string equipmentElementName, int? input, string cellName, string debugConfig, string[] strings, bool[] booleans, long[] numbers, string[] enums);
|
||||
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
Shared/Metrology/MET08DDUPSFS6420.cs
Normal file
14
Shared/Metrology/MET08DDUPSFS6420.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08DDUPSFS6420
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
Tencor = Metrology.Test.Tencor
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
Shared/Metrology/MET08DDUPSP1TBI.cs
Normal file
14
Shared/Metrology/MET08DDUPSP1TBI.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08DDUPSP1TBI
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
SP1 = Metrology.Test.SP1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
Shared/Metrology/MET08RESIHGCV.cs
Normal file
14
Shared/Metrology/MET08RESIHGCV.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08RESIHGCV
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
HgCV = Metrology.Test.HgCV
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
Shared/Metrology/MET08RESIMAPCDE.cs
Normal file
14
Shared/Metrology/MET08RESIMAPCDE.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08RESIMAPCDE
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
CDE = Metrology.Test.CDE
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
Shared/Metrology/MET08THFTIRQS408M.cs
Normal file
14
Shared/Metrology/MET08THFTIRQS408M.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08THFTIRQS408M
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
BioRadQS408M = Metrology.Test.BioRadQS408M
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
14
Shared/Metrology/MET08THFTIRSTRATUS.cs
Normal file
14
Shared/Metrology/MET08THFTIRSTRATUS.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08THFTIRSTRATUS
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
BioRadStratus = Metrology.Test.BioRadStratus
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
23
Shared/Metrology/MET08XRDXPERTPROMRDXL.cs
Normal file
23
Shared/Metrology/MET08XRDXPERTPROMRDXL.cs
Normal file
@ -0,0 +1,23 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class MET08XRDXPERTPROMRDXL
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
XRDXY = Metrology.Test.XRDXY,
|
||||
XRDWeightedAverage = Metrology.Test.XRDWeightedAverage,
|
||||
MonthlyXRD = Metrology.Test.MonthlyXRD,
|
||||
WeeklyXRD = Metrology.Test.WeeklyXRD,
|
||||
WeeklyXRDAIcomp = Metrology.Test.WeeklyXRDAIcomp,
|
||||
WeeklyXRDFWHM002 = Metrology.Test.WeeklyXRDFWHM002,
|
||||
WeeklyXRDFWHM105 = Metrology.Test.WeeklyXRDFWHM105,
|
||||
WeeklyXRDSLStks = Metrology.Test.WeeklyXRDSLStks,
|
||||
WeeklyXRDXRR = Metrology.Test.WeeklyXRDXRR,
|
||||
XRDXRAY = Metrology.Test.XRDXRAY
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
36
Shared/Metrology/OISiViewer.cs
Normal file
36
Shared/Metrology/OISiViewer.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System;
|
||||
|
||||
namespace 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.EquipmentConnection, "&is_error_file=", isErrorFile);
|
||||
_WebClient.OpenRead(address);
|
||||
result = _WebClient.ResponseHeaders["Date"];
|
||||
_WebClient.CancelAsync();
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
115
Shared/Metrology/ProcessData.Duplicator.cs
Normal file
115
Shared/Metrology/ProcessData.Duplicator.cs
Normal file
@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class Duplicator
|
||||
{
|
||||
|
||||
public class Description : IProcessDataDescription
|
||||
{
|
||||
|
||||
public int Test { get; set; }
|
||||
public int Count { get; set; }
|
||||
public int Index { get; set; }
|
||||
//
|
||||
public string EventName { get; set; }
|
||||
public string NullData { get; set; }
|
||||
public string JobID { get; set; }
|
||||
public string Sequence { get; set; }
|
||||
public string MesEntity { get; set; }
|
||||
public string ReportFullPath { get; set; }
|
||||
public string ProcessJobID { get; set; }
|
||||
public string MID { get; set; }
|
||||
public string Date { get; set; } //2021-02-22
|
||||
//
|
||||
public object Data { get; set; }
|
||||
public object Parameters { get; set; }
|
||||
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"),
|
||||
//
|
||||
Data = nameof(Data),
|
||||
Parameters = nameof(Parameters)
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<IProcessDataDescription> GetDescription(ILogic logic, ConfigDataBase configDataBase, List<Test> tests, object payload)
|
||||
{
|
||||
List<IProcessDataDescription> results = new List<IProcessDataDescription>();
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
520
Shared/Metrology/ProcessDataStandardFormat.cs
Normal file
520
Shared/Metrology/ProcessDataStandardFormat.cs
Normal file
@ -0,0 +1,520 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public class ProcessDataStandardFormat
|
||||
{
|
||||
|
||||
public const string RecordStart = "RECORD_START";
|
||||
|
||||
public enum SearchFor
|
||||
{
|
||||
EquipmentIntegration = 1,
|
||||
BusinessIntegration = 2,
|
||||
SystemExport = 3,
|
||||
Archive = 4
|
||||
}
|
||||
|
||||
public static void MaybeWriteIncompletePDSF(ILogic logic, ConfigDataBase configDataBase, JsonElement jsonElement, string writePath, int count, bool isSource)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(writePath) && count > 0 && jsonElement.ValueKind == JsonValueKind.Array)
|
||||
{
|
||||
string text;
|
||||
string file;
|
||||
int columns = 0;
|
||||
string endOffset = "E#######T";
|
||||
string dataOffset = "D#######T";
|
||||
string headerOffset = "H#######T";
|
||||
string format = "MM/dd/yyyy HH:mm:ss";
|
||||
List<string> lines = new List<string>();
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
string directoryName = Path.GetFileNameWithoutExtension(writePath);
|
||||
string directory = string.Concat(writePath, @"\", configDataBase.EquipmentConnection);
|
||||
if (isSource)
|
||||
directory = string.Concat(directory, @"\Source");
|
||||
else
|
||||
directory = string.Concat(directory, @"\Target");
|
||||
if (!Directory.Exists(directory))
|
||||
Directory.CreateDirectory(directory);
|
||||
stringBuilder.Clear();
|
||||
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();
|
||||
foreach (JsonProperty jsonProperty in jsonElements[0].EnumerateObject())
|
||||
{
|
||||
columns += 1;
|
||||
stringBuilder.Append("\"").Append(jsonProperty.Name).Append("\"").Append('\t');
|
||||
}
|
||||
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"));
|
||||
lines.Add(string.Concat("LOGISTICS_1", '\t', "A_CHAMBER=;A_INFO=", configDataBase.GetEventName(), ";A_INFO2=", configDataBase.EquipmentConnection, ";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=", configDataBase.GetEventName(), ";B_INFO2=", configDataBase.EquipmentConnection, ";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");
|
||||
file = string.Concat(directory, @"\", logic.Logistics.JobID, "_", logic.Logistics.Sequence, ".ipdsf");
|
||||
stringBuilder.Clear();
|
||||
foreach (string line in lines)
|
||||
stringBuilder.AppendLine(line);
|
||||
text = stringBuilder.ToString();
|
||||
text = text.Replace(headerOffset, text.IndexOf("NUM_DATA_ROWS").ToString().PadLeft(9, '0')).
|
||||
Replace(dataOffset, text.IndexOf('"').ToString().PadLeft(9, '0')).
|
||||
Replace(endOffset, text.Length.ToString().PadLeft(9, '0'));
|
||||
File.WriteAllText(file, text);
|
||||
if (logic.Logistics.TotalSecondsSinceLastWriteTimeFromSequence > 600)
|
||||
{
|
||||
try { File.SetLastWriteTime(file, logic.Logistics.DateTimeFromSequence); } catch (Exception) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 = 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 value;
|
||||
string[] segments;
|
||||
string logistics = pdsf.Item1;
|
||||
string[] columns = pdsf.Item2;
|
||||
string[] bodyLines = pdsf.Item3;
|
||||
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 logistics = pdsf.Item1;
|
||||
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.Trim().Split('\t');
|
||||
for (int c = 1; c < segments.Length; c++)
|
||||
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 (var 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, ScopeInfo 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;
|
||||
}
|
||||
}
|
||||
line = lines[group[0]];
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
405
Shared/Metrology/ScopeInfo.cs
Normal file
405
Shared/Metrology/ScopeInfo.cs
Normal file
@ -0,0 +1,405 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace 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 string EquipmentElementName { get; private set; }
|
||||
public EquipmentConnection EquipmentConnection { get; private set; }
|
||||
|
||||
public ScopeInfo(ILogic logic, ConfigDataBase configDataBase, Test test)
|
||||
{
|
||||
EquipmentElementName = configDataBase.EquipmentElementName;
|
||||
EquipmentConnection = configDataBase.EquipmentConnection.Value;
|
||||
Enum = test;
|
||||
Test = test;
|
||||
TestValue = (int)test;
|
||||
string eventName = GetEventNameAndSetRemaining();
|
||||
if (eventName != configDataBase.GetEventName())
|
||||
{
|
||||
File.Move(logic.Logistics.ReportFullPath, Path.ChangeExtension(logic.Logistics.ReportFullPath, eventName));
|
||||
throw new Exception();
|
||||
}
|
||||
else if (configDataBase.EquipmentConnection.HasValue && configDataBase.EquipmentConnection.Value != EquipmentConnection)
|
||||
{
|
||||
File.Move(logic.Logistics.ReportFullPath, Path.ChangeExtension(logic.Logistics.ReportFullPath, EquipmentConnection.ToString()));
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
|
||||
public ScopeInfo(ILogic logic, ConfigDataBase configDataBase, Test test, string fileName, string queryFilter, string title = "", string html = "")
|
||||
{
|
||||
EquipmentElementName = configDataBase.EquipmentElementName;
|
||||
EquipmentConnection = configDataBase.EquipmentConnection.Value;
|
||||
Enum = test;
|
||||
Test = test;
|
||||
TestValue = (int)test;
|
||||
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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.MET08XRDXPERTPROMRDXL;
|
||||
eventName = EventName.FileRead;
|
||||
FileNameWithoutExtension = "xrd_iqs_NEW_01_WtAVG";
|
||||
Header = "Reactor;fDate;fRecipeName;Lot;pocketNumber;g4Scribe;Name;Value;Group";
|
||||
QueryFilter = "Al% Barrier WTAVG";
|
||||
Title = "XRD Weighted Average Data";
|
||||
HTML = @"GaN Epi Data\11 - xrd.html";
|
||||
break;
|
||||
case Test.MonthlyXRD:
|
||||
EquipmentConnection = EquipmentConnection.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:
|
||||
EquipmentConnection = EquipmentConnection.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.XRDXRAY:
|
||||
EquipmentConnection = EquipmentConnection.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(EquipmentConnection, " - (", Enum, "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
56
Shared/Metrology/Test.cs
Normal file
56
Shared/Metrology/Test.cs
Normal file
@ -0,0 +1,56 @@
|
||||
namespace Shared.Metrology
|
||||
{
|
||||
|
||||
public enum Test
|
||||
{
|
||||
AFMRoughness = 34,
|
||||
BioRadQS408M = 25,
|
||||
BioRadStratus = 26,
|
||||
BreakdownVoltageCenter = 0,
|
||||
BreakdownVoltageEdge = 1,
|
||||
BreakdownVoltageMiddle8in = 2,
|
||||
CandelaKlarfDC = 6,
|
||||
CandelaLaser = 36,
|
||||
CandelaProdU = 39,
|
||||
CandelaPSL = 38,
|
||||
CandelaVerify = 37,
|
||||
CDE = 24,
|
||||
CV = 3,
|
||||
DailyRPMAverage = 19,
|
||||
DailyRPMPLRatio = 20,
|
||||
DailyRPMXY = 18,
|
||||
Denton = 9,
|
||||
DiffusionLength = 45,
|
||||
Hall = 10,
|
||||
HgCV = 23,
|
||||
Lehighton = 13,
|
||||
Microscope = 46,
|
||||
MonthlyCV = 4,
|
||||
MonthlyHall = 11,
|
||||
MonthlyXRD = 32,
|
||||
Photoreflectance = 22,
|
||||
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,
|
||||
XRDXRAY = 47, //Largest
|
||||
XRDXY = 30
|
||||
}
|
||||
|
||||
}
|
24
Shared/Metrology/WS.Attachment.cs
Normal file
24
Shared/Metrology/WS.Attachment.cs
Normal file
@ -0,0 +1,24 @@
|
||||
namespace 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
Shared/Metrology/WS.Results.cs
Normal file
33
Shared/Metrology/WS.Results.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace 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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
128
Shared/Metrology/WS.cs
Normal file
128
Shared/Metrology/WS.cs
Normal file
@ -0,0 +1,128 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace 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")
|
||||
};
|
||||
System.Threading.CancellationToken cancellationToken;
|
||||
HttpResponseMessage httpResponseMessage = httpClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead, cancellationToken).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