[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[netCDF #ITH-188331]: netcdf data append in f90



Hi Rama,

> I am using the netCDF routines to write netCDF files.
> 
> One of my netCDF files, needs to be updated every day
> instead of created every day.
> 
> For this netCDF file, I created it first, set the unlimited
> dimension for each one of the variables supposed to be
> in the file and then wrote it successfully.
> 
> However, when I try to update the file, it does not.
> Instead it overwrites, I suppose.
> 
> I follow exactly the guide-lines in the netCDF document.
> 
> When I want to update the existing netCDF file by appending
> data to the already existing variables I follow the procedure as
> mentioned below:
> 
> 1. nf90_open(filename, nf90_write, ncid)
> 
> 2.nf90_inq_varid(ncid, "varname", varid)
> "varname" is predefined in a separate f90 module
> 
> 3. nf90_put_var(ncid, varid, data)
> 
> Could you kindly help me figure out why the file is not getting appended
> but getting overwritten ?

Yes, the problem is that you are using nf90_put_var without specifying
where to start writing, which just replaces all the values with the
data you supply.  As the documentation for nf90_put_var says:

   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.

What this simplest put function is for is writing *all the data* you
give it to the variable.  It's not an append function, even if var is
a record variable.  You could write an append function in terms of
nf90_put_var, which would do something like this, to append a single
record's worth of data to the variable:

1. nf90_open(filename, nf90_write, ncid)

2. nf90_inq_varid(ncid, "varname", varid)

3. nf90_inquire(ncid, unlimitedDimID = recId)
   Gets the ID of the unlimited dimension in recId.

4. nf90_inquire_dimension(ncid, recId, len = nRecs)
   Gets the current number of records in nRecs.

5. nf90_put_var(ncid, varid, data, start = nRecs + 1, count = 1)
   Writes a single data value at the end of the array, assuming the
   netCDF variable you are writing is one-dimensional.

If instead the variable you are writing is two-dimensional, for example,
and you want to append another column to it that's stored in the
variable "data" in your program, you would instead use

5. integer :: starts(2), counts(2)
   starts = (/ 1,     nRecs + 1 /)
   counts = (/ nrows,         1 /)
   nf90_put_var(ncid, varid, data, start = starts, count = counts )
   Appends a column of data values at the end of a 2-dimensional
   array, assuming the netCDF variable you are writing is currently 
   nRows by nRecs and data is a 1-dimensional array in memory with
   nrows values.

Similarly if "varname" is a 3-dimensional netCDF record variable to
which you want to append a 2-dimensional slice, you would dimension
starts and counts to have 3 values

   starts = (/ 1,         1,    nRecs + 1 /)
   counts = (/ nrows, ncols,            1 /)

and use the same nf90_put_var call as above.

--Russ

Russ Rew                                         UCAR Unidata Program
address@hidden                     http://www.unidata.ucar.edu



Ticket Details
===================
Ticket ID: ITH-188331
Department: Support netCDF
Priority: Normal
Status: Closed