/// <summary>
        /// This method was set up as a TESTMETHOD in May 2017 but has not yet been debugged.
        /// It was transferred from Sandpit.cls. It is several years old.
        /// Updated May 2017.
        /// </summary>
        public static void TESTMETHOD_SpectralClustering(string wavFilePath, string outputDir, int frameSize)
        {
            string imageViewer = @"C:\Windows\system32\mspaint.exe";

            var recording = new AudioRecording(wavFilePath); // get recording segment

            // test clustering using amplitude spectrogram
            // double binaryThreshold = 0.07; // An amplitude threshold of 0.03 = -30 dB. A threshold of 0.05 = -26dB.
            // double[,] spectrogramData = GetAmplitudeSpectrogramNoiseReduced(recording, frameSize);

            // test clustering using decibel spectrogram
            double binaryThreshold = DefaultBinaryThresholdInDecibels; // A decibel threshold for converting to binary

            double[,] spectrogramData = GetDecibelSpectrogramNoiseReduced(recording, frameSize);

            //#######################################################################################################################################
            int    nyquistFreq  = recording.Nyquist;
            int    frameCount   = spectrogramData.GetLength(0);
            int    freqBinCount = spectrogramData.GetLength(1);
            double binWidth     = nyquistFreq / (double)freqBinCount;

            // We only use the midband of the Spectrogram, i.e. the band between lowerBinBound and upperBinBound.
            // int lowFreqBound = 1000;
            // int upperBinBound = freqBinCount - 5;
            // In June 2016, the mid-band was set to lowerBound=1000Hz, upperBound=8000hz, because this band contains most bird activity, i.e. it is the Bird-Band
            // This was done in order to make the cluster summary indices more reflective of bird call activity.
            // int lowerFreqBound = 482;
            int lowerFreqBound = 1000;
            int lowerBinBound  = (int)Math.Ceiling(lowerFreqBound / binWidth);
            int upperFreqBound = 8000;
            int upperBinBound  = (int)Math.Ceiling(upperFreqBound / binWidth);

            var midBandSpectrogram = MatrixTools.Submatrix(spectrogramData, 0, lowerBinBound, spectrogramData.GetLength(0) - 1, upperBinBound);
            var clusterInfo        = ClusterTheSpectra(midBandSpectrogram, lowerBinBound, upperBinBound, binaryThreshold);

            // transfer cluster info to spectral index results
            var clusterSpectrum1 = RestoreFullLengthSpectrum(clusterInfo.ClusterSpectrum, freqBinCount, lowerBinBound);

            Console.WriteLine("Lower BinBound=" + lowerBinBound);
            Console.WriteLine("Upper BinBound=" + upperBinBound);
            Console.WriteLine("Binary Threshold=" + binaryThreshold);
            Console.WriteLine("Cluster Count =" + clusterInfo.ClusterCount);
            Console.WriteLine("Three Gram Count=" + clusterInfo.TriGramUniqueCount);

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

            // Now repeat the entire process again. This time we want to get intermediate results to superimpose on spectrogram
            // Need to specify additional parameters. ACTIVITY THRESHOLD - require activity in at least N bins to include spectrum for training
            double           rowSumThreshold = DefaultRowSumThreshold;
            var              parameters      = new ClusteringParameters(lowerBinBound, upperBinBound, binaryThreshold, rowSumThreshold);
            TrainingDataInfo data            = GetTrainingDataForClustering(midBandSpectrogram, parameters);

            // make a normal standard decibel spectogram on which to superimpose cluster results
            var stdSpectrogram = GetStandardSpectrogram(recording, frameSize);
            var image          = DrawSonogram(stdSpectrogram, null, null, 0.0, null);

            SaveAndViewSpectrogramImage(image, outputDir, "test0Spectrogram.png", imageViewer);

            // Debug.Assert(data.TrainingDataAsSpectrogram != null, "data.TrainingDataAsSpectrogram != null");
            double[,] overlay = ConvertOverlayToSpectrogramSize(data.TrainingDataAsSpectrogram, lowerBinBound, frameCount, freqBinCount);
            image             = DrawSonogram(stdSpectrogram, null, null, 0.0, overlay);
            SaveAndViewSpectrogramImage(image, outputDir, "test1Spectrogram.png", imageViewer);

            // Return if no suitable training data for clustering
            if (data.TrainingData.Count <= 8)
            {
                Console.WriteLine("Abort clustering. Only {0} spectra available for training data. Must be at least 9.", data.TrainingData.Count);
            }
            else
            {
                // the following are pruning parameters
                double wtThreshold  = rowSumThreshold;     // used to remove wt vectors whose sum of wts <= threshold
                int    hitThreshold = DefaultHitThreshold; // used to remove wt vectors which have < N hits, i.e. cluster size < N

                clusterInfo = ClusterAnalysis(data.TrainingData, wtThreshold, hitThreshold, data.SelectedFrames);
                Console.WriteLine("Binary Threshold=" + binaryThreshold);
                Console.WriteLine("Weight Threshold=" + wtThreshold);
                Console.WriteLine("Hit Threshold=" + hitThreshold);
                Console.WriteLine("Cluster Count=" + clusterInfo.ClusterCount);
                Console.WriteLine("Three Gram Count=" + clusterInfo.TriGramUniqueCount);

                image = DrawClusterSpectrogram(stdSpectrogram, clusterInfo, data, lowerBinBound);
                SaveAndViewSpectrogramImage(image, outputDir, "test2Spectrogram.png", imageViewer);

                // transfer cluster info to spectral index results
                var clusterSpectrum2 = RestoreFullLengthSpectrum(clusterInfo.ClusterSpectrum, freqBinCount, lowerBinBound);
                TestTools.CompareTwoArrays(clusterSpectrum1, clusterSpectrum2);
            }
        }