def do_maxRidge_detection(self): ridge_y = core.get_maxRidge_ys(self.modulus) self.ridge = ridge_y if not np.any(ridge_y): self.e = MessageWindow("No ridge found..check spectrum!", "Ridge detection error") return self._has_ridge = True self.draw_ridge() # ridge_data made here
def do_maxRidge_detection(self): ridge_y = core.get_maxRidge_ys(self.modulus) self.ridge = ridge_y if not np.any(ridge_y): msgBox = QMessageBox() msgBox.setWindowTitle("Ridge detection error") msgBox.setText("No ridge found..check spectrum!") msgBox.exec() return self._has_ridge = True self.draw_ridge() # ridge_data made here
def get_maxRidge(self, power_thresh=0, smoothing_wsize=None): """ Computes the ridge as consecutive maxima of the modulus. Returns the ridge_data dictionary (see core.eval_ridge)! """ if not self._has_spec: print("Need to compute a wavelet spectrum first!") return # for easy integration modulus = self.modulus Nt = modulus.shape[1] # number of time points tvec = np.arange(Nt) * self.dt # ================ridge detection===================================== # just pick the consecutive modulus # (squared complex wavelet transform) maxima as the ridge # has to be odd if smoothing_wsize % 2 == 0: smoothing_wsize = smoothing_wsize + 1 ridge_y = core.get_maxRidge_ys(modulus) rd = core.eval_ridge( ridge_y, self.wlet, self.ana_signal, self.periods, tvec=tvec, power_thresh=power_thresh, smoothing_wsize=smoothing_wsize, ) self.ridge_data = rd self._has_ridge = True # return also directly return rd
def get_sign_maxRidge(self, empirical_background, confidence=core.chi2_95, smoothing_wsize=None): """ Computes and evaluates the ridge as consecutive maxima of the modulus, thresholded by a significance test for the given background spectrum. Confidence defaults to 95% interval. Returns the ridge_data DataFrame, see also `core.eval_ridge`! Additionally the analyser instance updates self.ridge_data with the results. Parameters ---------- empirical_background : 1d sequence, Fourier estimate of the background. Must hold the powers at exactly the periods used for the wavelet analysis! confidence : float, the Chi-squared value at the desired confidence level. Defaults to the 95% confidence interval. smoothing_wsize : int, optional Savitkzy-Golay smoothing window size for ridge smoothing Returns ------- A DataFrame with the following columns: time : the t-values of the ridge, can have gaps if thresholding! periods : the instantaneous periods frequencies : the instantaneous frequencies phase : the instantaneous phases power : the Wavelet Power normalized to white noise (<P(WN)> = 1) amplitude : the estimated amplitudes of the signal """ if self.transform is None: logger.warning("Need to compute a wavelet spectrum first!") return # for easy integration modulus = self.modulus Nt = modulus.shape[1] # number of time points tvec = np.arange(Nt) * self.dt # has to be odd if smoothing_wsize and smoothing_wsize % 2 == 0: smoothing_wsize = smoothing_wsize + 1 # ================ridge detection===================================== ridge_ys = core.get_maxRidge_ys(modulus) rd = core.eval_ridge( ridge_ys, self.transform, self.ana_signal, self.periods, tvec=tvec, power_thresh=0, # we need the complete ridge here! smoothing_wsize=smoothing_wsize ) spectrum_bool = core.get_significant_regions(self.modulus, empirical_background) # boolean mask for the ridge ridge_bool = spectrum_bool[ridge_ys, rd.index] # the significant parts of the ridge sign_ridge = rd[ridge_bool] # attach additional data, total length and sampling interval sign_ridge.Nt = rd.Nt sign_ridge.dt = rd.dt self.ridge_data = sign_ridge # return also directly return sign_ridge
def get_maxRidge(self, power_thresh=0, smoothing_wsize=None): """ Computes and evaluates the ridge as consecutive maxima of the modulus. Returns the ridge_data DataFrame, see also `core.eval_ridge`! Additionally the analyser instance updates self.ridge_data with the results. Parameters ---------- power_thresh : float, threshold for the ridge. smoothing_wsize : int, optional Savitkzy-Golay smoothing window size for ridge smoothing Returns ------- A DataFrame with the following columns: time : the t-values of the ridge, can have gaps if thresholding! periods : the instantaneous periods frequencies : the instantaneous frequencies phase : the instantaneous phases power : the Wavelet Power normalized to white noise (<P(WN)> = 1) amplitude : the estimated amplitudes of the signal """ if self.transform is None: logger.warning("Need to compute a wavelet spectrum first!") return # for easy integration modulus = self.modulus Nt = modulus.shape[1] # number of time points tvec = np.arange(Nt) * self.dt # has to be odd if smoothing_wsize and smoothing_wsize % 2 == 0: smoothing_wsize = smoothing_wsize + 1 # ================ridge detection===================================== ridge_ys = core.get_maxRidge_ys(modulus) rd = core.eval_ridge( ridge_ys, self.transform, self.ana_signal, self.periods, tvec=tvec, power_thresh=power_thresh, smoothing_wsize=smoothing_wsize ) self.ridge_data = rd # return also directly return rd
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