def test_probabilities_not_monotonically_increasing(
            self, warning_list=None):
        """
        Test that the plugin raises a Warning when the probabilities
        of the Cumulative Distribution Function are not monotonically
        increasing.
        """
        data = np.array([0.05, 0.7, 0.95])
        data = data[:, np.newaxis, np.newaxis, np.newaxis]

        self.current_temperature_forecast_cube = add_forecast_reference_time_and_forecast_period(
            set_up_probability_threshold_cube(
                data,
                "air_temperature",
                "degreesC",
                forecast_thresholds=[8, 10, 12],
                y_dimension_length=1,
                x_dimension_length=1,
                spp__relative_to_threshold="above",
            ))
        cube = self.current_temperature_forecast_cube
        percentiles = [10, 50, 90]
        bounds_pairing = (-40, 50)
        plugin = Plugin()
        warning_msg = "The probability values used to construct the"
        plugin._probabilities_to_percentiles(cube, percentiles, bounds_pairing)
        self.assertTrue(any(warning_msg in str(item) for item in warning_list))
    def test_transpose_cube_dimensions(self):
        """
        Test that the plugin returns an the expected data, when comparing
        input cubes which have dimensions in a different order.
        """
        # Calculate result for nontransposed cube.
        cube = self.current_temperature_forecast_cube
        percentiles = [10, 50, 90]
        bounds_pairing = (-40, 50)
        plugin = Plugin()
        nontransposed_result = plugin._probabilities_to_percentiles(
            cube, percentiles, bounds_pairing)

        # Calculate result for transposed cube.
        # Original cube dimensions are [P, T, Y, X].
        # Transposed cube dimensions are [X, Y, T, P].
        cube.transpose([3, 2, 1, 0])
        transposed_result = plugin._probabilities_to_percentiles(
            cube, percentiles, bounds_pairing)

        # Result cube will be [P, X, Y, T]
        # Transpose cube to be [P, T, Y, X]
        transposed_result.transpose([0, 3, 2, 1])
        self.assertArrayAlmostEqual(nontransposed_result.data,
                                    transposed_result.data)
 def test_unknown_thresholding(self):
     """Test that the plugin returns an Iris.cube.Cube."""
     cube = self.current_temperature_forecast_cube
     cube.coord(var_name="threshold"
                ).attributes["spp__relative_to_threshold"] = "between"
     percentiles = [10, 50, 90]
     bounds_pairing = (-40, 50)
     plugin = Plugin()
     msg = "Probabilities to percentiles only implemented for"
     with self.assertRaisesRegex(NotImplementedError, msg):
         plugin._probabilities_to_percentiles(cube, percentiles,
                                              bounds_pairing)
    def test_simple_check_data_below(self):
        """
        Test that the plugin returns an Iris.cube.Cube with the expected
        data values for the percentiles when input probabilities are given
        for being below a threshold.
        The input cube contains probabilities that values are below a given
        threshold.
        """
        expected = np.array([8.4, 10.61538462, 11.84615385])
        expected = expected[:, np.newaxis, np.newaxis, np.newaxis]

        data = np.array([0.95, 0.3, 0.05])[::-1]
        data = data[:, np.newaxis, np.newaxis, np.newaxis]

        self.current_temperature_forecast_cube = add_forecast_reference_time_and_forecast_period(
            set_up_probability_threshold_cube(
                data,
                "air_temperature",
                "degreesC",
                forecast_thresholds=[8, 10, 12],
                y_dimension_length=1,
                x_dimension_length=1,
                spp__relative_to_threshold="above",
            ))
        cube = self.current_temperature_forecast_cube
        cube.coord(var_name="threshold"
                   ).attributes["spp__relative_to_threshold"] = "below"
        percentiles = [10, 50, 90]
        bounds_pairing = (-40, 50)
        plugin = Plugin()
        result = plugin._probabilities_to_percentiles(cube, percentiles,
                                                      bounds_pairing)
        self.assertArrayAlmostEqual(result.data, expected)
