示例#1
0
def _run_fooof(raw,
               fmin=0.001,
               fmax=1,
               tmin=0,
               tmax=None,
               n_overlap=200,
               n_fft=400,
               peak_width_limits=(0.5, 12.0)):
    """Prepare data for FOOOF including welch and scaling, then apply."""
    from fooof import FOOOF

    spectra, freqs = psd_welch(raw,
                               fmin=fmin,
                               fmax=fmax,
                               tmin=tmin,
                               tmax=tmax,
                               n_overlap=n_overlap,
                               n_fft=n_fft)

    # FOOOF doesn't like low frequencies, so multiple by 10.
    # This is corrected for in the output below.
    freqs = freqs * 10

    # Remember these values are really 0.001 to 1.2 Hz
    fm = FOOOF(peak_width_limits=peak_width_limits)

    # And these values are really 0.0001 to 1 Hz
    freq_range = [0.001, 10]

    fm.fit(freqs, np.mean(spectra, axis=0), freq_range)

    return fm
示例#2
0
文件: test_fit.py 项目: vlitvak/fooof
def test_copy():
    """Test copy FOOOF method."""

    tfm = FOOOF(verbose=False)
    ntfm = tfm.copy()

    assert tfm != ntfm
示例#3
0
def refit_aperiodic(freqs, powers, peak_fit):
    """Refit the aperiodic component following the periodic refit.

    Parameters
    ----------
    freqs : 1d array
        Frequency values for the power spectrum, in linear scale.
    powers : 1d array
        Power values, in log10 scale.
    peak_fit : 1d array
        Perodic refit, in log10 scale.

    Returns
    -------
    ap_params : 1d array
        Exponent and offset values.
    ap_fit : 1d array
        Regenerated aperiodic fit.
    """
    # Access simple ap fit method
    _fm = FOOOF()
    _fm.power_spectrum = powers
    _fm.freqs = freqs

    # Remove peaks
    spectrum_peak_rm = powers - peak_fit

    # Refit
    ap_params = _fm._simple_ap_fit(freqs, spectrum_peak_rm)

    ap_fit = gen_aperiodic(freqs, ap_params)

    return ap_params, ap_fit
示例#4
0
def test_copy():
    """Test copy FOOOF method."""

    tfm = FOOOF()
    ntfm = tfm.copy()

    assert tfm != ntfm
示例#5
0
def run_foof(x, y):
    """
    Fits the FOOOF (fitting oscillations & one over f) model.

    Returns slopes (num obs), offsets (num obs), and the peak fit power spectra (num obs x num features)
    """
    res_shape = (y.shape[0], y.shape[-1]) if y.ndim == 3 else y.shape[0]
    slopes = np.full(res_shape, np.nan, dtype='float32')
    offsets = np.full(res_shape, np.nan, dtype='float32')
    resids = np.full(y.shape, np.nan, dtype='float32')

    # initialize foof
    fm = FOOOF(peak_width_limits=[1.0, 8.0], peak_threshold=0.5)

    for i, this_event in enumerate(y):
        if this_event.ndim == 2:
            freq_dim = np.array([n == len(x) for n in this_event.shape])
            freq_dim_num = np.where(freq_dim)[0][0]
            if freq_dim_num == 0:
                this_event = this_event.T
            for j, this_event_sub in enumerate(this_event):
                fm.add_data(x, y)
                fm.fit()
                offsets[i, j] = fm.background_params_[0]
                slopes[i, j] = fm.background_params_[1]
                resids[i, :, j] = fm._peak_fit
        else:
            fm.add_data(x, this_event)
            fm.fit()
            offsets[i] = fm.background_params_[0]
            slopes[i] = fm.background_params_[1]
            resids[i] = fm._peak_fit

    return slopes, offsets, resids
