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,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);
}
}
}
}