Skip to content

Commit 0d4cdd0

Browse files
committed
RF: Remove endianness, override copy, as_byteswapped, diagnose_binaryblock
1 parent fede660 commit 0d4cdd0

File tree

2 files changed

+63
-23
lines changed

2 files changed

+63
-23
lines changed

nibabel/freesurfer/mghformat.py

+37-5
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ class MGHHeader(LabeledWrapStruct):
9292

9393
def __init__(self,
9494
binaryblock=None,
95-
endianness='>',
9695
check=True):
9796
''' Initialize header from binary data block
9897
@@ -105,9 +104,6 @@ def __init__(self,
105104
Whether to check content of header in initialization.
106105
Default is True.
107106
'''
108-
if endianness != '>':
109-
raise ValueError("MGHHeader is big-endian")
110-
111107
min_size = self._hdrdtype.itemsize
112108
full_size = self.template_dtype.itemsize
113109
if binaryblock is not None and len(binaryblock) >= min_size:
@@ -117,7 +113,7 @@ def __init__(self,
117113
binaryblock = (binaryblock[:full_size] +
118114
b'\x00' * (full_size - len(binaryblock)))
119115
super(MGHHeader, self).__init__(binaryblock=binaryblock,
120-
endianness=endianness,
116+
endianness='big',
121117
check=False)
122118
if not self._structarr['goodRASFlag']:
123119
self._set_affine_default()
@@ -408,6 +404,42 @@ def writeftr_to(self, fileobj):
408404
fileobj.seek(self.get_footer_offset())
409405
fileobj.write(ftr_nd.tostring())
410406

407+
def copy(self):
408+
''' Return copy of structure '''
409+
return self.__class__(self.binaryblock, check=False)
410+
411+
def as_byteswapped(self, endianness=None):
412+
''' Return new object with given ``endianness``
413+
414+
If big endian, returns a copy of the object. Otherwise raises ValueError.
415+
416+
Parameters
417+
----------
418+
endianness : None or string, optional
419+
endian code to which to swap. None means swap from current
420+
endianness, and is the default
421+
422+
Returns
423+
-------
424+
wstr : ``MGHHeader``
425+
``MGHHeader`` object
426+
427+
'''
428+
if endianness is None or endian_codes[endianness] != '>':
429+
raise ValueError('Cannot byteswap MGHHeader - '
430+
'must always be big endian')
431+
return self.copy()
432+
433+
@classmethod
434+
def diagnose_binaryblock(klass, binaryblock, endianness=None):
435+
if endianness is not None and endian_codes[endianness] != '>':
436+
raise ValueError('MGHHeader must always be big endian')
437+
wstr = klass(binaryblock, check=False)
438+
battrun = BatteryRunner(klass._get_checks())
439+
reports = battrun.check_only(wstr)
440+
return '\n'.join([report.message
441+
for report in reports if report.message])
442+
411443
class _HeaderData:
412444
""" Provide interface to deprecated MGHHeader fields"""
413445
def __init__(self, structarr):

nibabel/freesurfer/tests/test_mghformat.py

+26-18
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@
4141
[0.0, -1.0, 0.0, 2.0],
4242
[0.0, 0.0, 0.0, 1.0]], dtype=np.float32)
4343

44+
BIG_CODES = ('>', 'big', 'BIG', 'b', 'be', 'B', 'BE')
45+
LITTLE_CODES = ('<', 'little', 'l', 'le', 'L', 'LE')
46+
47+
if sys_is_le:
48+
BIG_CODES += ('swapped', 's', 'S', '!')
49+
LITTLE_CODES += ('native', 'n', 'N', '=', '|', 'i', 'I')
50+
else:
51+
BIG_CODES += ('native', 'n', 'N', '=', '|', 'i', 'I')
52+
LITTLE_CODES += ('swapped', 's', 'S', '!')
53+
54+
4455

4556
def test_read_mgh():
4657
# test.mgz was generated by the following command
@@ -258,12 +269,6 @@ def test_mgh_load_fileobj():
258269
assert_array_equal(img.get_data(), img2.get_data())
259270

260271

261-
def test_mgh_reject_little_endian():
262-
bblock = b'\x00' * MGHHeader.template_dtype.itemsize
263-
with assert_raises(ValueError):
264-
MGHHeader(bblock, endianness='<')
265-
266-
267272
def test_mgh_affine_default():
268273
hdr = MGHHeader()
269274
hdr['goodRASFlag'] = 0
@@ -303,26 +308,29 @@ def test_mghheader_default_structarr():
303308
assert_equal(hdr['ti'], 0)
304309
assert_equal(hdr['fov'], 0)
305310

306-
big_codes = ('>', 'big', 'BIG', 'b', 'be', 'B', 'BE')
307-
little_codes = ('<', 'little', 'l', 'le', 'L', 'LE')
308-
309-
if sys_is_le:
310-
big_codes += ('swapped', 's', 'S', '!')
311-
little_codes += ('native', 'n', 'N', '=', '|', 'i', 'I')
312-
else:
313-
big_codes += ('native', 'n', 'N', '=', '|', 'i', 'I')
314-
little_codes += ('swapped', 's', 'S', '!')
315-
316-
for endianness in big_codes:
311+
for endianness in (None,) + BIG_CODES:
317312
hdr2 = MGHHeader.default_structarr(endianness=endianness)
318313
assert_equal(hdr2, hdr)
319314
assert_equal(hdr2.newbyteorder('>'), hdr)
320315

321-
for endianness in little_codes:
316+
for endianness in LITTLE_CODES:
322317
with assert_raises(ValueError):
323318
MGHHeader.default_structarr(endianness=endianness)
324319

325320

321+
def test_byteswap():
322+
hdr = MGHHeader()
323+
324+
for endianness in BIG_CODES:
325+
hdr2 = hdr.as_byteswapped(endianness)
326+
assert_true(hdr2 is not hdr)
327+
assert_equal(hdr2, hdr)
328+
329+
for endianness in (None,) + LITTLE_CODES:
330+
with assert_raises(ValueError):
331+
hdr.as_byteswapped(endianness)
332+
333+
326334
class TestMGHImage(tsi.TestSpatialImage, tsi.MmapImageMixin):
327335
""" Apply general image tests to MGHImage
328336
"""

0 commit comments

Comments
 (0)