[Next] [Previous] [Top] [Contents] [Index] [netCDF Home Page] [Unidata Home Page]
NetCDF User's Guide for C
Attributes may be associated with each netCDF variable to specify such properties as units, special values, maximum and minimum valid values, scaling factors, and offsets. Attributes for a netCDF dataset are defined when the dataset is first created, while the netCDF dataset is in define mode. Additional attributes may be added later by reentering define mode. A netCDF attribute has a netCDF variable to which it is assigned, a name, a type, a length, and a sequence of one or more values. An attribute is designated by its variable ID and name. When an attribute name is not known, it may be designated by its variable ID and number in order to determine its name, using the function nc_inq_attname
.
The attributes associated with a variable are typically defined immediately after the variable is created, while still in define mode. The data type, length, and value of an attribute may be changed even when in data mode, as long as the changed attribute requires no more space than the attribute as originally defined.
It is also possible to have attributes that are not associated with any variable. These are called global attributes and are identified by using NC_GLOBAL
as a variable pseudo-ID. Global attributes are usually related to the netCDF dataset as a whole and may be used for purposes such as providing a title or processing history for a netCDF dataset.
Operations supported on attributes are:
Names commencing with underscore ('_
') are reserved for use by the netCDF library. Most generic applications that process netCDF datasets assume standard attribute conventions and it is strongly recommended that these be followed unless there are good reasons for not doing so. Below we list the names and meanings of recommended standard attributes that have proven useful. Note that some of these (e.g. units
, valid_range
, scale_factor
) assume numeric data and should not be used with character data.
A character string that specifies the units used for the variable's data. Unidata has developed a freely-available library of routines to convert between character string and binary forms of unit specifications and to perform various useful operations on the binary forms. This library is used in some netCDF applications. Using the recommended units syntax permits data represented in conformable units to be automatically converted to common units for arithmetic operations. See Appendix A "Units," page 113, for more information. | |
A long descriptive name. This could be used for labeling plots, for example. If a variable has no | |
A scalar specifying the minimum valid value for this variable. | |
A scalar specifying the maximum valid value for this variable. | |
A vector of two numbers specifying the minimum and maximum valid values for this variable, equivalent to specifying values for both Generic applications should treat values outside the valid range as missing. The type of each If neither | |
If present for a variable, the data are to be multiplied by this factor after the data are read by the application that accesses the data. | |
If present for a variable, this number is to be added to the data after it is read by the application that accesses the data. If both When | |
The Generic applications often need to write a value to represent undefined or missing values. The fill value provides an appropriate value for this purpose because it is normally outside the valid range and therefore treated as missing when read by generic applications. It is legal (but not recommended) for the fill value to be within the valid range. See Section 7.16 "Fill Values," page 78, for more information. | |
This attribute is not treated in any special way by the library or conforming generic applications, but is often useful documentation and may be used by specific applications. The | |
Deprecated attribute, originally designed to indicate whether byte values should be treated as signed or unsigned. The attributes | |
A character array providing the format that should be used by C applications to print values for this variable. For example, if you know a variable is only accurate to three significant digits, it would be appropriate to define the | |
A character array providing the format that should be used by FORTRAN applications to print values for this variable. For example, if you know a variable is only accurate to three significant digits, it would be appropriate to define the | |
A global attribute that is a character array providing a succinct description of what is in the dataset. | |
A global attribute for an audit trail. This is a character array with a line for each invocation of a program that has modified the dataset. Well-behaved generic netCDF applications should append a line containing: date, time of day, user name, program name and command arguments. | |
If present, ' | |
| For example, if a group named NUWG agrees upon a set of conventions for dimension names, variable names, required attributes, and netCDF representations for certain discipline-specific data structures, they may store a document describing the agreed-upon conventions in a dataset in the |
| Later, if the group agrees upon some additional conventions for a specific subset of NUWG data, for example time series data, the description of the additional conventions might be stored in the |
nc_put_att_
type The function nc_put_att_
type adds or changes a variable attribute or global attribute of an open netCDF dataset. If this attribute is new, or if the space required to store the attribute is greater than before, the netCDF dataset must be in define mode.
Although it's possible to create attributes of all types, text and double attributes are adequate for most purposes.
int nc_put_att_text (int ncid, int varid, const char *name, size_t len, const char *tp); int nc_put_att_uchar (int ncid, int varid, const char *name, nc_type xtype, size_t len, const unsigned char *up); int nc_put_att_schar (int ncid, int varid, const char *name, nc_type xtype, size_t len, const signed char *cp); int nc_put_att_short (int ncid, int varid, const char *name, nc_type xtype, size_t len, const short *sp); int nc_put_att_int (int ncid, int varid, const char *name, nc_type xtype, size_t len, const int *ip); int nc_put_att_long (int ncid, int varid, const char *name, nc_type xtype, size_t len, const long *lp); int nc_put_att_float (int ncid, int varid, const char *name, nc_type xtype, size_t len, const float *fp); int nc_put_att_double (int ncid, int varid, const char *name, nc_type xtype, size_t len, const double *dp);
| NetCDF ID, from a previous call to |
| Variable ID of the variable to which the attribute will be assigned or |
| Attribute name. Must begin with an alphabetic character, followed by zero or more alphanumeric characters including the underscore (' |
| One of the set of predefined netCDF external data types. The type of this parameter, |
| |
| Pointer to one or more values. If the type of values differs from the netCDF attribute type specified as |
nc_put_att_
type returns the value NC_NOERR
if no errors occurred. Otherwise, the returned status indicates an error. Possible causes of errors include:
NC_MAX_ATTRS
.
Here is an example using nc_put_att_double
to add a variable attribute named valid_range
for a netCDF variable named rh
and a global attribute named title
to an existing netCDF dataset named foo.nc
:
#include <netcdf.h> ... int status; /* error status */ int ncid; /* netCDF ID */ int rh_id; /* variable ID */ static double rh_range[] = {0.0, 100.0};/* attribute vals */ static char title[] = "example netCDF dataset"; ... status = nc_open("foo.nc", NC_WRITE, &ncid); if (status != NC_NOERR) handle_error(status); ... status = nc_redef(ncid); /* enter define mode */ if (status != NC_NOERR) handle_error(status); status = nc_inq_varid (ncid, "rh", &rh_id); if (status != NC_NOERR) handle_error(status); ... status = nc_put_att_double (ncid, rh_id, "valid_range", NC_DOUBLE, 2, rh_range); if (status != NC_NOERR) handle_error(status); status = nc_put_att_text (ncid, NC_GLOBAL, "title", NC_CHAR, strlen(title), title) if (status != NC_NOERR) handle_error(status); ... status = nc_enddef(ncid); /* leave define mode */ if (status != NC_NOERR) handle_error(status);
nc_inq_att
FamilyThis family of functions returns information about a netCDF attribute. All but one of these functions require the variable ID and attribute name; the exception isnc_inq_attname
. Information about an attribute includes its type, length, name, and number. See the
nc_get_att
family for getting attribute values.
The function nc_inq_attname
gets the name of an attribute, given its variable ID and number. This function is useful in generic applications that need to get the names of all the attributes associated with a variable, since attributes are accessed by name rather than number in all other attribute functions. The number of an attribute is more volatile than the name, since it can change when other attributes of the same variable are deleted. This is why an attribute number is not called an attribute ID.
The function nc_inq_att
returns the attribute's type and length. The other functions each return just one item of information about an attribute.
int nc_inq_att (int ncid, int varid, const char *name, nc_type *xtypep, size_t *lenp); int nc_inq_atttype(int ncid, int varid, const char *name, nc_type *xtypep); int nc_inq_attlen (int ncid, int varid, const char *name, size_t *lenp); int nc_inq_attname(int ncid, int varid, int attnum, char *name); int nc_inq_attid (int ncid, int varid, const char *name, int *attnump);
Each function returns the value NC_NOERR
if no errors occurred. Otherwise, the returned status indicates an error. Possible causes of errors include:
nc_inq_attname
, the specified attribute number is negative or more than the number of attributes defined for the specified variable.
Here is an example using nc_inq_att
to find out the type and length of a variable attribute named valid_range
for a netCDF variable named rh
and a global attribute named title
in an existing netCDF dataset named foo.nc
:
#include <netcdf.h> ... int status; /* error status */ int ncid; /* netCDF ID */ int rh_id; /* variable ID */ nc_type vr_type, t_type; /* attribute types */ int vr_len, t_len; /* attribute lengths */ ... status = nc_open("foo.nc", NC_NOWRITE, &ncid); if (status != NC_NOERR) handle_error(status); ... status = nc_inq_varid (ncid, "rh", &rh_id); if (status != NC_NOERR) handle_error(status); ... status = nc_inq_att (ncid, rh_id, "valid_range", &vr_type, &vr_len); if (status != NC_NOERR) handle_error(status); status = nc_inq_att (ncid, NC_GLOBAL, "title", &t_type, &t_len); if (status != NC_NOERR) handle_error(status);
nc_get_att_
type Members of the nc_get_att_
type family of functions get the value(s) of a netCDF attribute, given its variable ID and name.
int nc_get_att_text (int ncid, int varid, const char *name, char *tp); int nc_get_att_uchar (int ncid, int varid, const char *name, unsigned char *up); int nc_get_att_schar (int ncid, int varid, const char *name, signed char *cp); int nc_get_att_short (int ncid, int varid, const char *name, short *sp); int nc_get_att_int (int ncid, int varid, const char *name, int *ip); int nc_get_att_long (int ncid, int varid, const char *name, long *lp); int nc_get_att_float (int ncid, int varid, const char *name, float *fp); int nc_get_att_double (int ncid, int varid, const char *name, double *dp);
nc_get_att_
type returns the value NC_NOERR
if no errors occurred. Otherwise, the returned status indicates an error. Possible causes of errors include:
Here is an example using nc_get_att_double
to determine the values of a variable attribute named valid_range
for a netCDF variable named rh
and a global attribute named title
in an existing netCDF dataset named foo.nc
. In this example, it is assumed that we don't know how many values will be returned, but that we do know the types of the attributes. Hence, to allocate enough space to store them, we must first inquire about the length of the attributes.
#include <netcdf.h> ... int status; /* error status */ int ncid; /* netCDF ID */ int rh_id; /* variable ID */ int vr_len, t_len; /* attribute lengths */ double *vr_val; /* ptr to attribute values */ char *title; /* ptr to attribute values */ extern char *malloc(); /* memory allocator */ ... status = nc_open("foo.nc", NC_NOWRITE, &ncid); if (status != NC_NOERR) handle_error(status); ... status = nc_inq_varid (ncid, "rh", &rh_id); if (status != NC_NOERR) handle_error(status); ... /* find out how much space is needed for attribute values */ status = nc_inq_attlen (ncid, rh_id, "valid_range", &vr_len); if (status != NC_NOERR) handle_error(status); status = nc_inq_attlen (ncid, NC_GLOBAL, "title", &t_len); if (status != NC_NOERR) handle_error(status); /* allocate required space before retrieving values */ vr_val = (double *) malloc(vr_len * sizeof(double)); title = (char *) malloc(t_len + 1); /* + 1 for trailing null */ /* get attribute values */ status = nc_get_att_double(ncid, rh_id, "valid_range", vr_val); if (status != NC_NOERR) handle_error(status); status = nc_get_att_text(ncid, NC_GLOBAL, "title", title); if (status != NC_NOERR) handle_error(status); title[t_len] = '\0'; /* null terminate */ ...
nc_copy_att
The function nc_copy_att
copies an attribute from one open netCDF dataset to another. It can also be used to copy an attribute from one variable to another within the same netCDF.
int nc_copy_att (int ncid_in, int varid_in, const char *name, int ncid_out, int varid_out);
ncid_in | The netCDF ID of an input netCDF dataset from which the attribute will be copied, from a previous call to |
varid_in | ID of the variable in the input netCDF dataset from which the attribute will be copied, or |
name | Name of the attribute in the input netCDF dataset to be copied. |
ncid_out | The netCDF ID of the output netCDF dataset to which the attribute will be copied, from a previous call to |
varid_out | ID of the variable in the output netCDF dataset to which the attribute will be copied, or |
nc_copy_att
returns the value NC_NOERR
if no errors occurred. Otherwise, the returned status indicates an error. Possible causes of errors include:
Here is an example using nc_copy_att
to copy the variable attribute units
from the variable rh
in an existing netCDF dataset named foo.nc
to the variable avgrh
in another existing netCDF dataset named bar.nc
, assuming that the variable avgrh
already exists, but does not yet have a units
attribute:
#include <netcdf.h> ... int status; /* error status */ int ncid1, ncid2; /* netCDF IDs */ int rh_id, avgrh_id; /* variable IDs */ ... status = nc_open("foo.nc", NC_NOWRITE, ncid1); if (status != NC_NOERR) handle_error(status); status = nc_open("bar.nc", NC_WRITE, ncid2); if (status != NC_NOERR) handle_error(status); ... status = nc_inq_varid (ncid1, "rh", &rh_id); if (status != NC_NOERR) handle_error(status); status = nc_inq_varid (ncid2, "avgrh", &avgrh_id); if (status != NC_NOERR) handle_error(status); ... status = nc_redef(ncid2); /* enter define mode */ if (status != NC_NOERR) handle_error(status); /* copy variable attribute from "rh" to "avgrh" */ status = nc_copy_att(ncid1, rh_id, "units", ncid2, avgrh_id); if (status != NC_NOERR) handle_error(status); ... status = nc_enddef(ncid2); /* leave define mode */ if (status != NC_NOERR) handle_error(status);
nc_rename_att
The function nc_rename_att
changes the name of an attribute. If the new name is longer than the original name, the netCDF dataset must be in define mode. You cannot rename an attribute to have the same name as another attribute of the same variable.
int nc_rename_att (int ncid, int varid, const char* name, const char* newname);
| NetCDF ID, from a previous call to |
| ID of the attribute's variable, or |
| The current attribute name. |
| The new name to be assigned to the specified attribute. If the new name is longer than the current name, the netCDF dataset must be in define mode. |
nc_rename_att
returns the value NC_NOERR
if no errors occurred. Otherwise, the returned status indicates an error. Possible causes of errors include:
Here is an example using nc_rename_att
to rename the variable attribute units
to Units
for a variable rh
in an existing netCDF dataset named foo.nc
:
#include <netcdf.h> ... int status; /* error status */ int ncid; /* netCDF ID */ int rh_id; /* variable id */ ... status = nc_open("foo.nc", NC_NOWRITE, &ncid); if (status != NC_NOERR) handle_error(status); ... status = nc_inq_varid (ncid, "rh", &rh_id); if (status != NC_NOERR) handle_error(status); ... /* rename attribute */ status = nc_rename_att(ncid, rh_id, "units", "Units"); if (status != NC_NOERR) handle_error(status);
nc_del_att
The function nc_del_att
deletes a netCDF attribute from an open netCDF dataset. The netCDF dataset must be in define mode.
int nc_del_att (int ncid, int varid, const char* name);
| NetCDF ID, from a previous call to |
ID of the attribute's variable, or | |
| The name of the attribute to be deleted. |
nc_del_att
returns the value NC_NOERR
if no errors occurred. Otherwise, the returned status indicates an error. Possible causes of errors include:
Here is an example using nc_del_att
to delete the variable attribute Units
for a variable rh
in an existing netCDF dataset named foo.nc
:
#include <netcdf.h> ... int status; /* error status */ int ncid; /* netCDF ID */ int rh_id; /* variable ID */ ... status = nc_open("foo.nc", NC_WRITE, &ncid); if (status != NC_NOERR) handle_error(status); ... status = nc_inq_varid (ncid, "rh", &rh_id); if (status != NC_NOERR) handle_error(status); ... /* delete attribute */ status = nc_redef(ncid); /* enter define mode */ if (status != NC_NOERR) handle_error(status); status = nc_del_att(ncid, rh_id, "Units"); if (status != NC_NOERR) handle_error(status); status = nc_enddef(ncid); /* leave define mode */ if (status != NC_NOERR) handle_error(status);
[Next] [Previous] [Top] [Contents] [Index] [netCDF Home Page] [Unidata Home Page]