# This script allows use of any of three python netCDF modules: # Scientific.IO.NetCDF, netCDF4, or pycdf # To use whichever netCDF module you might have installed put # from netCDF import * # in your script. # Programs should use the Scientific.IO.NetCDF syntax; # Generally, netCDF4 matches the Scientific.IO.NetCDF syntax and functionality. However there are some differences which require knowing which module is in use to properly call methods. The variable netCDF_module is provided to accomplish this. # If the pycdf module is to be used, an appropriate "translation" of the method calls is provided. # Written March 16, 2010 by Glen Granzow try: from Scientific.IO.NetCDF import NetCDFFile netCDF_module = 'Scientific.IO.NetCDF' except ImportError: try: from netCDF4 import Dataset as NetCDFFile netCDF_module = 'netCDF4' except ImportError: try: import pycdf netCDF_module = 'pycdf' except ImportError: print 'Unable to import any of the following python modules:' print ' Scientific.IO.NetCDF \n netcdf4 \n pycdf' print 'One of them must be installed.' raise ImportError('No netCDF module found') def NCtype(value): if isinstance(value,int): return pycdf.NC.INT if isinstance(value,float): return pycdf.NC.FLOAT if isinstance(value,str): return pycdf.NC.CHAR class NetCDFFile(object): def __init__(self,filename,mode): if mode == 'w': self.FILE = pycdf.CDF(filename, pycdf.NC.WRITE | pycdf.NC.CREATE | pycdf.NC.TRUNC) if mode == 'r': self.FILE = pycdf.CDF(filename, pycdf.NC.NOWRITE) if mode == 'a': self.FILE = pycdf.CDF(filename, pycdf.NC.WRITE) self.FILE.automode() def __setattr__(self,name,value): if name == 'FILE': object.__setattr__(self,name,value) else: # Used to assign global attributes self.FILE.attr(name).put(NCtype(value),value) def __getattr__(self,name): if name == 'dimensions': return self.FILE.dimensions() if name == 'variables': dictionary = dict() for variable in self.FILE.variables().keys(): dictionary[variable] = NetCDFvariable(self.FILE.var(variable),None,None,None) return dictionary global_attributes = self.FILE.attributes() if name in global_attributes: return global_attributes[name] return object.__getattribute__(self,name) def __dir__(self): return self.FILE.attributes().keys() def hasattr(self,name): return name in dir() def createDimension(self,name,size): self.FILE.def_dim(name,size) def createVariable(self,name,datatype,dimensions): dictNC = {'f':pycdf.NC.FLOAT, 'd':pycdf.NC.DOUBLE, 'i':pycdf.NC.INT, 'c':pycdf.NC.CHAR, 'b':pycdf.NC.BYTE} return NetCDFvariable(self.FILE,name,dictNC[datatype],dimensions) def sync(self): self.FILE.sync() def close(self): self.FILE.close() class NetCDFvariable(object): def __init__(self,FILE,name,datatype,dimensions): if isinstance(FILE,pycdf.pycdf.CDFVar): # FILE is an already defined netCDF variable (not a file) self.VARIABLE = FILE else: # Create a new variable in the netCDF file self.VARIABLE = FILE.def_var(name,datatype,dimensions) self.shape = self.VARIABLE.shape() def __setitem__(self,elem,data): self.VARIABLE[elem] = data def __getitem__(self,elem): return self.VARIABLE[elem] def __setattr__(self,name,value): if name in ('VARIABLE','shape'): object.__setattr__(self,name,value) else: # Used to assign variable attributes self.VARIABLE.attr(name).put(NCtype(value),value) def __getattr__(self,name): if name == 'dimensions': return self.VARIABLE.dimensions() variable_attributes = self.VARIABLE.attributes() if name in variable_attributes: return variable_attributes[name] return object.__getattribute__(self,name) def assignValue(self,value): self.VARIABLE.put(value) def getValue(self): return self.VARIABLE.get() def __dir__(self): return self.VARIABLE.attributes().keys() def typecode(self): NCdict = {pycdf.NC.FLOAT:'f', pycdf.NC.DOUBLE:'d', pycdf.NC.INT:'i', pycdf.NC.CHAR:'c', pycdf.NC.BYTE:'b'} return NCdict[self.VARIABLE.inq_type()] #NOTE: Turning this off becuase it is printed a bajillion times when using the build_and_test structure. #print 'Using',netCDF_module,'for netCDF file I/O'