Go to the previous, next section.
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 is referred to by a small integer called a variable ID. Attributes may be associated with a variable to specify such properties as units, fill values, maximum and minimum valid values, scaling factors, and offsets.
Operations supported on variables are:
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[]);
ncid
ncopen
or nccreate
.
name
datatype
nc_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
.
ndims
2
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
.
dimids
ndims
dimension IDs corresponding to the variable
dimensions. If the ID of the unlimited dimension is included, it
must be first.
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)
NCID
NCOPN
or NCCRE
.
VARNAM
VARTYP
NCBYTE
, NCCHAR
, NCSHORT
, NCLONG
, NCFLOAT
, and NCDOUBLE
.
NVDIMS
2
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
.
VDIMS
NVDIMS
dimension IDs corresponding to the variable
dimensions. If the ID of the unlimited dimension is included, it
must be last.
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);
ncid
ncopen
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)
NCID
NCOPN
or NCCRE
.
VARNAM
RCODE
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);
ncid
ncopen
or nccreate
.
varid
ncvardef
or
ncvarid
.
name
MAX_NC_NAME
.
If the name parameter is given as `(char *) 0', no name will be
returned so no space needs to be allocated.
datatype
nc_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 `(nc_type *) 0',
no type will be returned so no variable to hold the type needs to be
declared.
ndims
2
specifies a matrix, 1
specifies a vector, and
0
means the variable is a scalar with no dimensions. If this
parameter is given as `(int *) 0', no number of dimensions will be
returned so no variable to hold this information needs to be declared.
dimids
ndims
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 `(int *) 0', 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, (char *) 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)
NCID
NCOPN
or NCCRE
.
VARID
NCVDEF
or
NCVID
.
VARNAM
MAXNCNAM
.
VARTYP
NCBYTE
, NCCHAR
,
NCSHORT
, NCLONG
, NCFLOAT
, and NCDOUBLE
.
NVDIMS
2
specifies a matrix, 1
specifies a vector, and 0
means the
variable is a scalar with no dimensions.
VDIMS
NVDIMS
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
.
NVATTS
RCODE
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);
ncid
ncopen
or nccreate
.
varid
ncvardef
or
ncvarid
.
mindex
(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.
value
void *
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, (void *) &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.
NCID
NCOPN
or NCCRE
.
VARID
NCVDEF
or
NCVID
.
MINDEX
(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.
VALUE
NCVPT1
, 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.
CHVAL
NCVP1C
, 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 a hyperslab of values into a netCDF variable of an open
netCDF file. The hyperslab is specified by giving a corner and a vector
of edge lengths. The values are specified as a vector whose elements
are ordered by assuming that the last dimension of the hyperslab varies
fastest for C, the first dimension varies fastest for FORTRAN. 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);
ncid
ncopen
or nccreate
.
varid
ncvardef
or
ncvarid
.
start
(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.
count
count
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.
value
void *
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 hyperslab of values into netCDF variable */ ncvarput(ncid, rh_id, start, count, (void *) 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 a hyperslab 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.
NCID
NCOPN
or NCCRE
.
VARID
NCVDEF
or
NCVID
.
START
(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.
COUNT
COUNT
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.
VALUES
NCVPT
, the block of data values to be written. The order in
which the data will be written into the specified hyperslab 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.
STRING
NCVPTC
, 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 hyperslab
varying fastest (like the FORTRAN convention). The data
may be of a type corresponding to the netCDF types NCCHAR
or
NCBYTE
.
LENSTR
NCVPTC
, 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 INTEGER RHID ! variable ID INTEGER START(NDIMS), COUNT(NDIMS) ! hyperslab 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 generalized hyperslab of values into a netCDF variable
of an open
netCDF file. The generalized hyperslab is specified by giving a corner,
a vector of edge lengths, 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);
ncid
ncopen
or nccreate
.
varid
ncvardef
or
ncvarid
.
start
(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.
count
count
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.
stride
NULL
stride argument obtains the default behavior in which
adjacent values are accessed along each dimension.
imap
value
argument to a particular datum is given by the
inner product of the index mapping vector with the coordinates of
the datum.
(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.
value
void *
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 generalized hyperslab of values into netCDF variable */ ncvarputg(ncid, rh_id, start, count, stride, imap, (void*)&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 generalized hyperslab 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.
NCID
NCOPN
or NCCRE
.
VARID
NCVDEF
or
NCVID
.
START
(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.
COUNT
COUNT
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.
STRIDE
0
.
The size of the vector shall be at least the number of dimensions of the
associated
netCDF variable and its elements shall 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.
An 0
argument obtains the default behavior in which
adjacent values are accessed along each dimension.
IMAP
0
.
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) coordinates of
the datum.
(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.
VALUES
NCVPTG
, the block of data values to be written. The order in
which the data will be written from the specified hyperslab is with the
first dimension of the generalized hyperslab 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.
STRING
NCVPGC
, 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 generalized hyperslab
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) ! generalized hyperslab 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 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 NULL,
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 even a
segmentation violation. 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[]);
ncid
ncopen
or
nccreate
.
recnum
0
.
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.
datap
datap[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]; long 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 ncvarget */
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);
ncid
ncopen
or
nccreate
.
varid
ncvardef
or
ncvarid
.
mindex
(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.
value
void *
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, (void *) &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.
NCID
NCOPN
or
NCCRE
.
VARID
NCVDEF
or
NCVID
.
MINDEX
(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.
VALUE
NCVGT1
, 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.
CHVAL
NCVG1C
, 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 a hyperslab of values from a netCDF variable of an open
netCDF file. The hyperslab 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 of the hyperslab 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);
ncid
ncopen
or
nccreate
.
varid
ncvardef
or
ncvarid
.
start
(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 reading the data values.
count
count
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 read.
value
void *
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 hyperslab of values from netCDF variable */ ncvarget(ncid, rh_id, start, count, (void *) 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 a hyperslab 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.
NCID
NCOPN
or
NCCRE
.
VARID
NCVDEF
or
NCVID
.
START
(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 reading the data values.
COUNT
COUNT
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 read.
VALUES
NCVGT
, 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 of the specified hyperslab 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.
STRING
NCVGTC
, 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 of the specified hyperslab
varying fastest (like the FORTRAN convention). The data may be of a
type corresponding to the netCDF types NCCHAR
or NCBYTE
.
LENSTR
NCVGTC
, 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) ! hyperslab 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 generalized hyperslab of values from a netCDF variable
of an open netCDF file. The generalized hyperslab 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 generalized hyperslab 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);
ncid
ncopen
or
nccreate
.
varid
ncvardef
or
ncvarid
.
start
(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 reading the data values.
count
count
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 read.
stride
NULL
stride argument obtains the default behavior
in which adjacent values are accessed along each dimension.
imap
value
argument to a particular datum is given by the inner
product of the index mapping vector with the coordinates of the datum.
(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.
value
void *
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 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 generalized hyperslab of values from netCDF variable */ ncvargetg(ncid, rh_id, start, count, stride, imap, (void*)&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 generalized hyperslab 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.
NCID
NCOPN
or
NCCRE
.
VARID
NCVDEF
or
NCVID
.
START
(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 reading the data values.
COUNT
COUNT
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 read.
STRIDE
0
.
The size of the vector shall be at least the number of dimensions of the
associated netCDF variable and its elements shall 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. An 0
argument obtains the default behavior
in which adjacent values are accessed along each dimension.
IMAP
0
. 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)
coordinates of the datum. (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.
VALUES
NCVGTG
, 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 of the generalized hyperslab 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.
STRING
NCVGGC
, 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 of the generalized hyperslab
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) ! generalized hyperslab 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
NULL, to indicate that no data is to be written 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 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 even a
segmentation violation. 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[]);
ncid
ncopen
or
nccreate
.
recnum
0
.
datap
datap[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]; long 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 hyperslab 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 null (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; no hyperslab access is necessary (or possible) for attributes. 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
hyperslab 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 null byte, to save space. Variable-length strings should be written with a terminating null 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 /* dimensionality 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, (void *) 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 null 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 hyperslab
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' ... 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) ! hyperslab 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 hyperslab is 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 missing values when a netCDF variable is first written.
You may also 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.
There are several reasons for using a fill value instead of an error return for missing data. First, the interface for hyperslab access would necessarily be more complex and slower if information had to be returned about whether each value read had been written. Since data may have been written in a different order from that in which it is later read, it is possibile that only a few values in a block of retrieved values were never written. Second, it is usually preferable to delay the detection of missing values until there is a need for the values, since they may not be used in subsequent computations. Finally, the use of missing values is a common way to represent data points outside the boundaries of irregular regions of data enclosed by a hyperslab, making it possible to handle such data in a simpler way than would be possible with a more compact representation that represented the boundary explicitly.
The default fill values for each type are defined in the include file
`netcdf.h' (or `netcdf.inc' for FORTRAN). It is usually
better to use your own fill value instead, by defining the attribute
_FillValue
for a variable before writing it. A disadvantage of
the default fill values for floating-point and double-precision types is
that they may be defined differently for different platforms, and may be
difficult to compare with other values, since they are defined to be
right at the edge of the valid floating-point number ranges for each
machine.
Fill values are used for filling in missing data whenever a value is put beyond the end of data that has already been written. A default fill value has no other special meaning, so it can be used for valid values if you use your own fill value instead.
Currently the only difference between the netCDF byte and character types is that the two types have different default fill values. The fill value for bytes is on the edge of the range, representing the largest negative value for signed bytes. The fill value for characters, however, is the zero byte, a more useful value for detecting the end of C character strings.
Sometimes there is need for more than one value to represent different
kinds of missing data. In this case, the user should use one or more
other variable attributes for the different kinds of missing data. For
example, it might be appropriate to use _FillValue
to mean that
data that was expected never appeared, but missing_value
where
the creator of the data intends data to be missing, as around an
irregular region represented by a rectangular grid.
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 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);
ncid
ncopen
or nccreate
.
varid
ncvardef
or
ncvarid
.
name
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)
NCID
NCOPN
or NCCRE
.
VARID
NCVDEF
or
NCVID
.
NEWNAM
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);
datatype
nc_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
.
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, (char *) 0, &rh_type, &rh_ndims, rh_dims, &rh_natts); rhbytes = nctypelen (rh_type);
INTEGER FUNCTION NCTLEN (INTEGER TYPE ,INTEGER RCODE)
TYPE
NCBYTE
, 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[]);
ncid
ncopen
or nccreate
.
nrvars
rvarids
nrvars
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 `(int *) 0', no
vector will be returned so no space to hold the record variable IDs
needs to be declared or allocated.
rsizes
nrvars
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 `(int *) 0', 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);
Go to the previous, next section.