def test_distinct_xy_bounds_pole(self): # is UserWarning issued for out-of-bounds? results will be unexpected! cube = stock.simple_pp() cube = cube[:4, :4] lon = cube.coord('longitude') lat = cube.coord('latitude') lon.guess_bounds() lat.guess_bounds() from iris.util import regular_step quarter = abs(regular_step(lon) * regular_step(lat) * 0.25) half = abs(regular_step(lon) * regular_step(lat) * 0.5) top_cell_half = abs(regular_step(lon) * (90 - lat.bounds[0, 1]) * 0.5) minx = 3.7499990463256836 maxx = 7.499998092651367 miny = 84.99998474121094 maxy = 99.99998474121094 geometry = shapely.geometry.box(minx, miny, maxx, maxy) # see http://stackoverflow.com/a/3892301 to assert warnings with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") # always trigger all warnings weights = geometry_area_weights(cube, geometry) self.assertEqual(str(w[-1].message), "The geometry exceeds the " "cube's y dimension at the upper end.") self.assertTrue(issubclass(w[-1].category, UserWarning)) target = np.array([ [0, top_cell_half, top_cell_half, 0], [0, half, half, 0], [0, quarter, quarter, 0], [0, 0, 0, 0]]) self.assertTrue(np.allclose(weights, target))
def test_distinct_xy_bounds_pole(self): # is UserWarning issued for out-of-bounds? results will be unexpected! cube = stock.simple_pp() cube = cube[:4, :4] lon = cube.coord('longitude') lat = cube.coord('latitude') lon.guess_bounds() lat.guess_bounds() from iris.util import regular_step quarter = abs(regular_step(lon) * regular_step(lat) * 0.25) half = abs(regular_step(lon) * regular_step(lat) * 0.5) top_cell_half = abs(regular_step(lon) * (90 - lat.bounds[0, 1]) * 0.5) minx = 3.7499990463256836 maxx = 7.499998092651367 miny = 84.99998474121094 maxy = 99.99998474121094 geometry = shapely.geometry.box(minx, miny, maxx, maxy) # see http://stackoverflow.com/a/3892301 to assert warnings with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") # always trigger all warnings weights = geometry_area_weights(cube, geometry) self.assertEqual( str(w[-1].message), "The geometry exceeds the " "cube's y dimension at the upper end.") self.assertTrue(issubclass(w[-1].category, UserWarning)) target = np.array([[0, top_cell_half, top_cell_half, 0], [0, half, half, 0], [0, quarter, quarter, 0], [0, 0, 0, 0]]) self.assertTrue(np.allclose(weights, target))
def test_basic(self): dtype = np.float64 points = np.arange(5, dtype=dtype) coord = DimCoord(points) expected = np.mean(np.diff(points)) result = regular_step(coord) self.assertEqual(expected, result) self.assertEqual(result.dtype, dtype)
def dx_dy(x_coord, y_coord, grib): x_step = regular_step(x_coord) y_step = regular_step(y_coord) # Set x and y step. For degrees, this is encoded as an integer: # 1 * 10^6 * floating point value. # WMO Manual on Codes regulation 92.1.6 if x_coord.units == 'degrees': gribapi.grib_set(grib, "iDirectionIncrement", round(1e6 * float(abs(x_step)))) else: raise ValueError('X coordinate must be in degrees, not {}' '.'.format(x_coord.units)) if y_coord.units == 'degrees': gribapi.grib_set(grib, "jDirectionIncrement", round(1e6 * float(abs(y_step)))) else: raise ValueError('Y coordinate must be in degrees, not {}' '.'.format(y_coord.units))
def test_distinct_xy(self): cube = stock.simple_pp() cube = cube[:4, :4] lon = cube.coord('longitude') lat = cube.coord('latitude') lon.guess_bounds() lat.guess_bounds() from iris.util import regular_step quarter = abs(regular_step(lon) * regular_step(lat) * 0.25) half = abs(regular_step(lon) * regular_step(lat) * 0.5) minx = 3.7499990463256836 maxx = 7.499998092651367 miny = 84.99998474121094 maxy = 89.99998474121094 geometry = shapely.geometry.box(minx, miny, maxx, maxy) weights = geometry_area_weights(cube, geometry) target = np.array([[0, quarter, quarter, 0], [0, half, half, 0], [0, quarter, quarter, 0], [0, 0, 0, 0]]) self.assertTrue(np.allclose(weights, target))
def test_distinct_xy_bounds(self): # cases where geometry bnds are outside cube bnds correctly handled? cube = stock.simple_pp() cube = cube[:4, :4] lon = cube.coord('longitude') lat = cube.coord('latitude') lon.guess_bounds() lat.guess_bounds() from iris.util import regular_step quarter = abs(regular_step(lon) * regular_step(lat) * 0.25) half = abs(regular_step(lon) * regular_step(lat) * 0.5) full = abs(regular_step(lon) * regular_step(lat)) minx = 3.7499990463256836 maxx = 13.12499619 maxx_overshoot = 15. miny = 84.99998474121094 maxy = 89.99998474121094 geometry = shapely.geometry.box(minx, miny, maxx, maxy) geometry_overshoot = shapely.geometry.box(minx, miny, maxx_overshoot, maxy) weights = geometry_area_weights(cube, geometry) weights_overshoot = geometry_area_weights(cube, geometry_overshoot) target = np.array([[0, quarter, half, half], [0, half, full, full], [0, quarter, half, half], [0, 0, 0, 0]]) self.assertTrue(np.allclose(weights, target)) self.assertTrue(np.allclose(weights_overshoot, target))
def test_distinct_xy_bounds(self): # cases where geometry bnds are outside cube bnds correctly handled? cube = stock.simple_pp() cube = cube[:4, :4] lon = cube.coord('longitude') lat = cube.coord('latitude') lon.guess_bounds() lat.guess_bounds() from iris.util import regular_step quarter = abs(regular_step(lon) * regular_step(lat) * 0.25) half = abs(regular_step(lon) * regular_step(lat) * 0.5) full = abs(regular_step(lon) * regular_step(lat)) minx = 3.7499990463256836 maxx = 13.12499619 maxx_overshoot = 15. miny = 84.99998474121094 maxy = 89.99998474121094 geometry = shapely.geometry.box(minx, miny, maxx, maxy) geometry_overshoot = shapely.geometry.box(minx, miny, maxx_overshoot, maxy) weights = geometry_area_weights(cube, geometry) weights_overshoot = geometry_area_weights(cube, geometry_overshoot) target = np.array([ [0, quarter, half, half], [0, half, full, full], [0, quarter, half, half], [0, 0, 0, 0]]) self.assertTrue(np.allclose(weights, target)) self.assertTrue(np.allclose(weights_overshoot, target))
def test_distinct_xy(self): cube = stock.simple_pp() cube = cube[:4, :4] lon = cube.coord('longitude') lat = cube.coord('latitude') lon.guess_bounds() lat.guess_bounds() from iris.util import regular_step quarter = abs(regular_step(lon) * regular_step(lat) * 0.25) half = abs(regular_step(lon) * regular_step(lat) * 0.5) minx = 3.7499990463256836 maxx = 7.499998092651367 miny = 84.99998474121094 maxy = 89.99998474121094 geometry = shapely.geometry.box(minx, miny, maxx, maxy) weights = geometry_area_weights(cube, geometry) target = np.array([ [0, quarter, quarter, 0], [0, half, half, 0], [0, quarter, quarter, 0], [0, 0, 0, 0]]) self.assertTrue(np.allclose(weights, target))
def _grid_and_pole_rules(cube, pp): """ Rules for setting the horizontal grid and pole location of the PP field. Args: cube: the cube being saved as a series of PP fields. pp: the current PP field having save rules applied. Returns: The PP field with updated metadata. """ lon_coord = vector_coord(cube, 'longitude') grid_lon_coord = vector_coord(cube, 'grid_longitude') lat_coord = vector_coord(cube, 'latitude') grid_lat_coord = vector_coord(cube, 'grid_latitude') if lon_coord and not is_regular(lon_coord): pp.bzx = 0 pp.bdx = 0 pp.lbnpt = lon_coord.shape[0] pp.x = lon_coord.points elif grid_lon_coord and not is_regular(grid_lon_coord): pp.bzx = 0 pp.bdx = 0 pp.lbnpt = grid_lon_coord.shape[0] pp.x = grid_lon_coord.points elif lon_coord and is_regular(lon_coord): pp.bzx = lon_coord.points[0] - regular_step(lon_coord) pp.bdx = regular_step(lon_coord) pp.lbnpt = len(lon_coord.points) elif grid_lon_coord and is_regular(grid_lon_coord): pp.bzx = grid_lon_coord.points[0] - regular_step(grid_lon_coord) pp.bdx = regular_step(grid_lon_coord) pp.lbnpt = len(grid_lon_coord.points) if lat_coord and not is_regular(lat_coord): pp.bzy = 0 pp.bdy = 0 pp.lbrow = lat_coord.shape[0] pp.y = lat_coord.points elif grid_lat_coord and not is_regular(grid_lat_coord): pp.bzy = 0 pp.bdy = 0 pp.lbrow = grid_lat_coord.shape[0] pp.y = grid_lat_coord.points elif lat_coord and is_regular(lat_coord): pp.bzy = lat_coord.points[0] - regular_step(lat_coord) pp.bdy = regular_step(lat_coord) pp.lbrow = len(lat_coord.points) elif grid_lat_coord and is_regular(grid_lat_coord): pp.bzy = grid_lat_coord.points[0] - regular_step(grid_lat_coord) pp.bdy = regular_step(grid_lat_coord) pp.lbrow = len(grid_lat_coord.points) # Check if we have a rotated coord system. if cube.coord_system("RotatedGeogCS") is not None: pp.lbcode = int(pp.lbcode) + 100 # Check if we have a circular x-coord. for lon_coord in (lon_coord, grid_lon_coord): if lon_coord is not None: if lon_coord.circular: pp.lbhem = 0 else: pp.lbhem = 3 return pp
def test_2d_coord(self): coord = AuxCoord(np.arange(8).reshape(2, 4)) exp_emsg = 'Expected 1D coord' with self.assertRaisesRegexp(CoordinateMultiDimError, exp_emsg): regular_step(coord)
def test_coord_with_irregular_step(self): name = 'latitude' coord = AuxCoord(np.array([2, 5, 1, 4]), standard_name=name) exp_emsg = '{} is not regular'.format(name) with self.assertRaisesRegex(CoordinateNotRegularError, exp_emsg): regular_step(coord)
def test_scalar_coord(self): coord = DimCoord(5) exp_emsg = 'non-scalar coord' with self.assertRaisesRegex(ValueError, exp_emsg): regular_step(coord)
def test_scalar_coord(self): coord = DimCoord(5) exp_emsg = 'non-scalar coord' with self.assertRaisesRegexp(ValueError, exp_emsg): regular_step(coord)
def dx_dy(x_coord, y_coord, grib): x_step = regular_step(x_coord) y_step = regular_step(y_coord) gribapi.grib_set(grib, "DxInDegrees", float(abs(x_step))) gribapi.grib_set(grib, "DyInDegrees", float(abs(y_step)))
def test_coord_with_irregular_step(self): name = 'latitude' coord = AuxCoord(np.array([2, 5, 1, 4]), standard_name=name) exp_emsg = '{} is not regular'.format(name) with self.assertRaisesRegexp(CoordinateNotRegularError, exp_emsg): regular_step(coord)
def test_2d_coord(self): coord = AuxCoord(np.arange(8).reshape(2, 4)) exp_emsg = 'Expected 1D coord' with self.assertRaisesRegex(CoordinateMultiDimError, exp_emsg): regular_step(coord)