/* makenetcdf Aug 05 */ /* JGOFS data -> netcdf file capability */ /* Arg 1 - object spec */ /* Arg 2 - output file name */ /* Arg 3 - (optional) comma-separated list of variable names to be */ /* treated as alphas, or keyword #NONE#. Elements of this */ /* list are NOT checked for being legit varnames for the */ /* object. */ /* In absence of this arg, value of var that occurs in */ /* 1st rec is examined. If the value is missing, data */ /* are assumed numeric (compatibility w/matlab stuff) */ /* Note that problems can still occur if an alpha */ /* variable's first value happens to be numeric (eg, */ /* "standard station" variable) */ /* Switch -maxwidth - (optional; any position in arg list) */ /* Use "JGOFS system maximum" for width of alpha variables */ /* In absence of switch, widths attribute is used */ /* At issue is size of netcdf output file */ /* (Note that if sys max for makenetcdf's installation is */ /* < sys max for installation serving object, problems can */ /* still occur) */ /* Missing data not written to output file; accordingly, acquires */ /* netcdf "never written" value */ /************************************************************************/ #define MAKENETCDF_VERSION "makenetcdf 1.2 3 Dec 2012" /* 21 Jul 16. WJS */ /* Comment change/clarification */ /* 3 Dec 12. WJS */ /* Bug fix: if JGOFS dataset is empty, program was netcdf-closing */ /* without netcdf-opening. */ /* [Begin v 1.2] */ /* 22 Nov 08. WJS */ /* Allow strings w/trailing blanks to be considered numeric */ /* [Needs utils 2.4] */ /* [Needs core.h 2.0] */ /* [Begin v 1.1] */ #include INNEROPTIONS #include "jdbfuncdefns.h" #include /* utils routines */ Logical add_id_to_err(); char *buildstring(); void errn(); int get_integer_attribute(); char *lengthen_str(); char *lengthen_str_nl(); Logical string_in_list(); Logical string_is_numeric(); int level; int handle= -1; int nvar; char names[NVAR][VARNAMESIZE+1]; int namesize=VARNAMESIZE+1; char vals[NVAR][DATUMSIZE+1]; int valuesize=DATUMSIZE+1; #define MAXLEN_DIM_NAME_PREFIX "maxlen_" #define LEN_MAXLEN_DIM_NAME_PREFIX 7 char maxlen_dim_name_buffer[7+VARNAMESIZE+1] = MAXLEN_DIM_NAME_PREFIX; char attrbuf[ATTRSIZE+1]; /************************************************************************/ char *makenetcdf_return_vers() /* Dummy routine. Exists only to force .h file version string into */ /* this module. Note string must not be global or we'll have con- */ /* flicts if another routine similarly includes the version string */ { static char version[] = MAKENETCDF_VERSION"/"FULL_JDBFUNCDEFNSH_VERSION; return version; } void err(s,t) char *s,*t; { char *ss,*tt; add_id_to_err(&ss,&tt,s,t,MAKENETCDF_VERSION); printf ("%s\n%s\n",s,t); exit(ERROR_EXIT_STATUS); } int *widths_from_attributes(unit,nvar) int nvar,unit; { int *widths; int i; widths = (int *)malloc(nvar * (sizeof(int))); if (widths == NULL) errn ("widths malloc failure. # bytes in attempted allocation=", nvar * (sizeof(int))); for (i=0; i= 0 ) { var_is_numeric = (Logical *)malloc(nvar * (sizeof(Logical))); if (var_is_numeric == NULL) errn ("var_is_numeric malloc failure. # bytes in attempted allocation=", nvar * (sizeof(Logical))); /* Because we have to declare netcdf variable types before */ /* writing any, we have only the first JGOFS data record on */ /* which to base the info (unless we do 2 passes on the object) */ /* Therefore, an "nd" in the first data record forces us to guess */ /* at the type for that variable. We guess "alpha", since the */ /* user will at least have numeric data that way... */ /* Alternatively, user may have given us list of alpha vars. */ /* If so, use that */ for (i = 0; i < nvar; i++) if (alpha_var_list == NULL) var_is_numeric[i] = string_is_numeric(vals[i],TRUE); else var_is_numeric[i] = (all_numeric) ? TRUE : ( ! string_in_list(alpha_var_list,names[i],ALPHA_VAR_LIST_SEP)); status = nc_def_dim (netcdf_id,"unlimited",NC_UNLIMITED,&unlimited_dim); if (status != NC_NOERR) err ("nc_def_dim failure. netcdf err string: ", nc_strerror(status)); /* unlimited dimension must be first */ alpha_dims[0] = unlimited_dim; /* if we want all alpha vars to be sized "to the max", define that */ /* dimension now. Otherwise, we'll define a per-variable size based */ /* on width attribute */ if (max_width_flag) { status = nc_def_dim (netcdf_id,maxlen_dim_name_buffer, valuesize,&maxlen_dim); if (status != NC_NOERR) err ( buildstring("nc_def_dim failure for dimension ", maxlen_dim_name_buffer, " netcdf err string: ", "def_dim err msg" ), nc_strerror(status) ); alpha_dims[1] = maxlen_dim; } netcdf_varid = (int *)malloc(nvar * (sizeof(int))); if (netcdf_varid == NULL) errn ("netcdf_varid malloc failure. # bytes in attempted allocation=", nvar * (sizeof(int))); for (i=0; i= 0) { for (i=0; i