/// <summary> /// /// </summary> private CrosslinkSpectralMatch FindCrosslinkedPeptide(Ms2ScanWithSpecificMass theScan, List <BestPeptideScoreNotch> theScanBestPeptide, int scanIndex) { List <CrosslinkSpectralMatch> possibleMatches = new List <CrosslinkSpectralMatch>(); for (int alphaIndex = 0; alphaIndex < theScanBestPeptide.Count; alphaIndex++) { PeptideWithSetModifications bestPeptide = theScanBestPeptide[alphaIndex].BestPeptide; //Single Peptide if (XLPrecusorSearchMode.Accepts(theScan.PrecursorMass, bestPeptide.MonoisotopicMass) >= 0) { List <Product> products = bestPeptide.Fragment(CommonParameters.DissociationType, FragmentationTerminus.Both).ToList(); var matchedFragmentIons = MatchFragmentIons(theScan, products, CommonParameters); double score = CalculatePeptideScore(theScan.TheScan, matchedFragmentIons); var psmCrossSingle = new CrosslinkSpectralMatch(bestPeptide, theScanBestPeptide[alphaIndex].BestNotch, score, scanIndex, theScan, CommonParameters.DigestionParams, matchedFragmentIons) { CrossType = PsmCrossType.Single, XlRank = new List <int> { alphaIndex } }; possibleMatches.Add(psmCrossSingle); } // Deadend Peptide else if (QuenchTris && XLPrecusorSearchMode.Accepts(theScan.PrecursorMass, bestPeptide.MonoisotopicMass + Crosslinker.DeadendMassTris) >= 0) { List <int> possibleCrosslinkLocations = CrosslinkSpectralMatch.GetPossibleCrosslinkerModSites(AllCrosslinkerSites, bestPeptide); if (possibleCrosslinkLocations.Any()) { // tris deadend possibleMatches.Add(LocalizeDeadEndSite(bestPeptide, theScan, CommonParameters, possibleCrosslinkLocations, TrisDeadEnd, theScanBestPeptide[alphaIndex].BestNotch, scanIndex, alphaIndex)); } } else if (QuenchH2O && XLPrecusorSearchMode.Accepts(theScan.PrecursorMass, bestPeptide.MonoisotopicMass + Crosslinker.DeadendMassH2O) >= 0) { List <int> possibleCrosslinkLocations = CrosslinkSpectralMatch.GetPossibleCrosslinkerModSites(AllCrosslinkerSites, bestPeptide); if (possibleCrosslinkLocations.Any()) { // H2O deadend possibleMatches.Add(LocalizeDeadEndSite(bestPeptide, theScan, CommonParameters, possibleCrosslinkLocations, H2ODeadEnd, theScanBestPeptide[alphaIndex].BestNotch, scanIndex, alphaIndex)); } } else if (QuenchNH2 && XLPrecusorSearchMode.Accepts(theScan.PrecursorMass, bestPeptide.MonoisotopicMass + Crosslinker.DeadendMassNH2) >= 0) { List <int> possibleCrosslinkLocations = CrosslinkSpectralMatch.GetPossibleCrosslinkerModSites(AllCrosslinkerSites, bestPeptide); if (possibleCrosslinkLocations.Any()) { // NH2 deadend possibleMatches.Add(LocalizeDeadEndSite(bestPeptide, theScan, CommonParameters, possibleCrosslinkLocations, NH2DeadEnd, theScanBestPeptide[alphaIndex].BestNotch, scanIndex, alphaIndex)); } } // loop peptide else if (Crosslinker.LoopMass != 0 && XLPrecusorSearchMode.Accepts(theScan.PrecursorMass, bestPeptide.MonoisotopicMass + Crosslinker.LoopMass) >= 0) { List <int> possibleCrosslinkLocations = CrosslinkSpectralMatch.GetPossibleCrosslinkerModSites(AllCrosslinkerSites, bestPeptide); if (possibleCrosslinkLocations.Count >= 2) { possibleMatches.Add(LocalizeLoopSites(bestPeptide, theScan, CommonParameters, possibleCrosslinkLocations, Loop, theScanBestPeptide[alphaIndex].BestNotch, scanIndex, alphaIndex)); } } // Cross-linked peptide else if (theScan.PrecursorMass - bestPeptide.MonoisotopicMass >= (CommonParameters.DigestionParams.MinPeptideLength * 50)) { List <int> possibleCrosslinkLocations = CrosslinkSpectralMatch.GetPossibleCrosslinkerModSites(AllCrosslinkerSites, bestPeptide); if (!possibleCrosslinkLocations.Any()) { continue; } PeptideWithSetModifications alphaPeptide = bestPeptide; for (int betaIndex = 0; betaIndex < theScanBestPeptide.Count; betaIndex++) { PeptideWithSetModifications betaPeptide = theScanBestPeptide[betaIndex].BestPeptide; if (XLPrecusorSearchMode.Accepts(theScan.PrecursorMass, alphaPeptide.MonoisotopicMass + betaPeptide.MonoisotopicMass + Crosslinker.TotalMass) >= 0) { List <int> possibleBetaCrosslinkSites = CrosslinkSpectralMatch.GetPossibleCrosslinkerModSites(AllCrosslinkerSites, betaPeptide); if (!possibleBetaCrosslinkSites.Any()) { continue; } CrosslinkSpectralMatch csm = LocalizeCrosslinkSites(theScan, theScanBestPeptide[alphaIndex], theScanBestPeptide[betaIndex], Crosslinker, alphaIndex, betaIndex); possibleMatches.Add(csm); } } } } // get the best match for this spectrum // bestPsmCross will be null if there are no valid hits possibleMatches.RemoveAll(v => v == null); possibleMatches = possibleMatches.OrderByDescending(p => p.XLTotalScore).ToList(); var bestPsmCross = possibleMatches.FirstOrDefault(); // resolve ambiguities if (bestPsmCross != null) { bestPsmCross.ResolveAllAmbiguities(); if (bestPsmCross.BetaPeptide != null) { bestPsmCross.BetaPeptide.ResolveAllAmbiguities(); } } // calculate delta score if (possibleMatches.Count > 1) { bestPsmCross.DeltaScore = possibleMatches[0].XLTotalScore - possibleMatches[1].XLTotalScore; } return(bestPsmCross); }
/// <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); }
/// <summary> /// /// </summary> private List <CrosslinkSpectralMatch> FindCrosslinkedPeptide(Ms2ScanWithSpecificMass theScan, List <BestPeptideScoreNotch> theScanBestPeptide, int scanIndex) { List <CrosslinkSpectralMatch> possibleMatches = new List <CrosslinkSpectralMatch>(); for (int alphaIndex = 0; alphaIndex < theScanBestPeptide.Count; alphaIndex++) { PeptideWithSetModifications bestPeptide = theScanBestPeptide[alphaIndex].BestPeptide; //Single Peptide if (XLPrecusorSearchMode.Accepts(theScan.PrecursorMass, bestPeptide.MonoisotopicMass) >= 0) { List <Product> products = bestPeptide.Fragment(CommonParameters.DissociationType, FragmentationTerminus.Both).ToList(); var matchedFragmentIons = MatchFragmentIons(theScan, products, CommonParameters); double score = CalculatePeptideScore(theScan.TheScan, matchedFragmentIons); var psmCrossSingle = new CrosslinkSpectralMatch(bestPeptide, theScanBestPeptide[alphaIndex].BestNotch, score, scanIndex, theScan, CommonParameters.DigestionParams, matchedFragmentIons) { CrossType = PsmCrossType.Single, XlRank = new List <int> { alphaIndex } }; possibleMatches.Add(psmCrossSingle); } // Deadend Peptide else if (QuenchTris && XLPrecusorSearchMode.Accepts(theScan.PrecursorMass, bestPeptide.MonoisotopicMass + Crosslinker.DeadendMassTris) >= 0) { List <int> possibleCrosslinkLocations = CrosslinkSpectralMatch.GetPossibleCrosslinkerModSites(AllCrosslinkerSites, bestPeptide); if (possibleCrosslinkLocations.Any()) { // tris deadend possibleMatches.Add(LocalizeDeadEndSite(bestPeptide, theScan, CommonParameters, possibleCrosslinkLocations, TrisDeadEnd, theScanBestPeptide[alphaIndex].BestNotch, scanIndex, alphaIndex)); } } else if (QuenchH2O && XLPrecusorSearchMode.Accepts(theScan.PrecursorMass, bestPeptide.MonoisotopicMass + Crosslinker.DeadendMassH2O) >= 0) { List <int> possibleCrosslinkLocations = CrosslinkSpectralMatch.GetPossibleCrosslinkerModSites(AllCrosslinkerSites, bestPeptide); if (possibleCrosslinkLocations.Any()) { // H2O deadend possibleMatches.Add(LocalizeDeadEndSite(bestPeptide, theScan, CommonParameters, possibleCrosslinkLocations, H2ODeadEnd, theScanBestPeptide[alphaIndex].BestNotch, scanIndex, alphaIndex)); } } else if (QuenchNH2 && XLPrecusorSearchMode.Accepts(theScan.PrecursorMass, bestPeptide.MonoisotopicMass + Crosslinker.DeadendMassNH2) >= 0) { List <int> possibleCrosslinkLocations = CrosslinkSpectralMatch.GetPossibleCrosslinkerModSites(AllCrosslinkerSites, bestPeptide); if (possibleCrosslinkLocations.Any()) { // NH2 deadend possibleMatches.Add(LocalizeDeadEndSite(bestPeptide, theScan, CommonParameters, possibleCrosslinkLocations, NH2DeadEnd, theScanBestPeptide[alphaIndex].BestNotch, scanIndex, alphaIndex)); } } // loop peptide else if (Crosslinker.LoopMass != 0 && XLPrecusorSearchMode.Accepts(theScan.PrecursorMass, bestPeptide.MonoisotopicMass + Crosslinker.LoopMass) >= 0) { List <int> possibleCrosslinkLocations = CrosslinkSpectralMatch.GetPossibleCrosslinkerModSites(AllCrosslinkerSites, bestPeptide); if (possibleCrosslinkLocations.Count >= 2) { possibleMatches.Add(LocalizeLoopSites(bestPeptide, theScan, CommonParameters, possibleCrosslinkLocations, Loop, theScanBestPeptide[alphaIndex].BestNotch, scanIndex, alphaIndex)); } } // Cross-linked peptide else if (theScan.PrecursorMass - bestPeptide.MonoisotopicMass >= (CommonParameters.DigestionParams.MinPeptideLength * 50)) { List <int> possibleCrosslinkLocations = CrosslinkSpectralMatch.GetPossibleCrosslinkerModSites(AllCrosslinkerSites, bestPeptide); if (!possibleCrosslinkLocations.Any()) { continue; } PeptideWithSetModifications alphaPeptide = bestPeptide; for (int betaIndex = 0; betaIndex < theScanBestPeptide.Count; betaIndex++) { PeptideWithSetModifications betaPeptide = theScanBestPeptide[betaIndex].BestPeptide; if (XLPrecusorSearchMode.Accepts(theScan.PrecursorMass, alphaPeptide.MonoisotopicMass + betaPeptide.MonoisotopicMass + Crosslinker.TotalMass) >= 0) { List <int> possibleBetaCrosslinkSites = CrosslinkSpectralMatch.GetPossibleCrosslinkerModSites(AllCrosslinkerSites, betaPeptide); if (!possibleBetaCrosslinkSites.Any()) { continue; } CrosslinkSpectralMatch csm = LocalizeCrosslinkSites(theScan, theScanBestPeptide[alphaIndex], theScanBestPeptide[betaIndex], Crosslinker, alphaIndex, betaIndex); possibleMatches.Add(csm); } } } } return(possibleMatches); }