np.asanyarray(img.dataobj, img.get_data_dtype()) is almost never a great choice. np.asanyarray(img.dataobj) is intended to be conservative with its types, where either the original dtype is maintained or scaling is applied and the dtype becomes float64. The case where this fails in particular is when the on-disk dtype is int16 with scale factors. If the scale factors send the data beyond the int16 range (slope > 1), then casting to int16 is going to truncate the data outside the range.
The approach here is to be pragmatic. We always use np.asanyarray(img.dataobj) to give the best estimate of the values in the data array that NIfTI can provide. If a dtype is provided, then we set both the output array and the image type to that, to avoid unnecessary copies and casting. If it is not provided, then the output array keeps the dtype of the input data array (the "effective dtype") and the output image keeps the on-disk dtype of the input image.
np.asanyarray(img.dataobj, img.get_data_dtype())
is almost never a great choice.np.asanyarray(img.dataobj)
is intended to be conservative with its types, where either the original dtype is maintained or scaling is applied and the dtype becomesfloat64
. The case where this fails in particular is when the on-disk dtype isint16
with scale factors. If the scale factors send the data beyond the int16 range (slope > 1), then casting to int16 is going to truncate the data outside the range.The approach here is to be pragmatic. We always use
np.asanyarray(img.dataobj)
to give the best estimate of the values in the data array that NIfTI can provide. If a dtype is provided, then we set both the output array and the image type to that, to avoid unnecessary copies and casting. If it is not provided, then the output array keeps the dtype of the input data array (the "effective dtype") and the output image keeps the on-disk dtype of the input image.get_data_dtype()
scl_slope
/scl_inter
output_dtype
out_img.get_data_dtype()
int16
None
int16
int16
int16
None
float64
int16
int16
float32
float32
float32
int16
float32
float32
float32
float32
None
float32
float32
float32
None
float64
float32
float32
float32
float32
float32
float32
float32
float32
float32