static int read_numeric_attribute(int ncid, int varid, const char *name, harp_data_type *data_type, harp_scalar *data) { nc_type netcdf_data_type; size_t netcdf_num_elements; int result; result = nc_inq_att(ncid, varid, name, &netcdf_data_type, &netcdf_num_elements); if (result != NC_NOERR) { harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result)); return -1; } if (netcdf_num_elements != 1) { harp_set_error(HARP_ERROR_IMPORT, "attribute '%s' has invalid format", name); return -1; } if (get_harp_type(netcdf_data_type, data_type) != 0) { harp_add_error_message(" (attribute '%s')", name); return -1; } switch (netcdf_data_type) { case NC_BYTE: result = nc_get_att_schar(ncid, varid, name, &data->int8_data); break; case NC_SHORT: result = nc_get_att_short(ncid, varid, name, &data->int16_data); break; case NC_INT: result = nc_get_att_int(ncid, varid, name, &data->int32_data); break; case NC_FLOAT: result = nc_get_att_float(ncid, varid, name, &data->float_data); break; case NC_DOUBLE: result = nc_get_att_double(ncid, varid, name, &data->double_data); break; default: harp_set_error(HARP_ERROR_IMPORT, "attribute '%s' has invalid type", name); return -1; } if (result != NC_NOERR) { harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result)); return -1; } return 0; }
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; }
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"); }
/******************************************************************* void mpp_get_var_att_double(int fid, int vid, const char *name, double *val) get the attribute value of vid from file fid. ******************************************************************/ void mpp_get_var_att_double(int fid, int vid, const char *name, double *val) { int status; char errmsg[512]; nc_type type; short sval; int ival; 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, &ival); *val = ival; break; case NC_SHORT: status = nc_get_att_short(files[fid].ncid, files[fid].var[vid].fldid, name, &sval); *val = sval; 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); } }
/******************************************************************* void mpp_get_global_att(int fid, const char *name, void *val) get the global attribute from file fid. ******************************************************************/ void mpp_get_global_att(int fid, const char *name, void *val) { int status; char errmsg[512]; nc_type type; if(fid<0 || fid >=nfiles) mpp_error("mpp_io(mpp_get_global_att): invalid fid number, fid should be " "a nonnegative integer that less than nfiles"); status = nc_inq_atttype(files[fid].ncid, NC_GLOBAL, name, &type); if(status != NC_NOERR) { sprintf(errmsg, "mpp_io(mpp_get_global_att): Error in getting type of global attribute %s in file %s ", name, files[fid].name ); netcdf_error(errmsg, status); } switch(type) { case NC_DOUBLE:case NC_FLOAT: status = nc_get_att_double(files[fid].ncid, NC_GLOBAL, name, val); break; case NC_INT: status = nc_get_att_int(files[fid].ncid, NC_GLOBAL, name, val); break; case NC_SHORT: status = nc_get_att_short(files[fid].ncid, NC_GLOBAL, name, val); break; case NC_CHAR: status = nc_get_att_text(files[fid].ncid, NC_GLOBAL, name, val); break; default: sprintf(errmsg, "mpp_io(mpp_get_global_att): global attribute %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].name ); mpp_error(errmsg); } if(status != NC_NOERR) { sprintf(errmsg, "mpp_io(mpp_get_global_att): Error in getting value of global attribute %s from file %s", name, files[fid].name ); netcdf_error(errmsg, status); } }
float * avtNETCDFReaderBase::ReadTimeAttribute() { float *times_array = 0; // // See if the global attribute time exists. If it does and is // either a float or double, then return the first value of it // as the time array. // int status; nc_type atttype; size_t attsize; if((status = nc_inq_att(fileObject->GetFileHandle(), NC_GLOBAL, "Time", &atttype, &attsize)) == NC_NOERR) { if (atttype == NC_FLOAT) { times_array = new float[1]; float *value = new float[attsize]; nc_get_att_float(fileObject->GetFileHandle(), NC_GLOBAL, "Time", value); times_array[0] = value[0]; delete [] value; } else if (atttype == NC_DOUBLE) { times_array = new float[1]; double *value = new double[attsize]; nc_get_att_double(fileObject->GetFileHandle(), NC_GLOBAL, "Time", value); times_array[0] = value[0]; delete [] value; } } return times_array; }
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); }
/* * Get the value of a netCDF attribute given its variable ID and name. */ static void c_ncagt( int ncid, /* netCDF ID */ int varid, /* variable ID */ const char* attname, /* attribute name */ void* value, /* pointer to data values */ int* rcode /* returned error code */ ) { int status; nc_type datatype; if ((status = nc_inq_atttype(ncid, varid, attname, &datatype)) == 0) { switch (datatype) { case NC_CHAR: status = NC_ECHAR; break; case NC_BYTE: # if NF_INT1_IS_C_SIGNED_CHAR status = nc_get_att_schar(ncid, varid, attname, (signed char*)value); # elif NF_INT1_IS_C_SHORT status = nc_get_att_short(ncid, varid, attname, (short*)value); # elif NF_INT1_IS_C_INT status = nc_get_att_int(ncid, varid, attname, (int*)value); # elif NF_INT1_IS_C_LONG status = nc_get_att_long(ncid, varid, attname, (long*)value); # endif break; case NC_SHORT: # if NF_INT2_IS_C_SHORT status = nc_get_att_short(ncid, varid, attname, (short*)value); # elif NF_INT2_IS_C_INT status = nc_get_att_int(ncid, varid, attname, (int*)value); # elif NF_INT2_IS_C_LONG status = nc_get_att_long(ncid, varid, attname, (long*)value); # endif break; case NC_INT: # if NF_INT_IS_C_INT status = nc_get_att_int(ncid, varid, attname, (int*)value); # elif NF_INT_IS_C_LONG status = nc_get_att_long(ncid, varid, attname, (long*)value); # endif break; case NC_FLOAT: # if NF_REAL_IS_C_FLOAT status = nc_get_att_float(ncid, varid, attname, (float*)value); # elif NF_REAL_IS_C_DOUBLE status = nc_get_att_double(ncid, varid, attname, (double*)value); # endif break; case NC_DOUBLE: # if NF_DOUBLEPRECISION_IS_C_FLOAT status = nc_get_att_float(ncid, varid, attname, (float*)value); # elif NF_DOUBLEPRECISION_IS_C_DOUBLE status = nc_get_att_double(ncid, varid, attname, (double*)value); # endif break; } } if (status == 0) *rcode = 0; else { nc_advise("NCAGT", status, ""); *rcode = ncerr; } }
void write_output(char out_file[], char in_file[][FILE_NAME_SZ], char depth_file[], size_t nz, char var_names[MAX_VARS][NC_MAX_NAME], char time_names[2][NC_MAX_NAME], char depth_names[2][NC_MAX_NAME], int *num_var, char arglist[]) { int i, j, v; int ncid, nc_den_id, status, ndims, ndim, nvariables, ngatt, recdim; int use_dim[NC_MAX_DIMS]; int dv_id[NC_MAX_DIMS], dim2id[NC_MAX_DIMS], dim2vid[NC_MAX_DIMS]; int dimids[NC_MAX_VAR_DIMS], dd2id[2]; int ddvid[2], dd2vid[2]; int num_att; int use_file[MAX_FILES], max_file; char dim_name[10][NC_MAX_NAME]; char att_name[NC_MAX_NAME]; nc_type xtype; size_t dim_len[NC_MAX_DIMS], ddim_len[2], max_dim_len = 0; status = nc_open(in_file[0],NC_NOWRITE, &ncid); if (status != NC_NOERR) handle_error(status,in_file[0],status); ncInid[0] = ncid; use_file[0] = 1; status = nc_inq(ncid,&ndims,&nvariables,&ngatt,&recdim); if (status != NC_NOERR) handle_error(status,in_file[0],status); strcpy(master_in_file,in_file[0]); for (i=1;i<MAX_FILES;i++) { ncInid[i] = -1; use_file[i] = 0;} for (i=0;i<MAX_FILES;i++) if (strlen(in_file[i]) == 0) break; max_file = i; /* Determine which dimensions need to be created. */ for (i=0;i<ndims;i++) use_dim[i] = 0.0; for (v=0;v<*num_var;v++) { int vin_id, fn = 0, id; for (fn=0;fn<max_file;fn++) { if (ncInid[fn] < 0) { status = nc_open(in_file[fn],NC_NOWRITE, &ncInid[fn]); if (status != NC_NOERR) handle_error(status,in_file[fn],status); } status = nc_inq_varid(ncInid[fn], var_names[v], &vin_id); if (status == NC_NOERR) break; } if (fn==max_file) { printf("ERROR: Unable to find variable %s in any of %d files.\n",var_names[v],max_file); handle_error(status, var_names[v], v); } id = ncInid[fn]; status = nc_inq_var(id, vin_id, att_name, &xtype, &ndim, dimids, &num_att); if (status != NC_NOERR) handle_error(status, var_names[v], v); if (ndim < 2) printf("Variable %s has only 2 dimensions and will be excluded.\n", var_names[v]); else { use_dim[find_dimid(id,dimids[ndim-1],ncid)] = 1; use_dim[find_dimid(id,dimids[ndim-2],ncid)] = 1; if (ndim > 4) { printf("ERROR: Variable %s has %d dimensions. This program only works with up to 4 dimensions.\n", var_names[v],ndim); exit(-1); } if (ndim == 4) { int frecdim; status = nc_inq_unlimdim(id,&frecdim); if (status != NC_NOERR) handle_error(status,"Finding record dimid",status); if (dimids[0] = frecdim) use_dim[recdim] = 1; else { printf("ERROR: Variable %s has 4 non-record dimensions. This program only works with 3 such dimensions.\n", var_names[v]); exit(-1); } } var_file[v] = fn; use_file[fn] = 1; } } // Close any unneeded files. for (i=1;i<max_file;i++) if ((use_file[i] == 0) && (ncInid[i] >= 0)) { nc_close(ncInid[i]); ncInid[i] = -1; } status = nc_create(out_file, 0, &ncOutid); if (status != NC_NOERR) handle_error(status,out_file,status); status = nc_set_fill(ncOutid,NC_NOFILL,&j); if (status != NC_NOERR) handle_error(status,out_file,status); // printf("Created file %s with id %d.\n",out_file,ncOutid); // Copy all of the global attributes over. for (j=0;j<ngatt;j++) { status = nc_inq_attname (ncid, NC_GLOBAL, j, att_name); if (status != NC_NOERR) handle_error(status,"Global",j); status = nc_copy_att(ncid, NC_GLOBAL, att_name, ncOutid, NC_GLOBAL); if (status != NC_NOERR) handle_error(status,att_name,j); } { char hist[1000]; status = nc_get_att_text(ncid, NC_GLOBAL,"history",hist); if (status == NC_NOERR) {strcat(hist,"\n"); strcat(hist,arglist);} else strcpy(hist,arglist); status = nc_put_att_text(ncOutid, NC_GLOBAL,"history",strlen(hist),hist); } // Copy all appropriate dimensions over. for (i=0;i<ndims;i++) if (use_dim[i]) { status = nc_inq_dim(ncid, i, dim_name[i], &dim_len[i]); if (status != NC_NOERR) handle_error(status, "", i); if (dim_len[i] > max_dim_len) max_dim_len = dim_len[i]; if (i==recdim) status = nc_def_dim(ncOutid, dim_name[i], NC_UNLIMITED, &dim2id[i]); else status = nc_def_dim(ncOutid, dim_name[i], dim_len[i], &dim2id[i]); if (status != NC_NOERR) handle_error(status,dim_name[i],i); // Get information about the coordinate variable. status = nc_inq_varid (ncid, dim_name[i], &dv_id[i]); if (status != NC_NOERR) handle_error(status, dim_name[i], i); status = nc_inq_vartype(ncid, dv_id[i], &xtype); if (status != NC_NOERR) handle_error(status, dim_name[i], i); status = nc_inq_varnatts(ncid, dv_id[i], &num_att); if (status != NC_NOERR) handle_error(status,dim_name[i],i); // Create the coordinate variables. status = nc_def_var (ncOutid, dim_name[i], xtype, 1, &dim2id[i], &dim2vid[i]); if (status != NC_NOERR) handle_error(status, dim_name[i],i); // Copy all of the attributes over. for (j=0;j<num_att;j++) { status = nc_inq_attname (ncid, dv_id[i], j, att_name); if (status != NC_NOERR) handle_error(status,att_name,j); status = nc_copy_att(ncid, dv_id[i], att_name, ncOutid, dim2vid[i]); if (status != NC_NOERR) handle_error(status,att_name,j); } } // Copy the vertical dimensions over from depth_file. // if (strlen(depth_file) > 1) status = nc_open(depth_file,NC_NOWRITE, &nc_den_id); if (status != NC_NOERR) handle_error(status,depth_file,status); for (i=0;i<2;i++) { int ddid; status = nc_inq_dimid (nc_den_id, depth_names[i], &ddid); if (status != NC_NOERR) handle_error(status,depth_names[i],0); status = nc_inq_dimlen(nc_den_id, ddid, &ddim_len[i]); if (status != NC_NOERR) handle_error(status,depth_names[i], i); status = nc_def_dim(ncOutid, depth_names[i], ddim_len[i], &dd2id[i]); if (status != NC_NOERR) handle_error(status,depth_names[i],i); // Get information about the coordinate variable. status = nc_inq_varid (nc_den_id, depth_names[i], &ddvid[i]); if (status != NC_NOERR) handle_error(status, depth_names[i], i); status = nc_inq_vartype(nc_den_id, ddvid[i], &xtype); if (status != NC_NOERR) handle_error(status, depth_names[i], i); status = nc_inq_varnatts(nc_den_id, ddvid[i], &num_att); if (status != NC_NOERR) handle_error(status,depth_names[i],i); // Create the coordinate variables. status = nc_def_var (ncOutid, depth_names[i], xtype, 1, &dd2id[i], &dd2vid[i]); if (status != NC_NOERR) handle_error(status, depth_names[i],i); // Copy all of the attributes over. for (j=0;j<num_att;j++) { status = nc_inq_attname (nc_den_id, ddvid[i], j, att_name); if (status != NC_NOERR) handle_error(status,att_name,j); status = nc_copy_att(nc_den_id, ddvid[i], att_name, ncOutid, dd2vid[i]); if (status != NC_NOERR) handle_error(status,att_name,j); } } // Create the auxiliary time variable (if it exists) and store the time indices. if (recdim != -1) { // If there is a record dimension, it must be one of the two named // time dimensions. If none are named, the name of the record // dimension is copied into it. if ((strcmp(dim_name[recdim],time_names[0]) != 0) && (strcmp(dim_name[recdim],time_names[1]) != 0)) { if (strlen(time_names[0]) == 0) strcpy(time_names[0],dim_name[recdim]); else if (strlen(time_names[1]) == 0) strcpy(time_names[1],dim_name[recdim]); else { printf("ERROR: The specified time variables %s and %s do not agree\n" "\twith the record variable, %s.\n",time_names[0],time_names[1], dim_name[recdim]); exit(-1); } } } for (v=0;v<2;v++) { status = nc_inq_varid(ncOutid, time_names[v], &time_out_id[v]); if (status != NC_NOERR) { if (strlen(time_names[v]) > 0) { int out_dim; status = nc_inq_varid(ncid, time_names[v], &time_in_id[v]); if (status != NC_NOERR) handle_error(status, time_names[v], v); status = nc_inq_var(ncid, time_in_id[v], att_name, &xtype, &ndim, dimids, &num_att); if (status != NC_NOERR) handle_error(status, time_names[v], v); if (ndim > 1) { printf("ERROR: Time variable %s has %d dimensions in %s.\n",time_names[v],ndim,in_file[0]); exit(-1); } out_dim = dim2id[dimids[0]]; status = nc_def_var(ncOutid, time_names[v], xtype, ndim, &out_dim, &time_out_id[v]); if (status != NC_NOERR) handle_error(status, time_names[v],v); // Copy all of the attributes over. for (j=0;j<num_att;j++) { status = nc_inq_attname(ncid, time_in_id[v], j, att_name); if (status != NC_NOERR) handle_error(status,att_name,j); status = nc_copy_att(ncid, time_in_id[v], att_name, ncOutid, time_out_id[v]); if (status != NC_NOERR) handle_error(status,att_name,j); } } } else { status = nc_inq_varid(ncid, time_names[v], &time_in_id[v]); if (status != NC_NOERR) handle_error(status, time_names[v], v); } } // Create the output variables, while checking the validity of the list. for (v=0;v<*num_var;v++) { int id, vin_id, frecdim, valid = 1; for (i=0;i<2;i++) if (strcmp(var_names[v],time_names[i])==0) valid = 0; for (i=0;i<ndims;i++) if (strcmp(var_names[v],dim_name[i])==0) valid = 0; for (i=0;i<2;i++) if (strcmp(var_names[v],depth_names[i])==0) valid = 0; if (valid) { id = ncInid[var_file[v]]; if (var_file[v] == 0) frecdim = recdim; else { status = nc_inq_unlimdim(id,&frecdim); if (status != NC_NOERR) handle_error(status,"Finding record dimid",status); } status = nc_inq_varid(id, var_names[v], &vin_id); if (status != NC_NOERR) handle_error(status, var_names[v], v); status = nc_inq_var(id, vin_id, att_name, &xtype, &ndim, dimids, &num_att); if (status != NC_NOERR) handle_error(status, var_names[v], v); if (ndim <= 2) { printf("Variable %s has only 2 dimensions and will be excluded.\n", var_names[v]); valid = 0; } else if ((ndim == 3) && (dimids[0] == frecdim)) { printf("Variable %s uses the record dimension as 3rd dimension and will be excluded.\n", var_names[v]); valid = 0; } } if (valid) { // Get information about the variable. int out_dimids[4]; if (dimids[0] != frecdim) { out_dimids[0] = dd2id[0]; var_count[v][0] = ddim_len[0]; static_var[v] = 1; i = 1; } else { out_dimids[0] = dim2id[recdim]; out_dimids[1] = dd2id[0]; var_count[v][0] = 1; var_count[v][1] = ddim_len[0]; static_var[v] = 0; i = 2; } var_size[v] = ddim_len[0]; for (;i<ndim;i++) { int did; did = find_dimid(id,dimids[i],ncid); out_dimids[i] = dim2id[did]; var_count[v][i] = dim_len[did]; var_size[v] *= var_count[v][i]; } status = nc_def_var(ncOutid, var_names[v], xtype, ndim, out_dimids, &var_id[v]); if (status != NC_NOERR) handle_error(status, var_names[v],v); // Copy all of the attributes over. for (j=0;j<num_att;j++) { status = nc_inq_attname(id, vin_id, j, att_name); if (status != NC_NOERR) handle_error(status,att_name,j); status = nc_copy_att(id, vin_id, att_name, ncOutid, var_id[v]); if (status != NC_NOERR) handle_error(status,att_name,j); } status = nc_get_att_double(id, vin_id,"missing_value",&missing_val[v]); if (status != NC_NOERR) { missing_val[v] = -1.0e34; status = nc_put_att_double(ncOutid,var_id[v],"missing_value",xtype,1,&missing_val[v]); if (status != NC_NOERR) handle_error(status,"missing_value",v); } } else { for (i=v;i<*num_var-1;i++) strcpy(var_names[i],var_names[i+1]); (*num_var)--; v--; } } status = nc_enddef(ncOutid); if (status != NC_NOERR) handle_error(status,out_file,status); // printf("Finished define mode for %s.\n",out_file); /* // Create the vertical coordinates. // status = nc_def_dim(ncOutid, zc_name, nz, &layerid); if (status != NC_NOERR) handle_error(status,zc_name,0); status = nc_def_var (ncOutid, zc_name, NC_DOUBLE, 1, &layerid, &layervid); if (status != NC_NOERR) handle_error(status,zc_name,0); status = nc_def_dim(ncOutid, ze_name, (size_t) (nz+1), &intid); if (status != NC_NOERR) handle_error(status,ze_name,0); status = nc_def_var (ncOutid, ze_name, NC_DOUBLE, 1, &intid, &intvid); if (status != NC_NOERR) handle_error(status,ze_name,0); status = nc_put_att_text(ncOutid, intvid, "units", 2, "m"); if (status != NC_NOERR) handle_error(status,"Units Interface",0); dims[0] = layervid; { strcpy(att[0][0],"long_name"); strcpy(att[0][1],"Depth of Layer Center"); // strcpy(att[1][0],"units"); strcpy(att[1][1],"m"); strcpy(att[1][0],"units"); strcpy(att[1][1],"cm"); strcpy(att[2][0],"positive"); strcpy(att[2][1],"down"); strcpy(att[3][0],"edges"); strcpy(att[2][1],ze_name); for (j=0;j<=2;j++) { status = nc_put_att_text(ncOutid, layervid, att[j][0], strlen(att[j][1]), att[j][1]); if (status != NC_NOERR) handle_error(status,att[j][0],j); } strcpy(att[0][0],"long_name"); strcpy(att[0][1],"Depth of edges"); // strcpy(att[1][0],"units"); strcpy(att[1][1],"m"); strcpy(att[1][0],"units"); strcpy(att[1][1],"cm"); strcpy(att[2][0],"positive"); strcpy(att[2][1],"down"); for (j=0;j<=2;j++) { status = nc_put_att_text(ncOutid, intvid, att[j][0], strlen(att[j][1]), att[j][1]); if (status != NC_NOERR) handle_error(status,att[j][0],j); } } */ // Copy the axis values from the first file. { double *coord_array; coord_array = malloc(sizeof(double)*(max_dim_len)); for (i=0;i<ndims;i++) if (use_dim[i] && (i!=recdim)) { status = nc_get_var_double(ncid,dv_id[i],coord_array); if (status != NC_NOERR) handle_error(status,"Read Coordinate Variable",i); status = nc_put_var_double(ncOutid,dim2vid[i],coord_array); if (status != NC_NOERR) handle_error(status,"Write Coordinate Variable",i); } // Copy the vertical axis values from the depth file. for (i=0;i<2;i++) { status = nc_get_var_double(nc_den_id,ddvid[i],coord_array); if (status != NC_NOERR) handle_error(status,"Read Coordinate Variable",i); status = nc_put_var_double(ncOutid,dd2vid[i],coord_array); if (status != NC_NOERR) handle_error(status,"Write Coordinate Variable",i); } free(coord_array); } /* { double *z; z = (double *) calloc((size_t) (nz+1), sizeof(double)); for (i=0;i<=nz;i++) z[i] = (-100.0)*int_depth[i]; status = nc_put_var_double(ncOutid,intid,z); if (status != NC_NOERR) handle_error(status,"Interface Coordinate",0); for (i=0;i<nz;i++) z[i] = (-100.0)*lay_depth[i]; status = nc_put_var_double(ncOutid,layerid,z); if (status != NC_NOERR) handle_error(status,"Layer Coordinate",0); } */ nc_close(nc_den_id); }
int main(int argc, char **argv) { int ncid, dimid, fvarid, dvarid; int dimids[NDIMS]; float fvals[NVALS], fvals_in[NVALS]; double dvals[NVALS], dvals_in[NVALS]; float fnan = 0.f/0.f; double dnan = 0.0/0.0; float fpinf = 1.0f/0.0f; float fninf = -fpinf; double dpinf = 1.0/0.0; double dninf = -dpinf; nc_type att_type; size_t att_len; float att_fvals[NVALS]; double att_dvals[NVALS]; #ifdef USE_PARALLEL MPI_Init(&argc, &argv); #endif printf("*** creating NaN test file %s...", FILE8_NAME); if (nc_create(FILE8_NAME, NC_CLOBBER, &ncid)) ERR; if (nc_def_dim(ncid, DIM_NAME, NVALS, &dimid)) ERR; dimids[0] = dimid; if (nc_def_var(ncid, F_NAME, NC_FLOAT, NDIMS, NULL, &fvarid)) ERR; if (nc_def_var(ncid, D_NAME, NC_DOUBLE, NDIMS, NULL, &dvarid)) ERR; fvals[0] = fninf; fvals[1] = fnan; fvals[2] = fpinf; dvals[0] = dninf; dvals[1] = dnan; dvals[2] = dpinf; /* Create float and double attributes */ if (nc_put_att_float(ncid, fvarid, FV_NAME, NC_FLOAT, FV_NVALS, &fnan)) ERR; if (nc_put_att_float(ncid, fvarid, ATT_NAME, NC_FLOAT, NVALS, fvals)) ERR; if (nc_put_att_double(ncid, dvarid, FV_NAME, NC_DOUBLE, FV_NVALS, &dnan)) ERR; if (nc_put_att_double(ncid, dvarid, ATT_NAME, NC_DOUBLE, NVALS, dvals)) ERR; if (nc_enddef(ncid)) ERR; /* Write float and double data */ if (nc_put_var_float(ncid, fvarid, fvals)) ERR; if (nc_put_var_double(ncid, dvarid, dvals)) ERR; if (nc_close(ncid)) ERR; /* Check it out. */ /* Reopen the file. */ if (nc_open(FILE8_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq_varid(ncid, F_NAME, &fvarid)) ERR; if (nc_inq_varid(ncid, D_NAME, &dvarid)) ERR; /* Check the values of the float attributes */ if (nc_inq_att(ncid, fvarid, FV_NAME, &att_type, &att_len)) ERR; if (att_type != NC_FLOAT || att_len != FV_NVALS) ERR; if (nc_get_att_float(ncid, fvarid, FV_NAME, att_fvals)) ERR; if (!isnan(att_fvals[0])) ERR; if (nc_get_att_float(ncid, fvarid, ATT_NAME, att_fvals)) ERR; if (!(isinf(att_fvals[0]) && att_fvals[0] < 0)) ERR; if (!isnan(att_fvals[1])) ERR; if (!(isinf(att_fvals[2]) && att_fvals[2] > 0)) ERR; /* Check the values of double attributes */ if (nc_inq_att(ncid, dvarid, FV_NAME, &att_type, &att_len)) ERR; if (att_type != NC_DOUBLE || att_len != FV_NVALS) ERR; if (nc_get_att_double(ncid, dvarid, FV_NAME, att_dvals)) ERR; if (!isnan(att_dvals[0])) ERR; if (nc_get_att_double(ncid, dvarid, ATT_NAME, att_dvals)) ERR; if (!(isinf(att_dvals[0]) && att_dvals[0] < 0)) ERR; if (!isnan(att_dvals[1])) ERR; if (!(isinf(att_dvals[2]) && att_dvals[2] > 0)) ERR; /* Check values of float data */ if (nc_get_var_float(ncid, fvarid, fvals_in)) ERR; if (!(isinf(fvals_in[0]) && fvals_in[0] < 0)) ERR; if (!isnan(fvals_in[1])) ERR; if (!(isinf(fvals_in[2]) && fvals_in[2] > 0)) ERR; /* Check values of double data */ if (nc_get_var_double(ncid, dvarid, dvals_in)) ERR; if (!(isinf(dvals_in[0]) && dvals_in[0] < 0)) ERR; if (!isnan(dvals_in[1])) ERR; if (!(isinf(dvals_in[2]) && dvals_in[2] > 0)) ERR; if (nc_close(ncid)) ERR; SUMMARIZE_ERR; FINAL_RESULTS; #ifdef USE_PARALLEL MPI_Finalize(); #endif printf("*** SUCCESS writing example file tst_nans.nc!\n"); return 0; }
int main(int argc, char **argv) { int ncid, dimid, fvarid, dvarid; float fvals[NVALS], fvals_in[NVALS]; double dvals[NVALS], dvals_in[NVALS]; float fnan = NC_FNAN;//(NC_INFINITE-NC_INFINITE);//0.f/0.f; double dnan = NC_DNAN;//(NC_INFINITE-NC_INFINITE);//0.0/0.0; float fpinf = NC_FPINF;//NC_INFINITE;//1.0f/0.0f; float fninf = -fpinf; double dpinf = NC_DPINF;//NC_INFINITE;//1.0/0.0; double dninf = -dpinf; nc_type att_type; size_t att_len; float att_fvals[NVALS]; double att_dvals[NVALS]; printf("\n*** Testing NaN\n"); printf("*** creating NaN test file %s...", FILE8_NAME); if (nc_create(FILE8_NAME, NC_CLOBBER, &ncid)) ERR; if (nc_def_dim(ncid, DIM_NAME, NVALS, &dimid)) ERR; if (nc_def_var(ncid, F_NAME, NC_FLOAT, NDIMS, &dimid, &fvarid)) ERR; if (nc_def_var(ncid, D_NAME, NC_DOUBLE, NDIMS, &dimid, &dvarid)) ERR; fvals[0] = fninf; fvals[1] = fnan; fvals[2] = fpinf; dvals[0] = dninf; dvals[1] = dnan; dvals[2] = dpinf; /* Create float and double attributes */ if (nc_put_att_float(ncid, fvarid, FV_NAME, NC_FLOAT, FV_NVALS, &fnan)) ERR; if (nc_put_att_float(ncid, fvarid, ATT_NAME, NC_FLOAT, NVALS, fvals)) ERR; if (nc_put_att_double(ncid, dvarid, FV_NAME, NC_DOUBLE, FV_NVALS, &dnan)) ERR; if (nc_put_att_double(ncid, dvarid, ATT_NAME, NC_DOUBLE, NVALS, dvals)) ERR; if (nc_enddef(ncid)) ERR; /* Write float and double data */ if (nc_put_var_float(ncid, fvarid, fvals)) ERR; if (nc_put_var_double(ncid, dvarid, dvals)) ERR; if (nc_close(ncid)) ERR; /* Check it out. */ /* Reopen the file. */ if (nc_open(FILE8_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq_varid(ncid, F_NAME, &fvarid)) ERR; if (nc_inq_varid(ncid, D_NAME, &dvarid)) ERR; /* Check the values of the float attributes */ if (nc_inq_att(ncid, fvarid, FV_NAME, &att_type, &att_len)) ERR; if (att_type != NC_FLOAT || att_len != FV_NVALS) ERR; if (nc_get_att_float(ncid, fvarid, FV_NAME, att_fvals)) ERR; if (!isnan(att_fvals[0])) ERR; if (nc_get_att_float(ncid, fvarid, ATT_NAME, att_fvals)) ERR; if (!(isinf(att_fvals[0]) && att_fvals[0] < 0)) ERR; if (!isnan(att_fvals[1])) ERR; if (!(isinf(att_fvals[2]) && att_fvals[2] > 0)) ERR; /* Check the values of double attributes */ if (nc_inq_att(ncid, dvarid, FV_NAME, &att_type, &att_len)) ERR; if (att_type != NC_DOUBLE || att_len != FV_NVALS) ERR; if (nc_get_att_double(ncid, dvarid, FV_NAME, att_dvals)) ERR; if (!isnan(att_dvals[0])) ERR; if (nc_get_att_double(ncid, dvarid, ATT_NAME, att_dvals)) ERR; if (!(isinf(att_dvals[0]) && att_dvals[0] < 0)) ERR; if (!isnan(att_dvals[1])) ERR; if (!(isinf(att_dvals[2]) && att_dvals[2] > 0)) ERR; /* Check values of float data */ if (nc_get_var_float(ncid, fvarid, fvals_in)) ERR; if (!(isinf(fvals_in[0]) && fvals_in[0] < 0)) ERR; if (!isnan(fvals_in[1])) ERR; if (!(isinf(fvals_in[2]) && fvals_in[2] > 0)) ERR; /* Check values of double data */ if (nc_get_var_double(ncid, dvarid, dvals_in)) ERR; if (!(isinf(dvals_in[0]) && dvals_in[0] < 0)) ERR; if (!isnan(dvals_in[1])) ERR; if (!(isinf(dvals_in[2]) && dvals_in[2] > 0)) ERR; if (nc_close(ncid)) ERR; SUMMARIZE_ERR; FINAL_RESULTS; }
int main(int argc, char **argv) { char *valid[] = { /* pressure in 23 languages */ "\xd8\xa7\xd9\x84\xd8\xb6\xd8\xba\xd8\xb7", "\xd0\xbd\xd0\xb0\xd0\xbb\xd1\x8f\xd0\xb3\xd0\xb0\xd0\xbd\xd0\xb5", "\xe5\x8e\x8b\xe5\x8a\x9b", "\xe5\xa3\x93\xe5\x8a\x9b", "pritisak", "tlaku", "pres", "druk", "pressure", "paine", "pression", "Druck", "\xcf\x80\xce\xaf\xce\xb5\xcf\x83\xce\xb7", "\xe0\xa4\xa6\xe0\xa4\xac\xe0\xa4\xbe\xe0\xa4\xb5", "pressione", "\xe5\x9c\xa7\xe5\x8a\x9b", "\xec\x95\x95\xeb\xa0\xa5", "press", "ci\xc5\x9bnienie", "Press\xc3\xa3o", "presiune", "\xd0\xb4\xd0\xb0\xd0\xb2\xd0\xbb\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb5", "presi\xc3\xb3n", /* special characters in names, numeric characters at the start of names */ "has blank", "has:colon", "a", "A", "0leading_numeric_char", "1", "0x123" }; char *notvalid[] = { "-leading_special_char", "trailing_space ", "trailing_tab\t", "trailing_newline\n", "has_control_char_\a_in_name", "has ascii_del_\x7f_in name", /* Invalid UTF-8 of various sorts, thanks to Markus Kuhn */ "\xA0\xB0\xC0\xD0", "xyz\x80", /* unexpected continuation bytes */ "\x80xyz", "xyz\xBF", "\xBFxyz", "\xC0xyz", /* lonely start characters */ "x\xC0yz", "xy\xC0z", "xyz\xC0", "\xDFxyz", "x\xDFyz", "xy\xDFz", "xyz\xDF", "\xE0xyz", "x\xE0yz", "xy\xE0z", "xyz\xE0", "\xE0\xBFxy", "x\xE0\xBFy", "xy\xE0\xBF", "\xEFxyz", "x\xEFyz", "xy\xEFz", "xyz\xEF", "\xEF\x80xy", "x\xEF\x80y", "xy\xEF\x80", "\xF0xyz", "x\xF0yz", "xy\xF0z", "xyz\xF0", "\xF7xyz", "x\xF7yz", "xy\xF7z", "xyz\xF7", "\xF8xyz", "x\xF8yz", "xy\xF8z", "xyz\xF8", "\xFBxyz", "x\xFByz", "xy\xFBz", "xyz\xFB", "\xFCxyz", "x\xFCyz", "xy\xFCz", "xyz\xFC", "\xFDxyz", "x\xFDyz", "xy\xFDz", "xyz\xFD", "\xC0\xC0xy", /* last continuation byte missing */ "x\xC0\xC0y", "xy\xC0\xC0", "\xDF\xDFxy", "x\xDF\xDFy", "xy\xDF\xDF", "\xE0\x80xy", "x\xE0\x80y", "xy\xE0\x80", "\xEF\x80xy", "x\xEF\x80y", "xy\xEF\x80", "\xF0\x80\x80x", "x\xF0\x80\x80", "\xF7\x80\x80x", "x\xF7\x80\x80", "\xF8\x80\x80\x80x", "x\xF8\x80\x80\x80", "\xFB\x80\x80\x80x", "x\xFB\x80\x80\x80", "\xFC\x80\x80\x80\x80x", "x\xFC\x80\x80\x80\x80", "\xFD\x80\x80\x80\x80x", "x\xFD\x80\x80\x80\x80", "\xFExyz", /* impossible bytes */ "x\xFEyz", "xy\xFEz", "xyz\xFE", "\xFFxyz", "x\xFFyz", "xy\xFFz", "xyz\xFF", "\xC0\xAFxy", /* overlong sequences */ "x\xC0\xAFy", "xy\xC0\xAF", "\xE0\x80\xAFx", "x\xE0\x80\xAF", "\xF0\x80\x80\xAFx", "x\xF0\x80\x80\xAF", "\xF8\x80\x80\x80\xAFx", "x\xF8\x80\x80\x80\xAF", "\xFC\x80\x80\x80\x80\xAFx", "x\xFC\x80\x80\x80\x80\xAF", "\xC1\xBFxy", "x\xC1\xBFy", "xy\xC1\xBF", "\xE0\x9F\xBFx", "x\xE0\x9F\xBF", "\xF0\x8F\xBF\xBFx", "x\xF0\x8F\xBF\xBF", "\xF8\x87\xBF\xBF\xBFx", "x\xF8\x87\xBF\xBF\xBF", "\xFC\x83\xBF\xBF\xBF\xBFx", "x\xFC\x83\xBF\xBF\xBF\xBF", "x\xC0\x80", /* overlong NULs */ "x\xE0\x80\x80", "x\xF0\x80\x80\x80", "x\xF8\x80\x80\x80\x80", "x\xFC\x80\x80\x80\x80\x80", /* single UTF-16 surrogates */ "x\xED\xA0\x80", "x\xED\xAD\xBF", "x\xED\xAE\x80", "x\xED\xAF\xBF", "x\xED\xB0\x80", "x\xED\xBE\x80", "x\xED\xBF\xBF", "x\xED\xA0\x80\xED\xB0\x80", /* paired UTF-16 surrogates */ "x\xED\xA0\x80\xED\xBF\xBF", "x\xED\xAD\xBF\xED\xB0\x80", "x\xED\xAD\xBF\xED\xBF\xBF", "x\xED\xAE\x80\xED\xB0\x80", "x\xED\xAE\x80\xED\xBF\xBF", "x\xED\xAF\xBF\xED\xB0\x80", "x\xED\xAF\xBF\xED\xBF\xBF", "x\xEF\xBF\xBE", /* other illegal code positions */ "x\xEF\xBF\xBF" }; int i, j; #define NUM_BAD (sizeof notvalid / sizeof notvalid[0]) #define NUM_GOOD (sizeof valid / sizeof valid[0]) int ncid, dimid, varid, res; double attvals[] = {-2.0}; double attvals_in[1]; #define NATTVALS (sizeof attvals / sizeof attvals[0]) char *attstring = "text"; #define MAX_ATTSTRING_LEN 100 char attstr_in[MAX_ATTSTRING_LEN]; int dimids[NUM_GOOD]; int varids[NUM_GOOD]; #if 0 int attnums[NUM_GOOD]; #endif char *testfile = FILE_NAME; int formats[] = { NC_FORMAT_CLASSIC , NC_FORMAT_64BIT #ifdef USE_NETCDF4 , NC_FORMAT_NETCDF4 , NC_FORMAT_NETCDF4_CLASSIC #endif /* USE_NETCDF4 */ }; int num_formats = (sizeof formats) / (sizeof formats[0]); char *format_names[] = { "classic", "64-bit offset", "netCDF-4/HDF5", "netCDF-4 classic model" }; printf("\n*** testing names with file %s...\n", testfile); for (j = 0; j < num_formats; j++) { printf("*** switching to netCDF %s format...", format_names[j]); nc_set_default_format(formats[j], NULL); if((res = nc_create(testfile, NC_CLOBBER, &ncid))) ERR; /* Define dimensions, variables, and attributes with various * acceptable names */ for (i = 0; i < NUM_GOOD; i++) { if ((res = nc_def_dim(ncid, valid[i], DIMLEN, &dimid))) ERR; dimids[i] = dimid; /* Define variable with same name */ if ((res = nc_def_var(ncid, valid[i], NC_FLOAT, NDIMS, &dimids[i], &varid))) ERR; varids[i] = varid; /* Define variable and global attributes with same name and value */ if ((res = nc_put_att_text(ncid, varid, valid[i], strlen(valid[i]), valid[i]))) ERR; if ((res = nc_put_att_double(ncid, NC_GLOBAL, valid[i], NC_DOUBLE, NATTVALS, attvals))) ERR; #if 0 attnums[i] = i; #endif } /* Try defining dimensions, variables, and attributes with various * bad names and make sure these are rejected */ for (i = 0; i < NUM_BAD; i++) { if ((res = nc_def_dim(ncid, notvalid[i], DIMLEN, &dimid)) != NC_EBADNAME) ERR; if ((res = nc_def_var(ncid, notvalid[i], NC_FLOAT, NDIMS, dimids, &varid)) != NC_EBADNAME) ERR; if ((res = nc_put_att_text(ncid, varid, notvalid[i], strlen(attstring), attstring)) != NC_EBADNAME) ERR; if ((res = nc_put_att_double(ncid, NC_GLOBAL, notvalid[i], NC_DOUBLE, NATTVALS, attvals)) != NC_EBADNAME) ERR; } if ((res = nc_enddef(ncid))) ERR; if ((res = nc_close(ncid))) ERR; /* Check it out, make sure all objects with good names were defined OK */ if ((res = nc_open(testfile, NC_NOWRITE, &ncid))) ERR; for (i = 0; i < NUM_GOOD; i++) { size_t attlen; if ((res = nc_inq_dimid(ncid, valid[i], &dimid)) || dimid != dimids[i]) ERR; if ((res = nc_inq_varid(ncid, valid[i], &varid)) || varid != varids[i]) ERR; res = nc_inq_attlen(ncid, varid, valid[i], &attlen); if ((res = nc_get_att_text(ncid, varid, valid[i], attstr_in))) ERR; attstr_in[attlen] = '\0'; if (strcmp(valid[i], attstr_in) != 0) ERR; if ((res = nc_get_att_double(ncid, NC_GLOBAL, valid[i], attvals_in)) || attvals[0] != attvals_in[0]) ERR; } if ((res = nc_close(ncid))) ERR; /* (void) remove(testfile); */ SUMMARIZE_ERR; } FINAL_RESULTS; return 0; }
GDALDataset *GMTDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Does this file have the GMT magic number? */ /* -------------------------------------------------------------------- */ if( poOpenInfo->fpL == NULL || poOpenInfo->nHeaderBytes < 50 ) return NULL; if( poOpenInfo->pabyHeader[0] != 'C' || poOpenInfo->pabyHeader[1] != 'D' || poOpenInfo->pabyHeader[2] != 'F' || poOpenInfo->pabyHeader[3] != 1 ) return NULL; CPLMutexHolderD(&hNCMutex); /* -------------------------------------------------------------------- */ /* Try opening the dataset. */ /* -------------------------------------------------------------------- */ int cdfid, nm_id, dim_count, z_id; if( nc_open( poOpenInfo->pszFilename, NC_NOWRITE, &cdfid ) != NC_NOERR ) return NULL; if( nc_inq_varid( cdfid, "dimension", &nm_id ) != NC_NOERR || nc_inq_varid( cdfid, "z", &z_id ) != NC_NOERR ) { #ifdef notdef CPLError( CE_Warning, CPLE_AppDefined, "%s is a GMT file, but not in GMT configuration.", poOpenInfo->pszFilename ); #endif nc_close( cdfid ); return NULL; } if( nc_inq_ndims( cdfid, &dim_count ) != NC_NOERR || dim_count < 2 ) { nc_close( cdfid ); return NULL; } /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { nc_close( cdfid ); CPLError( CE_Failure, CPLE_NotSupported, "The GMT driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ GMTDataset *poDS; CPLReleaseMutex(hNCMutex); // Release mutex otherwise we'll deadlock with GDALDataset own mutex poDS = new GMTDataset(); CPLAcquireMutex(hNCMutex, 1000.0); poDS->cdfid = cdfid; poDS->z_id = z_id; /* -------------------------------------------------------------------- */ /* Get dimensions. If we can't find this, then this is a */ /* GMT file, but not a normal grid product. */ /* -------------------------------------------------------------------- */ size_t start[2], edge[2]; int nm[2]; start[0] = 0; edge[0] = 2; nc_get_vara_int(cdfid, nm_id, start, edge, nm); poDS->nRasterXSize = nm[0]; poDS->nRasterYSize = nm[1]; /* -------------------------------------------------------------------- */ /* Fetch "z" attributes scale_factor, add_offset, and */ /* node_offset. */ /* -------------------------------------------------------------------- */ double scale_factor=1.0, add_offset=0.0; int node_offset = 1; nc_get_att_double( cdfid, z_id, "scale_factor", &scale_factor ); nc_get_att_double( cdfid, z_id, "add_offset", &add_offset ); nc_get_att_int( cdfid, z_id, "node_offset", &node_offset ); /* -------------------------------------------------------------------- */ /* Get x/y range information. */ /* -------------------------------------------------------------------- */ int x_range_id, y_range_id; if( nc_inq_varid (cdfid, "x_range", &x_range_id) == NC_NOERR && nc_inq_varid (cdfid, "y_range", &y_range_id) == NC_NOERR ) { double x_range[2], y_range[2]; nc_get_vara_double( cdfid, x_range_id, start, edge, x_range ); nc_get_vara_double( cdfid, y_range_id, start, edge, y_range ); // Pixel is area if( node_offset == 1 ) { poDS->adfGeoTransform[0] = x_range[0]; poDS->adfGeoTransform[1] = (x_range[1] - x_range[0]) / poDS->nRasterXSize; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = y_range[1]; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = (y_range[0] - y_range[1]) / poDS->nRasterYSize; } // Pixel is point - offset by half pixel. else /* node_offset == 0 */ { poDS->adfGeoTransform[1] = (x_range[1] - x_range[0]) / (poDS->nRasterXSize-1); poDS->adfGeoTransform[0] = x_range[0] - poDS->adfGeoTransform[1]*0.5; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = (y_range[0] - y_range[1]) / (poDS->nRasterYSize-1); poDS->adfGeoTransform[3] = y_range[1] - poDS->adfGeoTransform[5]*0.5; } } else { poDS->adfGeoTransform[0] = 0.0; poDS->adfGeoTransform[1] = 1.0; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = 0.0; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = 1.0; } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ poDS->nBands = 1; poDS->SetBand( 1, new GMTRasterBand( poDS, z_id, 1 )); if( scale_factor != 1.0 || add_offset != 0.0 ) { poDS->GetRasterBand(1)->SetOffset( add_offset ); poDS->GetRasterBand(1)->SetScale( scale_factor ); } /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); CPLReleaseMutex(hNCMutex); // Release mutex otherwise we'll deadlock with GDALDataset own mutex poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for external overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->GetSiblingFiles() ); CPLAcquireMutex(hNCMutex, 1000.0); return( poDS ); }
int main(int argc, char **argv) { (void) signal(SIGFPE, SIG_IGN); printf("\n*** Testing netcdf-4 attribute functions.\n"); printf("*** testing really simple global atts..."); #define NUM_SIMPLE_ATTS 9 { int ncid; char name[NUM_SIMPLE_ATTS][ATT_MAX_NAME + 1] = {"Gc", "Gb", "Gs", "Gi", "Gf", "Gd", "G7", "G8", "G9"}; char name_in[NC_MAX_NAME]; int j; /* Create a file with some global atts. */ if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLOBBER, &ncid)) ERR; for (j = 0; j < NUM_SIMPLE_ATTS; j++) if (nc_put_att_int(ncid, NC_GLOBAL, name[j], NC_INT, 0, NULL)) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and check the order. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; for (j = 0; j < NUM_SIMPLE_ATTS; j++) { if (nc_inq_attname(ncid, NC_GLOBAL, j, name_in)) ERR; if (strcmp(name_in, name[j])) ERR; } /* Close up shop. */ if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing simple global atts..."); { int ncid; nc_type att_type; size_t att_len; int i; char *speech_in; signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE}; unsigned char uchar_in[ATT_LEN], uchar_out[ATT_LEN] = {0, 128, NC_MAX_CHAR}; short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT}; /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/ int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000}; float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125}; double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125}; unsigned short ushort_in[ATT_LEN], ushort_out[ATT_LEN] = {0, 128, NC_MAX_USHORT}; unsigned int uint_in[ATT_LEN], uint_out[ATT_LEN] = {0, 128, NC_MAX_UINT}; unsigned long long uint64_in[ATT_LEN], uint64_out[ATT_LEN] = {0, 128, 18446744073709551612ULL}; long long int64_in[ATT_LEN], int64_out[ATT_LEN] = {NC_MIN_INT64, 128, NC_MAX_INT64}; /* This won't work, because classic files can't create these types. */ if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; if (nc_put_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, NC_USHORT, ATT_LEN, ushort_out) != NC_ESTRICTNC3) ERR; if (nc_put_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, NC_UINT, ATT_LEN, uint_out) != NC_ESTRICTNC3) ERR; if (nc_put_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, NC_INT64, ATT_LEN, int64_out) != NC_ESTRICTNC3) ERR; if (nc_put_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, NC_UINT64, ATT_LEN, uint64_out) != NC_ESTRICTNC3) ERR; if (nc_close(ncid)) ERR; /* Create a file with a global attribute of each type. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR; if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR; if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UBYTE, ATT_LEN, uchar_out)) ERR; if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, ATT_LEN, short_out)) ERR; if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, ATT_LEN, int_out)) ERR; if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, ATT_LEN, float_out)) ERR; if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, ATT_LEN, double_out)) ERR; if (nc_put_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, NC_USHORT, ATT_LEN, ushort_out)) ERR; if (nc_put_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, NC_UINT, ATT_LEN, uint_out)) ERR; if (nc_put_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, NC_INT64, ATT_LEN, int64_out)) ERR; if (nc_put_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, NC_UINT64, ATT_LEN, uint64_out)) ERR; if (nc_close(ncid)) ERR; /* Open the file and check attributes. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; /* Check text. */ if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, &att_type, &att_len)) ERR; if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR; if (!(speech_in = malloc(att_len + 1))) ERR; if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, speech_in)) ERR; if (strcmp(speech, speech_in)) ERR; free(speech_in); /* Check numeric values. */ if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != schar_out[i]) ERR; if (nc_get_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, uchar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (uchar_in[i] != uchar_out[i]) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != short_out[i]) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != int_out[i]) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != float_out[i]) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != double_out[i]) ERR; if (nc_get_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, ushort_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (ushort_in[i] != ushort_out[i]) ERR; if (nc_get_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, uint_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (uint_in[i] != uint_out[i]) ERR; if (nc_get_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, int64_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int64_in[i] != int64_out[i]) ERR; if (nc_get_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, uint64_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (uint64_in[i] != uint64_out[i]) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing attribute data type conversions..."); { int ncid; int i; signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE}; short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT}; /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/ int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000}; float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125}; double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125}; unsigned short ushort_in[ATT_LEN]; unsigned int uint_in[ATT_LEN]; unsigned long long uint64_in[ATT_LEN]; long long int64_in[ATT_LEN]; /* Reopen the file and try different type conversions. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; /* No text conversions are allowed, and people who try them shold * be locked up, away from decent folk! */ if (nc_get_att_short(ncid, NC_GLOBAL, ATT_TEXT_NAME, short_in) != NC_ECHAR) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_TEXT_NAME, int_in) != NC_ECHAR) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_TEXT_NAME, float_in) != NC_ECHAR) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_TEXT_NAME, double_in) != NC_ECHAR) ERR; /* if (nc_get_att_ubyte(ncid, NC_GLOBAL, ATT_TEXT_NAME, uchar_in) != NC_ECHAR) ERR;*/ if (nc_get_att_ushort(ncid, NC_GLOBAL, ATT_TEXT_NAME, ushort_in) != NC_ECHAR) ERR; if (nc_get_att_uint(ncid, NC_GLOBAL, ATT_TEXT_NAME, uint_in) != NC_ECHAR) ERR; if (nc_get_att_longlong(ncid, NC_GLOBAL, ATT_TEXT_NAME, int64_in) != NC_ECHAR) ERR; if (nc_get_att_ulonglong(ncid, NC_GLOBAL, ATT_TEXT_NAME, uint64_in) != NC_ECHAR) ERR; /* Read all atts (except text) as double. */ if (nc_get_att_double(ncid, NC_GLOBAL, ATT_SCHAR_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != schar_out[i]) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_SHORT_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != short_out[i]) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_INT_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != int_out[i]) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_FLOAT_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != float_out[i]) ERR; /* Read all atts (except text) as float. */ if (nc_get_att_float(ncid, NC_GLOBAL, ATT_SCHAR_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != schar_out[i]) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_SHORT_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != short_out[i]) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_INT_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != (float)int_out[i]) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != (float)double_out[i]) ERR; /* Read all atts (except text) as int. */ if (nc_get_att_int(ncid, NC_GLOBAL, ATT_SCHAR_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != schar_out[i]) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_SHORT_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != short_out[i]) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_FLOAT_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != (int)float_out[i]) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != (int)double_out[i]) ERR; /* Read all atts (except text) as short. */ if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SCHAR_NAME, short_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != schar_out[i]) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_INT_NAME, short_in) != NC_ERANGE) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != (short)int_out[i]) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_FLOAT_NAME, short_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != (short)float_out[i]) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, short_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != (short)double_out[i]) ERR; /* Read all atts (except text) as schar. Some range errors will * result converting to schar. */ if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SHORT_NAME, schar_in) != NC_ERANGE) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != (signed char)short_out[i]) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_INT_NAME, schar_in) != NC_ERANGE) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != (signed char)int_out[i]) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, schar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != (signed char)float_out[i]) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, schar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != (signed char)double_out[i]) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing simple variable atts..."); { int ncid, varid, dimids[2]; nc_type att_type; size_t att_len; int i, v; char *speech_in; signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE}; short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT}; /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/ int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000}; float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125}; double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125}; /* Create a file with two vars, attaching to each an attribute of * each type. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR; if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR; if (nc_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid)) ERR; if (nc_put_att_text(ncid, varid, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR; if (nc_put_att_schar(ncid, varid, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR; if (nc_put_att_short(ncid, varid, ATT_SHORT_NAME, NC_SHORT, 3, short_out)) ERR; if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR; if (nc_put_att_float(ncid, varid, ATT_FLOAT_NAME, NC_FLOAT, 3, float_out)) ERR; if (nc_put_att_double(ncid, varid, ATT_DOUBLE_NAME, NC_DOUBLE, 3, double_out)) ERR; if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid)) ERR; if (nc_put_att_text(ncid, varid, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR; if (nc_put_att_schar(ncid, varid, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR; if (nc_put_att_short(ncid, varid, ATT_SHORT_NAME, NC_SHORT, 3, short_out)) ERR; if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR; if (nc_put_att_float(ncid, varid, ATT_FLOAT_NAME, NC_FLOAT, 3, float_out)) ERR; if (nc_put_att_double(ncid, varid, ATT_DOUBLE_NAME, NC_DOUBLE, 3, double_out)) ERR; if (nc_close(ncid)) ERR; /* Open the file and check attributes. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; for (v=0; v<2; v++) { if (nc_inq_att(ncid, v, ATT_TEXT_NAME, &att_type, &att_len)) ERR; if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR; if (!(speech_in = malloc(att_len + 1))) ERR; if (nc_get_att_text(ncid, v, ATT_TEXT_NAME, speech_in)) ERR; if (strcmp(speech, speech_in)) ERR; free(speech_in); if (nc_get_att_schar(ncid, v, ATT_SCHAR_NAME, schar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != schar_out[i]) ERR; if (nc_get_att_short(ncid, v, ATT_SHORT_NAME, short_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != short_out[i]) ERR; if (nc_get_att_int(ncid, v, ATT_INT_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != int_out[i]) ERR; if (nc_get_att_float(ncid, v, ATT_FLOAT_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != float_out[i]) ERR; if (nc_get_att_double(ncid, v, ATT_DOUBLE_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != double_out[i]) ERR; } if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing zero-length attributes..."); { int ncid; /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/ /* Create a file with a global attribute of each type of zero length. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, 0, NULL)) ERR; if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, 0, NULL)) ERR; /* if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UCHAR, ATT_LEN, uchar_out)) ERR;*/ if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, 0, NULL)) ERR; if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, 0, NULL)) ERR; if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, 0, NULL)) ERR; if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, 0, NULL)) ERR; if (nc_close(ncid)) ERR; } /* Make sure we can read all these zero-length atts. */ { int ncid; signed char schar_in[ATT_LEN]; short short_in[ATT_LEN]; /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/ int int_in[ATT_LEN]; float float_in[ATT_LEN]; double double_in[ATT_LEN]; size_t len; nc_type xtype; if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, NULL)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, &xtype, &len)) ERR; if (len || xtype != NC_CHAR) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_SCHAR_NAME, &xtype, &len)) ERR; if (len || xtype != NC_BYTE) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_SHORT_NAME, &xtype, &len)) ERR; if (len || xtype != NC_SHORT) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_INT_NAME, &xtype, &len)) ERR; if (len || xtype != NC_INT) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_FLOAT_NAME, &xtype, &len)) ERR; if (len || xtype != NC_FLOAT) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, &xtype, &len)) ERR; if (len || xtype != NC_DOUBLE) ERR; /* Conversions no longer result in range errors, since there's no data. */ if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, schar_in)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, schar_in)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_INT_NAME, schar_in)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SHORT_NAME, schar_in)) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing zero-length attributes and redef...(this test skipped for HDF5-1.8.0 beta1"); { int ncid; signed char schar_in[ATT_LEN]; short short_in[ATT_LEN]; int int_in[ATT_LEN]; float float_in[ATT_LEN]; double double_in[ATT_LEN]; /* Create a file with a global attribute of each type of zero length. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_enddef(ncid)) ERR; if (nc_redef(ncid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, 0, NULL)) ERR; if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, 0, NULL)) ERR; /* if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UCHAR, ATT_LEN, uchar_out)) ERR;*/ if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, 0, NULL)) ERR; if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, 0, NULL)) ERR; if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, 0, NULL)) ERR; if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, 0, NULL)) ERR; if (nc_close(ncid)) ERR; /* Make sure we can read all these zero-length atts added during a * redef. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, NULL)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR; /* Conversions no longer result in range errors, since there's no data. */ if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, schar_in)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, schar_in)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_INT_NAME, schar_in)) ERR; if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SHORT_NAME, schar_in)) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing attribute deletes and renames..."); { int ncid, varid, dimids[2]; nc_type att_type; size_t att_len; char *speech_in; char name_in[NC_MAX_NAME + 1]; int attid_in, natts_in; int int_out[ATT_LEN] = {-100000, 128, 100000}; /* Create a file with a global attribute. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR; if (nc_close(ncid)) ERR; /* Rename it. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq_attid(ncid, NC_GLOBAL, ATT_TEXT_NAME, &attid_in)) ERR; if (attid_in != 0) ERR; if (nc_inq_attname(ncid, NC_GLOBAL, attid_in, name_in)) ERR; if (strcmp(name_in, ATT_TEXT_NAME)) ERR; if (nc_rename_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, ATT_TEXT_NAME2)) ERR; if (nc_inq_attname(ncid, NC_GLOBAL, attid_in, name_in)) ERR; if (strcmp(name_in, ATT_TEXT_NAME2)) ERR; if (nc_close(ncid)) ERR; if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME2, &att_type, &att_len)) ERR; if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR; if (!(speech_in = malloc(att_len + 1))) ERR; if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME2, speech_in)) ERR; if (strcmp(speech, speech_in)) ERR; free(speech_in); if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, speech_in) != NC_ENOTATT) ERR; if (nc_close(ncid)) ERR; /* Now delete the att. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_del_att(ncid, NC_GLOBAL, ATT_TEXT_NAME2)) ERR; if (nc_close(ncid)) ERR; /* Now create a file with a variable, which has an att. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR; if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR; if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR; if (nc_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid)) ERR; if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and delete it. Make sure it's gone. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_del_att(ncid, 0, ATT_INT_NAME)) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and readd the attribute. Enddef and redef, * and delete it, then check to make sure it's gone. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR; if (nc_enddef(ncid)) ERR; if (nc_redef(ncid)) ERR; if (nc_del_att(ncid, 0, ATT_INT_NAME)) ERR; if (nc_inq_varnatts(ncid, 0, &natts_in)) ERR; if (natts_in != 0) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing attribute create order..."); #define ATT0 "Maturin" #define ATT1 "Aubery" { int ncid, varid, dimids[2]; int attid_in; const int number = 42; /* Create a file with several global attributes. */ if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; if (nc_put_att_int(ncid, NC_GLOBAL, ATT0, NC_INT, 1, &number)) ERR; if (nc_put_att_int(ncid, NC_GLOBAL, ATT1, NC_INT, 1, &number)) ERR; if (nc_close(ncid)) ERR; /* Open it and check the order. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq_attid(ncid, NC_GLOBAL, ATT0, &attid_in)) ERR; if (attid_in != 0) ERR; if (nc_inq_attid(ncid, NC_GLOBAL, ATT1, &attid_in)) ERR; if (attid_in != 1) ERR; if (nc_close(ncid)) ERR; /* Now create a file with a variable, which has two atts. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR; if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR; if (nc_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid)) ERR; if (nc_put_att_int(ncid, varid, ATT0, NC_INT, 1, &number)) ERR; if (nc_put_att_int(ncid, varid, ATT1, NC_INT, 1, &number)) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and check the order of the attributes on the var. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq_attid(ncid, 0, ATT0, &attid_in)) ERR; if (attid_in != 0) ERR; if (nc_inq_attid(ncid, 0, ATT1, &attid_in)) ERR; if (attid_in != 1) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing attribute ordering some more..."); #define VAR_NAME "i" #define A1_NAME "i" #define A2_NAME "f" #define A3_NAME "d" #define A1_LEN 3 #define A2_LEN 4 #define A3_LEN 5 { int ncid; int varid, natts, nvars; double dvalue[] = {999.99, 999.99, 999.99, 999.99, 999.99}; int varids[1]; char name_in[NC_MAX_NAME + 1]; /* Create a file with one var, and attach three atts to it. */ if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; if (nc_def_var(ncid, VAR_NAME, NC_INT, 0, NULL, &varid)) ERR; if (nc_put_att_double(ncid, varid, A1_NAME, NC_INT, A1_LEN, dvalue)) ERR; if (nc_put_att_double(ncid, varid, A2_NAME, NC_INT, A2_LEN, dvalue)) ERR; if (nc_put_att_double(ncid, varid, A3_NAME, NC_INT, A3_LEN, dvalue)) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and check. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_inq_varids(ncid, &nvars, varids)) ERR; if (nvars != 1 || varids[0] != 0) ERR; if (nc_inq_varnatts(ncid, 0, &natts)) ERR; if (natts != 3) ERR; if (nc_inq_attname(ncid, 0, 0, name_in)) ERR; if (strcmp(name_in, A1_NAME)) ERR; if (nc_inq_attname(ncid, 0, 1, name_in)) ERR; if (strcmp(name_in, A2_NAME)) ERR; if (nc_inq_attname(ncid, 0, 2, name_in)) ERR; if (strcmp(name_in, A3_NAME)) ERR; /* Close up shop. */ if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing attribute ordering even more..."); /* Test the ordering of atts for each cmode. */ if (tst_att_ordering(NC_CLOBBER)) ERR; if (tst_att_ordering(NC_CLOBBER|NC_64BIT_OFFSET)) ERR; if (tst_att_ordering(NC_CLOBBER|NC_NETCDF4)) ERR; if (tst_att_ordering(NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL)) ERR; SUMMARIZE_ERR; printf("*** testing attributes and enddef/redef..."); #define ATT_1 "a" #define ATT_2 "b" #define ATT_3 "c" { int ncid, att = 1; if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL|NC_CLOBBER, &ncid)) ERR; if (nc_enddef(ncid)) ERR; if (nc_redef(ncid)) ERR; if (nc_put_att(ncid, NC_GLOBAL, ATT_1, NC_INT, 1, &att)) ERR; if (nc_put_att(ncid, NC_GLOBAL, ATT_2, NC_INT, 1, &att)) ERR; if (nc_put_att(ncid, NC_GLOBAL, ATT_3, NC_INT, 1, &att)) ERR; if (nc_close(ncid)) ERR; if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing copy of simple global atts..."); { int ncid, ncid2; nc_type att_type; size_t att_len; int i; char *speech_in; signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE}; unsigned char uchar_in[ATT_LEN], uchar_out[ATT_LEN] = {0, 128, NC_MAX_CHAR}; short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT}; int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000}; float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125}; double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125}; unsigned short ushort_in[ATT_LEN], ushort_out[ATT_LEN] = {0, 128, NC_MAX_USHORT}; unsigned int uint_in[ATT_LEN], uint_out[ATT_LEN] = {0, 128, NC_MAX_UINT}; unsigned long long uint64_in[ATT_LEN], uint64_out[ATT_LEN] = {0, 128, 18446744073709551612ULL}; long long int64_in[ATT_LEN], int64_out[ATT_LEN] = {NC_MIN_INT64, 128, NC_MAX_INT64}; /* Create a file with a global attribute of each type. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR; if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR; if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UBYTE, ATT_LEN, uchar_out)) ERR; if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, ATT_LEN, short_out)) ERR; if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, ATT_LEN, int_out)) ERR; if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, ATT_LEN, float_out)) ERR; if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, ATT_LEN, double_out)) ERR; if (nc_put_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, NC_USHORT, ATT_LEN, ushort_out)) ERR; if (nc_put_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, NC_UINT, ATT_LEN, uint_out)) ERR; if (nc_put_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, NC_INT64, ATT_LEN, int64_out)) ERR; if (nc_put_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, NC_UINT64, ATT_LEN, uint64_out)) ERR; /* Create another file and copy all the attributes. */ if (nc_create(FILE_NAME2, NC_NETCDF4, &ncid2)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_SCHAR_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_UCHAR_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_SHORT_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_INT_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_FLOAT_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_USHORT_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_UINT_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_INT64_NAME, ncid2, NC_GLOBAL)) ERR; if (nc_copy_att(ncid, NC_GLOBAL, ATT_UINT64_NAME, ncid2, NC_GLOBAL)) ERR; /* Close both files. */ if (nc_close(ncid)) ERR; if (nc_close(ncid2)) ERR; /* Open the file and check attributes. */ if (nc_open(FILE_NAME2, 0, &ncid)) ERR; /* Check text. */ if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, &att_type, &att_len)) ERR; if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR; if (!(speech_in = malloc(att_len + 1))) ERR; if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, speech_in)) ERR; if (strcmp(speech, speech_in)) ERR; free(speech_in); /* Check numeric values. */ if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (schar_in[i] != schar_out[i]) ERR; if (nc_get_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, uchar_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (uchar_in[i] != uchar_out[i]) ERR; if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (short_in[i] != short_out[i]) ERR; if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int_in[i] != int_out[i]) ERR; if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (float_in[i] != float_out[i]) ERR; if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (double_in[i] != double_out[i]) ERR; if (nc_get_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, ushort_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (ushort_in[i] != ushort_out[i]) ERR; if (nc_get_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, uint_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (uint_in[i] != uint_out[i]) ERR; if (nc_get_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, int64_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (int64_in[i] != int64_out[i]) ERR; if (nc_get_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, uint64_in)) ERR; for (i = 0; i < ATT_LEN; i++) if (uint64_in[i] != uint64_out[i]) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; FINAL_RESULTS; }
int CNetCdfInterface::ncGetAttType(int ncid, int varid, const char* attrName, double* data) { return nc_get_att_double(ncid, varid, attrName, data); }
str NCDFattach(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { mvc *m = NULL; sql_schema *sch = NULL; sql_table *tfiles = NULL, *tdims = NULL, *tvars = NULL, *tvardim = NULL, *tattrs = NULL; sql_column *col; str msg = MAL_SUCCEED; str fname = *(str*)getArgReference(stk, pci, 1); char buf[BUFSIZ], *s= buf; oid fid, rid = oid_nil; sql_trans *tr; int ncid; /* dataset id */ int ndims, nvars, ngatts, unlimdim; int didx, vidx, vndims, vnatts, i, aidx, coord_dim_id = -1; int vdims[NC_MAX_VAR_DIMS]; size_t dlen, alen; char dname[NC_MAX_NAME+1], vname[NC_MAX_NAME+1], aname[NC_MAX_NAME +1], abuf[80], *aval; char **dims = NULL; nc_type vtype, atype; /* == int */ int retval, avalint; float avalfl; double avaldbl; msg = getSQLContext(cntxt, mb, &m, NULL); if (msg) return msg; tr = m->session->tr; sch = mvc_bind_schema(m, "sys"); if ( !sch ) return createException(MAL, "netcdf.attach", "Cannot get schema sys\n"); tfiles = mvc_bind_table(m, sch, "netcdf_files"); tdims = mvc_bind_table(m, sch, "netcdf_dims"); tvars = mvc_bind_table(m, sch, "netcdf_vars"); tvardim = mvc_bind_table(m, sch, "netcdf_vardim"); tattrs = mvc_bind_table(m, sch, "netcdf_attrs"); if (tfiles == NULL || tdims == NULL || tvars == NULL || tvardim == NULL || tattrs == NULL) return createException(MAL, "netcdf.attach", "Catalog table missing\n"); /* check if the file is already attached */ col = mvc_bind_column(m, tfiles, "location"); rid = table_funcs.column_find_row(m->session->tr, col, fname, NULL); if (rid != oid_nil) return createException(SQL, "netcdf.attach", "File %s is already attached\n", fname); /* Open NetCDF file */ if ((retval = nc_open(fname, NC_NOWRITE, &ncid))) return createException(MAL, "netcdf.test", "Cannot open NetCDF \ file %s: %s", fname, nc_strerror(retval)); if ((retval = nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdim))) return createException(MAL, "netcdf.test", "Cannot read NetCDF \ header: %s", nc_strerror(retval)); /* Insert row into netcdf_files table */ col = mvc_bind_column(m, tfiles, "file_id"); fid = store_funcs.count_col(tr, col, 1) + 1; snprintf(buf, BUFSIZ, INSFILE, (int)fid, fname); if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, FALSE, NULL)) != MAL_SUCCEED ) goto finish; /* Read dimensions from NetCDF header and insert a row for each one into netcdf_dims table */ dims = (char **)GDKzalloc(sizeof(char *) * ndims); for (didx = 0; didx < ndims; didx++){ if ((retval = nc_inq_dim(ncid, didx, dname, &dlen))) return createException(MAL, "netcdf.attach", "Cannot read dimension %d : %s", didx, nc_strerror(retval)); snprintf(buf, BUFSIZ, INSDIM, didx, (int)fid, dname, (int)dlen); if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, FALSE, NULL)) != MAL_SUCCEED ) goto finish; dims[didx] = GDKstrdup(dname); } /* Read variables and attributes from the header and insert rows in netcdf_vars, netcdf_vardims, and netcdf_attrs tables */ for (vidx = 0; vidx < nvars; vidx++){ if ( (retval = nc_inq_var(ncid, vidx, vname, &vtype, &vndims, vdims, &vnatts))) return createException(MAL, "netcdf.attach", "Cannot read variable %d : %s", vidx, nc_strerror(retval)); /* Check if this is coordinate variable */ if ( (vndims == 1) && ( strcmp(vname, dims[vdims[0]]) == 0 )) coord_dim_id = vdims[0]; else coord_dim_id = -1; snprintf(buf, BUFSIZ, INSVAR, vidx, (int)fid, vname, prim_type_name(vtype), vndims, coord_dim_id); if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, FALSE, NULL)) != MAL_SUCCEED ) goto finish; if ( coord_dim_id < 0 ){ for (i = 0; i < vndims; i++){ snprintf(buf, BUFSIZ, INSVARDIM, vidx, vdims[i], (int)fid, i); if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, FALSE, NULL)) != MAL_SUCCEED ) goto finish; } } if ( vnatts > 0 ) { /* fill in netcdf_attrs table */ for (aidx = 0; aidx < vnatts; aidx++){ if ((retval = nc_inq_attname(ncid,vidx,aidx,aname))) return createException(MAL, "netcdf.attach", "Cannot read attribute %d of variable %d: %s", aidx, vidx, nc_strerror(retval)); if ((retval = nc_inq_att(ncid,vidx,aname,&atype,&alen))) return createException(MAL, "netcdf.attach", "Cannot read attribute %s type and length: %s", aname, nc_strerror(retval)); switch ( atype ) { case NC_CHAR: aval = (char *) GDKzalloc(alen + 1); if ((retval = nc_get_att_text(ncid,vidx,aname,aval))) return createException(MAL, "netcdf.attach", "Cannot read attribute %s value: %s", aname, nc_strerror(retval)); fix_quote(aval, alen); aval[alen] = '\0'; snprintf(buf, BUFSIZ, INSATTR, vname, aname, "string", aval, (int)fid, "root"); GDKfree(aval); break; case NC_INT: if ((retval = nc_get_att_int(ncid,vidx,aname,&avalint))) return createException(MAL, "netcdf.attach", "Cannot read attribute %s value: %s", aname, nc_strerror(retval)); snprintf(abuf,80,"%d",avalint); snprintf(buf, BUFSIZ, INSATTR, vname, aname, prim_type_name(atype), abuf, (int)fid, "root"); break; case NC_FLOAT: if ((retval = nc_get_att_float(ncid,vidx,aname,&avalfl))) return createException(MAL, "netcdf.attach", "Cannot read attribute %s value: %s", aname, nc_strerror(retval)); snprintf(abuf,80,"%7.2f",avalfl); snprintf(buf, BUFSIZ, INSATTR, vname, aname, prim_type_name(atype), abuf, (int)fid, "root"); break; case NC_DOUBLE: if ((retval = nc_get_att_double(ncid,vidx,aname,&avaldbl))) return createException(MAL, "netcdf.attach", "Cannot read attribute %s value: %s", aname, nc_strerror(retval)); snprintf(abuf,80,"%7.2e",avaldbl); snprintf(buf, BUFSIZ, INSATTR, vname, aname, prim_type_name(atype), abuf, (int)fid, "root"); break; default: continue; /* next attribute */ } printf("statement: '%s'\n", s); if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, FALSE, NULL)) != MAL_SUCCEED ) goto finish; } /* attr loop */ } } /* var loop */ /* Extract global attributes */ for (aidx = 0; aidx < ngatts; aidx++){ if ((retval = nc_inq_attname(ncid,NC_GLOBAL,aidx,aname))) return createException(MAL, "netcdf.attach", "Cannot read global attribute %d: %s", aidx, nc_strerror(retval)); if ((retval = nc_inq_att(ncid,NC_GLOBAL,aname,&atype,&alen))) return createException(MAL, "netcdf.attach", "Cannot read global attribute %s type and length: %s", aname, nc_strerror(retval)); switch ( atype ) { case NC_CHAR: aval = (char *) GDKzalloc(alen + 1); if ((retval = nc_get_att_text(ncid,NC_GLOBAL,aname,aval))) return createException(MAL, "netcdf.attach", "Cannot read global attribute %s value: %s", aname, nc_strerror(retval)); fix_quote(aval, alen); aval[alen] = '\0'; snprintf(buf, BUFSIZ, INSATTR, "GLOBAL", aname, "string", aval, (int)fid, "root"); GDKfree(aval); break; case NC_INT: if ((retval = nc_get_att_int(ncid,NC_GLOBAL,aname,&avalint))) return createException(MAL, "netcdf.attach", "Cannot read global attribute %s of type %s : %s", aname, prim_type_name(atype), nc_strerror(retval)); snprintf(abuf,80,"%d",avalint); snprintf(buf, BUFSIZ, INSATTR, "GLOBAL", aname, prim_type_name(atype), abuf, (int)fid, "root"); break; case NC_FLOAT: if ((retval = nc_get_att_float(ncid,NC_GLOBAL,aname,&avalfl))) return createException(MAL, "netcdf.attach", "Cannot read global attribute %s of type %s: %s", aname, prim_type_name(atype), nc_strerror(retval)); snprintf(abuf,80,"%7.2f",avalfl); snprintf(buf, BUFSIZ, INSATTR, "GLOBAL", aname, prim_type_name(atype), abuf, (int)fid, "root"); break; case NC_DOUBLE: if ((retval = nc_get_att_double(ncid,NC_GLOBAL,aname,&avaldbl))) return createException(MAL, "netcdf.attach", "Cannot read global attribute %s value: %s", aname, nc_strerror(retval)); snprintf(abuf,80,"%7.2e",avaldbl); snprintf(buf, BUFSIZ, INSATTR, "GLOBAL", aname, prim_type_name(atype), abuf, (int)fid, "root"); break; default: continue; /* next attribute */ } printf("global: '%s'\n", s); if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, FALSE, NULL)) != MAL_SUCCEED ) goto finish; } /* global attr loop */ finish: nc_close(ncid); if (dims != NULL ){ for (didx = 0; didx < ndims; didx++) GDKfree(dims[didx]); GDKfree(dims); } return msg; }
bool NETCDFFileObject::ReadAttribute(const char *varname, const char *attname, TypeEnum *type, int *ndims, int **dims, void **value) { const char *mName = "NETCDFFileObject::ReadAttribute: "; int varid, status; int natts = 0; bool varvalid = false; if(varname == 0) { varid = NC_GLOBAL; if((status = nc_inq_natts(GetFileHandle(), &natts)) == NC_NOERR) varvalid = natts > 0; else { debug4 << mName << "0: "; HandleError(status); } } else { // Look up the variable name and gets its variable id. varvalid = GetVarId(varname, &varid); } if(varvalid) { nc_type atttype; size_t attsize; if((status = nc_inq_att(GetFileHandle(), varid, attname, &atttype, &attsize)) == NC_NOERR) { void *val = 0; TypeEnum t = NO_TYPE; // Try and read the attribute. if(atttype == NC_CHAR) { char *arr = new char[attsize+1]; status = nc_get_att_text(GetFileHandle(), varid, attname, arr); if(status != NC_NOERR) delete [] arr; else { // Trim trailing spaces. arr[attsize] = '\0'; char *c2 = arr + attsize - 1; while(c2 >= arr && *c2 == ' ') *c2-- = '\0'; val = (void*)arr; } t = CHARARRAY_TYPE; } else if(atttype == NC_BYTE) { unsigned char *arr = new unsigned char[attsize+1]; status = nc_get_att_uchar(GetFileHandle(), varid, attname, arr); if(status != NC_NOERR) delete [] arr; else val = (void*)arr; t = UCHARARRAY_TYPE; } else if(atttype == NC_SHORT) { short *arr = new short[attsize]; status = nc_get_att_short(GetFileHandle(), varid, attname, arr); if(status != NC_NOERR) delete [] arr; else val = (void*)arr; t = SHORTARRAY_TYPE; } else if(atttype == NC_INT) { int *arr = new int[attsize]; status = nc_get_att_int(GetFileHandle(), varid, attname, arr); if(status != NC_NOERR) delete [] arr; else val = (void*)arr; t = INTEGERARRAY_TYPE; } else if(atttype == NC_LONG) { long *arr = new long[attsize]; status = nc_get_att_long(GetFileHandle(), varid, attname, arr); if(status != NC_NOERR) delete [] arr; else val = (void*)arr; t = LONGARRAY_TYPE; } else if(atttype == NC_FLOAT) { float *arr = new float[attsize]; status = nc_get_att_float(GetFileHandle(), varid, attname, arr); if(status != NC_NOERR) delete [] arr; else val = (void*)arr; t = FLOATARRAY_TYPE; } else if(atttype == NC_DOUBLE) { double *arr = new double[attsize]; status = nc_get_att_double(GetFileHandle(), varid, attname, arr); if(status != NC_NOERR) delete [] arr; else val = (void*)arr; t = DOUBLEARRAY_TYPE; } if(status == NC_NOERR) { *type = t; *ndims = 1; int *d = new int[1]; d[0] = (int)attsize; *dims = d; *value = val; } else { *type = NO_TYPE; *ndims = 0; *dims = 0; *value = 0; debug4 << mName << "3: "; HandleError(status); varvalid = false; } } else { varvalid = false; debug4 << mName << "4: "; HandleError(status); } } return varvalid; }
/* NOTE that space for the attribute must already be allocated! */ void R_nc_get_att_double( int *ncid, int *varid, char **attname, double *attribute, int *retval ) { *retval = nc_get_att_double(*ncid, *varid, attname[0], attribute); }
int test_pio_attr(int flag) { /* MPI stuff. */ int mpi_size, mpi_rank; MPI_Comm comm = MPI_COMM_WORLD; MPI_Info info = MPI_INFO_NULL; /* Netcdf-4 stuff. */ int ncid; int nvid; int j, i; double rh_range[2]; static char title[] = "parallel attr to netCDF"; nc_type st_type,vr_type; size_t vr_len,st_len; size_t orivr_len; double *vr_val; char *st_val; /* two dimensional integer data*/ int dimids[NDIMS1]; size_t start[NDIMS1]; size_t count[NDIMS1]; int *data; int *tempdata; /* Initialize MPI. */ MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); /* Create a parallel netcdf-4 file. */ /* nc_set_log_level(NC_TURN_OFF_LOGGING); */ /* nc_set_log_level(3);*/ if (nc_create_par(file_name, facc_type, comm, info, &ncid)) ERR; /* Create a 2-D variable so that an attribute can be added. */ if (nc_def_dim(ncid, "d1", DIMSIZE2, dimids)) ERR; if (nc_def_dim(ncid, "d2", DIMSIZE, &dimids[1])) ERR; /* Create one var. */ if (nc_def_var(ncid, "v1", NC_INT, NDIMS1, dimids, &nvid)) ERR; orivr_len = 2; rh_range[0] = 1.0; rh_range[1] = 1000.0; /* Write attributes of a variable */ if (nc_put_att_double (ncid, nvid, "valid_range", NC_DOUBLE, orivr_len, rh_range)) ERR; if (nc_put_att_text (ncid, nvid, "title", strlen(title), title)) ERR; /* Write global attributes */ if (nc_put_att_double (ncid, NC_GLOBAL, "g_valid_range", NC_DOUBLE, orivr_len, rh_range)) ERR; if (nc_put_att_text (ncid, NC_GLOBAL, "g_title", strlen(title), title)) ERR; if (nc_enddef(ncid)) ERR; /* Set up slab for this process. */ start[0] = 0; start[1] = mpi_rank * DIMSIZE/mpi_size; count[0] = DIMSIZE2; count[1] = DIMSIZE/mpi_size; /* Access parallel */ if (nc_var_par_access(ncid, nvid, flag)) ERR; /* Allocating data */ data = malloc(sizeof(int)*count[1]*count[0]); tempdata = data; for(j = 0; j < count[0]; j++) for (i = 0; i < count[1]; i++) { *tempdata = mpi_rank * (j + 1); tempdata++; } if (nc_put_vara_int(ncid, nvid, start, count, data)) ERR; free(data); /* Close the netcdf file. */ if (nc_close(ncid)) ERR; /* Read attributes */ if (nc_open_par(file_name, facc_type_open, comm, info, &ncid)) ERR; /* Set up slab for this process. */ start[0] = 0; start[1] = mpi_rank * DIMSIZE/mpi_size; count[0] = DIMSIZE2; count[1] = DIMSIZE/mpi_size; /* Inquiry variable */ if (nc_inq_varid(ncid, "v1", &nvid)) ERR; /* Access parallel */ if (nc_var_par_access(ncid, nvid, flag)) ERR; /* Inquiry attribute */ if (nc_inq_att (ncid, nvid, "valid_range", &vr_type, &vr_len)) ERR; /* check stuff */ if(vr_type != NC_DOUBLE || vr_len != orivr_len) ERR; vr_val = (double *) malloc(vr_len * sizeof(double)); /* Get variable attribute values */ if (nc_get_att_double(ncid, nvid, "valid_range", vr_val)) ERR; /* Check variable attribute value */ for(i = 0; i < vr_len; i++) if (vr_val[i] != rh_range[i]) ERR_RET; free(vr_val); /* Inquiry global attribute */ if (nc_inq_att (ncid, NC_GLOBAL, "g_valid_range", &vr_type, &vr_len)) ERR; /* Check stuff. */ if(vr_type != NC_DOUBLE || vr_len != orivr_len) ERR; /* Obtain global attribute value */ vr_val = (double *) malloc(vr_len * sizeof(double)); if (nc_get_att_double(ncid, NC_GLOBAL, "g_valid_range", vr_val)) ERR; /* Check global attribute value */ for(i = 0; i < vr_len; i++) if (vr_val[i] != rh_range[i]) ERR_RET; free(vr_val); /* Inquiry string attribute of a variable */ if (nc_inq_att (ncid, nvid, "title", &st_type, &st_len)) ERR; /* check string attribute length */ if(st_len != strlen(title)) ERR_RET; /* Check string attribute type */ if(st_type != NC_CHAR) ERR_RET; /* Allocate meory for string attribute */ st_val = (char *) malloc(st_len * (sizeof(char))); /* Obtain variable string attribute value */ if (nc_get_att_text(ncid, nvid,"title", st_val)) ERR; /*check string value */ if(strncmp(st_val,title,st_len)) { free(st_val); ERR_RET; } free(st_val); /*Inquiry global attribute */ if (nc_inq_att (ncid, NC_GLOBAL, "g_title", &st_type, &st_len)) ERR; /* check attribute length*/ if(st_len != strlen(title)) ERR_RET; /*check attribute type*/ if(st_type != NC_CHAR) ERR_RET; /* obtain global string attribute value */ st_val = (char*)malloc(st_len*sizeof(char)); if (nc_get_att_text(ncid, NC_GLOBAL,"g_title", st_val)) ERR; /* check attribute value */ if(strncmp(st_val,title,st_len)){ free(st_val); ERR_RET; } free(st_val); /* Close the netcdf file. */ if (nc_close(ncid)) ERR; return 0; }
static void do_ncdump(const char *path, struct fspec* specp) { int ndims; /* number of dimensions */ int nvars; /* number of variables */ int ngatts; /* number of global attributes */ int xdimid; /* id of unlimited dimension */ int dimid; /* dimension id */ int varid; /* variable id */ struct ncdim dims[NC_MAX_DIMS]; /* dimensions */ size_t vdims[NC_MAX_DIMS]; /* dimension sizes for a single variable */ struct ncvar var; /* variable */ struct ncatt att; /* attribute */ int id; /* dimension number per variable */ int ia; /* attribute number */ int iv; /* variable number */ int is_coord; /* true if variable is a coordinate variable */ int ncid; /* netCDF id */ vnode* vlist = 0; /* list for vars specified with -v option */ int nc_status; /* return from netcdf calls */ nc_status = nc_open(path, NC_NOWRITE, &ncid); if (nc_status != NC_NOERR) { error("%s: %s", path, nc_strerror(nc_status)); } /* * If any vars were specified with -v option, get list of associated * variable ids */ if (specp->nlvars > 0) { vlist = newvlist(); /* list for vars specified with -v option */ for (iv=0; iv < specp->nlvars; iv++) { NC_CHECK( nc_inq_varid(ncid, specp->lvars[iv], &varid) ); varadd(vlist, varid); } } /* if name not specified, derive it from path */ if (specp->name == (char *)0) { specp->name = name_path (path); } Printf ("netcdf %s {\n", specp->name); /* * get number of dimensions, number of variables, number of global * atts, and dimension id of unlimited dimension, if any */ NC_CHECK( nc_inq(ncid, &ndims, &nvars, &ngatts, &xdimid) ); /* get dimension info */ if (ndims > 0) Printf ("dimensions:\n"); for (dimid = 0; dimid < ndims; dimid++) { NC_CHECK( nc_inq_dim(ncid, dimid, dims[dimid].name, &dims[dimid].size) ); if (dimid == xdimid) Printf ("\t%s = %s ; // (%ld currently)\n",dims[dimid].name, "UNLIMITED", (long)dims[dimid].size); else Printf ("\t%s = %ld ;\n", dims[dimid].name, (long)dims[dimid].size); } if (nvars > 0) Printf ("variables:\n"); /* get variable info, with variable attributes */ for (varid = 0; varid < nvars; varid++) { NC_CHECK( nc_inq_var(ncid, varid, var.name, &var.type, &var.ndims, var.dims, &var.natts) ); Printf ("\t%s %s", type_name(var.type), var.name); if (var.ndims > 0) Printf ("("); for (id = 0; id < var.ndims; id++) { Printf ("%s%s", dims[var.dims[id]].name, id < var.ndims-1 ? ", " : ")"); } Printf (" ;\n"); /* get variable attributes */ for (ia = 0; ia < var.natts; ia++) pr_att(ncid, varid, var.name, ia); /* print ia-th attribute */ } /* get global attributes */ if (ngatts > 0) Printf ("\n// global attributes:\n"); for (ia = 0; ia < ngatts; ia++) pr_att(ncid, NC_GLOBAL, "", ia); /* print ia-th global attribute */ if (! specp->header_only) { if (nvars > 0) { Printf ("data:\n"); } /* output variable data */ for (varid = 0; varid < nvars; varid++) { /* if var list specified, test for membership */ if (specp->nlvars > 0 && ! varmember(vlist, varid)) continue; NC_CHECK( nc_inq_var(ncid, varid, var.name, &var.type, &var.ndims, var.dims, &var.natts) ); if (specp->coord_vals) { /* Find out if this is a coordinate variable */ is_coord = 0; for (dimid = 0; dimid < ndims; dimid++) { if (strcmp(dims[dimid].name, var.name) == 0 && var.ndims == 1) { is_coord = 1; break; } } if (! is_coord) /* don't get data for non-coordinate vars */ continue; } /* * Only get data for variable if it is not a record variable, * or if it is a record variable and at least one record has * been written. */ if (var.ndims == 0 || var.dims[0] != xdimid || dims[xdimid].size != 0) { /* Collect variable's dim sizes */ for (id = 0; id < var.ndims; id++) vdims[id] = dims[var.dims[id]].size; var.has_fillval = 1; /* by default, but turn off for bytes */ /* get _FillValue attribute */ nc_status = nc_inq_att(ncid,varid,_FillValue,&att.type,&att.len); if(nc_status == NC_NOERR && att.type == var.type && att.len == 1) { if(var.type == NC_CHAR) { char fillc; NC_CHECK( nc_get_att_text(ncid, varid, _FillValue, &fillc ) ); var.fillval = fillc; } else { NC_CHECK( nc_get_att_double(ncid, varid, _FillValue, &var.fillval) ); } } else { switch (var.type) { case NC_BYTE: /* don't do default fill-values for bytes, too risky */ var.has_fillval = 0; break; case NC_CHAR: var.fillval = NC_FILL_CHAR; break; case NC_SHORT: var.fillval = NC_FILL_SHORT; break; case NC_INT: var.fillval = NC_FILL_INT; break; case NC_FLOAT: var.fillval = NC_FILL_FLOAT; break; case NC_DOUBLE: var.fillval = NC_FILL_DOUBLE; break; default: break; } } if (vardata(&var, vdims, ncid, varid, specp) == -1) { error("can't output data for variable %s", var.name); NC_CHECK( nc_close(ncid) ); if (vlist) free(vlist); return; } } } } Printf ("}\n"); NC_CHECK( nc_close(ncid) ); if (vlist) free(vlist); }
/*************************************************************************************** * Given a numeric varid, this reads the data from the file. * Does not return on errors. */ SEXP R_nc_get_vara_numvarid( SEXP sx_nc, SEXP sx_varid, SEXP sx_start, SEXP sx_count ) { int varid, ncid, ndims, len_start, len_count, i, j, ierr, start_arg[MAX_NC_DIMS], count_arg[MAX_NC_DIMS], *data_addr_i, missval_i, ndims_cgt1; SEXP rv_data = R_NilValue /* -Wall */, sx_dim; size_t start[MAX_NC_DIMS], count[MAX_NC_DIMS], varsize[MAX_NC_DIMS], tot_var_size, i_szt; double *data_addr_d, missval_d, missval_tol; nc_type vartype; /*--------------------------------------------------------------------------- * On entry, the following are guaranteed to be integers: * varid * *start * *count * * Note that varid, start, and/or count could be a single '-1' if the user * has not specified the start and count to use. * 'sx_nc' is guaranteed to be the full object of class 'ncdf'. *----------------------------------------------------------------------------*/ varid = INTEGER(sx_varid)[0]; ncid = INTEGER(R_ncu_getListElement( sx_nc, "id" ))[0]; /*----------------------------------------------------------------------- * Copy passed start and count to local vars so we can modify them safely *----------------------------------------------------------------------*/ len_start = length(sx_start); for( i=0; i<len_start; i++ ) start_arg[i] = INTEGER(sx_start)[i]; len_count = length(sx_count); for( i=0; i<len_count; i++ ) count_arg[i] = INTEGER(sx_count)[i]; /*----------------------------------------- * Get varid to use, if passed value is -1. *----------------------------------------*/ if( varid == -1 ) { /*---------------------------------------------------- * Get how many vars are in this file ... if only one, * use that one. Otherwise, signal error. *---------------------------------------------------*/ varid = R_ncu_varid_onlyvar( ncid ); if( varid == -1 ) error( "Error: no var specified, and the file has more than one valid var!" ); } else varid--; /* go from R to C indexing */ /*-------------------------------------------------------- * Get # of dims for this var, as a check to make sure any * passed 'start' and 'count' are correct. *-------------------------------------------------------*/ ierr = nc_inq_varndims( ncid, varid, &ndims ); if( ierr != NC_NOERR ) error( "Internal error in ncdf package, routine R_nc_get_vara_numvarid: failed to get ndims for var!\n" ); /*------------------------------------------------------ * Get our variable's size, and the start & count to use *-----------------------------------------------------*/ R_ncu_get_varsize( ncid, varid, ndims, varsize ); R_ncu_calc_start_count( ncid, varid, start_arg, len_start, count_arg, len_count, varsize, ndims, start, count ); /*------------------------------------------------------------ * Allocate space for data, depending on the type of var it is *-----------------------------------------------------------*/ ierr = nc_inq_vartype( ncid, varid, &vartype ); if( ierr != NC_NOERR ) error( "Internal error in ncdf package, routine R_nc_get_vara_numvarid: failed to get type for var!\n" ); tot_var_size = 1L; for( i=0; i<ndims; i++ ) { tot_var_size *= count[i]; } switch( vartype ) { case NC_CHAR: error( "chars not handled yet, use old interface" ); break; case NC_BYTE: case NC_SHORT: case NC_INT: /*--------------- * Allocate space *--------------*/ PROTECT( rv_data = allocVector( INTSXP, tot_var_size )); data_addr_i = &(INTEGER(rv_data)[0]); /* Is this guaranteed to work? Dunno. */ /*-------------- * Read the data *-------------*/ ierr = nc_get_vara_int( ncid, varid, start, count, data_addr_i ); if( ierr != NC_NOERR ) error( "Error while trying to read int data from file!" ); /*--------------------- * Handle missing value *--------------------*/ ierr = nc_get_att_int( ncid, varid, "missing_value", &missval_i ); if( ierr != NC_NOERR ) /* No missing value attribute found, use default value */ missval_i = NC_FILL_INT; for( i_szt=0L; i_szt<tot_var_size; i_szt++ ) if( data_addr_i[i_szt] == missval_i ) data_addr_i[i_szt] = NA_INTEGER; break; case NC_FLOAT: case NC_DOUBLE: /*--------------- * Allocate space *--------------*/ PROTECT( rv_data = allocVector( REALSXP, tot_var_size )); data_addr_d = &(REAL(rv_data)[0]); /* Is this guaranteed to work? Dunno. */ /*-------------- * Read the data *-------------*/ ierr = nc_get_vara_double( ncid, varid, start, count, data_addr_d ); if( ierr != NC_NOERR ) error( "Error while trying to read real data from file!" ); /*--------------------- * Handle missing value *--------------------*/ ierr = nc_get_att_double( ncid, varid, "missing_value", &missval_d ); if( ierr != NC_NOERR ) /* No missing value attribute found, use default value */ missval_d = 1.e30; missval_tol = 1.e-5*fabs(missval_d); for( i_szt=0L; i_szt<tot_var_size; i_szt++ ) if( fabs(data_addr_d[i_szt] - missval_d) < missval_tol ) data_addr_d[i_szt] = NA_REAL; break; default: error( "unhandled var type when allocating var space in R_nc_get_vara_numvarid"); } /*----------------------------------------- * Set our dims (note: non-degenerate only) *----------------------------------------*/ ndims_cgt1 = 0; for( i=0; i<ndims; i++ ) if( count[i] > 1 ) ndims_cgt1++; if( ndims_cgt1 == 0 ) { PROTECT( sx_dim = allocVector( INTSXP, 1 )); INTEGER(sx_dim)[0] = 1; } else { PROTECT( sx_dim = allocVector( INTSXP, ndims_cgt1 )); j = 0; for( i=0; i<ndims; i++ ) if( count[i] > 1 ) { INTEGER(sx_dim)[ndims_cgt1-j-1] = count[i]; j++; } } setAttrib( rv_data, R_DimSymbol, sx_dim ); UNPROTECT(2); return(rv_data); }
/*ARGSUSED*/ int main(int argc, char *argv[]) { int cmode=NC_CLOBBER, omode, ret; int id; char buf[256]; #ifdef SYNCDEBUG char *str = "one"; #endif int ii; size_t ui; const struct tcdfvar *tvp = testvars; union getret got; const size_t initialsz = 8192; size_t chunksz = 8192; size_t align = 8192/32; MPI_Init(&argc, &argv); /* cmode |= NC_PNETCDF |NC_64BIT_OFFSET; */ cmode != NC_PNETCDF |NC_64BIT_DATA; ret = nc_create_par(fname,cmode, MPI_COMM_WORLD, MPI_INFO_NULL, &id); if(ret != NC_NOERR) { fprintf(stderr,"Error %s in file %s at line %d\n",nc_strerror(ret),__FILE__,__LINE__); exit(ret); } assert( nc_put_att_text(id, NC_GLOBAL, "TITLE", 12, "another name") == NC_NOERR); assert( nc_get_att_text(id, NC_GLOBAL, "TITLE", buf) == NC_NOERR); /* (void) printf("title 1 \"%s\"\n", buf); */ assert( nc_put_att_text(id, NC_GLOBAL, "TITLE", strlen(fname), fname) == NC_NOERR); assert( nc_get_att_text(id, NC_GLOBAL, "TITLE", buf) == NC_NOERR); buf[strlen(fname)] = 0; /* (void) printf("title 2 \"%s\"\n", buf); */ assert( strcmp(fname, buf) == 0); createtestdims(id, NUM_DIMS, sizes, dim_names); testdims(id, NUM_DIMS, sizes, dim_names); createtestvars(id, testvars, NUM_TESTVARS); { int ifill = -1; double dfill = -9999; assert( nc_put_att_int(id, Long_id, _FillValue, NC_INT, 1, &ifill) == NC_NOERR); assert( nc_put_att_double(id, Double_id, _FillValue, NC_DOUBLE, 1, &dfill) == NC_NOERR); } #ifdef REDEF assert( nc__enddef(id, 0, align, 0, 2*align) == NC_NOERR ); assert( nc_put_var1_int(id, Long_id, indices[3], &birthday) == NC_NOERR ); fill_seq(id); assert( nc_redef(id) == NC_NOERR ); /* assert( nc_rename_dim(id,2, "a long dim name") == NC_NOERR); */ #endif assert( nc_rename_dim(id,1, "IXX") == NC_NOERR); assert( nc_inq_dim(id, 1, buf, &ui) == NC_NOERR); /* (void) printf("dimrename: %s\n", buf); */ assert( nc_rename_dim(id,1, dim_names[1]) == NC_NOERR); #ifdef ATTRX assert( nc_rename_att(id, 1, "UNITS", "units") == NC_NOERR); assert( nc_del_att(id, 4, "FIELDNAM")== NC_NOERR); assert( nc_del_att(id, 2, "SCALEMIN")== NC_NOERR); assert( nc_del_att(id, 2, "SCALEMAX")== NC_NOERR); #endif /* ATTRX */ assert( nc__enddef(id, 0, align, 0, 2*align) == NC_NOERR ); #ifndef REDEF fill_seq(id); assert( nc_put_var1_int(id, Long_id, indices[3], &birthday)== NC_NOERR ); #endif assert( nc_put_vara_schar(id, Byte_id, s_start, s_edges, (signed char *)sentence) == NC_NOERR); assert( nc_put_var1_schar(id, Byte_id, indices[6], (signed char *)(chs+1)) == NC_NOERR); assert( nc_put_var1_schar(id, Byte_id, indices[5], (signed char *)chs) == NC_NOERR); assert( nc_put_vara_text(id, Char_id, s_start, s_edges, sentence) == NC_NOERR); assert( nc_put_var1_text(id, Char_id, indices[6], (chs+1)) == NC_NOERR) ; assert( nc_put_var1_text(id, Char_id, indices[5], chs) == NC_NOERR); assert( nc_put_var1_short(id, Short_id, indices[4], shs) == NC_NOERR); assert( nc_put_var1_float(id, Float_id, indices[2], &e) == NC_NOERR); assert( nc_put_var1_double(id, Double_id, indices[1], &zed) == NC_NOERR); assert( nc_put_var1_double(id, Double_id, indices[0], &pinot) == NC_NOERR); #ifdef SYNCDEBUG (void) printf("Hit Return to sync\n"); gets(str); nc_sync(id,0); (void) printf("Sync done. Hit Return to continue\n"); gets(str); #endif /* SYNCDEBUG */ ret = nc_close(id); /* (void) printf("nc_close ret = %d\n\n", ret); */ /* * read it */ omode = NC_NOWRITE; omode = NC_NOWRITE | NC_PNETCDF; if(ret != NC_NOERR) { (void) printf("Could not open %s: %s\n", fname, nc_strerror(ret)); exit(1); } /* (void) printf("reopen id = %d for filename %s\n", */ /* id, fname); */ /* NC */ /* (void) printf("NC "); */ assert( nc_inq(id, &(cdesc->num_dims), &(cdesc->num_vars), &(cdesc->num_attrs), &(cdesc->xtendim) ) == NC_NOERR); assert((size_t) cdesc->num_dims == num_dims); assert(cdesc->num_attrs == 1); assert(cdesc->num_vars == NUM_TESTVARS); /* (void) printf("done\n"); */ /* GATTR */ /* (void) printf("GATTR "); */ assert( nc_inq_attname(id, NC_GLOBAL, 0, adesc->mnem) == 0); assert(strcmp("TITLE",adesc->mnem) == 0); assert( nc_inq_att(id, NC_GLOBAL, adesc->mnem, &(adesc->type), &(adesc->len))== NC_NOERR); assert( adesc->type == NC_CHAR ); assert( adesc->len == strlen(fname) ); assert( nc_get_att_text(id, NC_GLOBAL, "TITLE", buf)== NC_NOERR); buf[adesc->len] = 0; assert( strcmp(fname, buf) == 0); /* VAR */ /* (void) printf("VAR "); */ assert( cdesc->num_vars == NUM_TESTVARS ); for(ii = 0; ii < cdesc->num_vars; ii++, tvp++ ) { int jj; assert( nc_inq_var(id, ii, vdesc->mnem, &(vdesc->type), &(vdesc->ndims), vdesc->dims, &(vdesc->num_attrs)) == NC_NOERR); if(strcmp(tvp->mnem , vdesc->mnem) != 0) { (void) printf("attr %d mnem mismatch %s, %s\n", ii, tvp->mnem, vdesc->mnem); continue; } if(tvp->type != vdesc->type) { (void) printf("attr %d type mismatch %d, %d\n", ii, (int)tvp->type, (int)vdesc->type); continue; } for(jj = 0; jj < vdesc->ndims; jj++ ) { if(tvp->dims[jj] != vdesc->dims[jj] ) { (void) printf( "inconsistent dim[%d] for variable %d: %d != %d\n", jj, ii, tvp->dims[jj], vdesc->dims[jj] ); continue; } } /* VATTR */ /* (void) printf("VATTR\n"); */ for(jj=0; jj<vdesc->num_attrs; jj++ ) { assert( nc_inq_attname(id, ii, jj, adesc->mnem) == NC_NOERR); if( strcmp(adesc->mnem, reqattr[jj]) != 0 ) { (void) printf("var %d attr %d mismatch %s != %s\n", ii, jj, adesc->mnem, reqattr[jj] ); break; } } if( nc_inq_att(id, ii, reqattr[0], &(adesc->type), &(adesc->len)) != -1) { assert( adesc->type == NC_CHAR ); assert( adesc->len == strlen(tvp->units) ); assert( nc_get_att_text(id,ii,reqattr[0],buf)== NC_NOERR); buf[adesc->len] = 0; assert( strcmp(tvp->units, buf) == 0); } if( nc_inq_att(id, ii, reqattr[1], &(adesc->type), &(adesc->len)) != -1) { assert( adesc->type == NC_DOUBLE ); assert( adesc->len == 1 ); assert( nc_get_att_double(id, ii, reqattr[1], &got.dbl)== NC_NOERR); chkgot(adesc->type, got, tvp->validmin); } if( nc_inq_att(id, ii, reqattr[2], &(adesc->type), &(adesc->len)) != -1) { assert( adesc->type == NC_DOUBLE ); assert( adesc->len == 1 ); assert( nc_get_att_double(id, ii, reqattr[2], &got.dbl)== NC_NOERR); chkgot(adesc->type, got, tvp->validmax); } if( nc_inq_att(id, ii, reqattr[3], &(adesc->type), &(adesc->len)) != -1) { assert( adesc->type == NC_DOUBLE ); assert( adesc->len ==1 ); assert( nc_get_att_double(id, ii, reqattr[3], &got.dbl)== NC_NOERR); chkgot(adesc->type, got, tvp->scalemin); } if( nc_inq_att(id, ii, reqattr[4], &(adesc->type), &(adesc->len)) != -1) { assert( adesc->type == NC_DOUBLE ); assert( adesc->len == 1 ); assert( nc_get_att_double(id, ii, reqattr[4], &got.dbl)== NC_NOERR); chkgot(adesc->type, got, tvp->scalemax); } if( nc_inq_att(id, ii, reqattr[5], &(adesc->type), &(adesc->len))== NC_NOERR) { assert( adesc->type == NC_CHAR ); assert( adesc->len == strlen(tvp->fieldnam) ); assert( nc_get_att_text(id,ii,reqattr[5],buf)== NC_NOERR); buf[adesc->len] = 0; assert( strcmp(tvp->fieldnam, buf) == 0); } } /* (void) printf("fill_seq "); */ check_fill_seq(id); /* (void) printf("Done\n"); */ assert( nc_get_var1_double(id, Double_id, indices[0], &got.dbl)== NC_NOERR); /* (void) printf("got val = %f\n", got.dbl ); */ assert( nc_get_var1_double(id, Double_id, indices[1], &got.dbl)== NC_NOERR); /* (void) printf("got val = %f\n", got.dbl ); */ assert( nc_get_var1_float(id, Float_id, indices[2], &got.fl[0])== NC_NOERR); /* (void) printf("got val = %f\n", got.fl[0] ); */ assert( nc_get_var1_int(id, Long_id, indices[3], &got.in[0])== NC_NOERR); /* (void) printf("got val = %d\n", got.in[0] ); */ assert( nc_get_var1_short(id, Short_id, indices[4], &got.sh[0])== NC_NOERR); /* (void) printf("got val = %d\n", got.sh[0] ); */ assert( nc_get_var1_text(id, Char_id, indices[5], &got.by[0]) == NC_NOERR); /* (void) printf("got NC_CHAR val = %c (0x%02x) \n", */ /* got.by[0] , got.by[0]); */ assert( nc_get_var1_text(id, Char_id, indices[6], &got.by[0]) == NC_NOERR); /* (void) printf("got NC_CHAR val = %c (0x%02x) \n", */ /* got.by[0], got.by[0] ); */ (void) memset(buf,0,sizeof(buf)); assert( nc_get_vara_text(id, Char_id, s_start, s_edges, buf) == NC_NOERR); /* (void) printf("got NC_CHAR val = \"%s\"\n", buf); */ assert( nc_get_var1_schar(id, Byte_id, indices[5], (signed char *)&got.by[0])== NC_NOERR); /* (void) printf("got val = %c (0x%02x) \n", got.by[0] , got.by[0]); */ assert( nc_get_var1_schar(id, Byte_id, indices[6], (signed char *)&got.by[0])== NC_NOERR); /* (void) printf("got val = %c (0x%02x) \n", got.by[0], got.by[0] ); */ (void) memset(buf,0,sizeof(buf)); assert( nc_get_vara_schar(id, Byte_id, s_start, s_edges, (signed char *)buf)== NC_NOERR ); /* (void) printf("got val = \"%s\"\n", buf); */ { double dbuf[NUM_RECS * SIZE_1 * SIZE_2]; assert(nc_get_var_double(id, Float_id, dbuf) == NC_NOERR); /* (void) printf("got vals = %f ... %f\n", dbuf[0], */ /* dbuf[NUM_RECS * SIZE_1 * SIZE_2 -1] ); */ } ret = nc_close(id); /* (void) printf("re nc_close ret = %d\n", ret); */ MPI_Finalize(); return 0; }
int NETCDF_setup(coordinateInfo *trajInfo, int *actualAtoms) { #ifdef BINTRAJ int err,spatial,i; netcdfTrajectoryInfo *NCInfo; char *filename; # ifdef MPI MPI_Offset ist; # else size_t ist; # endif if (prnlev>0) fprintf(stdout,"NETCDF_setup(): Setting up %s\n",trajInfo->filename); NCInfo=trajInfo->NCInfo; if (NCInfo == NULL) return 1; filename=trajInfo->filename; /* DAN ROE: For DEBUG of netcdf files, prints what vars are stored */ if (prnlev>3) dan_netcdf_debug(NCInfo->ncid); /* * Get global attributes (after initializing a structure to hold the data), */ trajInfo->title = netcdfGetAttributeText(NCInfo->ncid, NC_GLOBAL, "title"); trajInfo->application = netcdfGetAttributeText(NCInfo->ncid, NC_GLOBAL, "application"); trajInfo->program = netcdfGetAttributeText(NCInfo->ncid, NC_GLOBAL, "program"); trajInfo->version = netcdfGetAttributeText(NCInfo->ncid, NC_GLOBAL, "programVersion"); NCInfo->Conventions = netcdfGetAttributeText(NCInfo->ncid, NC_GLOBAL, "Conventions"); NCInfo->ConventionVersion = netcdfGetAttributeText(NCInfo->ncid, NC_GLOBAL, "ConventionVersion"); if (strstr(NCInfo->Conventions, "AMBER") == NULL) { printfone("WARNING: NetCDF file has Conventions that do not include the string \"AMBER\"\n"); } if (strcmp(NCInfo->ConventionVersion, "1.0") != 0) { printfone("WARNING: NetCDF file has ConventionVersion differing from \"1.0\"\n"); } /* * get the NetCDF dimension ID's and sizes for the frames, spatial and atoms */ NCInfo->frameDID = netcdfGetDimensionInfo(NCInfo->ncid, AMBER_NETCDF_FRAME, &(trajInfo->stop)); NCInfo->spatialDID = netcdfGetDimensionInfo(NCInfo->ncid, AMBER_NETCDF_SPATIAL, &spatial); NCInfo->atomDID = netcdfGetDimensionInfo(NCInfo->ncid, AMBER_NETCDF_ATOM, actualAtoms); if (spatial != 3) { printfone("ptraj cannot handle NetCDF files with other than 3 dims\n"); return 1; } /* * perform a sanity check on time variable and units. * DAN ROE: Should errors here really terminate ptraj? */ err = nc_inq_varid(NCInfo->ncid, AMBER_NETCDF_TIME, &NCInfo->timeVID); if (err != NC_NOERR) { printfone("Error: NetCDF time variable: %s", nc_strerror(err)); return 1; } // error(ROUTINE, "NetCDF time variable, error: %s", nc_strerror(err)); err = nc_inq_varnatts(NCInfo->ncid, NCInfo->timeVID, &i); if ( err != NC_NOERR ) { printfone("Error: Getting number of time attributes in NetCDF file %s\n", filename); return 1; } // error(ROUTINE, "Getting number of time attributes in NetCDF file %s\n", filename); if ( i != 1 ) { printfone("Error: Only one time attribute is expected in NetCDF file %s\n", filename); return 1; } // error(ROUTINE, "Only one time attribute is expected in NetCDF file %s\n", filename); err = nc_inq_attlen(NCInfo->ncid, NCInfo->timeVID, "units", &ist); if (err != NC_NOERR) { printfone("Error: Grabbing time units attribute length in NetCDF file: %s\n", nc_strerror(err)); return 1; } NCInfo->timeUnits = (char *) safe_malloc(sizeof(char) * (ist+1)); err = nc_get_att_text(NCInfo->ncid, NCInfo->timeVID, "units", NCInfo->timeUnits); if (err != NC_NOERR) { printfone("Error: Could not get time units from NetCDF file %s: %s", filename, nc_strerror(err)); safe_free(NCInfo->timeUnits); return 1; } if (strcmp("picosecond",NCInfo->timeUnits) != 0) printfone("WARNING: Expecting time units in picoseconds, got -%s-\n", NCInfo->timeUnits); err = nc_inq_varid(NCInfo->ncid, AMBER_NETCDF_SPATIAL, &NCInfo->spatialVID); if (err != NC_NOERR) { printfone("Error: Getting spatialVID in the NetCDF file %s: %s\n", filename, nc_strerror(err)); return 1; } /* * NETCDF: check to see what trajectory data is within the NetCDF file * and perform sanity checks... * * ARE COORDINATES PRESENT? */ err = nc_inq_varid(NCInfo->ncid, AMBER_NETCDF_COORDS, &NCInfo->coordinateVID); if (err != NC_NOERR) { printfone("Error: No coordinates are present in the NetCDF file %s\n", filename); return 1; } err = nc_inq_varnatts(NCInfo->ncid, NCInfo->coordinateVID, &i); if ( err != NC_NOERR ) { printfone("Error: Getting number of coordinate attributes in NetCDF file %s\n", filename); return 1; } if ( i != 1 ) { printfone("Error: Only a single coordinate attribute is expected in NetCDF file %s\n", filename); return 1; } err = nc_inq_attlen(NCInfo->ncid, NCInfo->coordinateVID, "units", &ist); if (err != NC_NOERR) { printfone("Error: Getting coordinateVID attribute length. %s\n",nc_strerror(err)); return 1; } NCInfo->coordinateUnits = (char *) safe_malloc(sizeof(char) * (ist+1)); err = nc_get_att_text(NCInfo->ncid, NCInfo->coordinateVID, "units", NCInfo->coordinateUnits); if (err != NC_NOERR) { printfone("Error: Could not get coordinate units from NetCDF file %s", filename); safe_free(NCInfo->coordinateUnits); return 1; } if (strcmp("angstrom",NCInfo->coordinateUnits) != 0) printfone("WARNING: Expecting coordinate units in angstroms, got %s\n", NCInfo->coordinateUnits); /* * ARE CELL_LENGTHS (i.e. box info) PRESENT? */ err = nc_inq_varid(NCInfo->ncid, "cell_angles", &NCInfo->cellAngleVID); if ((err != NC_NOERR)&&(prnlev>0)) printfone("Warning: NetCDF cell angle variable ID: %s\n", nc_strerror(err)); err = nc_inq_varid(NCInfo->ncid, "cell_lengths", &NCInfo->cellLengthVID); if ((err != NC_NOERR)&&(prnlev>0)) printfone("Warning: NetCDF cell length variable ID: %s\n", nc_strerror(err)); // Set up box information if (err == NC_NOERR) { // Angle information err = nc_inq_varnatts(NCInfo->ncid, NCInfo->cellAngleVID, &i); if ( i > 0 ) { err = nc_inq_attlen(NCInfo->ncid, NCInfo->cellAngleVID, "units", &ist); if (err == NC_NOERR) { NCInfo->cellAngleUnits = (char *) safe_malloc(sizeof(char) * (ist+1)); err=nc_get_att_text(NCInfo->ncid, NCInfo->cellAngleVID, "units", NCInfo->cellAngleUnits); } } // Cell length information err = nc_inq_varnatts(NCInfo->ncid, NCInfo->cellLengthVID, &i); if ( i > 0 ) { err = nc_inq_attlen(NCInfo->ncid, NCInfo->cellLengthVID, "units", &ist); if (err == NC_NOERR) { NCInfo->cellLengthUnits = (char *) safe_malloc(sizeof(char) * (ist+1)); err=nc_get_att_text(NCInfo->ncid, NCInfo->cellLengthVID, "units", NCInfo->cellLengthUnits); } } trajInfo->isBox = 1; } // End box information setup /* * ARE VELOCITIES PRESENT? */ err = nc_inq_varid(NCInfo->ncid, "velocities", &NCInfo->velocityVID); if (err == NC_NOERR) { trajInfo->isVelocity = 1; err = nc_inq_varnatts(NCInfo->ncid, NCInfo->velocityVID, &i); if ( i > 1 ) { err = nc_inq_attlen(NCInfo->ncid, NCInfo->velocityVID, "units", &ist); if (err == NC_NOERR) { NCInfo->velocityUnits = (char *) safe_malloc(sizeof(char) * (ist+1)); err = nc_get_att_text(NCInfo->ncid, NCInfo->velocityVID, "units", NCInfo->velocityUnits); } err = nc_get_att_double(NCInfo->ncid, NCInfo->velocityVID, "scale_factor", &NCInfo->velocityScale); } } /* * Are replica temperatures present? */ err= nc_inq_varid(NCInfo->ncid,"temp0",&NCInfo->TempVarID); if (err == NC_NOERR) { if (prnlev>0) printfone("\nNetCDF file has replica temperatures.\n"); } else { if (prnlev>0) printfone("\nNetCDF file does not have replica temperatures.\n"); NCInfo->TempVarID=-1; } return 0; #endif //BINTRAJ return 1; }
NCstate NCdsHandleGContDefine(NCdsHandleGCont_t *gCont, int *ncids, size_t n) { int status, varid, i; int missingInt, fillInt; double missingFloat, fillFloat, scale, offset; size_t unitlen, row, col; char unitstr[NC_MAX_NAME], gunitstr[NC_MAX_NAME]; gCont->Data = (double *) NULL; gCont->AuxData = (double *) NULL; gCont->ObsNum = (size_t *) NULL; gCont->MeanIds = gCont->MinIds = gCont->MaxIds = gCont->StdIds = (int *) NULL; if (n < 1) return (NCfailed); if (NCdsHandleGridDefine((NCdsHandleGrid_t *) gCont, ncids, n) == NCfailed) return (NCfailed); if (gCont->DataType != NCtypeGCont) { CMmsgPrint(CMmsgAppError, "Invalid grid data in: %s %d", __FILE__, __LINE__); NCdsHandleGridClear((NCdsHandleGrid_t *) gCont); return (NCfailed); } if (((gCont->MeanIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) || ((gCont->MinIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) || ((gCont->MaxIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) || ((gCont->StdIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) || ((gCont->Data = (double *) calloc(gCont->ColNum * gCont->RowNum, sizeof(double))) == (double *) NULL) || ((gCont->AuxData = (double *) calloc(gCont->ColNum * gCont->RowNum, sizeof(double))) == (double *) NULL) || ((gCont->ObsNum = (size_t *) calloc(gCont->ColNum * gCont->RowNum, sizeof(size_t))) == (size_t *) NULL)) { CMmsgPrint(CMmsgSysError, "Memory allocation error in: %s %d", __FILE__, __LINE__); if (gCont->MeanIds != (int *) NULL) free(gCont->MeanIds); if (gCont->MinIds != (int *) NULL) free(gCont->MinIds); if (gCont->MaxIds != (int *) NULL) free(gCont->MaxIds); if (gCont->StdIds != (int *) NULL) free(gCont->StdIds); NCdsHandleGridClear((NCdsHandleGrid_t *) gCont); return (NCfailed); } for (i = 0; i < n; ++i) gCont->MeanIds[i] = gCont->MinIds[i] = gCont->MaxIds[i] = gCont->StdIds[i] = NCundefined; for (i = 0; i < n; ++i) { switch (gCont->GType) { default: gCont->FillValue.Float = gCont->MissingVal.Float = FLOAT_NOVALUE; break; case NC_BYTE: case NC_SHORT: case NC_INT: if ((status = nc_get_att_int(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAFillValue, &fillInt)) != NC_NOERR) { if ((status = nc_get_att_int(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal, &missingInt)) != NC_NOERR) missingInt = fillInt = INT_NOVALUE; else fillInt = missingInt; } else if ((status = nc_get_att_int(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal, &missingInt)) != NC_NOERR) missingInt = fillInt; break; case NC_FLOAT: case NC_DOUBLE: if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAFillValue, &fillFloat)) != NC_NOERR) { if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal, &missingFloat)) != NC_NOERR) missingFloat = fillFloat = FLOAT_NOVALUE; else fillFloat = missingFloat; } else if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal, &missingFloat)) != NC_NOERR) missingFloat = fillFloat; break; } if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAScaleFactor, &scale)) != NC_NOERR) scale = 1.0; if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAAddOffset, &offset)) != NC_NOERR) offset = 0.0; if (((status = nc_inq_attlen(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAUnits, &unitlen)) == NC_NOERR) && ((status = nc_get_att_text(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAUnits, unitstr)) == NC_NOERR)) unitstr[unitlen] = '\0'; if (i == 0) { if ((status == NC_NOERR) && (utScan(unitstr, &(gCont->GUnit)) == 0)) { gCont->DoGUnit = true; strcpy (gunitstr, unitstr); } else gCont->DoGUnit = false; switch (gCont->GType) { case NC_BYTE: case NC_SHORT: case NC_INT: gCont->FillValue.Int = fillInt; gCont->MissingVal.Int = missingInt; break; default: case NC_FLOAT: case NC_DOUBLE: gCont->FillValue.Float = fillFloat; gCont->MissingVal.Float = missingFloat; break; } gCont->Scale = scale; gCont->Offset = offset; } else { if (gCont->DoGUnit && ((status != NC_NOERR) || strcmp(unitstr, gunitstr) != 0)) { CMmsgPrint(CMmsgAppError, "Inconsistent data bundle (units) in: %s %d", __FILE__, __LINE__); return (NCfailed); } switch (gCont->GType) { case NC_BYTE: case NC_SHORT: case NC_INT: if ((gCont->FillValue.Int != fillInt) || (gCont->MissingVal.Int != missingInt)) { CMmsgPrint(CMmsgAppError, "Inconsistent data bundle (int fill value) in: %s %d", __FILE__, __LINE__); return (NCfailed); } break; default: case NC_FLOAT: case NC_DOUBLE: if ((NCmathEqualValues(gCont->FillValue.Float, fillFloat) == false) || (NCmathEqualValues(gCont->MissingVal.Float, missingFloat) == false)) { CMmsgPrint(CMmsgAppError, "Inconsistent bundle (float fill value) in: %s %d", __FILE__, __LINE__); return (NCfailed); } break; } if ((NCmathEqualValues(gCont->Scale, scale) == false) || (NCmathEqualValues(gCont->Offset, offset) == false)) { CMmsgPrint(CMmsgAppError, "Inconsistent bundle (scale and offset) in: %s %d", __FILE__, __LINE__); return (NCfailed); } } gCont->MeanIds[i] = nc_inq_varid(ncids[i], NCnameVAAverage, &varid) == NC_NOERR ? varid : NCundefined; gCont->MaxIds[i] = nc_inq_varid(ncids[i], NCnameVAMaximum, &varid) == NC_NOERR ? varid : NCundefined; gCont->MinIds[i] = nc_inq_varid(ncids[i], NCnameVAMinimum, &varid) == NC_NOERR ? varid : NCundefined; gCont->StdIds[i] = nc_inq_varid(ncids[i], NCnameVAStdDev, &varid) == NC_NOERR ? varid : NCundefined; } for (row = 0; row < gCont->RowNum; row++) for (col = 0; col < gCont->ColNum; col++) NCdsHandleGContSetFill(gCont, row, col); return (NCsucceeded); }