/* file: txtlog.c G. Moody 18 January 2009 Last revised: 3 February 2009 ------------------------------------------------------------------------------- txtlog: Convert a MIMIC II text log into a WFDB annotation file 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 determines a base time, creates a .hea file specifying that base time and a sampling frequency of 1 Hz, and writes one annotation per line of input. The base time is 1 day (24 hours) before the date and time given in the first (tab-delimited) column of the first input line. The input of this program is a MIMIC II text log; its format is described in detail at http://physionet.org/physiobank/tutorials/using-mimic2/ . Note that this program cannot process an arbitrary text file as input; the input must contain (at a minimum) timestamps and recognizable source codes in the proper formats, and each line of text must be no more than about 270 characters. The elements of each output annotation are determined as follows: time elapsed time in sample intervals from the base time, taken from the first column of the input line anntyp always NOTE (see ) subtyp determined by the second column of the input line (see stringtosubtyp) num high byte of sequence number * chan low byte of sequence number * aux string containing the third and later columns of the input line, except that any absolute times found are first converted to times (in sample intervals) relative to the time of the annotation. * Sequence numbers start at 0 for the first annotation in any set of simultaneous annotations, and increment for each subsequent annotation in the set. Sequence numbers for isolated annotations are zero. Run this program in a terminal window without any command-line arguments to get instructions on its use. */ #include #include #include #include #include #include "mimic2.h" char *pname; main(int argc, char **argv) { static char line[2048], delim, *p, *q, *r, *v, ab[256], *ap, tstring[20]; char *record = NULL, *prog_name(); int i, stat = 0; static WFDB_Anninfo ai; WFDB_Annotation annot; WFDB_Date jd; WFDB_Time tp = 0; 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 '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; 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); } ai.stat = WFDB_WRITE; annot.anntyp = NOTE; annot.chan = annot.num = 0; annot.aux = ab; while (fgets(line, sizeof(line), stdin)) { for (i = 0, p = q = line; *q; q++) { if (*q == '\t' || *q == '\n') { /* end of field */ delim = *q; *q = '\0'; if (i == 0) { /* first field (annotation time) */ if (stat == 0) { /* first line, initialize */ if (setsampfreq(1.) < 0) exit(2); *(q-1) = '\0'; /* strip trailing ']' */ jd = strdat(p+10) - 1; sprintf(p+10, "%s", datstr(jd)); if (setbasetime(p+1) < 0) exit(2); if (newheader(record) < 0) exit(2); *(q-1) = ']'; /* restore trailing ']' */ if (annopen(record, &ai, 1) < 0) exit(2); stat = 1; annot.time = strtim("24:0:0"); } else annot.time = -strtim(p); } else if (i == 1) { /* second field (table name string) */ annot.subtyp = stringtosubtyp(p); ap = ab+1; } else if (*p == 't' && *(p+3) == '[' && *(p+strlen(p)-1)== ']') { sprintf(tstring, "%ld", -(annot.time + strtim(p+3))); *(p+3) = '\0'; sprintf(ap, "%s%s%s", p, tstring, delim == '\t' ? "\t": ""); ap += strlen(ap); } else { sprintf(ap, "%s%s", p, delim == '\t' ? "\t": ""); ap += strlen(ap); } if (delim == '\n') { *ab = strlen(ab+1); if (annot.time == tp) { annot.chan++; if (annot.chan == 0) annot.num++; } else { tp = annot.time; annot.chan = annot.num = 0; } if (putann(0, &annot) < 0) exit(3); } i++; p = q + 1; } } } wfdbquit(); exit(0); } 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