/* file: rdsamp.c G. Moody 23 June 1983 Last revised: 29 June 2005 ------------------------------------------------------------------------------- rdsamp: Print an arbitrary number of samples from each signal Copyright (C) 1983-2004 George B. Moody 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; either version 2 of the License, or (at your option) any later version. 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. You may contact the author by e-mail (george@mit.edu) or postal mail (MIT Room E25-505A, Cambridge, MA 02139 USA). For updates to this software, please visit PhysioNet (http://www.physionet.org/). _______________________________________________________________________________ */ #include #include /* Define the default WFDB path for CD-ROM versions of this program (the MS-DOS executables found in the `bin' directories of the various CD-ROMs). This program has been revised since the appearance of these CD-ROMs; compiling this file will not produce executables identical to those on the CD-ROMs. Note that the drive letter is not included in these WFDB path definitions, since it varies among systems. */ #ifdef MITCDROM #define WFDBP ";\\mitdb;\\nstdb;\\stdb;\\vfdb;\\afdb;\\cdb;\\svdb;\\ltdb;\\cudb" #endif #ifdef STTCDROM #define WFDBP ";\\edb;\\valedb" #endif #ifdef SLPCDROM #define WFDBP ";\\slpdb" #endif #ifdef MGHCDROM #define WFDBP ";\\mghdb" #endif char *pname; main(argc, argv) int argc; char *argv[]; { char *record = NULL, *prog_name(); int highres = 0, i, isiglist, nsig, nosig = 0, pflag = 0, s, *sig = NULL, vflag = 0; long from = 0L, maxl = 0L, to = 0L; WFDB_Sample *v; WFDB_Siginfo *si; void help(); #ifdef WFDBP char *wfdbp = getwfdb(); if (*wfdbp == '\0') setwfdb(WFDBP); #endif pname = prog_name(argv[0]); /* Accept old syntax. */ if (argc >= 2 && argv[1][0] != '-') { record = argv[1]; i = 2; if (argc > 2 && argv[2][0] != '-') { from = 2; i = 3; } if (argc > 3 && argv[3][0] != '-') { to = 3; i = 4; } if (argc > 4) { isiglist = 4; while (i < argc && argv[i][0] != '-') { i++; nosig++; } } } else i = 1; for ( ; i < argc; i++) { if (*argv[i] == '-') switch (*(argv[i]+1)) { case 'f': /* starting time */ if (++i >= argc) { (void)fprintf(stderr, "%s: time must follow -f\n", pname); exit(1); } from = i; break; case 'h': /* help requested */ help(); exit(0); break; case 'H': /* select high-resolution mode */ highres = 1; break; case 'l': /* maximum length of output follows */ if (++i >= argc) { (void)fprintf(stderr, "%s: max output length must follow -l\n", pname); exit(1); } maxl = i; break; case 'r': /* record name */ if (++i >= argc) { (void)fprintf(stderr, "%s: record name must follow -r\n", pname); exit(1); } record = argv[i]; break; case 'p': /* output in physical units specified */ ++pflag; break; case 's': /* signal list follows */ isiglist = i+1; /* index of first argument containing a signal # */ while (i+1 < argc && *argv[i+1] != '-') { i++; nosig++; /* number of elements in signal list */ } if (nosig == 0) { (void)fprintf(stderr, "%s: signal list must follow -s\n", pname); exit(1); } break; case 't': /* end time */ if (++i >= argc) { (void)fprintf(stderr, "%s: time must follow -t\n",pname); exit(1); } to = i; break; case 'v': /* verbose output -- include column headings */ vflag = 1; break; default: (void)fprintf(stderr, "%s: unrecognized option %s\n", pname, argv[i]); exit(1); } else { (void)fprintf(stderr, "%s: unrecognized argument %s\n", pname, argv[i]); exit(1); } } if (record == NULL) { help(); exit(1); } if ((nsig = isigopen(record, NULL, 0)) <= 0) exit(2); if ((v = malloc(nsig * sizeof(WFDB_Sample))) == NULL || (si = malloc(nsig * sizeof(WFDB_Siginfo))) == NULL) { (void)fprintf(stderr, "%s: insufficient memory\n", pname); exit(2); } if ((nsig = isigopen(record, si, nsig)) <= 0) exit(2); for (i = 0; i < nsig; i++) if (si[i].gain == 0.0) si[i].gain = WFDB_DEFGAIN; if (highres) setgvmode(WFDB_HIGHRES); if (from > 0L && (from = strtim(argv[from])) < 0L) from = -from; if (isigsettime(from) < 0) exit(2); if (to > 0L && (to = strtim(argv[to])) < 0L) to = -to; if (maxl > 0L && (maxl = strtim(argv[maxl])) < 0L) maxl = -maxl; if (maxl && (to == 0L || to > from + maxl)) to = from + maxl; if (nosig) { /* print samples only from specified signals */ #ifndef lint if ((sig = (int *)malloc((unsigned)nosig*sizeof(int))) == NULL) { (void)fprintf(stderr, "%s: insufficient memory\n", pname); exit(2); } #endif for (i = 0; i < nosig; i++) { if ((s = atoi(argv[isiglist+i])) < 0 || s >= nsig) { (void)fprintf(stderr, "%s: can't read signal %d\n", pname, s); exit(2); } sig[i] = s; } nsig = nosig; } else { /* print samples from all signals */ #ifndef lint if ((sig = (int *)malloc((unsigned)nsig*sizeof(int))) == NULL) { (void)fprintf(stderr, "%s: insufficient memory\n", pname); exit(2); } #endif for (i = 0; i < nsig; i++) sig[i] = i; } /* Print column headers if '-v' option selected. */ if (vflag) { char *p, *r, *t; int j, l; if (pflag == 0) (void)printf("samp #"); else (void)printf("time"); if ((t = malloc((strlen(record)+30) * sizeof(char))) == NULL) { fprintf(stderr, "%s: insufficient memory\n", pname); exit(2); } for (r = record+strlen(record); r > record; r--) if (*r == '/') { r++; break; } for (i = 0; i < nsig; i++) { /* Check if a default signal description was provided. Note that if the description comes from the header file, the record name may include path information that might not match that in 'record' (if any); so we compare only the final part of the description (p+j below) against the expected description (t). */ (void)sprintf(t, "%s, signal %d", r, sig[i]); p = si[sig[i]].desc; j = strlen(p) - strlen(t); if (j > 0 && strcmp(p+j, t) == 0) { (void)sprintf(t, "sig %d", sig[i]); p = t; } l = strlen(p); if (l > 7) p += l - 7; /* Print the last 7 characters of each signal description. */ (void)printf("\t%s%s", pflag > 1 ? " " : "", p); } (void)printf("\n"); } /* Print data in physical units if '-p' option selected. */ if (pflag) { char *p, *fmt = pflag > 1 ? "\t%15.8lf" : "\t%7.3f"; double freq = sampfreq(NULL); /* Print units as a second line of column headers if '-v' selected. */ if (vflag) { (void)printf("(sec)"); for (i = 0; i < nsig; i++) { p = si[sig[i]].units; if (p == NULL) p = "mV"; if ((int)strlen(p) > 5) p[5] = '\0'; /* Print the first 5 characters of each signal units string. */ (void)printf("\t%s(%s)", pflag > 1 ? " " : "", p); } (void)printf("\n"); } while ((to == 0L || from < to) && getvec(v) >= 0) { (void)printf("%7.3lf", (double)(from++)/freq); for (i = 0; i < nsig; i++) { if (v[sig[i]] != WFDB_INVALID_SAMPLE) (void)printf(fmt, (double)(v[sig[i]] - si[sig[i]].baseline)/si[sig[i]].gain); else (void)printf(pflag > 1 ? "\t%15s" : "\t%7s", "-"); } (void)printf("\n"); } } else { while ((to == 0L || from < to) && getvec(v) >= 0) { (void)printf("%6ld", from++); for (i = 0; i < nsig; i++) (void)printf("\t%5d", v[sig[i]]); (void)printf("\n"); } } exit(0); /*NOTREACHED*/ } char *prog_name(s) char *s; { char *p = s + strlen(s); #ifdef MSDOS while (p >= s && *p != '\\' && *p != ':') { if (*p == '.') *p = '\0'; /* strip off extension */ if ('A' <= *p && *p <= 'Z') *p += 'a' - 'A'; /* convert to lower case */ p--; } #else while (p >= s && *p != '/') p--; #endif return (p+1); } static char *help_strings[] = { "usage: %s -r RECORD [OPTIONS ...]\n", "where RECORD is the name of the input record, and OPTIONS may include:", " -f TIME begin at specified time", " -h print this usage summary", " -H read multifrequency signals in high resolution mode", " -l INTERVAL truncate output after the specified time interval (hh:mm:ss)", " -p print times and samples in physical units (default: raw units)", " (use -p -p for greater precision)", " -s SIGNAL [SIGNAL ...] print only the specified signal(s)", " -t TIME stop at specified time", " -v print column headings", NULL }; void help() { int i; (void)fprintf(stderr, help_strings[0], pname); for (i = 1; help_strings[i] != NULL; i++) (void)fprintf(stderr, "%s\n", help_strings[i]); }