Exemplo n.º 1
0
 def test_nearest_minimum_dz(self):
     """Test name generated when using the nearest neighbour with the
     smallest vertical displacment method."""
     plugin = NeighbourSelection(minimum_dz=True)
     expected = 'nearest_minimum_dz'
     result = plugin.neighbour_finding_method_name()
     self.assertEqual(result, expected)
Exemplo n.º 2
0
 def test_nearest(self):
     """Test name generated when using the default nearest neighbour
     method."""
     plugin = NeighbourSelection()
     expected = 'nearest'
     result = plugin.neighbour_finding_method_name()
     self.assertEqual(result, expected)
Exemplo n.º 3
0
 def test_nearest_land(self):
     """Test name generated when using the nearest land neighbour
     method."""
     plugin = NeighbourSelection(land_constraint=True)
     expected = 'nearest_land'
     result = plugin.neighbour_finding_method_name()
     self.assertEqual(result, expected)
Exemplo n.º 4
0
    def test_all_valid(self):
        """Test case in which all sites are valid and fall within domain."""
        plugin = NeighbourSelection()
        sites = [{
            'projection_x_coordinate': 1.0E4,
            'projection_y_coordinate': 1.0E4
        }, {
            'projection_x_coordinate': 1.0E5,
            'projection_y_coordinate': 5.0E4
        }]
        x_points = np.array(
            [site['projection_x_coordinate'] for site in sites])
        y_points = np.array(
            [site['projection_y_coordinate'] for site in sites])
        site_coords = np.stack((x_points, y_points), axis=1)

        sites_out, site_coords_out, out_x, out_y = (
            plugin.check_sites_are_within_domain(sites, site_coords, x_points,
                                                 y_points,
                                                 self.region_orography))

        self.assertArrayEqual(sites_out, sites)
        self.assertArrayEqual(site_coords_out, site_coords)
        self.assertArrayEqual(out_x, x_points)
        self.assertArrayEqual(out_y, y_points)
Exemplo n.º 5
0
 def test_nearest_land_minimum_dz(self):
     """Test name generated when using the nearest land neighbour
     with smallest vertical displacment method."""
     plugin = NeighbourSelection(land_constraint=True, minimum_dz=True)
     expected = "nearest_land_minimum_dz"
     result = plugin.neighbour_finding_method_name()
     self.assertEqual(result, expected)
Exemplo n.º 6
0
    def test_global_invalid(self, warning_list=None):
        """Test case with some sites falling outside the global domain."""
        plugin = NeighbourSelection()
        sites = [{
            'latitude': 0.0,
            'longitude': 0.0
        }, {
            'latitude': 50.0,
            'longitude': 0.0
        }, {
            'latitude': 100.0,
            'longitude': 0.0
        }]

        x_points = np.array([site['longitude'] for site in sites])
        y_points = np.array([site['latitude'] for site in sites])
        site_coords = np.stack((x_points, y_points), axis=1)

        plugin.global_coordinate_system = True

        sites_out, site_coords_out, out_x, out_y = (
            plugin.check_sites_are_within_domain(sites, site_coords, x_points,
                                                 y_points,
                                                 self.global_orography))

        self.assertArrayEqual(sites_out, sites[0:2])
        self.assertArrayEqual(site_coords_out[0:2], site_coords[0:2])
        self.assertArrayEqual(out_x, x_points[0:2])
        self.assertArrayEqual(out_y, y_points[0:2])

        msg = "1 spot sites fall outside the grid"
        self.assertTrue(any([msg in str(warning) for warning in warning_list]))
        self.assertTrue(
            any(item.category == UserWarning for item in warning_list))
Exemplo n.º 7
0
    def test_global_circular_valid(self):
        """Test case with a site defined using a longitide exceeding 180
        degrees (e.g. with longitudes that run 0 to 360) is still included
        as the circular x-coordinate means it will still be used correctly."""
        plugin = NeighbourSelection()
        sites = [{
            'latitude': 0.0,
            'longitude': 100.0
        }, {
            'latitude': 30.0,
            'longitude': 200.0
        }, {
            'latitude': 60.0,
            'longitude': 300.0
        }]

        x_points = np.array([site['longitude'] for site in sites])
        y_points = np.array([site['latitude'] for site in sites])
        site_coords = np.stack((x_points, y_points), axis=1)

        plugin.global_coordinate_system = True

        sites_out, site_coords_out, out_x, out_y = (
            plugin.check_sites_are_within_domain(sites, site_coords, x_points,
                                                 y_points,
                                                 self.global_orography))

        self.assertArrayEqual(sites_out, sites)
        self.assertArrayEqual(site_coords_out, site_coords)
        self.assertArrayEqual(out_x, x_points)
        self.assertArrayEqual(out_y, y_points)
