This commit is contained in:
2026-04-17 14:55:32 -04:00
commit bc3ac1d4c9
18017 changed files with 4371742 additions and 0 deletions

View File

@@ -0,0 +1 @@
12

View File

@@ -0,0 +1 @@
12

View File

@@ -0,0 +1,522 @@
/*
* DTS.Slice.Control.Event.Module.Channel.SaeJ211Filter.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using DTS.Common.DAS.Concepts.DAS.Channel;
using DTS.Common.Utilities;
using DTS.Common.Utilities.DotNetProgrammingConstructs;
using DTS.Common.Utilities.Logging;
using DTS.Common.Utilities.SaeJ211;
namespace DTS.Common.SerializationPlus
{
/// <summary>
/// Base class for all SaeJ211-based event module channel filters. It is intended
/// that fixed-filter-setting filters be derived from this class that will set their
/// filter setting using the protected constructor.
/// </summary>
public class SaeJ211Filter
: Filter
{
public SaeJ211Filter(SaeJ211Filter originalFilter)
{
OriginalType = originalFilter.OriginalType;
_cutoffFrequencyHz.Value = originalFilter.CutoffFrequencyHz;
}
/// <summary>
/// Initialize an instance of the DTS.Utility.SaeJ211Filter class.
/// </summary>
///
/// <param name="originalType">
/// The <see cref="ChannelFilter"/> to be applied by this filter (ad hoc
/// filters that correspond to CFC values will be converted to the CFC, hence the
/// "original" qualification).
/// </param>
///
public SaeJ211Filter(ChannelFilter originalType)
{
try
{
switch (OriginalType = originalType)
{
//
// Try to set the frequency value according to type. Note that we can't set to
// "ad hoc" using this particular constructor as we don't know what frequency
// should be associated with it.
//
case ChannelFilter.AdHoc:
throw new Exception("cannot initialize SaeJ211 filter using only ChannelFilter of type " +
OriginalType.ToString());
default:
_cutoffFrequencyHz.Value = (double)originalType;
break;
}
}
catch (System.Exception ex)
{
throw new Exception("encountered problem constructing " + GetType().FullName, ex);
}
}
/// <summary>
/// Initialize an instance of the DTS.Utility.SaeJ211Filter class.
/// </summary>
///
/// <param name="cutoffFrequencyHz"></param>
public SaeJ211Filter(double cutoffFrequencyHz)
{
try
{
OriginalType = ChannelFilter.AdHoc;
_cutoffFrequencyHz.Value = cutoffFrequencyHz;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem constructing " + GetType().FullName, ex);
}
}
/// <summary>
/// Get <see cref="Boolean"/> value indicating whether or not this filter matches one of the
/// specified CFC values.
/// </summary>
public override bool IsCfc
{
get
{
try
{
//
// If we're not unfiltered and we're not ad hoc, then we
// must be CFC-compliant.
//
return Type != ChannelFilter.Unfiltered && Type != ChannelFilter.UnfilteredZero
&& Type != ChannelFilter.AdHoc;
}
catch (System.Exception ex)
{
throw new Exception(
"encountered problem determining whether or not filter corresponds to a CFC value", ex);
}
}
}
/// <summary>
/// Convert the specified frequency into a ChannelFilter type.
/// </summary>
///
/// <param name="frequency">
/// The <see cref="double"/> frequency to be converted.
/// </param>
///
/// <returns>
/// The best matching <see cref="ChannelFilter"/> type. A CFC match is preferred;
/// if one does not exist, "ad hoc" will be selected (if frequency > 0).
/// </returns>
///
private static ChannelFilter ConvertFrequencyToChannelFilter(double frequency)
{
try
{
var matchingFilterType = ChannelFilter.Unfiltered;
if (!(frequency > 0)) return matchingFilterType;
matchingFilterType = ChannelFilter.AdHoc;
foreach (int filterValue in Enum.GetValues(typeof(ChannelFilter)))
{
if (frequency == filterValue)
{
matchingFilterType = (ChannelFilter)filterValue;
}
}
return matchingFilterType;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem trying to match frequency to CRC value", ex);
}
}
/// <summary>
/// Get the "best fitting" <see cref="ChannelFilter"/> value for this filter.
/// </summary>
public override ChannelFilter Type
{
get
{
try
{
ChannelFilter actualType;
switch (OriginalType)
{
case ChannelFilter.AdHoc:
actualType = ConvertFrequencyToChannelFilter(CutoffFrequencyHz);
break;
default:
//
// Don't waste time on stuff we don't need to convert.
//
actualType = OriginalType;
break;
}
return actualType;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem determining filter type", ex);
}
}
}
public override char IsoDescription => new IsoDescriptionAttributeCoder().DecodeAttributeValue(Type)[0];
/// <summary>
/// Get the <see cref="double"/> cutoff frequency value.
/// </summary>
public override double CutoffFrequencyHz => _cutoffFrequencyHz.Value;
private readonly Property<double> _cutoffFrequencyHz
= new Property<double>(
typeof(SaeJ211Filter).Namespace + ".SaeJ211Filter.CutoffFrequencyHz",
-1,
true
);
/// <summary>
/// The <see cref="ChannelFilter"/>ing done by this object.
/// </summary>
public ChannelFilter OriginalType
{
get => _originalType.Value;
private set => _originalType.Value = value;
}
private readonly Property<ChannelFilter> _originalType
= new Property<ChannelFilter>(
typeof(SaeJ211Filter).Namespace + ".SaeJ211Filter.OriginalType",
ChannelFilter.Unfiltered,
false
);
private const string CUTOFF_FREQUENCY_UNIT_STRING = "Hz";
/// <summary>
/// The <see cref="string"/> name of this filter.
/// </summary>
public override string Name
{
get
{
try
{
if (null != _name) return _name;
var cult = System.Globalization.CultureInfo.InvariantCulture;
_name = ChannelFilter.AdHoc == Type
? CutoffFrequencyHz.ToString(cult) + CUTOFF_FREQUENCY_UNIT_STRING
: new DescriptionAttributeCoder<ChannelFilter>().DecodeAttributeValue(Type);
return _name;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem generating name string for " + GetType().FullName, ex);
}
}
}
private string _name;
/// <summary>
/// Apply this filter to the specified channel.
/// </summary>
///
/// <param name="channel">
/// The <see cref="DTS.Slice.Control.Event.Module.Channel"/> to be filtered.
/// </param>
/// <param name="displayUnits"></param>
/// <param name="bUseLegacyTDCSoftwareFilterAdjustment"></param>
/// <returns>
/// The array of filtered <see cref="double"/> EU data.
/// </returns>
public override double[] Apply
(
DTS.Slice.Control.Event.Module.Channel channel,
Slice.Control.Event.Module.Channel.DataDisplayUnits displayUnits,
bool bUseLegacyTDCSoftwareFilterAdjustment
)
{
try
{
var filterUtility = new FilterUtility();
filterUtility.Cfc = Type;
filterUtility.AdHocFrequency = CutoffFrequencyHz;
filterUtility.SampleRate = channel.ParentModule.SampleRateHz;
double[] data;
short[] adc = null;
if (channel.UnfilteredData is Serialization.SliceRaw.File.PersistentChannel unfilteredData)
{
adc = unfilteredData.GetAllData();
}
switch (displayUnits)
{
case Slice.Control.Event.Module.Channel.DataDisplayUnits.Adc:
if (null != adc)
{
using (var persistentUnfilteredData =
channel.UnfilteredData as Serialization.SliceRaw.File.PersistentChannel) // ;
{
data = new double[adc.Length];
for (var i = 0; i < data.Length; i++)
data[i] = adc[i];
}
}
else if (channel.UnfilteredData is Serialization.TDAS.File.PersistentChannel persistentChannel)
{
if (persistentChannel is ILargeDataAware largeDataAware)
if (!largeDataAware.IsDataArraySized)
throw new Serialization.TDAS.File.PersistentChannel.DataTooBigForArrayException(
"Data is too big to be viewed or filtered.");
using (var persistentUnfilteredData =
channel.UnfilteredData as Serialization.TDAS.File.PersistentChannel) // ;
{
var dataCount = persistentUnfilteredData.Count;
data = new double[dataCount];
for (var i = 0; i < dataCount; i++)
data[i] = persistentUnfilteredData[(ulong)i];
}
}
else data = channel.UnfilteredData.ConvertAll(datum => (double)datum).ToArray();
break;
case Slice.Control.Event.Module.Channel.DataDisplayUnits.Eu:
data = channel.UnfilteredDataEu.ToArray();
break;
case Slice.Control.Event.Module.Channel.DataDisplayUnits.Mv:
data = channel.UnfilteredDataMv.ToArray();
break;
default:
throw new NotImplementedException("handling for display unit type \"" + displayUnits +
"\" has not been implemented");
}
return filterUtility.ApplyFilter(data, delegate
{
var msg = $"Invalid data in channel: {channel.ChannelDescriptionString}.";
APILogger.Log(msg);
throw new Exception(msg);
}, bUseLegacyTDCSoftwareFilterAdjustment);
}
catch (System.Exception ex)
{
throw new Exception("encountered problem applying filter \"" + Name + "\" to channel", ex);
}
}
/// <summary>
/// Apply this filter to the specified channel.
/// </summary>
///
/// <param name="channel">
/// The <see cref="DTS.Slice.Control.Event.Module.Channel"/> to be filtered.
/// </param>
/// <param name="data"></param>
/// <param name="sampleRate"></param>
/// <param name="bUseLegacyTDCSoftwareFilterAdjustment">
/// controls whether filtered data is adjusted by one sample to match TDC behavior
/// 8747
/// </param>
/// <returns>
/// The array of filtered <see cref="double"/> EU data.
/// </returns>
public override double[] Apply
(
double[] data,
double sampleRate,
bool bUseLegacyTDCSoftwareFilterAdjustment
)
{
try
{
var filterUtility = new FilterUtility();
filterUtility.Cfc = Type;
filterUtility.AdHocFrequency = CutoffFrequencyHz;
filterUtility.SampleRate = sampleRate;
return filterUtility.ApplyFilter(data, delegate
{
const string msg = "Invalid data in channel.";
APILogger.Log(msg);
throw new Exception(msg);
}, bUseLegacyTDCSoftwareFilterAdjustment);
}
catch (System.Exception ex)
{
throw new Exception("encountered problem applying filter \"" + Name + "\" to channel", ex);
}
}
/// <summary>
/// Generate a string representation of this object.
/// </summary>
///
/// <returns>
/// A <see cref="string"/> representation of this object.
/// </returns>
///
public override string ToString()
{
try
{
return Name;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem generating the string value for " + GetType().FullName, ex);
}
}
/// <summary>
/// Generate a string representation of this object.
/// </summary>
///
/// <returns>
/// A <see cref="string"/> representation of this object.
/// </returns>
///
public override string ToBaseString()
{
try
{
return Name;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem generating the string value for " + GetType().FullName, ex);
}
}
/// <summary>
/// Determines whether this filter and the specified filter are the same.
/// </summary>
///
/// <param name="obj">
/// The filter <see cref="object"/> to be compared with this one.
/// </param>
///
/// <returns>
/// <see cref="bool"/> true if the filters are the same, false otherwise.
/// </returns>
///
public override bool Equals(object obj)
{
try
{
if (!(obj is SaeJ211Filter))
{
return false;
}
return Name.Equals(((SaeJ211Filter)obj).Name, StringComparison.OrdinalIgnoreCase);
}
catch (System.Exception ex)
{
throw new Exception(
"encountered problem equality checking filter \""
+ Name
+ "\" with filter "
+ ((obj as SaeJ211Filter)?.Name != null ? "\"" + (obj as SaeJ211Filter).Name + "\"" : "<null>"),
ex);
}
}
/// <summary>
/// provides an index for a given <see cref="SaeJ211Filter"/>
/// since we override Equals we should override get hashcode to ensure that any to objects considered
/// "Equal" are also hashed to the same location, however the result index does not need to be unique
/// between non equal objects.
/// 6/10/2010 - dtm
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
return Name.ToLower().GetHashCode();
}
/// <summary>
/// Create a filter from the specified string.
/// </summary>
///
/// <param name="serialization">
/// The <see cref="string"/> representation of the filter to be instantiated.
/// </param>
///
/// <returns>
/// A <see cref="Filter"/> equivalent of the
/// specified string. Throws an exception if object could not be created.
/// </returns>
///
public static Filter Parse(string serialization)
{
try
{
Filter filter = null;
//FB 13120 remove Hz if it presents inorder to convert it to frequency
if (!serialization.Contains(CUTOFF_FREQUENCY_UNIT_STRING))
{
double freq = 0;
if (double.TryParse(serialization, out freq))
{
serialization = serialization + CUTOFF_FREQUENCY_UNIT_STRING;
}
}
if (string.IsNullOrEmpty(serialization))
return new SaeJ211Filter(ChannelFilter.Unfiltered);
if (serialization.Contains(CUTOFF_FREQUENCY_UNIT_STRING))
{
var cult = new System.Globalization.CultureInfo("");
filter = new DefaultSaeJ211Filter(
double.Parse(serialization.Replace(CUTOFF_FREQUENCY_UNIT_STRING, ""), cult));
}
else
{
foreach (ChannelFilter filterType in Enum.GetValues(typeof(ChannelFilter)))
{
var coder = new DescriptionAttributeCoder<ChannelFilter>();
if (coder.DecodeAttributeValue(filterType)
.Equals(serialization, StringComparison.OrdinalIgnoreCase))
filter = new DefaultSaeJ211Filter(filterType);
}
}
return filter ?? new SaeJ211Filter(ChannelFilter.Unfiltered);
}
catch (System.Exception ex)
{
throw new Exception(
"encountered problem parsing string " +
(null != serialization ? "\"" + serialization + "\"" : "<NULL>") + " into filter", ex);
}
}
}
}

View File

@@ -0,0 +1,28 @@
/*
* DTS.Slice.Control.Event.DasModuleChannelAccessor.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using DTS.Common.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
/// <summary>
/// An object returned during Event creation that allows access to the event's channel information
/// by DAS ID/DAS module number/module channel number triplet.
/// </summary>
public class DasModuleChannelAccessor : ExceptionalDictionary<Common.DAS.Concepts.DAS.Id, ModuleChannelAccessor>
{
/// <summary>
/// Initialize an instance of the DTS.Slice.Control.Event.DasModuleChannelAccessor class.
/// </summary>
public DasModuleChannelAccessor() { }
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DTS.Common.SerializationPlus")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DTS.Common.SerializationPlus")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("b9d1ac5b-7a6f-4b14-9ff8-3a1fc03519e2")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,82 @@
/*
* DTS.Slice.Control.Event.TestInformation.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using DTS.Common.DASResource;
using DTS.Common.Utilities;
using DTS.Common.Utilities.DotNetProgrammingConstructs;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.DAS.Event.cs ***
public partial class Event
{
/// <summary>
/// Internal representation of DAS event test information.
/// </summary>
private sealed class TestInformation : Exceptional
{
/// <summary>
/// Get/set the <see cref="string"/> ID of the test associated with this DAS event.
/// </summary>
public string Id
{
get => _Id.Value;
set => _Id.Value = value;
}
private readonly Property<string> _Id = new Property<string>("DTS.Slice.Control.Event.TestInformation.Id", null, false);
/// <summary>
/// Get/set the <see cref="string"/> description of the test associated with this DAS event.
/// </summary>
public string Description
{
get => _Description.Value;
set => _Description.Value = value;
}
private readonly Property<string> _Description = new Property<string>("DTS.Slice.Control.Event.TestInformation.Description", null, false);
/// <summary>
/// Initialize an instance of the DTS.Slice.Control.Event.TestInformation class.
/// </summary>
public TestInformation()
{ //
// NOTE that the invocation of this constructor will leave this class'
// properties uninitialized.
} //
/// <summary>
/// Initialize an instance of the DTS.Slice.Control.Event.TestInformation class.
/// </summary>
///
/// <param name="id">
/// The <see cref="string"/> ID of the test associated with this DAS event.
/// </param>
///
/// <param name="description">
/// The <see cref="string"/> description of the test associated with this DAS event.
/// </param>
///
public TestInformation(string id, string description)
{
try
{
Id = id;
Description = description;
}
catch (System.Exception ex)
{
throw new Exception(
string.Format(
Strings.DTS_Slice_Control_Event_ConstructionFailedString, GetType().FullName),
ex);
}
}
}
}
}

View File

@@ -0,0 +1,27 @@
/*
* DTS.Slice.Control.Event.ChannelAccessor.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using DTS.Common.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
/// <summary>
/// A component object of the Event.DasModuleChannelAccessor.
/// </summary>
public class ChannelAccessor : ExceptionalDictionary<int, Module.Channel> // xxx change this int to DAS.(Module?).Channel.Id?
{
/// <summary>
/// Initialize an instance of the DTS.Slice.Control.Event.ChannelAccessor class.
/// </summary>
public ChannelAccessor() { }
}
}
}

View File

@@ -0,0 +1,81 @@
/*
* DTS.Slice.Control.Event.Module.Channel.ReviewableAttribute.NotApplicableException.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.Channel.cs ***
public partial class Channel
{
// *** see DTS.Slice.Control.Event.Module.Channel.ReviewableAttribute.cs ***
public partial class ReviewableAttribute
{
/// <summary>
/// Representation of an attempt to use a channel attribute that is not
/// applicable to the associated channel.
/// </summary>
public class NotApplicableException : ApplicationException
{ ///
/// <summary>
/// Initialize an instance of the NotApplicableException class.
/// </summary>
///
public NotApplicableException()
{
}
/// <summary>
/// Initialize an instance of the NotApplicableException class.
/// </summary>
///
/// <param name="msg">
/// The <see cref="string"/> message to be associated with this exception.
/// </param>
///
public NotApplicableException(string msg)
: base(msg)
{
}
/// <summary>
/// Initialize an instance of the NotApplicableException class.
/// </summary>
///
/// <param name="msg">
/// The <see cref="string"/> message to be associated with this exception.
/// </param>
///
/// <param name="innerEx">
/// The <see cref="System.Exception"/> responsible for this exception inception.
/// </param>
///
public NotApplicableException(string msg, System.Exception innerEx)
: base(msg, innerEx)
{
}
}
} // *** end ReviewableAttribute ***
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<ClassDiagram MajorVersion="1" MinorVersion="1">
<Class Name="DTS.Slice.Control.Event" Collapsed="true" BaseTypeListCollapsed="true">
<Position X="3" Y="0.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAiBEBA0AIoiAQsoAgAgAAQLBEEBIDUCCAAQBAEQhA=</HashCode>
<FileName>Control\Event\ChannelAccessor.cs</FileName>
</TypeIdentifier>
<Lollipop Position="0.2" Collapsed="true" />
</Class>
<Class Name="DTS.Slice.Control.IntervalSec" Collapsed="true">
<Position X="4.75" Y="1.5" Width="1.5" />
<TypeIdentifier>
<HashCode>CAIAAAAAAAAAAAAAgBAAAAAAAAAAEIBAAAAAAAAQAAA=</HashCode>
<FileName>Control\IntervalSec.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="DTS.Common.SerializationPlus.EventInfoAggregate" Collapsed="true">
<Position X="4.75" Y="0.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAJAAEQgAAAAAgAIAEAAAAgAAAAgQAAAQABAAIAACgg=</HashCode>
<FileName>EventInfoAggregate.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="DTS.Common.SerializationPlus.DefaultSaeJ211Filter" Collapsed="true">
<Position X="0.5" Y="3.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAAAEAAAAAIQAAAAAAAAAAAAAAAAAAAA=</HashCode>
<FileName>Filter\ChannelDefaultSaeJ211Filter.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="DTS.Common.SerializationPlus.Filter" Collapsed="true">
<Position X="0.5" Y="0.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAABAAIAAAAAAAAIUAAAAAAAAAAQAAACAAAAA=</HashCode>
<FileName>Filter\Filter.cs</FileName>
</TypeIdentifier>
<Lollipop Position="0.2" />
</Class>
<Class Name="DTS.Common.SerializationPlus.SaeJ211Filter" Collapsed="true">
<Position X="0.5" Y="2" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAgIAAAgBAAIAAEgAABgIUAAAAAAIAAAQAABCAAIAA=</HashCode>
<FileName>Filter\SaeJ211Filter.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="DTS.Serialization.XLSX.File" Collapsed="true" BaseTypeListCollapsed="true">
<Position X="3" Y="1.5" Width="1.5" />
<TypeIdentifier>
<HashCode>IAAAAAAAAAAAAAEIAAAAAAAQAAAAAAAAAAAAAAIAAAA=</HashCode>
<FileName>XLSX\Excel.File.cs</FileName>
</TypeIdentifier>
<Lollipop Position="0.2" Collapsed="true" />
</Class>
<Interface Name="DTS.Common.SerializationPlus.IFilter" Collapsed="true">
<Position X="3" Y="2.75" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAABAAIAAAAAAAAIUAAAAAAAAAAQAAACAAAAA=</HashCode>
<FileName>Filter\IFilter.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="DTS.Common.SerializationPlus.IFilterable" Collapsed="true">
<Position X="4.75" Y="2.75" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAQAAAAAAACAgAAAAAAAAQAAAAAAAAAAAAA=</HashCode>
<FileName>Filter\IFilterable.cs</FileName>
</TypeIdentifier>
</Interface>
<Font Name="Segoe UI" Size="9" />
</ClassDiagram>

View File

@@ -0,0 +1,69 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableShuntDeflectionPercentageAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel
{
/// <summary>
/// A reviewable shunt deflection attribute attached to a specific channel.
/// </summary>
public class ReviewableShuntDeflectionPercentageAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableShuntDeflectionPercentageAttribute(Event.Module.Channel channel)
: base("Shunt Error (%)", delegate { return (100.0 * ((channel as DTS.DAS.Concepts.DAS.Channel.IShuntAware).MeasuredShuntDeflectionMv - (channel as DTS.DAS.Concepts.DAS.Channel.IShuntAware).TargetShuntDeflectionMv) / (channel as DTS.DAS.Concepts.DAS.Channel.IShuntAware).TargetShuntDeflectionMv).ToString("F1"); })
{
}
}
/// <summary>
/// A reviewable shunt deflection attribute attached to a specific channel.
/// </summary>
public class ReviewableCalSignalPercentageAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableCalSignalPercentageAttribute(Event.Module.Channel channel)
: base("Calibration Signal Error (%)", delegate { return (100.0 * ((channel as DTS.DAS.Concepts.DAS.Channel.ICalSignalAware).MeasuredCalSignalMv - (channel as DTS.DAS.Concepts.DAS.Channel.ICalSignalAware).TargetCalSignalMv) / (channel as DTS.DAS.Concepts.DAS.Channel.ICalSignalAware).TargetCalSignalMv).ToString("F1"); })
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,50 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableIsoCodeAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel
{
/// <summary>
/// A reviewable serial number attribute attached to a specific channel.
/// </summary>
public class ReviewableIsoCodeAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableIsoCodeAttribute(Event.Module.Channel channel)
: base("ISO Code", delegate { return (channel as AnalogInputChannel).IsoCode.ToString(); })
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,50 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableSerialNumberAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel
{
/// <summary>
/// A reviewable serial number attribute attached to a specific channel.
/// </summary>
public class ReviewableSerialNumberAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableSerialNumberAttribute(Event.Module.Channel channel)
: base("Serial Number", delegate { return (channel as AnalogInputChannel).SerialNumber.ToString(); })
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,52 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableCfcAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DTS.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel
{
/// <summary>
/// A reviewable CFC attribute attached to a specific channel.
/// </summary>
public class ReviewableDescriptionAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableDescriptionAttribute(Event.Module.Channel channel)
: base("Description", delegate { return channel.ChannelDescriptionString; })
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,953 @@
/*
* XLSX.File.Writer.cs
*
* Copyright © 2017
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DTS.Common.Enums;
using DTS.Common.Enums.Sensors;
using DTS.Common.Interface.ExportData;
using DTS.Common.SerializationPlus;
using DTS.Common.Utilities.Logging;
using DTS.Slice.Control;
// ReSharper disable PossiblyMistakenUseOfParamsMethod
namespace DTS.Serialization.XLSX
{
public partial class File
{
/// <summary>
/// implementation of the Serialization.File.Writer class for XLSX
/// http://fogbugz/fogbugz/default.asp?9920
/// </summary>
public class Writer : Writer<File>, IWriter<Test>
{
#region properties
/// <summary>
/// the owning file that controls this writer
/// </summary>
internal File WriterParent { get; }
/// <summary>
/// controls whether to export ADC or not
/// </summary>
public bool ExportADC { get; set; }
/// <summary>
/// controls whether to export EU or not
/// </summary>
public bool ExportEU { get; set; }
/// <summary>
/// controls whether to export MV or not
/// </summary>
public bool ExportMv { get; set; }
/// <summary>
/// the starting
/// </summary>
public double Start { get; set; }
public double Stop { get; set; }
public bool Filtered { get; set; }
/// <summary>
/// FB 6410 The list of user selected headers to export
/// </summary>
public List<IExportHeader> ExportHeaders { get; set; }
#endregion
#region enums and constants
/// <summary>
/// every 1000 samples update progress
/// </summary>
private const int UPDATE_INTERVAL = 1000;
#endregion
#region methods
/// <summary>
/// writes out test to given path
/// </summary>
/// <param name="pathname"></param>
/// <param name="id"></param>
/// <param name="test"></param>
/// <param name="bFiltering"></param>
/// <param name="includeGroupNameInISOExport"></param>
/// <param name="dataCollectionLength"></param>
/// <param name="minStartTime"></param>
public void Write(string pathname, string id, Test test, bool bFiltering, bool includeGroupNameInISOExport, double minStartTime, int dataCollectionLength)
{
}
/// <summary>
/// returns a datascaler for the given channel
/// </summary>
/// <param name="currentAnalogChannel"></param>
/// <returns></returns>
public static Common.DAS.Concepts.DataScaler GetDataScaler(Test.Module.AnalogInputChannel currentAnalogChannel)
{
var scaler = new Common.DAS.Concepts.DataScaler
{
IsInverted = currentAnalogChannel.IsInverted,
IEPE = currentAnalogChannel.Bridge == SensorConstants.BridgeType.IEPE,
UnitConversion = currentAnalogChannel.UnitConversion,
BasedOnOutputAtCapacity = currentAnalogChannel.AtCapacity,
CapacityOutputIsBasedOn = currentAnalogChannel.CapacityOutputIsBasedOn,
SensitivityUnits = currentAnalogChannel.SensitivityUnits,
Multiplier = currentAnalogChannel.Multiplier,
UserOffsetEU = currentAnalogChannel.UserOffsetEU
};
scaler.SetLinearizationFormula(currentAnalogChannel.LinearizationFormula);
scaler.SetScaleFactorMv(currentAnalogChannel.Data.ScaleFactorMv);
scaler.SetScaleFactorEU(currentAnalogChannel.Data.ScaleFactorEU);
scaler.SetUseEUScaleFactors(currentAnalogChannel.Data.UseEUScaleFactors);
scaler.SetMvPerEu(currentAnalogChannel.Data.MvPerEu);
try
{
scaler.SetInitialOffset(currentAnalogChannel.InitialOffset);
scaler.ZeroMethodType = currentAnalogChannel.ZeroMethod;
scaler.SetRemovedADC(currentAnalogChannel.RemovedADC);
scaler.SetRemovedInternalADC(currentAnalogChannel.RemovedInternalADC);
scaler.SetDataZeroLevelADC(currentAnalogChannel.DataZeroLevelAdc);
scaler.SetZeroMvInADC(currentAnalogChannel.ZeroMvInADC);
try
{
//note the window average is the average over time when the average is not in your dataset
//sliceware is the only software that sets this currently
scaler.SetWindowAverageADC(currentAnalogChannel.WindowAverageADC);
}
catch (System.Exception ex)
{
APILogger.Log("WindowAverageADC failed to set", ex);
}
}
catch (System.Exception ex)
{
APILogger.Log("Failed to set parameters on scaler", ex);
}
scaler.NominalExcitationVoltage = currentAnalogChannel.ExcitationVoltage;
if (currentAnalogChannel.MeasuredExcitationVoltageValid)
{
try
{
scaler.MeasuredExcitationVoltage = currentAnalogChannel.MeasuredExcitationVoltage;
}
catch (System.Exception ex)
{
APILogger.Log("failed to get measured excitation voltage", ex);
}
}
if (currentAnalogChannel.FactoryExcitationVoltageValid)
{
try
{
scaler.FactoryExcitationVoltage = currentAnalogChannel.FactoryExcitationVoltage;
}
catch (System.Exception ex)
{
APILogger.Log("failed to get factory excitation", ex);
}
}
//14469 Excel export EU values incorrect for digital input channel
//digital properties were not being set
scaler.Digital = currentAnalogChannel.IsDigital();
scaler.DigitalMode = currentAnalogChannel.DigitalMode;
scaler.SetDigitalMultiplier(currentAnalogChannel.DigitalMultiplier);
scaler.ProportionalToExcitation = currentAnalogChannel.ProportionalToExcitation;
return scaler;
}
/// <summary>
/// updates the progress if possible
/// </summary>
/// <param name="dValue"></param>
/// <param name="tickEventHandler"></param>
private void UpdateProgress(double dValue, TickEventHandler tickEventHandler)
{
tickEventHandler?.Invoke(this, dValue);
}
private static readonly Dictionary<uint, Row> _rowIndexToRow = new Dictionary<uint, Row>();
/// <summary>
/// gets a cell given a work sheet and a strong cell reference
/// cell reference should be in the form SheetId!$Column$Row,
/// like DefinedNames use
/// </summary>
/// <param name="worksheet"></param>
/// <param name="xColumn"></param>
/// <param name="rowIndex"></param>
/// <param name="bLookForCell"></param>
/// <returns></returns>
protected Cell GetCell(Worksheet worksheet, string xColumn, uint rowIndex, bool bLookForCell = true)
{
var nameref = string.Format("{0}{1}", xColumn, rowIndex);
// ReSharper disable once ReplaceWithSingleCallToFirstOrDefault
Row theRow;
if (_rowIndexToRow.ContainsKey(rowIndex))
{
theRow = _rowIndexToRow[rowIndex];
}
else
{
return InsertCellInWorksheet(xColumn, rowIndex, worksheet.WorksheetPart, nameref, false);
}
if (!bLookForCell)
{
InsertCellInWorksheet(xColumn, rowIndex, worksheet.WorksheetPart, nameref, false);
}
// ReSharper disable once ReplaceWithSingleCallToFirstOrDefault
var theCell = theRow.Descendants<Cell>().Where(c => c.CellReference == nameref).FirstOrDefault();
return theCell ?? InsertCellInWorksheet(xColumn, rowIndex, worksheet.WorksheetPart, nameref, false);
}
// Given a column name, a row index, and a WorksheetPart, inserts a cell into the worksheet.
// If the cell already exists, returns it.
private static Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPart worksheetPart, string cellReference, bool bLookForCell)
{
var worksheet = worksheetPart.Worksheet;
var sheetData = worksheet.GetFirstChild<SheetData>();
// If the worksheet does not contain a row with the specified row index, insert one.
Row row;
if (_rowIndexToRow.ContainsKey(rowIndex))
{
row = _rowIndexToRow[rowIndex];
}
else
{
row = new Row { RowIndex = rowIndex };
_rowIndexToRow[rowIndex] = row;
sheetData.Append(row);
}
// If there is not a cell with the specified column name, insert one.
if (bLookForCell)
{
var matches = row.Elements<Cell>().Where(c => c.CellReference.Value == columnName + rowIndex);
//resharper suggests these should be made into an array first
var matchesAsArray = matches as Cell[] ?? matches.ToArray();
if (matchesAsArray.Any())
{
return matchesAsArray.First();
}
}
// Cells must be in sequential order according to CellReference. Determine where to insert the new cell.
var refCell = row.Elements<Cell>().Where(cell => cell.CellReference.Value.Length == cellReference.Length).FirstOrDefault(cell => string.Compare(cell.CellReference.Value, cellReference, StringComparison.OrdinalIgnoreCase) > 0);
var newCell = new Cell { CellReference = cellReference };
row.InsertBefore(newCell, refCell);
return newCell;
}
protected WorksheetPart GetWorksheetPartByName(SpreadsheetDocument document, string sheetName)
{
var sheets =
document.WorkbookPart.Workbook.GetFirstChild<Sheets>().
Elements<Sheet>().Where(s => s.Name == sheetName);
var enumerable = sheets as Sheet[] ?? sheets.ToArray();
if (!enumerable.Any())
{
// The specified worksheet does not exist.
return null;
}
var relationshipId = enumerable.First().Id.Value;
var worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(relationshipId);
return worksheetPart;
}
private Dictionary<string, int> _stringLookup;
protected int InsertSharedStringItem(string text, SharedStringTablePart shareStringPart)
{
if (null == text) { text = ""; }
// If the part does not contain a SharedStringTable, create one.
if (shareStringPart.SharedStringTable == null)
{
shareStringPart.SharedStringTable = new SharedStringTable();
}
int i;
if (null == _stringLookup)
{
i = 0;
_stringLookup = new Dictionary<string, int>();
foreach (var item in shareStringPart.SharedStringTable.Elements<SharedStringItem>())
{
_stringLookup[item.InnerText] = i++;
}
}
//if the string is already in the table, return it's index, otherwise add a new string to the table and return the new index
if (_stringLookup.ContainsKey(text)) { return _stringLookup[text]; }
i = _stringLookup.Count;
shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new Text(text)));
shareStringPart.SharedStringTable.Save();
_stringLookup[text] = i;
return i;
}
private void WriteTime(WorksheetPart ws,
string column,
uint row,
DateTime time, SharedStringTablePart sharedString)
{
var cell = GetCell(ws.Worksheet, column, row);
cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
cell.CellValue = new CellValue(InsertSharedStringItem(time.ToShortTimeString(), sharedString).ToString());
cell.StyleIndex = _dateFormatIndex;
}
/// <summary>
/// FB 6410 The override for WriteTime to use the correct row for the requested headerName
/// </summary>
/// <param name="ws"></param>
/// <param name="column"></param>
/// <param name="headerName"></param>
/// <param name="time"></param>
/// <param name="sharedString"></param>
private void WriteTime(WorksheetPart ws,
string column,
string headerName,
DateTime time, SharedStringTablePart sharedString)
{
if (!_headerRowLineIndex.ContainsKey(headerName))
{
return;
}
WriteTime(ws, column, _headerRowLineIndex[headerName], time, sharedString);
}
private void WriteDate(WorksheetPart ws,
string column,
uint row,
DateTime date)
{
var cell = GetCell(ws.Worksheet, column, row);
cell.DataType = new EnumValue<CellValues>(CellValues.Number);
cell.CellValue =
new CellValue(date.ToOADate().ToString(CultureInfo.InvariantCulture));
cell.StyleIndex = _dateFormatIndex;
}
/// <summary>
/// FB 6410 The override for WriteDate to use the correct row for the requested headerName
/// </summary>
/// <param name="ws"></param>
/// <param name="column"></param>
/// <param name="headerName"></param>
/// <param name="date"></param>
private void WriteDate(WorksheetPart ws,
string column,
string headerName,
DateTime date)
{
if (!_headerRowLineIndex.ContainsKey(headerName))
{
return;
}
WriteDate(ws, column, _headerRowLineIndex[headerName], date);
}
private void WriteDouble(WorksheetPart ws,
string column,
uint row,
double value)
{
var cell = GetCell(ws.Worksheet, column, row, false);
cell.CellValue = new CellValue(value.ToString(CultureInfo.InvariantCulture));
}
/// <summary>
/// FB 6410 The override for WriteDouble to use the correct row for the requested headerName
/// </summary>
/// <param name="ws"></param>
/// <param name="column"></param>
/// <param name="headerName"></param>
/// <param name="value"></param>
private void WriteDouble(WorksheetPart ws,
string column,
string headerName,
double value)
{
if (!_headerRowLineIndex.ContainsKey(headerName))
{
return;
}
WriteDouble(ws, column, _headerRowLineIndex[headerName], value);
}
private void WriteString(WorksheetPart ws,
string column,
uint row,
SharedStringTablePart sharedStringTablePart,
string value)
{
var cell = GetCell(ws.Worksheet, column, row, false);
cell.CellValue = new CellValue(InsertSharedStringItem(value, sharedStringTablePart).ToString());
cell.DataType = new EnumValue<CellValues> { Value = CellValues.SharedString };
}
/// <summary>
/// FB 6410 The override for WriteString to use the correct row for the requested headerName
/// </summary>
/// <param name="ws"></param>
/// <param name="column"></param>
/// <param name="headerName"></param>
/// <param name="sharedStringTablePart"></param>
/// <param name="value"></param>
private void WriteString(WorksheetPart ws,
string column,
string headerName,
SharedStringTablePart sharedStringTablePart,
string value)
{
//If we can't find the headerName that header is not selected by user and it's not in this dictionary skip this header
if (!_headerRowLineIndex.ContainsKey(headerName))
{
return;
}
// Do not eneter the header name twice if it's already entered
if (_alreadyEnteredHeader.Contains(value))
{
return;
}
WriteString(ws, column, _headerRowLineIndex[headerName], sharedStringTablePart, value);
_alreadyEnteredHeader.Add(headerName);
}
private List<string> _alreadyEnteredHeader = new List<string>();
private static string GetColumn(int index)
{
var dividend = index + 2;//we are starting at b...
var columnName = string.Empty;
while (dividend > 0)
{
var modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo) + columnName;
dividend = (dividend - modulo) / 26;
}
return columnName;
}
private uint _dateFormatIndex;
private void AddStyleSheet(SpreadsheetDocument sp)
{
var stylesheet = sp.WorkbookPart.WorkbookStylesPart.Stylesheet;
stylesheet.CellFormats.AppendChild(new CellFormat
{
NumberFormatId = 14,
ApplyNumberFormat = true
});
_dateFormatIndex = stylesheet.CellFormats.Count;
stylesheet.Save();
}
/// <summary>
/// Insert an empty row after the last entered row
/// </summary>
/// <param name="worksheetPart"></param>
private void InsertRow(WorksheetPart worksheetPart)
{
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
Row lastRow = sheetData.Elements<Row>().LastOrDefault();
if (lastRow != null)
{
sheetData.InsertAfter(new Row() { RowIndex = (lastRow.RowIndex + 1) }, lastRow);
}
}
private Dictionary<string, uint> _headerRowLineIndex = new Dictionary<string, uint>();
/// <summary>
/// This dictionary holds the datascaler for the AICs for the test. This was done for performance reasons. There
/// are several for/foreach loops that are in the write function that all need the scaler, but dont all need to
/// get it everytime.
/// </summary>
private Dictionary<int, Common.DAS.Concepts.DataScaler> _aicToScaler;
/// <summary>
/// writes out test to given path
/// </summary>
/// <param name="pathname"></param>
/// <param name="id"></param>
/// <param name="dataFolder"></param>
/// <param name="test"></param>
/// <param name="bFiltering"></param>
/// <param name="includeGroupNameInISOExport"></param>
/// <param name="fd"></param>
/// <param name="tmChannel"></param>
/// <param name="channelNumber"></param>
/// <param name="beginEventHandler"></param>
/// <param name="cancelEventHandler"></param>
/// <param name="endEventHandler"></param>
/// <param name="tickEventHandler"></param>
/// <param name="errorEventHandler"></param>
/// <param name="cancelRequested"></param>
/// <param name="minStartTime"></param>
/// <param name="dataCollectionLength"></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)
{
try
{
_rowIndexToRow.Clear();
_headerRowLineIndex.Clear();
_aicToScaler = new Dictionary<int, Common.DAS.Concepts.DataScaler>();
_stringLookup = null;
beginEventHandler?.Invoke(this, 100);
//pathname has the full path of our destination file
var sourceFile = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ReportTemplates",
"XLSXExportTemplate.xlsx");
var expectedWrites = double.NaN;
if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(pathname)))
{
System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(pathname));
}
System.IO.File.Copy(sourceFile, pathname, true);
//FB 6410 Build the dictionary to keep the name of the headers need to be exported along with the actual row number in the excel file
uint headerRowIndex = 1;
_headerRowLineIndex.Add(XLSXExportHeaderLine.Headers.GetDescription(), headerRowIndex);
foreach (var header in ExportHeaders)
{
if (header.IsSelected)
{
headerRowIndex++;
_headerRowLineIndex.Add(header.HeaderName, headerRowIndex);
}
}
headerRowIndex++;
_headerRowLineIndex.Add(XLSXExportHeaderLine.DataStart.GetDescription(), headerRowIndex);
headerRowIndex++;
_headerRowLineIndex.Add(XLSXExportHeaderLine.Labels.GetDescription(), headerRowIndex);
var maxSampleRate = test.Channels.Select(ch => ch.ParentModule.SampleRateHz).Max();
//14659 Excel (xlsx) export all (filtered) fails, but says export finished in green
//we need to use channel order rather than display order as display order in some data sets
//so that we can index the channels
var channels = new List<Test.Module.Channel>();
channels.AddRange(test.Channels);
channels.Sort((a, b) =>
{
var res = a.AbsoluteDisplayOrder.CompareTo(b.AbsoluteDisplayOrder);
if (res != 0) { return res; }
return a.Number.CompareTo(b.Number);
});
using (var sp = SpreadsheetDocument.Open(pathname, true))
{
AddStyleSheet(sp);
var shareStringPart = sp.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First();
sp.WorkbookPart.Workbook.CalculationProperties.ForceFullCalculation = true;
sp.WorkbookPart.Workbook.CalculationProperties.FullCalculationOnLoad = true;
var dataWs = GetWorksheetPartByName(sp, "Data");
var rows = dataWs.Worksheet.Descendants<Row>();
//FB 6410 insert rows for each selected header in the excel sheet which will be filled later on
for (int i = 0; i < _headerRowLineIndex.Count - 1; i++)
{
InsertRow(dataWs);
}
foreach (var row in rows)
{
_rowIndexToRow[row.RowIndex] = row;
}
WriteString(dataWs, "A", XLSXExportHeaderLine.TestDate.GetDescription(), shareStringPart, XLSXExportHeaderLine.TestDate.GetDescription());
WriteDate(dataWs, "B", XLSXExportHeaderLine.TestDate.GetDescription(), test.InceptionDate);
WriteString(dataWs, "A", XLSXExportHeaderLine.TestTime.GetDescription(), shareStringPart, XLSXExportHeaderLine.TestTime.GetDescription());
WriteTime(dataWs, "B", XLSXExportHeaderLine.TestTime.GetDescription(), test.InceptionDate, shareStringPart);
WriteString(dataWs, "A", XLSXExportHeaderLine.TestId.GetDescription(), shareStringPart, XLSXExportHeaderLine.TestId.GetDescription());
WriteString(dataWs, "B", XLSXExportHeaderLine.TestId.GetDescription(), shareStringPart, id);
WriteString(dataWs, "A", XLSXExportHeaderLine.TestDescription.GetDescription(), shareStringPart, XLSXExportHeaderLine.TestDescription.GetDescription());
WriteString(dataWs, "B", XLSXExportHeaderLine.TestDescription.GetDescription(), shareStringPart, test.Description);
//go through all the channels, and include whatever data is requested
foreach (var channel in channels)
{
//for now ignore the channel if it's not an analoginputchannel, this probably includes everything except maybe the calculated channels ...
if (!(channel is Test.Module.AnalogInputChannel aic)) { continue; }
//this should divide evenly, so ceiling is necessary in theory
var rate = Convert.ToInt32(Math.Ceiling(maxSampleRate / aic.ParentModule.SampleRateHz));
var iChannel = channels.IndexOf(channel);
if (double.IsNaN(expectedWrites))
{
expectedWrites = (double)test.Channels.Count * dataCollectionLength;
}
var column = GetColumn(iChannel);
WriteString(dataWs, "A", XLSXExportHeaderLine.SampleRate.GetDescription(), shareStringPart, XLSXExportHeaderLine.SampleRate.GetDescription());
WriteDouble(dataWs, column, XLSXExportHeaderLine.SampleRate.GetDescription(), maxSampleRate);
WriteString(dataWs, "A", XLSXExportHeaderLine.HardwareAntiAliasFilter.GetDescription(), shareStringPart, XLSXExportHeaderLine.HardwareAntiAliasFilter.GetDescription());
WriteDouble(dataWs, column, XLSXExportHeaderLine.HardwareAntiAliasFilter.GetDescription(), aic.ParentModule.AaFilterRateHz);
WriteString(dataWs, "A", XLSXExportHeaderLine.DataChannelNumber.GetDescription(), shareStringPart, XLSXExportHeaderLine.DataChannelNumber.GetDescription());
WriteDouble(dataWs, column, XLSXExportHeaderLine.DataChannelNumber.GetDescription(), (double)1 + iChannel);
var isoCode = "";
if (null != WriterParent)
{
switch (WriterParent.ISOViewMode)
{
case Common.Enums.IsoViewMode.ISOOnly:
isoCode = aic.IsoCode;
break;
case Common.Enums.IsoViewMode.ISOAndUserCode:
isoCode = $"{aic.IsoCode}/{aic.UserCode}";
break;
case Common.Enums.IsoViewMode.UserCodeOnly:
isoCode = aic.UserCode;
break;
case Common.Enums.IsoViewMode.ChannelNameOnly:
isoCode = string.Empty;
break;
}
}
WriteString(dataWs, "A", XLSXExportHeaderLine.IsoCode.GetDescription(), shareStringPart, XLSXExportHeaderLine.IsoCode.GetDescription());
WriteString(dataWs, column, XLSXExportHeaderLine.IsoCode.GetDescription(), shareStringPart, isoCode);
WriteString(dataWs, "A", XLSXExportHeaderLine.ChannelDescription.GetDescription(), shareStringPart, XLSXExportHeaderLine.ChannelDescription.GetDescription());
WriteString(dataWs, column, XLSXExportHeaderLine.ChannelDescription.GetDescription(), shareStringPart, aic.ChannelName2);
WriteString(dataWs, "A", XLSXExportHeaderLine.ChannelLocation.GetDescription(), shareStringPart, XLSXExportHeaderLine.ChannelLocation.GetDescription());
WriteString(dataWs, "A", XLSXExportHeaderLine.SensorSerialNumber.GetDescription(), shareStringPart, XLSXExportHeaderLine.SensorSerialNumber.GetDescription());
WriteString(dataWs, column, XLSXExportHeaderLine.SensorSerialNumber.GetDescription(), shareStringPart, aic.SerialNumber);
var filter = SaeJ211Filter.Parse(aic.SoftwareFilter);
WriteString(dataWs, "A", XLSXExportHeaderLine.SoftwareFilter.GetDescription(), shareStringPart, XLSXExportHeaderLine.SoftwareFilter.GetDescription());
//FB 18024 Show NONE for unfiltered
if (Filtered)
{
WriteString(dataWs, column, XLSXExportHeaderLine.SoftwareFilter.GetDescription(), shareStringPart, filter.Name);
}
else
{
WriteString(dataWs, column, XLSXExportHeaderLine.SoftwareFilter.GetDescription(), shareStringPart, "NONE");
}
if (bFiltering)
{
WriteString(dataWs, "A", XLSXExportHeaderLine.SoftwareFilterDb.GetDescription(), shareStringPart, XLSXExportHeaderLine.SoftwareFilterDb.GetDescription());
//FB 18024 Show NONE for unfiltered
if (Filtered)
{
WriteDouble(dataWs, column, XLSXExportHeaderLine.SoftwareFilterDb.GetDescription(), bFiltering ? filter.CutoffFrequencyHz : 0D);
}
else
{
WriteString(dataWs, column, XLSXExportHeaderLine.SoftwareFilterDb.GetDescription(), shareStringPart, "NONE");
}
}
WriteString(dataWs, "A", XLSXExportHeaderLine.EngineeringUnits.GetDescription(), shareStringPart, XLSXExportHeaderLine.EngineeringUnits.GetDescription());
WriteString(dataWs, column, XLSXExportHeaderLine.EngineeringUnits.GetDescription(), shareStringPart, aic.EngineeringUnits);
var preTriggerSamples = aic.ParentModule.TriggerSampleNumbers[0] - (double)aic.ParentModule.StartRecordSampleNumber;
if (preTriggerSamples < 0) { preTriggerSamples = 0D; }
if (preTriggerSamples > aic.ParentModule.NumberOfSamples) { preTriggerSamples = aic.ParentModule.NumberOfSamples; }
if (preTriggerSamples > Start * aic.ParentModule.SampleRateHz) { preTriggerSamples = Math.Truncate(Start * aic.ParentModule.SampleRateHz); }
WriteString(dataWs, "A", XLSXExportHeaderLine.UserComment.GetDescription(), shareStringPart, XLSXExportHeaderLine.UserComment.GetDescription());
WriteString(dataWs, "A", XLSXExportHeaderLine.PreZero.GetDescription(), shareStringPart, XLSXExportHeaderLine.PreZero.GetDescription());
WriteDouble(dataWs, column, XLSXExportHeaderLine.PreZero.GetDescription(), rate * preTriggerSamples);
var postTriggerSamples = aic.ParentModule.NumberOfSamples - preTriggerSamples;
if (postTriggerSamples < 0) { postTriggerSamples = 0D; }
if (postTriggerSamples > Stop * aic.ParentModule.SampleRateHz) { postTriggerSamples = Math.Truncate(Stop * aic.ParentModule.SampleRateHz); }
WriteString(dataWs, "A", XLSXExportHeaderLine.PostZero.GetDescription(), shareStringPart, XLSXExportHeaderLine.PostZero.GetDescription());
WriteDouble(dataWs, column, XLSXExportHeaderLine.PostZero.GetDescription(), rate * postTriggerSamples);
WriteString(dataWs, "A", XLSXExportHeaderLine.DataZero.GetDescription(), shareStringPart, XLSXExportHeaderLine.DataZero.GetDescription());
WriteDouble(dataWs, column, XLSXExportHeaderLine.DataZero.GetDescription(), aic.DataZeroLevelAdc);
_aicToScaler[iChannel] = GetDataScaler(aic);
WriteString(dataWs, "A", XLSXExportHeaderLine.ScaleEu.GetDescription(), shareStringPart, XLSXExportHeaderLine.ScaleEu.GetDescription());
WriteDouble(dataWs, column, XLSXExportHeaderLine.ScaleEu.GetDescription(), _aicToScaler[iChannel].GetAdcToEuScalingFactor());
WriteString(dataWs, "A", XLSXExportHeaderLine.ScaleMv.GetDescription(), shareStringPart, XLSXExportHeaderLine.ScaleMv.GetDescription());
WriteDouble(dataWs, column, XLSXExportHeaderLine.ScaleMv.GetDescription(), _aicToScaler[iChannel].GetAdcToMvScalingFactor());
WriteString(dataWs, "A", XLSXExportHeaderLine.DataStart.GetDescription(), shareStringPart, XLSXExportHeaderLine.DataStart.GetDescription());
WriteString(dataWs, "A", XLSXExportHeaderLine.Labels.GetDescription(), shareStringPart, XLSXExportHeaderLine.Labels.GetDescription());
WriteString(dataWs, column, XLSXExportHeaderLine.Labels.GetDescription(), shareStringPart, $"Chan {1 + iChannel}: {aic.ChannelName2}");
}
dataWs.Worksheet.Save();
}
//now that we are done with all the strings, open up as SAX and write all the values
//the numeric cells are easy, but non numeric have data types and sharedstringpart s to manipulate, so
//that's why I split the two up
using (var myDoc = SpreadsheetDocument.Open(pathname, true))
{
var workbookPart = myDoc.WorkbookPart;
var worksheetPart = GetWorksheetPartByName(myDoc, "Data");
var origninalSheetId = workbookPart.GetIdOfPart(worksheetPart);
var replacementPart =
workbookPart.AddNewPart<WorksheetPart>();
var replacementPartId = workbookPart.GetIdOfPart(replacementPart);
var reader = OpenXmlReader.Create(worksheetPart);
var writer = OpenXmlWriter.Create(replacementPart);
var filteredData = new double[test.Channels.Count][];
if (Filtered)
{
var data = filteredData;
Parallel.ForEach(channels, channel =>
{
var aic = (Test.Module.AnalogInputChannel)channel;
if (null == aic) { return; }
var iChannel = channels.IndexOf(channel);
var sampleCount = aic.PersistentChannelInfo.Data.Length;
data[iChannel] = new double[sampleCount];
for (var iSampleIdx = 0;
iSampleIdx < sampleCount;
iSampleIdx++)
{
data[iChannel][iSampleIdx] = _aicToScaler[iChannel].GetEU(aic.PersistentChannelInfo.Data[iSampleIdx]);
}
var filter = SaeJ211Filter.Parse(aic.SoftwareFilter);
data[iChannel] = filter.Apply(data[iChannel], aic.ParentModule.SampleRateHz, UseLegacyTDCSoftwareFiltering);
});
filteredData = data;
}
headerRowIndex++;
while (reader.Read())
{
if (reader.ElementType == typeof(SheetData) && !reader.IsEndElement)
{
writer.WriteStartElement(new SheetData());
}
else if (reader.ElementType == typeof(SheetData) && reader.IsEndElement)
{
for (var sampleIndex = 0UL;
(int)sampleIndex <= dataCollectionLength;
sampleIndex++)
{
var row = new Row { RowIndex = Convert.ToUInt32(headerRowIndex + sampleIndex) };
writer.WriteStartElement(row);
foreach (var channel in channels)
{
if (!(channel is Test.Module.AnalogInputChannel aic)) { continue; }
var iChannel = channels.IndexOf(channel);
var dStartTime = (double)aic.ParentModule.StartRecordSampleNumber / aic.ParentModule.SampleRateHz;
if (aic.ParentModule.TriggerSampleNumbers.Count > 0)
{
dStartTime -= (double)aic.ParentModule.TriggerSampleNumbers[0] / aic.ParentModule.SampleRateHz;
}
//14513 double rounding error causing data to be offset by one sample incorrectly
// note that using decimals will fix the imprecision issue, but will use more time ...
var delta = Convert.ToDecimal(dStartTime) - Convert.ToDecimal(minStartTime);
var channelOffsetStart = Convert.ToInt32(delta * Convert.ToDecimal(aic.ParentModule.SampleRateHz));
var rate = maxSampleRate / aic.ParentModule.SampleRateHz;
var indexAtCurrentTime = ((double)sampleIndex - channelOffsetStart) / rate;
var thisChannelsIndexAtCurrentTime = Convert.ToInt32(Math.Floor(indexAtCurrentTime));
var step = Convert.ToInt32(Math.Ceiling(indexAtCurrentTime) - thisChannelsIndexAtCurrentTime);
if (0 == iChannel)
{
var time = minStartTime + sampleIndex / maxSampleRate;
var c = new Cell
{
CellValue = new CellValue(time.ToString(CultureInfo.InvariantCulture))
};
writer.WriteElement(c);
}
var value = Filtered ? filteredData[iChannel][thisChannelsIndexAtCurrentTime] : _aicToScaler[iChannel].GetEU(aic.PersistentChannelInfo.Data[thisChannelsIndexAtCurrentTime]);
if (step > 0) //INTERPOLATE
{
var increment = 0D;
if (Filtered)
{
if ((1 + thisChannelsIndexAtCurrentTime) < filteredData[iChannel].Length)
{
increment = (filteredData[iChannel][1 + thisChannelsIndexAtCurrentTime] - value) / rate;
}
else
{
increment = (value - filteredData[iChannel][thisChannelsIndexAtCurrentTime - 1]) / rate;
}
}
else
{
if ((1 + thisChannelsIndexAtCurrentTime) < aic.PersistentChannelInfo.Data.Length)
{
increment = (_aicToScaler[iChannel].GetEU(aic.PersistentChannelInfo.Data[thisChannelsIndexAtCurrentTime + 1]) - value) / rate;
}
else
{
increment = (value - _aicToScaler[iChannel].GetEU(aic.PersistentChannelInfo.Data[thisChannelsIndexAtCurrentTime - 1])) / rate;
}
}
value = value + increment * step;
}
var cell = new Cell
{
CellValue = new CellValue(
value.ToString(CultureInfo.InvariantCulture))
};
writer.WriteElement(cell);
}
if (0 == sampleIndex % UPDATE_INTERVAL)
{
var currentWrite = (double)sampleIndex * test.Channels.Count;
UpdateProgress(100D * currentWrite / expectedWrites, tickEventHandler);
}
writer.WriteEndElement();
}
writer.WriteEndElement();
}
else
{
if (reader.ElementType == typeof(Row) && reader.IsStartElement)
{
writer.WriteElement(reader.LoadCurrentElement());
}
else
{
if (reader.IsStartElement)
{
writer.WriteStartElement(reader);
}
else if (reader.IsEndElement)
{
writer.WriteEndElement();
}
}
}
}
reader.Close();
writer.Close();
var sheet = workbookPart.Workbook.Descendants<Sheet>().Where(s => s.Id.Value.Equals(origninalSheetId)).First();
sheet.Id.Value = replacementPartId;
workbookPart.DeletePart(worksheetPart);
filteredData = null;
}
foreach (var channel in test.Channels)
{
if (!(channel is Test.Module.AnalogInputChannel aic)) continue;
aic.PersistentChannelInfo.UnSet();
// These garbage collection calls cause a significant performance hit and were removed becasue of this. They
// were probably put here when DP was still 32bit only.
//System.Runtime.GCSettings.LatencyMode = System.Runtime.GCLatencyMode.Batch;
//System.Runtime.GCSettings.LargeObjectHeapCompactionMode = System.Runtime.GCLargeObjectHeapCompactionMode.CompactOnce;
//GC.Collect();
}
}
catch (System.Exception ex)
{
APILogger.Log("encountered problem writing XLSX test files", ex);
errorEventHandler?.Invoke(this, ex);
}
finally
{
tickEventHandler?.Invoke(this, 100D);
endEventHandler?.Invoke(this);
}
}
#endregion
/// <summary>
/// constructs the writer with a given file and encoding
/// </summary>
/// <param name="fileType"></param>
/// <param name="encoding"></param>
internal Writer(File fileType, int encoding)
: base(fileType, encoding)
{
ExportADC = false;
ExportEU = true;
ExportMv = false;
WriterParent = fileType;
}
/// <summary>
/// initializes the writer
/// </summary>
/// <param name="pathname"></param>
/// <param name="id"></param>
/// <param name="dataFolder"></param>
/// <param name="test"></param>
/// <param name="bFiltering"></param>
/// <param name="includeGroupNameInISOExport"></param>
/// <param name="fd"></param>
/// <param name="tmChannel"></param>
/// <param name="channelNumber"></param>
/// <param name="beginEventHandler"></param>
/// <param name="cancelEventHandler"></param>
/// <param name="endEventHandler"></param>
/// <param name="tickEventHandler"></param>
/// <param name="errorEventHandler"></param>
/// <param name="cancelRequested"></param>
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)
{
}
}
}
}

View File

@@ -0,0 +1,64 @@
/*
* DTS.Slice.Control.DAS.Channel.IFilterable.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System.Collections.Generic;
using DTS.Slice.Control;
namespace DTS.Common.SerializationPlus
{
/// <summary>
/// Methodical definition of a filterable slice control event module channle.
/// </summary>
public interface IFilterable
//: DTS.Common.DAS.ConceptsIFilterable<Event.Module.Channel, short[]>
{
/// <summary>
/// Get/set the <see cref="bool"/> switch to (de)activate filter caching.
/// </summary>
bool UseFilterCaching
{
get;
set;
}
/// <summary>
/// Get the list of available filters for this object.
/// </summary>
List<IFilter> AvailableFilters
{
get;
}
/// <summary>
/// The currently applied filter.
/// </summary>
IFilter CurrentFilter
{
get;
set;
}
/// <summary>
/// Get the specified filtering for this object.
/// </summary>
///
/// <param name="filter">
/// The <see cref="DTS.Slice.Control.CAS.Channel.IFilter"/> to be applied to this object.
/// </param>
///
/// <param name="displayUnits">
/// Choose the output <see cref="DTS.Slice.Control.DAS.Channel.Data.DisplayUnits"/>.
/// </param>
///
/// <returns>
/// An array of <see cref="double"/> data reflecting the specified parameters.
/// </returns>
///
double[] GetDataFilteredBy(IFilter filter, Event.Module.Channel.DataDisplayUnits displayUnits);
}
}

View File

@@ -0,0 +1,118 @@
/*
* DTS.Slice.Control.ReviewableAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DTS.Utilities;
using DTS.Utilities.DotNetProgrammingConstructs;
namespace DTS.Slice.Control
{
/// <summary>
/// Representation of a "reviewable" attribute.
/// </summary>
abstract public class ReviewableAttribute : Exceptional
{ ///
/// <summary>
/// Initialize an instance of the ReviewableAttribute class.
/// </summary>
///
/// <param name="name">
/// The <see cref="string"/> name of the attribute represented by this object.
/// </param>
///
/// <param name="value">
/// The value of the attribute represented by this object.
/// </param>
///
public ReviewableAttribute(string name, DetermineValueString calculateValue)
{
try
{
this.Name = name;
this.CalculateValue = calculateValue;
}
catch (System.Exception ex)
{
throw new ReviewableAttribute.Exception("encountered problem constructing " + this.GetType().FullName, ex);
}
}
/// <summary>
/// The <see cref="string"/> name associated with this review tab-displayable attribute.
/// </summary>
public string Name
{
get { return _Name.Value; }
private set { _Name.Value = value; }
}
private Property<string> _Name
= new Property<string>(
typeof(ReviewableAttribute).Namespace + ".ReviewableAttribute.Name",
null,
false
);
/// <summary>
/// Get the value <see cref="string"/> for this attribute.
/// </summary>
public string Value
{
get
{
try
{
return CalculateValue();
}
catch (System.Exception ex)
{
Utilities.Logging.APILogger.Log("encountered problem getting ReviewableAttribute value", ex);
return "N/A";
//throw new ReviewableAttribute.Exception( "encountered problem getting ReviewableAttribute value", ex );
}
}
}
// Need to attach the list of attribute "accessors" to the channel in a similar way
// we do with filters. Have an "available" list. And then an "active" list.
public delegate string DetermineValueString();
/// <summary>
/// Determine the value associated with this review tab-displayable attribute.
/// </summary>
private DetermineValueString CalculateValue
{
get
{
try
{
if (!_CalculateValueIsInitialized)
throw new ApplicationException("method property \"CalculateValue\" has not been initialized");
else return _CalculateValue;
}
catch (System.Exception ex)
{
throw new ReviewableAttribute.Exception("encountered problem getting property value", ex);
}
}
set
{
_CalculateValue = value;
_CalculateValueIsInitialized = true;
}
}
private DetermineValueString _CalculateValue;
private bool _CalculateValueIsInitialized = false;
}
}

View File

@@ -0,0 +1,162 @@
using System;
using System.Collections.Generic;
using System.Linq;
using DTS.Common.Interface.DASFactory;
using DTS.Common.Interface.DASFactory.Download;
using DTS.Common.Utilities.Logging;
using DTS.DASLib.Service;
namespace DTS.Common.SerializationPlus
{
public class EventInfoAggregate : IEventInfoAggregate
{
public string EventId { get; set; }
public string EventDescription { get; set; }
public double DurationSeconds { get; set; }
public string GUID { get; set; }
public bool HasBeenDownloaded { get; set; }
public bool WasTriggered { get; set; }
public int NumberOfChannels { get; set; }
public ulong NumberOfSamples { get; set; }
public ulong NumberOfBytes { get; set; }
public bool Faulted { get; set; }
public int EventNumber { get; set; }
private readonly Dictionary<IDASCommunication, int> _eventIndices = new Dictionary<IDASCommunication, int>();
private List<IDASCommunication> _das = null;
private Slice.Control.Event _event;
public Slice.Control.Event GetEvent(bool bClear)
{
if (bClear) { _event = null; }
return GetEvent();
}
public Slice.Control.Event GetEvent()
{
if (null == _event)
{
_event = new Slice.Control.Event(GetDasList(), this);
}
return _event;
}
public int GetEventIndex(IDASCommunication idas)
{
if (!_eventIndices.ContainsKey(idas))
{
APILogger.Log(string.Format("ERROR in GetEventIndex for {0}", idas.SerialNumber));
return -1;
}
return _eventIndices[idas];
}
public List<IDASCommunication> GetDasList()
{
if (null == _das)
{
_das = new List<IDASCommunication>();
_das.AddRange(_eventIndices.Keys.ToArray());
}
return _das;
}
public EventInfoAggregate(DownloadReport.EventInfo newEvent)
{
EventId = newEvent.TestID;
EventDescription = newEvent.Description;
//if newEvent doesn't have modules this will throw an exception, we don't want that
//so populate the event here with no samples, no duration
//I discovered this issue while working on
//15575 No notification if unplug comm cable during downloading on G5
//if units do come back after disconnecting in the download step their module information may not be populated
//and would previously crash
if (newEvent.Modules.Any())
{
DurationSeconds = newEvent.Modules[0].PreTriggerSeconds + newEvent.Modules[0].PostTriggerSeconds;
}
else
{
DurationSeconds = 0;
}
GUID = newEvent.TestGUID.ToString();
HasBeenDownloaded = newEvent.HasBeenDownloaded;
WasTriggered = newEvent.WasTriggered;
NumberOfChannels = newEvent.Modules.Sum(s => s.Channels.Length);
if (newEvent.Modules.Any())
{
NumberOfSamples = newEvent.Modules[0].NumberOfSamples;
}
else
{
NumberOfSamples = 0;
}
NumberOfBytes = NumberOfSamples * (ulong)NumberOfChannels * 2;
Faulted = IsFaulted(newEvent);
EventNumber = newEvent.EventNumber;
if (newEvent.Modules.Any())
{
_eventIndices.Add(((DASModule)newEvent.Modules[0]).OwningDAS, newEvent.EventNumber);
}
}
/// <summary>
/// returns true if faulted
/// </summary>
private bool IsFaulted(IEventInfo info)
{
return 0 != info.FaultFlags || 0 != info.FaultFlagsEx;
}
public void Add(IEventInfo newEvent)
{
if (newEvent.TestID != EventId)
{
APILogger.Log("Warning, expected matching test ids: ", newEvent.TestID, EventId);
}
if (newEvent.Description != EventDescription)
{
APILogger.Log("Warning, expected matching test descriptions: ", newEvent.Description);
}
var duration = newEvent.Modules[0].PreTriggerSeconds + newEvent.Modules[0].PostTriggerSeconds;
if (duration != DurationSeconds)
{
APILogger.Log("Warning, durations don't match: ", duration, DurationSeconds);
DurationSeconds = Math.Min(DurationSeconds, duration);
}
if (newEvent.TestGUID.ToString() != GUID)
{
APILogger.Log("Warning, expected test GUIDs to match,", GUID, newEvent.TestGUID.ToString());
}
if (newEvent.HasBeenDownloaded != HasBeenDownloaded)
{
APILogger.Log("Warning, event has been downloaded from one unit, but not another");
}
if (newEvent.WasTriggered != WasTriggered)
{
APILogger.Log("Warning, one unit has triggered, but another has not");
}
var faulted = IsFaulted(newEvent);
Faulted = Faulted || faulted;
if (newEvent.Modules[0].NumberOfSamples != NumberOfSamples)
{
APILogger.Log("Warning, expected number of samples to match", NumberOfSamples, newEvent.Modules[0].NumberOfSamples);
NumberOfSamples = Math.Min(NumberOfSamples, newEvent.Modules[0].NumberOfSamples);
}
if (newEvent.EventNumber != EventNumber)
{
APILogger.Log("Warning, expected event numbers to match", EventNumber, newEvent.EventNumber);
}
NumberOfChannels += newEvent.Modules.Sum(s => s.Channels.Length);
NumberOfBytes = 2 * (ulong)NumberOfChannels * NumberOfSamples;
//rather than using .Add we should use index assignment in case there are duplicate keys
//I've eliminated the duplicate key that happened because of
//http://manuscript.dts.local/f/cases/44357/TSR-AIR-GO-given-UDP-auto-discovery-is-disabled-manually-entered-ip-address-failed-matching-the-DAS-and-can-t-ARM
//but this is better practice
_eventIndices[((DASModule)newEvent.Modules[0]).OwningDAS] = newEvent.EventNumber;
}
}
}

View File

@@ -0,0 +1,74 @@
/*
* DTS.Slice.Control.Event.Module.ReviewableAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
/// <summary>
/// A reviewable attribute attached to a specific channel.
/// </summary>
abstract public partial class ReviewableAttribute
: Slice.Control.ReviewableAttribute
{
/// <summary>
/// The concrete class should implement this constructor.
/// </summary>
///
/// <param name="channel">
/// The <see cref="DTS.Slice.Control.Event.Module"/> to which a specific instance
/// of this reviewable attribute class is attached. It should be used by this class' subclass'
/// DetermineAttributeValueString method.
/// </param>
///
public ReviewableAttribute(Event.Module channel)
: this(null, null)
{
try
{
throw new NotImplementedException("cannot initialize " + this.GetType().FullName + " with this constructor; must call parameterized version");
}
catch (System.Exception ex)
{
throw new Module.ReviewableAttribute.Exception("encountered problem constructing " + this.GetType().FullName, ex);
}
}
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="name">
/// The <see cref="string"/> name of the attribute represented by this class.
/// </param>
///
/// <param name="calculateValue">
/// The <see cref="DTS.Slice.Control.ReviewableAttribute.DetermineValueString"/>
/// </param>
///
protected ReviewableAttribute(string name, DetermineValueString calculateValue)
: base(name, calculateValue)
{
}
}
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,90 @@
/*
* DTS.Slice.Control.Event.Module.Channel.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using DTS.Common.Utilities;
namespace DTS.Common.SerializationPlus
{
/// <summary>
/// A filter for DTS.Slice.Control.Event.Module.Channels.
/// </summary>
public abstract class Filter
: Exceptional,
IFilter
{
/// <summary>
/// A descriptive <see cref="string"/> designation for the filter.
/// </summary>
public abstract string Name
{
get;
}
/// <summary>
/// Get the <see cref="bool"/> value indicating whether or not this filter
/// corresponds to a CFC value.
/// </summary>
public abstract bool IsCfc
{
get;
}
/// <summary>
/// Get a <see cref="ChannelFilter"/> designation for this filter.
/// </summary>
public abstract ChannelFilter Type
{
get;
}
public abstract char IsoDescription { get; }
/// <summary>
/// Get the <see cref="double"/> cutoff frequency for this filter.
/// </summary>
public abstract double CutoffFrequencyHz
{
get;
}
/// <summary>
/// Apply the filter to the specified input.
/// </summary>
///
/// <param name="input">
/// The input to the filter.
/// </param>
///
/// <param name="displayUnits">
/// The <see cref="DTS.Slice.Control.Event.Module.Channel.DataDisplayUnits"/> to be
/// filtered from the channel.
/// </param>
/// <param name="bUseLegacyTDCSoftwareFilterAdjustment">
/// controls whether filtered data is adjusted by one sample to match TDC behavior
/// 8747
/// </param>
/// <returns>
/// The filtering of the input.
/// </returns>
///
public abstract double[] Apply(
DTS.Slice.Control.Event.Module.Channel input,
Slice.Control.Event.Module.Channel.DataDisplayUnits displayUnits,
bool bUseLegacyTDCSoftwareFilterAdjustment);
public abstract double[] Apply(
double[] data,
double sampleRate,
bool bUseLegacyTDCSoftwareFilterAdjustment);
/// <summary>
/// the ToString is already overloaded, but we sometimes need the base name, not the decorated name that
/// is returned in ToString.
/// </summary>
/// <returns></returns>
public abstract string ToBaseString();
}
}

View File

@@ -0,0 +1,70 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableMeasuredShuntDeflectionAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel
{
/// <summary>
/// A reviewable measured shunt deflection attribute attached to a specific channel.
/// </summary>
public class ReviewableMeasuredShuntDeflectionAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableMeasuredShuntDeflectionAttribute(Event.Module.Channel channel)
: base("Measured Shunt Deflection (mV)", delegate { return (channel as DTS.DAS.Concepts.DAS.Channel.IShuntAware).MeasuredShuntDeflectionMv.ToString("F1"); })
{
}
}
/// <summary>
/// A reviewable measured shunt deflection attribute attached to a specific channel.
/// </summary>
public class ReviewableMeasuredCalSignalAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableMeasuredCalSignalAttribute(Event.Module.Channel channel)
: base("Measured Calibration Signal (mV)", delegate { return (channel as DTS.DAS.Concepts.DAS.Channel.ICalSignalAware).MeasuredCalSignalMv.ToString("F1"); })
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,46 @@
/*
* DTS.Slice.Control.Event.Module.ReviewableDasSerialNumberAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DTS.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
/// <summary>
/// A reviewable filter frequency attribute attached to a specific channel.
/// </summary>
public class ReviewableDasSerialNumberAttribute
: Slice.Control.Event.Module.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module"/> to which this attribute is attached.
/// </param>
///
public ReviewableDasSerialNumberAttribute(Event.Module module)
: base("DAS Serial Number", delegate { return module.DasSerialNumber; })
{
}
}
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,59 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableCfcAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DTS.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel
{
/// <summary>
/// A reviewable CFC attribute attached to a specific channel.
/// </summary>
public class ReviewableCfcAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableCfcAttribute(Event.Module.Channel channel)
: base("CFC",
delegate
{
//return ( new CfcValueAttributeCoder( ).DecodeAttributeValue( ( channel.CurrentFilter as SaeJ211Filter ).Type ) ).ToString( );
if (channel.CurrentFilter.Type == ChannelFilter.AdHoc) { return "N/A"; }
else { return (new CfcValueAttributeCoder().DecodeAttributeValue((channel.CurrentFilter as SaeJ211Filter).Type)).ToString(); }
}
)
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,69 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableTargetShuntDeflectionAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel
{
/// <summary>
/// A reviewable target shunt deflection attribute attached to a specific channel.
/// </summary>
public class ReviewableTargetShuntDeflectionAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableTargetShuntDeflectionAttribute(Event.Module.Channel channel)
: base("Target Shunt Deflection (mV)", delegate { return (channel as DTS.DAS.Concepts.DAS.Channel.IShuntAware).TargetShuntDeflectionMv.ToString("F1"); })
{
}
}
/// <summary>
/// A reviewable target shunt deflection attribute attached to a specific channel.
/// </summary>
public class ReviewableTargetCalSignalAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableTargetCalSignalAttribute(Event.Module.Channel channel)
: base("Target Calibration Signal (mV)", delegate { return (channel as DTS.DAS.Concepts.DAS.Channel.ICalSignalAware).TargetCalSignalMv.ToString("F1"); })
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,52 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableMinMaxEuAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DTS.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel
{
/// <summary>
/// A reviewable min/max EU attribute attached to a specific channel.
/// </summary>
public class ReviewableMinMaxEuAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableMinMaxEuAttribute(Event.Module.Channel channel)
: base("Max/Min (EU)", delegate { return channel.DataMaxFilteredEu.ToString("F1") + "/" + channel.DataMinFilteredEu.ToString("F1"); })
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,418 @@
using System;
using System.Collections.Generic;
using System.Linq;
using DTS.Common.Interface.DASFactory.Diagnostics;
using DTS.Common.SerializationPlus;
using DTS.Common.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
public partial class Channel
{
public abstract class CalculatedChannel : Channel, Common.DAS.Concepts.DAS.Channel.IEngineeringUnitAware
{
public enum Operation
{
Integral,
//DefiniteIntegral,
Derivative,
HeadInjuryCriteria,
FFT,
ImportedCSV,
Resultant,
TSR,
Scale,
Offset,
Sine,
Cosine,
}
private readonly Operation _operation;
public Operation CalculationType => _operation;
private readonly List<double> _x = new List<double>();
public double[] X => _x.ToArray();
private readonly List<double> _y = new List<double>();
public double[] Y => _y.ToArray();
private readonly XUnits _xAxis;
public XUnits XAxis => _xAxis;
public string XUnitsString
{
get
{
switch (_xAxis)
{
case XUnits.Hz: return "Hz";
case XUnits.msec: return "ms";
case XUnits.samples: return "samples";
case XUnits.sec: return "s";
default: return "N/A";
}
}
}
private string _yAxis;
public string EngineeringUnits
{
get => _yAxis;
set => _yAxis = value;
}
public override bool SupportsADC => false;
public override bool SupportsEU => true;
public override bool SupportsmV => false;
public override double ActualMaxRangeEu => _y.Max();
public override double ActualMaxRangeMv => throw new NotSupportedException();
public override double ActualMinRangeEu => _y.Min();
public override double ActualMinRangeMv => throw new NotImplementedException();
public override double DataHalfRangeValueEu => .5D * (_y.Min() + _y.Max());
public override double DataMaxEu => _y.Max();
public override double DataMinEu => _y.Min();
public override double DataRangeEu => (Math.Max(Math.Abs(_y.Min()), Math.Abs(_y.Max())));
public override short DataZeroLevelAdc => 0;
public override bool IsConfigured
{
get => true;
set => throw new NotSupportedException();
}
public override void FromDtsSerializationTestModuleChannel(Serialization.Test.Module.Channel that)
{
throw new NotSupportedException();
}
public override List<double> GetUnfilteredDataEu()
{
return new List<double>(_y);
}
/*
protected override void InitializeReviewableAttributes(List<ReviewableAttribute> reviewableAttributes)
{
switch (CalculationType)
{
case Operation.HeadInjuryCriteria:
break;
case Operation.ImportedCSV:
break;
case Operation.TSR:
break;
}
} */
public override void SetPropertyValuesFrom(DASLib.Service.DASChannel dasChannel)
{
throw new NotSupportedException();
}
public override void SetPropertyValuesFrom(IDiagnosticResult diagResults)
{
throw new NotSupportedException();
}
public override Serialization.Test.Module.Channel ToDtsSerializationTestModuleChannel(Serialization.Test.Module parentModule)
{
throw new NotSupportedException();
}
public override double SensorCapacityEU => throw new NotImplementedException();
public override List<double> GetUnfilteredDataMV()
{
throw new NotImplementedException();
}
public override double DesiredRangeEU => throw new NotImplementedException();
public enum XUnits
{
msec,
sec,
Hz,
samples
}
public CalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule
)
{
_x = new List<double>(xValues);
_y = new List<double>(yValues);
_xAxis = xAxis;
_yAxis = yAxis;
ChannelDescriptionString = name;
_operation = calcType;
Number = number;
CurrentFilter = new DefaultSaeJ211Filter(ChannelFilter.Unfiltered);
ParentModule = parentModule;
_UnfilteredDataEu = new List<double>(yValues);
DataCount = yValues.Length;
}
/// <summary>
/// Generate a <see cref="string"/> representation for this object.
/// </summary>
///
/// <returns>
/// The <see cref="string"/> representation of this object.
/// </returns>
///
public override string ToString()
{
try
{
return !string.IsNullOrEmpty(ChannelDescriptionString) ? ChannelDescriptionString : "N/A";
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting string representation", ex);
}
}
}
public class FFTCalculatedChannel : CalculatedChannel
{
private readonly double _peakFrequency;
public double PeakFrequency => _peakFrequency;
public FFTCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule,
double peakFrequency)
: base(name, xAxis, yAxis, xValues, yValues, calcType, number, parentModule)
{
_peakFrequency = peakFrequency;
}
/*
protected override void InitializeReviewableAttributes(List<ReviewableAttribute> reviewableAttributes)
{
base.InitializeReviewableAttributes(reviewableAttributes);
//try { reviewableAttributes.Add(new ReviewablePeakFrequencyAttribute(this)); }
//catch { }
}
public class ReviewablePeakFrequencyAttribute : Slice.Control.Event.Module.Channel.ReviewableAttribute
{
public ReviewablePeakFrequencyAttribute(Event.Module.Channel channel)
: base("Peak (Hz)",
delegate { return (channel as FFTCalculatedChannel).PeakFrequency.ToString("N"); }) { }
}*/
}
public class IntegralCalculatedChannel : CalculatedChannel
{
public IntegralCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule
)
: base(name, xAxis, yAxis, xValues, yValues, calcType, number, parentModule)
{ }
}
public class DerivativeCalculatedChannel : CalculatedChannel
{
public DerivativeCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule
)
: base(name, xAxis, yAxis, xValues, yValues, calcType, number, parentModule)
{ }
}
public class ScaleCalculatedChannel : CalculatedChannel
{
public ScaleCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule)
: base(name, xAxis, yAxis, xValues, yValues, calcType, number, parentModule)
{ }
}
public class OffsetCalculatedChannel : CalculatedChannel
{
public OffsetCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yVAlues,
Operation calcType,
int number,
Module parentModule)
: base(name, xAxis, yAxis, xValues, yVAlues, calcType, number, parentModule)
{ }
}
public class ResultantCalculatedChannel : CalculatedChannel
{
public ResultantCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule)
: base(name, xAxis, yAxis, xValues, yValues, calcType, number, parentModule)
{ }
}
public class AdditiveVectorCalculatedChannel : CalculatedChannel
{
public AdditiveVectorCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule)
: base(name, xAxis, yAxis, xValues, yValues, calcType, number, parentModule)
{ }
}
public class SineCalculatedChannel : CalculatedChannel
{
public SineCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule
)
: base(name, xAxis, yAxis, xValues, yValues, calcType, number, parentModule)
{ }
}
public class CosineCalculatedChannel : CalculatedChannel
{
public CosineCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule
)
: base(name, xAxis, yAxis, xValues, yValues, calcType, number, parentModule)
{ }
}
/*
public class HICCalculatedChannel : CalculatedChannel
{
public double GetT1(bool ms)
{
double start = (double)HIC.StartSample - (double)ParentModule.TriggerSampleNumbers[0] +
(double)ParentModule.StartRecordSampleNumber;
start /= (double)ParentModule.SampleRateHz;
if (ms) { start *= 1000; }
return start;
}
public double GetT2(bool ms)
{
double end = (double)HIC.EndSample - (double)ParentModule.TriggerSampleNumbers[0]
+ (double)ParentModule.StartRecordSampleNumber;
end /= (double)ParentModule.SampleRateHz;
if (ms) { end *= 1000; }
return end;
}
public HICCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule,
DTS.Calculations.HeadInjuryCriterion.HICResult hic
)
: base(name, xAxis, yAxis, xValues, yValues, calcType, number, parentModule)
{
_hic = hic;
}
private DTS.Calculations.HeadInjuryCriterion.HICResult _hic;
public DTS.Calculations.HeadInjuryCriterion.HICResult HIC { get { return _hic; } }
protected override void InitializeReviewableAttributes(List<ReviewableAttribute> reviewableAttributes)
{
base.InitializeReviewableAttributes(reviewableAttributes);
try { reviewableAttributes.Add(new ReviewableHICAttribute(this)); }
catch {}
try { reviewableAttributes.Add(new ReviewableHICLengthAttribute(this)); }
catch { }
try { reviewableAttributes.Add(new ReviewableHICT1T2Attribute(this)); }
catch { }
}
public class ReviewableHICLengthAttribute : Slice.Control.Event.Module.Channel.ReviewableAttribute
{
public ReviewableHICLengthAttribute(Event.Module.Channel channel)
: base("Clip Length",
delegate { return (channel as HICCalculatedChannel).HIC.HicLengthMS.ToString(); }) { }
}
public class ReviewableHICAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableHICAttribute(Event.Module.Channel channel)
: base("HIC",
delegate { return (channel as HICCalculatedChannel).HIC.HIC.ToString("N1"); })
{
}
}
public class ReviewableHICT1T2Attribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
public ReviewableHICT1T2Attribute(Event.Module.Channel channel)
: base("T1/T2",
delegate
{
HICCalculatedChannel hic = channel as HICCalculatedChannel;
if (null == hic) { return ""; }
else { return string.Format("{0}s/{1}s", hic.GetT1(false), hic.GetT2(false)); }
})
{
}
}
}
* */
}
}
}
}

