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);
        }
        public PeptideDocNode CreateDocNodeFromSettings(LibKey key, Peptide peptide, SrmSettingsDiff diff, out TransitionGroupDocNode nodeGroupMatched)
        {
            if (!key.Target.IsProteomic)
            {
                // Scan the spectral lib entry for top N ranked (for now, that's just by intensity with high mz as tie breaker) fragments,
                // add those as mass-only fragments, or with more detail if peak annotations are present.
                foreach (var nodePep in peptide.CreateDocNodes(Settings, new MaxModFilter(0)))
                {
                    SpectrumHeaderInfo libInfo;
                    if (nodePep != null && Settings.PeptideSettings.Libraries.TryGetLibInfo(key, out libInfo))
                    {
                        var isotopeLabelType = key.Adduct.HasIsotopeLabels ? IsotopeLabelType.heavy : IsotopeLabelType.light;
                        var group            = new TransitionGroup(peptide, key.Adduct, isotopeLabelType);
                        nodeGroupMatched = new TransitionGroupDocNode(group, Annotations.EMPTY, Settings, null, libInfo, ExplicitTransitionGroupValues.EMPTY, null, null, false);
                        SpectrumPeaksInfo spectrum;
                        if (Settings.PeptideSettings.Libraries.TryLoadSpectrum(key, out spectrum))
                        {
                            // Add fragment and precursor transitions as needed
                            var transitionDocNodes =
                                Settings.TransitionSettings.Filter.SmallMoleculeIonTypes.Contains(IonType.precursor)
                                    ? nodeGroupMatched.GetPrecursorChoices(Settings, null, true) // Gives list of precursors
                                    : new List <DocNode>();

                            if (Settings.TransitionSettings.Filter.SmallMoleculeIonTypes.Contains(IonType.custom))
                            {
                                GetSmallMoleculeFragments(key, nodeGroupMatched, spectrum, transitionDocNodes);
                            }
                            nodeGroupMatched = (TransitionGroupDocNode)nodeGroupMatched.ChangeChildren(transitionDocNodes);
                            return((PeptideDocNode)nodePep.ChangeChildren(new List <DocNode>()
                            {
                                nodeGroupMatched
                            }));
                        }
                    }
                }
                nodeGroupMatched = null;
                return(null);
            }
            return(CreateDocNodeFromSettings(key.Target, peptide, diff, out nodeGroupMatched));
        }