示例#6
0
文件: group.py 项目: vlitvak/fooof
    def get_fooof(self, ind, regenerate=False):
        """Return a FOOOF object from specified model in a FOOOFGroup object.

        Parameters
        ----------
        ind : int
            The index of the FOOOFResults in FOOOFGroup.group_results to load.
        regenerate : bool, optional, default: False
            Whether to regenerate the model fits from the given fit parameters.

        Returns
        -------
        inst : FOOOF() object
            The FOOOFResults data loaded into a FOOOF object.
        """

        # Initialize a FOOOF object, with same settings as current FOOOFGroup
        fm = FOOOF(*self.get_settings(), verbose=self.verbose)

        # Add data for specified single power spectrum, if available
        #  The power spectrum is inverted back to linear, as it's re-logged when added to FOOOF
        if np.any(self.power_spectra):
            fm.add_data(self.freqs, np.power(10, self.power_spectra[ind]))
        # If no power spectrum data available, copy over data information & regenerate freqs
        else:
            fm.add_meta_data(self.get_meta_data())

        # Add results for specified power spectrum, regenerating full fit if requested
        fm.add_results(self.group_results[ind])
        if regenerate:
            fm._regenerate_model()

        return fm
示例#7
0
    def __init__(self, *args, **kwargs):

        FOOOF.__init__(self, *args, **kwargs)

        self.power_spectra = np.array([])

        self._reset_group_results()
示例#8
0
def test_fooof_report(skip_if_no_mpl):
    """Check that running the top level model method runs."""

    tfm = FOOOF()

    tfm.report(*gen_power_spectrum([3, 50], [50, 2], [10, 0.5, 2, 20, 0.3, 4]))

    assert tfm
示例#9
0
def whitening(X,
              ordar=10,
              block_length=256,
              sfreq=1.,
              zero_phase=True,
              plot=False,
              use_fooof=False):
    n_trials, n_channels, n_times = X.shape

    ar_model = Arma(ordar=ordar, ordma=0, fs=sfreq, block_length=block_length)
    ar_model.periodogram(X.reshape(-1, n_times), hold=False, mean_psd=True)

    if use_fooof:  # pragma: no cover
        # Fit the psd with a 1/f^a background model plus a gaussian mixture.
        # We keep only the background model
        # (pip install fooof)
        from fooof import FOOOF
        fm = FOOOF(background_mode='fixed', verbose=False)
        power_spectrum = ar_model.psd[-1][0]
        freqs = np.linspace(0, sfreq / 2.0, len(power_spectrum))

        fm.fit(freqs, power_spectrum, freq_range=None)
        # repete first point, which is f_0
        bg_fit = np.r_[fm._bg_fit[0], fm._bg_fit][None, :]
        ar_model.psd.append(np.power(10, bg_fit))

    if zero_phase:
        ar_model.psd[-1] = np.sqrt(ar_model.psd[-1])
    ar_model.estimate()

    # apply the whitening for zero-phase filtering
    X_white = apply_whitening(ar_model, X, zero_phase=zero_phase, mode='same')
    assert X_white.shape == X.shape

    # removes edges
    n_times_white = X_white.shape[-1]
    X_white *= signal.tukey(n_times_white,
                            alpha=3 / float(n_times_white))[None, None, :]

    if plot:  # pragma: no cover
        import matplotlib.pyplot as plt
        # plot the Power Spectral Density (PSD) before/after
        ar_model.arma2psd(hold=True)
        if zero_phase:
            ar_model.psd[-2] **= 2
            ar_model.psd[-1] **= 2
        ar_model.periodogram(X_white.reshape(-1, n_times),
                             hold=True,
                             mean_psd=True)
        labels = ['signal', 'model AR', 'signal white']
        if use_fooof:
            labels = ['signal', 'FOOOF fit', 'model AR', 'signal white']
        ar_model.plot('periodogram before/after whitening',
                      labels=labels,
                      fscale='lin')
        plt.legend(loc='lower left')

    return ar_model, X_white
