From 2c0555afc6f149908e8400152a90394d898ca627 Mon Sep 17 00:00:00 2001 From: "Gregory R. Lee" Date: Wed, 25 Jan 2017 14:04:21 -0500 Subject: [PATCH 1/3] ENH: support some alternative header field name variants in .PAR files --- nibabel/parrec.py | 8 ++ nibabel/tests/data/variant_v4_2_header.par | 101 +++++++++++++++++++++ nibabel/tests/test_parrec.py | 14 +++ 3 files changed, 123 insertions(+) create mode 100644 nibabel/tests/data/variant_v4_2_header.par diff --git a/nibabel/parrec.py b/nibabel/parrec.py index c9c1568941..9928d1524c 100644 --- a/nibabel/parrec.py +++ b/nibabel/parrec.py @@ -206,6 +206,14 @@ '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), + # The following are duplicates of the above fields, but with slightly + # different abbreviation, spelling, or capatilization. Both variants have + # been observed in the wild in V4.2 PAR files: + # https://github.com/nipy/nibabel/issues/505 + 'Series_data_type': ('series_type',), + 'Patient Position': ('patient_position',), + 'Repetition time [msec]': ('repetition_time', float, None), + 'Diffusion echo time [msec]': ('diffusion_echo_time', float), } # Image information as coded into a numpy structured array diff --git a/nibabel/tests/data/variant_v4_2_header.par b/nibabel/tests/data/variant_v4_2_header.par new file mode 100644 index 0000000000..fde0dbe70b --- /dev/null +++ b/nibabel/tests/data/variant_v4_2_header.par @@ -0,0 +1,101 @@ +# === 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.1 +# +# === GENERAL INFORMATION ======================================================== +# +. Patient name : phantom +. Examination name : Konvertertest +. Protocol name : EPI_asc CLEAR +. Examination date/time : 2014.02.14 / 09:00:57 +. Series_data_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 : HFS +. Preparation direction : Anterior-Posterior +. Technique : FEEPI +. Scan resolution (x, y) : 64 39 +. Scan mode : MS +. Repetition time [msec] : 21225.76 +. 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 [msec] : 0.00 +. Max. number of diffusion values : 1 +. Max. number of gradient orients : 1 +# +# === 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) +# diffusion b value number (imagekey!) (integer) +# gradient orientation number (imagekey!) (integer) +# contrast type (string) +# diffusion anisotropy type (string) +# diffusion (ap, fh, rl) (3*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 b grad cont anis diffusion + + 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 + +# === END OF DATA DESCRIPTION FILE =============================================== diff --git a/nibabel/tests/test_parrec.py b/nibabel/tests/test_parrec.py index ed50150706..572f3a6ec4 100644 --- a/nibabel/tests/test_parrec.py +++ b/nibabel/tests/test_parrec.py @@ -49,6 +49,8 @@ # Fake varying scaling VARY_PAR = pjoin(DATA_PATH, 'phantom_varscale.PAR') VARY_REC = pjoin(DATA_PATH, 'phantom_varscale.REC') +# V4.2 PAR with variant field names in the header +VARIANT_PAR = pjoin(DATA_PATH, 'variant_v4_2_header.par') # Affine as we determined it mid-2014 AN_OLD_AFFINE = np.array( [[-3.64994708, 0., 1.83564171, 123.66276611], @@ -829,3 +831,15 @@ def test_dualTR(): expected_TRs) # zoom on 4th dimensions is the first TR (in seconds) assert_equal(dualTR_hdr.get_zooms()[3], expected_TRs[0]/1000) + + +def test_alternative_header_field_names(): + # some V4.2 files had variant spellings for some of the fields in the + # header. This test reads one such file and verifies that the fields with + # the alternate spelling were read. + with ImageOpener(VARIANT_PAR, 'rt') as _fobj: + HDR_INFO, HDR_DEFS = parse_PAR_header(_fobj) + assert_equal(HDR_INFO['series_type'], 'Image MRSERIES') + assert_equal(HDR_INFO['diffusion_echo_time'], 0.0) + assert_equal(HDR_INFO['repetition_time'], npa([ 21225.76])) + assert_equal(HDR_INFO['patient_position'], 'HFS') From ff49a066181ccc6639f8fa490a2af9e73eb722ef Mon Sep 17 00:00:00 2001 From: "Gregory R. Lee" Date: Thu, 26 Jan 2017 01:29:43 -0500 Subject: [PATCH 2/3] fix bad parrec test file --- nibabel/tests/data/variant_v4_2_header.par | 33 ++++++++++++++++++++-- nibabel/tests/test_parrec.py | 2 +- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/nibabel/tests/data/variant_v4_2_header.par b/nibabel/tests/data/variant_v4_2_header.par index fde0dbe70b..277aea358b 100644 --- a/nibabel/tests/data/variant_v4_2_header.par +++ b/nibabel/tests/data/variant_v4_2_header.par @@ -5,7 +5,7 @@ # # Dataset name: E:\\Export\phantom_EPI_asc_CLEAR_2_1 # -# CLINICAL TRYOUT Research image export tool V4.1 +# CLINICAL TRYOUT Research image export tool V4.2 # # === GENERAL INFORMATION ======================================================== # @@ -92,10 +92,37 @@ # contrast type (string) # diffusion anisotropy type (string) # diffusion (ap, fh, rl) (3*float) +# label type (ASL) (imagekey!) (integer) # # === 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 +# 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 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 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 + 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 1 1 8 0 0.000 0.000 0.000 1 # === END OF DATA DESCRIPTION FILE =============================================== diff --git a/nibabel/tests/test_parrec.py b/nibabel/tests/test_parrec.py index 572f3a6ec4..27912fe17f 100644 --- a/nibabel/tests/test_parrec.py +++ b/nibabel/tests/test_parrec.py @@ -50,7 +50,7 @@ VARY_PAR = pjoin(DATA_PATH, 'phantom_varscale.PAR') VARY_REC = pjoin(DATA_PATH, 'phantom_varscale.REC') # V4.2 PAR with variant field names in the header -VARIANT_PAR = pjoin(DATA_PATH, 'variant_v4_2_header.par') +VARIANT_PAR = pjoin(DATA_PATH, 'variant_v4_2_header.PAR') # Affine as we determined it mid-2014 AN_OLD_AFFINE = np.array( [[-3.64994708, 0., 1.83564171, 123.66276611], From 47a8d6af0167d138e6fa7afa021b26c45165317c Mon Sep 17 00:00:00 2001 From: "Gregory R. Lee" Date: Thu, 26 Jan 2017 01:48:59 -0500 Subject: [PATCH 3/3] case of extension changed --- .../data/{variant_v4_2_header.par => variant_v4_2_header.PAR} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename nibabel/tests/data/{variant_v4_2_header.par => variant_v4_2_header.PAR} (100%) diff --git a/nibabel/tests/data/variant_v4_2_header.par b/nibabel/tests/data/variant_v4_2_header.PAR similarity index 100% rename from nibabel/tests/data/variant_v4_2_header.par rename to nibabel/tests/data/variant_v4_2_header.PAR