public override void SummariseResults( AnalysisSettings analysisSettings, FileSegment inputFileSegment, EventBase[] events, SummaryIndexBase[] indices, SpectralIndexBase[] spectralIndices, AnalysisResult2[] results) { // below is example of how to access values in ContentDescription config file. //sampleRate = analysisSettings.Configuration.GetIntOrNull(AnalysisKeys.ResampleRate) ?? sampleRate; var cdConfiguration = (CdConfig)analysisSettings.Configuration; var ldSpectrogramConfig = cdConfiguration.LdSpectrogramConfig; //var cdConfigFile = analysisSettings.ConfigFile; //var configDirectory = cdConfigFile.DirectoryName ?? throw new ArgumentNullException(nameof(cdConfigFile), "Null value"); var sourceAudio = inputFileSegment.Source; string basename = Path.GetFileNameWithoutExtension(sourceAudio.Name); var resultsDirectory = AnalysisCoordinator.GetNamedDirectory(analysisSettings.AnalysisOutputDirectory, this); // check for null values - this was recommended by ReSharper! if (inputFileSegment.TargetFileDuration == null || inputFileSegment.TargetFileSampleRate == null) { throw new NullReferenceException(); } // output config data to disk so other analyzers can use the data, // Should contain data only - i.e. the configuration settings that generated these indices // this data can then be used by later analysis processes. var indexConfigData = new IndexGenerationData() { RecordingExtension = inputFileSegment.Source.Extension, RecordingBasename = basename, RecordingStartDate = inputFileSegment.TargetFileStartDate, RecordingDuration = inputFileSegment.TargetFileDuration.Value, SampleRateOriginal = inputFileSegment.TargetFileSampleRate.Value, SampleRateResampled = ContentSignatures.SampleRate, FrameLength = ContentSignatures.FrameSize, FrameStep = ContentSignatures.FrameSize, IndexCalculationDuration = TimeSpan.FromSeconds(ContentSignatures.IndexCalculationDurationInSeconds), BgNoiseNeighbourhood = TimeSpan.FromSeconds(5), // default value for content description AnalysisStartOffset = inputFileSegment.SegmentStartOffset ?? TimeSpan.Zero, MaximumSegmentDuration = analysisSettings.AnalysisMaxSegmentDuration, BackgroundFilterCoeff = SpectrogramConstants.BACKGROUND_FILTER_COEFF, LongDurationSpectrogramConfig = ldSpectrogramConfig, }; var icdPath = FilenameHelpers.AnalysisResultPath( resultsDirectory, basename, IndexGenerationData.FileNameFragment, "json"); Json.Serialise(icdPath.ToFileInfo(), indexConfigData); // gather spectra to form spectrograms. Assume same spectra in all analyzer results var dictionaryOfSpectra = spectralIndices.ToTwoDimensionalArray(SpectralIndexValuesForContentDescription.CachedSelectors, TwoDimensionalArray.Rotate90ClockWise); // Calculate the index distribution statistics and write to a json file. Also save as png image // The following method returns var indexDistributions =, but we have no use for them. IndexDistributions.WriteSpectralIndexDistributionStatistics(dictionaryOfSpectra, resultsDirectory, basename); // Draw ldfc spectrograms and return path to 2maps image. string ldfcSpectrogramPath = DrawSpectrogramsFromSpectralIndices( ldSpectrogramConfig, outputDirectory: resultsDirectory, indexGenerationData: indexConfigData, basename: basename, indexSpectrograms: dictionaryOfSpectra); // Gather the content description results into an array of DescriptionResult and then convert to dictionary var allContentDescriptionResults = results.Select(x => (DescriptionResult)x.MiscellaneousResults[nameof(DescriptionResult)]); var contentDictionary = DataProcessing.ConvertResultsToDictionaryOfArrays(allContentDescriptionResults.ToList()); // Write the results to a csv file var filePath = Path.Combine(resultsDirectory.FullName, "AcousticSignatures.csv"); // TODO: fix this so it writes header and a column of content description values. //Csv.WriteToCsv(new FileInfo(filePath), contentDictionary); FileTools.WriteDictionaryAsCsvFile(contentDictionary, filePath); // prepare graphical plots of the acoustic signatures. var contentPlots = GetPlots(contentDictionary); var images = GraphsAndCharts.DrawPlotDistributions(contentPlots); var plotsImage = ImageTools.CombineImagesVertically(images); plotsImage.Save(Path.Combine(resultsDirectory.FullName, "DistributionsOfContentScores.png")); // Attach content description plots to LDFC spectrogram and write to file var ldfcSpectrogram = Image.Load <Rgb24>(ldfcSpectrogramPath); var image = ContentVisualization.DrawLdfcSpectrogramWithContentScoreTracks(ldfcSpectrogram, contentPlots); var path3 = Path.Combine(resultsDirectory.FullName, basename + ".ContentDescription.png"); image.Save(path3); }