410 lines
18 KiB
C#
410 lines
18 KiB
C#
using Adaptation.Shared.Methods;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
|
|
namespace Adaptation.Shared;
|
|
|
|
public class ProcessDataStandardFormat
|
|
{
|
|
|
|
public enum SearchFor
|
|
{
|
|
EquipmentIntegration = 1,
|
|
BusinessIntegration = 2,
|
|
SystemExport = 3,
|
|
Archive = 4
|
|
}
|
|
|
|
public static string GetPDSFText(IFileRead fileRead, Logistics logistics, JsonElement[] jsonElements, string logisticsText)
|
|
{
|
|
string result;
|
|
if (jsonElements.Length == 0)
|
|
result = string.Empty;
|
|
else
|
|
{
|
|
int columns = 0;
|
|
List<string> lines;
|
|
string endOffset = "E#######T";
|
|
string dataOffset = "D#######T";
|
|
string headerOffset = "H#######T";
|
|
string format = "MM/dd/yyyy HH:mm:ss";
|
|
StringBuilder stringBuilder = new();
|
|
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');
|
|
for (int i = 0; i < jsonElements.Length;)
|
|
{
|
|
foreach (JsonProperty jsonProperty in jsonElements[0].EnumerateObject())
|
|
{
|
|
columns += 1;
|
|
_ = stringBuilder.Append('"').Append(jsonProperty.Name).Append('"').Append('\t');
|
|
}
|
|
break;
|
|
}
|
|
_ = stringBuilder.Remove(stringBuilder.Length - 1, 1);
|
|
lines.Add(stringBuilder.ToString());
|
|
for (int i = 0; i < jsonElements.Length; i++)
|
|
{
|
|
_ = stringBuilder.Clear();
|
|
_ = stringBuilder.Append("0.1").Append('\t');
|
|
_ = stringBuilder.Append('1').Append('\t');
|
|
_ = stringBuilder.Append('2').Append('\t');
|
|
foreach (JsonProperty jsonProperty in jsonElements[i].EnumerateObject())
|
|
_ = stringBuilder.Append(jsonProperty.Value).Append('\t');
|
|
_ = stringBuilder.Remove(stringBuilder.Length - 1, 1);
|
|
lines.Add(stringBuilder.ToString());
|
|
}
|
|
lines.Add(string.Concat("NUM_DATA_ROWS ", jsonElements.Length.ToString().PadLeft(9, '0')));
|
|
lines.Add(string.Concat("NUM_DATA_COLUMNS ", (columns + 3).ToString().PadLeft(9, '0')));
|
|
lines.Add("DELIMITER ;");
|
|
lines.Add(string.Concat("START_TIME_FORMAT ", format));
|
|
lines.Add(string.Concat("START_TIME ", logistics.DateTimeFromSequence.ToString(format))); //12/26/2019 15:22:44
|
|
lines.Add(string.Concat("LOGISTICS_COLUMN", '\t', "A_LOGISTICS"));
|
|
lines.Add(string.Concat("LOGISTICS_COLUMN", '\t', "B_LOGISTICS"));
|
|
if (!string.IsNullOrEmpty(logisticsText))
|
|
lines.Add(logisticsText);
|
|
else
|
|
{
|
|
lines.Add(string.Concat("LOGISTICS_1", '\t', "A_CHAMBER=;A_INFO=", fileRead.EventName, ";A_INFO2=", fileRead.EquipmentType, ";A_JOBID=", fileRead.CellInstanceName, ";A_MES_ENTITY=", fileRead.MesEntity, ";A_MID=", logistics.MID, ";A_NULL_DATA=", fileRead.NullData, ";A_PPID=NO_PPID;A_PROCESS_JOBID=", logistics.ProcessJobID, ";A_PRODUCT=;A_SEQUENCE=", logistics.Sequence, ";A_WAFER_ID=;"));
|
|
lines.Add(string.Concat("LOGISTICS_2", '\t', "B_CHAMBER=;B_INFO=", fileRead.EventName, ";B_INFO2=", fileRead.EquipmentType, ";B_JOBID=", fileRead.CellInstanceName, ";B_MES_ENTITY=", fileRead.MesEntity, ";B_MID=", logistics.MID, ";B_NULL_DATA=", fileRead.NullData, ";B_PPID=NO_PPID;B_PROCESS_JOBID=", logistics.ProcessJobID, ";B_PRODUCT=;B_SEQUENCE=", logistics.Sequence, ";B_WAFER_ID=;"));
|
|
lines.Add("END_HEADER");
|
|
}
|
|
_ = stringBuilder.Clear();
|
|
foreach (string line in lines)
|
|
_ = stringBuilder.AppendLine(line);
|
|
result = stringBuilder.ToString();
|
|
result = result.Replace(headerOffset, result.IndexOf("NUM_DATA_ROWS").ToString().PadLeft(9, '0')).
|
|
Replace(dataOffset, result.IndexOf('"').ToString().PadLeft(9, '0')).
|
|
Replace(endOffset, result.Length.ToString().PadLeft(9, '0'));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static Tuple<string, string[], string[]> GetLogisticsColumnsAndBody(string reportFullPath, string[] lines = null)
|
|
{
|
|
string segment;
|
|
List<string> body = new();
|
|
StringBuilder logistics = new();
|
|
lines ??= File.ReadAllLines(reportFullPath);
|
|
string[] segments;
|
|
if (lines.Length < 7)
|
|
segments = Array.Empty<string>();
|
|
else
|
|
segments = lines[6].Trim().Split('\t');
|
|
List<string> columns = new();
|
|
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.Length; 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.Length; 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[] results;
|
|
string logistics = pdsf.Item1;
|
|
string[] columns = pdsf.Item2;
|
|
string[] bodyLines = pdsf.Item3;
|
|
if (bodyLines.Length == 0 || !bodyLines[0].Contains('\t'))
|
|
results = JsonSerializer.Deserialize<JsonElement[]>("[]");
|
|
else
|
|
{
|
|
string value;
|
|
string[] segments;
|
|
List<string> lines = new();
|
|
StringBuilder stringBuilder = new();
|
|
foreach (string bodyLine in bodyLines)
|
|
{
|
|
_ = stringBuilder.Clear();
|
|
_ = 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("}");
|
|
lines.Add(stringBuilder.ToString());
|
|
}
|
|
string json = $"[{string.Join(",", lines)}]";
|
|
results = JsonSerializer.Deserialize<JsonElement[]>(json);
|
|
}
|
|
return results;
|
|
}
|
|
|
|
public static Dictionary<string, List<string>> GetDictionary(Tuple<string, string[], string[]> pdsf)
|
|
{
|
|
Dictionary<string, List<string>> results = new();
|
|
string[] segments;
|
|
string[] columns = pdsf.Item2;
|
|
string[] bodyLines = pdsf.Item3;
|
|
foreach (string column in columns)
|
|
results.Add(column, new List<string>());
|
|
foreach (string bodyLine in bodyLines)
|
|
{
|
|
segments = bodyLine.Split('\t');
|
|
for (int c = 1; c < segments.Length; c++)
|
|
{
|
|
if (c >= columns.Length)
|
|
continue;
|
|
results[columns[c]].Add(segments[c]);
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
public static Tuple<string, Dictionary<Test, Dictionary<string, List<string>>>> GetTestDictionary(Tuple<string, string[], string[]> pdsf)
|
|
{
|
|
Dictionary<Test, Dictionary<string, List<string>>> results = new();
|
|
List<string> collection;
|
|
string testColumn = nameof(Test);
|
|
Dictionary<string, List<string>> keyValuePairs = GetDictionary(pdsf);
|
|
if (!keyValuePairs.TryGetValue(testColumn, out collection))
|
|
throw new Exception();
|
|
int min;
|
|
int max;
|
|
Test testKey;
|
|
List<string> vs;
|
|
string columnKey;
|
|
Dictionary<Test, List<int>> tests = new();
|
|
for (int i = 0; i < collection.Count; i++)
|
|
{
|
|
if (Enum.TryParse(collection[i], out Test test))
|
|
{
|
|
if (!results.ContainsKey(test))
|
|
{
|
|
tests.Add(test, new List<int>());
|
|
results.Add(test, new Dictionary<string, List<string>>());
|
|
}
|
|
tests[test].Add(i);
|
|
}
|
|
}
|
|
foreach (KeyValuePair<Test, List<int>> testKeyValuePair in tests)
|
|
{
|
|
testKey = testKeyValuePair.Key;
|
|
min = testKeyValuePair.Value.Min();
|
|
max = testKeyValuePair.Value.Max() + 1;
|
|
foreach (KeyValuePair<string, List<string>> keyValuePair in keyValuePairs)
|
|
results[testKey].Add(keyValuePair.Key, new List<string>());
|
|
foreach (KeyValuePair<string, List<string>> keyValuePair in keyValuePairs)
|
|
{
|
|
vs = keyValuePair.Value;
|
|
columnKey = keyValuePair.Key;
|
|
for (int i = min; i < max; i++)
|
|
{
|
|
if (vs.Count > i)
|
|
results[testKey][columnKey].Add(vs[i]);
|
|
else
|
|
results[testKey][columnKey].Add(string.Empty);
|
|
}
|
|
}
|
|
}
|
|
return new Tuple<string, Dictionary<Test, Dictionary<string, List<string>>>>(pdsf.Item1, results);
|
|
}
|
|
|
|
private static string GetString(SearchFor searchFor, bool addSpaces, char separator = ' ')
|
|
{
|
|
if (!addSpaces)
|
|
return string.Concat(((int)searchFor).ToString().PadLeft(2, '0'), searchFor);
|
|
else
|
|
return string.Concat(((int)searchFor).ToString().PadLeft(2, '0'), separator, searchFor.ToString().Replace("In", string.Concat(separator, "In")).Replace("Ex", string.Concat(separator, "Ex")));
|
|
}
|
|
|
|
public static string EquipmentIntegration(bool addSpaces = true, char separator = ' ') => GetString(SearchFor.EquipmentIntegration, addSpaces, separator);
|
|
|
|
public static string BusinessIntegration(bool addSpaces = true, char separator = ' ') => GetString(SearchFor.BusinessIntegration, addSpaces, separator);
|
|
|
|
public static string SystemExport(bool addSpaces = true, char separator = ' ') => GetString(SearchFor.SystemExport, addSpaces, separator);
|
|
|
|
public static string Archive(bool addSpaces = true, char separator = ' ') => GetString(SearchFor.Archive, addSpaces, separator);
|
|
|
|
public static string GetLines(Logistics logistics, Properties.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();
|
|
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();
|
|
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.Count == 0)
|
|
{
|
|
_ = line.Remove(line.Length - 1, 1);
|
|
_ = result.AppendLine(line.ToString());
|
|
}
|
|
}
|
|
return result.ToString();
|
|
}
|
|
|
|
public static List<string> PDSFToFixedWidth(string reportFullPath)
|
|
{
|
|
List<string> results = new();
|
|
if (!File.Exists(reportFullPath))
|
|
throw new Exception();
|
|
int[] group;
|
|
string line;
|
|
int startsAt = 0;
|
|
string[] segments;
|
|
int? currentGroup = null;
|
|
char inputSeparator = '\t';
|
|
char outputSeparator = '\t';
|
|
List<int> vs = new();
|
|
List<int[]> groups = new();
|
|
string[] lines = File.ReadAllLines(reportFullPath);
|
|
StringBuilder stringBuilder = new();
|
|
for (int i = 0; i < lines.Length; i++)
|
|
{
|
|
if (string.IsNullOrEmpty(lines[i]))
|
|
continue;
|
|
segments = lines[i].Split(inputSeparator);
|
|
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(inputSeparator).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(inputSeparator);
|
|
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(inputSeparator);
|
|
for (int s = 0; s < segments.Length; s++)
|
|
{
|
|
if (vs[s] < segments[s].Length)
|
|
vs[s] = segments[s].Length;
|
|
}
|
|
}
|
|
_ = stringBuilder.Clear();
|
|
for (int s = 0; s < segments.Length; s++)
|
|
_ = stringBuilder.Append((s + 1).ToString().PadLeft(vs[s], ' ')).Append(outputSeparator);
|
|
_ = 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(inputSeparator);
|
|
for (int s = 0; s < segments.Length; s++)
|
|
_ = stringBuilder.Append(segments[s].PadLeft(vs[s], ' ')).Append(outputSeparator);
|
|
_ = stringBuilder.Remove(stringBuilder.Length - 1, 1);
|
|
results.Add(stringBuilder.ToString());
|
|
}
|
|
results.Add(string.Empty);
|
|
}
|
|
return results;
|
|
}
|
|
|
|
} |