/* file: txt2dat.c G. Moody 15 February 1996 Last revised: 19 February 1996 This program creates a DB record (with signal and header files) from a set of `.txt' files. Copyright (C) Massachusetts Institute of Technology 1996. All rights reserved. */ #include #include #include #define SAMPINT 1.024 /* sampling interval in `.txt' files, in seconds */ #define SEGLEN 600 /* maximum samples per signal per txt file */ char *pname; char parname[DB_MAXSIG][16]; char signame[DB_MAXSIG][16]; DB_Siginfo s[DB_MAXSIG]; int nsig; main(argc, argv) int argc; char **argv; { int identify_params(); char *prog_name(); char buf[80], *record = NULL, orec[DB_MAXRNL+1], osfname[30], *p; char ifname[20], *ifpath; static char alarmbuf[DB_MAXSIG+1][32], inopbuf[DB_MAXSIG+1][32]; FILE *ifile; int i, j, n, pending[DB_MAXSIG+1], segment, vflag = 0; double x, y, z; DB_Sample v[DB_MAXSIG+1]; DB_Anninfo a[2]; DB_Annotation alarm[DB_MAXSIG+1], inop[DB_MAXSIG+1]; void help(); pname = prog_name(argv[0]); for (i = 1; i < argc; i++) { if (*argv[i] == '-') switch (*(argv[i]+1)) { case 'h': /* help requested */ help(); exit(0); break; case 'r': /* record name follows */ if (++i >= argc) { fprintf(stderr, "%s: record name must follow -r\n", pname); exit(1); } record = argv[i]; break; case 'v': /* verbose mode */ 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); } /* Open the first segment. */ segment = 1; sprintf(ifname, "%s%05d.txt", record, segment); if ((ifpath = dbfile(ifname, NULL)) == NULL || (ifile = fopen(ifpath, "r")) == NULL) { fprintf(stderr, "%s: can't open data file `%s'\n", pname, ifname); exit(2); } if (vflag) fprintf(stderr, "Processing %s ...", ifpath); /* Read the first (timestamp) line of the new file. */ fgets(buf, sizeof(buf), ifile); if (identify_params(ifile) <= 0) { fprintf(stderr, "No measurements found.\n"); fclose(ifile); exit(3); } if (vflag) { fprintf(stderr, "nsig = %d\n", nsig); for (i = 0; i < nsig; i++) fprintf(stderr, "%s\t%s\n", parname[i], signame[i]); } rewind(ifile); sprintf(osfname, "%sn.dat", record); for (i = 0; i < nsig; i++) { s[i].fname = osfname; s[i].desc = signame[i]; s[i].fmt = s[i].adcres = 16; if (strncmp("HR", parname[i], 2) == 0 || strncmp("PULSE", parname[i], 5) == 0 || strncmp("RESP", parname[i], 4) == 0) { s[i].units = "bpm"; s[i].gain = 1; } else if (strncmp("ABP", parname[i], 3) == 0 || strncmp("PAP", parname[i], 3) == 0 || strncmp("CVP", parname[i], 3) == 0 || strncmp("ART", parname[i], 3) == 0 || strncmp("UAP", parname[i], 3) == 0 || strncmp("NBP", parname[i], 3) == 0 || strncmp("P4", parname[i], 2) == 0 || strncmp("PAWP", parname[i], 4) == 0) { s[i].units = "mmHg"; s[i].gain = 1; } else if (strncmp("SpO2", parname[i], 4) == 0) { s[i].units = "%"; s[i].gain = 1; } else if (strncmp("Tblood", parname[i], 6) == 0) { s[i].units = "degC"; s[i].gain = 10; } else if (strncmp("C.O.", parname[i], 4) == 0) { s[i].units = "lpm"; s[i].gain = 100; } else s[i].gain = 10; } if (osigfopen(s, nsig) != nsig) exit(1); setsampfreq(1.0/1.024); /* txt sampling intervals are 1024 msec */ /* Read the first (timestamp) line of the new file. */ fgets(buf, sizeof(buf), ifile); for (i = 0; buf[i] != ']'; i++) ; buf[i] = '\0'; setbasetime(buf+1); sprintf(orec, "%sn", record); a[0].name = "al"; a[1].name = "in"; a[0].stat = a[1].stat = WRITE; if (annopen(orec, a, 2) < 0) exit(4); for (i = 0; i <= nsig; i++) { v[i] = -32768; pending[i] = 0; alarm[i].subtyp = alarm[i].num = inop[i].subtyp = inop[i].num = 0; alarm[i].chan = inop[i].chan = i-1; alarm[i].aux = alarmbuf[i]; inop[i].aux = inopbuf[i]; } while (1) { if (fgets(buf, sizeof(buf), ifile) == NULL) { fclose(ifile); newheader(orec); /* Force fclose of header by creating another. */ newheader("foo"); /* Open the next segment and discard the first (timestamp) line. */ sprintf(ifname, "%s%05d.txt", record, ++segment); if ((ifpath = dbfile(ifname, NULL)) == NULL || (ifile = fopen(ifpath, "r")) == NULL || fgets(buf, sizeof(buf), ifile) == NULL) break; if (vflag) fprintf(stderr, " elapsed time = %s\nProcessing %s ...", timstr(strtim("o")), ifpath); } if (strncmp(buf, "INOP", 4) == 0) { for (i = 0; i < nsig; i++) if (strstr(buf+5, parname[i])) break; if (i == nsig) i = 0; else i++; inop[i].anntyp = NOTE; inop[i].time = strtim("o"); for (p = buf+5; *p == ' ' || *p == '\t'; p++) ; *(p + strlen(p) - 1) = '\0'; /* drop trailing newline */ strcpy(inopbuf[i]+1, p); inopbuf[i][0] = strlen(inopbuf[i]+1); continue; } if (strncmp(buf, "ALARM", 5) == 0) { for (i = 0; i < nsig; i++) if (strstr(buf+8, parname[i])) break; if (i == nsig) i = 0; else i++; alarm[i].anntyp = NOTE; alarm[i].time = strtim("o"); for (p = buf+8; *p == ' ' || *p == '\t'; p++) ; *(p + strlen(p) - 1) = '\0'; /* drop trailing newline */ strcpy(alarmbuf[i]+1, p); alarmbuf[i][0] = strlen(alarmbuf[i]+1); continue; } for (i = 0; i < nsig; i++) if (strncmp(buf, parname[i], strlen(parname[i])) == 0) break; if (i < nsig) { if (pending[i]) { if (putvec(v) < 0) break; for (j = 0; j <= nsig; j++) { v[j] = -32768; pending[j] = 0; if (alarm[j].anntyp) { putann(0, &alarm[j]); alarm[j].anntyp = 0; } if (inop[j].anntyp) { putann(1, &inop[j]); inop[j].anntyp = 0; } } } if (strstr(buf, "[inactive")) { x = -32768.0/s[i].gain; n = 1; } else n = sscanf(buf+strlen(parname[i]),"%lf\t%lf\t%lf", &x, &y, &z); if (n == 1) z = y = x; v[i] = x*s[i].gain; pending[i] = 1; if (++i < nsig && strncmp(buf, parname[i], strlen(parname[i])) == 0) { v[i] = y*s[i].gain; pending[i] = 1; if (++i < nsig && strncmp(buf, parname[i], strlen(parname[i])) == 0) { v[i] = z*s[i].gain; pending[i] = 1; } } } } if (ifile) fclose(ifile); if (vflag) fprintf(stderr, "\nProcessing complete. Elapsed time = %s\n", timstr(strtim("o"))); newheader(orec); /* Remove the bogus header created in the loop above */ unlink(dbfile("header", "foo")); dbquit(); exit(0); } int identify_params(ifile) FILE *ifile; { char buf[80], tmpstring[80]; int i, j, n; double x, y, z; while (nsig < DB_MAXSIG-2 && fgets(buf, sizeof(buf), ifile)) { if (buf[0] == '[') continue; if (strncmp(buf, "INOP", 4) == 0) continue; if (strncmp(buf, "ALARM", 5) == 0) continue; for (i = 0; i < nsig; i++) if (strncmp(buf, parname[i], strlen(parname[i])) == 0) break; if (i < nsig) continue; n = sscanf(buf, "%s\t%lf\t%lf\t%lf", parname[nsig], &x, &y, &z); if (n == 2) { strcpy(signame[nsig], parname[nsig]); nsig++; } else if (n == 4) { strcpy(parname[nsig+1], parname[nsig]); strcpy(parname[nsig+2], parname[nsig]); sprintf(signame[nsig], "%sdias", parname[nsig]); sprintf(signame[nsig+1], "%ssys", parname[nsig]); sprintf(signame[nsig+2], "%smean", parname[nsig]); nsig += 3; } else fprintf(stderr, "%s: unrecognized input (n = %d):\n\t%s\n", pname, n, buf); } /* Sort the signals. */ for (i = 0; i < nsig; i++) for (j = i; j < nsig; j++) if (strcmp(signame[i], signame[j]) > 0) { strcpy(tmpstring, parname[i]); strcpy(parname[i], parname[j]); strcpy(parname[j], tmpstring); strcpy(tmpstring, signame[i]); strcpy(signame[i], signame[j]); strcpy(signame[j], tmpstring); } return (nsig); } 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 specifies the input, and OPTIONS may include:", " -h print this usage summary", " -v run in verbose mode", 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]); }