From 8b6671164ce283169493b3e572c207820469d0ab Mon Sep 17 00:00:00 2001 From: towsey Date: Fri, 12 Jun 2020 14:41:04 +1000 Subject: [PATCH] Finished debugging Australasian Bittern and tests Issue #321 --- .../Towsey.BotaurusPoiciloptilus.yml | 26 +++---- .../Birds/BotaurusPoiciloptilus.cs | 74 ++----------------- .../Recognizers/AustBitternTests.cs | 9 ++- 3 files changed, 26 insertions(+), 83 deletions(-) diff --git a/src/AnalysisConfigFiles/RecognizerConfigFiles/Towsey.BotaurusPoiciloptilus.yml b/src/AnalysisConfigFiles/RecognizerConfigFiles/Towsey.BotaurusPoiciloptilus.yml index 2f0095f01..bda07129e 100644 --- a/src/AnalysisConfigFiles/RecognizerConfigFiles/Towsey.BotaurusPoiciloptilus.yml +++ b/src/AnalysisConfigFiles/RecognizerConfigFiles/Towsey.BotaurusPoiciloptilus.yml @@ -17,7 +17,6 @@ Profiles: FrameSize: 512 FrameStep: 256 WindowFunction: HANNING - #BgNoiseThreshold: 0.0 # min and max of the freq band to search MinHertz: 100 MaxHertz: 200 @@ -29,7 +28,7 @@ Profiles: # A: First post-processing steps are to combine overlapping/proximal/sequential events # 1: Combine overlapping events -#CombineOverlappingEvents: false +CombineOverlappingEvents: false # 2: Combine each pair of Boobook syllables as one event # Can also use this to "mop up" events in neighbourhood - these can be removed later. @@ -38,25 +37,27 @@ SyllableStartDifference: 3.0 SyllableHertzGap: 35 # B: Filter the events for excess activity in their upper and lower buffer zones -LowerHertzBuffer: 150 -UpperHertzBuffer: 400 +NeighbourhoodLowerHertzBuffer: 150 +NeighbourhoodUpperHertzBuffer: 400 +NeighbourhoodDbThreshold: 6.0 # C: Options to save results files -# 4: Available options for saving data files (case-sensitive): [False/Never | True/Always | WhenEventsDetected] -SaveIntermediateWavFiles: Never -SaveIntermediateCsvFiles: false -# Available options (case-sensitive): [False/Never | True/Always | WhenEventsDetected] +# 4: Available options for saving spectrograms (case-sensitive): [False/Never | True/Always | WhenEventsDetected] # "True" is useful when debugging but "WhenEventsDetected" is required for operational use. - -# 5: Available options for saving #SaveSonogramImages: True SaveSonogramImages: WhenEventsDetected -# DisplayCsvImage is obsolete - ensure it remains set to: false + +# 5: Available options for saving data files (case-sensitive): [False/Never | True/Always | WhenEventsDetected] +SaveIntermediateWavFiles: Never +SaveIntermediateCsvFiles: false + +# 6: DisplayCsvImage is obsolete - ensure it remains set to: false DisplayCsvImage: false ## End section for AnalyzeLongRecording # Other config files to reference HighResolutionIndicesConfig: "../Towsey.Acoustic.HiResIndicesForRecognisers.yml" +... ################################################################################ # Common settings @@ -67,5 +68,4 @@ HighResolutionIndicesConfig: "../Towsey.Acoustic.HiResIndicesForRecognisers.yml" # This notation means the a profile has all of the settings that the Standard profile has, # however, the DctDuration parameter has been overridden. # <<: *STANDARD -# DctDuration: 0.3 -... \ No newline at end of file +# DctDuration: 0.3 \ No newline at end of file diff --git a/src/AnalysisPrograms/Recognizers/Birds/BotaurusPoiciloptilus.cs b/src/AnalysisPrograms/Recognizers/Birds/BotaurusPoiciloptilus.cs index 1fb4d96d3..ddcb0da5e 100644 --- a/src/AnalysisPrograms/Recognizers/Birds/BotaurusPoiciloptilus.cs +++ b/src/AnalysisPrograms/Recognizers/Birds/BotaurusPoiciloptilus.cs @@ -99,65 +99,7 @@ public override RecognizerResults Recognize( return combinedResults; } - var newEvents = combinedResults.NewEvents; - - // NOTE: If the dB threshold is set low, may get lots of little events. - if (genericConfig.CombinePossibleSyllableSequence) - { - // Convert events to spectral events for combining of possible sequences. - // Can also use this parameter to combine events that are in the upper or lower neighbourhood. - // Such combinations will increase bandwidth of the event and this property can be used later to weed out unlikely events.. - var spectralEvents = newEvents.Cast().ToList(); - var startDiff = genericConfig.SyllableStartDifference; - var hertzDiff = genericConfig.SyllableHertzGap; - newEvents = CompositeEvent.CombineProximalEvents(spectralEvents, TimeSpan.FromSeconds(startDiff), (int)hertzDiff); - BitternLog.Debug($"Event count after combining proximals = {combinedResults.NewEvents.Count}"); - } - - // Get the Bittern syllable config. - const string profileName = "BitternSyllable"; - var configuration = (BotaurusPoiciloptilusConfig)genericConfig; - var whistleConfig = (OnebinTrackParameters)configuration.Profiles[profileName]; - - // 4: Filter events on the amount of acoustic activity in their upper and lower neighbourhoods - their buffer zone. - // The idea is that an unambiguous event should have some acoustic space above and below. - // The filter requires that the average acoustic activity in each frame and bin of the upper and lower buffer zones should not exceed the user specified decibel threshold. - // The bandwidth of these two neighbourhoods is determined by the following parameters. - // ########## These parameters could be specified by user in config.yml file. - var upperHertzBuffer = 400; - var lowerHertzBuffer = 150; - - // The decibel threshold is currently set 5/6ths of the user specified threshold. - // THIS IS TO BE WATCHED. IT MAY PROVE TO BE INAPPROPRIATE TO HARD-CODE. - // Want the activity in buffer zones to be "somewhat" less than the user-defined threshold. - var neighbourhoodDbThreshold = whistleConfig.DecibelThreshold.Value * 0.8333; - - if (upperHertzBuffer > 0 || lowerHertzBuffer > 0) - { - var spectralEvents2 = combinedResults.NewEvents.Cast().ToList(); - combinedResults.NewEvents = EventExtentions.FilterEventsOnNeighbourhood( - spectralEvents2, - combinedResults.Sonogram, - lowerHertzBuffer, - upperHertzBuffer, - segmentStartOffset, - neighbourhoodDbThreshold); - - BitternLog.Debug($"Event count after filtering on neighbourhood = {combinedResults.NewEvents.Count}"); - } - - if (combinedResults.NewEvents.Count == 0) - { - BitternLog.Debug($"Return zero events."); - return combinedResults; - } - - // 5: Filter on COMPONENT COUNT in Composite events. - int maxComponentCount = 6; - combinedResults.NewEvents = EventExtentions.FilterEventsOnCompositeContent(combinedResults.NewEvents, maxComponentCount); - BitternLog.Debug($"Event count after filtering on component count = {combinedResults.NewEvents.Count}"); - - // 6: Filter the events for duration in seconds + // 1: Filter the events for duration in seconds var minimumEventDuration = 0.5; var maximumEventDuration = 2.0; if (genericConfig.CombinePossibleSyllableSequence) @@ -166,16 +108,21 @@ public override RecognizerResults Recognize( maximumEventDuration = 10.0; } - combinedResults.NewEvents = EventExtentions.FilterOnDuration(newEvents, minimumEventDuration, maximumEventDuration); + combinedResults.NewEvents = EventExtentions.FilterOnDuration(combinedResults.NewEvents, minimumEventDuration, maximumEventDuration); BitternLog.Debug($"Event count after filtering on duration = {combinedResults.NewEvents.Count}"); - // 7: Filter the events for bandwidth in Hertz + // 2: Filter the events for bandwidth in Hertz double average = 100; double sd = 15; double sigmaThreshold = 3.0; combinedResults.NewEvents = EventExtentions.FilterOnBandwidth(combinedResults.NewEvents, average, sd, sigmaThreshold); BitternLog.Debug($"Event count after filtering on bandwidth = {combinedResults.NewEvents.Count}"); + // 3: Filter on COMPONENT COUNT in Composite events. + int maxComponentCount = 6; + combinedResults.NewEvents = EventExtentions.FilterEventsOnCompositeContent(combinedResults.NewEvents, maxComponentCount); + BitternLog.Debug($"Event count after filtering on component count = {combinedResults.NewEvents.Count}"); + // Uncomment the next line when want to obtain the event frequency profiles. // WriteFrequencyProfiles(chirpEvents); @@ -211,11 +158,6 @@ public override void SummariseResults( /// /> public class BotaurusPoiciloptilusConfig : GenericRecognizerConfig, INamedProfiles { - public bool CombinePossibleSyllableSequence { get; set; } = false; - - public double SyllableStartDifference { get; set; } = 0.5; - - public double SyllableHertzGap { get; set; } = 200; } } } diff --git a/tests/Acoustics.Test/AnalysisPrograms/Recognizers/AustBitternTests.cs b/tests/Acoustics.Test/AnalysisPrograms/Recognizers/AustBitternTests.cs index 51d1da256..08587a799 100644 --- a/tests/Acoustics.Test/AnalysisPrograms/Recognizers/AustBitternTests.cs +++ b/tests/Acoustics.Test/AnalysisPrograms/Recognizers/AustBitternTests.cs @@ -66,12 +66,13 @@ public void TestRecognizer() var onlyEvent = (CompositeEvent)events[0]; - Assert.AreEqual(5.12, onlyEvent.EventStartSeconds); - Assert.AreEqual(12.256, onlyEvent.EventEndSeconds); + Assert.AreEqual(3, onlyEvent.ComponentCount); + Assert.AreEqual(7.136, onlyEvent.EventStartSeconds); + Assert.AreEqual(12.224, onlyEvent.EventEndSeconds); Assert.AreEqual(105, onlyEvent.LowFrequencyHertz); Assert.AreEqual(180, onlyEvent.HighFrequencyHertz); - Assert.AreEqual(21.72, onlyEvent.Score, 0.01); - Assert.AreEqual(0.947, onlyEvent.ScoreNormalized, 0.01); + Assert.AreEqual(24.076815193551525, onlyEvent.Score, 0.01); + Assert.AreEqual(0.476507384367336, onlyEvent.ScoreNormalized, 0.01); } } } \ No newline at end of file