def test_basic(self): """Test that the plugin returns expected data type. """ result = LapseRate(nbhood_radius=1).process(self.temperature, self.orography, self.land_sea_mask) self.assertIsInstance(result, Cube) self.assertEqual(result.name(), "air_temperature_lapse_rate") self.assertEqual(result.units, "K m-1")
def test_dimension_order(self): """Test dimension order is preserved if realization is not the leading dimension""" enforce_coordinate_ordering(self.temperature, "realization", anchor_start=False) result = LapseRate(nbhood_radius=1).process( self.temperature, self.orography, self.land_sea_mask ) self.assertEqual(result.coord_dims("realization")[0], 2)
def test_dimensions(self): """Test that the output cube has the same shape and dimensions as the input temperature cube""" result = LapseRate(nbhood_radius=1).process(self.temperature, self.orography, self.land_sea_mask) self.assertSequenceEqual(result.shape, self.temperature.shape) self.assertSequenceEqual(result.coords(dim_coords=True), self.temperature.coords(dim_coords=True))
def test_scalar_realization(self): """Test dimensions are treated correctly if the realization coordinate is scalar""" temperature = next(self.temperature.slices_over('realization')) result = LapseRate(nbhood_radius=1).process(temperature, self.orography, self.land_sea_mask) self.assertSequenceEqual(result.shape, temperature.shape) self.assertSequenceEqual(result.coords(dim_coords=True), temperature.coords(dim_coords=True))
def test_lapse_rate_limits(self): """Test that the function limits the lapse rate to +DALR and -3*DALR. Where DALR = Dry Adiabatic Lapse Rate. """ expected_out = np.array( [ [ [0.0294, 0.0294, 0.0294, 0.0, DALR], [0.0294, 0.0294, 0.0294, 0.0, DALR], [0.0294, 0.0294, 0.0294, 0.0, DALR], [0.0294, 0.0294, 0.0294, 0.0, DALR], [0.0294, 0.0294, 0.0294, 0.0, DALR], ] ] ) # West data points should be -3*DALR and East should be DALR. self.temperature.data[:, :, 0] = 2 self.temperature.data[:, :, 1] = 1 self.temperature.data[:, :, 3] = -1 self.temperature.data[:, :, 4] = -2 self.orography.data[:, :] = 10 self.orography.data[:, 0] = 15 self.orography.data[:, 3] = 0 result = LapseRate(nbhood_radius=1).process( self.temperature, self.orography, self.land_sea_mask ) self.assertArrayAlmostEqual(result.data, expected_out)
def test_handles_nan_value(self): """Test that the function handles a NaN temperature value by replacing it with DALR. """ expected_out = np.array( [ [ [DALR, 0.015, 0.01, 0.006428571, 0.005], [DALR, 0.015, 0.01, 0.00625, 0.005], [DALR, 0.015, DALR, 0.00625, 0.005], [DALR, 0.015, 0.01, 0.00625, 0.005], [DALR, 0.015, 0.01, 0.006428571, 0.005], ] ] ) # West data points should be -3*DALR and East should be DALR. self.temperature.data[:, :, 0] = -0.2 self.temperature.data[:, :, 1] = -0.1 self.temperature.data[:, :, 2] = 0.0 self.temperature.data[:, :, 3] = 0.1 self.temperature.data[:, :, 4] = 0.2 self.temperature.data[:, 2, 2] = np.nan self.orography.data[:, 0:2] = 0 self.orography.data[:, 2] = 10 self.orography.data[:, 3] = 20 self.orography.data[:, 4] = 40 result = LapseRate(nbhood_radius=1).process( self.temperature, self.orography, self.land_sea_mask ) self.assertArrayAlmostEqual(result.data, expected_out)
def test_model_id_attr(self): """Test model ID attribute can be inherited""" result = LapseRate(nbhood_radius=1).process( self.temperature, self.orography, self.land_sea_mask, model_id_attr="mosg__model_configuration") self.assertEqual( result.attributes["mosg__model_configuration"], "uk_det")
def test_returns_expected_values(self): """Test that the function returns expected lapse rate. """ expected_out = -0.00765005774676 result = LapseRate(nbhood_radius=1)._generate_lapse_rate_array( self.temperature, self.orography, self.land_sea_mask)[1, 1] self.assertArrayAlmostEqual(result, expected_out)
def test_landsea_mask(self): """Test that the function returns DALR values wherever a land/sea mask is true. Mask is True for land-points and False for Sea. """ reset_cube_data(self.temperature, self.orography, self.land_sea_mask) expected_out = np.array([[0.0294, 0.0294, 0.0, DALR, DALR], [0.0294, 0.0294, 0.0, DALR, DALR], [0.0294, 0.0294, 0.0, DALR, DALR], [DALR, DALR, DALR, DALR, DALR], [DALR, DALR, DALR, DALR, DALR]]) # West data points should be -3*DALR and East should be DALR, South # should be zero. self.temperature.data[:, :, 0] = 2 self.temperature.data[:, :, 1] = 1 self.temperature.data[:, :, 3] = -1 self.temperature.data[:, :, 4] = -2 self.orography.data[:, :] = 10 self.land_sea_mask.data[3:5, :] = 0 result = LapseRate(nbhood_radius=1).process(self.temperature, self.orography, self.land_sea_mask) self.assertArrayAlmostEqual(result.data, expected_out)
def test_mask_max_height_diff_arg(self): """ Test that the function removes or leaves neighbours where their height difference from the centre point is greater than a specified, non-default max_height_diff.""" expected_out = np.array([[[DALR, DALR, DALR, -0.00642857, -0.005], [DALR, DALR, DALR, -0.00454128, -0.003], [DALR, DALR, DALR, -0.00454128, -0.003], [DALR, DALR, DALR, -0.00454128, -0.003], [DALR, DALR, DALR, -0.00642857, -0.005]]]) self.temperature.data[:, :, 0:2] = 0.4 self.temperature.data[:, :, 2] = 0.3 self.temperature.data[:, :, 3] = 0.2 self.temperature.data[:, :, 4] = 0.1 self.orography.data[:, 2] = 10 self.orography.data[:, 3] = 20 self.orography.data[:, 4] = 40 self.orography.data[2, 4] = 60 result = LapseRate(max_height_diff=50, nbhood_radius=1).process(self.temperature, self.orography, self.land_sea_mask) self.assertArrayAlmostEqual(result.data, expected_out)
def test_mask_max_height_diff(self): """Test that the function removes neighbours where their height difference from the centre point is greater than the default max_height_diff = 35metres. """ reset_cube_data(self.temperature, self.orography, self.land_sea_mask) expected_out = np.array([[DALR, DALR, DALR, -0.00642857, -0.005], [DALR, DALR, DALR, -0.0065517, -0.003], [DALR, DALR, DALR, -0.0065517, 0.0], [DALR, DALR, DALR, -0.0065517, -0.003], [DALR, DALR, DALR, -0.00642857, -0.005]]) self.temperature.data[:, :, 0:2] = 0.4 self.temperature.data[:, :, 2] = 0.3 self.temperature.data[:, :, 3] = 0.2 self.temperature.data[:, :, 4] = 0.1 self.orography.data[:, 2] = 10 self.orography.data[:, 3] = 20 self.orography.data[:, 4] = 40 self.orography.data[2, 4] = 60 result = LapseRate(nbhood_radius=1).process(self.temperature, self.orography, self.land_sea_mask) self.assertArrayAlmostEqual(result.data, expected_out)
def test_decr_temp_decr_orog(self): """ Test code where the temperature increases with height.""" expected_out = np.array( [ [ [DALR, 0.01, 0.01, 0.00642857, 0.005], [DALR, 0.01, 0.01, 0.00642857, 0.005], [DALR, 0.01, 0.01, 0.00642857, 0.005], [DALR, 0.01, 0.01, 0.00642857, 0.005], [DALR, 0.01, 0.01, 0.00642857, 0.005], ] ] ) self.temperature.data[:, :, 0:2] = 0.1 self.temperature.data[:, :, 2] = 0.2 self.temperature.data[:, :, 3] = 0.3 self.temperature.data[:, :, 4] = 0.4 self.orography.data[:, 2] = 10 self.orography.data[:, 3] = 20 self.orography.data[:, 4] = 40 result = LapseRate(nbhood_radius=1).process( self.temperature, self.orography, self.land_sea_mask ) self.assertArrayAlmostEqual(result.data, expected_out)
def test_returns_expected_values(self): """Test that the function returns expected lapse rate. """ expected_out = -0.00765005774676 result = LapseRate(nbhood_radius=1)._calc_lapse_rate( self.temperature, self.orography) self.assertArrayAlmostEqual(result, expected_out)
def test_decr_temp_incr_orog(self): """ Test code where temperature is decreasing with height. This is the expected scenario for lapse rate. """ reset_cube_data(self.temperature, self.orography, self.land_sea_mask) expected_out = np.array([[DALR, DALR, DALR, -0.00642857, -0.005], [DALR, DALR, DALR, -0.00642857, -0.005], [DALR, DALR, DALR, -0.00642857, -0.005], [DALR, DALR, DALR, -0.00642857, -0.005], [DALR, DALR, DALR, -0.00642857, -0.005]]) self.temperature.data[:, :, 0:2] = 0.4 self.temperature.data[:, :, 2] = 0.3 self.temperature.data[:, :, 3] = 0.2 self.temperature.data[:, :, 4] = 0.1 self.orography.data[:, 2] = 10 self.orography.data[:, 3] = 20 self.orography.data[:, 4] = 40 result = LapseRate(nbhood_radius=1).process(self.temperature, self.orography, self.land_sea_mask) self.assertArrayAlmostEqual(result.data, expected_out)
def test_specified_max_and_min_lapse_rate(self): """Test that the function correctly applies a specified, non default maximum and minimum lapse rate.""" reset_cube_data(self.temperature, self.orography, self.land_sea_mask) expected_out = np.array([[0.0392, 0.0392, 0.0, -0.0196, -0.0196], [0.0392, 0.0392, 0.0, -0.0196, -0.0196], [0.0392, 0.0392, 0.0, -0.0196, -0.0196], [0.0392, 0.0392, 0.0, -0.0196, -0.0196], [0.0392, 0.0392, 0.0, -0.0196, -0.0196]]) # West data points should be -4*DALR and East should be 2*DALR. self.temperature.data[:, :, 0] = 2 self.temperature.data[:, :, 1] = 1 self.temperature.data[:, :, 3] = -1 self.temperature.data[:, :, 4] = -2 self.orography.data[:, :] = 10 result = LapseRate(nbhood_radius=1, max_lapse_rate=-4 * DALR, min_lapse_rate=2 * DALR).process( self.temperature, self.orography, self.land_sea_mask) self.assertArrayAlmostEqual(result.data, expected_out)
def test_basic(self): """Test that the plugin returns expected data type. """ result = LapseRate(nbhood_radius=1).process(self.temperature, self.orography, self.land_sea_mask) self.assertIsInstance(result, Cube)
def test_fails_if_orography_wrong_units(self): """Test code raises a Value Error if the orography cube is the wrong unit.""" msg = r"Unable to convert from 'Unit\('K'\)' to 'Unit\('metres'\)'." with self.assertRaisesRegexp(ValueError, msg): LapseRate(nbhood_radius=1).process(self.temperature, self.temperature, self.land_sea_mask)
def test_fails_if_temperature_wrong_units(self): """Test code raises a Value Error if the temperature cube is the wrong unit.""" # Swap cubes around so have wrong units. msg = r"Unable to convert from 'Unit\('m'\)' to 'Unit\('K'\)'." with self.assertRaisesRegexp(ValueError, msg): LapseRate(nbhood_radius=1).process(self.orography, self.orography, self.land_sea_mask)
def test_basic(self): """Test that the __repr__ returns the expected string.""" result = str(LapseRate()) msg = ( "<LapseRate: max_height_diff: 35, nbhood_radius: 7," "max_lapse_rate: 0.0294, min_lapse_rate: -0.0098>" ) self.assertEqual(result, msg)
def test_fails_if_max_height_diff_less_than_zero(self): """Test code raises a Value Error if the maximum height difference is less than zero""" msg = "Maximum height difference is less than zero" with self.assertRaisesRegexp(ValueError, msg): LapseRate(max_height_diff=-1).process(self.temperature, self.orography, self.land_sea_mask)
def test_handles_nan(self): """Test that the function returns DALR value when central point is NaN.""" self.temperature[..., 1, 1] = np.nan expected_out = DALR result = LapseRate(nbhood_radius=1)._generate_lapse_rate_array( self.temperature, self.orography, self.land_sea_mask)[1, 1] self.assertArrayAlmostEqual(result, expected_out)
def test_fails_if_temperature_is_not_cube(self): """Test code raises a Type Error if input temperature cube is not a cube.""" incorrect_input = 50.0 msg = "Temperature input is not a cube, but {0}".format(type(incorrect_input)) with self.assertRaisesRegexp(TypeError, msg): LapseRate(nbhood_radius=1).process( incorrect_input, self.orography, self.land_sea_mask )
def test_fails_if_max_less_min_lapse_rate(self): """Test code raises a Value Error if input maximum lapse rate is less than input minimum lapse rate""" msg = "Maximum lapse rate is less than minimum lapse rate" with self.assertRaisesRegexp(ValueError, msg): LapseRate(max_lapse_rate=-1, min_lapse_rate=1).process( self.temperature, self.orography, self.land_sea_mask )
def test_fails_if_land_sea_mask_is_not_cube(self): """Test code raises a Type Error if input land/sea mask cube is not a cube.""" incorrect_input = 50.0 msg = 'Land/Sea mask input is not a cube, but {0}'.format( type(incorrect_input)) with self.assertRaisesRegexp(TypeError, msg): LapseRate(nbhood_radius=1).process(self.temperature, self.orography, incorrect_input)
def test_handles_nan(self): """Test that the function returns DALR value when central point is NaN.""" self.temperature[4] = np.nan expected_out = DALR result = LapseRate(nbhood_radius=1)._calc_lapse_rate( self.temperature, self.orography) self.assertArrayAlmostEqual(result, expected_out)
def test_fails_if_nbhood_radius_less_than_zero(self): """Test code raises a Value Error if input neighbourhood radius is less than zero""" msg = "Neighbourhood radius is less than zero" with self.assertRaisesRegexp(ValueError, msg): LapseRate(nbhood_radius=-1).process(self.temperature, self.orography, self.land_sea_mask)
def test_correct_lapse_rate_units_with_arguments(self): """Test that the plugin returns the correct unit type when non-default arguments specified""" result = LapseRate(max_height_diff=15, nbhood_radius=3, max_lapse_rate=0.06, min_lapse_rate=-0.01).process(self.temperature, self.orography, self.land_sea_mask) self.assertEqual(result.units, 'K m-1')
def test_returns_expected_values(self): """Test that the function returns True at points where the height difference to the central pixel is greater than 35m.""" expected_out = np.array( [[True, True, False, False, False, False, False, False, True], [True, True, False, False, False, False, False, False, True]]) result = LapseRate(nbhood_radius=1)._create_heightdiff_mask( self.orography) self.assertArrayAlmostEqual(result, expected_out)
def test_change_height_thresh(self): """Test that the function performs as expected when the height difference threshold has been changed.""" expected_out = np.array( [[False, True, False, False, False, False, False, False, True], [False, True, False, False, False, False, False, False, True]]) result = LapseRate(max_height_diff=40, nbhood_radius=1)._create_heightdiff_mask( self.orography) self.assertArrayAlmostEqual(result, expected_out)
def test_constant_orog(self): """Test that the function returns expected DALR values where the orography fields are constant values. """ expected_out = np.full((1, 5, 5), DALR) self.temperature.data[:, :, :] = 0.08 self.temperature.data[:, 1, 1] = 0.09 self.orography.data[:, :] = 10 result = LapseRate(nbhood_radius=1).process( self.temperature, self.orography, self.land_sea_mask ) self.assertArrayAlmostEqual(result.data, expected_out, decimal=4)