def test_weighted_max_non_equal_weights_array(self):
     """Test it works for weighted_max with weights [0.2, 0.8]
        given as a array."""
     coord = "time"
     plugin = WeightedBlendAcrossWholeDimension(coord, 'weighted_maximum')
     weights = np.array([0.2, 0.8])
     result = plugin.process(self.cube, weights)
     expected_result_array = np.ones((2, 2)) * 1.6
     self.assertArrayAlmostEqual(result.data, expected_result_array)
    def test_without_weights(self):
        """Test function when a data cube is provided, but no weights cube
        which should result in equal weightings."""
        plugin = WeightedBlendAcrossWholeDimension(self.coord)
        result = plugin.weighted_mean(self.cube, None)
        expected = np.full((2, 2), 2.0)

        self.assertIsInstance(result, iris.cube.Cube)
        self.assertArrayAlmostEqual(result.data, expected)
 def test_percentiles_weights_none(self):
     """Test it works for percentiles with weights set to None."""
     coord = "time"
     plugin = WeightedBlendAcrossWholeDimension(coord, 'weighted_mean')
     weights = None
     perc_cube = percentile_cube()
     result = plugin.process(perc_cube, weights)
     expected_result_array = np.reshape(BLENDED_PERCENTILE_DATA1, (6, 2, 2))
     self.assertArrayAlmostEqual(result.data, expected_result_array)
 def test_fails_coord_not_in_weights_cube(self):
     """Test it raises CoordinateNotFoundError if the blending coord is not
     found in the weights cube."""
     coord = "forecast_reference_time"
     self.weights1d.remove_coord("forecast_reference_time")
     plugin = WeightedBlendAcrossWholeDimension(coord)
     msg = ('Coordinate to be collapsed not found in weights cube.')
     with self.assertRaisesRegex(CoordinateNotFoundError, msg):
         plugin.process(self.cube, self.weights1d)
 def test_unmatched_validity_time_exemption(self):
     """Test that no ValueError is raised for unmatched validity times if
     we use the timeblending=True flag. As long as no exception is raised
     this test passes."""
     self.cube.remove_coord('time')
     self.cube.coord('forecast_reference_time').rename('time')
     coord = "forecast_reference_time"
     plugin = WeightedBlendAcrossWholeDimension(coord, timeblending=True)
     plugin.check_compatible_time_points(self.cube)
    def test_3D_weights_3D_cube_weighted_mean(self):
        """Test a 3D cube of weights results in a 3D array of weights of the
        same shape as the data cube."""

        coord = "forecast_reference_time"
        plugin = WeightedBlendAcrossWholeDimension(coord)
        result = plugin.shape_weights(self.cube, self.weights3d)
        self.assertEqual(self.cube.shape, result.shape)
        self.assertArrayEqual(self.weights3d.data, result)
 def test_forecast_reference_time_exception(self):
     """Test that a ValueError is raised if the coordinate to be blended
     is forecast_reference_time and the points on the time coordinate are
     not equal."""
     coord = "forecast_reference_time"
     plugin = WeightedBlendAcrossWholeDimension(coord, 'weighted_mean')
     msg = ('For blending using the forecast_reference_time')
     with self.assertRaisesRegexp(ValueError, msg):
         plugin.process(self.cube)
 def test_incompatible_weights_and_data_cubes(self):
     """Test an exception is raised if the weights cube and the data cube
     have incompatible coordinates."""
     self.weights1d.coord(self.coord).rename("threshold")
     plugin = WeightedBlendAcrossWholeDimension(self.coord)
     msg = ("threshold is a coordinate on the weights cube but it "
            "is not found on the cube we are trying to collapse.")
     with self.assertRaisesRegex(ValueError, msg):
         plugin.shape_weights(self.cube, self.weights1d)
 def test_fails_perc_coord_not_dim(self):
     """Test it raises a Value Error if percentile coord not a dim."""
     coord = "forecast_reference_time"
     plugin = WeightedBlendAcrossWholeDimension(coord)
     new_cube = self.cube.copy()
     new_cube.add_aux_coord(AuxCoord([10.0], long_name="percentile"))
     msg = ('The percentile coord must be a dimension ' 'of the cube.')
     with self.assertRaisesRegex(ValueError, msg):
         plugin.check_percentile_coord(new_cube)
