Source code for ms_deisotope.deconvolution.api

"""
High Level Deconvolution API
----------------------------

A high-level wrapper around the deconvolution machinery, orchestrating the
process of constructing a deconvoluter instance, performing deconvolution, and
extracting targets of interest from the result.
"""

from ms_peak_picker import FittedPeak

from ms_deisotope.peak_set import merge
from ms_deisotope.utils import DeconvolutionProcessResult
from ms_deisotope.constants import (
    ERROR_TOLERANCE,
    TRUNCATE_AFTER,
    MAX_ITERATION,
    SCALE_METHOD)

from ms_deisotope.averagine import PROTON

from .averagine_based import AveraginePeakDependenceGraphDeconvoluter
from .utils import logger, prepare_peaklist


[docs]def deconvolute_peaks(peaklist, decon_config=None, charge_range=(1, 8), error_tolerance=ERROR_TOLERANCE, priority_list=None, left_search_limit=1, right_search_limit=0, left_search_limit_for_priorities=None, right_search_limit_for_priorities=None, verbose_priorities=False, verbose=False, charge_carrier=PROTON, truncate_after=TRUNCATE_AFTER, iterations=MAX_ITERATION, deconvoluter_type=AveraginePeakDependenceGraphDeconvoluter, retention_strategy=None, use_quick_charge=False, **kwargs): """Deconvolute a centroided mass spectrum. This function constructs a deconvoluter object using the ``deconvoluter_type`` argument and deconvolutes the input ``peaklist`` by calling its :meth:`deconvolute` method. If ``priority_list`` is not :const:`None`, it is expected to be an iterable of either tuples of (:class:`~.FittedPeak`, ``(min charge, max charge)``) pairs, or instances of :class:`~.PriorityTarget`. These will be passed to :meth:`targeted_deconvolution` of the deconvoluter. Parameters ---------- peaklist : :class:`~.PeakSet` or list of Peak-like objects, see :func:`~.prepare_peaklist` The centroided mass spectrum to deconvolute. decon_config : dict, optional Parameters to use to initialize the deconvoluter instance produced by ``deconvoluter_type`` charge_range : tuple of integers, optional The range of charge states to consider. The range is inclusive. error_tolerance : float, optional PPM error tolerance to use to match experimental to theoretical peaks priority_list : list, optional The set of peaks to target for deconvolution to be able to enforce external constraints on, such as selected precursors for fragmentation. left_search_limit : int, optional The maximum number of neutron shifts to search to the left (decrease) from each query peak right_search_limit : int, optional The maximum number of neutron shifts to search to the right (increase) from each query peak left_search_limit_for_priorities : int, optional The maximum number of neutron shifts to search to the left (decrease) from each query peak for priority targets right_search_limit_for_priorities : int, optional The maximum number of neutron shifts to search to the right (increase) from each query peak for priority targets verbose_priorities : bool, optional Whether to turn on verbose mode for priority targets verbose : bool, optional Passed to the deconvoluter to enable verbose mode globally charge_carrier : float, optional The mass of the charge carrier. Defaults to |PROTON| truncate_after : float, optional The percentage of the isotopic pattern to include. Defaults to |TRUNCATE_AFTER| deconvoluter_type : type or callable, optional A callable returning a deconvoluter. Defaults to :class:`~.AveraginePeakDependenceGraphDeconvoluter` retention_strategy: :class:`~.PeakRetentionStrategyBase` or callable, optional A callable that may compute additional peaks to include in the output deconvoluted peaks. use_quick_charge: :class:`bool` Whether or not to use the :title-reference:`QuickCharge` algorithm to quickly filter theoretical charge states to consider for each peak. **kwargs Additional keywords included in ``decon_config`` See Also -------- :func:`ms_deisotope.peak_set.decharge` Notes ----- If speed is an issue, consider setting `use_quick_charge` :const:`True`. This will pre-screen charge states that are are missing peaks supporting the :term:`monoisotopic peak` or the :term:`A+1 peak`. Alternatively, you may set the charge range upper bound to something reasonable for your data, such as the precursor ion's charge when considering a product ion spectrum. When you do not expect a complete isotopic pattern for large ions, as is often the case for low abundance FT-MS/MS it may be useful to shrink the `truncate_after` parameter from the default (|TRUNCATE_AFTER|) to a slightly smaller value. Returns ------- :class:`~.DeconvolutionProcessResult` """ if priority_list is None: priority_list = [] if left_search_limit_for_priorities is None: left_search_limit_for_priorities = left_search_limit if right_search_limit_for_priorities is None: right_search_limit_for_priorities = right_search_limit decon_config = decon_config or {} decon_config.update(kwargs) decon_config.setdefault("use_subtraction", True) decon_config.setdefault("scale_method", SCALE_METHOD) decon_config.setdefault("use_quick_charge", use_quick_charge) peaklist = prepare_peaklist(peaklist) decon = deconvoluter_type(peaklist=peaklist, **decon_config) if verbose_priorities or verbose: decon.verbose = True priority_list_results = [] for p in priority_list: try: target_info = p p = target_info.peak hinted_charge_range = target_info.charge_range_hint(charge_range) except AttributeError: hinted_charge_range = charge_range if not isinstance(p, FittedPeak): p = decon.peaklist.has_peak(p, error_tolerance) priority_result = decon.targeted_deconvolution( p, error_tolerance=error_tolerance, charge_range=hinted_charge_range, left_search_limit=left_search_limit_for_priorities, right_search_limit=right_search_limit_for_priorities, charge_carrier=charge_carrier, truncate_after=truncate_after) priority_list_results.append(priority_result) if verbose_priorities and not verbose: decon.verbose = False deconvoluted_peaks = decon.deconvolute( error_tolerance=error_tolerance, charge_range=charge_range, left_search_limit=left_search_limit, right_search_limit=right_search_limit, charge_carrier=charge_carrier, truncate_after=truncate_after, iterations=iterations) acc = [] errors = [] for pr in priority_list_results: try: result = pr.get() except Exception as e: result = None errors.append(e) logger.error("Could not extract a solution for %r", pr.query_peak, exc_info=True) acc.append(result) priority_list_results = acc if retention_strategy is not None: retained = retention_strategy( decon.peaklist, peaklist, charge_range, deconvoluted_peaks) deconvoluted_peaks = merge(deconvoluted_peaks, retained) return DeconvolutionProcessResult( decon, deconvoluted_peaks, priority_list_results, errors)