NcValues* NcVar::values( void ) const { int ndims = num_dims(); size_t crnr[NC_MAX_DIMS]; size_t edgs[NC_MAX_DIMS]; for (int i = 0; i < ndims; i++) { crnr[i] = 0; edgs[i] = get_dim(i)->size(); } NcValues* valp = get_space(); int status; switch (type()) { case ncFloat: status = NcError::set_err( nc_get_vara_float(the_file->id(), the_id, crnr, edgs, (float *)valp->base()) ); break; case ncDouble: status = NcError::set_err( nc_get_vara_double(the_file->id(), the_id, crnr, edgs, (double *)valp->base()) ); break; case ncInt: status = NcError::set_err( nc_get_vara_int(the_file->id(), the_id, crnr, edgs, (int *)valp->base()) ); break; case ncShort: status = NcError::set_err( nc_get_vara_short(the_file->id(), the_id, crnr, edgs, (short *)valp->base()) ); break; case ncByte: status = NcError::set_err( nc_get_vara_schar(the_file->id(), the_id, crnr, edgs, (signed char *)valp->base()) ); break; case ncChar: status = NcError::set_err( nc_get_vara_text(the_file->id(), the_id, crnr, edgs, (char *)valp->base()) ); break; case ncNoType: default: return 0; } if (status != NC_NOERR) return 0; return valp; }
/* * 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; }
CPLErr GMTRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff, int nBlockYOff, void * pImage ) { size_t start[2], edge[2]; int nErr = NC_NOERR; int cdfid = ((GMTDataset *) poDS)->cdfid; CPLMutexHolderD(&hNCMutex); start[0] = nBlockYOff * nBlockXSize; edge[0] = nBlockXSize; if( eDataType == GDT_Byte ) nErr = nc_get_vara_uchar( cdfid, nZId, start, edge, (unsigned char *) pImage ); else if( eDataType == GDT_Int16 ) nErr = nc_get_vara_short( cdfid, nZId, start, edge, (short int *) pImage ); else if( eDataType == GDT_Int32 ) { if( sizeof(long) == 4 ) nErr = nc_get_vara_long( cdfid, nZId, start, edge, (long *) pImage ); else nErr = nc_get_vara_int( cdfid, nZId, start, edge, (int *) pImage ); } else if( eDataType == GDT_Float32 ) nErr = nc_get_vara_float( cdfid, nZId, start, edge, (float *) pImage ); else if( eDataType == GDT_Float64 ) nErr = nc_get_vara_double( cdfid, nZId, start, edge, (double *) pImage ); if( nErr != NC_NOERR ) { CPLError( CE_Failure, CPLE_AppDefined, "GMT scanline fetch failed: %s", nc_strerror( nErr ) ); return CE_Failure; } else return CE_None; }
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); }
/********************************************************************* void mpp_get_var_value_block(int fid, int vid, const size_t *start, const size_t *nread, void *data) read part of var data, the part is defined by start and nread. *********************************************************************/ void mpp_get_var_value_block(int fid, int vid, const size_t *start, const size_t *nread, void *data) { int status; char errmsg[512]; if(fid<0 || fid >=nfiles) mpp_error("mpp_io(mpp_get_var_value_block): invalid fid number, fid should be " "a nonnegative integer that less than nfiles"); if(vid<0 || vid >=files[fid].nvar) mpp_error("mpp_io(mpp_get_var_value_block): invalid vid number, vid should be " "a nonnegative integer that less than nvar"); switch(files[fid].var[vid].type) { case NC_DOUBLE:case NC_FLOAT: status = nc_get_vara_double(files[fid].ncid, files[fid].var[vid].fldid, start, nread, data); break; case NC_INT: status = nc_get_vara_int(files[fid].ncid, files[fid].var[vid].fldid, start, nread, data); break; case NC_SHORT: status = nc_get_vara_short(files[fid].ncid, files[fid].var[vid].fldid, start, nread, data); break; case NC_CHAR: status = nc_get_vara_text(files[fid].ncid, files[fid].var[vid].fldid, start, nread, data); break; default: sprintf(errmsg, "mpp_io(mpp_get_var_value_block): field %s in file %s has an invalid type, " "the type should be NC_DOUBLE, NC_FLOAT, NC_INT, NC_SHORT or NC_CHAR", files[fid].var[vid].name, files[fid].name ); mpp_error(errmsg); } if(status != NC_NOERR) { sprintf(errmsg, "mpp_io(mpp_get_var_value_block): Error in getting value of variable %s from file %s", files[fid].var[vid].name, files[fid].name ); netcdf_error(errmsg, status); } }; /* mpp_get_var_value_block */
/* This function use the first dimension to parallel and reads and writes all needed data only once, there is no iteration. Stride is not supported */ int extract_unary_1D_all(int mpi_rank,int mpi_size, int ncid,int vlid,int ncidout,int vlidout,int ndims,nc_type vtype,size_t *shape,size_t *begins,size_t *ends,size_t preLen,size_t *outLen){ int i,res; size_t *start=(size_t*)malloc(sizeof(size_t)*ndims); //start position for reading element from input file size_t *countOut=(size_t *)malloc(sizeof(size_t)*ndims); size_t *startOut=(size_t*)malloc(sizeof(size_t)*ndims); //start position for writing element to output file size_t *shapeOut=(size_t*)malloc(sizeof(size_t)*ndims); //output dimension shape size_t startOut0; size_t countOut0; int len0=1; int lenOut=1; for(i=0;i<ndims;++i){ /* shapeOut[0]=(ends[0]-begins[0])/strides[0]+1;*/ shapeOut[i]=ends[i]-begins[i]+1; lenOut*=shapeOut[i]; if(i>0){ startOut[i]=0; countOut[i]=shapeOut[i]; start[i]=begins[i]; len0*=ends[i]-begins[i]+1; } } if(outLen!=NULL) *outLen=lenOut; if(shapeOut[0]>=mpi_size){ startOut0=mpi_rank*(shapeOut[0]/mpi_size); if(mpi_rank!=mpi_size-1){ countOut0=(shapeOut[0]/mpi_size); }else{ countOut0=shapeOut[0]-startOut0; } }else{ if(mpi_rank<shapeOut[0]){ startOut0=mpi_rank; countOut0=1; }else{ return 0; } } int dataEnd=countOut0*len0; printf("mpi_rank %d,countOut0 %d\n",mpi_rank,countOut0); startOut[0]=startOut0+preLen/len0; countOut[0]=countOut0; /* start[0]=begins[0]+startOut0*strides[0];*/ start[0]=begins[0]+startOut0; switch(vtype){ case NC_BYTE: { unsigned char* dataOut=(unsigned char *)malloc(sizeof(unsigned char)*dataEnd); if((res=nc_get_vara_uchar(ncid,vlid,start,countOut,dataOut))) BAIL(res); if((res=nc_put_vara_uchar(ncidout,vlidout,startOut,countOut,(unsigned char *)dataOut))) BAIL(res); free(dataOut); } break; case NC_CHAR: { char* dataOut=(char *)malloc(sizeof(char)*dataEnd); if((res=nc_get_vara_schar(ncid,vlid,start,countOut,(signed char *)dataOut))) BAIL(res); if((res=nc_put_vara_schar(ncidout,vlidout,startOut,countOut,(signed char *)dataOut))) BAIL(res); free(dataOut); } break; case NC_SHORT: { short *dataOut=(short *)malloc(sizeof(short)*dataEnd); if((res=nc_get_vara_short(ncid,vlid,start,countOut,(short *)dataOut))) BAIL(res); if((res=nc_put_vara_short(ncidout,vlidout,startOut,countOut,(short *)dataOut))) BAIL(res); free(dataOut); } break; case NC_INT: { int * dataOut=(int *)malloc(sizeof(int)*dataEnd); if((res=nc_get_vara_int(ncid,vlid,start,countOut,(int *)dataOut))) BAIL(res); if((res=nc_put_vara_int(ncidout,vlidout,startOut,countOut,(int *)dataOut))) BAIL(res); free(dataOut); } break; case NC_FLOAT: { float * dataOut=(float *)malloc(sizeof(float)*dataEnd); if((res=nc_get_vara_float(ncid,vlid,start,countOut,(float *)dataOut))) BAIL(res); if((res=nc_put_vara_float(ncidout,vlidout,startOut,countOut,(float *)dataOut))) BAIL(res); free(dataOut); } break; case NC_DOUBLE: { double* dataOut=(double *)malloc(sizeof(double)*dataEnd); if((res=nc_get_vara_double(ncid,vlid,start,countOut,dataOut))) BAIL(res); if((res=nc_put_vara_double(ncidout,vlidout,startOut,countOut,(double *)dataOut))) BAIL(res); free(dataOut); } break; default: printf("Unknown data type\n"); } free(start); free(startOut); free(shapeOut); free(countOut); return 0; }
int extract_unary_1D(int mpi_rank,int mpi_size, int ncid,int vlid,int ncidout,int vlidout,int ndims,nc_type vtype,size_t *shape,size_t *begins,size_t *ends, ptrdiff_t *strides,size_t preLen,size_t *outLen){ int i,j,res; size_t *divider=(size_t *)malloc(sizeof(size_t)*ndims); //input divider size_t *dividerOut=(size_t *)malloc(sizeof(size_t)*ndims); // output divider size_t *start=(size_t*)malloc(sizeof(size_t)*ndims); //start position for reading element from input file size_t *count=(size_t*)malloc(sizeof(size_t)*ndims); size_t *countOut=(size_t *)malloc(sizeof(size_t)*ndims); size_t *startOut=(size_t*)malloc(sizeof(size_t)*ndims); //start position for writing element to output file size_t *shapeOut=(size_t*)malloc(sizeof(size_t)*ndims); //output dimension shape size_t startOut0; size_t countOut0; int len0=1; int lenOut=1; for(i=0;i<ndims;++i){ shapeOut[i]=(ends[i]-begins[i])/strides[i]+1; lenOut*=shapeOut[i]; if(i>0){ startOut[i]=0; countOut[i]=shapeOut[i]; start[i]=begins[i]; count[i]=ends[i]-begins[i]+1; len0*=ends[i]-begins[i]+1; } } if(outLen!=NULL) *outLen=lenOut; if(shapeOut[0]>=mpi_size){ startOut0=mpi_rank*(shapeOut[0]/mpi_size); if(mpi_rank!=mpi_size-1){ countOut0=(shapeOut[0]/mpi_size); }else{ countOut0=shapeOut[0]-startOut0; } }else{ if(mpi_rank<shapeOut[0]){ startOut0=mpi_rank; countOut0=1; }else{ return 0; } } int dataEnd=lenOut/shapeOut[0]; void* data=(void*)malloc(sizeof(double)*len0); void* dataOut=(void*)malloc(sizeof(double)*dataEnd); size_t* poses=(size_t*)malloc(sizeof(size_t)*dataEnd); getDivider(ndims,count,divider); getDivider(ndims,countOut,dividerOut); transfer_pos(poses,ndims-1,strides,dataEnd,dividerOut,divider); printf("mpi_rank %d,countOut0 %d\n",mpi_rank,countOut0); for(i=0;i<countOut0;++i){ startOut[0]=startOut0+i+preLen/len0; countOut[0]=1; start[0]=begins[0]+(startOut0+i)*strides[0]; count[0]=1; switch(vtype){ case NC_BYTE: if((res=nc_get_vara_uchar(ncid,vlid,start,count,(unsigned char *)data))) BAIL(res); if(len0==dataEnd){ if((res=nc_put_vara_uchar(ncidout,vlidout,startOut,countOut,(unsigned char *)data))) BAIL(res); }else{ for(j=0;j<dataEnd;++j){ ((unsigned char *)dataOut)[j]=((unsigned char *)data)[poses[j]]; } if((res=nc_put_vara_uchar(ncidout,vlidout,startOut,countOut,(unsigned char *)dataOut))) BAIL(res); } break; case NC_CHAR: if((res=nc_get_vara_schar(ncid,vlid,start,count,(signed char *)data))) BAIL(res); if(len0==dataEnd){ if((res=nc_put_vara_schar(ncidout,vlidout,startOut,countOut,(signed char *)data))) BAIL(res); }else{ for(j=0;j<dataEnd;++j){ ((signed char *)dataOut)[j]=((signed char *)data)[poses[j]]; } if((res=nc_put_vara_schar(ncidout,vlidout,startOut,countOut,(signed char *)dataOut))) BAIL(res); } break; case NC_SHORT: if((res=nc_get_vara_short(ncid,vlid,start,count,data))) BAIL(res); if(len0==dataEnd){ if((res=nc_put_vara_short(ncidout,vlidout,startOut,countOut,(short *)data))) BAIL(res); }else{ for(j=0;j<dataEnd;++j){ ((short *)dataOut)[j]=((short *)data)[poses[j]]; } if((res=nc_put_vara_short(ncidout,vlidout,startOut,countOut,(short *)dataOut))) BAIL(res); } break; case NC_INT: if((res=nc_get_vara_int(ncid,vlid,start,count,(int *)data))) BAIL(res); if(len0==dataEnd){ if((res=nc_put_vara_int(ncidout,vlidout,startOut,countOut,(int *)data))) BAIL(res); }else{ for(j=0;j<dataEnd;++j){ ((int *)dataOut)[j]=((int *)data)[poses[j]]; } if((res=nc_put_vara_int(ncidout,vlidout,startOut,countOut,(int *)dataOut))) BAIL(res); } break; case NC_FLOAT: if((res=nc_get_vara_float(ncid,vlid,start,count,data))) BAIL(res); if(len0==dataEnd){ if((res=nc_put_vara_float(ncidout,vlidout,startOut,countOut,(float *)data))) BAIL(res); }else{ for(j=0;j<dataEnd;++j){ ((float *)dataOut)[j]=((float *)data)[poses[j]]; } if((res=nc_put_vara_float(ncidout,vlidout,startOut,countOut,(float *)dataOut))) BAIL(res); } break; case NC_DOUBLE: if((res=nc_get_vara_double(ncid,vlid,start,count,(double *)data))) BAIL(res); if(len0==dataEnd){ if((res=nc_put_vara_double(ncidout,vlidout,startOut,countOut,(double *)data))) BAIL(res); }else{ for(j=0;j<dataEnd;++j){ ((double *)dataOut)[j]=((double *)data)[poses[j]]; } if((res=nc_put_vara_double(ncidout,vlidout,startOut,countOut,(double *)dataOut))) BAIL(res); } break; default: printf("Unknown data type\n"); } } /*free resourses*/ free(divider); free(dividerOut); free(start); free(startOut); free(shapeOut); free(data); free(dataOut); free(poses); return 0; }
/* * Read a hypercube of numeric values from a netCDF variable of an open * netCDF file. */ static void c_ncvgt( int ncid, /* netCDF ID */ int varid, /* variable ID */ const size_t* start, /* multidimensional index of hypercube corner */ const size_t* count, /* multidimensional hypercube edge lengths */ void* value, /* block of data values to be read */ int* rcode /* returned error code */ ) { int status; nc_type datatype; if ((status = nc_inq_vartype(ncid, varid, &datatype)) == 0) { switch (datatype) { case NC_CHAR: status = NC_ECHAR; break; case NC_BYTE: # if NF_INT1_IS_C_SIGNED_CHAR status = nc_get_vara_schar(ncid, varid, start, count, (signed char*)value); # elif NF_INT1_IS_C_SHORT status = nc_get_vara_short(ncid, varid, start, count, (short*)value); # elif NF_INT1_IS_C_INT status = nc_get_vara_int(ncid, varid, start, count, (int*)value); # elif NF_INT1_IS_C_LONG status = nc_get_vara_long(ncid, varid, start, count, (long*)value); # endif break; case NC_SHORT: # if NF_INT2_IS_C_SHORT status = nc_get_vara_short(ncid, varid, start, count, (short*)value); # elif NF_INT2_IS_C_INT status = nc_get_vara_int(ncid, varid, start, count, (int*)value); # elif NF_INT2_IS_C_LONG status = nc_get_vara_long(ncid, varid, start, count, (long*)value); # endif break; case NC_INT: # if NF_INT_IS_C_INT status = nc_get_vara_int(ncid, varid, start, count, (int*)value); # elif NF_INT_IS_C_LONG status = nc_get_vara_long(ncid, varid, start, count, (long*)value); # endif break; case NC_FLOAT: # if NF_REAL_IS_C_FLOAT status = nc_get_vara_float(ncid, varid, start, count, (float*)value); # elif NF_REAL_IS_C_DOUBLE status = nc_get_vara_double(ncid, varid, start, count, (double*)value); # endif break; case NC_DOUBLE: # if NF_DOUBLEPRECISION_IS_C_FLOAT status = nc_get_vara_float(ncid, varid, start, count, (float*)value); # elif NF_DOUBLEPRECISION_IS_C_DOUBLE status = nc_get_vara_double(ncid, varid, start, count, (double*)value); # endif break; } } if (status == 0) *rcode = 0; else { nc_advise("NCVGT", status, ""); *rcode = ncerr; } }
NcValues* NcVar::get_rec(NcDim* rdim, long slice) { int idx = dim_to_index(rdim); long size = num_dims(); size_t* start = new size_t[size]; long* startl = new long[size]; for (int i=1; i < size ; i++) { start[i] = 0; startl[i] = 0; } start[idx] = slice; startl[idx] = slice; NcBool result = set_cur(startl); if (! result ) { delete [] start; delete [] startl; return 0; } long* edgel = edges(); size_t* edge = new size_t[size]; for (int i=1; i < size ; i++) { edge[i] = edgel[i]; } edge[idx] = 1; edgel[idx] = 1; NcValues* valp = get_space(rec_size(rdim)); int status; switch (type()) { case ncFloat: status = NcError::set_err( nc_get_vara_float(the_file->id(), the_id, start, edge, (float *)valp->base()) ); break; case ncDouble: status = NcError::set_err( nc_get_vara_double(the_file->id(), the_id, start, edge, (double *)valp->base()) ); break; case ncInt: status = NcError::set_err( nc_get_vara_int(the_file->id(), the_id, start, edge, (int *)valp->base()) ); break; case ncShort: status = NcError::set_err( nc_get_vara_short(the_file->id(), the_id, start, edge, (short *)valp->base()) ); break; case ncByte: status = NcError::set_err( nc_get_vara_schar(the_file->id(), the_id, start, edge, (signed char *)valp->base()) ); break; case ncChar: status = NcError::set_err( nc_get_vara_text(the_file->id(), the_id, start, edge, (char *)valp->base()) ); break; case ncNoType: default: return 0; } delete [] start; delete [] startl; delete [] edge; delete [] edgel; if (status != NC_NOERR) { delete valp; return 0; } return valp; }
int main(int argc, char **argv) { int i; char* filename = "tst_diskless.nc"; /* Set defaults */ persist = 0; usenetcdf4 = 0; mmap = 0; for(i=1;i<argc;i++) { if(strcmp(argv[i],"netcdf4")==0) usenetcdf4=1; else if(strcmp(argv[i],"persist")==0) persist=1; else if(strcmp(argv[i],"mmap")==0) mmap=1; /* ignore anything not recognized */ } #ifndef USE_NETCDF4 usenetcdf4 = 0; #endif if(mmap) usenetcdf4 = 0; flags = usenetcdf4?FLAGS4:FLAGS3; if(persist) flags |= PERSIST; if(mmap) flags |= NC_MMAP; printf("\n*** Testing the diskless API.\n"); printf("*** testing diskless file with scalar vars..."); { int ncid, varid0, varid1, varid2; int ndims_in, nvars_in, natts_in, unlimdimid_in; char name_in[NC_MAX_NAME + 1]; nc_type type_in; float float_data = 3.14, float_data_in; int int_data = 42, int_data_in; short short_data = 2, short_data_in; removefile(persist,filename); /* Create a netCDF file (which exists only in memory). */ if (nc_create(filename, flags, &ncid)) ERR; /* Create some variables. */ if (nc_def_var(ncid, RESISTOR, NC_INT, 0, NULL, &varid0)) ERR; if (nc_def_var(ncid, CAPACITOR, NC_FLOAT, 0, NULL, &varid1)) ERR; if (nc_def_var(ncid, NUM555, NC_SHORT, 0, NULL, &varid2)) ERR; if (nc_enddef(ncid)) ERR; /* Write some data to this file. */ if (nc_put_vara_int(ncid, varid0, NULL, NULL, &int_data)) ERR; if (nc_put_vara_float(ncid, varid1, NULL, NULL, &float_data)) ERR; if (nc_put_vara_short(ncid, varid2, NULL, NULL, &short_data)) ERR; /* Now check the phony file. */ if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR; if (ndims_in != 0 || nvars_in != 3 || natts_in != 0 || unlimdimid_in != -1) ERR; /* Check variables. */ if (nc_inq_var(ncid, varid0, name_in, &type_in, &ndims_in, NULL, &natts_in)) ERR; if (strcmp(name_in, RESISTOR) || type_in != NC_INT || ndims_in != 0 || natts_in != 0) ERR; if (nc_inq_var(ncid, varid1, name_in, &type_in, &ndims_in, NULL, &natts_in)) ERR; if (strcmp(name_in, CAPACITOR) || type_in != NC_FLOAT || ndims_in != 0 || natts_in != 0) ERR; if (nc_inq_var(ncid, varid2, name_in, &type_in, &ndims_in, NULL, &natts_in)) ERR; if (strcmp(name_in, NUM555) || type_in != NC_SHORT || natts_in != 0) ERR; /* Read my absolutely crucial data. */ if (nc_get_vara_int(ncid, varid0, NULL, NULL, &int_data_in)) ERR; if (int_data_in != int_data) ERR; if (nc_get_vara_float(ncid, varid1, NULL, NULL, &float_data_in)) ERR; if (float_data_in != float_data) ERR; if (nc_get_vara_short(ncid, varid2, NULL, NULL, &short_data_in)) ERR; if (short_data_in != short_data) ERR; /* Close the file. */ if (nc_close(ncid)) abort(); //ERR; } SUMMARIZE_ERR; if(!usenetcdf4 && persist) { int ncid, varid0, varid1, varid2; float float_data = 3.14, float_data_in; int int_data = 42, int_data_in; short short_data = 2, short_data_in; printf("*** testing diskless open of previously created file..."); if (nc_open(filename, flags, &ncid)) ERR; /* Read and compare */ if (nc_inq_varid(ncid, RESISTOR, &varid0)) ERR; if (nc_inq_varid(ncid, CAPACITOR, &varid1)) ERR; if (nc_inq_varid(ncid, NUM555, &varid2)) ERR; if (nc_get_vara_int(ncid, varid0, NULL, NULL, &int_data_in)) ERR; if (int_data_in != int_data) ERR; if (nc_get_vara_float(ncid, varid1, NULL, NULL, &float_data_in)) ERR; if (float_data_in != float_data) ERR; if (nc_get_vara_short(ncid, varid2, NULL, NULL, &short_data_in)) ERR; if (short_data_in != short_data) ERR; nc_close(ncid); } SUMMARIZE_ERR; printf("*** testing creation of simple diskless file..."); { #define NDIMS 2 #define DIM0_NAME "Fun" #define DIM1_NAME "Money" #define DIM1_LEN 200 #define ATT0_NAME "home" #define ATT0_TEXT "earthship" #define VAR0_NAME "nightlife" #define VAR1_NAME "time" #define VAR2_NAME "taxi_distance" int ncid, dimid[NDIMS], dimid_in[NDIMS], varid0, varid1, varid2; int ndims_in, nvars_in, natts_in, unlimdimid_in; char name_in[NC_MAX_NAME + 1], att0_in[NC_MAX_NAME + 1]; nc_type type_in; size_t len_in; short short_data[DIM1_LEN]; size_t start[1] = {0}; size_t count[1] = {DIM1_LEN}; int i; float float_data = 42.22, float_data_in; /* This is some really important data that I want to save. */ for (i = 0; i < DIM1_LEN; i++) short_data[i] = i; removefile(persist,filename); /* Create a netCDF file (which exists only in memory). I am * confident that the world-famous netCDF format is the way to * store my data! */ if (nc_create(filename, flags, &ncid)) ERR; /* Create some atts. They will help document my data forever. */ if (nc_put_att_text(ncid, NC_GLOBAL, ATT0_NAME, sizeof(ATT0_TEXT) + 1, ATT0_TEXT)) ERR; /* Create dimensions: money is limited, but fun is not! */ if (nc_def_dim(ncid, DIM0_NAME, NC_UNLIMITED, &dimid[0])) ERR; if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimid[1])) ERR; /* Create some variables. The data they hold must persist * through the ages. */ if (nc_def_var(ncid, VAR0_NAME, NC_INT, NDIMS, dimid, &varid0)) ERR; if (nc_def_var(ncid, VAR1_NAME, NC_FLOAT, 0, NULL, &varid1)) ERR; if (nc_def_var(ncid, VAR2_NAME, NC_SHORT, 1, &dimid[1], &varid2)) ERR; if (nc_enddef(ncid)) ERR; /* Write some data to this file. I'm glad I'm saving this * important data in such a safe format! */ if (nc_put_vara_float(ncid, varid1, NULL, NULL, &float_data)) ERR; if (nc_put_vara_short(ncid, varid2, start, count, short_data)) ERR; /* Now check the phony file. Is my data safe? */ if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR; if (ndims_in != 2 || nvars_in != 3 || natts_in != 1 || unlimdimid_in != 0) ERR; /* Check attributes - they will be needed by future generations * of scientists to understand my data. */ if (nc_get_att_text(ncid, NC_GLOBAL, ATT0_NAME, att0_in)) ERR; if (strcmp(att0_in, ATT0_TEXT)) ERR; /* Check dimensions. */ if (nc_inq_dim(ncid, dimid[0], name_in, &len_in)) ERR; if (strcmp(name_in, DIM0_NAME) || len_in != 0) ERR; if (nc_inq_dim(ncid, dimid[1], name_in, &len_in)) ERR; if (strcmp(name_in, DIM1_NAME) || len_in != DIM1_LEN) ERR; /* Check variables. */ if (nc_inq_var(ncid, varid0, name_in, &type_in, &ndims_in, dimid_in, &natts_in)) ERR; if (strcmp(name_in, VAR0_NAME) || type_in != NC_INT || ndims_in != NDIMS || dimid_in[0] != 0 || dimid_in[1] != 1 || natts_in != 0) ERR; if (nc_inq_var(ncid, varid1, name_in, &type_in, &ndims_in, dimid_in, &natts_in)) ERR; if (strcmp(name_in, VAR1_NAME) || type_in != NC_FLOAT || ndims_in != 0 || natts_in != 0) ERR; if (nc_inq_var(ncid, varid2, name_in, &type_in, &ndims_in, dimid_in, &natts_in)) ERR; if (strcmp(name_in, VAR2_NAME) || type_in != NC_SHORT || ndims_in != 1 || dimid_in[0] != 1 || natts_in != 0) ERR; /* Read my absolutely crucial data. */ if (nc_get_vara_float(ncid, varid1, NULL, NULL, &float_data_in)) ERR; if (float_data_in != float_data) ERR; /* Close the file, losing all information. Hey! What kind of * storage format is this, anyway? */ if (nc_close(ncid)) abort(); //ERR; } SUMMARIZE_ERR; printf("*** testing diskless file with scalar vars and type conversion..."); { #define DUNE "dune" #define STAR_TREK "capacitor_value" #define STAR_WARS "number_of_555_timer_chips" int ncid, varid0, varid1, varid2; int ndims_in, nvars_in, natts_in, unlimdimid_in; char name_in[NC_MAX_NAME + 1]; nc_type type_in; float float_data = 3.14, float_data_in; int int_data = 42, int_data_in; short short_data = 2, short_data_in; removefile(persist,filename); /* Create a netCDF file (which exists only in memory). */ if (nc_create(filename, flags, &ncid)) ERR; /* Create some variables. */ if (nc_def_var(ncid, DUNE, NC_INT, 0, NULL, &varid0)) ERR; if (nc_def_var(ncid, STAR_TREK, NC_FLOAT, 0, NULL, &varid1)) ERR; if (nc_def_var(ncid, STAR_WARS, NC_SHORT, 0, NULL, &varid2)) ERR; if (nc_enddef(ncid)) ERR; /* Write some data to this file. */ if (nc_put_vara_int(ncid, varid0, NULL, NULL, &int_data)) ERR; if (nc_put_vara_float(ncid, varid1, NULL, NULL, &float_data)) ERR; if (nc_put_vara_short(ncid, varid2, NULL, NULL, &short_data)) ERR; /* Now check the phony file. */ if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR; if (ndims_in != 0 || nvars_in != 3 || natts_in != 0 || unlimdimid_in != -1) ERR; /* Check variables. */ if (nc_inq_var(ncid, varid0, name_in, &type_in, &ndims_in, NULL, &natts_in)) ERR; if (strcmp(name_in, DUNE) || type_in != NC_INT || ndims_in != 0 || natts_in != 0) ERR; if (nc_inq_var(ncid, varid1, name_in, &type_in, &ndims_in, NULL, &natts_in)) ERR; if (strcmp(name_in, STAR_TREK) || type_in != NC_FLOAT || ndims_in != 0 || natts_in != 0) ERR; if (nc_inq_var(ncid, varid2, name_in, &type_in, &ndims_in, NULL, &natts_in)) ERR; if (strcmp(name_in, STAR_WARS) || type_in != NC_SHORT || natts_in != 0) ERR; /* Read my absolutely crucial data. */ if (nc_get_vara_int(ncid, varid0, NULL, NULL, &int_data_in)) ERR; if (int_data_in != int_data) ERR; if (nc_get_vara_float(ncid, varid1, NULL, NULL, &float_data_in)) ERR; if (float_data_in != float_data) ERR; if (nc_get_vara_short(ncid, varid2, NULL, NULL, &short_data_in)) ERR; if (short_data_in != short_data) ERR; /* Close the file. */ if (nc_close(ncid)) abort(); //ERR; } SUMMARIZE_ERR; FINAL_RESULTS; /* Unnecessary exit(0), FINAL_RESULTS returns. */ //exit(0); }
int main(int argc, char **argv) { /* create tst_classic_fills.nc */ printf("\n*** Testing fill values.\n"); printf("*** testing empty fill values of a string var..."); { #define STRING_VAR_NAME "The_String" #define NDIMS_STRING 1 #define FILLVALUE_LEN 1 /* There is 1 string, the empty one. */ #define DATA_START 2 /* Real data here. */ int ncid, varid, dimid, varid_in; const char *missing_val[FILLVALUE_LEN] = {""}; const char *missing_val_in[FILLVALUE_LEN]; const char *data_out[1] = {"The evil that men do lives after them; " "the good is oft interred with their bones."}; char **data_in; size_t index = DATA_START; int i; /* Create file with a 1D string var. Set its fill value to the * empty string. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, "rec", NC_UNLIMITED, &dimid)) ERR; if (nc_def_var(ncid, STRING_VAR_NAME, NC_STRING, NDIMS_STRING, &dimid, &varid)) ERR; if (nc_put_att_string(ncid, varid, "_FillValue", FILLVALUE_LEN, missing_val)) ERR; /* Check it out. */ if (nc_inq_varid(ncid, STRING_VAR_NAME, &varid_in)) ERR; if (nc_get_att_string(ncid, varid_in, "_FillValue", (char **)missing_val_in)) ERR; if (strcmp(missing_val[0], missing_val_in[0])) ERR; if (nc_free_string(FILLVALUE_LEN, (char **)missing_val_in)) ERR; /* Write one string, leaving some blank records which will then * get the fill value. */ if (nc_put_var1_string(ncid, varid_in, &index, data_out)) ERR; /* Get all the data from the variable. */ if (!(data_in = malloc((DATA_START + 1) * sizeof(char *)))) ERR; if (nc_get_var_string(ncid, varid_in, data_in)) ERR; /* First there should be fill values, then the data value we * wrote. */ for (i = 0; i < DATA_START; i++) if (strcmp(data_in[i], "")) ERR; if (strcmp(data_in[DATA_START], data_out[0])) ERR; /* Close everything up. */ if (nc_close(ncid)) ERR; /* Now re-open file, read data, and check values again. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq_varid(ncid, STRING_VAR_NAME, &varid_in)) ERR; if (nc_get_att_string(ncid, varid_in, "_FillValue", (char **)missing_val_in)) ERR; if (strcmp(missing_val[0], missing_val_in[0])) ERR; if (nc_free_string(FILLVALUE_LEN, (char **)missing_val_in)) ERR; if (nc_close(ncid)) ERR; free(data_in); } SUMMARIZE_ERR; printf("*** testing non-empty fill values of a string var..."); { #define STRING_VAR_NAME2 "CASSIUS" #define FILLVALUE_LEN2 1 /* There is 1 string in the fillvalue array. */ #define DATA_START2 9 /* Real data starts here. */ int ncid, varid, dimid, varid_in; const char *missing_val[FILLVALUE_LEN2] = {"I know that virtue to be in you, Brutus"}; const char *missing_val_in[FILLVALUE_LEN2]; const char *data_out[1] = {"The evil that men do lives after them; " "the good is oft interred with their bones."}; char **data_in; size_t index = DATA_START2; int i; /* Create file with a 1D string var. Set its fill value to the * a non-empty string. */ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; if (nc_def_dim(ncid, "rec", NC_UNLIMITED, &dimid)) ERR; if (nc_def_var(ncid, STRING_VAR_NAME2, NC_STRING, NDIMS_STRING, &dimid, &varid)) ERR; if (nc_put_att_string(ncid, varid, "_FillValue", FILLVALUE_LEN2, missing_val)) ERR; /* Check it out. */ if (nc_inq_varid(ncid, STRING_VAR_NAME2, &varid_in)) ERR; if (nc_get_att_string(ncid, varid_in, "_FillValue", (char **)missing_val_in)) ERR; if (strcmp(missing_val[0], missing_val_in[0])) ERR; if (nc_free_string(FILLVALUE_LEN2, (char **)missing_val_in)) ERR; /* Write one string, leaving some blank records which will then * get the fill value. */ if (nc_put_var1_string(ncid, varid_in, &index, data_out)) ERR; /* Get all the data from the variable. */ if (!(data_in = malloc((DATA_START2 + 1) * sizeof(char *)))) ERR; if (nc_get_var_string(ncid, varid_in, data_in)) ERR; /* First there should be fill values, then the data value we * wrote. */ for (i = 0; i < DATA_START2; i++) if (strcmp(data_in[i], missing_val[0])) ERR; if (strcmp(data_in[DATA_START2], data_out[0])) ERR; /* Close everything up. */ if (nc_close(ncid)) ERR; /* Now re-open file, read data, and check values again. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq_varid(ncid, STRING_VAR_NAME2, &varid_in)) ERR; if (nc_get_att_string(ncid, varid_in, "_FillValue", (char **)missing_val_in)) ERR; if (strcmp(missing_val[0], missing_val_in[0])) ERR; if (nc_free_string(FILLVALUE_LEN2, (char **)missing_val_in)) ERR; if (nc_close(ncid)) ERR; free(data_in); } SUMMARIZE_ERR; printf("*** testing fill values of one var..."); { #define V1_NAME "v1" #define MAX_VALS 10 int ncid, varid, rec_id, dims[2]; static int rec[1] = {1}; size_t start[2] = {0, 0}; size_t count[2] = {1, MAX_VALS}; char vals[MAX_VALS]; int i; if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; /* Define dimensions and two vars, a 1D coordinate var for * unlimited dimension, and a 2D var which uses the unlimited * dimension. */ if (nc_def_dim(ncid, "rec", NC_UNLIMITED, &dims[0])) ERR; if (nc_def_dim(ncid, "len", MAX_VALS, &dims[1])) ERR; if (nc_def_var(ncid, "rec", NC_INT, 1, dims, &rec_id)) ERR; if (nc_def_var(ncid, V1_NAME, NC_CHAR, 2, dims, &varid)) ERR; /* Extend record dimension by 1. */ if (nc_put_vara_int(ncid, rec_id, start, count, rec)) ERR; /* Read the other variable; it must have only fill values. */ if (nc_get_vara_text(ncid, 1, start, count, vals)) ERR; for (i = 0; i < MAX_VALS; i++) if(vals[i] != NC_FILL_CHAR) ERR; if (nc_close(ncid)) ERR; /* Now re-open file, read data, and check values again. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; /* Read the other variable; it must have only fill values. */ if (nc_get_vara_text(ncid, 1, start, count, vals)) ERR; for (i = 0; i < MAX_VALS; i++) if(vals[i] != NC_FILL_CHAR) ERR; if(nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** testing fill values of lots of vars..."); { int ncid; /* netCDF id */ #define NVALS 10 /* values per fixed-size variable or record */ #define NFIXVARS 6 /* number of fixed-size vars, one of each type */ #define NRECVARS 6 /* number of record vars, one of each type */ #define RANK_REC 1 #define RANK_FIXVARS 1 #define RANK_RECVARS 2 /* dimension ids */ int rec_dim; int len_dim; /* dimension lengths */ size_t rec_len = NC_UNLIMITED; size_t len_len = NVALS; /* variable ids */ int rec_id; int fixvar_ids[NFIXVARS]; int recvar_ids[NRECVARS]; int rec_dims[RANK_REC]; int fixvar_dims[RANK_FIXVARS]; int recvar_dims[RANK_RECVARS]; int fixvar, recvar, i; char *fnames[] = {"c", "b", "s", "i", "f", "d"}; char *rnames[] = {"cr", "br", "sr", "ir", "fr", "dr"}; nc_type types[] = {NC_CHAR, NC_BYTE, NC_SHORT, NC_INT, NC_FLOAT, NC_DOUBLE}; /*if (nc_set_default_format(format + 1, NULL)) ERR;*/ if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; /* define dimensions */ if (nc_def_dim(ncid, "rec", rec_len, &rec_dim)) ERR; if (nc_def_dim(ncid, "len", len_len, &len_dim)) ERR; rec_dims[0] = rec_dim; if (nc_def_var(ncid, "rec", NC_INT, RANK_REC, rec_dims, &rec_id)) ERR; /* define fixed and record variables of all 6 primitive types */ fixvar_dims[0] = len_dim; for (fixvar = 0; fixvar < NFIXVARS; fixvar++) if (nc_def_var(ncid, fnames[fixvar], types[fixvar], RANK_FIXVARS, fixvar_dims, &fixvar_ids[fixvar])) ERR; recvar_dims[0] = rec_dim; recvar_dims[1] = len_dim; for (recvar = 0; recvar < NRECVARS; recvar++) if (nc_def_var(ncid, rnames[recvar], types[recvar], RANK_RECVARS, recvar_dims, &recvar_ids[recvar])) ERR; /* leave define mode */ if (nc_enddef(ncid)) ERR; { /* store rec */ static size_t rec_start[RANK_REC]; static size_t rec_count[RANK_REC]; static int rec[] = {1}; rec_len = 1; /* number of records of rec data */ rec_start[0] = 0; rec_count[0] = rec_len; if (nc_put_vara_int(ncid, rec_id, rec_start, rec_count, rec)) ERR; } if (nc_close(ncid)) ERR; /* Now re-open file, read data, and check values */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; /* Check that fixed-size variables are full of fill values */ for (fixvar = 0; fixvar < NFIXVARS; fixvar++) { int varid; nc_type type; if (nc_inq_varid(ncid, fnames[fixvar], &varid)) ERR; if (nc_inq_vartype(ncid, varid, &type)) ERR; switch(type) { case NC_CHAR: { char vals[NVALS]; if (nc_get_var_text(ncid, varid, vals)) ERR; for (i = 0; i < NVALS; i++) if(vals[i] != NC_FILL_CHAR) ERR; } break; case NC_BYTE: { signed char vals[NVALS]; if (nc_get_var_schar(ncid, varid, vals)) ERR; for (i = 0; i < NVALS; i++) if(vals[i] != NC_FILL_BYTE) ERR; } break; case NC_SHORT: { short vals[NVALS]; if (nc_get_var_short(ncid, varid, vals)) ERR; for (i = 0; i < NVALS; i++) if(vals[i] != NC_FILL_SHORT) ERR; } break; case NC_INT: { int vals[NVALS]; if (nc_get_var_int(ncid, varid, vals)) ERR; for (i = 0; i < NVALS; i++) if(vals[i] != NC_FILL_INT) ERR; } break; case NC_FLOAT: { float vals[NVALS]; if (nc_get_var_float(ncid, varid, vals)) ERR; for (i = 0; i < NVALS; i++) if(vals[i] != NC_FILL_FLOAT) ERR; } break; case NC_DOUBLE: { double vals[NVALS]; if (nc_get_var_double(ncid, varid, vals)) ERR; for (i = 0; i < NVALS; i++) if (vals[i] != NC_FILL_DOUBLE) ERR; } break; default: ERR; } } /* Read record, check record variables have only fill values */ for (recvar = 0; recvar < NRECVARS; recvar++) { int varid; nc_type type; size_t start[] = {0, 0}; size_t count[] = {1, NVALS}; if (nc_inq_varid(ncid, rnames[recvar], &varid)) ERR; if (nc_inq_vartype(ncid, varid, &type)) ERR; switch(type) { case NC_CHAR: { char vals[NVALS]; if (nc_get_vara_text(ncid, varid, start, count, vals)) ERR; for (i = 0; i < NVALS; i++) if(vals[i] != NC_FILL_CHAR) ERR; } break; case NC_BYTE: { signed char vals[NVALS]; if (nc_get_vara_schar(ncid, varid, start, count, vals)) ERR; for (i = 0; i < NVALS; i++) if(vals[i] != NC_FILL_BYTE) ERR; } break; case NC_SHORT: { short vals[NVALS]; if (nc_get_vara_short(ncid, varid, start, count, vals)) ERR; for (i = 0; i < NVALS; i++) if(vals[i] != NC_FILL_SHORT) ERR; } break; case NC_INT: { int vals[NVALS]; if (nc_get_vara_int(ncid, varid, start, count, vals)) ERR; for (i = 0; i < NVALS; i++) if(vals[i] != NC_FILL_INT) ERR; } break; case NC_FLOAT: { float vals[NVALS]; if (nc_get_vara_float(ncid, varid, start, count, vals)) ERR; for (i = 0; i < NVALS; i++) if(vals[i] != NC_FILL_FLOAT) ERR; } break; case NC_DOUBLE: { double vals[NVALS]; if (nc_get_vara_double(ncid, varid, start, count, vals)) ERR; for (i = 0; i < NVALS; i++) if(vals[i] != NC_FILL_DOUBLE) ERR; } break; default: ERR; } } if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; FINAL_RESULTS; return 0; }