453 lines
21 KiB
C#

using Adaptation.Shared;
using Adaptation.Shared.Metrology;
using log4net;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
namespace Adaptation.Helpers
{
public partial class ProcessData : IProcessData
{
public HgProbeFile Header { get; private set; }
public List<HgProbeDetail> Details { get; private set; }
private int _I;
private readonly ILog _Log;
private string _Data;
public ProcessData(ILogic logic, ConfigData configData, List<FileInfo> fileInfoCollection)
{
Header = null;
fileInfoCollection.Clear();
_I = 0;
_Data = string.Empty;
_Log = LogManager.GetLogger(typeof(ProcessData));
Details = new List<HgProbeDetail>();
Tuple<HgProbeFile, List<HgProbeDetail>> tuple = Parse(logic, configData, fileInfoCollection);
Details.AddRange(tuple.Item2);
Header = tuple.Item1;
}
public Tuple<string, JsonElement?, List<FileInfo>> GetResults(ILogic logic, ConfigDataBase configDataBase, List<FileInfo> fileInfoCollection)
{
Tuple<string, JsonElement?, List<FileInfo>> results;
if (!(configDataBase is ConfigData configData))
throw new Exception();
List<Test> tests = new List<Test>();
List<IProcessDataDescription> descriptions;
EventName eventName = configData.GetEventNameValue();
if (eventName == EventName.FileRead && Details.Any())
{
foreach (var item in Details)
tests.Add(Test.HgCV);
descriptions = configData.GetDescription(logic, tests, this);
}
else
throw new Exception();
if (!configData.EafHosted)
{
new FileRead.Description().GetDescription(logic, configData, tests, this);
}
if (tests.Count != descriptions.Count)
throw new Exception();
for (int i = 0; i < tests.Count; i++)
{
if (descriptions[i].Test != (int)tests[i])
throw new Exception();
}
string json;
if (descriptions[0] is Duplicator.Description)
{
List<Duplicator.Description> duplicatorDescriptions = (from l in descriptions select (Duplicator.Description)l).ToList();
json = JsonSerializer.Serialize(duplicatorDescriptions, duplicatorDescriptions.GetType());
}
else if (descriptions[0] is FileRead.Description)
{
List<FileRead.Description> fileReadDescriptions = (from l in descriptions select (FileRead.Description)l).ToList();
json = JsonSerializer.Serialize(fileReadDescriptions, fileReadDescriptions.GetType());
}
else
throw new Exception();
object @object = JsonSerializer.Deserialize<object>(json);
if (!(@object is JsonElement jsonElement))
throw new Exception();
results = new Tuple<string, JsonElement?, List<FileInfo>>(logic.Logistics.Logistics1[0], jsonElement, fileInfoCollection);
return results;
}
public static Dictionary<Test, List<Duplicator.Description>> GetKeyValuePairs(ConfigData configData, JsonElement jsonElement, List<Duplicator.Description> processDataDescriptions, bool extra = false)
{
Dictionary<Test, List<Duplicator.Description>> results = configData.GetKeyValuePairs(processDataDescriptions);
configData.CheckProcessDataDescription(results, extra);
return results;
}
public static List<FileRead.Description> GetProcessDataFileReadDescriptions(ConfigData configData, JsonElement jsonElement)
{
List<FileRead.Description> results = new List<FileRead.Description>();
List<IProcessDataDescription> processDataDescriptions = configData.GetIProcessDataDescriptions(jsonElement);
foreach (IProcessDataDescription processDataDescription in processDataDescriptions)
{
if (!(processDataDescription is FileRead.Description description))
continue;
results.Add(description);
}
return results;
}
public static string GetLines(ILogic logic, List<FileRead.Description> descriptions)
{
StringBuilder result = new StringBuilder();
return result.ToString();
}
internal static void PostOpenInsightMetrologyViewerAttachments(ILog log, ConfigData configData, Logistics logistics, DateTime dateTime, string logisticsSequenceMemoryDirectory, List<FileRead.Description> descriptions, string matchDirectory)
{
string[] pclFiles = Directory.GetFiles(matchDirectory, "*.pcl", SearchOption.TopDirectoryOnly);
if (pclFiles.Length != 1)
throw new Exception("Invalid source file count!");
string wsResultsMemoryFile = string.Concat(logisticsSequenceMemoryDirectory, @"\", nameof(WS.Results), ".json");
if (!File.Exists(wsResultsMemoryFile))
throw new Exception(string.Concat("Memory file <", wsResultsMemoryFile, "> doesn't exist!"));
string json = File.ReadAllText(wsResultsMemoryFile);
WS.Results metrologyWSRequest = JsonSerializer.Deserialize<WS.Results>(json);
long wsResultsHeaderID = metrologyWSRequest.HeaderID;
List<string> pdfFiles = new List<string>();
pdfFiles.AddRange(Directory.GetFiles(matchDirectory, "*.pdf_old", SearchOption.TopDirectoryOnly));
foreach (string pdfFile in pdfFiles)
File.Delete(pdfFile);
pdfFiles.Clear();
pdfFiles.AddRange(Directory.GetFiles(matchDirectory, "*.pdf", SearchOption.TopDirectoryOnly));
foreach (string pdfFile in pdfFiles)
File.Move(pdfFile, Path.ChangeExtension(pdfFile, ".pdf_old"));
pdfFiles.Clear();
foreach (string pclFile in pclFiles.OrderBy(l => l))
pdfFiles.Add(ConvertSourceFileToPdfWithChartData(configData, pclFile));
if (pdfFiles.Count == 0)
log.Debug("Invalid *.pdf file count!");
List<WS.Attachment> headerAttachments = new List<WS.Attachment> { new WS.Attachment(descriptions[0].HeaderUniqueId, "Data.pdf", pdfFiles[0]) };
WS.AttachFiles(configData.OpenInsightMetrogyViewerAPI, wsResultsHeaderID, headerAttachments, dataAttachments: null);
}
/// <summary>
/// Convert the raw data file to parsable file format - in this case from PCL to PDF
/// </summary>
/// <param name="sourceFile">source file to be converted to PDF</param>
/// <returns></returns>
private static string ConvertSourceFileToPdf(ConfigData configData, string sourceFile)
{
string result = Path.ChangeExtension(sourceFile, ".pdf");
if (!File.Exists(result))
{
//string arguments = string.Concat("-i \"", sourceFile, "\" -o \"", result, "\"");
string arguments = string.Concat("-dSAFER -dBATCH -dNOPAUSE -dFIXEDMEDIA -dFitPage -dAutoRotatePages=/All -dDEVICEWIDTHPOINTS=792 -dDEVICEHEIGHTPOINTS=612 -sOutputFile=\"", result, "\" -sDEVICE=pdfwrite \"", sourceFile, "\"");
//Process process = Process.Start(configData.LincPDFCFileName, arguments);
Process process = Process.Start(configData.GhostPCLFileName, arguments);
process.WaitForExit(30000);
if (!File.Exists(result))
throw new Exception("PDF file wasn't created");
}
return result;
}
/// <summary>
/// Convert the raw data file to parsable file format - in this case from PCL to PDF
/// </summary>
/// <param name="sourceFile">source file to be converted to PDF</param>
/// <returns></returns>
private static string ConvertSourceFileToPdfWithChartData(ConfigData configData, string sourceFile)
{
string result = Path.ChangeExtension(sourceFile, ".pdf");
if (!File.Exists(result))
{
string arguments = string.Concat("-i \"", sourceFile, "\" -o \"", result, "\"");
//string arguments = string.Concat("-dSAFER -dBATCH -dNOPAUSE -dFIXEDMEDIA -dFitPage -dAutoRotatePages=/All -dDEVICEWIDTHPOINTS=792 -dDEVICEHEIGHTPOINTS=612 -sOutputFile=\"", result, "\" -sDEVICE=pdfwrite \"", sourceFile, "\"");
Process process = Process.Start(configData.LincPDFCFileName, arguments);
//Process process = Process.Start(configData.GhostPCLFileName, arguments);
process.WaitForExit(30000);
if (!File.Exists(result))
throw new Exception("PDF file wasn't created");
}
return result;
}
private void ScanPast(string text)
{
int num = _Data.IndexOf(text, _I);
if (num > -1)
{
_I = num + text.Length;
}
else
{
_I = _Data.Length;
}
}
private string GetBefore(string text)
{
int num = _Data.IndexOf(text, _I);
string text2;
if (num > -1)
{
text2 = _Data.Substring(_I, num - _I);
_I = num + text.Length;
return text2.Trim();
}
text2 = _Data.Substring(_I);
_I = _Data.Length;
return text2.Trim();
}
private bool IsNullOrWhiteSpace(string text)
{
for (int i = 0; i < text.Length; i++)
{
if (!char.IsWhiteSpace(text[i]))
{
return false;
}
}
return true;
}
private bool IsBlankLine()
{
int num = _Data.IndexOf("\n", _I);
return IsNullOrWhiteSpace((num > -1) ? _Data.Substring(_I, num - _I) : _Data.Substring(_I));
}
private string GetToEOL()
{
return GetBefore("\n");
}
private string GetToken()
{
while (_I < _Data.Length && IsNullOrWhiteSpace(_Data.Substring(_I, 1)))
{
_I++;
}
int j;
for (j = _I; j < _Data.Length && !IsNullOrWhiteSpace(_Data.Substring(j, 1)); j++)
{
}
string text = _Data.Substring(_I, j - _I);
_I = j;
return text.Trim();
}
private Tuple<HgProbeFile, List<HgProbeDetail>> Parse(ILogic logic, ConfigData configData, List<FileInfo> fileInfoCollection)
{
Tuple<HgProbeFile, List<HgProbeDetail>> result;
string headerText;
string sourceFileNamePdf = ConvertSourceFileToPdf(configData, logic.Logistics.ReportFullPath);
fileInfoCollection.Add(new FileInfo(sourceFileNamePdf));
string altHeaderFileName = Path.ChangeExtension(logic.Logistics.ReportFullPath, ".txt");
if (File.Exists(altHeaderFileName))
{
headerText = File.ReadAllText(altHeaderFileName);
fileInfoCollection.Add(new FileInfo(altHeaderFileName));
}
else
{
//Pdfbox, IKVM.AWT.WinForms
org.apache.pdfbox.pdmodel.PDDocument pdfDocument = org.apache.pdfbox.pdmodel.PDDocument.load(sourceFileNamePdf);
org.apache.pdfbox.util.PDFTextStripper stripper = new org.apache.pdfbox.util.PDFTextStripper();
headerText = stripper.getText(pdfDocument);
pdfDocument.close();
File.AppendAllText(altHeaderFileName, headerText);
fileInfoCollection.Add(new FileInfo(altHeaderFileName));
}
List<HgProbeDetail> hgProbeDetails = new List<HgProbeDetail>();
HgProbeFile hgProbeFile = new HgProbeFile { JobID = logic.Logistics.JobID, MesEntity = logic.Logistics.MesEntity, Date = DateTime.Now.ToString() };
string h = string.Empty;
if (headerText.Contains("G A T E V O L T A G E"))
throw new Exception("Ignore: GATEVOLTAGE runs are not parsed.");
if (!string.IsNullOrEmpty(headerText))
{
headerText = headerText.Replace("box", "");
headerText = headerText.Replace("bar", "");
headerText = headerText.Replace("horiz", "");
headerText = headerText.Replace("center", "");
headerText = headerText.Replace("upper", "");
headerText = headerText.Replace("lower", "");
headerText = headerText.Replace("right", "");
headerText = headerText.Replace("left", "");
headerText = headerText.Replace("thin", "");
headerText = headerText.Replace("vertical", "");
headerText = headerText.Replace("line", "");
headerText = headerText.Replace("middle", "");
headerText = headerText.Replace("side", "");
headerText = headerText.Replace("top", ""); // This will change "Stop Voltage" to "S Voltage"
headerText = headerText.Replace("corner", "");
headerText = headerText.Replace("bottom", "");
headerText = headerText.Replace("ruleunder", "_");
headerText = headerText.Replace("@", "");
headerText = headerText.Replace("*", "");
_I = 0;
_Data = headerText;
_Log.Debug($"****MERCURY-DATA [002]= {headerText}");
ScanPast("Operator:");
hgProbeFile.Employee = GetBefore("Start Voltage:");
hgProbeFile.StartVoltage = GetBefore("V");
ScanPast("Wafer :");
hgProbeFile.Wafer = GetBefore("S Voltage :"); // This is actually "Stop Voltage"
hgProbeFile.StopVoltage = GetBefore("V");
ScanPast("Lot :");
if (headerText.Contains("Ramp Rate :"))
hgProbeFile.Lot = GetBefore("Ramp Rate :");
else if (headerText.Contains("Forward Rate :"))
hgProbeFile.Lot = GetBefore("Forward Rate :");
else if (headerText.Contains("Conduct Type:"))
hgProbeFile.Lot = GetBefore("Conduct Type:");
else
hgProbeFile.Lot = string.Empty;
// Remove illegal characters \/:*?"<>| found in the Lot.
hgProbeFile.Lot = Regex.Replace(hgProbeFile.Lot, @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]", "_").Split('\r')[0].Split('\n')[0];
hgProbeFile.RampRate = GetBefore("mV/sec");
ScanPast("Plan :");
hgProbeFile.Plan = GetBefore("G limit :");
//hgProbeFile.GLimit = GetBefore("S ");
hgProbeFile.GLimit = GetBefore("S");
hgProbeFile.Date = DateTime.Now.ToString();
ScanPast("Setup File:");
//hgProbeFile.SetupFile = GetBefore("O O");
hgProbeFile.SetupFile = GetBefore("O O");
ScanPast("Wafer size :");
hgProbeFile.WaferSize = GetBefore("mm");
ScanPast("Folder :");
//hgProbeFile.Folder = GetBefore("N N");
hgProbeFile.Folder = GetBefore("N N");
ScanPast("Ccomp : ");
hgProbeFile.Ccomp = GetBefore("pF");
ScanPast("Pattern :");
//hgProbeFile.Pattern = GetBefore("C C");
hgProbeFile.Pattern = GetBefore("C C");
ScanPast("Area:");
hgProbeFile.Area = GetBefore("cm2");
ScanPast("Cond Type :");
hgProbeFile.CondType = GetBefore("Rho Method:");
//hgProbeFile.RhoMethod = GetBefore("N N");
hgProbeFile.RhoMethod = GetBefore("N N");
ScanPast("Model :");
//hgProbeFile.Model = GetBefore("T T");
hgProbeFile.Model = GetBefore("T T");
ScanPast("Navg :");
hgProbeFile.NAvgMean = GetToken();
hgProbeFile.NAvgStdDev = GetToken();
hgProbeFile.NAvgRadialGradient = GetToken();
ScanPast("Nsl :");
hgProbeFile.NslMean = GetToken();
hgProbeFile.NslStdDev = GetToken();
hgProbeFile.NslRadialGradient = GetToken();
ScanPast("Vd :");
hgProbeFile.VdMean = GetToken();
hgProbeFile.VdStdDev = GetToken();
hgProbeFile.VdRadialGradient = GetToken();
ScanPast("Flat Z:");
hgProbeFile.FlatZMean = GetToken();
hgProbeFile.FlatZStdDev = GetToken();
hgProbeFile.FlatZRadialGradient = GetToken();
ScanPast("Rhoavg:");
hgProbeFile.RhoAvgMean = GetToken();
hgProbeFile.RhoAvgStdDev = GetToken();
hgProbeFile.RhoAvgRadialGradient = GetToken();
ScanPast("Rhosl :");
hgProbeFile.RhoslMean = GetToken();
hgProbeFile.RhoslStdDev = GetToken();
hgProbeFile.RhoslRadialGradient = GetToken();
ScanPast("Phase :");
hgProbeFile.PhaseMean = GetToken();
hgProbeFile.PhaseStdDev = GetToken();
hgProbeFile.PhaseRadialGradient = GetToken();
ScanPast("Grade :");
hgProbeFile.GradeMean = GetToken();
hgProbeFile.GradeStdDev = GetToken();
hgProbeFile.GradeRadialGradient = GetToken();
ScanPast("Rs :");
hgProbeFile.RsMean = GetToken();
hgProbeFile.RsStdDev = GetToken();
hgProbeFile.RsRadialGradient = GetToken();
string lot = hgProbeFile.Lot;
string[] segments = lot.Split('-');
if (segments.Length >= 1)
hgProbeFile.Reactor = segments[0];
if (segments.Length >= 2)
hgProbeFile.RDS = segments[1];
if (segments.Length >= 3)
{
string str = segments[2];
string[] segmentsB = str.Split('.');
if (segmentsB.Length >= 1)
hgProbeFile.PSN = segmentsB[0];
if (segmentsB.Length >= 2)
hgProbeFile.Layer = segmentsB[1];
}
if (segments.Length >= 4)
hgProbeFile.Zone = segments[3];
//ScanPast("Flat Z: Grade : % Flat Z: Grade : % Flat Z: Grade : %");
ScanPast("Flat Z: Grade : % Flat Z: Grade : % Flat Z: Grade : %");
string token = GetToken();
while (!string.IsNullOrEmpty(token))
{
HgProbeDetail hgProbeDetail = new HgProbeDetail { NAvg = token };
GetToEOL();
hgProbeDetail.Nsl = GetToken();
GetToEOL();
hgProbeDetail.Vd = GetToken();
GetToEOL();
hgProbeDetail.FlatZ = GetToken();
GetToEOL();
hgProbeDetail.RhoAvg = GetToken();
GetToEOL();
hgProbeDetail.Rhosl = GetToken();
GetToEOL();
hgProbeDetail.Phase = GetToken();
GetToEOL();
hgProbeDetail.Grade = GetToken();
hgProbeDetail.UniqueId = string.Concat("_Point-", hgProbeDetails.Count + 1);
hgProbeDetails.Add(hgProbeDetail);
GetToken();
GetToken();
GetToken();
GetToken();
token = GetToken();
//if (token.Contains("LincPDF") || token.Contains("MULTIPLE"))
if (token.Contains("MULTIPLE"))
{
//ScanPast("Flat Z: Grade : % Flat Z: Grade : % Flat Z: Grade : %");
//ScanPast("Flat Z: Grade : % Flat Z: Grade : % Flat Z: Grade : %");
ScanPast("Flat Z: Grade : % Flat Z: Grade : % Flat Z: Grade : %");
ScanPast("Flat Z: Grade : % Flat Z: Grade : % Flat Z: Grade : %");
token = GetToken();
}
}
}
hgProbeFile.UniqueId = string.Format("{0}_{1}_{2}", logic.Logistics.JobID, hgProbeFile.Lot, Path.GetFileNameWithoutExtension(logic.Logistics.ReportFullPath));
foreach (HgProbeDetail detail in hgProbeDetails)
{
detail.HeaderUniqueId = hgProbeFile.UniqueId;
detail.UniqueId = string.Concat(detail, detail.UniqueId);
}
fileInfoCollection.Add(new FileInfo(logic.Logistics.ReportFullPath));
result = new Tuple<HgProbeFile, List<HgProbeDetail>>(hgProbeFile, hgProbeDetails);
return result;
}
}
}