prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Normalise images before handing them to skimage.transform.warp
  From @ayshih at https://github.com/sunpy/sunpy/pull/4452#issuecomment-686504683:
  
  > #2041 removed the normalization code and cast everything to float64. However, I believe the removal of the normalization code should not have been done. Scikit-image's documentation is quite clear that it always assumes that floats are in the range of [0, 1]. While warp() does appear to work fine when that assumption is violated, we are currently relying on undefined behavior.
  
  > I suggest that the normalization code be re-inserted.
  
  I believe the work here is to normalise floating point input to `skimage.transform.warp` to the range [0, 1] in `sunpy.image.transform.affine_transform`, and then un-normalise it after the transform.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `sunpy/image/transform.py`
  Content:
  ```
  1 """
  2 Functions for geometrical image transformation and warping.
  3 """
  4 import numbers
  5 import warnings
  6 
  7 import numpy as np
  8 import scipy.ndimage.interpolation
  9 
  10 from sunpy.util.exceptions import SunpyUserWarning
  11 
  12 __all__ = ['affine_transform']
  13 
  14 
  15 def affine_transform(image, rmatrix, order=3, scale=1.0, image_center=None,
  16                      recenter=False, missing=0.0, use_scipy=False):
  17     """
  18     Rotates, shifts and scales an image.
  19 
  20     Will use `skimage.transform.warp` unless scikit-image can't be imported
  21     then it will use`scipy.ndimage.affine_transform`.
  22 
  23     Parameters
  24     ----------
  25     image : `numpy.ndarray`
  26         2D image to be rotated.
  27     rmatrix : `numpy.ndarray` that is 2x2
  28         Linear transformation rotation matrix.
  29     order : `int` 0-5, optional
  30         Interpolation order to be used, defaults to 3. When using scikit-image this parameter
  31         is passed into `skimage.transform.warp` (e.g., 3 corresponds to bi-cubic interpolation).
  32         When using scipy it is passed into
  33         `scipy.ndimage.affine_transform` where it controls the order of the spline.
  34     scale : `float`
  35         A scale factor for the image with the default being no scaling.
  36     image_center : tuple, optional
  37         The point in the image to rotate around (axis of rotation).
  38         Defaults to the center of the array.
  39     recenter : `bool` or array-like, optional
  40         Move the axis of rotation to the center of the array or recenter coords.
  41         Defaults to `True` i.e., recenter to the center of the array.
  42     missing : `float`, optional
  43         The value to replace any missing data after the transformation.
  44     use_scipy : `bool`, optional
  45         Force use of `scipy.ndimage.affine_transform`.
  46         Will set all "NaNs" in image to zero before doing the transform.
  47         Defaults to `False`, unless scikit-image can't be imported.
  48 
  49     Returns
  50     -------
  51     `numpy.ndarray`:
  52         New rotated, scaled and translated image.
  53 
  54     Notes
  55     -----
  56     This algorithm uses an affine transformation as opposed to a polynomial
  57     geometrical transformation, which by default is `skimage.transform.warp`.
  58     One can specify using `scipy.ndimage.affine_transform` as
  59     an alternative affine transformation. The two transformations use different
  60     algorithms and thus do not give identical output.
  61 
  62     When using for `skimage.transform.warp` with order >= 4 or using
  63     `scipy.ndimage.affine_transform` at all, "NaN" values will
  64     replaced with zero prior to rotation. No attempt is made to retain the NaN
  65     values.
  66 
  67     Input arrays with integer data are cast to float 64 and can be re-cast using
  68     `numpy.ndarray.astype` if desired.
  69 
  70     Although this function is analogous to the IDL's ``rot`` function, it does not
  71     use the same algorithm as the IDL ``rot`` function.
  72     IDL's ``rot`` calls the `POLY_2D <https://www.harrisgeospatial.com/docs/poly_2d.html>`__
  73     method to calculate the inverse mapping of original to target pixel
  74     coordinates. This is a polynomial geometrical transformation.
  75     Then optionally it uses a bicubic convolution interpolation
  76     algorithm to map the original to target pixel values.
  77     """
  78     rmatrix = rmatrix / scale
  79     array_center = (np.array(image.shape)[::-1] - 1) / 2.0
  80 
  81     # Make sure the image center is an array and is where it's supposed to be
  82     if image_center is not None:
  83         image_center = np.asanyarray(image_center)
  84     else:
  85         image_center = array_center
  86 
  87     # Determine center of rotation based on use (or not) of the recenter keyword
  88     if recenter:
  89         rot_center = array_center
  90     else:
  91         rot_center = image_center
  92 
  93     displacement = np.dot(rmatrix, rot_center)
  94     shift = image_center - displacement
  95     if not use_scipy:
  96         try:
  97             import skimage.transform
  98         except ImportError:
  99             warnings.warn("scikit-image could not be imported. Image rotation will use scipy",
  100                           ImportWarning)
  101             use_scipy = True
  102     if use_scipy:
  103         if np.any(np.isnan(image)):
  104             warnings.warn("Setting NaNs to 0 for SciPy rotation.", SunpyUserWarning)
  105         # Transform the image using the scipy affine transform
  106         rotated_image = scipy.ndimage.interpolation.affine_transform(
  107             np.nan_to_num(image).T, rmatrix, offset=shift, order=order,
  108             mode='constant', cval=missing).T
  109     else:
  110         # Make the rotation matrix 3x3 to include translation of the image
  111         skmatrix = np.zeros((3, 3))
  112         skmatrix[:2, :2] = rmatrix
  113         skmatrix[2, 2] = 1.0
  114         skmatrix[:2, 2] = shift
  115         tform = skimage.transform.AffineTransform(skmatrix)
  116 
  117         if issubclass(image.dtype.type, numbers.Integral):
  118             warnings.warn("Integer input data has been cast to float64, "
  119                           "which is required for the skikit-image transform.",
  120                           SunpyUserWarning)
  121             adjusted_image = image.astype(np.float64)
  122         else:
  123             adjusted_image = image.copy()
  124         if np.any(np.isnan(adjusted_image)) and order >= 4:
  125             warnings.warn("Setting NaNs to 0 for higher-order scikit-image rotation.",
  126                           SunpyUserWarning)
  127             adjusted_image = np.nan_to_num(adjusted_image)
  128 
  129         rotated_image = skimage.transform.warp(adjusted_image, tform, order=order,
  130                                                mode='constant', cval=missing,
  131                                                preserve_range=True)
  132 
  133     return rotated_image
  134
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/sunpy/image/transform.py b/sunpy/image/transform.py
  --- a/sunpy/image/transform.py
  +++ b/sunpy/image/transform.py
  @@ -59,14 +59,16 @@
       an alternative affine transformation. The two transformations use different
       algorithms and thus do not give identical output.
   
  -    When using for `skimage.transform.warp` with order >= 4 or using
  -    `scipy.ndimage.affine_transform` at all, "NaN" values will
  -    replaced with zero prior to rotation. No attempt is made to retain the NaN
  -    values.
  +    When using `skimage.transform.warp` with order >= 4 or using
  +    `scipy.ndimage.affine_transform` at all, "NaN" values will be replaced with
  +    zero prior to rotation. No attempt is made to retain the "NaN" values.
   
       Input arrays with integer data are cast to float 64 and can be re-cast using
       `numpy.ndarray.astype` if desired.
   
  +    In the case of `skimage.transform.warp`, the image is normalized to [0, 1]
  +    before passing it to the function. It is later rescaled back to the original range.
  +
       Although this function is analogous to the IDL's ``rot`` function, it does not
       use the same algorithm as the IDL ``rot`` function.
       IDL's ``rot`` calls the `POLY_2D <https://www.harrisgeospatial.com/docs/poly_2d.html>`__
  @@ -115,8 +117,7 @@
           tform = skimage.transform.AffineTransform(skmatrix)
   
           if issubclass(image.dtype.type, numbers.Integral):
  -            warnings.warn("Integer input data has been cast to float64, "
  -                          "which is required for the skikit-image transform.",
  +            warnings.warn("Integer input data has been cast to float64.",
                             SunpyUserWarning)
               adjusted_image = image.astype(np.float64)
           else:
  @@ -126,8 +127,28 @@
                             SunpyUserWarning)
               adjusted_image = np.nan_to_num(adjusted_image)
   
  +        # Scale image to range [0, 1] if it is valid (not made up entirely of NaNs)
  +        is_nan_image = np.all(np.isnan(adjusted_image))
  +        if is_nan_image:
  +            adjusted_missing = missing
  +        else:
  +            im_min = np.nanmin(adjusted_image)
  +            adjusted_image -= im_min
  +            im_max = np.nanmax(adjusted_image)
  +            if im_max > 0:
  +                adjusted_image /= im_max
  +                adjusted_missing = (missing - im_min) / im_max
  +            else:
  +                # The input array is all one value (aside from NaNs), so no scaling is needed
  +                adjusted_missing = missing - im_min
  +
           rotated_image = skimage.transform.warp(adjusted_image, tform, order=order,
  -                                               mode='constant', cval=missing,
  -                                               preserve_range=True)
  +                                               mode='constant', cval=adjusted_missing)
  +
  +        # Convert the image back to its original range if it is valid
  +        if not is_nan_image:
  +            if im_max > 0:
  +                rotated_image *= im_max
  +            rotated_image += im_min
   
       return rotated_image
  
verification_info: {"golden_diff": "diff --git a/sunpy/image/transform.py b/sunpy/image/transform.py\n--- a/sunpy/image/transform.py\n+++ b/sunpy/image/transform.py\n@@ -59,14 +59,16 @@\n     an alternative affine transformation. The two transformations use different\n     algorithms and thus do not give identical output.\n \n-    When using for `skimage.transform.warp` with order >= 4 or using\n-    `scipy.ndimage.affine_transform` at all, \"NaN\" values will\n-    replaced with zero prior to rotation. No attempt is made to retain the NaN\n-    values.\n+    When using `skimage.transform.warp` with order >= 4 or using\n+    `scipy.ndimage.affine_transform` at all, \"NaN\" values will be replaced with\n+    zero prior to rotation. No attempt is made to retain the \"NaN\" values.\n \n     Input arrays with integer data are cast to float 64 and can be re-cast using\n     `numpy.ndarray.astype` if desired.\n \n+    In the case of `skimage.transform.warp`, the image is normalized to [0, 1]\n+    before passing it to the function. It is later rescaled back to the original range.\n+\n     Although this function is analogous to the IDL's ``rot`` function, it does not\n     use the same algorithm as the IDL ``rot`` function.\n     IDL's ``rot`` calls the `POLY_2D <https://www.harrisgeospatial.com/docs/poly_2d.html>`__\n@@ -115,8 +117,7 @@\n         tform = skimage.transform.AffineTransform(skmatrix)\n \n         if issubclass(image.dtype.type, numbers.Integral):\n-            warnings.warn(\"Integer input data has been cast to float64, \"\n-                          \"which is required for the skikit-image transform.\",\n+            warnings.warn(\"Integer input data has been cast to float64.\",\n                           SunpyUserWarning)\n             adjusted_image = image.astype(np.float64)\n         else:\n@@ -126,8 +127,28 @@\n                           SunpyUserWarning)\n             adjusted_image = np.nan_to_num(adjusted_image)\n \n+        # Scale image to range [0, 1] if it is valid (not made up entirely of NaNs)\n+        is_nan_image = np.all(np.isnan(adjusted_image))\n+        if is_nan_image:\n+            adjusted_missing = missing\n+        else:\n+            im_min = np.nanmin(adjusted_image)\n+            adjusted_image -= im_min\n+            im_max = np.nanmax(adjusted_image)\n+            if im_max > 0:\n+                adjusted_image /= im_max\n+                adjusted_missing = (missing - im_min) / im_max\n+            else:\n+                # The input array is all one value (aside from NaNs), so no scaling is needed\n+                adjusted_missing = missing - im_min\n+\n         rotated_image = skimage.transform.warp(adjusted_image, tform, order=order,\n-                                               mode='constant', cval=missing,\n-                                               preserve_range=True)\n+                                               mode='constant', cval=adjusted_missing)\n+\n+        # Convert the image back to its original range if it is valid\n+        if not is_nan_image:\n+            if im_max > 0:\n+                rotated_image *= im_max\n+            rotated_image += im_min\n \n     return rotated_image\n", "issue": "Normalise images before handing them to skimage.transform.warp\nFrom @ayshih at https://github.com/sunpy/sunpy/pull/4452#issuecomment-686504683:\r\n\r\n> #2041 removed the normalization code and cast everything to float64. However, I believe the removal of the normalization code should not have been done. Scikit-image's documentation is quite clear that it always assumes that floats are in the range of [0, 1]. While warp() does appear to work fine when that assumption is violated, we are currently relying on undefined behavior.\r\n\r\n> I suggest that the normalization code be re-inserted.\r\n\r\nI believe the work here is to normalise floating point input to `skimage.transform.warp` to the range [0, 1] in `sunpy.image.transform.affine_transform`, and then un-normalise it after the transform.\n", "before_files": [{"content": "\"\"\"\nFunctions for geometrical image transformation and warping.\n\"\"\"\nimport numbers\nimport warnings\n\nimport numpy as np\nimport scipy.ndimage.interpolation\n\nfrom sunpy.util.exceptions import SunpyUserWarning\n\n__all__ = ['affine_transform']\n\n\ndef affine_transform(image, rmatrix, order=3, scale=1.0, image_center=None,\n                     recenter=False, missing=0.0, use_scipy=False):\n    \"\"\"\n    Rotates, shifts and scales an image.\n\n    Will use `skimage.transform.warp` unless scikit-image can't be imported\n    then it will use`scipy.ndimage.affine_transform`.\n\n    Parameters\n    ----------\n    image : `numpy.ndarray`\n        2D image to be rotated.\n    rmatrix : `numpy.ndarray` that is 2x2\n        Linear transformation rotation matrix.\n    order : `int` 0-5, optional\n        Interpolation order to be used, defaults to 3. When using scikit-image this parameter\n        is passed into `skimage.transform.warp` (e.g., 3 corresponds to bi-cubic interpolation).\n        When using scipy it is passed into\n        `scipy.ndimage.affine_transform` where it controls the order of the spline.\n    scale : `float`\n        A scale factor for the image with the default being no scaling.\n    image_center : tuple, optional\n        The point in the image to rotate around (axis of rotation).\n        Defaults to the center of the array.\n    recenter : `bool` or array-like, optional\n        Move the axis of rotation to the center of the array or recenter coords.\n        Defaults to `True` i.e., recenter to the center of the array.\n    missing : `float`, optional\n        The value to replace any missing data after the transformation.\n    use_scipy : `bool`, optional\n        Force use of `scipy.ndimage.affine_transform`.\n        Will set all \"NaNs\" in image to zero before doing the transform.\n        Defaults to `False`, unless scikit-image can't be imported.\n\n    Returns\n    -------\n    `numpy.ndarray`:\n        New rotated, scaled and translated image.\n\n    Notes\n    -----\n    This algorithm uses an affine transformation as opposed to a polynomial\n    geometrical transformation, which by default is `skimage.transform.warp`.\n    One can specify using `scipy.ndimage.affine_transform` as\n    an alternative affine transformation. The two transformations use different\n    algorithms and thus do not give identical output.\n\n    When using for `skimage.transform.warp` with order >= 4 or using\n    `scipy.ndimage.affine_transform` at all, \"NaN\" values will\n    replaced with zero prior to rotation. No attempt is made to retain the NaN\n    values.\n\n    Input arrays with integer data are cast to float 64 and can be re-cast using\n    `numpy.ndarray.astype` if desired.\n\n    Although this function is analogous to the IDL's ``rot`` function, it does not\n    use the same algorithm as the IDL ``rot`` function.\n    IDL's ``rot`` calls the `POLY_2D <https://www.harrisgeospatial.com/docs/poly_2d.html>`__\n    method to calculate the inverse mapping of original to target pixel\n    coordinates. This is a polynomial geometrical transformation.\n    Then optionally it uses a bicubic convolution interpolation\n    algorithm to map the original to target pixel values.\n    \"\"\"\n    rmatrix = rmatrix / scale\n    array_center = (np.array(image.shape)[::-1] - 1) / 2.0\n\n    # Make sure the image center is an array and is where it's supposed to be\n    if image_center is not None:\n        image_center = np.asanyarray(image_center)\n    else:\n        image_center = array_center\n\n    # Determine center of rotation based on use (or not) of the recenter keyword\n    if recenter:\n        rot_center = array_center\n    else:\n        rot_center = image_center\n\n    displacement = np.dot(rmatrix, rot_center)\n    shift = image_center - displacement\n    if not use_scipy:\n        try:\n            import skimage.transform\n        except ImportError:\n            warnings.warn(\"scikit-image could not be imported. Image rotation will use scipy\",\n                          ImportWarning)\n            use_scipy = True\n    if use_scipy:\n        if np.any(np.isnan(image)):\n            warnings.warn(\"Setting NaNs to 0 for SciPy rotation.\", SunpyUserWarning)\n        # Transform the image using the scipy affine transform\n        rotated_image = scipy.ndimage.interpolation.affine_transform(\n            np.nan_to_num(image).T, rmatrix, offset=shift, order=order,\n            mode='constant', cval=missing).T\n    else:\n        # Make the rotation matrix 3x3 to include translation of the image\n        skmatrix = np.zeros((3, 3))\n        skmatrix[:2, :2] = rmatrix\n        skmatrix[2, 2] = 1.0\n        skmatrix[:2, 2] = shift\n        tform = skimage.transform.AffineTransform(skmatrix)\n\n        if issubclass(image.dtype.type, numbers.Integral):\n            warnings.warn(\"Integer input data has been cast to float64, \"\n                          \"which is required for the skikit-image transform.\",\n                          SunpyUserWarning)\n            adjusted_image = image.astype(np.float64)\n        else:\n            adjusted_image = image.copy()\n        if np.any(np.isnan(adjusted_image)) and order >= 4:\n            warnings.warn(\"Setting NaNs to 0 for higher-order scikit-image rotation.\",\n                          SunpyUserWarning)\n            adjusted_image = np.nan_to_num(adjusted_image)\n\n        rotated_image = skimage.transform.warp(adjusted_image, tform, order=order,\n                                               mode='constant', cval=missing,\n                                               preserve_range=True)\n\n    return rotated_image\n", "path": "sunpy/image/transform.py"}], "after_files": [{"content": "\"\"\"\nFunctions for geometrical image transformation and warping.\n\"\"\"\nimport numbers\nimport warnings\n\nimport numpy as np\nimport scipy.ndimage.interpolation\n\nfrom sunpy.util.exceptions import SunpyUserWarning\n\n__all__ = ['affine_transform']\n\n\ndef affine_transform(image, rmatrix, order=3, scale=1.0, image_center=None,\n                     recenter=False, missing=0.0, use_scipy=False):\n    \"\"\"\n    Rotates, shifts and scales an image.\n\n    Will use `skimage.transform.warp` unless scikit-image can't be imported\n    then it will use`scipy.ndimage.affine_transform`.\n\n    Parameters\n    ----------\n    image : `numpy.ndarray`\n        2D image to be rotated.\n    rmatrix : `numpy.ndarray` that is 2x2\n        Linear transformation rotation matrix.\n    order : `int` 0-5, optional\n        Interpolation order to be used, defaults to 3. When using scikit-image this parameter\n        is passed into `skimage.transform.warp` (e.g., 3 corresponds to bi-cubic interpolation).\n        When using scipy it is passed into\n        `scipy.ndimage.affine_transform` where it controls the order of the spline.\n    scale : `float`\n        A scale factor for the image with the default being no scaling.\n    image_center : tuple, optional\n        The point in the image to rotate around (axis of rotation).\n        Defaults to the center of the array.\n    recenter : `bool` or array-like, optional\n        Move the axis of rotation to the center of the array or recenter coords.\n        Defaults to `True` i.e., recenter to the center of the array.\n    missing : `float`, optional\n        The value to replace any missing data after the transformation.\n    use_scipy : `bool`, optional\n        Force use of `scipy.ndimage.affine_transform`.\n        Will set all \"NaNs\" in image to zero before doing the transform.\n        Defaults to `False`, unless scikit-image can't be imported.\n\n    Returns\n    -------\n    `numpy.ndarray`:\n        New rotated, scaled and translated image.\n\n    Notes\n    -----\n    This algorithm uses an affine transformation as opposed to a polynomial\n    geometrical transformation, which by default is `skimage.transform.warp`.\n    One can specify using `scipy.ndimage.affine_transform` as\n    an alternative affine transformation. The two transformations use different\n    algorithms and thus do not give identical output.\n\n    When using `skimage.transform.warp` with order >= 4 or using\n    `scipy.ndimage.affine_transform` at all, \"NaN\" values will be replaced with\n    zero prior to rotation. No attempt is made to retain the \"NaN\" values.\n\n    Input arrays with integer data are cast to float 64 and can be re-cast using\n    `numpy.ndarray.astype` if desired.\n\n    In the case of `skimage.transform.warp`, the image is normalized to [0, 1]\n    before passing it to the function. It is later rescaled back to the original range.\n\n    Although this function is analogous to the IDL's ``rot`` function, it does not\n    use the same algorithm as the IDL ``rot`` function.\n    IDL's ``rot`` calls the `POLY_2D <https://www.harrisgeospatial.com/docs/poly_2d.html>`__\n    method to calculate the inverse mapping of original to target pixel\n    coordinates. This is a polynomial geometrical transformation.\n    Then optionally it uses a bicubic convolution interpolation\n    algorithm to map the original to target pixel values.\n    \"\"\"\n    rmatrix = rmatrix / scale\n    array_center = (np.array(image.shape)[::-1] - 1) / 2.0\n\n    # Make sure the image center is an array and is where it's supposed to be\n    if image_center is not None:\n        image_center = np.asanyarray(image_center)\n    else:\n        image_center = array_center\n\n    # Determine center of rotation based on use (or not) of the recenter keyword\n    if recenter:\n        rot_center = array_center\n    else:\n        rot_center = image_center\n\n    displacement = np.dot(rmatrix, rot_center)\n    shift = image_center - displacement\n    if not use_scipy:\n        try:\n            import skimage.transform\n        except ImportError:\n            warnings.warn(\"scikit-image could not be imported. Image rotation will use scipy\",\n                          ImportWarning)\n            use_scipy = True\n    if use_scipy:\n        if np.any(np.isnan(image)):\n            warnings.warn(\"Setting NaNs to 0 for SciPy rotation.\", SunpyUserWarning)\n        # Transform the image using the scipy affine transform\n        rotated_image = scipy.ndimage.interpolation.affine_transform(\n            np.nan_to_num(image).T, rmatrix, offset=shift, order=order,\n            mode='constant', cval=missing).T\n    else:\n        # Make the rotation matrix 3x3 to include translation of the image\n        skmatrix = np.zeros((3, 3))\n        skmatrix[:2, :2] = rmatrix\n        skmatrix[2, 2] = 1.0\n        skmatrix[:2, 2] = shift\n        tform = skimage.transform.AffineTransform(skmatrix)\n\n        if issubclass(image.dtype.type, numbers.Integral):\n            warnings.warn(\"Integer input data has been cast to float64.\",\n                          SunpyUserWarning)\n            adjusted_image = image.astype(np.float64)\n        else:\n            adjusted_image = image.copy()\n        if np.any(np.isnan(adjusted_image)) and order >= 4:\n            warnings.warn(\"Setting NaNs to 0 for higher-order scikit-image rotation.\",\n                          SunpyUserWarning)\n            adjusted_image = np.nan_to_num(adjusted_image)\n\n        # Scale image to range [0, 1] if it is valid (not made up entirely of NaNs)\n        is_nan_image = np.all(np.isnan(adjusted_image))\n        if is_nan_image:\n            adjusted_missing = missing\n        else:\n            im_min = np.nanmin(adjusted_image)\n            adjusted_image -= im_min\n            im_max = np.nanmax(adjusted_image)\n            if im_max > 0:\n                adjusted_image /= im_max\n                adjusted_missing = (missing - im_min) / im_max\n            else:\n                # The input array is all one value (aside from NaNs), so no scaling is needed\n                adjusted_missing = missing - im_min\n\n        rotated_image = skimage.transform.warp(adjusted_image, tform, order=order,\n                                               mode='constant', cval=adjusted_missing)\n\n        # Convert the image back to its original range if it is valid\n        if not is_nan_image:\n            if im_max > 0:\n                rotated_image *= im_max\n            rotated_image += im_min\n\n    return rotated_image\n", "path": "sunpy/image/transform.py"}]}