Exemplo n.º 1
0
    def __init__(
        self,
        signal,
        dt,
        Tmin,
        Tmax,
        position,
        signal_id,
        step_num,
        pow_max,
        time_unit,
        DEBUG=False,
    ):

        super().__init__()

        self.DEBUG = DEBUG

        self.signal_id = signal_id
        self.signal = signal
        self.pow_max = pow_max
        self.time_unit = time_unit

        self.periods = np.linspace(Tmin, Tmax, step_num)

        # generate time vector
        self.tvec = np.arange(0, len(signal)) * dt

        # no ridge yet
        self.ridge = None
        self.ridge_data = None
        self.power_thresh = None
        self.rsmoothing = None
        self._has_ridge = False  # no plotted ridge

        # no anneal parameters yet
        self.anneal_pars = None

        # =============Compute Spectrum========================================
        self.modulus, self.wlet = core.compute_spectrum(
            self.signal, dt, self.periods)
        # =====================================================================

        # Wavelet ridge-readout results
        self.ResultWindows = {}
        self.w_offset = 0

        self.initUI(position)
Exemplo n.º 2
0
    def compute_spectrum(self,
                         raw_signal,
                         sinc_detrend=True,
                         norm_amplitude=False,
                         do_plot=True,
                         draw_coi=False):
        """
        Computes the Wavelet spectrum for a given *signal* for the given *periods*
        
        signal  : a sequence, the time-series to be analyzed

        sinc_detrend : boolean, if True sinc-filter detrending 
                       will be done with the set T_cut_off parameter

        norm_amplitude : boolean, if True sliding window amplitude envelope
                          estimation is performed, and normalisation with
                          1/envelope
        
        do_plot      : boolean, set to False if no plot is desired, 
                       good for for batch processing

        draw_coi: boolean, set to True if cone of influence 
                           shall be drawn on the wavelet power spectrum
                   
        
        After a successful analysis, the analyser instance updates 

        self.wlet 
        self.modulus

        with the results.
        
        """

        if sinc_detrend:
            detrended = self.sinc_detrend(raw_signal)
            ana_signal = detrended
        else:
            ana_signal = raw_signal

        # only after potential detrending!
        if norm_amplitude:
            ana_signal = self.normalize_amplitude(ana_signal)

        self.ana_signal = ana_signal

        modulus, wlet = core.compute_spectrum(ana_signal, self.dt,
                                              self.periods)

        if do_plot:

            tvec = np.arange(len(ana_signal)) * self.dt

            axs = pl.mk_signal_modulus_ax(self.time_unit_label)
            pl.plot_signal_modulus(
                axs,
                time_vector=tvec,
                signal=ana_signal,
                modulus=modulus,
                periods=self.periods,
                p_max=self.p_max,
            )

            fig = ppl.gcf()
            fig.tight_layout()
            self.ax_spec = axs[1]

            if draw_coi:
                coi_m = core.Morlet_COI()
                pl.draw_COI(axs[1], time_vector=tvec)

        self.wlet = wlet
        self.modulus = modulus
        self._has_spec = True
Exemplo n.º 3
0
    def compute_spectrum(self,
                         raw_signal,
                         T_c=None,
                         window_size=None,
                         do_plot=True,
                         draw_coi=False):

        """
        Computes the Wavelet spectrum for a given *raw_signal*.

        Parameters
        ----------        
        signal  : a sequence, the time-series to be analyzed
        T_c : float, optional
              Cut off period for the sinc-filter detrending, all periods
              larger than that one are removed from the signal. If not given,
              no sinc-detending will be done.
        window_size : float, optional
                      Length of the sliding window for amplitude
                      envelope estimation in real time units, e.g. 17 minutes.
                      If not given no amplitude normalization will be done.    
        do_plot      : boolean, set to False if no plot is desired, 
                       good for batch processing
        draw_coi: boolean, set to True if cone of influence 
                           shall be drawn on the wavelet power spectrum
                           
        Returns
        -------
        modulus : 2d ndarray
              the real Wavelet power spectrum normalized by signal
              variance, has shape len(periods) x len(signal). Is set to None
              before any analysis is done.
        transform : 2d ndarray 
                the complex results of the Wavelet transform with 
                shape len(periods) x len(signal). Is set to None
                before any analysis is done.

        After a successful analysis, the analyzer instance updates 

        self.transform 
        self.modulus

        with the results. If do_plot was set to True, the attributes

        self.ax_spec_signal
        self.ax_spec

        allow to access the created subplots directly.
        """

        if T_c:
            detrended = self.sinc_detrend(raw_signal, T_c)
            ana_signal = detrended
        else:
            ana_signal = raw_signal

        # only after potential detrending!
        if window_size:
            ana_signal = self.normalize_amplitude(ana_signal, window_size)

        self.ana_signal = ana_signal

        modulus, transform = core.compute_spectrum(ana_signal, self.dt, self.periods)

        if do_plot:

            tvec = np.arange(len(ana_signal)) * self.dt

            axs = pl.mk_signal_modulus_ax(self.time_unit_label)
            pl.plot_signal_modulus(
                axs,
                time_vector=tvec,
                signal=ana_signal,
                modulus=modulus,
                periods=self.periods,
                p_max=self.p_max,
            )

            fig = ppl.gcf()
            fig.tight_layout()
            # some space for a title
            fig.subplots_adjust(top=0.95)            
            self.ax_spec_signal = axs[0]
            self.ax_spec = axs[1]

            if draw_coi:
                pl.draw_COI(axs[1], time_vector=tvec)

        self.transform = transform
        self.modulus = modulus

        # return also directly
        return modulus, transform