View File

@@ -0,0 +1,77 @@
/*
* Excel.File.cs
*
* Copyright © 2017
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
namespace DTS.Serialization.XLSX
{
/// <summary>
/// implementation of the Serialization.File class for XLSX
/// http://fogbugz/fogbugz/default.asp?9920'
/// right now this will only export EU, (filtered or unfiltered)
/// but we'll likely want to control whether to export mV/ADC in future
/// </summary>
public partial class File
: Serialization.File, IWritable<Test>
{
/// <summary>
/// constructor
/// </summary>
public File()
: base("XLSX")
{
}
/// <summary>
/// Get the file writer for this file type.
/// </summary>
public IWriter<Test> Exporter
{
get
{
try
{
if (_exporter == null)
{
var writer = new Writer(this, DefaultEncoding);
_exporter = writer;
}
return _exporter;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting exporter", ex);
}
}
}
private IWriter<Test> _exporter;
/// <summary>
/// Controls whether to export ADC or not
/// </summary>
public bool ExportADC
{
set => ((Writer)Exporter).ExportADC = value;
}
/// <summary>
/// Controls whether to export EU or not
/// </summary>
public bool ExportEU
{
set => ((Writer)Exporter).ExportEU = value;
}
/// <summary>
/// Controls whether to export mV or not
/// </summary>
public bool ExportMV
{
set => ((Writer)Exporter).ExportMv = value;
}
}
}

View File

@@ -0,0 +1,181 @@
/*
DTS.Slice.Control.IntervalSec.cs
Copyright © 2008
Diversified Technical Systems, Inc.
All Rights Reserved
*/
using DTS.Common.Utilities;
using DTS.Common.Utilities.DotNetProgrammingConstructs;
namespace DTS.Slice.Control
{
/// <summary>
/// Get/set the begin value.
/// </summary>
public class IntervalSec : Exceptional
{
/// <summary>
/// Create an instance of the IntervalSec class.
/// </summary>
public IntervalSec()
{ //
// Note that calling the parameterless constructor will leave the begin and
// end properties "uninitialized".
} //
/// <summary>
/// Create an instance of the IntervalSec class.
/// </summary>
///
/// <param name="begin">
/// The <see cref="double"/> begin time of this interval.
/// </param>
///
/// <param name="end">
/// The <see cref="double"/> end time of this interval.
/// </param>
///
public IntervalSec(double begin, double end)
{
try
{
Begin = begin;
End = end;
}
catch (System.Exception ex)
{
throw new Exception(
"encountered problem constructing " + GetType().FullName, ex);
}
}
/// <summary>
/// Get/set the <see cref="double"/> begin time of the interval.
/// </summary>
public double Begin
{
get => _Begin.Value;
set => _Begin.Value = value;
}
private readonly Property<double> _Begin
= new Property<double>(
typeof(IntervalSec).Namespace + ".IntervalSec.Begin", 0, false);
/// <summary>
/// Get/set the <see cref="double"/> end time of the interval.
/// </summary>
public double End
{
get => _End.Value;
set => _End.Value = value;
}
private readonly Property<double> _End
= new Property<double>(
typeof(IntervalSec).Namespace + ".IntervalSec.End", 0, false);
/// <summary>
/// Method to implicitly convert this type into a DTS.Serialization.Test.IntervalSec.
/// </summary>
///
/// <param name="thisInterval">
/// The <see cref="DTS.Slice.Control.IntervalSec"/> to be converted.
/// </param>
///
/// <returns>
/// A <see cref="DTS.Serialization.Test.IntervalSec"/> equivalent to the speceified interval
/// object.
/// </returns>
///
public static implicit operator Serialization.Test.IntervalSec(IntervalSec thisInterval)
{
try
{
return new Serialization.Test.IntervalSec(thisInterval.Begin, thisInterval.End);
}
catch (System.Exception ex)
{
throw new Exception("encountered problem implicitly converting " + typeof(IntervalSec).FullName + " to " + typeof(Serialization.Test.IntervalSec).FullName, ex);
}
}
/// <summary>
/// Method to implicitly convert a DTS.Serialization.Test.IntervalSec object into this type.
/// </summary>
///
/// <param name="thatInterval">
/// The <see cref="DTS.Serialization.Test.IntervalSec"/> to be converted.
/// </param>
///
/// <returns>
/// A <see cref="DTS.Slice.Control.IntervalSec"/> equivalent to the specified interval
/// object.
/// </returns>
///
public static implicit operator IntervalSec(Serialization.Test.IntervalSec thatInterval)
{
try
{
return new IntervalSec(thatInterval.Begin, thatInterval.End);
}
catch (System.Exception ex)
{
throw new Exception("encountered problem implicitly converting " + typeof(Serialization.Test.IntervalSec).FullName + " to " + typeof(IntervalSec).FullName, ex);
}
}
/// <summary>
/// Test the specified object for equality with this object.
/// </summary>
///
/// <param name="obj">
/// The <see cref="object"/> to be tested for equality.
/// </param>
///
/// <returns>
/// <see cref="bool"/> true if the specified object has memeberwise equality with
/// this object; false otherwise.
/// </returns>
///
public override bool Equals(object obj)
{
try
{
var that = obj as IntervalSec;
return null != obj
&& Begin.Equals(that.Begin)
&& End.Equals(that.End);
}
catch (System.Exception ex)
{
throw new Exception("encountered problem equality-testing the object " + (null != obj ? "\"" + obj.ToString() + "\"" : "<<NULL>>"), ex);
}
}
/// <summary>
/// Get has code for this object.
/// </summary>
///
/// <returns>
/// The <see cref="int"/> hash code for this object.
/// </returns>
///
public override int GetHashCode()
{
try
{
return base.GetHashCode();
}
catch (System.Exception ex)
{
throw new Exception("encountered problem generating hash code for " + GetType().FullName, ex);
}
}
}
}