示例#10
0
def run_fooof_trials(timewin, padlabel):
    """ Use FOOOF to get individual trial slope and HFA (offset) measurements. """
    for subject in SUBJECTS:
        print(subject)

        # Load data.
        mat_contents = sio.loadmat('/Volumes/DATAHD/Active/KAH/' + subject +
                                   '/psd/' + subject + '_FR1_psd_' +
                                   str(timewin[0]) + '_' + str(timewin[1]) +
                                   padlabel + '.mat')

        # Extract frequency axis and power spectra. PSDs are 'channels x frequencies x trials'.
        freq = np.squeeze(mat_contents['freq'])
        psds = mat_contents['psds']

        # Initialize FOOOF model.
        foof_model = FOOOF(background_mode='fixed',
                           peak_width_limits=[2.5, 12],
                           peak_threshold=np.inf)

        # Initialize output (list of FOOOF oscillation parameters), one for each channel and trial.
        slopes = [[[] for _ in range(psds.shape[-1])]
                  for _ in range(psds.shape[0])]
        hfa = [[[] for _ in range(psds.shape[-1])]
               for _ in range(psds.shape[0])]

        # Fit model per channel per trial.
        for ichan in range(psds.shape[0]):
            for itrial in range(psds.shape[-1]):
                # Fit for slope and HFA.
                try:
                    foof_model.fit(freq, psds[ichan, :, itrial], [2, 150])
                except Exception:
                    print('Skipping channel {}, trial {} because of slope'.
                          format(ichan, itrial))
                    continue
                hfa[ichan][itrial] = foof_model.background_params_[0]
                slopes[ichan][itrial] = foof_model.background_params_[1]

                # # Fit for HFA.
                # try:
                #     foof_model.fit(freq, psds[ichan, :, itrial], [2, 150])
                # except Exception:
                #     print('Skipping channel {}, trial {} because of hfa'.format(ichan, itrial))
                #     continue
                # hfa[ichan][itrial] = foof_model.background_params_[0]

        # Save to .mat file.
        sio.savemat(
            '/Volumes/DATAHD/Active/KAH/' + subject + '/fooof/' + subject +
            '_FR1_fooof_' + str(timewin[0]) + '_' + str(timewin[1]) +
            padlabel + '_slopes_hfa.mat', {
                'slopes': slopes,
                'hfa': hfa
            })

    print('Done.')
示例#11
0
def average_fg(fg, bands, avg_method='mean', generate_model=True):
    """Average across a FOOOFGroup object.

    Parameters
    ----------
    fg : FOOOFGroup
        A FOOOFGroup object with data to average across.
    bands : Bands
        Bands object that defines the frequency bands to collapse peaks across.
    avg : {'mean', 'median'}
        Averaging function to use.
    generate_model : bool, optional, default: True
        Whether to generate the model for the averaged parameters.

    Returns
    -------
    fm : FOOOF
        FOOOF object containing the average results from the FOOOFGroup input.
    """

    if avg_method not in ['mean', 'median']:
        raise ValueError('Requested average method not understood.')
    if not len(fg):
        raise ValueError(
            'Input FOOOFGroup has no fit results - can not proceed.')

    if avg_method == 'mean':
        avg_func = np.nanmean
    elif avg_method == 'median':
        avg_func = np.nanmedian

    ap_params = avg_func(fg.get_params('aperiodic_params'), 0)

    peak_params = np.array([avg_func(get_band_peak_fg(fg, band, 'peak_params'), 0) \
                            for label, band in bands])
    gaussian_params = np.array([avg_func(get_band_peak_fg(fg, band, 'gaussian_params'), 0) \
                                for label, band in bands])

    r2 = avg_func(fg.get_params('r_squared'))
    error = avg_func(fg.get_params('error'))

    results = FOOOFResults(ap_params, peak_params, r2, error, gaussian_params)

    # Create the new FOOOF object, with settings, data info & results
    fm = FOOOF()
    fm.add_settings(fg.get_settings())
    fm.add_meta_data(fg.get_meta_data())
    fm.add_results(results)

    # Generate the model from the average parameters
    if generate_model:
        fm._regenerate_model()

    return fm
