Files
2026-04-17 14:55:32 -04:00

12 KiB

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Graph/Model/TestDataSeries.cs
DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Graph/Model/TestDataSeriesModel.cs
2026-04-16T11:14:33.699820+00:00 zai-org/GLM-5-FP8 1 1630e6f30be700ba

Documentation: DTS.Viewer.Graph Module - Data Series Models

1. Purpose

This module provides the data models for representing and transforming test channel data into graphable series within the DTS Viewer application. TestDataSeries serves as the primary data transfer object holding X/Y values, metadata, and computed statistics for a single graphable channel. TestDataSeriesModel acts as a factory/processor that transforms raw ITestChannel data into TestDataSeries objects, handling time-series, FFT (Fast Fourier Transform), and PSD (Power Spectral Density) conversions with optional filtering and windowing. Together, they bridge the gap between raw binary sensor data and the visualization layer.


2. Public Interface

TestDataSeries Class

Namespace: DTS.Viewer.Graph.Model
Inherits: Common.Base.BasePropertyChanged
Implements: ITestDataSeries

Properties

Property Type Description
HIC bool Indicates if Head Injury Criteria data is present.
HICValue string Formatted HIC value.
T1Time, T2Time string T1/T2 timestamp strings for HIC calculations.
TestGroup string Group identifier for the test.
TestId string Unique test identifier.
TestSetupName string Name of the test setup configuration.
ChannelId string Channel identifier.
Xvalue double[] Array of X-axis values (time or frequency).
Yvalue double[] Array of Y-axis values (amplitude, magnitude, or PSD).
GraphColor Brush WPF brush for graph rendering; getter creates new SolidColorBrush from internal byte[].
HardwareChannel string Hardware channel name (auto-property).
GroupName string Channel group name (auto-property).
SWAAF string Software anti-aliasing filter setting (auto-property).
Bridge string Bridge type identifier (auto-property).
HWAAF string Hardware anti-aliasing filter rate (auto-property).
SampleRate string Sample rate in Hz (auto-property).
ISOCode, ISOChannelName string ISO-related identifiers (auto-properties).
UserCode, UserChannelName string User-defined identifiers (auto-properties).
ChannelName, Description string Channel naming and description (auto-properties).
SensorSN string Sensor serial number (auto-property).
SensorSNDisplay string Display-friendly serial number; returns "N/A" if test-specific embedded per SensorConstants.IsTestSpecificEmbedded().
EngineeringUnits string Engineering units string (auto-property).
Excitation string Excitation voltage (auto-property).
Polarity string Sensor polarity (auto-property).
MinY, MaxY, AvgY, StdDevY string Statistical values; default to Strings.Table_NA.
PeakMagnitude double Peak magnitude for FFT data; default 0.
PeakFrequency double Frequency of peak magnitude; default 0.
GRMS double Root-mean-squared acceleration for PSD; default 0.
FFT bool Indicates if series contains FFT/PSD data; default false.
T0EUValue string T0 value string; default empty.
RecordingMode string Recording mode description (auto-property).
IsSaved bool Read-only auto-property (getter only).

Methods

public void SetStatsFromYValues()

Sets AvgY, StdDevY, MinY, MaxY, T0EUValue from internal Yvalue array. Formats using "G5" format string.

public void SetStatsFromYValues(double[] values)

Overload that accepts an external double[] array. Handles null/empty arrays by setting all stats to NaN (displayed as Table_NA).

public void SetStatsFromChannel(ITestChannel channel)

Copies pre-calculated statistics from an ITestChannel instance using channel.MinY, channel.MaxY, channel.AveY, channel.StdDevY, channel.T0Value.


TestDataSeriesModel Class

Namespace: DTS.Viewer.Graph
Implements: IBaseModel

Properties

Property Type Description
Parent IGraphViewModel Parent view model reference.
_eventAggregator IEventAggregator Prism event aggregator for publishing progress events.
ErrorMessage string Error message string with property change notification.
IsSaved bool Read-only auto-property.

Methods

public Task<ITestDataSeries> GetTestDataAsync(ITestChannel channel, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null)

Async wrapper returning GetTestData(). Warning: Lacks await operators (runs synchronously per compiler warning suppression).

public Task<List<ITestDataSeries>> GetTestDataAsync(List<ITestChannel> channels, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null)

Async wrapper for batch channel processing. Catches OutOfDataException and re-throws with context. Optionally adds envelope channel if psdSettings.ShowEnvelope is true.

public List<ITestDataSeries> GetTestData(List<ITestChannel> channels, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null)

Synchronous batch processing. Maps each channel through GetTestData(). Handles OutOfDataException with sample index context.

public ITestDataSeries GetTestData(ITestChannel channel, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null)

Returns AddTestChannelToChart() result.

public TestDataSeries AddTestChannelToChart(ITestChannel channel, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null)

Primary processing method. Reads binary channel data via Serialization.SliceRaw.File.Reader.ReadChannelsBinaryData(), then branches based on chartOptions.UnitType:

  • FFT mode (ChartUnitTypeEnum.FFT with psdSettings == null): Sets FFT = true, populates PeakFrequency, PeakMagnitude, calculates stats.
  • Regular time-series (psdSettings == null): Handles HIC data if present, applies time unit multiplier, copies stats from channel.
  • PSD mode (psdSettings != null): Trims data to selected range, applies optional low/high pass filters, computes PSD via FftSharp.Transform.PSD_Welch(), calculates GRMS.

