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

Re: 20020909: UNLIMITED dimension question



>To: address@hidden
>cc: address@hidden
>From: David Han <address@hidden>
>Subject: UNLIMITED dimension question
>Organization: UCAR/Unidata
>Keywords: 200209091839.g89Id6107813

Hi David,

> I'm having problems adding data to a variable (in C) that is defined 
> as 1-d with UNLIMITED dimension.  Let's say I have a variable called 
> "temperature" that is measured at n (where n can be any arbitrary 
> number) different times and want to write these n different 
> temperatures.  Am I supposed to write one temperature at a time or 
> preload all the temperature values into an array and write that 
> array?  I tried both methods and neither one worked (no error 
> messages but no data was added to a file).
> 
> Do you any sample code that does a similar thing?

Sorry this is not clearer from the documentation.  The Fortran 90
Users Guide that has been update most recently has this note, which
should also be in the C and Fortran 77 Users Guides when we get around
to updating them:

   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.

So you can write one temperature at a time or preload all the
temperature values into an array and write that array, but in either
case you have to use the interface that lets you specify the number of
records to be written.

As an example, here's how you would write 5 records at a time (leaving
out the error checking for clarity):

 ...
   int n_dim;
   size_t n_len = NC_UNLIMITED;
   int temperature_id;
#define RANK_temperature 1
   int temperature_dims[RANK_temperature];
   int stat = nc_create("temperature.nc", NC_CLOBBER, &ncid);
   stat = nc_def_dim(ncid, "n", n_len, &n_dim);
   temperature_dims[0] = n_dim;
   stat = nc_def_var(ncid, "temperature", NC_FLOAT, RANK_temperature, 
                     temperature_dims, &temperature_id);
   stat = nc_enddef (ncid);

   {                    /* store temperature */
    static size_t temperature_start[RANK_temperature];
    static size_t temperature_count[RANK_temperature];
    static float temperature[] = {11, 22, 33, 44, 55};
    
    temperature_start[0] = 0;
    temperature_count[0] = 5; /* number of records of temperature data */
    stat = nc_put_vara_float(ncid, temperature_id, temperature_start, 
                             temperature_count, temperature);
   }

To write only one value of temperature at a time (one record at a
time), the only change would be to do the writes in a loop:

    temperature_count[0] = 1;
    for (int i=0; i<5; i++) {
       temperature_start[0] = i;
       stat = nc_put_vara_float(ncid, temperature_id, temperature_start, 
                                temperature_count, temperature);
    }

where you are changing where the write starts each time (at the ith
record) and how much to write each time (only 1 record's worth of
data).

--Russ

_____________________________________________________________________

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