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.fileformats.rules 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_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.fileformats.rules 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 = 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, half, 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_overlap_normalize(self): weights = geometry_area_weights(self.cube, self.geometry, normalize=True) expected = np.repeat([[[0., 0.], [0., 0.25]]], self.data.shape[0], axis=0) self.assertArrayEqual(weights, expected)
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(self): cube = tests.stock.simple_pp() cube = cube[:4, :4] lon = cube.coord("longitude") lat = cube.coord("latitude") lon.guess_bounds() lat.guess_bounds() from iris.fileformats.rules 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_overlap(self): weights = geometry_area_weights(self.cube, self.geometry) expected = np.repeat([[[0., 0.], [0., 1.]]], self.data.shape[0], axis=0) self.assertArrayEqual(weights, expected)
def test_no_overlap(self): geometry = shapely.geometry.Polygon([(4, 4), (4, 6), (6, 6), (6, 4)]) weights = geometry_area_weights(self.cube, geometry) self.assertEqual(np.sum(weights), 0)
def test_shared_xy(self): cube = stock.track_1d() geometry = shapely.geometry.box(1, 4, 3.5, 7) weights = geometry_area_weights(cube, geometry) target = np.array([0, 0, 2, 0.5, 0, 0, 0, 0, 0, 0, 0]) self.assertTrue(np.allclose(weights, target))
new_dpco2_cube.units = dpco2_cube.units new_d14c_cube.var_name = d14c_cube.var_name new_dpco2_cube.var_name = dpco2_cube.var_name shpfilename = natural_earth(resolution='110m', category='physical', name='land') reader = Reader(shpfilename) continents = reader.records() new_d14c_cube.coord('latitude').guess_bounds() new_d14c_cube.coord('longitude').guess_bounds() new_dpco2_cube.coord('latitude').guess_bounds() new_dpco2_cube.coord('longitude').guess_bounds() continent_geometries = reader.geometries() # NB. Switched from using records() all_continents_geometry = cascaded_union(list(continent_geometries)) area_weights = geometry_area_weights(new_d14c_cube, all_continents_geometry) land_mask = np.where(area_weights > 0, True, False) new_d14c_cube.data = np.ma.array(new_d14c_cube.data, mask=land_mask) area_weights = geometry_area_weights(new_dpco2_cube, all_continents_geometry) land_mask = np.where(area_weights > 0, True, False) new_dpco2_cube.data = np.ma.array(new_dpco2_cube.data, mask=land_mask) iris.fileformats.netcdf.save(new_d14c_cube, output_directory+model+'_d14c_hist.nc') iris.fileformats.netcdf.save(new_dpco2_cube, output_directory+model+'_dpco2_hist.nc') subprocess.call('rm '+temporary_file_space+temp_file3, shell=True) else: print 'No variable input files for this model' else: print 'file already exists'
def region_mask(cube, region_name): # mask cube to country import cartopy.io.shapereader as shpreader import itertools from iris.analysis.geometry import geometry_area_weights import numpy.ma as ma ### Guess bounds if currently not specified if cube.coord('latitude').bounds == None: cube.coord('latitude').guess_bounds() if cube.coord('longitude').bounds == None: cube.coord('longitude').guess_bounds() # get countries (resolution = 10m, 50m, 110m ) shpfilename = shpreader.natural_earth(category='cultural', name='admin_0_countries', resolution='110m') reader = shpreader.Reader(shpfilename) # list available attributes all_countries = reader.records() country = next(all_countries) # print(country.attributes.keys()) # get all values of an attribute key = 'name_long' values = set() all_countries = reader.records() for country in all_countries: values.add(country.attributes[key]) # print( key+': '+ ', '.join(values) ) # extract countries matching criteria - is there an easier way??? country_crit = lambda country: country.attributes[ 'name_long'] == region_name ## e.g., 'China' # country_crit = lambda country: country.attributes['continent'] == 'Asia' # country_crit = lambda country: country.attributes['region_un'] == 'Asia' # country_crit = lambda country: country.attributes['subregion'] == 'Eastern Asia' all_countries = reader.records() countries = itertools.ifilter(country_crit, all_countries) # work out area weights of single field's intersection with selected countries # !!! need to make generic (get first field from cube) country = next(countries) print('Getting field intersection area with ' + country.attributes['name_long']) area_weights = geometry_area_weights(cube, country.geometry) for country in countries: print('Getting field intersection area with ' + country.attributes['name_long']) area_weights += geometry_area_weights(cube, country.geometry) # create a mask from the area weights mask = np.where(area_weights > 0, False, True) masked_cube = cube.copy() # NB: this combines the mask and the data's existing mask as required masked_cube.data = ma.array(masked_cube.data, mask=mask) return masked_cube