From e3a4f76b782aef94e5d833ff2c0886188ab8e8f9 Mon Sep 17 00:00:00 2001 From: Paul McCarthy <pauldmccarthy@gmail.com> Date: Mon, 25 Jul 2022 18:28:07 +0100 Subject: [PATCH] Test that applywarp --usesqform adheres to FSL sform/qform usage conventions. --- unit_tests/fugue/applywarp/feedsRun | 81 +++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100755 unit_tests/fugue/applywarp/feedsRun diff --git a/unit_tests/fugue/applywarp/feedsRun b/unit_tests/fugue/applywarp/feedsRun new file mode 100755 index 0000000..73b53bb --- /dev/null +++ b/unit_tests/fugue/applywarp/feedsRun @@ -0,0 +1,81 @@ +#!/usr/bin/env fslpython + + +import shlex +import subprocess as sp +import numpy as np +import nibabel as nib +from fsl.data.image import Image +import fsl.transform.affine as affine + + +def applywarp(src, ref): + cmd = f'applywarp --in={src} --ref={ref} --usesqform --out=out' + sp.run(shlex.split(cmd), check=True) + return Image('out') + + +def make_image(fname, data, sform, sform_code, qform, qform_code): + hdr = nib.Nifti1Header() + hdr.set_sform(sform, sform_code) + hdr.set_qform(qform, qform_code) + img = Image(data, header=hdr) + img.save(fname) + return img + +# fsl/fugue!6 +# +# Make sure that applywarp --usesqform +# will correctly use the sform or qform +# +# FSL affine precedence rules are as follows: +# +# 1. If sform_code != 0, use sform; else +# 2. If qform_code != 0, use qform; else +# 3. Use a scaling matrix with pixdims along the +# diagonal +def test_applywarp_uses_sqform_correctly(): + + srcdata = np.zeros((20, 20, 20)) + refdata = np.zeros((20, 20, 20)) + + # Data from the two images + # aligned via their affines - + # src should be resampled so + # as to be identical to ref + srcdata[ 6: 9, 6: 9, 6: 9] = 1 + refdata[16:19, 16:19, 16:19] = 1 + + eye = np.eye(4) + srcaff = affine.scaleOffsetXform(1, [ 5, 5, 5]) + refaff = affine.scaleOffsetXform(1, [-5, -5, -5]) + + # aligned via sform + src = make_image('src', srcdata, srcaff, 2, eye, 1) + ref = make_image('ref', refdata, refaff, 2, eye, 1) + result = applywarp('src', 'ref') + assert np.all(np.isclose(result.data, ref.data)) + + # aligned via sform again + src = make_image('src', srcdata, srcaff, 2, eye, 0) + ref = make_image('ref', refdata, refaff, 2, eye, 0) + result = applywarp('src', 'ref') + assert np.all(np.isclose(result.data, ref.data)) + + # aligned via qform + src = make_image('src', srcdata, eye, 0, srcaff, 2) + ref = make_image('ref', refdata, eye, 0, refaff, 2) + result = applywarp('src', 'ref') + assert np.all(np.isclose(result.data, ref.data)) + + # not aligned - should result in a scaling + # matrix being used (an identify matrix here) + src = make_image('src', srcdata, eye, 0, srcaff, 0) + ref = make_image('ref', refdata, eye, 0, refaff, 0) + result = applywarp('src', 'ref') + assert not np.all(np.isclose(result.data, ref.data)) + assert np.all(np.isclose(result.data, src.data)) + + +if __name__ == '__main__': + test_applywarp_uses_sqform_correctly() -- GitLab