diff options
Diffstat (limited to 'vendor/voclient/voapps/votstat.c')
-rw-r--r-- | vendor/voclient/voapps/votstat.c | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/vendor/voclient/voapps/votstat.c b/vendor/voclient/voapps/votstat.c new file mode 100644 index 00000000..0065e314 --- /dev/null +++ b/vendor/voclient/voapps/votstat.c @@ -0,0 +1,281 @@ +/* + * VOTSTAT -- Compute statistics for numeric columns of a VOTable. + * + * Usage: + * votstat [<otps>] <votable> + * + * @file votstat.c + * @author Mike Fitzpatrick + * @date 6/03/12 + * + * @brief Compute statistics for numeric columns of a VOTable. + */ + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <math.h> + +#include "votParse.h" /* keep these in order! */ +#include "voApps.h" + + + +/* Global task declarations. + */ +static int vot = 0; /* VOTable handle */ + +static int do_all = 0; /* all columns? */ +static int do_return = 0; /* return result? */ + + +/* A result buffer should be defined to point to the result object if it is + * created dynamically, e.g. a list of votable columns. The task is + * responsible for initially allocating this pointer and then resizing as + * needed. + */ +#ifdef USE_RESBUF +#define SZ_RESBUF 8192 + +static char *resbuf; +#endif + + +/* Task specific option declarations. Task options are declared using the + * getopt_long(3) syntax. + */ +int votstat (int argc, char **argv, size_t *len, void **result); + +static Task self = { "votstat", votstat, 0, 0, 0 }; +static char *opts = "%:hao:r"; +static struct option long_opts[] = { + { "test", 1, 0, '%'}, + { "help", 2, 0, 'h'}, + { "all", 2, 0, 'a'}, + { "output", 1, 0, 'o'}, + { "return", 2, 0, 'r'}, + { NULL, 0, 0, 0 } +}; + + +/* Standard usage method. + */ +static void Usage (void); +static void Tests (char *input); + +void vot_colStat (int tdata, int col, int nrows, double *min, double *max, + double *mean, double *stddev); + +extern int vot_isNumericField (handle_t field); +extern double vot_atof (char *v); + + +/** + * Application entry point. + */ +int +votstat (int argc, char **argv, size_t *reslen, void **result) +{ + /* These declarations are required for the VOApps param interface. + */ + char **pargv, optval[SZ_FNAME]; + + /* These declarations are specific to the task. + */ + char *iname, *oname, *name, *id, *fstr; + int ch = 0, status = OK, numeric = 0; + int res, tab, data, tdata, field; + int i, ncols, nrows, pos = 0; + FILE *fd = (FILE *) NULL; + + + /* Initialize result object whether we return an object or not. + */ + *reslen = 0; + *result = NULL; + + iname = NULL; /* initialize local task values */ + oname = NULL; + + + /* Parse the argument list. + */ + pargv = vo_paramInit (argc, argv, opts, long_opts); + while ((ch = vo_paramNext(opts,long_opts,argc,pargv,optval,&pos)) != 0) { + if (ch > 0) { + switch (ch) { + case '%': Tests (optval); return (self.nfail); + case 'h': Usage (); return (OK); + case 'a': do_all++; break; + case 'o': oname = strdup (optval); break; + case 'r': do_return=1; break; + default: + fprintf (stderr, "Invalid option '%s'\n", optval); + return (1); + } + + } else if (ch == PARG_ERR) { + return (ERR); + + } else { + /* Process the positional arguments. + */ + iname = strdup (optval); + break; + } + } + + + /* Sanity checks. Tasks should validate input and accept stdin/stdout + * where it makes sense. + */ + if (iname == NULL) iname = strdup ("stdin"); + if (oname == NULL) oname = strdup ("stdout"); + if (strcmp(iname, "-") == 0) { free (iname), iname = strdup ("stdin"); } + if (strcmp(oname, "-") == 0) { free (oname), oname = strdup ("stdout"); } + + if (strcmp ("stdout", oname) == 0) + fd = stdout; + else { + if ((fd = fopen (oname, "w+")) == (FILE *) NULL) { + fprintf (stderr, "Cannot open output file '%s'\n", oname); + return (ERR); + } + } + + /* Open the table. This also parses it. + */ + if ( (vot = vot_openVOTABLE (iname) ) <= 0) { + fprintf (stderr, "Error opening VOTable '%s'\n", iname); + return (1); + } + + res = vot_getRESOURCE (vot); /* get handles */ + if (vot_getLength (res) > 1) { + fprintf (stderr, "Error: multiple RESOURCE elements not supported\n"); + goto clean_up_; + } + tab = vot_getTABLE (res); + if ((data = vot_getDATA (tab)) <= 0) + goto clean_up_; + tdata = vot_getTABLEDATA (data); + nrows = vot_getNRows (tdata); + ncols = vot_getNCols (tdata); + + + fprintf (fd, "# %3s %-20.20s %9.9s %9.9s %9.9s %9.9s\n#\n", + "Col", "Name", "Min", "Max", "Mean", "StdDev"); + + for (i=0,field=vot_getFIELD(tab); field; field=vot_getNext (field), i++) { + name = vot_getAttr (field, "name"); + id = vot_getAttr (field, "id"); + + numeric = vot_isNumericField (field); + fstr = (name ? name : (id ? id : "(none)")); + + if (do_all && !numeric) /* non-numeric column */ + fprintf (fd, " %3d %-20.20s\n", i, fstr); + + else if (do_all || numeric) { /* numeric column */ + double min, max, mean, stddev; + + vot_colStat (tdata, i, nrows, &min, &max, &mean, &stddev); + + if (mean > 1.0e6 || mean < 1.0e-3) + fprintf (fd, " %3d %-20.20s %9.4g %9.4g %9.4g %9.4g\n", + i, fstr, min, max, mean, stddev); + else + fprintf (fd, " %3d %-20.20s %9.2f %9.2f %9.2f %9.2f\n", + i, fstr, min, max, mean, stddev); + } + } + + + /* Clean up. Rememebr to free whatever pointers were created when + * parsing arguments. + */ +clean_up_: + if (iname) free (iname); + if (oname) free (oname); + + vo_paramFree (argc, pargv); + vot_closeVOTABLE (vot); + + if (fd != stdout) + fclose (fd); + + return (status); /* status must be OK or ERR (i.e. 0 or 1) */ +} + + +/** + * VOT_COLSTAT -- Determine the statistics of a table column. + */ +void +vot_colStat (int tdata, int col, int nrows, double *min, double *max, + double *mean, double *stddev) +{ + register int i = 0; + double sum = 0.0, sum2 = 0.0, val = 0.0; + + + *min = 0.99e306; + *max = -0.99e306; + *mean = 0.0; + *stddev = 0.0; + + for (i=0; i < nrows; i++) { + val = vot_atof (vot_getTableCell (tdata, i, col)); + sum += val; + sum2 += (val * val); + if (val < (*min)) *min = val; + if (val > (*max)) *max = val; + } + + *mean = (double) (sum / (double) nrows); + *stddev = sqrt ( ( sum2 / (double) nrows) - + ( (sum / (double) nrows) * (sum / (double) nrows) )); +} + + +/** + * USAGE -- Print task help summary. + */ +static void +Usage (void) +{ + fprintf (stderr, "\n Usage:\n\t" + "votstat [<opts>] votable.xml\n\n" + " where\n" + " -h,--help this message\n" + " -%%,--test run unit tests\n" + " -r,--return return result from method\n" + "\n" + " -a,--all print all columns\n" + " -o,--output=<file> output file\n" + "\n" + " Examples:\n\n" + " 1) Print statistics for a VOTable\n\n" + " %% votstat test.xml\n" + "\n" + " 2) Print statistics for all column in a VOTable and save \n" + " results to a file.\n\n" + " %% votstat -a -o stats test.xml\n" + "\n" + ); +} + + + +/** + * Tests -- Task unit tests. + */ +static void +Tests (char *input) +{ + Task *task = &self; + + vo_taskTest (task, "--help", NULL); +} |