Last edit: 05-08-29 Graham Wideman |
Analyze Format |
Mayo/SPM "Analyze" Format Spec
Compilation Article created: 2003-06-22 |
Mayo Clinic Analyze 7.5 format is a file format for storing MRI data. An Analyze 7.5 data set consists of two files:
Although this is conceptually straightforward, there is enough variation in how different software treats voxel ordering (orientation) that getting the desired results can be tricky.
This document is an attempt to compile definitive information from a number of sources. It may continue to be a work-in-progress.
The following discussion relies on some familiarity with terminology for axes, orientation, voxel order and so on. Some of this terminology is used in multiple and sometimes contradictory or opposite ways. For details see the Orientation and Voxel-Order Terminology page.
The following table lists the Analyze format as specified by Mayo Clinic, showing variations used in SPM and by Darren Weber's mri_toolbox. Not all software understands all fields, as further discussed in the Image File section later. See also the list of notes below this table.
Mayo Analyze 7.5 | SPM99 | SPM2 | mri_toolbox | ||||||||||
Row | OS | Sec | name | type | name | type | AKA | name | type | AKA | name | type | Short Description (Mayo doc, plus other notes) |
1 | 0 | key | sizeof_hdr | int32 | Must indicate the byte size of the header file.
Non SPM2: Always 348, used to test big/little-endian). SPM2: If >348 indicates extended header |
||||||||
2 | 4 | data_type | uchar[10] | ||||||||||
3 | 14 | db_name | uchar[18] | ||||||||||
4 | 32 | extents | int32 | Should be 16384, the image file is created as contiguous with a minimum extent size. | |||||||||
5 | 36 | session_error | int16 | ||||||||||
6 | 38 | regular | uchar | Must be "r" to indicate that all images and volumes are the same size. | |||||||||
7 | 39 | hkey_un0 | uchar | ||||||||||
8 | 40 | dim | dim[0] | int16 | Number of dimensions in database; usually 4 | ||||||||
9 | 42 | dim[1] | int16 | DIM | Image X dimension; number of pixels in an image row | ||||||||
10 | 44 | dim[2] | int16 | DIM | Image Y dimension; number of pixel rows in slice | ||||||||
11 | 46 | dim[3] | int16 | DIM | Volume Z dimension; number of slices in a volume | ||||||||
12 | 48 | dim[4] | int16 | Time points, number of volumes in database. | |||||||||
13 | 50 | dim[5] | int16 | undoc | |||||||||
14 | 52 | dim[6] | int16 | undoc | |||||||||
15 | 54 | dim[7] | int16 | undoc | |||||||||
16 | 56 | vox_units | uchar[4] | spatial units of measure for a voxel | |||||||||
17 | 60 | cal_units | uchar[8] | name of the calibration unit | |||||||||
18 | 68 | unused1 | int16 | ||||||||||
19 | 70 | datatype | int16 | See DT_xxx values | |||||||||
20 | 72 | bitpix | int16 | bits per pixel; 1, 8, 16, 32, or 64. | |||||||||
21 | 74 | dim_un0 | int16 | unused | |||||||||
22 | 76 | pixdim[0] | float | ||||||||||
23 | 80 | pixdim[1] | float | voxel width in mm. | |||||||||
24 | 84 | pixdim[2] | float | voxel height in mm. | |||||||||
25 | 88 | pixdim[3] | float | slice thickness in mm. | |||||||||
26 | 92 | pixdim[4] | float | undoc | |||||||||
27 | 96 | pixdim[5] | float | undoc | |||||||||
28 | 100 | pixdim[6] | float | undoc | |||||||||
29 | 104 | pixdim[7] | float | undoc | |||||||||
30 | 108 | vox_offset | float | Byte offset in the .img file at which voxels start. This value can be negative to specify that the absolute value is applied for every image in the file. | |||||||||
31 | 112 | funused1 | float | funused1 | float | SCALE | funused1 | float | scal | roi_scale | float | SPM: Scale factor | |
32 | 116 | funused2 | float | funused2 | float | funused2 | float | dcoff | funused1 | float | SPM2: image intensity zero-intercept | ||
33 | 120 | funused3 | float | funused3 | float | funused3 | float | funused2 | float | ||||
34 | 124 | cal_max | float | max calibration value | |||||||||
35 | 128 | cal_min | float | min calibration value | |||||||||
36 | 132 | compressed | float | ||||||||||
37 | 136 | verified | float | ||||||||||
38 | 140 | glmax | int32 | max pixel value for entire database | |||||||||
39 | 144 | glmin | int32 | min pixel value for entire database | |||||||||
40 | 148 | hist | descrip | uchar[80] | |||||||||
41 | 228 | aux_file | uchar[24] | ||||||||||
42 | 252 | orient | uchar | slice orientation for this dataset: See separate note | |||||||||
43 | 253 | originator | uchar[10] | origin[0] | int16 | ORIGIN | origin[0] | int16 | originator | uchar[10] | SPM99: X near Anterior Commissure | ||
44 | origin[1] | int16 | ORIGIN | origin[1] | int16 | SPM99: Y near Anterior Commissure | |||||||
45 | origin[2] | int16 | ORIGIN | origin[2] | int16 | SPM99: Z near Anterior Commissure | |||||||
46 | origin[3] | int16 | ORIGIN | origin[3] | int16 | ||||||||
47 | origin[4] | int16 | ORIGIN | origin[4] | int16 | ||||||||
48 | 263 | generated | uchar[10] | ||||||||||
49 | 273 | scannum | uchar[10] | ||||||||||
50 | 283 | patient_id | uchar[10] | ||||||||||
51 | 293 | exp_date | uchar[10] | ||||||||||
52 | 303 | exp_time | uchar[10] | ||||||||||
53 | 313 | hist_un0 | uchar[3] | ||||||||||
54 | 316 | views | int32 | ||||||||||
55 | 320 | vols_added | int32 | ||||||||||
56 | 324 | start_field | int32 | ||||||||||
57 | 328 | field_skip | int32 | ||||||||||
58 | 332 | omax | int32 | ||||||||||
59 | 336 | omin | int32 | ||||||||||
60 | 340 | smax | int32 | ||||||||||
61 | 344 | smin | int32 | ||||||||||
348 | TOTAL BYTES |
.
Key | Source |
Mayo Analyze 7.5 | Mayo Clinic Analyze 7.5 Format: www.mayo.edu/bir/PDF/ANALYZE75.pdf |
SPM99 | SPM99 spm_hread.m SPM Home: www.fil.ion.ucl.ac.uk/spm |
SPM2 | SPM2 spm_read_hdr.m |
mri_toolbox | Darren Weber's mri_toolbox v1.8: Matlab EEG-MRI Toolbox |
.
datatype DT_xxx | Value | Description |
DT_NONE | 0 | |
DT_UNKNOWN | 0 | |
DT_BINARY | 1 | 1 bit per voxel |
DT_UNSIGNED_CHAR | 2 | 8 bits per voxel |
DT_SIGNED_SHORT | 4 | 16 bits per voxel |
DT_SIGNED_INT | 8 | 32 bits per voxel |
DT_FLOAT | 16 | 32 bits per voxel (single) |
DT_COMPLEX | 32 | 2 x 32 bit single |
DT_DOUBLE | 64 | 64 bits per voxel |
DT_RGB | 128 | |
DT_ALL | 255 |
.
Notes | |
unused8 to unused14 | The Mayo Format Doc ANALYZE75.pdf lists fields unused8-14 at Offsets 56-69. However, their dbh.h file lists vox_units and cal_units in this area, and even the comments in the pdf file refer to vox_units -- indicating that perhaps their unused8-14 fields are left over from an earlier generation of source code. |
sizeof_hdr | This field implies that Analyze format was
originally intended to be extensible, but in practice this did not happen,
and instead the file size (and hence the value of this field) is 348.
Software commonly tests the value in this field to detect whether the byte
ordering is Big-Endian or Little-Endian. (Note that future variants of Analyze format with longer files are anticipated. See also SPM2 note below. Hopefully each extended format will be readily identifiable if longer than 348 bytes even if byte-order is not known). |
MatLab array indices | I have shown array indices as based at 0, as for example from C language. If using them from MatLab I believe it's necessary to treat arrays as one-based. |
hist.orient | Subject of more discussion below |
SPM2 extension | SPM2 source code (spm_read_hdr.m) indicates that it can employ an extension to the size of the hdr file to contain further info. |
.
An Analyze 7.5 image file consists of one long stream of voxel intensities. The format and ordering of the img file is described as follows:
Format aspect | Field etc | Discussion |
Data type | dim.datatype | A particular img file represents voxel intensities using from one bit to 8 bytes per voxel, according to the value of this field. See the DT_xxx values. |
byte order | --- | Little-endian vs Big-Endian-- software must test for which byte-order is in use in this file. See note on sizeof_hdr as a test field. |
Voxel order | hist.orient dim.pixdim others? |
See further details in discussion below |
Multiple volumes | --- | One after another in the file. The key.regular field suggests that volumes could be different sizes etc, but that would presumably also require multiple dim sections, and this does not seem to occur. |
Of crucial importance is the ordering of voxels within the img file. Unfortunately, the document "Mayo Clinic Analyze 7.5 Format" omits some essential details on this (possibly an oversight). Whether as a result of this or not, there is considerable variation in the way different software developers have treated voxel storage order.
Consequently, there are two different stories to be told:
My understanding of this owes a great deal to the patient persuasion of Darren Weber (and his thoroughly researched mri_toolbox source code). I have since corroborated his detective work with inputs from another group, so this looks like a solid case, even if the info is hard to come by (less so thanks to Darren of course).
Consolidating the notes in Darren's source code, which is based on email from AnalyzeSupport.com, we get.
hist.orient | Mayo name | Voxel[Index0, Index1, Index2] | ||
Index0 | Index1 | Index2 | ||
0 (default) | transverse unflipped | R-L | P-A | I-S |
1 | coronal unflipped | R-L | I-S | P-A |
2 | sagittal unflipped | P-A | I-S | R-L |
3 | transverse flipped | R-L | A-P | I-S |
4 | coronal flipped | R-L | S-I | P-A |
5 | sagittal flipped | P-A | S-I | R-L |
Note: Index0 is
fastest-varying (innermost-nested) index, Index2 the outermost. Index0..Index2 are often called X, Y, Z, but I am trying to avoid confusion with spatial coordinates. 2004-04-18: See later section for comparison to NIfTI |
Aside from the hard-to-come-by documentation of hist.orient, the major shortcoming of this field as a code for voxel order is that it only covers 6 of the 48 possible orders. This means that software authors who wanted to be able to honor some voxel-order scheme did not have a field provided. In particular, though hist.orient provides the popular (R-L, P-A, I-S) orientation, it omits the L-R flip of this, (L-R, P-A, I-S).
This has proven to be a critical issue. Neither end users nor software authors have been held back from reorienting their data, either to create different views in viewers which lack orientation control, or for convenience in processing the data.
In recognition of this fact, one of the most hopeful thrusts of the NIfTI initiative (more below) is to establish a standard way to use this field. (It can't arrive soon enough!).
Below are some variations in the way software deals with Analyze format voxel order, with implications for results when using these packages, or files produced by these packages. (This is not a criticism of these packages so much as simply a caution that given the uncertainty in the way voxel-order is actually handled by software it's important to be aware of the hazard and prepare to take remedial action.)
Some important factors:
In the list below, I won't attempt to get the exact details correct enough for programmer satisfaction, but simply to indicate where the particular software differs from "Strict" Analyze 7.5 format in some manner. The main point is to raise awareness that orientation can't be taken for granted.
Software | Version | hist.orient | -negative pixdims | Orientation Treatment |
SPM | 99 | ignores | not sure | Pre-normalization: assumes voxels in (R-L, P-A,
I-S) order. Normalization creates data in (L-R, P-A, I-S) order SPM adds a third file (something.mat) with a transformation matrix -- not sure how this impacts data order There is also a sptl_Ornt variable |
SPM | 2 | ignores | not sure | Change in voxel order: "images spatially normalised using SPM99 or earlier will need to be spatially normalised again" according to SPM docs. |
AFNI | 2003-04 | ignores | ignores | Various AFNI utilities convert to or from
Analyze format. Generally you can set parameters to describe any input voxel
order, or to specify any output voxel order, disregarding hist.orient or -ve
pixdims. Program to3d attempts to detect SPM-normalized files by
looking for SPM's special usage of the hist.origin fields. According to AFNI docs, the AFNI viewer assumes (L-R P-A I-S) unless the AFNI_ANALYZE_ORIENT environment variable is set. |
MRIcro Viewer | 1.36 | ignores | ignores | File-to-screen mapping is such that a RPI (R-L, P-A, I-S) file will appear with patient right on screen left, superior at top, and anterior at top or right depending on view. Files with different ordering of axes will display, but oriented in ways that don't correspond to MRIcro's controls. See screenshots on Orientation page |
FSL | 3.0 | ignores | aware of | FSL programs do not use the history.orient field. As for pixdims, accordingto Mark Jenkinson: "Negative pixdims are used to determine the Talairach coordinates in fsl programs. They are not used to flip the data order or change the display, only to work out the Talairach (technically the MNI) coordinate in mm." |
Brought to my attention by several correspondents is the NIfTI initiative to define a new descendant of the Analyze format which would fix some of the shortcomings of the existing situation. Given that the group includes participants from a number of the more active Analyze-format-supporting software development groups, this holds promise that a format spec might result that will be more consistently adhered to.
Darren posted some additional related info to the FreeSurfer list, of interest to those who really need to understand Analyze data. I feel that DW's work and articles on this subject are the most authoritative available, particularly the notes in his avw_img_read source code that includes email from Analyze support documenting the hist.orient field.
Readers should be aware that his use of data-orientation notation is different from mine -- probably based on our different perceptions of which notations can be relied upon to be understood by others. I've more or less concluded that the three-letter notation for volume data orientation is sufficiently wobbly that I should always use 6-letter notation (eg: (R-L, P-A, I-S).
Darren's MRI Orientation Notes:
eeg.sourceforge.net/mri_orientation_notes.html
Description of avw_img_read.m
Darren is hosting two pdf docs that are versions of the Mayo Analyze 7.5 format spec. Linked from: Matlab EEG_Toolbox and MRI_Toolbox page, under the "MRI_Toolbox Features" head. You can read these docs in conjunction with the tables above that provide additional notes on the various header fields.
YT on the FreeSurfer list pointed out that the NIfTI 2004-04-15 NIfTI-1 Data Format Extension and Customization spec reports an interpretation of the sagittal flipped value (5) that is at odds with Darren W's research, and the distaillation I provided above.
hist.orient | Mayo name | Voxel[Index0, Index1, Index2] | NIfTI (2004-4-15) | ||
Index0 | Index1 | Index2 | Index0..2 | ||
0 (default) | transverse unflipped | R-L | P-A | I-S | R→L P→A I→S |
1 | coronal unflipped | R-L | I-S | P-A | R→L I→S P→A |
2 | sagittal unflipped | P-A | I-S | R-L | P→A I→S R→L |
3 | transverse flipped | R-L | A-P | I-S | R→L A→P I→S |
4 | coronal flipped | R-L | S-I | P-A | R→L S→I P→A |
5 | sagittal flipped | P-A | S-I | R-L | P→A I→S L→R |
Note: Index0 is
fastest-varying (innermost-nested) index, Index2 the outermost. 2004-04-15: NIfTI's interpretation of "sagittal flipped" looks off to me. See further notes below. |
To resolve this it would be great to see what source NIfTI's interpretation is based upon, and for my part I'll further detail the basis used here.
Darren W at some point received email from support at AnalyzeDirect.com, and includes it in the source code for avw_img_read.m. The salient parts are:
From avw_img_read.m, sections of the email from AnalyzeDirect.com | My comments |
orient = 2: The primary orientation of the data on disk is in the sagittal plane relative to the object scanned. Most commonly, the fastest moving index through the voxels that are part of this sagittal image would span the posterior-anterior extent of the structure imaged, with the next fastest moving index spanning the inferior-superior extent of the structure. | [P-A, I-S, ??] |
This 'orient' flag would indicate to Analyze that this data should be placed in the Y-Z plane of the 3D Analyze Coordinate System, with the X dimension being the slice direction. | [P-A, I-S, R-L] for orient.hist=2 |
Orient values 3-5 have the second index reversed in order, | so orient.hist=5 says to
flip the I-S axis, giving us: [P-A, S-I, R-L]... |
essentially 'flipping' the images relative to what would most likely become the vertical axis of the displayed image. | ... with this comment confirming that it's a "vertical" flip that's intended (relative to a viewer), and not an R-L flip. |
Left-handed coordinate
system X-Y plane is Transverse X-Z plane is Coronal Y-Z plane is Sagittal X axis runs from patient right (low X) to patient left (high X) Y axis runs from posterior (low Y) to anterior (high Y) Z axis runs from inferior (low Z) to superior (high Z) |
And for what it's worth, here we have X, Y and Z being used as synonyms for RL, PA and IS spatial axes (and thus not as synonyms for index 0..2). |
For the 'sagittal
flipped' type, the voxels are stored with Pixels in 'y' axis (varies fastest) - from patient posterior to Anterior Rows in 'z' axis - from patient superior to Inferior* Slices in 'x' axis - from patient right to Left |
And finally, Darren's summary of orient.hist=5 |
Darren Weber: First for researching and debating this problem at length in the past. Extensive posts on FSL and SPM lists. Some of Darren's discoveries are worked into Matlab EEG-MRI Toolbox. The avw_img_read.m file quotes crucial correspondence from Mayo on the meaning of hist.orient. Second for extensive and patient correspondence on these issues.
Chris Rorden, Author of MRIcro Viewer (and MRI Swiss Army Knife): A number of illuminating emails, explanations and background info.
Steve Smith and Mark Jenkinson of FMRIB for answering a number of questions relating to FSL.
The Analyze 7.5 File Format document contains the following copyright notice
regarding the header file format:
ANALYZE TM Header File Format
(c) Copyright, 1986-1995
Biomedical Imaging Resource
Mayo Foundation