From 5b2762cfafc9a409e6737cf9d8b1689904ffc62f Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauldmccarthy@gmail.com>
Date: Tue, 27 Feb 2018 11:51:14 +0000
Subject: [PATCH] imagewrapper.naninfrange moved into its own module

---
 fsl/utils/naninfrange.py | 55 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)
 create mode 100644 fsl/utils/naninfrange.py

diff --git a/fsl/utils/naninfrange.py b/fsl/utils/naninfrange.py
new file mode 100644
index 000000000..523f4080c
--- /dev/null
+++ b/fsl/utils/naninfrange.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+#
+# naninfrange.py - The naninfrange function.
+#
+# Author: Paul McCarthy <pauldmccarthy@gmail.com>
+#
+"""This module provides the :func:`naninfrange` function, which calculates
+the range of a numpy array, ignoring infinite and nan values.
+"""
+
+
+import numpy as np
+
+
+def naninfrange(data):
+    """Returns the minimum and maximum values in the given ``numpy`` array,
+    ignoring ``nan`` and ``inf`` values.
+
+    The ``numpy.nanmin``/``numpy.nanmax`` functions do not handle
+    positive/negative infinity, so if such values are in the data, we need to
+    use an alternate approach to calculating the minimum/maximum.
+    """
+
+    if not np.issubdtype(data.dtype, np.floating):
+        return data.min(), data.max()
+
+    # But np.nanmin/nanmax are substantially
+    # faster than the alternate, so we try it
+    # first.
+    dmin = np.nanmin(data)
+    dmax = np.nanmax(data)
+
+    # If there are no nans/infs in the data,
+    # we can just use nanmin/nanmax
+    if np.isfinite(dmin) and np.isfinite(dmax):
+        return dmin, dmax
+
+    # The entire array contains nans
+    if np.isnan(dmin):
+        return dmin, dmin
+
+    # Otherwise we need to calculate min/max
+    # only on finite values. This is the slow
+    # option.
+
+    # Find all finite values
+    finite = np.isfinite(data)
+
+    # Try to calculate min/max on those values.
+    # An error will be raised if there are no
+    # finite values in the array
+    try:
+        return data[finite].min(), data[finite].max()
+    except Exception:
+        return np.nan, np.nan
-- 
GitLab