Each dataset has a header which is always stored at the beginning of a file with extension ".mri". So the header for dataset "example1" is located in "example1.mri". The header holds a set of key/value pairs. The value of a key is a string. For instance, we could have an "acquisition_date" key with value "15-Dec-95". Other keys could hold strictly numerical strings, such as "34".
In the special case where the key's value is "[chunk]", the key points off to a large chunk of binary data. These chunks are simply multidimensional arrays of data. So we may have an "images" key which points to a 256x256x9x100 array of image data, holding 256x256 resolution images with 9 slices at each of 100 timesteps.
These binary chunks may be stored in the ".mri" file after the header. Or they may be directed into other files at the API level. For instance, it would not be unusual to keep the "images" data in a file named "example1.dat".
The header is written at the beginning of the .mri file and consists of ASCII characters so that it is human-readable. The header is basically just a list of lines of the form "key = value".
The format may be described by the following grammar (a '|' indicates alternative constructions and a '*' indicates 0 or more repetitions of the starred item):
<mri-file> := <header> |
<header> ^L^Z <binary data>*
<header> := <key-value-pair>*
<key-value-pair> := <key> = <value> ^J # one key/value pair per line
<key> := <string>
<value> := <string>
<string> := <an unquoted sequence of non-control
characters but excluding '='> |
" <a quoted C-style string> "
We separate the binary data with ^L^Z
to facilitate viewing the file with
'more' and other utilities.
Keys are arbitrary strings; note that case is significant.
Values are arbitrary strings; special case: [chunk] indicates that the value is a chunk.
White space is ignored between elements, but is significant within quoted string values.
The only mandatory keys are "!format" and "!version" keys which identify the file as a PGH-format MRI dataset. The '!' prefix is used to force these keys to be first in the header, since the header is typically written out with the keys sorted alphabetically.
!format = pgh
!version = 1.0
We reserve some keys in order to specify how binary chunks are to be interpreted. We adopt the convention that these keys are named by concatenating the chunk name with a dot and an identifying suffix. For example if we have an "images" chunk, we will name its properties as follows:
images.datatype = int16
images.dimensions = xyzt
images.extent.x = 64
images.extent.y = 64
images.extent.z = 10
images.file = .dat
images.order = 0
images.offset = 0
images.size = 81920
where:
uint8 # unsigned 8-bit integer
int16 # signed 16-bit integer
int32 # sigend 32-bit integer
float32 # 32-bit IEEE floating pt number
float64 # 64-bit IEEE floating pt number