# First, we will start by generating a noisy simulated power spectrum
#

###################################################################################################

# Set the frequency range to generate the power spectrum
f_range = [1, 50]
# Set aperiodic component parameters, as [offset, exponent]
ap_params = [20, 2]
# Gaussian peak parameters
gauss_params = [[10, 1.0, 2.5], [20, 0.8, 2], [32, 0.6, 1]]
# Set the level of noise to generate the power spectrum with
nlv = 0.1

# Set random seed, for consistency generating simulated data
set_random_seed(21)

# Create a simulated power spectrum
freqs, spectrum = gen_power_spectrum(f_range, ap_params, gauss_params, nlv)

###################################################################################################

# Fit an (unconstrained) model, liable to overfit
fm = FOOOF()
fm.report(freqs, spectrum)

###################################################################################################
#
# Notice that in the above fit, we are very likely to think that the model has
# been overzealous in fitting peaks, and is therefore overfitting.
#
Example #2
0
def FOOOF(eeg_epoch_full_df):
    # Import required code for visualizing example models
    from fooof import FOOOF
    from fooof.sim.gen import gen_power_spectrum
    from fooof.sim.utils import set_random_seed
    from fooof.plts.annotate import plot_annotated_model

    # Set random seed, for consistency generating simulated data
    set_random_seed(10)

    # Simulate example power spectra
    freqs1, powers1 = gen_power_spectrum([3, 40], [1, 1],
                                         [[10, 0.2, 1.25], [30, 0.15, 2]])

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

    plot_annotated_model(fm1, annotate_aperiodic=True)
    # Constants
    freq_range = [1, 40]
    alpha_range = (7, 12)
    # Initialize a FOOOF object
    fm = FOOOF(peak_width_limits=[1, 8], max_n_peaks=6, min_peak_height=0.4)

    # Get the PSD of our EEG Signal
    sig = eeg_epoch_full_df['Cz'][0]
    freq, psd = getMeanFreqPSD(sig)

    fm.add_data(freq, psd, freq_range)

    fm.fit()
    fm.report()

    # Get PSD averages for each channel for each event type (0=left or 1=right)
    psd_averages_by_type = {}

    for event_type in event_types.keys():
        psds_only_one_type = {}
        freqs_only_one_type = {}
        for i, row in eeg_epoch_full_df[eeg_epoch_full_df["event_type"] ==
                                        event_type].iterrows():
            for ch in all_chans:
                if ch not in psds_only_one_type:
                    psds_only_one_type[ch] = list()
                    freqs_only_one_type[ch] = list()
                f, p = getMeanFreqPSD(row[ch])
                psds_only_one_type[ch].append(p)
                freqs_only_one_type[ch].append(f)
        avg_psds_one_type = {}
        for ch in all_chans:
            psds_only_one_type[ch] = np.array(psds_only_one_type[ch])
            avg_psds_one_type[ch] = np.mean(psds_only_one_type[ch], axis=0)
        psd_averages_by_type[event_type] = dict(avg_psds_one_type)

    # Visualize the parameters in these two classes of C4 activity
    fm_left_C4 = FOOOF(peak_width_limits=[1, 8],
                       max_n_peaks=6,
                       min_peak_height=0.4)
    fm_left_C4.add_data(freqs_only_one_type[eeg_chans[0]][0],
                        psd_averages_by_type[0]['C4'], freq_range)
    fm_left_C4.fit()
    fm_left_C4.report()

    fm_right_C4 = FOOOF(peak_width_limits=[1, 8],
                        max_n_peaks=6,
                        min_peak_height=0.4)
    fm_right_C4.add_data(freqs_only_one_type[eeg_chans[0]][0],
                         psd_averages_by_type[1]['C4'], freq_range)
    fm_right_C4.fit()
    fm_right_C4.report()

    # Calculate central freq, alpha power, and bandwidth for each channel and each trial
    # This cell takes a few minutes to run (~8 mins on my computer). There are 3680 trials in the training data.

    # Initialize a fooof object
    fm = FOOOF(peak_width_limits=[1, 8], max_n_peaks=6, min_peak_height=0.4)

    # Some will not have alpha peaks, use these variables to keep track
    num_with_alpha = 0
    num_without_alpha = 0
    fooof_parameters = {}
    for i in range(len(eeg_epoch_full_df)):
        # Print the trial number every 100 to make sure we're making progress
        if i % 100 == 0:
            print(i)
        for ch in all_chans:
            # Determine the key
            CF_key = ch + "_alpha_central_freq"
            PW_key = ch + "_alpha_power"
            BW_key = ch + "_alpha_band_width"
            if CF_key not in fooof_parameters:
                fooof_parameters[CF_key] = []
            if PW_key not in fooof_parameters:
                fooof_parameters[PW_key] = []
            if BW_key not in fooof_parameters:
                fooof_parameters[BW_key] = []

            # Calculate the PSD for the desired signal
            sig = eeg_epoch_full_df[ch][i]
            freq, psd = getMeanFreqPSD(sig)

            # Set the frequency and spectral data into the FOOOF model and get peak params
            fm.add_data(freq, psd, freq_range)
            fm.fit()
            peak_params = fm.peak_params_

            # Only select the peaks within alpha power
            peak_params_alpha = []
            for param in peak_params:
                if (param[0] > alpha_range[0]) and (param[0] < alpha_range[1]):
                    peak_params_alpha.append(param)

            # Take the average if there are multiple peaks detected, otherwise 0 everything
            means = []
            if len(peak_params_alpha) > 0:
                num_with_alpha += 1
                means = np.mean(peak_params_alpha, axis=0)
            else:
                num_without_alpha += 1
                means = [0, 0, 0]

            fooof_parameters[CF_key].append(means[0])
            fooof_parameters[PW_key].append(means[1])
            fooof_parameters[BW_key].append(means[2])

    fooof_parameters_df = pd.DataFrame(fooof_parameters)
    print("% with alpha:",
          num_with_alpha / (num_with_alpha + num_without_alpha))
    return fooof_parameters_df