-
Notifications
You must be signed in to change notification settings - Fork 262
TEST: Check non-integral slopes, intercepts in ArrayProxy API #847
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0f8842c
460c8d9
381ad1c
8cc2629
779f27b
b1f6e2c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -360,10 +360,13 @@ def _get_scaled(self, dtype, slicer): | |
scl_slope = np.asanyarray(self._slope) | ||
scl_inter = np.asanyarray(self._inter) | ||
use_dtype = scl_slope.dtype if dtype is None else dtype | ||
slope = scl_slope.astype(use_dtype) | ||
inter = scl_inter.astype(use_dtype) | ||
|
||
if np.can_cast(scl_slope, use_dtype): | ||
scl_slope = scl_slope.astype(use_dtype) | ||
if np.can_cast(scl_inter, use_dtype): | ||
scl_inter = scl_inter.astype(use_dtype) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unconditionally casting to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So if it can't cast, but the user asks to, should this maybe spit a warning out? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a helper method intended to do a best-effort downcast, but not to the detriment of accuracy. If you ask me to return |
||
# Read array and upcast as necessary for big slopes, intercepts | ||
scaled = apply_read_scaling(self._get_unscaled(slicer=slicer), slope, inter) | ||
scaled = apply_read_scaling(self._get_unscaled(slicer=slicer), scl_slope, scl_inter) | ||
if dtype is not None: | ||
scaled = scaled.astype(np.promote_types(scaled.dtype, dtype), copy=False) | ||
return scaled | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,14 +47,15 @@ | |
from .._h5py_compat import h5py, have_h5py | ||
from .. import ecat | ||
from .. import parrec | ||
from ..casting import have_binary128 | ||
|
||
from ..arrayproxy import ArrayProxy, is_proxy | ||
|
||
from nose import SkipTest | ||
from nose.tools import (assert_true, assert_false, assert_raises, | ||
assert_equal, assert_not_equal, assert_greater_equal) | ||
|
||
from numpy.testing import (assert_almost_equal, assert_array_equal) | ||
from numpy.testing import assert_almost_equal, assert_array_equal, assert_allclose | ||
|
||
from ..testing import data_path as DATA_PATH, assert_dt_equal | ||
|
||
|
@@ -142,7 +143,10 @@ def validate_get_scaled(self, pmaker, params): | |
|
||
for dtype in np.sctypes['float'] + np.sctypes['int'] + np.sctypes['uint']: | ||
out = prox.get_scaled(dtype=dtype) | ||
assert_almost_equal(out, params['arr_out']) | ||
# Half-precision is imprecise. Obviously. It's a bad idea, but don't break | ||
# the test over it. | ||
rtol = 1e-03 if dtype == np.float16 else 1e-05 | ||
assert_allclose(out, params['arr_out'].astype(out.dtype), rtol=rtol, atol=1e-08) | ||
assert_greater_equal(out.dtype, np.dtype(dtype)) | ||
# Shape matches expected shape | ||
assert_equal(out.shape, params['shape']) | ||
|
@@ -192,6 +196,7 @@ class TestAnalyzeProxyAPI(_TestProxyAPI): | |
shapes = ((2,), (2, 3), (2, 3, 4), (2, 3, 4, 5)) | ||
has_slope = False | ||
has_inter = False | ||
data_dtypes = (np.uint8, np.int16, np.int32, np.float32, np.complex64, np.float64) | ||
array_order = 'F' | ||
# Cannot set offset for Freesurfer | ||
settable_offset = True | ||
|
@@ -216,11 +221,12 @@ def obj_params(self): | |
offsets = (self.header_class().get_data_offset(),) | ||
else: | ||
offsets = (0, 16) | ||
slopes = (1., 2.) if self.has_slope else (1.,) | ||
inters = (0., 10.) if self.has_inter else (0.,) | ||
dtypes = (np.uint8, np.int16, np.float32) | ||
# For non-integral parameters, cast to float32 value can be losslessly cast | ||
# later, enabling exact checks, then back to float for consistency | ||
slopes = (1., 2., float(np.float32(3.1416))) if self.has_slope else (1.,) | ||
inters = (0., 10., float(np.float32(2.7183))) if self.has_inter else (0.,) | ||
effigies marked this conversation as resolved.
Show resolved
Hide resolved
|
||
for shape, dtype, offset, slope, inter in product(self.shapes, | ||
dtypes, | ||
self.data_dtypes, | ||
offsets, | ||
slopes, | ||
inters): | ||
|
@@ -262,7 +268,7 @@ def sio_func(): | |
dtype=dtype, | ||
dtype_out=dtype_out, | ||
arr=arr.copy(), | ||
arr_out=arr * slope + inter, | ||
arr_out=arr.astype(dtype_out) * slope + inter, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If This change ensures that we produce our expected array in the wider dtype. |
||
shape=shape, | ||
offset=offset, | ||
slope=slope, | ||
|
@@ -325,6 +331,10 @@ class TestSpm2AnalyzeProxyAPI(TestSpm99AnalyzeProxyAPI): | |
class TestNifti1ProxyAPI(TestSpm99AnalyzeProxyAPI): | ||
header_class = Nifti1Header | ||
has_inter = True | ||
data_dtypes = (np.uint8, np.int16, np.int32, np.float32, np.complex64, np.float64, | ||
np.int8, np.uint16, np.uint32, np.int64, np.uint64, np.complex128) | ||
if have_binary128(): | ||
data_dtypes.extend(np.float128, np.complex256) | ||
|
||
|
||
class TestMGHAPI(TestAnalyzeProxyAPI): | ||
|
@@ -334,6 +344,7 @@ class TestMGHAPI(TestAnalyzeProxyAPI): | |
has_inter = False | ||
settable_offset = False | ||
data_endian = '>' | ||
data_dtypes = (np.uint8, np.int16, np.int32, np.float32) | ||
|
||
|
||
class TestMinc1API(_TestProxyAPI): | ||
|
Uh oh!
There was an error while loading. Please reload this page.