Example #1
0
/* Get the dimids for a fortran function (i.e. add 1 to each
 * dimid.) */
extern int
nc_inq_dimids_f(int ncid, int *ndims, int *fdimids, int parent)
{
   int *dimids, ndims1;
   int i, ret = NC_NOERR;

   /* Get the information from the C library. */
   if ((ret = nc_inq_dimids(ncid, &ndims1, NULL, parent)))
      return ret;
   if (!(dimids = malloc(ndims1 * sizeof(int))))
      return NC_ENOMEM;
   if ((ret = nc_inq_dimids(ncid, NULL, dimids, parent)))
      goto exit;

   /* Add one to each, for fortran. */
   for (i = 0; i < ndims1; i++)
      fdimids[i] = dimids[i] + 1;

   /* Tell the user how many there are. */
   if (ndims)
      *ndims = ndims1;

  exit:
   free(dimids);
   return ret;
}
Example #2
0
   std::vector<std::string> CONetCDF4::getDimensionsIdList (const std::string * _varname)
   {
      char full_name_in[NC_MAX_NAME +1];
      int nbdim = 0, *dimid = NULL;
      int grpid = this->getCurrentGroup();
      int varid = (_varname != NULL) ? this->getVariable(*_varname) : NC_GLOBAL;
      std::vector<std::string> retvalue;

      if (_varname != NULL)
      {
         CheckError(nc_inq_varndims(grpid, varid, &nbdim));
         dimid = new int[nbdim]();
         CheckError(nc_inq_vardimid(grpid, varid, dimid));
      }
      else
      {
         CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1));
         dimid = new int[nbdim]();
         CheckError(nc_inq_dimids(grpid, NULL, dimid, 1));
      }

      for (int i = 0; i < nbdim; i++)
      {
         CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in));
         std::string dimname(full_name_in);
         retvalue.push_back(dimname);
      }
      delete [] dimid;

      return (retvalue);
   }
