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

Re: 971211: Problem with ncrecput



>To: address@hidden
>From: "j.ankenbrand" <address@hidden>
>Subject: Problem with ncrecput!
>Organization: .
>Keywords: 199712110942.CAA08463

Hi Juergen,

> We have a problem with the C Interface ncrecput.
> 
> We use NetCDF version 2.4.x.
> 
> We'll make measurements during an experimental fly and we want to save
> the values directly in a netCDf-file. There are about 100 parameters,
> which have to be written at every second. Because of the huge dimension
> of the single parameter (the fly will be several hours) , it is too
> slowly to make about 100 calls to the function ncvarput1 at every
> second.  We think, that one call to ncrecput at every second with a
> void-datapointer,who contains the values of the 100 parameters, would be
> much faster.  Our unlimitted dimension would then be the time.

Unfortunately, making a single ncrecput() call will not be faster than
making 100 ncvarput1() calls, because all ncrecput does is make the
appropriate calls to ncvarput().  It is merely a convenience interface,
and offers no significant efficiency benefits.

> But neither with the borland3.1 C-compiler on a PC nor with the cc
> -compiler on aix-workstations, I get data written in the netCDF-file by
> a call to ncrecput.  Several calls to ncrecput only increase the
> unlimitted dimension, but no data-values are witten in the netCDF file.

There is a bug in netCDF version 2.4.x (and earlier versions) that you
are seeing.  If you attempt to write a record by calling ncrecput() and
there are no record variables defined, ncrecput should produce an error
message, but instead it doesn't detect the error and just returns after
incrementing the number of records.

The current release (netCDF version 3.3.1) correctly emits the following
error message when your program is run:

  ncrecput: ncid 4: nc_rec op when there are no record vars

which means you attempted a record operation (ncrecput) when there are
no record variables defined (variables that use the unlimited
dimension).  Also since the current version is generally faster than
version 2.4.3 by a factor of two or more, you might get adequate
performance merely by using the current netCDF version.

The example from the User's guide you are following is merely a fragment
of a complete program and does not include the calls necessary to define
record variables.  If you leave out these calls, there will be no record
variables defined, so an ncrecput() call should not write any data.  I
have appended a complete working example below.

> In our header file the function is declared
>  int ncrecput(int ncid,long recnum,void* const* datap)
> in difference of the description in the NETCDF Users's Guide
>  int ncrecput(int ncid,long recnum,const void *datap[])
> 
> In my opinion, the 'const' could be on the wrong place.
> 
> Here is the programm, which is almost similar to this of the User's guide:
> 
> #include </usr/local/icg/icg1/netCDF/src/libsrc/netcdf.h>
> 
> void main(void)
> {
>   static struct
>   {
>     char city[20];
>     nclong data;
>     float lat;
>     float lon;
>     float precip[24];
>   }rec ={
>     "Pocatello",
>     930228,
>     42.92,
>     -112.60,
>     {0,0,.1,.2,.3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
>   };
> 
>   int ncid;
>   long recnum;
>   void *datap[5];
> 
>   ncid=nccreate("rectest.nc",NC_CLOBBER);
>   ncdimdef(ncid,"recnum",NC_UNLIMITED);
>   ncendef(ncid);
>   recnum=0;
> 
>   datap[0] =&rec.city[0];
>   datap[1] =&rec.data;
>   datap[2] =&rec.lat;
>   datap[3] =&rec.lon;
>   datap[4] =&rec.precip[0];
> 
>   ncrecput(ncid,recnum,datap);
> 
>   ncclose(ncid);
> 
>   exit(0);
> }
> 
> 
> I hope you can help me!
> 
> Much thanks
> Juergen Ankenbrand

The appended program shows how to define the variables before calling
ncrecput().  I just tested this on netCDF 2.4.3 and netCDF 3.3.1 and it
seems to work properly in both cases.

Thanks for reporting the bug in netCDF 2.4.3.

--Russ

_____________________________________________________________________

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


#include <netcdf.h>

void main(void)
{
  static struct
  {
    char city[20];
    nclong data;
    float lat;
    float lon;
    float precip[24];
  }rec ={
    "Pocatello",
    930228,
    42.92,
    -112.60,
    {0,0,.1,.2,.3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
  };

  int ncid;
  long recnum;
  void *datap[5];

  /* dimension ids */
  int  recnum_dim, hour_dim, strlen_dim;

  /* variable ids */
  int  city_id, population_id, lat_id, lon_id, precip_id;

  /* variable shapes */
  int dims[2];

  /* enter define mode */
  ncid = nccreate("rectest.nc", NC_CLOBBER);

  /* define dimensions */
  recnum_dim = ncdimdef(ncid, "recnum", NC_UNLIMITED);
  hour_dim = ncdimdef(ncid, "hour", 24L);
  strlen_dim = ncdimdef(ncid, "strlen", 20L);

  /* define variables */
  dims[0] = recnum_dim;
  dims[1] = strlen_dim;
  city_id = ncvardef (ncid, "city", NC_CHAR, 2, dims);

  dims[0] = recnum_dim;
  population_id = ncvardef (ncid, "population", NC_LONG, 1, dims);

  dims[0] = recnum_dim;
  lat_id = ncvardef (ncid, "lat", NC_FLOAT, 1, dims);
  
  dims[0] = recnum_dim;
  lon_id = ncvardef (ncid, "lon", NC_FLOAT, 1, dims);

  dims[0] = recnum_dim;
  dims[1] = hour_dim;
  precip_id = ncvardef (ncid, "precip", NC_FLOAT, 2, dims);

  ncendef(ncid);
  recnum=0;

  datap[0] =&rec.city[0];
  datap[1] =&rec.data;
  datap[2] =&rec.lat;
  datap[3] =&rec.lon;
  datap[4] =&rec.precip[0];

  ncrecput(ncid,recnum,datap);

  ncclose(ncid);

  exit(0);
}