示例#12
0
def get_tfm():
    """Get a FOOOF object, with a fit power spectrum, for testing."""

    freq_range = [3, 50]
    bg_params = [50, 2]
    gauss_params = [10, 0.5, 2, 20, 0.3, 4]

    xs, ys = gen_power_spectrum(freq_range, bg_params, gauss_params)

    tfm = FOOOF()
    tfm.fit(xs, ys)

    return tfm
示例#13
0
def test_fooof_fit_knee():
    """Test FOOOF fit, with a knee."""

    bgp = [50, 2, 1]
    gauss_params = [10, 0.5, 2, 20, 0.3, 4]

    xs, ys = gen_power_spectrum([3, 50], bgp, gauss_params)

    tfm = FOOOF(background_mode='knee')
    tfm.fit(xs, ys)

    # Note: currently, this test has no accuracy checking at all
    assert True
示例#14
0
文件: test_fit.py 项目: vlitvak/fooof
def test_fooof_fit_knee():
    """Test FOOOF fit, with a knee."""

    ap_params = [50, 2, 1]
    gaussian_params = [10, 0.5, 2, 20, 0.3, 4]

    xs, ys = gen_power_spectrum([3, 50], ap_params, gaussian_params)

    tfm = FOOOF(aperiodic_mode='knee', verbose=False)
    tfm.fit(xs, ys)

    # Note: currently, this test has no accuracy checking at all
    assert True
示例#15
0
def avg_fg(fg, avg='mean'):
    """Average across a FOOOFGroup object."""

    if avg == 'mean':
        avg_func = np.nanmean
    elif avg == 'median':
        avg_func = np.nanmedian

    ap_params = avg_func(fg.get_all_data('aperiodic_params'), 0)

    peak_params = avg_func(
        get_band_peak_group(fg.get_all_data('peak_params'), [7, 14], len(fg)),
        0)
    peak_params = peak_params[np.newaxis, :]

    gaussian_params = avg_func(
        get_band_peak_group(fg.get_all_data('gaussian_params'), [7, 14],
                            len(fg)), 0)
    gaussian_params = gaussian_params[np.newaxis, :]

    r2 = avg_func(fg.get_all_data('r_squared'))
    error = avg_func(fg.get_all_data('error'))

    results = FOOOFResults(ap_params, peak_params, r2, error, gaussian_params)

    # Create the new FOOOF object, with settings, data info & results
    fm = FOOOF()
    fm.add_settings(fg.get_settings())
    fm.add_data_info(fg.get_data_info())
    fm.add_results(results)

    return fm
示例#16
0
def cal_FOOOF_parameters(pxx, f, rois=210, freq_range=[0.5, 48]):
    # initialize FOOOF oject
    fm = FOOOF()
    # create variables
    FOOOF_offset = np.empty(rois)
    FOOOF_slope = np.empty(rois)
    # loop over all rois
    for roi in np.arange(rois):
        # model the power spectrum with FOOOF for each roi in rois
        # LD: this part does not run because the size of the freqs var is somehow not consistent
        fm.fit(f, pxx[:, roi], freq_range)
        FOOOF_offset[roi] = fm.background_params_[0]
        FOOOF_slope[roi] = fm.background_params_[1]

    return FOOOF_offset, FOOOF_slope
