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.
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_var
ncid
varid
values
start
By default, start(:) = 1.
count
By default, count(:numDims) = shape(values) and
count(numDims + 1:) = 1, where numDims = size(shape(values)).
stride
By default, stride(:) = 1.
imap
By default, edgeLengths = shape(values), and map = (/ 1, (product(edgeLengths(:i)), i = 1, size(edgeLengths) - 1) /), that is, there is no mapping.
Use of Fortran 90 intrinsic functions (including reshape, transpose, and spread) may let you avoid using this argument.
NF90_PUT_VAR1_ type returns the value NF90_NOERR if no errors occurred. Otherwise, the returned status indicates an error. Possible causes of errors include:
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)