home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------
- * The GMT-system: @(#)sample1d.c 2.20 4/11/95
- *
- * Copyright (c) 1991-1995 by P. Wessel and W. H. F. Smith
- * See README file for copying and redistribution conditions.
- *--------------------------------------------------------------------*/
- /*
- * sample1d reads a 1-D dataset, and resamples the values on (1) user
- * supplied time values or (2) equidistant time-values based on <timestart> and
- * <dt>, both supplied at the command line. Choose among linear, cubic
- * spline, and Akima's spline. sample1d will handle multiple column files,
- * user must choose which column contains the independent, monotonically
- * increasing variable.
- *
- * Author: Paul Wessel
- * Date: 5-JAN-1990
- * Version: v2.0
- *
- */
-
- #include "gmt.h"
-
- double *t_out, *tmp, *ttime, *data, **col, **out;
- BOOLEAN *nan_flag;
-
- main (argc, argv)
- int argc;
- char **argv; {
- int i, j, k, t = 0, n, m, n_alloc, m_alloc, result, n_col;
-
- BOOLEAN error = FALSE, equidist = FALSE, first = TRUE, t_supplied = FALSE;
- BOOLEAN got_t0 = FALSE, got_dt = FALSE, multi_segments = FALSE, ok;
-
- double dt = 0.0, t0 = 0.0, value, tt;
-
- char line[512], test[512], *ptr, type[3], *more, EOL_flag = '>';
-
- FILE *fpi = NULL, *fpt = NULL;
-
- type[0] = 'L'; type[1] = 'A'; type[2] = 'C';
-
- argc = gmt_begin (argc, argv);
-
- for (i = 1; i < argc; i++) {
- if (argv[i][0] == '-') {
- switch (argv[i][1]) {
-
- /* Common parameters */
-
- case 'H':
- case '\0':
- error += get_common_args (argv[i], 0, 0, 0, 0);
- break;
-
- /* Supplemental parameters */
-
- case 'A':
- gmtdefs.interpolant = 1;
- break;
- case 'C':
- gmtdefs.interpolant = 2;
- break;
- case 'I':
- dt = atof (&argv[i][2]);
- equidist = TRUE;
- got_dt = TRUE;
- break;
- case 'L':
- gmtdefs.interpolant = 0;
- break;
- case 'T':
- t = atoi (&argv[i][2]);
- break;
- case 'M': /* Multiple line segments */
- multi_segments = TRUE;
- if (argv[i][2]) EOL_flag = argv[i][2];
- break;
- case 'N':
- if ((fpt = fopen (&argv[i][2], "r")) == NULL) {
- fprintf (stderr, "sample1d: Cannot open file %s\n", &argv[i][2]);
- exit (-1);
- }
- t_supplied = TRUE;
- break;
- case 'S':
- t0 = atof (&argv[i][2]);
- equidist = TRUE;
- got_t0 = TRUE;
- break;
-
- default:
- error = TRUE;
- gmt_default_error (argv[i][1]);
- break;
- }
- }
- else if ((fpi = fopen (argv[i], "r")) == NULL) {
- fprintf (stderr, "sample1d: Cannot open file %s\n", argv[i]);
- exit (-1);
- }
-
- }
-
- if (argc == 1 || gmt_quick) { /* Display usage */
- fprintf (stderr,"sample1d %s - Resampling of 1-D data sets\n\n", GMT_VERSION);
- fprintf(stderr, "usage: sample1d <infile> [-A] [-C] [-H] [-I<t_inc>] [-L] [-M[<flag>]] [-N<knotfile>]\n");
- fprintf(stderr, " [-S<xstart>] [-T<time_col>]\n\n");
-
- if (gmt_quick) exit(-1);
-
- fprintf(stderr, " <infile> is a multicolumn ASCII table. [Default is standard input]\n");
- fprintf(stderr, "\n\tOPTIONS:\n");
- fprintf(stderr, " -A use Akima spline interpolation. [Default is -%c]\n", type[gmtdefs.interpolant]);
- fprintf(stderr, " -C use cubic spline interpolation. [Default is -%c]\n", type[gmtdefs.interpolant]);
- explain_option ('H');
- fprintf(stderr, " -I <x_inc> sets equidistant grid interval\n");
- fprintf(stderr, " -L use linear interpolation. [Default is -%c]\n", type[gmtdefs.interpolant]);
- fprintf(stderr, " -M Input files each consist of multiple segments separated by one record.\n");
- fprintf(stderr, " whose first character is <flag> [>].\n");
- fprintf(stderr, " -N <knotfile> is an ASCII table with the desired time positions in column 0\n");
- fprintf(stderr, " Overrides the -I and -S settings. If none of -I, -S, and -N is set\n");
- fprintf(stderr, " then <tstart> = first input point, <t_inc> = (t[1] - t[0])\n");
- fprintf(stderr, " -S <xstart> sets the first output point\n");
- fprintf(stderr, " -T gives column number of the independent variable (time) [Default is 0 (first)]\n");
- explain_option ('.');
- exit(-1);
- }
-
- if (t < 0) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -T option: Column number cannot be negative\n", gmt_program);
- error++;
- }
- if (t_supplied && equidist) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR: Specify only one of -N and -S\n", gmt_program);
- error++;
- }
- if (!t_supplied && !equidist) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR: Must specify one of -N and -S\n", gmt_program);
- error++;
- }
- if (got_dt && dt <= 0.0) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -I option: Must specify positive increment\n", gmt_program);
- error++;
- }
-
- if (error) exit (-1);
-
- if (fpi == NULL) fpi = stdin;
-
- if (gmtdefs.io_header) {
- for (i = 0; i < gmtdefs.n_header_recs; i++) {
- fgets (line, 512, fpi);
- printf ("%s", line);
- }
- }
- if (multi_segments) {
- fgets (line, 512, fpi);
- printf ("%s", line);
- }
-
- i = 0;
- more = fgets (line, 512, fpi);
-
- while (more) {
-
- i++;
- n = 0;
-
- if (first) { /* Allocate memory first time around */
- first = FALSE;
- strcpy (test, line);
- ptr = strtok (test, " \t");
- n_col = 0;
- while (ptr) {
- ptr = strtok (CNULL, " \t");
- n_col++;
- }
- if (t >= n_col) {
- fprintf (stderr, "sample1d: time_col exceeds range of columns!\n");
- exit (-1);
- }
- col = (double **) memory (CNULL, n_col, sizeof (double *), "sample1d");
- out = (double **) memory (CNULL, n_col, sizeof (double *), "sample1d");
- nan_flag = (BOOLEAN *) memory (CNULL, n_col, sizeof (BOOLEAN), "sample1d");
- n_alloc = GMT_CHUNK;
- for (j = 0; j < n_col; j++) col[j] = (double *) memory (CNULL, n_alloc, sizeof (double), "sample1d");
- }
-
- while ((more && !multi_segments) || (more && multi_segments && line[0] != EOL_flag)) {
-
- ptr = strtok (line, " \t");
- j = 0;
- while (ptr && j < n_col) {
- ok = sscanf (ptr, "%lf", &value);
- if (ok)
- col[j][n] = value;
- else {
- nan_flag[j] = TRUE;
- col[j][n] = gmt_NaN;
- }
- ptr = strtok (CNULL, " \t");
- j++;
- }
- if (ptr || j != n_col)
- fprintf (stderr, "sample1d: Column mismatch in record # %d\n", i);
- else
- n++;
-
- if (n == n_alloc) { /* Get more memory */
- n_alloc += GMT_CHUNK;
- for (j = 0; j < n_col; j++) col[j] = (double *) memory ((char *)col[j], n_alloc, sizeof (double), "sample1d");
- }
-
- more = fgets (line, 512, fpi);
- }
-
-
- if (nan_flag[t]) {
- fprintf (stderr, "sample1d: Independent column has NaN's!\n");
- exit (-1);
- }
-
- if (t_supplied) { /* read file with abscissae */
- m_alloc = GMT_CHUNK;
- t_out = (double *) memory ((char *)t_out, m_alloc, sizeof (double), "sample1d");
- m = 0;
- if (gmtdefs.io_header) for (i = 0; i < gmtdefs.n_header_recs; i++) fgets (line, 512, fpt);
- while (fgets (line, 512, fpt)) {
- sscanf (line, "%lf", &t_out[m]);
- m++;
- if (m == m_alloc) { /* Get more memory */
- m_alloc += GMT_CHUNK;
- t_out = (double *) memory ((char *)t_out, m_alloc, sizeof (double), "sample1d");
- }
- }
- fclose(fpt);
- }
- else { /* Generate evenly spaced grid */
- if (!got_dt) dt = col[t][1] - col[t][0];
- if (!got_t0) {
- t0 = floor (col[t][0] / dt) * dt;
- if (t0 < col[t][0]) t0 += dt;
- }
- m = m_alloc = rint ((col[t][n-1] - t0) / dt) + 1;
- if (m < 0) {
- fprintf (stderr, "sample1d: Abscissa must be monotonically increasing!\n");
- exit (-1);
- }
- t_out = (double *) memory (CNULL, m_alloc, sizeof (double), "sample1d");
- t_out[0] = t0;
- i = 1;
- while (i < m && (tt = t0 + i * dt) <= col[t][n-1]) {
- t_out[i] = tt;
- i++;
- }
- m = i;
- if (fabs (t_out[m-1]-col[t][n-1]) < SMALL) { /* Fix roundoff */
- t_out[m-1] = col[t][n-1];
- }
- }
-
- for (j = 0; !error && j < n_col; j++) {
- if (j == t) continue;
-
- tmp = (double *) memory (CNULL, m, sizeof (double), "sample1d");
-
- if (nan_flag[j]) { /* NaN's present, need "clean" time and data columns */
- ttime = (double *) memory (CNULL, n, sizeof (double), "sample1d");
- data = (double *) memory (CNULL, n, sizeof (double), "sample1d");
- for (i = k = 0; i < n; i++) {
- if ( bad_float (col[j][i]) ) continue;
- ttime[k] = col[t][i];
- data[k] = col[j][i];
- k++;
- }
- result = intpol (ttime, data, k, m, t_out, tmp, gmtdefs.interpolant);
- free ((char *)ttime);
- free ((char *)data);
- }
- else
- result = intpol (col[t], col[j], n, m, t_out, tmp, gmtdefs.interpolant);
-
- if (result != 0) {
- fprintf(stderr, "sample1d: Error from intpol (%d) for column %d!\n", result, j);
- error = TRUE;
- }
- else
- out[j] = tmp;
- }
-
- out[t] = t_out;
-
- for (i = 0; !error && i < m; i++) {
- printf (gmtdefs.d_format, out[0][i]);
- for (j = 1; j < n_col; j++) {
- putchar ('\t');
- printf (gmtdefs.d_format, out[j][i]);
- }
- putchar ('\n');
- }
-
- for (j = 1; j < n_col; j++) free ((char *)out[j]);
-
- if (more) {
- if (multi_segments) printf ("%s", line);
- more = fgets (line, 512, fpi);
- }
- }
-
- if (fpi != stdin) fclose(fpi);
-
- for (j = 0; j < n_col; j++) free ((char *)col[j]);
- free ((char *)t_out);
-
- gmt_end (argc, argv);
- }
-