Source space to brain space plotting

It looks like the source space (src) is in head coordinates but when I tried to follow this to transform to surface RAS (Source alignment and coordinate frames — MNE 0.22.0 documentation) it didn’t work. How do you transform coordinates from source space to plot on the brain object (stc.plot), the same coordinates in brain.geo['lh'].coords[vertex]?

import os
import os.path as op
import numpy as np
import mne
from mne.datasets import sample
import nibabel as nib

data_path = sample.data_path()
subjects_dir = op.join(data_path, 'subjects')
subject = 'sample'
sample_dir = op.join(data_path, 'MEG', subject)

fname_raw = op.join(sample_dir, 'sample_audvis_raw.fif')
raw =, preload=True)
events = mne.find_events(raw)
# choose event 3, left visual field stimulus
epochs = mne.Epochs(raw, events, event_id=3, tmin=-0.5, tmax=1, baseline=None)
evoked = epochs.average()

# Read inverse solution
fname_inv = op.join(sample_dir, 'sample_audvis-meg-oct-6-meg-inv.fif')
inv = mne.minimum_norm.read_inverse_operator(fname_inv)

# Apply inverse solution, set to obtain an :class:`mne.SourceEstimate` object
snr = 3.0
lambda2 = 1.0 / snr ** 2
stc = mne.minimum_norm.apply_inverse(evoked, inv, lambda2, 'dSPM', pick_ori='normal')

fwd = mne.read_forward_solution(
    op.join(sample_dir, 'sample_audvis-meg-eeg-oct-6-fwd.fif'))
mne.convert_forward_solution(fwd, surf_ori=True, copy=False)

lh, rh = fwd['src']
vert = lh['rr'][stc.lh_vertno[99]]

os.environ['SUBJECTS_DIR'] = subjects_dir
os.environ['SUBJECT'] = subject

brain = stc.plot(smoothing_steps=0, hemi='both',
                     colorbar=False, time_viewer=False)

trans_fname = op.join(sample_dir, 'sample_audvis_raw-trans.fif')
trans = mne.read_trans(trans_fname)

t1w = nib.load(op.join(data_path, 'subjects', 'sample', 'mri', 'T1.mgz'))
t1w = nib.Nifti1Image(t1w.dataobj, t1w.affine)
t1w.header['xyzt_units'] = np.array(10, dtype='uint8')
t1_mgh = nib.MGHImage(t1w.dataobj, t1w.affine)

vox_to_mri = t1_mgh.header.get_vox2ras_tkr()
mri_to_vox = np.linalg.inv(vox_to_mri)

vert_mri = mne.transforms.apply_trans(trans, vert, move=True)
# Then transform to voxel space, after converting from meters to millimeters
vert_vox = mne.transforms.apply_trans(
    mri_to_vox, vert_mri * 1e3, move=True)

print(brain.geo['lh'].coords[99])  # idea is that they match

Also lh['coord_frame'] is 4 or head space where lh is the left src.

The MRI Surface RAS <-> Head transform is produced during your co-registration step. The famous “trans” file that you need to construct the forward model and such.

For the sample data, it’s located in: MEG/sample/sample_audvis_raw-trans.fif

But you already got that, ok :slight_smile:

Can you tell a bit more about what you’re trying to accomplish? Because looking at your code, I can see some things that are clearly wrong, but I can’t correct them as I’m not certain what your end goal is.

In the simplest case, if you want to plot a vertex that is part of the source space on top of the brain, you do brain.add_foci(stc.lh_vertno[99], coords_as_verts = True). But perhaps you want something more advanced.

I want to find a normal vector to a point on the plane (using the two nearest points) and then project all points within 30 cm to that plane in order to determine their angle in the plane for use in simulating a traveling wave. So it would be nice to plot two vectors from a point to the two nearest neighbors, their cross product and then also the projection onto the plane of a few choice points in the cortical patch. I don’t think built-in functions are going to quite cover that, unfortunately.