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 vals1, out List vals2) { vals1 = new List(); vals2 = new List(); 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 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 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 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(CloseEnough)); }); } [Test] public void BasicWelch_4_TestBasicFlatTopNoOverlap4096Width() { //Arrange List gVals, sVals; ParseData("Raw.csv", out sVals, out gVals); List 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(CloseEnough)); }); } } }