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

159 lines
8.0 KiB
Markdown

---
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<ITestDataSeries> GetTestDataAsync(ITestChannel channel, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null)
```
Async wrapper that calls synchronous `GetTestData`. Returns a single `ITestDataSeries`.
```csharp
public Task<List<ITestDataSeries>> GetTestDataAsync(List<ITestChannel> 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<ITestDataSeries> GetTestData(List<ITestChannel> 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<ITestDataSeries> 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