-
Notifications
You must be signed in to change notification settings - Fork 262
WIP: Automatically reshape FreeSurfer ico7 niftis #315
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
Conversation
@matthew-brett How does one actually run the
|
Run the tests locally you mean? You could start with |
Thanks. Wrote tests that pass locally, with change in https://bitbucket.org/nipy/nitest-freesurfer/pull-request/1/. If that PR goes through, I'll push the tests. |
'inconsistent freesurfer type header?') | ||
return (vec_len, 1, 1) | ||
# Apply freesurfer hack for ico7 surface | ||
elif shape == (27307, 1, 6): |
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.
Do I understand right - that this is one particular image ('ico7')? So the hack only applies to that image?
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.
To surfaces with that number of vertices. I can't find a good reference to the arguments as to why they do this[0], but a reasonably common FreeSurfer surface is a warped icosahedron, and in particular they recommend using the 7th-order icosahedron. This is the number of vertices used in their fsaverage
group template for comparisons across subjects.
Their MATLAB code indicates that this specific surface shape is hard-coded:
https://code.google.com/p/fieldtrip/source/browse/trunk/external/freesurfer/save_nifti.m?r=8776#50
https://code.google.com/p/fieldtrip/source/browse/trunk/external/freesurfer/load_nifti.m?r=8776#86
Edit: Nipype's documentation indicates that icosahedra up to the 7th order are supported. 6th order and under have few enough vertices to not require a hack, which explains why it's so specific to ico7.
[0] I believe the use of the icosahedron is to allow for near constant neighbor-neighbor distances.
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 noticed this:
"""
By default, mri_surf2surf will save the output as multiple 'slices'; has no effect for paint/w output format. For ico, the output will appear to be a 'volume' with Nv/R colums, 1 row, R slices and Nf frames, where Nv is the number of vertices on the surface. For icosahedrons, R=6. For others, R will be the prime factor of Nv closest to 6. Reshaping is for logistical purposes (eg, in the analyze format the size of a dimension cannot exceed 2^15). Use this flag to prevent this behavior. This has no effect when the output type is paint.
"""
at https://surfer.nmr.mgh.harvard.edu/fswiki/mri_surf2surf - comment for --noreshape
.
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.
The easiest way to clarify the situation is to simply try all of the icosahedra:
$ for ORDER in {1..7}; do
mri_surf2surf --hemi rh --srcsubject fsaverage \
--srcsurfval $SUBJECTS_DIR/fsaverage/surf/rh.orig.avg.area.mgh \
--trgsubject ico --trgsurfval rh.ico$ORDER.nii \
--trgicoorder $ORDER &> /dev/null \
&& python -c "from nibabel import load;\
print ($ORDER, load('rh.ico$ORDER.nii').header._structarr['dim'][1:4])" \
&& rm rh.ico$ORDER.nii
done
(1, array([42, 1, 1], dtype=int16))
(2, array([162, 1, 1], dtype=int16))
(3, array([642, 1, 1], dtype=int16))
(4, array([2562, 1, 1], dtype=int16))
(5, array([10242, 1, 1], dtype=int16))
(6, array([-1, 1, 1], dtype=int16))
(7, array([27307, 1, 6], dtype=int16))
So whatever their ideal of what ought to be done for icosahedra with >2^15 vertices, in practice, they use the (27307, 1, 6) shape for ico7, the large vector hack for ico6 and just (x, 1, 1) for lesser icosahedra. (ico8 does not work.)
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.
Is there any possibility that someone will try to use this with a volume with some other number of vertices? Would they expect it to work?
Ben - I noticed your email to the freesurfer list, and I think it got no reply. What do you think we should do here? |
I figured I'd at least wait until Monday, since I sent this email out on a Friday in the summer. If we don't hear anything, my feeling is we should follow the lead of Though the Assuming the decision is to restrict ourselves to the existing cases, is there anything you need from me regarding the nitest-freesurfer PR? |
Just needs tests - I guess these are waiting on the nitest-freesurfer PR |
Yup. In case BitBucket didn't alert you, I updated the PR over there. |
Merged the data commit, thanks for that. |
Seems not to be fetching the new nitest-freesurfer. Is that just a thing that requires time to sync? https://travis-ci.org/nipy/nibabel/jobs/66921373 |
Ah no - you need to update the submodule. The submodule points to one exact commit, not a branch - https://matthew-brett.github.io/pydagogue/git_submodules.html |
Great - thanks very much for this - in it goes. |
MRG: Automatically reshape FreeSurfer ico7 niftis Tried to follow in the footsteps of f53c168. Presents programmer with data object equivalent to an MGH, leaving header intact for writing to file.
MRG: Automatically reshape FreeSurfer ico7 niftis Tried to follow in the footsteps of f53c168. Presents programmer with data object equivalent to an MGH, leaving header intact for writing to file.
Closes #309.
Tried to follow in the footsteps of f53c168. Presents programmer with data object equivalent to an MGH, leaving header intact for writing to file.
Tests planned:
mri_convert
a.mgh
file innibabel-data/nitest-freesurfer/fsaverage/surf
to '.nii' and verifyimg.get_data()
is equalimg.header._structarr['dim'][1:4] == (27307, 1, 6)