--- 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-17T15:55:05.952766+00:00" model: "zai-org/GLM-5-FP8" schema_version: 1 sha256: "8c9823f92db20638" --- # Test Modification Module Documentation ## 1. Purpose This module provides functionality for modifying test data within the DTS Viewer application. It enables users to adjust channel parameters (sensitivity, EU multiplier/offset, T0 time shifts, line fit, software filters, data flags, and descriptions) and persist those changes to both binary channel files (`.chn`) and test configuration files (`.dts`). The module implements a backup-and-restore system to allow reverting modifications, and tracks modification state to indicate unsaved changes to the user interface. --- ## 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. } ``` A configuration key enum used to control T0 modification behavior restrictions. --- ### TestModificationModel.cs #### `TestModificationModel` Class Implements `ITestModificationModel` and provides `INotifyPropertyChanged` for data binding. **Calibration Properties:** - `string CalDate` — Read-only; returns `Cal.CalibrationDate.ToShortDateString()` or empty string if `Cal` is null. - `string ModifyDate` — Read-only; returns formatted modify date/time or empty string if `Cal` is null. - `double CalSensitivity` — Gets/sets sensitivity from `Cal.Records.Records[0].Sensitivity`; returns `double.NaN` if unavailable. - `bool ProportionalToExcitation` — Read-only; returns `Cal.IsProportional`. - `bool NonLinear` — Read-only; returns `Cal.NonLinear`. - `bool ShowSensorCal` — Read-only; returns true if `Cal` and `Sensor` are non-null and `NonLinear` is false. - `ISensorCalDbRecord Cal` — Gets/sets the latest calibration record; triggers `RebindCalProperties()` on set. - `ISensorDbRecord Sensor` — Gets/sets the sensor record; triggers `RebindCalProperties()` on set. **Channel Selection:** - `ITestChannel SelectedChannel` — The currently selected channel for modification. **Modification Value Properties:** - `string Description` — Channel description text. - `double EuMultiplier` — EU multiplier value. - `double EuOffset` — EU offset value. - `double T0` — T0 time shift value (milliseconds). - `double T1` — Line fit start point (milliseconds). - `double T2` — Line fit end point (milliseconds). - `double Sensitivity` — Channel sensitivity value. - `IFilterClass SelectedFilter` — Selected software filter; defaults to `FilterClass(FilterClassType.Unfiltered)`. - `DataFlag SelectedDataFlag` — Selected data flag; defaults to `DataFlag.None`. - `T0Mode T0Mode` — T0 application mode (`T0Mode.Test` or `T0Mode.DAS`); defaults to `T0Mode.Test`. **Modification State Properties (Read-only):** - `bool IsModifiedDescription` — True if `Description` differs from `SelectedChannel.ChannelDescriptionString`. - `bool IsModifiedEuMultiplier` — True if `EuMultiplier` differs from `SelectedChannel.Multiplier`. - `bool IsModifiedEuOffset` — True if `EuOffset` differs from `SelectedChannel.UserOffsetEu`. - `bool IsModifiedT0` — True if `T0` is not zero. - `bool IsModifiedLineFit` — True if `T1` or `T2` is not zero. - `bool IsModifiedSensitivity` — True if `Sensitivity` differs from `SelectedChannel.Sensitivity`. - `bool IsModifiedFilter` — True if `SelectedFilter` differs from the channel's current software filter. - `bool IsModifiedDataFlag` — True if `SelectedDataFlag` differs from `SelectedChannel.DataFlag`. - `bool IsModified` — Aggregate flag indicating any modification exists and `SelectedChannel` is non-null. **Control Enable Properties:** - `bool EnableSensitivityControl` — Controls UI sensitivity control visibility. - `bool EnableLineFitControl` — Controls UI line fit control visibility. - `bool EnableEUOffsetControl` — Controls UI EU offset control visibility. - `bool EnableEUMultiplierControl` — Controls UI EU multiplier control visibility. - `bool EnableFilterControl` — Controls UI filter control visibility. - `bool EnableDescriptionControl` — Controls UI description control visibility. - `bool IsDataFlagEnabled` — Controls UI data flag control visibility. - `bool IsT0Enabled` — Controls UI T0 control visibility. - `bool IsT0ModeTestOnly` — When true, forces `T0Mode` to `T0Mode.Test`. **Other Properties:** - `ITestModificationViewModel Parent` — Reference to parent view model. - `bool IsSaved` — Read-only property (no setter visible in source). **Methods:** - `void OnPropertyChanged(string propertyName)` — Raises `PropertyChanged` event and recalculates `IsModified`. - `bool ValidateT0()` — Validates T0 falls within the channel's dataset time range; returns true if `SelectedChannel` or `ParentModule` is null. **Commands:** - `DelegateCommand UpdateDatabaseCommand` — Executes `Parent.UpdateDatabaseMethod()`. --- ### TestModelManipulation.cs #### `TestModelManipulation` Class Static utility class for file-based test modification operations. **Constants:** - `double UNUSED_START_TIME = 0` - `int UNUSED_DATA_COLLECTION_LENGTH = 0` - `string BackupHeaderExtension = ".header.bak"` (private) - `string BackupFileExtension = ".bak"` (private) **Public Methods:** - `static void UndoAllModification(ITestModificationModel model)` — Reverts all modifications by restoring `.dts` and all binary channel files from backups. Publishes `ChannelsModificationNotification`, `RefreshTestRequestEvent`, and `TestModificationEvent`. - `static bool BackupExists(ITestModificationModel model)` — Returns true if either `.dts.bak` or `.chn.bak` backup files exist for the model's selected channel. - `static void BackupChannelIfNeeded(Test.Module.Channel testModuleChannel, bool headerOnly)` — Creates backup of channel binary file. If `headerOnly` is true, backs up only the header portion; otherwise backs up the entire file. - `static bool SaveModification(ITestModificationModel model, bool useISOCodeFilterMapping, bool bUseZeroForUnfiltered)` — Persists all modifications to disk. Returns true on success. Handles T0 (Test and DAS modes), line fit, filter, sensitivity, EU multiplier/offset, description, and data flag modifications. - `static bool SaveModificationDataFlag(ITestModificationModel model)` — Saves only data flag modifications to disk. - `static void ApplyLineFit(ITestModificationModel model, Test.Module.Channel channel)` — Applies linear interpolation between `T1` and `T2` sample indices on the channel's ADC data. - `static void PreviewLineFit(ITestModificationModel model)` — Publishes `ChannelsModificationLineFitNotification` with calculated start/end indices without modifying disk. - `static void UndoModification(ITestModificationModel model)` — Re-populates model from channel and publishes `ChannelsModificationNotification`. - `static void PopulateFromChannel(ITestModificationModel model)` — Initializes model properties from `SelectedChannel` values. --- ## 3. Invariants 1. **Backup File Semantics**: Backup files (`.bak` and `.header.bak`) represent the *original* unmodified files. Once a backup exists, it is never overwritten by subsequent modifications—this preserves the ability to revert to the original state. 2. **IsModified Aggregation**: `IsModified` is true if and only if at least one `IsModified*` property is true AND `SelectedChannel` is non-null. 3. **T0Mode Restriction**: When `IsT0ModeTestOnly` is true, `T0Mode` setter forces the value to `T0Mode.Test` regardless of the input value. 4. **Calibration Property Dependencies**: `CalSensitivity`, `ProportionalToExcitation`, `NonLinear`, `ShowSensorCal`, `CalDate`, and `ModifyDate` all depend on `Cal` being non-null; they return default values (`false`, `NaN`, empty string) when `Cal` is null. 5. **Line Fit Index Ordering**: In `ApplyLineFit`, if `startIndex > endIndex`, the values are swapped before processing. 6. **T0 Validation Range**: `ValidateT0()` returns `true` (valid) if `SelectedChannel` or `ParentModule` is null, treating missing 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 including `TestModificationEvent`, `TestModificationArgs`, `ChannelsModificationNotification`, `RefreshTestRequestEvent`, `ChannelsModificationLineFitNotification`, `LineFitArgs` - `DTS.Common.Settings` — `SettingsDB` for global configuration values - `DTS.Common.Utilities.Logging` — `APILogger` - `DTS.Common.ISO` — `IsoCode` class - `DTS.Serialization` — Serialization utilities including `SliceRaw.File` - `DTS.SensorDB` — Sensor database interfaces - `Prism.Commands` — `DelegateCommand` - `Prism.Ioc` — `ContainerLocator` - `Prism.Events` — `IEventAggregator` ### What Depends On This Module: - Not determinable from the provided source files alone. --- ## 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. **ReSharper Suppressions**: The `TestModificationModel.cs` file contains multiple ReSharper suppressions (`InconsistentNaming`, `RedundantDefaultMemberInitializer`, `CheckNamespace`, `UnassignedGetOnlyAutoProperty`), suggesting known code style deviations. 3. **IsSaved Property Never Set**: The `IsSaved` property has a getter but no visible setter or initialization in the provided source, making its purpose unclear. 4. **Backup Strategy Complexity**: Binary channels can be backed up in two ways (header-only vs. full file). The `BackupChannelIfNeeded` method handles conversion between these modes, but developers should be aware that a header backup may be promoted to a full backup if subsequent modifications require it. 5. **T0 DAS Mode Scope**: When `T0Mode.DAS` is used, T0 changes are applied to all channels on the same DAS (matching `BaseSerialNumber`), not just the selected channel. This is a broader scope than might be expected. 6. **Line Fit Overwrites Data**: `ApplyLineFit` permanently replaces ADC data between T1 and T2 with linearly interpolated values. There is no undo mechanism specific to line fit beyond the full file restore. 7. **File Encoding Assumption**: `WriteDTSFileChanges` forces UTF-16 encoding for `.dts` files. The code catches exceptions and falls back to `Encoding.Default`, but this fallback could produce files incompatible with other consumers. 8. **Thread.Sleep in File Writing**: `WriteDTSFileChanges` includes a 10ms `Thread.Sleep()` after writing, suggesting a timing-related workaround for file system operations.