Skip to content

Commit

Permalink
Get unit tests working for spectral events
Browse files Browse the repository at this point in the history
Issue #297 esp. drawing of composite events.
  • Loading branch information
towsey committed Apr 28, 2020
1 parent 269edd1 commit 76573b7
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public EventRenderingOptions(UnitConverters converters)
/// </summary>
public bool TargetImageIsSpectral { get; } = true;

public bool DrawBorder { get; } = true;
public bool DrawBorder { get; set; } = true;

public bool DrawFill { get; } = true;

Expand Down
11 changes: 9 additions & 2 deletions src/AudioAnalysisTools/Events/EventConverters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ public static SpectralEvent ConvertAcousticEventToSpectralEvent(this AcousticEve
var segmentOffset = TimeSpan.FromSeconds(ae.SegmentStartSeconds);
var eventStart = ae.EventStartSeconds;
var eventEnd = ae.EventEndSeconds;

return new SpectralEvent(segmentStartOffset: segmentOffset, eventStartRecordingRelative: eventStart, eventEndRecordingRelative: eventEnd, ae.LowFrequencyHertz, ae.HighFrequencyHertz)
{
EventEndSeconds = ae.EventEndSeconds,
Name = ae.Name,
//SegmentStartSeconds = ae.SegmentStartSeconds,
SegmentDurationSeconds = ae.SegmentDurationSeconds,
};
}

Expand All @@ -30,7 +32,12 @@ public static AcousticEvent ConvertSpectralEventToAcousticEvent(this SpectralEve
double duration = se.EventDurationSeconds;
double minHz = se.HighFrequencyHertz;
double maxHz = se.HighFrequencyHertz;
var ae = new AcousticEvent(segmentStartOffset, startTime, duration, minHz, maxHz);
var ae = new AcousticEvent(segmentStartOffset, startTime, duration, minHz, maxHz)
{
Name = se.Name,
SegmentDurationSeconds = se.SegmentDurationSeconds,
};

return ae;
}

