public static void TestCompIons_MatchIonsScore() { TestDataFile t = new TestDataFile(); Tolerance productMassTolerance = new AbsoluteTolerance(0.01); double precursorMass = 300; //The below theoretical does not accurately represent B-Y ions double[] sorted_theoretical_product_masses_for_this_peptide = new double[] { precursorMass + (2 * Constants.ProtonMass) - 275.1350, precursorMass + (2 * Constants.ProtonMass) - 258.127, precursorMass + (2 * Constants.ProtonMass) - 257.1244, 50, 60, 70, 147.0764, precursorMass + (2 * Constants.ProtonMass) - 147.0764, precursorMass + (2 * Constants.ProtonMass) - 70, precursorMass + (2 * Constants.ProtonMass) - 60, precursorMass + (2 * Constants.ProtonMass) - 50, 257.1244, 258.127, 275.1350 }; //{ 50, 60, 70, 147.0764, 257.1244, 258.127, 275.1350 } List <Product> productsWithLocalizedMassDiff = new List <Product>(); foreach (double d in sorted_theoretical_product_masses_for_this_peptide) { productsWithLocalizedMassDiff.Add(new Product(ProductType.b, FragmentationTerminus.Both, d, 1, 1, 0)); } CommonParameters commonParametersNoComp = new CommonParameters { ProductMassTolerance = new AbsoluteTolerance(0.01) }; CommonParameters commonParametersWithComp = new CommonParameters(productMassTolerance: new AbsoluteTolerance(0.01), addCompIons: true); MsDataScan scan = t.GetOneBasedScan(2); var scanWithMass = new Ms2ScanWithSpecificMass(scan, precursorMass.ToMz(1), 1, "", new CommonParameters()); List <MatchedFragmentIon> matchedIons = MetaMorpheusEngine.MatchFragmentIons(scanWithMass, productsWithLocalizedMassDiff, commonParametersNoComp); List <MatchedFragmentIon> matchedCompIons = MetaMorpheusEngine.MatchFragmentIons(scanWithMass, productsWithLocalizedMassDiff, commonParametersWithComp); matchedCompIons.AddRange(matchedIons); // score when the mass-diff is on this residue double localizedScore = MetaMorpheusEngine.CalculatePeptideScore(scan, matchedIons); double scoreNormal = MetaMorpheusEngine.CalculatePeptideScore(scan, matchedIons); double scoreComp = MetaMorpheusEngine.CalculatePeptideScore(scan, matchedCompIons); Assert.IsTrue(scoreNormal * 2 == scoreComp && scoreComp > scoreNormal + 1); }
public static void TestPsmHeader() { CommonParameters commonParameters = new CommonParameters(); PeptideWithSetModifications pepWithSetMods = new Protein( "MQQQQQQQ", "accession1", "org", new List <Tuple <string, string> > { new Tuple <string, string>("geneNameType", "geneName") }, new Dictionary <int, List <Modification> > { { 2, new List <Modification> { new Modification("mod", "mod") } } }, name: "name", fullName: "fullName", sequenceVariations: new List <SequenceVariation> { new SequenceVariation(2, "P", "Q", "changed this sequence") }) .Digest(commonParameters.DigestionParams, new List <Modification>(), new List <Modification>()).First(); MsDataFile myMsDataFile = new TestDataFile(pepWithSetMods, "quadratic"); MsDataScan scann = myMsDataFile.GetOneBasedScan(2); Ms2ScanWithSpecificMass scan = new Ms2ScanWithSpecificMass(scann, 4, 1, null, new CommonParameters()); var theoreticalIons = new List <Product>(); pepWithSetMods.Fragment(DissociationType.HCD, FragmentationTerminus.Both, theoreticalIons); var matchedIons = MetaMorpheusEngine.MatchFragmentIons(scan, theoreticalIons, new CommonParameters()); PeptideSpectralMatch psm = new PeptideSpectralMatch(pepWithSetMods, 1, 2, 3, scan, commonParameters, matchedIons); psm.ResolveAllAmbiguities(); var t = psm.ToString(); var tabsepheader = PeptideSpectralMatch.GetTabSeparatedHeader(); Assert.AreEqual(psm.ToString().Count(f => f == '\t'), PeptideSpectralMatch.GetTabSeparatedHeader().Count(f => f == '\t')); Assert.AreEqual(psm.ToString().Count(f => f == '\t'), PeptideSpectralMatch.GetTabSeparatedHeader().Count(f => f == '\t')); Tolerance fragmentTolerance = new PpmTolerance(10); new LocalizationEngine(new List <PeptideSpectralMatch> { psm }, myMsDataFile, new CommonParameters(productMassTolerance: fragmentTolerance), null, new List <string>()).Run(); Assert.AreEqual(psm.ToString().Count(f => f == '\t'), PeptideSpectralMatch.GetTabSeparatedHeader().Count(f => f == '\t')); psm.SetFdrValues(6, 6, 6, 6, 6, 0, 0, 0); Assert.AreEqual(psm.ToString().Count(f => f == '\t'), PeptideSpectralMatch.GetTabSeparatedHeader().Count(f => f == '\t')); }
public static void GlyTest_GlyGetTheoreticalFragments() { Protein pep = new Protein("TKPREEQYNSTYR", "accession"); DigestionParams digestionParams = new DigestionParams(minPeptideLength: 7); var aPeptideWithSetModifications = pep.Digest(digestionParams, new List <Modification>(), new List <Modification>()); string[] motifs = new string[] { "Nxs", "Nxt" }; var sites = GlycoSpectralMatch.GetPossibleModSites(aPeptideWithSetModifications.Last(), motifs); Glycan glycan = Glycan.Struct2Glycan("(N(F)(N(H(H(N))(H(N)))))", 0); //using (StreamWriter output = new StreamWriter(Path.Combine(TestContext.CurrentContext.TestDirectory, "GlycanFragmentions.txt"))) //{ // foreach (var product in fragmentIons) // { // foreach (var ion in product.Item2) // { // output.WriteLine(ion.Annotation + "\t" + ion.NeutralLoss.ToString() + "\t" + ion.NeutralMass.ToString()); // } // } //} CommonParameters commonParameters = new CommonParameters(deconvolutionMassTolerance: new PpmTolerance(20), trimMsMsPeaks: false); string filePath = Path.Combine(TestContext.CurrentContext.TestDirectory, @"GlycoTestData/Glyco_3383.mgf"); //"25170.mgf" MyFileManager myFileManager = new MyFileManager(true); var msDataFile = myFileManager.LoadFile(filePath, commonParameters); var listOfSortedms2Scans = MetaMorpheusTask.GetMs2Scans(msDataFile, filePath, commonParameters).ToArray(); var glycanMod = Glycan.NGlycanToModification(glycan); var glycopep = GlycoPeptides.GenerateGlycopeptide(sites[0], aPeptideWithSetModifications.Last(), glycan); List <Product> fragmentIons = new List <Product>(); glycopep.Fragment(DissociationType.HCD, FragmentationTerminus.Both, fragmentIons); var glycanYIons = GlycoPeptides.GetGlycanYIons(listOfSortedms2Scans[0].PrecursorMass, glycan); var matchedGlycanYIons = MetaMorpheusEngine.MatchFragmentIons(listOfSortedms2Scans[0], glycanYIons, commonParameters); Assert.AreEqual(matchedGlycanYIons.Count, 14); //TO DO: The neutroloss is not annotated well. var matchedFragmentIons = MetaMorpheusEngine.MatchFragmentIons(listOfSortedms2Scans[0], fragmentIons, commonParameters); var coreIons = GlycoPeptides.ScanGetTrimannosylCore(matchedFragmentIons, glycan); Assert.AreEqual(coreIons.Count, 6); var filter = GlycoPeptides.ScanTrimannosylCoreFilter(matchedFragmentIons, glycan); Assert.AreEqual(filter, true); var NGlycans = GlycanDatabase.LoadGlycan(GlobalVariables.NGlycanLocations[0], true, false); var bestGlycans = GlycoPeptides.MatchBestGlycan(listOfSortedms2Scans[0], NGlycans.ToArray(), commonParameters).Where(p => p != null && p.Item2 >= 2).OrderByDescending(p => p.Item2).Take(100).OrderBy(p => p.Item3).ToArray();; }
public static void SingleEventArgsTest() { Protein parentProteinForMatch = new Protein("MEK", null); CommonParameters commonParameters = new CommonParameters(digestionParams: new DigestionParams(minPeptideLength: 1)); var fsp = new List <(string fileName, CommonParameters fileSpecificParameters)>(); fsp.Add(("", commonParameters)); ModificationMotif.TryGetMotif("E", out ModificationMotif motif); List <Modification> variableModifications = new List <Modification> { new Modification(_originalId: "21", _target: motif, _locationRestriction: "Anywhere.", _monoisotopicMass: 21.981943) }; List <PeptideWithSetModifications> allPeptidesWithSetModifications = parentProteinForMatch.Digest(commonParameters.DigestionParams, new List <Modification>(), variableModifications).ToList(); Assert.AreEqual(4, allPeptidesWithSetModifications.Count()); PeptideWithSetModifications ps = allPeptidesWithSetModifications.First(); PeptideWithSetModifications pepWithSetModsForSpectrum = allPeptidesWithSetModifications[1]; MsDataFile myMsDataFile = new TestDataFile(new List <PeptideWithSetModifications> { pepWithSetModsForSpectrum }); Tolerance fragmentTolerance = new AbsoluteTolerance(0.01); Ms2ScanWithSpecificMass scan = new Ms2ScanWithSpecificMass(myMsDataFile.GetAllScansList().Last(), pepWithSetModsForSpectrum.MonoisotopicMass.ToMz(1), 1, null, new CommonParameters()); var theoreticalProducts = new List <Product>(); ps.Fragment(DissociationType.HCD, FragmentationTerminus.Both, theoreticalProducts); var matchedIons = MetaMorpheusEngine.MatchFragmentIons(scan, theoreticalProducts, new CommonParameters()); PeptideSpectralMatch newPsm = new PeptideSpectralMatch(ps, 0, 0, 2, scan, commonParameters, matchedIons); LocalizationEngine f = new LocalizationEngine(new List <PeptideSpectralMatch> { newPsm }, myMsDataFile, new CommonParameters(), fsp, new List <string>()); var singleEngine = new SingleEngineEventArgs(f); Assert.That(singleEngine.MyEngine.Equals(f)); var singleFile = new SingleFileEventArgs("", new List <string>()); Assert.That(singleFile.WrittenFile.Equals("")); var stringList = new StringListEventArgs(new List <string>()); var rr = (stringList.StringList.DefaultIfEmpty().First()); Assert.That(stringList.StringList.DefaultIfEmpty().First() == null); }
public static void TestLocalization() { Protein parentProteinForMatch = new Protein("MEK", null); CommonParameters commonParameters = new CommonParameters(digestionParams: new DigestionParams(minPeptideLength: 1)); var fsp = new List <(string fileName, CommonParameters fileSpecificParameters)>(); fsp.Add(("", commonParameters)); ModificationMotif.TryGetMotif("E", out ModificationMotif motif); List <Modification> variableModifications = new List <Modification> { new Modification(_originalId: "21", _target: motif, _locationRestriction: "Anywhere.", _monoisotopicMass: 21.981943) }; List <PeptideWithSetModifications> allPeptidesWithSetModifications = parentProteinForMatch.Digest(commonParameters.DigestionParams, new List <Modification>(), variableModifications).ToList(); Assert.AreEqual(4, allPeptidesWithSetModifications.Count()); PeptideWithSetModifications ps = allPeptidesWithSetModifications.First(); PeptideWithSetModifications pepWithSetModsForSpectrum = allPeptidesWithSetModifications[1]; MsDataFile myMsDataFile = new TestDataFile(new List <PeptideWithSetModifications> { pepWithSetModsForSpectrum }); Tolerance fragmentTolerance = new AbsoluteTolerance(0.01); Ms2ScanWithSpecificMass scan = new Ms2ScanWithSpecificMass(myMsDataFile.GetAllScansList().Last(), pepWithSetModsForSpectrum.MonoisotopicMass.ToMz(1), 1, null, new CommonParameters()); var theoreticalProducts = new List <Product>(); ps.Fragment(DissociationType.HCD, FragmentationTerminus.Both, theoreticalProducts); var matchedIons = MetaMorpheusEngine.MatchFragmentIons(scan, theoreticalProducts, new CommonParameters()); PeptideSpectralMatch newPsm = new PeptideSpectralMatch(ps, 0, 0, 2, scan, commonParameters, matchedIons); newPsm.ResolveAllAmbiguities(); LocalizationEngine f = new LocalizationEngine(new List <PeptideSpectralMatch> { newPsm }, myMsDataFile, commonParameters, fsp, new List <string>()); f.Run(); // single peak matches Assert.AreEqual(1, newPsm.MatchedFragmentIons.Where(p => p.NeutralTheoreticalProduct.ProductType == ProductType.b).Count());//including b1 now Assert.AreEqual(1, newPsm.MatchedFragmentIons.Where(p => p.NeutralTheoreticalProduct.ProductType == ProductType.y).Count()); // when localizing, three peaks match Assert.IsTrue(newPsm.LocalizedScores[1] > 4 && newPsm.LocalizedScores[1] < 5);//we have another matched ion }
public static void AddCompIonsMzOutput() { PeptideWithSetModifications pwsm = new PeptideWithSetModifications("ASDFASDF", null); Ms2ScanWithSpecificMass testScan = MetaMorpheusTask.GetMs2Scans(new TestDataFile(pwsm), null, new CommonParameters()).OrderBy(b => b.PrecursorMass).First(); CommonParameters cp = new CommonParameters(addCompIons: true); List <Product> theoreticalIons = new List <Product>(); pwsm.Fragment(cp.DissociationType, FragmentationTerminus.Both, theoreticalIons); List <MatchedFragmentIon> matchedIons = MetaMorpheusEngine.MatchFragmentIons(testScan, theoreticalIons, cp); //check that the matchedIons have m/z values that are similar to their neutral mass. //There was an "issue" where the saved m/z was the original experimental peak (which is the complementary of the added ion). //A fix was introduced to save a "fake" m/z for the added ion foreach (MatchedFragmentIon ion in matchedIons) { Assert.IsTrue(ion.NeutralTheoreticalProduct.NeutralMass < ion.Mz); Assert.IsTrue(ion.NeutralTheoreticalProduct.NeutralMass + 2 > ion.Mz); } }
public static Tuple <int, double, double>[] MatchBestGlycan(Ms2ScanWithSpecificMass theScan, Glycan[] glycans, CommonParameters commonParameters) { Tuple <int, double, double>[] tuples = new Tuple <int, double, double> [glycans.Length]; //Tuple<id, Yion matched score, glycan mass> //TO DO: Parallel this? for (int i = 0; i < glycans.Length; i++) { if (theScan.PrecursorMass - (double)glycans[i].Mass / 1E5 < 350) //Filter large glycans { continue; } List <Product> YIons = GetGlycanYIons(theScan.PrecursorMass, glycans[i]); List <MatchedFragmentIon> matchedFragmentIons = MetaMorpheusEngine.MatchFragmentIons(theScan, YIons, commonParameters); if (ScanTrimannosylCoreFilter(matchedFragmentIons, glycans[i])) { var score = MetaMorpheusEngine.CalculatePeptideScore(theScan.TheScan, matchedFragmentIons); tuples[i] = new Tuple <int, double, double>(i, score, (double)glycans[i].Mass / 1E5); } } return(tuples); }
public static void OGlycoTest_Localization2() { //There may have a bug that MM cannot identify Peptide modified with (HexNAc), This is to test and find the bug. //Get glycanBox var glycanBox = OGlycanBoxes[0]; //Get unmodified peptide, products, allPossible modPos and all boxes. Protein protein = new Protein("AATVGSLAGQPLQER", "P16150"); var peptide = protein.Digest(new DigestionParams(), new List <Modification>(), new List <Modification>()).First(); List <Product> products = new List <Product>(); peptide.Fragment(DissociationType.ETD, FragmentationTerminus.Both, products); int[] modPos = GlycoSpectralMatch.GetPossibleModSites(peptide, new string[] { "S", "T" }).OrderBy(p => p).ToArray(); var boxes = GlycanBox.BuildChildOGlycanBoxes(glycanBox.NumberOfMods, glycanBox.ModIds).ToArray(); //Load scan. CommonParameters commonParameters = new CommonParameters(dissociationType: DissociationType.ETD, trimMsMsPeaks: false); string spectraFile = Path.Combine(TestContext.CurrentContext.TestDirectory, @"GlycoTestData\181217_Fusion_(LC2)_NewObj_Serum_deSA_Jacalin_HRM_4h_ETD_HCD_DDA_mz(400_1200)_21707.mgf"); var file = new MyFileManager(true).LoadFile(spectraFile, commonParameters); var scans = MetaMorpheusTask.GetMs2Scans(file, spectraFile, commonParameters).ToArray(); //Known peptideWithMod match. var peptideWithMod = GlycoPeptides.OGlyGetTheoreticalPeptide(new int[1] { 4 }, peptide, glycanBox); Assert.That(peptideWithMod.FullSequence == "AAT[O-Glycosylation:N1 on X]VGSLAGQPLQER"); //List<Product> knownProducts = peptideWithMod.Fragment(DissociationType.EThcD, FragmentationTerminus.Both).ToList(); List <Product> knownProducts = GlycoPeptides.OGlyGetTheoreticalFragments(DissociationType.ETD, peptide, peptideWithMod); var matchedKnownFragmentIons = MetaMorpheusEngine.MatchFragmentIons(scans.First(), knownProducts, commonParameters); //Get hashset int int obsPreviousFragmentCeilingMz = 0; List <int> binsToSearch = new List <int>(); foreach (var envelope in scans.First().ExperimentalFragments) { // assume charge state 1 to calculate mass tolerance double experimentalFragmentMass = envelope.MonoisotopicMass; // get theoretical fragment bins within mass tolerance int obsFragmentFloorMass = (int)Math.Floor((commonParameters.ProductMassTolerance.GetMinimumValue(experimentalFragmentMass)) * 1000); int obsFragmentCeilingMass = (int)Math.Ceiling((commonParameters.ProductMassTolerance.GetMaximumValue(experimentalFragmentMass)) * 1000); // prevents double-counting peaks close in m/z and lower-bound out of range exceptions if (obsFragmentFloorMass < obsPreviousFragmentCeilingMz) { obsFragmentFloorMass = obsPreviousFragmentCeilingMz; } obsPreviousFragmentCeilingMz = obsFragmentCeilingMass + 1; // search mass bins within a tolerance for (int fragmentBin = obsFragmentFloorMass; fragmentBin <= obsFragmentCeilingMass; fragmentBin++) { binsToSearch.Add(fragmentBin); } } HashSet <int> allPeaks = new HashSet <int>(binsToSearch); //Graph Localization LocalizationGraph localizationGraph = new LocalizationGraph(modPos, glycanBox, boxes, -1); LocalizationGraph.LocalizeOGlycan(localizationGraph, scans.First(), commonParameters.ProductMassTolerance, products); var allPaths = LocalizationGraph.GetAllHighestScorePaths(localizationGraph.array, localizationGraph.ChildModBoxes); var knowPath = new int[2] { 1, 1 }; Assert.That(Enumerable.SequenceEqual(knowPath, allPaths[0])); var local = LocalizationGraph.GetLocalizedPath(localizationGraph, allPaths.First()); Assert.That(Enumerable.SequenceEqual(local.Mods.Select(p => p.Item1), new List <int> { 4 })); Assert.That(Enumerable.SequenceEqual(local.Mods.Select(p => p.Item2), new List <int> { 0 })); }
public static void OGlycoTest_Localization() { //Get glycanBox var glycanBox = OGlycanBoxes[19]; //Get unmodified peptide, products, allPossible modPos and all boxes. Protein protein = new Protein("TTGSLEPSSGASGPQVSSVK", "P16150"); var peptide = protein.Digest(new DigestionParams(), new List <Modification>(), new List <Modification>()).First(); List <Product> products = new List <Product>(); peptide.Fragment(DissociationType.ETD, FragmentationTerminus.Both, products); int[] modPos = GlycoSpectralMatch.GetPossibleModSites(peptide, new string[] { "S", "T" }).OrderBy(v => v).ToArray(); var boxes = GlycanBox.BuildChildOGlycanBoxes(3, glycanBox.ModIds).ToArray(); Assert.That(boxes.Count() == 6); //Get Unlocal Fragment var unlocalCost = GlycoPeptides.GetUnlocalFragment(products, modPos, glycanBox); Assert.That(unlocalCost.Count == 4); //Basicly, the unlocal are c/z ions that don't localize glycosylation. //Get scan CommonParameters commonParameters = new CommonParameters(dissociationType: DissociationType.EThcD, trimMsMsPeaks: false); string spectraFile = Path.Combine(TestContext.CurrentContext.TestDirectory, @"GlycoTestData\2019_09_16_StcEmix_35trig_EThcD25_rep1_4565.mgf"); var file = new MyFileManager(true).LoadFile(spectraFile, commonParameters); var scans = MetaMorpheusTask.GetMs2Scans(file, spectraFile, commonParameters).ToArray(); //Known peptideWithMod match. var peptideWithMod = GlycoPeptides.OGlyGetTheoreticalPeptide(new int[3] { 10, 2, 3 }, peptide, glycanBox); Assert.That(peptideWithMod.FullSequence == "T[O-Glycosylation:H1N1 on X]T[O-Glycosylation:H1N1 on X]GSLEPSS[O-Glycosylation:N1 on X]GASGPQVSSVK"); List <Product> knownProducts = GlycoPeptides.OGlyGetTheoreticalFragments(DissociationType.EThcD, peptide, peptideWithMod); var matchedKnownFragmentIons = MetaMorpheusEngine.MatchFragmentIons(scans.First(), knownProducts, commonParameters); //Graph Localization LocalizationGraph localizationGraph = new LocalizationGraph(modPos, glycanBox, boxes, -1); LocalizationGraph.LocalizeOGlycan(localizationGraph, scans.First(), commonParameters.ProductMassTolerance, products); var allPaths = LocalizationGraph.GetAllHighestScorePaths(localizationGraph.array, localizationGraph.ChildModBoxes); var knowPath = new int[8] { 2, 4, 4, 4, 5, 5, 5, 5 }; Assert.That(Enumerable.SequenceEqual(knowPath, allPaths[0])); //Get localized Route var local = LocalizationGraph.GetLocalizedPath(localizationGraph, allPaths.First()); Assert.That(Enumerable.SequenceEqual(local.Mods.Select(v => v.Item1), new List <int> { 2, 3, 10 })); Assert.That(Enumerable.SequenceEqual(local.Mods.Select(v => v.Item2), new List <int> { 1, 1, 0 })); //Get all paths, calculate PScore and calculate position probability. var p = scans.First().TheScan.MassSpectrum.Size *commonParameters.ProductMassTolerance.GetRange(1000).Width / scans.First().TheScan.MassSpectrum.Range.Width; var n = knownProducts.Where(v => v.ProductType == ProductType.c || v.ProductType == ProductType.zDot).Count(); var allPathWithWeights = LocalizationGraph.GetAllPaths_CalP(localizationGraph, p, n); Assert.That(allPathWithWeights.Count == 168); //Calculate Site Specific Localization Probability var y = LocalizationGraph.CalSiteSpecificLocalizationProbability(allPathWithWeights, localizationGraph.ModPos); Assert.That(y.Count == 8); Assert.That(y.First().Value[1].Item2 > 0.99); }
public static void MatchInternalFragmentIons(PeptideSpectralMatch[] fileSpecificPsms, Ms2ScanWithSpecificMass[] arrayOfMs2ScansSortedByMass, CommonParameters combinedParams, int minInternalFragmentLength) { //for each PSM with an ID for (int index = 0; index < fileSpecificPsms.Length; index++) { PeptideSpectralMatch psm = fileSpecificPsms[index]; if (psm != null && psm.BestMatchingPeptides.Count() > 0) { //Get the scan Ms2ScanWithSpecificMass scanForThisPsm = arrayOfMs2ScansSortedByMass[index]; DissociationType dissociationType = combinedParams.DissociationType == DissociationType.Autodetect ? scanForThisPsm.TheScan.DissociationType.Value : combinedParams.DissociationType; //Get the theoretical peptides List <PeptideWithSetModifications> ambiguousPeptides = new List <PeptideWithSetModifications>(); List <int> notches = new List <int>(); foreach (var(Notch, Peptide) in psm.BestMatchingPeptides) { ambiguousPeptides.Add(Peptide); notches.Add(Notch); } //get matched ions for each peptide List <List <MatchedFragmentIon> > matchedIonsForAllAmbiguousPeptides = new List <List <MatchedFragmentIon> >(); List <Product> internalFragments = new List <Product>(); foreach (PeptideWithSetModifications peptide in ambiguousPeptides) { internalFragments.Clear(); peptide.FragmentInternally(combinedParams.DissociationType, minInternalFragmentLength, internalFragments); //TODO: currently, internal and terminal ions can match to the same observed peaks (much like how b- and y-ions can match to the same peaks). Investigate if we should change that... matchedIonsForAllAmbiguousPeptides.Add(MetaMorpheusEngine.MatchFragmentIons(scanForThisPsm, internalFragments, combinedParams)); } //Find the max number of matched ions int maxNumMatchedIons = matchedIonsForAllAmbiguousPeptides.Max(x => x.Count); //remove peptides if they have fewer than max-1 matched ions, thus requiring at least two internal ions to disambiguate an ID //if not removed, then add the matched internal ions HashSet <PeptideWithSetModifications> PeptidesToMatchingInternalFragments = new HashSet <PeptideWithSetModifications>(); for (int peptideIndex = 0; peptideIndex < ambiguousPeptides.Count; peptideIndex++) { //if we should remove the theoretical, remove it if (matchedIonsForAllAmbiguousPeptides[peptideIndex].Count + 1 < maxNumMatchedIons) { psm.RemoveThisAmbiguousPeptide(notches[peptideIndex], ambiguousPeptides[peptideIndex]); } // otherwise add the matched internal ions to the total ions else { PeptideWithSetModifications currentPwsm = ambiguousPeptides[peptideIndex]; //check that we haven't already added the matched ions for this peptide if (!PeptidesToMatchingInternalFragments.Contains(currentPwsm)) { PeptidesToMatchingInternalFragments.Add(currentPwsm); //record that we've seen this peptide psm.PeptidesToMatchingFragments[currentPwsm].AddRange(matchedIonsForAllAmbiguousPeptides[peptideIndex]); //add the matched ions } } } } } }