Example #1
0
 public TransitionLoss(StaticMod precursorMod, FragmentLoss loss, MassType massType)
     : this()
 {
     PrecursorMod = precursorMod;
     Loss = loss;
     Mass = Loss.GetMass(massType);
 }
 public DatabaseSearcher(IList<string> dataFilepaths,
     int minimumAssumedPrecursorChargeState, int maximumAssumedPrecursorChargeState,
     double absoluteThreshold, double relativeThresholdPercent, int maximumNumberOfPeaks,
     bool assignChargeStates, bool deisotope,
     string proteinFastaDatabaseFilepath, bool onTheFlyDecoys,
     Protease protease, int maximumMissedCleavages, InitiatorMethionineBehavior initiatorMethionineBehavior,
     IEnumerable<Modification> fixedModifications, IEnumerable<Modification> variableModifications, int maximumVariableModificationIsoforms,
     MassTolerance precursorMassTolerance, MassType precursorMassType,
     bool precursorMonoisotopicPeakCorrection, int minimumPrecursorMonoisotopicPeakOffset, int maximumPrecursorMonoisotopicPeakOffset,
     MassTolerance productMassTolerance, MassType productMassType,
     double maximumFalseDiscoveryRate, bool considerModifiedFormsAsUniquePeptides,
     int maximumThreads, bool minimizeMemoryUsage,
     string outputFolder)
 {
     this.dataFilepaths = dataFilepaths;
     this.assignChargeStates = assignChargeStates;
     this.deisotope = deisotope;
     this.proteinFastaDatabaseFilepath = proteinFastaDatabaseFilepath;
     this.onTheFlyDecoys = onTheFlyDecoys;
     this.protease = protease;
     this.maximumMissedCleavages = maximumMissedCleavages;
     this.initiatorMethionineBehavior = initiatorMethionineBehavior;
     this.fixedModifications = fixedModifications;
     this.variableModifications = variableModifications;
     this.maximumVariableModificationIsoforms = maximumVariableModificationIsoforms;
     this.minimumAssumedPrecursorChargeState = minimumAssumedPrecursorChargeState;
     this.maximumAssumedPrecursorChargeState = maximumAssumedPrecursorChargeState;
     this.absoluteThreshold = absoluteThreshold;
     this.relativeThresholdPercent = relativeThresholdPercent;
     this.maximumNumberOfPeaks = maximumNumberOfPeaks;
     this.precursorMassTolerance = precursorMassTolerance;
     this.precursorMassType = precursorMassType;
     this.precursorMonoisotopicPeakCorrection = precursorMonoisotopicPeakCorrection;
     this.minimumPrecursorMonoisotopicPeakOffset = minimumPrecursorMonoisotopicPeakOffset;
     this.maximumPrecursorMonoisotopicPeakOffset = maximumPrecursorMonoisotopicPeakOffset;
     this.productMassTolerance = productMassTolerance;
     this.productMassType = productMassType;
     this.maximumFalseDiscoveryRate = maximumFalseDiscoveryRate;
     this.considerModifiedFormsAsUniquePeptides = considerModifiedFormsAsUniquePeptides;
     this.maximumThreads = maximumThreads;
     this.minimizeMemoryUsage = minimizeMemoryUsage;
     this.outputFolder = outputFolder;
 }
Example #3
0
        /// <summary>
        /// Create a simple mass calculator for use in calculating
        /// protein, peptide and fragment masses.
        /// </summary>
        /// <param name="type">Monoisotopic or average mass calculations</param>
        public BioMassCalc(MassType type)
        {
            MassType = type;
            AddMass(H, 1.007825035, 1.00794); //Unimod
            AddMass(H2, 2.014101779, 2.014101779); //Unimod
            AddMass(O, 15.99491463, 15.9994); //Unimod
            AddMass(O17, 16.9991315, 16.9991315); //NIST
            AddMass(O18, 17.9991604, 17.9991604); //NIST, Unimod=17.9991603
            AddMass(N, 14.003074, 14.0067); //Unimod
            AddMass(N15, 15.0001088984, 15.0001088984); //NIST, Unimod=15.00010897
            AddMass(C, 12.0, 12.01085); //MacCoss average
            AddMass(C13, 13.0033548378, 13.0033548378); //NIST, Unimod=13.00335483
            AddMass(S, 31.9720707, 32.065); //Unimod
            AddMass(P, 30.973762, 30.973761); //Unimod

            AddMass(Se, 79.9165196, 78.96); //Unimod, Most abundant Se isotope is 80
            AddMass(Li, 7.016003, 6.941); //Unimod
            AddMass(F, 18.99840322, 18.9984032); //Unimod
            AddMass(Na, 22.9897677, 22.98977); //Unimod
            AddMass(S, 31.9720707, 32.065); //Unimod
            AddMass(Cl, 34.96885272, 35.453); //Unimod
            AddMass(K, 38.9637074, 39.0983); //Unimod
            AddMass(Ca, 39.9625906, 40.078); //Unimod
            AddMass(Fe, 55.9349393, 55.845); //Unimod
            AddMass(Ni, 57.9353462, 58.6934); //Unimod
            AddMass(Cu, 62.9295989, 63.546); //Unimod
            AddMass(Zn, 63.9291448, 65.409); //Unimod
            AddMass(Br, 78.9183361, 79.904); //Unimod
            AddMass(Mo, 97.9054073, 95.94); //Unimod
            AddMass(Ag, 106.905092, 107.8682); //Unimod
            AddMass(I, 126.904473, 126.90447); //Unimod
            AddMass(Au, 196.966543, 196.96655); //Unimod
            AddMass(Hg, 201.970617, 200.59); //Unimod
            AddMass(B, 11.0093055, 10.811);
            AddMass(As, 74.9215942, 74.9215942);
            AddMass(Cd, 113.903357, 112.411);
            AddMass(Cr, 51.9405098, 51.9961);
            AddMass(Co, 58.9331976, 58.933195);
            AddMass(Mn, 54.9380471, 54.938045);
            AddMass(Mg, 23.9850423, 24.305);
            AddMass(Si, 27.9769265, 28.085); // Per Wikipedia
        }
