def setUp(self): """ Set up cubes for testing. """ data = np.full((1, 2, 2), 0.5, dtype=np.float32) self.cube1 = set_up_probability_cube( data, np.array([0.001], dtype=np.float32), variable_name="lwe_thickness_of_precipitation_amount", time=datetime(2015, 11, 19, 0), time_bounds=(datetime(2015, 11, 18, 23), datetime(2015, 11, 19, 0)), frt=datetime(2015, 11, 18, 22), attributes={'attribute_to_update': 'first_value'}) data = np.full((1, 2, 2), 0.6, dtype=np.float32) self.cube2 = set_up_probability_cube( data, np.array([0.001], dtype=np.float32), variable_name="lwe_thickness_of_precipitation_amount", time=datetime(2015, 11, 19, 1), time_bounds=(datetime(2015, 11, 19, 0), datetime(2015, 11, 19, 1)), frt=datetime(2015, 11, 18, 22), attributes={'attribute_to_update': 'first_value'}) data = np.full((1, 2, 2), 0.1, dtype=np.float32) self.cube3 = set_up_probability_cube( data, np.array([0.001], dtype=np.float32), variable_name="lwe_thickness_of_precipitation_amount", time=datetime(2015, 11, 19, 1), time_bounds=(datetime(2015, 11, 19, 0), datetime(2015, 11, 19, 1)), frt=datetime(2015, 11, 18, 22), attributes={'attribute_to_update': 'first_value'})
def setUp(self): """Set up some probability cubes from different models""" data = np.array([ 0.9 * np.ones((3, 3)), 0.5 * np.ones((3, 3)), 0.1 * np.ones((3, 3)) ], dtype=np.float32) thresholds = np.array([273., 275., 277.], dtype=np.float32) time_point = dt(2015, 11, 23, 7) # set up a MOGREPS-UK cube with 7 hour forecast period self.cube_enuk = set_up_probability_cube( data.copy(), thresholds, standard_grid_metadata='uk_ens', time=time_point, frt=dt(2015, 11, 23, 0)) # set up a UKV cube with 4 hour forecast period self.cube_ukv = set_up_probability_cube( data.copy(), thresholds, standard_grid_metadata='uk_det', time=time_point, frt=dt(2015, 11, 23, 3)) self.cubelist = iris.cube.CubeList([self.cube_enuk, self.cube_ukv]) self.plugin = MergeCubesForWeightedBlending( "model", weighting_coord="forecast_period", model_id_attr="mosg__model_configuration")
def setUp(self): """Use temperature exceedance probability cubes to test with.""" data = np.ones((2, 3, 3), dtype=np.float32) thresholds = np.array([274, 275], dtype=np.float32) time_point = dt(2015, 11, 23, 7) # set up some UKV cubes with 4, 5 and 6 hour forecast periods and # different histories self.cube_ukv = set_up_probability_cube( data.copy(), thresholds.copy(), standard_grid_metadata='uk_det', time=time_point, frt=dt(2015, 11, 23, 3), attributes={'history': 'something'}) self.cube_ukv_t1 = set_up_probability_cube( data.copy(), thresholds.copy(), standard_grid_metadata='uk_det', time=time_point, frt=dt(2015, 11, 23, 2), attributes={'history': 'different'}) self.cube_ukv_t2 = set_up_probability_cube( data.copy(), thresholds.copy(), standard_grid_metadata='uk_det', time=time_point, frt=dt(2015, 11, 23, 1), attributes={'history': 'entirely'}) self.plugin = MergeCubes()
def test_dict(self): """Test dictionary option for model blending with non-equal weights""" data = np.ones((3, 3, 3), dtype=np.float32) thresholds = np.array([276, 277, 278], dtype=np.float32) ukv_cube = set_up_probability_cube(data, thresholds, time=dt(2018, 9, 10, 7), frt=dt(2018, 9, 10, 1), standard_grid_metadata="uk_det") enukx_cube = set_up_probability_cube(data, thresholds, time=dt(2018, 9, 10, 7), frt=dt(2018, 9, 10, 1), standard_grid_metadata="uk_ens") merger = MergeCubesForWeightedBlending( "model_id", weighting_coord="forecast_period", model_id_attr="mosg__model_configuration") cube = merger.process([ukv_cube, enukx_cube]) plugin = WeightAndBlend("model_id", "dict", weighting_coord="forecast_period", wts_dict=MODEL_WEIGHTS) # at 6 hours lead time we should have 1/3 UKV and 2/3 MOGREPS-UK, # according to the dictionary weights specified above weights = plugin._calculate_blending_weights(cube) self.assertArrayEqual( weights.coord("model_configuration").points, ["uk_det", "uk_ens"]) self.assertArrayAlmostEqual(weights.data, np.array([0.3333333, 0.6666667]))
def setUp(self): """Set up test cubes (each with a single point and 3 thresholds)""" thresholds = np.array([0.5, 1, 2], dtype=np.float32) units = "mm h-1" name = "lwe_precipitation_rate" datatime = dt(2018, 9, 10, 7) cycletime = dt(2018, 9, 10, 3) # a UKV cube with some rain and a 4 hr forecast period rain_data = np.array([[[0.9]], [[0.5]], [[0]]], dtype=np.float32) self.ukv_cube = set_up_probability_cube( rain_data, thresholds, variable_name=name, threshold_units=units, time=datatime, frt=cycletime, standard_grid_metadata="uk_det") # a UKV cube from a more recent cycle with more rain more_rain_data = np.array([[[1]], [[0.6]], [[0.2]]], dtype=np.float32) self.ukv_cube_latest = set_up_probability_cube( more_rain_data, thresholds, variable_name=name, threshold_units=units, time=datatime, frt=dt(2018, 9, 10, 4), standard_grid_metadata="uk_det") # a nowcast cube with more rain and a 2 hr forecast period self.nowcast_cube = set_up_probability_cube( more_rain_data, thresholds, variable_name=name, threshold_units=units, time=datatime, frt=dt(2018, 9, 10, 5), attributes={"mosg__model_configuration": "nc_det"}) # a MOGREPS-UK cube with less rain and a 4 hr forecast period less_rain_data = np.array([[[0.7]], [[0.3]], [[0]]], dtype=np.float32) self.enukx_cube = set_up_probability_cube( less_rain_data, thresholds, variable_name=name, threshold_units=units, time=datatime, frt=cycletime, standard_grid_metadata="uk_ens") self.plugin_cycle = WeightAndBlend("forecast_reference_time", "linear", y0val=1, ynval=1) self.plugin_model = WeightAndBlend("model_id", "dict", weighting_coord="forecast_period", wts_dict=MODEL_WEIGHTS)
def test_relative_to_threshold_set(self): """Test that an error is raised if the "relative_to_threshold" attribute has not been set when setting up a probability cube""" msg = 'The relative_to_threshold attribute MUST be set' with self.assertRaisesRegex(ValueError, msg): set_up_probability_cube(self.data, self.thresholds, relative_to_threshold=None)
def setUp(self): """ Set up a basic cube and linear weights cube for the process method. Input cube has 2 thresholds on and 3 forecast_reference_times """ thresholds = [10, 20] data = np.ones((2, 2, 3), dtype=np.float32) cycle1 = set_up_probability_cube( data, thresholds, spatial_grid="equalarea", time=datetime(2017, 11, 10, 4, 0), frt=datetime(2017, 11, 10, 0, 0), ) cycle2 = set_up_probability_cube( data, thresholds, spatial_grid="equalarea", time=datetime(2017, 11, 10, 4, 0), frt=datetime(2017, 11, 10, 1, 0), ) cycle3 = set_up_probability_cube( data, thresholds, spatial_grid="equalarea", time=datetime(2017, 11, 10, 4, 0), frt=datetime(2017, 11, 10, 2, 0), ) self.cube_to_collapse = CubeList([cycle1, cycle2, cycle3]).merge_cube() self.cube_to_collapse = squeeze(self.cube_to_collapse) self.cube_to_collapse.rename("weights") # This input array has 3 forecast reference times and 2 thresholds. # The two thresholds have the same weights. self.cube_to_collapse.data = np.array( [[[[1, 0, 1], [1, 1, 1]], [[1, 0, 1], [1, 1, 1]]], [[[0, 0, 1], [0, 1, 1]], [[0, 0, 1], [0, 1, 1]]], [[[1, 1, 1], [1, 1, 1]], [[1, 1, 1], [1, 1, 1]]]], dtype=np.float32) self.cube_to_collapse.data = np.ma.masked_equal( self.cube_to_collapse.data, 0) # Create a one_dimensional weights cube by slicing the larger # weights cube. # The resulting cube only has a forecast_reference_time coordinate. self.one_dimensional_weights_cube = self.cube_to_collapse[:, 0, 0, 0] self.one_dimensional_weights_cube.remove_coord( "projection_x_coordinate") self.one_dimensional_weights_cube.remove_coord( "projection_y_coordinate") self.one_dimensional_weights_cube.remove_coord( find_threshold_coordinate(self.one_dimensional_weights_cube)) self.one_dimensional_weights_cube.data = np.array([0.2, 0.5, 0.3], dtype=np.float32) self.plugin = SpatiallyVaryingWeightsFromMask(fuzzy_length=4)
def setUp(self): """ Set up a basic weights cube with 2 thresholds to multiple with a cube with one_dimensional weights. """ thresholds = [10, 20] data = np.ones((2, 2, 3), dtype=np.float32) cycle1 = set_up_probability_cube( data, thresholds, spatial_grid="equalarea", time=datetime(2017, 11, 10, 4, 0), frt=datetime(2017, 11, 10, 0, 0), ) cycle2 = set_up_probability_cube( data, thresholds, spatial_grid="equalarea", time=datetime(2017, 11, 10, 4, 0), frt=datetime(2017, 11, 10, 1, 0), ) cycle3 = set_up_probability_cube( data, thresholds, spatial_grid="equalarea", time=datetime(2017, 11, 10, 4, 0), frt=datetime(2017, 11, 10, 2, 0), ) self.spatial_weights_cube = CubeList([cycle1, cycle2, cycle3]).merge_cube() self.spatial_weights_cube = squeeze(self.spatial_weights_cube) self.spatial_weights_cube.rename("weights") # This input array has 3 forecast reference times and 2 thresholds. # The two thresholds have the same weights. self.spatial_weights_cube.data = np.array( [[[[1, 0, 1], [1, 0, 1]], [[1, 0, 1], [1, 0, 1]]], [[[0, 0, 1], [0, 0, 1]], [[0, 0, 1], [0, 0, 1]]], [[[1, 1, 1], [1, 1, 1]], [[1, 1, 1], [1, 1, 1]]]], dtype=np.float32) # Create a one_dimensional weights cube by slicing the # larger weights cube. # The resulting cube only has a forecast_reference_time coordinate. self.one_dimensional_weights_cube = (self.spatial_weights_cube[:, 0, 0, 0]) self.one_dimensional_weights_cube.remove_coord( "projection_x_coordinate") self.one_dimensional_weights_cube.remove_coord( "projection_y_coordinate") self.one_dimensional_weights_cube.remove_coord( find_threshold_coordinate(self.one_dimensional_weights_cube)) self.one_dimensional_weights_cube.data = np.array([0.2, 0.5, 0.3], dtype=np.float32) self.plugin = SpatiallyVaryingWeightsFromMask()
def set_up_basic_model_config_cube(frt=None, time_points=None): """Set up cube with dimensions of time x air_temperature x lat x lon, plus model id and configuration scalar coordinates Args: frt (datetime.datetime): Forecast reference time point time_points (list): List of times as datetime instances to create a dim coord """ if frt is None: frt = dt(2017, 1, 10, 3, 0) if time_points is None: time_points = [dt(2017, 1, 10, 9, 0), dt(2017, 1, 10, 10, 0), dt(2017, 1, 10, 11, 0)] model_id_coord = AuxCoord([1000], long_name="model_id") model_config_coord = AuxCoord(["uk_det"], long_name="model_configuration") data = np.ones((2, 2, 2), dtype=np.float32) thresholds = np.array([275., 276.], dtype=np.float32) cube = set_up_probability_cube( data, thresholds, time=frt, frt=frt, include_scalar_coords=[model_id_coord, model_config_coord]) cube = add_coordinate( cube, time_points, "time", is_datetime=True) return cube
def create_cube_with_threshold(data=None, threshold_values=None): """ Create a cube with threshold coord. Data and threshold values MUST be provided as float32 (not float64), or cube setup will fail. """ if threshold_values is None: threshold_values = np.array([1.0], dtype=np.float32) if data is None: data = np.zeros((len(threshold_values), 2, 2, 2), dtype=np.float32) data[:, 0, :, :] = 0.5 data[:, 1, :, :] = 0.6 cube = set_up_probability_cube( data[:, 0, :, :], threshold_values, variable_name="rainfall_rate", threshold_units="m s-1", time=dt(2015, 11, 19, 1, 30), frt=dt(2015, 11, 18, 22, 0)) time_points = [dt(2015, 11, 19, 0, 30), dt(2015, 11, 19, 1, 30)] cube = add_coordinate( cube, time_points, "time", order=[1, 0, 2, 3], is_datetime=True) cube.attributes["attribute_to_update"] = "first_value" cube.data = data return cube
def setUp(self): """Create a cube like this: probability_of_lwe_precipitation_rate_above_threshold / (1) Dimension coordinates: lwe_precipitation_rate: 1; projection_y_coordinate: 16; projection_x_coordinate: 16; Scalar coordinates: forecast_period: 14400 seconds forecast_reference_time: 2017-11-10 00:00:00 time: 2017-11-10 04:00:00 Cell methods: mean: realization The lwe_precipitation_rate coordinate will have the attribute: spp__relative_to_threshold: above. """ data = np.ones((1, 16, 16), dtype=np.float32) thresholds = np.array([0.5], dtype=np.float32) self.cube = set_up_probability_cube( data, thresholds, variable_name='lwe_precipitation_rate', threshold_units='mm h-1') self.cube.add_cell_method(CellMethod('mean', coords='realization')) self.plugin = Plugin()
def test_mismatched_time_bounds_ranges(self): """Test for mismatched bounds ranges error.""" frt = dt(2017, 11, 9, 21, 0) times = [ dt(2017, 11, 10, 3, 0), dt(2017, 11, 10, 4, 0), dt(2017, 11, 10, 5, 0) ] time_bounds = np.array( [[dt(2017, 11, 10, 2, 0), dt(2017, 11, 10, 3, 0)], [dt(2017, 11, 10, 3, 0), dt(2017, 11, 10, 4, 0)], [dt(2017, 11, 10, 2, 0), dt(2017, 11, 10, 5, 0)]]) cubelist = iris.cube.CubeList([]) for tpoint, tbounds in zip(times, time_bounds): cube = set_up_probability_cube(0.6 * np.ones( (2, 3, 3), dtype=np.float32), np.array([278., 280.], dtype=np.float32), time=tpoint, frt=frt, time_bounds=tbounds) cubelist.append(cube) msg = "Cube with mismatching time bounds ranges" with self.assertRaisesRegex(ValueError, msg): merge_cubes(cubelist, blend_coord="time")
def test_relative_to_threshold(self): """Test ability to reset the "relative_to_threshold" attribute""" data = np.flipud(self.data) result = set_up_probability_cube(data, self.thresholds, relative_to_threshold='below') self.assertEqual(len(result.attributes), 1) self.assertEqual(result.attributes['relative_to_threshold'], 'below')
def setUp(self): """Set up some probability cubes from different models""" data = np.array([ 0.9 * np.ones((3, 3)), 0.5 * np.ones((3, 3)), 0.1 * np.ones((3, 3)) ], dtype=np.float32) thresholds = np.array([273., 275., 277.], dtype=np.float32) time_point = dt(2015, 11, 23, 7) time_bounds = [dt(2015, 11, 23, 4), time_point] # set up a MOGREPS-UK cube with 7 hour forecast period self.cube_enuk = set_up_probability_cube( data.copy(), thresholds, standard_grid_metadata='uk_ens', time=time_point, frt=dt(2015, 11, 23, 0), time_bounds=time_bounds) # set up a UKV cube with 4 hour forecast period self.cube_ukv = set_up_probability_cube( data.copy(), thresholds, standard_grid_metadata='uk_det', time=time_point, frt=dt(2015, 11, 23, 3), time_bounds=time_bounds) self.cubelist = iris.cube.CubeList([self.cube_enuk, self.cube_ukv]) # set up some non-UK test cubes cube_non_mo_ens = self.cube_enuk.copy() cube_non_mo_ens.attributes.pop("mosg__model_configuration") cube_non_mo_ens.attributes['non_mo_model_config'] = 'non_uk_ens' cube_non_mo_det = self.cube_ukv.copy() cube_non_mo_det.attributes.pop("mosg__model_configuration") cube_non_mo_det.attributes['non_mo_model_config'] = 'non_uk_det' self.non_mo_cubelist = iris.cube.CubeList( [cube_non_mo_ens, cube_non_mo_det]) # set up plugin for multi-model blending weighted by forecast period self.plugin = MergeCubesForWeightedBlending( "model", weighting_coord="forecast_period", model_id_attr="mosg__model_configuration")
def test_default_nonlinear(self): """Test non-linear weighting over forecast reference time, where the earlier cycle has a higher weighting""" data = np.ones((3, 3, 3), dtype=np.float32) thresholds = np.array([276, 277, 278], dtype=np.float32) ukv_cube_earlier = set_up_probability_cube( data, thresholds, time=dt(2018, 9, 10, 7), frt=dt(2018, 9, 10, 3)) ukv_cube_later = set_up_probability_cube( data, thresholds, time=dt(2018, 9, 10, 7), frt=dt(2018, 9, 10, 4)) cube = iris.cube.CubeList( [ukv_cube_later, ukv_cube_earlier]).merge_cube() plugin = WeightAndBlend( "forecast_reference_time", "nonlinear", cval=0.85) weights = plugin._calculate_blending_weights(cube) self.assertArrayAlmostEqual( weights.data, np.array([0.5405405, 0.45945945]))
def set_up_masked_cubes(): """ Set up cubes with masked data for spatial weights tests Returns: iris.cube.CubeList: List containing a UKV cube with some rain, and a masked nowcast cube with more rain. """ thresholds = np.array([0.5, 1, 2], dtype=np.float32) units = "mm h-1" name = "lwe_precipitation_rate" datatime = dt(2018, 9, 10, 7) cycletime = dt(2018, 9, 10, 5) # 5x5 matrix results in grid spacing of 200 km base_data = np.ones((5, 5), dtype=np.float32) # set up a UKV cube with some rain rain_data = np.array([0.9 * base_data, 0.5 * base_data, 0 * base_data]) ukv_cube = set_up_probability_cube(rain_data, thresholds, variable_name=name, threshold_units=units, time=datatime, frt=cycletime, spatial_grid="equalarea", standard_grid_metadata="uk_det") # set up a masked nowcast cube with more rain more_rain_data = np.array([base_data, 0.6 * base_data, 0.2 * base_data]) radar_mask = np.broadcast_to(np.array([False, False, False, True, True]), (3, 5, 5)) more_rain_data = np.ma.MaskedArray(more_rain_data, mask=radar_mask) nowcast_cube = set_up_probability_cube( more_rain_data, thresholds, variable_name=name, threshold_units=units, time=datatime, frt=cycletime, spatial_grid="equalarea", attributes={"mosg__model_configuration": "nc_det"}) return iris.cube.CubeList([ukv_cube, nowcast_cube])
def test_standard_grid_metadata(self): """Test standard grid metadata""" result = set_up_probability_cube(self.data, self.thresholds, standard_grid_metadata='uk_ens') self.assertEqual(result.attributes['mosg__grid_type'], 'standard') self.assertEqual(result.attributes['mosg__grid_version'], '1.3.0') self.assertEqual( result.attributes['mosg__grid_domain'], 'uk_extended') self.assertEqual( result.attributes['mosg__model_configuration'], 'uk_ens')
def setUp(self): """Set up an example cube to test with""" thresholds = [10] data = np.ones((1, 2, 3), dtype=np.float32) cycle1 = set_up_probability_cube(data, thresholds, time=datetime(2017, 11, 10, 4, 0), frt=datetime(2017, 11, 10, 0, 0)) cycle2 = set_up_probability_cube(data, thresholds, time=datetime(2017, 11, 10, 4, 0), frt=datetime(2017, 11, 10, 1, 0)) cycle3 = set_up_probability_cube(data, thresholds, time=datetime(2017, 11, 10, 4, 0), frt=datetime(2017, 11, 10, 2, 0)) self.cube = CubeList([cycle1, cycle2, cycle3]).merge_cube() self.cube = squeeze(self.cube) self.plugin = SpatiallyVaryingWeightsFromMask()
def setUp(self): """Set up test probability cubes with old and new threshold coordinate naming conventions""" data = np.ones((3, 3, 3), dtype=np.float32) self.threshold_points = np.array([276, 277, 278], dtype=np.float32) cube = set_up_probability_cube(data, self.threshold_points) self.cube_new = cube.copy() self.cube_old = cube.copy() self.cube_old.coord("air_temperature").rename("threshold")
def test_defaults(self): """Test default arguments produce cube with expected dimensions and metadata""" result = set_up_probability_cube(self.data, self.thresholds) thresh_coord = result.coord("threshold") self.assertEqual(result.name(), 'probability_of_air_temperature') self.assertEqual(result.units, '1') self.assertArrayEqual(thresh_coord.points, self.thresholds) self.assertEqual(thresh_coord.units, 'K') self.assertEqual(len(result.attributes), 1) self.assertEqual(result.attributes['relative_to_threshold'], 'above')
def setUp(self): """ Set up a basic input cube. Input cube has 2 thresholds on and 3 forecast_reference_times """ thresholds = [10, 20] data = np.ones((2, 2, 3), dtype=np.float32) cycle1 = set_up_probability_cube( data, thresholds, spatial_grid="equalarea", time=datetime(2017, 11, 10, 4, 0), frt=datetime(2017, 11, 10, 0, 0), ) cycle2 = set_up_probability_cube( data, thresholds, spatial_grid="equalarea", time=datetime(2017, 11, 10, 4, 0), frt=datetime(2017, 11, 10, 1, 0), ) cycle3 = set_up_probability_cube( data, thresholds, spatial_grid="equalarea", time=datetime(2017, 11, 10, 4, 0), frt=datetime(2017, 11, 10, 2, 0), ) self.cube_to_collapse = CubeList([cycle1, cycle2, cycle3]).merge_cube() self.cube_to_collapse = squeeze(self.cube_to_collapse) self.cube_to_collapse.rename("weights") # This input array has 3 forecast reference times and 2 thresholds. # The two thresholds have the same weights. self.cube_to_collapse.data = np.array( [[[[1, 0, 1], [1, 1, 1]], [[1, 0, 1], [1, 1, 1]]], [[[0, 0, 1], [0, 1, 1]], [[0, 0, 1], [0, 1, 1]]], [[[1, 1, 1], [1, 1, 1]], [[1, 1, 1], [1, 1, 1]]]], dtype=np.float32) self.cube_to_collapse.data = np.ma.masked_equal( self.cube_to_collapse.data, 0) self.plugin = SpatiallyVaryingWeightsFromMask()
def setUp(self): """Set up some cubes with different time bounds ranges""" frt = dt(2017, 11, 9, 21, 0) times = [ dt(2017, 11, 10, 3, 0), dt(2017, 11, 10, 4, 0), dt(2017, 11, 10, 5, 0) ] time_bounds = np.array( [[dt(2017, 11, 10, 2, 0), dt(2017, 11, 10, 3, 0)], [dt(2017, 11, 10, 3, 0), dt(2017, 11, 10, 4, 0)], [dt(2017, 11, 10, 4, 0), dt(2017, 11, 10, 5, 0)]]) cubes = iris.cube.CubeList([]) for tpoint, tbounds in zip(times, time_bounds): cube = set_up_probability_cube(0.6 * np.ones( (2, 3, 3), dtype=np.float32), np.array([278., 280.], dtype=np.float32), time=tpoint, frt=frt, time_bounds=tbounds) cubes.append(cube) self.matched_cube = cubes.merge_cube() time_bounds[2, 0] = dt(2017, 11, 10, 2, 0) cubes = iris.cube.CubeList([]) for tpoint, tbounds in zip(times, time_bounds): cube = set_up_probability_cube(0.6 * np.ones( (2, 3, 3), dtype=np.float32), np.array([278., 280.], dtype=np.float32), time=tpoint, frt=frt, time_bounds=tbounds) cubes.append(cube) self.unmatched_cube = cubes.merge_cube() self.plugin = MergeCubes()
def test_ordering_for_threshold_coordinate(self): """Test that the cube has been reordered, if it is originally in an undesirable order and the cube contains a "threshold" coordinate.""" cube = set_up_probability_cube( np.zeros((3, 4, 5), dtype=np.float32), np.array([273., 274., 275.], dtype=np.float32)) cube.transpose([2, 1, 0]) save_netcdf(cube, self.filepath) result = load_cube(self.filepath) self.assertEqual(result.coord_dims("threshold")[0], 0) self.assertArrayAlmostEqual(result.coord_dims("latitude")[0], 1) self.assertArrayAlmostEqual(result.coord_dims("longitude")[0], 2)
def setUp(self): """Use temperature probability cube to test with.""" data = np.array([ 0.9 * np.ones((3, 3)), 0.5 * np.ones((3, 3)), 0.1 * np.ones((3, 3)) ], dtype=np.float32) thresholds = np.array([273., 275., 277.], dtype=np.float32) self.cube = set_up_probability_cube(data.copy(), thresholds) self.cell_method1 = iris.coords.CellMethod("mean", "realization") self.cell_method2 = iris.coords.CellMethod("mean", "time") self.cell_method3 = iris.coords.CellMethod("max", "neighbourhood") self.plugin = MergeCubes()
def setUp(self): """Set up a cube with 2 thresholds to test normalisation. We are testing normalising along the leading dimension in this cube.""" thresholds = [10, 20] data = np.ones((2, 2, 3), dtype=np.float32) cycle1 = set_up_probability_cube( data, thresholds, spatial_grid="equalarea", time=datetime(2017, 11, 10, 4, 0), frt=datetime(2017, 11, 10, 0, 0), ) cycle2 = set_up_probability_cube( data, thresholds, spatial_grid="equalarea", time=datetime(2017, 11, 10, 4, 0), frt=datetime(2017, 11, 10, 1, 0), ) cycle3 = set_up_probability_cube( data, thresholds, spatial_grid="equalarea", time=datetime(2017, 11, 10, 4, 0), frt=datetime(2017, 11, 10, 2, 0), ) self.spatial_weights_cube = CubeList([cycle1, cycle2, cycle3]).merge_cube() self.spatial_weights_cube = squeeze(self.spatial_weights_cube) self.spatial_weights_cube.rename("weights") # This input array has 3 forecast reference times and 2 thresholds. # The two thresholds have the same weights. self.spatial_weights_cube.data = np.array( [[[[0.2, 0, 0.2], [0.2, 0, 0.2]], [[0.2, 0, 0.2], [0.2, 0, 0.2]]], [[[0, 0, 0.5], [0, 0, 0.5]], [[0, 0, 0.5], [0, 0, 0.5]]], [[[0.3, 0.3, 0.3], [0.3, 0.3, 0.3]], [[0.3, 0.3, 0.3], [0.3, 0.3, 0.3]]]], dtype=np.float32) self.plugin = SpatiallyVaryingWeightsFromMask()
def setUp(self): """Set up a test cube with probability data""" data = np.array([ [[1.0, 1.0, 1.0], [1.0, 1.0, 1.0], [1.0, 1.0, 1.0]], [[0.9, 0.9, 0.9], [0.8, 0.8, 0.8], [0.7, 0.7, 0.7]], [[0.1, 0.2, 0.3], [0.1, 0.2, 0.3], [0.1, 0.2, 0.3]], [[0.0, 0.0, 0.0], [0.1, 0.1, 0.1], [0.1, 0.2, 0.2]]], dtype=np.float32) temp_thresholds = np.array([279, 280, 281, 282], dtype=np.float32) vis_thresholds = np.array([100, 1000, 5000, 10000], dtype=np.float32) self.temp_cube = set_up_probability_cube(data, temp_thresholds) self.vis_cube = set_up_probability_cube( np.flip(data, axis=0), vis_thresholds, variable_name='visibility', threshold_units='m', spp__relative_to_threshold='below') # set up a cube of rainfall rates in m s-1 (~1e-8 values) self.precip_cube = self.temp_cube.copy() self.precip_cube.coord('air_temperature').rename('rainfall_rate') self.precip_cube.coord('rainfall_rate').var_name = 'threshold' self.precip_cube.coord('rainfall_rate').points = np.array( [0, 0.25, 0.5, 1], dtype=np.float32) self.precip_cube.coord('rainfall_rate').units = 'mm h-1' self.precip_cube.coord('rainfall_rate').convert_units('m s-1')
def setUp(self): """ Set up a basic 2D cube with a large enough grid to see the effect of the fuzzy weights. """ thresholds = [10] data = np.ones((1, 7, 7), dtype=np.float32) self.cube = set_up_probability_cube( data, thresholds, spatial_grid="equalarea", time=datetime(2017, 11, 10, 4, 0), frt=datetime(2017, 11, 10, 0, 0), ) self.cube = squeeze(self.cube)
def setUp(self): """Set up some conformant cubes of air_temperature to test""" data = 275 * np.ones((3, 3), dtype=np.float32) self.data_cube = set_up_variable_cube(data, spatial_grid='equalarea') data = np.ones((3, 3, 3), dtype=np.float32) thresholds = np.array([272, 273, 274], dtype=np.float32) self.probability_cube = set_up_probability_cube(data, thresholds) data = np.array([ 274 * np.ones((3, 3), dtype=np.float32), 275 * np.ones( (3, 3), dtype=np.float32), 276 * np.ones( (3, 3), dtype=np.float32) ]) percentiles = np.array([25, 50, 75], np.float32) self.percentile_cube = set_up_percentile_cube(data, percentiles)
def setUp(self): """Set up some conformant cubes of air_temperature to test""" data = 275 * np.ones((3, 3), dtype=np.float32) self.data_cube = set_up_variable_cube(data, spatial_grid='equalarea') data = np.ones((3, 3, 3), dtype=np.float32) thresholds = np.array([272, 273, 274], dtype=np.float32) self.probability_cube = set_up_probability_cube(data, thresholds) data = np.array([ 274 * np.ones((3, 3), dtype=np.float32), 275 * np.ones( (3, 3), dtype=np.float32), 276 * np.ones( (3, 3), dtype=np.float32) ]) percentiles = np.array([25, 50, 75], np.float32) self.percentile_cube = set_up_percentile_cube(data, percentiles) # set to real source here, to test consistency of setup functions # with up-to-date metadata standard cube_units.DEFAULT_UNITS = improver.units.DEFAULT_UNITS
def test_ordering_for_realization_threshold_percentile_over_coordinate( self): """Test that the cube has been reordered, if it is originally in an undesirable order and the cube contains a "threshold" coordinate, a "realization" coordinate and a "percentile_over" coordinate.""" cube = set_up_probability_cube( np.zeros((3, 4, 5), dtype=np.float32), np.array([273., 274., 275.], dtype=np.float32)) cube = add_coordinate(cube, [0, 1, 2], "realization") cube = add_coordinate(cube, [10, 50, 90], "percentile_over_neighbourhood") cube.transpose([4, 3, 2, 1, 0]) save_netcdf(cube, self.filepath) result = load_cube(self.filepath) self.assertEqual(result.coord_dims("realization")[0], 0) self.assertEqual( result.coord_dims("percentile_over_neighbourhood")[0], 1) self.assertEqual(result.coord_dims("threshold")[0], 2) self.assertArrayAlmostEqual(result.coord_dims("latitude")[0], 3) self.assertArrayAlmostEqual(result.coord_dims("longitude")[0], 4)