|
15 | 15 |
|
16 | 16 | import pickle
|
17 | 17 | from io import BytesIO
|
| 18 | +from packaging.version import Version |
18 | 19 | from ..tmpdirs import InTemporaryDirectory
|
19 | 20 |
|
20 | 21 | import numpy as np
|
21 | 22 |
|
| 23 | +from .. import __version__ |
22 | 24 | from ..arrayproxy import (ArrayProxy, is_proxy, reshape_dataobj, get_obj_dtype)
|
23 | 25 | from ..openers import ImageOpener
|
24 | 26 | from ..nifti1 import Nifti1Header
|
| 27 | +from ..deprecator import ExpiredDeprecationError |
25 | 28 |
|
26 | 29 | from unittest import mock
|
27 | 30 |
|
@@ -57,6 +60,10 @@ def copy(self):
|
57 | 60 |
|
58 | 61 | class CArrayProxy(ArrayProxy):
|
59 | 62 | # C array memory layout
|
| 63 | + _default_order = 'C' |
| 64 | + |
| 65 | + |
| 66 | +class DeprecatedCArrayProxy(ArrayProxy): |
60 | 67 | order = 'C'
|
61 | 68 |
|
62 | 69 |
|
@@ -154,33 +161,87 @@ def test_nifti1_init():
|
154 | 161 | assert_array_equal(np.asarray(ap), arr * 2.0 + 10)
|
155 | 162 |
|
156 | 163 |
|
157 |
| -def test_proxy_slicing(): |
158 |
| - shapes = (15, 16, 17) |
159 |
| - for n_dim in range(1, len(shapes) + 1): |
160 |
| - shape = shapes[:n_dim] |
161 |
| - arr = np.arange(np.prod(shape)).reshape(shape) |
162 |
| - for offset in (0, 20): |
163 |
| - hdr = Nifti1Header() |
164 |
| - hdr.set_data_offset(offset) |
165 |
| - hdr.set_data_dtype(arr.dtype) |
166 |
| - hdr.set_data_shape(shape) |
167 |
| - for order, klass in ('F', ArrayProxy), ('C', CArrayProxy): |
168 |
| - fobj = BytesIO() |
169 |
| - fobj.write(b'\0' * offset) |
170 |
| - fobj.write(arr.tobytes(order=order)) |
171 |
| - prox = klass(fobj, hdr) |
172 |
| - for sliceobj in slicer_samples(shape): |
173 |
| - assert_array_equal(arr[sliceobj], prox[sliceobj]) |
174 |
| - # Check slicing works with scaling |
| 164 | +@pytest.mark.parametrize("n_dim", (1, 2, 3)) |
| 165 | +@pytest.mark.parametrize("offset", (0, 20)) |
| 166 | +def test_proxy_slicing(n_dim, offset): |
| 167 | + shape = (15, 16, 17)[:n_dim] |
| 168 | + arr = np.arange(np.prod(shape)).reshape(shape) |
| 169 | + hdr = Nifti1Header() |
| 170 | + hdr.set_data_offset(offset) |
| 171 | + hdr.set_data_dtype(arr.dtype) |
| 172 | + hdr.set_data_shape(shape) |
| 173 | + for order, klass in ('F', ArrayProxy), ('C', CArrayProxy): |
| 174 | + fobj = BytesIO() |
| 175 | + fobj.write(b'\0' * offset) |
| 176 | + fobj.write(arr.tobytes(order=order)) |
| 177 | + prox = klass(fobj, hdr) |
| 178 | + assert prox.order == order |
| 179 | + for sliceobj in slicer_samples(shape): |
| 180 | + assert_array_equal(arr[sliceobj], prox[sliceobj]) |
| 181 | + |
| 182 | + |
| 183 | +def test_proxy_slicing_with_scaling(): |
| 184 | + shape = (15, 16, 17) |
| 185 | + offset = 20 |
| 186 | + arr = np.arange(np.prod(shape)).reshape(shape) |
| 187 | + hdr = Nifti1Header() |
| 188 | + hdr.set_data_offset(offset) |
| 189 | + hdr.set_data_dtype(arr.dtype) |
| 190 | + hdr.set_data_shape(shape) |
175 | 191 | hdr.set_slope_inter(2.0, 1.0)
|
176 | 192 | fobj = BytesIO()
|
177 |
| - fobj.write(b'\0' * offset) |
| 193 | + fobj.write(bytes(offset)) |
178 | 194 | fobj.write(arr.tobytes(order='F'))
|
179 | 195 | prox = ArrayProxy(fobj, hdr)
|
180 | 196 | sliceobj = (None, slice(None), 1, -1)
|
181 | 197 | assert_array_equal(arr[sliceobj] * 2.0 + 1.0, prox[sliceobj])
|
182 | 198 |
|
183 | 199 |
|
| 200 | +@pytest.mark.parametrize("order", ("C", "F")) |
| 201 | +def test_order_override(order): |
| 202 | + shape = (15, 16, 17) |
| 203 | + arr = np.arange(np.prod(shape)).reshape(shape) |
| 204 | + fobj = BytesIO() |
| 205 | + fobj.write(arr.tobytes(order=order)) |
| 206 | + for klass in (ArrayProxy, CArrayProxy): |
| 207 | + prox = klass(fobj, (shape, arr.dtype), order=order) |
| 208 | + assert prox.order == order |
| 209 | + sliceobj = (None, slice(None), 1, -1) |
| 210 | + assert_array_equal(arr[sliceobj], prox[sliceobj]) |
| 211 | + |
| 212 | + |
| 213 | +def test_deprecated_order_classvar(): |
| 214 | + shape = (15, 16, 17) |
| 215 | + arr = np.arange(np.prod(shape)).reshape(shape) |
| 216 | + fobj = BytesIO() |
| 217 | + fobj.write(arr.tobytes(order='C')) |
| 218 | + sliceobj = (None, slice(None), 1, -1) |
| 219 | + |
| 220 | + # We don't really care about the original order, just that the behavior |
| 221 | + # of the deprecated mode matches the new behavior |
| 222 | + fprox = ArrayProxy(fobj, (shape, arr.dtype), order='F') |
| 223 | + cprox = ArrayProxy(fobj, (shape, arr.dtype), order='C') |
| 224 | + |
| 225 | + # Start raising errors when we crank the dev version |
| 226 | + if Version(__version__) >= Version('7.0.0.dev0'): |
| 227 | + cm = pytest.raises(ExpiredDeprecationError) |
| 228 | + else: |
| 229 | + cm = pytest.deprecated_call() |
| 230 | + |
| 231 | + with cm: |
| 232 | + prox = DeprecatedCArrayProxy(fobj, (shape, arr.dtype)) |
| 233 | + assert prox.order == 'C' |
| 234 | + assert_array_equal(prox[sliceobj], cprox[sliceobj]) |
| 235 | + with cm: |
| 236 | + prox = DeprecatedCArrayProxy(fobj, (shape, arr.dtype), order='C') |
| 237 | + assert prox.order == 'C' |
| 238 | + assert_array_equal(prox[sliceobj], cprox[sliceobj]) |
| 239 | + with cm: |
| 240 | + prox = DeprecatedCArrayProxy(fobj, (shape, arr.dtype), order='F') |
| 241 | + assert prox.order == 'F' |
| 242 | + assert_array_equal(prox[sliceobj], fprox[sliceobj]) |
| 243 | + |
| 244 | + |
184 | 245 | def test_is_proxy():
|
185 | 246 | # Test is_proxy function
|
186 | 247 | hdr = FunkyHeader((2, 3, 4))
|
|
0 commit comments