# Average EEG signal across various disorders

This tutorial demonstrates how to compute and visualize the average
EEG signal across various disorders using `mne`, `pandas`, and
`seaborn` in conjunction with `almirah`.

## Setup

First, we'll import the necessary libraries and set the log level for MNE.

```python
import mne
import pandas as pd
import seaborn as sns

from almirah import Dataset

mne.set_log_level(False)
```

## Loading the Dataset

Next, we'll load the dataset and query the EEG files.

```python
ds = Dataset(name="calm-brain")
eeg_header_files = ds.query(datatype="eeg", task="rest", extension=".vhdr")
eeg_data_files = ds.query(datatype="eeg", task="rest", extension=".eeg")
len(eeg_data_files)
```

This should give the total number of EEG files:

    1120

We then download the EEG data files.

```python
for file in eeg_data_files:
    file.download()
```

## Querying the Database

We connect to the database and query the presenting disorders table.

```python
db = ds.components[2]
db.connect("username", "password")
df = ds.query(table="psychiatric_diagnostic_profile")
df[["subject", "session", "addiction"]].head()
```

This displays the first few rows of the queried table in a DataFrame format.

<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle.
    }
    .dataframe tbody tr th {
        vertical-align: top.
    }
    .dataframe thead th {
        text-align: right.
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>subject</th>
      <th>session</th>
      <th>addiction</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>D0019</td>
      <td>101</td>
      <td>0</td>
    </tr>
    <tr>
      <th>1</th>
      <td>D0019</td>
      <td>111</td>
      <td>0</td>
    </tr>
    <tr>
      <th>2</th>
      <td>D0020</td>
      <td>101</td>
      <td>0</td>
    </tr>
    <tr>
      <th>3</th>
      <td>D0020</td>
      <td>111</td>
      <td>&lt;NA&gt;</td>
    </tr>
    <tr>
      <th>4</th>
      <td>D0021</td>
      <td>101</td>
      <td>0</td>
    </tr>
  </tbody>
</table>
</div>

## Processing the EEG Data

We define functions to compute the mean EEG signal and retrieve the disorders.

```python
def get_eeg_mean(file):
    raw = mne.io.read_raw_brainvision(file.path)
    return raw.get_data().mean()

def get_disorders(file):
    disorders = []
    subject, session = file.tags["subject"], file.tags["session"]
    filtered_df = df[(df["subject"] == subject) & (df["session"] == session)]

    if filtered_df.empty:
        print(subject, session)
        return None
    
    for column in ["addiction", "bipolar", "dementia", "ocd", "schizophrenia"]:
        presence = filtered_df.iloc[0][column]
        if not pd.isna(presence) and presence:
            disorders.append(column)
    
    return disorders if disorders else ["healthy"]

def file_func(file):
    mean_eeg, disorders = get_eeg_mean(file), get_disorders(file)

    if not disorders:
        return pd.DataFrame()
        
    mean_df = pd.DataFrame({"mean": [mean_eeg] * len(disorders), "disorder": disorders})
    return mean_df.dropna()
```

We process the EEG header files to compute the mean EEG signal and retrieve the disorders.

```python
mean_dfs = list(map(file_func, eeg_header_files))
mean_dfs = [df for df in mean_dfs if not df.empty]
mean_df = pd.concat(mean_dfs, sort=False)
mean_df.head()
```

This displays the first few rows of the combined DataFrame.

<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle.
    }
    .dataframe tbody tr th {
        vertical-align: top.
    }
    .dataframe thead th {
        text-align: right.
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>mean</th>
      <th>disorder</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>-0.008766</td>
      <td>healthy</td>
    </tr>
    <tr>
      <th>1</th>
      <td>0.000457</td>
      <td>addiction</td>
    </tr>
    <tr>
      <th>2</th>
      <td>-0.006335</td>
      <td>healthy</td>
    </tr>
    <tr>
      <th>3</th>
      <td>-0.002764</td>
      <td>healthy</td>
    </tr>
    <tr>
      <th>4</th>
      <td>-0.008269</td>
      <td>ocd</td>
    </tr>
  </tbody>
</table>
</div>

We compute the mean EEG signal for each disorder.

```python
mean_df.groupby("disorder").mean()
```

This displays the mean EEG signal for each disorder.

<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle.
    }
    .dataframe tbody tr th {
        vertical-align: top.
    }
    .dataframe thead th {
        text-align: right.
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>mean</th>
    </tr>
    <tr>
      <th>disorder</th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>addiction</th>
      <td>0.003414</td>
    </tr>
    <tr>
      <th>bipolar</th>
      <td>0.001613</td>
    </tr>
    <tr>
      <th>dementia</th>
      <td>0.010485</td>
    </tr>
    <tr>
      <th>healthy</th>
      <td>0.002449</td>
    </tr>
    <tr>
      <th>ocd</th>
      <td>-0.000875</td>
    </tr>
    <tr>
      <th>schizophrenia</th>
      <td>0.005444</td>
    </tr>
  </tbody>
</table>
</div>

## Visualizing the Results

We visualize the distribution of the mean EEG signal for each disorder using a violin plot.

```python
ax = sns.violinplot(data=mean_df, x="mean", hue="disorder")
sns.move_legend(ax, "upper left", bbox_to_anchor=(1, 1))
```
    
This generates the plot:

![png](../images/multimodal/average-eeg-across-disorders.png)

This concludes the tutorial. You've learned how different modalities
can be strung together to perform analysis involving multiple
modalities.