This archive contains answers to questions sent to Unidata support through mid-2025. Note that the archive is no longer being updated. We provide the archive for reference; many of the answers presented here remain technically correct, even if somewhat outdated. For the most up-to-date information on the use of NSF Unidata software and data services, please consult the Software Documentation first.
>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); }