public Transition(TransitionGroup group, IonType type, int?offset, int?massIndex, int charge, int?decoyMassShift, CustomIon customIon = null) { _group = group; IonType = type; CleavageOffset = offset ?? 0; MassIndex = massIndex ?? 0; Charge = charge; DecoyMassShift = decoyMassShift; // Small molecule precursor transition should have same custom ion as parent if (IsPrecursor(type) && group.IsCustomIon) { CustomIon = group.CustomIon; } else { CustomIon = customIon; } // Derived values if (!IsCustom(type, group)) { Peptide peptide = group.Peptide; Ordinal = OffsetToOrdinal(type, (int)offset, peptide.Length); AA = (IsNTerminal() ? peptide.Sequence[(int)offset] : peptide.Sequence[(int)offset + 1]); } else { // caller may have passed in offset = group.Peptide.Length - 1, which for custom ions gives -1 CleavageOffset = 0; } Validate(); }
public override string ToString() { if (IsPrecursor()) { return(Resources.Transition_ToString_precursor + GetChargeIndicator(Adduct) + GetMassIndexText(MassIndex)); } if (IsCustom()) { var text = CustomIon.ToString(); // Was there enough information to generate a string more distinctive that just "Ion"? if (String.IsNullOrEmpty(CustomIon.Name) && String.IsNullOrEmpty(CustomIon.NeutralFormula)) { // No, add mz and charge to whatever generic text was used to describe it var mz = Adduct.MzFromNeutralMass(CustomIon.MonoisotopicMass); return(string.Format(@"{0} {1:F04}{2}", text, mz, GetChargeIndicator(Adduct))); } return(text); } return(string.Format(@"{0} - {1}{2}{3}{4}", AA, IonType.ToString().ToLowerInvariant(), Ordinal, GetDecoyText(DecoyMassShift), GetChargeIndicator(Adduct))); }
private bool Equals(CustomIon other) { var equal = string.Equals(Formula, other.Formula) && string.Equals(Name, other.Name) && MonoisotopicMass.Equals(other.MonoisotopicMass) && AverageMass.Equals(other.AverageMass); return(equal); // For debugging convenience }
public static CustomIon Deserialize(XmlReader reader) { var ion = new CustomIon(); Adduct adduct; ion.ReadAttributes(reader, out adduct); ion.Adduct = adduct; return(ion); }
public static bool Equivalent(Transition t, Transition obj) { return(Equals(obj.IonType, t.IonType) && obj.CleavageOffset == t.CleavageOffset && obj.Charge == t.Charge && obj.MassIndex == t.MassIndex && CustomIon.Equivalent(obj.CustomIon, t.CustomIon) && // Looks at unlabeled formula or name only (obj.DecoyMassShift.Equals(t.DecoyMassShift) || // Deal with strange case of mProphet golden standard data set - only a concern for peptides, not small molecules (obj.DecoyMassShift.HasValue && t.DecoyMassShift.HasValue && (obj.Group.LabelType.IsLight && obj.DecoyMassShift == 0 && !t.Group.LabelType.IsLight && t.DecoyMassShift != 0) || (!obj.Group.LabelType.IsLight && obj.DecoyMassShift != 0 && t.Group.LabelType.IsLight && t.DecoyMassShift == 0)))); }
public override int GetHashCode() { unchecked { int result = (_fastaSequence != null ? _fastaSequence.GetHashCode() : 0); result = (result * 397) ^ (Sequence != null ? Sequence.GetHashCode() : 0); result = (result * 397) ^ (Begin.HasValue ? Begin.Value : 0); result = (result * 397) ^ (End.HasValue ? End.Value : 0); result = (result * 397) ^ MissedCleavages; result = (result * 397) ^ IsDecoy.GetHashCode(); result = (result * 397) ^ (CustomIon != null ? CustomIon.GetHashCode() : 0); return(result); } }
public override int GetHashCode() { unchecked { int result = _group.GetHashCode(); result = (result * 397) ^ IonType.GetHashCode(); result = (result * 397) ^ CleavageOffset; result = (result * 397) ^ MassIndex; result = (result * 397) ^ Adduct.GetHashCode(); result = (result * 397) ^ (DecoyMassShift.HasValue ? DecoyMassShift.Value : 0); result = (result * 397) ^ (CustomIon != null ? CustomIon.GetHashCode() : 0); return(result); } }
public string GetFragmentIonName(CultureInfo cultureInfo, double?tolerance = null) { if (IsCustom() && !IsPrecursor()) { return(CustomIon.ToString(tolerance)); } string ionName = ReferenceEquals(cultureInfo, CultureInfo.InvariantCulture) ? IonType.ToString() : IonType.GetLocalizedString(); if (!IsPrecursor()) { ionName += Ordinal; } return(ionName); }
private void Validate() { if (IsCustomIon) { Assume.IsNull(_fastaSequence); Assume.IsNull(Sequence); CustomIon.Validate(); } else if (_fastaSequence == null) { if (Begin.HasValue || End.HasValue) { throw new InvalidDataException(Resources.Peptide_Validate_Peptides_without_a_protein_sequence_do_not_support_the_start_and_end_properties); } // No FastaSequence checked the sequence, so check it here. FastaSequence.ValidateSequence(Sequence); } else { // Otherwise, validate the peptide sequence against the group sequence if (!Begin.HasValue || !End.HasValue) { throw new InvalidDataException(Resources.Peptide_Validate_Peptides_from_protein_sequences_must_have_start_and_end_values); } if (0 > Begin.Value || End.Value > _fastaSequence.Sequence.Length) { throw new InvalidDataException(Resources.Peptide_Validate_Peptide_sequence_exceeds_the_bounds_of_the_protein_sequence); } var j = 0; for (var i = Begin.Value; i < End.Value;) { if (!Equals(Sequence[j++], _fastaSequence.Sequence[i++])) { string sequenceCheck = _fastaSequence.Sequence.Substring(Begin.Value, End.Value - Begin.Value); throw new InvalidDataException( string.Format(Resources.Peptide_Validate_The_peptide_sequence__0__does_not_agree_with_the_protein_sequence__1__at__2__3__, Sequence, sequenceCheck, Begin.Value, End.Value)); } } } // CONSIDER: Validate missed cleavages some day? }
public Transition(TransitionGroup group, IonType type, int?offset, int?massIndex, Adduct adduct, int?decoyMassShift, CustomMolecule customMolecule = null) { _group = group; IonType = type; CleavageOffset = offset ?? 0; MassIndex = massIndex ?? 0; Adduct = adduct; DecoyMassShift = decoyMassShift; // Small molecule precursor transition should have same custom molecule as parent if (IsPrecursor(type) && group.IsCustomIon) { CustomIon = new CustomIon(group.CustomMolecule, adduct); } else if (customMolecule is CustomIon) { // As with reporter ions CustomIon = (CustomIon)customMolecule; Assume.IsTrue(Equals(adduct.AdductCharge, CustomIon.Adduct.AdductCharge)); Adduct = CustomIon.Adduct; // Ion mass is part of formula, so use charge only adduct } else if (customMolecule != null) { CustomIon = new CustomIon(customMolecule, adduct); } // Derived values if (!IsCustom(type, group)) { Peptide peptide = group.Peptide; Ordinal = OffsetToOrdinal(type, (int)offset, peptide.Length); AA = (IsNTerminal() ? peptide.Sequence[(int)offset] : peptide.Sequence[(int)offset + 1]); } else { // caller may have passed in offset = group.Peptide.Length - 1, which for custom ions gives -1 CleavageOffset = 0; } Validate(); }
/// <summary> /// For use in heavy/light matching, where formula or name is only reliable match value /// Without that we use transition list mz sort order /// </summary> public static bool Equivalent(CustomIon ionA, CustomIon ionB) { if (Equals(ionA, ionB)) { return(true); } if (ionA == null || ionB == null) { return(false); // One null, one non-null } // Name if (ionA.PrimaryEquivalenceKey != null || ionB.PrimaryEquivalenceKey != null) { return(Equals(ionA.PrimaryEquivalenceKey, ionB.PrimaryEquivalenceKey)); } // Formula (stripped of labels) if (ionA.SecondaryEquivalenceKey != null || ionB.SecondaryEquivalenceKey != null) { return(Equals(ionA.SecondaryEquivalenceKey, ionB.SecondaryEquivalenceKey)); } return(true); // Not proven to be unequivalent - it's up to caller to think about mz }
public IEnumerable <TransitionDocNode> GetPrecursorTransitions(SrmSettings settings, ExplicitMods mods, IPrecursorMassCalc calcFilterPre, IFragmentMassCalc calcPredict, double precursorMz, IsotopeDistInfo isotopeDist, IList <IList <ExplicitLoss> > potentialLosses, IDictionary <double, LibraryRankedSpectrumInfo.RankedMI> transitionRanks, bool libraryFilter, bool useFilter) { var tranSettings = settings.TransitionSettings; var fullScan = tranSettings.FullScan; MassType massType = tranSettings.Prediction.FragmentMassType; int minMz = tranSettings.Instrument.GetMinMz(precursorMz); int maxMz = tranSettings.Instrument.MaxMz; bool precursorMS1 = fullScan.IsEnabledMs; if (IsCustomIon) { var ionMz = BioMassCalc.CalculateIonMz( CustomIon.GetMass(settings.TransitionSettings.Prediction.PrecursorMassType), PrecursorCharge); if (!useFilter || !libraryFilter || IsMatched(transitionRanks, ionMz, IonType.precursor, PrecursorCharge, null)) { if (precursorMS1 && isotopeDist != null) { foreach (int i in fullScan.SelectMassIndices(isotopeDist, useFilter)) { double precursorMS1Mass = isotopeDist.GetMassI(i); ionMz = BioMassCalc.CalculateIonMz(precursorMS1Mass, PrecursorCharge); if (minMz > ionMz || ionMz > maxMz) { continue; } var isotopeDistInfo = new TransitionIsotopeDistInfo(isotopeDist.GetRankI(i), isotopeDist.GetProportionI(i)); yield return(CreateTransitionNode(i, precursorMS1Mass, isotopeDistInfo, null, transitionRanks, CustomIon)); } } else { var transition = new Transition(this, PrecursorCharge, null, CustomIon, IonType.precursor); double massH = CustomIon.GetMass(settings.TransitionSettings.Prediction.PrecursorMassType); yield return(new TransitionDocNode(transition, null, massH, null, null)); } } yield break; } string sequence = Peptide.Sequence; bool precursorNoProducts = precursorMS1 && !fullScan.IsEnabledMsMs && tranSettings.Filter.IonTypes.Count == 1 && tranSettings.Filter.IonTypes[0] == IonType.precursor; double precursorMassPredict = calcPredict.GetPrecursorFragmentMass(sequence); foreach (var losses in CalcTransitionLosses(IonType.precursor, 0, massType, potentialLosses)) { double ionMz = SequenceMassCalc.GetMZ(Transition.CalcMass(precursorMassPredict, losses), PrecursorCharge); if (losses == null) { if (precursorMS1 && isotopeDist != null) { foreach (int i in fullScan.SelectMassIndices(isotopeDist, useFilter)) { double precursorMS1Mass = isotopeDist.GetMassI(i, DecoyMassShift); ionMz = SequenceMassCalc.GetMZ(precursorMS1Mass, PrecursorCharge); if (minMz > ionMz || ionMz > maxMz) { continue; } var isotopeDistInfo = new TransitionIsotopeDistInfo( isotopeDist.GetRankI(i), isotopeDist.GetProportionI(i)); yield return(CreateTransitionNode(i, precursorMS1Mass, isotopeDistInfo, null, transitionRanks)); } continue; } } // If there was loss, it is possible (though not likely) that the ion m/z value // will now fall below the minimum measurable value for the instrument else if (minMz > ionMz) { continue; } // If filtering precursors from MS1 scans, then ranking in MS/MS does not apply bool precursorIsProduct = !precursorMS1 || losses != null; // Skip product ion precursors, if the should not be included if (useFilter && precursorIsProduct && precursorNoProducts) { continue; } if (!useFilter || !precursorIsProduct || !libraryFilter || IsMatched(transitionRanks, ionMz, IonType.precursor, PrecursorCharge, losses)) { yield return(CreateTransitionNode(0, precursorMassPredict, null, losses, precursorIsProduct ? transitionRanks : null)); } } }
/// <summary> /// Creates a precursor transition /// </summary> /// <param name="group">The <see cref="TransitionGroup"/> which the transition represents</param> /// <param name="massIndex">Isotope mass shift</param> /// <param name="customIon">Non-null if this is a custom transition</param> public Transition(TransitionGroup group, int massIndex, CustomIon customIon = null) : this(group, IonType.precursor, group.Peptide.Length - 1, massIndex, group.PrecursorCharge, null, customIon) { }
public Transition(TransitionGroup group, int charge, int?massIndex, CustomIon customIon, IonType type = IonType.custom) : this(group, type, null, massIndex, charge, null, customIon) { }
public RefinementIdentity(CustomIon customIon) { CustomIon = customIon; }
private TransitionDocNode CreateTransitionNode(IonType type, int cleavageOffset, int charge, double massH, TransitionLosses losses, IDictionary <double, LibraryRankedSpectrumInfo.RankedMI> transitionRanks, CustomIon customIon = null) { Transition transition = new Transition(this, type, cleavageOffset, 0, charge, null, customIon); var info = TransitionDocNode.GetLibInfo(transition, Transition.CalcMass(massH, losses), transitionRanks); return(new TransitionDocNode(transition, losses, massH, null, info)); }
private bool Equals(CustomIon other) { var equal = string.Equals(Formula, other.Formula) && string.Equals(Name, other.Name) && MonoisotopicMass.Equals(other.MonoisotopicMass) && AverageMass.Equals(other.AverageMass); return equal; // For debugging convenience }
public double GetPrecursorMass(CustomIon customIon) { return (MassType == MassType.Average) ? customIon.AverageMass : customIon.MonoisotopicMass; }
public double GetPrecursorMass(CustomIon ion) { return _massCalcBase.GetPrecursorMass(ion); }
public Transition(TransitionGroup group, IonType type, int? offset, int? massIndex, int charge, int? decoyMassShift, CustomIon customIon = null) { _group = group; IonType = type; CleavageOffset = offset ?? 0; MassIndex = massIndex ?? 0; Charge = charge; DecoyMassShift = decoyMassShift; // Small molecule precursor transition should have same custom ion as parent if (IsPrecursor(type) && group.IsCustomIon) CustomIon = group.CustomIon; else CustomIon = customIon; // Derived values if (!IsCustom(type, group)) { Peptide peptide = group.Peptide; Ordinal = OffsetToOrdinal(type, (int)offset, peptide.Length); AA = (IsNTerminal() ? peptide.Sequence[(int)offset] : peptide.Sequence[(int)offset + 1]); } else { // caller may have passed in offset = group.Peptide.Length - 1, which for custom ions gives -1 CleavageOffset = 0; } Validate(); }
public Transition(TransitionGroup group, int charge, int? massIndex, CustomIon customIon, IonType type=IonType.custom) : this(group, type, null, massIndex, charge, null, customIon) { }
/// <summary> /// Creates a precursor transition /// </summary> /// <param name="group">The <see cref="TransitionGroup"/> which the transition represents</param> /// <param name="massIndex">Isotope mass shift</param> /// <param name="customIon">Non-null if this is a custom transition</param> public Transition(TransitionGroup group, int massIndex, CustomIon customIon = null) : this(group, IonType.precursor, group.Peptide.Length - 1, massIndex, group.PrecursorCharge, null, customIon) { }
private TransitionDocNode CreateTransitionNode(int massIndex, double precursorMassH, TransitionIsotopeDistInfo isotopeDistInfo, TransitionLosses losses, IDictionary <double, LibraryRankedSpectrumInfo.RankedMI> transitionRanks, CustomIon customIon = null) { Transition transition = new Transition(this, massIndex, customIon); var info = isotopeDistInfo == null?TransitionDocNode.GetLibInfo(transition, Transition.CalcMass(precursorMassH, losses), transitionRanks) : null; return(new TransitionDocNode(transition, losses, precursorMassH, isotopeDistInfo, info)); }
/// <summary> /// For use in heavy/light matching, where formula or name is only reliable match value /// Without that we use transition list mz sort order /// </summary> public static bool Equivalent(CustomIon ionA, CustomIon ionB) { if (Equals(ionA, ionB)) return true; if (ionA == null || ionB == null) return false; // One null, one non-null // Name if (ionA.PrimaryEquivalenceKey != null || ionB.PrimaryEquivalenceKey != null) return Equals(ionA.PrimaryEquivalenceKey, ionB.PrimaryEquivalenceKey); // Formula (stripped of labels) if (ionA.SecondaryEquivalenceKey != null || ionB.SecondaryEquivalenceKey != null) return Equals(ionA.SecondaryEquivalenceKey, ionB.SecondaryEquivalenceKey); return true; // Not proven to be unequivalent - it's up to caller to think about mz }