예제 #10
0
 def test_fails_percentile_data_max_mode(self):
     """Test a Value Error is raised if the maximum mode is applied to
     percentile data."""
     coord = "forecast_reference_time"
     plugin = WeightedBlendAcrossWholeDimension(coord, 'weighted_maximum')
     new_cube = percentile_cube()
     msg = ('The "weighted_maximum" mode is not supported for percentile '
            'data.')
     with self.assertRaisesRegex(ValueError, msg):
         plugin.check_percentile_coord(new_cube)
 def test_without_weights(self):
     """Test function when a data cube is provided, but no weights cube
     which should result in equal weightings."""
     plugin = WeightedBlendAcrossWholeDimension(self.coord)
     perc_coord = self.perc_cube.coord("percentile")
     result = plugin.percentile_weighted_mean(self.perc_cube, None,
                                              perc_coord)
     self.assertIsInstance(result, iris.cube.Cube)
     self.assertArrayAlmostEqual(result.data,
                                 BLENDED_PERCENTILE_DATA_EQUAL_WEIGHTS)
 def test_weights_do_not_sum_to_1_error(self):
     """Test that if a weights cube is provided which is not properly
     normalised, i.e. the weights do not sum to one over the blending
     dimension, an error is raised."""
     plugin = WeightedBlendAcrossWholeDimension(self.coord)
     weights = self.weights3d.data
     weights[0, 0, 1] = 1.0
     msg = "Weights do not sum to 1 over the blending coordinate."
     with self.assertRaisesRegex(ValueError, msg):
         plugin.check_weights(weights, 0)
예제 #13
0
    def test_scalar_coord(self):
        """Test plugin throws an error if trying to blending across a scalar
        coordinate."""

        coord = "dummy_scalar_coord"
        plugin = WeightedBlendAcrossWholeDimension(coord, 'weighted_mean')
        weights = ([1.0])
        msg = 'has no associated dimension'
        with self.assertRaisesRegex(ValueError, msg):
            _ = plugin.process(self.cube_with_scalar, weights)
예제 #14
0
 def tests_threshold_splicing_works_with_threshold(self):
     """Test splicing works when the blending is over threshold."""
     coord = "threshold"
     plugin = WeightedBlendAcrossWholeDimension(coord, 'weighted_mean')
     weights = np.array([0.8, 0.2])
     self.cube_threshold.data[0, :, :, :] = 0.5
     self.cube_threshold.data[1, :, :, :] = 0.8
     result = plugin.process(self.cube_threshold, weights)
     expected_result_array = np.ones((2, 2, 2)) * 0.56
     self.assertArrayAlmostEqual(result.data, expected_result_array)
    def test_with_weights(self):
        """Test function when a data cube and a weights cube are provided."""

        perc_cube = percentile_cube()
        coord = "forecast_reference_time"
        plugin = WeightedBlendAcrossWholeDimension(coord)
        perc_coord = perc_cube.coord("percentile")
        result = plugin.percentile_weighted_mean(perc_cube, self.weights1d, perc_coord)
        self.assertIsInstance(result, iris.cube.Cube)
        self.assertArrayAlmostEqual(result.data, BLENDED_PERCENTILE_DATA)
예제 #16
0
 def test_fails_weights_shape(self):
     """Test it raises a Value Error if weights shape does not match
        coord shape."""
     coord = "time"
     plugin = WeightedBlendAcrossWholeDimension(coord, 'weighted_mean')
     weights = [0.1, 0.2, 0.7]
     msg = ('The weights array must match the shape ' +
            'of the coordinate in the input cube')
     with self.assertRaisesRegexp(ValueError, msg):
         plugin.process(self.cube, weights)
