Source code for cf.coordinatebounds

from .variable import Variable


# ====================================================================
#
# CoordinateBounds object
#
# ====================================================================

[docs]class CoordinateBounds(Variable): ''' A CF coordinate's bounds object containing cell boundaries or intervals of climatological time. The parent coordinate's `!climatology` attribute indicates which type of bounds are present. ''' # ---------------------------------------------------------------- # Attribute (read only) # ---------------------------------------------------------------- @property def lower_bounds(self): ''' The lower coordinate bounds in a `cf.Data` object. ``b.lower_bounds`` is equivalent to ``b.data.min(axes=-1)``. .. seealso:: `upper_bounds` :Examples: >>> print b.array [[ 5 3] [ 3 1] [ 1 -1]] >>> b.lower_bounds <CF Data: [3, ..., -1]> >>> print b.lower_bounds.array [ 3 1 -1] ''' if not self._hasData: raise ValueError("Can't get lower bounds when there are no bounds") return self.data.min(-1).squeeze(-1, i=True) #--- End: def # ---------------------------------------------------------------- # Attribute (read only) # ---------------------------------------------------------------- @property def upper_bounds(self): ''' The upper coordinate bounds in a `cf.Data` object. ``b.upper_bounds`` is equivalent to ``b.data.max(axes=-1)``. .. seealso:: `lower_bounds` :Examples: >>> print b.array [[ 5 3] [ 3 1] [ 1 -1]] >>> b.upper_bounds <CF Data: [5, ..., 1]> >>> b.upper_bounds.array array([5, 3, 1]) ''' if not self._hasData: raise ValueError("Can't get upper bounds when there are no bounds") return self.data.max(-1).squeeze(-1, i=True) #--- End: def def contiguous(self, overlap=True, direction=None): ''' Return True if the bounds are contiguous. Bounds are contiguous if the cell boundaries match up, or overlap, with the boundaries of adjacent cells. In general, it is only possible for 1 or 0 dimensional coordinates with bounds to be contiguous, but size 1 coordinates with any number of dimensions are always contiguous. An exception occurs if the coordinate is multdimensional and has more than one element. ''' if not self._hasData: return False nbounds = self.shape[-1] if self.size == nbounds: return True if nbounds == 4 and self.ndim ==3: if overlap == True: raise ValueError("Cannot tell if 2D coordinate bounds are" + " contiguous if overlap is True.") bnd = self.array for j in xrange(self.shape[0] - 1): for i in xrange(self.shape[1] - 1): # check cells (j, i) and cells (j, i+1) are contiguous if bnd[j,i,1] != bnd[j,i+1,0] or \ bnd[j,i,2] != bnd[j,i+1,3]: return False # check cells (j, i) and (j+1, i) are contiguous if bnd[j,i,3] != bnd[j+1,i,0] or \ bnd[j,i,2] != bnd[j+1,i,1]: return False return True if nbounds > 2 or self.ndim > 2: raise ValueError( "Can't tell if a multidimensional coordinate bounds are contiguous") data = self.Data if not overlap: return data[1:, 0].equals(data[:-1, 1]) else: if direction is None: b = data[(0,)*(data.ndim-1)].array direction = b.item(0,) < b.item(1,) #--- End: if if direction: return (data[1:, 0] <= data[:-1, 1]).all() else: return (data[1:, 0] >= data[:-1, 1]).all()
#--- End: def #--- End: class