Example #3
0
        public override IEnumerable <DocNode> GetChoices(bool useFilter)
        {
            var nodePep = PepNode;

            if (nodePep == null)
            {
                throw new InvalidOperationException(
                          Resources.TransitionGroupTreeNode_GetChoices_Invalid_attempt_to_get_choices_for_a_node_that_has_not_been_added_to_the_tree_yet);
            }

            var listChildrenNew = DocNode.GetPrecursorChoices(DocSettings, nodePep.ExplicitMods, useFilter);

            // Existing transitions must be part of the first settings change to ensure proper
            // handling of user set peak boundaries.
            MergeChosen(listChildrenNew, useFilter, node => ((TransitionDocNode)node).Key(DocNode));
            var nodeGroup = (TransitionGroupDocNode)DocNode.ChangeChildrenChecked(listChildrenNew);
            var diff      = new SrmSettingsDiff(DocSettings, true);

            // Update results on the group to correctly handle user set peak boundaries
            nodeGroup = nodeGroup.UpdateResults(DocSettings, diff, nodePep, DocNode);

            // Make sure any properties that depend on peptide relationships,
            // like ratios get updated.
            nodePep = (PeptideDocNode)nodePep.ReplaceChild(nodeGroup);
            diff    = new SrmSettingsDiff(diff, SrmSettingsDiff.PROPS);
            nodePep = nodePep.ChangeSettings(DocSettings, diff);
            var id     = nodeGroup.Id;
            int iGroup = nodePep.Children.IndexOf(n => ReferenceEquals(n.Id, id));

            if (iGroup != -1)
            {
                nodeGroup = (TransitionGroupDocNode)nodePep.Children[iGroup];
            }
            listChildrenNew = new List <DocNode>(nodeGroup.Children);
            // Merge with existing transitions again to avoid changes based on the settings
            // updates.
            MergeChosen(listChildrenNew, useFilter, node => ((TransitionDocNode)node).Key(nodeGroup));
            return(listChildrenNew);
        }
        public PeptideDocNode GetModifiedNode(LibKey key, string seqUnmod, SrmSettings settings, SrmSettingsDiff diff)
        {
            if (string.IsNullOrEmpty(seqUnmod))
            {
                return(null);
            }

            var peptide = new Peptide(null, seqUnmod, null, null,
                                      settings.PeptideSettings.Enzyme.CountCleavagePoints(seqUnmod));

            // First try and create the match from the settings created to match the library explorer.
            Settings = HasMatches
                ? settings.ChangePeptideModifications(mods => MatcherPepMods)
                : settings;
            TransitionGroupDocNode nodeGroup;
            var nodePep = CreateDocNodeFromSettings(key.Sequence, peptide, diff, out nodeGroup);

            if (nodePep != null)
            {
                if (diff == null)
                {
                    nodePep = (PeptideDocNode)nodePep.ChangeAutoManageChildren(false);
                }
                else
                {
                    // Keep only the matching transition group, so that modifications
                    // will be highlighted differently for light and heavy forms.
                    // Only performed when getting peptides for display in the explorer.
                    nodePep = (PeptideDocNode)nodePep.ChangeChildrenChecked(
                        new DocNode[] { nodeGroup });
                }
                return(nodePep);
            }
            else if (Matches == null)
            {
                return(null);
            }
            bool hasHeavy;

            // Create explicit mods from the found matches.
            nodePep = CreateDocNodeFromMatches(new PeptideDocNode(peptide),
                                               EnumerateSequenceInfos(key.Key, true), false, out hasHeavy);

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

            // Call change settings with the matched modification settings to enumerate the children.
            nodePep = nodePep.ChangeSettings(settings.ChangePeptideModifications(mods =>
                                                                                 !HasMatches ? settings.PeptideSettings.Modifications : MatcherPepMods), diff ?? SrmSettingsDiff.ALL);
            if (nodePep.Children.Count == 0)
            {
                return(null);
            }
            // Select the correct child, only for use with the library explorer.
            if (diff != null && nodePep.Children.Count > 1)
            {
                nodePep =
                    (PeptideDocNode)
                    nodePep.ChangeChildrenChecked(new List <DocNode> {
                    nodePep.Children[hasHeavy ? 1 : 0]
                });
            }
            if (diff == null)
            {
                nodePep = (PeptideDocNode)nodePep.ChangeAutoManageChildren(false);
            }
            return(nodePep);
        }
        private PeptideDocNode CreateDocNodeFromSettings(Target seq, PeptideDocNode nodePep, SrmSettingsDiff diff,
                                                         out TransitionGroupDocNode nodeGroupMatched)
        {
            PeptideDocNode         nodePepMod = nodePep.ChangeSettings(Settings, diff ?? SrmSettingsDiff.ALL, false);
            TransitionGroupDocNode nodeGroupMatchedFound;

            if (IsMatch(seq, nodePepMod, out nodeGroupMatchedFound))
            {
                nodeGroupMatched = nodeGroupMatchedFound;
                return(nodePepMod);
            }
            nodeGroupMatched = null;
            return(null);
        }
        public PeptideGroupDocNode ChangeSettings(SrmSettings settingsNew, SrmSettingsDiff diff)
        {
            if (diff.Monitor != null)
            {
                diff.Monitor.ProcessGroup(this);
            }

            if (diff.DiffPeptides && settingsNew.PeptideSettings.Filter.AutoSelect && AutoManageChildren)
            {
                IList <DocNode> childrenNew = new List <DocNode>();

                int countPeptides = 0;
                int countIons     = 0;

                Dictionary <int, DocNode>           mapIndexToChild = CreateGlobalIndexToChildMap();
                Dictionary <PeptideModKey, DocNode> mapIdToChild    = CreatePeptideModToChildMap();

                foreach (PeptideDocNode nodePep in GetPeptideNodes(settingsNew, true))
                {
                    PeptideDocNode  nodePepResult = nodePep;
                    SrmSettingsDiff diffNode      = SrmSettingsDiff.ALL;

                    DocNode existing;
                    // Add values that existed before the change. First check for exact match by
                    // global index, which will happen when explicit modifications are added,
                    // and then by content identity.
                    if (mapIndexToChild.TryGetValue(nodePep.Id.GlobalIndex, out existing) ||
                        mapIdToChild.TryGetValue(nodePep.Key, out existing))
                    {
                        nodePepResult = (PeptideDocNode)existing;
                        diffNode      = diff;
                    }

                    if (nodePepResult != null)
                    {
                        // Materialize children of the peptide.
                        nodePepResult = nodePepResult.ChangeSettings(settingsNew, diffNode);

                        childrenNew.Add(nodePepResult);

                        // Make sure a single peptide group does not exceed document limits.
                        countPeptides++;
                        countIons += nodePepResult.TransitionCount;
                        if (countIons > SrmDocument.MAX_TRANSITION_COUNT)
                        {
                            throw new InvalidDataException(String.Format(
                                                               Resources.PeptideGroupDocNode_ChangeSettings_The_current_document_settings_would_cause_the_number_of_targeted_transitions_to_exceed__0_n0___The_document_settings_must_be_more_restrictive_or_add_fewer_proteins_,
                                                               SrmDocument.MAX_TRANSITION_COUNT));
                        }
                        if (countPeptides > SrmDocument.MAX_PEPTIDE_COUNT)
                        {
                            throw new InvalidDataException(String.Format(
                                                               Resources.PeptideGroupDocNode_ChangeSettings_The_current_document_settings_would_cause_the_number_of_peptides_to_exceed__0_n0___The_document_settings_must_be_more_restrictive_or_add_fewer_proteins_,
                                                               SrmDocument.MAX_PEPTIDE_COUNT));
                        }
                    }
                }

                if (PeptideGroup.Sequence != null)
                {
                    childrenNew = PeptideGroup.RankPeptides(childrenNew, settingsNew, true);
                }

                return((PeptideGroupDocNode)ChangeChildrenChecked(childrenNew));
            }
            else
            {
                var nodeResult = this;

                if (diff.DiffPeptides && diff.SettingsOld != null)
                {
                    // If variable modifications changed, remove all peptides with variable
                    // modifications which are no longer possible.
                    var modsNew    = settingsNew.PeptideSettings.Modifications;
                    var modsVarNew = modsNew.VariableModifications.ToArray();
                    var modsOld    = diff.SettingsOld.PeptideSettings.Modifications;
                    var modsVarOld = modsOld.VariableModifications.ToArray();
                    if (modsNew.MaxVariableMods < modsOld.MaxVariableMods ||
                        !ArrayUtil.EqualsDeep(modsVarNew, modsVarOld))
                    {
                        IList <DocNode> childrenNew = new List <DocNode>();
                        foreach (PeptideDocNode nodePeptide in nodeResult.Children)
                        {
                            if (nodePeptide.AreVariableModsPossible(modsNew.MaxVariableMods, modsVarNew))
                            {
                                childrenNew.Add(nodePeptide);
                            }
                        }

                        nodeResult = (PeptideGroupDocNode)nodeResult.ChangeChildrenChecked(childrenNew);
                    }
                }

                // Check for changes affecting children
                if (diff.DiffPeptideProps || diff.DiffExplicit ||
                    diff.DiffTransitionGroups || diff.DiffTransitionGroupProps ||
                    diff.DiffTransitions || diff.DiffTransitionProps ||
                    diff.DiffResults)
                {
                    IList <DocNode> childrenNew = new List <DocNode>();

                    // Enumerate the nodes making necessary changes.
                    foreach (PeptideDocNode nodePeptide in nodeResult.Children)
                    {
                        childrenNew.Add(nodePeptide.ChangeSettings(settingsNew, diff));
                    }

                    childrenNew = RankChildren(settingsNew, childrenNew);

                    nodeResult = (PeptideGroupDocNode)nodeResult.ChangeChildrenChecked(childrenNew);
                }
                return(nodeResult);
            }
        }
