def create_cube(lon_min, lon_max, bounds=False): n_lons = max(lon_min, lon_max) - min(lon_max, lon_min) data = np.arange(4 * 3 * n_lons, dtype='f4').reshape(4, 3, n_lons) data = biggus.NumpyArrayAdapter(data) cube = Cube(data, standard_name='x_wind', units='ms-1') cube.add_dim_coord( iris.coords.DimCoord([0, 20, 40, 80], long_name='level_height', units='m'), 0) cube.add_aux_coord( iris.coords.AuxCoord([1.0, 0.9, 0.8, 0.6], long_name='sigma'), 0) cube.add_dim_coord( iris.coords.DimCoord([-45, 0, 45], 'latitude', units='degrees'), 1) step = 1 if lon_max > lon_min else -1 cube.add_dim_coord( iris.coords.DimCoord(np.arange(lon_min, lon_max, step), 'longitude', units='degrees'), 2) if bounds: cube.coord('longitude').guess_bounds() cube.add_aux_coord( iris.coords.AuxCoord(np.arange(3 * n_lons).reshape(3, n_lons) * 10, 'surface_altitude', units='m'), [1, 2]) cube.add_aux_factory( iris.aux_factory.HybridHeightFactory(cube.coord('level_height'), cube.coord('sigma'), cube.coord('surface_altitude'))) return cube
def test_hybrid_height_with_non_standard_coords(self): # Check the save rules are using the AuxFactory to find the # hybrid height coordinates and not relying on their names. ny, nx = 30, 40 sigma_lower, sigma, sigma_upper = 0.75, 0.8, 0.75 delta_lower, delta, delta_upper = 150, 200, 250 cube = Cube(np.zeros((ny, nx)), 'air_temperature') level_coord = AuxCoord(0, 'model_level_number') cube.add_aux_coord(level_coord) delta_coord = AuxCoord(delta, bounds=[[delta_lower, delta_upper]], long_name='moog', units='m') sigma_coord = AuxCoord(sigma, bounds=[[sigma_lower, sigma_upper]], long_name='mavis') surface_altitude_coord = AuxCoord(np.zeros((ny, nx)), 'surface_altitude', units='m') cube.add_aux_coord(delta_coord) cube.add_aux_coord(sigma_coord) cube.add_aux_coord(surface_altitude_coord, (0, 1)) cube.add_aux_factory(HybridHeightFactory(delta_coord, sigma_coord, surface_altitude_coord)) field = iris.fileformats.pp.PPField3() field.lbfc = 0 field.lbvc = 0 field.brsvd = [None, None] field.lbuser = [None] * 7 iris.fileformats.pp._ensure_save_rules_loaded() iris.fileformats.pp._save_rules.verify(cube, field) self.assertEqual(field.blev, delta) self.assertEqual(field.brlev, delta_lower) self.assertEqual(field.bhlev, sigma) self.assertEqual(field.bhrlev, sigma_lower) self.assertEqual(field.brsvd, [delta_upper, sigma_upper])
def test_hybrid_pressure_with_non_standard_coords(self): # Check the save rules are using the AuxFactory to find the # hybrid pressure coordinates and not relying on their names. ny, nx = 30, 40 sigma_lower, sigma, sigma_upper = 0.75, 0.8, 0.75 delta_lower, delta, delta_upper = 0.15, 0.2, 0.25 cube = Cube(np.zeros((ny, nx)), 'air_temperature') level_coord = AuxCoord(0, 'model_level_number') cube.add_aux_coord(level_coord) delta_coord = AuxCoord(delta, bounds=[[delta_lower, delta_upper]], long_name='moog', units='Pa') sigma_coord = AuxCoord(sigma, bounds=[[sigma_lower, sigma_upper]], long_name='mavis') surface_air_pressure_coord = AuxCoord(np.zeros((ny, nx)), 'surface_air_pressure', units='Pa') cube.add_aux_coord(delta_coord) cube.add_aux_coord(sigma_coord) cube.add_aux_coord(surface_air_pressure_coord, (0, 1)) cube.add_aux_factory(HybridPressureFactory( delta_coord, sigma_coord, surface_air_pressure_coord)) field = iris.fileformats.pp.PPField3() field.lbfc = 0 field.lbvc = 0 field.brsvd = [None, None] field.lbuser = [None] * 7 field = verify(cube, field) self.assertEqual(field.bhlev, delta) self.assertEqual(field.bhrlev, delta_lower) self.assertEqual(field.blev, sigma) self.assertEqual(field.brlev, sigma_lower) self.assertEqual(field.brsvd, [sigma_upper, delta_upper])
def create_cube(lon_min, lon_max, bounds=False): n_lons = max(lon_min, lon_max) - min(lon_max, lon_min) data = np.arange(4 * 3 * n_lons, dtype='f4').reshape(4, 3, n_lons) data = biggus.NumpyArrayAdapter(data) cube = Cube(data, standard_name='x_wind', units='ms-1') cube.add_dim_coord(iris.coords.DimCoord([0, 20, 40, 80], long_name='level_height', units='m'), 0) cube.add_aux_coord(iris.coords.AuxCoord([1.0, 0.9, 0.8, 0.6], long_name='sigma'), 0) cube.add_dim_coord(iris.coords.DimCoord([-45, 0, 45], 'latitude', units='degrees'), 1) step = 1 if lon_max > lon_min else -1 circular = (abs(lon_max - lon_min) == 360) cube.add_dim_coord(iris.coords.DimCoord(np.arange(lon_min, lon_max, step), 'longitude', units='degrees', circular=circular), 2) if bounds: cube.coord('longitude').guess_bounds() cube.add_aux_coord(iris.coords.AuxCoord( np.arange(3 * n_lons).reshape(3, n_lons) * 10, 'surface_altitude', units='m'), [1, 2]) cube.add_aux_factory(iris.aux_factory.HybridHeightFactory( cube.coord('level_height'), cube.coord('sigma'), cube.coord('surface_altitude'))) return cube
def test_hybrid_pressure_with_non_standard_coords(self): # Check the save rules are using the AuxFactory to find the # hybrid pressure coordinates and not relying on their names. ny, nx = 30, 40 sigma_lower, sigma, sigma_upper = 0.75, 0.8, 0.75 delta_lower, delta, delta_upper = 0.15, 0.2, 0.25 cube = Cube(np.zeros((ny, nx)), "air_temperature") level_coord = AuxCoord(0, "model_level_number") cube.add_aux_coord(level_coord) delta_coord = AuxCoord(delta, bounds=[[delta_lower, delta_upper]], long_name="moog", units="Pa") sigma_coord = AuxCoord(sigma, bounds=[[sigma_lower, sigma_upper]], long_name="mavis") surface_air_pressure_coord = AuxCoord(np.zeros((ny, nx)), "surface_air_pressure", units="Pa") cube.add_aux_coord(delta_coord) cube.add_aux_coord(sigma_coord) cube.add_aux_coord(surface_air_pressure_coord, (0, 1)) cube.add_aux_factory(HybridPressureFactory(delta_coord, sigma_coord, surface_air_pressure_coord)) field = iris.fileformats.pp.PPField3() field.lbfc = 0 field.lbvc = 0 field.brsvd = [None, None] field.lbuser = [None] * 7 iris.fileformats.pp._ensure_save_rules_loaded() iris.fileformats.pp._save_rules.verify(cube, field) self.assertEqual(field.bhlev, delta) self.assertEqual(field.bhrlev, delta_lower) self.assertEqual(field.blev, sigma) self.assertEqual(field.brlev, sigma_lower) self.assertEqual(field.brsvd, [sigma_upper, delta_upper])
def ocean_sigma_z(): """ Return a sample cube with an :class:`iris.aux_factory.OceanSigmaZFactory` vertical coordinate. This is a fairly small cube with real coordinate arrays. The coordinate values are derived from the sample data linked at https://github.com/SciTools/iris/pull/509#issuecomment-23565381. """ co_time = DimCoord([0.0, 1.0], standard_name='time', units='') co_lats = DimCoord([-58.1, -52.7, -46.9], standard_name='latitude', units=Unit('degrees')) co_lons = DimCoord([65.1, 72.9, 83.7, 96.5], standard_name='longitude', units=Unit('degrees')) co_ssh = AuxCoord([[[-0.63157895, -0.52631579, -0.42105263, -0.31578947], [-0.78947368, -0.68421053, -0.57894737, -0.47368421], [-0.94736842, -0.84210526, -0.73684211, -0.63157895]], [[-0.84210526, -0.73684211, -0.63157895, -0.52631579], [-1.00000000, -0.89473684, -0.78947368, -0.68421053], [-1.15789474, -1.05263158, -0.94736842, -0.84210526]]], standard_name=u'sea_surface_height', units=Unit('m')) co_sigma = AuxCoord([0., -0.1, -0.6, -1., -1.], standard_name=u'ocean_sigma_z_coordinate', units=Unit('1'), attributes={'positive': 'up'}) co_zlay = AuxCoord([-137.2, -137.3, -137.4, -368.4, -1495.6], long_name='layer_depth', units=Unit('m')) co_depth = AuxCoord([[1625.7, 3921.2, 4106.4, 5243.5], [3615.4, 4942.6, 3883.6, 4823.1], [3263.2, 2816.3, 2741.8, 3883.6]], standard_name=u'depth', units=Unit('m')) co_depthc = DimCoord(137.9, long_name='depth_c', units=Unit('m')) co_nsigma = DimCoord(3, long_name='nsigma') cube = Cube(np.zeros((2, 5, 3, 4))) cube.add_dim_coord(co_time, 0) cube.add_dim_coord(co_lats, 2) cube.add_dim_coord(co_lons, 3) cube.add_aux_coord(co_zlay, 1) cube.add_aux_coord(co_sigma, 1) cube.add_aux_coord(co_ssh, (0, 2, 3)) cube.add_aux_coord(co_depth, (2, 3)) cube.add_aux_coord(co_depthc) cube.add_aux_coord(co_nsigma) fact = iris.aux_factory.OceanSigmaZFactory( depth=co_depth, eta=co_ssh, depth_c=co_depthc, zlev=co_zlay, sigma=co_sigma, nsigma=co_nsigma) cube.add_aux_factory(fact) return cube
def empty_model_level_cube(data, name=None, unit=None, stash=None, **kwargs): """ Create a model_level cube from input data. """ if data is None: data = np.empty([1, 3, 8, 6]) assert data.shape == (3, 8, 6) # Make axis=0 for time dim_coord new_data = data[np.newaxis, :] cube = Cube(new_data) # time = AuxCoord([0], 'time', units='hours since epoch') time = DimCoord([0], 'time', units='hours since epoch') # model = DimCoord([1, 2, 3], 'model_level_number', # attributes={'positive': 'up'}) model = DimCoord([1, 2, 3], 'air_pressure', attributes={'positive': 'up'}) latitude = DimCoord([6.26953125, 6.38671875, 6.50390625, 6.62109375, 6.73828125, 6.85546875, 6.97265625, 7.08984375], standard_name='latitude', units='degrees') longitude = DimCoord([81.12304688, 81.29882812, 81.47460938, 81.65039062, 81.82617188, 82.00195312], standard_name='longitude', units='degrees') level_heights = np.array([20., 53.336, 100.]) level_height = DimCoord(level_heights, long_name='level_height', units='m') surface = AuxCoord(topo_aps3.data, 'surface_altitude', units='m') sigma = AuxCoord([0.99772321, 0.99393402, 0.98864199], long_name='sigma') cube.add_dim_coord(time, 0) cube.add_dim_coord(model, 1) cube.add_dim_coord(latitude, 2) cube.add_dim_coord(longitude, 3) cube.add_aux_coord(level_height, 1) cube.add_aux_coord(sigma, 1) cube.add_aux_coord(surface, (2, 3)) # Now that we have all of the necessary information, construct a # HybridHeight derived "altitude" coordinate. cube.add_aux_factory(HybridHeightFactory(level_height, sigma, surface)) if name: cube.long_name = name if unit: cube.units = unit if stash: cube.attributes['STASH'] = stash return cube
def uk_cube(): data = np.arange(12, dtype=np.float32).reshape(3, 4) uk = Cube(data) cs = OSGB() y_coord = DimCoord(range(3), 'projection_y_coordinate', units='m', coord_system=cs) x_coord = DimCoord(range(4), 'projection_x_coordinate', units='m', coord_system=cs) uk.add_dim_coord(y_coord, 0) uk.add_dim_coord(x_coord, 1) surface = AuxCoord(data * 10, 'surface_altitude', units='m') uk.add_aux_coord(surface, (0, 1)) uk.add_aux_factory(HybridHeightFactory(orography=surface)) return uk
def uk_cube(): data = np.arange(12, dtype=np.float32).reshape(3, 4) uk = Cube(data) cs = OSGB() y_coord = DimCoord(np.arange(3), 'projection_y_coordinate', units='m', coord_system=cs) x_coord = DimCoord(np.arange(4), 'projection_x_coordinate', units='m', coord_system=cs) uk.add_dim_coord(y_coord, 0) uk.add_dim_coord(x_coord, 1) surface = AuxCoord(data * 10, 'surface_altitude', units='m') uk.add_aux_coord(surface, (0, 1)) uk.add_aux_factory(HybridHeightFactory(orography=surface)) return uk
def test_hybrid_height_with_non_standard_coords(self): # Check the save rules are using the AuxFactory to find the # hybrid height coordinates and not relying on their names. ny, nx = 30, 40 sigma_lower, sigma, sigma_upper = 0.75, 0.8, 0.75 delta_lower, delta, delta_upper = 150, 200, 250 cube = Cube(np.zeros((ny, nx)), "air_temperature") level_coord = AuxCoord(0, "model_level_number", units="1") cube.add_aux_coord(level_coord) delta_coord = AuxCoord( delta, bounds=[[delta_lower, delta_upper]], long_name="moog", units="m", ) sigma_coord = AuxCoord( sigma, bounds=[[sigma_lower, sigma_upper]], long_name="mavis", units="1", ) surface_altitude_coord = AuxCoord( np.zeros((ny, nx)), "surface_altitude", units="m" ) cube.add_aux_coord(delta_coord) cube.add_aux_coord(sigma_coord) cube.add_aux_coord(surface_altitude_coord, (0, 1)) cube.add_aux_factory( HybridHeightFactory( delta_coord, sigma_coord, surface_altitude_coord ) ) field = iris.fileformats.pp.PPField3() field.lbfc = 0 field.lbvc = 0 field.brsvd = [None, None] field.lbuser = [None] * 7 field = verify(cube, field) self.assertEqual(field.blev, delta) self.assertEqual(field.brlev, delta_lower) self.assertEqual(field.bhlev, sigma) self.assertEqual(field.bhrlev, sigma_lower) self.assertEqual(field.brsvd, [delta_upper, sigma_upper])
def _copy_cube_transformed(src_cube, data, coord_func): """ Returns a new cube based on the src_cube, but with the given data, and with the coordinates transformed via coord_func. The data must have the same number of dimensions as the source cube. """ from iris.cube import Cube assert src_cube.ndim == data.ndim # Start with just the metadata and the data... new_cube = Cube(data) new_cube.metadata = src_cube.metadata new_cube.metadata = src_cube.metadata # ... and then create all the coordinates. # Record a mapping from old coordinate IDs to new coordinates, # for subsequent use in creating updated aux_factories. coord_mapping = {} def copy_coords(source_coords, add_method): for coord in source_coords: new_coord = coord_func(coord) add_method(new_coord, src_cube.coord_dims(coord)) coord_mapping[id(coord)] = new_coord copy_coords(src_cube.dim_coords, new_cube.add_dim_coord) copy_coords(src_cube.aux_coords, new_cube.add_aux_coord) for factory in src_cube.aux_factories: new_cube.add_aux_factory(factory.updated(coord_mapping)) return new_cube
def ocean_sigma_z(): """ Return a sample cube with an :class:`iris.aux_factory.OceanSigmaZFactory` vertical coordinate. This is a fairly small cube with real coordinate arrays. The coordinate values are derived from the sample data linked at https://github.com/SciTools/iris/pull/509#issuecomment-23565381. """ co_time = DimCoord([0.0, 1.0], standard_name="time", units="") co_lats = DimCoord([-58.1, -52.7, -46.9], standard_name="latitude", units=Unit("degrees")) co_lons = DimCoord( [65.1, 72.9, 83.7, 96.5], standard_name="longitude", units=Unit("degrees"), ) co_ssh = AuxCoord( [ [ [-0.63157895, -0.52631579, -0.42105263, -0.31578947], [-0.78947368, -0.68421053, -0.57894737, -0.47368421], [-0.94736842, -0.84210526, -0.73684211, -0.63157895], ], [ [-0.84210526, -0.73684211, -0.63157895, -0.52631579], [-1.00000000, -0.89473684, -0.78947368, -0.68421053], [-1.15789474, -1.05263158, -0.94736842, -0.84210526], ], ], standard_name="sea_surface_height", units=Unit("m"), ) co_sigma = AuxCoord( [0.0, -0.1, -0.6, -1.0, -1.0], standard_name="ocean_sigma_z_coordinate", units=Unit("1"), attributes={"positive": "up"}, ) co_zlay = AuxCoord( [-137.2, -137.3, -137.4, -368.4, -1495.6], long_name="layer_depth", units=Unit("m"), ) co_depth = AuxCoord( [ [1625.7, 3921.2, 4106.4, 5243.5], [3615.4, 4942.6, 3883.6, 4823.1], [3263.2, 2816.3, 2741.8, 3883.6], ], standard_name="depth", units=Unit("m"), ) co_depthc = DimCoord(137.9, long_name="depth_c", units=Unit("m")) co_nsigma = DimCoord(3, long_name="nsigma") cube = Cube(np.zeros((2, 5, 3, 4))) cube.add_dim_coord(co_time, 0) cube.add_dim_coord(co_lats, 2) cube.add_dim_coord(co_lons, 3) cube.add_aux_coord(co_zlay, 1) cube.add_aux_coord(co_sigma, 1) cube.add_aux_coord(co_ssh, (0, 2, 3)) cube.add_aux_coord(co_depth, (2, 3)) cube.add_aux_coord(co_depthc) cube.add_aux_coord(co_nsigma) fact = iris.aux_factory.OceanSigmaZFactory( depth=co_depth, eta=co_ssh, depth_c=co_depthc, zlev=co_zlay, sigma=co_sigma, nsigma=co_nsigma, ) cube.add_aux_factory(fact) return cube
def _create_cube( data, src, x_dim, y_dim, src_x_coord, src_y_coord, grid_x_coord, grid_y_coord, sample_grid_x, sample_grid_y, regrid_callback, ): """ Return a new Cube for the result of regridding the source Cube onto the new grid. All the metadata and coordinates of the result Cube are copied from the source Cube, with two exceptions: - Grid dimension coordinates are copied from the grid Cube. - Auxiliary coordinates which span the grid dimensions are ignored, except where they provide a reference surface for an :class:`iris.aux_factory.AuxCoordFactory`. Args: * data: The regridded data as an N-dimensional NumPy array. * src: The source Cube. * x_dim: The X dimension within the source Cube. * y_dim: The Y dimension within the source Cube. * src_x_coord: The X :class:`iris.coords.DimCoord`. * src_y_coord: The Y :class:`iris.coords.DimCoord`. * grid_x_coord: The :class:`iris.coords.DimCoord` for the new grid's X coordinate. * grid_y_coord: The :class:`iris.coords.DimCoord` for the new grid's Y coordinate. * sample_grid_x: A 2-dimensional array of sample X values. * sample_grid_y: A 2-dimensional array of sample Y values. * regrid_callback: The routine that will be used to calculate the interpolated values of any reference surfaces. Returns: The new, regridded Cube. """ from iris.cube import Cube # # XXX: At the moment requires to be a static method as used by # experimental regrid_area_weighted_rectilinear_src_and_grid # # Create a result cube with the appropriate metadata result = Cube(data) result.metadata = copy.deepcopy(src.metadata) # Copy across all the coordinates which don't span the grid. # Record a mapping from old coordinate IDs to new coordinates, # for subsequent use in creating updated aux_factories. coord_mapping = {} def copy_coords(src_coords, add_method): for coord in src_coords: dims = src.coord_dims(coord) if coord == src_x_coord: coord = grid_x_coord elif coord == src_y_coord: coord = grid_y_coord elif x_dim in dims or y_dim in dims: continue result_coord = coord.copy() add_method(result_coord, dims) coord_mapping[id(coord)] = result_coord copy_coords(src.dim_coords, result.add_dim_coord) copy_coords(src.aux_coords, result.add_aux_coord) def regrid_reference_surface( src_surface_coord, surface_dims, x_dim, y_dim, src_x_coord, src_y_coord, sample_grid_x, sample_grid_y, regrid_callback, ): # Determine which of the reference surface's dimensions span the X # and Y dimensions of the source cube. surface_x_dim = surface_dims.index(x_dim) surface_y_dim = surface_dims.index(y_dim) surface = regrid_callback( src_surface_coord.points, surface_x_dim, surface_y_dim, src_x_coord, src_y_coord, sample_grid_x, sample_grid_y, ) surface_coord = src_surface_coord.copy(surface) return surface_coord # Copy across any AuxFactory instances, and regrid their reference # surfaces where required. for factory in src.aux_factories: for coord in factory.dependencies.values(): if coord is None: continue dims = src.coord_dims(coord) if x_dim in dims and y_dim in dims: result_coord = regrid_reference_surface( coord, dims, x_dim, y_dim, src_x_coord, src_y_coord, sample_grid_x, sample_grid_y, regrid_callback, ) result.add_aux_coord(result_coord, dims) coord_mapping[id(coord)] = result_coord try: result.add_aux_factory(factory.updated(coord_mapping)) except KeyError: msg = ("Cannot update aux_factory {!r} because of dropped" " coordinates.".format(factory.name())) warnings.warn(msg) return result
def make_mock_cube(lat_dim_length=5, lon_dim_length=3, lon_range=None, alt_dim_length=0, pres_dim_length=0, time_dim_length=0, horizontal_offset=0, altitude_offset=0, pressure_offset=0, time_offset=0, data_offset=0, surf_pres_offset=0, hybrid_ht_len=0, hybrid_pr_len=0, geopotential_height=False, dim_order=None, mask=False): """ Makes a cube of any shape required, with coordinate offsets from the default available. If no arguments are given get a 5x3 cube of the form: array([[1,2,3], [4,5,6], [7,8,9], [10,11,12], [13,14,15]]) and coordinates in latitude: array([ -10, -5, 0, 5, 10 ]) longitude: array([ -5, 0, 5 ]) :param lat_dim_length: Latitude grid length :param lon_dim_length: Longitude grid length :param alt_dim_length: Altitude grid length :param pres_dim_length: Pressure grid length :param time_dim_length: Time grid length :param horizontal_offset: Offset from the default grid, in degrees, in lat and lon :param altitude_offset: Offset from the default grid in altitude :param pressure_offset: Offset from the default grid in pressure :param time_offset: Offset from the default grid in time :param data_offset: Offset from the default data values :param surf_pres_offset: Offset for the optional surface pressure field :param hybrid_ht_len: Hybrid height grid length :param hybrid_pr_len: Hybrid pressure grid length :param geopotential_height: Include a geopotential height field when calcluting a hybrid pressure? (default False) :param dim_order: List of 'lat', 'lon', 'alt', 'pres', 'time' in the order in which the dimensions occur :param mask: A mask to apply to the data, this should be either a scalar or the same shape as the data :return: A cube with well defined data. """ import iris from iris.aux_factory import HybridHeightFactory, HybridPressureFactory data_size = 1 DIM_NAMES = ['lat', 'lon', 'alt', 'pres', 'time', 'hybrid_ht', 'hybrid_pr'] dim_lengths = [lat_dim_length, lon_dim_length, alt_dim_length, pres_dim_length, time_dim_length, hybrid_ht_len, hybrid_pr_len] lon_range = lon_range or (-5., 5.) if dim_order is None: dim_order = list(DIM_NAMES) if any([True for d in dim_order if d not in DIM_NAMES]): raise ValueError("dim_order contains unrecognised name") for idx, dim in enumerate(DIM_NAMES): if dim_lengths[idx] == 0 and dim in dim_order: del dim_order[dim_order.index(dim)] coord_map = {} for idx, dim in enumerate(dim_order): coord_map[dim] = dim_order.index(dim) coord_list = [None] * len(coord_map) if lat_dim_length: coord_list[coord_map['lat']] = (DimCoord(np.linspace(-10., 10., lat_dim_length) + horizontal_offset, standard_name='latitude', units='degrees', var_name='lat'), coord_map['lat']) data_size *= lat_dim_length if lon_dim_length: coord_list[coord_map['lon']] = ( DimCoord(np.linspace(lon_range[0], lon_range[1], lon_dim_length) + horizontal_offset, standard_name='longitude', units='degrees', var_name='lon'), coord_map['lon']) data_size *= lon_dim_length if alt_dim_length: coord_list[coord_map['alt']] = (DimCoord(np.linspace(0., 7., alt_dim_length) + altitude_offset, standard_name='altitude', units='metres', var_name='alt'), coord_map['alt']) data_size *= alt_dim_length if pres_dim_length: coord_list[coord_map['pres']] = (DimCoord(np.linspace(0., 7., pres_dim_length) + pressure_offset, standard_name='air_pressure', units='hPa', var_name='pres'), coord_map['pres']) data_size *= pres_dim_length if time_dim_length: t0 = datetime.datetime(1984, 8, 27) times = np.array([t0 + datetime.timedelta(days=d + time_offset) for d in range(time_dim_length)]) time_nums = convert_datetime_to_std_time(times) time_bounds = None if time_dim_length == 1: time_bounds = convert_datetime_to_std_time(np.array([times[0] - datetime.timedelta(days=0.5), times[0] + datetime.timedelta(days=0.5)])) coord_list[coord_map['time']] = (DimCoord(time_nums, standard_name='time', units='days since 1600-01-01 00:00:00', var_name='time', bounds=time_bounds), coord_map['time']) data_size *= time_dim_length if hybrid_ht_len: coord_list[coord_map['hybrid_ht']] = (DimCoord(np.arange(hybrid_ht_len, dtype='i8') + 10, "model_level_number", units="1"), coord_map['hybrid_ht']) data_size *= hybrid_ht_len if hybrid_pr_len: coord_list[coord_map['hybrid_pr']] = (DimCoord(np.arange(hybrid_pr_len, dtype='i8'), "atmosphere_hybrid_sigma_pressure_coordinate", units="1"), coord_map['hybrid_pr']) data_size *= hybrid_pr_len data = np.reshape(np.arange(data_size) + data_offset + 1., tuple(len(i[0].points) for i in coord_list)) if mask: data = np.ma.asarray(data) data.mask = mask return_cube = Cube(data, dim_coords_and_dims=coord_list, var_name='rain', standard_name='rainfall_rate', long_name="TOTAL RAINFALL RATE: LS+CONV KG/M2/S", units="kg m-2 s-1") if hybrid_ht_len: return_cube.add_aux_coord(iris.coords.AuxCoord(np.arange(hybrid_ht_len, dtype='i8') + 40, long_name="level_height", units="m", var_name='hybrid_ht'), coord_map['hybrid_ht']) return_cube.add_aux_coord(iris.coords.AuxCoord(np.arange(hybrid_ht_len, dtype='i8') + 50, long_name="sigma", units="1", var_name='sigma'), coord_map['hybrid_ht']) return_cube.add_aux_coord(iris.coords.AuxCoord( np.arange(lat_dim_length * lon_dim_length, dtype='i8').reshape(lat_dim_length, lon_dim_length) + 100, long_name="surface_altitude", units="m"), [coord_map['lat'], coord_map['lon']]) return_cube.add_aux_factory(HybridHeightFactory( delta=return_cube.coord("level_height"), sigma=return_cube.coord("sigma"), orography=return_cube.coord("surface_altitude"))) elif hybrid_pr_len: return_cube.add_aux_coord(iris.coords.AuxCoord(np.arange(hybrid_pr_len, dtype='i8') + 40, long_name="hybrid A coefficient at layer midpoints", units="Pa", var_name='a'), coord_map['hybrid_pr']) return_cube.add_aux_coord(iris.coords.AuxCoord(np.arange(hybrid_pr_len, dtype='f8') + 50, long_name="hybrid B coefficient at layer midpoints", units="1", var_name='b'), coord_map['hybrid_pr']) return_cube.add_aux_coord( iris.coords.AuxCoord(np.arange(lat_dim_length * lon_dim_length * time_dim_length, dtype='i8') .reshape(lat_dim_length, lon_dim_length, time_dim_length) * 100000 + surf_pres_offset, "surface_air_pressure", units="Pa"), [coord_map['lat'], coord_map['lon'], coord_map['time']]) if geopotential_height: return_cube.add_aux_coord(iris.coords.AuxCoord( np.arange(lat_dim_length * lon_dim_length * time_dim_length * hybrid_pr_len, dtype='i8') .reshape(lat_dim_length, lon_dim_length, time_dim_length, hybrid_pr_len) + 10, "altitude", long_name="Geopotential height at layer midpoints", units="meter"), [coord_map['lat'], coord_map['lon'], coord_map['time'], coord_map['hybrid_pr']]) return_cube.add_aux_factory(HybridPressureFactory( delta=return_cube.coord("hybrid A coefficient at layer midpoints"), sigma=return_cube.coord("hybrid B coefficient at layer midpoints"), surface_air_pressure=return_cube.coord("surface_air_pressure"))) for coord in return_cube.coords(dim_coords=True): if coord.bounds is None: coord.guess_bounds() return return_cube