candiscreate, candiscomment, candisparam, candisdim, candisidim, dcandisidim, candisfld, dcandisfld, candiswrite, candisread, candiscinfo, candispinfo, candisdinfo, candisfinfo, candiscget, candispnameget, candispvalget, candisdnameget, candisdsizeget, candisdvalsget, candisfnameget, candisfsizeget, candisfndimget, candisfdimsget, candisfvalsget: High level routines to read and write a one-variable-slice Candis file
#include
<stdio.h>
#include <quickcandis.h>
This set of routines makes it easy to read and write Candis files containing only one variable slice. Each dimension is created with an index field, and only index fields are put in the static slice. Only evenly spaced index fields are created. The routines are found in "libcdf.a".
For writing files:
int
candiscreate(file_name,instance)
char *file_name;
int instance;
This routine opens a file of the specified name with "instance" as a suffix, and initializes a null Candis header. If the file name is "-", the result is sent to the standard output. The routine returns an integer "file handle", which must be used in all subsequent calls on this file.
int
candiscomment(handle,comment)
int handle;
char *comment;
This routine adds the specified comment to the header of the file specified by the file handle. The file handle is returned.
int
candisparam(handle,parameter,value)
int handle;
char *parameter;
float value;
This routine adds the specified parameter name and value to the header of the file specified by the file handle. The file handle is returned. Notice that parameter values are of type float. Thus, non-float parameters cannot be accomodated. However, since most parameters are of float or int type, this saves the trouble of converting the parameter to an ascii string. The file handle is returned.
int
candisdim(handle,dim_name,size,start_val,increment)
int handle;
char *dim_name;
long size;
float start_val;
float increment;
This routine specifies a dimension and creates the associated index parameters and index field for the file specified by the file handle. The dimension is given the name "dim_name", and has "size" points located at "start_val + increment*loop", where loop = 0, 1, ... , size - 1. Notice that irregularly spaced grid points are not accomodated. A "dimension handle" is returned, which must be used in the "candisfld" or "dcandisfld" call.
int
candisidim(handle,dim_name,size,data)
int handle;
char *dim_name;
long size;
float *data;
This routine is like candisdim except that instead of specifying a start value and increment for the grid point values, the actual values are specified in "data". Thus, irregularly spaced grid points can be accomodated by this routine.
int
dcandisidim(handle,dim_name,size,data)
int handle;
char *dim_name;
long size;
double *data;
This routine is like candisidim except that the data are type double. They is converted into type float internally.
int
candisfld(handle,field_name,num_dims,dh1,dh2,dh3,dh4,data_pointer)
int handle;
char *field_name;
int num_dims;
int dh1,dh2,dh3,dh4;
float *data_pointer;
This routine adds the field description for the field named "field_name" to the header specified by the file handle. It also transfers the field data in the 1-D float array "data_pointer" to an internal buffer. The number of dimensions in the field is given by "num_dims", while the size of each dimension is obtained from previous calls to "candisdim", which return the dimension handles "dh1, ...". Only as many dimension handles are needed as there are dimensions, but unused dimension handles must have their place held by zeros. The file handle is returned.
int
dcandisfld(handle,field_name,num_dims,dh1,dh2,dh3,dh4,data_pointer)
int handle;
char *field_name;
int num_dims;
int dh1,dh2,dh3,dh4;
double *data_pointer;
This routine is just like "candisfld" except that it handles double precision input fields, converting them to single precision.
int
candiswrite(handle)
int handle;
This routine writes the file specified by the file handle to disk, closes the file, and frees the space occupied by data buffers. It returns the file handle.
For reading files:
int
candisread(filename)
char *filename;
This routine reads in a complete Candis file, assumed to contain only a single variable slice. It returns a file handle which must be used in the following calls, which extract information from this file.
int
candiscinfo(handle)
int handle;
This routine returns the number of comment lines in the Candis file defined by the file handle returned by candisread.
int
candispinfo(handle)
int handle;
This routine returns the number of parameters in the Candis file defined by the file handle returned by candisread.
int
candisdinfo(handle)
int handle;
This routine returns the number of dimensions in the Candis file defined by the file handle returned by candisread.
int
candisfinfo(handle)
int handle;
This routine returns the number of variable fields in the Candis file defined by the file handle returned by candisread.
char
*candiscget(handle,i)
int handle;
int i;
This routine returns the ith comment line in the Candis file defined by the file handle returned by candisread. If i is out of range, the routine fails with an error message.
char
*candispnameget(handle,i)
int handle;
int i;
This routine returns the ith parameter name in the Candis file defined by the file handle returned by candisread. If i is out of range, the routine fails with an error message.
float
candispvalget(handle,i)
int handle;
int i;
This routine returns the ith parameter value in the Candis file defined by the file handle returned by candisread. If i is out of range, the routine fails with an error message.
char
*candisdnameget(handle,i)
int handle;
int i;
This routine returns the ith dimension name in the Candis file defined by the file handle returned by candisread. If i is out of range, the routine fails with an error message.
long
candisdsizeget(handle,i)
int handle;
int i;
This routine returns the ith dimension size in the Candis file defined by the file handle returned by candisread. If i is out of range, the routine fails with an error message.
float
*candisdvalsget(handle,i)
int handle;
int i;
This routine returns the ith dimension’s values in the Candis file defined by the file handle returned by candisread. If i is out of range, the routine fails with an error message.
char
*candisfnameget(handle,i)
int handle;
int i;
This routine returns the ith variable field’s name in the Candis file defined by the file handle returned by candisread. If i is out of range, the routine fails with an error message.
long
candisfsizeget(handle,i)
int handle;
int i;
This routine returns the ith variable field’s total size in the Candis file defined by the file handle returned by candisread. If i is out of range, the routine fails with an error message.
int
candisfndimget(handle,i)
int handle;
int i;
This routine returns the ith variable field’s number of dimensions in the Candis file defined by the file handle returned by candisread. If i is out of range, the routine fails with an error message.
int
*candisfdimsget(handle,i)
int handle;
int i;
This routine returns the ith variable field’s list of dimensions in the Candis file defined by the file handle returned by candisread. If i is out of range, the routine fails with an error message.
float
*candisfvalsget(handle,i)
int handle;
int i;
This routine returns the ith variable field’s values in the Candis file defined by the file handle returned by candisread. If i is out of range, the routine fails with an error message.
The following program fragment creates a Candis file.
#define NX 25
#define NY 21
float a[NX*NY];
float b[NX];
float c[NY];
int ix,iy;
int fh,dh1,dh2;
for (ix = 0; ix
< NX; ix++) {
for (iy = 0; iy < NY; iy++) {
a[iy + NY*ix] = ...;
}
b[ix] = ...;
}
for (iy = 0; iy < NY; iy++) {
c[iy] = ...;
}
fh =
candiscreate("candisfile");
fh = candiscomment(fh,"This is a comment");
fh = candisparam(fh,"badlim",1.e10);
dh1 = candisdim(fh,"east",NX,-30.,5.);
dh2 = candisdim(fh,"north",NY,25.,5.);
candisfld(fh,"a",2,dh1,dh2,0,0,a);
candisfld(fh,"b",1,dh1,0,0,0,b);
candisfld(fh,"c",1,dh2,0,0,0,c);
candiswrite(fh);
The following program replicates a Candis file:
/* replicate.c -- Read a file and write it */
#include
<stdio.h>
#include <quickcandis.h>
char
*cline,*pname,*dname,*fname;
float pval,*dvals,*fvals;
int nclines,nparams,ndims,nfields,nfdim,*dims;
long dsize,fsize;
main()
{
long i;
int inh,outh;
inh =
candisread("-");
outh = candiscreate("-",0);
nclines =
candiscinfo(inh);
nparams = candispinfo(inh);
ndims = candisdinfo(inh);
nfields = candisfinfo(inh);
for (i = 0; i
< nclines; i++) {
cline = candiscget(inh,i);
outh = candiscomment(outh,cline);
}
for (i = 0; i
< nparams; i++) {
pname = candispnameget(inh,i);
pval = candispvalget(inh,i);
outh = candisparam(outh,pname,pval);
}
for (i = 0; i
< ndims; i++) {
dname = candisdnameget(inh,i);
dsize = candisdsizeget(inh,i);
dvals = candisdvalsget(inh,i);
outh = candisidim(outh,dname,dsize,dvals);
}
for (i = 0; i
< nfields; i++) {
fname = candisfnameget(inh,i);
fsize = candisfsizeget(inh,i);
nfdim = candisfndimget(inh,i);
dims = candisfdimsget(inh,i);
fvals = candisfvalsget(inh,i);
outh = candisfld(outh,fname,nfdim,
dims[0],dims[1],dims[2],dims[3],fvals);
}
candiswrite(outh);
exit(0);
}
Only one Candis file can (presently) be open at a time for input and one for output.
Candisread ignores non-index static fields.
Candisdim and candisidim add index parameters even if this duplicates existing parameters.