Skip to content

Commit 1b2d201

Browse files
committed
Merge pull request #254 from Eric89GXL/clean-tests
MRG: Cleaner tests In the process of working on #253 I was a little bit surprised by the number of warnings during testing. This cleans that up, and fixes a couple minor errors along the way.
2 parents 5e00fd2 + fb605c9 commit 1b2d201

20 files changed

+141
-85
lines changed

doc/source/coordinate_systems.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ the array.
5555
>>> slice_1 = epi_img_data[:, 30, :]
5656
>>> slice_2 = epi_img_data[:, :, 16]
5757
>>> show_slices([slice_0, slice_1, slice_2])
58-
>>> plt.suptitle("Center slices for EPI image")
58+
>>> plt.suptitle("Center slices for EPI image") # doctest: +SKIP
5959

6060
We collected an anatomical image in the same session. We can load that image
6161
and look at slices in the three axes:
@@ -77,7 +77,7 @@ and look at slices in the three axes:
7777
>>> show_slices([anat_img_data[28, :, :],
7878
... anat_img_data[:, 33, :],
7979
... anat_img_data[:, :, 28]])
80-
>>> plt.suptitle("Center slices for anatomical image")
80+
>>> plt.suptitle("Center slices for anatomical image") # doctest: +SKIP
8181

8282
As is usually the case, we had a different field of view for the anatomical
8383
scan, and so the anatomical image has a different shape, size, and orientation