示例#17
0
def run_fooofgroup(number_of_patients, base_params_save_path, patient_group,
                   brain_region, freq_range):
    """converts text files of Power and Frequency to numpy files to be processed by FOOOFGroup
    """

    joiner = [
        base_params_save_path, patient_group, 'Results_', brain_region, '/'
    ]
    params_save_path = ''.join(str(e) for e in joiner)

    fm = FOOOF(peak_width_limits=[1.5, 8],
               max_n_peaks=6,
               min_peak_amplitude=0.3)

    joiner = [
        base_params_save_path, 'raw_', patient_group, 'data/',
        frequencies_file_name
    ]
    """remove hashtags before ", delimiter" for text files with comma-separated data points"""

    realfreqs = np.loadtxt(
        ''.join(joiner))  #, delimiter = ',', usecols=range((118)))

    joiner = [
        base_params_save_path, 'raw_', patient_group, 'data/', power_file_name
    ]
    realspectrum = np.loadtxt(
        ''.join(joiner))  #,delimiter = ',', usecols=range((118)))
    joiner = [
        base_params_save_path, patient_group, 'Results_', brain_region,
        '/Freqs_', brain_region, '_', patient_group, '.npy'
    ]
    np.save(''.join(joiner), np.array(realfreqs))
    joiner = [
        base_params_save_path, patient_group, 'Results_', brain_region,
        '/Freqs_', brain_region, '_', patient_group, '.npy'
    ]
    frequencies = np.load(''.join(joiner))  #load new freqlist
    joiner = [
        params_save_path, 'Spec_', brain_region, '_', patient_group, '.npy'
    ]
    np.save(''.join(joiner), np.array(realspectrum))
    joiner = [
        params_save_path, 'Spec_', brain_region, '_', patient_group, '.npy'
    ]
    spectrum = np.load(''.join(joiner))  #load new powlist
    """flattens, to pdfs"""

    get_flattened_plots(spectrum, frequencies, number_of_patients, fm, fg,
                        patient_group, brain_region, params_save_path)
    """group results, to pdf"""

    get_group_results(fg, frequencies, spectrum, freq_range, params_save_path)
    """Extract background data, to pdfs"""

    get_data_for_each_fit(fg, params_save_path, patient_group, brain_region)
    """saves individual fits, to pdfs!"""

    get_individual_fits(number_of_patients, patient_group, brain_region, fg,
                        params_save_path)
示例#18
0
def test_fooof_fit_nk():
    """Test FOOOF fit, no knee."""

    bgp = [50, 2]
    gauss_params = [10, 0.5, 2, 20, 0.3, 4]

    xs, ys = gen_power_spectrum([3, 50], bgp, gauss_params)

    tfm = FOOOF()
    tfm.fit(xs, ys)

    # Check model results - background parameters
    assert np.all(np.isclose(bgp, tfm.background_params_, [0.5, 0.1]))

    # Check model results - gaussian parameters
    for ii, gauss in enumerate(group_three(gauss_params)):
        assert np.all(np.isclose(gauss, tfm._gaussian_params[ii], [1.5, 0.25, 0.5]))
示例#19
0
def test_fooof_fit_failure():
    """Test that fit handles a failure."""

    # Use a new FOOOF, that is monkey-patched to raise an error
    #  This mimicks the main fit-failure, without requiring bad data / waiting for it to fail.
    tfm = FOOOF()
    def raise_runtime_error(*args, **kwargs):
        raise RuntimeError('Test-MonkeyPatch')
    tfm._fit_peaks = raise_runtime_error

    # Run a FOOOF fit - this should raise an error, but continue in try/except
    tfm.fit(*gen_power_spectrum([3, 50], [50, 2], [10, 0.5, 2, 20, 0.3, 4]))

    # Check after failing out of fit, all results are reset
    for result in get_obj_desc()['results']:
        cur_res = getattr(tfm, result)
        assert cur_res is None or np.all(np.isnan(cur_res))
