646 lines
37 KiB
C#
646 lines
37 KiB
C#
/*
|
|
* 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;
|
|
}
|
|
}
|
|
}
|