Example #4
0
 public IList<double> GetModMasses(MassType massType, IsotopeLabelType labelType)
 {
     var index = GetModIndex(labelType);
     // This will throw, if the modification type is not found.
     return _modifications[index].GetModMasses(massType);
 }
Example #5
0
        public TransitionLosses(List<TransitionLoss> losses, MassType massType)
        {
            // Make sure losses are always in a consistent order, ascending my mass
            if (losses.Count > 1)
                losses.Sort((l1, l2) => Comparer<double>.Default.Compare(l1.Mass, l2.Mass));

            _losses = new OneOrManyList<TransitionLoss>(losses);
            MassType = massType;
            Mass = CalcLossMass(Losses);
        }
Example #6
0
 public double GetMass(MassType massType)
 {
     return massType == MassType.Monoisotopic ? MonoisotopicMass : AverageMass;
 }
Example #7
0
 public double this[ProductType productType, MassType massType]
 {
     get { return PRODUCT_CAP_MASSES[(int)productType, (int)massType]; }
 }
Example #8
0
 private static SequenceMassCalc CreateMassCalc(MassType type, IEnumerable<StaticMod> staticMods)
 {
     return CreateMassCalc(type, staticMods, null);
 }
Example #9
0
 public static bool IsMonoisotopic(this MassType val)
 {
     return(!val.IsAverage());
 }
Example #10
0
 public static MassType GetEnum(string enumValue, MassType defaultValue)
 {
     return(Helpers.EnumFromLocalizedString(enumValue, LOCALIZED_VALUES, defaultValue));
 }
Example #11
0
 public static string GetLocalizedString(this MassType val)
 {
     return(LOCALIZED_VALUES[(int)val & (int)MassType.Average]); // Strip off bMassH, bHeavy
 }
Example #12
0
 public TypedMass(double value, MassType t)
 {
     _value    = value;
     _massType = t;
 }
Example #13
0
 public static bool IsHeavy(this MassType val)
 {
     return((val & MassType.bHeavy) != 0);
 }
Example #14
0
 public double GetMass(MassType massType) => _hasMass.GetMass(massType);
Example #15
0
 public double GetMass(MassType massType) => _chemicalFormula.GetMass(massType);
Example #16
0
 public static bool IsAverage(this MassType val)
 {
     return((val & MassType.Average) != 0);
 }
 public static void SetPrecursorMassType(MassType precursorMassType)
 {
     PeptideSpectrumMatch.precursorMassType = precursorMassType;
 }
Example #18
0
 public static bool IsMassH(this MassType val)
 {
     return((val & MassType.bMassH) != 0);
 }
Example #19
0
        private ImmutableList<TypedMassCalc> CreateMassCalcs(MassType type)
        {
            var calcs = new List<TypedMassCalc>();

            var mods = PeptideSettings.Modifications;

            var modsStatic = mods.StaticModifications;
            calcs.Add(new TypedMassCalc(IsotopeLabelType.light, CreateMassCalc(type, modsStatic)));

            foreach (var typedMods in mods.GetHeavyModifications())
            {
                // Only add a heavy calculator for this type if it contains
                // implicit modifications.
                var modsHeavy = typedMods.Modifications;
                if (modsHeavy.Contains(mod => !mod.IsExplicit))
                {
                    calcs.Add(new TypedMassCalc(typedMods.LabelType,
                        CreateMassCalc(type, modsStatic, modsHeavy)));
                }
            }

            return MakeReadOnly(calcs.ToArray());
        }
 public double GetScore(MassType type)
 {
     return(score.GetScore(type));
 }
Example #21
0
 public double GetMass(MassType massType)
 {
     return (massType == MassType.Average) ? AverageMass : MonoisotopicMass;
 }
Example #22
0
 public string ToString(MassType massType)
 {
     return(Formula != null?
            string.Format("{0:F04} - {1}", GetMass(massType), Formula) : // Not L10N
                string.Format("{0:F04}", GetMass(massType)));            // Not L10N
 }
Example #23
0
 public string ToString(MassType massType)
 {
     return Formula != null ?
         string.Format("{0:F04} - {1}", GetMass(massType), Formula) : // Not L10N
         string.Format("{0:F04}", GetMass(massType)); // Not L10N
 }
