/// <summary> /// The values in this class were derived from See5 runs of data taken from ???? /// </summary> /// <param name="indices"></param> /// <returns></returns> public static string ConvertAcousticIndices2Classifcations(RainStruct indices) { string classification = header_negative; if (indices.spikes > 0.2) { if (indices.hiFreqCover > 0.24) { return(header_rain); } else { return(header_negative); } } else { if (indices.spectralEntropy < 0.6 && indices.bgNoise > -20) { return(header_cicada); } } return(classification); }
} //struct Indices /// <summary> /// /// </summary> /// <param name="signalEnvelope">envelope of the original signal</param> /// <param name="audioDuration"></param> /// <param name="frameStepDuration"></param> /// <param name="spectrogram">the original amplitude spectrum BUT noise reduced</param> /// <param name="lowFreqBound"></param> /// <param name="midFreqBound"></param> /// <param name="binWidth">derived from original nyquist and window/2</param> /// <returns></returns> public static Dictionary <string, double> GetIndices(double[] signalEnvelope, TimeSpan audioDuration, TimeSpan frameStepDuration, double[,] spectrogram, int lowFreqBound, int midFreqBound, double binWidth) { int chunkDuration = 10; //seconds - assume that signal is not less than one minute duration double framesPerSecond = 1 / frameStepDuration.TotalSeconds; int chunkCount = (int)Math.Round(audioDuration.TotalSeconds / chunkDuration); int framesPerChunk = (int)(chunkDuration * framesPerSecond); int nyquistBin = spectrogram.GetLength(1); string[] classifications = new string[chunkCount]; //get acoustic indices and convert to rain indices. var sb = new StringBuilder(); for (int i = 0; i < chunkCount; i++) { int startSecond = i * chunkDuration; int start = (int)(startSecond * framesPerSecond); int end = start + framesPerChunk; if (end >= signalEnvelope.Length) { end = signalEnvelope.Length - 1; } double[] chunkSignal = DataTools.Subarray(signalEnvelope, start, framesPerChunk); if (chunkSignal.Length < 50) { continue; //an arbitrary minimum length } double[,] chunkSpectro = DataTools.Submatrix(spectrogram, start, 1, end, nyquistBin - 1); RainStruct rainIndices = Get10SecondIndices(chunkSignal, chunkSpectro, lowFreqBound, midFreqBound, frameStepDuration, binWidth); string classification = ConvertAcousticIndices2Classifcations(rainIndices); classifications[i] = classification; //write indices and classification info to console string separator = ","; string line = string.Format("{1:d2}{0} {2:d2}{0} {3:f1}{0} {4:f1}{0} {5:f1}{0} {6:f2}{0} {7:f3}{0} {8:f2}{0} {9:f2}{0} {10:f2}{0} {11:f2}{0} {12:f2}{0} {13:f2}{0} {14}", separator, startSecond, startSecond + chunkDuration, rainIndices.avSig_dB, rainIndices.bgNoise, rainIndices.snr, rainIndices.activity, rainIndices.spikes, rainIndices.ACI, rainIndices.lowFreqCover, rainIndices.midFreqCover, rainIndices.hiFreqCover, rainIndices.temporalEntropy, rainIndices.spectralEntropy, classification); //if (verbose) if (false) { LoggedConsole.WriteLine(line); } //FOR PREPARING SEE.5 DATA ------- write indices and clsasification info to file //sb.AppendLine(line); } //FOR PREPARING SEE.5 DATA ------ write indices and clsasification info to file //string opDir = @"C:\SensorNetworks\Output\Rain"; //string opPath = Path.Combine(opDir, recording.BaseName + ".Rain.csv"); //FileTools.WriteTextFile(opPath, sb.ToString()); Dictionary <string, double> dict = ConvertClassifcations2Dictionary(classifications); return(dict); } //Analysis()