コード例 #1
0
        private bool CanAddLabelType(IsotopeLabelType labelType)
        {
            if (_settings.TryGetPrecursorCalc(labelType, null) != null)
            {
                return(true);
            }

            return(_document.Molecules.Any(nodePep =>
                                           _settings.TryGetPrecursorCalc(labelType, nodePep.ExplicitMods) != null));
        }
コード例 #2
0
        private static IEnumerable <KeyValuePair <IsotopeLabelType, string> > GetTypedModifiedSequences(
            PeptideDocNode nodePep, SrmSettings settings)
        {
            foreach (var labelType in settings.PeptideSettings.Modifications.GetModificationTypes())
            {
                if (nodePep.Peptide.IsCustomMolecule)
                {
                    continue;
                }
                // Only return the modified sequence, if the peptide actually as a child
                // of this type.
                if (!nodePep.HasChildType(labelType))
                {
                    continue;
                }
                var calc = settings.TryGetPrecursorCalc(labelType, nodePep.ExplicitMods);
                if (calc == null)
                {
                    continue;
                }

                string modSequence = calc.GetModifiedSequence(nodePep.Peptide.Target, true).Sequence; // Never have to worry about this being a custom molecule, we already checked

                // Only return if the modified sequence contains modifications
                if (modSequence.Contains('['))
                {
                    yield return(new KeyValuePair <IsotopeLabelType, string>(labelType, modSequence));
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Creates a text sequence with the fully modified peptide sequence text
        /// and font information for a given label type.
        /// </summary>
        private static TextSequence CreateTypeTextSequence(PeptideDocNode nodePep, SrmSettings settings,
                                                           IsotopeLabelType labelType, ModFontHolder fonts)
        {
            var calc = settings.TryGetPrecursorCalc(labelType, nodePep.ExplicitMods);

            if (calc == null)
            {
                return(null);
            }

            return(new TextSequence
            {
                Text = nodePep.IsProteomic
                               ? calc.GetModifiedSequence(nodePep.Peptide.Target, SequenceModFormatType.mass_diff_narrow, false).Sequence
                               : nodePep.CustomMolecule.DisplayName,
                Font = fonts.GetModFont(labelType),
                Color = ModFontHolder.GetModColor(labelType)
            });
        }
コード例 #4
0
        /// <summary>
        /// Creates a text sequence with the fully modified peptide sequence text
        /// and font information for a given label type.
        /// </summary>
        private static TextSequence CreateTypeTextSequence(PeptideDocNode nodePep, SrmSettings settings,
                                                           IsotopeLabelType labelType, ModFontHolder fonts)
        {
            var calc = settings.TryGetPrecursorCalc(labelType, nodePep.ExplicitMods);

            if (calc == null)
            {
                return(null);
            }

            return(new TextSequence
            {
                Text = nodePep.IsProteomic
                               ? calc.GetModifiedSequence(nodePep.Peptide.Sequence, true)
                               : nodePep.CustomIon.DisplayName,
                Font = fonts.GetModFont(labelType),
                Color = ModFontHolder.GetModColor(labelType)
            });
        }
コード例 #5
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);
                    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);
                            }
                        }
                    }
                }
            }
        }