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,187 @@
---
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-16T13:52:27.037806+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "1630e6f30be700ba"
---
# Documentation: DTS.Viewer.Graph Module - Test 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 channel metadata, X/Y coordinate arrays, statistical calculations, and visualization properties. `TestDataSeriesModel` acts as a factory/processor that reads raw binary channel data, applies transformations (including FFT and PSD calculations), and populates `TestDataSeries` instances for display. The module supports three data modes: regular time-series, FFT (Fast Fourier Transform), and PSD (Power Spectral Density) with configurable windowing and filtering.
---
## 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). |
| `Yvalue` | `double[]` | Y-axis data array (amplitude, magnitude, or PSD). |
| `GraphColor` | `Brush` | WPF brush for graph rendering. Internally stored as `byte[]` for thread-safety. |
| `IsSaved` | `bool` | Get-only property indicating save state. |
| `HardwareChannel` | `string` | Hardware channel name. |
| `GroupName` | `string` | Channel group name. |
| `SWAAF` | `string` | Software anti-aliasing filter setting. |
| `Bridge` | `string` | Bridge type identifier. |
| `HWAAF` | `string` | Hardware anti-aliasing filter rate. |
| `SampleRate` | `string` | Sample rate in Hz. |
| `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` | Get-only; returns `"N/A"` if `SensorSN` 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 formatted as strings, 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 for PSD results). |
| `FFT` | `bool` | Indicates whether series contains FFT-transformed data. |
| `T0EUValue` | `string` | T0 value string. |
| `RecordingMode` | `string` | Recording mode description. |
#### Methods
```csharp
public void SetStatsFromYValues()
```
Calculates and sets `AvgY`, `StdDevY`, `MinY`, `MaxY` from internal `Yvalue` array. Uses `"G5"` format for string conversion.
```csharp
public void SetStatsFromYValues(double[] values)
```
Overload that calculates statistics from a provided `double[]` array. Handles null/empty arrays by setting all stats to `Table_NA`.
```csharp
public void SetStatsFromChannel(ITestChannel channel)
```
Sets statistics from pre-calculated values on an `ITestChannel` instance (properties: `MinY`, `MaxY`, `AveY`, `StdDevY`, `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 `PropertyChanged` notification. |
| `IsSaved` | `bool` | Get-only property. |
#### Methods
```csharp
public Task<ITestDataSeries> GetTestDataAsync(ITestChannel channel, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null)
```
Async wrapper returning `GetTestData()`. **Warning:** Lacks `await` operators and runs synchronously (per compiler warning CS1998).
```csharp
public Task<List<ITestDataSeries>> GetTestDataAsync(List<ITestChannel> channels, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null)
```
Async wrapper for multiple channels. Includes envelope channel if `psdSettings.ShowEnvelope` is true.
```csharp
public List<ITestDataSeries> GetTestData(List<ITestChannel> channels, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null)
```
Synchronously processes multiple channels. Throws `Exception` with context on `OutOfDataException` or other failures. Logs failures via `APILogger.Log()`.
```csharp
public ITestDataSeries GetTestData(ITestChannel channel, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null)
```
Returns `AddTestChannelToChart()` result.
```csharp
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()`, applies transformations based on `chartOptions.UnitType`:
- **FFT mode** (`ChartUnitTypeEnum.FFT` with null `psdSettings`): Sets `FFT=true`, populates `PeakFrequency`, `PeakMagnitude`.
- **Regular mode** (null `psdSettings`): Time-series data with optional HIC calculation.
- **PSD mode** (non-null `psdSettings`): Applies data trimming, windowing (Hanning, Hamming, Blackman, BlackmanHarris, FlatTop, Rectangle), optional low/high pass filtering via `Exocortex.DSP`, and Welch PSD transform via `FftSharp.Transform.PSD_Welch()`.
Returns `null` if `channel.ErrorMessage` is not empty.
---
## 3. Invariants
1. **Array Initialization**: `Xvalue` and `Yvalue` are never null; they default to `new double[0]`.
2. **GraphColor Thread-Safety**: `GraphColor` getter creates a new `SolidColorBrush` on each call. The underlying color is stored as a 4-byte array (`[A, R, G, B]`) to enable cross-thread access.
3. **FFT/PSD Filter Bypass**: When `chartOptions.UnitType` is `FFT` or `PSD`, `channel.SoftwareFilter` is forcibly set to `"none"` before reading data.
4. **Statistics Default**: `MinY`, `MaxY`, `AvgY` default to `Strings.Table_NA` (not empty string).
5. **PSD Data Length**: PSD processing resizes input arrays to the nearest enclosing power of 2 via `Utils.GetEnclosingPower2()`.
6. **Frequency Array First Element**: In PSD mode, `freq[0]` is explicitly set to `1` after calculation.
7. **IEPE Bridge Excitation**: Channels with `Bridge == "IEPE"` display `"---"` for excitation instead of measured voltage.
---
## 4. Dependencies
### This Module Depends On:
- `DTS.Common.Base` - `BasePropertyChanged` base class
- `DTS.Common.Enums.Sensors` - `SensorConstants` for bridge type detection
- `DTS.Common.Enums.Viewer` - `ChartUnitTypeEnum`, `TimeUnitTypeEnum`, window/filter enums
- `DTS.Common.Enums.DASFactory` - `DFConstantsAndEnums.RecordingMode`
- `DTS.Common.Interface` - `ITestDataSeries`, `ITestChannel`, `IGraphViewModel`, `IChartOptionsModel`, `IBaseModel`, `IPSDReportSettingsModel`
- `DTS.Common.Strings` - Localized string constants (`Table_NA`, `Envelope`, etc.)
- `DTS.Common.Utils` - `Utils.GetEnclosingPower2()`
- `DTS.Common.Utilities` - `RecordingModeExtensions`
- `DTS.Common.Utilities.Logging` - `APILogger`
- `DTS.Common.Converters` - `EnumDescriptionTypeConverter`
- `DTS.Common.Events` - `GraphChannelReadCalcProgressChangedEvent`, `GraphChannelReadCalcProgressChangedEventArgs`
- `DTS.Common.Exceptions` - `OutOfDataException`
- `Prism.Events` - `IEventAggregator`
- `System.Windows.Media` - `Brush`, `SolidColorBrush`, `Color`, `Colors`
- `FftSharp` - `Transform.PSD_Welch()`, `Transform.FFTfreq()`, `WindowType`, `WindowAveragingType`
- `Exocortex.DSP` - `PassFilter.LowPass()`, `PassFilter.HighPass()`, `PassFilterType`
- `Serialization.SliceRaw.File.Reader` - `ReadChannelsBinaryData()` (external/unclear origin)
### Dependents (Inferred):
- Any view or view model that displays graph data and implements `IGraphViewModel`
- PSD report generation components
---
## 5. Gotchas
1. **Async Methods Are Not Async**: Both `GetTestDataAsync` overloads are marked `async` but contain no `await` operators. They execute synchronously despite the method signature. Compiler warning CS1998 is suppressed with pragmas.
2. **GraphColor Allocation on Every Access**: The `GraphColor` getter instantiates a new `SolidColorBrush` on every call. Frequent access in UI binding scenarios may cause unnecessary allocations.
3. **T0EUValue Naming Misnomer**: Per 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"*. The property name is misleading.
4. **PSD Envelope Requires Non-Empty Input**: `GetEnvelopeChannel()` returns an empty `TestDataSeries` if input list is null or empty, without any error indication.
5. **Channel Error Short-Circuit**: `AddTestChannelToChart()` returns `null` (not an exception) if `channel.ErrorMessage` is non-empty, which may cause null reference exceptions in callers not expecting null.
6. **Digital Channel Detection String Comparison**: Digital channels are detected via `channel.Bridge.StartsWith(SensorConstants.BridgeType.DigitalInput.ToString())`. This relies on `ToString()` matching the enum name exactly.
7. **GRMS Calculation Edge Case**: `CalculateGRMS()` uses `N.EqualsDigitPrecision(-1, 1)` for a special case. The method `EqualsDigitPrecision` is not defined in the provided source—its behavior is unclear.
8. **Frequency Array Mutation**: In PSD mode, `freq[0] = 1` mutates the array returned from `FftSharp.Transform.FFTfreq()`. This may affect any other consumers of that array if it's shared.