Example #24
0
        public static IList <IList <ExplicitLoss> > CalcPotentialLosses(Target target,
                                                                        PeptideModifications pepMods, ExplicitMods mods, MassType massType)
        {
            if (!target.IsProteomic || string.IsNullOrEmpty(target.Sequence))
            {
                return(new IList <ExplicitLoss> [0]);
            }
            var sequence = target.Sequence;

            // First build a list of the amino acids in this peptide which can be experience loss,
            // and the losses which apply to them.
            IList <KeyValuePair <IList <TransitionLoss>, int> > listIndexedListLosses = null;

            // Add losses for any explicit static modifications
            bool explicitStatic = (mods != null && mods.StaticModifications != null);
            bool explicitLosses = (explicitStatic && mods.HasNeutralLosses);

            // Add the losses for the implicit modifications, if there
            // are no explicit static modifications, or if explicit static
            // modifications exist, but they are for variable modifications.
            bool implicitAllowed = (!explicitStatic || mods.IsVariableStaticMods);
            bool implicitLosses  = (implicitAllowed && pepMods.HasNeutralLosses);

            if (explicitLosses || implicitLosses)
            {
                // Enumerate each amino acid in the sequence
                int len = sequence.Length;
                for (int i = 0; i < len; i++)
                {
                    char aa = sequence[i];
                    if (implicitLosses)
                    {
                        // Test implicit modifications to see if they apply
                        foreach (var mod in pepMods.NeutralLossModifications)
                        {
                            // If the modification does apply, store it in the list
                            if (mod.IsLoss(aa, i, len))
                            {
                                listIndexedListLosses = AddNeutralLosses(i, mod, massType, listIndexedListLosses);
                            }
                        }
                    }
                    if (explicitLosses)
                    {
                        foreach (var mod in mods.NeutralLossModifications)
                        {
                            if (mod.IndexAA == i)
                            {
                                listIndexedListLosses = AddNeutralLosses(mod.IndexAA, mod.Modification,
                                                                         massType, listIndexedListLosses);
                            }
                        }
                    }
                }
            }

            // If no losses were found, return null
            if (listIndexedListLosses == null)
            {
                return(null);
            }

            var listListLosses = new List <IList <ExplicitLoss> >();
            int maxLossCount   = Math.Min(pepMods.MaxNeutralLosses, listIndexedListLosses.Count);

            for (int lossCount = 1; lossCount <= maxLossCount; lossCount++)
            {
                var lossStateMachine = new NeutralLossStateMachine(lossCount, listIndexedListLosses);

                foreach (var listLosses in lossStateMachine.GetStates())
                {
                    listListLosses.Add(listLosses);
                }
            }
            return(listListLosses);
        }
Example #25
0
 public TransitionLosses ChangeMassType(MassType massType)
 {
     var listLosses = new List<TransitionLoss>();
     foreach (var loss in Losses)
         listLosses.Add(new TransitionLoss(loss.PrecursorMod, loss.Loss, massType));
     if (ArrayUtil.EqualsDeep(listLosses, _losses))
         return this;
     return ChangeProp(ImClone(this), im =>
     {
         im._losses = new OneOrManyList<TransitionLoss>(listLosses);
         im.Mass = CalcLossMass(im.Losses);
     });
 }
Example #26
0
 private static IList <KeyValuePair <IList <TransitionLoss>, int> > AddNeutralLosses(int indexAA,
                                                                                     StaticMod mod, MassType massType, IList <KeyValuePair <IList <TransitionLoss>, int> > listListMods)
 {
     if (listListMods == null)
     {
         listListMods = new List <KeyValuePair <IList <TransitionLoss>, int> >();
     }
     if (listListMods.Count == 0 || listListMods[listListMods.Count - 1].Value != indexAA)
     {
         listListMods.Add(new KeyValuePair <IList <TransitionLoss>, int>(new List <TransitionLoss>(), indexAA));
     }
     foreach (var loss in mod.Losses)
     {
         listListMods[listListMods.Count - 1].Key.Add(new TransitionLoss(mod, loss, massType));
     }
     return(listListMods);
 }
Example #27
0
 public IList<double> GetModMasses(MassType massType)
 {
     return (massType == MassType.Monoisotopic ? _modMassesMono : _modMassesAvg);
 }
Example #28
0
        /// <summary>
        /// Calculate all possible transition losses that apply to a transition with
        /// a specific type and cleavage offset, given all of the potential loss permutations
        /// for the precursor.
        /// </summary>
        public static IEnumerable <TransitionLosses> CalcTransitionLosses(IonType type, int cleavageOffset,
                                                                          MassType massType, IEnumerable <IList <ExplicitLoss> > potentialLosses)
        {
            // First return no losses
            yield return(null);

            if (type.Equals(IonType.custom))
            {
                foreach (var potentialLoss in potentialLosses)
                {
                    yield return(GetCustomTransitionLosses(potentialLoss, massType));
                }
            }
            else if (potentialLosses != null)
            {
                // Try to avoid allocating a whole list for this, as in many cases
                // there should be only one loss
                TransitionLosses        firstLosses   = null;
                List <TransitionLosses> allLosses     = null;
                HashSet <double>        allLossMasses = null;
                foreach (var losses in potentialLosses)
                {
                    double lossMass = CalcTransitionLossesMass(type, cleavageOffset, massType, losses);
                    if (lossMass == 0 ||
                        (firstLosses != null && firstLosses.Mass == lossMass) ||
                        (allLossMasses != null && allLossMasses.Contains(lossMass)))
                    {
                        continue;
                    }

                    var tranLosses = CalcTransitionLosses(type, cleavageOffset, massType, losses);
                    if (allLosses == null)
                    {
                        if (firstLosses == null)
                        {
                            firstLosses = tranLosses;
                        }
                        else
                        {
                            allLosses = new List <TransitionLosses> {
                                firstLosses
                            };
                            allLossMasses = new HashSet <double>();
                            allLossMasses.Add(firstLosses.Mass);
                            firstLosses = null;
                        }
                    }
                    if (allLosses != null)
                    {
                        allLosses.Add(tranLosses);
                    }
                    if (allLossMasses != null)
                    {
                        allLossMasses.Add(tranLosses.Mass);
                    }
                }

                // Handle the single losses case first
                if (firstLosses != null)
                {
                    yield return(firstLosses);
                }
                else if (allLosses != null)
                {
                    // If more then one set of transition losses return them sorted by mass
                    allLosses.Sort((l1, l2) => Comparer <double> .Default.Compare(l1.Mass, l2.Mass));
                    foreach (var tranLosses in allLosses)
                    {
                        yield return(tranLosses);
                    }
                }
            }
        }
