Skip to content

Commit

Permalink
Finished debugging Australasian Bittern and tests
Browse files Browse the repository at this point in the history
Issue #321
  • Loading branch information
towsey authored and atruskie committed Jun 12, 2020
1 parent daabd7e commit ea6b336
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand All @@ -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
Expand All @@ -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
...
# DctDuration: 0.3
74 changes: 8 additions & 66 deletions src/AnalysisPrograms/Recognizers/Birds/BotaurusPoiciloptilus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<SpectralEvent>().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<SpectralEvent>().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)
Expand All @@ -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);

Expand Down Expand Up @@ -211,11 +158,6 @@ public override void SummariseResults(
/// <inheritdoc cref="BotaurusPoiciloptilusConfig"/> />
public class BotaurusPoiciloptilusConfig : GenericRecognizerConfig, INamedProfiles<object>
{
public bool CombinePossibleSyllableSequence { get; set; } = false;

public double SyllableStartDifference { get; set; } = 0.5;

public double SyllableHertzGap { get; set; } = 200;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}

0 comments on commit ea6b336

Please sign in to comment.