(This article is about the nifti-1 file format. For an overview of how the nifti-2 differs from the nifti-1, see this one.)
The Neuroimaging Informatics Technology Initiative (nifti) file format was envisioned about a decade ago as a replacement to the then widespread, yet problematic, analyze 7.5 file format. The main problem with the previous format was perhaps the lack of adequate information about orientation in space, such that the stored data could not be unambiguously interpreted. Although the file was used by many different imaging software, the lack of adequate information on orientation obliged some, most notably spm, to include, for every analyze file, an accompanying file describing the orientation, such as a file with extension
.mat. The new format was defined in two meetings of the so called Data Format Working Group (dfwg) at the National Institutes of Health (nih), one in 31 March and another in 02 September of 2003. Representatives of some of the most popular neuroimaging software agreed upon a format that would include new information, and upon using the new format, either natively, or have it as an option to import and export.
Radiological or “neurological”?
Perhaps the most visible consequence of the lack of orientation information was the then reigning confusion between left and right sides of brain images during the years in which the analyze format was dominant. It was by this time that researchers became used to describe an image as being in “neurological” or in “radiological” convention. These terms have always been inadequate because, in the absence of orientation information, no two pieces of software necessarily would have to display the same file with the same side of the brain in the same side of the screen. A file could be shown in “neurological” orientation in one software, but in radiological orientation in another, to the dismay of an unaware user. Moreover, although there is indeed a convention adopted by virtually all manufacturers of radiological equipment to show the left side of the patient on the right side of the observer, as if the patient were being observed from face-to-face or, if lying supine, from the feet, it is not known whether reputable neurologists ever actually convened to create a “neurological” convention that would be just the opposite of the radiological. The way as radiological exams are normally shown reflects the reality of the medical examination, in which the physician commonly approaches the patient in the bed from the direction of the feet (usually there is a wall behind the bed), and tend to stay face-to-face most of the time. Although the neurological examination does indeed include a few manoeuvres performed at the back, for most of the time, even in the more specialised semiotics, the physician stays at the front. The nifti format obviated all these issues, rendering these terms obsolete. Software can now mark the left or the right side correctly, sometimes giving the option of showing it flipped to better adapt to the user personal orientation preference.
Same format, different presentations
A single image stored in the analyze 7.5 format requires two files: a header, with extension
.hdr, to store meta-information, and the actual data, with extension
.img. In order to keep compatibility with the previous format, data stored in nifti format also uses a pair of files,
.hdr/.img. Care was taken so that the internal structure of the nifti format would be mostly compatible with the structure of the analyze format. However, the new format added some clever improvements. Work with a pair of files for each image as in the
.hdr/.img, rather than just one, is not only inconvenient, but it is also error prone, as one might easily forget (or not know) that the data of interest is actually split across more than one file. To address this issue, the nifti format also allows for storage as a single file, with extension
.nii. Single file or pair of files are not the only possible presentations, though. It is very common for images to have large areas of solid background, or files describing masks and regions of interest containing just a few unique values that appear repeated many times. Files like these occupy large space in the disk, but with little actual information content. This is the perfect case where compression can achieve excellent results. Indeed, both nifti and analyze files can be compressed. The deflate algorithm (used, e.g., by
gzip) can operate in streams, allowing compression and decompression on-the-fly. The compressed versions have the
.gz extension appended:
.nii.gz (single file) or
.hdr/.img.gz (pair of files, either nifti or analyze).
Predefined dimensions for space and time
In the nifti format, the first three dimensions are reserved to define the three spatial dimensions — x, y and z —, while the fourth dimension is reserved to define the time points — t. The remaining dimensions, from fifth to seventh, are for other uses. The fifth dimension, however, can still have some predefined uses, such as to store voxel-specific distributional parameters or to hold vector-based data.
Overview of the header structure
In order to keep compatibility with the analyze format, the size of the nifti header was maintained at 348 bytes as in the old format. Some fields were reused, some were preserved, but ignored, and some were entirely overwritten. The table below shows each of the fields, their sizes, and a brief description. More details on how each field should be interpreted are provided further below.
||0B||4B||Size of the header. Must be 348 (bytes).|
||4B||10B||Not used; compatibility with analyze.|
||14B||18B||Not used; compatibility with analyze.|
||32B||4B||Not used; compatibility with analyze.|
||36B||2B||Not used; compatibility with analyze.|
||38B||1B||Not used; compatibility with analyze.|
||39B||1B||Encoding directions (phase, frequency, slice).|
||40B||16B||Data array dimensions.|
||56B||4B||1st intent parameter.|
||60B||4B||2nd intent parameter.|
||64B||4B||3rd intent parameter.|
||72B||2B||Number of bits per voxel.|
||74B||2B||First slice index.|
||76B||32B||Grid spacings (unit per dimension).|
||108B||4B||Offset into a .nii file.|
||112B||4B||Data scaling, slope.|
||116B||4B||Data scaling, offset.|
||120B||2B||Last slice index.|
||122B||1B||Slice timing order.|
||123B||1B||Units of pixdim[1..4].|
||124B||4B||Maximum display intensity.|
||128B||4B||Minimum display intensity.|
||132B||4B||Time for one slice.|
||136B||4B||Time axis shift.|
||140B||4B||Not used; compatibility with analyze.|
||144B||4B||Not used; compatibility with analyze.|
||252B||2B||Use the quaternion fields.|
||254B||2B||Use of the affine fields.|
||256B||4B||Quaternion b parameter.|
||260B||4B||Quaternion c parameter.|
||264B||4B||Quaternion d parameter.|
||268B||4B||Quaternion x shift.|
||272B||4B||Quaternion y shift.|
||276B||4B||Quaternion z shift.|
||280B||16B||1st row affine transform|
||296B||16B||2nd row affine transform.|
||312B||16B||3rd row affine transform.|
||328B||16B||Name or meaning of the data.|
Each of these fields is described in mode detail below, in the order as they appear in the header.
Size of the header
int sizeof_hdr stores the size of the header. It must be 348 for a nifti or analyze format.
char dim_info stores, in just one byte, the frequency encoding direction (1, 2 or 3), the phase encoding direction (1, 2 or 3), and the direction in which the volume was sliced during the acquisition (1, 2 or 3). For spiral sequences, frequency and phase encoding are both set as 0. The reason to collapse all this information in just one byte was to save space. See also the fields
char slice_code and
short dim contains the size of the image array. The first element (
dim) contains the number of dimensions (1-7). If
dim is not in this interval, the data is assumed to have opposite endianness and so, should be byte-swapped (the nifti standard does not specify a specific field for endianness, but encourages the use of
dim for this purpose). The dimensions 1, 2 and 3 are assumed to refer to space (x, y, z), the 4th dimension is assumed to refer to time, and the remaining dimensions, 5, 6 and 7, can be anything else. The value
dim[i] is a positive integer representing the length of the i-th dimension.
short intent_code is an integer that codifies that the data is supposed to contain. Some of these codes require extra-parameters, such as the number of degrees of freedom (df). These extra parameters, when needed, can be stored in the fields
intent_p* when they can be applied to the image as a while, or in the 5th dimension if voxelwise. A list of intent codes is in the table below:
||p1 = degrees of freedom (df)|
||p1 = df|
||p1 = numerator df, p2 = denominator df|
||p1 = df|
||p1 = a, p2 = b|
||p1 = number of trials, p2 = probability per trial|
||p1 = shape, p2 = scale|
||p1 = mean|
||p1 = mean, p2 = standard deviation|
|Noncentral F statistic||
||p1 = numerator df, p2 = denominator df, p3 = numerator noncentrality parameter|
||p1 = dof, p2 = noncentrality parameter|
||p1 = location, p2 = scale|
||p1 = location, p2 = scale|
||p1 = lower end, p2 = upper end|
|Noncentral t statistic||
||p1 = dof, p2 = noncentrality parameter|
||p1 = location, p2 = scale, p3 = power|
||p1 = df*|
||p1 = , p2 =|
|Extreme value type I||
||p1 = location, p2 = scale|
* Note: For the distribution, when p1=1, it is a “half-normal” distribution; when p1=2, it is a Rayleigh distribution; and when p1=3, it is a Maxwell-Boltzmann distribution. Other intent codes are available to indicate that the file contains data that is not of statistical nature.
||Estimate of some parameter, possibly indicated in
||Indices of a set of labels, which may be indicated in
||Indices in the NeuroNames set of labels.|
||For a MxN matrix in the 5th dimension, row major. p1 = M, p2 = N (integers as
||For a symmetric NxN matrix in the 5th dimension, row major, lower matrix. p1 = N (integer as
||Vector per voxel, stored in the 5th dimension.|
||As above, vector per voxel, stored in the 5th dimension.|
||Points in the space, in the 5th dimension.
||Indices of points in space, in the 5th dimension.
||Quaternion in the 5th dimension.|
||Nothing. The intent may be in
||Each voxel contains a time series.|
||Each voxel is an index of a surface dataset.|
||rgb triplet in the 5th dimension.
||rgba quadruplet in the 5th dimension.
||Value at each location is a shape parameter, such as a curvature.|
The intent parameters are stored in the fields
float intent_p2 and
float intent_p3. Alternatively, if the parameters are different for each voxel, they should be stored in the 5th dimension of the file. A human readable intent name can be stored in the field
char intent_name, which may help to explain the intention of the data when it cannot or is not coded with any of the intent codes and parameters above.
Data type and bits per pixel/voxel
int datatype indicates the type of the data stored. Acceptable values are:
|unsigned char||8 bits||
|signed short||16 bits||
|signed int||32 bits||
|signed char||8 bits||
|unsigned short||16 bits||
|unsigned int||32 bits||
|long long||64 bits||
|unsigned long long||64 bits||
|long double||128 bits||
|double pair||128 bits||
|long double pair||256 bits||
short bitpix holds the information of the number of bits per voxel. The value must match the type determined by
datatype as shown above.
Slice acquisition information
The fields fields
short slice_end and
float slice_duration are useful to store information about the timing of an fMRI acquisition, and need to be used together with the
char dim_info, which contains the field
slice_dim. If, and only if, the
slice_dim is different than zero,
slice_code is interpreted as:
||Slice order unknown|
||Interleaved, increasing, starting at the 1st mri slice|
||Interleaved, decreasing, starting at the last mri slice|
||Interleaved, increasing, starting at the 2nd mri slice|
||Interleaved, decreasing, starting at one before the last mri slice|
short slice_start and
short slice_end inform respectively which are the first the last slices that correspond to the actual mri acquisition. Slices present in the image that are outside this range are treated as padded slices (for instance, containing zeroes). The field
float slice_duration indicates the amount of time needed to acquire a single slice. Having this information in a separate field allows to correctly store images of experiments in which
slice_duration*dim[slice_dim] is smaller than the value stored in
pixdim, usually the repetition time (tr).
The dimension for each voxel is stored in the field
float pixdim, and each element match its respective in
short dim. The value in
float pixdim, however, has a special meaning, discussed below; it should always be -1 or 1. The units of measurement for the first 4 dimensions are specified in the field
xyzt_units, discussed below.
int vox_offset indicates, for single files (
.nii), the byte offset before the imaging data starts. For compatibility with older software, possible values are multiples of 16, and the minimum value is 352 (the smallest multiple of 16 that is larger than 348). For file pairs (
.hdr/.img), this should be set as zero if no information other than image data itself is to be stored in the
.img (most common), but it can also be larger than zero, allowing for user-defined extra-information to be prepended into the
.img, such as a dicom header. In this case, however, the rule of being a multiple of 16 may eventually be violated. This field is of type
float (32-bit, ieee-754), allowing integers up to 224 to be specified. The reason for using
float rather than what would be the more natural choice,
int, is to allow compatibility with the analyze format.
The values stored in each voxel can be linearly scaled to different units. The fields
float scl_slope and
float scl_inter define a slope and an intercept for a linear function. The data scaling feature allows the storage in a wider range than what would be allowed by the datatype. Yet, it is possible to use scaling within the same datatype. Both scaling fields should be ignored for the storage of rgb data. For complex types, it should be applied to both real and imaginary parts.
For files that store scalar (non-vector) data, the fields
float cal_min and
float cal_max determine the intended display range when the image is opened. Voxel values equal or below
cal_min should be shown with the smallest colour in the colourscale (typically black in a gray-scale visualisation), and values equal or above
cal_max should be shown with the largest colour in the colourscale (typically white).
Both spatial and temporal measurement units, used for the dimensions
dim (and, respectively, for
pixdim), are encoded in the field
char xyzt_units. The bits 1-3 are used to store the spatial dimensions, the bits 4-6 are for temporal dimensions, and the bits 6 and 7 are not used. A temporal offset can be specified in the field
float toffset. The codes for
xyzt_units, in decimal, are:
|Radians per second (rad/s)||
char descrip can contain any text with up to 80 characters. The standard does not specify whether this string needs to be terminated by a null character or not. Presumably, it is up to the application to correctly handle it.
A supplementary file, containing extra-information, can be specified in the field
char aux_file. This file can, for instance, contain the face indices for meshes which points are stored in the 5th dimension or a look-up-table to display colours.
The most visible improvement of the nifti format over the previous analyze format is the ability to unambiguously store information orientation. The file standard assumes that the voxel coordinates refer to the center of each voxel, rather than at any of its corners. The world coordinate system is assumed to be ras: +x is Right, +y is Anterior and +z is Superior, which is precisely different than the coordinate system used in analyze, which is las. The format provides three different methods to map the voxel coordinates (i,j,k) to the world coordinates (x,y,z). The first method exists only to allow compatibility with the analyze format. The other two methods may coexist, and convey different coordinate systems. These systems are specified in the fields
short qform_code and
short sform_code, which can assume the values specified in the table:
||Arbitrary coordinates. Use Method 1.|
||Scanner-based anatomical coordinates.|
||Coordinates aligned to another file, or to the “truth” (with an arbitrary coordinate center).|
||Coordinates aligned to the Talairach space.|
||Coordinates aligned to the mni space.|
In principle, the
qform_code (Method 2 below) should contain either
2, whereas the
sform_code (Method 3 below) could contain any of the codes shown in the table.
The Method 1 is for compatibility with analyze and is not supposed to be used as the main orientation method. The world coordinates are determined simply by scaling by the voxel size:
where is the Hadamard product.
The Method 2 is used when
short qform_code is larger than zero, and is intended to be used to indicate the scanner coordinates, in a way that resembles the coordinates specified in the dicom header. It can also be used to represent the alignment of an image to a previous session of the same subject (such as for coregistration). For compactness and simplicity, the information in this field is stored as quaternions (a,b,c,d), which last three coefficients are in the fields
float quatern_d. The first coefficient can be calculated from the other three as . These fields are used to construct a rotation matrix as:
This rotation matrix, together with the voxel sizes and a translation vector, is used to define the final transformation from voxel to world space:
where is, again, the Hadamard product, and is the
qfac value, stored at the otherwise unused
pixdim, which should be either
1. Any different value should be treated as
The Method 3 is used when
short sform_code is larger than zero. It relies on a full affine matrix, stored in the header in the fields
float srow_*, to map voxel to world coordinates:
Differently than Method 2, which is supposed to contain a transformation that maps voxel indices to the scanner world coordinates, or to align between two distinct images of the same subject, the Method 3 is used to indicate the transformation to some standard world space, such as the Talairach or mni coordinates, in which case, the coordinate system has its origin (0,0,0) at the anterior comissure of the brain.
char magic field is a “magic” string that declares the file as conforming with the nifti standard. It was placed at the very end of the header to avoid overwriting fields that are needed for the analyze format. Ideally, however, this string should be checked first. It should be
'6E 69 31 00' in hexadecimal) for
.hdr/.img pair, or
'6E 2B 31 00') for a
.nii single file. In the absence of this string, the file should be treated as analyze. Future versions of the nifti format may increment the string to
'n+3', etc. Indeed, as of 2012, a second version is under preparation.
short session_error and
char regular are not used by the nifti format, but were included in the header for compatibility with analyze. The
extents should be the integer 16384, and
regular should be the character
'r'. The fields
int glmin and
int glmax specify respectively the minimum and maximum of the entire dataset in the analyze format.
Extra information can be included in the nifti format in a number of ways as allowed by the standard. At the end of the header, the next 4 bytes (i.e., from byte 349 to 352, inclusive) may or may not be present in a
.hdr file. However, these bytes will always be present in a
.nii file. They should be interpreted as a character array, i.e.
char extension. In principle, these 4 bytes should be all set to zero. If the first,
extension, is non-zero, this indicates the presence of extended information beginning at the byte number 353. Such extended information needs to have size multiple of 16. The first 8 bytes of this extension should be interpreted as two integers,
int esize and
int ecode. The field
esize indicates the size of the extent, including the first 8 bytes that are the
ecode themselves. The field
ecode indicates the format used for the remaining of the extension. At the time of this writing, three codes have been defined:
||Unknown. This code should be avoided.|
||xml extensions used by the afni software package.|
More than one extension can be present in the same file, each one always starting with the pair
ecode, and with its first byte immediately past the last byte of the previous extension. In a single
.nii file, the
float vox_offset must be set properly so that the imaging data begins only after the end of the last extension.
The nifti format brought a number of great benefits if compared to the old analyze format. However, it also brought its own set of new problems. Fortunately, these problems are not severe. Here are some:
- Even though a huge effort was done to keep compatibility with analyze, a crucial aspect was not preserved: the world coordinate system is assumed, in the nifti format, to be ras, which is weird and confusing. The las is a much more logical choice from a medical perspective. Fortunately, since orientation is stored unambiguously, it is possible to later flip the images in the screen at will in most software.
- The file format still relies too much on the file extension being
.niior on a pair
.hdr/.img, rather than much less ambiguous magic strings or numbers. On the other hand, the different magic strings for single file and for file pairs effectively prevent the possibility of file splitting/merging using common operating system tools (such as
ddin Linux), as the magic string needs to be changed, even though the header structure remains absolutely identical.
- The magic string that is present in the header is not placed at the beginning, but near its end, which makes the file virtually unrecognisable outside of the neuroimaging field.
- The specification of three different coordinate systems, while bringing flexibility, also brought ambiguity, as nowhere in the standard there is information on which should be preferred when more than one is present. Certain software packages explicitly force the
sform_codeto be identical to each other.
- There is no field specifying a preferred interpolation method when using Methods 2 or 3, even though these methods do allow fractional voxels to be found with the specification of world coordinates.
- Method 2 allows only rotation and translation, but sometimes, due to all sorts of scanner calibration issues and different kinds of geometric distortion present in different sequences, the coregistration between two images of the same subject may require scaling and shear, which are only provided in Method 3.
- Method 3 is supposed to inform that the data is aligned to a standard space using an affine transformation. This works perfectly if the data has been previously warped to such a space. Otherwise, the simple alignment of any actual brain from native to standard space cannot be obtained with only linear transformations.
- To squeeze information while keeping compatibility with the analyze format, some fields had to be mangled into just one byte, such as
char xyzt_units, which is not practical and require sub-byte manipulation.
- The field
float vox_offset, directly inherited from the analyze format, should in fact, be an integer. Having it as a float only adds confusion.
- Not all software packages implement the format exactly in the same way. Vector-based data, for instance, which should be stored in the 5th dimension, is often stored in the 4th, which should be reserved for time. Although this is not a problem with the format itself, but with the use made of it, easy implementation malpractices lead to a dissemination of ambiguous and ill-formed files that eventually cannot be read in other applications as intended by the time of the file creation.
Despite these issues, the format has been very successful as a means to exchange data between different software packages. An updated format, the nifti 2.0, with a header with more than 500 bytes of information, may become official soon. (UPDATE: details here)
The official definition of the nifti format is available as a c header file (
nifti1.h) here and mirrored here.