/** @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; }
std::vector<std::string> CONetCDF4::getDimensionsIdList (const std::string * _varname) { char full_name_in[NC_MAX_NAME +1]; int nbdim = 0, *dimid = NULL; int grpid = this->getCurrentGroup(); int varid = (_varname != NULL) ? this->getVariable(*_varname) : NC_GLOBAL; std::vector<std::string> retvalue; if (_varname != NULL) { CheckError(nc_inq_varndims(grpid, varid, &nbdim)); dimid = new int[nbdim](); CheckError(nc_inq_vardimid(grpid, varid, dimid)); } else { CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1)); dimid = new int[nbdim](); CheckError(nc_inq_dimids(grpid, NULL, dimid, 1)); } for (int i = 0; i < nbdim; i++) { CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in)); std::string dimname(full_name_in); retvalue.push_back(dimname); } delete [] dimid; return (retvalue); }
/* * Retrieves the dimension sizes of a variable with a specified variable id in * an open netCDF file. Returns -1 on error. */ static int dimsizes(int ncid, int varid, size_t *sizes) { int status; int ndims; int id; int dimids[MAX_NC_DIMS]; 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 || sizes == NULL) return NC_NOERR; for (id = 0; id < ndims; id++) { size_t len; status = nc_inq_dimlen(ncid, dimids[id], &len); if(status != NC_NOERR) return status; sizes[id] = len; } return NC_NOERR; }
int NCdataGetCoreVarId(int ncid) { int status; int varid, nvars, ndims; int dimid[4], xdim = NCundefined, ydim = NCundefined, i, j; if ((status = nc_inq_nvars(ncid, &nvars)) != NC_NOERR) { NCprintNCError (status, "NCdataGetGridVarId"); return (NCfailed); } if (((xdim = NCdataGetCDimId(ncid)) == NCfailed) && (((xdim = NCdataGetXDimId(ncid)) == NCfailed) || ((ydim = NCdataGetYDimId(ncid)) == NCfailed))) return (NCfailed); for (varid = 0; varid < nvars; ++varid) { if ((status = nc_inq_varndims(ncid, varid, &ndims)) != NC_NOERR) { NCprintNCError (status, "NCdataGetGridVarId"); return (NCfailed); } if ((ndims < 1) || (ndims > 4)) continue; if ((status = nc_inq_vardimid(ncid, varid, dimid)) != NC_NOERR) { NCprintNCError (status, "NCdataGetGridVarId"); return (NCfailed); } for (i = 0; i < ndims; ++i) if (xdim == dimid[i]) { if (ydim == NCundefined) return (varid); for (j = 0; j < ndims; ++j) if (ydim == dimid[j]) return (varid); } } return (NCfailed); }
/********************************************************************* void mpp_get_var_dimname(int fid, int vid, int i, char *name) For each dimension we are assuming there is a 1-d field have the same name as the dimension. *********************************************************************/ void mpp_get_var_dimname(int fid, int vid, int ind, char *name) { int status, ncid, fldid, ndims, dims[4]; char errmsg[512]; if(fid<0 || fid >=nfiles) mpp_error("mpp_io(mpp_get_var_dimname): invalid fid number, fid should be " "a nonnegative integer that less than nfiles"); if(vid<0 || vid >=files[fid].nvar) mpp_error("mpp_io(mpp_get_var_dimname): invalid vid number, vid should be " "a nonnegative integer that less than nvar"); ncid = files[fid].ncid; fldid = files[fid].var[vid].fldid; status = nc_inq_varndims(ncid, fldid, &ndims); if(status != NC_NOERR) { sprintf(errmsg, "mpp_io(mpp_get_var2D_dimname): Error in getting ndims of var %s from file %s", files[fid].var[vid].name, files[fid].name ); netcdf_error(errmsg, status); } if(ind < 0 || ind >= ndims) mpp_error("mpp_io(mpp_get_var_dimname): invalid ind value, ind should be between 0 and ndim-1"); status = nc_inq_vardimid(ncid,fldid,dims); if(status != NC_NOERR) { sprintf(errmsg, "mpp_io(mpp_get_var2D_dimname): Error in getting dimid of var %s from file %s", files[fid].var[vid].name, files[fid].name ); netcdf_error(errmsg, status); } status = nc_inq_dimname(ncid, dims[ind], name); if(status != NC_NOERR) { sprintf(errmsg, "mpp_io(mpp_get_var2D_dimname): Error in getting %d dimension name of var %s from file %s", ind, files[fid].var[vid].name, files[fid].name ); netcdf_error(errmsg, status); } }; /* mpp_get_var_dimname */
void bi::MCMCNetCDFBuffer::map() { std::vector<int> dimids; llVar = nc_inq_varid(ncid, "loglikelihood"); BI_ERROR_MSG(llVar >= 0, "No variable loglikelihood in file " << file); dimids = nc_inq_vardimid(ncid, llVar); BI_ERROR_MSG(dimids.size() == 1u, "Variable loglikelihood has " << dimids.size() << " dimensions, should have 1, in file " << file); BI_ERROR_MSG(dimids[0] == npDim, "Only dimension of variable loglikelihood should be np, in file " << file); lpVar = nc_inq_varid(ncid, "logprior"); BI_ERROR_MSG(lpVar >= 0, "No variable logprior in file " << file); dimids = nc_inq_vardimid(ncid, lpVar); BI_ERROR_MSG(dimids.size() == 1u, "Variable logprior has " << dimids.size() << " dimensions, should have 1, in file " << file); BI_ERROR_MSG(dimids[0] == npDim, "Only dimension of variable logprior should be np, in file " << file); }
void bi::ParticleFilterNetCDFBuffer::map() { std::vector<int> dimids; aVar = nc_inq_varid(ncid, "ancestor"); BI_ERROR_MSG(aVar >= 0, "No variable ancestor in file " << file); dimids = nc_inq_vardimid(ncid, aVar); if (schema == FLEXI) { BI_ERROR_MSG(dimids.size() == 1u, "Variable ancestor has " << dimids.size() << " dimensions, should have 1, in file " << file); BI_ERROR_MSG(dimids[0] == nrpDim, "Only dimension of variable ancestor should be nrp, in file " << file); } else { BI_ERROR_MSG(dimids.size() == 2u, "Variable ancestor has " << dimids.size() << " dimensions, should have 2, in file " << file); BI_ERROR_MSG(dimids[0] == nrDim, "First dimension of variable ancestor should be nr, in file " << file); BI_ERROR_MSG(dims[1] == npDim, "Second dimension of variable ancestor should be np, in file " << file); } lwVar = nc_inq_varid(ncid, "logweight"); BI_ERROR_MSG(lwVar >= 0, "No variable logweight in file " << file); dimids = nc_inq_vardimid(ncid, lwVar); if (schema == FLEXI) { BI_ERROR_MSG(dimids.size() == 1u, "Variable logweight has " << dimids.size() << " dimensions, should have 1, in file " << file); BI_ERROR_MSG(dimids[0] == nrpDim, "Only dimension of variable logweight should be nrp, in file " << file); } else { BI_ERROR_MSG(dimids.size() == 2u, "Variable logweight has " << dimids.size() << " dimensions, should have 2, in file " << file); BI_ERROR_MSG(dimids[0] == nrDim, "First dimension of variable logweight should be nr, in file " << file); BI_ERROR_MSG(dimids[1] == npDim, "Second dimension of variable logweight should be np, in file " << file); } llVar = nc_inq_varid(ncid, "loglikelihood"); BI_ERROR_MSG(llVar >= 0, "No variable loglikelihood in file " << file); dimids = nc_inq_vardimid(ncid, llVar); BI_ERROR_MSG(dimids.size() == 0u, "Variable loglikelihood has " << dimids.size() << " dimensions, should have 0, in file " << file); }
/* * 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; }
void bi::SMCNetCDFBuffer::map() { std::vector<int> dimids; lwVar = nc_inq_varid(ncid, "logweight"); BI_ERROR_MSG(lwVar >= 0, "No variable logweight in file " << file); dimids = nc_inq_vardimid(ncid, lwVar); BI_ERROR_MSG(dimids.size() == 1, "Variable logweight has " << dimids.size() << " dimensions, should have 1, in file " << file); BI_ERROR_MSG(dimids[0] == npDim, "Only dimension of variable logweight should be np, in file " << file); }
/* Initialize iteration for a variable. Just a wrapper for * nc_blkio_init() that makes the netCDF calls needed to initialize * lower-level iterator. */ int nc_get_iter(int ncid, int varid, size_t bufsize, /* size in bytes of memory buffer */ nciter_t **iterpp /* returned opaque iteration state */) { int stat = NC_NOERR; nciter_t *iterp; nc_type vartype; size_t value_size = 0; /* size in bytes of each variable element */ int ndims; /* number of dimensions for variable */ int *dimids; long long nvalues = 1; int dim; int chunked = 0; /* Caller should free this by calling nc_free_iter(iterp) */ iterp = (nciter_t *) emalloc(sizeof(nciter_t)); memset((void*)iterp,0,sizeof(nciter_t)); /* make sure it is initialized */ NC_CHECK(nc_inq_varndims(ncid, varid, &ndims)); dimids = (int *) emalloc((ndims + 1) * sizeof(int)); iterp->dimsizes = (size_t *) emalloc((ndims + 1) * sizeof(size_t)); iterp->chunksizes = (size_t *) emalloc((ndims + 1) * sizeof(size_t)); NC_CHECK(nc_inq_vardimid (ncid, varid, dimids)); for(dim = 0; dim < ndims; dim++) { size_t len; NC_CHECK(nc_inq_dimlen(ncid, dimids[dim], &len)); nvalues *= len; iterp->dimsizes[dim] = len; } NC_CHECK(nc_inq_vartype(ncid, varid, &vartype)); NC_CHECK(inq_value_size(ncid, vartype, &value_size)); #ifdef USE_NETCDF4 { int contig = 1; if(ndims > 0) { NC_CHECK(nc_inq_var_chunking(ncid, varid, &contig, NULL)); } if(contig == 0) { /* chunked */ NC_CHECK(nc_inq_var_chunking(ncid, varid, &contig, iterp->chunksizes)); chunked = 1; } } #endif /* USE_NETCDF4 */ NC_CHECK(nc_blkio_init(bufsize, value_size, ndims, chunked, iterp)); iterp->to_get = 0; free(dimids); *iterpp = iterp; return stat; }
int read_axes(char var_name[], double **array, size_t *nz, size_t *nx, size_t *ny) { size_t count[MAX_VAR_DIMS]; int ncid, i, varid, ndims, dimids[MAX_VAR_DIMS], status; char dimname[NC_MAX_NAME]; ncid = ncInid[0]; if (ncid < 0) { printf("ERROR: Required file (%d) for reading axes of %s is not open.\n",0,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); if (ndims < 3) { printf("ERROR: Unable to determine array sizes from %d-D field %s in file 0.\n", ndims, var_name); return -1; } 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); } *nz = count[ndims-3]; *ny = count[ndims-2]; *nx = count[ndims-1]; // printf("Done getting info about %s.\n",var_name); if (*array == NULL) { *array = (double *) calloc(*nz, sizeof(double)); if (*array == NULL) printf("Unable to allocate array of size %ld for %s.\n",(long) *nz,var_name); } status = nc_inq_dimname(ncid,dimids[ndims-3],dimname); if (status != NC_NOERR) handle_error(status,var_name,dimids[ndims-3]); status = nc_inq_varid(ncid, dimname, &varid); if (status != NC_NOERR) handle_error(status,dimname,status); status = nc_get_var_double(ncid,varid,*array); if (status != NC_NOERR) handle_error(status,dimname,status); if (status != NC_NOERR) return -1; return 0; }
void bi::OptimiserNetCDFBuffer::map() { std::string name; std::vector<int> dimids; /* function value variable */ valueVar = nc_inq_varid(ncid, "optimiser.value"); BI_ERROR_MSG(valueVar >= 0, "No variable optimiser.value in file " << file); dimids = nc_inq_vardimid(ncid, valueVar); BI_ERROR_MSG(dimids.size() == 1, "Variable optimiser.value has " << dimids.size() << " dimensions, should have 1, in file " << file); BI_ERROR_MSG(dimids[0] == npDim, "Only dimension of variable optimiser.value should be np, in file " << file); /* size variable */ sizeVar = nc_inq_varid(ncid, "optimiser.size"); BI_ERROR_MSG(sizeVar >= 0, "No variable optimiser.size in file " << file); dimids = nc_inq_vardimid(ncid, sizeVar); BI_ERROR_MSG(dimids.size() == 1, "Variable optimiser.size has " << dimids.size() << " dimensions, should have 1, in file " << file); BI_ERROR_MSG(dimids[0] == npDim, "Only dimension of variable optimiser.size should be np, in file " << file); }
int bi::InputNetCDFBuffer::mapCoordDim(int ncVar) { int ncDim, j = 0; /* check dimensions */ std::vector<int> dimids = nc_inq_vardimid(ncid, ncVar); ncDim = dimids[j]; if (ncDim >= 0 && ncDim == nsDim) { ncDim = dimids[j++]; } BI_ERROR_MSG(ncDim >= 0 && dimids.size() <= 3, "Coordinate variable " << nc_inq_varname(ncid, ncVar) << " has invalid dimensions, must have optional ns dimension followed by one or two arbitrary dimensions"); return ncDim; }
/** \internal \ingroup variables Get the shape of a variable. */ int NC_getshape(int ncid, int varid, int ndims, size_t* shape) { int dimids[NC_MAX_VAR_DIMS]; int i; int status = NC_NOERR; if ((status = nc_inq_vardimid(ncid, varid, dimids))) return status; for(i = 0; i < ndims; i++) if ((status = nc_inq_dimlen(ncid, dimids[i], &shape[i]))) break; return status; }
/*! This function makes a request to netcdf, returns a list of dimension ID describing the shape of the variable, given its id \param [in] ncid Groupd id (or File Id) \param [in] varId Id of variable \param [in/out] dimIds list of dimension of the variable \return Status code */ int CNetCdfInterface::inqVarDimId(int ncid, int varId, int* dimIds) { int status = nc_inq_vardimid(ncid, varId, dimIds); if (NC_NOERR != status) { StdString errormsg(nc_strerror(status)); StdStringStream sstr; sstr << "Error when calling function nc_inq_vardimid(ncid, varId, dimIds)" << std::endl << errormsg << std::endl << "Unable to get list of dimension id of the variable with id " << varId << std::endl; StdString e = sstr.str(); throw CNetCdfException(e); } return status; }
static int _NCtableVarLen(int ncid, int varid, int dimid, int *dimids) { int status, ndims, i, len = 1; size_t dimlen; if((status = nc_inq_varndims (ncid,varid,&ndims)) != NC_NOERR) { NCprintNCError (status,"_NCtableVarCheck"); return (NCfailed); } if((status = nc_inq_vardimid (ncid,varid,dimids)) != NC_NOERR) { NCprintNCError (status,"_NCtableVarCheck"); return (NCfailed); } if(dimids[0] != dimid) return (NCfailed); for(i = 1; i < ndims; i++) { if((status = nc_inq_dimlen(ncid,dimids [i],&dimlen)) != NC_NOERR) { NCprintNCError (status,"_NCtableVarCheck"); return (NCfailed); } len = len * dimlen; } return (len); }
/** @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); }
/* * 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; }
void bi::InputNetCDFBuffer::readTime(int ncVar, const long start, size_t* const len, real* const t) { /* pre-condition */ BI_ASSERT(start >= 0); BI_ASSERT(len != NULL); BI_ASSERT(t != NULL); std::vector<size_t> offsets(2), counts(2); std::vector<int> dimids = nc_inq_vardimid(ncid, ncVar); real tnxt; int j = 0; size_t T; if (nsDim >= 0 && dimids[j] == nsDim) { /* optional ns dimension */ offsets[j] = ns; counts[j] = 1; ++j; } BI_ASSERT(j < static_cast<int>(dimids.size())); T = nc_inq_dimlen(ncid, dimids[j]); offsets[j] = start; counts[j] = 1; //++j; // not here, need to hold ref to last offset /* may be multiple records with same time, keep reading until time changes */ *len = 0; *t = 0.0; tnxt = 0.0; while (*t == tnxt && offsets[j] < T) { nc_get_vara(ncid, ncVar, offsets, counts, &tnxt); if (*len == 0) { *t = tnxt; } if (tnxt == *t) { ++offsets[j]; ++(*len); } } }
std::vector<std::size_t> CONetCDF4::getDimensions(const std::string & varname) { std::size_t size = 0; std::vector<std::size_t> retvalue; int grpid = this->getCurrentGroup(); int varid = this->getVariable(varname); int nbdim = 0, *dimid = NULL; CheckError(nc_inq_varndims(grpid, varid, &nbdim)); dimid = new int[nbdim](); CheckError(nc_inq_vardimid(grpid, varid, dimid)); for (int i = 0; i < nbdim; i++) { CheckError(nc_inq_dimlen (grpid, dimid[i], &size)); if (size == NC_UNLIMITED) size = UNLIMITED_DIM; retvalue.push_back(size); } return (retvalue); }
/******************************************************************************* * Internal utility function to get the vector of the variable's dim sizes. * Returns 0 on success, -1 if an error is encountered. */ int R_ncu_get_varsize( int ncid, int varid, int ndims, size_t *varsize ) { int ierr, i, dimids[MAX_NC_DIMS]; size_t len; ierr = nc_inq_vardimid( ncid, varid, dimids ); if( ierr != NC_NOERR ) { error( "Internal error in ncdf package, routine R_ncu_get_varsize: error while reading file to get var's dimids!\n" ); return(-1); } for( i=0; i<ndims; i++ ) { ierr = nc_inq_dimlen( ncid, dimids[i], &len ); if( ierr != NC_NOERR ) { error( "Internal error in ncdf package, routine R_ncu_get_varsize: error while reading file to get dim's length!\n" ); return(-1); } varsize[i] = len; } return(0); }
/* * 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 a vector of dim sizes for the variable */ void R_nc_varsize( int *ncid, int *varid, int *varsize, int *retval ) { int i, err, ndims, dimid[NC_MAX_DIMS]; size_t dimlen; *retval = 0; /* Get ndims */ err = nc_inq_varndims( *ncid, *varid, &ndims ); if( err != NC_NOERR ) { REprintf( "Error in R_nc_varsize on nc_inq_varndims call: %s\n", nc_strerror(err) ); *retval = -1; return; } /* Get dimids */ err = nc_inq_vardimid( *ncid, *varid, dimid ); if( err != NC_NOERR ) { REprintf( "Error in R_nc_varsize on nc_inq_vardimid call: %s\n", nc_strerror(err) ); *retval = -1; return; } /* Get size of each dim */ for( i=0; i<ndims; i++ ) { err = nc_inq_dimlen( *ncid, dimid[i], &dimlen ); if( err != NC_NOERR ) { REprintf( "Error in R_nc_varsize on nc_inq_dimlen call: %s\n", nc_strerror(err) ); *retval = -1; return; } varsize[i] = (int)dimlen; } }
/* 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 main(int argc,char *argv[]) { struct DataMap *ptr; struct DataMapScalar *sx,*sy; struct DataMapArray *ax,*ay; size_t index[256]; size_t start[256]; size_t count[256]; int s; unsigned char vbflg=0; unsigned char help=0; unsigned char option=0; unsigned char zflg=0; FILE *fp=NULL; gzFile zfp=0; FILE *mapfp; int n,c,x; int ncid; int block=0; int varid; int strsze; char **strptr; char *tmpbuf=NULL; OptionAdd(&opt,"-help",'x',&help); OptionAdd(&opt,"-option",'x',&option); OptionAdd(&opt,"vb",'x',&vbflg); OptionAdd(&opt,"z",'x',&zflg); if (argc>1) { arg=OptionProcess(1,argc,argv,&opt,NULL); if (help==1) { OptionPrintInfo(stdout,hlpstr); exit(0); } if (option==1) { OptionDump(stdout,&opt); exit(0); } if (zflg) { zfp=gzopen(argv[arg],"r"); if (zfp==0) { fprintf(stderr,"File not found.\n"); exit(-1); } } else { fp=fopen(argv[arg],"r"); if (fp==NULL) { fprintf(stderr,"File not found.\n"); exit(-1); } } } else { OptionPrintInfo(stdout,errstr); exit(-1); } /* load the map */ mapfp=fopen(argv[arg+1],"r"); loadmap(mapfp); fclose(mapfp); s=nc_open(argv[arg+2],NC_WRITE,&ncid); if (s !=NC_NOERR) { fprintf(stderr,"Error opening CDF file.\n"); exit(-1); } block=0; while (1) { if (zflg) ptr=DataMapReadZ(zfp); else ptr=DataMapFread(fp); if (ptr==NULL) break; for (c=0;c<ptr->snum;c++) { sx=ptr->scl[c]; for (n=0;n<snum;n++) { sy=sptr[n]; if (strcmp(sx->name,sy->name) !=0) continue; if (sx->type !=sy->type) continue; break; } if (n !=snum) { /* mapped variable */ s=nc_inq_varid(ncid,cdfsname[n],&varid); if (s !=NC_NOERR) { fprintf(stderr,"Error accessing CDF file.\n"); exit(-1); } index[0]=block; switch (sx->type) { case DATACHAR: s=nc_put_var1_text(ncid,varid,index,sx->data.cptr); break; case DATASHORT: s=nc_put_var1_short(ncid,varid,index,sx->data.sptr); break; case DATAINT: s=nc_put_var1_int(ncid,varid,index,sx->data.iptr); break; case DATAFLOAT: s=nc_put_var1_float(ncid,varid,index,sx->data.fptr); break; case DATADOUBLE: s=nc_put_var1_double(ncid,varid,index,sx->data.dptr); break; case DATASTRING: start[0]=block; start[1]=0; count[0]=1; count[1]=strlen(*((char **) sx->data.vptr))+1; s=nc_put_vara_text(ncid,varid,start,count, *((char **) sx->data.vptr)); break; } if (s !=NC_NOERR) { fprintf(stderr,"Error writing CDF file (%d).\n",s); exit(-1); } } } for (c=0;c<ptr->anum;c++) { ax=ptr->arr[c]; for (n=0;n<anum;n++) { ay=aptr[n]; if (strcmp(ax->name,ay->name) !=0) continue; if (ax->type !=ay->type) continue; if (ax->dim !=ay->dim) continue; break; } if (n !=anum) { /* mapped variable */ s=nc_inq_varid(ncid,cdfaname[n],&varid); if (s !=NC_NOERR) { fprintf(stderr,"Error accessing CDF file.\n"); exit(-1); } start[0]=block; count[0]=1; n=1; for (x=0;x<ax->dim;x++) { start[1+x]=0; count[1+x]=ax->rng[x]; n=n*ax->rng[x]; } if (ax->type==DATASTRING) { int ndims; int dimids[NC_MAX_VAR_DIMS]; size_t dimlen; s=nc_inq_varndims(ncid,varid,&ndims); if (s !=NC_NOERR) { fprintf(stderr,"Error accessing CDF file.\n"); exit(-1); } s=nc_inq_vardimid(ncid,varid,dimids); if (s !=NC_NOERR) { fprintf(stderr,"Error accessing CDF file.\n"); exit(-1); } if (ndims-2!=ax->dim) { fprintf(stderr,"Error matching dimensions.\n"); exit(-1); } s=nc_inq_dimlen(ncid,dimids[ndims-1],&dimlen); if (s !=NC_NOERR) { fprintf(stderr,"Error accessing CDF file.\n"); exit(-1); } strsze=dimlen; tmpbuf=malloc(n*strsze); if (tmpbuf==NULL) { fprintf(stderr,"Failed to allocate buffer.\n"); exit(-1); } memset(tmpbuf,0,n*strsze); start[1+ax->dim]=0; count[1+ax->dim]=strsze; strptr=(char **) ax->data.vptr; for (x=0;x<n;x++) strncpy(tmpbuf+x*strsze,strptr[x],strsze); } switch (ax->type) { case DATACHAR: s=nc_put_vara_text(ncid,varid,start,count,ax->data.cptr); break; case DATASHORT: s=nc_put_vara_short(ncid,varid,start,count,ax->data.sptr); break; case DATAINT: s=nc_put_vara_int(ncid,varid,start,count,ax->data.iptr); break; case DATAFLOAT: s=nc_put_vara_float(ncid,varid,start,count,ax->data.fptr); break; case DATADOUBLE: s=nc_put_vara_double(ncid,varid,start,count,ax->data.dptr); break; case DATASTRING: s=nc_put_vara_text(ncid,varid,start,count,tmpbuf); break; } if (tmpbuf !=NULL) { free(tmpbuf); tmpbuf=NULL; } if (s !=NC_NOERR) { fprintf(stderr,"Error writing CDF file (%d).\n",s); exit(-1); } } } DataMapFree(ptr); block++; } nc_close(ncid); if (zflg) gzclose(zfp); else fclose(fp); return 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; }
int main(int argc, char *argv[]) { fprintf(stdout, "start\n"); int varid; int ndims; int dimids[NC_MAX_VAR_DIMS]; size_t nx, ny, size, var_size, var_offset, i; int shm_id, shm_key; int nhours, nvars, var_i, frame; float* shm_p; float* data_p; if (argc != 9) { fprintf(stdout, "usage: ./load-dap {SHM_KEY} {NHOURS} {NVARS} {VAR_ID} {FRAME} {URL} {VAR_NAME} {Z_LEVEL}\n"); exit(EXIT_FAILURE); } fprintf(stdout, "nc_open %s\n", argv[URL]); ne(nc_open(argv[URL], 0, &ncid)); fprintf(stdout, "nc_inq\n"); ne(nc_inq_varid (ncid, argv[VAR_NAME], &varid)); ne(nc_inq_varndims(ncid, varid, &ndims)); ne(nc_inq_vardimid(ncid, varid, dimids)); fprintf(stdout, "ndims\n"); if (ndims==2) { ne(nc_inq_dimlen(ncid, dimids[0], &ny)); ne(nc_inq_dimlen(ncid, dimids[1], &nx)); } else if (ndims==3) { ne(nc_inq_dimlen(ncid, dimids[1], &ny)); ne(nc_inq_dimlen(ncid, dimids[2], &nx)); } shm_key=atoi(argv[SHM_KEY]); shm_id=shmget(shm_key, 0, 0644); if (shm_id == -1) { fprintf(stderr, "Shared memory shmget() failed\n"); exit(EXIT_FAILURE); } shm_p = shmat(shm_id, NULL, 0); if (shm_p == (void *)-1) { fprintf(stderr, "Shared memory shmat() failed\n"); exit(EXIT_FAILURE); } size=nx*ny; data_p=malloc(size*sizeof(float)); if (data_p == NULL) { fprintf(stderr, "malloc() failed\n"); exit(EXIT_FAILURE); } if (ndims==2) { ne(nc_get_var_float(ncid, varid, data_p)); } else { size_t start[3]={0,0,0}; size_t count[3]={1,ny,nx}; start[0]=atoi(argv[Z_LEVEL]); ne(nc_get_vara_float(ncid, varid, start, count, data_p)); } // run[point[var[frames[]]]] nhours=atoi(argv[NHOURS]); nvars=atoi(argv[NVARS]); frame=atoi(argv[FRAME]); var_i=atoi(argv[VAR_ID]); size_t index; var_size=nhours*nvars; var_offset=var_i*nhours+frame; for (i=0; i<size; i++) { index=i*var_size+var_offset; shm_p[index]=data_p[i]; } free(data_p); if(shmdt(shm_p)==-1){ fprintf(stderr, "Shared memory shmdt() failed\n"); exit(EXIT_FAILURE); } nc_close(ncid); return 0; }
void CTAI_SObs_netcdf_Create_Init( /* Allocate the memory which is neccesary to store the data necessary for a netcdf-observer */ // IN-OUTPUTS CTAI_SObs_netcdf *x, // The netcdf-observer for which the memory must // be allocated // INPUTS: CTA_Handle userdata, // User data: database-name. Note: the string ends with the date // It is possible that userdata is vector of two handles: (name,timeoffset) // OUTPUTS int *retval) // Error code. Possible error: Illegal data type { #if HAVE_LIBNETCDF char *dbname; int ncid, varid, nmeasr, intNStations; size_t nstations; int ierr, i, len; int dimids[1]; CTA_Time tspan0; float lon1,lon2,lat1,lat2; int *flag; CTAI_OMI_database *database; double timeoffset; CTA_Handle userdata1, userdata2; database = CTA_Malloc(sizeof(CTAI_OMI_database)); // Get the name of the database file: // Check if userdata is a string (database name) or a vector (name and timeoffset) ierr=CTA_Handle_Check((CTA_Handle) userdata,CTA_VECTOR); if (ierr!=CTA_OK) { //then it should be only the string with the database name ierr=CTA_Handle_Check((CTA_Handle) userdata,CTA_STRING); if (ierr!=CTA_OK) { printf("sobs_netcdf: create :: userdata is neither a database name or vector\n");exit(-1);} userdata1 = userdata; timeoffset = 0.0; if (IDEBUG>0) {printf("sobs_netcdf_create 1: timeoffset %f ",timeoffset);} } else { //it is a vector: deconstruct it into the database string and the timeoffset CTA_Vector_GetVal(userdata,1,&userdata1,CTA_HANDLE); CTA_Vector_GetVal(userdata,2,&userdata2,CTA_HANDLE); ierr=CTA_Vector_GetVal(userdata2,1,&timeoffset,CTA_DOUBLE); if (ierr!=CTA_OK) { printf("CTAI_SObs_netcdf :: Create: userdata2 is not a vector of doubles! \n"); } if (IDEBUG>0) {printf("sobs_netcdf_create 2: timeoffset %f ",timeoffset);} } // Allocate a name-string *retval = CTA_String_GetLength(userdata1, &len); if (*retval!=CTA_OK) return; // Get the name of the database dbname = CTA_Malloc((len+1)*sizeof(char)); *retval = CTA_String_Get(userdata1, dbname); if (*retval!=CTA_OK) return; // Open the database ierr = nc_open(dbname, NC_NOWRITE, &ncid); if (ierr != CTA_OK) {printf("Error: could not open netcdf-file \n"); *retval = -1; return;} // Count the stations in this observer. // Note: we denote each valid observation of the satellite as one station with a specific pace and time. // The number of valid observations is O(10^4), while the total grid is typical O(10^5), in the case of // OMI-data and our part of Europe: 350x501 and a time series of length 8000. ierr = nc_inq_varid(ncid, "longitude", &varid); if (ierr != CTA_OK) {printf("Error: could not find datetime \n");*retval = -1; return;} ierr = nc_inq_vardimid(ncid, varid, dimids); // get ID of time dimension if (ierr != CTA_OK) {printf("Error: could not find dimension ID \n");*retval = -1; return;} ierr = nc_inq_dimlen(ncid, dimids[0], &nstations); /* get length of time series */ if (ierr != CTA_OK) {printf("Error: could not length of time series \n");*retval = -1; return;} // initialise the selection relation table CTA_RelTable_Create(&(x->selectionReltab)); flag=CTA_Malloc(nstations*sizeof(int)); for (i=0; i < (int) nstations; i++) {flag[i] = i+1;} intNStations=(int) nstations; CTA_RelTable_SetSelectVal(x->selectionReltab, flag, intNStations,CTA_INTEGER); if (IDEBUG>0) {printf("ctai_sobs_netcdf_init: number of stations/length of time series: %d \n",intNStations);} // initialise the time CTA_Time_Create(&tspan0); CTA_Time_SetSpan(tspan0, 0.0, 24.0); // initialise the spatial window. Maybe it should be read from netcdf-file (global attribute) lon1 = -90.0; // far west lon2 = 90.0; // far east lat1 = 0.0; //equator lat2= 90.0; //north pole // Measurements in this observer = Number of stations in our case! nmeasr = nstations; // Set the observer-fields x->tspan = tspan0; x->bb_lon[0] = lon1; x->bb_lon[1] = lon2; x->bb_lat[0] = lat1; x->bb_lat[1] = lat2; database->dbname = dbname; database->ncid = ncid; database->nusers = 1; x->database = database; x->nstations = nstations; x->nmeasr = nmeasr; x->nmeasr_orig = nmeasr; x->timeoffset = timeoffset; if (IDEBUG>0) {printf("END of cta_sobs_netcdf_create_init \n");} *retval=CTA_OK; #else printf("Error: CTAI_SObs_netcdf_Create_Init: COSTA is compiled without NETCDF support\n"); *retval=CTA_NOT_IMPLEMENTED; #endif };
sta_struct *decode_fsl2(int cdfid, long miss, int *iret) { int ndims,nvars,natts,nunlim; int tmpint[20]; int ier,i,j,unlimsiz; int wmoStaNum_id,wmoStaNum,staName_id; char staName[20]; int staLat_id,staLon_id,staElev_id,timeObs_id,levels_id; int uwnd_id,vwnd_id,wwnd_id,uv_qual_id,w_qual_id,levelMode_id; int sigma_uv_id,sigma_w_id; int sfc_sped_id,sfc_drct_id,sfc_pres_id,sfc_temp_id,sfc_relh_id,sfc_rain_id; float staLat,staLon,staElev,level; float uwnd,vwnd,wwnd,sigma_uv,sigma_w; int uv_qual,w_qual,levelMode; float sfc_sped,sfc_drct,sfc_pres,sfc_temp,sfc_relh,sfc_rain; double timeObs; nc_type xtype; int nvdims,nvatts,time_interval; size_t dimsiz,var_i[5],vc[5],namelen; float ufill,vfill,wfill; float pfill,tfill,dfill,sfill,rfill,rrfill; float fmiss,e; time_t obs_time; char timestr[80],*atttext; int year,month,day,hour,minute; struct tm *gmt_time=NULL,new_time; sta_struct *stadat,*head=NULL; prof_data *plev,*plast; udebug("decoding fsl2\0"); fmiss = (float)miss; ier = nc_inq(cdfid,&ndims,&nvars,&natts,&nunlim); ier = nc_inq_atttype(cdfid,NC_GLOBAL,"avgTimePeriod",&xtype); if(xtype == NC_CHAR) { ier = nc_inq_attlen(cdfid,NC_GLOBAL,"avgTimePeriod",&namelen); udebug("AvgTimPeriod name len is %d",namelen); atttext = (char *)malloc(namelen + 1); ier = nc_get_att_text(cdfid,NC_GLOBAL,"avgTimePeriod",atttext); sscanf(atttext,"%d",tmpint); udebug("AvgTimPeriod type is NC_CHAR %s VAL %d",atttext,tmpint[0]); free(atttext); } else { ier = nc_get_att_int(cdfid,NC_GLOBAL,"avgTimePeriod",tmpint); } udebug("AvgTimPeriod is %d\0",tmpint[0]); time_interval = tmpint[0]; ier = 0; ier += nc_inq_varid(cdfid,"wmoStaNum",&wmoStaNum_id); ier += nc_inq_varid(cdfid,"staName",&staName_id); ier += nc_inq_varid(cdfid,"staLat",&staLat_id); ier += nc_inq_varid(cdfid,"staLon",&staLon_id); ier += nc_inq_varid(cdfid,"staElev",&staElev_id); ier += nc_inq_varid(cdfid,"timeObs",&timeObs_id); ier += nc_inq_varid(cdfid,"levels",&levels_id); ier += nc_inq_varid(cdfid,"uComponent",&uwnd_id); ier += nc_inq_varid(cdfid,"vComponent",&vwnd_id); ier += nc_inq_varid(cdfid,"wComponent",&wwnd_id); ier += nc_get_att_float(cdfid,uwnd_id,"_FillValue",&ufill); ier += nc_get_att_float(cdfid,vwnd_id,"_FillValue",&vfill); ier += nc_get_att_float(cdfid,wwnd_id,"_FillValue",&wfill); ier += nc_inq_varid(cdfid,"uvQualityCode",&uv_qual_id); ier += nc_inq_varid(cdfid,"wQualityCode",&w_qual_id); ier += nc_inq_varid(cdfid,"windSpeedStdDev",&sigma_uv_id); ier += nc_inq_varid(cdfid,"wStdDev",&sigma_w_id); ier += nc_inq_varid(cdfid,"levelMode",&levelMode_id); ier += nc_inq_varid(cdfid,"windSpeedSfc",&sfc_sped_id); ier += nc_inq_varid(cdfid,"windDirSfc",&sfc_drct_id); ier += nc_inq_varid(cdfid,"pressure",&sfc_pres_id); ier += nc_inq_varid(cdfid,"temperature",&sfc_temp_id); ier += nc_inq_varid(cdfid,"relHumidity",&sfc_relh_id); ier += nc_inq_varid(cdfid,"rainRate",&sfc_rain_id); ier += nc_get_att_float(cdfid,sfc_sped_id,"_FillValue",&sfill); ier += nc_get_att_float(cdfid,sfc_drct_id,"_FillValue",&dfill); ier += nc_get_att_float(cdfid,sfc_pres_id,"_FillValue",&pfill); ier += nc_get_att_float(cdfid,sfc_temp_id,"_FillValue",&tfill); ier += nc_get_att_float(cdfid,sfc_relh_id,"_FillValue",&rfill); ier += nc_get_att_float(cdfid,sfc_rain_id,"_FillValue",&rrfill); if(ier != 0) { uerror("could not get station information\0"); *iret = -1; return(NULL); } ier = nc_inq_vardimid(cdfid,staName_id,tmpint); ier += nc_inq_dimlen(cdfid,tmpint[1],&namelen); tmpint[0] = 0;tmpint[1] = 0; ier += nc_inq_var(cdfid,wmoStaNum_id,NULL, &xtype, &nvdims, tmpint, &nvatts); ier += nc_inq_dimlen(cdfid,tmpint[0],&dimsiz); if(ier == 0) unlimsiz = dimsiz; for(i=0;i<unlimsiz;i++) { var_i[0] = i; var_i[1] = 0; vc[0] = 1; vc[1] = namelen-1; memset(staName,'\0',20); ier = nc_get_vara_text(cdfid,staName_id,var_i,vc,staName); ier = nc_get_var1_int(cdfid,wmoStaNum_id,var_i,&wmoStaNum); ier = nc_get_var1_float(cdfid,staLat_id,var_i,&staLat); ier = nc_get_var1_float(cdfid,staLon_id,var_i,&staLon); ier = nc_get_var1_float(cdfid,staElev_id,var_i,&staElev); ier = nc_get_var1_float(cdfid,sfc_sped_id,var_i,&sfc_sped); ier = nc_get_var1_float(cdfid,sfc_drct_id,var_i,&sfc_drct); ier = nc_get_var1_float(cdfid,sfc_pres_id,var_i,&sfc_pres); ier = nc_get_var1_float(cdfid,sfc_temp_id,var_i,&sfc_temp); ier = nc_get_var1_float(cdfid,sfc_relh_id,var_i,&sfc_relh); ier = nc_get_var1_float(cdfid,sfc_rain_id,var_i,&sfc_rain); ier = nc_get_var1_double(cdfid,timeObs_id,var_i,&timeObs); obs_time = (time_t) timeObs; gmt_time = gmtime(&obs_time); new_time = *gmt_time; timestr[0] = '\0'; strftime(timestr,80,"%Y %m %d %H %M",&new_time); sscanf(timestr,"%d %d %d %d %d",&year,&month,&day,&hour,&minute); udebug("Station %3d %8d %s = %6.2f %7.2f %5.0f %s\0",i,wmoStaNum, staName,staLat,staLon,staElev,timestr); stadat = (sta_struct *)malloc(sizeof(sta_struct)); if(stadat == NULL) { uerror("Could not allocate station data structure\0"); exit(-2); } stadat->wmoStaNum = wmoStaNum; stadat->staName = (char *)malloc(strlen(staName)+1); strcpy(stadat->staName,staName); stadat->staLat = staLat; stadat->staLon = staLon; stadat->staElev = staElev; stadat->timeObs = timeObs; stadat->year = year; stadat->month = month; stadat->day = day; stadat->hour = hour; stadat->minute = minute; stadat->time_interval = time_interval; stadat->pdata = NULL; stadat->rdata = NULL; stadat->sfc_pres = fmiss; stadat->sfc_temp = fmiss; stadat->sfc_sped = fmiss; stadat->sfc_drct = fmiss; stadat->sfc_relh = fmiss; stadat->sfc_rain_rate = fmiss; stadat->sfc_rain_amt = fmiss; stadat->sfc_dwpc = fmiss; if(sfc_pres != pfill) stadat->sfc_pres = sfc_pres; if(sfc_temp != tfill) stadat->sfc_temp = sfc_temp - 273.15; if(sfc_sped != sfill) stadat->sfc_sped = sfc_sped; if(sfc_drct != dfill) stadat->sfc_drct = sfc_drct; if(sfc_relh != rfill) stadat->sfc_relh = sfc_relh; if(sfc_rain != rrfill) stadat->sfc_rain_rate = sfc_rain; if((stadat->sfc_temp != fmiss)&&(stadat->sfc_relh != fmiss)) { VAPOR_PRES(stadat->sfc_temp+273.15,&e); e = e * (stadat->sfc_relh / 100.); t_from_e(e,&stadat->sfc_dwpc); stadat->sfc_dwpc = stadat->sfc_dwpc - 273.15; } ier = nc_inq_var(cdfid,levels_id,NULL, &xtype, &nvdims, tmpint, &nvatts); if(ier == 0) { ier = nc_inq_dimlen(cdfid,tmpint[0],&dimsiz); stadat->numlevs = dimsiz; plast = stadat->pdata; for(j=0;j<stadat->numlevs;j++) { var_i[0] = j; ier = nc_get_var1_float(cdfid,levels_id,var_i,&level); ier = nc_get_var1_int(cdfid,levelMode_id,var_i,&levelMode); var_i[0] = i; var_i[1] = j; ier = nc_get_var1_float(cdfid,uwnd_id,var_i,&uwnd); ier = nc_get_var1_float(cdfid,vwnd_id,var_i,&vwnd); ier = nc_get_var1_float(cdfid,wwnd_id,var_i,&wwnd); ier = nc_get_var1_int(cdfid,uv_qual_id,var_i,&uv_qual); ier = nc_get_var1_int(cdfid,w_qual_id,var_i,&w_qual); ier = nc_get_var1_float(cdfid,sigma_uv_id,var_i,&sigma_uv); ier = nc_get_var1_float(cdfid,sigma_w_id,var_i,&sigma_w); plev = (prof_data *)malloc(sizeof(prof_data)); if(plev != NULL) { plev->level = level; if(uwnd == ufill) uwnd = fmiss; if(vwnd == vfill) vwnd = fmiss; if(wwnd == wfill) wwnd = fmiss; if(uv_qual != 0) { uwnd = fmiss; vwnd = fmiss; } if(w_qual != 0) wwnd = fmiss; if((uwnd == fmiss)||(vwnd == fmiss)) sigma_uv = fmiss; if(wwnd == fmiss) sigma_w = fmiss; plev->u = uwnd; plev->v = vwnd; plev->w = wwnd; plev->sigma_uv = sigma_uv; plev->sigma_w = sigma_w; plev->levmode = levelMode; plev->nextlev = NULL; if(plast == NULL) stadat->pdata = plev; else plast->nextlev = plev; plast = plev; } } } else stadat->numlevs = 0; stadat->next = head; head = stadat; } return(head); }
/** * Convert a Version 2 Fortran IMAP vector into a Version 3 C imap vector. */ static ptrdiff_t* f2c_v2imap(int ncid, int varid, const int* fimap, ptrdiff_t* cimap) { int rank; nc_type datatype; if (nc_inq_vartype(ncid, varid, &datatype) || nc_inq_varndims(ncid, varid, &rank) || rank <= 0) { return NULL; } /* else */ if (fimap[0] == 0) { /* * Special Fortran version 2 semantics: use external netCDF variable * structure. */ int dimids[NC_MAX_VAR_DIMS]; int idim; size_t total; if (nc_inq_vardimid(ncid, varid, dimids) != NC_NOERR) return NULL; for (total = 1, idim = rank - 1; idim >= 0; --idim) { size_t length; cimap[idim] = total; if (nc_inq_dimlen(ncid, dimids[idim], &length) != NC_NOERR) return NULL; total *= length; } } else { /* * Regular Fortran version 2 semantics: convert byte counts to * element counts. */ int idim; size_t size; switch (datatype) { case NC_CHAR: size = sizeof(char); break; case NC_BYTE: # if NF_INT1_IS_C_SIGNED_CHAR size = sizeof(signed char); # elif NF_INT1_IS_C_SHORT size = sizeof(short); # elif NF_INT1_IS_C_INT size = sizeof(int); # elif NF_INT1_IS_C_LONG size = sizeof(long); # endif break; case NC_SHORT: # if NF_INT2_IS_C_SHORT size = sizeof(short); # elif NF_INT2_IS_C_INT size = sizeof(int); # elif NF_INT2_IS_C_LONG size = sizeof(long); # endif break; case NC_INT: # if NF_INT_IS_C_INT size = sizeof(int); # elif NF_INT_IS_C_LONG size = sizeof(long); # endif break; case NC_FLOAT: # if NF_REAL_IS_C_FLOAT size = sizeof(float); # elif NF_REAL_IS_C_DOUBLE size = sizeof(double); # endif break; case NC_DOUBLE: # if NF_DOUBLEPRECISION_IS_C_FLOAT size = sizeof(float); # elif NF_DOUBLEPRECISION_IS_C_DOUBLE size = sizeof(double); # endif break; default: return NULL; } for (idim = 0; idim < rank; ++idim) cimap[idim] = fimap[rank - 1 - idim] / size; } return cimap; }