예제 #5
0
    def test_lots_of_percentiles(self):
        """
        Test that the plugin returns an Iris.cube.Cube with the expected
        data values for the percentiles, if lots of percentile values are
        requested.
        """
        data = np.array(
            [[[[13.9, -16., 10.2], [-28., -16., -35.2], [-35.2, -37., -37.6]]],
             [[[17.7, 8.25, 10.6], [-4., 8.25, -25.6], [-25.6, -31., -32.8]]],
             [[[21.5, 8.75, 11.], [8.33333333, 8.75, -16.], [-16., -25., -28.]]
              ], [[[25.3, 9.25, 11.4], [9., 9.25, -6.4], [-6.4, -19., -23.2]]],
             [[[29.1, 9.75, 11.8], [9.66666667, 9.75, 3.2], [3.2, -13., -18.4]]
              ],
             [[[32.9, 10.33333333, 15.8], [10.33333333, 10.2, 8.5],
               [8.33333333, -7., -13.6]]],
             [[[36.7, 11., 23.4], [11., 10.6, 9.5], [9., -1., -8.8]]],
             [[[40.5, 11.66666667, 31.], [11.66666667, 11., 10.5],
               [9.66666667, 5., -4.]]],
             [[[44.3, 21.5, 38.6], [21.5, 11.4, 11.5], [10.5, 8.5, 0.8]]],
             [[[48.1, 40.5, 46.2], [40.5, 11.8, 31.], [11.5, 9.5, 5.6]]]],
            dtype=np.float32)

        cube = self.current_temperature_forecast_cube
        percentiles = np.arange(5, 100, 10)
        bounds_pairing = (-40, 50)
        plugin = Plugin()
        result = plugin._probabilities_to_percentiles(cube, percentiles,
                                                      bounds_pairing)
        self.assertArrayAlmostEqual(result.data, data, decimal=5)
예제 #6
0
    def test_lots_of_probability_thresholds(self):
        """
        Test that the plugin returns an Iris.cube.Cube with the expected
        data values for the percentiles, if there are lots of thresholds.
        """
        input_probs_1d = np.linspace(1, 0, 30)
        input_probs = np.tile(input_probs_1d, (3, 3, 1, 1)).T

        data = np.array(
            [[[[2.9, 2.9, 2.9], [2.9, 2.9, 2.9], [2.9, 2.9, 2.9]]],
             [[[14.5, 14.5, 14.5], [14.5, 14.5, 14.5], [14.5, 14.5, 14.5]]],
             [[[26.099998, 26.099998, 26.099998],
               [26.099998, 26.099998, 26.099998],
               [26.099998, 26.099998, 26.099998]]]],
            dtype=np.float32)

        temperature_values = np.arange(0, 30)
        cube = (add_forecast_reference_time_and_forecast_period(
            set_up_probability_threshold_cube(
                input_probs,
                "air_temperature",
                "degreesC",
                forecast_thresholds=temperature_values,
                spp__relative_to_threshold='above')))
        percentiles = [10, 50, 90]
        bounds_pairing = (-40, 50)
        plugin = Plugin()
        result = plugin._probabilities_to_percentiles(cube, percentiles,
                                                      bounds_pairing)

        self.assertArrayAlmostEqual(result.data, data)
