Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor fixes to main #54

Merged
merged 4 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ PyRASA is a Python library designed to separate and parametrize aperiodic (fract
- **Aperiodic and Periodic Decomposition:** Utilize the IRASA algorithm to decompose power spectra into aperiodic and periodic components, enabling better interpretation of neurophysiological signals.
- **Time Resolved Spectral Parametrization:** Perform time resolved spectral parametrizazion, allowing you to track changes in spectral components over time.
- **Support for Raw and Epoched MNE Objects:** PyRASA provides functions designed for both continuous (Raw) and event-related (Epochs) data, making it versatile for various types of EEG/MEG analyses.
- **Consistent Ontology:** PyRASA uses the same jargon to label parameters as specparam, the most commonly used tool to parametrize power spectra, to allow users to easily switch between tools depending on their needs, while keeping the labeling of features consistent.
- **Custom Aperiodic Fit Models:** In addition to the built-in "fixed" and "knee" models for aperiodic fitting, users can specify their custom aperiodic fit functions, offering flexibility in how aperiodic components are modeled.


Expand Down Expand Up @@ -53,7 +54,7 @@ from pyrasa.irasa import irasa

irasa_out = irasa(sig,
fs=fs,
band=(1, 100),
band=(.1, 200),
psd_kwargs={'nperseg': duration*fs,
'noverlap': duration*fs*overlap
},
Expand All @@ -72,7 +73,7 @@ irasa_out.get_peaks()
```
| ch_name | cf | bw | pw |
|----------:|-----:|--------:|-------:|
| 0 | 9.5 | 1.44337 | 0.4146 |
| 0 | 9.5 | 1.4426 | 0.4178 |

Extract aperiodic parameters

Expand All @@ -82,9 +83,9 @@ irasa_out.fit_aperiodic_model(fit_func='knee').aperiodic_params

```

| Offset | Knee | Exponent_1 | Exponent_2 | fit_type | Knee Frequency (Hz) | ch_name |
|---------:|-------:|-------------:|-------------:|:-----------|----------------------:|----------:|
| 1.38098 | 532.91 | 0.511999 | 1.89448 | knee | 8.59554 | 0 |
| Offset | Knee | Exponent_1 | Exponent_2 | fit_type | Knee Frequency (Hz) | tau | ch_name |
|---------:|-------:|-------------:|-------------:|:-----------|----------------------:|----------:|----------:|
| 1.737402e-16 | 60.942144 | 0.039556 | 1.472746 | knee | 14.131277 | 0.011263 | 0 |

And the goodness of fit

Expand All @@ -96,7 +97,7 @@ irasa_out.fit_aperiodic_model(fit_func='knee').gof

| mse | r_squared | BIC | AIC | fit_type | ch_name |
|------------:|------------:|---------:|---------:|:-----------|----------:|
| 3.02402e-05 | 0.999894 | -2049.69 | -2062.86 | knee | 0 |
| 0.000051 | 0.999751 | -3931.840246 | -3947.806104 | knee | 0 |


### How to Contribute
Expand Down
144 changes: 80 additions & 64 deletions examples/basic_functionality.ipynb

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions pyrasa/utils/fit_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ def add_infos_to_df(self, df_params: pd.DataFrame) -> pd.DataFrame:
df_params['Knee Frequency (Hz)'] = df_params['Knee'] ** (
1.0 / (2 * df_params['Exponent_1'] + df_params['Exponent_2'])
)
df_params['tau'] = 1.0 / (2 * np.pi * df_params['Knee Frequency (Hz)'])
return df_params

@property
Expand Down
Binary file modified simulations/example_knee.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 14 additions & 2 deletions tests/test_irasa_knee.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,13 @@ def test_irasa_knee_peakless(load_knee_aperiodic_signal, fs, exponent, knee):
# test whether we can get the first exponent correctly
assert bool(np.isclose(slope_fit_k.aperiodic_params['Exponent_1'][0], 0, atol=TOLERANCE))
# test whether we can get the second exponent correctly
assert bool(np.isclose(slope_fit_k.aperiodic_params['Exponent_2'][0], np.abs(exponent), atol=TOLERANCE))
assert bool(
np.isclose(
slope_fit_k.aperiodic_params['Exponent_2'][0],
np.abs(exponent),
atol=TOLERANCE,
)
)
# test whether we can get the knee correctly
knee_hat = slope_fit_k.aperiodic_params['Knee'][0] ** (
1 / (2 * slope_fit_k.aperiodic_params['Exponent_1'][0] + slope_fit_k.aperiodic_params['Exponent_2'][0])
Expand Down Expand Up @@ -59,7 +65,13 @@ def test_irasa_knee_cmb(load_knee_cmb_signal, fs, exponent, knee, osc_freq):
# test whether we can get the first exponent correctly
assert bool(np.isclose(slope_fit_k.aperiodic_params['Exponent_1'][0], 0, atol=TOLERANCE))
# test whether we can get the second exponent correctly
assert bool(np.isclose(slope_fit_k.aperiodic_params['Exponent_2'][0], np.abs(exponent), atol=TOLERANCE))
assert bool(
np.isclose(
slope_fit_k.aperiodic_params['Exponent_2'][0],
np.abs(exponent),
atol=TOLERANCE,
)
)
# test whether we can get the knee correctly
knee_hat = slope_fit_k.aperiodic_params['Knee'][0] ** (
1 / (2 * slope_fit_k.aperiodic_params['Exponent_1'][0] + slope_fit_k.aperiodic_params['Exponent_2'][0])
Expand Down