Morph dipole to fsaverage brain

External Email - Use Caution

Dear MNE-Python community,

I have a bunch of dipoles that were fitted in the brains of several subjects.
Now I want to visualize the locations of all these dipoles in a shared brain.
Is there a way to morph the positions of the dipoles from the individual
subjects to a template brain, for example fsaverage?

I see that there is a head_to_mni function that will convert the position to MNI
space. That is close, but does not match fsaverage space. Or is there a way to
visualize the MNI brain in a 3d sort of way (not MRI image slices)?

best,
Marijn.

External Email - Use Caution

Hi Marijn,

Is morph = mne.compute_source_morph() and morph.apply() what you are
looking for?

Best,

Christian

External Email - Use Caution

hi,

how do you want to visualize this? you can go from MNI to fsaverage
surface RAS but the dipole will not be positioned on the surface.

Alex

External Email - Use Caution

fsaverage is in MNI space, so you should be able to use that affine if you
want. If they don't land in the right place it suggests some problem with
how you're applying the transformation or a problem return the
transformation itself, which you could manually adjust using tkregister
(then probably rerun the subsequent recon steps) or something similar.

If you want to go beyond affine, you could use the SDR volumetric
transformation code in compute_source_morph. You could try using a full 1mm
MRI resolution, but this might run into memory problems. You could code it
yourself if you want to try it from reading the MNE code, but you have to
be careful about the coordinate frames.

We could extend compute_source_morph to work with discrete source spaces
using this full-resolution MRI intermediate approach. Then you could set up
each subjects one dipole (or as many ECDs add you have) as a discrete
source space with one element, and morph it/them.

Eric

External Email - Use Caution

Hi Eric,

if I morph the dipoles to MNI space (mne.head_to_mni(dip.pos)) and throw them on
top of an fsaverage brain with brain.add_foci(morphed_dip_pos), I don't get
reasonable results, points are floating way outside of the brain. They are sort
of aligned on the brain, so origin point may be reasonable, but the scaling I
wouldn't exactly call close enough.

Making compute_source_morph work for discrete source spaces would be a great
solution. But that sounds hard :slight_smile:

best,
Marijn.

External Email - Use Caution

Hi Marijn,

Have you tried to pick the closest subject surface to your dipole location
and use the morph_surface to get the alignment? Not know how the morph
works, ny hack would something like this:

elec_xyz = np.random.randn(3)*50
surf_xyz, _ = nibabel.freesurfer.read_geometry('sub-0001/surf/lh.pial')

distances = np.sum((surf_xyz - elec_xyz[None,:])**2, 1)
closest = np.argmin(distances)
data = np.zeros(len(surf_xyz))
data[closest] = 1.

stc = mne.SourceEstimate(data, vertices=range(len(surf_xyz)), tmin=0.,
tstep=1., subject='sub-0001')
morph = mne.compute_source_morph(stc, subject_to='fsaverage',
subjects_dir='./')
stc_morph = morph.apply(stc)
vert_idx = stc_morph.vertices[np.argmax(stc_morph.data)] # fixme deal with
left and right hemi

surf_xyz, _ = nibabel.freesurfer.read_geometry('fsaverage/surf/lh.pial')

plt.plot(*surf_xyz[vert_idx])

JR

External Email - Use Caution

Marijn,

If you can replicate the mni problem with sample or privately share the MRI
with me I'm happy to look into the MNI problem.

Also please open an issue about morphing discrete source spaces. We should
have a way to do it, and I actually don't think it will require many
changes.

Eric

External Email - Use Caution

Hi Eric,

I've narrowed it down to a problem with the talairach.xfm files in the
FreeSurfer folder. Thanks for your suggestion!

Here is a script testing dipole plotting in various ways on the
MNE-Sample data, where all is well:

https://gist.github.com/wmvanvliet/c8e3aa6f312da5a82d75ba44b38badcc

best,
Marijn.