Files

262 lines
12 KiB
Markdown
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/Model/Enums.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/Model/TestModificationModel.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/Model/TestModelManipulation.cs
generated_at: "2026-04-16T11:09:33.877186+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "1e3214665d63bf12"
---
# Test Modification Module Documentation
## 1. Purpose
This module provides functionality for modifying test data within the DTS Viewer application. It manages the state of user-initiated modifications to channel parameters (sensitivity, EU multiplier/offset, T0 timing, line fit, software filters, data flags, and descriptions) and handles the persistence of these changes to both `.dts` metadata files and binary `.chn` channel files. The module supports backup/restore operations to allow reverting modifications and maintains change tracking to indicate which properties have been modified from their original values.
---
## 2. Public Interface
### Enums.cs
#### `Keys` Enum
```csharp
public enum Keys
{
ApplyShiftT0ModsTestOnly // System Setting for whether to restrict "Shift T0" test modifications to "Test" only.
}
```
- Defines a configuration key for controlling T0 modification behavior.
---
### TestModificationModel.cs
#### `TestModificationModel` Class
Implements `ITestModificationModel`. A model class that tracks modification state for a selected test channel.
**Calibration Properties:**
| Property | Type | Description |
|----------|------|-------------|
| `CalDate` | `string` | Returns calibration date as short date string, or empty if `Cal` is null. |
| `ModifyDate` | `string` | Returns modify date/time string, or empty if `Cal` is null. |
| `CalSensitivity` | `double` | Gets/sets sensitivity from first calibration record. Returns `double.NaN` if unavailable. |
| `ProportionalToExcitation` | `bool` | Returns whether calibration is proportional to excitation. |
| `ShowSensorCal` | `bool` | Returns true if `Cal` and `Sensor` are non-null and calibration is not non-linear. |
| `NonLinear` | `bool` | Returns whether calibration is non-linear. |
| `Cal` | `ISensorCalDbRecord` | The latest calibration record for the channel. |
| `Sensor` | `ISensorDbRecord` | The sensor corresponding to the channel. |
**Channel Selection & Modification Tracking:**
| Property | Type | Description |
|----------|------|-------------|
| `SelectedChannel` | `ITestChannel` | The currently selected test channel. |
| `Description` | `string` | Channel description string. |
| `IsModifiedDescription` | `bool` | True if `Description` differs from `SelectedChannel.ChannelDescriptionString`. |
| `EuMultiplier` | `double` | EU multiplier value. |
| `IsModifiedEuMultiplier` | `bool` | True if `EuMultiplier` differs from `SelectedChannel.Multiplier`. |
| `EuOffset` | `double` | EU offset value. |
| `IsModifiedEuOffset` | `bool` | True if `EuOffset` differs from `SelectedChannel.UserOffsetEu`. |
| `T0` | `double` | T0 timing offset (in ms). |
| `IsModifiedT0` | `bool` | True if `T0` is not 0. |
| `T1` | `double` | Line fit start point (in ms). |
| `T2` | `double` | Line fit end point (in ms). |
| `IsModifiedLineFit` | `bool` | True if `T1` or `T2` is not 0. |
| `Sensitivity` | `double` | Sensitivity value. |
| `IsModifiedSensitivity` | `bool` | True if `Sensitivity` differs from `SelectedChannel.Sensitivity`. |
| `SelectedFilter` | `IFilterClass` | Selected software filter (defaults to `FilterClassType.Unfiltered`). |
| `IsModifiedFilter` | `bool` | True if `SelectedFilter` differs from channel's software filter. |
| `SelectedDataFlag` | `DataFlag` | Selected data flag. |
| `IsModifiedDataFlag` | `bool` | True if `SelectedDataFlag` differs from channel's data flag. |
| `IsModified` | `bool` | Aggregate flag indicating any modification exists and `SelectedChannel` is not null. |
**Control Enable/Disable Properties:**
| Property | Type | Default |
|----------|------|---------|
| `EnableSensitivityControl` | `bool` | `true` |
| `EnableLineFitControl` | `bool` | `true` |
| `EnableEUOffsetControl` | `bool` | `true` |
| `EnableEUMultiplierControl` | `bool` | `true` |
| `EnableFilterControl` | `bool` | `true` |
| `EnableDescriptionControl` | `bool` | `true` |
| `IsDataFlagEnabled` | `bool` | `true` |
| `IsT0Enabled` | `bool` | `true` |
**T0 Mode Properties:**
| Property | Type | Description |
|----------|------|-------------|
| `T0Mode` | `T0Mode` | Gets/sets T0 mode (`Test` or `DAS`). When `IsT0ModeTestOnly` is true, setter forces value to `T0Mode.Test`. |
| `IsT0ModeTestOnly` | `bool` | When true, restricts T0 mode to `Test` only. |
**Other Properties:**
| Property | Type | Description |
|----------|------|-------------|
| `Parent` | `ITestModificationViewModel` | Reference to parent view model. |
| `IsSaved` | `bool` | Property exists but has no implementation visible. |
**Methods:**
```csharp
public bool ValidateT0()
```
- Validates that T0 falls within the dataset's time range (between start and end times).
- Returns `true` if `SelectedChannel` or `SelectedChannel.ParentModule` is null.
- Calculates valid range from `StartRecordSampleNumber`, `TriggerSampleNumbers[0]`, `NumberOfSamples`, and `SampleRateHz`.
```csharp
public void OnPropertyChanged(string propertyName)
```
- Raises `PropertyChanged` event.
- Updates `IsModified` aggregate flag when non-IsModified properties change.
- Calls `Parent?.PublishChanges()`.
**Commands:**
```csharp
public DelegateCommand UpdateDatabaseCommand
```
- Executes `UpdateDatabaseMethod()` which delegates to `Parent.UpdateDatabaseMethod()`.
---
### TestModelManipulation.cs
#### `TestModelManipulation` Class
Static utility class for file-based test modification operations.
**Constants:**
| Constant | Value | Description |
|----------|-------|-------------|
| `UNUSED_START_TIME` | `0` | Placeholder for test serialization. |
| `UNUSED_DATA_COLLECTION_LENGTH` | `0` | Placeholder for test serialization. |
| `BackupHeaderExtension` | `".header.bak"` | Extension for header-only backups. |
| `BackupFileExtension` | `".bak"` | Extension for full file backups. |
**Public Methods:**
```csharp
public static void UndoAllModification(ITestModificationModel model)
```
- Reverts all modifications by restoring `.dts` and all `.chn` files from backups.
- Publishes `ChannelsModificationNotification`, `RefreshTestRequestEvent`, and `TestModificationEvent`.
```csharp
public static bool BackupExists(ITestModificationModel model)
```
- Returns true if either `.dts.bak` or `.chn.bak` files exist for the selected channel.
```csharp
public static bool SaveModification(ITestModificationModel model, bool useISOCodeFilterMapping, bool bUseZeroForUnfiltered)
```
- Persists all modifications to disk.
- Handles T0 changes (applying to test or DAS based on `T0Mode`).
- Handles filter changes with optional ISO code mapping.
- Handles sensitivity, EU multiplier/offset, description, data flag, and line fit changes.
- Publishes `TestModificationEvent` on completion.
```csharp
public static bool SaveModificationDataFlag(ITestModificationModel model)
```
- Saves only data flag modifications.
- Publishes `ChannelsModificationNotification` and repopulates model from channel.
```csharp
public static void ApplyLineFit(ITestModificationModel model, Test.Module.Channel channel)
```
- Applies linear interpolation between sample indices derived from `T1` and `T2`.
- Backs up channel file (full backup, not header-only).
- Modifies ADC data in place using straight-line fit between two points.
```csharp
public static void PreviewLineFit(ITestModificationModel model)
```
- Publishes `ChannelsModificationLineFitNotification` with calculated start/end indices for UI preview without disk modification.
```csharp
public static void UndoModification(ITestModificationModel model)
```
- Reverts in-memory changes by repopulating from channel.
- Publishes `ChannelsModificationNotification`.
```csharp
public static void PopulateFromChannel(ITestModificationModel model)
```
- Initializes model properties from `SelectedChannel` values.
- Resets `T0`, `T1`, `T2` to 0.
---
## 3. Invariants
1. **Calibration Record Access**: `CalSensitivity` getter assumes `Cal.Records.Records[0]` exists if the collection is non-null and non-empty. No bounds checking beyond length > 0.
2. **Modification Flag Consistency**: `IsModified` is always `false` when `SelectedChannel` is null, regardless of other modification flags.
3. **T0Mode Restriction**: When `IsT0ModeTestOnly` is `true`, the `T0Mode` setter always forces the value to `T0Mode.Test`, ignoring the provided value.
4. **Backup File Semantics**: Backup files (`.bak`) represent the **original** unmodified files. If a backup exists, it is never overwritten by subsequent backup operations.
5. **Line Fit Index Ordering**: `ApplyLineFit` automatically swaps start/end indices if `startIndex > endIndex`.
6. **T0 Validation Range**: `ValidateT0()` calculates time range assuming `TriggerSampleNumbers[0]` exists (no bounds check on the list).
7. **Channel Matching**: `SaveModification` matches channels by both `ChannelId` AND `BinaryFileName` suffix for most operations (except T0 modifications which apply more broadly).
---
## 4. Dependencies
### Imports (This module depends on):
**From TestModificationModel.cs:**
- `DTS.Common` - Common utilities
- `DTS.Common.Classes.Sensors` - Sensor classes
- `DTS.Common.Enums.Sensors` - Sensor enums
- `DTS.Common.Interface` - Common interfaces
- `DTS.Common.Interface.Sensors` - Sensor interfaces
- `DTS.Common.Interface.Sensors.SoftwareFilters` - Filter interfaces
- `DTS.SensorDB` - Sensor database interfaces (`ISensorCalDbRecord`, `ISensorDbRecord`)
- `Prism.Commands` - `DelegateCommand`
**From TestModelManipulation.cs:**
- `DTS.Common` - Common utilities
- `DTS.Common.Classes.Sensors` - Sensor classes
- `DTS.Common.Events` - Event types (`TestModificationEvent`, `TestModificationArgs`, `ChannelsModificationNotification`, `ChannelsModificationLineFitNotification`, `LineFitArgs`, `RefreshTestRequestEvent`)
- `DTS.Common.Interface` - `ITestChannel`
- `DTS.Common.Settings` - `SettingsDB`
- `DTS.Common.Utilities.Logging` - `APILogger`
- `DTS.Serialization` - Serialization utilities (`Serialization.SliceRaw.File`)
- `Prism.Ioc` - `ContainerLocator`
- `Prism.Events` - `IEventAggregator`
### External Type References (Interfaces expected from elsewhere):
- `ITestModificationModel` - Interface implemented by `TestModificationModel`
- `ITestModificationViewModel` - Parent view model interface
- `ITestChannel` - Test channel interface
- `ISensorCalDbRecord` - Calibration database record
- `ISensorDbRecord` - Sensor database record
- `IFilterClass` / `FilterClass` - Software filter abstraction
- `T0Mode` - Enum for T0 modification scope
- `DataFlag` - Enum for data flags
- `Test.Module.Channel` / `Test.Module.AnalogInputChannel` - Channel types from serialization
- `Test` / `TestSetup` - Test structure types
---
## 5. Gotchas
1. **Namespace Mismatch**: `TestModificationModel.cs` is declared in namespace `DTS.Viewer.ChartOptions.Model` despite residing in `DTS.Viewer.TestModification/Model/`. This may cause confusion when locating the class.
2. **IsSaved Property**: The `IsSaved` property has a getter but no visible setter or backing field implementation. Its behavior is unclear from source alone.
3. **T0 Mode DAS Logic**: In `SaveModification`, when `T0Mode == T0Mode.DAS`, T0 changes are applied to modules that **do not** contain the selected channel but share the same `BaseSerialNumber` as the module that does. This could affect more channels than expected.
4. **Line Fit Data Type**: `ApplyLineFit` casts ADC data to `short` after floating-point interpolation, which could cause precision loss or overflow for extreme values.
5. **Thread.Sleep in File Writing**: `WriteDTSFileChanges` includes `System.Threading.Thread.Sleep(10)` after writing the DTS file. The reason for this delay is not documented in source.
6. **Backup Strategy Selection**: `BackupChannelIfNeeded` uses header-only backup for sensitivity/T0/filter changes (when `useISOCodeFilterMapping` is true), but full backup for line fit. This is a performance optimization but means different modification types have different restore behaviors.
7. **FilterClassType Default**: `SelectedFilter` defaults to `FilterClassType.Unfiltered`, but the source does not show the definition of `FilterClassType` enum.
8. **PropertyChanged Event Naming**: `RebindCalProperties` raises events with string property names rather than using `nameof()` operator, which could lead to runtime errors if property names change.