Exemplo n.º 4
0
def transform_stack(movie, dt, Tmin, Tmax, nT, T_c = None, win_size = None):

    '''
    Analyzes a 3-dimensional array 
    with shape (NFrames, ydim, xdim) along
    its 1st axis 'pixel-by-pixel'.

    Returns four arrays with the same shape as the input
    array holding the results of the transform for each pixel.

    For high spatial resolution input this might take a very
    long time as ydim \times xdim transformations have to be calculated!
    Parallel execution is recommended (see `run_parallel` below).

    Parameters
    ----------

    movie : ndarray with ndim = 3, transform is done along 1st axis 
    dt    : float, sampling interval               
    Tmin : float, smallest period
    Tmax : float, largest period
    nT  : int,  number of periods/transforms
    T_c : float, sinc cut off period, defaults to None to disable 
                 sinc-detrending (not recommended!)
    win_size   : float, amplitude normalization sliding window size. 
                 Default is None which disables normalization.

    Returns
    -------
    
    results : dictionary, with keys holding the output movies
          'phase' : 32bit ndarray, holding the instantaneous phases
          'period' : 32bit ndarray, holding the instantaneous periods 
          'power' : 32bit ndarray, holding the wavelet powers 
          'amplitude' : 32bit ndarray, holding the instantaneous amplitudes 

    '''

    if Tmin < 2 * dt:
        logger.warning('Warning, Nyquist limit is 2 times the sampling interval!')
        logger.info('..setting Tmin to {:.2f}'.format( 2 * dt ))
        Tmin = 2 * dt

    if Tmax > dt * movie.shape[0]: 
        logger.warning('Warning: Very large periods chosen!')
        logger.info('..setting Tmax to {:.2f}'.format( dt * Nt ))
        Tmax = dt * Nt
    
    # the periods to scan for
    periods = np.linspace(Tmin, Tmax, nT)
    
    # create output arrays, needs 32bit for Fiji FloatProcessor :/
    period_movie = np.zeros(movie.shape, dtype=np.float32)  
    phase_movie = np.zeros(movie.shape, dtype=np.float32)  
    power_movie = np.zeros(movie.shape, dtype=np.float32)  
    amplitude_movie = np.zeros(movie.shape, dtype=np.float32)  

    ydim, xdim = movie.shape[1:] # F, Y, X ordering
    
    Npixels = ydim * xdim
    
    logger.info(f'Computing the transforms for {Npixels} pixels')
    sys.stdout.flush()

    # loop over pixel coordinates
    for x in range(xdim):

        for y in range(ydim):

            # show progress
            if Npixels < 10:
                logger.info(f"Processed {(ydim*x + y)/Npixels * 100 :.1f}%..")
                sys.stdout.flush()

            elif (ydim*x + y)%(int(Npixels/5)) == 0 and x != 0:
                logger.info(f"Processed {(ydim*x + y)/Npixels * 100 :.1f}%..")
            
            input_vec = movie[:, y, x]  # the time_series at pixel (x,y)

            signal = input_vec
            
            # detrending
            if T_c is not None:
                trend = pbcore.sinc_smooth(signal, T_c, dt)
                signal = signal - trend
                
            # amplitude normalization?
            if win_size is not None:
                signal = pbcore.normalize_with_envelope(signal, win_size, dt)

            sigma = np.std(signal)
            Nt = len(signal)
            
            modulus, wlet = pbcore.compute_spectrum(signal, dt, periods)
            ridge_ys = pbcore.get_maxRidge_ys(modulus)

            ridge_periods = periods[ridge_ys]
            powers = modulus[ridge_ys, np.arange(Nt)]
            phases = np.angle(wlet[ridge_ys, np.arange(Nt)])
            # map to [0, 2pi]
            phases = phases % (2 * np.pi)
            amplitudes = pbcore.power_to_amplitude(ridge_periods,
                                                    powers, sigma, dt)
            
            phase_movie[:, y, x] = phases
            period_movie[:, y, x] = ridge_periods
            power_movie[:, y, x] = powers
            amplitude_movie[:, y, x] = amplitudes

    results = {'phase' : phase_movie, 'period' : period_movie,
               'power' : power_movie, 'amplitude' : amplitude_movie}
    
    return results