From abd05f906309ff49a2777a0ad836e91588eb1b8e Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauld.mccarthy@gmail.com>
Date: Thu, 1 Sep 2016 15:25:42 +0100
Subject: [PATCH] Started adding wsome test cases for fsl.data.image.

---
 tests/conftest.py          |  33 +++++++
 tests/test_image.py        |  37 ++++++++
 tests/test_imagewrapper.py | 180 +++++++++++++++++++------------------
 3 files changed, 164 insertions(+), 86 deletions(-)
 create mode 100644 tests/conftest.py
 create mode 100644 tests/test_image.py

diff --git a/tests/conftest.py b/tests/conftest.py
new file mode 100644
index 000000000..0047f5247
--- /dev/null
+++ b/tests/conftest.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+#
+# conftest.py -
+#
+# Author: Paul McCarthy <pauldmccarthy@gmail.com>
+#
+
+import pytest
+
+
+def pytest_addoption(parser):
+    parser.addoption('--niters',
+                     type=int,
+                     action='store',
+                     default=150,
+                     help='Number of test iterations for imagewrapper')
+    
+    parser.addoption('--testdir',
+                     action='store',
+                     help='FSLeyes test data directory')
+
+
+    
+@pytest.fixture
+def testdir(request):
+    """FSLeyes test data directory."""
+    return request.config.getoption('--testdir')
+
+
+@pytest.fixture
+def niters(request):
+    """Number of test iterations."""
+    return request.config.getoption('--niters')
diff --git a/tests/test_image.py b/tests/test_image.py
new file mode 100644
index 000000000..ff722fc2b
--- /dev/null
+++ b/tests/test_image.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+#
+# test_image.py -
+#
+# Author: Paul McCarthy <pauldmccarthy@gmail.com>
+#
+
+import os.path as op
+import logging
+
+
+import numpy   as np
+import nibabel as nib
+
+import fsl.data.image as fslimage
+
+
+# Need to test:
+#     - Create image from file name (create a temp .nii.gz)
+#     - Create image from existing nibabel image
+#     - Create image from numpy array
+#     - calcRange
+#     - loadData
+
+def test_load(testdir):
+
+    assert testdir is not None
+    
+    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'))
+
+
diff --git a/tests/test_imagewrapper.py b/tests/test_imagewrapper.py
index b2f5279e0..0692f1da2 100644
--- a/tests/test_imagewrapper.py
+++ b/tests/test_imagewrapper.py
@@ -5,6 +5,7 @@
 # Author: Paul McCarthy <pauldmccarthy@gmail.com>
 
 
+from __future__ import print_function
 
 import              collections
 import              random
@@ -17,6 +18,12 @@ import fsl.data.image        as image
 import fsl.data.imagewrapper as imagewrap
 
 
+real_print = print
+
+def print(*args, **kwargs):
+    pass
+
+
 def setup_module():
     pass
 
@@ -24,13 +31,14 @@ def teardown_module():
     pass
 
 
+
 def random_coverage(shape, vol_limit=None):
     
     ndims = len(shape) - 1
     nvols = shape[-1]
 
-    print '{}D (shape: {}, {} vectors/slices/volumes)'.format(
-        ndims, shape, nvols)
+    print('{}D (shape: {}, {} vectors/slices/volumes)'.format(
+        ndims, shape, nvols))
 
     # Generate a random coverage. 
     # We use the same coverage for
@@ -304,10 +312,10 @@ def test_adjustCoverage():
         assert np.all(imagewrap.adjustCoverage(coverage, expansion) == result)
 
 
-def test_sliceOverlap(niters=150):
+def test_sliceOverlap(niters):
 
     # A bunch of random coverages
-    for i in range(niters):
+    for _ in range(niters):
 
         # 2D, 3D or 4D?
         # ndims is the number of dimensions
@@ -324,27 +332,27 @@ def test_sliceOverlap(niters=150):
 
         # Generate some slices that should
         # be contained within the coverage
-        for j in range(niters):
+        for _ in range(niters):
             slices = random_slices(coverage, shape, 'in')
             assert imagewrap.sliceOverlap(slices, coverage) == imagewrap.OVERLAP_ALL
 
         # Generate some slices that should
         # overlap with the coverage 
