Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Work on whistle algorithm #477

Merged
merged 5 commits into from
May 24, 2021
Merged

Work on whistle algorithm #477

merged 5 commits into from
May 24, 2021

Conversation

towsey
Copy link
Contributor

@towsey towsey commented Apr 14, 2021

Issue #470 Endeavour to fix error where event was found outside search frequency band. I believe this error was caused by the rounding of the search bounds from Hertz to a frequency bin. I have endeavored to tighten up the conversion of Hertz bound to frequency bin. Also added amore components to the unit test for whistle events.
Also added two lines to write spectrogram results for visualization. This is a temporary fix - to be removed later.

Incorporate repair to whistle algorithm

Changes

Main change is the how the search bounds in Hertz are converted to bin search bounds.
Also added more components to the unit test.

Issues

It is possible that this "error" could occur again in situation where the lower search bound is very close to an actual whistle event. I did duplicate this error with the original code but have not been able to duplicate it with the revised code - so hopefully the error is fixed. If the error occurs again I believe it is due to the frequency conversion as described above and is not a serious error.

Visual Changes

Two lines were added to the unit test in order to produce a debug image. These can be deleted when the debug spectrogram gets written to locatable folder.

Fixes #470

Issue #470 Endeavour to fix error where event was found outside search frequency band. I believe this error was caused by the rounding of the search bounds from Hertz to a frequency bin. I have endeavored to tighten up the conversion of Hertz bound to frequency bin. Also added amore components to the unit test for whistle events.
Also added two lines to write spectrogram results for visualization. This is a temporary fix - to be removed later.
@codecov
Copy link

codecov bot commented Apr 14, 2021

Codecov Report

Merging #477 (42552f8) into master (16580be) will increase coverage by 37.81%.
The diff coverage is 92.50%.

Impacted file tree graph

@@             Coverage Diff             @@
##           master     #477       +/-   ##
===========================================
+ Coverage    0.71%   38.53%   +37.81%     
===========================================
  Files         481      482        +1     
  Lines       48928    67647    +18719     
  Branches     7678     7901      +223     
===========================================
+ Hits          350    26067    +25717     
+ Misses      48527    41489     -7038     
- Partials       51       91       +40     
Impacted Files Coverage Δ
src/AudioAnalysisTools/CommonParameters.cs 100.00% <ø> (+100.00%) ⬆️
.../AudioAnalysisTools/Tracks/OnebinTrackAlgorithm.cs 97.10% <91.17%> (+97.10%) ⬆️
...alysisTools/Tracks/MinAndMaxBandwidthParameters.cs 100.00% <100.00%> (+100.00%) ⬆️
.../AudioAnalysisTools/Tracks/UpwardTrackAlgorithm.cs 98.52% <100.00%> (+98.52%) ⬆️
src/Acoustics.Shared.FSharp/INumeric.fs 13.57% <0.00%> (-0.40%) ⬇️
src/AnalysisPrograms/Sandpit.cs 0.00% <0.00%> (ø)
src/AnalysisBase/AnalysisResult.cs 0.00% <0.00%> (ø)
src/TowseyLibrary/RandomVariable.cs 0.00% <0.00%> (ø)
src/TowseyLibrary/PolarCoordinates.cs 0.00% <0.00%> (ø)
src/AcousticWorkbench/AcousticEventService.cs 0.00% <0.00%> (ø)
... and 466 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 16580be...42552f8. Read the comment docs.

Issue #470 Fixed broken whistle unit test that resulted from changing the name of two variables. Fixed Australasian Pipet broken test that resulted from previous changes as noted by Truskinger.

In addition, added two new parameters, SearchbandMinHertz and SearchbandMaxHertz, because the parameters MinHertz and MaxHertz were  being used to specify two different kinds of bound, that is the min and max bounds of the search band in which to find events and as the min and max bounds of an actual event. This issue has been fixed for the Whistle and the Whip generic events but I request Truskinger to determine if he is happy with how this has been done before proceeding with other generic events where this problem also occurs.
@towsey
Copy link
Contributor Author

towsey commented Apr 20, 2021

I have fixed two broken unit tests. The whistle test was broken due to introduction of two new variables to remove an ambiguous dual use of the variables MinHertz and MaxHertz.
Request @Truskinger to check what has been done before proceeding to remove this ambiguity in other generic syllable types.

@atruskie
Copy link
Member

@towsey

I haven't reviewed this properly yet, but some notes:

  • What is the difference between [Min|Max]Hertz and Searchband[Min|Max]Hertz?
    • The documentation for these new properties is not aiding my understanding either...
    Gets or sets the bottom bound of the rectangle. Units are Hertz.
    
    vs
    Gets or sets the minimum bandwidth, units = Hertz.
    
  • The validation in CommonParameters probably should not be disabled: https://github.com/QutEcoacoustics/audio-analysis/pull/477/files#diff-090545b4a4071d03cbd9d28356981e8bb5b9a9a1a64a1160b57070f771ead268R98-R99
    Other algorithms assume these values are not null so your change would affect more than just the whistle algoirthm.
  • Do note I'll me integrating my interval library into AP soon. This will remove all min|max properties which should allow for more natural representations of parameters. e.g.
    SearchBandHertz: "[400, 2000]"
    ScoreThrehsold: ">0.6"