doc/source/neuro_radio_conventions.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ Here we are showing the middle slice of :download:`an image
9595
>>> img_data = img.get_data()
9696
>>> a_slice = img_data[:, :, 28]
9797
>>> # Need transpose to put first axis left-right, second bottom-top
98-
>>> plt.imshow(a_slice.T, cmap="gray", origin="lower")
98+
>>> plt.imshow(a_slice.T, cmap="gray", origin="lower") # doctest: +SKIP
9999

100100
This slice does have the voxels from the right of isocenter towards the right
101101
of the screen, neurology style.

nibabel/imageglobals.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
logger = logging.getLogger('nibabel.global')
3131
logger.addHandler(logging.StreamHandler())
3232

33+
3334
class ErrorLevel(object):
3435
""" Context manager to set log error level
3536
"""
@@ -45,3 +46,15 @@ def __exit__(self, exc, value, tb):
4546
global error_level
4647
error_level = self._original_level
4748
return False
49+
50+
51+
class LoggingOutputSuppressor(object):
52+
"""Context manager to prevent global logger from printing"""
53+
def __enter__(self):
54+
self.orig_handlers = logger.handlers
55+
for handler in self.orig_handlers:
56+
logger.removeHandler(handler)
57+
58+
def __exit__(self, exc, value, tb):
59+
for handler in self.orig_handlers:
60+
logger.addHandler(handler)

nibabel/nicom/dicomwrappers.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ def rotation_matrix(self):
169169
"""
170170
iop = self.image_orient_patient
171171
s_norm = self.slice_normal
172-
if None in (iop, s_norm):
172+
if iop is None or s_norm is None:
173173
return None
174174
R = np.eye(3)
175175
# np.fliplr(iop) gives matrix F in
@@ -235,7 +235,7 @@ def slice_indicator(self):
235235
"""
236236
ipp = self.image_position
237237
s_norm = self.slice_normal
238-
if None in (ipp, s_norm):
238+
if ipp is None or s_norm is None:
239239
return None
240240
return np.inner(ipp, s_norm)
241241

@@ -304,7 +304,7 @@ def get_affine(self):
304304
# column, slice)
305305
vox = self.voxel_sizes
306306
ipp = self.image_position
307-
if None in (orient, vox, ipp):
307+
if any(p is None for p in (orient, vox, ipp)):
308308
raise WrapperError('Not enough information for affine')
309309
aff = np.eye(4)
310310
aff[:3, :3] = orient * np.array(vox)
@@ -786,7 +786,7 @@ def image_position(self):
786786
md_rows, md_cols = (self.get('Rows'), self.get('Columns'))
787787
iop = self.image_orient_patient
788788
pix_spacing = self.get('PixelSpacing')
789-
if None in (ipp, md_rows, md_cols, iop, pix_spacing):
789+
if any(x is None for x in (ipp, md_rows, md_cols, iop, pix_spacing)):
790790
return None
791791
# PixelSpacing values are python Decimal in pydicom 0.9.7
792792
pix_spacing = np.array(list(map(float, pix_spacing)))
@@ -881,8 +881,8 @@ def none_or_close(val1, val2, rtol=1e-5, atol=1e-6):
881881
>>> none_or_close([0,1], [0,2])
882882
False
883883
"""
884-
if (val1, val2) == (None, None):
884+
if val1 is None and val2 is None:
885885
return True
886-
if None in (val1, val2):
886+
if val1 is None or val2 is None:
887887
return False
888888
return np.allclose(val1, val2, rtol, atol)

nibabel/nifti1.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1061,7 +1061,7 @@ def set_slope_inter(self, slope, inter=None):
10611061
raise HeaderDataError('Slope cannot be 0 or infinite')
10621062
if inter in (np.inf, -np.inf):
10631063
raise HeaderDataError('Intercept cannot be infinite')
1064-
if np.diff(np.isnan([slope, inter])):
1064+
if np.isnan(slope) ^ np.isnan(inter):
10651065
raise HeaderDataError('None or both of slope, inter should be nan')
10661066
self._structarr['scl_slope'] = slope
10671067
self._structarr['scl_inter'] = inter

nibabel/testing/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from os.path import dirname, abspath, join as pjoin
1111

1212
import numpy as np
13+
from warnings import catch_warnings, simplefilter
1314

1415
# set path to example data
1516
data_path = abspath(pjoin(dirname(__file__), '..', 'tests', 'data'))
@@ -49,3 +50,12 @@ def assert_allclose_safely(a, b, match_nans=True):
4950
if b.dtype.kind in 'ui':
5051
b = b.astype(float)
5152
assert_true(np.allclose(a, b))
53+
54+
55+
class suppress_warnings(catch_warnings):
56+
""" Version of ``catch_warnings`` class that suppresses warnings
57+
"""
58+
def __enter__(self):
59+
res = super(suppress_warnings, self).__enter__()
60+
simplefilter('ignore')
61+
return res

nibabel/tests/test_analyze.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
assert_array_almost_equal)
3636

3737
from ..testing import (assert_equal, assert_not_equal, assert_true,
38-
assert_false, assert_raises, data_path)
38+
assert_false, assert_raises, data_path,
39+
suppress_warnings)
3940

4041
from .test_wrapstruct import _TestLabeledWrapStruct
4142
from . import test_spatialimages as tsi
@@ -45,6 +46,7 @@
4546

4647
PIXDIM0_MSG = 'pixdim[1,2,3] should be non-zero; setting 0 dims to 1'
4748

49+
4850
class TestAnalyzeHeader(_TestLabeledWrapStruct):
4951
header_class = AnalyzeHeader
5052
example_file = header_file
@@ -97,7 +99,8 @@ def test_empty(self):
9799

98100
def _set_something_into_hdr(self, hdr):
99101
# Called from test_bytes test method. Specific to the header data type
100-
hdr.set_data_shape((1, 2, 3))
102+
with suppress_warnings():
103+
hdr.set_data_shape((1, 2, 3))
101104

102105
def test_checks(self):
103106
# Test header checks
@@ -106,8 +109,9 @@ def test_checks(self):
106109
assert_equal(self._dxer(hdr_t), '')
107110
hdr = hdr_t.copy()
108111
hdr['sizeof_hdr'] = 1
109-
assert_equal(self._dxer(hdr), 'sizeof_hdr should be ' +
110-
str(self.sizeof_hdr))
112+
with suppress_warnings():
113+
assert_equal(self._dxer(hdr), 'sizeof_hdr should be ' +
114+
str(self.sizeof_hdr))
111115
hdr = hdr_t.copy()
112116
hdr['datatype'] = 0
113117
assert_equal(self._dxer(hdr), 'data code 0 not supported\n'
@@ -125,8 +129,9 @@ def test_log_checks(self):
125129
HC = self.header_class
126130
# magic
127131
hdr = HC()
128-
hdr['sizeof_hdr'] = 350 # severity 30
129-
fhdr, message, raiser = self.log_chk(hdr, 30)
132+
with suppress_warnings():
133+
hdr['sizeof_hdr'] = 350 # severity 30
134+
fhdr, message, raiser = self.log_chk(hdr, 30)
130135
assert_equal(fhdr['sizeof_hdr'], self.sizeof_hdr)
131136
assert_equal(message,
132137
'sizeof_hdr should be {0}; set sizeof_hdr to {0}'.format(
@@ -139,15 +144,16 @@ def test_log_checks(self):
139144
# datatype not recognized
140145
hdr = HC()
141146
hdr['datatype'] = -1 # severity 40
142-
fhdr, message, raiser = self.log_chk(hdr, 40)
147+
with suppress_warnings():
148+
fhdr, message, raiser = self.log_chk(hdr, 40)
143149
assert_equal(message, 'data code -1 not recognized; '
144150
'not attempting fix')
145151
assert_raises(*raiser)
146152
# datatype not supported
147153
hdr['datatype'] = 255 # severity 40
148154
fhdr, message, raiser = self.log_chk(hdr, 40)
149155
assert_equal(message, 'data code 255 not supported; '
150-
'not attempting fix')
156+
'not attempting fix')
151157
assert_raises(*raiser)
152158
# bitpix
153159
hdr = HC()

nibabel/tests/test_arraywriters.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from platform import python_compiler, machine
99
from distutils.version import LooseVersion
1010
import itertools
11-
1211
import numpy as np
1312

1413
from ..externals.six import BytesIO
@@ -28,7 +27,7 @@
2827
assert_equal, assert_not_equal,
2928
assert_raises)
3029

31-
from ..testing import assert_allclose_safely
30+
from ..testing import assert_allclose_safely, suppress_warnings
3231
from ..checkwarns import ErrorWarnings
3332

3433

@@ -135,8 +134,9 @@ def test_no_scaling():
135134
kwargs = (dict(check_scaling=False) if awt == ArrayWriter
136135
else dict(calc_scale=False))
137136
aw = awt(arr, out_dtype, **kwargs)
138-
back_arr = round_trip(aw)
139-
exp_back = arr.astype(float)
137+
with suppress_warnings(): # cast to real from cplx
138+
back_arr = round_trip(aw)
139+
exp_back = arr.astype(float)
140140
if out_dtype in IUINT_TYPES:
141141
exp_back = np.round(exp_back)
142142
if hasattr(aw, 'slope') and in_dtype in FLOAT_TYPES:
@@ -642,7 +642,8 @@ def test_float_int_min_max():
642642
continue
643643
for out_dt in IUINT_TYPES:
644644
try:
645-
aw = SlopeInterArrayWriter(arr, out_dt)
645+
with suppress_warnings(): # overflow
646+
aw = SlopeInterArrayWriter(arr, out_dt)
646647
except ScalingError:
647648
continue
648649
arr_back_sc = round_trip(aw)

nibabel/tests/test_casting.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
import os
44

55
from platform import machine
6-
76
import numpy as np
87

98
from ..casting import (float_to_int, shared_range, CastingError, int_to_float,
109
as_int, int_abs, floor_log2, able_int_type, best_float,
1110
ulp, longdouble_precision_improved)
11+
from ..testing import suppress_warnings
1212

1313
from numpy.testing import (assert_array_almost_equal, assert_array_equal)
1414

@@ -23,7 +23,8 @@ def test_shared_range():
2323
# (if this system generates that) or something smaller (because of
2424
# overflow)
2525
mn, mx = shared_range(ft, it)
26-
ovs = ft(mx) + np.arange(2048, dtype=ft)
26+
with suppress_warnings():
27+
ovs = ft(mx) + np.arange(2048, dtype=ft)
2728
# Float16 can overflow to inf
2829
bit_bigger = ovs[np.isfinite(ovs)].astype(it)
2930
casted_mx = ft(mx).astype(it)
@@ -51,7 +52,8 @@ def test_shared_range():
5152
assert_equal(mn, 0)
5253
continue
5354
# And something larger for the minimum
54-
ovs = ft(mn) - np.arange(2048, dtype=ft)
55+
with suppress_warnings(): # overflow
56+
ovs = ft(mn) - np.arange(2048, dtype=ft)
5557
# Float16 can overflow to inf
5658
bit_smaller = ovs[np.isfinite(ovs)].astype(it)
5759
casted_mn = ft(mn).astype(it)

nibabel/tests/test_ecat.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,20 @@
1616
from ..ecat import EcatHeader, EcatMlist, EcatSubHeader, EcatImage
1717

1818
from unittest import TestCase
19-
2019
from nose.tools import (assert_true, assert_false, assert_equal,
2120
assert_not_equal, assert_raises)
2221

2322
from numpy.testing import assert_array_equal, assert_array_almost_equal
2423

25-
from ..testing import data_path
24+
from ..testing import data_path, suppress_warnings
2625
from ..tmpdirs import InTemporaryDirectory
2726

2827
from .test_wrapstruct import _TestWrapStructBase
2928
from .test_fileslice import slicer_samples
3029

3130
ecat_file = os.path.join(data_path, 'tinypet.v')
3231

32+
3333
class TestEcatHeader(_TestWrapStructBase):
3434
header_class = EcatHeader
3535
example_file = ecat_file
@@ -111,7 +111,8 @@ def test_mlist(self):
111111
6.01670000e+04, 1.00000000e+00],
112112
[ 1.68427580e+07, 6.01680000e+04,
113113
7.22000000e+04, 1.00000000e+00]])
114-
assert_true(badordermlist.get_frame_order()[0][0] == 1)
114+
with suppress_warnings(): # STORED order
115+
assert_true(badordermlist.get_frame_order()[0][0] == 1)
115116

116117
def test_mlist_errors(self):
117118
fid = open(self.example_file, 'rb')
@@ -130,18 +131,21 @@ def test_mlist_errors(self):
130131
6.01670000e+04, 1.00000000e+00],
131132
[ 1.68427580e+07, 6.01680000e+04,
132133
7.22000000e+04, 1.00000000e+00]])
133-
series_framenumbers = mlist.get_series_framenumbers()
134+
with suppress_warnings(): # STORED order
135+
series_framenumbers = mlist.get_series_framenumbers()
134136
# first frame stored was actually 2nd frame acquired
135137
assert_true(series_framenumbers[0] == 2)
136138
order = [series_framenumbers[x] for x in sorted(series_framenumbers)]
137139
# true series order is [2,1,3,4,5,6], note counting starts at 1
138140
assert_true(order == [2, 1, 3, 4, 5, 6])
139141
mlist._mlist[0,0] = 0
140-
frames_order = mlist.get_frame_order()
142+
with suppress_warnings():
143+
frames_order = mlist.get_frame_order()
141144
neworder =[frames_order[x][0] for x in sorted(frames_order)]
142145
assert_true(neworder == [1, 2, 3, 4, 5])
143-
assert_raises(IOError,
144-
mlist.get_series_framenumbers)
146+
with suppress_warnings():
147+
assert_raises(IOError,
148+
mlist.get_series_framenumbers)
145149

146150

147151

@@ -178,6 +182,7 @@ def test_subheader(self):
178182
ecat_calib_factor = self.hdr['ecat_calibration_factor']
179183
assert_equal(ecat_calib_factor, 25007614.0)
180184

185+
181186
class TestEcatImage(TestCase):
182187
image_class = EcatImage
183188
example_file = ecat_file

0 commit comments

Comments
 (0)