|
|
|||
|
||||
[Next] [Previous] [Top] [Contents] [Index] [netCDF Home Page] [Unidata Home Page]
NetCDF User's Guide for FORTRAN
You can
use the netCDF library without knowing about all of the netCDF interface.
If you are creating a netCDF dataset, only a handful of routines are required
to define the necessary dimensions, variables, and attributes, and to write
the data to the netCDF dataset. (Even less are needed if you use the ncgen
utility to create the dataset before running a program using netCDF library
calls to write data.) Similarly, if you are writing software to access data
stored in a particular netCDF object, only a small subset of the netCDF library
is required to open the netCDF dataset and access the data. Authors of generic
applications that access arbitrary netCDF datasets need to be familiar with
more of the netCDF library.
In this
chapter we provide templates of common sequences of netCDF calls needed for
common uses. For clarity we present only the names of routines; omit declarations
and error checking; omit the type-specific suffixes of routine names for variables
and attributes; indent statements that are typically invoked multiple times;
and use ... to represent arbitrary sequences of other statements.
Full parameter lists are described in later chapters.
Here is a typical sequence of netCDF calls used to create a new netCDF dataset:
NF_CREATE ! create netCDF dataset: enter define mode ... NF_DEF_DIM ! define dimensions: from name and length ... NF_DEF_VAR ! define variables: from name, type, dims ... NF_PUT_ATT ! assign attribute values ... NF_ENDDEF ! end definitions: leave define mode ... NF_PUT_VAR ! provide values for variable ... NF_CLOSE ! close: save new netCDF dataset
Only one call is needed to create a netCDF dataset, at which point you will be in the first of two netCDF modes. When accessing an open netCDF dataset, it is either in define mode or data mode. In define mode, you can create dimensions, variables, and new attributes, but you cannot read or write variable data. In data mode, you can access data and change existing attributes, but you are not permitted to create new dimensions, variables, or attributes.
One call to NF_DEF_DIM is needed
for each dimension created. Similarly, one call to NF_DEF_VAR
is needed for each variable creation, and one call to a member of the NF_PUT_ATT
family is needed for each attribute defined and assigned a value. To leave
define mode and enter data mode, call NF_ENDDEF.
Once in data mode, you can add new data to variables, change old values,
and change values of existing attributes (so long as the attribute changes
do not require more storage space). Single values may be written to a netCDF
variable with one of the members of the NF_PUT_VAR1
family, depending on what type of data you have
to write. All the values of a variable may be written at once with one of
the members of the NF_PUT_VAR family.
Arrays or array cross-sections of a variable may be written using members
of the NF_PUT_VARA family.
Subsampled array sections may be written using members of the NF_PUT_VARS
family. Mapped array sections may be written using members
of the NF_PUT_VARM family. (Subsampled
and mapped access are general forms of data access that are explained later.)
Finally, you
should explicitly close all netCDF datasets that have been opened for writing
by calling NF_CLOSE. By default, access
to the file system is buffered by the netCDF library. If a program terminates
abnormally with netCDF datasets open for writing, your most recent modifications
may be lost. This default buffering of data is disabled by setting the NF_SHARE
flag when opening the dataset. But even if this flag is set, changes to attribute
values or changes made in define mode are not written out until NF_SYNC
or NF_CLOSE is called.
Here we consider the case where you know the names of not only the netCDF datasets, but also the names of their dimensions, variables, and attributes. (Otherwise you would have to do "inquire" calls.) The order of typical C calls to read data from those variables in a netCDF dataset is:
NF_OPEN ! open existing netCDF dataset
...
NF_INQ_DIMID ! get dimension IDs
...
NF_INQ_VARID ! get variable IDs
...
NF_GET_ATT ! get attribute values
...
NF_GET_VAR ! get values of variables
...
NF_CLOSE ! close netCDF dataset
First, a single call opens the netCDF dataset, given the dataset name, and returns a netCDF ID that is used to refer to the open netCDF dataset in all subsequent calls.
Next, a
call to NF_INQ_DIMID
for each dimension of interest gets the dimension ID from the dimension name.
Similarly, each required variable ID is determined from its name by a call
to NF_INQ_VARID.Once
variable IDs are known, variable attribute values can be retrieved using the
netCDF ID, the variable ID, and the desired attribute name as input to a member
of the NF_GET_ATT family
(typically NF_GET_ATT_TEXT or NF_GET_ATT_DOUBLE)
for each desired attribute. Variable data values can be directly accessed
from the netCDF dataset with calls to members of the NF_GET_VAR1
family for single values, the NF_GET_VAR
family for entire variables, or various other members of the NF_GET_VARA,
NF_GET_VARS,
or NF_GET_VARM families for array,
subsampled or mapped access.
Finally, the netCDF dataset
is closed with NF_CLOSE. There is
no need to close a dataset open only for reading.
It is possible to write programs (e.g., generic software) which do such things as processing every variable, without needing to know in advance the names of these variables. Similarly, the names of dimensions and attributes may be unknown.
Names and other information about netCDF objects may be obtained from netCDF datasets by calling inquire functions. These return information about a whole netCDF dataset, a dimension, a variable, or an attribute. The following template illustrates how they are used:
NF_OPEN ! open existing netCDF dataset ... NF_INQ ! find out what is in it ... NF_INQ_DIM ! get dimension names, lengths ... NF_INQ_VAR ! get variable names, types, shapes ... NF_INQ_ATTNAME ! get attribute names ... NF_INQ_ATT ! get attribute values ... NF_GET_ATT ! get attribute values ... NF_GET_VAR ! get values of variables ... NF_CLOSE ! close netCDF dataset
As in the previous example, a single call opens the existing netCDF dataset,
returning a netCDF ID. This netCDF ID is given to the NF_INQ
routine, which returns the number of dimensions, the number of variables,
the number of global attributes, and the ID of the unlimited dimension, if
there is one.
All the inquire functions are inexpensive to use and require no I/O, since the information they provide is stored in memory when a netCDF dataset is first opened.
Dimension IDs
use consecutive integers, beginning at 1. Also
dimensions, once created, cannot be deleted. Therefore, knowing the number
of dimension IDs in a netCDF dataset means knowing all the dimension IDs:
they are the integers 1, 2, 3, ... up to the number
of dimensions. For each dimension ID, a call to the inquire function NF_INQ_DIM
returns the dimension name and length.
Variable IDs are also
assigned from consecutive integers 1, 2, 3, ...
up to the number of variables. These can be used in NF_INQ_VAR
calls to find out the names, types, shapes, and the number of attributes assigned
to each variable.
Once the number of attributes for a variable is
known, successive calls to NF_INQ_ATTNAME
return the name for each attribute given the netCDF ID, variable ID, and attribute
number. Armed with the attribute name, a call to NF_INQ_ATT
returns its type and length. Given the type and length, you can allocate enough
space to hold the attribute values. Then a call to a member of the NF_GET_ATT
family returns the attribute values.
Once the IDs and shapes of netCDF variables are known, data values can be
accessed by calling a member of the NF_GET_VAR1
family for single values, or members of the NF_GET_VAR,
NF_GET_VARA, NF_GET_VARS,
or NF_GET_VARM for various
kinds of array access.
An existing netCDF dataset can be extensively altered. New dimensions, variables, and attributes can be added or existing ones renamed, and existing attributes can be deleted. Existing dimensions, variables, and attributes can be renamed. The following code template lists a typical sequence of calls to add new netCDF components to an existing dataset:
NF_OPEN ! open existing netCDF dataset
...
NF_REDEF ! put it into define mode
...
NF_DEF_DIM ! define additional dimensions (if any)
...
NF_DEF_VAR ! define additional variables (if any)
...
NF_PUT_ATT ! define other attributes (if any)
...
NF_ENDDEF ! check definitions, leave define mode
...
NF_PUT_VAR ! provide new variable values
...
NF_CLOSE ! close netCDF dataset
A netCDF
dataset is first opened by the NF_OPEN
call. This call puts the open dataset in data mode, which means existing
data values can be accessed and changed, existing attributes can be changed
(so long as they do not grow), but nothing can be added. To add new netCDF
dimensions, variables, or attributes you must enter define mode, by
calling NF_REDEF.In
define mode, call NF_DEF_DIM to define
new dimensions, NF_DEF_VAR to define
new variables, and a member of the NF_PUT_ATT
family to assign new attributes to variables or enlarge old attributes.
You can leave define mode and reenter data mode, checking all the new definitions
for consistency and committing the changes to disk, by calling NF_ENDDEF.
If you do not wish to reenter data mode, just call NF_CLOSE,
which will have the effect of first calling NF_ENDDEF.
Until the
NF_ENDDEF call, you may back out of
all the redefinitions made in define mode and restore the previous state of
the netCDF dataset by calling NF_ABORT.
You may also use the NF_ABORT call
to restore the netCDF dataset to a consistent state if the call to NF_ENDDEF
fails. If you have called NF_CLOSE
from definition mode and the implied call to NF_ENDDEF
fails, NF_ABORT will automatically
be called to close the netCDF dataset and leave it in its previous consistent
state (before you entered define mode).
At most one process should have a netCDF dataset open for writing at one time. The library is designed to provide limited support for multiple concurrent readers with one writer, via disciplined use of the NF_SYNC function and the NF_SHARE flag. If a writer makes changes in define mode, such as the addition of new variables, dimensions, or attributes, some means external to the library is necessary to prevent readers from making concurrent accesses and to inform readers to call NF_SYNC before the next access.
The netCDF library provides the facilities needed to handle errors in a flexible way. Each netCDF function returns an integer status value. If the returned status value indicates an error, you may handle it in any way desired, from printing an associated error message and exiting to ignoring the error indication and proceeding (not recommended!). For simplicity, the examples in this guide check the error status and call a separate function to handle any errors.
The NF_STRERROR function is available to convert a returned integer error status into an error message string.
Occasionally, low-level I/O errors may occur in a layer below the netCDF library. For example, if a write operation causes you to exceed disk quotas or to attempt to write to a device that is no longer available, you may get an error from a layer below the netCDF library, but the resulting write error will still be reflected in the returned status value.
Details of how to compile and link a program that uses the netCDF C or FORTRAN interfaces differ, depending on the operating system, the available compilers, and where the netCDF library and include files are installed. Nevertheless, we provide here examples of how to compile and link a program that uses the netCDF library on a Unix platform, so that you can adjust these examples to fit your installation.
Every FORTRAN
file that references netCDF functions or constants must contain an appropriate
INCLUDE statement before the first such reference:
INCLUDE 'netcdf.inc'
Unless the netcdf.inc file is installed in a standard directory
where the FORTRAN compiler always looks, you must use the -I
option when invoking the compiler, to specify a directory where netcdf.inc
is installed, for example:
f77 -c -I/usr/local/netcdf/include myprogram.f
Alternatively, you could specify an absolute path name in the INCLUDE
statement, but then your program would not compile on another platform where
netCDF is installed in a different location.
Unless the netCDF library is installed in a standard directory where the
linker always looks, you must use the -L and -l
options to link an object file that uses the netCDF library. For example:
f77 -o myprogram myprogram.o -L/usr/local/netcdf/lib -lnetcdf
Alternatively, you could specify an absolute path name for the library:
f77 -o myprogram myprogram.o -l/usr/local/netcdf/lib/libnetcdf.
[Next] [Previous] [Top] [Contents] [Index] [netCDF Home Page] [Unidata Home Page]
| Contact Us Site Map Search Terms and Conditions Privacy Policy Participation Policy | ||||||
|
||||||