/// <summary> /// Calculate the relative intensities. /// </summary> /// <param name="mgfScan">The scan.</param> /// <returns>The scan with normalised intensities.</returns> private static RawScan CalcRelativeIntVals(RawScan mgfScan) { // Get the maximum intensity in the scan double maxInt = mgfScan.Intencities.Max(); // Create a temporary list of intensities List <double> intVals = new List <double>(); // Create a temporary list of M/Z-values List <double> mzVals = new List <double>(); // Loop through all of the intensities for (int i = 0; i <= mgfScan.Intencities.Length - 1; i++) { // Normalise the intensities double normIntVal = Math.Round(mgfScan.Intencities[i] / maxInt * 100); // If the normalised intensity is grater than 0, add the notmalised intensity and the current M/Z-value to their respective lists if (normIntVal > 0) { intVals.Add(normIntVal); mzVals.Add(mgfScan.MzValues[i]); } } // Set the new intensities mgfScan.Intencities = intVals.ToArray(); // Set the new M/Z-values mgfScan.MzValues = mzVals.ToArray(); // Return the new scan return(mgfScan); }
/// <summary> /// Add the info for a potential citrullination. /// </summary> /// <param name="index">The index of the potential citrullination.</param> private void AddPotCitInfo(int index) { // Set the parent mass double pMass = 1.007276470; // Get the spectrum XTSpectrum argSpec = valKVP.Key; // Get the scan RawScan potCitScan = valKVP.Value[index]; string scanIDProtein = string.Format("{0} / {1}", potCitScan.ScanNumber, argSpec.SpectrumLabel.Split('|')[1]); // Set the scan id metroLabelCitID.Text = scanIDProtein; // Set the parent mass metroLabelCitPMass.Text = Math.Round((potCitScan.PreCursorMz * potCitScan.Charge) - ((potCitScan.Charge - 1) * pMass), 3).ToString(); // Set the charge metroLabelCitCharge.Text = potCitScan.Charge.ToString(); // Set the sequence metroLabelCitSeq.Text = string.Format("({0})", argSpec.Proteins[0].DoaminSeq); // Set the retention time for the arginine spectrum metroLabelCitRTime.Text = string.Format("{0} sec.", potCitScan.RetentionTime); // Set the retention time for the MS1 Serie spectrum metroLabelPotCitMS1RTime.Text = string.Format("{0} sec.", potCitScan.RetentionTime); // Set the filename metroLabelPotCitFileName.Text = potCitScan.OriginalFileName.Split('.')[0]; // Set the scores metroLabelCitScore.Text = potCitScan.CitScore.ToString(); metroLabelMatchScore.Text = potCitScan.MatchScore.ToString(); }
/// <summary> /// Calculate CitScore and MatchScore for the complementary cit scan. /// </summary> /// <param name="mainArgSpectrum">The main arginine spectrum.</param> /// <param name="complCitScan">The complementary cit scan.</param> /// <returns>The scored scan.</returns> private static RawScan ScoreCitComplSpectrum(XTSpectrum mainArgSpectrum, RawScan complCitScan) { double citScore; //Validate the fragmentation. if (ValidateSpectrumFragmentation(complCitScan, mainArgSpectrum.SpectrumAminoAcidSequence)) { // Calculate CitScore citScore = IsIsoCyanicAcidLossPresentMs1(complCitScan) ? 10 : 0; //citScore += CountIsoCyanicAcidLossPresentMs2(mainArgSpectrum, complCitScan) * 1; citScore = -Math.Log10(0.05); citScore += CountIsoCyanicAcidLossPresentMs2(complCitScan, GetIndexOfCitrullinationFromArg(mainArgSpectrum), mainArgSpectrum.SpectrumAminoAcidSequence); } else { // If the fragmentation is invalid, set CitScore to 0 citScore = 0; complCitScan.IsoCyanicLossMzMs2 = new double[0]; } // Set the CitScore complCitScan.CitScore = Math.Round(citScore, 1); // Score match between spectra complCitScan = ScoreMatchMainArgComplCit(mainArgSpectrum, complCitScan); // Return spectra return(complCitScan); }
/// <summary> /// Find potential citrullination parent in MS1. /// </summary> /// <param name="scanMS2">The MS2 scan.</param> /// <returns>The MS2 spectrum with the new information.</returns> internal static RawScan FindPotCitParentMS1Scan(RawScan scanMS2) { // Loop through each of the input files foreach (Input input in FileReader.inputFiles) { // Get the filename of the input file string inputFileName = input.FilePath.Split('\\').Last(); // Check if input filename matches the original filename of the MS2 scan if (scanMS2.OriginalFileName == inputFileName) { // Loop through each of the MS1 scans foreach (RawScan s in input.MS1Scans) { // Check if the MS2 parent scan number matches the MS1 scan number if (scanMS2.ParentScanNumber == s.ScanNumber) { // If so: Set the MS1 scan as the parent scan of MS2 scanMS2.ParentScan = s; // Set MS2 to be an non-orphan scanMS2.Orphan = false; // Break and continue with the next scan break; } else { // If not: Set the scan to be an orphan scanMS2.Orphan = true; } } } } // Return the scan with the new information return(scanMS2); }
/// <summary> /// Add the next potnetial cirullination MS1 series. /// </summary> /// <param name="scanMS1">The MS1 scan.</param> private void AddNextPotCitMS1Series(RawScan scanMS1) { //Removes old series: chartPotCitMS1.Series.Remove(chartPotCitMS1.Series["Serie"]); //Add Data: chartPotCitMS1.Series.Add("Serie"); chartPotCitMS1.Series["Serie"].ChartType = SeriesChartType.StackedColumn; chartPotCitMS1.Series["Serie"].AxisLabel = "m/z"; chartPotCitMS1.Series["Serie"]["PixelPointWidth"] = "2"; double[] mzVals = scanMS1.ParentScan.MzValues; double[] intVals = scanMS1.ParentScan.Intencities; for (int i = 0; i <= mzVals.Length - 1; i++) { chartPotCitMS1.Series["Serie"].Points.AddXY(mzVals[i], intVals[i]); } chartPotCitMS1.Series["Serie"].ChartArea = "ChartArea"; chartPotCitMS1.Legends.Clear(); double ms2PrecursorMzVal = scanMS1.PreCursorMz; double tolerance = 0.05; for (int i = 0; i <= chartPotCitMS1.Series["Serie"].Points.Count() - 1; i++) { double error = Math.Abs(chartPotCitMS1.Series["Serie"].Points[i].XValue - ms2PrecursorMzVal); if (error <= tolerance) { chartPotCitMS1.Series["Serie"].Points[i].Color = Color.Blue; } if (chartPotCitMS1.Series["Serie"].Points[i].XValue == scanMS1.IsoCyanicMzMs1) { chartPotCitMS1.Series["Serie"].Points[i].Color = Color.Cyan; } } //Add X-Axis Maximum to chart: int xAxisMax = (int)Math.Ceiling(mzVals.Last() / 100) * 100; chartPotCitMS1.ChartAreas["ChartArea"].AxisX.Maximum = xAxisMax; //Make Custom Labels for X-Axis, interval 100: int endIndex = xAxisMax / 100; for (int i = 1; i <= endIndex; i++) { int index = i * 100; chartPotCitMS1.ChartAreas["ChartArea"].AxisX.CustomLabels.Add(index - 25, index + 25, string.Format("{0}", index), 2, LabelMarkStyle.None, GridTickTypes.TickMark); } }
/// <summary> /// Find the MS2 precursor peak the MS1 scans. /// </summary> /// <param name="precursorMass">The precursor mass.</param> /// <param name="scanMS1">The MS1 scan.</param> /// <returns>The intensity for the precursor peak.</returns> internal static double FindMS2PrecursorPeakIntInMS1(double precursorMass, RawScan scanMS1) { // Set a temporary intensity value double intVal = 0; // Loop through of the M/Z values in the MS1 scan for (int i = 0; i <= scanMS1.MzValues.Count() - 1; i++) { // If the M/Z-value matches the precursor mass, set the intensity. if (scanMS1.MzValues[i] == precursorMass) { intVal = scanMS1.Intencities[i]; } } // Return the intensity for the precursor peak return(intVal); }
/// <summary> /// Score the arginine spectra. /// </summary> /// <param name="inputSpectra">The dictionary with the arginine spectra to be scored and their complementary citrullinated spectra.</param> /// <returns>he dictionary with the scored spectra an their complementary citrullinated spectra.</returns> internal static Dictionary <XTSpectrum, List <RawScan> > ScoreArginineSpectra(Dictionary <XTSpectrum, List <RawScan> > inputSpectra) { // Create a temporary dictionary of scored spectra Dictionary <XTSpectrum, List <RawScan> > scoredSpectra = new Dictionary <XTSpectrum, List <RawScan> >(); // Loop throguh all of the spectra keyvaluepairs foreach (KeyValuePair <XTSpectrum, List <RawScan> > spectrum in inputSpectra) { // Get the arginine spectrum and set the array of isocyanic loss m/z in order to prevent error XTSpectrum argSpectrum = spectrum.Key; argSpectrum.IsoCyanicLossMzMs2 = new double[0]; List <RawScan> scoredCompCitScans = new List <RawScan>(); // Loop trough all of the complementary cit spectra foreach (RawScan citScan in spectrum.Value) { // Calculate the score RawScan scoredScan = ScoreCitComplSpectrum(argSpectrum, citScan); // Add the score to the list of cit scans scoredCompCitScans.Add(scoredScan); } // Sort the list var scoredCompSpectraSorted = from x in scoredCompCitScans orderby x.MatchScore descending select x; scoredCompCitScans = scoredCompSpectraSorted.ToList(); scoredSpectra.Add(argSpectrum, scoredCompCitScans); } // Sort dictionary var sortedScoredSpectra = (from x in scoredSpectra orderby x.Key.CitScore descending select x).ToDictionary(x => x.Key, x => x.Value); // Add spectra above cut-off if set to do so. if (ScoreSettings.IncludeCutOff) { // Add to quantification AddArgSpectraAboveCutOffToQuantification(sortedScoredSpectra); } // Return the sorted scored spectra return(sortedScoredSpectra); }
/// <summary> /// Handle orphan scan. /// </summary> /// <param name="scanMS2">The MS2 scan.</param> /// <returns>The MS2 scan with a "false" parent.</returns> internal static RawScan HandleOrphanScans(RawScan scanMS2) { // Create an array of MZ-values double[] valMZ = { 100, 300, 500, 700, 900, 1100, 1300, scanMS2.PreCursorMz }; // Create an array of intensities double[] valInt = { 30, 50, 100, 70, 40, 10, 20, 60 }; // Create a parent scan var scanParent = new RawScan { MzValues = valMZ, RetentionTime = 0, Intencities = valInt, TotalIonCount = 0 }; // If the scan is an orphan set the newly created scan to be the parent if (scanMS2.Orphan == true) { scanMS2.ParentScan = scanParent; } // The spectrum with a parent return(scanMS2); }
/// <summary> /// Score the match between the main arginine spectrum and the complementary citrullinated spectrum. /// </summary> /// <param name="mainArgSpectrum">The main arginine spectrum.</param> /// <param name="complCitSpectrum">The complementary citrullinated spectrum.</param> /// <returns>The complementary spectrum with the match score.</returns> internal static RawScan ScoreMatchMainArgComplCit(XTSpectrum mainArgSpectrum, RawScan complCitSpectrum) { // Create a temporary variables for the counts int aIonCount = 0; int bIonCount = 0; int b17IonCount = 0; int b18IonCount = 0; int yIonCount = 0; int y17IonCount = 0; int y18IonCount = 0; int citIndex = GetIndexOfCitrullinationFromArg(mainArgSpectrum); // Get the mass fragment error double fragMassError = double.Parse(External.XTandemInput.FMError, FileReader.NumberFormat); // Loop through the all of amino acid sequence. However only the index is used. for (int i = 0; i < mainArgSpectrum.SpectrumAminoAcidSequence.Length; i++) { // Check that both spectra contains the A-ion at this specific amino acid if (complCitSpectrum.AIonIndex.Contains(i) && mainArgSpectrum.AIonIndex.Contains(i)) { /* Calculate A-ion */ // Get the M/Z value for A-ion on the complementary citrullinated spectrum double citMz = complCitSpectrum.SpectrumPossibleAIons[i]; // Get the M/Z value for b-ion on the main arginine spectrum double argMz = mainArgSpectrum.SpectrumPossibleAIons[i]; // If the m/z-values has the right shift. Increment the ion count by 1 if (HasCorrectCitMassShift(citMz, argMz, fragMassError, i >= citIndex)) { aIonCount++; } } // Check that both spectra contains the B-ion at this specific amino acid if (complCitSpectrum.BIonIndex.Contains(i) && mainArgSpectrum.BIonIndex.Contains(i)) { /* Calculate B-ion */ // Get the M/Z value for b-ion on the complementary citrullinated spectrum double citMz = complCitSpectrum.SpectrumPossibleBIons[i]; // Get the M/Z value for b-ion on the main arginine spectrum double argMz = mainArgSpectrum.SpectrumPossibleBIons[i]; // If the m/z-values has the right shift. Increment the ion count by 1 if (HasCorrectCitMassShift(citMz, argMz, fragMassError, i >= citIndex)) { bIonCount++; } } // Check that both spectra contains the B-17-ion at this specific amino acid if (complCitSpectrum.B17IonIndex.Contains(i) && mainArgSpectrum.B17IonIndex.Contains(i)) { /* Calculate B-17-ion */ // Get the M/Z value for b-17-ion on the complementary citrullinated spectrum double citMz = complCitSpectrum.SpectrumPossibleBm17Ions[i]; // Get the M/Z value for b-17-ion on the main arginine spectrum double artMz = mainArgSpectrum.SpectrumPossibleBm17Ions[i]; // If the m/z-values has the right shift. Increment the ion count by 1 if (HasCorrectCitMassShift(citMz, artMz, fragMassError, i >= citIndex)) { b17IonCount++; } } // Check that both spectra contains the B-18-ion at this specific amino acid if (complCitSpectrum.B18IonIndex.Contains(i) && mainArgSpectrum.B18IonIndex.Contains(i)) { /* Calculate B-18-ion */ // Get the M/Z value for b-ion on the complementary citrullinated spectrum double citMz = complCitSpectrum.SpectrumPossibleBm18Ions[i]; // Get the M/Z value for b-ion on the main arginine spectrum double argMz = mainArgSpectrum.SpectrumPossibleBm18Ions[i]; // If the m/z-values has the right shift. Increment the ion count by 1 if (HasCorrectCitMassShift(citMz, argMz, fragMassError, i >= citIndex)) { b18IonCount++; } } // Check that both spectra contains the Y-ion at this specific amino acid if (complCitSpectrum.YIonIndex.Contains(i) && mainArgSpectrum.YIonIndex.Contains(i)) { /* Calculate Y-ion */ // Get the M/Z value for y-ion on the complementary citrullinated spectrum double citMz = complCitSpectrum.SpectrumPossibleYIons[i]; // Get the M/Z value for y-ion on the main arginine spectrum double argMz = mainArgSpectrum.SpectrumPossibleYIons[i]; // If the m/z-values has the right shift. Increment the ion count by 1 if (HasCorrectCitMassShift(citMz, argMz, fragMassError, i <= citIndex)) { yIonCount++; } } // Check that both spectra contains the B-ion at this specific amino acid if (complCitSpectrum.Y17IonIndex.Contains(i) && mainArgSpectrum.Y17IonIndex.Contains(i)) { /* Calculate Y-ion */ // Get the M/Z value for y-18-ion on the complementary citrullinated spectrum double citMz = complCitSpectrum.SpectrumPossibleYm17Ions[i]; // Get the M/Z value for y-ion on the main arginine spectrum double argMz = mainArgSpectrum.SpectrumPossibleYm17Ions[i]; // If the m/z-values has the right shift. Increment the ion count by 1 if (HasCorrectCitMassShift(citMz, argMz, fragMassError, i <= citIndex)) { y17IonCount++; } } if (complCitSpectrum.Y18IonIndex.Contains(i) && mainArgSpectrum.Y18IonIndex.Contains(i)) { /* Calculate Y-18-ion */ // Get the M/Z value for y-18-ion on the complementary citrullinated spectrum double citMz = complCitSpectrum.SpectrumPossibleYm18Ions[i]; // Get the M/Z value for y-18-ion on the main arginine spectrum double argMz = mainArgSpectrum.SpectrumPossibleYm18Ions[i]; // If the m/z-values has the right shift. Increment the ion count by 1. if (HasCorrectCitMassShift(citMz, argMz, fragMassError, i <= citIndex)) { y18IonCount++; } } } /* Calculate the score */ double score = aIonCount * ScoreSettings.AIonMatchScore; score += bIonCount * ScoreSettings.BIonMatchScore; score += b17IonCount * (ScoreSettings.BIonMatchScore / ScoreSettings.LossMatchScoreDivider); score += b18IonCount * (ScoreSettings.BIonMatchScore / ScoreSettings.LossMatchScoreDivider); score += yIonCount * ScoreSettings.YIonMatchScore; score += y17IonCount * (ScoreSettings.YIonMatchScore / ScoreSettings.LossMatchScoreDivider); score += y18IonCount * (ScoreSettings.YIonMatchScore / ScoreSettings.LossMatchScoreDivider); // Round the score to x. score = Math.Round(score, 1); // Set the score complCitSpectrum.MatchScore = score; // Return the match score return(complCitSpectrum); }
/// <summary> /// Add the arginine spectra to the quantififcation dictionary. /// </summary> /// <param name="argSpec">The arginine spectra.</param> /// <param name="citScan">The citrullinated scan.</param> /// <returns>The dictionary containing the new spectra.</returns> internal static Dictionary <XTSpectrum, RawScan> AddTokvpArgSpecScanDict(XTSpectrum argSpec, RawScan citScan) { if (argSpecScanDict.ContainsKey(argSpec) == false) { argSpecScanDict.Add(argSpec, citScan); } return(argSpecScanDict); }
/// <summary> /// Set the original filename to the MS2 spectrum. /// </summary> /// <param name="potCitSpecMS2">The MS2 scab.</param> /// <param name="input">The input file.</param> /// <returns>The MS2 scan with the original filename.</returns> private static RawScan ReturnOriginalFileNameScan(RawScan potCitSpecMS2, Input input) { potCitSpecMS2.OriginalFileName = input.FilePath.Split('\\').Last(); return(potCitSpecMS2); }
/// <summary> /// Find complementary citrullinated scans. /// </summary> /// <param name="error">The maximum parent mass error allowed.</param> internal static void FindComplimentaryCitrullinationScans(double error) { // Get the list of used citrullination spectra List <int> usedIDList = GetListOfUsedIDs(); // Set the proton mass double pMass = 1.007276470; // Set the arginine validation result list to list of validation results var vResultList = argValResults; // Loop through all of the vlaidation results foreach (ValResult result in vResultList) { // Get the name of the inpput file string inputFileName = result.ParentResult.OriginalInputFile; // Loop through all of the input results foreach (Input input in FileReader.inputFiles) { // TODO: Can be inserted into if statement if it needs only to work on single results // Create a temporary dictionary of spectra and their complementary scans Dictionary <XTSpectrum, List <RawScan> > compPepDic = new Dictionary <XTSpectrum, List <RawScan> >(); // Loop through all of the arginine spectra foreach (XTSpectrum specArg in result.ArginineSpectra) { // If the arginine spectra is already used, continue if (usedIDList.Contains(specArg.ID)) { continue; } else { // If not. // Create a tmeporary list of complementary scans var compPeptides = new List <RawScan>(); // Calculate the ions XTSpectrum scanArg = IonCalculation.CalculateAllIons(specArg); // Loop through all of the MS2 scans foreach (RawScan mgfScan in input.MS2Scans) { // Calculate the parent mass error double delta = Math.Abs(scanArg.ParentMass - ((mgfScan.PreCursorMz * mgfScan.Charge) - ((mgfScan.Charge - 1) * pMass) - 0.984)); // Check if the parent mass error is less than the allowed parent mass error if (delta <= error) { // If so. // Calculate the relative intenties values RawScan normMgfScan = CalcRelativeIntVals(mgfScan); // Calculate all potential citrullination ions normMgfScan = IonCalculation.CalculateAllPotentialCitrullinationIons(scanArg, normMgfScan); // Get the original filename normMgfScan = ReturnOriginalFileNameScan(normMgfScan, input); // Find the potential citrullinated parent in MS1 normMgfScan = FindMS1.FindPotCitParentMS1Scan(normMgfScan); // Handle orphan scans normMgfScan = FindMS1.HandleOrphanScans(normMgfScan); // Add the scan to the list compPeptides.Add(normMgfScan); } } // If no complementary scan has been found, continue. if (compPeptides.Count() == 0) { continue; } else { // If the dictionary of complementary scans does not already contains the arginine spectra, add it if (compPepDic.ContainsKey(scanArg) == false) { compPepDic.Add(scanArg, compPeptides); } } } } // Set the dictionary to the result result.ArgSpectraDictionary = compPepDic; } } // Set the result list ReturnValResultArg(vResultList); }
/// <summary> /// Calculate all of the potential citrullination ions. /// </summary> /// <param name="argScanMS2">The arginine MS2 spectrum.</param> /// <param name="potCitMS2Scan">The potential citrulliated scan.</param> /// <returns>The scan with the potential citrullination ions.</returns> internal static RawScan CalculateAllPotentialCitrullinationIons(XTSpectrum argScanMS2, RawScan potCitMS2Scan) { // Get the amino acid sequence string[] aas = argScanMS2.SpectrumAminoAcidSequence; // Create a variable for holding the arginine B-index int aaModB = 0; // Loop through the sequence and try to find the index of the arginine. for (int i = 0; i <= aas.Length - 1; i++) { if (aas[i] == "R") { aaModB = i; break; } } // Calculate the Y-index int aaModY = Math.Abs(aaModB - aas.Length) - 1; // Create a temporary list for the possible y-ions List <double> posYIonList = new List <double>(); // Loop through all of the possible y-ions for (int i = 0; i <= argScanMS2.SpectrumPossibleYIons.Length - 1; i++) { // If the current ion is greater than the currenty y-ion index if (i >= aaModY) { // Calculate the modification and add it to the list double modYIon = argScanMS2.SpectrumPossibleYIons[i] + 0.9845; posYIonList.Add(modYIon); } else { // If it is less than the value, just add it posYIonList.Add(argScanMS2.SpectrumPossibleYIons[i]); } } // Set the possible ions double[] yIonsPos = posYIonList.ToArray(); // Create a temporary list of B-ions List <double> posBIonList = new List <double>(); // Loop through all of the possible y-ions for (int i = 0; i <= argScanMS2.SpectrumPossibleBIons.Length - 1; i++) { // If the current ion is greater than the currenty b-ion index if (i >= aaModB) { // Calculate the modification and add it to the list double modBIon = argScanMS2.SpectrumPossibleBIons[i] + 0.9845; posBIonList.Add(modBIon); } else { // If it is less than the value, just add it posBIonList.Add(argScanMS2.SpectrumPossibleBIons[i]); } } // Set the possible ions double[] posBIons = posBIonList.ToArray(); // Make all the necesarry list to calculate all the Ions: List <double> bIons = new List <double>(); List <double> b17Ions = new List <double>(); List <double> b18Ions = new List <double>(); List <double> yIons = new List <double>(); List <double> y17Ions = new List <double>(); List <double> y18Ions = new List <double>(); List <double> aIons = new List <double>(); List <double> b17IonsPos = new List <double>(); List <double> b18IonsPos = new List <double>(); List <double> y17IonsPos = new List <double>(); List <double> y18IonsPos = new List <double>(); List <double> aIonsPos = new List <double>(); List <int> bIonIndex = new List <int>(); List <int> b17IonIndex = new List <int>(); List <int> b18IonIndex = new List <int>(); List <int> yIonIndex = new List <int>(); List <int> y17IonIndex = new List <int>(); List <int> y18IonIndex = new List <int>(); List <int> aIonIndex = new List <int>(); // Set tha mass of hydrogen, carbon and oxygen. Calculate masses for OH- and CO-groups and water double hMass = 1.007825035; double cMAss = 12.000000000; double oMass = 15.994914630; double ohMass = hMass + oMass; double coMass = cMAss + oMass; double h2oMass = (2 * hMass) + oMass; //Begin calculating all the existing Ions in the spectrum: double error = double.Parse(External.XTandemInput.FMError, FileReader.NumberFormat); // Loop through all of the M/Z-values foreach (double mz in potCitMS2Scan.MzValues) { // Loop through all of the possible B-ions to find the B-ions. for (int i = 0; i <= posBIons.Length - 1; i++) { // Calculate the the fragment difference double delta = Math.Abs(mz - posBIons[i]); // If the fragment difference is less than the max error, add it to the list if (delta <= error) { bIons.Add(mz); bIonIndex.Add(i); } } // Loop through all of the possible B-ions to find the B-17 ions. for (int i = 0; i <= posBIons.Length - 1; i++) { // Add the possible ion b17IonsPos.Add(Math.Round(posBIons[i] - ohMass, 3)); // Calculate the the fragment difference double delta = Math.Abs(mz - (posBIons[i] - ohMass)); // If the fragment difference is less than the max error, add it to the list if (delta <= error) { b17Ions.Add(mz); b17IonIndex.Add(i); } } // Loop through all of the possible B-ions to find the B-17 ions. for (int i = 0; i <= posBIons.Length - 1; i++) { // Add the possible ion b18IonsPos.Add(Math.Round(posBIons[i] - h2oMass, 3)); // Calculate the the fragment difference double delta = Math.Abs(mz - (posBIons[i] - h2oMass)); // If the fragment difference is less than the max error, add it to the list if (delta <= error) { b18Ions.Add(mz); b18IonIndex.Add(i); } } // Loop through all of the possible Y-ions to find the Y-ions. for (int i = 0; i <= yIonsPos.Length - 1; i++) { // Calculate the the fragment difference double delta = Math.Abs(mz - yIonsPos[i]); // If the fragment difference is less than the max error, add it to the list if (delta <= error) { yIons.Add(mz); yIonIndex.Add(i); } } // Loop through all of the possible Y-ions to find the Y-17 ions. for (int i = 0; i <= yIonsPos.Length - 1; i++) { // Add the possible ion y17IonsPos.Add(Math.Round(yIonsPos[i] - ohMass, 3)); // Calculate the the fragment difference double delta = Math.Abs(mz - (yIonsPos[i] - ohMass)); // If the fragment difference is less than the max error, add it to the list if (delta <= error) { y17Ions.Add(mz); y17IonIndex.Add(i); } } // Loop through all of the possible Y-ions to find the Y-18 ions. for (int i = 0; i <= yIonsPos.Length - 1; i++) { // Add the possible ion y18IonsPos.Add(Math.Round(yIonsPos[i] - h2oMass, 3)); // Calculate the the fragment difference double delta = Math.Abs(mz - (yIonsPos[i] - h2oMass)); // If the fragment difference is less than the max error, add it to the list if (delta <= error) { y18Ions.Add(mz); y18IonIndex.Add(i); } } // Loop through all of the possible Y-ions to find the A-ions. for (int i = 0; i <= posBIons.Length - 1; i++) { // Add the possible ion aIonsPos.Add(Math.Round(posBIons[i] - coMass, 3)); // Calculate the the fragment difference double delta = Math.Abs(mz - (posBIons[i] - coMass)); // If the fragment difference is less than the max error, add it to the list if (delta <= error) { aIons.Add(mz); aIonIndex.Add(i); } } } // Set the lists to the spectrum potCitMS2Scan.SpectrumPossibleBIons = posBIons; potCitMS2Scan.SpectrumPossibleYIons = yIonsPos; potCitMS2Scan.SpectrumPossibleAIons = aIonsPos.ToArray(); potCitMS2Scan.SpectrumPossibleBm18Ions = b18IonsPos.ToArray(); potCitMS2Scan.SpectrumPossibleBm17Ions = b17IonsPos.ToArray(); potCitMS2Scan.SpectrumPossibleYm18Ions = y18IonsPos.ToArray(); potCitMS2Scan.SpectrumPossibleYm17Ions = y17IonsPos.ToArray(); potCitMS2Scan.SpectrumExistingBIons = bIons.ToArray(); potCitMS2Scan.SpectrumBm17Ions = b17Ions.ToArray(); potCitMS2Scan.SpectrumBm18Ions = b18Ions.ToArray(); potCitMS2Scan.SpectrumExistingYIons = yIons.ToArray(); potCitMS2Scan.SpectrumYm17Ions = y17Ions.ToArray(); potCitMS2Scan.SpectrumYm18Ions = y18Ions.ToArray(); potCitMS2Scan.SpectrumAIons = aIons.ToArray(); potCitMS2Scan.BIonIndex = bIonIndex.ToArray(); potCitMS2Scan.B17IonIndex = b17IonIndex.ToArray(); potCitMS2Scan.B18IonIndex = b18IonIndex.ToArray(); potCitMS2Scan.YIonIndex = yIonIndex.ToArray(); potCitMS2Scan.Y17IonIndex = y17IonIndex.ToArray(); potCitMS2Scan.Y18IonIndex = y18IonIndex.ToArray(); potCitMS2Scan.AIonIndex = aIonIndex.ToArray(); // Return the spectrum with the new information return(potCitMS2Scan); }