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.
> Organization: NOAA/FSL > Keywords: 199410201923.AA18899 version ncgen fill values Hi Linda, > I have two questions. First is, how can you determine which > version of netcdf is installed on a machine? I think it is > version 2.3.2, but I am not sure. If the source directory from which netCDF was built and installed is still available, you can look at the file named VERSION in the top-level netcdf source directory, which should contain a single line with the version number, "2.3.2" for the current version. It's also in the second line of the README file in the same directory. If you only have an installed version, on a UNIX system you can run the command strings `which ncgen` | grep Header and if the date in the resulting version control line is later than April 1993, you are running version 2.3 or later. Version 2.3.2 was released in June 1993, so if your executables were built more recently than that, there is a good chance they are version 2.3.2. There have been a couple of official patches releases since 2.3.2, mostly to correct bugs found in ncdump and ncgen. These have resulted in the current 2.3.2pl2 patch-level release. > Second is, when I run the following cdl file through ncgen: > > netcdf lw3 { > > dimensions: > record = unlimited, > z = 22, > x = 61, > y = 61; > > variables: > // u wind component > > float > u(record,z,y,x); > u:_FillValue= 1.e+37; > > // inventory variables > > short > u_fcinv(record, z); > u_fcinv:_FillValue= 0; > > } > > ********************************************* > I get the following output: > > > #include "netcdf.h" > > int > main() { /* create lw3 */ > > int ncid; /* netCDF id */ > > /* dimension ids */ > int record_dim, z_dim, x_dim, y_dim; > > /* variable ids */ > int u_id, u_fcinv_id; > > /* variable shapes */ > int dims[4]; > > /* containers for scalar attributes */ > long long_val; > double double_val; > > /* enter define mode */ > ncid = nccreate("lw3", NC_CLOBBER); > > /* define dimensions */ > record_dim = ncdimdef(ncid, "record", NC_UNLIMITED); > z_dim = ncdimdef(ncid, "z", 22L); > x_dim = ncdimdef(ncid, "x", 61L); > y_dim = ncdimdef(ncid, "y", 61L); > > /* define variables */ > > dims[0] = record_dim; > dims[1] = z_dim; > dims[2] = y_dim; > dims[3] = x_dim; > u_id = ncvardef (ncid, "u", NC_FLOAT, 4, dims); > > dims[0] = record_dim; > dims[1] = z_dim; > u_fcinv_id = ncvardef (ncid, "u_fcinv", NC_SHORT, 2, dims); > > /* assign attributes */ > double_val = 1e+37; > ncattput (ncid, u_id, "_FillValue", NC_DOUBLE, 1,(void *) &double_val); > long_val = 0; > ncattput (ncid, u_fcinv_id, "_FillValue", NC_LONG, 1,(void *) &long_val); > > /* leave define mode */ > ncendef (ncid); > ncclose (ncid); > return 0; > } I get the same, so this indicates you are using the current version. > ***************************************** > The problem I am having is with the _FillValue attributes. > Variable u is declared as float, with a fillValue of 1.e+37. > IEEE specs for a float on a 32 bit machine allow 8 bits for > the exponent, which is more than capable of storing the > number 37. Ncgen sets up the _FillValue attribute as a > double, and tries to assign a double_val to the float variable. It uses a double, because the type of an attribute specified in a CDL file is implied by the way its value is specified, not from the type of variable the attribute is attached to. If you want the _FillValue to be of type float (which it should be for a floating-point variable), you must append "f" to the value, just as you would in C to specify a float rather than a double for a floating-point constant: u:_FillValue= 1.e+37f; > When ncendef is executed, there is a "FillValue mis-match" > error returned. Similarly, variable u_fcinv is declared as a > short, and ncgen sets up code to fill _FillValue with a long. Similarly to specify a short integer constant, you need to append "s" to the constant, as in: u_fcinv:_FillValue= 0s; > Any ideas on what's going on, and how to fix it? I use the > command ncgen -g "cdlfile" > "outfile" to generate the [I assume you meant you use the "-c" flag] > c code now, but will be running ncgen through a system call > to generate c code on the fly. Thus I won't be able to > adjust the output code, as I have been. I think if you make the above changes to your CDL file, things will work OK. The documentation for the syntax for CDL constants is in the netCDF User's Guide under the section "CDL Notation for Data Constants". If you're using a system() call, are you sure you don't want to just generate the netCDF file specified by the CDL file directly, by using "ncgen -b cdlfile > netcdffile" instead of producing C code and compiling it? The latter takes a *lot* longer, and won't work for files that have so much data that the generated C chokes the C compiler. -- Russ Rew UCAR Unidata Program address@hidden P.O. Box 3000 http://www.unidata.ucar.edu/ Boulder, CO 80307-3000