/** @ingroup variables @internal Get the number of record dimensions for a variable and an array that identifies which of a variable's dimensions are record dimensions. Intended to be used instead of NC_is_recvar(), which doesn't work for netCDF-4 variables which have multiple unlimited dimensions or an unlimited dimension that is not the first of a variable's dimensions. @param ncid File ID. @param varid Variable ID. @param nrecdimsp Pointer that gets number of record dims. @param is_recdim Pointer that gets 1 if there is one or more record dimensions, 0 if not. @returns 0 if not a record var, 1 if it is. Example use: @code int nrecdims; int is_recdim[NC_MAX_VAR_DIMS]; ... status = NC_inq_recvar(ncid,varid,&nrecdims,is_recdim); isrecvar = (nrecdims > 0); @endcode */ int NC_inq_recvar(int ncid, int varid, int* nrecdimsp, int *is_recdim) { int status = NC_NOERR; int unlimid; int nvardims; int dimset[NC_MAX_VAR_DIMS]; int dim; int nrecdims = 0; status = nc_inq_varndims(ncid,varid,&nvardims); if(status != NC_NOERR) return status; if(nvardims == 0) return NC_NOERR; /* scalars have no dims */ for(dim = 0; dim < nvardims; dim++) is_recdim[dim] = 0; status = nc_inq_unlimdim(ncid, &unlimid); if(status != NC_NOERR) return status; if(unlimid == -1) return status; /* no unlimited dims for any variables */ #ifdef USE_NETCDF4 { int nunlimdims; int *unlimids; int recdim; status = nc_inq_unlimdims(ncid, &nunlimdims, NULL); /* for group or file, not variable */ if(status != NC_NOERR) return status; if(nunlimdims == 0) return status; if (!(unlimids = malloc(nunlimdims * sizeof(int)))) return NC_ENOMEM; status = nc_inq_unlimdims(ncid, &nunlimdims, unlimids); /* for group or file, not variable */ if(status != NC_NOERR) { free(unlimids); return status; } status = nc_inq_vardimid(ncid, varid, dimset); if(status != NC_NOERR) { free(unlimids); return status; } for (dim = 0; dim < nvardims; dim++) { /* netCDF-4 rec dims need not be first dim for a rec var */ for(recdim = 0; recdim < nunlimdims; recdim++) { if(dimset[dim] == unlimids[recdim]) { is_recdim[dim] = 1; nrecdims++; } } } free(unlimids); } #else status = nc_inq_vardimid(ncid, varid, dimset); if(status != NC_NOERR) return status; if(dimset[0] == unlimid) { is_recdim[0] = 1; nrecdims++; } #endif /* USE_NETCDF4 */ if(nrecdimsp) *nrecdimsp = nrecdims; return status; }
int CONetCDF4::getUnlimitedDimension(void) { int dimid = 0; int grpid = this->getCurrentGroup(); CheckError(nc_inq_unlimdim (grpid, &dimid)); return (dimid); }
void R_nc_inq_unlimdim( int *ncid, int *unlimdimid, int *retval ) { *retval = nc_inq_unlimdim(*ncid, unlimdimid ); if( *retval != NC_NOERR ) REprintf( "Error in R_nc_inq_unlimdim: %s\n", nc_strerror(*retval) ); }
int ncd_wdset(int ncid,char *path,char *name, void *val, \ enum ADIOS_TYPES type, int rank, \ struct adios_bp_dimension_struct *dims) { int i,valid,retval; char fullname[100]; char dimname[100]; fullname[0]='\0'; char *result=NULL; int dimids[2]; dimids[1]=0; strcpy(fullname,name); if(start[0]==0) { retval=nc_redef(ncid); sprintf(dimname,"%s_%d",name,0); retval=nc_inq_unlimdim(ncid,&dimids[1]); if(dimids[1]==-1)retval=nc_def_dim(ncid,"timesteps",NC_UNLIMITED,&dimids[0]); retval=nc_def_dim(ncid,dimname,dims[0].local_bound,&dimids[1]); if(type==adios_real) retval=nc_def_var(ncid,fullname,NC_FLOAT,2,dimids,&valid); if(type==adios_integer) retval=nc_def_var(ncid,fullname,NC_INT,2,dimids,&valid); if(type==adios_long) retval=nc_def_var(ncid,fullname,NC_LONG,2,dimids,&valid); if(type==adios_double) { retval=nc_def_var(ncid,fullname,NC_DOUBLE,2,dimids,&valid); ERR(retval); } //printf("\t RANK=%d, DIMS:%s[0]=%d dimids[1]=%d\n",rank,dimname,dims[0].local_bound,dimids[1]); retval=nc_enddef(ncid); } else retval=nc_inq_varid (ncid, fullname, &valid); start[1]=0;//dims[0].local_bound; count[0]=1; count[1]=dims[0].local_bound; if(type==adios_double) retval=nc_put_vara_double(ncid,valid,start,count,val); if(type==adios_real) retval=nc_put_vara_float(ncid,valid,start,count,val); if(type==adios_integer) retval=nc_put_vara_int(ncid,valid,start,count,val); if(type==adios_long) retval=nc_put_vara_long(ncid,valid,start,count,val); //#if DEBUG //printf("create dataset:%s\n",fullname); //printf("start:%dx%d. count:%dx%d\n",start[0],start[1],count[0],count[1]); //printf("-------------------\n"); //#endif return; }
NcBool NcDim::is_unlimited( void ) const { if (!the_file) return FALSE; int recdim; NcError::set_err( nc_inq_unlimdim(the_file->id(), &recdim) ); return the_id == recdim; }
NcDim* NcFile::rec_dim( ) const { if (! is_valid()) return 0; int recdim; if(NcError::set_err( nc_inq_unlimdim(the_id, &recdim) ) != NC_NOERR) return 0; return get_dim(recdim); }
static int NC3_inq_unlimdims(int ncid, int *ndimsp, int *unlimdimidsp) { int retval; int unlimid; if ((retval = nc_inq_unlimdim(ncid, &unlimid))) return retval; if (unlimid != -1) { if(ndimsp) *ndimsp = 1; if (unlimdimidsp) unlimdimidsp[0] = unlimid; } else if(ndimsp) *ndimsp = 0; return NC_NOERR; }
/*! This function makes a request to netcdf with a netCdf dimension name then return ncid of the named dimension \param [in] ncid Groupd id (or File Id) \param [in/out] dimId Dimension id if this dimension is found \return Status code */ int CNetCdfInterface::inqUnLimDim(int ncid, int& dimId) { int status = nc_inq_unlimdim(ncid, &dimId); if (NC_NOERR != status) { StdString errormsg(nc_strerror(status)); StdStringStream sstr; sstr << "Error when calling function nc_inq_dimid" << std::endl << errormsg << std::endl << "Unable to get id of unlimited dimension " << std::endl; StdString e = sstr.str(); throw CNetCdfException(e); } return status; }
/* * Retrieves the number of record variables, the record variable ids, and the * record size of each record variable. If any pointer to info to be returned * is null, the associated information is not returned. Returns -1 on error. */ int nc_inq_rec( int ncid, size_t *nrecvarsp, int *recvarids, size_t *recsizes) { int status; int nvars = 0; int recdimid; int varid; int rvarids[MAX_NC_VARS]; int nrvars = 0; status = nc_inq_nvars(ncid, &nvars); if(status != NC_NOERR) return status; status = nc_inq_unlimdim(ncid, &recdimid); if(status != NC_NOERR) return status; *nrecvarsp = 0; if (recdimid == -1) return NC_NOERR; status = numrecvars(ncid, &nrvars, rvarids); if(status != NC_NOERR) return status; if (nrecvarsp != NULL) *nrecvarsp = nrvars; if (recvarids != NULL) for (varid = 0; varid < nrvars; varid++) recvarids[varid] = rvarids[varid]; if (recsizes != NULL) for (varid = 0; varid < nrvars; varid++) { size_t rsize; status = ncrecsize(ncid, rvarids[varid], &rsize); if (status != NC_NOERR) return status; recsizes[varid] = rsize; } return NC_NOERR; }
int ncd_wscalar(int ncid,char *path,char *name, void *val, \ enum ADIOS_TYPES type) { int i,valid,retval; char fullname[100]; char dimname[100]; fullname[0]='\0'; char *result=NULL; int dimids[1]; dimids[0]=0; strcpy(fullname,name); if(start[0]==0) { retval=nc_redef(ncid); sprintf(dimname,"%s_%d",name,0); retval=nc_inq_unlimdim(ncid,&dimids[0]); if(dimids[0]==-1)retval=nc_def_dim(ncid,"timesteps",NC_UNLIMITED,&dimids[0]); if(type==adios_real) retval=nc_def_var(ncid,fullname,NC_FLOAT,1,dimids,&valid); else if(type==adios_double) retval=nc_def_var(ncid,fullname,NC_DOUBLE,1,dimids,&valid); else if(type==adios_integer) retval=nc_def_var(ncid,fullname,NC_INT,1,dimids,&valid); else if(type==adios_long) retval=nc_def_var(ncid,fullname,NC_LONG,1,dimids,&valid); retval=nc_enddef(ncid); } else retval=nc_inq_varid (ncid, fullname, &valid); if(type==adios_real) retval=nc_put_vara_float(ncid,valid,start_scalar,count_scalar,val); else if(type==bp_double) retval=nc_put_vara_double(ncid,valid,start_scalar,count_scalar,val); else if(type==adios_integer) retval=nc_put_vara_int(ncid,valid,start_scalar,count_scalar,val); else if(type==adios_long) retval=nc_put_vara_long(ncid,valid,start_scalar,count_scalar,val); ERR(retval); return 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); }
/* * return 1 if varid identifies a record variable * else return 0 */ int isrecvar(int ncid, int varid) { int ndims; int is_recvar = 0; int *dimids; NC_CHECK( nc_inq_varndims(ncid, varid, &ndims) ); #ifdef USE_NETCDF4 if (ndims > 0) { int nunlimdims; int *recdimids; int dim, recdim; dimids = (int *) emalloc((ndims + 1) * sizeof(int)); NC_CHECK( nc_inq_vardimid(ncid, varid, dimids) ); NC_CHECK( nc_inq_unlimdims(ncid, &nunlimdims, NULL) ); recdimids = (int *) emalloc((nunlimdims + 1) * sizeof(int)); NC_CHECK( nc_inq_unlimdims(ncid, NULL, recdimids) ); for (dim = 0; dim < ndims && is_recvar == 0; dim++) { for(recdim = 0; recdim < nunlimdims; recdim++) { if(dimids[dim] == recdimids[recdim]) { is_recvar = 1; break; } } } free(dimids); free(recdimids); } #else if (ndims > 0) { int recdimid; dimids = (int *) emalloc((ndims + 1) * sizeof(int)); NC_CHECK( nc_inq_vardimid(ncid, varid, dimids) ); NC_CHECK( nc_inq_unlimdim(ncid, &recdimid) ); if(dimids[0] == recdimid) is_recvar = 1; free(dimids); } #endif /* USE_NETCDF4 */ return is_recvar; }
/* * Computes number of record variables in an open netCDF file, and an array of * the record variable ids, if the array parameter is non-null. */ static int numrecvars(int ncid, int *nrecvarsp, int *recvarids) { int status; int nvars = 0; int ndims = 0; int nrecvars = 0; int varid; int recdimid; int dimids[MAX_NC_DIMS]; status = nc_inq_nvars(ncid, &nvars); if(status != NC_NOERR) return status; status = nc_inq_unlimdim(ncid, &recdimid); if(status != NC_NOERR) return status; if (recdimid == -1) { *nrecvarsp = 0; return NC_NOERR; } nrecvars = 0; for (varid = 0; varid < nvars; varid++) { status = nc_inq_varndims(ncid, varid, &ndims); if(status != NC_NOERR) return status; status = nc_inq_vardimid(ncid, varid, dimids); if(status != NC_NOERR) return status; if (ndims > 0 && dimids[0] == recdimid) { if (recvarids != NULL) recvarids[nrecvars] = varid; nrecvars++; } } *nrecvarsp = nrecvars; return NC_NOERR; }
/* * Computes record size (in bytes) of the record variable with a specified * variable id. Returns size as 0 if not a record variable. */ static int ncrecsize(int ncid, int varid, size_t *recsizep) { int status; int recdimid; nc_type type; int ndims; int dimids[MAX_NC_DIMS]; int id; size_t size; *recsizep = 0; status = nc_inq_unlimdim(ncid, &recdimid); if(status != NC_NOERR) return status; status = nc_inq_vartype(ncid, varid, &type); if(status != NC_NOERR) return status; status = nc_inq_varndims(ncid, varid, &ndims); if(status != NC_NOERR) return status; status = nc_inq_vardimid(ncid, varid, dimids); if(status != NC_NOERR) return status; if (ndims == 0 || dimids[0] != recdimid) { return NC_NOERR; } size = nctypelen(type); for (id = 1; id < ndims; id++) { size_t len; status = nc_inq_dimlen(ncid, dimids[id], &len); if(status != NC_NOERR) return status; size *= len; } *recsizep = size; return NC_NOERR; }
/* Returns 1 if this var has an unlimited dimension, 0 otherwise */ void R_nc_inq_varunlim( int *ncid, int *varid, int *isunlim, int *retval ) { int i, ndims, unlimdimid, dimids[MAX_NC_DIMS]; /* Get the unlimited dim id */ *retval = nc_inq_unlimdim( *ncid, &unlimdimid ); if( *retval != NC_NOERR ) { REprintf( "Error in R_nc_inq_varunlim while getting unlimdimid: %s\n", nc_strerror(*retval) ); return; } /* Get this var's ndims */ *retval = nc_inq_varndims( *ncid, *varid, &ndims ); if( *retval != NC_NOERR ) { REprintf( "Error in R_nc_inq_varunlim while getting ndims: %s\n", nc_strerror(*retval) ); REprintf( "Using ncid=%d and varid=%d\n", *ncid, *varid ); return; } /* Get this var's dims */ *retval = nc_inq_vardimid( *ncid, *varid, dimids ); if( *retval != NC_NOERR ) { REprintf( "Error in R_nc_inq_varunlim while getting dimids: %s\n", nc_strerror(*retval) ); return; } *isunlim = 0; for( i=0; i<ndims; i++ ) if( dimids[i] == unlimdimid ) { *isunlim = 1; break; } }
int read_field(int fn, int lev, char var_name[], double **array, size_t *nlay, size_t *nx, size_t *ny, double st[2]) { static int ncid; size_t start[MAX_VAR_DIMS] = {0}, count[MAX_VAR_DIMS]; int i, varid, ndims, dimids[MAX_VAR_DIMS], recdim, status; ncid = ncInid[fn]; if (ncid < 0) { printf("ERROR: Required file (%d) for reading %s is not open.\n",fn,var_name); exit(-1); } // printf("Inquire unlimdim of %s - id %d.\n",in_file,ncid); status = nc_inq_unlimdim(ncid,&recdim); if (status != NC_NOERR) handle_error(status,var_name,status); // printf("Done opening %s.\n",in_file); status = nc_inq_varid(ncid,var_name,&varid); if (status != NC_NOERR) handle_error(status,var_name,status); status = nc_inq_varndims(ncid,varid,&ndims); if (status != NC_NOERR) handle_error(status,var_name,status); status = nc_inq_vardimid(ncid,varid,dimids); if (status != NC_NOERR) handle_error(status,var_name,status); // printf("Get %d dim lengths %s.\n",ndims,in_file); for (i=0;i<ndims;i++) { status = nc_inq_dimlen(ncid,dimids[i],&count[i]); if (status != NC_NOERR) handle_error(status,var_name,i); } if (dimids[0] == recdim) { if (count[0] < lev+1) return -1; start[0] = lev; count[0] = 1; } else if (lev > 0) return -1; for (i=ndims-2;i<ndims;i++) { char dimname[NC_MAX_NAME]; int varid; size_t index = 0; status = nc_inq_dimname(ncid,dimids[i],dimname); if (status != NC_NOERR) handle_error(status,var_name,i); status = nc_inq_varid(ncid, dimname, &varid); if (status != NC_NOERR) handle_error(status,dimname,status); status = nc_get_var1_double(ncid, varid, &index, &st[i-ndims+2]); if (status != NC_NOERR) handle_error(status,dimname,status); } // printf("Done getting info about %s.\n",var_name); if (*array == NULL) { size_t sz = 1; for (i=0;i<ndims;i++) if (count[i] > 1) sz *= count[i]+1; // printf("Attempting to allocate array of size %ld.\n",(long) sz); *array = (double *) calloc(sz, sizeof(double)); if (*array == NULL) printf("Unable to allocate array of size %ld for %s.\n",(long) sz,var_name); } *nlay = count[ndims-3]; *nx = count[ndims-1]; *ny = count[ndims-2]; { size_t sz = 1; for (i=0;i<ndims;i++) if (count[i] > 1) sz *= count[i]; // printf("Attempting to read array of size %ld.\n",(long) sz); } status = nc_get_vara_double(ncid,varid,start,count,*array); if (status != NC_NOERR) return -1; return 0; }
/** * Create or open an existing netCdf-file * * If i_baseName appended with the ".nc" extension represents an existing * NetCDF file, the file is opened and it is tried to append to the * file (e.g. open a checkpoint-file of a previously crashed run) * * @param i_baseName base name of the netCDF-file to which the data will be written to. * @param i_nX number of cells in the horizontal direction. * @param i_nY number of cells in the vertical direction. * @param i_dX cell size in x-direction. * @param i_dY cell size in y-direction. * @param i_originX * @param i_originY * @param i_coarseness The coarseness factor * @param i_flush If > 0, flush data to disk every i_flush write operation * @param i_dynamicBathymetry */ io::NetCdfWriter::NetCdfWriter( const std::string &i_baseName, const Float2D &i_b, const BoundarySize &i_boundarySize, int i_nX, int i_nY, float i_dX, float i_dY, float i_originX, float i_originY, float i_coarseness, unsigned int i_flush) : //const bool &i_dynamicBathymetry) : //!TODO io::Writer(i_baseName + ".nc", i_b, i_boundarySize, i_nX, i_nY, i_coarseness), flush(i_flush) { int status; // variables (TODO: add rest of CF-1.5) int l_xVar, l_yVar; // dimensions int l_timeDim, l_xDim, l_yDim; // Try to open the file (to see if it is an existing checkpoint file) status = nc_open(fileName.c_str(), NC_WRITE, &dataFile); if(status == NC_NOERR) { // File exists and is a NetCDF file we can write to // Read ID for time, x, y, h, hu, hv and b dimensions and variables status = nc_inq_unlimdim(dataFile, &l_timeDim); status = nc_inq_dimid(dataFile, "x", &l_xDim); status = nc_inq_dimid(dataFile, "y", &l_yDim); status = nc_inq_varid(dataFile, "time", &timeVar); status = nc_inq_varid(dataFile, "x", &l_xVar); status = nc_inq_varid(dataFile, "y", &l_yVar); status = nc_inq_varid(dataFile, "h", &hVar); status = nc_inq_varid(dataFile, "hu", &huVar); status = nc_inq_varid(dataFile, "hv", &hvVar); status = nc_inq_varid(dataFile, "b", &bVar); // Read Dimensions for x and y variable size_t l_xLen, l_yLen; status = nc_inq_dimlen(dataFile, l_xDim, &l_xLen); status = nc_inq_dimlen(dataFile, l_yDim, &l_yLen); // Set next timeStep status = nc_inq_dimlen(dataFile, l_timeDim, &timeStep); // Check actual dimensions in file against supplied dimensions assert(l_xLen == coarseX); assert(l_yLen == coarseY); } else { // File does not exist or is not a valid NetCDF file //create a netCDF-file, an existing file will be replaced status = nc_create(fileName.c_str(), NC_NETCDF4, &dataFile); //check if the netCDF-file creation constructor succeeded. if (status != NC_NOERR) { assert(false); return; } #ifdef PRINT_NETCDFWRITER_INFORMATION std::cout << " *** io::NetCdfWriter::createNetCdfFile" << std::endl; std::cout << " created/replaced: " << fileName << std::endl; std::cout << " internal dimensions(nx, ny): " << nX << ", " << nY << std::endl; std::cout << " dimensions(nx, ny): " << coarseX << ", " << coarseY << std::endl; std::cout << " coarseness: " << coarseness << std::endl; std::cout << " cell width(dx,dy): " << i_dX << ", " << i_dY << std::endl; std::cout << " origin(x,y): " << i_originX << ", " << i_originY << std::endl; #endif nc_def_dim(dataFile, "time", NC_UNLIMITED, &l_timeDim); nc_def_dim(dataFile, "x", coarseX, &l_xDim); nc_def_dim(dataFile, "y", coarseY, &l_yDim); nc_def_var(dataFile, "time", NC_FLOAT, 1, &l_timeDim, &timeVar); ncPutAttText(timeVar, "long_name", "Time"); ncPutAttText(timeVar, "units", "seconds since simulation start"); // the word "since" is important for the paraview reader nc_def_var(dataFile, "x", NC_FLOAT, 1, &l_xDim, &l_xVar); nc_def_var(dataFile, "y", NC_FLOAT, 1, &l_yDim, &l_yVar); //variables, fastest changing index is on the right (C syntax), will be mirrored by the library int dims[] = {l_timeDim, l_yDim, l_xDim}; nc_def_var(dataFile, "h", NC_FLOAT, 3, dims, &hVar); nc_def_var(dataFile, "hu", NC_FLOAT, 3, dims, &huVar); nc_def_var(dataFile, "hv", NC_FLOAT, 3, dims, &hvVar); nc_def_var(dataFile, "b", NC_FLOAT, 2, &dims[1], &bVar); //set attributes to match CF-1.5 convention ncPutAttText(NC_GLOBAL, "Conventions", "CF-1.5"); ncPutAttText(NC_GLOBAL, "title", "Computed tsunami solution"); ncPutAttText(NC_GLOBAL, "history", "SWE"); ncPutAttText(NC_GLOBAL, "institution", "Technische Universitaet Muenchen, Department of Informatics, Chair of Scientific Computing"); ncPutAttText(NC_GLOBAL, "source", "Bathymetry and displacement data."); ncPutAttText(NC_GLOBAL, "references", "http://www5.in.tum.de/SWE"); ncPutAttText(NC_GLOBAL, "comment", "SWE is free software and licensed under the GNU General Public License. Remark: In general this does not hold for the used input data."); //setup grid size float gridPosition = i_originX + (float).5 * i_dX; for(size_t i = 0; i < coarseX; i++) { nc_put_var1_float(dataFile, l_xVar, &i, &gridPosition); gridPosition += i_dX; } gridPosition = i_originY + (float).5 * i_dY; for(size_t j = 0; j < coarseY; j++) { nc_put_var1_float(dataFile, l_yVar, &j, &gridPosition); gridPosition += i_dY; } } }
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; }
int Ensemble::getTimes(std::string &str) { // reading netcdf files int ncid, dimid, varid, status; size_t recSize, len; size_t index=0; double val ; int retVal=0; std::string begStr; std::string endStr; for( size_t i=0 ; i < member.size() ; ++i ) { if( nc_open( member[i]->getFile().c_str(), 0, &ncid) ) { isInvalid = true; member[i]->state = "could not open file"; continue; } nc_inq_unlimdim(ncid, &dimid) ; if( dimid == -1 ) // try for a regular dimension time nc_inq_dimid(ncid, "time", &dimid); // no unlimited variable found; this is not // neccessarily an error. if( dimid == -1 ) { isNoRec = true; nc_close(ncid); if( sz == 1 ) return 0; // a single file else retVal=4; isInvalid = true; member[i]->state += "missing time dimension"; continue; } if( (status = nc_inq_dimlen(ncid, dimid, &recSize) ) ) { isInvalid = true; member[i]->state = "could not read time dimension"; nc_close(ncid); continue; } if( status == 0 && recSize == 0 ) { // this could be wrong // or just a fixed variable with time dimension defined. isNoRec = true; nc_close(ncid); if( sz == 1 ) return 0; isInvalid = true; member[i]->state = "no time values available"; continue; } if( (status = nc_inq_varid(ncid, "time", &varid) ) ) { isNoRec = true; nc_close(ncid); if( sz == 1 ) return 0; member[i]->state = "missing time variable"; continue; } // reference calendar std::vector<std::string> vs; if( getAttText(ncid, varid, "calendar", vs) ) { // failure member[i]->state = "missing or invalid calendar attribute"; nc_close(ncid); continue; } else // successful reading of calendar member[i]->refDate.setCalendar(vs[0]) ; // reference date if( getAttText(ncid, varid, "units", vs) ) { // failure member[i]->state = "missing or invalid units attribute"; nc_close(ncid); continue; } else { if( vs[0].find("%Y") < std::string::npos ) member[i]->refDate.setFormattedDate(); else member[i]->refDate = vs[0] ; } // time values: fist and last index=0; if( (status = nc_get_var1_double(ncid, varid, &index, &val) ) ) { if( sz > 1 ) { isInvalid = true; member[i]->state = "could not read first time value"; nc_close(ncid); continue; } } // any reasonable values available? nc_type var_type ; status = nc_inq_vartype(ncid, varid, &var_type) ; // return value type is double double fV; int noFill=0; int statusF = nc_inq_var_fill(ncid, varid, &noFill, &fV); if( noFill != 1 && (statusF || val == fV) ) { isInvalid = true; member[i]->state = "first time value equals _FillValue"; nc_close(ncid); continue; } if(member[i]->refDate.isValid(val)) member[i]->setBegin( member[i]->refDate.getDate(val) ); else { isInvalid=true; retVal=5; member[i]->putState("invalid data, found " + hdhC::double2String(val), false); nc_close(ncid); continue; } index=recSize-1; if( (status = nc_get_var1_double(ncid, varid, &index, &val) ) ) { if( sz > 1 ) { isInvalid = true; member[i]->putState("could not read last time value"); nc_close(ncid); } } if( noFill != 1 && (statusF || val == fV) ) { isInvalid = true; member[i]->putState("last time value equals _FillValue"); nc_close(ncid); continue; } if(member[i]->refDate.isValid(val)) member[i]->setEnd( member[i]->refDate.getDate(val) ); else { isInvalid=true; retVal=5; member[i]->putState("invalid data, found " + hdhC::double2String(val), false); } nc_close(ncid); } // any serious conditions if( isInvalid ) { // only files with annotations enablePrintOnlyMarked(); str = getOutput(); if( retVal ) return retVal; else return 3 ; // unspecific error } // get modification times of files for(size_t i=0 ; i < member.size() ; ++i ) member[i]->getModificationTime() ; // sorted vector of pointers of dates sortDate(); return 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; }
void write_output(char out_file[], char in_file[][FILE_NAME_SZ], char depth_file[], size_t nz, char var_names[MAX_VARS][NC_MAX_NAME], char time_names[2][NC_MAX_NAME], char depth_names[2][NC_MAX_NAME], int *num_var, char arglist[]) { int i, j, v; int ncid, nc_den_id, status, ndims, ndim, nvariables, ngatt, recdim; int use_dim[NC_MAX_DIMS]; int dv_id[NC_MAX_DIMS], dim2id[NC_MAX_DIMS], dim2vid[NC_MAX_DIMS]; int dimids[NC_MAX_VAR_DIMS], dd2id[2]; int ddvid[2], dd2vid[2]; int num_att; int use_file[MAX_FILES], max_file; char dim_name[10][NC_MAX_NAME]; char att_name[NC_MAX_NAME]; nc_type xtype; size_t dim_len[NC_MAX_DIMS], ddim_len[2], max_dim_len = 0; status = nc_open(in_file[0],NC_NOWRITE, &ncid); if (status != NC_NOERR) handle_error(status,in_file[0],status); ncInid[0] = ncid; use_file[0] = 1; status = nc_inq(ncid,&ndims,&nvariables,&ngatt,&recdim); if (status != NC_NOERR) handle_error(status,in_file[0],status); strcpy(master_in_file,in_file[0]); for (i=1;i<MAX_FILES;i++) { ncInid[i] = -1; use_file[i] = 0;} for (i=0;i<MAX_FILES;i++) if (strlen(in_file[i]) == 0) break; max_file = i; /* Determine which dimensions need to be created. */ for (i=0;i<ndims;i++) use_dim[i] = 0.0; for (v=0;v<*num_var;v++) { int vin_id, fn = 0, id; for (fn=0;fn<max_file;fn++) { if (ncInid[fn] < 0) { status = nc_open(in_file[fn],NC_NOWRITE, &ncInid[fn]); if (status != NC_NOERR) handle_error(status,in_file[fn],status); } status = nc_inq_varid(ncInid[fn], var_names[v], &vin_id); if (status == NC_NOERR) break; } if (fn==max_file) { printf("ERROR: Unable to find variable %s in any of %d files.\n",var_names[v],max_file); handle_error(status, var_names[v], v); } id = ncInid[fn]; status = nc_inq_var(id, vin_id, att_name, &xtype, &ndim, dimids, &num_att); if (status != NC_NOERR) handle_error(status, var_names[v], v); if (ndim < 2) printf("Variable %s has only 2 dimensions and will be excluded.\n", var_names[v]); else { use_dim[find_dimid(id,dimids[ndim-1],ncid)] = 1; use_dim[find_dimid(id,dimids[ndim-2],ncid)] = 1; if (ndim > 4) { printf("ERROR: Variable %s has %d dimensions. This program only works with up to 4 dimensions.\n", var_names[v],ndim); exit(-1); } if (ndim == 4) { int frecdim; status = nc_inq_unlimdim(id,&frecdim); if (status != NC_NOERR) handle_error(status,"Finding record dimid",status); if (dimids[0] = frecdim) use_dim[recdim] = 1; else { printf("ERROR: Variable %s has 4 non-record dimensions. This program only works with 3 such dimensions.\n", var_names[v]); exit(-1); } } var_file[v] = fn; use_file[fn] = 1; } } // Close any unneeded files. for (i=1;i<max_file;i++) if ((use_file[i] == 0) && (ncInid[i] >= 0)) { nc_close(ncInid[i]); ncInid[i] = -1; } status = nc_create(out_file, 0, &ncOutid); if (status != NC_NOERR) handle_error(status,out_file,status); status = nc_set_fill(ncOutid,NC_NOFILL,&j); if (status != NC_NOERR) handle_error(status,out_file,status); // printf("Created file %s with id %d.\n",out_file,ncOutid); // Copy all of the global attributes over. for (j=0;j<ngatt;j++) { status = nc_inq_attname (ncid, NC_GLOBAL, j, att_name); if (status != NC_NOERR) handle_error(status,"Global",j); status = nc_copy_att(ncid, NC_GLOBAL, att_name, ncOutid, NC_GLOBAL); if (status != NC_NOERR) handle_error(status,att_name,j); } { char hist[1000]; status = nc_get_att_text(ncid, NC_GLOBAL,"history",hist); if (status == NC_NOERR) {strcat(hist,"\n"); strcat(hist,arglist);} else strcpy(hist,arglist); status = nc_put_att_text(ncOutid, NC_GLOBAL,"history",strlen(hist),hist); } // Copy all appropriate dimensions over. for (i=0;i<ndims;i++) if (use_dim[i]) { status = nc_inq_dim(ncid, i, dim_name[i], &dim_len[i]); if (status != NC_NOERR) handle_error(status, "", i); if (dim_len[i] > max_dim_len) max_dim_len = dim_len[i]; if (i==recdim) status = nc_def_dim(ncOutid, dim_name[i], NC_UNLIMITED, &dim2id[i]); else status = nc_def_dim(ncOutid, dim_name[i], dim_len[i], &dim2id[i]); if (status != NC_NOERR) handle_error(status,dim_name[i],i); // Get information about the coordinate variable. status = nc_inq_varid (ncid, dim_name[i], &dv_id[i]); if (status != NC_NOERR) handle_error(status, dim_name[i], i); status = nc_inq_vartype(ncid, dv_id[i], &xtype); if (status != NC_NOERR) handle_error(status, dim_name[i], i); status = nc_inq_varnatts(ncid, dv_id[i], &num_att); if (status != NC_NOERR) handle_error(status,dim_name[i],i); // Create the coordinate variables. status = nc_def_var (ncOutid, dim_name[i], xtype, 1, &dim2id[i], &dim2vid[i]); if (status != NC_NOERR) handle_error(status, dim_name[i],i); // Copy all of the attributes over. for (j=0;j<num_att;j++) { status = nc_inq_attname (ncid, dv_id[i], j, att_name); if (status != NC_NOERR) handle_error(status,att_name,j); status = nc_copy_att(ncid, dv_id[i], att_name, ncOutid, dim2vid[i]); if (status != NC_NOERR) handle_error(status,att_name,j); } } // Copy the vertical dimensions over from depth_file. // if (strlen(depth_file) > 1) status = nc_open(depth_file,NC_NOWRITE, &nc_den_id); if (status != NC_NOERR) handle_error(status,depth_file,status); for (i=0;i<2;i++) { int ddid; status = nc_inq_dimid (nc_den_id, depth_names[i], &ddid); if (status != NC_NOERR) handle_error(status,depth_names[i],0); status = nc_inq_dimlen(nc_den_id, ddid, &ddim_len[i]); if (status != NC_NOERR) handle_error(status,depth_names[i], i); status = nc_def_dim(ncOutid, depth_names[i], ddim_len[i], &dd2id[i]); if (status != NC_NOERR) handle_error(status,depth_names[i],i); // Get information about the coordinate variable. status = nc_inq_varid (nc_den_id, depth_names[i], &ddvid[i]); if (status != NC_NOERR) handle_error(status, depth_names[i], i); status = nc_inq_vartype(nc_den_id, ddvid[i], &xtype); if (status != NC_NOERR) handle_error(status, depth_names[i], i); status = nc_inq_varnatts(nc_den_id, ddvid[i], &num_att); if (status != NC_NOERR) handle_error(status,depth_names[i],i); // Create the coordinate variables. status = nc_def_var (ncOutid, depth_names[i], xtype, 1, &dd2id[i], &dd2vid[i]); if (status != NC_NOERR) handle_error(status, depth_names[i],i); // Copy all of the attributes over. for (j=0;j<num_att;j++) { status = nc_inq_attname (nc_den_id, ddvid[i], j, att_name); if (status != NC_NOERR) handle_error(status,att_name,j); status = nc_copy_att(nc_den_id, ddvid[i], att_name, ncOutid, dd2vid[i]); if (status != NC_NOERR) handle_error(status,att_name,j); } } // Create the auxiliary time variable (if it exists) and store the time indices. if (recdim != -1) { // If there is a record dimension, it must be one of the two named // time dimensions. If none are named, the name of the record // dimension is copied into it. if ((strcmp(dim_name[recdim],time_names[0]) != 0) && (strcmp(dim_name[recdim],time_names[1]) != 0)) { if (strlen(time_names[0]) == 0) strcpy(time_names[0],dim_name[recdim]); else if (strlen(time_names[1]) == 0) strcpy(time_names[1],dim_name[recdim]); else { printf("ERROR: The specified time variables %s and %s do not agree\n" "\twith the record variable, %s.\n",time_names[0],time_names[1], dim_name[recdim]); exit(-1); } } } for (v=0;v<2;v++) { status = nc_inq_varid(ncOutid, time_names[v], &time_out_id[v]); if (status != NC_NOERR) { if (strlen(time_names[v]) > 0) { int out_dim; status = nc_inq_varid(ncid, time_names[v], &time_in_id[v]); if (status != NC_NOERR) handle_error(status, time_names[v], v); status = nc_inq_var(ncid, time_in_id[v], att_name, &xtype, &ndim, dimids, &num_att); if (status != NC_NOERR) handle_error(status, time_names[v], v); if (ndim > 1) { printf("ERROR: Time variable %s has %d dimensions in %s.\n",time_names[v],ndim,in_file[0]); exit(-1); } out_dim = dim2id[dimids[0]]; status = nc_def_var(ncOutid, time_names[v], xtype, ndim, &out_dim, &time_out_id[v]); if (status != NC_NOERR) handle_error(status, time_names[v],v); // Copy all of the attributes over. for (j=0;j<num_att;j++) { status = nc_inq_attname(ncid, time_in_id[v], j, att_name); if (status != NC_NOERR) handle_error(status,att_name,j); status = nc_copy_att(ncid, time_in_id[v], att_name, ncOutid, time_out_id[v]); if (status != NC_NOERR) handle_error(status,att_name,j); } } } else { status = nc_inq_varid(ncid, time_names[v], &time_in_id[v]); if (status != NC_NOERR) handle_error(status, time_names[v], v); } } // Create the output variables, while checking the validity of the list. for (v=0;v<*num_var;v++) { int id, vin_id, frecdim, valid = 1; for (i=0;i<2;i++) if (strcmp(var_names[v],time_names[i])==0) valid = 0; for (i=0;i<ndims;i++) if (strcmp(var_names[v],dim_name[i])==0) valid = 0; for (i=0;i<2;i++) if (strcmp(var_names[v],depth_names[i])==0) valid = 0; if (valid) { id = ncInid[var_file[v]]; if (var_file[v] == 0) frecdim = recdim; else { status = nc_inq_unlimdim(id,&frecdim); if (status != NC_NOERR) handle_error(status,"Finding record dimid",status); } status = nc_inq_varid(id, var_names[v], &vin_id); if (status != NC_NOERR) handle_error(status, var_names[v], v); status = nc_inq_var(id, vin_id, att_name, &xtype, &ndim, dimids, &num_att); if (status != NC_NOERR) handle_error(status, var_names[v], v); if (ndim <= 2) { printf("Variable %s has only 2 dimensions and will be excluded.\n", var_names[v]); valid = 0; } else if ((ndim == 3) && (dimids[0] == frecdim)) { printf("Variable %s uses the record dimension as 3rd dimension and will be excluded.\n", var_names[v]); valid = 0; } } if (valid) { // Get information about the variable. int out_dimids[4]; if (dimids[0] != frecdim) { out_dimids[0] = dd2id[0]; var_count[v][0] = ddim_len[0]; static_var[v] = 1; i = 1; } else { out_dimids[0] = dim2id[recdim]; out_dimids[1] = dd2id[0]; var_count[v][0] = 1; var_count[v][1] = ddim_len[0]; static_var[v] = 0; i = 2; } var_size[v] = ddim_len[0]; for (;i<ndim;i++) { int did; did = find_dimid(id,dimids[i],ncid); out_dimids[i] = dim2id[did]; var_count[v][i] = dim_len[did]; var_size[v] *= var_count[v][i]; } status = nc_def_var(ncOutid, var_names[v], xtype, ndim, out_dimids, &var_id[v]); if (status != NC_NOERR) handle_error(status, var_names[v],v); // Copy all of the attributes over. for (j=0;j<num_att;j++) { status = nc_inq_attname(id, vin_id, j, att_name); if (status != NC_NOERR) handle_error(status,att_name,j); status = nc_copy_att(id, vin_id, att_name, ncOutid, var_id[v]); if (status != NC_NOERR) handle_error(status,att_name,j); } status = nc_get_att_double(id, vin_id,"missing_value",&missing_val[v]); if (status != NC_NOERR) { missing_val[v] = -1.0e34; status = nc_put_att_double(ncOutid,var_id[v],"missing_value",xtype,1,&missing_val[v]); if (status != NC_NOERR) handle_error(status,"missing_value",v); } } else { for (i=v;i<*num_var-1;i++) strcpy(var_names[i],var_names[i+1]); (*num_var)--; v--; } } status = nc_enddef(ncOutid); if (status != NC_NOERR) handle_error(status,out_file,status); // printf("Finished define mode for %s.\n",out_file); /* // Create the vertical coordinates. // status = nc_def_dim(ncOutid, zc_name, nz, &layerid); if (status != NC_NOERR) handle_error(status,zc_name,0); status = nc_def_var (ncOutid, zc_name, NC_DOUBLE, 1, &layerid, &layervid); if (status != NC_NOERR) handle_error(status,zc_name,0); status = nc_def_dim(ncOutid, ze_name, (size_t) (nz+1), &intid); if (status != NC_NOERR) handle_error(status,ze_name,0); status = nc_def_var (ncOutid, ze_name, NC_DOUBLE, 1, &intid, &intvid); if (status != NC_NOERR) handle_error(status,ze_name,0); status = nc_put_att_text(ncOutid, intvid, "units", 2, "m"); if (status != NC_NOERR) handle_error(status,"Units Interface",0); dims[0] = layervid; { strcpy(att[0][0],"long_name"); strcpy(att[0][1],"Depth of Layer Center"); // strcpy(att[1][0],"units"); strcpy(att[1][1],"m"); strcpy(att[1][0],"units"); strcpy(att[1][1],"cm"); strcpy(att[2][0],"positive"); strcpy(att[2][1],"down"); strcpy(att[3][0],"edges"); strcpy(att[2][1],ze_name); for (j=0;j<=2;j++) { status = nc_put_att_text(ncOutid, layervid, att[j][0], strlen(att[j][1]), att[j][1]); if (status != NC_NOERR) handle_error(status,att[j][0],j); } strcpy(att[0][0],"long_name"); strcpy(att[0][1],"Depth of edges"); // strcpy(att[1][0],"units"); strcpy(att[1][1],"m"); strcpy(att[1][0],"units"); strcpy(att[1][1],"cm"); strcpy(att[2][0],"positive"); strcpy(att[2][1],"down"); for (j=0;j<=2;j++) { status = nc_put_att_text(ncOutid, intvid, att[j][0], strlen(att[j][1]), att[j][1]); if (status != NC_NOERR) handle_error(status,att[j][0],j); } } */ // Copy the axis values from the first file. { double *coord_array; coord_array = malloc(sizeof(double)*(max_dim_len)); for (i=0;i<ndims;i++) if (use_dim[i] && (i!=recdim)) { status = nc_get_var_double(ncid,dv_id[i],coord_array); if (status != NC_NOERR) handle_error(status,"Read Coordinate Variable",i); status = nc_put_var_double(ncOutid,dim2vid[i],coord_array); if (status != NC_NOERR) handle_error(status,"Write Coordinate Variable",i); } // Copy the vertical axis values from the depth file. for (i=0;i<2;i++) { status = nc_get_var_double(nc_den_id,ddvid[i],coord_array); if (status != NC_NOERR) handle_error(status,"Read Coordinate Variable",i); status = nc_put_var_double(ncOutid,dd2vid[i],coord_array); if (status != NC_NOERR) handle_error(status,"Write Coordinate Variable",i); } free(coord_array); } /* { double *z; z = (double *) calloc((size_t) (nz+1), sizeof(double)); for (i=0;i<=nz;i++) z[i] = (-100.0)*int_depth[i]; status = nc_put_var_double(ncOutid,intid,z); if (status != NC_NOERR) handle_error(status,"Interface Coordinate",0); for (i=0;i<nz;i++) z[i] = (-100.0)*lay_depth[i]; status = nc_put_var_double(ncOutid,layerid,z); if (status != NC_NOERR) handle_error(status,"Layer Coordinate",0); } */ nc_close(nc_den_id); }