spike.plugins.sane — spike 0.99.12-425 documentation

# Source code for spike.plugins.sane

    #!/usr/bin/env python
    # encoding: utf-8

    """plugin for Sane denoising

    This plugin implements the SANE denoising algorithm,
    SANE is inspired from urQRd algorithm, but is improved in several points

    - faster on vector length != 2**n
    - much more efficient on weak signals
    - requires less iterations and less overestimate of rank
    - however, a non productive iteration is always performed,
      so processing time for I iterations of SANE should be compared
      with I+1 iterations of urQRd.

    associated publications
    - Bray, F., Bouclon, J., Chiron, L., Witt, M., Delsuc, M.-A., & Rolando, C. (2017).
      Nonuniform Sampling Acquisition of Two-Dimensional Fourier Transform Ion Cyclotron Resonance Mass Spectrometry for Increased Mass Resolution of Tandem Mass Spectrometry Precursor Ions.
      Analytical Chemistry, acs.analchem.7b01850. http://doi.org/10.1021/acs.analchem.7b01850

    - Chiron, L., van Agthoven, M. A., Kieffer, B., Rolando, C., & Delsuc, M.-A. (2014).
      Efficient denoising algorithms for large experimental datasets and their applications in Fourier transform ion cyclotron resonance mass spectrometry.
      PNAS , 111(4), 1385–1390. http://doi.org/10.1073/pnas.1306700111
    """

    from __future__ import print_function
    import sys #
    import unittest

    from spike.NPKData import NPKData_plugin, as_cpx, as_float, _base_fft,\
                _base_ifft, _base_rfft, _base_irfft
    from spike.Algo.sane import sane
    if sys.version_info[0] < 3:
        pass
    else:
        xrange = range

    def sane_plugin(npkd, rank, orda=None, iterations=1, axis=0, trick=True, optk=False, ktrick=False):
        """
        Apply "sane" denoising to data
        rank is about 2 x number_of_expected_lines
        Manages real and complex cases.
        Handles the case of hypercomplex for denoising of 2D FTICR for example.

        sane algorithm. Name stands for Support Selection for Noise Elimination.
        From a data series return a denoised series denoised
        data : the series to be denoised - a (normally complex) numpy buffer
        rank : the rank of the analysis
        orda : is the order of the analysis
            internally, a Hankel matrix (M,N) is constructed, with M = orda and N = len(data)-orda+1
            if None (default) orda = (len(data)+1)/2
        iterations : the number of time the operation should be repeated
        optk : if set to True will calculate the rank giving the best recovery for an automatic estimated noise level.
        trick : permits to enhanced the denoising by using a cleaned signal as the projective space. "Support Selection"
        ktrick : if a value is given, it permits to change the rank on the second pass.
                 The idea is that for the first pass a rank large enough as to be used to compensate for the noise while
                 for the second pass a lower rank can be used.

        """
        if npkd.dim == 1:
            if npkd.axis1.itype == 0:   # real
                buff = as_cpx(_base_ifft(_base_rfft(npkd.buffer)))       # real case, go to analytical signal
            else:   #complex
                buff = npkd.get_buffer()                       # complex case, makes complex
            sane_result = sane(buff, rank, orda=orda, trick=trick, iterations=iterations) # performs denoising
            if npkd.axis1.itype == 0:   # real
                buff = _base_irfft(_base_fft(as_float(sane_result)))      # real case, comes back to real
                npkd.set_buffer(buff)
            else:
                npkd.buffer = as_float(sane_result)             # complex case, makes real
        elif npkd.dim == 2:
            todo = npkd.test_axis(axis)
            if todo == 2:
                for i in xrange(npkd.size1):
                    r = npkd.row(i).sane(rank=rank, orda=orda, iterations=iterations)
                    npkd.set_row(i,r)
            elif todo == 1:
                for i in xrange(npkd.size2):
                    r = npkd.col(i).sane(rank=rank, orda=orda, iterations=iterations)
                    npkd.set_col(i,r)
        elif npkd.dim == 3:
            raise Exception("not implemented yet")
        return npkd

    NPKData_plugin("sane", sane_plugin)