-        for j in range(niters):
+        for _ in range(niters):
             slices = random_slices(coverage, shape, 'overlap')
             assert imagewrap.sliceOverlap(slices, coverage) == imagewrap.OVERLAP_SOME
 
         # Generate some slices that should
         # be outside of the coverage 
-        for j in range(niters):
+        for _ in range(niters):
             slices = random_slices(coverage, shape, 'out')
             assert imagewrap.sliceOverlap(slices, coverage)  == imagewrap.OVERLAP_NONE
 
         
-def test_sliceCovered(niters=150):
+def test_sliceCovered(niters):
 
     # A bunch of random coverages
-    for i in range(niters):
+    for _ in range(niters):
 
         # 2D, 3D or 4D?
         # ndims is the number of dimensions
@@ -361,19 +369,19 @@ def test_sliceCovered(niters=150):
 
         # Generate some slices that should
         # be contained within the coverage
-        for j in range(niters):
+        for _ in range(niters):
             slices = random_slices(coverage, shape, 'in')
             assert imagewrap.sliceCovered(slices, coverage)
 
         # Generate some slices that should
         # overlap with the coverage 
-        for j in range(niters):
+        for _ in range(niters):
             slices = random_slices(coverage, shape, 'overlap')
             assert not imagewrap.sliceCovered(slices, coverage)
 
         # Generate some slices that should
         # be outside of the coverage 
-        for j in range(niters):
+        for _ in range(niters):
             slices = random_slices(coverage, shape, 'out')
             assert not imagewrap.sliceCovered(slices, coverage) 
 
@@ -389,8 +397,8 @@ def test_sliceCovered(niters=150):
 def _test_expansion(coverage, slices, volumes, expansions):
     ndims = coverage.shape[1]
 
-    print
-    print 'Slice:    "{}"'.format(" ".join(["{:2d} {:2d}".format(l, h) for l, h in slices]))
+    print()
+    print('Slice:    "{}"'.format(" ".join(["{:2d} {:2d}".format(l, h) for l, h in slices])))
 
     # Figure out what the adjusted
     # coverage should look like (assumes
@@ -415,9 +423,9 @@ def _test_expansion(coverage, slices, volumes, expansions):
     # Bin the expansions by volume
     expsByVol = collections.defaultdict(list)
     for vol, exp in zip(volumes, expansions):
-        print '  {:3d}:    "{}"'.format(
+        print('  {:3d}:    "{}"'.format(
             int(vol),
-            " ".join(["{:2d} {:2d}".format(int(l), int(h)) for l, h in exp]))
+            " ".join(["{:2d} {:2d}".format(int(l), int(h)) for l, h in exp])))
         expsByVol[vol].append(exp)
         
     for point in points:
@@ -456,26 +464,26 @@ def _test_expansion(coverage, slices, volumes, expansions):
             raise AssertionError(point)
 
             
-def test_calcExpansionNoCoverage(niters=150):
+def test_calcExpansionNoCoverage(niters):
 
-    for i in range(niters):
+    for _ in range(niters):
         ndims       = random.choice((2, 3, 4)) - 1
         shape       = np.random.randint(5, 100, size=ndims + 1)
         shape[-1]   = np.random.randint(1, 8)
         coverage    = np.zeros((2, ndims, shape[-1]))
         coverage[:] = np.nan
 
-        print
-        print '-- Out --' 
-        for j in range(niters):
+        print()
+        print('-- Out --' )
+        for _ in range(niters):
             slices     = random_slices(coverage, shape, 'out')
             vols, exps = imagewrap.calcExpansion(slices, coverage)
             _test_expansion(coverage, slices, vols, exps)
 
                 
-def test_calcExpansion(niters=150):
+def test_calcExpansion(niters):
 
-    for i in range(niters):
+    for _ in range(niters):
 
         ndims     = random.choice((2, 3, 4)) - 1
         shape     = np.random.randint(5, 60, size=ndims + 1)
@@ -484,12 +492,12 @@ def test_calcExpansion(niters=150):
 
         cov = [(lo, hi) for lo, hi in coverage[:, :, 0].T]
 