def calc_spec_peak(freqs, powers, fitting_bw=[1, 55], out_image_path=None):
    '''Spectral fitting routine from the FOOOF toolbox
    https://fooof-tools.github.io/fooof/index.html
    
        
    doi: https://doi.org/10.1101/299859 
    
    Fit the spectral peaks and return the fit parameters
    Save the image of the spectral data and peak fits
    
    Inputs:
        freqs - numpy array of frequencies
        powers - numpy array of spectral power
        fitting_bw - Reduce the total bandwidth to fit the 1/f and spectral peaks
        
    Outputs:
        params - parameters from the FOOOF fit
        
    '''

    #Crop Frequencies for 1/f
    powers = powers[(freqs > fitting_bw[0]) & (freqs <= fitting_bw[1])]
    freqs = freqs[(freqs > fitting_bw[0]) & (freqs <= fitting_bw[1])]

    # Initialize power spectrum model objects and fit the power spectra
    fm1 = FOOOF(min_peak_height=0.05, verbose=False)
    fm1.fit(freqs, powers)

    if out_image_path is not None:
        import matplotlib
        from matplotlib import pylab
        matplotlib.use('Agg')
        # import pylab
        fig = pylab.Figure(figsize=[10, 6])  #, dpi=150)
        ax = fig.add_subplot()
        plot_annotated_model(fm1, annotate_peaks=False, ax=ax)
        fig.tight_layout()
        fig.savefig(out_image_path, dpi=150, bbox_inches="tight")

    params = fm1.get_results()
    params.peak_params[0]

    # plot_spectrum(freqs, powers, log_powers=True,
    #               color='black', label='Original Spectrum')
    return params
示例#21
0
文件: test_fit.py 项目: vlitvak/fooof
def test_fooof_fit_nk():
    """Test FOOOF fit, no knee."""

    ap_params = [50, 2]
    gauss_params = [10, 0.5, 2, 20, 0.3, 4]

    xs, ys = gen_power_spectrum([3, 50], ap_params, gauss_params)

    tfm = FOOOF(verbose=False)
    tfm.fit(xs, ys)

    # Check model results - aperiodic parameters
    assert np.all(np.isclose(ap_params, tfm.aperiodic_params_, [0.5, 0.1]))

    # Check model results - gaussian parameters
    for ii, gauss in enumerate(group_three(gauss_params)):
        assert np.all(
            np.isclose(gauss, tfm.gaussian_params_[ii], [2.0, 0.5, 1.0]))
示例#22
0
def get_tt_psd_peaks(freqs, pxx, theta_range=None):
    if theta_range is None:
        theta_range = [4, 12]
    n_chans = pxx.shape[0]
    sixty_range = [58, 62]

    df = pd.DataFrame(
        columns=['th_pk', 'th_amp', '60_pk', '60_amp', '1/f_r2', 'rmse'])
    for ch in range(n_chans):
        fm = FOOOF(max_n_peaks=2,
                   peak_threshold=2.0,
                   peak_width_limits=[0.5, 6.0],
                   verbose=False)
        fm.fit(freqs, pxx[ch], [2, 100])

        pks = fm.peak_params_.flatten()[::3]
        amps = fm.peak_params_.flatten()[1::3]

        idx = (pks >= theta_range[0]) & (pks <= theta_range[1])
        theta_pk = pks[idx]
        theta_amp = amps[idx]

        idx = (pks >= sixty_range[0]) & (pks <= sixty_range[1])
        sixty_pk = pks[idx]
        sixty_amp = amps[idx]

        if len(theta_pk) == 1:
            df.at[ch, 'th_pk'] = np.around(theta_pk[0], decimals=2)
            df.at[ch, 'th_amp'] = np.around(theta_amp[0], decimals=2)
        elif len(theta_pk) > 1:
            df.at[ch, 'th_pk'] = np.around(np.mean(theta_pk), decimals=2)
            df.at[ch, 'th_amp'] = np.around(np.mean(theta_amp), decimals=2)

        if len(sixty_pk) == 1:
            df.at[ch, '60_pk'] = np.around(sixty_pk[0], decimals=2)
            df.at[ch, '60_amp'] = np.around(sixty_amp[0], decimals=2)
        elif len(sixty_pk) > 1:
            df.at[ch, '60_pk'] = np.around(np.mean(sixty_pk), decimals=2)
            df.at[ch, '60_amp'] = np.around(np.mean(sixty_amp), decimals=2)

        df.at[ch, 'rmse'] = np.around(fm.error_, decimals=3)
        df.at[ch, '1/f_r2'] = np.around(fm.r_squared_, decimals=3)
    return df
