int fetchannotations(void) { int afirst = 1, i; WFDB_Anninfo ai; WFDB_Time ta0, taf; if (nann < 1) return (0); if (tfreq != ffreq) { ta0 = (WFDB_Time)(t0*tfreq/ffreq + 0.5); taf = (WFDB_Time)(tf*tfreq/ffreq + 0.5); } else { ta0 = t0; taf = tf; } printf(" %c \"annotator\":\n [", nosig > 0 ? ' ' : '{'); setgvmode(WFDB_HIGHRES); for (i = 0; i < nann; i++) { ai.name = annotator[i]; ai.stat = WFDB_READ; if (annopen(recpath, &ai, 1) >= 0) { char *p; int first = 1; WFDB_Annotation annot; if (ta0 > 0L) iannsettime(ta0); if (!afirst) printf(","); else afirst = 0; printf("\n { \"name\": \"%s\",\n", annotator[i]); printf(" \"annotation\":\n"); printf(" ["); while ((getann(0, &annot) == 0) && (taf <= 0 || annot.time < taf)) { if (!first) printf(","); else first = 0; printf("\n { \"t\": %ld,\n", (long)(annot.time)); printf(" \"a\": %s,\n", p = strjson(annstr(annot.anntyp))); SFREE(p); printf(" \"s\": %d,\n", annot.subtyp); printf(" \"c\": %d,\n", annot.chan); printf(" \"n\": %d,\n", annot.num); if (annot.aux && *(annot.aux)) { printf(" \"x\": %s\n", p = strjson(annot.aux+1)); SFREE(p); } else printf(" \"x\": null\n"); printf(" }"); } printf("\n ]\n }"); } } printf("\n ]\n }\n"); return (1); }
INTEGER getann_(INTEGER *annotator, INTEGER *time, INTEGER *anntyp, INTEGER *subtyp, INTEGER *chan, INTEGER *num, char *aux) { static WFDB_Annotation iann; int i, j; i = getann((WFDB_Annotator)(*annotator), &iann); if (i == 0) { *time = iann.time; *anntyp = iann.anntyp; *subtyp = iann.subtyp; *chan = iann.chan; *num = iann.num; aux = iann.aux; } return (i); }
main() { WFDB_Anninfo an[2]; char record[8], iann[10], oann[10]; WFDB_Annotation annot; printf("Type record name: "); fgets(record, 8, stdin); record[strlen(record)-1] = '\0'; printf("Type input annotator name: "); fgets(iann, 10, stdin); iann[strlen(iann)-1] = '\0'; printf("Type output annotator name: "); fgets(oann, 10, stdin); oann[strlen(oann)-1] = '\0'; an[0].name = iann; an[0].stat = WFDB_READ; an[1].name = oann; an[1].stat = WFDB_WRITE; if (annopen(record, an, 2) < 0) exit(1); while (getann(0, &annot) == 0) if (isqrs(annot.anntyp)) { annot.anntyp = NORMAL; if (putann(0, &annot) < 0) break; } wfdbquit(); }
int main(int argc, char **argv) { int c; int inflag = 0; int dbg = 0; int sr_ds = 200; char * rec_name = "vfdb/427"; char * db_path = "/opt/physiobank/database"; size_t win_sec = 8; /* r stands for record with folder * p for path * i for information of record * s downsample sr * w window length default:8 * d debug */ while ((c = getopt(argc, argv, "idr:p:s:w:")) != -1) switch (c){ case 'i': inflag = 1; break; case 'r': rec_name = optarg; break; case 'p': db_path = optarg; break; case 's': sr_ds= atoi(optarg); break; case'w': win_sec = atoi(optarg); break; case'd': dbg = 1; break; default: abort(); } int i, j, nsig; WFDB_Sample *v; WFDB_Siginfo *s; WFDB_Anninfo a; setwfdb(db_path); nsig = isigopen(rec_name, NULL, 0); if (nsig < 1){ printf("nsig:%d\n",nsig); exit(1); } s = (WFDB_Siginfo *)malloc(nsig * sizeof(WFDB_Siginfo)); if (isigopen(rec_name, s, nsig) != nsig) exit(1); v = (WFDB_Sample *)malloc(nsig * sizeof(WFDB_Sample)); int orig_sr = sampfreq(rec_name); a.name = "atr"; a.stat = WFDB_READ; if (wfdbinit(rec_name, &a, 1, s, nsig) != nsig) exit(3); if(1 == inflag ){ printf("sr:%d\n",orig_sr); printf("%d signals\n", nsig); for (i = 0; i < nsig; i++) { printf("Group %d, Signal %d:\n", s[i].group, i); printf("File: %s\n", s[i].fname); printf("Description: %s\n", s[i].desc); printf("Gain: "); if (s[i].gain == 0.) printf("uncalibrated; assume %g", WFDB_DEFGAIN); else printf("%g", s[i].gain); printf(" adu/%s\n", s[i].units ? s[i].units : "mV"); printf(" Initial value: %d\n", s[i].initval); printf(" Storage format: %d\n", s[i].fmt); printf(" I/O: "); if (s[i].bsize == 0) printf("can be unbuffered\n"); else printf("%d-byte blocks\n", s[i].bsize); printf(" ADC resolution: %d bits\n", s[i].adcres); printf(" ADC zero: %d\n", s[i].adczero); if (s[i].nsamp > 0L) { printf(" Length: %s (%ld sample intervals)\n", timstr(s[i].nsamp), s[i].nsamp); printf(" Checksum: %d\n", s[i].cksum); } else printf(" Length undefined\n"); } } fifo_t fifo_ecg; int fifo_ecg_buf[FIFO_SIZE]; fifo_init(&fifo_ecg, fifo_ecg_buf, FIFO_SIZE); fifo_t fifo_bt; int fifo_bt_buf[FIFO_SIZE]; fifo_init(&fifo_bt, fifo_bt_buf, FIFO_SIZE); int tmp = 0; int sr = 200; WFDB_Time begin_samp = 0; WFDB_Time end_samp = orig_sr*win_sec; WFDB_Annotation begin_ann; WFDB_Annotation end_ann; getann(0, &begin_ann); while(0 == getann(0, &end_ann)) if ((end_ann.aux != NULL && *end_ann.aux > 0) ||0 == strcmp(annstr(end_ann.anntyp), "[") ||0 == strcmp(annstr(end_ann.anntyp), "]") ||0 == strcmp(annstr(end_ann.anntyp), "~") ){ break; } int * pBt_len = (int*)calloc(win_sec,sizeof(int)); ResetBDAC(); for (; ;) { if (getvec(v) < 0) break; // for (j = 0; j < nsig; j++){ // } tmp = v[nsig-1]; tmp = v[0]; int vout1 = 0; static int bt_i = 0; static unsigned int samplecnt = 0; int idx = 0; if(down_sample(tmp, &vout1, orig_sr, sr)) { samplecnt ++; fifo_write(&fifo_ecg, &vout1, 1*sizeof(int)); int beatType, beatMatch; long ltmp = vout1-s[0].adczero; ltmp *= 200; ltmp /= s[0].gain; int bdac_dly = BeatDetectAndClassify(ltmp, &beatType, &beatMatch); idx = bt_i/sr; if (0 != bdac_dly ) { pBt_len[idx]++; fifo_write(&fifo_bt, &beatType, sizeof(int)); } bt_i = ++bt_i%(win_sec*sr); } double cm = 0.0; int size = win_sec*sr; if(fifo_len(&fifo_ecg)/sizeof(int) >= sr*win_sec){ int * win_data = (int*)malloc(win_sec*sr*sizeof(int)); int * ds_data = (int*)malloc(win_sec*sr_ds*sizeof(int)); int len = fifo_len(&fifo_bt)/sizeof(int); int * p = (int*)calloc(len, sizeof(int)); if (0 != len){ //printf("bt_i:%d\n", bt_i); fifo_read_steps(&fifo_bt, p, len*sizeof(int), pBt_len[bt_i/sr]*sizeof(int)); //for (i = 0;i< len;i++) printf("%d ", p[i]); //printf("\n"); } pBt_len[bt_i/sr] = 0; fifo_read_steps(&fifo_ecg, win_data, size*sizeof(int), sr*sizeof(int)); filtering(win_data, size, sr); int i = 0; int ds_size = 0; int vout; for(i = 0;i < size;i++){ // if(down_sample(win_data[i], &vout, sr, sr_ds)) ds_data[ds_size++] = vout; } double dven = 0.0; if (0 != len){ int tmp_cnt = 0; for(i = 0; i < len ; i++){ if(5 == p[i]) dven ++; } //printf("div:%d %d\n", tmp_cnt, len); dven /= len; } //cm = ecg_complexity_measure(win_data, size); //cm = ecg_complexity_measure(ds_data, ds_size); //cm = cpsd(ds_data, ds_size, 0.5*sr_ds); //cm = calc_grid(ds_data, ds_size, 0.5*sr_ds); cm = calc_grid(win_data, size, 0.5*sr); if (-1 == cm ) continue; //VT print 1; //VF print 2; int hr = (int)((double)(len*60)/win_sec+0.5); int ret = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(VT"); if (1 == ret){ printf("%d %lf %lf %d\n", 1, cm, dven, hr); } else if (0 == ret) { ret = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(VFL"); int ret2 = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "["); if (1 == ret || 1 == ret2){ printf("%d %lf %lf %d\n", 2, cm, dven, hr); } else if (0 == ret){ // ret = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(N"); // int ret3 = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "N"); // if ((1 == ret || 1 == ret3) && -1 != begin_ann.subtyp) printf ("%d %lf %lf %d\n", 0, cm, dven, hr); if (1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(AFIB") || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(AFL") || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(IVR") || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(SVTA") || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(SBR") || 1 == check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(BII") ) printf ("%d %lf %lf %d\n", 0, cm, dven, hr); // int ret = check_ann(begin_samp, end_samp, &begin_ann, &end_ann, "(SVTA"); // if (1 == ret) printf ("%d %lf\n", 0, cm); } } //iannsettime(begin_samp); begin_samp += orig_sr; end_samp += orig_sr; if(end_ann.time < begin_samp){ begin_ann = end_ann; while(1) if (0 != getann(0, &end_ann)){ end_ann = begin_ann; /*the last sample of the signal*/ end_ann.time = s[nsig-1].nsamp; break; }else if ((end_ann.aux != NULL && *end_ann.aux > 0) ||0 == strcmp(annstr(end_ann.anntyp), "[") ||0 == strcmp(annstr(end_ann.anntyp), "]") ||0 == strcmp(annstr(end_ann.anntyp), "~") ){ break; } if(dbg){ printf("begin tm:%s type:%s ", mstimstr(begin_ann.time), annstr(begin_ann.anntyp)); if(begin_ann.aux != NULL) printf("begin aux:%s", begin_ann.aux+1); printf("\n"); printf("end tm:%s type:%s ", mstimstr(end_ann.time), annstr(end_ann.anntyp)); if (end_ann.aux != NULL) printf("end aux:%s", end_ann.aux+1); printf("\n"); printf("begin sample:%s\n", mstimstr(begin_samp)); printf("ann diff:%s\n", mstimstr(end_ann.time-begin_ann.time)); } } free(p); free(ds_data); free(win_data); } } free(pBt_len); wfdbquit(); return 0; }
main(int argc, char **argv) { char *oaname = "gqf"; double HR; FILE *config = NULL; int a0 = 0, a1 = 0, **count, dn, i, ibest, ichosen = 0, j, *mbuf, n, niann = 0, nseg, tdn; WFDB_Anninfo *a; WFDB_Annotation annot; WFDB_Frequency spm; WFDB_Time t0, tf; pname = prog_name(argv[0]); for (i = 1; i < argc; i++) { if (*argv[i] == '-') switch (*(argv[i]+1)) { case 'a': /* input annotator names */ for (a0 = a1 = ++i; a1 < argc && *argv[a1] != '-'; a1++, i++) ; if ((niann = a1 - a0) < 2) { (void)fprintf(stderr, "%s: input annotator names must follow -a\n", pname); cleanup(1); } break; case 'c': /* configuration file */ if (++i >= argc) { (void)fprintf(stderr, "%s: name of configuration file must follow -c\n", pname); cleanup(1); } if ((config = fopen(argv[i], "rt")) == NULL) { (void)fprintf(stderr, "%s: can't read configuration file %s\n", pname, argv[i]); cleanup(1); } break; case 'h': /* help requested */ help(); cleanup(0); break; case 'o': /* output annotator name */ if (++i >= argc) { (void)fprintf(stderr, "%s: output annotator name must follow -o\n", pname); cleanup(1); } oaname = argv[i]; break; case 'r': /* record name */ if (++i >= argc) { (void)fprintf(stderr, "%s: input record name must follow -r\n", pname); cleanup(1); } record = argv[i]; break; default: (void)fprintf(stderr, "%s: unrecognized option %s\n", pname, argv[i]); cleanup(1); } else { (void)fprintf(stderr, "%s: unrecognized argument %s\n", pname, argv[i]); cleanup(1); } } /* Quit unless record name and at least two annotator names specified. */ if (record == NULL || niann < 2) { help(); cleanup(1); } /* Set up annotator info. */ a = gcalloc(sizeof(WFDB_Anninfo), niann+1); for (i = a0, j = 0; i < a1; i++, j++) { a[j].name = argv[i]; a[j].stat = WFDB_READ; } a[j].name = oaname; a[j].stat = WFDB_WRITE; /* Read a priori physiologic parameters from the configuration file if available. They can be adjusted in the configuration file for pediatric, fetal, or animal ECGs. */ if (config) { char buf[256], *p; /* Read the configuration file a line at a time. */ while (fgets(buf, sizeof(buf), config)) { /* Skip comments (empty lines and lines beginning with `#'). */ if (buf[0] == '#' || buf[0] == '\n') continue; /* Set parameters. Each `getconf' below is executed once for each non-comment line in the configuration file. */ getconf(HR, "%lf"); } fclose(config); } /* If any a priori parameters were not specified in the configuration file, initialize them here (using values chosen for adult human ECGs). */ if (HR == 0.0) HR = 75; spm = 60.0 * sampfreq(record); /* sample intervals per minute */ nseg = strtim("e")/spm; /* number of complete 1-minute intervals */ /* Set up buffer for median calculation. */ mbuf = gcalloc(sizeof(int), niann + 1); mbuf[niann] = HR; /* initial median is HR */ /* Set up arrays for HR minute-by-minute time series. */ count = gcalloc(sizeof(int *), niann + 1); for (i = 0; i < niann; i++) count[i] = gcalloc(sizeof(int), nseg+1); /* Pass 1: Load the HR arrays. */ if (annopen(record, a, niann) < 0) cleanup(2); for (i = 0; i < niann; i++) { for (tf = spm, j = 0; j < nseg+1; tf += spm, j++) { n = 0; while (getann(i, &annot) == 0 && annot.time < tf) if (isqrs(annot.anntyp)) n++; count[i][j] = n; } } wfdbquit(); /* Pass 2: Select the input annotations to be copied, and copy them. */ if (annopen(record, a, niann+1) < 0) cleanup(2); for (j = 0, t0 = 0, tf = spm; j < nseg+1; j++, t0 = tf, tf += spm) { for (i = 0; i < niann; i++) mbuf[i] = count[i][j]; /* Note that the last element, mbuf[niann], is the previous median. */ qsort(mbuf, niann+1, sizeof(int), icomp); /* If mbuf has an even number of members, the median is the mean of the two central values. */ if (niann & 1) mbuf[niann] = (mbuf[(niann-1)/2] + mbuf[(niann+1)/2])/2; /* Otherwise it's the single central value. */ else mbuf[niann] = mbuf[niann/2]; /* Find the input that best matches the prediction (the median). */ for (i = 0, dn = 9999; i < niann; i++) { tdn = mbuf[niann] - count[i][j]; if (tdn < 0) tdn = -tdn; if (tdn < dn) { dn = tdn; ibest = i; } } /* If the best match is not the previously chosen input, avoid switching the input unless it's more than 2 beats further from the median. */ if (ibest != ichosen) { tdn = mbuf[niann] - count[ichosen][j]; if (tdn < 0) tdn = -tdn; if (tdn < dn + 3) ibest = ichosen; } ichosen = ibest; /* Copy the chosen annotations for this one-minute segment. */ n = 0; while (getann(ichosen, &annot) == 0 && n <= count[ichosen][j]) { if (annot.time >= t0 && isqrs(annot.anntyp)) { putann(0, &annot); n++; } } ungetann(ichosen, &annot); } cleanup(0); }
void gettest() /* get next test annotation */ { static long tt; /* time of previous test beat annotation */ static struct WFDB_ann annot; tt = t; t = tprime; a = aprime; /* See comments on the similar code in getref(), above. */ if (tt == 0L || t == huge_time || (tt <= vfontest && vfontest < t) || (tt <= sdontest && sdontest < t) || (tt <= pvfontest && pvfontest < t) || (tt <= psdontest && psdontest < t)) rr = 0L; else rr = t - tt; if (oflag) test_annot = annot; while (getann(1, &annot) == 0) { if (isqrs(annot.anntyp) || Oflag) { tprime = annot.time; aprime = amap(annot.anntyp); return; } if (annot.anntyp == NOISE) { if ((annot.subtyp & 0x30) == 0x30) { psdontest = sdontest; psdofftest = sdofftest; sdontest = annot.time; if (getann(1, &annot) < 0) { tprime = huge_time; aprime = '*'; if (end_time > 0L) shut_down += end_time - sdontest; else { (void)fprintf(stderr, "%s: unterminated shutdown starting at %s in record %s, annotator %s\n", pname, timstr(sdontest), record, an[1].name); (void)fprintf(stderr, " (not included in shutdown duration measurement)\n"); } return; } if (annot.anntyp == NOISE && (annot.subtyp & 0x30) != 0x30) sdofftest = annot.time; else { if (vfofftest > t) sdontest = vfofftest + match_dt; else sdontest = t + match_dt; sdofftest = annot.time - match_dt; if (sdontest > sdofftest) sdontest = sdofftest; (void)ungetann(0, &annot); } /* update shutdown duration tally */ shut_down += sdofftest - sdontest; } } else if (annot.anntyp == VFON) { pvfontest = vfontest; pvfofftest = vfofftest; vfontest = annot.time; do { if (getann(1, &annot) < 0) { tprime = huge_time; aprime = '*'; return; } } while (annot.anntyp != VFOFF); vfofftest = annot.time; } } tprime = huge_time; aprime = '*'; }
void getref() /* get next reference beat annotation */ { static long TT; /* time of previous reference beat annotation */ static struct WFDB_ann annot; TT = T; T = Tprime; A = Aprime; /* T-TT is not a valid RR interval if T is the time of the first beat, if TT is the time of the last beat, or if a period of VF or shutdown occurs between TT and T. */ if (TT == 0L || T == huge_time || (TT <= vfonref && vfonref < T) || (TT <= sdonref && sdonref < T) || (TT <= pvfonref && pvfonref < T) || (TT <= psdonref && psdonref < T)) RR = 0L; else RR = T - TT; if (oflag) ref_annot = annot; /* Read reference annotations until a beat annotation is read, or EOF. If an expanded output annotation file is required, all annotations are treated as if they were beat annotations. */ while (getann(0, &annot) == 0) { if (isqrs(annot.anntyp) || Oflag) { /* beat annotation */ Tprime = annot.time; Aprime = amap(annot.anntyp); return; } /* Shutdown occurs when neither signal is readable; the beginning of shutdown is indicated by a NOISE annotation in which bits 4 and 5 of the subtyp field are set, and the end of shutdown is indicated by a NOISE annotation with any value of `subtyp' for which at least one of bits 4 and 5 is zero. In AHA DB reference annotation files, shutdown is indicated by a single shutdown annotation placed roughly in the middle of the shutdown interval; in this case, shutdown is assumed to begin match_dt samples after the previous beat annotation or VFOFF annotation, and is assumed to end match_dt samples before the next annotation. */ else if (annot.anntyp == NOISE) { if ((annot.subtyp & 0x30) == 0x30) { psdonref = sdonref; psdoffref = sdoffref; sdonref = annot.time; /* Read next annotation, which should mark end of shutdown. */ if (getann(0, &annot) < 0) { /* EOF before end of shutdown */ Tprime = sdoffref = huge_time; Aprime = '*'; return; } if (annot.anntyp == NOISE && (annot.subtyp & 0x30) != 0x30) sdoffref = annot.time; else { if (vfoffref > T) sdonref = vfoffref + match_dt; else sdonref = T + match_dt; sdoffref = annot.time - match_dt; if (sdonref > sdoffref) sdonref = sdoffref; (void)ungetann(0, &annot); } } } /* The beginning of ventricular fibrillation is indicated by a VFON annotation, and its end by a VFOFF annotation; any annotations between VFON and VFOFF are read and ignored. */ else if (annot.anntyp == VFON) { pvfonref = vfonref; pvfoffref = vfoffref; vfonref = annot.time; /* Read additional annotations, until end of VF or EOF. */ do { if (getann(0, &annot) < 0) { /* EOF before end of VF */ Tprime = huge_time; Aprime = '*'; return; } } while (annot.anntyp != VFOFF); vfoffref = annot.time; } } /* When this statement is reached, there are no more annotations in the reference annotation file. */ Tprime = huge_time; Aprime = '*'; }
int rtorrent(char *torrent){ int ret; ret = readtorr(torrent); if (ret < 0) { printf("%s:%d wrong:",__FILE__,__LINE__); return -1; } ret = getann(); if (ret < 0) { printf("%s:%d wrong:",__FILE__,__LINE__); return -1; } ret = ismulti(); if (ret < 0) { printf("%s:%d wrong:",__FILE__,__LINE__); return -1; } ret = getpilen(); if (ret < 0) { printf("%s:%d wrong:",__FILE__,__LINE__); return -1; } ret = getpihash(); if (ret < 0) { printf("%s:%d wrong:",__FILE__,__LINE__); return -1; } ret = getfname(); if (ret < 0) { printf("%s:%d wrong:",__FILE__,__LINE__); return -1; } ret = getflap(); if (ret < 0){ printf("%s:%d wrong:",__FILE__,__LINE__); return -1; } ret = getflen(); if (ret < 0){ printf("%s:%d wrong:",__FILE__,__LINE__); return -1; } ret = getinhash(); if (ret < 0){ printf("%s:%d wrong:",__FILE__,__LINE__); return -1; } ret = getpeid(); if (ret < 0){ printf("%s:%d wrong:",__FILE__,__LINE__); return -1; } return 0; }