Example #7
0
        public PeptideGroupDocNode ChangeSettings(SrmSettings settingsNew, SrmSettingsDiff diff,
                                                  DocumentSettingsContext context = null)
        {
            if (diff.Monitor != null)
            {
                diff.Monitor.ProcessGroup(this);
            }

            if (diff.DiffPeptides && settingsNew.PeptideSettings.Filter.AutoSelect && AutoManageChildren)
            {
                IList <DocNode> childrenNew = new List <DocNode>();

                int countPeptides = 0;
                int countIons     = 0;

                Dictionary <int, DocNode>           mapIndexToChild = CreateGlobalIndexToChildMap();
                Dictionary <PeptideModKey, DocNode> mapIdToChild    = CreatePeptideModToChildMap();

                IEnumerable <PeptideDocNode> peptideDocNodes;
                if (settingsNew.PeptideSettings.Filter.PeptideUniqueness == PeptideFilter.PeptideUniquenessConstraint.none ||
                    settingsNew.PeptideSettings.NeedsBackgroundProteomeUniquenessCheckProcessing)
                {
                    peptideDocNodes = GetPeptideNodes(settingsNew, true).ToList();
                }
                else
                {
                    // Checking peptide uniqueness against the background proteome can be expensive.
                    // Do all the regular processing, then filter those results at the end when we
                    // can do it in aggregate for best speed.
                    IEnumerable <PeptideDocNode> peptideDocNodesUnique;
                    var peptideDocNodesPrecalculatedForUniquenessCheck = context == null ? null : context.PeptideDocNodesPrecalculatedForUniquenessCheck;
                    var uniquenessDict = context == null ? null : context.UniquenessDict;
                    if (peptideDocNodesPrecalculatedForUniquenessCheck != null)
                    {
                        // Already processed, and a global list of peptides provided
                        Assume.IsNotNull(uniquenessDict);
                        peptideDocNodesUnique = peptideDocNodesPrecalculatedForUniquenessCheck;
                    }
                    else
                    {
                        // We'll have to do the processing for this node, and work with
                        // just the peptides on this node.  With luck the background proteome
                        // will already have those cached for uniqueness checks.
                        var settingsNoUniquenessFilter =
                            settingsNew.ChangePeptideFilter(f => f.ChangePeptideUniqueness(PeptideFilter.PeptideUniquenessConstraint.none));
                        var nodes     = GetPeptideNodes(settingsNoUniquenessFilter, true).ToList();
                        var sequences = new List <string>(from p in nodes select p.Peptide.Sequence);
                        peptideDocNodesUnique = nodes;  // Avoid ReSharper multiple enumeration warning
                        uniquenessDict        = settingsNew.PeptideSettings.Filter.CheckPeptideUniqueness(settingsNew, sequences, diff.Monitor);
                    }
                    // ReSharper disable once PossibleNullReferenceException
                    peptideDocNodes = peptideDocNodesUnique.Where(p =>
                    {
                        // It's possible during document load for uniqueness dict to get out of synch, so be
                        // cautious with lookup and just return false of not found. Final document change will clean that up.
                        bool isUnique;
                        return(uniquenessDict.TryGetValue(p.Peptide.Sequence, out isUnique) && isUnique);
                    });
                }

                foreach (var nodePep in peptideDocNodes)
                {
                    PeptideDocNode  nodePepResult = nodePep;
                    SrmSettingsDiff diffNode      = SrmSettingsDiff.ALL;

                    DocNode existing;
                    // Add values that existed before the change. First check for exact match by
                    // global index, which will happen when explicit modifications are added,
                    // and then by content identity.
                    if (mapIndexToChild.TryGetValue(nodePep.Id.GlobalIndex, out existing) ||
                        mapIdToChild.TryGetValue(nodePep.Key, out existing))
                    {
                        nodePepResult = (PeptideDocNode)existing;
                        diffNode      = diff;
                    }

                    if (nodePepResult != null)
                    {
                        // Materialize children of the peptide.
                        nodePepResult = nodePepResult.ChangeSettings(settingsNew, diffNode);

                        childrenNew.Add(nodePepResult);

                        // Make sure a single peptide group does not exceed document limits.
                        countPeptides++;
                        countIons += nodePepResult.TransitionCount;
                        if (countIons > SrmDocument.MAX_TRANSITION_COUNT)
                        {
                            throw new InvalidDataException(String.Format(
                                                               Resources.PeptideGroupDocNode_ChangeSettings_The_current_document_settings_would_cause_the_number_of_targeted_transitions_to_exceed__0_n0___The_document_settings_must_be_more_restrictive_or_add_fewer_proteins_,
                                                               SrmDocument.MAX_TRANSITION_COUNT));
                        }
                        if (countPeptides > SrmDocument.MAX_PEPTIDE_COUNT)
                        {
                            throw new InvalidDataException(String.Format(
                                                               Resources.PeptideGroupDocNode_ChangeSettings_The_current_document_settings_would_cause_the_number_of_peptides_to_exceed__0_n0___The_document_settings_must_be_more_restrictive_or_add_fewer_proteins_,
                                                               SrmDocument.MAX_PEPTIDE_COUNT));
                        }
                    }
                }

                if (PeptideGroup.Sequence != null)
                {
                    childrenNew = PeptideGroup.RankPeptides(childrenNew, settingsNew, true);
                }

                return((PeptideGroupDocNode)ChangeChildrenChecked(childrenNew));
            }
            else
            {
                var nodeResult = this;

                if (diff.DiffPeptides && diff.SettingsOld != null)
                {
                    // If variable modifications changed, remove all peptides with variable
                    // modifications which are no longer possible.
                    var modsNew    = settingsNew.PeptideSettings.Modifications;
                    var modsVarNew = modsNew.VariableModifications.ToArray();
                    var modsOld    = diff.SettingsOld.PeptideSettings.Modifications;
                    var modsVarOld = modsOld.VariableModifications.ToArray();
                    if (modsNew.MaxVariableMods < modsOld.MaxVariableMods ||
                        !ArrayUtil.EqualsDeep(modsVarNew, modsVarOld))
                    {
                        IList <DocNode> childrenNew = new List <DocNode>();
                        foreach (PeptideDocNode nodePeptide in nodeResult.Children)
                        {
                            if (nodePeptide.AreVariableModsPossible(modsNew.MaxVariableMods, modsVarNew))
                            {
                                childrenNew.Add(nodePeptide);
                            }
                        }

                        nodeResult = (PeptideGroupDocNode)nodeResult.ChangeChildrenChecked(childrenNew);
                    }
                }

                // Check for changes affecting children
                if (diff.DiffPeptideProps || diff.DiffExplicit ||
                    diff.DiffTransitionGroups || diff.DiffTransitionGroupProps ||
                    diff.DiffTransitions || diff.DiffTransitionProps ||
                    diff.DiffResults)
                {
                    IList <DocNode> childrenNew = new List <DocNode>();

                    // Enumerate the nodes making necessary changes.
                    foreach (PeptideDocNode nodePeptide in nodeResult.Children)
                    {
                        childrenNew.Add(nodePeptide.ChangeSettings(settingsNew, diff));
                    }

                    childrenNew = RankChildren(settingsNew, childrenNew);

                    nodeResult = (PeptideGroupDocNode)nodeResult.ChangeChildrenChecked(childrenNew);
                }
                return(nodeResult);
            }
        }
