Files
2026-04-17 14:55:32 -04:00

6.4 KiB

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.AddCalculatedChannel/Model/CalculatedChannelCreator.cs
2026-04-16T13:59:32.414209+00:00 zai-org/GLM-5-FP8 1 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

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

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)

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:

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:

var stepRPot1 = Convert.ToInt32(Math.Ceiling(indexAtCurrentTimeIRTracc) - actualIndexAtCurrentTimeIRTracc);

This should likely use indexAtCurrentTimeRPot1 instead of indexAtCurrentTimeIRTracc.

Assignment in Conditional (Line 398)

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.