-        print 'Shape:    {}'.format(shape)
-        print 'Coverage: {}'.format(cov)
+        print('Shape:    {}'.format(shape))
+        print('Coverage: {}'.format(cov))
 
-        print
-        print '-- In --'
-        for j in range(niters):
+        print()
+        print('-- In --')
+        for _ in range(niters):
             slices     = random_slices(coverage, shape, 'in')
             vols, exps = imagewrap.calcExpansion(slices, coverage)
 
@@ -497,24 +505,24 @@ def test_calcExpansion(niters=150):
             # slice that's inside the coverage
             assert len(vols) == 0 and len(exps) == 0
             
-        print
-        print '-- Overlap --' 
-        for j in range(niters):
+        print()
+        print('-- Overlap --' )
+        for _ in range(niters):
             slices     = random_slices(coverage, shape, 'overlap')
             vols, exps = imagewrap.calcExpansion(slices, coverage)
             _test_expansion(coverage, slices, vols, exps)
 
-        print
-        print '-- Out --' 
-        for j in range(niters):
+        print()
+        print('-- Out --' )
+        for _ in range(niters):
             slices     = random_slices(coverage, shape, 'out')
             vols, exps = imagewrap.calcExpansion(slices, coverage)
             _test_expansion(coverage, slices, vols, exps)
 
 
-def test_ImageWrapper_read(niters=150):
+def test_ImageWrapper_read(niters):
 
-    for i in range(niters):
+    for _ in range(niters):
 
         # Generate an image with a number of volumes
         ndims     = random.choice((2, 3, 4)) - 1
@@ -530,10 +538,10 @@ def test_ImageWrapper_read(niters=150):
         volRanges    = [(np.min(data[..., 0]),
                          np.max(data[..., 0]))]
 
-        for i in range(1, nvols):
-            data[..., i] = data[..., 0] * (i + 1)
-            volRanges.append((np.min(data[..., i]),
-                              np.max(data[..., i])))
+        for vol in range(1, nvols):
+            data[..., vol] = data[..., 0] * (vol + 1)
+            volRanges.append((np.min(data[..., vol]),
+                              np.max(data[..., vol])))
 
         img     = nib.Nifti1Image(data, np.eye(4))
         wrapper = imagewrap.ImageWrapper(img, loadData=False)
@@ -542,7 +550,7 @@ def test_ImageWrapper_read(niters=150):
         # through the image wrapper with a
         # bunch of random volume orderings.
 
-        for i in range(niters):
+        for _ in range(niters):
 
             ordering = list(range(nvols))
             random.shuffle(ordering)
@@ -570,11 +578,11 @@ def test_ImageWrapper_read(niters=150):
                 else:             assert     wrapper.covered
 
                 
-def test_ImageWrapper_write_out(niters=150):
+def test_ImageWrapper_write_out(niters):
     # This is HORRIBLE
  
     # Generate a bunch of random coverages
-    for i in range(niters):
+    for _ in range(niters):
         
         # Generate an image with just two volumes. We're only
         # testing within-volume modifications here.
@@ -588,13 +596,13 @@ def test_ImageWrapper_write_out(niters=150):
         # The data range of each volume
         # increases sequentially
         data[..., 0] = np.random.randint(-5, 6, shape[:-1])
-        for i in range(1, nvols):
-            data[..., i] = data[..., 0] * (i + 1)
+        for vol in range(1, nvols):
+            data[..., vol] = data[..., 0] * (vol + 1)
 
         # Generate a random coverage
         cov = random_coverage(shape, vol_limit=1)
 
-        print 'This is the coverage: {}'.format(cov)
+        print('This is the coverage: {}'.format(cov))
 
         img     = nib.Nifti1Image(data, np.eye(4))
         wrapper = imagewrap.ImageWrapper(img)
@@ -603,7 +611,7 @@ def test_ImageWrapper_write_out(niters=150):
 
         # Now, we'll simulate some writes
         # outside of the coverage area.
-        for i in range(niters):
+        for _ in range(niters):
 
             # Generate some slices outside
             # of the coverage area, making
