/* * * based on ancio by Jason Cristy, PNNL * ** attempt to compile with g++ ** added ( and ) to truth tests ** ** ** effort to convert to classes from structs */ /* * Headers. ************/ #include "mycode.h" // ClassImp(_Dimensions); // ClassImp(_Attributes); // ClassImp(_Variables); // ClassImp(_ncData); /* added to avoid C++ compiler error when putting -1 to initialize atttype and vartype -- see code change below consisting of att->atttype = (nc_type) newtest; and var->vartype = (nc_type) newtest; */ int newtest = -1; /* * Read the contents of the netcdf file. *****************************************/ int ncx_read(ncDataP data) { int status; /* Error check. ****************/ if(data == (ncDataP)NULL) { printf("\nNull argument passed to ncx_read.\n"); /* Return failure. */ return EXIT_FAILURE; } if(data->infile == (char *)NULL) { printf("\nNo file name specified.\n"); /* Return failure. */ return EXIT_FAILURE; } if (!data->isopen) { /* Open the netcdf file. *************************/ if((status=nc_open(data->infile,NC_NOWRITE,&data->fid) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } /* Set flag. *************/ data->isopen = TRUE; } /* Inquire about the netcdf file. **********************************/ if((status=nc_inq(data->fid, &data->ndims, &data->nvars, &data->ngatts, &data->unlimited) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } /* Get all dimensions. ***********************/ if (ncx_getdimensions(data) == EXIT_FAILURE) { printf("\nThere was an error reading in the dimensions:\n\t >> %s.\n", data->infile); /* Return failure. */ return EXIT_FAILURE; } /* Get all global attributes. ******************************/ if (ncx_getglobals(data) == EXIT_FAILURE) { printf("\nThere was an error reading in the global attributes.\n\t >> %s\n", data->infile); /* Return failure. */ return EXIT_FAILURE; } /* Get all variables. **********************/ if(ncx_getvariables(data) == EXIT_FAILURE) { printf("\nThere was an error reading in the variables.\n\t >> %s\n", data->infile); /* Return failure. */ return EXIT_FAILURE; } /* Close the netcdf file. **************************/ if((status=nc_close(data->fid) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } /* Set flag. *************/ data->isopen = FALSE; /* Return success. */ return EXIT_SUCCESS; } /* * Get all of the dimensions. ******************************/ int ncx_getdimensions(ncDataP data) { int d; /* Allocate memory for dimensions. */ if ((data->dimensions = (DimensionsP *)calloc(data->ndims,sizeof(DimensionsP))) == NULL) { memory_fail(__FILE__,__LINE__); } /* Read in each dimension. ***************************/ for (d=0; dndims; d++) { /* Allocate memory. */ if ((data->dimensions[d] = (DimensionsP)calloc(1, sizeof(DimensionsS))) == NULL) { memory_fail(__FILE__,__LINE__); } /* Initialize. */ init_dimension(data->dimensions[d]); /* Set id. */ data->dimensions[d]->dimid = d; /* Read the dimension. */ if(ncx_getdimension(data, data->dimensions[d]) == EXIT_FAILURE) { /* Return failure. */ return EXIT_FAILURE; } } /* Return success. */ return EXIT_SUCCESS; } /* * Read in an individual dimension. ************************************/ int ncx_getdimension(ncDataP data, DimensionsP dim) { int status; /* Error check. */ if(dim == (DimensionsP)NULL || dim->dimid == -1) /* Return failure. */ return EXIT_FAILURE; if (!data->isopen) { /* Open the netcdf file. */ if((status=nc_open(data->infile,NC_NOWRITE,&data->fid) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } /* Set flag. */ data->isopen = TRUE; } /* Allocate memory. */ if((dim->dimname = (char *)calloc(NC_MAX_NAME,sizeof(char))) == NULL) { memory_fail(__FILE__,__LINE__); } /* Set the flag. */ dim->keep=1; /* Retrieve the dimension info. */ if((status=nc_inq_dim(data->fid,dim->dimid,dim->dimname,&dim->dimlength) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } /* Return success. */ return EXIT_SUCCESS; } /* * Get all of the global attributes. *************************************/ int ncx_getglobals(ncDataP data) { int g; /* Allocate memory for attributes. */ if ((data->globals = (AttributesP *)calloc(data->ngatts,sizeof(AttributesP))) == NULL) { memory_fail(__FILE__,__LINE__); } /* Read in each global attribute. **********************************/ for (g=0; gngatts; g++) { /* Allocate memory. */ if ((data->globals[g] = (AttributesP)calloc(1, sizeof(AttributesS))) == NULL) { memory_fail(__FILE__,__LINE__); } /* Initialize. */ init_attribute(data->globals[g]); /* Set id. */ data->globals[g]->attid = g; /* Read the global attribute. */ if(ncx_getattribute(data, data->globals[g], (VariablesP)NULL) == EXIT_FAILURE) { /* Return failure. */ return EXIT_FAILURE; } if(data->getattvalues) { /* Retrieve the attribute value. */ if(ncx_getattributevalue(data, data->globals[g], (VariablesP)NULL) == EXIT_FAILURE) { /* Return failure. */ return EXIT_FAILURE; } } } /* Return success. */ return EXIT_SUCCESS; } /* * Get all of the field-level attributes. ******************************************/ int ncx_getattributes(ncDataP data, VariablesP var) { int a; /* Allocate memory for attributes. */ if ((var->attributes = (AttributesP *)calloc(var->varnatts,sizeof(AttributesP))) == NULL) { memory_fail(__FILE__,__LINE__); } /* Read in each attribute. ***************************/ for (a=0; avarnatts; a++) { /* Allocate memory. */ if ((var->attributes[a] = (AttributesP)calloc(1, sizeof(AttributesS))) == NULL) { memory_fail(__FILE__,__LINE__); } /* Initialize. */ init_attribute(var->attributes[a]); /* Set id. */ var->attributes[a]->attid = a; /* Read the attribute. */ if(ncx_getattribute(data, var->attributes[a], var) == EXIT_FAILURE) { /* Return failure. */ return EXIT_FAILURE; } /* Retrieve the attribute value. */ if(data->getattvalues) { if(ncx_getattributevalue(data, var->attributes[a], var) == EXIT_FAILURE) { /* Return failure. */ return EXIT_FAILURE; } } } /* Return success. */ return EXIT_SUCCESS; } /* * Read in an attribute. *************************/ int ncx_getattribute(ncDataP data, AttributesP att, VariablesP var) { int status,varid=NC_GLOBAL; /* Error check. */ if(att == (AttributesP)NULL || att->attid == -1) /* Return failure. */ return EXIT_FAILURE; if (!data->isopen) { /* Open the netcdf file. */ if((status=nc_open(data->infile,NC_NOWRITE,&data->fid) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } /* Set flag. */ data->isopen = TRUE; } /* Get variable id. */ if(var != NULL) varid = var->varid; /* Allocate memory. */ if((att->attname=(char *)calloc(NC_MAX_NAME,sizeof(char))) == NULL) { memory_fail(__FILE__,__LINE__); } /* Set the flag. */ att->keep=1; /* Retrieve the attribute name. */ if((status=nc_inq_attname(data->fid,varid,att->attid,att->attname) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } /* Retrieve the attribute type. */ if((status=nc_inq_atttype(data->fid,varid,att->attname,&att->atttype) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } /* Retrieve the attribute length. */ if((status=nc_inq_attlen(data->fid,varid,att->attname,&att->attlength) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } /* Return success. */ return EXIT_SUCCESS; } /* * Read in an attribute value. *******************************/ int ncx_getattributevalue(ncDataP data, AttributesP att, VariablesP var) { int status,varid=NC_GLOBAL; /* Error check. */ if(att == (AttributesP)NULL || att->attid == -1) /* Return failure. */ return EXIT_FAILURE; if (!data->isopen) { /* Open the netcdf file. */ if((status=nc_open(data->infile,NC_NOWRITE,&data->fid) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } /* Set flag. */ data->isopen = TRUE; } /* Get variable id. */ if(var != NULL) varid = var->varid; /* Determine what type the attribute is. */ switch(att->atttype) { case NC_LONG: /* Allocate memory. */ if((att->long_val=(long *)calloc(att->attlength,sizeof(long))) == NULL) { memory_fail(__FILE__,__LINE__); } /* Retrieve the attribute value. */ if((status=nc_get_att_long(data->fid,varid,att->attname,att->long_val) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } break; case NC_CHAR: /* Allocate memory. */ if((att->char_val=(char *)calloc(att->attlength+1,sizeof(char))) == NULL) { memory_fail(__FILE__,__LINE__); } /* Retrieve the attribute value. */ if((status=nc_get_att_text(data->fid,varid,att->attname,att->char_val) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } break; case NC_DOUBLE: /* Allocate memory. */ if((att->double_val=(double *)calloc(att->attlength,sizeof(double))) == NULL) { memory_fail(__FILE__,__LINE__); } /* Retrieve the attribute value. */ if((status=nc_get_att_double(data->fid,varid,att->attname,att->double_val) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } break; case NC_FLOAT: /* Allocate memory. */ if((att->float_val=(float *)calloc(att->attlength,sizeof(float))) == NULL) { memory_fail(__FILE__,__LINE__); } /* Retrieve the attribute value. */ if((status=nc_get_att_float(data->fid,varid,att->attname,att->float_val) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } break; case NC_SHORT: /* Allocate memory. */ if((att->short_val=(short *)calloc(att->attlength,sizeof(short))) == NULL) { memory_fail(__FILE__,__LINE__); } /* Retrieve the attribute value. */ if((status=nc_get_att_short(data->fid,varid,att->attname,att->short_val) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } break; case NC_BYTE: /* Allocate memory. */ if((att->uchar_val=(unsigned char *)calloc(att->attlength,sizeof(unsigned char))) == NULL) { memory_fail(__FILE__,__LINE__); } /* Retrieve the attribute value. */ if((status=nc_get_att_uchar(data->fid,varid,att->attname,att->uchar_val) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } break; default: printf("\nUnknown data type for attribute: %s.\n", att->attname); /* Return failure. */ return EXIT_FAILURE; } //I added this to avoid "warning control reaches end of non-void function return EXIT_SUCCESS; } /* * Get all of the variables. *****************************/ int ncx_getvariables(ncDataP data) { int v; /* Allocate memory for variables. */ if ((data->variables = (VariablesP *)calloc(data->nvars,sizeof(VariablesP))) == NULL) { memory_fail(__FILE__,__LINE__); } /* Read in each variable. **************************/ for (v=0; vnvars; v++) { /* Allocate memory. */ if ((data->variables[v] = (VariablesP)calloc(1, sizeof(VariablesS))) == NULL) { memory_fail(__FILE__,__LINE__); } /* Initialize. */ init_variable(data->variables[v]); /* Set id. */ data->variables[v]->varid = v; /* Read the variable. */ if(ncx_getvariable(data, data->variables[v]) == EXIT_FAILURE) { /* Return failure. */ return EXIT_FAILURE; } /* Retrieve the data. */ if(data->getvardata) { if(ncx_getvariabledata(data, data->variables[v], NULL, NULL) == EXIT_FAILURE) { /* Return failure. */ return EXIT_FAILURE; } } /* Read in all field-level attributes. ***************************************/ if (ncx_getattributes(data, data->variables[v]) == EXIT_FAILURE) { printf("\nThere was an error reading the attributes for variable: %s\n\t >> %s\n", data->variables[v]->varname, data->infile); /* Return failure. */ return EXIT_FAILURE; } } /* Return success. */ return EXIT_SUCCESS; } /* * Read in an individual variable. ***********************************/ int ncx_getvariable(ncDataP data, VariablesP var) { int status; /* Error check. */ if(var == (VariablesP)NULL || var->varid == -1) /* Return failure. */ return EXIT_FAILURE; if (!data->isopen) { /* Open the netcdf file. */ if((status=nc_open(data->infile,NC_NOWRITE,&data->fid) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } /* Set flag. */ data->isopen = TRUE; } /* Allocate memory. */ if((var->varname=(char *)calloc(NC_MAX_NAME,sizeof(char))) == NULL) { memory_fail(__FILE__,__LINE__); } /* Set the flag. */ var->keep=1; /* Retrieve the variable name. */ if((status=nc_inq_varname(data->fid,var->varid,var->varname) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } /* Retrieve the variable type. */ if((status=nc_inq_vartype(data->fid,var->varid,&var->vartype) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } /* Retrieve the number of dimensions. */ if((status=nc_inq_varndims(data->fid,var->varid,&var->varndims) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } /* Allocate memory. */ if((var->vardimids=(int *)calloc(var->varndims + 1, sizeof(int))) == NULL) { memory_fail(__FILE__,__LINE__); } /* Retrieve the dimension ids. */ if((status=nc_inq_vardimid(data->fid,var->varid,var->vardimids) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } /* Retrieve the number of attributes. */ if((status=nc_inq_varnatts(data->fid,var->varid,&var->varnatts) != NC_NOERR)) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } /* Return success. */ return EXIT_SUCCESS; } /* * Read in a variable's data. ******************************/ int ncx_getvariabledata( ncDataP data, VariablesP var, unsigned int *spts, unsigned int *elens ) { int vd,d,freem,status; unsigned int *start,*lengths; time_t timer; /* moved this from below, used before initialization */ /* Initialize. */ timer = time( 0 ); /* Error check. */ if ( var == ( VariablesP )NULL || var->varid == -1 ) { /* Return failure. */ return EXIT_FAILURE; } /* Check if the file is open. */ if ( ! data->isopen ) { /* Open the netcdf file. */ if (( status = nc_open( data->infile, NC_NOWRITE, &data->fid ) != NC_NOERR )) { printf( "\n%s\n", nc_strerror( status ) ); /* Return failure. */ return EXIT_FAILURE; } /* Set flag. */ data->isopen = TRUE; } freem = 0; start = spts; lengths = elens; if ( start == ( unsigned int * )NULL && lengths == ( unsigned int * )NULL ) { /* Allocate memory. */ if ( ( start = ( unsigned int * )calloc( var->varndims, sizeof( unsigned int ) ) ) == NULL ) { memory_fail( __FILE__, __LINE__ ); } if ( ( lengths = ( unsigned int * )calloc( var->varndims, sizeof( unsigned int ) ) ) == NULL) { memory_fail(__FILE__,__LINE__); } /* * Set default start points and end * lengths to retrieve all values. */ for (vd = 0; vd < var->varndims; vd++ ) { start[ vd ] = 0; lengths[ vd ] = 0; for ( d = 0; d < data->ndims; d++ ) { if ( var->vardimids[ vd ] == data->dimensions[ d ]->dimid ) { lengths[ vd ] = data->dimensions[ d ]->dimlength; break; } } } freem = 1; } /* Initialize. */ var->nsamples = 1; /* Get the total number of samples. */ for( vd = 0; vd < var->varndims; vd++ ) { var->nsamples *= lengths[ vd ]; } /* Check if the verbose time flag is set. */ if ( data->time_flag ) { /* Print a friendly message. */ printf( "-------------------------------\n" "Variable '%s' (%d total samples)\n", var->varname, var->nsamples ); } /* Determine what type the variable is. */ switch( var->vartype ) { case NC_LONG: /* Allocate memory. */ if ( ( var->long_data = ( long * )calloc( var->nsamples, sizeof( long ) ) ) == NULL ) { memory_fail( __FILE__, __LINE__ ); } /* Retrieve the data. */ if (( status = nc_get_vara_long( data->fid, var->varid, start, lengths, var->long_data ) != NC_NOERR )) { printf("\n%s\n", nc_strerror(status)); /* Return failure. */ return EXIT_FAILURE; } break; case NC_CHAR: /* Allocate memory. */ if ( ( var->char_data = ( char * )calloc( var->nsamples, sizeof( char ) ) ) == NULL ) { memory_fail( __FILE__, __LINE__ ); } /* Retrieve the data. */ if (( status = nc_get_vara_text( data->fid, var->varid, start, lengths, var->char_data ) != NC_NOERR )) { printf( "\n%s\n", nc_strerror( status ) ); /* Return failure. */ return EXIT_FAILURE; } break; case NC_DOUBLE: /* Allocate memory. */ if ( ( var->double_data = ( double * )calloc( var->nsamples, sizeof( double ) ) ) == NULL ) { memory_fail( __FILE__, __LINE__ ); } /* Retrieve the data. */ if (( status = nc_get_vara_double( data->fid, var->varid, start, lengths, var->double_data ) != NC_NOERR )) { printf( "\n%s\n", nc_strerror( status ) ); /* Return failure. */ return EXIT_FAILURE; } break; case NC_FLOAT: /* Allocate memory. */ if ( ( var->float_data = ( float * )calloc( var->nsamples, sizeof( float ) ) ) == NULL ) { memory_fail( __FILE__,__LINE__ ); } /* Retrieve the data. */ if (( status = nc_get_vara_float( data->fid, var->varid, start, lengths, var->float_data ) != NC_NOERR )) { printf( "\n%s\n", nc_strerror( status ) ); /* Return failure. */ return EXIT_FAILURE; } break; case NC_SHORT: /* Allocate memory. */ if ( ( var->short_data = ( short * )calloc( var->nsamples, sizeof( short ) ) ) == NULL ) { memory_fail( __FILE__,__LINE__ ); } /* Retrieve the data. */ if (( status = nc_get_vara_short( data->fid, var->varid, start, lengths, var->short_data ) != NC_NOERR )) { printf( "\n%s\n", nc_strerror( status ) ); /* Return failure. */ return EXIT_FAILURE; } break; case NC_BYTE: /* Allocate memory. */ if ( ( var->uchar_data = ( unsigned char * )calloc( var->nsamples, sizeof( unsigned char ) ) ) == NULL ) { memory_fail( __FILE__,__LINE__ ); } /* Retrieve the data. */ if (( status = nc_get_vara_uchar( data->fid, var->varid, start, lengths, var->uchar_data ) != NC_NOERR )) { printf( "\n%s\n", nc_strerror( status ) ); /* Return failure. */ return EXIT_FAILURE; } break; default: printf( "\nUnknown data type for variable: %s\n", var->varname ); /* Return failure. */ return EXIT_FAILURE; } /* Check if the verbose time flag is set. */ if ( data->time_flag ) { /* Print a friendly message. */ /* added 'l' for 'long int', g++ compiler warning */ printf( "Reading data from input file ... (%ld seconds)\n", ( time( 0 ) - timer ) ); } /* Free memory. */ if ( freem ) { free( start ); free( lengths ); } /* Return success. */ return EXIT_SUCCESS; } /* * Initialize dimension structure. ***********************************/ void init_dimension(DimensionsP dim) { dim->dimid = -1; dim->dimname = (char *)NULL; dim->dimlength = -1; dim->keep = 0; dim->wdimid = -1; } /* * Initialize attribute structure. ***********************************/ void init_attribute(AttributesP att) { att->attid = -1; att->atttype = (nc_type) newtest; /* C++ treats enum differently than C */ att->attname = (char *)NULL; att->attlength = 0; att->long_val = (long *)NULL; att->char_val = (char *)NULL; att->double_val = (double *)NULL; att->float_val = (float *)NULL; att->short_val = (short *)NULL; att->uchar_val = (unsigned char *)NULL; att->keep = 0; att->wattid = -1; } /* * Initialize variable structure. **********************************/ void init_variable(VariablesP var) { var->varid = -1; var->varname = (char *)NULL; var->vartype = (nc_type) newtest; /* C++ treats enum differently than C */ var->varndims = 0; var->vardimids = (int *)NULL; var->varnatts = 0; var->attributes = (AttributesP *)NULL; var->nsamples = 0; var->long_data = (long *)NULL; var->char_data = (char *)NULL; var->double_data = (double *)NULL; var->float_data = (float *)NULL; var->short_data = (short *)NULL; var->uchar_data = (unsigned char *)NULL; var->keep = 0; var->wvarid = -1; } /* * Initialize [arm ] generic netCDF data structure. **********************************/ void init_ncdata(ncDataP data) { data->fid = -1; data->ndims = 0; data->nvars = 0; data->ngatts = 0; data->unlimited = -1; data->dimensions = ( DimensionsP * )NULL; data->globals = ( AttributesP * )NULL; data->variables = ( VariablesP * )NULL; data->infile = ( char * )NULL; data->outfile = ( char * )NULL; data->isopen = FALSE; data->getvardata = TRUE; data->getattvalues = TRUE; data->mode = NC_NOCLOBBER; data->sort = 0; data->time_flag = 0; } /* * Print dimension info. *************************/ void print_dimension(DimensionsP dim) { printf("| DIM: %s, ID: %d, Length: %d\n", dim->dimname, dim->dimid, dim->dimlength); } /* * Print attribute info. *************************/ void print_attribute(AttributesP att) { printf("| ATT: %s, ID: %d, Length: %d\n", att->attname, att->attid, att->attlength); } /* * Print variable info. ************************/ void print_variable(VariablesP var) { int a,d; printf("| VAR: %s, ID: %d, Dimids: (", var->varname, var->varid); if (var->varndims > 0) { for (d=0; d<(var->varndims-1); d++) { printf("%d,", var->vardimids[d]); } printf("%d", var->vardimids[var->varndims-1]); } printf(")\n"); printf("|---------------------------------\n"); printf("| Attributes:\n"); for (a=0; avarnatts; a++) { print_attribute(var->attributes[a]); } printf("|---------------------------------\n"); } /* * Print [arm ] generic netCDF structure info. *****************************/ void print_ncdata(ncDataP data) { int d,g,v; printf("==================================\n"); printf(" Dimensions:\n"); printf("==================================\n"); for (d=0; dndims; d++) { print_dimension(data->dimensions[d]); } printf("==================================\n"); printf(" Global Attributes:\n"); printf("==================================\n"); for (g=0; gngatts; g++) { print_attribute(data->globals[g]); } printf("==================================\n"); printf(" Variables:\n"); printf("==================================\n"); for (v=0; vnvars; v++) { print_variable(data->variables[v]); } } /* * Free all dimensions. ************************/ int free_dimensions(ncDataP data) { int d; /* Error check. */ if(data == (ncDataP)NULL) /* Return failure. */ return EXIT_FAILURE; /* Loop over the dimensions. */ for(d=data->ndims-1; d>=0; d--) { free_dimension(data->dimensions[d]); } /* Free the dimension structure. */ free(data->dimensions); /* Return success. */ return EXIT_SUCCESS; } /* * Free individual dimension. ******************************/ int free_dimension(DimensionsP dim) { /* Free the dimension name. */ free(dim->dimname); /* Free the structure. */ free(dim); /* Return failure. */ return EXIT_SUCCESS; } /* * Free all attributes. ************************/ int free_attributes(AttributesP *atts, int natts) { int a; /* Error check. */ if(atts == (AttributesP *)NULL) /* Return failure. */ return EXIT_FAILURE; /* Loop over the attributes. */ for(a=natts-1; a>=0; a--) { free_attribute(atts[a]); } /* Free the attribute structure. */ free(atts); /* Return success. */ return EXIT_SUCCESS; } /* * Free individual attribute. ******************************/ int free_attribute(AttributesP att) { /* Free the attribute name. */ free(att->attname); /* Free the attribute value. */ free(att->long_val); free(att->char_val); free(att->double_val); free(att->float_val); free(att->short_val); free(att->uchar_val); /* Free the structure. */ free(att); /* Return success. */ return EXIT_SUCCESS; } /* * Free all the variables. ***************************/ int free_variables(ncDataP data) { int v; /* Error check. */ if(data == (ncDataP)NULL) /* Return failure. */ return EXIT_FAILURE; /* Loop over the variables. */ for(v=data->nvars-1; v>=0; v--) { free_variable(data->variables[v]); free(data->variables[v]); } free(data->variables); /* Return success. */ return EXIT_SUCCESS; } /* * Free individual variable. *****************************/ int free_variable(VariablesP var) { /* Free the variable name. */ free(var->varname); /* Free the attributes. */ free_attributes(var->attributes,var->varnatts); /* Free the dimension ids. */ free(var->vardimids); /* Free the data. */ free(var->long_data); free(var->char_data); free(var->double_data); free(var->float_data); free(var->short_data); free(var->uchar_data); /* Return success. */ return EXIT_SUCCESS; } /* * Free the data structure. ****************************/ int free_ncdata(ncDataP data) { /* Error check. */ if(data == (ncDataP)NULL) /* Return failure. */ return EXIT_FAILURE; /* Free the dimensions. */ free_dimensions(data); /* Free the variables info. */ free_variables(data); /* Free the global attributes. */ free_attributes(data->globals,data->ngatts); /* Free the input file. */ free(data->infile); /* Free the output file. */ free(data->outfile); /* Free the ncData. */ free(data); /* Return success. */ return EXIT_SUCCESS; } /* * Memory allocation error. ****************************/ void memory_fail(char *file, int line) { printf("\n\nUnable to allocate memory at %s, %d.\n\n",file,line); exit(EXIT_FAILURE); } /* * This function will return the total * number of samples in the specified variable. */ int ncx_getvarsize(ncDataP data, int v) { int d, nsamples; /* Error check. */ if(data == (ncDataP)NULL) /* Return failure. */ return EXIT_FAILURE; if((v < 0) || (v > data->nvars)) /* Return failure. */ return EXIT_FAILURE; /* Initialize. */ nsamples=1; /* Loop over the dimensions. */ for(d=0; dvariables[v]->varndims; d++) { /* Get the total number of samples. */ nsamples*=data->dimensions[data->variables[v]-> vardimids[d]]->dimlength; } /* Return the number of samples. */ return nsamples; } /* * Parse configuration file with command line arguments */ int parse_config(char *program, char *filename, int (*parse_args)(int,char **)) { struct stat stbuf; off_t size; FILE *fp; char *buffer; int nread; int nlines; int argc; char **argv; char *c; char q; int status; /* make sure a filename was specified */ if ((filename == NULL) || (filename[0] == '\0')) { printf("%% no filename was specifed in call to parse_config"); return(0); } /* make sure a parse_args function was specified */ if (parse_args == NULL) { printf("%% parse_config requires a parse_args function to be specified"); return(0); } /* get file size so we know the size the buffer needs to be */ if (stat(filename, &stbuf) == 0) { size = stbuf.st_size; } else { printf("Error #%i getting stats for file: %s: %s", errno, filename, strerror(errno)); return(0); } /* allocate space for the buffer */ buffer = (char *)calloc(size + 1, sizeof(char)); if (buffer == NULL) { printf("Can't allocate memory for buffer"); return(0); } /* open the file */ if((fp = fopen(filename, "r")) == NULL) { printf("Error #%i opening file %s: %s", errno, filename, strerror(errno)); free(buffer); return(0); } /* read the file into the buffer */ nread = fread((void *)buffer, sizeof(char), size, fp); if (nread != size) { if (feof(fp)) { printf("Unexpected end of file found in %s", filename); } else { printf("Error #%i reading file %s: %s", errno, filename, strerror(errno)); } free(buffer); fclose(fp); return(0); } /* initialize argc and argv */ argv = (char **)calloc(2, sizeof(char *)); if (argv == NULL) { printf("Can't allocate memory for argv"); return(0); } nlines = 1; argc = 1; argv[0] = program; argv[1] = NULL; /* parse the buffer and create a command line like argc and argv */ for (c = buffer; c < buffer + size; c++) { /* skip non-printable chars and white space */ if (!isprint(*c) || *c == ' ') { if (*c == '\n') nlines++; continue; } /* skip end of line comments */ if (*c == '#') { while (*c != '\n' && (c < buffer + size)) c++; nlines++; continue; } /* allocate space for a new argv entry */ argv = (char **)realloc(argv, (argc+2) * sizeof(char *)); if (argv == NULL) { printf("Can't re-allocate memory for argv"); free(buffer); fclose(fp); return(0); } /* point the new argv entry into the buffer */ argv[argc] = c; argv[++argc] = NULL; /* check if this is a quoted argument */ if ((*c == '"') || (*c == '\'')) { q = *c; argv[argc-1]++; for(c++; (*c != q) && (c < buffer + size); c++); if (c >= buffer + size) { printf("Run away quoted argument starting on line %i, in file: %s", nlines, filename); } } else { while (isgraph(*c)) c++; } /* terminate the argument entry in the buffer */ if (*c == '\n') nlines++; *c = '\0'; } fclose(fp); /* Initialize. */ status = 1; /* call the parse_args function */ if(parse_args(argc, argv) == EXIT_FAILURE) { /* Reset the status. */ status = 0; } /* free the buffer space */ free(buffer); free(argv); /* Return status. */ return status; } /* * The purpose of this procedure is to take * an input netCDF file, open it, read in * the variable names and close the file. * It will return an array of strings * containing the variable names. A * return value of (char **)NULL indicates * a failure in that the file name was set * to NULL or the file was corrupted. *****************************************/ char **get_varnames(char *infile, int *outnvars) { char **varnames; int status, fid, i; int ndims, nvars, ngatts, unlimited; /* Error check. */ if ( outnvars == (int *)NULL ) { /* Print an error message. */ fprintf(stderr, "\nThe variable to hold the number " "of variables read in is set\n" "to NULL in get_varnames()\n" "in file %s line %d.\n", __FILE__, __LINE__); /* Return null. */ return (char **)NULL; } /* Initialize. */ *outnvars = 0; /* Error check. */ if ( infile == (char *)NULL ) { /* Print an error message. */ fprintf(stderr, "\nThe file name is set\n" "to NULL in get_varnames()\n" "in file %s line %d.\n", __FILE__, __LINE__); /* Return null. */ return (char **)NULL; } /* Open the netcdf file. */ if (( status = nc_open(infile, NC_NOWRITE, &fid )) != NC_NOERR) { /* Print an error message. */ fprintf(stderr, "\n%s\n", nc_strerror(status)); /* Return null. */ return (char **)NULL; } /* Inquire about the netcdf file. */ if (( status = nc_inq(fid, &ndims, &nvars, &ngatts, &unlimited )) != NC_NOERR) { /* Print an error message. */ fprintf(stderr, "\n%s\n", nc_strerror(status)); /* Return null. */ return (char **)NULL; } /* Make sure nvars is valid. */ if ( nvars <= 0 ) { /* Print an error message. */ fprintf(stderr, "\nThe number of variables in %s is %d.\n", infile, nvars); } /* Allocate memory. */ if ( ( varnames = CALLOC(nvars, char *) ) == (char **)NULL ) { /* Print an error message and quit. */ memory_fail(__FILE__,__LINE__); } /* Loop over the number of variables. */ for ( i = 0; i < nvars; i++ ) { /* Allocate memory. */ if ( ( varnames[i] = (char *)calloc(NC_MAX_NAME, sizeof(char)) ) == (char *)NULL ) { /* Loop over previous variables read in. */ for ( i = i - 1; i >= 0; i-- ) { /* Free data. */ free(varnames[i]); } /* Print an error message and quit. */ memory_fail(__FILE__,__LINE__); } /* Retrieve the variable name. */ if ( ( status = nc_inq_varname(fid, i, varnames[i])) != NC_NOERR ) { /* Print an error message. */ fprintf(stderr, "\n%s\n", nc_strerror(status)); /* Loop over previous variables read in. */ for ( i = i - 1; i >= 0; i-- ) { /* Free data. */ free(varnames[i]); } /* Return null. */ return (char **)NULL; } } /* Open the netcdf file. */ if ( ( status = nc_close(fid) ) != NC_NOERR ) { /* Print an error message. */ fprintf(stderr, "\n%s\n", nc_strerror(status)); /* Loop over previous variables read in. */ for ( i = i - 1; i >= 0; i-- ) { /* Free data. */ free(varnames[i]); } /* Return null. */ return (char **)NULL; } /* Set the output variable with the number of variables. */ *outnvars = nvars; /* Return the variable names. */ return varnames; } /* * This procedure will set the name of the input or * output file by first allocating memory then copying * the variable into the struct. To set the input * file name, set the input flag to 1, else 0 for the * output filename. */ int ncx_setFilename(ncDataP data, char *filename, int flag) { int len; /* Error check. */ if ( (data == (ncDataP)NULL) || (filename == (char *)NULL) ) { /* Print an error message. */ printf("\n\nInvalid arguments in " "file %s line %d.\n\n", __FILE__, __LINE__); /* Return failure. */ return EXIT_FAILURE; } /* Get the length of the filename. */ len = (int)strlen(filename) + 1; /* If this is true, then the input file was passed in. */ if ( flag == 1 ) { /* Allocate memory. */ if ( ( data->infile = CALLOC(len, char) ) == (char *)NULL ) { /* Print an error message and quit. */ memory_fail(__FILE__, __LINE__); } /* Copy the filename. */ strcpy(data->infile, filename); } /* Output filename. */ else { /* Allocate memory. */ if ( ( data->outfile = CALLOC(len, char) ) == (char *)NULL ) { /* Print an error message and quit. */ memory_fail(__FILE__, __LINE__); } /* Copy the filename. */ strcpy(data->outfile, filename); } /* Return success. */ return EXIT_SUCCESS; } /************************************************** * * DESCRIPTION * This function will return a reference to the * input netCDF file. * **************************************************/ char *ncx_getFile(ncDataP data, int in) { /* Error check. */ if ( data == (ncDataP)NULL ) { /* Print an error message. */ fprintf(stderr, "\n\nncx_getFile(): Input parameter " "is NULL in file %s line %d\n\n", __FILE__, __LINE__); /* Return null. */ return (char *)NULL; } /* Determine if the input file name is wanted. */ if ( in == 1 ) { /* Return the input file name. */ return data->infile; } else { /* Return the output file name. */ return data->outfile; } } int main() { //ncDataP data; //ncx_DataCALLOC(data); _ncData *data = new _ncData(); ncx_setFilename(data, "trun.nc", 1); if ( ncx_read(data) == EXIT_FAILURE ) { free_ncdata(data); return EXIT_FAILURE; } else print_ncdata(data); std::cout << "put tree here" << std::endl; TFile f("tree2.root","recreate"); TTree t2("t2","a Tree with data from trun.nc"); t2.Branch("trun.nc","_ncData", &data,8000,1); t2.Fill(); t2.Write(); //TTree *tree = new TTree(name, title, maxvirtualsize); //TBranch *branch = tree->Branch(branchname,className,object, bufsize, splitlevel); //create the file, the Tree and a few branches with tree2a.C //a subset of gctrak // TFile f("tree2.root","recreate"); // TTree t2("t2","a Tree with data from a fake Geant3"); // Gctrak *gstep = new Gctrak; // t2.Branch("track",&gstep,8000,1); /* Case B ====== TBranch *branch = tree->Branch(branchname,className,object, bufsize, splitlevel) object is the address of a pointer to an existing object (derived from TObject). if splitlevel=0, the object is serialized in the branch buffer. if splitlevel=1 (default), this branch will automatically be split into subbranches, with one subbranch for each data member or object of the object itself. In case the object member is a TClonesArray, the mechanism described in case C is applied to this array. if splitlevel=2 ,this branch will automatically be split into subbranches, with one subbranch for each data member or object of the object itself. In case the object member is a TClonesArray, it is processed as a TObject*, only one branch. */ return 0; }