Files
DP44/Common/DTS.Common.Utilities/DataWindowAverager.cs

236 lines
8.3 KiB
C#
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
/*
* DataWindowAverager.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Linq;
using DTS.Common.Utilities.DotNetProgrammingConstructs;
namespace DTS.Common.Utilities
{
/// <summary>
/// Time averaging data over a specific window
/// there can be pretrigger time and begin time can be used to compute the start
/// of the averaging window
/// </summary>
public partial class DataWindowAverager : Exceptional
{ ///
/// <summary>
/// Initialize an instance of this data window averager class.
/// </summary>
///
/// <param name="beginTimeSec">
/// Get the <see cref="double"/> time value (sec) of the start of the averaging window.
/// </param>
///
/// <param name="endTimeSec">
/// Get the <see cref="double"/> time value (sec) of the end of the averaging window.
/// </param>
///
/// <param name="preTriggerTimeSec">
/// Get the <see cref="double"/> pre-trigger time (sec).
/// </param>
///
/// <param name="sampleRateHz">
/// Get the <see cref="double"/> sample rate (Hz).
/// </param>
///
/// <param name="defaultValue">
/// Get the default <see cref="short"/> ADC value to be returned if the specified window
/// is invalid.
/// </param>
///
public DataWindowAverager(
double beginTimeSec,
double endTimeSec,
double preTriggerTimeSec,
double sampleRateHz,
short defaultValue)
{
try
{
BeginTimeSec = beginTimeSec;
EndTimeSec = endTimeSec;
PreTriggerTimeSec = preTriggerTimeSec;
SampleRateHz = sampleRateHz;
DefaultValue = defaultValue;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem constructing " + GetType().FullName, ex);
}
}
/// <summary>
/// Get the <see cref="double"/> time value (sec) of the start of the averaging window.
/// </summary>
public double BeginTimeSec
{
get => _beginTimeSec.Value;
private set => _beginTimeSec.Value = value;
}
private readonly Property<double> _beginTimeSec
= new Property<double>(
typeof(DataWindowAverager).FullName + ".BeginTimeSec",
0.0,
false
);
/// <summary>
/// Get the <see cref="double"/> time value (sec) of the end of the averaging window.
/// </summary>
public double EndTimeSec
{
get => _endTimeSec.Value;
private set => _endTimeSec.Value = value;
}
private readonly Property<double> _endTimeSec
= new Property<double>(
typeof(DataWindowAverager).FullName + ".EndTimeSec",
0.0,
false
);
/// <summary>
/// Get the <see cref="double"/> pre-trigger time (sec).
/// </summary>
public double PreTriggerTimeSec
{
get => _preTriggerTimeSec.Value;
private set => _preTriggerTimeSec.Value = value;
}
private readonly Property<double> _preTriggerTimeSec
= new Property<double>(
typeof(DataWindowAverager).FullName + ".PreTriggerTimeSec",
0.0,
false
);
/// <summary>
/// Get the <see cref="double"/> sample rate (Hz).
/// </summary>
public double SampleRateHz
{
get => _sampleRateHz.Value;
private set => _sampleRateHz.Value = value;
}
private readonly Property<double> _sampleRateHz
= new Property<double>(
typeof(DataWindowAverager).FullName + ".SampleRateHz",
0.0,
false
);
/// <summary>
/// Get the default <see cref="short"/> ADC value to be returned if the specified window
/// is invalid.
/// </summary>
public short DefaultValue
{
get => _defaultValue.Value;
private set => _defaultValue.Value = value;
}
private readonly Property<short> _defaultValue
= new Property<short>(
typeof(DataWindowAverager).FullName + ".DefaultValue",
0,
false
);
/// <summary>
/// Compute the <see cref="short"/> average of the window represented by the current state
/// of this object over the specified window values.
/// </summary>
///
/// <param name="windowValues">
/// An array of <see cref="short"/> values to be window-averaged.
/// </param>
///
/// <returns>
/// The average of the specified value falling within this object's window.
/// </returns>
///
public short DetermineWindowAverage(short[] windowValues)
{
try
{
var numSamples = (ulong)((EndTimeSec - BeginTimeSec) * SampleRateHz) + 1;
var windowSamples = new double[numSamples];
var startingIndex = ((long)((PreTriggerTimeSec + BeginTimeSec) * SampleRateHz));
if (0 > startingIndex)
throw new WindowDoesNotExistException(
"the specified averaging window (" + BeginTimeSec + "s to " + EndTimeSec + "s) does not exist in the specified data set"
);
try
{
for (ulong i = 0; i < numSamples; i++)
windowSamples[i] = windowValues[i + (ulong)startingIndex];
return ((short)windowSamples.Average());
}
catch (IndexOutOfRangeException)
{
throw new WindowDoesNotExistException("the specified averaging window lies outside of the supplied data");
}
}
catch (System.Exception ex)
{
throw new Exception("encountered problem determining window average", ex);
}
}
/// <summary>
/// Compute the <see cref="short"/> average of the window represented by the current state
/// of this object over the specified window values.
/// </summary>
///
/// <param name="windowValues">
/// An array of <see cref="double"/> values to be window-averaged.
/// </param>
///
/// <returns>
/// The average of the specified value falling within this object's window.
/// </returns>
///
public short DetermineWindowAverage(double[] windowValues)
{
try
{
var numSamples = (ulong)((EndTimeSec - BeginTimeSec) * SampleRateHz) + 1;
var windowSamples = new double[numSamples];
var startingIndex = ((long)((PreTriggerTimeSec + BeginTimeSec) * SampleRateHz));
if (0 > startingIndex)
throw new WindowDoesNotExistException(
"the specified averaging window (" + BeginTimeSec + "s to " + EndTimeSec + "s) does not exist in the given data set"
);
try
{
for (ulong i = 0; i < numSamples; i++)
windowSamples[i] = windowValues[i + (ulong)startingIndex];
var ave = (short)windowSamples.Average();
return (ave);
}
catch (IndexOutOfRangeException)
{
throw new WindowDoesNotExistException("the specified averaging window lies outside of the supplied data");
}
}
catch (System.Exception ex)
{
throw new Exception("encountered problem determining window average", ex);
}
}
}
}