/*
* DTS.Slice.Control.Event.Module.Channel.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using DTS.DASLib.Service;
using DTS.Common.DAS.Concepts.DAS.Channel;
using DTS.Common.DAS.Concepts;
using DTS.Common.DASResource;
using DTS.Common.Enums;
using DTS.Common.Enums.Sensors;
using DTS.Common.SerializationPlus;
using DTS.Common.Utilities;
using DTS.Common.Utilities.DotNetProgrammingConstructs;
using DTS.Common.Interface.DASFactory.Diagnostics;
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
{
///
/// Representation of the DTS.Slice.Control.Event.Module.Channel class.
///
public abstract partial class Channel
: Exceptional,
IFilterable, IDisposable
{
public void Dispose() { }
///
/// Initialize an instance of the Event.Module.Channel class. Specifically, perform initializations
/// that will be required no matter what constructor parameter signature is invoked.
///
private Channel()
{
try
{
//this.InitializeReviewableAttributes(this.ReviewableAttributes);
}
catch (System.Exception ex)
{
throw new Exception("encountered problem constructing channel", ex);
}
}
///
/// Initialize an instance of the DTS.Slice.Control.Event.Module.Channel class.
///
///
///
/// The that contains this channel.
///
///
///
/// The unique "absolute" number of the channel with respect to all other channels
/// on all other DASes in the system.
///
///
protected Channel(Module parentModule, int absoluteNumber)
: this()
{
try
{
var enumerabilityGrabber = new EnumerabilityAttributeCoder();
ParentModule = parentModule;
AbsoluteNumber = absoluteNumber;
foreach (int enumValue in Enum.GetValues(typeof(ChannelFilter)))
if (enumerabilityGrabber.DecodeAttributeValue((ChannelFilter)enumValue))
AvailableFilters.Add(
new SaeJ211Filter((ChannelFilter)enumValue)
);
CurrentFilter = AvailableFilters[0];
}
catch (System.Exception ex)
{
throw new Exception("encountered problem constructing " + GetType().FullName, ex);
}
}
///
/// Initialize an instance of the DTS.Slice.Control.Event.Module.Channel class.
///
///
///
/// The object with which to initialize
/// this object.
///
///
///
/// The that contains this channel.
///
///
///
/// The unique "absolute" number of the channel with respect to all other channels
/// on all other DASes in the system.
///
///
public Channel(DASChannel channel, Module parentModule, int absoluteNumber)
: this(parentModule, absoluteNumber)
{
try
{ //
// Initialize basic channel properties with any values we can find
// in the specified channel object.
//
Number = channel.ModuleChannelNumber;
Start = channel.EventStartTime;
AbsoluteDisplayOrder = channel.AbsoluteDisplayOrder;
UnitConversion = channel.UnitConverision;
AtCapacity = channel.AtCapacity;
CapacityOutputIsBasedOn = channel.CapacityOutputIsBasedOn;
SensitivityUnits = channel.SensitivityUnits;
IsoChannelName = channel.IsoChannelName;
UserCode = channel.UserCode;
UserChannelName = channel.UserChannelName;
LinearSensorCalibration = channel.LinearSensorCalibration;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem constructing " + GetType().FullName, ex);
}
}
///
/// Initialize an instance of the DTS.Slice.Control.Event.Module.Channel class.
///
///
///
/// The object with which to initialize
/// this object.
///
///
///
/// The that contains this channel.
///
///
///
/// The unique "absolute" number of the channel with respect to all other channels
/// on all other DASes in the system.
///
///
public Channel(Serialization.Test.Module.Channel channel, Module parentModule, int absoluteNumber)
: this(parentModule, absoluteNumber)
{
try
{ //
// Initialize basic channel properties with any values we can find
// in the specified channel object.
//
AbsoluteDisplayOrder = channel.AbsoluteDisplayOrder;
Multiplier = channel.Data.Multiplier;
UnitConversion = channel.Data.UnitConversion;
UserOffsetEU = channel.Data.UserOffsetEU;
Number = channel.Number;
Start = channel.Start;
try
{
if (channel.TimeOfFirstSampleValid) { TimeOfFirstSampleSec = channel.TimeOfFirstSampleSec; }
}
catch { }
if (channel.IsLastCalibrationDateValid) { LastCalibrationDate = channel.LastCalibrationDate; }
if (channel.IsCalDueDateValid) { CalDueDate = channel.CalDueDate; }
if (channel.IsSensorIDValid) { SensorID = channel.SensorID; }
if (channel.IsOffsetToleranceLowMvValid) { OffsetToleranceLowMv = channel.OffsetToleranceLowMv; }
if (channel.IsOffsetToleranceHighMvValid) { OffsetToleranceHighMv = channel.OffsetToleranceHighMv; }
if (channel.IsUserCodeValid) { UserCode = channel.UserCode; }
if (channel.IsUserChannelNameValid) { UserChannelName = channel.UserChannelName; }
if (channel.IsIsoChannelNameValid) { IsoChannelName = channel.IsoChannelName; }
IsSubsampled = channel.IsSubsampled;
UnsubsampledSampleRateHz = channel.UnsubsampledSampleRateHz;
IsSupersampled = channel.IsSupersampled;
UseEUScaler = channel.Data.UseEUScaleFactors;
UnsupersampledSampleRateHz = channel.UnsupersampledSampleRateHz;
try
{
if (channel.PersistentChannelInfo == null)
{
UnfilteredData = channel.TDASPersistentChannelInfo;
}
else
{
UnfilteredData = channel.PersistentChannelInfo; //channel.Data;
}
}
catch (System.Exception) { throw new System.IO.InvalidDataException("Invalid or corrupt data file, channel: " + channel.ChannelDescriptionString + " - " + channel.ChannelName2); }
// xxx proposal: this.UnfilteredData = ( null != channel.PersistentChannelInfo ? channel.PersistentChannelInfo : channel.Data );
// If everything uses persistent channel info, that's going to break the data viewer completely in the short term, unless we either
// change the data viewer to be clever about extracting something displayable or provide the "classic" data structure through the
// "UnfilteredData" property somehow.
}
catch (System.IO.InvalidDataException) { throw; }
catch (System.Exception ex)
{
throw new Exception("encountered problem constructing " + GetType().FullName, ex);
}
}
/*
///
/// Get "reviewable" (attributes that can be automatically converted to strings and displayed
/// on the review tab) for this channel.
///
public List ReviewableAttributes
{
get { return _ReviewableAttributes.Value; }
private set { _ReviewableAttributes.Value = value; }
}
private Property> _ReviewableAttributes
= new Property>(
typeof(Event.Module.Channel).Namespace + ".Event.Module.Channel.ReviewableAttributes",
new List(),
true
);
*/
/*
///
/// Method to allow derived classes to initialize their own reviewable attributes.
///
///
///
/// The or s to be initialized.
///
///
protected abstract void InitializeReviewableAttributes(List reviewableAttributes);
*/
///
/// Our data display unit options.
///
public enum DataDisplayUnits
{
Adc,
Mv,
Eu
}
///
/// The that contains this channel.
///
public Module ParentModule
{
get => _ParentModule.Value;
private set => _ParentModule.Value = value;
}
private readonly Property _ParentModule
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.ParentModule",
null,
false
);
///
/// Get the data scaler for this channel.
///
public DataScaler Scaler => _Scaler.Value;
private readonly Property _Scaler
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.Scaler",
new DataScaler(),
true
);
///
/// Get/set the switch to enable/disable filter caching.
///
public bool UseFilterCaching
{
//for now NEVER cache
/*get { return _UseFilterCaching.Value; }
set
{
if (false == (_UseFilterCaching.Value = value))
{ //
// If we disable filter caching on the fly, make sure the caches are cleared.
//
_Data = null;
_DataEu = null;
_DataMv = null;
lock (previouslyFilteredDataLock)
{
_previouslyFilteredData.Clear();
}
}
}*/
get => false;
set { }
}
/*private Property _UseFilterCaching
= new Property(
typeof(Event.Module.Channel).Namespace + ".Event.Module.Channel.UseFilterCaching",
true,
true
);
*/
///
/// Get/set a user-readable description of this channel object; intended to be
/// the UI representation of this object. Literally, what the API channel's
/// ToString method said it was.
///
public string ChannelDescriptionString
{
get => _ChannelDescriptionString.Value;
set => _ChannelDescriptionString.Value = value;
}
private readonly Property _ChannelDescriptionString
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.ChannelDescriptionString",
null,
false
);
///
/// Get/set the manufacturer of this channel object's sensor.
///
public string Manufacturer
{
get => _Manufacturer.Value;
set => _Manufacturer.Value = value;
}
private readonly Property _Manufacturer
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.Manufacturer",
null,
false
);
///
/// Get/set the manufacturer of this channel object's sensor.
///
public string Model
{
get => _Model.Value;
set => _Model.Value = value;
}
private readonly Property _Model
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.Model",
null,
false
);
public string OriginalChannelName
{
get => _OriginalChannelName.Value;
set => _OriginalChannelName.Value = value;
}
private readonly Property _OriginalChannelName
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.OriginalChannelName",
"",
true);
public string ChannelName2
{
get => _ChannelName2.Value;
set => _ChannelName2.Value = value;
}
private readonly Property _ChannelName2
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.ChannelName2",
"",
true);
private readonly Property _HardwareChannelName
= new Property(
typeof(Channel).Name + ".Event.Module.Channel.HardwareChannelName",
"",
true);
public string HardwareChannelName
{
get => _HardwareChannelName.Value;
set => _HardwareChannelName.Value = value;
}
private readonly Property _ChannelId
= new Property(
typeof(Channel).Name + ".Event.Module.Channel.ChannelId",
"",
true);
///
/// refers to a unique id for a logical channel in the test
/// for now this is using TestObjectChannel.GetId()
/// which is in the form of TestObjectSerial_ChannelType_ChannelId
///
public string ChannelId
{
get => _ChannelId.Value;
set => _ChannelId.Value = value;
}
private readonly Property _Sensor
= new Property(
typeof(Channel).Name + ".Event.Module.Channel.Sensor",
"",
true);
///
/// refers to a unique sensor serial number for a logical channel in the test
///
public string Sensor
{
get => _Sensor.Value;
set => _Sensor.Value = value;
}
private readonly Property _ChannelGroupName
= new Property(
typeof(Channel).Name + ".Event.Module.Channel.ChannelGroupName",
"",
true);
///
/// refers to the Group for a logical channel in the test
///
public string ChannelGroupName
{
get => _ChannelGroupName.Value ?? "";
set => _ChannelGroupName.Value = value;
}
public string UserValue1
{
get => _userValue1.Value;
set => _userValue1.Value = value;
}
private readonly Property _userValue1 = new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.UserValue1",
"", true);
public string UserValue2
{
get => _userValue2.Value;
set => _userValue2.Value = value;
}
private readonly Property _userValue2 = new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.UserValue2",
"", true);
public string UserValue3
{
get => _userValue3.Value;
set => _userValue3.Value = value;
}
private readonly Property _userValue3 = new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.UserValue3",
"", true);
///
/// Get/set the channel's ordinal number within the stack.
///
public int Number
{
get => _Number.Value;
set => _Number.Value = value;
}
private readonly Property _Number = new Property("DTS.Control.Event.Module.Channel.Number", -1, false);
///
/// Get the channel's ordinal number within the entire system.
///
public int AbsoluteNumber
{
get => _AbsoluteNumber.Value;
private set => _AbsoluteNumber.Value = value;
}
private readonly Property _AbsoluteNumber
= new Property(
typeof(Channel).FullName + ".AbsoluteNumber",
-1,
false
);
public bool TimeOfFirstSampleSecValid => _TimeOfFirstSampleSec.IsInitialized;
///
/// The time of the first sample. Will be needed if the time
/// scale can't be determined by the trigger sample number (possible, as it's an unsigned
/// value and an all-positive ROI that doesn't contain T0 would need it to be negative).
///
public double TimeOfFirstSampleSec
{
get => _TimeOfFirstSampleSec.Value;
set => _TimeOfFirstSampleSec.Value = value;
}
private readonly Property _TimeOfFirstSampleSec
= new Property(
typeof(Channel).FullName + ".TimeOfFirstSample",
0.0,
false
);
///
/// Get/set the start time for this channel.
///
public DateTime Start
{
get => _Start.Value;
set => _Start.Value = value;
}
private readonly Property _Start = new Property("DTS.Control.Event.Module.Channel.Start", DateTime.Now, false);
public LinkedList PartialUnfilteredData = null;
// Method for creating channel files directly to disk.
// Change that linked list class to something that will handle this...
// I think what we need to do instead is to change the class/data structure that represents
// the channel data into an object that maybe double passes the reference, or derives from the
// memory-mapped file objecct, but it can also have extra methods and throw an exception if we
// try to access it before it's been properly initialized.
///
/// Get/set the data value list for this channel.
///
public List UnfilteredData
{
get => _UnfilteredData.Value;
set
{
try
{
// Reset unfiltered data caches.
_UnfilteredData.Value = value;
_UnfilteredDataEu = null;
_UnfilteredDataMv = null;
_DataRangeAdc.UnInitialize();
//_DataRangeEu .UnInitialize( ); // *** not currently cached.
//_DataRangeMv .UnInitialize( ); // *** not currently cached.
// Reset filtered data caches.
_Data = null;
_DataEu = null;
_DataMv = null;
lock (previouslyFilteredDataLock)
{
_previouslyFilteredData.Clear();
}
// Update the data count.
if (value is Serialization.SliceRaw.File.PersistentChannel persistentChannel)
DataCount = persistentChannel.Count;
else if (value is Serialization.TDAS.File.PersistentChannel tdasPersistentChannel)
DataCount = tdasPersistentChannel.Count;
else DataCount = value.Count;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem setting unfiltered data", ex);
}
}
}
private readonly Property> _UnfilteredData = new Property>("DTS.Control.Event.Module.Channel.Data", null, false);
public List UnfilteredAlternateData
{
get => _UnfilteredAlternateData.Value;
set
{
try
{
// Reset unfiltered data caches.
_UnfilteredAlternateData.Value = value;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem setting unfiltered alternate data", ex);
}
}
}
private readonly Property> _UnfilteredAlternateData = new Property>("DTS.Control.Event.Module.Channel.AlternateData", null, false);
///
/// Get the filtered double-converted data for this channel.
///
public List Data
{
get
{
try
{
if (UseFilterCaching)
{
if (null == _Data)
return _Data = new List(GetDataFilteredBy(CurrentFilter, DataDisplayUnits.Adc));
return _Data;
}
return new List(GetDataFilteredBy(CurrentFilter, DataDisplayUnits.Adc));
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting filtered data", ex);
}
}
}
private List _Data = null;
///
/// Get the data count for this channel.
///
public int DataCount
{
get;
private set;
}
public abstract List GetUnfilteredDataEu();
public abstract List GetUnfilteredDataMV();
///
/// Get an EU-scaled version of the data .
///
public List UnfilteredDataEu
{
get
{
try
{ //
// If scaled data has yet to be computed, then compute, cache and return it.
// Otherwise just return the cached version.
//
if (null == _UnfilteredDataEu)
{
if (UnfilteredData is ILargeDataAware largeDataAware)
{
if (!largeDataAware.IsDataArraySized)
{
throw new Serialization.SliceRaw.File.PersistentChannel.DataTooBigForArrayException("Data is too big to be viewed or filtered.");
}
}
_UnfilteredDataEu = GetUnfilteredDataEu();
}
return _UnfilteredDataEu;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting EU-scaled data", ex);
}
}
}
private List _UnfilteredDataEu = null;
protected List UnfilteredDataMV
{
get
{
try
{ //
// If scaled data has yet to be computed, then compute, cache and return it.
// Otherwise just return the cached version.
//
if (null == _UnfilteredDataMV)
{
if (UnfilteredData is ILargeDataAware largeDataAware)
{
if (!largeDataAware.IsDataArraySized)
{
throw new Serialization.SliceRaw.File.PersistentChannel.DataTooBigForArrayException("Data is too big to be viewed or filtered.");
}
}
_UnfilteredDataMV = GetUnfilteredDataMV();
}
return _UnfilteredDataMV;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting EU-scaled data", ex);
}
}
}
private List _UnfilteredDataMV = null;
private List _DataADC = null;
public List DataADC
{
get
{
try
{ //
// If scaled data has yet to be computed, then compute, cache and return it.
// Otherwise just return the cached version.
//
if (null == _DataADC)
{
if (UnfilteredData is ILargeDataAware largeDataAware)
if (!largeDataAware.IsDataArraySized)
throw new Serialization.SliceRaw.File.PersistentChannel.DataTooBigForArrayException("Data is too big to be viewed or filtered.");
var persistentUnfilteredData
= UnfilteredData as Serialization.SliceRaw.File.PersistentChannel;
//double scalingFactor = AdcToMvScalingFactor;
_DataADC = new List();
var dataCount = persistentUnfilteredData.Count;
for (var i = 0; i < dataCount; i++)
_DataADC.Add(persistentUnfilteredData[i]);
}
return _DataADC;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting ADC data", ex);
}
}
}
public virtual bool SupportsEU => true;
public virtual bool SupportsADC => true;
public virtual bool SupportsmV => true;
///
/// Get/set the filtered EU data for this channel.
///
public IList DataEu
{
get
{
try
{
if (UseFilterCaching)
{
if (null == _DataEu)
return _DataEu = new List(GetDataFilteredBy(CurrentFilter, DataDisplayUnits.Eu));
return _DataEu;
}
return new List(GetDataFilteredBy(CurrentFilter, DataDisplayUnits.Eu));
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting filtered EU data", ex);
}
}
}
private List _DataEu = null;
///
/// Get an MV-scaled version of the data list.
///
public List UnfilteredDataMv
{
get
{
try
{ //
// If scaled data has yet to be computed, then compute, cache and return it.
// Otherwise just return the cached version.
//
if (null == _UnfilteredDataMv)
{
if (UnfilteredData is ILargeDataAware largeDataAware)
if (!largeDataAware.IsDataArraySized)
throw new Serialization.SliceRaw.File.PersistentChannel.DataTooBigForArrayException("Data is too big to be viewed or filtered.");
if (UnfilteredData is Serialization.SliceRaw.File.PersistentChannel persistentUnfilteredData)
{
_UnfilteredDataMv = new List();
var dataCount = persistentUnfilteredData.Count;
for (var i = 0; i < dataCount; i++)
{
_UnfilteredDataMv.Add(Scaler.GetMv(persistentUnfilteredData[i]));
}
}
else if (UnfilteredData is Serialization.TDAS.File.PersistentChannel tdasUnfilteredData)
{
_UnfilteredDataMv = new List();
var dataCount = tdasUnfilteredData.Count;
for (var i = 0; i < dataCount; i++)
{
_UnfilteredDataMv.Add(Scaler.GetMv(tdasUnfilteredData[i]));
}
}
}
return _UnfilteredDataMv;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting MV-scaled data", ex);
}
}
}
private List _UnfilteredDataMv = null;
///
/// Get/set the filtered MV data for this channel.
///
public List DataMv
{
get
{
try
{
if (UseFilterCaching)
{
if (null == _DataMv)
return _DataMv = new List(GetDataFilteredBy(CurrentFilter, DataDisplayUnits.Mv));
return _DataMv;
}
return new List(GetDataFilteredBy(CurrentFilter, DataDisplayUnits.Mv));
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting filtered MV data", ex);
}
}
}
private List _DataMv = null;
///
/// Get/set the ADC->MV scale factor for this channel.
///
public double ScaleFactorMv
{
get => Scaler.GetScaleFactorMv();
set
{
try
{
Scaler.SetScaleFactorMv(value);
_DataEu = null;
lock (previouslyFilteredDataLock)
{
_previouslyFilteredData.Clear();
}
_UnfilteredDataEu = null;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem setting " + typeof(Channel).Namespace + ".Event.Module.Channel.ScaleFactorMv property value", ex);
}
}
}
public double ScaleFactorEU
{
get => Scaler.GetScaleFactorEU();
set
{
try
{
Scaler.SetScaleFactorEU(value);
_DataEu = null;
lock (previouslyFilteredDataLock)
{
_previouslyFilteredData.Clear();
}
_UnfilteredDataEu = null;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem setting " + typeof(Channel).Namespace + ".Event.Module.Channel.ScaleFactorEU property value", ex);
}
}
}
public double UserOffsetEU
{
get => Scaler.UserOffsetEU;
set
{
Scaler.UserOffsetEU = value;
_DataEu = null;
lock (previouslyFilteredDataLock)
{
_previouslyFilteredData.Clear();
}
_UnfilteredDataEu = null;
}
}
public double Multiplier
{
get => Scaler.Multiplier;
set => Scaler.Multiplier = value;
}
public double UnitConversion
{
get => Scaler.UnitConversion;
set => Scaler.UnitConversion = value;
}
public bool AtCapacity
{
get => Scaler.BasedOnOutputAtCapacity;
set => Scaler.BasedOnOutputAtCapacity = value;
}
public double CapacityOutputIsBasedOn
{
get => Scaler.CapacityOutputIsBasedOn;
set => Scaler.CapacityOutputIsBasedOn = value;
}
public SensorConstants.SensUnits SensitivityUnits
{
get => Scaler.SensitivityUnits;
set => Scaler.SensitivityUnits = value;
}
///
/// Get/set the sensitivity mV/EU factor for this channel.
///
public double MvPerEu
{
set
{
try
{
Scaler.SetMvPerEu(value);
}
catch (System.Exception ex)
{
throw new Exception("encountered problem setting " + typeof(Channel).Namespace + ".Event.Module.Channel.MvPerEu property value", ex);
}
}
}
///
/// putting this in a separate function to force that MvPerEu is not being used directly in calcuations
///
///
public double GetMvPerEu()
{
return Scaler.GetMvPerEu();
}
public double GetScaleFactorMv()
{
return Scaler.GetScaleFactorMv();
}
///
/// Get value indicating whether or not the specified channel is configured.
///
public abstract bool IsConfigured
{
get;
set;
}
///
/// Get the actual available maximum Adc range based on datum bit resolution.
///
public double ActualMaxRangeAdc
{
get
{
try
{
return short.MaxValue;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem calculating actual max ADC range", ex);
}
}
}
///
/// Get the actual available minimum ADC range based on datum bit resolution.
///
public double ActualMinRangeAdc
{
get
{
try
{
return short.MinValue;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem calculating actual min ADC range", ex);
}
}
}
///
/// Get the actual available maximum EU range based on scaling factor and bit resolution.
///
public abstract double ActualMaxRangeEu { get; }
///
/// Get the actual available minimum EU range based on scaling factor and bit resolution.
///
public abstract double ActualMinRangeEu { get; }
public abstract double DesiredRangeEU { get; }
public abstract double SensorCapacityEU { get; }
///
/// Get the actual available maximum MV range based on scaling factor and bit resolution.
///
public virtual double ActualMaxRangeMv
{
get
{
try
{
return (Scaler.GetAdcToMvScalingFactor() >= 0) ? Scaler.GetMv(ActualMaxRangeAdc) : Scaler.GetMv(ActualMinRangeAdc);
}
catch (System.Exception ex)
{
throw new Exception("encountered problem calculating actual max MV range", ex);
}
}
}
///
/// Get the actual available minimum MV range based on scaling factor and bit resolution.
///
public virtual double ActualMinRangeMv
{
get
{
try
{
return (Scaler.GetAdcToMvScalingFactor() >= 0) ? Scaler.GetMv(ActualMinRangeAdc) : Scaler.GetMv(ActualMaxRangeAdc);
}
catch (System.Exception ex)
{
throw new Exception("encountered problem calculating actual min MV range", ex);
}
}
}
///
/// Compute data min and max for this channel.
///
///
///
/// The data min to be populated with
/// the min result of this method.
///
///
///
/// The data max to be populated with
/// the max result of this method.
///
///
private void ComputeDataMinMaxAdc(Property dataMinAdc, Property dataMaxAdc)
{
try
{
if (UnfilteredData is Serialization.TDAS.File.PersistentChannel) //temp
{
ComputeTDASDataMinMaxAdc(dataMinAdc, dataMaxAdc);
}
else
{
var dataCount = (UnfilteredData is Serialization.SliceRaw.File.PersistentChannel persistentChannel)
? persistentChannel.Count // use "persistent channel" count
: UnfilteredData.Count;
if (dataCount <= 0)
throw new Exception("channel has no data");
{
// Find the max and min in raw ADC.
double min, max;
if (!(UnfilteredData is Serialization.SliceRaw.File.PersistentChannel data))
throw new ApplicationException("attempting to use channel data object as memory-mapped file, but it apparently is not one");
min = max = data[0];
for (var i = 1; i < dataCount; i++)
{
min = Math.Min(min, data[i]);
max = Math.Max(max, data[i]);
}
dataMinAdc.Value = min;
dataMaxAdc.Value = max;
}
}
}
catch (System.Exception ex)
{
throw new Exception("encountered problem computing channel data min/max", ex);
}
}
private void ComputeTDASDataMinMaxAdc(Property dataMinAdc, Property dataMaxAdc)
{
try
{
var dataCount = (UnfilteredData is Serialization.TDAS.File.PersistentChannel persistentChannel)
? persistentChannel.Count // use "persistent channel" count
: UnfilteredData.Count;
if (dataCount <= 0)
throw new Exception("channel has no data");
{
// Find the max and min in raw ADC.
double min, max;
if (!(UnfilteredData is Serialization.TDAS.File.PersistentChannel data))
throw new ApplicationException("attempting to use channel data object as memory-mapped file, but it apparently is not one");
min = max = data[0];
for (var i = 1; i < dataCount; i++)
{
min = Math.Min(min, data[i]);
max = Math.Max(max, data[i]);
}
dataMinAdc.Value = min;
dataMaxAdc.Value = max;
}
}
catch (System.Exception ex)
{
throw new Exception("encountered problem computing channel data min/max", ex);
}
}
///
/// Compute the min and max values in the given data vector.
///
///
///
/// Returns the minimum data value in the specified data vector.
///
///
///
/// Returns the maximum data value in the specified data vector.
///
///
///
/// The array of s to be scoured for min and max values.
///
///
private void ComputeDataMinMax(out double dataMin, out double dataMax, double[] data)
{
try
{
if (null == data)
throw new ArgumentException("cannot process null data reference");
if (data.Length <= 0)
throw new ArgumentException("cannot process empty data vector");
dataMin = dataMax = data[0];
for (var i = 0; i < data.Length; i++)
{
dataMin = Math.Min(dataMin, data[i]);
dataMax = Math.Max(dataMax, data[i]);
}
}
catch (System.Exception ex)
{
throw new Exception("encountered problem computing data vector min/max", ex);
}
}
///
/// Get the data min in ADC.
///
public double DataMinAdc
{
get
{
try
{
if (!_DataMinAdc.IsInitialized)
ComputeDataMinMaxAdc(_DataMinAdc, _DataMaxAdc);
return _DataMinAdc.Value;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting " + typeof(Channel).Namespace + ".Event.Module.Channel.DataMinAdc", ex);
}
}
}
private readonly Property _DataMinAdc
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.DataMinAdc",
0.0,
false
);
///
/// Get the data min in EU.
///
public abstract double DataMinEu { get; }
///
/// Get the data min in MV.
///
public double DataMinMv => (Scaler.GetAdcToMvScalingFactor() >= 0) ?
Scaler.GetMv(DataMinAdc) :
Scaler.GetMv(DataMaxAdc);
///
/// Get the data max in ADC.
///
public double DataMaxAdc
{
get
{
try
{
if (!_DataMaxAdc.IsInitialized)
ComputeDataMinMaxAdc(_DataMinAdc, _DataMaxAdc);
return _DataMaxAdc.Value;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting " + typeof(Channel).Namespace + ".Event.Module.Channel.DataMaxAdc", ex);
}
}
}
private readonly Property _DataMaxAdc
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.DataMaxAdc",
0.0,
false
);
///
/// Get the data max in EU.
///
public abstract double DataMaxEu { get; }
///
/// Populate the specified filter-index'd dictionaries with the min/max values for the
/// specified filter setting.
///
///
///
/// The -indexed Dictionary of
/// data min values.
///
///
///
/// The -indexed Dictionary of
/// data max values.
///
///
///
/// The to be applied to the the channel's data prior to
/// the min/max calculation.
///
///
private void PopulateFilteredMinMaxValues(IDictionary filteredMins,
IDictionary filteredMaxs,
ChannelFilter filter)
{
try
{
ComputeDataMinMax(out double min, out double max, CurrentFilter.Apply(this, DataDisplayUnits.Eu, Serialization.File.UseLegacyTDCSoftwareFiltering));
filteredMins[CurrentFilter.CutoffFrequencyHz] = min;
filteredMaxs[CurrentFilter.CutoffFrequencyHz] = max;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem propulating filtered min/max values", ex);
}
}
///
/// Get the minimum EU data value for the current filtering.
///
public double DataMinFilteredEu
{
get
{
try
{
if (!_DataMinFilteredEu.Keys.Contains(CurrentFilter.CutoffFrequencyHz))
PopulateFilteredMinMaxValues(_DataMinFilteredEu, _DataMaxFilteredEu, CurrentFilter.Type);
return _DataMinFilteredEu[CurrentFilter.CutoffFrequencyHz];
}
catch (System.Exception ex)
{
throw new Exception(
"encountered problem getting min filtered EU on DAS: " + ((null != ParentModule && null != ParentModule.DasSerialNumber) ? ParentModule.DasSerialNumber : "") + ", Channel: " + Number.ToString(),
ex
);
}
}
}
private readonly IDictionary _DataMinFilteredEu
= new Dictionary();
///
/// Get the maximum EU data value for the current filtering.
///
public double DataMaxFilteredEu
{
get
{
try
{
if (!_DataMaxFilteredEu.Keys.Contains(CurrentFilter.CutoffFrequencyHz))
PopulateFilteredMinMaxValues(_DataMinFilteredEu, _DataMaxFilteredEu, CurrentFilter.Type);
return _DataMaxFilteredEu[CurrentFilter.CutoffFrequencyHz];
}
catch (System.Exception ex)
{
throw new Exception(
"encountered problem getting max filtered EU on DAS: " + ((null != ParentModule && null != ParentModule.DasSerialNumber) ? ParentModule.DasSerialNumber : "") + ", Channel: " + Number.ToString(),
ex
);
}
}
}
private readonly IDictionary _DataMaxFilteredEu
= new Dictionary();
///
/// Get the data max in MV.
///
public double DataMaxMv => (Scaler.GetAdcToMvScalingFactor() >= 0) ?
Scaler.GetMv(DataMaxAdc) :
Scaler.GetMv(DataMinAdc);
///
/// Get the data range of this channel in ADC.
///
public double DataRangeAdc
{
get
{
try
{
if (!_DataRangeAdc.IsInitialized)
return _DataRangeAdc.Value = DataMaxAdc - DataMinAdc;
return _DataRangeAdc.Value;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting " + typeof(Channel).Namespace + ".Event.Module.Channel.DataRangeAdc", ex);
}
}
}
private readonly Property _DataRangeAdc
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.DataRangeAdc",
0.0,
false
);
///
/// Get the data range in EU.
///
public abstract double DataRangeEu { get; }
///
/// Get the data range in MV.
///
public double DataRangeMv => Math.Abs(Scaler.GetMv(DataRangeAdc));
///
/// Get the data range/2 of this channel in ADC.
///
public double DataHalfRangeValueAdc
{
get
{
try
{
if (!_DataHalfRangeValueAdc.IsInitialized)
return _DataHalfRangeValueAdc.Value = (DataMaxAdc + DataMinAdc) / 2;
return _DataHalfRangeValueAdc.Value;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting " + typeof(Channel).Namespace + ".Event.Module.Channel.DataMeanAdc", ex);
}
}
}
private readonly Property _DataHalfRangeValueAdc
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.DataHalfRangeValueAdc",
0.0,
false
);
///
/// Get the data range/2 in EU.
///
public abstract double DataHalfRangeValueEu { get; }
///
/// Get the data range/2 in MV.
///
public double DataHalfRangeValueMv => Scaler.GetMv(DataHalfRangeValueAdc);
///
/// Get/set noise as percentage of full scale value for this channel.
///
public double NoiseAsPercentageOfFullScale
{
get => _NoiseAsPercentageOfFullScale.Value;
set => _NoiseAsPercentageOfFullScale.Value = value;
}
private readonly Property _NoiseAsPercentageOfFullScale
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.NoiseAsPercentageOfFullScale",
0.0,
false
);
///
/// Get the pre-test zero level (in ADC).
///
public short PreTestZeroLevelAdc
{
get => _PreTestZeroLevelAdc.Value;
set => _PreTestZeroLevelAdc.Value = value;
}
private readonly Property _PreTestZeroLevelAdc
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.PreTestZeroLevelAdc",
0,
false
);
//zeroMvInADC
public short ZeroMvInADC
{
get => _ZeroMvInADC.Value;
set => _ZeroMvInADC.Value = value;
}
private readonly Property _ZeroMvInADC
= new Property(
typeof(Channel).Name + ".Event.Module.Channel.ZeroMvInADC",
0,
false
);
///
/// Window Average ADC is the average ADC over the zeroing window specified for the channel
/// short.MinValue indicates an invalid or uninitialized value
///
public short WindowAverageADC
{
get => _WindowAverageADC.Value;
set => _WindowAverageADC.Value = value;
}
private readonly Property _WindowAverageADC
= new Property(
typeof(Channel).Name + ".Event.Module.Channel.WindowAverageADC",
short.MinValue,
false
);
///
/// Get the pre-test zero level (in ADC).
///
public double PreTestZeroLevelMv
{
get
{
if (_PreTestZeroLevelMv.IsValueInitialized)
{
return _PreTestZeroLevelMv.Value;
}
return 0D;
}
set => _PreTestZeroLevelMv.Value = value;
}
private readonly Property _PreTestZeroLevelMv
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.PreTestZeroLevelMv",
0D,
true
);
public int RemovedADC
{
get
{
if (_removedADC.IsValueInitialized)
{
return _removedADC.Value;
}
return 0;
}
set
{
_removedADC.Value = value;
Scaler.SetRemovedADC(value);
}
}
private readonly Property _removedADC
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.RemovedADC",
0,
true
);
public int RemovedInternalADC
{
get
{
if (_removedInternalADC.IsValueInitialized)
{
return _removedInternalADC.Value;
}
return 0;
}
set
{
_removedInternalADC.Value = value;
Scaler.SetRemovedInternalADC(value);
}
}
private readonly Property _removedInternalADC
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.RemovedInternalADC",
0,
true
);
///
/// the order of this channel among all channels when displaying channels
/// AbsoluteNumber on the other hand refers to physical order
/// -1 is an uninitialized value, which means channels will be sorted by AbsoluteNumber instead
///
public int AbsoluteDisplayOrder
{
get
{
if (_absoluteDisplayOrder.IsValueInitialized) { return _absoluteDisplayOrder.Value; }
return -1;
}
set => _absoluteDisplayOrder.Value = value;
}
private readonly Property _absoluteDisplayOrder = new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.AbsoluteDisplayOrder",
-1,
true);
///
/// Get data zero level counts.
///
public abstract short DataZeroLevelAdc
{
get;
}
///
/// Get/Set channel Last Calibration Date
///
public DateTime LastCalibrationDate
{
get => _LastCalibrationDate.Value;
set => _LastCalibrationDate.Value = value;
}
private readonly Property _LastCalibrationDate
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.LastCalibrationDate",
(DateTime)System.Data.SqlTypes.SqlDateTime.MinValue,
true
);
public bool IsLastCalibrationDateValid => _LastCalibrationDate.IsInitialized;
///
/// Get/Set channel Last Calibration Date
///
public DateTime CalDueDate
{
get => _CalDueDate.Value;
set => _CalDueDate.Value = value;
}
private readonly Property _CalDueDate
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.CalDueDate",
(DateTime)System.Data.SqlTypes.SqlDateTime.MinValue,
true
);
public bool IsCalDueDateValid => _CalDueDate.IsInitialized;
public string SensorID
{
get => _SensorID.Value;
set => _SensorID.Value = value;
}
private readonly Property _SensorID
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.SensorID",
"",
true
);
public bool IsSensorIDValid => _SensorID.IsInitialized;
public double OffsetToleranceLowMv
{
get => _offsetToleranceLowMv.Value;
set => _offsetToleranceLowMv.Value = value;
}
private readonly Property _offsetToleranceLowMv
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.OffsetToleranceLowMv",
0D,
true
);
public bool IsOffsetToleranceLowMvValid => _offsetToleranceLowMv.IsInitialized;
public double OffsetToleranceHighMv
{
get => _offsetToleranceHighMv.Value;
set => _offsetToleranceHighMv.Value = value;
}
private readonly Property _offsetToleranceHighMv
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.OffsetToleranceHighMv",
0D,
true
);
public bool IsOffsetToleranceHighMvValid => _offsetToleranceHighMv.IsInitialized;
public string IsoChannelName
{
get => _isoChannelName.Value;
set => _isoChannelName.Value = value;
}
private readonly Property _isoChannelName
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.IsoChannelName",
"",
true
);
public bool IsIsoChannelNameValid => _isoChannelName.IsInitialized;
public string UserCode
{
get => _userCode.Value;
set => _userCode.Value = value;
}
private readonly Property _userCode
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.UserCode",
"",
true
);
public bool IsUserCodeValid => _userCode.IsInitialized;
public string UserChannelName
{
get => _userChannelName.Value;
set => _userChannelName.Value = value;
}
private readonly Property _userChannelName
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.UserChannelName",
"",
true
);
public string LinearSensorCalibration
{
get => _linearSensorCalibration.Value;
set => _linearSensorCalibration.Value = value;
}
private readonly Property _linearSensorCalibration
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.LinearSensorCalibration",
"",
true
);
public bool IsUserChannelNameValid => _userChannelName.IsInitialized;
///
/// Get/set channel subsample indicator.
///
public bool IsSubsampled
{
get => _IsSubsampled.Value;
set => _IsSubsampled.Value = value;
}
private readonly Property _IsSubsampled
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.IsSubsampled",
false,
true
);
///
/// Get/set channel unsubsampled sample rate.
///
public float UnsubsampledSampleRateHz
{
get => _UnsubsampledSampleRateHz.Value;
set => _UnsubsampledSampleRateHz.Value = value;
}
private readonly Property _UnsubsampledSampleRateHz
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.UnsubsampledSampleRateHz",
0,
true
);
///
/// Get/set the sample rate for this test module.
///
public bool IsSupersampled
{
get => _IsSupersampled.Value;
set => _IsSupersampled.Value = value;
}
private readonly Property _IsSupersampled
= new Property(
typeof(Module).Namespace + ".Event.Module.Channel.IsSupersampled",
false,
false
);
///
/// Get/set whether viewing and exporting this channel should use the EU Scalar.
///
public bool UseEUScaler
{
get => _UseEUScalar.Value;
set => _UseEUScalar.Value = value;
}
private readonly Property _UseEUScalar
= new Property(
typeof(Module).Namespace + ".Event.Module.Channel.UseEUScaler",
false,
false
);
///
/// Get/set the sample rate for this test module.
///
public float UnsupersampledSampleRateHz
{
get => _UnsupersampledSampleRateHz.Value;
set => _UnsupersampledSampleRateHz.Value = value;
}
private readonly Property _UnsupersampledSampleRateHz
= new Property(
typeof(Module).Namespace + ".Event.Module.Channel.UnsupersampledSampleRateHz",
0,
false
);
public void ClearDataCache()
{
var filtering = UseFilterCaching;
_Data = null;
_DataEu = null;
_DataMv = null;
_UnfilteredDataEu = null;
_DataADC = null;
lock (previouslyFilteredDataLock)
{
_previouslyFilteredData.Clear();
}
UseFilterCaching = filtering;
}
///
/// Create the matching Event.Module.Channel-based representation of the specified
/// DTS.DASLib.Service.DASChannel-based object.
///
///
///
/// The object to be represented.
///
///
///
/// The that contains the created channel.
///
///
///
/// The -based representation of the specified
/// channel object.
///
///
///
/// The unique "absolute" number of the channel with respect to all other channels
/// on all other DASes in the system.
///
///
public static Channel CreateChannel(DASChannel channel, Module parentModule, int absoluteNumber)
{
try
{
switch (channel.GetType().FullName)
{
case "DTS.DASLib.Service.AnalogInputDASChannel":
return new AnalogInputChannel(channel, parentModule, absoluteNumber);
case "DTS.DASLib.Service.IEPEChannel":
return new IEPEInputChannel(channel, parentModule, absoluteNumber);
case "DTS.DASLib.Service.OutputSquibChannel":
{
var osc = channel as OutputSquibChannel;
var output = new SquibEventChannel(channel, parentModule, absoluteNumber);
output.MeasurementType = osc.MeasurementType;
output.ChannelName2 = osc.ChannelName2;
if (osc.MeasurementType == SquibMeasurementType.CURRENT)
{
if (osc.SquibDescription.EndsWith(".1"))
{
var newName = osc.SquibDescription.Substring(0,
osc.SquibDescription.Length - 2);
newName += ".2";
output.ChannelName2 = output.ChannelName2.Replace(osc.SquibDescription, newName);
}
}
output.ChannelId = osc.ChannelId;
output.Sensor = osc.Sensor;
output.SerialNumber = osc.SerialNumber;
output.ChannelGroupName = osc.ChannelGroupName;
return output;
}
case "DTS.DASLib.Service.OutputTOMDigitalChannel":
{
return new SquibDigitalChannel(channel, parentModule, absoluteNumber);
}
case "DTS.DASLib.Service.TimestampDASChannel":
{
return new TimestampChannel(channel, parentModule, absoluteNumber);
}
case "DTS.DASLib.Service.StreamInputDASChannel":
{
return new StreamInputChannel(channel, parentModule, absoluteNumber);
}
default:
throw new NotImplementedException("cannot create a " + typeof(Channel).FullName + "-based representation of a " + channel.GetType().FullName + " object");
}
}
catch (System.Exception ex)
{
throw new ApplicationException("encountered problem creating channel", ex);
}
}
///
/// Create the matching Event.Module.Channel-based representation of the specified
/// DTS.DASLib.Service.DASChannel-based object.
///
///
///
/// The object to be represented.
///
///
///
/// The that contains the created channel.
///
///
///
/// The -based representation of the specified
/// channel object.
///
///
///
/// The unique "absolute" number of the channel with respect to all other channels
/// on all other DASes in the system.
///
///
public static Channel CreateChannel(Serialization.Test.Module.Channel channel, Module parentModule, int absoluteNumber)
{
try
{
switch (channel.GetType().FullName)
{
case "DTS.Serialization.Test+Module+AnalogInputChannel":
return new AnalogInputChannel(channel, parentModule, absoluteNumber);
case "DTS.Serialization.Test+Module+CalculatedChannel":
return new AnalogInputChannel(channel, parentModule, absoluteNumber);
default:
throw new NotImplementedException("cannot create a " + typeof(Channel).FullName + "-based representation of a " + channel.GetType().FullName + " object");
}
}
catch (System.IO.InvalidDataException ex2) { throw ex2; }
catch (System.Exception ex)
{
throw new ApplicationException("encountered problem creating channel", ex);
}
}
///
/// Set the appropriate properties in this class from the equivalent properties
/// of the specified object.
///
///
///
/// The object containing the
/// property values to be copied.
///
///
public abstract void SetPropertyValuesFrom(DASChannel dasChannel);
///
/// Set the appropriate properties in this class from the equivalent properties
/// of the specified object.
///
///
///
/// The object containing the
/// property values to be copied.
///
///
public virtual void SetPropertyValuesFrom(IDiagnosticResult diagResults)
{
try
{
if (null == diagResults)
throw new ArgumentNullException("cannot set property values from null " + typeof(DiagnosticsResult).FullName);
ScaleFactorEU = diagResults.ScalefactorEngineeringUnitsPerADC;
ScaleFactorMv = diagResults.ScalefactorMilliVoltsPerADC;
if (this is AnalogInputChannel)
{
Scaler.IEPE = (this as AnalogInputChannel).Bridge == SensorConstants.BridgeType.IEPE;
}
try
{
if (this is AnalogInputChannel)
{
Scaler.Digital = (this as AnalogInputChannel).Bridge == SensorConstants.BridgeType.DigitalInput;
}
else { Scaler.Digital = false; }
}
catch (System.Exception) { }
if (this is IShuntAware)
{
if (null != diagResults.MeasuredShuntDeflectionMv)
(this as IShuntAware).MeasuredShuntDeflectionMv = (double)diagResults.MeasuredShuntDeflectionMv;
if (null != diagResults.TargetShuntDeflectionMv)
(this as IShuntAware).TargetShuntDeflectionMv = (double)diagResults.TargetShuntDeflectionMv;
}
if (this is ICalSignalAware)
{
if (null != diagResults.MeasuredCalSignalMv)
(this as ICalSignalAware).MeasuredCalSignalMv = (double)diagResults.MeasuredCalSignalMv;
if (null != diagResults.TargetCalSignalMv)
(this as ICalSignalAware).TargetCalSignalMv = (double)diagResults.TargetCalSignalMv;
}
try
{
NoiseAsPercentageOfFullScale = null != diagResults.NoisePercentFullScale ? (double)diagResults.NoisePercentFullScale : 0.0;
}
catch (InvalidOperationException)
{
throw new UserException("Diagnostics service did not return a value for requested \"noise as percentage of full scale\" statistic");
}
if (null != diagResults.FinalOffsetADC)
{
try
{
PreTestZeroLevelAdc = (short)diagResults.FinalOffsetADC;
}
catch (InvalidOperationException)
{
throw new UserException("Diagnostics service did not return a value for requested \"final offset\" statistic");
}
}
else
{
PreTestZeroLevelAdc = 0;
}
ZeroMvInADC = Convert.ToInt16(diagResults.ZeroMVInADC);
WindowAverageADC = Convert.ToInt16(diagResults.WindowAverageADC);
if (null != diagResults.MeasuredOffsetMilliVolts)
{
try
{
PreTestZeroLevelMv = (double)diagResults.MeasuredOffsetMilliVolts;
}
catch (InvalidOperationException)
{
/*throw new UserException( "diagnostics service did not return a value for requested \"measured offset\" statistic" ); */
PreTestZeroLevelMv = 0D;
}
}
else { PreTestZeroLevelMv = 0D; }
}
catch (System.Exception ex)
{
throw new Exception("encountered problem setting property value from " + (null != diagResults ? diagResults.GetType().FullName : "<>") + " object", ex);
}
try
{
if (null != diagResults.RemovedOffsetADC)
{
RemovedADC = (short)diagResults.RemovedOffsetADC;
}
else { RemovedADC = 0; }
}
catch (System.Exception) { }
}
/////
///// Get the list of available filters.
/////
public List AvailableFilters => _AvailableFilters.Value;
private readonly Property> _AvailableFilters
= new Property>(
typeof(Channel).Namespace + ".Event.Module.Channel.AvailableFilters",
new List(),
true
);
///
/// Get/set the default filter for this channel.
///
public IFilter CurrentFilter
{
get => _CurrentFilter.Value;
set
{ //
// Might be lots of gratuitous "changing" of filter to the same value, since
// last I checked it happens every time you flip from one channel to another
// in the data viewer. Anyway, if nothing has changed, don't force a reload
// of the cached data.
//
if (_CurrentFilter.Value == null
|| !value.Name.Equals(_CurrentFilter.Value.Name, StringComparison.OrdinalIgnoreCase))
{ //
// Clear filtered data caches and set new filter value.
//
_Data = null;
_DataEu = null;
_DataMv = null;
_CurrentFilter.Value = value;
}
}
}
private readonly Property _CurrentFilter = new Property(typeof(Channel).Namespace + ".Event.Module.Channel.CurrentFilter",
null,
true
);
///
/// Get/set the default filter for this channel.
///
public IFilter DefaultFilter
{
get => _defaultFilter.Value;
set
{
if (_defaultFilter.Value == null || !value.Name.Equals(_defaultFilter.Value.Name, StringComparison.OrdinalIgnoreCase))
{
_Data = null;
_DataEu = null;
_DataMv = null;
_defaultFilter.Value = value;
}
}
}
private readonly Property _defaultFilter = new Property(typeof(Channel).Namespace + ".Event.Module.Channel.DefaultFilter", null, true);
public string FileName
{
get => _FileName.Value;
set => _FileName.Value = value;
}
private readonly Property _FileName
= new Property(
typeof(Channel).Namespace + ".Event.Module.Channel.FileName",
"",
true
);
protected static readonly object DisplayUnitLock = new object();
protected static readonly object previouslyFilteredDataLock = new object();
public void UnSet()
{
if (null != _previouslyFilteredData) { _previouslyFilteredData.Clear(); }
if (null != _DataEu) { _DataEu.Clear(); _DataEu = null; }
if (null != _UnfilteredDataEu) { _UnfilteredDataEu.Clear(); _UnfilteredDataEu = null; }
System.Runtime.GCSettings.LatencyMode = System.Runtime.GCLatencyMode.Batch;
System.Runtime.GCSettings.LargeObjectHeapCompactionMode = System.Runtime.GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
}
///
/// Get the channel data after filtering by the specified filter.
///
///
///
/// The to be applied to the channel.
///
///
///
/// The requested filtered channel data.
///
///
public double[] GetDataFilteredBy(IFilter filter, DataDisplayUnits displayUnits)
{
try
{
double[] filteredData;
if (UseFilterCaching)
{
IDictionary displayUnitData;
lock (previouslyFilteredDataLock)
{
if (!_previouslyFilteredData.Keys.Contains(filter.Name))
_previouslyFilteredData.Add(filter.Name, new Dictionary());
// First cache key should now exist, so work it, baby!
displayUnitData = _previouslyFilteredData[filter.Name];
}
lock (DisplayUnitLock)
{
if (displayUnitData.Keys.Contains(displayUnits))
filteredData = displayUnitData[displayUnits];
else
{
try
{
displayUnitData.Add(displayUnits, filteredData = filter.Apply(this, displayUnits, Serialization.File.UseLegacyTDCSoftwareFiltering));
}
catch (System.Exception ex)
{
throw new Exception("encountered problem adding; displayUnits " + displayUnits, ex);
}
}
}
}
else filteredData = filter.Apply(this, displayUnits, Serialization.File.UseLegacyTDCSoftwareFiltering);
// By hook or crook, filter data should be here.
return filteredData;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting data filtered by channel filter " + (null != filter && null != filter.Name ? "\"" + filter.Name + "\"" : ""), ex);
}
}
private readonly IDictionary> _previouslyFilteredData
= new Dictionary>();
///
/// Test the specified object for equality with this object.
///
///
///
/// The to be tested for equality.
///
///
///
/// true if the specified object has memeberwise equality with
/// this object; false otherwise.
///
///
public override bool Equals(object obj)
{
try
{
var that = obj as Channel;
return null != obj
&& DataEquals(that.UnfilteredData)
&& Number.Equals(that.Number)
&& PreTestZeroLevelAdc.Equals(that.PreTestZeroLevelAdc)
&& IsSubsampled.Equals(that.IsSubsampled)
&& UnsubsampledSampleRateHz.Equals(that.UnsubsampledSampleRateHz)
&& IsSupersampled.Equals(that.IsSupersampled)
&& UseEUScaler.Equals(that.UseEUScaler)
&& UnsupersampledSampleRateHz.Equals(that.UnsupersampledSampleRateHz)
&& _TimeOfFirstSampleSec.IsInitialized == that._TimeOfFirstSampleSec.IsInitialized && (TimeOfFirstSampleSecValid ? TimeOfFirstSampleSec == that.TimeOfFirstSampleSec : true)
&& Start.ToString().Equals(that.Start.ToString())
&& (ZeroMvInADC == that.ZeroMvInADC)
&& (WindowAverageADC == that.WindowAverageADC)
&& (UserCode == that.UserCode)
&& (IsoChannelName == that.IsoChannelName)
&& (UserChannelName == that.UserChannelName);
}
catch (System.Exception ex)
{
throw new Exception(
string.Format(
Strings.DTS_Slice_Control_Equals_ComparisonFailedString, null != obj ? "\"" + obj.ToString() + "\"" : Strings.DTS_Slice_Control_Event_Event_NullDasListString),
ex);
}
}
///
/// Test the specified object's data list for equality with this object's
/// data list.
///
///
///
/// The List of data objects to be compared
/// for equality with this module's equivalent.
///
///
///
/// true if the two lists contain equivalent-valued members;
/// false otherwise.
///
///
private bool DataEquals(List thoseData)
{
try
{
if (null == thoseData || Data.Count != thoseData.Count)
return false;
for (var i = 0; i < thoseData.Count; i++)
if (!UnfilteredData[i].Equals(thoseData[i]))
return false;
return true;
}
catch (System.Exception ex)
{
throw new Exception(Strings.DTS_Slice_Control_Event_Module_Channel_DataEquals_ComparisonFailedString, ex);
}
}
///
/// Return the hash code for this object.
///
///
///
/// The hash code for this object.
///
///
public override int GetHashCode()
{
try
{
return base.GetHashCode();
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting has code for " + GetType().FullName, ex);
}
}
///
/// Convert this object to a DTS.Serialization.Test.Module.Channel.
///
///
///
/// A equivalent for this object.
///
///
public abstract Serialization.Test.Module.Channel ToDtsSerializationTestModuleChannel(Serialization.Test.Module parentModule);
///
/// Initialize this object from the specified DTS.Serialization.Test.Module.Channel.
///
///
///
/// A from which to initialize this object.
///
///
public abstract void FromDtsSerializationTestModuleChannel(Serialization.Test.Module.Channel that);
}
}
}
}