Example #8
0
        public ViewLibraryPepInfo AssociateMatchingPeptide(ViewLibraryPepInfo pepInfo, Adduct charge, SrmSettingsDiff settingsDiff)
        {
            var key = pepInfo.Key;

            if (key.IsPrecursorKey)
            {
                return(pepInfo);
            }

            var settings = _chargeSettingsMap[charge];

            // Change current document settings to match the current library and change the charge filter to
            // match the current peptide.
            if (settings == null)
            {
                settings = _document.Settings;
                var rankId = settings.PeptideSettings.Libraries.RankId;
                if (rankId != null && !_selectedSpec.PeptideRankIds.Contains(rankId))
                {
                    settings = settings.ChangePeptideLibraries(lib => lib.ChangeRankId(null));
                }
                var isProteomic = pepInfo.Target.IsProteomic;
                settings = settings.ChangePeptideLibraries(
                    lib => lib.ChangeLibraries(new[] { _selectedSpec }, new[] { _selectedLibrary })
                    .ChangePick(PeptidePick.library))
                           .ChangeTransitionFilter(
                    filter => (isProteomic ?
                               filter.ChangePeptidePrecursorCharges(new[] { charge }) :
                               filter.ChangeSmallMoleculePrecursorAdducts(new[] { charge }))
                    .ChangeAutoSelect(true))
                           .ChangeMeasuredResults(null);

                _chargeSettingsMap[charge] = settings;
            }

            var nodePep = _matcher.GetModifiedNode(key, settings, settingsDiff);

            if (nodePep != null)
            {
                pepInfo = pepInfo.ChangePeptideNode(nodePep);
            }
            return(pepInfo);
        }
        public ViewLibraryPepInfo AssociateMatchingPeptide(ViewLibraryPepInfo pepInfo, int charge, SrmSettingsDiff settingsDiff)
        {
            var key = pepInfo.Key;

            var settings = _chargeSettingsMap[charge];

            // Change current document settings to match the current library and change the charge filter to
            // match the current peptide.
            if (settings == null)
            {
                settings = _document.Settings;
                var rankId = settings.PeptideSettings.Libraries.RankId;
                if (rankId != null && !_selectedSpec.PeptideRankIds.Contains(rankId))
                {
                    settings = settings.ChangePeptideLibraries(lib => lib.ChangeRankId(null));
                }

                settings = settings.ChangePeptideLibraries(
                    lib => lib.ChangeLibraries(new[] { _selectedSpec }, new[] { _selectedLibrary })
                    .ChangePick(PeptidePick.library))
                           .ChangeTransitionFilter(
                    filter => filter.ChangePrecursorCharges(new[] { charge }).ChangeAutoSelect(true))
                           .ChangeMeasuredResults(null);

                _chargeSettingsMap[charge] = settings;
            }

            var nodePep = _matcher.GetModifiedNode(key, pepInfo.GetAASequence(_lookupPool), settings, settingsDiff);

            if (nodePep != null)
            {
                pepInfo.PeptideNode = nodePep;
            }
            return(pepInfo);
        }