View File

@@ -0,0 +1,51 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableUnitsAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel
{
/// <summary>
/// A reviewable engineering units attribute attached to a specific channel.
/// </summary>
public class ReviewableUnitsAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableUnitsAttribute(Event.Module.Channel channel)
: base("Units", delegate { return (channel as DTS.DAS.Concepts.DAS.Channel.IEngineeringUnitAware).EngineeringUnits.ToString(); })
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,81 @@
/*
* DTS.Slice.Control.Event.Module.ReviewableSampleRateAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DTS.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event {
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module {
/// <summary>
/// A reviewable filter frequency attribute attached to a specific channel.
/// </summary>
public class ReviewableSampleRateAttribute
: Slice.Control.Event.Module.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module"/> to which this attribute is attached.
/// </param>
///
public ReviewableSampleRateAttribute(Event.Module module)
: base("Sample Rate", delegate { return module.SampleRateHz.ToString("N"); })
{
}
}
/// <summary>
/// A reviewable filter frequency attribute attached to a specific channel.
/// </summary>
public class ReviewableTestDescriptionAttribute
: Slice.Control.Event.Module.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module"/> to which this attribute is attached.
/// </param>
///
public ReviewableTestDescriptionAttribute(Event.Module module)
: base("Test Description", delegate { return module.ParentEvent.Description; })
{
}
}
public class ReviewableHardwareFrequencyAttribute
: Slice.Control.Event.Module.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableHardwareFrequencyAttribute(Event.Module module)
: base("HW AAF", delegate { return module.AaFilterRateHz.ToString("N2"); })
{
}
}
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,114 @@
/*
* DTS.Slice.Control.Event.Module.Channel.SaeJ211Filter.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using DTS.Common.Utilities;
namespace DTS.Common.SerializationPlus
{
/// <summary>
/// Base class for all SaeJ211-based event module channel filters. It is intended
/// that fixed-filter-setting filters be derived from this class that will set their
/// filter setting using the protected constructor.
/// </summary>
public class DefaultSaeJ211Filter
: SaeJ211Filter
{
public DefaultSaeJ211Filter(SaeJ211Filter filter)
: base(filter)
{
}
/// <summary>
/// Initialize an instance of the DefaultSaeJ211Filter class.
/// </summary>
///
/// <param name="filterType">
/// The <see cref="ChannelFilter"/> to be applied by this filter.
/// </param>
///
public DefaultSaeJ211Filter(ChannelFilter filterType)
: base(filterType)
{
}
/// <summary>
/// Initialize an instance of the DefaultSaeJ211Filter class.
/// </summary>
///
///<param name="adHocFrequency">
///The <see cref="double"/> ad hoc frequency of this filter.
/// </param>
///
public DefaultSaeJ211Filter(double adHocFrequency)
: base(adHocFrequency)
{
}
/// <summary>
/// The <see cref="string"/> name of this filter.
/// </summary>
public override string Name
{
get
{
try
{
return "Default (" + base.Name + ")";
}
catch (System.Exception ex)
{
throw new Exception("encountered problem generating name string for " + GetType().FullName, ex);
}
}
}
/// <summary>
/// Generate a string representation of this object.
/// </summary>
///
/// <returns>
/// A <see cref="string"/> representation of this object.
/// </returns>
///
public override string ToBaseString()
{
try
{
return base.Name;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem generating the string value for " + GetType().FullName, ex);
}
}
/// <summary>
/// Generate a string representation of this object.
/// </summary>
///
/// <returns>
/// A <see cref="string"/> representation of this object.
/// </returns>
///
public override string ToString()
{
try
{
return Name;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem generating the string value for " + GetType().FullName, ex);
}
}
}
}

View File

@@ -0,0 +1,26 @@
/*
* DTS.Slice.Control.Event.DasChannelAccessor.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System.Collections.Generic;
using DTS.Common.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
/// <summary>
/// An object returned during Event creation that allows access to the event's channel
/// by DAS ID/DAS channel number pair.
/// </summary>
public class DasChannelAccessor : ExceptionalDictionary<Common.DAS.Concepts.DAS.Id, List<Module.Channel>>
{
public DasChannelAccessor() { }
}
}
}

View File

@@ -0,0 +1,49 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableFilterFrequencyAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DTS.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event {
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module {
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel {
/// <summary>
/// A reviewable filter frequency attribute attached to a specific channel.
/// </summary>
public class ReviewableFilterFrequencyAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableFilterFrequencyAttribute( Event.Module.Channel channel )
: base( "Filter Frequency", delegate { return ( ( int )( channel.CurrentFilter as SaeJ211Filter ).CutoffFrequencyHz ).ToString("N"); } )
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,47 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableShuntDeflectionAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event {
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module {
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel {
/// <summary>
/// A reviewable shunt deflection attribute attached to a specific channel.
/// </summary>
public class ReviewableShuntDeflectionAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableShuntDeflectionAttribute( Event.Module.Channel channel )
: base( "Shunt Deflection (mV)", delegate { return ( channel as DTS.DAS.Concepts.DAS.Channel.IShuntAware ).MeasuredShuntDeflectionMv.ToString( "F1" ); } )
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,89 @@
/*
* DTS.Slice.Control.DAS.Channel.IFilter.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using DTS.Common.Utilities;
using DTS.Slice.Control;
namespace DTS.Common.SerializationPlus
{
/// <summary>
/// Methodical definition of a slice control event module channel filter.
/// </summary>
public interface IFilter
{
/// <summary>
/// A descriptive <see cref="string"/> designation for the filter.
/// </summary>
string Name
{
get;
}
/// <summary>
/// value indicating whether or not this filter is
/// a cardinal CFC value.
/// </summary>
bool IsCfc
{
get;
}
/// <summary>
/// Get a <see cref="ChannelFilter"/> designation for this filter.
/// </summary>
ChannelFilter Type
{
get;
}
/// <summary>
/// Get the <see cref="double"/> cutoff frequency for this filter.
/// </summary>
double CutoffFrequencyHz
{
get;
}
char IsoDescription { get; }
/// <summary>
/// Apply the filter to the specified input.
/// </summary>
///
/// <param name="input">
/// The input to the filter.
/// </param>
///
/// <param name="displayUnits">
/// The <see cref="Event.Module.Channel.DataDisplayUnits"/> to be
/// filtered from the channel.
/// </param>
/// <param name="bUseLegacyTDCSofwareFilterAdjustment">
/// when true will adjust data one sample to the right to preserve existing TDC filtering behavior
/// </param>
/// <returns>
/// The filtering of the input.
/// </returns>
///
double[] Apply(
Event.Module.Channel input,
Event.Module.Channel.DataDisplayUnits displayUnits,
bool bUseLegacyTDCSofwareFilterAdjustment);
double[] Apply(
double[] data,
double sampleRate,
bool bUseLegacyTDCSoftwareFilterAdjustment
);
/// <summary>
/// the ToString is already overloaded, but we sometimes need the base name, not the decorated name that
/// is returned in ToString.
/// </summary>
/// <returns></returns>
string ToBaseString();
}
}

View File

@@ -0,0 +1,26 @@
/*
* DTS.Slice.Control.Event.DasModuleAccessor.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System.Collections.Generic;
using DTS.Common.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
/// <summary>
/// An object returned during Event creation that allows access to the event's module information
/// by DAS ID/DAS module number pair.
/// </summary>
public class DasModuleAccessor : ExceptionalDictionary<Common.DAS.Concepts.DAS.Id, List<Module>>
{
public DasModuleAccessor() { }
}
}
}

View File

@@ -0,0 +1,27 @@
/*
* DTS.Slice.Control.Event.ModuleChannelAccessor.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using DTS.Common.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
/// <summary>
/// A component object of the Event.DasModuleChannelAccessor.
/// </summary>
public class ModuleChannelAccessor : ExceptionalDictionary<int, ChannelAccessor> // xxx change this int to DAS.Module.Id?
{
/// <summary>
/// Initialize an instance of the DTS.Slice.Control.Event.ModuleChannelAccessor class.
/// </summary>
public ModuleChannelAccessor() { }
}
}
}

View File

@@ -0,0 +1,84 @@
/*
* DTS.Slice.Control.Event.Module.Channel.DataValues.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using DTS.Common.Utilities;
using DTS.Common.Utilities.DotNetProgrammingConstructs;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.Channel.cs ***
public partial class Channel
{
/// <summary>
/// Representation of a channel's data.
/// </summary>
public class DataValues : Exceptional
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
public DataValues()
: this(true)
{
}
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="useMemoryMappedFile">
/// A <see cref="bool"/> determining whether or not this data class will use memory mapped files
/// to store data (necessary for data sets that exceed internal process memory limitations).
/// </param>
///
public DataValues(bool useMemoryMappedFile)
{
try
{
UseMemoryMappedFile = useMemoryMappedFile;
if (UseMemoryMappedFile)
{
}
}
catch (System.Exception ex)
{
throw new Exception("encountered problem constructing " + GetType().FullName, ex);
}
}
/// <summary>
/// Get/set the switch that will cause this class to use memory mapped files in lieu
/// of in-memory list.
/// </summary>
public bool UseMemoryMappedFile
{
get => _UseMemoryMappedFile.Value;
set => _UseMemoryMappedFile.Value = value;
}
private readonly Property<bool> _UseMemoryMappedFile =
new Property<bool>(
typeof(DataValues).Namespace + ".UseMemoryMappedFile",
false,
false
);
}
} // *** End Event.Module.Channel ***
} // *** End Event.Module ***
} // *** End Event ***
}

View File

@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{B9D1AC5B-7A6F-4B14-9FF8-3A1FC03519E2}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DTS.Common.SerializationPlus</RootNamespace>
<AssemblyName>DTS.Common.SerializationPlus</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="DocumentFormat.OpenXml, Version=2.5.5631.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>C:\Program Files (x86)\Open XML SDK\V2.5\lib\DocumentFormat.OpenXml.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="Filter\IFilter.cs" />
<Compile Include="Filter\IFilterable.cs" />
<Compile Include="Control\Event\ChannelAccessor.cs" />
<Compile Include="Control\Event\DasChannelAccessor.cs" />
<Compile Include="Control\Event\DasModuleAccessor.cs" />
<Compile Include="Control\Event\DasModuleChannelAccessor.cs" />
<Compile Include="Control\Event\Event.cs" />
<Compile Include="Control\Event\ModuleChannelAccessor.cs" />
<Compile Include="Control\Event\Module\AnalogInputChannel\AnalogInputChannel.cs" />
<Compile Include="Control\Event\Module\Channel\CalculatedChannel.cs" />
<Compile Include="Control\Event\Module\Channel\Channel.cs" />
<Compile Include="Filter\ChannelDefaultSaeJ211Filter.cs" />
<Compile Include="Control\Event\Module\Channel\DataValues.cs" />
<Compile Include="Filter\Filter.cs" />
<Compile Include="Filter\SaeJ211Filter.cs" />
<Compile Include="Control\Event\Module\Module.cs" />
<Compile Include="Control\Event\TestInformation.cs" />
<Compile Include="Control\IntervalSec.cs" />
<Compile Include="EventInfoAggregate.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="XLSX\Excel.File.cs" />
<Compile Include="XLSX\Excel.File.Writer.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Common\DTS.Common.DAS.Concepts\DTS.Common.DAS.Concepts.csproj">
<Project>{03d8c736-36eb-4cd1-a6d9-130452b23239}</Project>
<Name>DTS.Common.DAS.Concepts</Name>
</ProjectReference>
<ProjectReference Include="..\..\Common\DTS.Common.DASResource\DTS.Common.DASResource.csproj">
<Project>{23c0fb0c-35d9-4a4d-a1a1-0deb5c217106}</Project>
<Name>DTS.Common.DASResource</Name>
</ProjectReference>
<ProjectReference Include="..\..\Common\DTS.Common.Serialization\DTS.Common.Serialization.csproj">
<Project>{b7d50b14-fa61-4fe4-bff7-b257902b55b0}</Project>
<Name>DTS.Common.Serialization</Name>
</ProjectReference>
<ProjectReference Include="..\..\Common\DTS.Common.Utilities\DTS.Common.Utilities.csproj">
<Project>{03eace47-ea59-44ac-b49d-956e4dc4d618}</Project>
<Name>DTS.Common.Utilities</Name>
</ProjectReference>
<ProjectReference Include="..\..\DataPRO\IService\IService.csproj">
<Project>{c9c45b72-05a3-4962-bc13-a78b1f4b1925}</Project>
<Name>IService</Name>
</ProjectReference>
<ProjectReference Include="..\DTS.Common\DTS.Common.csproj">
<Project>{114EDC77-F3B5-4576-A91B-40818D503B55}</Project>
<Name>DTS.Common</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Design\DTS.Common.SerialzationPlusClassDiagram.cd" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

Binary file not shown.

View File

@@ -0,0 +1,27 @@
/*
* DTS.Slice.Control.Event.ChannelAccessor.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using DTS.Common.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
/// <summary>
/// A component object of the Event.DasModuleChannelAccessor.
/// </summary>
public class ChannelAccessor : ExceptionalDictionary<int, Module.Channel> // xxx change this int to DAS.(Module?).Channel.Id?
{
/// <summary>
/// Initialize an instance of the DTS.Slice.Control.Event.ChannelAccessor class.
/// </summary>
public ChannelAccessor() { }
}
}
}

View File

@@ -0,0 +1,26 @@
/*
* DTS.Slice.Control.Event.DasChannelAccessor.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System.Collections.Generic;
using DTS.Common.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
/// <summary>
/// An object returned during Event creation that allows access to the event's channel
/// by DAS ID/DAS channel number pair.
/// </summary>
public class DasChannelAccessor : ExceptionalDictionary<Common.DAS.Concepts.DAS.Id, List<Module.Channel>>
{
public DasChannelAccessor() { }
}
}
}

View File

@@ -0,0 +1,26 @@
/*
* DTS.Slice.Control.Event.DasModuleAccessor.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System.Collections.Generic;
using DTS.Common.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
/// <summary>
/// An object returned during Event creation that allows access to the event's module information
/// by DAS ID/DAS module number pair.
/// </summary>
public class DasModuleAccessor : ExceptionalDictionary<Common.DAS.Concepts.DAS.Id, List<Module>>
{
public DasModuleAccessor() { }
}
}
}

View File

@@ -0,0 +1,28 @@
/*
* DTS.Slice.Control.Event.DasModuleChannelAccessor.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using DTS.Common.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
/// <summary>
/// An object returned during Event creation that allows access to the event's channel information
/// by DAS ID/DAS module number/module channel number triplet.
/// </summary>
public class DasModuleChannelAccessor : ExceptionalDictionary<Common.DAS.Concepts.DAS.Id, ModuleChannelAccessor>
{
/// <summary>
/// Initialize an instance of the DTS.Slice.Control.Event.DasModuleChannelAccessor class.
/// </summary>
public DasModuleChannelAccessor() { }
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,59 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableCfcAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DTS.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel
{
/// <summary>
/// A reviewable CFC attribute attached to a specific channel.
/// </summary>
public class ReviewableCfcAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableCfcAttribute(Event.Module.Channel channel)
: base("CFC",
delegate
{
//return ( new CfcValueAttributeCoder( ).DecodeAttributeValue( ( channel.CurrentFilter as SaeJ211Filter ).Type ) ).ToString( );
if (channel.CurrentFilter.Type == ChannelFilter.AdHoc) { return "N/A"; }
else { return (new CfcValueAttributeCoder().DecodeAttributeValue((channel.CurrentFilter as SaeJ211Filter).Type)).ToString(); }
}
)
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,52 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableCfcAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DTS.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel
{
/// <summary>
/// A reviewable CFC attribute attached to a specific channel.
/// </summary>
public class ReviewableDescriptionAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableDescriptionAttribute(Event.Module.Channel channel)
: base("Description", delegate { return channel.ChannelDescriptionString; })
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,49 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableFilterFrequencyAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DTS.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event {
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module {
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel {
/// <summary>
/// A reviewable filter frequency attribute attached to a specific channel.
/// </summary>
public class ReviewableFilterFrequencyAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableFilterFrequencyAttribute( Event.Module.Channel channel )
: base( "Filter Frequency", delegate { return ( ( int )( channel.CurrentFilter as SaeJ211Filter ).CutoffFrequencyHz ).ToString("N"); } )
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,50 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableIsoCodeAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel
{
/// <summary>
/// A reviewable serial number attribute attached to a specific channel.
/// </summary>
public class ReviewableIsoCodeAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableIsoCodeAttribute(Event.Module.Channel channel)
: base("ISO Code", delegate { return (channel as AnalogInputChannel).IsoCode.ToString(); })
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,70 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableMeasuredShuntDeflectionAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel
{
/// <summary>
/// A reviewable measured shunt deflection attribute attached to a specific channel.
/// </summary>
public class ReviewableMeasuredShuntDeflectionAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableMeasuredShuntDeflectionAttribute(Event.Module.Channel channel)
: base("Measured Shunt Deflection (mV)", delegate { return (channel as DTS.DAS.Concepts.DAS.Channel.IShuntAware).MeasuredShuntDeflectionMv.ToString("F1"); })
{
}
}
/// <summary>
/// A reviewable measured shunt deflection attribute attached to a specific channel.
/// </summary>
public class ReviewableMeasuredCalSignalAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableMeasuredCalSignalAttribute(Event.Module.Channel channel)
: base("Measured Calibration Signal (mV)", delegate { return (channel as DTS.DAS.Concepts.DAS.Channel.ICalSignalAware).MeasuredCalSignalMv.ToString("F1"); })
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,52 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableMinMaxEuAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DTS.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel
{
/// <summary>
/// A reviewable min/max EU attribute attached to a specific channel.
/// </summary>
public class ReviewableMinMaxEuAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableMinMaxEuAttribute(Event.Module.Channel channel)
: base("Max/Min (EU)", delegate { return channel.DataMaxFilteredEu.ToString("F1") + "/" + channel.DataMinFilteredEu.ToString("F1"); })
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,50 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableSerialNumberAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel
{
/// <summary>
/// A reviewable serial number attribute attached to a specific channel.
/// </summary>
public class ReviewableSerialNumberAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableSerialNumberAttribute(Event.Module.Channel channel)
: base("Serial Number", delegate { return (channel as AnalogInputChannel).SerialNumber.ToString(); })
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,47 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableShuntDeflectionAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event {
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module {
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel {
/// <summary>
/// A reviewable shunt deflection attribute attached to a specific channel.
/// </summary>
public class ReviewableShuntDeflectionAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableShuntDeflectionAttribute( Event.Module.Channel channel )
: base( "Shunt Deflection (mV)", delegate { return ( channel as DTS.DAS.Concepts.DAS.Channel.IShuntAware ).MeasuredShuntDeflectionMv.ToString( "F1" ); } )
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,69 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableShuntDeflectionPercentageAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel
{
/// <summary>
/// A reviewable shunt deflection attribute attached to a specific channel.
/// </summary>
public class ReviewableShuntDeflectionPercentageAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableShuntDeflectionPercentageAttribute(Event.Module.Channel channel)
: base("Shunt Error (%)", delegate { return (100.0 * ((channel as DTS.DAS.Concepts.DAS.Channel.IShuntAware).MeasuredShuntDeflectionMv - (channel as DTS.DAS.Concepts.DAS.Channel.IShuntAware).TargetShuntDeflectionMv) / (channel as DTS.DAS.Concepts.DAS.Channel.IShuntAware).TargetShuntDeflectionMv).ToString("F1"); })
{
}
}
/// <summary>
/// A reviewable shunt deflection attribute attached to a specific channel.
/// </summary>
public class ReviewableCalSignalPercentageAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableCalSignalPercentageAttribute(Event.Module.Channel channel)
: base("Calibration Signal Error (%)", delegate { return (100.0 * ((channel as DTS.DAS.Concepts.DAS.Channel.ICalSignalAware).MeasuredCalSignalMv - (channel as DTS.DAS.Concepts.DAS.Channel.ICalSignalAware).TargetCalSignalMv) / (channel as DTS.DAS.Concepts.DAS.Channel.ICalSignalAware).TargetCalSignalMv).ToString("F1"); })
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,69 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableTargetShuntDeflectionAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel
{
/// <summary>
/// A reviewable target shunt deflection attribute attached to a specific channel.
/// </summary>
public class ReviewableTargetShuntDeflectionAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableTargetShuntDeflectionAttribute(Event.Module.Channel channel)
: base("Target Shunt Deflection (mV)", delegate { return (channel as DTS.DAS.Concepts.DAS.Channel.IShuntAware).TargetShuntDeflectionMv.ToString("F1"); })
{
}
}
/// <summary>
/// A reviewable target shunt deflection attribute attached to a specific channel.
/// </summary>
public class ReviewableTargetCalSignalAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableTargetCalSignalAttribute(Event.Module.Channel channel)
: base("Target Calibration Signal (mV)", delegate { return (channel as DTS.DAS.Concepts.DAS.Channel.ICalSignalAware).TargetCalSignalMv.ToString("F1"); })
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,51 @@
/*
* DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableUnitsAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.AnalogInputChannel.cs ***
public partial class AnalogInputChannel
{
/// <summary>
/// A reviewable engineering units attribute attached to a specific channel.
/// </summary>
public class ReviewableUnitsAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableUnitsAttribute(Event.Module.Channel channel)
: base("Units", delegate { return (channel as DTS.DAS.Concepts.DAS.Channel.IEngineeringUnitAware).EngineeringUnits.ToString(); })
{
}
}
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,418 @@
using System;
using System.Collections.Generic;
using System.Linq;
using DTS.Common.Interface.DASFactory.Diagnostics;
using DTS.Common.SerializationPlus;
using DTS.Common.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
public partial class Channel
{
public abstract class CalculatedChannel : Channel, Common.DAS.Concepts.DAS.Channel.IEngineeringUnitAware
{
public enum Operation
{
Integral,
//DefiniteIntegral,
Derivative,
HeadInjuryCriteria,
FFT,
ImportedCSV,
Resultant,
TSR,
Scale,
Offset,
Sine,
Cosine,
}
private readonly Operation _operation;
public Operation CalculationType => _operation;
private readonly List<double> _x = new List<double>();
public double[] X => _x.ToArray();
private readonly List<double> _y = new List<double>();
public double[] Y => _y.ToArray();
private readonly XUnits _xAxis;
public XUnits XAxis => _xAxis;
public string XUnitsString
{
get
{
switch (_xAxis)
{
case XUnits.Hz: return "Hz";
case XUnits.msec: return "ms";
case XUnits.samples: return "samples";
case XUnits.sec: return "s";
default: return "N/A";
}
}
}
private string _yAxis;
public string EngineeringUnits
{
get => _yAxis;
set => _yAxis = value;
}
public override bool SupportsADC => false;
public override bool SupportsEU => true;
public override bool SupportsmV => false;
public override double ActualMaxRangeEu => _y.Max();
public override double ActualMaxRangeMv => throw new NotSupportedException();
public override double ActualMinRangeEu => _y.Min();
public override double ActualMinRangeMv => throw new NotImplementedException();
public override double DataHalfRangeValueEu => .5D * (_y.Min() + _y.Max());
public override double DataMaxEu => _y.Max();
public override double DataMinEu => _y.Min();
public override double DataRangeEu => (Math.Max(Math.Abs(_y.Min()), Math.Abs(_y.Max())));
public override short DataZeroLevelAdc => 0;
public override bool IsConfigured
{
get => true;
set => throw new NotSupportedException();
}
public override void FromDtsSerializationTestModuleChannel(Serialization.Test.Module.Channel that)
{
throw new NotSupportedException();
}
public override List<double> GetUnfilteredDataEu()
{
return new List<double>(_y);
}
/*
protected override void InitializeReviewableAttributes(List<ReviewableAttribute> reviewableAttributes)
{
switch (CalculationType)
{
case Operation.HeadInjuryCriteria:
break;
case Operation.ImportedCSV:
break;
case Operation.TSR:
break;
}
} */
public override void SetPropertyValuesFrom(DASLib.Service.DASChannel dasChannel)
{
throw new NotSupportedException();
}
public override void SetPropertyValuesFrom(IDiagnosticResult diagResults)
{
throw new NotSupportedException();
}
public override Serialization.Test.Module.Channel ToDtsSerializationTestModuleChannel(Serialization.Test.Module parentModule)
{
throw new NotSupportedException();
}
public override double SensorCapacityEU => throw new NotImplementedException();
public override List<double> GetUnfilteredDataMV()
{
throw new NotImplementedException();
}
public override double DesiredRangeEU => throw new NotImplementedException();
public enum XUnits
{
msec,
sec,
Hz,
samples
}
public CalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule
)
{
_x = new List<double>(xValues);
_y = new List<double>(yValues);
_xAxis = xAxis;
_yAxis = yAxis;
ChannelDescriptionString = name;
_operation = calcType;
Number = number;
CurrentFilter = new DefaultSaeJ211Filter(ChannelFilter.Unfiltered);
ParentModule = parentModule;
_UnfilteredDataEu = new List<double>(yValues);
DataCount = yValues.Length;
}
/// <summary>
/// Generate a <see cref="string"/> representation for this object.
/// </summary>
///
/// <returns>
/// The <see cref="string"/> representation of this object.
/// </returns>
///
public override string ToString()
{
try
{
return !string.IsNullOrEmpty(ChannelDescriptionString) ? ChannelDescriptionString : "N/A";
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting string representation", ex);
}
}
}
public class FFTCalculatedChannel : CalculatedChannel
{
private readonly double _peakFrequency;
public double PeakFrequency => _peakFrequency;
public FFTCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule,
double peakFrequency)
: base(name, xAxis, yAxis, xValues, yValues, calcType, number, parentModule)
{
_peakFrequency = peakFrequency;
}
/*
protected override void InitializeReviewableAttributes(List<ReviewableAttribute> reviewableAttributes)
{
base.InitializeReviewableAttributes(reviewableAttributes);
//try { reviewableAttributes.Add(new ReviewablePeakFrequencyAttribute(this)); }
//catch { }
}
public class ReviewablePeakFrequencyAttribute : Slice.Control.Event.Module.Channel.ReviewableAttribute
{
public ReviewablePeakFrequencyAttribute(Event.Module.Channel channel)
: base("Peak (Hz)",
delegate { return (channel as FFTCalculatedChannel).PeakFrequency.ToString("N"); }) { }
}*/
}
public class IntegralCalculatedChannel : CalculatedChannel
{
public IntegralCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule
)
: base(name, xAxis, yAxis, xValues, yValues, calcType, number, parentModule)
{ }
}
public class DerivativeCalculatedChannel : CalculatedChannel
{
public DerivativeCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule
)
: base(name, xAxis, yAxis, xValues, yValues, calcType, number, parentModule)
{ }
}
public class ScaleCalculatedChannel : CalculatedChannel
{
public ScaleCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule)
: base(name, xAxis, yAxis, xValues, yValues, calcType, number, parentModule)
{ }
}
public class OffsetCalculatedChannel : CalculatedChannel
{
public OffsetCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yVAlues,
Operation calcType,
int number,
Module parentModule)
: base(name, xAxis, yAxis, xValues, yVAlues, calcType, number, parentModule)
{ }
}
public class ResultantCalculatedChannel : CalculatedChannel
{
public ResultantCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule)
: base(name, xAxis, yAxis, xValues, yValues, calcType, number, parentModule)
{ }
}
public class AdditiveVectorCalculatedChannel : CalculatedChannel
{
public AdditiveVectorCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule)
: base(name, xAxis, yAxis, xValues, yValues, calcType, number, parentModule)
{ }
}
public class SineCalculatedChannel : CalculatedChannel
{
public SineCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule
)
: base(name, xAxis, yAxis, xValues, yValues, calcType, number, parentModule)
{ }
}
public class CosineCalculatedChannel : CalculatedChannel
{
public CosineCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule
)
: base(name, xAxis, yAxis, xValues, yValues, calcType, number, parentModule)
{ }
}
/*
public class HICCalculatedChannel : CalculatedChannel
{
public double GetT1(bool ms)
{
double start = (double)HIC.StartSample - (double)ParentModule.TriggerSampleNumbers[0] +
(double)ParentModule.StartRecordSampleNumber;
start /= (double)ParentModule.SampleRateHz;
if (ms) { start *= 1000; }
return start;
}
public double GetT2(bool ms)
{
double end = (double)HIC.EndSample - (double)ParentModule.TriggerSampleNumbers[0]
+ (double)ParentModule.StartRecordSampleNumber;
end /= (double)ParentModule.SampleRateHz;
if (ms) { end *= 1000; }
return end;
}
public HICCalculatedChannel(string name,
XUnits xAxis,
string yAxis,
double[] xValues,
double[] yValues,
Operation calcType,
int number,
Module parentModule,
DTS.Calculations.HeadInjuryCriterion.HICResult hic
)
: base(name, xAxis, yAxis, xValues, yValues, calcType, number, parentModule)
{
_hic = hic;
}
private DTS.Calculations.HeadInjuryCriterion.HICResult _hic;
public DTS.Calculations.HeadInjuryCriterion.HICResult HIC { get { return _hic; } }
protected override void InitializeReviewableAttributes(List<ReviewableAttribute> reviewableAttributes)
{
base.InitializeReviewableAttributes(reviewableAttributes);
try { reviewableAttributes.Add(new ReviewableHICAttribute(this)); }
catch {}
try { reviewableAttributes.Add(new ReviewableHICLengthAttribute(this)); }
catch { }
try { reviewableAttributes.Add(new ReviewableHICT1T2Attribute(this)); }
catch { }
}
public class ReviewableHICLengthAttribute : Slice.Control.Event.Module.Channel.ReviewableAttribute
{
public ReviewableHICLengthAttribute(Event.Module.Channel channel)
: base("Clip Length",
delegate { return (channel as HICCalculatedChannel).HIC.HicLengthMS.ToString(); }) { }
}
public class ReviewableHICAttribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableHICAttribute(Event.Module.Channel channel)
: base("HIC",
delegate { return (channel as HICCalculatedChannel).HIC.HIC.ToString("N1"); })
{
}
}
public class ReviewableHICT1T2Attribute
: Slice.Control.Event.Module.Channel.ReviewableAttribute
{
public ReviewableHICT1T2Attribute(Event.Module.Channel channel)
: base("T1/T2",
delegate
{
HICCalculatedChannel hic = channel as HICCalculatedChannel;
if (null == hic) { return ""; }
else { return string.Format("{0}s/{1}s", hic.GetT1(false), hic.GetT2(false)); }
})
{
}
}
}
* */
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,84 @@
/*
* DTS.Slice.Control.Event.Module.Channel.DataValues.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using DTS.Common.Utilities;
using DTS.Common.Utilities.DotNetProgrammingConstructs;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.Channel.cs ***
public partial class Channel
{
/// <summary>
/// Representation of a channel's data.
/// </summary>
public class DataValues : Exceptional
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
public DataValues()
: this(true)
{
}
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="useMemoryMappedFile">
/// A <see cref="bool"/> determining whether or not this data class will use memory mapped files
/// to store data (necessary for data sets that exceed internal process memory limitations).
/// </param>
///
public DataValues(bool useMemoryMappedFile)
{
try
{
UseMemoryMappedFile = useMemoryMappedFile;
if (UseMemoryMappedFile)
{
}
}
catch (System.Exception ex)
{
throw new Exception("encountered problem constructing " + GetType().FullName, ex);
}
}
/// <summary>
/// Get/set the switch that will cause this class to use memory mapped files in lieu
/// of in-memory list.
/// </summary>
public bool UseMemoryMappedFile
{
get => _UseMemoryMappedFile.Value;
set => _UseMemoryMappedFile.Value = value;
}
private readonly Property<bool> _UseMemoryMappedFile =
new Property<bool>(
typeof(DataValues).Namespace + ".UseMemoryMappedFile",
false,
false
);
}
} // *** End Event.Module.Channel ***
} // *** End Event.Module ***
} // *** End Event ***
}

View File

@@ -0,0 +1,81 @@
/*
* DTS.Slice.Control.Event.Module.Channel.ReviewableAttribute.NotApplicableException.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
// *** see DTS.Slice.Control.Event.Module.Channel.cs ***
public partial class Channel
{
// *** see DTS.Slice.Control.Event.Module.Channel.ReviewableAttribute.cs ***
public partial class ReviewableAttribute
{
/// <summary>
/// Representation of an attempt to use a channel attribute that is not
/// applicable to the associated channel.
/// </summary>
public class NotApplicableException : ApplicationException
{ ///
/// <summary>
/// Initialize an instance of the NotApplicableException class.
/// </summary>
///
public NotApplicableException()
{
}
/// <summary>
/// Initialize an instance of the NotApplicableException class.
/// </summary>
///
/// <param name="msg">
/// The <see cref="string"/> message to be associated with this exception.
/// </param>
///
public NotApplicableException(string msg)
: base(msg)
{
}
/// <summary>
/// Initialize an instance of the NotApplicableException class.
/// </summary>
///
/// <param name="msg">
/// The <see cref="string"/> message to be associated with this exception.
/// </param>
///
/// <param name="innerEx">
/// The <see cref="System.Exception"/> responsible for this exception inception.
/// </param>
///
public NotApplicableException(string msg, System.Exception innerEx)
: base(msg, innerEx)
{
}
}
} // *** end ReviewableAttribute ***
} // *** end Channel ***
} // *** end Module ***
} // *** end Event ***
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,74 @@
/*
* DTS.Slice.Control.Event.Module.ReviewableAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
/// <summary>
/// A reviewable attribute attached to a specific channel.
/// </summary>
abstract public partial class ReviewableAttribute
: Slice.Control.ReviewableAttribute
{
/// <summary>
/// The concrete class should implement this constructor.
/// </summary>
///
/// <param name="channel">
/// The <see cref="DTS.Slice.Control.Event.Module"/> to which a specific instance
/// of this reviewable attribute class is attached. It should be used by this class' subclass'
/// DetermineAttributeValueString method.
/// </param>
///
public ReviewableAttribute(Event.Module channel)
: this(null, null)
{
try
{
throw new NotImplementedException("cannot initialize " + this.GetType().FullName + " with this constructor; must call parameterized version");
}
catch (System.Exception ex)
{
throw new Module.ReviewableAttribute.Exception("encountered problem constructing " + this.GetType().FullName, ex);
}
}
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="name">
/// The <see cref="string"/> name of the attribute represented by this class.
/// </param>
///
/// <param name="calculateValue">
/// The <see cref="DTS.Slice.Control.ReviewableAttribute.DetermineValueString"/>
/// </param>
///
protected ReviewableAttribute(string name, DetermineValueString calculateValue)
: base(name, calculateValue)
{
}
}
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,46 @@
/*
* DTS.Slice.Control.Event.Module.ReviewableDasSerialNumberAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DTS.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module
{
/// <summary>
/// A reviewable filter frequency attribute attached to a specific channel.
/// </summary>
public class ReviewableDasSerialNumberAttribute
: Slice.Control.Event.Module.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module"/> to which this attribute is attached.
/// </param>
///
public ReviewableDasSerialNumberAttribute(Event.Module module)
: base("DAS Serial Number", delegate { return module.DasSerialNumber; })
{
}
}
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,81 @@
/*
* DTS.Slice.Control.Event.Module.ReviewableSampleRateAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DTS.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event {
// *** see DTS.Slice.Control.Event.Module.cs ***
public partial class Module {
/// <summary>
/// A reviewable filter frequency attribute attached to a specific channel.
/// </summary>
public class ReviewableSampleRateAttribute
: Slice.Control.Event.Module.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module"/> to which this attribute is attached.
/// </param>
///
public ReviewableSampleRateAttribute(Event.Module module)
: base("Sample Rate", delegate { return module.SampleRateHz.ToString("N"); })
{
}
}
/// <summary>
/// A reviewable filter frequency attribute attached to a specific channel.
/// </summary>
public class ReviewableTestDescriptionAttribute
: Slice.Control.Event.Module.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module"/> to which this attribute is attached.
/// </param>
///
public ReviewableTestDescriptionAttribute(Event.Module module)
: base("Test Description", delegate { return module.ParentEvent.Description; })
{
}
}
public class ReviewableHardwareFrequencyAttribute
: Slice.Control.Event.Module.ReviewableAttribute
{
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="channel">
/// The <see cref="Event.Module.Channel"/> to which this attribute is attached.
/// </param>
///
public ReviewableHardwareFrequencyAttribute(Event.Module module)
: base("HW AAF", delegate { return module.AaFilterRateHz.ToString("N2"); })
{
}
}
} // *** end Module ***
} // *** end Event ***
}

View File

@@ -0,0 +1,27 @@
/*
* DTS.Slice.Control.Event.ModuleChannelAccessor.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using DTS.Common.Utilities;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.Event.cs ***
public partial class Event
{
/// <summary>
/// A component object of the Event.DasModuleChannelAccessor.
/// </summary>
public class ModuleChannelAccessor : ExceptionalDictionary<int, ChannelAccessor> // xxx change this int to DAS.Module.Id?
{
/// <summary>
/// Initialize an instance of the DTS.Slice.Control.Event.ModuleChannelAccessor class.
/// </summary>
public ModuleChannelAccessor() { }
}
}
}

View File

@@ -0,0 +1,82 @@
/*
* DTS.Slice.Control.Event.TestInformation.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using DTS.Common.DASResource;
using DTS.Common.Utilities;
using DTS.Common.Utilities.DotNetProgrammingConstructs;
namespace DTS.Slice.Control
{
// *** see DTS.Slice.Control.DAS.Event.cs ***
public partial class Event
{
/// <summary>
/// Internal representation of DAS event test information.
/// </summary>
private sealed class TestInformation : Exceptional
{
/// <summary>
/// Get/set the <see cref="string"/> ID of the test associated with this DAS event.
/// </summary>
public string Id
{
get => _Id.Value;
set => _Id.Value = value;
}
private readonly Property<string> _Id = new Property<string>("DTS.Slice.Control.Event.TestInformation.Id", null, false);
/// <summary>
/// Get/set the <see cref="string"/> description of the test associated with this DAS event.
/// </summary>
public string Description
{
get => _Description.Value;
set => _Description.Value = value;
}
private readonly Property<string> _Description = new Property<string>("DTS.Slice.Control.Event.TestInformation.Description", null, false);
/// <summary>
/// Initialize an instance of the DTS.Slice.Control.Event.TestInformation class.
/// </summary>
public TestInformation()
{ //
// NOTE that the invocation of this constructor will leave this class'
// properties uninitialized.
} //
/// <summary>
/// Initialize an instance of the DTS.Slice.Control.Event.TestInformation class.
/// </summary>
///
/// <param name="id">
/// The <see cref="string"/> ID of the test associated with this DAS event.
/// </param>
///
/// <param name="description">
/// The <see cref="string"/> description of the test associated with this DAS event.
/// </param>
///
public TestInformation(string id, string description)
{
try
{
Id = id;
Description = description;
}
catch (System.Exception ex)
{
throw new Exception(
string.Format(
Strings.DTS_Slice_Control_Event_ConstructionFailedString, GetType().FullName),
ex);
}
}
}
}
}

View File

@@ -0,0 +1,181 @@
/*
DTS.Slice.Control.IntervalSec.cs
Copyright © 2008
Diversified Technical Systems, Inc.
All Rights Reserved
*/
using DTS.Common.Utilities;
using DTS.Common.Utilities.DotNetProgrammingConstructs;
namespace DTS.Slice.Control
{
/// <summary>
/// Get/set the begin value.
/// </summary>
public class IntervalSec : Exceptional
{
/// <summary>
/// Create an instance of the IntervalSec class.
/// </summary>
public IntervalSec()
{ //
// Note that calling the parameterless constructor will leave the begin and
// end properties "uninitialized".
} //
/// <summary>
/// Create an instance of the IntervalSec class.
/// </summary>
///
/// <param name="begin">
/// The <see cref="double"/> begin time of this interval.
/// </param>
///
/// <param name="end">
/// The <see cref="double"/> end time of this interval.
/// </param>
///
public IntervalSec(double begin, double end)
{
try
{
Begin = begin;
End = end;
}
catch (System.Exception ex)
{
throw new Exception(
"encountered problem constructing " + GetType().FullName, ex);
}
}
/// <summary>
/// Get/set the <see cref="double"/> begin time of the interval.
/// </summary>
public double Begin
{
get => _Begin.Value;
set => _Begin.Value = value;
}
private readonly Property<double> _Begin
= new Property<double>(
typeof(IntervalSec).Namespace + ".IntervalSec.Begin", 0, false);
/// <summary>
/// Get/set the <see cref="double"/> end time of the interval.
/// </summary>
public double End
{
get => _End.Value;
set => _End.Value = value;
}
private readonly Property<double> _End
= new Property<double>(
typeof(IntervalSec).Namespace + ".IntervalSec.End", 0, false);
/// <summary>
/// Method to implicitly convert this type into a DTS.Serialization.Test.IntervalSec.
/// </summary>
///
/// <param name="thisInterval">
/// The <see cref="DTS.Slice.Control.IntervalSec"/> to be converted.
/// </param>
///
/// <returns>
/// A <see cref="DTS.Serialization.Test.IntervalSec"/> equivalent to the speceified interval
/// object.
/// </returns>
///
public static implicit operator Serialization.Test.IntervalSec(IntervalSec thisInterval)
{
try
{
return new Serialization.Test.IntervalSec(thisInterval.Begin, thisInterval.End);
}
catch (System.Exception ex)
{
throw new Exception("encountered problem implicitly converting " + typeof(IntervalSec).FullName + " to " + typeof(Serialization.Test.IntervalSec).FullName, ex);
}
}
/// <summary>
/// Method to implicitly convert a DTS.Serialization.Test.IntervalSec object into this type.
/// </summary>
///
/// <param name="thatInterval">
/// The <see cref="DTS.Serialization.Test.IntervalSec"/> to be converted.
/// </param>
///
/// <returns>
/// A <see cref="DTS.Slice.Control.IntervalSec"/> equivalent to the specified interval
/// object.
/// </returns>
///
public static implicit operator IntervalSec(Serialization.Test.IntervalSec thatInterval)
{
try
{
return new IntervalSec(thatInterval.Begin, thatInterval.End);
}
catch (System.Exception ex)
{
throw new Exception("encountered problem implicitly converting " + typeof(Serialization.Test.IntervalSec).FullName + " to " + typeof(IntervalSec).FullName, ex);
}
}
/// <summary>
/// Test the specified object for equality with this object.
/// </summary>
///
/// <param name="obj">
/// The <see cref="object"/> to be tested for equality.
/// </param>
///
/// <returns>
/// <see cref="bool"/> true if the specified object has memeberwise equality with
/// this object; false otherwise.
/// </returns>
///
public override bool Equals(object obj)
{
try
{
var that = obj as IntervalSec;
return null != obj
&& Begin.Equals(that.Begin)
&& End.Equals(that.End);
}
catch (System.Exception ex)
{
throw new Exception("encountered problem equality-testing the object " + (null != obj ? "\"" + obj.ToString() + "\"" : "<<NULL>>"), ex);
}
}
/// <summary>
/// Get has code for this object.
/// </summary>
///
/// <returns>
/// The <see cref="int"/> hash code for this object.
/// </returns>
///
public override int GetHashCode()
{
try
{
return base.GetHashCode();
}
catch (System.Exception ex)
{
throw new Exception("encountered problem generating hash code for " + GetType().FullName, ex);
}
}
}
}

