Skip to content

Commit 664f11c

Browse files
committed
TEST: TestWrapStruct features, set_zooms, deprecated fields
1 parent 93f3c70 commit 664f11c

File tree

1 file changed

+136
-8
lines changed

1 file changed

+136
-8
lines changed

nibabel/freesurfer/tests/test_mghformat.py

+136-8
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,21 @@
1818
from ..mghformat import MGHHeader, MGHError, MGHImage
1919
from ...tmpdirs import InTemporaryDirectory
2020
from ...fileholders import FileHolder
21+
from ...spatialimages import HeaderDataError
2122
from ...volumeutils import sys_is_le
23+
from ...wrapstruct import WrapStructError
2224

2325
from nose.tools import assert_true, assert_false
2426

2527
from numpy.testing import (assert_equal, assert_array_equal,
2628
assert_array_almost_equal, assert_almost_equal,
2729
assert_raises)
30+
from ...testing import assert_not_equal
2831

2932
from ...testing import data_path
3033

3134
from ...tests import test_spatialimages as tsi
35+
from ...tests.test_wrapstruct import _TestWrapStructBase
3236

3337
MGZ_FNAME = os.path.join(data_path, 'test.mgz')
3438

@@ -141,6 +145,21 @@ def test_write_noaffine_mgh():
141145
assert_array_almost_equal(h['Pxyz_c'], [0, 0, 0])
142146

143147

