@@ -35,6 +35,8 @@ def __init__(self, array, out_dtype=None, order='F')
35
35
WriterError , ScalingError , ArrayWriter ,
36
36
make_array_writer , get_slope_inter )
37
37
38
+ from ..casting import int_abs
39
+
38
40
from ..volumeutils import array_from_file , apply_read_scaling
39
41
40
42
from numpy .testing import (assert_array_almost_equal ,
@@ -171,9 +173,17 @@ def test_calculate_scale():
171
173
# Offset handles scaling when it can
172
174
aw = SIAW (npa ([- 2 , - 1 ], dtype = np .int8 ), np .uint8 )
173
175
assert_equal (get_slope_inter (aw ), (1.0 , - 2.0 ))
174
- # Sign flip handles this case
176
+ # Sign flip handles these cases
175
177
aw = SAW (npa ([- 2 , - 1 ], dtype = np .int8 ), np .uint8 )
176
178
assert_equal (get_slope_inter (aw ), (- 1.0 , 0.0 ))
179
+ aw = SAW (npa ([- 2 , 0 ], dtype = np .int8 ), np .uint8 )
180
+ assert_equal (get_slope_inter (aw ), (- 1.0 , 0.0 ))
181
+ # But not when min magnitude is too large (scaling mechanism kicks in)
182
+ aw = SAW (npa ([- 510 , 0 ], dtype = np .int16 ), np .uint8 )
183
+ assert_equal (get_slope_inter (aw ), (- 2.0 , 0.0 ))
184
+ # Or for floats (attempts to expand across range)
185
+ aw = SAW (npa ([- 2 , 0 ], dtype = np .float32 ), np .uint8 )
186
+ assert_not_equal (get_slope_inter (aw ), (- 1.0 , 0.0 ))
177
187
# Case where offset handles scaling
178
188
aw = SIAW (npa ([- 1 , 1 ], dtype = np .int8 ), np .uint8 )
179
189
assert_equal (get_slope_inter (aw ), (1.0 , - 1.0 ))
@@ -187,9 +197,12 @@ def test_calculate_scale():
187
197
def test_no_offset_scale ():
188
198
# Specific tests of no-offset scaling
189
199
SAW = SlopeArrayWriter
200
+ # Floating point
190
201
for data in ((- 128 , 127 ),
191
202
(- 128 , 126 ),
192
203
(- 128 , - 127 ),
204
+ (- 128 , 0 ),
205
+ (- 128 , - 1 ),
193
206
(126 , 127 ),
194
207
(- 127 , 127 )):
195
208
aw = SAW (np .array (data , dtype = np .float32 ), np .int8 )
@@ -200,6 +213,19 @@ def test_no_offset_scale():
200
213
assert_equal (aw .slope , 2 )
201
214
202
215
216
+ def test_with_offset_scale ():
217
+ # Tests of specific cases in slope, inter
218
+ SIAW = SlopeInterArrayWriter
219
+ aw = SIAW (np .array ([0 , 127 ], dtype = np .int8 ), np .uint8 )
220
+ assert_equal ((aw .slope , aw .inter ), (1 , 0 )) # in range
221
+ aw = SIAW (np .array ([- 1 , 126 ], dtype = np .int8 ), np .uint8 )
222
+ assert_equal ((aw .slope , aw .inter ), (1 , - 1 )) # offset only
223
+ aw = SIAW (np .array ([- 1 , 254 ], dtype = np .int16 ), np .uint8 )
224
+ assert_equal ((aw .slope , aw .inter ), (1 , - 1 )) # offset only
225
+ aw = SIAW (np .array ([- 1 , 255 ], dtype = np .int16 ), np .uint8 )
226
+ assert_not_equal ((aw .slope , aw .inter ), (1 , - 1 )) # Too big for offset only
227
+
228
+
203
229
def test_io_scaling ():
204
230
# Test scaling works for max, min when going from larger to smaller type,
205
231
# and from float to integer.
@@ -364,6 +390,51 @@ def test_float_int_min_max():
364
390
assert_true (np .allclose (arr , arr_back_sc ))
365
391
366
392
393
+ def test_int_int_min_max ():
394
+ # Conversion between (u)int and (u)int
395
+ eps = np .finfo (np .float64 ).eps
396
+ rtol = 1e-6
397
+ for in_dt in IUINT_TYPES :
398
+ iinf = np .iinfo (in_dt )
399
+ arr = np .array ([iinf .min , iinf .max ], dtype = in_dt )
400
+ for out_dt in IUINT_TYPES :
401
+ try :
402
+ aw = SlopeInterArrayWriter (arr , out_dt )
403
+ except ScalingError :
404
+ continue
405
+ arr_back_sc = round_trip (aw )
406
+ # integer allclose
407
+ adiff = int_abs (arr - arr_back_sc )
408
+ rdiff = adiff / (arr + eps )
409
+ assert_true (np .all (rdiff < rtol ))
410
+
411
+
412
+ def test_int_int_slope ():
413
+ # Conversion between (u)int and (u)int for slopes only
414
+ eps = np .finfo (np .float64 ).eps
415
+ rtol = 1e-7
416
+ for in_dt in IUINT_TYPES :
417
+ iinf = np .iinfo (in_dt )
418
+ for out_dt in IUINT_TYPES :
419
+ kinds = np .dtype (in_dt ).kind + np .dtype (out_dt ).kind
420
+ if kinds in ('ii' , 'uu' , 'ui' ):
421
+ arrs = (np .array ([iinf .min , iinf .max ], dtype = in_dt ),)
422
+ elif kinds == 'iu' :
423
+ arrs = (np .array ([iinf .min , 0 ], dtype = in_dt ),
424
+ np .array ([0 , iinf .max ], dtype = in_dt ))
425
+ for arr in arrs :
426
+ try :
427
+ aw = SlopeArrayWriter (arr , out_dt )
428
+ except ScalingError :
429
+ continue
430
+ assert_false (aw .slope == 0 )
431
+ arr_back_sc = round_trip (aw )
432
+ # integer allclose
433
+ adiff = int_abs (arr - arr_back_sc )
434
+ rdiff = adiff / (arr + eps )
435
+ assert_true (np .all (rdiff < rtol ))
436
+
437
+
367
438
def test_float_int_spread ():
368
439
# Test rounding error for spread of values
369
440
powers = np .arange (- 10 , 10 , 0.5 )
0 commit comments