public static bool IsIntraCsm(CrosslinkSpectralMatch csm) { //The pair "ProteinA and Decoy_ProteinA" is count for intra-crosslink. if (csm.ProteinAccession != null && csm.BetaPeptide.ProteinAccession != null) { if (csm.ProteinAccession == csm.BetaPeptide.ProteinAccession || csm.ProteinAccession == "DECOY_" + csm.BetaPeptide.ProteinAccession || csm.BetaPeptide.ProteinAccession == "DECOY_" + csm.ProteinAccession) { return(true); } } if (csm.ProteinAccession == null) { var alphaProteins = csm.BestMatchingPeptides.Select(p => p.Peptide.Protein.Accession).ToList(); var betaProteins = csm.BetaPeptide.BestMatchingPeptides.Select(p => p.Peptide.Protein.Accession).ToList(); foreach (var alpha in alphaProteins) { foreach (var beta in betaProteins) { if (alpha == beta || alpha == "DECOY_" + beta || beta == "DECOY_" + alpha) { return(true); } } } } return(false); }
/// <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); }
public static void ResolveProteinPosAmbiguitiesForXl(CrosslinkSpectralMatch csm) { csm.ResolveAllAmbiguities(); if (csm.BetaPeptide != null) { csm.BetaPeptide.ResolveAllAmbiguities(); } //Assign PsmCrossType.Cross to Intra or Inter. if (csm.CrossType == PsmCrossType.Cross) { if (IsIntraCsm(csm)) { csm.CrossType = PsmCrossType.Intra; } else { csm.CrossType = PsmCrossType.Inter; } } if (csm.CrossType == PsmCrossType.Cross || csm.CrossType == PsmCrossType.Intra || csm.CrossType == PsmCrossType.Inter) { // alpha peptide crosslink residue in the protein csm.XlProteinPos = csm.OneBasedStartResidueInProtein == null ? (int?)null : csm.OneBasedStartResidueInProtein.Value + csm.LinkPositions[0] - 1; // beta crosslink residue in protein csm.BetaPeptide.XlProteinPos = csm.BetaPeptide.OneBasedStartResidueInProtein == null ? (int?)null : csm.BetaPeptide.OneBasedStartResidueInProtein.Value + csm.BetaPeptide.LinkPositions[0] - 1; } else if (csm.CrossType == PsmCrossType.DeadEnd || csm.CrossType == PsmCrossType.DeadEndH2O || csm.CrossType == PsmCrossType.DeadEndNH2 || csm.CrossType == PsmCrossType.DeadEndTris) { csm.XlProteinPos = csm.OneBasedStartResidueInProtein == null ? (int?)null : csm.OneBasedStartResidueInProtein.Value + csm.LinkPositions[0] - 1; } else if (csm.CrossType == PsmCrossType.Loop) { csm.XlProteinPos = csm.OneBasedStartResidueInProtein == null ? (int?)null : csm.OneBasedStartResidueInProtein.Value + csm.LinkPositions[0] - 1; csm.XlProteinPosLoop = csm.OneBasedStartResidueInProtein == null ? (int?)null : csm.OneBasedStartResidueInProtein.Value + csm.LinkPositions[1] - 1; } }
/// <summary> /// Localizes the deadend mod to a residue /// </summary> private CrosslinkSpectralMatch LocalizeDeadEndSite(PeptideWithSetModifications originalPeptide, Ms2ScanWithSpecificMass theScan, CommonParameters commonParameters, List <int> possiblePositions, Modification deadEndMod, int notch, int scanIndex, int peptideIndex) { double bestScore = 0; List <MatchedFragmentIon> bestMatchingFragments = new List <MatchedFragmentIon>(); PeptideWithSetModifications bestLocalizedPeptide = null; int bestPosition = 0; foreach (int location in possiblePositions) { Dictionary <int, Modification> mods = originalPeptide.AllModsOneIsNterminus.ToDictionary(p => p.Key, p => p.Value); if (mods.ContainsKey(location + 1)) { var alreadyAnnotatedMod = mods[location + 1]; double combinedMass = mods[location + 1].MonoisotopicMass.Value + deadEndMod.MonoisotopicMass.Value; Modification combinedMod = new Modification(_originalId: alreadyAnnotatedMod.OriginalId + "+" + deadEndMod.OriginalId, _modificationType: "Crosslink", _target: alreadyAnnotatedMod.Target, _locationRestriction: "Anywhere.", _monoisotopicMass: combinedMass); mods[location + 1] = combinedMod; } else { mods.Add(location + 1, deadEndMod); } var localizedPeptide = new PeptideWithSetModifications(originalPeptide.Protein, originalPeptide.DigestionParams, originalPeptide.OneBasedStartResidueInProtein, originalPeptide.OneBasedEndResidueInProtein, originalPeptide.CleavageSpecificityForFdrCategory, originalPeptide.PeptideDescription, originalPeptide.MissedCleavages, mods, originalPeptide.NumFixedMods); var products = localizedPeptide.Fragment(commonParameters.DissociationType, FragmentationTerminus.Both).ToList(); var matchedFragmentIons = MatchFragmentIons(theScan, products, commonParameters); double score = CalculatePeptideScore(theScan.TheScan, matchedFragmentIons); if (score > bestScore) { bestMatchingFragments = matchedFragmentIons; bestScore = score; bestLocalizedPeptide = localizedPeptide; bestPosition = location; } } if (bestScore < commonParameters.ScoreCutoff) { return(null); } var csm = new CrosslinkSpectralMatch(bestLocalizedPeptide, notch, bestScore, scanIndex, theScan, originalPeptide.DigestionParams, bestMatchingFragments); if (deadEndMod == TrisDeadEnd) { csm.CrossType = PsmCrossType.DeadEndTris; } else if (deadEndMod == H2ODeadEnd) { csm.CrossType = PsmCrossType.DeadEndH2O; } else if (deadEndMod == NH2DeadEnd) { csm.CrossType = PsmCrossType.DeadEndNH2; } csm.LinkPositions = new List <int> { bestPosition }; csm.XlRank = new List <int> { peptideIndex }; 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); }
/// <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> /// /// </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); }