Example #29
0
        public SequenceMassCalc(MassType type)
        {
            _massCalc = new BioMassCalc(type);

            // Not L10N

            // Mass of a proton, i.e. +1 positive charge, hydrogen atom without its electron.
            // See http://antoine.frostburg.edu/chem/senese/101/atoms/index.shtml
            // _massWater = _massCalc.CalculateMass("H2O");
            // _massAmmonia = _massCalc.CalculateMass("NH3");

            // ReSharper disable NonLocalizedString
            _massDiffA = -_massCalc.CalculateMassFromFormula("CO");
            _massDiffB = 0.0;
            _massDiffC = _massCalc.CalculateMassFromFormula("NH3");
            _massDiffY = _massCalc.CalculateMassFromFormula("H2O");
            _massDiffX = _massCalc.CalculateMassFromFormula("CO2");
            _massDiffZ = _massDiffY - _massCalc.CalculateMassFromFormula("NH2");

            _massCleaveN = _massCalc.CalculateMassFromFormula("H");
            _massCleaveC = _massCalc.CalculateMassFromFormula("OH");
            // ReSharper restore NonLocalizedString

            // These numbers are set intentionally smaller than any known instrument
            // can measure.  Filters are then applied to resulting distributions
            // to get more useful numbers.
            _massResolution = 0.001;
            _minimumAbundance = 0.00001;    // 0.001%

            InitAminoAcidMasses();
        }
Example #30
0
        private static TransitionLosses GetCustomTransitionLosses(IEnumerable <ExplicitLoss> losses, MassType massType)
        {
            List <TransitionLoss> listLosses = new List <TransitionLoss>();

            foreach (var loss in losses)
            {
                listLosses.Add(loss.TransitionLoss);
            }
            return(new TransitionLosses(listLosses, massType));
        }
Example #31
0
 public static MassType GetEnum(string enumValue, MassType defaultValue)
 {
     return Helpers.EnumFromLocalizedString(enumValue, LOCALIZED_VALUES, defaultValue);
 }
Example #32
0
 public TypedMass GetMass(MassType massType)
 {
     return(massType.IsMonoisotopic() ? MonoisotopicMass :  AverageMass);
 }
Example #33
0
        public static int CalcProductCharge(double productPrecursorMass,
            int precursorCharge,
            double[,] productMasses,
            IList<IList<ExplicitLoss>> potentialLosses,
            double productMz,
            double tolerance,
            MassType massType,
            MassShiftType massShiftType,
            out IonType? ionType,
            out int? ordinal,
            out TransitionLosses losses,
            out int massShift)
        {
            // Get length of fragment ion mass array
            int len = productMasses.GetLength(1);

            // Check all possible ion types and offsets
            double minDelta = double.MaxValue, minDeltaNs = double.MaxValue;
            int bestCharge = 0, bestChargeNs = 0;
            IonType? bestIonType = null, bestIonTypeNs = null;
            int? bestOrdinal = null, bestOrdinalNs = null;
            TransitionLosses bestLosses = null, bestLossesNs = null;
            int bestMassShift = 0;

            // Check to see if it is the precursor
            foreach (var lossesTrial in TransitionGroup.CalcTransitionLosses(IonType.precursor, 0, massType, potentialLosses))
            {
                double productMass = productPrecursorMass - (lossesTrial != null ? lossesTrial.Mass : 0);
                int potentialMassShift;
                int nearestCharge;
                int? charge = CalcProductCharge(productMass, productMz, tolerance, false, precursorCharge,
                                               massShiftType, out potentialMassShift, out nearestCharge);
                if (charge.HasValue && charge.Value == precursorCharge)
                {
                    double potentialMz = SequenceMassCalc.GetMZ(productMass, charge.Value) + potentialMassShift;
                    double delta = Math.Abs(productMz - potentialMz);

                    if (potentialMassShift == 0 && minDeltaNs > delta)
                    {
                        bestChargeNs = charge.Value;
                        bestIonTypeNs = IonType.precursor;
                        bestOrdinalNs = len + 1;
                        bestLossesNs = lossesTrial;

                        minDeltaNs = delta;
                    }
                    else if (potentialMassShift != 0 && minDelta > delta)
                    {
                        bestCharge = charge.Value;
                        bestIonType = IonType.precursor;
                        bestOrdinal = len + 1;
                        bestLosses = lossesTrial;
                        bestMassShift = potentialMassShift;

                        minDelta = delta;
                    }
                }
            }

            foreach (IonType type in Transition.ALL_TYPES)
            {
                // Types have priorities.  If moving to a lower priority type, and there is already a
                // suitable answer stop looking.
                if ((type == Transition.ALL_TYPES[2] || type == Transition.ALL_TYPES[2]) &&
                        (MatchMz(minDelta, tolerance) || MatchMz(minDeltaNs, tolerance)))
                    break;

                for (int offset = 0; offset < len; offset++)
                {
                    foreach (var lossesTrial in TransitionGroup.CalcTransitionLosses(type, offset, massType, potentialLosses))
                    {
                        // Look for the closest match.
                        double productMass = productMasses[(int) type, offset];
                        if (lossesTrial != null)
                            productMass -= lossesTrial.Mass;
                        int potentialMassShift;
                        int nearestCharge;
                        int? chargeFound = CalcProductCharge(productMass, productMz, tolerance, false, precursorCharge,
                                                       massShiftType, out potentialMassShift, out nearestCharge);
                        if (chargeFound.HasValue)
                        {
                            int charge = chargeFound.Value;
                            double potentialMz = SequenceMassCalc.GetMZ(productMass, charge) + potentialMassShift;
                            double delta = Math.Abs(productMz - potentialMz);
                            if (potentialMassShift == 0 && minDeltaNs > delta)
                            {
                                bestChargeNs = charge;
                                bestIonTypeNs = type;
                                // The peptide length is 1 longer than the mass array
                                bestOrdinalNs = Transition.OffsetToOrdinal(type, offset, len + 1);
                                bestLossesNs = lossesTrial;

                                minDeltaNs = delta;
                            }
                            else if (potentialMassShift != 0 && minDelta > delta)
                            {
                                bestCharge = charge;
                                bestIonType = type;
                                // The peptide length is 1 longer than the mass array
                                bestOrdinal = Transition.OffsetToOrdinal(type, offset, len + 1);
                                bestLosses = lossesTrial;
                                bestMassShift = potentialMassShift;

                                minDelta = delta;
                            }
                        }
                    }
                }
            }

            // Pefer no-shift to shift, even if the shift value is closer
            if (MatchMz(minDelta, tolerance) && !MatchMz(minDeltaNs, tolerance))
            {
                ionType = bestIonType;
                ordinal = bestOrdinal;
                losses = bestLosses;
                massShift = bestMassShift;
                return bestCharge;
            }

            ionType = bestIonTypeNs;
            ordinal = bestOrdinalNs;
            losses = bestLossesNs;
            massShift = 0;
            return bestChargeNs;
        }
