From 2fb312ae8d5a45f6215b679d2acdc3db9e796126 Mon Sep 17 00:00:00 2001 From: Paul McCarthy <pauldmccarthy@gmail.com> Date: Fri, 19 Jul 2019 16:10:26 +0100 Subject: [PATCH] TEST: Update transform tests --- tests/test_transform/test_fnirt.py | 6 +- tests/test_transform/test_nonlinear.py | 94 +++++++-------------- tests/test_transform/test_x5.py | 110 ++++++++----------------- 3 files changed, 68 insertions(+), 142 deletions(-) diff --git a/tests/test_transform/test_fnirt.py b/tests/test_transform/test_fnirt.py index 3288972f3..eefc68b64 100644 --- a/tests/test_transform/test_fnirt.py +++ b/tests/test_transform/test_fnirt.py @@ -39,7 +39,7 @@ def test_readFnirt(): fnirt.readFnirt(src, src, ref) assert isinstance(coef, nonlinear.CoefficientField) - assert isinstance(disp, nonlinear.DisplacementField) + assert isinstance(disp, nonlinear.DeformationField) assert coef.src.sameSpace(src) assert coef.ref.sameSpace(ref) @@ -68,7 +68,7 @@ def test_toFnirt(): spaces = it.permutations(('voxel', 'fsl', 'world'), 2) for from_, to in spaces: - field = nonlinear.convertDisplacementSpace(basefield, from_, to) + field = nonlinear.convertDeformationSpace(basefield, from_, to) got = fnirt.toFnirt(field) check(got, basefield) @@ -122,6 +122,6 @@ def test_fromFnirt(): for from_, to in spaces: cnv = fnirt.fromFnirt(coef, from_, to) - exp = nonlinear.convertDisplacementSpace(disp, from_, to) + exp = nonlinear.convertDeformationSpace(disp, from_, to) tol = dict(atol=1e-5, rtol=1e-5) assert np.all(np.isclose(cnv.data, exp.data, **tol)) diff --git a/tests/test_transform/test_nonlinear.py b/tests/test_transform/test_nonlinear.py index 8b66bdac3..2da07f386 100644 --- a/tests/test_transform/test_nonlinear.py +++ b/tests/test_transform/test_nonlinear.py @@ -38,7 +38,7 @@ def _random_field(): np.random.randint(1, 100, 3), np.random.random(3) * np.pi / 2) - return nonlinear.DisplacementField(field, src=src, xform=aff) + return nonlinear.DeformationField(field, src=src, xform=aff) def _random_affine_field(): @@ -61,9 +61,9 @@ def _random_affine_field(): field = np.zeros(list(ref.shape[:3]) + [3]) field[:] = (scoords - rcoords).reshape(*it.chain(ref.shape, [3])) - field = nonlinear.DisplacementField(field, src, ref, - header=ref.header, - dispType='relative') + field = nonlinear.DeformationField(field, src, ref, + header=ref.header, + defType='relative') return field, xform @@ -78,31 +78,31 @@ def _field_coords(field): field.getAffine('voxel', 'fsl')).reshape(field.shape) -def test_detectDisplacementType(): +def test_detectDeformationType(): relfield = _random_field() coords = _field_coords(relfield) - absfield = nonlinear.DisplacementField( + absfield = nonlinear.DeformationField( relfield.data + coords, src=relfield.src, xform=relfield.voxToWorldMat) - assert nonlinear.detectDisplacementType(relfield) == 'relative' - assert nonlinear.detectDisplacementType(absfield) == 'absolute' + assert nonlinear.detectDeformationType(relfield) == 'relative' + assert nonlinear.detectDeformationType(absfield) == 'absolute' -def test_convertDisplacementType(): +def test_convertDeformationType(): relfield = _random_field() coords = _field_coords(relfield) - absfield = nonlinear.DisplacementField( + absfield = nonlinear.DeformationField( relfield.data + coords, src=relfield.src, xform=relfield.voxToWorldMat) - gotconvrel1 = nonlinear.convertDisplacementType(relfield) - gotconvabs1 = nonlinear.convertDisplacementType(absfield) - gotconvrel2 = nonlinear.convertDisplacementType(relfield, 'absolute') - gotconvabs2 = nonlinear.convertDisplacementType(absfield, 'relative') + gotconvrel1 = nonlinear.convertDeformationType(relfield) + gotconvabs1 = nonlinear.convertDeformationType(absfield) + gotconvrel2 = nonlinear.convertDeformationType(relfield, 'absolute') + gotconvabs2 = nonlinear.convertDeformationType(absfield, 'relative') tol = dict(atol=1e-5, rtol=1e-5) @@ -112,7 +112,7 @@ def test_convertDisplacementType(): assert np.all(np.isclose(gotconvabs2, relfield.data, **tol)) -def test_convertDisplacementSpace(): +def test_convertDeformationSpace(): basefield, xform = _random_affine_field() src = basefield.src @@ -137,7 +137,7 @@ def test_convertDisplacementSpace(): refcoords = affine.transform(refcoords, ref.voxToScaledVoxMat) srccoords = basefield.transform(refcoords) - field = nonlinear.convertDisplacementSpace(basefield, from_, to) + field = nonlinear.convertDeformationSpace(basefield, from_, to) premat = ref.getAffine('fsl', from_) postmat = src.getAffine('fsl', to) @@ -152,7 +152,7 @@ def test_convertDisplacementSpace(): assert np.all(np.isclose(expect[~enan], got[~gnan])) -def test_DisplacementField_transform(): +def test_DeformationField_transform(): relfield, xform = _random_affine_field() src = relfield.src @@ -168,9 +168,9 @@ def test_DisplacementField_transform(): absfield = np.zeros(list(ref.shape[:3]) + [3]) absfield[:] = scoords.reshape(*it.chain(ref.shape, [3])) - absfield = nonlinear.DisplacementField(absfield, src, ref, - header=ref.header, - dispType='absolute') + absfield = nonlinear.DeformationField(absfield, src, ref, + header=ref.header, + defType='absolute') got = relfield.transform(rcoords) assert np.all(np.isclose(got, scoords)) @@ -279,7 +279,7 @@ def test_CoefficientField_transform(): assert np.all(np.isclose(gotnp, srccoordsnp[srcspace], **tol)) -def test_coefficientFieldToDisplacementField(): +def test_coefficientFieldToDeformationField(): nldir = op.join(datadir, 'nonlinear') src = op.join(nldir, 'src.nii.gz') @@ -293,50 +293,20 @@ def test_coefficientFieldToDisplacementField(): cf = fnirt.readFnirt(cf, src, ref) rdf = fnirt.readFnirt(df, src, ref) rdfnp = fnirt.readFnirt(dfnp, src, ref) - adf = nonlinear.convertDisplacementType(rdf) - adfnp = nonlinear.convertDisplacementType(rdfnp) - - rcnv = nonlinear.coefficientFieldToDisplacementField(cf) - acnv = nonlinear.coefficientFieldToDisplacementField(cf, - dispType='absolute') - acnvnp = nonlinear.coefficientFieldToDisplacementField(cf, - dispType='absolute', - premat=False) - rcnvnp = nonlinear.coefficientFieldToDisplacementField(cf, - premat=False) + adf = nonlinear.convertDeformationType(rdf) + adfnp = nonlinear.convertDeformationType(rdfnp) + + rcnv = nonlinear.coefficientFieldToDeformationField(cf) + acnv = nonlinear.coefficientFieldToDeformationField(cf, + defType='absolute') + acnvnp = nonlinear.coefficientFieldToDeformationField(cf, + defType='absolute', + premat=False) + rcnvnp = nonlinear.coefficientFieldToDeformationField(cf, + premat=False) tol = dict(atol=1e-5, rtol=1e-5) assert np.all(np.isclose(rcnv.data, rdf .data, **tol)) assert np.all(np.isclose(acnv.data, adf .data, **tol)) assert np.all(np.isclose(rcnvnp.data, rdfnp.data, **tol)) assert np.all(np.isclose(acnvnp.data, adfnp.data, **tol)) - - -def test_DisplacementFIeld_srcToRefMat(): - - field1 = _random_field() - xform = affine.compose( - np.random.randint( 1, 10, 3), - np.random.randint(1, 100, 3), - np.random.random(3) * np.pi / 2) - - field2 = nonlinear.DisplacementField( - field1.data, - xform=field1.voxToWorldMat, - src=field1.src, - ref=field1.ref, - srcToRefMat=xform) - - x = np.random.randint(0, field1.shape[0], 100) - y = np.random.randint(0, field1.shape[1], 100) - z = np.random.randint(0, field1.shape[2], 100) - - coords = np.array([x, y, z]).T - coords = affine.transform( - coords, field1.ref.getAffine('voxel', 'fsl')) - - coordsf1 = field1.transform(coords) - coordsf2 = field2.transform(coords) - coordsf1 = affine.transform(coordsf1, affine.invert(xform)) - - assert np.all(np.isclose(coordsf1, coordsf2)) diff --git a/tests/test_transform/test_x5.py b/tests/test_transform/test_x5.py index ec9667203..3a92ece65 100644 --- a/tests/test_transform/test_x5.py +++ b/tests/test_transform/test_x5.py @@ -9,6 +9,8 @@ import os.path as op import numpy as np +import pytest + import h5py import fsl.data.image as fslimage @@ -27,8 +29,8 @@ def _check_metadata(group): def _check_affine(group, xform): - assert group.attrs['Type'] == 'linear' - gotxform = np.array(group['Transform']) + assert group.attrs['Type'] == 'affine' + gotxform = np.array(group['Matrix']) assert np.all(np.isclose(gotxform, xform)) @@ -39,28 +41,12 @@ def _check_space(group, img): _check_affine(group['Mapping'], img.voxToWorldMat) -def _check_nonlinear_common(group, field): - assert group.attrs['Type'] == 'nonlinear' - - if isinstance(field, nonlinear.DisplacementField): - assert group.attrs['SubType'] == 'displacement' - assert group.attrs['Representation'] == field.displacementType - - elif isinstance(field, nonlinear.CoefficientField): - assert group.attrs['SubType'] == 'coefficient' - if field.fieldType == 'cubic': - assert group.attrs['Representation'] == 'cubic bspline' - elif field.fieldType == 'quadratic': - assert group.attrs['Representation'] == 'quadratic bspline' - - _check_space(group['From'], field.src) - _check_space(group['To'], field.ref) - - pre = field.ref.getAffine('world', 'fsl') - post = field.src.getAffine('fsl', 'world') - - _check_affine(group['Pre'], pre) - _check_affine(group['Post'], post) +def _check_deformation(group, field): + assert group.attrs['Type'] == 'deformation' + assert group.attrs['SubType'] == field.deformationType + xform = np.array(group['Matrix']) + assert np.all(np.isclose(xform, field.data)) + _check_affine(group['Mapping'], field.voxToWorldMat) def test_readWriteLinearX5(): @@ -84,73 +70,43 @@ def test_readWriteLinearX5(): with h5py.File('linear.x5', 'r') as f: _check_metadata(f) - _check_affine(f['/'], xform) - _check_space( f['/From'], src) - _check_space( f['/To'], ref) + assert f.attrs['Type'] == 'linear' + _check_affine(f['/Transform'], xform) + _check_space( f['/A'], src) + _check_space( f['/B'], ref) -def test_readWriteNonLinearX5_DisplacementField(): +def test_readWriteNonLinearX5(): datadir = op.join(op.dirname(__file__), 'testdata', 'nonlinear') dffile = op.join(datadir, 'displacementfield.nii.gz') srcfile = op.join(datadir, 'src.nii.gz') reffile = op.join(datadir, 'ref.nii.gz') - src = fslimage.Image(srcfile) - ref = fslimage.Image(reffile) - - dfield = fnirt.readFnirt(dffile, src, ref) + src = fslimage.Image(srcfile) + ref = fslimage.Image(reffile) + dfield = fnirt.readFnirt(dffile, src, ref) + wdfield = nonlinear.convertDeformationSpace(dfield, 'world', 'world') with tempdir.tempdir(): - x5.writeNonLinearX5('nonlinear.x5', dfield) + + # field must be world->world + with pytest.raises(x5.X5Error): + x5.writeNonLinearX5('nonlinear.x5', dfield) + + x5.writeNonLinearX5('nonlinear.x5', wdfield) gotdfield = x5.readNonLinearX5('nonlinear.x5') assert gotdfield.src.sameSpace(src) assert gotdfield.ref.sameSpace(ref) - assert gotdfield.srcSpace == dfield.srcSpace - assert gotdfield.refSpace == dfield.refSpace - assert gotdfield.displacementType == dfield.displacementType - assert np.all(np.isclose(gotdfield.data, dfield.data)) + assert gotdfield.srcSpace == wdfield.srcSpace + assert gotdfield.refSpace == wdfield.refSpace + assert gotdfield.deformationType == wdfield.deformationType + assert np.all(np.isclose(gotdfield.data, wdfield.data)) with h5py.File('nonlinear.x5', 'r') as f: + assert f.attrs['Type'] == 'nonlinear' _check_metadata(f) - _check_nonlinear_common(f['/'], dfield) - - xform = np.array(f['/Transform']) - assert np.all(np.isclose(xform, dfield.data)) - - - -def test_readWriteNonLinearX5_CoefficientField(): - datadir = op.join(op.dirname(__file__), 'testdata', 'nonlinear') - cffile = op.join(datadir, 'coefficientfield.nii.gz') - srcfile = op.join(datadir, 'src.nii.gz') - reffile = op.join(datadir, 'ref.nii.gz') - - src = fslimage.Image(srcfile) - ref = fslimage.Image(reffile) - - cfield = fnirt.readFnirt(cffile, src, ref) - - with tempdir.tempdir(): - x5.writeNonLinearX5('nonlinear.x5', cfield) - - gotcfield = x5.readNonLinearX5('nonlinear.x5') - - assert gotcfield.src.sameSpace(src) - assert gotcfield.ref.sameSpace(ref) - assert gotcfield.srcSpace == cfield.srcSpace - assert gotcfield.refSpace == cfield.refSpace - assert gotcfield.knotSpacing == cfield.knotSpacing - - assert np.all(np.isclose(gotcfield.fieldToRefMat, cfield.fieldToRefMat)) - assert np.all(np.isclose(gotcfield.srcToRefMat, cfield.srcToRefMat)) - assert np.all(np.isclose(gotcfield.data, cfield.data)) - - with h5py.File('nonlinear.x5', 'r') as f: - _check_metadata(f) - _check_nonlinear_common(f['/'], cfield) - - _check_affine(f['/InitialAlignment'], cfield.srcToRefMat) - _check_affine(f['/Parameters/ReferenceToField'], cfield.refToFieldMat) - assert np.all(np.isclose(f['/Parameters'].attrs['Spacing'], cfield.knotSpacing)) + _check_deformation(f['/Transform'], wdfield) + _check_space( f['/A'], ref) + _check_space( f['/B'], src) -- GitLab