示例#23
0
def test_get_obj_desc():

    desc = get_obj_desc()

    tfm = FOOOF()
    objs = dir(tfm)

    # Test that everything in dict is a valid component of the fooof object
    for ke, va in desc.items():
        for it in va:
            assert it in objs
示例#24
0
    def get_fooof(self, ind, regenerate=False):
        """Return a FOOOF object from specified model in a FOOOFGroup object.

        Parameters
        ----------
        ind : int
            The index of the FOOOFResult in FOOOFGroup.group_results to load.
        regenerate : bool, optional
            Whether to regenerate the model fits from the given fit parameters. default : False

        Returns
        -------
        inst : FOOOF() object
            The FOOOFResult data loaded into a FOOOF object.
        """

        # Initialize a FOOOF object, with same settings as current FOOOFGroup
        fm = FOOOF(self.peak_width_limits, self.max_n_peaks,
                   self.min_peak_amplitude, self.peak_threshold,
                   self.background_mode, self.verbose)

        # Add data for specified single power spectrum, if available
        #  The power spectrum is inverted back to linear, as it's re-logged when added to FOOOF
        if np.any(self.power_spectra):
            fm.add_data(self.freqs, np.power(10, self.power_spectra[ind]))

        # Add results for specified power spectrum, regenerating full fit if requested
        fm.add_results(self.group_results[ind], regenerate=regenerate)

        return fm
def run_fooof(freq_path,loc_path,save_report_path,save_variables_path,save_variable_prefix,save_variables = True
,save_report=True,freq_range=[1,30],channel = 'Oz'):

    freqIterator = folderIterator(freq_path)
    chan_inds_iterator = chanIndIterator(loc_path)

    # Constant
    bg_ppts= []# background parameters/ppts
    peak_ppts = []
    errors = []
    for chan_ind, freq_var in zip(chan_inds_iterator,freqIterator)
        if True: # if files[0].endswith(".mat"): TODO: set the conditions for safety            
            power,spectrum = getFreqValuesVec(freq_var)
            if chan_ind != -1
                power = 10**np.array(power[chan_ind])
                spectrum=np.array(spectrum).flatten()
                # Initialize FOOOF object
                fm = FOOOF(peak_width_limits=[0.5,8])
                
                # Model the power spectrum with FOOOF, and print out a report
                fm.fit(spectrum, power, freq_range)

                bg_ppts.append(fm.background_params_)
                peak_ppts.append(fm.peak_params_)
                errors.append(fm.error_)
                if save_report:
                    fm.save_report(str(freq_var[-7:-4]),save_report_path)

    if save_variables :
        with cd(save_variables_path):
            save_file(save_variable_prefix+'bg_ppts.npy',bg_ppts)
            save_file(save_variable_prefix+'peak_ppts.npy',peak_ppts)
            save_file(save_variable_prefix+'errors.npy',errors) 
示例#26
0
def get_all_features(eeg_epoch_full_df):
    power_ratios_df, std_err_df, avg_df = getPowerBin(eeg_epoch_full_df)
    band_ratios_df = getPowerBandRatios(power_ratios_df)
    diff_df = get_channel_relationships(power_ratios_df)
    insta_stat_df = get_alpha_instantaneous_statistics(eeg_epoch_full_df)
    fooof_parameters_df = FOOOF(eeg_epoch_full_df)
    # Concatenate power_ratios_df with band_ratios_df to get full feature df
    feature_df = pd.concat([
        power_ratios_df, band_ratios_df, diff_df, insta_stat_df,
        fooof_parameters_df
    ],
                           axis=1)

    return feature_df
