Exemplo n.º 1
0
int find_dimid(int ncid1,int dimf1,int ncid2) {
  // Find the dimension ID in ncid2 with the same name as dimf1 in ncid1.
  char dimname[NC_MAX_NAME], message[200];
  int status, dimid;
  size_t len1, len2;

  if (ncid1==ncid2) return dimf1;
  
  status = nc_inq_dim(ncid1,dimf1,dimname,&len1);
  if (status != NC_NOERR) handle_error(status,"Finding dimension name",status);
  status = nc_inq_dimid(ncid2,dimname,&dimid);
  if (status != NC_NOERR) {
    sprintf(message,"Cannot find dimension %s in first input file.\n",dimname);
    handle_error(status,dimname,status);
  }
  status = nc_inq_dimlen(ncid2,dimid,&len2);

  if (len1 != len2) {
    printf("ERROR: Dimension %s does not agree in size between files; it is %ld and %ld.\n",
           dimname,(long)len2,(long)len1);
    exit(-1);
  }

  // Compare axis data?

  return dimid;
}
Exemplo n.º 2
0
/** @brief Check the output file.
 *
 *  Use netCDF to check that the output is as expected. 
 *
 * @param ntasks The number of processors running the example. 
 * @param filename The name of the example file to check. 
 *
 * @return 0 if example file is correct, non-zero otherwise. */
