Source code for cdms2.fvariable

# Automatically adapted for numpy.oldnumeric Aug 01, 2007 by
# Further modified to be pure new numpy June 24th 2008

"CDMS File-based variables."
import numpy
from .cdmsobj import Max32int
from .variable import DatasetVariable
from .error import CDMSError
from .sliceut import reverseSlice
from .Cdunif import CdunifError
# import cdms2.Cdunif.CdunifError as CdunifError

FileClosed = "Cannot read from closed file, variable: "
FileClosedWrite = "Cannot write to a closed file, variable: "


[docs]class FileVariable(DatasetVariable): "A variable in a single file." def __init__(self, parent, varname, cdunifobj=None): DatasetVariable.__init__(self, parent, varname) self._obj_ = cdunifobj if cdunifobj is not None: for attname, attval in list(cdunifobj.__dict__.items()): self.__dict__[attname] = attval self.attributes[attname] = attval if '_FillValue' in self.__dict__.keys(): self.__dict__['missing_value'] = self.__dict__['_FillValue'] self.attributes['missing_value'] = self.__dict__['_FillValue'] if self.__dict__['missing_value'] is None: self.__dict__[ 'missing_value'] = numpy.ma.default_fill_value(self) self.attributes['missing_value'] = numpy.ma.default_fill_value( self) # needed for dask 2.0.0 self.__dict__['ndim'] = self.rank() self.attributes['ndim'] = self.rank() val = self.__cdms_internals__ + ['name_in_file', ] self.___cdms_internals__ = val # Initialize the domain
[docs] def initDomain(self, axisdict): "Initialized the domain" self.domain = [] for dimname in self._obj_.dimensions: axis = axisdict.get(dimname) start = 0 length = len(axis) truelen = length self.domain.append((axis, start, length, truelen))
[docs] def typecode(self): """convert to new typecode.""" tc = self._obj_.typecode() # tc = typeconv.convtypecode2(tc).char return tc
[docs] def assignValue(self, data): if self.parent is None: raise CDMSError(FileClosedWrite + self.id) if numpy.ma.isMaskedArray(data): if data.mask is not numpy.ma.nomask and not numpy.ma.allclose( data.mask, 0): saveFill = data.fill_value if self.getMissing() is None: self.setMissing(saveFill) else: data.set_fill_value(self.getMissing()) self._obj_.assignValue(numpy.ma.filled(data)) if numpy.ma.isMaskedArray(data): if data.mask is not numpy.ma.nomask and not numpy.ma.allclose( data.mask, 0): data.set_fill_value(saveFill)
[docs] def expertSlice(self, initslicelist): # Handle negative slices revlist = [] # Slices to apply to result if reversals needed slist = [] # Slices with positive strides haveReversals = 0 # True iff result array needs reversing i = 0 for s in initslicelist: if s.step < 0: axislen = self.shape[i] slist.append(reverseSlice(s, axislen)) revlist.append(slice(None, None, -1)) haveReversals = 1 else: slist.append(s) revlist.append(slice(None, None, 1)) i += 1 if self.parent is None: raise CDMSError(FileClosed + self.id) if self.rank() == 0: return self._obj_.getValue() result = self._obj_.getitem(*slist) # If slices with negative strides were input, apply the appropriate # reversals. if haveReversals: result = result[revlist] return result
def __setitem__(self, index, value): if self.parent is None: raise CDMSError(FileClosedWrite + self.id) if numpy.ma.isMaskedArray(value): if value.mask is not numpy.ma.nomask and not numpy.ma.allclose( value.mask, 0): saveFill = value.fill_value if self.getMissing() is None: self.setMissing(saveFill) else: value.set_fill_value(self.getMissing()) self._obj_.setitem(*(index, numpy.ma.filled(value))) if numpy.ma.isMaskedArray(value): if value.mask is not numpy.ma.nomask and not numpy.ma.allclose( value.mask, 0): value.set_fill_value(saveFill) def __setslice__(self, low, high, value): if self.parent is None: raise CDMSError(FileClosedWrite + self.id) # Hack to prevent netCDF overflow error on 64-bit architectures high = min(Max32int, high) if high == Max32int and self.rank() == 0: high = 1 if numpy.ma.isMaskedArray(value): if value.mask is not numpy.ma.nomask and not numpy.ma.allclose( value.mask, 0): saveFill = value.fill_value if self.getMissing() is None: self.setMissing(saveFill) else: value.set_fill_value(self.getMissing()) self._obj_.setslice(*(low, high, numpy.ma.filled(value))) if numpy.ma.isMaskedArray(value): if value.mask is not numpy.ma.nomask and not numpy.ma.allclose( value.mask, 0): value.set_fill_value(saveFill) def _getShape(self): if self.parent is None: raise CDMSError(FileClosed + self.id) return self._obj_.shape # Write external attributes to the file. # Note: __setattr__ is defined at the PropertiedClasses level. # This function intercepts the basic set operation, and ensures # that the value is propagated to the external file. def __setattr__(self, name, value): if hasattr(self, "parent") and self.parent is None: raise CDMSError(FileClosedWrite + self.id) if (name not in self.__cdms_internals__) and (value is not None): try: setattr(self._obj_, str(name), value) except Exception: raise CDMSError( "Setting %s.%s=%s" % (self.id, name, repr(value))) self.attributes[name] = value self.__dict__[name] = value # Delete external file attributes. # Note: __delattr__ is defined at the PropertiedClasses level. # This function intercepts the basic del operation, and ensures # that the delete is propagated to the external file. def __delattr__(self, name): if (name not in self.__cdms_internals__): try: delattr(self._obj_, name) except CdunifError: raise CDMSError("Deleting %s.%s" % (self.id, name)) del(self.attributes[name]) del self.__dict__[name]
[docs] def getValue(self, squeeze=1): """Return the entire set of values.""" if self.parent is None: raise CDMSError(FileClosed + self.id) if self.rank() > 0: return self.getSlice(Ellipsis, squeeze=squeeze) else: return self._obj_.getValue()
[docs] def __len__(self): "Length of first dimension. " if self.parent is None: raise CDMSError(FileClosed + self.id) return len(self._obj_)
# def __repr__(self): # if self.parent is not None: # return "<Variable: %s, file: %s, shape: %s>"%(self.id, self.parent.id, `self.shape`) # else: # return "<Variable: %s, file: **CLOSED**>"%self.id shape = property(_getShape, None)