@@ -306,57 +306,57 @@ def test_int_int_scaling(self):
306306 img_rt = bytesio_round_trip (img )
307307 assert_array_equal (img_rt .get_fdata (), np .clip (arr , 0 , 255 ))
308308
309- def test_no_scaling (self ):
309+ # NOTE: Need to check complex scaling
310+ @pytest .mark .parametrize ('in_dtype' , FLOAT_TYPES + IUINT_TYPES )
311+ def test_no_scaling (self , in_dtype , supported_dtype ):
310312 # Test writing image converting types when not calculating scaling
311313 img_class = self .image_class
312314 hdr_class = img_class .header_class
313315 hdr = hdr_class ()
314- supported_types = supported_np_types (hdr )
315316 # Any old non-default slope and intercept
316317 slope = 2
317318 inter = 10 if hdr .has_data_intercept else 0
318- for in_dtype , out_dtype in itertools .product (FLOAT_TYPES + IUINT_TYPES , supported_types ):
319- # Need to check complex scaling
320- mn_in , mx_in = _dt_min_max (in_dtype )
321- arr = np .array ([mn_in , - 1 , 0 , 1 , 10 , mx_in ], dtype = in_dtype )
322- img = img_class (arr , np .eye (4 ), hdr )
323- img .set_data_dtype (out_dtype )
324- # Setting the scaling means we don't calculate it later
325- img .header .set_slope_inter (slope , inter )
326- with np .errstate (invalid = 'ignore' ):
327- rt_img = bytesio_round_trip (img )
328- with suppress_warnings (): # invalid mult
329- back_arr = np .asanyarray (rt_img .dataobj )
330- exp_back = arr .copy ()
331- # If converting to floating point type, casting is direct.
332- # Otherwise we will need to do float-(u)int casting at some point
333- if out_dtype in IUINT_TYPES :
334- if in_dtype in FLOAT_TYPES :
335- # Working precision is (at least) float
336- exp_back = exp_back .astype (float )
337- # Float to iu conversion will always round, clip
338- with np .errstate (invalid = 'ignore' ):
339- exp_back = np .round (exp_back )
340- if in_dtype in FLOAT_TYPES :
341- # Clip to shared range of working precision
342- exp_back = np .clip (exp_back , * shared_range (float , out_dtype ))
343- else : # iu input and output type
344- # No scaling, never gets converted to float.
345- # Does get clipped to range of output type
346- mn_out , mx_out = _dt_min_max (out_dtype )
347- if (mn_in , mx_in ) != (mn_out , mx_out ):
348- # Use smaller of input, output range to avoid np.clip
349- # upcasting the array because of large clip limits.
350- exp_back = np .clip (exp_back , max (mn_in , mn_out ), min (mx_in , mx_out ))
351- if out_dtype in COMPLEX_TYPES :
352- # always cast to real from complex
353- exp_back = exp_back .astype (out_dtype )
354- else :
355- # Cast to working precision
319+
320+ mn_in , mx_in = _dt_min_max (in_dtype )
321+ arr = np .array ([mn_in , - 1 , 0 , 1 , 10 , mx_in ], dtype = in_dtype )
322+ img = img_class (arr , np .eye (4 ), hdr )
323+ img .set_data_dtype (supported_dtype )
324+ # Setting the scaling means we don't calculate it later
325+ img .header .set_slope_inter (slope , inter )
326+ with np .errstate (invalid = 'ignore' ):
327+ rt_img = bytesio_round_trip (img )
328+ with suppress_warnings (): # invalid mult
329+ back_arr = np .asanyarray (rt_img .dataobj )
330+ exp_back = arr .copy ()
331+ # If converting to floating point type, casting is direct.
332+ # Otherwise we will need to do float-(u)int casting at some point
333+ if supported_dtype in IUINT_TYPES :
334+ if in_dtype in FLOAT_TYPES :
335+ # Working precision is (at least) float
356336 exp_back = exp_back .astype (float )
357- # Allow for small differences in large numbers
358- with suppress_warnings (): # invalid value
359- assert_allclose_safely (back_arr , exp_back * slope + inter )
337+ # Float to iu conversion will always round, clip
338+ with np .errstate (invalid = 'ignore' ):
339+ exp_back = np .round (exp_back )
340+ if in_dtype in FLOAT_TYPES :
341+ # Clip to shared range of working precision
342+ exp_back = np .clip (exp_back , * shared_range (float , supported_dtype ))
343+ else : # iu input and output type
344+ # No scaling, never gets converted to float.
345+ # Does get clipped to range of output type
346+ mn_out , mx_out = _dt_min_max (supported_dtype )
347+ if (mn_in , mx_in ) != (mn_out , mx_out ):
348+ # Use smaller of input, output range to avoid np.clip
349+ # upcasting the array because of large clip limits.
350+ exp_back = np .clip (exp_back , max (mn_in , mn_out ), min (mx_in , mx_out ))
351+ if supported_dtype in COMPLEX_TYPES :
352+ # always cast to real from complex
353+ exp_back = exp_back .astype (supported_dtype )
354+ else :
355+ # Cast to working precision
356+ exp_back = exp_back .astype (float )
357+ # Allow for small differences in large numbers
358+ with suppress_warnings (): # invalid value
359+ assert_allclose_safely (back_arr , exp_back * slope + inter )
360360
361361 def test_write_scaling (self ):
362362 # Check writes with scaling set
0 commit comments