def test_aggregating_over_masked_cubes_and_coordinates(self):
        """Test of aggregating over coordinates and cubes in a single call
        using a masked reliability table. In this instance the latitude and
        longitude coordinates are collapsed and the values from two input cube
        combined."""

        frt = "forecast_reference_time"
        expected_points = self.masked_different_frt.coord(frt).points
        expected_bounds = [[
            self.masked_reliability_cube.coord(frt).bounds[0][0],
            self.masked_different_frt.coord(frt).bounds[-1][1],
        ]]
        expected_result = np.array([
            [0.0, 0.0, 2.0, 4.0, 2.0],
            [0.0, 0.625, 2.625, 3.25, 2.0],
            [0.0, 3.0, 5.0, 4.0, 2.0],
        ])

        plugin = Plugin()
        result = plugin.process(
            [self.masked_reliability_cube, self.masked_different_frt],
            coordinates=["latitude", "longitude"],
        )
        self.assertIsInstance(result.data, np.ma.MaskedArray)
        assert_array_equal(result.data, expected_result)
        self.assertEqual(result.coord(frt).points, expected_points)
        assert_array_equal(result.coord(frt).bounds, expected_bounds)
def test_frt_coord_invalid_bounds(reliability_cube, overlapping_frt):
    """Test that an exception is raised if the input cubes have forecast
    reference time bounds that overlap."""

    plugin = Plugin()
    msg = "Reliability calibration tables have overlapping"
    with pytest.raises(ValueError, match=msg):
        plugin._check_frt_coord([reliability_cube, overlapping_frt])
def test_single_cube(reliability_cube):
    """Test the plugin returns an unaltered cube if only one is passed in
    and no coordinates are given."""

    plugin = Plugin()
    expected = reliability_cube.copy()
    result = plugin.process([reliability_cube])
    assert result == expected
Exemple #4
0
    def test_invalid_bounds(self):
        """Test that an exception is raised if the input cubes have forecast
        reference time bounds that overlap."""

        plugin = Plugin()
        msg = "Reliability calibration tables have overlapping"
        with self.assertRaisesRegex(ValueError, msg):
            plugin._check_frt_coord([self.reliability_cube, self.overlapping_frt])
    def test_single_cube(self):
        """Test the plugin returns an unaltered cube if only one is passed in
        and no coordinates are given."""

        plugin = Plugin()

        expected = self.reliability_cube.copy()
        result = plugin.process([self.reliability_cube])

        self.assertEqual(result, expected)
 def test_matching_bounds(self):
     """Test that no exception is raised in the input cubes if a cube
     contains matching bounds."""
     lower_bound = self.reliability_cube.coord(
         "forecast_reference_time").bounds[0][0]
     self.reliability_cube.coord("forecast_reference_time").bounds = [[
         lower_bound, lower_bound
     ]]
     plugin = Plugin()
     plugin._check_frt_coord([self.reliability_cube, self.different_frt])
    def test_aggregating_cubes_with_overlapping_frt(self):
        """Test that attempting to aggregate reliability calibration tables
        with overlapping forecast reference time bounds raises an exception.
        The presence of overlapping forecast reference time bounds indicates
        that the same forecast data has contributed to both tables, thus
        aggregating them would double count these contributions."""

        plugin = Plugin()
        msg = "Reliability calibration tables have overlapping"
        with self.assertRaisesRegex(ValueError, msg):
            plugin.process([self.reliability_cube, self.overlapping_frt])
    def test_aggregating_over_single_cube_coordinates(self):
        """Test of aggregating over coordinates of a single cube. In this
        instance the latitude and longitude coordinates are collapsed."""

        frt = "forecast_reference_time"
        expected_points = self.reliability_cube.coord(frt).points
        expected_bounds = self.reliability_cube.coord(frt).bounds

        plugin = Plugin()
        result = plugin.process([self.reliability_cube],
                                coordinates=["latitude", "longitude"])
        assert_array_equal(result.data, self.lat_lon_collapse)
        self.assertEqual(result.coord(frt).points, expected_points)
        assert_array_equal(result.coord(frt).bounds, expected_bounds)
