Example #1
0
    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
Example #2
0
    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())
Example #3
0
    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())
Example #4
0
    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())
Example #5
0
    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())
Example #6
0
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