# Morphing subject's hippocampus source space to fsaverage template

**URL:** <https://mne.discourse.group/t/morphing-subjects-hippocampus-source-space-to-fsaverage-template/10995>\
**Category:** Support & Discussions\
**Tags:** ﻿source-localization\
**Created:** [March 22, 2025, 5:37pm UTC](https://mne.discourse.group/t/morphing-subjects-hippocampus-source-space-to-fsaverage-template/10995 "2025-03-22T17:37:12Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![dasdiptyajit](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/dasdiptyajit/32/4796_2.png) [@dasdiptyajit](https://mne.discourse.group/u/dasdiptyajit)\
**Post date:** [March 22, 2025, 5:37pm UTC](https://mne.discourse.group/t/morphing-subjects-hippocampus-source-space-to-fsaverage-template/10995/1 "2025-03-22T17:37:12Z")

</div>

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:

```python
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

 ![Screenshot from 2025-03-22 18-13-03](https://global.discourse-cdn.com/free1/uploads/mne/original/2X/b/ba37b44da4eb873189162313e384cf85bf58014d.png)

best,  
Dip

---

<div class="post-metadata">

**Author:** ![larsoner](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/larsoner/32/3_2.png) [@larsoner](https://mne.discourse.group/u/larsoner)\
**Post date:** [March 22, 2025, 6:10pm UTC](https://mne.discourse.group/t/morphing-subjects-hippocampus-source-space-to-fsaverage-template/10995/2 "2025-03-22T18:10:43Z")

</div>

Hmm… I would first try seeing if you can take some `.w` file data, which FreeSurfer should be able to understand, and get FreeSurfer to morph that data correctly. Once that works we should hopefully have the machinery in MNE-Python to match what it does. Can you see if you can get some FreeSurfer commands to morph the data correctly?

---

<div class="post-metadata">

**Author:** ![dasdiptyajit](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/dasdiptyajit/32/4796_2.png) [@dasdiptyajit](https://mne.discourse.group/u/dasdiptyajit)\
**Post date:** [March 23, 2025, 10:08pm UTC](https://mne.discourse.group/t/morphing-subjects-hippocampus-source-space-to-fsaverage-template/10995/3 "2025-03-23T22:08:19Z")

</div>

@larsoner Hi Eric, thanks for getting back to this.

Here are some tests results using two subjects with spherical alignment from Freesurfer :

 ![spherical morphing 1](https://global.discourse-cdn.com/free1/uploads/mne/original/2X/8/8878f569a85e8f8776b2ecf27e0349414a6f1896.png)

 ![Sphere mesh (subj1 and fsaverage)](https://global.discourse-cdn.com/free1/uploads/mne/original/2X/b/bdd631365f19f2f58cbc392bb0d21f4e9714c6a2.jpeg)

 ![spherical morphing 2](https://global.discourse-cdn.com/free1/uploads/mne/original/2X/3/39198dc33bc6e9fa1b62ebb96f0da27e7c17d8e1.png)

 ![Sphere mesh (subj2 and fsaverage)](https://global.discourse-cdn.com/free1/uploads/mne/original/2X/e/eea8bfdc23e52138dc5dd938cd502a09ebea7a6e.jpeg)

sub1:

 ![subj 1 stc morphing](https://global.discourse-cdn.com/free1/uploads/mne/original/2X/a/a0187c33c6c3abb6b82331639cca87c7494f48ba.png)

Subject vertex 50 → fsaverage vertices: [5 13 16 23 25 28 37 39 52 65]  
Subject vertex 200 → fsaverage vertices: [270 279 306 315]  
Subject vertex 250 → fsaverage vertices: [299 323]  
Subject vertex 300 → fsaverage vertices: [378 392 393 412]  
Subject vertex 450 → fsaverage vertices: [582 591 599 608 609]

sub2:

 ![subj 2 stc morphing](https://global.discourse-cdn.com/free1/uploads/mne/original/2X/a/a8ab74d2fc6b702eef66752667e466928b68ee9a.png)

Subject vertex 50 → fsaverage vertices: [108 116 127 140]  
Subject vertex 200 → fsaverage vertices: [243 253 263 264]  
Subject vertex 250 → fsaverage vertices: [279 306 315 357]  
Subject vertex 300 → fsaverage vertices: [381 395 396]  
Subject vertex 450 → fsaverage vertices: [606]

Once I managed to remove overlapping intersecting faces from the spherical surface (`?h.sphere`), the quality of the resulting registration (`?h.sphere.reg`) improved significantly. However, the curvature-based spherical alignment is still not perfect. In my experience, the 2D surface of the hippocampus doesn’t unfold onto a sphere as cleanly as the neocortex does. Still, the current results seem usable to me. Perhaps other registration methods could provide more accurate morphing for the hippocampus?
