netcdf-c/nc_test4/tst_dims3.c
Dennis Heimbigner 25f062528b This completes (for now) the refactoring of libsrc4.
The file docs/indexing.dox tries to provide design
information for the refactoring.

The primary change is to replace all walking of linked
lists with the use of the NCindex data structure.
Ncindex is a combination of a hash table (for name-based
lookup) and a vector (for walking the elements in the index).
Additionally, global vectors are added to NC_HDF5_FILE_INFO_T
to support direct mapping of an e.g. dimid to the NC_DIM_INFO_T
object. These global vectors exist for dimensions, types, and groups
because they have globally unique id numbers.

WARNING:
1. since libsrc4 and libsrchdf4 share code, there are also
   changes in libsrchdf4.
2. Any outstanding pull requests that change libsrc4 or libhdf4
   are likely to cause conflicts with this code.
3. The original reason for doing this was for performance improvements,
   but as noted elsewhere, this may not be significant because
   the meta-data read performance apparently is being dominated
   by the hdf5 library because we do bulk meta-data reading rather
   than lazy reading.
2018-03-16 11:46:18 -06:00

203 lines
8.2 KiB
C

/* This is part of the netCDF package. Copyright 2008 University
Corporation for Atmospheric Research/Unidata See COPYRIGHT file for
conditions of use. See www.unidata.ucar.edu for more info.
Test netcdf-4 dimensions inheritance.
$Id: tst_dims3.c,v 1.7 2010/05/25 13:53:04 ed Exp $
*/
#include <config.h>
#include <nc_tests.h>
#include "err_macros.h"
int
main(int argc, char **argv)
{
printf("\n*** Testing netcdf-4 dimensions even more.\n");
printf("*** testing netcdf-4 dimension inheritance...");
{
#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;
size_t len;
int time_data[NUM_TIMES] = {1, 2} ;
size_t time_startset[TIME_RANK] = {0} ;
size_t time_countset[TIME_RANK] = {NUM_TIMES} ;
/* Create file with unlimited dim and associated coordinate
* variable in root group, another variable that uses unlimited
* dim in subgroup. */
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
if (nc_def_grp(ncid, GRP_NAME, &grpid)) ERR;
if (nc_def_dim(ncid, TIME_NAME, NC_UNLIMITED, &time_dim)) ERR;
if (nc_def_var(ncid, TIME_NAME, NC_INT, TIME_RANK, &time_dim,
&time_var)) ERR;
if (nc_def_var(grpid, VAR2_NAME, NC_INT, TIME_RANK, &time_dim,
&z_var)) ERR;
if (nc_enddef(ncid)) ERR;
/* Assign data to time variable, creating two times */
if (nc_put_vara(ncid, time_dim, time_startset, time_countset,
time_data)) ERR;
/* Check the dim len from the root group */
if (nc_inq_dimlen(ncid, time_dim, &len)) ERR;
if (len != NUM_TIMES) ERR;
/* Check the dim len from the sub group */
if (nc_inq_dimlen(grpid, time_dim, &len)) ERR;
if (len != NUM_TIMES) ERR;
if (nc_close(ncid)) ERR;
/* Now check how many times there are from the subgroup */
if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
if (nc_inq_ncid(ncid, GRP_NAME, &grpid)) ERR;
if (nc_inq_dimid(ncid, TIME_NAME, &time_dim)) ERR;
/* Check the dim len from the root group */
if (nc_inq_dimlen(ncid, time_dim, &len)) ERR;
if (len != NUM_TIMES) ERR;
/* Check the dim len from the sub group */
if (nc_inq_dimlen(grpid, time_dim, &len)) ERR;
if (len != NUM_TIMES) ERR;
/* Find the dimension by name. */
if (nc_inq_dimid(grpid, TIME_NAME, &time_dim_in)) ERR;
if (time_dim_in != time_dim) ERR;
if (nc_close(ncid)) ERR;
}
SUMMARIZE_ERR;
printf("*** testing a scalar coordinate dimension...");
{
int ncid, dimid, varid;
float data = 42.5;
/* Create a scalar coordinate dimension. The only reason that
* the user can ever possibly have for doing this is just
* because they like to make life difficult for poor, poor
* netCDF programmers, trapped in this horrible place, in a
* Rocky Mountain valley, drenched in sunlight, with a stream
* quietly gurgling, deer feeding on the grasses, and all those
* damn birds chirping! */
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR_RET;
if (nc_def_dim(ncid, "scalar", 0, &dimid)) ERR_RET;
if (nc_def_var(ncid, "scalar", NC_FLOAT, 0, &dimid, &varid)) ERR_RET;
if (nc_put_var_float(ncid, varid, &data)) ERR_RET;
if (nc_close(ncid))
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, g2lev_dimid, g2vrt_dimid;
int time_dimid_in, lev_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, g2lev_dimid, g2vrt_dimid;
int time_dimid_in, lev_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;
}