def test_basic(self): """Test times can be set""" coord_dims = construct_scalar_time_coords(datetime(2017, 12, 1, 14, 0), None, datetime(2017, 12, 1, 9, 0)) time_coords = [item[0] for item in coord_dims] for crd in time_coords: self.assertIsInstance(crd, iris.coords.DimCoord) self.assertEqual(time_coords[0].name(), "time") self.assertEqual( iris_time_to_datetime(time_coords[0])[0], datetime(2017, 12, 1, 14, 0)) self.assertEqual(time_coords[1].name(), "forecast_reference_time") self.assertEqual( iris_time_to_datetime(time_coords[1])[0], datetime(2017, 12, 1, 9, 0)) self.assertEqual(time_coords[2].name(), "forecast_period") self.assertEqual(time_coords[2].points[0], 3600 * 5) for crd in time_coords[:2]: self.assertEqual(crd.dtype, np.int64) self.assertEqual(crd.units, "seconds since 1970-01-01 00:00:00") self.assertEqual(time_coords[2].units, "seconds") self.assertEqual(time_coords[2].dtype, np.int32)
def set_up_variable_cube(data, name="temperature", units="degC", xo=400000., yo=0.): """ Set up cube containing diagnostic variable data for regridding tests. Data are on a 2 km Transverse Mercator grid with an inverted y-axis, located in the UK. """ y_points = 2000. * (data.shape[0] - np.arange(data.shape[0])) + yo x_points = 2000. * np.arange(data.shape[1]) + xo y_coord = DimCoord(y_points, 'projection_y_coordinate', units='m', coord_system=TMercCS) x_coord = DimCoord(x_points, 'projection_x_coordinate', units='m', coord_system=TMercCS) time_coords = construct_scalar_time_coords(datetime(2015, 11, 23, 4, 30), None, datetime(2015, 11, 22, 22, 30)) cube = iris.cube.Cube(data, long_name=name, units=units, dim_coords_and_dims=[(y_coord, 0), (x_coord, 1)], aux_coords_and_dims=time_coords) return cube
def test_error_negative_fp(self): """Test an error is raised if the calculated forecast period is negative""" msg = 'Cannot set up cube with negative forecast period' with self.assertRaisesRegex(ValueError, msg): _ = construct_scalar_time_coords( datetime(2017, 12, 1, 14, 0), None, datetime(2017, 12, 1, 16, 0))
def test_error_invalid_time_bounds(self): """Test an error is raised if the time point is not between the specified bounds""" msg = 'not within bounds' with self.assertRaisesRegex(ValueError, msg): _ = construct_scalar_time_coords( datetime(2017, 11, 10, 4, 0), (datetime(2017, 12, 1, 13, 0), datetime(2017, 12, 1, 14, 0)), datetime(2017, 11, 10, 0, 0))
def test_time_bounds(self): """Test creation of time coordinate with bounds""" coord_dims = construct_scalar_time_coords( datetime(2017, 12, 1, 14, 0), (datetime(2017, 12, 1, 13, 0), datetime(2017, 12, 1, 14, 0)), datetime(2017, 12, 1, 9, 0)) time_coord = coord_dims[0][0] self.assertEqual(iris_time_to_datetime(time_coord)[0], datetime(2017, 12, 1, 14, 0)) self.assertEqual(time_coord.bounds[0][0], time_coord.points[0] - 3600) self.assertEqual(time_coord.bounds[0][1], time_coord.points[0])
def test_time_bounds_wrong_order(self): """Test time bounds are correctly applied even if supplied in the wrong order""" coord_dims = construct_scalar_time_coords( datetime(2017, 12, 1, 14, 0), (datetime(2017, 12, 1, 14, 0), datetime(2017, 12, 1, 13, 0)), datetime(2017, 12, 1, 9, 0)) time_coord = coord_dims[0][0] self.assertEqual(iris_time_to_datetime(time_coord)[0], datetime(2017, 12, 1, 14, 0)) self.assertEqual(time_coord.bounds[0][0], time_coord.points[0] - 3600) self.assertEqual(time_coord.bounds[0][1], time_coord.points[0])
def test_scalar_coords(self): """Test additional scalar coordinates""" [(time_coord, _), (frt_coord, _), (fp_coord, _) ] = (construct_scalar_time_coords(datetime(2015, 11, 23, 4, 30), None, datetime(2015, 11, 22, 22, 30))) data = np.ones((4, 2), dtype=np.float32) result = build_spotdata_cube( data, 'air_temperature', 'degC', self.altitude, self.latitude, self.longitude, self.wmo_id, scalar_coords=[time_coord, frt_coord, fp_coord], neighbour_methods=self.neighbour_methods) self.assertEqual(result.coord('time').points[0], time_coord.points[0]) self.assertEqual( result.coord('forecast_reference_time').points[0], frt_coord.points[0]) self.assertEqual( result.coord('forecast_period').points[0], fp_coord.points[0])
def setUp(self): """ Set up cubes for use in testing SpotLapseRateAdjust. Inputs are envisaged as follows: Gridded Lapse rate Orography Temperatures (not used directly) (x DALR) A B C A B C A B C a 2 1 1 1 1 1 270 270 270 b 1 2 1 1 4 1 270 280 270 c 1 1 2 1 1 1 270 270 270 Spot (note the neighbours are identified with the A-C, a-c indices above) Site Temperature Altitude Nearest DZ MinDZ DZ neighbour neighbour 0 280 3 Ac 2 Bb -1 1 270 4 Bb 0 Bb 0 2 280 0 Ca -1 Ca -1 """ # Set up lapse rate cube lapse_rate_data = np.ones(9).reshape(3, 3).astype(np.float32) * DALR lapse_rate_data[0, 2] = 2 * DALR lapse_rate_data[1, 1] = 2 * DALR lapse_rate_data[2, 0] = 2 * DALR self.lapse_rate_cube = set_up_variable_cube(lapse_rate_data, name="lapse_rate", units="K m-1", spatial_grid="equalarea") diagnostic_cube_hash = create_coordinate_hash(self.lapse_rate_cube) # Set up neighbour and spot diagnostic cubes y_coord, x_coord = construct_xy_coords(3, 3, "equalarea") y_coord = y_coord.points x_coord = x_coord.points # neighbours, each group is for a point under two methods, e.g. # [ 0. 0. 0.] is the nearest point to the first spot site, whilst # [ 1. 1. -1.] is the nearest point with minimum height difference. neighbours = np.array([[[0., 0., 2.], [1., 1., -1.]], [[1., 1., 0.], [1., 1., 0.]], [[2., 2., -1.], [2., 2., -1.]]]) altitudes = np.array([3, 4, 0]) latitudes = np.array([y_coord[0], y_coord[1], y_coord[2]]) longitudes = np.array([x_coord[0], x_coord[1], x_coord[2]]) wmo_ids = np.arange(3) grid_attributes = ['x_index', 'y_index', 'vertical_displacement'] neighbour_methods = ['nearest', 'nearest_minimum_dz'] self.neighbour_cube = build_spotdata_cube( neighbours, 'grid_neighbours', 1, altitudes, latitudes, longitudes, wmo_ids, grid_attributes=grid_attributes, neighbour_methods=neighbour_methods) self.neighbour_cube.attributes['model_grid_hash'] = ( diagnostic_cube_hash) time, = iris_time_to_datetime(self.lapse_rate_cube.coord("time")) frt, = iris_time_to_datetime( self.lapse_rate_cube.coord("forecast_reference_time")) time_bounds = None time_coords = construct_scalar_time_coords(time, time_bounds, frt) time_coords = [item[0] for item in time_coords] # This temperature cube is set up with the spot sites having obtained # their temperature values from the nearest grid sites. temperatures_nearest = np.array([280, 270, 280]) self.spot_temperature_nearest = build_spotdata_cube( temperatures_nearest, 'air_temperature', 'K', altitudes, latitudes, longitudes, wmo_ids, scalar_coords=time_coords) self.spot_temperature_nearest.attributes['model_grid_hash'] = ( diagnostic_cube_hash) # This temperature cube is set up with the spot sites having obtained # their temperature values from the nearest minimum vertical # displacment grid sites. The only difference here is for site 0, which # now gets its temperature from Bb (see doc-string above). temperatures_mindz = np.array([270, 270, 280]) self.spot_temperature_mindz = build_spotdata_cube( temperatures_mindz, 'air_temperature', 'K', altitudes, latitudes, longitudes, wmo_ids, scalar_coords=time_coords) self.spot_temperature_mindz.attributes['model_grid_hash'] = ( diagnostic_cube_hash)