Files
DP44/Common/DTS.Common.Calculations/HeadInjuryCriterion.cs
2026-04-17 14:55:32 -04:00

70 lines
3.1 KiB
C#

using System;
namespace DTS.Common.Calculations
{
public class HeadInjuryCriterion
{
/// <summary>
/// Calculates the head injury criterion given a resultant channel, and a desired clip length
/// </summary>
/// <param name="resultant">Acceleration vector (x,y,z resultant)</param>
/// <param name="SPS">Actual sample rate</param>
/// <param name="clipLengthMS">Length in ms </param>
/// <returns>MAX Head Injury Criterion over the data input for the clip requested</returns>
public static HICResult GetHeadInjuryCriterion(ChannelData resultant, double SPS, int clipLengthMS)
{
System.Diagnostics.Trace.Assert(SPS > 0, "Actual sample rate must be positive");
System.Diagnostics.Trace.Assert(clipLengthMS > 0, "Clip length must be positive");
int maxHICPoint = int.MinValue;
double maxHIC = int.MinValue;
int maxHICEndPoint = int.MinValue;
int maxclip = Convert.ToInt32(Math.Ceiling(clipLengthMS * SPS / 1000D));
for (int clip = 1; clip <= maxclip; clip++)
{
System.Diagnostics.Trace.Assert(clip < resultant.FilteredEU.Length, string.Format("data must be atleast {0} ms", clipLengthMS));
double clipInSeconds = clip / SPS;
for (int i = 0; i < resultant.FilteredEU.Length - clip; i++)
{
//note we are exhaustively recalculating sums, we can do this much better without a doubt, but lets get the
//first method done (brute force)
//also note, definite integral doesn't include last point, so we have to add one point back in
double integral = Integral.DefiniteIntegral(resultant.FilteredEU, i, i + clip, SPS);
double hic = clipInSeconds * Math.Pow(integral / clipInSeconds, 2.5D);
if (hic > maxHIC) { maxHIC = hic; maxHICPoint = i; maxHICEndPoint = i + clip; }
}
}
return new HICResult(maxHIC, clipLengthMS, maxHICPoint, maxHICEndPoint);
}
/// <summary>
/// helper class for storing/handling hic results
/// </summary>
public class HICResult
{
public int StartSample { get; }
public int EndSample { get; }
public int HicLengthMS { get; }
public double HIC { get; }
/// <summary>
/// constructs a new HIC result
/// </summary>
/// <param name="hic">HIC value</param>
/// <param name="hicLength">length of HIC in ms</param>
/// <param name="endSample">start sample of HIC</param>
/// <param name="startSample">end sample of HIC</param>
public HICResult(double hic, int hicLength, int startSample, int endSample)
{
StartSample = startSample;
EndSample = endSample;
HicLengthMS = hicLength;
HIC = hic;
}
}
}
}