def gen_aperiodic(freqs, aperiodic_params, aperiodic_mode=None): """Generate aperiodic values. Parameters ---------- freqs : 1d array Frequency vector to create aperiodic component for. aperiodic_params : list of float Parameters that define the aperiodic component. aperiodic_mode : {'fixed', 'knee'}, optional Which kind of aperiodic component to generate. If not provided, is inferred from the parameters. Returns ------- ap_vals : 1d array Aperiodic values, in log10 spacing. """ if not aperiodic_mode: aperiodic_mode = infer_ap_func(aperiodic_params) ap_func = get_ap_func(aperiodic_mode) ap_vals = ap_func(freqs, *aperiodic_params) return ap_vals
def _robust_ap_fit(self, freqs, power_spectrum): """Fit the aperiodic component of the power spectrum robustly, ignoring outliers. Parameters ---------- freqs : 1d array Frequency values for the power spectrum, in linear scale. power_spectrum : 1d array Power values, in log10 scale. Returns ------- aperiodic_params : 1d array Parameter estimates for aperiodic fit. """ # Do a quick, initial aperiodic fit popt = self._simple_ap_fit(freqs, power_spectrum) initial_fit = gen_aperiodic(freqs, popt) # Flatten power_spectrum based on initial aperiodic fit flatspec = power_spectrum - initial_fit # Flatten outliers - any points that drop below 0 flatspec[flatspec < 0] = 0 # Use percential threshold, in terms of # of points, to extract and re-fit perc_thresh = np.percentile(flatspec, self._ap_percentile_thresh) perc_mask = flatspec <= perc_thresh freqs_ignore = freqs[perc_mask] spectrum_ignore = power_spectrum[perc_mask] # Second aperiodic fit - using results of first fit as guess parameters # See note in _simple_ap_fit about warnings with warnings.catch_warnings(): warnings.simplefilter("ignore") aperiodic_params, _ = curve_fit(get_ap_func(self.aperiodic_mode), freqs_ignore, spectrum_ignore, p0=popt, maxfev=5000, bounds=self._ap_bounds) return aperiodic_params
def _simple_ap_fit(self, freqs, power_spectrum): """Fit the aperiodic component of the power spectrum. Parameters ---------- freqs : 1d array Frequency values for the power_spectrum, in linear scale. power_spectrum : 1d array Power values, in log10 scale. Returns ------- aperiodic_params : 1d array Parameter estimates for aperiodic fit. """ # Set guess params for lorentzian aperiodic fit, guess params set at init guess = np.array( ([power_spectrum[0]] if not self._ap_guess[0] else [self._ap_guess[0]]) + ([self._ap_guess[1]] if self.aperiodic_mode == 'knee' else []) + [self._ap_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") aperiodic_params, _ = curve_fit(get_ap_func(self.aperiodic_mode), freqs, power_spectrum, p0=guess, maxfev=5000, bounds=self._ap_bounds) return aperiodic_params