Contact: zegraph  @  yahoo.com      Last update: January 2020

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; however, in practice other types of attributes are hardly used.

Function Parameter Type Remark
netcdf(filename[,mode]) string, string Opens a file and returns a netCDF object if successful; returns null otherwise. The optional mode determines witting or creation ("w"), or reading ("r"). The default mode is reading.
.version()   Returns the netCDF library version as string.
.close()   Closes the opened file.
.defdim(name, size) string, integer Defines dimension of the specified name and returns the dimension 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 variable of the specified name. The type parameter should be "char" (or "byte"), "short", "int", "float", or "double". The number of augments after type determines the number of dimensions. Each dimension size is determined by the dimension size of the specified dimension ID. If the unlimited dimension id is used, it must be given by dimid0.
.variable(name) string Sets the named variable as the target for reading and writing. It returns a negative value if the variable does not exit or the 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 if it has more than one dimensions, or returns an integer.
.attribute(name, i, value) string, integer, number Sets the value to the ith element of the named array attribute.
.das(callback) user Calls the callback function with the the dataset attribute structure parematers. For each variable and each attribute in a variable, the callback gets 8 parameters for variable id, attribute id, variable name, variable type, attribute name, attribute type, attribute length, and a pointer to attribute data.
.dds(callback) user Calls the callback function with the the dataset descriptor structure parematers. For each variable, the callback gets 6 parameters for variable id, variable name, variable type, number of dimensions, an integer pointer to dimention ids, and an unsigned integer pointer to dimension sizes, respectively.
.info([fname]) string Displays structure of the opened netCDF file. If the file name fname is given, results will be saved to the file.
.__get(name) string To be called by such an expression as cdf.name to get an attribute of the target variable. It may returns a string, an integer, a real, or an array of integer or real, depending on the 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 variable. A null index (may be represented by *) specifies reading all data in that dimension; an integer index (must be positive) specifies reading a position in that dimension; and a range index (e.g., 1:5) specifies reading a 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 of number or user To be called by such an expression as cdf[*,1]=data to write data to the target variable. If data is a user type, you are responsible to ensure that its pointer points to correct type and number of data.

netCDF Example

///// Example-1 /////

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

// create a netcdf file

nc = netcdf("test.cdf", "w");

// global attribute must be set before defining any variable

nc.g_att = "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.units = "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 time

nc.variable("time");

for (i=0; i<10; i++) {
    nc[i] = i;
}

// 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 data2

nc.variable("data2");

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

for (i=0; i<10; i++) {
    nc[i,*,*] = ptr;
}

// show netCDF structure

nc.info();

///// Example-2 /////

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

// open a netcdf file

nc = netcdf("test.cdf");

// get and display attributes of lat

nc.variable("lat");
csv(nc.units);
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.csv();