コード例 #1
0
ファイル: wfdbf.c プロジェクト: cardionetics/wfdb
INTEGER physadu_(INTEGER *signal, DOUBLE_PRECISION *v)
{
    return (physadu((WFDB_Signal)(*signal), *v));
}
コード例 #2
0
ファイル: wabp.c プロジェクト: DanielEColi/wfdb
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);
}