Пример #1
0
    def test_grid(self):
        # Test mask variable information is propagated through property.
        grid = self.get_gridxy(with_xy_bounds=True)
        self.assertTrue(grid.is_vectorized)
        self.assertTrue(grid.has_bounds)
        np.random.seed(1)
        value = np.random.rand(*grid.shape)
        select = value > 0.4
        mask_var = create_spatial_mask_variable('nonstandard', select, grid.dimensions)
        grid.set_mask(mask_var)
        field = Field(grid=grid)
        self.assertTrue(field.grid.has_bounds)
        self.assertEqual(field.dimension_map.get_spatial_mask(), mask_var.name)
        self.assertNumpyAll(field.grid.get_mask(), mask_var.get_mask())

        # Test dimension map bounds are updated appropriately.
        dim = Dimension('count', 2)
        x = Variable(name='x', value=[1., 2.], dimensions=dim)
        y = Variable(name='y', value=[1., 2.], dimensions=dim)
        xb = Variable(name='xb', value=[[0., 1.5], [1.5, 2.5]], dimensions=[dim, 'bounds'])
        yb = Variable(name='yb', value=[[0., 1.5], [1.5, 2.5]], dimensions=[dim, 'bounds'])
        variables = [x, y, xb, yb]
        dmap = DimensionMap()
        dmap.set_variable(DMK.X, x, bounds=xb)
        dmap.set_variable(DMK.Y, y, bounds=yb)
        f = Field(dimension_map=dmap, variables=variables)
        self.assertTrue(f.grid.has_bounds)
Пример #2
0
    def test_init_dimension_map(self):
        """Test initializing with a dimension map only."""

        dmap = DimensionMap()
        x = Variable(value=[1, 2, 3], dimensions='elements', name='x')
        y = Variable(value=[4, 5, 6], dimensions='elements', name='y')
        topo = dmap.get_topology(Topology.POINT, create=True)
        topo.set_variable(DMK.X, x)
        topo.set_variable(DMK.Y, y)
        f = Field(variables=[x, y], dimension_map=dmap)
        p = PointGC(parent=f)
        self.assertNumpyAll(x.get_value(), p.x.get_value())
        self.assertNumpyAll(y.get_value(), p.y.get_value())
Пример #3
0
    def test_init_dimension_map(self):
        """Test initializing with a dimension map only."""

        dmap = DimensionMap()
        x = Variable(value=[1, 2, 3], dimensions='elements', name='x')
        y = Variable(value=[4, 5, 6], dimensions='elements', name='y')
        topo = dmap.get_topology(Topology.POINT, create=True)
        topo.set_variable(DMK.X, x)
        topo.set_variable(DMK.Y, y)
        f = Field(variables=[x, y], dimension_map=dmap)
        p = PointGC(parent=f)
        self.assertNumpyAll(x.get_value(), p.x.get_value())
        self.assertNumpyAll(y.get_value(), p.y.get_value())
Пример #4
0
    def test_get_name_mapping(self):
        dimension_map = {'crs': {'variable': 'latitude_longitude'}, 'level': {'variable': None, 'dimension': []},
                         'time': {'variable': u'time', 'attrs': {'axis': 'T'}, 'bounds': u'time_bnds',
                                  'dimension': [u'time']}, 'driver': 'netcdf-cf', 'spatial_mask': {'variable': None},
                         'groups': {}, 'realization': {'variable': None, 'dimension': []},
                         'y': {'variable': u'lat', 'attrs': {}, 'bounds': u'lat_vertices', 'dimension': [u'rlat']},
                         'x': {'variable': u'lon', 'attrs': {}, 'bounds': u'lon_vertices', 'dimension': [u'rlon']}}
        dimension_map = DimensionMap.from_dict(dimension_map)

        actual = get_name_mapping(dimension_map)
        desired = {'y': [u'rlat'], 'x': [u'rlon'], 'time': [u'time']}
        self.assertEqual(actual, desired)
Пример #5
0
    def create_dimension_map(self, group_metadata, **kwargs):
        ret = DimensionMap()
        ret.set_driver(self)

        topo = ret.get_topology(Topology.POINT, create=True)
        topo.set_variable(DMK.X, 'grid_center_lon', dimension='grid_size')
        topo.set_variable(DMK.Y, 'grid_center_lat', dimension='grid_size')

        if 'grid_corner_lon' in group_metadata['variables']:
            topo = ret.get_topology(Topology.POLYGON, create=True)
            topo.set_variable(DMK.X, 'grid_corner_lon', dimension='grid_size')
            topo.set_variable(DMK.Y, 'grid_corner_lat', dimension='grid_size')

        if 'grid_imask' in group_metadata['variables']:
            # Use the intrinsic SCRIP default attributes associated with the variable.
            ret.set_spatial_mask('grid_imask', default_attrs={})

        # The isomorphic property covers all possible mesh topologies.
        ret.set_property(DMK.IS_ISOMORPHIC, True)

        return ret
