diff --git a/unit_tests/avwutils/fslcreatehd/feedsRun b/unit_tests/avwutils/fslcreatehd/feedsRun index 5668155d52780c93842fe4159dfd43b7ceb77eeb..c1ce6e473f26d97aec5552f4107eb2752652d404 100755 --- a/unit_tests/avwutils/fslcreatehd/feedsRun +++ b/unit_tests/avwutils/fslcreatehd/feedsRun @@ -1,6 +1,7 @@ #!/usr/bin/env fslpython import os +import os.path as op import sys import subprocess as sp @@ -8,6 +9,9 @@ import numpy as np import nibabel as nib +THISDIR = op.dirname(__file__) + + # 2=char, 4=short, 8=int, 16=float, 64=double DTYPE_MAPPING = { 2 : np.uint8, @@ -17,6 +21,11 @@ DTYPE_MAPPING = { 64 : np.float64 } +MNI152_2MM_AFFINE = np.array([[-2, 0, 0, 90], + [ 0, 2, 0, -126], + [ 0, 0, 2, -72], + [ 0, 0, 0, 1]]) + def validate_result(imgfile, expshape, exppixdim, exporigin, expdtype): @@ -83,6 +92,13 @@ def test_new_file(): args = list(test.split()) imgfile = 'image.nii.gz' + try: + os.remove(imgfile) + except: + pass + + print(['fslcreatehd'] + args + [imgfile]) + sp.run(['fslcreatehd'] + args + [imgfile]) args = [float(a) for a in args] @@ -175,9 +191,72 @@ def test_existing_file(): os.remove(imgfile) +def test_new_file_xml(): + xmlfile = op.join(THISDIR, 'mni2mm.xml') + sp.run(['fslcreatehd', xmlfile, 'mni.nii.gz']) + img = nib.load('mni.nii.gz') + + assert img.shape == (91, 109, 91) + assert img.header.get_zooms()[:3] == (2.0, 2.0, 2.0) + assert img.header['intent_code'] == 10 + assert img.header['intent_p1'] == 20 + assert img.header['intent_p2'] == 30 + assert img.header['intent_p3'] == 40 + + +def test_existing_file_xml_same_shape(): + xmlfile = op.join(THISDIR, 'mni2mm.xml') + img = create_image((91, 109, 91), (3, 3, 3), (5, 5, 5), np.float32) + img.to_filename('image.nii.gz') + + sp.run(['fslcreatehd', xmlfile, 'image.nii.gz']) + + result = nib.load('image.nii.gz') + + assert result.shape == (91, 109, 91) + assert result.header.get_zooms()[:3] == (2.0, 2.0, 2.0) + + # bug in FSL<=6.0.4 caused intent codes to not be set + assert result.header['intent_code'] == 10 + assert result.header['intent_p1'] == 20 + assert result.header['intent_p2'] == 30 + assert result.header['intent_p3'] == 40 + assert np.all(result.affine == MNI152_2MM_AFFINE) + + # data should be preserved + assert np.all(result.get_fdata() == img.get_fdata()) + + +def test_existing_file_xml_different_shape(): + + xmlfile = op.join(THISDIR, 'mni2mm.xml') + img = create_image((20, 20, 20), (3, 3, 3), (5, 5, 5), np.float32) + + img.to_filename('image.nii.gz') + + sp.run(['fslcreatehd', xmlfile, 'image.nii.gz']) + + result = nib.load('image.nii.gz') + + assert result.shape == (91, 109, 91) + assert result.header.get_zooms()[:3] == (2.0, 2.0, 2.0) + assert result.header['intent_code'] == 10 + assert result.header['intent_p1'] == 20 + assert result.header['intent_p2'] == 30 + assert result.header['intent_p3'] == 40 + assert np.all(result.affine == MNI152_2MM_AFFINE) + + # data should be cleared + assert np.all(result.get_fdata() == 0) + + def main(): test_new_file() test_existing_file() + test_new_file_xml() + test_existing_file_xml_same_shape() + test_existing_file_xml_different_shape() + if __name__ == '__main__': sys.exit(main()) diff --git a/unit_tests/avwutils/fslcreatehd/mni2mm.xml b/unit_tests/avwutils/fslcreatehd/mni2mm.xml new file mode 100644 index 0000000000000000000000000000000000000000..06b8043c942be6a6bec7c11a26aa44a5cb243471 --- /dev/null +++ b/unit_tests/avwutils/fslcreatehd/mni2mm.xml @@ -0,0 +1,44 @@ +<nifti_image + image_offset = '352' + ndim = '3' + nx = '91' + ny = '109' + nz = '91' + nt = '1' + dx = '2' + dy = '2' + dz = '2' + dt = '1' + datatype = '4' + nvox = '902629' + nbyper = '2' + scl_slope = '1' + scl_inter = '0' + intent_code = '10' + intent_p1 = '20' + intent_p2 = '30' + intent_p3 = '40' + intent_name = '' + toffset = '0' + xyz_units = '2' + time_units = '8' + freq_dim = '0' + phase_dim = '0' + slice_dim = '0' + descrip = 'FSL5.0' + aux_file = '' + qform_code = '4' + qfac = '-1' + quatern_b = '0' + quatern_c = '1' + quatern_d = '0' + qoffset_x = '90' + qoffset_y = '-126' + qoffset_z = '-72' + sform_code = '4' + sto_xyz_matrix = '-2 0 0 90 0 2 0 -126 0 0 2 -72 0 0 0 1' + slice_code = '0' + slice_start = '0' + scl_end = '0' + scl_duration = '0' +/>