@@ -200,7 +200,8 @@ def validate_data_interface(self, imaker, params):
200200 img = imaker ()
201201 assert_equal (img .shape , img .dataobj .shape )
202202 assert_data_similar (img .dataobj , params )
203- for meth_name in ('get_fdata' , 'get_data' ):
203+ meth_names = ('get_fdata' , 'get_data' )
204+ for meth_name in meth_names :
204205 if params ['is_proxy' ]:
205206 # Parameters assert this is an array proxy
206207 img = imaker ()
@@ -220,9 +221,16 @@ def validate_data_interface(self, imaker, params):
220221 assert_false (img .in_memory )
221222 # Default load, does caching
222223 data = method ()
223- # Data now cached
224+ # Data now cached. in_memory is True if either of the get_data
225+ # or get_fdata caches are not-None
224226 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.
225229 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 )
226234 # Now caching='unchanged' does nothing, returns cached version
227235 data_again = method (caching = 'unchanged' )
228236 assert_true (data is data_again )
@@ -249,6 +257,51 @@ def validate_data_interface(self, imaker, params):
249257 assert_true (img .in_memory )
250258 data_again = method ()
251259 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 )
252305 else : # not proxy
253306 for caching in (None , 'fill' , 'unchanged' ):
254307 img = imaker ()
0 commit comments