--- 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-16T13:47:44.691721+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 offset/multiplier, T0 timing, line fit, software filters, data flags, and descriptions), tracks which values have been modified from their originals, and handles the persistence of these changes to both `.dts` XML files and binary `.chn` channel files. The module also manages backup/restore operations to allow undoing modifications. --- ## 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 configuration keys used by the TestModification module. --- ### TestModificationModel.cs #### `TestModificationModel` Class Implements `ITestModificationModel`. A model class that tracks modification state for a selected test channel. **Calibration Properties:** - `string CalDate` — Read-only; returns calibration date or empty string if `Cal` is null. - `string ModifyDate` — Read-only; returns modify date/time or empty string if `Cal` is null. - `double CalSensitivity` — Gets/sets sensitivity from the first calibration record; returns `double.NaN` if unavailable. - `bool ProportionalToExcitation` — Read-only; returns whether calibration is proportional to excitation. - `bool ShowSensorCal` — Read-only; returns true if `Cal` and `Sensor` exist and calibration is not non-linear. - `bool NonLinear` — Read-only; returns whether calibration is non-linear. - `ISensorCalDbRecord Cal` — Gets/sets the latest calibration record for the channel. - `ISensorDbRecord Sensor` — Gets/sets the sensor corresponding to the channel. **Selection & Description:** - `ITestChannel SelectedChannel` — The currently selected test channel. - `string Description` — Channel description string. - `bool IsModifiedDescription` — True if description differs from `SelectedChannel.ChannelDescriptionString`. **EU (Engineering Units) Properties:** - `double EuMultiplier` — EU multiplier value. - `bool IsModifiedEuMultiplier` — True if multiplier differs from `SelectedChannel.Multiplier`. - `double EuOffset` — EU offset value. - `bool IsModifiedEuOffset` — True if offset differs from `SelectedChannel.UserOffsetEu`. **Timing Properties:** - `double T0` — T0 shift value (milliseconds). - `bool IsModifiedT0` — True if T0 is not equal to 0. - `T0Mode T0Mode` — Indicates whether T0 changes apply to DAS or Test; coerced to `T0Mode.Test` if `IsT0ModeTestOnly` is true. - `bool IsT0ModeTestOnly` — Internal setter; restricts T0 mode selection. **Line Fit Properties:** - `double T1` — Line fit start point (milliseconds). - `double T2` — Line fit end point (milliseconds). - `bool IsModifiedLineFit` — True if T1 or T2 are non-zero. **Sensitivity & Filter:** - `double Sensitivity` — Channel sensitivity value. - `bool IsModifiedSensitivity` — True if sensitivity differs from `SelectedChannel.Sensitivity`. - `IFilterClass SelectedFilter` — Selected software filter; defaults to `FilterClass(FilterClassType.Unfiltered)`. - `bool IsModifiedFilter` — True if filter differs from `SelectedChannel.SoftwareFilter`. **Data Flag:** - `DataFlag SelectedDataFlag` — Selected data flag; defaults to `DataFlag.None`. - `bool IsModifiedDataFlag` — True if data flag differs from `SelectedChannel.DataFlag`. **Control Enable Properties (internal setters):** - `bool EnableSensitivityControl` - `bool EnableLineFitControl` - `bool EnableEUOffsetControl` - `bool EnableEUMultiplierControl` - `bool EnableFilterControl` - `bool EnableDescriptionControl` - `bool IsDataFlagEnabled` - `bool IsT0Enabled` **State Tracking:** - `bool IsModified` — True if any modification flag is true and `SelectedChannel` is not null. - `bool IsSaved` — Read-only property (appears unimplemented in source). - `ITestModificationViewModel Parent` — Reference to parent view model. **Methods:** - `void OnPropertyChanged(string propertyName)` — Raises `PropertyChanged` event and recalculates `IsModified`. - `bool ValidateT0()` — Validates that T0 falls within the dataset's start and end time bounds. **Commands:** - `DelegateCommand UpdateDatabaseCommand` — Executes `Parent.UpdateDatabaseMethod()`. --- ### TestModelManipulation.cs #### `TestModelManipulation` Class Static utility class for file-based test modification operations. **Constants:** ```csharp public const double UNUSED_START_TIME = 0; public const int UNUSED_DATA_COLLECTION_LENGTH = 0; private const string BackupHeaderExtension = ".header.bak"; private const string BackupFileExtension = ".bak"; ``` **Public Methods:** - `static void UndoAllModification(ITestModificationModel model)` — Reverts all modifications by restoring `.dts` and all binary `.chn` files from backups. Publishes `TestModificationEvent` and optionally `ChannelsModificationNotification`/`RefreshTestRequestEvent`. - `static bool BackupExists(ITestModificationModel model)` — Returns true if a `.dts.bak` or `.chn.bak` file exists for the selected channel. - `static bool SaveModification(ITestModificationModel model, bool useISOCodeFilterMapping, bool bUseZeroForUnfiltered)` — Persists all modifications to disk. Handles T0 (Test or DAS mode), line fit, sensitivity, filter, EU offset/multiplier, description, and data flag changes. Returns true on success. - `static bool SaveModificationDataFlag(ITestModificationModel model)` — Saves only data flag modifications to the `.dts` file. - `static void ApplyLineFit(ITestModificationModel model, Test.Module.Channel channel)` — Applies a linear interpolation between T1 and T2 sample indices, modifying the channel's ADC data in place. - `static void PreviewLineFit(ITestModificationModel model)` — Publishes `ChannelsModificationLineFitNotification` with line fit parameters for UI preview without disk modification. - `static void UndoModification(ITestModificationModel model)` — Reverts in-memory model state from the selected channel and publishes `ChannelsModificationNotification`. - `static void PopulateFromChannel(ITestModificationModel model)` — Initializes model properties from `SelectedChannel` values. - `static void BackupChannelIfNeeded(Test.Module.Channel testModuleChannel, bool headerOnly)` — Creates a backup of a `.chn` file (full file or header only). --- ## 3. Invariants 1. **IsModified Consistency**: `IsModified` is always `false` when `SelectedChannel` is `null`, regardless of other property states. 2. **T0Mode Coercion**: When `IsT0ModeTestOnly` is `true`, the `T0Mode` setter always coerces the value to `T0Mode.Test`. 3. **Backup File Semantics**: Backup files (`.bak` and `.header.bak`) represent the *original* unmodified state. If a backup already exists, it is not overwritten—this preserves the original file for undo operations. 4. **Line Fit Index Ordering**: In `ApplyLineFit`, if `startIndex > endIndex`, the values are swapped before processing. 5. **Calibration Record Access**: `CalSensitivity` always accesses `Cal.Records.Records[0]` (first record); behavior is undefined if multiple records exist and others are relevant. 6. **T0 Validation Bounds**: `ValidateT0()` returns `true` (valid) if `SelectedChannel` or `SelectedChannel.ParentModule` is null, treating unavailable data as "no constraint." --- ## 4. Dependencies **This module depends on:** - `DTS.Common` — Core utilities and interfaces - `DTS.Common.Classes.Sensors` — Sensor-related classes - `DTS.Common.Enums.Sensors` — Sensor enumerations including `DataFlag`, `T0Mode` - `DTS.Common.Interface` — Core interfaces including `ITestChannel` - `DTS.Common.Interface.Sensors` — Sensor interfaces including `ISensorCalDbRecord`, `ISensorDbRecord` - `DTS.Common.Interface.Sensors.SoftwareFilters` — `IFilterClass`, `FilterClass`, `FilterClassType` - `DTS.Common.Events` — Event types (`TestModificationEvent`, `TestModificationArgs`, `ChannelsModificationNotification`, `ChannelsModificationLineFitNotification`, `LineFitArgs`, `RefreshTestRequestEvent`) - `DTS.Common.Settings` — `SettingsDB` for global settings - `DTS.Common.Utilities.Logging` — `APILogger` - `DTS.Serialization` — Serialization utilities for `.chn` and `.dts` files - `DTS.SensorDB` — Sensor database interfaces - `Prism.Commands` — `DelegateCommand` - `Prism.Ioc` — `ContainerLocator` - `Prism.Events` — `IEventAggregator` **Consumers of this module:** - Not explicitly shown in source; inferred consumer is `ITestModificationViewModel` implementation referenced via `Parent` property. --- ## 5. Gotchas 1. **Namespace Mismatch**: `TestModificationModel.cs` declares namespace `DTS.Viewer.ChartOptions.Model` while the file path suggests `DTS.Viewer.TestModification.Model`. This inconsistency may cause confusion or require external namespace mapping. 2. **IsSaved Property Unimplemented**: The `IsSaved` property has a getter but no setter or backing field initialization, meaning it will always return `false` (default for `bool`). 3. **T0 DAS Mode Scope**: When `T0Mode.DAS` is used, T0 changes are applied to all modules matching the `BaseSerialNumber` of the module containing the selected channel—even if those modules don't contain the selected channel itself. This is a cross-module modification. 4. **Line Fit Boundary Handling**: `ApplyLineFit` uses indices `startIndex + 1` through `endIndex - 1` for interpolation, meaning the actual start and end points are not modified (they define the line but are not overwritten). 5. **File Encoding Assumption**: `WriteDTSFileChanges` forces UTF-16 encoding with a fallback to default encoding on exception. The comment indicates this is intentional for `.dts` file compatibility. 6. **Thread.Sleep in File Write**: `WriteDTSFileChanges` includes `System.Threading.Thread.Sleep(10)` after writing—purpose is unclear from source alone, possibly a workaround for file locking or timing issues. 7. **ISO Code Filter Mapping Side Effect**: When `useISOCodeFilterMapping` is true in `SaveModification`, modifying the filter also modifies the channel's `IsoCode` field, which triggers a header backup even if only the filter was changed. 8. **BackupExists Returns True for Any Backup**: The method returns `true` if either `.dts.bak` or `.chn.bak` exists, not necessarily both. This could indicate partial backup state.