NOTICE: This version of the NSF Unidata web site (archive.unidata.ucar.edu) is no longer being updated.
Current content can be found at unidata.ucar.edu.
To learn about what's going on, see About the Archive Site.
I am building a python interface to netCDF that is at the core of a project I am working on. It isn't quite ready for distribution but appended is a description of the classes and methods and an example. It works well on both MacOS (where I do most of the development) and unix (Digital Unix). Python is especially useful since it works both in an interactive mode for poking around a netcdf and batch mode for prewritten scripts. Since it is dynamically typed, writing generic handler routines is much easier. --Bill Noon Northeast Regional Climate Center Cornell University --------------------------- Module exports the following: ncerror: Module exception type. WRITE, NOWRITE: Options for nc.open() CLOBBER, NOCLOBBER: Options for nc.create() UNLIMITED: Record dimension definition CHAR, BYTE, SHORT, LONG, FLOAT, DOUBLE: Different netCDF data types. open(name [,mode]) returns an ncfile object. <mode> is either WRITE or NOWRITE. create(name [,cmode]) returns an ncfile object. <cmode> is the create mode either CLOBBER or NOCLOBBER. ncfile objects have the following methods: close() closes the netCDF file. abort() aborts definition changes to the netCDF file. sync() syncs the file to disk. redef() enters define mode. endef() leaves define mode. setfill() enables the fill mode. setnofill() disables fill mode. def_dim(name, length) define a dimension with <name> and <length>. Must be in define mode, ncfile opened writable and <name> not already used. def_att(name, variable, nctype, data [,length]) define an attribute <name> of the variable named <variable>. If <variable> is "" then the attribute will be global. <data> is either a float/int, a string, or a tuple of float/ints. def_var(name, nctype, [(dim[,dim]*)]) define a variable <name> of type nctype. The tuple of dimension names defines the variable dimensions. If a dimension tuple is not defined, the variable is scalar. list_dim() list dimensions. list_att([name]) returns a dictionary of the attributes of variable <name>. If <name> is not supplied it returns the global attributes. list_var() list variables. var(name) returns a ncvar object for variable <name>. get_rec(rec_num) returns a dictionary of all the record variables for <num_rec> record. put_rec(rec_num, dict) puts the values defined in the <dict> dictiontary into the <rec_num> record. Variables not defined will not be inserted or altered. append(dict) as above but adds a new record with the <dict> var/value pairs. ncvar objects are either pseudo-sequences or pseudo-variable. They have the following methods: list_dim() list_att() NetCDF attributes are treated as python attributes and can be put/get but not created on the fly. Global attributes are attributes of the ncfile object, variable attributes are attributes of the ncvar object. There is a namespace clash where an attribute may have the same name as one of the above methods. In that case, it can be put/get with a put_att() or get_att() method. There is a further enhancement that uses the udunits library and the "_units" attribute to do automatic unit conversion. --------------------------------------------- >>> import nc >>> a = nc.create('test.nc',nc.CLOBBER) >>> a.def_dim('time',nc.UNLIMITED) >>> a.def_dim('x', 10) >>> a.def_dim('y', 5) >>> a.def_att('Title','',nc.CHAR,'Test netCDF dataset') >>> a.def_var('temp',nc.FLOAT,('time','x')) >>> a.def_var('pres',nc.FLOAT,('time','y')) >>> a.def_att('_units','temp',nc.CHAR,'degree_Fahrenheit') >>> a.endef() This creates the netCDF file and defines some dimensions, attributes and variables. This generally follows the netCDF API. >>> a.list_var() [('temp', 5, 1, 2, [0, 1]), ('pres', 5, 0, 2, [0, 2])] >>> a.list_att() {'Title': 'Test netCDF dataset'} >>> a.list_att('temp') {'_units': 'degree_Fahrenheit'} >>> temp = a.var('temp') >>> temp.list_att() {'_units': 'degree_Fahrenheit'} >>> temp._units 'degree_Fahrenheit' >>> temp <netCDF variable object at 140055a00> A netCDF variable object has attributes and values. The current indexing scheme in python only allows 1 dimension to be addressed. This is being fixed with the numerical extensions. >>> temp[0] = (10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0) >>> temp[:] [10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0] >>> temp[1] = range(20,30) >>> temp[:] [[10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0], [20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0]] >>> z = temp[0] >>> z[5] = 200 >>> temp[0] = z >>> temp[0] [10.0, 11.0, 12.0, 13.0, 14.0, 200.0, 16.0, 17.0, 18.0, 19.0] >>> temp[0][5] 200.0 >>> a.close() The variable object methods hide most of the access routines in the netCDF API. >>> a = nc.open('test.nc') >>> temp = a.var('temp') >>> temp[0] [10.0, 11.0, 12.0, 13.0, 14.0, 200.0, 16.0, 17.0, 18.0, 19.0] >>> a.close() One problem is the use of scalar variables. Due to the python method of always passing by reference, the syntax can't be the expected simple assign. If z is a scalar netCDF variable, z = 10.0 would replace the z variable with the value 10. I have decided to make all assignment and reference to scalar values be of the form z[0].
netcdfgroup
archives: