364 lines
20 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |