(as in ANALYZE 7.5):
dim[0] = number of dimensions;
- if dim[0] is outside range 1..7, then the header information needs to be byte swapped appropriately
- ANALYZE supports dim[0] up to 7, but NIFTI-1 reserves dimensions 1,2,3 for space (x,y,z), 4 for time (t), and 5,6,7 for anything else needed.
dim[i] = length of dimension #i, for i=1..dim[0] (must be positive)
- also see the discussion of intent_code, far below
pixdim[i] = voxel width along dimension #i, i=1..dim[0] (positive)
- cf. ORIENTATION section below for use of pixdim[0]
- the units of pixdim can be specified with the xyzt_units
field (also described far below).
Number of bits per voxel value is in bitpix, which MUST correspond with the datatype field. The total number of bytes in the image data is
dim[1] * ... * dim[dim[0]] * bitpix / 8
In NIFTI-1 files, dimensions 1,2,3 are for space, dimension 4 is for time, and dimension 5 is for storing multiple values at each spatiotemporal voxel. Some examples:
- A typical whole-brain FMRI experiment's time series:
- dim[0] = 4
- dim[1] = 64 pixdim[1] = 3.75 xyzt_units = NIFTI_UNITS_MM | NIFTI_UNITS_SEC
- dim[2] = 64 pixdim[2] = 3.75
- dim[3] = 20 pixdim[3] = 5.0
- dim[4] = 120 pixdim[4] = 2.0
- A typical T1-weighted anatomical volume:
- dim[0] = 3
- dim[1] = 256 pixdim[1] = 1.0 xyzt_units = NIFTI_UNITS_MM
- dim[2] = 256 pixdim[2] = 1.0
- dim[3] = 128 pixdim[3] = 1.1
- A single slice EPI time series:
- dim[0] = 4
- dim[1] = 64 pixdim[1] = 3.75 xyzt_units = NIFTI_UNITS_MM | NIFTI_UNITS_SEC
- dim[2] = 64 pixdim[2] = 3.75
- dim[3] = 1 pixdim[3] = 5.0
- dim[4] = 1200 pixdim[4] = 0.2
- A 3-vector stored at each point in a 3D volume:
- dim[0] = 5
- dim[1] = 256 pixdim[1] = 1.0 xyzt_units = NIFTI_UNITS_MM
- dim[2] = 256 pixdim[2] = 1.0
- dim[3] = 128 pixdim[3] = 1.1
- dim[4] = 1 pixdim[4] = 0.0
- dim[5] = 3 intent_code = NIFTI_INTENT_VECTOR
- A single time series with a 3x3 matrix at each point:
- dim[0] = 5
- dim[1] = 1 xyzt_units = NIFTI_UNITS_SEC
- dim[2] = 1
- dim[3] = 1
- dim[4] = 1200 pixdim[4] = 0.2
- dim[5] = 9 intent_code = NIFTI_INTENT_GENMATRIX
- intent_p1 = intent_p2 = 3.0 (indicates matrix dimensions)
The 5th dimension of the dataset, if present (i.e., dim[0]=5 and dim[5] > 1), contains multiple values (e.g., a vector) to be stored
at each spatiotemporal location. For example, the header values
- dim[0] = 5
- dim[1] = 64
- dim[2] = 64
- dim[3] = 20
- dim[4] = 1 (indicates no time axis)
- dim[5] = 3
- datatype = DT_FLOAT
- intent_code = NIFTI_INTENT_VECTOR
mean that this dataset should be interpreted as a 3D volume (64x64x20), with a 3-vector of floats defined at each point in the 3D grid.
A program reading a dataset with a 5th dimension may want to reformat the image data to store each voxels' set of values together in a struct or array. This programming detail, however, is beyond the scope of the NIFTI-1 file specification! Uses of dimensions 6 and 7 are also not specified here.
If the magic field is "n+1", then the voxel data is stored in the same file as the header. In this case, the voxel data starts at offset
(int)vox_offset into the header file. Thus, vox_offset=348.0 means that the data starts immediately after the NIFTI-1 header. If vox_offset is
greater than 348, the NIFTI-1 format does not say anything about the contents of the dataset file between the end of the header and the start of the data.
If the magic field is "ni1", then the voxel data is stored in the associated ".img" file, starting at offset 0 (i.e., vox_offset is not
used in this case, and should be set to 0.0).
When storing NIFTI-1 datasets in pairs of files, it is customary to name the files in the pattern "name.hdr" and "name.img", as in ANALYZE 7.5.
When storing in a single file ("n+1"), the file name should be in the form "name.nii" (the ".nft" and ".nif" suffixes are already taken;
cf. http://www.icdatamaster.com/n.html ).
The byte order of the data arrays is presumed to be the same as the byte order of the header (which is determined by examining dim[0]). Floating point types are presumed to be stored in IEEE-754 format.
If the scl_slope field is nonzero, then each voxel value in the dataset should be scaled as y = scl_slope * x + scl_inter
where x = voxel value stored y = "true" voxel value
Normally, we would expect this scaling to be used to store "true" floating values in a smaller integer datatype, but that is not required. That is,
it is legal to use scaling even if the datatype is a float type (crazy, perhaps, but legal).
- However, the scaling is to be ignored if datatype is DT_RGB24.
- If datatype is a complex type, then the scaling is to be applied to both the real and imaginary parts.
The cal_min and cal_max fields (if nonzero) are used for mapping (possibly scaled) dataset values to display colors:
- Minimum display intensity (black) corresponds to dataset value cal_min.
- Maximum display intensity (white) corresponds to dataset value cal_max.
- Dataset values below cal_min should display as black also, and values
above cal_max as white.
- Colors "black" and "white", of course, may refer to any scalar display
scheme (e.g., a color lookup table specified via aux_file).
- cal_min and cal_max only make sense when applied to scalar-valued datasets (i.e., dim[0] < 5 or dim[5] = 1).
Values of datatype smaller than 256 are ANALYZE 7.5 compatible. Larger values are NIFTI-1 additions. These are all multiples of 256, so that no bits below position 8 are set in datatype. But there is no need to use only powers-of-2, as the original ANALYZE 7.5 datatype codes do.
The additional codes are intended to include a complete list of basic scalar types, including signed and unsigned integers from 8 to 64 bits, floats from 32 to 128 bits, and complex (float pairs) from 64 to 256 bits.
Note that most programs will support only a few of these datatypes! A NIFTI-1 program should fail gracefully (e.g., print a warning message) when it encounters a dataset with a type it doesn't like.
Some of the ANALYZE 7.5 fields marked as ++UNUSED++ may need to be set to particular values for compatibility with other programs. The issue of interoperability of ANALYZE 7.5 files is a murky one -- not all programs require exactly the same set of fields. (Unobscuring this murkiness is a principal motivation behind NIFTI-1.)
Some of the fields that may need to be set for other (non-NIFTI aware) software to be happy are:
extents dbh.h says this should be 16384
regular dbh.h says this should be the character 'r'
glmin, glmax dbh.h says these values should be the min and max voxel values for the entire dataset
It is best to initialize ALL fields in the NIFTI-1 header to 0 (e.g., with calloc()), then fill in what is needed.
Information from nifti1.h by RW Cox, NIH