Exemplo n.º 8
0
    def test_some_invalid(self, warning_list=None):
        """Test case with some sites falling outside the regional domain."""
        plugin = NeighbourSelection()
        sites = [{
            'projection_x_coordinate': 1.0E4,
            'projection_y_coordinate': 1.0E4
        }, {
            'projection_x_coordinate': 1.0E5,
            'projection_y_coordinate': 5.0E4
        }, {
            'projection_x_coordinate': 1.0E6,
            'projection_y_coordinate': 1.0E5
        }]

        x_points = np.array(
            [site['projection_x_coordinate'] for site in sites])
        y_points = np.array(
            [site['projection_y_coordinate'] for site in sites])
        site_coords = np.stack((x_points, y_points), axis=1)

        sites_out, site_coords_out, out_x, out_y = (
            plugin.check_sites_are_within_domain(sites, site_coords, x_points,
                                                 y_points,
                                                 self.region_orography))

        self.assertArrayEqual(sites_out, sites[0:2])
        self.assertArrayEqual(site_coords_out[0:2], site_coords[0:2])
        self.assertArrayEqual(out_x, x_points[0:2])
        self.assertArrayEqual(out_y, y_points[0:2])

        msg = "1 spot sites fall outside the grid"
        self.assertTrue(any([msg in str(warning) for warning in warning_list]))
        self.assertTrue(
            any(item.category == UserWarning for item in warning_list))
Exemplo n.º 9
0
    def test_different_cube_grids(self):
        """Test an error is raised if the land mask and orography cubes
        provided are on different grids."""

        msg = 'Orography and land_mask cubes are not on the same'
        plugin = NeighbourSelection()
        with self.assertRaisesRegex(ValueError, msg):
            plugin.process(self.region_sites, self.region_orography,
                           self.global_land_mask)
Exemplo n.º 10
0
    def test_global_land(self):
        """Test how the neighbour index changes when a land constraint is
        imposed. Here we expect to go 'west' to the first band of land
        which has an altitude of 5m. So we expect [1, 4, -3]."""

        plugin = NeighbourSelection(land_constraint=True, search_radius=1E7)
        result = plugin.process(self.global_sites, self.global_orography,
                                self.global_land_mask)
        expected = [[[1, 4, -3]]]

        self.assertArrayEqual(result.data, expected)
Exemplo n.º 11
0
    def test_non_metre_spatial_dimensions(self):
        """Test an error is raised if a regional grid is provided for which the
        spatial coordinates do not have units of metres."""

        self.region_orography.coord(axis='x').convert_units('feet')
        msg = 'Cube spatial coordinates for regional grids'

        plugin = NeighbourSelection()
        with self.assertRaisesRegex(ValueError, msg):
            plugin.process(self.region_sites, self.region_orography,
                           self.region_land_mask)
Exemplo n.º 12
0
    def test_only_land(self):
        """Test that the expected number of nodes are created and that a tree
        is returned. In this case the number of nodes should be this should be
        equal to the number of land points."""

        plugin = NeighbourSelection(land_constraint=True)
        result, result_nodes = plugin.build_KDTree(self.region_land_mask)
        expected_length = np.nonzero(self.region_land_mask.data)[0].shape[0]

        self.assertEqual(result_nodes.shape[0], expected_length)
        self.assertIsInstance(result, scipy.spatial.ckdtree.cKDTree)
Exemplo n.º 13
0
    def test_global_to_global(self):
        """Test coordinates generated when the input and output coordinate
        systems are the same, in this case Plate-Carree."""
        plugin = NeighbourSelection()
        x_points = np.array([0, 10, 20])
        y_points = np.array([0, 0, 10])
        expected = np.stack((x_points, y_points), axis=1)
        result = plugin._transform_sites_coordinate_system(
            x_points, y_points, self.global_orography)

        self.assertArrayAlmostEqual(result, expected)
Exemplo n.º 14
0
    def test_global_attribute(self):
        """Test that a cube is returned with a model_grid_hash that matches
        that of the global input grids."""

        expected = create_coordinate_hash(self.global_orography)
        plugin = NeighbourSelection()
        result = plugin.process(self.global_sites, self.global_orography,
                                self.global_land_mask)

        self.assertIsInstance(result, iris.cube.Cube)
        self.assertEqual(result.attributes['model_grid_hash'], expected)
