|
38 | 38 |
|
39 | 39 | from .. import (AnalyzeImage, Spm99AnalyzeImage, Spm2AnalyzeImage, |
40 | 40 | Nifti1Pair, Nifti1Image, Nifti2Pair, Nifti2Image, |
| 41 | + GiftiImage, |
41 | 42 | MGHImage, Minc1Image, Minc2Image, is_proxy) |
42 | 43 | from ..spatialimages import SpatialImage |
43 | 44 | from .. import minc1, minc2, parrec, brikhead |
@@ -493,6 +494,67 @@ def validate_affine_deprecated(self, imaker, params): |
493 | 494 | assert_true(aff is img.get_affine()) |
494 | 495 |
|
495 | 496 |
|
| 497 | +class SerializeMixin(object): |
| 498 | + def validate_to_bytes(self, imaker, params): |
| 499 | + img = imaker() |
| 500 | + serialized = img.to_bytes() |
| 501 | + with InTemporaryDirectory(): |
| 502 | + fname = 'img' + self.standard_extension |
| 503 | + img.to_filename(fname) |
| 504 | + with open(fname, 'rb') as fobj: |
| 505 | + file_contents = fobj.read() |
| 506 | + assert serialized == file_contents |
| 507 | + |
| 508 | + def validate_from_bytes(self, imaker, params): |
| 509 | + img = imaker() |
| 510 | + klass = getattr(self, 'klass', img.__class__) |
| 511 | + with InTemporaryDirectory(): |
| 512 | + fname = 'img' + self.standard_extension |
| 513 | + img.to_filename(fname) |
| 514 | + |
| 515 | + all_images = list(getattr(self, 'example_images', [])) + [{'fname': fname}] |
| 516 | + for img_params in all_images: |
| 517 | + img_a = klass.from_filename(img_params['fname']) |
| 518 | + with open(img_params['fname'], 'rb') as fobj: |
| 519 | + img_b = klass.from_bytes(fobj.read()) |
| 520 | + |
| 521 | + assert self._header_eq(img_a.header, img_b.header) |
| 522 | + assert np.array_equal(img_a.get_data(), img_b.get_data()) |
| 523 | + del img_a |
| 524 | + del img_b |
| 525 | + |
| 526 | + def validate_to_from_bytes(self, imaker, params): |
| 527 | + img = imaker() |
| 528 | + klass = getattr(self, 'klass', img.__class__) |
| 529 | + with InTemporaryDirectory(): |
| 530 | + fname = 'img' + self.standard_extension |
| 531 | + img.to_filename(fname) |
| 532 | + |
| 533 | + all_images = list(getattr(self, 'example_images', [])) + [{'fname': fname}] |
| 534 | + for img_params in all_images: |
| 535 | + img_a = klass.from_filename(img_params['fname']) |
| 536 | + bytes_a = img_a.to_bytes() |
| 537 | + |
| 538 | + img_b = klass.from_bytes(bytes_a) |
| 539 | + |
| 540 | + assert img_b.to_bytes() == bytes_a |
| 541 | + assert self._header_eq(img_a.header, img_b.header) |
| 542 | + assert np.array_equal(img_a.get_data(), img_b.get_data()) |
| 543 | + del img_a |
| 544 | + del img_b |
| 545 | + |
| 546 | + @staticmethod |
| 547 | + def _header_eq(header_a, header_b): |
| 548 | + """ Header equality check that can be overridden by a subclass of this test |
| 549 | +
|
| 550 | + This allows us to retain the same tests above when testing an image that uses an |
| 551 | + abstract class as a header, namely when testing the FileBasedImage API, which |
| 552 | + raises a NotImplementedError for __eq__ |
| 553 | + """ |
| 554 | + return header_a == header_b |
| 555 | + |
| 556 | + |
| 557 | + |
496 | 558 | class LoadImageAPI(GenericImageAPI, |
497 | 559 | DataInterfaceMixin, |
498 | 560 | AffineMixin, |
@@ -613,7 +675,7 @@ class TestNifti1PairAPI(TestSpm99AnalyzeAPI): |
613 | 675 | can_save = True |
614 | 676 |
|
615 | 677 |
|
616 | | -class TestNifti1API(TestNifti1PairAPI): |
| 678 | +class TestNifti1API(TestNifti1PairAPI, SerializeMixin): |
617 | 679 | klass = image_maker = Nifti1Image |
618 | 680 | standard_extension = '.nii' |
619 | 681 |
|
@@ -660,14 +722,20 @@ def loader(self, fname): |
660 | 722 | # standard_extension = '.v' |
661 | 723 |
|
662 | 724 |
|
663 | | -class TestMGHAPI(ImageHeaderAPI): |
| 725 | +class TestMGHAPI(ImageHeaderAPI, SerializeMixin): |
664 | 726 | klass = image_maker = MGHImage |
665 | 727 | example_shapes = ((2, 3, 4), (2, 3, 4, 5)) # MGH can only do >= 3D |
666 | 728 | has_scaling = True |
667 | 729 | can_save = True |
668 | 730 | standard_extension = '.mgh' |
669 | 731 |
|
670 | 732 |
|
| 733 | +class TestGiftiAPI(LoadImageAPI, SerializeMixin): |
| 734 | + klass = image_maker = GiftiImage |
| 735 | + can_save = True |
| 736 | + standard_extension = '.gii' |
| 737 | + |
| 738 | + |
671 | 739 | class TestAFNIAPI(LoadImageAPI): |
672 | 740 | loader = brikhead.load |
673 | 741 | klass = image_maker = brikhead.AFNIImage |
|
0 commit comments