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); }
/********************************************************************************* * Return the varid of the only var in the file, or -1 if more than one. */ int R_ncu_varid_onlyvar( int ncid ) { int ierr, nvars, varid, i, dimid; char varname[MAX_NC_NAME]; varid = -1; ierr = nc_inq_nvars( ncid, &nvars ); if( ierr != NC_NOERR ) error("Error reading from netcdf file!"); for( i=0; i<nvars; i++ ) { ierr = nc_inq_varname( ncid, i, varname ); if( ierr != NC_NOERR ) error("Error reading from netcdf file!"); ierr = nc_inq_dimid( ncid, varname, &dimid ); if( ierr != NC_NOERR ) { /* Did NOT find this var as a dim, means it is NOT a dimvar */ if( varid != -1 ) /* More than one non-dimvar dim in this file */ return( -1 ); varid = i; } } return( varid ); }
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); }
int NcFile::num_vars( void ) const { int num = 0; if (is_valid()) NcError::set_err( nc_inq_nvars(the_id, &num) ); return num; }
/* * 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; }
NCstate NCdataCopyAllAttibutes(int inNCid, int outNCid, bool overwrite) { int status, inVarid, outVarid, varnum; char varName[NC_MAX_NAME]; if (NCdataCopyAttributes(inNCid, NC_GLOBAL, outNCid, NC_GLOBAL, overwrite) == NCfailed) return (NCfailed); if ((status = nc_inq_nvars(inNCid, &varnum)) != NC_NOERR) { NCprintNCError (status, "NCdataCopyAttibutes"); return (NCfailed); } for (inVarid = 0; inVarid < varnum; ++inVarid) { if ((status = nc_inq_varname(inNCid, inVarid, varName)) != NC_NOERR) { NCprintNCError (status, "NCdataCopyAttibutes"); return (NCfailed); } if ((status = nc_inq_varid(outNCid, varName, &outVarid)) != NC_NOERR) continue; if (NCdataCopyAttributes(inNCid, inVarid, outNCid, outVarid, overwrite) == NCfailed) return (NCfailed); } return (NCsucceeded); }
/* * 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; }
NCtable_t *NCtableOpen(int ncid, char *tablename) { int status, *dimids, dimid, i = 0, j = 0; int ndims, nvars; size_t nrecords; size_t len; char varname [NC_MAX_NAME]; nc_type type; NCfield_t *field = (NCfield_t *) NULL; NCtable_t *tbl = (NCtable_t *) NULL; if((status = nc_inq_dimid (ncid,tablename,&dimid)) != NC_NOERR) { NCprintNCError (status,"NCtableOpen"); return ((NCtable_t *) NULL); } if((status = nc_inq_dimlen (ncid,dimid,&nrecords)) != NC_NOERR) { NCprintNCError (status,"NCtableOpen"); return ((NCtable_t *) NULL); } if((status = nc_inq_nvars (ncid,&nvars)) != NC_NOERR) { NCprintNCError (status,"NCtableOpen"); return ((NCtable_t *) NULL); } if(nc_inq_ndims(ncid,&ndims) != NC_NOERR) { NCprintNCError (status,"NCtableOpen"); return ((NCtable_t *) NULL); } if ((dimids = (int *) malloc(sizeof(int) * ndims)) == (int *) NULL) { CMmsgPrint (CMmsgSysError, "Memory allocation error in: %s %d",__FILE__,__LINE__); return (NCtable_t *) NULL; } if ((tbl = (NCtable_t *) malloc(sizeof(NCtable_t))) == (NCtable_t *) NULL) { CMmsgPrint (CMmsgSysError, "Memory allocation error in: %s %d",__FILE__,__LINE__); free (dimids); return ((NCtable_t *) NULL); } if ((tbl->Name = (char *) malloc (strlen(tablename) + 1)) == (char *) NULL) { CMmsgPrint (CMmsgSysError, "Memory allocation error in: %s %d",__FILE__,__LINE__); free (dimids); free (tbl); return ((NCtable_t *) NULL); } strcpy(tbl->Name,tablename); tbl->NFields = 0; tbl->Fields = (NCfield_t *) NULL; for(i = 0; i < nvars; i++) { if ((status = nc_inq_vartype(ncid,i,&type)) != NC_NOERR) { NCprintNCError (status,"NCtableOpen"); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); } if ((len = _NCtableVarLen(ncid,i,dimid,dimids)) == NCfailed) continue; if ((type != NC_CHAR) && (len > 1)) continue; if((status = nc_inq_varname(ncid,i,varname)) != NC_NOERR) { NCprintNCError (status,"NCtableOpen"); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); } if ((tbl->Fields = (NCfield_t *) realloc (tbl->Fields, sizeof (NCfield_t) * (tbl->NFields + 1))) == (NCfield_t *) NULL) { CMmsgPrint (CMmsgSysError, "Error allocating memory in: %s %d",__FILE__,__LINE__); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); } field = tbl->Fields + tbl->NFields; tbl->NFields += 1; field->NRecords = nrecords; field->Data = (void *) NULL; field->Name = (char *) NULL; field->Type = type; field->Len = len; if ((field->Name = malloc (strlen (varname) + 1)) == (char *) NULL) { CMmsgPrint (CMmsgSysError, "Error allocating memory in: %s %d",__FILE__,__LINE__); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); } strcpy (field->Name,varname); if (nc_get_att_double (ncid,i,NCnameVAScaleFactor,&field->Scale) != NC_NOERR) field->Scale = 1.0; if (nc_get_att_double (ncid,i,NCnameVAAddOffset, &field->Offset) != NC_NOERR) field->Offset = 0.0; switch(field->Type) { case NC_CHAR: if ((field->Data = (void *) malloc(field->NRecords * field->Len * sizeof (char))) == (void *) NULL) { CMmsgPrint (CMmsgSysError, "Error allocating memory in: %s %d",__FILE__,__LINE__); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); } if((status = nc_get_var_text(ncid,i,(char *) (field->Data))) != NC_NOERR) { NCprintNCError (status,"NCtableOpen"); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); } break; case NC_BYTE: case NC_SHORT: case NC_INT: if ((field->Data = (void *) malloc(field->NRecords * field->Len * sizeof (int))) == (void *) NULL) { CMmsgPrint (CMmsgSysError, "Error allocating memory in: %s %d",__FILE__,__LINE__); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); } if((status = nc_get_var_int(ncid,i,(int *) (field->Data))) != NC_NOERR) { NCprintNCError (status,"NCtableOpen"); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); } if (nc_get_att_int (ncid,i,NCnameVAFillValue, &field->FillValue.Int) != NC_NOERR) field->FillValue.Int = INT_NOVALUE; if (nc_get_att_double (ncid,i,NCnameVAMissingVal, &field->MissingVal) != NC_NOERR) field->MissingVal = FLOAT_NOVALUE; break; case NC_FLOAT: case NC_DOUBLE: if ((field->Data = (void *) malloc(field->NRecords * field->Len * sizeof (double))) == (void *) NULL) { CMmsgPrint (CMmsgSysError, "Error allocating memory in: %s %d",__FILE__,__LINE__); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); } if((status = nc_get_var_double(ncid,i,(double *) (field->Data))) != NC_NOERR) { NCprintNCError (status,"NCtableOpen"); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); } if (nc_get_att_double (ncid,i,NCnameVAFillValue, &field->FillValue.Float) != NC_NOERR) field->FillValue.Float = FLOAT_NOVALUE; if (nc_get_att_double (ncid,i,NCnameVAMissingVal, &field->MissingVal) != NC_NOERR) field->MissingVal = FLOAT_NOVALUE; break; default: field->Data = (void *) NULL; break; } if(GetDebug()) CMmsgPrint (CMmsgUsrError, "Loaded: %s(dimid: %d)\n",field->Name,dimid); } if(GetDebug()) { CMmsgPrint (CMmsgUsrError, "Dim: %d Name: %s Cols: %d Rows: %d\n",dimid,tbl->Name,tbl->NFields,field->NRecords); for(i = 0; i < tbl->NFields; i++) { field = tbl->Fields + i; CMmsgPrint (CMmsgUsrError, "\tField: %d Name: %s ",i,field->Name); switch(field->Type) { case NC_CHAR: if(field->Len == 1) { CMmsgPrint (CMmsgUsrError, "Type: char\n"); for(j = 0; j < 5; j++) CMmsgPrint (CMmsgUsrError, "\t\t%d %c\n",j,((char *) (field->Data)) [j]); } else { CMmsgPrint (CMmsgUsrError, "Type: string\n"); for(j = 0; j < 5; j++) CMmsgPrint (CMmsgUsrError, "\t\t%d %s\n",j,((char *) (field->Data)) + j * field->Len); } break; case NC_BYTE: case NC_SHORT: case NC_INT: CMmsgPrint (CMmsgUsrError, "Type: int\n"); for(j = 0; j < 5; j++) CMmsgPrint (CMmsgUsrError, "\t\t%d %i\n",j,((int *) (field->Data)) [j]); break; case NC_FLOAT: case NC_DOUBLE: CMmsgPrint (CMmsgUsrError, "Type: double\n"); for(j = 0; j < 5; j++) CMmsgPrint (CMmsgUsrError, "\t\t%d %f\n",j,((double *) (field->Data)) [j]); break; default: break; } } } return (tbl); }
int check_4D_example(char *file_name, int expected_format) { int ncid; int format, ndims_in, nvars_in, natts_in; int dimid[NDIMS_EX]; int varid[NVARS_EX]; char dim_name_in[NDIMS_EX][NC_MAX_NAME]; char var_name_in[NVARS_EX][NC_MAX_NAME]; char name_in[NC_MAX_NAME + 1]; char units_in[NC_MAX_NAME + 1]; nc_type xtype_in; size_t len_in; int i; if (nc_open(file_name, 0, &ncid)) ERR; /* Count stuff. */ if (nc_inq_format(ncid, &format)) ERR; if (nc_inq_ndims(ncid, &ndims_in)) ERR; if (ndims_in != NDIMS_EX) ERR; if (nc_inq_nvars(ncid, &nvars_in)) ERR; if (nvars_in != NVARS_EX) ERR; if (nc_inq_natts(ncid, &natts_in)) ERR; if (natts_in != 0) ERR; if (format != expected_format) ERR; /* Check dimensions. */ ndims_in = 0; if (nc_inq_dimids(ncid, &ndims_in, dimid, 0)) ERR; if (ndims_in != NDIMS_EX) ERR; for (i = 0; i < NDIMS_EX; i++) { if (dimid[i] != i) ERR; if (nc_inq_dimname(ncid, i, dim_name_in[i])) ERR; } if (strcmp(dim_name_in[0], LVL_NAME) || strcmp(dim_name_in[1], LAT_NAME) || strcmp(dim_name_in[2], LON_NAME) || strcmp(dim_name_in[3], REC_NAME)) ERR; /* Check variables. */ nvars_in = 0; if (nc_inq_varids(ncid, &nvars_in, varid)) ERR; if (nvars_in != NVARS_EX) ERR; for (i = 0; i < NVARS_EX; i++) { if (varid[i] != i) ERR; if (nc_inq_varname(ncid, i, var_name_in[i])) ERR; } if (strcmp(var_name_in[0], LAT_NAME) || strcmp(var_name_in[1], LON_NAME) || strcmp(var_name_in[2], PRES_NAME) || strcmp(var_name_in[3], TEMP_NAME)) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimid, &natts_in)) ERR; if (strcmp(name_in, LAT_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 || dimid[0] != 1 || natts_in != 1) ERR; if (nc_inq_var(ncid, 1, name_in, &xtype_in, &ndims_in, dimid, &natts_in)) ERR; if (strcmp(name_in, LON_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 || dimid[0] != 2 || natts_in != 1) ERR; if (nc_inq_var(ncid, 2, name_in, &xtype_in, &ndims_in, dimid, &natts_in)) ERR; if (strcmp(name_in, PRES_NAME) || xtype_in != NC_FLOAT || ndims_in != 4 || dimid[0] != 3 || dimid[1] != 0 || dimid[2] != 1 || dimid[3] != 2 || natts_in != 1) ERR; if (nc_inq_var(ncid, 3, name_in, &xtype_in, &ndims_in, dimid, &natts_in)) ERR; if (strcmp(name_in, TEMP_NAME) || xtype_in != NC_FLOAT || ndims_in != 4 || dimid[0] != 3 || dimid[1] != 0 || dimid[2] != 1 || dimid[3] != 2 || natts_in != 1) ERR; /* Check variable atts. */ if (nc_inq_att(ncid, 0, UNITS, &xtype_in, &len_in)) ERR; if (xtype_in != NC_CHAR || len_in != strlen(DEGREES_NORTH)) ERR; if (nc_get_att_text(ncid, 0, UNITS, units_in)) ERR; if (strncmp(units_in, DEGREES_NORTH, strlen(DEGREES_NORTH))) ERR; if (nc_inq_att(ncid, 1, UNITS, &xtype_in, &len_in)) ERR; if (xtype_in != NC_CHAR || len_in != strlen(DEGREES_EAST)) ERR; if (nc_get_att_text(ncid, 1, UNITS, units_in)) ERR; if (strncmp(units_in, DEGREES_EAST, strlen(DEGREES_EAST))) ERR; if (nc_inq_att(ncid, 2, UNITS, &xtype_in, &len_in)) ERR; if (xtype_in != NC_CHAR || len_in != strlen(PRES_UNITS)) ERR; if (nc_get_att_text(ncid, 2, UNITS, units_in)) ERR; if (strncmp(units_in, PRES_UNITS, strlen(PRES_UNITS))) ERR; if (nc_inq_att(ncid, 3, UNITS, &xtype_in, &len_in)) ERR; if (xtype_in != NC_CHAR || len_in != strlen(TEMP_UNITS)) ERR; if (nc_get_att_text(ncid, 3, UNITS, units_in)) ERR; if (strncmp(units_in, TEMP_UNITS, strlen(TEMP_UNITS))) ERR; if (nc_close(ncid)) ERR; return err; }
int main(int argc, char **argv) { size_t sizehint = 2100000; /* default if not set on command line, * exposes bug. It turns out any * value between 2091953 and 2150032 * triggers bug, whereas all other * values work fine. */ if (argc > 1) { char *endptr, *str = argv[1]; errno = 0; sizehint = strtol(str, &endptr, 0); /* check for various possible errors */ if ((errno == ERANGE && (sizehint == LONG_MAX || sizehint == LONG_MIN)) || (errno != 0 && sizehint == 0)) { perror("strtol"); exit(EXIT_FAILURE); } if (endptr == str) { fprintf(stderr, "No digits were found\n"); exit(EXIT_FAILURE); } } printf("\n*** Testing nofill mode.\n"); { printf("*** Create file in nofill mode, writing all values..."); if (create_file(FILE_NAME1, NC_NOFILL, &sizehint)) ERR; SUMMARIZE_ERR; } { printf("*** Create file with same data in fill mode, writing all values..."); if (create_file(FILE_NAME2, NC_FILL, &sizehint)) ERR; SUMMARIZE_ERR; } { int ncid1, ncid2; int nvars1, nvars2; int varid; int badvars; printf("*** Compare values in nofill mode and fill mode files..."); /* compare data in two files created with nofill mode and fill * mode, which should be identical if all the data were written */ if (nc_open(FILE_NAME1, NC_NOWRITE, &ncid1)) ERR; if (nc_open(FILE_NAME2, NC_NOWRITE, &ncid2)) ERR; if (nc_inq_nvars(ncid1, &nvars1)) ERR; if (nc_inq_nvars(ncid2, &nvars2)) ERR; if (nvars1 != nvars2) ERR; badvars = 0; for(varid = 0; varid < nvars1; varid++) { size_t nvals, nn; int ndims, *dimids, dim; nc_type vtype; char varname1[NC_MAX_NAME]; char varname2[NC_MAX_NAME]; /* How many values in this variable to compare? */ if (nc_inq_varndims(ncid1, varid, &ndims)) ERR; dimids = malloc((ndims + 1) * sizeof(int)); if (!dimids) ERR; if (nc_inq_vardimid (ncid1, varid, dimids)) ERR; nvals = 1; for(dim = 0; dim < ndims; dim++) { size_t len; if (nc_inq_dimlen(ncid1, dimids[dim], &len)) ERR; nvals *= len; } if (nc_inq_vartype(ncid1, varid, &vtype)) ERR; if (nc_inq_varname(ncid1, varid, varname1)) ERR; if (nc_inq_varname(ncid1, varid, varname2)) ERR; if (vtype != NC_CHAR) { /* numeric data, just read in as doubles */ double *data1, *data2; /* Allocate space to hold values in both files */ data1 = malloc((nvals + 1) * sizeof(double)); if (!data1) ERR; data2 = malloc((nvals + 1) * sizeof(double)); if (!data2) ERR; /* Read in values */ if (nc_get_var_double(ncid1, varid, data1)) ERR; if (nc_get_var_double(ncid2, varid, data2)) ERR; /* Compare values */ for(nn = 0; nn < nvals; nn++) { if (data1[nn] != data2[nn]) { badvars++; fprintf(stderr, "\tFrom nofill file, %s[%d] = %.15g\tFrom fill file, %s[%d] = %.15g\n", varname1, nn, data1[nn], varname2, nn, data2[nn]); break; }; } free(data1); free(data2); } else { /* character data */ char *data1, *data2; /* Allocate space to hold values in both files */ data1 = malloc((nvals + 1) * sizeof(char)); if (!data1) ERR; data2 = malloc((nvals + 1) * sizeof(char)); if (!data2) ERR; /* Read in values */ if (nc_get_var_text(ncid1, varid, data1)) ERR; if (nc_get_var_text(ncid2, varid, data2)) ERR; /* Compare values */ for(nn = 0; nn < nvals; nn++) { if (data1[nn] != data2[nn]) { badvars++; fprintf(stderr, "\tFrom nofill file, %s[%d] = %d\tFrom fill file, %s[%d] = %d\n", varname1, nn, data1[nn], varname2, nn, data2[nn]); break; }; } free(data1); free(data2); } free(dimids); } if(badvars > 0) ERR; if (nc_close(ncid1)) ERR; if (nc_close(ncid2)) ERR; SUMMARIZE_ERR; } FINAL_RESULTS; }
/* Has to be at the bottom because it uses many * other functions */ void sdatio_open_file(struct sdatio_file * sfile ) { /*printf("called\n");*/ int retval; int ndims, nvars; int i, j; struct sdatio_dimension * sdim; struct sdatio_variable * svar; size_t lengthp; int nunlimdims; int *unlimdims; int is_unlimited; char * name_tmp; int * vardimids; char * dimension_list; nc_type vartype; int vartypeint; int dummy; int *nunlim; DEBUG_MESS("starting sdatio_open_file\n"); retval = 0; if (sfile->is_open){ printf("ERROR: The supplied sdatio_file struct corresponds to an already open file.\n"); abort(); } /* We make the choice to always open the file in readwrite mode*/ sfile->mode = sfile->mode|NC_WRITE; DEBUG_MESS("sdatio_open_file opening file\n"); /* Open the file*/ if (sfile->is_parallel) { #ifdef PARALLEL if ((retval = nc_open_par(sfile->name, sfile->mode, *(sfile->communicator), MPI_INFO_NULL, &(sfile->nc_file_id)))) ERR(retval); #else printf("sdatio was built without --enable-parallel, sdatio_create_file will not work for parallel files\n"); abort(); #endif } else { if ((retval = nc_open(sfile->name, sfile->mode, &(sfile->nc_file_id)))) ERR(retval); } DEBUG_MESS("sdatio_open_file opened file\n"); /*Initialize object file data*/ sfile->is_open = 1; sfile->n_dimensions = 0; sfile->n_variables = 0; sfile->data_written = 0; /* Get number of dimensions in the file*/ if ((retval = nc_inq_ndims(sfile->nc_file_id, &ndims))) ERR(retval); /* Allocate some temp storate*/ name_tmp = (char*)malloc(sizeof(char*)*(NC_MAX_NAME+1)); /* Get a list of unlimited dimensions*/ if ((retval = nc_inq_unlimdims(sfile->nc_file_id, &nunlimdims, NULL))) ERR(retval); unlimdims = (int*)malloc(sizeof(int*)*nunlimdims); if ((retval = nc_inq_unlimdims(sfile->nc_file_id, &nunlimdims, unlimdims))) ERR(retval); /* Add each dimension to the sfile object*/ for (i=0; i<ndims; i++){ if ((retval = nc_inq_dim(sfile->nc_file_id, i, name_tmp, &lengthp))) ERR(retval); sdim = (struct sdatio_dimension *) malloc(sizeof(struct sdatio_dimension)); /*if ((retval = nc_def_dim(sfile->nc_file_id, dimension_name, size, &(sdim->nc_id)))) ERR(retval);*/ /*}*/ /*sdatio_end_definitions(sfile);*/ is_unlimited = 0; for(j=0; j<nunlimdims; j++) if (unlimdims[j] == i) is_unlimited = 1; if (is_unlimited) { sdim->size = SDATIO_UNLIMITED; /* We choose the first write to unlimited variables to be the last * existing record. Users can easily move to the next by * calling sdatio_increment_start before writing anything */ sdim->start = lengthp-1; } else { sdim->size = lengthp; sdim->start = 0; } if (strlen(name_tmp)>1){ sfile->has_long_dim_names = 1; /*printf("Dimension names can only be one character long!\n");*/ /*abort();*/ } sdim->nc_id = i; sdim->name = (char *)malloc(sizeof(char)*(strlen(name_tmp)+1)); strcpy(sdim->name, name_tmp); sdatio_append_dimension(sfile, sdim); } DEBUG_MESS("Finished reading dimensions\n"); /* Get the number of variables in the file*/ if ((retval = nc_inq_nvars(sfile->nc_file_id, &nvars))) ERR(retval); /* Add each variable to the sfile object*/ for (i=0; i<nvars; i++){ if ((retval = nc_inq_varndims(sfile->nc_file_id, i, &ndims))) ERR(retval); vardimids = (int*)malloc(sizeof(int)*ndims); if ((retval = nc_inq_var(sfile->nc_file_id, i, name_tmp, &vartype, &ndims, vardimids, &dummy))) ERR(retval); vartypeint = vartype; vartypeint = sdatio_sdatio_variable_type(vartypeint); svar = (struct sdatio_variable *) malloc(sizeof(struct sdatio_variable)); /*Set variable id*/ svar->nc_id = i; /* Set variable name*/ svar->name = (char *)malloc(sizeof(char)*(strlen(name_tmp)+1)); strcpy(svar->name, name_tmp); /*ndims = strlen(dimension_list);*/ svar->ndims = ndims; DEBUG_MESS("ndims = %d for variable %s\n", ndims, name_tmp); /* Set the dimension_ids*/ svar->dimension_ids = vardimids; /*sdatio_get_dimension_ids(sfile, dimension_list, svar);*/ sdatio_get_dimension_list(sfile, vardimids, svar); /*svar->dimension_ids = dimension_ids;*/ DEBUG_MESS("Setting type for variable %s\n", svar->name); switch (vartypeint){ case SDATIO_INT: svar->type_size = sizeof(int); break; case SDATIO_FLOAT: svar->type_size = sizeof(float); break; case SDATIO_DOUBLE: svar->type_size = sizeof(double); break; case SDATIO_CHAR: svar->type_size = sizeof(char); break; default: printf("Unknown type in sdatio_create_variable\n"); abort(); } svar->type = vartypeint; DEBUG_MESS("Allocating manual starts and counts for variable %s; ndims %d\n", svar->name, ndims); svar->manual_starts=(int*)malloc(sizeof(int)*ndims); svar->manual_counts=(int*)malloc(sizeof(int)*ndims); svar->manual_offsets=(int*)malloc(sizeof(int)*ndims); DEBUG_MESS("Setting manual starts and counts for variable %s\n", svar->name); for (j=0;j<ndims;j++){ svar->manual_starts[j]=-1; svar->manual_counts[j]=-1; svar->manual_offsets[j]=-1; } DEBUG_MESS("Starting sdatio_append_variable\n"); sdatio_append_variable(sfile, svar); DEBUG_MESS("Ending sdatio_append_variable\n"); #ifdef PARALLEL if (sfile->is_parallel){ sdatio_number_of_unlimited_dimensions(sfile, svar->name, &nunlim); if (nunlim > 0) if ((retval = nc_var_par_access(sfile->nc_file_id, svar->nc_id, NC_COLLECTIVE))) ERR(retval); } #endif /*vartypeint = */ } DEBUG_MESS("Finished reading variables\n"); free(unlimdims); free(name_tmp); }
int Read_NetCDF_METARS_Header( char *filename, irregular_v5dstruct *ir) { int temp, c, i, j, k, t, *times, tnid, status; int offset, numuniquetimes; int nc_id, numrecsid; int id, year, day, hour, minute, second; nc_type type; size_t sizea, sized, numrecs; int ntimes[MAXTIMES], uniquetimes[MAXTIMES]; char vname[1000]; char tdim[1000]; size_t num_cloud_layers; int numdims; int dimids[10]; size_t stringsize; int cloud_layer_id; int latid, lonid, hgtid; status = nc_open( filename, NC_NOWRITE, &nc_id); if(status != NC_NOERR){ return -1; } /****************/ /* get filename */ /****************/ strncpy(ir->filename, filename, 1000); /******************/ /* get file title */ /******************/ status = nc_get_att_text(nc_id, NC_GLOBAL, "title", ir->filetitle); if(status != NC_NOERR){ return -1; } /*************************/ /* get number of records */ /*************************/ status = nc_inq_dimid(nc_id, "recNum", &numrecsid); if(status != NC_NOERR){ return -1; } status = nc_inq_dimlen(nc_id, numrecsid, &numrecs); if(status != NC_NOERR){ return -1; } /****************/ /* get numtimes */ /****************/ for (i = 0; i < MAXTIMES; i++){ uniquetimes[i] = -1; } status = nc_inq_varid( nc_id, "time_nominal", &tnid); if(status != NC_NOERR){ return -1; } times = (int *) malloc(sizeof(int)*numrecs); if (!times){ return -1; } status = nc_get_var_int( nc_id, tnid, times); if(status != NC_NOERR){ free(times); return -1; } numuniquetimes = 1; uniquetimes[0] = times[0]; ntimes[0] = 1; for (i = 1; i < numrecs; i++){ for (j = 0; j < numuniquetimes; j++){ if (times[i] == uniquetimes[j]){ ntimes[j]++; break; } } if (j == numuniquetimes){ uniquetimes[j] = times[i]; ntimes[j] = 1; numuniquetimes++; } } ir->numtimes = numuniquetimes; /* bubble sort unique times */ for (i = 0; i < numuniquetimes; i++){ for (j = 0; j < numuniquetimes-1-i; j++){ if (times[j+1] > times[j]){ temp = uniquetimes[j]; uniquetimes[j] = uniquetimes[j+1]; uniquetimes[j+1] = temp; temp = ntimes[j]; ntimes[j] = ntimes[j+1]; ntimes[j+1] = temp; } } } ir->numrecs = 0; for (i = 0; i < ir->numtimes; i++){ if (ntimes[i] > ir->numrecs){ ir->numrecs = ntimes[i]; } } /***********************/ /* get day/time stamps */ /***********************/ for (i=0; i < ir->numtimes; i++){ t = times[i]; day = t/86400; t -= 86400 * day; if (day > 730){ day -= 730; year = (4*day)/1461; day = day - (365*year+(year-1)/4); year += 72; } else{ year = day / 365; day = day - (365*year); } hour = t/3600; t -= 3600*hour; minute = t/60; t -= 60*minute; second = t; ir->timestamp[i] = 10000*hour+100*minute+second; ir->daystamp[i] = 1000*year+day; } /*********************/ /* get variable info */ /*********************/ status = nc_inq_nvars( nc_id, &ir->numvars); if(status != NC_NOERR){ free(times); return -1; } /* check to make sure lat, lon and hgt are there */ /* and subtract 3 from the total number of variables */ status = nc_inq_varid( nc_id, METAR_LAT, &latid); if(status != NC_NOERR){ free(times); return -1; } status = nc_inq_varid( nc_id, METAR_LON, &lonid); if(status != NC_NOERR){ free(times); return -1; } status = nc_inq_varid( nc_id, METAR_HGT, &hgtid); if(status != NC_NOERR){ free(times); return -1; } /* useless! for (i = 0; i < numrecs; i++){ size_t theindex[3]; theindex[0] = i; theindex[1] = 0; for (j = 0; j < 4; j++){ theindex[2] = j; nc_get_var1_text(nc_id, 20, theindex, &tdim[j]); } tdim[4] = 0; } */ offset = 0; /* get cloud layers */ status = nc_inq_dimid(nc_id, METAR_CLOUD_LAYERS, &cloud_layer_id); if(status != NC_NOERR){ printf("no cloud_layers dimension\n"); free(times); return -1; } status = nc_inq_dimlen(nc_id, cloud_layer_id, &num_cloud_layers); if(status != NC_NOERR){ printf("no cloud_layers dimension\n"); free(times); return -1; } if (num_cloud_layers < 1 || num_cloud_layers > 9){ printf("number of cloud layers must be between 1..9\n"); free(times); return -1; } for (i = 0; i < ir->numvars; i++){ k = i - offset; status = nc_inq_varname( nc_id, i, vname); if(status != NC_NOERR){ free(times); return -1; } status = nc_inq_vartype( nc_id, i, &type); if(status != NC_NOERR){ free(times); return -1; } if (strncmp(METAR_LAT, vname, strlen(METAR_LAT)) != 0 && strncmp(METAR_LON, vname, strlen(METAR_LON)) != 0 && strncmp(METAR_HGT, vname, strlen(METAR_HGT)) != 0){ if (strlen(vname) < MAX_VAR_LENGTH){ strncpy(ir->VarName[k], vname, MAX_VAR_LENGTH); status = nc_inq_varndims( nc_id, i, &numdims); if(status != NC_NOERR){ printf("error getting numdims\n"); free(times); return -1; } status = nc_inq_vardimid( nc_id, i, dimids); if(status != NC_NOERR){ printf("error getting dimids\n"); free(times); return -1; } if (type == NC_CHAR){ if (numdims == 3){ /* cloud layers so get max num of layers */ /* and create vars to correspond to cl layers */ ir->VarName[k][strlen(ir->VarName[k])] = '0'; for (c = 1; c < num_cloud_layers; c++){ strncpy(ir->VarName[k+c], vname, MAX_VAR_LENGTH); ir->VarName[k+c][strlen(ir->VarName[k+c])] = c + '0'; offset--; } status = nc_inq_dimlen( nc_id, dimids[2], &stringsize); if(status != NC_NOERR){ printf("error getting stringsize\n"); free(times); return -1; } for (c = 0; c < num_cloud_layers; c++){ ir->CharVarLength[k+c] = stringsize+1; ir->VarType[k] = 1; } } else if (numdims == 2){ status = nc_inq_dimlen( nc_id, dimids[1], &stringsize); if(status != NC_NOERR){ printf("error getting stringsize\n"); free(times); return -1; } ir->CharVarLength[k] = stringsize+1; } else{ printf("don't know what to do with four dimensional var\n"); free(times); return -1; } ir->VarType[k] = 1; ir->CharVarLength[k] = stringsize+1; } else{ if (numdims == 2){ if (dimids[1] != cloud_layer_id){ printf("error with var second demension\n"); free(times); return -1; } ir->VarName[k][strlen(ir->VarName[k])] = '0'; for (c = 1; c < num_cloud_layers; c++){ strncpy(ir->VarName[k+c], vname, MAX_VAR_LENGTH); ir->VarName[k+c][strlen(ir->VarName[k+c])] = c + '0'; offset--; ir->CharVarLength[k+c] = 0; ir->VarType[k+c] = 0; } } ir->VarType[k] = 0; ir->CharVarLength[k+c] = 0; } } else{ /* don't include this var becuase */ /* wont be able to access it by its */ /* full variable name later */ offset++; } } else{ offset++; } } ir->numvars -= offset; /* for (c = 0; c < ir->numvars; c++){ printf("var = %d name = %s\n", c, ir->VarName[c]); } */ free(times); /* get bounds */ ir->NorthBound = 0.0; ir->SouthBound = 0.0; ir->WestBound = 0.0; ir->EastBound = 0.0; ir->BottomBound =0.0; ir->TopBound = 0.0; { float *latdata, *londata, *hgtdata; latdata = (float *) malloc(numrecs * sizeof(float)); if (!latdata){ printf("couldn't allocate enough memory\n"); return -1; } londata = (float *) malloc(numrecs * sizeof(float)); if (!londata){ printf("couldn't allocate enough memory\n"); free(latdata); return -1; } hgtdata = (float *) malloc(numrecs * sizeof(float)); if (!hgtdata){ printf("couldn't allocate enough memory\n"); free(latdata); free(londata); return -1; } status = nc_get_var_float( nc_id, latid, latdata); if(status != NC_NOERR){ printf("error getting bounds\n"); free(latdata); free(londata); free(hgtdata); return -1; } status = nc_get_var_float( nc_id, lonid, londata); if(status != NC_NOERR){ printf("error getting bounds\n"); free(latdata); free(londata); free(hgtdata); return -1; } status = nc_get_var_float( nc_id, hgtid, hgtdata); if(status != NC_NOERR){ printf("error getting bounds\n"); free(latdata); free(londata); free(hgtdata); return -1; } for (i = 0; i < numrecs; i++){ if (latdata[i] != -99999.0){ if (latdata[i] > ir->NorthBound){ ir->NorthBound = latdata[i]; } else if (latdata[i] < ir->SouthBound){ ir->SouthBound = latdata[i]; } } } for (i = 0; i < numrecs; i++){ if (londata[i] != -99999.0){ if (londata[i] < ir->EastBound){ ir->EastBound = londata[i]; } else if (londata[i] > ir->WestBound){ ir->WestBound = londata[i]; } } } for (i = 0; i < numrecs; i++){ if (hgtdata[i] != -99999.0){ if (hgtdata[i] > ir->TopBound){ ir->TopBound = hgtdata[i]; } else if (hgtdata[i] < ir->BottomBound){ ir->BottomBound = hgtdata[i]; } } } printf("n = %f s = %f w = %f e = %f t = %f b = %f\n", ir->NorthBound, ir->SouthBound, ir->WestBound, ir->EastBound, ir->TopBound, ir->BottomBound); } return 0; }
void bi::InputNetCDFBuffer::map() { int ncDim, ncVar; Var* var; std::string name; VarType type; int i, k, id; /* ns dimension */ nsDim = nc_inq_dimid(ncid, "ns"); if (nsDim >= 0) { BI_ERROR_MSG(ns < (int )nc_inq_dimlen(ncid, nsDim), "Given index " << ns << " outside range of ns dimension"); } /* np dimension */ npDim = nc_inq_dimid(ncid, "np"); if (npDim >= 0) { BI_ERROR_MSG(np < 0 || np < (int )nc_inq_dimlen(ncid, npDim), "Given index " << np << " outside range of np dimension"); } /* record dimensions, time and coordinate variables */ int nvars = nc_inq_nvars(ncid); for (i = 0; i < nvars; ++i) { ncVar = i; name = nc_inq_varname(ncid, i); if (name.find("time") == 0) { /* is a time variable */ ncDim = mapTimeDim(ncVar); if (ncDim >= 0) { BOOST_AUTO(iter, std::find(recDims.begin(), recDims.end(), ncDim)); if (iter == recDims.end()) { /* newly encountered record dimension */ recDims.push_back(ncDim); timeVars.push_back(ncVar); coordVars.push_back(-1); } else { /* record dimension encountered before */ k = std::distance(recDims.begin(), iter); BI_ASSERT_MSG(timeVars[k] < 0, "Time variables " << nc_inq_varname(ncid, timeVars[k]) << " and " << name << " cannot share the same record dimension " << nc_inq_dimname(ncid, *iter)); timeVars[k] = ncVar; } } } else if (name.find("coord") == 0) { /* is a coordinate variable */ ncDim = mapCoordDim(ncVar); if (ncDim >= 0) { BOOST_AUTO(iter, std::find(recDims.begin(), recDims.end(), ncDim)); if (iter == recDims.end()) { /* newly encountered record dimension */ recDims.push_back(ncDim); timeVars.push_back(-1); coordVars.push_back(ncVar); } else { /* record dimension encountered before */ k = std::distance(recDims.begin(), iter); BI_ASSERT_MSG(coordVars[k] < 0, "Coordinate variables " << nc_inq_varname(ncid, coordVars[k]) << " and " << name << " cannot share the same record dimension " << nc_inq_dimname(ncid, *iter)); coordVars[k] = ncVar; } } } } /* model variables */ for (i = 0; i < NUM_VAR_TYPES; ++i) { type = static_cast<VarType>(i); /* initialise NetCDF variables for this type */ vars[type].resize(m.getNumVars(type), -1); /* map model variables */ for (id = 0; id < m.getNumVars(type); ++id) { var = m.getVar(type, id); if (var->hasInput()) { BOOST_AUTO(pair, mapVarDim(var)); k = pair.first; ncVar = pair.second; if (ncVar >= 0) { vars[type][id] = ncVar; } modelVars.insert(std::make_pair(k, var)); } } } /* preload random access tables */ std::multimap<real,int> seq; std::vector<size_t> starts(recDims.size(), 0), lens(recDims.size(), 0); real tnxt; for (k = 0; k < int(recDims.size()); ++k) { if (timeVars[k] >= 0 && modelVars.count(k) > 0) { /* ^ ignores record dimensions with no associated time or model * variables */ readTime(timeVars[k], starts[k], &lens[k], &tnxt); seq.insert(std::make_pair(tnxt, k)); } } while (!seq.empty()) { /* next in time */ tnxt = seq.begin()->first; k = seq.begin()->second; seq.erase(seq.begin()); ncDim = recDims[k]; ncVar = timeVars[k]; if (times.empty() || times.back() != tnxt) { times.push_back(tnxt); recStarts.push_back(std::vector < size_t > (recDims.size(), 0)); recLens.push_back(std::vector < size_t > (recDims.size(), 0)); } recStarts.back()[k] = starts[k]; recLens.back()[k] = lens[k]; /* read next time and range for this time variable */ starts[k] += lens[k]; if (starts[k] < nc_inq_dimlen(ncid, ncDim)) { /* more to come on this record dimension */ readTime(ncVar, starts[k], &lens[k], &tnxt); seq.insert(std::make_pair(tnxt, k)); } } }