Description
Hello!
I have been tasked with implementing a FOOOF function within our EEG processing pipeline; specifically, we are analyzing alpha waves in occipital electrodes. I am a novice coder and new to working within Python and had some questions regarding working with FOOOF.
Specifically, how best to adapt FOOOFs settings to fit our data; presently, I believe the model is overfitting our data based on high R2 of the model fit (>0.98), and low error of the model fit (<0.04) in addition to a high number of peaks detected within very close proximity. I believe this is indicative of the model fitting small fluctuations whether due to noise, or just small bumps present in the data. Additionally, I am wondering if I would be better served to fit the model with a knee, I had decided not based on the small range of frequencies with which I am fitting the data (1 - 45 Hz), and when I do fit with a knee, the outputs are strange and hard to interpret.
I have reviewed the tutorial on fitting the aperiodic model (tutorial #5) and tuning & troubleshooting (tutorial #7) and have adjusted some of the model parameters (limiting peaks, peak width, and minimum peak height) but have stalled in my progress.
Any additional help you may have to offer would be greatly appreciated!
See some code below and snippets of output for reference:
##
Run Initial FOOOF Model on a single Epoched File
import mne
import numpy as np
import matplotlib.pyplot as plt
from fooof import FOOOF
from fooof.plts.spectra import plot_spectra
from fooof.plts.annotate import plot_annotated_model
def run_fixed_fooof(filepath, channel='Oz', fmin=1, fmax=100, fit_range=[1, 45],
mode='fixed', plot=True, plot_annotated_fx=False, return_model=True):
"""
Run FOOOF analysis on a single epoched EEG file.
Parameters:
- filepath : str
Path to the MNE epochs .fif file
- channel : str
EEG channel to analyze (e.g., 'Oz')
- fmin, fmax : float
Frequency range for computing PSD
- fit_range : list of two floats
Frequency range to fit FOOOF model
- mode : 'fixed' or 'knee'
Type of FOOOF aperiodic model
- plot : bool
Whether to plot the spectrum and model
- return_model : bool
Whether to return the FOOOF model or just the parameters
Returns:
- model : FOOOF object (optional)
- results : dict of model parameters
"""
# Load epoched data
epochs = mne.read_epochs(filepath, preload=True)
# Pick channel if specified
if channel:
epochs.pick_channels([channel])
# Compute PSD
psd = epochs.compute_psd(method='welch', fmin=fmin, fmax=fmax, n_fft=350)
freqs = psd.freqs
spectrum = psd.get_data().mean(axis=0).mean(axis=0)
# Fit FOOOF model
fm = FOOOF(aperiodic_mode=mode, peak_width_limits=[1.5, 6],
min_peak_height=0.15, max_n_peaks=6)
fm.fit(freqs, spectrum, fit_range)
if plot:
fm.plot(plt_log=True)
if plot_annotated_fx:
plot_annotated_model(fm, plt_log=True)
results = {
'aperiodic_params': fm.aperiodic_params_,
'peak_params': fm.peak_params_,
'r_squared': fm.r_squared_,
'error': fm.error_,
'linear_powers': [10**pw for _, pw, _ in fm.peak_params_],
'fm.print_results()': fm.print_results(),
}
return (fm, results) if return_model else `results`
Thanks so much!