def calculate(self, signal): self.full_sig_shape = signal.shape # Shape of input signal self.full_sig_spectral_size = signal.shape[ -1] # Length of spectral axis if self.rng is None: self.rng = _np.arange(self.full_sig_spectral_size) self.rng_sig_shape = signal[..., self.rng].shape self.rng_sig_spectral_size = self.rng_sig_shape[-1] # N signals to detrend self.n_sig_to_detrend = int(signal.size / self.full_sig_spectral_size) tmr = _timeit.default_timer() if self.redux == 1: self.redux_sig_shape = self.rng_sig_shape self.redux_sig_spectral_size = self.redux_sig_shape[-1] output = _np.zeros(self.full_sig_shape, dtype=signal.dtype) output[..., self.rng] = self._calc(signal[..., self.rng]) else: # Sub-sample # Dummy indep variable x = _np.arange(self.rng.size) x_sub = _np.linspace( x[0], x[-1], _np.round(x.size / self.redux).astype(_np.integer)) self.redux_sig_shape = list(self.full_sig_shape) self.redux_sig_shape[-1] = x_sub.size self.redux_sig_spectral_size = self.redux_sig_shape[-1] signal_sampled = _np.zeros(self.redux_sig_shape) # Spline interpolation/sub-sampling for coords in _np.ndindex(signal.shape[:-1]): spl = _USpline(x, signal[coords][self.rng], s=0) signal_sampled[coords] = spl(x_sub) # Baseline from sub-sampled signal output_sampled = self._calc(signal_sampled) output = _np.zeros(signal.shape) # Spline interpolation/super-sampling for coords in _np.ndindex(output_sampled.shape[0:-1]): spl2 = _USpline(x_sub, output_sampled[coords], s=0) output[[*coords, self.rng]] = spl2(x) tmr -= _timeit.default_timer() self.t = -tmr self.t_per_iter = self.t / self.n_sig_to_detrend return output
def calculate(self, signal): self.full_sig_shape = signal.shape # Shape of input signal self.full_sig_spectral_size = signal.shape[-1] # Length of spectral axis if self.rng is None: self.rng = _np.arange(self.full_sig_spectral_size) self.rng_sig_shape = signal[..., self.rng].shape self.rng_sig_spectral_size = self.rng_sig_shape[-1] # N signals to detrend self.n_sig_to_detrend = int(signal.size/self.full_sig_spectral_size) tmr = _timeit.default_timer() if self.redux == 1: self.redux_sig_shape = self.rng_sig_shape self.redux_sig_spectral_size = self.redux_sig_shape[-1] output = _np.zeros(self.full_sig_shape, dtype=signal.dtype) output[..., self.rng] = self._calc(signal[..., self.rng]) else: # Sub-sample # Dummy indep variable x = _np.arange(self.rng.size) x_sub = _np.linspace(x[0], x[-1], _np.round(x.size / self.redux).astype(_np.integer)) self.redux_sig_shape = list(self.full_sig_shape) self.redux_sig_shape[-1] = x_sub.size self.redux_sig_spectral_size = self.redux_sig_shape[-1] signal_sampled = _np.zeros(self.redux_sig_shape) # Spline interpolation/sub-sampling for coords in _np.ndindex(signal.shape[:-1]): spl = _USpline(x,signal[coords][self.rng],s=0) signal_sampled[coords] = spl(x_sub) # Baseline from sub-sampled signal output_sampled = self._calc(signal_sampled) output = _np.zeros(signal.shape) # Spline interpolation/super-sampling for coords in _np.ndindex(output_sampled.shape[0:-1]): spl2 = _USpline(x_sub,output_sampled[coords],s=0) output[[*coords, self.rng]] = spl2(x) tmr -= _timeit.default_timer() self.t = -tmr self.t_per_iter = self.t/self.n_sig_to_detrend return output
def asym_param(self): if _np.size(self._asym_param) == 1: return self._asym_param elif self.redux == 1: return self._asym_param[self.rng] elif self.redux > 1: x = _np.arange(self.rng.size) x_sub = _np.linspace(x[0], x[-1], _np.round(x.size / self.redux).astype(_np.integer)) spl = _USpline(x,self._asym_param[self.rng],s=0) return spl(x_sub)
def asym_param(self): if _np.size(self._asym_param) == 1: return self._asym_param elif self.redux == 1: return self._asym_param[self.rng] elif self.redux > 1: x = _np.arange(self.rng.size) x_sub = _np.linspace( x[0], x[-1], _np.round(x.size / self.redux).astype(_np.integer)) spl = _USpline(x, self._asym_param[self.rng], s=0) return spl(x_sub)
def als_baseline_redux(signal_input, redux_factor=10, redux_full=True, smoothness_param=1, asym_param=1e-2, cholesky_type=_cholesky_type,print_iteration=True): """ Compute the baseline_current of signal_input using an asymmetric least squares algorithm designed by P. H. C. Eilers. This method is actually a wrapper to the particular implementations. NOTE: This method is the exact same as als_baseline EXCEPT it has a \ performance enhancement by using interpolation to reduce the size of \ signal_input. Parameters ---------- signal_input : ndarray (1D) redux_factor : int Redeuction in size of signal_input via interpolation. Returned value \ is re-interpolated redux_full : bool (default, True) Perform size-reduction using interpolation. This minimizes right-side \ edge-effects. If false, the size reduction is from sub-sampling \ i.e., signal_sub = signal[0::redux_factor] smoothness_param : float, optional (default, 1e3) Smoothness parameter asym_param : float, optional (default, 1e-4) Assymetry parameter cholesky_type : string, optional (default _cholesky_type) Algoirthmic type of Cholesky factorization to use. The default behavior is the method determined upon loading of this (sub-)module. The order of precedence is 1. cvxopt.cholmod (sparse, uses CHOLMOD API) 2. scitkits.sparse (sparse, uses LAPACK/ATLAS API) 3. scipy.linalg (dense) Returns ------- out : [ndarray, string] Baseline vector Notes ----- The optimal implementation of Cholesky factorization for your particular application may not be that selected by the order-of- presedence. CHOLMOD was selected as the top presendence method as it has the least computational penalty due to particular array length. For certain array lengths, however, LAPACK/ATLAS is faster. You can set the particular method via the optional input argument 'cholesky_type'. This is the first attempt at converting MATLAB (Mathworks, Inc) scripts into Python code; thus, there will be bugs, the efficiency will be low(-ish), and I appreciate any useful suggestions or bug-finds. References ---------- [1] P. H. C. Eilers, "A perfect smoother," Anal. Chem. 75, 3631-3636 (2003). [2] P. H. C. Eilers and H. F. M. Boelens, "Baseline correction with asymmetric least squares smoothing," Report. October 21, 2005. [3] C. H. Camp Jr, Y. J. Lee, and M. T. Cicerone, "Quantitative, Comparable Coherent Anti-Stokes Raman Scattering (CARS) Spectroscopy: Correcting Errors in Phase Retrieval" """ signal_shape_orig = signal_input.shape signal_ndim = _np.ndim(signal_input) x = _np.arange(0, signal_shape_orig[-1], 1) # dummy indep variable # Sub-sample via interpolation or simple slicing if redux_full is True and redux_factor != 1: # Sub-sampled x x_sub = _np.linspace(x[0], x[-1], _np.round(x.size/redux_factor).astype(int)) elif redux_full is False and redux_factor != 1: x_sub = x[::redux_factor] else: # Do not reduce baseline, _ = als_baseline(signal_input, smoothness_param=smoothness_param, asym_param=asym_param, print_iteration=print_iteration) return [baseline, cholesky_type] if signal_ndim == 1: spl = _USpline(x, signal_input, s=0) sampled_signal = spl(x_sub) sub_baseline, _ = als_baseline(sampled_signal, smoothness_param=smoothness_param, asym_param=asym_param, print_iteration=print_iteration) spl2 = _USpline(x_sub, sub_baseline, s=0) baseline = spl2(x) elif signal_ndim == 2: sampled_signal = _np.zeros((signal_shape_orig[0],x_sub.size)) baseline = _np.zeros(signal_shape_orig) for num, sp in enumerate(signal_input): spl = _USpline(x,sp,s=0) sampled_signal[num,:] = spl(x_sub) sub_baseline,_ = als_baseline(sampled_signal, smoothness_param=smoothness_param, asym_param=asym_param, print_iteration=print_iteration) for num, sp in enumerate(sub_baseline): spl2 = _USpline(x_sub,sp,s=0) baseline[num,:] = spl2(x) elif signal_ndim == 3: sampled_signal = _np.zeros((signal_shape_orig[0],signal_shape_orig[1], x_sub.size)) baseline = _np.zeros(signal_shape_orig) for row_num, blk in enumerate(signal_input): for col_num, sp in enumerate(blk): spl = _USpline(x,sp,s=0) sampled_signal[row_num, col_num,:] = spl(x_sub) sub_baseline,_ = als_baseline(sampled_signal, smoothness_param=smoothness_param, asym_param=asym_param, print_iteration=print_iteration) for row_num, blk in enumerate(sub_baseline): for col_num, sp in enumerate(blk): spl2 = _USpline(x_sub,sp,s=0) baseline[row_num, col_num,:] = spl2(x) return [baseline, cholesky_type]