@@ -622,8 +630,8 @@ def test_ImageWrapper_write_out(niters=150):
                 sliceshape = sliceshape[:-1]
                 break
 
-            print '---------------'
-            print 'Slice {}'.format(slices)
+            print('---------------')
+            print('Slice {}'.format(slices))
 
             # Expected wrapper coverage after the write
             expCov = imagewrap.adjustCoverage(cov[..., 0], slices)
@@ -661,9 +669,9 @@ def test_ImageWrapper_write_out(niters=150):
                 wrapper = imagewrap.ImageWrapper(img)
                 applyCoverage(wrapper, cov)
 
-                print 'ndims', ndims
-                print 'sliceshape', sliceshape
-                print 'sliceobjs', sliceobjs
+                print('ndims', ndims)
+                print('sliceshape', sliceshape)
+                print('sliceobjs', sliceobjs)
 
                 newData = np.linspace(rlo, rhi, np.prod(sliceshape))
                 newData = newData.reshape(sliceshape)
@@ -671,7 +679,7 @@ def test_ImageWrapper_write_out(niters=150):
                 # Make sure that the expected low/high values
                 # are present in the data being written
 
-                print 'Writing data (shape: {})'.format(newData.shape)
+                print('Writing data (shape: {})'.format(newData.shape))
 
                 oldCov = wrapper.coverage(0)
 
@@ -680,32 +688,32 @@ def test_ImageWrapper_write_out(niters=150):
                 expLo, expHi = coverageDataRange(img.get_data(), cov, slices)
                 newLo, newHi = wrapper.dataRange
 
-                print 'Old    range: {} - {}'.format(clo,   chi)
-                print 'Sim    range: {} - {}'.format(rlo,   rhi)
-                print 'Exp    range: {} - {}'.format(expLo, expHi)
-                print 'NewDat range: {} - {}'.format(newData.min(), newData.max())
-                print 'Data   range: {} - {}'.format(data.min(),   data.max())
-                print 'Expand range: {} - {}'.format(elo, ehi)
-                print 'New    range: {} - {}'.format(newLo, newHi)
+                print('Old    range: {} - {}'.format(clo,   chi))
+                print('Sim    range: {} - {}'.format(rlo,   rhi))
+                print('Exp    range: {} - {}'.format(expLo, expHi))
+                print('NewDat range: {} - {}'.format(newData.min(), newData.max()))
+                print('Data   range: {} - {}'.format(data.min(),   data.max()))
+                print('Expand range: {} - {}'.format(elo, ehi))
+                print('New    range: {} - {}'.format(newLo, newHi))
 
                 newCov = wrapper.coverage(0)
-                print 'Old coverage:      {}'.format(oldCov)
-                print 'New coverage:      {}'.format(newCov)
-                print 'Expected coverage: {}'.format(expCov)
-                print
-                print
+                print('Old coverage:      {}'.format(oldCov))
+                print('New coverage:      {}'.format(newCov))
+                print('Expected coverage: {}'.format(expCov))
+                print()
+                print()
 
                 assert np.all(newCov == expCov)
 
                 assert np.isclose(newLo, expLo)
                 assert np.isclose(newHi, expHi)
-            print '--------------'
+            print('--------------')
 
             
-def test_ImageWrapper_write_in_overlap(niters=150):
+def test_ImageWrapper_write_in_overlap(niters):
 
     # Generate a bunch of random coverages
-    for i in range(niters):
+    for _ in range(niters):
 
         # Generate an image with just two volumes. We're only
         # testing within-volume modifications here.
@@ -719,8 +727,8 @@ def test_ImageWrapper_write_in_overlap(niters=150):
         # The data range of each volume
         # increases sequentially
         data[..., 0] = np.random.randint(-5, 6, shape[:-1])
-        for i in range(1, nvols):
-            data[..., i] = data[..., 0] * (i + 1)        
+        for vol in range(1, nvols):
+            data[..., vol] = data[..., 0] * (vol + 1)
 
         # Generate a random coverage
         cov = random_coverage(shape, vol_limit=1)
@@ -728,7 +736,7 @@ def test_ImageWrapper_write_in_overlap(niters=150):
         # Now, we'll simulate some writes
         # which are contained within, or
         # overlap with, the initial coverage
