/* file: logtxt.c G. Moody 19 January 2009 Last revised: 3 February 2009 ------------------------------------------------------------------------------- logtxt: Convert a MIMIC II annotation log to a text log Copyright (C) 2009 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/). _______________________________________________________________________________ This program reads a MIMIC II annotation log (in WFDB annotation file format) and produces text output that contains the same information. The text can be converted into an identical copy of the original annotation log by the complementary program, txtlog. The output of this program is a MIMIC II text log; its format is described in detail at http://physionet.org/physiobank/tutorials/using-mimic2/ . To obtain a human-readable version of a MIMIC II annotation log, use loghtml rather than this program. The output of loghtml is also documented at the URL above. Run this program in a terminal window without any command-line arguments to get instructions on its use. */ #include #include #include #include "mimic2.h" char *pname; main(int argc, char **argv) { char ab[300], *p, *q, *record = NULL, *prog_name(); signed char cflag = 0, nflag = 0, sflag = 0, submatch; double sps; int i; long from_time = 0L, to_time = 0L, atol(); static WFDB_Anninfo ai; WFDB_Annotation annot; void help(); pname = prog_name(argv[0]); /* Interpret command-line options. */ for (i = 1; i < argc; i++) { if (*argv[i] == '-') switch (*(argv[i]+1)) { case 'a': /* annotator follows */ if (++i >= argc) { (void)fprintf(stderr, "%s: annotator must follow -a\n", pname); exit(1); } ai.name = argv[i]; break; case 'f': /* starting time follows */ if (++i >= argc) { (void)fprintf(stderr, "%s: starting time must follow -f\n", pname); exit(1); } from_time = i; /* to be converted to sample intervals below */ break; case 'h': /* print usage summary and quit */ help(); exit(0); break; case 'r': /* input record name follows */ if (++i >= argc) { (void)fprintf(stderr, "%s: input record name must follow -r\n", pname); exit(1); } record = argv[i]; break; case 's': /* source code follows */ if (++i >= argc) { (void)fprintf(stderr, "%s: two-character source code must follow -s\n", pname); exit(1); } submatch = stringtosubtyp(argv[i]); sflag = 1; break; case 't': /* ending time follows */ if (++i >= argc) { (void)fprintf(stderr, "%s: end time must follow -t\n", pname); exit(1); } to_time = i; 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 || ai.name == NULL) { help(); exit(1); } if ((sps = sampfreq(record)) < 0.) (void)setsampfreq(sps = 1.0); ai.stat = WFDB_READ; if (annopen(record, &ai, 1) < 0) /* open annotation file */ exit(2); /* Handle -f and -t options if present. */ if (from_time) from_time = strtim(argv[(int)from_time]); if (from_time < 0L) from_time = -from_time; if (to_time) to_time = strtim(argv[(int)to_time]); else to_time = strtim("e"); if (to_time < 0L) to_time = -to_time; if (to_time > 0L && to_time < from_time) { long tt; tt = from_time; from_time = to_time; to_time = tt; } while (getann(0, &annot) == 0 && (to_time == 0L || annot.time <= to_time)) { if (annot.time < from_time) continue; /* skip entries before start */ if (sflag == 0 || annot.subtyp == submatch) { (void)printf("%s\t%s", timstr(-annot.time), subtyptostring(annot.subtyp)); if (annot.aux == NULL || *annot.aux == 0) { printf("\n"); continue; } strncpy(ab, annot.aux+1, *annot.aux + 1); *(ab + *annot.aux + 1) = '\0'; for (p = q = ab; *p; q++) { if (*q == '\t' || *q == '\0') { if (*p == 't') { *(p+2) = '\0'; printf("\t%s=%s", p, timstr(-(annot.time + atol(p+3)))); } else { *q = '\0'; printf("\t%s", p); } p = q+1; } } 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 -a ANNOTATOR [OPTIONS ...]\n", "where RECORD and ANNOTATOR specify the input, and OPTIONS may include:", " -f TIME start at specified TIME", " -h print this usage summary", " -s SOURCE print annotations with specified SOURCE only", " -t TIME stop at specified TIME", 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]); }