An implementation of the dimension info as desribed in
http://nifti.nimh.nih.gov/pub/dist/src/niftilib/nifti1.h
In particular, it allows one to check if a CoordinateMap instance can be coerced into a valid NIFTI CoordinateMap instance. For a valid NIFTI coordmap, we can then ask which axes correspond to time, slice, phase and frequency.
NIFTI files can have up to seven dimensions. We take the convention that the output coordinate names are [‘x’,’y’,’z’,’t’,’u’,’v’,’w’] and the input coordinate names are [‘i’,’j’,’k’,’l’,’m’,’n’,’o’].
In the NIFTI specification, the order of the output coordinates (at least the first 3) are fixed to be [‘x’,’y’,’z’] and their order is not meant to change. As for input coordinates, the first three can be reordered, so [‘j’,’k’,’i’,’l’] is valid, for instance.
NIFTI has a ‘diminfo’ header attribute that optionally specifies the order of the [‘i’, ‘j’, ‘k’] axes. To use similar terms to those in the nifti1.h header, ‘phase’ corresponds to ‘i’; ‘frequency’ to ‘j’ and ‘slice’ to ‘k’. We use [‘i’,’j’,’k’] instead because there are images for which the terms ‘phase’ and ‘frequency’ have no proper meaning. See the functions get_freq_axes, get_phase_axis for how this is dealt with.
NIFTI’s voxel convention is what can best be described as 0-based FORTRAN indexing (confirm this). For example: suppose we want the x=20-th, y=10-th pixel of the third slice of an image with 30 64x64 slices. This
>>> from nipy.testing import anatfile
>>> from nipy.io.api import load_image
>>> nifti_ijk = [19,9,2]
>>> fortran_ijk = [20,10,3]
>>> c_kji = [2,9,19]
>>> imgarr = np.asarray(load_image(anatfile))
>>> request1 = imgarr[nifti_ijk[2], nifti_ijk[1], nifti_ijk[0]]
>>> request2 = imgarr[fortran_ijk[2]-1,fortran_ijk[1]-1, fortran_ijk[0]-1]
>>> request3 = imgarr[c_kji[0],c_kji[1],c_kji[2]]
>>> request1 == request2
True
>>> request2 == request3
True
FIXME: (finish this thought.... Are we going to open NIFTI files with NIFTI input coordinates?) For this reason, we have to consider whether we should transpose the memmap from pynifti.
Determine if a given CoordinateMap instance can be used as a valid coordmap for a NIFTI image, so that an Image can be saved.
If the input coordinates must be reordered, the order defaults to the NIFTI order [‘i’,’j’,’k’,’l’,’m’,’n’,’o’].
Generate a CoordinateMap from an affine transform.
This is a convenience function to create a CoordinateMap from image attributes. It uses the orientation field from pynifti IO to map to the nipy names, prepending time or vector depending on dimension.
FIXME: This is an internal function and should be revisited when the CoordinateMap is refactored.
Determine if a given CoordinateMap instance can be used as a valid coordmap for a NIFTI image, so that an Image can be saved.
This may raise various warnings about the coordmap.
Take a valid NIFTI coordmap, and return a coordmap with input_coordinates in the standard order, i.e. with names ‘ijklmno’[:coordmap.ndim[0]] and the order of coordinates that put the coordmap into standard order.
NOTE: If the coordmap is only ‘coerceable’ and not ‘valid’ (i.e. warnings are raised, then this may give unexpected results because it only checks the reordering of the first 3 coordinates.
>>> cmap = Affine.from_params('ikjl', 'xyzt', np.identity(5))
>>> sorder, scmap = standard_order(cmap)
>>> print cmap.input_coords.coord_names
('i', 'k', 'j', 'l')
>>> print scmap.input_coords.coord_names
('i', 'j', 'k', 'l')
>>> print scmap.output_coords.coord_names
('x', 'y', 'z', 't')
>>> print cmap.output_coords.coord_names
('x', 'y', 'z', 't')