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

9.5 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-16T11:21:00.745415+00:00 zai-org/GLM-5-FP8 1 5cfd5d272102b3bf

Documentation: AddCalculatedChannelViewModel

1. Purpose

This module provides a ViewModel for the "Add Calculated Channel" feature in the DTS Viewer application. It enables users to create derived data channels from existing test data by applying mathematical transformations (integrals, derivatives, trigonometric functions) or specialized biomechanical calculations (HIC, 3D IR-Tracc, Resultant). The ViewModel manages channel selection UI state, validates user inputs, orchestrates the calculated channel creation via CalculatedChannelCreator, and persists changes back to .dts test files.


2. Public Interface

Public Properties

Property Type Description
View IBaseView The associated view instance.
Parent IBaseViewModel Reference to the parent ViewModel.
ContextSearchRegion object Placeholder for context search region.
NotificationRequest InteractionRequest<Notification> Raises notification dialogs.
ConfirmationRequest InteractionRequest<Confirmation> Raises confirmation dialogs.
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 formatting.
DefaultDTSEncoding int Encoding code page 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 for the channel (defaults to "NONE").
SingleChannelSelectorVisibility bool Controls visibility for single-channel selection UI.
HICChannelSelectorVisibility bool Controls visibility for HIC channel selection UI.
MultipleChannelSelectorVisibility bool Controls visibility for multi-channel selection UI.
ThreeDIRTRACCVisibility bool Controls visibility for 3D IR-Tracc selection UI.
CalculationList CalculationHelper[] Lazy-initialized list of available calculations.
SelectedCalculation CalculationHelper Currently selected calculation type.
ChannelList ObservableCollection<ITestChannel> All available input channels.
ChannelListObjects ObservableCollection<ChannelHelper> Wrapped channel objects with IsIncluded selection state.
AvailableHICChannels ChannelHelper[] Channels with acceleration units valid for HIC calculation.
HICAccelerationX/Y/Z ChannelHelper Selected X/Y/Z acceleration channels for HIC.
HICLength int HIC calculation length (default: 16).
SourceChannel ITestChannel Selected source channel for single-channel calculations.
IRTraccChannelList ObservableCollection<ChannelHelper> Valid IR-Tracc channels.
IRTraccChannel ChannelHelper Selected IR-Tracc channel.
Pot1ChannelList/Pot2ChannelList ObservableCollection<ChannelHelper> Valid potentiometer channels.
Pot1Channel/Pot2Channel ChannelHelper Selected potentiometer channels.

Public Commands

Command Handler Description
AddCalculatedChannelCommand AddCalculatedChannel(object obj) Validates inputs, creates calculated channel(s), and saves to .dts file.

Public Methods

Method Signature Description
PublishChanges void PublishChanges() Not implemented (contains commented-out NotImplementedException).
Initialize void Initialize() Calls Initialize(null).
Initialize void Initialize(object parameter) Sets Parent from parameter and subscribes to events.
Activated void Activated() Resets UI state: sets default source channel, ISO code, calculation, and channel name.
Cleanup void Cleanup() Empty implementation.
Validate bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow) Validates channel name and calculation-specific requirements.

Public Enums

Calculation

Defines available calculation types with Description attributes for display:

Value Description
Integral = 0 "Integral"
DoubleIntegral = 1 "Double Integral"
Derivative = 2 "Derivative"
Sin = 3 "Sin"
Cos = 4 "Cos"
ThreeDIRTracc = 5 "3D IR-Tracc"
SUM = 6 "SUM"
AVE = 7 "Average"
ThreeDIRTraccAbdomen = 8 "3D IR-TRACC Abdomen"
ThreeDIRTraccLowerThorax = 9 "3D IR-TRACC Lower Thorax"
Resultant = 10 "Resultant"
HIC = 11 "HIC"

Public Nested Classes

ChannelHelper : BasePropertyChanged

Wraps ITestChannel for UI binding with DisplayName formatting based on IsoViewModeStatic.ViewMode and IsIncluded selection state.

CalculationHelper

