From 8bc789a8c014c9a26bde54939ffcea1393c54027 Mon Sep 17 00:00:00 2001 From: Paul McCarthy <pauld.mccarthy@gmail.com> Date: Fri, 2 Sep 2016 16:47:42 +0100 Subject: [PATCH] More path tests, and tests for fsl.data.image --- tests/test_fsl_utils_path.py | 22 ++--- tests/test_image.py | 165 +++++++++++++++++++++++++++++++++-- 2 files changed, 168 insertions(+), 19 deletions(-) diff --git a/tests/test_fsl_utils_path.py b/tests/test_fsl_utils_path.py index bb6b9cb17..25f945620 100644 --- a/tests/test_fsl_utils_path.py +++ b/tests/test_fsl_utils_path.py @@ -10,6 +10,7 @@ import os.path as op import pytest import fsl.utils.path as fslpath +import fsl.data.image as fslimage def test_addExt_exists_shouldPass(testdir): @@ -17,9 +18,8 @@ def test_addExt_exists_shouldPass(testdir): are valid. """ - # If we have a .hdr/.img pair, the .img should take precedence - replacements = {'.hdr' : ['.img', '.img.gz']} - allowedExts = ['.hdr', '.img', '.nii', '.nii.gz', '.img.gz'] + replacements = fslimage.REPLACEMENTS + allowedExts = fslimage.ALLOWED_EXTENSIONS tests = [ ('compressed', 'compressed.nii.gz'), @@ -30,7 +30,7 @@ def test_addExt_exists_shouldPass(testdir): ('img_hdr_pair.hdr', 'img_hdr_pair.hdr'), ('img_hdr_pair.img', 'img_hdr_pair.img'), ('compressed_img_hdr_pair', 'compressed_img_hdr_pair.img.gz'), - ('compressed_img_hdr_pair.hdr', 'compressed_img_hdr_pair.hdr'), + ('compressed_img_hdr_pair.hdr.gz', 'compressed_img_hdr_pair.hdr.gz'), ('compressed_img_hdr_pair.img.gz', 'compressed_img_hdr_pair.img.gz'), ] @@ -48,9 +48,9 @@ def test_addExt_exists_shouldFail(testdir): """Tests the addExt function with inputs that should cause it to raise an error. """ - - replacements = {'.hdr' : ['.img', '.img.gz']} - allowedExts = ['.hdr', '.img', '.nii', '.nii.gz', '.img.gz'] + + replacements = fslimage.REPLACEMENTS + allowedExts = fslimage.ALLOWED_EXTENSIONS shouldFail = [ @@ -73,6 +73,8 @@ def test_addExt_exists_shouldFail(testdir): ('ambiguous', [], {'.hdr' : ['.img']}), ('ambiguous', False, {'.hdr' : ['.img.gz']}), ('ambiguous', [], {'.hdr' : ['.img.gz']}), + ('ambiguous', False, {'.hdr' : ['.img', '.img.gz', '.nii']}), + ('ambiguous', [], {'.hdr' : ['.img', '.img.gz', '.nii']}), ('badpath'), ('badpath.nii.gz'), @@ -101,7 +103,7 @@ def test_addExt_exists_shouldFail(testdir): def test_addExt_noExist(testdir): - allowedExts = ['.hdr', '.img', '.nii', '.nii.gz', '.img.gz'] + allowedExts = fslimage.ALLOWED_EXTENSIONS # Prefix, output, defaultExt, allowedExts tests = [ @@ -136,7 +138,7 @@ def test_addExt_noExist(testdir): def test_removeExt(testdir): - allowedExts = ['.hdr', '.img', '.nii', '.nii.gz', '.img.gz'] + allowedExts = fslimage.ALLOWED_EXTENSIONS # If len(test) == 2, allowedExts is set from above # Otherwise, it is set from the test tuple @@ -170,7 +172,7 @@ def test_removeExt(testdir): def test_getExt(testdir): - allowedExts = ['.hdr', '.img', '.nii', '.nii.gz', '.img.gz'] + allowedExts = fslimage.ALLOWED_EXTENSIONS # len(test) == 2 -> allowedExts set from above # Otherwise, allowedExts set from test tuple diff --git a/tests/test_image.py b/tests/test_image.py index ff722fc2b..757789f17 100644 --- a/tests/test_image.py +++ b/tests/test_image.py @@ -6,13 +6,16 @@ # import os.path as op -import logging +import pytest +import glob import numpy as np import nibabel as nib -import fsl.data.image as fslimage +import fsl.data.constants as constants +import fsl.data.image as fslimage +import fsl.utils.path as fslpath # Need to test: @@ -25,13 +28,157 @@ import fsl.data.image as fslimage def test_load(testdir): assert testdir is not None + + shouldPass = ['compressed', + 'compressed.nii.gz', + 'uncompressed', + 'uncompressed.nii', + 'img_hdr_pair', + 'img_hdr_pair.img', + 'img_hdr_pair.hdr', + 'compressed_img_hdr_pair', + 'compressed_img_hdr_pair.img.gz', + 'compressed_img_hdr_pair.hdr.gz', + 'ambiguous.nii', + 'ambiguous.hdr', + 'ambiguous.img', + 'ambiguous.hdr.gz', + 'ambiguous.img.gz'] + shouldRaise = ['notexist', + 'notexist.nii.gz', + 'ambiguous'] - fslimage.Image(op.join(testdir, 'nifti_formats', 'compressed')) - fslimage.Image(op.join(testdir, 'nifti_formats', 'compressed.nii.gz')) - fslimage.Image(op.join(testdir, 'nifti_formats', 'uncompressed')) - fslimage.Image(op.join(testdir, 'nifti_formats', 'uncompressed.nii')) - fslimage.Image(op.join(testdir, 'nifti_formats', 'img_hdr_pair')) - fslimage.Image(op.join(testdir, 'nifti_formats', 'img_hdr_pair.img')) - fslimage.Image(op.join(testdir, 'nifti_formats', 'img_hdr_pair.hdr')) + # Not raising an error means the test passes + for fname in shouldPass: + fslimage.Image(op.join(testdir, 'nifti_formats', fname)) + + # These should raise an error + for fname in shouldRaise: + with pytest.raises(fslpath.PathError): + print fname + fslimage.Image(op.join(testdir, 'nifti_formats', fname)) + + + +def test_Image_atts(testdir): + + allowedExts = fslimage.ALLOWED_EXTENSIONS + + # (file, dims, pixdims) + tests = [ + ('MNI152_T1_0.5mm', (364, 436, 364), (0.5, 0.5, 0.5), np.uint8), + ('MNI152_T1_1mm', (182, 218, 182), (1.0, 1.0, 1.0), np.int16), + ('MNI152_T1_2mm', (91, 109, 91), (2.0, 2.0, 2.0), np.int16), + ('MNI152_T1_2mm_4D', (91, 109, 91, 5), (2.0, 2.0, 2.0, 1.0), np.int16), + (op.join('nifti2D', 'MNI152_T1_2mm_sliceXY'), (91, 109, 1), (2.0, 2.0, 2.0), np.int16), + (op.join('nifti2D', 'MNI152_T1_2mm_sliceXZ'), (91, 1, 91), (2.0, 2.0, 2.0), np.int16), + (op.join('nifti2D', 'MNI152_T1_2mm_sliceYZ'), (1, 109, 91), (2.0, 2.0, 2.0), np.int16)] + + for path, dims, pixdims, dtype in tests: + + path = op.abspath(op.join(testdir, path)) + i = fslimage.Image(path) + + assert tuple(i.shape) == tuple(dims) + assert tuple(i.pixdim) == tuple(pixdims) + assert tuple(i.nibImage.shape) == tuple(dims) + assert tuple(i.nibImage.header.get_zooms()) == tuple(pixdims) + + assert i.dtype == dtype + assert i.name == op.basename(path) + assert i.dataSource == fslpath.addExt(path, allowedExts, mustExist=True) + + +def test_looksLikeImage(): + + # (file, expected) + tests = [ + ('blah', False), + ('blah.moo', False), + ('blah.nii', True), + ('blah.nii.gz', True), + ('blah.hdr', True), + ('blah.img', True), + ('blah.hdr.gz', True), + ('blah.img.gz', True), + ] + + for path, expected in tests: + assert fslimage.looksLikeImage(path) == expected + +def test_addExt(testdir): + default = fslimage.DEFAULT_EXTENSION + + # (file, mustExist, expected) + tests = [ + ('blah', False, 'blah{}'.format(default)), + ('blah.nii', False, 'blah.nii'), + ('blah.nii.gz', False, 'blah.nii.gz'), + ('blah.img', False, 'blah.img'), + ('blah.hdr', False, 'blah.hdr'), + ('blah.img.gz', False, 'blah.img.gz'), + ('blah.hdr.gz', False, 'blah.hdr.gz'), + ('compressed', True, 'compressed.nii.gz'), + ('compressed.nii.gz', True, 'compressed.nii.gz'), + ('uncompressed', True, 'uncompressed.nii'), + ('uncompressed.nii', True, 'uncompressed.nii'), + ('img_hdr_pair', True, 'img_hdr_pair.img'), + ('img_hdr_pair.hdr', True, 'img_hdr_pair.hdr'), + ('img_hdr_pair.img', True, 'img_hdr_pair.img'), + ('compressed_img_hdr_pair', True, 'compressed_img_hdr_pair.img.gz'), + ('compressed_img_hdr_pair.img.gz', True, 'compressed_img_hdr_pair.img.gz'), + ('compressed_img_hdr_pair.hdr.gz', True, 'compressed_img_hdr_pair.hdr.gz'), + ('ambiguous.nii', True, 'ambiguous.nii'), + ('ambiguous.nii.gz', True, 'ambiguous.nii.gz'), + ('ambiguous.img', True, 'ambiguous.img'), + ('ambiguous.hdr', True, 'ambiguous.hdr'), + ('ambiguous.img.gz', True, 'ambiguous.img.gz'), + ('ambiguous.hdr.gz', True, 'ambiguous.hdr.gz')] + + for path, mustExist, expected in tests: + if mustExist: + path = op.join(testdir, 'nifti_formats', path) + expected = op.join(testdir, 'nifti_formats', expected) + + assert fslimage.addExt(path, mustExist) == expected + + with pytest.raises(fslimage.PathError): + path = op.join(testdir, 'nifti_formats', 'ambiguous') + fslimage.addExt(path, mustExist=True) + + +def test_Image_orientation(testdir): + + neuro = op.join(testdir, 'dtifit', 'neuro', 'dti_FA') + radio = op.join(testdir, 'dtifit', 'radio', 'dti_FA') + + neuro = fslimage.Image(neuro) + radio = fslimage.Image(radio) + + assert neuro.isNeurological() + assert not radio.isNeurological() + + # Both images should have the + # same orientation in the + # world coordinate system + assert neuro.getOrientation(0, np.eye(4)) == constants.ORIENT_L2R + assert neuro.getOrientation(1, np.eye(4)) == constants.ORIENT_P2A + assert neuro.getOrientation(2, np.eye(4)) == constants.ORIENT_I2S + assert radio.getOrientation(0, np.eye(4)) == constants.ORIENT_L2R + assert radio.getOrientation(1, np.eye(4)) == constants.ORIENT_P2A + assert radio.getOrientation(2, np.eye(4)) == constants.ORIENT_I2S + + # The radio image should be + # l/r flipped in the voxel + # coordinate system + assert neuro.getOrientation(0, neuro.worldToVoxMat) == constants.ORIENT_L2R + assert neuro.getOrientation(1, neuro.worldToVoxMat) == constants.ORIENT_P2A + assert neuro.getOrientation(2, neuro.worldToVoxMat) == constants.ORIENT_I2S + + assert radio.getOrientation(0, radio.worldToVoxMat) == constants.ORIENT_R2L + assert radio.getOrientation(1, radio.worldToVoxMat) == constants.ORIENT_P2A + assert radio.getOrientation(2, radio.worldToVoxMat) == constants.ORIENT_I2S + + -- GitLab