Exemplo n.º 15
0
    def test_global_nearest(self):
        """Test that a cube is returned, here using a conventional site list
        with lat/lon site coordinates. Neighbour coordinates of [2, 4] are
        expected, with a vertical displacement of 2.."""

        plugin = NeighbourSelection()
        result = plugin.process(self.global_sites, self.global_orography,
                                self.global_land_mask)
        expected = [[[2, 4, 2]]]

        self.assertIsInstance(result, iris.cube.Cube)
        self.assertArrayEqual(result.data, expected)
Exemplo n.º 16
0
    def test_basic(self):
        """Test that the expected number of nodes are created and that a tree
        is returned; this should be the lengths of the x and y coordinates
        multiplied in the simple case."""

        plugin = NeighbourSelection()
        result, result_nodes = plugin.build_KDTree(self.region_land_mask)
        expected_length = (self.region_land_mask.shape[0] *
                           self.region_land_mask.shape[1])

        self.assertEqual(result_nodes.shape[0], expected_length)
        self.assertIsInstance(result, scipy.spatial.ckdtree.cKDTree)
Exemplo n.º 17
0
    def test_wmo_ids(self):
        """Test that the returned cube has the wmo_ids present when they are
        available. Should be None when they are not provided."""

        plugin = NeighbourSelection()
        sites = self.global_sites + [self.global_sites.copy()[0].copy()]
        sites[1]["wmo_id"] = None
        expected = ["1", "None"]

        result = plugin.process(sites, self.global_orography, self.global_land_mask)

        self.assertArrayEqual(result.coord("wmo_id").points, expected)
Exemplo n.º 18
0
    def test_basic(self):
        """Test a (0, 0) coordinate conversion to geocentric cartesian. This is
        expected to give an x coordinate which is the semi-major axis of the
        globe defined in the global coordinate system."""

        plugin = NeighbourSelection()
        x_points = np.array([0])
        y_points = np.array([0])
        result = plugin.geocentric_cartesian(self.global_orography, x_points, y_points)
        radius = self.global_orography.coord_system().semi_major_axis
        expected = [[radius, 0, 0]]
        self.assertArrayAlmostEqual(result, expected)
Exemplo n.º 19
0
    def test_error_for_unique_ids_longer_than_8_digits(self):
        """Test that an error is raised if the list of unique IDs contains values
        that are more than 8 characters in length. This limitation is inteded to
        give consistent length identifiers."""

        plugin = NeighbourSelection(unique_site_id_key="met_office_site_id")
        sites = self.global_sites
        sites[0]["met_office_site_id"] = 123456789

        msg = "Unique IDs should be 8 digits or less"
        with self.assertRaisesRegex(ValueError, msg):
            plugin.process(sites, self.global_orography, self.global_land_mask)
Exemplo n.º 20
0
    def test_region_to_region(self):
        """Test coordinates generated when the input and output coordinate
        systems are the same, in this case Lambert Azimuthal Equal Areas."""
        plugin = NeighbourSelection(
            site_coordinate_system=self.region_projection.as_cartopy_crs())
        x_points = np.array([0, 1, 2])
        y_points = np.array([0, 0, 1])
        expected = np.stack((x_points, y_points), axis=1)
        result = plugin._transform_sites_coordinate_system(
            x_points, y_points, self.region_orography)

        self.assertArrayAlmostEqual(result, expected)
Exemplo n.º 21
0
 def test_global_to_region(self):
     """Test coordinates generated when transforming from a global to
     regional coordinate system, in this case PlateCarree to Lambert
     Azimuthal Equal Areas."""
     plugin = NeighbourSelection()
     x_points = np.array([0, 10, 20])
     y_points = np.array([0, 0, 10])
     expected = [[0., 0.], [1111782.53516264, 0.],
                 [2189747.33076441, 1121357.32401753]]
     result = plugin._transform_sites_coordinate_system(
         x_points, y_points, self.region_orography)
     self.assertArrayAlmostEqual(result, expected)
Exemplo n.º 22
0
    def test_all_invalid_points(self):
        """Test a case where all nodes are beyond the imposed search_radius,
        so the returned value should be None."""

        plugin = NeighbourSelection()
        site_altitude = 5.
        nodes = np.array([[0, 4], [1, 4], [2, 4], [3, 4], [4, 4]])
        distance = np.full(5, np.inf)
        indices = np.arange(5)

        result = plugin.select_minimum_dz(self.region_orography, site_altitude,
                                          nodes, distance, indices)
        self.assertEqual(result, None)
Exemplo n.º 23
0
    def test_north_pole(self):
        """Test a (0, 90) coordinate conversion to geocentric cartesian, this
        being the north pole. This is expected to give an x coordinate which 0
        and a z coordinate equivalent to the semi-major axis of the globe
        defined in the global coordinate system."""

        plugin = NeighbourSelection()
        x_points = np.array([0])
        y_points = np.array([90])
        result = plugin.geocentric_cartesian(self.global_orography, x_points, y_points)
        radius = self.global_orography.coord_system().semi_major_axis
        expected = [[0, 0, radius]]
        self.assertArrayAlmostEqual(result, expected)
