using Adaptation.Shared.Metrology; using System; using System.Collections.Generic; using System.Linq; namespace Adaptation.Shared { public class ExtractResult { public object ProcessData { get; internal set; } public long LastTicksDuration { get; private set; } public long BreakAfterSeconds { get; private set; } public Enum[] EnumColumns { get; protected set; } public List SourceFiles { get; private set; } public Column[] PairedColumns { get; protected set; } public Dictionary> Headers { get; protected set; } public Dictionary> Details { get; protected set; } public Dictionary> Parameters { get; protected set; } public Dictionary> ExtendedParameters { get; protected set; } public Dictionary> DatabaseHeaders { get; protected set; } public Dictionary> DatabaseDetails { get; protected set; } public Dictionary> RowColumns { get; protected set; } public Dictionary>> IgnoreIndeices { get; protected set; } public Dictionary> LogisticsColumns { get; protected set; } public ExtractResult(ExtractResult extractResult, long breakAfterSeconds, Enum[] enumColumns, Column[] pairedColumns) { if (enumColumns is null) enumColumns = new Enum[] { }; if (pairedColumns is null) pairedColumns = new Column[] { }; ProcessData = null; EnumColumns = enumColumns; PairedColumns = pairedColumns; SourceFiles = new List(); if (!(extractResult is null) && !(extractResult.SourceFiles is null)) SourceFiles.AddRange(extractResult.SourceFiles); BreakAfterSeconds = breakAfterSeconds; List headers = new List(); List details = new List(); List parameters = new List(); List databaseHeaders = new List(); List databaseDetails = new List(); UpdateLastTicksDuration(breakAfterSeconds * 10000000); Common(headers, details, parameters, databaseHeaders, databaseDetails); } private void Common(List headers, List details, List parameters, List databaseHeaders, List databaseDetails) { Headers = new Dictionary>(); Details = new Dictionary>(); Parameters = new Dictionary>(); ExtendedParameters = new Dictionary>(); DatabaseHeaders = new Dictionary>(); DatabaseDetails = new Dictionary>(); IgnoreIndeices = new Dictionary>>(); LogisticsColumns = new Dictionary>(); foreach (var item in headers) Headers.Add(item, new List()); foreach (var item in details) Details.Add(item, new List()); foreach (var item in parameters) Parameters.Add(item, new List()); foreach (var item in parameters) ExtendedParameters.Add(item, new List()); foreach (var item in databaseHeaders) DatabaseHeaders.Add(item, new List()); foreach (var item in databaseDetails) DatabaseDetails.Add(item, new List()); Array array; array = Enum.GetValues(typeof(Description.RowColumn)); RowColumns = new Dictionary>(); foreach (Description.RowColumn item in array) RowColumns.Add(item, new List()); array = Enum.GetValues(typeof(Description.LogisticsColumn)); foreach (Description.LogisticsColumn item in array) LogisticsColumns.Add(item, new List()); } internal void Reset() { ProcessData = null; SourceFiles.Clear(); List headers = new List(); List details = new List(); List parameters = new List(); List databaseHeaders = new List(); List databaseDetails = new List(); foreach (var item in Headers) headers.Add(item.Key); foreach (var item in Details) details.Add(item.Key); foreach (var item in Parameters) parameters.Add(item.Key); foreach (var item in DatabaseHeaders) databaseHeaders.Add(item.Key); foreach (var item in DatabaseDetails) databaseDetails.Add(item.Key); Common(headers, details, parameters, databaseHeaders, databaseDetails); } public ExtractResult ShallowCopy() { return (ExtractResult)MemberwiseClone(); } internal void HeadersAddRange(Enum column) { Headers.Add(column, new List()); } internal void HeadersAddRange(params Enum[] columns) { foreach (var item in columns) Headers.Add(item, new List()); } internal void HeadersAddRange(List columns) { foreach (var item in columns) Headers.Add(item, new List()); } internal void DetailsAddRange(Enum column) { Details.Add(column, new List()); } internal void DetailsAddRange(params Enum[] columns) { foreach (var item in columns) Details.Add(item, new List()); } internal void DetailsAddRange(List columns) { foreach (var item in columns) Details.Add(item, new List()); } internal void ParametersAddRange(Enum column) { Parameters.Add(column, new List()); } internal void ParametersAddRange(params Enum[] columns) { foreach (var item in columns) Parameters.Add(item, new List()); } internal void ParametersAddRange(List columns) { foreach (var item in columns) Parameters.Add(item, new List()); } internal void DatabaseHeadersAddRange(Enum column) { DatabaseHeaders.Add(column, new List()); } internal void DatabaseHeadersAddRange(params Enum[] columns) { foreach (var item in columns) DatabaseHeaders.Add(item, new List()); } internal void DatabaseHeadersAddRange(List columns) { foreach (var item in columns) DatabaseHeaders.Add(item, new List()); } internal void DatabaseDetailsAddRange(Enum column) { DatabaseDetails.Add(column, new List()); } internal void DatabaseDetailsAddRange(params Enum[] columns) { foreach (var item in columns) DatabaseDetails.Add(item, new List()); } internal void DatabaseDetailsAddRange(List columns) { foreach (var item in columns) DatabaseDetails.Add(item, new List()); } internal int GetCount() { int result = 0; List counts = new List { RowColumns[Description.RowColumn.Test].Count() }; foreach (var item in Headers) counts.Add(item.Value.Count()); foreach (var item in Details) counts.Add(item.Value.Count()); foreach (var item in Parameters) counts.Add(item.Value.Count()); foreach (var item in DatabaseHeaders) counts.Add(item.Value.Count()); foreach (var item in DatabaseDetails) counts.Add(item.Value.Count()); result = counts.Max(); if (counts.Distinct().Count() != 1) throw new Exception(); return result; } private Dictionary> Merge(List>> keyValuePairs) { Dictionary> results = new Dictionary>(); foreach (var element in keyValuePairs) results.Add(element.Key, element.Value); return results; } private List>> GetAllColumnKeyValuePairs() { List>> results = new List>>(); foreach (var item in Headers) results.Add(new KeyValuePair>(item.Key, item.Value)); foreach (var item in Details) results.Add(new KeyValuePair>(item.Key, item.Value)); foreach (var item in Parameters) results.Add(new KeyValuePair>(item.Key, item.Value)); foreach (var item in DatabaseHeaders) results.Add(new KeyValuePair>(item.Key, item.Value)); foreach (var item in DatabaseDetails) results.Add(new KeyValuePair>(item.Key, item.Value)); return results; } internal Dictionary> GetAllColumnCollection() { Dictionary> results; if (!EnumColumns.Any()) { List>> keyValuePairs = GetAllColumnKeyValuePairs(); results = Merge(keyValuePairs); } else { results = new Dictionary>(); foreach (var item in EnumColumns) results.Add(item, new List()); foreach (var item in PairedColumns) results.Add(item, new List()); foreach (var item in Headers) results[item.Key].AddRange(item.Value); foreach (var item in Details) results[item.Key].AddRange(item.Value); foreach (var item in Parameters) results[item.Key].AddRange(item.Value); foreach (var item in DatabaseHeaders) results[item.Key].AddRange(item.Value); foreach (var item in DatabaseDetails) results[item.Key].AddRange(item.Value); int count = GetCount(); foreach (var keyValuePair in results) { for (int i = keyValuePair.Value.Count; i < count; i++) results[keyValuePair.Key].Add(string.Empty); } } return results; } private Dictionary Merge(List> keyValuePairs) { Dictionary results = new Dictionary(); foreach (var element in keyValuePairs) results.Add(element.Key, element.Value); return results; } private List> GetAllColumnKeyValuePairs(int? i) { List> results = new List>(); if (i.HasValue) { foreach (var item in Headers) results.Add(new KeyValuePair(item.Key, item.Value[i.Value])); foreach (var item in Details) results.Add(new KeyValuePair(item.Key, item.Value[i.Value])); foreach (var item in Parameters) results.Add(new KeyValuePair(item.Key, item.Value[i.Value])); foreach (var item in DatabaseHeaders) results.Add(new KeyValuePair(item.Key, item.Value[i.Value])); foreach (var item in DatabaseDetails) results.Add(new KeyValuePair(item.Key, item.Value[i.Value])); } return results; } internal Dictionary GetAllColumnCollection(int? i) { Dictionary results; List> keyValuePairs = GetAllColumnKeyValuePairs(i); results = Merge(keyValuePairs); return results; } private List>> GetToolHeadersAndDatabaseHeadersColumnKeyValuePairs() { List>> results = new List>>(); foreach (var item in Headers) results.Add(new KeyValuePair>(item.Key, item.Value)); foreach (var item in DatabaseHeaders) results.Add(new KeyValuePair>(item.Key, item.Value)); return results; } internal Dictionary> GetToolHeadersAndDatabaseHeadersCollection() { Dictionary> results; List>> keyValuePairs = GetToolHeadersAndDatabaseHeadersColumnKeyValuePairs(); results = Merge(keyValuePairs); return results; } private List>> GetToolDetailsAndDatabaseDetailsColumnKeyValuePairs() { List>> results = new List>>(); foreach (var item in Details) results.Add(new KeyValuePair>(item.Key, item.Value)); foreach (var item in Parameters) results.Add(new KeyValuePair>(item.Key, item.Value)); foreach (var item in DatabaseDetails) results.Add(new KeyValuePair>(item.Key, item.Value)); return results; } internal Dictionary> GetToolDetailsAndDatabaseDetailsCollection() { Dictionary> results; List>> keyValuePairs = GetToolDetailsAndDatabaseDetailsColumnKeyValuePairs(); results = Merge(keyValuePairs); return results; } internal Dictionary> GetTests() { Dictionary> results = new Dictionary>(); Test test; for (int i = 0; i < RowColumns[Description.RowColumn.Test].Count; i++) { test = (Test)RowColumns[Description.RowColumn.Test][i]; if (!results.ContainsKey(test)) results.Add(test, new List()); results[test].Add(i); } return results; } internal void FillIn(string nullData, int count, Enum[] currentColumns) { foreach (Enum column in Headers.Keys) { for (int i = Headers[column].Count(); i < count; i++) Headers[column].Add(nullData); } foreach (Enum column in Details.Keys) { for (int i = Details[column].Count(); i < count; i++) Details[column].Add(nullData); } if (!(currentColumns is null)) { foreach (Enum column in currentColumns) { for (int i = Parameters[column].Count(); i < count; i++) Parameters[column].Add(nullData); } } foreach (Enum column in Parameters.Keys) { for (int i = Parameters[column].Count(); i < count; i++) Parameters[column].Add(string.Empty); } foreach (Enum column in DatabaseHeaders.Keys) { for (int i = DatabaseHeaders[column].Count(); i < count; i++) DatabaseHeaders[column].Add(string.Empty); } foreach (Enum column in DatabaseDetails.Keys) { for (int i = DatabaseDetails[column].Count(); i < count; i++) DatabaseDetails[column].Add(string.Empty); } if (RowColumns[Description.RowColumn.Count].Count() != RowColumns[Description.RowColumn.Test].Count()) { count = RowColumns[Description.RowColumn.Test].Count(); RowColumns[Description.RowColumn.Count].Clear(); for (int i = 0; i < count; i++) RowColumns[Description.RowColumn.Count].Add(count); } } internal void SetCollections(Logistics logistics, Dictionary>> rawData) { Array array; Column? column; bool recordStartPresent = false; Description.RowColumn? rowColumn; Description.LogisticsColumn? logisticsColumn; array = Enum.GetValues(typeof(Description.RowColumn)); Dictionary headers = new Dictionary(); Dictionary details = new Dictionary(); Dictionary parameters = new Dictionary(); Dictionary databaseHeaders = new Dictionary(); Dictionary databaseDetails = new Dictionary(); Dictionary> rowColumns = new Dictionary>(); foreach (var item in Headers) headers.Add(item.Key.ToString(), item.Key); foreach (var item in Details) headers.Add(item.Key.ToString(), item.Key); foreach (var item in Parameters) headers.Add(item.Key.ToString(), item.Key); foreach (var item in DatabaseHeaders) headers.Add(item.Key.ToString(), item.Key); foreach (var item in DatabaseDetails) headers.Add(item.Key.ToString(), item.Key); foreach (Description.RowColumn item in array) rowColumns.Add(item, new List()); foreach (var element in rawData) { foreach (var item in element.Value) { column = null; rowColumn = null; logisticsColumn = null; if (item.Key == "Time") continue; else if (item.Key == "A_LOGISTICS") continue; else if (item.Key == "B_LOGISTICS") continue; else if (item.Key == "EventId") continue; else if (item.Key == ProcessDataStandardFormat.RecordStart) { recordStartPresent = true; continue; } if (Enum.TryParse(item.Key, out Column columnTry)) column = columnTry; else { if (Enum.TryParse(item.Key, out Description.LogisticsColumn logisticsColumnTry)) logisticsColumn = logisticsColumnTry; else { if (Enum.TryParse(item.Key, out Description.RowColumn rowColumnTry)) rowColumn = rowColumnTry; } } if (rowColumn.HasValue) rowColumns[rowColumn.Value].AddRange(item.Value); else if (logisticsColumn.HasValue) LogisticsColumns[logisticsColumn.Value].AddRange(item.Value); else if (column.HasValue) { if (Headers.ContainsKey(column.Value)) Headers[column.Value].AddRange(item.Value); else if (Details.ContainsKey(column.Value)) Details[column.Value].AddRange(item.Value); else if (Parameters.ContainsKey(column.Value)) Parameters[column.Value].AddRange(item.Value); else if (DatabaseHeaders.ContainsKey(column.Value)) DatabaseHeaders[column.Value].AddRange(item.Value); else if (DatabaseDetails.ContainsKey(column.Value)) DatabaseDetails[column.Value].AddRange(item.Value); else { if (!recordStartPresent) throw new Exception(); } } else { if (headers.ContainsKey(item.Key)) Headers[headers[item.Key]].AddRange(item.Value); else if (details.ContainsKey(item.Key)) Details[details[item.Key]].AddRange(item.Value); else if (parameters.ContainsKey(item.Key)) Parameters[parameters[item.Key]].AddRange(item.Value); else if (databaseHeaders.ContainsKey(item.Key)) DatabaseHeaders[databaseHeaders[item.Key]].AddRange(item.Value); else if (databaseDetails.ContainsKey(item.Key)) DatabaseDetails[databaseDetails[item.Key]].AddRange(item.Value); else { if (!recordStartPresent) throw new Exception(); } } } } foreach (var element in rowColumns) { for (int i = 0; i < element.Value.Count(); i++) { int.TryParse(element.Value[i], out int rowColumnTry); RowColumns[element.Key].Add(rowColumnTry); } } array = Enum.GetValues(typeof(Description.RowColumn)); foreach (Description.RowColumn item in array) { if (!RowColumns.ContainsKey(item)) throw new Exception(); } array = Enum.GetValues(typeof(Description.LogisticsColumn)); foreach (Description.LogisticsColumn item in array) { if (!LogisticsColumns.ContainsKey(item)) throw new Exception(); } int count = rowColumns[Description.RowColumn.Test].Count(); foreach (var element in DatabaseHeaders) { for (int i = element.Value.Count(); i < count; i++) element.Value.Add(string.Empty); } foreach (var element in DatabaseDetails) { for (int i = element.Value.Count(); i < count; i++) element.Value.Add(string.Empty); } string nullData; if (logistics.NullData is null) nullData = string.Empty; else nullData = logistics.NullData.ToString(); Dictionary> keyValuePairs; foreach (Test key in rawData.Keys) { IgnoreIndeices.Add(key, new Dictionary>()); for (int g = 1; g < 4; g++) { switch (g) { case 1: keyValuePairs = Details; break; case 2: keyValuePairs = Parameters; break; case 3: keyValuePairs = DatabaseDetails; break; default: throw new Exception(); } foreach (var element in keyValuePairs) { IgnoreIndeices[key].Add(element.Key, new List()); if (!element.Value.Any()) { for (int i = 0; i < RowColumns[Description.RowColumn.Test].Count(); i++) { IgnoreIndeices[key][element.Key].Add(i); element.Value.Add(string.Empty); } } else { for (int i = 0; i < element.Value.Count(); i++) { if (RowColumns[Description.RowColumn.Test][i] == (int)key) { if (string.IsNullOrEmpty(element.Value[i])) IgnoreIndeices[key][element.Key].Add(i); else if (!(logistics.NullData is null) && element.Value[i] == nullData) IgnoreIndeices[key][element.Key].Add(i); } } } } } } if (recordStartPresent) FillIn(string.Empty, RowColumns[Description.RowColumn.Test].Count(), currentColumns: null); GetCount(); } internal void UpdateLastTicksDuration(long ticksDuration) { if (ticksDuration < 50000000) ticksDuration = 50000000; LastTicksDuration = (long)Math.Ceiling(ticksDuration * .667); } private string GetTupleFile(Logistics logistics, ScopeInfo scopeInfo, string duplicateDirectory) { string result; string rds; string dateValue; string datePlaceholder; string[] segments = logistics.MID.Split('-'); if (segments.Length < 2) rds = "%RDS%"; else rds = segments[1]; segments = scopeInfo.FileName.Split(new string[] { "DateTime:" }, StringSplitOptions.RemoveEmptyEntries); if (segments.Length == 0) result = string.Concat(duplicateDirectory, @"\", scopeInfo.FileNameWithoutExtension.Replace("%RDS%", rds)); else { datePlaceholder = "%DateTime%"; segments = segments[1].Split('%'); dateValue = logistics.DateTimeFromSequence.ToString(segments[0]); foreach (string segment in scopeInfo.FileName.Split('%')) { if (!segment.Contains(segments[0])) continue; datePlaceholder = string.Concat('%', segment, '%'); } result = string.Concat(duplicateDirectory, @"\", scopeInfo.FileName.Replace("%RDS%", rds).Replace(datePlaceholder, dateValue)); } if (result.Contains('%')) throw new Exception("Placeholder exists!"); return result; } internal void AutoAdd(Enum key, string value) { if (Headers.ContainsKey(key)) Headers[key].Add(value); else if (Details.ContainsKey(key)) Details[key].Add(value); else if (Parameters.ContainsKey(key)) Parameters[key].Add(value); else if (DatabaseHeaders.ContainsKey(key)) DatabaseHeaders[key].Add(value); else if (DatabaseDetails.ContainsKey(key)) DatabaseDetails[key].Add(value); else throw new Exception(); } } }