Files
DP44/enriched-qwen3-coder-next/Common/DTS.Common.Calculations.md
2026-04-17 14:55:32 -04:00

6.7 KiB

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
Common/DTS.Common.Calculations/ChannelData.cs
Common/DTS.Common.Calculations/Integral.cs
Common/DTS.Common.Calculations/Resultant.cs
Common/DTS.Common.Calculations/HeadInjuryCriterion.cs
2026-04-16T14:13:55.996245+00:00 zai-org/GLM-5-FP8 1 2d2deac012cb62cf

DTS.Common.Calculations Module Documentation

1. Purpose

This module provides mathematical calculation utilities for signal processing in biomechanical analysis contexts. It contains data structures for holding filtered channel data (ChannelData), numerical integration via trapezoidal summation (Integral), resultant vector computation from multiple input channels (Resultant), and Head Injury Criterion (HIC) calculation used in impact testing scenarios (HeadInjuryCriterion). The module is designed to work with pre-filtered engineering unit data sampled at consistent rates.


2. Public Interface

ChannelData (Class)

Namespace: DTS.Common.Calculations

Simple data container for filtered channel data.

Member Signature Description
Units public string Units { get; } Read-only engineering units of the data. Set via constructor.
FilteredEU public double[] FilteredEU { get; set; } Pre-filtered engineering unit data array. Mutable.
Constructor public ChannelData(string units) Constructs a new ChannelData instance with the specified units. FilteredEU is not initialized by constructor.

Integral (Static Class)

Namespace: DTS.Common.Calculations

Method Signature Description
DefiniteIntegral public static double DefiniteIntegral(double[] input, int start, int end, double SPS) Computes the definite integral of input from index start to end (both inclusive) using trapezoidal summation. SPS is samples per second (divisor for time normalization).

Resultant (Static Class)

Namespace: DTS.Common.Calculations

Method Signature Description
GenerateResultantChannel public static ChannelData GenerateResultantChannel(List<ChannelData> channels) Computes the resultant vector from multiple input channels using sum-of-squares: √(Σ ch[i]²). Returns a new ChannelData with the resultant values. Units are taken from the first input channel.

HeadInjuryCriterion (Static Class)

Namespace: DTS.Common.Calculations

Method Signature Description
GetHeadInjuryCriterion public static HICResult GetHeadInjuryCriterion(ChannelData resultant, double SPS, int clipLengthMS) Calculates the maximum Head Injury Criterion over the input data for the specified clip length. Uses brute-force exhaustive search across all clip lengths from 1 sample up to clipLengthMS.

HeadInjuryCriterion.HICResult (Nested Class)

Member Signature Description
StartSample public int StartSample { get; } Start sample index of the maximum HIC window.
EndSample public int EndSample { get; } End sample index of the maximum HIC window.
HicLengthMS public int HicLengthMS { get; } Length of the HIC window in milliseconds.
HIC public double HIC { get; } The calculated HIC value.
Constructor public HICResult(double hic, int hicLength, int startSample, int endSample) Constructs a new HICResult. Note: parameter order is hic, hicLength, startSample, endSample.

3. Invariants

  • ChannelData.Units is immutable after construction; it can only be set via the constructor.
  • ChannelData.FilteredEU is not initialized by the constructor and must be set before use.
  • Integral.DefiniteIntegral assumes input data is tightly time-aligned (uniform sampling interval).
  • Resultant.GenerateResultantChannel requires all input channels to have identical FilteredEU.Length values.
  • Resultant.GenerateResultantChannel requires all input channels to have identical Units values.
  • HeadInjuryCriterion.GetHeadInjuryCriterion requires SPS > 0 and clipLengthMS > 0.
  • HeadInjuryCriterion.GetHeadInjuryCriterion requires resultant.FilteredEU.Length to be at least as many samples as clipLengthMS represents at the given SPS.

4. Dependencies

This module depends on:

  • System (for Math, Convert, DateTime-related types)
  • System.Collections.Generic (for List<T>)
  • System.Linq (for Distinct(), Max(), First(), Select())
  • System.Diagnostics (for Trace.Assert)

What depends on this module:

  • Unclear from source alone — no internal module references indicate consumers. This appears to be a low-level calculation library intended for use by higher-level analysis or data processing modules.

5. Gotchas

  1. HICResult constructor parameter order differs from property order: The constructor signature is (double hic, int hicLength, int startSample, int endSample), but the XML documentation comments incorrectly describe the parameters in a different order. The actual parameter mapping is:

    • hicHIC
    • hicLengthHicLengthMS
    • startSampleStartSample
    • endSampleEndSample
  2. Assertions in production code: Both Resultant.GenerateResultantChannel and HeadInjuryCriterion.GetHeadInjuryCriterion use System.Diagnostics.Trace.Assert for input validation. These assertions may not throw exceptions in release builds depending on configuration, potentially allowing invalid states to propagate silently.

  3. Brute-force HIC algorithm: GetHeadInjuryCriterion uses an O(n²) brute-force approach, recalculating integrals exhaustively. The source explicitly acknowledges this inefficiency with a comment: "we can do this much better without a doubt, but lets get the first method done (brute force)".

  4. ChannelData.FilteredEU is unset after construction: The constructor only sets Units. Callers must manually assign FilteredEU after instantiation, or the property will be null.

  5. Integral.DefiniteIntegral boundary behavior: The loop iterates from start + 1 to end - 1 (exclusive of end), then adds input[start] and input[end] separately. This is correct trapezoidal integration but may be counterintuitive compared to typical half-open interval patterns in C#.

  6. Future parallelization comment in Resultant: The source contains a comment indicating intent to parallelize the loop in a future version, noting that values.Add would need to be replaced with an indexer. Current implementation is single-threaded.