def build_cube(data, spherical=False): """ Create a cube suitable for testing. """ cube = iris.cube.Cube(data, standard_name="x_wind", units="km/h") nx = data.shape[-1] ny = data.shape[-2] nz = data.shape[-3] if data.ndim > 2 else None dimx = data.ndim - 1 dimy = data.ndim - 2 dimz = data.ndim - 3 if data.ndim > 2 else None if spherical: hcs = iris.coord_systems.LatLonCS( iris.coord_systems.SpheroidDatum(label="Tiny Earth", semi_major_axis=6321, flattening=0.0, units="m"), iris.coord_systems.PrimeMeridian(), iris.coord_systems.GeoPosition(90, 0), "reference_longitude?") cube.add_dim_coord(DimCoord(numpy.arange(-180, 180, 360./nx, dtype=numpy.float32), 'longitude', units='degrees', coord_system=hcs, circular=True), dimx) cube.add_dim_coord(DimCoord(numpy.arange(-90, 90, 180./ny, dtype=numpy.float32), 'latitude', units='degrees',coord_system=hcs), dimy) else: hcs = iris.coord_systems.HorizontalCS("Cartesian Datum?") cube.add_dim_coord(DimCoord(numpy.arange(nx, dtype=numpy.float32) * 2.21 + 2, 'projection_x_coordinate', units='meters', coord_system=hcs), dimx) cube.add_dim_coord(DimCoord(numpy.arange(ny, dtype=numpy.float32) * 25 -50, 'projection_y_coordinate', units='meters', coord_system=hcs), dimy) if nz is None: cube.add_aux_coord(DimCoord(numpy.array([10], dtype=numpy.float32), long_name='z', units='meters', attributes={"positive":"up"})) else: cube.add_dim_coord(DimCoord(numpy.arange(nz, dtype=numpy.float32) * 2, long_name='z', units='meters', attributes={"positive":"up"}), dimz) return cube
def test_simple_intersect(self): cube = iris.cube.Cube(np.array([[1,2,3,4,5], [2,3,4,5,6], [3,4,5,6,7], [4,5,6,7,8], [5,6,7,8,9]], dtype=np.int32)) lonlat_cs = iris.coord_systems.RotatedGeogCS(10, 20) cube.add_dim_coord(iris.coords.DimCoord(np.arange(5, dtype=np.float32) * 90 - 180, 'longitude', units='degrees', coord_system=lonlat_cs), 1) cube.add_dim_coord(iris.coords.DimCoord(np.arange(5, dtype=np.float32) * 45 - 90, 'latitude', units='degrees', coord_system=lonlat_cs), 0) cube.add_aux_coord(iris.coords.DimCoord(points=np.int32(11), long_name='pressure', units='Pa')) cube.rename("temperature") cube.units = "K" cube2 = iris.cube.Cube(np.array([[1,2,3,4,5], [2,3,4,5,6], [3,4,5,6,7], [4,5,6,7,8], [5,6,7,8,50]], dtype=np.int32)) lonlat_cs = iris.coord_systems.RotatedGeogCS(10, 20) cube2.add_dim_coord(iris.coords.DimCoord(np.arange(5, dtype=np.float32) * 90, 'longitude', units='degrees', coord_system=lonlat_cs), 1) cube2.add_dim_coord(iris.coords.DimCoord(np.arange(5, dtype=np.float32) * 45 - 90, 'latitude', units='degrees', coord_system=lonlat_cs), 0) cube2.add_aux_coord(iris.coords.DimCoord(points=np.int32(11), long_name='pressure', units='Pa')) cube2.rename("") r = iris.analysis.maths.intersection_of_cubes(cube, cube2) self.assertCML(r, ('cdm', 'test_simple_cube_intersection.cml'))
def build_cube(data, spherical=False): """ Create a cube suitable for testing. """ cube = iris.cube.Cube(data, standard_name="x_wind", units="km/h") nx = data.shape[-1] ny = data.shape[-2] nz = data.shape[-3] if data.ndim > 2 else None dimx = data.ndim - 1 dimy = data.ndim - 2 dimz = data.ndim - 3 if data.ndim > 2 else None if spherical: hcs = iris.coord_systems.GeogCS(6321) cube.add_dim_coord(DimCoord(np.arange(-180, 180, 360./nx, dtype=np.float32), 'longitude', units='degrees', coord_system=hcs, circular=True), dimx) cube.add_dim_coord(DimCoord(np.arange(-90, 90, 180./ny, dtype=np.float32), 'latitude', units='degrees',coord_system=hcs), dimy) else: cube.add_dim_coord(DimCoord(np.arange(nx, dtype=np.float32) * 2.21 + 2, 'projection_x_coordinate', units='meters'), dimx) cube.add_dim_coord(DimCoord(np.arange(ny, dtype=np.float32) * 25 -50, 'projection_y_coordinate', units='meters'), dimy) if nz is None: cube.add_aux_coord(DimCoord(np.array([10], dtype=np.float32), long_name='z', units='meters', attributes={"positive":"up"})) else: cube.add_dim_coord(DimCoord(np.arange(nz, dtype=np.float32) * 2, long_name='z', units='meters', attributes={"positive":"up"}), dimz) return cube
def setUp(self): # XXX Comes from test_aggregated_by cube = iris.cube.Cube(np.array([[6, 10, 12, 18], [8, 12, 14, 20], [18, 12, 10, 6]]), long_name='temperature', units='kelvin') cube.add_dim_coord(iris.coords.DimCoord(np.array([0, 5, 10], dtype=np.float64), 'latitude', units='degrees'), 0) cube.add_dim_coord(iris.coords.DimCoord(np.array([0, 2, 4, 6], dtype=np.float64), 'longitude', units='degrees'), 1) self.cube = cube
def setUp(self): data = np.array([[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7], [4, 5, 6, 7, 9]], dtype=np.float32) cube = iris.cube.Cube(data, standard_name="x_wind", units="km/h") self.lonlat_cs = iris.coord_systems.GeogCS(6371229) cube.add_dim_coord( DimCoord( np.arange(4, dtype=np.float32) * 90 - 180, "longitude", units="degrees", circular=True, coord_system=self.lonlat_cs, ), 0, ) cube.add_dim_coord( DimCoord( np.arange(5, dtype=np.float32) * 45 - 90, "latitude", units="degrees", coord_system=self.lonlat_cs ), 1, ) cube.add_aux_coord(DimCoord(np.arange(4, dtype=np.float32), long_name="x", units="count", circular=True), 0) cube.add_aux_coord(DimCoord(np.arange(5, dtype=np.float32), long_name="y", units="count"), 1) self.cube = cube
def setUp(self): data = ma.array([[1, 2], [4, 5]], dtype=np.float32, mask=[[False, True], [False, True]]) cube = iris.cube.Cube(data, long_name="test_data", units="1") lat_coord = iris.coords.DimCoord(np.array([1, 2], dtype=np.float32), long_name="lat", units="1") lon_coord = iris.coords.DimCoord(np.array([3, 4], dtype=np.float32), long_name="lon", units="1") cube.add_dim_coord(lat_coord, 0) cube.add_dim_coord(lon_coord, 1) self.cube = cube
def setUp(self): cube = stock.simple_3d_w_multidim_coords() cube.add_aux_coord(iris.coords.DimCoord(range(2), 'height'), 0) cube.add_dim_coord(iris.coords.DimCoord(range(3), 'latitude'), 1) cube.add_dim_coord(iris.coords.DimCoord(range(4), 'longitude'), 2) self.data = np.arange(24).reshape(2, 3, 4).astype(np.float32) cube.data = self.data self.cube = cube
def _lat_lon_cube_no_time(self): """Returns a cube with a latitude and longitude suitable for testing saving to PP/NetCDF etc.""" cube = iris.cube.Cube(np.arange(12, dtype=np.int32).reshape((3, 4))) cs = iris.coord_systems.GeogCS(6371229) cube.add_dim_coord(iris.coords.DimCoord(np.arange(4) * 90 + -180, 'longitude', units='degrees', coord_system=cs), 1) cube.add_dim_coord(iris.coords.DimCoord(np.arange(3) * 45 + -90, 'latitude', units='degrees', coord_system=cs), 0) return cube
def _lat_lon_cube_no_time(self): """Returns a cube with a latitude and longitude suitable for testing saving to PP/NetCDF etc.""" cube = iris.cube.Cube(numpy.arange(12, dtype=numpy.int32).reshape((3, 4))) cs = iris.coord_systems.LatLonCS(iris.coord_systems.SpheroidDatum(), 'pm', iris.coord_systems.GeoPosition(90, 0), 0) cube.add_dim_coord(iris.coords.DimCoord(numpy.arange(4) * 90 + -180, 'longitude', units='degrees', coord_system=cs), 1) cube.add_dim_coord(iris.coords.DimCoord(numpy.arange(3) * 45 + -90, 'latitude', units='degrees', coord_system=cs), 0) return cube
def setUp(self): data = numpy.arange(2500, dtype=numpy.float32).reshape(50, 50) cube = iris.cube.Cube(data, standard_name="x_wind", units="km/h") self.lonlat_cs = iris.coord_systems.LatLonCS(iris.coord_systems.SpheroidDatum(), iris.coord_systems.PrimeMeridian(), iris.coord_systems.GeoPosition(90, 0), "reference_longitude?") cube.add_dim_coord(DimCoord(numpy.arange(50, dtype=numpy.float32) * 4.5 -180, 'longitude', units='degrees', coord_system=self.lonlat_cs), 0) cube.add_dim_coord(DimCoord(numpy.arange(50, dtype=numpy.float32) * 4.5 -90, 'latitude', units='degrees', coord_system=self.lonlat_cs), 1) self.cube = cube
def interpolator(self): data = np.arange(12).reshape(4, 3) cube = iris.cube.Cube(data) time_coord = iris.coords.DimCoord(range(0, 48, 12), 'time', units='hours since epoch') height_coord = iris.coords.DimCoord(range(3), 'altitude', units='m') cube.add_dim_coord(time_coord, 0) cube.add_dim_coord(height_coord, 1) return LinearInterpolator(cube, ['time'])
def interpolator(self, method=LINEAR): data = np.arange(12).reshape(4, 3) cube = iris.cube.Cube(data) time_coord = iris.coords.DimCoord(np.arange(0.0, 48.0, 12.0), 'time', units='hours since epoch') height_coord = iris.coords.DimCoord(range(3), 'altitude', units='m') cube.add_dim_coord(time_coord, 0) cube.add_dim_coord(height_coord, 1) return RectilinearInterpolator(cube, ['time'], method, EXTRAPOLATE)
def build_lazy_cube(self, points, bounds=None, nx=4): data = np.arange(len(points) * nx).reshape(len(points), nx) data = biggus.NumpyArrayAdapter(data) cube = iris.cube.Cube(data, standard_name='air_temperature', units='K') lat = iris.coords.DimCoord(points, 'latitude', bounds=bounds) lon = iris.coords.DimCoord(range(nx), 'longitude') cube.add_dim_coord(lat, 0) cube.add_dim_coord(lon, 1) return cube
def _target_grid_cube(self): if self._target_grid_cube_cache is None: x, y = self._target_grid data = np.empty((y.points.size, x.points.size)) cube = iris.cube.Cube(data) cube.add_dim_coord(y, 0) cube.add_dim_coord(x, 1) self._target_grid_cube_cache = cube return self._target_grid_cube_cache
def setUp(self): data = np.arange(2500, dtype=np.float32).reshape(50, 50) cube = iris.cube.Cube(data, standard_name="x_wind", units="km/h") self.lonlat_cs = iris.coord_systems.GeogCS(6371229) cube.add_dim_coord(DimCoord(np.arange(50, dtype=np.float32) * 4.5 -180, 'longitude', units='degrees', coord_system=self.lonlat_cs), 0) cube.add_dim_coord(DimCoord(np.arange(50, dtype=np.float32) * 4.5 -90, 'latitude', units='degrees', coord_system=self.lonlat_cs), 1) self.cube = cube
def _make_cube(self, points, bounds=None): nx = 4 data = np.arange(len(points) * nx).reshape(len(points), nx) cube = iris.cube.Cube(data, standard_name='air_temperature', units='K') lat = iris.coords.DimCoord(points, 'latitude', bounds=bounds) lon = iris.coords.DimCoord(range(nx), 'longitude') cube.add_dim_coord(lat, 0) cube.add_dim_coord(lon, 1) return cube
def _make_cube(self, a, b, c, data=0): cube_data = numpy.empty((4, 5), dtype=numpy.float32) cube_data[:] = data cube = iris.cube.Cube(cube_data) cube.add_dim_coord(DimCoord(numpy.array([0, 1, 2, 3, 4], dtype=numpy.int32), long_name='x', units='1'), 1) cube.add_dim_coord(DimCoord(numpy.array([0, 1, 2, 3], dtype=numpy.int32), long_name='y', units='1'), 0) cube.add_aux_coord(DimCoord(numpy.array([a], dtype=numpy.int32), standard_name='forecast_period', units='1')) cube.add_aux_coord(DimCoord(numpy.array([b], dtype=numpy.int32), standard_name='forecast_reference_time', units='1')) cube.add_aux_coord(DimCoord(numpy.array([c], dtype=numpy.int32), standard_name='time', units='1')) return cube
def test_fully_wrapped_not_circular(self): cube = stock.lat_lon_cube() new_long = cube.coord('longitude').copy( cube.coord('longitude').points + 710) cube.remove_coord('longitude') cube.add_dim_coord(new_long, 1) interpolator = LinearInterpolator(cube, ['longitude']) res = interpolator([-10]) self.assertArrayEqual(res.data, cube[:, 1].data)
def setUp(self): data = np.array( [[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7], [4, 5, 6, 7, 8], [5, 6, 7, 8, 10]], dtype=np.float32 ) cube = iris.cube.Cube(data, standard_name="x_wind", units="km/h") cube.add_dim_coord(DimCoord(np.arange(5, dtype=np.float32), long_name="x", units="count"), 0) cube.add_dim_coord(DimCoord(np.arange(5, dtype=np.float32), long_name="y", units="count"), 1) self.cube = cube
def _make_cube(self, a, b, c, data=0): cube_data = np.empty((4, 5), dtype=np.float32) cube_data[:] = data cube = iris.cube.Cube(cube_data) cube.add_dim_coord(DimCoord(np.array([0, 1, 2, 3, 4], dtype=np.int32), long_name="x", units="1"), 1) cube.add_dim_coord(DimCoord(np.array([0, 1, 2, 3], dtype=np.int32), long_name="y", units="1"), 0) cube.add_aux_coord(DimCoord(np.array([a], dtype=np.int32), standard_name="forecast_period", units="1")) cube.add_aux_coord(DimCoord(np.array([b], dtype=np.int32), standard_name="forecast_reference_time", units="1")) cube.add_aux_coord(DimCoord(np.array([c], dtype=np.int32), standard_name="time", units="1")) return cube
def _make_cube(self, a, b, c, data): cube_data = np.empty((4, 5), dtype=np.float32) cube_data[:] = data cube = iris.cube.Cube(cube_data) cube.add_dim_coord(DimCoord(np.array([0, 1, 2, 3, 4], dtype=np.int32), long_name="x", units="1"), 1) cube.add_dim_coord(DimCoord(np.array([0, 1, 2, 3], dtype=np.int32), long_name="y", units="1"), 0) cube.add_aux_coord(DimCoord(np.array([a], dtype=np.int32), long_name="a", units="1")) cube.add_aux_coord(DimCoord(np.array([b], dtype=np.int32), long_name="b", units="1")) cube.add_aux_coord(DimCoord(np.array([c], dtype=np.int32), long_name="c", units="1")) return cube
def _make_cube(self, a, b, c, data): cube_data = np.empty((4, 5), dtype=np.float32) cube_data[:] = data cube = iris.cube.Cube(cube_data) cube.add_dim_coord(DimCoord(np.array([0, 1, 2, 3, 4], dtype=np.int32), long_name='x', units='1'), 1) cube.add_dim_coord(DimCoord(np.array([0, 1, 2, 3], dtype=np.int32), long_name='y', units='1'), 0) cube.add_aux_coord(DimCoord(np.array([a], dtype=np.int32), long_name='a', units='1')) cube.add_aux_coord(DimCoord(np.array([b], dtype=np.int32), long_name='b', units='1')) cube.add_aux_coord(DimCoord(np.array([c], dtype=np.int32), long_name='c', units='1')) return cube
def test_cosine_latitude_weights_range(self): # check the range of returned values, needs a cube that spans the full # latitude range lat_coord = iris.coords.DimCoord( np.linspace(-90, 90, 73), standard_name="latitude", units=iris.unit.Unit("degrees_north") ) cube = iris.cube.Cube(np.ones([73], dtype=np.float64), long_name="test_cube", units="1") cube.add_dim_coord(lat_coord, 0) weights = iris.analysis.cartography.cosine_latitude_weights(cube) self.assertTrue(weights.max() <= 1) self.assertTrue(weights.min() >= 0)
def setUp(self): src_cube = iris.tests.stock.global_pp() # Make a cube that can't be located on the globe. cube = iris.cube.Cube(src_cube.data) cube.add_dim_coord(iris.coords.DimCoord(np.arange(96, dtype=np.float32) * 100, long_name='x', units='m'), 1) cube.add_dim_coord(iris.coords.DimCoord(np.arange(73, dtype=np.float32) * 100, long_name='y', units='m'), 0) cube.standard_name = 'air_temperature' cube.units = 'K' cube.assert_valid() self.cube = cube
def _make_cube(self, a, b, c, d, data=0): cube_data = np.empty((4, 5), dtype=np.float32) cube_data[:] = data cube = iris.cube.Cube(cube_data) cube.add_dim_coord(DimCoord(np.array([0, 1, 2, 3, 4], dtype=np.int32), long_name="x", units="1"), 1) cube.add_dim_coord(DimCoord(np.array([0, 1, 2, 3], dtype=np.int32), long_name="y", units="1"), 0) for name, value in zip(["a", "b", "c", "d"], [a, b, c, d]): dtype = np.str if isinstance(value, six.string_types) else np.float32 cube.add_aux_coord(AuxCoord(np.array([value], dtype=dtype), long_name=name, units="1")) return cube
def simple_1d_time_cubes(self, reftimes, coords_points): cubes = [] data_points = [273, 275, 278, 277, 274] for reftime, coord_points in zip(reftimes, coords_points): cube = iris.cube.Cube(np.array(data_points, dtype=np.float32), standard_name="air_temperature", units="K") unit = iris.unit.Unit(reftime, calendar="gregorian") coord = iris.coords.DimCoord( points=np.array(coord_points, dtype=np.float32), standard_name="time", units=unit ) cube.add_dim_coord(coord, 0) cubes.append(cube) return cubes
def dummy_field(shape=(1400, 1000)): ny, nx = shape data = np.arange(nx * ny).reshape(shape) cube = iris.cube.Cube(data, long_name='test_values') lons = np.linspace(-180.0, 180.0, nx, endpoint=False) lats = np.linspace(-90.0, 90.0, ny, endpoint=True) co_x = iris.coords.DimCoord(lons, standard_name='longitude', units='degrees', coord_system=cs_pc) co_y = iris.coords.DimCoord(lats, standard_name='latitude', units='degrees', coord_system=cs_pc) cube.add_dim_coord(co_y, 0) cube.add_dim_coord(co_x, 1) return cube
def _expected_cube(self, data): cube = iris.cube.Cube(data) cube.metadata = copy.deepcopy(self.src) grid_x = self.grid.coord('longitude') grid_y = self.grid.coord('latitude') cube.add_dim_coord(grid_x.copy(), self.grid.coord_dims(grid_x)) cube.add_dim_coord(grid_y.copy(), self.grid.coord_dims(grid_y)) src_x = self.src.coord('longitude') src_y = self.src.coord('latitude') for coord in self.src.aux_coords: if coord is not src_x and coord is not src_y: if not self.src.coord_dims(coord): cube.add_aux_coord(coord) return cube
def test_weighted_mean_little(self): data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.float32) weights = np.array([[9, 8, 7], [6, 5, 4], [3, 2, 1]], dtype=np.float32) cube = iris.cube.Cube(data, long_name="test_data", units="1") hcs = iris.coord_systems.GeogCS(6371229) lat_coord = iris.coords.DimCoord(np.array([1, 2, 3], dtype=np.float32), long_name="lat", units="1", coord_system=hcs) lon_coord = iris.coords.DimCoord(np.array([1, 2, 3], dtype=np.float32), long_name="lon", units="1", coord_system=hcs) cube.add_dim_coord(lat_coord, 0) cube.add_dim_coord(lon_coord, 1) cube.add_aux_coord(iris.coords.AuxCoord(np.arange(3, dtype=np.float32), long_name="dummy", units=1), 1) self.assertCML(cube, ('analysis', 'weighted_mean_source.cml')) a = cube.collapsed('lat', iris.analysis.MEAN, weights=weights) # np.ma.average doesn't apply type promotion rules in some versions, # and instead makes the result type float64. To ignore that case we # fix up the dtype here if it is promotable from float32. We still want # to catch cases where there is a loss of precision however. if a.dtype > np.float32: cast_data = a.data.astype(np.float32) a.replace(cast_data, fill_value=a.fill_value) self.assertCMLApproxData(a, ('analysis', 'weighted_mean_lat.cml')) b = cube.collapsed(lon_coord, iris.analysis.MEAN, weights=weights) if b.dtype > np.float32: cast_data = b.data.astype(np.float32) b.replace(cast_data, fill_value=b.fill_value) b.data = np.asarray(b.data) self.assertCMLApproxData(b, ('analysis', 'weighted_mean_lon.cml')) self.assertEqual(b.coord('dummy').shape, (1, )) # test collapsing multiple coordinates (and the fact that one of the coordinates isn't the same coordinate instance as on the cube) c = cube.collapsed([lat_coord[:], lon_coord], iris.analysis.MEAN, weights=weights) if c.dtype > np.float32: cast_data = c.data.astype(np.float32) c.replace(cast_data, fill_value=c.fill_value) self.assertCMLApproxData(c, ('analysis', 'weighted_mean_latlon.cml')) self.assertEqual(c.coord('dummy').shape, (1, )) # Check new coord bounds - made from points self.assertArrayEqual(c.coord('lat').bounds, [[1, 3]]) # Check new coord bounds - made from bounds cube.coord('lat').bounds = [[0.5, 1.5], [1.5, 2.5], [2.5, 3.5]] c = cube.collapsed(['lat', 'lon'], iris.analysis.MEAN, weights=weights) self.assertArrayEqual(c.coord('lat').bounds, [[0.5, 3.5]]) cube.coord('lat').bounds = None # Check there was no residual change self.assertCML(cube, ('analysis', 'weighted_mean_source.cml'))
def _make_cube(self, a, b, data=0, a_dim=False, b_dim=False): cube_data = np.empty((4, 5), dtype=np.float32) cube_data[:] = data cube = iris.cube.Cube(cube_data) cube.add_dim_coord(DimCoord(np.array([0, 1, 2, 3, 4], dtype=np.int32), long_name="x", units="1"), 1) cube.add_dim_coord(DimCoord(np.array([0, 1, 2, 3], dtype=np.int32), long_name="y", units="1"), 0) for name, value, dim in zip(["a", "b"], [a, b], [a_dim, b_dim]): dtype = np.str if isinstance(value, six.string_types) else np.float32 ctype = DimCoord if dim else AuxCoord coord = ctype(np.array([value], dtype=dtype), long_name=name, units="1") cube.add_aux_coord(coord) return cube
def _makecube(self, y, cm=False, av=False): cube = iris.cube.Cube([0, 0]) cube.add_dim_coord(iris.coords.DimCoord([0, 1], long_name="x"), 0) cube.add_aux_coord(iris.coords.DimCoord(y, long_name="y")) if cm: cube.add_cell_measure( iris.coords.CellMeasure([1, 1], long_name="foo"), 0, ) if av: cube.add_ancillary_variable( iris.coords.AncillaryVariable([1, 1], long_name="bar"), 0, ) return cube
def _make_cube(self, a, b, c, d, data=0): cube_data = np.empty((4, 5), dtype=np.float32) cube_data[:] = data cube = iris.cube.Cube(cube_data) cube.add_dim_coord(DimCoord(np.array([0, 1, 2, 3, 4], dtype=np.int32), long_name='x', units='1'), 1) cube.add_dim_coord(DimCoord(np.array([0, 1, 2, 3], dtype=np.int32), long_name='y', units='1'), 0) for name, value in zip(['a', 'b', 'c', 'd'], [a, b, c, d]): dtype = np.str if isinstance(value, six.string_types) else np.float32 cube.add_aux_coord(AuxCoord(np.array([value], dtype=dtype), long_name=name, units='1')) return cube
def test_delta_coord_lookup(self): cube = iris.cube.Cube(np.arange(10), standard_name='air_temperature') # Add a coordinate with a lot of metadata. coord = iris.coords.DimCoord(np.arange(10), long_name='projection_x_coordinate', var_name='foo', attributes={'source': 'testing'}, units='m', coord_system=iris.coord_systems.OSGB()) cube.add_dim_coord(coord, 0) delta = iris.analysis.calculus.cube_delta(cube, 'projection_x_coordinate') delta_coord = delta.coord('projection_x_coordinate') self.assertEqual(delta_coord, delta.coord(coord)) self.assertEqual(coord, cube.coord(delta_coord))
def simple_1d_time_cubes(self, reftimes, coords_points): cubes = [] data_points = [273, 275, 278, 277, 274] for reftime, coord_points in zip(reftimes, coords_points): cube = iris.cube.Cube(np.array(data_points, dtype=np.float32), standard_name='air_temperature', units='K') unit = cf_units.Unit(reftime, calendar='gregorian') coord = iris.coords.DimCoord(points=np.array(coord_points, dtype=np.float32), standard_name='time', units=unit) cube.add_dim_coord(coord, 0) cubes.append(cube) return cubes
def setUp(self): data = np.array( [[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7], [4, 5, 6, 7, 9]], dtype=np.float32) cube = iris.cube.Cube(data, standard_name="x_wind", units="km/h") self.lonlat_cs = iris.coord_systems.GeogCS(6371229) cube.add_dim_coord(DimCoord(np.arange(4, dtype=np.float32) * 90 -180, 'longitude', units='degrees', circular=True, coord_system=self.lonlat_cs), 0) cube.add_dim_coord(DimCoord(np.arange(5, dtype=np.float32) * 45 -90, 'latitude', units='degrees', coord_system=self.lonlat_cs), 1) cube.add_aux_coord(DimCoord(np.arange(4, dtype=np.float32), long_name='x', units='count', circular=True), 0) cube.add_aux_coord(DimCoord(np.arange(5, dtype=np.float32), long_name='y', units='count'), 1) self.cube = cube
def test_simple_intersect(self): cube = iris.cube.Cube( np.array([[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7], [4, 5, 6, 7, 8], [5, 6, 7, 8, 9]], dtype=np.int32)) lonlat_cs = iris.coord_systems.RotatedGeogCS(10, 20) cube.add_dim_coord( iris.coords.DimCoord(np.arange(5, dtype=np.float32) * 90 - 180, 'longitude', units='degrees', coord_system=lonlat_cs), 1) cube.add_dim_coord( iris.coords.DimCoord(np.arange(5, dtype=np.float32) * 45 - 90, 'latitude', units='degrees', coord_system=lonlat_cs), 0) cube.add_aux_coord( iris.coords.DimCoord(points=np.int32(11), long_name='pressure', units='Pa')) cube.rename("temperature") cube.units = "K" cube2 = iris.cube.Cube( np.array([[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7], [4, 5, 6, 7, 8], [5, 6, 7, 8, 50]], dtype=np.int32)) lonlat_cs = iris.coord_systems.RotatedGeogCS(10, 20) cube2.add_dim_coord( iris.coords.DimCoord(np.arange(5, dtype=np.float32) * 90, 'longitude', units='degrees', coord_system=lonlat_cs), 1) cube2.add_dim_coord( iris.coords.DimCoord(np.arange(5, dtype=np.float32) * 45 - 90, 'latitude', units='degrees', coord_system=lonlat_cs), 0) cube2.add_aux_coord( iris.coords.DimCoord(points=np.int32(11), long_name='pressure', units='Pa')) cube2.rename("") r = iris.analysis.maths.intersection_of_cubes(cube, cube2) self.assertCML(r, ('cdm', 'test_simple_cube_intersection.cml'))
def test_weighted_mean_little(self): data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.float32) weights = np.array([[9, 8, 7], [6, 5, 4], [3, 2, 1]], dtype=np.float32) cube = iris.cube.Cube(data, long_name="test_data", units="1") hcs = iris.coord_systems.GeogCS(6371229) lat_coord = iris.coords.DimCoord(np.array([1, 2, 3], dtype=np.float32), long_name="lat", units="1", coord_system=hcs) lon_coord = iris.coords.DimCoord(np.array([1, 2, 3], dtype=np.float32), long_name="lon", units="1", coord_system=hcs) cube.add_dim_coord(lat_coord, 0) cube.add_dim_coord(lon_coord, 1) cube.add_aux_coord( iris.coords.AuxCoord(np.arange(3, dtype=np.float32), long_name="dummy", units=1), 1) self.assertCML(cube, ('analysis', 'weighted_mean_source.cml')) a = cube.collapsed('lat', iris.analysis.MEAN, weights=weights) self.assertCMLApproxData(a, ('analysis', 'weighted_mean_lat.cml')) b = cube.collapsed(lon_coord, iris.analysis.MEAN, weights=weights) b.data = np.asarray(b.data) self.assertCMLApproxData(b, ('analysis', 'weighted_mean_lon.cml')) self.assertEqual(b.coord('dummy').shape, (1, )) # test collapsing multiple coordinates (and the fact that one of the coordinates isn't the same coordinate instance as on the cube) c = cube.collapsed([lat_coord[:], lon_coord], iris.analysis.MEAN, weights=weights) self.assertCMLApproxData(c, ('analysis', 'weighted_mean_latlon.cml')) self.assertEqual(c.coord('dummy').shape, (1, )) # Check new coord bounds - made from points self.assertArrayEqual(c.coord('lat').bounds, [[1, 3]]) # Check new coord bounds - made from bounds cube.coord('lat').bounds = [[0.5, 1.5], [1.5, 2.5], [2.5, 3.5]] c = cube.collapsed(['lat', 'lon'], iris.analysis.MEAN, weights=weights) self.assertArrayEqual(c.coord('lat').bounds, [[0.5, 3.5]]) cube.coord('lat').bounds = None # Check there was no residual change self.assertCML(cube, ('analysis', 'weighted_mean_source.cml'))
def setUp(self): data = np.array([[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7], [4, 5, 6, 7, 8], [5, 6, 7, 8, 10]], dtype=np.float32) cube = iris.cube.Cube(data, standard_name="x_wind", units="km/h") cube.add_dim_coord( DimCoord(np.arange(5, dtype=np.float32), long_name='x', units='count'), 0) cube.add_dim_coord( DimCoord(np.arange(5, dtype=np.float32), long_name='y', units='count'), 1) self.cube = cube
def _lat_lon_cube_no_time(self): """Returns a cube with a latitude and longitude suitable for testing saving to PP/NetCDF etc.""" cube = iris.cube.Cube(np.arange(12, dtype=np.int32).reshape((3, 4))) cs = iris.coord_systems.GeogCS(6371229) cube.add_dim_coord( iris.coords.DimCoord(np.arange(4) * 90 + -180, 'longitude', units='degrees', coord_system=cs), 1) cube.add_dim_coord( iris.coords.DimCoord(np.arange(3) * 45 + -90, 'latitude', units='degrees', coord_system=cs), 0) return cube
def setUp(self): # XXX Comes from test_aggregated_by cube = iris.cube.Cube(np.array([[6, 10, 12, 18], [8, 12, 14, 20], [18, 12, 10, 6]]), long_name='temperature', units='kelvin') cube.add_dim_coord( iris.coords.DimCoord(np.array([0, 5, 10], dtype=np.float64), 'latitude', units='degrees'), 0) cube.add_dim_coord( iris.coords.DimCoord(np.array([0, 2, 4, 6], dtype=np.float64), 'longitude', units='degrees'), 1) self.cube = cube
def test_delta_coord_lookup(self): cube = iris.cube.Cube(np.arange(10), standard_name="air_temperature") # Add a coordinate with a lot of metadata. coord = iris.coords.DimCoord( np.arange(10), long_name="projection_x_coordinate", var_name="foo", attributes={"source": "testing"}, units="m", coord_system=iris.coord_systems.OSGB(), ) cube.add_dim_coord(coord, 0) delta = iris.analysis.calculus.cube_delta(cube, "projection_x_coordinate") delta_coord = delta.coord("projection_x_coordinate") self.assertEqual(delta_coord, delta.coord(coord)) self.assertEqual(coord, cube.coord(delta_coord))
def setUp(self): data = np.arange(2500, dtype=np.float32).reshape(50, 50) cube = iris.cube.Cube(data, standard_name="x_wind", units="km/h") self.lonlat_cs = iris.coord_systems.GeogCS(6371229) cube.add_dim_coord( DimCoord(np.arange(50, dtype=np.float32) * 4.5 - 180, 'longitude', units='degrees', coord_system=self.lonlat_cs), 0) cube.add_dim_coord( DimCoord(np.arange(50, dtype=np.float32) * 4.5 - 90, 'latitude', units='degrees', coord_system=self.lonlat_cs), 1) self.cube = cube
def setUp(self): super().setUp() src_cube = iris.tests.stock.global_pp() # Make a cube that can't be located on the globe. cube = iris.cube.Cube(src_cube.data) cube.add_dim_coord( iris.coords.DimCoord(np.arange(96, dtype=np.float32) * 100, long_name='x', units='m'), 1) cube.add_dim_coord( iris.coords.DimCoord(np.arange(73, dtype=np.float32) * 100, long_name='y', units='m'), 0) cube.standard_name = 'air_temperature' cube.units = 'K' self.cube = cube
def _make_cube(self, a, b, data=0, a_dim=False, b_dim=False): cube_data = np.empty((4, 5), dtype=np.float32) cube_data[:] = data cube = iris.cube.Cube(cube_data) cube.add_dim_coord(DimCoord(np.array([0, 1, 2, 3, 4], dtype=np.int32), long_name='x', units='1'), 1) cube.add_dim_coord(DimCoord(np.array([0, 1, 2, 3], dtype=np.int32), long_name='y', units='1'), 0) for name, value, dim in zip(['a', 'b'], [a, b], [a_dim, b_dim]): dtype = np.str if isinstance(value, six.string_types) else np.float32 ctype = DimCoord if dim else AuxCoord coord = ctype(np.array([value], dtype=dtype), long_name=name, units='1') cube.add_aux_coord(coord) return cube
def create_cube(self): data = np.arange(4).reshape(2, 2) lat = iris.coords.DimCoord([0, 30], standard_name='latitude', units='degrees') lon = iris.coords.DimCoord([0, 15], standard_name='longitude', units='degrees') height = iris.coords.AuxCoord([1.5], standard_name='height', units='m') t_unit = cf_units.Unit('hours since 1970-01-01 00:00:00', calendar='gregorian') time = iris.coords.DimCoord([0, 6], standard_name='time', units=t_unit) cube = iris.cube.Cube(data, standard_name='air_temperature', units='K') cube.add_dim_coord(time, 0) cube.add_dim_coord(lat, 1) cube.add_aux_coord(lon, 1) cube.add_aux_coord(height) return cube
def _make_cube(self, a, b, c, data): cube_data = np.empty((4, 5), dtype=np.float32) cube_data[:] = data cube = iris.cube.Cube(cube_data) cube.add_dim_coord( DimCoord(np.array([0, 1, 2, 3, 4], dtype=np.int32), long_name='x', units='1'), 1) cube.add_dim_coord( DimCoord(np.array([0, 1, 2, 3], dtype=np.int32), long_name='y', units='1'), 0) cube.add_aux_coord( DimCoord(np.array([a], dtype=np.int32), long_name='a', units='1')) cube.add_aux_coord( DimCoord(np.array([b], dtype=np.int32), long_name='b', units='1')) cube.add_aux_coord( DimCoord(np.array([c], dtype=np.int32), long_name='c', units='1')) return cube
def create_cube(self): data = np.arange(4).reshape(2, 2) lat = iris.coords.DimCoord([0, 30], standard_name="latitude", units="degrees") lon = iris.coords.DimCoord([0, 15], standard_name="longitude", units="degrees") height = iris.coords.AuxCoord([1.5], standard_name="height", units="m") t_unit = cf_units.Unit("hours since 1970-01-01 00:00:00", calendar="gregorian") time = iris.coords.DimCoord([0, 6], standard_name="time", units=t_unit) cube = iris.cube.Cube(data, standard_name="air_temperature", units="K") cube.add_dim_coord(time, 0) cube.add_dim_coord(lat, 1) cube.add_aux_coord(lon, 1) cube.add_aux_coord(height) return cube
def setUp(self): data = np.arange(24, dtype=np.float32).reshape(2, 3, 4) cube = iris.cube.Cube(data, standard_name='air_temperature', units='K') # Time coord t_unit = iris.unit.Unit('hours since 1970-01-01 00:00:00', calendar='gregorian') t_coord = iris.coords.DimCoord(points=np.arange(2, dtype=np.float32), standard_name='time', units=t_unit) cube.add_dim_coord(t_coord, 0) # Lats and lons x_coord = iris.coords.DimCoord(points=np.arange(3, dtype=np.float32), standard_name='longitude', units='degrees') cube.add_dim_coord(x_coord, 1) y_coord = iris.coords.DimCoord(points=np.arange(4, dtype=np.float32), standard_name='latitude', units='degrees') cube.add_dim_coord(y_coord, 2) # Scalars cube.add_aux_coord(iris.coords.AuxCoord([0], "height", units="m")) # Aux Coords cube.add_aux_coord(iris.coords.AuxCoord(data, long_name='wibble', units='1'), data_dims=(0, 1, 2)) cube.add_aux_coord(iris.coords.AuxCoord([0, 1, 2], long_name='foo', units='1'), data_dims=(1, )) self.cube = cube
def _make_cube(self, a, b, c, data=0): cube_data = np.empty((4, 5), dtype=np.float32) cube_data[:] = data cube = iris.cube.Cube(cube_data) cube.add_dim_coord( DimCoord( np.array([0, 1, 2, 3, 4], dtype=np.int32), long_name="x", units="1", ), 1, ) cube.add_dim_coord( DimCoord( np.array([0, 1, 2, 3], dtype=np.int32), long_name="y", units="1", ), 0, ) cube.add_aux_coord( DimCoord( np.array([a], dtype=np.int32), standard_name="forecast_period", units="1", ) ) cube.add_aux_coord( DimCoord( np.array([b], dtype=np.int32), standard_name="forecast_reference_time", units="1", ) ) cube.add_aux_coord( DimCoord( np.array([c], dtype=np.int32), standard_name="time", units="1" ) ) return cube
def add_coord(self, cube): added = False # Try to add to dim_coords? if isinstance(self.coord, iris.coords.DimCoord) and self.dims: if len(self.dims) > 1: raise Exception("Only 1 dim allowed for a DimCoord") # Does the cube already have a coord for this dim? already_taken = False for coord, coord_dim in cube._dim_coords_and_dims: if coord_dim == self.dims[0]: already_taken = True break if not already_taken: cube.add_dim_coord(self.coord, self.dims[0]) added = True # If we didn't add it to dim_coords, add it to aux_coords. if not added: cube.add_aux_coord(self.coord, self.dims)
def create_cube(self): data = np.arange(4).reshape(2, 2) lat = iris.coords.DimCoord([0, 30], standard_name="latitude", units="degrees") volume = iris.coords.CellMeasure([0, 15], measure="volume", long_name="volume") area = iris.coords.CellMeasure([1.5], standard_name="height", units="m") t_unit = cf_units.Unit("hours since 1970-01-01 00:00:00", calendar="gregorian") time = iris.coords.DimCoord([0, 6], standard_name="time", units=t_unit) cube = iris.cube.Cube(data, standard_name="air_temperature", units="K") cube.add_dim_coord(time, 0) cube.add_dim_coord(lat, 1) cube.add_cell_measure(volume, 1) cube.add_cell_measure(area) return cube
def _make_cube( self, data, dtype=np.dtype("int32"), fill_value=None, mask=None, lazy=False, N=3, ): x = np.arange(N) y = np.arange(N) payload = self._make_data( data, dtype=dtype, fill_value=fill_value, mask=mask, lazy=lazy, N=N ) cube = iris.cube.Cube(payload) lat = DimCoord(y, standard_name="latitude", units="degrees") cube.add_dim_coord(lat, 0) lon = DimCoord(x, standard_name="longitude", units="degrees") cube.add_dim_coord(lon, 1) height = DimCoord(data, standard_name="height", units="m") cube.add_aux_coord(height) return cube
def _make_cube(self, data, dtype=np.dtype('int32'), fill_value=None, mask=None, lazy=False, N=3): x = np.arange(N) y = np.arange(N) payload = self._make_data(data, dtype=dtype, fill_value=fill_value, mask=mask, lazy=lazy, N=N) cube = iris.cube.Cube(payload, dtype=dtype, fill_value=fill_value) lat = DimCoord(y, standard_name='latitude', units='degrees') cube.add_dim_coord(lat, 0) lon = DimCoord(x, standard_name='longitude', units='degrees') cube.add_dim_coord(lon, 1) height = DimCoord(data, standard_name='height', units='m') cube.add_aux_coord(height) return cube
def setUp(self): data = np.arange(24, dtype=np.float32).reshape(2, 3, 4) cube = iris.cube.Cube(data, standard_name="air_temperature", units="K") # Time coord t_unit = cf_units.Unit("hours since 1970-01-01 00:00:00", calendar="gregorian") t_coord = iris.coords.DimCoord( points=np.arange(2, dtype=np.float32), standard_name="time", units=t_unit, ) cube.add_dim_coord(t_coord, 0) # Lats and lons x_coord = iris.coords.DimCoord( points=np.arange(3, dtype=np.float32), standard_name="longitude", units="degrees", ) cube.add_dim_coord(x_coord, 1) y_coord = iris.coords.DimCoord( points=np.arange(4, dtype=np.float32), standard_name="latitude", units="degrees", ) cube.add_dim_coord(y_coord, 2) # Scalars cube.add_aux_coord(iris.coords.AuxCoord([0], "height", units="m")) # Aux Coords cube.add_aux_coord( iris.coords.AuxCoord(data, long_name="wibble", units="1"), data_dims=(0, 1, 2), ) cube.add_aux_coord( iris.coords.AuxCoord([0, 1, 2], long_name="foo", units="1"), data_dims=(1, ), ) cube.add_cell_measure( iris.coords.CellMeasure([0, 1, 2], long_name="bar", units="1"), data_dims=(1, ), ) cube.add_ancillary_variable( iris.coords.AncillaryVariable([0, 1, 2], long_name="baz", units="1"), data_dims=(1, ), ) self.cube = cube
def load_NAMEIII_trajectory(filename): """ Load a NAME III trajectory file returning a generator of :class:`iris.cube.Cube` instances. Args: * filename (string): Name of file to load. Returns: A generator :class:`iris.cube.Cube` instances. """ time_unit = iris.unit.Unit('hours since epoch', calendar=iris.unit.CALENDAR_GREGORIAN) with open(filename, 'r') as infile: header = read_header(infile) # read the column headings for line in infile: if line.startswith(" "): break headings = [heading.strip() for heading in line.split(",")] # read the columns columns = [[] for i in range(len(headings))] for line in infile: values = [v.strip() for v in line.split(",")] for c, v in enumerate(values): if "UTC" in v: v = v.replace(":00 ", " ") # Strip out milliseconds. v = datetime.datetime.strptime(v, NAMEIII_DATETIME_FORMAT) else: try: v = float(v) except ValueError: pass columns[c].append(v) # Where's the Z column? z_column = None for i, heading in enumerate(headings): if heading.startswith("Z "): z_column = i break if z_column is None: raise iris.exceptions.TranslationError("Expected a Z column") # Every column up to Z becomes a coordinate. coords = [] for name, values in izip(headings[:z_column + 1], columns[:z_column + 1]): values = np.array(values) if np.all(np.array(values) == values[0]): values = [values[0]] standard_name = long_name = units = None if isinstance(values[0], datetime.datetime): values = time_unit.date2num(values) units = time_unit if name == "Time": name = "time" elif " (Lat-Long)" in name: if name.startswith("X"): name = "longitude" elif name.startswith("Y"): name = "latitude" units = "degrees" elif name == "Z (m asl)": name = "height" units = "m" try: coord = DimCoord(values, units=units) except ValueError: coord = AuxCoord(values, units=units) coord.rename(name) coords.append(coord) # Every numerical column after the Z becomes a cube. for name, values in izip(headings[z_column + 1:], columns[z_column + 1:]): try: float(values[0]) except ValueError: continue # units embedded in column heading? name, units = _split_name_and_units(name) cube = iris.cube.Cube(values, units=units) cube.rename(name) for coord in coords: dim = 0 if len(coord.points) > 1 else None if isinstance(coord, DimCoord) and coord.name() == "time": cube.add_dim_coord(coord.copy(), dim) else: cube.add_aux_coord(coord.copy(), dim) yield cube
def _generate_cubes(header, column_headings, coords, data_arrays, cell_methods=None): """ Yield :class:`iris.cube.Cube` instances given the headers, column headings, coords and data_arrays extracted from a NAME file. """ for i, data_array in enumerate(data_arrays): # Turn the dictionary of column headings with a list of header # information for each field into a dictionary of headings for # just this field. field_headings = {k: v[i] for k, v in column_headings.iteritems()} # Make a cube. cube = iris.cube.Cube(data_array) # Determine the name and units. name = '{} {}'.format(field_headings['Species'], field_headings['Quantity']) name = name.upper().replace(' ', '_') cube.rename(name) # Some units are not in SI units, are missing spaces or typed # in the wrong case. _parse_units returns units that are # recognised by Iris. cube.units = _parse_units(field_headings['Unit']) # Define and add the singular coordinates of the field (flight # level, time etc.) z_coord = _cf_height_from_name(field_headings['Z']) cube.add_aux_coord(z_coord) # Define the time unit and use it to serialise the datetime for # the time coordinate. time_unit = iris.unit.Unit('hours since epoch', calendar=iris.unit.CALENDAR_GREGORIAN) # Build time, latitude and longitude coordinates. for coord in coords: pts = coord.values coord_sys = None if coord.name == 'latitude' or coord.name == 'longitude': coord_units = 'degrees' coord_sys = iris.coord_systems.GeogCS(EARTH_RADIUS) if coord.name == 'time': coord_units = time_unit pts = time_unit.date2num(coord.values) if coord.dimension is not None: icoord = DimCoord(points=pts, standard_name=coord.name, units=coord_units, coord_system=coord_sys) if coord.name == 'time' and 'Av or Int period' in \ field_headings: dt = coord.values - \ field_headings['Av or Int period'] bnds = time_unit.date2num(np.vstack((dt, coord.values)).T) icoord.bounds = bnds else: icoord.guess_bounds() cube.add_dim_coord(icoord, coord.dimension) else: icoord = AuxCoord(points=pts[i], standard_name=coord.name, coord_system=coord_sys, units=coord_units) if coord.name == 'time' and 'Av or Int period' in \ field_headings: dt = coord.values - \ field_headings['Av or Int period'] bnds = time_unit.date2num(np.vstack((dt, coord.values)).T) icoord.bounds = bnds[i, :] cube.add_aux_coord(icoord) # Headings/column headings which are encoded elsewhere. headings = [ 'X', 'Y', 'Z', 'Time', 'Unit', 'Av or Int period', 'X grid origin', 'Y grid origin', 'X grid size', 'Y grid size', 'X grid resolution', 'Y grid resolution', ] # Add the Main Headings as attributes. for key, value in header.iteritems(): if value is not None and value != '' and \ key not in headings: cube.attributes[key] = value # Add the Column Headings as attributes for key, value in field_headings.iteritems(): if value is not None and value != '' and \ key not in headings: cube.attributes[key] = value if cell_methods is not None: cube.add_cell_method(cell_methods[i]) yield cube
def _make_cube_3d(x, y, z, data, aux=None, offset=0): """ A convenience test function that creates a custom 3D cube. Args: * x: A (start, stop, step) tuple for specifying the x-axis dimensional coordinate points. Bounds are automatically guessed. * y: A (start, stop, step) tuple for specifying the y-axis dimensional coordinate points. Bounds are automatically guessed. * z: A (start, stop, step) tuple for specifying the z-axis dimensional coordinate points. Bounds are automatically guessed. * data: The data payload for the cube. Kwargs: * aux: A CSV string specifying which points only auxiliary coordinates to create. Accepts either of 'x', 'y', 'z', 'xy', 'xz', 'yz', 'xyz'. * offset: Offset value to be added to non-1D auxiliary coordinate points. Returns: The newly created 3D :class:`iris.cube.Cube`. """ x_range = np.arange(*x, dtype=np.float32) y_range = np.arange(*y, dtype=np.float32) z_range = np.arange(*z, dtype=np.float32) x_size, y_size, z_size = len(x_range), len(y_range), len(z_range) cube_data = np.empty((x_size, y_size, z_size), dtype=np.float32) cube_data[:] = data cube = iris.cube.Cube(cube_data) coord = DimCoord(z_range, long_name="z", units="1") coord.guess_bounds() cube.add_dim_coord(coord, 0) coord = DimCoord(y_range, long_name="y", units="1") coord.guess_bounds() cube.add_dim_coord(coord, 1) coord = DimCoord(x_range, long_name="x", units="1") coord.guess_bounds() cube.add_dim_coord(coord, 2) if aux is not None: aux = aux.split(",") if "z" in aux: coord = AuxCoord(z_range * 10, long_name="z-aux", units="1") cube.add_aux_coord(coord, (0, )) if "y" in aux: coord = AuxCoord(y_range * 10, long_name="y-aux", units="1") cube.add_aux_coord(coord, (1, )) if "x" in aux: coord = AuxCoord(x_range * 10, long_name="x-aux", units="1") cube.add_aux_coord(coord, (2, )) if "xy" in aux: payload = np.arange(x_size * y_size, dtype=np.float32).reshape(y_size, x_size) coord = AuxCoord(payload + offset, long_name="xy-aux", units="1") cube.add_aux_coord(coord, (1, 2)) if "xz" in aux: payload = np.arange(x_size * z_size, dtype=np.float32).reshape(z_size, x_size) coord = AuxCoord(payload * 10 + offset, long_name="xz-aux", units="1") cube.add_aux_coord(coord, (0, 2)) if "yz" in aux: payload = np.arange(y_size * z_size, dtype=np.float32).reshape(z_size, y_size) coord = AuxCoord(payload * 100 + offset, long_name="yz-aux", units="1") cube.add_aux_coord(coord, (0, 1)) if "xyz" in aux: payload = np.arange(x_size * y_size * z_size, dtype=np.float32).reshape( z_size, y_size, x_size) coord = AuxCoord(payload * 1000 + offset, long_name="xyz-aux", units="1") cube.add_aux_coord(coord, (0, 1, 2)) return cube
def _make_cube(x, y, data, aux=None, cell_measure=None, ancil=None, offset=0, scalar=None): """ A convenience test function that creates a custom 2D cube. Args: * x: A (start, stop, step) tuple for specifying the x-axis dimensional coordinate points. Bounds are automatically guessed. * y: A (start, stop, step) tuple for specifying the y-axis dimensional coordinate points. Bounds are automatically guessed. * data: The data payload for the cube. Kwargs: * aux: A CSV string specifying which points only auxiliary coordinates to create. Accepts either of 'x', 'y', 'xy'. * offset: Offset value to be added to the 'xy' auxiliary coordinate points. * scalar: Create a 'height' scalar coordinate with the given value. Returns: The newly created 2D :class:`iris.cube.Cube`. """ x_range = np.arange(*x, dtype=np.float32) y_range = np.arange(*y, dtype=np.float32) x_size = len(x_range) y_size = len(y_range) cube_data = np.empty((y_size, x_size), dtype=np.float32) cube_data[:] = data cube = iris.cube.Cube(cube_data) coord = DimCoord(y_range, long_name="y", units="1") coord.guess_bounds() cube.add_dim_coord(coord, 0) coord = DimCoord(x_range, long_name="x", units="1") coord.guess_bounds() cube.add_dim_coord(coord, 1) if aux is not None: aux = aux.split(",") if "y" in aux: coord = AuxCoord(y_range * 10, long_name="y-aux", units="1") cube.add_aux_coord(coord, (0, )) if "x" in aux: coord = AuxCoord(x_range * 10, long_name="x-aux", units="1") cube.add_aux_coord(coord, (1, )) if "xy" in aux: payload = np.arange(y_size * x_size, dtype=np.float32).reshape(y_size, x_size) coord = AuxCoord(payload * 100 + offset, long_name="xy-aux", units="1") cube.add_aux_coord(coord, (0, 1)) if cell_measure is not None: cell_measure = cell_measure.split(",") if "y" in cell_measure: cm = CellMeasure(y_range * 10, long_name="y-aux", units="1") cube.add_cell_measure(cm, (0, )) if "x" in cell_measure: cm = CellMeasure(x_range * 10, long_name="x-aux", units="1") cube.add_cell_measure(cm, (1, )) if "xy" in cell_measure: payload = x_range + y_range[:, np.newaxis] cm = CellMeasure(payload * 100 + offset, long_name="xy-aux", units="1") cube.add_cell_measure(cm, (0, 1)) if ancil is not None: ancil = ancil.split(",") if "y" in ancil: av = AncillaryVariable(y_range * 10, long_name="y-aux", units="1") cube.add_ancillary_variable(av, (0, )) if "x" in ancil: av = AncillaryVariable(x_range * 10, long_name="x-aux", units="1") cube.add_ancillary_variable(av, (1, )) if "xy" in ancil: payload = x_range + y_range[:, np.newaxis] av = AncillaryVariable(payload * 100 + offset, long_name="xy-aux", units="1") cube.add_ancillary_variable(av, (0, 1)) if scalar is not None: data = np.array([scalar], dtype=np.float32) coord = AuxCoord(data, long_name="height", units="m") cube.add_aux_coord(coord, ()) return cube
def _generate_cubes(header, column_headings, coords, data_arrays, cell_methods=None): """ Yield :class:`iris.cube.Cube` instances given the headers, column headings, coords and data_arrays extracted from a NAME file. """ for i, data_array in enumerate(data_arrays): # Turn the dictionary of column headings with a list of header # information for each field into a dictionary of headings for # just this field. field_headings = {k: v[i] for k, v in column_headings.items()} # Make a cube. cube = iris.cube.Cube(data_array) # Determine the name and units. name = "{} {}".format(field_headings["Species"], field_headings["Quantity"]) name = name.upper().replace(" ", "_") cube.rename(name) # Some units are not in SI units, are missing spaces or typed # in the wrong case. _parse_units returns units that are # recognised by Iris. cube.units = _parse_units(field_headings["Units"]) # Define and add the singular coordinates of the field (flight # level, time etc.) if "Z" in field_headings: (upper_bound, ) = [ field_headings["... to [Z]"] if "... to [Z]" in field_headings else None ] (lower_bound, ) = [ field_headings["... from [Z]"] if "... from [Z]" in field_headings else None ] z_coord = _cf_height_from_name( field_headings["Z"], upper_bound=upper_bound, lower_bound=lower_bound, ) cube.add_aux_coord(z_coord) # Define the time unit and use it to serialise the datetime for # the time coordinate. time_unit = cf_units.Unit("hours since epoch", calendar=cf_units.CALENDAR_GREGORIAN) # Build time, height, latitude and longitude coordinates. for coord in coords: pts = coord.values coord_sys = None if coord.name == "latitude" or coord.name == "longitude": coord_units = "degrees" coord_sys = iris.coord_systems.GeogCS(EARTH_RADIUS) if (coord.name == "projection_x_coordinate" or coord.name == "projection_y_coordinate"): coord_units = "m" coord_sys = iris.coord_systems.OSGB() if coord.name == "height": coord_units = "m" long_name = "height above ground level" pts = coord.values if coord.name == "altitude": coord_units = "m" long_name = "altitude above sea level" pts = coord.values if coord.name == "air_pressure": coord_units = "Pa" pts = coord.values if coord.name == "flight_level": pts = coord.values long_name = "flight_level" coord_units = _parse_units("FL") if coord.name == "time": coord_units = time_unit pts = time_unit.date2num(coord.values).astype(float) if coord.dimension is not None: if coord.name == "longitude": circular = iris.util._is_circular(pts, 360.0) else: circular = False if coord.name == "flight_level": icoord = DimCoord(points=pts, units=coord_units, long_name=long_name) else: icoord = DimCoord( points=pts, standard_name=coord.name, units=coord_units, coord_system=coord_sys, circular=circular, ) if coord.name == "height" or coord.name == "altitude": icoord.long_name = long_name if (coord.name == "time" and "Av or Int period" in field_headings): dt = coord.values - field_headings["Av or Int period"] bnds = time_unit.date2num(np.vstack((dt, coord.values)).T) icoord.bounds = bnds.astype(float) else: icoord.guess_bounds() cube.add_dim_coord(icoord, coord.dimension) else: icoord = AuxCoord( points=pts[i], standard_name=coord.name, coord_system=coord_sys, units=coord_units, ) if (coord.name == "time" and "Av or Int period" in field_headings): dt = coord.values - field_headings["Av or Int period"] bnds = time_unit.date2num(np.vstack((dt, coord.values)).T) icoord.bounds = bnds[i, :].astype(float) cube.add_aux_coord(icoord) # Headings/column headings which are encoded elsewhere. headings = [ "X", "Y", "Z", "Time", "T", "Units", "Av or Int period", "... from [Z]", "... to [Z]", "X grid origin", "Y grid origin", "X grid size", "Y grid size", "X grid resolution", "Y grid resolution", "Number of field cols", "Number of preliminary cols", "Number of fields", "Number of series", "Output format", ] # Add the Main Headings as attributes. for key, value in header.items(): if value is not None and value != "" and key not in headings: cube.attributes[key] = value # Add the Column Headings as attributes for key, value in field_headings.items(): if value is not None and value != "" and key not in headings: cube.attributes[key] = value if cell_methods is not None: cube.add_cell_method(cell_methods[i]) yield cube
def load_NAMEIII_trajectory(filename): """ Load a NAME III trajectory file returning a generator of :class:`iris.cube.Cube` instances. Args: * filename (string): Name of file to load. Returns: A generator :class:`iris.cube.Cube` instances. """ time_unit = cf_units.Unit("hours since epoch", calendar=cf_units.CALENDAR_GREGORIAN) with open(filename, "r") as infile: header = read_header(infile) # read the column headings for line in infile: if line.startswith(" "): break headings = [heading.strip() for heading in line.split(",")] # read the columns columns = [[] for i in range(len(headings))] for line in infile: values = [v.strip() for v in line.split(",")] for c, v in enumerate(values): if "UTC" in v: v = datetime.datetime.strptime(v, NAMETRAJ_DATETIME_FORMAT) else: try: v = float(v) except ValueError: pass columns[c].append(v) # Sort columns according to PP Index columns_t = list(map(list, zip(*columns))) columns_t.sort(key=itemgetter(1)) columns = list(map(list, zip(*columns_t))) # Where's the Z column? z_column = None for i, heading in enumerate(headings): if heading.startswith("Z "): z_column = i break if z_column is None: raise TranslationError("Expected a Z column") # Every column up to Z becomes a coordinate. coords = [] for name, values in zip(headings[:z_column + 1], columns[:z_column + 1]): values = np.array(values) if np.all(np.array(values) == values[0]): values = [values[0]] long_name = units = None if isinstance(values[0], datetime.datetime): values = time_unit.date2num(values).astype(float) units = time_unit if name == "Time": name = "time" elif " (Lat-Long)" in name: if name.startswith("X"): name = "longitude" elif name.startswith("Y"): name = "latitude" units = "degrees" elif name == "Z (m asl)": name = "altitude" units = "m" long_name = "altitude above sea level" elif name == "Z (m agl)": name = "height" units = "m" long_name = "height above ground level" elif name == "Z (FL)": name = "flight_level" long_name = name try: coord = DimCoord(values, units=units) except ValueError: coord = AuxCoord(values, units=units) coord.rename(name) if coord.long_name is None and long_name is not None: coord.long_name = long_name coords.append(coord) # Every numerical column after the Z becomes a cube. for name, values in zip(headings[z_column + 1:], columns[z_column + 1:]): try: float(values[0]) except ValueError: continue # units embedded in column heading? name, units = _split_name_and_units(name) cube = iris.cube.Cube(values, units=units) cube.rename(name) # Add the Main Headings as attributes. for key, value in header.items(): if value is not None and value != "" and key not in headings: cube.attributes[key] = value # Add coordinates for coord in coords: dim = 0 if len(coord.points) > 1 else None if dim == 0 and coord.name() == "time": cube.add_dim_coord(coord.copy(), dim) elif dim == 0 and coord.name() == "PP Index": cube.add_dim_coord(coord.copy(), dim) else: cube.add_aux_coord(coord.copy(), dim) yield cube