Commit abd05f90 authored by Paul McCarthy's avatar Paul McCarthy
Browse files

Started adding wsome test cases for fsl.data.image.

parent 9fa9ee4b
#!/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')
#!/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'))
......@@ -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
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment