Files
DP44/DataPRO/FftSharp.Test/PowerSpectralDensityShould.cs
2026-04-17 14:55:32 -04:00

134 lines
4.7 KiB
C#

using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FftSharp.Tests
{
[TestFixture]
public class PowerSpectralDensityShould
{
#region helper functions
private void ParseData(string filename, out List<double> vals1, out List<double> vals2)
{
vals1 = new List<double>();
vals2 = new List<double>();
using (var rawReader = new StreamReader(TestContext.CurrentContext.TestDirectory + "\\" + filename))
{
while (!rawReader.EndOfStream)
{
var line = rawReader.ReadLine();
var values = line.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (double.TryParse(values[0], out double val1))
{
vals1.Add(val1);
}
if (double.TryParse(values[1], out double val2))
{
vals2.Add(val2);
}
}
}
}
private static bool CloseEnough(double[] val1, double[] val2)
{
for (int i = 0; i < val1.Length; i++)
{
var exp = Math.Floor(Math.Log10(val1[i]));
var exp2 = Math.Floor(Math.Log10(val2[i]));
exp += exp < 0 ? 1 : -1;
if (exp <= -10 && exp2 <= -10) continue; // under 1e-10? we're in the noise floor, skip
var diff = Math.Abs(val1[i] - val2[i]);
var delta = Math.Pow(10, exp);
if (diff > delta)
{
return false;
}
}
return true;
}
#endregion
const int RawValueLength = 304478;
const int PSDValueLength = 2049;
[Test]
public void BasicWelch_1_RawTestDataShouldParse()
{
//Arrange
List<double> gVals, sVals;
ParseData("Raw.csv", out sVals, out gVals);
//Act
//Assert
Assert.Multiple(() =>
{
Assert.That(gVals.Count, Is.EqualTo(RawValueLength));
Assert.That(sVals.Count, Is.EqualTo(RawValueLength));
});
}
[Test]
public void BasicWelch_2_PSDResultsDataShouldParse()
{
//Arrange
List<double> hzVals, g2ovHzVals;
ParseData("PSD.csv", out hzVals, out g2ovHzVals);
//Act
//Assert
Assert.Multiple(() =>
{
Assert.That(g2ovHzVals.Count, Is.EqualTo(PSDValueLength));
Assert.That(hzVals.Count, Is.EqualTo(PSDValueLength));
});
}
[Test]
public void BasicWelch_3_FFTSharpFreqShouldMatchPSDResultFreq()
{
//Arrange
List<double> hzVals, g2ovHzVals;
ParseData("PSD.csv", out hzVals, out g2ovHzVals);
var sampleRate = 10000;
//Act
var freq = FftSharp.Transform.FFTfreq(sampleRate, g2ovHzVals.Count);
//Assert
Assert.Multiple(() =>
{
Assert.That(hzVals.Count, Is.EqualTo(PSDValueLength));
Assert.That(freq.Length, Is.EqualTo(PSDValueLength));
// see if they're close enough
Assert.That(hzVals.ToArray(), Is.EqualTo(freq).Using<double[]>(CloseEnough));
});
}
[Test]
public void BasicWelch_4_TestBasicFlatTopNoOverlap4096Width()
{
//Arrange
List<double> gVals, sVals;
ParseData("Raw.csv", out sVals, out gVals);
List<double> hzVals, g2ovHzVals;
ParseData("PSD.csv", out hzVals, out g2ovHzVals);
var sampleRate = 10000;
var averagingType = FftSharp.WindowAveragingType.Averaging;
var windowWidth = 4096;
var overlappingPct = 0;
//Act
FftSharp.WindowType type = WindowType.Rectangular;
var psd = FftSharp.Transform.PSD_Welch(gVals.ToArray(), sampleRate, type, windowWidth, overlappingPct, averagingType);
//Assert
Assert.Multiple(() =>
{
Assert.That(g2ovHzVals.Count, Is.EqualTo(PSDValueLength));
Assert.That(psd.Length, Is.EqualTo(PSDValueLength));
// see if they're close enough
Assert.That(g2ovHzVals.ToArray(), Is.EqualTo(psd).Using<double[]>(CloseEnough));
});
}
}
}