From 0c2d451bd6ec1c05ae5ac9f670bfb5003657e8be Mon Sep 17 00:00:00 2001 From: towsey Date: Fri, 19 Feb 2021 10:32:02 +1100 Subject: [PATCH] Add feedback to user about results of filtering events on syllable periodicity Issue #451 Also write a new method to convert an array of real values to a string. --- src/AudioAnalysisTools/Events/EventFilters.cs | 51 ++++++++++--------- .../Events/Types/EventPostProcessing.cs | 10 +++- src/TowseyLibrary/DataTools.cs | 11 ++++ 3 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/AudioAnalysisTools/Events/EventFilters.cs b/src/AudioAnalysisTools/Events/EventFilters.cs index 0af033b4e..f9eb14b5d 100644 --- a/src/AudioAnalysisTools/Events/EventFilters.cs +++ b/src/AudioAnalysisTools/Events/EventFilters.cs @@ -7,12 +7,16 @@ namespace AudioAnalysisTools.Events using System; using System.Collections.Generic; using System.Linq; + using System.Reflection; using AudioAnalysisTools.Events.Types; using AudioAnalysisTools.StandardSpectrograms; + using log4net; using TowseyLibrary; public static class EventFilters { + private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + //NOTES on SYNTAX: //"Select" is a transform - fails if it encounters anything that is not of type SpectralEvent. //var spectralEvents = events.Select(x => (SpectralEvent)x).ToList(); @@ -166,9 +170,9 @@ public static List FilterEventsOnSyllableCountAndPeriodicity(List(); + var actualPeriodSeconds = new List(); int previousEventStart = 0; for (int f = 1; f < temporalFootprint.Length; f++) { @@ -176,14 +180,18 @@ public static List FilterEventsOnSyllableCountAndPeriodicity(List maxSyllableCount) { + Log.Debug($" EventRejected: Actual syllable count > max: {syllableCount} > {maxSyllableCount}"); continue; } @@ -196,31 +204,24 @@ public static List FilterEventsOnSyllableCountAndPeriodicity(List 2) + { + actualAvPeriod = actualPeriodSeconds.Average(); + } + + // Require that the actual average period or interval should fall between required min and max period. + if (actualAvPeriod >= minExpectedPeriod && actualAvPeriod <= maxExpectedPeriod) { - // there were only two events, with one interval - // accept this as valid outcome, iff the interval falls within the expected interval. - var actualInterval = periodSeconds[0]; - - if (actualInterval >= minExpectedPeriod && actualInterval <= maxExpectedPeriod) - { - filteredEvents.Add(ev); - } + Log.Debug($" EventAccepted: Actual average syllable interval = {actualAvPeriod}"); + filteredEvents.Add(ev); } else { - // there were more than two events. Require overlap between actual and expected ranges. - NormalDist.AverageAndSD(periodSeconds.ToArray(), out double averagePeriod, out double sdPeriod); - - // get the difference between the expected and absolute periods. - var periodDifference = Math.Abs(averagePeriod - expectedPeriod); - - //This difference should be less than the combined SDs. - var combinedSds = (sdPeriod + expectedSd) * 2; - if (periodDifference <= combinedSds) - { - filteredEvents.Add(ev); - } + Log.Debug($" EventRejected: Actual average syllable interval = {actualAvPeriod}"); } } } diff --git a/src/AudioAnalysisTools/Events/Types/EventPostProcessing.cs b/src/AudioAnalysisTools/Events/Types/EventPostProcessing.cs index b27fed5b3..4efd16482 100644 --- a/src/AudioAnalysisTools/Events/Types/EventPostProcessing.cs +++ b/src/AudioAnalysisTools/Events/Types/EventPostProcessing.cs @@ -57,9 +57,15 @@ public static List PostProcessingOfSpectralEvents( { // filter on number of syllables and their periodicity. var maxComponentCount = sequenceConfig.SyllableMaxCount; - var period = sequenceConfig.ExpectedPeriod; + var periodAv = sequenceConfig.ExpectedPeriod; var periodSd = sequenceConfig.PeriodStandardDeviation; - newEvents = EventFilters.FilterEventsOnSyllableCountAndPeriodicity(newEvents, maxComponentCount, period, periodSd); + var minPeriod = periodAv - (3 * periodSd); + var maxPeriod = periodAv + (3 * periodSd); + Log.Debug($"FILTER SYLLABLE SEQUENCE"); + Log.Debug($" Syllables: max={maxComponentCount}"); + Log.Debug($" Period: av={periodAv}s, sd={periodSd:F3} min={minPeriod:F3}s, max={maxPeriod:F3}s"); + + newEvents = EventFilters.FilterEventsOnSyllableCountAndPeriodicity(newEvents, maxComponentCount, periodAv, periodSd); Log.Debug($"Event count after filtering on periodicity = {newEvents.Count}"); } } diff --git a/src/TowseyLibrary/DataTools.cs b/src/TowseyLibrary/DataTools.cs index ff24c2063..2d9c2a2c9 100644 --- a/src/TowseyLibrary/DataTools.cs +++ b/src/TowseyLibrary/DataTools.cs @@ -1620,6 +1620,17 @@ public static string Array2String(int[] array) return sb.ToString(); } + public static string Array2String(double[] array) + { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < array.Length; i++) + { + sb.Append(array[i].ToString("F3") + ", "); + } + + return sb.ToString(); + } + public static string Array2String(string[] array) { StringBuilder sb = new StringBuilder();