Source Morphing (and reverting to original) Question

Hello,

Iā€™ve got a question regarding the source morphing process (MNE 1.7.0). Namely, the shape and use of the .morph_mat. My understanding is that the matrix is such that the ._data of subject_from source space could be matrix multiplied to convert to subject_to as done in this tutorial. If I print the shape of the morph mat, I get, what I assume to be, (N voxels subject_to = 20484, N voxels subject_from). However, if I then create a source morph for the reverse (i.e., subject_from = ā€˜fsaverageā€™, subject_to = subj_id), then the source morph for that has shape (N voxels subject_from = 20484, N voxels subject_to).

  1. Why do both matrices put the FSAverage dimensions, regardless of if that is the subject_from or subject_to?
  2. Ultimately, I am hoping to convert all subjectsā€™ data to the brain shape of the same size (hence FSAverage), perform some computations, and then convert each one to the subject-specific space. Is taking the morph_rev.morph_mat.T (Subject Voxels, 20484) @ morphed data (20484, Time) the proper way to convert back? I know there is a is a .to_original_src, but for this particular use case I would greatly prefer to just have to keep track of arrays than source estimate objects.

I should point out that I am making the assumption in both bases 20484 are the voxels for FSAverage, as those are the vertex numbers associated with in the various tutorials such as this one.

Forward Morph: Subj ID ā†’ FSAverage

src = mne.setup_source_space(subject=subj_id,
surface = ā€˜pialā€™,
add_dist=ā€˜patchā€™,
spacing = ā€˜allā€™,
subjects_dir=path_to_MRIs);

morph = mne.compute_source_morph(src=src,
subject_from=subj_id,
subject_to=ā€˜fsaverageā€™,
subjects_dir=path_to_MRIs)

print("Morph matrix shape: ", morph.morph_mat.shape) # (20484, 249578)

Do the reverse: FSAverage ā†’ Subj ID

src_reverse = mne.setup_source_space(subject=ā€˜fsaverageā€™,
surface = ā€˜pialā€™,
add_dist=ā€˜patchā€™,
spacing = ā€˜allā€™, # ā€˜oct6ā€™, # ā€˜allā€™
subjects_dir=path_to_MRIs);

morph_rev = mne.compute_source_morph(src=src_reverse,
subject_from=ā€˜fsaverageā€™,
subject_to=subj_id,
smooth=ā€˜nearestā€™,
subjects_dir=path_to_MRIs)

print("Morph matrix shape: ", morph_rev.morph_mat.shape) # (20484, 327684)

Also, the voxels corresponding to Subj_ID have different shapes, but after digging around I think it is acceptable to just extract the vertices from the source morph matrices corresponding to the vertices in the forward src? Can someone confirm this?

fwd_vertices = [fwd_fixed[ā€˜srcā€™][0][ā€˜vertnoā€™], fwd_fixed[ā€˜srcā€™][1][ā€˜vertnoā€™]] # List of active vertices
fwd_vertices = np.hstack(fwd_vertices)
reduced_morph_matrix_rev = morph_rev.morph_mat[:, fwd_vertices]

Any insight you have is appreciated. Thank you!

Edit: Further testing indicates that my assumption that the 20484 voxels belonged to FSAverage was a bad assumption. Playing around a bit more (adding a specific src_to = argument) and things are behaving as I expected them to. Case closed :slight_smile: