From 84b2cd91f2eebb6355823b561b60a6f7fe2db6bc Mon Sep 17 00:00:00 2001
From: Martyn Gigg <martyn.gigg@stfc.ac.uk>
Date: Fri, 19 Jul 2019 10:53:14 +0100
Subject: [PATCH] Define wrapper for np.testing.assert_almost_equal for np <
 1.9.0

Avoids a huge performance bottleneck when running the function
in a tight loop.
---
 .../test/python/mantid/plots/CMakeLists.txt   |   3 +-
 .../test/python/mantid/plots/ScalesTest.py    |  10 +-
 .../plugins/algorithms/CalculateFluxTest.py   |   4 +-
 .../algorithms/FractionalIndexingTest.py      |   1 +
 .../DirectILLApplySelfShieldingTest.py        |  14 +-
 .../DirectILLCollectDataTest.py               |  26 ++--
 .../DirectILLReductionTest.py                 |  10 +-
 .../DirectILLSelfShieldingTest.py             |   7 +-
 .../ReflectometryILLPreprocessTest.py         |  22 ++--
 .../test/testhelpers/__init__.py              | 123 +++++++++++++++++-
 .../ILLDetectorEfficiencyCorUserTest.py       |  10 +-
 .../plotting/test/test_figureinteraction.py   |   2 +-
 scripts/test/CrystalFieldMultiSiteTest.py     |  12 +-
 13 files changed, 184 insertions(+), 60 deletions(-)

diff --git a/Framework/PythonInterface/test/python/mantid/plots/CMakeLists.txt b/Framework/PythonInterface/test/python/mantid/plots/CMakeLists.txt
index 568495accf0..dfc7e590e48 100644
--- a/Framework/PythonInterface/test/python/mantid/plots/CMakeLists.txt
+++ b/Framework/PythonInterface/test/python/mantid/plots/CMakeLists.txt
@@ -6,7 +6,8 @@ set(TEST_PY_FILES
   helperfunctionsTest.py
   plotfunctionsTest.py
   plotfunctions3DTest.py
-  plots__init__Test.py)
+  plots__init__Test.py
+  ScalesTest.py)
 
 check_tests_valid(${CMAKE_CURRENT_SOURCE_DIR} ${TEST_PY_FILES})
 
diff --git a/Framework/PythonInterface/test/python/mantid/plots/ScalesTest.py b/Framework/PythonInterface/test/python/mantid/plots/ScalesTest.py
index 1fa0c3e8046..471c0da281e 100644
--- a/Framework/PythonInterface/test/python/mantid/plots/ScalesTest.py
+++ b/Framework/PythonInterface/test/python/mantid/plots/ScalesTest.py
@@ -18,7 +18,7 @@ import unittest
 from matplotlib.scale import scale_factory
 from mantid.plots.scales import PowerScale, SquareScale
 import numpy as np
-
+import testhelpers
 
 class ScalesTest(unittest.TestCase):
 
@@ -31,7 +31,7 @@ class ScalesTest(unittest.TestCase):
         scale = PowerScale(None, gamma=gamma)
         x = np.linspace(0, 10, 1)
         transform = scale.get_transform()
