def setUp(self): """Set up the cube.""" height_points = np.array([5.0, 10.0, 20.0]) cube = _set_up_height_cube(height_points) self.plugin_positive = Integration("height", positive_integration=True) self.plugin_positive.input_cube = cube.copy() self.plugin_negative = Integration("height") self.plugin_negative.input_cube = cube.copy()
def setUp(self): """Set up the cube.""" self.ascending_height_points = np.array([5.0, 10.0, 20.0]) self.ascending_cube = _set_up_height_cube(self.ascending_height_points) self.descending_height_points = np.array([20.0, 10.0, 5.0]) self.descending_cube = _set_up_height_cube( self.descending_height_points, ascending=False) self.plugin_positive = Integration("height", positive_integration=True) self.plugin_negative = Integration("height")
def __init__(self, precision=0.005, coord_name_to_integrate="height", start_point=None, end_point=None, direction_of_integration="negative"): """ Initialise class. Keyword Args: precision (float): The precision to which the Newton iterator must converge before returning wet bulb temperatures. coord_name_to_integrate (string): Name of the coordinate to be integrated. start_point (float or None): Point at which to start the integration. Default is None. If start_point is None, integration starts from the first available point. end_point (float or None): Point at which to end the integration. Default is None. If end_point is None, integration will continue until the last available point. direction_of_integration (string): Description of the direction in which to integrate. Options are 'positive' or 'negative'. 'positive' corresponds to the values within the array increasing as the array index increases. 'negative' corresponds to the values within the array decreasing as the array index increases. """ self.wet_bulb_temperature_plugin = ( WetBulbTemperature(precision=precision)) self.integration_plugin = Integration( coord_name_to_integrate, start_point=start_point, end_point=end_point, direction_of_integration=direction_of_integration) self.coord_name_to_integrate = coord_name_to_integrate
def __init__(self, coord_name_to_integrate="height", start_point=None, end_point=None, direction_of_integration="negative"): """ Initialise class. Args: coord_name_to_integrate (str): Name of the coordinate to be integrated. start_point (float or None): Point at which to start the integration. Default is None. If start_point is None, integration starts from the first available point. end_point (float or None): Point at which to end the integration. Default is None. If end_point is None, integration will continue until the last available point. direction_of_integration (str): Description of the direction in which to integrate. Options are 'positive' or 'negative'. 'positive' corresponds to the values within the array increasing as the array index increases. 'negative' corresponds to the values within the array decreasing as the array index increases. """ self.integration_plugin = Integration( coord_name_to_integrate, start_point=start_point, end_point=end_point, direction_of_integration=direction_of_integration) self.coord_name_to_integrate = coord_name_to_integrate
def test_end_point_negative(self): """Test that the resulting cube contains the expected data when a end_point is specified, so that only part of the column is integrated. For integration in the negative direction (equivalent to integrating downwards for a height coordinate), the presense of an end_point indicates that the integration may end above the lowest height within the column to be integrated.""" expected = np.array( [[[25.00, 25.00, 25.00], [25.00, 25.00, 25.00], [25.00, 25.00, 25.00]]]) coord_name = "height" end_point = 8. direction = "negative" result = ( Integration( coord_name, end_point=end_point, direction_of_integration=direction ).perform_integration( self.negative_upper_bounds_cube, self.negative_lower_bounds_cube, self.negative_integrated_cube)) self.assertArrayAlmostEqual( result.coord("height").points, np.array([10.])) self.assertArrayAlmostEqual(result.data, expected)
def test_end_point_at_bound_negative(self): """Test that the resulting cube contains the expected data when a end_point is specified, so that only part of the column is integrated. In this instance, the end_point of 10 is equal to the available height levels [5., 10., 20.]. If the end_point is lower than a height level then integration will end. In this example, the end_point is equal to a height level, so the layer above the end_point is included within the integration. For integration in the negative direction (equivalent to integrating downwards for a height coordinate), the presense of an end_point indicates that the integration may end above the lowest height within the column to be integrated.""" expected = np.array( [[[25.00, 25.00, 25.00], [25.00, 25.00, 25.00], [25.00, 25.00, 25.00]]]) coord_name = "height" end_point = 10. direction = "negative" result = ( Integration( coord_name, end_point=end_point, direction_of_integration=direction ).perform_integration( self.negative_upper_bounds_cube, self.negative_lower_bounds_cube, self.negative_integrated_cube)) self.assertArrayAlmostEqual( result.coord("height").points, np.array([10.])) self.assertArrayAlmostEqual(result.data, expected)
def test_raise_exception(self): """Test that an error is raised, if the direction_of_integration is not valid.""" coord_name = "height" direction = "sideways" msg = "The specified direction of integration" with self.assertRaisesRegexp(ValueError, msg): Integration(coord_name, direction_of_integration=direction)
def test_basic(self): """Test that the __repr__ returns the expected string.""" coord_name = "height" result = str(Integration(coord_name)) msg = ('<Integration: coord_name_to_integrate: height, ' 'start_point: None, end_point: None, ' 'positive_integration: False>') self.assertEqual(result, msg)
def test_basic(self): """Test that a cube with the points on the chosen coordinate are in the expected order.""" coord_name = "height" direction = "negative" result = (Integration( coord_name, direction_of_integration=direction).process(self.cube)) self.assertIsInstance(result, iris.cube.Cube) self.assertArrayAlmostEqual( result.coord("height").points, np.array([10., 5.]))
def setUp(self): """Set up the cube.""" cube = _set_up_height_cube(np.array([5.0, 10.0, 20.0])) self.coord_name = "height" data = np.zeros(cube.shape) data[0] = np.ones(cube[0].shape, dtype=np.int32) data[1] = np.full(cube[1].shape, 2, dtype=np.int32) data[2] = np.full(cube[2].shape, 3, dtype=np.int32) data[0, 0, 0] = 6 cube.data = data self.cube = cube self.plugin = Integration("height")
def test_descending_coordinate_negative(self): """Test that for a monotonically ascending coordinate, where the chosen direction is negative, the resulting coordinate still decreases monotonically in the positive direction.""" coord_name = "height" direction = "negative" cube = (Integration(coord_name, direction_of_integration=direction). ensure_monotonic_increase_in_chosen_direction( self.descending_cube)) self.assertIsInstance(cube, iris.cube.Cube) self.assertArrayAlmostEqual( cube.coord(coord_name).points, self.descending_height_points)
def setUp(self): """Set up the cubes. One set of cubes for integrating in the positive direction and another set of cubes for integrating in the negative direction.""" cube = _set_up_height_cube(np.array([5.0, 10.0, 20.0])) data = np.zeros(cube.shape) data[0] = np.ones(cube[0].shape, dtype=np.int32) data[1] = np.full(cube[1].shape, 2, dtype=np.int32) data[2] = np.full(cube[2].shape, 3, dtype=np.int32) data[0, 0, 0] = 6 cube.data = data # Cubes for integrating in the positive direction. self.positive_upper_bounds_cube = cube[1:, ...] self.positive_lower_bounds_cube = cube[:-1, ...] self.positive_integrated_cube = cube[1:, ...] self.positive_integrated_cube.data = np.zeros( self.positive_integrated_cube.shape ) # Cubes for integrating in the negative direction. new_cube = cube.copy() # Sort cube so that it is in the expected order. index = [[2, 1, 0], slice(None), slice(None), slice(None)] new_cube = new_cube[tuple(index)] self.negative_upper_bounds_cube = new_cube[:-1, ...] self.negative_lower_bounds_cube = new_cube[1:, ...] self.expected_data_zero_or_negative = np.array( [ [[10.00, 25.00, 25.00], [25.00, 25.00, 25.00], [25.00, 25.00, 25.00]], [[30.00, 32.50, 32.50], [32.50, 32.50, 32.50], [32.50, 32.50, 32.50]], ] ) self.plugin_positive = Integration("height", positive_integration=True) self.plugin_positive.input_cube = cube.copy() self.plugin_negative = Integration("height") self.plugin_negative.input_cube = cube.copy()
def test_data(self): """Test that the resulting cube contains the expected data following vertical integration.""" expected = np.array([[[[25.00, 25.00, 25.00], [25.00, 25.00, 25.00], [25.00, 25.00, 25.00]]], [[[45.00, 32.50, 32.50], [32.50, 32.50, 32.50], [32.50, 32.50, 32.50]]]]) coord_name = "height" direction = "negative" result = (Integration( coord_name, direction_of_integration=direction).process(self.cube)) self.assertArrayAlmostEqual( result.coord("height").points, np.array([10., 5.])) self.assertArrayAlmostEqual(result.data, expected)
def test_basic(self): """Test that the type of the returned value is as expected and the expected number of items are returned.""" coord_name = "height" direction = "negative" result = ( Integration( coord_name, direction_of_integration=direction ).prepare_for_integration(self.cube)) self.assertIsInstance(result, tuple) self.assertEqual(len(result), 3) self.assertIsInstance(result[0], iris.cube.Cube) self.assertIsInstance(result[1], iris.cube.Cube) self.assertIsInstance(result[2], iris.cube.Cube)
def test_basic(self): """Test that a cube is returned by the perform_integration method with the expected coordinate points.""" coord_name = "height" direction = "negative" result = (Integration( coord_name, direction_of_integration=direction).perform_integration( self.negative_upper_bounds_cube, self.negative_lower_bounds_cube, self.negative_integrated_cube)) self.assertIsInstance(result, iris.cube.Cube) self.assertArrayAlmostEqual( result.coord("height").points, np.array([5., 10.]))
def test_positive_points(self): """Test that the expected coordinate points are returned for each cube when the direction of integration is positive.""" coord_name = "height" direction = "positive" result = ( Integration( coord_name, direction_of_integration=direction ).prepare_for_integration(self.cube)) self.assertArrayAlmostEqual( result[0].coord("height").points, np.array([10., 20.])) self.assertArrayAlmostEqual( result[1].coord("height").points, np.array([5., 10.])) self.assertArrayAlmostEqual( result[2].coord("height").points, np.array([10., 20.]))
def test_integration_not_performed(self): """Test that the expected exception is raise if no integration can be performed, as a result of the options selected, for example, if the start_point is above the height of any of the levels within the cube.""" coord_name = "height" start_point = 25. direction = "positive" msg = "No integration could be performed for" with self.assertRaisesRegexp(ValueError, msg): Integration( coord_name, start_point=start_point, direction_of_integration=direction ).perform_integration( self.positive_upper_bounds_cube, self.positive_lower_bounds_cube, self.positive_integrated_cube)
def test_positive_values_in_data(self): """Test that the resulting cube contains the expected data following vertical integration.""" expected = np.array([[[[45.00, 32.50, 32.50], [32.50, 32.50, 32.50], [32.50, 32.50, 32.50]]], [[[25.00, 25.00, 25.00], [25.00, 25.00, 25.00], [25.00, 25.00, 25.00]]]]) coord_name = "height" direction = "negative" result = (Integration( coord_name, direction_of_integration=direction).perform_integration( self.negative_upper_bounds_cube, self.negative_lower_bounds_cube, self.negative_integrated_cube)) self.assertArrayAlmostEqual( result.coord("height").points, np.array([5., 10.])) self.assertArrayAlmostEqual(result.data, expected)
def test_zero_values_in_data(self): """Test that the resulting cube contains the expected data following vertical integration where some of the values in the data are equal to zero. This provides a baseline as the Integration plugin is currently restricted so that only positive values contribute towards the integral.""" self.negative_upper_bounds_cube.data[0, :, 0, 0] = 0 coord_name = "height" direction = "negative" result = (Integration( coord_name, direction_of_integration=direction).perform_integration( self.negative_upper_bounds_cube, self.negative_lower_bounds_cube, self.negative_integrated_cube)) self.assertArrayAlmostEqual( result.coord("height").points, np.array([5., 10.])) self.assertArrayAlmostEqual(result.data, self.expected_data_zero_or_negative)
def test_start_point_negative_direction(self): """Test that the resulting cube contains the expected data when a start_point is specified, so that only part of the column is integrated. For integration in the negative direction (equivalent to integrating downwards for the height coordinate in the input cube), the presence of a start_point indicates that the integration may start below the highest height within the column to be integrated.""" expected = np.array([[[20.00, 7.50, 7.50], [7.50, 7.50, 7.50], [7.50, 7.50, 7.50]]]) coord_name = "height" start_point = 18. direction = "negative" result = (Integration( coord_name, start_point=start_point, direction_of_integration=direction).perform_integration( self.negative_upper_bounds_cube, self.negative_lower_bounds_cube, self.negative_integrated_cube)) self.assertArrayAlmostEqual( result.coord("height").points, np.array([5.])) self.assertArrayAlmostEqual(result.data, expected)
def __init__(self): """Initialise class.""" self.integration_plugin = Integration("height")