Example #3
0
/* NOTE that 'dimids' must ALREADY be allocated to ndims
*/
void R_nc4_inq_dimids( int *ncid, int *dimids, int *retval )
{
	int dummy_ndims, include_parents;

	include_parents = 0;
        *retval = nc_inq_dimids( *ncid, &dummy_ndims, dimids, include_parents );
	if( *retval != NC_NOERR ) 
		Rprintf( "Error in R_nc4_inq_dimids call with ncid=%d: %s\n", 
			*ncid, nc_strerror(*retval) );
}
/*!
This function makes a request to netcdf, to find all dimension in a group
\param [in] ncid Groupd id (or File Id)
\param [in/out] nDims number of list of dimension
\param [in/out] dimIds list of dimension in a group or any of its parent
\param [in] includeParents number of parents
\return Status code
*/
int CNetCdfInterface::inqDimIds(int ncid, int& nDims, int* dimIds, int includeParents)
{
  int status = nc_inq_dimids(ncid, &nDims, dimIds, includeParents);
  if (NC_NOERR != status)
  {
    StdString errormsg(nc_strerror(status));
    StdStringStream sstr;

    sstr << "Error when calling function nc_inq_dimids(ncid, &nDims, dimIds, includeParents)" << std::endl;
    sstr << errormsg << std::endl;
    sstr << "Unable to retrieve number of dimension in the group with id: " << ncid << std::endl;
    sstr << "With number of Parents " << includeParents << std::endl;
    StdString e = sstr.str();
    throw CNetCdfException(e);
  }

  return status;
}
Example #5
0
int
main(int argc, char **argv) 
{/* create file that caused seg fault in ncdump */

    int  ncid;  /* netCDF id */

    /* dimension ids */
    int Time_dim;
    int X_dim;
    int Y_dim;

    /* dimension lengths */
    size_t Time_len = NC_UNLIMITED;
    size_t X_len = 4;
    size_t Y_len = 3;

    /* variable ids */
    int Time_id;
    int P_id;

    /* rank (number of dimensions) for each variable */
#   define RANK_Time 1
#   define RANK_P 3

    /* variable shapes */
    int Time_dims[RANK_Time];
    int P_dims[RANK_P];

   printf("\n*** Testing preparation of fillbug test.\n");
   printf("*** creating fillbug test file %s...", FILENAME);

    /* enter define mode */
    if (nc_create(FILENAME, NC_CLOBBER|NC_NETCDF4, &ncid)) ERR;

    /* define dimensions */
    if (nc_def_dim(ncid, "Time", Time_len, &Time_dim)) ERR;
    if (nc_def_dim(ncid, "X", X_len, &X_dim)) ERR;
    if (nc_def_dim(ncid, "Y", Y_len, &Y_dim)) ERR;

    /* define variables */

    Time_dims[0] = Time_dim;
    if (nc_def_var(ncid, "Time", NC_DOUBLE, RANK_Time, Time_dims, &Time_id)) ERR;

    P_dims[0] = Time_dim;
    P_dims[1] = Y_dim;
    P_dims[2] = X_dim;
    if (nc_def_var(ncid, "P", NC_FLOAT, RANK_P, P_dims, &P_id)) ERR;

    /* leave define mode */
    if (nc_enddef (ncid)) ERR;

    {/* assign variable data */
    static double Time_data[1]={3.14159};
    static size_t Time_startset[1] = {0};
    static size_t Time_countset[1] = {1};
    if (nc_put_vara(ncid, Time_id, Time_startset, Time_countset, Time_data)) ERR;
    }

    if (nc_close(ncid)) ERR;

    /* Try to duplicate segfault ncdump gets by making the same calls
     * to the netCDF-4 library, in the same order.  This doesn't
     * result in the same segfault, so either we have missed a call
     * made by ncdump, or an earlier ncdump bug masks the real problem
     * until a call is made into the netCDF-4 library ...  */
    if (nc_open(FILENAME, NC_NOWRITE, &ncid)) ERR;
    
    {   		
	/* We declare local arrays with small constant sizes to avoid
	 * all the mallocs and frees used in ncdump.  For the example
	 * above, the fixed-size arrays are ample. */
	int format, ndims, nvars, ngatts, xdimid, ndims_grp, dimids_grp[3],
	    unlimids[1], d_grp, nunlim, nvars_grp, varids_grp[3], v_grp,
	    varid, varndims, vardims[3], varnatts, vartype, dimids[3], is_recvar,
	    vdims[3], id, ntypes, numgrps, atttype, nc_status;
	size_t dimsize, len, attlen;
	char dimname[20], varname[20];
	if ( nc_inq_format(ncid, &format)) ERR;
	ntypes = count_udtypes(ncid);
	if ( nc_inq_typeids(ncid, &ntypes, NULL) ) ERR;
	if ( nc_inq_format(ncid, &format)) ERR;
	if ( nc_inq_grps(ncid, &numgrps, NULL) ) ERR;
	if ( nc_inq_typeids(ncid, &ntypes, NULL) ) ERR;
	if ( nc_inq(ncid, &ndims, &nvars, &ngatts, &xdimid) ) ERR;
	if ( nc_inq_ndims(ncid, &ndims_grp) ) ERR;
	if ( nc_inq_dimids(ncid, 0, dimids_grp, 0) ) ERR;
	if ( nc_inq_unlimdims(ncid, &nunlim, NULL) ) ERR;
	if ( nc_inq_unlimdims(ncid, &nunlim, unlimids) ) ERR;
	for (d_grp = 0; d_grp < ndims_grp; d_grp++) {
	    int dimid = dimids_grp[d_grp];
	    if ( nc_inq_dim(ncid, dimid, dimname, &dimsize) ) ERR;
	}
	if ( nc_inq_format(ncid, &format) ) ERR;
	if ( nc_inq_varids(ncid, &nvars_grp, varids_grp) ) ERR;
	for (v_grp = 0; v_grp < nvars_grp; v_grp++) {
	    varid = varids_grp[v_grp];
	    if ( nc_inq_varndims(ncid, varid, &varndims) ) ERR;
	    if ( nc_inq_var(ncid, varid, varname, &vartype, 0, vardims, 
			    &varnatts) ) ERR;
	    for (id = 0; id < varndims; id++) {
		if ( nc_inq_dimname(ncid, vardims[id], dimname) ) ERR;
	    }
	}
	for (v_grp = 0; v_grp < nvars_grp; v_grp++) {
	    varid = varids_grp[v_grp];
	    if( nc_inq_varndims(ncid, varid, &varndims) ) ERR;
	    if( nc_inq_var(ncid, varid, varname, &vartype, 0, vardims, 
			   &varnatts) ) ERR;
	    {
		is_recvar = 0;
		if ( nc_inq_varndims(ncid, varid, &ndims) ) ERR;
		if (ndims > 0) {
		    int nunlimdims;
		    int recdimids[3];
		    int dim, recdim;
		    if ( nc_inq_vardimid(ncid, varid, dimids) ) ERR;
		    if ( nc_inq_unlimdims(ncid, &nunlimdims, NULL) ) ERR;
		    if ( nc_inq_unlimdims(ncid, NULL, recdimids) ) ERR;
		    for (dim = 0; dim < ndims && is_recvar == 0; dim++) {
			for(recdim = 0; recdim < nunlimdims; recdim++) {
			    if(dimids[dim] == recdimids[recdim]) {
				is_recvar = 1;
				break;
			    }		
			}
		    }
		}
	    }
	    for (id = 0; id < varndims; id++) {
		if( nc_inq_dimlen(ncid, vardims[id], &len) ) ERR;
		vdims[id] = len;
	    }
	    nc_status = nc_inq_att(ncid,varid,_FillValue,&atttype,&attlen);
	    nc_status = nc_inq_att(ncid, varid, "units", &atttype, &attlen);
	    nc_status = nc_inq_att(ncid, varid, "C_format", &atttype, &attlen);
	    if (varid == 0) {
		/* read Time variable */
		static double Time_data;
		static size_t cor[RANK_Time] = {0};
		static size_t edg[RANK_Time] = {1};
		if (nc_get_vara(ncid, varid, cor, edg, &Time_data)) ERR;
	    } else {
		/* read data slices from P variable, should get fill values */
		static float P_data[4];
		static size_t cor[RANK_P] = {0, 0, 0};
		static size_t edg[RANK_P] = {1, 1, 4};

		/* first slice retrieved OK */
		if (nc_get_vara(ncid, varid, cor, edg, P_data)) ERR;
		
		/* In ncdump, reading second slice gets seg fault in
		 * nc4_open_var_grp(), but this attempt to do all the
		 * same netCDF calls as ncdump can't duplicate the
		 * error, which would seem to implicate ncdump rather
		 * than HDF5 or netCDF-4 library ... */
		cor[1] = 1;
		if (nc_get_vara(ncid, varid, cor, edg, P_data)) ERR;
	    }
	}
    }
    if (nc_close(ncid)) ERR;
      
   SUMMARIZE_ERR;
   FINAL_RESULTS;
}
Example #6
0
int
main(int argc, char **argv)
{
   printf("\n*** Testing netcdf-4 dimensions.\n");
   printf("*** Testing that netcdf-4 dimids inq works on netcdf-3 file...");
   {
      int ncid, dimid;
      int ndims_in, dimids_in[MAX_DIMS];

      /* Create a netcdf-3 file with one dim. */
      if (nc_create(FILE_NAME, 0, &ncid)) ERR;
      if (nc_def_dim(ncid, LAT_NAME, LAT_LEN, &dimid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and make sure nc_inq_dimids yeilds correct
       * result. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR;
      if (ndims_in != 0) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Testing that netcdf-4 dimids inq works on more complex netcdf-3 file...");
   {
      int ncid, dimid;
      int lon_dimid;
      int ndims_in, dimids_in[MAX_DIMS];

      /* Create a netcdf-3 file with three dim. */
      if (nc_create(FILE_NAME, 0, &ncid)) ERR;
      if (nc_def_dim(ncid, LEVEL_NAME, NC_UNLIMITED, &dimid)) ERR;
      if (nc_def_dim(ncid, LAT_NAME, LAT_LEN, &dimid)) ERR;
      if (nc_def_dim(ncid, LON_NAME, LON_LEN, &lon_dimid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and make sure nc_inq_dimids yeilds correct
       * result. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 3 || dimids_in[0] != 0 || dimids_in[1] != 1 ||
	 dimids_in[2] != 2) ERR;
      if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** Testing file with just one dimension...");
   {
      int ncid, dimid;
      int ndims_in, dimids_in[MAX_DIMS];
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      int dimid_in;

      /* Create a file with one dim and nothing else. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, LAT_NAME, LAT_LEN, &dimid)) ERR;

      /* Check out what we've got. */
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != LAT_LEN || strcmp(name_in, LAT_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1) ERR;
      if (nc_inq_dimid(ncid, LAT_NAME, &dimid_in)) ERR;
      if (dimid_in != 0) ERR;
      if (nc_inq_dimname(ncid, 0, name_in)) ERR;
      if (strcmp(name_in, LAT_NAME)) ERR;
      if (nc_inq_dimlen(ncid, 0, &len_in)) ERR;
      if (len_in != LAT_LEN) ERR;
      if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR;
      if (ndims_in != 0) ERR;
      if (nc_close(ncid)) ERR;

      /* Reopen and check it out again. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != LAT_LEN || strcmp(name_in, LAT_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1) ERR;
      if (nc_inq_dimid(ncid, LAT_NAME, &dimid_in)) ERR;
      if (dimid_in != 0) ERR;
      if (nc_inq_dimname(ncid, 0, name_in)) ERR;
      if (strcmp(name_in, LAT_NAME)) ERR;
      if (nc_inq_dimlen(ncid, 0, &len_in)) ERR;
      if (len_in != LAT_LEN) ERR;
      if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR;
      if (ndims_in != 0) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** Testing renaming of one dimension...");
   {
      int ncid, dimid, dimid_in;
      char name_in[NC_MAX_NAME + 1];
      size_t len_in;
      int ndims_in, dimids_in[MAX_DIMS];

      /* Reopen the file with one dim, and change the name of the dim. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_rename_dim(ncid, 0, BUBBA)) ERR;

      /* Check out what we've got. */
      dimid = 0;
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != LAT_LEN || strcmp(name_in, BUBBA)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1) ERR;
      if (dimids_in[0] != 0) ERR;
      if (nc_inq_dimid(ncid, BUBBA, &dimid_in)) ERR;
      if (dimid_in != 0) ERR;
      if (nc_inq_dimname(ncid, 0, name_in)) ERR;
      if (strcmp(name_in, BUBBA)) ERR;
      if (nc_inq_dimlen(ncid, 0, &len_in)) ERR;
      if (len_in != LAT_LEN) ERR;
      if (nc_close(ncid)) ERR;

      /* Reopen and check out what we've got again. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != LAT_LEN || strcmp(name_in, BUBBA)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_dimid(ncid, BUBBA, &dimid_in)) ERR;
      if (dimid_in != 0) ERR;
      if (nc_inq_dimname(ncid, 0, name_in)) ERR;
      if (strcmp(name_in, BUBBA)) ERR;
      if (nc_inq_dimlen(ncid, 0, &len_in)) ERR;
      if (len_in != LAT_LEN) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Testing renaming dimensions and vars...");
   {
#define FILE_NAME1 "foo1.nc"
#define FILE_NAME2 "foo2.nc"
#define FILE_NAME3 "foo3.nc"
#define FILE_NAME4 "foo4.nc"
#define DIM_NAME "lat_T42"
#define VAR_NAME DIM_NAME
#define DIM_NAME2 "lat"
#define VAR_NAME2 DIM_NAME2
#define RANK_lat_T42 1
      int  ncid, varid, dimid;
      int lat_T42_dim;
      size_t lat_T42_len = 3;
      int lat_T42_id;
      int lat_T42_dims[RANK_lat_T42];
      char name[NC_MAX_NAME + 1];

    /* =========== */
    /* Sub-test #1 */
    /* =========== */
      /* create file with dimension and associated coordinate variable */
      if (nc_create(FILE_NAME1, NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM_NAME, lat_T42_len, &lat_T42_dim)) ERR;
      lat_T42_dims[0] = lat_T42_dim;
      if (nc_def_var(ncid, VAR_NAME, NC_INT, RANK_lat_T42, lat_T42_dims, &lat_T42_id)) ERR;
      if (nc_close(ncid)) ERR;


      /* reopen file, rename coordinate dimension and then associated variable */
      if (nc_open(FILE_NAME1, NC_WRITE, &ncid)) ERR;
      if (nc_inq_dimid(ncid, DIM_NAME, &dimid)) ERR;
      if (nc_inq_varid(ncid, VAR_NAME, &varid)) ERR;
      if (nc_rename_dim(ncid, dimid, DIM_NAME2)) ERR;
      if (nc_rename_var(ncid, varid, VAR_NAME2)) ERR;
      if (nc_close(ncid)) ERR;


      /* reopen file, check coordinate dimension and associated variable names */
      /* Should be just like they created the file with DIM_NAME2 & VAR_NAME2 to
       *  begin with.
       */
      if (nc_open(FILE_NAME1, NC_WRITE, &ncid)) ERR;
      if (nc_inq_dimid(ncid, DIM_NAME2, &dimid)) ERR;
      if (nc_inq_varid(ncid, VAR_NAME2, &varid)) ERR;
      if (nc_inq_dimname(ncid, dimid, name)) ERR;
      if (strcmp(name, DIM_NAME2)) ERR;
      if (nc_inq_varname(ncid, varid, name)) ERR;
      if (strcmp(name, VAR_NAME2)) ERR;
      if (nc_close(ncid)) ERR;


    /* =========== */
    /* Sub-test #2 */
    /* =========== */
      /* create file with dimension and associated coordinate variable */
      if (nc_create(FILE_NAME1, NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM_NAME, lat_T42_len, &lat_T42_dim)) ERR;
      lat_T42_dims[0] = lat_T42_dim;
      if (nc_def_var(ncid, VAR_NAME, NC_INT, RANK_lat_T42, lat_T42_dims, &lat_T42_id)) ERR;
      if (nc_close(ncid)) ERR;


      /* reopen file, just rename coordinate dimension */
      if (nc_open(FILE_NAME1, NC_WRITE, &ncid)) ERR;
      if (nc_inq_dimid(ncid, DIM_NAME, &dimid)) ERR;
      if (nc_rename_dim(ncid, dimid, DIM_NAME2)) ERR;
      if (nc_close(ncid)) ERR;


      /* reopen file, check coordinate dimension and associated variable names */
      /* Should be just like the file was created with DIM_NAME2 to begin with */
      if (nc_open(FILE_NAME1, NC_WRITE, &ncid)) ERR;
      if (nc_inq_dimid(ncid, DIM_NAME2, &dimid)) ERR;
      if (nc_inq_varid(ncid, VAR_NAME, &varid)) ERR;
      if (nc_inq_dimname(ncid, dimid, name)) ERR;
      if (strcmp(name, DIM_NAME2)) ERR;
      if (nc_inq_varname(ncid, varid, name)) ERR;
      if (strcmp(name, VAR_NAME)) ERR;
      if (nc_close(ncid)) ERR;


    /* =========== */
    /* Sub-test #3 */
    /* =========== */
      /* create file with dimension and associated coordinate variable */
      if (nc_create(FILE_NAME1, NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM_NAME, lat_T42_len, &lat_T42_dim)) ERR;
      lat_T42_dims[0] = lat_T42_dim;
      if (nc_def_var(ncid, VAR_NAME, NC_INT, RANK_lat_T42, lat_T42_dims, &lat_T42_id)) ERR;
      if (nc_close(ncid)) ERR;


      /* reopen file, just rename variable */
      if (nc_open(FILE_NAME1, NC_WRITE, &ncid)) ERR;
      if (nc_inq_varid(ncid, VAR_NAME, &varid)) ERR;
      if (nc_rename_var(ncid, varid, VAR_NAME2)) ERR;
      if (nc_close(ncid)) ERR;


      /* reopen file, check coordinate dimension and associated variable names */
      /* Should be just like the file was created with VAR_NAME2 to begin with */
      if (nc_open(FILE_NAME1, NC_WRITE, &ncid)) ERR;
      if (nc_inq_dimid(ncid, DIM_NAME, &dimid)) ERR;
      if (nc_inq_varid(ncid, VAR_NAME2, &varid)) ERR;
      if (nc_inq_dimname(ncid, dimid, name)) ERR;
      if (strcmp(name, DIM_NAME)) ERR;
      if (nc_inq_varname(ncid, varid, name)) ERR;
      if (strcmp(name, VAR_NAME2)) ERR;
      if (nc_close(ncid)) ERR;


    /* =========== */
    /* Sub-test #4 */
    /* =========== */
      /* create file with dimension and associated coordinate variable */
      if (nc_create(FILE_NAME1, NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM_NAME, lat_T42_len, &lat_T42_dim)) ERR;
      lat_T42_dims[0] = lat_T42_dim;
      if (nc_def_var(ncid, VAR_NAME, NC_INT, RANK_lat_T42, lat_T42_dims, &lat_T42_id)) ERR;
      if (nc_close(ncid)) ERR;


      /* reopen file, rename associated variable and then coordinate dimension */
      if (nc_open(FILE_NAME1, NC_WRITE, &ncid)) ERR;
      if (nc_inq_dimid(ncid, DIM_NAME, &dimid)) ERR;
      if (nc_inq_varid(ncid, VAR_NAME, &varid)) ERR;
      if (nc_rename_var(ncid, varid, VAR_NAME2)) ERR;
      if (nc_rename_dim(ncid, dimid, DIM_NAME2)) ERR;
      if (nc_close(ncid)) ERR;


      /* reopen file, check coordinate dimension and associated variable names */
      /* Should be just like they created the file with DIM_NAME2 & VAR_NAME2 to
       *  begin with.
       */
      if (nc_open(FILE_NAME1, NC_WRITE, &ncid)) ERR;
      if (nc_inq_dimid(ncid, DIM_NAME2, &dimid)) ERR;
      if (nc_inq_varid(ncid, VAR_NAME2, &varid)) ERR;
      if (nc_inq_dimname(ncid, dimid, name)) ERR;
      if (strcmp(name, DIM_NAME2)) ERR;
      if (nc_inq_varname(ncid, varid, name)) ERR;
      if (strcmp(name, VAR_NAME2)) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Testing file with just one unlimited dimension...");
   {
      int ncid, dimid;
      int ndims_in, dimids_in[MAX_DIMS];
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      int unlimdimid_in;
      int nunlimdims_in;

      /* Create a file with one unlimied dim and nothing else. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, LEVEL_NAME, NC_UNLIMITED, &dimid)) ERR;

      /* Check it out before the enddef. */
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != NC_UNLIMITED || strcmp(name_in, LEVEL_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_unlimdim(ncid, &unlimdimid_in)) ERR;
      if (unlimdimid_in != 0) ERR;
      if (nc_inq_unlimdims(ncid, &nunlimdims_in, &unlimdimid_in)) ERR;
      if (nunlimdims_in != 1 || unlimdimid_in != 0) ERR;

      /* Automatically enddef and close. */
      if (nc_close(ncid)) ERR;

      /* Reopen and check it out. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != NC_UNLIMITED || strcmp(name_in, LEVEL_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_unlimdim(ncid, &unlimdimid_in)) ERR;
      if (unlimdimid_in != 0) ERR;
      if (nc_inq_unlimdims(ncid, &nunlimdims_in, &unlimdimid_in)) ERR;
      if (nunlimdims_in != 1 || unlimdimid_in != 0) ERR;
      if (unlimdimid_in != 0) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
#define ROMULUS "Romulus"
#define REMUS "Remus"
#define DIMS2 2
   printf("*** Testing file with two unlimited dimensions...");
   {
      int ncid, dimid[DIMS2];
      int ndims_in, dimids_in[DIMS2];
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      int unlimdimid_in[DIMS2];
      int nunlimdims_in;

      /* Create a file with two unlimited dims and nothing else. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, REMUS, NC_UNLIMITED, &dimid[0])) ERR;
      if (nc_def_dim(ncid, ROMULUS, NC_UNLIMITED, &dimid[1])) ERR;

      /* Check it out before the enddef. */
      if (nc_inq_dim(ncid, dimid[0], name_in, &len_in)) ERR;
      if (len_in != NC_UNLIMITED || strcmp(name_in, REMUS)) ERR;
      if (nc_inq_dim(ncid, dimid[1], name_in, &len_in)) ERR;
      if (len_in != NC_UNLIMITED || strcmp(name_in, ROMULUS)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 2 || dimids_in[0] != 0 || dimids_in[1] != 1) ERR;
      if (nc_inq_unlimdim(ncid, &unlimdimid_in[0])) ERR;
      if (unlimdimid_in[0] != 0) ERR;
      if (nc_inq_unlimdims(ncid, &nunlimdims_in, unlimdimid_in)) ERR;
      if (nunlimdims_in != 2 || unlimdimid_in[0] != 0 || unlimdimid_in[1] != 1) ERR;

      /* Automatically enddef and close. */
      if (nc_close(ncid)) ERR;

      /* Reopen and check it out. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Testing ordering of dimensions...");
   {
#define A_NAME "a"
#define B_NAME "b"
#define A_LEN 50
#define B_LEN 92
#define A_DIMID 1
#define B_DIMID 0

      int ncid;
      int ndims_in, dimids_in[MAX_DIMS];
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      int dimid_a, dimid_b;

      /* Create a file with two dims and nothing else. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, B_NAME, B_LEN, &dimid_b)) ERR;
      if (nc_def_dim(ncid, A_NAME, A_LEN, &dimid_a)) ERR;
      if (dimid_b != B_DIMID || dimid_a != A_DIMID) ERR;

      /* Check out what we've got. */
      if (nc_inq_dim(ncid, dimid_a, name_in, &len_in)) ERR;
      if (len_in != A_LEN || strcmp(name_in, A_NAME)) ERR;
      if (nc_inq_dim(ncid, dimid_b, name_in, &len_in)) ERR;
      if (len_in != B_LEN || strcmp(name_in, B_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 2 || dimids_in[0] != 0 || dimids_in[1] != 1) ERR;

      if (nc_close(ncid)) ERR;

      /* Reopen and check it out again. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      if (nc_inq_dim(ncid, B_DIMID, name_in, &len_in)) ERR;
      if (len_in != B_LEN || strcmp(name_in, B_NAME)) ERR;
      if (nc_inq_dim(ncid, A_DIMID, name_in, &len_in)) ERR;
      if (len_in != A_LEN || strcmp(name_in, A_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 2 || dimids_in[0] != 0 ||
	  dimids_in[1] != 1) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Testing file with just one unlimited dimension and one var...");
   {
      int ncid, dimid, dimids[MAX_DIMS];
      int level_varid;
      int natts_in, ndims_in, dimids_in[MAX_DIMS];
      nc_type xtype_in;
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      int unlimdimid_in;
      size_t start[MAX_DIMS], count[MAX_DIMS];
      int varid_in, nvars_in, nunlimdims_in;
      unsigned long long uint64_data[1] = {42};

      /* Create a file with one unlimied dim and nothing else. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, LEVEL_NAME, NC_UNLIMITED, &dimid)) ERR;
      if (dimid != 0) ERR;
      dimids[0] = dimid;
      if (nc_def_var(ncid, LEVEL_NAME, NC_UINT64, 1, dimids, &level_varid)) ERR;
      if (level_varid != 0) ERR;

      /* Check it out before enddef. */
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != 0 || strcmp(name_in, LEVEL_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_unlimdim(ncid, &unlimdimid_in)) ERR;
      if (unlimdimid_in != 0) ERR;
      if (nc_inq_unlimdims(ncid, &nunlimdims_in, &unlimdimid_in)) ERR;
      if (nunlimdims_in != 1 || unlimdimid_in != 0) ERR;
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 || unlimdimid_in != 0) ERR;
      if (nc_inq_varid(ncid, LEVEL_NAME, &varid_in)) ERR;
      if (varid_in != 0) ERR;
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, LEVEL_NAME) || xtype_in != NC_UINT64 || ndims_in != 1 ||
	  dimids_in[0] != 0 || natts_in != 0) ERR;
      if (nc_inq_varname(ncid, 0, name_in)) ERR;
      if (strcmp(name_in, LEVEL_NAME)) ERR;

      /* Now write one record of data to the var. */
      start[0] = 0;
      count[0] = 1;
      if (nc_put_vara_ulonglong(ncid, 0, start, count, uint64_data)) ERR;

      /* Check dimension informaiton again. Now the length of this
       * dimension should be one. */
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != 1 || strcmp(name_in, LEVEL_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_dimlen(ncid, 0, &len_in)) ERR;
      if (len_in != 1) ERR;
      if (nc_inq_unlimdim(ncid, &unlimdimid_in)) ERR;
      if (unlimdimid_in != 0) ERR;
      if (nc_inq_unlimdims(ncid, &nunlimdims_in, &unlimdimid_in)) ERR;
      if (nunlimdims_in != 1 || unlimdimid_in != 0) ERR;
      if (unlimdimid_in != 0) ERR;
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 || unlimdimid_in != 0) ERR;
      if (nc_inq_varid(ncid, LEVEL_NAME, &varid_in)) ERR;
      if (varid_in != 0) ERR;
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, LEVEL_NAME) || xtype_in != NC_UINT64 || ndims_in != 1 ||
	  dimids_in[0] != 0 || natts_in != 0) ERR;
      if (nc_inq_varname(ncid, 0, name_in)) ERR;
      if (strcmp(name_in, LEVEL_NAME)) ERR;

      /* Close the file. */
      if (nc_close(ncid)) ERR;

      /* Check it out. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != 1 || strcmp(name_in, LEVEL_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_unlimdim(ncid, &unlimdimid_in)) ERR;
      if (unlimdimid_in != 0) ERR;
      if (nc_inq_unlimdims(ncid, &nunlimdims_in, &unlimdimid_in)) ERR;
      if (nunlimdims_in != 1 || unlimdimid_in != 0) ERR;
      if (unlimdimid_in != 0) ERR;
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 || unlimdimid_in != 0) ERR;
      if (nc_inq_varid(ncid, LEVEL_NAME, &varid_in)) ERR;
      if (varid_in != 0) ERR;
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, LEVEL_NAME) || xtype_in != NC_UINT64 || ndims_in != 1 ||
	  dimids_in[0] != 0 || natts_in != 0) ERR;
      if (nc_inq_varname(ncid, 0, name_in)) ERR;
      if (strcmp(name_in, LEVEL_NAME)) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Testing adding a coordinate var to file with dimension...");
   {
      int ncid, dimid, dimids[MAX_DIMS];
      int natts_in, ndims_in, dimids_in[MAX_DIMS];
      nc_type xtype_in;
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      int unlimdimid_in;
      int nvars_in, dim5_varid;

      /* Create a file with one dim and nothing else. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM5_NAME, DIM5_LEN, &dimid)) ERR;

      /* Check out what we've got. */
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 0 || natts_in != 0 ||
	 unlimdimid_in != -1) ERR;
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != DIM5_LEN || strcmp(name_in, DIM5_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;

      if (nc_close(ncid)) ERR;

      /* Reopen and check it out again. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 0 || natts_in != 0 ||
	 unlimdimid_in != -1) ERR;
      if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR;
      if (len_in != DIM5_LEN || strcmp(name_in, DIM5_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;

      /* Add a coordinate var for this dimension. */
      dimids[0] = 0;
      if (nc_def_var(ncid, DIM5_NAME, NC_FLOAT, 1, dimids, &dim5_varid)) ERR;

      /* Check it out. */
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 ||
	 unlimdimid_in != -1) ERR;
      if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR;
      if (len_in != DIM5_LEN || strcmp(name_in, DIM5_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, DIM5_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != 0 || natts_in != 0) ERR;

      if (nc_close(ncid)) ERR;

      /* Reopen and check it out again. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 ||
	 unlimdimid_in != -1) ERR;
      if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR;
      if (len_in != DIM5_LEN || strcmp(name_in, DIM5_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, DIM5_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != 0 || natts_in != 0) ERR;

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Testing adding a coordinate var to file with unlimited dimension...");
   {
      int ncid, dimid, dimids[MAX_DIMS];
      int natts_in, ndims_in, dimids_in[MAX_DIMS];
      nc_type xtype_in;
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      int unlimdimid_in;
      size_t start[MAX_DIMS], count[MAX_DIMS], index[MAX_DIMS];
      unsigned short data[2] = {42, 24}, data_in[2];
      int nvars_in, hp_varid, dim5_varid;

      /* Create a file with one dim and one var. This time make
       * it an unlimited dim. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM5_NAME, NC_UNLIMITED, &dimid)) ERR;
      if (dimid != 0) ERR;
      dimids[0] = dimid;
      if (nc_def_var(ncid, HP_NAME, NC_USHORT, 1, dimids, &hp_varid)) ERR;
      if (hp_varid != 0) ERR;

      /* Check out what we've got. */
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 ||
	 unlimdimid_in != 0) ERR;
      if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR;
      if (len_in != 0 || strcmp(name_in, DIM5_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, HP_NAME) || xtype_in != NC_USHORT || ndims_in != 1 ||
	  dimids_in[0] != 0 || natts_in != 0) ERR;

      /* Add a record to the HP variable. */
      start[0] = 0;
      count[0] = 1;
      if (nc_put_vara(ncid, hp_varid, start, count, data)) ERR;

      /* Check to ensure dimension grew. */
      if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR;
      if (len_in != 1 || strcmp(name_in, DIM5_NAME)) ERR;

      /* Reread the value just written. */
      index[0] = 0;
      if (nc_get_var1_ushort(ncid, hp_varid, index, data_in)) ERR;
      if (data_in[0] != data[0]) ERR;

      if (nc_close(ncid)) ERR;

      /* Reopen and check it out again. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 ||
	 unlimdimid_in != 0) ERR;
      if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR;
      if (len_in != 1 || strcmp(name_in, DIM5_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;

      /* Add a coordinate var for this dimension. */
      dimids[0] = 0;
      if (nc_def_var(ncid, DIM5_NAME, NC_FLOAT, 1, dimids, &dim5_varid)) ERR;

      /* Check it out. */
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 2 || natts_in != 0 ||
	 unlimdimid_in != 0) ERR;
      if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR;
      if (len_in != 1 || strcmp(name_in, DIM5_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_var(ncid, dim5_varid, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, DIM5_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != 0 || natts_in != 0) ERR;

      if (nc_close(ncid)) ERR;

      /* Reopen and check it out again. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 2 || natts_in != 0 ||
	 unlimdimid_in != 0) ERR;
      if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR;
      if (len_in != 1 || strcmp(name_in, DIM5_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_var(ncid, dim5_varid, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, DIM5_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != 0 || natts_in != 0) ERR;

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Creating file with 1 data var, 2 dims, and 2 coord. vars...");

   {
      int ncid, dimids[MAX_DIMS];
      int lat_dimid, lon_dimid, lat_varid, lon_varid;
      int pres_varid;
      char name_in[NC_MAX_NAME + 1];
      int natts_in, ndims_in, dimids_in[MAX_DIMS];
      nc_type xtype_in;
      size_t len_in;
      float lat[LAT_LEN], lon[LON_LEN];
      float lat_in[LAT_LEN], lon_in[LON_LEN];
      double pres[LAT_LEN][LON_LEN], pres_in[LAT_LEN][LON_LEN];
      int i, j;

      /* Lats and lons suitable for some South American data. */
      for (lat[0] = 40.0, i = 1; i < LAT_LEN; i++)
	 lat[i] = lat[i - 1] + .5;
      for (lon[0] = 20.0, i = 1; i < LON_LEN; i++)
	 lon[i] = lon[i - 1] + 1.5;

      /* Some phoney 2D pressure data. */
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    pres[i][j] = 1013.1 + j;

      /* Create a file. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;

      /* Define lat and lon dimensions, with associated variables. */
      if (nc_def_dim(ncid, LAT_NAME, LAT_LEN, &lat_dimid)) ERR;
      dimids[0] = lat_dimid;
      if (nc_def_var(ncid, LAT_NAME, NC_FLOAT, 1, dimids, &lat_varid)) ERR;
      if (nc_def_dim(ncid, LON_NAME, LON_LEN, &lon_dimid)) ERR;
      dimids[0] = lon_dimid;
      if (nc_def_var(ncid, LON_NAME, NC_FLOAT, 1, dimids, &lon_varid)) ERR;

      /* Define a 2D variable called pressure, with NC_DOUBLE on a lat
       * lon grid. */
      dimids[0] = lat_dimid;
      dimids[1] = lon_dimid;
      if (nc_def_var(ncid, PRES_NAME, NC_DOUBLE, 2, dimids, &pres_varid)) ERR;

      /* Check our dimensions. */
      if (nc_inq_dim(ncid, lat_dimid, name_in, &len_in)) ERR;
      if (len_in != LAT_LEN || strcmp(name_in, LAT_NAME)) ERR;
      if (nc_inq_dim(ncid, lon_dimid, name_in, &len_in)) ERR;
      if (len_in != LON_LEN || strcmp(name_in, LON_NAME)) ERR;
      if (nc_inq_var(ncid, lat_varid, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, LAT_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != lat_dimid || natts_in != 0) ERR;
      if (nc_inq_var(ncid, lon_varid, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, LON_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != lon_dimid || natts_in != 0) ERR;

      /* Check our data variable. */
      if (nc_inq_var(ncid, pres_varid, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, PRES_NAME) || xtype_in != NC_DOUBLE || ndims_in != 2 ||
	  dimids_in[0] != lat_dimid || dimids_in[1] != lon_dimid || natts_in != 0) ERR;

      /* Write our latitude and longitude values. This writes all
       * metadata to disk too. */
      if (nc_put_var_float(ncid, lat_varid, lat)) ERR;
      if (nc_put_var_float(ncid, lon_varid, lon)) ERR;

      /* Write our 2D pressure values. */
      if (nc_put_var_double(ncid, pres_varid, (double *)pres)) ERR;

      /* Check our latitude and longitude values. */
      if (nc_get_var(ncid, lat_varid, lat_in)) ERR;
      for (i = 0; i < LAT_LEN; i++)
	 if (lat[i] != lat_in[i]) ERR;
      if (nc_get_var_float(ncid, lon_varid, lon_in)) ERR;
      for (i = 0; i < LON_LEN; i++)
	 if (lon[i] != lon_in[i]) ERR;

      /* Check our pressure values. */
      if (nc_get_var_double(ncid, pres_varid, (double *)pres_in)) ERR;
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    if (pres[i][j] != pres_in[i][j]) ERR;

      /* Close the file. */
      if (nc_close(ncid)) ERR;

      /* Reopen the file and check it out again. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      /* Check our dimensions. */
      if (nc_inq_dim(ncid, lat_dimid, name_in, &len_in)) ERR;
      if (len_in != LAT_LEN || strcmp(name_in, LAT_NAME)) ERR;
      if (nc_inq_dim(ncid, lon_dimid, name_in, &len_in)) ERR;
      if (len_in != LON_LEN || strcmp(name_in, LON_NAME)) ERR;
      if (nc_inq_var(ncid, lat_varid, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, LAT_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != lat_dimid || natts_in != 0) ERR;
      if (nc_inq_var(ncid, lon_varid, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, LON_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != lon_dimid || natts_in != 0) ERR;

      /* Check our data variable. */
      if (nc_inq_var(ncid, pres_varid, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, PRES_NAME) || xtype_in != NC_DOUBLE || ndims_in != 2 ||
	  dimids_in[0] != lat_dimid || dimids_in[1] != lon_dimid || natts_in != 0) ERR;

      /* Check our latitude and longitude values. */
      if (nc_get_var(ncid, lat_varid, lat_in)) ERR;
      for (i = 0; i < LAT_LEN; i++)
	 if (lat[i] != lat_in[i]) ERR;
      if (nc_get_var_float(ncid, lon_varid, lon_in)) ERR;
      for (i = 0; i < LON_LEN; i++)
	 if (lon[i] != lon_in[i]) ERR;

      /* Check our pressure values. */
      if (nc_get_var_double(ncid, pres_varid, (double *)pres_in)) ERR;
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    if (pres[i][j] != pres_in[i][j]) ERR;

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Creating file with 3 data vars, 4 dims, and 2 coord. vars...");

   {
      int ncid, lat_dimid, dimids[MAX_DIMS];
      int level_dimid, time_dimid, elev_varid;
      int lat_varid, lon_dimid, lon_varid, pres_varid, hp_varid;
      double pres[LAT_LEN][LON_LEN][LEVEL_LEN][TIME_LEN];
      double pres_in[LAT_LEN][LON_LEN][LEVEL_LEN][TIME_LEN];
      unsigned short hp[LAT_LEN][LON_LEN][TIME_LEN];
      unsigned short hp_in[LAT_LEN][LON_LEN][TIME_LEN];
      unsigned long long elev[LAT_LEN][LON_LEN], elev_in[LAT_LEN][LON_LEN];
      size_t start[4], count[4];
      int nvars, ndims, natts, unlimdimid;
      int natts_in, ndims_in, dimids_in[MAX_DIMS];
      nc_type xtype_in;
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      float lat[LAT_LEN], lon[LON_LEN];
      float lat_in[LAT_LEN], lon_in[LON_LEN];
      int i, j, k, l;

      /* Some phony 4D pressure data. */
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    for (k = 0; k < LEVEL_LEN; k++)
	       for (l = 0; l <TIME_LEN; l++)
		  pres[i][j][k][l] = 1013.1 + j;

      /* Some phony 3D hp data. */
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    for (l = 0; l <TIME_LEN; l++)
	       hp[i][j][l] = 100 + l;

      /* Some phony 2D elevaton data. */
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    elev[i][j] = 1010101022223333ULL  + i + j;

      /* Some phony 1D lats and lons. */
      for (i = 0; i < LAT_LEN; i++)
	 lat[i] = i * 5.;
      for (i = 0; i < LON_LEN; i++)
	 lon[i] = i * 5.;

      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;

      /* Define lat, lon, level, and timestep dimensions, with
       * associated coordinate variables for lat and lon only. Time is
       * an unlimited dimension. */
      if (nc_def_dim(ncid, LAT_NAME, LAT_LEN, &lat_dimid)) ERR;
      if (lat_dimid != LAT_DIMID) ERR;
      dimids[0] = lat_dimid;
      if (nc_def_var(ncid, LAT_NAME, NC_FLOAT, 1, dimids, &lat_varid)) ERR;
      if (lat_varid != LAT_VARID) ERR;
      if (nc_def_dim(ncid, LON_NAME, LON_LEN, &lon_dimid)) ERR;
      if (lon_dimid != LON_DIMID) ERR;
      dimids[0] = lon_dimid;
      if (nc_def_var(ncid, LON_NAME, NC_FLOAT, 1, dimids, &lon_varid)) ERR;
      if (lon_varid != LON_VARID) ERR;
      if (nc_def_dim(ncid, LEVEL_NAME, LEVEL_LEN, &level_dimid)) ERR;
      if (level_dimid != LEVEL_DIMID) ERR;
      if (nc_def_dim(ncid, TIME_NAME, NC_UNLIMITED, &time_dimid)) ERR;
      if (time_dimid != TIME_DIMID) ERR;

      /* Define a 4D NC_DOUBLE variable called pressure. */
      dimids[0] = lat_dimid;
      dimids[1] = lon_dimid;
      dimids[2] = level_dimid;
      dimids[3] = time_dimid;
      if (nc_def_var(ncid, PRES_NAME, NC_DOUBLE, 4, dimids, &pres_varid)) ERR;
      if (pres_varid != PRES_VARID) ERR;

      /* Define a 2D variable for surface elevation. Use NC_INT64
       * because our units for this is Angstroms from Earth's
       * Center. */
      if (nc_def_var(ncid, ELEV_NAME, NC_INT64, 2, dimids, &elev_varid)) ERR;
      if (elev_varid != ELEV_VARID) ERR;

      /* Define a 3D NC_USHORT variable to store the number of Harry
       * Potter books in this grid square at this time (ignore HP
       * books in airplanes, dirigibles, hot air balloons, space
       * capsules, hang-gliders, parachutes, and flying on brooms). */
      dimids[2] = time_dimid;
      if (nc_def_var(ncid, HP_NAME, NC_USHORT, 3, dimids, &hp_varid)) ERR;
      if (hp_varid != HP_VARID) ERR;

      /* Did all our stuff make it into the internal metadata model
       * intact? */
      /* Check our dimensions. */
      if (nc_inq_dim(ncid, LAT_DIMID, name_in, &len_in)) ERR;
      if (len_in != LAT_LEN || strcmp(name_in, LAT_NAME)) ERR;
      if (nc_inq_dim(ncid, LON_DIMID, name_in, &len_in)) ERR;
      if (len_in != LON_LEN || strcmp(name_in, LON_NAME)) ERR;
      if (nc_inq_dim(ncid, LEVEL_DIMID, name_in, &len_in)) ERR;
      if (len_in != LEVEL_LEN || strcmp(name_in, LEVEL_NAME)) ERR;
      if (nc_inq_dim(ncid, TIME_DIMID, name_in, &len_in)) ERR;
      if (len_in != 0 || strcmp(name_in, TIME_NAME)) ERR;

      /* Check our coordinate variables. */
      if (nc_inq_var(ncid, LAT_VARID, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, LAT_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != LAT_DIMID || natts_in != 0) ERR;
      if (nc_inq_var(ncid, LON_VARID, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, LON_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != LON_DIMID || natts_in != 0) ERR;

      /* Check our data variables. */
      if (nc_inq_var(ncid, PRES_VARID, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, PRES_NAME) || xtype_in != NC_DOUBLE || ndims_in != 4 ||
	  dimids_in[0] != LAT_DIMID || dimids_in[1] != LON_DIMID ||
	  dimids_in[2] != LEVEL_DIMID || dimids_in[3] != TIME_DIMID ||
	  natts_in != 0) ERR;
      if (nc_inq_var(ncid, ELEV_VARID, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, ELEV_NAME) || xtype_in != NC_INT64 || ndims_in != 2 ||
	  dimids_in[0] != LAT_DIMID || dimids_in[1] != LON_DIMID ||
	  natts_in != 0) ERR;
      if (nc_inq_var(ncid, HP_VARID, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, HP_NAME) || xtype_in != NC_USHORT || ndims_in != 3 ||
	  dimids_in[0] != LAT_DIMID || dimids_in[1] != LON_DIMID ||
	  dimids_in[2] != TIME_DIMID || natts_in != 0) ERR;

      /* Write our latitude and longitude values. This writes all
       * metadata to disk too. */
      if (nc_put_var_float(ncid, lat_varid, lat)) ERR;
      if (nc_put_var_float(ncid, lon_varid, lon)) ERR;

      /* Write our 4D pressure, elevation, and hp data. But this
       * should do nothing for pressure and hp, because these are
       * record vars, and nc_put_var_* doesn't do anything to record
       * vars, because it doesn't know how big the var is supposed to
       * be. */
      if (nc_put_var_double(ncid, pres_varid, (double *)pres)) ERR;
      if (nc_put_var_ulonglong(ncid, elev_varid, (unsigned long long *)elev)) ERR;
      if (nc_put_var_ushort(ncid, hp_varid, (unsigned short *)hp)) ERR;

      /* Check our latitude and longitude values. */
      if (nc_get_var(ncid, lat_varid, lat_in)) ERR;
      for (i = 0; i < LAT_LEN; i++)
	 if (lat[i] != lat_in[i]) ERR;
      if (nc_get_var_float(ncid, lon_varid, lon_in)) ERR;
      for (i = 0; i < LON_LEN; i++)
	 if (lon[i] != lon_in[i]) ERR;

      /* Make sure our pressure and hp variables are still
       * empty. get_var calls will return no error, but fetch no
       * data. */
      if (nc_inq_var(ncid, pres_varid, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (nc_inq_dim(ncid, dimids_in[3], NULL, &len_in)) ERR;
      if (len_in != 0) ERR;
      memset(pres_in, 0, sizeof(pres_in));
      if (nc_get_var_double(ncid, pres_varid, (double *)pres_in)) ERR;

      /* Check our pressure values. */
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    for (k = 0; k < LEVEL_LEN; k++)
	       for (l = 0; l <TIME_LEN; l++)
		  if (0 != pres_in[i][j][k][l]) ERR;

      if (nc_inq_var(ncid, hp_varid, NULL, NULL, &ndims_in,
		     dimids_in, NULL)) ERR;
      if (nc_inq_dim(ncid, dimids_in[2], NULL, &len_in)) ERR;
      if (len_in != 0) ERR;
      memset(hp_in, 0, sizeof(hp_in));
      if (nc_get_var_ushort(ncid, hp_varid, (unsigned short *)hp_in)) ERR;

      /* Check our hp values. */
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    for (l = 0; l <TIME_LEN; l++)
	       if (0 != hp_in[i][j][l]) ERR;

      /* Now use nc_put_vara to really write pressure and hp
       * data. Write TIME_LEN (4) records of each. */
      start[0] = start[1] = start[2] = start[3] = 0;
      count[0] = LAT_LEN;
      count[1] = LON_LEN;
      count[2] = LEVEL_LEN;
      count[3] = TIME_LEN;
      if (nc_put_vara(ncid, pres_varid, start, count,
		      (double *)pres)) ERR;
      count[2] = TIME_LEN;
      if (nc_put_vara(ncid, hp_varid, start, count,
		      (double *)hp)) ERR;

      /* Check our pressure values. */
      if (nc_get_var_double(ncid, pres_varid, (double *)pres_in)) ERR;
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    for (k = 0; k < LEVEL_LEN; k++)
	       for (l = 0; l <TIME_LEN; l++)
		  if (pres[i][j][k][l] != pres_in[i][j][k][l]) ERR;

      /* Check our elevation values. */
      if (nc_get_var_ulonglong(ncid, elev_varid, (unsigned long long *)elev_in)) ERR;
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    if (elev[i][j] != elev_in[i][j]) ERR;

      /* Check our hp values. */
      if (nc_get_var_ushort(ncid, hp_varid, (unsigned short *)hp_in)) ERR;
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    for (l = 0; l <TIME_LEN; l++)
	       if (hp[i][j][l] != hp_in[i][j][l]) ERR;

      /* Close the file. */
      if (nc_close(ncid)) ERR;

      /* Reopen the file and check it out again. At the moment, we
       * can't count on the varids and dimids being the same. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 4 || nvars != 5 || natts != 0) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Testing file with dims and only some coordinate vars...");
#define NDIMS_EX 4
#define NLAT 6
#define NLON 12
#define LAT_NAME_EX "latitude"
#define LON_NAME_EX "longitude"
#define NREC 2
#define REC_NAME "time"
#define LVL_NAME "level"
#define NLVL 2

/* Names of things. */
#define PRES_NAME "pressure"
#define TEMP_NAME "temperature"
#define UNITS "units"
#define DEGREES_EAST "degrees_east"
#define DEGREES_NORTH "degrees_north"

/* There are 4 vars, two for data, two for coordinate data. */
#define NVARS_EX 4

/* These are used to construct some example data. */
#define SAMPLE_PRESSURE 900
#define SAMPLE_TEMP 9.0
#define START_LAT 25.0
#define START_LON -125.0

/* For the units attributes. */
#define UNITS "units"
#define PRES_UNITS "hPa"
#define TEMP_UNITS "celsius"
#define LAT_UNITS "degrees_north"
#define LON_UNITS "degrees_east"
#define MAX_ATT_LEN 80
   {
      /* IDs for the netCDF file, dimensions, and variables. */
      int ncid, lon_dimid, lat_dimid;
      int lon_varid;
      int ndims_in;
      int dimid[NDIMS_EX];
      char dim_name_in[NDIMS_EX][NC_MAX_NAME];
      int i;

      /* Create the file. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;

      /* Define the dimensions. */
      if (nc_def_dim(ncid, LAT_NAME_EX, NLAT, &lat_dimid)) ERR;
      if (nc_def_dim(ncid, LON_NAME_EX, NLON, &lon_dimid)) ERR;

      /* Define a coordinate var. */
      if (nc_def_var(ncid, LON_NAME_EX, NC_FLOAT, 1, &lon_dimid,
			       &lon_varid)) ERR;

      /* Close the file. */
      if (nc_close(ncid)) ERR;

      if (nc_open(FILE_NAME, 0, &ncid)) ERR;

      /* Check dimensions. */
      ndims_in = 0;
      if (nc_inq_dimids(ncid, &ndims_in, dimid, 0)) ERR;
      if (ndims_in != 2) ERR;
      for (i = 0; i < 2; i++)
      {
	 if (dimid[i] != i) ERR;
	 if (nc_inq_dimname(ncid, i, dim_name_in[i])) ERR;
      }
      if (strcmp(dim_name_in[0], LAT_NAME_EX) ||
	  strcmp(dim_name_in[1], LON_NAME_EX)) ERR;

      /* Close the file. */
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** Testing file with just one very long dimension...");
   {
#define VERY_LONG_LEN (size_t)4500000000LL
      int ncid, dimid;
      int ndims_in, dimids_in[MAX_DIMS];
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      int varid_in;

      if (SIZEOF_SIZE_T == 8)
      {
	 /* Create a file with one dim and nothing else. */
	 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
	 if (nc_def_dim(ncid, LAT_NAME, VERY_LONG_LEN, &dimid)) ERR;

	 /* Check it out. */
	 if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
	 if (len_in != ((SIZEOF_SIZE_T == 8) ? VERY_LONG_LEN : NC_MAX_UINT) ||
	     strcmp(name_in, LAT_NAME)) ERR;
	 if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
	 if (ndims_in != 1) ERR;
	 if (nc_inq_dimid(ncid, LAT_NAME, &varid_in)) ERR;
	 if (varid_in != 0) ERR;
	 if (nc_inq_dimname(ncid, 0, name_in)) ERR;
	 if (strcmp(name_in, LAT_NAME)) ERR;
	 if (nc_inq_dimlen(ncid, 0, &len_in)) ERR;
	 if (len_in != ((SIZEOF_SIZE_T == 8) ? VERY_LONG_LEN : NC_MAX_UINT)) ERR;
	 if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR;
	 if (ndims_in != 0) ERR;
	 if (nc_close(ncid)) ERR;

	 /* Reopen and check it out again. */
	 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
	 /* Check it out. */
	 if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
	 if (len_in != ((SIZEOF_SIZE_T == 8) ? VERY_LONG_LEN : NC_MAX_UINT) ||
	     strcmp(name_in, LAT_NAME)) ERR;
	 if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
	 if (ndims_in != 1) ERR;
	 if (nc_inq_dimid(ncid, LAT_NAME, &varid_in)) ERR;
	 if (varid_in != 0) ERR;
	 if (nc_inq_dimname(ncid, 0, name_in)) ERR;
	 if (strcmp(name_in, LAT_NAME)) ERR;
	 if (nc_inq_dimlen(ncid, 0, &len_in)) ERR;
	 if (len_in != ((SIZEOF_SIZE_T == 8) ? VERY_LONG_LEN : NC_MAX_UINT)) ERR;
	 if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR;
	 if (ndims_in != 0) ERR;
	 if (nc_close(ncid)) ERR;
      }
   }
   SUMMARIZE_ERR;
   printf("*** Testing reference file with just one very long dimension...");
   {
#define REF_FILE_NAME "ref_tst_dims.nc"
      int ncid, dimid = 0;
      int ndims_in, dimids_in[MAX_DIMS];
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      int varid_in;
      char file_in[NC_MAX_NAME + 1];
      int ret;

      strcpy(file_in, "");
      if (getenv("srcdir"))
      {
	 strcat(file_in, getenv("srcdir"));
	 strcat(file_in, "/");
      }
      strcat(file_in, REF_FILE_NAME);

      /* Reopen and check it out again. */
      if (nc_open(file_in, NC_NOWRITE, &ncid)) ERR;

      /* Check it out. */
      ret = nc_inq_dim(ncid, dimid, name_in, &len_in);
      if ((SIZEOF_SIZE_T >= 8 && ret) ||
	  (SIZEOF_SIZE_T < 8 && ret != NC_EDIMSIZE)) ERR;
      if (SIZEOF_SIZE_T < 8)
      {
	 if (len_in != NC_MAX_UINT) ERR;
      }
      else
      {
	 if (len_in != VERY_LONG_LEN) ERR;
      }
      if (strcmp(name_in, LAT_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1) ERR;
      if (nc_inq_dimid(ncid, LAT_NAME, &varid_in)) ERR;
      if (varid_in != 0) ERR;
      if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR;
      if (ndims_in != 0) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   FINAL_RESULTS;
}
Example #7
0
int
main(int argc, char **argv)
{
   printf("\n*** Testing netcdf-4 group functions.\n");
   printf("*** testing use of unlimited dim in parent group...");
   {
#define NDIMS_IN_VAR 1
#define NDIMS_IN_FILE 2
#define BABE_LIMIT 3
#define DIM_NAME1 "Influence"
#define DIM_NAME2 "Babe_Factor"
#define VAR_NAME1 "Court_of_Star_Chamber"
#define VAR_NAME2 "Justice_of_the_Peace"
#define VAR_NAME3 "Bosworth_Field"
      int ncid, dimid1, dimid2, varid1, varid2, varid3, henry_vii_id;
      int grpid_in, varid_in1, varid_in2, varid_in3;
      nc_type xtype_in;
      int ndims_in, dimids_in[NDIMS_IN_FILE], dimid1_in, natts;
      char name_in[NC_MAX_NAME + 1];
      size_t len_in, index[NDIMS_IN_VAR] = {0};
      long long value = NC_FILL_INT64 + 1, value_in;

      /* Create a file with an unlimited dim and a limited, used by
       * variables in child groups. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM_NAME1, NC_UNLIMITED, &dimid1)) ERR;
      if (nc_def_dim(ncid, DIM_NAME2, BABE_LIMIT, &dimid2)) ERR;
      if (nc_def_grp(ncid, HENRY_VII, &henry_vii_id)) ERR;
      if (nc_def_var(henry_vii_id, VAR_NAME1, NC_INT64, NDIMS_IN_VAR, &dimid1, &varid1)) ERR;
      if (nc_def_var(henry_vii_id, VAR_NAME2, NC_INT64, NDIMS_IN_VAR, &dimid1, &varid2)) ERR;
      if (nc_def_var(henry_vii_id, VAR_NAME3, NC_INT64, NDIMS_IN_VAR, &dimid2, &varid3)) ERR;

      /* Check it out. Find the group by name. */
      if (nc_inq_ncid(ncid, HENRY_VII, &grpid_in)) ERR;

      /* Ensure that dimensions in parent are visible and correct. */
      if (nc_inq_dimids(grpid_in, &ndims_in, dimids_in, 1)) ERR;
      if (ndims_in != NDIMS_IN_FILE || dimids_in[0] != dimid1 || dimids_in[1] != dimid2) ERR;
      if (nc_inq_dim(grpid_in, dimids_in[0], name_in, &len_in)) ERR;
      if (strcmp(name_in, DIM_NAME1) || len_in != 0) ERR;
      if (nc_inq_dim(grpid_in, dimids_in[1], name_in, &len_in)) ERR;
      if (strcmp(name_in, DIM_NAME2) || len_in != BABE_LIMIT) ERR;

      /* Check the vars in the group. */
      if (nc_inq_varid(grpid_in, VAR_NAME1, &varid_in1)) ERR;
      if (nc_inq_varid(grpid_in, VAR_NAME2, &varid_in2)) ERR;
      if (nc_inq_varid(grpid_in, VAR_NAME3, &varid_in3)) ERR;
      if (varid_in1 != varid1 || varid_in2 != varid2 || varid_in3 != varid3) ERR;
      if (nc_inq_var(grpid_in, varid1, name_in, &xtype_in, &ndims_in, &dimid1_in, &natts)) ERR;
      if (strcmp(name_in, VAR_NAME1) || xtype_in != NC_INT64 || ndims_in != NDIMS_IN_VAR ||
          dimid1_in != dimid1 || natts != 0) ERR;
      if (nc_inq_var(grpid_in, varid2, name_in, &xtype_in, &ndims_in, &dimid1_in, &natts)) ERR;
      if (strcmp(name_in, VAR_NAME2) || xtype_in != NC_INT64 || ndims_in != NDIMS_IN_VAR ||
          dimid1_in != dimid1 || natts != 0) ERR;
      if (nc_inq_var(grpid_in, varid3, name_in, &xtype_in, &ndims_in, &dimid1_in, &natts)) ERR;
      if (strcmp(name_in, VAR_NAME3) || xtype_in != NC_INT64 || ndims_in != NDIMS_IN_VAR ||
          dimid1_in != dimid2 || natts != 0) ERR;

      /* Write one value to one variable. */
      if (nc_put_var1_longlong(grpid_in, varid_in1, index, &value)) ERR;

      /* Read one value from the second unlim dim variable. It should
       * be the fill value. */
      if (nc_get_var1_longlong(grpid_in, varid_in2, index, &value_in)) ERR;
      if (value_in != NC_FILL_INT64) ERR;

      /* Read one value from the variable with limited dim. It should
       * be the fill value. */
      if (nc_get_var1_longlong(grpid_in, varid_in3, index, &value_in)) ERR;
      if (value_in != NC_FILL_INT64) ERR;

      /* Attempt to read beyond end of dimensions to generate error. */
      index[0] = BABE_LIMIT;
      if (nc_get_var1_longlong(grpid_in, varid_in1, index, &value_in) != NC_EINVALCOORDS) ERR;
      if (nc_get_var1_longlong(grpid_in, varid_in2, index, &value_in) != NC_EINVALCOORDS) ERR;
      if (nc_get_var1_longlong(grpid_in, varid_in3, index, &value_in) != NC_EINVALCOORDS) ERR;

      if (nc_close(ncid)) ERR;

      /* Check it out again. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      /* Find the group by name. */
      if (nc_inq_ncid(ncid, HENRY_VII, &grpid_in)) ERR;

      /* Ensure that dimensions in parent are visible and correct. */
      if (nc_inq_dimids(grpid_in, &ndims_in, dimids_in, 1)) ERR;
      if (ndims_in != NDIMS_IN_FILE || dimids_in[0] != dimid1 || dimids_in[1] != dimid2) ERR;
      if (nc_inq_dim(grpid_in, dimids_in[0], name_in, &len_in)) ERR;
      if (strcmp(name_in, DIM_NAME1) || len_in != 1) ERR;
      if (nc_inq_dim(grpid_in, dimids_in[1], name_in, &len_in)) ERR;
      if (strcmp(name_in, DIM_NAME2) || len_in != BABE_LIMIT) ERR;

      /* Check the vars in the group. */
      if (nc_inq_varid(grpid_in, VAR_NAME1, &varid_in1)) ERR;
      if (nc_inq_varid(grpid_in, VAR_NAME2, &varid_in2)) ERR;
      if (nc_inq_varid(grpid_in, VAR_NAME3, &varid_in3)) ERR;
      if (varid_in1 != varid1 || varid_in2 != varid2 || varid_in3 != varid3) ERR;
      if (nc_inq_var(grpid_in, varid1, name_in, &xtype_in, &ndims_in, &dimid1_in, &natts)) ERR;
      if (strcmp(name_in, VAR_NAME1) || xtype_in != NC_INT64 || ndims_in != NDIMS_IN_VAR ||
          dimid1_in != dimid1 || natts != 0) ERR;
      if (nc_inq_var(grpid_in, varid2, name_in, &xtype_in, &ndims_in, &dimid1_in, &natts)) ERR;
      if (strcmp(name_in, VAR_NAME2) || xtype_in != NC_INT64 || ndims_in != NDIMS_IN_VAR ||
          dimid1_in != dimid1 || natts != 0) ERR;
      if (nc_inq_var(grpid_in, varid3, name_in, &xtype_in, &ndims_in, &dimid1_in, &natts)) ERR;
      if (strcmp(name_in, VAR_NAME3) || xtype_in != NC_INT64 || ndims_in != NDIMS_IN_VAR ||
          dimid1_in != dimid2 || natts != 0) ERR;

      /* Read one value from the second unlim dim variable. It should
       * be the fill value. */
      index[0] = 0;
      if (nc_get_var1_longlong(grpid_in, varid_in2, index, &value_in)) ERR;
      if (value_in != NC_FILL_INT64) ERR;

      /* Read one value from the variable with limited dim. It should
       * be the fill value. */
      if (nc_get_var1_longlong(grpid_in, varid_in3, index, &value_in)) ERR;
      if (value_in != NC_FILL_INT64) ERR;

      /* Attempt to read beyond end of dimensions to generate error. */
      index[0] = BABE_LIMIT;
      if (nc_get_var1_longlong(grpid_in, varid_in1, index, &value_in) != NC_EINVALCOORDS) ERR;
      if (nc_get_var1_longlong(grpid_in, varid_in2, index, &value_in) != NC_EINVALCOORDS) ERR;
      if (nc_get_var1_longlong(grpid_in, varid_in3, index, &value_in) != NC_EINVALCOORDS) ERR;

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing groups and unlimited dimensions...");
   {
      int ncid;
      int henry_vii_id;
      int tudor_id;
      int dimids_in[MAX_SIBLING_GROUPS], ndims_in;
      int num_grps;
      int dimid, dynasty, varid;
      size_t len_in;
      int natts_in;
      int grpids_in[10];
      nc_type xtype_in;
      char name_in[NC_MAX_NAME + 1];
      int data_out[DIM1_LEN] = {0, 2, 6}, data_in[DIM1_LEN];
      size_t start[1] = {0}, count[1] = {3};
      int j;

      /* Create one group, with one var, which has one dimension, which is unlimited. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_grp(ncid, DYNASTY, &tudor_id)) ERR;
      if (nc_def_dim(tudor_id, DIM1_NAME, NC_UNLIMITED, &dimid)) ERR;
      if (nc_def_grp(tudor_id, HENRY_VII, &henry_vii_id)) ERR;
      if (nc_def_var(henry_vii_id, VAR1_NAME, NC_INT, 1, &dimid, &varid)) ERR;
      if (nc_put_vara_int(henry_vii_id, varid, start, count, data_out)) ERR;
      if (nc_close(ncid)) ERR;

      /* Now check the file to see if the dimension and variable are
       * there. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_grps(ncid, &num_grps, &dynasty)) ERR;
      if (num_grps != 1) ERR;
      if (nc_inq_grps(dynasty, &num_grps, grpids_in)) ERR;
      if (num_grps != 1) ERR;
      if (nc_inq_dim(grpids_in[0], 0, name_in, &len_in)) ERR;
      if (strcmp(name_in, DIM1_NAME) || len_in != DIM1_LEN) ERR;
      if (nc_inq_var(grpids_in[0], 0, name_in, &xtype_in, &ndims_in, dimids_in,
		     &natts_in)) ERR;
      if (strcmp(name_in, VAR1_NAME) || xtype_in != NC_INT || ndims_in != 1 ||
	  dimids_in[0] != 0 || natts_in != 0) ERR;
      if (nc_get_vara_int(grpids_in[0], 0, start, count, data_in)) ERR;
      for (j=0; j<DIM1_LEN; j++)
	 if (data_in[j] != data_out[j]) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   FINAL_RESULTS;
}
Example #8
0
int
check_4D_example(char *file_name, int expected_format)
{
   int ncid;
   int format, ndims_in, nvars_in, natts_in;
   int dimid[NDIMS_EX];
   int varid[NVARS_EX];
   char dim_name_in[NDIMS_EX][NC_MAX_NAME];
   char var_name_in[NVARS_EX][NC_MAX_NAME];
   char name_in[NC_MAX_NAME + 1];
   char units_in[NC_MAX_NAME + 1];
   nc_type xtype_in;
   size_t len_in;
   int i;

   if (nc_open(file_name, 0, &ncid)) ERR;

   /* Count stuff. */
   if (nc_inq_format(ncid, &format)) ERR;
   if (nc_inq_ndims(ncid, &ndims_in)) ERR;
   if (ndims_in != NDIMS_EX) ERR;
   if (nc_inq_nvars(ncid, &nvars_in)) ERR;
   if (nvars_in != NVARS_EX) ERR;
   if (nc_inq_natts(ncid, &natts_in)) ERR;
   if (natts_in != 0) ERR;
   if (format != expected_format) ERR;

   /* Check dimensions. */
   ndims_in = 0;
   if (nc_inq_dimids(ncid, &ndims_in, dimid, 0)) ERR;
   if (ndims_in != NDIMS_EX) ERR;
   for (i = 0; i < NDIMS_EX; i++)
   {
      if (dimid[i] != i) ERR;
      if (nc_inq_dimname(ncid, i, dim_name_in[i])) ERR;
   }
   if (strcmp(dim_name_in[0], LVL_NAME) || strcmp(dim_name_in[1], LAT_NAME) ||
       strcmp(dim_name_in[2], LON_NAME) || strcmp(dim_name_in[3], REC_NAME)) ERR;

   /* Check variables. */
   nvars_in = 0;
   if (nc_inq_varids(ncid, &nvars_in, varid)) ERR;
   if (nvars_in != NVARS_EX) ERR;
   for (i = 0; i < NVARS_EX; i++)
   {
      if (varid[i] != i) ERR;
      if (nc_inq_varname(ncid, i, var_name_in[i])) ERR;
   }
   if (strcmp(var_name_in[0], LAT_NAME) || strcmp(var_name_in[1], LON_NAME) ||
       strcmp(var_name_in[2], PRES_NAME) || strcmp(var_name_in[3], TEMP_NAME)) ERR;

   if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimid, &natts_in)) ERR;
   if (strcmp(name_in, LAT_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 || 
       dimid[0] != 1 || natts_in != 1) ERR;
   if (nc_inq_var(ncid, 1, name_in, &xtype_in, &ndims_in, dimid, &natts_in)) ERR;
   if (strcmp(name_in, LON_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 || 
       dimid[0] != 2 || natts_in != 1) ERR;
   if (nc_inq_var(ncid, 2, name_in, &xtype_in, &ndims_in, dimid, &natts_in)) ERR;
   if (strcmp(name_in, PRES_NAME) || xtype_in != NC_FLOAT || ndims_in != 4 || 
       dimid[0] != 3 || dimid[1] != 0 || dimid[2] != 1 || dimid[3] != 2 || 
       natts_in != 1) ERR;
   if (nc_inq_var(ncid, 3, name_in, &xtype_in, &ndims_in, dimid, &natts_in)) ERR;
   if (strcmp(name_in, TEMP_NAME) || xtype_in != NC_FLOAT || ndims_in != 4 || 
       dimid[0] != 3 || dimid[1] != 0 || dimid[2] != 1 || dimid[3] != 2 || 
       natts_in != 1) ERR;

   /* Check variable atts. */
   if (nc_inq_att(ncid, 0, UNITS, &xtype_in, &len_in)) ERR;
   if (xtype_in != NC_CHAR || len_in != strlen(DEGREES_NORTH)) ERR;
   if (nc_get_att_text(ncid, 0, UNITS, units_in)) ERR;
   if (strncmp(units_in, DEGREES_NORTH, strlen(DEGREES_NORTH))) ERR;

   if (nc_inq_att(ncid, 1, UNITS, &xtype_in, &len_in)) ERR;
   if (xtype_in != NC_CHAR || len_in != strlen(DEGREES_EAST)) ERR;
   if (nc_get_att_text(ncid, 1, UNITS, units_in)) ERR;
   if (strncmp(units_in, DEGREES_EAST, strlen(DEGREES_EAST))) ERR;

   if (nc_inq_att(ncid, 2, UNITS, &xtype_in, &len_in)) ERR;
   if (xtype_in != NC_CHAR || len_in != strlen(PRES_UNITS)) ERR;
   if (nc_get_att_text(ncid, 2, UNITS, units_in)) ERR;
   if (strncmp(units_in, PRES_UNITS, strlen(PRES_UNITS))) ERR;

   if (nc_inq_att(ncid, 3, UNITS, &xtype_in, &len_in)) ERR;
   if (xtype_in != NC_CHAR || len_in != strlen(TEMP_UNITS)) ERR;
   if (nc_get_att_text(ncid, 3, UNITS, units_in)) ERR;
   if (strncmp(units_in, TEMP_UNITS, strlen(TEMP_UNITS))) ERR;

   if (nc_close(ncid)) ERR;
   return err;
}
Example #9
0
int
main(int argc, char **argv)
{
   printf("\n*** Testing netcdf-4 coordinate dimensions and variables, some more.\n");

   printf("**** testing more complex 2D coordinate variable with dimensions defined in different order...");
   {
#define NDIMS 5
#define NVARS 4
#define LON_NAME "lon"
#define LAT_NAME "lat"
#define LVL_NAME "lvl"
#define TIME_NAME "time"
#define TEXT_LEN_NAME "text_len"
#define TEMP_NAME "temp"
#define PRES_NAME "pres"
#define LON_LEN 5
#define LAT_LEN 3
#define LVL_LEN 7
#define TIME_LEN 2
#define TEXT_LEN 15
#define TIME_NDIMS 2
#define DATA_NDIMS 4

      int ncid, nvars_in, varids_in[NVARS];
      int time_dimids[TIME_NDIMS];
      int dimids[NDIMS], time_id, lon_id, pres_id, temp_id;
      size_t time_count[NDIMS], time_index[NDIMS] = {0, 0};
      const char ttext[TEXT_LEN + 1]="20051224.150000";
      char ttext_in[TEXT_LEN + 1];
      int nvars, ndims, ngatts, unlimdimid;
      int ndims_in, natts_in, dimids_in[NDIMS];
      char var_name_in[NC_MAX_NAME + 1], dim_name_in[NC_MAX_NAME + 1];
      size_t len_in;
      nc_type xtype_in;
      int d;

      /* Create a netcdf-4 file. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;

      /* Define dimensions. */
      if (nc_def_dim(ncid, LON_NAME, LON_LEN, &dimids[0])) ERR;
      if (nc_def_dim(ncid, LAT_NAME, LAT_LEN, &dimids[1])) ERR;
      if (nc_def_dim(ncid, LVL_NAME, LVL_LEN, &dimids[2])) ERR;
      if (nc_def_dim(ncid, TIME_NAME, TIME_LEN, &dimids[3])) ERR;
      if (nc_def_dim(ncid, TEXT_LEN_NAME, TEXT_LEN, &dimids[4])) ERR;

      /* Define two coordinate variables out of order. */
      time_dimids[0] = dimids[3];
      time_dimids[1] = dimids[4];
      if (nc_def_var(ncid, TIME_NAME, NC_CHAR, TIME_NDIMS, time_dimids, &time_id)) ERR;
      if (nc_def_var(ncid, LON_NAME, NC_CHAR, 1, &dimids[0], &lon_id)) ERR;

      /* Write one time to the coordinate variable. */
      time_count[0] = 1;
      time_count[1] = TEXT_LEN;
      if (nc_put_vara_text(ncid, time_id, time_index, time_count, ttext)) ERR;

      /* Define two data variable. */
      if (nc_def_var(ncid, PRES_NAME, NC_CHAR, DATA_NDIMS, dimids, &pres_id)) ERR;
      if (nc_def_var(ncid, TEMP_NAME, NC_CHAR, DATA_NDIMS, dimids, &temp_id)) ERR;

      /* Check the data. */
      if (nc_get_vara_text(ncid, time_id, time_index, time_count, ttext_in)) ERR;
      if (strncmp(ttext, ttext_in, TEXT_LEN)) ERR;

      /* Check the metadata. */
      if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
      if (nvars != NVARS || ndims != NDIMS || ngatts != 0 || unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
      if (nvars_in != NVARS || varids_in[0] != 0 || varids_in[1] != 1 || 
	  varids_in[2] != 2 || varids_in[3] != 3) ERR;
      if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(var_name_in, TIME_NAME) || xtype_in != NC_CHAR || ndims_in != TIME_NDIMS ||
	dimids_in[0] != time_dimids[0] || dimids_in[1] != time_dimids[1] || natts_in != 0) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != NDIMS) ERR;
      for (d = 0; d < NDIMS; d++)
	 if (dimids_in[d] != dimids[d]) ERR;
      if (nc_inq_dim(ncid, 0, dim_name_in, &len_in)) ERR;
      if (strcmp(dim_name_in, LON_NAME) || len_in != LON_LEN) ERR;
      if (nc_inq_dim(ncid, 1, dim_name_in, &len_in)) ERR;
      if (strcmp(dim_name_in, LAT_NAME) || len_in != LAT_LEN) ERR;
      if (nc_inq_dim(ncid, 2, dim_name_in, &len_in)) ERR;
      if (strcmp(dim_name_in, LVL_NAME) || len_in != LVL_LEN) ERR;
      if (nc_inq_dim(ncid, 3, dim_name_in, &len_in)) ERR;
      if (strcmp(dim_name_in, TIME_NAME) || len_in != TIME_LEN) ERR;
      if (nc_inq_dim(ncid, 4, dim_name_in, &len_in)) ERR;
      if (strcmp(dim_name_in, TEXT_LEN_NAME) || len_in != TEXT_LEN) ERR;

      /* Close up. */
      if (nc_close(ncid)) ERR;

      /* Open the file and check the order of variables and dimensions. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
      if (nvars != NVARS || ndims != NDIMS || ngatts != 0 || unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
      if (nvars_in != NVARS || varids_in[0] != 0 || varids_in[1] != 1 || 
	  varids_in[2] != 2 || varids_in[3] != 3) ERR;
      if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(var_name_in, TIME_NAME) || xtype_in != NC_CHAR || ndims_in != TIME_NDIMS ||
	dimids_in[0] != time_dimids[0] || dimids_in[1] != time_dimids[1] || natts_in != 0) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != NDIMS) ERR;
      for (d = 0; d < NDIMS; d++)
	 if (dimids_in[d] != dimids[d]) ERR;
      if (nc_inq_dim(ncid, 0, dim_name_in, &len_in)) ERR;
      if (strcmp(dim_name_in, LON_NAME) || len_in != LON_LEN) ERR;
      if (nc_inq_dim(ncid, 1, dim_name_in, &len_in)) ERR;
      if (strcmp(dim_name_in, LAT_NAME) || len_in != LAT_LEN) ERR;
      if (nc_inq_dim(ncid, 2, dim_name_in, &len_in)) ERR;
      if (strcmp(dim_name_in, LVL_NAME) || len_in != LVL_LEN) ERR;
      if (nc_inq_dim(ncid, 3, dim_name_in, &len_in)) ERR;
      if (strcmp(dim_name_in, TIME_NAME) || len_in != TIME_LEN) ERR;
      if (nc_inq_dim(ncid, 4, dim_name_in, &len_in)) ERR;
      if (strcmp(dim_name_in, TEXT_LEN_NAME) || len_in != TEXT_LEN) ERR;

      /* Check the data. */
      if (nc_get_vara_text(ncid, time_id, time_index, time_count, ttext_in)) ERR;
      if (strncmp(ttext, ttext_in, TEXT_LEN)) ERR;

      /* Close up. */
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("**** testing example from bug NCF-247, multidimensional coord variable in subgroup ...");
   {
#define GRPNAME "g1"
#define DIM0NAME "dim0"
#define DIM1NAME "dim1"
#define DIM2NAME "coord"
#define DIM3NAME "dim3"
#define VARNAME  DIM2NAME
#define VARRANK 2
       int  ncid, grpid, varid, var_dims[VARRANK], var_dims_in[VARRANK];
       char name2[NC_MAX_NAME], name3[NC_MAX_NAME];
       int dim0_dim, dim1_dim, dim2_dim, dim3_dim;
       size_t dim0_len = 3, dim1_len = 2, dim2_len = 5, dim3_len = 7;

       if (nc_create(FILE_NAME, NC_CLOBBER|NC_NETCDF4, &ncid)) ERR;
       if (nc_def_grp(ncid, GRPNAME, &grpid)) ERR;
       
       if (nc_def_dim(ncid, DIM0NAME, dim0_len, &dim0_dim)) ERR;
       if (nc_def_dim(ncid, DIM1NAME, dim1_len, &dim1_dim)) ERR;
       if (nc_def_dim(grpid, DIM2NAME, dim2_len, &dim2_dim)) ERR;
       if (nc_def_dim(grpid, DIM3NAME, dim3_len, &dim3_dim)) ERR;

       var_dims[0] = dim2_dim;
       var_dims[1] = dim3_dim;
       if (nc_def_var(grpid, VARNAME, NC_INT, VARRANK, var_dims, &varid)) ERR;
    
       if (nc_close(ncid)) ERR;
    
       if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
    
       if (nc_inq_grp_ncid(ncid, GRPNAME, &grpid)) ERR;
    
       if (nc_inq_varid(grpid, VARNAME, &varid)) ERR;
       if (nc_inq_vardimid(grpid, varid, var_dims_in)) ERR;
       if (nc_inq_dimname(grpid, var_dims_in[0], name2)) ERR;
       if (nc_inq_dimname(grpid, var_dims_in[1], name3)) ERR;
       if (strcmp(name2, DIM2NAME) != 0 || strcmp(name3, DIM3NAME) != 0) ERR;
       if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   FINAL_RESULTS;
}
Example #10
0
int
main(int argc, char **argv)
{
   char file_name[NC_MAX_NAME + 1];

#ifdef USE_PARALLEL
   MPI_Init(&argc, &argv);
#endif

    printf("\n*** Testing really large files in netCDF-4/HDF5 format, quickly.\n");

    printf("*** Testing create of simple, but large, file...");
    {
#define DIM_NAME "Time_in_nanoseconds"
#define NUMDIMS 1
#define NUMVARS 4

       int ncid, dimids[NUMDIMS], varid[NUMVARS], chunksize[NUMDIMS];
       char var_name[NUMVARS][NC_MAX_NAME + 1] = {"England", "Scotland", "Ireland", "Wales"};
       size_t index[NUMDIMS] = {QTR_CLASSIC_MAX-1};
       int ndims, nvars, natts, unlimdimid;
       nc_type xtype;
       char name_in[NC_MAX_NAME + 1];
       size_t len;
       double pi = 3.1459, pi_in;
       int i; 

       /* Create a netCDF netCDF-4/HDF5 format file, with 4 vars. */
	sprintf(file_name, "%s/%s", TEMP_LARGE, FILE_NAME);
       if (nc_create(file_name, NC_NETCDF4, &ncid)) ERR;
       if (nc_set_fill(ncid, NC_NOFILL, NULL)) ERR;
       if (nc_def_dim(ncid, DIM_NAME, QTR_CLASSIC_MAX, dimids)) ERR;
       chunksize[0] = MEGABYTE/DOUBLE_SIZE;
       for (i = 0; i < NUMVARS; i++)
       {
	  if (nc_def_var(ncid, var_name[i], NC_DOUBLE, NUMDIMS, 
			 dimids, &varid[i])) ERR;
	  if (nc_def_var_chunking(ncid, i, 0, chunksize)) ERR;
       }
       if (nc_enddef(ncid)) ERR;
       for (i = 0; i < NUMVARS; i++)
	  if (nc_put_var1_double(ncid, i, index, &pi)) ERR;
       if (nc_close(ncid)) ERR;
       
       /* Reopen and check the file. */
       if (nc_open(file_name, 0, &ncid)) ERR;
       if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
       if (ndims != NUMDIMS || nvars != NUMVARS || natts != 0 || unlimdimid != -1) ERR;
       if (nc_inq_dimids(ncid, &ndims, dimids, 1)) ERR;
       if (ndims != 1 || dimids[0] != 0) ERR;
       if (nc_inq_dim(ncid, 0, name_in, &len)) ERR;
       if (strcmp(name_in, DIM_NAME) || len != QTR_CLASSIC_MAX) ERR;
       for (i = 0; i < NUMVARS; i++)
       {
	  if (nc_inq_var(ncid, i, name_in, &xtype, &ndims, dimids, &natts)) ERR;
	  if (strcmp(name_in, var_name[i]) || xtype != NC_DOUBLE || ndims != 1 || 
	      dimids[0] != 0 || natts != 0) ERR;
	  if (nc_get_var1_double(ncid, i, index, &pi_in)) ERR;
	  if (pi_in != pi) ERR;
       }
       if (nc_close(ncid)) ERR;
    }

    SUMMARIZE_ERR;

#ifdef USE_PARALLEL
   MPI_Finalize();
#endif   

    FINAL_RESULTS;
}
Example #11
0
int
main(int argc, char **argv)
{
   printf("\n*** Testing netcdf-4 coordinate variables and dimensions.\n");

   printf("**** testing Jeff Whitakers reported 4.1 bug...");
   {
#define NDIMS 2
#define NLAT 10
#define NLON 20
#define LAT_NAME "lat"
#define LON_NAME "lon"
#define NVARS 2
#define START_LAT 25.0
#define START_LON -125.0
      {
	 int ncid, lon_dimid, lat_dimid;
	 int lat_varid, lon_varid;
	 float lats[NLAT], lons[NLON];
	 int lat, lon;
	 int nvars, ndims, ngatts, unlimdimid, nvars_in, varids_in[NVARS];
	 int ndims_in, natts_in, dimids_in[NDIMS];
	 char var_name_in[NC_MAX_NAME + 1];
	 nc_type xtype_in;

	 /* Initialize coord data. */
	 for (lat = 0; lat < NLAT; lat++)
	    lats[lat] = START_LAT + 5. * lat;
	 for (lon = 0; lon < NLON; lon++)
	    lons[lon] = START_LON + 5. * lon;

	 /* Create file with two dimensions. */
	 if (nc_create(FILE_NAME, NC_NETCDF4 | NC_CLOBBER, &ncid)) ERR;
	 if (nc_def_dim(ncid, LAT_NAME, NLAT, &lat_dimid)) ERR;
	 if (nc_def_dim(ncid, LON_NAME, NLON, &lon_dimid)) ERR;

	 if (nc_def_var(ncid, LON_NAME, NC_FLOAT, 1, &lon_dimid, &lon_varid)) ERR;

	 /* Define and write longitude coord variable. */
	 if (nc_put_var_float(ncid, lon_varid, &lons[0])) ERR;

	 /* Define and write latitude coord variable. */
	 if (nc_def_var(ncid, LAT_NAME, NC_FLOAT, 1, &lat_dimid, &lat_varid)) ERR;
	 if (nc_put_var_float(ncid, lat_varid, &lats[0])) ERR;

	 if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
	 if (nvars != 2 || ndims != 2 || ngatts != 0 || unlimdimid != -1) ERR;
	 if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
	 if (nvars_in != 2 || varids_in[0] != 0 || varids_in[1] != 1) ERR;
	 if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
	 if (strcmp(var_name_in, LON_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	     dimids_in[0] != 1 || natts_in != 0) ERR;

	 /* Close the file. */
	 if (nc_close(ncid)) ERR;

	 /* Re-open and check the file. */
	 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

	 if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
	 if (nvars != 2 || ndims != 2 || ngatts != 0 || unlimdimid != -1) ERR;
	 if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
	 if (nvars_in != 2 || varids_in[0] != 0 || varids_in[1] != 1) ERR;
	 if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
	 if (strcmp(var_name_in, LON_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	 dimids_in[0] != 1 || natts_in != 0) ERR;

	 if (nc_close(ncid)) ERR;
      }

   }
   SUMMARIZE_ERR;
   printf("**** testing setting cache values for coordinate variables...");
   {
#define RANK_1 1
#define DIM0_NAME "d0"
#define CACHE_SIZE 1000000
#define CACHE_NELEMS 1009
#define CACHE_PREEMPTION .90

      int ncid, dimid, varid;
      char name_in[NC_MAX_NAME + 1];

      /* Create a test file with one dim and coord variable. */
      if (nc_create(FILE_NAME, NC_CLASSIC_MODEL|NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM0_NAME, NC_UNLIMITED, &dimid)) ERR;
      if (nc_def_var(ncid, DIM0_NAME, NC_DOUBLE, 1, &dimid, &varid)) ERR;
      if (nc_set_var_chunk_cache(ncid, varid, CACHE_SIZE, CACHE_NELEMS, CACHE_PREEMPTION)) ERR;
      if (nc_close(ncid)) ERR;

      /* Reopen the file and check. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_varname(ncid, 0, name_in)) ERR;
      if (strcmp(name_in, DIM0_NAME)) ERR;
      if (nc_set_var_chunk_cache(ncid, 0, CACHE_SIZE, CACHE_NELEMS, CACHE_PREEMPTION)) ERR;
      if (nc_inq_dimname(ncid, 0, name_in)) ERR;
      if (strcmp(name_in, DIM0_NAME)) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("**** testing multi-line strings in attributes...");
   {
      int ncid_classic, ncid_nc4;
      /*int attid;*/
      char att_in_classic[NC_MAX_NAME + 1], att_in_nc4[NC_MAX_NAME + 1];

#define FILE_CLASSIC "tst_coords_classic_att.nc"
#define FILE_NC4 "tst_coords_nc4_att.nc"
      /* Create a classic and a netcdf-4 file. */
      if (nc_create(FILE_CLASSIC, 0, &ncid_classic)) ERR;
      if (nc_create(FILE_NC4, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid_nc4)) ERR;

      /* Write an att to both. */
      if (nc_put_att_text(ncid_classic, NC_GLOBAL, INST_NAME, strlen(INSTITUTION) + 1, INSTITUTION)) ERR;
      if (nc_put_att_text(ncid_nc4, NC_GLOBAL, INST_NAME, strlen(INSTITUTION) + 1, INSTITUTION)) ERR;

      /* Close them. */
      if (nc_close(ncid_classic)) ERR;
      if (nc_close(ncid_nc4)) ERR;

      /* Reopen the files. */
      if (nc_open(FILE_CLASSIC, 0, &ncid_classic)) ERR;
      if (nc_open(FILE_NC4, 0, &ncid_nc4)) ERR;

      /* I'll show you mine, if you show me yours... */
      if (nc_get_att_text(ncid_classic, NC_GLOBAL, INST_NAME, att_in_classic)) ERR;
      if (nc_get_att_text(ncid_nc4, NC_GLOBAL, INST_NAME, att_in_nc4)) ERR;
      if (strcmp(att_in_classic, INSTITUTION) || strcmp(att_in_nc4, INSTITUTION) ||
	  strcmp(att_in_classic, att_in_nc4)) ERR;
      if (memcmp(att_in_classic, att_in_nc4, strlen(INSTITUTION) + 1)) ERR;

      /* Close them. */
      if (nc_close(ncid_classic)) ERR;
      if (nc_close(ncid_nc4)) ERR;
   }
   SUMMARIZE_ERR;
   printf("**** testing ar-4 example metadata with ncgen-generated code...");
   {
      int  stat;  /* return status */
      int  ncid;  /* netCDF id */

      /* group ids */
      int root_grp;

      /* dimension ids */
      int lon_dim;
      int lat_dim;
      int bnds_dim;
      int time_dim;

      /* dimension lengths */
      size_t lon_len = 256;
      size_t lat_len = 128;
      size_t bnds_len = 2;
      size_t time_len = NC_UNLIMITED;

      /* variable ids */
      int lon_bnds_id;
      int lat_bnds_id;
      int time_bnds_id;
      int time_id;
      int lat_id;
      int lon_id;
      int pr_id;

      /* rank (number of dimensions) for each variable */
#   define RANK_lon_bnds 2
#   define RANK_lat_bnds 2
#   define RANK_time_bnds 2
#   define RANK_time 1
#   define RANK_lat 1
#   define RANK_lon 1
#   define RANK_pr 3

      /* variable shapes */
      int lon_bnds_dims[RANK_lon_bnds];
      int lat_bnds_dims[RANK_lat_bnds];
      int time_bnds_dims[RANK_time_bnds];
      int time_dims[RANK_time];
      int lat_dims[RANK_lat];
      int lon_dims[RANK_lon];
      int pr_dims[RANK_pr];

      /* enter define mode */
      stat = nc_create(FILE_NAME, NC_NETCDF4 | NC_CLASSIC_MODEL, &ncid);
      check_err(stat,__LINE__,__FILE__);
      root_grp = ncid;

      /* define dimensions */
      stat = nc_def_dim(root_grp, "lon", lon_len, &lon_dim);
      check_err(stat,__LINE__,__FILE__);
      stat = nc_def_dim(root_grp, "lat", lat_len, &lat_dim);
      check_err(stat,__LINE__,__FILE__);
      stat = nc_def_dim(root_grp, "bnds", bnds_len, &bnds_dim);
      check_err(stat,__LINE__,__FILE__);
      stat = nc_def_dim(root_grp, "time", time_len, &time_dim);
      check_err(stat,__LINE__,__FILE__);

      /* define variables */

      lon_bnds_dims[0] = lon_dim;
      lon_bnds_dims[1] = bnds_dim;
      stat = nc_def_var(root_grp, "lon_bnds", NC_DOUBLE, RANK_lon_bnds, lon_bnds_dims, &lon_bnds_id);
      check_err(stat,__LINE__,__FILE__);

      lat_bnds_dims[0] = lat_dim;
      lat_bnds_dims[1] = bnds_dim;
      stat = nc_def_var(root_grp, "lat_bnds", NC_DOUBLE, RANK_lat_bnds, lat_bnds_dims, &lat_bnds_id);
      check_err(stat,__LINE__,__FILE__);

      time_bnds_dims[0] = time_dim;
      time_bnds_dims[1] = bnds_dim;
      stat = nc_def_var(root_grp, "time_bnds", NC_DOUBLE, RANK_time_bnds, time_bnds_dims, &time_bnds_id);
      check_err(stat,__LINE__,__FILE__);

      time_dims[0] = time_dim;
      stat = nc_def_var(root_grp, "time", NC_DOUBLE, RANK_time, time_dims, &time_id);
      check_err(stat,__LINE__,__FILE__);

      lat_dims[0] = lat_dim;
      stat = nc_def_var(root_grp, "lat", NC_DOUBLE, RANK_lat, lat_dims, &lat_id);
      check_err(stat,__LINE__,__FILE__);

      lon_dims[0] = lon_dim;
      stat = nc_def_var(root_grp, "lon", NC_DOUBLE, RANK_lon, lon_dims, &lon_id);
      check_err(stat,__LINE__,__FILE__);

      pr_dims[0] = time_dim;
      pr_dims[1] = lat_dim;
      pr_dims[2] = lon_dim;
      stat = nc_def_var(root_grp, "pr", NC_FLOAT, RANK_pr, pr_dims, &pr_id);
      check_err(stat,__LINE__,__FILE__);

      /* assign global attributes */
      { /* table_id */
	 static const char table_id_att[8] = {"Table A1"} ;
	 stat = nc_put_att_text(root_grp, NC_GLOBAL, "table_id", 8, table_id_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* title */
	 static const char title_att[34] = {"model output prepared for IPCC AR4"} ;
	 stat = nc_put_att_text(root_grp, NC_GLOBAL, "title", 34, title_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* institution */
	 static const char institution_att[66] = {INSTITUTION} ;
	 stat = nc_put_att_text(root_grp, NC_GLOBAL, INST_NAME, 66, institution_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* source */
	 static const char source_att[153] = {"CCSM3.0, version vector05 (2004): \natmosphere: CAM3.0, T85L26;\nocean     : POP1.4.3 (modified), gx1v3\nsea ice   : CSIM5.0, gx1v3;\nland      : CLM3.0, T85"} ;
	 stat = nc_put_att_text(root_grp, NC_GLOBAL, "source", 153, source_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* contact */
	 static const char contact_att[13] = {"*****@*****.**"} ;
	 stat = nc_put_att_text(root_grp, NC_GLOBAL, "contact", 13, contact_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* project_id */
	 static const char project_id_att[22] = {"IPCC Fourth Assessment"} ;
	 stat = nc_put_att_text(root_grp, NC_GLOBAL, "project_id", 22, project_id_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* Conventions */
	 static const char Conventions_att[6] = {"CF-1.0"} ;
	 stat = nc_put_att_text(root_grp, NC_GLOBAL, "Conventions", 6, Conventions_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* references */
	 static const char references_att[137] = {"Collins, W.D., et al., 2005:\n The Community Climate System Model, Version 3\n Journal of Climate\n \n Main website: http://www.ccsm.ucar.edu"} ;
	 stat = nc_put_att_text(root_grp, NC_GLOBAL, "references", 137, references_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* acknowledgment */
	 static const char acknowledgment_att[847] = {" Any use of CCSM data should acknowledge the contribution\n of the CCSM project and CCSM sponsor agencies with the \n following citation:\n 'This research uses data provided by the Community Climate\n System Model project (www.ccsm.ucar.edu), supported by the\n Directorate for Geosciences of the National Science Foundation\n and the Office of Biological and Environmental Research of\n the U.S. Department of Energy.'\nIn addition, the words 'Community Climate System Model' and\n 'CCSM' should be included as metadata for webpages referencing\n work using CCSM data or as keywords provided to journal or book\npublishers of your manuscripts.\nUsers of CCSM data accept the responsibility of emailing\n citations of publications of research using CCSM data to\n [email protected].\nAny redistribution of CCSM data must include this data\n acknowledgement statement."} ;
	 stat = nc_put_att_text(root_grp, NC_GLOBAL, "acknowledgment", 847, acknowledgment_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* realization */
	 static const int realization_att[1] = {8} ;
	 stat = nc_put_att_int(root_grp, NC_GLOBAL, "realization", NC_INT, 1, realization_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* experiment_id */
	 static const char experiment_id_att[46] = {"climate of the 20th Century experiment (20C3M)"} ;
	 stat = nc_put_att_text(root_grp, NC_GLOBAL, "experiment_id", 46, experiment_id_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* history */
	 static const char history_att[139] = {"Created from CCSM3 case b30.030g.ES01\n by [email protected]\n on Wed Sep 10 12:22:06 MDT 2008\n \n For all data, added IPCC requested metadata"} ;
	 stat = nc_put_att_text(root_grp, NC_GLOBAL, "history", 139, history_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* comment */
	 static const char comment_att[1105] = {"This simulation was initiated from year 460 of \n CCSM3 model run b30.020.ES01 and executed on \n hardware Earth Simulator Center, JAMSTEC. The input external forcings are\nozone forcing    : mozart.o3.128x64_L18_1870-2000_c040515.nc\naerosol optics   : AerosolOptics_c040105.nc\naerosol MMR      : AerosolMass_V_128x256_clim_c031022.nc\ncarbon scaling   : carbonscaling_1870-2000_c040225.nc\nsolar forcing    : scon_lean_1870-2100_c040123.nc\nGHGs             : ghg_1870_2100_c040122.nc\nGHG loss rates   : noaamisc.r8.nc\nvolcanic forcing : VolcanicMass_1870-1999_64x1_L18_c040123.nc\nDMS emissions    : DMS_emissions_128x256_clim_c040122.nc\noxidants         : oxid_128x256_L26_clim_c040112.nc\nSOx emissions    : SOx_emissions_128x256_L2_1850-2000_c040321.nc\n Physical constants used for derived data:\n Lv (latent heat of evaporation): 2.501e6 J kg-1\n Lf (latent heat of fusion     ): 3.337e5 J kg-1\n r[h2o] (density of water      ): 1000 kg m-3\n g2kg   (grams to kilograms    ): 1000 g kg-1\n \n Integrations were performed by NCAR and CRIEPI with support\n and facilities provided by NSF, DOE, MEXT and ESC/JAMSTEC."} ;
	 stat = nc_put_att_text(root_grp, NC_GLOBAL, "comment", 1105, comment_att);
	 check_err(stat,__LINE__,__FILE__);
      }


      /* assign per-variable attributes */
      { /* calendar */
	 static const char time_calendar_att[6] = {"noleap"} ;
	 stat = nc_put_att_text(root_grp, time_id, "calendar", 6, time_calendar_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* standard_name */
	 static const char time_standard_name_att[4] = {"time"} ;
	 stat = nc_put_att_text(root_grp, time_id, "standard_name", 4, time_standard_name_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* axis */
	 static const char time_axis_att[1] = {"T"} ;
	 stat = nc_put_att_text(root_grp, time_id, "axis", 1, time_axis_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* units */
	 static const char time_units_att[19] = {"days since 0000-1-1"} ;
	 stat = nc_put_att_text(root_grp, time_id, "units", 19, time_units_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* bounds */
	 static const char time_bounds_att[9] = {"time_bnds"} ;
	 stat = nc_put_att_text(root_grp, time_id, "bounds", 9, time_bounds_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* long_name */
	 static const char time_long_name_att[4] = {"time"} ;
	 stat = nc_put_att_text(root_grp, time_id, "long_name", 4, time_long_name_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* axis */
	 static const char lat_axis_att[1] = {"Y"} ;
	 stat = nc_put_att_text(root_grp, lat_id, "axis", 1, lat_axis_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* standard_name */
	 static const char lat_standard_name_att[8] = {"latitude"} ;
	 stat = nc_put_att_text(root_grp, lat_id, "standard_name", 8, lat_standard_name_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* bounds */
	 static const char lat_bounds_att[8] = {"lat_bnds"} ;
	 stat = nc_put_att_text(root_grp, lat_id, "bounds", 8, lat_bounds_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* long_name */
	 static const char lat_long_name_att[8] = {"latitude"} ;
	 stat = nc_put_att_text(root_grp, lat_id, "long_name", 8, lat_long_name_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* units */
	 static const char lat_units_att[13] = {"degrees_north"} ;
	 stat = nc_put_att_text(root_grp, lat_id, "units", 13, lat_units_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* axis */
	 static const char lon_axis_att[1] = {"X"} ;
	 stat = nc_put_att_text(root_grp, lon_id, "axis", 1, lon_axis_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* standard_name */
	 static const char lon_standard_name_att[9] = {"longitude"} ;
	 stat = nc_put_att_text(root_grp, lon_id, "standard_name", 9, lon_standard_name_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* bounds */
	 static const char lon_bounds_att[8] = {"lon_bnds"} ;
	 stat = nc_put_att_text(root_grp, lon_id, "bounds", 8, lon_bounds_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* long_name */
	 static const char lon_long_name_att[9] = {"longitude"} ;
	 stat = nc_put_att_text(root_grp, lon_id, "long_name", 9, lon_long_name_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* units */
	 static const char lon_units_att[12] = {"degrees_east"} ;
	 stat = nc_put_att_text(root_grp, lon_id, "units", 12, lon_units_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* comment */
	 static const char pr_comment_att[60] = {"Created using NCL code CCSM_atmm_2cf.ncl on\n machine mineral"} ;
	 stat = nc_put_att_text(root_grp, pr_id, "comment", 60, pr_comment_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* missing_value */
	 static const float pr_missing_value_att[1] = {1e+20} ;
	 stat = nc_put_att_float(root_grp, pr_id, "missing_value", NC_FLOAT, 1, pr_missing_value_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* _FillValue */
	 static const float pr_FillValue_att[1] = {1e+20} ;
	 stat = nc_put_att_float(root_grp, pr_id, "_FillValue", NC_FLOAT, 1, pr_FillValue_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* cell_methods */
	 static const char pr_cell_methods_att[30] = {"time: mean (interval: 1 month)"} ;
	 stat = nc_put_att_text(root_grp, pr_id, "cell_methods", 30, pr_cell_methods_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* history */
	 static const char pr_history_att[20] = {"(PRECC+PRECL)*r[h2o]"} ;
	 stat = nc_put_att_text(root_grp, pr_id, "history", 20, pr_history_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* original_units */
	 static const char pr_original_units_att[7] = {"m-1 s-1"} ;
	 stat = nc_put_att_text(root_grp, pr_id, "original_units", 7, pr_original_units_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* original_name */
	 static const char pr_original_name_att[12] = {"PRECC, PRECL"} ;
	 stat = nc_put_att_text(root_grp, pr_id, "original_name", 12, pr_original_name_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* standard_name */
	 static const char pr_standard_name_att[18] = {"precipitation_flux"} ;
	 stat = nc_put_att_text(root_grp, pr_id, "standard_name", 18, pr_standard_name_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* units */
	 static const char pr_units_att[10] = {"kg m-2 s-1"} ;
	 stat = nc_put_att_text(root_grp, pr_id, "units", 10, pr_units_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* long_name */
	 static const char pr_long_name_att[18] = {"precipitation_flux"} ;
	 stat = nc_put_att_text(root_grp, pr_id, "long_name", 18, pr_long_name_att);
	 check_err(stat,__LINE__,__FILE__);
      }
      { /* cell_method */
	 static const char pr_cell_method_att[10] = {"time: mean"} ;
	 stat = nc_put_att_text(root_grp, pr_id, "cell_method", 10, pr_cell_method_att);
	 check_err(stat,__LINE__,__FILE__);
      }

      /* don't initialize variables with fill values */
      stat = nc_set_fill(root_grp, NC_NOFILL, 0);
      check_err(stat,__LINE__,__FILE__);

      /* leave define mode */
      stat = nc_enddef (root_grp);
      check_err(stat,__LINE__,__FILE__);

      stat = nc_close(root_grp);
      check_err(stat,__LINE__,__FILE__);

      {
#define NDIMS4 4
	 int ndims, dimids_in[NDIMS4];
	 char name_in[NC_MAX_NAME + 1];
	 char institution_att_in[NC_MAX_NAME + 1];

	 /* Now open this file and check order of dimensions. */
	 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

	 /* Check dimids. */
	 if (nc_inq_dimname(ncid, 0, name_in)) ERR;
	 if (strcmp(name_in, "lon")) ERR;
	 if (nc_inq_dimname(ncid, 1, name_in)) ERR;
	 if (strcmp(name_in, "lat")) ERR;
	 if (nc_inq_dimname(ncid, 2, name_in)) ERR;
	 if (strcmp(name_in, "bnds")) ERR;
	 if (nc_inq_dimname(ncid, 3, name_in)) ERR;
	 if (strcmp(name_in, "time")) ERR;

	 /* Check inq_dimids function. */
	 if (nc_inq_dimids(ncid, &ndims, dimids_in, 0)) ERR;
	 if (ndims != NDIMS4 || dimids_in[0] != 0 || dimids_in[1] != 1 ||
	     dimids_in[2] != 2 || dimids_in[3] != 3) ERR;

	 /* Check attribute with line breaks. */
	 if (nc_get_att_text(ncid, NC_GLOBAL, INST_NAME,
			     institution_att_in)) ERR;
	 if (strncmp(institution_att_in, INSTITUTION, strlen(INSTITUTION))) ERR;

	 if (nc_close(ncid)) ERR;
      }

   }
   SUMMARIZE_ERR;
   printf("**** testing dim order when coord vars are defined in the wrong order...");
   {
#define RANK_2 2
#define DIM0 "d0"
#define DIM1 "d1"
      int ncid, dimids[RANK_2], varid[RANK_2];
      char name_in[NC_MAX_NAME + 1];

      /* Create a test file. */
      if (nc_create(FILE_NAME, NC_CLASSIC_MODEL|NC_NETCDF4, &ncid)) ERR;

      /* Define dimensions in order. */
      if (nc_def_dim(ncid, DIM0, NC_UNLIMITED, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM1, 4, &dimids[1])) ERR;

      /* Define coordinate variables in a different order. */
      if (nc_def_var(ncid, DIM1, NC_DOUBLE, 1, &dimids[1], &varid[1])) ERR;
      if (nc_def_var(ncid, DIM0, NC_DOUBLE, 1, &dimids[0], &varid[0])) ERR;

      /* That's it! */
      if (nc_close(ncid)) ERR;

      /* Reopen the file and check dimension order. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      if (nc_inq_dimname(ncid, 0, name_in)) ERR;
      if (strcmp(name_in, DIM0)) ERR;
      if (nc_inq_dimname(ncid, 1, name_in)) ERR;
      if (strcmp(name_in, DIM1)) ERR;

      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("**** testing order of coordinate dims...");
   {
#define RANK_3 3
#define DIM1_NAME "d1"
#define DIM2_NAME "d2"
#define DIM3_NAME "d3"
      int ncid, dimids[RANK_3], varid[RANK_3];
      char name_in[NC_MAX_NAME + 1];

      /* Create a 3D test file. */
      if (nc_create(FILE_NAME, NC_CLASSIC_MODEL|NC_NETCDF4, &ncid)) ERR;

      /* Define dimensions in order. */
      if (nc_def_dim(ncid, DIM1_NAME, NC_UNLIMITED, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM2_NAME, 4, &dimids[1])) ERR;
      if (nc_def_dim(ncid, DIM3_NAME, 3, &dimids[2])) ERR;

      /* Define coordinate variables in a different order. */
      if (nc_def_var(ncid, DIM1_NAME, NC_DOUBLE, 1, &dimids[0], &varid[0])) ERR;
      if (nc_def_var(ncid, DIM2_NAME, NC_DOUBLE, 1, &dimids[1], &varid[1])) ERR;
      if (nc_def_var(ncid, DIM3_NAME, NC_DOUBLE, 1, &dimids[2], &varid[2])) ERR;

      /* That's it! */
      if (nc_close(ncid)) ERR;

      /* Reopen the file and check dimension order. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      if (nc_inq_dimname(ncid, 0, name_in)) ERR;
      if (strcmp(name_in, DIM1_NAME)) ERR;
      if (nc_inq_dimname(ncid, 1, name_in)) ERR;
      if (strcmp(name_in, DIM2_NAME)) ERR;
      if (nc_inq_dimname(ncid, 2, name_in)) ERR;
      if (strcmp(name_in, DIM3_NAME)) ERR;

      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("**** testing coordinate vars...");
   {
#   define RANK_Coordinates_lat 1
      int ncid;
      int Coordinates_grp;
      int lat_dim;
      size_t lat_len = 3;
      int Coordinates_lat_id;

      if(nc_create(FILE_NAME, NC_CLOBBER|NC_NETCDF4, &ncid)) ERR;
      if (nc_def_grp(ncid, "Coordinates", &Coordinates_grp)) ERR;

      /* Define dimensions in root group. */
      if (nc_def_dim(ncid, "lat", lat_len, &lat_dim)) ERR;

      /* Define coordinate variable in Coordinates group. */
      if (nc_def_var(Coordinates_grp, "lat", NC_FLOAT,
		     1, &lat_dim, &Coordinates_lat_id)) ERR;

      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("**** testing 2D non-coordinate variable...");
   {
#define VAR_NAME "Britany"
#define NDIMS 2
#define TEXT_LEN 15
#define D0_NAME "time"
#define D1_NAME "tl"
      int ncid, nvars_in, varids_in[1];
      int time_dimids[NDIMS], time_id;
      size_t time_count[NDIMS], time_index[NDIMS] = {0, 0};
      const char ttext[TEXT_LEN]="20051224.150000";
      int nvars, ndims, ngatts, unlimdimid;
      int ndims_in, natts_in, dimids_in[NDIMS];
      char var_name_in[NC_MAX_NAME + 1];
      nc_type xtype_in;

      /* Create a netcdf-4 file with 2D coordinate var. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;

      if (nc_def_dim(ncid, D0_NAME, NC_UNLIMITED, &time_dimids[0])) ERR;
      if (nc_def_dim(ncid, D1_NAME, TEXT_LEN, &time_dimids[1])) ERR;
      if (nc_def_var(ncid, VAR_NAME, NC_USHORT, NDIMS, time_dimids,
		     &time_id) != NC_ESTRICTNC3) ERR;
      if (nc_def_var(ncid, VAR_NAME, NC_CHAR, NDIMS, time_dimids, &time_id)) ERR;
      if (nc_enddef(ncid)) ERR;

      /* Write one time to the coordinate variable. */
      time_count[0] = 1;
      time_count[1] = TEXT_LEN;
      if (nc_put_vara_text(ncid, time_id, time_index, time_count, ttext)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and check. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
      if (nvars != 1 || ndims != 2 || ngatts != 0 || unlimdimid != 0) ERR;
      if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
      if (nvars_in != 1 || varids_in[0] != 0) ERR;
      if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(var_name_in, VAR_NAME) || xtype_in != NC_CHAR || ndims_in != 2 ||
          dimids_in[0] != 0 || dimids_in[1] != 1 || natts_in != 0) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("**** testing 2D coordinate variable...");
   {
#define NDIMS 2
#define TEXT_LEN 15
#define D0_NAME "time"
#define D1_NAME "tl"
      int ncid, nvars_in, varids_in[1];
      int time_dimids[NDIMS], time_id;
      size_t time_count[NDIMS], time_index[NDIMS] = {0, 0};
      const char ttext[TEXT_LEN + 1]="20051224.150000";
      int nvars, ndims, ngatts, unlimdimid;
      int ndims_in, natts_in, dimids_in[NDIMS];
      char var_name_in[NC_MAX_NAME + 1];
      nc_type xtype_in;

      /* Create a netcdf-4 file with 2D coordinate var. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, D0_NAME, NC_UNLIMITED, &time_dimids[0])) ERR;
      if (nc_def_dim(ncid, D1_NAME, TEXT_LEN, &time_dimids[1])) ERR;
      if (nc_def_var(ncid, D0_NAME, NC_CHAR, NDIMS, time_dimids, &time_id)) ERR;

      /* Write one time to the coordinate variable. */
      time_count[0] = 1;
      time_count[1] = TEXT_LEN;
      if (nc_put_vara_text(ncid, time_id, time_index, time_count, ttext)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and check. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
      if (nvars != 1 || ndims != 2 || ngatts != 0 || unlimdimid != 0) ERR;
      if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
      if (nvars_in != 1 || varids_in[0] != 0) ERR;
      if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(var_name_in, D0_NAME) || xtype_in != NC_CHAR || ndims_in != 2 ||
	dimids_in[0] != 0 || dimids_in[1] != 1 || natts_in != 0) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("**** testing new order of doing things with coordinate variable...");
   {
      /* In this test:
           define a dimension
           define a variable that uses that dimension
           put values in the variable
           define coordinate values for the dimension
      */
#define VAR_NAME_BB "The_Birth_of_Britain"
#define NDIMS_1 1
#define TEXT_LEN 15
#define WINSTON_CHURCHILL "Winston_S_Churchill"
#define D0_LEN 2
#define NUM_VARS_2 2
      int ncid, nvars_in, varids_in[NUM_VARS_2];
      int dimid, varid, varid2;
      int nvars, ndims, ngatts, unlimdimid;
      int ndims_in, natts_in, dimids_in[NDIMS];
      char var_name_in[NC_MAX_NAME + 1];
      nc_type xtype_in;
      int data[D0_LEN] = {42, -42};

      /* Create a netcdf-4 file with 2D coordinate var. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, WINSTON_CHURCHILL, NC_UNLIMITED, &dimid)) ERR;
      if (nc_def_var(ncid, VAR_NAME, NC_INT, NDIMS_1, &dimid, &varid)) ERR;
      if (nc_put_var_int(ncid, varid, data)) ERR;
      if (nc_def_var(ncid, WINSTON_CHURCHILL, NC_INT, NDIMS_1, &dimid, &varid2)) ERR;
      if (nc_put_var_int(ncid, varid2, data)) ERR;

      /* Check things. */
      if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
      if (nvars != 2 || ndims != 1 || ngatts != 0 || unlimdimid != 0) ERR;
      if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
      if (nvars_in != 2 || varids_in[0] != 0 || varids_in[1] != 1) ERR;
      if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(var_name_in, VAR_NAME) || xtype_in != NC_INT || ndims_in != 1 ||
	  dimids_in[0] != 0 || natts_in != 0) ERR;

      if (nc_close(ncid)) ERR;

      /* Open the file and check. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
      if (nvars != 2 || ndims != 1 || ngatts != 0 || unlimdimid != 0) ERR;
      if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
      if (nvars_in != 2 || varids_in[0] != 0 || varids_in[1] != 1) ERR;
      if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(var_name_in, VAR_NAME) || xtype_in != NC_INT || ndims_in != 1 ||
	  dimids_in[0] != 0 || natts_in != 0) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("**** testing 2D coordinate variable with dimensions defined in different order...");
   {
#define NDIMS 2
#define TEXT_LEN 15
#define D0_NAME "time"
#define D1_NAME "tl"
#define NUM_VARS 2
      int ncid, nvars_in, varids_in[NUM_VARS];
      int time_dimids[NDIMS], time_id, tl_id;
      size_t time_count[NDIMS], time_index[NDIMS] = {0, 0};
      const char ttext[TEXT_LEN + 1]="20051224.150000";
      char ttext_in[TEXT_LEN + 1];
      int nvars, ndims, ngatts, unlimdimid;
      int ndims_in, natts_in, dimids_in[NDIMS];
      char var_name_in[NC_MAX_NAME + 1], dim_name_in[NC_MAX_NAME + 1];
      size_t len_in;
      nc_type xtype_in;

      /* Create a netcdf-4 file with 2D coordinate var. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, D1_NAME, TEXT_LEN, &time_dimids[1])) ERR;
      if (nc_def_dim(ncid, D0_NAME, NC_UNLIMITED, &time_dimids[0])) ERR;
      if (nc_def_var(ncid, D0_NAME, NC_CHAR, NDIMS, time_dimids, &time_id)) ERR;
      if (nc_def_var(ncid, D1_NAME, NC_CHAR, 1, &time_dimids[0], &tl_id)) ERR;

      /* Write one time to the coordinate variable. */
      time_count[0] = 1;
      time_count[1] = TEXT_LEN;
      if (nc_put_vara_text(ncid, time_id, time_index, time_count, ttext)) ERR;

      /* Check the data. */
      if (nc_get_vara_text(ncid, time_id, time_index, time_count, ttext_in)) ERR;
      if (strncmp(ttext, ttext_in, TEXT_LEN)) ERR;

      /* Close up. */
      if (nc_close(ncid)) ERR;

      /* Open the file and check. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
      if (nvars != NUM_VARS || ndims != NDIMS || ngatts != 0 || unlimdimid != 1) ERR;
      if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
      if (nvars_in != NUM_VARS || varids_in[0] != 0 || varids_in[1] != 1) ERR;
      if (nc_inq_var(ncid, 0, var_name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(var_name_in, D0_NAME) || xtype_in != NC_CHAR || ndims_in != NDIMS ||
	dimids_in[0] != 1 || dimids_in[1] != 0 || natts_in != 0) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != NDIMS || dimids_in[0] != 0 || dimids_in[1] != 1) ERR;
      if (nc_inq_dim(ncid, 0, dim_name_in, &len_in)) ERR;
      if (strcmp(dim_name_in, D1_NAME) || len_in != TEXT_LEN) ERR;
      if (nc_inq_dim(ncid, 1, dim_name_in, &len_in)) ERR;
      if (strcmp(dim_name_in, D0_NAME) || len_in != 1) ERR;

      /* Check the data. */
      if (nc_get_vara_text(ncid, time_id, time_index, time_count, ttext_in)) ERR;
      if (strncmp(ttext, ttext_in, TEXT_LEN)) ERR;

      /* Close up. */
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   FINAL_RESULTS;
}
Example #12
0
int NC::Init(const char *fname) {
  FILE *F;
  int   jj,rc;
  int   ncid, ndims, dimids[128];
  int   nvars, varids[128], vardim;
  size_t alen, len[128];

  F=fopen(fname,"r");
  if ( !F ) {
    fprintf(stderr, "Bummer: unable to open %s to read. \n", fname);
    return (-1);
  }
  fclose(F);

  /* read the netCDF file  */
  if ( (rc = nc_open(fname, NC_NOWRITE, &ncid)) != NC_NOERR) NETCDF_ERR(rc);

  
  if ( (rc = nc_inq_dimids(ncid, &ndims, dimids,0)) != NC_NOERR) NETCDF_ERR(rc);
#if PRT
  int kk,where;
  printf("dim = %d\n", ndims);
#endif
  for (jj=0; jj<ndims;jj++) { 
    if ( (rc = nc_inq_dimlen(ncid, dimids[jj],&alen)) != NC_NOERR) NETCDF_ERR(rc);
    len[jj] = alen;

#if PRT
    printf("The %d th dimension's length is: %d \n", dimids[jj], (unsigned int)alen);
#endif
  }

  _num_comid = (int)len[0];
  _num_time = (int)len[1];
  
  if ( (rc = nc_inq_varids(ncid, &nvars, varids)) != NC_NOERR) NETCDF_ERR(rc);
#if PRT
  printf("var = %d\n", nvars);
#endif

  _num_vars = nvars;

  for (jj=0; jj<nvars;jj++) {
    if ( (rc = nc_inq_varndims(ncid, varids[jj],&vardim)) != NC_NOERR) NETCDF_ERR(rc);
#if PRT
    printf("%d %d\n", varids[jj], vardim);
#endif
  }

#if PRT
  printf("%d\n", (unsigned int)len[0]);
#endif



  _comids = (int*)malloc( len[0] *sizeof(int) ); //allocate memory for comids
  _runoff = (float*)malloc( len[0]*len[1] * sizeof(float));  //assign memory for runoff



  if (!_comids) return (-1);
  //assign comid to memory
  if ( ( rc = nc_get_var_int(ncid, varids[0], _comids)) != NC_NOERR) NETCDF_ERR(rc);
  
  if ( !_runoff ) return (-1);

  if ( (rc=nc_get_var_float(ncid, varids[1], _runoff)) != NC_NOERR) NETCDF_ERR(rc);

  if (nvars == 3)
  {
    _upstream_hg = (float*)malloc( len[0]*len[1] * sizeof(float));

    if ( (rc=nc_get_var_float(ncid, varids[2], _upstream_hg)) != NC_NOERR) NETCDF_ERR(rc);
  }

  if ( (rc=nc_close(ncid)) != NC_NOERR ) NETCDF_ERR(rc);

//printf("dimensions : %d , %d \n", len[0],len[1]);
//for (int kk = 0; kk<_num_comid; kk++){printf("%i \n", _comids[kk]);}

#if PRT  
  for (kk=0; kk< len[0]; kk++) {
    where = _search_index(_comids[kk]);
    if ( where >= 0 ) {
      printf("%d: ", _comids[kk]);
      for ( jj=0; jj<len[1]; jj++) {
	printf("%g ", _runoff[jj*len[0]+where]); 
      }
      printf("\n");
      
    } else {
      printf("%d not found\n", _comids[kk]);
    }
  }
#endif

#if 0
  *e_comids = comids;
  *e_sgs = bgs;
  *e_ss = ss;
#endif

  return rc;

}