-        np.testing.assert_almost_equal(np.power(x, gamma),
+        testhelpers.assert_almost_equal(np.power(x, gamma),
                                        transform.transform_non_affine(x))
 
     def test_power_inverse_transform(self):
@@ -39,7 +39,7 @@ class ScalesTest(unittest.TestCase):
         scale = PowerScale(None, gamma=gamma)
         x = np.linspace(0, 10, 1)
         inv_transform = scale.get_transform().inverted()
-        np.testing.assert_almost_equal(np.power(x, 1./gamma),
+        testhelpers.assert_almost_equal(np.power(x, 1./gamma),
                                        inv_transform.transform_non_affine(x))
 
 
@@ -51,7 +51,7 @@ class ScalesTest(unittest.TestCase):
         scale = SquareScale(None)
         x = np.linspace(0, 10, 1)
         transform = scale.get_transform()
-        np.testing.assert_almost_equal(np.power(x, 2),
+        testhelpers.assert_almost_equal(np.power(x, 2),
                                        transform.transform_non_affine(x))
 
 
@@ -59,7 +59,7 @@ class ScalesTest(unittest.TestCase):
         scale = SquareScale(None)
         x = np.linspace(0, 10, 1)
         inv_transform = scale.get_transform().inverted()
-        np.testing.assert_almost_equal(np.sqrt(x),
+        testhelpers.assert_almost_equal(np.sqrt(x),
                                        inv_transform.transform_non_affine(x))
 
 
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/CalculateFluxTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/CalculateFluxTest.py
index a87a03a9b93..ccee5b80476 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/CalculateFluxTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/CalculateFluxTest.py
@@ -9,7 +9,7 @@ from __future__ import (absolute_import, division, print_function)
 import unittest
 from mantid.simpleapi import CalculateFlux, CreateSampleWorkspace, FindDetectorsInShape, mtd
 import numpy as np
-
+import testhelpers
 
 class CalculateFluxTest(unittest.TestCase):
 
@@ -37,7 +37,7 @@ class CalculateFluxTest(unittest.TestCase):
         expectation.fill(self.pixels_in_shape * 0.3)
         expectation[50] = self.pixels_in_shape * 10.3
         reality = mtd["flux"].readY(0)
-        np.testing.assert_almost_equal(reality, expectation, decimal=6)
+        testhelpers.assert_almost_equal(reality, expectation, decimal=6)
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/FractionalIndexingTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/FractionalIndexingTest.py
index 90cf09d575a..55f7089ad77 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/FractionalIndexingTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/FractionalIndexingTest.py
@@ -7,6 +7,7 @@
 import unittest
 import numpy as np
 import numpy.testing as npt
+import testhelpers
 
 from mantid.geometry import UnitCell
 from mantid.simpleapi import CreatePeaksWorkspace, CreateSimulationWorkspace
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLApplySelfShieldingTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLApplySelfShieldingTest.py
index d38d6f8c947..b42cb9e3fdc 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLApplySelfShieldingTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLApplySelfShieldingTest.py
@@ -10,7 +10,7 @@ from __future__ import (absolute_import, division, print_function)
 from mantid.api import (mtd)
 from mantid.simpleapi import (CloneWorkspace)
 import numpy.testing
-from testhelpers import illhelpers, run_algorithm
+from testhelpers import assert_almost_equal, illhelpers, run_algorithm
 import unittest
 
 
@@ -44,7 +44,7 @@ class DirectILLApplySelfShieldingTest(unittest.TestCase):
         self.assertEqual(outWS.getNumberHistograms(), ws.getNumberHistograms())
         ys = outWS.extractY()
         originalYs = ws.extractY()
-        numpy.testing.assert_almost_equal(ys, (1.0 - ecFactor) * originalYs)
+        assert_almost_equal(ys, (1.0 - ecFactor) * originalYs)
 
     def testEmptyContainerSubtractionWithScaling(self):
         ws = self._cloneTestWorkspace()
@@ -67,7 +67,7 @@ class DirectILLApplySelfShieldingTest(unittest.TestCase):
         self.assertEqual(outWS.getNumberHistograms(), ws.getNumberHistograms())
         ys = outWS.extractY()
         originalYs = ws.extractY()
-        numpy.testing.assert_almost_equal(ys, (1.0 - ecScaling * ecFactor) * originalYs)
+        assert_almost_equal(ys, (1.0 - ecScaling * ecFactor) * originalYs)
 
     def testSelfShieldingCorrections(self):
         ws = self._cloneTestWorkspace()
@@ -91,10 +91,10 @@ class DirectILLApplySelfShieldingTest(unittest.TestCase):
         self.assertEqual(outWS.getNumberHistograms(), ws.getNumberHistograms())
         ys = outWS.extractY()
         originalYs = ws.extractY()
-        numpy.testing.assert_almost_equal(ys, originalYs / corrFactor)
+        assert_almost_equal(ys, originalYs / corrFactor)
         es = outWS.extractE()
         originalEs = ws.extractE()
-        numpy.testing.assert_almost_equal(es, originalEs / corrFactor)
+        assert_almost_equal(es, originalEs / corrFactor)
 
     def testNoOperationClonesInputWorkspace(self):
         ws = self._cloneTestWorkspace()
@@ -127,10 +127,10 @@ class DirectILLApplySelfShieldingTest(unittest.TestCase):
         self.assertEqual(outWS.getNumberHistograms(), ws.getNumberHistograms())
         ys = outWS.extractY()
         originalYs = ws.extractY()
-        numpy.testing.assert_almost_equal(ys, originalYs / corrFactor)
+        assert_almost_equal(ys, originalYs / corrFactor)
         es = outWS.extractE()
         originalEs = ws.extractE()
-        numpy.testing.assert_almost_equal(es, originalEs / corrFactor)
+        assert_almost_equal(es, originalEs / corrFactor)
 
     def _cloneTestWorkspace(self, wsName=None):
         if not wsName:
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLCollectDataTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLCollectDataTest.py
index 83d1f980f15..f040fd22723 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLCollectDataTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLCollectDataTest.py
@@ -8,7 +8,7 @@ from __future__ import (absolute_import, division, print_function)
 
 from mantid.api import mtd
 import numpy.testing
-from testhelpers import illhelpers, run_algorithm
+from testhelpers import assert_almost_equal, illhelpers, run_algorithm
 import unittest
 
 
@@ -51,7 +51,7 @@ class DirectILLCollectDataTest(unittest.TestCase):
         self.assertEqual(outWS.getNumberHistograms(), inWS.getNumberHistograms() - 1)
         ys = outWS.extractY()
         originalYs = inWS.extractY()
-        numpy.testing.assert_almost_equal(ys, originalYs[:-1, :] - self._BKG_LEVEL)
+        assert_almost_equal(ys, originalYs[:-1, :] - self._BKG_LEVEL)
 
     def testBackgroundOutput(self):
         outWSName = 'outWS'
@@ -70,7 +70,7 @@ class DirectILLCollectDataTest(unittest.TestCase):
         run_algorithm('DirectILLCollectData', **algProperties)
         self.assertTrue(mtd.doesExist(outBkgWSName))
         outBkgWS = mtd[outBkgWSName]
-        numpy.testing.assert_almost_equal(outBkgWS.extractY(), self._BKG_LEVEL)
+        assert_almost_equal(outBkgWS.extractY(), self._BKG_LEVEL)
 
     def testNormalisationToTime(self):
         outWSName = 'outWS'
@@ -90,10 +90,10 @@ class DirectILLCollectDataTest(unittest.TestCase):
         inWS = mtd[self._TEST_WS_NAME]
         ys = outWS.extractY()
         originalYs = inWS.extractY()
-        numpy.testing.assert_almost_equal(ys, originalYs[:-1, :] / duration)
+        assert_almost_equal(ys, originalYs[:-1, :] / duration)
         es = outWS.extractE()
         originalEs = inWS.extractE()
-        numpy.testing.assert_almost_equal(es, originalEs[:-1, :] / duration)
+        assert_almost_equal(es, originalEs[:-1, :] / duration)
 
     def testNormalisationToTimeWhenMonitorCountsAreTooLow(self):
         outWSName = 'outWS'
@@ -116,10 +116,10 @@ class DirectILLCollectDataTest(unittest.TestCase):
         inWS = mtd[self._TEST_WS_NAME]
         ys = outWS.extractY()
         originalYs = inWS.extractY()
-        numpy.testing.assert_almost_equal(ys, originalYs[:-1, :] / duration)
+        assert_almost_equal(ys, originalYs[:-1, :] / duration)
         es = outWS.extractE()
         originalEs = inWS.extractE()
-        numpy.testing.assert_almost_equal(es, originalEs[:-1, :] / duration)
+        assert_almost_equal(es, originalEs[:-1, :] / duration)
 
     def testRawWorkspaceOutput(self):
         outWSName = 'outWS'
@@ -138,13 +138,13 @@ class DirectILLCollectDataTest(unittest.TestCase):
         rawWS = mtd[rawWSName]
         ys = rawWS.extractY()
         originalYS = inWS.extractY()
-        numpy.testing.assert_almost_equal(ys, originalYS[:-1, :])
+        assert_almost_equal(ys, originalYS[:-1, :])
         es = rawWS.extractE()
         originalES = inWS.extractE()
-        numpy.testing.assert_almost_equal(es, originalES[:-1, :])
+        assert_almost_equal(es, originalES[:-1, :])
         xs = rawWS.extractX()
         outXS = outWS.extractX()
-        numpy.testing.assert_almost_equal(xs, outXS)
+        assert_almost_equal(xs, outXS)
         Ei = rawWS.getRun().getProperty('Ei').value
         outEi = outWS.getRun().getProperty('Ei').value
         self.assertEqual(Ei, outEi)
@@ -170,13 +170,13 @@ class DirectILLCollectDataTest(unittest.TestCase):
         self.assertEqual(outWS.getNumberHistograms(), inWS.getNumberHistograms() - 1)
         xs = outWS.extractX()
         originalXs = inWS.extractX()
-        numpy.testing.assert_almost_equal(xs, originalXs[:-1, :])
+        assert_almost_equal(xs, originalXs[:-1, :])
         ys = outWS.extractY()
         originalYs = inWS.extractY()
-        numpy.testing.assert_almost_equal(ys, originalYs[:-1, :])
+        assert_almost_equal(ys, originalYs[:-1, :])
         es = outWS.extractE()
         originalEs = inWS.extractE()
-        numpy.testing.assert_almost_equal(es, originalEs[:-1, :])
+        assert_almost_equal(es, originalEs[:-1, :])
 
     def testOutputIncidentEnergyWorkspaceWhenEnergyCalibrationIsOff(self):
         outWSName = 'outWS'
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLReductionTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLReductionTest.py
index 495ec867bc0..f2c4b6d1ad2 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLReductionTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLReductionTest.py
@@ -10,7 +10,7 @@ import collections
 from mantid.api import mtd
 import numpy
 import numpy.testing
-from testhelpers import illhelpers, run_algorithm
+from testhelpers import assert_almost_equal, illhelpers, run_algorithm
 import unittest
 
 
@@ -154,7 +154,7 @@ class DirectILLReductionTest(unittest.TestCase):
         ws = mtd[outWSName]
         self.assertEqual(ws.getAxis(0).getUnit().unitID(), 'DeltaE')
         xs = ws.readX(0)
-        numpy.testing.assert_almost_equal(xs, numpy.arange(E0, E1 + 0.01, dE))
+        assert_almost_equal(xs, numpy.arange(E0, E1 + 0.01, dE))
 
     def testHybridERebinningSingleUserRange(self):
         outWSName = 'outWS'
@@ -173,7 +173,7 @@ class DirectILLReductionTest(unittest.TestCase):
         ws = mtd[outWSName]
         self.assertEqual(ws.getAxis(0).getUnit().unitID(), 'DeltaE')
         xs = ws.readX(0)
-        numpy.testing.assert_almost_equal(xs, numpy.arange(E0, E1 + 0.01, dE))
+        assert_almost_equal(xs, numpy.arange(E0, E1 + 0.01, dE))
 
     def testHybridERebinningUserConstrainedAutoRange(self):
         outWSName = 'outWS'
@@ -211,7 +211,7 @@ class DirectILLReductionTest(unittest.TestCase):
         ws = mtd[outWSName]
         self.assertEqual(ws.getAxis(0).getUnit().unitID(), 'MomentumTransfer')
         xs = ws.readX(0)
-        numpy.testing.assert_almost_equal(xs, numpy.arange(Q0, Q1, dQ))
+        assert_almost_equal(xs, numpy.arange(Q0, Q1, dQ))
 
     def testQRebinningBinWidthOnly(self):
         _add_natural_angle_step_parameter(self._TEST_WS_NAME)
@@ -231,7 +231,7 @@ class DirectILLReductionTest(unittest.TestCase):
         self.assertGreater(len(xs), 3)
         dx = xs[1:] - xs[:-1]
         # Bin widths may differ at the edges.
-        numpy.testing.assert_almost_equal(dx[1:-1], 0.1)
+        assert_almost_equal(dx[1:-1], 0.1)
 
     def _checkAlgorithmsInHistory(self, ws, *args):
         """Return true if algorithm names listed in *args are found in the
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLSelfShieldingTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLSelfShieldingTest.py
index 3a0bd040d86..94f2f7bae40 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLSelfShieldingTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLSelfShieldingTest.py
@@ -6,9 +6,8 @@
 # SPDX - License - Identifier: GPL - 3.0 +
 from __future__ import (absolute_import, division, print_function)
 
-from testhelpers import illhelpers, run_algorithm
+from testhelpers import assert_almost_equal, illhelpers, run_algorithm
 from mantid.api import mtd
-import numpy.testing
 import unittest
 
 
@@ -58,7 +57,7 @@ class DirectILLSelfShieldingTest(unittest.TestCase):
         self.assertEqual(outWS.getNumberHistograms(), inWS.getNumberHistograms())
         xs = outWS.extractX()
         originalXs = inWS.extractX()
-        numpy.testing.assert_almost_equal(xs, originalXs[:, :])
+        assert_almost_equal(xs, originalXs[:, :])
 
     def testOutputHasCommonBinningWithInput(self):
         self._setDefaultSample(self._TEST_WS_NAME)
@@ -75,7 +74,7 @@ class DirectILLSelfShieldingTest(unittest.TestCase):
         self.assertEqual(outWS.getNumberHistograms(), inWS.getNumberHistograms())
         xs = outWS.extractX()
         originalXs = inWS.extractX()
-        numpy.testing.assert_almost_equal(xs, originalXs[:, :])
+        assert_almost_equal(xs, originalXs[:, :])
 
     def _setDefaultSample(self, wsName):
         geometry = {
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/ReflectometryILLPreprocessTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/ReflectometryILLPreprocessTest.py
index f6f0bbe9209..57fcf4ae427 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/ReflectometryILLPreprocessTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/ReflectometryILLPreprocessTest.py
@@ -11,7 +11,7 @@ from __future__ import (absolute_import, division, print_function)
 from mantid.api import mtd
 from mantid.simpleapi import ReflectometryILLPreprocess
 import numpy.testing
-from testhelpers import (assertRaisesNothing, create_algorithm, illhelpers)
+from testhelpers import (assertRaisesNothing, assert_almost_equal, create_algorithm, illhelpers)
 import unittest
 import ReflectometryILL_common as common
 
@@ -84,9 +84,9 @@ class ReflectometryILLPreprocessTest(unittest.TestCase):
         for i in range(outWS.getNumberHistograms()):
             ys = outWS.readY(i)
             if i != 49:
-                numpy.testing.assert_almost_equal(ys, [0.0] * ysSize, decimal=12)
+                assert_almost_equal(ys, [0.0] * ysSize, decimal=12)
             else:
-                numpy.testing.assert_almost_equal(ys, [10.0] * ysSize, decimal=12)
+                assert_almost_equal(ys, [10.0] * ysSize, decimal=12)
         self.assertEqual(mtd.getObjectNames(), ['ReflectometryILLPreprocess_test_ws'])
 
     def _backgroundSubtraction(self, subtractionType):
@@ -113,9 +113,9 @@ class ReflectometryILLPreprocessTest(unittest.TestCase):
         for i in range(outWS.getNumberHistograms()):
             ys = outWS.readY(i)
             if i != 49:
-                numpy.testing.assert_almost_equal(ys, [0.0] * ysSize)
+                assert_almost_equal(ys, [0.0] * ysSize)
             else:
-                numpy.testing.assert_almost_equal(ys, [10.0] * ysSize)
+                assert_almost_equal(ys, [10.0] * ysSize)
         self.assertEqual(mtd.getObjectNames(), ['ReflectometryILLPreprocess_test_ws'])
 
     def testLinearFlatBackgroundSubtraction(self):
@@ -199,17 +199,17 @@ class ReflectometryILLPreprocessTest(unittest.TestCase):
         for i in range(outWS.getNumberHistograms()):
             ys = outWS.readY(i)
             if i in lowerBkgIndices:
-                numpy.testing.assert_almost_equal(ys, [0.0] * ysSize)
+                assert_almost_equal(ys, [0.0] * ysSize)
             elif i in lowerExclusionIndices:
-                numpy.testing.assert_almost_equal(ys, [-1005.0] * ysSize)
+                assert_almost_equal(ys, [-1005.0] * ysSize)
             elif i in foregroundIndices:
-                numpy.testing.assert_almost_equal(ys, [995.0] * ysSize)
+                assert_almost_equal(ys, [995.0] * ysSize)
             elif i in upperExclusionIndices:
-                numpy.testing.assert_almost_equal(ys, [-1005.0] * ysSize)
+                assert_almost_equal(ys, [-1005.0] * ysSize)
             elif i in upperBkgIndices:
-                numpy.testing.assert_almost_equal(ys, [0.0] * ysSize)
+                assert_almost_equal(ys, [0.0] * ysSize)
             else:
-                numpy.testing.assert_almost_equal(ys, [-5.0] * ysSize)
+                assert_almost_equal(ys, [-5.0] * ysSize)
         self.assertEqual(mtd.getObjectNames(), ['ReflectometryILLPreprocess_test_ws'])
 
     def testAsymmetricForegroundRanges(self):
diff --git a/Framework/PythonInterface/test/testhelpers/__init__.py b/Framework/PythonInterface/test/testhelpers/__init__.py
index ac62d537261..fae1de93f4e 100644
--- a/Framework/PythonInterface/test/testhelpers/__init__.py
+++ b/Framework/PythonInterface/test/testhelpers/__init__.py
@@ -10,13 +10,16 @@ are for use in unit tests only!
 from __future__ import (absolute_import, division,
                         print_function)
 
+from distutils.version import LooseVersion
+
 # Import mantid to set MANTIDPATH for any ConfigService call that may be done
 import mantid  # noqa
 # Add workspace creation namespace
 import WorkspaceCreationHelper
 
-# Define some pure-Python functions to add to the mix
+import numpy
 
+# Define some pure-Python functions to add to the mix
 
 def run_algorithm(name, **kwargs):
     """Run a named algorithm and return the
@@ -101,3 +104,121 @@ def can_be_instantiated(cls):
     except RuntimeError:
         result = False
     return result
+
+
+# Work around for slow testhelpers.assert_almost_equal that was fixed in 1.9.0:
+#   - https://github.com/numpy/numpy/commit/79d3a94f41b7e3c661eceed2f26ba6cce362ba4f
+# Running assert_almost_equal in a tight loop with v<1.9.0 causes major slows (read minutes)
+if LooseVersion(numpy.__version__) >= LooseVersion("1.9.0"):
+    assert_almost_equal = numpy.testing.assert_almost_equal
+else:
+    def assert_almost_equal(actual,desired,decimal=7,err_msg='',verbose=True):
+        """
+        Raises an AssertionError if two items are not equal up to desired
+        precision.
+        .. note:: It is recommended to use one of `assert_allclose`,
+                  `assert_array_almost_equal_nulp` or `assert_array_max_ulp`
+                  instead of this function for more consistent floating point
+                  comparisons.
+        The test is equivalent to ``abs(desired-actual) < 0.5 * 10**(-decimal)``.
+        Given two objects (numbers or ndarrays), check that all elements of these
+        objects are almost equal. An exception is raised at conflicting values.
+        For ndarrays this delegates to assert_array_almost_equal
+        Parameters
+        ----------
+        actual : array_like
+            The object to check.
+        desired : array_like
+            The expected object.
+        decimal : int, optional
+            Desired precision, default is 7.
+        err_msg : str, optional
+            The error message to be printed in case of failure.
+        verbose : bool, optional
+            If True, the conflicting values are appended to the error message.
+        Raises
+        ------
+        AssertionError
+          If actual and desired are not equal up to specified precision.
+        See Also
+        --------
+        assert_allclose: Compare two array_like objects for equality with desired
+                         relative and/or absolute precision.
+        assert_array_almost_equal_nulp, assert_array_max_ulp, assert_equal
+        Examples
+        --------
+        >>> import numpy.testing as npt
+        >>> npt.assert_almost_equal(2.3333333333333, 2.33333334)
+        >>> npt.assert_almost_equal(2.3333333333333, 2.33333334, decimal=10)
+        ...
+        <type 'exceptions.AssertionError'>:
+        Items are not equal:
+         ACTUAL: 2.3333333333333002
+         DESIRED: 2.3333333399999998
+        >>> npt.assert_almost_equal(np.array([1.0,2.3333333333333]),
+        ...                         np.array([1.0,2.33333334]), decimal=9)
+        ...
+        <type 'exceptions.AssertionError'>:
+        Arrays are not almost equal
+        <BLANKLINE>
+        (mismatch 50.0%)
+         x: array([ 1.        ,  2.33333333])
+         y: array([ 1.        ,  2.33333334])
+        """
+        __tracebackhide__ = True  # Hide traceback for py.test
+        from numpy.core import ndarray
+        from numpy.lib import iscomplexobj, real, imag
+        from numpy.testing.utils import (assert_array_almost_equal, build_err_msg,
+                                         gisfinite, gisnan)
+
+        # Handle complex numbers: separate into real/imag to handle
+        # nan/inf/negative zero correctly
+        # XXX: catch ValueError for subclasses of ndarray where iscomplex fail
+        try:
+            usecomplex = iscomplexobj(actual) or iscomplexobj(desired)
+        except ValueError:
+            usecomplex = False
+
+        def _build_err_msg():
+            header = ('Arrays are not almost equal to %d decimals' % decimal)
+            return build_err_msg([actual, desired], err_msg, verbose=verbose,
+                                 header=header)
+
+        if usecomplex:
+            if iscomplexobj(actual):
+                actualr = real(actual)
+                actuali = imag(actual)
+            else:
+                actualr = actual
+                actuali = 0
+            if iscomplexobj(desired):
+                desiredr = real(desired)
+                desiredi = imag(desired)
+            else:
+                desiredr = desired
+                desiredi = 0
+            try:
+                assert_almost_equal(actualr, desiredr, decimal=decimal)
+                assert_almost_equal(actuali, desiredi, decimal=decimal)
+            except AssertionError:
+                raise AssertionError(_build_err_msg())
+
+        if isinstance(actual, (ndarray, tuple, list)) \
+                or isinstance(desired, (ndarray, tuple, list)):
+            return assert_array_almost_equal(actual, desired, decimal, err_msg)
+        try:
+            # If one of desired/actual is not finite, handle it specially here:
+            # check that both are nan if any is a nan, and test for equality
+            # otherwise
+            if not (gisfinite(desired) and gisfinite(actual)):
+                if gisnan(desired) or gisnan(actual):
+                    if not (gisnan(desired) and gisnan(actual)):
+                        raise AssertionError(_build_err_msg())
+                else:
+                    if not desired == actual:
+                        raise AssertionError(_build_err_msg())
+                return
+        except (NotImplementedError, TypeError):
+            pass
+        if round(abs(desired - actual), decimal) != 0:
+            raise AssertionError(_build_err_msg())
diff --git a/Testing/SystemTests/tests/analysis/ILLDetectorEfficiencyCorUserTest.py b/Testing/SystemTests/tests/analysis/ILLDetectorEfficiencyCorUserTest.py
index ac712e242d1..255d5dfec62 100644
--- a/Testing/SystemTests/tests/analysis/ILLDetectorEfficiencyCorUserTest.py
+++ b/Testing/SystemTests/tests/analysis/ILLDetectorEfficiencyCorUserTest.py
@@ -7,9 +7,9 @@
 from __future__ import (absolute_import, division, print_function)
 
 import numpy
-import numpy.testing
 import systemtesting
 from mantid.simpleapi import (ConvertUnits, DetectorEfficiencyCorUser, DirectILLCollectData)
+from testhelpers import assert_almost_equal
 
 
 class IN4(systemtesting.MantidSystemTest):
@@ -35,12 +35,12 @@ class IN4(systemtesting.MantidSystemTest):
         for i in range(0, 300):
             x = (corr.readX(i)[:-1] + corr.readX(i)[1:]) / 2.
             e = Ei - x
-            numpy.testing.assert_almost_equal(corr.readY(i), eff_factor(e, wide_angle_corr))
+            assert_almost_equal(corr.readY(i), eff_factor(e, wide_angle_corr))
         # Rosace detectors are at ws indices 300-395
         for i in range(300, 396):
             x = (corr.readX(i)[:-1] + corr.readX(i)[1:]) / 2.
             e = Ei - x
-            numpy.testing.assert_almost_equal(corr.readY(i), eff_factor(e, rosace_corr))
+            assert_almost_equal(corr.readY(i), eff_factor(e, rosace_corr))
 
 
 class IN5(systemtesting.MantidSystemTest):
@@ -60,7 +60,7 @@ class IN5(systemtesting.MantidSystemTest):
         for i in range(corr.getNumberHistograms()):
             x = (corr.readX(i)[:-1] + corr.readX(i)[1:]) / 2.
             e = Ei - x
-            numpy.testing.assert_almost_equal(corr.readY(i), corr_at_Ei / tube_corr(e))
+            assert_almost_equal(corr.readY(i), corr_at_Ei / tube_corr(e))
 
 
 class IN6(systemtesting.MantidSystemTest):
@@ -85,4 +85,4 @@ class IN6(systemtesting.MantidSystemTest):
         for i in range(corr.getNumberHistograms()):
             x = (corr.readX(i)[:-1] + corr.readX(i)[1:]) / 2.
             e = Ei - x
-            numpy.testing.assert_almost_equal(corr.readY(i), corr_at_Ei / det_corr(e))
+            assert_almost_equal(corr.readY(i), corr_at_Ei / det_corr(e))
diff --git a/qt/applications/workbench/workbench/plotting/test/test_figureinteraction.py b/qt/applications/workbench/workbench/plotting/test/test_figureinteraction.py
index e01fc3f768c..137693774c7 100644
--- a/qt/applications/workbench/workbench/plotting/test/test_figureinteraction.py
+++ b/qt/applications/workbench/workbench/plotting/test/test_figureinteraction.py
@@ -16,8 +16,8 @@ import unittest
 import matplotlib
 matplotlib.use('AGG')  # noqa
 import numpy as np
-from numpy.testing import assert_almost_equal
 from qtpy.QtCore import Qt
+from testhelpers import assert_almost_equal
 
 # local package imports
 from mantid.plots import MantidAxes
diff --git a/scripts/test/CrystalFieldMultiSiteTest.py b/scripts/test/CrystalFieldMultiSiteTest.py
index f9138fcf5a7..64d4d6d32f1 100644
--- a/scripts/test/CrystalFieldMultiSiteTest.py
+++ b/scripts/test/CrystalFieldMultiSiteTest.py
@@ -7,8 +7,10 @@
 import numpy as np
 import unittest
 
+import testhelpers
 from CrystalField.CrystalFieldMultiSite import CrystalFieldMultiSite
 
+
 c_mbsr = 79.5774715459  # Conversion from barn to mb/sr
 
 
@@ -121,7 +123,7 @@ class CrystalFieldMultiSiteTests(unittest.TestCase):
         y = y / c_mbsr
         expected_y = [12.474955, 1.190169, 0.122781, 0.042940, 10.837438]
         np.testing.assert_equal(x, r)
-        np.testing.assert_almost_equal(y, expected_y, 6)
+        testhelpers.assert_almost_equal(y, expected_y, 6)
 
     def test_get_spectrum_ws(self):
         from mantid.simpleapi import CreateWorkspace
@@ -159,13 +161,13 @@ class CrystalFieldMultiSiteTests(unittest.TestCase):
         y = y / c_mbsr
         expected_y = [12.474946, 1.190160, 0.122785, 0.042940, 10.837170]
         np.testing.assert_equal(x, r)
-        np.testing.assert_almost_equal(y, expected_y, 6)
+        testhelpers.assert_almost_equal(y, expected_y, 6)
 
         x, y = cfms.getSpectrum(1, r)
         y = y / c_mbsr
         expected_y = [6.304662, 0.331218, 1.224681, 0.078540, 2.638049]
         np.testing.assert_equal(x, r)
-        np.testing.assert_almost_equal(y, expected_y, 6)
+        testhelpers.assert_almost_equal(y, expected_y, 6)
 
     def test_get_spectrum_ws_multi_spectra(self):
         from mantid.simpleapi import CreateWorkspace
@@ -213,13 +215,13 @@ class CrystalFieldMultiSiteTests(unittest.TestCase):
         y = y / c_mbsr
         expected_y = [3.904037, 0.744519, 0.274897, 0.175713, 0.106540]
         np.testing.assert_equal(x, r)
-        np.testing.assert_almost_equal(y, expected_y, 6)
+        testhelpers.assert_almost_equal(y, expected_y, 6)
 
         x, y = cfms.getSpectrum(1, r)
         y = y / c_mbsr
         expected_y = [3.704726, 0.785600, 0.296255, 0.190176, 0.115650]
         np.testing.assert_equal(x, r)
-        np.testing.assert_almost_equal(y, expected_y, 6)
+        testhelpers.assert_almost_equal(y, expected_y, 6)
 
     def test_fit_multi_ion_single_spectrum(self):
 
-- 
GitLab