init
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
---
|
||||
source_files:
|
||||
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.AddCalculatedChannel/Model/CalculatedChannelCreator.cs
|
||||
generated_at: "2026-04-16T13:59:32.414209+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "d05bf6b72e9c97be"
|
||||
---
|
||||
|
||||
# CalculatedChannelCreator Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
The `CalculatedChannelCreator` class is a factory responsible for creating derived data channels from existing sensor input channels. It supports three categories of calculations: 3D IR-Tracc displacement calculations (Thorax, Abdomen, LowerThorax variants), aggregate operations across multiple channels (SUM, AVE, Resultant, HIC), and single-channel binary operations (Integral, DoubleIntegral, Derivative, Sin, Cos). The class handles sample rate alignment via interpolation, creates persistent file-backed channel storage, and manages the full lifecycle of calculated channel creation including validation, computation, scaling, and serialization.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### `CreateChannels`
|
||||
```csharp
|
||||
public static Test.Module.CalculatedChannel[] CreateChannels(
|
||||
string testId,
|
||||
string folder,
|
||||
Calculation calculation,
|
||||
List<Test.Module.Channel> inputChannels,
|
||||
string channelName,
|
||||
int startingNumber,
|
||||
List<Test.Module.Channel> allChannels,
|
||||
int clipLength,
|
||||
out List<string> errorList,
|
||||
int defaultEncoding)
|
||||
```
|
||||
**Behavior:** Main entry point for creating calculated channels. Dispatches to appropriate private creation methods based on the `Calculation` enum value. Returns an array of `Test.Module.CalculatedChannel` objects or `null` on failure. Validates channel names before returning. Sets `AbsoluteDisplayOrder` on each created channel.
|
||||
|
||||
### `ValidateChannelName`
|
||||
```csharp
|
||||
public static bool ValidateChannelName(
|
||||
string channelName,
|
||||
List<Test.Module.Channel> inputChannels,
|
||||
List<Test.Module.Channel> allChannels,
|
||||
out List<string> errorList)
|
||||
```
|
||||
**Behavior:** Validates that the channel name is non-empty and unique across both input channels and all channels. Returns `true` if validation passes (empty error list). If `allChannels` is `null`, returns `true` immediately with empty error list (special case for calls from `MakeCalculatedChannels()` in Download.xaml.cs per source comments).
|
||||
|
||||
### `ThreeDIRTraccType` (enum)
|
||||
```csharp
|
||||
public enum ThreeDIRTraccType
|
||||
{
|
||||
Thorax,
|
||||
Abdomen,
|
||||
LowerThorax
|
||||
}
|
||||
```
|
||||
**Behavior:** Defines the three anatomical positions for 3D IR-Tracc sensor calculations, each using different constants (`δ` and `D0`) from `SensorConstants`.
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **Channel Number Indicator:** All calculated channels use `ChannelNumberCalculationChannelIndicator` (100000) as a base offset for channel numbering.
|
||||
- **3D IR-Tracc Input Count:** Must have exactly 3 input channels (enforced by `Trace.Assert`).
|
||||
- **Aggregate Operation Input Count:** Must have at least 1 input channel (enforced by `Trace.Assert` for SUM/AVE/Resultant/HIC).
|
||||
- **Sample Rate Divisibility:** The maximum sample rate among input channels must be a multiple of all other input channel sample rates; otherwise `NotSupportedException` is thrown.
|
||||
- **Super-sampling Notification:** When input channels have different sample rates, a `PageErrorEvent` with `SuperSamplingWarning` is published via `IEventAggregator`.
|
||||
- **Data Scaling:** Output data is scaled to fit within `short.MaxValue` range for ADC representation.
|
||||
- **Engineering Units:** 3D IR-Tracc output channels use "mm" as engineering units; Sin/Cos use "rads".
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### This Module Depends On:
|
||||
- `DTS.Common.Enums.Sensors` - `SensorConstants` for IR-Tracc physical constants
|
||||
- `DTS.Common.Utilities.Logging` - `APILogger` for file operation logging
|
||||
- `DTS.Common.Utils` - `FileUtils` for file deletion
|
||||
- `DTS.Serialization` - `Serialization.SliceRaw.File` and related types for persistent storage
|
||||
- `DTS.Slice.Control` - Unclear specific usage from source alone
|
||||
- `DTS.Common` - `Constants.ADC_MIDPOINT`, `ZeroMethodType`
|
||||
- `DTS.Common.Events` - `PageErrorEvent`, `PageErrorArg`
|
||||
- `DTS.Common.Calculations` - `HeadInjuryCriterion` for HIC calculations
|
||||
- `DTS.Common.Utilities.Math.Nhtsa` - `Integration`, `Differentiation` classes
|
||||
- `Prism.Ioc` - `ContainerLocator` for service location
|
||||
- `Prism.Events` - `IEventAggregator` for event publishing
|
||||
- `Test.Module` namespace - `Channel`, `CalculatedChannel`, `AnalogInputChannel`
|
||||
- `Event.Module` namespace - `Channel`, `AnalogInputChannel` (EMC layer)
|
||||
|
||||
### What Depends On This Module:
|
||||
- Unclear from source alone; callers are external to this file.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
### Critical Bug in `CreateChannels` Return Logic
|
||||
Lines 54-57 contain inverted logic:
|
||||
```csharp
|
||||
if (ValidateChannelName(channelName, inputChannels, allChannels, out errorList)) return calculatedChannels;
|
||||
//ReportErrors(errorList);
|
||||
return null;
|
||||
```
|
||||
The method returns `calculatedChannels` when validation **succeeds** but then immediately returns `null` afterward (unreachable code for the error path). The commented-out `ReportErrors` suggests incomplete error handling. The intent appears reversed—validation failure should likely return `null`.
|
||||
|
||||
### Copy-Paste Bug in `PerformCalculation`
|
||||
Line 388 calculates `stepRPot1` using the wrong index variable:
|
||||
```csharp
|
||||
var stepRPot1 = Convert.ToInt32(Math.Ceiling(indexAtCurrentTimeIRTracc) - actualIndexAtCurrentTimeIRTracc);
|
||||
```
|
||||
This should likely use `indexAtCurrentTimeRPot1` instead of `indexAtCurrentTimeIRTracc`.
|
||||
|
||||
### Assignment in Conditional (Line 398)
|
||||
```csharp
|
||||
incrementRPot2 = (valueRPot2AtPoint = rPot2EUData[actualIndexAtCurrentTimeRPot2 - 1]) / rateRPot2;
|
||||
```
|
||||
This assigns to `valueRPot2AtPoint` inside a conditional branch, which differs from the parallel IRTracc and RPot1 branches that only read the value.
|
||||
|
||||
### Explicit GC Collection
|
||||
`CreatePersistentInformationObject` calls `GC.Collect()` before file deletion to release memory-mapped file handles—a potential performance concern.
|
||||
|
||||
### Debug/Test Data Injection
|
||||
`PerformCalculation` calls `DiskUtility.ReplaceDataIfNeeded` with hardcoded filenames ("DISPLEU.txt", "YPOTEU.txt", "ZPOTEU.txt"), suggesting debug/override capability that may affect production behavior.
|
||||
|
||||
### HIC Unit Conversion
|
||||
`PerformCalculationsAggregate` converts m/s² to g's (multiplying by 9.80665) for HIC calculations when engineering units are not already "g", but this conversion is applied inconsistently—only to `dataAtPoint` for the `dSumSquares` calculation, not to `dAggregateValue`.
|
||||
|
||||
### Unused Variable
|
||||
Line 246 declares `var timeAtIndex =` with no assignment or usage.
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
source_files:
|
||||
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.AddCalculatedChannel/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-16T13:59:10.185944+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "013fcfe349498337"
|
||||
---
|
||||
|
||||
# Documentation: DTS.Viewer.AddCalculatedChannel Assembly Configuration
|
||||
|
||||
## 1. Purpose
|
||||
This source file provides assembly-level metadata and configuration for the `DTS.Viewer.AddCalculatedChannel` module. It serves as the identity manifest for the compiled binary, defining its title, version, copyright, and COM visibility settings. Based on the assembly name, this module appears to be a plugin or component within the larger DTS Viewer application responsible for functionality related to adding derived or computed data channels.
|
||||
|
||||
## 2. Public Interface
|
||||
This file contains no executable classes, methods, or functions. It consists entirely of assembly-level attributes used by the .NET runtime and build system.
|
||||
|
||||
* **`AssemblyTitle`**: Set to `"DTS.Viewer.AddCalculatedChannel"`.
|
||||
* **`AssemblyProduct`**: Set to `"DTS.Viewer.AddCalculatedChannel"`.
|
||||
* **`AssemblyVersion`**: Set to `"1.0.0.0"`.
|
||||
* **`AssemblyFileVersion`**: Set to `"1.0.0.0"`.
|
||||
* **`Guid`**: Set to `"6451f3ed-934e-47e3-a1ca-33c223a6507a"`.
|
||||
* **`ComVisible`**: Set to `false`.
|
||||
|
||||
## 3. Invariants
|
||||
* **COM Visibility:** The types within this assembly are never visible to COM components (`ComVisible` is explicitly `false`).
|
||||
* **Culture Neutrality:** The assembly is marked with an empty `AssemblyCulture`, indicating it is culture-neutral and not a satellite assembly.
|
||||
* **Versioning:** Both the assembly version and file version are currently locked to the specific quadruple `1.0.0.0`.
|
||||
|
||||
## 4. Dependencies
|
||||
* **Internal Dependencies:**
|
||||
* `System.Reflection`
|
||||
* `System.Runtime.CompilerServices`
|
||||
* `System.Runtime.InteropServices`
|
||||
* **External Consumers:** The compiled assembly produced by this project is likely consumed by the main `DTS Viewer` application or a plugin loader, though specific consumers cannot be determined from this file alone.
|
||||
|
||||
## 5. Gotchas
|
||||
* **Missing Description:** The `AssemblyDescription` attribute is an empty string. Developers cannot rely on assembly metadata to understand the purpose of this module; they must inspect the code or external documentation.
|
||||
* **Static Versioning:** The `AssemblyVersion` and `AssemblyFileVersion` are hardcoded to `1.0.0.0`. They do not use the wildcard syntax (`"1.0.*"`) to auto-generate build/revision numbers, which may require manual updating for future releases.
|
||||
* **Legacy Project Structure:** The presence of a standalone `AssemblyInfo.cs` file suggests this is a legacy .NET Framework project structure (prior to the SDK-style project format introduced in .NET Core/5+), where this information is typically auto-generated.
|
||||
@@ -0,0 +1,145 @@
|
||||
---
|
||||
source_files:
|
||||
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.AddCalculatedChannel/Resources/TranslateExtension.cs
|
||||
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.AddCalculatedChannel/Resources/StringResources.Designer.cs
|
||||
generated_at: "2026-04-16T13:58:32.085292+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "5726c0d4d71935f1"
|
||||
---
|
||||
|
||||
# Documentation: DTS.Viewer.AddCalculatedChannel.Resources
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides localization infrastructure for the "Add Calculated Channel" feature within the DTS Viewer application. It enables XAML-based UI elements to bind to localized strings at design-time and runtime through a WPF markup extension pattern, while the `StringResources` class serves as a strongly-typed accessor for culture-specific strings related to calculation types, channel operations, IR-TRACC measurements, and validation error messages.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### TranslateExtension (MarkupExtension)
|
||||
|
||||
**Class Definition:**
|
||||
```csharp
|
||||
[MarkupExtensionReturnType(typeof(string))]
|
||||
public class TranslateExtension : MarkupExtension
|
||||
```
|
||||
|
||||
**Constructor:**
|
||||
```csharp
|
||||
public TranslateExtension(string key)
|
||||
```
|
||||
Initializes the extension with a resource key to look up.
|
||||
|
||||
**Method:**
|
||||
```csharp
|
||||
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||
```
|
||||
Returns the localized string for the provided `_key`. Returns `#stringnotfound#` if `_key` is null or empty. Returns `#stringnotfound# <key>` (where `<key>` is the actual key value) if the resource manager returns null for the given key.
|
||||
|
||||
---
|
||||
|
||||
### StringResources (Auto-generated Resource Class)
|
||||
|
||||
**Class Definition:**
|
||||
```csharp
|
||||
internal class StringResources
|
||||
```
|
||||
|
||||
**Properties:**
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `ResourceManager` | `global::System.Resources.ResourceManager` (static) | Cached ResourceManager instance for the `DTS.Viewer.AddCalculatedChannel.Resources.StringResources` resource bundle |
|
||||
| `Culture` | `global::System.Globalization.CultureInfo` (static) | Gets or sets the current thread's CurrentUICulture for resource lookups |
|
||||
|
||||
**Resource String Properties (static, read-only):**
|
||||
|
||||
| Property Name | Default Value (from comments) |
|
||||
|---------------|-------------------------------|
|
||||
| `AddCalculatedChannel` | "Add Calculated Channel" |
|
||||
| `CalculatedChannel_Average` | "Average" |
|
||||
| `CalculatedChannel_Sum` | "Sum" |
|
||||
| `CalculatedChannel_IRTRACC3D` | "3D IR-TRACC (upper thorax)" |
|
||||
| `CalculatedChannel_IRTRACC3D_Abdomen` | "3D IR-TRACC (abdomen)" |
|
||||
| `CalculatedChannel_IRTRACC3D_LowerThorax` | "3D IR-TRACC (lower thorax)" |
|
||||
| `CalculatedChannel_IRTRACC3D_Thorax` | "3D IR-TRACC (thorax)" |
|
||||
| `CalculatedChannel_IRTRACC3DAbdomen` | "3D IR-TRACC (abdomen)" |
|
||||
| `CalculatedChannel_IRTRACC3DLowerThorax` | "3D IR-TRACC (lower thorax)" |
|
||||
| `Calculation` | "Calculation" |
|
||||
| `CALCULATION_Cos` | "Cosine" |
|
||||
| `CALCULATION_Derivative` | "Derivative" |
|
||||
| `CALCULATION_DoubleIntegral` | "Double integral" |
|
||||
| `CALCULATION_Integral` | "Integral" |
|
||||
| `CALCULATION_Sin` | "Sine" |
|
||||
| `CALCULATION_ThreeDIRTracc` | "3D IR-TRACC (upper thorax)" |
|
||||
| `CALCULATION_ThreeDIRTraccAbdomen` | "3D IR-TRACC (abdomen)" |
|
||||
| `CALCULATION_ThreeDIRTraccLowerThorax` | "3D IR-TRACC (lower thorax)" |
|
||||
| `CalculationInputChannel` | "Calculation Input Channel" |
|
||||
| `Channel` | "Channel" |
|
||||
| `ChannelName` | "Channel Name" |
|
||||
| `ClipLengthMS` | "Clip length (ms)" |
|
||||
| `Description` | "Description" |
|
||||
| `HICAccelerationX` | "Acceleration X" |
|
||||
| `HICAccelerationY` | "Acceleration Y" |
|
||||
| `HICAccelerationZ` | "AccelerationZ" |
|
||||
| `HICRequires3Channels` | "Error: Head injury criterion requires 3 channels." |
|
||||
| `InputChannels` | "Input channels" |
|
||||
| `ISOCode` | "ISO Code" |
|
||||
| `NoChannelsIncluded` | "Error: No channels included." |
|
||||
| `ResultantUnitsDontMatch` | "Error: Units don't match for all input channels." |
|
||||
| `SampleRatesDontMatch` | "Error: Sample rates don't match for all input channels." |
|
||||
| `SuperSamplingWarning` | "Calculation contains multiple sample rates. Input will be resampled to the highest sample rate using linear interpolation." |
|
||||
| `ThreeD_IRTracc` | "IR-TRACC" |
|
||||
| `ThreeD_RotPot1` | "R. Pot Y" |
|
||||
| `ThreeD_RotPot2` | "R. Pot Z" |
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **TranslateExtension return guarantee:** `ProvideValue` always returns a non-null `string` object; it never returns null.
|
||||
- **Error indicator format:** Missing keys are indicated by the constant `#stringnotfound#` (exact literal, lowercase), optionally followed by a space and the key name.
|
||||
- **StringResources visibility:** The `StringResources` class is `internal` and only accessible within the `DTS.Viewer.AddCalculatedChannel` assembly.
|
||||
- **Auto-generation constraint:** `StringResources.Designer.cs` is auto-generated by `System.Resources.Tools.StronglyTypedResourceBuilder` (version 17.0.0.0). Manual edits will be lost upon regeneration.
|
||||
- **Resource bundle path:** Resources are loaded from the manifest resource name `"DTS.Viewer.AddCalculatedChannel.Resources.StringResources"`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### This module depends on:
|
||||
- `System` (core types)
|
||||
- `System.Windows.Markup` (for `MarkupExtension` and `MarkupExtensionReturnTypeAttribute`)
|
||||
- `System.Resources` (for `ResourceManager`)
|
||||
- `System.Globalization` (for `CultureInfo`)
|
||||
- `System.CodeDom.Compiler`, `System.Diagnostics`, `System.Runtime.CompilerServices`, `System.ComponentModel`, `System.Diagnostics.CodeAnalysis` (for auto-generated attributes)
|
||||
|
||||
### What depends on this module:
|
||||
- **Inferred:** XAML files within the `DTS.Viewer.AddCalculatedChannel` namespace that use the `{local:Translate KeyName}` markup extension syntax for localized UI strings.
|
||||
- **Inferred:** Code-behind files that reference `StringResources.<PropertyName>` for error messages and labels.
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
1. **Duplicate/near-duplicate resource keys:** Several IR-TRACC-related strings exist with different naming conventions that produce identical default values:
|
||||
- `CalculatedChannel_IRTRACC3D_Abdomen` and `CalculatedChannel_IRTRACC3DAbdomen` both default to "3D IR-TRACC (abdomen)"
|
||||
- `CalculatedChannel_IRTRACC3D_LowerThorax` and `CalculatedChannel_IRTRACC3DLowerThorax` both default to "3D IR-TRACC (lower thorax)"
|
||||
- `CALCULATION_ThreeDIRTracc` and `CalculatedChannel_IRTRACC3D` both default to "3D IR-TRACC (upper thorax)"
|
||||
|
||||
This may indicate a naming convention migration or accidental duplication. The source alone does not clarify which keys are actively used.
|
||||
|
||||
2. **Inconsistent key naming conventions:** Resource keys use at least three different naming patterns:
|
||||
- `PascalCase` (e.g., `Channel`, `Description`)
|
||||
- `Category_Property` (e.g., `CalculatedChannel_Average`)
|
||||
- `CATEGORY_Property` (e.g., `CALCULATION_Sin`, `CALCULATION_Derivative`)
|
||||
|
||||
Developers adding new keys should verify which convention is expected.
|
||||
|
||||
3. **Typo in HICAccelerationZ:** The default value is "AccelerationZ" (no space), whereas `HICAccelerationX` and `HICAccelerationY` have spaces ("Acceleration X", "Acceleration Y"). This inconsistency is visible in the source comments.
|
||||
|
||||
4. **NotFound constant is private:** The `NotFound` constant in `TranslateExtension` is `private const string`, so consumers cannot reference it for comparison. The literal `#stringnotfound#` would need to be hardcoded for string comparison checks.
|
||||
|
||||
5. **No null-coalescing on empty string:** `ProvideValue` checks `string.IsNullOrEmpty(_key)`, returning `NotFound` without appending the key. However, if `_key` is an empty string, the caller receives `#stringnotfound#` without indication that an empty string was passed.
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
source_files:
|
||||
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.AddCalculatedChannel/View/AddCalculatedChannelView.xaml.cs
|
||||
generated_at: "2026-04-16T13:59:47.969397+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "13409539a2c3243c"
|
||||
---
|
||||
|
||||
# Documentation: AddCalculatedChannelView.xaml.cs
|
||||
|
||||
## 1. Purpose
|
||||
This file defines the code-behind class `AddCalculatedChannelView` for a WPF XAML user interface component. It serves as the visual view for the "Add Calculated Channel" feature within the DTS Viewer application. Its primary role is to implement the `IAddCalculatedChannelView` interface, allowing it to be consumed by other components (likely a presenter or view model) while handling the initialization of the XAML component tree.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Class: `AddCalculatedChannelView`
|
||||
- **Inheritance:** Implements `IAddCalculatedChannelView`.
|
||||
- **Modifiers:** `public`, `partial`.
|
||||
|
||||
#### Constructor: `AddCalculatedChannelView()`
|
||||
- **Signature:** `public AddCalculatedChannelView()`
|
||||
- **Behavior:** Calls `InitializeComponent()`, which loads and initializes the XAML-defined UI layout associated with this code-beind file.
|
||||
|
||||
## 3. Invariants
|
||||
- **Partial Definition:** The class is defined as `partial`. A corresponding XAML file (`AddCalculatedChannelView.xaml`) must exist to provide the other part of the class definition (typically defining the base class and UI elements).
|
||||
- **Interface Compliance:** The class must fulfill any contract defined by `IAddCalculatedChannelView` (imported from `DTS.Common.Interface`), though no explicit interface members are visible in this specific source file.
|
||||
|
||||
## 4. Dependencies
|
||||
- **External Dependencies:**
|
||||
- `DTS.Common.Interface`: Required for the `IAddCalculatedChannelView` interface.
|
||||
- **Implicit Dependencies:**
|
||||
- WPF Subsystem: Relies on `InitializeComponent()`, a standard method usually generated by the WPF build process.
|
||||
- `AddCalculatedChannelView.xaml`: The markup file corresponding to this code-behind.
|
||||
|
||||
## 5. Gotchas
|
||||
- **Namespace Mismatch:** The source contains `// ReSharper disable CheckNamespace`. This directive suppresses the IDE warning that the namespace `DTS.Viewer.AddCalculatedChannel` does not match the file path structure (`DTS.Viewer.Modules/DTS.Viewer.AddCalculatedChannel/View/`). Developers should be aware that the namespace is intentionally flattened or differs from the folder hierarchy.
|
||||
- **Hidden Base Class:** The C# code shows the class inheriting from `IAddCalculatedChannelView`. In a standard WPF setup, the class would also inherit from a base class like `UserControl` or `Window`. This inheritance is typically defined in the root element of the XAML file, not the C# `class` declaration. Therefore, the concrete UI base type is not visible in this source file alone.
|
||||
@@ -0,0 +1,215 @@
|
||||
---
|
||||
source_files:
|
||||
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.AddCalculatedChannel/ViewModel/AddCalculatedChannelViewModel.cs
|
||||
generated_at: "2026-04-16T13:58:53.491336+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "5cfd5d272102b3bf"
|
||||
---
|
||||
|
||||
# Documentation: AddCalculatedChannelViewModel
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
The `AddCalculatedChannelViewModel` class provides the presentation logic for creating and adding calculated channels to test data within the DTS Viewer application. It supports multiple calculation types including mathematical operations (Integral, Double Integral, Derivative, Sin, Cos), aggregate functions (SUM, Average, Resultant), and specialized biomechanical calculations (3D IR-Tracc variants, HIC - Head Injury Criterion). The ViewModel manages channel selection UI state, validates user inputs, persists calculated channels to `.dts` test files, and coordinates with the event aggregation system for cross-component communication.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Class Declaration
|
||||
```csharp
|
||||
public class AddCalculatedChannelViewModel : BaseViewModel<IAddCalculatedChannelViewModel>, IAddCalculatedChannelViewModel
|
||||
```
|
||||
|
||||
### Constructor
|
||||
```csharp
|
||||
public AddCalculatedChannelViewModel(IAddCalculatedChannelView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)
|
||||
```
|
||||
Initializes the ViewModel with its associated view, region manager for UI composition, event aggregator for pub/sub messaging, and Unity dependency injection container.
|
||||
|
||||
### Public Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `View` | `IBaseView` | The associated view instance; DataContext is set to `this` in constructor. |
|
||||
| `Parent` | `IBaseViewModel` | Parent ViewModel passed during initialization. |
|
||||
| `ContextSearchRegion` | `object` | Context region placeholder. |
|
||||
| `NotificationRequest` | `InteractionRequest<Notification>` | Raises notification dialogs. |
|
||||
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | Raises confirmation dialogs (hides base member). |
|
||||
| `HeaderInfo` | `string` | Returns `"AddCalculatedChannelRegion"`. |
|
||||
| `IsBusy` | `bool` | Throws `NotImplementedException` on get/set. |
|
||||
| `IsDirty` | `bool` | Throws `NotImplementedException` on get. |
|
||||
| `IsAddCalculatedChannelIncluded` | `bool` | Feature inclusion flag. |
|
||||
| `IncludeGroupNameInISOExport` | `bool` | Controls ISO export format. |
|
||||
| `DefaultDTSEncoding` | `int` | Encoding codepage for DTS file operations. |
|
||||
| `ChannelName` | `string` | Name for the new calculated channel. |
|
||||
| `ChannelDescription` | `string` | Auto-generated description based on selected calculation and channels. |
|
||||
| `IsoCode` | `string` | ISO code identifier; defaults to `"NONE"`. |
|
||||
| `SingleChannelSelectorVisibility` | `bool` | Controls visibility for single-channel selection UI. |
|
||||
| `MultipleChannelSelectorVisibility` | `bool` | Controls visibility for multi-channel selection UI. |
|
||||
| `HICChannelSelectorVisibility` | `bool` | Controls visibility for HIC-specific channel selection. |
|
||||
| `ThreeDIRTRACCVisibility` | `bool` | Controls visibility for 3D IR-Tracc channel selection. |
|
||||
| `CalculationList` | `CalculationHelper[]` | Lazy-initialized list of available calculations. |
|
||||
| `SelectedCalculation` | `CalculationHelper` | Currently selected calculation type; setter updates UI visibility states. |
|
||||
| `ChannelList` | `ObservableCollection<ITestChannel>` | All available input channels. |
|
||||
| `ChannelListObjects` | `ObservableCollection<ChannelHelper>` | Wrapped channel objects with inclusion tracking. |
|
||||
| `SourceChannel` | `ITestChannel` | Selected source channel for single-channel calculations. |
|
||||
| `AvailableHICChannels` | `ChannelHelper[]` | Channels with acceleration units valid for HIC calculation. |
|
||||
| `HICAccelerationX` | `ChannelHelper` | X-axis acceleration channel for HIC. |
|
||||
| `HICAccelerationY` | `ChannelHelper` | Y-axis acceleration channel for HIC. |
|
||||
| `HICAccelerationZ` | `ChannelHelper` | Z-axis acceleration channel for HIC. |
|
||||
| `HICLength` | `int` | HIC calculation length parameter; defaults to `16`. |
|
||||
| `IRTraccChannelList` | `ObservableCollection<ChannelHelper>` | Valid IR-Tracc channels. |
|
||||
| `IRTraccChannel` | `ChannelHelper` | Selected IR-Tracc channel. |
|
||||
| `Pot1ChannelList` | `ObservableCollection<ChannelHelper>` | Valid potentiometer 1 channels. |
|
||||
| `Pot1Channel` | `ChannelHelper` | Selected potentiometer 1 channel. |
|
||||
| `Pot2ChannelList` | `ObservableCollection<ChannelHelper>` | Valid potentiometer 2 channels. |
|
||||
| `Pot2Channel` | `ChannelHelper` | Selected potentiometer 2 channel. |
|
||||
|
||||
### Public Methods
|
||||
|
||||
```csharp
|
||||
public void PublishChanges()
|
||||
```
|
||||
Empty implementation (commented `NotImplementedException`).
|
||||
|
||||
```csharp
|
||||
public override void Initialize()
|
||||
public override void Initialize(object parameter)
|
||||
```
|
||||
Sets `Parent` from parameter and subscribes to events.
|
||||
|
||||
```csharp
|
||||
public override void Activated()
|
||||
```
|
||||
Resets UI state: sets default `SourceChannel`, `IsoCode` to `"NONE"`, `ChannelName` to `"New Channel"`, clears HIC selections, sets `HICLength` to `16`.
|
||||
|
||||
```csharp
|
||||
public override void Cleanup()
|
||||
```
|
||||
Empty implementation.
|
||||
|
||||
```csharp
|
||||
public bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)
|
||||
```
|
||||
Validates channel name and calculation-specific requirements (HIC requires 3 channels; Resultant requires matching units and sample rates).
|
||||
|
||||
```csharp
|
||||
public bool ValidateChannelName()
|
||||
```
|
||||
Returns `true` if `ChannelName` is non-empty.
|
||||
|
||||
### Commands
|
||||
|
||||
```csharp
|
||||
public ICommand AddCalculatedChannelCommand { get; private set; }
|
||||
```
|
||||
Executes `AddCalculatedChannel(object obj)` which validates input, creates calculated channels via `CalculatedChannelCreator.CreateChannels()`, adds them to the test structure, and persists changes to `.dts` files.
|
||||
|
||||
### Public Enum
|
||||
|
||||
```csharp
|
||||
public enum Calculation
|
||||
{
|
||||
[Description("Integral")] Integral = 0,
|
||||
[Description("Double Integral")] DoubleIntegral = 1,
|
||||
[Description("Derivative")] Derivative = 2,
|
||||
[Description("Sin")] Sin = 3,
|
||||
[Description("Cos")] Cos = 4,
|
||||
[Description("3D IR-Tracc")] ThreeDIRTracc = 5,
|
||||
[Description("SUM")] SUM = 6,
|
||||
[Description("Average")] AVE = 7,
|
||||
[Description("3D IR-TRACC Abdomen")] ThreeDIRTraccAbdomen = 8,
|
||||
[Description("3D IR-TRACC Lower Thorax")] ThreeDIRTraccLowerThorax = 9,
|
||||
[Description("Resultant")] Resultant = 10,
|
||||
[Description("HIC")] HIC = 11
|
||||
}
|
||||
```
|
||||
|
||||
### Nested Public Classes
|
||||
|
||||
```csharp
|
||||
public class ChannelHelper : BasePropertyChanged
|
||||
```
|
||||
Wraps `ITestChannel` with `DisplayName`, `ChannelName`, and `IsIncluded` properties for UI binding.
|
||||
|
||||
```csharp
|
||||
public class CalculationHelper
|
||||
```
|
||||
Wraps `Calculation` enum with localized `ToString()` via resource manager.
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
1. **Channel Name Validation**: `ChannelName` must be non-null and non-empty for validation to pass.
|
||||
2. **HIC Channel Requirement**: HIC calculation requires all three acceleration channels (`HICAccelerationX`, `HICAccelerationY`, `HICAccelerationZ`) to be non-null.
|
||||
3. **Resultant Channel Consistency**: All channels included in a Resultant calculation must have identical `SensitivityUnits` and `SampleRateHz`.
|
||||
4. **Display Order Preservation**: Channels are sorted by `AbsoluteDisplayOrder` when determining insertion position for new calculated channels.
|
||||
5. **File Backup Behavior**: Backup files (`.dtsbak`) are created only if one does not already exist; original file is preserved.
|
||||
6. **IR-Tracc Channel Eligibility**: IR-Tracc channels must be `AnalogInputChannel` type with valid `LinearizationFormula`, `ZeroMethod` of `None`, non-zero `ZeroPoint`, and non-zero `FactoryExcitationVoltage`.
|
||||
7. **Potentiometer Channel Eligibility**: Pot channels must be `AnalogInputChannel` type with units `"deg"` or `"deg-ang"`, `ZeroMethod` of `None`, and non-zero `FactoryExcitationVoltage`.
|
||||
8. **HIC Channel Filtering**: Only channels with units in `Constants.ACCELERATION_UNITS` are available for HIC selection.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### External Dependencies (from imports)
|
||||
- `Prism.Events` - `IEventAggregator` for event pub/sub
|
||||
- `Prism.Regions` - `IRegionManager` for UI region management
|
||||
- `Unity` - `IUnityContainer` for dependency injection
|
||||
- `DTS.Serialization.Test` - Test data structures
|
||||
- `DTS.Serialization.SliceRaw.File` - File I/O for `.dts` files
|
||||
|
||||
### Internal Dependencies
|
||||
- `DTS.Common` / `DTS.Common.Base` - Base classes, constants
|
||||
- `DTS.Common.Classes.Viewer.Commands` - `RelayCommand`
|
||||
- `DTS.Common.DAS.Concepts` - `ITestChannel` interface
|
||||
- `DTS.Common.Enums.Sensors` - `ZeroMethodType`
|
||||
- `DTS.Common.Events` - Event types (`RaiseNotification`, `TestSummaryChangeNotification`, `PageErrorEvent`, `SetSaveButton`, `RefreshTestRequestEvent`)
|
||||
- `DTS.Common.Interactivity` - `InteractionRequest<T>`, `Notification`, `Confirmation`
|
||||
- `DTS.Common.Interface` - `IAddCalculatedChannelView`, `IAddCalculatedChannelViewModel`
|
||||
- `DTS.Common.Utilities.Logging` - `APILogger`
|
||||
- `DTS.Common.Utils` - `Utils` static helpers
|
||||
- `DTS.Slice.Control` - Slice control functionality
|
||||
- `DTS.Viewer.AddCalculatedChannel.Model` - `CalculatedChannelCreator`, `LinearizationFormula`
|
||||
|
||||
### Events Consumed
|
||||
- `RaiseNotification` - Displays notification dialogs
|
||||
- `TestSummaryChangeNotification` - Triggers channel list population
|
||||
|
||||
### Events Published
|
||||
- `PageErrorEvent` - Publishes validation errors/warnings
|
||||
- `SetSaveButton` - Controls save button enabled state
|
||||
- `RefreshTestRequestEvent` - Triggers test data refresh after save
|
||||
- `RaiseNotification` - Displays error messages
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
1. **NotImplementedException on IsBusy/IsDirty**: Both properties throw on access. These appear to be placeholder implementations that were never completed.
|
||||
|
||||
2. **HIC Save Button Logic Appears Inverted**: In `UpdateSaveButtonVisibility()`, the HIC case sets `IsUsable = true` when channels are null and `IsUsable = false` when all three are set—the opposite of expected behavior:
|
||||
```csharp
|
||||
if (null == HICAccelerationX || null == HICAccelerationY || null == HICAccelerationZ)
|
||||
{
|
||||
_eventAggregator.GetEvent<SetSaveButton>().Publish(new SaveButtonUsability() { IsUsable = true });
|
||||
}
|
||||
else
|
||||
{
|
||||
_eventAggregator.GetEvent<SetSaveButton>().Publish(new SaveButtonUsability() { IsUsable = false });
|
||||
}
|
||||
```
|
||||
|
||||
3. **Member Hiding with `new` Keyword**: Several members (`PropertyChanged`, `OnPropertyChanged`, `IsBusy`, `IsDirty`, `ConfirmationRequest`) hide base class members using `new`, which may cause confusion when casting to base types.
|
||||
|
||||
4. **Empty PublishChanges() Method**: The `PublishChanges()` method has a commented-out `NotImplementedException` with no implementation, suggesting incomplete feature work.
|
||||
|
||||
5. **Hardcoded Thread.Sleep**: A 10ms `Thread.Sleep()` is used after file write operations in `AddCalculatedChannel()`—this is a potential code smell for file I/O timing issues.
|
||||
|
||||
6. **Test ID Extraction Fragility**: `GetTestIdFromBinaryFileName()` parses the test ID from binary filenames by looking for `"Ch"` substring; if not found, it uses the entire prefix which may produce incorrect results.
|
||||
|
||||
7. **Duplicate Channel Handling**: When adding a calculated channel, existing channels with the same `ChannelId` are silently removed without user confirmation (logged only).
|
||||
Reference in New Issue
Block a user