def test_simple_data(self):
        """
        Test that the plugin returns the expected values for the generated
        percentiles when an idealised set of data values between 1 and 3
        is used to create the mean and the variance.
        """
        data = np.array([[[[1, 1, 1], [1, 1, 1], [1, 1, 1]]],
                         [[[2, 2, 2], [2, 2, 2], [2, 2, 2]]],
                         [[[3, 3, 3], [3, 3, 3], [3, 3, 3]]]])

        result_data = np.array([[[[0.71844843, 0.71844843, 0.71844843],
                                  [0.71844843, 0.71844843, 0.71844843],
                                  [0.71844843, 0.71844843, 0.71844843]]],
                                [[[2., 2., 2.], [2., 2., 2.], [2., 2., 2.]]],
                                [[[3.28155157, 3.28155157, 3.28155157],
                                  [3.28155157, 3.28155157, 3.28155157],
                                  [3.28155157, 3.28155157, 3.28155157]]]])

        cube = self.current_temperature_forecast_cube
        cube.data = data
        current_forecast_predictor = cube.collapsed("realization",
                                                    iris.analysis.MEAN)
        current_forecast_variance = cube.collapsed("realization",
                                                   iris.analysis.VARIANCE)
        percentiles = [10, 50, 90]
        plugin = Plugin()
        result = plugin._mean_and_variance_to_percentiles(
            current_forecast_predictor, current_forecast_variance, percentiles)
        self.assertArrayAlmostEqual(result.data, result_data)
    def test_if_nearly_identical_data(self):
        """
        Test that the plugin returns the expected values, if every
        percentile has an identical value. This causes an issue because
        the default for the underlying scipy function is to yield a NaN for
        tied values. For this application, any NaN values are overwritten with
        the predicted mean value for all probability thresholds.
        """
        data = np.array([[[[1., 1., 1.], [4., 2., 2.], [3., 3., 3.]]],
                         [[[1., 1., 1.], [2., 2., 2.], [3., 3., 3.]]],
                         [[[1., 1., 1.], [2., 2., 2.], [3., 3., 3.]]]])

        result_data = np.array([[[[1., 1., 1.], [1.18685838, 2., 2.],
                                  [3., 3., 3.]]],
                                [[[1., 1., 1.], [2.66666667, 2., 2.],
                                  [3., 3., 3.]]],
                                [[[1., 1., 1.], [4.14647495, 2., 2.],
                                  [3., 3., 3.]]]])

        cube = self.current_temperature_forecast_cube
        cube.data = data
        current_forecast_predictor = cube.collapsed("realization",
                                                    iris.analysis.MEAN)
        current_forecast_variance = cube.collapsed("realization",
                                                   iris.analysis.VARIANCE)
        percentiles = [10, 50, 90]
        plugin = Plugin()
        result = plugin._mean_and_variance_to_percentiles(
            current_forecast_predictor, current_forecast_variance, percentiles)
        self.assertArrayAlmostEqual(result.data, result_data)
    def test_check_data(self):
        """
        Test that the plugin returns an Iris.cube.Cube matching the expected
        data values when a cube containing mean and variance is passed in.
        The resulting data values are the percentiles, which have been
        generated.
        """
        data = np.array([[[[225.568115, 236.818115, 248.068115],
                           [259.318115, 270.568115, 281.818115],
                           [293.068115, 304.318115, 315.568115]]],
                         [[[229.483322, 240.733322, 251.983322],
                           [263.233307, 274.483307, 285.733307],
                           [296.983307, 308.233307, 319.483307]]],
                         [[[233.398529, 244.648529, 255.898529],
                           [267.148499, 278.398499, 289.648499],
                           [300.898499, 312.148499, 323.398499]]]],
                        dtype=np.float32)

        cube = self.current_temperature_forecast_cube
        current_forecast_predictor = cube.collapsed("realization",
                                                    iris.analysis.MEAN)
        current_forecast_variance = cube.collapsed("realization",
                                                   iris.analysis.VARIANCE)
        percentiles = [10, 50, 90]
        plugin = Plugin()
        result = plugin._mean_and_variance_to_percentiles(
            current_forecast_predictor, current_forecast_variance, percentiles)
        self.assertIsInstance(result, Cube)
        self.assertArrayAlmostEqual(result.data, data)
 def test_negative_percentiles(self):
     """
     Test that the plugin returns the expected values for the
     percentiles if negative probabilities are requested.
     """
     cube = self.current_temperature_forecast_cube
     current_forecast_predictor = cube.collapsed("realization",
                                                 iris.analysis.MEAN)
     current_forecast_variance = cube.collapsed("realization",
                                                iris.analysis.VARIANCE)
     percentiles = [-10, 10]
     plugin = Plugin()
     msg = "NaNs are present within the result for the"
     with self.assertRaisesRegex(ValueError, msg):
         plugin._mean_and_variance_to_percentiles(
             current_forecast_predictor, current_forecast_variance, cube,
             percentiles)
 def test_many_percentiles(self):
     """
     Test that the plugin returns an iris.cube.Cube if many percentiles
     are requested.
     """
     cube = self.current_temperature_forecast_cube
     current_forecast_predictor = cube.collapsed(
         "realization", iris.analysis.MEAN)
     current_forecast_variance = cube.collapsed(
         "realization", iris.analysis.VARIANCE)
     percentiles = np.linspace(1, 99, num=1000, endpoint=True)
     plugin = Plugin()
     result = plugin._mean_and_variance_to_percentiles(
         current_forecast_predictor, current_forecast_variance, percentiles)
     self.assertIsInstance(result, Cube)