Files
DP44/Common/DTS.Common.Serialization/Diadem.File.Writer.cs

646 lines
37 KiB
C#
Raw Normal View History

2026-04-17 14:55:32 -04:00
/*
* Diadem.File.Writer.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using DTS.Common.DAS.Concepts;
using DTS.Common.Enums.Sensors;
using DTS.Common.Utilities;
using DTS.Common.Utilities.Logging;
using System.Linq;
namespace DTS.Serialization.Diadem
{
// *** see Diadem.File.cs ***
public partial class File
{ ///
/// <summary>
/// Utility object for serializing <see cref="DTS.Serialization.Test"/>s to disk
/// in the Diadem
/// </summary>
///
public class Writer : Writer<File>, IWriter<Test>
{
public File WriterParent { get; set; }
public bool UseEVG20 { get; set; } = false;
public Common.ISO.TestPlan TestPlan { get; set; } = null;
public DiademOptions ChannelName200Option { get; set; }
public DiademOptions UserComment201Option { get; set; }
public DiademOptionsReserved1 Reserved1_301Option { get; set; }
public DiademOptionsReserved2 Reserved2_302Option { get; set; }
public string ExtensionPrefix { get; set; } = string.Empty;
/// <summary>
/// Initialize an instance of the Diadem.File.Writer class.
/// </summary>
///
/// <param name="fileType">
/// The associated <see cref="DTS.SErialization.Diadem.File"/> object.
/// </param>
///
internal Writer(File fileType, int encoding)
: base(fileType, encoding)
{
}
/// <summary>
/// Write the specified test to the specified pathname.
/// </summary>
///
/// <param name="pathname">
/// The <see cref="string"/> pathname to which the specified test should be serialized.
/// </param>
///
/// <param name="test">
/// The <see cref="DTS.Serialization.Test"/> to be written out.
/// </param>
///
public void Write(string pathname, string id, Test test, bool bFiltering, bool includeGroupNameInISOExport, double minStartTime, int dataCollectionLength)
{
try
{
Write(pathname, id, null, test, bFiltering, includeGroupNameInISOExport, null, null, 0, null, null, null, null, null, null, minStartTime, dataCollectionLength);
}
catch (System.Exception ex)
{
throw new Exception("encountered problem non-event notified writing test", ex);
}
}
/// <summary>
/// Write the representation file/files of the specified DTS.Serialization.Test
/// at the given pathname.
/// </summary>
///
/// <param name="targetPathname">
/// The <see cref="string"/> pathname of the specified object's resulting file
/// representation.
/// </param>
///
public void Write(string pathname,
string id,
string dataFolder,
Test test,
bool bFiltering,
bool includeGroupNameInISOExport,
FilteredData fd,
Test.Module.Channel tmChannel,
int channelNumber,
BeginEventHandler beginEventHandler,
CancelEventHandler cancelEventHandler,
EndEventHandler endEventHandler,
TickEventHandler tickEventHandler,
ErrorEventHandler errorEventHandler,
CancelRequested cancelRequested,
double minStartTime,
int dataCollectionLength)
{
Exception exception = null;
try
{
if (!Directory.Exists(pathname))
Directory.CreateDirectory(pathname);
var filename = Path.Combine(pathname, id + (ExtensionPrefix ?? "") + ".dat");
//using ( StreamWriter fileWriter = new StreamWriter( pathname, false ) )
Encoding encoder;
try
{
encoder = Common.Utils.FileUtils.GetEncoding(DefaultEncoding);
}
catch (System.Exception ex)
{
APILogger.Log("Problem getting encoder", ex);
encoder = Encoding.Default;
}
using (var fileWriter = new StreamWriter(filename, false, encoder))
{
beginEventHandler?.Invoke(this, 1);
//
// Determine the exact number of bytes that will be required by the export and
// see if we have enough space for it.
//
var countFileName = filename + ".tmp";
using (var characterCounter = new CharacterCountingStreamWriter(countFileName, false, encoder))
{
WriteChannelInfo(characterCounter, test, id, null, dataFolder, cancelRequested, pathname, UseEVG20, TestPlan);
var predictedExportSize = characterCounter.CharactersCounted * sizeof(char);
// Get the stats on available disk space.
//string saveLocation = countFileName.Remove(countFileName.IndexOf(System.IO.Path.VolumeSeparatorChar) + 1);
var saveLocation = pathname + "\\";
DiskUtility.GetDiskFreeSpaceEx(saveLocation, out ulong freeBytesAvailable, out ulong totalNumberOfBytes, out ulong totalNumberOfFreeBytes);
// Do the comparison.
if (freeBytesAvailable < predictedExportSize)
{
var bytesNeeded = DiskUtility.GetHumanReadableBytes(predictedExportSize);
var bytesAvailable = DiskUtility.GetHumanReadableBytes(freeBytesAvailable);
throw new UserException("Export requires " + bytesNeeded + " but there are only " + bytesAvailable + " available on \"" + saveLocation + "\"");
}
}
if (System.IO.File.Exists(countFileName))
System.IO.File.Delete(countFileName);
WriteChannelInfo(fileWriter, test, id, tickEventHandler, dataFolder, cancelRequested, pathname, UseEVG20, TestPlan);
tickEventHandler?.Invoke(this, 100.0);
endEventHandler?.Invoke(this);
}
}
catch (System.Exception ex)
{
exception = new Exception("encountered problem writing Diadem test files", ex);
APILogger.Log("encountered problem writing Diadem test files", ex);
}
if (null != errorEventHandler && null != exception)
{
endEventHandler(this);
errorEventHandler(this, exception);
}
else if (null != exception) { throw exception; }
}
public void Initialize(string pathname,
string id,
string dataFolder,
Test test,
bool bFiltering,
bool includeGroupNameInISOExport,
FilteredData fd,
Test.Module.Channel tmChannel,
int channelNumber,
BeginEventHandler beginEventHandler,
CancelEventHandler cancelEventHandler,
EndEventHandler endEventHandler,
TickEventHandler tickEventHandler,
ErrorEventHandler errorEventHandler,
CancelRequested cancelRequested)
{
}
public bool UseIsoCodeForDiadem200 { get; set; }
public bool UseZeroForUnfiltered { get; set; }
private const string INSTRUMENTATION_STANDARD = "SAE J 211";
private const string DATA_FORMAT_EDITION_NUMBER = "1.5";
private const string BITRESOLUTION = "16";
private void CreateConvertedData(Test.Module.Channel CurrentChannel, string fileTypeSuffix, string pathName)
{
var sChnName = CurrentChannel.PersistentChannelInfo.Filename;
var sNewFileName = sChnName.Replace(".chn", fileTypeSuffix);
var bytes = new List<byte>(100000);
var dataScaler = new DataScaler();
double[] data = null;
data = GetEUData(CurrentChannel);
for (ulong i = 0; i < CurrentChannel.ParentModule.NumberOfSamples; i++)
{
bytes.AddRange(BitConverter.GetBytes(data[i]));
}
System.IO.File.WriteAllBytes(sNewFileName, bytes.ToArray());
APILogger.Log("copying ", sNewFileName);
System.IO.File.Copy(sNewFileName, Path.Combine(Path.GetFullPath(pathName), Path.GetFileName(sNewFileName)), true);
//this will create a csv file that can be easily read to verify the .lin/.dig file content
//var newFile = sNewFileName.ToLower().Replace(".lin", ".csv");
//newFile = newFile.Replace(".dig", ".csv");
//var sb = new StringBuilder(50000);
//if (System.IO.File.Exists(newFile))
//{
// Common.Utils.FileUtils.DeleteFileOrMove(newFile, APILogger.Log);
//}
//for (ulong i = 0; i < CurrentChannel.ParentModule.NumberOfSamples; i++)
//{
// sb.AppendLine($",{data[i]}");
//}
//System.IO.File.AppendAllText(newFile, sb.ToString());
//This file didn't exist when the .chn files were copied from the Binary folder, so do it now
//System.IO.File.Copy(newFile, Path.Combine(Path.GetFullPath(pathName), Path.GetFileName(newFile)), true);
}
private double[] GetEUData(Test.Module.Channel channel)
{
//if (FilteredExport) { return _EUFilteredDataForLinearizedChannels[channel.AbsoluteDisplayOrder].Data; }
//else { return _EUUnfilteredDataForLinearizedChannels[channel.AbsoluteDisplayOrder].Data; }
return WriterParent.GetEUData(channel.ChannelId).Data;
}
//private Dictionary<int, Serialization.FilteredData> _EUFilteredDataForLinearizedChannels = new Dictionary<int, double[]>();
/// <summary>
/// Write the specified test to the specified stream.
/// </summary>
///
/// <param name="fileWriter">
/// The <see cref="System.IO.StreamWriter"/> to which the specified test should be serialized.
/// </param>
///
/// <param name="test">
/// The <see cref="DTS.Serialization.Test"/> to be serialized.
/// </param>
///
/// <param name="writeEvent">
/// The <see cref="Diadem.File.Writer.EventHandler"/> that should handle write-progress
/// reporting; null if none is to be used.
/// </param>
///
protected void WriteChannelInfo
(
StreamWriter fileWriter,
Test test,
string testId,
TickEventHandler tickEventHandler,
string dataFolder,
CancelRequested cancelRequested,
string pathName,
bool bUseEGV20,
Common.ISO.TestPlan testPlan
)
{
try
{
fileWriter.WriteLine("DIAEXTENDED {@:ENGLISH");
fileWriter.WriteLine("");
fileWriter.WriteLine("#BEGINGLOBALHEADER"); // GENERAL HEADER
fileWriter.WriteLine("1,WINDOWS"); // OPERATING SYSTEM
fileWriter.WriteLine("2,@R:302"); // REVISION NUMBER
fileWriter.WriteLine("101," + test.Description); // FILE COMMENT
if (UseEVG20)
{
fileWriter.WriteLine("102," + testPlan.GetField(Common.ISO.TestPlan.IsoFields.LaboratoryName));//header 1
fileWriter.WriteLine("102," + testPlan.GetField(Common.ISO.TestPlan.IsoFields.LaboratoryContactName));//header 2
fileWriter.WriteLine("102," + testPlan.GetField(Common.ISO.TestPlan.IsoFields.LaboratoryContactPhone));//header 3
fileWriter.WriteLine("102," + testPlan.GetField(Common.ISO.TestPlan.IsoFields.LaboratoryContactFax));//header 4
fileWriter.WriteLine("102," + testPlan.GetField(Common.ISO.TestPlan.IsoFields.CustomerName));//header 5
fileWriter.WriteLine("102," + testPlan.GetField(Common.ISO.TestPlan.IsoFields.LaboratoryTestReferenceNumber));//header 6
fileWriter.WriteLine("102," + testPlan.GetField(Common.ISO.TestPlan.IsoFields.CustomerTestReferenceNumber));//header 7
fileWriter.WriteLine("102," + testPlan.GetField(Common.ISO.TestPlan.IsoFields.Title));//header 8
fileWriter.WriteLine("102," + testPlan.GetField(Common.ISO.TestPlan.IsoFields.NumberOfMedia));//header 9
fileWriter.WriteLine("102," + testPlan.GetField(Common.ISO.TestPlan.IsoFields.Type));//header 10
fileWriter.WriteLine("102," + testPlan.GetField(Common.ISO.TestPlan.IsoFields.Date));//header 11
fileWriter.WriteLine("102," + INSTRUMENTATION_STANDARD);//header 12
fileWriter.WriteLine("102," + test.Channels.Count.ToString(System.Globalization.CultureInfo.InvariantCulture));//header 13
fileWriter.WriteLine("102," + DATA_FORMAT_EDITION_NUMBER);//header 14
fileWriter.WriteLine("102,");//header 15
fileWriter.WriteLine("102,");//header 16
fileWriter.WriteLine("102,");//header 17
fileWriter.WriteLine("102,");//header 18
fileWriter.WriteLine("102," + testPlan.GetField(Common.ISO.TestPlan.IsoFields.TestEngineerName));//header 19, FB13148: DIAdem export not populating MIRA QA header specific numbers
fileWriter.WriteLine("102," + testPlan.NumberOfTestObjects);//header 20
foreach (var to in testPlan.ISOTestObjects)
{
fileWriter.WriteLine("102," + to.Name);//header 21
fileWriter.WriteLine("102," + to.VelocityMeterPerSecond);//header 22
fileWriter.WriteLine("102," + to.MassOfTestObject);//header 23
fileWriter.WriteLine("102," + QuickParse(to.DriverPosition));//header 24
fileWriter.WriteLine("102," + QuickParse(to.ImpactSide));//header 25
}
fileWriter.WriteLine("103,");
}
fileWriter.WriteLine("104," + test.InceptionDate.ToShortDateString());
fileWriter.WriteLine("105," + test.InceptionDate.ToShortTimeString());
fileWriter.WriteLine("#ENDGLOBALHEADER");
fileWriter.WriteLine("");
/* WRITE CHANNEL HEADERS */
/* WRITE TIME HEADER */
fileWriter.WriteLine("#BEGINCHANNELHEADER"); // CHANNEL HEADER
if (UseIsoCodeForDiadem200)
{
fileWriter.WriteLine("200,000000000000TI00");
}
else
{
fileWriter.WriteLine("200,Time axis"); // CHANNEL NAME
}
fileWriter.WriteLine("201,Time"); // CHANNEL COMMENTS
fileWriter.WriteLine("202,s");// UNIT
//get the trigger sample number, if not present, use 0
double trigger = 0;
if (test.Modules[0].TriggerSampleNumbers.Count > 0) { trigger = test.Modules[0].TriggerSampleNumbers[0]; }
//ordinarily pretrigger is negative and goes is calculated from 0 to trigger. However, the start
//might actually be AFTER the trigger (and should be positive) and might not go from 0
var startSampleAdjusted = test.Modules[0].StartRecordSampleNumber - trigger;//adjusted for T0
var start = startSampleAdjusted / test.Modules[0].SampleRateHz;
var maxTime = ((double)test.Modules[0].NumberOfSamples - 1) / test.Modules[0].SampleRateHz + start;
fileWriter.WriteLine("210,IMPLICIT"); // CHANNEL TYPE
fileWriter.WriteLine("213,CHANNEL");
fileWriter.WriteLine("214,REAL64");
fileWriter.WriteLine("220," + test.Modules[0].NumberOfSamples.ToString(System.Globalization.CultureInfo.InvariantCulture)); // NO OF VALUES IN CHANNEL
fileWriter.WriteLine("240," + start.ToString(System.Globalization.CultureInfo.InvariantCulture)); // STARTING VALUE
fileWriter.WriteLine("241," + (1D / test.Modules[0].SampleRateHz).ToString(System.Globalization.CultureInfo.InvariantCulture));// SCALING FACTOR
fileWriter.WriteLine("250," + start.ToString(System.Globalization.CultureInfo.InvariantCulture));// MINIMUM VALUE
//now we want to calculate the post trigger, or the max time value
//note this could be negative if our test data is -10s to -5s, or our test could go 5s to 10s..
//so calculate total time, and then adjust by the start. so -10s to -5s; 5s total time - 10s start = -5s is where end is at
fileWriter.WriteLine("251," + maxTime.ToString(System.Globalization.CultureInfo.InvariantCulture)); //MAXIMUM VALUE
fileWriter.WriteLine("252,No"); // NOVALUES IN THE CHANNEL
fileWriter.WriteLine("253,increasing"); // MONOTONY
//}
fileWriter.WriteLine("260,Numeric"); // DATA DISPLAY AT THE INTERFACE
fileWriter.WriteLine("271," + (1D / test.Modules[0].SampleRateHz).ToString(System.Globalization.CultureInfo.InvariantCulture));// Samplerate - FB 13384
fileWriter.WriteLine("280,1"); // object for time channel
fileWriter.WriteLine("#ENDCHANNELHEADER");
var exportChannels = test.Channels;
foreach (var CurrentChannel in exportChannels)
{
var bLinear = false;
var bDigital = false;
if ((CurrentChannel is Test.Module.AnalogInputChannel) && (CurrentChannel as Test.Module.AnalogInputChannel).LinearizationFormula.IsValid())
{
CreateConvertedData(CurrentChannel, ".lin", pathName);
bLinear = true;
}
if ((CurrentChannel is Test.Module.AnalogInputChannel) && (CurrentChannel as Test.Module.AnalogInputChannel).IsDigital())
{
CreateConvertedData(CurrentChannel, ".dig", pathName);
bDigital = true;
}
if (CurrentChannel is Test.Module.CalculatedChannel) { continue; }
fileWriter.WriteLine("");
fileWriter.WriteLine("#BEGINCHANNELHEADER"); // CHANNEL HEADER
fileWriter.Write("200,");
var isoChannel = CurrentChannel as Common.DAS.Concepts.DAS.Channel.IIsoCodeAware;
var isoCodeUnfiltered = string.Empty;
var paddedIsoCode = new Common.ISO.IsoCode(isoChannel.IsoCode).StringRepresentation;
if (UseZeroForUnfiltered || paddedIsoCode.Substring(15, 1) == "0")
{
isoCodeUnfiltered = paddedIsoCode.Substring(0, 15) + "0";
}
else
{
isoCodeUnfiltered = paddedIsoCode.Substring(0, 15) + "P";
}
fileWriter.WriteLine(GetDiademString(ChannelName200Option, CurrentChannel, isoChannel, isoCodeUnfiltered));
if (CurrentChannel is Common.DAS.Concepts.DAS.Channel.IIsoCodeAware)
{
fileWriter.WriteLine("201," + GetDiademString(UserComment201Option, CurrentChannel, isoChannel, isoCodeUnfiltered));
}
fileWriter.WriteLine("202," + ((Test.Module.AnalogInputChannel)(CurrentChannel)).EngineeringUnits.TrimEnd(null)); // UNIT
fileWriter.WriteLine("210,EXPLICIT"); // CHANNEL TYPE
var diademFormattedFolder = Path.GetFullPath(dataFolder);
string fileNameWithEvent = null;
var eventNum = dataFolder.Split('\\').Last();
if (eventNum.StartsWith($"{DTS.Common.Constants.EventNumber}"))
{
var segments = CurrentChannel.PersistentChannelInfo.Filename.Split('\\');
var indexOfEvent = (segments.Length - 2);
if (segments[indexOfEvent] != eventNum)
{
fileNameWithEvent = CurrentChannel.PersistentChannelInfo.Filename.Replace(segments[indexOfEvent], eventNum);
}
}
var sFileName = GetRelativeFileName(fileNameWithEvent ?? CurrentChannel.PersistentChannelInfo.Filename, diademFormattedFolder);
if (bLinear) { fileWriter.WriteLine("211," + sFileName.Replace(".chn", ".lin")); }
else if (bDigital) { fileWriter.WriteLine("211," + sFileName.Replace(".chn", ".dig")); }
else { fileWriter.WriteLine("211," + sFileName); }
fileWriter.WriteLine("213,CHANNEL"); // METHOD OF STORING THE DATA
if (bLinear || bDigital) { fileWriter.WriteLine("214,REAL64"); }
else { fileWriter.WriteLine("214,INT16"); } // DATA TYPE
if (UseEVG20) { fileWriter.WriteLine("215,-1"); }
fileWriter.WriteLine("220," + CurrentChannel.PersistentChannelInfo.Length.ToString(System.Globalization.CultureInfo.InvariantCulture)); // NO OF VALUES IN CHANNEL
if (bLinear || bDigital) { fileWriter.WriteLine("221,1"); }
else { fileWriter.WriteLine("221, " + (1 + CurrentChannel.PersistentChannelInfo.OffsetOfSampleDataStart / 2).ToString(System.Globalization.CultureInfo.InvariantCulture)); }
double initialEU = 0;
var dataScaler = new DataScaler();
//28183 EU offset made in View Data not showing correctly when exported
//originally in the calculation for line 240 both initial EU and user offset were being applied
//instead I created a variable that holds either initialEU or the original initialEU + user offset
//this corrects the one situation I see it being calculated incorrectly while hopefully not affecting anything else
var offsetToApplyToLine240 = 0D;
if (CurrentChannel is Test.Module.AnalogInputChannel)
{ //
// If we have access to enough information to initialize a scaling object,
// then use one.
//
var analogChannel = CurrentChannel as Test.Module.AnalogInputChannel;
initialEU = analogChannel.InitialEu;
dataScaler.NominalExcitationVoltage = analogChannel.ExcitationVoltage;
try { dataScaler.MeasuredExcitationVoltage = analogChannel.MeasuredExcitationVoltage; } catch { };
try { dataScaler.FactoryExcitationVoltage = analogChannel.FactoryExcitationVoltage; } catch { };
dataScaler.IsInverted = analogChannel.IsInverted;
dataScaler.SetLinearizationFormula(analogChannel.LinearizationFormula);
dataScaler.SetMvPerEu(analogChannel.Data.MvPerEu);
dataScaler.ProportionalToExcitation = analogChannel.ProportionalToExcitation;
dataScaler.BasedOnOutputAtCapacity = analogChannel.AtCapacity;
dataScaler.CapacityOutputIsBasedOn = analogChannel.CapacityOutputIsBasedOn;
dataScaler.SensitivityUnits = analogChannel.SensitivityUnits;
dataScaler.SetScaleFactorMv(analogChannel.Data.ScaleFactorMv);
dataScaler.SetScaleFactorEU(analogChannel.Data.ScaleFactorEU);
dataScaler.SetUseEUScaleFactors(analogChannel.Data.UseEUScaleFactors);
dataScaler.UnitConversion = analogChannel.UnitConversion;
dataScaler.IEPE = analogChannel.Bridge == SensorConstants.BridgeType.IEPE;
dataScaler.Digital = analogChannel.Bridge == SensorConstants.BridgeType.DigitalInput;
dataScaler.SetLinearizationFormula(analogChannel.LinearizationFormula);
dataScaler.SetDigitalMultiplier(analogChannel.DigitalMultiplier);
dataScaler.Digital = analogChannel.IsDigital();
dataScaler.DigitalMode = analogChannel.DigitalMode;
dataScaler.Multiplier = analogChannel.Multiplier;
dataScaler.UserOffsetEU = analogChannel.UserOffsetEU;
try
{
if (analogChannel.RemoveOffset) { dataScaler.SetRemovedADC(analogChannel.RemovedADC); dataScaler.SetRemovedInternalADC(analogChannel.RemovedInternalADC); }
else { dataScaler.SetRemovedADC(0); dataScaler.SetRemovedInternalADC(0); }
dataScaler.SetZeroMvInADC(analogChannel.ZeroMvInADC);
try { dataScaler.SetWindowAverageADC(analogChannel.WindowAverageADC); }
catch (System.Exception) { }
dataScaler.SetDataZeroLevelADC(analogChannel.DataZeroLevelAdc);
dataScaler.SetInitialOffset(analogChannel.InitialOffset);
dataScaler.ZeroMethodType = analogChannel.ZeroMethod;
//19039 Export data in DIAdem not respecting initial offset(EU at mV) settings.
//initialEU is set above only using analogChannel.InitialEU and not taking into consideration
//InitialOffset. If InitialEU is 0, then there's a chance we should be considering InitialOffset
//since I want to minimize the impact of the changes limiting when it's done
var euAtDataZeroLevelADC = dataScaler.GetEU(CurrentChannel.DataZeroLevelAdc);
if (0 != euAtDataZeroLevelADC && 0 == initialEU && !string.IsNullOrWhiteSpace(analogChannel.InitialOffset))
{
initialEU = euAtDataZeroLevelADC;
offsetToApplyToLine240 = initialEU;
}
else
{
offsetToApplyToLine240 = initialEU + dataScaler.UserOffsetEU;
}
}
catch (System.Exception) { }
}
var adcToEUScaler = dataScaler.GetAdcToEuScalingFactor() * dataScaler.Multiplier;
if (bLinear || bDigital) { fileWriter.WriteLine("240,0"); }
else
{
fileWriter.WriteLine("240," + ((-1D * adcToEUScaler * CurrentChannel.DataZeroLevelAdc) + offsetToApplyToLine240).ToString(System.Globalization.CultureInfo.InvariantCulture));
}
if (bLinear || bDigital) { fileWriter.WriteLine("241,1"); }
else { fileWriter.WriteLine("241," + adcToEUScaler.ToString(System.Globalization.CultureInfo.InvariantCulture)); } // SCALING FACTOR
fileWriter.WriteLine("260,Numeric"); // DATA DISPLAY AT THE INTERFACE
if (UseEVG20)
{
if (CurrentChannel is Test.Module.AnalogInputChannel)
{ //
// If we have access to enough information to initialize a scaling object,
// then use one.
//
var analogChannel = CurrentChannel as Test.Module.AnalogInputChannel;
if (bLinear || bDigital) { fileWriter.WriteLine("270,120"); }
else { fileWriter.WriteLine("270," + analogChannel.DesiredRange.ToString("F1", System.Globalization.CultureInfo.InvariantCulture)); }
fileWriter.WriteLine("271," + (1D / test.Modules[0].SampleRateHz).ToString(System.Globalization.CultureInfo.InvariantCulture));
fileWriter.WriteLine("272," + start.ToString(System.Globalization.CultureInfo.InvariantCulture));//+ CurrentChannel.TimeOfFirstSampleSec.ToString("F1", System.Globalization.CultureInfo.InvariantCulture));
fileWriter.WriteLine("280," + GetTestObjectNumber(analogChannel.IsoCode, testPlan));
fileWriter.WriteLine("281," + BITRESOLUTION);
fileWriter.WriteLine("300," + testPlan.GetField(Common.ISO.TestPlan.IsoFields.CustomerTestReferenceNumber));
// 43958 Add Group Name as a possibility instead of AAF Rate in Reserved 1
if (Reserved1_301Option != DiademOptionsReserved1.NONE)
{
// AAF Rate or Group Name
switch (Reserved1_301Option)
{
case DiademOptionsReserved1.AAF_RATE:
fileWriter.WriteLine("301," + analogChannel.ParentModule.AaFilterRateHz.ToString("F1", System.Globalization.CultureInfo.InvariantCulture));
break;
case DiademOptionsReserved1.GROUP_NAME:
fileWriter.WriteLine("301," + analogChannel.ChannelGroupName);
break;
}
}
// FB43958: Add Channel Sensitivity as a possibility in Reserved 2
if (Reserved2_302Option != DiademOptionsReserved2.NONE)
{
fileWriter.WriteLine("302," + analogChannel.Sensitivity);
}
}
}
fileWriter.WriteLine("#ENDCHANNELHEADER");
}
}
catch (System.Exception ex)
{
throw new Exception("encountered problem writing DIAdem channel headers", ex);
}
}
private string GetDiademString(DiademOptions option, Test.Module.Channel CurrentChannel, Common.DAS.Concepts.DAS.Channel.IIsoCodeAware isoChannel, string isoCodeUnfiltered)
{
var diademString = string.Empty;
switch (option)
{
// FB16225: rename "channel comment" to "channel name"
case DiademOptions.CHANNEL_NAME:
diademString = null != isoChannel ? CurrentChannel.IsoChannelName :
!string.IsNullOrEmpty(CurrentChannel.UserChannelName) ? CurrentChannel.UserChannelName :
CurrentChannel.ChannelName2;
//18664 DIAdem.dat file no longer includes sensor names
//if we have an empty isochannel name/name, see if we can use channelname2 as a substitute
if (string.IsNullOrWhiteSpace(diademString) && !string.IsNullOrWhiteSpace(CurrentChannel.ChannelName2))
{
diademString = CurrentChannel.ChannelName2;
}
break;
case DiademOptions.ISO_CODE:
diademString = null != isoChannel ? isoCodeUnfiltered : CurrentChannel.ChannelDescriptionString;
break;
case DiademOptions.NONE:
break;
case DiademOptions.SENSOR_SERIAL_NUMBER:
if (CurrentChannel is Test.Module.AnalogInputChannel aic)
{
diademString = aic.IsSquib() ? aic.Description : aic.SerialNumber;
}
break;
}
return diademString;
}
public string GetTestObjectNumber(string isocode, Common.ISO.TestPlan plan)
{
var ic = new Common.ISO.IsoCode(isocode);
var testobjectcharacter = ic.TestObject;
var objectNumber = 1;
foreach (var to in plan.ISOTestObjects)
{
if (to.TypeOfTestObject == testobjectcharacter) { return objectNumber.ToString(System.Globalization.CultureInfo.InvariantCulture); }
objectNumber++;
}
return objectNumber.ToString("1");
}
/// <summary>
/// handles RE - rear, 1 - Left, etc
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private string QuickParse(string input)
{
var index = input.IndexOf("-");
if (index > 0)
{
return input.Substring(0, index - 1);
}
return input;
}
}
private static string GetRelativeFileName(string AbsoluteFileName, string RootFolder)
{
//diadem files are in the same directory now, just needs the file name.
return new FileInfo(AbsoluteFileName).Name;
}
}
}