|
|
|||
|
||||
7 Variables
Variables for a netCDF dataset are defined when the dataset is created, while the netCDF dataset is in define mode. Other variables may be added later by reentering define mode. A netCDF variable has a name, a type, and a shape, which are specified when it is defined. A variable may also have values, which are established later in data mode.
Ordinarily, the name, type, and shape are fixed when the variable is first defined. The name may be changed, but the type and shape of a variable cannot be changed. However, a variable defined in terms of the unlimited dimension can grow without bound in that dimension.
A netCDF variable in an open netCDF dataset is referred to by a small integer called a variable ID.
Variable IDs reflect the order in which variables were defined within a netCDF dataset. Variable IDs are 1, 2, 3, ..., in the order in which the variables were defined. A function is available for getting the variable ID from the variable name and vice-versa.
Attributes (see Chapter 8 "Attributes," page 69) may be associated with a variable to specify such properties as units.
Operations supported on variables are:
- Create a variable, given its name, data type, and shape.
- Get a variable ID from its name.
- Get a variable's name, data type, shape, and number of attributes from its ID.
- Put a data value into a variable, given variable ID, indices, and value.
- Put an array of values into a variable, given variable ID, corner indices, edge lengths, and a block of values.
- Put a subsampled or mapped array-section of values into a variable, given variable ID, corner indices, edge lengths, stride vector, index mapping vector, and a block of values.
- Get a data value from a variable, given variable ID and indices.
- Get an array of values from a variable, given variable ID, corner indices, and edge lengths.
- Get a subsampled or mapped array-section of values from a variable, given variable ID, corner indices, edge lengths, stride vector, and index mapping vector.
- Rename a variable.
7.1 Language Types Corresponding to NetCDF External Data Types
The following table gives the netCDF external data types and the corresponding type constants for defining variables in the Fortran 90 interface:
netCDF/CDL Data Type Fortran 90 API Mnemonic Bits byte NF90_BYTE 8 char NF90_CHAR 8 short NF90_SHORT 16 int NF90_INT 32 float NF90_FLOAT 32 double NF90_DOUBLE 64The first column gives the netCDF external data type, which is the same as the CDL data type. The next column gives the corresponding Fortran 90 parameter for use in netCDF functions (the parameters are defined in the netCDF Fortran 90 module netcdf.f90). The last column gives the number of bits used in the external representation of values of the corresponding type.
Note that there are no netCDF types corresponding to 64-bit integers or to characters wider than 8 bits in the current version of the netCDF library.
7.2 Create a Variable: NF90_DEF_VAR
The function NF90_DEF_VAR adds a new variable to an open netCDF dataset in define mode. It returns (as an argument) a variable ID, given the netCDF ID, the variable name, the variable type, the number of dimensions, and a list of the dimension IDs.
Usage
function nf90_def_var(ncid, name, xtype, dimids, varid) integer, intent( in) :: ncid character (len = *), intent( in) :: name integer, intent( in) :: xtype integer, dimension(:), intent( in) :: dimids integer :: nf90_def_varErrors
NF90_DEF_VAR returns the value NF90_NOERR if no errors occurred. Otherwise, the returned status indicates an error. Possible causes of errors include:
- The netCDF dataset is not in define mode.
- The specified variable name is the name of another existing variable.
- The specified type is not a valid netCDF type.
- The specified number of dimensions is negative or more than the constant NF90_MAX_VAR_DIMS, the maximum number of dimensions permitted for a netCDF variable.
- One or more of the dimension IDs in the list of dimensions is not a valid dimension ID for the netCDF dataset.
- The number of variables would exceed the constant NF90_MAX_VARS, the maximum number of variables permitted in a netCDF dataset.
- The specified netCDF ID does not refer to an open netCDF dataset.
Example
Here is an example using NF90_DEF_VAR to create a variable named rh of type double with three dimensions, time, lat, and lon in a new netCDF dataset named foo.nc:
use netcdf implicit none integer :: status, ncid integer :: LonDimId, LatDimId, TimeDimId integer :: RhVarId ... status = nf90_create("foo.nc", nf90_NoClobber, ncid) if(status /= nf90_NoErr) call handle_error(status) ... ! Define the dimensions status = nf90_def_dim(ncid, "lat", 5, LatDimId) if(status /= nf90_NoErr) call handle_error(status) status = nf90_def_dim(ncid, "lon", 10, LonDimId) if(status /= nf90_NoErr) call handle_error(status) status = nf90_def_dim(ncid, "time", nf90_unlimited, TimeDimId) if(status /= nf90_NoErr) call handle_error(status) ... ! Define the variable status = nf90_def_var(ncid, "rh", nf90_double, & (/ LonDimId, LatDimID, TimeDimID /), RhVarId) if(status /= nf90_NoErr) call handle_error(status)7.3 Get a Variable ID from Its Name: NF90_INQ_VARID
The function NF90_INQ_VARID returns the ID of a netCDF variable, given its name.
Usage
function nf90_inq_varid(ncid, name, varid) integer, intent( in) :: ncid character (len = *), intent( in) :: name integer, intent(out) :: varid integer :: nf90_inq_varid
ncid NetCDF ID, from a previous call to NF90_OPEN or NF90_CREATE. name Variable name for which ID is desired. varid Returned variable ID.Errors
NF90_INQ_VARID returns the value NF90_NOERR if no errors occurred. Otherwise, the returned status indicates an error. Possible causes of errors include:
- The specified variable name is not a valid name for a variable in the specified netCDF dataset.
- The specified netCDF ID does not refer to an open netCDF dataset.
Example
Here is an example using NF90_INQ_VARID to find out the ID of a variable named rh in an existing netCDF dataset named foo.nc:
use netcdf implicit none integer :: status, ncid, RhVarId ... status = nf90_open("foo.nc", nf90_NoWrite, ncid) if(status /= nf90_NoErr) call handle_err(status) ... status = nf90_inq_varid(ncid, "rh", RhVarId) if(status /= nf90_NoErr) call handle_err(status)7.4 Get Information about a Variable from Its ID: NF90_Inquire_Variable
NF90_Inquire_Variable returns information about a netCDF variable given its ID. Information about a variable includes its 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.
Usage
function nf90_Inquire_Variable(ncid, varid, name, xtype, ndims, dimids, nAtts) integer, intent( in) :: ncid, varid character (len = *), optional, intent(out) :: name integer, optional, intent(out) :: xtype, ndims integer, dimension(*), optional, intent(out) :: dimids integer, optional, intent(out) :: nAtts integer :: nf90_Inquire_VariableErrors
Function NF90_Inquire_Variable returns the value NF90_NOERR if no errors occurred. Otherwise, the returned status indicates an error. Possible causes of errors include:
- The variable ID is invalid for the specified netCDF dataset.
- The specified netCDF ID does not refer to an open netCDF dataset.
Example
Here is an example using NF90_Inquire_Variable to find out about a variable named rh in an existing netCDF dataset named foo.nc:
use netcdf implicit none integer :: status, ncid, & RhVarId & numDims, numAtts integer, dimension(nf90_max_var_dims) :: rhDimIds ... status = nf90_open("foo.nc", nf90_NoWrite, ncid) if(status /= nf90_NoErr) call handle_error(status) ... status = nf90_inq_varid(ncid, "rh", RhVarId) if(status /= nf90_NoErr) call handle_err(status) status = nf90_Inquire_Var(ncid, RhVarId, ndims = numDims, natts = numAtts) if(status /= nf90_NoErr) call handle_err(status) status = nf90_Inquire_Var(ncid, RhVarId, dimids = rhDimIds(:numDims)) if(status /= nf90_NoErr) call handle_err(status)7.5 Writing Data Values: NF90_PUT_VAR
The function NF90_PUT_VAR puts one or more data values into the variable of an open netCDF dataset that is in data mode. Required inputs are the netCDF ID, the variable ID, and one or more data values. Optional inputs may indicate the starting position of the data values in the netCDF variable (argument start), the sampling frequency with which data values are written into the netCDF variable (argument stride), and a mapping between the dimensions of the data array and the netCDF variable (argument map). The values to be written are associated with the netCDF variable by assuming that the first dimension of the netCDF variable varies fastest in the Fortran 90 interface. Data values converted to the external type of the variable, if necessary.
Take care when using the simplest forms of this interface with record variables when you don't specify how many records are to be written. If you try to write all the values of a record variable into a netCDF file that has no record data yet (hence has 0 records), nothing will be written. Similarly, if you try to write all of a record variable but there are more records in the file than you assume, more data may be written to the file than you supply, which may result in a segmentation violation.
Usage
function nf90_put_var(ncid, varid, values, start, count, stride, map) integer, intent( in) :: ncid, varid any valid type, scalar or array of any rank, & intent( in) :: values integer, dimension(:), optional, intent( in) :: start, count, stride, map integer :: nf90_put_varErrors
NF90_PUT_VAR returns the value NF90_NOERR if no errors occurred. Otherwise, the returned status indicates an error. Possible causes of errors include:
- The variable ID is invalid for the specified netCDF dataset.
- The assumed or specified start, count, and stride generate an index which is out of range. Note that no error checking is possible on the map vector.
- One or more of the specified values are out of the range of values representable by the external data type of the variable.
- The specified netCDF is in define mode rather than data mode.
- The specified netCDF ID does not refer to an open netCDF dataset.
(As noted above, another possible source of error is using this interface to write all the values of a record variable without specifying the number of records. If there are a different number of records in the file than you assume, the amount of data written may be different from what you expect!)
Example
Here is an example using NF90_PUT_VAR to set the (4,3,2) element of the variable named rh to 0.5 in an existing netCDF dataset 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:
use netcdf implicit none integer :: ncId, rhVarId, status ... status = nf90_open("foo.nc", nf90_Write, ncid) if(status /= nf90_NoErr) call handle_err(status) ...ß status = nf90_inq_varid(ncid, "rh", rhVarId) if(status /= nf90_NoErr) call handle_err(status) status = nf90_put_var(ncid, rhVarId, 0.5, start = (/ 4, 3, 2 /) ) if(status /= nf90_NoErr) call handle_err(status)In this example we use NF90_PUT_VAR to add or change all the values of the variable named rh to 0.5 in an existing netCDF dataset named foo.nc. We assume that we know that rh is dimensioned with lon, lat, and time. In this example we query the netCDF file to discover the lengths of the dimensions, then use the Fortran 90 intrinsic function reshape to create a temporary array of data values which is the same shape as the netCDF variable.
use netcdf implicit none integer :: ncId, rhVarId,status, & lonDimID, latDimId, timeDimId, & numLons, numLats, numTimes, & i integer, dimension(nf90_max_var_dims) :: dimIDs ... status = nf90_open("foo.nc", nf90_Write, ncid) if(status /= nf90_NoErr) call handle_err(status) ... status = nf90_inq_varid(ncid, "rh", rhVarId) if(status /= nf90_NoErr) call handle_err(status) ! How big is the netCDF variable, that is, what are the lengths of ! its constituent dimensions? status = nf90_Inquire_Variable(ncid, rhVarId, dimids = dimIDs) if(status /= nf90_NoErr) call handle_err(status) status = nf90_Inquire_Dimension(ncid, dimIDs(1), len = numLons) if(status /= nf90_NoErr) call handle_err(status) status = nf90_Inquire_Dimension(ncid, dimIDs(2), len = numLats) if(status /= nf90_NoErr) call handle_err(status) status = nf90_Inquire_Dimension(ncid, dimIDs(3), len = numTimes) if(status /= nf90_NoErr) call handle_err(status) ... ! Make a temporary array the same shape as the netCDF variable. status = nf90_put_var(ncid, rhVarId, & reshape( & (/ (0.5, i = 1, numLons * numLats * numTimes) /) , & shape = (/ numLons, numLats, numTimes /) ) if(status /= nf90_NoErr) call handle_err(status)Here is an example using NF90_PUT_VAR to add or change a section of the variable named rh to 0.5 in an existing netCDF dataset named foo.nc. For simplicity in this example, we assume that we know that rh is dimensioned with lon, lat, and time, that there are ten lon values, five lat values, and three time values, and that we want to replace all the values at the last time.
use netcdf implicit none integer :: ncId, rhVarId, status integer, parameter :: numLons = 10, numLats = 5, numTimes = 3 real, dimension(numLons, numLats) & :: rhValues ... status = nf90_open("foo.nc", nf90_Write, ncid) if(status /= nf90_NoErr) call handle_err(status) ... status = nf90_inq_varid(ncid, "rh", rhVarId) if(status /= nf90_NoErr) call handle_err(status) ! Fill in all values at the last time rhValues(:, :) = 0.5 status = nf90_put_var(ncid, rhVarId,rhvalues, & start = (/ 1, 1, numTimes /), & count = (/ numLats, numLons, 1 /)) if(status /= nf90_NoErr) call handle_err(status)Here is an example of using NF_PUT_VAR to write every other point of a netCDF variable named rh having dimensions (6, 4).
use netcdf implicit none integer :: ncId, rhVarId, status integer, parameter :: numLons = 6, numLats = 4 real, dimension(numLons, numLats) & :: rhValues = 0.5 ... status = nf90_open("foo.nc", nf90_Write, ncid) if(status /= nf90_NoErr) call handle_err(status) ... status = nf90_inq_varid(ncid, "rh", rhVarId) if(status /= nf90_NoErr) call handle_err(status) ... ! Fill in every other value using an array section status = nf90_put_var(ncid, rhVarId, rhValues(::2, ::2), & stride = (/ 2, 2 /)) if(status /= nf90_NoErr) call handle_err(status)The following map vector shows the default mapping between a 2x3x4 netCDF variable and an internal array of the same shape:
real, dimension(2, 3, 4):: a ! same shape as netCDF variable integer, dimension(3) :: map = (/ 1, 2, 6 /) ! netCDF dimension inter-element distance ! ---------------- ---------------------- ! most rapidly varying 1 ! intermediate 2 (= map(1)*2) ! most slowly varying 6 (= map(2)*3)Using the map vector above obtains the same result as simply not passing a map vector at all.
Here is an example of using nf90_put_var to write a netCDF variable named rh whose dimensions are the transpose of the Fortran 90 array:
use netcdf implicit none integer :: ncId, rhVarId, status integer, parameter :: numLons = 6, numLats = 4 real, dimension(numLons, numLats) :: rhValues ! netCDF variable has dimensions (numLats, numLons) ... status = nf90_open("foo.nc", nf90_Write, ncid) if(status /= nf90_NoErr) call handle_err(status) ... status = nf90_inq_varid(ncid, "rh", rhVarId) if(status /= nf90_NoErr) call handle_err(status) ... !Write transposed values: map vector would be (/ 1, numLats /) for ! no transposition status = nf90_put_var(ncid, rhVarId,rhValues, map = (/ numLons, 1 /)) if(status /= nf90_NoErr) call handle_err(status)The same effect can be obtained more simply using Fortran 90 intrinsic functions:
use netcdf implicit none integer :: ncId, rhVarId, status integer, parameter :: numLons = 6, numLats = 4 real, dimension(numLons, numLats) :: rhValues ! netCDF variable has dimensions (numLats, numLons) ... status = nf90_open("foo.nc", nf90_Write, ncid) if(status /= nf90_NoErr) call handle_err(status) ... status = nf90_inq_varid(ncid, "rh", rhVarId) if(status /= nf90_NoErr) call handle_err(status) ... status = nf90_put_var(ncid, rhVarId, transpose(rhValues)) if(status /= nf90_NoErr) call handle_err(status)7.6 Reading Data Values: NF90_GET_VAR
The function NF90_GET_VAR gets one or more data values from a netCDF variable of an open netCDF dataset that is in data mode. Required inputs are the netCDF ID, the variable ID, and a specification for the data values into which the data will be read. Optional inputs may indicate the starting position of the data values in the netCDF variable (argument start), the sampling frequency with which data values are read from the netCDF variable (argument stride), and a mapping between the dimensions of the data array and the netCDF variable (argument map). The values to be read are associated with the netCDF variable by assuming that the first dimension of the netCDF variable varies fastest in the Fortran 90 interface. Data values are converted from the external type of the variable, if necessary.
Take care when using the simplest forms of this interface with record variables when you don't specify how many records are to be read. If you try to read all the values of a record variable into an array but there are more records in the file than you assume, more data will be read than you expect, which may cause a segmentation violation.
Usage
function nf90_get_var(ncid, varid, values, start, count, stride, map) integer, intent( in) :: ncid, varid any valid type, scalar or array of any rank, & intent(out) :: values integer, dimension(:), optional, intent( in) :: start, count, stride, map integer :: nf90_get_varErrors
NF90_GET_VAR returns the value NF90_NOERR if no errors occurred. Otherwise, the returned status indicates an error. Possible causes of errors include:
- The variable ID is invalid for the specified netCDF dataset.
- The assumed or specified start, count, and stride generate an index which is out of range. Note that no error checking is possible on the map vector.
- One or more of the specified values are out of the range of values representable by the desired type.
- The specified netCDF is in define mode rather than data mode.
- The specified netCDF ID does not refer to an open netCDF dataset.
(As noted above, another possible source of error is using this interface to read all the values of a record variable without specifying the number of records. If there are more records in the file than you assume, more data will be read than you expect!)
Example
Here is an example using NF90_GET_VAR to read the (4,3,2) element of the variable named rh from an existing netCDF dataset 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 read the value of rh that corresponds to the fourth lon value, the third lat value, and the second time value:
use netcdf implicit none integer :: ncId, rhVarId, status real :: rhValue ... status = nf90_open("foo.nc", nf90_NoWrite, ncid) if(status /= nf90_NoErr) call handle_err(status) - status = nf90_inq_varid(ncid, "rh", rhVarId) if(status /= nf90_NoErr) call handle_err(status) status = nf90_get_var(ncid, rhVarId, rhValue, start = (/ 4, 3, 2 /) ) if(status /= nf90_NoErr) call handle_err(status)In this example we use NF90_GET_VAR to read all the values of the variable named rh from an existing netCDF dataset named foo.nc. We assume that we know that rh is dimensioned with lon, lat, and time. In this example we query the netCDF file to discover the lengths of the dimensions, then allocate a Fortran 90 array the same shape as the netCDF variable.
use netcdf implicit none integer :: ncId, rhVarId, & lonDimID, latDimId, timeDimId, & numLons, numLats, numTimes, & status integer, dimension(nf90_max_var_dims) :: dimIDs real, dimension(:, :, :), allocatable :: rhValues ... status = nf90_open("foo.nc", nf90_NoWrite, ncid) if(status /= nf90_NoErr) call handle_err(status) ... status = nf90_inq_varid(ncid, "rh", rhVarId) if(status /= nf90_NoErr) call handle_err(status) ! How big is the netCDF variable, that is, what are the lengths of ! its constituent dimensions? status = nf90_Inquire_Variable(ncid, rhVarId, dimids = dimIDs) if(status /= nf90_NoErr) call handle_err(status) status = nf90_Inquire_Dimension(ncid, dimIDs(1), len = numLons) if(status /= nf90_NoErr) call handle_err(status) status = nf90_Inquire_Dimension(ncid, dimIDs(2), len = numLats) if(status /= nf90_NoErr) call handle_err(status) status = nf90_Inquire_Dimension(ncid, dimIDs(3), len = numTimes) if(status /= nf90_NoErr) call handle_err(status) allocate(rhValues(numLons, numLats, numTimes)) ... status = nf90_get_var(ncid, rhVarId, rhValues) if(status /= nf90_NoErr) call handle_err(status)Here is an example using NF90_GET_VAR to read a section of the variable named rh from an existing netCDF dataset named foo.nc. For simplicity in this example, we assume that we know that rh is dimensioned with lon, lat, and time, that there are ten lon values, five lat values, and three time values, and that we want to replace all the values at the last time.
use netcdf implicit none integer :: ncId, rhVarId, status integer, parameter :: numLons = 10, numLats = 5, numTimes = 3 real, dimension(numLons, numLats, numTimes) & :: rhValues ... status = nf90_open("foo.nc", nf90_NoWrite, ncid) if(status /= nf90_NoErr) call handle_err(status) ... status = nf90_inq_varid(ncid, "rh", rhVarId) if(status /= nf90_NoErr) call handle_err(status) !Read the values at the last time by passing an array section status = nf90_get_var(ncid, rhVarId, rhValues(:, :, 3), & start = (/ 1, 1, numTimes /), & count = (/ numLats, numLons, 1 /)) if(status /= nf90_NoErr) call handle_err(status)Here is an example of using NF_GET_VAR to read every other point of a netCDF variable named rh having dimensions (6, 4).
use netcdf implicit none integer :: ncId, rhVarId, status integer, parameter :: numLons = 6, numLats = 4 real, dimension(numLons, numLats) & :: rhValues ... status = nf90_open("foo.nc", nf90_NoWrite, ncid) if(status /= nf90_NoErr) call handle_err(status) ... status = nf90_inq_varid(ncid, "rh", rhVarId) if(status /= nf90_NoErr) call handle_err(status) ... ! Read every other value into an array section status = nf90_get_var(ncid, rhVarId, rhValues(::2, ::2) & stride = (/ 2, 2 /)) if(status /= nf90_NoErr) call handle_err(status)The following map vector shows the default mapping between a 2x3x4 netCDF variable and an internal array of the same shape:
real, dimension(2, 3, 4):: a ! same shape as netCDF variable integer, dimension(3) :: map = (/ 1, 2, 6 /) ! netCDF dimension inter-element distance ! ---------------- ---------------------- ! most rapidly varying 1 ! intermediate 2 (= map(1)*2) ! most slowly varying 6 (= map(2)*3)Using the map vector above obtains the same result as simply not passing a map vector at all.
Here is an example of using nf90_get_var to read a netCDF variable named rh whose dimensions are the transpose of the Fortran 90 array:
use netcdf implicit none integer :: ncId, rhVarId, status integer, parameter :: numLons = 6, numLats = 4 real, dimension(numLons, numLats) :: rhValues ! netCDF variable has dimensions (numLats, numLons) ... status = nf90_open("foo.nc", nf90_NoWrite, ncid) if(status /= nf90_NoErr) call handle_err(status) ... status = nf90_inq_varid(ncid, "rh", rhVarId) if(status /= nf90_NoErr) call handle_err(status) ... ! Read transposed values: map vector would be (/ 1, numLats /) for ! no transposition status = nf90_get_var(ncid, rhVarId,rhValues, map = (/ numLons, 1 /)) if(status /= nf90_NoErr) call handle_err(status)The same effect can be obtained more simply, though using more memory, using Fortran 90 intrinsic functions:
use netcdf implicit none integer :: ncId, rhVarId, status integer, parameter :: numLons = 6, numLats = 4 real, dimension(numLons, numLats) :: rhValues ! netCDF variable has dimensions (numLats, numLons) real, dimension(numLons, numLats) :: tempValues ... status = nf90_open("foo.nc", nf90_NoWrite, ncid) if(status /= nf90_NoErr) call handle_err(status) ... status = nf90_inq_varid(ncid, "rh", rhVarId) if(status /= nf90_NoErr) call handle_err(status) ... status = nf90_get_var(ncid, rhVarId, tempValues)) if(status /= nf90_NoErr) call handle_err(status) rhValues(:, :) = transpose(tempValues)7.7 Reading and Writing Character String Values
Character strings are not a primitive netCDF external data type, in part because FORTRAN does not support the abstraction of variable-length character strings (the FORTRAN LEN function returns the static length of a character string, not its dynamic length). As a result, a character string cannot be written or read as a single object in the netCDF interface. Instead, a character string must be treated as an array of characters, and array access must be used to read and write character strings as variable data in netCDF datasets. Furthermore, variable-length strings are not supported by the netCDF interface except by convention; for example, you may treat a zero byte as terminating a character string, but you must explicitly specify the length of strings to be read from and written to netCDF variables.
Character strings as attribute values are easier to use, since the strings are treated as a single unit for access. However, the value of a character-string attribute is still an array of characters with an explicit length that must be specified when the attribute is defined.
When you define a variable that will have character-string values, use a character-position dimension as the most quickly varying dimension for the variable (the first dimension for the variable in Fortran 90). The length 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-length 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 either entire variable access or array access. The latter requires that you specify both a corner and a vector of edge lengths. The character-position dimension at the corner should be one for Fortran 90. 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: (n, 1, 1, ..., 1).
In Fortran 90, fixed-length strings may be written to a netCDF dataset without a terminating character, to save space. Variable-length strings should follow the C convention of writing strings with a terminating zero byte so that the intended length of the string can be determined when it is later read by either C or Fortran 90 programs.
7.8 Fill Values
What happens when you try to read a value that was never written in an open netCDF dataset? 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 dataset that is not open for reading, if the variable ID is invalid for the specified netCDF dataset, or if the specified indices are not properly within the range defined by the dimension lengths of the specified variable. Otherwise, reading a value that was not written returns a special fill value used to fill in any undefined values when a netCDF variable is first written.
You may ignore fill values and use the entire range of a netCDF external 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 writing. This may provide a significant performance gain for netCDF writes.
The variable attribute _FillValue may be used to specify the fill value for a variable. There are default fill values for each type, defined in module netcdf: NF90_FILL_CHAR, NF90_FILL_INT1 (same as NF90_FILL_BYTE), NF90_FILL_INT2 (same as NF90_FILL_SHORT), NF90_FILL_INT, NF90_FILL_REAL (same as NF90_FILL_FLOAT), and NF90_FILL_DOUBLE
The netCDF byte and character types have different default fill values. The default fill value for characters is the zero byte, a useful value for detecting the end of variable-length C character strings. If you need a fill value for a byte variable, it is recommended that you explicitly define an appropriate _FillValue attribute, as generic utilities such as ncdump will not assume a default fill value for byte variables.
Type conversion for fill values is identical to type conversion for other values: attempting to convert a value from one type to another type that can't represent the value results in a range error. Such errors may occur on writing or reading values from a larger type (such as double) to a smaller type (such as float), if the fill value for the larger type cannot be represented in the smaller type.
7.9 Rename a Variable: NF90_RENAME_VAR
The function NF90_RENAME_VAR changes the name of a netCDF variable in an open netCDF dataset. If the new name is longer than the old name, the netCDF dataset must be in define mode. You cannot rename a variable to have the name of any existing variable.
Usage
function nf90_rename_var(ncid, varid, newname) integer, intent( in) :: ncid, varid character (len = *), intent( in) :: newname integer :: nf90_rename_var
ncid NetCDF ID, from a previous call to NF90_OPEN or NF90_CREATE. varid Variable ID. newname New name for the specified variable.Errors
NF90_RENAME_VAR returns the value NF90_NOERR if no errors occurred. Otherwise, the returned status indicates an error. Possible causes of errors include:
- The new name is in use as the name of another variable.
- The variable ID is invalid for the specified netCDF dataset.
- The specified netCDF ID does not refer to an open netCDF dataset.
Example
Here is an example using NF90_RENAME_VAR to rename the variable rh to rel_hum in an existing netCDF dataset named foo.nc:
use netcdf implicit none integer :: ncId, rhVarId, status ... status = nf90_open("foo.nc", nf90_Write, ncid) if(status /= nf90_NoErr) call handle_err(status) ... status = nf90_inq_varid(ncid, "rh", rhVarId) if(status /= nf90_NoErr) call handle_err(status) status = nf90_redef(ncid) ! Enter define mode to change variable name if(status /= nf90_NoErr) call handle_err(status) status = nf90_rename_var(ncid, rhVarId, "rel_hum") if(status /= nf90_NoErr) call handle_err(status) status = nf90_enddef(ncid) ! Leave define mode if(status /= nf90_NoErr) call handle_err(status)
| Contact Us Site Map Search Terms and Conditions Privacy Policy Participation Policy | ||||||
|
||||||