private List <MatchedFragmentIon> ScoreChildScan(Ms2ScanWithSpecificMass parentScan, Ms2ScanWithSpecificMass childScan, int possibleSite, BestPeptideScoreNotch mainPeptide, BestPeptideScoreNotch otherPeptide) { bool shortMassAlphaMs3 = XLPrecusorSearchMode.Accepts(childScan.PrecursorMass, mainPeptide.BestPeptide.MonoisotopicMass + Crosslinker.CleaveMassShort) >= 0; bool longMassAlphaMs3 = XLPrecusorSearchMode.Accepts(childScan.PrecursorMass, mainPeptide.BestPeptide.MonoisotopicMass + Crosslinker.CleaveMassLong) >= 0; List <Product> childProducts; if (Crosslinker.Cleavable && (shortMassAlphaMs3 || longMassAlphaMs3)) { double massToLocalize = shortMassAlphaMs3 ? Crosslinker.CleaveMassShort : Crosslinker.CleaveMassLong; if (mainPeptide.BestPeptide.AllModsOneIsNterminus.TryGetValue(possibleSite + 1, out var existingMod)) { massToLocalize += existingMod.MonoisotopicMass.Value; } Dictionary <int, Modification> mod = new Dictionary <int, Modification> { { possibleSite + 1, new Modification(_monoisotopicMass: massToLocalize) } }; foreach (var otherExistingMod in mainPeptide.BestPeptide.AllModsOneIsNterminus.Where(p => p.Key != possibleSite + 1)) { mod.Add(otherExistingMod.Key, otherExistingMod.Value); } var peptideWithMod = new PeptideWithSetModifications(mainPeptide.BestPeptide.Protein, mainPeptide.BestPeptide.DigestionParams, mainPeptide.BestPeptide.OneBasedStartResidueInProtein, mainPeptide.BestPeptide.OneBasedEndResidueInProtein, mainPeptide.BestPeptide.CleavageSpecificityForFdrCategory, mainPeptide.BestPeptide.PeptideDescription, mainPeptide.BestPeptide.MissedCleavages, mod, mainPeptide.BestPeptide.NumFixedMods); childProducts = peptideWithMod.Fragment(CommonParameters.ChildScanDissociationType, FragmentationTerminus.Both).ToList(); } else if (Math.Abs(childScan.PrecursorMass - parentScan.PrecursorMass) < 0.01 && CommonParameters.DissociationType != CommonParameters.ChildScanDissociationType) { // same species got fragmented twice, the second time with a different dissociation type childProducts = CrosslinkedPeptide.XlGetTheoreticalFragments(CommonParameters.ChildScanDissociationType, Crosslinker, new List <int> { possibleSite }, otherPeptide.BestPeptide.MonoisotopicMass, mainPeptide.BestPeptide).First().Item2; } else { return(null); } var matchedChildIons = MatchFragmentIons(childScan, childProducts, CommonParameters); return(matchedChildIons); }
/// <summary> /// Localizes the loop to a begin and end residue /// </summary> private CrosslinkSpectralMatch LocalizeLoopSites(PeptideWithSetModifications originalPeptide, Ms2ScanWithSpecificMass theScan, CommonParameters commonParameters, List <int> possiblePositions, Modification loopMod, int notch, int scanIndex, int peptideIndex) { var possibleFragmentSets = CrosslinkedPeptide.XlLoopGetTheoreticalFragments(commonParameters.DissociationType, Loop, possiblePositions, originalPeptide); double bestScore = 0; Tuple <int, int> bestModPositionSites = null; List <MatchedFragmentIon> bestMatchingFragments = new List <MatchedFragmentIon>(); foreach (var setOfPositions in possibleFragmentSets) { var matchedFragmentIons = MatchFragmentIons(theScan, setOfPositions.Value, commonParameters); double score = CalculatePeptideScore(theScan.TheScan, matchedFragmentIons); if (score > bestScore) { bestMatchingFragments = matchedFragmentIons; bestScore = score; bestModPositionSites = setOfPositions.Key; } } if (bestScore < commonParameters.ScoreCutoff) { return(null); } var csm = new CrosslinkSpectralMatch(originalPeptide, notch, bestScore, scanIndex, theScan, originalPeptide.DigestionParams, bestMatchingFragments) { CrossType = PsmCrossType.Loop, XlRank = new List <int> { peptideIndex }, LinkPositions = new List <int> { bestModPositionSites.Item1, bestModPositionSites.Item2 } }; return(csm); }
/// <summary> /// Localizes the crosslink position on the alpha and beta peptides /// </summary> private CrosslinkSpectralMatch LocalizeCrosslinkSites(Ms2ScanWithSpecificMass theScan, BestPeptideScoreNotch alphaPeptide, BestPeptideScoreNotch betaPeptide, Crosslinker crosslinker, int ind, int inx) { CrosslinkSpectralMatch localizedCrosslinkedSpectralMatch = null; List <Tuple <List <int>, List <int> > > pairs = new List <Tuple <List <int>, List <int> > >(); if (crosslinker.CrosslinkerModSites.Equals(crosslinker.CrosslinkerModSites2)) { List <int> possibleAlphaXlSites = CrosslinkSpectralMatch.GetPossibleCrosslinkerModSites(crosslinker.CrosslinkerModSites.ToCharArray(), alphaPeptide.BestPeptide); List <int> possibleBetaXlSites = CrosslinkSpectralMatch.GetPossibleCrosslinkerModSites(crosslinker.CrosslinkerModSites.ToCharArray(), betaPeptide.BestPeptide); pairs.Add(new Tuple <List <int>, List <int> >(possibleAlphaXlSites, possibleBetaXlSites)); } else { List <int> possibleAlphaXlSites = CrosslinkSpectralMatch.GetPossibleCrosslinkerModSites(crosslinker.CrosslinkerModSites.ToCharArray(), alphaPeptide.BestPeptide); List <int> possibleBetaXlSites = CrosslinkSpectralMatch.GetPossibleCrosslinkerModSites(crosslinker.CrosslinkerModSites2.ToCharArray(), betaPeptide.BestPeptide); pairs.Add(new Tuple <List <int>, List <int> >(possibleAlphaXlSites, possibleBetaXlSites)); possibleAlphaXlSites = CrosslinkSpectralMatch.GetPossibleCrosslinkerModSites(crosslinker.CrosslinkerModSites2.ToCharArray(), alphaPeptide.BestPeptide); possibleBetaXlSites = CrosslinkSpectralMatch.GetPossibleCrosslinkerModSites(crosslinker.CrosslinkerModSites.ToCharArray(), betaPeptide.BestPeptide); pairs.Add(new Tuple <List <int>, List <int> >(possibleAlphaXlSites, possibleBetaXlSites)); } foreach (var pair in pairs) { List <int> possibleAlphaXlSites = pair.Item1; List <int> possibleBetaXlSites = pair.Item2; if (possibleAlphaXlSites.Any() && possibleBetaXlSites.Any()) { int bestAlphaSite = 0; int bestBetaSite = 0; List <MatchedFragmentIon> bestMatchedAlphaIons = new List <MatchedFragmentIon>(); List <MatchedFragmentIon> bestMatchedBetaIons = new List <MatchedFragmentIon>(); Dictionary <int, List <MatchedFragmentIon> > bestMatchedChildAlphaIons = new Dictionary <int, List <MatchedFragmentIon> >(); Dictionary <int, List <MatchedFragmentIon> > bestMatchedChildBetaIons = new Dictionary <int, List <MatchedFragmentIon> >(); double bestAlphaLocalizedScore = 0; double bestBetaLocalizedScore = 0; var fragmentsForEachAlphaLocalizedPossibility = CrosslinkedPeptide.XlGetTheoreticalFragments(CommonParameters.DissociationType, Crosslinker, possibleAlphaXlSites, betaPeptide.BestPeptide.MonoisotopicMass, alphaPeptide.BestPeptide).ToList(); foreach (int possibleSite in possibleAlphaXlSites) { foreach (var setOfFragments in fragmentsForEachAlphaLocalizedPossibility.Where(v => v.Item1 == possibleSite)) { var matchedChildAlphaIons = new Dictionary <int, List <MatchedFragmentIon> >(); var matchedIons = MatchFragmentIons(theScan, setOfFragments.Item2, CommonParameters); double score = CalculatePeptideScore(theScan.TheScan, matchedIons); // search child scans (MS2+MS3) foreach (Ms2ScanWithSpecificMass childScan in theScan.ChildScans) { var matchedChildIons = ScoreChildScan(theScan, childScan, possibleSite, alphaPeptide, betaPeptide); if (matchedChildIons == null) { continue; } matchedChildAlphaIons.Add(childScan.OneBasedScanNumber, matchedChildIons); //double childScore = CalculatePeptideScore(childScan.TheScan, matchedChildIons); //score += childScore; } if (score > bestAlphaLocalizedScore) { bestAlphaLocalizedScore = score; bestAlphaSite = possibleSite; bestMatchedAlphaIons = matchedIons; bestMatchedChildAlphaIons = matchedChildAlphaIons; } } } var fragmentsForEachBetaLocalizedPossibility = CrosslinkedPeptide.XlGetTheoreticalFragments(CommonParameters.DissociationType, Crosslinker, possibleBetaXlSites, alphaPeptide.BestPeptide.MonoisotopicMass, betaPeptide.BestPeptide).ToList(); var alphaMz = new HashSet <double>(bestMatchedAlphaIons.Select(p => p.Mz)); foreach (int possibleSite in possibleBetaXlSites) { foreach (var setOfFragments in fragmentsForEachBetaLocalizedPossibility.Where(v => v.Item1 == possibleSite)) { var matchedIons = MatchFragmentIons(theScan, setOfFragments.Item2, CommonParameters); var matchedChildBetaIons = new Dictionary <int, List <MatchedFragmentIon> >(); // remove any matched beta ions that also matched to the alpha peptide matchedIons.RemoveAll(p => alphaMz.Contains(p.Mz)); double score = CalculatePeptideScore(theScan.TheScan, matchedIons); // search child scans (MS2+MS3) foreach (Ms2ScanWithSpecificMass childScan in theScan.ChildScans) { var matchedChildIons = ScoreChildScan(theScan, childScan, possibleSite, betaPeptide, alphaPeptide); if (matchedChildIons == null) { continue; } matchedChildBetaIons.Add(childScan.OneBasedScanNumber, matchedChildIons); //double childScore = CalculatePeptideScore(childScan.TheScan, matchedChildIons); //score += childScore; } if (score > bestBetaLocalizedScore) { bestBetaLocalizedScore = score; bestBetaSite = possibleSite; bestMatchedBetaIons = matchedIons; bestMatchedChildBetaIons = matchedChildBetaIons; } } } if (bestAlphaLocalizedScore < CommonParameters.ScoreCutoff || bestBetaLocalizedScore < CommonParameters.ScoreCutoff) { return(null); } var localizedAlpha = new CrosslinkSpectralMatch(alphaPeptide.BestPeptide, alphaPeptide.BestNotch, bestAlphaLocalizedScore, 0, theScan, alphaPeptide.BestPeptide.DigestionParams, bestMatchedAlphaIons); var localizedBeta = new CrosslinkSpectralMatch(betaPeptide.BestPeptide, betaPeptide.BestNotch, bestBetaLocalizedScore, 0, theScan, betaPeptide.BestPeptide.DigestionParams, bestMatchedBetaIons); localizedAlpha.XlRank = new List <int> { ind, inx }; localizedAlpha.XLTotalScore = localizedAlpha.Score + localizedBeta.Score; localizedAlpha.BetaPeptide = localizedBeta; localizedAlpha.ChildMatchedFragmentIons = bestMatchedChildAlphaIons; localizedBeta.ChildMatchedFragmentIons = bestMatchedChildBetaIons; if (crosslinker.Cleavable) { //TODO: re-enable intensity ranks //psmCrossAlpha.ParentIonMaxIntensityRanks = psmCrossAlpha.MatchedFragmentIons.Where(p => p.NeutralTheoreticalProduct.ProductType == ProductType.M).Select(p => p.IntensityRank).ToList(); //localizedAlpha.ParentIonMaxIntensityRanks = new List<int>(); //localizedAlpha.ParentIonExistNum = psmCrossAlpha.ParentIonMaxIntensityRanks.Count; } localizedAlpha.CrossType = PsmCrossType.Cross; localizedCrosslinkedSpectralMatch = localizedAlpha; localizedCrosslinkedSpectralMatch.LinkPositions = new List <int> { bestAlphaSite }; localizedCrosslinkedSpectralMatch.BetaPeptide.LinkPositions = new List <int> { bestBetaSite }; } } return(localizedCrosslinkedSpectralMatch); }