View File

@@ -0,0 +1,118 @@
/*
* DTS.Slice.Control.ReviewableAttribute.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DTS.Utilities;
using DTS.Utilities.DotNetProgrammingConstructs;
namespace DTS.Slice.Control
{
/// <summary>
/// Representation of a "reviewable" attribute.
/// </summary>
abstract public class ReviewableAttribute : Exceptional
{ ///
/// <summary>
/// Initialize an instance of the ReviewableAttribute class.
/// </summary>
///
/// <param name="name">
/// The <see cref="string"/> name of the attribute represented by this object.
/// </param>
///
/// <param name="value">
/// The value of the attribute represented by this object.
/// </param>
///
public ReviewableAttribute(string name, DetermineValueString calculateValue)
{
try
{
this.Name = name;
this.CalculateValue = calculateValue;
}
catch (System.Exception ex)
{
throw new ReviewableAttribute.Exception("encountered problem constructing " + this.GetType().FullName, ex);
}
}
/// <summary>
/// The <see cref="string"/> name associated with this review tab-displayable attribute.
/// </summary>
public string Name
{
get { return _Name.Value; }
private set { _Name.Value = value; }
}
private Property<string> _Name
= new Property<string>(
typeof(ReviewableAttribute).Namespace + ".ReviewableAttribute.Name",
null,
false
);
/// <summary>
/// Get the value <see cref="string"/> for this attribute.
/// </summary>
public string Value
{
get
{
try
{
return CalculateValue();
}
catch (System.Exception ex)
{
Utilities.Logging.APILogger.Log("encountered problem getting ReviewableAttribute value", ex);
return "N/A";
//throw new ReviewableAttribute.Exception( "encountered problem getting ReviewableAttribute value", ex );
}
}
}
// Need to attach the list of attribute "accessors" to the channel in a similar way
// we do with filters. Have an "available" list. And then an "active" list.
public delegate string DetermineValueString();
/// <summary>
/// Determine the value associated with this review tab-displayable attribute.
/// </summary>
private DetermineValueString CalculateValue
{
get
{
try
{
if (!_CalculateValueIsInitialized)
throw new ApplicationException("method property \"CalculateValue\" has not been initialized");
else return _CalculateValue;
}
catch (System.Exception ex)
{
throw new ReviewableAttribute.Exception("encountered problem getting property value", ex);
}
}
set
{
_CalculateValue = value;
_CalculateValueIsInitialized = true;
}
}
private DetermineValueString _CalculateValue;
private bool _CalculateValueIsInitialized = false;
}
}

View File

@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{B9D1AC5B-7A6F-4B14-9FF8-3A1FC03519E2}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DTS.Common.SerializationPlus</RootNamespace>
<AssemblyName>DTS.Common.SerializationPlus</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="DocumentFormat.OpenXml, Version=2.5.5631.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>C:\Program Files (x86)\Open XML SDK\V2.5\lib\DocumentFormat.OpenXml.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="Filter\IFilter.cs" />
<Compile Include="Filter\IFilterable.cs" />
<Compile Include="Control\Event\ChannelAccessor.cs" />
<Compile Include="Control\Event\DasChannelAccessor.cs" />
<Compile Include="Control\Event\DasModuleAccessor.cs" />
<Compile Include="Control\Event\DasModuleChannelAccessor.cs" />
<Compile Include="Control\Event\Event.cs" />
<Compile Include="Control\Event\ModuleChannelAccessor.cs" />
<Compile Include="Control\Event\Module\AnalogInputChannel\AnalogInputChannel.cs" />
<Compile Include="Control\Event\Module\Channel\CalculatedChannel.cs" />
<Compile Include="Control\Event\Module\Channel\Channel.cs" />
<Compile Include="Filter\ChannelDefaultSaeJ211Filter.cs" />
<Compile Include="Control\Event\Module\Channel\DataValues.cs" />
<Compile Include="Filter\Filter.cs" />
<Compile Include="Filter\SaeJ211Filter.cs" />
<Compile Include="Control\Event\Module\Module.cs" />
<Compile Include="Control\Event\TestInformation.cs" />
<Compile Include="Control\IntervalSec.cs" />
<Compile Include="EventInfoAggregate.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="XLSX\Excel.File.cs" />
<Compile Include="XLSX\Excel.File.Writer.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Common\DTS.Common.DAS.Concepts\DTS.Common.DAS.Concepts.csproj">
<Project>{03d8c736-36eb-4cd1-a6d9-130452b23239}</Project>
<Name>DTS.Common.DAS.Concepts</Name>
</ProjectReference>
<ProjectReference Include="..\..\Common\DTS.Common.DASResource\DTS.Common.DASResource.csproj">
<Project>{23c0fb0c-35d9-4a4d-a1a1-0deb5c217106}</Project>
<Name>DTS.Common.DASResource</Name>
</ProjectReference>
<ProjectReference Include="..\..\Common\DTS.Common.Serialization\DTS.Common.Serialization.csproj">
<Project>{b7d50b14-fa61-4fe4-bff7-b257902b55b0}</Project>
<Name>DTS.Common.Serialization</Name>
</ProjectReference>
<ProjectReference Include="..\..\Common\DTS.Common.Utilities\DTS.Common.Utilities.csproj">
<Project>{03eace47-ea59-44ac-b49d-956e4dc4d618}</Project>
<Name>DTS.Common.Utilities</Name>
</ProjectReference>
<ProjectReference Include="..\..\DataPRO\IService\IService.csproj">
<Project>{c9c45b72-05a3-4962-bc13-a78b1f4b1925}</Project>
<Name>IService</Name>
</ProjectReference>
<ProjectReference Include="..\DTS.Common\DTS.Common.csproj">
<Project>{114EDC77-F3B5-4576-A91B-40818D503B55}</Project>
<Name>DTS.Common</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Design\DTS.Common.SerialzationPlusClassDiagram.cd" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<ClassDiagram MajorVersion="1" MinorVersion="1">
<Class Name="DTS.Slice.Control.Event" Collapsed="true" BaseTypeListCollapsed="true">
<Position X="3" Y="0.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAiBEBA0AIoiAQsoAgAgAAQLBEEBIDUCCAAQBAEQhA=</HashCode>
<FileName>Control\Event\ChannelAccessor.cs</FileName>
</TypeIdentifier>
<Lollipop Position="0.2" Collapsed="true" />
</Class>
<Class Name="DTS.Slice.Control.IntervalSec" Collapsed="true">
<Position X="4.75" Y="1.5" Width="1.5" />
<TypeIdentifier>
<HashCode>CAIAAAAAAAAAAAAAgBAAAAAAAAAAEIBAAAAAAAAQAAA=</HashCode>
<FileName>Control\IntervalSec.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="DTS.Common.SerializationPlus.EventInfoAggregate" Collapsed="true">
<Position X="4.75" Y="0.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAJAAEQgAAAAAgAIAEAAAAgAAAAgQAAAQABAAIAACgg=</HashCode>
<FileName>EventInfoAggregate.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="DTS.Common.SerializationPlus.DefaultSaeJ211Filter" Collapsed="true">
<Position X="0.5" Y="3.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAAAEAAAAAIQAAAAAAAAAAAAAAAAAAAA=</HashCode>
<FileName>Filter\ChannelDefaultSaeJ211Filter.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="DTS.Common.SerializationPlus.Filter" Collapsed="true">
<Position X="0.5" Y="0.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAABAAIAAAAAAAAIUAAAAAAAAAAQAAACAAAAA=</HashCode>
<FileName>Filter\Filter.cs</FileName>
</TypeIdentifier>
<Lollipop Position="0.2" />
</Class>
<Class Name="DTS.Common.SerializationPlus.SaeJ211Filter" Collapsed="true">
<Position X="0.5" Y="2" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAgIAAAgBAAIAAEgAABgIUAAAAAAIAAAQAABCAAIAA=</HashCode>
<FileName>Filter\SaeJ211Filter.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="DTS.Serialization.XLSX.File" Collapsed="true" BaseTypeListCollapsed="true">
<Position X="3" Y="1.5" Width="1.5" />
<TypeIdentifier>
<HashCode>IAAAAAAAAAAAAAEIAAAAAAAQAAAAAAAAAAAAAAIAAAA=</HashCode>
<FileName>XLSX\Excel.File.cs</FileName>
</TypeIdentifier>
<Lollipop Position="0.2" Collapsed="true" />
</Class>
<Interface Name="DTS.Common.SerializationPlus.IFilter" Collapsed="true">
<Position X="3" Y="2.75" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAABAAIAAAAAAAAIUAAAAAAAAAAQAAACAAAAA=</HashCode>
<FileName>Filter\IFilter.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="DTS.Common.SerializationPlus.IFilterable" Collapsed="true">
<Position X="4.75" Y="2.75" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAQAAAAAAACAgAAAAAAAAQAAAAAAAAAAAAA=</HashCode>
<FileName>Filter\IFilterable.cs</FileName>
</TypeIdentifier>
</Interface>
<Font Name="Segoe UI" Size="9" />
</ClassDiagram>

View File

@@ -0,0 +1,162 @@
using System;
using System.Collections.Generic;
using System.Linq;
using DTS.Common.Interface.DASFactory;
using DTS.Common.Interface.DASFactory.Download;
using DTS.Common.Utilities.Logging;
using DTS.DASLib.Service;
namespace DTS.Common.SerializationPlus
{
public class EventInfoAggregate : IEventInfoAggregate
{
public string EventId { get; set; }
public string EventDescription { get; set; }
public double DurationSeconds { get; set; }
public string GUID { get; set; }
public bool HasBeenDownloaded { get; set; }
public bool WasTriggered { get; set; }
public int NumberOfChannels { get; set; }
public ulong NumberOfSamples { get; set; }
public ulong NumberOfBytes { get; set; }
public bool Faulted { get; set; }
public int EventNumber { get; set; }
private readonly Dictionary<IDASCommunication, int> _eventIndices = new Dictionary<IDASCommunication, int>();
private List<IDASCommunication> _das = null;
private Slice.Control.Event _event;
public Slice.Control.Event GetEvent(bool bClear)
{
if (bClear) { _event = null; }
return GetEvent();
}
public Slice.Control.Event GetEvent()
{
if (null == _event)
{
_event = new Slice.Control.Event(GetDasList(), this);
}
return _event;
}
public int GetEventIndex(IDASCommunication idas)
{
if (!_eventIndices.ContainsKey(idas))
{
APILogger.Log(string.Format("ERROR in GetEventIndex for {0}", idas.SerialNumber));
return -1;
}
return _eventIndices[idas];
}
public List<IDASCommunication> GetDasList()
{
if (null == _das)
{
_das = new List<IDASCommunication>();
_das.AddRange(_eventIndices.Keys.ToArray());
}
return _das;
}
public EventInfoAggregate(DownloadReport.EventInfo newEvent)
{
EventId = newEvent.TestID;
EventDescription = newEvent.Description;
//if newEvent doesn't have modules this will throw an exception, we don't want that
//so populate the event here with no samples, no duration
//I discovered this issue while working on
//15575 No notification if unplug comm cable during downloading on G5
//if units do come back after disconnecting in the download step their module information may not be populated
//and would previously crash
if (newEvent.Modules.Any())
{
DurationSeconds = newEvent.Modules[0].PreTriggerSeconds + newEvent.Modules[0].PostTriggerSeconds;
}
else
{
DurationSeconds = 0;
}
GUID = newEvent.TestGUID.ToString();
HasBeenDownloaded = newEvent.HasBeenDownloaded;
WasTriggered = newEvent.WasTriggered;
NumberOfChannels = newEvent.Modules.Sum(s => s.Channels.Length);
if (newEvent.Modules.Any())
{
NumberOfSamples = newEvent.Modules[0].NumberOfSamples;
}
else
{
NumberOfSamples = 0;
}
NumberOfBytes = NumberOfSamples * (ulong)NumberOfChannels * 2;
Faulted = IsFaulted(newEvent);
EventNumber = newEvent.EventNumber;
if (newEvent.Modules.Any())
{
_eventIndices.Add(((DASModule)newEvent.Modules[0]).OwningDAS, newEvent.EventNumber);
}
}
/// <summary>
/// returns true if faulted
/// </summary>
private bool IsFaulted(IEventInfo info)
{
return 0 != info.FaultFlags || 0 != info.FaultFlagsEx;
}
public void Add(IEventInfo newEvent)
{
if (newEvent.TestID != EventId)
{
APILogger.Log("Warning, expected matching test ids: ", newEvent.TestID, EventId);
}
if (newEvent.Description != EventDescription)
{
APILogger.Log("Warning, expected matching test descriptions: ", newEvent.Description);
}
var duration = newEvent.Modules[0].PreTriggerSeconds + newEvent.Modules[0].PostTriggerSeconds;
if (duration != DurationSeconds)
{
APILogger.Log("Warning, durations don't match: ", duration, DurationSeconds);
DurationSeconds = Math.Min(DurationSeconds, duration);
}
if (newEvent.TestGUID.ToString() != GUID)
{
APILogger.Log("Warning, expected test GUIDs to match,", GUID, newEvent.TestGUID.ToString());
}
if (newEvent.HasBeenDownloaded != HasBeenDownloaded)
{
APILogger.Log("Warning, event has been downloaded from one unit, but not another");
}
if (newEvent.WasTriggered != WasTriggered)
{
APILogger.Log("Warning, one unit has triggered, but another has not");
}
var faulted = IsFaulted(newEvent);
Faulted = Faulted || faulted;
if (newEvent.Modules[0].NumberOfSamples != NumberOfSamples)
{
APILogger.Log("Warning, expected number of samples to match", NumberOfSamples, newEvent.Modules[0].NumberOfSamples);
NumberOfSamples = Math.Min(NumberOfSamples, newEvent.Modules[0].NumberOfSamples);
}
if (newEvent.EventNumber != EventNumber)
{
APILogger.Log("Warning, expected event numbers to match", EventNumber, newEvent.EventNumber);
}
NumberOfChannels += newEvent.Modules.Sum(s => s.Channels.Length);
NumberOfBytes = 2 * (ulong)NumberOfChannels * NumberOfSamples;
//rather than using .Add we should use index assignment in case there are duplicate keys
//I've eliminated the duplicate key that happened because of
//http://manuscript.dts.local/f/cases/44357/TSR-AIR-GO-given-UDP-auto-discovery-is-disabled-manually-entered-ip-address-failed-matching-the-DAS-and-can-t-ARM
//but this is better practice
_eventIndices[((DASModule)newEvent.Modules[0]).OwningDAS] = newEvent.EventNumber;
}
}
}

View File

@@ -0,0 +1,114 @@
/*
* DTS.Slice.Control.Event.Module.Channel.SaeJ211Filter.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using DTS.Common.Utilities;
namespace DTS.Common.SerializationPlus
{
/// <summary>
/// Base class for all SaeJ211-based event module channel filters. It is intended
/// that fixed-filter-setting filters be derived from this class that will set their
/// filter setting using the protected constructor.
/// </summary>
public class DefaultSaeJ211Filter
: SaeJ211Filter
{
public DefaultSaeJ211Filter(SaeJ211Filter filter)
: base(filter)
{
}
/// <summary>
/// Initialize an instance of the DefaultSaeJ211Filter class.
/// </summary>
///
/// <param name="filterType">
/// The <see cref="ChannelFilter"/> to be applied by this filter.
/// </param>
///
public DefaultSaeJ211Filter(ChannelFilter filterType)
: base(filterType)
{
}
/// <summary>
/// Initialize an instance of the DefaultSaeJ211Filter class.
/// </summary>
///
///<param name="adHocFrequency">
///The <see cref="double"/> ad hoc frequency of this filter.
/// </param>
///
public DefaultSaeJ211Filter(double adHocFrequency)
: base(adHocFrequency)
{
}
/// <summary>
/// The <see cref="string"/> name of this filter.
/// </summary>
public override string Name
{
get
{
try
{
return "Default (" + base.Name + ")";
}
catch (System.Exception ex)
{
throw new Exception("encountered problem generating name string for " + GetType().FullName, ex);
}
}
}
/// <summary>
/// Generate a string representation of this object.
/// </summary>
///
/// <returns>
/// A <see cref="string"/> representation of this object.
/// </returns>
///
public override string ToBaseString()
{
try
{
return base.Name;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem generating the string value for " + GetType().FullName, ex);
}
}
/// <summary>
/// Generate a string representation of this object.
/// </summary>
///
/// <returns>
/// A <see cref="string"/> representation of this object.
/// </returns>
///
public override string ToString()
{
try
{
return Name;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem generating the string value for " + GetType().FullName, ex);
}
}
}
}

View File

@@ -0,0 +1,90 @@
/*
* DTS.Slice.Control.Event.Module.Channel.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using DTS.Common.Utilities;
namespace DTS.Common.SerializationPlus
{
/// <summary>
/// A filter for DTS.Slice.Control.Event.Module.Channels.
/// </summary>
public abstract class Filter
: Exceptional,
IFilter
{
/// <summary>
/// A descriptive <see cref="string"/> designation for the filter.
/// </summary>
public abstract string Name
{
get;
}
/// <summary>
/// Get the <see cref="bool"/> value indicating whether or not this filter
/// corresponds to a CFC value.
/// </summary>
public abstract bool IsCfc
{
get;
}
/// <summary>
/// Get a <see cref="ChannelFilter"/> designation for this filter.
/// </summary>
public abstract ChannelFilter Type
{
get;
}
public abstract char IsoDescription { get; }
/// <summary>
/// Get the <see cref="double"/> cutoff frequency for this filter.
/// </summary>
public abstract double CutoffFrequencyHz
{
get;
}
/// <summary>
/// Apply the filter to the specified input.
/// </summary>
///
/// <param name="input">
/// The input to the filter.
/// </param>
///
/// <param name="displayUnits">
/// The <see cref="DTS.Slice.Control.Event.Module.Channel.DataDisplayUnits"/> to be
/// filtered from the channel.
/// </param>
/// <param name="bUseLegacyTDCSoftwareFilterAdjustment">
/// controls whether filtered data is adjusted by one sample to match TDC behavior
/// 8747
/// </param>
/// <returns>
/// The filtering of the input.
/// </returns>
///
public abstract double[] Apply(
DTS.Slice.Control.Event.Module.Channel input,
Slice.Control.Event.Module.Channel.DataDisplayUnits displayUnits,
bool bUseLegacyTDCSoftwareFilterAdjustment);
public abstract double[] Apply(
double[] data,
double sampleRate,
bool bUseLegacyTDCSoftwareFilterAdjustment);
/// <summary>
/// the ToString is already overloaded, but we sometimes need the base name, not the decorated name that
/// is returned in ToString.
/// </summary>
/// <returns></returns>
public abstract string ToBaseString();
}
}

View File

@@ -0,0 +1,89 @@
/*
* DTS.Slice.Control.DAS.Channel.IFilter.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using DTS.Common.Utilities;
using DTS.Slice.Control;
namespace DTS.Common.SerializationPlus
{
/// <summary>
/// Methodical definition of a slice control event module channel filter.
/// </summary>
public interface IFilter
{
/// <summary>
/// A descriptive <see cref="string"/> designation for the filter.
/// </summary>
string Name
{
get;
}
/// <summary>
/// value indicating whether or not this filter is
/// a cardinal CFC value.
/// </summary>
bool IsCfc
{
get;
}
/// <summary>
/// Get a <see cref="ChannelFilter"/> designation for this filter.
/// </summary>
ChannelFilter Type
{
get;
}
/// <summary>
/// Get the <see cref="double"/> cutoff frequency for this filter.
/// </summary>
double CutoffFrequencyHz
{
get;
}
char IsoDescription { get; }
/// <summary>
/// Apply the filter to the specified input.
/// </summary>
///
/// <param name="input">
/// The input to the filter.
/// </param>
///
/// <param name="displayUnits">
/// The <see cref="Event.Module.Channel.DataDisplayUnits"/> to be
/// filtered from the channel.
/// </param>
/// <param name="bUseLegacyTDCSofwareFilterAdjustment">
/// when true will adjust data one sample to the right to preserve existing TDC filtering behavior
/// </param>
/// <returns>
/// The filtering of the input.
/// </returns>
///
double[] Apply(
Event.Module.Channel input,
Event.Module.Channel.DataDisplayUnits displayUnits,
bool bUseLegacyTDCSofwareFilterAdjustment);
double[] Apply(
double[] data,
double sampleRate,
bool bUseLegacyTDCSoftwareFilterAdjustment
);
/// <summary>
/// the ToString is already overloaded, but we sometimes need the base name, not the decorated name that
/// is returned in ToString.
/// </summary>
/// <returns></returns>
string ToBaseString();
}
}

View File

@@ -0,0 +1,64 @@
/*
* DTS.Slice.Control.DAS.Channel.IFilterable.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System.Collections.Generic;
using DTS.Slice.Control;
namespace DTS.Common.SerializationPlus
{
/// <summary>
/// Methodical definition of a filterable slice control event module channle.
/// </summary>
public interface IFilterable
//: DTS.Common.DAS.ConceptsIFilterable<Event.Module.Channel, short[]>
{
/// <summary>
/// Get/set the <see cref="bool"/> switch to (de)activate filter caching.
/// </summary>
bool UseFilterCaching
{
get;
set;
}
/// <summary>
/// Get the list of available filters for this object.
/// </summary>
List<IFilter> AvailableFilters
{
get;
}
/// <summary>
/// The currently applied filter.
/// </summary>
IFilter CurrentFilter
{
get;
set;
}
/// <summary>
/// Get the specified filtering for this object.
/// </summary>
///
/// <param name="filter">
/// The <see cref="DTS.Slice.Control.CAS.Channel.IFilter"/> to be applied to this object.
/// </param>
///
/// <param name="displayUnits">
/// Choose the output <see cref="DTS.Slice.Control.DAS.Channel.Data.DisplayUnits"/>.
/// </param>
///
/// <returns>
/// An array of <see cref="double"/> data reflecting the specified parameters.
/// </returns>
///
double[] GetDataFilteredBy(IFilter filter, Event.Module.Channel.DataDisplayUnits displayUnits);
}
}

View File

@@ -0,0 +1,522 @@
/*
* DTS.Slice.Control.Event.Module.Channel.SaeJ211Filter.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using DTS.Common.DAS.Concepts.DAS.Channel;
using DTS.Common.Utilities;
using DTS.Common.Utilities.DotNetProgrammingConstructs;
using DTS.Common.Utilities.Logging;
using DTS.Common.Utilities.SaeJ211;
namespace DTS.Common.SerializationPlus
{
/// <summary>
/// Base class for all SaeJ211-based event module channel filters. It is intended
/// that fixed-filter-setting filters be derived from this class that will set their
/// filter setting using the protected constructor.
/// </summary>
public class SaeJ211Filter
: Filter
{
public SaeJ211Filter(SaeJ211Filter originalFilter)
{
OriginalType = originalFilter.OriginalType;
_cutoffFrequencyHz.Value = originalFilter.CutoffFrequencyHz;
}
/// <summary>
/// Initialize an instance of the DTS.Utility.SaeJ211Filter class.
/// </summary>
///
/// <param name="originalType">
/// The <see cref="ChannelFilter"/> to be applied by this filter (ad hoc
/// filters that correspond to CFC values will be converted to the CFC, hence the
/// "original" qualification).
/// </param>
///
public SaeJ211Filter(ChannelFilter originalType)
{
try
{
switch (OriginalType = originalType)
{
//
// Try to set the frequency value according to type. Note that we can't set to
// "ad hoc" using this particular constructor as we don't know what frequency
// should be associated with it.
//
case ChannelFilter.AdHoc:
throw new Exception("cannot initialize SaeJ211 filter using only ChannelFilter of type " +
OriginalType.ToString());
default:
_cutoffFrequencyHz.Value = (double)originalType;
break;
}
}
catch (System.Exception ex)
{
throw new Exception("encountered problem constructing " + GetType().FullName, ex);
}
}
/// <summary>
/// Initialize an instance of the DTS.Utility.SaeJ211Filter class.
/// </summary>
///
/// <param name="cutoffFrequencyHz"></param>
public SaeJ211Filter(double cutoffFrequencyHz)
{
try
{
OriginalType = ChannelFilter.AdHoc;
_cutoffFrequencyHz.Value = cutoffFrequencyHz;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem constructing " + GetType().FullName, ex);
}
}
/// <summary>
/// Get <see cref="Boolean"/> value indicating whether or not this filter matches one of the
/// specified CFC values.
/// </summary>
public override bool IsCfc
{
get
{
try
{
//
// If we're not unfiltered and we're not ad hoc, then we
// must be CFC-compliant.
//
return Type != ChannelFilter.Unfiltered && Type != ChannelFilter.UnfilteredZero
&& Type != ChannelFilter.AdHoc;
}
catch (System.Exception ex)
{
throw new Exception(
"encountered problem determining whether or not filter corresponds to a CFC value", ex);
}
}
}
/// <summary>
/// Convert the specified frequency into a ChannelFilter type.
/// </summary>
///
/// <param name="frequency">
/// The <see cref="double"/> frequency to be converted.
/// </param>
///
/// <returns>
/// The best matching <see cref="ChannelFilter"/> type. A CFC match is preferred;
/// if one does not exist, "ad hoc" will be selected (if frequency > 0).
/// </returns>
///
private static ChannelFilter ConvertFrequencyToChannelFilter(double frequency)
{
try
{
var matchingFilterType = ChannelFilter.Unfiltered;
if (!(frequency > 0)) return matchingFilterType;
matchingFilterType = ChannelFilter.AdHoc;
foreach (int filterValue in Enum.GetValues(typeof(ChannelFilter)))
{
if (frequency == filterValue)
{
matchingFilterType = (ChannelFilter)filterValue;
}
}
return matchingFilterType;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem trying to match frequency to CRC value", ex);
}
}
/// <summary>
/// Get the "best fitting" <see cref="ChannelFilter"/> value for this filter.
/// </summary>
public override ChannelFilter Type
{
get
{
try
{
ChannelFilter actualType;
switch (OriginalType)
{
case ChannelFilter.AdHoc:
actualType = ConvertFrequencyToChannelFilter(CutoffFrequencyHz);
break;
default:
//
// Don't waste time on stuff we don't need to convert.
//
actualType = OriginalType;
break;
}
return actualType;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem determining filter type", ex);
}
}
}
public override char IsoDescription => new IsoDescriptionAttributeCoder().DecodeAttributeValue(Type)[0];
/// <summary>
/// Get the <see cref="double"/> cutoff frequency value.
/// </summary>
public override double CutoffFrequencyHz => _cutoffFrequencyHz.Value;
private readonly Property<double> _cutoffFrequencyHz
= new Property<double>(
typeof(SaeJ211Filter).Namespace + ".SaeJ211Filter.CutoffFrequencyHz",
-1,
true
);
/// <summary>
/// The <see cref="ChannelFilter"/>ing done by this object.
/// </summary>
public ChannelFilter OriginalType
{
get => _originalType.Value;
private set => _originalType.Value = value;
}
private readonly Property<ChannelFilter> _originalType
= new Property<ChannelFilter>(
typeof(SaeJ211Filter).Namespace + ".SaeJ211Filter.OriginalType",
ChannelFilter.Unfiltered,
false
);
private const string CUTOFF_FREQUENCY_UNIT_STRING = "Hz";
/// <summary>
/// The <see cref="string"/> name of this filter.
/// </summary>
public override string Name
{
get
{
try
{
if (null != _name) return _name;
var cult = System.Globalization.CultureInfo.InvariantCulture;
_name = ChannelFilter.AdHoc == Type
? CutoffFrequencyHz.ToString(cult) + CUTOFF_FREQUENCY_UNIT_STRING
: new DescriptionAttributeCoder<ChannelFilter>().DecodeAttributeValue(Type);
return _name;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem generating name string for " + GetType().FullName, ex);
}
}
}
private string _name;
/// <summary>
/// Apply this filter to the specified channel.
/// </summary>
///
/// <param name="channel">
/// The <see cref="DTS.Slice.Control.Event.Module.Channel"/> to be filtered.
/// </param>
/// <param name="displayUnits"></param>
/// <param name="bUseLegacyTDCSoftwareFilterAdjustment"></param>
/// <returns>
/// The array of filtered <see cref="double"/> EU data.
/// </returns>
public override double[] Apply
(
DTS.Slice.Control.Event.Module.Channel channel,
Slice.Control.Event.Module.Channel.DataDisplayUnits displayUnits,
bool bUseLegacyTDCSoftwareFilterAdjustment
)
{
try
{
var filterUtility = new FilterUtility();
filterUtility.Cfc = Type;
filterUtility.AdHocFrequency = CutoffFrequencyHz;
filterUtility.SampleRate = channel.ParentModule.SampleRateHz;
double[] data;
short[] adc = null;
if (channel.UnfilteredData is Serialization.SliceRaw.File.PersistentChannel unfilteredData)
{
adc = unfilteredData.GetAllData();
}
switch (displayUnits)
{
case Slice.Control.Event.Module.Channel.DataDisplayUnits.Adc:
if (null != adc)
{
using (var persistentUnfilteredData =
channel.UnfilteredData as Serialization.SliceRaw.File.PersistentChannel) // ;
{
data = new double[adc.Length];
for (var i = 0; i < data.Length; i++)
data[i] = adc[i];
}
}
else if (channel.UnfilteredData is Serialization.TDAS.File.PersistentChannel persistentChannel)
{
if (persistentChannel is ILargeDataAware largeDataAware)
if (!largeDataAware.IsDataArraySized)
throw new Serialization.TDAS.File.PersistentChannel.DataTooBigForArrayException(
"Data is too big to be viewed or filtered.");
using (var persistentUnfilteredData =
channel.UnfilteredData as Serialization.TDAS.File.PersistentChannel) // ;
{
var dataCount = persistentUnfilteredData.Count;
data = new double[dataCount];
for (var i = 0; i < dataCount; i++)
data[i] = persistentUnfilteredData[(ulong)i];
}
}
else data = channel.UnfilteredData.ConvertAll(datum => (double)datum).ToArray();
break;
case Slice.Control.Event.Module.Channel.DataDisplayUnits.Eu:
data = channel.UnfilteredDataEu.ToArray();
break;
case Slice.Control.Event.Module.Channel.DataDisplayUnits.Mv:
data = channel.UnfilteredDataMv.ToArray();
break;
default:
throw new NotImplementedException("handling for display unit type \"" + displayUnits +
"\" has not been implemented");
}
return filterUtility.ApplyFilter(data, delegate
{
var msg = $"Invalid data in channel: {channel.ChannelDescriptionString}.";
APILogger.Log(msg);
throw new Exception(msg);
}, bUseLegacyTDCSoftwareFilterAdjustment);
}
catch (System.Exception ex)
{
throw new Exception("encountered problem applying filter \"" + Name + "\" to channel", ex);
}
}
/// <summary>
/// Apply this filter to the specified channel.
/// </summary>
///
/// <param name="channel">
/// The <see cref="DTS.Slice.Control.Event.Module.Channel"/> to be filtered.
/// </param>
/// <param name="data"></param>
/// <param name="sampleRate"></param>
/// <param name="bUseLegacyTDCSoftwareFilterAdjustment">
/// controls whether filtered data is adjusted by one sample to match TDC behavior
/// 8747
/// </param>
/// <returns>
/// The array of filtered <see cref="double"/> EU data.
/// </returns>
public override double[] Apply
(
double[] data,
double sampleRate,
bool bUseLegacyTDCSoftwareFilterAdjustment
)
{
try
{
var filterUtility = new FilterUtility();
filterUtility.Cfc = Type;
filterUtility.AdHocFrequency = CutoffFrequencyHz;
filterUtility.SampleRate = sampleRate;
return filterUtility.ApplyFilter(data, delegate
{
const string msg = "Invalid data in channel.";
APILogger.Log(msg);
throw new Exception(msg);
}, bUseLegacyTDCSoftwareFilterAdjustment);
}
catch (System.Exception ex)
{
throw new Exception("encountered problem applying filter \"" + Name + "\" to channel", ex);
}
}
/// <summary>
/// Generate a string representation of this object.
/// </summary>
///
/// <returns>
/// A <see cref="string"/> representation of this object.
/// </returns>
///
public override string ToString()
{
try
{
return Name;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem generating the string value for " + GetType().FullName, ex);
}
}
/// <summary>
/// Generate a string representation of this object.
/// </summary>
///
/// <returns>
/// A <see cref="string"/> representation of this object.
/// </returns>
///
public override string ToBaseString()
{
try
{
return Name;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem generating the string value for " + GetType().FullName, ex);
}
}
/// <summary>
/// Determines whether this filter and the specified filter are the same.
/// </summary>
///
/// <param name="obj">
/// The filter <see cref="object"/> to be compared with this one.
/// </param>
///
/// <returns>
/// <see cref="bool"/> true if the filters are the same, false otherwise.
/// </returns>
///
public override bool Equals(object obj)
{
try
{
if (!(obj is SaeJ211Filter))
{
return false;
}
return Name.Equals(((SaeJ211Filter)obj).Name, StringComparison.OrdinalIgnoreCase);
}
catch (System.Exception ex)
{
throw new Exception(
"encountered problem equality checking filter \""
+ Name
+ "\" with filter "
+ ((obj as SaeJ211Filter)?.Name != null ? "\"" + (obj as SaeJ211Filter).Name + "\"" : "<null>"),
ex);
}
}
/// <summary>
/// provides an index for a given <see cref="SaeJ211Filter"/>
/// since we override Equals we should override get hashcode to ensure that any to objects considered
/// "Equal" are also hashed to the same location, however the result index does not need to be unique
/// between non equal objects.
/// 6/10/2010 - dtm
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
return Name.ToLower().GetHashCode();
}
/// <summary>
/// Create a filter from the specified string.
/// </summary>
///
/// <param name="serialization">
/// The <see cref="string"/> representation of the filter to be instantiated.
/// </param>
///
/// <returns>
/// A <see cref="Filter"/> equivalent of the
/// specified string. Throws an exception if object could not be created.
/// </returns>
///
public static Filter Parse(string serialization)
{
try
{
Filter filter = null;
//FB 13120 remove Hz if it presents inorder to convert it to frequency
if (!serialization.Contains(CUTOFF_FREQUENCY_UNIT_STRING))
{
double freq = 0;
if (double.TryParse(serialization, out freq))
{
serialization = serialization + CUTOFF_FREQUENCY_UNIT_STRING;
}
}
if (string.IsNullOrEmpty(serialization))
return new SaeJ211Filter(ChannelFilter.Unfiltered);
if (serialization.Contains(CUTOFF_FREQUENCY_UNIT_STRING))
{
var cult = new System.Globalization.CultureInfo("");
filter = new DefaultSaeJ211Filter(
double.Parse(serialization.Replace(CUTOFF_FREQUENCY_UNIT_STRING, ""), cult));
}
else
{
foreach (ChannelFilter filterType in Enum.GetValues(typeof(ChannelFilter)))
{
var coder = new DescriptionAttributeCoder<ChannelFilter>();
if (coder.DecodeAttributeValue(filterType)
.Equals(serialization, StringComparison.OrdinalIgnoreCase))
filter = new DefaultSaeJ211Filter(filterType);
}
}
return filter ?? new SaeJ211Filter(ChannelFilter.Unfiltered);
}
catch (System.Exception ex)
{
throw new Exception(
"encountered problem parsing string " +
(null != serialization ? "\"" + serialization + "\"" : "<NULL>") + " into filter", ex);
}
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DTS.Common.SerializationPlus")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DTS.Common.SerializationPlus")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("b9d1ac5b-7a6f-4b14-9ff8-3a1fc03519e2")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,953 @@
/*
* XLSX.File.Writer.cs
*
* Copyright © 2017
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DTS.Common.Enums;
using DTS.Common.Enums.Sensors;
using DTS.Common.Interface.ExportData;
using DTS.Common.SerializationPlus;
using DTS.Common.Utilities.Logging;
using DTS.Slice.Control;
// ReSharper disable PossiblyMistakenUseOfParamsMethod
namespace DTS.Serialization.XLSX
{
public partial class File
{
/// <summary>
/// implementation of the Serialization.File.Writer class for XLSX
/// http://fogbugz/fogbugz/default.asp?9920
/// </summary>
public class Writer : Writer<File>, IWriter<Test>
{
#region properties
/// <summary>
/// the owning file that controls this writer
/// </summary>
internal File WriterParent { get; }
/// <summary>
/// controls whether to export ADC or not
/// </summary>
public bool ExportADC { get; set; }
/// <summary>
/// controls whether to export EU or not
/// </summary>
public bool ExportEU { get; set; }
/// <summary>
/// controls whether to export MV or not
/// </summary>
public bool ExportMv { get; set; }
/// <summary>
/// the starting
/// </summary>
public double Start { get; set; }
public double Stop { get; set; }
public bool Filtered { get; set; }
/// <summary>
/// FB 6410 The list of user selected headers to export
/// </summary>
public List<IExportHeader> ExportHeaders { get; set; }
#endregion
#region enums and constants
/// <summary>
/// every 1000 samples update progress
/// </summary>
private const int UPDATE_INTERVAL = 1000;
#endregion
#region methods
/// <summary>
/// writes out test to given path
/// </summary>
/// <param name="pathname"></param>
/// <param name="id"></param>
/// <param name="test"></param>
/// <param name="bFiltering"></param>
/// <param name="includeGroupNameInISOExport"></param>
/// <param name="dataCollectionLength"></param>
/// <param name="minStartTime"></param>
public void Write(string pathname, string id, Test test, bool bFiltering, bool includeGroupNameInISOExport, double minStartTime, int dataCollectionLength)
{
}
/// <summary>
/// returns a datascaler for the given channel
/// </summary>
/// <param name="currentAnalogChannel"></param>
/// <returns></returns>
public static Common.DAS.Concepts.DataScaler GetDataScaler(Test.Module.AnalogInputChannel currentAnalogChannel)
{
var scaler = new Common.DAS.Concepts.DataScaler
{
IsInverted = currentAnalogChannel.IsInverted,
IEPE = currentAnalogChannel.Bridge == SensorConstants.BridgeType.IEPE,
UnitConversion = currentAnalogChannel.UnitConversion,
BasedOnOutputAtCapacity = currentAnalogChannel.AtCapacity,
CapacityOutputIsBasedOn = currentAnalogChannel.CapacityOutputIsBasedOn,
SensitivityUnits = currentAnalogChannel.SensitivityUnits,
Multiplier = currentAnalogChannel.Multiplier,
UserOffsetEU = currentAnalogChannel.UserOffsetEU
};
scaler.SetLinearizationFormula(currentAnalogChannel.LinearizationFormula);
scaler.SetScaleFactorMv(currentAnalogChannel.Data.ScaleFactorMv);
scaler.SetScaleFactorEU(currentAnalogChannel.Data.ScaleFactorEU);
scaler.SetUseEUScaleFactors(currentAnalogChannel.Data.UseEUScaleFactors);
scaler.SetMvPerEu(currentAnalogChannel.Data.MvPerEu);
try
{
scaler.SetInitialOffset(currentAnalogChannel.InitialOffset);
scaler.ZeroMethodType = currentAnalogChannel.ZeroMethod;
scaler.SetRemovedADC(currentAnalogChannel.RemovedADC);
scaler.SetRemovedInternalADC(currentAnalogChannel.RemovedInternalADC);
scaler.SetDataZeroLevelADC(currentAnalogChannel.DataZeroLevelAdc);
scaler.SetZeroMvInADC(currentAnalogChannel.ZeroMvInADC);
try
{
//note the window average is the average over time when the average is not in your dataset
//sliceware is the only software that sets this currently
scaler.SetWindowAverageADC(currentAnalogChannel.WindowAverageADC);
}
catch (System.Exception ex)
{
APILogger.Log("WindowAverageADC failed to set", ex);
}
}
catch (System.Exception ex)
{
APILogger.Log("Failed to set parameters on scaler", ex);
}
scaler.NominalExcitationVoltage = currentAnalogChannel.ExcitationVoltage;
if (currentAnalogChannel.MeasuredExcitationVoltageValid)
{
try
{
scaler.MeasuredExcitationVoltage = currentAnalogChannel.MeasuredExcitationVoltage;
}
catch (System.Exception ex)
{
APILogger.Log("failed to get measured excitation voltage", ex);
}
}
if (currentAnalogChannel.FactoryExcitationVoltageValid)
{
try
{
scaler.FactoryExcitationVoltage = currentAnalogChannel.FactoryExcitationVoltage;
}
catch (System.Exception ex)
{
APILogger.Log("failed to get factory excitation", ex);
}
}
//14469 Excel export EU values incorrect for digital input channel
//digital properties were not being set
scaler.Digital = currentAnalogChannel.IsDigital();
scaler.DigitalMode = currentAnalogChannel.DigitalMode;
scaler.SetDigitalMultiplier(currentAnalogChannel.DigitalMultiplier);
scaler.ProportionalToExcitation = currentAnalogChannel.ProportionalToExcitation;
return scaler;
}
/// <summary>
/// updates the progress if possible
/// </summary>
/// <param name="dValue"></param>
/// <param name="tickEventHandler"></param>
private void UpdateProgress(double dValue, TickEventHandler tickEventHandler)
{
tickEventHandler?.Invoke(this, dValue);
}
private static readonly Dictionary<uint, Row> _rowIndexToRow = new Dictionary<uint, Row>();
/// <summary>
/// gets a cell given a work sheet and a strong cell reference
/// cell reference should be in the form SheetId!$Column$Row,
/// like DefinedNames use
/// </summary>
/// <param name="worksheet"></param>
/// <param name="xColumn"></param>
/// <param name="rowIndex"></param>
/// <param name="bLookForCell"></param>
/// <returns></returns>
protected Cell GetCell(Worksheet worksheet, string xColumn, uint rowIndex, bool bLookForCell = true)
{
var nameref = string.Format("{0}{1}", xColumn, rowIndex);
// ReSharper disable once ReplaceWithSingleCallToFirstOrDefault
Row theRow;
if (_rowIndexToRow.ContainsKey(rowIndex))
{
theRow = _rowIndexToRow[rowIndex];
}
else
{
return InsertCellInWorksheet(xColumn, rowIndex, worksheet.WorksheetPart, nameref, false);
}
if (!bLookForCell)
{
InsertCellInWorksheet(xColumn, rowIndex, worksheet.WorksheetPart, nameref, false);
}
// ReSharper disable once ReplaceWithSingleCallToFirstOrDefault
var theCell = theRow.Descendants<Cell>().Where(c => c.CellReference == nameref).FirstOrDefault();
return theCell ?? InsertCellInWorksheet(xColumn, rowIndex, worksheet.WorksheetPart, nameref, false);
}
// Given a column name, a row index, and a WorksheetPart, inserts a cell into the worksheet.
// If the cell already exists, returns it.
private static Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPart worksheetPart, string cellReference, bool bLookForCell)
{
var worksheet = worksheetPart.Worksheet;
var sheetData = worksheet.GetFirstChild<SheetData>();
// If the worksheet does not contain a row with the specified row index, insert one.
Row row;
if (_rowIndexToRow.ContainsKey(rowIndex))
{
row = _rowIndexToRow[rowIndex];
}
else
{
row = new Row { RowIndex = rowIndex };
_rowIndexToRow[rowIndex] = row;
sheetData.Append(row);
}
// If there is not a cell with the specified column name, insert one.
if (bLookForCell)
{
var matches = row.Elements<Cell>().Where(c => c.CellReference.Value == columnName + rowIndex);
//resharper suggests these should be made into an array first
var matchesAsArray = matches as Cell[] ?? matches.ToArray();
if (matchesAsArray.Any())
{
return matchesAsArray.First();
}
}
// Cells must be in sequential order according to CellReference. Determine where to insert the new cell.
var refCell = row.Elements<Cell>().Where(cell => cell.CellReference.Value.Length == cellReference.Length).FirstOrDefault(cell => string.Compare(cell.CellReference.Value, cellReference, StringComparison.OrdinalIgnoreCase) > 0);
var newCell = new Cell { CellReference = cellReference };
row.InsertBefore(newCell, refCell);
return newCell;
}
protected WorksheetPart GetWorksheetPartByName(SpreadsheetDocument document, string sheetName)
{
var sheets =
document.WorkbookPart.Workbook.GetFirstChild<Sheets>().
Elements<Sheet>().Where(s => s.Name == sheetName);
var enumerable = sheets as Sheet[] ?? sheets.ToArray();
if (!enumerable.Any())
{
// The specified worksheet does not exist.
return null;
}
var relationshipId = enumerable.First().Id.Value;
var worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(relationshipId);
return worksheetPart;
}
private Dictionary<string, int> _stringLookup;
protected int InsertSharedStringItem(string text, SharedStringTablePart shareStringPart)
{
if (null == text) { text = ""; }
// If the part does not contain a SharedStringTable, create one.
if (shareStringPart.SharedStringTable == null)
{
shareStringPart.SharedStringTable = new SharedStringTable();
}
int i;
if (null == _stringLookup)
{
i = 0;
_stringLookup = new Dictionary<string, int>();
foreach (var item in shareStringPart.SharedStringTable.Elements<SharedStringItem>())
{
_stringLookup[item.InnerText] = i++;
}
}
//if the string is already in the table, return it's index, otherwise add a new string to the table and return the new index
if (_stringLookup.ContainsKey(text)) { return _stringLookup[text]; }
i = _stringLookup.Count;
shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new Text(text)));
shareStringPart.SharedStringTable.Save();
_stringLookup[text] = i;
return i;
}
private void WriteTime(WorksheetPart ws,
string column,
uint row,
DateTime time, SharedStringTablePart sharedString)
{
var cell = GetCell(ws.Worksheet, column, row);
cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
cell.CellValue = new CellValue(InsertSharedStringItem(time.ToShortTimeString(), sharedString).ToString());
cell.StyleIndex = _dateFormatIndex;
}
/// <summary>
/// FB 6410 The override for WriteTime to use the correct row for the requested headerName
/// </summary>
/// <param name="ws"></param>
/// <param name="column"></param>
/// <param name="headerName"></param>
/// <param name="time"></param>
/// <param name="sharedString"></param>
private void WriteTime(WorksheetPart ws,
string column,
string headerName,
DateTime time, SharedStringTablePart sharedString)
{
if (!_headerRowLineIndex.ContainsKey(headerName))
{
return;
}
WriteTime(ws, column, _headerRowLineIndex[headerName], time, sharedString);
}
private void WriteDate(WorksheetPart ws,
string column,
uint row,
DateTime date)
{
var cell = GetCell(ws.Worksheet, column, row);
cell.DataType = new EnumValue<CellValues>(CellValues.Number);
cell.CellValue =
new CellValue(date.ToOADate().ToString(CultureInfo.InvariantCulture));
cell.StyleIndex = _dateFormatIndex;
}
/// <summary>
/// FB 6410 The override for WriteDate to use the correct row for the requested headerName
/// </summary>
/// <param name="ws"></param>
/// <param name="column"></param>
/// <param name="headerName"></param>
/// <param name="date"></param>
private void WriteDate(WorksheetPart ws,
string column,
string headerName,
DateTime date)
{
if (!_headerRowLineIndex.ContainsKey(headerName))
{
return;
}
WriteDate(ws, column, _headerRowLineIndex[headerName], date);
}
private void WriteDouble(WorksheetPart ws,
string column,
uint row,
double value)
{
var cell = GetCell(ws.Worksheet, column, row, false);
cell.CellValue = new CellValue(value.ToString(CultureInfo.InvariantCulture));
}
/// <summary>
/// FB 6410 The override for WriteDouble to use the correct row for the requested headerName
/// </summary>
/// <param name="ws"></param>
/// <param name="column"></param>
/// <param name="headerName"></param>
/// <param name="value"></param>
private void WriteDouble(WorksheetPart ws,
string column,
string headerName,
double value)
{
if (!_headerRowLineIndex.ContainsKey(headerName))
{
return;
}
WriteDouble(ws, column, _headerRowLineIndex[headerName], value);
}
private void WriteString(WorksheetPart ws,
string column,
uint row,
SharedStringTablePart sharedStringTablePart,
string value)
{
var cell = GetCell(ws.Worksheet, column, row, false);
cell.CellValue = new CellValue(InsertSharedStringItem(value, sharedStringTablePart).ToString());
cell.DataType = new EnumValue<CellValues> { Value = CellValues.SharedString };
}
/// <summary>
/// FB 6410 The override for WriteString to use the correct row for the requested headerName
/// </summary>
/// <param name="ws"></param>
/// <param name="column"></param>
/// <param name="headerName"></param>
/// <param name="sharedStringTablePart"></param>
/// <param name="value"></param>
private void WriteString(WorksheetPart ws,
string column,
string headerName,
SharedStringTablePart sharedStringTablePart,
string value)
{
//If we can't find the headerName that header is not selected by user and it's not in this dictionary skip this header
if (!_headerRowLineIndex.ContainsKey(headerName))
{
return;
}
// Do not eneter the header name twice if it's already entered
if (_alreadyEnteredHeader.Contains(value))
{
return;
}
WriteString(ws, column, _headerRowLineIndex[headerName], sharedStringTablePart, value);
_alreadyEnteredHeader.Add(headerName);
}
private List<string> _alreadyEnteredHeader = new List<string>();
private static string GetColumn(int index)
{
var dividend = index + 2;//we are starting at b...
var columnName = string.Empty;
while (dividend > 0)
{
var modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo) + columnName;
dividend = (dividend - modulo) / 26;
}
return columnName;
}
private uint _dateFormatIndex;
private void AddStyleSheet(SpreadsheetDocument sp)
{
var stylesheet = sp.WorkbookPart.WorkbookStylesPart.Stylesheet;
stylesheet.CellFormats.AppendChild(new CellFormat
{
NumberFormatId = 14,
ApplyNumberFormat = true
});
_dateFormatIndex = stylesheet.CellFormats.Count;
stylesheet.Save();
}
/// <summary>
/// Insert an empty row after the last entered row
/// </summary>
/// <param name="worksheetPart"></param>
private void InsertRow(WorksheetPart worksheetPart)
{
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
Row lastRow = sheetData.Elements<Row>().LastOrDefault();
if (lastRow != null)
{
sheetData.InsertAfter(new Row() { RowIndex = (lastRow.RowIndex + 1) }, lastRow);
}
}
private Dictionary<string, uint> _headerRowLineIndex = new Dictionary<string, uint>();
/// <summary>
/// This dictionary holds the datascaler for the AICs for the test. This was done for performance reasons. There
/// are several for/foreach loops that are in the write function that all need the scaler, but dont all need to
/// get it everytime.
/// </summary>
private Dictionary<int, Common.DAS.Concepts.DataScaler> _aicToScaler;
/// <summary>
/// writes out test to given path
/// </summary>
/// <param name="pathname"></param>
/// <param name="id"></param>
/// <param name="dataFolder"></param>
/// <param name="test"></param>
/// <param name="bFiltering"></param>
/// <param name="includeGroupNameInISOExport"></param>
/// <param name="fd"></param>
/// <param name="tmChannel"></param>
/// <param name="channelNumber"></param>
/// <param name="beginEventHandler"></param>
/// <param name="cancelEventHandler"></param>
/// <param name="endEventHandler"></param>
/// <param name="tickEventHandler"></param>
/// <param name="errorEventHandler"></param>
/// <param name="cancelRequested"></param>
/// <param name="minStartTime"></param>
/// <param name="dataCollectionLength"></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)
{
try
{
_rowIndexToRow.Clear();
_headerRowLineIndex.Clear();
_aicToScaler = new Dictionary<int, Common.DAS.Concepts.DataScaler>();
_stringLookup = null;
beginEventHandler?.Invoke(this, 100);
//pathname has the full path of our destination file
var sourceFile = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ReportTemplates",
"XLSXExportTemplate.xlsx");
var expectedWrites = double.NaN;
if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(pathname)))
{
System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(pathname));
}
System.IO.File.Copy(sourceFile, pathname, true);
//FB 6410 Build the dictionary to keep the name of the headers need to be exported along with the actual row number in the excel file
uint headerRowIndex = 1;
_headerRowLineIndex.Add(XLSXExportHeaderLine.Headers.GetDescription(), headerRowIndex);
foreach (var header in ExportHeaders)
{
if (header.IsSelected)
{
headerRowIndex++;
_headerRowLineIndex.Add(header.HeaderName, headerRowIndex);
}
}
headerRowIndex++;
_headerRowLineIndex.Add(XLSXExportHeaderLine.DataStart.GetDescription(), headerRowIndex);
headerRowIndex++;
_headerRowLineIndex.Add(XLSXExportHeaderLine.Labels.GetDescription(), headerRowIndex);
var maxSampleRate = test.Channels.Select(ch => ch.ParentModule.SampleRateHz).Max();
//14659 Excel (xlsx) export all (filtered) fails, but says export finished in green
//we need to use channel order rather than display order as display order in some data sets
//so that we can index the channels
var channels = new List<Test.Module.Channel>();
channels.AddRange(test.Channels);
channels.Sort((a, b) =>
{
var res = a.AbsoluteDisplayOrder.CompareTo(b.AbsoluteDisplayOrder);
if (res != 0) { return res; }
return a.Number.CompareTo(b.Number);
});
using (var sp = SpreadsheetDocument.Open(pathname, true))
{
AddStyleSheet(sp);
var shareStringPart = sp.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First();
sp.WorkbookPart.Workbook.CalculationProperties.ForceFullCalculation = true;
sp.WorkbookPart.Workbook.CalculationProperties.FullCalculationOnLoad = true;
var dataWs = GetWorksheetPartByName(sp, "Data");
var rows = dataWs.Worksheet.Descendants<Row>();
//FB 6410 insert rows for each selected header in the excel sheet which will be filled later on
for (int i = 0; i < _headerRowLineIndex.Count - 1; i++)
{
InsertRow(dataWs);
}
foreach (var row in rows)
{
_rowIndexToRow[row.RowIndex] = row;
}
WriteString(dataWs, "A", XLSXExportHeaderLine.TestDate.GetDescription(), shareStringPart, XLSXExportHeaderLine.TestDate.GetDescription());
WriteDate(dataWs, "B", XLSXExportHeaderLine.TestDate.GetDescription(), test.InceptionDate);
WriteString(dataWs, "A", XLSXExportHeaderLine.TestTime.GetDescription(), shareStringPart, XLSXExportHeaderLine.TestTime.GetDescription());
WriteTime(dataWs, "B", XLSXExportHeaderLine.TestTime.GetDescription(), test.InceptionDate, shareStringPart);
WriteString(dataWs, "A", XLSXExportHeaderLine.TestId.GetDescription(), shareStringPart, XLSXExportHeaderLine.TestId.GetDescription());
WriteString(dataWs, "B", XLSXExportHeaderLine.TestId.GetDescription(), shareStringPart, id);
WriteString(dataWs, "A", XLSXExportHeaderLine.TestDescription.GetDescription(), shareStringPart, XLSXExportHeaderLine.TestDescription.GetDescription());
WriteString(dataWs, "B", XLSXExportHeaderLine.TestDescription.GetDescription(), shareStringPart, test.Description);
//go through all the channels, and include whatever data is requested
foreach (var channel in channels)
{
//for now ignore the channel if it's not an analoginputchannel, this probably includes everything except maybe the calculated channels ...
if (!(channel is Test.Module.AnalogInputChannel aic)) { continue; }
//this should divide evenly, so ceiling is necessary in theory
var rate = Convert.ToInt32(Math.Ceiling(maxSampleRate / aic.ParentModule.SampleRateHz));
var iChannel = channels.IndexOf(channel);
if (double.IsNaN(expectedWrites))
{
expectedWrites = (double)test.Channels.Count * dataCollectionLength;
}
var column = GetColumn(iChannel);
WriteString(dataWs, "A", XLSXExportHeaderLine.SampleRate.GetDescription(), shareStringPart, XLSXExportHeaderLine.SampleRate.GetDescription());
WriteDouble(dataWs, column, XLSXExportHeaderLine.SampleRate.GetDescription(), maxSampleRate);
WriteString(dataWs, "A", XLSXExportHeaderLine.HardwareAntiAliasFilter.GetDescription(), shareStringPart, XLSXExportHeaderLine.HardwareAntiAliasFilter.GetDescription());
WriteDouble(dataWs, column, XLSXExportHeaderLine.HardwareAntiAliasFilter.GetDescription(), aic.ParentModule.AaFilterRateHz);
WriteString(dataWs, "A", XLSXExportHeaderLine.DataChannelNumber.GetDescription(), shareStringPart, XLSXExportHeaderLine.DataChannelNumber.GetDescription());
WriteDouble(dataWs, column, XLSXExportHeaderLine.DataChannelNumber.GetDescription(), (double)1 + iChannel);
var isoCode = "";
if (null != WriterParent)
{
switch (WriterParent.ISOViewMode)
{
case Common.Enums.IsoViewMode.ISOOnly:
isoCode = aic.IsoCode;
break;
case Common.Enums.IsoViewMode.ISOAndUserCode:
isoCode = $"{aic.IsoCode}/{aic.UserCode}";
break;
case Common.Enums.IsoViewMode.UserCodeOnly:
isoCode = aic.UserCode;
break;
case Common.Enums.IsoViewMode.ChannelNameOnly:
isoCode = string.Empty;
break;
}
}
WriteString(dataWs, "A", XLSXExportHeaderLine.IsoCode.GetDescription(), shareStringPart, XLSXExportHeaderLine.IsoCode.GetDescription());
WriteString(dataWs, column, XLSXExportHeaderLine.IsoCode.GetDescription(), shareStringPart, isoCode);
WriteString(dataWs, "A", XLSXExportHeaderLine.ChannelDescription.GetDescription(), shareStringPart, XLSXExportHeaderLine.ChannelDescription.GetDescription());
WriteString(dataWs, column, XLSXExportHeaderLine.ChannelDescription.GetDescription(), shareStringPart, aic.ChannelName2);
WriteString(dataWs, "A", XLSXExportHeaderLine.ChannelLocation.GetDescription(), shareStringPart, XLSXExportHeaderLine.ChannelLocation.GetDescription());
WriteString(dataWs, "A", XLSXExportHeaderLine.SensorSerialNumber.GetDescription(), shareStringPart, XLSXExportHeaderLine.SensorSerialNumber.GetDescription());
WriteString(dataWs, column, XLSXExportHeaderLine.SensorSerialNumber.GetDescription(), shareStringPart, aic.SerialNumber);
var filter = SaeJ211Filter.Parse(aic.SoftwareFilter);
WriteString(dataWs, "A", XLSXExportHeaderLine.SoftwareFilter.GetDescription(), shareStringPart, XLSXExportHeaderLine.SoftwareFilter.GetDescription());
//FB 18024 Show NONE for unfiltered
if (Filtered)
{
WriteString(dataWs, column, XLSXExportHeaderLine.SoftwareFilter.GetDescription(), shareStringPart, filter.Name);
}
else
{
WriteString(dataWs, column, XLSXExportHeaderLine.SoftwareFilter.GetDescription(), shareStringPart, "NONE");
}
if (bFiltering)
{
WriteString(dataWs, "A", XLSXExportHeaderLine.SoftwareFilterDb.GetDescription(), shareStringPart, XLSXExportHeaderLine.SoftwareFilterDb.GetDescription());
//FB 18024 Show NONE for unfiltered
if (Filtered)
{
WriteDouble(dataWs, column, XLSXExportHeaderLine.SoftwareFilterDb.GetDescription(), bFiltering ? filter.CutoffFrequencyHz : 0D);
}
else
{
WriteString(dataWs, column, XLSXExportHeaderLine.SoftwareFilterDb.GetDescription(), shareStringPart, "NONE");
}
}
WriteString(dataWs, "A", XLSXExportHeaderLine.EngineeringUnits.GetDescription(), shareStringPart, XLSXExportHeaderLine.EngineeringUnits.GetDescription());
WriteString(dataWs, column, XLSXExportHeaderLine.EngineeringUnits.GetDescription(), shareStringPart, aic.EngineeringUnits);
var preTriggerSamples = aic.ParentModule.TriggerSampleNumbers[0] - (double)aic.ParentModule.StartRecordSampleNumber;
if (preTriggerSamples < 0) { preTriggerSamples = 0D; }
if (preTriggerSamples > aic.ParentModule.NumberOfSamples) { preTriggerSamples = aic.ParentModule.NumberOfSamples; }
if (preTriggerSamples > Start * aic.ParentModule.SampleRateHz) { preTriggerSamples = Math.Truncate(Start * aic.ParentModule.SampleRateHz); }
WriteString(dataWs, "A", XLSXExportHeaderLine.UserComment.GetDescription(), shareStringPart, XLSXExportHeaderLine.UserComment.GetDescription());
WriteString(dataWs, "A", XLSXExportHeaderLine.PreZero.GetDescription(), shareStringPart, XLSXExportHeaderLine.PreZero.GetDescription());
WriteDouble(dataWs, column, XLSXExportHeaderLine.PreZero.GetDescription(), rate * preTriggerSamples);
var postTriggerSamples = aic.ParentModule.NumberOfSamples - preTriggerSamples;
if (postTriggerSamples < 0) { postTriggerSamples = 0D; }
if (postTriggerSamples > Stop * aic.ParentModule.SampleRateHz) { postTriggerSamples = Math.Truncate(Stop * aic.ParentModule.SampleRateHz); }
WriteString(dataWs, "A", XLSXExportHeaderLine.PostZero.GetDescription(), shareStringPart, XLSXExportHeaderLine.PostZero.GetDescription());
WriteDouble(dataWs, column, XLSXExportHeaderLine.PostZero.GetDescription(), rate * postTriggerSamples);
WriteString(dataWs, "A", XLSXExportHeaderLine.DataZero.GetDescription(), shareStringPart, XLSXExportHeaderLine.DataZero.GetDescription());
WriteDouble(dataWs, column, XLSXExportHeaderLine.DataZero.GetDescription(), aic.DataZeroLevelAdc);
_aicToScaler[iChannel] = GetDataScaler(aic);
WriteString(dataWs, "A", XLSXExportHeaderLine.ScaleEu.GetDescription(), shareStringPart, XLSXExportHeaderLine.ScaleEu.GetDescription());
WriteDouble(dataWs, column, XLSXExportHeaderLine.ScaleEu.GetDescription(), _aicToScaler[iChannel].GetAdcToEuScalingFactor());
WriteString(dataWs, "A", XLSXExportHeaderLine.ScaleMv.GetDescription(), shareStringPart, XLSXExportHeaderLine.ScaleMv.GetDescription());
WriteDouble(dataWs, column, XLSXExportHeaderLine.ScaleMv.GetDescription(), _aicToScaler[iChannel].GetAdcToMvScalingFactor());
WriteString(dataWs, "A", XLSXExportHeaderLine.DataStart.GetDescription(), shareStringPart, XLSXExportHeaderLine.DataStart.GetDescription());
WriteString(dataWs, "A", XLSXExportHeaderLine.Labels.GetDescription(), shareStringPart, XLSXExportHeaderLine.Labels.GetDescription());
WriteString(dataWs, column, XLSXExportHeaderLine.Labels.GetDescription(), shareStringPart, $"Chan {1 + iChannel}: {aic.ChannelName2}");
}
dataWs.Worksheet.Save();
}
//now that we are done with all the strings, open up as SAX and write all the values
//the numeric cells are easy, but non numeric have data types and sharedstringpart s to manipulate, so
//that's why I split the two up
using (var myDoc = SpreadsheetDocument.Open(pathname, true))
{
var workbookPart = myDoc.WorkbookPart;
var worksheetPart = GetWorksheetPartByName(myDoc, "Data");
var origninalSheetId = workbookPart.GetIdOfPart(worksheetPart);
var replacementPart =
workbookPart.AddNewPart<WorksheetPart>();
var replacementPartId = workbookPart.GetIdOfPart(replacementPart);
var reader = OpenXmlReader.Create(worksheetPart);
var writer = OpenXmlWriter.Create(replacementPart);
var filteredData = new double[test.Channels.Count][];
if (Filtered)
{
var data = filteredData;
Parallel.ForEach(channels, channel =>
{
var aic = (Test.Module.AnalogInputChannel)channel;
if (null == aic) { return; }
var iChannel = channels.IndexOf(channel);
var sampleCount = aic.PersistentChannelInfo.Data.Length;
data[iChannel] = new double[sampleCount];
for (var iSampleIdx = 0;
iSampleIdx < sampleCount;
iSampleIdx++)
{
data[iChannel][iSampleIdx] = _aicToScaler[iChannel].GetEU(aic.PersistentChannelInfo.Data[iSampleIdx]);
}
var filter = SaeJ211Filter.Parse(aic.SoftwareFilter);
data[iChannel] = filter.Apply(data[iChannel], aic.ParentModule.SampleRateHz, UseLegacyTDCSoftwareFiltering);
});
filteredData = data;
}
headerRowIndex++;
while (reader.Read())
{
if (reader.ElementType == typeof(SheetData) && !reader.IsEndElement)
{
writer.WriteStartElement(new SheetData());
}
else if (reader.ElementType == typeof(SheetData) && reader.IsEndElement)
{
for (var sampleIndex = 0UL;
(int)sampleIndex <= dataCollectionLength;
sampleIndex++)
{
var row = new Row { RowIndex = Convert.ToUInt32(headerRowIndex + sampleIndex) };
writer.WriteStartElement(row);
foreach (var channel in channels)
{
if (!(channel is Test.Module.AnalogInputChannel aic)) { continue; }
var iChannel = channels.IndexOf(channel);
var dStartTime = (double)aic.ParentModule.StartRecordSampleNumber / aic.ParentModule.SampleRateHz;
if (aic.ParentModule.TriggerSampleNumbers.Count > 0)
{
dStartTime -= (double)aic.ParentModule.TriggerSampleNumbers[0] / aic.ParentModule.SampleRateHz;
}
//14513 double rounding error causing data to be offset by one sample incorrectly
// note that using decimals will fix the imprecision issue, but will use more time ...
var delta = Convert.ToDecimal(dStartTime) - Convert.ToDecimal(minStartTime);
var channelOffsetStart = Convert.ToInt32(delta * Convert.ToDecimal(aic.ParentModule.SampleRateHz));
var rate = maxSampleRate / aic.ParentModule.SampleRateHz;
var indexAtCurrentTime = ((double)sampleIndex - channelOffsetStart) / rate;
var thisChannelsIndexAtCurrentTime = Convert.ToInt32(Math.Floor(indexAtCurrentTime));
var step = Convert.ToInt32(Math.Ceiling(indexAtCurrentTime) - thisChannelsIndexAtCurrentTime);
if (0 == iChannel)
{
var time = minStartTime + sampleIndex / maxSampleRate;
var c = new Cell
{
CellValue = new CellValue(time.ToString(CultureInfo.InvariantCulture))
};
writer.WriteElement(c);
}
var value = Filtered ? filteredData[iChannel][thisChannelsIndexAtCurrentTime] : _aicToScaler[iChannel].GetEU(aic.PersistentChannelInfo.Data[thisChannelsIndexAtCurrentTime]);
if (step > 0) //INTERPOLATE
{
var increment = 0D;
if (Filtered)
{
if ((1 + thisChannelsIndexAtCurrentTime) < filteredData[iChannel].Length)
{
increment = (filteredData[iChannel][1 + thisChannelsIndexAtCurrentTime] - value) / rate;
}
else
{
increment = (value - filteredData[iChannel][thisChannelsIndexAtCurrentTime - 1]) / rate;
}
}
else
{
if ((1 + thisChannelsIndexAtCurrentTime) < aic.PersistentChannelInfo.Data.Length)
{
increment = (_aicToScaler[iChannel].GetEU(aic.PersistentChannelInfo.Data[thisChannelsIndexAtCurrentTime + 1]) - value) / rate;
}
else
{
increment = (value - _aicToScaler[iChannel].GetEU(aic.PersistentChannelInfo.Data[thisChannelsIndexAtCurrentTime - 1])) / rate;
}
}
value = value + increment * step;
}
var cell = new Cell
{
CellValue = new CellValue(
value.ToString(CultureInfo.InvariantCulture))
};
writer.WriteElement(cell);
}
if (0 == sampleIndex % UPDATE_INTERVAL)
{
var currentWrite = (double)sampleIndex * test.Channels.Count;
UpdateProgress(100D * currentWrite / expectedWrites, tickEventHandler);
}
writer.WriteEndElement();
}
writer.WriteEndElement();
}
else
{
if (reader.ElementType == typeof(Row) && reader.IsStartElement)
{
writer.WriteElement(reader.LoadCurrentElement());
}
else
{
if (reader.IsStartElement)
{
writer.WriteStartElement(reader);
}
else if (reader.IsEndElement)
{
writer.WriteEndElement();
}
}
}
}
reader.Close();
writer.Close();
var sheet = workbookPart.Workbook.Descendants<Sheet>().Where(s => s.Id.Value.Equals(origninalSheetId)).First();
sheet.Id.Value = replacementPartId;
workbookPart.DeletePart(worksheetPart);
filteredData = null;
}
foreach (var channel in test.Channels)
{
if (!(channel is Test.Module.AnalogInputChannel aic)) continue;
aic.PersistentChannelInfo.UnSet();
// These garbage collection calls cause a significant performance hit and were removed becasue of this. They
// were probably put here when DP was still 32bit only.
//System.Runtime.GCSettings.LatencyMode = System.Runtime.GCLatencyMode.Batch;
//System.Runtime.GCSettings.LargeObjectHeapCompactionMode = System.Runtime.GCLargeObjectHeapCompactionMode.CompactOnce;
//GC.Collect();
}
}
catch (System.Exception ex)
{
APILogger.Log("encountered problem writing XLSX test files", ex);
errorEventHandler?.Invoke(this, ex);
}
finally
{
tickEventHandler?.Invoke(this, 100D);
endEventHandler?.Invoke(this);
}
}
#endregion
/// <summary>
/// constructs the writer with a given file and encoding
/// </summary>
/// <param name="fileType"></param>
/// <param name="encoding"></param>
internal Writer(File fileType, int encoding)
: base(fileType, encoding)
{
ExportADC = false;
ExportEU = true;
ExportMv = false;
WriterParent = fileType;
}
/// <summary>
/// initializes the writer
/// </summary>
/// <param name="pathname"></param>
/// <param name="id"></param>
/// <param name="dataFolder"></param>
/// <param name="test"></param>
/// <param name="bFiltering"></param>
/// <param name="includeGroupNameInISOExport"></param>
/// <param name="fd"></param>
/// <param name="tmChannel"></param>
/// <param name="channelNumber"></param>
/// <param name="beginEventHandler"></param>
/// <param name="cancelEventHandler"></param>
/// <param name="endEventHandler"></param>
/// <param name="tickEventHandler"></param>
/// <param name="errorEventHandler"></param>
/// <param name="cancelRequested"></param>
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)
{
}
}
}
}

View File

@@ -0,0 +1,77 @@
/*
* Excel.File.cs
*
* Copyright © 2017
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
namespace DTS.Serialization.XLSX
{
/// <summary>
/// implementation of the Serialization.File class for XLSX
/// http://fogbugz/fogbugz/default.asp?9920'
/// right now this will only export EU, (filtered or unfiltered)
/// but we'll likely want to control whether to export mV/ADC in future
/// </summary>
public partial class File
: Serialization.File, IWritable<Test>
{
/// <summary>
/// constructor
/// </summary>
public File()
: base("XLSX")
{
}
/// <summary>
/// Get the file writer for this file type.
/// </summary>
public IWriter<Test> Exporter
{
get
{
try
{
if (_exporter == null)
{
var writer = new Writer(this, DefaultEncoding);
_exporter = writer;
}
return _exporter;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting exporter", ex);
}
}
}
private IWriter<Test> _exporter;
/// <summary>
/// Controls whether to export ADC or not
/// </summary>
public bool ExportADC
{
set => ((Writer)Exporter).ExportADC = value;
}
/// <summary>
/// Controls whether to export EU or not
/// </summary>
public bool ExportEU
{
set => ((Writer)Exporter).ExportEU = value;
}
/// <summary>
/// Controls whether to export mV or not
/// </summary>
public bool ExportMV
{
set => ((Writer)Exporter).ExportMv = value;
}
}
}

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.8", FrameworkDisplayName = "")]

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]