Skip to content

NF: add support for V4 of PARREC format #277

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 19, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 32 additions & 13 deletions nibabel/parrec.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@
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.2 of this format. Other versions
could probably be supported, but the author is lacking samples of them.
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.

###############
PAR file format
Expand Down Expand Up @@ -120,8 +123,6 @@
[1, 0, 0, 0], # L
[0, 0, 0, 1]])
)
# PAR header versions we claim to understand
supported_versions = ['V4.2']

# General information dict definitions
# assign props to PAR header entries
Expand Down Expand Up @@ -159,14 +160,17 @@
'Dynamic scan <0=no 1=yes> ?': ('dyn_scan', int),
'Diffusion <0=no 1=yes> ?': ('diffusion', int),
'Diffusion echo time [ms]': ('diffusion_echo_time', float),
# Lines below added for par / rec versions > 4
'Max. number of diffusion values': ('max_diffusion_values', int),
'Max. number of gradient orients': ('max_gradient_orient', int),
# Line below added for par / rec version > 4.1
'Number of label types <0=no ASL>': ('nr_label_types', int),
}

# Image information as coded into a numpy structured array
# header items order per image definition line
image_def_dtd = [
image_def_dtds = {}
image_def_dtds['V4'] = [
('slice number', int),
('echo number', int,),
('dynamic scan number', int,),
Expand Down Expand Up @@ -201,17 +205,29 @@
('minimum RR-interval', int,),
('maximum RR-interval', int,),
('TURBO factor', int,),
('Inversion delay', float),
('Inversion delay', float)]

# Extra image def fields for 4.1 compared to 4
image_def_dtds['V4.1'] = image_def_dtds['V4'] + [
('diffusion b value number', int,), # (imagekey!)
('gradient orientation number', int,), # (imagekey!)
('contrast type', 'S30'), # XXX might be too short?
('diffusion anisotropy type', 'S30'), # XXX might be too short?
('diffusion', float, (3,)),
('label type', int,), # (imagekey!)
]
image_def_dtype = np.dtype(image_def_dtd)

# slice orientation codes
# Extra image def fields for 4.2 compared to 4.1
image_def_dtds['V4.2'] = image_def_dtds['V4.1'] + [
('label type', int,), # (imagekey!)
]

#: PAR header versions we claim to understand
supported_versions = list(image_def_dtds.keys())

#: Deprecated; please don't use
image_def_dtype = np.dtype(image_def_dtds['V4.2'])

#: slice orientation codes
slice_orientation_codes = Recoder(( # code, label
(1, 'transverse'),
(2, 'sagittal'),
Expand Down Expand Up @@ -281,12 +297,13 @@ def _process_gen_dict(gen_dict):
return general_info


def _process_image_lines(image_lines):
""" Process image information definition lines
def _process_image_lines(image_lines, version):
""" Process image information definition lines according to `version`
"""
# postproc image def props
image_def_dtd = image_def_dtds[version]
# create an array for all image defs
image_defs = np.zeros(len(image_lines), dtype=image_def_dtype)
image_defs = np.zeros(len(image_lines), dtype=image_def_dtd)
# for every image definition
for i, line in enumerate(image_lines):
items = line.split()
Expand Down Expand Up @@ -385,6 +402,8 @@ def _err_or_warn(msg):
warnings.warn(msg)

def _chk_trunc(idef_name, gdef_max_name):
if not gdef_max_name in general_info:
return
id_values = image_defs[idef_name + ' number']
n_have = len(set(id_values))
n_expected = general_info[gdef_max_name]
Expand Down Expand Up @@ -435,7 +454,7 @@ def parse_PAR_header(fobj):
list, if you are interested in adding support for this version.
""".format(version)))
general_info = _process_gen_dict(gen_dict)
image_defs = _process_image_lines(image_lines)
image_defs = _process_image_lines(image_lines, version)
return general_info, image_defs


Expand Down
120 changes: 120 additions & 0 deletions nibabel/tests/data/phantom_fake_v4.PAR
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# === DATA DESCRIPTION FILE ======================================================
#
# CAUTION - Investigational device.
# Limited by Federal Law to investigational use.
#
# Dataset name: E:\\Export\phantom_EPI_asc_CLEAR_2_1
#
# CLINICAL TRYOUT Research image export tool V4
#
# === GENERAL INFORMATION ========================================================
#
. Patient name : phantom
. Examination name : Konvertertest
. Protocol name : EPI_asc CLEAR
. Examination date/time : 2014.02.14 / 09:00:57
. Series Type : Image MRSERIES
. Acquisition nr : 2
. Reconstruction nr : 1
. Scan Duration [sec] : 14
. Max. number of cardiac phases : 1
. Max. number of echoes : 1
. Max. number of slices/locations : 9
. Max. number of dynamics : 3
. Max. number of mixes : 1
. Patient position : Head First Supine
. Preparation direction : Anterior-Posterior
. Technique : FEEPI
. Scan resolution (x, y) : 64 39
. Scan mode : MS
. Repetition time [ms] : 2000.000
. FOV (ap,fh,rl) [mm] : 240.000 70.000 240.000
. Water Fat shift [pixels] : 11.050
. Angulation midslice(ap,fh,rl)[degr]: -13.265 0.000 0.000
. Off Centre midslice(ap,fh,rl) [mm] : 2.508 30.339 -16.032
. Flow compensation <0=no 1=yes> ? : 0
. Presaturation <0=no 1=yes> ? : 0
. Phase encoding velocity [cm/sec] : 0.000000 0.000000 0.000000
. MTC <0=no 1=yes> ? : 0
. SPIR <0=no 1=yes> ? : 1
. EPI factor <0,1=no EPI> : 39
. Dynamic scan <0=no 1=yes> ? : 1
. Diffusion <0=no 1=yes> ? : 0
. Diffusion echo time [ms] : 0.0000
#
# === PIXEL VALUES =============================================================
# PV = pixel value in REC file, FP = floating point value, DV = displayed value on console
# RS = rescale slope, RI = rescale intercept, SS = scale slope
# DV = PV * RS + RI FP = DV / (RS * SS)
#
# === 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)
# cardiac phase number (integer)
# image_type_mr (integer)
# scanning sequence (integer)
# index in REC file (in images) (integer)
# image pixel size (in bits) (integer)
# scan percentage (integer)
# recon resolution (x y) (2*integer)
# rescale intercept (float)
# rescale slope (float)
# scale slope (float)
# window center (integer)
# window width (integer)
# image angulation (ap,fh,rl in degrees ) (3*float)
# image offcentre (ap,fh,rl in mm ) (3*float)
# slice thickness (in mm ) (float)
# slice gap (in mm ) (float)
# image_display_orientation (integer)
# slice orientation ( TRA/SAG/COR ) (integer)
# fmri_status_indication (integer)
# image_type_ed_es (end diast/end syst) (integer)
# pixel spacing (x,y) (in mm) (2*float)
# echo_time (float)
# dyn_scan_begin_time (float)
# trigger_time (float)
# diffusion_b_factor (float)
# number of averages (integer)
# image_flip_angle (in degrees) (float)
# cardiac frequency (bpm) (integer)
# minimum RR-interval (in ms) (integer)
# maximum RR-interval (in ms) (integer)
# TURBO factor <0=no turbo> (integer)
# Inversion delay (in ms) (float)
#
# === 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

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
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
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
4 1 1 1 0 2 3 16 62 64 64 0.00000 1.29035 4.28404e-003 1217 2116 -13.26 -0.00 -0.00 2.51 22.55 -14.20 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
5 1 1 1 0 2 4 16 62 64 64 0.00000 1.29035 4.28404e-003 1216 2113 -13.26 -0.00 -0.00 2.51 30.34 -16.03 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
6 1 1 1 0 2 5 16 62 64 64 0.00000 1.29035 4.28404e-003 1141 1983 -13.26 -0.00 -0.00 2.51 38.13 -17.87 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
7 1 1 1 0 2 6 16 62 64 64 0.00000 1.29035 4.28404e-003 1119 1945 -13.26 -0.00 -0.00 2.51 45.91 -19.70 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
8 1 1 1 0 2 7 16 62 64 64 0.00000 1.29035 4.28404e-003 1097 1907 -13.26 -0.00 -0.00 2.51 53.70 -21.54 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
9 1 1 1 0 2 8 16 62 64 64 0.00000 1.29035 4.28404e-003 1146 1991 -13.26 -0.00 -0.00 2.51 61.49 -23.37 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 2 1 0 2 9 16 62 64 64 0.00000 1.29035 4.28404e-003 1071 1863 -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 2.00 0.00 0.00 0 90.00 0 0 0 39 0.0
2 1 2 1 0 2 10 16 62 64 64 0.00000 1.29035 4.28404e-003 1123 1953 -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 2.00 0.00 0.00 0 90.00 0 0 0 39 0.0
3 1 2 1 0 2 11 16 62 64 64 0.00000 1.29035 4.28404e-003 1135 1973 -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 2.00 0.00 0.00 0 90.00 0 0 0 39 0.0
4 1 2 1 0 2 12 16 62 64 64 0.00000 1.29035 4.28404e-003 1209 2101 -13.26 -0.00 -0.00 2.51 22.55 -14.20 6.000 2.000 0 1 0 2 3.750 3.750 30.00 2.00 0.00 0.00 0 90.00 0 0 0 39 0.0
5 1 2 1 0 2 13 16 62 64 64 0.00000 1.29035 4.28404e-003 1215 2113 -13.26 -0.00 -0.00 2.51 30.34 -16.03 6.000 2.000 0 1 0 2 3.750 3.750 30.00 2.00 0.00 0.00 0 90.00 0 0 0 39 0.0
6 1 2 1 0 2 14 16 62 64 64 0.00000 1.29035 4.28404e-003 1145 1990 -13.26 -0.00 -0.00 2.51 38.13 -17.87 6.000 2.000 0 1 0 2 3.750 3.750 30.00 2.00 0.00 0.00 0 90.00 0 0 0 39 0.0
7 1 2 1 0 2 15 16 62 64 64 0.00000 1.29035 4.28404e-003 1119 1945 -13.26 -0.00 -0.00 2.51 45.91 -19.70 6.000 2.000 0 1 0 2 3.750 3.750 30.00 2.00 0.00 0.00 0 90.00 0 0 0 39 0.0
8 1 2 1 0 2 16 16 62 64 64 0.00000 1.29035 4.28404e-003 1093 1899 -13.26 -0.00 -0.00 2.51 53.70 -21.54 6.000 2.000 0 1 0 2 3.750 3.750 30.00 2.00 0.00 0.00 0 90.00 0 0 0 39 0.0
9 1 2 1 0 2 17 16 62 64 64 0.00000 1.29035 4.28404e-003 1150 1999 -13.26 -0.00 -0.00 2.51 61.49 -23.37 6.000 2.000 0 1 0 2 3.750 3.750 30.00 2.00 0.00 0.00 0 90.00 0 0 0 39 0.0
1 1 3 1 0 2 18 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 4.00 0.00 0.00 0 90.00 0 0 0 39 0.0
2 1 3 1 0 2 19 16 62 64 64 0.00000 1.29035 4.28404e-003 1125 1955 -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 4.00 0.00 0.00 0 90.00 0 0 0 39 0.0
3 1 3 1 0 2 20 16 62 64 64 0.00000 1.29035 4.28404e-003 1135 1973 -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 4.00 0.00 0.00 0 90.00 0 0 0 39 0.0
4 1 3 1 0 2 21 16 62 64 64 0.00000 1.29035 4.28404e-003 1211 2105 -13.26 -0.00 -0.00 2.51 22.55 -14.20 6.000 2.000 0 1 0 2 3.750 3.750 30.00 4.00 0.00 0.00 0 90.00 0 0 0 39 0.0
5 1 3 1 0 2 22 16 62 64 64 0.00000 1.29035 4.28404e-003 1218 2118 -13.26 -0.00 -0.00 2.51 30.34 -16.03 6.000 2.000 0 1 0 2 3.750 3.750 30.00 4.00 0.00 0.00 0 90.00 0 0 0 39 0.0
6 1 3 1 0 2 23 16 62 64 64 0.00000 1.29035 4.28404e-003 1143 1987 -13.26 -0.00 -0.00 2.51 38.13 -17.87 6.000 2.000 0 1 0 2 3.750 3.750 30.00 4.00 0.00 0.00 0 90.00 0 0 0 39 0.0
7 1 3 1 0 2 24 16 62 64 64 0.00000 1.29035 4.28404e-003 1120 1947 -13.26 -0.00 -0.00 2.51 45.91 -19.70 6.000 2.000 0 1 0 2 3.750 3.750 30.00 4.00 0.00 0.00 0 90.00 0 0 0 39 0.0
8 1 3 1 0 2 25 16 62 64 64 0.00000 1.29035 4.28404e-003 1093 1901 -13.26 -0.00 -0.00 2.51 53.70 -21.54 6.000 2.000 0 1 0 2 3.750 3.750 30.00 4.00 0.00 0.00 0 90.00 0 0 0 39 0.0
9 1 3 1 0 2 26 16 62 64 64 0.00000 1.29035 4.28404e-003 1151 2001 -13.26 -0.00 -0.00 2.51 61.49 -23.37 6.000 2.000 0 1 0 2 3.750 3.750 30.00 4.00 0.00 0.00 0 90.00 0 0 0 39 0.0

# === END OF DATA DESCRIPTION FILE ===============================================
Loading