Skip to content

Commit

Permalink
Merge pull request #54 from schmidtfa/minor_fixes
Browse files Browse the repository at this point in the history
Minor fixes to main
  • Loading branch information
schmidtfa authored Aug 16, 2024
2 parents 114b4df + cd2e484 commit 382cf54
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 72 deletions.
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

0 comments on commit 382cf54

Please sign in to comment.