Hello all,
I suspect it is an "operator error", but I tried all possible
interpretations of the API documentation and can not fill data block
with either nc_put_vara_double() or nc_put_vars_double().
nc_put_var1_double() works as expected.
A simple test program is attached ("#define WRITE_MODE ..." controls
type of write).
Here is a snapshot of non-working code:
...
double ray_data[RANGE_BINS_COUNT] = {0.0};
...
for (sweep_idx = 0; sweep_idx < SWEEPS_COUNT; sweep_idx++ )
for(ray_idx = 0; ray_idx < RAYS_PER_SWEEP_COUNT; ray_idx++ ) {
size_t start[3] = {sweep_idx, ray_idx, 0};
size_t count[3] = {0, 0, RANGE_BINS_COUNT};
status = nc_put_vara_double(ncid, dbz_id, start, count, ray_data);
if (status != NC_NOERR)
handle_error(status);
}
...
nc_put_vara_double() call does not fail, but "dbz_id" data set remains
uninitialized. Everything works as expected when nc_put_var1_double()
is used instead:
...
for (sweep_idx = 0; sweep_idx < SWEEPS_COUNT; sweep_idx++)
for (ray_idx = 0; ray_idx < RAYS_PER_SWEEP_COUNT; ray_idx++)
for (bin_idx = 0; bin_idx < RANGE_BINS_COUNT; bin_idx++) {
size_t index_3d[3] = {sweep_idx, ray_idx, bin_idx};
double val = 0.0;
status = nc_put_var1_double(ncid, dbz_id, index_3d, &val);
if (status != NC_NOERR)
handle_error(status);
}
...
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netcdf.h>
#define USE_VAR1 0
#define USE_VARA 1
#define USE_VARS 2
#define WRITE_MODE USE_VARA
void handle_error(int status) {
if (status != NC_NOERR) {
fprintf(stderr, "%s\n", nc_strerror(status));
exit(-1);
}
}
#define RANGE_BINS_COUNT 64
#define SWEEPS_COUNT 4
#define RAYS_PER_SWEEP_COUNT 90
int main()
{
int status, ncid;
int sweep, ray, bin, data_dim[3];
int dbz_id, zdr_id;
int sweep_idx, ray_idx, bin_idx;
const char * site_name = "Some Site";
const char * task_name = "Some_Task";
double ray_data[RANGE_BINS_COUNT] = {0.0};
printf("NetCDF: %s\n", nc_inq_libvers());
status = nc_create("nctest.nc", NC_NOCLOBBER, &ncid);
if (status != NC_NOERR)
handle_error(status);
status = nc_def_dim(ncid, "sweeps", SWEEPS_COUNT, &sweep);
if (status != NC_NOERR)
handle_error(status);
status = nc_def_dim(ncid, "rays", RAYS_PER_SWEEP_COUNT, &ray);
if (status != NC_NOERR)
handle_error(status);
status = nc_def_dim(ncid, "bins", RANGE_BINS_COUNT, &bin);
if (status != NC_NOERR)
handle_error(status);
/* Global Attributes */
status = nc_put_att_text (ncid, NC_GLOBAL, "site",
strlen(site_name), site_name);
if (status != NC_NOERR)
handle_error(status);
status = nc_put_att_text (ncid, NC_GLOBAL, "task",
strlen(task_name), task_name);
if (status != NC_NOERR)
handle_error(status);
data_dim[0] = sweep;
data_dim[1] = ray;
data_dim[2] = bin;
status = nc_def_var (ncid, "Z", NC_DOUBLE, 3, data_dim, &dbz_id);
if (status != NC_NOERR)
handle_error(status);
status = nc_put_att_text (ncid, dbz_id, "units",
strlen("dBZ"), "dBZ");
if (status != NC_NOERR)
handle_error(status);
status = nc_put_att_text (ncid, dbz_id, "name",
strlen("Reflectivity (Z)"),
"Reflectivity (Z)");
if (status != NC_NOERR)
handle_error(status);
status = nc_def_var (ncid, "ZDR", NC_DOUBLE, 3, data_dim, &zdr_id);
if (status != NC_NOERR)
handle_error(status);
status = nc_put_att_text (ncid, zdr_id, "name",
strlen("Differential Reflectivity (ZDR)"),
"Differential Reflectivity (ZDR)");
if (status != NC_NOERR)
handle_error(status);
status = nc_put_att_text (ncid, zdr_id, "units",
strlen("dB"), "dB");
if (status != NC_NOERR)
handle_error(status);
status = nc_enddef(ncid); /* end definitions: leave define mode */
if (status != NC_NOERR)
handle_error(status);
#if (WRITE_MODE == USE_VAR1)
fprintf(stderr, "One-by-one\n\n");
for (sweep_idx = 0; sweep_idx < SWEEPS_COUNT; sweep_idx++)
for (ray_idx = 0; ray_idx < RAYS_PER_SWEEP_COUNT; ray_idx++)
for (bin_idx = 0; bin_idx < RANGE_BINS_COUNT; bin_idx++) {
size_t index_3d[3] = {sweep_idx, ray_idx, bin_idx};
double val = 0.0;
status = nc_put_var1_double(ncid, dbz_id, index_3d, &val);
if (status != NC_NOERR)
handle_error(status);
status = nc_put_var1_double(ncid, zdr_id, index_3d, &val);
if (status != NC_NOERR)
handle_error(status);
}
#elif (WRITE_MODE == USE_VARA)
fprintf(stderr, "Via _put_vara_\n\n");
for (sweep_idx = 0; sweep_idx < SWEEPS_COUNT; sweep_idx++)
for (ray_idx = 0; ray_idx < RAYS_PER_SWEEP_COUNT; ray_idx++) {
size_t start[3] = {sweep_idx, ray_idx, 0};
size_t count[3] = {0, 0, RANGE_BINS_COUNT};
status = nc_put_vara_double(ncid, dbz_id, start, count, ray_data);
if (status != NC_NOERR)
handle_error(status);
status = nc_put_vara_double(ncid, zdr_id, start, count, ray_data);
if (status != NC_NOERR)
handle_error(status);
}
#elif (WRITE_MODE == USE_VARS)
fprintf(stderr, "Via _put_vars_\n\n");
for (sweep_idx = 0; sweep_idx < SWEEPS_COUNT; sweep_idx++ )
for(ray_idx = 0; ray_idx < RAYS_PER_SWEEP_COUNT; ray_idx++ ) {
size_t start[3] = {sweep_idx, ray_idx, 0};
size_t count[3] = {0, 0, RANGE_BINS_COUNT};
ptrdiff_t stride[3] = {1, 1, 1};
status = nc_put_vars_double(ncid, dbz_id, start, count, stride,
ray_data);
if (status != NC_NOERR)
handle_error(status);
status = nc_put_vars_double(ncid, zdr_id, start, count, stride,
ray_data);
if (status != NC_NOERR)
handle_error(status);
}
#endif
/* close: save new netCDF dataset */
status = nc_close(ncid);
if (status != NC_NOERR)
handle_error(status);
return 0;
}