|
15 | 15 | from nibabel.affines import from_matvec
|
16 | 16 | from scipy.io import loadmat
|
17 | 17 | from nitransforms.linear import Affine
|
18 |
| -from ..io import ( |
| 18 | +from nitransforms.io import ( |
19 | 19 | afni,
|
20 | 20 | fsl,
|
21 | 21 | lta as fs,
|
22 | 22 | itk,
|
23 | 23 | )
|
24 |
| -from ..io.lta import ( |
| 24 | +from nitransforms.io.lta import ( |
25 | 25 | VolumeGeometry as VG,
|
26 | 26 | FSLinearTransform as LT,
|
27 | 27 | FSLinearTransformArray as LTA,
|
28 | 28 | )
|
29 |
| -from ..io.base import LinearParameters, TransformIOError, TransformFileError |
| 29 | +from nitransforms.io.base import LinearParameters, TransformIOError, TransformFileError |
| 30 | +from nitransforms.conftest import _datadir, _testdir |
30 | 31 |
|
31 | 32 | LPS = np.diag([-1, -1, 1, 1])
|
32 | 33 | ITK_MAT = LPS.dot(np.ones((4, 4)).dot(LPS))
|
@@ -410,33 +411,35 @@ def test_afni_Displacements():
|
410 | 411 | afni.AFNIDisplacementsField.from_image(field)
|
411 | 412 |
|
412 | 413 |
|
413 |
| -def test_itk_h5(tmpdir, testdata_path): |
| 414 | +@pytest.mark.parametrize("only_linear", [True, False]) |
| 415 | +@pytest.mark.parametrize("h5_path,nxforms", [ |
| 416 | + (_datadir / "affine-antsComposite.h5", 1), |
| 417 | + (_testdir / "ds-005_sub-01_from-T1w_to-MNI152NLin2009cAsym_mode-image_xfm.h5", 2), |
| 418 | +]) |
| 419 | +def test_itk_h5(tmpdir, only_linear, h5_path, nxforms): |
414 | 420 | """Test displacements fields."""
|
415 | 421 | assert (
|
416 | 422 | len(
|
417 | 423 | list(
|
418 | 424 | itk.ITKCompositeH5.from_filename(
|
419 |
| - testdata_path |
420 |
| - / "ds-005_sub-01_from-T1w_to-MNI152NLin2009cAsym_mode-image_xfm.h5" |
| 425 | + h5_path, |
| 426 | + only_linear=only_linear, |
421 | 427 | )
|
422 | 428 | )
|
423 | 429 | )
|
424 |
| - == 2 |
| 430 | + == nxforms if not only_linear else 1 |
425 | 431 | )
|
426 | 432 |
|
427 | 433 | with pytest.raises(TransformFileError):
|
428 | 434 | list(
|
429 | 435 | itk.ITKCompositeH5.from_filename(
|
430 |
| - testdata_path |
431 |
| - / "ds-005_sub-01_from-T1w_to-MNI152NLin2009cAsym_mode-image_xfm.x5" |
| 436 | + h5_path.absolute().name.replace(".h5", ".x5"), |
| 437 | + only_linear=only_linear, |
432 | 438 | )
|
433 | 439 | )
|
434 | 440 |
|
435 | 441 | tmpdir.chdir()
|
436 |
| - shutil.copy( |
437 |
| - testdata_path / "ds-005_sub-01_from-T1w_to-MNI152NLin2009cAsym_mode-image_xfm.h5", |
438 |
| - "test.h5", |
439 |
| - ) |
| 442 | + shutil.copy(h5_path, "test.h5") |
440 | 443 | os.chmod("test.h5", 0o666)
|
441 | 444 |
|
442 | 445 | with H5File("test.h5", "r+") as h5file:
|
@@ -584,3 +587,72 @@ def _generate_reoriented(path, directions, swapaxes, parameters):
|
584 | 587 | hdr.set_qform(newaff, code=1)
|
585 | 588 | hdr.set_sform(newaff, code=1)
|
586 | 589 | return img.__class__(data, newaff, hdr), R
|
| 590 | + |
| 591 | + |
| 592 | +def test_itk_linear_h5(tmpdir, data_path, testdata_path): |
| 593 | + """Check different lower-level loading options.""" |
| 594 | + |
| 595 | + # File loadable with transform array |
| 596 | + h5xfm = itk.ITKLinearTransformArray.from_filename( |
| 597 | + data_path / "affine-antsComposite.h5" |
| 598 | + ) |
| 599 | + assert len(h5xfm.xforms) == 1 |
| 600 | + |
| 601 | + h5xfm = itk.ITKLinearTransformArray.from_fileobj( |
| 602 | + (data_path / "affine-antsComposite.h5").open() |
| 603 | + ) |
| 604 | + assert len(h5xfm.xforms) == 1 |
| 605 | + |
| 606 | + # File loadable with single affine object |
| 607 | + itk.ITKLinearTransform.from_filename( |
| 608 | + data_path / "affine-antsComposite.h5" |
| 609 | + ) |
| 610 | + |
| 611 | + itk.ITKLinearTransform.from_fileobj( |
| 612 | + (data_path / "affine-antsComposite.h5").open() |
| 613 | + ) |
| 614 | + |
| 615 | + # Exercise only_linear |
| 616 | + itk.ITKCompositeH5.from_filename( |
| 617 | + testdata_path / "ds-005_sub-01_from-T1w_to-MNI152NLin2009cAsym_mode-image_xfm.h5", |
| 618 | + only_linear=True, |
| 619 | + ) |
| 620 | + |
| 621 | + tmpdir.chdir() |
| 622 | + shutil.copy(data_path / "affine-antsComposite.h5", "test.h5") |
| 623 | + os.chmod("test.h5", 0o666) |
| 624 | + |
| 625 | + with H5File("test.h5", "r+") as h5file: |
| 626 | + h5group = h5file["TransformGroup"] |
| 627 | + xfm = h5group.create_group("2") |
| 628 | + xfm["TransformType"] = (b"AffineTransform", b"") |
| 629 | + xfm["TransformParameters"] = np.zeros(12, dtype=float) |
| 630 | + xfm["TransformFixedParameters"] = np.zeros(3, dtype=float) |
| 631 | + |
| 632 | + # File loadable with transform array |
| 633 | + h5xfm = itk.ITKLinearTransformArray.from_filename("test.h5") |
| 634 | + assert len(h5xfm.xforms) == 2 |
| 635 | + |
| 636 | + # File loadable with generalistic object (NOTE we directly access the list) |
| 637 | + h5xfm = itk.ITKCompositeH5.from_filename("test.h5") |
| 638 | + assert len(h5xfm) == 2 |
| 639 | + |
| 640 | + # Error raised if the we try to use the single affine loader |
| 641 | + with pytest.raises(TransformIOError): |
| 642 | + itk.ITKLinearTransform.from_filename("test.h5") |
| 643 | + |
| 644 | + shutil.copy(data_path / "affine-antsComposite.h5", "test.h5") |
| 645 | + os.chmod("test.h5", 0o666) |
| 646 | + |
| 647 | + # Generate an empty h5 file |
| 648 | + with H5File("test.h5", "r+") as h5file: |
| 649 | + h5group = h5file["TransformGroup"] |
| 650 | + del h5group["1"] |
| 651 | + |
| 652 | + # File loadable with generalistic object |
| 653 | + h5xfm = itk.ITKCompositeH5.from_filename("test.h5") |
| 654 | + assert len(h5xfm) == 0 |
| 655 | + |
| 656 | + # Error raised if the we try to use the single affine loader |
| 657 | + with pytest.raises(TransformIOError): |
| 658 | + itk.ITKLinearTransform.from_filename("test.h5") |
0 commit comments