# Processing EEG with MNE-Python

This tutorial demonstrates how to process EEG data using MNE-Python
and `almirah`. The goal is to show how to interface with other
analysis libraries and generate plots, rather than derive insights.

## Setup

First, we'll import the necessary libraries and set up the logging and
warning configurations.

```python
import mne
import warnings
import numpy as np
import matplotlib.pyplot as plt

from almirah import Layout

mne.set_log_level(False)
warnings.filterwarnings('ignore')
```

## Loading the Data

Next, we'll set up the layout to access the EEG data.

```python
lay = Layout(root="/path/to/data", specification_name="bids")
lay
```

This should output:

    <Layout root: '/path/to/data'>
    
We can also get the layout using the specification name:

```python
lay = Layout.get(specification_name='bids')
```

We can query the layout to find all EEG files with the `.vhdr` extension:

```python
files = lay.query(datatype="eeg", extension=".vhdr")
len(files)
```

This gives the total number of EEG files:

    2223

## Querying Specific Files

To query specific files, we can filter by subject, session, datatype, task, and extension:

```python
vhdr_file = lay.query(subject="D0019", session="101", datatype="eeg", task="rest", extension=".vhdr")[0]
eeg_file = lay.query(subject="D0019", session="101", datatype="eeg", task="rest", extension=".eeg")[0]
montage_file = lay.query(subject="D0019", session="101", space="CapTrak", suffix="electrodes")[0]

print(vhdr_file.rel_path)
```

This should output the relative path of the file:

    sub-D0019/ses-101/eeg/sub-D0019_ses-101_task-rest_run-01_eeg.vhdr

We can then download the EEG file:

```python
eeg_file.download()
```

## Setting Up the Montage and Reading Raw Data

Next, we set up the montage and read the raw EEG data:

```python
montage = mne.channels.read_custom_montage(montage_file.path)
raw = mne.io.read_raw_brainvision(vhdr_file.path, preload=True)
raw.set_montage(montage)
raw.info["bads"] = ["VREF"]

raw.info
```

<details open>
  <summary><strong>General</strong></summary>
  **Measurement date:** Unknown  
  **Experimenter:** Unknown  
  **Participant:** Unknown  
</details>

<details open>
  <summary><strong>Channels</strong></summary>
  **Digitized points:** 132 points  
  **Good channels:** 128 EEG, 5 misc  
  **Bad channels:** VREF  
  **EOG channels:** Not available  
  **ECG channels:** Not available  
</details>

<details open>
  <summary><strong>Data</strong></summary>
  **Sampling frequency:** 1000.00 Hz  
  **Highpass:** 0.00 Hz  
  **Lowpass:** 500.00 Hz  
</details>

## Preprocessing

We apply a band-pass filter and plot the raw data:

```python
# Apply a band-pass filter
raw.filter(1, 40, fir_design="firwin")

# Plot the raw data
raw.plot(n_channels=30, duration=30, scalings="auto")
plt.close()
```

![png](../images/eeg/raw-plot.png)
    
## Artifact Removal using ICA

We set up and apply Independent Component Analysis (ICA) to remove artifacts:

```python
# Setup ICA
ica = mne.preprocessing.ICA(n_components=15, random_state=97)
ica.fit(raw)

# Plot ICA components
ica.plot_components()

# Select bad components manually (usually by visual inspection)
ica.exclude = [0, 6, 14]  # Example: components 0 and 1 are eye blinks and heartbeats

# Apply ICA removal
raw_clean = ica.apply(raw.copy())
```
    
![png](../images/eeg/ica-plot.png)
    
## Power Spectral Analysis

We compute and plot the Power Spectral Density (PSD):

```python
# Compute and plot Power Spectral Density (PSD)
raw_clean.compute_psd().plot(exclude="bads", amplitude=False)
plt.show()
```
    
![png](../images/eeg/psd-plot.png)

We also plot the topographic distribution of the spectral power:

```python
raw_clean.compute_psd().plot_topomap(ch_type="eeg", agg_fun=np.median)
plt.close()
```
    
![png](../images/eeg/spectrum-topo-plot.png)

This concludes the tutorial. You've learned how to interface with
MNE-Python to process EEG data using `almirah`.
