EEG forward operator with a template MRI

This tutorial explains how to compute the forward operator from EEG data using the standard template MRI subject fsaverage.

Caution

Source reconstruction without an individual T1 MRI from the subject will be less accurate. Do not over interpret activity locations which can be off by multiple centimeters.

# Authors: Alexandre Gramfort <alexandre.gramfort@inria.fr>
#          Joan Massich <mailsik@gmail.com>
#
# License: BSD Style.

import os.path as op

import mne
from mne.datasets import eegbci
from mne.datasets import fetch_fsaverage

# Download fsaverage files
fs_dir = fetch_fsaverage(verbose=True)
subjects_dir = op.dirname(fs_dir)

# The files live in:
subject = 'fsaverage'
trans = 'fsaverage'  # MNE has a built-in fsaverage transformation
src = op.join(fs_dir, 'bem', 'fsaverage-ico-5-src.fif')
bem = op.join(fs_dir, 'bem', 'fsaverage-5120-5120-5120-bem-sol.fif')

Out:

0 files missing from /home/circleci/project/mne/datasets/_fsaverage/root.txt in /home/circleci/mne_data/MNE-sample-data/subjects
0 files missing from /home/circleci/project/mne/datasets/_fsaverage/bem.txt in /home/circleci/mne_data/MNE-sample-data/subjects/fsaverage

Load the data

We use here EEG data from the BCI dataset.

Note

See Plotting sensor layouts of EEG Systems to view all the standard EEG montages available in MNE-Python.

raw_fname, = eegbci.load_data(subject=1, runs=[6])
raw = mne.io.read_raw_edf(raw_fname, preload=True)

# Clean channel names to be able to use a standard 1005 montage
new_names = dict(
    (ch_name,
     ch_name.rstrip('.').upper().replace('Z', 'z').replace('FP', 'Fp'))
    for ch_name in raw.ch_names)
raw.rename_channels(new_names)

# Read and set the EEG electrode locations
montage = mne.channels.make_standard_montage('standard_1005')

raw.set_montage(montage)
raw.set_eeg_reference(projection=True)  # needed for inverse modeling

# Check that the locations of EEG electrodes is correct with respect to MRI
mne.viz.plot_alignment(
    raw.info, src=src, eeg=['original', 'projected'], trans=trans,
    show_axes=True, mri_fiducials=True, dig='fiducials')
../../_images/sphx_glr_plot_eeg_no_mri_001.png

Out:

Extracting EDF parameters from /home/circleci/mne_data/MNE-eegbci-data/physiobank/database/eegmmidb/S001/S001R06.edf...
EDF file detected
Setting channel info structure...
Creating raw.info structure...
Reading 0 ... 19999  =      0.000 ...   124.994 secs...
DigMontage is a superset of info. 279 in DigMontage will be ignored. The ignored channels are: {'POO10', 'FFC5h', 'AFpz', 'FFC1', 'C2h', 'FTT9', 'TP10h', 'PO1h', 'PPO2h', 'FFT10', 'P9h', 'TTP7h', 'POO1', 'PO9h', 'PO2', 'AFp9h', 'AFF8h', 'TP8h', 'CCP6h', 'I1h', 'AFp1h', 'PPO7h', 'F6h', 'FCC6h', 'POO6h', 'O2h', 'AFp3', 'AFF4', 'FFT7', 'FFC1h', 'PPO1h', 'TPP9', 'AF4h', 'AFF10h', 'CCP1h', 'PPOz', 'I2', 'F3h', 'FCC5h', 'O1h', 'F1h', 'OIz', 'T6', 'A2', 'C3h', 'FTT7h', 'AFp7', 'TP9h', 'AF1', 'PPO6', 'CPPz', 'AFF5', 'FCC4', 'PPO6h', 'POO3', 'FT9h', 'TPP8', 'AF8h', 'CPP3h', 'POO2h', 'P10', 'CPP4h', 'CP6h', 'FFC3', 'POO9h', 'PPO10h', 'F2h', 'POO5', 'A1', 'PO6', 'AF2h', 'FTT10h', 'FC1h', 'PO5', 'Fp2h', 'CCP2h', 'PO5h', 'OI2', 'P9', 'AFF5h', 'I1', 'FFC6', 'PPO8', 'AFF3', 'TP9', 'AF6', 'POO10h', 'FC2h', 'FFC5', 'POO8', 'CPP2h', 'PO7h', 'AFp6', 'T7h', 'FC3h', 'P5h', 'POOz', 'T3', 'F9h', 'TP10', 'PO9', 'FCC3h', 'POO9', 'TTP9h', 'Fp1h', 'FC6h', 'C6h', 'AFp7h', 'FFC4h', 'AF2', 'C1h', 'C5h', 'FTT9h', 'FFC6h', 'FC4h', 'CP3h', 'FTT10', 'F10h', 'FCC2', 'T4', 'AF9', 'TPP9h', 'PO3h', 'PPO4', 'FCC1h', 'T8h', 'PO8h', 'AFF1h', 'AFF7h', 'CP1h', 'CCP2', 'AF10', 'PO6h', 'AFp4', 'POO6', 'FFT9', 'CPP6', 'PO10h', 'AFFz', 'PPO3h', 'FT10', 'POO5h', 'AFF9', 'TP7h', 'AFp2', 'CPP5', 'PPO5', 'PPO2', 'CPP3', 'FFC2', 'CPP1', 'CP4h', 'FCC1', 'AFF2h', 'CPP4', 'T5', 'AFp8', 'POO8h', 'I2h', 'PPO7', 'FT7h', 'OI1', 'AFF6', 'F8h', 'CP2h', 'F4h', 'AF5', 'FFT10h', 'P6h', 'CCP3h', 'AF6h', 'CPP5h', 'TPP10', 'AF5h', 'CP5h', 'TPP8h', 'AF9h', 'AFp10', 'CCP4h', 'FCCz', 'CPP6h', 'PPO5h', 'TTP9', 'AFF2', 'PPO3', 'TTP8', 'CCP6', 'TPP7', 'AF7h', 'AF1h', 'FFT9h', 'AFF4h', 'M1', 'FT10h', 'FTT8h', 'PPO10', 'FTT8', 'T9h', 'P3h', 'PPO1', 'FCC2h', 'CCPz', 'F5h', 'POO1h', 'PPO9', 'FCC3', 'AFp1', 'POO7', 'PO4h', 'TTP8h', 'CCP5h', 'CPP1h', 'FFT8h', 'TPP7h', 'AFp9', 'C4h', 'FTT7', 'AFp2h', 'CCP1', 'P4h', 'TTP7', 'AFF3h', 'AF3h', 'CCP5', 'FFC4', 'P8h', 'POO7h', 'T10h', 'AFp8h', 'AFF6h', 'P1h', 'P10h', 'TPP10h', 'OI2h', 'FFT7h', 'AFF7', 'FCC4h', 'AFp10h', 'PPO4h', 'PO10', 'F7h', 'FCC6', 'AFp4h', 'CCP3', 'FFT8', 'TTP10', 'FT9', 'P2h', 'AFF1', 'POO4', 'FFC2h', 'P7h', 'FT8h', 'AFF10', 'FCC5', 'M2', 'TTP10h', 'AFF8', 'POO2', 'CPP2', 'CCP4', 'AFp5h', 'FFCz', 'PPO9h', 'F10', 'POO4h', 'PPO8h', 'FFC3h', 'FC5h', 'F9', 'AF10h', 'AFp5', 'AFp3h', 'POO3h', 'PO2h', 'AFF9h', 'AFp6h', 'PO1', 'OI1h'}
Adding average EEG reference projection.
1 projection items deactivated
Average reference projection was added, but has not been applied yet. Use the apply_proj method to apply it.
Reading /home/circleci/mne_data/MNE-sample-data/subjects/fsaverage/bem/fsaverage-ico-5-src.fif...
Using outer_skin.surf for head surface.

