Skip to content

Commit

Permalink
Set up wind and rain detection methods
Browse files Browse the repository at this point in the history
Issue #252 Set up basic approach to scoring broad band events such as wind and rain.
  • Loading branch information
towsey committed Sep 9, 2019
1 parent d2511f4 commit c2ec082
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 23 deletions.
63 changes: 58 additions & 5 deletions src/AnalysisPrograms/Sandpit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,20 +120,73 @@ public override Task<int> Execute(CommandLineApplication app)

public static void ContentDescriptionDev()
{
//var dir = new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez02\Towsey.Acoustic");

DirectoryInfo[] directories =
{
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez01\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez02\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez03\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez04\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez05\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez06\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez07\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez08\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez09\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez10\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez11\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez12\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez13\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez14\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez15\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez16\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez17\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez18\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez19\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez20\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez21\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez22\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez23\Towsey.Acoustic"),
new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez24\Towsey.Acoustic"),
};

string[] baseNames = { "SM304256_0+1_20151114_001652", "SM304256_0+1_20151114_011652" };
string[] baseNames = { "SM304256_0+1_20151114_001652",
"SM304256_0+1_20151114_011652",
"SM304256_0+1_20151114_021652",
"SM304256_0+1_20151114_031652",
"SM304256_0+1_20151114_041652",
"SM304256_0+1_20151114_051652",
"SM304256_0+1_20151114_061652",
"SM304256_0+1_20151114_071652",
"SM304256_0+1_20151114_081652",
"SM304256_0+1_20151114_091652",
"SM304256_0+1_20151114_101652",
"SM304256_0+1_20151114_111652",
"SM304256_0+1_20151114_121652",
"SM304256_0+1_20151114_131652",
"SM304256_0+1_20151114_141652",
"SM304256_0+1_20151114_151652",
"SM304256_0+1_20151114_161652",
"SM304256_0+1_20151114_171652",
"SM304256_0+1_20151114_181652",
"SM304256_0+1_20151114_191652",
"SM304256_0+1_20151114_201652",
"SM304256_0+1_20151114_211652",
"SM304256_0+1_20151114_221652",
"SM304256_0+1_20151114_231652",
};

//PREPARE STRONG WIND TEMPLATE
//var path2 = Path.Combine(@"C:\Ecoacoustics\Output\ContentDescription", "StrongWindTemplate.csv");
//var dir = new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez02\Towsey.Acoustic");
//string baseName = "SM304256_0+1_20151114_011652";
//var path2 = Path.Combine(@"C:\Ecoacoustics\Output\ContentDescription", "StrongWindTemplate1.csv");
//WindContent.WriteStrongWindTemplateToFile(dictionary, path2);

//PREPARE LIGHT RAIN TEMPLATE
//var dir = new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez08\Towsey.Acoustic");
//string baseName = "SM304256_0+1_20151114_071652";
//var dictionary = ContentDescription.ReadIndexMatrices(dir, baseName);
//var path2 = Path.Combine(@"C:\Ecoacoustics\Output\ContentDescription", "LightRainTemplate1.csv");
//RainContent.WriteLightRainTemplateToFile(dictionary, path2);

var contentPlots = ContentDescription.ContentDescriptionOfMultipleRecordingFiles(directories, baseNames);

// Attach content description plots to LDFC spectrogram
Expand All @@ -146,7 +199,7 @@ public static void ContentDescriptionDev()
//};

var image = ContentDescription.DrawLdfcSpectrogramWithContentScoreTracks(ldfcSpectrogram, contentPlots);
var path1 = Path.Combine(@"C:\Ecoacoustics\Output\ContentDescription", "Testing__2Maps.CONTENT2.png");
var path1 = Path.Combine(@"C:\Ecoacoustics\Output\ContentDescription", "Testing__2Maps.CONTENT3.png");
image.Save(path1);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public static List<Plot> ContentDescriptionOfMultipleRecordingFiles(DirectoryInf
var completeListOfResults = new List<DescriptionResult>();

// cycle through the directories
// WARNING: Assume one-hour duration for each recording
for (int i = 0; i < directories.Length; i++)
{
// read the spectral indices for the current file
Expand All @@ -55,6 +56,7 @@ public static List<Plot> ContentDescriptionOfMultipleRecordingFiles(DirectoryInf

var plotDict = ContentDescription.ConvertResultsToPlots(completeListOfResults, 1440, 0);
var contentPlots = ContentDescription.ConvertPlotDictionaryToPlotList(plotDict);
contentPlots = SubtractMeanPlusSd(contentPlots);
return contentPlots;
}

Expand Down Expand Up @@ -324,6 +326,41 @@ public static Dictionary<string, Plot> ConvertResultsToPlots(List<DescriptionRes
return plots;
}

public static List<Plot> SubtractMeanPlusSd(List<Plot> plots)
{
var opPlots = new List<Plot>();

// subtract average from each plot array
foreach (Plot plot in plots)
{
var scores = plot.data;
NormalDist.AverageAndSD(scores, out double average, out double sd);

// normalise the scores to z-scores
for (int i = 0; i < scores.Length; i++)
{
// Convert scores to z-scores
scores[i] = (scores[i] - average) / sd;
if (scores[i] < 0.0)
{
scores[i] = 0.0;
}

if (scores[i] > 4.0)
{
scores[i] = 4.0;
}

// normalise full scale to 4 SDs.
scores[i] /= 4.0;
}

opPlots.Add(plot);
}

return opPlots;
}

public static List<Plot> ConvertPlotDictionaryToPlotList(Dictionary<string, Plot> dict)
{
var list = new List<Plot>();
Expand Down
82 changes: 71 additions & 11 deletions src/AudioAnalysisTools/ContentDescriptionTools/RainContent.cs
Original file line number Diff line number Diff line change
@@ -1,29 +1,89 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// <copyright file="WindContent.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>

namespace AudioAnalysisTools.ContentDescriptionTools
{
using System;
using System.Collections.Generic;
using TowseyLibrary;

public static class RainContent
{
private const int ReductionFactor = 16;

private static Dictionary<string, double[]> StrongRainTemplate = new Dictionary<string, double[]>
{
["ACI"] = new[] { 0.076, 0.046, 0.167, 0.360, 0.426, 0.443, 0.545, 0.595, 0.564, 0.612, 0.659, 0.570, 0.542, 0.520, 0.485, 0.485 },
["ENT"] = new[] { 0.065, 0.061, 0.176, 0.289, 0.249, 0.255, 0.296, 0.292, 0.262, 0.386, 0.462, 0.262, 0.222, 0.243, 0.217, 0.205 },
["EVN"] = new[] { 0.136, 0.009, 0.022, 0.051, 0.072, 0.092, 0.109, 0.150, 0.175, 0.176, 0.193, 0.155, 0.171, 0.135, 0.109, 0.133 },
["BGN"] = new[] { 0.366, 0.249, 0.181, 0.148, 0.122, 0.111, 0.106, 0.105, 0.104, 0.111, 0.111, 0.111, 0.105, 0.100, 0.090, 0.048 },
["PMN"] = new[] { 0.182, 0.076, 0.243, 0.459, 0.470, 0.501, 0.592, 0.651, 0.625, 0.699, 0.792, 0.599, 0.572, 0.550, 0.490, 0.488 },
};

public static KeyValuePair<string, double> GetStrongRainContent(Dictionary<string, double[]> oneMinuteOfIndices)
{
const string name = "StrongRain1";
var rn = new RandomNumber((int)DateTime.Now.Ticks + 27);
var score = rn.GetDouble();
return new KeyValuePair<string, double>(name, score);

var reducedIndices = ContentDescription.ReduceIndicesByFactor(oneMinuteOfIndices, ReductionFactor);
var oneMinuteVector = ContentDescription.ConvertDictionaryToVector(reducedIndices);
var templateVector = ContentDescription.ConvertDictionaryToVector(StrongRainTemplate);

//Get Euclidian distance and normalise the distance
var distance = DataTools.EuclidianDistance(templateVector, oneMinuteVector);
distance /= Math.Sqrt(templateVector.Length);

// get dummy data
//var rn = new RandomNumber(DateTime.Now.Second + (int)DateTime.Now.Ticks + 333);
//var distance = rn.GetDouble();

return new KeyValuePair<string, double>(name, 1 - distance);
}

// #######################################################################################################################

private static Dictionary<string, double[]> LightRainTemplate = new Dictionary<string, double[]>
{
["ACI"] = new[] { 0.076, 0.046, 0.167, 0.360, 0.426, 0.443, 0.545, 0.595, 0.564, 0.612, 0.659, 0.570, 0.542, 0.520, 0.485, 0.485 },
["ENT"] = new[] { 0.065, 0.061, 0.176, 0.289, 0.249, 0.255, 0.296, 0.292, 0.262, 0.386, 0.462, 0.262, 0.222, 0.243, 0.217, 0.205 },
["EVN"] = new[] { 0.136, 0.009, 0.022, 0.051, 0.072, 0.092, 0.109, 0.150, 0.175, 0.176, 0.193, 0.155, 0.171, 0.135, 0.109, 0.133 },
["BGN"] = new[] { 0.366, 0.249, 0.181, 0.148, 0.122, 0.111, 0.106, 0.105, 0.104, 0.111, 0.111, 0.111, 0.105, 0.100, 0.090, 0.048 },
["PMN"] = new[] { 0.182, 0.076, 0.243, 0.459, 0.470, 0.501, 0.592, 0.651, 0.625, 0.699, 0.792, 0.599, 0.572, 0.550, 0.490, 0.488 },
};


public static KeyValuePair<string, double> GetLightRainContent(Dictionary<string, double[]> oneMinuteOfIndices)
{
const string name = "LightRain1";
var rn = new RandomNumber(DateTime.Now.Millisecond + 9);
var score = rn.GetDouble();
return new KeyValuePair<string, double>(name, score);
var reducedIndices = ContentDescription.ReduceIndicesByFactor(oneMinuteOfIndices, ReductionFactor);
var oneMinuteVector = ContentDescription.ConvertDictionaryToVector(reducedIndices);
var templateVector = ContentDescription.ConvertDictionaryToVector(LightRainTemplate);

//Get Euclidian distance and normalise the distance
var distance = DataTools.EuclidianDistance(templateVector, oneMinuteVector);
distance /= Math.Sqrt(templateVector.Length);

// get dummy data
//var rn = new RandomNumber(DateTime.Now.Second + (int)DateTime.Now.Ticks + 333);
//var distance = rn.GetDouble();

return new KeyValuePair<string, double>(name, 1 - distance);
}

/// <summary>
/// string baseName = "SM304256_0+1_20151114_071652".
/// </summary>
public static Dictionary<string, double[]> GetLightRainTemplate(Dictionary<string, double[,]> dictionaryOfIndices)
{
var windIndices = ContentDescription.AverageIndicesOverMinutes(dictionaryOfIndices, 32, 36);
var reducedIndices = ContentDescription.ReduceIndicesByFactor(windIndices, ReductionFactor);
return reducedIndices;
}

public static void WriteLightRainTemplateToFile(Dictionary<string, double[,]> dictionaryOfIndices, string path)
{
var template = GetLightRainTemplate(dictionaryOfIndices);
FileTools.WriteDictionaryToFile(template, path);
}
}
}
13 changes: 6 additions & 7 deletions src/AudioAnalysisTools/ContentDescriptionTools/WindContent.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// <copyright file="WindContent.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>

namespace AudioAnalysisTools.ContentDescriptionTools
{
using System.IO;
using System;
using System.Collections.Generic;
using TowseyLibrary;

public static class WindContent
Expand Down Expand Up @@ -51,7 +50,7 @@ public static Dictionary<string, double[]> GetStrongWindTemplate(Dictionary<stri

public static void WriteStrongWindTemplateToFile(Dictionary<string, double[,]> dictionaryOfIndices, string path)
{
var template = WindContent.GetStrongWindTemplate(dictionaryOfIndices);
var template = GetStrongWindTemplate(dictionaryOfIndices);
FileTools.WriteDictionaryToFile(template, path);
}

Expand Down

0 comments on commit c2ec082

Please sign in to comment.