Repository: Project-MONAI/MONAI

Issue:
RandHistogramShift dtype inconsistency
**Describe the bug**
RandHistogramShift transform doesn't preserve the float32 precision

**To Reproduce**
```py
import numpy as np
from monai.transforms import RandHistogramShift

inputs = np.zeros((2, 2), dtype=np.float32)
result = RandHistogramShift(num_control_points=(5, 20), prob=1.0)(inputs)
print(inputs.dtype)  # float32
print(result.dtype)  # float64
```

**Expected behavior**
result type should be float32 if the input's is


**Environment (please complete the following information):**
MONAI version: 0.3.0rc3+0.g3f4e064.dirty
Python version: 3.6.10 |Anaconda, Inc.| (default, Mar 25 2020, 18:53:43)  [GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)]
Numpy version: 1.19.2
Pytorch version: 1.6.0

--
Thanks for reporting the issue @Can-Zhao!



Discussion:

Resolving patch:
diff --git a/monai/transforms/intensity/array.py b/monai/transforms/intensity/array.py
--- a/monai/transforms/intensity/array.py
+++ b/monai/transforms/intensity/array.py
@@ -698,4 +698,4 @@ def __call__(self, img: np.ndarray) -> np.ndarray:
         img_min, img_max = img.min(), img.max()
         reference_control_points_scaled = self.reference_control_points * (img_max - img_min) + img_min
         floating_control_points_scaled = self.floating_control_points * (img_max - img_min) + img_min
-        return np.interp(img, reference_control_points_scaled, floating_control_points_scaled)
+        return np.interp(img, reference_control_points_scaled, floating_control_points_scaled).astype(img.dtype)
diff --git a/monai/transforms/intensity/dictionary.py b/monai/transforms/intensity/dictionary.py
--- a/monai/transforms/intensity/dictionary.py
+++ b/monai/transforms/intensity/dictionary.py
@@ -646,7 +646,8 @@ def __call__(self, data: Mapping[Hashable, np.ndarray]) -> Dict[Hashable, np.nda
             img_min, img_max = d[key].min(), d[key].max()
             reference_control_points_scaled = self.reference_control_points * (img_max - img_min) + img_min
             floating_control_points_scaled = self.floating_control_points * (img_max - img_min) + img_min
-            d[key] = np.interp(d[key], reference_control_points_scaled, floating_control_points_scaled)
+            dtype = d[key].dtype
+            d[key] = np.interp(d[key], reference_control_points_scaled, floating_control_points_scaled).astype(dtype)
         return d
 
 


Test patch:
diff --git a/tests/test_rand_histogram_shift.py b/tests/test_rand_histogram_shift.py
--- a/tests/test_rand_histogram_shift.py
+++ b/tests/test_rand_histogram_shift.py
@@ -24,12 +24,12 @@
     ],
     [
         {"num_control_points": 5, "prob": 0.9},
-        {"img": np.arange(8).reshape((1, 2, 2, 2))},
+        {"img": np.arange(8).reshape((1, 2, 2, 2)).astype(np.float32)},
         np.array([[[[0.0, 0.57227867], [1.1391707, 1.68990281]], [[2.75833219, 4.34445884], [5.70913743, 7.0]]]]),
     ],
     [
         {"num_control_points": (5, 20), "prob": 0.9},
-        {"img": np.arange(8).reshape((1, 2, 2, 2))},
+        {"img": np.arange(8).reshape((1, 2, 2, 2)).astype(np.float32)},
         np.array([[[[0.0, 1.17472492], [2.21553091, 2.88292011]], [[3.98407301, 5.01302123], [6.09275004, 7.0]]]]),
     ],
 ]
diff --git a/tests/test_rand_histogram_shiftd.py b/tests/test_rand_histogram_shiftd.py
--- a/tests/test_rand_histogram_shiftd.py
+++ b/tests/test_rand_histogram_shiftd.py
@@ -24,7 +24,7 @@
     ],
     [
         {"keys": ("img",), "num_control_points": 5, "prob": 0.9},
-        {"img": np.arange(8).reshape((1, 2, 2, 2)), "seg": np.ones(8).reshape((1, 2, 2, 2))},
+        {"img": np.arange(8).reshape((1, 2, 2, 2)).astype(np.float32), "seg": np.ones(8).reshape((1, 2, 2, 2))},
         {
             "img": np.array(
                 [[[[0.0, 0.57227867], [1.1391707, 1.68990281]], [[2.75833219, 4.34445884], [5.70913743, 7.0]]]]
@@ -34,7 +34,7 @@
     ],
     [
         {"keys": ("img",), "num_control_points": (5, 20), "prob": 0.9},
-        {"img": np.arange(8).reshape((1, 2, 2, 2)), "seg": np.ones(8).reshape((1, 2, 2, 2))},
+        {"img": np.arange(8).reshape((1, 2, 2, 2)).astype(np.float32), "seg": np.ones(8).reshape((1, 2, 2, 2))},
         {
             "img": np.array(
                 [[[[0.0, 1.17472492], [2.21553091, 2.88292011]], [[3.98407301, 5.01302123], [6.09275004, 7.0]]]]