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_grid_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)
def set_mask(self, value, cascade=False): """ Set the grid's mask from boolean array or variable. :param value: A mask array having the same shape as the grid. This may also be a variable with the same dimensions. :type value: :class:`numpy.ndarray` | :class:`~ocgis.Variable` :param cascade: If ``True``, cascade the mask along shared dimension on the grid. """ from ocgis.spatial.grid import create_grid_mask_variable, grid_set_mask_cascade if isinstance(value, Variable): self.parent.add_variable(value, force=True) mask_variable = value else: mask_variable = self.mask_variable if mask_variable is None: mask_variable = create_grid_mask_variable(VariableName.SPATIAL_MASK, value, self.dimensions) self.parent.add_variable(mask_variable) else: mask_variable.set_mask(value) self.dimension_map.set_spatial_mask(mask_variable) if cascade: grid_set_mask_cascade(self)
def test_set_spatial_mask(self): dmap = DimensionMap() dims = Dimension('x', 3), Dimension('y', 7) mask_var = create_grid_mask_variable('a_mask', None, dims) self.assertFalse(np.any(mask_var.get_mask())) dmap.set_spatial_mask(mask_var) self.assertEqual(dmap.get_spatial_mask(), mask_var.name) with self.assertRaises(DimensionMapError): dmap.set_variable(DMK.SPATIAL_MASK, mask_var) # Test custom variables may be used. dmap = DimensionMap() dims = Dimension('x', 3), Dimension('y', 7) mask_var = create_grid_mask_variable('a_mask', None, dims) attrs = {'please keep me': 'no overwriting'} dmap.set_spatial_mask(mask_var, attrs=attrs) attrs = dmap.get_attrs(DMK.SPATIAL_MASK) self.assertIn('please keep me', attrs)
def test_grid(self): # Test mask variable information is propagated through property. grid = self.get_gridxy() np.random.seed(1) value = np.random.rand(*grid.shape) select = value > 0.4 mask_var = create_grid_mask_variable('nonstandard', select, grid.dimensions) grid.set_mask(mask_var) field = Field(grid=grid) self.assertEqual(field.dimension_map.get_spatial_mask(), mask_var.name) # field.dimension_map.pprint() self.assertNumpyAll(field.grid.get_mask(), mask_var.get_mask())
def __init__(self, **kwargs): kwargs = kwargs.copy() x = kwargs.pop(KeywordArgument.X) y = kwargs.pop(KeywordArgument.Y) z = kwargs.pop(KeywordArgument.Z, None) mask = kwargs.pop(KeywordArgument.MASK, None) pos = kwargs.pop(KeywordArgument.POS, (0, 1)) parent = kwargs.get(KeywordArgument.PARENT, None) # -------------------------------------------------------------------------------------------------------------- if x is None: if parent is None: raise ValueError('A "parent" is required if no coordinate variables are provided.') x, y, z = self._get_xyz_from_parent_(parent) if x is None or y is None: if parent is not None: raise GridDeficientError("'x' or 'y' coordinates are missing.") else: raise ValueError("'x' and 'y' coordinates are required without a parent.") if x.dimensions is None or y.dimensions is None or (z is not None and z.dimensions is None): raise ValueError('Coordinate variables must have dimensions.') # -------------------------------------------------------------------------------------------------------------- new_variables = [x, y] if z is not None: new_variables.append(z) if parent is None: parent = self._get_parent_class_()(variables=new_variables, force=True) kwargs[KeywordArgument.PARENT] = parent else: for var in new_variables: parent.add_variable(var, force=True) self._set_xyz_on_dimension_map_(x, y, z, pos, parent=parent) super(AbstractXYZSpatialContainer, self).__init__(**kwargs) if mask is not None: if not isinstance(mask, Variable): from ocgis.spatial.grid import create_grid_mask_variable mask = create_grid_mask_variable(VariableName.SPATIAL_MASK, mask, self.dimensions) self.parent.add_variable(mask, force=True) self.dimension_map.set_spatial_mask(mask)
def get_mask(self, *args, **kwargs): """ The grid's mask is stored independently from the coordinate variables' masks. The mask is actually a variable containing a mask. This approach ensures the mask may be persisted to file and retrieved/modified leaving all coordinate variables intact. .. note:: See :meth:`~ocgis.Variable.get_mask` for documentation. """ from ocgis.spatial.grid import create_grid_mask_variable create = kwargs.get(KeywordArgument.CREATE, False) mask_variable = self.mask_variable ret = None if mask_variable is None: if create: mask_variable = create_grid_mask_variable(VariableName.SPATIAL_MASK, None, self.dimensions) self.set_mask(mask_variable) if mask_variable is not None: ret = mask_variable.get_mask(*args, **kwargs) if mask_variable.attrs.get('ocgis_role') != 'spatial_mask': msg = 'Mask variable "{}" must have an "ocgis_role" attribute with a value of "spatial_mask".'.format( ret.name) raise ValueError(msg) return ret
def fixture_mask(self): return create_grid_mask_variable( 'mask', [False, False, False, False, True, False], dimensions=self.fixture_element_dimension)