mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-12-27 08:49:16 +08:00
Merged latest from trunk
This commit is contained in:
commit
618f3ea1a5
@ -8,6 +8,11 @@ VERSION COMMENTS
|
||||
------- --------
|
||||
4.3 Released 201?-??-??
|
||||
|
||||
Fixed netCDF-4 bug with particular order of
|
||||
creation of dimensions, coordinate variables, and
|
||||
subgroups resulting in two dimensions with the same
|
||||
dimension ID. [NCF-244]
|
||||
|
||||
Fixed bug with incorrect fixed-size variable offsets in header
|
||||
getting written when schema changed for files created
|
||||
by parallel-netcdf. Thanks to Wei-keng Liao for
|
||||
|
@ -317,6 +317,7 @@ int nc4_pg_varm(NC_PG_T pg, NC *nc, int ncid, int varid, const size_t *startp,
|
||||
const size_t *countp, const ptrdiff_t *stridep,
|
||||
const ptrdiff_t *imapp, nc_type xtype, int is_long, void *op);
|
||||
int nc4_rec_match_dimscales(NC_GRP_INFO_T *grp);
|
||||
int nc4_rec_detect_bad_coord_order(NC_GRP_INFO_T *grp, int *bad_coord_orderp);
|
||||
int nc4_rec_write_metadata(NC_GRP_INFO_T *grp, int bad_coord_order);
|
||||
int nc4_rec_write_types(NC_GRP_INFO_T *grp);
|
||||
int nc4_enddef_netcdf4_file(NC_HDF5_FILE_INFO_T *h5);
|
||||
|
@ -2964,6 +2964,8 @@ sync_netcdf4_file(NC_HDF5_FILE_INFO_T *h5)
|
||||
int bad_coord_order = 0; /* if detected, propagate to all groups to consistently store dimids */
|
||||
if ((retval = nc4_rec_write_types(h5->root_grp)))
|
||||
return retval;
|
||||
if ((retval = nc4_rec_detect_bad_coord_order(h5->root_grp, &bad_coord_order)))
|
||||
return retval;
|
||||
if ((retval = nc4_rec_write_metadata(h5->root_grp, bad_coord_order)))
|
||||
return retval;
|
||||
}
|
||||
|
@ -2425,26 +2425,18 @@ write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, int write_dimid)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Recursively write all the metadata in a group. Groups and types
|
||||
* have all already been written. Propagate bad cooordinate order to
|
||||
* subgroups, if detected. */
|
||||
/* Recursively determine if there is a mismatch between order of
|
||||
* coordinate creation and associated dimensions in this group or any
|
||||
* subgroups, to find out if we have to handle that situation. */
|
||||
int
|
||||
nc4_rec_write_metadata(NC_GRP_INFO_T *grp, int bad_coord_order)
|
||||
nc4_rec_detect_bad_coord_order(NC_GRP_INFO_T *grp, int *bad_coord_orderp)
|
||||
{
|
||||
NC_DIM_INFO_T *dim;
|
||||
NC_VAR_INFO_T *var;
|
||||
NC_GRP_INFO_T *child_grp;
|
||||
int found_coord, coord_varid = -1, wrote_coord;
|
||||
int last_dimid = -1;
|
||||
int retval;
|
||||
|
||||
assert(grp && grp->name && grp->hdf_grpid);
|
||||
LOG((3, "nc4_rec_write_metadata: grp->name %s, bad_coord_order %d", grp->name, bad_coord_order));
|
||||
|
||||
/* Write global attributes for this group. */
|
||||
if ((retval = write_attlist(grp->att, NC_GLOBAL, grp)))
|
||||
return retval;
|
||||
|
||||
/* If the user writes coord vars in a different order then he
|
||||
* defined their dimensions, then, when the file is reopened, the
|
||||
* order of the dimids will change to match the order of the coord
|
||||
@ -2456,8 +2448,8 @@ nc4_rec_write_metadata(NC_GRP_INFO_T *grp, int bad_coord_order)
|
||||
{
|
||||
if (var->dimids[0] < last_dimid)
|
||||
{
|
||||
bad_coord_order++;
|
||||
break;
|
||||
*bad_coord_orderp = 1;
|
||||
return NC_NOERR;
|
||||
}
|
||||
last_dimid = var->dimids[0];
|
||||
}
|
||||
@ -2472,9 +2464,39 @@ nc4_rec_write_metadata(NC_GRP_INFO_T *grp, int bad_coord_order)
|
||||
if (!strcmp(dim->name, var->name) && !dim->dirty)
|
||||
{
|
||||
LOG((5, "coord var defined after enddef/redef"));
|
||||
bad_coord_order++;
|
||||
*bad_coord_orderp = 1;
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
/* If there are any child groups, check them also for this condition. */
|
||||
for (child_grp = grp->children; child_grp; child_grp = child_grp->next)
|
||||
if ((retval = nc4_rec_detect_bad_coord_order(child_grp, bad_coord_orderp)))
|
||||
return retval;
|
||||
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
|
||||
/* Recursively write all the metadata in a group. Groups and types
|
||||
* have all already been written. Propagate bad cooordinate order to
|
||||
* subgroups, if detected. */
|
||||
int
|
||||
nc4_rec_write_metadata(NC_GRP_INFO_T *grp, int bad_coord_order)
|
||||
{
|
||||
NC_DIM_INFO_T *dim;
|
||||
NC_VAR_INFO_T *var;
|
||||
NC_GRP_INFO_T *child_grp;
|
||||
int found_coord, coord_varid = -1, wrote_coord;
|
||||
|
||||
int last_dimid = -1;
|
||||
int retval;
|
||||
|
||||
assert(grp && grp->name && grp->hdf_grpid);
|
||||
LOG((3, "nc4_rec_write_metadata: grp->name %s, bad_coord_order %d", grp->name, bad_coord_order));
|
||||
|
||||
/* Write global attributes for this group. */
|
||||
if ((retval = write_attlist(grp->att, NC_GLOBAL, grp)))
|
||||
return retval;
|
||||
|
||||
/* For some stupid reason, the dim list is stored backwards! Get to
|
||||
* the back of the list. */
|
||||
|
@ -20,10 +20,18 @@ nc_set_log_level(0);
|
||||
#define FILE_NAME "tst_dims3.nc"
|
||||
#define RANK_time 1
|
||||
#define GRP_NAME "G"
|
||||
#define GRP2_NAME "G2"
|
||||
#define TIME_NAME "time"
|
||||
#define VAR2_NAME "z"
|
||||
#define TIME_RANK 1
|
||||
#define NUM_TIMES 2
|
||||
#define LEV_NAME "level"
|
||||
#define VRT_NAME "vert_number"
|
||||
#define LEV_NUM 3
|
||||
#define LEV_RANK 1
|
||||
#define VRT_RANK 1
|
||||
#define VAR2_RANK 2
|
||||
#define NUM_VRT 3
|
||||
int ncid, grpid;
|
||||
int time_dim, time_dim_in;
|
||||
int time_var, z_var;
|
||||
@ -97,5 +105,98 @@ nc_set_log_level(0);
|
||||
ERR_RET;
|
||||
}
|
||||
SUMMARIZE_ERR;
|
||||
printf("*** testing defining dimensions and coord variables in different orders in root group...");
|
||||
{
|
||||
int ncid, grpid, grp2id;
|
||||
int time_dimid, lev_dimid, vrt_dimid, g2lev_dimid, g2vrt_dimid;
|
||||
int time_dimid_in, lev_dimid_in, vrt_dimid_in, g2lev_dimid_in, g2vrt_dimid_in;
|
||||
int time_varid, lev_varid, gvar2_varid, g2lev_varid, g2vrt_varid;
|
||||
int var2_dims[VAR2_RANK];
|
||||
/* Create test for fix of bug that resulted in two dimensions
|
||||
* having the same dimid, which violates the Pauli exclusion
|
||||
* principle for dimensions. */
|
||||
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR_RET;
|
||||
if (nc_def_grp(ncid, GRP_NAME, &grpid)) ERR;
|
||||
if (nc_def_dim(ncid, TIME_NAME, NC_UNLIMITED, &time_dimid)) ERR_RET;
|
||||
if (nc_def_dim(ncid, LEV_NAME, LEV_NUM, &lev_dimid)) ERR_RET;
|
||||
var2_dims[0] = time_dimid;
|
||||
var2_dims[1] = lev_dimid;
|
||||
if (nc_def_var(grpid, VAR2_NAME, NC_FLOAT, VAR2_RANK, var2_dims, &gvar2_varid)) ERR;
|
||||
/* define coord vars in opposite order of coord dims */
|
||||
if (nc_def_var(ncid, LEV_NAME, NC_FLOAT, LEV_RANK, &lev_dimid, &lev_varid)) ERR;
|
||||
if (nc_def_var(ncid, TIME_NAME, NC_FLOAT, TIME_RANK, &time_dimid, &time_varid)) ERR;
|
||||
|
||||
if (nc_def_grp(ncid, GRP2_NAME, &grp2id)) ERR;
|
||||
if (nc_def_dim(grp2id, LEV_NAME, LEV_NUM, &g2lev_dimid)) ERR_RET;
|
||||
if (nc_def_dim(grp2id, VRT_NAME, NUM_VRT, &g2vrt_dimid)) ERR_RET;
|
||||
if (nc_def_var(grp2id, LEV_NAME, NC_FLOAT, LEV_RANK, &g2lev_dimid, &g2lev_varid)) ERR;
|
||||
if (nc_def_var(grp2id, VRT_NAME, NC_FLOAT, VRT_RANK, &g2vrt_dimid, &g2vrt_varid)) ERR;
|
||||
if (nc_close(ncid)) ERR;
|
||||
|
||||
/* Re-open, in which dimids may get reassigned */
|
||||
if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
|
||||
if (nc_inq_dimid(ncid, TIME_NAME, &time_dimid_in)) ERR;
|
||||
if (nc_inq_dimid(ncid, LEV_NAME, &lev_dimid_in)) ERR;
|
||||
if (nc_inq_ncid(ncid, GRP2_NAME, &grp2id)) ERR;
|
||||
if (nc_inq_dimid(grp2id, LEV_NAME, &g2lev_dimid_in)) ERR;
|
||||
if (nc_inq_dimid(grp2id, VRT_NAME, &g2vrt_dimid_in)) ERR;
|
||||
/* dimids must still all be distinct */
|
||||
if (time_dimid_in == lev_dimid_in ||
|
||||
time_dimid_in == g2lev_dimid_in ||
|
||||
time_dimid_in == g2vrt_dimid_in ||
|
||||
lev_dimid_in == g2lev_dimid_in ||
|
||||
lev_dimid_in == g2vrt_dimid_in ||
|
||||
g2lev_dimid_in == g2vrt_dimid_in) ERR;
|
||||
|
||||
if (nc_close(ncid))
|
||||
ERR_RET;
|
||||
}
|
||||
SUMMARIZE_ERR;
|
||||
printf("*** testing defining dimensions and coord variables in different orders in subgroup...");
|
||||
{
|
||||
int ncid, grpid, grp2id;
|
||||
int time_dimid, lev_dimid, vrt_dimid, g2lev_dimid, g2vrt_dimid;
|
||||
int time_dimid_in, lev_dimid_in, vrt_dimid_in, g2lev_dimid_in, g2vrt_dimid_in;
|
||||
int time_varid, lev_varid, gvar2_varid, g2lev_varid, g2vrt_varid;
|
||||
int var2_dims[VAR2_RANK];
|
||||
/* Create test for fix of bug inside a subgroup that results in two dimensions
|
||||
* having the same dimid. */
|
||||
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR_RET;
|
||||
if (nc_def_grp(ncid, GRP_NAME, &grpid)) ERR;
|
||||
if (nc_def_dim(ncid, TIME_NAME, NC_UNLIMITED, &time_dimid)) ERR_RET;
|
||||
if (nc_def_dim(ncid, LEV_NAME, LEV_NUM, &lev_dimid)) ERR_RET;
|
||||
var2_dims[0] = time_dimid;
|
||||
var2_dims[1] = lev_dimid;
|
||||
if (nc_def_var(grpid, VAR2_NAME, NC_FLOAT, VAR2_RANK, var2_dims, &gvar2_varid)) ERR;
|
||||
if (nc_def_var(ncid, TIME_NAME, NC_FLOAT, TIME_RANK, &time_dimid, &time_varid)) ERR;
|
||||
if (nc_def_var(ncid, LEV_NAME, NC_FLOAT, LEV_RANK, &lev_dimid, &lev_varid)) ERR;
|
||||
|
||||
if (nc_def_grp(ncid, GRP2_NAME, &grp2id)) ERR;
|
||||
if (nc_def_dim(grp2id, LEV_NAME, LEV_NUM, &g2lev_dimid)) ERR_RET;
|
||||
if (nc_def_dim(grp2id, VRT_NAME, NUM_VRT, &g2vrt_dimid)) ERR_RET;
|
||||
/* define coord vars in opposite order of coord dims */
|
||||
if (nc_def_var(grp2id, VRT_NAME, NC_FLOAT, VRT_RANK, &g2vrt_dimid, &g2vrt_varid)) ERR;
|
||||
if (nc_def_var(grp2id, LEV_NAME, NC_FLOAT, LEV_RANK, &g2lev_dimid, &g2lev_varid)) ERR;
|
||||
if (nc_close(ncid)) ERR;
|
||||
|
||||
/* Re-open, in which dimids may get reassigned */
|
||||
if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
|
||||
if (nc_inq_dimid(ncid, TIME_NAME, &time_dimid_in)) ERR;
|
||||
if (nc_inq_dimid(ncid, LEV_NAME, &lev_dimid_in)) ERR;
|
||||
if (nc_inq_ncid(ncid, GRP2_NAME, &grp2id)) ERR;
|
||||
if (nc_inq_dimid(grp2id, LEV_NAME, &g2lev_dimid_in)) ERR;
|
||||
if (nc_inq_dimid(grp2id, VRT_NAME, &g2vrt_dimid_in)) ERR;
|
||||
/* dimids must still all be distinct */
|
||||
if (time_dimid_in == lev_dimid_in ||
|
||||
time_dimid_in == g2lev_dimid_in ||
|
||||
time_dimid_in == g2vrt_dimid_in ||
|
||||
lev_dimid_in == g2lev_dimid_in ||
|
||||
lev_dimid_in == g2vrt_dimid_in ||
|
||||
g2lev_dimid_in == g2vrt_dimid_in) ERR;
|
||||
|
||||
if (nc_close(ncid))
|
||||
ERR_RET;
|
||||
}
|
||||
SUMMARIZE_ERR;
|
||||
FINAL_RESULTS;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user