예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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();
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
 /// <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);
 }
예제 #5
0
        /// <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);
            }
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
        /// <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);
        }
예제 #8
0
        /// <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);
        }
예제 #9
0
        /// <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);
        }
예제 #10
0
        /// <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);
        }
예제 #11
0
 /// <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);
 }
예제 #12
0
        /// <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);
        }
예제 #13
0
        /// <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);
        }