Skip to content

Commit

Permalink
Renamed class and methods to reflect new nomenclature
Browse files Browse the repository at this point in the history
Issue #297 Have adopted new nomenclature for track types and incorporated the track type as a field in the Track class
  • Loading branch information
towsey committed Apr 17, 2020
1 parent f537c36 commit 1cd8412
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 75 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// <copyright file="HorizontalTrackParameters.cs" company="QutEcoacoustics">
// <copyright file="FowardTrackParameters.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 @@ -14,10 +14,11 @@ namespace AnalysisPrograms.Recognizers.Base
using TowseyLibrary;

/// <summary>
/// Parameters needed from a config file to detect spectral peak tracks.
/// Parameters needed from a config file to detect fowards spectral peak tracks.
/// A FowardTrack sounds like a fluctuating tone or technically, a chirp. Each track point advances one time step. Points may move up or down by at most two frequency bins.
/// </summary>
[YamlTypeTag(typeof(HorizontalTrackParameters))]
public class HorizontalTrackParameters : CommonParameters
[YamlTypeTag(typeof(FowardTrackParameters))]
public class FowardTrackParameters : CommonParameters
{
/// <summary>
/// Gets or sets a value indicating whether coincident tracks stacked on top of one another are to be combined.
Expand All @@ -31,14 +32,22 @@ public class HorizontalTrackParameters : CommonParameters
public int HertzGap { get; set; }

/// <summary>
/// This method returns spectral peak tracks enclosed in acoustic events.
/// This method returns foward (spectral peak) tracks enclosed in acoustic events.
/// It averages dB log values incorrectly but it is faster than doing many log conversions.
/// </summary>
/// <param name="sonogram">The spectrogram to be searched.</param>
/// <param name="minHz">Bottom of the frequency band to be searched.</param>
/// <param name="maxHz">Top of the frequency band to be searched.</param>
/// <param name="decibelThreshold">Ignore spectrogram cells below this amplitude.</param>
/// <param name="minDuration">Minimum duration of a valid event.</param>
/// <param name="maxDuration">Maximum duration of a valid event.</param>
/// <param name="combinePossibleHarmonics">Combine tracks that are likely to be harmonics/formants.</param>
/// <param name="segmentStartOffset">The start time of the current recording segment under analysis.</param>
/// <returns>A list of acoustic events containing foward tracks.</returns>
public static (List<AcousticEvent> Events, double[] CombinedIntensity) GetFowardTracks(
SpectrogramStandard sonogram,
int minHz,
int maxHz,
int nyquist,
double decibelThreshold,
double minDuration,
double maxDuration,
Expand All @@ -48,7 +57,7 @@ public static (List<AcousticEvent> Events, double[] CombinedIntensity) GetFoward
var sonogramData = sonogram.Data;
int frameCount = sonogramData.GetLength(0);
int binCount = sonogramData.GetLength(1);

int nyquist = sonogram.NyquistFrequency;
double binWidth = nyquist / (double)binCount;
int minBin = (int)Math.Round(minHz / binWidth);
int maxBin = (int)Math.Round(maxHz / binWidth);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// <copyright file="VerticalTrackParameters.cs" company="QutEcoacoustics">
// <copyright file="UpwardTrackParameters.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 @@ -15,9 +15,10 @@ namespace AnalysisPrograms.Recognizers.Base

/// <summary>
/// Parameters needed from a config file to detect vertical track components i.e. events which are completed within very few time frames, i.e. whips and near clicks.
/// An UpwardTrack sounds like a whip. Each track point ascends one frequency bin. Points may move forwards or back one frame step.
/// </summary>
[YamlTypeTag(typeof(VerticalTrackParameters))]
public class VerticalTrackParameters : CommonParameters
[YamlTypeTag(typeof(UpwardTrackParameters))]
public class UpwardTrackParameters : CommonParameters
{
/// <summary>
/// Gets or sets the minimum bandwidth, units = Hertz.
Expand Down Expand Up @@ -45,11 +46,19 @@ public class VerticalTrackParameters : CommonParameters
/// They would typically be only a few time-frames duration.
/// THis method averages dB log values incorrectly but it is faster than doing many log conversions and is accurate enough for the purpose.
/// </summary>
public static (List<AcousticEvent> Events, double[] CombinedIntensity) GetVerticalTracks(
/// <param name="sonogram">The spectrogram to be searched.</param>
/// <param name="minHz">Bottom of the frequency band to be searched.</param>
/// <param name="maxHz">Top of the frequency band to be searched.</param>
/// <param name="decibelThreshold">Ignore spectrogram cells below this amplitude.</param>
/// <param name="minBandwidthHertz">Minimum bandwidth (Hertz) of a valid event.</param>
/// <param name="maxBandwidthHertz">Maximum bandwidth (Hertz) of a valid event.</param>
/// <param name="combineProximalSimilarEvents">Combine tracks that are likely to be repeated chatter.</param>
/// <param name="segmentStartOffset">The start time of the current recording segment under analysis.</param>
/// <returns>A list of acoustic events containing foward tracks.</returns>
public static (List<AcousticEvent> Events, double[] CombinedIntensity) GetUpwardTracks(
SpectrogramStandard sonogram,
int minHz,
int maxHz,
int nyquist,
double decibelThreshold,
int minBandwidthHertz,
int maxBandwidthHertz,
Expand All @@ -60,7 +69,7 @@ public static (List<AcousticEvent> Events, double[] CombinedIntensity) GetVertic
int frameCount = sonogramData.GetLength(0);
int binCount = sonogramData.GetLength(1);
var frameStep = sonogram.FrameStep;

int nyquist = sonogram.NyquistFrequency;
double binWidth = nyquist / (double)binCount;
int minBin = (int)Math.Round(minHz / binWidth);
int maxBin = (int)Math.Round(maxHz / binWidth);
Expand All @@ -71,7 +80,8 @@ public static (List<AcousticEvent> Events, double[] CombinedIntensity) GetVertic
frameSize: sonogram.Configuration.WindowSize,
frameOverlap: sonogram.Configuration.WindowOverlap);

//Find all frame peaks and place in peaks matrix
// Find all frame peaks and place in peaks matrix
// avoid row edge effects.
var peaks = new double[frameCount, binCount];
for (int row = 1; row < frameCount - 1; row++)
{
Expand All @@ -92,7 +102,7 @@ public static (List<AcousticEvent> Events, double[] CombinedIntensity) GetVertic
}

//NOTE: the Peaks matrix is same size as the sonogram.
var tracks = TrackExtractor.GetVerticalTracks(peaks, minBin, maxBin, minBandwidthHertz, maxBandwidthHertz, decibelThreshold, converter);
var tracks = TrackExtractor.GetUpwardTracks(peaks, minBin, maxBin, minBandwidthHertz, maxBandwidthHertz, decibelThreshold, converter);

// initialise tracks as events and get the combined intensity array.
var events = new List<AcousticEvent>();
Expand Down
28 changes: 13 additions & 15 deletions src/AnalysisPrograms/Recognizers/GenericRecognizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ namespace AnalysisPrograms.Recognizers
/// </summary>
public class GenericRecognizer : RecognizerBase
{
private bool combineOverlappedEvents = false;

private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

private bool combineOverlappedEvents = false;

/// <inheritdoc />
public override string Author => "Ecosounds";

Expand All @@ -51,7 +51,6 @@ public override AnalyzerConfig ParseConfig(FileInfo file)

// validation of configs can be done here
// sanity check the algorithm
string algorithmName;
foreach (var (profileName, profile) in result.Profiles)
{
if (profile is CommonParameters c)
Expand All @@ -60,6 +59,7 @@ public override AnalyzerConfig ParseConfig(FileInfo file)
c.MaxHertz.ConfigNotNull(nameof(c.MaxHertz), file);
}

string algorithmName;
switch (profile)
{
case BlobParameters _:
Expand All @@ -74,10 +74,10 @@ public override AnalyzerConfig ParseConfig(FileInfo file)
case HarmonicParameters _:
algorithmName = "Harmonics";
break;
case HorizontalTrackParameters _:
case FowardTrackParameters _:
algorithmName = "SpectralTrack";
break;
case VerticalTrackParameters _:
case UpwardTrackParameters _:
algorithmName = "VerticalTrack";
break;
case ClickParameters _:
Expand All @@ -93,8 +93,8 @@ public override AnalyzerConfig ParseConfig(FileInfo file)
$"{nameof(OscillationParameters)}," +
$"{nameof(WhistleParameters)}," +
$"{nameof(HarmonicParameters)}," +
$"{nameof(HorizontalTrackParameters)}," +
$"{nameof(VerticalTrackParameters)}," +
$"{nameof(FowardTrackParameters)}," +
$"{nameof(UpwardTrackParameters)}," +
$"{nameof(ClickParameters)}," +
$"{nameof(Aed.AedConfiguration)}";
throw new ConfigFileException($"The algorithm type in profile {profileName} is not recognized. It must be one of {allowedAlgorithms}");
Expand Down Expand Up @@ -150,8 +150,8 @@ public override RecognizerResults Recognize(
|| profileConfig is OscillationParameters
|| profileConfig is WhistleParameters
|| profileConfig is HarmonicParameters
|| profileConfig is HorizontalTrackParameters
|| profileConfig is VerticalTrackParameters
|| profileConfig is FowardTrackParameters
|| profileConfig is UpwardTrackParameters
|| profileConfig is ClickParameters)
{
sonogram = new SpectrogramStandard(ParametersToSonogramConfig(parameters), audioRecording.WavReader);
Expand Down Expand Up @@ -244,14 +244,13 @@ public override RecognizerResults Recognize(
var plot = PreparePlot(harmonicIntensityScores, $"{profileName} (Harmonics:dct intensity)", hp.DctThreshold.Value);
plots.Add(plot);
}
else if (profileConfig is HorizontalTrackParameters tp)
else if (profileConfig is FowardTrackParameters tp)
{
double[] decibelArray;
(acousticEvents, decibelArray) = HorizontalTrackParameters.GetFowardTracks(
(acousticEvents, decibelArray) = FowardTrackParameters.GetFowardTracks(
sonogram,
tp.MinHertz.Value,
tp.MaxHertz.Value,
sonogram.NyquistFrequency,
tp.DecibelThreshold.Value,
tp.MinDuration.Value,
tp.MaxDuration.Value,
Expand All @@ -278,14 +277,13 @@ public override RecognizerResults Recognize(
var plot = PreparePlot(decibelArray, $"{profileName} (Click:dB Intensity)", cp.DecibelThreshold.Value);
plots.Add(plot);
}
else if (profileConfig is VerticalTrackParameters vtp)
else if (profileConfig is UpwardTrackParameters vtp)
{
double[] decibelArray;
(acousticEvents, decibelArray) = VerticalTrackParameters.GetVerticalTracks(
(acousticEvents, decibelArray) = UpwardTrackParameters.GetUpwardTracks(
sonogram,
vtp.MinHertz.Value,
vtp.MaxHertz.Value,
sonogram.NyquistFrequency,
vtp.DecibelThreshold.Value,
vtp.MinBandwidthHertz.Value,
vtp.MaxBandwidthHertz.Value,
Expand Down
21 changes: 13 additions & 8 deletions src/AudioAnalysisTools/Events/Tracks/Track.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ public enum TrackType
FowardTrack, // Sounds like fluctuating tone/chirp. Each track point advances one time step. Points may move up or down two frequency bins.
UpwardTrack, // Sounds like whip. Each track point ascends one frequency bin. Points may move forwards or back one frame step.
VerticalTrack, // Sounds like click. Each track point ascends one frequency bin. All points remain in the same time frame.
MixedTrack, // A track containing segments of two or more of the above. At present time, only created to accomodate test at TrackTests at Line 116.
}

public class Track : ITrack
{
private readonly UnitConverters converter;

private readonly TrackType trackType;

/// <summary>
/// Initializes a new instance of the <see cref="Track"/> class.
/// Constructor.
Expand All @@ -31,29 +34,30 @@ public class Track : ITrack
/// A reference to unit conversions this track class should use to
/// convert spectrogram data to real units.
/// </param>
public Track(UnitConverters converter)
/// <param name="aTrackType"> The type of track - see enum above. </param>
public Track(UnitConverters converter, TrackType aTrackType)
{
this.converter = converter;
this.trackType = aTrackType;
this.Points = new SortedSet<ISpectralPoint>();
}

/// <inheritdoc cref="Track.Track(UnitConverters)"/>
/// <inheritdoc cref="Track.Track(UnitConverters, TrackType)"/>
/// <param name="initialPoints">
/// A set of initial points to add into the point data collection.
/// </param>
public Track(
UnitConverters converter,
TrackType trackType,
params (int Frame, int Bin, double Amplitude)[] initialPoints)
: this(converter)
: this(converter, trackType)
{
foreach (var point in initialPoints)
{
this.SetPoint(point.Frame, point.Bin, point.Amplitude);
}
}

public TrackType trackType { get; }

public int PointCount => this.Points.Count;

public double StartTimeSeconds => this.converter.SegmentStartOffset + this.Points.Min(x => x.Seconds.Minimum);
Expand Down Expand Up @@ -126,6 +130,7 @@ public string CheckPoint(int frame, int bin)
if (frame != outFrame || bin != outBin)
{
LoggedConsole.WriteWarnLine("WARNING" + info);
//throw new Exception("WARNING" + info);
}
else
{
Expand Down Expand Up @@ -179,6 +184,7 @@ public double[] GetTrackFrequencyProfile()

/// <summary>
/// Returns the maximum amplitude in each time frame.
/// TODO
/// </summary>
public double[] GetAmplitudeOverTimeFrames()
{
Expand Down Expand Up @@ -221,11 +227,10 @@ public void Draw(IImageProcessingContext graphics, EventRenderingOptions options
((IPointData)this).DrawPointsAsPath(graphics, options);
break;
case TrackType.FowardTrack:
((IPointData)this).DrawPointsAsPath(graphics, options);
((IPointData)this).DrawPointsAsFill(graphics, options);
break;
default:
//((IPointData)this).DrawPointsAsPath(graphics, options);
((IPointData)this).DrawPointsAsFill(graphics, options);
((IPointData)this).DrawPointsAsPath(graphics, options);
break;
}
}
Expand Down
Loading

0 comments on commit 1cd8412

Please sign in to comment.