Skip to content

Commit 214dd3b

Browse files
committed
RF+TST: add test for 4D MINC to processing + test
Processing routines should barf on 4D MINC because they do not know how to work out the spatial axes. Use new `spatial_axes_first` function to check for problem images, raise. Test errors raised.
1 parent 3abff0d commit 214dd3b

File tree

2 files changed

+46
-7
lines changed

2 files changed

+46
-7
lines changed

nibabel/processing.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from .affines import AffineError, to_matvec, from_matvec, append_diag
2626
from .spaces import vox2out_vox
2727
from .nifti1 import Nifti1Image
28+
from .imageclasses import spatial_axes_first
2829

2930
SIGMA2FWHM = np.sqrt(8 * np.log(2))
3031

@@ -124,9 +125,9 @@ def resample_from_to(from_img,
124125
Parameters
125126
----------
126127
from_img : object
127-
Object having attributes ``dataobj``, ``affine``, ``header``. If
128-
`out_class` is not None, ``img.__class__`` should be able to construct
129-
an image from data, affine and header.
128+
Object having attributes ``dataobj``, ``affine``, ``header`` and
129+
``shape``. If `out_class` is not None, ``img.__class__`` should be able
130+
to construct an image from data, affine and header.
130131
to_vox_map : image object or length 2 sequence
131132
If object, has attributes ``shape`` giving input voxel shape, and
132133
``affine`` giving mapping of input voxels to output space. If length 2
@@ -153,6 +154,10 @@ def resample_from_to(from_img,
153154
resampling `from_img` into axes aligned to the output space of
154155
``from_img.affine``
155156
"""
157+
# This check requires `shape` attribute of image
158+
if not spatial_axes_first(from_img):
159+
raise ValueError('Cannot predict position of spatial axes for Image '
160+
'type ' + str(type(from_img)))
156161
try:
157162
to_shape, to_affine = to_vox_map.shape, to_vox_map.affine
158163
except AttributeError:
@@ -248,9 +253,9 @@ def smooth_image(img,
248253
Parameters
249254
----------
250255
img : object
251-
Object having attributes ``dataobj``, ``affine``, ``header``. If
252-
`out_class` is not None, ``img.__class__`` should be able to construct
253-
an image from data, affine and header.
256+
Object having attributes ``dataobj``, ``affine``, ``header`` and
257+
``shape``. If `out_class` is not None, ``img.__class__`` should be able
258+
to construct an image from data, affine and header.
254259
fwhm : scalar or length 3 sequence
255260
FWHM *in mm* over which to smooth. The smoothing applies to the voxel
256261
axes, not to the output axes, but is in millimeters. The function
@@ -280,6 +285,10 @@ def smooth_image(img,
280285
Image of instance specified by `out_class`, containing data output from
281286
smoothing `img` data by given FWHM kernel.
282287
"""
288+
# This check requires `shape` attribute of image
289+
if not spatial_axes_first(img):
290+
raise ValueError('Cannot predict position of spatial axes for Image '
291+
'type ' + str(type(img)))
283292
if out_class is None:
284293
out_class = img.__class__
285294
n_dim = len(img.shape)

nibabel/tests/test_processing.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
from nibabel.nifti1 import Nifti1Image
2525
from nibabel.nifti2 import Nifti2Image
2626
from nibabel.orientations import flip_axis, inv_ornt_aff
27-
from nibabel.affines import AffineError, from_matvec, to_matvec, apply_affine
27+
from nibabel.affines import (AffineError, from_matvec, to_matvec, apply_affine,
28+
voxel_sizes)
2829
from nibabel.eulerangles import euler2mat
2930

3031
from numpy.testing import (assert_almost_equal,
@@ -41,6 +42,15 @@
4142

4243
DATA_DIR = pjoin(dirname(__file__), 'data')
4344

45+
# 3D MINC work correctly with processing, but not 4D MINC
46+
from .test_imageclasses import MINC_3DS, MINC_4DS
47+
48+
# Filenames of other images that should work correctly with processing
49+
OTHER_IMGS = ('anatomical.nii', 'functional.nii',
50+
'example4d.nii.gz', 'example_nifti2.nii.gz',
51+
'phantom_EPI_asc_CLEAR_2_1.PAR')
52+
53+
4454
def test_sigma2fwhm():
4555
# Test from constant
4656
assert_almost_equal(sigma2fwhm(1), 2.3548200)
@@ -346,6 +356,26 @@ def test_smooth_image():
346356
Nifti2Image)
347357

348358

359+
@needs_scipy
360+
def test_spatial_axes_check():
361+
for fname in MINC_3DS + OTHER_IMGS:
362+
img = nib.load(pjoin(DATA_DIR, fname))
363+
s_img = smooth_image(img, 0)
364+
assert_array_equal(img.dataobj, s_img.dataobj)
365+
out = resample_from_to(img, img, mode='nearest')
366+
assert_almost_equal(img.dataobj, out.dataobj)
367+
if len(img.shape) > 3:
368+
continue
369+
# Resample to output does not raise an error
370+
out = resample_to_output(img, voxel_sizes(img.affine))
371+
for fname in MINC_4DS:
372+
img = nib.load(pjoin(DATA_DIR, fname))
373+
assert_raises(ValueError, smooth_image, img, 0)
374+
assert_raises(ValueError, resample_from_to, img, img, mode='nearest')
375+
assert_raises(ValueError,
376+
resample_to_output, img, voxel_sizes(img.affine))
377+
378+
349379
def assert_spm_resampling_close(from_img, our_resampled, spm_resampled):
350380
""" Assert our resampling is close to SPM's, allowing for edge effects
351381
"""

0 commit comments

Comments
 (0)