From 93cb93b61a9ca05cc62caae4004905e67332419c Mon Sep 17 00:00:00 2001 From: towsey Date: Sat, 31 Aug 2019 18:06:34 +1000 Subject: [PATCH] More work on FlyingFox tests Issue #238 More work on unit tests --- .../Recognizers/PteropusSpecies.cs | 2 +- .../Recognizers/PteropusSp/PteropusSpTests.cs | 215 ++++++++++-------- 2 files changed, 116 insertions(+), 101 deletions(-) diff --git a/src/AnalysisPrograms/Recognizers/PteropusSpecies.cs b/src/AnalysisPrograms/Recognizers/PteropusSpecies.cs index 41ff7aeef..9ee1f02bc 100644 --- a/src/AnalysisPrograms/Recognizers/PteropusSpecies.cs +++ b/src/AnalysisPrograms/Recognizers/PteropusSpecies.cs @@ -459,8 +459,8 @@ internal static BaseSonogram GetSonogram(Config configuration, AudioRecording au WindowSize = 512, NoiseReductionType = NoiseReductionType.Standard, NoiseReductionParameter = configuration.GetDoubleOrNull(AnalysisKeys.NoiseBgThreshold) ?? 0.0, + WindowOverlap = 0.0, }; - sonoConfig.WindowOverlap = 0.0; // now construct the standard decibel spectrogram WITH noise removal, and look for LimConvex // get frame parameters for the analysis diff --git a/tests/Acoustics.Test/AnalysisPrograms/Recognizers/PteropusSp/PteropusSpTests.cs b/tests/Acoustics.Test/AnalysisPrograms/Recognizers/PteropusSp/PteropusSpTests.cs index d827f5ce6..913493ede 100644 --- a/tests/Acoustics.Test/AnalysisPrograms/Recognizers/PteropusSp/PteropusSpTests.cs +++ b/tests/Acoustics.Test/AnalysisPrograms/Recognizers/PteropusSp/PteropusSpTests.cs @@ -6,127 +6,142 @@ namespace Acoustics.Test.AnalysisPrograms.Recognizers.PteropusSp { using System; using System.Collections.Generic; + using System.IO; using System.Linq; - using System.Text; - using System.Threading.Tasks; using Acoustics.Shared; + using Acoustics.Shared.ConfigFile; + using Acoustics.Test.TestHelpers; using Acoustics.Tools.Wav; + using global::AnalysisPrograms.Recognizers; + using global::AudioAnalysisTools; using global::AudioAnalysisTools.DSP; using global::AudioAnalysisTools.EventStatistics; + using global::AudioAnalysisTools.StandardSpectrograms; using global::AudioAnalysisTools.WavTools; using global::TowseyLibrary; using Microsoft.VisualStudio.TestTools.UnitTesting; - using TestHelpers; [TestClass] public class PteropusSpTests { - [TestMethod] - public void TestGetWingBeatEvents() + private DirectoryInfo outputDirectory; + private AudioRecording audioRecording; + private BaseSonogram sonogram; + + [TestInitialize] + public void Setup() { - int sampleRate = 22050; - double duration = 28; - int[] harmonics1 = { 500 }; - int[] harmonics2 = { 500, 1000, 2000, 4000, 8000 }; - var signal1 = DspFilters.GenerateTestSignal(sampleRate, duration, harmonics1, WaveType.Sine); - var signal2 = DspFilters.GenerateTestSignal(sampleRate, 4, harmonics2, WaveType.Sine); - var signal3 = DspFilters.GenerateTestSignal(sampleRate, duration, harmonics1, WaveType.Sine); - - var signal = DataTools.ConcatenateVectors(signal1, signal2, signal3); - var wr = new WavReader(signal, 1, 16, sampleRate); - var recording = new AudioRecording(wr); - - // this value is fake, but we set it to ensure output values are calculated correctly w.r.t. segment start - var segmentOffset = 547.123.Seconds(); - - var start = TimeSpan.FromSeconds(28) + segmentOffset; - var end = TimeSpan.FromSeconds(32) + segmentOffset; - double lowFreq = 1500.0; - double topFreq = 8500.0; - - var statsConfig = new EventStatisticsConfiguration() + this.outputDirectory = PathHelper.GetTempDir(); + this.audioRecording = new AudioRecording(PathHelper.ResolveAsset("Recordings", "20190115_Bellingen_Feeding_minute6.wav")); + var sonoConfig = new SonogramConfig { - FrameSize = 512, - FrameStep = 512, + WindowSize = 512, + NoiseReductionType = NoiseReductionType.Standard, + NoiseReductionParameter = 0.0, + WindowOverlap = 0.0, }; + this.sonogram = (BaseSonogram)new SpectrogramStandard(sonoConfig, this.audioRecording.WavReader); + } - EventStatistics stats = - EventStatisticsCalculate.AnalyzeAudioEvent( - recording, - (start, end).AsRange(), - (lowFreq, topFreq).AsRange(), - statsConfig, - segmentOffset); - - LoggedConsole.WriteLine($"Stats: Temporal entropy = {stats.TemporalEnergyDistribution:f4}"); - LoggedConsole.WriteLine($"Stats: Spectral entropy = {stats.SpectralEnergyDistribution:f4}"); - LoggedConsole.WriteLine($"Stats: Spectral centroid= {stats.SpectralCentroid}"); - LoggedConsole.WriteLine($"Stats: DominantFrequency= {stats.DominantFrequency}"); - - Assert.AreEqual(0.0, stats.TemporalEnergyDistribution, 1E-4); - Assert.AreEqual(0.6062, stats.SpectralEnergyDistribution, 1E-4); - Assert.AreEqual(6687, stats.SpectralCentroid); - Assert.AreEqual(8003, stats.DominantFrequency); - - Assert.AreEqual(1500, stats.LowFrequencyHertz); - Assert.AreEqual(8500, stats.HighFrequencyHertz); - Assert.AreEqual(28.Seconds() + segmentOffset, stats.EventStartSeconds.Seconds()); - Assert.AreEqual(32.Seconds() + segmentOffset, stats.EventEndSeconds.Seconds()); - Assert.AreEqual(28.Seconds() + segmentOffset, stats.ResultStartSeconds.Seconds()); + [TestCleanup] + public void Cleanup() + { + PathHelper.DeleteTempDir(this.outputDirectory); } [TestMethod] - public void TestGetEventsAroundMaxima() + public void TestGetWingBeatEvents() { - int sampleRate = 22050; - double duration = 28; - int[] harmonics1 = { 500 }; - int[] harmonics2 = { 500, 1000, 2000, 4000, 8000 }; - var signal1 = DspFilters.GenerateTestSignal(sampleRate, duration, harmonics1, WaveType.Sine); - var signal2 = DspFilters.GenerateTestSignal(sampleRate, 4, harmonics2, WaveType.Sine); - var signal3 = DspFilters.GenerateTestSignal(sampleRate, duration, harmonics1, WaveType.Sine); - - var signal = DataTools.ConcatenateVectors(signal1, signal2, signal3); - var wr = new WavReader(signal, 1, 16, sampleRate); - var recording = new AudioRecording(wr); - - // this value is fake, but we set it to ensure output values are calculated correctly w.r.t. segment start - var segmentOffset = 547.123.Seconds(); - - var start = TimeSpan.FromSeconds(28) + segmentOffset; - var end = TimeSpan.FromSeconds(32) + segmentOffset; - double lowFreq = 1500.0; - double topFreq = 8500.0; - - var statsConfig = new EventStatisticsConfiguration() - { - FrameSize = 512, - FrameStep = 512, - }; - EventStatistics stats = - EventStatisticsCalculate.AnalyzeAudioEvent( - recording, - (start, end).AsRange(), - (lowFreq, topFreq).AsRange(), - statsConfig, - segmentOffset); - - LoggedConsole.WriteLine($"Stats: Temporal entropy = {stats.TemporalEnergyDistribution:f4}"); - LoggedConsole.WriteLine($"Stats: Spectral entropy = {stats.SpectralEnergyDistribution:f4}"); - LoggedConsole.WriteLine($"Stats: Spectral centroid= {stats.SpectralCentroid}"); - LoggedConsole.WriteLine($"Stats: DominantFrequency= {stats.DominantFrequency}"); - - Assert.AreEqual(0.0, stats.TemporalEnergyDistribution, 1E-4); - Assert.AreEqual(0.6062, stats.SpectralEnergyDistribution, 1E-4); - Assert.AreEqual(6687, stats.SpectralCentroid); - Assert.AreEqual(8003, stats.DominantFrequency); - - Assert.AreEqual(1500, stats.LowFrequencyHertz); - Assert.AreEqual(8500, stats.HighFrequencyHertz); - Assert.AreEqual(28.Seconds() + segmentOffset, stats.EventStartSeconds.Seconds()); - Assert.AreEqual(32.Seconds() + segmentOffset, stats.EventEndSeconds.Seconds()); - Assert.AreEqual(28.Seconds() + segmentOffset, stats.ResultStartSeconds.Seconds()); + //string speciesName = "Pteropus species"; + //string abbreviatedSpeciesName = "Pteropus"; + double minDurationSeconds = 1.0; + double maxDurationSeconds = 10.0; + double dctDuration = 1.0; + double dctThreshold = 0.5; + double minOscilFreq = 4.0; + double maxOscilFreq = 6.0; + double eventThreshold = 0.3; + int minHz = 100; + int maxHz = 3000; + TimeSpan segmentStartOffset = TimeSpan.Zero; + + // Look for wing beats using oscillation detector + Oscillations2012.Execute( + (SpectrogramStandard)this.sonogram, + minHz, + maxHz, + dctDuration, + (int)Math.Floor(minOscilFreq), + (int)Math.Floor(maxOscilFreq), + dctThreshold, + eventThreshold, + minDurationSeconds, + maxDurationSeconds, + out var scores, + out var acousticEvents, + out var hits, + segmentStartOffset); + + //LoggedConsole.WriteLine($"Stats: Temporal entropy = {stats.TemporalEnergyDistribution:f4}"); + //LoggedConsole.WriteLine($"Stats: Spectral entropy = {stats.SpectralEnergyDistribution:f4}"); + //LoggedConsole.WriteLine($"Stats: Spectral centroid= {stats.SpectralCentroid}"); + //LoggedConsole.WriteLine($"Stats: DominantFrequency= {stats.DominantFrequency}"); + + //Assert.AreEqual(0.0, stats.TemporalEnergyDistribution, 1E-4); + //Assert.AreEqual(0.6062, stats.SpectralEnergyDistribution, 1E-4); + //Assert.AreEqual(6687, stats.SpectralCentroid); + //Assert.AreEqual(8003, stats.DominantFrequency); + } + + [TestMethod] + public void TestGetEventsAroundMaxima() + { + //string abbreviatedSpeciesName = "Pteropus"; + string speciesName = "Pteropus species"; + var minTimeSpan = TimeSpan.FromSeconds(0.1); + var maxTimeSpan = TimeSpan.FromSeconds(10.0); + double decibelThreshold = 0.5; + int minHz = 100; + int maxHz = 3000; + TimeSpan segmentStartOffset = TimeSpan.Zero; + + var decibelArray = SNR.CalculateFreqBandAvIntensity(this.sonogram.Data, minHz, maxHz, this.sonogram.NyquistFrequency); + + // prepare plots + double intensityNormalisationMax = 3 * decibelThreshold; + var eventThreshold = decibelThreshold / intensityNormalisationMax; + var normalisedIntensityArray = DataTools.NormaliseInZeroOne(decibelArray, 0, intensityNormalisationMax); + var plot = new Plot(speciesName + " Territory", normalisedIntensityArray, eventThreshold); + var plots = new List { plot }; + + //iii: CONVERT decibel SCORES TO ACOUSTIC EVENTS + var acousticEvents = AcousticEvent.GetEventsAroundMaxima( + decibelArray, + segmentStartOffset, + minHz, + maxHz, + decibelThreshold, + minTimeSpan, + maxTimeSpan, + this.sonogram.FramesPerSecond, + this.sonogram.FBinWidth); + + //LoggedConsole.WriteLine($"Stats: Temporal entropy = {stats.TemporalEnergyDistribution:f4}"); + //LoggedConsole.WriteLine($"Stats: Spectral entropy = {stats.SpectralEnergyDistribution:f4}"); + //LoggedConsole.WriteLine($"Stats: Spectral centroid= {stats.SpectralCentroid}"); + //LoggedConsole.WriteLine($"Stats: DominantFrequency= {stats.DominantFrequency}"); + + //Assert.AreEqual(0.0, stats.TemporalEnergyDistribution, 1E-4); + //Assert.AreEqual(0.6062, stats.SpectralEnergyDistribution, 1E-4); + //Assert.AreEqual(6687, stats.SpectralCentroid); + //Assert.AreEqual(8003, stats.DominantFrequency); + + //Assert.AreEqual(1500, stats.LowFrequencyHertz); + //Assert.AreEqual(8500, stats.HighFrequencyHertz); + //Assert.AreEqual(28.Seconds() + segmentOffset, stats.EventStartSeconds.Seconds()); + //Assert.AreEqual(32.Seconds() + segmentOffset, stats.EventEndSeconds.Seconds()); + //Assert.AreEqual(28.Seconds() + segmentOffset, stats.ResultStartSeconds.Seconds()); } } }