Returns null if channel.ErrorMessage is not empty.

private ITestDataSeries GetEnvelopeChannel(List<ITestDataSeries> data)

Creates a synthetic "envelope" series by taking the maximum Y-value at each frequency index across all input series. Sets FFT = true, color to black.

private double CalculateGRMS(double[] freq, double[] psd)

Calculates Grms using numerical integration of PSD. Uses logarithmic interpolation formula; handles N = -1 edge case separately. Returns Math.Sqrt(aRMS.Sum()).


3. Invariants

  1. Array Length Consistency: Xvalue and Yvalue arrays should have matching lengths after processing by TestDataSeriesModel.

  2. FFT Flag Consistency: When FFT == true, Xvalue represents frequency (Hz) and Yvalue represents magnitude or PSD. When FFT == false, Xvalue represents time.

  3. Statistics Default: MinY, MaxY, AvgY default to Strings.Table_NA (not null or empty string).

  4. GraphColor Thread Safety: GraphColor getter creates a new SolidColorBrush on each call; the underlying color data is stored as byte[] _graphColorARGB to ensure thread safety (per comment referencing issue #34455).

  5. FFT/PSD Filter Bypass: When chartOptions.UnitType is FFT or PSD, channel.SoftwareFilter is forcibly set to "none" before reading data.

  6. PSD Data Length: PSD calculations require input length to be an even power of 2; Utils.GetEnclosingPower2() is used to resize the array with zero-padding if necessary.

  7. HIC Validity: HIC is only set to true when channel.HIC != 0 AND channel.T2Sample > 0.


4. Dependencies

TestDataSeries Dependencies

External Dependencies:

  • System.Windows.Media - Brush, SolidColorBrush, Color, Colors
  • DTS.Common.Enums.Sensors - SensorConstants for serial number validation
  • DTS.Common.Interface - ITestDataSeries interface
  • DTS.Common.Strings - Localized string constants (Table_NA)
  • DTS.Common.Base - BasePropertyChanged for INPC implementation

Dependents (Inferred):

  • TestDataSeriesModel - Primary consumer/factory
  • Graph view models and charting components (via ITestDataSeries)

TestDataSeriesModel Dependencies

External Dependencies:

  • System.Windows.Media - Color types
  • Prism.Events - IEventAggregator for event publishing
  • FftSharp - FFT/PSD transforms (Transform.PSD_Welch, Transform.FFTfreq, WindowType, WindowAveragingType)
  • Exocortex.DSP - PassFilter.LowPass/HighPass filtering

Internal Dependencies:

  • DTS.Common.Interface - ITestChannel, ITestDataSeries, IGraphViewModel, IChartOptionsModel, IPSDReportSettingsModel, IBaseModel
  • DTS.Common.Enums.Viewer - ChartUnitTypeEnum, TimeUnitTypeEnum, Reports.WindowType, Reports.WindowAveragingType
  • DTS.Common.Enums.Sensors - SensorConstants.BridgeType.DigitalInput
  • DTS.Common.Enums.DASFactory - DFConstantsAndEnums.RecordingMode
  • DTS.Common.Converters - EnumDescriptionTypeConverter
  • DTS.Common.Exceptions - OutOfDataException
  • DTS.Common.Events - GraphChannelReadCalcProgressChangedEvent, GraphChannelReadCalcProgressChangedEventArgs
  • DTS.Common.Utilities.Logging - APILogger
  • DTS.Common.Utils - Utils.GetEnclosingPower2()
  • DTS.Common.Strings - Localized strings
  • Serialization.SliceRaw.File.Reader - ReadChannelsBinaryData() for binary data deserialization
  • ChannelFilter - AdHoc filter constant

Dependents (Inferred):

  • Graph view models implementing IGraphViewModel
  • PSD report generation components

5. Gotchas

  1. Async Methods Are Not Truly Async: Both GetTestDataAsync overloads have suppressed compiler warning CS1998 and run synchronously. The async keyword is misleading—these methods will block the calling thread.

  2. GraphColor Getter Allocates on Every Call: The GraphColor property getter instantiates a new SolidColorBrush on every access. Frequent access in UI binding scenarios could cause unnecessary allocations.

  3. PSD Frequency Array Mutation: In PSD processing, freq[0] = 1 forcibly sets the first frequency bin to 1 Hz, potentially overwriting the actual DC component value from FftSharp.Transform.FFTfreq().

  4. CalculateStdDev Uses Population Formula Incorrectly: The method divides by (values.Length - 1) (sample standard deviation) but does not check for single-element arrays, which would cause division by zero.

  5. T0EUValue Naming Is Misleading: Per the source comment: "this is the T0 value regardless of units ... it's not really EU but since it's already in use I'm not going to change it" — historical naming debt.

  6. Envelope Channel Returns Empty Series on Null Input: GetEnvelopeChannel() returns a default TestDataSeries() if input list is null or empty, rather than returning null or throwing.

  7. IEPE Bridge Hardcoded: The constant IEPE_BRIDGE = "IEPE" is used for special-casing excitation display, but the value is not sourced from a shared constant.

  8. Digital Channel Detection Uses String Prefix: channel.Bridge.StartsWith(SensorConstants.BridgeType.DigitalInput.ToString()) relies on string matching rather than enum comparison.

  9. GRMS Calculation Has Index Bounds Check: The loop condition i < psd.Length - 2 && i < freq.Length - 2 skips the last two elements, which is correct for the pairwise calculation but may silently drop data if arrays have different lengths.