예제 #17
0
 def test_fails_perc_coord_not_dim(self):
     """Test it raises a Value Error if not percentile coord not a dim."""
     coord = "time"
     plugin = WeightedBlendAcrossWholeDimension(coord, 'weighted_mean')
     new_cube = self.cube.copy()
     new_cube.add_aux_coord(
         AuxCoord([10.0], long_name="percentile_over_time"))
     msg = ('The percentile coord must be a dimension ' 'of the cube.')
     with self.assertRaisesRegexp(ValueError, msg):
         plugin.process(new_cube)
    def test_with_weights(self):
        """Test function when a data cube and a weights cube are provided."""

        coord = "forecast_reference_time"
        plugin = WeightedBlendAcrossWholeDimension(coord)
        result = plugin.weighted_mean(self.cube, self.weights1d)
        expected = np.full((2, 2), 1.5)

        self.assertIsInstance(result, iris.cube.Cube)
        self.assertArrayAlmostEqual(result.data, expected)
예제 #19
0
 def test_fails_more_than_one_perc_coord(self):
     """Test it raises a Value Error if more than one percentile coord."""
     coord = "time"
     plugin = WeightedBlendAcrossWholeDimension(coord, 'weighted_mean')
     new_cube = percentile_cube()
     new_cube.add_aux_coord(
         AuxCoord([10.0], long_name="percentile_over_dummy"))
     msg = ('There should only be one percentile coord ' 'on the cube.')
     with self.assertRaisesRegexp(ValueError, msg):
         plugin.process(new_cube)
 def test_fails_only_one_percentile_value(self):
     """Test it raises a Value Error if there is only one percentile."""
     plugin = WeightedBlendAcrossWholeDimension(self.coord)
     new_cube = Cube([[0.0]])
     new_cube.add_dim_coord(DimCoord([10.0], long_name="percentile"), 0)
     new_cube.add_dim_coord(
         DimCoord([10.0], long_name="forecast_reference_time"), 1)
     msg = ("Percentile coordinate does not have enough points"
            " in order to blend. Must have at least 2 percentiles.")
     with self.assertRaisesRegex(ValueError, msg):
         plugin.check_percentile_coord(new_cube)
 def test_scalar_coord(self):
     """Test plugin throws an error if trying to blending across a scalar
     coordinate."""
     coord = "dummy_scalar_coord"
     new_scalar_coord = AuxCoord(1, long_name=coord, units="no_unit")
     self.cube.add_aux_coord(new_scalar_coord)
     plugin = WeightedBlendAcrossWholeDimension(coord)
     weights = [1.0]
     msg = "has no associated dimension"
     with self.assertRaisesRegex(ValueError, msg):
         plugin(self.cube, weights)
 def test_unmatched_validity_time_exception(self):
     """Test that a ValueError is raised if the validity time of the
     slices over the blending coordinate differ. We should only be blending
     data at equivalent times unless we are triangular time blending."""
     self.cube.remove_coord("time")
     self.cube.coord("forecast_reference_time").rename("time")
     coord = "forecast_reference_time"
     plugin = WeightedBlendAcrossWholeDimension(coord)
     msg = "Attempting to blend data for different validity times."
     with self.assertRaisesRegex(ValueError, msg):
         plugin.check_compatible_time_points(self.cube)
 def test_weights_sum_to_1_but_with_a_zero_weight(self):
     """Test that if a weights cube is provided which is zero or properly
     normalised,  i.e. the weights sum to one over the blending
     dimension, no exception is raised."""
     weights = np.array([[[0, 0.3], [0.2, 0.4]], [[0, 0.3], [0.2, 0.4]],
                         [[0, 0.4], [0.6, 0.2]]])
     plugin = WeightedBlendAcrossWholeDimension(self.coord)
     try:
         plugin.check_weights(weights, 0)
     except ValueError:
         self.fail("Error testing check_weights")
 def test_no_weights_cube_provided(self):
     """Test that if a weights cube is not provided, the function generates
     a weights array that will equally weight all fields along the blending
     coordinate."""
     plugin = WeightedBlendAcrossWholeDimension(self.coord)
     result = plugin.non_percentile_weights(self.cube, None)
     (blending_coord_length, ) = self.cube.coord(self.coord).shape
     expected = (np.ones(blending_coord_length) /
                 blending_coord_length).astype(np.float32)
     self.assertEqual(self.cube.shape, result.shape)
     self.assertArrayEqual(expected, result[:, 0, 0])
 def test_with_weights_perc_as_float64(self):
     """Test function when a data cube and a weights cube are provided. But with
     a percentile coord that is float64"""
     plugin = WeightedBlendAcrossWholeDimension(self.coord)
     perc_coord = self.perc_cube.coord("percentile")
     perc_coord.points = perc_coord.points.astype(np.float64)
     result = plugin.percentile_weighted_mean(self.perc_cube,
                                              self.weights1d, perc_coord)
     self.assertIsInstance(result, iris.cube.Cube)
     self.assertArrayAlmostEqual(result.data, BLENDED_PERCENTILE_DATA)
     self.assertEqual(result.coord("percentile").points.dtype, np.float64)
    def test_with_spatially_varying_weights(self):
        """Test function when a data cube and a multi dimensional weights cube
        are provided. This tests spatially varying weights, where each x-y
        position is weighted differently in each slice along the blending
        coordinate."""
        plugin = WeightedBlendAcrossWholeDimension(self.coord)
        result = plugin.weighted_mean(self.cube, self.weights3d)
        expected = np.array([[2.7, 2.1], [2.4, 1.8]])

        self.assertIsInstance(result, iris.cube.Cube)
        self.assertArrayAlmostEqual(result.data, expected)