Example #10
0
        public ViewLibraryPepInfo AssociateMatchingPeptide(ViewLibraryPepInfo pepInfo, Adduct charge, SrmSettingsDiff settingsDiff)
        {
            var key = pepInfo.Key;

            if (key.IsPrecursorKey)
            {
                return(pepInfo);
            }

            var settings = _chargeSettingsMap[charge];

            // Change current document settings to match the current library and change the charge filter to
            // match the current peptide.
            if (settings == null)
            {
                settings = _document.Settings;
                var rankId = settings.PeptideSettings.Libraries.RankId;
                if (rankId != null && !_selectedSpec.PeptideRankIds.Contains(rankId))
                {
                    settings = settings.ChangePeptideLibraries(lib => lib.ChangeRankId(null));
                }
                var isProteomic = pepInfo.Target.IsProteomic;
                settings = settings.ChangePeptideLibraries(
                    lib => lib.ChangeLibraries(new[] { _selectedSpec }, new[] { _selectedLibrary })
                    .ChangePick(PeptidePick.library))
                           .ChangeTransitionFilter(
                    filter => (isProteomic ?
                               filter.ChangePeptidePrecursorCharges(new[] { charge }) :
                               filter.ChangeSmallMoleculePrecursorAdducts(new[] { charge }))
                    .ChangeAutoSelect(true))
                           .ChangeMeasuredResults(null);
                var staticMods = settings.PeptideSettings.Modifications.StaticModifications.ToList();
                foreach (var crosslinkMod in Properties.Settings.Default.StaticModList.Where(mod =>
                                                                                             null != mod.CrosslinkerSettings))
                {
                    if (!staticMods.Any(mod => mod.Name == crosslinkMod.Name))
                    {
                        staticMods.Add(crosslinkMod);
                    }
                }

                settings = settings.ChangePeptideSettings(
                    settings.PeptideSettings.ChangeModifications(
                        settings.PeptideSettings.Modifications.ChangeStaticModifications(staticMods)));


                _chargeSettingsMap[charge] = settings;
            }

            var nodePep = _matcher.GetModifiedNode(key, settings, settingsDiff);

            if (nodePep != null)
            {
                pepInfo = pepInfo.ChangePeptideNode(nodePep);
            }
            return(pepInfo);
        }