18
18
from ..mghformat import MGHHeader , MGHError , MGHImage
19
19
from ...tmpdirs import InTemporaryDirectory
20
20
from ...fileholders import FileHolder
21
+ from ...spatialimages import HeaderDataError
21
22
from ...volumeutils import sys_is_le
23
+ from ...wrapstruct import WrapStructError
22
24
23
25
from nose .tools import assert_true , assert_false
24
26
25
27
from numpy .testing import (assert_equal , assert_array_equal ,
26
28
assert_array_almost_equal , assert_almost_equal ,
27
29
assert_raises )
30
+ from ...testing import assert_not_equal
28
31
29
32
from ...testing import data_path
30
33
31
34
from ...tests import test_spatialimages as tsi
35
+ from ...tests .test_wrapstruct import _TestWrapStructBase
32
36
33
37
MGZ_FNAME = os .path .join (data_path , 'test.mgz' )
34
38
@@ -141,6 +145,21 @@ def test_write_noaffine_mgh():
141
145
assert_array_almost_equal (h ['Pxyz_c' ], [0 , 0 , 0 ])
142
146
143
147
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
+
144
163
def bad_dtype_mgh ():
145
164
''' This function raises an MGHError exception because
146
165
uint16 is not a valid MGH datatype.
@@ -318,17 +337,25 @@ def test_mghheader_default_structarr():
318
337
MGHHeader .default_structarr (endianness = endianness )
319
338
320
339
321
- def test_byteswap ():
340
+ def test_deprecated_fields ():
322
341
hdr = MGHHeader ()
323
342
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 )
328
345
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 ])
332
359
333
360
334
361
class TestMGHImage (tsi .TestSpatialImage , tsi .MmapImageMixin ):
@@ -342,3 +369,104 @@ def check_dtypes(self, expected, actual):
342
369
# others may only require the same type
343
370
# MGH requires the actual to be a big endian version of expected
344
371
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