protected override bool IsMatch(Target target, PeptideDocNode nodePep, out TransitionGroupDocNode nodeGroup) { string seqSimplified = SimplifyUnimodSequence(target.Sequence); var seqLight = FastaSequence.StripModifications(seqSimplified, FastaSequence.RGX_HEAVY); var seqHeavy = FastaSequence.StripModifications(seqSimplified, FastaSequence.RGX_LIGHT); var calcLight = Settings.TryGetPrecursorCalc(IsotopeLabelType.light, nodePep.ExplicitMods); foreach (TransitionGroupDocNode nodeGroupChild in nodePep.Children) { nodeGroup = nodeGroupChild; if (nodeGroup.TransitionGroup.LabelType.IsLight) { // Light modifications must match. if (!EqualsModifications(seqLight, calcLight, null)) { return(false); } // If the sequence only has light modifications, a match has been found. if (Equals(seqLight, seqSimplified)) { return(true); } } else { var calc = Settings.TryGetPrecursorCalc(nodeGroup.TransitionGroup.LabelType, nodePep.ExplicitMods); if (calc != null && EqualsModifications(seqHeavy, calc, calcLight)) { return(true); } } } nodeGroup = null; return(false); }
public PeptideDocNode CreateDocNodeFromSettings(string seq, Peptide peptide, SrmSettingsDiff diff, out TransitionGroupDocNode nodeGroupMatched) { seq = Transition.StripChargeIndicators(seq, TransitionGroup.MIN_PRECURSOR_CHARGE, TransitionGroup.MAX_PRECURSOR_CHARGE); if (peptide == null) { string seqUnmod = FastaSequence.StripModifications(seq); try { peptide = new Peptide(null, seqUnmod, null, null, Settings.PeptideSettings.Enzyme.CountCleavagePoints(seqUnmod)); } catch (InvalidDataException) { nodeGroupMatched = null; return(null); } } // Use the number of modifications as the maximum, if it is less than the current // settings to keep from over enumerating, which can be slow. var filter = new MaxModFilter(Math.Min(seq.Count(c => c == '[' || c == '('), Settings.PeptideSettings.Modifications.MaxVariableMods)); foreach (var nodePep in peptide.CreateDocNodes(Settings, filter)) { var nodePepMod = CreateDocNodeFromSettings(seq, nodePep, diff, out nodeGroupMatched); if (nodePepMod != null) { return(nodePepMod); } } nodeGroupMatched = null; return(null); }
/// <summary> /// Compares the modifications indicated in the sequence string to the calculated masses. /// </summary> /// <param name="seq">The modified sequence.</param> /// <param name="calc">Calculator used to calculate the masses.</param> /// <param name="calcLight"> /// Additional light calculator if necessary to isolate mass changes /// caused by heavy modifications alone. /// </param> /// <returns> /// True if the given calculators explain the modifications indicated on the sequence, /// false otherwise. /// </returns> private bool EqualsModifications(string seq, IPrecursorMassCalc calc, IPrecursorMassCalc calcLight) { var modifications = Settings.PeptideSettings.Modifications; bool structural = calcLight == null; string aas = FastaSequence.StripModifications(seq); foreach (var info in EnumerateSequenceInfos(seq, true)) { int indexAA = info.IndexAA; // ReSharper var aa = aas[indexAA]; var roundedTo = info.RoundedTo; // If the user has indicated the modification by name, find that modification // and calculate the mass. double massKey; if (info.Mass != null) { massKey = (double)info.Mass; } else { var info1 = info; StaticMod modMatch = null; int index; if (structural && ((index = modifications.StaticModifications.IndexOf(mod => Equals(mod.Name, info1.Name))) != -1)) { modMatch = modifications.StaticModifications[index]; } if (!structural && ((index = modifications.HeavyModifications.IndexOf(mod => Equals(mod.Name, info1.Name))) != -1)) { modMatch = modifications.HeavyModifications[index]; } if (modMatch == null) { return(false); } roundedTo = DEFAULT_ROUNDING_DIGITS; massKey = Math.Round(GetDefaultModMass(aa, modMatch), roundedTo); } double massMod = Math.Round(calc.GetAAModMass(aas[indexAA], indexAA, aas.Length), roundedTo); // Subtract the mass difference of the light // modifications to isolate the masses of the heavy modifications. if (calcLight != null) { massMod -= Math.Round(calcLight.GetAAModMass(aas[indexAA], indexAA, aas.Length), roundedTo); } if (!Equals(massKey, massMod)) { return(false); } } return(true); }
public string SimplifyUnimodSequence(string seq) { var sb = new StringBuilder(seq); string aas = FastaSequence.StripModifications(seq); int indexAA = 0; int i = 0; while (i < seq.Length) { var aa = aas[indexAA]; int indexBracket = i + 1; if (indexBracket < seq.Length && (FastaSequence.OPEN_MOD.Contains(seq[indexBracket]))) { char openBracket = seq[indexBracket]; char closeBracket = FastaSequence.CLOSE_MOD[FastaSequence.OPEN_MOD.IndexOf(c => c == openBracket)]; int indexStart = indexBracket + 1; int indexClose = seq.IndexOf(closeBracket, indexBracket); string mod = seq.Substring(indexStart, indexClose - indexStart); i = indexClose; ModTerminus?modTerminus = null; if (indexAA == 0) { modTerminus = ModTerminus.N; } if (indexAA == aas.Length - 1) { modTerminus = ModTerminus.C; } // Here we are only interested in uniMod int uniModId; if (TryGetIdFromUnimod(mod, out uniModId)) { var staticMod = GetStaticMod(uniModId, aa, modTerminus); if (staticMod == null) { ThrowUnimodException(seq, uniModId, indexAA, indexBracket, indexClose); return(null); // Keep ReSharper happy } string name = staticMod.Name; bool isHeavy = !UniMod.DictStructuralModNames.ContainsKey(name); sb[indexBracket] = isHeavy ? '{' : '['; sb[indexClose] = isHeavy ? '}' : ']'; } } // If the next character is a bracket, continue using the same amino // acid and leave i where it is. int iNext = i + 1; if (iNext >= seq.Length || !FastaSequence.OPEN_MOD.Contains(seq[iNext])) { indexAA++; i++; } } return(sb.ToString()); }
public PeptideDocNode GetModifiedNode(string seq, FastaSequence fastaSequence) { var seqUnmod = FastaSequence.StripModifications(seq); var peptide = fastaSequence != null ? fastaSequence.CreateFullPeptideDocNode(Settings, new Target(seqUnmod)).Peptide : new Peptide(null, seqUnmod, null, null, Settings.PeptideSettings.Enzyme.CountCleavagePoints(seqUnmod)); // First, try to create the peptide using the current settings. TransitionGroupDocNode nodeGroup; PeptideDocNode nodePep = CreateDocNodeFromSettings(new Target(seq), peptide, SrmSettingsDiff.ALL, out nodeGroup); if (nodePep != null) { return(nodePep); } // Create the peptideDocNode. nodePep = fastaSequence == null ? new PeptideDocNode(peptide) : fastaSequence.CreateFullPeptideDocNode(Settings, new Target(seqUnmod)); return(CreateDocNodeFromMatches(nodePep, EnumerateSequenceInfos(seq, false))); }
private IEnumerable <AAModInfo> EnumerateSequenceInfos(string seq, bool includeUnmod) { string aas = FastaSequence.StripModifications(seq); bool isSpecificHeavy = FastaSequence.OPEN_MOD.All(paren => aas.Length > seq.Count(c => c == paren)); int indexAA = 0; int indexAAInSeq = 0; int i = 0; while (i < seq.Length) { var aa = aas[indexAA]; int indexBracket = i + 1; if (indexBracket < seq.Length && (FastaSequence.OPEN_MOD.Contains(seq[indexBracket]))) { char openBracket = seq[indexBracket]; bool isHeavy = openBracket == '{'; char closeBracket = FastaSequence.CLOSE_MOD[FastaSequence.OPEN_MOD.IndexOf(c => c == openBracket)]; int indexStart = indexBracket + 1; int indexClose = seq.IndexOf(closeBracket, indexBracket); string mod = seq.Substring(indexStart, indexClose - indexStart); i = indexClose; ModTerminus?modTerminus = null; if (indexAA == 0) { modTerminus = ModTerminus.N; } if (indexAA == aas.Length - 1) { modTerminus = ModTerminus.C; } string name = null; double?mass = null; int roundedTo = 0; // If passed in modification in UniMod notation, look up the id and find the name and mass int uniModId; if (TryGetIdFromUnimod(mod, out uniModId)) { var staticMod = GetStaticMod(uniModId, aa, modTerminus); if (staticMod == null) { throw ThrowUnimodException(seq, uniModId, indexAA, indexBracket, indexClose); } name = staticMod.Name; isHeavy = !UniMod.IsStructuralModification(name); // CONSIDER: Mass depends on TransitionPrediction settings for precursors mass = staticMod.MonoisotopicMass; roundedTo = DEFAULT_ROUNDING_DIGITS; } else { MassModification massModification = MassModification.Parse(mod); if (massModification != null) { mass = massModification.Mass; roundedTo = Math.Min(massModification.Precision, DEFAULT_ROUNDING_DIGITS); } else { name = mod; } } if (mass.HasValue) { mass = Math.Round(mass.Value, roundedTo); } var key = new AAModKey { Name = name, Mass = mass, AA = aa, Terminus = modTerminus, UserIndicatedHeavy = isHeavy, RoundedTo = roundedTo, AppearsToBeSpecificMod = isSpecificHeavy }; yield return(new AAModInfo { ModKey = key, IndexAA = indexAA, IndexAAInSeq = indexAAInSeq, }); } else if (includeUnmod) { // If need unmodified amino acids (as when // checking for equality), yield SequenceKeys for these AA's. var key = new AAModKey { AA = aa, Mass = 0 }; yield return(new AAModInfo { ModKey = key, IndexAA = indexAA, }); } // If the next character is a bracket, continue using the same amino // acid and leave i where it is. int iNext = i + 1; if (iNext >= seq.Length || !FastaSequence.OPEN_MOD.Contains(seq[iNext])) { i = indexAAInSeq = iNext; indexAA++; } } }