Use source space morphing#

This example shows how to use source space morphing (as opposed to SourceEstimate morphing) to create data that can be compared between subjects.

Warning

Source space morphing will likely lead to source spaces that are less evenly sampled than source spaces created for individual subjects. Use with caution and check effects on localization before use.

# Authors: Denis A. Engemann <denis.engemann@gmail.com>
#          Eric larson <larson.eric.d@gmail.com>
#
# License: BSD-3-Clause
import mne

data_path = mne.datasets.sample.data_path()
subjects_dir = data_path / 'subjects'
fname_trans = (
    data_path / 'MEG' / 'sample' / 'sample_audvis_raw-trans.fif')
fname_bem = (
    subjects_dir / 'sample' / 'bem' / 'sample-5120-bem-sol.fif')
fname_src_fs = (
    subjects_dir / 'fsaverage' / 'bem' / 'fsaverage-ico-5-src.fif')
raw_fname = data_path / 'MEG' / 'sample' / 'sample_audvis_raw.fif'

# Get relevant channel information
info = mne.io.read_info(raw_fname)
info = mne.pick_info(info, mne.pick_types(info, meg=True, eeg=False,
                                          exclude=[]))

# Morph fsaverage's source space to sample
src_fs = mne.read_source_spaces(fname_src_fs)
src_morph = mne.morph_source_spaces(src_fs, subject_to='sample',
                                    subjects_dir=subjects_dir)

# Compute the forward with our morphed source space
fwd = mne.make_forward_solution(info, trans=fname_trans,
                                src=src_morph, bem=fname_bem)
mag_map = mne.sensitivity_map(fwd, ch_type='mag')

# Return this SourceEstimate (on sample's surfaces) to fsaverage's surfaces
mag_map_fs = mag_map.to_original_src(src_fs, subjects_dir=subjects_dir)

# Plot the result, which tracks the sulcal-gyral folding
# outliers may occur, we'll place the cutoff at 99 percent.
kwargs = dict(clim=dict(kind='percent', lims=[0, 50, 99]),
              # no smoothing, let's see the dipoles on the cortex.
              smoothing_steps=1, hemi='rh', views=['lat'])

# Now note that the dipoles on fsaverage are almost equidistant while
# morphing will distribute the dipoles unevenly across the given subject's
# cortical surface to achieve the closest approximation to the average brain.
# Our testing code suggests a correlation of higher than 0.99.

brain_subject = mag_map.plot(  # plot forward in subject source space (morphed)
    time_label='Morphed', subjects_dir=subjects_dir, **kwargs)

brain_fs = mag_map_fs.plot(  # plot forward in original source space (remapped)
    time_label='Remapped', subjects_dir=subjects_dir, **kwargs)
source space morphingsource space morphing
    Read a total of 3 projection items:
        PCA-v1 (1 x 102)  idle
        PCA-v2 (1 x 102)  idle
        PCA-v3 (1 x 102)  idle
    Reading a source space...
    [done]
    Reading a source space...
    [done]
    2 source spaces read
Reading destination surface /home/circleci/mne_data/MNE-sample-data/subjects/sample/surf/lh.white
    Triangle neighbors and vertex normals...
Mapping lh fsaverage -> sample (nearest neighbor)...
[done]

Reading destination surface /home/circleci/mne_data/MNE-sample-data/subjects/sample/surf/rh.white
    Triangle neighbors and vertex normals...
Mapping rh fsaverage -> sample (nearest neighbor)...
[done]

Source space          : <SourceSpaces: [<surface (lh), n_vertices=155407, n_used=10242>, <surface (rh), n_vertices=156866, n_used=10242>] MRI (surface RAS) coords, subject 'sample', ~24.9 MB>
MRI -> head transform : /home/circleci/mne_data/MNE-sample-data/MEG/sample/sample_audvis_raw-trans.fif
Measurement data      : instance of Info
Conductor model   : /home/circleci/mne_data/MNE-sample-data/subjects/sample/bem/sample-5120-bem-sol.fif
Accurate field computations
Do computations in head coordinates
Free source orientations

Read 2 source spaces a total of 20484 active source locations

Coordinate transformation: MRI (surface RAS) -> head
     0.999310  0.009985 -0.035787      -3.17 mm
     0.012759  0.812405  0.582954       6.86 mm
     0.034894 -0.583008  0.811716      28.88 mm
     0.000000  0.000000  0.000000       1.00

Read 306 MEG channels from info
105 coil definitions read
Coordinate transformation: MEG device -> head
     0.991420 -0.039936 -0.124467      -6.13 mm
     0.060661  0.984012  0.167456       0.06 mm
     0.115790 -0.173570  0.977991      64.74 mm
     0.000000  0.000000  0.000000       1.00
MEG coil definitions created in head coordinates.
Source spaces are now in head coordinates.

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

Loading surfaces...

Loading the solution matrix...

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

Source spaces are in head coordinates.
Checking that the sources are inside the surface (will take a few...)
Checking surface interior status for 10242 points...
    Found  2154/10242 points inside  an interior sphere of radius   43.6 mm
    Found     0/10242 points outside an exterior sphere of radius   91.8 mm
    Found     9/ 8088 points outside using surface Qhull
[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    4.5s remaining:    0.0s
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    4.5s finished
    Found     0/ 8079 points outside using solid angles
    Total 10233/10242 points inside the surface
Interior check completed in 4540.3 ms
    9 source space points omitted because they are outside the inner skull surface.
Checking surface interior status for 10242 points...
    Found  2113/10242 points inside  an interior sphere of radius   43.6 mm
    Found     0/10242 points outside an exterior sphere of radius   91.8 mm
    Found     4/ 8129 points outside using surface Qhull
[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    4.7s remaining:    0.0s
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    4.7s finished
    Found     1/ 8125 point  outside using solid angles
    Total 10237/10242 points inside the surface
Interior check completed in 4671.5 ms
    5 source space points omitted because they are outside the inner skull surface.

Checking surface interior status for 306 points...
    Found   0/306 points inside  an interior sphere of radius   43.6 mm
    Found 306/306 points outside an exterior sphere of radius   91.8 mm
    Found   0/  0 points outside using surface Qhull
[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    0.0s remaining:    0.0s
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    0.0s finished
    Found   0/  0 points outside using solid angles
    Total 0/306 points inside the surface
Interior check completed in 26.9 ms

Composing the field computation matrix...
[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    1.5s remaining:    0.0s
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    1.5s finished
[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    1.4s remaining:    0.0s
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    1.4s finished
[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    1.6s remaining:    0.0s
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    1.6s finished
[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    0.1s remaining:    0.0s
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    0.1s finished
Computing MEG at 20470 source locations (free orientations)...
[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    3.7s remaining:    0.0s
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    3.7s finished

Finished.
    102 out of 306 channels remain after picking
Mapping lh fsaverage -> sample (nearest neighbor)...
Mapping rh fsaverage -> sample (nearest neighbor)...
Using control points [0.00205101 0.08784125 0.17433707]
Using control points [0.00205101 0.08784125 0.17433707]

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

Estimated memory usage: 592 MB

Gallery generated by Sphinx-Gallery