예제 #7
0
    def test_check_single_threshold(self):
        """
        Test that the plugin returns an Iris.cube.Cube with the expected
        data values for the percentiles, if a single threshold is used for
        constructing the percentiles.
        """
        data = np.array(
            [[[[12.2, 8., 12.2], [-16., 8., -30.4], [-30.4, -34., -35.2]]],
             [[[29., 26.66666667, 29.], [23.75, 26.66666667, 8.],
               [8., -10., -16.]]],
             [[[45.8, 45.33333333, 45.8], [44.75, 45.33333333, 41.6],
               [41.6, 29., 3.2]]]],
            dtype=np.float32)

        threshold_coord = find_threshold_coordinate(
            self.current_temperature_forecast_cube)
        for acube in self.current_temperature_forecast_cube.slices_over(
                threshold_coord):
            cube = acube
            break
        percentiles = [10, 50, 90]
        bounds_pairing = (-40, 50)
        plugin = Plugin()
        result = plugin._probabilities_to_percentiles(cube, percentiles,
                                                      bounds_pairing)
        self.assertArrayAlmostEqual(result.data, data, decimal=5)
 def test_basic(self):
     """Test that the plugin returns an Iris.cube.Cube."""
     cube = self.current_temperature_forecast_cube
     percentiles = [10, 50, 90]
     bounds_pairing = (-40, 50)
     plugin = Plugin()
     result = plugin._probabilities_to_percentiles(cube, percentiles,
                                                   bounds_pairing)
     self.assertIsInstance(result, Cube)
 def test_return_name(self):
     """Test that the plugin returns an Iris.cube.Cube with an appropriate
     name.
     """
     cube = self.current_temperature_forecast_cube
     percentiles = [10, 50, 90]
     bounds_pairing = (-40, 50)
     plugin = Plugin()
     result = plugin._probabilities_to_percentiles(cube, percentiles,
                                                   bounds_pairing)
     self.assertEqual(result.name(), "air_temperature")
 def test_result_cube_has_no_air_temperature_threshold_coordinate(self):
     """
     Test that the plugin returns a cube with coordinates that
     do not include the air_temperature_threshold coordinate.
     """
     cube = self.current_temperature_forecast_cube
     percentiles = [10, 50, 90]
     bounds_pairing = (-40, 50)
     plugin = Plugin()
     result = plugin._probabilities_to_percentiles(cube, percentiles,
                                                   bounds_pairing)
     for coord in result.coords():
         self.assertNotEqual(coord.name(), "threshold")
 def test_return_coord_units(self):
     """Test that the plugin returns an Iris.cube.Cube with an appropriate
     percentile coordinate with suitable units.
     """
     cube = self.current_temperature_forecast_cube
     percentiles = [10, 50, 90]
     bounds_pairing = (-40, 50)
     plugin = Plugin()
     result = plugin._probabilities_to_percentiles(cube, percentiles,
                                                   bounds_pairing)
     self.assertIsInstance(result.coord("percentile"), DimCoord)
     self.assertArrayEqual(result.coord("percentile").points, percentiles)
     self.assertEqual(result.coord("percentile").units, unit.Unit("%"))
    def test_check_data_multiple_timesteps(self):
        """
        Test that the plugin returns an Iris.cube.Cube with the expected
        data values for the percentiles.
        """
        expected = np.array(
            [
                [[[8.0, 8.0], [-8.0, 8.66666667]], [[8.0, -16.0], [8.0, -16.0]]
                 ],
                [[[12.0, 12.0], [12.0, 12.0]], [[10.5, 10.0], [10.5, 10.0]]],
                [[[31.0, 31.0], [31.0, 31.0]],
                 [[11.5, 11.33333333], [11.5, 12.0]]],
            ],
            dtype=np.float32,
        )

        data = np.array(
            [
                [[[0.8, 0.8], [0.7, 0.9]], [[0.8, 0.6], [0.8, 0.6]]],
                [[[0.6, 0.6], [0.6, 0.6]], [[0.5, 0.4], [0.5, 0.4]]],
                [[[0.4, 0.4], [0.4, 0.4]], [[0.1, 0.1], [0.1, 0.2]]],
            ],
            dtype=np.float32,
        )

        cube = set_up_probability_threshold_cube(
            data,
            "air_temperature",
            "degreesC",
            timesteps=2,
            x_dimension_length=2,
            y_dimension_length=2,
            spp__relative_to_threshold="above",
        )
        self.probability_cube = add_forecast_reference_time_and_forecast_period(
            cube,
            time_point=np.array([402295.0, 402296.0]),
            fp_point=[2.0, 3.0])
        cube = self.probability_cube
        percentiles = [20, 60, 80]
        bounds_pairing = (-40, 50)
        plugin = Plugin()
        result = plugin._probabilities_to_percentiles(cube, percentiles,
                                                      bounds_pairing)
        self.assertArrayAlmostEqual(result.data, expected, decimal=5)
예제 #13
0
    def test_check_data_spot_forecasts(self):
        """
        Test that the plugin returns an Iris.cube.Cube with the expected
        data values for the percentiles for spot forecasts.
        """
        data = np.array(
            [[[15.8, 8., 10.4, -16., 8., -30.4, -30.4, -34., -35.2]],
             [[31., 10., 12., 10., 10., 8., 8., -10., -16.]],
             [[46.2, 31., 42.4, 31., 11.6, 12., 11., 9., 3.2]]],
            dtype=np.float32)

        cube = self.current_temperature_spot_forecast_cube
        percentiles = [10, 50, 90]
        bounds_pairing = (-40, 50)
        plugin = Plugin()
        result = plugin._probabilities_to_percentiles(cube, percentiles,
                                                      bounds_pairing)
        self.assertArrayAlmostEqual(result.data, data, decimal=5)