/* * Put a single character into an open netCDF file. */ static void c_ncvp1c( int ncid, /* netCDF ID */ int varid, /* variable ID */ const size_t* indices,/* multidim index of data to be written */ const char* value, /* pointer to data value to be written */ int* rcode /* returned error code */ ) { int status; nc_type datatype; if ((status = nc_inq_vartype(ncid, varid, &datatype)) == 0) { status = datatype != NC_CHAR ? NC_ECHAR : nc_put_var1_text(ncid, varid, indices, value); } if (status == 0) *rcode = 0; else { nc_advise("NCVP1C", status, ""); *rcode = ncerr; } }
/* * Get a single character data value from a variable of an open * netCDF file. */ static void c_ncvg1c( int ncid, /* netCDF ID */ int varid, /* variable ID */ const size_t* indices,/* multidim index of data to be read */ char* value, /* pointer to data value to be read */ int* rcode /* returned error code */ ) { int status; nc_type datatype; if ((status = nc_inq_vartype(ncid, varid, &datatype)) == 0) { switch (datatype) { case NC_CHAR: status = nc_get_var1_text(ncid, varid, indices, value); break; default: status = NC_ECHAR; break; } } if (status == 0) *rcode = 0; else { nc_advise("NCVG1C", status, ""); *rcode = ncerr; } }
/* Get attributes which define missing data information. If the * attributes are not there, then provide the valid data anyway, based * on netCDF defaults. */ int nccf_inq_var_missing(int ncid, int varid, void *fill_value, void *valid_min, void *valid_max) { nc_type xtype; int ret; if ((ret = nc_inq_vartype(ncid, varid, &xtype))) return ret; /* Does the user want the fill value?*/ if (fill_value) { /* Get the value of the _FillValue att, if it is there. */ ret = nc_get_att(ncid, varid, CF_FILL_VALUE, fill_value); if (ret == NC_ENOTATT) { /* No _FillValue att, so find the default fill value for this * type. */ if ((ret = nccf_get_default_missing(xtype, fill_value, NULL, NULL))) return ret; } else if (ret != NC_NOERR) return ret; } /* Does the user want the fill value?*/ if (valid_min) { /* Get the value of the valid_min, if it is there. */ ret = nc_get_att(ncid, varid, CF_VALID_MIN, valid_min); if (ret == NC_ENOTATT) { /* No _FillValue att, so find the default fill value for this * type. */ if ((ret = nccf_get_default_missing(xtype, NULL, valid_min, NULL))) return ret; } else if (ret != NC_NOERR) return ret; } /* Does the user want the fill value?*/ if (valid_max) { /* Get the value of the _FillValue att, if it is there. */ ret = nc_get_att(ncid, varid, CF_VALID_MAX, valid_max); if (ret == NC_ENOTATT) { /* No _FillValue att, so find the default fill value for this * type. */ if ((ret = nccf_get_default_missing(xtype, NULL, NULL, valid_max))) return ret; } else if (ret != NC_NOERR) return ret; } return NC_NOERR; }
/* Return size of chunk in bytes for a variable varid in a group igrp, or 0 if * layout is contiguous */ static int inq_var_chunksize(int igrp, int varid, size_t* chunksizep) { int stat = NC_NOERR; int ndims; size_t *chunksizes; int dim; int contig = 1; nc_type vartype; size_t value_size; size_t prod; NC_CHECK(nc_inq_vartype(igrp, varid, &vartype)); /* from type, get size in memory needed for each value */ NC_CHECK(nc_inq_type(igrp, vartype, NULL, &value_size)); prod = value_size; NC_CHECK(nc_inq_varndims(igrp, varid, &ndims)); chunksizes = (size_t *) emalloc((ndims + 1) * sizeof(size_t)); if(ndims > 0) { NC_CHECK(nc_inq_var_chunking(igrp, varid, &contig, NULL)); } if(contig == 1) { *chunksizep = 0; } else { NC_CHECK(nc_inq_var_chunking(igrp, varid, &contig, chunksizes)); for(dim = 0; dim < ndims; dim++) { prod *= chunksizes[dim]; } *chunksizep = prod; } free(chunksizes); return stat; }
NcType NcVar::type( void ) const { nc_type typ; NcError::set_err( nc_inq_vartype(the_file->id(), the_id, &typ) ); return (NcType) typ; }
/* Initialize iteration for a variable. Just a wrapper for * nc_blkio_init() that makes the netCDF calls needed to initialize * lower-level iterator. */ int nc_get_iter(int ncid, int varid, size_t bufsize, /* size in bytes of memory buffer */ nciter_t **iterpp /* returned opaque iteration state */) { int stat = NC_NOERR; nciter_t *iterp; nc_type vartype; size_t value_size = 0; /* size in bytes of each variable element */ int ndims; /* number of dimensions for variable */ int *dimids; long long nvalues = 1; int dim; int chunked = 0; /* Caller should free this by calling nc_free_iter(iterp) */ iterp = (nciter_t *) emalloc(sizeof(nciter_t)); memset((void*)iterp,0,sizeof(nciter_t)); /* make sure it is initialized */ NC_CHECK(nc_inq_varndims(ncid, varid, &ndims)); dimids = (int *) emalloc((ndims + 1) * sizeof(int)); iterp->dimsizes = (size_t *) emalloc((ndims + 1) * sizeof(size_t)); iterp->chunksizes = (size_t *) emalloc((ndims + 1) * sizeof(size_t)); NC_CHECK(nc_inq_vardimid (ncid, varid, dimids)); for(dim = 0; dim < ndims; dim++) { size_t len; NC_CHECK(nc_inq_dimlen(ncid, dimids[dim], &len)); nvalues *= len; iterp->dimsizes[dim] = len; } NC_CHECK(nc_inq_vartype(ncid, varid, &vartype)); NC_CHECK(inq_value_size(ncid, vartype, &value_size)); #ifdef USE_NETCDF4 { int contig = 1; if(ndims > 0) { NC_CHECK(nc_inq_var_chunking(ncid, varid, &contig, NULL)); } if(contig == 0) { /* chunked */ NC_CHECK(nc_inq_var_chunking(ncid, varid, &contig, iterp->chunksizes)); chunked = 1; } } #endif /* USE_NETCDF4 */ NC_CHECK(nc_blkio_init(bufsize, value_size, ndims, chunked, iterp)); iterp->to_get = 0; free(dimids); *iterpp = iterp; return stat; }
/**@{*/ int nc_get_vara(int ncid, int varid, const size_t *startp, const size_t *countp, void *ip) { NC* ncp = NULL; nc_type xtype = NC_NAT; int stat = NC_check_id(ncid, &ncp); if(stat != NC_NOERR) return stat; stat = nc_inq_vartype(ncid, varid, &xtype); if(stat != NC_NOERR) return stat; return NC_get_vara(ncid, varid, startp, countp, ip, xtype); }
/**@{*/ int nc_put_vara(int ncid, int varid, const size_t *startp, const size_t *countp, const void *op) { NC* ncp; int stat = NC_check_id(ncid, &ncp); nc_type xtype; if(stat != NC_NOERR) return stat; stat = nc_inq_vartype(ncid, varid, &xtype); if(stat != NC_NOERR) return stat; return NC_put_vara(ncid, varid, startp, countp, op, xtype); }
/* byte_style is 1 for signed, 2 for unsigned */ void R_nc_get_vara_int( int *ncid, int *varid, int *start, int *count, int *byte_style, int *data, int *retval ) { int i, err, ndims; size_t s_start[MAX_NC_DIMS], s_count[MAX_NC_DIMS], tot_size, k; char vn[2048]; nc_type nct; err = nc_inq_varndims(*ncid, *varid, &ndims ); if( err != NC_NOERR ) REprintf( "Error in R_nc_get_vara_int while getting ndims: %s\n", nc_strerror(*retval) ); tot_size = 1L; for( i=0; i<ndims; i++ ) { s_start[i] = (size_t)start[i]; s_count[i] = (size_t)count[i]; tot_size *= s_count[i]; } *retval = nc_get_vara_int(*ncid, *varid, s_start, s_count, data ); if( *retval != NC_NOERR ) { nc_inq_varname( *ncid, *varid, vn ); REprintf( "Error in R_nc_get_vara_int: %s\n", nc_strerror(*retval) ); REprintf( "Var: %s Ndims: %d Start: ", vn, ndims ); for( i=0; i<ndims; i++ ) { REprintf( "%u", (unsigned int)s_start[i] ); if( i < ndims-1 ) REprintf( "," ); } REprintf( "Count: " ); for( i=0; i<ndims; i++ ) { REprintf( "%u", (unsigned int)s_count[i] ); if( i < ndims-1 ) REprintf( "," ); } } *retval = nc_inq_vartype( *ncid, *varid, &nct ); if( nct == NC_BYTE ) { /* netcdf library for reading from byte to int, as we do here, * is SIGNED. So, if user requests signed, we don't have to * do anything; only adjust if user asks for unsigned. */ if( *byte_style == 2 ) { /* unsigned */ for( k=0L; k<tot_size; k++ ) { if( data[k] < 0 ) data[k] += 256; } } } }
void R_nc_inq_vartype( int *ncid, int *varid, int *precint, int *retval ) { nc_type nct; *retval = nc_inq_vartype( *ncid, *varid, &nct ); if( *retval != NC_NOERR ) REprintf( "Error in R_nc_inq_var: %s\n", nc_strerror(*retval) ); *precint = R_nc_nctype_to_Rtypecode(nct); }
/* * Write a hypercube of character values into an open netCDF file. */ static void c_ncvptc( int ncid, /* netCDF ID */ int varid, /* variable ID */ const size_t* start, /* multidimensional index of hypercube corner */ const size_t* count, /* multidimensional hypercube edge lengths */ const char* value, /* block of data values to be written */ int lenstr, /* declared length of the data argument */ int* rcode /* returned error code */ ) { int status; nc_type datatype; if ((status = nc_inq_vartype(ncid, varid, &datatype)) == 0) { if (datatype != NC_CHAR) status = NC_ECHAR; else { int rank; status = nc_inq_varndims(ncid, varid, &rank); if (status == 0) { if (dimprod(count, rank) > (size_t)lenstr) status = NC_ESTS; else status = nc_put_vara_text(ncid, varid, start, count, value); } } } if (status == 0) *rcode = 0; else { nc_advise("NCVPTC", status, ""); *rcode = ncerr; } }
/******************************************************************** nc_type mpp_get_var_type(int fid, int vid) get var type ********************************************************************/ nc_type mpp_get_var_type(int fid, int vid) { char errmsg[512]; nc_type vartype; int status; if(fid<0 || fid >=nfiles) mpp_error("mpp_io(mpp_get_var_ndim): 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_ndim): invalid vid number, vid should be " "a nonnegative integer that less than nvar"); status = nc_inq_vartype(files[fid].ncid, files[fid].var[vid].fldid, &vartype); if(status != NC_NOERR) { sprintf(errmsg, "mpp_io(mpp_get_var_type): Error in getting type of var %s from file %s", files[fid].var[vid].name, files[fid].name ); netcdf_error(errmsg, status); } return vartype; }
/* * Read a hypercube of character values from a netCDF variable. */ static void c_ncvgtc( int ncid, /* netCDF ID */ int varid, /* variable ID */ const size_t* start, /* multidimensional index of hypercube corner */ const size_t* count, /* multidimensional hypercube edge lengths */ char* value, /* block of data values to be read */ int lenstr, /* declared length of the data argument */ int* rcode /* returned error code */ ) { int status; nc_type datatype; if ((status = nc_inq_vartype(ncid, varid, &datatype)) == 0) { if (datatype != NC_CHAR) status = NC_ECHAR; else if ((status = nc_get_vara_text(ncid, varid, start, count, value)) == 0) { int rank; if ((status = nc_inq_varndims(ncid, varid, &rank)) == 0) { size_t total = dimprod(count, rank); (void) memset(value+total, ' ', lenstr - total); } } } if (status == 0) *rcode = 0; else { nc_advise("NCVGTC", status, ""); *rcode = ncerr; } }
/* * Read a generalized hypercube of character values from a netCDF variable * of an open netCDF file. */ static void c_ncvggc( int ncid, /* netCDF ID */ int varid, /* variable ID */ const size_t* start, /* multidimensional index of hypercube corner */ const size_t* count, /* multidimensional hypercube edge lengths */ const ptrdiff_t* strides,/* netCDF variable access strides */ const ptrdiff_t* imap, /* memory values access basis vector */ char* value, /* block of data values to be written */ int* rcode /* returned error code */ ) { int status; int rank; nc_type datatype; if ((status = nc_inq_vartype(ncid, varid, &datatype)) == 0 && (status = nc_inq_varndims(ncid, varid, &rank)) == 0) { switch (datatype) { case NC_CHAR: status = nc_get_varm_text(ncid, varid, start, count, strides, imap, value); break; default: status = NC_ECHAR; break; } } if (status == 0) *rcode = 0; else { nc_advise("NCVGGC", status, ""); *rcode = ncerr; } }
/* * Computes record size (in bytes) of the record variable with a specified * variable id. Returns size as 0 if not a record variable. */ static int ncrecsize(int ncid, int varid, size_t *recsizep) { int status; int recdimid; nc_type type; int ndims; int dimids[MAX_NC_DIMS]; int id; size_t size; *recsizep = 0; status = nc_inq_unlimdim(ncid, &recdimid); if(status != NC_NOERR) return status; status = nc_inq_vartype(ncid, varid, &type); if(status != NC_NOERR) return status; status = nc_inq_varndims(ncid, varid, &ndims); if(status != NC_NOERR) return status; status = nc_inq_vardimid(ncid, varid, dimids); if(status != NC_NOERR) return status; if (ndims == 0 || dimids[0] != recdimid) { return NC_NOERR; } size = nctypelen(type); for (id = 1; id < ndims; id++) { size_t len; status = nc_inq_dimlen(ncid, dimids[id], &len); if(status != NC_NOERR) return status; size *= len; } *recsizep = size; return NC_NOERR; }
/* Set attributes to define missing data information. */ int nccf_def_var_missing(int ncid, int varid, const void *fill_value, const void *valid_min, const void *valid_max) { nc_type xtype; int ret; /* User must provide either both or neither of valid_min and * valid_max. */ if ((valid_min && !valid_max) || (!valid_min && valid_max)) return CF_EMINMAX; /* Get the variable type. */ if ((ret = nc_inq_vartype(ncid, varid, &xtype))) return ret; /* Write a fill value if the user provided one. */ if (fill_value) if ((ret = nc_put_att(ncid, varid, CF_FILL_VALUE, xtype, 1, fill_value))) return ret; /* Write a valid_min if the user provided one. */ if (valid_min) if ((ret = nc_put_att(ncid, varid, CF_VALID_MIN, xtype, 1, valid_min))) return ret; /* Write a valid_max value if the user provided one. */ if (valid_max) if ((ret = nc_put_att(ncid, varid, CF_VALID_MAX, xtype, 1, valid_max))) return ret; return NC_NOERR; }
static NFvarType _NCgridVariableType(NFio_p io, NFvarHandle varHandle) { int status; NCgridVariable_p gridVariable = (NCgridVariable_p) varHandle; nc_type vartype; if ((status = nc_inq_vartype(((NCgrid_p) (io->PluginData))->NCid, gridVariable->VarIDs[0], &vartype)) != NC_NOERR) { CMmsgPrint(CMmsgAppError, "Variable type inquery error in %s:%d!\n", __FILE__, __LINE__); return (NFvarTypeVoid); } switch (vartype) { default: return (NFvarTypeVoid); case NC_CHAR: return (NFvarTypeByte); case NC_SHORT: case NC_INT: return (NFvarTypeShort); case NC_FLOAT: return (NFvarTypeFloat); case NC_DOUBLE: return (NFvarTypeDouble); } return (NFvarTypeVoid); }
/********************************************************************* int mpp_get_varid(int fid, const char *varname) get the id of the varname from file with fid, the id will be the index in files[fid].var. *********************************************************************/ int mpp_get_varid(int fid, const char *varname) { int status, fldid, vid, n; char errmsg[512]; /* First look through existing variables to see if the fldid of varname is already retrieved. */ if(fid<0 || fid >=nfiles) mpp_error("mpp_io(mpp_get_varid): invalid id number, id should be " "a nonnegative integer that less than nfiles"); for(n=0; n<files[fid].nvar; n++) { if( !strcmp(files[fid].var[n].name, varname) ) return n; } vid = files[fid].nvar; files[fid].nvar++; if(files[fid].nvar > MAXVAR ) mpp_error("mpp_io(mpp_get_varid): nvar is larger than MAXVAR, increase MAXVAR"); status = nc_inq_varid(files[fid].ncid, varname, &fldid); if(status != NC_NOERR) { sprintf(errmsg, "mpp_io(mpp_get_varid): error in get field_id of variable %s from file %s", varname, files[fid].name); netcdf_error(errmsg, status); } status = nc_inq_vartype(files[fid].ncid, fldid, &(files[fid].var[vid].type)); if(status != NC_NOERR) { sprintf(errmsg, "mpp_io(mpp_get_varid): Error in getting type of of field %s in file %s ", files[fid].var[vid].name, files[fid].name ); netcdf_error(errmsg, status); } files[fid].var[vid].fldid = fldid; strcpy(files[fid].var[vid].name, varname); return vid; };/* mpp_get_varid */
/* * Write a generalized hypercube of numeric values into a netCDF variable of * an open netCDF file. */ static void c_ncvptg ( int ncid, /* netCDF ID */ int varid, /* variable ID */ const size_t* start, /* multidimensional index of hypercube corner */ const size_t* count, /* multidimensional hypercube edge lengths */ const ptrdiff_t* strides,/* netCDF variable access strides */ const ptrdiff_t* imap, /* memory values access mapping vector */ const void* value, /* block of data values to be written */ int* rcode /* returned error code */ ) { int status; int rank; nc_type datatype; if ((status = nc_inq_vartype(ncid, varid, &datatype)) == 0 && (status = nc_inq_varndims(ncid, varid, &rank)) == 0) { switch (datatype) { case NC_CHAR: status = NC_ECHAR; break; case NC_BYTE: # if NF_INT1_IS_C_SIGNED_CHAR status = nc_put_varm_schar(ncid, varid, start, count, strides, imap, (const signed char*)value); # elif NF_INT1_IS_C_SHORT status = nc_put_varm_short(ncid, varid, start, count, strides, imap, (const short*)value); # elif NF_INT1_IS_C_INT status = nc_put_varm_int(ncid, varid, start, count, strides, imap, (const int*)value); # elif NF_INT1_IS_C_LONG status = nc_put_varm_long(ncid, varid, start, count, strides, imap, (const long*)value); # endif break; case NC_SHORT: # if NF_INT2_IS_C_SHORT status = nc_put_varm_short(ncid, varid, start, count, strides, imap, (const short*)value); # elif NF_INT2_IS_C_INT status = nc_put_varm_int(ncid, varid, start, count, strides, imap, (const int*)value); # elif NF_INT2_IS_C_LONG status = nc_put_varm_long(ncid, varid, start, count, strides, imap, (const long*)value); # endif break; case NC_INT: # if NF_INT_IS_C_INT status = nc_put_varm_int(ncid, varid, start, count, strides, imap, (const int*)value); # elif NF_INT_IS_C_LONG status = nc_put_varm_long(ncid, varid, start, count, strides, imap, (const long*)value); # endif break; case NC_FLOAT: # if NF_REAL_IS_C_FLOAT status = nc_put_varm_float(ncid, varid, start, count, strides, imap, (const float*)value); # elif NF_REAL_IS_C_DOUBLE status = nc_put_varm_double(ncid, varid, start, count, strides, imap, (const double*)value); # endif break; case NC_DOUBLE: # if NF_DOUBLEPRECISION_IS_C_FLOAT status = nc_put_varm_float(ncid, varid, start, count, strides, imap, (const float*)value); # elif NF_DOUBLEPRECISION_IS_C_DOUBLE status = nc_put_varm_double(ncid, varid, start, count, strides, imap, (const double*)value); # endif break; } } if (status == 0) *rcode = 0; else { nc_advise("NCVPTG", status, ""); *rcode = ncerr; } }
/* * Put a single numeric data value into a variable of an open netCDF. */ static void c_ncvpt1 ( int ncid, /* netCDF ID */ int varid, /* variable ID */ const size_t* indices,/* multidim index of data to be written */ const void* value, /* pointer to data value to be written */ int* rcode /* returned error code */ ) { int status; nc_type datatype; if ((status = nc_inq_vartype(ncid, varid, &datatype)) == 0) { switch (datatype) { case NC_CHAR: status = NC_ECHAR; break; case NC_BYTE: # if NF_INT1_IS_C_SIGNED_CHAR status = nc_put_var1_schar(ncid, varid, indices, (const signed char*)value); # elif NF_INT1_IS_C_SHORT status = nc_put_var1_short(ncid, varid, indices, (const short*)value); # elif NF_INT1_IS_C_INT status = nc_put_var1_int(ncid, varid, indices, (const int*)value); # elif NF_INT1_IS_C_LONG status = nc_put_var1_long(ncid, varid, indices, (const long*)value); # endif break; case NC_SHORT: # if NF_INT2_IS_C_SHORT status = nc_put_var1_short(ncid, varid, indices, (const short*)value); # elif NF_INT2_IS_C_INT status = nc_put_var1_int(ncid, varid, indices, (const int*)value); # elif NF_INT2_IS_C_LONG status = nc_put_var1_long(ncid, varid, indices, (const long*)value); # endif break; case NC_INT: # if NF_INT_IS_C_INT status = nc_put_var1_int(ncid, varid, indices, (const int*)value); # elif NF_INT_IS_C_LONG status = nc_put_var1_long(ncid, varid, indices, (const long*)value); # endif break; case NC_FLOAT: # if NF_REAL_IS_C_FLOAT status = nc_put_var1_float(ncid, varid, indices, (const float*)value); # elif NF_REAL_IS_C_DOUBLE status = nc_put_var1_double(ncid, varid, indices, (const double*)value); # endif break; case NC_DOUBLE: # if NF_DOUBLEPRECISION_IS_C_FLOAT status = nc_put_var1_float(ncid, varid, indices, (const float*)value); # elif NF_DOUBLEPRECISION_IS_C_DOUBLE status = nc_put_var1_double(ncid, varid, indices, (const double*)value); # endif break; } } if (status == 0) *rcode = 0; else { nc_advise("NCVPT1", status, ""); *rcode = ncerr; } }
/** * Convert a Version 2 Fortran IMAP vector into a Version 3 C imap vector. */ static ptrdiff_t* f2c_v2imap(int ncid, int varid, const int* fimap, ptrdiff_t* cimap) { int rank; nc_type datatype; if (nc_inq_vartype(ncid, varid, &datatype) || nc_inq_varndims(ncid, varid, &rank) || rank <= 0) { return NULL; } /* else */ if (fimap[0] == 0) { /* * Special Fortran version 2 semantics: use external netCDF variable * structure. */ int dimids[NC_MAX_VAR_DIMS]; int idim; size_t total; if (nc_inq_vardimid(ncid, varid, dimids) != NC_NOERR) return NULL; for (total = 1, idim = rank - 1; idim >= 0; --idim) { size_t length; cimap[idim] = total; if (nc_inq_dimlen(ncid, dimids[idim], &length) != NC_NOERR) return NULL; total *= length; } } else { /* * Regular Fortran version 2 semantics: convert byte counts to * element counts. */ int idim; size_t size; switch (datatype) { case NC_CHAR: size = sizeof(char); break; case NC_BYTE: # if NF_INT1_IS_C_SIGNED_CHAR size = sizeof(signed char); # elif NF_INT1_IS_C_SHORT size = sizeof(short); # elif NF_INT1_IS_C_INT size = sizeof(int); # elif NF_INT1_IS_C_LONG size = sizeof(long); # endif break; case NC_SHORT: # if NF_INT2_IS_C_SHORT size = sizeof(short); # elif NF_INT2_IS_C_INT size = sizeof(int); # elif NF_INT2_IS_C_LONG size = sizeof(long); # endif break; case NC_INT: # if NF_INT_IS_C_INT size = sizeof(int); # elif NF_INT_IS_C_LONG size = sizeof(long); # endif break; case NC_FLOAT: # if NF_REAL_IS_C_FLOAT size = sizeof(float); # elif NF_REAL_IS_C_DOUBLE size = sizeof(double); # endif break; case NC_DOUBLE: # if NF_DOUBLEPRECISION_IS_C_FLOAT size = sizeof(float); # elif NF_DOUBLEPRECISION_IS_C_DOUBLE size = sizeof(double); # endif break; default: return NULL; } for (idim = 0; idim < rank; ++idim) cimap[idim] = fimap[rank - 1 - idim] / size; } return cimap; }
/* * Read a hypercube of numeric values from a netCDF variable of an open * netCDF file. */ static void c_ncvgt( int ncid, /* netCDF ID */ int varid, /* variable ID */ const size_t* start, /* multidimensional index of hypercube corner */ const size_t* count, /* multidimensional hypercube edge lengths */ void* value, /* block of data values to be read */ int* rcode /* returned error code */ ) { int status; nc_type datatype; if ((status = nc_inq_vartype(ncid, varid, &datatype)) == 0) { switch (datatype) { case NC_CHAR: status = NC_ECHAR; break; case NC_BYTE: # if NF_INT1_IS_C_SIGNED_CHAR status = nc_get_vara_schar(ncid, varid, start, count, (signed char*)value); # elif NF_INT1_IS_C_SHORT status = nc_get_vara_short(ncid, varid, start, count, (short*)value); # elif NF_INT1_IS_C_INT status = nc_get_vara_int(ncid, varid, start, count, (int*)value); # elif NF_INT1_IS_C_LONG status = nc_get_vara_long(ncid, varid, start, count, (long*)value); # endif break; case NC_SHORT: # if NF_INT2_IS_C_SHORT status = nc_get_vara_short(ncid, varid, start, count, (short*)value); # elif NF_INT2_IS_C_INT status = nc_get_vara_int(ncid, varid, start, count, (int*)value); # elif NF_INT2_IS_C_LONG status = nc_get_vara_long(ncid, varid, start, count, (long*)value); # endif break; case NC_INT: # if NF_INT_IS_C_INT status = nc_get_vara_int(ncid, varid, start, count, (int*)value); # elif NF_INT_IS_C_LONG status = nc_get_vara_long(ncid, varid, start, count, (long*)value); # endif break; case NC_FLOAT: # if NF_REAL_IS_C_FLOAT status = nc_get_vara_float(ncid, varid, start, count, (float*)value); # elif NF_REAL_IS_C_DOUBLE status = nc_get_vara_double(ncid, varid, start, count, (double*)value); # endif break; case NC_DOUBLE: # if NF_DOUBLEPRECISION_IS_C_FLOAT status = nc_get_vara_float(ncid, varid, start, count, (float*)value); # elif NF_DOUBLEPRECISION_IS_C_DOUBLE status = nc_get_vara_double(ncid, varid, start, count, (double*)value); # endif break; } } if (status == 0) *rcode = 0; else { nc_advise("NCVGT", status, ""); *rcode = ncerr; } }
int main(int argc, char **argv) { #ifdef USE_PARALLEL MPI_Init(&argc, &argv); #endif int ncid, dimids[3]; int char_varid, byte_varid, ubyte_varid, short_varid, int_varid, float_varid, double_varid; int ushort_varid, uint_varid, int64_varid, uint64_varid; int i, j; unsigned char ubyte_out[DIM1_LEN][DIM2_LEN] = {{1, 128, 255},{1, 128, 255}}; signed char byte_in[DIM1_LEN][DIM2_LEN], byte_out[DIM1_LEN][DIM2_LEN] = {{-127, 1, 127},{-127, 1, 127}}; unsigned short ushort_out[DIM1_LEN][DIM2_LEN] = {{110, 128, 255},{110, 128, 255}}; short short_in[DIM1_LEN][DIM2_LEN], short_out[DIM1_LEN][DIM2_LEN] = {{-110, -128, 255},{-110, -128, 255}}; int int_in[DIM1_LEN][DIM2_LEN], int_out[DIM1_LEN][DIM2_LEN] = {{0, 128, 255},{0, 128, 255}}; float float_in[DIM1_LEN][DIM2_LEN], float_out[DIM1_LEN][DIM2_LEN] = {{-.1, 9999.99, 100.001},{-.1, 9999.99, 100.001}}; double double_in[DIM1_LEN][DIM2_LEN], double_out[DIM1_LEN][DIM2_LEN] = {{0.02, .1128, 1090.1},{0.02, .1128, 1090.1}}; unsigned int uint_in[DIM1_LEN][DIM2_LEN], uint_out[DIM1_LEN][DIM2_LEN] = {{0, 128, 255},{0, 128, 255}}; long long int64_in[DIM1_LEN][DIM2_LEN], int64_out[DIM1_LEN][DIM2_LEN] = {{-111, 777, 100},{-111, 777, 100}}; unsigned long long uint64_in[DIM1_LEN][DIM2_LEN]; unsigned long long uint64_out[DIM1_LEN][DIM2_LEN] = {{0, 10101, 9999999},{0, 10101, 9999999}}; char char_out[DIM1_LEN][DIM2_LEN][DIM3_LEN] = {{"lalala", "lololo", "lelele"}, {"lalala", "lololo", "lelele"}}; /*nc_set_log_level(4);*/ printf("\n*** Testing netcdf-4 variable functions.\n"); printf("*** testing netcdf-4 varids inq on netcdf-3 file..."); { int nvars_in, varids_in[2]; /* Create a netcdf-3 file with one dim and two vars. */ if (nc_create(FILE_NAME, 0, &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_dim(ncid, DIM3_NAME, DIM3_LEN, &dimids[2])) ERR; if (nc_def_var(ncid, VAR_BYTE_NAME, NC_BYTE, 2, dimids, &byte_varid)) ERR; if (nc_def_var(ncid, VAR_CHAR_NAME, NC_CHAR, 3, dimids, &char_varid)) ERR; if (nc_close(ncid)) ERR; /* Open the file and make sure nc_inq_varids yeilds correct * result. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR; if (nvars_in != 2 || varids_in[0] != 0 || varids_in[1] != 1) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing simple variables..."); { /* Create a file with a variable 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_dim(ncid, DIM3_NAME, DIM3_LEN, &dimids[2])) ERR; if (nc_def_var(ncid, VAR_BYTE_NAME, NC_BYTE, 2, dimids, &byte_varid)) ERR; if (nc_def_var(ncid, VAR_CHAR_NAME, NC_CHAR, 3, dimids, &char_varid)) ERR; if (nc_def_var(ncid, VAR_SHORT_NAME, NC_SHORT, 2, dimids, &short_varid)) ERR; if (nc_def_var(ncid, VAR_INT_NAME, NC_INT, 2, dimids, &int_varid)) ERR; if (nc_def_var(ncid, VAR_FLOAT_NAME, NC_FLOAT, 2, dimids, &float_varid)) ERR; if (nc_def_var(ncid, VAR_DOUBLE_NAME, NC_DOUBLE, 2, dimids, &double_varid)) ERR; if (nc_def_var(ncid, VAR_UBYTE_NAME, NC_UBYTE, 2, dimids, &ubyte_varid)) ERR; if (nc_def_var(ncid, VAR_USHORT_NAME, NC_USHORT, 2, dimids, &ushort_varid)) ERR; if (nc_def_var(ncid, VAR_UINT_NAME, NC_UINT, 2, dimids, &uint_varid)) ERR; if (nc_def_var(ncid, VAR_INT64_NAME, NC_INT64, 2, dimids, &int64_varid)) ERR; if (nc_def_var(ncid, VAR_UINT64_NAME, NC_UINT64, 2, dimids, &uint64_varid)) ERR; if (nc_put_var_schar(ncid, byte_varid, (signed char *)byte_out)) ERR; if (nc_put_var_text(ncid, char_varid, (char *)char_out)) ERR; if (nc_put_var_short(ncid, short_varid, (short *)short_out)) ERR; if (nc_put_var_int(ncid, int_varid, (int *)int_out)) ERR; if (nc_put_var_float(ncid, float_varid, (float *)float_out)) ERR; if (nc_put_var_double(ncid, double_varid, (double *)double_out)) ERR; if (nc_put_var_ubyte(ncid, ubyte_varid, (unsigned char *)ubyte_out)) ERR; if (nc_put_var_ushort(ncid, ushort_varid, (unsigned short *)ushort_out)) ERR; if (nc_put_var_uint(ncid, uint_varid, (unsigned int *)uint_out)) ERR; if (nc_put_var_longlong(ncid, int64_varid, (long long *)int64_out)) ERR; if (nc_put_var_ulonglong(ncid, uint64_varid, (unsigned long long *)uint64_out)) ERR; if (nc_close(ncid)) ERR; /* Open the file and check metadata. */ { nc_type xtype_in; int ndims_in, dimids_in[10], natts_in, varid_in; char name_in[NC_MAX_NAME+1]; if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, VAR_BYTE_NAME) || xtype_in != NC_BYTE || ndims_in != 2 || natts_in != 0 || dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR; if (nc_inq_varid(ncid, VAR_BYTE_NAME, &varid_in)) ERR; if (varid_in != 0) ERR; if (nc_inq_varid(ncid, VAR_CHAR_NAME, &varid_in)) ERR; if (varid_in != 1) ERR; if (nc_inq_varid(ncid, VAR_SHORT_NAME, &varid_in)) ERR; if (varid_in != 2) ERR; if (nc_inq_varname(ncid, 0, name_in)) ERR; if (strcmp(name_in, VAR_BYTE_NAME)) ERR; if (nc_inq_varname(ncid, 1, name_in)) ERR; if (strcmp(name_in, VAR_CHAR_NAME)) ERR; if (nc_inq_varname(ncid, 2, name_in)) ERR; if (strcmp(name_in, VAR_SHORT_NAME)) ERR; if (nc_inq_vartype(ncid, 0, &xtype_in)) ERR; if (xtype_in != NC_BYTE) ERR; if (nc_inq_vartype(ncid, 1, &xtype_in)) ERR; if (xtype_in != NC_CHAR) ERR; if (nc_inq_vartype(ncid, 2, &xtype_in)) ERR; if (xtype_in != NC_SHORT) ERR; if (nc_close(ncid)) ERR; } /* Open the file and check data. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_get_var_schar(ncid, byte_varid, (signed char *)byte_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != byte_out[i][j]) ERR; if (nc_get_var_short(ncid, short_varid, (short *)short_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (short_in[i][j] != short_out[i][j]) ERR; if (nc_get_var_int(ncid, int_varid, (int *)int_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (int_in[i][j] != int_out[i][j]) ERR; if (nc_get_var_float(ncid, float_varid, (float *)float_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (float_in[i][j] != float_out[i][j]) ERR; if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != double_out[i][j]) ERR; if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != double_out[i][j]) ERR; if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != double_out[i][j]) ERR; if (nc_get_var_uint(ncid, uint_varid, (unsigned int *)uint_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (uint_in[i][j] != uint_out[i][j]) ERR; if (nc_get_var_longlong(ncid, int64_varid, (long long *)int64_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (int64_in[i][j] != int64_out[i][j]) ERR; if (nc_get_var_ulonglong(ncid, uint64_varid, (unsigned long long *)uint64_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (uint64_in[i][j] != uint64_out[i][j]) ERR; if (nc_close(ncid)) ERR; /* Open the file and read everything as double. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_get_var_double(ncid, byte_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != (double)byte_out[i][j]) ERR; if (nc_get_var_double(ncid, ubyte_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != (double)ubyte_out[i][j]) ERR; if (nc_get_var_double(ncid, short_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != (double)short_out[i][j]) ERR; if (nc_get_var_double(ncid, ushort_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != (double)ushort_out[i][j]) ERR; if (nc_get_var_double(ncid, int_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != (double)int_out[i][j]) ERR; if (nc_get_var_double(ncid, uint_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != (double)uint_out[i][j]) ERR; if (nc_get_var_double(ncid, float_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != (double)float_out[i][j]) ERR; if (nc_get_var_double(ncid, int64_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != (double)int64_out[i][j]) ERR; if (nc_get_var_double(ncid, uint64_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != (double)uint64_out[i][j]) ERR; if (nc_close(ncid)) ERR; /* Open the file and read everything as NC_BYTE. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_get_var_schar(ncid, byte_varid, (signed char *)byte_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != (signed char)byte_out[i][j]) ERR; if (nc_get_var_schar(ncid, ubyte_varid, (signed char *)byte_in) != NC_ERANGE) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != (signed char)ubyte_out[i][j]) ERR; if (nc_get_var_schar(ncid, short_varid, (signed char *)byte_in) != NC_ERANGE) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != (signed char)short_out[i][j]) ERR; if (nc_get_var_schar(ncid, ushort_varid, (signed char *)byte_in) != NC_ERANGE) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != (signed char)ushort_out[i][j]) ERR; if (nc_get_var_schar(ncid, int_varid, (signed char *)byte_in) != NC_ERANGE) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != (signed char)int_out[i][j]) ERR; if (nc_get_var_schar(ncid, uint_varid, (signed char *)byte_in) != NC_ERANGE) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != (signed char)uint_out[i][j]) ERR; if (nc_get_var_schar(ncid, float_varid, (signed char *)byte_in) != NC_ERANGE) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != (signed char)float_out[i][j]) ERR; if (nc_get_var_schar(ncid, int64_varid, (signed char *)byte_in) != NC_ERANGE) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != (signed char)int64_out[i][j]) ERR; if (nc_get_var_schar(ncid, uint64_varid, (signed char *)byte_in) != NC_ERANGE) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != (signed char)uint64_out[i][j]) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; #define DEFLATE_LEVEL_4 4 printf("*** testing simple variables with deflation..."); { /* Create a file with a variable 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_dim(ncid, DIM3_NAME, DIM3_LEN, &dimids[2])) ERR; if (nc_def_var(ncid, VAR_BYTE_NAME, NC_BYTE, 2, dimids, &byte_varid)) ERR; if (nc_def_var_deflate(ncid, byte_varid, 0, 1, DEFLATE_LEVEL_4)) ERR; if (nc_def_var(ncid, VAR_CHAR_NAME, NC_CHAR, 3, dimids, &char_varid)) ERR; if (nc_def_var_deflate(ncid, byte_varid, 0, 1, DEFLATE_LEVEL_4)) ERR; if (nc_def_var(ncid, VAR_SHORT_NAME, NC_SHORT, 2, dimids, &short_varid)) ERR; if (nc_def_var_deflate(ncid, short_varid, 0, 1, DEFLATE_LEVEL_4)) ERR; if (nc_def_var(ncid, VAR_INT_NAME, NC_INT, 2, dimids, &int_varid)) ERR; if (nc_def_var_deflate(ncid, int_varid, 0, 1, DEFLATE_LEVEL_4)) ERR; if (nc_def_var(ncid, VAR_FLOAT_NAME, NC_FLOAT, 2, dimids, &float_varid)) ERR; if (nc_def_var_deflate(ncid, float_varid, 0, 1, DEFLATE_LEVEL_4)) ERR; if (nc_def_var(ncid, VAR_DOUBLE_NAME, NC_DOUBLE, 2, dimids, &double_varid)) ERR; if (nc_def_var_deflate(ncid, double_varid, 0, 1, DEFLATE_LEVEL_4)) ERR; if (nc_def_var(ncid, VAR_UBYTE_NAME, NC_UBYTE, 2, dimids, &ubyte_varid)) ERR; if (nc_def_var_deflate(ncid, ubyte_varid, 0, 1, DEFLATE_LEVEL_4)) ERR; if (nc_def_var(ncid, VAR_USHORT_NAME, NC_USHORT, 2, dimids, &ushort_varid)) ERR; if (nc_def_var_deflate(ncid, ushort_varid, 0, 1, DEFLATE_LEVEL_4)) ERR; if (nc_def_var(ncid, VAR_UINT_NAME, NC_UINT, 2, dimids, &uint_varid)) ERR; if (nc_def_var_deflate(ncid, uint_varid, 0, 1, DEFLATE_LEVEL_4)) ERR; if (nc_def_var(ncid, VAR_INT64_NAME, NC_INT64, 2, dimids, &int64_varid)) ERR; if (nc_def_var_deflate(ncid, int64_varid, 0, 1, DEFLATE_LEVEL_4)) ERR; if (nc_def_var(ncid, VAR_UINT64_NAME, NC_UINT64, 2, dimids, &uint64_varid)) ERR; if (nc_def_var_deflate(ncid, uint64_varid, 0, 1, DEFLATE_LEVEL_4)) ERR; if (nc_put_var_schar(ncid, byte_varid, (signed char *)byte_out)) ERR; if (nc_put_var_text(ncid, char_varid, (char *)char_out)) ERR; if (nc_put_var_short(ncid, short_varid, (short *)short_out)) ERR; if (nc_put_var_int(ncid, int_varid, (int *)int_out)) ERR; if (nc_put_var_float(ncid, float_varid, (float *)float_out)) ERR; if (nc_put_var_double(ncid, double_varid, (double *)double_out)) ERR; if (nc_put_var_ubyte(ncid, ubyte_varid, (unsigned char *)ubyte_out)) ERR; if (nc_put_var_ushort(ncid, ushort_varid, (unsigned short *)ushort_out)) ERR; if (nc_put_var_uint(ncid, uint_varid, (unsigned int *)uint_out)) ERR; if (nc_put_var_longlong(ncid, int64_varid, (long long *)int64_out)) ERR; if (nc_put_var_ulonglong(ncid, uint64_varid, (unsigned long long *)uint64_out)) ERR; if (nc_close(ncid)) ERR; /* Open the file and check metadata. */ { nc_type xtype_in; int ndims_in, dimids_in[10], natts_in, varid_in; char name_in[NC_MAX_NAME+1]; if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, VAR_BYTE_NAME) || xtype_in != NC_BYTE || ndims_in != 2 || natts_in != 0 || dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR; if (nc_inq_varid(ncid, VAR_BYTE_NAME, &varid_in)) ERR; if (varid_in != 0) ERR; if (nc_inq_varid(ncid, VAR_CHAR_NAME, &varid_in)) ERR; if (varid_in != 1) ERR; if (nc_inq_varid(ncid, VAR_SHORT_NAME, &varid_in)) ERR; if (varid_in != 2) ERR; if (nc_inq_varname(ncid, 0, name_in)) ERR; if (strcmp(name_in, VAR_BYTE_NAME)) ERR; if (nc_inq_varname(ncid, 1, name_in)) ERR; if (strcmp(name_in, VAR_CHAR_NAME)) ERR; if (nc_inq_varname(ncid, 2, name_in)) ERR; if (strcmp(name_in, VAR_SHORT_NAME)) ERR; if (nc_inq_vartype(ncid, 0, &xtype_in)) ERR; if (xtype_in != NC_BYTE) ERR; if (nc_inq_vartype(ncid, 1, &xtype_in)) ERR; if (xtype_in != NC_CHAR) ERR; if (nc_inq_vartype(ncid, 2, &xtype_in)) ERR; if (xtype_in != NC_SHORT) ERR; if (nc_close(ncid)) ERR; } /* Open the file and check data. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_get_var_schar(ncid, byte_varid, (signed char *)byte_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != byte_out[i][j]) ERR; if (nc_get_var_short(ncid, short_varid, (short *)short_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (short_in[i][j] != short_out[i][j]) ERR; if (nc_get_var_int(ncid, int_varid, (int *)int_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (int_in[i][j] != int_out[i][j]) ERR; if (nc_get_var_float(ncid, float_varid, (float *)float_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (float_in[i][j] != float_out[i][j]) ERR; if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != double_out[i][j]) ERR; if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != double_out[i][j]) ERR; if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != double_out[i][j]) ERR; if (nc_get_var_uint(ncid, uint_varid, (unsigned int *)uint_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (uint_in[i][j] != uint_out[i][j]) ERR; if (nc_get_var_longlong(ncid, int64_varid, (long long *)int64_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (int64_in[i][j] != int64_out[i][j]) ERR; if (nc_get_var_ulonglong(ncid, uint64_varid, (unsigned long long *)uint64_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (uint64_in[i][j] != uint64_out[i][j]) ERR; if (nc_close(ncid)) ERR; /* Open the file and read everything as double. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_get_var_double(ncid, byte_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != (double)byte_out[i][j]) ERR; if (nc_get_var_double(ncid, ubyte_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != (double)ubyte_out[i][j]) ERR; if (nc_get_var_double(ncid, short_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != (double)short_out[i][j]) ERR; if (nc_get_var_double(ncid, ushort_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != (double)ushort_out[i][j]) ERR; if (nc_get_var_double(ncid, int_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != (double)int_out[i][j]) ERR; if (nc_get_var_double(ncid, uint_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != (double)uint_out[i][j]) ERR; if (nc_get_var_double(ncid, float_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != (double)float_out[i][j]) ERR; if (nc_get_var_double(ncid, int64_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != (double)int64_out[i][j]) ERR; if (nc_get_var_double(ncid, uint64_varid, (double *)double_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (double_in[i][j] != (double)uint64_out[i][j]) ERR; if (nc_close(ncid)) ERR; /* Open the file and read everything as NC_BYTE. */ if (nc_open(FILE_NAME, 0, &ncid)) ERR; if (nc_get_var_schar(ncid, byte_varid, (signed char *)byte_in)) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != (signed char)byte_out[i][j]) ERR; if (nc_get_var_schar(ncid, ubyte_varid, (signed char *)byte_in) != NC_ERANGE) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != (signed char)ubyte_out[i][j]) ERR; if (nc_get_var_schar(ncid, short_varid, (signed char *)byte_in) != NC_ERANGE) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != (signed char)short_out[i][j]) ERR; if (nc_get_var_schar(ncid, ushort_varid, (signed char *)byte_in) != NC_ERANGE) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != (signed char)ushort_out[i][j]) ERR; if (nc_get_var_schar(ncid, int_varid, (signed char *)byte_in) != NC_ERANGE) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != (signed char)int_out[i][j]) ERR; if (nc_get_var_schar(ncid, uint_varid, (signed char *)byte_in) != NC_ERANGE) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != (signed char)uint_out[i][j]) ERR; if (nc_get_var_schar(ncid, float_varid, (signed char *)byte_in) != NC_ERANGE) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != (signed char)float_out[i][j]) ERR; if (nc_get_var_schar(ncid, int64_varid, (signed char *)byte_in) != NC_ERANGE) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != (signed char)int64_out[i][j]) ERR; if (nc_get_var_schar(ncid, uint64_varid, (signed char *)byte_in) != NC_ERANGE) ERR; for (i = 0; i < DIM1_LEN; i++) for (j = 0; j < DIM2_LEN; j++) if (byte_in[i][j] != (signed char)uint64_out[i][j]) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; #define NDIMS4 1 #define NVARS4 1 #define DIM4_NAME "treaty_of_paris_1783" #define DIM4_LEN 5 #define VAR_NAME4 "John_Adams" #define DEFLATE_LEVEL 6 printf("*** testing netcdf-4 simple variable define..."); { int dimids[NDIMS4], dimids_in[NDIMS4]; int varid, varids_in[NVARS4]; int ndims, nvars, natts, unlimdimid; nc_type xtype_in; char name_in[NC_MAX_NAME + 1]; int shuffle_in, deflate_in, deflate_level; /* Create a netcdf-4 file with one dim and one var. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, DIM4_NAME, DIM4_LEN, &dimids[0])) ERR; if (dimids[0] != 0) ERR; if (nc_def_var(ncid, VAR_NAME4, NC_INT64, NDIMS4, dimids, &varid)) ERR; if (nc_def_var_deflate(ncid, varid, 0, 1, DEFLATE_LEVEL)) ERR; if (varid != 0) ERR; /* Check stuff. */ if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != NDIMS4 || nvars != NVARS4 || natts != 0 || unlimdimid != -1) ERR; if (nc_inq_varids(ncid, &nvars, varids_in)) ERR; if (nvars != NVARS4) ERR; if (varids_in[0] != 0) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(name_in, VAR_NAME4) || xtype_in != NC_INT64 || ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR; if (nc_inq_var_deflate(ncid, 0, &shuffle_in, &deflate_in, &deflate_level)) ERR; if (shuffle_in ||!deflate_in || deflate_level != DEFLATE_LEVEL) ERR; if (nc_close(ncid)) ERR; /* Open the file and check the same stuff. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != NDIMS4 || nvars != NVARS4 || natts != 0 || unlimdimid != -1) ERR; if (nc_inq_varids(ncid, &nvars, varids_in)) ERR; if (nvars != NVARS4) ERR; if (varids_in[0] != 0) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(name_in, VAR_NAME4) || xtype_in != NC_INT64 || ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR; if (nc_inq_var_deflate(ncid, 0, &shuffle_in, &deflate_in, &deflate_level)) ERR; if (shuffle_in ||!deflate_in || deflate_level != DEFLATE_LEVEL) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; #define NDIMS5 1 #define NVARS5 5 #define DIM5_NAME "treaty_of_paris_1783" #define DIM5_LEN 5 printf("*** testing netcdf-4 less simple variable define..."); { int dimids[NDIMS5], dimids_in[NDIMS5]; int varid[NVARS5], varids_in[NVARS5]; int ndims, nvars, natts, unlimdimid; nc_type xtype_in; char name_in[NC_MAX_NAME + 1]; char var_name[NVARS5][NC_MAX_NAME + 1] = {"Jean-Pierre_Blanchard", "Madame_Blanchard", "Giffard", "Stanislas_Charles_Henri_Dupuy_de_Lome", "Charles_F_Ritchel"}; int shuffle_in, deflate_in, deflate_level_in; int deflate_level[NVARS5]; int i; /* Set up options for this var. */ for (i = 0; i < NVARS5; i++) deflate_level[i] = i; /* Create a netcdf-4 file with one dim and two vars. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, DIM5_NAME, DIM5_LEN, &dimids[0])) ERR; if (dimids[0] != 0) ERR; for (i = 0; i < NVARS5; i++) { if (nc_def_var(ncid, var_name[i], NC_INT64, NDIMS5, dimids, &varid[i])) ERR; if (varid[i] != i) ERR; if (nc_def_var_deflate(ncid, varid[i], 1, 1, deflate_level[i])) ERR; } /* Check stuff. */ if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != NDIMS5 || nvars != NVARS5 || natts != 0 || unlimdimid != -1) ERR; if (nc_inq_varids(ncid, &nvars, varids_in)) ERR; if (nvars != NVARS5) ERR; for (i = 0; i < NVARS5; i++) { if (varids_in[i] != i) ERR; if (nc_inq_var(ncid, i, name_in, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(name_in, var_name[i]) || xtype_in != NC_INT64 || ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR; if (nc_inq_var_deflate(ncid, varid[i], &shuffle_in, &deflate_in, &deflate_level_in)) ERR; if (!shuffle_in || !deflate_in || deflate_level_in != deflate_level[i]) ERR; } if (nc_close(ncid)) ERR; /* Open the file and check the same stuff. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != NDIMS5 || nvars != NVARS5 || natts != 0 || unlimdimid != -1) ERR; if (nc_inq_varids(ncid, &nvars, varids_in)) ERR; if (nvars != NVARS5) ERR; for (i = 0; i < NVARS5; i++) { if (varids_in[i] != i) ERR; if (nc_inq_var(ncid, i, name_in, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(name_in, var_name[i]) || xtype_in != NC_INT64 || ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR; if (nc_inq_var_deflate(ncid, varid[i], &shuffle_in, &deflate_in, &deflate_level_in)) ERR; if (!shuffle_in || !deflate_in || deflate_level_in != deflate_level[i]) ERR; } if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; #define NVARS 5 #define NDIMS 1 #define DIM6_NAME "airship_cross_sectional_area" #define DIM6_LEN 100 #define TEN_K_M2 10000.0 #define INCREMENT 1000.0 printf("*** testing more complex netcdf-4 variable defines..."); { int dimids[NDIMS], dimids_in[NDIMS]; int varid[NVARS], varids_in[NVARS]; int ndims, nvars, natts, unlimdimid; char var_name[NVARS][50] = {"Jean-Pierre_Blanchard", "Madame_Blanchard", "Giffard", "Stanislas_Charles_Henri_Dupuy_de_Lome", "Charles_F_Ritchel"}; double data[DIM6_LEN]; nc_type xtype_in; char name_in[NC_MAX_NAME + 1]; int shuffle_in, deflate_in, deflate_level_in; int fletcher32_in; int i; /* Create some phoney data. */ for (i = 1, data[0] = TEN_K_M2; i < DIM6_LEN; i++) data[i] = data[i - 1] + INCREMENT; /* Create a netcdf-4 file with one dim and 5 NC_DOUBLE vars. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, DIM6_NAME, DIM6_LEN, &dimids[0])) ERR; for (i = 0; i < NVARS; i++) { if (nc_def_var(ncid, var_name[i], NC_DOUBLE, NDIMS, dimids, &varid[i])) ERR; if (nc_def_var_deflate(ncid, varid[i], 0, 1, 0)) ERR; if (nc_def_var_fletcher32(ncid, varid[i], 1)) ERR; } /* Check stuff. */ if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != NDIMS || nvars != NVARS || natts != 0 || unlimdimid != -1) ERR; if (nc_inq_varids(ncid, &nvars, varids_in)) ERR; if (nvars != NVARS) ERR; for (i = 0; i < NVARS; i++) if (varids_in[i] != i) ERR; for (i = 0; i < NVARS; i++) { if (nc_inq_var(ncid, i, name_in, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(name_in, var_name[i]) || xtype_in != NC_DOUBLE || ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR; if (nc_inq_var_deflate(ncid, varid[i], &shuffle_in, &deflate_in, &deflate_level_in)) ERR; if (shuffle_in || !deflate_in || deflate_level_in != 0) ERR; if (nc_inq_var_fletcher32(ncid, varid[i], &fletcher32_in)) ERR; if (!fletcher32_in) ERR; } if (nc_close(ncid)) ERR; /* Open the file and check the same stuff. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != NDIMS || nvars != NVARS || natts != 0 || unlimdimid != -1) ERR; if (nc_inq_varids(ncid, &nvars, varids_in)) ERR; if (nvars != NVARS) ERR; for (i = 0; i < NVARS; i++) if (varids_in[i] != i) ERR; for (i = 0; i < NVARS; i++) { if (nc_inq_var(ncid, i, name_in, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(name_in, var_name[i]) || xtype_in != NC_DOUBLE || ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR; if (nc_inq_var_deflate(ncid, varid[i], &shuffle_in, &deflate_in, &deflate_level_in)) ERR; if (shuffle_in || !deflate_in || deflate_level_in != 0) ERR; if (nc_inq_var_fletcher32(ncid, varid[i], &fletcher32_in)) ERR; if (!fletcher32_in) ERR; } if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; #define DIM7_LEN 2 #define DIM7_NAME "dim_7_from_Indiana" #define VAR7_NAME "var_7_from_Idaho" #define NDIMS 1 printf("*** testing fill values..."); { int dimids[NDIMS], dimids_in[NDIMS]; size_t index[NDIMS]; int varid, ndims, natts; nc_type xtype_in; char name_in[NC_MAX_NAME + 1]; int shuffle_in, deflate_in, deflate_level_in; int fletcher32_in, no_fill; unsigned short ushort_data = 42, ushort_data_in, fill_value_in; /* Create a netcdf-4 file with one dim and 1 NC_USHORT var. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, DIM7_NAME, DIM7_LEN, &dimids[0])) ERR; if (nc_def_var(ncid, VAR7_NAME, NC_USHORT, NDIMS, dimids, &varid)) ERR; /* Check stuff. */ if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(name_in, VAR7_NAME) || xtype_in != NC_USHORT || ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR; if (nc_inq_var_deflate(ncid, 0, &shuffle_in, &deflate_in, &deflate_level_in)) ERR; if (shuffle_in || deflate_in) ERR; if (nc_inq_var_fletcher32(ncid, 0, &fletcher32_in)) ERR; if (fletcher32_in) ERR; if (nc_inq_var_fill(ncid, 0, &no_fill, &fill_value_in)) ERR; if (no_fill || fill_value_in != NC_FILL_USHORT) ERR; /* Write the second of two values. */ index[0] = 1; if (nc_put_var1_ushort(ncid, 0, index, &ushort_data)) ERR; /* Get the first value, and make sure we get the default fill * value for USHORT. */ index[0] = 0; if (nc_get_var1_ushort(ncid, 0, index, &ushort_data_in)) ERR; if (ushort_data_in != NC_FILL_USHORT) ERR; if (nc_close(ncid)) ERR; /* Open the file and check the same stuff. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; /* Check stuff. */ if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims, dimids_in, &natts)) ERR; if (strcmp(name_in, VAR7_NAME) || xtype_in != NC_USHORT || ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR; if (nc_inq_var_deflate(ncid, 0, &shuffle_in, &deflate_in, &deflate_level_in)) ERR; if (shuffle_in || deflate_in) ERR; if (nc_inq_var_fletcher32(ncid, 0, &fletcher32_in)) ERR; if (fletcher32_in) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing more fill values..."); { int dimids[NDIMS]; size_t index[NDIMS]; int varid; int no_fill; unsigned short ushort_data = 42, ushort_data_in, fill_value_in; /* Create a netcdf-4 file with one dim and 1 NC_USHORT var. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, DIM7_NAME, DIM7_LEN, &dimids[0])) ERR; if (nc_def_var(ncid, VAR7_NAME, NC_USHORT, NDIMS, dimids, &varid)) ERR; if (nc_def_var_fill(ncid, varid, 1, NULL)) ERR; /* Check stuff. */ if (nc_inq_var_fill(ncid, varid, &no_fill, &fill_value_in)) ERR; if (!no_fill) ERR; /* Write the second of two values. */ index[0] = 1; if (nc_put_var1_ushort(ncid, varid, index, &ushort_data)) ERR; /* Get the first value, and make sure we get the default fill * value for USHORT. */ index[0] = 0; if (nc_get_var1_ushort(ncid, varid, index, &ushort_data_in)) ERR; if (nc_close(ncid)) ERR; /* Open the file and check the same stuff. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; /* Check stuff. */ if (nc_inq_var_fill(ncid, varid, &no_fill, &fill_value_in)) ERR; if (!no_fill) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing lots of variables..."); #define DIM_A_NAME "x" #define DIM_A_LEN 10 #define NUM_VARS 2000 #define MAX_VARNAME 10 { /* This simple test failed on HDF5 1.7.58, but passes just fine * on 1.8.0 alpha5... */ int ncid, dimids[1], i; char varname[MAX_VARNAME]; int varids[NUM_VARS]; /* Create a file with three dimensions. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, DIM_A_NAME, DIM_A_LEN, &dimids[0])) ERR; /* Create a large number of variables. */ for (i = 0; i < NUM_VARS; i++) { sprintf(varname, "a_%d", i); if (nc_def_var(ncid, varname, NC_FLOAT, 1, dimids, &varids[i])) ERR; } if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; #define NC3_CLASSIC_FILE "tst_pres_temp_4D_classic.nc" #define NC3_64BIT_OFFSET_FILE "tst_pres_temp_4D_64bit_offset.nc" #define NC3_NETCDF4_FILE "tst_pres_temp_4D_netcdf4.nc" #define NC3_NETCDF4_CLASSIC_FILE "tst_pres_temp_4D_netcdf4_classic.nc" printf("*** testing 4D example file in classic format..."); if (create_4D_example(NC3_CLASSIC_FILE, NC_CLOBBER)) ERR; if (check_4D_example(NC3_CLASSIC_FILE, NC_FORMAT_CLASSIC)) ERR; SUMMARIZE_ERR; printf("*** testing 4D example file in 64-bit offset format..."); if (create_4D_example(NC3_64BIT_OFFSET_FILE, NC_CLOBBER|NC_64BIT_OFFSET)) ERR; if (check_4D_example(NC3_64BIT_OFFSET_FILE, NC_FORMAT_64BIT)) ERR; SUMMARIZE_ERR; printf("*** testing 4D example file in netCDF-4/HDF5 format..."); if (create_4D_example(NC3_NETCDF4_FILE, NC_CLOBBER|NC_NETCDF4)) ERR; if (check_4D_example(NC3_NETCDF4_FILE, NC_FORMAT_NETCDF4)) ERR; SUMMARIZE_ERR; printf("*** testing 4D example file in netCDF-4/HDF5 format with classic model rules..."); if (create_4D_example(NC3_NETCDF4_CLASSIC_FILE, NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL)) ERR; if (check_4D_example(NC3_NETCDF4_CLASSIC_FILE, NC_FORMAT_NETCDF4_CLASSIC)) ERR; SUMMARIZE_ERR; FINAL_RESULTS; #ifdef USE_PARALLEL MPI_Finalize(); #endif }
/*! \internal */ int cpy_var_def(int in_id,int out_id,int rec_dim_id,char *var_nm) /* int in_id: input netCDF input-file ID int out_id: input netCDF output-file ID int rec_dim_id: input input-file record dimension ID char *var_nm: input variable name int cpy_var_def(): output output-file variable ID */ { /* Routine to copy the variable metadata from an input netCDF file * to an output netCDF file. */ int status; int *dim_in_id; int *dim_out_id; int idx; int nbr_dim; int var_in_id; int var_out_id; nc_type var_type; /* See if the requested variable is already in the output file. */ status = nc_inq_varid(out_id, var_nm, &var_out_id); if(status == NC_NOERR) return var_out_id; /* See if the requested variable is in the input file. */ (void)nc_inq_varid(in_id, var_nm, &var_in_id); /* Get the type of the variable and the number of dimensions. */ (void)nc_inq_vartype (in_id, var_in_id, &var_type); (void)nc_inq_varndims(in_id, var_in_id, &nbr_dim); /* Recall: 1. The dimensions must be defined before the variable. 2. The variable must be defined before the attributes. */ /* Allocate space to hold the dimension IDs */ dim_in_id=malloc(nbr_dim*sizeof(int)); dim_out_id=malloc(nbr_dim*sizeof(int)); /* Get the dimension IDs */ (void)nc_inq_vardimid(in_id, var_in_id, dim_in_id); /* Get the dimension sizes and names */ for(idx=0;idx<nbr_dim;idx++){ char dim_nm[NC_MAX_NAME]; size_t dim_sz; (void)nc_inq_dim(in_id, dim_in_id[idx], dim_nm, &dim_sz); /* See if the dimension has already been defined */ status = nc_inq_dimid(out_id, dim_nm, &dim_out_id[idx]); /* If the dimension hasn't been defined, copy it */ if (status != NC_NOERR) { if (dim_in_id[idx] != rec_dim_id) { (void)nc_def_dim(out_id, dim_nm, dim_sz, &dim_out_id[idx]); } else { (void)nc_def_dim(out_id, dim_nm, NC_UNLIMITED, &dim_out_id[idx]); } } } /* Define the variable in the output file */ /* If variable is float or double, define it according to the EXODUS file's IO_word_size */ if ((var_type == NC_FLOAT) || (var_type == NC_DOUBLE)) { (void)nc_def_var(out_id, var_nm, nc_flt_code(out_id), nbr_dim, dim_out_id, &var_out_id); ex_compress_variable(out_id, var_out_id, 2); } else { (void)nc_def_var(out_id, var_nm, var_type, nbr_dim, dim_out_id, &var_out_id); ex_compress_variable(out_id, var_out_id, 1); } /* Free the space holding the dimension IDs */ (void)free(dim_in_id); (void)free(dim_out_id); return var_out_id; } /* end cpy_var_def() */
/** \internal \ingroup variables */ int NCDEFAULT_get_varm(int ncid, int varid, const size_t *start, const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t *imapp, void *value0, nc_type memtype) { int status = NC_NOERR; nc_type vartype = NC_NAT; int varndims,maxidim; NC* ncp; int memtypelen; char* value = (char*)value0; status = NC_check_id (ncid, &ncp); if(status != NC_NOERR) return status; /* if(NC_indef(ncp)) return NC_EINDEFINE; */ status = nc_inq_vartype(ncid, varid, &vartype); if(status != NC_NOERR) return status; /* Check that this is an atomic type */ if(vartype > NC_MAX_ATOMIC_TYPE) return NC_EMAPTYPE; status = nc_inq_varndims(ncid, varid, &varndims); if(status != NC_NOERR) return status; if(memtype == NC_NAT) { memtype = vartype; } if(memtype == NC_CHAR && vartype != NC_CHAR) return NC_ECHAR; else if(memtype != NC_CHAR && vartype == NC_CHAR) return NC_ECHAR; memtypelen = nctypelen(memtype); maxidim = (int) varndims - 1; if (maxidim < 0) { /* * The variable is a scalar; consequently, * there s only one thing to get and only one place to put it. * (Why was I called?) */ size_t edge1[1] = {1}; return NC_get_vara(ncid, varid, start, edge1, value, memtype); } /* * else * The variable is an array. */ { int idim; size_t *mystart = NULL; size_t *myedges; size_t *iocount; /* count vector */ size_t *stop; /* stop indexes */ size_t *length; /* edge lengths in bytes */ ptrdiff_t *mystride; ptrdiff_t *mymap; size_t varshape[NC_MAX_VAR_DIMS]; int isrecvar; size_t numrecs; /* Compute some dimension related values */ isrecvar = NC_is_recvar(ncid,varid,&numrecs); NC_getshape(ncid,varid,varndims,varshape); /* * Verify stride argument; also see if stride is all ones */ if(stride != NULL) { int stride1 = 1; for (idim = 0; idim <= maxidim; ++idim) { if (stride[idim] == 0 /* cast needed for braindead systems with signed size_t */ || ((unsigned long) stride[idim] >= X_INT_MAX)) { return NC_ESTRIDE; } if(stride[idim] != 1) stride1 = 0; } /* If stride1 is true, and there is no imap then call get_vara directly. */ if(stride1 && imapp == NULL) { return NC_get_vara(ncid, varid, start, edges, value, memtype); } } /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */ /* Allocate space for mystart,mystride,mymap etc.all at once */ mystart = (size_t *)calloc((size_t)(varndims * 7), sizeof(ptrdiff_t)); if(mystart == NULL) return NC_ENOMEM; myedges = mystart + varndims; iocount = myedges + varndims; stop = iocount + varndims; length = stop + varndims; mystride = (ptrdiff_t *)(length + varndims); mymap = mystride + varndims; /* * Initialize I/O parameters. */ for (idim = maxidim; idim >= 0; --idim) { mystart[idim] = start != NULL ? start[idim] : 0; if (edges != NULL && edges[idim] == 0) { status = NC_NOERR; /* read/write no data */ goto done; } #ifdef COMPLEX myedges[idim] = edges != NULL ? edges[idim] : idim == 0 && isrecvar ? numrecs - mystart[idim] : varshape[idim] - mystart[idim]; #else if(edges != NULL) myedges[idim] = edges[idim]; else if (idim == 0 && isrecvar) myedges[idim] = numrecs - mystart[idim]; else myedges[idim] = varshape[idim] - mystart[idim]; #endif mystride[idim] = stride != NULL ? stride[idim] : 1; /* Remember: in netCDF-2 imapp is byte oriented, not index oriented * Starting from netCDF-3, imapp is index oriented */ #ifdef COMPLEX mymap[idim] = (imapp != NULL ? imapp[idim] : (idim == maxidim ? 1 : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1])); #else if(imapp != NULL) mymap[idim] = imapp[idim]; else if (idim == maxidim) mymap[idim] = 1; else mymap[idim] = mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; #endif iocount[idim] = 1; length[idim] = ((size_t)mymap[idim]) * myedges[idim]; stop[idim] = (mystart[idim] + myedges[idim] * (size_t)mystride[idim]); } /* * Check start, edges */ for (idim = maxidim; idim >= 0; --idim) { size_t dimlen = idim == 0 && isrecvar ? numrecs : varshape[idim]; if (mystart[idim] >= dimlen) { status = NC_EINVALCOORDS; goto done; } if (mystart[idim] + myedges[idim] > dimlen) { status = NC_EEDGE; goto done; } } /* Lower body */ /* * As an optimization, adjust I/O parameters when the fastest * dimension has unity stride both externally and internally. * In this case, the user could have called a simpler routine * (i.e. ncvar$1() */ if (mystride[maxidim] == 1 && mymap[maxidim] == 1) { iocount[maxidim] = myedges[maxidim]; mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; mymap[maxidim] = (ptrdiff_t) length[maxidim]; } /* * Perform I/O. Exit when done. */ for (;;) { /* TODO: */ int lstatus = NC_get_vara(ncid, varid, mystart, iocount, value, memtype); if (lstatus != NC_NOERR) { if(status == NC_NOERR || lstatus != NC_ERANGE) status = lstatus; } /* * The following code permutes through the variable s * external start-index space and it s internal address * space. At the UPC, this algorithm is commonly * called "odometer code". */ idim = maxidim; carry: value += (((int)mymap[idim]) * memtypelen); mystart[idim] += (size_t)mystride[idim]; if (mystart[idim] == stop[idim]) { size_t l = (length[idim] * (size_t)memtypelen); value -= l; mystart[idim] = start[idim]; if (--idim < 0) break; /* normal return */ goto carry; } } /* I/O loop */ done: free(mystart); } /* variable is array */ return status; }
/*! \internal */ int cpy_var_val(int in_id,int out_id,char *var_nm) /* int in_id: input netCDF input-file ID int out_id: input netCDF output-file ID char *var_nm: input variable name */ { /* Routine to copy the variable data from an input netCDF file * to an output netCDF file. */ int *dim_id; int idx; int nbr_dim; int var_in_id; int var_out_id; size_t *dim_cnt; size_t *dim_sz; size_t *dim_srt; size_t var_sz=1L; nc_type var_type_in, var_type_out; void *void_ptr = NULL; /* Get the var_id for the requested variable from both files. */ (void)nc_inq_varid(in_id, var_nm, &var_in_id); (void)nc_inq_varid(out_id,var_nm, &var_out_id); /* Get the number of dimensions for the variable. */ (void)nc_inq_vartype( out_id, var_out_id, &var_type_out); (void)nc_inq_varndims(out_id, var_out_id, &nbr_dim); (void)nc_inq_vartype( in_id, var_in_id, &var_type_in); (void)nc_inq_varndims(in_id, var_in_id, &nbr_dim); /* Allocate space to hold the dimension IDs */ dim_cnt = malloc(nbr_dim*sizeof(size_t)); dim_id=malloc(nbr_dim*sizeof(int)); dim_sz=malloc(nbr_dim*sizeof(size_t)); dim_srt=malloc(nbr_dim*sizeof(size_t)); /* Get the dimension IDs from the input file */ (void)nc_inq_vardimid(in_id, var_in_id, dim_id); /* Get the dimension sizes and names from the input file */ for(idx=0;idx<nbr_dim;idx++){ /* NB: For the unlimited dimension, ncdiminq() returns the maximum value used so far in writing data for that dimension. Thus if you read the dimension sizes from the output file, then the ncdiminq() returns dim_sz=0 for the unlimited dimension until a variable has been written with that dimension. This is the reason for always reading the input file for the dimension sizes. */ (void)nc_inq_dimlen(in_id,dim_id[idx],dim_cnt+idx); /* Initialize the indicial offset and stride arrays */ dim_srt[idx]=0L; var_sz*=dim_cnt[idx]; } /* end loop over dim */ /* Allocate enough space to hold the variable */ if (var_sz > 0) void_ptr=malloc(var_sz * type_size(var_type_in)); /* Get the variable */ /* if variable is float or double, convert if necessary */ if(nbr_dim==0){ /* variable is a scalar */ if (var_type_in == NC_INT && var_type_out == NC_INT) { nc_get_var1_int(in_id, var_in_id, 0L, void_ptr); nc_put_var1_int(out_id, var_out_id, 0L, void_ptr); } else if (var_type_in == NC_INT64 && var_type_out == NC_INT64) { nc_get_var1_longlong(in_id, var_in_id, 0L, void_ptr); nc_put_var1_longlong(out_id, var_out_id, 0L, void_ptr); } else if (var_type_in == NC_FLOAT) { nc_get_var1_float(in_id, var_in_id, 0L, void_ptr); nc_put_var1_float(out_id, var_out_id, 0L, void_ptr); } else if (var_type_in == NC_DOUBLE) { nc_get_var1_double(in_id, var_in_id, 0L, void_ptr); nc_put_var1_double(out_id, var_out_id, 0L, void_ptr); } else if (var_type_in == NC_CHAR) { nc_get_var1_text(in_id, var_in_id, 0L, void_ptr); nc_put_var1_text(out_id, var_out_id, 0L, void_ptr); } else { assert(1==0); } } else { /* variable is a vector */ if (var_type_in == NC_INT && var_type_out == NC_INT) { (void)nc_get_var_int(in_id, var_in_id, void_ptr); (void)nc_put_var_int(out_id, var_out_id, void_ptr); } else if (var_type_in == NC_INT64 && var_type_out == NC_INT64) { (void)nc_get_var_longlong(in_id, var_in_id, void_ptr); (void)nc_put_var_longlong(out_id, var_out_id, void_ptr); } else if (var_type_in == NC_FLOAT) { (void)nc_get_var_float(in_id, var_in_id, void_ptr); (void)nc_put_var_float(out_id, var_out_id, void_ptr); } else if (var_type_in == NC_DOUBLE) { (void)nc_get_var_double(in_id, var_in_id, void_ptr); (void)nc_put_var_double(out_id, var_out_id, void_ptr); } else if (var_type_in == NC_CHAR) { (void)nc_get_var_text(in_id, var_in_id, void_ptr); (void)nc_put_var_text(out_id, var_out_id, void_ptr); } else { assert(1==0); } } /* end if variable is an array */ /* Free the space that held the dimension IDs */ (void)free(dim_cnt); (void)free(dim_id); (void)free(dim_sz); (void)free(dim_srt); /* Free the space that held the variable */ (void)free(void_ptr); return(EX_NOERR); } /* end cpy_var_val() */
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); }
/*! \internal */ int cpy_coord_val(int in_id,int out_id,char *var_nm, int in_large, int out_large) /* int in_id: input netCDF input-file ID int out_id: input netCDF output-file ID char *var_nm: input variable name */ { /* Routine to copy the coordinate data from an input netCDF file * to an output netCDF file. */ const char *routine = NULL; int temp; size_t i; size_t spatial_dim, num_nodes; size_t start[2], count[2]; nc_type var_type_in, var_type_out; void *void_ptr = NULL; /* Handle easiest situation first: in_large matches out_large */ if (in_large == out_large) return cpy_var_val(in_id, out_id, var_nm); /* At this point, know that in_large != out_large, so will need to either copy a vector to multiple scalars or vice-versa. Also will need a couple dimensions, so get them now.*/ ex_get_dimension(in_id, DIM_NUM_DIM, "dimension", &spatial_dim, &temp, routine); ex_get_dimension(in_id, DIM_NUM_NODES, "nodes", &num_nodes, &temp, routine); if (in_large == 0 && out_large == 1) { /* output file will have coordx, coordy, coordz (if 3d). */ /* Get the var_id for the requested variable from both files. */ int var_in_id, var_out_id[3]; (void)nc_inq_varid(in_id, VAR_COORD, &var_in_id); (void)nc_inq_varid(out_id, VAR_COORD_X, &var_out_id[0]); (void)nc_inq_varid(out_id, VAR_COORD_Y, &var_out_id[1]); (void)nc_inq_varid(out_id, VAR_COORD_Z, &var_out_id[2]); (void)nc_inq_vartype( in_id, var_in_id, &var_type_in); (void)nc_inq_vartype(out_id, var_out_id[0], &var_type_out); if (num_nodes > 0) void_ptr=malloc(num_nodes * type_size(var_type_in)); /* Copy each component of the variable... */ for (i=0; i < spatial_dim; i++) { start[0] = i; start[1] = 0; count[0] = 1; count[1] = num_nodes; if (var_type_in == NC_FLOAT) { nc_get_vara_float(in_id, var_in_id, start, count, void_ptr); nc_put_var_float(out_id, var_out_id[i], void_ptr); } else { assert(var_type_in == NC_DOUBLE); nc_get_vara_double(in_id, var_in_id, start, count, void_ptr); nc_put_var_double(out_id, var_out_id[i], void_ptr); } } } if (in_large == 1 && out_large == 0) { /* input file will have coordx, coordy, coordz (if 3d); output has only "coord" */ int var_in_id[3], var_out_id; (void)nc_inq_varid(in_id, VAR_COORD_X, &var_in_id[0]); (void)nc_inq_varid(in_id, VAR_COORD_Y, &var_in_id[1]); (void)nc_inq_varid(in_id, VAR_COORD_Z, &var_in_id[2]); (void)nc_inq_varid(out_id, VAR_COORD, &var_out_id); (void)nc_inq_vartype(in_id, var_in_id[0], &var_type_in); (void)nc_inq_vartype(out_id, var_out_id, &var_type_out); if (num_nodes > 0) void_ptr=malloc(num_nodes * type_size(var_type_in)); /* Copy each component of the variable... */ for (i=0; i < spatial_dim; i++) { start[0] = i; start[1] = 0; count[0] = 1; count[1] = num_nodes; if (var_type_in == NC_FLOAT) { nc_get_var_float( in_id, var_in_id[i], void_ptr); nc_put_vara_float(out_id, var_out_id, start, count, void_ptr); } else { nc_get_var_double( in_id, var_in_id[i], void_ptr); nc_put_vara_double(out_id, var_out_id, start, count, void_ptr); } } } /* Free the space that held the variable */ (void)free(void_ptr); return(EX_NOERR); } /* end cpy_coord_val() */
/*************************************************************************************** * 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); }
/** \internal \ingroup variables Most dispatch tables will use the default procedures */ int NCDEFAULT_get_vars(int ncid, int varid, const size_t * start, const size_t * edges, const ptrdiff_t * stride, void *value0, nc_type memtype) { #ifdef VARS_USES_VARM NC* ncp; int stat = NC_check_id(ncid, &ncp); if(stat != NC_NOERR) return stat; return ncp->dispatch->get_varm(ncid,varid,start,edges,stride,NULL,value0,memtype); #else /* Rebuilt get_vars code to simplify and avoid use of get_varm */ int status = NC_NOERR; int i,simplestride,isrecvar; int rank; struct GETodometer odom; nc_type vartype = NC_NAT; NC* ncp; int memtypelen; size_t vartypelen; char* value = (char*)value0; size_t numrecs; size_t varshape[NC_MAX_VAR_DIMS]; size_t mystart[NC_MAX_VAR_DIMS]; size_t myedges[NC_MAX_VAR_DIMS]; ptrdiff_t mystride[NC_MAX_VAR_DIMS]; char *memptr = NULL; status = NC_check_id (ncid, &ncp); if(status != NC_NOERR) return status; status = nc_inq_vartype(ncid, varid, &vartype); if(status != NC_NOERR) return status; if(memtype == NC_NAT) memtype = vartype; /* compute the variable type size */ status = nc_inq_type(ncid,vartype,NULL,&vartypelen); if(status != NC_NOERR) return status; if(memtype > NC_MAX_ATOMIC_TYPE) memtypelen = (int)vartypelen; else memtypelen = nctypelen(memtype); /* Check gross internal/external type compatibility */ if(vartype != memtype) { /* If !atomic, the two types must be the same */ if(vartype > NC_MAX_ATOMIC_TYPE || memtype > NC_MAX_ATOMIC_TYPE) return NC_EBADTYPE; /* ok, the types differ but both are atomic */ if(memtype == NC_CHAR || vartype == NC_CHAR) return NC_ECHAR; } /* Get the variable rank */ status = nc_inq_varndims(ncid, varid, &rank); if(status != NC_NOERR) return status; /* Get variable dimension sizes */ isrecvar = NC_is_recvar(ncid,varid,&numrecs); NC_getshape(ncid,varid,rank,varshape); /* Optimize out using various checks */ if (rank == 0) { /* * The variable is a scalar; consequently, * there s only one thing to get and only one place to put it. * (Why was I called?) */ size_t edge1[1] = {1}; return NC_get_vara(ncid, varid, start, edge1, value, memtype); } /* Do various checks and fixups on start/edges/stride */ simplestride = 1; /* assume so */ for(i=0;i<rank;i++) { size_t dimlen; mystart[i] = (start == NULL ? 0 : start[i]); if(edges == NULL) { if(i == 0 && isrecvar) myedges[i] = numrecs - start[i]; else myedges[i] = varshape[i] - mystart[i]; } else myedges[i] = edges[i]; if(myedges[i] == 0) return NC_NOERR; /* cannot read anything */ mystride[i] = (stride == NULL ? 1 : stride[i]); if(mystride[i] <= 0 /* cast needed for braindead systems with signed size_t */ || ((unsigned long) mystride[i] >= X_INT_MAX)) return NC_ESTRIDE; if(mystride[i] != 1) simplestride = 0; /* illegal value checks */ dimlen = (i == 0 && isrecvar ? numrecs : varshape[i]); /* mystart is unsigned, never < 0 */ if(mystart[i] >= dimlen) return NC_EINVALCOORDS; /* myedges is unsigned, never < 0 */ if(mystart[i] + myedges[i] > dimlen) return NC_EEDGE; } if(simplestride) { return NC_get_vara(ncid, varid, mystart, myedges, value, memtype); } /* memptr indicates where to store the next value */ memptr = value; odom_init(&odom,rank,mystart,myedges,mystride); /* walk the odometer to extract values */ while(odom_more(&odom)) { int localstatus = NC_NOERR; /* Read a single value */ localstatus = NC_get_vara(ncid,varid,odom.index,nc_sizevector1,memptr,memtype); /* So it turns out that when get_varm is used, all errors are delayed and ERANGE will be overwritten by more serious errors. */ if(localstatus != NC_NOERR) { if(status == NC_NOERR || localstatus != NC_ERANGE) status = localstatus; } memptr += memtypelen; odom_next(&odom); } return status; #endif }