-        for i in range(niters):
+        for _ in range(niters):
 
             # Generate some slices outside
             # of the coverage area, making
@@ -757,7 +765,7 @@ def test_ImageWrapper_write_in_overlap(niters=150):
             nullCov[:] = np.nan
             expCov     = imagewrap.adjustCoverage(nullCov[..., 0], slices)
 
-            for i in range(10):
+            for _ in range(10):
 
                 rlo = rfloat(data.min() - 100, data.max() + 100)
                 rhi = rfloat(rlo,              data.max() + 100)
@@ -770,15 +778,15 @@ def test_ImageWrapper_write_in_overlap(niters=150):
                 newData = newData.reshape(sliceshape)
 
 
-                print 'Old range:      {} - {}'.format(*wrapper.dataRange)
+                print('Old range:      {} - {}'.format(*wrapper.dataRange))
 
                 wrapper[tuple(sliceobjs)] = newData
 
                 newCov       = wrapper.coverage(0)
                 newLo, newHi = wrapper.dataRange
 
-                print 'Expected range: {} - {}'.format(rlo,   rhi)
-                print 'New range:      {} - {}'.format(newLo, newHi)
+                print('Expected range: {} - {}'.format(rlo,   rhi))
+                print('New range:      {} - {}'.format(newLo, newHi))
 
                 assert np.all(newCov == expCov)
 
@@ -786,9 +794,9 @@ def test_ImageWrapper_write_in_overlap(niters=150):
                 assert np.isclose(newHi, rhi)
 
             
-def test_ImageWrapper_write_different_volume(niters=150):
+def test_ImageWrapper_write_different_volume(niters):
 
-    for i in range(niters):
+    for _ in range(niters):
 
         # Generate an image with several volumes. 
         ndims     = random.choice((2, 3, 4)) - 1
@@ -801,8 +809,8 @@ def test_ImageWrapper_write_different_volume(niters=150):
         # The data range of each volume
         # increases sequentially
         data[..., 0] = np.random.randint(-5, 6, shape[:-1])
-        for i in range(1, nvols):
-            data[..., i] = data[..., 0] * (i + 1)
+        for vol in range(1, nvols):
+            data[..., vol] = data[..., 0] * (vol + 1)
 
 
         # Generate a random coverage
@@ -826,14 +834,14 @@ def test_ImageWrapper_write_different_volume(niters=150):
 
         covlo, covhi = coverageDataRange(data, cov)
 
-        print 'Coverage: {} [{} - {}]'.format(
+        print('Coverage: {} [{} - {}]'.format(
             [(lo, hi) for lo, hi in cov[:, :, covvlo].T],
-            covvlo, covvhi)
+            covvlo, covvhi))
 
         # Now, we'll simulate some writes
         # on volumes that are not in the
         # coverage
-        for i in range(niters):
+        for _ in range(niters):
 
             # Generate a slice, making
             # sure that the slice covers
@@ -843,7 +851,7 @@ def test_ImageWrapper_write_different_volume(niters=150):
                                        shape,
                                        random.choice(('out', 'in', 'overlap')))
 
-                # print slices
+                # print(slices)
 
                 # Clobber the slice volume range
                 # so it does not overlap with the
@@ -923,7 +931,7 @@ def test_ImageWrapper_write_different_volume(niters=150):
                 assert np.isclose(newHi, ehi)
 
 
-def test_collapseExpansions(niters=500):
+def test_collapseExpansions(niters):
 
     def expEq(exp1, exp2):
         
@@ -943,7 +951,7 @@ def test_collapseExpansions(niters=500):
         return not ((r1lo > r2hi) or (r1hi < r2lo) or \
                     (r2lo > r1hi) or (r2hi < r1lo))
 
-    for i in range(niters):
+    for _ in range(niters):
 
         # Generate a random coverage shape
         ndims     = random.choice((2, 3, 4)) - 1
@@ -957,7 +965,7 @@ def test_collapseExpansions(niters=500):
         exps     = []
         expected = []
 
-        for i in range(10):
+        for _ in range(10):
 
             # Generate a random slice with a volume
             # range that doesn't overlap with, and
-- 
GitLab