init
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.CommonCore/Classes/DTS.Viewer/Commands/RelayCommand.cs
|
||||
generated_at: "2026-04-16T02:42:33.604683+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "63672ade54ed35d0"
|
||||
---
|
||||
|
||||
# Commands
|
||||
|
||||
### **Purpose**
|
||||
This module implements a concrete, reusable `ICommand`-based command class (`RelayCommand`) for WPF applications, enabling decoupling of UI actions (e.g., button clicks) from their execution logic. It serves as a lightweight command adapter that forwards `Execute` and `CanExecute` calls to user-provided delegates, supporting both mandatory execution logic and optional, parameterized execution guards. This pattern is foundational for implementing MVVM-style command binding in WPF.
|
||||
|
||||
---
|
||||
|
||||
### **Public Interface**
|
||||
All members are public and part of the `RelayCommand` class.
|
||||
|
||||
- **`RelayCommand(Action<object> execute)`**
|
||||
Constructor. Initializes the command with an execution delegate and no `CanExecute` guard (i.e., `CanExecute` always returns `true`). Throws `ArgumentNullException` if `execute` is `null`.
|
||||
|
||||
- **`RelayCommand(Action<object> execute, Predicate<object> canExecute)`**
|
||||
Constructor. Initializes the command with both execution and guard delegates. Throws `ArgumentNullException` if `execute` is `null`. The `canExecute` parameter may be `null`, in which case `CanExecute` defaults to `true`.
|
||||
|
||||
- **`bool CanExecute(object parameter)`**
|
||||
Implements `ICommand.CanExecute`. Invokes the stored `_canExecute` predicate (if non-null) with `parameter`; otherwise returns `true`.
|
||||
|
||||
- **`void Execute(object parameter)`**
|
||||
Implements `ICommand.Execute`. Invokes the stored `_execute` action with `parameter`. No validation is performed on `parameter` beyond null-safety of the delegate itself.
|
||||
|
||||
- **`event EventHandler CanExecuteChanged`**
|
||||
Implements `ICommand.CanExecuteChanged`. Subscribes/unsubscribes to `CommandManager.RequerySuggested`, enabling automatic re-evaluation of `CanExecute` when WPF detects relevant state changes (e.g., keyboard/mouse input, focus changes).
|
||||
|
||||
---
|
||||
|
||||
### **Invariants**
|
||||
- `_execute` is **never null** after construction (enforced via `ArgumentNullException` in both constructors).
|
||||
- `_canExecute` may be `null`; if so, `CanExecute` always returns `true`.
|
||||
- `CanExecuteChanged` event handlers are **always** attached to `CommandManager.RequerySuggested`, ensuring WPF’s command system triggers requery logic.
|
||||
- No explicit validation is performed on the `parameter` passed to `Execute` or `CanExecute`; nulls are passed directly to the delegates.
|
||||
|
||||
---
|
||||
|
||||
### **Dependencies**
|
||||
- **External Dependencies**:
|
||||
- `System` (for `Action<T>`, `Predicate<T>`, `ArgumentNullException`)
|
||||
- `System.Windows.Input` (for `ICommand`, `CommandManager`)
|
||||
- **Internal Dependencies**:
|
||||
- No other modules in the codebase are referenced (self-contained).
|
||||
- **Depended Upon**:
|
||||
- Likely consumed by WPF UI layers (e.g., `Button.Command` bindings) and view models throughout the `DTS.Viewer` subsystem.
|
||||
|
||||
---
|
||||
|
||||
### **Gotchas**
|
||||
- **No manual `CanExecuteChanged` raising**: The class relies solely on `CommandManager.RequerySuggested` to trigger `CanExecute` re-evaluation. If the command’s executability depends on non-UI state changes (e.g., background thread updates), callers must manually invoke `CommandManager.InvalidateRequerySuggested()` (or similar) to force updates.
|
||||
- **Parameter handling**: The `parameter` passed to `Execute`/`CanExecute` is unvalidated. Passing `null` is permitted and will be forwarded to the delegates—consumers must handle `null` parameters explicitly if needed.
|
||||
- **Thread affinity**: `CommandManager.RequerySuggested` is raised on the UI thread. If `CanExecute` delegates access non-UI-thread resources, thread-safety must be ensured by the caller.
|
||||
- **No disposal pattern**: The class does not implement `IDisposable`, and event subscriptions (via `CanExecuteChanged`) are not explicitly cleaned up—relying on WPF’s lifetime management. This is acceptable for typical view model lifetimes but may cause leaks in long-lived command instances.
|
||||
- **No async support**: `Execute` is synchronous; asynchronous operations require manual wrapping (e.g., `async void` or fire-and-forget), which is error-prone.
|
||||
@@ -0,0 +1,62 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.CommonCore/Classes/DTS.Viewer/Reports/ChannelGRMSSummary.cs
|
||||
generated_at: "2026-04-16T02:42:43.162304+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "7b6bc8e72ad59bb8"
|
||||
---
|
||||
|
||||
# Reports
|
||||
|
||||
### **Purpose**
|
||||
This module defines the `ChannelGRMSSummary` class, a data container for summarizing GRMS (Gaussian Root Mean Square) vibration metrics for a single channel in a test or analysis report. It implements `INotifyPropertyChanged` to support data binding scenarios (e.g., UI views), enabling reactive updates when property values change. The class serves as a lightweight, observable model for reporting tools that visualize or export channel-level GRMS results.
|
||||
|
||||
---
|
||||
|
||||
### **Public Interface**
|
||||
|
||||
- **`ChannelName`** (`string` property)
|
||||
Gets or sets the human-readable name of the channel (e.g., `"Ch1-Accel-X"`).
|
||||
|
||||
- **`SampleRate`** (`int` property)
|
||||
Gets or sets the sample rate (in Hz) associated with the channel’s data.
|
||||
|
||||
- **`GRMS`** (`double` property)
|
||||
Gets or sets the computed GRMS value (a scalar vibration intensity metric) for the channel.
|
||||
|
||||
- **`PropertyChanged`** (`event PropertyChangedEventHandler`)
|
||||
Event raised when a property value changes. Used by data-binding frameworks (e.g., WPF, WinForms) to refresh UI elements.
|
||||
|
||||
- **`OnPropertyChanged(string propertyName)`** (`void` method)
|
||||
Invokes the `PropertyChanged` event with the specified property name. Callers must ensure `propertyName` matches the actual property name (e.g., `"GRMS"`) to maintain binding correctness.
|
||||
|
||||
---
|
||||
|
||||
### **Invariants**
|
||||
- `ChannelName` may be `null` or empty; no validation is enforced in the class itself.
|
||||
- `SampleRate` is an `int`, but no constraints (e.g., positive values) are enforced.
|
||||
- `GRMS` is a `double`; negative values are *not* logically invalid at the type level but may be semantically nonsensical (GRMS is typically ≥0).
|
||||
- The `OnPropertyChanged` method does **not** validate whether `propertyName` corresponds to a real property; invalid names will still trigger the event.
|
||||
- Thread safety is **not** guaranteed; `PropertyChanged` invocation is not synchronized.
|
||||
|
||||
---
|
||||
|
||||
### **Dependencies**
|
||||
- **Depends on**:
|
||||
- `System.ComponentModel` (for `INotifyPropertyChanged` via `PropertyChangedEventHandler` and `PropertyChangedEventArgs`).
|
||||
- `DTS.Common.Interface` (for the `IChannelGRMSSummary` interface—implementation is implicit via class declaration).
|
||||
- **Implements**:
|
||||
- `IChannelGRMSSummary` (from `DTS.Common.Interface`), though the interface definition is not provided here.
|
||||
- **Used by**:
|
||||
- Presumably UI components (e.g., data grids, charts) that bind to GRMS summary reports.
|
||||
- Report-generation logic that aggregates or filters channel-level results.
|
||||
|
||||
---
|
||||
|
||||
### **Gotchas**
|
||||
- **No null-safety for `PropertyChanged`**: The null-conditional operator (`?.`) is used in `OnPropertyChanged`, but callers must still ensure `propertyName` is non-null to avoid runtime issues (though `null` would only cause no event to fire, not an exception).
|
||||
- **No validation on `GRMS`**: Negative or `NaN` values are permitted; consumers must handle invalid values appropriately.
|
||||
- **No explicit interface implementation**: The class declares `public event PropertyChangedEventHandler PropertyChanged` rather than explicit `INotifyPropertyChanged.PropertyChanged`, which may expose the event unnecessarily in some contexts.
|
||||
- **No documentation of `IChannelGRMSSummary`**: Without the interface definition, it is unclear whether `IChannelGRMSSummary` enforces additional members (e.g., `ToString()`, comparison logic).
|
||||
- **No constructor**: Relies on auto-implemented properties and default initialization; callers must explicitly set all properties post-instantiation.
|
||||
@@ -0,0 +1,300 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.CommonCore/Classes/DTS.Viewer/TestMetadata/TestMetadata.cs
|
||||
- Common/DTS.CommonCore/Classes/DTS.Viewer/TestMetadata/TestGraphs.cs
|
||||
- Common/DTS.CommonCore/Classes/DTS.Viewer/TestMetadata/TestSetupMetadata.cs
|
||||
- Common/DTS.CommonCore/Classes/DTS.Viewer/TestMetadata/TestRunMetadata.cs
|
||||
- Common/DTS.CommonCore/Classes/DTS.Viewer/TestMetadata/TestSummary.cs
|
||||
- Common/DTS.CommonCore/Classes/DTS.Viewer/TestMetadata/TestModule.cs
|
||||
- Common/DTS.CommonCore/Classes/DTS.Viewer/TestMetadata/TestChannel.cs
|
||||
- Common/DTS.CommonCore/Classes/DTS.Viewer/TestMetadata/TestMetadataList.cs
|
||||
generated_at: "2026-04-16T02:42:52.937741+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "c38901448183a71b"
|
||||
---
|
||||
|
||||
# Documentation: TestMetadata Module
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides data structures and parsing logic for loading, representing, and managing test metadata from XML-based `.dts` files in the DTS Viewer system. It defines core domain models (`TestMetadata`, `TestRunMetadata`, `TestSetupMetadata`, `TestModule`, `TestChannel`, `TestGraphs`, `TestSummary`) that encapsulate test configuration, hardware setup, channel definitions, and summary information. The `TestMetadataList` class is responsible for deserializing XML metadata files into strongly-typed objects and constructing `TestSummary` instances for UI consumption, including timestamp resolution using PTP1588 timing data when available.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `TestMetadataList`
|
||||
|
||||
#### `GetTestSummaryListAsync(IBaseViewModel parent, string path, string file, string pattern = "")`
|
||||
- **Behavior**: Asynchronous wrapper (currently synchronous implementation) that returns an `ObservableCollection<ITestSummary>` by parsing `.dts` files in the specified directory. Uses `pattern` to filter files (default: `.dts`). Requires `parent` for view model hierarchy.
|
||||
|
||||
#### `GetTestSummaryList(IBaseViewModel parent, string path, string file = "", string pattern = "")`
|
||||
- **Behavior**: Synchronously returns an `ObservableCollection<ITestSummary>` by parsing `.dts` files. Uses `parent` to set `TestSummary.Parent`.
|
||||
|
||||
#### `GetTestSummaryList(string path, string file = "", string pattern = "")`
|
||||
- **Behavior**: Same as above but without a `parent` parameter (used when parent is not applicable or set later).
|
||||
|
||||
#### `GetTestMetadataList(XDocument xDoc, string path, string file)`
|
||||
- **Behavior**: Parses an `XDocument` (loaded `.dts` XML) into a `List<ITestMetadata>`. Handles channel array initialization and publishes errors via `IEventAggregator` on failure. Returns empty list on exception.
|
||||
|
||||
### `TestMetadata`
|
||||
|
||||
- **Properties**:
|
||||
- `ITestRunMetadata TestRun { get; set; }`
|
||||
- `ITestSetupMetadata TestSetup { get; set; }`
|
||||
- **Behavior**: Simple container for test run and setup metadata.
|
||||
|
||||
### `TestRunMetadata`
|
||||
|
||||
- **Properties**:
|
||||
- `string Name { get; set; }` — Logical test name (from XML `@Id` attribute).
|
||||
- `string Id { get; set; }` — File name without extension (derived from `@FilePath`).
|
||||
- `string Description { get; set; }`
|
||||
- `bool InlineSerializedData { get; set; }`
|
||||
- `string TestGuid { get; set; }`
|
||||
- `int FaultFlags { get; set; }`
|
||||
- `string Software { get; set; }`
|
||||
- `string SoftwareVersion { get; set; }`
|
||||
- `string DataType { get; set; }`
|
||||
- `DateTime FileDate { get; set; }`
|
||||
- `string FilePath { get; set; }`
|
||||
- `List<ITestModule> Modules { get; set; }`
|
||||
- `List<ITestChannel> Channels { get; set; }`
|
||||
- `List<ITestChannel> CalculatedChannels { get; set; }`
|
||||
- `bool IsSelected { get; set; }`
|
||||
- **Events**:
|
||||
- `event PropertyChangedEventHandler PropertyChanged` — Implements `INotifyPropertyChanged`.
|
||||
|
||||
### `TestSetupMetadata`
|
||||
|
||||
- **Properties**:
|
||||
- `string SetupName { get; set; }`
|
||||
- `DateTime TimeStamp { get; set; }`
|
||||
- `List<ITestGraphs> TestGraphs { get; set; }`
|
||||
- `CalibrationBehaviors CalibrationBehavior { get; set; }`
|
||||
|
||||
### `TestGraphs`
|
||||
|
||||
- **Properties**:
|
||||
- `string Name { get; set; }`
|
||||
- `string HardwareChannelName { get; set; }`
|
||||
- `List<string> ChannelIds { get; set; }`
|
||||
- `List<ITestChannel> Channels { get; set; }`
|
||||
|
||||
### `TestModule`
|
||||
|
||||
- **Properties**:
|
||||
- `string SerialNumber { get; set; }`
|
||||
- `string BaseSerialNumber { get; set; }`
|
||||
- `int AaFilterRateHz { get; set; }`
|
||||
- `int Number { get; set; }`
|
||||
- `int NumberOfSamples { get; set; }`
|
||||
- `int UnsubsampledNumberOfSamples { get; set; }`
|
||||
- `double RequestedPostTriggerSeconds { get; set; }`
|
||||
- `double RequestedPreTriggerSeconds { get; set; }`
|
||||
- `double PostTriggerSeconds { get; set; }`
|
||||
- `double PreTriggerSeconds { get; set; }`
|
||||
- `string RecordingMode { get; set; }`
|
||||
- `int SampleRateHz { get; set; }`
|
||||
- `int StartRecordSampleNumber { get; set; }`
|
||||
- `int NumberOfChannels { get; set; }`
|
||||
- `bool InlineSerializedData { get; set; }`
|
||||
- `int StartRecordTimestampSec { get; set; }`
|
||||
- `int StartRecordTimestampNanoSec { get; set; }`
|
||||
- `int TriggerTimestampSec { get; set; }`
|
||||
- `int TriggerTimestampNanoSec { get; set; }`
|
||||
- `List<ulong> TriggerSampleNumbers { get; set; }` — *Always empty* (see *Gotchas*).
|
||||
- `bool PTPMasterSync { get; set; }`
|
||||
- `int TiltSensorAxisX/Y/ZDegreesPre/Post { get; set; }`
|
||||
- `int TemperatureLocation1/2/3/4Pre/Post { get; set; }`
|
||||
- `List<ITestChannel> Channels { get; set; }`
|
||||
- `List<ITestChannel> CalculatedChannels { get; set; }`
|
||||
- `bool IsSelected { get; set; }`
|
||||
- **Events**:
|
||||
- `event PropertyChangedEventHandler PropertyChanged`
|
||||
|
||||
### `TestChannel`
|
||||
|
||||
- **Properties**:
|
||||
- `string Group { get; set; }`
|
||||
- `string SubGroup { get; set; }`
|
||||
- `bool IsGraphChannel { get; set; }`
|
||||
- `string GraphName { get; set; }`
|
||||
- `string TestId { get; set; }`
|
||||
- `string TestSetupName { get; set; }`
|
||||
- `string ModuleSerialNumber { get; set; }`
|
||||
- `string SerialNumber { get; set; }`
|
||||
- `string ChannelId { get; set; }`
|
||||
- `string ChannelDisplayName { get; set; }`
|
||||
- `string Description { get; set; }`
|
||||
- `string IsoCode { get; set; }`
|
||||
- `string IsoChannelName { get; set; }`
|
||||
- `string UserCode { get; set; }`
|
||||
- `string UserChannelName { get; set; }`
|
||||
- `string ChannelGroupName { get; set; }`
|
||||
- `string ChannelType { get; set; }`
|
||||
- `bool IsCalculatedChannel { get; set; }`
|
||||
- `int Number { get; set; }`
|
||||
- `string DigitalMultiplier { get; set; }`
|
||||
- `string DigitalMode { get; set; }`
|
||||
- `DateTime Start { get; set; }`
|
||||
- `string Bridge { get; set; }`
|
||||
- `double BridgeResistanceOhms { get; set; }`
|
||||
- `double ZeroPoint { get; set; }`
|
||||
- `string ChannelDescriptionString { get; set; }`
|
||||
- `string ChannelName2 { get; set; }`
|
||||
- `string HardwareChannelName { get; set; }`
|
||||
- `double DesiredRange { get; set; }`
|
||||
- `double ActualMaxRangeEu { get; set; }`
|
||||
- `double ActualMinRangeEu { get; set; }`
|
||||
- `double ActualMaxRangeAdc { get; set; }` — Always `short.MaxValue`
|
||||
- `double ActualMinRangeAdc { get; set; }` — Always `short.MinValue`
|
||||
- `double ActualMaxRangeMv { get; set; }`
|
||||
- `double ActualMinRangeMv { get; set; }`
|
||||
- `double Sensitivity { get; set; }`
|
||||
- `string SoftwareFilter { get; set; }`
|
||||
- `bool ProportionalToExcitation { get; set; }`
|
||||
- `bool IsInverted { get; set; }`
|
||||
- `string LinearizationFormula { get; set; }`
|
||||
- `bool IsSubsampled { get; set; }`
|
||||
- `int AbsoluteDisplayOrder { get; set; }`
|
||||
- `DateTime LastCalibrationDate { get; set; }`
|
||||
- `string SensorId { get; set; }`
|
||||
- `int OffsetToleranceLowMv { get; set; }`
|
||||
- `int OffsetToleranceHighMv { get; set; }`
|
||||
- `int DataFlag { get; set; }`
|
||||
- `string ExcitationVoltage { get; set; }`
|
||||
- `string Eu { get; set; }`
|
||||
- `bool CalSignalEnabled { get; set; }`
|
||||
- `bool ShuntEnabled { get; set; }`
|
||||
- `bool VoltageInsertionCheckEnabled { get; set; }`
|
||||
- `bool RemoveOffset { get; set; }`
|
||||
- `string ZeroMethod { get; set; }`
|
||||
- `double ZeroAverageWindowBegin { get; set; }`
|
||||
- `double ZeroAverageWindowEnd { get; set; }`
|
||||
- `int InitialEu { get; set; }`
|
||||
- `string InitialOffset { get; set; }`
|
||||
- `int UnsubsampledSampleRateHz { get; set; }`
|
||||
- `double MeasuredShuntDeflectionMv { get; set; }`
|
||||
- `double TargetShuntDeflectionMv { get; set; }`
|
||||
- `double MeasuredExcitationVoltage { get; set; }`
|
||||
- `double FactoryExcitationVoltage { get; set; }`
|
||||
- `double TimeOfFirstSample { get; set; }`
|
||||
- `double Multiplier { get; set; }`
|
||||
- `double UserOffsetEu { get; set; }`
|
||||
- `int UnitConversion { get; set; }`
|
||||
- `bool AtCapacity { get; set; }`
|
||||
- `int CapacityOutputIsBasedOn { get; set; }`
|
||||
- `string SourceChannelNumber { get; set; }`
|
||||
- `string SourceModuleNumber { get; set; }`
|
||||
- `string SourceModuleSerialNumber { get; set; }`
|
||||
- `string Calculation { get; set; }`
|
||||
- `int SampleRateHz { get; set; }`
|
||||
- `string SensitivityUnits { get; set; }`
|
||||
- `int SensorCapacity { get; set; }`
|
||||
- `string SensorPolarity { get; set; }`
|
||||
- `int ChannelNumber { get; set; }`
|
||||
- `string BinaryFileName { get; set; }`
|
||||
- `string BinaryFilePath { get; set; }`
|
||||
- `double Xmax { get; set; }`
|
||||
- `double Xmin { get; set; }`
|
||||
- `int SequentialNumbers { get; set; }`
|
||||
- `ITestSetupMetadata ParentTestSetup { get; set; }`
|
||||
- `ITestModule ParentModule { get; set; }`
|
||||
- `IBaseViewModel Parent { get; set; }`
|
||||
- `Color ChannelColor { get; set; }`
|
||||
- `string ErrorMessage { get; set; }`
|
||||
- `bool IsError { get; set; }`
|
||||
- `Color? ErrorColor { get; set; }` — Derived from `IsError`.
|
||||
- `bool IsLocked { get; set; }`
|
||||
- `bool CanLock { get; set; }`
|
||||
- `bool CanSelectChannel { get; set; }`
|
||||
- `bool IsExpanded { get; set; }`
|
||||
- `bool IsSelected { get; set; }`
|
||||
- `double MinADC/MaxADC/AveADC/StdDevADC/T0ADC { get; set; }`
|
||||
- `double MinMV/MaxMV/AveMV/StdDevMV/T0MV { get; set; }`
|
||||
- `double MinEU/MaxEU/AveEU/StdDevEU/T0EU { get; set; }`
|
||||
- `double MinY/MaxY/AveY/StdDevY/T0Value { get; set; }`
|
||||
- **Methods**:
|
||||
- `void SetChannelDescriptionAndDisplayName(string channelDescription)` — Sets `ChannelDescriptionString` and `ChannelDisplayName`.
|
||||
- `ITestChannel Copy()` — Shallow copy via `MemberwiseClone()`.
|
||||
- `override string ToString()` — Returns `ChannelDescriptionString` or `"N/A"` if test-specific embedded.
|
||||
- **Events**:
|
||||
- `event PropertyChangedEventHandler PropertyChanged` — Inherited from `BasePropertyChanged`.
|
||||
|
||||
### `TestSummary`
|
||||
|
||||
- **Properties**:
|
||||
- `string Id { get; set; }` — Concatenation of `TestRun.Id` and event number from `FilePath`.
|
||||
- `string SetupName { get; set; }`
|
||||
- `string Description { get; set; }`
|
||||
- `int ChannelCount { get; set; }`
|
||||
- `DateTime FileDate { get; set; }`
|
||||
- `DateTime TimeStamp { get; set; }` — Derived from module PTP timestamps if valid, else `TestSetup.TimeStamp`.
|
||||
- `string DataType { get; set; }`
|
||||
- `bool IsSelected { get; set; }`
|
||||
- `List<ITestGraphs> Graphs { get; set; }`
|
||||
- `List<ITestChannel> Channels { get; set; }`
|
||||
- `List<ITestChannel> CalculatedChannels { get; set; }`
|
||||
- `IBaseViewModel Parent { get; set; }`
|
||||
- `CalibrationBehaviors CalibrationBehavior { get; set; }` — Default: `NonLinearIfAvailable`.
|
||||
- `ITestMetadata TestMetadata { get; set; }`
|
||||
- **Commands**:
|
||||
- `DelegateCommand IsSelectedCommand { get; }` — Toggles selection and updates `Parent.SelectedTestSummaryList`.
|
||||
- **Methods**:
|
||||
- `void SelectionChanged()` — Adds/removes `this` from `Parent.SelectedTestSummaryList` and calls `PublishSelectedTestSummaryList()` on parent.
|
||||
- `void OnPropertyChanged(string propertyName)` — Raises `PropertyChanged`.
|
||||
- **Events**:
|
||||
- `event PropertyChangedEventHandler PropertyChanged`
|
||||
- **Constants**:
|
||||
- `public const string ROI_SUFFIX = @"_ROI Period";`
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **`TestMetadata`**: Must contain non-null `TestRun` and `TestSetup` references after successful parsing.
|
||||
- **`TestRunMetadata.Channels` and `TestRunMetadata.CalculatedChannels`**: Initialized as empty lists during parsing if missing in XML.
|
||||
- **`TestModule.TriggerSampleNumbers`**: Always initialized as an empty list; never populated (see *Gotchas*).
|
||||
- **`TestChannel.ChannelId`**: If missing or `-1` in XML, defaults to `m.GetHashCode().ToString()` (non-deterministic).
|
||||
- **`TestChannel.HardwareChannelName`**: For calculated channels, always set to `"N/A"` (via `Strings.Strings.Table_NA`).
|
||||
- **`TestChannel.SerialNumber`**: For calculated channels, always set to `"N/A"`.
|
||||
- **`TestSummary.TimeStamp`**: Falls back to `TestSetup.TimeStamp` if PTP timestamps are invalid or unavailable.
|
||||
- **`TestSummary.Id`**: Always includes event number extracted from `FilePath` via `ParseEventNumber`.
|
||||
- **`TestChannel.IsCalculatedChannel`**: Must be `true` for channels loaded via `LoadTestCalculatedChannels`.
|
||||
- **`TestSummary.IsSelected`**: Setter enforces selection logic via `SelectionChanged()` and `Parent` interaction.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Internal Dependencies (from source):
|
||||
- **Interfaces**:
|
||||
- `DTS.Common.Interface.ITestMetadata`, `ITestRunMetadata`, `ITestSetupMetadata`, `ITestGraphs`, `ITestModule`, `ITestChannel`, `ITestSummary`, `IBaseViewModel`, `IGraphMainViewModel`
|
||||
- **Enums**:
|
||||
- `DTS.Common.Enums.Sensors.CalibrationBehaviors`
|
||||
- **Utilities**:
|
||||
- `DTS.Common.XMLUtils.TestMetadataXml`
|
||||
- `DTS.Common.Base.BasePropertyChanged`
|
||||
- `DTS.Common.Constants.EventNumber`
|
||||
- `DTS.Common.Utils.TestUtils`, `PTP1588Timestamps`
|
||||
- `DTS.Common.XMLUtils.TestMetadataFields`, `TestSetupMetadataFields`, `TestGraphsFields`, `TestModuleFields`, `TestChannelFields`
|
||||
- `DTS.Common.Strings.Strings`
|
||||
- **Prism Framework**:
|
||||
- `Microsoft.Practices.Prism.Commands.DelegateCommand`
|
||||
- `Microsoft.Practices.Prism.Events.IEventAggregator`, `Events.PageErrorEvent`
|
||||
- `Microsoft.Practices.ServiceLocation.ServiceLocator`
|
||||
|
||||
### External Dependencies:
|
||||
- `System.Xml.Linq`
|
||||
- `System.Collections.ObjectModel`
|
||||
- `System.ComponentModel`
|
||||
- `System.Windows.Media` (for `Color`)
|
||||
|
||||
### Inferred Consumers:
|
||||
- UI view models (`ITestSummaryListViewModel`, `IGraphMainViewModel`) that interact with `TestSummary` and `TestChannel`.
|
||||
- XML loading utilities (`TestMetadataXml`) for parsing `.dts` files.
|
||||
- Event aggregation system for error reporting.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
- **`TestModule.TriggerSampleNumbers` is always empty**: The `LoadTriggerSampleNumbers` method ignores its input and returns `new List<ulong>()`. This field is likely unused or deprecated.
|
||||
- **Non-deterministic `ChannelId` for missing IDs**: If `ChannelId` attribute is missing or `-1`, `m.GetHashCode().ToString()` is used, which is not stable across runs or app restarts.
|
||||
- **Calculated channel data loss**: For calculated channels, many fields (e.g., `IsoCode`, `IsoChannelName`, `UserCode`, `UserChannelName`, `HardwareChannelName`, `SerialNumber`) are hardcoded to `"N/A"`. Some fields like `FactoryExcitationVoltage` and `TimeOfFirstSample` are incorrectly assigned values from unrelated attributes (e.g., `UnsubsampledSampleRateHz` → `FactoryExcitationVoltage`).
|
||||
- **`TestRunMetadata.Id` vs `Name` confusion**: `Id` is derived from file name (`Path.GetFileNameWithoutExtension(FilePath)`), while `Name` comes from XML `@Id` attribute. This may be counterintuitive.
|
||||
- **`TestSummary.TimeStamp` fallback behavior**: Uses `TestSetup.TimeStamp`
|
||||
Reference in New Issue
Block a user