def process(*cubes: cli.inputcube,
            coordinates: cli.comma_separated_list = None):
    """Aggregate reliability tables.

    Aggregate multiple reliability calibration tables and/or aggregate over
    coordinates within the table(s) to produce a new reliability calibration
    table.

    Args:
        cubes (list of iris.cube.Cube):
            The cube or cubes containing the reliability calibration tables
            to aggregate.
        coordinates (list):
            A list of coordinates over which to aggregate the reliability
            calibration table using summation. If the list is empty
            and a single cube is provided, this cube will be returned
            unchanged.
    Returns:
        iris.cube.Cube:
            Aggregated reliability table.
    """
    from improver.calibration.reliability_calibration import (
        AggregateReliabilityCalibrationTables, )

    return AggregateReliabilityCalibrationTables()(cubes,
                                                   coordinates=coordinates)
def test_process_aggregating_multiple_cubes(reliability_cube, different_frt,
                                            expected_table):
    """Test of aggregating two cubes without any additional coordinate
    collapsing."""
    frt = "forecast_reference_time"
    expected_points = different_frt.coord(frt).points
    expected_bounds = [[
        reliability_cube.coord(frt).bounds[0][0],
        different_frt.coord(frt).bounds[-1][1],
    ]]
    plugin = Plugin()
    result = plugin.process([reliability_cube, different_frt])
    assert_array_equal(result.data, expected_table * 2)
    assert_array_equal(result.shape, (3, 5, 3, 3))
    assert_array_equal(result.coord(frt).points, expected_points)
    assert_array_equal(result.coord(frt).bounds, expected_bounds)
def test_process_and_aggregate(create_rel_table_inputs):
    """Test that aggregation during construction produces the same result as
    applying the two plugins sequentially."""
    # use the spatial coordinates for aggregation - input is a parameterised fixture
    if create_rel_table_inputs.forecast.coords("spot_index"):
        agg_coords = ["spot_index"]
    else:
        agg_coords = ["longitude", "latitude"]

    # construct and aggregate as two separate plugins
    constructed = Plugin(
        single_value_lower_limit=True, single_value_upper_limit=True
    ).process(create_rel_table_inputs.forecast, create_rel_table_inputs.truth)
    aggregated = AggregateReliabilityCalibrationTables().process(
        [constructed], agg_coords
    )

    # construct plugin with aggregate_coords option
    constructed_with_agg = Plugin(
        single_value_lower_limit=True, single_value_upper_limit=True
    ).process(
        create_rel_table_inputs.forecast, create_rel_table_inputs.truth, agg_coords
    )

    # check that the two cubes are identical
    assert constructed_with_agg == aggregated
Exemple #12
0
    def test_aggregating_over_cubes_and_coordinates(self):
        """Test of aggregating over coordinates and cubes in a single call. In
        this instance the latitude and longitude coordinates are collapsed and
        the values from two input cube combined."""

        frt = 'forecast_reference_time'
        expected_points = self.different_frt.coord(frt).points
        expected_bounds = [[
            self.reliability_cube.coord(frt).bounds[0][0],
            self.different_frt.coord(frt).bounds[-1][1]
        ]]

        plugin = Plugin()
        result = plugin.process([self.reliability_cube, self.different_frt],
                                coordinates=['latitude', 'longitude'])
        assert_array_equal(result.data, self.lat_lon_collapse * 2)
        self.assertEqual(result.coord(frt).points, expected_points)
        assert_array_equal(result.coord(frt).bounds, expected_bounds)
def test_process_aggregating_over_cubes_and_coordinates(
        reliability_cube, different_frt, lat_lon_collapse):
    """Test of aggregating over coordinates and cubes in a single call. In
    this instance the latitude and longitude coordinates are collapsed and
    the values from two input cube combined."""

    frt = "forecast_reference_time"
    expected_points = different_frt.coord(frt).points
    expected_bounds = [[
        reliability_cube.coord(frt).bounds[0][0],
        different_frt.coord(frt).bounds[-1][1],
    ]]

    plugin = Plugin()
    result = plugin.process(
        [reliability_cube, different_frt],
        coordinates=["latitude", "longitude"],
    )
    assert_array_equal(result.data, lat_lon_collapse * 2)
    assert_array_equal(result.coord(frt).points, expected_points)
    assert_array_equal(result.coord(frt).bounds, expected_bounds)
    def test_valid_bounds(self):
        """Test that no exception is raised if the input cubes have forecast
        reference time bounds that do not overlap."""

        plugin = Plugin()
        plugin._check_frt_coord([self.reliability_cube, self.different_frt])