Hi, I’m working with SEEG data and am trying to coregister digitized montages to my freesurfer subject brains. I don’t have the post op CTs on hand as they are with a collaborator, but I’m led to believe that the electrode locations were digitized in MRI RAS (not freesurfer RAS) space. I’m hoping to check my process with those who have more experience with this.
The electrode locations (x,y,z) are in mm, and I used:
In the figure that results, it appears that the electrode locations are close to correct in x and z dimensions but not in y, they are too anterior by about half a brain’s length and sit outside the brain. Am I missing something here?
I wrote mne_bids.convert_montage_to_mri to avoid having to write how to do the transforms correctly every time, maybe try that first. You might have to scale the montage positions to m first.
Thank you for your answer.
I’ve tried to use mne_bids.convert_montage_to_mri, but it returns an AttributeError: No mne attribute bids. I did install mne-bids, and imported mne_bids, but I still get this. I was hoping it would return a transformation matrix.
I feel like there should be a simple solution to this…
I figured out the solution after a while.
From the opening post, the matrix multiplications produce a transformation matrix, but the signs and order of axes were mixed up in the translocation matrix (first 3 rows of the last column). To correct this:
Multiplied [0,3] by -1
[1,3] should be [2,3]
[2,3] should be [1,3] * (-1)
After these modifications, I used mne.transforms.Transform to turn this into a transformation matrix (head to mri), then used this in plot_alignment.
Hope this helps somebody.
I’m glad you found a solution that works but you really shouldn’t have to modify the transformation matrix directly something like this should work:
import numpy as np
import mne, mne_bids
raw = mne.io.read_raw('xxxx.fif')
mm2m = np.eye(4)
mm2m[:3,:3] *= 0.001
mm2m = mne.transforms.Transform('ras', 'ras', trans=mm2m)
montage = raw.get_montage()
montage.apply_trans(mm2m) # to m in RAS
mne_bids.convert_montage_to_mri(montage, 'sub-x') # to mri surface RAS
trans = mne.coreg.estimate_head_mri('sub-x') # estimate surface RAS to head
# (between left and right auricular points is 0)
montage.apply_trans(mne.transforms.invert_transform(trans)) # to head
raw.set_montage(montage)
mne.viz.plot_alignment(raw.info, trans=trans, subject='sub-x', surfaces=dict(pial=0.5, sensor_colors='cyan')
here the trans can be estimated by a transformation from fsaverage which already has the fiducials marked or faked as the identity even, it is going round trip (applied and then inverse applied inside plot_alignment) so it doesn’t matter what it is in practice.
Oh also, it looks like your montage may have already started in head coordinates. If fiducials were present in the montage, this transformation takes place automatically. You might want to just hold out those fiducials in order to suppress that transformation. You could use those fiducials to transform directly to mri (surface RAS) but I’m not sure there’s a nice way within the existing MNE API currently, it would probably require a pull request.