/*-------------------------------------------------------------------- * $Id: minmax.c,v 1.3.4.3 2002/02/27 17:41:10 pwessel Exp $ * * Copyright (c) 1991-2002 by P. Wessel and W. H. F. Smith * See COPYING file for copying and redistribution conditions. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * Contact info: gmt.soest.hawaii.edu *--------------------------------------------------------------------*/ /* * minmax.c will read ascii or binary tables and report the * extreme values for all columns * * Author: Paul Wessel * Date: 20-JUN-2000 * Revised: 20-FEB-2001 BCH-J: Added -D option for dateline discontinuity * Version: 3.4.1 */ #include "gmt.h" main (int argc, char **argv) { int n, i, ncol, n_files = 0, fno, n_args, n_fields, n_expected_fields; BOOLEAN error = FALSE, nofile = TRUE, done = FALSE, got_stuff = FALSE, first, step = FALSE, columns = FALSE, give_r_string = FALSE; BOOLEAN dateline = FALSE; double delta[2], *xyzmin, *xyzmax, west, east, south, north, low, high, *in; char line[BUFSIZ], file[BUFSIZ], format[BUFSIZ], empty_format[15]; FILE *fp = NULL; argc = GMT_begin (argc, argv); for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { /* Common parameters */ case 'H': case ':': case '\0': error += GMT_get_common_args (argv[i], 0, 0, 0, 0); break; /* Supplemental parameters */ case 'b': error += GMT_io_selection (&argv[i][2]); break; case 'C': columns = TRUE; break; case 'D': dateline = TRUE; break; case 'M': GMT_multisegment (&argv[i][2]); break; case 'I': GMT_getinc (&argv[i][2], &delta[0], &delta[1]); step = TRUE; break; case 'L': GMT_geographic_in = TRUE; break; default: error = TRUE; GMT_default_error (argv[i][1]); break; } } else n_files++; } if (error || GMT_quick) { /* Because it's ok to give no arguments */ fprintf (stderr, "minmax %s - Find extreme values in ASCII tables\n\n", GMT_VERSION); fprintf (stderr, "usage: minmax [files] [-C] [-D] [-H[]] [-Idx[/dy]] [-L] [-M[]] [-:] [-bi[s][]\n"); if (GMT_quick) exit (EXIT_FAILURE); fprintf (stderr, "\t-C formats the min and max into separate columns\n"); fprintf (stderr, "\t-D sets longitude discontinuity to dateline (requires -L)\n"); GMT_explain_option ('H'); fprintf (stderr, "\t-I returns textstring -Rw/e/s/n to nearest multiple of dx/dy (assumes 2+ col data)\n"); fprintf (stderr, "\t If -C is set then only the first 2 columns are rounded off and no -R string is issued\n"); fprintf (stderr, "\t-L means that x is longitude, i.e. assumed to be periodic in 360\n"); GMT_explain_option ('M'); GMT_explain_option (':'); GMT_explain_option ('i'); GMT_explain_option ('n'); fprintf (stderr, "\t Default is 2 input columns\n"); GMT_explain_option ('.'); exit (EXIT_FAILURE); } if (step && (delta[0] <= 0.0 || delta[1] <= 0.0)) { fprintf (stderr, "%s: GMT SYNTAX ERROR -I option. Must specify positive increment(s)\n", GMT_program); error++; } if (GMT_io.binary[0] && gmtdefs.io_header) { fprintf (stderr, "%s: GMT SYNTAX ERROR. Binary input data cannot have header -H\n", GMT_program); error++; } if (GMT_io.binary[0] && GMT_io.ncol[0] == 0) GMT_io.ncol[0] = 2; if (GMT_io.binary[0] && GMT_io.ncol[0] < 1) { fprintf (stderr, "%s: GMT SYNTAX ERROR. Binary input data (-bi) must have at least 1 column\n", GMT_program); error++; } if (! GMT_geographic_in && dateline) { fprintf (stderr, "%s: GMT SYNTAX ERROR -D option: requires -L\n", GMT_program); error++; } if (error) exit (EXIT_FAILURE); GMT_put_history (argc, argv); /* Update .gmtcommands */ if (GMT_io.binary[0] && gmtdefs.verbose) { char *type[2] = {"double", "single"}; fprintf (stderr, "%s: Expects %d-column %s-precision binary data\n", GMT_program, GMT_io.ncol[0], type[GMT_io.single_precision[0]]); } if (n_files > 0) nofile = FALSE; else n_files = 1; n_args = (argc > 1) ? argc : 2; west = south = DBL_MAX; east = north = -DBL_MAX; xyzmin = (double *) GMT_memory (VNULL, (size_t)1, sizeof (double), GMT_program); xyzmax = (double *) GMT_memory (VNULL, (size_t)1, sizeof (double), GMT_program); if (step && !columns) { give_r_string = TRUE; sprintf (format, "-R%s/%s/%s/%s\n", gmtdefs.d_format, gmtdefs.d_format, gmtdefs.d_format, gmtdefs.d_format); } else if (columns) { sprintf (format, "\t%s\t%s", gmtdefs.d_format, gmtdefs.d_format); strcpy (empty_format, "\tNaN\tNaN"); } else { sprintf (format, "\t<%s/%s>", gmtdefs.d_format, gmtdefs.d_format); strcpy (empty_format, "\t"); } n_expected_fields = (GMT_io.ncol[0]) ? GMT_io.ncol[0] : BUFSIZ; for (fno = 1; !done && fno < n_args; fno++) { /* Loop over input files, if any */ if (!nofile && argv[fno][0] == '-') continue; if (nofile) { /* Just read standard input */ fp = GMT_stdin; done = TRUE; strcpy (file, ""); if (gmtdefs.verbose) fprintf (stderr, "%s: Reading from standard input\n", GMT_program); #ifdef SET_IO_MODE GMT_setmode (0); #endif } else { strcpy (file, argv[fno]); if ((fp = GMT_fopen (file, GMT_io.r_mode)) == NULL) { fprintf (stderr, "%s: Cannot open file %s\n", GMT_program, file); continue; } } if (gmtdefs.io_header) for (i = 0; i < gmtdefs.n_header_recs; i++) GMT_fgets (line, BUFSIZ, fp); n = ncol = 0; n_expected_fields = (GMT_io.ncol[0]) ? GMT_io.ncol[0] : BUFSIZ; first = TRUE; n_fields = GMT_input (fp, &n_expected_fields, &in); while (! (GMT_io.status & GMT_IO_EOF)) { /* Not yet EOF */ while ((GMT_io.status & GMT_IO_SEGMENT_HEADER) && !(GMT_io.status & GMT_IO_EOF)) { n_fields = GMT_input (fp, &n_expected_fields, &in); } if ((GMT_io.status & GMT_IO_EOF)) continue; /* At EOF */ if (GMT_io.status & GMT_IO_MISMATCH) { fprintf (stderr, "%s: Mismatch between actual (%d) and expected (%d) fields near line %d\n", GMT_program, n_fields, n_expected_fields, n); exit (EXIT_FAILURE); } if (first) { /* First time, allocate # of columns */ ncol = n_expected_fields; /* Now we know # of columns, so allocate memory */ xyzmin = (double *) GMT_memory ((void *)xyzmin, (size_t)ncol, sizeof (double), GMT_program); xyzmax = (double *) GMT_memory ((void *)xyzmax, (size_t)ncol, sizeof (double), GMT_program); for (i = 0; i < ncol; i++) { /* Initialize */ xyzmin[i] = +DBL_MAX; xyzmax[i] = -DBL_MAX; } if (step && ncol < 2 && !columns) step = FALSE; first = FALSE; } /* Decode all fields and update minmax arrays */ while (dateline && in[0] > 180.0) in[0] -= 360.0; for (i = 0; i < ncol; i++) { if (GMT_is_dnan (in[i])) continue; if (in[i] < xyzmin[i]) xyzmin[i] = in[i]; if (in[i] > xyzmax[i]) xyzmax[i] = in[i]; } n++; n_fields = GMT_input (fp, &n_expected_fields, &in); } if (fp != GMT_stdin) GMT_fclose (fp); if (!got_stuff) got_stuff = (n > 0); /* We were able to open and read at least 1 record from a file */ if (give_r_string && got_stuff) { west = MIN (west, xyzmin[0]); east = MAX (east, xyzmax[0]); south = MIN (south, xyzmin[1]); north = MAX (north, xyzmax[1]); } else if (n > 0) { if (!columns) fprintf (GMT_stdout, "%s: N = %d", file, n); for (i = 0; i < ncol; i++) { if (xyzmin[i] == DBL_MAX) fprintf (GMT_stdout, "%s", empty_format); else if (i < 2) { low = (step) ? floor (xyzmin[i] / delta[i]) * delta[i] : xyzmin[i]; high = (step) ? ceil (xyzmax[i] / delta[i]) * delta[i] : xyzmax[i]; fprintf (GMT_stdout, format, low, high); } else { fprintf (GMT_stdout, format, xyzmin[i], xyzmax[i]); } } fprintf (GMT_stdout, "\n"); } } if (got_stuff && give_r_string) { west = floor (west / delta[0]) * delta[0]; east = ceil (east / delta[0]) * delta[0]; south = floor (south / delta[1]) * delta[1]; north = ceil (north / delta[1]) * delta[1]; fprintf (GMT_stdout, format, west, east, south, north); } else if (!got_stuff) fprintf (stderr, "%s: No input data found!\n", GMT_program); GMT_free ((void *)xyzmin); GMT_free ((void *)xyzmax); GMT_end (argc, argv); }