From 3be2b416a4072cdb5ff10c467702d85bd142de5b Mon Sep 17 00:00:00 2001 From: Paul McCarthy <pauldmccarthy@gmail.com> Date: Mon, 8 Jul 2019 15:04:46 +0100 Subject: [PATCH] TEST: More flirt.py unit tests, tests for fnirt.py --- tests/test_transform/test_flirt.py | 67 ++++++++++++--- tests/test_transform/test_fnirt.py | 128 +++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+), 10 deletions(-) create mode 100644 tests/test_transform/test_fnirt.py diff --git a/tests/test_transform/test_flirt.py b/tests/test_transform/test_flirt.py index c301fc75c..d2dd68e29 100644 --- a/tests/test_transform/test_flirt.py +++ b/tests/test_transform/test_flirt.py @@ -5,16 +5,20 @@ # Author: Paul McCarthy <pauldmccarthy@gmail.com> # +import itertools as it import os.path as op import numpy as np -import fsl.data.image as fslimage -import fsl.transform as transform -import fsl.utils.tempdir as tempdir +import fsl.data.image as fslimage +import fsl.transform.flirt as flirt +import fsl.transform.affine as affine +import fsl.utils.tempdir as tempdir from .test_affine import readlines +from .. import make_random_image + datadir = op.join(op.dirname(__file__), 'testdata') @@ -22,17 +26,60 @@ datadir = op.join(op.dirname(__file__), 'testdata') def test_read_write(): with tempdir.tempdir(): aff = np.random.random((4, 4)) - transform.writeFlirt(aff, 'aff.mat') - got = transform.readFlirt('aff.mat') + flirt.writeFlirt(aff, 'aff.mat') + got = flirt.readFlirt('aff.mat') assert np.all(np.isclose(aff, got)) def test_fromFlirt(): - pass + + src = affine.compose(np.random.randint( 1, 5, 3), + np.random.randint(-20, 20, 3), + np.random.random(3) - 0.5) + ref = affine.compose(np.random.randint( 1, 5, 3), + np.random.randint(-20, 20, 3), + np.random.random(3) - 0.5) + + src = fslimage.Image(make_random_image(xform=src)) + ref = fslimage.Image(make_random_image(xform=ref)) + flirtmat = affine.concat(ref.getAffine('world', 'fsl'), + src.getAffine('fsl', 'world')) + + + spaces = it.permutations(('voxel', 'fsl', 'world'), 2) + + for from_, to in spaces: + got = flirt.fromFlirt(flirtmat, src, ref, from_, to) + exp = affine.concat(ref.getAffine('fsl', to), + flirtmat, + src.getAffine(from_, 'fsl')) + + assert np.all(np.isclose(got, exp)) def test_toFlirt(): - pass + + src = affine.compose(np.random.randint( 1, 5, 3), + np.random.randint(-20, 20, 3), + np.random.random(3) - 0.5) + ref = affine.compose(np.random.randint( 1, 5, 3), + np.random.randint(-20, 20, 3), + np.random.random(3) - 0.5) + + src = fslimage.Image(make_random_image(xform=src)) + ref = fslimage.Image(make_random_image(xform=ref)) + flirtmat = affine.concat(ref.getAffine('world', 'fsl'), + src.getAffine('fsl', 'world')) + + + spaces = it.permutations(('voxel', 'fsl', 'world'), 2) + + for from_, to in spaces: + xform = affine.concat(ref.getAffine('world', to), + src.getAffine(from_, 'world')) + got = flirt.toFlirt(xform, src, ref, from_, to) + + assert np.all(np.isclose(got, flirtmat)) def test_flirtMatrixToSform(): @@ -53,7 +100,7 @@ def test_flirtMatrixToSform(): srcImg = fslimage.Image(np.zeros(srcShape), xform=srcXform) refImg = fslimage.Image(np.zeros(refShape), xform=refXform) - result = transform.flirtMatrixToSform(flirtMat, srcImg, refImg) + result = flirt.flirtMatrixToSform(flirtMat, srcImg, refImg) assert np.all(np.isclose(result, expected)) @@ -78,8 +125,8 @@ def test_sformToFlirtMatrix(): srcImg2.voxToWorldMat = srcXformOvr - result1 = transform.sformToFlirtMatrix(srcImg1, refImg, srcXformOvr) - result2 = transform.sformToFlirtMatrix(srcImg2, refImg) + result1 = flirt.sformToFlirtMatrix(srcImg1, refImg, srcXformOvr) + result2 = flirt.sformToFlirtMatrix(srcImg2, refImg) assert np.all(np.isclose(result1, expected)) assert np.all(np.isclose(result2, expected)) diff --git a/tests/test_transform/test_fnirt.py b/tests/test_transform/test_fnirt.py new file mode 100644 index 000000000..323d93e43 --- /dev/null +++ b/tests/test_transform/test_fnirt.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python +# +# test_fnirt.py - +# +# Author: Paul McCarthy <pauldmccarthy@gmail.com> +# + +import os.path as op +import itertools as it + +import numpy as np + +import pytest + +import fsl.data.image as fslimage +import fsl.transform.affine as affine +import fsl.transform.nonlinear as nonlinear +import fsl.transform.fnirt as fnirt + +from .test_nonlinear import _random_affine_field + + +datadir = op.join(op.dirname(__file__), 'testdata', 'nonlinear') + + +def test_readFnirt(): + + src = op.join(datadir, 'src') + ref = op.join(datadir, 'ref') + coef = op.join(datadir, 'coefficientfield') + disp = op.join(datadir, 'displacementfield') + + src = fslimage.Image(src) + ref = fslimage.Image(ref) + coef = fnirt.readFnirt(coef, src, ref) + disp = fnirt.readFnirt(disp, src, ref) + + with pytest.raises(ValueError): + fnirt.readFnirt(src, src, ref) + + assert isinstance(coef, nonlinear.CoefficientField) + assert isinstance(disp, nonlinear.DisplacementField) + + assert coef.src.sameSpace(src) + assert coef.ref.sameSpace(ref) + assert disp.src.sameSpace(src) + assert disp.ref.sameSpace(ref) + assert coef.srcSpace == 'fsl' + assert coef.refSpace == 'fsl' + assert disp.srcSpace == 'fsl' + assert disp.refSpace == 'fsl' + + +def test_toFnirt(): + + def check(got, exp): + tol = dict(atol=1e-5, rtol=1e-5) + assert np.all(np.isclose(got.data, exp.data, **tol)) + assert got.src.sameSpace(exp.src) + assert got.ref.sameSpace(exp.ref) + assert got.srcSpace == 'fsl' + assert got.refSpace == 'fsl' + + basefield, xform = _random_affine_field() + src = basefield.src + ref = basefield.ref + + spaces = it.permutations(('voxel', 'fsl', 'world'), 2) + + for from_, to in spaces: + field = nonlinear.convertDisplacementSpace(basefield, from_, to) + got = fnirt.toFnirt(field) + check(got, basefield) + + src = fslimage.Image(op.join(datadir, 'src')) + ref = fslimage.Image(op.join(datadir, 'ref')) + coef = fnirt.readFnirt(op.join(datadir, 'coefficientfield'), src, ref) + disp = fnirt.readFnirt(op.join(datadir, 'displacementfield'), src, ref) + got = fnirt.toFnirt(coef) + check(got, disp) + + +def test_fromFnirt(): + + basefield, basexform = _random_affine_field() + src = basefield.src + ref = basefield.ref + spaces = list(it.permutations(('voxel', 'fsl', 'world'), 2)) + + for from_, to in spaces: + + got = fnirt.fromFnirt(basefield, from_, to) + + assert got.srcSpace == to + assert got.refSpace == from_ + + coords = [np.random.randint(0, basefield.shape[0], 5), + np.random.randint(0, basefield.shape[1], 5), + np.random.randint(0, basefield.shape[2], 5)] + coords = np.array(coords).T + + coords = affine.transform(coords, ref.getAffine('voxel', from_)) + + aff = affine.concat(src.getAffine('fsl', to), + basexform, + ref.getAffine(from_, 'fsl')) + + got = got.transform(coords) + exp = affine.transform(coords, aff) + + enan = np.isnan(exp) + gnan = np.isnan(got) + + assert np.all(np.isclose(enan, gnan)) + assert np.all(np.isclose(exp[~enan], got[~gnan])) + + # Converting from a FNIRT coefficient field + src = fslimage.Image(op.join(datadir, 'src')) + ref = fslimage.Image(op.join(datadir, 'ref')) + coef = fnirt.readFnirt(op.join(datadir, 'coefficientfield'), src, ref) + disp = fnirt.readFnirt(op.join(datadir, 'displacementfield'), src, ref) + + for from_, to in spaces: + + cnv = fnirt.fromFnirt(coef, from_, to) + exp = nonlinear.convertDisplacementSpace(disp, from_, to) + tol = dict(atol=1e-5, rtol=1e-5) + assert np.all(np.isclose(cnv.data, exp.data, **tol)) -- GitLab