init
This commit is contained in:
219
Common/DTS.Common.Serialization/TDM/Writer.cs
Normal file
219
Common/DTS.Common.Serialization/TDM/Writer.cs
Normal file
@@ -0,0 +1,219 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using DTS.Common.DAS.Concepts;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.Serialization.TDM
|
||||
{
|
||||
public class Writer : Serialization.File.Writer<File>, IWriter<Test>
|
||||
{
|
||||
public bool AllowTTSExportFiltering { get; set; } = false;
|
||||
public double Start { get; set; }
|
||||
public double Stop { get; set; }
|
||||
|
||||
public List<FilteredData> FilteredData { get; set; }
|
||||
public Test Test { get; set; }
|
||||
public ulong IncrementLevel { get; private set; }
|
||||
public ushort SubSampleInterval { get; set; }
|
||||
public string ExtensionPrefix { get; set; } = string.Empty;
|
||||
internal Writer(File fileType, int encoding)
|
||||
: base(fileType, encoding)
|
||||
{
|
||||
}
|
||||
///
|
||||
/// <summary>
|
||||
/// Generate the path-specified serialization from the given object.
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="pathname">
|
||||
/// The <see cref="string"/> pathname to which the serialization will be written.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="target">
|
||||
/// The object to be serialized.
|
||||
/// </param>
|
||||
///
|
||||
public void Write(string pathname, string id, Test target, bool bFiltering, bool includeGroupNameInISOExport, double minStartTime, int dataCollectionLength)
|
||||
{
|
||||
throw new NotSupportedException("TDM::Writer Write(pathname, id, test, bFiltering) not supported");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate the path-specified serialization from the given object.
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="pathname">
|
||||
/// The <see cref="string"/> pathname to which the serialization will be written.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="target">
|
||||
/// The object to be serialized.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="onBeginEvent">
|
||||
/// The <see cref="DTS.Serialization.BeginEventHandler"/> to be notified when the write begins.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="onEndEvent">
|
||||
/// The <see cref="DTS.Serialization.EndEventHandler"/> to be notified when the write completes.
|
||||
/// </param>
|
||||
///
|
||||
/// <param name="onTickEvent">
|
||||
/// The <see cref="DTS.Serialization.TickEventHandler"/> to be notified when the write "progresses".
|
||||
/// </param>
|
||||
///
|
||||
public void Write(string pathname,
|
||||
string id,
|
||||
string dataFolder,
|
||||
Test target,
|
||||
bool bFiltering,
|
||||
bool includeGroupNameInISOExport,
|
||||
FilteredData fd,
|
||||
Test.Module.Channel tmChannel,
|
||||
int channelNumber,
|
||||
BeginEventHandler onBeginEvent,
|
||||
CancelEventHandler onCancelEvent,
|
||||
EndEventHandler onEndEvent,
|
||||
TickEventHandler onTickEvent,
|
||||
ErrorEventHandler onErrorEvent,
|
||||
CancelRequested cancelRequested,
|
||||
double minStartTime,
|
||||
int dataCollectionLength)
|
||||
{
|
||||
Test = target;
|
||||
try
|
||||
{
|
||||
_onTickEvent = onTickEvent;
|
||||
|
||||
//There are some cases in Data Pro where the UI is storing precision that is not communicated to the user. For example, an ROI of 0.500 seconds
|
||||
// may actually be represented as 0.5001. There is nothing magic about it - standard floating point problem. However the roots
|
||||
// of it are actually in differences between the download code of TDAS and SLICE. SLICE doesn't care about trigger sample numbers, but
|
||||
// TDAS download is expressed as sample around t=0 with t=0 sample implied. This too is not really a big deal. Where it gets ugly is in reconciling
|
||||
// the fact that Data PRO, SLICEWare, and the services are written around the SLICE model.
|
||||
|
||||
// For now (and this is definitely a hack), round to the nearest millisecond. This should be transparent if/when the root problem is fixed.
|
||||
|
||||
Start = Math.Round(Start, 3);
|
||||
Stop = Math.Round(Stop, 3);
|
||||
|
||||
|
||||
var maxRate = Test.Channels.Select(ch => ch.ParentModule.SampleRateHz).Max();
|
||||
|
||||
|
||||
var numSamples = (Stop - Start) * maxRate;
|
||||
|
||||
//the way the dataform handles ticks is a little weird, it expects an uint below and can only handle single tick
|
||||
//progress updates, despite saying "percentage", so this is just a safety check for the case of large number of samples
|
||||
//it's probably won't be needed.
|
||||
if (numSamples * 2D / 100 > int.MaxValue) { IncrementLevel = 10000; }
|
||||
else if (numSamples < 10000) { IncrementLevel = 10; }//also probably unlikely, but in the case of
|
||||
//a huge number of channels and not many samples, it'd be nice to see something
|
||||
else { IncrementLevel = 1000; }
|
||||
|
||||
var ticksNeeded = 4D + 2D * numSamples / IncrementLevel;
|
||||
onBeginEvent?.Invoke(this, Convert.ToUInt32(ticksNeeded));
|
||||
DoExport(false, pathname, Start, Stop, AllowTTSExportFiltering);
|
||||
}
|
||||
catch (System.Exception ex) { throw ex; }
|
||||
finally
|
||||
{
|
||||
onTickEvent?.Invoke(this, 100D);
|
||||
onEndEvent?.Invoke(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
private TickEventHandler _onTickEvent;
|
||||
public void IncrementDone(double amount)
|
||||
{
|
||||
_onTickEvent(this, amount);
|
||||
}
|
||||
|
||||
private void DoExport(bool bFiltered, string pathname, double start, double stop, bool allowTTSFilteredExport)
|
||||
{
|
||||
var format = "{0}{1}.csv";
|
||||
|
||||
var fileName = System.IO.Path.Combine(pathname, Test.Id);
|
||||
|
||||
if (1 != SubSampleInterval)
|
||||
{
|
||||
fileName += "_Subsampled";
|
||||
}
|
||||
|
||||
fileName = string.Format(format, fileName, ExtensionPrefix ?? "");
|
||||
System.IO.TextWriter tw = null;
|
||||
try
|
||||
{
|
||||
Encoding encoder = new UTF8Encoding(true);
|
||||
try
|
||||
{
|
||||
if (DefaultEncoding != Encoding.UTF8.CodePage)
|
||||
{
|
||||
encoder = Common.Utils.FileUtils.GetEncoding(DefaultEncoding);
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
APILogger.Log("Problem getting encoding", ex);
|
||||
encoder = Encoding.Default;
|
||||
}
|
||||
|
||||
tw = new System.IO.StreamWriter(fileName, false, encoder);
|
||||
|
||||
var th = new TestHeader();
|
||||
var ch = new ChannelHeader();
|
||||
var cd = new ChannelData();
|
||||
|
||||
var bFilterThisExport = bFiltered && allowTTSFilteredExport;
|
||||
|
||||
cd.GenerateChannelData(this, tw, bFilterThisExport, start, stop, SubSampleInterval, out ulong practicalNumSamples, out ulong numSamples, out Test test, out DataScaler[] scalers, out double sampleRate,
|
||||
out List<short[]> ChannelDataUnFiltered, out List<double[]> ChannelDataFiltered, out int preTriggerSamples);
|
||||
th.WriteTestHeader(this, tw, bFilterThisExport, SubSampleInterval, Math.Min(numSamples, practicalNumSamples), preTriggerSamples);
|
||||
ch.WriteChannelHeaderToString(this, tw, bFilterThisExport, start, stop);
|
||||
cd.WriteChannelData(this, tw, bFilterThisExport, start, stop, SubSampleInterval, practicalNumSamples, numSamples, test, scalers, sampleRate, ChannelDataUnFiltered,
|
||||
ChannelDataFiltered);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
APILogger.Log("Exception in DoExport, ", ex);
|
||||
throw ex;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (null != tw)
|
||||
{
|
||||
try
|
||||
{
|
||||
tw.Flush();
|
||||
tw.Close();
|
||||
tw.Dispose();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
APILogger.Log("Exception in DoExport cleanup, ", ex);
|
||||
}
|
||||
tw = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user