/* * In netCDF-3.6.2, an assertion failure occurs on 32-bit platforms * when creating a byte variable for which the product of dimensions * is greater than 2**32. Check that this bug has been fixed. */ static int test_big_var(const char *testfile) { int ncid, varid, dimids[NUMDIMS]; size_t index[NUMDIMS]; int nval = 99; int nval_in; /* Create a file with one big variable. */ if (nc_create(testfile, NC_CLOBBER, &ncid)) ERR; if (nc_set_fill(ncid, NC_NOFILL, NULL)) ERR; if (nc_def_dim(ncid, "dim1", DIM1, &dimids[0])) ERR; if (nc_def_dim(ncid, "dim2", DIM2 - 1, &dimids[1])) ERR; if (nc_def_var(ncid, "var", NC_BYTE, NUMDIMS, dimids, &varid)) ERR; if (nc_enddef(ncid)) ERR; index[0] = DIM1 - 1; index[1] = DIM2 - 2; if (nc_put_var1_int(ncid, varid, index, &nval)) ERR; if (nc_close(ncid)) ERR; /* Open the file and check it. */ if (nc_open(testfile, NC_NOWRITE, &ncid)) ERR; if (nc_inq_varid(ncid, "var", &varid)) ERR; if (nc_get_var1_int(ncid, varid, index, &nval_in)) ERR; if (nval != nval_in) ERR; if (nc_close(ncid)) ERR; return 0; }
/* * In netCDF-3.6.2, a divide by zero occurs on 32-bit platforms when * creating a variable for which the product of dimensions is exactly * 2**32. Check that this bug has been fixed. */ static int test_big_var(const char *testfile) { int ncid, varid, dimids[NUMDIMS]; int cflag = NC_CLOBBER; nc_type type = NC_BYTE; size_t index[NUMDIMS]; signed char nval = 99; int nval_in; /* Define the file with one large variable. */ if (nc_create(testfile, cflag, &ncid)) ERR; if (nc_set_fill(ncid, NC_NOFILL, NULL)) ERR; if (nc_def_dim(ncid, "dim1", DIM1, &dimids[0])) ERR; if (nc_def_dim(ncid, "dim2", DIM2 - 1, &dimids[1])) ERR; if (nc_def_var(ncid, "var", type, NUMDIMS, dimids, &varid)) ERR; if (nc_enddef(ncid)) ERR; /* Write one datum, near the end of the variable. */ index[0] = DIM1 - 1; index[1] = DIM2 - 2; if (nc_put_var1_schar(ncid, varid, index, &nval)) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and check that datum. */ if (nc_open(testfile, NC_NOWRITE, &ncid)) ERR; if (nc_inq_varid(ncid, "var", &varid)) ERR; if (nc_get_var1_int(ncid, varid, index, &nval_in)) ERR; if (nval != nval_in) ERR; if (nc_close(ncid)) ERR; return 0; }
int create_file(char *file_name, int fill_mode) { int ncid; int lon_dim, lat_dim, lvl_dim, time_dim; int time_id, zonal_wnd_id; int i; /* rank (number of dimensions) for each variable */ # define RANK_time 1 # define RANK_zonal_wnd 3 /* variable shapes */ int zonal_wnd_dims[RANK_zonal_wnd]; size_t zonal_wnd_start[RANK_zonal_wnd]; size_t zonal_wnd_count[RANK_zonal_wnd]; float zonal_wnd[LON_LEN*LAT_LEN]; int time[TIME_LEN]; for(i = 0; i < TIME_LEN; i++) { time[i] = 1; } if (nc_create(file_name, NC_CLOBBER, &ncid)) ERR; if (nc_set_fill(ncid, fill_mode, NULL)) ERR; /* define dimensions */ if (nc_def_dim(ncid, "lon", LON_LEN, &lon_dim)) ERR; if (nc_def_dim(ncid, "lat", LAT_LEN, &lat_dim)) ERR; if (nc_def_dim(ncid, "lvl", LVL_LEN, &lvl_dim)) ERR; if (nc_def_dim(ncid, "time", TIME_LEN, &time_dim)) ERR; /* define variables */ if (nc_def_var(ncid, "time", NC_INT, RANK_time, &time_dim, &time_id)) ERR; zonal_wnd_dims[0] = lvl_dim; zonal_wnd_dims[1] = lat_dim; zonal_wnd_dims[2] = lon_dim; if (nc_def_var(ncid, "zonal_wnd", NC_FLOAT, RANK_zonal_wnd, zonal_wnd_dims, &zonal_wnd_id)) ERR; if (nc_enddef (ncid)) ERR; if (nc_put_var_int(ncid, time_id, time)) ERR; /* Bug exposed when last value written. */ { int izw; i = LVL_LEN - 1; for(izw = 0; izw < LAT_LEN * LON_LEN; izw++) { zonal_wnd[izw] = 100 + i; } zonal_wnd_start[0] = i; zonal_wnd_start[1] = 0; zonal_wnd_start[2] = 0; zonal_wnd_count[0] = 1; zonal_wnd_count[1] = LAT_LEN; zonal_wnd_count[2] = LON_LEN; if (nc_put_vara_float(ncid, zonal_wnd_id, zonal_wnd_start, zonal_wnd_count, zonal_wnd)) ERR; } if (nc_close(ncid)) ERR; return 0; }
/* * In netCDF-3.6.2, a divide by zero occurs on 32-bit platforms when * creating a variable for which the product of dimensions is exactly * 2**32. Check that this bug has been fixed. */ static void test_big_var(const char *testfile) { int ncid, varid, dimids[NUMDIMS]; int cflag = NC_CLOBBER; nc_type type = NC_BYTE; size_t index[NUMDIMS]; signed char nval = 99; int nval_in; if (nc_create(testfile, cflag, &ncid)) ERR; if (nc_set_fill(ncid, NC_NOFILL, NULL)) ERR; if (nc_def_dim(ncid, "dim1", DIM1, &dimids[0])) ERR; if (nc_def_dim(ncid, "dim2", DIM2 - 1, &dimids[1])) ERR; if (nc_def_var(ncid, "var", type, NUMDIMS, dimids, &varid)) ERR; if (nc_enddef(ncid)) ERR; index[0] = DIM1 - 1; index[1] = DIM2 - 2; if (nc_put_var1_schar(ncid, varid, index, &nval)) ERR; if (nc_close(ncid)) ERR; if (nc_open(testfile, NC_NOWRITE, &ncid)) ERR; if (nc_inq_varid(ncid, "var", &varid)) ERR; if (nc_get_var1_int(ncid, varid, index, &nval_in)) ERR; if (nval != nval_in) ERR; if (nc_close(ncid)) ERR; }
bi::NetCDFBuffer::NetCDFBuffer(const std::string& file, const FileMode mode) : file(file) { switch (mode) { case WRITE: ncid = nc_open(file, NC_WRITE); break; case NEW: ncid = nc_create(file, NC_NETCDF4 | NC_NOCLOBBER); nc_set_fill(ncid, NC_NOFILL); break; case REPLACE: ncid = nc_create(file, NC_NETCDF4); nc_set_fill(ncid, NC_NOFILL); break; default: ncid = nc_open(file, NC_NOWRITE); } }
NcBool NcFile::set_fill( FillMode a_mode ) { int prev_mode; if (NcError::set_err( nc_set_fill(the_id, a_mode, &prev_mode) ) == NC_NOERR) { the_fill_mode = a_mode; return TRUE; } return FALSE; }
/* * This program tests the fix for a large file bug in versions * previous to netCDF-4.1.2 for 32-bit platforms, writing to a * variable with more than 1 dimension and more than 2**32 values, * where the write starts after the first 2**32 elements. The bug * applies to record variables with more than 2**32 values per record * as well, but that's not tested here. */ static int test_big_var(const char *testfile) { int ncid, varid, dimids[NUMDIMS]; size_t start[NUMDIMS] = {0, 0, 0, 0}; size_t count[NUMDIMS] = {1, 1, 1, DIM3}; short data[DIM3]; int i, j, k; int nerrs = 0; /* Create a file with one big 4D variable. */ if (nc_create(testfile, NC_CLOBBER, &ncid)) ERR; if (nc_set_fill(ncid, NC_NOFILL, NULL)) ERR; if (nc_def_dim(ncid, "dim0", DIM0, &dimids[0])) ERR; if (nc_def_dim(ncid, "dim1", DIM1, &dimids[1])) ERR; if (nc_def_dim(ncid, "dim2", DIM2, &dimids[2])) ERR; if (nc_def_dim(ncid, "dim3", DIM3, &dimids[3])) ERR; if (nc_def_var(ncid, "var", NC_SHORT, NUMDIMS, dimids, &varid)) ERR; if (nc_enddef(ncid)) ERR; /* write var(0,0,4294,*) as all FIRST_VAL */ start[0] = 0; start[1] = 0; start[2] = 4294; for (j = 0; j < DIM3; j++) data[j] = FIRST_VAL; if (nc_put_vara_short(ncid, varid, start, count, &data[0])) ERR; /* write var(0,1,0,*) as all 8588 */ start[0] = 0; start[1] = 1; start[2] = 0; for (j = 0; j < DIM3; j++) data[j] = SECOND_VAL; if (nc_put_vara_short(ncid, varid, start, count, &data[0])) ERR; /* Read and check var(0,0,4294,*) */ start[0] = 0; start[1] = 0; start[2] = 4294; if (nc_get_vara_short(ncid, varid, start, count, &data[0])) ERR; for (j = 0; j < DIM3; j++) { if (data[j] != FIRST_VAL ) { printf("error on start[0..2]: %d,%d,%d j: %d, expected %d got %d\n", start[0], start[1], start[2], j, FIRST_VAL, data[j]); ERR; if(nerrs++ > 1) return nerrs; } } if (nc_close(ncid)) ERR; return NC_NOERR; }
int ncsetfill( int ncid, int fillmode ) { int oldmode = -1; const int status = nc_set_fill(ncid, fillmode, &oldmode); if(status != NC_NOERR) { nc_advise("ncsetfill", status, "ncid %d", ncid); return -1; } return oldmode; }
static int create(void) { int i; /* Create a file with one big variable */ CHECK(nc_create(TESTFILE, NC_NETCDF4|NC_CLOBBER, &ncid)); CHECK(nc_set_fill(ncid, NC_NOFILL, NULL)); for(i=0;i<ndims;i++) { char dimname[1024]; snprintf(dimname,sizeof(dimname),"dim%d",i); CHECK(nc_def_dim(ncid, dimname, dimsize[i], &dimids[i])); } CHECK(nc_def_var(ncid, "var", NC_FLOAT, ndims, dimids, &varid)); return NC_NOERR; }
/* Test a small file with one record var, which grows. */ static int test_one_growing(const char *testfile) { int ncid, dimid, varid; char data[MAX_RECS], data_in; size_t start[ONE_DIM], count[ONE_DIM], index[ONE_DIM], len_in; int r, f; /* Create some phoney data. */ for (data[0] = 'a', r = 1; r < MAX_RECS; r++) data[r] = data[r - 1] + 1; /* Run this with and without fill mode. */ for (f = 0; f < 2; f++) { /* Create a file with one ulimited dimensions, and one var. */ if (nc_create(testfile, NC_CLOBBER, &ncid)) ERR; if (nc_def_dim(ncid, DIM1_NAME, NC_UNLIMITED, &dimid)) ERR; if (nc_def_var(ncid, VAR_NAME, NC_CHAR, 1, &dimid, &varid)) ERR; if (nc_close(ncid)) ERR; /* Normally one would not close and reopen the file for each * record, but I am giving the library a little work-out here... */ for (r = 0; r < MAX_RECS; r++) { /* Write one record of var data, a single character. */ if (nc_open(testfile, NC_WRITE, &ncid)) ERR; if (f && nc_set_fill(ncid, NC_NOFILL, NULL)) ERR; count[0] = 1; start[0] = r; if (nc_put_vara_text(ncid, varid, start, count, &data[r])) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and check it. */ if (nc_open(testfile, NC_NOWRITE, &ncid)) ERR; if (nc_inq_dimlen(ncid, 0, &len_in)) ERR; if (len_in != r + 1) ERR; index[0] = r; if (nc_get_var1_text(ncid, 0, index, &data_in)) ERR; if (data_in != data[r]) ERR; if (nc_close(ncid)) ERR; } /* Next record. */ } return 0; }
/*! Set or unset the fill mode for a NetCDF file specified by its file id. \param [in] ncid File id \param [in] fill Define whether the fill mode should be enabled or not \return Status code */ int CNetCdfInterface::setFill(int ncid, bool fill) { int old_fill_mode; int status = nc_set_fill(ncid, fill ? NC_FILL: NC_NOFILL, &old_fill_mode); if (NC_NOERR != status) { StdString errormsg(nc_strerror(status)); StdStringStream sstr; sstr << "Error when calling function nc_set_fill(ncid, fill ? NC_FILL: NC_NOFILL, &old_fill_mode)" << std::endl; sstr << errormsg << std::endl; sstr << "Unable to set the fill mode to: " << (fill ? "NC_FILL": "NC_NOFILL") << std::endl; StdString e = sstr.str(); throw CNetCdfException(e); } return status; }
int main() { int ncid, spockid, kirkid, dimids[NUMDIMS]; double val_in, val_out = 999.99; size_t index[NUMDIMS] = {1}; int i, res; /* Create the netCDF classic format file. */ if ((res = nc_create("example.nc", NC_CLOBBER, &ncid))) BAIL(res); /* Turn off fill mode to speed things up. */ if ((res = nc_set_fill(ncid, NC_NOFILL, NULL))) BAIL(res); /* Define dimension. */ if ((res = nc_def_dim(ncid, "longdim", DIM_LEN, dimids))) BAIL(res); /* Define two variables. */ if ((res = nc_def_var(ncid, "spock", NC_DOUBLE, NUMDIMS, dimids, &spockid))) BAIL(res); if ((res = nc_def_var(ncid, "kirk", NC_DOUBLE, NUMDIMS, dimids, &kirkid))) BAIL(res); /* We're finished defining metadata. */ if ((res = nc_enddef(ncid))) BAIL(res); if ((res = nc_put_var1_double(ncid, spockid, index, &val_out))) BAIL(res); /* We're done! */ if ((res = nc_close(ncid))) BAIL(res); return 0; }
static void test_large_byte_var(const char *testfile) { int ncid, varid, dimids[NUMDIMS]; size_t index[2] = {0, 0}; int cflag = NC_CLOBBER; signed char vals[DIM2]; signed char char_val_in; int i, j; if (nc_create(testfile, cflag, &ncid)) ERR; if (nc_set_fill(ncid, NC_NOFILL, NULL)) ERR; if (nc_def_dim(ncid, "dim1", DIM1, &dimids[0])) ERR; if (nc_def_dim(ncid, "dim2", DIM2, &dimids[1])) ERR; if (nc_def_var(ncid, "var", NC_BYTE, NUMDIMS, dimids, &varid)) ERR; if (nc_enddef(ncid)) ERR; for (i=0; i<DIM1; i++) { size_t start[NUMDIMS]; size_t count[NUMDIMS]; start[0] = i; start[1] = 0; count[0] = 1; count[1] = DIM2; for (j=0; j < DIM2; j++) { vals[j] = (i+9)*(j+11); /* note vals[j] is 99 when i==0 and j==0 */ } if (nc_put_vara_schar(ncid, varid, start, count, vals)) { ERR; break; } } if (nc_close(ncid)) ERR; if (nc_open(testfile, NC_NOWRITE, &ncid)) ERR; if (nc_inq_varid(ncid, "var", &varid)) ERR; if (nc_get_var1_schar(ncid, varid, index, &char_val_in)) ERR; if (char_val_in != 99) /* see above, the value written when i==0, j==0 */ ERR; if (nc_close(ncid)) ERR; }
int main(int argc, char *argv[]) { int i, err, nerrs=0, ncid, dimid[2], varid[2]; short buf[10]; size_t start, count; err = nc_create(FILE_NAME, NC_CLOBBER|NC_64BIT_DATA, &ncid); ERR; err = nc_def_dim(ncid, "dim0", NC_MAX_UINT, &dimid[0]); ERR err = nc_def_dim(ncid, "dim1", 10, &dimid[1]); ERR /* define one small variable after one big variable */ err = nc_def_var(ncid, "var_big", NC_SHORT, 1, &dimid[0], &varid[0]); ERR err = nc_def_var(ncid, "var_small", NC_SHORT, 1, &dimid[1], &varid[1]); ERR err = nc_set_fill(ncid, NC_NOFILL, NULL); ERR err = nc_enddef(ncid); ERR /* write to var_big in location overlapping with var_small when using * netCDF 4.4.x or prior */ start = NC_MAX_UINT/sizeof(short); count = 10; for (i=0; i<10; i++) buf[i] = i; err = nc_put_vara_short(ncid, varid[0], &start, &count, buf); ERR /* write var_small */ for (i=0; i<10; i++) buf[i] = -1; err = nc_put_var_short(ncid, varid[1], buf); ERR /* read back var_big and check contents */ for (i=0; i<10; i++) buf[i] = -1; err = nc_get_vara_short(ncid, varid[0], &start, &count,buf); ERR for (i=0; i<10; i++) { if (buf[i] != i) { printf("Error at buf[%d] expect %d but got %hd\n",i,i,buf[i]); nerrs++; } } err = nc_close(ncid); ERR return (nerrs > 0); }
static int test_large_byte_var(const char *testfile) { int ncid, varid, dimids[NUMDIMS]; size_t index[NUMDIMS] = {0, 0}; signed char vals[DIM2]; signed char char_val_in; size_t start[NUMDIMS], count[NUMDIMS]; int j; if (nc_create(testfile, NC_CLOBBER, &ncid)) ERR; if (nc_set_fill(ncid, NC_NOFILL, NULL)) ERR; if (nc_def_dim(ncid, "dim1", DIM1, &dimids[0])) ERR; if (nc_def_dim(ncid, "dim2", DIM2, &dimids[1])) ERR; if (nc_def_var(ncid, "var", NC_BYTE, NUMDIMS, dimids, &varid)) ERR; if (nc_enddef(ncid)) ERR; for (j = 0; j < DIM2; j++) { vals[j] = 9 * (j + 11); /* note vals[j] is 99 when j==0 */ } start[1] = 0; count[0] = 1; count[1] = DIM2; for (start[0] = 0; start[0] < DIM1; start[0]++) { if (nc_put_vara_schar(ncid, varid, start, count, vals)) { ERR; break; } } if (nc_close(ncid)) ERR; if (nc_open(testfile, NC_NOWRITE, &ncid)) ERR; if (nc_inq_varid(ncid, "var", &varid)) ERR; if (nc_get_var1_schar(ncid, varid, index, &char_val_in)) ERR; if (char_val_in != 99) /* see above, the value written when start[0]==0, j==0 */ ERR; if (nc_close(ncid)) ERR; return 0; }
static void test_small_atts(const char *testfile) { int ncid; char att[MAX_LEN + 1], att_in[MAX_LEN + 1], source[MAX_LEN + 1] = "0123456"; int ndims, nvars, natts, unlimdimid; size_t len_in; int t, l, f; /* Run this with and without fill mode. */ for (f = 0; f < 2; f++) { /* Create small files with an attribute that grows by one each * time. */ for (t = 1; t < MAX_LEN; t++) { /* Create null-terminated text string of correct length. */ strncpy(att, source, t); /* Create a file with one attribute. */ if (nc_create(testfile, NC_CLOBBER, &ncid)) ERR; if (nc_put_att_text(ncid, NC_GLOBAL, ATT_NAME, t + 1, att)) ERR; if (f && nc_set_fill(ncid, NC_NOFILL, NULL)) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and check it. */ if (nc_open(testfile, NC_NOWRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != 0 && nvars != 0 && natts != 1 && unlimdimid != -1) ERR; if (nc_inq_attlen(ncid, NC_GLOBAL, ATT_NAME, &len_in)) ERR; if (len_in != t + 1) ERR; if (nc_get_att_text(ncid, NC_GLOBAL, ATT_NAME, att_in)); l = strlen(att_in); if (strncmp(att_in, att, t)) ERR; if (nc_close(ncid)) ERR; } } }
/* * NETCDF_setupOutput() * Given a coordinateInfo structure which has been opened for writing NETCDF * (NCInfo is allocated), set up the NCInfo structure. * Return 0 on success, 1 on failure. */ int NETCDF_setupOutput(coordinateInfo *trajInfo, int atoms) { #ifdef BINTRAJ netcdfTrajectoryInfo *NCInfo; int dimensionID[NC_MAX_VAR_DIMS],err,oldMode; # ifdef MPI MPI_Offset start[3], count[3]; # else size_t start[3], count[3]; # endif char xyz[3]; char abc[15] = { 'a', 'l', 'p', 'h', 'a', 'b', 'e', 't', 'a', ' ', 'g', 'a', 'm', 'm', 'a' }; if (trajInfo->NCInfo==NULL) return 1; NCInfo = trajInfo->NCInfo; /* * define the global dimensions of the NetCDF file */ netcdfDefineDimension(NCInfo->ncid, AMBER_NETCDF_FRAME, NC_UNLIMITED, &NCInfo->frameDID); netcdfDefineDimension(NCInfo->ncid, AMBER_NETCDF_SPATIAL, 3, &NCInfo->spatialDID); netcdfDefineDimension(NCInfo->ncid, AMBER_NETCDF_ATOM, atoms, &NCInfo->atomDID); netcdfDefineDimension(NCInfo->ncid, AMBER_NETCDF_LABEL, AMBER_NETCDF_LABELLEN, &NCInfo->labelDID); netcdfDefineDimension(NCInfo->ncid, AMBER_NETCDF_CELL_SPATIAL, 3, &NCInfo->cell_spatialDID); netcdfDefineDimension(NCInfo->ncid, AMBER_NETCDF_CELL_ANGULAR, 3, &NCInfo->cell_angularDID); /* * put global attributes */ netcdfPutAttributeText(NCInfo->ncid, NC_GLOBAL, "title", trajInfo->title); netcdfPutAttributeText(NCInfo->ncid, NC_GLOBAL, "application", trajInfo->application); netcdfPutAttributeText(NCInfo->ncid, NC_GLOBAL, "program", trajInfo->program); netcdfPutAttributeText(NCInfo->ncid, NC_GLOBAL, "programVersion", trajInfo->version); netcdfPutAttributeText(NCInfo->ncid, NC_GLOBAL, "Conventions", "AMBER"); netcdfPutAttributeText(NCInfo->ncid, NC_GLOBAL, "ConventionVersion", "1.0"); /* * handle definition of non-optional variables */ dimensionID[0] = NCInfo->spatialDID; netcdfDefineVariable(NCInfo->ncid, AMBER_NETCDF_SPATIAL, NC_CHAR, 1, dimensionID, &NCInfo->spatialVID); dimensionID[0] = NCInfo->frameDID; netcdfDefineVariable(NCInfo->ncid, AMBER_NETCDF_TIME, NC_FLOAT, 1, dimensionID, &NCInfo->timeVID); netcdfPutAttributeText(NCInfo->ncid, NCInfo->timeVID, "units", "picosecond"); dimensionID[0] = NCInfo->frameDID; dimensionID[1] = NCInfo->atomDID; dimensionID[2] = NCInfo->spatialDID; netcdfDefineVariable(NCInfo->ncid, AMBER_NETCDF_COORDS, NC_FLOAT, 3, dimensionID, &NCInfo->coordinateVID); netcdfPutAttributeText(NCInfo->ncid, NCInfo->coordinateVID, "units", "angstrom"); dimensionID[0] = NCInfo->cell_spatialDID; netcdfDefineVariable(NCInfo->ncid, AMBER_NETCDF_CELL_SPATIAL, NC_CHAR, 1, dimensionID, &NCInfo->cell_spatialVID); dimensionID[0] = NCInfo->cell_angularDID; dimensionID[1] = NCInfo->labelDID; netcdfDefineVariable(NCInfo->ncid, AMBER_NETCDF_CELL_ANGULAR, NC_CHAR, 2, dimensionID, &NCInfo->cell_angularVID); // Set up Box coords if (trajInfo->isBox) { dimensionID[0] = NCInfo->frameDID; dimensionID[1] = NCInfo->cell_spatialDID; netcdfDefineVariable(NCInfo->ncid, "cell_lengths", NC_DOUBLE, 2, dimensionID, &NCInfo->cellLengthVID); netcdfPutAttributeText(NCInfo->ncid, NCInfo->cellLengthVID, "units", "angstrom"); dimensionID[1] = NCInfo->cell_angularDID; netcdfDefineVariable(NCInfo->ncid, "cell_angles", NC_DOUBLE, 2, dimensionID, &NCInfo->cellAngleVID); netcdfPutAttributeText(NCInfo->ncid, NCInfo->cellAngleVID, "units", "degree"); } /* DAN ROE: Replica temperature */ if (trajInfo->isREMDTRAJ) { fprintf(stdout,"NETCDF: Defining replica temperature in output trajectory.\n"); dimensionID[0] = NCInfo->frameDID; netcdfDefineVariable(NCInfo->ncid, "temp0", NC_DOUBLE, 1, dimensionID, &NCInfo->TempVarID); netcdfPutAttributeText(NCInfo->ncid, NCInfo->TempVarID,"units","kelvin"); } /* * set fill mode */ err = nc_set_fill(NCInfo->ncid, NC_NOFILL, &oldMode); if (err != NC_NOERR) { printfone("NetCDF setting fill value: %s\n", nc_strerror(err)); return 1; } /* * end of NetCDF definitions */ err = nc_enddef(NCInfo->ncid); if (err != NC_NOERR) { printfone("NetCDF error on ending definitions: %s\n", nc_strerror(err)); return 1; } /* * specify spatial dimension labels */ start[0] = 0; count[0] = 3; xyz[0] = 'x'; xyz[1] = 'y'; xyz[2] = 'z'; err = nc_put_vara_text(NCInfo->ncid, NCInfo->spatialVID, start, count, xyz); if (err != NC_NOERR) { printfone("Error on NetCDF output of spatial VID 'x', 'y' and 'z': %s\n", nc_strerror(err)); return 1; } xyz[0] = 'a'; xyz[1] = 'b'; xyz[2] = 'c'; err = nc_put_vara_text(NCInfo->ncid, NCInfo->cell_spatialVID, start, count, xyz); if (err != NC_NOERR) { printfone("Error on NetCDF output of spatial VID 'x', 'y' and 'z': %s\n", nc_strerror(err)); return 1; } start[0] = 0; start[1] = 0; count[0] = 3; count[1] = 5; err = nc_put_vara_text(NCInfo->ncid, NCInfo->cell_angularVID, start, count, abc); if (err != NC_NOERR) { printfone("Error on NetCDF output of angular VID 'alpha', 'beta ' and 'gamma': %s\n", nc_strerror(err)); return 1; } //outInfo->NCInfo = NCInfo; return 0; #endif return 1; }
/* See ncd3dispatch.c for other version */ int NCD3_open(const char * path, int mode, int basepe, size_t *chunksizehintp, int useparallel, void* mpidata, NC_Dispatch* dispatch, NC** ncpp) { NCerror ncstat = NC_NOERR; OCerror ocstat = OC_NOERR; NC* drno = NULL; NCDAPCOMMON* dapcomm = NULL; const char* value; char* tmpname = NULL; if(!nc3dinitialized) nc3dinitialize(); if(path == NULL) return NC_EDAPURL; if(dispatch == NULL) PANIC("NC3D_open: no dispatch table"); /* Setup our NC and NCDAPCOMMON state*/ drno = (NC*)calloc(1,sizeof(NC)); if(drno == NULL) {ncstat = NC_ENOMEM; goto done;} /* compute an ncid */ ncstat = add_to_NCList(drno); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} dapcomm = (NCDAPCOMMON*)calloc(1,sizeof(NCDAPCOMMON)); if(dapcomm == NULL) {ncstat = NC_ENOMEM; goto done;} drno->dispatch = dispatch; drno->dispatchdata = dapcomm; dapcomm->controller = (NC*)drno; dapcomm->cdf.separator = "."; dapcomm->cdf.smallsizelimit = DFALTSMALLLIMIT; dapcomm->cdf.cache = createnccache(); #ifdef HAVE_GETRLIMIT { struct rlimit rl; if(getrlimit(RLIMIT_NOFILE, &rl) >= 0) { dapcomm->cdf.cache->cachecount = (size_t)(rl.rlim_cur / 2); } } #endif #ifdef OCCOMPILEBYDEFAULT /* set the compile flag by default */ dapcomm->oc.rawurltext = (char*)emalloc(strlen(path)+strlen("[compile]")+1); strcpy(dapcomm->oc.rawurltext,"[compile]"); strcat(dapcomm->oc.rawurltext, path); #else dapcomm->oc.rawurltext = strdup(path); #endif nc_uriparse(dapcomm->oc.rawurltext,&dapcomm->oc.url); /* parse the client parameters */ nc_uridecodeparams(dapcomm->oc.url); if(!constrainable34(dapcomm->oc.url)) SETFLAG(dapcomm->controls,NCF_UNCONSTRAINABLE); /* Use libsrc code for storing metadata */ tmpname = nulldup(PSEUDOFILE); /* Now, use the file to create the netcdf file */ if(sizeof(size_t) == sizeof(unsigned int)) ncstat = nc_create(tmpname,NC_CLOBBER,&drno->substrate); else ncstat = nc_create(tmpname,NC_CLOBBER|NC_64BIT_OFFSET,&drno->substrate); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* free the filename so it will automatically go away*/ unlink(tmpname); nullfree(tmpname); /* Avoid fill */ nc_set_fill(drno->substrate,NC_NOFILL,NULL); dapcomm->oc.dapconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT); dapcomm->oc.dapconstraint->projections = nclistnew(); dapcomm->oc.dapconstraint->selections = nclistnew(); /* Parse constraints to make sure they are syntactically correct */ ncstat = parsedapconstraints(dapcomm,dapcomm->oc.url->constraint,dapcomm->oc.dapconstraint); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* Complain if we are unconstrainable but have constraints */ if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) { if(dapcomm->oc.url->constraint != NULL && strlen(dapcomm->oc.url->constraint) > 0) { nclog(NCLOGWARN,"Attempt to constrain an unconstrainable data source: %s", dapcomm->oc.url->constraint); } } /* Construct a url for oc minus any parameters */ dapcomm->oc.urltext = nc_uribuild(dapcomm->oc.url,NULL,NULL, (NC_URIALL ^ NC_URICONSTRAINTS)); /* Pass to OC */ ocstat = oc_open(dapcomm->oc.urltext,&dapcomm->oc.conn); if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;} nullfree(dapcomm->oc.urltext); /* clean up */ dapcomm->oc.urltext = NULL; /* process control client parameters */ applyclientparamcontrols3(dapcomm); /* Turn on logging; only do this after oc_open*/ if((value = paramvalue34(dapcomm,"log")) != NULL) { ncloginit(); ncsetlogging(1); nclogopen(value); oc_loginit(); oc_setlogging(1); oc_logopen(value); } /* fetch and build the (almost) unconstrained DDS for use as template */ ncstat = fetchtemplatemetadata3(dapcomm); if(ncstat != NC_NOERR) goto done; /* fetch and build the constrained DDS */ ncstat = fetchconstrainedmetadata3(dapcomm); if(ncstat != NC_NOERR) goto done; #ifdef DEBUG2 fprintf(stderr,"constrained dds: %s\n",dumptree(dapcomm->cdf.ddsroot)); #endif /* The following actions are (mostly) WRT to the constrained tree */ /* Accumulate useful nodes sets */ ncstat = computecdfnodesets3(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} /* Fix grids */ ncstat = fixgrids3(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} /* Locate and mark usable sequences */ ncstat = sequencecheck3(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} /* suppress variables not in usable sequences */ ncstat = suppressunusablevars3(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} /* apply client parameters */ ncstat = applyclientparams34(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} /* Add (as needed) string dimensions*/ ncstat = addstringdims(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} if(nclistlength(dapcomm->cdf.seqnodes) > 0) { /* Build the sequence related dimensions */ ncstat = defseqdims(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} } /* Define the dimsetplus and dimsetall lists */ ncstat = definedimsets3(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} /* Re-compute the dimension names*/ ncstat = computecdfdimnames34(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} /* Deal with zero size dimensions */ ncstat = fixzerodims3(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} /* Attempt to use the DODS_EXTRA info to turn one of the dimensions into unlimited. Assume computecdfdimnames34 has already been called. */ ncstat = defrecorddim3(dapcomm); if(ncstat) {THROWCHK(ncstat); goto done;} if(dapcomm->cdf.recorddimname != NULL && nclistlength(dapcomm->cdf.seqnodes) > 0) { /*nclog(NCLOGWARN,"unlimited dimension specified, but sequences exist in DDS");*/ PANIC("unlimited dimension specified, but sequences exist in DDS"); } /* Re-compute the var names*/ ncstat = computecdfvarnames3(dapcomm,dapcomm->cdf.ddsroot,dapcomm->cdf.varnodes); if(ncstat) {THROWCHK(ncstat); goto done;} /* Transfer data from the unconstrained DDS data to the unconstrained DDS */ ncstat = dimimprint3(dapcomm); if(ncstat) goto done; /* Process the constraints to map to the constrained CDF tree */ /* (must follow fixgrids3 */ ncstat = mapconstraints3(dapcomm->oc.dapconstraint,dapcomm->cdf.ddsroot); if(ncstat != NC_NOERR) goto done; /* Canonicalize the constraint */ ncstat = fixprojections(dapcomm->oc.dapconstraint->projections); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* Fill in segment information */ ncstat = qualifyconstraints3(dapcomm->oc.dapconstraint); if(ncstat != NC_NOERR) goto done; /* using the modified constraint, rebuild the constraint string */ if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) { /* ignore all constraints */ dapcomm->oc.urltext = nc_uribuild(dapcomm->oc.url,NULL,NULL,0); } else { char* constraintstring = buildconstraintstring3(dapcomm->oc.dapconstraint); nc_urisetconstraints(dapcomm->oc.url,constraintstring); nullfree(constraintstring); dapcomm->oc.urltext = nc_uribuild(dapcomm->oc.url,NULL,NULL,NC_URICONSTRAINTS); } #ifdef DEBUG fprintf(stderr,"ncdap3: final constraint: %s\n",dapcomm->oc.url->constraint); #endif /* Estimate the variable sizes */ estimatevarsizes3(dapcomm); /* Build the meta data */ ncstat = buildncstructures3(dapcomm); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* Do any necessary data prefetch */ if(FLAGSET(dapcomm->controls,NCF_PREFETCH)) { ncstat = prefetchdata3(dapcomm); if(ncstat != NC_NOERR) { del_from_NCList((NC*)drno); /* undefine here */ {THROWCHK(ncstat); goto done;} } } { /* Mark as no longer writable and no longer indef; requires breaking abstraction */ NC* nc; ncstat = NC_check_id(drno->substrate, &nc); /* Mark as no longer writeable */ fClr(nc->nciop->ioflags, NC_WRITE); /* Mark as no longer indef; (do NOT use nc_enddef until diskless is working)*/ fSet(nc->flags, NC_INDEF); } if(ncpp) *ncpp = (NC*)drno; return ncstat; done: if(drno != NULL) NCD3_abort(drno->ext_ncid); if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); return THROW(ncstat); }
int main(int argc, char **argv) { int ncid, spockid, kirkid, dimids[NUMDIMS]; int int_val_in, int_val_out = 99; double double_val_in, double_val_out = 1.79769313486230e+308; /* from ncx.h */ size_t index[2] = {QTR_CLASSIC_MAX-1, 0}; /* These are for the revolutionary generals tests. */ int cromwellid, collinsid, washingtonid; int napoleanid, dimids_gen[4], dimids_gen1[4]; /* All create modes will be anded to this. All tests will be run twice, with and without NC_SHARE.*/ int cmode_run; int cflag = NC_CLOBBER; int res; printf("\n*** Testing large files, quickly.\n"); for (cmode_run=0; cmode_run<2; cmode_run++) { /* On second pass, try using NC_SHARE. */ if (cmode_run == 1) { cflag |= NC_SHARE; printf("*** Turned on NC_SHARE for subsequent tests.\n"); } /* Create a netCDF 64-bit offset format file. Write a value. */ printf("*** Creating %s for 64-bit offset large file test...", FILE_NAME); if ((res = nc_create(FILE_NAME, cflag|NC_64BIT_OFFSET, &ncid))) ERR; if ((res = nc_set_fill(ncid, NC_NOFILL, NULL))) ERR; if ((res = nc_def_dim(ncid, "longdim", QTR_CLASSIC_MAX, dimids))) ERR; if ((res = nc_def_var(ncid, "spock", NC_DOUBLE, NUMDIMS, dimids, &spockid))) ERR; if ((res = nc_def_var(ncid, "kirk", NC_DOUBLE, NUMDIMS, dimids, &kirkid))) ERR; if ((res = nc_enddef(ncid))) ERR; if ((res = nc_put_var1_double(ncid, kirkid, index, &double_val_out))) ERR; if ((res = nc_close(ncid))) ERR; printf("ok\n"); /* How about a meteorological data file about the weather experience by various generals of revolutionary armies? This has 3 dims, 4 vars. The dimensions are such that this will (just barely) not fit in a classic format file. The first three vars are cromwell, 536870911 bytes, washington, 2*536870911 bytes, and napolean, 536870911 bytes. That's a grand total of 2147483644 bytes. Recall our magic limit for the combined size of all fixed vars: 2 GiB - 4 bytes, or 2147483644. So you would think these would exactly fit, unless you realized that everything is rounded to a 4 byte boundary, so you need to add some bytes for that (how many?), and that pushes us over the limit. We will create this file twice, once to ensure it succeeds (with 64-bit offset format), and once to make sure it fails (with classic format). Then some variations to check record var boundaries. */ printf("*** Now a 64-bit offset, large file, fixed var test..."); if ((res = nc_create(FILE_NAME, cflag|NC_64BIT_OFFSET, &ncid))) ERR; if ((res = nc_set_fill(ncid, NC_NOFILL, NULL))) ERR; if ((res = nc_def_dim(ncid, "revolutionary_fervor", QTR_CLASSIC_MAX, &dimids_gen[0]))) ERR; if ((res = nc_def_dim(ncid, "post_revoultionary_hangover", QTR_CLASSIC_MAX, &dimids_gen[1]))) ERR; if ((res = nc_def_dim(ncid, "ruthlessness", 100, &dimids_gen[2]))) ERR; if ((res = nc_def_var(ncid, "Cromwell", NC_BYTE, 1, &dimids_gen[0], &cromwellid))) ERR; if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 1, &dimids_gen[1], &washingtonid))) ERR; if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 1, &dimids_gen[0], &napoleanid))) ERR; if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 1, &dimids_gen[2], &collinsid))) ERR; if ((res = nc_enddef(ncid))) ERR; printf("ok\n"); /* Write a value or two just for fun. */ /*index[0] = QTR_CLASSIC_MAX - 296; if ((res = nc_put_var1_int(ncid, napoleanid, index, &int_val_out))) ERR; if ((res = nc_get_var1_int(ncid, napoleanid, index, &int_val_in))) ERR; if (int_val_in != int_val_out) BAIL2;*/ printf("*** Now writing some values..."); index[0] = QTR_CLASSIC_MAX - 295; if ((res = nc_put_var1_int(ncid, napoleanid, index, &int_val_out))) ERR; if ((res = nc_get_var1_int(ncid, napoleanid, index, &int_val_in))) ERR; if (int_val_in != int_val_out) ERR; index[0] = QTR_CLASSIC_MAX - 1; if ((res = nc_put_var1_int(ncid, napoleanid, index, &int_val_out))) ERR; if ((res = nc_get_var1_int(ncid, napoleanid, index, &int_val_in))) ERR; if (int_val_in != int_val_out) ERR; index[0] = QTR_CLASSIC_MAX - 1; if ((res = nc_put_var1_int(ncid, washingtonid, index, &int_val_out))) ERR; if ((res = nc_get_var1_int(ncid, washingtonid, index, &int_val_in))) ERR; if (int_val_in != int_val_out) ERR; if ((res = nc_close(ncid))) ERR; printf("ok\n"); /* This time it should fail, because we're trying to cram this into a classic format file. nc_enddef will detect our violations and give an error. We've*/ printf("*** Now a classic file which will fail..."); if ((res = nc_create(FILE_NAME, cflag, &ncid))) ERR; if ((res = nc_set_fill(ncid, NC_NOFILL, NULL))) ERR; if ((res = nc_def_dim(ncid, "revolutionary_fervor", QTR_CLASSIC_MAX, &dimids_gen[0]))) ERR; if ((res = nc_def_dim(ncid, "post_revoultionary_hangover", QTR_CLASSIC_MAX, &dimids_gen[1]))) ERR; if ((res = nc_def_dim(ncid, "ruthlessness", 100, &dimids_gen[2]))) ERR; if ((res = nc_def_var(ncid, "Cromwell", NC_BYTE, 1, &dimids_gen[0], &cromwellid))) ERR; if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 1, &dimids_gen[1], &washingtonid))) ERR; if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 1, &dimids_gen[0], &napoleanid))) ERR; if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 1, &dimids_gen[2], &collinsid))) ERR; if ((res = nc_enddef(ncid)) != NC_EVARSIZE) ERR; if ((res = nc_close(ncid)) != NC_EVARSIZE) ERR; printf("ok\n"); /* This will create some max sized 64-bit offset format fixed vars. */ printf("*** Now a 64-bit offset, simple fixed var create test..."); if ((res = nc_create(FILE_NAME, cflag|NC_64BIT_OFFSET, &ncid))) ERR; if ((res = nc_set_fill(ncid, NC_NOFILL, NULL))) ERR; if ((res = nc_def_dim(ncid, "revolutionary_fervor", MAX_CLASSIC_BYTES, &dimids_gen[0]))) ERR; if ((res = nc_def_var(ncid, "Cromwell", NC_SHORT, 1, dimids_gen, &cromwellid))) ERR; if ((res = nc_def_var(ncid, "Napolean", NC_SHORT, 1, dimids_gen, &napoleanid))) ERR; if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 1, dimids_gen, &collinsid))) ERR; if ((res = nc_enddef(ncid))) ERR; if ((res = nc_close(ncid))) ERR; printf("ok\n"); /* This will exceed the 64-bit offset format limits for one of the fixed vars. */ printf("*** Now a 64-bit offset, over-sized file that will fail..."); if ((res = nc_create(FILE_NAME, cflag|NC_64BIT_OFFSET, &ncid))) ERR; if ((res = nc_set_fill(ncid, NC_NOFILL, NULL))) ERR; /* max dim size is MAX_CLASSIC_BYTES. */ if ((res = nc_def_dim(ncid, "revolutionary_fervor", MAX_CLASSIC_BYTES, dimids_gen))) ERR; if ((res = nc_def_var(ncid, "Cromwell", NC_DOUBLE, 1, dimids_gen, &cromwellid))) ERR; if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 1, dimids_gen, &washingtonid))) if ((res = nc_enddef(ncid)) != NC_EVARSIZE) ERR; if ((res = nc_close(ncid)) != NC_EVARSIZE) ERR; printf("ok\n"); /* Now let's see about record vars. First create a 64-bit offset file with three rec variables, each with the same numbers as defined above for the fixed var tests. This should all work. */ printf("*** Now a 64-bit offset, record var file..."); if ((res = nc_create(FILE_NAME, cflag|NC_64BIT_OFFSET, &ncid))) ERR; if ((res = nc_set_fill(ncid, NC_NOFILL, NULL))) ERR; if ((res = nc_def_dim(ncid, "political_trouble", NC_UNLIMITED, &dimids_gen[0]))) ERR; if ((res = nc_def_dim(ncid, "revolutionary_fervor", QTR_CLASSIC_MAX, &dimids_gen[1]))) ERR; if ((res = nc_def_dim(ncid, "post_revoultionary_hangover", QTR_CLASSIC_MAX, &dimids_gen[2]))) ERR; if ((res = nc_def_dim(ncid, "ruthlessness", 100, &dimids_gen[3]))) ERR; if ((res = nc_def_var(ncid, "Cromwell", NC_BYTE, 2, dimids_gen, &cromwellid))) ERR; if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 2, dimids_gen, &washingtonid))) ERR; if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 2, dimids_gen, &napoleanid))) ERR; if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 1, &dimids_gen[2], &collinsid))) ERR; if ((res = nc_enddef(ncid))) ERR; if ((res = nc_close(ncid))) ERR; printf("ok\n"); /* Now try this record file in classic format. It should fail and the enddef. Too many bytes in the first record.*/ printf("*** Now a classic file that's too big and will fail..."); if ((res = nc_create(FILE_NAME, cflag, &ncid))) ERR; if ((res = nc_set_fill(ncid, NC_NOFILL, NULL))) ERR; if ((res = nc_def_dim(ncid, "political_trouble", NC_UNLIMITED, &dimids_gen[0]))) ERR; if ((res = nc_def_dim(ncid, "revolutionary_fervor", QTR_CLASSIC_MAX, &dimids_gen[1]))) ERR; if ((res = nc_def_dim(ncid, "post_revoultionary_hangover", QTR_CLASSIC_MAX, &dimids_gen[2]))) ERR; if ((res = nc_def_dim(ncid, "ruthlessness", 100, &dimids_gen[3]))) ERR; if ((res = nc_def_var(ncid, "Cromwell", NC_BYTE, 2, dimids_gen, &cromwellid))) ERR; if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 2, dimids_gen, &washingtonid))) ERR; if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 2, dimids_gen, &napoleanid))) ERR; if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 1, &dimids_gen[2], &collinsid))) ERR; if ((res = nc_enddef(ncid)) != NC_EVARSIZE) ERR; if ((res = nc_close(ncid)) != NC_EVARSIZE) ERR; printf("ok\n"); /* Now try this record file in classic format. It just barely passes at the enddef. Almost, but not quite, too many bytes in the first record. Since I'm adding a fixed variable (Collins), I don't get the last record size exemption. */ printf("*** Now a classic file with recs and one fixed will fail..."); if ((res = nc_create(FILE_NAME, cflag, &ncid))) ERR; if ((res = nc_set_fill(ncid, NC_NOFILL, NULL))) ERR; if ((res = nc_def_dim(ncid, "political_trouble", NC_UNLIMITED, &dimids_gen[0]))) ERR; if ((res = nc_def_dim(ncid, "revolutionary_fervor", MAX_CLASSIC_BYTES, &dimids_gen[1]))) ERR; if ((res = nc_def_dim(ncid, "ruthlessness", 100, &dimids_gen[2]))) ERR; if ((res = nc_def_var(ncid, "Cromwell", NC_BYTE, 2, dimids_gen, &cromwellid))) ERR; if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 1, &dimids_gen[2], &collinsid))) ERR; if ((res = nc_enddef(ncid))) ERR; if ((res = nc_close(ncid))) ERR; printf("ok\n"); /* Try a classic file with several records, and the last record var with a record size greater than our magic number of 2 GiB - 4 bytes. We'll start with just one oversized record var. This should work. Cromwell has been changed to NC_DOUBLE, and that increases his size to 2147483644 (the max dimension size) times 8, or about 16 GB per record. Zowie! (Mind you, Cromwell certainly had a great deal of revolutionary fervor.) */ printf("*** Now a classic file with one large rec var..."); if ((res = nc_create(FILE_NAME, cflag, &ncid))) ERR; if ((res = nc_set_fill(ncid, NC_NOFILL, NULL))) ERR; if ((res = nc_def_dim(ncid, "political_trouble", NC_UNLIMITED, &dimids_gen[0]))) ERR; if ((res = nc_def_dim(ncid, "revolutionary_fervor", MAX_CLASSIC_BYTES, &dimids_gen[1]))) ERR; if ((res = nc_def_var(ncid, "Cromwell", NC_DOUBLE, 2, dimids_gen, &cromwellid))) ERR; if ((res = nc_enddef(ncid))) ERR; index[0] = 0; index[1] = MAX_CLASSIC_BYTES - 1; if ((res = nc_put_var1_double(ncid, cromwellid, index, &double_val_out))) ERR; if ((res = nc_get_var1_double(ncid, cromwellid, index, &double_val_in))) ERR; if (double_val_in != double_val_out) ERR; if ((res = nc_close(ncid))) ERR; printf("ok\n"); /* This is a classic format file with an extra-large last record var. */ printf("*** Now a classic file with extra-large last record var..."); if ((res = nc_create(FILE_NAME, cflag, &ncid))) ERR; if ((res = nc_set_fill(ncid, NC_NOFILL, NULL))) ERR; if ((res = nc_def_dim(ncid, "political_trouble", NC_UNLIMITED, &dimids_gen[0]))) ERR; if ((res = nc_def_dim(ncid, "revolutionary_fervor", MAX_CLASSIC_BYTES, &dimids_gen[1]))) ERR; dimids_gen1[0] = dimids_gen[0]; if ((res = nc_def_dim(ncid, "post_revoultionary_hangover", 5368, &dimids_gen1[1]))) ERR; if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 2, dimids_gen1, &washingtonid))) ERR; if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 2, dimids_gen1, &napoleanid))) ERR; if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 2, dimids_gen1, &collinsid))) ERR; if ((res = nc_def_var(ncid, "Cromwell", NC_DOUBLE, 2, dimids_gen, &cromwellid))) ERR; if ((res = nc_enddef(ncid))) ERR; index[0] = 0; index[1] = MAX_CLASSIC_BYTES - 1; if ((res = nc_put_var1_double(ncid, cromwellid, index, &double_val_out))) ERR; if ((res = nc_get_var1_double(ncid, cromwellid, index, &double_val_in))) ERR; if (double_val_in != double_val_out) ERR; if ((res = nc_close(ncid))) ERR; printf("ok\n"); /* This is a classic format file with an extra-large second to last record var. But this time it won't work, because the size exemption only applies to the last record var. Note that one dimension is small (5000). */ printf("*** Now a classic file xtra-large 2nd to last var that will fail..."); if ((res = nc_create(FILE_NAME, cflag, &ncid))) ERR; if ((res = nc_set_fill(ncid, NC_NOFILL, NULL))) ERR; if ((res = nc_def_dim(ncid, "political_trouble", NC_UNLIMITED, &dimids_gen[0]))) ERR; if ((res = nc_def_dim(ncid, "revolutionary_fervor", MAX_CLASSIC_BYTES, &dimids_gen[1]))) ERR; dimids_gen1[0] = dimids_gen[0]; if ((res = nc_def_dim(ncid, "post_revoultionary_hangover", 5000, &dimids_gen1[1]))) ERR; if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 2, dimids_gen1, &washingtonid))) ERR; if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 2, dimids_gen1, &napoleanid))) ERR; if ((res = nc_def_var(ncid, "Cromwell", NC_DOUBLE, 2, dimids_gen, &cromwellid))) ERR; if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 2, dimids_gen1, &collinsid))) ERR; if ((res = nc_enddef(ncid)) != NC_EVARSIZE) ERR; if ((res = nc_close(ncid)) != NC_EVARSIZE) ERR; printf("ok\n"); /* Now try an extra large second to last ver with 64-bit offset. This won't work either, because the cromwell var is so large. It exceeds the 4GiB - 4 byte per record limit for record vars. */ printf("*** Now a 64-bit offset file with too-large rec var that will fail..."); if ((res = nc_create(FILE_NAME, cflag|NC_64BIT_OFFSET, &ncid))) ERR; if ((res = nc_set_fill(ncid, NC_NOFILL, NULL))) ERR; if ((res = nc_def_dim(ncid, "political_trouble", NC_UNLIMITED, &dimids_gen[0]))) ERR; if ((res = nc_def_dim(ncid, "revolutionary_fervor", MAX_CLASSIC_BYTES, &dimids_gen[1]))) ERR; dimids_gen1[0] = dimids_gen[0]; if ((res = nc_def_dim(ncid, "post_revoultionary_hangover", 5368, &dimids_gen1[1]))) ERR; if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 2, dimids_gen1, &washingtonid))) ERR; if ((res = nc_def_var(ncid, "Napolean", NC_BYTE, 2, dimids_gen1, &napoleanid))) ERR; if ((res = nc_def_var(ncid, "Cromwell", NC_DOUBLE, 2, dimids_gen, &cromwellid))) ERR; if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 2, dimids_gen1, &collinsid))) ERR; if ((res = nc_enddef(ncid)) != NC_EVARSIZE) ERR; if ((res = nc_close(ncid)) != NC_EVARSIZE) ERR; printf("ok\n"); /* A 64-bit offset record file that just fits... */ printf("*** Now a 64 bit-offset file that just fits..."); if ((res = nc_create(FILE_NAME, cflag|NC_64BIT_OFFSET, &ncid))) ERR; if ((res = nc_set_fill(ncid, NC_NOFILL, NULL))) ERR; if ((res = nc_def_dim(ncid, "political_trouble", NC_UNLIMITED, &dimids_gen[0]))) ERR; if ((res = nc_def_dim(ncid, "revolutionary_fervor", MAX_CLASSIC_BYTES, &dimids_gen[1]))) ERR; dimids_gen1[0] = dimids_gen[0]; if ((res = nc_def_dim(ncid, "post_revoultionary_hangover", MAX_CLASSIC_BYTES, &dimids_gen1[1]))) ERR; if ((res = nc_def_var(ncid, "Washington", NC_SHORT, 2, dimids_gen1, &washingtonid))) ERR; if ((res = nc_def_var(ncid, "Napolean", NC_SHORT, 2, dimids_gen1, &napoleanid))) ERR; if ((res = nc_def_var(ncid, "Cromwell", NC_SHORT, 2, dimids_gen, &cromwellid))) ERR; if ((res = nc_def_var(ncid, "Collins", NC_DOUBLE, 2, dimids_gen1, &collinsid))) ERR; if ((res = nc_enddef(ncid))) ERR; index[0] = 0; index[1] = MAX_CLASSIC_BYTES - 1; if ((res = nc_put_var1_int(ncid, cromwellid, index, &int_val_out))) ERR; if ((res = nc_get_var1_int(ncid, cromwellid, index, &int_val_in))) ERR; if (int_val_in != int_val_out) ERR; if ((res = nc_close(ncid))) ERR; printf("ok\n"); } /* end of cmode run */ /* Wow! Everything worked! */ printf("\n*** All large file tests were successful.\n"); /* Delete the huge data file we created. */ (void) remove(FILE_NAME); printf("*** Success ***\n"); return 0; }
int ex_put_prop_names(int exoid, ex_entity_type obj_type, int num_props, char **prop_names) { int status; int oldfill, temp; int i, propid, dimid, dims[1]; size_t name_length, prop_name_len; char * name; long long vals[1]; int max_name_len = 0; int int_type = NC_INT; char errmsg[MAX_ERR_LENGTH]; exerrval = 0; /* clear error code */ if (ex_int64_status(exoid) & EX_IDS_INT64_DB) { int_type = NC_INT64; } /* Get the name string length */ name_length = ex_inquire_int(exoid, EX_INQ_DB_MAX_ALLOWED_NAME_LENGTH) + 1; /* inquire id of previously defined dimension (number of objects) */ if ((status = nc_inq_dimid(exoid, ex_dim_num_objects(obj_type), &dimid)) != NC_NOERR) { exerrval = status; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to locate number of %s in file id %d", ex_name_of_object(obj_type), exoid); ex_err("ex_put_prop_names", errmsg, exerrval); return (EX_FATAL); } nc_set_fill(exoid, NC_FILL, &oldfill); /* fill with zeros per routine spec */ /* put netcdf file into define mode */ if ((status = nc_redef(exoid)) != NC_NOERR) { exerrval = status; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode", exoid); ex_err("ex_put_prop_names", errmsg, exerrval); return (EX_FATAL); } /* define num_props variables; we postpend the netcdf variable name with */ /* a counter starting at 2 because "xx_prop1" is reserved for the id array*/ dims[0] = dimid; for (i = 0; i < num_props; i++) { switch (obj_type) { case EX_ELEM_BLOCK: name = VAR_EB_PROP(i + 2); break; case EX_FACE_BLOCK: name = VAR_FA_PROP(i + 2); break; case EX_EDGE_BLOCK: name = VAR_ED_PROP(i + 2); break; case EX_NODE_SET: name = VAR_NS_PROP(i + 2); break; case EX_SIDE_SET: name = VAR_SS_PROP(i + 2); break; case EX_EDGE_SET: name = VAR_ES_PROP(i + 2); break; case EX_FACE_SET: name = VAR_FS_PROP(i + 2); break; case EX_ELEM_SET: name = VAR_ELS_PROP(i + 2); break; case EX_ELEM_MAP: name = VAR_EM_PROP(i + 2); break; case EX_FACE_MAP: name = VAR_FAM_PROP(i + 2); break; case EX_EDGE_MAP: name = VAR_EDM_PROP(i + 2); break; case EX_NODE_MAP: name = VAR_NM_PROP(i + 2); break; default: exerrval = EX_BADPARAM; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: object type %d not supported; file id %d", obj_type, exoid); ex_err("ex_put_prop_names", errmsg, exerrval); goto error_ret; /* Exit define mode and return */ } if ((status = nc_def_var(exoid, name, int_type, 1, dims, &propid)) != NC_NOERR) { exerrval = status; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to create property array variable in file id %d", exoid); ex_err("ex_put_prop_names", errmsg, exerrval); goto error_ret; /* Exit define mode and return */ } vals[0] = 0; /* fill value */ /* create attribute to cause variable to fill with zeros per routine spec */ if ((status = nc_put_att_longlong(exoid, propid, _FillValue, int_type, 1, vals)) != NC_NOERR) { exerrval = status; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to create property name fill attribute in file id %d", exoid); ex_err("ex_put_prop_names", errmsg, exerrval); goto error_ret; /* Exit define mode and return */ } /* Check that the property name length is less than MAX_NAME_LENGTH */ prop_name_len = strlen(prop_names[i]) + 1; if (prop_name_len > name_length) { fprintf(stderr, "Warning: The property name '%s' is too long.\n\tIt will " "be truncated from %d to %d characters\n", prop_names[i], (int)prop_name_len - 1, (int)name_length - 1); prop_name_len = name_length; } if (prop_name_len > max_name_len) { max_name_len = prop_name_len; } /* store property name as attribute of property array variable */ if ((status = nc_put_att_text(exoid, propid, ATT_PROP_NAME, prop_name_len, prop_names[i])) != NC_NOERR) { exerrval = status; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to store property name %s in file id %d", prop_names[i], exoid); ex_err("ex_put_prop_names", errmsg, exerrval); goto error_ret; /* Exit define mode and return */ } } /* leave define mode */ if ((status = nc_enddef(exoid)) != NC_NOERR) { exerrval = status; snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to leave define mode in file id %d", exoid); ex_err("ex_put_prop_names", errmsg, exerrval); return (EX_FATAL); } /* Update the maximum_name_length attribute on the file. */ ex_update_max_name_length(exoid, max_name_len - 1); nc_set_fill(exoid, oldfill, &temp); /* default: turn off fill */ return (EX_NOERR); /* Fatal error: exit definition mode and return */ error_ret: if (nc_enddef(exoid) != NC_NOERR) { /* exit define mode */ snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition for file id %d", exoid); ex_err("ex_put_prop_names", errmsg, exerrval); } return (EX_FATAL); }
int ex_put_prop_array(int exoid, ex_entity_type obj_type, const char *prop_name, const void_int *values) { int oldfill = 0; int temp; int num_props, i, propid, dimid, dims[1], status; int found = EX_FALSE; int int_type; size_t num_obj; char * name; char tmpstr[MAX_STR_LENGTH + 1]; char errmsg[MAX_ERR_LENGTH]; EX_FUNC_ENTER(); ex_check_valid_file_id(exoid, __func__); /* check if property has already been created */ num_props = ex_get_num_props(exoid, obj_type); /* inquire id of previously defined dimension (number of objects) */ status = ex_get_dimension(exoid, ex_dim_num_objects(obj_type), ex_name_of_object(obj_type), &num_obj, &dimid, __func__); if (status != NC_NOERR) { EX_FUNC_LEAVE(status); } for (i = 1; i <= num_props; i++) { switch (obj_type) { case EX_ELEM_BLOCK: name = VAR_EB_PROP(i); break; case EX_FACE_BLOCK: name = VAR_FA_PROP(i); break; case EX_EDGE_BLOCK: name = VAR_ED_PROP(i); break; case EX_NODE_SET: name = VAR_NS_PROP(i); break; case EX_EDGE_SET: name = VAR_ES_PROP(i); break; case EX_FACE_SET: name = VAR_FS_PROP(i); break; case EX_ELEM_SET: name = VAR_ELS_PROP(i); break; case EX_SIDE_SET: name = VAR_SS_PROP(i); break; case EX_ELEM_MAP: name = VAR_EM_PROP(i); break; case EX_FACE_MAP: name = VAR_FAM_PROP(i); break; case EX_EDGE_MAP: name = VAR_EDM_PROP(i); break; case EX_NODE_MAP: name = VAR_NM_PROP(i); break; default: snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: object type %d not supported; file id %d", obj_type, exoid); ex_err(__func__, errmsg, EX_BADPARAM); EX_FUNC_LEAVE(EX_FATAL); } if ((status = nc_inq_varid(exoid, name, &propid)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get property array id in file id %d", exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } /* compare stored attribute name with passed property name */ memset(tmpstr, 0, MAX_STR_LENGTH + 1); if ((status = nc_get_att_text(exoid, propid, ATT_PROP_NAME, tmpstr)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get property name in file id %d", exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } if (strcmp(tmpstr, prop_name) == 0) { found = EX_TRUE; break; } } /* if property array has not been created, create it */ if (!found) { /* put netcdf file into define mode */ if ((status = nc_redef(exoid)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode", exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } /* create a variable with a name xx_prop#, where # is the new number */ /* of properties */ switch (obj_type) { case EX_ELEM_BLOCK: name = VAR_EB_PROP(num_props + 1); break; case EX_FACE_BLOCK: name = VAR_FA_PROP(num_props + 1); break; case EX_EDGE_BLOCK: name = VAR_ED_PROP(num_props + 1); break; case EX_NODE_SET: name = VAR_NS_PROP(num_props + 1); break; case EX_EDGE_SET: name = VAR_ES_PROP(num_props + 1); break; case EX_FACE_SET: name = VAR_FS_PROP(num_props + 1); break; case EX_ELEM_SET: name = VAR_ELS_PROP(num_props + 1); break; case EX_SIDE_SET: name = VAR_SS_PROP(num_props + 1); break; case EX_ELEM_MAP: name = VAR_EM_PROP(num_props + 1); break; case EX_FACE_MAP: name = VAR_FAM_PROP(num_props + 1); break; case EX_EDGE_MAP: name = VAR_EDM_PROP(num_props + 1); break; case EX_NODE_MAP: name = VAR_NM_PROP(num_props + 1); break; default: snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: object type %d not supported; file id %d", obj_type, exoid); ex_err(__func__, errmsg, EX_BADPARAM); goto error_ret; /* Exit define mode and return */ } dims[0] = dimid; nc_set_fill(exoid, NC_FILL, &oldfill); /* fill with zeros per routine spec */ int_type = NC_INT; if (ex_int64_status(exoid) & EX_IDS_INT64_DB) { int_type = NC_INT64; } if ((status = nc_def_var(exoid, name, int_type, 1, dims, &propid)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to create property array variable in file id %d", exoid); ex_err(__func__, errmsg, status); goto error_ret; /* Exit define mode and return */ } nc_set_fill(exoid, oldfill, &temp); /* default: nofill */ /* store property name as attribute of property array variable */ if ((status = nc_put_att_text(exoid, propid, ATT_PROP_NAME, strlen(prop_name) + 1, prop_name)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to store property name %s in file id %d", prop_name, exoid); ex_err(__func__, errmsg, status); goto error_ret; /* Exit define mode and return */ } /* leave define mode */ if ((status = nc_enddef(exoid)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to leave define mode in file id %d", exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } } /* put num_obj values in property array */ if (ex_int64_status(exoid) & EX_IDS_INT64_API) { status = nc_put_var_longlong(exoid, propid, values); } else { status = nc_put_var_int(exoid, propid, values); } if (status != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to store property values in file id %d", exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } EX_FUNC_LEAVE(EX_NOERR); /* Fatal error: exit definition mode and return */ error_ret: nc_set_fill(exoid, oldfill, &temp); /* default: nofill */ if ((status = nc_enddef(exoid)) != NC_NOERR) { /* exit define mode */ snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition for file id %d", exoid); ex_err(__func__, errmsg, status); } EX_FUNC_LEAVE(EX_FATAL); }
int ex_open_int(const char *path, int mode, int *comp_ws, int *io_ws, float *version, int run_version) { int exoid; int status, stat_att, stat_dim; nc_type att_type = NC_NAT; size_t att_len = 0; int old_fill; int file_wordsize; int dim_str_name; int int64_status = 0; int nc_mode = 0; char errmsg[MAX_ERR_LENGTH]; EX_FUNC_ENTER(); /* set error handling mode to no messages, non-fatal errors */ ex_opts(exoptval); /* call required to set ncopts first time through */ if (run_version != EX_API_VERS_NODOT && warning_output == 0) { int run_version_major = run_version / 100; int run_version_minor = run_version % 100; int lib_version_major = EX_API_VERS_NODOT / 100; int lib_version_minor = EX_API_VERS_NODOT % 100; fprintf(stderr, "EXODUS: Warning: This code was compiled with exodus " "version %d.%02d,\n but was linked with exodus " "library version %d.%02d\n This is probably an " "error in the build process of this code.\n", run_version_major, run_version_minor, lib_version_major, lib_version_minor); warning_output = 1; } if ((mode & EX_READ) && (mode & EX_WRITE)) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Cannot specify both EX_READ and EX_WRITE"); ex_err(__func__, errmsg, EX_BADFILEMODE); EX_FUNC_LEAVE(EX_FATAL); } /* The EX_READ mode is the default if EX_WRITE is not specified... */ if (!(mode & EX_WRITE)) { /* READ ONLY */ nc_mode = NC_NOWRITE | NC_SHARE; #if NC_HAS_DISKLESS if (mode & EX_DISKLESS) { nc_mode |= NC_DISKLESS; } #endif if ((status = nc_open(path, nc_mode, &exoid)) != NC_NOERR) { /* NOTE: netCDF returns an id of -1 on an error - but no error code! */ /* It is possible that the user is trying to open a netcdf4 file, but the netcdf4 capabilities aren't available in the netcdf linked to this library. Note that we can't just use a compile-time define since we could be using a shareable netcdf library, so the netcdf4 capabilities aren't known until runtime... Later versions of netcdf-4.X have a function that can be queried to determine whether the library being used was compiled with --enable-netcdf4, but not everyone is using that version yet, so we may have to do some guessing... At this time, query the beginning of the file and see if it is an HDF-5 file and if it is assume that the open failure is due to the netcdf library not enabling netcdf4 features unless we have the define that shows it is enabled, then assume other error... */ int type = 0; ex_check_file_type(path, &type); if (type == 5) { #if NC_HAS_HDF5 fprintf(stderr, "EXODUS: ERROR: Attempting to open the netcdf-4 " "file:\n\t'%s'\n\t failed. The netcdf library supports " "netcdf-4 so there must be a filesystem or some other " "issue \n", path); #else /* This is an hdf5 (netcdf4) file. If NC_HAS_HDF5 is not defined, then we either don't have hdf5 support in this netcdf version, OR this is an older netcdf version that doesn't provide that define. In either case, we don't have enough information, so we assume that the netcdf doesn't have netcdf4 capabilities enabled. Tell the user... */ fprintf(stderr, "EXODUS: ERROR: Attempting to open the netcdf-4 " "file:\n\t'%s'\n\t. Either the netcdf library does not " "support netcdf-4 or there is a filesystem or some " "other issue \n", path); #endif } else if (type == 4) { #if defined(NC_64BIT_DATA) fprintf(stderr, "EXODUS: ERROR: Attempting to open the CDF5 " "file:\n\t'%s'\n\t failed. The netcdf library supports " "CDF5-type files so there must be a filesystem or some other " "issue \n", path); #else /* This is an cdf5 (64BIT_DATA) file. If NC_64BIT_DATA is not defined, then we either don't have cdf5 support in this netcdf version, OR this is an older netcdf version that doesn't provide that define. In either case, we don't have enough information, so we assume that the netcdf doesn't have cdf5 capabilities enabled. Tell the user... */ fprintf(stderr, "EXODUS: ERROR: Attempting to open the CDF5 " "file:\n\t'%s'\n\t. Either the netcdf library does not " "support CDF5 or there is a filesystem or some " "other issue \n", path); #endif } snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to open %s read only", path); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } } else { /* (mode & EX_WRITE) READ/WRITE */ nc_mode = NC_WRITE | NC_SHARE; #if NC_HAS_DISKLESS if (mode & EX_DISKLESS) { nc_mode |= NC_DISKLESS; } #endif if ((status = nc_open(path, nc_mode, &exoid)) != NC_NOERR) { /* NOTE: netCDF returns an id of -1 on an error - but no error code! */ snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to open %s write only", path); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } /* turn off automatic filling of netCDF variables */ if ((status = nc_set_fill(exoid, NC_NOFILL, &old_fill)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to set nofill mode in file id %d", exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } stat_att = nc_inq_att(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, &att_type, &att_len); stat_dim = nc_inq_dimid(exoid, DIM_STR_NAME, &dim_str_name); if (stat_att != NC_NOERR || stat_dim != NC_NOERR) { if ((status = nc_redef(exoid)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to place file id %d into define mode", exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } if (stat_att != NC_NOERR) { int max_so_far = 32; nc_put_att_int(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, NC_INT, 1, &max_so_far); } /* If the DIM_STR_NAME variable does not exist on the database, we need to * add it now. */ if (stat_dim != NC_NOERR) { /* Not found; set to default value of 32+1. */ int max_name = ex_default_max_name_length < 32 ? 32 : ex_default_max_name_length; if ((status = nc_def_dim(exoid, DIM_STR_NAME, max_name + 1, &dim_str_name)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define string name dimension in file id %d", exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } } if ((status = nc_enddef(exoid)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition in file id %d", exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } } } /* determine version of EXODUS file, and the word size of * floating point and integer values stored in the file */ if ((status = nc_get_att_float(exoid, NC_GLOBAL, ATT_VERSION, version)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get database version for file id: %d", exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } /* check ExodusII file version - old version 1.x files are not supported */ if (*version < 2.0) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: Unsupported file version %.2f in file id: %d", *version, exoid); ex_err(__func__, errmsg, EX_BADPARAM); EX_FUNC_LEAVE(EX_FATAL); } if (nc_get_att_int(exoid, NC_GLOBAL, ATT_FLT_WORDSIZE, &file_wordsize) != NC_NOERR) { /* try old (prior to db version 2.02) attribute name */ if ((status = nc_get_att_int(exoid, NC_GLOBAL, ATT_FLT_WORDSIZE_BLANK, &file_wordsize)) != NC_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get file wordsize from file id: %d", exoid); ex_err(__func__, errmsg, status); EX_FUNC_LEAVE(EX_FATAL); } } /* See if int64 status attribute exists and if so, what data is stored as * int64 * Older files don't have the attribute, so it is not an error if it is * missing */ if (nc_get_att_int(exoid, NC_GLOBAL, ATT_INT64_STATUS, &int64_status) != NC_NOERR) { int64_status = 0; /* Just in case it gets munged by a failed get_att_int call */ } /* Merge in API int64 status flags as specified by caller of function... */ int64_status |= (mode & EX_ALL_INT64_API); /* Verify that there is not an existing file_item struct for this exoid This could happen (and has) when application calls ex_open(), but then closes file using nc_close() and then reopens file. NetCDF will possibly reuse the exoid which results in internal corruption in exodus data structures since exodus does not know that file was closed and possibly new file opened for this exoid */ if (ex_find_file_item(exoid) != NULL) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: There is an existing file already using the file " "id %d which was also assigned to file %s.\n\tWas " "nc_close() called instead of ex_close() on an open Exodus " "file?\n", exoid, path); ex_err(__func__, errmsg, EX_BADFILEID); nc_close(exoid); EX_FUNC_LEAVE(EX_FATAL); } /* initialize floating point and integer size conversion. */ if (ex_conv_ini(exoid, comp_ws, io_ws, file_wordsize, int64_status, 0, 0, 0) != EX_NOERR) { snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to initialize conversion routines in file id %d", exoid); ex_err(__func__, errmsg, EX_LASTERR); EX_FUNC_LEAVE(EX_FATAL); } EX_FUNC_LEAVE(exoid); }
bool CNetCDFTraj::WriteHeader(CAmberTopology* p_top) { if( p_top == NULL ){ INVALID_ARGUMENT("p_top == NULL"); } if( NCID < 0 ) { ES_ERROR("file is not opened"); return(false); } int dimensionID[NC_MAX_VAR_DIMS]; NumOfTopologyAtoms = p_top->AtomList.GetNumberOfAtoms(); ActualAtoms = NumOfTopologyAtoms; CurrentSnapshot = 0; TotalSnapshots = 0; if( Coordinates != NULL ) { delete Coordinates; } Coordinates = new float[ActualAtoms*3]; // global dimmensions DefineDimension(AMBER_NETCDF_FRAME, NC_UNLIMITED, &TimeDID); DefineDimension(AMBER_NETCDF_SPATIAL, 3, &SpatialDID); DefineDimension(AMBER_NETCDF_ATOM, ActualAtoms, &CoordinateDID); DefineDimension(AMBER_NETCDF_LABEL, AMBER_NETCDF_LABELLEN, &LabelDID); DefineDimension(AMBER_NETCDF_CELL_SPATIAL, 3, &CellSpatialDID); DefineDimension(AMBER_NETCDF_CELL_ANGULAR, 3, &CellAngularDID); // put global attributes Conventions = "AMBER"; ConventionVersion = "1.0"; PutAttributeText(NC_GLOBAL, "title", Title); PutAttributeText(NC_GLOBAL, "application", Application); PutAttributeText(NC_GLOBAL, "program", Program); PutAttributeText(NC_GLOBAL, "programVersion", Version); PutAttributeText(NC_GLOBAL, "Conventions", Conventions); PutAttributeText(NC_GLOBAL, "ConventionVersion", ConventionVersion); // handle definition of non-optional variables dimensionID[0] = SpatialDID; DefineVariable(AMBER_NETCDF_SPATIAL, NC_CHAR, 1, dimensionID, &SpatialVID); dimensionID[0] = TimeDID; DefineVariable(AMBER_NETCDF_TIME, NC_FLOAT, 1, dimensionID, &TimeVID); PutAttributeText(TimeVID, "units", "picosecond"); dimensionID[0] = TimeDID; dimensionID[1] = CoordinateDID; dimensionID[2] = SpatialDID; DefineVariable(AMBER_NETCDF_COORDS, NC_FLOAT, 3, dimensionID, &CoordinateVID); PutAttributeText(CoordinateVID, "units", "angstrom"); dimensionID[0] = CellSpatialDID; DefineVariable(AMBER_NETCDF_CELL_SPATIAL, NC_CHAR, 1, dimensionID, &CellSpatialVID); dimensionID[0] = CellAngularDID; dimensionID[1] = LabelDID; DefineVariable(AMBER_NETCDF_CELL_ANGULAR, NC_CHAR, 2, dimensionID, &CellAngularVID); // set up box coords HasBox = p_top->BoxInfo.GetType() != AMBER_BOX_NONE; if( HasBox ) { dimensionID[0] = TimeDID; dimensionID[1] = CellSpatialDID; DefineVariable("cell_lengths", NC_DOUBLE, 2, dimensionID, &CellLengthVID); PutAttributeText(CellLengthVID, "units", "angstrom"); dimensionID[1] = CellAngularDID; DefineVariable("cell_angles", NC_DOUBLE, 2, dimensionID, &CellAngleVID); PutAttributeText(CellAngleVID, "units", "degree"); } int err,oldMode; // set fill mode err = nc_set_fill(NCID, NC_NOFILL, &oldMode); if (err != NC_NOERR) { CSmallString error; error << "unable to set fill value (" << nc_strerror(err) << ")"; ES_ERROR(error); return(false); } // end definition err = nc_enddef(NCID); if (err != NC_NOERR) { CSmallString error; error << "unable to end definitions (" << nc_strerror(err) << ")"; ES_ERROR(error); return(false); } size_t start[3]; size_t count[3]; char xyz[3]; char abc[15] = { 'a', 'l', 'p', 'h', 'a', 'b', 'e', 't', 'a', ' ', 'g', 'a', 'm', 'm', 'a' }; // setup labels start[0] = 0; count[0] = 3; xyz[0] = 'x'; xyz[1] = 'y'; xyz[2] = 'z'; err = nc_put_vara_text(NCID, SpatialVID, start, count, xyz); if (err != NC_NOERR) { CSmallString error; error << "unable to set spatial VID 'x', 'y' and 'z' (" << nc_strerror(err) << ")"; ES_ERROR(error); return(false); } start[0] = 0; count[0] = 3; xyz[0] = 'a'; xyz[1] = 'b'; xyz[2] = 'c'; err = nc_put_vara_text(NCID, CellSpatialVID, start, count, xyz); if (err != NC_NOERR) { CSmallString error; error << "unable to set spatial cell VID 'a', 'b' and 'c' (" << nc_strerror(err) << ")"; ES_ERROR(error); return(false); } start[0] = 0; start[1] = 0; count[0] = 3; count[1] = 5; err = nc_put_vara_text(NCID, CellAngularVID, start, count, abc); if (err != NC_NOERR) { CSmallString error; error << "unable to set angular cell VID 'alpha', 'beta ' and 'gamma' (" << nc_strerror(err) << ")"; ES_ERROR(error); return(false); } return(true); }
/*! Main function for tst_fill_attr_vanish.c * */ int main() { int ncid, dimids[RANK_P], time_id, p_id, test_id; int ndims, dimids_in[RANK_P]; int test_data[1] = {1}; size_t test_start[1] = {0}, test_count[1] = {1}; int test_fill_val[] = {5}; double data[1] = {3.14159}; size_t start[1] = {0}, count[1] = {1}; float ddata[1][4][3]; static float P_data[LEN]; size_t cor[RANK_P] = {0, 1, 0}; size_t edg[RANK_P] = {1, 1, LEN}; float pfills[] = {3}; printf("\n*** Testing for a netCDF-4 fill-value bug.\n"); printf("*** Creating a file with no _FillValue defined. ***\n"); /* Create a 3D test file. */ if (nc_create(FILENAME, NC_CLOBBER|NC_NETCDF4, &ncid)) ERR; if (nc_set_fill(ncid, NC_NOFILL, NULL)) ERR; /* define dimensions */ if (nc_def_dim(ncid, "Time", NC_UNLIMITED, &dimids[0])) ERR; if (nc_def_dim(ncid, "X", 4, &dimids[2])) ERR; if (nc_def_dim(ncid, "Y", 3, &dimids[1])) ERR; /* define variables */ if (nc_def_var(ncid, "Time", NC_DOUBLE, 1, dimids, &time_id)) ERR; if (nc_def_var(ncid, "P", NC_FLOAT, RANK_P, dimids, &p_id)) ERR; if (nc_def_var(ncid, "Test", NC_INT, 1, &dimids[1], &test_id)) ERR; /* Add a _FillValue attribute */ if (nc_put_att_text(ncid, test_id, ATTNAME, strlen(ATTVAL), ATTVAL)) ERR; /* Add a value to the test variable */ if (nc_put_vara(ncid, test_id, test_start, test_count, test_data)) ERR; /* Add one record in coordinate variable. */ if (nc_put_vara(ncid, time_id, start, count, data)) ERR; /* That's it! */ if (nc_close(ncid)) ERR; /********************************************/ /* Reopen the file, add a fillvalue attribute. */ if (nc_open(FILENAME, NC_NOCLOBBER|NC_WRITE, &ncid)) ERR; if (nc_redef(ncid)) ERR; if (nc_inq_varid(ncid, "Test", &test_id)) ERR; /* Query existing attribute. */ { printf("**** Checking that attribute still exists:\t"); char *attval = malloc(sizeof(char) * strlen(ATTVAL)); if(nc_get_att_text(ncid,test_id,ATTNAME,attval)) {printf("Fail\n"); ERR;} else {printf("%s\n",attval);} free(attval); } printf("**** Adding _FillValue attribute.\n"); if (nc_put_att_int(ncid, test_id, "_FillValue", NC_INT, 1, test_fill_val)) ERR; /* Query existing attribute. */ { printf("**** Checking that attribute still exists, pre-write:\t"); char *attval = malloc(sizeof(char) * strlen(ATTVAL)); if(nc_get_att_text(ncid,test_id,ATTNAME,attval)) {printf("Fail\n"); ERR;} else {printf("%s\n",attval);} free(attval); } /* Close file again. */ printf( "**** Saving, closing file.\n"); if (nc_close(ncid)) ERR; /********************************************/ printf( "*** Reopening file.\n"); /* Reopen the file, checking that all attributes are preserved. */ if (nc_open(FILENAME, NC_NOCLOBBER|NC_WRITE, &ncid)) ERR; if (nc_redef(ncid)) ERR; if (nc_inq_varid(ncid, "Test", &test_id)) ERR; /* Query existing attribute. */ { printf("**** Checking that attribute still exists:\t"); char *attval = malloc(sizeof(char) * strlen(ATTVAL)); if(nc_get_att_text(ncid,test_id,ATTNAME,attval)) {printf("Fail\n"); ERR;} else {printf("%s\n",attval);} free(attval); } if (nc_close(ncid)) ERR; /********************************************/ SUMMARIZE_ERR; FINAL_RESULTS; return 0; }
int ex_open_int (const char *path, int mode, int *comp_ws, int *io_ws, float *version, int run_version) { int exoid; int status, stat_att, stat_dim; nc_type att_type = NC_NAT; size_t att_len = 0; int old_fill; int file_wordsize; int dim_str_name; int int64_status = 0; char errmsg[MAX_ERR_LENGTH]; exerrval = 0; /* clear error code */ /* set error handling mode to no messages, non-fatal errors */ ex_opts(exoptval); /* call required to set ncopts first time through */ if (run_version != EX_API_VERS_NODOT && warning_output == 0) { int run_version_major = run_version / 100; int run_version_minor = run_version % 100; int lib_version_major = EX_API_VERS_NODOT / 100; int lib_version_minor = EX_API_VERS_NODOT % 100; fprintf(stderr, "EXODUS: Warning: This code was compiled with exodus version %d.%02d,\n but was linked with exodus library version %d.%02d\n This is probably an error in the build process of this code.\n", run_version_major, run_version_minor, lib_version_major, lib_version_minor); warning_output = 1; } if ((mode & EX_READ) && (mode & EX_WRITE)) { exerrval = EX_BADFILEMODE; sprintf(errmsg,"Error: Cannot specify both EX_READ and EX_WRITE"); ex_err("ex_open",errmsg,exerrval); return (EX_FATAL); } /* The EX_READ mode is the default if EX_WRITE is not specified... */ if (!(mode & EX_WRITE)) { /* READ ONLY */ #if defined(__LIBCATAMOUNT__) if ((status = nc_open (path, NC_NOWRITE, &exoid)) != NC_NOERR) #else if ((status = nc_open (path, NC_NOWRITE|NC_SHARE, &exoid)) != NC_NOERR) #endif { /* NOTE: netCDF returns an id of -1 on an error - but no error code! */ if (status == 0) { exerrval = EX_FATAL; } else { /* It is possible that the user is trying to open a netcdf4 file, but the netcdf4 capabilities aren't available in the netcdf linked to this library. Note that we can't just use a compile-time define since we could be using a shareable netcdf library, so the netcdf4 capabilities aren't known until runtime... Netcdf-4.X does not (yet?) have a function that can be queried to determine whether the library being used was compiled with --enable-netcdf4, so that isn't very helpful.. At this time, query the beginning of the file and see if it is an HDF-5 file and if it is assume that the open failure is due to the netcdf library not enabling netcdf4 features... */ int type = 0; ex_check_file_type(path, &type); if (type == 5) { /* This is an hdf5 (netcdf4) file. Since the nc_open failed, the assumption is that the netcdf doesn't have netcdf4 capabilities enabled. Tell the user... */ fprintf(stderr, "EXODUS: Error: Attempting to open the netcdf-4 file:\n\t'%s'\n\twith a netcdf library that does not support netcdf-4\n", path); } exerrval = status; } sprintf(errmsg,"Error: failed to open %s read only",path); ex_err("ex_open",errmsg,exerrval); return(EX_FATAL); } } else /* (mode & EX_WRITE) READ/WRITE */ { #if defined(__LIBCATAMOUNT__) if ((status = nc_open (path, NC_WRITE, &exoid)) != NC_NOERR) #else if ((status = nc_open (path, NC_WRITE|NC_SHARE, &exoid)) != NC_NOERR) #endif { /* NOTE: netCDF returns an id of -1 on an error - but no error code! */ if (status == 0) exerrval = EX_FATAL; else exerrval = status; sprintf(errmsg,"Error: failed to open %s write only",path); ex_err("ex_open",errmsg,exerrval); return(EX_FATAL); } /* turn off automatic filling of netCDF variables */ if ((status = nc_set_fill (exoid, NC_NOFILL, &old_fill)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to set nofill mode in file id %d", exoid); ex_err("ex_open", errmsg, exerrval); return (EX_FATAL); } stat_att = nc_inq_att(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, &att_type, &att_len); stat_dim = nc_inq_dimid(exoid, DIM_STR_NAME, &dim_str_name); if(stat_att != NC_NOERR || stat_dim != NC_NOERR) { nc_redef(exoid); if (stat_att != NC_NOERR) { int max_so_far = 32; nc_put_att_int(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, NC_INT, 1, &max_so_far); } /* If the DIM_STR_NAME variable does not exist on the database, we need to add it now. */ if(stat_dim != NC_NOERR) { /* Not found; set to default value of 32+1. */ int max_name = ex_default_max_name_length < 32 ? 32 : ex_default_max_name_length; nc_def_dim(exoid, DIM_STR_NAME, max_name+1, &dim_str_name); } nc_enddef (exoid); } } /* determine version of EXODUS II file, and the word size of * floating point and integer values stored in the file */ if ((status = nc_get_att_float(exoid, NC_GLOBAL, ATT_VERSION, version)) != NC_NOERR) { exerrval = status; sprintf(errmsg,"Error: failed to get database version for file id: %d", exoid); ex_err("ex_open",errmsg,exerrval); return(EX_FATAL); } /* check ExodusII file version - old version 1.x files are not supported */ if (*version < 2.0) { exerrval = EX_FATAL; sprintf(errmsg,"Error: Unsupported file version %.2f in file id: %d", *version, exoid); ex_err("ex_open",errmsg,exerrval); return(EX_FATAL); } if (nc_get_att_int (exoid, NC_GLOBAL, ATT_FLT_WORDSIZE, &file_wordsize) != NC_NOERR) { /* try old (prior to db version 2.02) attribute name */ if (nc_get_att_int (exoid,NC_GLOBAL,ATT_FLT_WORDSIZE_BLANK,&file_wordsize) != NC_NOERR) { exerrval = EX_FATAL; sprintf(errmsg,"Error: failed to get file wordsize from file id: %d", exoid); ex_err("ex_open",errmsg,exerrval); return(exerrval); } } /* See if int64 status attribute exists and if so, what data is stored as int64 * Older files don't have the attribute, so it is not an error if it is missing */ if (nc_get_att_int (exoid, NC_GLOBAL, ATT_INT64_STATUS, &int64_status) != NC_NOERR) { int64_status = 0; /* Just in case it gets munged by a failed get_att_int call */ } /* Merge in API int64 status flags as specified by caller of function... */ int64_status |= (mode & EX_ALL_INT64_API); /* initialize floating point and integer size conversion. */ if (ex_conv_ini( exoid, comp_ws, io_ws, file_wordsize, int64_status ) != EX_NOERR ) { exerrval = EX_FATAL; sprintf(errmsg, "Error: failed to initialize conversion routines in file id %d", exoid); ex_err("ex_open", errmsg, exerrval); return (EX_FATAL); } return (exoid); }
int create_file(char *file_name, int fill_mode, size_t* sizehintp) { int i; int stat; /* return status */ int ncid; /* netCDF id */ /* dimension ids */ int lon_dim; int lat_dim; int lvl_dim; int time_dim; /* dimension lengths */ size_t lon_len = LON_LEN; size_t lat_len = LAT_LEN; size_t lvl_len = LVL_LEN; size_t time_len = TIME_LEN; /* variable ids */ int time_id; int lat_id; int lon_id; int lvl_id; int sfc_pres_id; int temp_scrn_id; int qsair_scrn_id; int topog_id; int mslp_id; int sfc_temp_id; int zonal_wnd_id; /* rank (number of dimensions) for each variable */ # define RANK_time 1 # define RANK_lat 1 # define RANK_lon 1 # define RANK_lvl 1 # define RANK_sfc_pres 3 # define RANK_temp_scrn 3 # define RANK_qsair_scrn 3 # define RANK_topog 3 # define RANK_mslp 3 # define RANK_sfc_temp 3 # define RANK_zonal_wnd 4 /* variable shapes */ int time_dims[RANK_time]; int lat_dims[RANK_lat]; int lon_dims[RANK_lon]; int lvl_dims[RANK_lvl]; int sfc_pres_dims[RANK_sfc_pres]; int temp_scrn_dims[RANK_temp_scrn]; int qsair_scrn_dims[RANK_qsair_scrn]; int topog_dims[RANK_topog]; int mslp_dims[RANK_mslp]; int sfc_temp_dims[RANK_sfc_temp]; int zonal_wnd_dims[RANK_zonal_wnd]; size_t zonal_wnd_start[RANK_zonal_wnd]; size_t zonal_wnd_count[RANK_zonal_wnd]; float zonal_wnd[LON_LEN*LAT_LEN*TIME_LEN]; int ii; int old_fill_mode; size_t default_initialsize = 0; /* To test bug on filesystem without large block size, we can get * the same effect by providing the desired value as sizehint to * nc__create() instead of calling nc_create() and getting the * block size reported by fstat */ stat = nc__create(file_name, NC_CLOBBER, default_initialsize, sizehintp, &ncid); check_err(stat,__LINE__,__FILE__); stat = nc_set_fill(ncid, fill_mode, &old_fill_mode); check_err(stat,__LINE__,__FILE__); /* define dimensions */ stat = nc_def_dim(ncid, "lon", lon_len, &lon_dim); check_err(stat,__LINE__,__FILE__); stat = nc_def_dim(ncid, "lat", lat_len, &lat_dim); check_err(stat,__LINE__,__FILE__); stat = nc_def_dim(ncid, "lvl", lvl_len, &lvl_dim); check_err(stat,__LINE__,__FILE__); stat = nc_def_dim(ncid, "time", time_len, &time_dim); check_err(stat,__LINE__,__FILE__); /* define variables */ time_dims[0] = time_dim; stat = nc_def_var(ncid, "time", NC_DOUBLE, RANK_time, time_dims, &time_id); check_err(stat,__LINE__,__FILE__); lat_dims[0] = lat_dim; stat = nc_def_var(ncid, "lat", NC_FLOAT, RANK_lat, lat_dims, &lat_id); check_err(stat,__LINE__,__FILE__); lon_dims[0] = lon_dim; stat = nc_def_var(ncid, "lon", NC_FLOAT, RANK_lon, lon_dims, &lon_id); check_err(stat,__LINE__,__FILE__); lvl_dims[0] = lvl_dim; stat = nc_def_var(ncid, "lvl", NC_FLOAT, RANK_lvl, lvl_dims, &lvl_id); check_err(stat,__LINE__,__FILE__); sfc_pres_dims[0] = time_dim; sfc_pres_dims[1] = lat_dim; sfc_pres_dims[2] = lon_dim; stat = nc_def_var(ncid, "sfc_pres", NC_FLOAT, RANK_sfc_pres, sfc_pres_dims, &sfc_pres_id); check_err(stat,__LINE__,__FILE__); temp_scrn_dims[0] = time_dim; temp_scrn_dims[1] = lat_dim; temp_scrn_dims[2] = lon_dim; stat = nc_def_var(ncid, "temp_scrn", NC_FLOAT, RANK_temp_scrn, temp_scrn_dims, &temp_scrn_id); check_err(stat,__LINE__,__FILE__); qsair_scrn_dims[0] = time_dim; qsair_scrn_dims[1] = lat_dim; qsair_scrn_dims[2] = lon_dim; stat = nc_def_var(ncid, "qsair_scrn", NC_FLOAT, RANK_qsair_scrn, qsair_scrn_dims, &qsair_scrn_id); check_err(stat,__LINE__,__FILE__); topog_dims[0] = time_dim; topog_dims[1] = lat_dim; topog_dims[2] = lon_dim; stat = nc_def_var(ncid, "topog", NC_FLOAT, RANK_topog, topog_dims, &topog_id); check_err(stat,__LINE__,__FILE__); mslp_dims[0] = time_dim; mslp_dims[1] = lat_dim; mslp_dims[2] = lon_dim; stat = nc_def_var(ncid, "mslp", NC_FLOAT, RANK_mslp, mslp_dims, &mslp_id); check_err(stat,__LINE__,__FILE__); sfc_temp_dims[0] = time_dim; sfc_temp_dims[1] = lat_dim; sfc_temp_dims[2] = lon_dim; stat = nc_def_var(ncid, "sfc_temp", NC_FLOAT, RANK_sfc_temp, sfc_temp_dims, &sfc_temp_id); check_err(stat,__LINE__,__FILE__); zonal_wnd_dims[0] = time_dim; zonal_wnd_dims[1] = lvl_dim; zonal_wnd_dims[2] = lat_dim; zonal_wnd_dims[3] = lon_dim; stat = nc_def_var(ncid, "zonal_wnd", NC_FLOAT, RANK_zonal_wnd, zonal_wnd_dims, &zonal_wnd_id); check_err(stat,__LINE__,__FILE__); /* leave define mode */ stat = nc_enddef (ncid); check_err(stat,__LINE__,__FILE__); { /* store time */ size_t time_start[RANK_time]; size_t time_count[RANK_time]; double time[TIME_LEN] = {1.}; time_len = 1; time_start[0] = 0; time_count[0] = time_len; stat = nc_put_vara_double(ncid, time_id, time_start, time_count, time); check_err(stat,__LINE__,__FILE__); } { /* store lat */ float lat[] = {90, 88.5, 87, 85.5, 84, 82.5, 81, 79.5, 78, 76.5, 75, 73.5, 72, 70.5, 69, 67.5, 66, 64.5, 63, 61.5, 60, 58.5, 57, 55.5, 54, 52.5, 51, 49.5, 48, 46.5, 45, 43.5, 42, 40.5, 39, 37.5, 36, 34.5, 33, 31.5, 30, 28.5, 27, 25.5, 24, 22.5, 21, 19.5, 18, 16.5, 15, 13.5, 12, 10.5, 9, 7.5, 6, 4.5, 3, 1.5, 0, -1.5, -3, -4.5, -6, -7.5, -9, -10.5, -12, -13.5, -15, -16.5, -18, -19.5, -21, -22.5, -24, -25.5, -27, -28.5, -30, -31.5, -33, -34.5, -36, -37.5, -39, -40.5, -42, -43.5, -45, -46.5, -48, -49.5, -51, -52.5, -54, -55.5, -57, -58.5, -60, -61.5, -63, -64.5, -66, -67.5, -69, -70.5, -72, -73.5, -75, -76.5, -78, -79.5, -81, -82.5, -84, -85.5, -87, -88.5, -90}; stat = nc_put_var_float(ncid, lat_id, lat); check_err(stat,__LINE__,__FILE__); } { /* store lon */ float lon[] = {0, 1.5, 3, 4.5, 6, 7.5, 9, 10.5, 12, 13.5, 15, 16.5, 18, 19.5, 21, 22.5, 24, 25.5, 27, 28.5, 30, 31.5, 33, 34.5, 36, 37.5, 39, 40.5, 42, 43.5, 45, 46.5, 48, 49.5, 51, 52.5, 54, 55.5, 57, 58.5, 60, 61.5, 63, 64.5, 66, 67.5, 69, 70.5, 72, 73.5, 75, 76.5, 78, 79.5, 81, 82.5, 84, 85.5, 87, 88.5, 90, 91.5, 93, 94.5, 96, 97.5, 99, 100.5, 102, 103.5, 105, 106.5, 108, 109.5, 111, 112.5, 114, 115.5, 117, 118.5, 120, 121.5, 123, 124.5, 126, 127.5, 129, 130.5, 132, 133.5, 135, 136.5, 138, 139.5, 141, 142.5, 144, 145.5, 147, 148.5, 150, 151.5, 153, 154.5, 156, 157.5, 159, 160.5, 162, 163.5, 165, 166.5, 168, 169.5, 171, 172.5, 174, 175.5, 177, 178.5, 180, 181.5, 183, 184.5, 186, 187.5, 189, 190.5, 192, 193.5, 195, 196.5, 198, 199.5, 201, 202.5, 204, 205.5, 207, 208.5, 210, 211.5, 213, 214.5, 216, 217.5, 219, 220.5, 222, 223.5, 225, 226.5, 228, 229.5, 231, 232.5, 234, 235.5, 237, 238.5, 240, 241.5, 243, 244.5, 246, 247.5, 249, 250.5, 252, 253.5, 255, 256.5, 258, 259.5, 261, 262.5, 264, 265.5, 267, 268.5, 270, 271.5, 273, 274.5, 276, 277.5, 279, 280.5, 282, 283.5, 285, 286.5, 288, 289.5, 291, 292.5, 294, 295.5, 297, 298.5, 300, 301.5, 303, 304.5, 306, 307.5, 309, 310.5, 312, 313.5, 315, 316.5, 318, 319.5, 321, 322.5, 324, 325.5, 327, 328.5, 330, 331.5, 333, 334.5, 336, 337.5, 339, 340.5, 342, 343.5, 345, 346.5, 348, 349.5, 351, 352.5, 354, 355.5, 357, 358.5}; stat = nc_put_var_float(ncid, lon_id, lon); check_err(stat,__LINE__,__FILE__); } { /* store lvl */ float lvl[] = {1000, 995, 990, 985, 975, 950, 925, 900, 875, 850, 800, 750, 700, 600, 500, 450, 400, 350, 300, 275, 250, 225, 200, 175, 150, 100, 70, 50, 30, 20, 10}; stat = nc_put_var_float(ncid, lvl_id, lvl); check_err(stat,__LINE__,__FILE__); } { /* store sfc_pres */ size_t sfc_pres_start[RANK_sfc_pres]; size_t sfc_pres_count[RANK_sfc_pres]; float sfc_pres[LON_LEN*LAT_LEN]; for(ii = 0; ii < LAT_LEN * LON_LEN; ii++) { sfc_pres[ii] = 6; } sfc_pres_start[0] = 0; sfc_pres_start[1] = 0; sfc_pres_start[2] = 0; sfc_pres_count[0] = time_len; sfc_pres_count[1] = lat_len; sfc_pres_count[2] = lon_len; stat = nc_put_vara_float(ncid, sfc_pres_id, sfc_pres_start, sfc_pres_count, sfc_pres); check_err(stat,__LINE__,__FILE__); } { /* store temp_scrn */ size_t temp_scrn_start[RANK_temp_scrn]; size_t temp_scrn_count[RANK_temp_scrn]; float temp_scrn[LON_LEN*LAT_LEN]; for(ii = 0; ii < LAT_LEN * LON_LEN; ii++) { temp_scrn[ii] = 11; } temp_scrn_start[0] = 0; temp_scrn_start[1] = 0; temp_scrn_start[2] = 0; temp_scrn_count[0] = time_len; temp_scrn_count[1] = lat_len; temp_scrn_count[2] = lon_len; stat = nc_put_vara_float(ncid, temp_scrn_id, temp_scrn_start, temp_scrn_count, temp_scrn); check_err(stat,__LINE__,__FILE__); } { /* store qsair_scrn */ size_t qsair_scrn_start[RANK_qsair_scrn]; size_t qsair_scrn_count[RANK_qsair_scrn]; float qsair_scrn[LON_LEN*LAT_LEN]; for(ii = 0; ii < LAT_LEN * LON_LEN; ii++) { qsair_scrn[ii] = 22; } qsair_scrn_start[0] = 0; qsair_scrn_start[1] = 0; qsair_scrn_start[2] = 0; qsair_scrn_count[0] = time_len; qsair_scrn_count[1] = lat_len; qsair_scrn_count[2] = lon_len; stat = nc_put_vara_float(ncid, qsair_scrn_id, qsair_scrn_start, qsair_scrn_count, qsair_scrn); check_err(stat,__LINE__,__FILE__); } { /* store topog */ size_t topog_start[RANK_topog]; size_t topog_count[RANK_topog]; float topog[LON_LEN*LAT_LEN]; for(ii = 0; ii < LAT_LEN * LON_LEN; ii++) { topog[ii] = 33; } topog_start[0] = 0; topog_start[1] = 0; topog_start[2] = 0; topog_count[0] = time_len; topog_count[1] = lat_len; topog_count[2] = lon_len; stat = nc_put_vara_float(ncid, topog_id, topog_start, topog_count, topog); check_err(stat,__LINE__,__FILE__); } { /* store mslp */ size_t mslp_start[RANK_mslp]; size_t mslp_count[RANK_mslp]; float mslp[LON_LEN*LAT_LEN]; for(ii = 0; ii < LAT_LEN * LON_LEN; ii++) { mslp[ii] = 44; } mslp_start[0] = 0; mslp_start[1] = 0; mslp_start[2] = 0; mslp_count[0] = time_len; mslp_count[1] = lat_len; mslp_count[2] = lon_len; stat = nc_put_vara_float(ncid, mslp_id, mslp_start, mslp_count, mslp); check_err(stat,__LINE__,__FILE__); } { /* store sfc_temp */ size_t sfc_temp_start[RANK_sfc_temp]; size_t sfc_temp_count[RANK_sfc_temp]; float sfc_temp[LON_LEN*LAT_LEN]; for(ii = 0; ii < LAT_LEN * LON_LEN; ii++) { sfc_temp[ii] = 55; } sfc_temp_start[0] = 0; sfc_temp_start[1] = 0; sfc_temp_start[2] = 0; sfc_temp_count[0] = time_len; sfc_temp_count[1] = lat_len; sfc_temp_count[2] = lon_len; stat = nc_put_vara_float(ncid, sfc_temp_id, sfc_temp_start, sfc_temp_count, sfc_temp); check_err(stat,__LINE__,__FILE__); } { /* store zonal_wnd */ /* Bug exposed when written in reverse order. */ for(i = LVL_LEN - 1; i>=0; i--) /* for(i = 0; i < LVL_LEN; i++) */ { int izw; for(izw = 0; izw < TIME_LEN * LAT_LEN * LON_LEN; izw++) { zonal_wnd[izw] = 100 + i; } zonal_wnd_start[0] = 0; zonal_wnd_start[1] = i; zonal_wnd_start[2] = 0; zonal_wnd_start[3] = 0; zonal_wnd_count[0] = time_len; zonal_wnd_count[1] = 1; zonal_wnd_count[2] = lat_len; zonal_wnd_count[3] = lon_len; stat = nc_put_vara_float(ncid, zonal_wnd_id, zonal_wnd_start, zonal_wnd_count, zonal_wnd); check_err(stat,__LINE__,__FILE__); } } stat = nc_close(ncid); check_err(stat,__LINE__,__FILE__); return 0; }
int main() { /* create rec2Gp.nc */ int stat; /* return status */ int ncid; /* netCDF id */ int rec, i, j, k; signed char x[] = {42, 21}; /* dimension ids */ int rec_dim; int i_dim; int j_dim; int k_dim; int n_dim; #define NUMRECS 1 #define I_LEN 4104 #define J_LEN 1023 #define K_LEN 1023 #define N_LEN 2 /* dimension lengths */ size_t rec_len = NC_UNLIMITED; size_t i_len = I_LEN; size_t j_len = J_LEN; size_t k_len = K_LEN; size_t n_len = N_LEN; /* variable ids */ int var1_id; int x_id; /* rank (number of dimensions) for each variable */ # define RANK_var1 4 # define RANK_x 2 /* variable shapes */ int var1_dims[RANK_var1]; int x_dims[RANK_x]; /* enter define mode */ stat = nc_create("rec2Gp.nc", NC_CLOBBER|NC_64BIT_OFFSET, &ncid); check_err(stat,__LINE__,__FILE__); /* define dimensions */ stat = nc_def_dim(ncid, "rec", rec_len, &rec_dim); check_err(stat,__LINE__,__FILE__); stat = nc_def_dim(ncid, "i", i_len, &i_dim); check_err(stat,__LINE__,__FILE__); stat = nc_def_dim(ncid, "j", j_len, &j_dim); check_err(stat,__LINE__,__FILE__); stat = nc_def_dim(ncid, "k", k_len, &k_dim); check_err(stat,__LINE__,__FILE__); stat = nc_def_dim(ncid, "n", n_len, &n_dim); check_err(stat,__LINE__,__FILE__); /* define variables */ var1_dims[0] = rec_dim; var1_dims[1] = i_dim; var1_dims[2] = j_dim; var1_dims[3] = k_dim; stat = nc_def_var(ncid, "var1", NC_BYTE, RANK_var1, var1_dims, &var1_id); check_err(stat,__LINE__,__FILE__); x_dims[0] = rec_dim; x_dims[1] = n_dim; stat = nc_def_var(ncid, "x", NC_BYTE, RANK_x, x_dims, &x_id); check_err(stat,__LINE__,__FILE__); /* don't initialize variables with fill values */ stat = nc_set_fill(ncid, NC_NOFILL, 0); check_err(stat,__LINE__,__FILE__); /* leave define mode */ stat = nc_enddef (ncid); check_err(stat,__LINE__,__FILE__); { /* store var1 */ int n = 0; static signed char var1[J_LEN][K_LEN]; static size_t var1_start[RANK_var1] = {0, 0, 0, 0}; static size_t var1_count[RANK_var1] = {1, 1, J_LEN, K_LEN}; static size_t x_start[RANK_x] = {0, 0}; static size_t x_count[RANK_x] = {1, N_LEN}; for(rec=0; rec<NUMRECS; rec++) { var1_start[0] = rec; x_start[0] = rec; for(i=0; i<I_LEN; i++) { for(j=0; j<J_LEN; j++) { for (k=0; k<K_LEN; k++) { var1[j][k] = n++; } } var1_start[1] = i; stat = nc_put_vara_schar(ncid, var1_id, var1_start, var1_count, &var1[0][0]); check_err(stat,__LINE__,__FILE__); } } stat = nc_put_vara_schar(ncid, x_id, x_start, x_count, x); check_err(stat,__LINE__,__FILE__); } stat = nc_close(ncid); check_err(stat,__LINE__,__FILE__); stat = nc_open("rec2Gp.nc", NC_NOWRITE, &ncid); check_err(stat,__LINE__,__FILE__); { /* read var1 */ int n = 0; static signed char var1[J_LEN][K_LEN]; static size_t var1_start[RANK_var1] = {0, 0, 0, 0}; static size_t var1_count[RANK_var1] = {1, 1, J_LEN, K_LEN}; static size_t x_start[RANK_x] = {0, 0}; static size_t x_count[RANK_x] = {1, N_LEN}; for(rec=0; rec<NUMRECS; rec++) { var1_start[0] = rec; x_start[0] = rec; for(i=0; i<I_LEN; i++) { var1_start[1] = i; stat = nc_get_vara_schar(ncid, var1_id, var1_start, var1_count, &var1[0][0]); check_err(stat,__LINE__,__FILE__); for(j=0; j<J_LEN; j++) { for (k=0; k<K_LEN; k++) { if (var1[j][k] != (signed char) n) { printf("Error on read, var1[%d, %d, %d, %d] = %d wrong, should be %d !\n", rec, i, j, k, var1[j][k], (signed char) n); return 1; } n++; } } } nc_get_vara_schar(ncid, x_id, x_start, x_count, x); if(x[0] != 42 || x[1] != 21) { printf("Error on read, x[] = %d, %d\n", x[0], x[1]); return 1; } } } stat = nc_close(ncid); check_err(stat,__LINE__,__FILE__); return 0; }
/* * Generate C code for creating netCDF from in-memory structure. */ void gen_netcdf(const char *filename) { int stat, ncid; int idim, ivar, iatt; int ndims, nvars, natts, ngatts; #ifdef USE_NETCDF4 int ntyps, ngrps, igrp; #endif Bytebuffer* databuf = bbNew(); ndims = listlength(dimdefs); nvars = listlength(vardefs); natts = listlength(attdefs); ngatts = listlength(gattdefs); #ifdef USE_NETCDF4 ntyps = listlength(typdefs); ngrps = listlength(grpdefs); #endif /*USE_NETCDF4*/ /* create netCDF file, uses NC_CLOBBER mode */ cmode_modifier |= NC_CLOBBER; #ifdef USE_NETCDF4 if(!usingclassic) cmode_modifier |= NC_NETCDF4; #endif stat = nc_create(filename, cmode_modifier, &ncid); check_err(stat,__LINE__,__FILE__); /* ncid created above is also root group*/ rootgroup->ncid = ncid; #ifdef USE_NETCDF4 /* Define the group structure */ /* walking grdefs list will do a preorder walk of all defined groups*/ for(igrp=0;igrp<ngrps;igrp++) { Symbol* gsym = (Symbol*)listget(grpdefs,igrp); if(gsym == rootgroup) continue; /* ignore root group*/ stat = nc_def_grp(gsym->container->ncid,gsym->name,&gsym->ncid); check_err(stat,__LINE__,__FILE__); } #endif #ifdef USE_NETCDF4 /* Define the types*/ if (ntyps > 0) { int ityp; for(ityp = 0; ityp < ntyps; ityp++) { Symbol* tsym = (Symbol*)listget(typdefs,ityp); genbin_deftype(tsym); } } #endif /* define dimensions from info in dims array */ if (ndims > 0) { for(idim = 0; idim < ndims; idim++) { Symbol* dsym = (Symbol*)listget(dimdefs,idim); stat = nc_def_dim(dsym->container->ncid, dsym->name, (dsym->dim.isunlimited?NC_UNLIMITED:dsym->dim.declsize), &dsym->ncid); check_err(stat,__LINE__,__FILE__); } } /* define variables from info in vars array */ if (nvars > 0) { for(ivar = 0; ivar < nvars; ivar++) { Symbol* vsym = (Symbol*)listget(vardefs,ivar); if (vsym->typ.dimset.ndims > 0) { /* a dimensioned variable */ /* construct a vector of dimension ids*/ int dimids[NC_MAX_VAR_DIMS]; for(idim=0;idim<vsym->typ.dimset.ndims;idim++) dimids[idim] = vsym->typ.dimset.dimsyms[idim]->ncid; stat = nc_def_var(vsym->container->ncid, vsym->name, vsym->typ.basetype->ncid, vsym->typ.dimset.ndims, dimids, &vsym->ncid); } else { /* a scalar */ stat = nc_def_var(vsym->container->ncid, vsym->name, vsym->typ.basetype->ncid, vsym->typ.dimset.ndims, NULL, &vsym->ncid); } check_err(stat,__LINE__,__FILE__); } } #ifdef USE_NETCDF4 /* define special variable properties */ if(nvars > 0) { for(ivar = 0; ivar < nvars; ivar++) { Symbol* var = (Symbol*)listget(vardefs,ivar); genbin_definespecialattributes(var); } } #endif /*USE_NETCDF4*/ /* define global attributes */ if(ngatts > 0) { for(iatt = 0; iatt < ngatts; iatt++) { Symbol* gasym = (Symbol*)listget(gattdefs,iatt); genbin_defineattr(gasym); } } /* define per-variable attributes */ if(natts > 0) { for(iatt = 0; iatt < natts; iatt++) { Symbol* asym = (Symbol*)listget(attdefs,iatt); genbin_defineattr(asym); } } if (nofill_flag) { stat = nc_set_fill(rootgroup->ncid, NC_NOFILL, 0); check_err(stat,__LINE__,__FILE__); } /* leave define mode */ stat = nc_enddef(rootgroup->ncid); check_err(stat,__LINE__,__FILE__); if(!header_only) { /* Load values into those variables with defined data */ if(nvars > 0) { for(ivar = 0; ivar < nvars; ivar++) { Symbol* vsym = (Symbol*)listget(vardefs,ivar); if(vsym->data != NULL) { bbClear(databuf); genbin_definevardata(vsym); } } } } bbFree(databuf); }
int ex_put_prop (int exoid, ex_entity_type obj_type, ex_entity_id obj_id, const char *prop_name, ex_entity_id value) { int status; int oldfill = 0; int temp; int found = FALSE; int num_props, i, dimid, propid, dims[1]; int int_type; size_t start[1]; size_t prop_name_len, name_length; char name[MAX_VAR_NAME_LENGTH+1]; char tmpstr[MAX_STR_LENGTH+1]; char dim_name[MAX_VAR_NAME_LENGTH+1]; long long vals[1]; char errmsg[MAX_ERR_LENGTH]; exerrval = 0; /* clear error code */ /* check if property has already been created */ num_props = ex_get_num_props(exoid, obj_type); if (num_props > 1) { /* any properties other than the default 1? */ for (i=1; i<=num_props; i++) { switch (obj_type) { case EX_ELEM_BLOCK: strcpy (name, VAR_EB_PROP(i)); break; case EX_EDGE_BLOCK: strcpy (name, VAR_ED_PROP(i)); break; case EX_FACE_BLOCK: strcpy (name, VAR_FA_PROP(i)); break; case EX_NODE_SET: strcpy (name, VAR_NS_PROP(i)); break; case EX_EDGE_SET: strcpy (name, VAR_ES_PROP(i)); break; case EX_FACE_SET: strcpy (name, VAR_FS_PROP(i)); break; case EX_ELEM_SET: strcpy (name, VAR_ELS_PROP(i)); break; case EX_SIDE_SET: strcpy (name, VAR_SS_PROP(i)); break; case EX_ELEM_MAP: strcpy (name, VAR_EM_PROP(i)); break; case EX_FACE_MAP: strcpy (name, VAR_FAM_PROP(i)); break; case EX_EDGE_MAP: strcpy (name, VAR_EDM_PROP(i)); break; case EX_NODE_MAP: strcpy (name, VAR_NM_PROP(i)); break; default: exerrval = EX_BADPARAM; sprintf(errmsg, "Error: object type %d not supported; file id %d", obj_type, exoid); ex_err("ex_put_prop",errmsg,exerrval); return(EX_FATAL); } if ((status = nc_inq_varid(exoid, name, &propid)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to get property array id in file id %d", exoid); ex_err("ex_put_prop",errmsg,exerrval); return (EX_FATAL); } /* compare stored attribute name with passed property name */ memset(tmpstr, 0, MAX_STR_LENGTH+1); if ((status = nc_get_att_text(exoid, propid, ATT_PROP_NAME, tmpstr)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to get property name in file id %d", exoid); ex_err("ex_put_prop",errmsg,exerrval); return (EX_FATAL); } if (strcmp(tmpstr, prop_name) == 0) { found = TRUE; break; } } } /* if property array has not been created, create it */ if (!found) { name_length = ex_inquire_int(exoid, EX_INQ_DB_MAX_ALLOWED_NAME_LENGTH)+1; /* put netcdf file into define mode */ if ((status = nc_redef (exoid)) != NC_NOERR) { exerrval = status; sprintf(errmsg,"Error: failed to place file id %d into define mode",exoid); ex_err("ex_put_prop",errmsg,exerrval); return (EX_FATAL); } /* create a variable with a name xx_prop#, where # is the new number */ /* of the property */ switch (obj_type){ case EX_ELEM_BLOCK: strcpy (name, VAR_EB_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_EL_BLK); break; case EX_FACE_BLOCK: strcpy (name, VAR_FA_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_FA_BLK); break; case EX_EDGE_BLOCK: strcpy (name, VAR_ED_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_ED_BLK); break; case EX_NODE_SET: strcpy (name, VAR_NS_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_NS); break; case EX_EDGE_SET: strcpy (name, VAR_ES_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_ES); break; case EX_FACE_SET: strcpy (name, VAR_FS_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_FS); break; case EX_ELEM_SET: strcpy (name, VAR_ELS_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_ELS); break; case EX_SIDE_SET: strcpy (name, VAR_SS_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_SS); break; case EX_ELEM_MAP: strcpy (name, VAR_EM_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_EM); break; case EX_FACE_MAP: strcpy (name, VAR_FAM_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_FAM); break; case EX_EDGE_MAP: strcpy (name, VAR_EDM_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_EDM); break; case EX_NODE_MAP: strcpy (name, VAR_NM_PROP(num_props+1)); strcpy (dim_name, DIM_NUM_NM); break; default: exerrval = EX_BADPARAM; sprintf(errmsg, "Error: object type %d not supported; file id %d", obj_type, exoid); ex_err("ex_put_prop",errmsg,exerrval); goto error_ret; /* Exit define mode and return */ } /* inquire id of previously defined dimension (number of objects) */ if ((status = nc_inq_dimid(exoid, dim_name, &dimid)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to locate number of objects in file id %d", exoid); ex_err("ex_put_prop",errmsg, exerrval); goto error_ret; /* Exit define mode and return */ } dims[0] = dimid; nc_set_fill(exoid, NC_FILL, &oldfill); /* fill with zeros per routine spec */ int_type = NC_INT; if (ex_int64_status(exoid) & EX_IDS_INT64_DB) { int_type = NC_INT64; } if ((status = nc_def_var(exoid, name, int_type, 1, dims, &propid)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to create property array variable in file id %d", exoid); ex_err("ex_put_prop",errmsg,exerrval); goto error_ret; /* Exit define mode and return */ } vals[0] = 0; /* fill value */ /* create attribute to cause variable to fill with zeros per routine spec */ if ((status = nc_put_att_longlong(exoid, propid, _FillValue, int_type, 1, vals)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to create property name fill attribute in file id %d", exoid); ex_err("ex_put_prop",errmsg,exerrval); goto error_ret; /* Exit define mode and return */ } /* Check that the property name length is less than MAX_NAME_LENGTH */ prop_name_len = strlen(prop_name)+1; if (prop_name_len > name_length) { fprintf(stderr, "Warning: The property name '%s' is too long.\n\tIt will be truncated from %d to %d characters\n", prop_name, (int)prop_name_len-1, (int)name_length-1); prop_name_len = name_length; } /* store property name as attribute of property array variable */ if ((status = nc_put_att_text(exoid, propid, ATT_PROP_NAME, prop_name_len, (void*)prop_name)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to store property name %s in file id %d", prop_name,exoid); ex_err("ex_put_prop",errmsg,exerrval); goto error_ret; /* Exit define mode and return */ } ex_update_max_name_length(exoid, prop_name_len-1); /* leave define mode */ if ((status = nc_enddef (exoid)) != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to leave define mode in file id %d", exoid); ex_err("ex_put_prop",errmsg,exerrval); return (EX_FATAL); } nc_set_fill(exoid, oldfill, &temp); /* default: nofill */ } /* find index into property array using obj_id; put value in property */ /* array at proper index; ex_id_lkup returns an index that is 1-based,*/ /* but netcdf expects 0-based arrays so subtract 1 */ /* special case: property name ID - check for duplicate ID assignment */ if (strcmp("ID",prop_name) == 0) { start[0] = ex_id_lkup (exoid, obj_type, value); if (exerrval != EX_LOOKUPFAIL) /* found the id */ { exerrval = EX_BADPARAM; sprintf(errmsg, "Warning: attempt to assign duplicate %s ID %"PRId64" in file id %d", ex_name_of_object(obj_type), value, exoid); ex_err("ex_put_prop",errmsg,exerrval); return (EX_WARN); } } start[0] = ex_id_lkup (exoid, obj_type, obj_id); if (exerrval != 0) { if (exerrval == EX_NULLENTITY) { sprintf(errmsg, "Warning: no properties allowed for NULL %s id %"PRId64" in file id %d", ex_name_of_object(obj_type), obj_id,exoid); ex_err("ex_put_prop",errmsg,EX_MSG); return (EX_WARN); } else { sprintf(errmsg, "Error: failed to find value %"PRId64" in %s property array in file id %d", obj_id, ex_name_of_object(obj_type), exoid); ex_err("ex_put_prop",errmsg,exerrval); return (EX_FATAL); } } start[0] = start[0] - 1; /* value is of type 'ex_entity_id' which is a typedef to int64_t or long long */ status = nc_put_var1_longlong(exoid, propid, start, (long long*)&value); if (status != NC_NOERR) { exerrval = status; sprintf(errmsg, "Error: failed to store property value in file id %d", exoid); ex_err("ex_put_prop",errmsg,exerrval); return (EX_FATAL); } return (EX_NOERR); /* Fatal error: exit definition mode and return */ error_ret: nc_set_fill(exoid, oldfill, &temp); /* default: nofill */ if (nc_enddef (exoid) != NC_NOERR) { /* exit define mode */ sprintf(errmsg, "Error: failed to complete definition for file id %d", exoid); ex_err("ex_put_prop",errmsg,exerrval); } return (EX_FATAL); }
int main(int argc, char **argv) { int status = NC_NOERR; int i,j,iv; unsigned int data[DATASIZE]; size_t start[1]; size_t count[1]; Tag tag = Create; int cmode = 0; int ncid; int dimids[1]; void* memory; int nvars; int varids[4096]; size_t varsize; size_t filesize; /* Get the specified var/file size */ if(argc > 1) { filesize = atol(argv[1]); } else { if(sizeof(size_t) == 4) filesize = 1000000000; else if(sizeof(size_t) == 8) filesize = 3000000000; else { fprintf(stderr,"Cannot compute filesize\n"); exit(1); } } /* Test that we can malloc that much space */ memory = malloc(filesize); if(memory == NULL) { fprintf(stderr,"Cannot malloc %lu bytes\n",(unsigned long)filesize); exit(1); } free(memory); if(argc > 2) { if(strcmp(argv[2],"create")==0) tag = Create; else if(strcmp(argv[2],"creatediskless")==0) tag = CreateDiskless; else if(strcmp(argv[2],"open")==0) tag = Open; else if(strcmp(argv[2],"opendiskless")==0) tag = OpenDiskless; else { fprintf(stderr,"illegal tag: %s",argv[2]); exit(1); } } else tag = Create; /* default */ switch (tag) { case Create: printf("\n*** Create file\n"); break; case CreateDiskless: printf("\n*** Create file diskless\n"); break; case Open: printf("\n*** Open file\n"); break; case OpenDiskless: printf("\n*** Open file diskless\n"); break; } switch (tag) { case Create: cmode = NC_CLOBBER; break; case CreateDiskless: cmode = NC_CLOBBER|NC_DISKLESS|NC_WRITE; break; case Open: cmode = 0; break; case OpenDiskless: cmode = NC_DISKLESS; break; } switch (tag) { case Create: case CreateDiskless: /* Try to alloc as much as possible initially */ if((status=nc__create(FILE_NAME, cmode, filesize, NULL, &ncid))) REPORT; if((status=nc_set_fill(ncid, NC_NOFILL, NULL))) REPORT; /* Only need 1 dimension */ if((status=nc_def_dim(ncid, "dim", DIMMAX, &dimids[0]))) REPORT; break; case Open: case OpenDiskless: if((status=nc_open(FILE_NAME, cmode, &ncid))) REPORT; if((status=nc_inq_dimid(ncid, "dim", &dimids[0]))) REPORT; break; } varsize = DIMMAX; nvars = filesize / varsize; assert((filesize % DIMMAX) == 0); assert(nvars < 4096); for(iv=0;iv<nvars;iv++) { char varname[32]; sprintf(varname,"var%d",iv); switch (tag) { case Create: case CreateDiskless: if((status=nc_def_var(ncid, varname, NC_BYTE, 1, &dimids[0], &varids[iv]))) REPORT; break; case Open: case OpenDiskless: if((status=nc_inq_varid(ncid, varname, &varids[iv]))) REPORT; break; } } if(tag == Create || tag == CreateDiskless) { if((status=nc_enddef(ncid))) REPORT; } for(iv=0;iv<nvars;iv++) { size_t pieces = varsize/CHUNKSIZE; switch (tag) { case Create: case CreateDiskless: /* Fill and put as integers */ for(i=0;i<pieces;i++) { start[0] = i*CHUNKSIZE; count[0] = CHUNKSIZE; for(j=0;j<DATASIZE;j++) data[j] = iv*((i*CHUNKSIZE)+j); if((status=nc_put_vara(ncid,varids[iv],start,count,(void*)data))) REPORT; } break; case Open: case OpenDiskless: /* Read the var contents and validate */ for(i=0;i<pieces;i++) { start[0] = i*CHUNKSIZE; count[0] = CHUNKSIZE; if((status=nc_get_vara(ncid,varids[iv],start,count,(void*)data))) REPORT; for(j=0;j<DATASIZE;j++) { unsigned int expected = iv*((i*CHUNKSIZE)+j); if(data[j] != expected) { printf("mismatch: iv=%d i=%u j=%u data=%u; should be %u\n", iv, i,j,data[j],expected); err++; } } } break; } } if((status=nc_close(ncid))) REPORT; SUMMARIZE_ERR; exit(0); return 0; }