def missing_additional_data(self, method, ancillary_data, additional_data):
        """Test that the plugin copes with missing additional data."""

        plugin = Plugin(method)
        with self.assertRaises(KeyError):
            plugin.process(self.cube, self.sites, self.neighbour_list,
                           ancillary_data, additional_data)
    def test_extracted_value_deep_valley(self):
        """Test that the plugin returns the correct value.

        Site set to be 100m or 70m below the land surface (90m or 60m below sea
        level). The enforcement of a maximum extrapolation down into valleys
        should result in the two site altitudes returning the same temperature.

        This is an extrapolation scenario, an 'unresolved valley'."""

        # Temperatures set up to mimic a cold night with an inversion where
        # valley temperatures may be expected to fall considerably due to
        # katabatic drainage.
        t_level0 = np.ones((1, 20, 20)) * 0.
        t_level1 = np.ones((1, 20, 20)) * 1.
        t_level2 = np.ones((1, 20, 20)) * 2.
        t_data = np.vstack((t_level0, t_level1, t_level2))
        t_data.resize((3, 20, 20))

        self.ad['temperature_on_height_levels'].data = t_data
        cube = self.cube.extract(self.time_extract)
        cube.data = cube.data * 0.0

        self.sites['100']['altitude'] = -90.
        self.neighbour_list['dz'] = -100.
        plugin = Plugin(self.method)

        result_dz = plugin.process(cube, self.sites, self.neighbour_list,
                                   self.ancillary_data, self.ad, **self.kwargs)

        self.sites['100']['altitude'] = -60.
        self.neighbour_list['dz'] = -70.
        result_70 = plugin.process(cube, self.sites, self.neighbour_list,
                                   self.ancillary_data, self.ad, **self.kwargs)

        self.assertEqual(result_dz.data, result_70.data)
    def different_projection(self, method, ancillary_data, additional_data,
                             expected, **kwargs):
        """Test that the plugin copes with non-lat/lon grids."""

        src_crs = ccrs.PlateCarree()
        trg_crs = ccrs.TransverseMercator(central_latitude=0,
                                          central_longitude=0)
        trg_crs_iris = coord_systems.TransverseMercator(0, 0, 0, 0, 1.0)

        lons = [-50, 50]
        lats = [-25, 25]
        x, y = [], []
        for lon, lat in zip(lons, lats):
            x_trg, y_trg = trg_crs.transform_point(lon, lat, src_crs)
            x.append(x_trg)
            y.append(y_trg)

        new_x = DimCoord(np.linspace(x[0], x[1], 20),
                         standard_name='projection_x_coordinate',
                         units='m',
                         coord_system=trg_crs_iris)
        new_y = DimCoord(np.linspace(y[0], y[1], 20),
                         standard_name='projection_y_coordinate',
                         units='m',
                         coord_system=trg_crs_iris)

        new_cube = Cube(np.zeros(400).reshape(20, 20),
                        long_name="air_temperature",
                        dim_coords_and_dims=[(new_y, 0), (new_x, 1)],
                        units="K")

        cube = self.cube.copy()
        cube = cube.regrid(new_cube, iris.analysis.Nearest())

        if ancillary_data is not None:
            ancillary_data['orography'] = ancillary_data['orography'].regrid(
                new_cube, iris.analysis.Nearest())
        if additional_data is not None:
            for ad in additional_data.keys():
                additional_data[ad] = additional_data[ad].regrid(
                    new_cube, iris.analysis.Nearest())

        # Define neighbours on this new projection
        self.neighbour_list['i'] = 11
        self.neighbour_list['j'] = 11

        plugin = Plugin(method)
        with iris.FUTURE.context(cell_datetime_objects=True):
            cube = cube.extract(self.time_extract)

        result = plugin.process(cube, self.sites, self.neighbour_list,
                                ancillary_data, additional_data, **kwargs)

        self.assertEqual(cube.coord_system(), trg_crs_iris)
        self.assertAlmostEqual(result.data, expected)
        self.assertEqual(result.coord(axis='y').name(), 'latitude')
        self.assertEqual(result.coord(axis='x').name(), 'longitude')
        self.assertAlmostEqual(result.coord(axis='y').points, 4.74)
        self.assertAlmostEqual(result.coord(axis='x').points, 9.47)
 def test_make_spotdata_cube(self):
     """Test the make_cube function."""
     plugin = Plugin().make_cube
     data = np.array([123])
     result = plugin(self.cube, data, self.sites)
     self.assertIsInstance(result, Cube)
     self.assertEqual(result.data, data)
     self.assertEqual(result.name(), 'air_temperature')
    def return_type(self, method, ancillary_data, additional_data, **kwargs):
        """Test that the plugin returns an iris.cube.Cube."""
        plugin = Plugin(method)
        cube = self.cube.extract(self.time_extract)
        result = plugin.process(cube, self.sites, self.neighbour_list,
                                ancillary_data, additional_data, **kwargs)

        self.assertIsInstance(result, Cube)
 def test_aux_coord_and_metadata(self):
     """Test that the plugin returns cubes with expected metadata and
     coordinates."""
     plugin = Plugin().make_cube
     data = np.array([123])
     result = plugin(self.cube, data, self.sites)
     self.assertEqual(result.coord('forecast_reference_time'),
                      self.cube.coord('forecast_reference_time'))
     self.assertEqual(result.metadata, self.cube.metadata)
 def test_missing_forecast_ref_time_in_source(self):
     """Ensure an error is raised if a source cube is missing a forecast
     reference time."""
     plugin = Plugin().make_cube
     data = np.array([123])
     self.cube.remove_coord('forecast_reference_time')
     msg = 'No forecast reference time found on source cube.'
     with self.assertRaisesRegexp(CoordinateNotFoundError, msg):
         plugin(self.cube, data, self.sites)
    def extracted_value(self, method, ancillary_data, additional_data,
                        expected, **kwargs):
        """Test that the plugin returns the correct value."""
        plugin = Plugin(method)
        cube = self.cube.extract(self.time_extract)
        result = plugin.process(cube, self.sites, self.neighbour_list,
                                ancillary_data, additional_data, **kwargs)

        self.assertArrayAlmostEqual(result.data, expected)
    def extracted_value(self, method, ancillary_data, additional_data,
                        expected, **kwargs):
        """Test that the plugin returns the correct value."""
        plugin = Plugin(method)
        with iris.FUTURE.context(cell_datetime_objects=True):
            cube = self.cube.extract(self.time_extract)
        result = plugin.process(cube, self.sites, self.neighbour_list,
                                ancillary_data, additional_data, **kwargs)

        self.assertAlmostEqual(result.data, expected)
    def test_invalid_method(self):
        """Test that the plugin can handle an invalid method being passed
        in."""

        plugin = Plugin('quantum_interpolation')
        msg = 'Unknown method'
        cube = self.cube.extract(self.time_extract)
        with self.assertRaisesRegex(AttributeError, msg):
            plugin.process(cube, self.sites, self.neighbour_list, {}, None,
                           **self.kwargs)
    def test_build_latitude_coordinate(self):
        """Test building a latitude coordinate."""

        plugin = Plugin()._build_coordinate
        coord_system = iris.coord_systems.GeogCS(6371229.0)
        result = plugin(self.latitudes,
                        'latitude',
                        units='degrees',
                        coord_system=coord_system)
        self.assertArrayEqual(result.points, self.latitudes)
        self.assertEqual(result.name(), 'latitude')
        self.assertIsInstance(result, DimCoord)
        self.assertEqual(result.units, 'degrees')
    def test_cube_reorder_realization(self):
        """Test reordering a cube with a realization coordinate to make it come
        first."""

        plugin = Plugin().make_stat_coordinate_first
        cube = set_up_cube(zero_point_indices=((0, 0, 2, 2), (1, 0, 3, 3),
                                               (0, 1, 0, 0), (1, 1, 2, 1)),
                           num_time_points=2,
                           num_grid_points=5,
                           num_realization_points=2)
        incorrect_cube = cube.copy()
        incorrect_cube.transpose([1, 2, 0, 3])
        result = plugin(incorrect_cube)
        self.assertEqual(cube.coords()[0].name(), result.coords()[0].name())
        self.assertEqual(cube.coords(), result.coords())