Пример #6
0
    def __iter__(self):
        non_iterables = [AbstractRequestObject, dict, Field]
        if env.USE_ESMF:
            import ESMF
            non_iterables.append(ESMF.Field)

        if isinstance(self._value, tuple(non_iterables)):
            to_itr = [self._value]
        else:
            to_itr = self._value
        for uid, element in enumerate(to_itr, start=1):
            if isinstance(element, dict):
                element = RequestDataset(**element)

            if env.USE_ESMF and isinstance(element, ESMF.Field):
                from ocgis.regrid.base import get_ocgis_field_from_esmf_field
                dimension_map = {
                    DimensionMapKey.X: {
                        DimensionMapKey.VARIABLE: 'x',
                        DimensionMapKey.DIMENSION: ['x']
                    },
                    DimensionMapKey.Y: {
                        DimensionMapKey.VARIABLE: 'y',
                        DimensionMapKey.DIMENSION: ['y']
                    }
                }
                dimension_map = DimensionMap.from_dict(dimension_map)
                element = get_ocgis_field_from_esmf_field(
                    element,
                    dimensions=self.esmf_field_dimensions,
                    dimension_map=dimension_map)

            try:
                element = element.copy()
            except AttributeError:
                element = copy(element)

            if element.uid is None:
                element.uid = uid
                # TODO: Remove me once the driver does not accept request datasets at initialization.
                # Try to change the driver UID.
                try:
                    element.driver.rd.uid = uid
                except AttributeError:
                    # The field driver does not keep a copy of the request dataset.
                    if hasattr(element.driver, 'rd'):
                        raise

            yield element
Пример #7
0
def get_ocgis_grid_from_esmf_grid(egrid, crs=None, dimension_map=None):
    """
    Create an OCGIS :class:`~ocgis.interface.base.dimension.spatial.SpatialDimension` object from an ESMF
    :class:`~ESMF.driver.grid.Grid`.

    :type egrid: :class:`ESMF.driver.grid.Grid`
    :param crs: The coordinate system to attach to the output spatial dimension.
    :type crs: :class:`ocgis.interface.base.crs.CoordinateReferenceSystem`
    :param dimension_map: Dimension map for the outgoing OCGIS field/grid.
    :type dimension_map: :class:`ocgis.DimensionMap`
    :rtype: :class:`~ocgis.Grid`
    """

    if dimension_map is None:
        dimension_map = {
            DimensionMapKey.X: {
                'variable': 'x',
                'bounds': 'x_bounds',
                DimensionMapKey.DIMENSION: ['x']
            },
            DimensionMapKey.Y: {
                'variable': 'y',
                'bounds': 'y_bounds',
                DimensionMapKey.DIMENSION: ['y']
            }
        }
        dimension_map = DimensionMap.from_dict(dimension_map)
    else:
        assert isinstance(dimension_map, DimensionMap)

    # OCGIS grid values are built on centers.
    coords = egrid.coords[ESMF.StaggerLoc.CENTER]
    shape_coords_list = list(coords[0].shape)
    dtype_coords = coords[0].dtype
    # construct the ocgis grid array and fill
    grid_value = np.zeros([2] + shape_coords_list, dtype=dtype_coords)
    grid_value[0, ...] = coords[1]
    grid_value[1, ...] = coords[0]

    # Build OCGIS corners array if corners are present on the ESMF grid object.
    has_corners = get_esmf_grid_has_corners(egrid)
    if has_corners:
        corner = egrid.coords[ESMF.StaggerLoc.CORNER]
        grid_corners = np.zeros([2] + shape_coords_list + [4],
                                dtype=dtype_coords)
        slices = [(0, 0), (0, 1), (1, 1), (1, 0)]
        for ii, jj in iter_array(coords[0], use_mask=False):
            row_slice = slice(ii, ii + 2)
            col_slice = slice(jj, jj + 2)
            row_corners = corner[1][row_slice, col_slice]
            col_corners = corner[0][row_slice, col_slice]
            for kk, slc in enumerate(slices):
                grid_corners[:, ii, jj,
                             kk] = row_corners[slc], col_corners[slc]
    else:
        grid_corners = None

    # Does the grid have a mask?
    has_mask = False
    if egrid.mask is not None:
        if egrid.mask[ESMF.StaggerLoc.CENTER] is not None:
            has_mask = True
    if has_mask:
        # if there is a mask, update the grid values
        egrid_mask = egrid.mask[ESMF.StaggerLoc.CENTER]
        egrid_mask = np.invert(egrid_mask.astype(bool))

    # actually construct the masked arrays
    grid_value = np.ma.array(grid_value)
    if grid_corners is not None:
        grid_corners = np.ma.array(grid_corners)

    grid_dimensions = [
        dimension_map.get_dimension(DimensionMapKey.Y)[0],
        dimension_map.get_dimension(DimensionMapKey.X)[0]
    ]
    if grid_corners is not None:
        grid_bounds_dimensions = deepcopy(grid_dimensions)
        grid_bounds_dimensions.append(constants.DEFAULT_NAME_CORNERS_DIMENSION)

        name = dimension_map.get_bounds(DimensionMapKey.X)
        x_bounds = Variable(
            name=name,
            value=grid_corners[1, ...],
            dimensions=['y', 'x', constants.DEFAULT_NAME_CORNERS_DIMENSION])

        name = dimension_map.get_bounds(DimensionMapKey.Y)
        y_bounds = Variable(
            name=name,
            value=grid_corners[0, ...],
            dimensions=['y', 'x', constants.DEFAULT_NAME_CORNERS_DIMENSION])
    else:
        x_bounds, y_bounds = [None] * 2

    name = dimension_map.get_variable(DimensionMapKey.X)
    x = Variable(name=name,
                 dimensions=grid_dimensions,
                 value=grid_value[1, ...],
                 bounds=x_bounds)

    name = dimension_map.get_variable(DimensionMapKey.Y)
    y = Variable(name=name,
                 dimensions=grid_dimensions,
                 value=grid_value[0, ...],
                 bounds=y_bounds)

    ogrid = Grid(x, y, crs=crs)

    if has_mask:
        ogrid.set_mask(egrid_mask)

    return ogrid