Exemplo n.º 24
0
 def test_region_to_global(self):
     """Test coordinates generated when transforming from a regional to
     global coordinate system, in this case Lambert Azimuthal Equal Areas
     to PlateCarree."""
     plugin = NeighbourSelection(
         site_coordinate_system=self.region_projection.as_cartopy_crs())
     x_points = np.array([0, 1, 2])
     y_points = np.array([0, 0, 1])
     expected = [[0., 0.], [8.98315284e-06, 0.],
                 [1.79663057e-05, 9.04369476e-06]]
     result = plugin._transform_sites_coordinate_system(
         x_points, y_points, self.global_orography)
     self.assertArrayAlmostEqual(result, expected)
Exemplo n.º 25
0
    def test_global_land_minimum_dz(self):
        """Test how the neighbour index changes when a land constraint is
        imposed and a minimum height difference condition. Here we expect to go
        'west' to the second band of land that we encounter, which has an
        altitude closer to that of the site. So we expect [0, 4, 1]."""

        plugin = NeighbourSelection(land_constraint=True, minimum_dz=True,
                                    search_radius=1E8)
        result = plugin.process(self.global_sites, self.global_orography,
                                self.global_land_mask)
        expected = [[[0, 4, 1]]]

        self.assertArrayEqual(result.data, expected)
Exemplo n.º 26
0
    def test_global_tied_case_nearest_land(self):
        """Test which neighbour is returned in an artificial case in which two
        neighbouring grid points are identically close. Identical to the test
        above except for the land constraint is now applied, so the neigbour is
        found using the KDTree. Using the KDTree the neighbour to the east is
        returned everytime the test is run."""

        self.global_sites[0]['longitude'] = -60.0
        plugin = NeighbourSelection(land_constraint=True, search_radius=1E8)
        result = plugin.process(self.global_sites, self.global_orography,
                                self.global_land_mask)
        expected = [[[4, 4, 2]]]

        self.assertArrayEqual(result.data, expected)
Exemplo n.º 27
0
    def test_region_attribute(self):
        """Test that a cube is returned with a model_grid_hash that matches
        that of the regional input grids."""

        expected = create_coordinate_hash(self.region_orography)
        plugin = NeighbourSelection(
            site_coordinate_system=self.region_projection.as_cartopy_crs(),
            site_x_coordinate='projection_x_coordinate',
            site_y_coordinate='projection_y_coordinate')
        result = plugin.process(self.region_sites, self.region_orography,
                                self.region_land_mask)

        self.assertIsInstance(result, iris.cube.Cube)
        self.assertEqual(result.attributes['model_grid_hash'], expected)
Exemplo n.º 28
0
    def test_basic(self):
        """Test that expected coordinates are returned."""

        plugin = NeighbourSelection()

        x_points = np.array(
            [site['projection_x_coordinate'] for site in self.region_sites])
        y_points = np.array(
            [site['projection_y_coordinate'] for site in self.region_sites])
        site_coords = np.stack((x_points, y_points), axis=1)

        expected = [[2, 4]]
        result = plugin.get_nearest_indices(site_coords, self.region_orography)
        self.assertArrayEqual(result, expected)
Exemplo n.º 29
0
    def test_use_of_unique_ids(self):
        """Test that the returned cube has the unique_id present when they are
        provided. These are stored as 8 digits encoded as strings, so
        zero-padding is expected."""

        plugin = NeighbourSelection(unique_site_id_key="met_office_site_id")
        sites = self.global_sites + [self.global_sites[0].copy()]
        sites[0]["met_office_site_id"] = sites[0]["wmo_id"]
        sites[1]["wmo_id"] = None
        sites[1]["met_office_site_id"] = 353
        expected = ["00000001", "00000353"]
        result = plugin.process(sites, self.global_orography, self.global_land_mask)

        self.assertArrayEqual(result.coord("met_office_site_id").points, expected)
Exemplo n.º 30
0
    def test_basic(self):
        """Test a simple case where the first element in the provided lists
        has the smallest vertical displacement to the site. Expect the
        coordinates of the first node to be returned."""

        plugin = NeighbourSelection()
        site_altitude = 3.
        nodes = np.array([[0, 4], [1, 4], [2, 4], [3, 4], [4, 4]])
        distance = np.arange(5)
        indices = np.arange(5)

        result = plugin.select_minimum_dz(self.region_orography, site_altitude,
                                          nodes, distance, indices)
        self.assertArrayEqual(result, nodes[0])