# 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. #
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