Skip to content

BF FreeSurfer nifti surfaces can have >3 dimensions #332

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

Merged
merged 1 commit into from
Aug 25, 2015

Conversation

effigies
Copy link
Member

Quick workaround for https://mail.python.org/pipermail/neuroimaging/2015-July/000132.html.

This uses the FreeSurfer hacks on any shapes beginning with (-1, 1, 1) or (27307, 1, 6), which seems fairly safe, but we can restrict down to 4-dimensional, or possibly only allow (-1, 1, 1, 1) or (27307, 1, 6, 1) in the 4D case.

I guess we should also add tests for these cases.

@matthew-brett
Copy link
Member

Seems reasonable. I'm afraid we do need some tests :)

@effigies
Copy link
Member Author

Okay. Looking at https://code.google.com/p/fieldtrip/source/browse/trunk/external/freesurfer/save_nifti.m?r=8776#52 again, it looks like this MATLAB code at least only ever works with 4D volumes, but does allow the 4th dimension to vary. The tests I uploaded permit up to 7 dimensions, which is the max of hdr['dim'] capabilities, and verify the first three dimensions are either (27307, 1, 6) or (-1, 1, 1).

@bcipolli
Copy link
Contributor

Looks reasonable to me as well. I would, however, add some comments to the get and set shape functions about the current limits of shape.

@effigies
Copy link
Member Author

How about adding the following to set_data_shape?

    # For Nifti surface files, the first dimension is assumed to correspond
    # to vertices/nodes on a surface, and dimensions two and three are
    # assumed to have depth of 1. Dimensions 4-7 are not subject to
    # constraints beyond type bounds.

Or should I describe the hacks? I think the code in set_data_shape is about as readable as any comments I could add. I'm not sure what to add to get_data_shape that adds any clarity, except maybe (see set_data_shape for details).

@bcipolli
Copy link
Contributor

@effigies that's just what I was looking for. I would put that on set_data_shape in the docstring, or in the Nifti1Image docstring if it's more widely applicable.

I found the code to be very readable, I doubt inline comments could help.

@effigies
Copy link
Member Author

Added a variation on that comment. One possible quibble is that surface files that have <65536 nodes will not trigger constraints on dimensions 2 and 3, since they won't hit either of the large surface hacks. I'm not sure this is a problem, but I'd be open to suggestions of rewording.

@bcipolli
Copy link
Contributor

@effigies I appreciate the note, and I'll follow up on this (to see if it is an issue) as I get closer to working on CIFTI/GIFTI stuff.

@@ -723,6 +723,11 @@ def set_data_shape(self, shape):
If ``ndims == len(shape)`` then we set zooms for dimensions higher than
``ndims`` to 1.0

Nifti1 images can have up to seven dimensions. For Nifti surface files,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you say "Nifti surface files" - do you mean that this is part of the NIfTI standard somewhere? Or you just mean NIfTI as creatively reinterpreted by Freesurfer?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's my understanding that CIFTI, which contains both surface and volume data, follows the NIFTI2 spec.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add something to that effect here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, there are Nifti1 surface files (http://nifti.nimh.nih.gov/pub/dist/src/niftilib/nifti1.h):

#define NIFTI_INTENT_VECTOR    1007   /* for any other type of vector */

 /*! To signify that the vector value at each voxel is really a
     spatial coordinate (e.g., the vertices or nodes of a surface mesh):
       - dataset must have a 5th dimension
       - intent_code must be NIFTI_INTENT_POINTSET
       - dim[0] = 5
       - dim[1] = number of points
       - dim[2] = dim[3] = dim[4] = 1
       - dim[5] must be the dimensionality of space (e.g., 3 => 3D space).
       - intent_name may describe the object these points come from
         (e.g., "pial", "gray/white" , "EEG", "MEG").                   */

Annoyingly, this isn't how FreeSurfer actually implements its surfaces, presumably because of the need for large vector hacks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent precision of the thing - could these go in the docstring, for posterity?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice - but - can you clean up the appearance of the links in the output by using ReST links, defined at the bottom of the docstring?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Learning Sphinx, today. Have another look?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice ! Does it look OK in the source code as well?

@matthew-brett
Copy link
Member

Looks good apart from my line comments.

@effigies
Copy link
Member Author

Pushed new commit. If source needs cleanup, let me know.

@matthew-brett
Copy link
Member

Thanks for that - looks good now. Any more comments? Otherwise I will merge tomorrow.

@bcipolli
Copy link
Contributor

@matthew-brett @effigies this seems ready to go?

matthew-brett added a commit that referenced this pull request Aug 25, 2015
MRG: FreeSurfer nifti surfaces can have >3 dimensions

Quick workaround for https://mail.python.org/pipermail/neuroimaging/2015-July/000132.html.

This uses the FreeSurfer hacks on any shapes beginning with (-1, 1, 1) or (27307, 1, 6), which seems fairly safe, but we can restrict down to 4-dimensional, or possibly only allow (-1, 1, 1, 1) or (27307, 1, 6, 1) in the 4D case.
@matthew-brett matthew-brett merged commit 6e4a144 into nipy:master Aug 25, 2015
@matthew-brett
Copy link
Member

Thanks for reminding me.

@effigies effigies deleted the freesurfer4d branch August 25, 2015 15:32
@effigies effigies mentioned this pull request Nov 6, 2015
grlee77 pushed a commit to grlee77/nibabel that referenced this pull request Mar 15, 2016
MRG: FreeSurfer nifti surfaces can have >3 dimensions

Quick workaround for https://mail.python.org/pipermail/neuroimaging/2015-July/000132.html.

This uses the FreeSurfer hacks on any shapes beginning with (-1, 1, 1) or (27307, 1, 6), which seems fairly safe, but we can restrict down to 4-dimensional, or possibly only allow (-1, 1, 1, 1) or (27307, 1, 6, 1) in the 4D case.
@coveralls
Copy link

Coverage Status

Coverage remained the same at 95.349% when pulling 0a3b0b8 on effigies:freesurfer4d into 60d4b72 on nipy:master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants