Read images in PAR/REC format.
This is yet another MRI image format generated by Philips scanners. It is an ASCII header (PAR) plus a binary blob (REC).
This implementation aims to read version 4 and 4.2 of this format. Other versions could probably be supported, but we need example images to test against. If you want us to support another version, and have an image we can add to the test suite, let us know. You would make us very happy by submitting a pull request.
The PAR format appears to have two sections:
This is a set of lines each giving one key : value pair, examples:
. EPI factor <0,1=no EPI> : 39
. Dynamic scan <0=no 1=yes> ? : 1
. Diffusion <0=no 1=yes> ? : 0
(from nibabe/tests/data/phantom_EPI_asc_CLEAR_2_1.PAR)
There is a # prefixed list of fields under the heading “IMAGE INFORMATION DEFINITION”. From the same file, here is the start of this list:
# === IMAGE INFORMATION DEFINITION =============================================
# The rest of this file contains ONE line per image, this line contains the following information:
#
# slice number (integer)
# echo number (integer)
# dynamic scan number (integer)
There follows a space separated table with values for these fields, each row containing all the named values. Here’s the first few lines from the example file above:
# === IMAGE INFORMATION ==========================================================
# sl ec dyn ph ty idx pix scan% rec size (re)scale window angulation offcentre thick gap info spacing echo dtime ttime diff avg flip freq RR-int turbo delay b grad cont anis diffusion L.ty
1 1 1 1 0 2 0 16 62 64 64 0.00000 1.29035 4.28404e-003 1070 1860 -13.26 -0.00 -0.00 2.51 -0.81 -8.69 6.000 2.000 0 1 0 2 3.750 3.750 30.00 0.00 0.00 0.00 0 90.00 0 0 0 39 0.0 1 1 8 0 0.000 0.000 0.000 1
2 1 1 1 0 2 1 16 62 64 64 0.00000 1.29035 4.28404e-003 1122 1951 -13.26 -0.00 -0.00 2.51 6.98 -10.53 6.000 2.000 0 1 0 2 3.750 3.750 30.00 0.00 0.00 0.00 0 90.00 0 0 0 39 0.0 1 1 8 0 0.000 0.000 0.000 1
3 1 1 1 0 2 2 16 62 64 64 0.00000 1.29035 4.28404e-003 1137 1977 -13.26 -0.00 -0.00 2.51 14.77 -12.36 6.000 2.000 0 1 0 2 3.750 3.750 30.00 0.00 0.00 0.00 0 90.00 0 0 0 39 0.0 1 1 8 0 0.000 0.000 0.000 1
PAR files refer to orientations “ap”, “fh” and “rl”.
Nibabel’s required affine output axes are RAS (left to Right, posterior to Anterior, inferior to Superior). The correspondence of the PAR file’s axes to RAS axes is:
The orientation of the PAR file axes corresponds to DICOM’s LPS coordinate system (right to Left, anterior to Posterior, inferior to Superior), but in a different order.
We call the PAR file’s axis system “PSL” (Posterior, Superior, Left)
It seems that everyone agrees that Philips stores REC data in little-endian format - see https://github.com/nipy/nibabel/issues/274
Philips XML header files, and some previous experience, suggest that the REC data is always stored as 8 or 16 bit unsigned integers - see https://github.com/nipy/nibabel/issues/275
PARRECArrayProxy(*args, **kwargs) | Initialize PARREC array proxy |
PARRECError | Exception for PAR/REC format related problems. |
PARRECHeader(info, image_defs[, ...]) | PAR/REC header |
PARRECImage(dataobj, affine[, header, ...]) | PAR/REC image |
load | Create PARREC image from filename filename |
one_line(long_str) | Make maybe mutli-line long_str into one long line |
parse_PAR_header(fobj) | Parse a PAR header and aggregate all information into useful containers. |
vol_is_full(slice_nos, slice_max[, slice_min]) | Vector with True for slices in complete volume, False otherwise |
vol_numbers(slice_nos) | Calculate volume numbers inferred from slice numbers slice_nos |
Bases: object
Initialize PARREC array proxy
Parameters: | file_like : file-like object
header : PARRECHeader instance
mmap : {True, False, ‘c’, ‘r’}, optional, keyword only
scaling : {‘fp’, ‘dv’}, optional, keyword only
|
---|
Initialize PARREC array proxy
Parameters: | file_like : file-like object
header : PARRECHeader instance
mmap : {True, False, ‘c’, ‘r’}, optional, keyword only
scaling : {‘fp’, ‘dv’}, optional, keyword only
|
---|
Bases: nibabel.spatialimages.Header
PAR/REC header
Parameters: | info : dict
image_defs : array
permit_truncated : bool, optional
|
---|
Parameters: | info : dict
image_defs : array
permit_truncated : bool, optional
|
---|
Convert PAR parameters to NIFTI1 format
Compute affine transformation into scanner space.
The method only considers global rotation and offset settings in the header and ignores potentially deviating information in the image definitions.
Parameters: | origin : {‘scanner’, ‘fov’}
|
---|---|
Returns: | aff : (4, 4) array
|
Notes
Transformations appear to be specified in (ap, fh, rl) axes. The orientation of data is recorded in the “slice orientation” field of the PAR header “General Information”.
We need to:
Get bvals and bvecs from data
Returns: | b_vals : None or array
b_vectors : None or array
|
---|
PAR header always has 0 data offset (into REC file)
Returns scaling slope and intercept.
Parameters: | method : {‘fp’, ‘dv’}
|
---|---|
Returns: | slope : array
intercept : array
|
Notes
The PAR header contains two different scaling settings: ‘dv’ (value on console) and ‘fp’ (floating point value). Here is how they are defined:
PV: value in REC RS: rescale slope RI: rescale intercept SS: scale slope
DV = PV * RS + RI FP = DV / (RS * SS)
Echo train length of the recording
Get Q vectors from the data
Returns: | q_vectors : None or array
|
---|
Returns the slice orientation label.
Returns: | orientation : {‘transverse’, ‘sagittal’, ‘coronal’} |
---|
Indices to sort (and maybe discard) slices in REC file
Returns list for indexing into the last (third) dimension of the REC data array, and (equivalently) the only dimension of self.image_defs.
If the recording is truncated, the returned indices take care of discarding any indices that are not meant to be used.
Returns the spatial extent of a voxel.
Does not include the slice gap in the slice extent.
This function is deprecated and we will remove it in future versions of nibabel. Please use get_zooms instead. If you need the slice thickness not including the slice gap, use self.image_defs['slice thickness'].
Returns: | vox_size: shape (3,) ndarray : |
---|
Water fat shift, in pixels
PAR header always has 0 data offset (into REC file)
Bases: nibabel.spatialimages.SpatialImage
PAR/REC image
Initialize image
The image is a combination of (array, affine matrix, header), with optional metadata in extra, and filename / file-like objects contained in the file_map mapping.
Parameters: | dataobj : object
affine : None or (4,4) array-like
header : None or mapping or header instance, optional
extra : None or mapping, optional
file_map : mapping, optional
|
---|
Initialize image
The image is a combination of (array, affine matrix, header), with optional metadata in extra, and filename / file-like objects contained in the file_map mapping.
Parameters: | dataobj : object
affine : None or (4,4) array-like
header : None or mapping or header instance, optional
extra : None or mapping, optional
file_map : mapping, optional
|
---|
alias of PARRECArrayProxy
Create PARREC image from file map file_map
Parameters: | file_map : dict
mmap : {True, False, ‘c’, ‘r’}, optional, keyword only
permit_truncated : {False, True}, optional, keyword-only
scaling : {‘dv’, ‘fp’}, optional, keyword-only
|
---|
Create PARREC image from filename filename
Parameters: | filename : str
mmap : {True, False, ‘c’, ‘r’}, optional, keyword only
permit_truncated : {False, True}, optional, keyword-only
scaling : {‘dv’, ‘fp’}, optional, keyword-only
|
---|
alias of PARRECHeader
Create PARREC image from filename filename
Parameters: | filename : str
mmap : {True, False, ‘c’, ‘r’}, optional, keyword only
permit_truncated : {False, True}, optional, keyword-only
scaling : {‘dv’, ‘fp’}, optional, keyword-only
|
---|
Create PARREC image from filename filename
Parameters: | filename : str
mmap : {True, False, ‘c’, ‘r’}, optional, keyword only
permit_truncated : {False, True}, optional, keyword-only
scaling : {‘dv’, ‘fp’}, optional, keyword-only
|
---|
Parse a PAR header and aggregate all information into useful containers.
Parameters: | fobj : file-object
|
---|---|
Returns: | general_info : dict
image_info : ndarray
|
Vector with True for slices in complete volume, False otherwise
Parameters: | slice_nos : sequence
slice_max : int
slice_min : int
|
---|---|
Returns: | is_full : array
|
Raises: | ValueError :
|
Calculate volume numbers inferred from slice numbers slice_nos
The volume number for each slice is the number of times this slice has occurred previously in the slice_nos sequence
Parameters: | slice_nos : sequence
|
---|---|
Returns: | vol_nos : list
|