Expand Down
3 changes: 2 additions & 1 deletion src/AudioAnalysisTools/Events/SpectralEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ public SpectralEvent(TimeSpan segmentStartOffset, double eventStartRecordingRela
public override void Draw(IImageProcessingContext graphics, EventRenderingOptions options)
{
// draw a border around this event
if (options.DrawBorder) {
if (options.DrawBorder)
{
var border = options.Converters.GetPixelRectangle(this);
graphics.NoAA().DrawBorderInset(options.Border, border);
}
Expand Down
8 changes: 6 additions & 2 deletions src/AudioAnalysisTools/Events/Types/CompositeEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,12 @@ public override void Draw(IImageProcessingContext graphics, EventRenderingOption
foreach (var @event in this.ComponentEvents)
{
// disable border
// options.DisableBorder = true
@event.Draw(graphics, options);
var newOptions = new EventRenderingOptions(options.Converters)
{
DrawBorder = false,
};

@event.Draw(graphics, newOptions);
}

// draw a border around all of it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,8 @@ public static Image<Rgb24> GetSonogramPlusCharts(
var height = spectrogram.Height;
var width = spectrogram.Width;
var frameSize = sonogram.Configuration.WindowSize;
var segmentDuration = sonogram.Duration;

// ############################################################### THIS NEXT LINE NEEDS TO BE FIXED TO ENABLE ANY START TIME.
var segmentStartTime = TimeSpan.Zero;
//var segmentDuration = sonogram.Duration;
var spectrogramDuration = width * sonogram.FrameStep;

// init with linear frequency scale and draw freq grid lines on image
int hertzInterval = 1000;
Expand All @@ -81,7 +79,7 @@ public static Image<Rgb24> GetSonogramPlusCharts(
{
foreach (SpectralEvent ev in events)
{
var options = new EventRenderingOptions(new UnitConverters(segmentStartTime.TotalSeconds, segmentDuration.TotalSeconds, nyquist, width, height));
var options = new EventRenderingOptions(new UnitConverters(ev.SegmentStartSeconds, spectrogramDuration, nyquist, width, height));
spectrogram.Mutate(x => ev.Draw(x, options));
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/AudioAnalysisTools/Tracks/ForwardTrackAlgorithm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ public static (List<EventCommon> Events, double[] CombinedIntensity) GetForwardT
var maxScore = decibelThreshold * 5;
var ae = new ChirpEvent(track, maxScore)
{
SegmentDurationSeconds = frameCount * converter.StepSize,
SegmentStartSeconds = segmentStartOffset.TotalSeconds,
SegmentDurationSeconds = frameCount * converter.SecondsPerFrameStep,
Name = "noName",
};

events.Add(ae);
Expand Down
4 changes: 3 additions & 1 deletion src/AudioAnalysisTools/Tracks/OnebinTrackAlgorithm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ public static (List<EventCommon> ListOfevents, double[] CombinedIntensityArray)
{
var ae = new WhistleEvent(track, maxScore)
{
SegmentDurationSeconds = frameCount * converter.StepSize,
SegmentStartSeconds = segmentStartOffset.TotalSeconds,
SegmentDurationSeconds = frameCount * converter.SecondsPerFrameStep,
Name = "noName",
};

events.Add(ae);
Expand Down
4 changes: 3 additions & 1 deletion src/AudioAnalysisTools/Tracks/OneframeTrackAlgorithm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ public static (List<EventCommon> Events, double[] Intensity) GetOneFrameTracks(
{
var ae = new ClickEvent(track, maxScore)
{
SegmentDurationSeconds = frameCount * frameStep,
SegmentStartSeconds = segmentStartOffset.TotalSeconds,
SegmentDurationSeconds = frameCount * converter.SecondsPerFrameStep,
Name = "noName",
};

events.Add(ae);
Expand Down
17 changes: 10 additions & 7 deletions src/AudioAnalysisTools/Tracks/UpwardTrackAlgorithm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ namespace AudioAnalysisTools.Tracks
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AudioAnalysisTools.Events;
using AudioAnalysisTools.Events.Tracks;
using AudioAnalysisTools.Events.Types;
using AudioAnalysisTools.StandardSpectrograms;
using TowseyLibrary;
using TrackType = AudioAnalysisTools.Events.Tracks.TrackType;
Expand Down Expand Up @@ -72,14 +74,16 @@ public static (List<EventCommon> Events, double[] CombinedIntensity) GetUpwardTr
var tracks = GetUpwardTracks(peaks, minBin, maxBin, minBandwidthHertz, maxBandwidthHertz, decibelThreshold, converter);

// initialise tracks as events and get the combined intensity array.
var events = new List<EventCommon>();
var events = new List<SpectralEvent>();
var temporalIntensityArray = new double[frameCount];
var maxScore = decibelThreshold * 5;
foreach (var track in tracks)
{
var ae = new WhipEvent(track, maxScore)
{
SegmentDurationSeconds = frameCount * frameStep,
SegmentStartSeconds = segmentStartOffset.TotalSeconds,
SegmentDurationSeconds = frameCount * converter.SecondsPerFrameStep,
Name = "noName",
};

events.Add(ae);
Expand All @@ -94,16 +98,15 @@ public static (List<EventCommon> Events, double[] CombinedIntensity) GetUpwardTr
}
}

List<EventCommon> returnEvents = events.Cast<EventCommon>().ToList();

// combine proximal events that occupy similar frequency band
if (parameters.CombineProximalSimilarEvents)
{
TimeSpan startDifference = TimeSpan.FromSeconds(0.5);
int hertzDifference = 500;
// ########################################################################################## TODO TODO TODO
//events = AcousticEvent.CombineSimilarProximalEvents(events, startDifference, hertzDifference);
returnEvents = CompositeEvent.CombineSimilarProximalEvents(events, parameters.SyllableStartDifference, parameters.SyllableHertzDifference);
}

return (events, temporalIntensityArray);
return (returnEvents, temporalIntensityArray);
}

public static List<Track> GetUpwardTracks(double[,] peaks, int minBin, int maxBin, double minBandwidthHertz, double maxBandwidthHertz, double threshold, UnitConverters converter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,8 @@ public void TestHarmonicsAlgorithm()
Assert.AreEqual(4, allResults.NewEvents.Count);

var @event = (SpectralEvent)allResults.NewEvents[0];
Assert.AreEqual("NoName", @event.Name);
Assert.AreEqual("Harmonics", @event.ComponentName);
Assert.AreEqual("Harmonics", @event.Name);
Assert.AreEqual("SpectralEvent", @event.ComponentName);
Assert.AreEqual(3.0, @event.EventStartSeconds, 0.1);
Assert.AreEqual(4.0, @event.EventEndSeconds, 0.1);
Assert.AreEqual(500, @event.LowFrequencyHertz);
Expand Down Expand Up @@ -337,7 +337,7 @@ public void TestOnebinTrackAlgorithm()
//results.Sonogram.GetImage().Save(this.outputDirectory + "\\debug.png");

var plots = new List<Plot>();
var (acousticEvents, dBArray) = OnebinTrackAlgorithm.GetOnebinTracks(
var (spectralEvents, dBArray) = OnebinTrackAlgorithm.GetOnebinTracks(
spectrogram,
parameters,
segmentStartOffset);
Expand All @@ -351,15 +351,15 @@ public void TestOnebinTrackAlgorithm()

var allResults = new RecognizerResults()
{
Events = new List<AcousticEvent>(),
NewEvents = new List<EventCommon>(),
Hits = null,
ScoreTrack = null,
Plots = new List<Plot>(),
Sonogram = null,
};

// combine the results i.e. add the events list of call events.
allResults.NewEvents.AddRange(acousticEvents);
allResults.NewEvents.AddRange(spectralEvents);
allResults.Plots.AddRange(plots);
allResults.Sonogram = spectrogram;

Expand All @@ -371,7 +371,13 @@ public void TestOnebinTrackAlgorithm()
// but three of them are too weak to be detected at this threshold.
Assert.AreEqual(13, allResults.NewEvents.Count);

var @event = (SpectralEvent)allResults.NewEvents[4];
var @event = (SpectralEvent)allResults.NewEvents[0];
Assert.AreEqual(60 + 0.0, @event.EventStartSeconds, 0.1);
Assert.AreEqual(60 + 0.35, @event.EventEndSeconds, 0.1);
Assert.AreEqual(2150, @event.LowFrequencyHertz);
Assert.AreEqual(2193, @event.HighFrequencyHertz);

@event = (SpectralEvent)allResults.NewEvents[4];
Assert.AreEqual(60 + 5.0, @event.EventStartSeconds, 0.1);
Assert.AreEqual(60 + 6.0, @event.EventEndSeconds, 0.1);
Assert.AreEqual(989, @event.LowFrequencyHertz);
Expand Down Expand Up @@ -441,7 +447,7 @@ public void TestForwardTrackAlgorithm()

var allResults = new RecognizerResults()
{
Events = new List<AcousticEvent>(),
NewEvents = new List<EventCommon>(),
Hits = null,
ScoreTrack = null,
Plots = new List<Plot>(),
Expand Down Expand Up @@ -485,9 +491,6 @@ public void TestOneframeTrackAlgorithm()
MinBandwidthHertz = 100,
MaxBandwidthHertz = 5000,
DecibelThreshold = 2.0,
//CombineProximalSimilarEvents = false,
//SyllableStartDifference = TimeSpan.FromSeconds(0.2),
//SyllableHertzDifference = 300,
};

//Set up the virtual recording.
Expand All @@ -514,7 +517,7 @@ public void TestOneframeTrackAlgorithm()

var segmentStartOffset = TimeSpan.Zero;
var plots = new List<Plot>();
var (acousticEvents, dBArray) = OneframeTrackAlgorithm.GetOneFrameTracks(
var (spectralEvents, dBArray) = OneframeTrackAlgorithm.GetOneFrameTracks(
spectrogram,
parameters,
segmentStartOffset);
Expand All @@ -526,10 +529,17 @@ public void TestOneframeTrackAlgorithm()
var plot1 = new Plot("decibel max", normalisedDecibelArray, dBThreshold);
plots.Add(plot1);

var allResults = new RecognizerResults();
var allResults = new RecognizerResults()
{
NewEvents = new List<EventCommon>(),
Hits = null,
ScoreTrack = null,
Plots = new List<Plot>(),
Sonogram = null,
};

// combine the results i.e. add the events list of call events.
allResults.NewEvents.AddRange(acousticEvents);
allResults.NewEvents.AddRange(spectralEvents);
allResults.Plots.AddRange(plots);

// effectively keeps only the *last* sonogram produced
Expand All @@ -539,17 +549,17 @@ public void TestOneframeTrackAlgorithm()
var outputDirectory = new DirectoryInfo("C:\\temp");
GenericRecognizer.SaveDebugSpectrogram(allResults, null, outputDirectory, "ClickTrack");

Assert.AreEqual(2, allResults.NewEvents.Count);
Assert.AreEqual(6, allResults.NewEvents.Count);

var @event = (SpectralEvent)allResults.NewEvents[0];
Assert.AreEqual(10.0, @event.EventStartSeconds, 0.1);
Assert.AreEqual(10.1, @event.EventEndSeconds, 0.1);
Assert.AreEqual(6450, @event.LowFrequencyHertz);
Assert.AreEqual(10750, @event.HighFrequencyHertz);

@event = (SpectralEvent)allResults.NewEvents[1];
Assert.AreEqual(11.0, @event.EventStartSeconds, 0.1);
Assert.AreEqual(11.2, @event.EventEndSeconds, 0.1);
@event = (SpectralEvent)allResults.NewEvents[2];
Assert.AreEqual(11.05, @event.EventStartSeconds, 0.05);
Assert.AreEqual(11.07, @event.EventEndSeconds, 0.05);
Assert.AreEqual(6450, @event.LowFrequencyHertz);
Assert.AreEqual(7310, @event.HighFrequencyHertz);
}
Expand All @@ -568,7 +578,7 @@ public void Test1UpwardsTrackAlgorithm()
MinBandwidthHertz = 100,
MaxBandwidthHertz = 5000,
DecibelThreshold = 2.0,
CombineProximalSimilarEvents = false,
CombineProximalSimilarEvents = true,
SyllableStartDifference = TimeSpan.FromSeconds(0.2),
SyllableHertzDifference = 300,
};
Expand Down Expand Up @@ -597,7 +607,7 @@ public void Test1UpwardsTrackAlgorithm()

var segmentStartOffset = TimeSpan.Zero;
var plots = new List<Plot>();
var (acousticEvents, dBArray) = UpwardTrackAlgorithm.GetUpwardTracks(
var (spectralEvents, dBArray) = UpwardTrackAlgorithm.GetUpwardTracks(
spectrogram,
parameters,
segmentStartOffset);
Expand All @@ -609,10 +619,17 @@ public void Test1UpwardsTrackAlgorithm()
var plot1 = new Plot("decibel max", normalisedDecibelArray, dBThreshold);
plots.Add(plot1);

var allResults = new RecognizerResults();
var allResults = new RecognizerResults()
{
NewEvents = new List<EventCommon>(),
Hits = null,
ScoreTrack = null,
Plots = new List<Plot>(),
Sonogram = null,
};

// combine the results i.e. add the events list of call events.
allResults.NewEvents.AddRange(acousticEvents);
allResults.NewEvents.AddRange(spectralEvents);
allResults.Plots.AddRange(plots);

// effectively keeps only the *last* sonogram produced
Expand Down Expand Up @@ -650,8 +667,6 @@ public void Test2UpwardsTrackAlgorithm()
MaxHertz = 6000,
MinBandwidthHertz = 200,
MaxBandwidthHertz = 5000,
//MinDuration = 0.2,
//MaxDuration = 1.1,
DecibelThreshold = 2.0,
CombineProximalSimilarEvents = false,
SyllableStartDifference = TimeSpan.FromSeconds(0.2),
Expand Down Expand Up @@ -680,7 +695,7 @@ public void Test2UpwardsTrackAlgorithm()
var plots = new List<Plot>();

// do a SECOND TEST of the vertical tracks
var (acousticEvents, dBArray) = UpwardTrackAlgorithm.GetUpwardTracks(
var (spectralEvents, dBArray) = UpwardTrackAlgorithm.GetUpwardTracks(
spectrogram,
parameters,
segmentStartOffset);
Expand All @@ -692,10 +707,17 @@ public void Test2UpwardsTrackAlgorithm()
var plot2 = new Plot("decibel max", normalisedDecibelArray, dBThreshold);
plots.Add(plot2);

var allResults2 = new RecognizerResults();
var allResults2 = new RecognizerResults()
{
NewEvents = new List<EventCommon>(),
Hits = null,
ScoreTrack = null,
Plots = new List<Plot>(),
Sonogram = null,
};

// combine the results i.e. add the events list of call events.
allResults2.NewEvents.AddRange(acousticEvents);
allResults2.NewEvents.AddRange(spectralEvents);
allResults2.Plots.AddRange(plots);
allResults2.Sonogram = spectrogram;

Expand Down

0 comments on commit 76573b7

Please sign in to comment.