Files
DP44/Common/DTS.Common.Serialization/SliceRaw/SliceRaw.File.Writer.cs
2026-04-17 14:55:32 -04:00

364 lines
20 KiB
C#

/*
SliceRaw.File.Writer.cs
Copyright © 2009
Diversified Technical Systems, Inc.
All Rights Reserved
*/
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using DTS.Common.Utilities.Logging;
namespace DTS.Serialization.SliceRaw
{
// *** see SliceRaw.File.cs ***
public partial class File
{ ///
/// <summary>
/// Utility object for serializing <see cref="DTS.Serialization.Test"/>s to disk
/// in the SliceRaw format.
/// </summary>
///
public class Writer : Writer<File>, IWriter<Test>
{ ///
/// <summary>
/// Initialize an instance of the SliceRaw.File.Writer class.
/// </summary>
///
/// <param name="fileType">
/// The <see cref="DTS.Serialization.SliceRaw.File"/>-type this serializer is associated with.
/// </param>
///
public Writer(File fileType, int encoding)
: base(fileType, encoding)
{
}
public delegate void SetProgressDelegate(double d);
/// <summary>
/// if present will be used to notify of progress
/// used to provide "finishing download" progrses
/// 17587 Add Finishing download feedback
/// </summary>
public SetProgressDelegate SetProgress { get; set; }
/// <summary>
/// Perform disk serialization now.
/// </summary>
///
/// <param name="directory">
/// The <see cref="string"/> path of the directory to contain the written test.
/// </param>
///
/// <param name="test">
/// The <see cref="DTS.Serialization.Test"/> to be written out.
/// </param>
///
public void Write(string directory, string id, Test test, bool bFiltering, bool includeGroupNameInISOExport, double minStartTime, int dataCollectionLength)
{
try
{
Write(directory, 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 doing non-event reporting write", ex);
}
}
private void ChannelException(string problem, string channel, System.Exception ex)
{
APILogger.Log("Exception writing channel: ", channel, " field: ", problem, " exception: ", ex);
}
/// <summary>
/// Perform disk serialization now.
/// </summary>
///
/// <param name="directory">
/// The <see cref="string"/> path of the directory to contin the written test.
/// </param>
///
/// <param name="test">
/// The <see cref="DTS.Serialization.Test"/> to be written out.
/// </param>
///
/// <param name="onEvent">
/// The <see cref="DTS.Serialization.File.Writer.EventHandler"/> to be notified whenever
/// the writer does something noteworthy.
/// </param>
///
public void Write(string directory,
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)
{
System.Exception exception = null;
//int line = 0;
try
{
if (null == test)
{
throw new ArgumentNullException("cannot write null test reference");
}
//ConfigurationManager.AppSettings
test.Software = System.Reflection.Assembly.GetEntryAssembly().GetName().Name;
test.SoftwareVersion = System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString(4);
//line = 1;
var numberOfFiles = 1; // There will always be the main test file.
var numberOfTicksSent = 0;
foreach (var module in test.Modules)
numberOfFiles += module.Channels.Count;
beginEventHandler?.Invoke(this, (uint)numberOfFiles);
//line = 2;
var encoder = Encoding.Default;
try
{
//force UTF-16 for the dts file, it contains "UTF-16" in the xml by default and isn't consumed by anything that requires
//codepage exports (CSV/excel)
encoder = Common.Utils.FileUtils.GetEncoding(DefaultEncoding);
}
catch (System.Exception ex)
{
APILogger.Log("Problem getting encoder", ex);
encoder = Encoding.Default;
}
//line = 3;
using (StringWriter writer = new StringWriterWithEncoding(encoder))
{
new XmlSerializer(typeof(Test)).Serialize(writer, test);
//FB14854 Add option to move ROI Download folders into the main test folder
// Cleaned up folder get/set to accomodate ROI both within the main test folder and without
var testIdNode = id;// new DirectoryInfo(Path.GetDirectoryName(subPath)).Name;
using (var fileWriter = new StreamWriter((directory.EndsWith("\\") ? directory : directory + "\\") + testIdNode + TestFileExtension, false, encoder))
fileWriter.Write(writer.ToString());
tickEventHandler?.Invoke(this, (uint)(++numberOfTicksSent) / numberOfFiles * 100);
}
var file = 0;
if (true == bFiltering)
{
//line = 4;
foreach (var module in test.Modules)
{
//line = 5;
foreach (var channel in module.Channels)
{
file++;
if (null != cancelRequested && cancelRequested()) { break; }
CreatePersistentChannel(channel, module.NumberOfSamples, module.SampleRateHz, tickEventHandler, cancelRequested, numberOfFiles, numberOfTicksSent);
SetProgress?.Invoke(100D * file / numberOfFiles);
}
}
}
}
catch (System.Exception ex)
{
exception = new Exception("encountered problem doing test file write", ex);
}
finally
{
endEventHandler?.Invoke(this);
if (null != exception && null != errorEventHandler)
{
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 void CreatePersistentChannel(Test.Module.Channel channel,
ulong numberOfSamples,
float sampleRateHz,
TickEventHandler tickEventHandler,
CancelRequested cancelRequested,
int numberOfFiles,
int numberOfTicksSent)
{
try
{
//line = 6;
channel.ExpressDataInlineOnXmlSerialization = false;
const string DefaultIsoCode = "????????????????";
var fields = Enum.GetValues(typeof(PersistentChannel.Field)).Cast<PersistentChannel.Field>().ToArray();
foreach (var field in fields)
{
try
{
//line = 7;
if (null != cancelRequested && cancelRequested()) { break; }
switch (field)
{
case PersistentChannel.Field.AreSamplesSigned:
channel.PersistentChannelInfo.AreSamplesSigned = 1;
break;
case PersistentChannel.Field.BeginningOfData:
break;
case PersistentChannel.Field.BeginningOfFile:
break;
case PersistentChannel.Field.Crc32:
break;
case PersistentChannel.Field.DataZeroLevelCounts:
try { channel.PersistentChannelInfo.DataZeroLevelCounts = channel.DataZeroLevelAdc; }// xxx This needs to be calculated on the fly during download.
catch (System.Exception myException) { ChannelException("DataZeroLevelCounts", channel.ChannelDescriptionString, myException); }
break;
case PersistentChannel.Field.EngineeringUnit:
break;
case PersistentChannel.Field.EuFieldLengthWithTerminator:
break;
case PersistentChannel.Field.Excitation:
try { channel.PersistentChannelInfo.Excitation = channel.Excitation; }
catch (System.Exception) { }
break;
case PersistentChannel.Field.HeaderVersionNumber:
break;
case PersistentChannel.Field.IsoCode:
try
{
channel.PersistentChannelInfo.IsoCode = (channel is Common.DAS.Concepts.DAS.Channel.IIsoCodeAware)
? (channel as Common.DAS.Concepts.DAS.Channel.IIsoCodeAware).IsoCode.PadRight(DefaultIsoCode.Length, '?').ToCharArray(0, DefaultIsoCode.Length)
: DefaultIsoCode.ToCharArray();
}
catch (System.Exception myException)
{
ChannelException("IsoCode", channel.ChannelDescriptionString, myException);
}
break;
case PersistentChannel.Field.MagicKey:
break;
case PersistentChannel.Field.MvPerEu:
try { channel.PersistentChannelInfo.MvPerEu = channel.Data.MvPerEu; }
catch (System.Exception myException) { ChannelException("MvPerEu", channel.ChannelDescriptionString, myException); }
break;
case PersistentChannel.Field.NumberOfBitsPerSample:
channel.PersistentChannelInfo.NumberOfBitsPerSample = 16;
break;
case PersistentChannel.Field.NumberOfSamples:
try
{
var numSamples = (0 != numberOfSamples ? numberOfSamples : (ulong)channel.Data.Values.Length);
channel.PersistentChannelInfo.NumberOfSamples = numSamples;
}
catch (System.Exception myException) { ChannelException("NumberOfSamples", channel.ChannelDescriptionString, myException); }
break;
case PersistentChannel.Field.NumberOfTriggers:
break;
case PersistentChannel.Field.OffsetOfSampleDataStart:
try { channel.PersistentChannelInfo.OffsetOfSampleDataStart = (ulong)(channel.PersistentChannelInfo.GetFileOffsetOf(PersistentChannel.Field.BeginningOfData)); }
catch (System.Exception myException) { ChannelException("OffsetOfSampleDataStart", channel.ChannelDescriptionString, myException); }
break;
case PersistentChannel.Field.OriginalOffsetADC:
try { channel.PersistentChannelInfo.OriginalOffsetADC = channel.OriginalOffsetADC; }
catch (System.Exception) { }
break;
case PersistentChannel.Field.PostTestDiagnosticsLevelCounts:
try { channel.PersistentChannelInfo.PostTestDiagnosticsLevelCounts = 0; }
catch (System.Exception myException) { ChannelException("PostTestDiagnosticsLevelCounts", channel.ChannelDescriptionString, myException); }
break;
case PersistentChannel.Field.PostTestZeroLevelCounts:
try { channel.PersistentChannelInfo.PostTestZeroLevelCounts = channel.PreTestZeroLevelAdc; }
catch (System.Exception myException) { ChannelException("PostTestZeroLevelCounts", channel.ChannelDescriptionString, myException); }
break;
case PersistentChannel.Field.PreTestDiagnosticsLevelCounts:
channel.PersistentChannelInfo.PreTestDiagnosticsLevelCounts = 0;
break;
case PersistentChannel.Field.PreTestNoisePercentageOfFullScale:
try { channel.PersistentChannelInfo.PreTestNoisePercentageOfFullScale = channel.NoiseAsPercentageOfFullScale; }
catch (System.Exception myException) { ChannelException("PreTestNoisePercentageOfFullScale", channel.ChannelDescriptionString, myException); }
break;
case PersistentChannel.Field.PreTestZeroLevelCounts:
try { channel.PersistentChannelInfo.PreTestZeroLevelCounts = channel.PreTestZeroLevelAdc; }
catch (System.Exception myException) { ChannelException("PreTestZeroLevelCounts", channel.ChannelDescriptionString, myException); }
break;
case PersistentChannel.Field.RemovedADC:
try { channel.PersistentChannelInfo.RemovedADC = channel.RemovedADC; }
catch (System.Exception) { }
break;
case PersistentChannel.Field.SampleRate:
try { channel.PersistentChannelInfo.SampleRate = sampleRateHz; }
catch (System.Exception myException) { ChannelException("SampleRate", channel.ChannelDescriptionString, myException); }
break;
case PersistentChannel.Field.ScaleFactorMv:
try { channel.PersistentChannelInfo.ScaleFactorMv = channel.Data.ScaleFactorMv; }
catch (System.Exception myException) { ChannelException("ScaleFactorMv", channel.ChannelDescriptionString, myException); }
break;
case PersistentChannel.Field.TriggerAdjustmentSamples:
try { channel.PersistentChannelInfo.TriggerAdjustmentSamples = channel.TriggerAdjustmentSamples; }
catch (System.Exception) { }
break;
case PersistentChannel.Field.TriggerSampleNumbers:
break;
case PersistentChannel.Field.ZeroMvInADC:
try { channel.PersistentChannelInfo.ZeroMvInADC = channel.ZeroMvInADC; }
catch (System.Exception) { }
break;
case PersistentChannel.Field.WindowAverageADC:
try { channel.PersistentChannelInfo.WindowAverageADC = channel.WindowAverageADC; }
catch (System.Exception) { }
break;
}
}
catch (System.Exception ex)
{
APILogger.Log("exception writing serializing channel header, field: " + field.ToString());
throw ex;
}
}
channel.PersistentChannelInfo.StampCrc();
// force file handle release
try
{
channel.PersistentChannelInfo.Dispose();
channel.PersistentChannelInfo = null;
}
catch (System.Exception) { }
tickEventHandler?.Invoke(this, (uint)(++numberOfTicksSent) / numberOfFiles * 100);
}
catch (System.Exception channelException)
{
APILogger.Log("Exception writing serializing channel header, Channel: ", channel.ChannelDescriptionString, " Exception: ", channelException);
}
}
}
}
}