My understanding is the existing [Min|Max]Hertz values are treated as search limits. They're sometimes also used to set the size of resulting event afterwards (if no more pertinent information is available). Thus, your new parameters are inconsistent with the other algorithms?

If I've misunderstood, then we should set up a call?

#470 Add more detailed summary to variables SearchbandMinHertzand and SearchbandMaxHertz.
@towsey
Copy link
Contributor Author

towsey commented Apr 20, 2021

Sorry - I am having a bit of trouble getting internet connection here so I upload even when not finished. I rewritten the summaries for the two new variables and hopefully they explain what is intended. Min/MaxHertz are event parameters where as SearchbandMin/MaxHertz are algorithm parameters. I am not sure that I have placed them in the best position.

The new interval library looks good.

I commented out the two validation lines to get the new variables working. I am not sure where the most logical place is to put the new variables. They will be common to most algorithms but not all. The Blob algorithm and the Harmonics algorithm would not currently need the distinction. However I am thinking to write a new Blob2 event recognizer which would detect blob events of limited bandwidth anywhere in a wide search band. This would be a better way to do your Bell Bird recognizer.

If this does not make the issues clearer then we will have to have a call. But it is not easy here on French Island. We are leaving FI on Thursday and driving to Albury on Friday.

@atruskie
Copy link
Member

Ok the new documentation makes sense.

To summarize: the new definition for [Min|Max]Hertz set limits on event bandwidth size, while Searchband[Min|Max]Hertz set limits on where the algorithm can search.

Follow up questions:

  1. Can't post-processing do the job of the new [Min|Max]Hertz?
  2. Previously [Min|Max]Hertz operated the same as Searchband[Min|Max]Hertz, why change the name?
  3. With your current changeset you've only changed two of the algorithms' names?
  4. Even though you've provided a distinction between the two parameters ([Min|Max]Hertz and Searchband[Min|Max]Hertz) they both aren't used at the same time, suggesting the distinction is not needed?

For reference here are all the places where [Min|Max]Hertz are currently used as a bandwidth limit to the search:

All these uses were consistent. Thus, this change is a partially implemented suggestion to change all uses?

Can I suggest that no change to the names are needed currently?

Or as another suggestion, leave [Min|Max]Hertz as is, and introduce a new more specific parameter for whistle algorithm (all though again, it does not look like it is needed).

@atruskie
Copy link
Member

atruskie commented Apr 21, 2021

We're communicating offline with bad internet connections so I'm including a summary of our convsation here for prosperity:

Concerning the issue of the generic recognizer Hertz parameters, in the most general case a profile needs at least four Hertz parameters, two to set the search bounds and two to set the event bandwidth bounds. After an event is found, its actual location in frequency domain is then assigned to the MinHertz and Max Hertz parameters.

Historically with the blob recognizer, the search bounds and event bounds were conflated. However conflating these parameters is very limiting as you discovered with the Bellbird recognizer. When you explained what you were doing with the Bellbird recognizer, I immediately understood that we need a new algorithm with the four parameters as described above. I was intending to call it Blob2 unless you can think of a more sensible name.

I had already implemented something like this with the whistle recognizer, the only difference being that the event bandwidth of a whistle is by default three frequency bins wide. So no need to set this parameter. But in implmenting the whistle, I reused the Min/MaxHertz parameters even though their actual meaning was now something different.

In one of your issues I saw that you talked about ambiguity and I thought this was the problem you were referring to. Now realise it is something different. But I decided to fix up the names of the whistle and whip parameters to make them consistent with what I stated above. The click and chirp algorithms have yet to be done. I stopped because I am not sure how best to make these changes with the current class hierarchy. That is why also commented out the two verification lines - just to get things working.

I am pretty sure that the oscillations reconizer already searches a frequency band but I need to check that again.

With the harmonics recognizer, the searchband will also be the event bounds because the implementation of the DCT algorithm offers more flexible. In other words, the profile only needs the two searchband bounds because the DCT algorithm can (within limits) detect a set of harmonics anywhere in the searchband.

And with regard to your final point - can we not use the post-processing to deal with bandwidth? The short answer in my opinion is no. The profiles define the parameters required to find syllable/primitive acoustic events. THe post-processing is all about combining syllable/primitives to recognize multi-syllable calls. After the syllables have been combined we need the time/frequency filters to remove combined events that fall outside the call constraints. These are different from the syllable constraints.

I need your advice as how to incorporate these changes into the current class hierarchy or how to change the hierarchy. But for clarity, I believe we need to make all the above distinctions.