Exemple #13
0
    def test__build_coordinates(self):
        """
        Test the _build_coordinates private function.

        """
        plugin = Plugin()._build_coordinates
        points = np.array([0, 1, 2])
        indices, latitude, longitude, altitude, utc_offset, wmo_site = (plugin(
            points, points, points, points[::-1], points))
        self.assertArrayEqual(indices.points, points)
        self.assertArrayEqual(altitude.points, points)
        self.assertArrayEqual(utc_offset.points, points[::-1])
        self.assertEqual(latitude.name(), 'latitude')
        self.assertEqual(longitude.name(), 'longitude')
        self.assertEqual(wmo_site.name(), 'wmo_site')
        self.assertIsInstance(indices, DimCoord)
        self.assertIsInstance(latitude, AuxCoord)
Exemple #14
0
    def different_projection(self, method, ancillary_data, additional_data,
                             expected, **kwargs):
        """Test that the plugin copes with non-lat/lon grids."""

        trg_crs = None
        src_crs = ccrs.PlateCarree()
        trg_crs = ccrs.LambertConformal(central_longitude=50,
                                        central_latitude=10)
        trg_crs_iris = coord_systems.LambertConformal(central_lon=50,
                                                      central_lat=10)
        lons = self.cube.coord('longitude').points
        lats = self.cube.coord('latitude').points
        x, y = [], []
        for lon, lat in zip(lons, lats):
            x_trg, y_trg = trg_crs.transform_point(lon, lat, src_crs)
            x.append(x_trg)
            y.append(y_trg)

        new_x = AuxCoord(x,
                         standard_name='projection_x_coordinate',
                         units='m',
                         coord_system=trg_crs_iris)
        new_y = AuxCoord(y,
                         standard_name='projection_y_coordinate',
                         units='m',
                         coord_system=trg_crs_iris)

        cube = Cube(self.cube.data,
                    long_name="air_temperature",
                    dim_coords_and_dims=[(self.cube.coord('time'), 0)],
                    aux_coords_and_dims=[(new_y, 1), (new_x, 2)],
                    units="K")

        plugin = Plugin(method)
        with iris.FUTURE.context(cell_datetime_objects=True):
            cube = cube.extract(self.time_extract)
        result = plugin.process(cube, self.sites, self.neighbour_list,
                                ancillary_data, additional_data, **kwargs)

        self.assertEqual(cube.coord_system(), trg_crs_iris)
        self.assertAlmostEqual(result.data, expected)
        self.assertEqual(result.coord(axis='y').name(), 'latitude')
        self.assertEqual(result.coord(axis='x').name(), 'longitude')
        self.assertAlmostEqual(result.coord(axis='y').points, 4.74)
        self.assertAlmostEqual(result.coord(axis='x').points, 9.47)
    def test_cube_reorder_percentile_and_realization(self):
        """Test reordering a cube with a percentile and a realization
        coordinate. Should produce a warning and promote the first statistical
        coordinate that is found."""

        plugin = Plugin().make_stat_coordinate_first
        cube = set_up_cube(zero_point_indices=((0, 0, 2, 2), (1, 0, 3, 3),
                                               (0, 1, 0, 0), (1, 1, 2, 1)),
                           num_time_points=2,
                           num_grid_points=5,
                           num_realization_points=2)
        realization = cube.coords()[0][0].copy()
        cube.coords()[0].rename('percentile_over_time')
        cube.add_aux_coord(realization)
        cube = iris.util.new_axis(cube, 'realization')
        incorrect_cube = cube.copy()
        incorrect_cube.transpose([2, 1, 0, 3, 4])
        with warnings.catch_warnings(record=True) as w_messages:
            result = plugin(incorrect_cube)
            assert len(w_messages) == 1
            assert issubclass(w_messages[0].category, UserWarning)
            assert "More than one statistical" in str(w_messages[0])
        self.assertEqual(cube.coords()[0].name(), result.coords()[0].name())