public IndexedMassSpectralPeak(MassSpectralPeak peak, IMsDataScan <IMzSpectrum <IMzPeak> > scan, int index) { mainPeak = peak; this.scan = scan; zeroBasedIndexOfPeakInScan = index; massSpectralPeakIntensity = peak.Intensity; oneBasedScanNumber = scan.OneBasedScanNumber; retentionTime = scan.RetentionTime; }
public static void MatchIons(IMsDataScan <IMzSpectrum <IMzPeak> > thisScan, Tolerance productMassTolerance, double[] sortedTheoreticalProductMassesForThisPeptide, List <double> matchedIonMassesList, List <double> productMassErrorDa, List <double> productMassErrorPpm, double precursorMass, List <DissociationType> dissociationTypes, bool addCompIons) { var TotalProductsHere = sortedTheoreticalProductMassesForThisPeptide.Length; if (TotalProductsHere == 0) { return; } int currentTheoreticalIndex = -1; double currentTheoreticalMass; do { currentTheoreticalIndex++; currentTheoreticalMass = sortedTheoreticalProductMassesForThisPeptide[currentTheoreticalIndex]; } while (double.IsNaN(currentTheoreticalMass) && currentTheoreticalIndex < sortedTheoreticalProductMassesForThisPeptide.Length - 1); if (double.IsNaN(currentTheoreticalMass)) { return; } double currentTheoreticalMz = currentTheoreticalMass + Constants.protonMass; int testTheoreticalIndex; double testTheoreticalMass; double testTheoreticalMz; // speed optimizations double[] experimental_mzs = thisScan.MassSpectrum.XArray; double[] experimental_intensities = thisScan.MassSpectrum.YArray; int numExperimentalPeaks = experimental_mzs.Length; // Loop over all experimental indices for (int experimentalIndex = 0; experimentalIndex < numExperimentalPeaks; experimentalIndex++) { double currentExperimentalMz = experimental_mzs[experimentalIndex]; // If found match if (productMassTolerance.Within(currentExperimentalMz, currentTheoreticalMz)) { matchedIonMassesList.Add(currentTheoreticalMass); double currentExperimentalMass = currentExperimentalMz - Constants.protonMass; productMassErrorDa.Add(currentExperimentalMass - currentTheoreticalMass); productMassErrorPpm.Add((currentExperimentalMass - currentTheoreticalMass) * 1000000 / currentTheoreticalMass); currentTheoreticalIndex++; if (currentTheoreticalIndex == TotalProductsHere) { break; } currentTheoreticalMass = sortedTheoreticalProductMassesForThisPeptide[currentTheoreticalIndex]; currentTheoreticalMz = currentTheoreticalMass + Constants.protonMass; } // Else if for sure did not reach the next theoretical yet else if (currentExperimentalMz > currentTheoreticalMz) { // Move on to next index and never come back! currentTheoreticalIndex++; if (currentTheoreticalIndex == TotalProductsHere) { break; } currentTheoreticalMass = sortedTheoreticalProductMassesForThisPeptide[currentTheoreticalIndex]; currentTheoreticalMz = currentTheoreticalMass + Constants.protonMass; // Start with the current ones testTheoreticalIndex = currentTheoreticalIndex; testTheoreticalMass = currentTheoreticalMass; testTheoreticalMz = currentTheoreticalMz; // Mark the skipped theoreticals as not found. The last one is not for sure, might be flipped! while (currentExperimentalMz > testTheoreticalMz) { // Store old info for possible reuse currentTheoreticalMz = testTheoreticalMz; currentTheoreticalMass = testTheoreticalMass; currentTheoreticalIndex = testTheoreticalIndex; // Update test stuff! testTheoreticalIndex++; if (testTheoreticalIndex == TotalProductsHere) { break; } testTheoreticalMass = sortedTheoreticalProductMassesForThisPeptide[testTheoreticalIndex]; testTheoreticalMz = testTheoreticalMass + Constants.protonMass; } experimentalIndex--; } } if (addCompIons) { double[] complementaryMasses = new double[numExperimentalPeaks]; double[] complementaryIntensities = new double[numExperimentalPeaks]; foreach (DissociationType dissociationType in dissociationTypes) { if (complementaryIonConversionDictionary.TryGetValue(dissociationType, out double protonMassShift)) { currentTheoreticalIndex = -1; do { currentTheoreticalIndex++; currentTheoreticalMass = sortedTheoreticalProductMassesForThisPeptide[currentTheoreticalIndex]; } while (double.IsNaN(currentTheoreticalMass) && currentTheoreticalIndex < sortedTheoreticalProductMassesForThisPeptide.Length - 1); double massShiftForComplementaryConversion = precursorMass + protonMassShift; //mass shift needed to reobtain the original product ion for calculating tolerance for (int i = numExperimentalPeaks - 1; i >= 0; i--) { complementaryMasses[numExperimentalPeaks - i - 1] = massShiftForComplementaryConversion - experimental_mzs[i]; complementaryIntensities[numExperimentalPeaks - i - 1] = experimental_intensities[i]; } // Loop over all experimental indices for (int experimentalIndex = 0; experimentalIndex < numExperimentalPeaks; experimentalIndex++) { double currentExperimentalMass = complementaryMasses[experimentalIndex]; double originalExperimentalMass = massShiftForComplementaryConversion - currentExperimentalMass; double minBoundary = currentExperimentalMass - originalExperimentalMass + productMassTolerance.GetMinimumValue(originalExperimentalMass); double maxBoundary = currentExperimentalMass - originalExperimentalMass + productMassTolerance.GetMaximumValue(originalExperimentalMass); // If found match if (minBoundary < currentTheoreticalMass && maxBoundary > currentTheoreticalMass) { matchedIonMassesList.Add(currentTheoreticalMass); productMassErrorDa.Add(currentExperimentalMass - currentTheoreticalMass); productMassErrorPpm.Add((currentExperimentalMass - currentTheoreticalMass) * 1000000 / currentTheoreticalMass); currentTheoreticalIndex++; if (currentTheoreticalIndex == TotalProductsHere) { break; } currentTheoreticalMass = sortedTheoreticalProductMassesForThisPeptide[currentTheoreticalIndex]; } // Else if for sure passed a theoretical else if (currentExperimentalMass > currentTheoreticalMass) { // Move on to next index and never come back! currentTheoreticalIndex++; if (currentTheoreticalIndex == TotalProductsHere) { break; } currentTheoreticalMass = sortedTheoreticalProductMassesForThisPeptide[currentTheoreticalIndex]; // Start with the current ones testTheoreticalIndex = currentTheoreticalIndex; testTheoreticalMass = currentTheoreticalMass; // Mark the skipped theoreticals as not found. The last one is not for sure, might be flipped! while (currentExperimentalMass > testTheoreticalMass) { // Store old info for possible reuse currentTheoreticalMass = testTheoreticalMass; currentTheoreticalIndex = testTheoreticalIndex; // Update test stuff! testTheoreticalIndex++; if (testTheoreticalIndex == TotalProductsHere) { break; } testTheoreticalMass = sortedTheoreticalProductMassesForThisPeptide[testTheoreticalIndex]; } experimentalIndex--; } } } else { throw new NotImplementedException(); } } } }
//Calculate score based on Product Masses. public static double XlMatchIons(IMsDataScan <IMzSpectrum <IMzPeak> > thisScan, Tolerance productMassTolerance, double[] sorted_theoretical_product_masses_for_this_peptide, string[] sorted_theoretical_product_name_for_this_peptide, MatchedIonInfo matchedIonMassesListPositiveIsMatch) { var TotalProductsHere = sorted_theoretical_product_masses_for_this_peptide.Length; if (TotalProductsHere == 0) { return(0); } int MatchingProductsHere = 0; double MatchingIntensityHere = 0; // speed optimizations double[] experimental_mzs = thisScan.MassSpectrum.XArray; double[] experimental_intensities = thisScan.MassSpectrum.YArray; int[] experimental_intensities_rank = GenerateIntensityRanks(experimental_mzs, experimental_intensities); int num_experimental_peaks = experimental_mzs.Length; int currentTheoreticalIndex = -1; double currentTheoreticalMass; do { currentTheoreticalIndex++; currentTheoreticalMass = sorted_theoretical_product_masses_for_this_peptide[currentTheoreticalIndex]; } while (double.IsNaN(currentTheoreticalMass) && currentTheoreticalIndex < sorted_theoretical_product_masses_for_this_peptide.Length - 1); if (double.IsNaN(currentTheoreticalMass)) { return(0); } double currentTheoreticalMz = currentTheoreticalMass + Constants.protonMass; int testTheoreticalIndex; double testTheoreticalMZ; double testTheoreticalMass; // Loop over all experimenal indices for (int experimentalIndex = 0; experimentalIndex < num_experimental_peaks; experimentalIndex++) { double currentExperimentalMZ = experimental_mzs[experimentalIndex]; // If found match if (productMassTolerance.Within(currentExperimentalMZ, currentTheoreticalMz)) { MatchingProductsHere++; MatchingIntensityHere += experimental_intensities[experimentalIndex]; matchedIonMassesListPositiveIsMatch.MatchedIonMz[currentTheoreticalIndex] = currentTheoreticalMass; matchedIonMassesListPositiveIsMatch.MatchedIonIntensity[currentTheoreticalIndex] = experimental_intensities[experimentalIndex]; matchedIonMassesListPositiveIsMatch.MatchedIonName[currentTheoreticalIndex] = sorted_theoretical_product_name_for_this_peptide[currentTheoreticalIndex]; matchedIonMassesListPositiveIsMatch.MatchedIonIntensityRank[currentTheoreticalIndex] = experimental_intensities_rank[experimentalIndex]; currentTheoreticalIndex++; if (currentTheoreticalIndex == TotalProductsHere) { break; } currentTheoreticalMass = sorted_theoretical_product_masses_for_this_peptide[currentTheoreticalIndex]; currentTheoreticalMz = currentTheoreticalMass + Constants.protonMass; } // Else if for sure did not reach the next theoretical yet, move to next experimental else if (currentExperimentalMZ < currentTheoreticalMz) { continue; } // Else if for sure passed a theoretical else { // Mark the theoretical as missed matchedIonMassesListPositiveIsMatch.MatchedIonMz[currentTheoreticalIndex] = -currentTheoreticalMass; // Move on to next index and never come back! currentTheoreticalIndex++; if (currentTheoreticalIndex == TotalProductsHere) { break; } currentTheoreticalMass = sorted_theoretical_product_masses_for_this_peptide[currentTheoreticalIndex]; currentTheoreticalMz = currentTheoreticalMass + Constants.protonMass; // Start with the current ones testTheoreticalIndex = currentTheoreticalIndex; testTheoreticalMZ = currentTheoreticalMz; testTheoreticalMass = currentTheoreticalMass; // Mark the skipped theoreticals as not found. The last one is not for sure, might be flipped! while (currentExperimentalMZ > testTheoreticalMZ) { matchedIonMassesListPositiveIsMatch.MatchedIonMz[testTheoreticalIndex] = -currentTheoreticalMass; // Store old info for possible reuse currentTheoreticalMass = testTheoreticalMass; currentTheoreticalMz = testTheoreticalMZ; currentTheoreticalIndex = testTheoreticalIndex; // Update test stuff! testTheoreticalIndex++; if (testTheoreticalIndex == TotalProductsHere) { break; } testTheoreticalMass = sorted_theoretical_product_masses_for_this_peptide[testTheoreticalIndex]; testTheoreticalMZ = testTheoreticalMass + Constants.protonMass; } experimentalIndex--; } } return(MatchingProductsHere + MatchingIntensityHere / thisScan.TotalIonCurrent); }
public void Compress() { scan = null; }