4747from .._h5py_compat import h5py , have_h5py
4848from .. import ecat
4949from .. import parrec
50+ from ..casting import have_binary128
5051
5152from ..arrayproxy import ArrayProxy , is_proxy
5253
5354from nose import SkipTest
5455from nose .tools import (assert_true , assert_false , assert_raises ,
5556 assert_equal , assert_not_equal , assert_greater_equal )
5657
57- from numpy .testing import ( assert_almost_equal , assert_array_equal )
58+ from numpy .testing import assert_almost_equal , assert_array_equal , assert_allclose
5859
5960from ..testing import data_path as DATA_PATH , assert_dt_equal
6061
@@ -142,7 +143,10 @@ def validate_get_scaled(self, pmaker, params):
142143
143144 for dtype in np .sctypes ['float' ] + np .sctypes ['int' ] + np .sctypes ['uint' ]:
144145 out = prox .get_scaled (dtype = dtype )
145- assert_almost_equal (out , params ['arr_out' ])
146+ # Half-precision is imprecise. Obviously. It's a bad idea, but don't break
147+ # the test over it.
148+ rtol = 1e-03 if dtype == np .float16 else 1e-05
149+ assert_allclose (out , params ['arr_out' ].astype (out .dtype ), rtol = rtol , atol = 1e-08 )
146150 assert_greater_equal (out .dtype , np .dtype (dtype ))
147151 # Shape matches expected shape
148152 assert_equal (out .shape , params ['shape' ])
@@ -192,6 +196,7 @@ class TestAnalyzeProxyAPI(_TestProxyAPI):
192196 shapes = ((2 ,), (2 , 3 ), (2 , 3 , 4 ), (2 , 3 , 4 , 5 ))
193197 has_slope = False
194198 has_inter = False
199+ data_dtypes = (np .uint8 , np .int16 , np .int32 , np .float32 , np .complex64 , np .float64 )
195200 array_order = 'F'
196201 # Cannot set offset for Freesurfer
197202 settable_offset = True
@@ -216,11 +221,12 @@ def obj_params(self):
216221 offsets = (self .header_class ().get_data_offset (),)
217222 else :
218223 offsets = (0 , 16 )
219- slopes = (1. , 2. ) if self .has_slope else (1. ,)
220- inters = (0. , 10. ) if self .has_inter else (0. ,)
221- dtypes = (np .uint8 , np .int16 , np .float32 )
224+ # For non-integral parameters, cast to float32 value can be losslessly cast
225+ # later, enabling exact checks, then back to float for consistency
226+ slopes = (1. , 2. , float (np .float32 (3.1416 ))) if self .has_slope else (1. ,)
227+ inters = (0. , 10. , float (np .float32 (2.7183 ))) if self .has_inter else (0. ,)
222228 for shape , dtype , offset , slope , inter in product (self .shapes ,
223- dtypes ,
229+ self . data_dtypes ,
224230 offsets ,
225231 slopes ,
226232 inters ):
@@ -262,7 +268,7 @@ def sio_func():
262268 dtype = dtype ,
263269 dtype_out = dtype_out ,
264270 arr = arr .copy (),
265- arr_out = arr * slope + inter ,
271+ arr_out = arr . astype ( dtype_out ) * slope + inter ,
266272 shape = shape ,
267273 offset = offset ,
268274 slope = slope ,
@@ -325,6 +331,10 @@ class TestSpm2AnalyzeProxyAPI(TestSpm99AnalyzeProxyAPI):
325331class TestNifti1ProxyAPI (TestSpm99AnalyzeProxyAPI ):
326332 header_class = Nifti1Header
327333 has_inter = True
334+ data_dtypes = (np .uint8 , np .int16 , np .int32 , np .float32 , np .complex64 , np .float64 ,
335+ np .int8 , np .uint16 , np .uint32 , np .int64 , np .uint64 , np .complex128 )
336+ if have_binary128 ():
337+ data_dtypes .extend (np .float128 , np .complex256 )
328338
329339
330340class TestMGHAPI (TestAnalyzeProxyAPI ):
@@ -334,6 +344,7 @@ class TestMGHAPI(TestAnalyzeProxyAPI):
334344 has_inter = False
335345 settable_offset = False
336346 data_endian = '>'
347+ data_dtypes = (np .uint8 , np .int16 , np .int32 , np .float32 )
337348
338349
339350class TestMinc1API (_TestProxyAPI ):
0 commit comments