148+
def test_set_zooms():
149+
mgz = load(MGZ_FNAME)
150+
h = mgz.header
151+
assert_array_almost_equal(h.get_zooms(), [1, 1, 1, 2])
152+
h.set_zooms([1, 1, 1, 3])
153+
assert_array_almost_equal(h.get_zooms(), [1, 1, 1, 3])
154+
for zooms in ((-1, 1, 1, 1),
155+
(1, -1, 1, 1),
156+
(1, 1, -1, 1),
157+
(1, 1, 1, -1),
158+
(1, 1, 1, 1, 5)):
159+
with assert_raises(HeaderDataError):
160+
h.set_zooms(zooms)
161+
162+
144163
def bad_dtype_mgh():
145164
''' This function raises an MGHError exception because
146165
uint16 is not a valid MGH datatype.
@@ -318,17 +337,25 @@ def test_mghheader_default_structarr():
318337
MGHHeader.default_structarr(endianness=endianness)
319338

320339

321-
def test_byteswap():
340+
def test_deprecated_fields():
322341
hdr = MGHHeader()
323342

324-
for endianness in BIG_CODES:
325-
hdr2 = hdr.as_byteswapped(endianness)
326-
assert_true(hdr2 is not hdr)
327-
assert_equal(hdr2, hdr)
343+
# mrparams is the only deprecated field at the moment
344+
assert_array_equal(hdr['mrparams'], 0)
328345

329-
for endianness in (None,) + LITTLE_CODES:
330-
with assert_raises(ValueError):
331-
hdr.as_byteswapped(endianness)
346+
hdr['mrparams'] = [1, 2, 3, 4]
347+
assert_array_almost_equal(hdr['mrparams'], [1, 2, 3, 4])
348+
assert_equal(hdr['tr'], 1)
349+
assert_equal(hdr['flip_angle'], 2)
350+
assert_equal(hdr['te'], 3)
351+
assert_equal(hdr['ti'], 4)
352+
assert_equal(hdr['fov'], 0)
353+
354+
hdr['tr'] = 5
355+
hdr['flip_angle'] = 6
356+
hdr['te'] = 7
357+
hdr['ti'] = 8
358+
assert_array_almost_equal(hdr['mrparams'], [5, 6, 7, 8])
332359

333360

334361
class TestMGHImage(tsi.TestSpatialImage, tsi.MmapImageMixin):
@@ -342,3 +369,104 @@ def check_dtypes(self, expected, actual):
342369
# others may only require the same type
343370
# MGH requires the actual to be a big endian version of expected
344371
assert_equal(expected.newbyteorder('>'), actual)
372+
373+
374+
class TestMGHHeader(_TestWrapStructBase):
375+
header_class = MGHHeader
376+
377+
def test_general_init(self):
378+
hdr = self.header_class()
379+
# binaryblock has length given by header data dtype
380+
binblock = hdr.binaryblock
381+
assert_equal(len(binblock), hdr.structarr.dtype.itemsize)
382+
# Endianness will always be big, and cannot be set
383+
assert_equal(hdr.endianness, '>')
384+
# You can also pass in a check flag, without data this has no
385+
# effect
386+
hdr = self.header_class(check=False)
387+
388+
def _set_something_into_hdr(self, hdr):
389+
hdr['dims'] = [4, 3, 2, 1]
390+
391+
# Update tests to account for big-endian requirement
392+
def test__eq__(self):
393+
# Test equal and not equal
394+
hdr1 = self.header_class()
395+
hdr2 = self.header_class()
396+
assert_equal(hdr1, hdr2)
397+
self._set_something_into_hdr(hdr1)
398+
assert_not_equal(hdr1, hdr2)
399+
self._set_something_into_hdr(hdr2)
400+
assert_equal(hdr1, hdr2)
401+
# REMOVED as_byteswapped() test
402+
# Check comparing to funny thing says no
403+
assert_not_equal(hdr1, None)
404+
assert_not_equal(hdr1, 1)
405+
406+
def test_to_from_fileobj(self):
407+
# Successful write using write_to
408+
hdr = self.header_class()
409+
str_io = io.BytesIO()
410+
hdr.write_to(str_io)
411+
str_io.seek(0)
412+
hdr2 = self.header_class.from_fileobj(str_io)
413+
assert_equal(hdr2.endianness, '>')
414+
assert_equal(hdr2.binaryblock, hdr.binaryblock)
415+
416+
def test_endian_guess(self):
417+
# Check guesses of endian
418+
eh = self.header_class()
419+
assert_equal(eh.endianness, '>')
420+
assert_equal(self.header_class.guessed_endian(eh), '>')
421+
422+
def test_bytes(self):
423+
# Test get of bytes
424+
hdr1 = self.header_class()
425+
bb = hdr1.binaryblock
426+
hdr2 = self.header_class(hdr1.binaryblock)
427+
assert_equal(hdr1, hdr2)
428+
assert_equal(hdr1.binaryblock, hdr2.binaryblock)
429+
# Do a set into the header, and try again. The specifics of 'setting
430+
# something' will depend on the nature of the bytes object
431+
self._set_something_into_hdr(hdr1)
432+
hdr2 = self.header_class(hdr1.binaryblock)
433+
assert_equal(hdr1, hdr2)
434+
assert_equal(hdr1.binaryblock, hdr2.binaryblock)
435+
# Short binaryblocks give errors (here set through init)
436+
# Long binaryblocks are truncated
437+
assert_raises(WrapStructError,
438+
self.header_class,
439+
bb[:self.header_class._hdrdtype.itemsize - 1])
440+
# Checking set to true by default, and prevents nonsense being
441+
# set into the header.
442+
bb_bad = self.get_bad_bb()
443+
if bb_bad is None:
444+
return
445+
with imageglobals.LoggingOutputSuppressor():
446+
assert_raises(HeaderDataError, self.header_class, bb_bad)
447+
# now slips past without check
448+
_ = self.header_class(bb_bad, check=False)
449+
450+
def test_as_byteswapped(self):
451+
# Check byte swapping
452+
hdr = self.header_class()
453+
assert_equal(hdr.endianness, '>')
454+
# same code just returns a copy
455+
for endianness in BIG_CODES:
456+
hdr2 = hdr.as_byteswapped(endianness)
457+
assert_false(hdr2 is hdr)
458+
assert_equal(hdr2, hdr)
459+
460+
# Different code raises error
461+
for endianness in (None,) + LITTLE_CODES:
462+
with assert_raises(ValueError):
463+
hdr.as_byteswapped(endianness)
464+
# Note that contents is not rechecked on swap / copy
465+
class DC(self.header_class):
466+
def check_fix(self, *args, **kwargs):
467+
raise Exception
468+
469+
# Assumes check=True default
470+
assert_raises(Exception, DC, hdr.binaryblock)
471+
hdr = DC(hdr.binaryblock, check=False)
472+
hdr2 = hdr.as_byteswapped('>')

0 commit comments

Comments
 (0)