mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-03-07 17:08:02 +08:00
ported rename fix changes from branch ejh_fill_values for easy merging
This commit is contained in:
parent
2281f3e133
commit
3fa3d3f9f9
@ -102,6 +102,12 @@ typedef enum {VAR, DIM, ATT} NC_OBJ_T;
|
|||||||
* as the netCDF dimid. */
|
* as the netCDF dimid. */
|
||||||
#define NC_DIMID_ATT_NAME "_Netcdf4Dimid"
|
#define NC_DIMID_ATT_NAME "_Netcdf4Dimid"
|
||||||
|
|
||||||
|
/** This is the name of the class HDF5 dimension scale attribute. */
|
||||||
|
#define HDF5_DIMSCALE_CLASS_ATT_NAME "CLASS"
|
||||||
|
|
||||||
|
/** This is the name of the name HDF5 dimension scale attribute. */
|
||||||
|
#define HDF5_DIMSCALE_NAME_ATT_NAME "NAME"
|
||||||
|
|
||||||
/* Boolean type, to make the code easier to read */
|
/* Boolean type, to make the code easier to read */
|
||||||
typedef enum {NC_FALSE = 0, NC_TRUE = 1} nc_bool_t;
|
typedef enum {NC_FALSE = 0, NC_TRUE = 1} nc_bool_t;
|
||||||
|
|
||||||
@ -126,7 +132,7 @@ typedef struct NC_DIM_INFO
|
|||||||
nc_bool_t unlimited; /* True if the dimension is unlimited */
|
nc_bool_t unlimited; /* True if the dimension is unlimited */
|
||||||
nc_bool_t extended; /* True if the dimension needs to be extended */
|
nc_bool_t extended; /* True if the dimension needs to be extended */
|
||||||
nc_bool_t too_long; /* True if len is too big to fit in local size_t. */
|
nc_bool_t too_long; /* True if len is too big to fit in local size_t. */
|
||||||
hid_t hdf_dimscaleid;
|
hid_t hdf_dimscaleid; /* Non-zero if a DIM_WITHOUT_VARIABLE dataset is in use (no coord var). */
|
||||||
HDF5_OBJID_T hdf5_objid;
|
HDF5_OBJID_T hdf5_objid;
|
||||||
struct NC_VAR_INFO *coord_var; /* The coord var, if it exists. */
|
struct NC_VAR_INFO *coord_var; /* The coord var, if it exists. */
|
||||||
} NC_DIM_INFO_T;
|
} NC_DIM_INFO_T;
|
||||||
@ -344,6 +350,7 @@ int nc4_convert_type(const void *src, void *dest,
|
|||||||
/* These functions do HDF5 things. */
|
/* These functions do HDF5 things. */
|
||||||
int rec_detach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid);
|
int rec_detach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid);
|
||||||
int rec_reattach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid);
|
int rec_reattach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid);
|
||||||
|
int delete_existing_dimscale_dataset(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T *dim);
|
||||||
int nc4_open_var_grp2(NC_GRP_INFO_T *grp, int varid, hid_t *dataset);
|
int nc4_open_var_grp2(NC_GRP_INFO_T *grp, int varid, hid_t *dataset);
|
||||||
int nc4_put_vara(NC *nc, int ncid, int varid, const size_t *startp,
|
int nc4_put_vara(NC *nc, int ncid, int varid, const size_t *startp,
|
||||||
const size_t *countp, nc_type xtype, int is_long, void *op);
|
const size_t *countp, nc_type xtype, int is_long, void *op);
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
/* Copyright 2003-2018, University Corporation for Atmospheric
|
||||||
|
* Research. See the COPYRIGHT file for copying and redistribution
|
||||||
|
* conditions. */
|
||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* @internal This file is part of netcdf-4, a netCDF-like interface
|
* @internal This file is part of netcdf-4, a netCDF-like interface
|
||||||
@ -6,9 +9,6 @@
|
|||||||
*
|
*
|
||||||
* This file handles the nc4 dimension functions.
|
* This file handles the nc4 dimension functions.
|
||||||
*
|
*
|
||||||
* Copyright 2003-5, University Corporation for Atmospheric Research. See
|
|
||||||
* the COPYRIGHT file for copying and redistribution conditions.
|
|
||||||
*
|
|
||||||
* @author Ed Hartnett
|
* @author Ed Hartnett
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -103,8 +103,7 @@ NC4_def_dim(int ncid, const char *name, size_t len, int *idp)
|
|||||||
/* Find our global metadata structure. */
|
/* Find our global metadata structure. */
|
||||||
if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
|
if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
|
||||||
return retval;
|
return retval;
|
||||||
|
assert(h5 && nc && grp);
|
||||||
assert(h5 && nc /*& grp*/);
|
|
||||||
|
|
||||||
/* If the file is read-only, return an error. */
|
/* If the file is read-only, return an error. */
|
||||||
if (h5->no_write)
|
if (h5->no_write)
|
||||||
@ -327,9 +326,7 @@ NC4_rename_dim(int ncid, int dimid, const char *name)
|
|||||||
/* Find info for this file and group, and set pointer to each. */
|
/* Find info for this file and group, and set pointer to each. */
|
||||||
if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
|
if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
|
||||||
return retval;
|
return retval;
|
||||||
|
assert(nc && h5 && grp);
|
||||||
assert(nc);
|
|
||||||
assert(h5 && grp);
|
|
||||||
|
|
||||||
/* Trying to write to a read-only file? No way, Jose! */
|
/* Trying to write to a read-only file? No way, Jose! */
|
||||||
if (h5->no_write)
|
if (h5->no_write)
|
||||||
@ -352,33 +349,30 @@ NC4_rename_dim(int ncid, int dimid, const char *name)
|
|||||||
return NC_EBADDIM;
|
return NC_EBADDIM;
|
||||||
dim = tmp_dim;
|
dim = tmp_dim;
|
||||||
|
|
||||||
/* Check for renaming dimension w/o variable */
|
/* Check for renaming dimension w/o variable. */
|
||||||
if (dim->hdf_dimscaleid)
|
if (dim->hdf_dimscaleid)
|
||||||
{
|
{
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
assert(!dim->coord_var);
|
assert(!dim->coord_var);
|
||||||
|
LOG((3, "dim %s is a dim without variable", dim->name));
|
||||||
|
|
||||||
/* Close the HDF5 dataset */
|
/* Delete the dimscale-only dataset. */
|
||||||
if (H5Dclose(dim->hdf_dimscaleid) < 0)
|
if ((retval = delete_existing_dimscale_dataset(grp, dimid, dim)))
|
||||||
return NC_EHDFERR;
|
return retval;
|
||||||
dim->hdf_dimscaleid = 0;
|
|
||||||
|
|
||||||
/* Now delete the dataset (it will be recreated later, if necessary) */
|
|
||||||
if (H5Gunlink(grp->hdf_grpid, dim->name) < 0)
|
|
||||||
return NC_EDIMMETA;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Give the dimension its new name in metadata. UTF8 normalization
|
/* Give the dimension its new name in metadata. UTF8 normalization
|
||||||
* has been done. */
|
* has been done. */
|
||||||
if(dim->name)
|
assert(dim->name);
|
||||||
free(dim->name);
|
free(dim->name);
|
||||||
if (!(dim->name = malloc((strlen(norm_name) + 1) * sizeof(char))))
|
if (!(dim->name = malloc((strlen(norm_name) + 1) * sizeof(char))))
|
||||||
return NC_ENOMEM;
|
return NC_ENOMEM;
|
||||||
strcpy(dim->name, norm_name);
|
strcpy(dim->name, norm_name);
|
||||||
|
|
||||||
dim->hash = hash_fast(norm_name, strlen(norm_name));
|
dim->hash = hash_fast(norm_name, strlen(norm_name));
|
||||||
|
LOG((3, "dim is now named %s", dim->name));
|
||||||
|
|
||||||
/* Check if dimension was a coordinate variable, but names are different now */
|
/* Check if dimension was a coordinate variable, but names are
|
||||||
|
* different now */
|
||||||
if (dim->coord_var && strcmp(dim->name, dim->coord_var->name))
|
if (dim->coord_var && strcmp(dim->name, dim->coord_var->name))
|
||||||
{
|
{
|
||||||
/* Break up the coordinate variable */
|
/* Break up the coordinate variable */
|
||||||
@ -386,24 +380,24 @@ NC4_rename_dim(int ncid, int dimid, const char *name)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if dimension should become a coordinate variable */
|
/* Check if dimension should become a coordinate variable. */
|
||||||
if (!dim->coord_var)
|
if (!dim->coord_var)
|
||||||
{
|
{
|
||||||
NC_VAR_INFO_T *var;
|
NC_VAR_INFO_T *var;
|
||||||
|
|
||||||
/* Attempt to find a variable with the same name as the dimension in
|
/* Attempt to find a variable with the same name as the
|
||||||
* the current group. */
|
* dimension in the current group. */
|
||||||
if ((retval = nc4_find_var(grp, dim->name, &var)))
|
if ((retval = nc4_find_var(grp, dim->name, &var)))
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
/* Check if we found a variable and the variable has the dimension in
|
/* Check if we found a variable and the variable has the
|
||||||
* index 0. */
|
* dimension in index 0. */
|
||||||
if (var && var->dim[0] == dim)
|
if (var && var->dim[0] == dim)
|
||||||
{
|
{
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
assert(var->dimids[0] == dim->dimid);
|
assert(var->dimids[0] == dim->dimid);
|
||||||
|
|
||||||
/* Reform the coordinate variable */
|
/* Reform the coordinate variable. */
|
||||||
if ((retval = nc4_reform_coord_var(grp, var, dim)))
|
if ((retval = nc4_reform_coord_var(grp, var, dim)))
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -1526,7 +1526,9 @@ nc4_rec_grp_del(NC_GRP_INFO_T **list, NC_GRP_INFO_T *grp)
|
|||||||
while (dim)
|
while (dim)
|
||||||
{
|
{
|
||||||
LOG((4, "%s: deleting dim %s", __func__, dim->name));
|
LOG((4, "%s: deleting dim %s", __func__, dim->name));
|
||||||
/* Close HDF5 dataset associated with this dim. */
|
/* If this is a dim without a coordinate variable, then close
|
||||||
|
* the HDF5 DIM_WITHOUT_VARIABLE dataset associated with this
|
||||||
|
* dim. */
|
||||||
if (dim->hdf_dimscaleid && H5Dclose(dim->hdf_dimscaleid) < 0)
|
if (dim->hdf_dimscaleid && H5Dclose(dim->hdf_dimscaleid) < 0)
|
||||||
return NC_EHDFERR;
|
return NC_EHDFERR;
|
||||||
d = dim->l.next;
|
d = dim->l.next;
|
||||||
@ -1622,13 +1624,18 @@ nc4_att_list_del(NC_ATT_INFO_T **list, NC_ATT_INFO_T *att)
|
|||||||
* @internal Break a coordinate variable to separate the dimension and
|
* @internal Break a coordinate variable to separate the dimension and
|
||||||
* the variable.
|
* the variable.
|
||||||
*
|
*
|
||||||
|
* This is called from nc_rename_dim() and nc_rename_var(). In some
|
||||||
|
* renames, the coord variable must stay, but it is no longer a coord
|
||||||
|
* variable. This function changes a coord var into an ordinary
|
||||||
|
* variable.
|
||||||
|
*
|
||||||
* @param grp Pointer to group info struct.
|
* @param grp Pointer to group info struct.
|
||||||
* @param coord_var Pointer to variable info struct.
|
* @param coord_var Pointer to variable info struct.
|
||||||
* @param dim Pointer to dimension info struct.
|
* @param dim Pointer to dimension info struct.
|
||||||
*
|
*
|
||||||
* @return ::NC_NOERR No error.
|
* @return ::NC_NOERR No error.
|
||||||
* @return ::NC_ENOMEM Out of memory.
|
* @return ::NC_ENOMEM Out of memory.
|
||||||
* @author Quincey Koziol
|
* @author Quincey Koziol, Ed Hartnett
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
nc4_break_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *coord_var, NC_DIM_INFO_T *dim)
|
nc4_break_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *coord_var, NC_DIM_INFO_T *dim)
|
||||||
@ -1636,10 +1643,11 @@ nc4_break_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *coord_var, NC_DIM_INFO_T
|
|||||||
int retval = NC_NOERR;
|
int retval = NC_NOERR;
|
||||||
|
|
||||||
/* Sanity checks */
|
/* Sanity checks */
|
||||||
assert(dim->coord_var == coord_var);
|
assert(grp && coord_var && dim && dim->coord_var == coord_var &&
|
||||||
assert(coord_var->dim[0] == dim);
|
coord_var->dim[0] == dim && coord_var->dimids[0] == dim->dimid &&
|
||||||
assert(coord_var->dimids[0] == dim->dimid);
|
!dim->hdf_dimscaleid);
|
||||||
assert(0 == dim->hdf_dimscaleid);
|
LOG((3, "%s dim %s was associated with var %s, but now has different name",
|
||||||
|
__func__, dim->name, coord_var->name));
|
||||||
|
|
||||||
/* If we're replacing an existing dimscale dataset, go to
|
/* If we're replacing an existing dimscale dataset, go to
|
||||||
* every var in the file and detach this dimension scale. */
|
* every var in the file and detach this dimension scale. */
|
||||||
@ -1647,17 +1655,23 @@ nc4_break_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *coord_var, NC_DIM_INFO_T
|
|||||||
dim->dimid, coord_var->hdf_datasetid)))
|
dim->dimid, coord_var->hdf_datasetid)))
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
/* Allow attached dimscales to be tracked on the [former] coordinate variable */
|
/* Allow attached dimscales to be tracked on the [former]
|
||||||
|
* coordinate variable */
|
||||||
if (coord_var->ndims)
|
if (coord_var->ndims)
|
||||||
{
|
{
|
||||||
/* Coordinate variables shouldn't have dimscales attached */
|
/* Coordinate variables shouldn't have dimscales attached. */
|
||||||
assert(NULL == coord_var->dimscale_attached);
|
assert(!coord_var->dimscale_attached);
|
||||||
|
|
||||||
/* Allocate space for tracking them */
|
/* Allocate space for tracking them */
|
||||||
if (NULL == (coord_var->dimscale_attached = calloc(coord_var->ndims, sizeof(nc_bool_t))))
|
if (!(coord_var->dimscale_attached = calloc(coord_var->ndims,
|
||||||
|
sizeof(nc_bool_t))))
|
||||||
return NC_ENOMEM;
|
return NC_ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Remove the atts that go with being a coordinate var. */
|
||||||
|
/* if ((retval = remove_coord_atts(coord_var->hdf_datasetid))) */
|
||||||
|
/* return retval; */
|
||||||
|
|
||||||
/* Detach dimension from variable */
|
/* Detach dimension from variable */
|
||||||
coord_var->dimscale = NC_FALSE;
|
coord_var->dimscale = NC_FALSE;
|
||||||
dim->coord_var = NULL;
|
dim->coord_var = NULL;
|
||||||
@ -1669,9 +1683,54 @@ nc4_break_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *coord_var, NC_DIM_INFO_T
|
|||||||
return NC_NOERR;
|
return NC_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal Delete an existing dimscale-only dataset.
|
||||||
|
*
|
||||||
|
* A dimscale-only HDF5 dataset is created when a dim is defined
|
||||||
|
* without an accompanying coordinate variable.
|
||||||
|
*
|
||||||
|
* Sometimes, during renames, or late creation of variables, an
|
||||||
|
* existing, dimscale-only dataset must be removed. This means
|
||||||
|
* detatching all variables that use the dataset, then closing and
|
||||||
|
* unlinking it.
|
||||||
|
*
|
||||||
|
* @param grp The grp of the dimscale-only dataset to be deleted, or a
|
||||||
|
* higher group in the heirarchy (ex. root group).
|
||||||
|
* @param dim Pointer to the dim with the dimscale-only dataset to be
|
||||||
|
* deleted.
|
||||||
|
*
|
||||||
|
* @return ::NC_NOERR No error.
|
||||||
|
* @return ::NC_EHDFERR HDF5 error.
|
||||||
|
* @author Ed Hartnett
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
delete_existing_dimscale_dataset(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T *dim)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
assert(grp && dim);
|
||||||
|
LOG((2, "%s: deleting dimscale dataset %s dimid %d", __func__, dim->name,
|
||||||
|
dimid));
|
||||||
|
|
||||||
|
/* Detach dimscale from any variables using it */
|
||||||
|
if ((retval = rec_detach_scales(grp, dimid, dim->hdf_dimscaleid)) < 0)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
/* Close the HDF5 dataset */
|
||||||
|
if (H5Dclose(dim->hdf_dimscaleid) < 0)
|
||||||
|
return NC_EHDFERR;
|
||||||
|
dim->hdf_dimscaleid = 0;
|
||||||
|
|
||||||
|
/* Now delete the dataset. */
|
||||||
|
if (H5Gunlink(grp->hdf_grpid, dim->name) < 0)
|
||||||
|
return NC_EHDFERR;
|
||||||
|
|
||||||
|
return NC_NOERR;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal Reform a coordinate variable from a dimension and a
|
* @internal Reform a coordinate variable from a dimension and a
|
||||||
* variable
|
* variable.
|
||||||
*
|
*
|
||||||
* @param grp Pointer to group info struct.
|
* @param grp Pointer to group info struct.
|
||||||
* @param var Pointer to variable info struct.
|
* @param var Pointer to variable info struct.
|
||||||
@ -1683,8 +1742,12 @@ nc4_break_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *coord_var, NC_DIM_INFO_T
|
|||||||
int
|
int
|
||||||
nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, NC_DIM_INFO_T *dim)
|
nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, NC_DIM_INFO_T *dim)
|
||||||
{
|
{
|
||||||
|
int need_to_reattach_scales = 0;
|
||||||
int retval = NC_NOERR;
|
int retval = NC_NOERR;
|
||||||
|
|
||||||
|
assert(grp && var && dim);
|
||||||
|
LOG((3, "%s: dim->name %s var->name %s", __func__, dim->name, var->name));
|
||||||
|
|
||||||
/* Detach dimscales from the [new] coordinate variable */
|
/* Detach dimscales from the [new] coordinate variable */
|
||||||
if(var->dimscale_attached)
|
if(var->dimscale_attached)
|
||||||
{
|
{
|
||||||
@ -1694,6 +1757,7 @@ nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, NC_DIM_INFO_T *dim)
|
|||||||
|
|
||||||
/* Loop over all dimensions for variable */
|
/* Loop over all dimensions for variable */
|
||||||
for (d = 0; d < var->ndims && !finished; d++)
|
for (d = 0; d < var->ndims && !finished; d++)
|
||||||
|
{
|
||||||
/* Is there a dimscale attached to this axis? */
|
/* Is there a dimscale attached to this axis? */
|
||||||
if(var->dimscale_attached[d])
|
if(var->dimscale_attached[d])
|
||||||
{
|
{
|
||||||
@ -1704,6 +1768,7 @@ nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, NC_DIM_INFO_T *dim)
|
|||||||
NC_DIM_INFO_T *dim1;
|
NC_DIM_INFO_T *dim1;
|
||||||
|
|
||||||
for (dim1 = g->dim; dim1 && !finished; dim1 = dim1->l.next)
|
for (dim1 = g->dim; dim1 && !finished; dim1 = dim1->l.next)
|
||||||
|
{
|
||||||
if (var->dimids[d] == dim1->dimid)
|
if (var->dimids[d] == dim1->dimid)
|
||||||
{
|
{
|
||||||
hid_t dim_datasetid; /* Dataset ID for dimension */
|
hid_t dim_datasetid; /* Dataset ID for dimension */
|
||||||
@ -1713,24 +1778,36 @@ nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, NC_DIM_INFO_T *dim)
|
|||||||
dim_datasetid = dim1->coord_var->hdf_datasetid;
|
dim_datasetid = dim1->coord_var->hdf_datasetid;
|
||||||
else
|
else
|
||||||
dim_datasetid = dim1->hdf_dimscaleid;
|
dim_datasetid = dim1->hdf_dimscaleid;
|
||||||
assert(dim_datasetid > 0);
|
|
||||||
if (H5DSdetach_scale(var->hdf_datasetid, dim_datasetid, d) < 0)
|
/* dim_datasetid may be 0 in some cases when
|
||||||
BAIL(NC_EHDFERR);
|
* renames of dims and vars are happening. In
|
||||||
|
* this case, the scale has already been
|
||||||
|
* detached. */
|
||||||
|
if (dim_datasetid > 0)
|
||||||
|
{
|
||||||
|
LOG((3, "detaching scale from %s", var->name));
|
||||||
|
if (H5DSdetach_scale(var->hdf_datasetid, dim_datasetid, d) < 0)
|
||||||
|
BAIL(NC_EHDFERR);
|
||||||
|
}
|
||||||
var->dimscale_attached[d] = NC_FALSE;
|
var->dimscale_attached[d] = NC_FALSE;
|
||||||
if (dims_detached++ == var->ndims)
|
if (dims_detached++ == var->ndims)
|
||||||
finished++;
|
finished++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} /* next variable dimension */
|
||||||
|
|
||||||
/* Release & reset the array tracking attached dimscales */
|
/* Release & reset the array tracking attached dimscales */
|
||||||
free(var->dimscale_attached);
|
free(var->dimscale_attached);
|
||||||
var->dimscale_attached = NULL;
|
var->dimscale_attached = NULL;
|
||||||
|
need_to_reattach_scales++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use variable's dataset ID for the dimscale ID */
|
/* Use variable's dataset ID for the dimscale ID. */
|
||||||
if (dim->hdf_dimscaleid && grp != NULL)
|
if (dim->hdf_dimscaleid && grp != NULL)
|
||||||
{
|
{
|
||||||
|
LOG((3, "closing and unlinking dimscale dataset %s", dim->name));
|
||||||
if (H5Dclose(dim->hdf_dimscaleid) < 0)
|
if (H5Dclose(dim->hdf_dimscaleid) < 0)
|
||||||
BAIL(NC_EHDFERR);
|
BAIL(NC_EHDFERR);
|
||||||
dim->hdf_dimscaleid = 0;
|
dim->hdf_dimscaleid = 0;
|
||||||
@ -1746,7 +1823,7 @@ nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, NC_DIM_INFO_T *dim)
|
|||||||
dim->coord_var = var;
|
dim->coord_var = var;
|
||||||
|
|
||||||
/* Check if this variable used to be a coord. var */
|
/* Check if this variable used to be a coord. var */
|
||||||
if (var->was_coord_var && grp != NULL)
|
if (need_to_reattach_scales || (var->was_coord_var && grp != NULL))
|
||||||
{
|
{
|
||||||
/* Reattach the scale everywhere it is used. */
|
/* Reattach the scale everywhere it is used. */
|
||||||
/* (Recall that netCDF dimscales are always 1-D) */
|
/* (Recall that netCDF dimscales are always 1-D) */
|
||||||
|
@ -597,7 +597,7 @@ NC4_def_var(int ncid, const char *name, nc_type xtype,
|
|||||||
BAIL(NC_EBADTYPE);
|
BAIL(NC_EBADTYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a new var. */
|
/* Create a new var and fill in some HDF5 cache setting values. */
|
||||||
if ((retval = nc4_var_add(&var)))
|
if ((retval = nc4_var_add(&var)))
|
||||||
BAIL(retval);
|
BAIL(retval);
|
||||||
|
|
||||||
@ -654,18 +654,22 @@ NC4_def_var(int ncid, const char *name, nc_type xtype,
|
|||||||
var->dimscale = NC_TRUE;
|
var->dimscale = NC_TRUE;
|
||||||
dim->coord_var = var;
|
dim->coord_var = var;
|
||||||
|
|
||||||
/* Use variable's dataset ID for the dimscale ID */
|
/* Use variable's dataset ID for the dimscale ID. So delete
|
||||||
|
* the HDF5 DIM_WITHOUT_VARIABLE dataset that was created for
|
||||||
|
* this dim. */
|
||||||
if (dim->hdf_dimscaleid)
|
if (dim->hdf_dimscaleid)
|
||||||
{
|
{
|
||||||
/* Detach dimscale from any variables using it */
|
/* Detach dimscale from any variables using it */
|
||||||
if ((retval = rec_detach_scales(grp, dimidsp[d], dim->hdf_dimscaleid)) < 0)
|
if ((retval = rec_detach_scales(grp, dimidsp[d], dim->hdf_dimscaleid)) < 0)
|
||||||
BAIL(retval);
|
BAIL(retval);
|
||||||
|
|
||||||
|
/* Close the HDF5 DIM_WITHOUT_VARIABLE dataset. */
|
||||||
if (H5Dclose(dim->hdf_dimscaleid) < 0)
|
if (H5Dclose(dim->hdf_dimscaleid) < 0)
|
||||||
BAIL(NC_EHDFERR);
|
BAIL(NC_EHDFERR);
|
||||||
dim->hdf_dimscaleid = 0;
|
dim->hdf_dimscaleid = 0;
|
||||||
|
|
||||||
/* Now delete the dataset (it will be recreated later, if necessary) */
|
/* Now delete the DIM_WITHOUT_VARIABLE dataset (it will be
|
||||||
|
* recreated later, if necessary). */
|
||||||
if (H5Gunlink(grp->hdf_grpid, dim->name) < 0)
|
if (H5Gunlink(grp->hdf_grpid, dim->name) < 0)
|
||||||
BAIL(NC_EDIMMETA);
|
BAIL(NC_EDIMMETA);
|
||||||
}
|
}
|
||||||
@ -686,7 +690,7 @@ NC4_def_var(int ncid, const char *name, nc_type xtype,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Determine default chunksizes for this variable. (Even for
|
/* Determine default chunksizes for this variable. (Even for
|
||||||
* variables which may be contiguous. */
|
* variables which may be contiguous.) */
|
||||||
LOG((4, "allocating array of %d size_t to hold chunksizes for var %s",
|
LOG((4, "allocating array of %d size_t to hold chunksizes for var %s",
|
||||||
var->ndims, var->name));
|
var->ndims, var->name));
|
||||||
if (var->ndims)
|
if (var->ndims)
|
||||||
@ -743,8 +747,12 @@ exit:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal Get all the information about a variable. Pass NULL for whatever
|
* @internal Get all the information about a variable. Pass NULL for
|
||||||
* you don't care about.
|
* whatever you don't care about. This is the internal function called
|
||||||
|
* by nc_inq_var(), nc_inq_var_deflate(), nc_inq_var_fletcher32(),
|
||||||
|
* nc_inq_var_chunking(), nc_inq_var_chunking_ints(),
|
||||||
|
* nc_inq_var_fill(), nc_inq_var_endian(), nc_inq_var_filter(), and
|
||||||
|
* nc_inq_var_szip().
|
||||||
*
|
*
|
||||||
* @param ncid File ID.
|
* @param ncid File ID.
|
||||||
* @param varid Variable ID.
|
* @param varid Variable ID.
|
||||||
@ -1567,14 +1575,16 @@ NC4_rename_var(int ncid, int varid, const char *name)
|
|||||||
int retval = NC_NOERR;
|
int retval = NC_NOERR;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
LOG((2, "%s: ncid 0x%x varid %d name %s",
|
if (!name)
|
||||||
__func__, ncid, varid, name));
|
return NC_EINVAL;
|
||||||
|
|
||||||
|
LOG((2, "%s: ncid 0x%x varid %d name %s", __func__, ncid, varid,
|
||||||
|
name));
|
||||||
|
|
||||||
/* Find info for this file and group, and set pointer to each. */
|
/* Find info for this file and group, and set pointer to each. */
|
||||||
if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
|
if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
|
||||||
return retval;
|
return retval;
|
||||||
|
assert(h5 && grp && h5);
|
||||||
assert(h5);
|
|
||||||
|
|
||||||
/* Is the new name too long? */
|
/* Is the new name too long? */
|
||||||
if (strlen(name) > NC_MAX_NAME)
|
if (strlen(name) > NC_MAX_NAME)
|
||||||
@ -1612,9 +1622,19 @@ NC4_rename_var(int ncid, int varid, const char *name)
|
|||||||
return NC_ENOTINDEFINE;
|
return NC_ENOTINDEFINE;
|
||||||
|
|
||||||
/* Change the HDF5 file, if this var has already been created
|
/* Change the HDF5 file, if this var has already been created
|
||||||
there. */
|
there. Should we check here to ensure there is not already a
|
||||||
|
dimscale dataset of name name??? */
|
||||||
if (var->created)
|
if (var->created)
|
||||||
{
|
{
|
||||||
|
/* Is there an existing dimscale-only dataset of this name? If
|
||||||
|
* so, it must be deleted. */
|
||||||
|
if (var->ndims && var->dim[0]->hdf_dimscaleid)
|
||||||
|
{
|
||||||
|
if ((retval = delete_existing_dimscale_dataset(grp, var->dim[0]->dimid, var->dim[0])))
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG((3, "Moving dataset %s to %s", var->name, name));
|
||||||
if (H5Gmove(grp->hdf_grpid, var->name, name) < 0)
|
if (H5Gmove(grp->hdf_grpid, var->name, name) < 0)
|
||||||
BAIL(NC_EHDFERR);
|
BAIL(NC_EHDFERR);
|
||||||
}
|
}
|
||||||
@ -1625,6 +1645,7 @@ NC4_rename_var(int ncid, int varid, const char *name)
|
|||||||
return NC_ENOMEM;
|
return NC_ENOMEM;
|
||||||
strcpy(var->name, name);
|
strcpy(var->name, name);
|
||||||
var->hash = nn_hash;
|
var->hash = nn_hash;
|
||||||
|
LOG((3, "var is now %s", var->name));
|
||||||
|
|
||||||
/* Check if this was a coordinate variable previously, but names are different now */
|
/* Check if this was a coordinate variable previously, but names are different now */
|
||||||
if (var->dimscale && strcmp(var->name, var->dim[0]->name))
|
if (var->dimscale && strcmp(var->name, var->dim[0]->name))
|
||||||
|
@ -1,86 +1,121 @@
|
|||||||
/*
|
/*
|
||||||
* Demonstrate netcdf-4 rename bug.
|
* Test renames of vars and dims. It's a surprisingly tricky business.
|
||||||
|
*
|
||||||
|
* Quincey Koziol, Ed Hartnett
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <netcdf.h>
|
#include "nc_tests.h"
|
||||||
#include <stdio.h>
|
#include "err_macros.h"
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* On error, prints line number and file of test program. */
|
#define FILE_NAME3 "tst_rename_fix3.nc"
|
||||||
#define ERR do { \
|
#define FILE_NAME4 "tst_rename_fix4.nc"
|
||||||
fflush(stdout); \
|
#define ODIM_NAME "lat" /* name for coord dim */
|
||||||
fprintf(stderr, "Unexpected result, %s, line: %d\n", \
|
#define LAT "lat"
|
||||||
__FILE__, __LINE__); \
|
#define TAL "tal"
|
||||||
return 2; \
|
#define TAL1 "tal1"
|
||||||
} while (0)
|
#define TAL2 "tal2"
|
||||||
|
#define RH "rh"
|
||||||
|
#define NDIM_NAME "tal" /* new name for coord dim */
|
||||||
|
#define OVAR_NAME "lat" /* name for coord var */
|
||||||
|
#define NVAR_NAME "tal" /* new name for coord var */
|
||||||
|
#define OVAR2_NAME "rh" /* name for non-coord var that uses coord dim */
|
||||||
|
#define VAR_RANK 1 /* all vars in this test are of same rank */
|
||||||
|
#define DIM_LEN 2 /* all dims in this test are of same len */
|
||||||
|
|
||||||
#define FILE_NAME3 "tst_rnfix3.nc"
|
/* Test data. */
|
||||||
#define FILE_NAME4 "tst_rnfix4.nc"
|
int lats[DIM_LEN] = {-90, 90};
|
||||||
#define ODIM_NAME "lat" /* name for coord dim */
|
float rh[DIM_LEN] = {0.25, 0.75};
|
||||||
#define NDIM_NAME "tal" /* new name for coord dim */
|
|
||||||
#define OVAR_NAME "lat" /* name for coord var */
|
|
||||||
#define NVAR_NAME "tal" /* new name for coord var */
|
|
||||||
#define OVAR2_NAME "rh" /* name for non-coord var that uses coord dim */
|
|
||||||
#define VAR_RANK 1 /* all vars in this test are of same rank */
|
|
||||||
#define DIM_LEN 2 /* all dims in this test are of same len */
|
|
||||||
|
|
||||||
/* For renaming tests. Create small test file of specified format
|
/* For renaming tests. Create small test file of specified format
|
||||||
* with a coordinate dimension, corresponding coordinate variable, and
|
* with a coordinate dimension, corresponding coordinate variable, and
|
||||||
* a non-coordinate variable that uses the coordinate dimension.
|
* a non-coordinate variable that uses the coordinate dimension. */
|
||||||
*/
|
|
||||||
int
|
int
|
||||||
create_test_file(
|
create_test_file(char *path, int format)
|
||||||
char *path, /* filename */
|
|
||||||
int format /* NC_FORMAT_CLASSIC, NC_FORMAT_64BIT,
|
|
||||||
NC_FORMAT_NETCDF4, or NC_FORMAT_NETCDF4_CLASSIC */
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
int ncid, dimid, varid, var2id;
|
int ncid, varid, var2id;
|
||||||
int dims[VAR_RANK];
|
int dims[VAR_RANK];
|
||||||
int lats[DIM_LEN] = {-90, 90};
|
|
||||||
float rh[DIM_LEN] = {0.25, 0.75};
|
if (nc_set_default_format(format, NULL)) ERR;
|
||||||
switch (format) {
|
if (nc_create(path, 0, &ncid)) ERR;
|
||||||
case (NC_FORMAT_CLASSIC):
|
if (nc_def_dim(ncid, LAT, DIM_LEN, &dims[0])) ERR;
|
||||||
if (nc_create(path, 0, &ncid)) ERR;
|
if (nc_def_var(ncid, LAT, NC_INT, VAR_RANK, dims, &varid)) ERR;
|
||||||
break;
|
if (nc_def_var(ncid, RH, NC_FLOAT, VAR_RANK, dims, &var2id)) ERR;
|
||||||
case (NC_FORMAT_64BIT_OFFSET):
|
if (nc_enddef(ncid)) ERR; /* not necessary for netCDF-4 files */
|
||||||
if (nc_create(path, NC_64BIT_OFFSET, &ncid)) ERR;
|
if (nc_put_var_int(ncid, varid, lats)) ERR;
|
||||||
break;
|
if (nc_put_var_float(ncid, var2id, rh)) ERR;
|
||||||
case (NC_FORMAT_NETCDF4):
|
if (nc_close(ncid)) ERR;
|
||||||
if (nc_create(path, NC_NETCDF4, &ncid)) ERR;
|
return 0;
|
||||||
break;
|
}
|
||||||
case(NC_FORMAT_NETCDF4_CLASSIC):
|
|
||||||
if (nc_create(path, NC_NETCDF4 | NC_CLASSIC_MODEL, &ncid)) ERR;
|
/* Check the file that was produced by create_test_file(). Only the
|
||||||
break;
|
* names have been changed... */
|
||||||
default:
|
int
|
||||||
ERR;
|
check_file(int ncid, char *var0_name, char *var1_name, char *dim_name)
|
||||||
return NC_ENOTNC;
|
{
|
||||||
}
|
int varid;
|
||||||
if (nc_def_dim(ncid, ODIM_NAME, DIM_LEN, &dimid)) ERR;
|
int var2id;
|
||||||
dims[0] = dimid;
|
int dimid;
|
||||||
if (nc_def_var(ncid, OVAR_NAME, NC_INT, VAR_RANK, dims, &varid)) ERR;
|
int lats_in[DIM_LEN];
|
||||||
if (nc_def_var(ncid, OVAR2_NAME, NC_FLOAT, VAR_RANK, dims, &var2id)) ERR;
|
float rh_in[DIM_LEN];
|
||||||
if (nc_enddef(ncid)) ERR; /* not necessary for netCDF-4 files */
|
int ii;
|
||||||
if (nc_put_var_int(ncid, varid, lats)) ERR;
|
|
||||||
if (nc_put_var_float(ncid, var2id, rh)) ERR;
|
/* printf("checking for vars %s and %s, dim %s\n", var0_name, var1_name, */
|
||||||
if (nc_close(ncid)) ERR;
|
/* dim_name); */
|
||||||
return 0;
|
|
||||||
|
/* Check vars. Ids will change because of rename. */
|
||||||
|
if (nc_inq_varid(ncid, var0_name, &varid)) ERR;
|
||||||
|
if (nc_inq_varid(ncid, var1_name, &var2id)) ERR;
|
||||||
|
|
||||||
|
/* Check dim. */
|
||||||
|
if (nc_inq_dimid(ncid, dim_name, &dimid)) ERR;
|
||||||
|
if (dimid != 0) ERR;
|
||||||
|
|
||||||
|
/* Check the lats. */
|
||||||
|
if (nc_get_var_int(ncid, varid, lats_in)) ERR;
|
||||||
|
for (ii = 0; ii < DIM_LEN; ii++)
|
||||||
|
if (lats_in[ii] != lats[ii])
|
||||||
|
ERR;
|
||||||
|
|
||||||
|
/* Check the RH. */
|
||||||
|
if (nc_get_var_float(ncid, var2id, rh_in)) ERR;
|
||||||
|
for (ii = 0; ii < DIM_LEN; ii++)
|
||||||
|
if (rh_in[ii] != rh[ii])
|
||||||
|
ERR;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the file created in Charlie Zender's test. See github
|
||||||
|
* #597. */
|
||||||
|
int
|
||||||
|
check_charlies_file(char *file, char *dim_name, char *var_name)
|
||||||
|
{
|
||||||
|
int ncid;
|
||||||
|
int varid, dimid;
|
||||||
|
|
||||||
|
if (nc_open(file, 0, &ncid)) ERR;
|
||||||
|
if (nc_inq_varid(ncid, var_name, &varid)) ERR;
|
||||||
|
if (nc_inq_dimid(ncid, dim_name, &dimid)) ERR;
|
||||||
|
if (varid || dimid) ERR;
|
||||||
|
if (nc_close(ncid)) ERR;
|
||||||
|
return NC_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
#define NUM_FORMATS 2
|
#define NUM_FORMATS 2
|
||||||
int formats[NUM_FORMATS] = {NC_FORMAT_NETCDF4, NC_FORMAT_NETCDF4_CLASSIC};
|
int formats[NUM_FORMATS] = {NC_FORMAT_NETCDF4, NC_FORMAT_NETCDF4_CLASSIC};
|
||||||
char *fmt_names[] = {"netCDF-4", "netCDF-4 classic model"};
|
char *fmt_names[] = {"netCDF-4", "netCDF-4 classic model"};
|
||||||
char *file_names[] = {FILE_NAME3, FILE_NAME4};
|
char *file_names[] = {FILE_NAME3, FILE_NAME4};
|
||||||
int format;
|
int format;
|
||||||
|
|
||||||
fprintf(stderr,"*** Testing netcdf rename bugs and fixes.\n");
|
fprintf(stderr,"*** Testing netcdf rename bugs and fixes.\n");
|
||||||
|
nc_set_log_level(5);
|
||||||
|
|
||||||
for(format = 0; format < NUM_FORMATS; format++)
|
for (format = 0; format < NUM_FORMATS; format++)
|
||||||
{
|
/* for (format = 0; format < 1; format++) */
|
||||||
|
{
|
||||||
int ncid, dimid, varid, var2id;
|
int ncid, dimid, varid, var2id;
|
||||||
int lats[DIM_LEN] = {-90, 90};
|
int lats[DIM_LEN] = {-90, 90};
|
||||||
int lats_in[DIM_LEN];
|
int lats_in[DIM_LEN];
|
||||||
@ -88,80 +123,276 @@ main(int argc, char **argv)
|
|||||||
float rh_in[DIM_LEN];
|
float rh_in[DIM_LEN];
|
||||||
int ii;
|
int ii;
|
||||||
|
|
||||||
fprintf(stderr,"*** Test renaming coordinate variable and its dimension for %s...\n",
|
fprintf(stderr,"*** Test Charlie's test for renaming...");
|
||||||
fmt_names[format]);
|
{
|
||||||
if (create_test_file(file_names[format], formats[format])) ERR;
|
#define CHARLIE_TEST_FILE "tst_charlie_rename_coord_dim.nc"
|
||||||
if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
|
#define LON "lon"
|
||||||
if (nc_inq_dimid(ncid, ODIM_NAME, &dimid)) ERR;
|
#define LONGITUDE "longitude"
|
||||||
if (nc_inq_varid(ncid, OVAR_NAME, &varid)) ERR;
|
#define DIM1_LEN 4
|
||||||
if (nc_inq_varid(ncid, OVAR2_NAME, &var2id)) ERR;
|
#define NDIM1 1
|
||||||
if (nc_redef(ncid)) ERR; /* omitting this and nc_enddef call eliminates bug */
|
int ncid, dimid, varid;
|
||||||
if (nc_rename_dim(ncid, dimid, NDIM_NAME)) ERR;
|
float data[DIM1_LEN] = {0, 90.0, 180.0, 270.0};
|
||||||
if (nc_rename_var(ncid, varid, NVAR_NAME)) ERR;
|
|
||||||
if (nc_enddef(ncid)) ERR;
|
|
||||||
if (nc_get_var_int(ncid, varid, lats_in)) ERR;
|
|
||||||
for (ii = 0; ii < DIM_LEN; ii++) {
|
|
||||||
if (lats_in[ii] != lats[ii])
|
|
||||||
fprintf(stderr, "\tlats_in[%d] is %d, should be %d\n", ii, lats_in[ii], lats[ii]);
|
|
||||||
}
|
|
||||||
if (nc_get_var_float(ncid, var2id, rh_in)) ERR;
|
|
||||||
for (ii = 0; ii < DIM_LEN; ii++) {
|
|
||||||
if (rh_in[ii] != rh[ii])
|
|
||||||
fprintf(stderr, "\trh_in[%d] is %g, should be %g\n", ii, rh_in[ii], rh[ii]);
|
|
||||||
}
|
|
||||||
if (nc_close(ncid)) ERR;
|
|
||||||
|
|
||||||
fprintf(stderr,"*** Test renaming just coordinate variable for %s...\n",
|
/* Create a nice, simple file. This file will contain one
|
||||||
fmt_names[format]);
|
* dataset, "lon", which is a dimscale. */
|
||||||
if (create_test_file(file_names[format], formats[format])) ERR;
|
if (nc_create(CHARLIE_TEST_FILE, NC_NETCDF4, &ncid)) ERR;
|
||||||
if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
|
if (nc_def_dim(ncid, LON, DIM1_LEN, &dimid)) ERR;
|
||||||
if (nc_inq_dimid(ncid, ODIM_NAME, &dimid)) ERR;
|
if (nc_def_var(ncid, LON, NC_FLOAT, NDIM1, &dimid, &varid)) ERR;
|
||||||
if (nc_inq_varid(ncid, OVAR_NAME, &varid)) ERR;
|
if (nc_enddef(ncid)) ERR;
|
||||||
if (nc_inq_varid(ncid, OVAR2_NAME, &var2id)) ERR;
|
if (nc_put_var_float(ncid, varid, data)) ERR;
|
||||||
if (nc_redef(ncid)) ERR; /* omitting this and nc_enddef call eliminates bug */
|
if (nc_close(ncid)) ERR;
|
||||||
/* if (nc_rename_dim(ncid, dimid, NDIM_NAME)) ERR; */
|
|
||||||
if (nc_rename_var(ncid, varid, NVAR_NAME)) ERR;
|
|
||||||
if (nc_enddef(ncid)) ERR;
|
|
||||||
if (nc_get_var_int(ncid, varid, lats_in)) ERR;
|
|
||||||
for (ii = 0; ii < DIM_LEN; ii++) {
|
|
||||||
if (lats_in[ii] != lats[ii])
|
|
||||||
fprintf(stderr, "\tlats_in[%d] is %d, should be %d\n", ii, lats_in[ii], lats[ii]);
|
|
||||||
}
|
|
||||||
if (nc_get_var_float(ncid, var2id, rh_in)) ERR;
|
|
||||||
for (ii = 0; ii < DIM_LEN; ii++) {
|
|
||||||
if (rh_in[ii] != rh[ii])
|
|
||||||
fprintf(stderr, "\trh_in[%d] is %g, should be %g\n", ii, rh_in[ii], rh[ii]);
|
|
||||||
}
|
|
||||||
if (nc_close(ncid)) ERR;
|
|
||||||
|
|
||||||
|
/* Check the file. */
|
||||||
|
if (check_charlies_file(CHARLIE_TEST_FILE, LON, LON)) ERR;
|
||||||
|
|
||||||
fprintf(stderr,"*** Test renaming just coordinate dimension for %s...\n",
|
/* Open the file and rename the dimension. This will cause
|
||||||
fmt_names[format]);
|
* lon to stop being a coord var and dimscale, and create a
|
||||||
if (create_test_file(file_names[format], formats[format])) ERR;
|
* new dimscale without var dataset "longitude". Dataset
|
||||||
if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
|
* "lon" will point to "longitude" as its dimscale. */
|
||||||
if (nc_inq_dimid(ncid, ODIM_NAME, &dimid)) ERR;
|
if (nc_open(CHARLIE_TEST_FILE, NC_WRITE, &ncid)) ERR;
|
||||||
if (nc_inq_varid(ncid, OVAR_NAME, &varid)) ERR;
|
if (nc_redef(ncid)) ERR;
|
||||||
if (nc_inq_varid(ncid, OVAR2_NAME, &var2id)) ERR;
|
if (nc_rename_dim(ncid, 0, LONGITUDE)) ERR;
|
||||||
if (nc_redef(ncid)) ERR; /* omitting this and nc_enddef call eliminates bug */
|
if (nc_enddef(ncid)) ERR;
|
||||||
if (nc_rename_dim(ncid, dimid, NDIM_NAME)) ERR;
|
if (nc_close(ncid)) ERR;
|
||||||
/* if (nc_rename_var(ncid, varid, NVAR_NAME)) ERR; */
|
|
||||||
if (nc_enddef(ncid)) ERR;
|
|
||||||
if (nc_get_var_int(ncid, varid, lats_in)) ERR;
|
|
||||||
for (ii = 0; ii < DIM_LEN; ii++) {
|
|
||||||
if (lats_in[ii] != lats[ii])
|
|
||||||
fprintf(stderr, "\tlats_in[%d] is %d, should be %d\n", ii, lats_in[ii], lats[ii]);
|
|
||||||
}
|
|
||||||
if (nc_get_var_float(ncid, var2id, rh_in)) ERR;
|
|
||||||
for (ii = 0; ii < DIM_LEN; ii++) {
|
|
||||||
if (rh_in[ii] != rh[ii])
|
|
||||||
fprintf(stderr, "\trh_in[%d] is %g, should be %g\n", ii, rh_in[ii], rh[ii]);
|
|
||||||
}
|
|
||||||
if (nc_close(ncid)) ERR;
|
|
||||||
|
|
||||||
if (formats[format] == NC_FORMAT_NETCDF4) {
|
/* Reopen the file to check. */
|
||||||
printf("*** Test renaming attribute in sub-group for %s...\n",
|
if (check_charlies_file(CHARLIE_TEST_FILE, LONGITUDE, LON)) ERR;
|
||||||
|
|
||||||
|
/* Open the file and rename the variable. This will remove
|
||||||
|
* the dimscale-only dataset "longitude" and rename the
|
||||||
|
* extisting dataset "lon" to "longitude". Variable
|
||||||
|
* "longitude" will become a coordinate var. */
|
||||||
|
/* if (nc_open(CHARLIE_TEST_FILE, NC_WRITE, &ncid)) ERR; */
|
||||||
|
/* if (nc_redef(ncid)) ERR; */
|
||||||
|
/* if (nc_rename_var(ncid, 0, LONGITUDE)) ERR; */
|
||||||
|
/* if (nc_enddef(ncid)) ERR; */
|
||||||
|
/* if (nc_close(ncid)) ERR; */
|
||||||
|
|
||||||
|
/* Reopen the file to check. */
|
||||||
|
/* if (check_charlies_file(CHARLIE_TEST_FILE, LONGITUDE, LONGITUDE)) ERR; */
|
||||||
|
}
|
||||||
|
SUMMARIZE_ERR;
|
||||||
|
|
||||||
|
printf("*** testing renaming before enddef for %s...", fmt_names[format]);
|
||||||
|
{
|
||||||
|
int ncid, varid, var2id;
|
||||||
|
int dimid;
|
||||||
|
|
||||||
|
if (nc_set_default_format(formats[format], NULL)) ERR;
|
||||||
|
if (nc_create(file_names[format], 0, &ncid)) ERR;
|
||||||
|
if (nc_def_dim(ncid, LAT, DIM_LEN, &dimid)) ERR;
|
||||||
|
if (nc_def_var(ncid, LAT, NC_INT, VAR_RANK, &dimid, &varid)) ERR;
|
||||||
|
if (nc_def_var(ncid, RH, NC_FLOAT, VAR_RANK, &dimid, &var2id)) ERR;
|
||||||
|
|
||||||
|
/* Now rename the dim. */
|
||||||
|
if (nc_rename_dim(ncid, dimid, TAL)) ERR;
|
||||||
|
if (nc_rename_var(ncid, varid, TAL)) ERR;
|
||||||
|
|
||||||
|
if (nc_enddef(ncid)) ERR; /* not necessary for netCDF-4 files */
|
||||||
|
if (nc_put_var_int(ncid, varid, lats)) ERR;
|
||||||
|
if (nc_put_var_float(ncid, var2id, rh)) ERR;
|
||||||
|
if (nc_close(ncid)) ERR;
|
||||||
|
|
||||||
|
/* Reopen and check. */
|
||||||
|
if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
|
||||||
|
if (check_file(ncid, TAL, RH, TAL)) ERR;
|
||||||
|
if (nc_close(ncid)) ERR;
|
||||||
|
}
|
||||||
|
SUMMARIZE_ERR;
|
||||||
|
|
||||||
|
printf("*** testing renaming after enddef for %s...", fmt_names[format]);
|
||||||
|
{
|
||||||
|
int ncid, varid, var2id;
|
||||||
|
int dimid;
|
||||||
|
|
||||||
|
if (nc_set_default_format(formats[format], NULL)) ERR;
|
||||||
|
if (nc_create(file_names[format], 0, &ncid)) ERR;
|
||||||
|
if (nc_def_dim(ncid, LAT, DIM_LEN, &dimid)) ERR;
|
||||||
|
if (nc_def_var(ncid, TAL1, NC_INT, VAR_RANK, &dimid, &varid)) ERR;
|
||||||
|
if (nc_def_var(ncid, RH, NC_FLOAT, VAR_RANK, &dimid, &var2id)) ERR;
|
||||||
|
if (nc_enddef(ncid)) ERR;
|
||||||
|
if (nc_redef(ncid)) ERR;
|
||||||
|
|
||||||
|
if (nc_rename_var(ncid, varid, TAL2)) ERR;
|
||||||
|
if (nc_rename_dim(ncid, dimid, TAL)) ERR;
|
||||||
|
if (nc_enddef(ncid)) ERR;
|
||||||
|
|
||||||
|
if (nc_put_var_int(ncid, varid, lats)) ERR;
|
||||||
|
if (nc_put_var_float(ncid, var2id, rh)) ERR;
|
||||||
|
if (nc_close(ncid)) ERR;
|
||||||
|
|
||||||
|
/* Reopen and check. */
|
||||||
|
if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
|
||||||
|
if (check_file(ncid, TAL2, RH, TAL)) ERR;
|
||||||
|
if (nc_close(ncid)) ERR;
|
||||||
|
}
|
||||||
|
SUMMARIZE_ERR;
|
||||||
|
printf("*** testing more renaming after enddef for %s...", fmt_names[format]);
|
||||||
|
{
|
||||||
|
int ncid, varid, var2id;
|
||||||
|
int dimid;
|
||||||
|
|
||||||
|
/* This will create a HDF5 file with two datasets, RH, and
|
||||||
|
* LAT. LAT is a dimscale. RH points to dimscale LAT. Life is
|
||||||
|
* so simple. */
|
||||||
|
if (nc_set_default_format(formats[format], NULL)) ERR;
|
||||||
|
if (nc_create(file_names[format], 0, &ncid)) ERR;
|
||||||
|
if (nc_def_dim(ncid, LAT, DIM_LEN, &dimid)) ERR;
|
||||||
|
if (nc_def_var(ncid, LAT, NC_INT, VAR_RANK, &dimid, &varid)) ERR;
|
||||||
|
if (nc_def_var(ncid, RH, NC_FLOAT, VAR_RANK, &dimid, &var2id)) ERR;
|
||||||
|
if (nc_enddef(ncid)) ERR;
|
||||||
|
if (nc_redef(ncid)) ERR;
|
||||||
|
|
||||||
|
/* This will cause dataset LAT to be renamed TAL. It will no
|
||||||
|
* longer be a dimscale. Dataset LAT will be created as a
|
||||||
|
* dimscale without a variable. Datasets RH and TAL will
|
||||||
|
* re-point to (new) dimscale LAT. */
|
||||||
|
if (nc_rename_var(ncid, varid, TAL)) ERR;
|
||||||
|
if (nc_enddef(ncid)) ERR;
|
||||||
|
|
||||||
|
if (nc_redef(ncid)) ERR;
|
||||||
|
|
||||||
|
/* This will cause dimscale-only dataset LAT to be
|
||||||
|
* deleted. Existing dataset TAL will become the dimscale
|
||||||
|
* dataset. Dataset RH will re-point to dimscale TAL. */
|
||||||
|
if (nc_rename_dim(ncid, dimid, TAL)) ERR;
|
||||||
|
if (nc_enddef(ncid)) ERR;
|
||||||
|
|
||||||
|
/* Varids have changed, so get them again. */
|
||||||
|
if (nc_inq_varid(ncid, TAL, &varid)) ERR;
|
||||||
|
if (nc_inq_varid(ncid, RH, &var2id)) ERR;
|
||||||
|
|
||||||
|
/* Write some data. */
|
||||||
|
if (nc_put_var_int(ncid, varid, lats)) ERR;
|
||||||
|
if (nc_put_var_float(ncid, var2id, rh)) ERR;
|
||||||
|
if (nc_close(ncid)) ERR;
|
||||||
|
|
||||||
|
/* Reopen and check. */
|
||||||
|
if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
|
||||||
|
if (check_file(ncid, TAL, RH, TAL)) ERR;
|
||||||
|
if (nc_close(ncid)) ERR;
|
||||||
|
}
|
||||||
|
SUMMARIZE_ERR;
|
||||||
|
|
||||||
|
printf("*** testing renaming after enddef for %s...", fmt_names[format]);
|
||||||
|
{
|
||||||
|
int ncid, varid, var2id;
|
||||||
|
int dimid;
|
||||||
|
|
||||||
|
if (nc_set_default_format(formats[format], NULL)) ERR;
|
||||||
|
if (nc_create(file_names[format], 0, &ncid)) ERR;
|
||||||
|
if (nc_def_dim(ncid, LAT, DIM_LEN, &dimid)) ERR;
|
||||||
|
if (nc_def_var(ncid, LAT, NC_INT, VAR_RANK, &dimid, &varid)) ERR;
|
||||||
|
if (nc_def_var(ncid, RH, NC_FLOAT, VAR_RANK, &dimid, &var2id)) ERR;
|
||||||
|
if (nc_enddef(ncid)) ERR; /* not necessary for netCDF-4 files */
|
||||||
|
if (nc_redef(ncid)) ERR; /* not necessary for netCDF-4 files */
|
||||||
|
|
||||||
|
/* Now rename the dim. */
|
||||||
|
if (nc_rename_dim(ncid, dimid, TAL)) ERR;
|
||||||
|
if (nc_rename_var(ncid, varid, TAL)) ERR;
|
||||||
|
if (nc_enddef(ncid)) ERR; /* not necessary for netCDF-4 files */
|
||||||
|
|
||||||
|
if (nc_put_var_int(ncid, varid, lats)) ERR;
|
||||||
|
if (nc_put_var_float(ncid, var2id, rh)) ERR;
|
||||||
|
if (nc_close(ncid)) ERR;
|
||||||
|
|
||||||
|
/* Reopen and check. */
|
||||||
|
if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
|
||||||
|
/* if (check_file(ncid, LAT, RH, TAL)) ERR; */
|
||||||
|
/* if (check_file(ncid, TAL, RH, TAL)) ERR; */
|
||||||
|
if (nc_close(ncid)) ERR;
|
||||||
|
}
|
||||||
|
SUMMARIZE_ERR;
|
||||||
|
|
||||||
|
printf("*** testing renaming after enddef for %s...", fmt_names[format]);
|
||||||
|
{
|
||||||
|
/* Create a file with datasets LAT, RH. LAT is a dimscale. RH
|
||||||
|
* points to LAT. */
|
||||||
|
if (create_test_file(file_names[format], formats[format])) ERR;
|
||||||
|
if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
|
||||||
|
if (nc_inq_dimid(ncid, LAT, &dimid)) ERR;
|
||||||
|
if (nc_inq_varid(ncid, LAT, &varid)) ERR;
|
||||||
|
if (nc_inq_varid(ncid, RH, &var2id)) ERR;
|
||||||
|
if (check_file(ncid, LAT, RH, LAT)) ERR;
|
||||||
|
if (nc_redef(ncid)) ERR;
|
||||||
|
|
||||||
|
/* Rename the dim. This creates new dataset TAL. LAT is no
|
||||||
|
* longer a dimscale. RH is repointed to TAL. LAT is pointed
|
||||||
|
* to TAL. */
|
||||||
|
if (nc_rename_dim(ncid, dimid, TAL)) ERR;
|
||||||
|
if (nc_enddef(ncid)) ERR;
|
||||||
|
if (nc_redef(ncid)) ERR;
|
||||||
|
|
||||||
|
/* Rename the var. This will remove dimscale-only dataset
|
||||||
|
* TAL. LAT will become a dimscale. RH will point to LAT. */
|
||||||
|
if (nc_rename_var(ncid, varid, TAL)) ERR;
|
||||||
|
if (nc_enddef(ncid)) ERR;
|
||||||
|
/* if (check_file(ncid, LAT, RH, TAL)) ERR; */
|
||||||
|
if (nc_close(ncid)) ERR;
|
||||||
|
|
||||||
|
if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
|
||||||
|
/* if (check_file(ncid, LAT, RH, TAL)) ERR; */
|
||||||
|
if (nc_close(ncid)) ERR;
|
||||||
|
}
|
||||||
|
SUMMARIZE_ERR;
|
||||||
|
|
||||||
|
fprintf(stderr,"*** Test renaming just coordinate variable for %s...",
|
||||||
|
fmt_names[format]);
|
||||||
|
{
|
||||||
|
if (create_test_file(file_names[format], formats[format])) ERR;
|
||||||
|
if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
|
||||||
|
if (nc_inq_dimid(ncid, ODIM_NAME, &dimid)) ERR;
|
||||||
|
if (nc_inq_varid(ncid, OVAR_NAME, &varid)) ERR;
|
||||||
|
if (nc_inq_varid(ncid, OVAR2_NAME, &var2id)) ERR;
|
||||||
|
if (nc_redef(ncid)) ERR; /* omitting this and nc_enddef call eliminates bug */
|
||||||
|
/* if (nc_rename_dim(ncid, dimid, NDIM_NAME)) ERR; */
|
||||||
|
if (nc_rename_var(ncid, varid, NVAR_NAME)) ERR;
|
||||||
|
if (nc_enddef(ncid)) ERR;
|
||||||
|
if (nc_get_var_int(ncid, varid, lats_in)) ERR;
|
||||||
|
for (ii = 0; ii < DIM_LEN; ii++) {
|
||||||
|
if (lats_in[ii] != lats[ii])
|
||||||
|
fprintf(stderr, "\tlats_in[%d] is %d, should be %d\n", ii, lats_in[ii], lats[ii]);
|
||||||
|
}
|
||||||
|
if (nc_get_var_float(ncid, var2id, rh_in)) ERR;
|
||||||
|
for (ii = 0; ii < DIM_LEN; ii++) {
|
||||||
|
if (rh_in[ii] != rh[ii])
|
||||||
|
fprintf(stderr, "\trh_in[%d] is %g, should be %g\n", ii, rh_in[ii], rh[ii]);
|
||||||
|
}
|
||||||
|
if (nc_close(ncid)) ERR;
|
||||||
|
}
|
||||||
|
SUMMARIZE_ERR;
|
||||||
|
|
||||||
|
fprintf(stderr,"*** Test renaming just coordinate dimension for %s...",
|
||||||
|
fmt_names[format]);
|
||||||
|
{
|
||||||
|
if (create_test_file(file_names[format], formats[format])) ERR;
|
||||||
|
if (nc_open(file_names[format], NC_WRITE, &ncid)) ERR;
|
||||||
|
if (nc_inq_dimid(ncid, ODIM_NAME, &dimid)) ERR;
|
||||||
|
if (nc_inq_varid(ncid, OVAR_NAME, &varid)) ERR;
|
||||||
|
if (nc_inq_varid(ncid, OVAR2_NAME, &var2id)) ERR;
|
||||||
|
if (nc_redef(ncid)) ERR; /* omitting this and nc_enddef call eliminates bug */
|
||||||
|
if (nc_rename_dim(ncid, dimid, NDIM_NAME)) ERR;
|
||||||
|
/* if (nc_rename_var(ncid, varid, NVAR_NAME)) ERR; */
|
||||||
|
if (nc_enddef(ncid)) ERR;
|
||||||
|
if (nc_get_var_int(ncid, varid, lats_in)) ERR;
|
||||||
|
for (ii = 0; ii < DIM_LEN; ii++) {
|
||||||
|
if (lats_in[ii] != lats[ii])
|
||||||
|
fprintf(stderr, "\tlats_in[%d] is %d, should be %d\n", ii, lats_in[ii], lats[ii]);
|
||||||
|
}
|
||||||
|
if (nc_get_var_float(ncid, var2id, rh_in)) ERR;
|
||||||
|
for (ii = 0; ii < DIM_LEN; ii++) {
|
||||||
|
if (rh_in[ii] != rh[ii])
|
||||||
|
fprintf(stderr, "\trh_in[%d] is %g, should be %g\n", ii, rh_in[ii], rh[ii]);
|
||||||
|
}
|
||||||
|
if (nc_close(ncid)) ERR;
|
||||||
|
}
|
||||||
|
SUMMARIZE_ERR;
|
||||||
|
|
||||||
|
if (formats[format] == NC_FORMAT_NETCDF4)
|
||||||
|
{
|
||||||
|
printf("*** Test renaming attribute in sub-group for %s...",
|
||||||
fmt_names[format]);
|
fmt_names[format]);
|
||||||
{
|
{
|
||||||
#define DIMNAME "lon"
|
#define DIMNAME "lon"
|
||||||
#define VARNAME "lon"
|
#define VARNAME "lon"
|
||||||
#define G1_VARNAME "lon"
|
#define G1_VARNAME "lon"
|
||||||
@ -199,16 +430,16 @@ main(int argc, char **argv)
|
|||||||
if (nc_enddef (ncid)) ERR;
|
if (nc_enddef (ncid)) ERR;
|
||||||
/* write variable data */
|
/* write variable data */
|
||||||
{
|
{
|
||||||
float lon_data[4] = {0, 90, 180, 270};
|
float lon_data[4] = {0, 90, 180, 270};
|
||||||
size_t start[] = {0};
|
size_t start[] = {0};
|
||||||
size_t count[] = {4};
|
size_t count[] = {4};
|
||||||
if (nc_put_vara(ncid, lon_var, start, count, lon_data)) ERR;
|
if (nc_put_vara(ncid, lon_var, start, count, lon_data)) ERR;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
float g1_lon_data[4] = {0, 90, 180, 270};
|
float g1_lon_data[4] = {0, 90, 180, 270};
|
||||||
size_t start[] = {0};
|
size_t start[] = {0};
|
||||||
size_t count[] = {4};
|
size_t count[] = {4};
|
||||||
if (nc_put_vara(g1_grp, g1_lon_var, start, count, g1_lon_data)) ERR;
|
if (nc_put_vara(g1_grp, g1_lon_var, start, count, g1_lon_data)) ERR;
|
||||||
}
|
}
|
||||||
if (nc_close(ncid)) ERR;
|
if (nc_close(ncid)) ERR;
|
||||||
|
|
||||||
@ -223,17 +454,17 @@ main(int argc, char **argv)
|
|||||||
has expected value */
|
has expected value */
|
||||||
{
|
{
|
||||||
|
|
||||||
if (nc_open(file_names[format], NC_NOWRITE, &ncid)) ERR;
|
if (nc_open(file_names[format], NC_NOWRITE, &ncid)) ERR;
|
||||||
if (nc_inq_grp_ncid(ncid, GRP_NAME, &g1_grp)) ERR;
|
if (nc_inq_grp_ncid(ncid, GRP_NAME, &g1_grp)) ERR;
|
||||||
if (nc_inq_varid(g1_grp, VARNAME, &g1_lon_var)) ERR;
|
if (nc_inq_varid(g1_grp, VARNAME, &g1_lon_var)) ERR;
|
||||||
if (nc_get_att_text(g1_grp, g1_lon_var, NEW_NAME, data_in)) ERR;
|
if (nc_get_att_text(g1_grp, g1_lon_var, NEW_NAME, data_in)) ERR;
|
||||||
if (strncmp(CONTENTS, data_in, strlen(CONTENTS))) ERR;
|
if (strncmp(CONTENTS, data_in, strlen(CONTENTS))) ERR;
|
||||||
if (nc_close(ncid)) ERR;
|
if (nc_close(ncid)) ERR;
|
||||||
}
|
}
|
||||||
free(data_in);
|
free(data_in);
|
||||||
}
|
}
|
||||||
|
SUMMARIZE_ERR;
|
||||||
}
|
}
|
||||||
}
|
} /* next format */
|
||||||
|
FINAL_RESULTS;
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user