def test_coordinate_not_found(self): """Coordinate not found on the cube.""" nbhooded_cube = self.weights_cube.copy() plugin = CollapseMaskedNeighbourhoodCoordinate("kitten", self.weights_cube) message = "Expected to find exactly 1 .* coordinate, but found none." with self.assertRaisesRegex(CoordinateNotFoundError, message): plugin.renormalize_weights(nbhooded_cube)
def test_normalizing_along_another_axis_with_error(self): """Normalizing along another axis, when raises error. In this case we are normalizing along an axis where in some places the sum along that axis is zero.""" nbhooded_cube = self.weights_cube.copy() plugin = CollapseMaskedNeighbourhoodCoordinate( "projection_x_coordinate", self.weights_cube) message = "Sum of weights must be > 0.0" with self.assertRaisesRegex(ValueError, message): plugin.renormalize_weights(nbhooded_cube)
def test_normalizing_along_another_axis(self): """Normalizing along another axis, when this is a valid thing to do. This is normalizing along the rows of the input weights.""" input_weights = np.array( [ [ [0.0, 0.7, 0.0, 0.0, 0.0], [0.0, 0.3, 0.0, 0.0, 0.0], [0.3, 0.1, 0.0, 0.0, 0.0], [0.2, 0.0, 0.0, 0.0, 0.0], [0.1, 0.0, 0.0, 0.0, 0.0], ], [ [1.0, 0.0, 1.0, 1.0, 1.0], [1.0, 0.0, 1.0, 1.0, 1.0], [0.0, 0.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.9, 0.1], [1.0, 1.0, 1.0, 0.0, 0.0], ], [ [0.2, 0.0, 0.0, 0.0, 0.0], [0.3, 0.0, 0.0, 0.0, 0.0], [0.1, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.1, 0.0], [0.0, 0.0, 0.0, 0.4, 0.8], ], ] ) expected_weights = np.array( [ [ [0.0, 1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0, 0.0], [0.75, 0.25, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0], ], [ [0.25, 0.0, 0.25, 0.25, 0.25], [0.25, 0.0, 0.25, 0.25, 0.25], [0.0, 0.0, 0.333333, 0.333333, 0.333333], [0.0, 0.0, 0.0, 0.9, 0.1], [0.333333, 0.333333, 0.333333, 0.0, 0.0], ], [ [1.0, 0.0, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 0.333333, 0.666667], ], ] ) weights_cube = self.weights_cube.copy(input_weights) nbhooded_cube = self.weights_cube.copy() plugin = CollapseMaskedNeighbourhoodCoordinate( "projection_x_coordinate", weights_cube ) weights = plugin.renormalize_weights(nbhooded_cube) self.assertArrayAlmostEqual(expected_weights, weights)
class Test_renormalize_weights(IrisTest): """Test the renormalize_weights function.""" def setUp(self): """Set up a weights cube and default plugin instance.""" self.mask = np.array([[[1, 1, 1, 0, 0], [1, 1, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 1, 1, 1, 1]], [[1, 1, 1, 0, 0], [1, 1, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 1, 1, 1, 1]], [[1, 1, 1, 0, 0], [1, 1, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 1, 1, 1, 1]]]) weights_data = np.array([[[0.8, 0.7, 0.0, 0.0, 0.0], [0.7, 0.3, 0.0, 0.0, 0.0], [0.3, 0.1, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0]], [[0.2, 0.3, 1.0, 1.0, 1.0], [0.3, 0.7, 1.0, 1.0, 1.0], [0.7, 0.9, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 0.9, 0.5], [1.0, 1.0, 1.0, 0.6, 0.2]], [[0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.1, 0.5], [0.0, 0.0, 0.0, 0.4, 0.8]]]) topographic_zone_points = [50, 150, 250] topographic_zone_bounds = [[0, 100], [100, 200], [200, 300]] weights_cubes = iris.cube.CubeList([]) for data, point, bounds in zip(weights_data, topographic_zone_points, topographic_zone_bounds): weights_cubes.append( set_up_topographic_zone_cube(data, point, bounds, num_grid_points=5)) self.weights_cube = weights_cubes.merge_cube() self.plugin = CollapseMaskedNeighbourhoodCoordinate( "topographic_zone", self.weights_cube) def test_basic(self): """Test weights_cube is still a cube after the function call""" nbhooded_cube = self.weights_cube.copy() self.plugin.renormalize_weights(nbhooded_cube) self.assertIsInstance(self.weights_cube, iris.cube.Cube) def test_no_NaNs_in_nbhooded_cube(self): """No NaNs in the neighbourhood cube, so no renormalization is needed""" nbhooded_cube = self.weights_cube.copy() expected_weights = self.weights_cube.data.copy() self.plugin.renormalize_weights(nbhooded_cube) self.assertArrayAlmostEqual(expected_weights, self.weights_cube.data) def test_all_NaNs_in_nbhooded_cube(self): """Test an error is raised when all NaNs in the nbhood cube so cannot have any sensible weights.""" nbhood_data = np.empty(self.weights_cube.data.shape) nbhood_data[:] = np.nan nbhooded_cube = self.weights_cube.copy(nbhood_data) message = "Sum of weights must be > 0.0" with self.assertRaisesRegex(ValueError, message): self.plugin.renormalize_weights(nbhooded_cube) def test_no_NaNs_in_nbhooded_cube_and_masked_weights(self): """No NaNs in the neighbourhood cube, but masked weights.""" nbhooded_cube = self.weights_cube.copy() self.weights_cube.data = np.ma.masked_array(self.weights_cube.data, mask=self.mask) expected_weights = self.weights_cube.data.copy() self.plugin.renormalize_weights(nbhooded_cube) self.assertArrayAlmostEqual(expected_weights.data, self.weights_cube.data.data) self.assertArrayAlmostEqual(expected_weights.mask, self.weights_cube.data.mask) def test_some_NaNs_in_nbhooded_cube(self): """Some NaNs in the neighbourhood cube, so renormalization is needed""" nbhood_data = np.ones((3, 5, 5)) nbhood_data[0, 0:2, 0] = np.nan nbhood_data[2, 2:4, 4] = np.nan expected_weights = np.array([[[0.0, 0.7, 0.0, 0.0, 0.0], [0.0, 0.3, 0.0, 0.0, 0.0], [0.3, 0.1, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0]], [[1.0, 0.3, 1.0, 1.0, 1.0], [1.0, 0.7, 1.0, 1.0, 1.0], [0.7, 0.9, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 0.9, 1.0], [1.0, 1.0, 1.0, 0.6, 0.2]], [[0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.1, 0.0], [0.0, 0.0, 0.0, 0.4, 0.8]]]) nbhooded_cube = self.weights_cube.copy(nbhood_data) self.plugin.renormalize_weights(nbhooded_cube) self.assertArrayAlmostEqual(expected_weights, self.weights_cube.data) def test_some_NaNs_in_nbhooded_cube_and_masked_weights(self): """Some NaNs in the neighbourhood cube, so renormalization is needed. As the points with NaNs in the neighbourhood cube are masked in the weights cube then they are not renormalizeed.""" nbhood_data = np.ones((3, 5, 5)) nbhood_data[0, 0:2, 0] = np.nan nbhood_data[2, 2:4, 4] = np.nan nbhooded_cube = self.weights_cube.copy() self.weights_cube.data = np.ma.masked_array(self.weights_cube.data, mask=self.mask) expected_weights = self.weights_cube.data.copy() self.plugin.renormalize_weights(nbhooded_cube) self.assertArrayAlmostEqual(expected_weights.data, self.weights_cube.data.data) self.assertArrayAlmostEqual(expected_weights.mask, self.weights_cube.data.mask) def test_coordinate_not_found(self): """Coordinate not found on the cube.""" nbhooded_cube = self.weights_cube.copy() plugin = CollapseMaskedNeighbourhoodCoordinate("kitten", self.weights_cube) message = "Expected to find exactly 1 .* coordinate, but found none." with self.assertRaisesRegex(CoordinateNotFoundError, message): plugin.renormalize_weights(nbhooded_cube) def test_normalizing_along_another_axis_with_error(self): """Normalizing along another axis, when raises error. In this case we are normalizing along an axis where in some places the sum along that axis is zero.""" nbhooded_cube = self.weights_cube.copy() plugin = CollapseMaskedNeighbourhoodCoordinate( "projection_x_coordinate", self.weights_cube) message = "Sum of weights must be > 0.0" with self.assertRaisesRegex(ValueError, message): plugin.renormalize_weights(nbhooded_cube) def test_normalizing_along_another_axis(self): """Normalizing along another axis, when this is a valid thing to do. This is normalizing along the rows of the input weights.""" input_weights = np.array([[[0.0, 0.7, 0.0, 0.0, 0.0], [0.0, 0.3, 0.0, 0.0, 0.0], [0.3, 0.1, 0.0, 0.0, 0.0], [0.2, 0.0, 0.0, 0.0, 0.0], [0.1, 0.0, 0.0, 0.0, 0.0]], [[1.0, 0.0, 1.0, 1.0, 1.0], [1.0, 0.0, 1.0, 1.0, 1.0], [0.0, 0.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.9, 0.1], [1.0, 1.0, 1.0, 0.0, 0.0]], [[0.2, 0.0, 0.0, 0.0, 0.0], [0.3, 0.0, 0.0, 0.0, 0.0], [0.1, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.1, 0.0], [0.0, 0.0, 0.0, 0.4, 0.8]]]) expected_weights = np.array([[[0.0, 1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0, 0.0], [0.75, 0.25, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0]], [[0.25, 0.0, 0.25, 0.25, 0.25], [0.25, 0.0, 0.25, 0.25, 0.25], [0.0, 0.0, 0.333333, 0.333333, 0.333333], [0.0, 0.0, 0.0, 0.9, 0.1], [0.333333, 0.333333, 0.333333, 0.0, 0.0]], [[1.0, 0.0, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 0.333333, 0.666667]]]) weights_cube = self.weights_cube.copy(input_weights) nbhooded_cube = self.weights_cube.copy() plugin = CollapseMaskedNeighbourhoodCoordinate( "projection_x_coordinate", weights_cube) plugin.renormalize_weights(nbhooded_cube) self.assertArrayAlmostEqual(expected_weights, weights_cube.data)