Skip to content

Commit a5b67b4

Browse files
committed
Merge pull request #279 from matthew-brett/parrec-as-uint
MRG: PAR / REC data are unsigned 8 or 16 bit integers Consensus seems to be that REC data is in uint format - see #275 Raise error for data width other than 8 or 16 bit because we haven't any examples to know what these are.
2 parents 20ff9e5 + 0378272 commit a5b67b4

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

nibabel/parrec.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,17 @@
7474
different order.
7575
7676
We call the PAR file's axis system "PSL" (Posterior, Superior, Left)
77+
78+
#########
79+
Data type
80+
#########
81+
82+
It seems that everyone agrees that Philips stores REC data in little-endian
83+
format - see https://github.com/nipy/nibabel/issues/274
84+
85+
Philips XML header files, and some previous experience, suggest that the REC
86+
data is always stored as 8 or 16 bit unsigned integers - see
87+
https://github.com/nipy/nibabel/issues/275
7788
"""
7889
from __future__ import print_function, division
7990

@@ -556,8 +567,12 @@ def __init__(self, info, image_defs, permit_truncated=False):
556567
# functionality
557568
# dtype
558569
bitpix = self._get_unique_image_prop('image pixel size')
559-
# REC data always little endian?
560-
dt = np.dtype('int' + str(bitpix)).newbyteorder('<')
570+
if bitpix not in (8, 16):
571+
raise PARRECError('Only 8- and 16-bit data supported (not %s)'
572+
'please report this to the nibabel developers'
573+
% bitpix)
574+
# REC data always little endian
575+
dt = np.dtype('uint' + str(bitpix)).newbyteorder('<')
561576
Header.__init__(self,
562577
data_dtype=dt,
563578
shape=self._calc_data_shape(),

nibabel/tests/test_parrec.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@
124124
dict(
125125
fname = EG_PAR,
126126
shape = (64, 64, 9, 3),
127-
dtype = np.int16,
127+
dtype = np.uint16,
128128
# We disagree with Philips about the right affine, for the moment, so
129129
# use our own affine as determined from a previous load in nibabel
130130
affine = AN_OLD_AFFINE,
@@ -146,7 +146,7 @@ def test_top_level_load():
146146
def test_header():
147147
hdr = PARRECHeader(HDR_INFO, HDR_DEFS)
148148
assert_equal(hdr.get_data_shape(), (64, 64, 9, 3))
149-
assert_equal(hdr.get_data_dtype(), np.dtype('<i2'))
149+
assert_equal(hdr.get_data_dtype(), np.dtype('<u2'))
150150
assert_equal(hdr.get_zooms(), (3.75, 3.75, 8.0, 2.0))
151151
assert_equal(hdr.get_data_offset(), 0)
152152
si = np.array([np.unique(x) for x in hdr.get_data_scaling()]).ravel()
@@ -534,3 +534,11 @@ class TestPARRECImage(tsi.MmapImageMixin):
534534

535535
def write_image(self):
536536
return parrec.load(EG_PAR), EG_PAR
537+
538+
539+
def test_bitpix():
540+
# Check errors for other than 8, 16 bit
541+
hdr_defs = HDR_DEFS.copy()
542+
for pix_size in (24, 32):
543+
hdr_defs['image pixel size'] = pix_size
544+
assert_raises(PARRECError, PARRECHeader, HDR_INFO, hdr_defs)

nibabel/tests/test_scripts.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def test_parrec2nii():
9595
run_command(['parrec2nii', in_fname])
9696
img = load(out_froot)
9797
assert_equal(img.shape, (64, 64, 9, 3))
98-
assert_equal(img.get_data_dtype(), np.dtype(np.int16))
98+
assert_equal(img.get_data_dtype(), np.dtype(np.uint16))
9999
# Check against values from Philips converted nifti image
100100
data = img.get_data()
101101
assert_true(np.allclose(

0 commit comments

Comments
 (0)