public void CompressIndexSpectrogramsBasicAverageTest() { // testing an average that occurs with three windows, each of 5 values, // with the last window being two values too long var someSpectra = new double[256, 13].ForEach((i, j) => i); var spectra = new Dictionary <string, double[, ]> { { "I_DO_NOT_EXIST", someSpectra }, }; var compressed = IndexMatrices.CompressIndexSpectrograms( spectra, 5.Seconds(), 1.Seconds(), d => Math.Round(d, MidpointRounding.AwayFromZero)); var compressedSpectra = compressed["I_DO_NOT_EXIST"]; var average = compressedSpectra.Average(); Assert.AreEqual(127.5, average, $"Expected total average to be -100 but it was {average}"); // and make sure every value is as we expect for (int j = 0; j < compressedSpectra.LastColumnIndex(); j++) { Assert.AreEqual(127.5, compressedSpectra.GetColumn(j).Average()); } }
public void CompressIndexSpectrogramsFillsAllValuesTest(double renderScale, int dataSize, string key) { var someSpectra = new double[256, dataSize].Fill(-100); var spectra = new Dictionary <string, double[, ]> { { key, someSpectra }, }; var compressed = IndexMatrices.CompressIndexSpectrograms( spectra, renderScale.Seconds(), 0.1.Seconds(), d => Math.Round(d, MidpointRounding.AwayFromZero)); // ReSharper disable once CompareOfFloatsByEqualityOperator (We are testing exact values) if (renderScale == 0.1) { // in cases where the scales are equal, the method should short circuit and // just return the same matrix. Assert.AreEqual(spectra, compressed); } var compressedSpectra = compressed[key]; var average = compressedSpectra.Average(); // this test is specifically testing whether the last column has the correct value var lastColumn = MatrixTools.GetColumn(compressedSpectra, compressedSpectra.LastColumnIndex()); var lastColumnAverage = lastColumn.Average(); Assert.AreEqual(-100, lastColumnAverage, 0.0000000001, $"Expected last column to have value -100 but it was {lastColumnAverage:R}"); Assert.AreEqual(-100, average, 0.0000000001, $"Expected total average to be -100 but it was {average:R}"); }
public void CompressIndexSpectrogramsAcceptsRoundingFuncTest() { var spectra = new Dictionary <string, double[, ]> { { "Test", new double[, ] { { 1, 2, 3, 4, 5 } } }, }; // the default rounding func (when param omitted) is floor var result = IndexMatrices.CompressIndexSpectrograms( spectra, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(30)); Assert.AreEqual(2, result.First().Value.Length); result = IndexMatrices.CompressIndexSpectrograms( spectra, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(30), Math.Ceiling); Assert.AreEqual(3, result.First().Value.Length); result = IndexMatrices.CompressIndexSpectrograms( spectra, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(30), d => Math.Round(d, MidpointRounding.AwayFromZero)); Assert.AreEqual(3, result.First().Value.Length); }
public void CompressIndexSpectrogramsTest() { var spectra = new Dictionary <string, double[, ]> { { "Test", new double[, ] { { 1, 2, 3, 4 } } }, }; Assert.ThrowsException <ArgumentException>( () => IndexMatrices.CompressIndexSpectrograms( spectra, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(80))); }
/// <summary> /// Compress high resolution indices - intended to be used when summarizing results. /// Summarize method not yet written. /// </summary> /// <param name="analysisResults"></param> /// <param name="indexResults"></param> /// <param name="highResolutionParsedConfiguration"></param> private void SummarizeHighResolutionIndices( AnalysisResult2 analysisResults, IndexCalculateResult[] indexResults, AcousticIndices.AcousticIndicesConfig highResolutionParsedConfiguration) { // NOW COMPRESS THE HI-RESOLUTION SPECTRAL INDICES TO LOW RES double lowResolution = highResolutionParsedConfiguration.GetDoubleOrNull("LowResolution") ?? 60.0; TimeSpan imageScale = TimeSpan.FromSeconds(lowResolution); TimeSpan dataScale = highResolutionParsedConfiguration.IndexCalculationDuration.Seconds(); var dictionaryOfSpectra = indexResults.Select(icr => icr.SpectralIndexValues).ToArray().ToTwoDimensionalArray(SpectralIndexValues.CachedSelectors, TwoDimensionalArray.Rotate90ClockWise); var spectralSelection = IndexMatrices.CompressIndexSpectrograms(dictionaryOfSpectra, imageScale, dataScale); // check that have not compressed matrices to zero length double[,] matrix = spectralSelection.First().Value; if (matrix.GetLength(0) == 0 || matrix.GetLength(1) == 0) { LoggedConsole.WriteErrorLine("WARNING: SPECTRAL INDEX MATRICES compressed to zero length!!!!!!!!!!!!!!!!!!!!!!!!"); } // Place LOW RESOLUTION SPECTRAL INDICES INTO analysisResults before returning. //int windowLength = (int?)highResolutionConfig[AnalysisKeys.FrameLength] ?? IndexCalculate.DefaultWindowSize; var indexProperties = highResolutionParsedConfiguration.IndexProperties; SpectralIndexValues.CheckExistenceOfSpectralIndexValues(indexProperties); // Init a new spectral indices class and populate it with spectral indices var spectrums = SpectralIndexValues.ImportFromDictionary(spectralSelection); for (int i = 0; i < spectrums.Length; i++) { spectrums[i].ResultStartSeconds = (analysisResults.SegmentStartOffset + TimeSpan.FromSeconds(i * lowResolution)).TotalSeconds; spectrums[i].SegmentDurationSeconds = imageScale.TotalSeconds; spectrums[i].FileName = ((SegmentSettings <object>)analysisResults.SegmentSettings).Segment.SourceMetadata.Identifier; } // assign to the analysis result analysisResults.SpectralIndices = spectrums; // TODO TODO TODO // ALSO NEED TO COMPRESS THE analysisResults.SummaryIndices To LOW RESOLUTION //var summaryIndexValues = new SummaryIndexValues(); //summaryIndexValues.BackgroundNoise = ETC; // ETC //var summaryiv = new SummaryIndexValues[1]; //summaryiv[0] = summaryIndexValues; //analysisResults.SummaryIndices = summaryiv; }
public void CompressIndexSpectrogramsFillsAllValuesTest(double renderScale, int dataSize) { var bgnSpectra = new double[256, dataSize].Fill(-100); var spectra = new Dictionary <string, double[, ]> { { "BGN", bgnSpectra }, }; var compressed = IndexMatrices.CompressIndexSpectrograms( spectra, renderScale.Seconds(), 0.1.Seconds(), d => Math.Round(d, MidpointRounding.AwayFromZero)); var bgn = compressed["BGN"]; var average = bgn.Average(); // this test is specifically testing whether the last column has the correct value var lastColumn = MatrixTools.GetColumn(bgn, bgn.LastColumnIndex()); Assert.AreEqual(-100, lastColumn.Average()); Assert.AreEqual(-100, average); }
public static Image DrawIndexSpectrogramCommon( LdSpectrogramConfig config, IndexGenerationData indexGenerationData, Dictionary <string, IndexProperties> indexProperties, TimeSpan startTime, TimeSpan endTime, TimeSpan dataScale, TimeSpan imageScale, int imageWidth, Dictionary <string, double[, ]> spectra, string basename) { double scalingFactor = Math.Round(imageScale.TotalMilliseconds / dataScale.TotalMilliseconds); Contract.Requires(scalingFactor >= 1.0, $"Compression scale `{scalingFactor}`is invalid"); // calculate data duration from column count of abitrary matrix //TimeSpan dataDuration = TimeSpan.FromSeconds(matrix.GetLength(1) * dataScale.TotalSeconds); int columnCount = spectra.FirstValue().GetLength(1); var startIndex = (int)(startTime.Ticks / dataScale.Ticks); var endIndex = (int)(endTime.Ticks / dataScale.Ticks); Contract.Ensures(endIndex <= columnCount); // extract subset of target data var spectralSelection = new Dictionary <string, double[, ]>(); foreach (string key in spectra.Keys) { var matrix = spectra[key]; int rowCount = matrix.GetLength(0); spectralSelection[key] = MatrixTools.Submatrix(matrix, 0, startIndex, rowCount - 1, endIndex - 1); Contract.Ensures( spectralSelection[key].GetLength(1) == (endTime - startTime).Ticks / dataScale.Ticks, "The expected number of frames should be extracted."); } // compress spectrograms to correct scale if (scalingFactor > 1) { // we add rounding to the compression so that fractional pixels get rendered spectralSelection = IndexMatrices.CompressIndexSpectrograms( spectralSelection, imageScale, dataScale, d => Math.Round(d, MidpointRounding.AwayFromZero)); } else { // this else is unnecessary - completely defensive code Contract.Ensures(scalingFactor == 1); } // check that have not compressed matrices to zero length if (spectralSelection.FirstValue().GetLength(0) == 0 || spectralSelection.FirstValue().GetLength(1) == 0) { throw new InvalidOperationException("Spectral matrices compressed to zero size"); } // DEFINE the DEFAULT colour maps for the false-colour spectrograms // Then obtain values from spectrogramDrawingConfig. NOTE: WE REQUIRE LENGTH = 11 chars. string colorMap1 = "ACI-ENT-EVN"; if (config.ColorMap1 != null && config.ColorMap1.Length == 11) { colorMap1 = config.ColorMap1; } string colorMap2 = "BGN-PMN-EVN"; if (config.ColorMap2 != null && config.ColorMap2.Length == 11) { colorMap2 = config.ColorMap2; } double backgroundFilterCoeff = indexGenerationData.BackgroundFilterCoeff; // double colourGain = (double?)configuration.ColourGain ?? SpectrogramConstants.COLOUR_GAIN; // determines colour saturation var cs1 = new LDSpectrogramRGB(config, indexGenerationData, colorMap1) { FileName = basename, BackgroundFilter = backgroundFilterCoeff, }; cs1.SetSpectralIndexProperties(indexProperties); // set the relevant dictionary of index properties cs1.LoadSpectrogramDictionary(spectralSelection); // set up piecewise linear function to determine colour weights var logResolution = Math.Log(imageScale.TotalMilliseconds, 2); double upperResolution = Math.Log(32768, 2); double lowerResolution = Math.Log(256, 2); double range = upperResolution - lowerResolution; double blendWeight1; if (logResolution >= upperResolution) { blendWeight1 = 1.0; } else if (logResolution <= lowerResolution) { blendWeight1 = 0.0; } else { blendWeight1 = (logResolution - lowerResolution) / range; } double blendWeight2 = 1 - blendWeight1; //else if (imageScaleInMsPerPixel > 2000) //{ // blendWeight1 = 0.7; // blendWeight2 = 0.3; //} //else if (imageScaleInMsPerPixel > 1000) //{ // blendWeight1 = 0.3; // blendWeight2 = 0.7; //} //else if (imageScaleInMsPerPixel > 500) //{ // // > 0.5 seconds // blendWeight1 = 0.2; // blendWeight2 = 0.8; //} //else if (imageScaleInMsPerPixel > 300) //{ // // > 0.5 seconds // blendWeight1 = 0.1; // blendWeight2 = 0.9; //} var ldfcSpectrogram = cs1.DrawBlendedFalseColourSpectrogram(colorMap1, colorMap2, blendWeight1, blendWeight2); if (ldfcSpectrogram == null) { throw new InvalidOperationException("Null Image returned from DrawBlendedFalseColourSpectrogram"); } return(ldfcSpectrogram); }