@@ -195,156 +195,20 @@ class DataInterfaceMixin(GetSetDtypeMixin):
195
195
Use this mixin if your image has a ``dataobj`` property that contains an
196
196
array or an array-like thing.
197
197
"""
198
+ meth_names = ('get_fdata' , 'get_data' )
199
+
198
200
def validate_data_interface (self , imaker , params ):
199
201
# Check get data returns array, and caches
200
202
img = imaker ()
201
203
assert_equal (img .shape , img .dataobj .shape )
202
204
assert_data_similar (img .dataobj , params )
203
- meth_names = ('get_fdata' , 'get_data' )
204
- for meth_name in meth_names :
205
+ for meth_name in self .meth_names :
205
206
if params ['is_proxy' ]:
206
- # Parameters assert this is an array proxy
207
- img = imaker ()
208
- # Does is_proxy agree?
209
- assert_true (is_proxy (img .dataobj ))
210
- # Confirm it is not a numpy array
211
- assert_false (isinstance (img .dataobj , np .ndarray ))
212
- # Confirm it can be converted to a numpy array with asarray
213
- proxy_data = np .asarray (img .dataobj )
214
- proxy_copy = proxy_data .copy ()
215
- # Not yet cached, proxy image: in_memory is False
216
- assert_false (img .in_memory )
217
- # Load with caching='unchanged'
218
- method = getattr (img , meth_name )
219
- data = method (caching = 'unchanged' )
220
- # Still not cached
221
- assert_false (img .in_memory )
222
- # Default load, does caching
223
- data = method ()
224
- # Data now cached. in_memory is True if either of the get_data
225
- # or get_fdata caches are not-None
226
- assert_true (img .in_memory )
227
- # We previously got proxy_data from disk, but data, which we
228
- # have just fetched, is a fresh copy.
229
- assert_false (proxy_data is data )
230
- # asarray on dataobj, applied above, returns same numerical
231
- # values. This might not be true get_fdata operating on huge
232
- # integers, but lets assume that's not true here.
233
- assert_array_equal (proxy_data , data )
234
- # Now caching='unchanged' does nothing, returns cached version
235
- data_again = method (caching = 'unchanged' )
236
- assert_true (data is data_again )
237
- # caching='fill' does nothing because the cache is already full
238
- data_yet_again = method (caching = 'fill' )
239
- assert_true (data is data_yet_again )
240
- # changing array data does not change proxy data, or reloaded
241
- # data
242
- data [:] = 42
243
- assert_array_equal (proxy_data , proxy_copy )
244
- assert_array_equal (np .asarray (img .dataobj ), proxy_copy )
245
- # It does change the result of get_data
246
- assert_array_equal (method (), 42 )
247
- # until we uncache
248
- img .uncache ()
249
- # Which unsets in_memory
250
- assert_false (img .in_memory )
251
- assert_array_equal (method (), proxy_copy )
252
- # Check caching='fill' does cache data
253
- img = imaker ()
254
- method = getattr (img , meth_name )
255
- assert_false (img .in_memory )
256
- data = method (caching = 'fill' )
257
- assert_true (img .in_memory )
258
- data_again = method ()
259
- assert_true (data is data_again )
260
- # Check the interaction of caching with get_data, get_fdata.
261
- # Caching for `get_data` should have no effect on caching for
262
- # get_fdata, and vice versa.
263
- # Modify the cached data
264
- data [:] = 43
265
- # Load using the other data fetch method
266
- other_name = set (meth_names ).difference ({meth_name }).pop ()
267
- other_method = getattr (img , other_name )
268
- other_data = other_method ()
269
- # We get the original data, not the modified cache
270
- assert_array_equal (proxy_data , other_data )
271
- assert_false (np .all (data == other_data ))
272
- # We can modify the other cache, without affecting the first
273
- other_data [:] = 44
274
- assert_array_equal (other_method (), 44 )
275
- assert_false (np .all (method () == other_method ()))
276
- # Check that caching refreshes for new floating point type.
277
- if meth_name == 'get_fdata' :
278
- img .uncache ()
279
- fdata = img .get_fdata ()
280
- assert_equal (fdata .dtype , np .float64 )
281
- fdata [:] = 42
282
- fdata_back = img .get_fdata ()
283
- assert_array_equal (fdata_back , 42 )
284
- assert_equal (fdata_back .dtype , np .float64 )
285
- # New data dtype, no caching, doesn't use or alter cache
286
- fdata_new_dt = img .get_fdata (caching = 'unchanged' , dtype = 'f4' )
287
- # We get back the original read, not the modified cache
288
- assert_array_equal (fdata_new_dt , proxy_data .astype ('f4' ))
289
- assert_equal (fdata_new_dt .dtype , np .float32 )
290
- # The original cache stays in place, for default float64
291
- assert_array_equal (img .get_fdata (), 42 )
292
- # And for not-default float32, because we haven't cached
293
- fdata_new_dt [:] = 43
294
- fdata_new_dt = img .get_fdata (caching = 'unchanged' , dtype = 'f4' )
295
- assert_array_equal (fdata_new_dt , proxy_data .astype ('f4' ))
296
- # Until we reset with caching='fill', at which point we
297
- # drop the original float64 cache, and have a float32 cache
298
- fdata_new_dt = img .get_fdata (caching = 'fill' , dtype = 'f4' )
299
- assert_array_equal (fdata_new_dt , proxy_data .astype ('f4' ))
300
- # We're using the cache, for dtype='f4' reads
301
- fdata_new_dt [:] = 43
302
- assert_array_equal (img .get_fdata (dtype = 'f4' ), 43 )
303
- # We've lost the cache for float64 reads (no longer 42)
304
- assert_array_equal (img .get_fdata (), proxy_data )
305
- else : # not proxy
306
- for caching in (None , 'fill' , 'unchanged' ):
307
- img = imaker ()
308
- method = getattr (img , meth_name )
309
- get_data_func = (method if caching is None else
310
- partial (method , caching = caching ))
311
- assert_true (isinstance (img .dataobj , np .ndarray ))
312
- assert_true (img .in_memory )
313
- data = get_data_func ()
314
- # Returned data same object as underlying dataobj if using
315
- # old ``get_data`` method, or using newer ``get_fdata``
316
- # method, where original array was float64.
317
- dataobj_is_data = (img .dataobj .dtype == np .float64
318
- or method == img .get_data )
319
- # Set something to the output array.
320
- data [:] = 42
321
- get_result_changed = np .all (get_data_func () == 42 )
322
- assert_equal (get_result_changed ,
323
- dataobj_is_data or caching != 'unchanged' )
324
- if dataobj_is_data :
325
- assert_true (data is img .dataobj )
326
- # Changing array data changes
327
- # data
328
- assert_array_equal (np .asarray (img .dataobj ), 42 )
329
- # Uncache has no effect
330
- img .uncache ()
331
- assert_array_equal (get_data_func (), 42 )
332
- else :
333
- assert_false (data is img .dataobj )
334
- assert_false (np .all (np .asarray (img .dataobj ) == 42 ))
335
- # Uncache does have an effect
336
- img .uncache ()
337
- assert_false (np .all (get_data_func () == 42 ))
338
- # in_memory is always true for array images, regardless of
339
- # cache state.
340
- img .uncache ()
341
- assert_true (img .in_memory )
342
- # Values to get_(f)data caching parameter must be 'fill' or
343
- # 'unchanged'
344
- assert_raises (ValueError , img .get_data , caching = 'something' )
345
- assert_raises (ValueError , img .get_fdata , caching = 'something' )
207
+ self ._check_proxy_interface (imaker , meth_name )
208
+ else : # Array image
209
+ self ._check_array_interface (imaker , meth_name )
346
210
# Data shape is same as image shape
347
- assert_equal (img .shape , method ().shape )
211
+ assert_equal (img .shape , getattr ( img , meth_name ) ().shape )
348
212
# Values to get_data caching parameter must be 'fill' or
349
213
# 'unchanged'
350
214
assert_raises (ValueError , img .get_data , caching = 'something' )
@@ -354,6 +218,155 @@ def validate_data_interface(self, imaker, params):
354
218
# So is in_memory
355
219
assert_raises (AttributeError , setattr , img , 'in_memory' , False )
356
220
221
+ def _check_proxy_interface (self , imaker , meth_name ):
222
+ # Parameters assert this is an array proxy
223
+ img = imaker ()
224
+ # Does is_proxy agree?
225
+ assert_true (is_proxy (img .dataobj ))
226
+ # Confirm it is not a numpy array
227
+ assert_false (isinstance (img .dataobj , np .ndarray ))
228
+ # Confirm it can be converted to a numpy array with asarray
229
+ proxy_data = np .asarray (img .dataobj )
230
+ proxy_copy = proxy_data .copy ()
231
+ # Not yet cached, proxy image: in_memory is False
232
+ assert_false (img .in_memory )
233
+ # Load with caching='unchanged'
234
+ method = getattr (img , meth_name )
235
+ data = method (caching = 'unchanged' )
236
+ # Still not cached
237
+ assert_false (img .in_memory )
238
+ # Default load, does caching
239
+ data = method ()
240
+ # Data now cached. in_memory is True if either of the get_data
241
+ # or get_fdata caches are not-None
242
+ assert_true (img .in_memory )
243
+ # We previously got proxy_data from disk, but data, which we
244
+ # have just fetched, is a fresh copy.
245
+ assert_false (proxy_data is data )
246
+ # asarray on dataobj, applied above, returns same numerical
247
+ # values. This might not be true get_fdata operating on huge
248
+ # integers, but lets assume that's not true here.
249
+ assert_array_equal (proxy_data , data )
250
+ # Now caching='unchanged' does nothing, returns cached version
251
+ data_again = method (caching = 'unchanged' )
252
+ assert_true (data is data_again )
253
+ # caching='fill' does nothing because the cache is already full
254
+ data_yet_again = method (caching = 'fill' )
255
+ assert_true (data is data_yet_again )
256
+ # changing array data does not change proxy data, or reloaded
257
+ # data
258
+ data [:] = 42
259
+ assert_array_equal (proxy_data , proxy_copy )
260
+ assert_array_equal (np .asarray (img .dataobj ), proxy_copy )
261
+ # It does change the result of get_data
262
+ assert_array_equal (method (), 42 )
263
+ # until we uncache
264
+ img .uncache ()
265
+ # Which unsets in_memory
266
+ assert_false (img .in_memory )
267
+ assert_array_equal (method (), proxy_copy )
268
+ # Check caching='fill' does cache data
269
+ img = imaker ()
270
+ method = getattr (img , meth_name )
271
+ assert_false (img .in_memory )
272
+ data = method (caching = 'fill' )
273
+ assert_true (img .in_memory )
274
+ data_again = method ()
275
+ assert_true (data is data_again )
276
+ # Check the interaction of caching with get_data, get_fdata.
277
+ # Caching for `get_data` should have no effect on caching for
278
+ # get_fdata, and vice versa.
279
+ # Modify the cached data
280
+ data [:] = 43
281
+ # Load using the other data fetch method
282
+ other_name = set (self .meth_names ).difference ({meth_name }).pop ()
283
+ other_method = getattr (img , other_name )
284
+ other_data = other_method ()
285
+ # We get the original data, not the modified cache
286
+ assert_array_equal (proxy_data , other_data )
287
+ assert_false (np .all (data == other_data ))
288
+ # We can modify the other cache, without affecting the first
289
+ other_data [:] = 44
290
+ assert_array_equal (other_method (), 44 )
291
+ assert_false (np .all (method () == other_method ()))
292
+ if meth_name != 'get_fdata' :
293
+ return
294
+ # Check that caching refreshes for new floating point type.
295
+ img .uncache ()
296
+ fdata = img .get_fdata ()
297
+ assert_equal (fdata .dtype , np .float64 )
298
+ fdata [:] = 42
299
+ fdata_back = img .get_fdata ()
300
+ assert_array_equal (fdata_back , 42 )
301
+ assert_equal (fdata_back .dtype , np .float64 )
302
+ # New data dtype, no caching, doesn't use or alter cache
303
+ fdata_new_dt = img .get_fdata (caching = 'unchanged' , dtype = 'f4' )
304
+ # We get back the original read, not the modified cache
305
+ assert_array_equal (fdata_new_dt , proxy_data .astype ('f4' ))
306
+ assert_equal (fdata_new_dt .dtype , np .float32 )
307
+ # The original cache stays in place, for default float64
308
+ assert_array_equal (img .get_fdata (), 42 )
309
+ # And for not-default float32, because we haven't cached
310
+ fdata_new_dt [:] = 43
311
+ fdata_new_dt = img .get_fdata (caching = 'unchanged' , dtype = 'f4' )
312
+ assert_array_equal (fdata_new_dt , proxy_data .astype ('f4' ))
313
+ # Until we reset with caching='fill', at which point we
314
+ # drop the original float64 cache, and have a float32 cache
315
+ fdata_new_dt = img .get_fdata (caching = 'fill' , dtype = 'f4' )
316
+ assert_array_equal (fdata_new_dt , proxy_data .astype ('f4' ))
317
+ # We're using the cache, for dtype='f4' reads
318
+ fdata_new_dt [:] = 43
319
+ assert_array_equal (img .get_fdata (dtype = 'f4' ), 43 )
320
+ # We've lost the cache for float64 reads (no longer 42)
321
+ assert_array_equal (img .get_fdata (), proxy_data )
322
+
323
+ def _check_array_interface (self , imaker , meth_name ):
324
+ for caching in (None , 'fill' , 'unchanged' ):
325
+ self ._check_array_caching (imaker , meth_name , caching )
326
+ # Values to get_(f)data caching parameter must be 'fill' or
327
+ # 'unchanged'
328
+ img = imaker ()
329
+ for meth_name in self .meth_names :
330
+ method = getattr (img , meth_name )
331
+ assert_raises (ValueError , method , caching = 'something' )
332
+
333
+ def _check_array_caching (self , imaker , meth_name , caching ):
334
+ img = imaker ()
335
+ method = getattr (img , meth_name )
336
+ get_data_func = (method if caching is None else
337
+ partial (method , caching = caching ))
338
+ assert_true (isinstance (img .dataobj , np .ndarray ))
339
+ assert_true (img .in_memory )
340
+ data = get_data_func ()
341
+ # Returned data same object as underlying dataobj if using
342
+ # old ``get_data`` method, or using newer ``get_fdata``
343
+ # method, where original array was float64.
344
+ dataobj_is_data = (img .dataobj .dtype == np .float64
345
+ or method == img .get_data )
346
+ # Set something to the output array.
347
+ data [:] = 42
348
+ get_result_changed = np .all (get_data_func () == 42 )
349
+ assert_equal (get_result_changed ,
350
+ dataobj_is_data or caching != 'unchanged' )
351
+ if dataobj_is_data :
352
+ assert_true (data is img .dataobj )
353
+ # Changing array data changes
354
+ # data
355
+ assert_array_equal (np .asarray (img .dataobj ), 42 )
356
+ # Uncache has no effect
357
+ img .uncache ()
358
+ assert_array_equal (get_data_func (), 42 )
359
+ else :
360
+ assert_false (data is img .dataobj )
361
+ assert_false (np .all (np .asarray (img .dataobj ) == 42 ))
362
+ # Uncache does have an effect
363
+ img .uncache ()
364
+ assert_false (np .all (get_data_func () == 42 ))
365
+ # in_memory is always true for array images, regardless of
366
+ # cache state.
367
+ img .uncache ()
368
+ assert_true (img .in_memory )
369
+
357
370
def validate_data_deprecated (self , imaker , params ):
358
371
# Check _data property still exists, but raises warning
359
372
img = imaker ()
@@ -385,7 +398,6 @@ def validate_shape_deprecated(self, imaker, params):
385
398
assert_equal (len (w ), 1 )
386
399
387
400
388
-
389
401
class HeaderShapeMixin (object ):
390
402
""" Tests that header shape can be set and got
391
403
0 commit comments