def test_equal_to(self):
        """
        Test conditional equal to test. Should return the indices of all
        values equal to 2 (the middle band of the data array).

        """
        plugin = ConditionalListExtract('equal_to')
        expected = [sorted(range(4, 8) * 12), range(0, 12) * 4]
        result = plugin.process(self.data, self.data_indices, 2)
        self.assertArrayEqual(expected, result)
    def test_greater_than(self):
        """
        Test conditional greater than test. Should return the indices of all
        values greater than 2 (the bottom band of the data array).

        """
        plugin = ConditionalListExtract('greater_than')
        expected = [sorted(range(8, 12) * 12), range(0, 12) * 4]
        result = plugin.process(self.data, self.data_indices, 2)
        self.assertArrayEqual(expected, result)
    def test_not_equal_to(self):
        """
        Test conditional not equal to test. Should return the indices of all
        values not equal to 2 (the top and bottom bands of the data array).

        """
        plugin = ConditionalListExtract('not_equal_to')
        expected = [sorted((range(0, 4) + range(8, 12))*12), range(0, 12)*8]
        result = plugin.process(self.data, self.data_indices, 2)
        self.assertArrayEqual(expected, result)
    def test_less_than(self):
        """
        Test conditional less than test. Should return the indices of all
        values less than 2 (the top band of the data array).

        """
        plugin = ConditionalListExtract('less_than')
        expected = [sorted(list(range(0, 4)) * 12), list(range(0, 12)) * 4]
        result = plugin.process(self.data, self.data_indices, 2)
        self.assertArrayEqual(expected, result)
Beispiel #5
0
    def minimum_height_error_neighbour(self, cube, sites, orography,
                                       land_mask=None,
                                       default_neighbours=None,
                                       no_neighbours=9):
        """
        Find the horizontally nearest neighbour, then relax the conditions
        to find the neighbouring point in the "no_neighbours" nearest nodes to
        the input coordinate that minimises the height difference. This is
        typically used for temperature, where vertical displacement can be much
        more important that horizontal displacement in determining the
        conditions.

        A vertical displacement bias may be applied with the vertical_bias
        keyword; whether to prefer grid points above or below the site, or
        neither.

        A land constraint may be applied that requires a land grid point be
        selected for a site that is over land. Currently this is established
        by checking that the nearest grid point barring any other conditions
        is a land point. If a site is a sea point it will use the nearest
        neighbour as there should be no vertical displacement difference with
        other sea points.

        Args:
            cube/sites : See process() above.

            default_neighbours (numpy.array):
                An existing list of neighbours from which variations are made
                using specified options (e.g. land_constraint). If unset the
                fast_nearest_neighbour method will be used to build this list.

            orography (numpy.array):
                Array of orography data extracted from an iris.cube.Cube that
                corresponds to the grids on which all other input diagnostics
                will be provided.

            land_mask (numpy.array):
                Array of land_mask data extracted from an iris.cube.Cube that
                corresponds to the grids on which all other input diagnostics
                will be provided.

            no_neighbours (int):
                Number of grid points about the site to consider when relaxing
                the nearest neighbour condition. If unset this defaults to 9.
                e.g. consider a 5x5 grid of points -> no_neighbours = 25.

        Returns:
            neighbours (numpy.array):
                See process() above.

        """

        # Use the default nearest neighbour list as a starting point, and
        # if for some reason it is missing, recreate the list using the fast
        # method.
        if default_neighbours is None:
            neighbours = self.fast_nearest_neighbour(cube, sites,
                                                     orography=orography)
        else:
            neighbours = default_neighbours

        for i_site, site in enumerate(sites.values()):

            altitude = site['altitude']

            # If site altitude is set with np.nan this method cannot be used.
            if altitude == np.nan:
                continue

            i, j, dz_nearest = (neighbours['i'][i_site],
                                neighbours['j'][i_site],
                                neighbours['dz'][i_site])
            edgepoint = neighbours['edgepoint'][i_site]

            node_list = nearest_n_neighbours(i, j, no_neighbours)
            if edgepoint:
                node_list = node_edge_check(node_list, cube)

            if self.land_constraint:
                # Check that we are considering a land point and that at least
                # one neighbouring point is also land. If not no modification
                # is made to the nearest neighbour coordinates.

                neighbour_nodes = nearest_n_neighbours(i, j, no_neighbours,
                                                       exclude_self=True)
                if edgepoint:
                    neighbour_nodes = node_edge_check(neighbour_nodes, cube)
                if not land_mask[i, j] or not any(land_mask[neighbour_nodes]):
                    continue

                # Filter the node_list to keep only land points
                # (land_mask == 1).
                node_list = ConditionalListExtract('not_equal_to').process(
                    land_mask, node_list, 0)

            dzs = altitude - orography[node_list]
            dz_subset = apply_bias(self.vertical_bias, dzs)

            ij_min = index_of_minimum_difference(dzs, subset_list=dz_subset)
            i_min, j_min = list_entry_from_index(node_list, ij_min)
            dz_min = abs(altitude - orography[i_min, j_min])

            # Test to ensure that if multiple vertical displacements are the
            # same we don't select a more distant point because of array
            # ordering.
            if not np.isclose(dz_min, abs(dz_nearest)):
                neighbours[i_site] = i_min, j_min, dzs[ij_min], edgepoint

        return neighbours
 def test_unknown_method(self):
     """Test that the plugin copes with an unknown method."""
     plugin = ConditionalListExtract('not_to')
     msg = 'Unknown method'
     with self.assertRaisesRegexp(AttributeError, msg):
         plugin.process(self.data, self.data_indices, 2)