Contact: zeng  @  zegraph.com      Last update: 20 January 2010

netCDF Library

Although only part of the netCDF API is implemented in this library, you can achieve nearly all operations on netCDF variables and attributes. A char type attribute is treated as string for input and output; and only string, integer, and double types are allowed for writing to an attribute. The limitation, not affecting reading, is partly due to the supported data type of ZeScript. In practice other types of attributes are hardly used.

Function Parameter Type Remark
netcdf(filename[,mode]) string, string Returns a netCDF object if successful; returns null otherwise. The mode determines witting ("w"), creation ("c"), or reading ("r" or none).
.version()   Returns the netCDF library version string.
.defdim(name, size) string, integer Defines the dimension for the named variable and returns the variable ID. If size <= 0, defines the dimension as unlimited. The function should be called right after file creation. The unlimited dimension should be the last dimension.
.defvar(name, type, dimid0[, dimid1...]) string, string, integer[ integer...] Defines data type and dimensions for the named variable. The type should be "char" (or "byte"), "short", "int", "float", or "double". The number of augments after the type argument determines the number of dimensions. Each dimension size is determined by the dimension size of the specified dimension ID. If unlimited dimension id is used, it must be dimid0.
.variable(name) string Sets the named variable as the target for reading and writing. It returns null if failed or integer (variable id) otherwise.
.size()   Returns the number of data, datum size, and type name of the target variable in an array.
.dims()   Returns dimension sizes of the target variable in an array.
.info([fname]) string Displays structure of the opened netCDF file. If the file name is given, results will be saved to it.
.__get(name) string To be called by such an expression as cdf.name to get an attribute of the variable the target variable. It may returns a string, an integer, a real, or an array of integer or real, depending on attribute type.
.__get(idx...) null or integer or array To be called by such an expression as cdf[*, 1] to read data from the target dataset. A null index (may be represented by *) specifies reading all data in that dimension; an integer index (must be positive) specifies reading at that position in that dimension; and an array index (e.g., [1,2]) specifies reading range for that dimension. If the number of indices is smaller than the number of dimensions of the dataset, unspecified dimension indices are defaulted to null. The function returns an integer or real if indices are fully specified by integers; otherwise, it returns a pointer to data.
.__set(name, attribute) string, string or array of numbers To be called by an expression like cdf.name = attribute to set the named attribute of the target variable. Use "GLOBAL" for the name to write to the global attribute. Only a string attribute is allowed for the global attribute.
.__set(idx..., data) null or integer or array, number or user To be called by such an expression as cdf[*, 1] = data to write data to the target dataset. If the data is a user type, you are responsible to ensure that its pointer points to correct number of data.

netCDF Example

load("matrix", "netcdf.dll");

nc = netcdf("test.nc", "c");                        // create

// it seems global attribute must be created before
// define any other variables.

nc.GLOBAL = "global attribute ...";

// define dimensions and dimension variables

id1 = nc.defdim("lat", 19);
nc.defvar("lat", "int", id1);

id2 = nc.defdim("lon", 36);
nc.defvar("lon", "int", id2);

id3 = nc.defdim("time", 0);             // unlimited
nc.defvar("time", "int", id3);

// define variables

nc.defvar("data1", "short", id1, id2);
nc.defvar("data2", "double", id3, id1, id2);

// set lat as target

nc.variable("lat");

// write attributes

nc.unit = "degree";
nc.range = [-90, 90];

// write data

a = matrix("int", 19, 1);
a.fill(-90, 10);
[ptr, n, e] = a.ptr();
nc[*] = ptr;

// write data to lon

nc.variable("lon");

a.resize(36, 1);
a.fill(0, 10);
[ptr, n, e] = a.ptr();

nc[*] = ptr;

// write data to data1

nc.variable("data1");

a = matrix("short", 19, 36);
a.fill(0, 1);
[ptr, n, e] = a.ptr();

nc[*] = ptr;

nc[1,*] = 0;
nc[*,1] = 10;
nc[[10,15],[3,5]] = 0;

// write data to time

nc.variable("time");

a = matrix("int", 5, 1);
a.fill(1, 1);
[ptr, n, e] = a.ptr();

nc[*] = ptr;

// write data to data2

nc.variable("data2");

a = matrix("double", 19, 36);
a.fill(0, 1);
[ptr, n, e] = a.ptr();

nc[*] = ptr;

// show netCDF structure

nc.info();

/////////////////////// example for reading /////////////////////////

load("matrix", "netcdf.dll");

nc = netcdf("test.nc");

// get and display attributes of lat

nc.variable("lat");
csv(nc.unit);
csv(nc.range);

// get and display data of data1

nc.variable("data1");
csv(nc.size());
[m,n] = nc.dims();
a = matrix("short", m, n);
a.import(nc[*]);
a.print();