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.
|
||||
Reference in New Issue
Block a user