Пример #8
0
 def create_dimension_map(self, group_metadata, strict=False):
     from ocgis import DimensionMap
     return DimensionMap()
Пример #9
0
    def __init__(self, **kwargs):
        kwargs = kwargs.copy()
        dimension_map = kwargs.pop('dimension_map', None)

        # Flag updated by driver to indicate if the coordinate system is assigned or implied.
        self._has_assigned_coordinate_system = False
        # Flag to indicate if this is a regrid destination.
        self.regrid_destination = kwargs.pop('regrid_destination', False)
        # Flag to indicate if this is a regrid source.
        self.regrid_source = kwargs.pop('regrid_source', True)

        # Other incoming data objects may have a coordinate system which should be used.
        crs = kwargs.pop(KeywordArgument.CRS, 'auto')

        # Add grid variable metadata to dimension map.
        grid = kwargs.pop(KeywordArgument.GRID, 'auto')

        # Configure the driver.
        driver = kwargs.pop(KeywordArgument.DRIVER, 'auto')

        # Extract standard coordinate variables from the field keyword arguments.
        k = (DimensionMapKey.GEOM, DimensionMapKey.REALIZATION, DimensionMapKey.TIME, DimensionMapKey.LEVEL)
        s = OrderedDict()
        for ii in k:
            s[ii] = kwargs.pop(ii, None)

        grid_abstraction = kwargs.pop(KeywordArgument.GRID_ABSTRACTION, 'auto')
        if grid_abstraction is None:
            raise ValueError("'{}' may not be None.".format(KeywordArgument.GRID_ABSTRACTION))
        grid_is_isomorphic = kwargs.pop('grid_is_isomorphic', 'auto')
        if grid_is_isomorphic is None:
            raise ValueError("'{}' may not be None.".format('grid_is_isomorphic'))

        # TODO: This should maybe be part of the dimension map? Time variables are not dependent on fields.
        self.format_time = kwargs.pop(KeywordArgument.FORMAT_TIME, True)

        # Use tags to set data variables.
        is_data = kwargs.pop(KeywordArgument.IS_DATA, [])

        VariableCollection.__init__(self, **kwargs)

        dimension_map = deepcopy(dimension_map)
        if dimension_map is None:
            dimension_map = DimensionMap()
        elif isinstance(dimension_map, dict):
            dimension_map = DimensionMap.from_dict(dimension_map)
        self.dimension_map = dimension_map

        self.set_grid(grid, crs=crs)
        if driver != 'auto':
            self.dimension_map.set_driver(driver)
        if grid_abstraction != 'auto':
            self.dimension_map.set_grid_abstraction(grid_abstraction)
        if grid_is_isomorphic != 'auto':
            self.dimension_map.set_property(DMK.IS_ISOMORPHIC, grid_is_isomorphic)

        # Append the data variable tagged variable names.
        is_data = list(get_iter(is_data, dtype=Variable))
        is_data_variable_names = get_variable_names(is_data)
        for idvn in is_data_variable_names:
            self.append_to_tags(TagName.DATA_VARIABLES, idvn, create=True)
        for idx, dvn in enumerate(is_data_variable_names):
            if dvn not in self:
                if isinstance(is_data[idx], Variable):
                    self.add_variable(is_data[idx])

        # Configure the field updating the dimension map in the process.
        cvar = s[DimensionMapKey.REALIZATION]
        if cvar is not None:
            self.set_realization(cvar)
        cvar = s[DimensionMapKey.TIME]
        if cvar is not None:
            self.set_time(cvar)
        cvar = s[DimensionMapKey.LEVEL]
        if cvar is not None:
            self.set_level(cvar)
        cvar = s[DimensionMapKey.GEOM]
        if cvar is not None:
            self.set_geom(cvar, crs=crs)
        if crs != 'auto':
            self.set_crs(crs)