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 + doc string linting #53

Merged
merged 11 commits into from
Aug 10, 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
98 changes: 80 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,52 +1,114 @@
## PyRASA
# PyRASA - Spectral parameterization in python based on IRASA

[![Project Status: WIP – Initial development is in progress, but there has not yet been a stable, usable release suitable for the public.](https://www.repostatus.org/badges/latest/wip.svg)](https://www.repostatus.org/#wip)
[![License](https://img.shields.io/badge/License-BSD_2--Clause-orange.svg)](https://opensource.org/licenses/BSD-2-Clause)
[![Checked with mypy](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/)
[![Coverage Status](https://coveralls.io/repos/github/schmidtfa/pyrasa/badge.svg?branch=main)](https://coveralls.io/github/schmidtfa/pyrasa?branch=main)


Pyrasa is a repository that is build around the IRASA algorithm (Wen & Liu, 2016) to parametrize power and coherence spectra.
PyRASA is a Python library designed to separate and parametrize aperiodic (fractal) and periodic (oscillatory) components in time series data based on the IRASA algorithm (Wen & Liu, 2016).

WARNING - This repository is under heavy development and core functionality may change on a daily basis...
### Features
- **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.
- **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.


### Documentation
Documentation for PyRASA will soon be available [here].
## Documentation
Documentation for PyRASA, including detailed descriptions of functions, parameters, and examples, will soon be available [here].


### Installation
To install the latest stable version of PyRASA, you can soon use pip:

``` $ pip install pyrasa ```
```bash
$ pip install pyrasa
```

or conda:
or conda

``` $ conda install pyrasa ```
```bash
$ conda install pyrasa
```

### Dependencies
The minimum required dependencies to run PyRASA are:

[numpy](https://github.com/numpy/numpy)
PyRASA has the following dependencies:
- **Core Dependencies:**
- [numpy](https://github.com/numpy/numpy)
- [scipy](https://github.com/scipy/scipy)
- [pandas](https://github.com/pandas-dev/pandas)

[scipy](https://github.com/scipy/scipy)
- **Optional Dependencies for Full Functionality:**
- [mne](https://github.com/mne-tools/mne-python): Required for directly working with EEG/MEG data in `Raw` or `Epochs` formats.

[pandas](https://github.com/pandas-dev/pandas)

For full functionality, some functions require:
### Example Usage

[mne](https://github.com/mne-tools/mne-python)
Decompose spectra in periodic and aperiodic ccomponents

```python
from pyrasa.irasa import irasa

### How to contribute
Please take a look at the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information.
irasa_out = irasa(sig,
fs=fs,
band=(1, 100),
psd_kwargs={'nperseg': duration*fs,
'noverlap': duration*fs*overlap
},
hset_info=(1, 2, 0.05))

```

![image info](./simulations/example_knee.png)

Extract periodic parameters

```python

irasa_out.get_peaks()

```
| ch_name | cf | bw | pw |
|----------:|-----:|--------:|-------:|
| 0 | 9.5 | 1.44337 | 0.4146 |

Extract aperiodic parameters

```python

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 |

And the goodness of fit

```python

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 |


### How to Contribute

Contributions to PyRASA are welcome! Whether it's raising issues, improving documentation, fixing bugs, or adding new features, your help is appreciated. Please refer to the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information on how to get involved.


### Reference

If you are using the IRASA algorithm it probably makes sense to cite the smart people who came up with the algorithm:
If you are using IRASA please cite the smart people who came up with the algorithm:

```Wen, H., & Liu, Z. (2016). Separating fractal and oscillatory components in the power spectrum of neurophysiological signal. Brain topography, 29, 13-26.```
Wen, H., & Liu, Z. (2016). Separating fractal and oscillatory components in the power spectrum of neurophysiological signal. Brain topography, 29, 13-26. https://doi.org/10.1007/s10548-015-0448-0

If you are using PyRASA it would be nice, if you could additionally cite us (whenever the paper is finally ready):

Expand Down
213 changes: 141 additions & 72 deletions examples/basic_functionality.ipynb

Large diffs are not rendered by default.

56 changes: 28 additions & 28 deletions examples/custom_fit_functions.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import scipy.signal as dsp\n",
"from pyrasa.utils.aperiodic_utils import compute_slope\n",
"from pyrasa.utils.aperiodic_utils import compute_aperiodic_model\n",
"from pyrasa.utils.fit_funcs import AbstractFitFun\n",
"from pyrasa import irasa\n",
"import numpy as np\n",
Expand Down Expand Up @@ -51,7 +51,7 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -70,12 +70,12 @@
" return y_hat\n",
" \n",
"\n",
"slope_fit = compute_slope(psd, freqs, fit_func=CustomFitFun)\n"
"slope_fit = compute_aperiodic_model(psd, freqs, fit_func=CustomFitFun)\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 4,
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -108,8 +108,8 @@
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>-1.052551</td>\n",
" <td>1.510974</td>\n",
" <td>-1.111201</td>\n",
" <td>1.510531</td>\n",
" <td>custom</td>\n",
" <td>0</td>\n",
" </tr>\n",
Expand All @@ -119,10 +119,10 @@
],
"text/plain": [
" a b fit_type ch_name\n",
"0 -1.052551 1.510974 custom 0"
"0 -1.111201 1.510531 custom 0"
]
},
"execution_count": 3,
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -133,16 +133,16 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"slope_fit_2 = irasa(sig, fs=fs, band=f_range, psd_kwargs={'nperseg': 4 * fs}).get_slopes(fit_func=CustomFitFun)"
"slope_fit_2 = irasa(sig, fs=fs, band=f_range, psd_kwargs={'nperseg': 4 * fs}).fit_aperiodic_model(fit_func=CustomFitFun)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 7,
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -175,8 +175,8 @@
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>-1.067699</td>\n",
" <td>1.500347</td>\n",
" <td>-1.125121</td>\n",
" <td>1.500167</td>\n",
" <td>custom</td>\n",
" <td>0</td>\n",
" </tr>\n",
Expand All @@ -186,10 +186,10 @@
],
"text/plain": [
" a b fit_type ch_name\n",
"0 -1.067699 1.500347 custom 0"
"0 -1.125121 1.500167 custom 0"
]
},
"execution_count": 5,
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -200,7 +200,7 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 8,
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -235,19 +235,19 @@
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>0.006699</td>\n",
" <td>0.980793</td>\n",
" <td>-2965.641163</td>\n",
" <td>-2974.418286</td>\n",
" <td>0.007469</td>\n",
" <td>0.978620</td>\n",
" <td>-2900.899570</td>\n",
" <td>-2909.676693</td>\n",
" <td>custom</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>0.000291</td>\n",
" <td>0.999139</td>\n",
" <td>-4832.361294</td>\n",
" <td>-4841.138417</td>\n",
" <td>0.000350</td>\n",
" <td>0.998963</td>\n",
" <td>-4721.685378</td>\n",
" <td>-4730.462501</td>\n",
" <td>custom</td>\n",
" <td>0</td>\n",
" </tr>\n",
Expand All @@ -257,11 +257,11 @@
],
"text/plain": [
" mse r_squared BIC AIC fit_type ch_name\n",
"0 0.006699 0.980793 -2965.641163 -2974.418286 custom 0\n",
"0 0.000291 0.999139 -4832.361294 -4841.138417 custom 0"
"0 0.007469 0.978620 -2900.899570 -2909.676693 custom 0\n",
"0 0.000350 0.998963 -4721.685378 -4730.462501 custom 0"
]
},
"execution_count": 6,
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
Expand Down
Loading