def gen_background(xs, background_params, background_mode=None): """Generate background values, from parameter definition. Parameters ---------- xs : 1d array Frequency vector to create background from. background_params : list of float Paramters that define the background process. background_mode : {'fixed', 'knee'}, optional Which kind of background to generate power spectra with. If not provided, is infered from the parameters. Returns ------- 1d array Generated background values """ if not background_mode: background_mode = infer_bg_func(background_params) bg_func = get_bg_func(background_mode) return bg_func(xs, *background_params)
def _simple_bg_fit(self, freqs, power_spectrum): """Fit the 1/f background of power spectrum. Parameters ---------- freqs : 1d array Frequency values for the power_spectrum, in linear scale. power_spectrum : 1d array Power spectrum values, in log10 scale. Returns ------- background_params : 1d array Parameter estimates for background fit. """ # Set guess params for lorentzian background fit, guess params set at init guess = np.array(([power_spectrum[0]] if not self._bg_guess[0] else [self._bg_guess[0]]) + ([self._bg_guess[1]] if self.background_mode == 'knee' else []) + [self._bg_guess[2]]) # Ignore warnings that are raised in curve_fit # A runtime warning can occur while exploring parameters in curve fitting # This doesn't effect outcome - it won't settle on an answer that does this # It happens if / when b < 0 & |b| > x**2, as it leads to log of a negative number with warnings.catch_warnings(): warnings.simplefilter("ignore") background_params, _ = curve_fit(get_bg_func(self.background_mode), freqs, power_spectrum, p0=guess, maxfev=5000, bounds=self._bg_bounds) return background_params
def _robust_bg_fit(self, freqs, power_spectrum): """Fit the 1/f background of power spectrum robustly, ignoring outliers. Parameters ---------- freqs : 1d array Frequency values for the power spectrum, in linear scale. power_spectrum : 1d array Power spectrum values, in log10 scale. Returns ------- background_params : 1d array Parameter estimates for background fit. """ # Do a quick, initial background fit. popt = self._simple_bg_fit(freqs, power_spectrum) initial_fit = gen_background(freqs, popt) # Flatten power_spectrum based on initial background fit. flatspec = power_spectrum - initial_fit # Flatten outliers - any points that drop below 0. flatspec[flatspec < 0] = 0 # Amplitude threshold - in terms of # of points. perc_thresh = np.percentile(flatspec, self._bg_amp_thresh) amp_mask = flatspec <= perc_thresh freqs_ignore = freqs[amp_mask] spectrum_ignore = power_spectrum[amp_mask] # Second background fit - using results of first fit as guess parameters. # See note in _simple_bg_fit about warnings with warnings.catch_warnings(): warnings.simplefilter("ignore") background_params, _ = curve_fit(get_bg_func(self.background_mode), freqs_ignore, spectrum_ignore, p0=popt, maxfev=5000, bounds=self._bg_bounds) return background_params