/* Read the CF annotations. Recall that in C, strlens do not include * the null terminator. To get the lengths before the strings (in * order to allocatate) pass NULL for any or all strngs and the * lengths will be returned. Then call the funtion again after * allocating memory. * The CF version is guarenteed to be less than NC_MAX_NAME. * Any of these pointer args may be NULL, in which case it will be * ignored. */ int nccf_inq_file(int ncid, size_t *title_lenp, char *title, size_t *history_lenp, char *history) { int ret; /* Find length of title. */ if (title_lenp) if ((ret = nc_inq_attlen(ncid, NC_GLOBAL, CF_TITLE, title_lenp))) return ret; /* Get title. */ if (title) if ((ret = nc_get_att_text(ncid, NC_GLOBAL, CF_TITLE, title))) return ret; /* Find length of history. */ if (history_lenp) if ((ret = nc_inq_attlen(ncid, NC_GLOBAL, CF_HISTORY, history_lenp))) return ret; /* Get history. */ if (history) if ((ret = nc_get_att_text(ncid, NC_GLOBAL, CF_HISTORY, history))) return ret; return NC_NOERR; }
/* Read any or all of these four attributes of a file or * variable. */ int nccf_inq_notes(int ncid, int varid, size_t *institution_lenp, char *institution, size_t *source_lenp, char *source, size_t *comment_lenp, char *comment, size_t *references_lenp, char *references) { int ret; if (institution_lenp) if ((ret = nc_inq_attlen(ncid, varid, CF_INSTITUTION, institution_lenp))) return ret; if (institution) if ((ret = nc_get_att_text(ncid, varid, CF_INSTITUTION, institution))) return ret; if (source_lenp) if ((ret = nc_inq_attlen(ncid, varid, CF_SOURCE, source_lenp))) return ret; if (source) if ((ret = nc_get_att_text(ncid, varid, CF_SOURCE, source))) return ret; if (comment_lenp) if ((ret = nc_inq_attlen(ncid, varid, CF_COMMENT, comment_lenp))) return ret; if (comment) if ((ret = nc_get_att_text(ncid, varid, CF_COMMENT, comment))) return ret; if (references_lenp) if ((ret = nc_inq_attlen(ncid, varid, CF_REFERENCES, references_lenp))) return ret; if (references) if ((ret = nc_get_att_text(ncid, varid, CF_REFERENCES, references))) return ret; return NC_NOERR; }
/*************************************************************************** void mpp_get_var_bndname(int fid, int vid, char *bndname) Get the bound name of dimension variable if it exist, otherwise the value will be 'none' for time axis, the bounds may be 'climatology' **************************************************************************/ void mpp_get_var_bndname(int fid, int vid, char *bndname) { int ncid, fldid, status; char errmsg[512], name[32]; size_t siz; if(fid<0 || fid >=nfiles) mpp_error("mpp_io(mpp_get_var_cart): 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_cart): invalid vid number, vid should be " "a nonnegative integer that less than nvar"); ncid = files[fid].ncid; fldid = files[fid].var[vid].fldid; strcpy(name, "climatology"); status = nc_inq_attlen(ncid, fldid, name, &siz); if(status != NC_NOERR){ strcpy(name, "bounds"); status = nc_inq_attlen(ncid, fldid, name, &siz); } if(status != NC_NOERR){ strcpy(name, "edges"); status = nc_inq_attlen(ncid, fldid, name, &siz); } if(status != NC_NOERR) { strcpy(bndname, "none"); } else { status = nc_get_att_text(ncid, fldid, name, bndname); bndname[siz] = '\0'; if(status != NC_NOERR) { sprintf(errmsg, "mpp_io(mpp_get_var_bndname): Error in getting attribute %s of " "dimension variable %s from file %s", name, files[fid].var[vid].name, files[fid].name ); netcdf_error(errmsg, status); } } }
/** * Static identifier to determine if the netcdf file is an ndfd forecast. * Uses netcdf c api * * @param fileName netcdf filename * * @return true if the forecast is a NCEP Dgex forecast */ bool ncepDgexSurfInitialization::identify( std::string fileName ) { bool identified = true; //Acquire a lock to protect the non-thread safe netCDF library #ifdef _OPENMP omp_guard netCDF_guard(netCDF_lock); #endif int status, ncid, ndims, nvars, ngatts, unlimdimid; /* * Open the dataset */ status = nc_open( fileName.c_str(), 0, &ncid ); if ( status != NC_NOERR ) identified = false; /* * If we can't get simple data from the file, return false */ status = nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid); if ( status != NC_NOERR ) identified = false; /* * Check the variable names, return false if any aren't found */ int varid; std::vector<std::string> varList = getVariableList(); for( unsigned int i = 0;i < varList.size();i++ ) { status = nc_inq_varid( ncid, varList[i].c_str(), &varid ); if( status != NC_NOERR ) identified = false; } /* * Check the global attributes for the following tag: * :Generating_Model = "RAP Model from FSL (isentropic; scale: 20km at 40N)" */ size_t len; nc_type type; char* model; status = nc_inq_att( ncid, NC_GLOBAL, "Analysis_or_forecast_generating_process_identifier_defined_by_originating_centre", &type, &len ); if( status != NC_NOERR ) identified = false; else { model = new char[len + 1]; status = nc_get_att_text( ncid, NC_GLOBAL, "Analysis_or_forecast_generating_process_identifier_defined_by_originating_centre", model ); model[len] = '\0'; std::string s( model ); if( s.find("Downscaled GFS from NAM eXtension" ) == s.npos ) { identified = false; } delete[] model; } status = nc_close( ncid ); return identified; }
static char * has_c_format_att( int ncid, /* netcdf id */ int varid /* variable id */ ) { nc_type cfmt_type; size_t cfmt_len; #define C_FMT_NAME "C_format" /* name of C format attribute */ #define MAX_CFMT_LEN 100 /* max length of C format attribute */ static char cfmt[MAX_CFMT_LEN]; /* we expect nc_inq_att to fail if there is no "C_format" attribute */ int nc_stat = nc_inq_att(ncid, varid, "C_format", &cfmt_type, &cfmt_len); switch(nc_stat) { case NC_NOERR: if (cfmt_type == NC_CHAR && cfmt_len != 0 && cfmt_len < MAX_CFMT_LEN) { int nc_stat = nc_get_att_text(ncid, varid, "C_format", cfmt); if(nc_stat != NC_NOERR) nc_advise("Getting 'C_format' attribute", nc_stat, ""); return &cfmt[0]; } break; case NC_ENOTATT: break; default: nc_advise("Inquiring about 'C_format' attribute", nc_stat, ""); break; } return 0; }
/* Test a small file with one var and one att. */ static int test_one_with_att(const char *testfile) { int ncid, dimid, varid; char data = 'h', data_in; int ndims, nvars, natts, unlimdimid; size_t start[NDIMS], count[NDIMS]; /* Create a file with one ulimited dimensions, and one var. */ if (nc_create(testfile, NC_CLOBBER, &ncid)) ERR; if (nc_def_dim(ncid, DIM1_NAME, NC_UNLIMITED, &dimid)) ERR; if (nc_def_var(ncid, VAR_NAME, NC_CHAR, 1, &dimid, &varid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_NAME, 1, &data)) ERR; if (nc_enddef(ncid)) ERR; /* Write one record of var data, a single character. */ count[0] = 1; start[0] = 0; if (nc_put_vara_text(ncid, varid, start, count, &data)) ERR; /* We're done! */ if (nc_close(ncid)) ERR; /* Reopen the file and check it. */ if (nc_open(testfile, NC_NOWRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != 1 && nvars != 1 && natts != 0 && unlimdimid != 0) ERR; if (nc_get_var_text(ncid, varid, &data_in)) ERR; if (data_in != data) ERR; if (nc_get_att_text(ncid, NC_GLOBAL, ATT_NAME, &data_in)) ERR; if (data_in != data) ERR; if (nc_close(ncid)) ERR; return 0; }
/****************************************************************************** void get_var_text_att(const char *file, const char *name, const char *attname, char *att) get text attribute of field 'name' from 'file ******************************************************************************/ void get_var_text_att(const char *file, const char *name, const char *attname, char *att) { int ncid, varid, status; char msg[512]; #ifdef use_netCDF status = nc_open(file, NC_NOWRITE, &ncid); if(status != NC_NOERR) { sprintf(msg, "in opening file %s", file); handle_netcdf_error(msg, status); } status = nc_inq_varid(ncid, name, &varid); if(status != NC_NOERR) { sprintf(msg, "in getting varid of %s from file %s.", name, file); handle_netcdf_error(msg, status); } status = nc_get_att_text(ncid, varid, attname, att); if(status != NC_NOERR) { sprintf(msg, "in getting attribute %s of %s from file %s.", attname, name, file); handle_netcdf_error(msg, status); } status = nc_close(ncid); if(status != NC_NOERR) { sprintf(msg, "in closing file %s.", file); handle_netcdf_error(msg, status); } #else error_handler("read_mosaic: Add flag -Duse_netCDF when compiling"); #endif }; /* get_var_text_att */
int NCfindVariableByAttribute (int ncid, int ndims, const char *attribute, const char *content) { int status; int varid; int nvars; int n; size_t attlen; char text [NC_MAX_NAME + 1]; if ((status = nc_inq_nvars (ncid, &nvars)) != NC_NOERR) { CMmsgPrint (CMmsgAppError,"NetCDF file inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__); return (CMfailed); } for (varid = 0;varid < nvars; ++varid) { if (ndims > 0) { if ((status = nc_inq_varndims (ncid, varid, &n)) != NC_NOERR) { CMmsgPrint (CMmsgAppError,"NetCDF variable dimensions inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__); return (CMfailed); } if (n != ndims) continue; } if ((status = nc_inq_attlen (ncid, varid, attribute, &attlen)) != NC_NOERR) continue; if ((attlen > strlen (content)) || (attlen > NC_MAX_NAME)) continue; if ((status = nc_get_att_text (ncid,varid,attribute,text)) != NC_NOERR) { CMmsgPrint (CMmsgAppError,"NetCDF attribute inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__); return (CMfailed); } else text [attlen] = '\0'; if (strcmp (text,content) == 0) break; } return (varid < nvars ? varid : CMfailed); }
char * netcdfGetAttributeText( int ncid, int vid, char *attribute ) { int err; char *returnText; # ifdef MPI MPI_Offset ist; # else size_t ist; # endif err = nc_inq_attlen(ncid, vid, attribute, &ist); if (err == NC_NOERR) { returnText = (char *) safe_malloc(sizeof(char) * (ist+1)); err = nc_get_att_text(ncid, vid, attribute, returnText); if (err != NC_NOERR) { fprintf(stdout, "netcdfGetAttributeText: Could not get attribute (%s) from NetCDF file", attribute); safe_free(returnText); returnText = NULL; } } else fprintf(stdout, "netcdfGetAttributeText: Error grabbing attribute (%s): %s\n", attribute, nc_strerror(err)); return returnText; }
/* Read the CF annotations. Recall that in C, strlens do not include * the null terminator. To get the lengths before the strings (in * order to allocatate) pass NULL for any or all strngs and the * lengths will be returned. Then call the funtion again after * allocating memory. * Any of these pointer args may be NULL, in which case it will be * ignored. */ int nccf_inq_var(int ncid, int varid, size_t *units_lenp, char *units, size_t *long_name_lenp, char *long_name, size_t *standard_name_lenp, char *standard_name, int *ncoord_vars, int *coord_varids) { int ret; /* Read units length if desired. */ if (units_lenp) if ((ret = nc_inq_attlen(ncid, varid, CF_UNITS, units_lenp))) return ret; /* Read units value if desired. */ if (units) if ((ret = nc_get_att_text(ncid, varid, CF_UNITS, units))) return ret; if (long_name_lenp) if ((ret = nc_inq_attlen(ncid, varid, CF_LONG_NAME, long_name_lenp))) return ret; if (long_name) if ((ret = nc_get_att_text(ncid, varid, CF_LONG_NAME, long_name))) return ret; if (standard_name_lenp) if ((ret = nc_inq_attlen(ncid, varid, CF_STANDARD_NAME, standard_name_lenp))) return ret; if (standard_name) if ((ret = nc_get_att_text(ncid, varid, CF_STANDARD_NAME, standard_name))) return ret; /* Learn the number of coordinate variables, and their IDs, if * desired. */ if ((ret = nccf_parse_coords(ncid, varid, CF_COORDINATES, ncoord_vars, coord_varids))) return ret; return NC_NOERR; }
int ex_get_elem_type(int exoid, ex_entity_id elem_blk_id, char *elem_type) /* * Reads the element type for a specific element block * elem_type is assumed to have a length of MAX_STR_LENGTH+1 */ { int connid, el_blk_id_ndx, status; size_t len; char errmsg[MAX_ERR_LENGTH]; /*****************************************************************************/ EX_FUNC_ENTER(); ex_check_valid_file_id(exoid, __func__); /* inquire id's of previously defined dimensions */ if ((el_blk_id_ndx = ex_id_lkup(exoid, EX_ELEM_BLOCK, elem_blk_id)) == -1) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to find element block ID %" PRId64 " in file %d", elem_blk_id, exoid); ex_err(__func__, errmsg, EX_LASTERR); EX_FUNC_LEAVE(EX_FATAL); } if ((status = nc_inq_varid(exoid, VAR_CONN(el_blk_id_ndx), &connid)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to find connectivity variable in file ID %d", exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } /* get the element type name */ if ((status = nc_inq_attlen(exoid, connid, ATT_NAME_ELB, &len)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to find attribute in file ID %d", exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } if (len > (MAX_STR_LENGTH + 1)) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Element type must be of length %d in file ID %d", (int)len, exoid); ex_err(__func__, errmsg, EX_BADPARAM); EX_FUNC_LEAVE(EX_FATAL); } /* Make sure the end of the string is terminated with a null character */ elem_type[MAX_STR_LENGTH] = '\0'; if ((status = nc_get_att_text(exoid, connid, ATT_NAME_ELB, elem_type)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get attribute \"%s\" in file ID %d", ATT_NAME_ELB, exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } EX_FUNC_LEAVE(EX_NOERR); }
/* Append string to a named global attribute. Create the attribute if * it doesn't exist. */ static int nccf_append_att(int ncid, const char *name, const char *string) { char *att_str = NULL; size_t len, new_len; int ret; /* Find out if there is an attribute of this name. */ ret = nc_inq_attlen(ncid, NC_GLOBAL, name, &len); if (ret == NC_ENOTATT) { /* Create the attribute. I will null-terminate this * attribute. */ if ((ret = nc_put_att_text(ncid, NC_GLOBAL, name, strlen(string) + 1, string))) return ret; } else if (ret == NC_NOERR) { /* The attribute already exists. Get memory to hold the existing * att plus our version string. Add one for the space, and one * for a terminating null. */ new_len = len + strlen(string) + 1; if (!(att_str = malloc(new_len + 1))) return CF_ENOMEM; /* Get the existing attribute value. */ if ((ret = nc_get_att_text(ncid, NC_GLOBAL, name, att_str))) BAIL(CF_ENETCDF); /* If it's already in the string, our work is done.*/ if (strstr(att_str, string)) { free(att_str); return CF_NOERR; } /* Append our string to the existing att. */ att_str[len] = 0; strcat(att_str, " "); strcat(att_str, string); /* Delete the existing attribute, so we can rewrite it. */ if ((ret = nc_del_att(ncid, NC_GLOBAL, name))) BAIL(ret); /* Rewrite the attribute with our string appended. */ if ((ret = nc_put_att_text(ncid, NC_GLOBAL, name, strlen(att_str) + 1, att_str))) BAIL(ret); } exit: if (att_str) free(att_str); return ret; }
static void test_axis(const char *testfile) { int ncid, dimid, varid, dimids[1] = {0}; int axis_type; int nvars, ndims, natts, unlimdimid; char value[NC_MAX_NAME + 1]; /* Create a file. */ if (nc_create(testfile, NC_CLOBBER, &ncid)) ERR; /* Create an dimension and a coordinate var to go with it. */ if (nc_def_dim(ncid, DIM1_NAME, DIM_LEN, &dimid)) ERR; if (dimid != 0) ERR; if (nc_def_var(ncid, DIM1_NAME, NC_FLOAT, 1, dimids, &varid)) ERR; if (varid != 0) ERR; if (nccf_def_axis_type(ncid, varid, NCCF_LONGITUDE)) ERR; if (nccf_inq_axis_type(ncid, varid, &axis_type)) ERR; if (axis_type != NCCF_LONGITUDE) ERR; /* Write the file. */ if (nc_close(ncid)) ERR; /* Reopen the file, check the axis type. */ if (nc_open(testfile, NC_NOWRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != 1 && nvars != 2 && natts != 0 && unlimdimid != -1) ERR; if (nccf_inq_axis_type(ncid, 0, &axis_type)) ERR; if (axis_type != NCCF_LONGITUDE) ERR; if (nc_close(ncid)) ERR; /* Now create a file with the HEIGHT_UP axis. */ if (nc_create(testfile, NC_CLOBBER, &ncid)) ERR; /* Create an dimension and a coordinate var to go with it. */ if (nc_def_dim(ncid, DIM1_NAME, DIM_LEN, &dimid)) ERR; if (dimid != 0) ERR; if (nc_def_var(ncid, DIM1_NAME, NC_FLOAT, 1, dimids, &varid)) ERR; if (varid != 0) ERR; if (nccf_def_axis_type(ncid, varid, NCCF_HEIGHT_UP)) ERR; if (nccf_inq_axis_type(ncid, varid, &axis_type)) ERR; if (axis_type != NCCF_HEIGHT_UP) ERR; /* Write the file. */ if (nc_close(ncid)) ERR; /* Reopen the file, check the axis type. */ if (nc_open(testfile, NC_NOWRITE, &ncid)) ERR; if (nccf_inq_axis_type(ncid, 0, &axis_type)) ERR; if (axis_type != NCCF_HEIGHT_UP) ERR; if (nc_get_att_text(ncid, varid, COORDINATE_Z_IS_POSITIVE, value)) ERR; if (strcmp(value, Z_UP)) ERR; if (nc_close(ncid)) ERR; }
static void *open_cdf_read(const char *filename, const char *filetype, int *natoms) { int ncid, rc; size_t len; cdfdata *cdf; rc = nc_open(filename, NC_NOWRITE, &ncid); if (rc != NC_NOERR) return NULL; cdf = (cdfdata *) malloc(sizeof(cdfdata)); memset(cdf, 0, sizeof(cdfdata)); cdf->ncid = ncid; cdf->type = CDF_TYPE_UNKNOWN; /* Determine what NetCDF conventions apply to this data, if any */ rc = nc_inq_attlen(cdf->ncid, NC_GLOBAL, "Conventions", &len); if (rc == NC_NOERR && len > 0) { cdf->conventions = (char *) malloc((len+1) * sizeof(char)); nc_get_att_text(cdf->ncid, NC_GLOBAL, "Conventions", cdf->conventions); cdf->conventions[len] = '\0'; printf("netcdfplugin) conventions: '%s'\n", cdf->conventions); } if (cdf->conventions != NULL) { /* Check if this is a file generated by AMBER */ if (strstr(cdf->conventions, "AMBER") != NULL) { if (!open_amber_cdf_read(cdf)) { *natoms = cdf->natoms; return cdf; } } /* Check if this is a file generated by MMTK */ if (strstr(cdf->conventions, "MMTK") != NULL) { if (!open_mmtk_cdf_read(cdf, 1)) { *natoms = cdf->natoms; return cdf; } } } printf("netcdfplugin) Missing or unrecognized conventions attribute\n"); printf("netcdfplugin) checking for old format MMTK NetCDF file...\n"); /* If no conventions are specified, then maybe it's from MMTK */ if (!open_mmtk_cdf_read(cdf, 0)) { *natoms = cdf->natoms; return cdf; } /* if no conventions are recognized, then we free everything */ /* and return failure */ close_cdf_read(cdf); return NULL; }
/*+++++++++++++++++++++++++ .IDENTifer SCIA_RD_NC_HDO_META .PURPOSE read header from IMAP-HDO product in netCDF-4 (ADAGUC standard) .INPUT/OUTPUT call as SCIA_RD_NC_HDO_META( ncid, &hdr ); input: int ncid : netCDF file ID output: struct imap_hdr *hdr : IMAP header .RETURNS Nothing .COMMENTS static function -------------------------*/ void SCIA_RD_NC_HDO_META( int ncid, struct imap_hdr *hdr ) { int retval; int var_id; /* * Product meta-data */ if ( (retval = nc_inq_varid( ncid, "product", &var_id )) != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); retval = nc_get_att_text( ncid, var_id, "input_products", hdr->l1b_product ); if ( retval != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); retval = nc_get_att_text( ncid, var_id, "creation_date", hdr->creation_date ); if ( retval != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); retval = nc_get_att_text( ncid, var_id, "validity_start", hdr->validity_start ); if ( retval != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); retval = nc_get_att_text( ncid, var_id, "validity_stop", hdr->validity_stop ); if ( retval != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); retval = nc_get_att_text( ncid, var_id, "software_version", hdr->software_version ); if ( retval != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); /* * Custom meta-data */ if ( (retval = nc_inq_varid( ncid, "custom", &var_id )) != NC_NOERR ) NADC_RETURN_ERROR( NADC_ERR_FATAL, nc_strerror(retval) ); retval = nc_get_att_ushort( ncid, var_id, "number_input_products", &hdr->numProd ); retval = nc_get_att_ushort( ncid, var_id, "file_counter", &hdr->counter[0] ); retval = nc_get_att_uint( ncid, var_id, "abs_orbit", &hdr->orbit[0] ); }
/* Both CF and CDM use an attribute to hold a space-separated list of * names of coordinate variables. This function reads that attribute * and looks up the ID of each coordinate var. */ int nccf_parse_coords(int ncid, int varid, char *att_name, int *naxes, int *axis_varids) { size_t len; char *coords_str; char axis_name[NC_MAX_NAME + 1], *p, *a; int num_axes = 0; int *axes; int a1, ret; /* Check reasonableness of name. */ if (!att_name || strlen(att_name) > NC_MAX_NAME) return CF_EINVAL; /* Find length of the attribute. */ if ((ret = nc_inq_att(ncid, varid, att_name, NULL, &len))) return ret; /* Allocate space to read in the string. */ if (!(coords_str = malloc(len))) return CF_ENOMEM; /* Read in the system string. */ ret = nc_get_att_text(ncid, varid, att_name, coords_str); /* If we got the coord axes string, parse it to find the names of * the coordinate vars which make up this system. */ axes = (int*)malloc(sizeof(int)*NC_MAX_DIMS); if(axes == null) return NC_ENOMEM; for (p = coords_str; !ret && (p - coords_str) < strlen(coords_str);) { for (a = axis_name; *p && *p != ' '; ) *a++ = *p++; p++; *a = '\0'; ret = nc_inq_varid(ncid, axis_name, &axes[num_axes++]); } /* Thanks for the memories! */ free(coords_str); /* Give the user what they asked for. */ if (naxes) *naxes = num_axes; if (axis_varids) for (a1 = 0; a1 < num_axes; a1++) axis_varids[a1] = axes[a1]; free(axes) return CF_NOERR; }
NcValues* NcAtt::values( void ) const { NcValues* valp = get_space(); int status; switch (type()) { case ncFloat: status = NcError::set_err( nc_get_att_float(the_file->id(), the_variable->id(), the_name, (float *)valp->base()) ); break; case ncDouble: status = NcError::set_err( nc_get_att_double(the_file->id(), the_variable->id(), the_name, (double *)valp->base()) ); break; case ncInt: status = NcError::set_err( nc_get_att_int(the_file->id(), the_variable->id(), the_name, (int *)valp->base()) ); break; case ncShort: status = NcError::set_err( nc_get_att_short(the_file->id(), the_variable->id(), the_name, (short *)valp->base()) ); break; case ncByte: status = NcError::set_err( nc_get_att_schar(the_file->id(), the_variable->id(), the_name, (signed char *)valp->base()) ); break; case ncChar: status = NcError::set_err( nc_get_att_text(the_file->id(), the_variable->id(), the_name, (char *)valp->base()) ); break; case ncNoType: default: return 0; } if (status != NC_NOERR) { delete valp; return 0; } return valp; }
int nccf_inq_axis_type(int ncid, int varid, int *axis_type) { char value[NC_MAX_NAME + 1]; int i; int ret; /* Get the attribute which stores the axis type. */ if ((ret = nc_get_att_text(ncid, varid, COORDINATE_AXIS_TYPE, value))) return ret; /* Which axis type is this? */ for (i = 1; i <= NCCF_RADDIST; i++) if (!strcmp(value, axis_type_name[i])) break; /* For height we also have to look at another attribute to find out * whether it is up or down. At this point, i will equal * NCCF_HEIGHT_UP, find out whether it should be HEIGHT_DOWN. */ if (i == NCCF_HEIGHT_UP) { if ((ret = nc_get_att_text(ncid, varid, COORDINATE_Z_IS_POSITIVE, value))) return ret; if (!strcmp(value, Z_DOWN)) i = NCCF_HEIGHT_DOWN; } /* Return a valid type if we found one, otherwise zero. */ if (i > NCCF_RADDIST) return NCCF_NOAXISTYPE; if (axis_type) *axis_type = i; return NC_NOERR; }
EXTERNL int nccf_inq_transform(int ncid, int transform_varid, char *name, size_t *type_len, char *transform_type, size_t *name_len, char *transform_name) { int ret; /* Find the name of the transform var, if desired. */ if (name) if ((ret = nc_inq_varname(ncid, transform_varid, name))) return ret; /* If the user wants the length of the transform_type, find it. */ if (type_len) if ((ret = nc_inq_attlen(ncid, transform_varid, TRANSFORM_TYPE, type_len))) return ret; /* If the user wants the transform type string, get it. */ if (transform_type) if ((ret = nc_get_att_text(ncid, transform_varid, TRANSFORM_TYPE, transform_type))) return ret; /* If the user wants the length of the transform_name, find it. */ if (type_len) if ((ret = nc_inq_attlen(ncid, transform_varid, TRANSFORM_NAME, name_len))) return ret; /* If the user wants the transform name string, get it. */ if (transform_name) if ((ret = nc_get_att_text(ncid, transform_varid, TRANSFORM_NAME, transform_name))) return ret; return NC_NOERR; }
/*************************************************************************** char mpp_get_var_cart(int fid, int vid) get the cart of the dimension variable *************************************************************************/ char mpp_get_var_cart(int fid, int vid) { char cart; int ncid, fldid, status; char errmsg[512]; if(fid<0 || fid >=nfiles) mpp_error("mpp_io(mpp_get_var_cart): 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_cart): invalid vid number, vid should be " "a nonnegative integer that less than nvar"); cart = 'N'; ncid = files[fid].ncid; fldid = files[fid].var[vid].fldid; status = nc_get_att_text(ncid, fldid, "cartesian_axis", &cart); if(status != NC_NOERR)status = nc_get_att_text(ncid, fldid, "axis", &cart); if(status != NC_NOERR){ sprintf(errmsg, "mpp_io(mpp_get_var_cart): Error in getting attribute cartesian_axis/axis of " "dimension variable %s from file %s", files[fid].var[vid].name, files[fid].name ); netcdf_error(errmsg, status); } return cart; }
std::string FileNetcdf::getGlobalAttribute(std::string iName) { size_t len; int status = nc_inq_attlen(mFile, NC_GLOBAL, iName.c_str(), &len); handleNetcdfError(status, "could not determine global attribute length"); char* value = new char[len+1]; status = nc_get_att_text(mFile, NC_GLOBAL, iName.c_str(), value); handleNetcdfError(status, "could not get global attribute"); value[len] = '\0'; std::string ret = ""; if(status == NC_NOERR) ret = std::string(value); delete[] value; return ret; }
void FileNetcdf::prependGlobalAttribute(std::string iName, std::string iValue) { int id; int status = nc_inq_attid(mFile, NC_GLOBAL, iName.c_str(), &id); if(status == NC_NOERR) { char value[10000]; int status = nc_get_att_text(mFile, NC_GLOBAL, iName.c_str(), value); handleNetcdfError(status, "could not get attribute when prepending a new value"); std::stringstream ss; ss << iValue << "\n" << value; setGlobalAttribute(iName, ss.str()); } else { setGlobalAttribute(iName, iValue); } }
NCdataType NCdataGetType(int ncid) { int status; char dTypeStr[NC_MAX_NAME]; if ((status = nc_get_att_text(ncid, NC_GLOBAL, NCnameGADataType, dTypeStr)) == NC_NOERR) { if (strncmp(dTypeStr, NCnameTypeGCont, strlen(NCnameTypeGCont)) == 0) return (NCtypeGCont); else if (strncmp(dTypeStr, NCnameTypeGDisc, strlen(NCnameTypeGDisc)) == 0) return (NCtypeGDisc); else if (strncmp(dTypeStr, NCnameTypePoint, strlen(NCnameTypePoint)) == 0) return (NCtypePoint); else if (strncmp(dTypeStr, NCnameTypeLine, strlen(NCnameTypeLine)) == 0) return (NCtypeLine); else if (strncmp(dTypeStr, NCnameTypePolygon, strlen(NCnameTypePolygon)) == 0) return (NCtypePolygon); else if (strncmp(dTypeStr, NCnameTypeNetwork, strlen(NCnameTypeNetwork)) == 0) return (NCtypeNetwork); CMmsgPrint(CMmsgAppError, "Invalid data type in: %s %d", __FILE__, __LINE__); return (NCtypeUndefined); } return (NCtypeGCont); }
/* Test a small file with one record var, which grows, and has * attributes. */ static int test_one_growing_with_att(const char *testfile) { int ncid, dimid, varid; char data[MAX_RECS], data_in; char att_name[NC_MAX_NAME + 1]; size_t start[ONE_DIM], count[ONE_DIM], index[ONE_DIM], len_in; int r; /* Create a file with one ulimited dimensions, and one var. */ if (nc_create(testfile, NC_CLOBBER, &ncid)) ERR; if (nc_def_dim(ncid, DIM1_NAME, NC_UNLIMITED, &dimid)) ERR; if (nc_def_var(ncid, VAR_NAME, NC_CHAR, 1, &dimid, &varid)) ERR; if (nc_close(ncid)) ERR; /* Create some phoney data. */ for (data[0] = 'a', r = 1; r < MAX_RECS; r++) data[r] = data[r - 1] + 1; /* Normally one would not close and reopen the file for each * record, nor add an attribute each time I add a record, but I am * giving the library a little work-out here... */ for (r = 0; r < MAX_RECS; r++) { /* Write one record of var data, a single character. */ if (nc_open(testfile, NC_WRITE, &ncid)) ERR; count[0] = 1; start[0] = r; if (nc_put_vara_text(ncid, varid, start, count, &data[r])) ERR; sprintf(att_name, "a_%d", data[r]); if (nc_redef(ncid)) ERR; if (nc_put_att_text(ncid, varid, att_name, 1, &data[r])) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and check it. */ if (nc_open(testfile, NC_NOWRITE, &ncid)) ERR; if (nc_inq_dimlen(ncid, 0, &len_in)) ERR; if (len_in != r + 1) ERR; index[0] = r; if (nc_get_var1_text(ncid, 0, index, &data_in)) ERR; if (data_in != data[r]) ERR; if (nc_get_att_text(ncid, varid, att_name, &data_in)) ERR; if (data_in != data[r]) ERR; if (nc_close(ncid)) ERR; } /* Next record. */ return 0; }
int nccf_inq_convention(int ncid, int *cf_convention) { size_t len, new_len; char *existing_att = NULL; int ret = CF_NOERR; /* Find out if there is a conventions attribute. */ ret = nc_inq_attlen(ncid, NC_GLOBAL, CF_CONVENTIONS, &len); if (ret == NC_NOERR) { /* Get memory to hold the existing att plus our version * string. */ new_len = len + strlen(CF_CONVENTION_STRING) + 1; if (!(existing_att = malloc(new_len))) return CF_ENOMEM; /* Get the existing att. */ if ((ret = nc_get_att_text(ncid, NC_GLOBAL, CF_CONVENTIONS, existing_att))) BAIL(CF_ENETCDF); /* If it's already in the string, our work is done.*/ if (strstr(existing_att, CF_CONVENTION_STRING)) { if (cf_convention) *cf_convention = 1; ret = CF_NOERR; } } else if (ret == NC_ENOTATT) { /* No conventions att means no cf conventions. ;-( But this is * not an error. */ if (cf_convention) *cf_convention = 0; ret = NC_NOERR; } else BAIL(CF_ENETCDF); exit: if (existing_att) free(existing_att); return ret; }
static void pr_att( int ncid, int varid, const char *varname, int ia ) { struct ncatt att; /* attribute */ NC_CHECK( nc_inq_attname(ncid, varid, ia, att.name) ); Printf ("\t\t%s:%s = ", varname, att.name); NC_CHECK( nc_inq_att(ncid, varid, att.name, &att.type, &att.len) ); if (att.len == 0) { /* show 0-length attributes as empty strings */ att.type = NC_CHAR; att.len = 1; } switch (att.type) { case NC_CHAR: att.string = (char *) malloc(att.len); if (!att.string) { error("Out of memory!"); NC_CHECK( nc_close(ncid) ); return; } NC_CHECK( nc_get_att_text(ncid, varid, att.name, att.string ) ); pr_att_string(att.len, att.string); free(att.string); break; default: att.vals = (double *) malloc(att.len * sizeof(double)); if (!att.vals) { error("Out of memory!"); NC_CHECK( nc_close(ncid) ); return; } NC_CHECK( nc_get_att_double(ncid, varid, att.name, att.vals ) ); pr_att_vals(att.type, att.len, att.vals); free(att.vals); break; } Printf (" ;\n"); }
NCprojection NCdataGetProjection(int ncid) { int dimid; char projName[NC_MAX_NAME]; if (nc_get_att_text(ncid, NC_GLOBAL, NCnameGAProjection, projName) == NC_NOERR) { if (strcmp(projName, NCnameGAProjCartesian)) return (NCprojCartesian); else if (strcmp(projName, NCnameGAProjSpherical)) return (NCprojSpherical); CMmsgPrint(CMmsgAppError, "Invalid data type in: %s %d", __FILE__, __LINE__); } else { if (nc_inq_dimid(ncid, NCnameDNXCoord, &dimid) == NC_NOERR) return (NCprojCartesian); else if (nc_inq_dimid(ncid, NCnameDNLon, &dimid) == NC_NOERR) return (NCprojSpherical); else if (nc_inq_dimid(ncid, NCnameDNLongitude, &dimid) == NC_NOERR) return (NCprojSpherical); CMmsgPrint(CMmsgAppError, "Nongeographical data in: %s %d", __FILE__, __LINE__); } return (NCprojNoCoordinates); }
/* * Get the value of a netCDF character attribute given its variable * ID and name. */ static void c_ncagtc( int ncid, /* netCDF ID */ int varid, /* variable ID */ const char* attname, /* attribute name */ char* value, /* pointer to data values */ int attlen, /* length of string argument */ int* rcode /* returned error code */ ) { int status; nc_type datatype; if ((status = nc_inq_atttype(ncid, varid, attname, &datatype)) == 0) { if (datatype != NC_CHAR) status = NC_ECHAR; else { size_t len; status = nc_inq_attlen(ncid, varid, attname, &len); if (status == 0) { if (attlen < len) status = NC_ESTS; else { status = nc_get_att_text(ncid, varid, attname, value); if (status == 0) (void) memset(value+len, ' ', attlen - len); } } } } if (status == 0) *rcode = 0; else { nc_advise("NCAGTC", status, ""); *rcode = ncerr; } }
/******************************************************************* void mpp_get_var_att(int fid, int vid, const char *name, void *val) get the attribute value of vid from file fid. ******************************************************************/ void mpp_get_var_att(int fid, int vid, const char *name, void *val) { int status; char errmsg[512]; nc_type type; if(fid<0 || fid >=nfiles) mpp_error("mpp_io(mpp_get_var_att): 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_att): invalid vid number, vid should be " "a nonnegative integer that less than nvar"); status = nc_inq_atttype(files[fid].ncid, files[fid].var[vid].fldid, name, &type); if(status != NC_NOERR) { sprintf(errmsg, "mpp_io(mpp_get_var_att): Error in getting type of attribute %s of field %s in file %s ", name, files[fid].var[vid].name, files[fid].name ); netcdf_error(errmsg, status); } switch(type) { case NC_DOUBLE:case NC_FLOAT: status = nc_get_att_double(files[fid].ncid, files[fid].var[vid].fldid, name, val); break; case NC_INT: status = nc_get_att_int(files[fid].ncid, files[fid].var[vid].fldid, name, val); break; case NC_SHORT: status = nc_get_att_short(files[fid].ncid, files[fid].var[vid].fldid, name, val); break; case NC_CHAR: status = nc_get_att_text(files[fid].ncid, files[fid].var[vid].fldid, name, val); break; default: sprintf(errmsg, "mpp_io(mpp_get_var_att): attribute %s of field %s in file %s has an invalid type, " "the type should be NC_DOUBLE, NC_FLOAT, NC_INT, NC_SHORT or NC_CHAR", name, files[fid].var[vid].name, files[fid].name ); mpp_error(errmsg); } if(status != NC_NOERR) { sprintf(errmsg, "mpp_io(mpp_get_var_att): Error in getting value of attribute %s of variable %s from file %s", name, files[fid].var[vid].name, files[fid].name ); netcdf_error(errmsg, status); } }
/* Given the varid of a system, write an attribute to a varid, whcih * indicates that it (the var) partakes of the system. Recall that the * system is just a collection of var names which are axes of the * coordinate system. */ int nccf_assign_coord_system(int ncid, int varid, int system_varid) { char system_name[NC_MAX_NAME + 1]; char *systems_str; size_t len, new_len = 0; int ret; /* Find the name of this system. */ if ((ret = nc_inq_varname(ncid, system_varid, system_name))) return ret; /* Is the att already here? If so, get it's length, then it's * contents, then append a space and the new system name. */ ret = nc_inq_att(ncid, varid, COORDINATE_SYSTEMS, NULL, &len); if (ret != NC_ENOTATT && ret != NC_NOERR) return ret; if (!ret) new_len += len; new_len += strlen(system_name) + 1; if (!(systems_str = malloc(new_len))) return NC_NOERR; systems_str[0] = 0; if (!ret) { if ((ret = nc_get_att_text(ncid, varid, COORDINATE_SYSTEMS, systems_str))) return ret; strcat(systems_str, " "); } strcat(systems_str, system_name); /* Write an att, called _CoordinateSystems, which * contains a list of the system names related to this variable. */ ret = nc_put_att_text(ncid, varid, COORDINATE_SYSTEMS, strlen(systems_str) + 1, systems_str); /* Free the memory we allocated. */ free(systems_str); return ret; }