Wraps a Calculation enum value with localized string display via StringResources.ResourceManager.GetString("CALCULATION_" + MyCalculation).


3. Invariants

  1. Channel Name Validation: ValidateChannelName() returns true only if ChannelName is not null or empty.

  2. HIC Calculation Requirements: ValidateHIC() requires all three acceleration channels (HICAccelerationX, HICAccelerationY, HICAccelerationZ) to be non-null.

  3. Resultant Calculation Requirements: ValidateResultant() requires:

    • At least one channel with IsIncluded == true
    • All included channels must have matching SensitivityUnits
    • All included channels must have matching SampleRateHz
  4. Display Order: New calculated channels are assigned maxDisplayOrder + 1 from existing channels.

  5. Channel Uniqueness: ChannelList excludes duplicate channels by ChannelId during population.

  6. IR-Tracc Channel Filtering: Channels appear in IRTraccChannelList only if:

    • ChannelType is Test.Module.AnalogInputChannel
    • LinearizationFormula is valid per LinearizationFormula.IsValid()
    • ZeroMethod equals ZeroMethodType.None
    • ZeroPoint != 0
    • FactoryExcitationVoltage != 0
  7. Potentiometer Channel Filtering: Channels appear in Pot1ChannelList/Pot2ChannelList only if:

    • ChannelType is Test.Module.AnalogInputChannel
    • Eu is "deg" or "deg-ang" (case-insensitive, trimmed)
    • ZeroMethod equals ZeroMethodType.None
    • FactoryExcitationVoltage != 0

4. Dependencies

This Module Depends On

  • DTS.Common - Constants, utilities
  • DTS.Common.Base - BaseViewModel<T>, BasePropertyChanged
  • DTS.Common.Classes.Viewer.Commands - RelayCommand
  • DTS.Common.DAS.Concepts - Data concepts
  • 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 - IAddCalculatedChannelViewModel, IBaseView, IBaseViewModel, ITestChannel
  • DTS.Common.Utilities.Logging - APILogger
  • DTS.Common.Utils - Utils class for channel info loading
  • DTS.Slice.Control - Slice control functionality
  • DTS.Viewer.AddCalculatedChannel.Model - Model types (inferred)
  • DTS.Serialization - Test, TestSetup, SliceRaw.File
  • Prism.Events - IEventAggregator
  • Prism.Regions - IRegionManager
  • Unity - IUnityContainer

Events Subscribed

  • RaiseNotificationOnRaiseNotification
  • TestSummaryChangeNotificationOnTestSummaryChanged

Events Published

  • RaiseNotification
  • PageErrorEvent
  • SetSaveButton
  • RefreshTestRequestEvent

5. Gotchas

  1. IsBusy and IsDirty Throw Exceptions: Both properties throw NotImplementedException. Code paths that access these will fail at runtime.

  2. HIC Save Button Logic Appears Inverted: In UpdateSaveButtonVisibility(), the HIC case sets IsUsable = true when acceleration channels are null and IsUsable = false when they are not null. This contradicts the validation logic in ValidateHIC() which requires non-null channels. This appears to be a bug.

  3. File Backup Behavior: The .dts backup file (with BACKUP_FILE_EXTENSION) is created only if one doesn't already exist. The backup is deleted after successful save only if it was created during that save operation.

  4. Hardcoded Thread.Sleep: A Thread.Sleep(10) exists after file writing in AddCalculatedChannel(). Purpose is unclear from source alone.

  5. Lazy Channel Loading: In OnTestSummaryChanged(), if ts.Channels.FirstOrDefault() == null, channels are loaded on-demand via Utils.SetChannelInfo(). This side effect may not be obvious to callers.

  6. Duplicate Calculated Channel Handling: AddCalculatedChannelToTest() silently overwrites existing calculated channels with matching ChannelId by removing the duplicate before adding the new one. A log message is generated but no user confirmation is requested.

  7. PublishChanges() Not Implemented: The method body contains only a commented-out NotImplementedException. It is unclear if this is intentional or incomplete.