def get_field(self, ntime=2, variable_name='foo', nrow=2, ncol=2): """Create random field where mean varies with radius and std with the angle around the center of the grid. """ np.random.seed(1) row = Variable(value=np.arange(nrow) - nrow / 2., name='row', dimensions='row') col = Variable(value=np.arange(ncol) - ncol / 2., name='col', dimensions='col') grid = Grid(col, row) x, y = grid.get_value_stacked() start = dt.datetime(2000, 1, 1) delta = dt.timedelta(days=1) value_temporal = [start + i * delta for i in range(ntime)] temporal = TemporalVariable(value=value_temporal, dimensions='time', name='time') nlevel = 1 level = None nrlz = 1 realization = None value = np.random.rand(nrlz, ntime, nlevel, nrow, ncol) * np.arctan2(x, y).clip(.1) + np.hypot(x, y) variable = Variable(name=variable_name, value=value, dimensions=['realization', 'time', 'level', 'row', 'col']) field = Field(grid=grid, time=temporal, is_data=variable, level=level, realization=realization) return field
def test_system(self): from ocgis.regrid.base import create_esmf_grid, iter_esmf_fields, RegridOperation, destroy_esmf_objects import ESMF yc = Variable(name='yc', value=np.arange(-90 + (45 / 2.), 90, 45), dimensions='ydim', dtype=float) xc = Variable(name='xc', value=np.arange(15, 360, 30), dimensions='xdim', dtype=float) ogrid = Grid(y=yc, x=xc, crs=Spherical()) ogrid.set_extrapolated_bounds('xc_bounds', 'yc_bounds', 'bounds') np.random.seed(1) mask = np.random.rand(*ogrid.shape) mask = mask > 0.5 self.assertTrue(mask.sum() > 3) ogrid.set_mask(mask) egrid = create_esmf_grid(ogrid) actual_shape = egrid.size[0].tolist() desired_shape = np.flipud(ogrid.shape).tolist() self.assertEqual(actual_shape, desired_shape) desired = ogrid.get_value_stacked() desired = np.ma.array(desired, mask=False) desired.mask[0, :, :] = ogrid.get_mask() desired.mask[1, :, :] = ogrid.get_mask() desired = desired.sum() actual_col = egrid.get_coords(0) actual_row = egrid.get_coords(1) actual_mask = np.invert(egrid.mask[0].astype(bool)) actual = np.ma.array(actual_row, mask=actual_mask).sum() + np.ma.array(actual_col, mask=actual_mask).sum() self.assertEqual(actual, desired) desired = 9900.0 corners = egrid.coords[ESMF.StaggerLoc.CORNER] actual = corners[0].sum() + corners[1].sum() self.assertEqual(actual, desired) ofield = create_exact_field(ogrid, 'data', ntime=3, crs=Spherical()) variable_name, efield, tidx = list(iter_esmf_fields(ofield, split=False))[0] desired_value = ofield['data'].get_value() self.assertAlmostEqual(efield.data.sum(), desired_value.sum(), places=3) destroy_esmf_objects([egrid, efield]) ofield.grid.set_mask(ofield.grid.get_mask(), cascade=True) desired_value = ofield['data'].get_masked_value() keywords = dict(split=[False, True]) for k in self.iter_product_keywords(keywords): opts = {'split': k.split} dofield = ofield.deepcopy() dofield['data'].get_value().fill(0) ro = RegridOperation(ofield, dofield, regrid_options=opts) actual_field = ro.execute() actual_value = actual_field['data'].get_masked_value() self.assertAlmostEqual(0.0, np.abs(desired_value - actual_value).max())
def test_get_ocgis_field_from_esmf_spatial_only(self): """Test with spatial information only.""" from ocgis.regrid.base import get_esmf_field_from_ocgis_field from ocgis.regrid.base import get_ocgis_field_from_esmf_field row = Variable(name='row', value=[5, 6], dimensions='row') col = Variable(name='col', value=[7, 8], dimensions='col') grid = Grid(col, row) ofield = Field(grid=grid, crs=Spherical()) efield = get_esmf_field_from_ocgis_field(ofield) ofield_actual = get_ocgis_field_from_esmf_field(efield) self.assertEqual(len(ofield_actual.data_variables), 0) self.assertNumpyAll(grid.get_value_stacked(), ofield_actual.grid.get_value_stacked())
def test_system(self): from ocgis.regrid.base import get_esmf_grid, iter_esmf_fields, RegridOperation, destroy_esmf_objects import ESMF yc = Variable(name='yc', value=np.arange(-90 + (45 / 2.), 90, 45), dimensions='ydim', dtype=float) xc = Variable(name='xc', value=np.arange(15, 360, 30), dimensions='xdim', dtype=float) ogrid = Grid(y=yc, x=xc, crs=Spherical()) ogrid.set_extrapolated_bounds('xc_bounds', 'yc_bounds', 'bounds') np.random.seed(1) mask = np.random.rand(*ogrid.shape) mask = mask > 0.5 self.assertTrue(mask.sum() > 3) ogrid.set_mask(mask) egrid = get_esmf_grid(ogrid) actual_shape = egrid.size[0].tolist() desired_shape = np.flipud(ogrid.shape).tolist() self.assertEqual(actual_shape, desired_shape) desired = ogrid.get_value_stacked() desired = np.ma.array(desired, mask=False) desired.mask[0, :, :] = ogrid.get_mask() desired.mask[1, :, :] = ogrid.get_mask() desired = desired.sum() actual_col = egrid.get_coords(0) actual_row = egrid.get_coords(1) actual_mask = np.invert(egrid.mask[0].astype(bool)) actual = np.ma.array(actual_row, mask=actual_mask).sum() + np.ma.array( actual_col, mask=actual_mask).sum() self.assertEqual(actual, desired) desired = 9900.0 corners = egrid.coords[ESMF.StaggerLoc.CORNER] actual = corners[0].sum() + corners[1].sum() self.assertEqual(actual, desired) ofield = create_exact_field(ogrid, 'data', ntime=3, crs=Spherical()) variable_name, efield, tidx = list( iter_esmf_fields(ofield, split=False))[0] desired_value = ofield['data'].get_value() self.assertAlmostEqual(efield.data.sum(), desired_value.sum(), places=3) destroy_esmf_objects([egrid, efield]) ofield.grid.set_mask(ofield.grid.get_mask(), cascade=True) desired_value = ofield['data'].get_masked_value() keywords = dict(split=[False, True]) for k in self.iter_product_keywords(keywords): opts = {'split': k.split} dofield = ofield.deepcopy() dofield['data'].get_value().fill(0) ro = RegridOperation(ofield, dofield, regrid_options=opts) actual_field = ro.execute() actual_value = actual_field['data'].get_masked_value() self.assertAlmostEqual(0.0, np.abs(desired_value - actual_value).max())
def get_ugrid_data_structure(): x = Variable(name='node_x', value=[10, 20, 30], dtype=float, dimensions='x') y = Variable(name='node_y', value=[-60, -55, -50, -45, -40], dimensions='y') grid = Grid(x, y) grid.set_extrapolated_bounds('x_bounds', 'y_bounds', 'bounds') grid.expand() cindex = np.zeros((grid.archetype.size, 4), dtype=int) xc = grid.x.bounds.get_value().flatten() yc = grid.y.bounds.get_value().flatten() for eidx, (ridx, cidx) in enumerate(itertools.product(*[range(ii) for ii in grid.shape])): curr_element = grid[ridx, cidx] curr_xc = curr_element.x.bounds.get_value().flatten() curr_yc = curr_element.y.bounds.get_value().flatten() for element_node_idx in range(curr_xc.shape[0]): found_idx = find_index([xc, yc], [curr_xc[element_node_idx], curr_yc[element_node_idx]]) cindex[eidx, element_node_idx] = found_idx new_cindex, uindices = reduce_reindex_coordinate_index(cindex.flatten(), start_index=0) new_cindex = new_cindex.reshape(*cindex.shape) xc = xc[uindices] yc = yc[uindices] centers = grid.get_value_stacked() center_xc = centers[1].flatten() center_yc = centers[0].flatten() longitude_attrs = {'standard_name': 'longitude', 'units': 'degrees_east'} latitude_attrs = {'standard_name': 'latitude', 'units': 'degrees_north'} vc = VariableCollection(attrs={'conventions': 'CF-1.6, UGRID-1.0'}) face_center_x = Variable(name='face_center_x', value=center_xc, dimensions='n_face', parent=vc, attrs=longitude_attrs, dtype=float) face_center_y = Variable(name='face_center_y', value=center_yc, dimensions='n_face', parent=vc, attrs=latitude_attrs, dtype=float) face_node_index = Variable(name='face_node_index', value=new_cindex, dimensions=['n_face', 'max_nodes'], parent=vc, attrs={'standard_name': 'face_node_connectivity', 'order': 'counterclockwise'}) face_node_x = Variable(name='face_node_x', value=xc, dimensions='n_node', parent=vc, attrs=longitude_attrs, dtype=float) face_node_y = Variable(name='face_node_y', value=yc, dimensions='n_node', parent=vc, attrs=latitude_attrs, dtype=float) mesh = Variable(name='mesh', attrs={'standard_name': 'mesh_topology', 'cf_role': 'mesh_topology', 'dimension': 2, 'locations': 'face node', 'node_coordinates': 'face_node_x face_node_y', 'face_coordinates': 'face_center_x face_center_y', 'face_node_connectivity': 'face_node_index'}, parent=vc) # path = self.get_temporary_file_path('foo.nc') # vc.write(path) # self.ncdump(path) # # ============================================================================================================== # import matplotlib.pyplot as plt # from descartes import PolygonPatch # from shapely.geometry import Polygon, MultiPolygon # # BLUE = '#6699cc' # GRAY = '#999999' # # fig = plt.figure(num=1) # ax = fig.add_subplot(111) # # polys = [] # # for face_idx in range(face_node_index.shape[0]): # sub = face_node_index[face_idx, :].parent # curr_cindex = sub[face_node_index.name].get_value().flatten() # fcx = sub[face_node_x.name].get_value()[curr_cindex] # fcy = sub[face_node_y.name].get_value()[curr_cindex] # # coords = np.zeros((4, 2)) # coords[:, 0] = fcx # coords[:, 1] = fcy # # poly = Polygon(coords) # polys.append(poly) # patch = PolygonPatch(poly, fc=BLUE, ec=GRAY, alpha=0.5, zorder=2) # ax.add_patch(patch) # # minx, miny, maxx, maxy = MultiPolygon(polys).bounds # w, h = maxx - minx, maxy - miny # ax.set_xlim(minx - 0.2 * w, maxx + 0.2 * w) # ax.set_ylim(miny - 0.2 * h, maxy + 0.2 * h) # ax.set_aspect(1) # # plt.scatter(center_xc, center_yc, zorder=1) # # plt.show() # =============================================================================================================== return vc