def cal_FOOOF_parameters(pxx, f, freq_range=[0.5, 48]):
    """Obtain slope and offset using the FOOOF algorithm
    Reference paper: Haller M, Donoghue T, Peterson E, Varma P, Sebastian P,
    Gao R, Noto T, Knight RT, Shestyuk A, Voytek B (2018) Parameterizing Neural
    Power Spectra. bioRxiv, 299859. doi: https://doi.org/10.1101/299859

    Reference Github: https://fooof-tools.github.io/fooof/index.html

    Parameters
    ----------
    pxx: ndarray
        Column of power spectra
    f: 1d-array
        Array with sample frequencies (x-asix of power spectrum plot)
    freq_range: list, optional
        Gives the upper and lower boundaries to calculate the broadband power,
        default=[0.5, 48]

    Returns
    -------
    FOOOF_offset: float
        Offset
    FOOOF_slope: float
        Slope

    """

    # initialize FOOOF oject
    fm = FOOOF()
    # create variables
    fm.fit(f, pxx, freq_range)
    FOOOF_offset = fm.background_params_[0]
    FOOOF_slope = fm.background_params_[1]
    time.sleep(1)  # heavy algorithm

    return FOOOF_offset, FOOOF_slope
示例#28
0
def fit_fooof(freqs, powers, freq_range, init_kwargs, n_jobs):
    """A generalized FOOOF fit function to handle 1d, 2d, or 3d arrays.

    Parameters
    ----------
    powers : 1d, 2d, or 3d array
        Power values for a single spectrum, or group of power spectra.
        Power values are stored internally in log10 scale.
    freqs : 1d array
        Frequency values for the power spectra.
    freq_range : list of [float, float]
        Frequency range of the power spectra, as [lowest_freq, highest_freq].
    init_kwargs : dict
        FOOOF object initialization kwargs.
    n_jobs : int
        Specificy the number of jobs to run in parrallel for 2d or 3d arrays.

    Returns
    -------
    model : FOOOF, FOOOFGroup, or list of FOOOFGroup objects.
        A FOOOF object that has been fit. A 1d array will return a FOOOF objects, a 2d array will
        return a FOOOFGroup object, and a 3d array will return a list of FOOOFGroup objects.
    """

    if powers.ndim == 1:
        # Fit a 1d array
        model = FOOOF(**init_kwargs)
        model.fit(freqs, powers, freq_range=freq_range)

    elif powers.ndim == 2:
        # Fit a 2d array
        model = FOOOFGroup(**init_kwargs)
        model.fit(freqs, powers, freq_range=freq_range, n_jobs=n_jobs)

    elif powers.ndim == 3:
        # Fit a 3d array
        model = FOOOFGroup(**init_kwargs)
        model = fit_fooof_3d(model, freqs, powers, n_jobs=n_jobs)

    else:
        raise ValueError(
            'The power_spectrum argument must specify a 1d, 2d, or 3d array.')

    return model
示例#29
0
def fooofy(components, spectra, x_range, group=True):
    """
    fit FOOOF model on given spectrum and return params
        components: frequencies or PC dimensions
        spectra: PSDs or variance explained
        x_range: range for x axis of spectrum to fit
        group: whether to use FOOOFGroup or not
    """
    if group:
        fg = FOOOFGroup(max_n_peaks=0, aperiodic_mode='fixed', verbose=False) #initialize FOOOF object
    else:
        fg = FOOOF(max_n_peaks=0, aperiodic_mode='fixed', verbose=False) #initialize FOOOF object
    #print(spectra.shape, components.shape) #Use this line if things go weird

    fg.fit(components, spectra, x_range)
    exponents = fg.get_params('aperiodic_params', 'exponent')
    errors    = fg.get_params('error') # MAE
    offsets   = fg.get_params('aperiodic_params', 'offset')
    return exponents, errors, offsets
示例#30
0
def test_fooof_load():
    """Test load into FOOOF. Note: loads files from test_core_io."""

    file_name_all = 'test_fooof_str_all'
    file_name_res = 'test_fooof_str_res'
    file_path = pkg.resource_filename(__name__, 'test_files')

    tfm = FOOOF()

    tfm.load(file_name_all, file_path)
    assert tfm

    tfm.load(file_name_res, file_path)
    assert tfm