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

Issue300 fix debug spectrograms #301

Merged
merged 12 commits into from
Mar 20, 2020
15 changes: 11 additions & 4 deletions src/AnalysisBase/ResultBases/EventBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// --------------------------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="EventBase.cs" company="QutEcoacoustics">
// All code in this file and all associated files are the copyright and property of the QUT Ecoacoustics Research Group (formerly MQUTeR, and formerly QUT Bioacoustics Research Group).
// </copyright>
Expand All @@ -12,14 +12,14 @@ namespace AnalysisBase.ResultBases
using System;

/// <summary>
/// The base class for all Event style results
/// The base class for all Event style results.
/// </summary>
public abstract class EventBase : ResultBase
{
private double eventStartSeconds;

/// <summary>
/// Gets or sets the time the current audio segment is offset from the start of the file/recording.
/// Gets or sets the time (in seconds) from start of the file/recording to start of the current audio segment.
/// </summary>
/// <remarks>
/// <see cref="EventStartSeconds"/> will always be greater than or equal to <see cref="SegmentStartSeconds"/>.
Expand All @@ -36,7 +36,7 @@ public abstract class EventBase : ResultBase
/// </summary>
/// <remarks>
/// 2017-09: This field USED to be offset relative to the current segment.
/// 2017-09: This field is NOW equivalent to <see cref="ResultBase.ResultStartSeconds"/>
/// 2017-09: This field is NOW equivalent to <see cref="ResultBase.ResultStartSeconds"/>.
/// </remarks>
public virtual double EventStartSeconds
{
Expand All @@ -60,6 +60,13 @@ public virtual double EventStartSeconds
/// </summary>
public virtual double? LowFrequencyHertz { get; protected set; }

/// <summary>
/// Sets both the Segment start and the Event start.
/// <paramref name="segmentStart"/> is measured relative to the start of the recording.
/// <paramref name="eventStartSegmentRelative"/> is measured relative to the start of the segment.
/// This method sets both <see cref="SegmentStartSeconds"/> and <see cref="EventStartSeconds"/> which
/// are both measured relative to the start of the recording.
/// </summary>
protected void SetEventStartRelative(TimeSpan segmentStart, double eventStartSegmentRelative)
{
this.SegmentStartSeconds = segmentStart.TotalSeconds;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ public static void Execute(Arguments arguments)
{
Log.Warn($"Config file {configFile.FullName} not found... attempting to resolve config file");

// we use .ToString() here to get the original input string - Using fullname always produces an absolute path wrt to pwd... we don't want to prematurely make asusmptions:
// we use .ToString() here to get the original input string.
// Using fullname always produces an absolute path relative to pwd... we don't want to prematurely make assumptions:
// e.g. We require a missing absolute path to fail... that wouldn't work with .Name
// e.g. We require a relative path to try and resolve, using .FullName would fail the first absolute check inside ResolveConfigFile
configFile = ConfigFile.Resolve(configFile.ToString(), Directory.GetCurrentDirectory().ToDirectoryInfo());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public static async Task<int> ExecuteAsync(Arguments arguments)
Log.Warn($"Config file {config.FullName} not found... attempting to resolve config file");

// we use the original input string - Using FileInfo fullname always produces an
// absolute path wrt to pwd... we don't want to prematurely make assumptions:
// absolute path relative to pwd... we don't want to prematurely make assumptions:
// e.g. We require a missing absolute path to fail... that wouldn't work with .Name
// e.g. We require a relative path to try and resolve, using .FullName would fail the first absolute
// check inside ResolveConfigFile
Expand Down
10 changes: 3 additions & 7 deletions src/AnalysisPrograms/OscillationRecogniser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace AnalysisPrograms
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Acoustics.Shared.Csv;
using AudioAnalysisTools;
using AudioAnalysisTools.StandardSpectrograms;
using AudioAnalysisTools.WavTools;
Expand Down Expand Up @@ -126,15 +127,10 @@ public static void Execute(Arguments arguments)
pcHIF = 100 * hifCount / sonogram.FrameCount;
}

//write event count to results file.
double sigDuration = sonogram.Duration.TotalSeconds;
// write event count to results file.
string fname = recordingFile.BaseName();
int count = predictedEvents.Count;

//string str = String.Format("#RecordingName\tDuration(sec)\t#Ev\tCompT(ms)\t%hiFrames\n{0}\t{1}\t{2}\t{3}\t{4}\n", fname, sigDuration, count, analysisDuration.TotalMilliseconds, pcHIF);
string str = string.Format("{0}\t{1}\t{2}\t{3}\t{4}", fname, sigDuration, count, analysisDuration.TotalMilliseconds, pcHIF);
StringBuilder sb = AcousticEvent.WriteEvents(predictedEvents, str);
FileTools.WriteTextFile(opPath, sb.ToString());
Csv.WriteToCsv(opPath.ToFileInfo(), predictedEvents);

//draw images of sonograms
string imagePath = outputDir + fname + ".png";
Expand Down
29 changes: 0 additions & 29 deletions src/AnalysisPrograms/Recognizers/Base/RecognizerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -336,35 +336,6 @@ protected virtual Image DrawSonogram(
double eventThreshold)
{
var image = SpectrogramTools.GetSonogramPlusCharts(sonogram, predictedEvents, scores, hits);

//const bool doHighlightSubband = false;
//const bool add1KHzLines = true;
//var image = new Image_MultiTrack(sonogram.GetImage(doHighlightSubband, add1KHzLines, doMelScale: false));
//image.AddTrack(ImageTrack.GetTimeTrack(sonogram.Duration, sonogram.FramesPerSecond));
//image.AddTrack(ImageTrack.GetSegmentationTrack(sonogram));

//if (scores != null)
//{
// foreach (var plot in scores)
// {
// image.AddTrack(ImageTrack.GetNamedScoreTrack(plot.data, 0.0, 1.0, plot.threshold, plot.title));
// }
//}

//if (hits != null)
//{
// image.OverlayRedTransparency(hits);
//}

//if (predictedEvents != null && predictedEvents.Count > 0)
//{
// image.AddEvents(
// predictedEvents,
// sonogram.NyquistFrequency,
// sonogram.Configuration.FreqBinCount,
// sonogram.FramesPerSecond);
//}

return image;
}

Expand Down
33 changes: 3 additions & 30 deletions src/AnalysisPrograms/Recognizers/Base/WhistleParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ public static (List<AcousticEvent>, double[]) GetWhistles(
double binWidth = nyquist / (double)binCount;
int minBin = (int)Math.Round(minHz / binWidth);
int maxBin = (int)Math.Round(maxHz / binWidth);
//int binCountInBand = maxBin - minBin + 1;

// buffer zone around whistle is four bins wide.
int N = 4;

// list of accumulated acoustic events
var events = new List<AcousticEvent>();
Expand All @@ -54,7 +50,8 @@ public static (List<AcousticEvent>, double[]) GetWhistles(
// set up an intensity array for the frequency bin.
double[] intensity = new double[frameCount];

if (minBin < N)
// buffer zone around whistle is four bins wide.
if (minBin < 4)
{
// for all time frames in this frequency bin
for (int t = 0; t < frameCount; t++)
Expand Down Expand Up @@ -110,33 +107,9 @@ public static (List<AcousticEvent>, double[]) GetWhistles(
} //end for all freq bins

// combine adjacent acoustic events
events = AcousticEvent.CombineOverlappingEvents(events);
events = AcousticEvent.CombineOverlappingEvents(events, segmentStartOffset);

return (events, combinedIntensityArray);
}

/*
/// <summary>
/// Calculates the average intensity in a freq band having min and max freq,
/// AND then subtracts average intensity in the side/buffer bands, below and above.
/// THis method adds dB log values incorrectly but it is faster than doing many log conversions.
/// This method is used to find acoustic events and is accurate enough for the purpose.
/// </summary>
public static double[] CalculateFreqBandAvIntensityMinusBufferIntensity(double[,] sonogramData, int minHz, int maxHz, int nyquist)
{
var bandIntensity = SNR.CalculateFreqBandAvIntensity(sonogramData, minHz, maxHz, nyquist);
var bottomSideBandIntensity = SNR.CalculateFreqBandAvIntensity(sonogramData, minHz - bottomHzBuffer, minHz, nyquist);
var topSideBandIntensity = SNR.CalculateFreqBandAvIntensity(sonogramData, maxHz, maxHz + topHzBuffer, nyquist);

int frameCount = sonogramData.GetLength(0);
double[] netIntensity = new double[frameCount];
for (int i = 0; i < frameCount; i++)
{
netIntensity[i] = bandIntensity[i] - bottomSideBandIntensity[i] - topSideBandIntensity[i];
}

return netIntensity;
}
*/
}
}
11 changes: 1 addition & 10 deletions src/AnalysisPrograms/Recognizers/GenericRecognizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -325,18 +325,9 @@ private static Plot PreparePlot(double[] array, string title, double threshold)
/// </summary>
static void SaveDebugSpectrogram(RecognizerResults results, Config genericConfig, DirectoryInfo outputDirectory, string baseName)
{
//var image1 = results.Sonogram.GetImage(false, true, false);
//image1.Save(Path.Combine("C:\\temp\\test1.profile.png"));

//var image2 = results.Sonogram.GetImageFullyAnnotated("Test");
//image2.Save(Path.Combine("C:\\temp\\test2.profile.png"));

var image3 = SpectrogramTools.GetSonogramPlusCharts(results.Sonogram, results.Events, results.Plots, null);

//image3.Save(Path.Combine(outputDirectory.FullName, baseName + ".profile.png"));
image3.Save(Path.Combine("C:\\temp", baseName + ".profile.png"));

//sonogram.GetImageFullyAnnotated("test").Save("C:\\temp\\test.png");
image3.Save(Path.Combine(outputDirectory.FullName, baseName + ".profile.png"));
}

/// <inheritdoc cref="RecognizerConfig"/> />
Expand Down
10 changes: 1 addition & 9 deletions src/AnalysisPrograms/Recognizers/LewiniaPectoralis.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// --------------------------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="LewiniaPectoralis.cs" company="QutEcoacoustics">
// All code in this file and all associated files are the copyright and property of the QUT Ecoacoustics Research Group (formerly MQUTeR, and formerly QUT Bioacoustics Research Group).
// </copyright>
Expand Down Expand Up @@ -193,14 +193,6 @@ public override RecognizerResults Recognize(
prunedEvents.Add(ae);
}

// do a recognizer TEST.
if (false)
{
var testDir = new DirectoryInfo(outputDirectory.Parent.Parent.FullName);
TestTools.RecognizerScoresTest(recording.BaseName, testDir, recognizerConfig.AnalysisName, scoreArray);
AcousticEvent.TestToCompareEvents(recording.BaseName, testDir, recognizerConfig.AnalysisName, predictedEvents);
}

// increase very low scores
for (int j = 0; j < scoreArray.Length; j++)
{
Expand Down
10 changes: 1 addition & 9 deletions src/AnalysisPrograms/Recognizers/LitoriaBicolor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,6 @@ public override RecognizerResults Recognize(AudioRecording recording, Config con
ae.SegmentDurationSeconds = recordingDuration.TotalSeconds;
}

// do a RECOGNIZER TEST.
if (false)
{
var testDir = new DirectoryInfo(outputDirectory.Parent.Parent.FullName);
TestTools.RecognizerScoresTest(recording.BaseName, testDir, recognizerConfig.AnalysisName, scoreArray);
AcousticEvent.TestToCompareEvents(recording.BaseName, testDir, recognizerConfig.AnalysisName, predictedEvents);
}

var plot = new Plot(this.DisplayName, scoreArray, recognizerConfig.EventThreshold);
return new RecognizerResults()
{
Expand All @@ -171,7 +163,7 @@ public override RecognizerResults Recognize(AudioRecording recording, Config con
}

/// <summary>
/// ################ THE KEY ANALYSIS METHOD
/// THE KEY ANALYSIS METHOD.
/// </summary>
/// <param name="recording"></param>
/// <param name="sonoConfig"></param>
Expand Down
12 changes: 2 additions & 10 deletions src/AnalysisPrograms/Recognizers/LitoriaWatjulumensis.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,14 +157,6 @@ public override RecognizerResults Recognize(AudioRecording recording, Config con
ae.SegmentStartSeconds = segmentStartOffset.TotalSeconds;
}

// do a recognizer TEST.
if (false)
{
var testDir = new DirectoryInfo(outputDirectory.Parent.Parent.FullName);
TestTools.RecognizerScoresTest(recording.BaseName, testDir, recognizerConfig.AnalysisName, scoreArray);
AcousticEvent.TestToCompareEvents(recording.BaseName, testDir, recognizerConfig.AnalysisName, predictedEvents);
}

var plot = new Plot(this.DisplayName, scoreArray, recognizerConfig.EventThreshold);
return new RecognizerResults()
{
Expand All @@ -175,8 +167,8 @@ public override RecognizerResults Recognize(AudioRecording recording, Config con
};
}

/// <summary>
/// ################ THE KEY ANALYSIS METHOD for TRILLS
/// <summary>
/// ################ THE KEY ANALYSIS METHOD for TRILLS
///
/// See Anthony's ExempliGratia.Recognize() method in order to see how to use methods for config profiles.
/// </summary>
Expand Down
Loading