Example #34
0
 public ModifiedSequence(string unmodifiedSequence, IEnumerable <Modification> explicitMods, MassType defaultMassType)
 {
     _unmodifiedSequence = unmodifiedSequence;
     _explicitMods       = ImmutableList.ValueOf(explicitMods.OrderBy(mod => mod.IndexAA, SortOrder.Ascending));
     _defaultMassType    = defaultMassType;
 }
Example #35
0
 public override void OnInspectorGUI()
 {
     PhysicsObject obj = (PhysicsObject)target;
     EditorGUILayout.BeginHorizontal();
     massType = (MassType)EditorGUILayout.EnumPopup(massType);
     if (massType==MassType.mass)
         obj.mass = EditorGUILayout.FloatField(obj.mass);
     else if (massType==MassType.density)
         obj.density = EditorGUILayout.FloatField(obj.density);
     else if (massType==MassType.momentOfInertia)
         obj.momentOfInertia = EditorGUILayout.FloatField(obj.momentOfInertia);
     EditorGUILayout.EndHorizontal();
     base.OnInspectorGUI();
 }
Example #36
0
        public IEnumerable <TransitionDocNode> GetTransitions(SrmSettings settings,
                                                              TransitionGroupDocNode groupDocNode,
                                                              ExplicitMods mods,
                                                              double precursorMz,
                                                              IsotopeDistInfo isotopeDist,
                                                              SpectrumHeaderInfo libInfo,
                                                              IDictionary <double, LibraryRankedSpectrumInfo.RankedMI> transitionRanks,
                                                              bool useFilter)
        {
            Assume.IsTrue(ReferenceEquals(groupDocNode.TransitionGroup, this));
            // Get necessary mass calculators and masses
            var calcFilterPre  = settings.GetPrecursorCalc(IsotopeLabelType.light, mods);
            var calcPredictPre = settings.TryGetPrecursorCalc(LabelType, mods) ?? calcFilterPre;
            var calcFilter     = settings.GetFragmentCalc(IsotopeLabelType.light, mods);
            var calcPredict    = settings.GetFragmentCalc(LabelType, mods);

            var sequence = Peptide.Target;

            // Save the true precursor m/z for TranstionSettings.Accept() now that all isotope types are
            // checked.  This is more correct than just using the light precursor m/z for precursor window
            // exclusion.
            double precursorMzAccept = precursorMz;

            if (!ReferenceEquals(calcFilter, calcPredict))
            {
                // Get the normal precursor m/z for filtering, so that light and heavy ion picks will match.
                var    adduct = groupDocNode.TransitionGroup.PrecursorAdduct;
                string isotopicFormula;
                precursorMz = IsCustomIon ?
                              adduct.MzFromNeutralMass(calcFilterPre.GetPrecursorMass(groupDocNode.CustomMolecule, null, Adduct.EMPTY, out isotopicFormula),
                                                       calcFilterPre.MassType.IsMonoisotopic() ? MassType.Monoisotopic : MassType.Average) : // Don't pass the isMassH bit
                              SequenceMassCalc.GetMZ(calcFilterPre.GetPrecursorMass(sequence), adduct);
            }
            if (!IsAvoidMismatchedIsotopeTransitions)
            {
                precursorMzAccept = precursorMz;
            }

            var      tranSettings      = settings.TransitionSettings;
            var      filter            = tranSettings.Filter;
            var      adducts           = groupDocNode.IsCustomIon ? filter.SmallMoleculeFragmentAdducts : filter.PeptideProductCharges;
            var      startFinder       = filter.FragmentRangeFirst;
            var      endFinder         = filter.FragmentRangeLast;
            double   precursorMzWindow = filter.PrecursorMzWindow;
            var      types             = groupDocNode.IsCustomIon ? filter.SmallMoleculeIonTypes : filter.PeptideIonTypes;
            MassType massType          = tranSettings.Prediction.FragmentMassType;
            int      minMz             = tranSettings.Instrument.GetMinMz(precursorMzAccept);
            int      maxMz             = tranSettings.Instrument.MaxMz;

            var pepMods         = settings.PeptideSettings.Modifications;
            var potentialLosses = CalcPotentialLosses(sequence, pepMods, mods, massType);

            // A start m/z will need to be calculated if the start fragment
            // finder uses m/z and their are losses to consider.  If the filter
            // is set to only consider fragments with m/z greater than the
            // precursor, the code below needs to also prevent loss fragments
            // from being under that m/z.
            double startMz = 0;

            // Get library settings
            var pick = tranSettings.Libraries.Pick;

            if (!useFilter)
            {
                pick = TransitionLibraryPick.all;
                var listAll = IsProteomic
                    ? Transition.DEFAULT_PEPTIDE_CHARGES.ToList()
                    : Transition.DEFAULT_MOLECULE_CHARGES.ToList();
                listAll.AddRange(adducts.Where(c => !listAll.Contains(c)));
                listAll.Sort();
                adducts = listAll.ToArray();
                types   = IsProteomic ? Transition.PEPTIDE_ION_TYPES : Transition.MOLECULE_ION_TYPES;
            }
            // If there are no libraries or no library information, then
            // picking cannot use library information
            else if (!settings.PeptideSettings.Libraries.HasLibraries || libInfo == null)
            {
                pick = TransitionLibraryPick.none;
            }

            // If filtering without library picking
            if (potentialLosses != null && IsProteomic)
            {
                if (pick == TransitionLibraryPick.none)
                {
                    // Only include loss combinations where all losses are included always
                    potentialLosses = potentialLosses.Where(losses =>
                                                            losses.All(loss => loss.TransitionLoss.Loss.Inclusion == LossInclusion.Always)).ToArray();
                }
                else if (useFilter)
                {
                    // Exclude all losses which should never be included by default
                    potentialLosses = potentialLosses.Where(losses =>
                                                            losses.All(loss => loss.TransitionLoss.Loss.Inclusion != LossInclusion.Never)).ToArray();
                }
                if (!potentialLosses.Any())
                {
                    potentialLosses = null;
                }
            }

            // Return precursor ions
            if (!useFilter || types.Contains(IonType.precursor))
            {
                bool libraryFilter = (pick == TransitionLibraryPick.all || pick == TransitionLibraryPick.filter);
                foreach (var nodeTran in GetPrecursorTransitions(settings, mods, calcPredictPre, calcPredict ?? calcFilter,
                                                                 precursorMz, isotopeDist, potentialLosses, transitionRanks, libraryFilter, useFilter))
                {
                    if (minMz <= nodeTran.Mz && nodeTran.Mz <= maxMz)
                    {
                        yield return(nodeTran);
                    }
                }
            }

            // Return special ions from settings, if this is a peptide
            if (!IsCustomIon)
            {
                // This is a peptide, but it may have custom transitions (reporter ions), check those
                foreach (var measuredIon in tranSettings.Filter.MeasuredIons.Where(m => m.IsCustom))
                {
                    if (useFilter && measuredIon.IsOptional)
                    {
                        continue;
                    }
                    var tran     = new Transition(this, measuredIon.Adduct, null, measuredIon.SettingsCustomIon);
                    var mass     = settings.GetFragmentMass(null, null, tran, null);
                    var nodeTran = new TransitionDocNode(tran, null, mass, TransitionDocNode.TransitionQuantInfo.DEFAULT, ExplicitTransitionValues.EMPTY);
                    if (minMz <= nodeTran.Mz && nodeTran.Mz <= maxMz)
                    {
                        yield return(nodeTran);
                    }
                }
            }

            // For small molecules we can't generate new nodes, so just mz filter those we have
            foreach (var nodeTran in groupDocNode.Transitions.Where(tran => tran.Transition.IsNonPrecursorNonReporterCustomIon()))
            {
                if (minMz <= nodeTran.Mz && nodeTran.Mz <= maxMz)
                {
                    yield return(nodeTran);
                }
            }

            if (!sequence.IsProteomic) // Completely custom CONSIDER(bspratt) can this be further extended for small mol libs?
            {
                yield break;
            }

            // If picking relies on library information
            if (useFilter && pick != TransitionLibraryPick.none)
            {
                // If it is not yet loaded, or nothing got ranked, return an empty enumeration
                if (!settings.PeptideSettings.Libraries.IsLoaded ||
                    (transitionRanks != null && transitionRanks.Count == 0))
                {
                    yield break;
                }
            }

            var massesPredict = calcPredict.GetFragmentIonMasses(sequence);
            int len           = massesPredict.GetLength(1);

            if (len == 0)
            {
                yield break;
            }

            var massesFilter = massesPredict;

            if (!ReferenceEquals(calcFilter, calcPredict))
            {
                // Get the normal m/z values for filtering, so that light and heavy
                // ion picks will match.
                massesFilter = calcFilter.GetFragmentIonMasses(sequence);
            }

            // Get types other than this to make sure matches are possible for all types
            var listOtherTypes = new List <Tuple <TransitionGroupDocNode, IFragmentMassCalc> >();

            foreach (var labelType in settings.PeptideSettings.Modifications.GetModificationTypes())
            {
                if (Equals(labelType, LabelType))
                {
                    continue;
                }
                var calc = settings.GetFragmentCalc(labelType, mods);
                if (calc == null)
                {
                    continue;
                }
                var tranGroupOther = new TransitionGroup(Peptide, PrecursorAdduct, labelType, false, DecoyMassShift);
                var nodeGroupOther = new TransitionGroupDocNode(tranGroupOther, Annotations.EMPTY, settings, mods,
                                                                libInfo, ExplicitTransitionGroupValues.EMPTY, null, new TransitionDocNode[0], false);

                listOtherTypes.Add(new Tuple <TransitionGroupDocNode, IFragmentMassCalc>(nodeGroupOther, calc));
            }

            // Loop over potential product ions picking transitions
            foreach (IonType type in types)
            {
                // Precursor type is handled above.
                if (type == IonType.precursor)
                {
                    continue;
                }

                foreach (var adduct in adducts)
                {
                    // Precursor charge can never be lower than product ion charge.
                    if (Math.Abs(PrecursorAdduct.AdductCharge) < Math.Abs(adduct.AdductCharge))
                    {
                        continue;
                    }

                    int start = 0, end = 0;
                    if (pick != TransitionLibraryPick.all)
                    {
                        start = startFinder.FindStartFragment(massesFilter, type, adduct,
                                                              precursorMz, precursorMzWindow, out startMz);
                        end = endFinder.FindEndFragment(type, start, len);
                        if (Transition.IsCTerminal(type))
                        {
                            Helpers.Swap(ref start, ref end);
                        }
                    }

                    for (int i = 0; i < len; i++)
                    {
                        // Get the predicted m/z that would be used in the transition
                        var massH = massesPredict[type, i];
                        Assume.IsTrue(massH.IsMassH());
                        Assume.IsTrue(massH.IsMonoIsotopic() == calcPredict.MassType.IsMonoisotopic());
                        foreach (var losses in CalcTransitionLosses(type, i, massType, potentialLosses))
                        {
                            double ionMz = SequenceMassCalc.GetMZ(Transition.CalcMass(massH, losses), adduct);

                            // Make sure the fragment m/z value falls within the valid instrument range.
                            // CONSIDER: This means that a heavy transition might excede the instrument
                            //           range where a light one is accepted, leading to a disparity
                            //           between heavy and light transtions picked.
                            if (minMz > ionMz || ionMz > maxMz)
                            {
                                continue;
                            }

                            TransitionDocNode nodeTranReturn = null;
                            bool accept = true;
                            if (pick == TransitionLibraryPick.all || pick == TransitionLibraryPick.all_plus)
                            {
                                if (!useFilter)
                                {
                                    nodeTranReturn = CreateTransitionNode(type, i, adduct, massH, losses, transitionRanks);
                                    accept         = false;
                                }
                                else
                                {
                                    if (IsMatched(transitionRanks, ionMz, type, adduct, losses))
                                    {
                                        nodeTranReturn = CreateTransitionNode(type, i, adduct, massH, losses, transitionRanks);
                                        accept         = false;
                                    }
                                    // If allowing library or filter, check the filter to decide whether to accept
                                    else if (pick == TransitionLibraryPick.all_plus &&
                                             tranSettings.Accept(sequence, precursorMzAccept, type, i, ionMz, start, end, startMz))
                                    {
                                        nodeTranReturn = CreateTransitionNode(type, i, adduct, massH, losses, transitionRanks);
                                    }
                                }
                            }
                            else if (tranSettings.Accept(sequence, precursorMzAccept, type, i, ionMz, start, end, startMz))
                            {
                                if (pick == TransitionLibraryPick.none)
                                {
                                    nodeTranReturn = CreateTransitionNode(type, i, adduct, massH, losses, transitionRanks);
                                }
                                else
                                {
                                    if (IsMatched(transitionRanks, ionMz, type, adduct, losses))
                                    {
                                        nodeTranReturn = CreateTransitionNode(type, i, adduct, massH, losses, transitionRanks);
                                    }
                                }
                            }
                            if (nodeTranReturn != null)
                            {
                                if (IsAvoidMismatchedIsotopeTransitions &&
                                    !OtherLabelTypesAllowed(settings, minMz, maxMz, start, end, startMz, accept,
                                                            groupDocNode, nodeTranReturn, listOtherTypes))
                                {
                                    continue;
                                }
                                Assume.IsTrue(minMz <= nodeTranReturn.Mz && nodeTranReturn.Mz <= maxMz);
                                yield return(nodeTranReturn);
                            }
                        }
                    }
                }
            }
        }
