Dear MNE experts,
I have some spatial-temporal searchlight results and I wish to morph these volume source estimates to the volumetric fsaverage brain to get the group-level results.
However, as shown below, our source estimate is quite different from the original data.
So Iām writing to ask how to fix this problem. The code we used in our analysis is shown as follows.
Environmentļ¼
- MNE version: 1.0.3
- operating system: Centos (Linux version 3.10.0-1160.el7.x86_64)
- data: CTF MEG data.
1.Firstly, we make source space for fsaverage data
import mne
from os.path import join as pjoin
subj = 'fsaverage'
subj_head = pjoin(surfDir,subj)
bem_path = pjoin(subj_head, "bem")
subject = subj
BEM_spacing = 5
src_spacing = 'oct6'
BEM_method = "watershed"
BEM_conductivity = [0.3]
mne.bem.make_watershed_bem(
subject=subject,
subjects_dir=surfDir,
overwrite=True,
volume="T1",
atlas=True,
gcaatlas=False,
preflood=1.75,
show=True, # use True if plot set OK
copy=True,
verbose=True,
)
bem_surfaces = mne.make_bem_model(
subject=subject,
subjects_dir=surfDir,
ico=BEM_spacing,
conductivity=BEM_conductivity,
verbose=True,
)
fname_bem = pjoin(bem_path,
"{}_{}_ico{}_bem.fif".format(subj, BEM_method, BEM_spacing))
mne.write_bem_surfaces(fname_bem, bem_surfaces,
overwrite=True, verbose=True)
bem_sol = mne.make_bem_solution(surfs=bem_surfaces, verbose=True)
fname_bem_sol = pjoin(bem_path,
"{}_{}_ico{}_bem-sol.fif".format(subj, BEM_method, BEM_spacing))
mne.write_bem_solution(fname=fname_bem_sol, bem=bem_sol,
overwrite=True, verbose=True)
surface_name = "pial"
surface = pjoin(surfDir, subject, 'bem', 'inner_skull.surf')
# make and save source space for fsaverage
surf_src_fname = pjoin(bem_path,
"{}_{}_bem_{}_vol-src.fif".format(subj, BEM_method, surface_name))
src = mne.setup_volume_source_space(
subject, subjects_dir=surfDir, surface=surface,
add_interpolator=True)
mne.write_source_spaces(surf_src_fname, src, overwrite=True, verbose=True)
It returns a fsaverage source space.
<SourceSpaces: [<volume, shape=(31, 33, 25), n_used=5756>] MRI (surface RAS) coords, subject āfsaverageā, ~70.3 MB>
- Morph searchlight results to common source space (fsaverage)
# This code refers to https://mne.tools/stable/auto_examples/inverse/morph_volume_stc.html#sphx-glr-auto-examples-inverse-morph-volume-stc-py
import mne
import joblib
from os.path import join as pj
dataPath = '/meg2/'
surfDir = '/meg2/surf/'
subjList = ['subj001','subj002','subj003']
fullStc =[]
subjCount=0
for subj in subjList:
# load searchlight results
sourceName = pj(dataPath, subj,'sourced','rsa_'+subj+'.stc')
sourcedData = joblib.load(sourceName)
# morgh data to a common volume space
vol_src = pj(surfDir,subj, 'bem', subj+'_watershed_bem_pial_vol-src.fif')
inverse_operator = mne.minimum_norm.read_inverse_operator(pj(surfDir ,subj, subj+'LCMV'+'-inv.fif'))
# make bem model for fsaverage
fname_src_fsaverage = pj(surfDir,'fsaverage','bem', 'fsaverage'+'_watershed_bem_pial_vol-src.fif')
src_fs = mne.read_source_spaces(fname_src_fsaverage)
morph = mne.compute_source_morph(
inverse_operator['src'], subject_from=subj, subjects_dir=surfDir,
src_to=src_fs, verbose=True)
# save morphed data as stc file
fname_stc = pj(dataPath,'bfStat','rsa_'+str(subjCount)+'.stc') # .fif and .src
with open(fname_stc, 'wb') as f:
joblib.dump(stc_fsaverage, f)
f.close()
stc_fsaverage = morph.apply(sourcedData)
subjCount = subjCount+1
fullStc.append(stc_fsaverage)
Another question is, how to read labels of this morphed source estimate? I tried ā read_labels_from_annotā, but it seems that labels in āfsaverage/labelsā are not suited for morphed volume estimates (5756 voxels).
Best wishes!
Jinhua