Hi all,
I’m trying to morph source estimates from a subject’s custom hippocampus surface to the fsaverage
template using mne.compute_source_morph
. However, the morphing appears misaligned — the activity does not map properly to the corresponding neighboring vertices on fsaverage
.
To test this, I created a synthetic STC with some activity at some known vertices. After morphing, the peak appears at a distant or incorrect location on fsaverage
. This suggests that the surface registration (?h.sphere.reg
) might not be accurate or aligned.
Here’s a summary of what I did:
- Created hippocampus-only surface and sphere (
mris_sphere
) - Registered to a custom template (
mris_register
) - Built a source space (
mne.setup_source_space
) - Applied
compute_source_morph
and tested STC projection
Is there a reliable way to ensure correct morphing when using non-standard surfaces (like hippocampus-only)?
Any advice would be appreciated!
here is my test code:
import mne
import pdb # Importing the debugger
subjects_dir = '/media/dip_linux/Elements/Visual_p3_data/'
subject_trans = '/media/dip_linux/Elements/Visual_p3_data/3847/3847-trans1.fif'
fs_trans = '/media/dip_linux/Elements/Visual_p3_data/fsaverage/fsaverage-trans1.fif'
subject = '3847'
fs_subject = 'fsaverage'
# Compute source spaces
hippocampal_src = mne.setup_source_space(subject=subject, surface='smoothwm', spacing=3,
subjects_dir=subjects_dir, n_jobs=3)
fs_hippocampal_src = mne.setup_source_space(subject=fs_subject, surface='smoothwm', spacing=3,
subjects_dir=subjects_dir, n_jobs=3)
# Create a single 3D visualization with both subjects
fig = mne.viz.plot_alignment(subject=subject, subjects_dir=subjects_dir, surfaces="smoothwm",
src=hippocampal_src, trans=subject_trans)
# Add fsaverage to the same figure
mne.viz.plot_alignment(subject=fs_subject, subjects_dir=subjects_dir, surfaces="smoothwm",
src=fs_hippocampal_src, trans=fs_trans, fig=fig)
# Adjust the 3D view
mne.viz.set_3d_view(fig, azimuth=180, elevation=90, distance=0.30, focalpoint=(-0.03, -0.01, 0.03))
# testing
# Morph subject source space to fsaverage
morph = mne.compute_source_morph(src=hippocampal_src, subject_from=subject, subject_to='fsaverage',src_to=fs_hippocampal_src,
subjects_dir=subjects_dir)
import numpy as np
# Create synthetic STC
n_verts = sum(s['nuse'] for s in hippocampal_src)
vertices = [s['vertno'] for s in hippocampal_src]
n_times = 500
tmin = 0
tstep = 1e-3 # 1 ms per sample
# Simulate peak at some random vertex and time 300 ms (index 300)
stc_data = np.zeros((n_verts, n_times))
peak_vertices = [50, 200, 250, 300, 450, 500, 650, 800]
for v in peak_vertices:
stc_data[v, 300] = 25.0
stc = mne.SourceEstimate(stc_data, vertices=vertices,
tmin=tmin, tstep=tstep,
subject=subject)
# Morph to fsaverage
stc_fs = morph.apply(stc)
# Find peak vertex in morphed stc
peak_vertex, peak_time = stc_fs.get_peak()
print(f"Morphed peak at vertex {peak_vertex}, time {peak_time:.3f}s")
# Plot morph result
stc.plot(initial_time=0.3, surface='smoothwm', hemi='both', smoothing_steps=5)
stc_fs.plot(initial_time=0.3, surface='smoothwm', hemi='both',smoothing_steps=5)
n_verts = sum(s['nuse'] for s in hippocampal_src)
vertices = [s['vertno'] for s in hippocampal_src]
# Create a source estimate
stc = mne.SourceEstimate(np.eye(n_verts), vertices, 0, 1e-3, subject=subject)
stc_morphed = morph.apply(stc)
stc_morphed.plot(initial_time=0.3, surface='smoothwm')
results:
-
Source space of hippocampus : subject (top) and fsaverage (bottom)
-
Subject’s stc data and morphed stc data → fsaverage
best,
Dip