Example #37
0
 private static SequenceMassCalc CreateMassCalc(MassType type, IEnumerable<StaticMod> staticMods, IEnumerable<StaticMod> heavyMods)
 {
     SequenceMassCalc calc = new SequenceMassCalc(type);
     // Add implicit modifications to the mass calculator
     calc.AddStaticModifications(from mod in staticMods
                                 where !mod.IsExplicit
                                 select mod);
     if (heavyMods != null)
     {
         calc.AddHeavyModifications(from mod in heavyMods
                                    where !mod.IsExplicit
                                    select mod);
     }
     return calc;
 }
Example #38
0
        public IEnumerable <TransitionDocNode> GetPrecursorTransitions(SrmSettings settings,
                                                                       ExplicitMods mods,
                                                                       IPrecursorMassCalc calcPredictPre,
                                                                       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;
            int      minMz        = tranSettings.Instrument.GetMinMz(precursorMz);
            int      maxMz        = tranSettings.Instrument.MaxMz;
            bool     precursorMS1 = fullScan.IsEnabledMs;
            MassType massType     = tranSettings.Prediction.FragmentMassType;
            MassType massTypeIon  = precursorMS1 ? tranSettings.Prediction.PrecursorMassType : massType;

            var  sequence            = Peptide.Target;
            var  ionTypes            = IsProteomic ? tranSettings.Filter.PeptideIonTypes : tranSettings.Filter.SmallMoleculeIonTypes;
            bool precursorNoProducts = precursorMS1 && !fullScan.IsEnabledMsMs &&
                                       ionTypes.Count == 1 && ionTypes[0] == IonType.precursor;
            var precursorMassPredict = precursorMS1
                ? calcPredictPre.GetPrecursorMass(sequence)
                : calcPredict.GetPrecursorFragmentMass(sequence);

            foreach (var losses in CalcTransitionLosses(IonType.precursor, 0, massType, potentialLosses))
            {
                double ionMz = IsProteomic ?
                               SequenceMassCalc.GetMZ(Transition.CalcMass(precursorMassPredict, losses), PrecursorAdduct) :
                               PrecursorAdduct.MzFromNeutralMass(CustomMolecule.GetMass(massTypeIon), massTypeIon);

                if (losses == null)
                {
                    if (precursorMS1 && isotopeDist != null)
                    {
                        foreach (int i in fullScan.SelectMassIndices(isotopeDist, useFilter))
                        {
                            var precursorMS1Mass = isotopeDist.GetMassI(i, DecoyMassShift);
                            ionMz = SequenceMassCalc.GetMZ(precursorMS1Mass, PrecursorAdduct);
                            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,
                                                PrecursorAdduct, losses))
                {
                    yield return(CreateTransitionNode(0, precursorMassPredict, null, losses,
                                                      precursorIsProduct ? transitionRanks : null));
                }
            }
        }
 public static void SetProductMassType(MassType productMassType)
 {
     AminoAcidPolymer.productMassType = productMassType;
 }
Example #40
0
        public static Adduct CalcProductCharge(TypedMass productPrecursorMass,
                                               Adduct precursorCharge,
                                               IList <IonType> acceptedIonTypes,
                                               IonTable <TypedMass> productMasses,
                                               IList <IList <ExplicitLoss> > potentialLosses,
                                               double productMz,
                                               double tolerance,
                                               MassType massType,
                                               MassShiftType massShiftType,
                                               out IonType?ionType,
                                               out int?ordinal,
                                               out TransitionLosses losses,
                                               out int massShift)
        {
            // Get length of fragment ion mass array
            int len = productMasses.GetLength(1);

            // Check all possible ion types and offsets
            double           minDelta      = double.MaxValue;
            var              bestCharge    = Adduct.EMPTY;
            IonType?         bestIonType   = null;
            int?             bestOrdinal   = null;
            TransitionLosses bestLosses    = null;
            int              bestMassShift = 0;

            // Check to see if it is the precursor
            foreach (var lossesTrial in TransitionGroup.CalcTransitionLosses(IonType.precursor, 0, massType, potentialLosses))
            {
                var productMass = productPrecursorMass - (lossesTrial != null ? lossesTrial.Mass : 0);
                int potentialMassShift;
                int nearestCharge;
                var charge = CalcProductCharge(productMass, productMz, tolerance, false, precursorCharge,
                                               massShiftType, out potentialMassShift, out nearestCharge);
                if (Equals(charge, precursorCharge))
                {
                    double potentialMz = SequenceMassCalc.GetMZ(productMass, charge) + potentialMassShift;
                    double delta       = Math.Abs(productMz - potentialMz);

                    if (CompareIonMatch(delta, lossesTrial, potentialMassShift, minDelta, bestLosses, bestMassShift) < 0)
                    {
                        bestCharge    = charge;
                        bestIonType   = IonType.precursor;
                        bestOrdinal   = len + 1;
                        bestLosses    = lossesTrial;
                        bestMassShift = potentialMassShift;

                        minDelta = delta;
                    }
                }
            }

            var categoryLast = -1;

            foreach (var typeAccepted in GetIonTypes(acceptedIonTypes))
            {
                var type     = typeAccepted.IonType;
                var category = typeAccepted.IonCategory;

                // Types have priorities.  If changing type category, and there is already a
                // suitable answer stop looking.
                if (category != categoryLast && MatchMz(minDelta, tolerance))
                {
                    break;
                }
                categoryLast = category;

                for (int offset = 0; offset < len; offset++)
                {
                    foreach (var lossesTrial in TransitionGroup.CalcTransitionLosses(type, offset, massType, potentialLosses))
                    {
                        // Look for the closest match.
                        var productMass = productMasses[type, offset];
                        if (lossesTrial != null)
                        {
                            productMass -= lossesTrial.Mass;
                        }
                        int potentialMassShift;
                        int nearestCharge;
                        var chargeFound = CalcProductCharge(productMass, productMz, tolerance, false, precursorCharge,
                                                            massShiftType, out potentialMassShift, out nearestCharge);
                        if (!chargeFound.IsEmpty)
                        {
                            var    charge      = chargeFound;
                            double potentialMz = SequenceMassCalc.GetMZ(productMass, charge) + potentialMassShift;
                            double delta       = Math.Abs(productMz - potentialMz);
                            if (CompareIonMatch(delta, lossesTrial, potentialMassShift, minDelta, bestLosses, bestMassShift) < 0)
                            {
                                bestCharge  = charge;
                                bestIonType = type;
                                // The peptide length is 1 longer than the mass array
                                bestOrdinal   = Transition.OffsetToOrdinal(type, offset, len + 1);
                                bestLosses    = lossesTrial;
                                bestMassShift = potentialMassShift;

                                minDelta = delta;
                            }
                        }
                    }
                }
            }

            ionType   = bestIonType;
            ordinal   = bestOrdinal;
            losses    = bestLosses;
            massShift = bestMassShift;
            return(bestCharge);
        }