--- source_files: - DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Graph/Model/TestDataSeries.cs - DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Graph/Model/TestDataSeriesModel.cs generated_at: "2026-04-17T15:56:35.752282+00:00" model: "zai-org/GLM-5-FP8" schema_version: 1 sha256: "2fa01244d764d6f0" --- # Documentation: DTS.Viewer.Graph Module - Test Data Series ## 1. Purpose This module provides the data model and factory logic for rendering test channel data on graphs within the DTS Viewer application. `TestDataSeries` serves as the serializable, property-change-notifying data transfer object that holds channel metadata, time/frequency domain data, and computed statistics. `TestDataSeriesModel` acts as the factory that transforms raw `ITestChannel` binary data into `TestDataSeries` instances, handling time-domain, FFT, and PSD (Power Spectral Density) transformations with optional filtering and windowing. --- ## 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` | Test group identifier. | | `TestId` | `string` | Unique test identifier. | | `TestSetupName` | `string` | Name of the test setup configuration. | | `ChannelId` | `string` | Channel identifier. | | `Xvalue` | `double[]` | X-axis data array (time or frequency values). | | `Yvalue` | `double[]` | Y-axis data array (amplitude values). | | `GraphColor` | `Brush` | WPF brush for graph rendering. Getter creates new `SolidColorBrush` from internal `byte[]`. | | `HardwareChannel` | `string` | Hardware channel name. | | `Bridge` | `string` | Bridge type identifier. | | `SWAAF` | `string` | Software anti-aliasing filter setting. | | `HWAAF` | `string` | Hardware anti-aliasing filter rate. | | `SampleRate` | `string` | Sample rate in Hz. | | `RecordingMode` | `string` | Recording mode description. | | `ISOCode` / `ISOChannelName` | `string` | ISO channel identification. | | `UserCode` / `UserChannelName` | `string` | User-defined channel identification. | | `ChannelName` | `string` | Display channel name. | | `Description` | `string` | Channel description. | | `SensorSN` | `string` | Sensor serial number. | | `SensorSNDisplay` | `string` | Returns `Strings.Table_NA` if sensor is test-specific embedded, otherwise returns `SensorSN`. | | `EngineeringUnits` | `string` | Engineering units string. | | `Excitation` | `string` | Excitation voltage. | | `Polarity` | `string` | Sensor polarity. | | `MinY` / `MaxY` / `AvgY` / `StdDevY` | `string` | Statistical values, default to `Strings.Table_NA`. | | `PeakMagnitude` | `double` | Peak magnitude of frequencies (valid only when `FFT` is true). | | `PeakFrequency` | `double` | Frequency of highest magnitude (valid only when `FFT` is true). | | `GRMS` | `double` | Root-mean-squared acceleration (calculated in PSD results). | | `FFT` | `bool` | Indicates whether series is FFT-transformed data. | | `T0EUValue` | `string` | T0 value regardless of units. | | `IsSaved` | `bool` | Get-only property (purpose unclear from source). | #### Methods ```csharp public void SetStatsFromYValues() ``` Sets `AvgY`, `StdDevY`, `MinY`, `MaxY`, `T0EUValue` using internal `Yvalue` array. Formats using `"G5"` format string. ```csharp public void SetStatsFromYValues(double[] values) ``` Overload that accepts an external `double[]` array. Handles null/empty arrays by setting all stats to `NaN` (displayed as `Strings.Table_NA`). ```csharp public void SetStatsFromChannel(ITestChannel channel) ``` Sets statistics from pre-calculated values on an `ITestChannel` instance (`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 with property change notification. | | `IsSaved` | `bool` | Get-only property (purpose unclear from source). | #### Methods ```csharp public Task GetTestDataAsync(ITestChannel channel, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null) ``` Async wrapper that calls synchronous `GetTestData`. Returns a single `ITestDataSeries`. ```csharp public Task> GetTestDataAsync(List channels, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null) ``` Async wrapper for batch channel processing. If `psdSettings.ShowEnvelope` is true, appends an envelope channel to results. ```csharp public List GetTestData(List channels, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null) ``` Synchronous batch processing. Catches `OutOfDataException` and re-throws with sample index context. ```csharp public ITestDataSeries GetTestData(ITestChannel channel, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null) ``` Entry point for single channel processing, delegates to `AddTestChannelToChart`. ```csharp public TestDataSeries AddTestChannelToChart(ITestChannel channel, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null) ``` **Primary factory method.** Reads binary channel data via `Serialization.SliceRaw.File.Reader.ReadChannelsBinaryData`, then: - For **FFT mode** (`chartOptions.UnitType == FFT` and no PSD settings): Sets `FFT=true`, populates `PeakFrequency`, `PeakMagnitude`, `Xvalue`, `Yvalue`. - For **regular time-domain**: Calculates time axis with unit conversion (ms or s), handles HIC data if present, sets stats from channel. - For **PSD mode**: Applies data range selection, resizes to power-of-2 length, applies optional low-pass/high-pass filters, computes PSD via `FftSharp.Transform.PSD_Welch`, calculates GRMS. Returns `null` if `channel.ErrorMessage` is not empty. ```csharp private ITestDataSeries GetEnvelopeChannel(List data) ``` Creates an envelope channel by taking the maximum Y value at each frequency across all input series. Sets `ChannelId` and related fields to `Strings.EnvelopeUnique`. ```csharp private double CalculateGRMS(double[] freq, double[] psd) ``` Calculates Grms using numerical integration of PSD curve. Handles logarithmic slope calculation with special case for N=-1. --- ## 3. Invariants 1. **Array Initialization**: `Xvalue` and `Yvalue` are initialized to empty arrays (`new double[0]`), never null. 2. **GraphColor Thread Safety**: `GraphColor` getter always creates a new `SolidColorBrush` instance; internal storage is `byte[] _graphColorARGB` to ensure thread safety (per comment referencing issue 34455). 3. **FFT/PSD Filter Bypass**: When `chartOptions.UnitType` is `FFT` or `PSD`, `channel.SoftwareFilter` is forcibly set to `"none"` before reading data. 4. **Statistics Format**: All statistical string properties use `"G5"` format specifier via `STAT_FORMAT` constant. 5. **PSD Data Length**: PSD processing resizes input arrays to the next enclosing power of 2 via `Utils.GetEnclosingPower2`. 6. **Frequency Array First Element**: In PSD processing, `freq[0]` is explicitly set to `1` after calculation. 7. **SensorSNDisplay Logic**: Returns `Strings.Table_NA` when `SensorConstants.IsTestSpecificEmbedded(SensorSN)` returns true. --- ## 4. Dependencies ### Imports (What this module depends on): **TestDataSeries.cs:** - `DTS.Common.Enums.Sensors` - `SensorConstants` for embedded sensor detection - `DTS.Common.Interface` - `ITestDataSeries` interface - `DTS.Common.Strings` - Localized string constants - `System.Windows.Media` - WPF `Brush