Skip to content

Commit

Permalink
Fix most issues addressed by Anthony in PR response
Browse files Browse the repository at this point in the history
Issue #451 Major changes were to allow some parameter values to be nullable to avoid the use of booleans.
  • Loading branch information
towsey committed Feb 26, 2021
1 parent c75a8a8 commit 5a24efc
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 26 deletions.
8 changes: 5 additions & 3 deletions src/AnalysisPrograms/Recognizers/GenericRecognizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public override RecognizerResults Recognize(
{
var key = group.Key;
List<EventCommon> events = group.ToList<EventCommon>();
Log.Debug($"Profiles detected {events.Count} events at threshold {key} dB.");
//Log.Debug($"Profiles detected {events.Count} events at threshold {key} dB.");

var ppEvents = EventPostProcessing.PostProcessingOfSpectralEvents(
events,
Expand All @@ -159,6 +159,7 @@ public override RecognizerResults Recognize(

// Running profiles with multiple dB thresholds produces nested (Russian doll) events.
// Remove all but the outermost event.
Log.Debug($"\nFLATTEN RUSSIAN DOLL EVENTS.");
Log.Debug($"## Event count BEFORE removing enclosed events = {postEvents.Count}.");
results.NewEvents = CompositeEvent.RemoveEnclosedEvents(postEvents);
Log.Debug($"## Event count AFTER removing enclosed events = {postEvents.Count}.");
Expand Down Expand Up @@ -204,7 +205,7 @@ public static RecognizerResults RunProfiles(
{
speciesName = parameters.SpeciesName;
var decibelThresholds = parameters.DecibelThresholds;
var message = $"Number of decibel thresholds = {decibelThresholds.Length}: " + decibelThresholds.Join(", ");
var message = $"Decibel dectection thresholds: " + decibelThresholds.Join(", ");
Log.Info(message);

var spectrogram = new SpectrogramStandard(ParametersToSonogramConfig(parameters), audioRecording.WavReader);
Expand All @@ -228,7 +229,7 @@ public static RecognizerResults RunProfiles(
ae.Profile = profileName;
});

Log.Debug($"Profile {profileName}: event count = {profileResults.NewEvents.Count}");
Log.Debug($"Profile {profileName}: total event count = {profileResults.NewEvents.Count}");
combinedResults.NewEvents.AddRange(profileResults.NewEvents);
combinedResults.Plots.AddRange(profileResults.Plots);
combinedResults.Sonogram = spectrogram;
Expand All @@ -254,6 +255,7 @@ public static RecognizerResults RunProfiles(
ae.FileName = audioRecording.BaseName;
ae.Name = speciesName;
ae.Profile = profileName;
ae.DecibelDetectionThreshold = ac.IntensityThreshold;
});

// AED does not return plots.
Expand Down
67 changes: 58 additions & 9 deletions src/AudioAnalysisTools/Events/EventFilters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,11 @@ public static List<EventCommon> FilterEventsOnSyllableCountAndPeriodicity(List<E
}
}

//string strArray = DataTools.Array2String(actualPeriodSeconds.ToArray());
//Log.Debug($" Event{count} actual periods: {strArray}");
Log.Debug($" Event{count} actual periods: {actualPeriodSeconds.Join(",")}");
string strArray = DataTools.Array2String(actualPeriodSeconds.ToArray());
Log.Debug($" Event{count} actual periods: {strArray}");

// don't use following line because does not format decimal places.
//Log.Debug($" Event{count} actual periods: {actualPeriodSeconds.Join(",")}");

// reject composite events whose total syllable count exceeds the user defined max.
if (syllableCount > maxSyllableCount)
Expand Down Expand Up @@ -376,12 +378,59 @@ public static (int Count, double AveragePeriod, double SdPeriod) GetPeriodicity(
public static List<EventCommon> FilterEventsOnSidebandActivity(
List<SpectralEvent> events,
BaseSonogram spectrogram,
int lowerHertzBuffer,
int upperHertzBuffer,
int? lowerHertzBuffer,
int? upperHertzBuffer,
double? thresholdForBackgroundDecibels,
double? thresholdForMaxSidebandActivity,
TimeSpan segmentStartOffset)
{
// provide debug info about the parameter settings.
Log.Debug($"FILTER ON SIDEBAND ACTIVITY");

var logString = string.Empty;

if (lowerHertzBuffer == null)
{
logString += $" Lower sideband width not set.";
}
else
{
logString += $" Lower sideband width= {lowerHertzBuffer} Hz.";
}

if (upperHertzBuffer == null)
{
logString += $" Upper sideband width not set.";
}
else
{
logString += $" Upper sideband width= {upperHertzBuffer} Hz.";
}

Log.Debug(logString);

logString = string.Empty;

if (thresholdForBackgroundDecibels == null)
{
logString += $" Max permitted sideband background not set.";
}
else
{
logString += $" Max permitted sideband background = {thresholdForBackgroundDecibels:F0} dB.";
}

if (thresholdForMaxSidebandActivity == null)
{
logString += $" Max permitted sideband event activity not set.";
}
else
{
logString += $" Max permitted sideband event activity = {thresholdForBackgroundDecibels:F0} dB.";
}

Log.Debug(logString);

// allow bin gaps below the event.
int lowerBinGap = 2;
int upperBinGap = 2;
Expand All @@ -401,9 +450,9 @@ public static List<EventCommon> FilterEventsOnSidebandActivity(
var lowerSidebandAccepted = true;

// The lower sideband is subjected to two tests: the background test and the activity test.
if (lowerHertzBuffer > 0)
if ((lowerHertzBuffer != null) && (lowerHertzBuffer != 0))
{
var lowerSidebandMatrix = GetLowerEventSideband(ev, spectrogramData, lowerHertzBuffer, lowerBinGap, converter);
var lowerSidebandMatrix = GetLowerEventSideband(ev, spectrogramData, lowerHertzBuffer.Value, lowerBinGap, converter);
lowerSidebandAccepted = IsSidebandActivityBelowThreshold(
lowerSidebandMatrix,
"Lower",
Expand All @@ -417,9 +466,9 @@ public static List<EventCommon> FilterEventsOnSidebandActivity(
}

// The upper sideband is subjected to the same two tests: the background test and the activity test.
if (upperHertzBuffer > 0)
if ((upperHertzBuffer != null) && (lowerHertzBuffer != 0))
{
var upperSidebandMatrix = GetUpperEventSideband(ev, spectrogramData, upperHertzBuffer, upperBinGap, converter);
var upperSidebandMatrix = GetUpperEventSideband(ev, spectrogramData, upperHertzBuffer.Value, upperBinGap, converter);
upperSidebandAccepted = IsSidebandActivityBelowThreshold(
upperSidebandMatrix,
"Upper",
Expand Down
26 changes: 12 additions & 14 deletions src/AudioAnalysisTools/Events/Types/EventPostProcessing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public static List<EventCommon> PostProcessingOfSpectralEvents(
// This will be necessary where many small events have been found - possibly because the dB threshold is set low.
if (postprocessingConfig.CombineOverlappingEvents && (newEvents.Count > 0))
{
Log.Debug($"COMBINE EVENTS HAVING TEMPORAL *AND* SPECTRAL OVERLAP");
Log.Debug($"COMBINE EVENTS HAVING TEMPORAL&SPECTRAL OVERLAP");
newEvents = CompositeEvent.CombineOverlappingEvents(newEvents.Cast<EventCommon>().ToList());
Log.Debug($" Event count after combining overlapped events = {newEvents.Count}");
}
Expand All @@ -57,7 +57,7 @@ public static List<EventCommon> PostProcessingOfSpectralEvents(
// Such combinations will increase bandwidth of the event and this property can be used later to weed out unlikely events.
var sequenceConfig = postprocessingConfig.SyllableSequence;

if (sequenceConfig.NotNull() && sequenceConfig.CombinePossibleSyllableSequence && (newEvents.Count > 0))
if (sequenceConfig.NotNull() && (newEvents.Count > 0))
{
Log.Debug($"COMBINE PROXIMAL EVENTS");

Expand All @@ -79,6 +79,12 @@ public static List<EventCommon> PostProcessingOfSpectralEvents(
var maxPeriod = periodAv + (SigmaThreshold * periodSd);
Log.Debug($"FILTER ON SYLLABLE SEQUENCE");
Log.Debug($" Expected Syllable Sequence: max={maxComponentCount}, Period: av={periodAv}s, sd={periodSd:F3} min={minPeriod:F3}s, max={maxPeriod:F3}s");
if (minPeriod <= 0.0)
{
Log.Error($"Expected period={periodAv};sd={periodSd:F3} => min={minPeriod:F3}s;max={maxPeriod:F3}",
new Exception("FATAL ERROR: This combination of values is invalid => negative minimum value."));
System.Environment.Exit(1);
}

newEvents = EventFilters.FilterEventsOnSyllableCountAndPeriodicity(newEvents, maxComponentCount, periodAv, periodSd);
Log.Debug($" Event count after filtering on periodicity = {newEvents.Count}");
Expand Down Expand Up @@ -117,11 +123,8 @@ public static List<EventCommon> PostProcessingOfSpectralEvents(
var sidebandActivity = postprocessingConfig.SidebandAcousticActivity;
if ((sidebandActivity != null) && (newEvents.Count > 0))
{
if ((sidebandActivity.LowerSidebandWidth > 0) || (sidebandActivity.UpperSidebandWidth > 0))
if ((sidebandActivity.LowerSidebandWidth != null) || (sidebandActivity.UpperSidebandWidth != null))
{
Log.Debug($"FILTER ON SIDEBAND ACTIVITY");
Log.Debug($" Lower sideband width= {sidebandActivity.LowerSidebandWidth} Hz; Upper sideband width= {sidebandActivity.UpperSidebandWidth} Hz");
Log.Debug($" Max permitted sideband background = {sidebandActivity.MaxBackgroundDecibels:F0} dB and max permitted sideband activity = {sidebandActivity.MaxActivityDecibels:F0} dB");
var spectralEvents2 = newEvents.Cast<SpectralEvent>().ToList();
newEvents = EventFilters.FilterEventsOnSidebandActivity(
spectralEvents2,
Expand Down Expand Up @@ -214,13 +217,13 @@ public class SidebandConfig
/// Gets or sets a value indicating Whether or not to filter events based on acoustic conctent of upper buffer zone.
/// If value = 0, the upper sideband is ignored.
/// </summary>
public int UpperSidebandWidth { get; set; }
public int? UpperSidebandWidth { get; set; }

/// <summary>
/// Gets or sets a value indicating Whether or not to filter events based on the acoustic content of their lower buffer zone.
/// If value = 0, the lower sideband is ignored.
/// </summary>
public int LowerSidebandWidth { get; set; }
public int? LowerSidebandWidth { get; set; }

/// <summary>
/// Gets or sets a value indicating the maximum permissible value of background acoustic activity in the upper and lower sidebands of an event.
Expand All @@ -244,12 +247,7 @@ public class SidebandConfig
/// </summary>
public class SyllableSequenceConfig
{
// ################ The first three properties concern the combining of syllables into a sequence or stroph.

/// <summary>
/// Gets or sets a value indicating Whether or not to combine events that constitute a sequence of the same strophe.
/// </summary>
public bool CombinePossibleSyllableSequence { get; set; }
// ################ The first two properties concern the combining of syllables into a sequence or stroph.

/// <summary>
/// Gets or sets a value indicating the maximum allowable start time gap (seconds) between events within the same strophe.
Expand Down

0 comments on commit 5a24efc

Please sign in to comment.