/* Before using wfdbinit_, use setanninfo_ and setsiginfo_ to set the contents of the annotation and signal information structures. */ INTEGER wfdbinit_(char *record, INTEGER *nann, INTEGER *nsig) { return (wfdbinit(fcstring(record), ainfo, (unsigned int)(*nann), sinfo, (unsigned int)(*nsig))); }
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; }
int main(int argc, char **argv) { char *record = NULL; /* input record name */ float sps; /* sampling frequency, in Hz (SR) */ float samplingInterval; /* sampling interval, in milliseconds */ int i, max, min, minutes = 0, onset, timer, vflag = 0; int dflag = 0; /* if non-zero, dump raw and filtered samples only; do not run detector */ int Rflag = 0; /* if non-zero, resample at 125 Hz */ int EyeClosing; /* eye-closing period, related to SR */ int ExpectPeriod; /* if no ABP pulse is detected over this period, the threshold is automatically reduced to a minimum value; the threshold is restored upon a detection */ int Ta, T0; /* high and low detection thresholds */ WFDB_Anninfo a; WFDB_Annotation annot; WFDB_Siginfo *s; WFDB_Time from = 0L, next_minute, spm, t, tpq, to = 0L, tt, t1; char *p, *prog_name(); static int gvmode = 0; void help(); pname = prog_name(argv[0]); for (i = 1; i < argc; i++) { if (*argv[i] == '-') switch (*(argv[i]+1)) { case 'd': /* dump filter data */ dflag = 1; break; 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': /* operate in WFDB_HIGHRES mode */ gvmode = WFDB_HIGHRES; break; case 'm': /* threshold */ if (++i >= argc || (Tm = atoi(argv[i])) <= 0) { (void)fprintf(stderr, "%s: threshold ( > 0) must follow -m\n", pname); exit(1); } break; case 'r': /* record name */ if (++i >= argc) { (void)fprintf(stderr, "%s: input record name must follow -r\n", pname); exit(1); } record = argv[i]; break; case 'R': /* resample */ Rflag = 1; break; case 's': /* signal */ if (++i >= argc) { (void)fprintf(stderr, "%s: signal number or name must follow -s\n", pname); exit(1); } sig = i; /* remember argument until record is open */ 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 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); } if (gvmode == 0 && (p = getenv("WFDBGVMODE"))) gvmode = atoi(p); setgvmode(gvmode|WFDB_GVPAD); if ((nsig = isigopen(record, NULL, 0)) < 1) exit(2); if ((s = (WFDB_Siginfo *)malloc(nsig * sizeof(WFDB_Siginfo))) == NULL) { (void)fprintf(stderr, "%s: insufficient memory\n", pname); exit(2); } a.name = "wabp"; a.stat = WFDB_WRITE; if ((nsig = wfdbinit(record, &a, 1, s, nsig)) < 1) exit(2); if (sig >= 0) sig = findsig(argv[sig]); if (sig < 0 || sig >= nsig) { /* Identify the lowest-numbered ABP, ART, or BP signal */ for (i = 0; i < nsig; i++) if (strcmp(trim_whitespace(s[i].desc), "ABP") == 0 || strcmp(s[i].desc, "ART") == 0 || strcmp(s[i].desc, "BP") == 0) break; if (i == nsig) { fprintf(stderr, "%s: no ABP signal specified; use -s option\n\n", pname); help(); exit(3); } sig = i; } if (vflag) fprintf(stderr, "%s: analyzing signal %d (%s)\n", pname, sig, s[sig].desc); sps = sampfreq((char *)NULL); if (Rflag) setifreq(sps = 125.); if (from > 0L) { if ((from = strtim(argv[from])) < 0L) from = -from; } if (to > 0L) { if ((to = strtim(argv[to])) < 0L) to = -to; } annot.subtyp = annot.num = 0; annot.chan = sig; annot.aux = NULL; Tm = physadu((unsigned)sig, Tm); samplingInterval = 1000.0/sps; spm = 60 * sps; next_minute = from + spm; EyeClosing = sps * EYE_CLS; /* set eye-closing period */ ExpectPeriod = sps * NDP; /* maximum expected RR interval */ SLPwindow = sps * SLPW; /* slope window size */ if (vflag) { printf("\n------------------------------------------------------\n"); printf("Record Name: %s\n", record); printf("Total Signals: %d (", nsig); for (i = 0; i < nsig - 1; i++) printf("%d, ", i); printf("%d)\n", nsig - 1); printf("Sampling Frequency: %.1f Hz\n", sps); printf("Sampling Interval: %.3f ms\n", samplingInterval); printf("Signal channel used for detection: %d\n", sig); printf("Eye-closing period: %d samples (%.0f ms)\n", EyeClosing, EyeClosing*samplingInterval); printf("Minimum threshold: %d\n", Tm); printf("\n------------------------------------------------------\n\n"); printf("Processing:\n"); } (void)sample(sig, 0L); if (dflag) { for (t = from; (to == 0L || t < to) && sample_valid(); t++) printf("%6d\t%6d\n", sample(sig, t), slpsamp(t)); exit(0); } /* Average the first 8 seconds of the slope samples to determine the initial thresholds Ta and T0 */ t1 = from + strtim("8"); for (T0 = 0, t = from; t < t1 && sample_valid(); t++) T0 += slpsamp(t); T0 /= t1 - from; Ta = 3 * T0; /* Main loop */ for (t = from; (to == 0L || t < to) && sample_valid(); t++) { static int learning = 1, T1; if (learning) { if (t > from + LPERIOD) { learning = 0; T1 = T0; t = from; /* start over */ } else T1 = 2*T0; } if (slpsamp(t) > T1) { /* found a possible ABP pulse near t */ timer = 0; /* used for counting the time after previous ABP pulse */ max = min = slpsamp(t); for (tt = t+1; tt < t + EyeClosing/2; tt++) if (slpsamp(tt) > max) max = slpsamp(tt); for (tt = t-1; tt > t - EyeClosing/2; tt--) if (slpsamp(tt) < min) min = slpsamp(tt); if (max > min+10) { onset = max/100 + 2; tpq = t - 5; for (tt = t; tt > t - EyeClosing/2; tt--) { if (slpsamp(tt) - slpsamp(tt-1) < onset) { tpq = tt; break; } } if (!learning) { /* Check that we haven't reached the end of the record. */ (void)sample(sig, tpq); if (sample_valid() == 0) break; /* Record an annotation at the ABP pulse onset */ annot.time = tpq; annot.anntyp = NORMAL; if (putann(0, &annot) < 0) { /* write the annotation */ wfdbquit(); /* close files if an error occurred */ exit(1); } } /* Adjust thresholds */ Ta += (max - Ta)/10; T1 = Ta / 3; /* Lock out further detections during the eye-closing period */ t += EyeClosing; } } else if (!learning) { /* Once past the learning period, decrease threshold if no pulse was detected recently. */ if (++timer > ExpectPeriod && Ta > Tm) { Ta--; T1 = Ta / 3; } } /* Keep track of progress by printing a dot for each minute analyzed */ if (t >= next_minute) { next_minute += spm; (void)fprintf(stderr, "."); (void)fflush(stderr); if (++minutes >= 60) { (void)fprintf(stderr, "\n"); minutes = 0; } } } (void)free(lbuf); (void)free(ebuf); wfdbquit(); /* close WFDB files */ fprintf(stderr, "\n"); if (vflag) { printf("\n\nDone! \n\nResulting annotation file: %s.wabp\n\n\n", record); } exit(0); }