예제 #27
0
    def test_incompatible_weights_and_data_cubes(self):
        """Test an exception is raised if the weights cube and the data cube
        have incompatible coordinates."""

        coord = "forecast_reference_time"
        plugin = WeightedBlendAcrossWholeDimension(coord, 'weighted_mean')
        msg = (
            "precipitation_amount is a coordinate on the weights cube but it "
            "is not found on the cube we are trying to collapse.")
        with self.assertRaisesRegex(ValueError, msg):
            plugin.shape_weights(self.cube, self.weights_threshold)
 def test_3D_weights_3D_cube_weighted_mean_wrong_order(self):
     """Test a 3D cube of weights results in a 3D array of weights of the
     same shape as the data cube. In this test the weights cube has the
     same coordinates but slightly differently ordered. These should be
     reordered to match the cube."""
     plugin = WeightedBlendAcrossWholeDimension(self.coord)
     expected = self.weights3d.copy().data
     self.weights3d.transpose([1, 0, 2])
     result = plugin.shape_weights(self.cube, self.weights3d)
     self.assertEqual(expected.shape, result.shape)
     self.assertArrayEqual(expected.data, result)
예제 #29
0
    def test_without_weights(self):
        """Test function when a data cube is provided, but no weights cube
        which should result in equal weightings."""

        coord = "forecast_reference_time"
        plugin = WeightedBlendAcrossWholeDimension(coord, 'weighted_maximum')
        result = plugin.weighted_maximum(self.cube, None)
        expected = np.full((2, 2), 1.)

        self.assertIsInstance(result, iris.cube.Cube)
        self.assertArrayAlmostEqual(result.data, expected)
예제 #30
0
 def test_fails_only_one_percentile_value(self):
     """Test it raises a Value Error if there is only one percentile."""
     coord = "time"
     plugin = WeightedBlendAcrossWholeDimension(coord, 'weighted_mean')
     new_cube = Cube([[0.0]])
     new_cube.add_dim_coord(
         DimCoord([10.0], long_name="percentile_over_time"), 0)
     new_cube.add_dim_coord(DimCoord([10.0], long_name="time"), 1)
     msg = ('Percentile coordinate does not have enough points'
            ' in order to blend. Must have at least 2 percentiles.')
     with self.assertRaisesRegexp(ValueError, msg):
         plugin.process(new_cube)