Ejemplo n.º 1
0
Archivo: fm.py Proyecto: parhalje/fooof
def _add_peaks_outline(fm, plt_log, ax, **plot_kwargs):
    """Add an outline of each peak.

    Parameters
    ----------
    fm : FOOOF
        FOOOF object containing results from fitting.
    plt_log : boolean
        Whether to plot the frequency values in log10 spacing.
    ax : matplotlib.Axes
        Figure axes upon which to plot.
    **plot_kwargs
        Keyword arguments to pass into the plot call.
    """

    defaults = {'color': PLT_COLORS['periodic'], 'alpha': 0.7, 'lw': 1.5}
    plot_kwargs = check_plot_kwargs(plot_kwargs, defaults)

    for peak in fm.gaussian_params_:

        # Define the frequency range around each peak to plot - peak bandwidth +/- 3
        peak_range = [peak[0] - peak[2] * 3, peak[0] + peak[2] * 3]

        # Generate a peak reconstruction for each peak, and trim to desired range
        peak_line = fm._ap_fit + gen_periodic(fm.freqs, peak)
        peak_freqs, peak_line = trim_spectrum(fm.freqs, peak_line, peak_range)

        # Plot the peak outline
        peak_freqs = np.log10(peak_freqs) if plt_log else peak_freqs
        ax.plot(peak_freqs, peak_line, **plot_kwargs)
Ejemplo n.º 2
0
def _add_peaks_shade(fm, plt_log, ax, **plot_kwargs):
    """Add a shading in of all peaks.

    Parameters
    ----------
    fm : FOOOF
        FOOOF object containing results from fitting.
    plt_log : boolean
        Whether to plot the frequency values in log10 spacing.
    ax : matplotlib.Axes
        Figure axes upon which to plot.
    **plot_kwargs
        Keyword arguments to pass into the plot call.
    """

    kwargs = check_plot_kwargs(plot_kwargs, {
        'color': PLT_COLORS['periodic'],
        'alpha': 0.25
    })

    for peak in fm.gaussian_params_:

        peak_freqs = np.log10(fm.freqs) if plt_log else fm.freqs
        peak_line = fm._ap_fit + gen_periodic(fm.freqs, peak)

        ax.fill_between(peak_freqs, peak_line, fm._ap_fit, **kwargs)
Ejemplo n.º 3
0
def refit(fm, sig, fs, f_range, imf_kwargs=None, power_thresh=.2, energy_thresh=0., refit_ap=False):
    """Refit a power spectrum using EMD based parameter estimation.

    Parameters
    ----------
    fm : fooof.FOOOF
        FOOOF object containing results from fitting.
    sig : 1d array
        Voltage time series.
    fs : float
        Sampling rate, in Hz.
    f_range : tuple of [float, float]
        Frequency range to restrict power spectrum to.
    imf_kwargs : optional, default: None
        Optional keyword arguments for compute_emd. Includes:

        - max_imfs
        - sift_thresh
        - env_step_size
        - max_iters
        - energy_thresh
        - stop_method
        - sd_thresh
        - rilling_thresh

    power_thresh : float, optional, default: .2
        IMF power threshold as the mean power above the initial aperiodic fit.
    energy_thresh : float, optional, default: 0.
        Normalized HHT energy threshold to define oscillatory frequencies. This aids the removal of
        harmonic peaks if present.
    refit_ap : bool, optional, default: None
        Refits the aperiodic component when True. When False, the aperiodic component is defined
        from the intial specparam fit.

    Returns
    -------
    fm : fooof.FOOOF
        Updated FOOOF fit.
    imf : 2d array
        Intrinsic modes functions.
    pe_mask : 1d array
        Booleans to mark imfs above aperiodic fit.
    """

    fm_refit = fm.copy()

    if imf_kwargs is None:
        imf_kwargs = {'sd_thresh': .1}

    # Compute modes
    imf = compute_emd(sig, **imf_kwargs)

    # Convert spectra of mode timeseries
    _, powers_imf = compute_spectrum(imf, fs, f_range=f_range)

    freqs = fm_refit.freqs
    powers = fm_refit.power_spectrum
    powers_imf = np.log10(powers_imf)

    # Initial aperiodic fit
    powers_ap = fm_refit._ap_fit

    # Select superthreshold modes
    pe_mask = select_modes(powers_imf, powers_ap, power_thresh=power_thresh)

    # Refit periodic
    if not pe_mask.any():
        warnings.warn('No IMFs are above the intial aperiodic fit. '
                      'Returning the inital spectral fit.')
        return fm_refit, imf, pe_mask

    if energy_thresh > 0:

        # Limit frequency ranges to fit using HHT
        freqs_min, freqs_max = limit_freqs_hht(imf[pe_mask], freqs, fs,
                                               energy_thresh=energy_thresh)

        if freqs_min is None and freqs_max is None:
            warnings.warn('No superthreshold energy in HHT. '
                          'Returning the inital spectral fit.')
            return fm_refit, imf, np.zeros(len(pe_mask), dtype=bool)

        limits = (freqs_min, freqs_max)

        gauss_params = fit_gaussians(freqs, powers, powers_imf, powers_ap, pe_mask, limits)

    else:

        gauss_params = fit_gaussians(freqs, powers, powers_imf, powers_ap, pe_mask)

    if gauss_params is not None:

        fm_refit.peak_params_ = fm_refit._create_peak_params(gauss_params)
        fm_refit._peak_fit = gen_periodic(freqs, gauss_params.flatten())

    else:
        fm_refit.peak_params_ = None
        fm_refit._peak_fit = np.zeros_like(freqs)

    # Refit aperiodic
    if refit_ap:
        ap_params, ap_fit = refit_aperiodic(freqs, powers, fm_refit._peak_fit)
        fm_refit._ap_fit = ap_fit
        fm_refit.aperiodic_params_ = ap_params

    # Update attibutes
    fm_refit.gaussian_params_ = gauss_params
    fm_refit.fooofed_spectrum_ = fm_refit._peak_fit + fm_refit._ap_fit

    fm_refit._calc_r_squared()
    fm_refit._calc_error()

    return fm_refit, imf, pe_mask