Cheers, Michael


My response:

Like I said in the issue I think the simplest thing is not change the meaning of [Min|Max]Hertz simply because it's usage is currently consistent and widespread. Let's treat [Min|Max]Hertz as search bounds - it's just the simplest way forward, even if their current meaning was not your original intended meaning.

two to set the event bandwidth bounds.

As you pointed out, most algorithms at the moment simply default to using the search range as the bounds of the event. When more pertinent information is available (e.g. whistle algorithm defaults to three bins) then more precise bounds are reported.

I think rather than changing [Min|Max]Hertz to mean event bandwidth limit we should keep the definition as search limits and for algorithms that need event bandwidth limits we should add a new parameter: MinEventBandwidthHertz and MaxEventBandwidthHertz (or with an interval, EventSizeHertz: "[100, 300]")

I agree that [Min|Max]Hertz probably is the best term to describe the event bandwidth limit, however, that ship has sailed.

one of your issues I saw that you talked about ambiguity

Can you link me to it? I can add more context then.
There's #471 but that's for harmonics. And #461 but that's just a cleanup of unused things.

I was intending to call it Blob2 unless you can think of a more sensible name.

Yes I absolutely want to make new algorithms. We should come up with a more descriptive name though. Blob2 can work as a beta/dev name until the semantics and differences are clear.

To summarize, you did:

  • Changed [Min|Max]Hertz to Searchband[Min|Max]Hertz
  • Defined the new [Min|Max]Hertz to be an event size limit
  • The problem being the usage of [Min|Max]Hertzis now inconsistent

I'm suggesting:

  • Do not change [Min|Max]Hertz
  • For algorithms that need event size limits add a new parameter named [Min|Max]EventSizeHertz

Because that change is far smaller

Issue #477
Removed two variables that set min and max search bounds. Instead added comments to existing variable MinHertz and MaxHertz that indicate these variables in fact are used to set in and max search bounds. i.e. they are not the bounds of an acoustic event except where the discovered events occupy the entire search bandwidth.
@towsey
Copy link
Contributor Author

towsey commented May 18, 2021

I have removed the names of the two search bound variables I created and in addition added comments to the existing Min/MaxHertz variables indicating that they are actually functioning as search bounds.

Comment on lines 98 to 105
yield return this.MinHertz.ValidateNotNull(nameof(this.MinHertz));
yield return this.MaxHertz.ValidateNotNull(nameof(this.MaxHertz));
//yield return this.MinHertz.ValidateNotNull(nameof(this.MinHertz));
//yield return this.MaxHertz.ValidateNotNull(nameof(this.MaxHertz));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason this validation is disabled?

Revert change or delete validation (and explain).

Comment on lines 84 to 86
if (maxSearchBin > binCount - 6)
{
maxSearchBin = binCount - 6;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this magic number 6? Is that the "sideband"? Extract to a constant?

Comment on lines 114 to 117
var bandIntensity = ((sonogramData[tf, bin - 1] * 0.5) + sonogramData[tf, bin] + (sonogramData[tf, bin + 1] * 0.5)) / 2.0;
var topSidebandIntensity = (sonogramData[tf, bin + 3] + sonogramData[tf, bin + 4] + sonogramData[tf, bin + 5]) / 3.0;
var netAmplitude = 0.0;
if (bin < 4)
if (bin < 5)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More magic numbers

Comment on lines 23 to 32
/// <summary>
/// Gets or sets a value indicating the minimum Hertz value of the search band.
/// </summary>
public int? SearchbandMinHertz { get; set; }

/// <summary>
/// Gets or sets a value indicating the maximum Hertz value of the search band.
/// </summary>
public int? SearchbandMaxHertz { get; set; }

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These do not appear to be used. They're redundant? Remove?

Comment on lines 76 to 83
int minSearchBin = (int)Math.Floor(parameters.SearchbandMinHertz.Value / binWidth);
if (minSearchBin < 1)
{
minSearchBin = 1;
}

// set top search bin allowing for the top sideband.
int maxSearchBin = (int)Math.Floor(parameters.SearchbandMaxHertz.Value / binWidth) - 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The incorrect parameters SearchbandMinHertz and SearchbandMaxHertz are still being used here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have made the corrections as requested. I have also made an extensive class summary for the OneBinTrackAlgorithm class i.e. the class used to find whistles. I hope this will be helpful in understanding the algorithm and explaining the "magic numbers". In fact all the track algorithms require that a lot of thought be given to the choice of sample rate, frame size and frame step. The typical values are not always appropriate depending on the target call.

Issue #447 I have also written an extensive class summary for OneBinTrackAlgorithm i.e. the algorithm used to find whistles.
@atruskie atruskie merged commit 9a2b560 into master May 24, 2021
@atruskie atruskie deleted the Issue470_whistleBug branch May 24, 2021 05:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

The whistle algorithm can produce events outside of the bandwidth bounds
2 participants