Ejemplo n.º 1
0
        public PeptideDocNode ChangeSettings(SrmSettings settingsNew, SrmSettingsDiff diff, bool recurse = true)
        {
            if (diff.Monitor != null)
                diff.Monitor.ProcessMolecule(this);

            // If the peptide has explicit modifications, and the modifications have
            // changed, see if any of the explicit modifications have changed
            var explicitMods = ExplicitMods;
            if (HasExplicitMods &&
                !diff.IsUnexplainedExplicitModificationAllowed &&
                diff.SettingsOld != null &&
                !ReferenceEquals(settingsNew.PeptideSettings.Modifications,
                                 diff.SettingsOld.PeptideSettings.Modifications))
            {
                explicitMods = ExplicitMods.ChangeGlobalMods(settingsNew);
                if (explicitMods == null || !ArrayUtil.ReferencesEqual(explicitMods.GetHeavyModifications().ToArray(),
                                                                       ExplicitMods.GetHeavyModifications().ToArray()))
                {
                    diff = new SrmSettingsDiff(diff, SrmSettingsDiff.ALL);
                }
                else if (!ReferenceEquals(explicitMods.StaticModifications, ExplicitMods.StaticModifications))
                {
                    diff = new SrmSettingsDiff(diff, SrmSettingsDiff.PROPS);
                }
            }

            TransitionSettings transitionSettings = settingsNew.TransitionSettings;
            PeptideDocNode nodeResult = this;
            if (!ReferenceEquals(explicitMods, ExplicitMods))
                nodeResult = nodeResult.ChangeExplicitMods(explicitMods);
            nodeResult = nodeResult.UpdateModifiedSequence(settingsNew);

            if (diff.DiffPeptideProps)
            {
                var rt = settingsNew.PeptideSettings.Prediction.RetentionTime;
                bool isStandard = Equals(nodeResult.GlobalStandardType, STANDARD_TYPE_IRT);
                if (rt != null)
                {
                    bool isStandardNew = rt.IsStandardPeptide(nodeResult);
                    if (isStandard ^ isStandardNew)
                        nodeResult = nodeResult.ChangeStandardType(isStandardNew ? STANDARD_TYPE_IRT : null);
                }
                else if (isStandard)
                {
                    nodeResult = nodeResult.ChangeStandardType(null);
                }
            }

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

                PeptideRankId rankId = settingsNew.PeptideSettings.Libraries.RankId;
                bool useHighestRank = (rankId != null && settingsNew.PeptideSettings.Libraries.PeptideCount.HasValue);
                bool isPickedIntensityRank = useHighestRank &&
                                             ReferenceEquals(rankId, LibrarySpec.PEP_RANK_PICKED_INTENSITY);

                Dictionary<Identity, DocNode> mapIdToChild = CreateIdContentToChildMap();
                foreach (TransitionGroup tranGroup in GetTransitionGroups(settingsNew, explicitMods, true))
                {
                    TransitionGroupDocNode nodeGroup;
                    SrmSettingsDiff diffNode = diff;

                    DocNode existing;
                    // Add values that existed before the change, unless using picked intensity ranking,
                    // since this could bias the ranking, otherwise.
                    if (!isPickedIntensityRank && mapIdToChild.TryGetValue(tranGroup, out existing))
                        nodeGroup = (TransitionGroupDocNode)existing;
                    // Add new node
                    else
                    {
                        TransitionDocNode[] transitions = !isPickedIntensityRank
                            ? GetMatchingTransitions(tranGroup, settingsNew, explicitMods)
                            : null;

                        nodeGroup = new TransitionGroupDocNode(tranGroup, transitions);
                        // If not recursing, then ChangeSettings will not be called on nodeGroup.  So, make
                        // sure its precursor m/z is set correctly.
                        if (!recurse)
                            nodeGroup = nodeGroup.ChangePrecursorMz(settingsNew, explicitMods);
                        diffNode = SrmSettingsDiff.ALL;
                    }

                    if (nodeGroup != null)
                    {
                        TransitionGroupDocNode nodeChanged = recurse
                            ? nodeGroup.ChangeSettings(settingsNew, nodeResult, explicitMods, diffNode)
                            : nodeGroup;
                        if (transitionSettings.IsMeasurablePrecursor(nodeChanged.PrecursorMz))
                            childrenNew.Add(nodeChanged);
                    }
                }

                // If only using rank limited peptides, then choose only the single
                // highest ranked precursor charge.
                if (useHighestRank)
                {
                    childrenNew = FilterHighestRank(childrenNew, rankId);

                    // If using picked intensity, make sure original nodes are replaced
                    if (isPickedIntensityRank)
                    {
                        for (int i = 0; i < childrenNew.Count; i++)
                        {
                            var nodeNew = (TransitionGroupDocNode) childrenNew[i];
                            DocNode existing;
                            if (mapIdToChild.TryGetValue(nodeNew.TransitionGroup, out existing))
                                childrenNew[i] = existing;
                        }
                    }
                }

                nodeResult = (PeptideDocNode) nodeResult.ChangeChildrenChecked(childrenNew);
            }
            else
            {
                // Even with auto-select off, transition groups for which there is
                // no longer a precursor calculator must be removed.
                if (diff.DiffTransitionGroups && nodeResult.HasHeavyTransitionGroups)
                {
                    IList<DocNode> childrenNew = new List<DocNode>();
                    foreach (TransitionGroupDocNode nodeGroup in nodeResult.Children)
                    {
                        if (settingsNew.HasPrecursorCalc(nodeGroup.TransitionGroup.LabelType, explicitMods))
                            childrenNew.Add(nodeGroup);
                    }

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

                // Update properties and children, if necessary
                if (diff.DiffTransitionGroupProps ||
                    diff.DiffTransitions || diff.DiffTransitionProps ||
                    diff.DiffResults)
                {
                    IList<DocNode> childrenNew = new List<DocNode>();

                    // Enumerate the nodes making necessary changes.
                    foreach (TransitionGroupDocNode nodeGroup in nodeResult.Children)
                    {
                        TransitionGroupDocNode nodeChanged = nodeGroup.ChangeSettings(settingsNew, nodeResult, explicitMods, diff);
                        // Skip if the node can no longer be measured on the target instrument
                        if (!transitionSettings.IsMeasurablePrecursor(nodeChanged.PrecursorMz))
                            continue;
                        // Skip this node, if it is heavy and the update caused it to have the
                        // same m/z value as the light value.
                        if (!nodeChanged.TransitionGroup.LabelType.IsLight &&
                            !Peptide.IsCustomIon) // No mods on customs
                        {
                            double precursorMassLight = settingsNew.GetPrecursorMass(
                                IsotopeLabelType.light, Peptide.Sequence, explicitMods);
                            double precursorMzLight = SequenceMassCalc.GetMZ(precursorMassLight,
                                                                             nodeChanged.TransitionGroup.PrecursorCharge);
                            if (nodeChanged.PrecursorMz == precursorMzLight)
                                continue;
                        }

                        childrenNew.Add(nodeChanged);
                    }

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

            if (diff.DiffResults || ChangedResults(nodeResult))
                nodeResult = nodeResult.UpdateResults(settingsNew /*, diff*/);

            return nodeResult;
        }