-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[MRG] Coregistration #3466
[MRG] Coregistration #3466
Conversation
Codecov Report
@@ Coverage Diff @@
## master #3466 +/- ##
=========================================
- Coverage 86.07% 85.97% -0.1%
=========================================
Files 350 350
Lines 63028 63209 +181
Branches 9639 9659 +20
=========================================
+ Hits 54251 54344 +93
- Misses 6097 6181 +84
- Partials 2680 2684 +4 Continue to review full report at Codecov.
|
586f797
to
10a90cc
Compare
@christianbrodbeck is this worth resurrecting? It seems like at the very least the MRI fiducials would be cool. |
Sure! I can rebase or split it up if you think some features require more work than others. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Otherwise LGTM
mne/transforms.py
Outdated
raise TypeError('cf must be str or int, not %s' % type(cf)) | ||
else: | ||
try: | ||
cf = int(cf) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can instead do from numbers import Integral; if not isinstance(cf, Integral):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wish I'd known this! Simply returning int(cf)
(which is in master now) is sufficient though right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I think we already have a function like this somewhere that converts coordinate frame str or int to int. Can you check around, probably in mne/transforms.py
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... oh wait, this is in transforms
. Never mind! Yeah int(cf)
is fine
mne/viz/_3d.py
Outdated
ref_meg : bool | ||
If True (default False), include reference MEG sensors. | ||
fiducials : bool | str |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should probably be mri_fiducials
. The digitized fiducials are already displayed as part of dig
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll change. i assume also add the .. versionadded:: 0.14
tag?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes please
mne/viz/_3d.py
Outdated
head_dev_t = invert_transform(info['dev_head_t']) | ||
mri_dev_t = combine_transforms(mri_head_t, head_dev_t, 'mri', | ||
'meg') | ||
fid_locs = apply_trans(mri_dev_t, fid_locs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can now be simplified because there is IIRC a mri_transform
that is used to take anything originally in MRI space to the destination space
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mne/coreg.py
Outdated
"frames") | ||
coord_frame_from = frames_from[0] | ||
coords_to = _fiducial_coords(fiducials, coord_frame_to) | ||
trans = fit_matched_points(coords_from, coords_to, tol=tol) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this probably isn't the correct function. From fiducials you get a center point and axis directions. Using that geometry analytically is better than using a generic fitting function
mne/gui/_fiducials_gui.py
Outdated
'r': np.array(self.nasion[0])}, | ||
{'kind': FIFF.FIFFV_POINT_CARDINAL, | ||
'ident': FIFF.FIFFV_POINT_RPA, | ||
'r': np.array(self.rpa[0])}] | ||
write_fiducials(fname, dig, FIFF.FIFFV_COORD_MRI) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good at some point to use mne.io.write_dig
instead. This is just a specific use case of it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm write_fiducials()
does nothing but call write_dig()
... should it be deprecated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes probably. I think back when I fixed up write_dig
I just wasn't sure how to fix the coreg
code not to use it anymore.
This could use a rebase (might be easier to start from scratch?) then should be good hopefully |
Well the only thing that's left is the actual coregistration which as you indicated should be rewritten with the analytic approach... |
For now I think we can keep that. I think that we'll want to write a separate "mode" entirely, e.g. coordinate-frame-center-based instead of nasion-based. It's what I would have expected going in. |
42e5475
to
dde8ed3
Compare
Rebased and added a test; This is not nasion based, it just finds a transform to minimize points distances. |
mne/transforms.py
Outdated
@@ -63,8 +63,6 @@ def _to_const(cf): | |||
if cf not in _str_to_frame: | |||
raise ValueError('Unknown cf %s' % cf) | |||
cf = _str_to_frame[cf] | |||
elif not isinstance(cf, (int, np.integer)): | |||
raise TypeError('cf must be str or int, not %s' % type(cf)) | |||
return int(cf) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this check is superfluous, or am I missing some possibility?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it prevents people from accidentally passing float
. The correct thing to do, though, is really to check against from numbers import Integral; if isinstance(x, Integral)
c591be3
to
35e2202
Compare
Looks like |
Argh, probably an old |
Actually I get an error in this test (https://github.com/mne-tools/mne-python/blob/master/mne/tests/test_coreg.py#L67) and I am not sure how it could run without error?
|
Looks like you fixed it already, yes? |
yes :) |
Okay great. This looks pretty simple so I'll merge once the CIs come back happy |
Travis is unhappy with style https://travis-ci.org/mne-tools/mne-python/jobs/205022035#L3106 |
Thanks @christianbrodbeck |
@jona-sassenhagen the function is
mne.coreg.coregister_fiducials
. It currently has a scale parameter to use it with fsaverage, but this does not lead to satisfactory results and should be removed before merge.The PR also contains some other small modifications.
viz.plot_trans
to plot fiducials