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

11 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/ViewModel/AddCalculatedChannelViewModel.cs
2026-04-16T13:58:53.491336+00:00 zai-org/GLM-5-FP8 1 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

public class AddCalculatedChannelViewModel : BaseViewModel<IAddCalculatedChannelViewModel>, IAddCalculatedChannelViewModel

Constructor

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

public void PublishChanges()

Empty implementation (commented NotImplementedException).

public override void Initialize()
public override void Initialize(object parameter)

Sets Parent from parameter and subscribes to events.

public override void Activated()

Resets UI state: sets default SourceChannel, IsoCode to "NONE", ChannelName to "New Channel", clears HIC selections, sets HICLength to 16.

public override void Cleanup()

Empty implementation.

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).

public bool ValidateChannelName()

Returns true if ChannelName is non-empty.

Commands

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

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

public class ChannelHelper : BasePropertyChanged

Wraps ITestChannel with DisplayName, ChannelName, and IsIncluded properties for UI binding.

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:

    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).