|
|
|||
|
||||
Variables for a netCDF file are defined when the file is created, while the netCDF file is in define mode. Other variables may be added later by reentering define mode. A netCDF variable has a name, a type, and a shape, which are specified when it is defined. A variable may also have values, which are established later in data mode.
Ordinarily, the name, type, and shape are fixed when the variable is first defined. The name may be changed, but the type and shape of a variable cannot be changed. However, a variable defined in terms of the unlimited dimension can grow without bound in that dimension.
A netCDF variable in an open netCDF file is referred to in the C and FORTRAN interfaces by a small integer called a variable ID. Variable IDs reflect the order in which variables were defined within an netCDF file. In the C interface, variable IDs are 0, 1, 2, ..., whereas in the FORTRAN interface, they are instead 1, 2, 3, ..., in the order in which the variables were defined. A function is available in each interface for getting the variable ID from the variable name and vice-versa.
Attributes (see section Attributes) may be associated with a variable to specify such properties as units.
Operations supported on variables are:
The following table gives the correspondence between netCDF data types and C and FORTRAN data types:
netCDF/ | C | FORTRAN | CDL Data | Data API | Data API | Type | Type Mnemonic | Type Mnemonic |Bits ---------|--------------------|--------------------------------------|---- byte | char NC_BYTE | BYTE, LOGICAL*1 (INTEGER) NCBYTE | 8 char | char NC_CHAR | CHARACTER NCCHAR | 8 short | short NC_SHORT | INTEGER*2 (INTEGER) NCSHORT | 16 long | nclong NC_LONG | INTEGER*4 (INTEGER) NCLONG | 32 float | float NC_FLOAT | REAL*4 (REAL) NCFLOAT | 32 double | double NC_DOUBLE | REAL*8 (DOUBLEPRECISION) NCDOUBLE | 64
The first column gives the netCDF data type, which is the same as the CDL data
type. The next pair of columns give, respectively, the C data type corresponding
to the first column and the corresponding C preprocessor macro for use in netCDF
functions (the preprocessor macros are defined in the netCDF C header-file netcdf.h).
The next pair of columns give, respectively, the FORTRAN data type corresponding
to the first column and the corresponding FORTRAN parameter for use when calling
netCDF routines (the parameters are defined in the netCDF FORTRAN include-file
netcdf.inc). You should use the un-parenthesized FORTRAN types
if possible. For any type that your FORTRAN compiler doesn't support, use
the corresponding parenthesized type. The last column gives the number of bits
used in the external representation of values of the corresponding type.
Note that the C data type corresponding to a netCDF long is nclong.
This type should be used rather than int or long.
It is defined in the netCDF header-file netcdf.h, where it is set
to the appropriate type.
Note that there are no netCDF types corresponding to 64-bit integers or to wide characters in the current version of the netCDF library.
The function ncvardef
(or NCVDEF for FORTRAN) adds a new variable to an open netCDF file
in define mode. It returns a variable ID, given the netCDF ID, the variable
name, the variable type, the number of dimensions, and a list of the dimension
IDs.
In case of an error, ncvardef
returns -1; NCVDEF returns a nonzero value in rcode.
Possible causes of errors include:
MAX_VAR_DIMS, the maximum number of dimensions permitted for
a netCDF variable.
int ncvardef(int ncid, const char* name, nc_type datatype,
int ndims, const int dimids[]);
ncidncopen or nccreate.namedatatypenc_type, is defined in the netCDF header file. The valid netCDF
data types are NC_BYTE, NC_CHAR, NC_SHORT,
NC_LONG, NC_FLOAT, and NC_DOUBLE. ndims2 specifies
a matrix, 1 specifies a vector, and 0 means the
variable is a scalar with no dimensions. Must not be negative or greater than
the predefined constant MAX_VAR_DIMS.dimidsndims dimension IDs corresponding to the variable
dimensions. If the ID of the unlimited dimension is included, it must be first.
This argument is ignored if ndims is 0. Here is an example using ncvardef
to create a variable named rh of type long with three
dimensions, time, lat, and lon in a new
netCDF file named `foo.nc':
#include <netcdf.h>
...
int ncid; /* netCDF ID */
int lat_dim, lon_dim, time_dim; /* dimension IDs */
int rh_id; /* variable ID */
int rh_dimids[3]; /* variable shape */
...
ncid = nccreate("foo.nc", NC_CLOBBER);
...
/* define dimensions */
lat_dim = ncdimdef(ncid, "lat", 5L);
lon_dim = ncdimdef(ncid, "lon", 10L);
time_dim = ncdimdef(ncid, "time", NC_UNLIMITED);
...
/* define variable */
rh_dimids[0] = time_dim;
rh_dimids[1] = lat_dim;
rh_dimids[2] = lon_dim;
rh_id = ncvardef (ncid, "rh", NC_DOUBLE, 3, rh_dimids);
INTEGER FUNCTION NCVDEF(INTEGER NCID, CHARACTER*(*) VARNAM,
+ INTEGER VARTYP, INTEGER NVDIMS,
+ INTEGER VDIMS(*), INTEGER RCODE)
NCIDNCOPN or NCCRE.VARNAMVARTYPNCBYTE, NCCHAR, NCSHORT, NCLONG,
NCFLOAT, and NCDOUBLE. NVDIMS2 specifies
a matrix, 1 specifies a vector, and 0 means the
variable is a scalar with no dimensions. Must not be negative or greater than
the predefined constant MAXVDIMS.VDIMSNVDIMS dimension IDs corresponding to the variable
dimensions. If the ID of the unlimited dimension is included, it must be last.
This argument is ignored if NVDIMS is 0.RCODE Here is an example using NCVDEF
to create a variable named rh of type long with three
dimensions, time, lat, and lon in a new
netCDF file named `foo.nc':
INCLUDE 'netcdf.inc'
...
INTEGER NCID, RCODE
INTEGER LATDIM, LONDIM, TIMDIM ! dimension IDs
INTEGER RHID ! variable ID
INTEGER RHDIMS(3) ! variable shape
...
NCID = NCCRE ('foo.nc', NC_CLOBBER, RCODE)
...
! define dimensions
LATDIM = NCDDEF(NCID, 'lat', 5, RCODE)
LONDIM = NCDDEF(NCID, 'lon', 10, RCODE)
TIMDIM = NCDDEF(NCID, 'time', NCUNLIM, RCODE)
...
! define variable
RHDIMS(1) = LONDIM
RHDIMS(2) = LATDIM
RHDIMS(3) = TIMDIM
RHID = NCVDEF (NCID, 'rh', NCDOUBLE, 3, RHDIMS, RCODE)
The function ncvarid (or NCVID for
FORTRAN) returns the ID of a netCDF variable, given its name.
In case of an error, ncvarid returns -1; NCVID returns
a nonzero value in rcode. Possible causes of errors include:
int ncvarid(int ncid, const char* name);
ncidncopen or nccreate.name Here is an example using ncvarid
to find out the ID of a variable named rh in an existing netCDF
file named `foo.nc':
#include <netcdf.h>
...
int ncid; /* netCDF ID */
int rh_id; /* variable ID */
...
ncid = ncopen("foo.nc", NC_NOWRITE);
...
rh_id = ncvarid (ncid, "rh");
INTEGER FUNCTION NCVID(INTEGER NCID,
+ CHARACTER*(*) VARNAM,
+ INTEGER RCODE)
NCIDNCOPN or NCCRE.VARNAMRCODE Here is an example using NCVID
to find out the ID of a variable named rh in an existing netCDF
file named `foo.nc':
INCLUDE 'netcdf.inc'
...
INTEGER NCID, RCODE
INTEGER RHID ! variable ID
...
NCID = NCOPN ('foo.nc', NCNOWRIT, RCODE)
...
RHID = NCVID (NCID, 'rh', RCODE)
The function ncvarinq (or NCVINQ
for FORTRAN) returns information about a netCDF variable, given its ID. The
information returned is the name, type, number of dimensions, a list of dimension
IDs describing the shape of the variable, and the number of variable attributes
that have been assigned to the variable.
In case of an error, ncvarinq returns -1; NCVINQ
returns a nonzero value in rcode. Possible causes of errors include:
int ncvarinq(int ncid, int varid, char* name, nc_type* datatype,
int* ndims, int dimids[], int* natts);
ncidncopen or nccreate.varidnameMAX_NC_NAME. If the name parameter
is given as `0' (a null pointer), no name will be returned
so no space needs to be allocated.datatypenc_type, is defined in the netCDF
header file. The valid netCDF data types are NC_BYTE, NC_CHAR,
NC_SHORT, NC_LONG, NC_FLOAT, and NC_DOUBLE.
If this parameter is given as `0' (a null pointer), no type
will be returned so no variable to hold the type needs to be declared.ndims2 specifies a matrix, 1 specifies a vector, and
0 means the variable is a scalar with no dimensions. If this
parameter is given as `0' (a null pointer), no number of
dimensions will be returned so no variable to hold this information needs
to be declared. dimidsndims dimension IDs corresponding to the
variable dimensions. The caller must allocate enough space for a vector of
at least ndims integers to be returned. The maximum possible
number of dimensions for a variable is given by the predefined constant MAX_VAR_DIMS.
If this parameter is given as `0' (a null pointer), no vector
will be returned so no space to hold the dimension IDs needs to be declared
or allocated.natts Here is an example using ncvarinq
to find out about a variable named rh in an existing netCDF file
named `foo.nc':
#include <netcdf.h>
...
int ncid; /* netCDF ID */
int rh_id; /* variable ID */
nc_type rh_type; /* variable type */
int rh_ndims; /* number of dims */
int rh_dims[MAX_VAR_DIMS]; /* variable shape */
int rh_natts /* number of attributes */
...
ncid = ncopen ("foo.nc", NC_NOWRITE);
...
rh_id = ncvarid (ncid, "rh");
/* we don't need name, since we already know it */
ncvarinq (ncid, rh_id, 0, &rh_type, &rh_ndims, rh_dims, &rh_natts);
SUBROUTINE NCVINQ (INTEGER NCID, INTEGER VARID,
+ CHARACTER*(*) VARNAM, INTEGER VARTYP,
+ INTEGER NVDIMS, INTEGER VDIMS(*),
+ INTEGER NVATTS, INTEGER RCODE)
NCIDNCOPN or NCCRE.VARIDVARNAMMAXNCNAM.VARTYPNCBYTE, NCCHAR,
NCSHORT, NCLONG, NCFLOAT, and NCDOUBLE.NVDIMS2
specifies a matrix, 1 specifies a vector, and 0
means the variable is a scalar with no dimensions.
VDIMSNVDIMS dimension IDs corresponding to the
variable dimensions. The caller must allocate enough space for a vector of
at least NVDIMS integers to be returned. The maximum possible
number of dimensions for a variable is given by the predefined constant MAXVDIMS.NVATTSRCODE Here is an example using NCVINQ
to find out about a variable named rh in an existing netCDF file
named `foo.nc':
INCLUDE 'netcdf.inc'
...
INTEGER NCID, RCODE
INTEGER RHID ! variable ID
CHARACTER*31 RHNAME ! variable name
INTEGER RHTYPE ! variable type
INTEGER RHN ! number of dimensions
INTEGER RHDIMS(MAXVDIMS) ! variable shape
INTEGER RHNATT ! number of attributes
...
NCID = NCOPN ('foo.nc', NCNOWRIT, RCODE)
...
RHID = NCVID (NCID, 'rh', RCODE) ! get ID
CALL NCVINQ (NCID, RHID, RHNAME, RHTYPE, RHN, RHDIMS, RHNATT,
+ RCODE)
The function ncvarput1
(or NCVPT1 or NCVP1C for FORTRAN) puts a single data
value into a variable of an open netCDF file that is in data mode. Inputs are
the netCDF ID, the variable ID, a multidimensional index that specifies which
value to add or alter, and the data value.
In case of an error, ncvarput1 returns -1; NCVPT1
returns a nonzero value in rcode. Possible causes of errors include:
int ncvarput1(int ncid, int varid, const long mindex[], const void *value);
ncidncopen or nccreate.varidmindex(0,0). The elements of mindex
must correspond to the variable's dimensions. Hence, if the variable is
a record variable, the first index would correspond to the record number.valuevoid * because it can point to data of any of the basic
netCDF types. The data should be of the appropriate type for the netCDF variable.
Warning: neither the compiler nor the netCDF software can detect whether
the wrong type of data is used. Here is an example using ncvarput1
to set the (1,2,3) element of the variable named rh
to 0.5 in an existing netCDF file named `foo.nc'.
For simplicity in this example, we assume that we know that rh
is dimensioned with time, lat, and lon,
so we want to set the value of rh that corresponds to the second
time value, the third lat value, and the fourth lon
value:
#include <netcdf.h>
...
int ncid; /* netCDF ID */
int rh_id; /* variable ID */
static long rh_index[] = {1, 2, 3}; /* where to put value */
static double rh_val = 0.5; /* value to put */
...
ncid = ncopen("foo.nc", NC_WRITE);
...
rh_id = ncvarid (ncid, "rh");
...
ncvarput1(ncid, rh_id, rh_index, &rh_val);
SUBROUTINE NCVPT1 (INTEGER NCID, INTEGER VARID,
+ INTEGER MINDEX(*), type VALUE,
+ INTEGER RCODE)
SUBROUTINE NCVP1C (INTEGER NCID, INTEGER VARID,
+ INTEGER MINDEX(*), CHARACTER CHVAL,
+ INTEGER RCODE)
There are two FORTRAN subroutines, NCVPT1 and NCVP1C,
for putting a single value in a variable. The first puts a numeric value in
a variable of numeric type, and the second puts a character value in a variable
of character type.
NCIDNCOPN or NCCRE.VARIDMINDEX(1,1). The elements of mindex
must correspond to the variable's dimensions. Hence, if the variable is
a record variable, the last index would correspond to the record number.VALUENCVPT1, the data value to be written. The data may be of
a type corresponding to any of the netCDF types NCSHORT, NCLONG,
NCFLOAT, or NCDOUBLE, but must be appropriate for
the type of the netCDF variable. Warning: neither the compiler nor
the netCDF software can detect whether the wrong type of data is used.CHVALNCVP1C, the data value to be written. The data should be
of a type character, corresponding to the netCDF types NCCHAR
or NCBYTE.RCODE Here is an example using NCVPT1
to set the (4,3,2) element of the variable named rh
to 0.5 in an existing netCDF file named `foo.nc'.
For simplicity in this example, we assume that we know that rh
is dimensioned with lon, lat, and time,
so we want to set the value of rh that corresponds to the fourth
lon value, the third lat value, and the second time
value:
INCLUDE 'netcdf.inc'
...
INTEGER NCID, RCODE
INTEGER RHID ! variable ID
INTEGER RHINDX(3) ! where to put value
DATA RHINDX /4, 3, 2/
...
NCID = NCOPN ('foo.nc', NCWRITE, RCODE)
...
RHID = NCVID (NCID, 'rh', RCODE) ! get ID
CALL NCVPT1 (NCID, RHID, RHINDX, 0.5, RCODE)
The function ncvarput
(or NCVPT or NCVPTC for FORTRAN) writes values into
a netCDF variable of an open netCDF file. The part of the netCDF variable to
write is specified by giving a corner and a vector of edge lengths that refer
to an array section of the netCDF variable. The values to be written are associated
with the netCDF variable by assuming that the last dimension of the netCDF variable
varies fastest in the C interface, whereas the first dimension of the netCDF
variable varies fastest in the FORTRAN interface. The netCDF file must be in
data mode. (3)
In case of an error, ncvarput returns -1; NCVPT returns
a nonzero value in rcode. Possible causes of errors include:
int ncvarput(int ncid, int varid, const long start[], const long count[],
const void *values);
ncidncopen or nccreate.varidstart(0,
0, ..., 0). The size of start must be the same as the
number of dimensions of the specified variable. The elements of start
must correspond to the variable's dimensions in order. Hence, if the variable
is a record variable, the first index would correspond to the starting record
number for writing the data values.countcount as (1, 1, ..., 1). The size of count
is the number of dimensions of the specified variable. The elements of count
correspond to the variable's dimensions. Hence, if the variable is a record
variable, the first element of count corresponds to a count of
the number of records to write.valuevoid * because it can point to data of any of the basic
netCDF types. The data should be of the appropriate type for the netCDF variable.
Warning: neither the compiler nor the netCDF software can detect whether
the wrong type of data is used. Here is an example using ncvarput
to add or change all the values of the variable named rh to 0.5
in an existing netCDF file named `foo.nc'. For simplicity in this
example, we assume that we know that rh is dimensioned with time,
lat, and lon, and that there are three time
values, five lat values, and ten lon values.
#include <netcdf.h>
...
#define TIMES 3
#define LATS 5
#define LONS 10
int ncid; /* netCDF ID */
int rh_id; /* variable ID */
static long start[] = {0, 0, 0}; /* start at first value */
static long count[] = {TIMES, LATS, LONS};
double rh_vals[TIMES*LATS*LONS]; /* array to hold values */
int i;
...
ncid = ncopen("foo.nc", NC_WRITE);
...
rh_id = ncvarid (ncid, "rh");
...
for (i = 0; i < TIMES*LATS*LONS; i++)
rh_vals[i] = 0.5;
/* write values into netCDF variable */
ncvarput(ncid, rh_id, start, count, rh_vals);
SUBROUTINE NCVPT (INTEGER NCID, INTEGER VARID,
+ INTEGER START(*), INTEGER COUNT(*),
+ type VALUES, INTEGER RCODE)
SUBROUTINE NCVPTC(INTEGER NCID, INTEGER VARID,
+ INTEGER START(*), INTEGER COUNTS(*),
+ CHARACTER*(*) STRING, INTEGER LENSTR,
+ INTEGER RCODE)
There are two FORTRAN subroutines, NCVPT and NCVPTC,
for writing an array of values into a netCDF variable. The first writes numeric
values into a variable of numeric type, and the second writes character values
into a variable of character type.
NCIDNCOPN or NCCRE.VARIDSTART(1, 1,
..., 1). The size of START must be the same as the number
of dimensions of the specified variable. The elements of START
must correspond to the variable's dimensions in order. Hence, if the variable
is a record variable, the last index would correspond to the starting record
number for writing the data values.COUNTCOUNT as (1, 1, ..., 1). The size of COUNT
is the number of dimensions of the specified variable. The elements of COUNT
correspond to the variable's dimensions. Hence, if the variable is a record
variable, the last element of COUNT corresponds to a count of
the number of records to write.VALUESNCVPT, the block of data values to be written. The order
in which the data will be written into the specified variable is with the
first dimension varying fastest (like the ordinary FORTRAN convention). The
data may be of a type corresponding to any of the netCDF types NCSHORT,
NCLONG, NCFLOAT, or NCDOUBLE, but must
be appropriate for the type of the netCDF variable. Warning: neither
the compiler nor the netCDF software can detect whether the wrong type of
data is used.STRINGNCVPTC, the characters to be written. The order in which
the characters will be written to the netCDF variable is with the first dimension
of the specified variable varying fastest (like the FORTRAN convention). The
data may be of a type corresponding to the netCDF types NCCHAR
or NCBYTE.LENSTRNCVPTC, the total declared length (in characters) of the
STRING argument. This should be at least as large as the product
of the elements of the COUNT vector. Note that this is not necessarily
the same as the value returned by the FORTRAN LEN function, because
an array argument may be provided.RCODE Here is an example using NCVPT
to add or change all the values of the variable named rh to 0.5
in an existing netCDF file named `foo.nc'. For simplicity in this
example, we assume that we know that rh is dimensioned with lon,
lat, and time, and that there are ten lon
values, five lat values, and three time values.
INCLUDE 'netcdf.inc'
...
PARAMETER (NDIMS=3) ! number of dimensions
PARAMETER (TIMES=3, LATS=5, LONS=10) ! dimension sizes
INTEGER NCID, RCODE, TIMES
INTEGER RHID ! variable ID
INTEGER START(NDIMS), COUNT(NDIMS)
DOUBLE RHVALS(LONS, LATS, TIMES)
DATA START /1, 1, 1/ ! start at first value
DATA COUNT /LONS, LATS, TIMES/
...
NCID = NCOPN ('foo.nc', NCWRITE, RCODE)
...
RHID = NCVID (NCID, 'rh', RCODE) ! get ID
DO 10 ILON = 1, LONS
DO 10 ILAT = 1, LATS
DO 10 ITIME = 1, TIMES
RHVALS(ILON, ILAT, ITIME) = 0.5
10 CONTINUE
CALL NCVPT (NCID, RHID, START, COUNT, RHVALS, RCODE)
The function ncvarputg
(or NCVPTG or NCVPGC for FORTRAN) writes a subsampled
or mapped array section of values into a netCDF variable of an open netCDF file.
The subsampled or mapped array section is specified by giving a corner, a vector
of counts, a stride vector, and an index mapping vector. No assumptions are
made about the ordering or size of the dimensions of the data array. The netCDF
file must be in data mode.
In case of an error, ncvarputg returns -1; NCVPTG
and NCVPGC return a nonzero value in rcode. Possible
causes of errors include:
int ncvarputg(int ncid, int varid, const long start[], const long count[],
const long stride[], const long imap[], const void *values);
ncidncopen or nccreate.varidstart(0,
0, ..., 0). The elements of start correspond, in order,
to the variable's dimensions. Hence, if the variable is a record variable,
the first index corresponds to the starting record number for writing the
data values.countcount
as (1, 1, ..., 1). The elements of count correspond,
in order, to the variable's dimensions. Hence, if the variable is a record
variable, the first element of count corresponds to a count of
the number of records to write.strideNULL stride argument is treated as (1, 1,
..., 1).imapvalue argument to
a particular datum is given by the inner product of the index mapping vector
with the indices of the imaginary internal array which would be used if there
were no mapping. (The inner product of two vectors [x0, x1,
..., xn] and [y0, y1, ..., yn] is just x0*y0 + x1*y1 + ... + xn*yn.) The vector
may contain negative values if the value argument is appropriately
specified. A NULL argument obtains the default behavior in which
the memory-resident values are assumed to have the same structure as the associated
netCDF variable.valuevoid * because it can point to data of any of the basic
netCDF types. The data should be of the appropriate type for the netCDF variable.
Warning: neither the compiler nor the netCDF software can detect whether
the wrong type of data is used. Here is an example using ncvarputg
to add or change every other value in each dimension of the variable named rh
to 0.5 in an existing netCDF file named `foo.nc'.
Values are taken, using the same dimensional strides, from points in a 3-dimensional
array of structures whose dimensions are the reverse of the netCDF variable.
For simplicity in this example, we assume that we know that rh
is dimensioned with time, lat, and lon,
and that there are three time values, five lat values,
and ten lon values.
#include <netcdf.h>
...
#define TIMES 3
#define LATS 5
#define LONS 10
int ncid; /* netCDF ID */
int rh_id; /* variable ID */
static long start[] = {0, 0, 0}; /* start at first value */
static long count[] = {TIMES, LATS, LONS};
static long stride[] = {2, 2, 2}; /* every other value */
long imap[3]; /* set to reverse of variable */
struct datum {
int dummy; /* to illustrate mapping vector */
double rh_val; /* actual value to be written */
} data[LONS][LATS][TIMES]; /* reversed array to hold values. */
int itime, ilat, ilon;
...
ncid = ncopen("foo.nc", NC_WRITE);
...
rh_id = ncvarid (ncid, "rh");
...
for (ilon = 0; ilon < LONS; ilon += stride[2])
for (ilat = 0; ilat < LATS; ilat += stride[1])
for (itime = 0; itime < TIMES; itime += stride[0])
data[ilon][ilat][itime].rh_val = 0.5;
/* access every `stride' in-memory value using reversed dimensions */
imap[0] = stride[2]*sizeof(struct datum);
imap[1] = stride[1]*(1+(LONS-1)/stride[0])*imap[0];
imap[2] = stride[0]*(1+(LATS-1)/stride[1])*imap[1];
/* write subsampled or mapped array of values into netCDF variable */
ncvarputg(ncid, rh_id, start, count, stride, imap, &data[0][0][0].rh_val);
SUBROUTINE NCVPTG (INTEGER NCID, INTEGER VARID,
+ INTEGER START(*), INTEGER COUNT(*),
+ INTEGER STRIDE(*), INTEGER IMAP(*),
+ type VALUES, INTEGER RCODE)
SUBROUTINE NCVPGC (INTEGER NCID, INTEGER VARID,
+ INTEGER START(*), INTEGER COUNT(*),
+ INTEGER STRIDE(*), INTEGER IMAP(*),
+ CHARACTER*(*) STRING, INTEGER RCODE)
There are two FORTRAN subroutines, NCVPTG and NCVPGC,
for writing a subsampled or mapped array section of values into a netCDF variable.
The first writes numeric values into a variable of numeric type, and the second
writes character values into a variable of character type.
NCIDNCOPN or NCCRE.VARIDSTART(1, 1,
..., 1). The elements of START correspond, in order, to
the variable's dimensions. Hence, if the variable is a record variable,
the last index would correspond to the starting record number for writing
the data values.COUNTCOUNT
as (1, 1, ..., 1). The elements of COUNT correspond,
in order, to the variable's dimensions. Hence, if the variable is a record
variable, the last element of COUNT corresponds to a count of
the number of records to write.STRIDE0. The elements of the vector correspond,
in order, to the variable's dimensions. A value of 1 accesses adjacent
values of the netCDF variable in the corresponding dimension; a value of 2
accesses every other value of the netCDF variable in the corresponding dimension;
and so on. A 0 argument is treated as (1, 1, ..., 1).IMAP0.
The offset, in bytes, from the memory location pointed to by the value
argument to a particular datum is given by the inner product of the index
mapping vector with the (origin-0) indices of the imaginary internal array
which would be used if there were no mapping. (The inner product
of two vectors [x1, x2, ..., xn] and [y1, y2, ..., yn] is just x1*y1 + x2*y2
+ ... + xn*yn.) The vector may contain negative values if the value
argument is appropriately specified. A 0 argument obtains the
default behavior in which the internal (memory-resident) values are assumed
to have the same structure as the associated netCDF variable.VALUESNCVPTG, the block of data values to be written. The order
in which the data will be written is with the first dimension of the netCDF
variable varying fastest (like the ordinary FORTRAN convention). The data
may be of a type corresponding to any of the netCDF types NCSHORT,
NCLONG, NCFLOAT, or NCDOUBLE, but must
be appropriate for the type of the netCDF variable. Warning: neither
the compiler nor the netCDF software can detect whether the wrong type of
data is used.STRINGNCVPGC, the characters to be written. The order in which
the characters will be written to the netCDF variable is with the first dimension
of the subsampled or mapped array varying fastest (like the FORTRAN convention).
The data may be of a type corresponding to the netCDF types NCCHAR
or NCBYTE.RCODE Here is an example using NCVPTG
to add or change every other value in each dimension of the variable named rh
to 0.5 in an existing netCDF file named `foo.nc'.
Values are taken, using the same dimensional strides, from a 2-parameter array
whose dimensions are the reverse of the netCDF variable. For simplicity in this
example, we assume that we know that rh is dimensioned with lon,
lat, and time, and that there are ten lon
values, five lat values, and three time values.
INCLUDE 'netcdf.inc'
...
PARAMETER (NDIMS=3) ! number of dimensions
PARAMETER (TIMES=3, LATS=5, LONS=10) ! dimension sizes
INTEGER NCID, RCODE
INTEGER RHID ! variable ID
INTEGER START(NDIMS), COUNT(NDIMS),
+ STRIDE(NDIMS), IMAP(NDIMS) ! subsampled or mapped array
DOUBLE DATA(2, TIMES, LATS, LONS) ! rh is second parameter
DATA START /1, 1, 1/ ! start at first value
DATA COUNT /LONS, LATS, TIMES/
DATA STRIDE /2, 2, 2/
...
NCID = NCOPN ('foo.nc', NCWRITE, RCODE)
...
RHID = NCVID (NCID, 'rh', RCODE) ! get ID
DO 10 ILON = 1, LONGS, STRIDE(1)
DO 10 ILAT = 1, LATS, STRIDE(2)
DO 10 ITIME = 1, TIMES, STRIDE(3)
DATA(2, ITIME, ILAT, ILON) = 0.5
10 CONTINUE
IMAP(3) = 8*2*2 ! every other point of vector of 2-doubles
IMAP(2) = IMAP(3)*(1+(TIMES-1)/STRIDE(3))*2
IMAP(1) = IMAP(2)*(1+(LATS-1)/STRIDE(2))*2
CALL NCVPTG (NCID, RHID, START, COUNT, STRIDE, IMAP,
+ DATA(2,1,1,1), RCODE)
The function ncrecput
writes a multi-variable record of values (or part of a record of values) into
the record variables of an open netCDF file. The record is specified by giving
a (0-based) record number. The values to be written are specified by an array
of pointers, one for each record variable, to blocks of values. Each block of
values should be of the appropriate size and type for a record's worth of
data for the corresponding record variable. Each such pointer must be either
`0' (a null pointer), to indicate that no data is to be written
for that variable, or must point to an entire record's worth of data of
the appropriate type for the corresponding record variable. The values for each
record variable are assumed to be ordered with the last dimension varying fastest.
The netCDF file must be in data mode.
The ncrecput function is not strictly necessary, since the same
data may be written with a sequence of calls to ncvarput, one for
each record variable for which a non-null pointer is specified. This function
is provided in the C interface for convenience only; no corresponding FORTRAN
interface is available, so FORTRAN users should use multiple calls to NCVPT
or NCVPTC instead.
To use ncrecput properly, you must know the number, order, and
types of record variables in the netCDF file, information that can be determined
with a call to ncrecinq. If your assumptions about the number,
order, or types of record variables in the file is incorrect, calling this function
may lead to incorrect results or a memory access error. Warning: neither
the compiler nor the netCDF software can detect errors with the pointer array
argument to ncrecput.
In case of a detected error, ncrecput returns -1. Possible causes
of detectable errors include:
int ncrecput(int ncid, long recnum, const void *datap[]);
ncidncopen or nccreate.
recnum0. Note
that if you specify a value for recnum that is larger than the
current size of the unlimited dimension, intervening records will be written
with fill values before the data is written in the specified record, unless
ncsetfill has been called to specify no prefilling.datapdatap[i], if non-null, must point to an entire record's
worth of data for the i-th record variable. For null pointers,
no data will be written for the corresponding record variables. This permits
you to specify an arbitrary subset of record variables. The data pointed to
should be of the appropriate type for each record variable. Warning:
neither the compiler nor the netCDF software can detect whether the wrong
type of data is used. Here is an example using ncrecput
to write the value of a C struct into a netCDF file with a single call. This
example assumes that record variables of the appropriate shapes and types have
previously been created in the netCDF file.
#include <netcdf.h>
...
static struct {
char city[20];
nclong date;
float lat;
float lon;
float precip[24]; /* hourly precipitation */
} rec = {
"Pocatello",
930228,
42.92,
-112.60,
{0,0,.1,.2,.2,.3,.2,0,0,0,0,0,0,0,0,0,.3,1.1,0,0,0,0,0,0}
};
int ncid; /* id of open netcdf file */
long recnum; /* number of record to write */
void *datap[5]; /* array of address pointers for record
vars */
...
datap[0] = &rec.city[0];
datap[1] = &rec.date;
datap[2] = &rec.lat;
datap[3] = &rec.lon;
datap[4] = &rec.precip[0];
ncrecput(ncid, recnum, datap); /* instead of 5 calls to ncvarput */
The function ncvarget1
(or NCVGT1 or NCVG1C for FORTRAN) gets a single data
value from a variable of an open netCDF file that is in data mode. Inputs are
the netCDF ID, the variable ID, a multidimensional index that specifies which
value to get, and the address of a location into which the data value will be
read.
In case of an error, ncvarget1 returns -1; NCVGT1
returns a nonzero value in rcode. Possible causes of errors include:
int ncvarget1(int ncid, int varid, const long mindex[], void *value);
ncidncopen or nccreate.varidmindex(0,0). The elements of mindex
must correspond to the variable's dimensions. Hence, if the variable is
a record variable, the first index is the record number.valuevoid * because it can point to data
of any of the basic netCDF types. The data should be of the appropriate type
for the netCDF variable. Warning: neither the compiler nor the netCDF
software can detect whether the wrong type for the data value is used. Here is an example using ncvarget1
to get the (1,2,3) element of the variable named rh
in an existing netCDF file named `foo.nc'. For simplicity in this
example, we assume that we know that rh is dimensioned with time,
lat, and lon, so we want to get the value of rh
that corresponds to the second time value, the third lat
value, and the fourth lon value:
#include <netcdf.h>
...
int ncid; /* netCDF ID */
int rh_id; /* variable ID */
static long rh_index[] = {1, 2, 3}; /* where to get value from */
double rh_val; /* where to put it */
...
ncid = ncopen("foo.nc", NC_NOWRITE);
...
rh_id = ncvarid (ncid, "rh");
...
ncvarget1(ncid, rh_id, rh_index, &rh_val);
SUBROUTINE NCVGT1 (INTEGER NCID, INTEGER VARID,
+ INTEGER MINDEX(*), type VALUE,
+ INTEGER RCODE)
SUBROUTINE NCVG1C (INTEGER NCID, INTEGER VARID,
+ INTEGER MINDEX(*), CHARACTER CHVAL,
+ INTEGER RCODE)
There are two FORTRAN subroutines, NCVGT1 and NCVG1C,
for reading a single value from a variable. The first reads a numeric value
in a variable of numeric type, and the second reads a character value in a variable
of character type.
NCIDNCOPN or NCCRE.VARIDMINDEX(1,1). The elements of mindex
correspond to the variable's dimensions. Hence, if the variable is a record
variable, the last index is the record number.VALUENCVGT1, the location into which the data value will be
read. The data may be of a type corresponding to any of the netCDF types NCSHORT,
NCLONG, NCFLOAT, or NCDOUBLE, but must
be appropriate for the type of the netCDF variable. Warning: neither
the compiler nor the netCDF software can detect whether the wrong type of
data is used.CHVALNCVG1C, the location into which the data value will be
read. This should be of a type character, corresponding to the netCDF types
NCCHAR or NCBYTE.RCODE Here is an example using NCVGT1
to get the (4,3,2) element of the variable named rh
in an existing netCDF file named `foo.nc'. For simplicity in this
example, we assume that we know that rh is dimensioned with lon,
lat, and time, so we want to get the value of rh
that corresponds to the fourth lon value, the third lat
value, and the second time value:
INCLUDE 'netcdf.inc'
...
INTEGER NCID, RCODE
INTEGER RHID ! variable ID
INTEGER RHINDX(3) ! where to get value
DOUBLE PRECISION RHVAL ! put it here
DATA RHINDX /4, 3, 2/
...
NCID = NCOPN ('foo.nc', NCNOWRIT, RCODE)
...
RHID = NCVID (NCID, 'rh', RCODE) ! get ID
CALL NCVGT1 (NCID, RHID, RHINDX, RHVAL, RCODE)
The function ncvarget (or NCVGT or
NCVGTC for FORTRAN) reads an array of values from a netCDF variable
of an open netCDF file. The array is specified by giving a corner and a vector
of edge lengths. The values are read into consecutive locations with the last
(or first for FORTRAN) dimension varying fastest. The netCDF file must be in
data mode. (4)
In case of an error, ncvarget returns -1; NCVGT returns
a nonzero value in rcode. Possible causes of errors include:
int ncvarget(int ncid, int varid, const long start[], const long count[],
void *values);
ncidncopen or nccreate.varidstart(0, 0,
..., 0). The size of start must be the same as the number
of dimensions of the specified variable. The elements of start
correspond, in order, to the variable's dimensions. Hence, if the variable
is a record variable, the first index would correspond to the starting record
number for reading the data values.countcount as (1, 1, ..., 1). The size of count
is the number of dimensions of the specified variable. The elements of count
correspond, in order, to the variable's dimensions. Hence, if the variable
is a record variable, the first element of count corresponds
to a count of the number of records to read.valuevoid * because it can point to data of any of the basic
netCDF types. The data should be of the appropriate type for the netCDF variable.
Warning: neither the compiler nor the netCDF software can detect whether
the wrong type of data is used. Here is an example using ncvarget
to read all the values of the variable named rh from an existing
netCDF file named `foo.nc'. For simplicity in this example, we
assume that we know that rh is dimensioned with time,
lat, and lon, and that there are three time
values, five lat values, and ten lon values.
#include <netcdf.h>
...
#define TIMES 3
#define LATS 5
#define LONS 10
int ncid; /* netCDF ID */
int rh_id; /* variable ID */
static long start[] = {0, 0, 0}; /* start at first value */
static long count[] = {TIMES, LATS, LONS};
double rh_vals[TIMES*LATS*LONS]; /* array to hold values */
...
ncid = ncopen("foo.nc", NC_NOWRITE);
...
rh_id = ncvarid (ncid, "rh");
...
/* read values from netCDF variable */
ncvarget(ncid, rh_id, start, count, rh_vals);
SUBROUTINE NCVGT (INTEGER NCID, INTEGER VARID,
+ INTEGER START(*), INTEGER COUNT(*),
+ type VALUES, INTEGER RCODE)
SUBROUTINE NCVGTC(INTEGER NCID, INTEGER VARID,
+ INTEGER START(*), INTEGER COUNTS(*),
+ CHARACTER*(*) STRING, INTEGER LENSTR,
+ INTEGER RCODE)
There are two FORTRAN subroutines, NCVGT and NCVGTC,
for reading an array of values from a netCDF variable. The first reads numeric
values from a variable of numeric type, and the second reads character values
from a variable of character type.
NCIDNCOPN or NCCRE.VARIDSTART(1, 1, ..., 1).
The size of START must be the same as the number of dimensions
of the specified variable. The elements of START correspond,
in order, to the variable's dimensions. Hence, if the variable is a record
variable, the last index would correspond to the starting record number for
reading the data values.COUNTCOUNT as (1, 1, ..., 1). The size of COUNT
is the number of dimensions of the specified variable. The elements of COUNT
correspond, in order, to the variable's dimensions. Hence, if the variable
is a record variable, the last element of COUNT corresponds to
a count of the number of records to read.VALUESNCVGT, the locations into which the data values will be
read. The order in which the data will be read from the netCDF variable is
with the first dimension varying fastest (like the ordinary FORTRAN convention).
The data may be of a type corresponding to any of the netCDF types NCSHORT,
NCLONG, NCFLOAT, or NCDOUBLE, but must
be appropriate for the type of the netCDF variable. Warning: neither
the compiler nor the netCDF software can detect whether the wrong type of
data is used.STRINGNCVGTC, the character string into which the character data
will be read. The order in which the characters will be read from the netCDF
variable is with the first dimension varying fastest (like the FORTRAN convention).
The data may be of a type corresponding to the netCDF types NCCHAR
or NCBYTE.LENSTRNCVGTC, the total declared length (in characters) of the
STRING argument. This should be at least as large as the product
of the elements of the COUNT vector. Note that this is not necessarily
the same as the value returned by the FORTRAN LEN function, because
an array argument may be provided. NCVGTC will check to make
sure the requested data will fit in LENSTR characters.RCODE Here is an example using NCVGT
to read all the values of the variable named rh from an existing
netCDF file named `foo.nc'. For simplicity in this example, we
assume that we know that rh is dimensioned with lon,
lat, and time, and that there are ten lon
values, five lat values, and three time values.
INCLUDE 'netcdf.inc'
...
PARAMETER (NDIMS=3) ! number of dimensions
PARAMETER (TIMES=3, LATS=5, LONS=10) ! dimension sizes
INTEGER NCID, RCODE
INTEGER RHID ! variable ID
INTEGER START(NDIMS), COUNT(NDIMS)
DOUBLE RHVALS(LONS, LATS, TIMES)
DATA START /1, 1, 1/ ! start at first value
DATA COUNT /LONS, LATS, TIMES/
...
NCID = NCOPN ('foo.nc', NCNOWRIT, RCODE)
...
RHID = NCVID (NCID, 'rh', RCODE)! get ID
CALL NCVGT (NCID, RHID, START, COUNT, RHVALS, RCODE)
The function ncvargetg
(or NCVGTG or NCVGGC for FORTRAN) reads a subsampled
or mapped array section of values from a netCDF variable of an open netCDF file.
The subsampled or mapped array section is specified by giving a corner, a vector
of edge lengths, a stride vector, and an index mapping vector. The values are
read with the last (or first for FORTRAN) dimension of the netCDF variable varying
fastest. The netCDF file must be in data mode.
In case of an error, ncvargetg returns -1; NCVGTG
and NCVGGC return a nonzero value in rcode. Possible
causes of errors include:
int ncvargetg(int ncid, int varid, const long start[], const long count[],
const long stride[], const long imap[], void *values);
ncidncopen or nccreate.varidstart(0, 0,
..., 0). The elements of start correspond, in order, to
the variable's dimensions. Hence, if the variable is a record variable,
the first index corresponds to the starting record number for reading the
data values.countcount
as (1, 1, ..., 1). The elements of count correspond,
in order, to the variable's dimensions. Hence, if the variable is a record
variable, the first element of count corresponds to a count of
the number of records to read.strideNULL stride argument is treated as (1, 1, ...,
1).imapvalue argument to
a particular datum is given by the inner product of the index mapping vector
with the indices of the imaginary internal array which would be used if there
were no mapping. (The inner product of two vectors [x0, x1,
..., xn] and [y0, y1, ..., yn] is just x0*y0 + x1*y1 + ... + xn*yn.) The vector
may contain negative values if the value argument is appropriately
specified. A NULL argument obtains the default behavior in which
the memory-resident values are assumed to have the same structure as the associated
netCDF variable.valuevoid * because it can point to data of any of the basic
netCDF types. The data should be of the appropriate type for the netCDF variable.
Warning: neither the compiler nor the netCDF software can detect whether
the wrong type of data is used.As an example, let us define a C program to read the following netCDF file:
netcdf t {
dimensions:
D = 8 ;
variables:
short v(D) ;
data:
v = 10, 11, 12, 13, 14, 15, 16, 17 ;
}
The following program uses ncvargetg to read v[1]
into buf[2], v[3] into buf[1] and v[5]
into buf[0]:
#include <stdio.h>
#include "netcdf.h"
#define COUNT 3
int main()
{
int ncid;
int err;
int i;
int varid = 0;
long start[] = {1}
long count[] = {COUNT}
long stride[] = {2}
long imap[] = {-sizeof(short)}
short buf[COUNT];
ncid = ncopen("t.nc", NC_NOWRITE);
varid = ncvarid(ncid, "v");
err = ncvargetg(ncid, varid, start, count, stride, imap, &buf[COUNT-1]);
err = ncclose(ncid);
for (i = 0; i < COUNT; i++)
printf("buf[%d]: %d\n", i, buf[i]);
return 0;
}
This program prints the following:
buf[0]: 15 buf[1]: 13 buf[2]: 11
Here is another example which uses ncvargetg
to read every other value in each dimension of the variable named rh
from an existing netCDF file named `foo.nc'. Values are assigned,
using the same dimensional strides, to points in a 3-dimensional array of structures
whose dimensions are the reverse of the netCDF variable. For simplicity in this
example, we assume that we know that rh is dimensioned with time,
lat, and lon, and that there are three time
values, five lat values, and ten lon values.
#include <netcdf.h>
...
#define TIMES 3
#define LATS 5
#define LONS 10
int ncid; /* netCDF ID */
int rh_id; /* variable ID */
static long start[] = {0, 0, 0}; /* start at first value */
static long count[] = {TIMES, LATS, LONS};
static long stride[] = {2, 2, 2}; /* every other value */
long imap[3]; /* set to reverse of variable */
struct datum {
int dummy; /* to illustrate mapping vector usage */
double rh_val; /* actual value to be read */
} data[TIMES][LATS][LONS]; /* array to hold values */
...
ncid = ncopen("foo.nc", NC_NOWRITE);
...
rh_id = ncvarid (ncid, "rh");
...
/* access every `stride' in-memory value using reversed dimensions */
imap[0] = stride[2]*sizeof(struct datum);
imap[1] = stride[1]*(1+(LONS-1)/stride[0])*imap[0];
imap[2] = stride[0]*(1+(LATS-1)/stride[1])*imap[1];
/* read values from netCDF variable */
ncvargetg(ncid, rh_id, start, count, stride, imap, &data[0][0][0].rh_val);
...
SUBROUTINE NCVGTG (INTEGER NCID, INTEGER VARID,
+ INTEGER START(*), INTEGER COUNT(*),
+ INTEGER STRIDE(*), INTEGER IMAP(*),
+ type VALUES, INTEGER RCODE)
SUBROUTINE NCVGGC (INTEGER NCID, INTEGER VARID,
+ INTEGER START(*), INTEGER COUNT(*),
+ INTEGER STRIDE(*), INTEGER IMAP(*),
+ CHARACTER*(*) STRING, INTEGER RCODE)
There are two FORTRAN subroutines, NCVGTG and NCVGGC,
for reading a subsampled or mapped array section of values from a netCDF variable.
The first reads numeric values from a variable of numeric type, and the second
reads character values from a variable of character type.
NCIDNCOPN or NCCRE.VARIDSTART(1, 1,
..., 1). The elements of START correspond, in order, to
the variable's dimensions. Hence, if the variable is a record variable,
the last index would correspond to the starting record number for reading
the data values.COUNTCOUNT
as (1, 1, ..., 1). The elements of COUNT correspond,
in order, to the variable's dimensions. Hence, if the variable is a record
variable, the last element of COUNT corresponds to a count of
the number of records to read.STRIDE0. The elements of the vector correspond,
in order, to the variable's dimensions. A value of 1 accesses adjacent
values of the netCDF variable in the corresponding dimension; a value of 2
accesses every other value of the netCDF variable in the corresponding dimension;
and so on. A 0 argument is treated as (1, 1, ..., 1).IMAP0.
The offset, in bytes, from the memory location pointed to by the value
argument to a particular datum is given by the inner product of the index
mapping vector with the (origin-0) indices of the imaginary internal array
which would be used if there were no mapping. (The inner product
of two vectors [x1, x2, ..., xn] and [y1, y2, ..., yn] is just x1*y1 + x2*y2
+ ... + xn*yn.) The vector may contain negative values if the value
argument is appropriately specified. A 0 argument obtains the
default behavior in which the memory-resident values are assumed to have the
same structure as the associated netCDF variable.VALUESNCVGTG, the locations into which the data values will be
read. The order in which the data will be read from the netCDF variable is
with the first dimension varying fastest (like the ordinary FORTRAN convention).
The data may be of a type corresponding to any of the netCDF types NCSHORT,
NCLONG, NCFLOAT, or NCDOUBLE, but must
be appropriate for the type of the netCDF variable. Warning: neither
the compiler nor the netCDF software can detect whether the wrong type of
data is used.STRINGNCVGGC, the character string into which the character data
will be read. The order in which the characters will be read from the netCDF
variable is with the first dimension varying fastest (like the FORTRAN convention).
The data may be of a type corresponding to the netCDF types NCCHAR
or NCBYTE.RCODE Here is an example using NCVGTG
to read every other value in each dimension of the variable named rh
from an existing netCDF file named `foo.nc'. Values are assigned,
using the same dimensional strides, to a 2-parameter array whose dimensions
are the reverse of the netCDF variable. For simplicity in this example, we assume
that we know that rh is dimensioned with lon, lat,
and time, and that there are ten lon values, five
lat values, and three time values.
INCLUDE 'netcdf.inc'
...
PARAMETER (NDIMS=3) ! number of dimensions
PARAMETER (TIMES=3, LATS=5, LONS=10) ! dimension sizes
INTEGER NCID, RCODE
INTEGER RHID ! variable ID
INTEGER START(NDIMS), COUNT(NDIMS),
+ STRIDE(NDIMS), IMAP(NDIMS)
DOUBLE DATA(2, TIMES, LATS, LONS) ! rh is second parameter
DATA START /1, 1, 1/ ! start at first value
DATA COUNT /LONS, LATS, TIMES/
DATA STRIDE /2, 2, 2/
...
NCID = NCOPN ('foo.nc', NCNOWRIT, RCODE)
...
RHID = NCVID (NCID, 'rh', RCODE) ! get ID
IMAP(3) = 8*2*2 ! every other point of vector of 2-doubles
IMAP(2) = IMAP(3)*(1+(TIMES-1)/STRIDE(3))*2
IMAP(1) = IMAP(2)*(1+(LATS-1)/STRIDE(2))*2
CALL NCVGTG (NCID, RHID, START, COUNT, STRIDE, IMAP,
+ DATA(2,1,1,1), RCODE)
The function ncrecget
reads a multi-variable record of values (or part of a record of values) from
the record variables of an open netCDF file. The record is specified by giving
a record number. The locations into which the data will be read are specified
by an array of pointers, one for each record variable, to blocks of data. Each
block of data should be of the appropriate size and type for a record's
worth of data for the corresponding record variable. Each such pointer must
be either `0' (a null pointer), to indicate that no data is
to be read for that variable, or must point to space for an entire record's
worth of data of the appropriate type for the corresponding record variable.
The values for each record variable will be ordered with the last dimension
of the netCDF variable varying fastest. The netCDF file must be in data mode.
The ncrecget function is not strictly necessary, since the same
data may be read with a sequence of calls to ncvarget, one for
each record variable for which a non-null pointer is specified. This function
is provided in the C interface for convenience only; no corresponding FORTRAN
interface is available, so FORTRAN users should use multiple calls to NCVGT
or NCVGTC instead.
To use ncrecget properly, you must know the number, order, and
types of record variables in the netCDF file, information that can be determined
with a call to ncrecinq. If your assumptions about the number,
order, or types of record variables in the file is incorrect, calling this function
may lead to incorrect results or a memory access error. Warning: neither
the compiler nor the netCDF software can detect errors with the pointer array
argument to ncrecget.
In case of a detected error, ncrecget returns -1. Possible causes
of detectable errors include:
int ncrecget(int ncid, long recnum, void *datap[]);
ncidncopen or nccreate.recnum0.datapdatap[i], if non-null,
must point to enough space to hold an entire record's worth of data for
the i-th record variable. For null pointers, no data will be
read for the corresponding record variables. This permits you to specify an
arbitrary subset of record variables. The data pointed to should be of the
appropriate type for each record variable. Warning: neither the compiler
nor the netCDF software can detect whether the wrong type of data is used. Here is an example using ncrecget
to read values into several C arrays and scalars with a single call. This example
assumes that record variables of the appropriate shapes and types have previously
been created in the netCDF file.
#include <netcdf.h>
...
static struct {
char city[20];
nclong date;
float lat;
float lon;
float precip[24];
} rec[10];
int ncid; /* id of open netcdf file */
long i; /* number of record to read */
void *datap[5]; /* array of address pointers for record vars */
...
/* Get first 10 records of data */
for(i=0; i<10; i++) {
datap[0] = &rec[i].city[0];
datap[1] = &rec[i].date;
datap[2] = &rec[i].lat;
datap[3] = &rec[i].lon;
datap[4] = &rec[i].precip[0];
ncrecget(ncid, i, datap); /* instead of 5 calls to ncvarget */
}
Character strings are not a primitive netCDF data type, in part because FORTRAN
does not support the abstraction of variable-length character strings (the FORTRAN
LEN function returns the static length of a character string, not
its dynamic length). As a result, a character string cannot be written or read
as a single object in the netCDF interface. Instead, a character string must
be treated as an array of characters, and array access must be used to read
and write character strings as variable data in netCDF files. Furthermore, variable-length
strings are not supported by the netCDF interface except by convention; for
example, you may treat a zero byte as terminating a character string, but you
must explicitly specify the length of strings to be read from and written to
netCDF variables.
Character strings as attribute values are easier to use, since the strings are treated as a single unit for access. However, the value of a character-string attribute is still an array of characters with an explicit length that must be specified when the attribute is defined.
When you define a variable that will have character-string values, use a character-position dimension as the most quickly varying dimension for the variable (the last dimension for the variable in C, the first in FORTRAN). The size of the character-position dimension will be the maximum string length of any value to be stored in the character-string variable. Space for maximum-size strings will be allocated in the disk representation of character-string variables whether you use the space or not. If two or more variables have the same maximum length, the same character-position dimension may be used in defining the variable shapes.
To write a character-string value into a character-string variable, use array
access. This requires that you specify both a corner and a vector of edge lengths.
The character-position dimension at the corner should be zero (one for FORTRAN).
If the length of the string to be written is n, then the vector
of edge lengths will specify n in the character-position dimension,
and one for all the other dimensions, i.e., (1, 1, ..., 1, n) or
(n, 1, 1, ..., 1) in FORTRAN.
In C, fixed-size strings may be written to a netCDF file without the terminating zero byte, to save space. Variable-length strings should be written with a terminating zero byte so that the intended length of the string can be determined when it is later read.
Here is an example that defines a record variable, tx, for character
strings and stores a character-string value into the third record using ncvarput.
In this example, we assume the string variable and data are to be added to an
existing netCDF file named `foo.nc' that already has an unlimited
record dimension time.
#include <netcdf.h>
...
int ncid; /* netCDF ID */
int chid; /* dimension ID for char positions */
int timeid; /* dimension ID for record dimension */
int tx_id; /* variable ID */
#define TDIMS 2 /* rank of tx variable */
int tx_dims[TDIMS]; /* variable shape */
long tx_start[TDIMS];
long tx_count[TDIMS];
static char tx_val[] =
"example string"; /* string to be put */
...
ncid = ncopen("foo.nc", NC_WRITE);
ncredef(ncid); /* enter define mode */
...
/* define character-position dimension for strings of max length 40 */
chid = ncdimdef(ncid, "chid", 40L);
...
/* define a character-string variable */
tx_dims[0] = timeid;
tx_dims[1] = chid; /* character-position dimension last */
tx_id = ncvardef (ncid, "tx", NC_CHAR, TDIMS, tx_dims);
...
ncendef(ncid); /* leave define mode */
...
/* write tx_val into tx netCDF variable in record 3 */
tx_start[0] = 3; /* record number to write */
tx_start[1] = 0; /* start at beginning of variable */
tx_count[0] = 1; /* only write one record */
tx_count[1] = strlen(tx_val) + 1; /* number of chars to write */
ncvarput(ncid, tx_id, tx_start, tx_count, tx_val);
In FORTRAN, fixed-size strings may be written to a netCDF file without a terminating character, to save space. Variable-length strings should follow the C convention of writing strings with a terminating zero byte so that the intended length of the string can be determined when it is later read by either C or FORTRAN programs.
The FORTRAN interface for
reading and writing strings requires the use of different subroutines for accessing
string values and numeric values, because standard FORTRAN does not permit the
same formal parameter to be used for both character values and numeric values.
An additional argument, specifying the declared length of the character string
passed as a value, is required for NCVPTC and NCVGTC.
The actual length of the string is specified as the value of the edge-length
vector corresponding to the character-position dimension.
Here is an example that defines a record variable, tx, for character
strings and stores a character-string value into the third record using NCVPTC.
In this example, we assume the string variable and data are to be added to an
existing netCDF file named `foo.nc' that already has an unlimited
record dimension time.
INCLUDE 'netcdf.inc'
...
INTEGER TDIMS, TXLEN
PARAMETER (TDIMS=2) ! number of TX dimensions
PARAMETER (TXLEN = 15) ! length of example string
INTEGER NCID, RCODE
INTEGER CHID ! char position dimension id
INTEGER TIMEID ! record dimension id
INTEGER TXID ! variable ID
INTEGER TXDIMS(TDIMS) ! variable shape
INTEGER TSTART(TDIMS), TCOUNT(TDIMS)
CHARACTER*40 TXVAL ! max length 40
DATA TXVAL /'example string'/
...
TXVAL(TXLEN:TXLEN) = CHAR(0) ! null terminate
...
NCID = NCOPN('foo.nc', NCWRITE, RCODE)
CALL NCREDF(NCID, RCODE) ! enter define mode
...
* define character-position dimension for strings of max length 40
CHID = NCDDEF(NCID, "chid", 40, RCODE)
...
* define a character-string variable
TXDIMS(1) = CHID ! character-position dimension first
TXDIMS(2) = TIMEID
TXID = NCVDEF(NCID, "tx", NCCHAR, TDIMS, TXDIMS, RCODE)
...
CALL NCENDF(NCID, RCODE) ! leave define mode
...
* write txval into tx netCDF variable in record 3
TSTART(1) = 0 ! start at beginning of variable
TSTART(2) = 3 ! record number to write
TCOUNT(1) = TXLEN ! number of chars to write
TCOUNT(2) = 1 ! only write one record
CALL NCVPTC (NCID, TXID, TSTART, TCOUNT, TXVAL, 40, RCODE)
What happens when you try to read a value that was never written in an open netCDF file? You might expect that this should always be an error, and that you should get an error message or an error status returned. You do get an error if you try to read data from a netCDF file that is not open for reading, if the variable ID is invalid for the specified netCDF file, or if the specified indices are not properly within the range defined by the dimension sizes of the specified variable. Otherwise, reading a value that was not written returns a special fill value used to fill in any undefined values when a netCDF variable is first written.
You may ignore fill values and use the entire range of a netCDF data type,
but in this case you should make sure you write all data values before reading
them. If you know you will be writing all the data before reading it, you can
specify that no prefilling of variables with fill values will occur by calling
ncsetfill before writing. This may provide a significant performance
gain for netCDF writes.
The variable attribute _FillValue is used to specify the fill
value. The default fill values for each type
are defined in the include file `netcdf.h' (or `netcdf.inc'
for FORTRAN).
One difference between the netCDF byte and character types
is that the two types have different default fill values. The default fill value
for characters is the zero byte, a useful value for detecting the end of variable-length
C character strings. If you need a fill value for a byte variable, it is recommended
that you explicitly define an appropriate _FillValue attribute,
as generic utilities such as ncdump will not assume a default fill
value for byte variables.
The function ncvarrename
(or NCVREN for FORTRAN) changes the name of a netCDF variable in
an open netCDF. If the new name is longer than the old name, the netCDF file
must be in define mode. You cannot rename a variable to have the name of any
existing variable.
In case of an error, ncvarrename returns -1; NCVREN
returns a nonzero value in rcode. Possible causes of errors include:
int ncvarrename(int ncid, int varid, const char* name);
ncidncopen or nccreate.varidname Here is an example using ncvarrename
to rename the variable rh to rel_hum in an existing
netCDF file named `foo.nc':
#include <netcdf.h>
...
int ncid; /* netCDF ID */
int rh_id; /* variable ID */
...
ncid = ncopen("foo.nc", NC_WRITE);
...
ncredef(ncid); /* put in define mode to rename variable */
rh_id = ncvarid (ncid, "rh");
ncvarrename (ncid, rh_id, "rel_hum");
ncendef(ncid); /* leave define mode */
SUBROUTINE NCVREN (INTEGER NCID, INTEGER VARID,
+ CHARACTER*(*) NEWNAM, INTEGER RCODE)
NCIDNCOPN or NCCRE.VARIDNEWNAM Here is an example using NCVREN
to rename the variable rh to rel_hum in an existing
netCDF file named `foo.nc':
INCLUDE 'netcdf.inc'
...
INTEGER NCID, RCODE
INTEGER RHID ! variable ID
...
NCID = NCOPN ('foo.nc', NCWRITE, RCODE)
...
CALL NCREDF (CDFFID, RCODE) ! enter definition mode
RHID = NCVID (NCID, 'rh', RCODE) ! get ID
CALL NCVREN (NCID, RHID, 'rel_hum', RCODE)
CALL NCENDF (CDFFID, RCODE) ! leave definition mode
The function nctypelen
(or NCTLEN for FORTRAN) returns the number of bytes per netCDF
data type.
In case of an error, nctypelen returns -1; NCTLEN
returns a nonzero value in rcode. One possible cause of errors
is:
int nctypelen (nc_type datatype);
datatypenc_type, is defined in the netCDF header file. The valid netCDF
data types are NC_BYTE, NC_CHAR, NC_SHORT,
NC_LONG, NC_FLOAT, and NC_DOUBLE. Here is an example using nctypelen
to determine how many bytes are required to store a single value of the variable
rh in an existing netCDF file named `foo.nc':
#include <netcdf.h>
...
int ncid; /* netCDF ID */
int rh_id; /* variable ID */
nc_type rh_type; /* variable type */
int rh_ndims; /* number of dims */
int rh_dims[MAX_VAR_DIMS]; /* variable shape */
int rh_natts; /* number of attributes */
int rhbytes; /* number of bytes per value for "rh" */
...
ncid = ncopen("foo.nc", NC_NOWRITE);
...
rh_id = ncvarid (ncid, "rh");
/* get type. we don't need name, since we already know it */
ncvarinq (ncid, rh_id, 0, &rh_type, &rh_ndims, rh_dims,
&rh_natts);
rhbytes = nctypelen (rh_type);
INTEGER FUNCTION NCTLEN (INTEGER TYPE ,INTEGER RCODE)
TYPENCBYTE, NCCHAR, NCSHORT, NCLONG,
NCFLOAT, and NCDOUBLE.RCODE Here is an example using NCTLEN
to determine how many bytes are required to store a single value of the variable
rh in an existing netCDF file named `foo.nc':
INCLUDE 'netcdf.inc'
...
INTEGER NCID ! netCDF ID
INTEGER RHID ! variable ID
CHARACTER*31 RHNAME ! variable name
INTEGER RHTYPE ! variable type
INTEGER RHN ! number of dimensions
INTEGER RHDIMS(MAXVDIMS) ! variable shape
INTEGER RHNATT ! number of attributes
INTEGER RHBYTS ! bytes per value
...
NCID = NCOPN ('foo.nc', NCNOWRIT, RCODE)
...
RHID = NCVID (NCID, 'rh', RCODE)
* get type of "rh"
CALL NCVINQ (NCID, RHID, RHNAME, RHTYPE, RHN, RHDIMS, RHNATT,
+ RCODE)
RHBYTS = NCTLEN (RHTYPE)
The function ncrecinq
returns information about the record variables (variables that use the unlimited
dimension) in a netCDF file. The information returned is the number of record
variables, their variable IDs, and the size (in bytes) for a record's worth
of data for each record variable.
The ncrecinq function is not strictly necessary, since the information
it returns can be computed from information returned by ncinquire,
ncdiminq, and ncvarinq functions or their FORTRAN
counterparts. This function is provided in the C interface for convenience only,
to assist in using the C functions ncrecput and ncrecget.
In case of an error, ncrecinq returns -1. Possible causes of errors
include:
int ncrecinq(int ncid, int* nrvars, int rvarids[], long rsizes[]);
ncidncopen or nccreate.nrvarsrvaridsnrvars variable IDs for the record variables
in this netCDF file. The caller must allocate enough space for a vector of
at least nrvars integers to be returned. The maximum possible
number of variable IDs returned is given by the predefined constant MAX_NC_VARS.
If this parameter is given as `0' (a null pointer), no vector
will be returned so no space to hold the record variable IDs needs to be declared
or allocated.rsizesnrvars sizes for the record variables in
this netCDF file. The size of a record variable is the number of bytes required
to hold a record's worth of data, which is the product of the non-record
dimensions and the size of data type, in bytes. The caller must allocate enough
space for a vector of at least nrvars longs to be returned. The
maximum possible number of variable IDs returned is given by the predefined
constant MAX_NC_VARS. If this parameter is given as `0'
(a null pointer), no vector will be returned so no space to hold the record
variable sizes needs to be declared or allocated. Here is an example using ncrecinq
to find out about the record variables in an existing netCDF file named `foo.nc':
#include <netcdf.h>
...
int ncid; /* netCDF ID */
int nrvars; /* number of record variables */
int rvarids[MAX_NC_VARS]; /* IDs of record variables */
long rvarsizes[MAX_NC_VARS]; /* record sizes of record variables */
...
ncid = ncopen ("foo.nc", NC_NOWRITE);
...
ncrecinq (ncid, &nrvars, rvarids, rvarsizes);
| Contact Us Site Map Search Terms and Conditions Privacy Policy Participation Policy | ||||||
|
||||||