Files

1518 lines
82 KiB
C#
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
/*
* TDAS.File.Reader.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using DTS.Common.Enums;
using DTS.Common.Enums.DASFactory;
using DTS.Common.Enums.Sensors;
using DTS.Common.Utilities;
using DTS.Common.Utilities.Logging;
namespace DTS.Serialization.TDAS
{
// *** see TDAS.File.cs ***
public partial class File
{ ///
/// <summary>
/// Utility object for serializing <see cref="DTS.Serialization.Test"/>s to disk.
/// </summary>
///
public partial class Reader : Reader<File>, IReader<Test>
{ ///
/// <summary>
/// Initialize an instance of the File.Reader class.
/// </summary>
///
/// <param name="fileType">
/// The <see cref="DTS.Serialization.TDAS.File"/>-type this deserializer is associated with.
/// </param>
///
public Reader(File fileType)
: base(fileType)
{
}
///// <summary>
///// Notify <see cref="DTS.Serialization.BeginEventHandler"/> subscribers that the write
///// is starting.
///// </summary>
//public event BeginEventHandler OnBegin;
///// <summary>
///// Notify <see cref="DTS.Serialization.EndEventHandler"/> subscribers that the write
///// is finished.
///// </summary>
//public event EndEventHandler OnEnd;
///// <summary>
///// Notify <see cref="DTS.Serialization.TickEventHandler"/> subscribers that we are one
///// tick closer to write completion.
///// </summary>
//public event TickEventHandler OnTick;
/// <summary>
/// Indicates the type of read event that is represented by the
/// <see cref="DTS.Serialization.Files.Reader.EventHandler"/> that has received it.
/// </summary>
public enum Event
{
NumberOfFilesDetermined,
SingleFileReadComplete,
FullReadComplete,
}
/// <summary>
/// Handler for read events.
/// </summary>
///
/// <param name="Event">
/// Indicates the type of <see cref="DTS.Serialization.SliceRaw.File.Reader.Event"/> that is
/// represented by this invocation of EventHandler.
/// </param>
///
/// <param name="numFiles">
/// The <see cref="int"/> number of files to be generated by the file read process.
/// It should match the number of SliceRaw.File.Reader.Event.SingleFileReadComplete events
/// that will be received during the full write.
/// </param>
///
public delegate void EventHandler(Event readEvent,
int numFiles);
/// <summary>
/// Get a complete list of test files in the specified directory.
/// </summary>
///
/// <param name="directory">
/// The name <see cref="string"/> of the directory to be scoured for test
/// files.
/// </param>
///
/// <returns>
/// A <see cref="List"/> of filename <see cref="strings"/> naming all test
/// files in the specified directory.
/// </returns>
///
private List<string> GetChannelFilenames(string directory)
{
try
{
var channelFilenames = new List<string>(Directory.GetFiles(directory, "*" + ChannelFileExtension));
channelFilenames.Sort(ChFileCompare);
return channelFilenames;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting channel filenames", ex);
}
}
/// <summary>
/// Get full name of test serialization file.
/// </summary>
///
/// <param name="directory">
/// The <see cref="string"/> representation of the directory to be searched for test files.
/// </param>
///
/// <returns>
/// The <see cref="string"/> representation of the found test filename.
/// </returns>
///
private string GetTestFilename(string directory)
{
try
{
if (null == directory)
throw new ArgumentNullException("cannot get test filename from null directory");
if (null == TestFileExtension)
throw new ArgumentException("cannot get test filename with null extension");
var testFiles = Directory.GetFiles(directory, "*" + TestFileExtension);
//Remove any found that aren't just ".TLF" (for example, ".TLF PreTest Backup")
var testFilesList = testFiles.ToList<string>();
foreach (var testFile in testFiles)
{
if (testFile.LastIndexOf('.') < testFile.Length - 4)
{
testFilesList.Remove(testFile);
}
}
if (testFilesList.Count < 1)
throw new MissingFileException("Could not find required file " + "\"" + directory + TestFileExtension + "\"");
if (testFilesList.Count > 1)
throw new TooManyFilesException("Found " + testFiles.Length.ToString() + " \"" + TestFileExtension + "\" " + " files in directory \"" + directory + "\"; there should be only 1");
return testFilesList[0];
}
catch (System.Exception ex)
{
//throw new TDAS.File.Reader.Exception(ex.Message, ex);
throw new UserException(ex.Message);
}
}
/// <summary>
/// Perform read test serialization from it's containing file.
/// </summary>
///
/// <param name="path">
/// The <see cref="string"/> representation of the pathname of the base
/// directory containing the test file.
/// </param>
///
/// <returns>
/// The <see cref="string"/> serialization contained by the specified file.
/// </returns>
///
private string ReadTestStringFromFile(string path)
{
try
{
//APILogger.Log("reading 65 ", path);
using (var mutex = new System.Threading.Mutex(false, path.Replace(Path.DirectorySeparatorChar, '_')))
{
while (!mutex.WaitOne(50, false)) { System.Threading.Thread.Sleep(5); }
try
{
using (var reader = new StreamReader(path))
try { return reader.ReadToEnd(); }
catch (System.Exception ex) { throw new Exception("encountered problem reading filestream to end", ex); }
}
finally { mutex.ReleaseMutex(); }
}
}
catch (System.Exception ex)
{
throw new Exception("encountered problem reading test string from file " + (null != path ? "\"" + path + "\"" : "<<NULL>>"), ex);
}
}
/// <summary>
/// Deserialize the test structure contained in the specified serialization string.
/// </summary>
///
/// <param name="serialization">
/// The <see cref="string"/> serialization from whence the test will be extracted
/// and instantiated.
/// </param>
///
/// <returns>
/// The <see cref="DTS.Serialization.Test"/> represented by specified serialization
/// string.
/// </returns>
///
readonly Dictionary<string, string[]> rackLookup = new Dictionary<string, string[]>();
private Test DeserializeTestFromTLF(string testFileName)
{
try
{
if (null == testFileName)
throw new ArgumentNullException("cannot deserialize test from null string");
var _test = new Test();
using (var reader = new StreamReader(testFileName))
{
var allText = reader.ReadToEnd();
//string delimiter = "<?xml version=";
var delimiter = "\r\n";
var delimiterArray = new string[] { delimiter };
var allTextArray = allText.Split(delimiterArray, StringSplitOptions.None); //.RemoveEmptyEntries);
var stringNumber = 0;
_test = new Test();
if (allTextArray[1].Contains('.'))
{
_test.Id = allTextArray[1].Remove(allTextArray[1].IndexOf('.'));
}
else
{
_test.Id = allTextArray[1];
}
_test.Description = allTextArray[4];
_test.FaultFlags = 0;
_test.ClearExtendedFaultFlags();
_test.Guid = new Guid("11111111-1111-1111-1111-111111111111");
var startIndex = allTextArray[2].LastIndexOf('-') + 1; //year
var yearString = allTextArray[2].Substring(startIndex, allTextArray[2].Length - startIndex);
startIndex = 0; //month
var monthString = allTextArray[2].Substring(startIndex, 2);
startIndex = allTextArray[2].IndexOf('-') + 1; //day
var dayString = allTextArray[2].Substring(startIndex, 2);
int.TryParse(yearString, out int intResult);
var year = intResult;
intResult = 0;
int.TryParse(monthString, out intResult);
var month = intResult;
intResult = 0;
int.TryParse(dayString, out intResult);
var day = intResult;
_test.InceptionDate = new DateTime(year, month, day);
while (stringNumber < allTextArray.Length && allTextArray[stringNumber] != "---- Start Sampling Information ----")
{
stringNumber++;
}
if (stringNumber == allTextArray.Length)
{
throw new Exception("No Start Sampling Information");
}
//Found "---- Start Sampling Information ----", so skip it and its header text line
stringNumber++; //---- Start Sampling Information ----
stringNumber++; //rate(Hz),pretrigtime(sec),posttrigtime(sec),AdjAAfilter(Hz),postcaltime(sec),prezerodatapts,postzerodatapts,originalt=0pt
var samplingInformation = allTextArray[stringNumber].Split(',');
stringNumber++; //---- End Sampling Information ----
while (stringNumber < allTextArray.Length && allTextArray[stringNumber] != "---- Start Rack Information ----")
{
stringNumber++;
}
if (stringNumber == allTextArray.Length)
{
throw new Exception("No Start Rack Information");
}
//Found "---- Start Rack Information ----", so skip it and its header text line
stringNumber++; //---- Start Rack Information ----
stringNumber++; //Rack,racksn,mod1sn,mod2sn,mod3sn,mod4sn,mod5sn,mod6sn,mod7sn,mod8sn
//Dictionary<string, string[]> rackLookup = new Dictionary<string, string[]>();
while (stringNumber < allTextArray.Length && allTextArray[stringNumber] != "---- End Rack Information ----")
{
var rackIndex = 0;
var rackInformation = allTextArray[stringNumber].Split(',');
rackLookup.Add(rackInformation[rackIndex], rackInformation);
stringNumber++;
}
if (stringNumber == allTextArray.Length)
{
throw new Exception("No End Rack Information");
}
//Found "---- End Rack Information ----", so skip it and look for Start Module Information
stringNumber++; //---- End Rack Information ----
while (stringNumber < allTextArray.Length && allTextArray[stringNumber] != "---- Start Module Information ----")
{
stringNumber++;
}
if (stringNumber == allTextArray.Length)
{
throw new Exception("No Start Module Information");
}
//Found "---- Start Module Information ----", so skip it and its header text line
stringNumber++; //---- Start Module Information ----
stringNumber++; //rack,module,trigmode,trigchan,trigdir,triglevel,moduletype,prediag,postdiag
var moduleLookup = new Dictionary<string, string[]>();
//Dictionary<string, List<int>> moduleChannelLookup = Dictionary<string, List<int>>();
while (stringNumber < allTextArray.Length && allTextArray[stringNumber] != "---- End Module Information ----")
{
var rackIndex = 0;
var moduleIndex = 1;
var moduleInformation = allTextArray[stringNumber].Split(',');
var rackModule = "R" + moduleInformation[rackIndex] + "M" + moduleInformation[moduleIndex];
moduleLookup.Add(rackModule, moduleInformation);
stringNumber++;
}
if (stringNumber == allTextArray.Length)
{
throw new Exception("No End Module Information");
}
//Found "---- End Module Information ----", so skip it and look for Start Sensor Channel Information
stringNumber++; //---- End Module Information ----
while (stringNumber < allTextArray.Length && allTextArray[stringNumber] != "---- Start Sensor Channel Information ----")
{
stringNumber++;
}
if (stringNumber == allTextArray.Length)
{
throw new Exception("No Start Sensor Channel Information");
}
//Found "---- Start Sensor Channel Information ----", so skip it and its header text lines
stringNumber++; //---- Start Sensor Channel Information ----
stringNumber++; //PreTest Data
stringNumber++; //datachan,rack,mod,chan,descrip,s/n,offsetlow,offsethigh,calmode,calstep(ohm/volt),shuntval(eu),proptoext,sens(mv/eu or mv/v/eu),gain,extvolt,EU,filter,invert,zeroref,desiredmaxrange,commentfield,caldate,Offset?,InitialEU,sensorID,ISOcode,IRTRACC Exponent,Category
var preTestChannelLookup = new Dictionary<string, string[]>();
while (stringNumber < allTextArray.Length && allTextArray[stringNumber] != "PostTest Data")
{
//Get PreTest Data information
var rackIndex = 1;
var moduleIndex = 2;
var channelIndex = 3;
var channelInformation = allTextArray[stringNumber].Split(',');
var rackModuleChannel = "R" + channelInformation[rackIndex] + "M" + channelInformation[moduleIndex] + "C" + channelInformation[channelIndex];
preTestChannelLookup.Add(rackModuleChannel, channelInformation);
stringNumber++;
}
if (stringNumber == allTextArray.Length)
{
throw new Exception("No PostTest Data Information");
}
//Found "PostTest Data", so skip it and its header text line
stringNumber++; //PostTest Data
stringNumber++; //datachan,rack,mod,chan,actmaxrange,prediag,offset(mv),SNRatio(dB),prezero,precal,scalefactor(volts/cnt),scalefactor(eu/cnt),datazero,postzero,postcal,max(eu),maxtime(msec),min(eu),mintime(msec),chansat,postdiag,actual 0 mV cnts,desired max range scaling
var postTestChannelLookup = new Dictionary<string, string[]>();
while (stringNumber < allTextArray.Length && allTextArray[stringNumber] != "---- End Sensor Channel Information ----")
{
//Get PostTest Data information
var rackIndex = 1;
var moduleIndex = 2;
var channelIndex = 3;
var channelInformation = allTextArray[stringNumber].Split(',');
var rackModuleChannel = "R" + channelInformation[rackIndex] + "M" + channelInformation[moduleIndex] + "C" + channelInformation[channelIndex];
postTestChannelLookup.Add(rackModuleChannel, channelInformation);
stringNumber++;
}
if (stringNumber == allTextArray.Length)
{
throw new Exception("No End Sensor Channel Information");
}
//Found "---- End Sensor Channel Information ----", so skip it and look for Start Calculated Channel Information
stringNumber++; //---- End Sensor Channel Information ----
while (stringNumber < allTextArray.Length && allTextArray[stringNumber] != "---- Start Calculated Channel Information ----")
{
stringNumber++;
}
if (stringNumber == allTextArray.Length)
{
throw new Exception("No Start Calculated Channel Information");
}
//Found "---- Start Calculated Channel Information ----", so skip it and its header text lines
stringNumber++; //---- Start Calculated Channel Information ----
stringNumber++; //chan,descrip,processtype,1stchan,2ndchan,3rdchan,value,EU,expmaxrange
var calculatedChannelLookup = new Dictionary<string, string[]>();
while (stringNumber < allTextArray.Length && allTextArray[stringNumber] != "---- End Calculated Channel Information ----")
{
//Get calculated channel information
var channelIndex = 0;
var channelInformation = allTextArray[stringNumber].Split(',');
var calcChannel = channelInformation[channelIndex];
calculatedChannelLookup.Add(calcChannel, channelInformation);
stringNumber++;
}
if (stringNumber == allTextArray.Length)
{
throw new Exception("No End Calculated Channel Information");
}
//Found "---- End Calculated Channel Information ----", so skip it and look for Start TOM Channel Information
stringNumber++; //---- End Calculated Channel Information ----
while (stringNumber < allTextArray.Length &&
allTextArray[stringNumber] != "---- Start TOM Channel Information ----" &&
allTextArray[stringNumber] != "---- DIM Begin (1.0) ----" &&
allTextArray[stringNumber] != "---- G5 Digital Input Channels Begin ----")
{
stringNumber++;
}
var TOMChannelLookup = new Dictionary<string, string[]>();
var G5DigitalInputChannelLookup = new Dictionary<string, string[]>();
if (stringNumber < allTextArray.Length)
{
switch (allTextArray[stringNumber])
{
case "---- Start TOM Channel Information ----":
TOMChannelLookup = ProcessTOMChannelInformation(ref stringNumber, allTextArray);
break;
case "---- DIM Begin (1.0) ----":
ProcessDIMInformation(ref stringNumber, allTextArray);
break;
case "---- G5 Digital Input Channels Begin ----":
G5DigitalInputChannelLookup = ProcessG5DigitalInputChannelInformation(ref stringNumber, allTextArray);
break;
}
}
while (stringNumber < allTextArray.Length &&
allTextArray[stringNumber] != "---- DIM Begin (1.0) ----" &&
allTextArray[stringNumber] != "---- G5 Digital Input Channels Begin ----")
{
stringNumber++;
}
if (stringNumber < allTextArray.Length)
{
switch (allTextArray[stringNumber])
{
case "---- DIM Begin (1.0) ----":
ProcessDIMInformation(ref stringNumber, allTextArray);
break;
case "---- G5 Digital Input Channels Begin ----":
G5DigitalInputChannelLookup = ProcessG5DigitalInputChannelInformation(ref stringNumber, allTextArray);
break;
}
}
while (stringNumber < allTextArray.Length &&
allTextArray[stringNumber] != "---- G5 Digital Input Channels Begin ----")
{
stringNumber++;
}
if (stringNumber < allTextArray.Length)
{
G5DigitalInputChannelLookup = ProcessG5DigitalInputChannelInformation(ref stringNumber, allTextArray);
}
//Add loop for multiple racks here
//int rateIndex = 0;
//int pretrigtimeIndex = 1;
//int posttrigtimeIndex = 2;
//int AdjAAfilterIndex = 3;
//int prezerodataptsIndex = 5;
//int postzerodataptsIndex = 6;
foreach (var rackModule in moduleLookup)
{
//Get the non-TOM modules
var module = new Test.Module(_test);
var trigmodeIndex = 2;
InitializeModule(samplingInformation, module, rackModule.Key, rackModule.Value[trigmodeIndex], out int rackNumber);
var createModule = false;
foreach (var rackModuleChannel in preTestChannelLookup)
{
var rackString = rackModuleChannel.Key.Substring(1, rackModule.Key.IndexOf('M') - 1);
int.TryParse(rackString, out int rackInt);
var moduleNumberStart = rackModuleChannel.Key.IndexOf('M') + 1;
var moduleNumberEnd = rackModuleChannel.Key.IndexOf('C') - 1;
var moduleString = rackModuleChannel.Key.Substring(moduleNumberStart, moduleNumberEnd - moduleNumberStart + 1);
int.TryParse(moduleString, out int moduleInt);
if (rackInt == rackNumber && moduleInt == module.Number)
{
createModule = true;
GetPreAndPostTestData(module, preTestChannelLookup[rackModuleChannel.Key], postTestChannelLookup[rackModuleChannel.Key], allTextArray, year, month, day, rackModuleChannel.Key);
}
}
if (createModule)
{
_test.Modules.Add(module);
}
createModule = false;
foreach (var rackModuleChannel in G5DigitalInputChannelLookup)
{
var rackString = rackModuleChannel.Key.Substring(1, rackModule.Key.IndexOf('M') - 1);
int.TryParse(rackString, out int rackInt);
var moduleNumberStart = rackModuleChannel.Key.IndexOf('M') + 1;
var moduleNumberEnd = rackModuleChannel.Key.IndexOf('C') - 1;
var moduleString = rackModuleChannel.Key.Substring(moduleNumberStart, moduleNumberEnd - moduleNumberStart + 1);
int.TryParse(moduleString, out int moduleInt);
if (rackInt == rackNumber && moduleInt == module.Number)
{
createModule = true;
GetG5TestData(module, G5DigitalInputChannelLookup[rackModuleChannel.Key], allTextArray, year, month, day, rackModuleChannel.Key);
}
}
if (createModule)
{
_test.Modules.Add(module);
}
}
var squibFileNumber = 901;
foreach (var rackModule in moduleLookup)
{
//Now get the TOM modules
var module = new Test.Module(_test);
var trigmodeIndex = 2;
InitializeModule(samplingInformation, module, rackModule.Key, rackModule.Value[trigmodeIndex], out int rackNumber);
var createModule = false;
foreach (var rackModuleChannel in TOMChannelLookup)
{
var rackString = rackModuleChannel.Key.Substring(1, rackModule.Key.IndexOf('M') - 1);
int.TryParse(rackString, out int rackInt);
var moduleNumberStart = rackModuleChannel.Key.IndexOf('M') + 1;
var moduleNumberEnd = rackModuleChannel.Key.IndexOf('C') - 1;
var moduleString = rackModuleChannel.Key.Substring(moduleNumberStart, moduleNumberEnd - moduleNumberStart + 1);
int.TryParse(moduleString, out int moduleInt);
if (rackInt == rackNumber && moduleInt == module.Number)
{
createModule = true;
GetTOMSquibFireChannelsData(module, TOMChannelLookup[rackModuleChannel.Key], allTextArray, year, month, day, rackModuleChannel.Key, squibFileNumber);
squibFileNumber++;
squibFileNumber++;
}
}
if (createModule)
{
_test.Modules.Add(module);
}
}
//if (calculatedChannelLookup.Count > 0)
//{
// //Now make a calculated channel module
// int maxModuleNumber = 0;
// foreach (DTS.Serialization.Test.Module mod in _test.Modules)
// {
// maxModuleNumber = Math.Max(maxModuleNumber, mod.Number);
// }
// DTS.Serialization.Test.Module module = new DTS.Serialization.Test.Module(_test);
// //module.Number = maxModuleNumber + 1;
// //int trigmodeIndex = 2;
// int rackNumber = 0;
// InitializeModule(samplingInformation, module, "R0M" + (maxModuleNumber + 1).ToString(), 1.ToString(), out rackNumber);
// foreach (var calculatedChannel in calculatedChannelLookup.Values)
// {
// GetCalculatedChannelsData(module, calculatedChannel, allTextArray, year, month, day);
// }
// _test.Modules.Add(module);
//}
}
return _test;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem deserializing test from string", ex);
}
}
private void InitializeModule(string[] samplingInformation, Test.Module module, string rackModuleKey, string rackModuleValueTrigmodeIndex, out int rackNumber) // KeyValuePair<string, string[]> rackModule)
{
var rateIndex = 0;
var pretrigtimeIndex = 1;
var posttrigtimeIndex = 2;
var AdjAAfilterIndex = 3;
var prezerodataptsIndex = 5;
var postzerodataptsIndex = 6;
float.TryParse(samplingInformation[AdjAAfilterIndex], out float floatResult);
module.AaFilterRateHz = floatResult;
var moduleNumberStart = rackModuleKey.IndexOf('M') + 1;
var moduleIndexString = rackModuleKey.Substring(moduleNumberStart, rackModuleKey.Length - moduleNumberStart);
int.TryParse(moduleIndexString, out int intResult);
module.Number = intResult;
var rackIndexString = rackModuleKey.Substring(1, rackModuleKey.IndexOf('M') - 1);
intResult = 0;
if (rackIndexString == 0.ToString())
{
rackNumber = 0;
module.SerialNumber = "Calc";
module.BaseSerialNumber = "CBase";
}
else
{
var rack = rackLookup[rackIndexString];
//rackNumber = 0;
int.TryParse(rackIndexString, out intResult);
rackNumber = intResult;
module.SerialNumber = rack[module.Number + 1];
var racksnIndex = 1;
module.BaseSerialNumber = rack[racksnIndex];
}
ulong.TryParse(samplingInformation[prezerodataptsIndex], out ulong ulongResult);
var preZeroDataPoints = ulongResult;
ulong.TryParse(samplingInformation[postzerodataptsIndex], out ulongResult);
var postZeroDataPoints = ulongResult;
module.NumberOfSamples = preZeroDataPoints + postZeroDataPoints;
double.TryParse(samplingInformation[posttrigtimeIndex], out double doubleResult);
module.RequestedPostTriggerSeconds = doubleResult;
module.PostTriggerSeconds = doubleResult;
doubleResult = 0;
double.TryParse(samplingInformation[pretrigtimeIndex], out doubleResult);
module.RequestedPreTriggerSeconds = doubleResult;
module.PreTriggerSeconds = doubleResult;
intResult = 0;
int.TryParse(rackModuleValueTrigmodeIndex, out intResult);
if (intResult == 0)
{
module.RecordingMode = DFConstantsAndEnums.RecordingMode.CircularBuffer;
}
else if (intResult == 1)
{
module.RecordingMode = DFConstantsAndEnums.RecordingMode.RecorderMode;
}
floatResult = 0;
float.TryParse(samplingInformation[rateIndex], out floatResult);
module.SampleRateHz = floatResult;
module.StartRecordSampleNumber = 0;
module.TriggerSampleNumbers = new List<ulong>();
module.UnsubsampledTriggerSampleNumbers = new List<ulong>();
}
private Dictionary<string, string[]> ProcessTOMChannelInformation(ref int stringNumber, string[] allTextArray)
{
var TOMChannelLookup = new Dictionary<string, string[]>();
//Found "---- Start TOM Channel Information ----", so skip it and its header text lines
stringNumber++; //---- Start TOM Channel Information ----
stringNumber++; //---- TOM Squib Fire Channels ----
stringNumber++; //rack,module,chan,descrip,id,type,current,delay,durationON,duration,OhmLow,OhmHigh,ISO Code,measuredohms,recordtype,scalefactor1,scalefactor2,postmeasuredohms,voltage zero average ADC,current zero average ADC
while (stringNumber < allTextArray.Length && allTextArray[stringNumber] != "---- TOM Digital Channels ----")
{
var rackIndex = 0;
var moduleIndex = 1;
var channelIndex = 2;
//Get TOM Squib Fire channel information
var channelInformation = allTextArray[stringNumber].Split(',');
var rackModuleChannel = "R" + channelInformation[rackIndex] + "M" + channelInformation[moduleIndex] + "C" + channelInformation[channelIndex];
TOMChannelLookup.Add(rackModuleChannel, channelInformation);
stringNumber++;
}
if (stringNumber == allTextArray.Length)
{
throw new Exception("No TOM Digital Channels Information");
}
//Found "---- TOM Digital Channels ----", so skip it and its header text line
stringNumber++; //---- TOM Digital Channels ----
stringNumber++; //rack,module,chan,type,delay,durationON,duration
while (stringNumber < allTextArray.Length && allTextArray[stringNumber] != "---- End TOM Channel Information ----")
{
//Get TOM Digital channel information
stringNumber++;
}
if (stringNumber == allTextArray.Length)
{
throw new Exception("No End TOM Channel Information");
}
//Found "---- End TOM Channel Information ----", so skip it and look for DIM Begin (1.0)
stringNumber++; //---- End TOM Channel Information ----
return TOMChannelLookup;
}
private void ProcessDIMInformation(ref int stringNumber, string[] allTextArray)
{
//Found "---- DIM Begin (1.0) ----", so skip it and its header text line
stringNumber++; //---- DIM Begin (1.0) ----
stringNumber++; //Datachan,Rack,Module,Chan,Description,Serial No,Mode,Inverted,EID,Filename,Scale,Filter Mode,Filter Threshold,ISO CODE,Cable Test,Pre Test Results, Post TestResults
while (stringNumber < allTextArray.Length && allTextArray[stringNumber] != "---- DIM End ----")
{
//Get DIM channel information
stringNumber++;
}
if (stringNumber == allTextArray.Length)
{
throw new Exception("No DIM End");
}
//Found "---- DIM End ----", so skip it and look for G5 Digital Input Channels Begin
stringNumber++; //---- DIM End ----
}
private Dictionary<string, string[]> ProcessG5DigitalInputChannelInformation(ref int stringNumber, string[] allTextArray)
{
var G5DigitalInputChannelLookup = new Dictionary<string, string[]>();
//Found "---- G5 Digital Input Channels Begin ----", so skip it and its header text line
stringNumber++; //---- G5 Digital Input Channels Begin ----
stringNumber++; //datachan,rack,mod,chan,descrip,ISOCode,scale,invert
while (stringNumber < allTextArray.Length && allTextArray[stringNumber] != "---- G5 Digital Input Channels End ----")
{
var rackIndex = 1;
var moduleIndex = 2;
var channelIndex = 3;
var channelInformation = allTextArray[stringNumber].Split(',');
var rackModuleChannel = "R" + channelInformation[rackIndex] + "M" + channelInformation[moduleIndex] + "C" + channelInformation[channelIndex];
G5DigitalInputChannelLookup.Add(rackModuleChannel, channelInformation);
stringNumber++;
}
return G5DigitalInputChannelLookup;
}
private void GetPreAndPostTestData(Test.Module module, string[] channelPreTestData, string[] channelPostTestData, string[] allTextArray, int year, int month, int day, string rackModuleChannelKey)
{
var deserializedChannel = new Test.Module.AnalogInputChannel(module);
deserializedChannel.PersistentChannelInfo = null; // We're going to use TDASPersistentChannelInfo
deserializedChannel.Data = new Test.Module.Channel.DataArray<short>();
//PreTest Data
var chanIndex = 0;
var descripIndex = 4;
var snIndex = 5;
var proptoextIndex = 11;
var sensmveuormvveuIndex = 12;
var extvoltIndex = 14;
var EUIndex = 15;
var filterIndex = 16;
var invertIndex = 17;
var zerorefIndex = 18;
var desiredmaxrangeIndex = 19;
var OffsetIndex = 22;
var InitialEUIndex = 23;
var ISOcodeIndex = 25;
var CategoryIndex = 27;
var PolynomialCoefficent1Index = 29;
var PolynomialCoefficent2Index = 30;
var PolynomialCoefficent3Index = 31;
var PolynomialCoefficent4Index = 32;
//PostTest Data
var SNRatiodBIndex = 7;
var prezeroIndex = 8;
//const string SENSOR_CATEGORY_NORMAL = "0";
//const string SENSOR_CATEGORY_POT = "1";
//const string SENSOR_CATEGORY_IRTRACC = "2";
const string SENSOR_CATEGORY_POLYNOMIAL = "3";
//const int MAX_SENSOR_CATEGORIES = 4;
int.TryParse(channelPreTestData[chanIndex], out int intResult);
deserializedChannel.Number = intResult;
deserializedChannel.Start = GenerateStartDateTime(allTextArray, year, month, day);
//We are generating channels based on what's in the .TLF, but they may not exist on disk (removed or problem downloading), so initialize to -2
deserializedChannel.AbsoluteDisplayOrder = -2;
deserializedChannel.Bridge = SensorConstants.BridgeType.FullBridge;
deserializedChannel.BridgeResistanceOhms = 0.0;
deserializedChannel.ZeroPoint = 0D;
deserializedChannel.CalSignalEnabled = false;
if (channelPreTestData[descripIndex] == string.Empty)
{
if (channelPreTestData.Length > ISOcodeIndex)
{
deserializedChannel.ChannelDescriptionString = "ISO: " + channelPreTestData[ISOcodeIndex];
}
}
else
{
deserializedChannel.ChannelDescriptionString = channelPreTestData[descripIndex];
if (channelPreTestData.Length > ISOcodeIndex)
{
deserializedChannel.ChannelName2 = "ISO: " + channelPreTestData[ISOcodeIndex];
}
}
deserializedChannel.ChannelId = rackModuleChannelKey;
double.TryParse(channelPreTestData[desiredmaxrangeIndex], out double desiredMaxRange);
deserializedChannel.DesiredRange = desiredMaxRange;
deserializedChannel.EngineeringUnits = channelPreTestData[EUIndex];
deserializedChannel.ExcitationVoltage = ExcitationVoltageOptions.ExcitationVoltageOption.Undefined;
double.TryParse(channelPreTestData[InitialEUIndex], out double initialEU);
deserializedChannel.InitialEu = initialEU;
if (channelPreTestData[invertIndex] == "0")
{
deserializedChannel.IsInverted = false;
}
else
{
deserializedChannel.IsInverted = true;
}
if (channelPreTestData.Length > ISOcodeIndex)
{
deserializedChannel.IsoCode = channelPreTestData[ISOcodeIndex];
}
if (channelPreTestData.Length > PolynomialCoefficent4Index)
{
if (channelPreTestData[CategoryIndex] == SENSOR_CATEGORY_POLYNOMIAL)
{
deserializedChannel.LinearizationFormula = new Common.Classes.Sensors.LinearizationFormula();
deserializedChannel.LinearizationFormula.NonLinearStyle = NonLinearStyles.Polynomial;
var coefficients = new List<double>();
double.TryParse(channelPreTestData[PolynomialCoefficent4Index], out double doubleResult); //M (exponent of 0)
coefficients.Add(doubleResult);
doubleResult = 0.0;
double.TryParse(channelPreTestData[PolynomialCoefficent3Index], out doubleResult); //C (exponent of 3)
coefficients.Add(doubleResult);
doubleResult = 0.0;
double.TryParse(channelPreTestData[PolynomialCoefficent2Index], out doubleResult); //B (exponent of 2)
coefficients.Add(doubleResult);
doubleResult = 0.0;
double.TryParse(channelPreTestData[PolynomialCoefficent1Index], out doubleResult); //A (exponent of 1)
coefficients.Add(doubleResult);
deserializedChannel.LinearizationFormula.PolynomialCoefficients = coefficients.ToArray();
deserializedChannel.LinearizationFormula.FromTDCSerializeString(); //To set it valid???
}
}
double.TryParse(channelPreTestData[extvoltIndex], out double measuredExcitationVoltage);
deserializedChannel.MeasuredExcitationVoltage = measuredExcitationVoltage;
double.TryParse(channelPostTestData[SNRatiodBIndex], out double snRatio);
deserializedChannel.NoiseAsPercentageOfFullScale = snRatio;
short.TryParse(channelPostTestData[prezeroIndex], out short preZero);
deserializedChannel.PreTestZeroLevelAdc = preZero;
if (channelPreTestData[proptoextIndex] == "0")
{
deserializedChannel.ProportionalToExcitation = false;
}
else
{
deserializedChannel.ProportionalToExcitation = true;
}
if (channelPreTestData[OffsetIndex] == "Y")
{
deserializedChannel.RemoveOffset = true;
}
else
{
deserializedChannel.RemoveOffset = false;
}
double.TryParse(channelPostTestData[sensmveuormvveuIndex], out double sensitivity);
deserializedChannel.Sensitivity = sensitivity; //temp
deserializedChannel.SerialNumber = channelPreTestData[snIndex];
deserializedChannel.ShuntEnabled = true;
switch (channelPreTestData[filterIndex])
{
case "100":
deserializedChannel.SoftwareFilter = ChannelFilter.Class60.ToString();
break;
case "300":
deserializedChannel.SoftwareFilter = ChannelFilter.Class180.ToString();
break;
case "1000":
deserializedChannel.SoftwareFilter = ChannelFilter.Class600.ToString();
break;
case "1650":
deserializedChannel.SoftwareFilter = ChannelFilter.Class1000.ToString();
break;
default:
deserializedChannel.SoftwareFilter = ChannelFilter.Unfiltered.ToString();
break;
}
deserializedChannel.VoltageInsertionCheckEnabled = false;
deserializedChannel.ZeroAverageWindow = new Test.IntervalSec(0, 0); //So that AverageOverTime will return what UsePreEventDiagnosticsZero would return
switch (channelPreTestData[zerorefIndex])
{
case "0":
deserializedChannel.ZeroMethod = ZeroMethodType.AverageOverTime;
break;
case "1":
deserializedChannel.ZeroMethod = ZeroMethodType.UsePreEventDiagnosticsZero;
break;
case "2":
deserializedChannel.ZeroMethod = ZeroMethodType.None;
break;
default:
deserializedChannel.ZeroMethod = ZeroMethodType.None;
break;
}
module.Channels.Add(deserializedChannel);
}
private void GetG5TestData(Test.Module module, string[] channelG5DigitalInputData, string[] allTextArray, int year, int month, int day, string rackModuleChannelKey)
{
var deserializedChannel = new Test.Module.AnalogInputChannel(module);
deserializedChannel.PersistentChannelInfo = null; // We're going to use TDASPersistentChannelInfo
deserializedChannel.Data = new Test.Module.Channel.DataArray<short>();
//G5 Digital Input Data
var chanIndex = 3;
var descripIndex = 4;
var ISOCodeIndex = 5;
var invertIndex = 7;
int.TryParse(channelG5DigitalInputData[chanIndex], out int intResult);
deserializedChannel.Number = intResult;
deserializedChannel.Start = GenerateStartDateTime(allTextArray, year, month, day);
//We are generating channels based on what's in the .TLF, but they may not exist on disk (removed or problem downloading), so initialize to -2
deserializedChannel.AbsoluteDisplayOrder = -2;
deserializedChannel.Bridge = SensorConstants.BridgeType.FullBridge;
deserializedChannel.BridgeResistanceOhms = 0.0;
deserializedChannel.ZeroPoint = 0D;
deserializedChannel.CalSignalEnabled = false;
deserializedChannel.ChannelDescriptionString = channelG5DigitalInputData[descripIndex];
deserializedChannel.ChannelId = rackModuleChannelKey;
deserializedChannel.DesiredRange = 0.0;
deserializedChannel.EngineeringUnits = "0/1";//temp
deserializedChannel.ExcitationVoltage = ExcitationVoltageOptions.ExcitationVoltageOption.Undefined;
deserializedChannel.InitialEu = 0.0;
if (channelG5DigitalInputData[invertIndex] == "0")
{
deserializedChannel.IsInverted = false;
}
else
{
deserializedChannel.IsInverted = true;
}
deserializedChannel.IsoCode = channelG5DigitalInputData[ISOCodeIndex];
deserializedChannel.MeasuredExcitationVoltage = 0.0;
deserializedChannel.NoiseAsPercentageOfFullScale = 0.0;
deserializedChannel.PreTestZeroLevelAdc = 0;
deserializedChannel.ProportionalToExcitation = false;
deserializedChannel.RemoveOffset = false;
deserializedChannel.Sensitivity = 0.0; //temp
deserializedChannel.SerialNumber = string.Empty;
deserializedChannel.ShuntEnabled = true;
deserializedChannel.SoftwareFilter = ChannelFilter.Unfiltered.ToString();
deserializedChannel.VoltageInsertionCheckEnabled = false;
deserializedChannel.ZeroAverageWindow = new Test.IntervalSec(0, 0); //So that AverageOverTime will return what UsePreEventDiagnosticsZero would return
deserializedChannel.ZeroMethod = ZeroMethodType.AverageOverTime;
module.Channels.Add(deserializedChannel);
}
private void GetTOMSquibFireChannelsData(Test.Module module, string[] channelTOMData, string[] allTextArray, int year, int month, int day,
string rackModuleChannelKey, int squibFileNumber)
{
var deserializedVoltageChannel = new Test.Module.AnalogInputChannel(module);
var deserializedCurrentChannel = new Test.Module.AnalogInputChannel(module);
deserializedVoltageChannel.PersistentChannelInfo = null; // We're going to use TDASPersistentChannelInfo
deserializedCurrentChannel.PersistentChannelInfo = null; // We're going to use TDASPersistentChannelInfo
deserializedVoltageChannel.Data = new Test.Module.Channel.DataArray<short>();
deserializedCurrentChannel.Data = new Test.Module.Channel.DataArray<short>();
//TOM Squib Fire Channels
var descripIndex = 3;
var idIndex = 4;
//Most recent version:
var ISO_CodeIndex = 12;
var postMeasuredOhmsIndex = 17;
var voltageZeroAverageADCIndex = 18;
var currentZeroAverageADCIndex = 19;
if (channelTOMData.Length == 17) //hack
{
postMeasuredOhmsIndex = 16;
}
deserializedVoltageChannel.Number = squibFileNumber;
deserializedCurrentChannel.Number = squibFileNumber + 1;
deserializedVoltageChannel.Start = GenerateStartDateTime(allTextArray, year, month, day);
deserializedCurrentChannel.Start = GenerateStartDateTime(allTextArray, year, month, day);
//We are generating channels based on what's in the .TLF, but they may not exist on disk (removed or problem downloading), so initialize to -2
deserializedVoltageChannel.AbsoluteDisplayOrder = -2;
deserializedCurrentChannel.AbsoluteDisplayOrder = -2;
deserializedVoltageChannel.Bridge = SensorConstants.BridgeType.FullBridge;
deserializedCurrentChannel.Bridge = SensorConstants.BridgeType.FullBridge;
double.TryParse(channelTOMData[postMeasuredOhmsIndex], out double doubleResult);
deserializedVoltageChannel.BridgeResistanceOhms = doubleResult;
deserializedCurrentChannel.BridgeResistanceOhms = doubleResult;
deserializedVoltageChannel.ZeroPoint = 0D;
deserializedCurrentChannel.ZeroPoint = 0D;
deserializedVoltageChannel.CalSignalEnabled = false;
deserializedCurrentChannel.CalSignalEnabled = false;
deserializedVoltageChannel.ChannelDescriptionString = channelTOMData[descripIndex];
deserializedCurrentChannel.ChannelDescriptionString = channelTOMData[descripIndex];
deserializedVoltageChannel.ChannelId = rackModuleChannelKey;
deserializedCurrentChannel.ChannelId = rackModuleChannelKey;
deserializedVoltageChannel.DesiredRange = 1;
deserializedCurrentChannel.DesiredRange = 1;
deserializedVoltageChannel.EngineeringUnits = "Volts";
deserializedCurrentChannel.EngineeringUnits = "Amps";
deserializedVoltageChannel.ExcitationVoltage = ExcitationVoltageOptions.ExcitationVoltageOption.Volt5;
deserializedCurrentChannel.ExcitationVoltage = ExcitationVoltageOptions.ExcitationVoltageOption.Volt5;
deserializedVoltageChannel.InitialEu = 0.0;
deserializedCurrentChannel.InitialEu = 0.0;
deserializedVoltageChannel.IsInverted = false;
deserializedCurrentChannel.IsInverted = false;
deserializedVoltageChannel.IsoCode = channelTOMData[ISO_CodeIndex];
deserializedCurrentChannel.IsoCode = channelTOMData[ISO_CodeIndex];
deserializedVoltageChannel.MeasuredExcitationVoltage = 0.0;
deserializedCurrentChannel.MeasuredExcitationVoltage = 0.0;
deserializedVoltageChannel.NoiseAsPercentageOfFullScale = 0.0;
deserializedCurrentChannel.NoiseAsPercentageOfFullScale = 0.0;
short zeroAverageADC = 0;
if (channelTOMData.Length > voltageZeroAverageADCIndex)
{
short.TryParse(channelTOMData[voltageZeroAverageADCIndex], out zeroAverageADC);
}
deserializedVoltageChannel.PreTestZeroLevelAdc = zeroAverageADC;
zeroAverageADC = 0;
if (channelTOMData.Length > currentZeroAverageADCIndex)
{
short.TryParse(channelTOMData[currentZeroAverageADCIndex], out zeroAverageADC);
}
deserializedCurrentChannel.PreTestZeroLevelAdc = zeroAverageADC;
deserializedVoltageChannel.ProportionalToExcitation = true;
deserializedCurrentChannel.ProportionalToExcitation = true;
deserializedVoltageChannel.RemoveOffset = true;
deserializedCurrentChannel.RemoveOffset = true;
deserializedVoltageChannel.Sensitivity = 0.0;
deserializedCurrentChannel.Sensitivity = 0.0;
deserializedVoltageChannel.SerialNumber = channelTOMData[idIndex];
deserializedCurrentChannel.SerialNumber = channelTOMData[idIndex];
deserializedVoltageChannel.ShuntEnabled = false;
deserializedCurrentChannel.ShuntEnabled = false;
deserializedVoltageChannel.SoftwareFilter = ChannelFilter.Unfiltered.ToString();
deserializedCurrentChannel.SoftwareFilter = ChannelFilter.Unfiltered.ToString();
deserializedVoltageChannel.VoltageInsertionCheckEnabled = false;
deserializedCurrentChannel.VoltageInsertionCheckEnabled = false;
deserializedVoltageChannel.ZeroAverageWindow = new Test.IntervalSec(0, 0);
deserializedCurrentChannel.ZeroAverageWindow = new Test.IntervalSec(0, 0);
deserializedVoltageChannel.ZeroMethod = ZeroMethodType.UsePreEventDiagnosticsZero;
deserializedCurrentChannel.ZeroMethod = ZeroMethodType.UsePreEventDiagnosticsZero;
module.Channels.Add(deserializedVoltageChannel);
module.Channels.Add(deserializedCurrentChannel);
}
private void GetCalculatedChannelsData(Test.Module module, string[] calculatedChannelData, string[] allTextArray, int year, int month, int day)
{
var deserializedChannel = new Test.Module.AnalogInputChannel(module);
deserializedChannel.PersistentChannelInfo = null; // We're going to use TDASPersistentChannelInfo
deserializedChannel.Data = new Test.Module.Channel.DataArray<short>();
//Calculated Channel Data
var chanIndex = 0;
var descripIndex = 1;
var EUIndex = 7;
int.TryParse(calculatedChannelData[chanIndex], out int intResult);
deserializedChannel.Number = intResult;
deserializedChannel.Start = GenerateStartDateTime(allTextArray, year, month, day);
//We are generating channels based on what's in the .TLF, but they may not exist on disk (removed or problem downloading), so initialize to -2
deserializedChannel.AbsoluteDisplayOrder = -2;
deserializedChannel.Bridge = SensorConstants.BridgeType.FullBridge;
deserializedChannel.BridgeResistanceOhms = 0.0;
deserializedChannel.ZeroPoint = 0D;
deserializedChannel.CalSignalEnabled = false;
deserializedChannel.ChannelDescriptionString = calculatedChannelData[descripIndex];
deserializedChannel.ChannelId = "C" + deserializedChannel.Number;
deserializedChannel.DesiredRange = 0.0;
deserializedChannel.EngineeringUnits = calculatedChannelData[EUIndex];
deserializedChannel.ExcitationVoltage = ExcitationVoltageOptions.ExcitationVoltageOption.Undefined;
deserializedChannel.InitialEu = 0.0;
deserializedChannel.IsInverted = false;
deserializedChannel.IsoCode = string.Empty;
deserializedChannel.MeasuredExcitationVoltage = 0.0;
deserializedChannel.NoiseAsPercentageOfFullScale = 0.0;
deserializedChannel.PreTestZeroLevelAdc = 0;
deserializedChannel.ProportionalToExcitation = false;
deserializedChannel.RemoveOffset = false;
deserializedChannel.Sensitivity = 0.0; //temp
deserializedChannel.SerialNumber = string.Empty;
deserializedChannel.ShuntEnabled = true;
deserializedChannel.SoftwareFilter = ChannelFilter.Unfiltered.ToString();
deserializedChannel.VoltageInsertionCheckEnabled = false;
deserializedChannel.ZeroAverageWindow = new Test.IntervalSec(0, 0); //So that AverageOverTime will return what UsePreEventDiagnosticsZero would return
deserializedChannel.ZeroMethod = ZeroMethodType.AverageOverTime;
module.CalculatedChannels.Add(deserializedChannel);
}
private DateTime GenerateStartDateTime(string[] allTextArray, int year, int month, int day)
{
var startIndex = 0;
startIndex = allTextArray[3].LastIndexOf(':') + 1; //seconds
var secondString = allTextArray[3].Substring(startIndex, allTextArray[3].Length - startIndex);
startIndex = 0; //hour
var hourString = allTextArray[3].Substring(startIndex, 2);
startIndex = allTextArray[3].IndexOf(':') + 1; //minute
var minuteString = allTextArray[3].Substring(startIndex, 2);
int.TryParse(secondString, out int intResult);
var second = intResult;
intResult = 0;
int.TryParse(hourString, out intResult);
var hour = intResult;
intResult = 0;
int.TryParse(minuteString, out intResult);
var minute = intResult;
return new DateTime(year, month, day, hour, minute, second);
}
/// <summary>
/// Perform read of all test and channel data.
/// </summary>
///
/// <param name="directory">
/// The <see cref="string"/> pathname of the directory containing the serialization to be read.
/// </param>
///
/// <param name="test">
/// The <see cref="DTS.Serialization.Test"/> generated from the specified serialization.
/// </param>
///
/// <returns>
/// A test populated with deserialized test and channel data.
/// </returns>
///
public void Read(string directory, out Test test)
//public void Read(Test.Module.Channel channel, Test.Module module, string channelFileName, out DTS.Serialization.Test test)
{
Read(directory, out test, null);
}
/// <summary>
/// Perform read of all test and channel data.
/// </summary>
///
/// <param name="directory">
/// The <see cref="string"/> pathname of the directory containing the serialization to be read.
/// </param>
///
/// <param name="test">
/// The <see cref="DTS.Serialization.Test"/> generated from the specified serialization.
/// </param>
///
/// <param name="onEvent">
/// A <see cref="DTS.Serialization.File.Reader.EventHandler"/> to be notified with read
/// status updates.
/// </param>
///
/// <returns>
/// A test populated with deserialized test and channel data.
/// </returns>
///
public void Read(string directory, out Test test, EventHandler onEvent)
//public void Read(Test.Module.Channel channel, Test.Module module, string channelFileName, out DTS.Serialization.Test test, Reader.EventHandler onEvent)
{
string testFileName = null;
try
{
testFileName = GetTestFilename(directory);
var channelFileNames = GetChannelFilenames(directory);
//Combine the following into one foreach
//Remove any without .BIN extension (.BIN_OriginalData, for example)
var toRemove = new List<string>();
foreach (var fileName in channelFileNames)
{
if (fileName.Substring(fileName.Length - 4, 4) != ".BIN")
{
toRemove.Add(fileName);
}
}
foreach (var fileName in toRemove)
{
channelFileNames.Remove(fileName);
}
//Remove any remaining without a number (_Orig.BIN, for example)
toRemove = new List<string>();
foreach (var fileName in channelFileNames)
{
if (FileType.GetChannelNumberFromChannelFileName(fileName) == 0)
{
toRemove.Add(fileName);
}
}
foreach (var fileName in toRemove)
{
channelFileNames.Remove(fileName);
}
////Move Calculated Channel filenames to a different list
//List<string> calculatedChannelFileNames = new List<string>();
//foreach (string fileName in channelFileNames)
//{
// int startIndex = fileName.LastIndexOf('.') - 5;
// if (fileName.Substring(startIndex, 2) == "_C")
// {
// calculatedChannelFileNames.Add(fileName);
// }
//}
//foreach (string filename in calculatedChannelFileNames)
//{
// channelFileNames.Remove(filename);
//}
//int currentChannelFileNameIndex = 0;
onEvent?.Invoke(Event.NumberOfFilesDetermined, channelFileNames.Count + 1);
test = DeserializeTestFromTLF(testFileName);
// Generated from a serialization. Get the timestamp.
test.InceptionDate = System.IO.File.GetLastWriteTime(testFileName);
//Hack Alert. Test Id doesn't always match the TestID -- use the dts file name as the test id.
var testId = Path.GetFileNameWithoutExtension(testFileName);
if (false == test.Id.Equals(testId))
{
APILogger.Log("DTS File Name: " + testId + " does not match Test Id: " + test.Id + " . Using file name as test Id");
}
var bByPass = false;
foreach (var fileName in channelFileNames)
{
var startIndex = fileName.LastIndexOf('.') - 3;
var currentFileNameNumberString = fileName.Substring(startIndex, 3);
int.TryParse(currentFileNameNumberString, out int currentFileNameNumber);
foreach (var module in test.Modules)
{
foreach (var channel in module.Channels)
{
if (channel.Number == currentFileNameNumber)
{
if (!System.IO.File.Exists(fileName))
{
APILogger.Log("File not found ", fileName);
throw new FileNotFoundException(fileName);
}
ReadChannel(channel, module, fileName, ref bByPass);
channel.AbsoluteDisplayOrder = channelFileNames.IndexOf(fileName);
}
}
}
}
//foreach (string fileName in calculatedChannelFileNames)
//{
// int startIndex = fileName.LastIndexOf('.') - 3;
// string currentFileNameNumberString = fileName.Substring(startIndex, 3);
// int currentFileNameNumber = 0;
// Int32.TryParse(currentFileNameNumberString, out currentFileNameNumber);
// foreach (Test.Module module in test.Modules) //only one module with calculated channels?
// {
// foreach (Test.Module.Channel channel in module.CalculatedChannels)
// {
// if (channel.Number == currentFileNameNumber)
// {
// if (!System.IO.File.Exists(fileName))
// {
// APILogger.Log("File not found ", fileName);
// throw new FileNotFoundException(fileName);
// }
// ReadChannel(channel, module, fileName, ref bByPass);
// channel.AbsoluteDisplayOrder = channelFileNames.IndexOf(fileName) + 1000;
// }
// }
// }
//}
onEvent?.Invoke(Event.FullReadComplete, channelFileNames.Count + 1);
}
catch (Exception ex)
{
APILogger.Log($"Exception is '{ex.Message}'");
if (ex is MissingFileException || ex is BadCrcException || ex is UserException) { throw ex; }
else
{
throw new Exception("Encountered problem reading test file \"" + (testFileName ?? "<NULL>") + "\"", ex);
}
}
catch (FileNotFoundException)
{
throw;
}
finally
{
onEvent?.Invoke(Event.FullReadComplete, 0);
}
}
public void ReadChannel(Test.Module.Channel channel, Test.Module module, string channelFileName, ref bool bByPass)
{
APILogger.Log("Getting stream");
var attempt = 0;
var bFailed = true;
while (attempt < 30 && bFailed)
{
attempt++;
try
{
APILogger.Log("reading file 666 ", channelFileName);
using (var mutex = new System.Threading.Mutex(false, channelFileName.Replace(Path.DirectorySeparatorChar, '_')))
{
while (!mutex.WaitOne(50, false)) { System.Threading.Thread.Sleep(5); }
try
{
using (var stream = System.IO.File.OpenRead(channelFileName))
{
APILogger.Log("Getting reader");
using (var reader = new BinaryReader(stream))
{
var channelInfo = new TDASBinaryChannelHeader();
var fields = Enum.GetValues(typeof(PersistentChannel.Field)).Cast<PersistentChannel.Field>().ToArray();
APILogger.Log("Got fields");
foreach (var field in fields)
{
switch (field)
{
case PersistentChannel.Field.AcquisitionRate:
channelInfo.AcquisitionRate = reader.ReadDouble();
break;
case PersistentChannel.Field.NumberOfPreT0DataPoints:
channelInfo.NumberOfPreT0DataPoints = reader.ReadInt32();
if (channelInfo.NumberOfPreT0DataPoints >= -1)
{
if (module.TriggerSampleNumbers.Count == 0)
{
module.TriggerSampleNumbers.Add((ulong)channelInfo.NumberOfPreT0DataPoints);
}
}
break;
case PersistentChannel.Field.NumberOfPostT0DataPoints:
channelInfo.NumberOfPostT0DataPoints = reader.ReadInt32();
if (channelInfo.NumberOfPostT0DataPoints >= -1)
{
module.NumberOfSamples = (ulong)(channelInfo.NumberOfPreT0DataPoints + channelInfo.NumberOfPostT0DataPoints);
}
break;
case PersistentChannel.Field.PreZeroLevelInCnts:
channelInfo.PreZeroLevelInCnts = reader.ReadInt32();
break;
case PersistentChannel.Field.PreCalLevelInCnts:
channelInfo.PreCalLevelInCnts = reader.ReadInt32();
break;
case PersistentChannel.Field.SignalToNoiseRatioInDb:
channelInfo.SignalToNoiseRatioInDb = reader.ReadDouble();
break;
case PersistentChannel.Field.PostZeroLevelInCnts:
channelInfo.PostZeroLevelInCnts = reader.ReadInt32();
break;
case PersistentChannel.Field.PostCalLevelInCnts:
channelInfo.PostCalLevelInCnts = reader.ReadInt32();
break;
case PersistentChannel.Field.DataZeroLevelInCnts:
channelInfo.DataZeroLevelInCnts = (short)reader.ReadInt32();
break;
case PersistentChannel.Field.ScaleFactorMVPerCnt:
channelInfo.ScaleFactorMVPerCnt = reader.ReadDouble();
break;
case PersistentChannel.Field.ScaleFactorEUPerCnt:
channelInfo.ScaleFactorEUPerCnt = reader.ReadDouble();
break;
}
}//end foreach
try
{
const int DataChunkSize = 0x1000;
var dataChunk = new short[DataChunkSize];
var analogChannel = channel as Test.Module.AnalogInputChannel;
analogChannel.Multiplier = channel.Data.Multiplier;
analogChannel.UnitConversion = channel.Data.UnitConversion;
analogChannel.UserOffsetEU = channel.Data.UserOffsetEU;
if (null != analogChannel)
{
if (channel is Test.Module.CalculatedChannel)
{
var cc = channel as Test.Module.CalculatedChannel;
analogChannel.AverageAdcOverTime = new AverageShortValueOverTime(0, cc.SampleRateHz, "s");
}
else
{
analogChannel.AverageAdcOverTime = new AverageShortValueOverTime(0, analogChannel.ParentModule.SampleRateHz, "s");
}
}
channel.TDASPersistentChannelInfo = new PersistentChannel(channelFileName, null, false);
channel.Data = new Test.Module.Channel.DataArray<short>();
//if (channelInfo.ScaleFactorMVPerCnt == 0)
//{
// //Squibs have a ScaleFactorMVPerCnt of 0, but ScaleFactorEUPerCnt is all we need.
// //So, to make the EU come out right do the following
// channel.Data.MvPerEu = 1;
// channel.Data.ScaleFactorMv = channelInfo.ScaleFactorEUPerCnt;
//}
//else
//{
// voltage = (channel as DTS.Serialization.Test.Module.AnalogInputChannel).MeasuredExcitationVoltage;
// channel.Data.MvPerEu = channelInfo.ScaleFactorMVPerCnt / channelInfo.ScaleFactorEUPerCnt; // * voltage);
// channel.Data.ScaleFactorMv = channelInfo.ScaleFactorEUPerCnt * (voltage * channel.Data.MvPerEu);
//}
channel.Data.ScaleFactorMv = channelInfo.ScaleFactorMVPerCnt;
channel.Data.ScaleFactorEU = channelInfo.ScaleFactorEUPerCnt;
channel.Data.DataZeroLevel = (short)channelInfo.DataZeroLevelInCnts;
channel.Data.UseEUScaleFactors = true; //Since this is TDAS
channel.Data.MvPerEu = channelInfo.ScaleFactorMVPerCnt / channelInfo.ScaleFactorEUPerCnt;//Just to initialize to something
channel.Data.Multiplier = analogChannel.Multiplier;
channel.Data.UnitConversion = analogChannel.UnitConversion;
channel.Data.UserOffsetEU = analogChannel.UserOffsetEU;
}
catch (System.Exception ex)
{
APILogger.Log($"Exception is '{ex.Message}'");
if (ex is MissingFileException) { throw ex; }
throw new Exception("encountered problem extracting channel data from serialization", ex);
}
}//using binary stream
}//using file stream
}
catch (System.Exception)
{
throw;
}
finally { mutex.ReleaseMutex(); }
}
APILogger.Log("successfully opened file after, ", attempt, " attempts");
bFailed = false;
}//end try
catch (FileNotFoundException)
{
APILogger.Log(string.Format("File not found " + channelFileName));
throw;
}
catch (System.Exception ex)
{
//HACK ALERT! This method is eating legitimate exceptions in an attempt to satisfy some retry algorithm.
if (attempt == 30)
{
throw;
}
APILogger.Log("attempt number: ", attempt, ex);
System.Threading.Thread.Sleep(200);
}
}//end while
}
}
}
}