Setup source space and compute forward

fwd = mne.make_forward_solution(raw.info, trans=trans, src=src,
                                bem=bem, eeg=True, mindist=5.0, n_jobs=1)
print(fwd)

# for illustration purposes use fwd to compute the sensitivity map
eeg_map = mne.sensitivity_map(fwd, ch_type='eeg', mode='fixed')
eeg_map.plot(time_label='EEG sensitivity', subjects_dir=subjects_dir,
             clim=dict(lims=[5, 50, 100]))
../../_images/sphx_glr_plot_eeg_no_mri_002.png

Out:

Source space          : /home/circleci/mne_data/MNE-sample-data/subjects/fsaverage/bem/fsaverage-ico-5-src.fif
MRI -> head transform : /home/circleci/project/mne/data/fsaverage/fsaverage-trans.fif
Measurement data      : instance of Info
Conductor model   : /home/circleci/mne_data/MNE-sample-data/subjects/fsaverage/bem/fsaverage-5120-5120-5120-bem-sol.fif
Accurate field computations
Do computations in head coordinates
Free source orientations

Reading /home/circleci/mne_data/MNE-sample-data/subjects/fsaverage/bem/fsaverage-ico-5-src.fif...
Read 2 source spaces a total of 20484 active source locations

Coordinate transformation: MRI (surface RAS) -> head
     0.999994  0.003552  0.000202      -1.76 mm
    -0.003558  0.998389  0.056626      31.09 mm
    -0.000001 -0.056626  0.998395      39.60 mm
     0.000000  0.000000  0.000000       1.00

Read  64 EEG channels from info
Head coordinate coil definitions created.
Source spaces are now in head coordinates.

Setting up the BEM model using /home/circleci/mne_data/MNE-sample-data/subjects/fsaverage/bem/fsaverage-5120-5120-5120-bem-sol.fif...

Loading surfaces...
Three-layer model surfaces loaded.

Loading the solution matrix...

Loaded linear_collocation BEM solution from /home/circleci/mne_data/MNE-sample-data/subjects/fsaverage/bem/fsaverage-5120-5120-5120-bem-sol.fif
Employing the head->MRI coordinate transform with the BEM model.
BEM model fsaverage-5120-5120-5120-bem-sol.fif is now set up

Source spaces are in head coordinates.
Checking that the sources are inside the surface and at least    5.0 mm away (will take a few...)
    Skipping interior check for 2433 sources that fit inside a sphere of radius   47.7 mm
    Skipping solid angle check for 0 points using Qhull
    Skipping interior check for 2241 sources that fit inside a sphere of radius   47.7 mm
    Skipping solid angle check for 0 points using Qhull

Computing EEG at 20484 source locations (free orientations)...

Finished.
<Forward | MEG channels: 0 | EEG channels: 64 | Source space: Surface with 20484 vertices | Source orientation: Free>
    64 out of 64 channels remain after picking
Adding average EEG reference projection.
Using control points [0.35186294 0.5925817  1.        ]

Total running time of the script: ( 0 minutes 32.273 seconds)

Estimated memory usage: 391 MB

Gallery generated by Sphinx-Gallery