//** aligns the two peak's intensity profiles, returns cosine similarity (A dot B) / (|A| * |B|) ** public static float CalcCorrelation(Peak psI, Peak psJ) { //** scan indices of each peak ** int[] indI = psI.GetScanIndices(); int[] indJ = psJ.GetScanIndices(); //** min and max scan indexes over both peaks ** int minIndex = Math.Min(indI[0], indJ[0]); int maxIndex = Math.Max(indI[indI.Length - 1], indJ[indJ.Length - 1]); //** range of synthesized indices ** int len = maxIndex - minIndex + 1; //** intensity profile of peakI ** float[] profileI = new float[len + 2]; for (int a = 0; a < indI.Length; a++) { profileI[indI[a] - minIndex + 1] = psI.GetSmoothIntensity(a); } //** " peakJ ** float[] profileJ = new float[len + 2]; for (int a = 0; a < indJ.Length; a++) { profileJ[indJ[a] - minIndex + 1] = psJ.GetSmoothIntensity(a); } int c = 0; int l = profileI.Length; int[] valids = new int[l]; //** iterate through I's intensity profile, collecting index of valid peak intensities ** //** valid === one peak has an entry, or its the begnning or end ** for (int x = 0; x < l; x++) { if (profileI[x] > 0 || profileJ[x] > 0 || x == 0 || x == l - 1) { valids[c++] = x; } } //** trim valid array ** valids = ArrayUtil.SubArray(valids, c); //** return cosine similarity between the two aligned arrays ** return(ArrayUtil.Cosine(ArrayUtil.SubArray(profileI, valids), ArrayUtil.SubArray(profileJ, valids))); }