/** @ingroup variables @internal Get the number of record dimensions for a variable and an array that identifies which of a variable's dimensions are record dimensions. Intended to be used instead of NC_is_recvar(), which doesn't work for netCDF-4 variables which have multiple unlimited dimensions or an unlimited dimension that is not the first of a variable's dimensions. @param ncid File ID. @param varid Variable ID. @param nrecdimsp Pointer that gets number of record dims. @param is_recdim Pointer that gets 1 if there is one or more record dimensions, 0 if not. @returns 0 if not a record var, 1 if it is. Example use: @code int nrecdims; int is_recdim[NC_MAX_VAR_DIMS]; ... status = NC_inq_recvar(ncid,varid,&nrecdims,is_recdim); isrecvar = (nrecdims > 0); @endcode */ int NC_inq_recvar(int ncid, int varid, int* nrecdimsp, int *is_recdim) { int status = NC_NOERR; int unlimid; int nvardims; int dimset[NC_MAX_VAR_DIMS]; int dim; int nrecdims = 0; status = nc_inq_varndims(ncid,varid,&nvardims); if(status != NC_NOERR) return status; if(nvardims == 0) return NC_NOERR; /* scalars have no dims */ for(dim = 0; dim < nvardims; dim++) is_recdim[dim] = 0; status = nc_inq_unlimdim(ncid, &unlimid); if(status != NC_NOERR) return status; if(unlimid == -1) return status; /* no unlimited dims for any variables */ #ifdef USE_NETCDF4 { int nunlimdims; int *unlimids; int recdim; status = nc_inq_unlimdims(ncid, &nunlimdims, NULL); /* for group or file, not variable */ if(status != NC_NOERR) return status; if(nunlimdims == 0) return status; if (!(unlimids = malloc(nunlimdims * sizeof(int)))) return NC_ENOMEM; status = nc_inq_unlimdims(ncid, &nunlimdims, unlimids); /* for group or file, not variable */ if(status != NC_NOERR) { free(unlimids); return status; } status = nc_inq_vardimid(ncid, varid, dimset); if(status != NC_NOERR) { free(unlimids); return status; } for (dim = 0; dim < nvardims; dim++) { /* netCDF-4 rec dims need not be first dim for a rec var */ for(recdim = 0; recdim < nunlimdims; recdim++) { if(dimset[dim] == unlimids[recdim]) { is_recdim[dim] = 1; nrecdims++; } } } free(unlimids); } #else status = nc_inq_vardimid(ncid, varid, dimset); if(status != NC_NOERR) return status; if(dimset[0] == unlimid) { is_recdim[0] = 1; nrecdims++; } #endif /* USE_NETCDF4 */ if(nrecdimsp) *nrecdimsp = nrecdims; return status; }
/* * return 1 if varid identifies a record variable * else return 0 */ int isrecvar(int ncid, int varid) { int ndims; int is_recvar = 0; int *dimids; NC_CHECK( nc_inq_varndims(ncid, varid, &ndims) ); #ifdef USE_NETCDF4 if (ndims > 0) { int nunlimdims; int *recdimids; int dim, recdim; dimids = (int *) emalloc((ndims + 1) * sizeof(int)); NC_CHECK( nc_inq_vardimid(ncid, varid, dimids) ); NC_CHECK( nc_inq_unlimdims(ncid, &nunlimdims, NULL) ); recdimids = (int *) emalloc((nunlimdims + 1) * sizeof(int)); NC_CHECK( nc_inq_unlimdims(ncid, NULL, recdimids) ); for (dim = 0; dim < ndims && is_recvar == 0; dim++) { for(recdim = 0; recdim < nunlimdims; recdim++) { if(dimids[dim] == recdimids[recdim]) { is_recvar = 1; break; } } } free(dimids); free(recdimids); } #else if (ndims > 0) { int recdimid; dimids = (int *) emalloc((ndims + 1) * sizeof(int)); NC_CHECK( nc_inq_vardimid(ncid, varid, dimids) ); NC_CHECK( nc_inq_unlimdim(ncid, &recdimid) ); if(dimids[0] == recdimid) is_recvar = 1; free(dimids); } #endif /* USE_NETCDF4 */ return is_recvar; }
int main(int argc, char **argv) {/* create file that caused seg fault in ncdump */ int ncid; /* netCDF id */ /* dimension ids */ int Time_dim; int X_dim; int Y_dim; /* dimension lengths */ size_t Time_len = NC_UNLIMITED; size_t X_len = 4; size_t Y_len = 3; /* variable ids */ int Time_id; int P_id; /* rank (number of dimensions) for each variable */ # define RANK_Time 1 # define RANK_P 3 /* variable shapes */ int Time_dims[RANK_Time]; int P_dims[RANK_P]; printf("\n*** Testing preparation of fillbug test.\n"); printf("*** creating fillbug test file %s...", FILENAME); /* enter define mode */ if (nc_create(FILENAME, NC_CLOBBER|NC_NETCDF4, &ncid)) ERR; /* define dimensions */ if (nc_def_dim(ncid, "Time", Time_len, &Time_dim)) ERR; if (nc_def_dim(ncid, "X", X_len, &X_dim)) ERR; if (nc_def_dim(ncid, "Y", Y_len, &Y_dim)) ERR; /* define variables */ Time_dims[0] = Time_dim; if (nc_def_var(ncid, "Time", NC_DOUBLE, RANK_Time, Time_dims, &Time_id)) ERR; P_dims[0] = Time_dim; P_dims[1] = Y_dim; P_dims[2] = X_dim; if (nc_def_var(ncid, "P", NC_FLOAT, RANK_P, P_dims, &P_id)) ERR; /* leave define mode */ if (nc_enddef (ncid)) ERR; {/* assign variable data */ static double Time_data[1]={3.14159}; static size_t Time_startset[1] = {0}; static size_t Time_countset[1] = {1}; if (nc_put_vara(ncid, Time_id, Time_startset, Time_countset, Time_data)) ERR; } if (nc_close(ncid)) ERR; /* Try to duplicate segfault ncdump gets by making the same calls * to the netCDF-4 library, in the same order. This doesn't * result in the same segfault, so either we have missed a call * made by ncdump, or an earlier ncdump bug masks the real problem * until a call is made into the netCDF-4 library ... */ if (nc_open(FILENAME, NC_NOWRITE, &ncid)) ERR; { /* We declare local arrays with small constant sizes to avoid * all the mallocs and frees used in ncdump. For the example * above, the fixed-size arrays are ample. */ int format, ndims, nvars, ngatts, xdimid, ndims_grp, dimids_grp[3], unlimids[1], d_grp, nunlim, nvars_grp, varids_grp[3], v_grp, varid, varndims, vardims[3], varnatts, vartype, dimids[3], is_recvar, vdims[3], id, ntypes, numgrps, atttype, nc_status; size_t dimsize, len, attlen; char dimname[20], varname[20]; if ( nc_inq_format(ncid, &format)) ERR; ntypes = count_udtypes(ncid); if ( nc_inq_typeids(ncid, &ntypes, NULL) ) ERR; if ( nc_inq_format(ncid, &format)) ERR; if ( nc_inq_grps(ncid, &numgrps, NULL) ) ERR; if ( nc_inq_typeids(ncid, &ntypes, NULL) ) ERR; if ( nc_inq(ncid, &ndims, &nvars, &ngatts, &xdimid) ) ERR; if ( nc_inq_ndims(ncid, &ndims_grp) ) ERR; if ( nc_inq_dimids(ncid, 0, dimids_grp, 0) ) ERR; if ( nc_inq_unlimdims(ncid, &nunlim, NULL) ) ERR; if ( nc_inq_unlimdims(ncid, &nunlim, unlimids) ) ERR; for (d_grp = 0; d_grp < ndims_grp; d_grp++) { int dimid = dimids_grp[d_grp]; if ( nc_inq_dim(ncid, dimid, dimname, &dimsize) ) ERR; } if ( nc_inq_format(ncid, &format) ) ERR; if ( nc_inq_varids(ncid, &nvars_grp, varids_grp) ) ERR; for (v_grp = 0; v_grp < nvars_grp; v_grp++) { varid = varids_grp[v_grp]; if ( nc_inq_varndims(ncid, varid, &varndims) ) ERR; if ( nc_inq_var(ncid, varid, varname, &vartype, 0, vardims, &varnatts) ) ERR; for (id = 0; id < varndims; id++) { if ( nc_inq_dimname(ncid, vardims[id], dimname) ) ERR; } } for (v_grp = 0; v_grp < nvars_grp; v_grp++) { varid = varids_grp[v_grp]; if( nc_inq_varndims(ncid, varid, &varndims) ) ERR; if( nc_inq_var(ncid, varid, varname, &vartype, 0, vardims, &varnatts) ) ERR; { is_recvar = 0; if ( nc_inq_varndims(ncid, varid, &ndims) ) ERR; if (ndims > 0) { int nunlimdims; int recdimids[3]; int dim, recdim; if ( nc_inq_vardimid(ncid, varid, dimids) ) ERR; if ( nc_inq_unlimdims(ncid, &nunlimdims, NULL) ) ERR; if ( nc_inq_unlimdims(ncid, NULL, recdimids) ) ERR; for (dim = 0; dim < ndims && is_recvar == 0; dim++) { for(recdim = 0; recdim < nunlimdims; recdim++) { if(dimids[dim] == recdimids[recdim]) { is_recvar = 1; break; } } } } } for (id = 0; id < varndims; id++) { if( nc_inq_dimlen(ncid, vardims[id], &len) ) ERR; vdims[id] = len; } nc_status = nc_inq_att(ncid,varid,_FillValue,&atttype,&attlen); nc_status = nc_inq_att(ncid, varid, "units", &atttype, &attlen); nc_status = nc_inq_att(ncid, varid, "C_format", &atttype, &attlen); if (varid == 0) { /* read Time variable */ static double Time_data; static size_t cor[RANK_Time] = {0}; static size_t edg[RANK_Time] = {1}; if (nc_get_vara(ncid, varid, cor, edg, &Time_data)) ERR; } else { /* read data slices from P variable, should get fill values */ static float P_data[4]; static size_t cor[RANK_P] = {0, 0, 0}; static size_t edg[RANK_P] = {1, 1, 4}; /* first slice retrieved OK */ if (nc_get_vara(ncid, varid, cor, edg, P_data)) ERR; /* In ncdump, reading second slice gets seg fault in * nc4_open_var_grp(), but this attempt to do all the * same netCDF calls as ncdump can't duplicate the * error, which would seem to implicate ncdump rather * than HDF5 or netCDF-4 library ... */ cor[1] = 1; if (nc_get_vara(ncid, varid, cor, edg, P_data)) ERR; } } } if (nc_close(ncid)) ERR; SUMMARIZE_ERR; FINAL_RESULTS; }
int main(int argc, char **argv) { printf("\n*** Testing netcdf-4 dimensions.\n"); printf("*** Testing that netcdf-4 dimids inq works on netcdf-3 file..."); { int ncid, dimid; int ndims_in, dimids_in[MAX_DIMS]; /* Create a netcdf-3 file with one dim. */ if (nc_create(FILE_NAME, 0, &ncid)) ERR; if (nc_def_dim(ncid, LAT_NAME, LAT_LEN, &dimid)) ERR; if (nc_close(ncid)) ERR; /* Open the file and make sure nc_inq_dimids yeilds correct * result. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1 || dimids_in[0] != 0) ERR; if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR; if (ndims_in != 0) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** Testing that netcdf-4 dimids inq works on more complex netcdf-3 file..."); { int ncid, dimid; int lon_dimid; int ndims_in, dimids_in[MAX_DIMS]; /* Create a netcdf-3 file with three dim. */ if (nc_create(FILE_NAME, 0, &ncid)) ERR; if (nc_def_dim(ncid, LEVEL_NAME, NC_UNLIMITED, &dimid)) ERR; if (nc_def_dim(ncid, LAT_NAME, LAT_LEN, &dimid)) ERR; if (nc_def_dim(ncid, LON_NAME, LON_LEN, &lon_dimid)) ERR; if (nc_close(ncid)) ERR; /* Open the file and make sure nc_inq_dimids yeilds correct * result. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 3 || dimids_in[0] != 0 || dimids_in[1] != 1 || dimids_in[2] != 2) ERR; if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR; if (ndims_in != 1 || dimids_in[0] != 0) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** Testing file with just one dimension..."); { int ncid, dimid; int ndims_in, dimids_in[MAX_DIMS]; size_t len_in; char name_in[NC_MAX_NAME + 1]; int dimid_in; /* Create a file with one dim and nothing else. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, LAT_NAME, LAT_LEN, &dimid)) ERR; /* Check out what we've got. */ if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR; if (len_in != LAT_LEN || strcmp(name_in, LAT_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1) ERR; if (nc_inq_dimid(ncid, LAT_NAME, &dimid_in)) ERR; if (dimid_in != 0) ERR; if (nc_inq_dimname(ncid, 0, name_in)) ERR; if (strcmp(name_in, LAT_NAME)) ERR; if (nc_inq_dimlen(ncid, 0, &len_in)) ERR; if (len_in != LAT_LEN) ERR; if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR; if (ndims_in != 0) ERR; if (nc_close(ncid)) ERR; /* Reopen and check it out again. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR; if (len_in != LAT_LEN || strcmp(name_in, LAT_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1) ERR; if (nc_inq_dimid(ncid, LAT_NAME, &dimid_in)) ERR; if (dimid_in != 0) ERR; if (nc_inq_dimname(ncid, 0, name_in)) ERR; if (strcmp(name_in, LAT_NAME)) ERR; if (nc_inq_dimlen(ncid, 0, &len_in)) ERR; if (len_in != LAT_LEN) ERR; if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR; if (ndims_in != 0) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** Testing renaming of one dimension..."); { int ncid, dimid, dimid_in; char name_in[NC_MAX_NAME + 1]; size_t len_in; int ndims_in, dimids_in[MAX_DIMS]; /* Reopen the file with one dim, and change the name of the dim. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_rename_dim(ncid, 0, BUBBA)) ERR; /* Check out what we've got. */ dimid = 0; if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR; if (len_in != LAT_LEN || strcmp(name_in, BUBBA)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1) ERR; if (dimids_in[0] != 0) ERR; if (nc_inq_dimid(ncid, BUBBA, &dimid_in)) ERR; if (dimid_in != 0) ERR; if (nc_inq_dimname(ncid, 0, name_in)) ERR; if (strcmp(name_in, BUBBA)) ERR; if (nc_inq_dimlen(ncid, 0, &len_in)) ERR; if (len_in != LAT_LEN) ERR; if (nc_close(ncid)) ERR; /* Reopen and check out what we've got again. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR; if (len_in != LAT_LEN || strcmp(name_in, BUBBA)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1 || dimids_in[0] != 0) ERR; if (nc_inq_dimid(ncid, BUBBA, &dimid_in)) ERR; if (dimid_in != 0) ERR; if (nc_inq_dimname(ncid, 0, name_in)) ERR; if (strcmp(name_in, BUBBA)) ERR; if (nc_inq_dimlen(ncid, 0, &len_in)) ERR; if (len_in != LAT_LEN) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** Testing renaming dimensions and vars..."); { #define FILE_NAME1 "foo1.nc" #define FILE_NAME2 "foo2.nc" #define FILE_NAME3 "foo3.nc" #define FILE_NAME4 "foo4.nc" #define DIM_NAME "lat_T42" #define VAR_NAME DIM_NAME #define DIM_NAME2 "lat" #define VAR_NAME2 DIM_NAME2 #define RANK_lat_T42 1 int ncid, varid, dimid; int lat_T42_dim; size_t lat_T42_len = 3; int lat_T42_id; int lat_T42_dims[RANK_lat_T42]; char name[NC_MAX_NAME + 1]; /* =========== */ /* Sub-test #1 */ /* =========== */ /* create file with dimension and associated coordinate variable */ if (nc_create(FILE_NAME1, NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; if (nc_def_dim(ncid, DIM_NAME, lat_T42_len, &lat_T42_dim)) ERR; lat_T42_dims[0] = lat_T42_dim; if (nc_def_var(ncid, VAR_NAME, NC_INT, RANK_lat_T42, lat_T42_dims, &lat_T42_id)) ERR; if (nc_close(ncid)) ERR; /* reopen file, rename coordinate dimension and then associated variable */ if (nc_open(FILE_NAME1, NC_WRITE, &ncid)) ERR; if (nc_inq_dimid(ncid, DIM_NAME, &dimid)) ERR; if (nc_inq_varid(ncid, VAR_NAME, &varid)) ERR; if (nc_rename_dim(ncid, dimid, DIM_NAME2)) ERR; if (nc_rename_var(ncid, varid, VAR_NAME2)) ERR; if (nc_close(ncid)) ERR; /* reopen file, check coordinate dimension and associated variable names */ /* Should be just like they created the file with DIM_NAME2 & VAR_NAME2 to * begin with. */ if (nc_open(FILE_NAME1, NC_WRITE, &ncid)) ERR; if (nc_inq_dimid(ncid, DIM_NAME2, &dimid)) ERR; if (nc_inq_varid(ncid, VAR_NAME2, &varid)) ERR; if (nc_inq_dimname(ncid, dimid, name)) ERR; if (strcmp(name, DIM_NAME2)) ERR; if (nc_inq_varname(ncid, varid, name)) ERR; if (strcmp(name, VAR_NAME2)) ERR; if (nc_close(ncid)) ERR; /* =========== */ /* Sub-test #2 */ /* =========== */ /* create file with dimension and associated coordinate variable */ if (nc_create(FILE_NAME1, NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; if (nc_def_dim(ncid, DIM_NAME, lat_T42_len, &lat_T42_dim)) ERR; lat_T42_dims[0] = lat_T42_dim; if (nc_def_var(ncid, VAR_NAME, NC_INT, RANK_lat_T42, lat_T42_dims, &lat_T42_id)) ERR; if (nc_close(ncid)) ERR; /* reopen file, just rename coordinate dimension */ if (nc_open(FILE_NAME1, NC_WRITE, &ncid)) ERR; if (nc_inq_dimid(ncid, DIM_NAME, &dimid)) ERR; if (nc_rename_dim(ncid, dimid, DIM_NAME2)) ERR; if (nc_close(ncid)) ERR; /* reopen file, check coordinate dimension and associated variable names */ /* Should be just like the file was created with DIM_NAME2 to begin with */ if (nc_open(FILE_NAME1, NC_WRITE, &ncid)) ERR; if (nc_inq_dimid(ncid, DIM_NAME2, &dimid)) ERR; if (nc_inq_varid(ncid, VAR_NAME, &varid)) ERR; if (nc_inq_dimname(ncid, dimid, name)) ERR; if (strcmp(name, DIM_NAME2)) ERR; if (nc_inq_varname(ncid, varid, name)) ERR; if (strcmp(name, VAR_NAME)) ERR; if (nc_close(ncid)) ERR; /* =========== */ /* Sub-test #3 */ /* =========== */ /* create file with dimension and associated coordinate variable */ if (nc_create(FILE_NAME1, NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; if (nc_def_dim(ncid, DIM_NAME, lat_T42_len, &lat_T42_dim)) ERR; lat_T42_dims[0] = lat_T42_dim; if (nc_def_var(ncid, VAR_NAME, NC_INT, RANK_lat_T42, lat_T42_dims, &lat_T42_id)) ERR; if (nc_close(ncid)) ERR; /* reopen file, just rename variable */ if (nc_open(FILE_NAME1, NC_WRITE, &ncid)) ERR; if (nc_inq_varid(ncid, VAR_NAME, &varid)) ERR; if (nc_rename_var(ncid, varid, VAR_NAME2)) ERR; if (nc_close(ncid)) ERR; /* reopen file, check coordinate dimension and associated variable names */ /* Should be just like the file was created with VAR_NAME2 to begin with */ if (nc_open(FILE_NAME1, NC_WRITE, &ncid)) ERR; if (nc_inq_dimid(ncid, DIM_NAME, &dimid)) ERR; if (nc_inq_varid(ncid, VAR_NAME2, &varid)) ERR; if (nc_inq_dimname(ncid, dimid, name)) ERR; if (strcmp(name, DIM_NAME)) ERR; if (nc_inq_varname(ncid, varid, name)) ERR; if (strcmp(name, VAR_NAME2)) ERR; if (nc_close(ncid)) ERR; /* =========== */ /* Sub-test #4 */ /* =========== */ /* create file with dimension and associated coordinate variable */ if (nc_create(FILE_NAME1, NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; if (nc_def_dim(ncid, DIM_NAME, lat_T42_len, &lat_T42_dim)) ERR; lat_T42_dims[0] = lat_T42_dim; if (nc_def_var(ncid, VAR_NAME, NC_INT, RANK_lat_T42, lat_T42_dims, &lat_T42_id)) ERR; if (nc_close(ncid)) ERR; /* reopen file, rename associated variable and then coordinate dimension */ if (nc_open(FILE_NAME1, NC_WRITE, &ncid)) ERR; if (nc_inq_dimid(ncid, DIM_NAME, &dimid)) ERR; if (nc_inq_varid(ncid, VAR_NAME, &varid)) ERR; if (nc_rename_var(ncid, varid, VAR_NAME2)) ERR; if (nc_rename_dim(ncid, dimid, DIM_NAME2)) ERR; if (nc_close(ncid)) ERR; /* reopen file, check coordinate dimension and associated variable names */ /* Should be just like they created the file with DIM_NAME2 & VAR_NAME2 to * begin with. */ if (nc_open(FILE_NAME1, NC_WRITE, &ncid)) ERR; if (nc_inq_dimid(ncid, DIM_NAME2, &dimid)) ERR; if (nc_inq_varid(ncid, VAR_NAME2, &varid)) ERR; if (nc_inq_dimname(ncid, dimid, name)) ERR; if (strcmp(name, DIM_NAME2)) ERR; if (nc_inq_varname(ncid, varid, name)) ERR; if (strcmp(name, VAR_NAME2)) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** Testing file with just one unlimited dimension..."); { int ncid, dimid; int ndims_in, dimids_in[MAX_DIMS]; size_t len_in; char name_in[NC_MAX_NAME + 1]; int unlimdimid_in; int nunlimdims_in; /* Create a file with one unlimied dim and nothing else. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, LEVEL_NAME, NC_UNLIMITED, &dimid)) ERR; /* Check it out before the enddef. */ if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR; if (len_in != NC_UNLIMITED || strcmp(name_in, LEVEL_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1 || dimids_in[0] != 0) ERR; if (nc_inq_unlimdim(ncid, &unlimdimid_in)) ERR; if (unlimdimid_in != 0) ERR; if (nc_inq_unlimdims(ncid, &nunlimdims_in, &unlimdimid_in)) ERR; if (nunlimdims_in != 1 || unlimdimid_in != 0) ERR; /* Automatically enddef and close. */ if (nc_close(ncid)) ERR; /* Reopen and check it out. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR; if (len_in != NC_UNLIMITED || strcmp(name_in, LEVEL_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1 || dimids_in[0] != 0) ERR; if (nc_inq_unlimdim(ncid, &unlimdimid_in)) ERR; if (unlimdimid_in != 0) ERR; if (nc_inq_unlimdims(ncid, &nunlimdims_in, &unlimdimid_in)) ERR; if (nunlimdims_in != 1 || unlimdimid_in != 0) ERR; if (unlimdimid_in != 0) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; #define ROMULUS "Romulus" #define REMUS "Remus" #define DIMS2 2 printf("*** Testing file with two unlimited dimensions..."); { int ncid, dimid[DIMS2]; int ndims_in, dimids_in[DIMS2]; size_t len_in; char name_in[NC_MAX_NAME + 1]; int unlimdimid_in[DIMS2]; int nunlimdims_in; /* Create a file with two unlimited dims and nothing else. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, REMUS, NC_UNLIMITED, &dimid[0])) ERR; if (nc_def_dim(ncid, ROMULUS, NC_UNLIMITED, &dimid[1])) ERR; /* Check it out before the enddef. */ if (nc_inq_dim(ncid, dimid[0], name_in, &len_in)) ERR; if (len_in != NC_UNLIMITED || strcmp(name_in, REMUS)) ERR; if (nc_inq_dim(ncid, dimid[1], name_in, &len_in)) ERR; if (len_in != NC_UNLIMITED || strcmp(name_in, ROMULUS)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 2 || dimids_in[0] != 0 || dimids_in[1] != 1) ERR; if (nc_inq_unlimdim(ncid, &unlimdimid_in[0])) ERR; if (unlimdimid_in[0] != 0) ERR; if (nc_inq_unlimdims(ncid, &nunlimdims_in, unlimdimid_in)) ERR; if (nunlimdims_in != 2 || unlimdimid_in[0] != 0 || unlimdimid_in[1] != 1) ERR; /* Automatically enddef and close. */ if (nc_close(ncid)) ERR; /* Reopen and check it out. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** Testing ordering of dimensions..."); { #define A_NAME "a" #define B_NAME "b" #define A_LEN 50 #define B_LEN 92 #define A_DIMID 1 #define B_DIMID 0 int ncid; int ndims_in, dimids_in[MAX_DIMS]; size_t len_in; char name_in[NC_MAX_NAME + 1]; int dimid_a, dimid_b; /* Create a file with two dims and nothing else. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, B_NAME, B_LEN, &dimid_b)) ERR; if (nc_def_dim(ncid, A_NAME, A_LEN, &dimid_a)) ERR; if (dimid_b != B_DIMID || dimid_a != A_DIMID) ERR; /* Check out what we've got. */ if (nc_inq_dim(ncid, dimid_a, name_in, &len_in)) ERR; if (len_in != A_LEN || strcmp(name_in, A_NAME)) ERR; if (nc_inq_dim(ncid, dimid_b, name_in, &len_in)) ERR; if (len_in != B_LEN || strcmp(name_in, B_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 2 || dimids_in[0] != 0 || dimids_in[1] != 1) ERR; if (nc_close(ncid)) ERR; /* Reopen and check it out again. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq_dim(ncid, B_DIMID, name_in, &len_in)) ERR; if (len_in != B_LEN || strcmp(name_in, B_NAME)) ERR; if (nc_inq_dim(ncid, A_DIMID, name_in, &len_in)) ERR; if (len_in != A_LEN || strcmp(name_in, A_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 2 || dimids_in[0] != 0 || dimids_in[1] != 1) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** Testing file with just one unlimited dimension and one var..."); { int ncid, dimid, dimids[MAX_DIMS]; int level_varid; int natts_in, ndims_in, dimids_in[MAX_DIMS]; nc_type xtype_in; size_t len_in; char name_in[NC_MAX_NAME + 1]; int unlimdimid_in; size_t start[MAX_DIMS], count[MAX_DIMS]; int varid_in, nvars_in, nunlimdims_in; unsigned long long uint64_data[1] = {42}; /* Create a file with one unlimied dim and nothing else. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, LEVEL_NAME, NC_UNLIMITED, &dimid)) ERR; if (dimid != 0) ERR; dimids[0] = dimid; if (nc_def_var(ncid, LEVEL_NAME, NC_UINT64, 1, dimids, &level_varid)) ERR; if (level_varid != 0) ERR; /* Check it out before enddef. */ if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR; if (len_in != 0 || strcmp(name_in, LEVEL_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1 || dimids_in[0] != 0) ERR; if (nc_inq_unlimdim(ncid, &unlimdimid_in)) ERR; if (unlimdimid_in != 0) ERR; if (nc_inq_unlimdims(ncid, &nunlimdims_in, &unlimdimid_in)) ERR; if (nunlimdims_in != 1 || unlimdimid_in != 0) ERR; if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR; if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 || unlimdimid_in != 0) ERR; if (nc_inq_varid(ncid, LEVEL_NAME, &varid_in)) ERR; if (varid_in != 0) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, LEVEL_NAME) || xtype_in != NC_UINT64 || ndims_in != 1 || dimids_in[0] != 0 || natts_in != 0) ERR; if (nc_inq_varname(ncid, 0, name_in)) ERR; if (strcmp(name_in, LEVEL_NAME)) ERR; /* Now write one record of data to the var. */ start[0] = 0; count[0] = 1; if (nc_put_vara_ulonglong(ncid, 0, start, count, uint64_data)) ERR; /* Check dimension informaiton again. Now the length of this * dimension should be one. */ if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR; if (len_in != 1 || strcmp(name_in, LEVEL_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1 || dimids_in[0] != 0) ERR; if (nc_inq_dimlen(ncid, 0, &len_in)) ERR; if (len_in != 1) ERR; if (nc_inq_unlimdim(ncid, &unlimdimid_in)) ERR; if (unlimdimid_in != 0) ERR; if (nc_inq_unlimdims(ncid, &nunlimdims_in, &unlimdimid_in)) ERR; if (nunlimdims_in != 1 || unlimdimid_in != 0) ERR; if (unlimdimid_in != 0) ERR; if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR; if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 || unlimdimid_in != 0) ERR; if (nc_inq_varid(ncid, LEVEL_NAME, &varid_in)) ERR; if (varid_in != 0) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, LEVEL_NAME) || xtype_in != NC_UINT64 || ndims_in != 1 || dimids_in[0] != 0 || natts_in != 0) ERR; if (nc_inq_varname(ncid, 0, name_in)) ERR; if (strcmp(name_in, LEVEL_NAME)) ERR; /* Close the file. */ if (nc_close(ncid)) ERR; /* Check it out. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR; if (len_in != 1 || strcmp(name_in, LEVEL_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1 || dimids_in[0] != 0) ERR; if (nc_inq_unlimdim(ncid, &unlimdimid_in)) ERR; if (unlimdimid_in != 0) ERR; if (nc_inq_unlimdims(ncid, &nunlimdims_in, &unlimdimid_in)) ERR; if (nunlimdims_in != 1 || unlimdimid_in != 0) ERR; if (unlimdimid_in != 0) ERR; if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR; if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 || unlimdimid_in != 0) ERR; if (nc_inq_varid(ncid, LEVEL_NAME, &varid_in)) ERR; if (varid_in != 0) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, LEVEL_NAME) || xtype_in != NC_UINT64 || ndims_in != 1 || dimids_in[0] != 0 || natts_in != 0) ERR; if (nc_inq_varname(ncid, 0, name_in)) ERR; if (strcmp(name_in, LEVEL_NAME)) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** Testing adding a coordinate var to file with dimension..."); { int ncid, dimid, dimids[MAX_DIMS]; int natts_in, ndims_in, dimids_in[MAX_DIMS]; nc_type xtype_in; size_t len_in; char name_in[NC_MAX_NAME + 1]; int unlimdimid_in; int nvars_in, dim5_varid; /* Create a file with one dim and nothing else. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, DIM5_NAME, DIM5_LEN, &dimid)) ERR; /* Check out what we've got. */ if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR; if (ndims_in != 1 || nvars_in != 0 || natts_in != 0 || unlimdimid_in != -1) ERR; if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR; if (len_in != DIM5_LEN || strcmp(name_in, DIM5_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1 || dimids_in[0] != 0) ERR; if (nc_close(ncid)) ERR; /* Reopen and check it out again. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR; if (ndims_in != 1 || nvars_in != 0 || natts_in != 0 || unlimdimid_in != -1) ERR; if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR; if (len_in != DIM5_LEN || strcmp(name_in, DIM5_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1 || dimids_in[0] != 0) ERR; /* Add a coordinate var for this dimension. */ dimids[0] = 0; if (nc_def_var(ncid, DIM5_NAME, NC_FLOAT, 1, dimids, &dim5_varid)) ERR; /* Check it out. */ if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR; if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 || unlimdimid_in != -1) ERR; if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR; if (len_in != DIM5_LEN || strcmp(name_in, DIM5_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1 || dimids_in[0] != 0) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, DIM5_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 || dimids_in[0] != 0 || natts_in != 0) ERR; if (nc_close(ncid)) ERR; /* Reopen and check it out again. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR; if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 || unlimdimid_in != -1) ERR; if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR; if (len_in != DIM5_LEN || strcmp(name_in, DIM5_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1 || dimids_in[0] != 0) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, DIM5_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 || dimids_in[0] != 0 || natts_in != 0) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** Testing adding a coordinate var to file with unlimited dimension..."); { int ncid, dimid, dimids[MAX_DIMS]; int natts_in, ndims_in, dimids_in[MAX_DIMS]; nc_type xtype_in; size_t len_in; char name_in[NC_MAX_NAME + 1]; int unlimdimid_in; size_t start[MAX_DIMS], count[MAX_DIMS], index[MAX_DIMS]; unsigned short data[2] = {42, 24}, data_in[2]; int nvars_in, hp_varid, dim5_varid; /* Create a file with one dim and one var. This time make * it an unlimited dim. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, DIM5_NAME, NC_UNLIMITED, &dimid)) ERR; if (dimid != 0) ERR; dimids[0] = dimid; if (nc_def_var(ncid, HP_NAME, NC_USHORT, 1, dimids, &hp_varid)) ERR; if (hp_varid != 0) ERR; /* Check out what we've got. */ if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR; if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 || unlimdimid_in != 0) ERR; if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR; if (len_in != 0 || strcmp(name_in, DIM5_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1 || dimids_in[0] != 0) ERR; if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, HP_NAME) || xtype_in != NC_USHORT || ndims_in != 1 || dimids_in[0] != 0 || natts_in != 0) ERR; /* Add a record to the HP variable. */ start[0] = 0; count[0] = 1; if (nc_put_vara(ncid, hp_varid, start, count, data)) ERR; /* Check to ensure dimension grew. */ if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR; if (len_in != 1 || strcmp(name_in, DIM5_NAME)) ERR; /* Reread the value just written. */ index[0] = 0; if (nc_get_var1_ushort(ncid, hp_varid, index, data_in)) ERR; if (data_in[0] != data[0]) ERR; if (nc_close(ncid)) ERR; /* Reopen and check it out again. */ if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR; if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 || unlimdimid_in != 0) ERR; if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR; if (len_in != 1 || strcmp(name_in, DIM5_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1 || dimids_in[0] != 0) ERR; /* Add a coordinate var for this dimension. */ dimids[0] = 0; if (nc_def_var(ncid, DIM5_NAME, NC_FLOAT, 1, dimids, &dim5_varid)) ERR; /* Check it out. */ if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR; if (ndims_in != 1 || nvars_in != 2 || natts_in != 0 || unlimdimid_in != 0) ERR; if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR; if (len_in != 1 || strcmp(name_in, DIM5_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1 || dimids_in[0] != 0) ERR; if (nc_inq_var(ncid, dim5_varid, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, DIM5_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 || dimids_in[0] != 0 || natts_in != 0) ERR; if (nc_close(ncid)) ERR; /* Reopen and check it out again. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR; if (ndims_in != 1 || nvars_in != 2 || natts_in != 0 || unlimdimid_in != 0) ERR; if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR; if (len_in != 1 || strcmp(name_in, DIM5_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1 || dimids_in[0] != 0) ERR; if (nc_inq_var(ncid, dim5_varid, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, DIM5_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 || dimids_in[0] != 0 || natts_in != 0) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** Creating file with 1 data var, 2 dims, and 2 coord. vars..."); { int ncid, dimids[MAX_DIMS]; int lat_dimid, lon_dimid, lat_varid, lon_varid; int pres_varid; char name_in[NC_MAX_NAME + 1]; int natts_in, ndims_in, dimids_in[MAX_DIMS]; nc_type xtype_in; size_t len_in; float lat[LAT_LEN], lon[LON_LEN]; float lat_in[LAT_LEN], lon_in[LON_LEN]; double pres[LAT_LEN][LON_LEN], pres_in[LAT_LEN][LON_LEN]; int i, j; /* Lats and lons suitable for some South American data. */ for (lat[0] = 40.0, i = 1; i < LAT_LEN; i++) lat[i] = lat[i - 1] + .5; for (lon[0] = 20.0, i = 1; i < LON_LEN; i++) lon[i] = lon[i - 1] + 1.5; /* Some phoney 2D pressure data. */ for (i = 0; i < LAT_LEN; i++) for (j = 0; j < LON_LEN; j++) pres[i][j] = 1013.1 + j; /* Create a file. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; /* Define lat and lon dimensions, with associated variables. */ if (nc_def_dim(ncid, LAT_NAME, LAT_LEN, &lat_dimid)) ERR; dimids[0] = lat_dimid; if (nc_def_var(ncid, LAT_NAME, NC_FLOAT, 1, dimids, &lat_varid)) ERR; if (nc_def_dim(ncid, LON_NAME, LON_LEN, &lon_dimid)) ERR; dimids[0] = lon_dimid; if (nc_def_var(ncid, LON_NAME, NC_FLOAT, 1, dimids, &lon_varid)) ERR; /* Define a 2D variable called pressure, with NC_DOUBLE on a lat * lon grid. */ dimids[0] = lat_dimid; dimids[1] = lon_dimid; if (nc_def_var(ncid, PRES_NAME, NC_DOUBLE, 2, dimids, &pres_varid)) ERR; /* Check our dimensions. */ if (nc_inq_dim(ncid, lat_dimid, name_in, &len_in)) ERR; if (len_in != LAT_LEN || strcmp(name_in, LAT_NAME)) ERR; if (nc_inq_dim(ncid, lon_dimid, name_in, &len_in)) ERR; if (len_in != LON_LEN || strcmp(name_in, LON_NAME)) ERR; if (nc_inq_var(ncid, lat_varid, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, LAT_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 || dimids_in[0] != lat_dimid || natts_in != 0) ERR; if (nc_inq_var(ncid, lon_varid, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, LON_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 || dimids_in[0] != lon_dimid || natts_in != 0) ERR; /* Check our data variable. */ if (nc_inq_var(ncid, pres_varid, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, PRES_NAME) || xtype_in != NC_DOUBLE || ndims_in != 2 || dimids_in[0] != lat_dimid || dimids_in[1] != lon_dimid || natts_in != 0) ERR; /* Write our latitude and longitude values. This writes all * metadata to disk too. */ if (nc_put_var_float(ncid, lat_varid, lat)) ERR; if (nc_put_var_float(ncid, lon_varid, lon)) ERR; /* Write our 2D pressure values. */ if (nc_put_var_double(ncid, pres_varid, (double *)pres)) ERR; /* Check our latitude and longitude values. */ if (nc_get_var(ncid, lat_varid, lat_in)) ERR; for (i = 0; i < LAT_LEN; i++) if (lat[i] != lat_in[i]) ERR; if (nc_get_var_float(ncid, lon_varid, lon_in)) ERR; for (i = 0; i < LON_LEN; i++) if (lon[i] != lon_in[i]) ERR; /* Check our pressure values. */ if (nc_get_var_double(ncid, pres_varid, (double *)pres_in)) ERR; for (i = 0; i < LAT_LEN; i++) for (j = 0; j < LON_LEN; j++) if (pres[i][j] != pres_in[i][j]) ERR; /* Close the file. */ if (nc_close(ncid)) ERR; /* Reopen the file and check it out again. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; /* Check our dimensions. */ if (nc_inq_dim(ncid, lat_dimid, name_in, &len_in)) ERR; if (len_in != LAT_LEN || strcmp(name_in, LAT_NAME)) ERR; if (nc_inq_dim(ncid, lon_dimid, name_in, &len_in)) ERR; if (len_in != LON_LEN || strcmp(name_in, LON_NAME)) ERR; if (nc_inq_var(ncid, lat_varid, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, LAT_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 || dimids_in[0] != lat_dimid || natts_in != 0) ERR; if (nc_inq_var(ncid, lon_varid, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, LON_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 || dimids_in[0] != lon_dimid || natts_in != 0) ERR; /* Check our data variable. */ if (nc_inq_var(ncid, pres_varid, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, PRES_NAME) || xtype_in != NC_DOUBLE || ndims_in != 2 || dimids_in[0] != lat_dimid || dimids_in[1] != lon_dimid || natts_in != 0) ERR; /* Check our latitude and longitude values. */ if (nc_get_var(ncid, lat_varid, lat_in)) ERR; for (i = 0; i < LAT_LEN; i++) if (lat[i] != lat_in[i]) ERR; if (nc_get_var_float(ncid, lon_varid, lon_in)) ERR; for (i = 0; i < LON_LEN; i++) if (lon[i] != lon_in[i]) ERR; /* Check our pressure values. */ if (nc_get_var_double(ncid, pres_varid, (double *)pres_in)) ERR; for (i = 0; i < LAT_LEN; i++) for (j = 0; j < LON_LEN; j++) if (pres[i][j] != pres_in[i][j]) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** Creating file with 3 data vars, 4 dims, and 2 coord. vars..."); { int ncid, lat_dimid, dimids[MAX_DIMS]; int level_dimid, time_dimid, elev_varid; int lat_varid, lon_dimid, lon_varid, pres_varid, hp_varid; double pres[LAT_LEN][LON_LEN][LEVEL_LEN][TIME_LEN]; double pres_in[LAT_LEN][LON_LEN][LEVEL_LEN][TIME_LEN]; unsigned short hp[LAT_LEN][LON_LEN][TIME_LEN]; unsigned short hp_in[LAT_LEN][LON_LEN][TIME_LEN]; unsigned long long elev[LAT_LEN][LON_LEN], elev_in[LAT_LEN][LON_LEN]; size_t start[4], count[4]; int nvars, ndims, natts, unlimdimid; int natts_in, ndims_in, dimids_in[MAX_DIMS]; nc_type xtype_in; size_t len_in; char name_in[NC_MAX_NAME + 1]; float lat[LAT_LEN], lon[LON_LEN]; float lat_in[LAT_LEN], lon_in[LON_LEN]; int i, j, k, l; /* Some phony 4D pressure data. */ for (i = 0; i < LAT_LEN; i++) for (j = 0; j < LON_LEN; j++) for (k = 0; k < LEVEL_LEN; k++) for (l = 0; l <TIME_LEN; l++) pres[i][j][k][l] = 1013.1 + j; /* Some phony 3D hp data. */ for (i = 0; i < LAT_LEN; i++) for (j = 0; j < LON_LEN; j++) for (l = 0; l <TIME_LEN; l++) hp[i][j][l] = 100 + l; /* Some phony 2D elevaton data. */ for (i = 0; i < LAT_LEN; i++) for (j = 0; j < LON_LEN; j++) elev[i][j] = 1010101022223333ULL + i + j; /* Some phony 1D lats and lons. */ for (i = 0; i < LAT_LEN; i++) lat[i] = i * 5.; for (i = 0; i < LON_LEN; i++) lon[i] = i * 5.; if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; /* Define lat, lon, level, and timestep dimensions, with * associated coordinate variables for lat and lon only. Time is * an unlimited dimension. */ if (nc_def_dim(ncid, LAT_NAME, LAT_LEN, &lat_dimid)) ERR; if (lat_dimid != LAT_DIMID) ERR; dimids[0] = lat_dimid; if (nc_def_var(ncid, LAT_NAME, NC_FLOAT, 1, dimids, &lat_varid)) ERR; if (lat_varid != LAT_VARID) ERR; if (nc_def_dim(ncid, LON_NAME, LON_LEN, &lon_dimid)) ERR; if (lon_dimid != LON_DIMID) ERR; dimids[0] = lon_dimid; if (nc_def_var(ncid, LON_NAME, NC_FLOAT, 1, dimids, &lon_varid)) ERR; if (lon_varid != LON_VARID) ERR; if (nc_def_dim(ncid, LEVEL_NAME, LEVEL_LEN, &level_dimid)) ERR; if (level_dimid != LEVEL_DIMID) ERR; if (nc_def_dim(ncid, TIME_NAME, NC_UNLIMITED, &time_dimid)) ERR; if (time_dimid != TIME_DIMID) ERR; /* Define a 4D NC_DOUBLE variable called pressure. */ dimids[0] = lat_dimid; dimids[1] = lon_dimid; dimids[2] = level_dimid; dimids[3] = time_dimid; if (nc_def_var(ncid, PRES_NAME, NC_DOUBLE, 4, dimids, &pres_varid)) ERR; if (pres_varid != PRES_VARID) ERR; /* Define a 2D variable for surface elevation. Use NC_INT64 * because our units for this is Angstroms from Earth's * Center. */ if (nc_def_var(ncid, ELEV_NAME, NC_INT64, 2, dimids, &elev_varid)) ERR; if (elev_varid != ELEV_VARID) ERR; /* Define a 3D NC_USHORT variable to store the number of Harry * Potter books in this grid square at this time (ignore HP * books in airplanes, dirigibles, hot air balloons, space * capsules, hang-gliders, parachutes, and flying on brooms). */ dimids[2] = time_dimid; if (nc_def_var(ncid, HP_NAME, NC_USHORT, 3, dimids, &hp_varid)) ERR; if (hp_varid != HP_VARID) ERR; /* Did all our stuff make it into the internal metadata model * intact? */ /* Check our dimensions. */ if (nc_inq_dim(ncid, LAT_DIMID, name_in, &len_in)) ERR; if (len_in != LAT_LEN || strcmp(name_in, LAT_NAME)) ERR; if (nc_inq_dim(ncid, LON_DIMID, name_in, &len_in)) ERR; if (len_in != LON_LEN || strcmp(name_in, LON_NAME)) ERR; if (nc_inq_dim(ncid, LEVEL_DIMID, name_in, &len_in)) ERR; if (len_in != LEVEL_LEN || strcmp(name_in, LEVEL_NAME)) ERR; if (nc_inq_dim(ncid, TIME_DIMID, name_in, &len_in)) ERR; if (len_in != 0 || strcmp(name_in, TIME_NAME)) ERR; /* Check our coordinate variables. */ if (nc_inq_var(ncid, LAT_VARID, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, LAT_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 || dimids_in[0] != LAT_DIMID || natts_in != 0) ERR; if (nc_inq_var(ncid, LON_VARID, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, LON_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 || dimids_in[0] != LON_DIMID || natts_in != 0) ERR; /* Check our data variables. */ if (nc_inq_var(ncid, PRES_VARID, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, PRES_NAME) || xtype_in != NC_DOUBLE || ndims_in != 4 || dimids_in[0] != LAT_DIMID || dimids_in[1] != LON_DIMID || dimids_in[2] != LEVEL_DIMID || dimids_in[3] != TIME_DIMID || natts_in != 0) ERR; if (nc_inq_var(ncid, ELEV_VARID, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, ELEV_NAME) || xtype_in != NC_INT64 || ndims_in != 2 || dimids_in[0] != LAT_DIMID || dimids_in[1] != LON_DIMID || natts_in != 0) ERR; if (nc_inq_var(ncid, HP_VARID, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (strcmp(name_in, HP_NAME) || xtype_in != NC_USHORT || ndims_in != 3 || dimids_in[0] != LAT_DIMID || dimids_in[1] != LON_DIMID || dimids_in[2] != TIME_DIMID || natts_in != 0) ERR; /* Write our latitude and longitude values. This writes all * metadata to disk too. */ if (nc_put_var_float(ncid, lat_varid, lat)) ERR; if (nc_put_var_float(ncid, lon_varid, lon)) ERR; /* Write our 4D pressure, elevation, and hp data. But this * should do nothing for pressure and hp, because these are * record vars, and nc_put_var_* doesn't do anything to record * vars, because it doesn't know how big the var is supposed to * be. */ if (nc_put_var_double(ncid, pres_varid, (double *)pres)) ERR; if (nc_put_var_ulonglong(ncid, elev_varid, (unsigned long long *)elev)) ERR; if (nc_put_var_ushort(ncid, hp_varid, (unsigned short *)hp)) ERR; /* Check our latitude and longitude values. */ if (nc_get_var(ncid, lat_varid, lat_in)) ERR; for (i = 0; i < LAT_LEN; i++) if (lat[i] != lat_in[i]) ERR; if (nc_get_var_float(ncid, lon_varid, lon_in)) ERR; for (i = 0; i < LON_LEN; i++) if (lon[i] != lon_in[i]) ERR; /* Make sure our pressure and hp variables are still * empty. get_var calls will return no error, but fetch no * data. */ if (nc_inq_var(ncid, pres_varid, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR; if (nc_inq_dim(ncid, dimids_in[3], NULL, &len_in)) ERR; if (len_in != 0) ERR; memset(pres_in, 0, sizeof(pres_in)); if (nc_get_var_double(ncid, pres_varid, (double *)pres_in)) ERR; /* Check our pressure values. */ for (i = 0; i < LAT_LEN; i++) for (j = 0; j < LON_LEN; j++) for (k = 0; k < LEVEL_LEN; k++) for (l = 0; l <TIME_LEN; l++) if (0 != pres_in[i][j][k][l]) ERR; if (nc_inq_var(ncid, hp_varid, NULL, NULL, &ndims_in, dimids_in, NULL)) ERR; if (nc_inq_dim(ncid, dimids_in[2], NULL, &len_in)) ERR; if (len_in != 0) ERR; memset(hp_in, 0, sizeof(hp_in)); if (nc_get_var_ushort(ncid, hp_varid, (unsigned short *)hp_in)) ERR; /* Check our hp values. */ for (i = 0; i < LAT_LEN; i++) for (j = 0; j < LON_LEN; j++) for (l = 0; l <TIME_LEN; l++) if (0 != hp_in[i][j][l]) ERR; /* Now use nc_put_vara to really write pressure and hp * data. Write TIME_LEN (4) records of each. */ start[0] = start[1] = start[2] = start[3] = 0; count[0] = LAT_LEN; count[1] = LON_LEN; count[2] = LEVEL_LEN; count[3] = TIME_LEN; if (nc_put_vara(ncid, pres_varid, start, count, (double *)pres)) ERR; count[2] = TIME_LEN; if (nc_put_vara(ncid, hp_varid, start, count, (double *)hp)) ERR; /* Check our pressure values. */ if (nc_get_var_double(ncid, pres_varid, (double *)pres_in)) ERR; for (i = 0; i < LAT_LEN; i++) for (j = 0; j < LON_LEN; j++) for (k = 0; k < LEVEL_LEN; k++) for (l = 0; l <TIME_LEN; l++) if (pres[i][j][k][l] != pres_in[i][j][k][l]) ERR; /* Check our elevation values. */ if (nc_get_var_ulonglong(ncid, elev_varid, (unsigned long long *)elev_in)) ERR; for (i = 0; i < LAT_LEN; i++) for (j = 0; j < LON_LEN; j++) if (elev[i][j] != elev_in[i][j]) ERR; /* Check our hp values. */ if (nc_get_var_ushort(ncid, hp_varid, (unsigned short *)hp_in)) ERR; for (i = 0; i < LAT_LEN; i++) for (j = 0; j < LON_LEN; j++) for (l = 0; l <TIME_LEN; l++) if (hp[i][j][l] != hp_in[i][j][l]) ERR; /* Close the file. */ if (nc_close(ncid)) ERR; /* Reopen the file and check it out again. At the moment, we * can't count on the varids and dimids being the same. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR; if (ndims != 4 || nvars != 5 || natts != 0) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** Testing file with dims and only some coordinate vars..."); #define NDIMS_EX 4 #define NLAT 6 #define NLON 12 #define LAT_NAME_EX "latitude" #define LON_NAME_EX "longitude" #define NREC 2 #define REC_NAME "time" #define LVL_NAME "level" #define NLVL 2 /* Names of things. */ #define PRES_NAME "pressure" #define TEMP_NAME "temperature" #define UNITS "units" #define DEGREES_EAST "degrees_east" #define DEGREES_NORTH "degrees_north" /* There are 4 vars, two for data, two for coordinate data. */ #define NVARS_EX 4 /* These are used to construct some example data. */ #define SAMPLE_PRESSURE 900 #define SAMPLE_TEMP 9.0 #define START_LAT 25.0 #define START_LON -125.0 /* For the units attributes. */ #define UNITS "units" #define PRES_UNITS "hPa" #define TEMP_UNITS "celsius" #define LAT_UNITS "degrees_north" #define LON_UNITS "degrees_east" #define MAX_ATT_LEN 80 { /* IDs for the netCDF file, dimensions, and variables. */ int ncid, lon_dimid, lat_dimid; int lon_varid; int ndims_in; int dimid[NDIMS_EX]; char dim_name_in[NDIMS_EX][NC_MAX_NAME]; int i; /* Create the file. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; /* Define the dimensions. */ if (nc_def_dim(ncid, LAT_NAME_EX, NLAT, &lat_dimid)) ERR; if (nc_def_dim(ncid, LON_NAME_EX, NLON, &lon_dimid)) ERR; /* Define a coordinate var. */ if (nc_def_var(ncid, LON_NAME_EX, NC_FLOAT, 1, &lon_dimid, &lon_varid)) ERR; /* Close the file. */ if (nc_close(ncid)) ERR; if (nc_open(FILE_NAME, 0, &ncid)) ERR; /* Check dimensions. */ ndims_in = 0; if (nc_inq_dimids(ncid, &ndims_in, dimid, 0)) ERR; if (ndims_in != 2) ERR; for (i = 0; i < 2; i++) { if (dimid[i] != i) ERR; if (nc_inq_dimname(ncid, i, dim_name_in[i])) ERR; } if (strcmp(dim_name_in[0], LAT_NAME_EX) || strcmp(dim_name_in[1], LON_NAME_EX)) ERR; /* Close the file. */ if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** Testing file with just one very long dimension..."); { #define VERY_LONG_LEN (size_t)4500000000LL int ncid, dimid; int ndims_in, dimids_in[MAX_DIMS]; size_t len_in; char name_in[NC_MAX_NAME + 1]; int varid_in; if (SIZEOF_SIZE_T == 8) { /* Create a file with one dim and nothing else. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, LAT_NAME, VERY_LONG_LEN, &dimid)) ERR; /* Check it out. */ if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR; if (len_in != ((SIZEOF_SIZE_T == 8) ? VERY_LONG_LEN : NC_MAX_UINT) || strcmp(name_in, LAT_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1) ERR; if (nc_inq_dimid(ncid, LAT_NAME, &varid_in)) ERR; if (varid_in != 0) ERR; if (nc_inq_dimname(ncid, 0, name_in)) ERR; if (strcmp(name_in, LAT_NAME)) ERR; if (nc_inq_dimlen(ncid, 0, &len_in)) ERR; if (len_in != ((SIZEOF_SIZE_T == 8) ? VERY_LONG_LEN : NC_MAX_UINT)) ERR; if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR; if (ndims_in != 0) ERR; if (nc_close(ncid)) ERR; /* Reopen and check it out again. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; /* Check it out. */ if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR; if (len_in != ((SIZEOF_SIZE_T == 8) ? VERY_LONG_LEN : NC_MAX_UINT) || strcmp(name_in, LAT_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1) ERR; if (nc_inq_dimid(ncid, LAT_NAME, &varid_in)) ERR; if (varid_in != 0) ERR; if (nc_inq_dimname(ncid, 0, name_in)) ERR; if (strcmp(name_in, LAT_NAME)) ERR; if (nc_inq_dimlen(ncid, 0, &len_in)) ERR; if (len_in != ((SIZEOF_SIZE_T == 8) ? VERY_LONG_LEN : NC_MAX_UINT)) ERR; if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR; if (ndims_in != 0) ERR; if (nc_close(ncid)) ERR; } } SUMMARIZE_ERR; printf("*** Testing reference file with just one very long dimension..."); { #define REF_FILE_NAME "ref_tst_dims.nc" int ncid, dimid = 0; int ndims_in, dimids_in[MAX_DIMS]; size_t len_in; char name_in[NC_MAX_NAME + 1]; int varid_in; char file_in[NC_MAX_NAME + 1]; int ret; strcpy(file_in, ""); if (getenv("srcdir")) { strcat(file_in, getenv("srcdir")); strcat(file_in, "/"); } strcat(file_in, REF_FILE_NAME); /* Reopen and check it out again. */ if (nc_open(file_in, NC_NOWRITE, &ncid)) ERR; /* Check it out. */ ret = nc_inq_dim(ncid, dimid, name_in, &len_in); if ((SIZEOF_SIZE_T >= 8 && ret) || (SIZEOF_SIZE_T < 8 && ret != NC_EDIMSIZE)) ERR; if (SIZEOF_SIZE_T < 8) { if (len_in != NC_MAX_UINT) ERR; } else { if (len_in != VERY_LONG_LEN) ERR; } if (strcmp(name_in, LAT_NAME)) ERR; if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR; if (ndims_in != 1) ERR; if (nc_inq_dimid(ncid, LAT_NAME, &varid_in)) ERR; if (varid_in != 0) ERR; if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR; if (ndims_in != 0) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; FINAL_RESULTS; }
/* Has to be at the bottom because it uses many * other functions */ void sdatio_open_file(struct sdatio_file * sfile ) { /*printf("called\n");*/ int retval; int ndims, nvars; int i, j; struct sdatio_dimension * sdim; struct sdatio_variable * svar; size_t lengthp; int nunlimdims; int *unlimdims; int is_unlimited; char * name_tmp; int * vardimids; char * dimension_list; nc_type vartype; int vartypeint; int dummy; int *nunlim; DEBUG_MESS("starting sdatio_open_file\n"); retval = 0; if (sfile->is_open){ printf("ERROR: The supplied sdatio_file struct corresponds to an already open file.\n"); abort(); } /* We make the choice to always open the file in readwrite mode*/ sfile->mode = sfile->mode|NC_WRITE; DEBUG_MESS("sdatio_open_file opening file\n"); /* Open the file*/ if (sfile->is_parallel) { #ifdef PARALLEL if ((retval = nc_open_par(sfile->name, sfile->mode, *(sfile->communicator), MPI_INFO_NULL, &(sfile->nc_file_id)))) ERR(retval); #else printf("sdatio was built without --enable-parallel, sdatio_create_file will not work for parallel files\n"); abort(); #endif } else { if ((retval = nc_open(sfile->name, sfile->mode, &(sfile->nc_file_id)))) ERR(retval); } DEBUG_MESS("sdatio_open_file opened file\n"); /*Initialize object file data*/ sfile->is_open = 1; sfile->n_dimensions = 0; sfile->n_variables = 0; sfile->data_written = 0; /* Get number of dimensions in the file*/ if ((retval = nc_inq_ndims(sfile->nc_file_id, &ndims))) ERR(retval); /* Allocate some temp storate*/ name_tmp = (char*)malloc(sizeof(char*)*(NC_MAX_NAME+1)); /* Get a list of unlimited dimensions*/ if ((retval = nc_inq_unlimdims(sfile->nc_file_id, &nunlimdims, NULL))) ERR(retval); unlimdims = (int*)malloc(sizeof(int*)*nunlimdims); if ((retval = nc_inq_unlimdims(sfile->nc_file_id, &nunlimdims, unlimdims))) ERR(retval); /* Add each dimension to the sfile object*/ for (i=0; i<ndims; i++){ if ((retval = nc_inq_dim(sfile->nc_file_id, i, name_tmp, &lengthp))) ERR(retval); sdim = (struct sdatio_dimension *) malloc(sizeof(struct sdatio_dimension)); /*if ((retval = nc_def_dim(sfile->nc_file_id, dimension_name, size, &(sdim->nc_id)))) ERR(retval);*/ /*}*/ /*sdatio_end_definitions(sfile);*/ is_unlimited = 0; for(j=0; j<nunlimdims; j++) if (unlimdims[j] == i) is_unlimited = 1; if (is_unlimited) { sdim->size = SDATIO_UNLIMITED; /* We choose the first write to unlimited variables to be the last * existing record. Users can easily move to the next by * calling sdatio_increment_start before writing anything */ sdim->start = lengthp-1; } else { sdim->size = lengthp; sdim->start = 0; } if (strlen(name_tmp)>1){ sfile->has_long_dim_names = 1; /*printf("Dimension names can only be one character long!\n");*/ /*abort();*/ } sdim->nc_id = i; sdim->name = (char *)malloc(sizeof(char)*(strlen(name_tmp)+1)); strcpy(sdim->name, name_tmp); sdatio_append_dimension(sfile, sdim); } DEBUG_MESS("Finished reading dimensions\n"); /* Get the number of variables in the file*/ if ((retval = nc_inq_nvars(sfile->nc_file_id, &nvars))) ERR(retval); /* Add each variable to the sfile object*/ for (i=0; i<nvars; i++){ if ((retval = nc_inq_varndims(sfile->nc_file_id, i, &ndims))) ERR(retval); vardimids = (int*)malloc(sizeof(int)*ndims); if ((retval = nc_inq_var(sfile->nc_file_id, i, name_tmp, &vartype, &ndims, vardimids, &dummy))) ERR(retval); vartypeint = vartype; vartypeint = sdatio_sdatio_variable_type(vartypeint); svar = (struct sdatio_variable *) malloc(sizeof(struct sdatio_variable)); /*Set variable id*/ svar->nc_id = i; /* Set variable name*/ svar->name = (char *)malloc(sizeof(char)*(strlen(name_tmp)+1)); strcpy(svar->name, name_tmp); /*ndims = strlen(dimension_list);*/ svar->ndims = ndims; DEBUG_MESS("ndims = %d for variable %s\n", ndims, name_tmp); /* Set the dimension_ids*/ svar->dimension_ids = vardimids; /*sdatio_get_dimension_ids(sfile, dimension_list, svar);*/ sdatio_get_dimension_list(sfile, vardimids, svar); /*svar->dimension_ids = dimension_ids;*/ DEBUG_MESS("Setting type for variable %s\n", svar->name); switch (vartypeint){ case SDATIO_INT: svar->type_size = sizeof(int); break; case SDATIO_FLOAT: svar->type_size = sizeof(float); break; case SDATIO_DOUBLE: svar->type_size = sizeof(double); break; case SDATIO_CHAR: svar->type_size = sizeof(char); break; default: printf("Unknown type in sdatio_create_variable\n"); abort(); } svar->type = vartypeint; DEBUG_MESS("Allocating manual starts and counts for variable %s; ndims %d\n", svar->name, ndims); svar->manual_starts=(int*)malloc(sizeof(int)*ndims); svar->manual_counts=(int*)malloc(sizeof(int)*ndims); svar->manual_offsets=(int*)malloc(sizeof(int)*ndims); DEBUG_MESS("Setting manual starts and counts for variable %s\n", svar->name); for (j=0;j<ndims;j++){ svar->manual_starts[j]=-1; svar->manual_counts[j]=-1; svar->manual_offsets[j]=-1; } DEBUG_MESS("Starting sdatio_append_variable\n"); sdatio_append_variable(sfile, svar); DEBUG_MESS("Ending sdatio_append_variable\n"); #ifdef PARALLEL if (sfile->is_parallel){ sdatio_number_of_unlimited_dimensions(sfile, svar->name, &nunlim); if (nunlim > 0) if ((retval = nc_var_par_access(sfile->nc_file_id, svar->nc_id, NC_COLLECTIVE))) ERR(retval); } #endif /*vartypeint = */ } DEBUG_MESS("Finished reading variables\n"); free(unlimdims); free(name_tmp); }
void R_nc4_inq_dim( int *ncid, int *dimid, char **dimname, int *dimlen, int *unlim, int *retval ) { char name[NC_MAX_NAME]; size_t len; int i, n_unlimdims, *unlimids; *retval = nc_inq_dim(*ncid, *dimid, name, &len); if( *retval != NC_NOERR ) { Rprintf( "Error in R_nc4_inq_dim on nc_inq_dim call with ncid=%d and dimid=%d: %s\n", *ncid, *dimid, nc_strerror(*retval) ); return; } *dimlen = (int)len; /* NOTE NOTE NOTE!! This assumes that the calling process * allocated storage of at least NC_MAX_NAME! */ strcpy(dimname[0], name); /* Now set *unlim to 1 if this is an unlimited dimension, * and to 0 otherwise. Start by getting NUMBER of * unlimited dimensions. */ *retval = nc_inq_unlimdims( *ncid, &n_unlimdims, NULL ); if( *retval != NC_NOERR ) { Rprintf( "Error in R_nc4_inq_dim on nc_inq_unlimdims call (1): %s\n", nc_strerror(*retval) ); return; } /* There ARE no unlmited dims, so this can't be one! */ if( n_unlimdims == 0 ) { *unlim = 0; return; } /* Get IDs of the unlimited dims */ unlimids = (int *)malloc( sizeof(int)*n_unlimdims ); if( unlimids == NULL ) { Rprintf( "Error in R_nc4_inq_dim: failed to allocate %d ints\n", n_unlimdims ); *retval = -1; return; } *retval = nc_inq_unlimdims( *ncid, NULL, unlimids ); if( *retval != NC_NOERR ) { Rprintf( "Error in R_nc4_inq_dim on nc_inq_unlimdims call (2): %s\n", nc_strerror(*retval) ); return; } /* See if there is a match between this dimid and the list of unlimited dim ids */ *unlim = 0; for( i=0; i<n_unlimdims; i++ ) if( unlimids[i] == *dimid ) { *unlim = 1; break; } free( unlimids ); }