class Test__slice_input_cubes(IrisTest): """Test the _slice_input_cubes method""" def setUp(self): """Set up plugin with suitable parameters (used for dict only)""" self.plugin = ChooseWeightsLinear("forecast_period", CONFIG_DICT_UKV) # create a cube with irrelevant threshold coordinate (dimensions: # model_id: 2; threshold: 2; latitude: 2; longitude: 2) cube = set_up_probability_cube( np.ones((2, 2, 2), dtype=np.float32), thresholds=np.array([278.0, 279.0], dtype=np.float32), ) self.cube = add_coordinate(cube, [1000, 2000], "model_id", dtype=np.int32) self.cube.add_aux_coord(AuxCoord(["uk_det", "uk_ens"], long_name="model_configuration"), data_dims=0) # create a reference cube as above WITHOUT threshold self.reference_cube = iris.util.squeeze(self.cube[:, 0, :, :].copy()) # split into a cubelist by model self.reference_cubelist = iris.cube.CubeList( [self.reference_cube[0], self.reference_cube[1]]) def test_slices(self): """Test function slices out extra dimensions""" result = self.plugin._slice_input_cubes(self.cube) self.assertIsInstance(result, iris.cube.CubeList) for cube, refcube in zip(result, self.reference_cubelist): self.assertArrayAlmostEqual(cube.data, refcube.data) self.assertEqual(cube.metadata, refcube.metadata) def test_cubelist(self): """Test function creates cubelist with same dimensions where needed""" result = self.plugin._slice_input_cubes(self.reference_cube) self.assertIsInstance(result, iris.cube.CubeList) for cube, refcube in zip(result, self.reference_cubelist): self.assertArrayAlmostEqual(cube.data, refcube.data) self.assertEqual(cube.metadata, refcube.metadata) def test_single_cube(self): """Test function populates a cubelist if given a cube with a scalar blending coordinate""" single_cube = self.reference_cube[0] result = self.plugin._slice_input_cubes(single_cube) self.assertIsInstance(result, iris.cube.CubeList) self.assertEqual(len(result), 1) self.assertArrayAlmostEqual(result[0].data, single_cube.data) self.assertEqual(result[0].metadata, single_cube.metadata)
class Test__create_new_weights_cube(IrisTest): """Test the _create_new_weights_cube function. """ def setUp(self): """Set up some plugin inputs""" self.plugin = ChooseWeightsLinear( "forecast_period", config_dict=CONFIG_DICT_UKV) self.cube, = self.plugin._slice_input_cubes( set_up_basic_model_config_cube()) self.weights = np.array([0., 0., 0.2]) def test_with_dict(self): """Test a new weights cube is created as intended, with the desired cube name.""" new_weights_cube = self.plugin._create_new_weights_cube( self.cube, self.weights) self.assertArrayAlmostEqual(new_weights_cube.data, self.weights) self.assertEqual(new_weights_cube.name(), "weights") # test only relevant coordinates have been retained on the weights cube expected_coords = { 'time', 'forecast_reference_time', 'forecast_period', 'model_id', 'model_configuration'} result_coords = {coord.name() for coord in new_weights_cube.coords()} self.assertSetEqual(result_coords, expected_coords) def test_with_dict_masked_input_cube(self): """Test a new weights cube is created as intended when we have a masked input cube.""" self.cube.data = np.ma.masked_array( self.cube.data, np.ones(self.cube.data.shape)*True) new_weights_cube = self.plugin._create_new_weights_cube( self.cube, self.weights) self.assertEqual(np.ma.is_masked(new_weights_cube.data), False) self.assertArrayAlmostEqual(new_weights_cube.data, self.weights)
class Test__calculate_weights(IrisTest): """Test the _calculate_weights method""" def setUp(self): """Set up some cubes and plugins to work with""" config_dict = CONFIG_DICT_UKV weighting_coord_name = "forecast_period" self.plugin_dict = ChooseWeightsLinear(weighting_coord_name, config_dict) (self.temp_cube,) = self.plugin_dict._slice_input_cubes( set_up_basic_model_config_cube() ) self.expected_weights_below_range = np.array([0.0, 0.0, 0.2]) self.expected_weights_within_range = np.array([0.8, 1.0, 1.0]) self.expected_weights_above_range = np.array([0.166667, 0.0, 0.0]) def test_below_range_dict(self): """Test that interpolation works as intended when the forecast period required for the interpolation output is below the range specified within the inputs.""" new_weights_cube = self.plugin_dict._calculate_weights(self.temp_cube) self.assertIsInstance(new_weights_cube, iris.cube.Cube) self.assertArrayAlmostEqual( new_weights_cube.data, self.expected_weights_below_range ) self.assertEqual(new_weights_cube.name(), "weights") def test_within_range_dict(self): """Test that interpolation works as intended when the forecast period required for the interpolation output is within the range specified within the inputs.""" cube = update_time_and_forecast_period(self.temp_cube, 3600 * 5) new_weights_cube = self.plugin_dict._calculate_weights(cube) self.assertIsInstance(new_weights_cube, iris.cube.Cube) self.assertArrayAlmostEqual( new_weights_cube.data, self.expected_weights_within_range ) self.assertEqual(new_weights_cube.name(), "weights") def test_above_range_dict(self): """Test that interpolation works as intended when the forecast period required for the interpolation output is above the range specified within the inputs.""" cube = update_time_and_forecast_period(self.temp_cube, 3600 * 47) new_weights_cube = self.plugin_dict._calculate_weights(cube) self.assertIsInstance(new_weights_cube, iris.cube.Cube) self.assertArrayAlmostEqual( new_weights_cube.data, self.expected_weights_above_range ) self.assertEqual(new_weights_cube.name(), "weights")
class Test__slice_input_cubes(IrisTest): """Test the _slice_input_cubes method""" def setUp(self): """Set up plugin with suitable parameters (used for dict only)""" self.plugin = ChooseWeightsLinear( "forecast_period", CONFIG_DICT_UKV) # create a cube with unnecessary realization coordinate (dimensions: # model_id: 2; realization: 1; latitude: 2; longitude: 2) cube = set_up_variable_cube(278.*np.ones((1, 2, 2), dtype=np.float32)) self.cube = add_coordinate( cube, [1000, 2000], "model_id", dtype=np.int32) self.cube.add_aux_coord( AuxCoord(["uk_det", "uk_ens"], long_name="model_configuration"), data_dims=0) # create a reference cube as above WITHOUT realization new_data = self.cube.data[:, 0, :, :] dim_coords = [(self.cube.coord("model_id"), 0), (self.cube.coord("latitude"), 1), (self.cube.coord("longitude"), 2)] aux_coords = [(self.cube.coord("model_configuration"), 0), (self.cube.coord("time"), None), (self.cube.coord("forecast_period"), None), (self.cube.coord("forecast_reference_time"), None)] self.reference_cube = iris.cube.Cube( new_data, "air_temperature", units="K", dim_coords_and_dims=dim_coords, aux_coords_and_dims=aux_coords) self.reference_cube.add_aux_coord(AuxCoord(0, "realization")) # split into a cubelist for each model self.reference_cubelist = iris.cube.CubeList([self.reference_cube[0], self.reference_cube[1]]) def test_slices(self): """Test function slices out extra dimensions""" result = self.plugin._slice_input_cubes(self.cube) self.assertIsInstance(result, iris.cube.CubeList) for cube, refcube in zip(result, self.reference_cubelist): self.assertArrayAlmostEqual(cube.data, refcube.data) self.assertEqual(cube.metadata, refcube.metadata) def test_cubelist(self): """Test function creates cubelist with same dimensions where needed""" result = self.plugin._slice_input_cubes(self.reference_cube) self.assertIsInstance(result, iris.cube.CubeList) for cube, refcube in zip(result, self.reference_cubelist): self.assertArrayAlmostEqual(cube.data, refcube.data) self.assertEqual(cube.metadata, refcube.metadata) def test_single_cube(self): """Test function populates a cubelist if given a cube with a scalar blending coordinate""" single_cube = self.reference_cube[0] result = self.plugin._slice_input_cubes(single_cube) self.assertIsInstance(result, iris.cube.CubeList) self.assertEqual(len(result), 1) self.assertArrayAlmostEqual(result[0].data, single_cube.data) self.assertEqual(result[0].metadata, single_cube.metadata)