public static Image <Rgb24> DrawDistanceSpectrogram(LDSpectrogramRGB cs1, LDSpectrogramRGB cs2) { string[] keys = cs1.ColorMap.Split('-'); string key = keys[0]; double[,] m1Red = cs1.GetNormalisedSpectrogramMatrix(key); IndexDistributions.SpectralStats stats = IndexDistributions.GetModeAndOneTailedStandardDeviation(m1Red); cs1.IndexStats.Add(key, stats); m1Red = MatrixTools.Matrix2ZScores(m1Red, stats.Mode, stats.StandardDeviation); ////LoggedConsole.WriteLine("1.{0}: Min={1:f2} Max={2:f2} Mode={3:f2}+/-{4:f3} (SD=One-tailed)", key, dict["min"], dict["max"], dict["mode"], dict["sd"]); key = keys[1]; double[,] m1Grn = cs1.GetNormalisedSpectrogramMatrix(key); stats = IndexDistributions.GetModeAndOneTailedStandardDeviation(m1Grn); cs1.IndexStats.Add(key, stats); m1Grn = MatrixTools.Matrix2ZScores(m1Grn, stats.Mode, stats.StandardDeviation); ////LoggedConsole.WriteLine("1.{0}: Min={1:f2} Max={2:f2} Mode={3:f2}+/-{4:f3} (SD=One-tailed)", key, dict["min"], dict["max"], dict["mode"], dict["sd"]); key = keys[2]; double[,] m1Blu = cs1.GetNormalisedSpectrogramMatrix(key); stats = IndexDistributions.GetModeAndOneTailedStandardDeviation(m1Blu); cs1.IndexStats.Add(key, stats); m1Blu = MatrixTools.Matrix2ZScores(m1Blu, stats.Mode, stats.StandardDeviation); ////LoggedConsole.WriteLine("1.{0}: Min={1:f2} Max={2:f2} Mode={3:f2}+/-{4:f3} (SD=One-tailed)", key, dict["min"], dict["max"], dict["mode"], dict["sd"]); key = keys[0]; double[,] m2Red = cs2.GetNormalisedSpectrogramMatrix(key); stats = IndexDistributions.GetModeAndOneTailedStandardDeviation(m2Red); cs2.IndexStats.Add(key, stats); m2Red = MatrixTools.Matrix2ZScores(m2Red, stats.Mode, stats.StandardDeviation); ////LoggedConsole.WriteLine("2.{0}: Min={1:f2} Max={2:f2} Mode={3:f2}+/-{4:f3} (SD=One-tailed)", key, dict["min"], dict["max"], dict["mode"], dict["sd"]); key = keys[1]; double[,] m2Grn = cs2.GetNormalisedSpectrogramMatrix(key); stats = IndexDistributions.GetModeAndOneTailedStandardDeviation(m2Grn); cs2.IndexStats.Add(key, stats); m2Grn = MatrixTools.Matrix2ZScores(m2Grn, stats.Mode, stats.StandardDeviation); ////LoggedConsole.WriteLine("2.{0}: Min={1:f2} Max={2:f2} Mode={3:f2}+/-{4:f3} (SD=One-tailed)", key, dict["min"], dict["max"], dict["mode"], dict["sd"]); key = keys[2]; double[,] m2Blu = cs2.GetNormalisedSpectrogramMatrix(key); stats = IndexDistributions.GetModeAndOneTailedStandardDeviation(m2Blu); cs2.IndexStats.Add(key, stats); m2Blu = MatrixTools.Matrix2ZScores(m2Blu, stats.Mode, stats.StandardDeviation); ////LoggedConsole.WriteLine("2.{0}: Min={1:f2} Max={2:f2} Mode={3:f2}+/-{4:f3} (SD=One-tailed)", key, dict["min"], dict["max"], dict["mode"], dict["sd"]); var v1 = new double[3]; double[] mode1 = { cs1.IndexStats[keys[0]].Mode, cs1.IndexStats[keys[1]].Mode, cs1.IndexStats[keys[2]].Mode, }; double[] stDv1 = { cs1.IndexStats[keys[0]].StandardDeviation, cs1.IndexStats[keys[1]].StandardDeviation, cs1.IndexStats[keys[2]].StandardDeviation, }; LoggedConsole.WriteLine( "1: avACI={0:f3}+/-{1:f3}; avTEN={2:f3}+/-{3:f3}; avCVR={4:f3}+/-{5:f3}", mode1[0], stDv1[0], mode1[1], stDv1[1], mode1[2], stDv1[2]); var v2 = new double[3]; double[] mode2 = { cs2.IndexStats[keys[0]].Mode, cs2.IndexStats[keys[1]].Mode, cs2.IndexStats[keys[2]].Mode, }; double[] stDv2 = { cs2.IndexStats[keys[0]].StandardDeviation, cs2.IndexStats[keys[1]].StandardDeviation, cs2.IndexStats[keys[2]].StandardDeviation, }; LoggedConsole.WriteLine( "2: avACI={0:f3}+/-{1:f3}; avTEN={2:f3}+/-{3:f3}; avCVR={4:f3}+/-{5:f3}", mode2[0], stDv2[0], mode2[1], stDv2[1], mode2[2], stDv2[2]); // assume all matrices are normalised and of the same dimensions int rows = m1Red.GetLength(0); // number of rows int cols = m1Red.GetLength(1); // number var d12Matrix = new double[rows, cols]; var d11Matrix = new double[rows, cols]; var d22Matrix = new double[rows, cols]; for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { v1[0] = m1Red[row, col]; v1[1] = m1Grn[row, col]; v1[2] = m1Blu[row, col]; v2[0] = m2Red[row, col]; v2[1] = m2Grn[row, col]; v2[2] = m2Blu[row, col]; d12Matrix[row, col] = DataTools.EuclideanDistance(v1, v2); d11Matrix[row, col] = (v1[0] + v1[1] + v1[2]) / 3; // get average of the normalised values d22Matrix[row, col] = (v2[0] + v2[1] + v2[2]) / 3; // following lines are for debugging purposes // if ((row == 150) && (col == 1100)) // { // LoggedConsole.WriteLine("V1={0:f3}, {1:f3}, {2:f3}", v1[0], v1[1], v1[2]); // LoggedConsole.WriteLine("V2={0:f3}, {1:f3}, {2:f3}", v2[0], v2[1], v2[2]); // LoggedConsole.WriteLine("EDist12={0:f4}; ED11={1:f4}; ED22={2:f4}", d12Matrix[row, col], d11Matrix[row, col], d22Matrix[row, col]); // } } } double[] array = DataTools.Matrix2Array(d12Matrix); NormalDist.AverageAndSD(array, out var avDist, out var sdDist); for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { d12Matrix[row, col] = (d12Matrix[row, col] - avDist) / sdDist; } } double zScore; Dictionary <string, Color> colourChart = GetDifferenceColourChart(); Color colour; var bmp = new Image <Rgb24>(cols, rows); for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { zScore = d12Matrix[row, col]; if (d11Matrix[row, col] >= d22Matrix[row, col]) { if (zScore > 3.08) { colour = colourChart["+99.9%"]; } // 99.9% conf else { if (zScore > 2.33) { colour = colourChart["+99.0%"]; } // 99.0% conf else { if (zScore > 1.65) { colour = colourChart["+95.0%"]; } // 95% conf else { if (zScore < 0.0) { colour = colourChart["NoValue"]; } else { // v = Convert.ToInt32(zScore * MaxRGBValue); // colour = Color.FromRgb(v, 0, v); colour = colourChart["+NotSig"]; } } } } // if() else bmp[col, row] = colour; } else { if (zScore > 3.08) { colour = colourChart["-99.9%"]; } // 99.9% conf else { if (zScore > 2.33) { colour = colourChart["-99.0%"]; } // 99.0% conf else { if (zScore > 1.65) { colour = colourChart["-95.0%"]; } // 95% conf else { if (zScore < 0.0) { colour = colourChart["NoValue"]; } else { // v = Convert.ToInt32(zScore * MaxRGBValue); // if() // colour = Color.FromRgb(0, v, v); colour = colourChart["-NotSig"]; } } } } // if() else bmp[col, row] = colour; } } // all rows } // all rows return(bmp); }