int check_file(int ntasks, char *filename) {
    
    int ncid;         /**< File ID from netCDF. */
    int ndims;        /**< Number of dimensions. */
    int nvars;        /**< Number of variables. */
    int ngatts;       /**< Number of global attributes. */
    int unlimdimid;   /**< ID of unlimited dimension. */
    size_t dimlen;    /**< Length of the dimension. */
    int natts;        /**< Number of variable attributes. */
    nc_type xtype;    /**< NetCDF data type of this variable. */
    int ret;          /**< Return code for function calls. */
    int dimids[NDIM]; /**< Dimension ids for this variable. */
    char dim_name[NC_MAX_NAME];   /**< Name of the dimension. */
    char var_name[NC_MAX_NAME];   /**< Name of the variable. */
    size_t start[NDIM];           /**< Zero-based index to start read. */
    size_t count[NDIM];           /**< Number of elements to read. */
    int buffer[DIM_LEN];          /**< Buffer to read in data. */
    int expected[DIM_LEN];        /**< Data values we expect to find. */
    
    /* Open the file. */
    if ((ret = nc_open(filename, 0, &ncid)))
	return ret;

    /* Check the metadata. */
    if ((ret = nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)))
	return ret;
    if (ndims != NDIM || nvars != 1 || ngatts != 0 || unlimdimid != -1)
	return ERR_BAD;
    if ((ret = nc_inq_dim(ncid, 0, dim_name, &dimlen)))
	return ret;
    if (dimlen != DIM_LEN || strcmp(dim_name, DIM_NAME))
	return ERR_BAD;
    if ((ret = nc_inq_var(ncid, 0, var_name, &xtype, &ndims, dimids, &natts)))
	return ret;
    if (xtype != NC_INT || ndims != NDIM || dimids[0] != 0 || natts != 0)
	return ERR_BAD;

    /* Use the number of processors to figure out what the data in the
     * file should look like. */
    int div = DIM_LEN/ntasks;
    for (int d = 0; d < DIM_LEN; d++)
	expected[d] = START_DATA_VAL + d/div;
    
    /* Check the data. */
    start[0] = 0;
    count[0] = DIM_LEN;
    if ((ret = nc_get_vara(ncid, 0, start, count, buffer)))
	return ret;
    for (int d = 0; d < DIM_LEN; d++)
	if (buffer[d] != expected[d])
	    return ERR_BAD;

    /* Close the file. */
    if ((ret = nc_close(ncid)))
	return ret;

    /* Everything looks good! */
    return 0;
}
Exemplo n.º 3
0
int
main(int argc, char **argv)
{
   printf("\n*** Testing netcdf file functions some more.\n");
#ifdef USE_DAP
#ifdef ENABLE_DAP_REMOTE_TESTS
   printf("*** testing simple opendap open/close...");
   {
      int ncid;

      /* Test with URL. */
      if (nc_open(URL, 0, &ncid)) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
#endif /*ENABLE_DAP_REMOTE_TESTS*/
#endif /* USE_DAP */
   printf("*** testing Jeff Whitaker's test...");
   {
#define DIM_NAME "xc"      
#define DIM_LEN 134      
#define VAR_NAME1 "var1"
#define VAR_NAME2 "var2"
      
      int ncid, dimid, varid1, varid2, dimid_in;
      int ndims_in, natts_in;
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      nc_type xtype_in;

      if (nc_create(FILE_NAME, NC_CLOBBER|NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM_NAME, DIM_LEN, &dimid)) ERR;
      if (nc_def_var(ncid, VAR_NAME1, NC_FLOAT, 1, &dimid, &varid1)) ERR;
      if (nc_def_var(ncid, VAR_NAME2, NC_FLOAT, 1, &dimid, &varid2)) ERR;
      if (nc_def_var(ncid, DIM_NAME, NC_FLOAT, 1, &dimid, &varid2)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open and check. */
      if (nc_open(FILE_NAME, NC_CLOBBER|NC_NETCDF4, &ncid)) ERR;
      if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR;
      if (strcmp(name_in, DIM_NAME) || len_in != DIM_LEN) ERR;
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, 
		     &dimid_in, &natts_in)) ERR;
      if (strcmp(name_in, VAR_NAME1) || xtype_in != NC_FLOAT || 
	  ndims_in != 1 || dimid_in != 0 || natts_in != 0) ERR;
      if (nc_inq_var(ncid, 1, name_in, &xtype_in, &ndims_in, 
		     &dimid_in, &natts_in)) ERR;
      if (strcmp(name_in, VAR_NAME2) || xtype_in != NC_FLOAT || 
	  ndims_in != 1 || dimid_in != 0 || natts_in != 0) ERR;
      if (nc_inq_var(ncid, 2, name_in, &xtype_in, &ndims_in, 
		     &dimid_in, &natts_in)) ERR;
      if (strcmp(name_in, DIM_NAME) || xtype_in != NC_FLOAT || 
	  ndims_in != 1 || dimid_in != 0 || natts_in != 0) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   FINAL_RESULTS;
}
Exemplo n.º 4
0
void sdatio_dimension_size(struct sdatio_file * sfile, char * dimension_name, int * n){
  struct sdatio_dimension * sdim = sdatio_find_dimension(sfile, dimension_name);
  size_t lengthp;
  int retval;
  char * name_tmp = (char*)malloc(sizeof(char*)*(NC_MAX_NAME+1));
  if (sdim->size == SDATIO_UNLIMITED){
    if ((retval = nc_inq_dim(sfile->nc_file_id, sdim->nc_id, name_tmp, &lengthp))) ERR(retval);
    *n = lengthp;
  }
  else *n =  sdim->size;
  free(name_tmp);
}
Exemplo n.º 5
0
Arquivo: ncdf.c Projeto: cran/ncdf
void R_nc_inq_dim( int *ncid, int *dimid, char **dimname, int *dimlen,
				int *retval )
{
	char name[NC_MAX_NAME];
	size_t len;

	*retval = nc_inq_dim(*ncid, *dimid, name, &len);
	if( *retval != NC_NOERR ) 
		REprintf( "Error in R_nc_inq_dim: %s\n", 
			nc_strerror(*retval) );
	*dimlen = (int)len;
	/* NOTE NOTE NOTE!! This assumes that the calling process
	 * allocated storage of at least NC_MAX_NAME!
	 */
	strcpy(dimname[0], name);
}
Exemplo n.º 6
0
static void
testdims(int cdfid, size_t num_dims, size_t *sizes, const char * const dim_names[])
{
	int ii;
	size_t size;
	char cp[NC_MAX_NAME];
	for(ii=0; (size_t) ii < num_dims; ii++, sizes++)
	{
		assert( nc_inq_dim(cdfid, ii, cp, &size) == NC_NOERR);
		if( size != *sizes)
			(void) fprintf(stderr, "%d: %lu != %lu\n",
				ii, (unsigned long)size, (unsigned long)*sizes);
		assert( size == *sizes);
		assert( strcmp(cp, *dim_names++) == 0);
	}

}
Exemplo n.º 7
0
/* Compose create table statement to create table representing NetCDF variable in the
 * database. Used for testing, can be removed from release. */
str
NCDFimportVarStmt(str *sciqlstmt, str *fname, int *varid)
{
	int ncid;   /* dataset id */
	int vndims, vnatts, i, j, retval;
	int vdims[NC_MAX_VAR_DIMS];

	size_t dlen;
	char dname[NC_MAX_NAME+1], vname[NC_MAX_NAME+1];
	nc_type vtype; /* == int */

	char buf[BUFSIZ];
	str msg = MAL_SUCCEED;

	/* Open NetCDF file  */
	if ((retval = nc_open(*fname, NC_NOWRITE, &ncid)))
        return createException(MAL, "netcdf.importvar",
            "Cannot open NetCDF file %s: %s", *fname, nc_strerror(retval));

	if ( (retval = nc_inq_var(ncid, *varid, vname, &vtype, &vndims, vdims, &vnatts)))
	    return createException(MAL, "netcdf.attach",
		    "Cannot read variable %d : %s", *varid, nc_strerror(retval));


	j = snprintf(buf, BUFSIZ,"create table %s( ", vname);

	for (i = 0; i < vndims; i++){
	    if ((retval = nc_inq_dim(ncid, vdims[i], dname, &dlen)))
	        return createException(MAL, "netcdf.attach",
			    "Cannot read dimension %d : %s", vdims[i], nc_strerror(retval));

	  (void)dlen;
	  j += snprintf(buf + j, BUFSIZ - j, "%s INTEGER, ", dname);

	}

	j += snprintf(buf + j, BUFSIZ - j, "value %s);", NCDF2SQL(vtype));

	nc_close(ncid);

	*sciqlstmt = GDKstrdup(buf);
	return msg;
}
Exemplo n.º 8
0
/**
@ingroup variables
@internal Does a variable have a record dimension?

@param ncid File ID.
@param varid Variable ID.
@param nrecs Pointer that gets number of records.

@returns 0 if not a record var, 1 if it is.
 */
int
NC_is_recvar(int ncid, int varid, size_t* nrecs)
{
   int status = NC_NOERR;
   int unlimid;
   int ndims;
   int dimset[NC_MAX_VAR_DIMS];

   status = nc_inq_unlimdim(ncid,&unlimid);
   if(status != NC_NOERR) return 0; /* no unlimited defined */
   status = nc_inq_varndims(ncid,varid,&ndims);
   if(status != NC_NOERR) return 0; /* no unlimited defined */
   if(ndims == 0) return 0; /* scalar */
   status = nc_inq_vardimid(ncid,varid,dimset);
   if(status != NC_NOERR) return 0; /* no unlimited defined */
   status = nc_inq_dim(ncid,dimset[0],NULL,nrecs);
   if(status != NC_NOERR) return 0;
   return (dimset[0] == unlimid ? 1: 0);
}
Exemplo n.º 9
0
Arquivo: v2i.c Projeto: stcorp/harp
int
ncdiminq(
    int		ncid,
    int		dimid,
    char*	name,
    long*	length
)
{
	size_t ll;
	const int status = nc_inq_dim(ncid, dimid, name, &ll);

	if(status != NC_NOERR)
	{
		nc_advise("ncdiminq", status, "ncid %d", ncid);
		return -1;
	}
	/* else */
	
	if(length != NULL)
		*length = (int) ll;

	return dimid;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
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;
}
Exemplo n.º 12
0
int ex_copy (int in_exoid, int out_exoid)
{
   int status;
   int ndims;                   /* number of dimensions */
   int nvars;                   /* number of variables */
   int ngatts;                  /* number of global attributes */
   int recdimid;                /* id of unlimited dimension */
   int dimid;                   /* dimension id */
   int dim_out_id;              /* dimension id */
   int varid;                   /* variable id */
   int var_out_id;              /* variable id */
   struct ncvar var;            /* variable */
   struct ncatt att;            /* attribute */
   nc_type att_type = NC_NAT;
   size_t att_len = 0;
   size_t i;
   size_t numrec;
   size_t dim_sz;
   char dim_nm[NC_MAX_NAME];
   int in_large, out_large;
   char errmsg[MAX_ERR_LENGTH];

   exerrval = 0; /* clear error code */

   /*
    * Get exodus_large_model setting on both input and output
    * databases so know how to handle coordinates.
    */
   in_large  = ex_large_model(in_exoid);
   out_large = ex_large_model(out_exoid);
   
   /*
    * get number of dimensions, number of variables, number of global
    * atts, and dimension id of unlimited dimension, if any
    */

   (void)nc_inq(in_exoid, &ndims, &nvars, &ngatts, &recdimid);
   (void)nc_inq_dimlen(in_exoid, recdimid, &numrec);

   /* put output file into define mode */
   (void)nc_redef(out_exoid);

   /* copy global attributes */
   for (i = 0; i < (size_t)ngatts; i++) {

     (void)nc_inq_attname(in_exoid, NC_GLOBAL, i, att.name);
        
     /* if attribute exists in output file, don't overwrite it; compute 
      * word size, I/O word size etc. are global attributes stored when
      * file is created with ex_create;  we don't want to overwrite those
      */
     if ((status = nc_inq_att(out_exoid, NC_GLOBAL, att.name, &att.type, &att.len)) != NC_NOERR) {

        /* The "last_written_time" attribute is a special attribute
           used by the Sierra IO system to determine whether a
           timestep has been fully written to the database in order to
           try to detect a database crash that happens in the middle
           of a database output step. Don't want to copy that attribute.
        */
        if (strcmp(att.name,"last_written_time") != 0) {
          /* attribute doesn't exist in new file so OK to create it */
          nc_copy_att(in_exoid,NC_GLOBAL,att.name,out_exoid,NC_GLOBAL);
        }
      }
   }

   /* copy dimensions */

   /* Get the dimension sizes and names */

   for(dimid = 0; dimid < ndims; dimid++){

     (void)nc_inq_dim(in_exoid,dimid,dim_nm,&dim_sz);

     /* If the dimension isn't one we specifically don't want 
      * to copy (ie, number of QA or INFO records) and it 
      * hasn't been defined, copy it */
     
     if ( ( strcmp(dim_nm,DIM_NUM_QA)        != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_INFO)      != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_NOD_VAR)   != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_EDG_VAR)   != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_FAC_VAR)   != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_ELE_VAR)   != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_NSET_VAR)  != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_ESET_VAR)  != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_FSET_VAR)  != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_SSET_VAR)  != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_ELSET_VAR) != 0) &&
	  ( strcmp(dim_nm,DIM_NUM_GLO_VAR)   != 0) ) {
       
       /* See if the dimension has already been defined */
       status = nc_inq_dimid(out_exoid, dim_nm, &dim_out_id);
       
       if(status != NC_NOERR) {
	 if(dimid != recdimid) {
	   status = nc_def_dim(out_exoid, dim_nm, dim_sz,       &dim_out_id);
	 } else {
	   status = nc_def_dim(out_exoid, dim_nm, NC_UNLIMITED, &dim_out_id);
	 } /* end else */
	 if (status != NC_NOERR) {
	   exerrval = status;
	   sprintf(errmsg,
		   "Error: failed to define %s dimension in file id %d",
		   dim_nm, out_exoid);
	   ex_err("ex_copy",errmsg,exerrval);
	   return (EX_FATAL);
	 }
       } /* end if */
     } /* end if */
   } /* end loop over dim */

   /* DIM_STR_NAME is a newly added dimension required by current API.
    * If it doesn't exist on the source database, we need to add it to
    * the target...
    */
   status = nc_inq_dimid(in_exoid, DIM_STR_NAME, &dim_out_id);
   if (status != NC_NOERR) {
     /* Not found; set to default value of 32+1. */
     if ((status = nc_def_dim(out_exoid, DIM_STR_NAME, 33, &dim_out_id)) != NC_NOERR) {
       exerrval = status;
       sprintf(errmsg,
	       "Error: failed to define string name dimension in file id %d",
	       out_exoid);
       ex_err("ex_copy",errmsg,exerrval);
       return (EX_FATAL);
     }
   }

   status = nc_inq_att(in_exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, &att_type, &att_len);
   if (status != NC_NOERR) {
      int max_so_far = 32;
      nc_put_att_int(out_exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, NC_INT, 1, &max_so_far);
    }

   /* copy variable definitions and variable attributes */
   for (varid = 0; varid < nvars; varid++) {

     (void)nc_inq_var(in_exoid, varid, var.name, &var.type, &var.ndims, 
		 var.dims, &var.natts);

      /* we don't want to copy some variables because there is not a
       * simple way to add to them;
       * QA records, info records and all results variables (nodal
       * element, and global results) are examples
       */

      if ( ( strcmp(var.name,VAR_QA_TITLE)      != 0) &&
           ( strcmp(var.name,VAR_INFO)          != 0) &&
           ( strcmp(var.name,VAR_EBLK_TAB)      != 0) &&
           ( strcmp(var.name,VAR_FBLK_TAB)      != 0) &&
           ( strcmp(var.name,VAR_ELEM_TAB)      != 0) &&
           ( strcmp(var.name,VAR_ELSET_TAB)     != 0) &&
           ( strcmp(var.name,VAR_SSET_TAB)      != 0) &&
           ( strcmp(var.name,VAR_FSET_TAB)      != 0) &&
           ( strcmp(var.name,VAR_ESET_TAB)      != 0) &&
           ( strcmp(var.name,VAR_NSET_TAB)      != 0) &&
           ( strcmp(var.name,VAR_NAME_GLO_VAR)  != 0) &&
           ( strcmp(var.name,VAR_GLO_VAR)       != 0) &&
           ( strcmp(var.name,VAR_NAME_NOD_VAR)  != 0) &&
           ( strcmp(var.name,VAR_NOD_VAR)       != 0) &&
           ( strcmp(var.name,VAR_NAME_EDG_VAR)  != 0) &&
           ( strcmp(var.name,VAR_NAME_FAC_VAR)  != 0) &&
           ( strcmp(var.name,VAR_NAME_ELE_VAR)  != 0) &&
           ( strcmp(var.name,VAR_NAME_NSET_VAR) != 0) &&
           ( strcmp(var.name,VAR_NAME_ESET_VAR) != 0) &&
           ( strcmp(var.name,VAR_NAME_FSET_VAR) != 0) &&
           ( strcmp(var.name,VAR_NAME_SSET_VAR) != 0) &&
           ( strcmp(var.name,VAR_NAME_ELSET_VAR) != 0)&&
           ( strncmp(var.name,"vals_elset_var", 14) != 0) &&
           ( strncmp(var.name,"vals_sset_var",  13) != 0) &&
           ( strncmp(var.name,"vals_fset_var",  13) != 0) &&
           ( strncmp(var.name,"vals_eset_var",  13) != 0) &&
           ( strncmp(var.name,"vals_nset_var",  13) != 0) &&
           ( strncmp(var.name,"vals_nod_var",   12) != 0) &&
           ( strncmp(var.name,"vals_edge_var",  13) != 0) &&
           ( strncmp(var.name,"vals_face_var",  13) != 0) &&
           ( strncmp(var.name,"vals_elem_var",  13) != 0) ) {

        if (strncmp(var.name,VAR_COORD,5) == 0) {
          var_out_id = cpy_coord_def (in_exoid, out_exoid, recdimid, var.name,
                                      in_large, out_large);
        } else {
          var_out_id = cpy_var_def (in_exoid, out_exoid, recdimid, var.name);
        }

         /* copy the variable's attributes */
         (void) cpy_att (in_exoid, out_exoid, varid, var_out_id);

      }
   }

   /* take the output file out of define mode */
   if ((exerrval=nc_enddef (out_exoid)) != NC_NOERR) {
     sprintf(errmsg,
	     "Error: failed to complete definition in file id %d", 
	     out_exoid);
     ex_err("ex_copy",errmsg,exerrval);
     return (EX_FATAL);
   }

   /* output variable data */

   for (varid = 0; varid < nvars; varid++) {
     (void)nc_inq_var(in_exoid, varid, var.name, &var.type, &var.ndims,
		 var.dims, &var.natts);

      /* we don't want to copy some variable values;
       * QA records and info records shouldn't be copied because there
       * isn't an easy way to add to them;
       * the time value array ("time_whole") and any results variables
       * (nodal, elemental, or global) shouldn't be copied 
       */

      if ( ( strcmp(var.name,VAR_QA_TITLE) != 0)        &&
           ( strcmp(var.name,VAR_INFO) != 0)            &&
           ( strcmp(var.name,VAR_EBLK_TAB) != 0)        &&
           ( strcmp(var.name,VAR_FBLK_TAB) != 0)        &&
           ( strcmp(var.name,VAR_ELEM_TAB) != 0)        &&
           ( strcmp(var.name,VAR_ELSET_TAB) != 0)       &&
           ( strcmp(var.name,VAR_SSET_TAB) != 0)        &&
           ( strcmp(var.name,VAR_FSET_TAB) != 0)        &&
           ( strcmp(var.name,VAR_ESET_TAB) != 0)        &&
           ( strcmp(var.name,VAR_NSET_TAB) != 0)        &&
           ( strcmp(var.name,VAR_NAME_GLO_VAR) != 0)    &&
           ( strcmp(var.name,VAR_GLO_VAR) != 0)         &&
           ( strcmp(var.name,VAR_NAME_NOD_VAR) != 0)    &&
           ( strcmp(var.name,VAR_NOD_VAR) != 0)         &&
           ( strcmp(var.name,VAR_NAME_EDG_VAR) != 0)    &&
           ( strcmp(var.name,VAR_NAME_FAC_VAR) != 0)    &&
           ( strcmp(var.name,VAR_NAME_ELE_VAR) != 0)    &&
           ( strcmp(var.name,VAR_NAME_NSET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_ESET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_FSET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_SSET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_ELSET_VAR) != 0)  &&
           ( strncmp(var.name,"vals_elset_var", 14) != 0)&&
           ( strncmp(var.name,"vals_sset_var", 13) != 0)&&
           ( strncmp(var.name,"vals_fset_var", 13) != 0)&&
           ( strncmp(var.name,"vals_eset_var", 13) != 0)&&
           ( strncmp(var.name,"vals_nset_var", 13) != 0)&&
           ( strncmp(var.name,"vals_nod_var", 12) != 0) &&
           ( strncmp(var.name,"vals_edge_var",13) != 0) &&
           ( strncmp(var.name,"vals_face_var",13) != 0) &&
           ( strncmp(var.name,"vals_elem_var",13) != 0) &&
           ( strcmp(var.name,VAR_WHOLE_TIME) != 0) ) {

        if (strncmp(var.name,VAR_COORD,5) == 0) {
          (void) cpy_coord_val (in_exoid, out_exoid, var.name,
                                in_large, out_large);
        } else {
          (void) cpy_var_val (in_exoid, out_exoid, var.name);
        }

      }
   }

   /* ensure internal data structures are updated */

   /* if number of blocks > 0 */
   update_internal_structs( out_exoid, EX_INQ_EDGE_BLK, ex_get_counter_list(EX_EDGE_BLOCK));
   update_internal_structs( out_exoid, EX_INQ_FACE_BLK, ex_get_counter_list(EX_FACE_BLOCK));
   update_internal_structs( out_exoid, EX_INQ_ELEM_BLK, ex_get_counter_list(EX_ELEM_BLOCK));

   /* if number of sets > 0 */
   update_internal_structs( out_exoid, EX_INQ_NODE_SETS, ex_get_counter_list(EX_NODE_SET));
   update_internal_structs( out_exoid, EX_INQ_EDGE_SETS, ex_get_counter_list(EX_EDGE_SET));
   update_internal_structs( out_exoid, EX_INQ_FACE_SETS, ex_get_counter_list(EX_FACE_SET));
   update_internal_structs( out_exoid, EX_INQ_SIDE_SETS, ex_get_counter_list(EX_SIDE_SET));
   update_internal_structs( out_exoid, EX_INQ_ELEM_SETS, ex_get_counter_list(EX_ELEM_SET));

   /* if number of maps > 0 */
   update_internal_structs( out_exoid, EX_INQ_NODE_MAP, ex_get_counter_list(EX_NODE_MAP));
   update_internal_structs( out_exoid, EX_INQ_EDGE_MAP, ex_get_counter_list(EX_EDGE_MAP));
   update_internal_structs( out_exoid, EX_INQ_FACE_MAP, ex_get_counter_list(EX_FACE_MAP));
   update_internal_structs( out_exoid, EX_INQ_ELEM_MAP, ex_get_counter_list(EX_ELEM_MAP));

   return(EX_NOERR);
}
Exemplo n.º 13
0
OSErr NetCDFWindMoverCurv::TextRead(char *path, TMap **newMap, char *topFilePath) // don't want a map  
{
	// this code is for curvilinear grids
	OSErr err = 0;
	long i,j, numScanned, indexOfStart = 0;
	int status, ncid, latIndexid, lonIndexid, latid, lonid, recid, timeid, numdims;
	size_t latLength, lonLength, recs, t_len, t_len2;
	float timeVal;
	char recname[NC_MAX_NAME], *timeUnits=0, month[10];	
	char dimname[NC_MAX_NAME], s[256], topPath[256];
	WORLDPOINTFH vertexPtsH=0;
	float *lat_vals=0,*lon_vals=0,yearShift=0.;
	static size_t timeIndex,ptIndex[2]={0,0};
	static size_t pt_count[2];
	Seconds startTime, startTime2;
	double timeConversion = 1.;
	char errmsg[256] = "",className[256]="";
	char fileName[64],*modelTypeStr=0;
	Point where;
	OSType typeList[] = { 'NULL', 'NULL', 'NULL', 'NULL' };
	MySFReply reply;
	Boolean bTopFile = false, fIsNavy = false;	// for now keep code around but probably don't need Navy curvilinear wind
	//VelocityFH velocityH = 0;
	char outPath[256];
	
	if (!path || !path[0]) return 0;
	strcpy(fPathName,path);
	
	strcpy(s,path);
	SplitPathFile (s, fileName);
	strcpy(fFileName, fileName); // maybe use a name from the file
	status = nc_open(path, NC_NOWRITE, &ncid);
	//if (status != NC_NOERR) {err = -1; goto done;}
	if (status != NC_NOERR) 
	{
#if TARGET_API_MAC_CARBON
		err = ConvertTraditionalPathToUnixPath((const char *) path, outPath, kMaxNameLen) ;
		status = nc_open(outPath, NC_NOWRITE, &ncid);
#endif
		if (status != NC_NOERR) {err = -1; goto done;}
	}
	// check number of dimensions - 2D or 3D
	status = nc_inq_ndims(ncid, &numdims);
	if (status != NC_NOERR) {err = -1; goto done;}
	
	status = nc_inq_attlen(ncid,NC_GLOBAL,"generating_model",&t_len2);
	if (status != NC_NOERR) {fIsNavy = false; /*goto done;*/}	
	else 
	{
		fIsNavy = true;
		// may only need to see keyword is there, since already checked grid type
		modelTypeStr = new char[t_len2+1];
		status = nc_get_att_text(ncid, NC_GLOBAL, "generating_model", modelTypeStr);
		if (status != NC_NOERR) {fIsNavy = false; goto done;}	
		modelTypeStr[t_len2] = '\0';
		
		strcpy(fFileName, modelTypeStr); 
	}
	GetClassName(className);
	if (!strcmp("NetCDF Wind",className))
		SetClassName(fFileName); //first check that name is now the default and not set by command file ("NetCDF Wind")
	
	//if (fIsNavy)
	{
		status = nc_inq_dimid(ncid, "time", &recid); //Navy
		//if (status != NC_NOERR) {err = -1; goto done;}
		if (status != NC_NOERR) 
		{	status = nc_inq_unlimdim(ncid, &recid);	// issue of time not being unlimited dimension
			if (status != NC_NOERR) {err = -1; goto done;}
		}			
	}
	/*else
	 {
	 status = nc_inq_unlimdim(ncid, &recid);	// issue of time not being unlimited dimension
	 if (status != NC_NOERR) {err = -1; goto done;}
	 }*/
	
	//if (fIsNavy)
	status = nc_inq_varid(ncid, "time", &timeid); 
	if (status != NC_NOERR) 
	{	
		status = nc_inq_varid(ncid, "ProjectionHr", &timeid); 
		if (status != NC_NOERR) {err = -1; goto done;}
	}			
	//	if (status != NC_NOERR) {/*err = -1; goto done;*/timeid=recid;} 
	
	//if (!fIsNavy)
	//status = nc_inq_attlen(ncid, recid, "units", &t_len);	// recid is the dimension id not the variable id
	//else	// LAS has them in order, and time is unlimited, but variable/dimension names keep changing so leave this way for now
	status = nc_inq_attlen(ncid, timeid, "units", &t_len);
	if (status != NC_NOERR) 
	{
		timeUnits = 0;	// files should always have this info
		timeConversion = 3600.;		// default is hours
		startTime2 = model->GetStartTime();	// default to model start time
		//err = -1; goto done;
	}
	else
	{
		DateTimeRec time;
		char unitStr[24], junk[10];
		
		timeUnits = new char[t_len+1];
		//if (!fIsNavy)
		//status = nc_get_att_text(ncid, recid, "units", timeUnits);	// recid is the dimension id not the variable id
		//else
		status = nc_get_att_text(ncid, timeid, "units", timeUnits);
		if (status != NC_NOERR) {err = -1; goto done;} 
		timeUnits[t_len] = '\0'; // moved this statement before StringSubstitute, JLM 5/2/10
		StringSubstitute(timeUnits, ':', ' ');
		StringSubstitute(timeUnits, '-', ' ');
		StringSubstitute(timeUnits, 'T', ' ');
		StringSubstitute(timeUnits, 'Z', ' ');
		
		numScanned=sscanf(timeUnits, "%s %s %hd %hd %hd %hd %hd %hd",
						  unitStr, junk, &time.year, &time.month, &time.day,
						  &time.hour, &time.minute, &time.second) ;
		if (numScanned==5)	
		{time.hour = 0; time.minute = 0; time.second = 0; }
		else if (numScanned==7) // has two extra time entries ??	
			time.second = 0;
		else if (numScanned<8)	
		//else if (numScanned!=8)	
		{ 
			//timeUnits = 0;	// files should always have this info
			//timeConversion = 3600.;		// default is hours
			//startTime2 = model->GetStartTime();	// default to model start time
			err = -1; TechError("NetCDFWindMoverCurv::TextRead()", "sscanf() == 8", 0); goto done;
		}
		else
		{
			// code goes here, trouble with the DAYS since 1900 format, since converts to seconds since 1904
			if (time.year ==1900) {time.year += 40; time.day += 1; /*for the 1900 non-leap yr issue*/ yearShift = 40.;}
			DateToSeconds (&time, &startTime2);	// code goes here, which start Time to use ??
			if (!strcmpnocase(unitStr,"HOURS") || !strcmpnocase(unitStr,"HOUR"))
				timeConversion = 3600.;
			else if (!strcmpnocase(unitStr,"MINUTES") || !strcmpnocase(unitStr,"MINUTE"))
				timeConversion = 60.;
			else if (!strcmpnocase(unitStr,"SECONDS") || !strcmpnocase(unitStr,"SECOND"))
				timeConversion = 1.;
			else if (!strcmpnocase(unitStr,"DAYS") || !strcmpnocase(unitStr,"DAY"))
				timeConversion = 24.*3600.;
		}
	} 
	
	if (fIsNavy)
	{
		status = nc_inq_dimid(ncid, "gridy", &latIndexid); //Navy
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_dimlen(ncid, latIndexid, &latLength);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_dimid(ncid, "gridx", &lonIndexid);	//Navy
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_dimlen(ncid, lonIndexid, &lonLength);
		if (status != NC_NOERR) {err = -1; goto done;}
		// option to use index values?
		status = nc_inq_varid(ncid, "grid_lat", &latid);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_varid(ncid, "grid_lon", &lonid);
		if (status != NC_NOERR) {err = -1; goto done;}
	}
	else
	{
		for (i=0;i<numdims;i++)
		{
			if (i == recid) continue;
			status = nc_inq_dimname(ncid,i,dimname);
			if (status != NC_NOERR) {err = -1; goto done;}
			if (!strncmpnocase(dimname,"X",1) || !strncmpnocase(dimname,"LON",3) || !strncmpnocase(dimname,"nx",2))
			{
				lonIndexid = i;
			}
			if (!strncmpnocase(dimname,"Y",1) || !strncmpnocase(dimname,"LAT",3) || !strncmpnocase(dimname,"ny",2))
			{
				latIndexid = i;
			}
		}
		
		status = nc_inq_dimlen(ncid, latIndexid, &latLength);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_dimlen(ncid, lonIndexid, &lonLength);
		if (status != NC_NOERR) {err = -1; goto done;}
		
		status = nc_inq_varid(ncid, "LATITUDE", &latid);
		if (status != NC_NOERR) 
		{
			status = nc_inq_varid(ncid, "lat", &latid);
			if (status != NC_NOERR) 
			{
				status = nc_inq_varid(ncid, "latitude", &latid);
				if (status != NC_NOERR) {err = -1; goto done;}
			}
		}
		status = nc_inq_varid(ncid, "LONGITUDE", &lonid);
		if (status != NC_NOERR) 
		{
			status = nc_inq_varid(ncid, "lon", &lonid);
			if (status != NC_NOERR) 
			{
				status = nc_inq_varid(ncid, "longitude", &lonid);
				if (status != NC_NOERR) {err = -1; goto done;}
			}
		}
	}
	
	pt_count[0] = latLength;
	pt_count[1] = lonLength;
	vertexPtsH = (WorldPointF**)_NewHandleClear(latLength*lonLength*sizeof(WorldPointF));
	if (!vertexPtsH) {err = memFullErr; goto done;}
	lat_vals = new float[latLength*lonLength]; 
	lon_vals = new float[latLength*lonLength]; 
	if (!lat_vals || !lon_vals) {err = memFullErr; goto done;}
	status = nc_get_vara_float(ncid, latid, ptIndex, pt_count, lat_vals);
	if (status != NC_NOERR) {err = -1; goto done;}
	status = nc_get_vara_float(ncid, lonid, ptIndex, pt_count, lon_vals);
	if (status != NC_NOERR) {err = -1; goto done;}
	for (i=0;i<latLength;i++)
	{
		for (j=0;j<lonLength;j++)
		{
			//if (lat_vals[(latLength-i-1)*lonLength+j]==fill_value)	// this would be an error
			//lat_vals[(latLength-i-1)*lonLength+j]=0.;
			//if (lon_vals[(latLength-i-1)*lonLength+j]==fill_value)
			//lon_vals[(latLength-i-1)*lonLength+j]=0.;
			INDEXH(vertexPtsH,i*lonLength+j).pLat = lat_vals[(latLength-i-1)*lonLength+j];	
			INDEXH(vertexPtsH,i*lonLength+j).pLong = lon_vals[(latLength-i-1)*lonLength+j];
		}
	}
	fVertexPtsH	 = vertexPtsH;
	
	status = nc_inq_dim(ncid, recid, recname, &recs);
	if (status != NC_NOERR) {err = -1; goto done;}
	if (recs<=0) {strcpy(errmsg,"No times in file. Error opening NetCDF wind file"); err =  -1; goto done;}
	
	fTimeHdl = (Seconds**)_NewHandleClear(recs*sizeof(Seconds));
	if (!fTimeHdl) {err = memFullErr; goto done;}
	for (i=0;i<recs;i++)
	{
		Seconds newTime;
		// possible units are, HOURS, MINUTES, SECONDS,...
		timeIndex = i;
		//if (!fIsNavy)
		//status = nc_get_var1_float(ncid, recid, &timeIndex, &timeVal);	// recid is the dimension id not the variable id
		//else
		status = nc_get_var1_float(ncid, timeid, &timeIndex, &timeVal);
		if (status != NC_NOERR) {err = -1; goto done;}
		newTime = RoundDateSeconds(round(startTime2+timeVal*timeConversion));
		//INDEXH(fTimeHdl,i) = startTime2+(long)(timeVal*timeConversion -yearShift*3600.*24.*365.25);	// which start time where?
		//if (i==0) startTime = startTime2+(long)(timeVal*timeConversion -yearShift*3600.*24.*365.25);
		INDEXH(fTimeHdl,i) = newTime-yearShift*3600.*24.*365.25;	// which start time where?
		if (i==0) startTime = newTime-yearShift*3600.*24.*365.25;
	}
	if (model->GetStartTime() != startTime || model->GetModelTime()!=model->GetStartTime())
	{
		if (true)	// maybe use NOAA.ver here?
		{
			short buttonSelected;
			//buttonSelected  = MULTICHOICEALERT(1688,"Do you want to reset the model start time to the first time in the file?",FALSE);
			if(!gCommandFileRun)	// also may want to skip for location files...
				buttonSelected  = MULTICHOICEALERT(1688,"Do you want to reset the model start time to the first time in the file?",FALSE);
			else buttonSelected = 1;	// TAP user doesn't want to see any dialogs, always reset (or maybe never reset? or send message to errorlog?)
			switch(buttonSelected){
				case 1: // reset model start time
					//bTopFile = true;
					model->SetModelTime(startTime);
					model->SetStartTime(startTime);
					model->NewDirtNotification(DIRTY_RUNBAR); // must reset the runbar
					break;  
				case 3: // don't reset model start time
					//bTopFile = false;
					break;
				case 4: // cancel
					err=-1;// user cancel
					goto done;
			}
		}
		//model->SetModelTime(startTime);
		//model->SetStartTime(startTime);
		//model->NewDirtNotification(DIRTY_RUNBAR); // must reset the runbar
	}
	
	fNumRows = latLength;
	fNumCols = lonLength;
	
	status = nc_close(ncid);
	if (status != NC_NOERR) {err = -1; goto done;}
	
	//err = this -> SetInterval(errmsg);
	//if(err) goto done;
	
	// look for topology in the file
	// for now ask for an ascii file, output from Topology save option
	// need dialog to ask for file
	//if (fIsNavy)	// for now don't allow for wind files
	{if (topFilePath[0]) {err = ReadTopology(topFilePath,newMap); goto done;}}
	if (!gCommandFileRun)
	{
		short buttonSelected;
		buttonSelected  = MULTICHOICEALERT(1688,"Do you have an extended topology file to load?",FALSE);
		switch(buttonSelected){
			case 1: // there is an extended top file
				bTopFile = true;
				break;  
			case 3: // no extended top file
				bTopFile = false;
				break;
			case 4: // cancel
				err=-1;// stay at this dialog
				goto done;
		}
	}
	if(bTopFile)
	{
#if TARGET_API_MAC_CARBON
		mysfpgetfile(&where, "", -1, typeList,
					 (MyDlgHookUPP)0, &reply, M38c, MakeModalFilterUPP(STDFilter));
		if (!reply.good)/* return USERCANCEL;*/
		{
			/*if (recs>0)
				err = this -> ReadTimeData(indexOfStart,&velocityH,errmsg);
			else {strcpy(errmsg,"No times in file. Error opening NetCDF file"); err =  -1;}
			if(err) goto done;*/
			err = dynamic_cast<NetCDFWindMoverCurv *>(this)->ReorderPoints(newMap,errmsg);	
			//err = ReorderPoints(fStartData.dataHdl,newMap,errmsg);	// if u, v input separately only do this once?
	 		goto done;
		}
		else
			strcpy(topPath, reply.fullPath);
		
#else
		where = CenteredDialogUpLeft(M38c);
		sfpgetfile(&where, "",
				   (FileFilterUPP)0,
				   -1, typeList,
				   (DlgHookUPP)0,
				   &reply, M38c,
				   (ModalFilterUPP)MakeUPP((ProcPtr)STDFilter, uppModalFilterProcInfo));
		if (!reply.good) 
		{
			/*if (recs>0)
				err = this -> ReadTimeData(indexOfStart,&velocityH,errmsg);
			else {strcpy(errmsg,"No times in file. Error opening NetCDF file"); err =  -1;}
			if(err) goto done;*/
			err = dynamic_cast<NetCDFWindMoverCurv *>(this)->ReorderPoints(newMap,errmsg);	
			//err = ReorderPoints(fStartData.dataHdl,newMap,errmsg);	
	 		/*if (err)*/ goto done;
		}
		
		my_p2cstr(reply.fName);
		
#ifdef MAC
		GetFullPath(reply.vRefNum, 0, (char *)reply.fName, topPath);
#else
		strcpy(topPath, reply.fName);
#endif
#endif		
		strcpy (s, topPath);
		err = ReadTopology(topPath,newMap);	
		goto done;
	}
	
	/*if (recs>0)
		err = this -> ReadTimeData(indexOfStart,&velocityH,errmsg);
	else {strcpy(errmsg,"No times in file. Error opening NetCDF wind file"); err =  -1;}
	if(err) goto done;*/
	err = dynamic_cast<NetCDFWindMoverCurv *>(this)->ReorderPoints(newMap,errmsg);	
	//err = ReorderPoints(fStartData.dataHdl,newMap,errmsg);	
	
done:
	if (err)
	{
		printNote("Error opening NetCDF wind file");
		if(fGrid)
		{
			fGrid ->Dispose();
			delete fGrid;
			fGrid = 0;
		}
		if(vertexPtsH) {DisposeHandle((Handle)vertexPtsH); vertexPtsH = 0;	fVertexPtsH	 = 0;}
	}
	
	if (timeUnits) delete [] timeUnits;
	if (lat_vals) delete [] lat_vals;
	if (lon_vals) delete [] lon_vals;
	if (modelTypeStr) delete [] modelTypeStr;
	//if (velocityH) {DisposeHandle((Handle)velocityH); velocityH = 0;}
	return err;
}
Exemplo n.º 14
0
int
test_redef(int format)   
{
   int ncid, varid, dimids[REDEF_NDIMS], dimids_in[REDEF_NDIMS];
   int ndims, nvars, natts, unlimdimid;
   int dimids_var[REDEF_NDIMS], var_type;
   int cflags = 0;
   size_t dim_len;
   char dim_name[NC_MAX_NAME+1], var_name[NC_MAX_NAME+1];
   float float_in;
   double double_out = 99E99;
   int int_in;
   unsigned char uchar_in, uchar_out = 255;
   short short_out = -999;
   nc_type xtype_in;
   size_t cache_size_in, cache_nelems_in;
   float cache_preemption_in;
   int ret;

   if (format == NC_FORMAT_64BIT)
      cflags |= NC_64BIT_OFFSET;
   else if (format == NC_FORMAT_NETCDF4_CLASSIC)
      cflags |= (NC_NETCDF4|NC_CLASSIC_MODEL);
   else if (format == NC_FORMAT_NETCDF4)
      cflags |= NC_NETCDF4;

   /* Change chunk cache. */
   if (nc_set_chunk_cache(NEW_CACHE_SIZE, NEW_CACHE_NELEMS, 
			  NEW_CACHE_PREEMPTION)) ERR;

   /* Create a file with two dims, two vars, and two atts. */
   if (nc_create(FILE_NAME, cflags|NC_CLOBBER, &ncid)) ERR;

   /* Retrieve the chunk cache settings, just for fun. */
   if (nc_get_chunk_cache(&cache_size_in, &cache_nelems_in, 
			  &cache_preemption_in)) ERR;
   if (cache_size_in != NEW_CACHE_SIZE || cache_nelems_in != NEW_CACHE_NELEMS ||
       cache_preemption_in != NEW_CACHE_PREEMPTION) ERR;

   /* This will fail, except for netcdf-4/hdf5, which permits any
    * name. */
   if (format != NC_FORMAT_NETCDF4)
      if ((ret = nc_def_dim(ncid, REDEF_NAME_ILLEGAL, REDEF_DIM2_LEN, 
			    &dimids[1])) != NC_EBADNAME) ERR;

   if (nc_def_dim(ncid, REDEF_DIM1_NAME, REDEF_DIM1_LEN, &dimids[0])) ERR;
   if (nc_def_dim(ncid, REDEF_DIM2_NAME, REDEF_DIM2_LEN, &dimids[1])) ERR;
   if (nc_def_var(ncid, REDEF_VAR1_NAME, NC_INT, REDEF_NDIMS, dimids, &varid)) ERR;
   if (nc_def_var(ncid, REDEF_VAR2_NAME, NC_BYTE, REDEF_NDIMS, dimids, &varid)) ERR;
   if (nc_put_att_double(ncid, NC_GLOBAL, REDEF_ATT1_NAME, NC_DOUBLE, 1, &double_out)) ERR;
   if (nc_put_att_short(ncid, NC_GLOBAL, REDEF_ATT2_NAME, NC_SHORT, 1, &short_out)) ERR;

   /* Check it out. */
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
   if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;

   /* Close it up. */
   if (format != NC_FORMAT_NETCDF4)
      if (nc_enddef(ncid)) ERR;
   if (nc_close(ncid)) ERR;

   /* Reopen as read only - make sure it doesn't let us change file. */
   if (nc_open(FILE_NAME, 0, &ncid)) ERR;
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
   if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;

   /* This will fail. */
   ret = nc_def_var(ncid, REDEF_VAR3_NAME, NC_UBYTE, REDEF_NDIMS, 
			  dimids, &varid);
   if(format == NC_FORMAT_NETCDF4) {
	if(ret != NC_EPERM) {
	    ERR;
	}
   } else {
	if(ret != NC_ENOTINDEFINE) {
	    ERR;
	}
   }
   /* This will fail. */
   if (!nc_put_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, NC_CHAR, 1, &uchar_out)) ERR;
   if (nc_close(ncid)) ERR;      

   /* Make sure we can't redef a file opened for NOWRITE. */
   if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
   if (nc_redef(ncid) != NC_EPERM) ERR;

   /* Check it out again. */
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
   if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;

   if (nc_close(ncid)) ERR;      

   /* Reopen the file and check it, add a variable and attribute. */
   if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;

   /* Check it out. */
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;

   /* Add var. */
   if ((format != NC_FORMAT_NETCDF4) && nc_redef(ncid)) ERR;
   if (nc_def_var(ncid, REDEF_VAR3_NAME, NC_BYTE, REDEF_NDIMS, dimids, &varid)) ERR;

   /* Add att. */
   ret = nc_put_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, NC_BYTE, 1, &uchar_out);
   if (format != NC_FORMAT_NETCDF4 && ret) ERR;
   else if (format == NC_FORMAT_NETCDF4 && ret != NC_ERANGE) ERR;

   /* Check it out. */
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 3 || natts != 3 || unlimdimid != -1) ERR;
   if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 2, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
   if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR3_NAME) || var_type != NC_BYTE ||
       natts != 0) ERR;

   if (nc_close(ncid)) ERR;      

   /* Reopen it and check each dim, var, and att. */
   if (nc_open(FILE_NAME, 0, &ncid)) ERR;
   if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
   if (dim_len != REDEF_DIM1_LEN || strcmp(dim_name, REDEF_DIM1_NAME)) ERR;
   if (nc_inq_dim(ncid, 1, dim_name, &dim_len)) ERR;
   if (dim_len != REDEF_DIM2_LEN || strcmp(dim_name, REDEF_DIM2_NAME)) ERR;
   if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
   if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR1_NAME) || var_type != NC_INT ||
       natts != 0) ERR;
   if (nc_inq_var(ncid, 1, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
   if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR2_NAME) || var_type != NC_BYTE ||
       natts != 0) ERR;
   if (nc_inq_var(ncid, 2, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
   if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR3_NAME) || var_type != NC_BYTE ||
       natts != 0) ERR;
   if (nc_get_att_float(ncid, NC_GLOBAL, REDEF_ATT1_NAME, &float_in) != NC_ERANGE) ERR;
   if (nc_get_att_int(ncid, NC_GLOBAL, REDEF_ATT2_NAME, &int_in)) ERR;
   if (int_in != short_out) ERR;
   ret = nc_get_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, &uchar_in);
   if (format == NC_FORMAT_NETCDF4)
   {
      if (ret != NC_ERANGE) ERR;
   }
   else if (ret) ERR;
	 
   if (uchar_in != uchar_out) ERR;
   if (nc_close(ncid)) ERR;      
   return NC_NOERR;
}
Exemplo n.º 15
0
/*! \internal */
int cpy_var_def(int in_id,int out_id,int rec_dim_id,char *var_nm)
/*
   int in_id: input netCDF input-file ID
   int out_id: input netCDF output-file ID
   int rec_dim_id: input input-file record dimension ID
   char *var_nm: input variable name
   int cpy_var_def(): output output-file variable ID
 */
{
  /* Routine to copy the variable metadata from an input netCDF file
   * to an output netCDF file. 
   */

  int status;
  int *dim_in_id;
  int *dim_out_id;
  int idx;
  int nbr_dim;
  int var_in_id;
  int var_out_id;

  nc_type var_type;

  /* See if the requested variable is already in the output file. */
  status = nc_inq_varid(out_id, var_nm, &var_out_id);
  if(status == NC_NOERR)
    return var_out_id;

  /* See if the requested variable is in the input file. */
  (void)nc_inq_varid(in_id, var_nm, &var_in_id);

  /* Get the type of the variable and the number of dimensions. */
  (void)nc_inq_vartype (in_id, var_in_id, &var_type);
  (void)nc_inq_varndims(in_id, var_in_id, &nbr_dim);

  /* Recall:
     1. The dimensions must be defined before the variable.
     2. The variable must be defined before the attributes. */

  /* Allocate space to hold the dimension IDs */
  dim_in_id=malloc(nbr_dim*sizeof(int)); 
  dim_out_id=malloc(nbr_dim*sizeof(int));

  /* Get the dimension IDs */
  (void)nc_inq_vardimid(in_id, var_in_id, dim_in_id);

  /* Get the dimension sizes and names */
  for(idx=0;idx<nbr_dim;idx++){
    char dim_nm[NC_MAX_NAME];
    size_t dim_sz;

    (void)nc_inq_dim(in_id, dim_in_id[idx], dim_nm, &dim_sz);

    /* See if the dimension has already been defined */
    status = nc_inq_dimid(out_id, dim_nm, &dim_out_id[idx]);

    /* If the dimension hasn't been defined, copy it */
    if (status != NC_NOERR) {
      if (dim_in_id[idx] != rec_dim_id) {
        (void)nc_def_dim(out_id, dim_nm, dim_sz, &dim_out_id[idx]);
      } else {
        (void)nc_def_dim(out_id, dim_nm, NC_UNLIMITED, &dim_out_id[idx]);
      } 
    } 
  } 

  /* Define the variable in the output file */

  /* If variable is float or double, define it according to the EXODUS
     file's IO_word_size */

  if ((var_type == NC_FLOAT) || (var_type == NC_DOUBLE)) {
    (void)nc_def_var(out_id, var_nm, nc_flt_code(out_id), nbr_dim, dim_out_id, &var_out_id);
    ex_compress_variable(out_id, var_out_id, 2);
  } else {
    (void)nc_def_var(out_id, var_nm, var_type,            nbr_dim, dim_out_id, &var_out_id);
    ex_compress_variable(out_id, var_out_id, 1);
  }

  /* Free the space holding the dimension IDs */
  (void)free(dim_in_id);
  (void)free(dim_out_id);

  return var_out_id;
} /* end cpy_var_def() */
Exemplo n.º 16
0
static void
do_ncdump(const char *path, struct fspec* specp)
{
    int ndims;			/* number of dimensions */
    int nvars;			/* number of variables */
    int ngatts;			/* number of global attributes */
    int xdimid;			/* id of unlimited dimension */
    int dimid;			/* dimension id */
    int varid;			/* variable id */
    struct ncdim dims[NC_MAX_DIMS]; /* dimensions */
    size_t vdims[NC_MAX_DIMS];	/* dimension sizes for a single variable */
    struct ncvar var;		/* variable */
    struct ncatt att;		/* attribute */
    int id;			/* dimension number per variable */
    int ia;			/* attribute number */
    int iv;			/* variable number */
    int is_coord;		/* true if variable is a coordinate variable */
    int ncid;			/* netCDF id */
    vnode* vlist = 0;		/* list for vars specified with -v option */
    int nc_status;		/* return from netcdf calls */

    nc_status = nc_open(path, NC_NOWRITE, &ncid);
    if (nc_status != NC_NOERR) {
	error("%s: %s", path, nc_strerror(nc_status));
    }
    /*
     * If any vars were specified with -v option, get list of associated
     * variable ids
     */
    if (specp->nlvars > 0) {
	vlist = newvlist();	/* list for vars specified with -v option */
	for (iv=0; iv < specp->nlvars; iv++) {
	    NC_CHECK( nc_inq_varid(ncid, specp->lvars[iv], &varid) );
	    varadd(vlist, varid);
	}
    }

    /* if name not specified, derive it from path */
    if (specp->name == (char *)0) {
	specp->name = name_path (path);
    }

    Printf ("netcdf %s {\n", specp->name);
    /*
     * get number of dimensions, number of variables, number of global
     * atts, and dimension id of unlimited dimension, if any
     */
    NC_CHECK( nc_inq(ncid, &ndims, &nvars, &ngatts, &xdimid) );
    /* get dimension info */
    if (ndims > 0)
      Printf ("dimensions:\n");
    for (dimid = 0; dimid < ndims; dimid++) {
	NC_CHECK( nc_inq_dim(ncid, dimid, dims[dimid].name, &dims[dimid].size) );
	if (dimid == xdimid)
	  Printf ("\t%s = %s ; // (%ld currently)\n",dims[dimid].name,
		  "UNLIMITED", (long)dims[dimid].size);
	else
	  Printf ("\t%s = %ld ;\n", dims[dimid].name, (long)dims[dimid].size);
    }

    if (nvars > 0)
	Printf ("variables:\n");
    /* get variable info, with variable attributes */
    for (varid = 0; varid < nvars; varid++) {
	NC_CHECK( nc_inq_var(ncid, varid, var.name, &var.type, &var.ndims,
			     var.dims, &var.natts) );
	Printf ("\t%s %s", type_name(var.type), var.name);
	if (var.ndims > 0)
	  Printf ("(");
	for (id = 0; id < var.ndims; id++) {
	    Printf ("%s%s",
		    dims[var.dims[id]].name,
		    id < var.ndims-1 ? ", " : ")");
	}
	Printf (" ;\n");

	/* get variable attributes */
	for (ia = 0; ia < var.natts; ia++)
	    pr_att(ncid, varid, var.name, ia); /* print ia-th attribute */
    }


    /* get global attributes */
    if (ngatts > 0)
      Printf ("\n// global attributes:\n");
    for (ia = 0; ia < ngatts; ia++)
	pr_att(ncid, NC_GLOBAL, "", ia); /* print ia-th global attribute */
    
    if (! specp->header_only) {
	if (nvars > 0) {
	    Printf ("data:\n");
	}
	/* output variable data */
	for (varid = 0; varid < nvars; varid++) {
	    /* if var list specified, test for membership */
	    if (specp->nlvars > 0 && ! varmember(vlist, varid))
	      continue;
	    NC_CHECK( nc_inq_var(ncid, varid, var.name, &var.type, &var.ndims,
			    var.dims, &var.natts) );
	    if (specp->coord_vals) {
		/* Find out if this is a coordinate variable */
		is_coord = 0;
		for (dimid = 0; dimid < ndims; dimid++) {
		    if (strcmp(dims[dimid].name, var.name) == 0 &&
			var.ndims == 1) {
			is_coord = 1;
			break;
		    }
		}
		if (! is_coord)	/* don't get data for non-coordinate vars */
		  continue;
	    }
	    /*
	     * Only get data for variable if it is not a record variable,
	     * or if it is a record variable and at least one record has
	     * been written.
	     */
	    if (var.ndims == 0
		|| var.dims[0] != xdimid
		|| dims[xdimid].size != 0) {

		/* Collect variable's dim sizes */
		for (id = 0; id < var.ndims; id++)
		  vdims[id] = dims[var.dims[id]].size;
		var.has_fillval = 1; /* by default, but turn off for bytes */

		/* get _FillValue attribute */
		nc_status = nc_inq_att(ncid,varid,_FillValue,&att.type,&att.len);
		if(nc_status == NC_NOERR &&
		   att.type == var.type && att.len == 1) {
		    if(var.type == NC_CHAR) {
			char fillc;
			NC_CHECK( nc_get_att_text(ncid, varid, _FillValue,
						  &fillc ) );
			var.fillval = fillc;
		    } else {
			NC_CHECK( nc_get_att_double(ncid, varid, _FillValue,
						    &var.fillval) );
		    }
		} else {
		    switch (var.type) {
		    case NC_BYTE:
			/* don't do default fill-values for bytes, too risky */
			var.has_fillval = 0;
			break;
		    case NC_CHAR:
			var.fillval = NC_FILL_CHAR;
			break;
		    case NC_SHORT:
			var.fillval = NC_FILL_SHORT;
			break;
		    case NC_INT:
			var.fillval = NC_FILL_INT;
			break;
		    case NC_FLOAT:
			var.fillval = NC_FILL_FLOAT;
			break;
		    case NC_DOUBLE:
			var.fillval = NC_FILL_DOUBLE;
			break;
		    default:
			break;
		    }
		}
		if (vardata(&var, vdims, ncid, varid, specp) == -1) {
		    error("can't output data for variable %s", var.name);
		    NC_CHECK(
			nc_close(ncid) );
		    if (vlist)
			free(vlist);
		    return;
		}
	    }
	}
    }
    
    Printf ("}\n");
    NC_CHECK(
	nc_close(ncid) );
    if (vlist)
	free(vlist);
}
Exemplo n.º 17
0
int
main(int argc, char **argv)
{
   printf("\n*** Testing netcdf-4 file functions.\n");
   {
      char str[NC_MAX_NAME+1];
      
      /* Actually we never make any promises about the length of the
       * version string, but it is always smaller than NC_MAX_NAME. */
      if (strlen(nc_inq_libvers()) > NC_MAX_NAME) ERR;
      strcpy(str, nc_inq_libvers());
      printf("*** testing version %s...", str);
   }
   SUMMARIZE_ERR;
   printf("*** testing with bad inputs...");
   {
      int ncid;

      /* Make sure bad create mode causes failure. */
      /*if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;*/
      
      /* Create an empty file. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_close(ncid)) ERR;

      if (nc_open(FILE_NAME, NC_MPIIO|NC_MPIPOSIX, &ncid) != NC_EINVAL) ERR;

      if (nc_create(FILE_NAME, NC_64BIT_OFFSET|NC_NETCDF4, &ncid) != NC_EINVAL) ERR;
      if (nc_create(FILE_NAME, NC_CLASSIC_MODEL|NC_MPIIO|NC_MPIPOSIX, &ncid) != NC_EINVAL) ERR;
      if (nc_create(FILE_NAME, NC_MPIIO|NC_MPIPOSIX, &ncid) != NC_EINVAL) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing simple opens and creates...");
   {
      int ncid, ncid2, ncid3, varid, dimids[2];
      int ndims, nvars, natts, unlimdimid;
      int dimids_var[1], var_type;
      size_t dim_len;
      char dim_name[NC_MAX_NAME+1], var_name[NC_MAX_NAME+1];
      unsigned char uchar_out[DIM1_LEN] = {0, 128, 255};

      /* Open and close empty file. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Recreate it again. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_INT, 1, dimids, &varid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Check the contents. Then define a new variable. Since it's
       * netcdf-4, nc_enddef isn't required - it's called
       * automatically. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 2 || nvars != 2 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_redef(ncid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_def_var(ncid, VAR3_NAME, NC_INT, 2, dimids, &varid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open three copies of the same file. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_open(FILE_NAME, NC_WRITE, &ncid2)) ERR;
      if (nc_open(FILE_NAME, NC_WRITE, &ncid3)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 2 || nvars != 3 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_inq(ncid2, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 2 || nvars != 3 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_inq(ncid3, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 2 || nvars != 3 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_close(ncid)) ERR;
      if (nc_close(ncid2)) ERR;
      if (nc_close(ncid3)) ERR;
      
      /* Open and close empty file. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Check the contents. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 0 || nvars != 0 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_close(ncid)) ERR;

      /* Create a file with one dimension and nothing else. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Check the contents. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 1 || nvars != 0 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
      if (dim_len != DIM1_LEN || strcmp(dim_name, DIM1_NAME)) ERR;
      if (nc_close(ncid)) ERR;

      /* Create a simple file, and write some data to it. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_BYTE, 1, dimids, &varid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_put_var_uchar(ncid, varid, uchar_out) != NC_ERANGE) ERR;
      if (nc_close(ncid)) ERR;

      /* Check the contents. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 1 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
      if (dim_len != DIM1_LEN || strcmp(dim_name, DIM1_NAME)) ERR;
      if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
      if (ndims != 1 || strcmp(var_name, VAR1_NAME) || var_type != NC_BYTE ||
	  dimids_var[0] != dimids[0] || natts != 0) ERR;
      if (nc_close(ncid)) ERR;

      /* Recreate the file. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_BYTE, 1, dimids, &varid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_put_var_uchar(ncid, varid, uchar_out)) ERR;
      if (nc_close(ncid)) ERR;

      /* Recreate it, then make sure NOCLOBBER works. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_close(ncid)) ERR;
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_NOCLOBBER, &ncid) != NC_EEXIST) ERR;

      /* Recreate it again. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_INT, 1, dimids, &varid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Check the contents. Then define a new variable. Since it's
       * netcdf-4, nc_enddef isn't required - it's called
       * automatically. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 2 || nvars != 2 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_redef(ncid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_def_var(ncid, VAR3_NAME, NC_INT, 2, dimids, &varid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Recreate it again with netcdf-3 rules turned on. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_INT, 1, dimids, &varid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Check the contents. Check that netcdf-3 rules are in effect. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 1 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid) != NC_ENOTINDEFINE) ERR;
      if (nc_close(ncid)) ERR;

      /* Check some other stuff about it. Closing and reopening the
       * file forces HDF5 to tell us if we forgot to free some HDF5
       * resource associated with the file. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
      if (dim_len != DIM1_LEN || strcmp(dim_name, DIM1_NAME)) ERR;
      if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
      if (ndims != 1 || strcmp(var_name, VAR1_NAME) || var_type != NC_INT ||
	  dimids_var[0] != dimids[0] || natts != 0) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing more complex opens and creates...");
   {
      int ncid, varid, dimids[2];
      int ndims, nvars, natts, unlimdimid;
      int dimids_var[2], var_type;
      size_t dim_len;
      char dim_name[NC_MAX_NAME+1], var_name[NC_MAX_NAME+1];
      float float_in, float_out = 99.99;
      int int_in, int_out = -9999;

      /* Create a file, this time with attributes. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLOBBER, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid)) ERR;
      if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid)) ERR;
      if (nc_put_att_float(ncid, NC_GLOBAL, ATT1_NAME, NC_FLOAT, 1, &float_out)) ERR;
      if (nc_put_att_int(ncid, NC_GLOBAL, ATT2_NAME, NC_INT, 1, &int_out)) ERR;
      if (nc_close(ncid)) ERR;

      /* Reopen the file and check it. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 2 || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
      if (nc_close(ncid)) ERR;

      /* Reopen it and check each dim, var, and att. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
      if (dim_len != DIM1_LEN || strcmp(dim_name, DIM1_NAME)) ERR;
      if (nc_inq_dim(ncid, 1, dim_name, &dim_len)) ERR;
      if (dim_len != DIM2_LEN || strcmp(dim_name, DIM2_NAME)) ERR;
      if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
      if (ndims != 2 || strcmp(var_name, VAR1_NAME) || var_type != NC_INT ||
	  dimids_var[0] != dimids[0] || natts != 0) ERR;
      if (nc_inq_var(ncid, 1, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
      if (ndims != 2 || strcmp(var_name, VAR2_NAME) || var_type != NC_UINT ||
	  dimids_var[1] != dimids[1] || natts != 0) ERR;
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT1_NAME, &float_in)) ERR;
      if (float_in != float_out) ERR;
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT2_NAME, &int_in)) ERR;
      if (int_in != int_out) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;

   printf("*** testing redef for netCDF classic...");
   test_redef(NC_FORMAT_CLASSIC);
   SUMMARIZE_ERR;
   printf("*** testing redef for netCDF 64-bit offset...");
   test_redef(NC_FORMAT_64BIT);
   SUMMARIZE_ERR;
   printf("*** testing redef for netCDF-4 ...");
   test_redef(NC_FORMAT_NETCDF4);
   SUMMARIZE_ERR;
   printf("*** testing redef for netCDF-4, with strict netCDF-3 rules...");
   test_redef(NC_FORMAT_NETCDF4_CLASSIC);
   SUMMARIZE_ERR;
   printf("*** testing different formats...");
   {
      int ncid;
      int format;

      /* Create a netcdf-3 file. */
      if (nc_create(FILE_NAME, NC_CLOBBER, &ncid)) ERR;
      if (nc_inq_format(ncid, &format)) ERR;
      if (format != NC_FORMAT_CLASSIC) ERR;
      if (nc_close(ncid)) ERR;

      /* Create a netcdf-3 64-bit offset file. */
      if (nc_create(FILE_NAME, NC_64BIT_OFFSET|NC_CLOBBER, &ncid)) ERR;
      if (nc_inq_format(ncid, &format)) ERR;
      if (format != NC_FORMAT_64BIT) ERR;
      if (nc_close(ncid)) ERR;

      /* Create a netcdf-4 file. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLOBBER, &ncid)) ERR;
      if (nc_inq_format(ncid, &format)) ERR;
      if (format != NC_FORMAT_NETCDF4) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing CLASSIC_MODEL flag with classic formats...");
   {
      int ncid;
      int format;

      /* Create a netcdf-3 file. */
      if (nc_create(FILE_NAME, NC_CLOBBER|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_inq_format(ncid, &format)) ERR;
      if (format != NC_FORMAT_CLASSIC) ERR;
      if (nc_close(ncid)) ERR;

      /* Create a netcdf-3 64-bit offset file. */
      if (nc_create(FILE_NAME, NC_64BIT_OFFSET|NC_CLOBBER|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_inq_format(ncid, &format)) ERR;
      if (format != NC_FORMAT_64BIT) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing multiple open files...");
   {
#define VAR_NAME "Captain_Kirk"
#define NDIMS 1
#define NUM_FILES 30
#define TEXT_LEN 15
#define D1_NAME "tl"
      int ncid[NUM_FILES], varid;
      int dimid;
      size_t count[NDIMS], index[NDIMS] = {0};
      const char ttext[TEXT_LEN + 1] = "20051224.150000";
      char ttext_in[TEXT_LEN + 1];
      char file_name[NC_MAX_NAME + 1];
      size_t chunks[NDIMS] = {TEXT_LEN + 1};
      int f;

      /* Create a bunch of files. */
      for (f = 0; f < NUM_FILES; f++)
      {
	 sprintf(file_name, "tst_files2_%d.nc", f);
	 if (nc_create(file_name, NC_NETCDF4, &ncid[f])) ERR;
	 if (nc_def_dim(ncid[f], D1_NAME, TEXT_LEN + 1, &dimid)) ERR;
	 if (nc_def_var(ncid[f], VAR_NAME, NC_CHAR, NDIMS, &dimid, &varid)) ERR;
	 if (f % 2 == 0)
	    if (nc_def_var_chunking(ncid[f], varid, 0, chunks)) ERR;
	 
	 /* Write one time to the coordinate variable. */
	 count[0] = TEXT_LEN + 1;
	 if (nc_put_vara_text(ncid[f], varid, index, count, ttext)) ERR;
      }

      /* Read something from each file. */
      for (f = 0; f < NUM_FILES; f++)
      {
	 if (nc_get_vara_text(ncid[f], varid, index, count, (char *)ttext_in)) ERR;
	 if (strcmp(ttext_in, ttext)) ERR;
      }

      /* Close all open files. */
      for (f = 0; f < NUM_FILES; f++)
	 if (nc_close(ncid[f])) ERR;
   }
   SUMMARIZE_ERR;
   FINAL_RESULTS;
}
Exemplo n.º 18
0
/* extract a variable from a netcdf file ant write it to another netcdf parallely, the function
 * will create new netcdf file if the output file does not exist. If the output file exists and the
 * output variable doesn't exist in the output file, the function creates a new variable or aborts.*/
int extract_unary(char *var,char *varOut,char **outDims,int outDimNum,size_t *begins,int beginNum,size_t *ends,int endNum,ptrdiff_t *strides,int strideNum,char *fileIn,char* fileOut){
	int mpi_size,mpi_rank;
	MPI_Comm_size(MPI_COMM_WORLD,&mpi_size);
	MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);

	MPI_Comm comm=MPI_COMM_WORLD;
	MPI_Info info=MPI_INFO_NULL;
	
	int ncid,vlid,ndims,dimids[NC_MAX_VAR_DIMS],nattrs;
	int ncidout,vlidout;
	int i,res;
	char varName[NC_MAX_NAME+1];
	nc_type vtype;	

	/* 
		open input file
	*/
	if((res=nc_open_par(fileIn,NC_MPIIO,comm,info,&ncid))){
		printf("Cannot open input file %s\n",fileIn);
		BAIL(res);
	}
	if((res=nc_inq_varid(ncid,var,&vlid))){
		printf("Cannot query variable %s in input file %s\n",var,fileIn);
		BAIL(res);	
	}
	if((res=nc_inq_var(ncid,vlid,varName,&vtype,&ndims,dimids,&nattrs))){
		printf("Cannot query dimension info of varialbe %s in input file %s\n",var,fileIn);
		BAIL(res);
	}


	char **dimsName=(char **)malloc(sizeof(char *)*ndims);
	size_t *shape=(size_t *)malloc(sizeof(size_t)*ndims);


	for(i=0;i<ndims;++i){
		dimsName[i]=(char *)malloc(NC_MAX_NAME+1);
		nc_inq_dim(ncid,dimids[i],dimsName[i],&shape[i]);//get dimsName and dimsLen
	}

	int is_strides_null=0;
	int is_begins_null=0;
	int is_ends_null=0;
	
	/* initialize begins ends and strides*/
	init_begins_ends_strides(ndims,&begins,&beginNum,&is_begins_null,&ends,&endNum,&is_ends_null,&strides,&strideNum,&is_strides_null,shape);
	
	/* deal with -d and -r arguments */
	dim_opts_handler(&global_attr,dimids,ncid,ndims,begins,ends,strides);
	
	/* check begins ends and strides */
	if(-1==check_begins_ends_strides(ndims,begins,beginNum,ends,endNum,strides,strideNum,shape,dimsName)){return -1;}


	/* set independent parallel access for input file */
	if((res=nc_var_par_access(ncid,vlid,NC_INDEPENDENT))){
		printf("Cannot set parallel access for variable %s in input file %s\n",var,fileIn);
		BAIL(res);
	}
	/*
		create output file and define dims and var
	*/
	int *dimidsOut=(int *)malloc(sizeof(int)*ndims);
	if(-1==	open_output_file_and_define_var(fileOut,&ncidout,&vlidout,dimidsOut,global_attr.append,ndims,vtype,dimsName,begins,ends,strides,shape,var,varOut,outDims,outDimNum)){return -1;}
	
	
	/* define attributes */
	copy_attrs(ncid, vlid, ncidout, vlidout, nattrs);
	add_cmd_attr(ncidout,vlidout,global_attr.argc,global_attr.argv,mpi_size);
	if((res=nc_enddef(ncidout))){
		printf("End define netcdf id %d in output file %s failed\n",ncidout,fileOut);
		BAIL(res);
	}

	if((res=nc_var_par_access(ncidout,vlidout,NC_INDEPENDENT))) {
		printf("Cannot set parallel access for variable %s in output file %s\n",var,fileOut);
		BAIL(res);
	}
	extract_unary_selector(mpi_rank,mpi_size,ncid,vlid,ncidout,vlidout,ndims,vtype,shape,begins,ends,strides,0L,NULL);// select reasonable parallel funtion

	/* free resources */
	if(is_strides_null)
		free(strides);
	if(is_begins_null)
		free(begins);
	if(is_ends_null)
		free(ends);
	for(i=0;i<ndims;++i){
		free(dimsName[i]);
	}
	free(dimsName);
	free(dimidsOut);
	free(shape);

	/*close file*/
	if((res=nc_close(ncid))){
		printf("Close input file %s failed\n",fileIn);
		BAIL(res);
	}
	if((res=nc_close(ncidout))){
		printf("Close output file %s failed\n",fileOut);
		BAIL(res);
	}
	return 0;
}
Exemplo n.º 19
0
/* Copy a netCDF file, changing cmode if desired. */
static
int copy_file(char *file_name_in, char *file_name_out, int cmode_out,
	      int *chunking, int *deflate)
{
   int ncid_in, ncid_out;
   int natts, nvars, ndims, unlimdimid;
   char name[NC_MAX_NAME + 1];
   size_t len;
   int a, v, d;

   if (nc_open(file_name_in, NC_NOWRITE, &ncid_in)) ERR;
   if (nc_create(file_name_out, cmode_out, &ncid_out)) ERR;
      
   if (nc_inq(ncid_in, &ndims, &nvars, &natts, &unlimdimid)) ERR;

   /* Copy dims. */
   for (d = 0; d < ndims; d++)
   {
      if (nc_inq_dim(ncid_in, d, name, &len)) ERR;
      if (nc_def_dim(ncid_out, name, len, NULL)) ERR;
   }

   /* Copy global atts. */
   for (a = 0; a < natts; a++)
   {
      if (nc_inq_attname(ncid_in, NC_GLOBAL, a, name)) ERR;
      if (nc_copy_att(ncid_in, NC_GLOBAL, name, ncid_out, NC_GLOBAL)) ERR;
   }

   /* Copy the variable metadata. */
   for (v = 0; v < nvars; v++)
   {
      char name[NC_MAX_NAME + 1];
      char att_name[NC_MAX_NAME + 1];
      nc_type xtype;
      int ndims, dimids[NC_MAX_VAR_DIMS], natts;
      int varid_out;
      int a;
      int retval = NC_NOERR;

      /* Learn about this var. */
      if ((retval = nc_inq_var(ncid_in, v, name, &xtype, &ndims, dimids, &natts)))
	 return retval;

      /* Create the output var. */
      if (nc_def_var(ncid_out, name, xtype, ndims, dimids, &varid_out)) ERR;

      /* Except for 1D vars, sent chunking and compression. */
      if (ndims != 1)
      {
	 if (chunking)
	    if (nc_def_var_chunking(ncid_out, v, NC_CHUNKED, chunking)) ERR;
	 if (deflate)
	    if (nc_def_var_deflate(ncid_out, v, NC_NOSHUFFLE, *deflate, *deflate)) ERR;
      }

      /* Copy the attributes. */
      for (a=0; a<natts; a++)
      {
	 if (nc_inq_attname(ncid_in, v, a, att_name)) ERR;
	 if (nc_copy_att(ncid_in, v, att_name, ncid_out, varid_out)) ERR;
      }
   }

   /* Copy the variable data. */
   for (v = 0; v < nvars; v++)
   {
      char name[NC_MAX_NAME + 1];
      nc_type xtype;
      int ndims, dimids[NC_MAX_VAR_DIMS], natts, real_ndims;
      int d;
      void *data = NULL;
      size_t *count = NULL, *start = NULL;
      size_t reclen = 1;
      size_t *dimlen = NULL;
      int retval = NC_NOERR;
      size_t type_size;
      char type_name[NC_MAX_NAME+1];

      /* Learn about this var. */
      if ((retval = nc_inq_var(ncid_in, v, name, &xtype, &ndims, dimids, &natts)))
	 return retval;

      /* Later on, we will need to know the size of this type. */
      if ((retval = nc_inq_type(ncid_in, xtype, type_name, &type_size)))
	 return retval;
      LOG((3, "type %s has size %d", type_name, type_size));

      /* Allocate memory for our start and count arrays. If ndims = 0
	 this is a scalar, which I will treat as a 1-D array with one
	 element. */
      real_ndims = ndims ? ndims : 1;
      if (!(start = nc_malloc(real_ndims * sizeof(size_t))))
	 BAIL(NC_ENOMEM);
      if (!(count = nc_malloc(real_ndims * sizeof(size_t))))
	 BAIL(NC_ENOMEM);

      /* The start array will be all zeros, except the first element,
	 which will be the record number. Count will be the dimension
	 size, except for the first element, which will be one, because
	 we will copy one record at a time. For this we need the var
	 shape. */
      if (!(dimlen = nc_malloc(real_ndims * sizeof(size_t))))
	 BAIL(NC_ENOMEM);

      /* Find out how much data. */
      for (d=0; d<ndims; d++)
      {
	 if ((retval = nc_inq_dimlen(ncid_in, dimids[d], &dimlen[d])))
	    BAIL(retval);
	 LOG((4, "nc_copy_var: there are %d data", dimlen[d]));
      }

      /* If this is really a scalar, then set the dimlen to 1. */
      if (ndims == 0)
	 dimlen[0] = 1;

      for (d=0; d<real_ndims; d++)
      {
	 start[d] = 0;
	 count[d] = d ? dimlen[d] : 1;
	 if (d) reclen *= dimlen[d];
      }

      /* If there are no records, we're done. */
      if (!dimlen[0])
	 goto exit;

      /* Allocate memory for one record. */
      if (!(data = nc_malloc(reclen * type_size)))
	 return NC_ENOMEM;
   
      /* Copy the var data one record at a time. */
      for (start[0]=0; !retval && start[0]<(size_t)dimlen[0]; start[0]++)
      {
	 if (nc_get_vara(ncid_in, v, start, count, data)) ERR;
	 if (nc_put_vara(ncid_out, v, start, count, data)) ERR;
      }
    
     exit:
      if (data) nc_free(data);
      if (dimlen) nc_free(dimlen);
      if (start) nc_free(start);
      if (count) nc_free(count);

   }

   if (nc_close(ncid_in)) ERR;
   if (nc_close(ncid_out)) ERR;

   return NC_NOERR;
}
Exemplo n.º 20
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;
}
Exemplo n.º 21
0
/*******************************************************************************
  Function name: Read2DMatrixNetCDF()

  Purpose      : Function to read a 2D array from a file.

  Required     :
    FileName   - name of input file
    Matrix     - address of array data into
    NumberType - code for number type (taken from HDF, see comments at the
                 beginning of InitFileIO.c for more detail)
    NY         - Number of rows
    NX         - Number of columns
    NDataSet   - number of the dataset to read, i.e. the first matrix in a 
                 file is number 0, etc. (this is not used for the NetCDF file,
		 since we can retrieve the variable by name).
    VarName    - Name of variable to retrieve

  Returns      : Number of elements read

  Modifies     : Matrix

  Comments     : NOTE that we cannot modify anything other than the returned
                 Matrix, because we have to stay compatible with Read2DMatrixBin 
*******************************************************************************/
 int Read2DMatrixNetCDF(char *FileName, void *Matrix, int NumberType, int NY,
		       int NX, int NDataSet, ...) 
{
  const char *Routine = "Read2DMatrixNetCDF";
  char Str[BUFSIZE + 1];
  char dimname[NC_MAX_NAME + 1];
  char *VarName;
  int dimids[3];
  int ndims;
  int ncid;
  int ncstatus;
  nc_type TempNumberType;
  int varid;
  size_t index;	
  double time;
  int timid;
  size_t count[3];
  size_t start[3] = { 0, 0, 0 };
  size_t dimlen;
  size_t timelen;
  va_list ap;
  double *Ycoord;
  double *Xcoord;  /* lat, lon variables */
  int	LatisAsc, LonisAsc, flag;    /* flag */
  int lon_varid, lat_varid;
  count[0] = 1;
  count[1] = NY;
  count[2] = NX;

  /****************************************************************************/
  /*                   GO THROUGH VARIABLE ARGUMENT LIST                      */
  /****************************************************************************/
  va_start(ap, NDataSet);
  VarName = va_arg(ap, char *);
  index = va_arg(ap, int);
  /****************************************************************************/
  /*                           QUERY NETDCF FILE                              */
  /****************************************************************************/

  ncstatus = nc_open(FileName, NC_NOWRITE, &ncid);
  /* debugging if any file fails to be opened */
  //printf("Trying to open %s\n", FileName);
  nc_check_err(ncstatus, __LINE__, __FILE__);

  /* check whether the variable exists and get its parameters */
  ncstatus = nc_inq_varid(ncid, VarName, &varid);
  nc_check_err(ncstatus, __LINE__, __FILE__);

  ncstatus = nc_inq_var(ncid, varid, 0, &TempNumberType, &ndims, dimids, NULL);
  nc_check_err(ncstatus, __LINE__, __FILE__);
  if (TempNumberType != NumberType) {
    sprintf(Str, "%s: nc_type for %s is different than expected.\n",
	    FileName, VarName);
    ReportWarning(Str, 58);
  }

  /* make sure that the x and y dimensions have the correct sizes */
  ncstatus = nc_inq_dim(ncid, dimids[1], dimname, &dimlen);  
  nc_check_err(ncstatus, __LINE__, __FILE__);
  ncstatus = nc_inq_varid(ncid, dimname, &lat_varid);
  nc_check_err(ncstatus, __LINE__, __FILE__);
  if (dimlen != NY)
	  ReportError(VarName, 59);
  Ycoord = (double *) calloc(dimlen, sizeof(double));
  if (Ycoord == NULL)
    ReportError((char *) Routine, 1);
    /* Read the latitude coordinate variable data. */
  ncstatus = nc_get_var_double(ncid, lat_varid, Ycoord);
  nc_check_err(ncstatus, __LINE__, __FILE__);
  /* A quick check if the lat, long are in a ascending order. 
  If so, matrix must be flipped so the first value in the matrix will be 
  assigned to the lower left corner cell that has lowest X (lon) & Y (lat) value. 
  (see more comments in the header of this C file). */
  LatisAsc = 1;
  if( Ycoord[0] > Ycoord[NY - 1] ) 
	  LatisAsc = 0;

  ncstatus = nc_inq_dim(ncid, dimids[2], dimname, &dimlen);
  nc_check_err(ncstatus, __LINE__, __FILE__);
  ncstatus = nc_inq_varid(ncid, dimname, &lon_varid);
  nc_check_err(ncstatus, __LINE__, __FILE__);
  if (dimlen != NX)
    ReportError(VarName, 60);
  Xcoord = (double *) calloc(NX, sizeof(double));
  if (Xcoord == NULL)
    ReportError((char *) Routine, 1);
  /* Read the latitude coordinate variable data. */
  ncstatus = nc_get_var_double(ncid, lon_varid, Xcoord);
  nc_check_err(ncstatus, __LINE__, __FILE__);
  LonisAsc = 1;
  if( Xcoord[0] > Xcoord[NX - 1] ) 
	  LonisAsc = 0;

  if (LonisAsc == 0){
	  printf("The current program does not handle the cases when longitude or X \
values in the .nc input in an descending order. You can either change the input \
.nc file format outside of this program. or you can easily modify this program to \
fit your needs. \n");
	  ReportError("Improper NetCDF input files", 58);
  }
Exemplo n.º 22
0
/*ARGSUSED*/
int
main(int argc, char *argv[])
{
	int cmode=NC_CLOBBER, omode, ret;
	int	 id;
	char buf[256];
#ifdef SYNCDEBUG
	char *str = "one";
#endif
	int ii;
	size_t ui;
	const struct tcdfvar *tvp = testvars;
	union getret got;
	const size_t initialsz = 8192;
	size_t chunksz = 8192;
	size_t align = 8192/32;

	MPI_Init(&argc, &argv);

        /* cmode |= NC_PNETCDF |NC_64BIT_OFFSET; */
        cmode != NC_PNETCDF |NC_64BIT_DATA;
	ret = nc_create_par(fname,cmode, MPI_COMM_WORLD, MPI_INFO_NULL, &id);
	if(ret != NC_NOERR)  {
		fprintf(stderr,"Error %s in file %s at line %d\n",nc_strerror(ret),__FILE__,__LINE__);
		exit(ret);
        }
	
	assert( nc_put_att_text(id, NC_GLOBAL,
		"TITLE", 12, "another name") == NC_NOERR);
	assert( nc_get_att_text(id, NC_GLOBAL,
		"TITLE", buf) == NC_NOERR);
/*	(void) printf("title 1 \"%s\"\n", buf); */
	assert( nc_put_att_text(id, NC_GLOBAL,
		"TITLE", strlen(fname), fname) == NC_NOERR);
	assert( nc_get_att_text(id, NC_GLOBAL,
		"TITLE", buf) == NC_NOERR);
	buf[strlen(fname)] = 0;
/*	(void) printf("title 2 \"%s\"\n", buf); */
	assert( strcmp(fname, buf) == 0);

	createtestdims(id, NUM_DIMS, sizes, dim_names);
	testdims(id, NUM_DIMS, sizes, dim_names);

	createtestvars(id, testvars, NUM_TESTVARS); 

 	{
 	int ifill = -1; double dfill = -9999;
 	assert( nc_put_att_int(id, Long_id,
 		_FillValue, NC_INT, 1, &ifill) == NC_NOERR);
 	assert( nc_put_att_double(id, Double_id,
 		_FillValue, NC_DOUBLE, 1, &dfill) == NC_NOERR);
 	}

#ifdef REDEF
	assert( nc__enddef(id, 0, align, 0, 2*align) == NC_NOERR );
	assert( nc_put_var1_int(id, Long_id, indices[3], &birthday) 
		== NC_NOERR );
	fill_seq(id);
	assert( nc_redef(id) == NC_NOERR );
/*	assert( nc_rename_dim(id,2, "a long dim name") == NC_NOERR); */
#endif

	assert( nc_rename_dim(id,1, "IXX") == NC_NOERR);
	assert( nc_inq_dim(id, 1, buf, &ui) == NC_NOERR);
	/* (void) printf("dimrename: %s\n", buf); */
	assert( nc_rename_dim(id,1, dim_names[1]) == NC_NOERR);

#ifdef ATTRX
	assert( nc_rename_att(id, 1, "UNITS", "units") == NC_NOERR);
	assert( nc_del_att(id, 4, "FIELDNAM")== NC_NOERR);
	assert( nc_del_att(id, 2, "SCALEMIN")== NC_NOERR);
	assert( nc_del_att(id, 2, "SCALEMAX")== NC_NOERR);
#endif /* ATTRX */

	assert( nc__enddef(id, 0, align, 0, 2*align) == NC_NOERR );

#ifndef REDEF
	fill_seq(id);
	assert( nc_put_var1_int(id, Long_id, indices[3], &birthday)== NC_NOERR );
#endif

	assert( nc_put_vara_schar(id, Byte_id, s_start, s_edges,
		(signed char *)sentence)
		== NC_NOERR);
	assert( nc_put_var1_schar(id, Byte_id, indices[6], (signed char *)(chs+1))
		== NC_NOERR);
	assert( nc_put_var1_schar(id, Byte_id, indices[5], (signed char *)chs)
		== NC_NOERR);

	assert( nc_put_vara_text(id, Char_id, s_start, s_edges, sentence)
		== NC_NOERR);
	assert( nc_put_var1_text(id, Char_id, indices[6], (chs+1))
		== NC_NOERR) ;
	assert( nc_put_var1_text(id, Char_id, indices[5], chs)
		== NC_NOERR);

	assert( nc_put_var1_short(id, Short_id, indices[4], shs)
		== NC_NOERR);

	assert( nc_put_var1_float(id, Float_id, indices[2], &e)
		== NC_NOERR);

	assert( nc_put_var1_double(id, Double_id, indices[1], &zed)
		== NC_NOERR);
	assert( nc_put_var1_double(id, Double_id, indices[0], &pinot)
		== NC_NOERR);


#ifdef SYNCDEBUG
	(void) printf("Hit Return to sync\n");
	gets(str);
	nc_sync(id,0);
	(void) printf("Sync done. Hit Return to continue\n");
	gets(str);
#endif /* SYNCDEBUG */

	ret = nc_close(id);
	/* (void) printf("nc_close ret = %d\n\n", ret); */


/*
 *	read it
 */
        omode = NC_NOWRITE;
        omode = NC_NOWRITE | NC_PNETCDF;
	if(ret != NC_NOERR)
	{
   	    (void) printf("Could not open %s: %s\n", fname,
			nc_strerror(ret));
   	    exit(1);
	}
	/* (void) printf("reopen id = %d for filename %s\n", */
	/* 	id, fname); */

	/*	NC	*/ 
	/* (void) printf("NC "); */
	assert( nc_inq(id, &(cdesc->num_dims), &(cdesc->num_vars),
		&(cdesc->num_attrs), &(cdesc->xtendim) ) == NC_NOERR);
	assert((size_t) cdesc->num_dims == num_dims);
	assert(cdesc->num_attrs == 1);
	assert(cdesc->num_vars == NUM_TESTVARS);
	/* (void) printf("done\n"); */
	
	/*	GATTR	*/
	/* (void) printf("GATTR "); */

	assert( nc_inq_attname(id, NC_GLOBAL, 0, adesc->mnem) == 0);
	assert(strcmp("TITLE",adesc->mnem) == 0);
	assert( nc_inq_att(id, NC_GLOBAL, adesc->mnem, &(adesc->type), &(adesc->len))== NC_NOERR);
	assert( adesc->type == NC_CHAR );
	assert( adesc->len == strlen(fname) );
	assert( nc_get_att_text(id, NC_GLOBAL, "TITLE", buf)== NC_NOERR);
	buf[adesc->len] = 0;
	assert( strcmp(fname, buf) == 0);

	/*	VAR	*/
	/* (void) printf("VAR "); */
	assert( cdesc->num_vars == NUM_TESTVARS );

	for(ii = 0; ii < cdesc->num_vars; ii++, tvp++ ) 
	{
		int jj;
		assert( nc_inq_var(id, ii,
			vdesc->mnem,
			&(vdesc->type),
			&(vdesc->ndims),
			vdesc->dims,
			&(vdesc->num_attrs)) == NC_NOERR);
		if(strcmp(tvp->mnem , vdesc->mnem) != 0)
		{
			(void) printf("attr %d mnem mismatch %s, %s\n",
				ii, tvp->mnem, vdesc->mnem);
			continue;
		}
		if(tvp->type != vdesc->type)
		{
			(void) printf("attr %d type mismatch %d, %d\n",
				ii, (int)tvp->type, (int)vdesc->type);
			continue;
		}
		for(jj = 0; jj < vdesc->ndims; jj++ )
		{
			if(tvp->dims[jj] != vdesc->dims[jj] )
			{
		(void) printf(
		"inconsistent dim[%d] for variable %d: %d != %d\n",
		jj, ii, tvp->dims[jj], vdesc->dims[jj] );
			continue;
			}
		}

		/* VATTR */
		/* (void) printf("VATTR\n"); */
		for(jj=0; jj<vdesc->num_attrs; jj++ ) 
		{
			assert( nc_inq_attname(id, ii, jj, adesc->mnem) == NC_NOERR);
			if( strcmp(adesc->mnem, reqattr[jj]) != 0 )
			{
				(void) printf("var %d attr %d mismatch %s != %s\n",
					ii, jj, adesc->mnem, reqattr[jj] );
				break;
			}
		}

		if( nc_inq_att(id, ii, reqattr[0], &(adesc->type), &(adesc->len))
			!= -1) {
		assert( adesc->type == NC_CHAR );
		assert( adesc->len == strlen(tvp->units) );
	 	assert( nc_get_att_text(id,ii,reqattr[0],buf)== NC_NOERR); 
		buf[adesc->len] = 0;
		assert( strcmp(tvp->units, buf) == 0);
		}

		if(
			nc_inq_att(id, ii, reqattr[1], &(adesc->type), &(adesc->len))
			!= -1)
		{
		assert( adesc->type == NC_DOUBLE );
		assert( adesc->len == 1 );
	 	assert( nc_get_att_double(id, ii, reqattr[1], &got.dbl)== NC_NOERR);
		chkgot(adesc->type, got, tvp->validmin);
		}

		if(
			nc_inq_att(id, ii, reqattr[2], &(adesc->type), &(adesc->len))
			!= -1)
		{
		assert( adesc->type == NC_DOUBLE );
		assert( adesc->len == 1 );
	 	assert( nc_get_att_double(id, ii, reqattr[2], &got.dbl)== NC_NOERR);
		chkgot(adesc->type, got, tvp->validmax);
		}

		if(
			nc_inq_att(id, ii, reqattr[3], &(adesc->type), &(adesc->len))
			!= -1)
		{
		assert( adesc->type == NC_DOUBLE );
		assert( adesc->len ==1 );
	 	assert( nc_get_att_double(id, ii, reqattr[3], &got.dbl)== NC_NOERR);
		chkgot(adesc->type, got, tvp->scalemin);
		}

		if(
			nc_inq_att(id, ii, reqattr[4], &(adesc->type), &(adesc->len))
			!= -1)
		{
		assert( adesc->type == NC_DOUBLE );
		assert( adesc->len == 1 );
	 	assert( nc_get_att_double(id, ii, reqattr[4], &got.dbl)== NC_NOERR);
		chkgot(adesc->type, got, tvp->scalemax);
		}

		if( nc_inq_att(id, ii, reqattr[5], &(adesc->type), &(adesc->len))== NC_NOERR)
		{
		assert( adesc->type == NC_CHAR );
		assert( adesc->len == strlen(tvp->fieldnam) );
	 	assert( nc_get_att_text(id,ii,reqattr[5],buf)== NC_NOERR); 
		buf[adesc->len] = 0;
		assert( strcmp(tvp->fieldnam, buf) == 0);
		}
	}

	/* (void) printf("fill_seq "); */
	check_fill_seq(id);
	/* (void) printf("Done\n"); */

	assert( nc_get_var1_double(id, Double_id, indices[0], &got.dbl)== NC_NOERR);
	/* (void) printf("got val = %f\n", got.dbl ); */

	assert( nc_get_var1_double(id, Double_id, indices[1], &got.dbl)== NC_NOERR);
	/* (void) printf("got val = %f\n", got.dbl ); */

	assert( nc_get_var1_float(id, Float_id, indices[2], &got.fl[0])== NC_NOERR);
	/* (void) printf("got val = %f\n", got.fl[0] ); */

	assert( nc_get_var1_int(id, Long_id, indices[3], &got.in[0])== NC_NOERR);
	/* (void) printf("got val = %d\n", got.in[0] ); */

	assert( nc_get_var1_short(id, Short_id, indices[4], &got.sh[0])== NC_NOERR);
	/* (void) printf("got val = %d\n", got.sh[0] ); */

	assert( nc_get_var1_text(id, Char_id, indices[5], &got.by[0]) == NC_NOERR);
	/* (void) printf("got NC_CHAR val = %c (0x%02x) \n", */
		 /* got.by[0] , got.by[0]); */

	assert( nc_get_var1_text(id, Char_id, indices[6], &got.by[0]) == NC_NOERR);
	/* (void) printf("got NC_CHAR val = %c (0x%02x) \n", */
	/* 	 got.by[0], got.by[0] ); */

	(void) memset(buf,0,sizeof(buf));
	assert( nc_get_vara_text(id, Char_id, s_start, s_edges, buf) == NC_NOERR);
	/* (void) printf("got NC_CHAR val = \"%s\"\n", buf); */

	assert( nc_get_var1_schar(id, Byte_id, indices[5],
			(signed char *)&got.by[0])== NC_NOERR);
	/* (void) printf("got val = %c (0x%02x) \n", got.by[0] , got.by[0]); */

	assert( nc_get_var1_schar(id, Byte_id, indices[6],
			(signed char *)&got.by[0])== NC_NOERR);
	/* (void) printf("got val = %c (0x%02x) \n", got.by[0], got.by[0] ); */

	(void) memset(buf,0,sizeof(buf));
	assert( nc_get_vara_schar(id, Byte_id, s_start, s_edges,
			(signed char *)buf)== NC_NOERR );
	/* (void) printf("got val = \"%s\"\n", buf); */

	{
		double dbuf[NUM_RECS * SIZE_1 * SIZE_2];
		assert(nc_get_var_double(id, Float_id, dbuf) == NC_NOERR);
		/* (void) printf("got vals = %f ... %f\n", dbuf[0], */
		/* 	 dbuf[NUM_RECS * SIZE_1 * SIZE_2 -1] ); */
	}

	ret = nc_close(id);
	/* (void) printf("re nc_close ret = %d\n", ret); */

	MPI_Finalize();
	return 0;
}
Exemplo n.º 23
0
/* Write the grid to the netcdf file fname */
void WriteGridnetcdf(char *fname, int gridno)
{
    int i, j, cnt;
    int *ellist;

    int ncid;			/* netCDF id */

    /* dimension ids */
    int nmnp_dim;
    int nmel_dim;
    int elements_dim;

    /* dimension lengths */
    size_t nmnp_len;
    size_t nmel_len;
    size_t elements_len;
    size_t start[2], count[2];

    /* variable ids */
    int x_id;
    int y_id;
    int z_id;
    int elements_id;

    int stat;

    stat = nc_open(fname, NC_WRITE, &ncid);
    check_err(stat, __LINE__, __FILE__);
    stat = nc_inq_dimid(ncid, "nmel", &nmel_dim);
    stat = nc_inq_dim(ncid, nmel_dim, "nmel", &nmel_len);
    stat = nc_inq_dimid(ncid, "nmnp", &nmnp_dim);
    stat = nc_inq_dim(ncid, nmnp_dim, "nmnp", &nmnp_len);
    stat = nc_inq_dimid(ncid, "elements", &elements_dim);
    stat = nc_inq_dim(ncid, elements_dim, "elements", &elements_len);
    stat = nc_inq_varid(ncid, "x", &x_id);
    stat = nc_inq_varid(ncid, "y", &y_id);
    stat = nc_inq_varid(ncid, "z", &z_id);
    stat = nc_inq_varid(ncid, "elements", &elements_id);

    ellist = (int *) malloc(elements_len * sizeof(int));
    if (ellist == NULL) {
	stat = nc_close(ncid);
	return;
    }
    start[0] = 0;
    count[0] = nmnp_len;
    stat = nc_put_vara_double(ncid, x_id, start, count, grid[gridno].xord);
    stat = nc_put_vara_double(ncid, y_id, start, count, grid[gridno].yord);
    stat = nc_put_vara_double(ncid, z_id, start, count, grid[gridno].depth);

    cnt = 0;
    for (i = 0; i < grid[gridno].nmel; i++) {
	ellist[cnt++] = grid[gridno].icon[i].nn;
	for (j = 0; j < grid[gridno].icon[i].nn; j++) {
	    ellist[cnt++] = grid[gridno].icon[i].nl[j];
	}
    }
    /*
     * Oops, number of items in elements differs between the grid and the
     * file, bail out.
     */
    if (cnt != elements_len) {
	free(ellist);
	stat = nc_close(ncid);
	return;
    }
    start[0] = 0;
    count[0] = cnt;
    stat = nc_put_vara_int(ncid, elements_id, start, count, ellist);
    free(ellist);
    stat = nc_close(ncid);
    check_err(stat, __LINE__, __FILE__);
}
Exemplo n.º 24
0
/* Read the grid from the netcdf file fname */
void ReadGridnetcdf(char *fname, int gridno)
{
    int i, j, cnt, nel, newelement;
    int *ellist;

    int ncid;			/* netCDF id */

    /* dimension ids */
    int nmnp_dim;
    int nmel_dim;
    int elements_dim;

    /* dimension lengths */
    size_t nmnp_len;
    size_t nmel_len;
    size_t elements_len;
    size_t start[2], count[2];

    /* variable ids */
    int x_id;
    int y_id;
    int z_id;
    int elements_id;

    int stat;

    stat = nc_open(fname, NC_NOWRITE, &ncid);
    check_err(stat, __LINE__, __FILE__);
    stat = nc_inq_dimid(ncid, "nmel", &nmel_dim);
    check_err(stat, __LINE__, __FILE__);
    stat = nc_inq_dim(ncid, nmel_dim, "nmel", &nmel_len);
    check_err(stat, __LINE__, __FILE__);
    stat = nc_inq_dimid(ncid, "nmnp", &nmnp_dim);
    check_err(stat, __LINE__, __FILE__);
    stat = nc_inq_dim(ncid, nmnp_dim, "nmnp", &nmnp_len);
    check_err(stat, __LINE__, __FILE__);
    stat = nc_inq_dimid(ncid, "elements", &elements_dim);
    check_err(stat, __LINE__, __FILE__);
    stat = nc_inq_dim(ncid, elements_dim, "elements", &elements_len);
    check_err(stat, __LINE__, __FILE__);
    stat = nc_inq_varid(ncid, "x", &x_id);
    check_err(stat, __LINE__, __FILE__);
    stat = nc_inq_varid(ncid, "y", &y_id);
    check_err(stat, __LINE__, __FILE__);
    stat = nc_inq_varid(ncid, "z", &z_id);
    check_err(stat, __LINE__, __FILE__);
    stat = nc_inq_varid(ncid, "elements", &elements_id);
    check_err(stat, __LINE__, __FILE__);

    ellist = (int *) malloc(elements_len * sizeof(int));
    if (ellist == NULL) {
	stat = nc_close(ncid);
	check_err(stat, __LINE__, __FILE__);
	return;
    }

    Free_grid(gridno);

    grid[gridno].alphid[0] = '\0';
    if (!Allocate_grid(gridno, nmel_len, nmnp_len)) {
	errwin("Can't allocate memory for grid");
	Free_grid(gridno);
	free(ellist);
	stat = nc_close(ncid);
	return;
    }
    start[0] = 0;
    count[0] = elements_len;
    stat = nc_get_vara_int(ncid, elements_id, start, count, ellist);
    check_err(stat, __LINE__, __FILE__);

/*
 * Read table of nodes
 */
    start[0] = 0;
    count[0] = nmnp_len;
    stat = nc_get_vara_double(ncid, x_id, start, count, grid[gridno].xord);
    check_err(stat, __LINE__, __FILE__);
    stat = nc_get_vara_double(ncid, y_id, start, count, grid[gridno].yord);
    check_err(stat, __LINE__, __FILE__);
    stat = nc_get_vara_double(ncid, z_id, start, count, grid[gridno].depth);
    check_err(stat, __LINE__, __FILE__);

/*
 * Read table of elements
 */
    cnt = 0;
    newelement = 1;
    nel = 0;
    for (i = 0; i < elements_len; i++) {
	if (newelement) {
	    grid[gridno].icon[nel].nn = ellist[i];
	    grid[gridno].icon[nel].type = ellist[i]; /* for now, type and nn are the same */
	    cnt = 0;
	    newelement = 0;
	} else {
	    grid[gridno].icon[nel].nl[cnt] = ellist[i];
	    cnt++;
	    if (cnt == grid[gridno].icon[nel].nn) {
		newelement = 1;
		nel++;
	    }
	}
    }

    free(ellist);

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

    grid[gridno].gridtype = 1;  /* set gridtype to linear. */
    set_grid_limits(gridno);
    default_isolines(&grid[gridno].ip);
    autoscale_isolines(grid[gridno].dmin, grid[gridno].dmax, &grid[gridno].ip);
    mindist = (grid[gridno].xmax - grid[gridno].xmin) * 0.01;
}
bool
avtNETCDFReaderBase::GetTimeDimension(NETCDFFileObject *fileObject, int &ncdim, int &nts, std::string &name)
{
    const char *mName = "avtNETCDFReaderBase::GetTimeDimension: ";
    bool retval = false;

    ncdim = -1;
    nts = -1;
    name = "";

    int status, nDims, nVars, nGlobalAtts, unlimitedDimension;
    status = nc_inq(fileObject->GetFileHandle(), &nDims, &nVars, &nGlobalAtts,
                    &unlimitedDimension);
    // Check the dimension size.
    size_t sz = 0;
    char dimName[NC_MAX_NAME+1];
    if(status == NC_NOERR && unlimitedDimension >= 0)
    {
        ncdim = unlimitedDimension;
        debug4 << mName << "unlimitedDimension = " << unlimitedDimension << endl;

        if((status = nc_inq_dim(fileObject->GetFileHandle(), unlimitedDimension, dimName,
            &sz)) == NC_NOERR)
        {
            nts = sz;
            name = dimName;
            retval = true;
            debug4 << mName << "unlimitedDimension name=" << name << ", size=" << nts << endl;
        }
    }

    if(nts == -1)
    {
        debug4 << mName << "No unlimited dimension so look for suitable time dimensions" << endl;
        const char *timedims[] = {"time", "Time", "T"};
        for(int i = 0; i < 3; ++i)
        {
            if(fileObject->GetDimensionInfo(timedims[i], &sz))
            {
                // Look up which nc dimension this is too.
                for(int j = 0; j < nDims && ncdim == -1; ++j)
                {
                    if((status = nc_inq_dim(fileObject->GetFileHandle(), j, dimName,
                                            &sz)) == NC_NOERR)
                    {
                        if(strcmp(dimName, timedims[i]) == 0)
                            ncdim = j;
                    }
                }

                nts = sz;
                name = timedims[i];
                retval = true;
                debug4 << mName << timedims[i] << " dimension size=" << nts << endl;
                break;
            }
        }
    }

    return retval;
}
Exemplo n.º 26
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;
}
Exemplo n.º 27
0
int 
main(int argc, char **argv)
{
   extern int optind;
   extern int opterr;
   extern char *optarg;
   int c, header = 0, verbose = 0, timeseries = 0;
   int ncid, varid, storage;
   char name_in[NC_MAX_NAME + 1];
   size_t len;
   size_t cs[NDIMS3] = {0, 0, 0};
   int cache = MEGABYTE;
   int ndims, dimid[NDIMS3];
   float hor_data[LAT_LEN * LON_LEN];
   int read_1_us, avg_read_us;
   float ts_data[TIME_LEN];
   size_t start[NDIMS3], count[NDIMS3];
   int deflate, shuffle, deflate_level;
   struct timeval start_time, end_time, diff_time;

   while ((c = getopt(argc, argv, "vhtc:")) != EOF)
      switch(c) 
      {
	 case 'v':
	    verbose++;
	    break;
	 case 'h':
	    header++;
	    break;
	 case 't':
	    timeseries++;
	    break;
	 case 'c':
	    sscanf(optarg, "%d", &cache);
	    break;
	 case '?':
	    usage();
	    return 1;
      }
      
   argc -= optind;
   argv += optind;
      
   /* If no file arguments left, report and exit */
   if (argc < 1)
   {
      printf("no file specified\n");
      return 0;
   }
      
   /* Print the header if desired. */
   if (header)
   {
      printf("cs[0]\tcs[1]\tcs[2]\tcache(MB)\tdeflate\tshuffle");
      if (timeseries)
	 printf("\t1st_read_ser(us)\tavg_read_ser(us)\n");
      else
	 printf("\t1st_read_hor(us)\tavg_read_hor(us)\n");
   }

#define PREEMPTION .75
      /* Also tried NELEMS of 2500009*/
#define NELEMS 7919
   if (nc_set_chunk_cache(cache, NELEMS, PREEMPTION)) ERR;
   if (nc_open(argv[0], 0, &ncid)) ERR;

   /* Check to make sure that all the dimension information is
    * correct. */
   if (nc_inq_varid(ncid, DATA_VAR_NAME, &varid)) ERR;
   if (nc_inq_dim(ncid, LON_DIMID, name_in, &len)) ERR;
   if (strcmp(name_in, "lon") || len != LON_LEN) ERR;
   if (nc_inq_dim(ncid, LAT_DIMID, name_in, &len)) ERR;
   if (strcmp(name_in, "lat") || len != LAT_LEN) ERR;
   if (nc_inq_dim(ncid, BNDS_DIMID, name_in, &len)) ERR;
   if (strcmp(name_in, "bnds") || len != BNDS_LEN) ERR;
   if (nc_inq_dim(ncid, TIME_DIMID, name_in, &len)) ERR;
   if (strcmp(name_in, "time") || len != TIME_LEN) ERR;
   if (nc_inq_var(ncid, varid, NULL, NULL, &ndims, dimid, NULL)) ERR;
   if (ndims != NDIMS3 || dimid[0] != TIME_DIMID || 
       dimid[1] != LAT_DIMID || dimid[2] != LON_DIMID) ERR;

   /* Get info about the main data var. */
   if (nc_inq_var_chunking(ncid, varid, &storage, cs)) ERR;
   if (nc_inq_var_deflate(ncid, varid, &shuffle, &deflate, 
			  &deflate_level)) ERR;

   if (timeseries)
   {
      /* Read the var as a time series. */
      start[0] = 0;
      start[1] = 0;
      start[2] = 0;
      count[0] = TIME_LEN;
      count[1] = 1;
      count[2] = 1;
      
      /* Read the first timeseries. */
      if (gettimeofday(&start_time, NULL)) ERR;
      if (nc_get_vara_float(ncid, varid, start, count, ts_data)) ERR_RET;
      if (gettimeofday(&end_time, NULL)) ERR;
      if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
      read_1_us = (int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec;

      /* Read all the rest. */
      if (gettimeofday(&start_time, NULL)) ERR;
      for (start[1] = 0; start[1] < LAT_LEN; start[1]++)
	 for (start[2] = 1; start[2] < LON_LEN; start[2]++)
	    if (nc_get_vara_float(ncid, varid, start, count, ts_data)) ERR_RET;
      if (gettimeofday(&end_time, NULL)) ERR;
      if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
      avg_read_us = ((int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec + read_1_us) / 
	 (LAT_LEN * LON_LEN);
   }
   else
   {
      /* Read the data variable in horizontal slices. */
      start[0] = 0;
      start[1] = 0;
      start[2] = 0;
      count[0] = 1;
      count[1] = LAT_LEN;
      count[2] = LON_LEN;

      /* Read (and time) the first one. */
      if (gettimeofday(&start_time, NULL)) ERR;
      if (nc_get_vara_float(ncid, varid, start, count, hor_data)) ERR_RET;
      if (gettimeofday(&end_time, NULL)) ERR;
      if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
      read_1_us = (int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec;

      /* Read (and time) all the rest. */
      if (gettimeofday(&start_time, NULL)) ERR;
      for (start[0] = 1; start[0] < TIME_LEN; start[0]++)
	 if (nc_get_vara_float(ncid, varid, start, count, hor_data)) ERR_RET;
      if (gettimeofday(&end_time, NULL)) ERR;
      if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
      avg_read_us = ((int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec + 
		     read_1_us) / TIME_LEN;
   }

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

   /* Print results. */
   printf("%d\t%d\t%d\t%.1f\t\t%d\t%d\t\t",
	  (int)cs[0], (int)cs[1], (int)cs[2], 
	  (storage == NC_CHUNKED) ? (cache/(float)MEGABYTE) : 0, 
	  deflate, shuffle);
   if (timeseries)
      printf("%d\t\t%d\n", (int)read_1_us, (int)avg_read_us);
   else
      printf("%d\t\t%d\n", (int)read_1_us, (int)avg_read_us);

   return 0;
}
Exemplo n.º 28
0
static int read_product(int ncid, harp_product *product, netcdf_dimensions *dimensions)
{
    int num_dimensions;
    int num_variables;
    int num_attributes;
    int unlim_dim;
    int result;
    int i;

    result = nc_inq(ncid, &num_dimensions, &num_variables, &num_attributes, &unlim_dim);
    if (result != NC_NOERR)
    {
        harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
        return -1;
    }

    for (i = 0; i < num_dimensions; i++)
    {
        netcdf_dimension_type dimension_type;
        char name[NC_MAX_NAME + 1];
        size_t length;

        result = nc_inq_dim(ncid, i, name, &length);
        if (result != NC_NOERR)
        {
            harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
            return -1;
        }

        if (parse_dimension_type(name, &dimension_type) != 0)
        {
            return -1;
        }

        if (dimensions_add(dimensions, dimension_type, length) != i)
        {
            harp_set_error(HARP_ERROR_IMPORT, "duplicate dimensions with name '%s'", name);
            return -1;
        }
    }

    for (i = 0; i < num_variables; i++)
    {
        if (read_variable(product, ncid, i, dimensions) != 0)
        {
            return -1;
        }
    }

    result = nc_inq_att(ncid, NC_GLOBAL, "source_product", NULL, NULL);
    if (result == NC_NOERR)
    {
        if (read_string_attribute(ncid, NC_GLOBAL, "source_product", &product->source_product) != 0)
        {
            return -1;
        }
    }
    else if (result != NC_ENOTATT)
    {
        harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
        return -1;
    }

    result = nc_inq_att(ncid, NC_GLOBAL, "history", NULL, NULL);
    if (result == NC_NOERR)
    {
        if (read_string_attribute(ncid, NC_GLOBAL, "history", &product->history) != 0)
        {
            return -1;
        }
    }
    else if (result != NC_ENOTATT)
    {
        harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
        return -1;
    }

    return 0;
}
Exemplo n.º 29
0
int
dumpmetadata(int ncid, NChdr** hdrp)
{
    int stat,i,j,k;
    NChdr* hdr = (NChdr*)calloc(1,sizeof(NChdr));
    MEMCHECK(hdr,NC_ENOMEM);
    hdr->ncid = ncid;
    hdr->content = ncbytesnew();
    if(hdrp) *hdrp = hdr;

    stat = nc_inq(hdr->ncid,
		  &hdr->ndims,
		  &hdr->nvars,
		  &hdr->ngatts,
		  &hdr->unlimid);
    CHECK(stat);
    if(ncdap3debug > 0) {
        fprintf(stdout,"ncid=%d ngatts=%d ndims=%d nvars=%d unlimid=%d\n",
		hdr->ncid,hdr->ngatts,hdr->ndims,hdr->nvars,hdr->unlimid);
    }
    hdr->gatts = (NCattribute*)calloc(1,hdr->ngatts*sizeof(NCattribute));
    MEMCHECK(hdr->gatts,NC_ENOMEM);
    if(hdr->ngatts > 0)
	fprintf(stdout,"global attributes:\n");
    for(i=0;i<hdr->ngatts;i++) {
	NCattribute* att = &hdr->gatts[i];
        char attname[NC_MAX_NAME];
	nc_type nctype;
	size_t typesize;
        size_t nvalues;

        stat = nc_inq_attname(hdr->ncid,NC_GLOBAL,i,attname);
        CHECK(stat);
	att->name = nulldup(attname);
	stat = nc_inq_att(hdr->ncid,NC_GLOBAL,att->name,&nctype,&nvalues);
        CHECK(stat);
	att->etype = nctypetodap(nctype);
 	typesize = nctypesizeof(att->etype);
	fprintf(stdout,"\t[%d]: name=%s type=%s values(%lu)=",
			i,att->name,nctypetostring(octypetonc(att->etype)),
                        (unsigned long)nvalues);
	if(nctype == NC_CHAR) {
	    size_t len = typesize*nvalues;
	    char* values = (char*)malloc(len+1);/* for null terminate*/
	    MEMCHECK(values,NC_ENOMEM);
	    stat = nc_get_att(hdr->ncid,NC_GLOBAL,att->name,values);
            CHECK(stat);
	    values[len] = '\0';
	    fprintf(stdout," '%s'",values);
	} else {
	    size_t len = typesize*nvalues;
	    char* values = (char*)malloc(len);
	    MEMCHECK(values,NC_ENOMEM);
	    stat = nc_get_att(hdr->ncid,NC_GLOBAL,att->name,values);
            CHECK(stat);
	    for(k=0;k<nvalues;k++) {
		fprintf(stdout," ");
		dumpdata1(octypetonc(att->etype),k,values);
	    }
	}
	fprintf(stdout,"\n");
    }

    hdr->dims = (Dim*)malloc(hdr->ndims*sizeof(Dim));
    MEMCHECK(hdr->dims,NC_ENOMEM);
    for(i=0;i<hdr->ndims;i++) {
	hdr->dims[i].dimid = i;
        stat = nc_inq_dim(hdr->ncid,
	                  hdr->dims[i].dimid,
	                  hdr->dims[i].name,
	                  &hdr->dims[i].size);
        CHECK(stat);
	fprintf(stdout,"dim[%d]: name=%s size=%lu\n",
		i,hdr->dims[i].name,(unsigned long)hdr->dims[i].size);
    }    
    hdr->vars = (Var*)malloc(hdr->nvars*sizeof(Var));
    MEMCHECK(hdr->vars,NC_ENOMEM);
    for(i=0;i<hdr->nvars;i++) {
	Var* var = &hdr->vars[i];
	nc_type nctype;
	var->varid = i;
        stat = nc_inq_var(hdr->ncid,
	                  var->varid,
	                  var->name,
			  &nctype,
			  &var->ndims,
			  var->dimids,
	                  &var->natts);
        CHECK(stat);
	var->nctype = (nctype);
	fprintf(stdout,"var[%d]: name=%s type=%s |dims|=%d",
		i,
		var->name,
		nctypetostring(var->nctype),
		var->ndims);
	fprintf(stdout," dims={");
	for(j=0;j<var->ndims;j++) {
	    fprintf(stdout," %d",var->dimids[j]);
	}
	fprintf(stdout,"}\n");
	var->atts = (NCattribute*)malloc(var->natts*sizeof(NCattribute));
        MEMCHECK(var->atts,NC_ENOMEM);
        for(j=0;j<var->natts;j++) {
	    NCattribute* att = &var->atts[j];
	    char attname[NC_MAX_NAME];
	    size_t typesize;
	    char* values;
	    nc_type nctype;
	    size_t nvalues;
            stat = nc_inq_attname(hdr->ncid,var->varid,j,attname);
	    CHECK(stat);
	    att->name = nulldup(attname);
	    stat = nc_inq_att(hdr->ncid,var->varid,att->name,&nctype,&nvalues);
	    CHECK(stat);
	    att->etype = nctypetodap(nctype);
	    typesize = nctypesizeof(att->etype);
	    values = (char*)malloc(typesize*nvalues);
	    MEMCHECK(values,NC_ENOMEM);
	    stat = nc_get_att(hdr->ncid,var->varid,att->name,values);
            CHECK(stat);
	    fprintf(stdout,"\tattr[%d]: name=%s type=%s values(%lu)=",
			j,att->name,nctypetostring(octypetonc(att->etype)),(unsigned long)nvalues);
	    for(k=0;k<nvalues;k++) {
		fprintf(stdout," ");
		dumpdata1(octypetonc(att->etype),k,values);
	    }
	    fprintf(stdout,"\n");
	}
    }    
    fflush(stdout);
    return NC_NOERR;
}
Exemplo n.º 30
0
int harp_import_global_attributes_netcdf(const char *filename, double *datetime_start, double *datetime_stop,
                                         long dimension[], char **source_product)
{
    char *attr_source_product = NULL;
    harp_scalar attr_datetime_start;
    harp_scalar attr_datetime_stop;
    harp_data_type attr_data_type;
    long attr_dimension[HARP_NUM_DIM_TYPES];
    int result;
    int ncid;
    int i;

    if (datetime_start == NULL && datetime_stop == NULL)
    {
        return 0;
    }

    if (filename == NULL)
    {
        harp_set_error(HARP_ERROR_INVALID_ARGUMENT, "filename is NULL (%s:%u)", __FILE__, __LINE__);
        return -1;
    }

    result = nc_open(filename, 0, &ncid);
    if (result != NC_NOERR)
    {
        harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
        return -1;
    }

    if (verify_product(ncid) != 0)
    {
        nc_close(ncid);
        return -1;
    }

    if (datetime_start != NULL)
    {
        if (nc_inq_att(ncid, NC_GLOBAL, "datetime_start", NULL, NULL) == NC_NOERR)
        {
            if (read_numeric_attribute(ncid, NC_GLOBAL, "datetime_start", &attr_data_type, &attr_datetime_start) != 0)
            {
                nc_close(ncid);
                return -1;
            }

            if (attr_data_type != harp_type_double)
            {
                harp_set_error(HARP_ERROR_IMPORT, "attribute 'datetime_start' has invalid type");
                nc_close(ncid);
                return -1;
            }
        }
        else
        {
            attr_datetime_start.double_data = harp_mininf();
        }
    }

    if (datetime_stop != NULL)
    {
        if (nc_inq_att(ncid, NC_GLOBAL, "datetime_stop", NULL, NULL) == NC_NOERR)
        {
            if (read_numeric_attribute(ncid, NC_GLOBAL, "datetime_stop", &attr_data_type, &attr_datetime_stop) != 0)
            {
                nc_close(ncid);
                return -1;
            }

            if (attr_data_type != harp_type_double)
            {
                harp_set_error(HARP_ERROR_IMPORT, "attribute 'datetime_stop' has invalid type");
                nc_close(ncid);
                return -1;
            }
        }
        else
        {
            attr_datetime_stop.double_data = harp_plusinf();
        }
    }

    if (source_product != NULL)
    {
        if (read_string_attribute(ncid, NC_GLOBAL, "source_product", &attr_source_product) != 0)
        {
            nc_close(ncid);
            return -1;
        }
    }

    if (dimension != NULL)
    {
        int num_dimensions;
        int num_variables;
        int num_attributes;
        int unlim_dim;
        int result;

        for (i = 0; i < HARP_NUM_DIM_TYPES; i++)
        {
            attr_dimension[i] = -1;
        }

        result = nc_inq(ncid, &num_dimensions, &num_variables, &num_attributes, &unlim_dim);
        if (result != NC_NOERR)
        {
            harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
            return -1;
        }

        for (i = 0; i < num_dimensions; i++)
        {
            netcdf_dimension_type netcdf_dim_type;
            harp_dimension_type harp_dim_type;
            char name[NC_MAX_NAME + 1];
            size_t length;

            result = nc_inq_dim(ncid, i, name, &length);
            if (result != NC_NOERR)
            {
                harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
                return -1;
            }

            if (parse_dimension_type(name, &netcdf_dim_type) != 0)
            {
                return -1;
            }
            if (netcdf_dim_type != netcdf_dimension_independent && netcdf_dim_type != netcdf_dimension_string)
            {
                if (get_harp_dimension_type(netcdf_dim_type, &harp_dim_type) != 0)
                {
                    return -1;
                }
                attr_dimension[harp_dim_type] = length;
            }
        }
    }

    result = nc_close(ncid);
    if (result != NC_NOERR)
    {
        harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
        free(attr_source_product);
        return -1;
    }

    if (datetime_start != NULL)
    {
        *datetime_start = attr_datetime_start.double_data;
    }

    if (datetime_stop != NULL)
    {
        *datetime_stop = attr_datetime_stop.double_data;
    }

    if (source_product != NULL)
    {
        *source_product = attr_source_product;
    }

    if (dimension != NULL)
    {
        for (i = 0; i < HARP_NUM_DIM_TYPES; i++)
        {
            dimension[i] = attr_dimension[i];
        }
    }

    return 0;
}