Closed
Description
Hi,
I have a problem with the fm.fit. All my knee values are very high. I have checked my power spectrum and it looks OK (no artefacts), but as soon as I run the Fooof analysis and fit, the knee values are totally inconsistent.
I tried with the FOOOF and then with the SpectralModel and it gives the same thing. Can anyone help me?
Here is a part of my code:
Parameters
sampling_rate = 250
min_peak_height = 0.15
max_n_peaks = 6
min_freq = 4
max_freq = 75
peak_width_limits=[2,25]
frequency_range = (min_freq, max_freq)
for index, row in filtered_df.iterrows():
if isinstance(row["Ch 1 data"], (list, np.ndarray)) and len(row["Ch 1 data"]) > 0:
freqs, powers = {}, {}
# Compute Welch power spectrum for all channels
for ch in range(1, 5):
channel_data = row[f"Ch {ch} data"]
freqs[ch], powers[ch] = compute_spectrum(channel_data, fs=sampling_rate, method='welch',avg_type='mean', nperseg=500, scaling='density')
## added to limit the frequency range
freq_mask = (freqs[ch] >= min_freq) & (freqs[ch] <= max_freq)
if len(freqs[ch]) > 0 and len(powers[ch]) > 0:
filtered_df.at[index, f"Ch {ch} frequencies"] = freqs[ch][freq_mask]
filtered_df.at[index, f"Ch {ch} power_spectrum"] = powers[ch][freq_mask]
fm = SpectralModel(peak_width_limits,aperiodic_mode='knee', min_peak_height=min_peak_height, max_n_peaks=max_n_peaks, verbose=False)
try:
print(f"Running FOOOF on Channel {ch}, Row {index}")
fm.fit(freqs[ch][freq_mask], powers[ch][freq_mask], frequency_range)
fm.report()
FOOOF results if fm.has_model:
print(f"Model fit successful for Channel {ch}, Row {index}")
aperiodic_params = fm.get_params('aperiodic')
filtered_df.at[index, f"Ch {ch} offset"] = fm.get_params('aperiodic')[0]
if len(fm.aperiodic_params_) > 2:
filtered_df.at[index, f"Ch {ch} knee"] = fm.get_params('aperiodic')[1]
filtered_df.at[index, f"Ch {ch} log_knee"] = math.log10(max(aperiodic_params[1], 1e-6))
filtered_df.at[index, f"Ch {ch} exponent"] = fm.get_params('aperiodic')[2]
filtered_df.at[index, f"Ch {ch} r_squared"] = fm.get_params('r_squared')
filtered_df.at[index, f"Ch {ch} error"] = fm.get_params('error')
filtered_df.at[index, f"Ch {ch} peaks"] = fm.get_params('peak_params')[0]
print(f"Results for Channel {ch}, Row {index}: Aperiodic parameters: {aperiodic_params}")
And the output for FOOOF analysis:
Thank you for your help!