Skip to content

Commit

Permalink
WIP for zooming spectrograms
Browse files Browse the repository at this point in the history
Largely refactoring. Code is non functional at this point.

I did swap the underlying implementation for the Spectrogram matrix reading function. I covered it with unit tests to ensure compatibility.
  • Loading branch information
atruskie committed Nov 2, 2017
1 parent 93f8d96 commit 4c29188
Show file tree
Hide file tree
Showing 19 changed files with 321 additions and 286 deletions.
19 changes: 15 additions & 4 deletions Acoustics/Acoustics.Shared/AnalysisIo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,24 @@ namespace Acoustics.Shared

public class AnalysisIo
{
public AnalysisIo(IFileSystem input, IFileSystem output, IFileSystem temp)
public AnalysisIo((IFileSystem FileSystem, FileSystemEntry Base) input, (IFileSystem FileSystem, DirectoryEntry Base) output, (IFileSystem FileSystem, DirectoryEntry Base)? temp)
{
this.Input = input;
this.Output = output;
this.Temp = temp ?? input;
this.Input = input.FileSystem;
this.InputBase = input.Base;

this.Output = output.FileSystem;
this.OutputBase = output.Base;

this.Temp = (temp ?? input).FileSystem;
this.TempBase = (DirectoryEntry)(temp ?? input).Base;
}

public FileSystemEntry InputBase { get; set; }

public DirectoryEntry OutputBase { get; set; }

public DirectoryEntry TempBase { get; set; }

public IFileSystem Input { get; }

public IFileSystem Output { get; }
Expand Down
32 changes: 27 additions & 5 deletions Acoustics/Acoustics.Shared/Extensions/RandomExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
// <copyright file="RandomExtensions.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 Acoustics.Shared.Extensions
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public static class RandomExtensions
{
public static Guid NextGuid(this Random random)
Expand Down Expand Up @@ -43,7 +47,25 @@ public static long NextLong(this Random random, long min, long max)
random.NextBytes(buf);
long longRand = BitConverter.ToInt64(buf, 0);

return (Math.Abs(longRand % (max - min)) + min);
return Math.Abs(longRand % (max - min)) + min;
}

public static double[,] NextMatrix(
this Random random,
int length,
int height)
{
var array = new double[length, height];

for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
array[i, j] = random.NextDouble();
}
}

return array;
}

public static DateTimeOffset NextDate(this Random random, DateTimeOffset? minimum = null, DateTimeOffset? maximum = null)
Expand Down
51 changes: 51 additions & 0 deletions Acoustics/Acoustics.Shared/Extensions/ZioExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
// 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>

// ReSharper disable once CheckNamespace
namespace Zio
{
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
Expand All @@ -20,5 +22,54 @@ public static UPath ToUPath(this FileSystemInfo file)
{
return FileSystem.ConvertPathFromInternal(file.FullName);
}

public static DirectoryEntry ToDirectoryEntry(this DirectoryInfo directory)
{
return new DirectoryEntry(FileSystem, directory.ToUPath());
}

public static DirectoryEntry ToFileEntry(this FileInfo file)
{
return new DirectoryEntry(FileSystem, file.ToUPath());
}

/// <summary>
/// Adapter method that converts a DirectoryInfo or FileInfo to a default Zio PhysicalFileSystem and equivalent
/// UPath.
/// </summary>
public static (IFileSystem FileSystem, UPath Path) ToZio(this FileSystemInfo file)
{
return (FileSystem, FileSystem.ConvertPathFromInternal(file.FullName));
}

/// <summary>
/// Return a default physical file system that can act as a crutch while we migrate
/// </summary>
/// <param name="path">Any UPath. This parameter has no effect.</param>
/// <returns>A stati</returns>
public static PhysicalFileSystem DefaultFileSystem(this UPath path)
{
return FileSystem;
}

public static void Save(this System.Drawing.Bitmap bitmap, IFileSystem fileSystem, UPath path)
{
var extension = path.GetExtensionWithDot();

ImageFormat format;
switch (extension)
{
case ".png":
format = ImageFormat.Png;
break;
default:
throw new NotSupportedException();
}

using (var fileStream = fileSystem.CreateFile(path))
{
bitmap.Save(fileStream, format);
}
}
}
}
1 change: 1 addition & 0 deletions Acoustics/Acoustics.Test/Acoustics.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@
<Compile Include="AudioAnalysisTools\EventStatistics\EventStatisticsCalculateTests.cs" />
<Compile Include="AudioAnalysisTools\Indices\ClusterIndexTest.cs" />
<Compile Include="AudioAnalysisTools\Indices\IndexCalculateTest.cs" />
<Compile Include="AudioAnalysisTools\Indices\IndexMatricesTests.cs" />
<Compile Include="AudioAnalysisTools\LongDurationSpectrograms\LdSpectrogramConfigTests.cs" />
<Compile Include="AudioAnalysisTools\LongDurationSpectrograms\LdSpectrogramStitchingTests.cs" />
<Compile Include="AudioAnalysisTools\Oscillations2014\OscillationTests.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ public class FileSystemProviderTests : OutputDirectoryTest
[DataRow(null)]
public void TestFullFileSystem(string path)
{
var fs = FileSystemProvider.DetermineFileSystem(path);
var fs = FileSystemProvider.DetermineFileSystem(path).Item1;

Assert.IsInstanceOfType(fs, typeof(PhysicalFileSystem));
}

[TestMethod]
public void TestSubFileSystem()
{
var fs = FileSystemProvider.DetermineFileSystem(this.outputDirectory.FullName);
var fs = FileSystemProvider.DetermineFileSystem(this.outputDirectory.FullName).Item1;

Assert.IsInstanceOfType(fs, typeof(SubFileSystem));

Expand All @@ -40,7 +40,7 @@ public void TestSubFileSystem()
public void TestSqliteFileSystem()
{
var path = this.outputDirectory.FullName + "\\test.sqlite3";
var fs = FileSystemProvider.DetermineFileSystem(path);
var fs = FileSystemProvider.DetermineFileSystem(path).Item1;

Assert.IsInstanceOfType(fs, typeof(SqliteFileSystem));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// <copyright file="IndexMatricesTests.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 Acoustics.Test.AudioAnalysisTools.Indices
{
using System;
using Acoustics.Shared.Csv;
using Acoustics.Shared.Extensions;
using global::AudioAnalysisTools.Indices;
using global::TowseyLibrary;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestHelpers;

[TestClass]
public class IndexMatricesTests : OutputDirectoryTest
{
[TestMethod]
public void TestReadSpectrogram()
{
var testSpectra = PathHelper.ResolveAssetPath("20160725_203006_continuous1__Towsey.Acoustic.ACI.csv");

var matrix = IndexMatrices.ReadSpectrogram(testSpectra.ToFileInfo(), out var binCount);

Assert.AreEqual(30, matrix.GetLength(0));
Assert.AreEqual(256, matrix.GetLength(1));
Assert.AreEqual(256, binCount);

Assert.AreEqual(0.462924678189025, matrix[0, 0]);
Assert.AreEqual(0.42779069684277, matrix[0, 1]);
Assert.AreEqual(0.46412042529103, matrix[1, 0]);
Assert.AreEqual(0.444650614488611, matrix[1, 1]);
}

[TestMethod]
public void TestWriteReadSpectrogram()
{
var random = TestHelpers.Random.GetRandom();
var testSpectra = random.NextMatrix(100, 50);

var testFile = this.outputDirectory.CombineFile("test.matrix.csv");
Csv.WriteMatrixToCsv(testFile, testSpectra);

var matrix = IndexMatrices.ReadSpectrogram(testFile, out var binCount);

Assert.AreEqual(100, matrix.GetLength(0));
Assert.AreEqual(50, matrix.GetLength(1));
Assert.AreEqual(50, binCount);

var actualEnumerator = matrix.GetEnumerator();
foreach (var expected in testSpectra)
{
actualEnumerator.MoveNext();

Assert.AreEqual(expected, (double)actualEnumerator.Current, 1E-14, $"delta: {expected - (double)actualEnumerator.Current}");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace Acoustics.Test.AudioAnalysisTools.TileImage
using global::AudioAnalysisTools.TileImage;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestHelpers;
using Zio;

[TestClass]
public class AbsoluteDateTimeTilerTests
Expand Down Expand Up @@ -36,7 +37,7 @@ public void Setup()
this.outputDirectory = PathHelper.GetTempDir();

this.tiler = new Tiler(
this.outputDirectory,
this.outputDirectory.ToDirectoryEntry(),
this.tilingProfile,
new SortedSet<double>() { 60.0 },
60.0,
Expand Down Expand Up @@ -80,7 +81,7 @@ public void TestItShouldCutAndPadRightWithTransparency()
public void TestPaddingANonBlockTime()
{
this.tiler = new Tiler(
this.outputDirectory,
this.outputDirectory.ToDirectoryEntry(),
this.tilingProfileNotRoundStart,
new SortedSet<double>() { 60.0 },
60.0,
Expand Down
27 changes: 14 additions & 13 deletions Acoustics/Acoustics.Test/AudioAnalysisTools/TileImage/TilerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace Acoustics.Test.AudioAnalysisTools.TileImage
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using TestHelpers;
using Zio;

[TestClass]
public class TilerTests
Expand All @@ -32,7 +33,7 @@ public void Setup()
this.outputDirectory = PathHelper.GetTempDir();

this.tiler = new Tiler(
this.outputDirectory,
this.outputDirectory.ToDirectoryEntry(),
this.tilingProfile,
new SortedSet<double>() { 60.0, 24, 12, 6, 2, 1 },
60.0,
Expand Down Expand Up @@ -121,7 +122,7 @@ public void TestTileManyGroupsTilesByScaleAndSortsByOffset()
List<ISuperTile> moqCurrent = new List<ISuperTile>(testCases.Length),
moqNext = new List<ISuperTile>(testCases.Length);
var tilerMock = new Mock<Tiler>(
this.outputDirectory,
this.outputDirectory.ToDirectoryEntry(),
this.tilingProfile,
new SortedSet<double>() { 60.0, 24, 12, 6, 2, 1 },
60.0,
Expand All @@ -139,17 +140,17 @@ public void TestTileManyGroupsTilesByScaleAndSortsByOffset()

tilerMock.Object.TileMany(testCases);

const ISuperTile Empty = null;
const ISuperTile empty = null;
var expected = new[]
{
Tuple.Create(Empty, testCases[5]), Tuple.Create(testCases[5], Empty),
Tuple.Create(Empty, Empty), Tuple.Create(Empty, testCases[0]),
Tuple.Create(testCases[0], testCases[1]), Tuple.Create(testCases[1], Empty),
Tuple.Create(Empty, Empty), Tuple.Create(Empty, testCases[4]),
Tuple.Create(empty, testCases[5]), Tuple.Create(testCases[5], empty),
Tuple.Create(empty, empty), Tuple.Create(empty, testCases[0]),
Tuple.Create(testCases[0], testCases[1]), Tuple.Create(testCases[1], empty),
Tuple.Create(empty, empty), Tuple.Create(empty, testCases[4]),
Tuple.Create(testCases[4], testCases[3]), Tuple.Create(testCases[3], testCases[2]),
Tuple.Create(testCases[2], Empty), Tuple.Create(Empty, Empty),
Tuple.Create(Empty, testCases[6]), Tuple.Create(testCases[6], Empty),
Tuple.Create(Empty, Empty),
Tuple.Create(testCases[2], empty), Tuple.Create(empty, empty),
Tuple.Create(empty, testCases[6]), Tuple.Create(testCases[6], empty),
Tuple.Create(empty, empty),
};

Assert.AreEqual(expected.Length, moqCurrent.Count);
Expand Down Expand Up @@ -426,7 +427,7 @@ public void EnsureSameTileNotRenderedTwice_ForWeirdlyOrderedResults()

// scale size results in two images drawn
var singleScaleTiler = new Tiler(
this.outputDirectory,
this.outputDirectory.ToDirectoryEntry(),
this.tilingProfile,
new SortedSet<double>() { 0.16 },
60.0,
Expand Down Expand Up @@ -468,7 +469,7 @@ public void EnsureSameTileNotRenderedTwice_ForWeirdlyOrderedResultsReversed()

// scale size results in two images drawn
var singleScaleTiler = new Tiler(
this.outputDirectory,
this.outputDirectory.ToDirectoryEntry(),
this.tilingProfile,
new SortedSet<double>() { 0.16 },
60.0,
Expand Down Expand Up @@ -507,7 +508,7 @@ public void EnsureSameThreeTilesWrittenForTwoOddlySizedSuperTiles()
};

var singleScaleTiler = new Tiler(
this.outputDirectory,
this.outputDirectory.ToDirectoryEntry(),
this.tilingProfile,
new SortedSet<double>() { 0.16 },
60.0,
Expand Down
Loading

0 comments on commit 4c29188

Please sign in to comment.