コード例 #1
0
ファイル: TestWfdb.c プロジェクト: lizhihuan/CExercise
int main(void) {
	puts("TestWfdb works");

	WFDB_Anninfo ar;
	ar.name = "atr";
	ar.stat = WFDB_READ;

	annopen("D:\\我的公司\\data\\100",&ar,0);
}
コード例 #2
0
ファイル: wfdbinit.c プロジェクト: TheChetan/ECGCS
FINT wfdbinit(char *record, WFDB_Anninfo *aiarray, unsigned int nann,
	      WFDB_Siginfo *siarray, unsigned int nsig)
{
    int stat;

    if ((stat = annopen(record, aiarray, nann)) == 0)
	stat = isigopen(record, siarray, (int)nsig);
    return (stat);
}
コード例 #3
0
ファイル: lightwave.c プロジェクト: bemoody/lightwave
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);
}
コード例 #4
0
ファイル: ahaecg2mit.c プロジェクト: TheChetan/ECGCS
void process(char *record, FILE *ifile)
{
    char ofname[10], data[5];
    WFDB_Time t = -1;
    static WFDB_Siginfo si[2];
    static WFDB_Anninfo ai;
    static WFDB_Sample v[2];
    static WFDB_Annotation a;

    setsampfreq(250.0);	/* AHA DB is sampled at 250 Hz for each signal */
    sprintf(ofname, "%s.dat", record);
    si[0].fname = ofname;
    si[0].desc = "ECG0";
    si[0].units = "mV";
    si[0].gain = 400;
    si[0].fmt = 212;
    si[0].adcres = 12;
    si[1] = si[0];
    si[1].desc = "ECG1";
    ai.name = "atr";
    ai.stat = WFDB_WRITE;
    if (osigfopen(si, 2) != 2 || annopen(record, &ai, 1) < 0) {
	wfdbquit();
	return;
    }
    while (fread(data, 1, 5, ifile) == 5) {
	v[0] = (data[0] & 0xff) | ((data[1] << 8) & 0xff00);
	v[1] = (data[2] & 0xff) | ((data[3] << 8) & 0xff00);
	(void)putvec(v);
	if (data[4] != '.') {
	    a.anntyp = ammap(data[4]);
	    a.subtyp = (data[4] == 'U' ? -1 : 0);
	    a.time = t;
	    (void)putann(0, &a);
	}
	t++;
    }
    (void)newheader(record);
    wfdbquit();
    fprintf(stderr, "wrote %s.atr, $s.dat, and %s.hea\n", record,record,record);
    return;
}
コード例 #5
0
ファイル: bxbep.c プロジェクト: TheChetan/ECGCS
void NewInit(void)
	{
	char testAnnName[20], rec ;

	// Initialize counts.
	Nn = Ns = Nv = Nf = Nq = No = Nx = 0 ;
	Sn = Ss = Sv = Sf = Sq = So = Sx =  0 ;
	Vn = Vs = Vv = Vf = Vq = Vo = Vx =  0 ;
	Fn = Fs = Fv = Ff = Fq = Fo = Fx =  0 ;
	Qn = Qs = Qv = Qf = Qq = Qo = Qx =  0 ;
	On = Os = Ov = Of = Oq =  0 ;
	Xn = Xs = Xv = Xf = Xq = 0 ;

	T = Tprime = 0 ;
	t = tprime = 0 ;


	setwfdb(ECG_DB_PATH) ;

 //	printf("Enter record: ") ;
 //	gets(record) ;

	sampfreq(record) ;
	an[0].name = "atruth" ;
	an[1].name = "atest" ;
	an[0].stat = an[1].stat = WFDB_READ ;
	if(annopen(record,an,2) < 0)
		{
		printf("Couldn't open annotation files.\n") ;
		exit(0) ;
		}

	fflag = 3 ;

	ofname = "testrpt.txt" ;	// Name of file for report.
	match_dt = (int) strtim(".15") ;
	start = strtim("5:0") ;
	end_time = -1L ;
	shut_down = (int) strtim(".5") ;
	}
コード例 #6
0
ファイル: example1.c プロジェクト: DanielEColi/wfdb
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();
}
コード例 #7
0
ファイル: gqfuse.c プロジェクト: KrisKelner/wfdb-java
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);
}
コード例 #8
0
ファイル: bxbep.c プロジェクト: TheChetan/ECGCS
/* Read and interpret command-line arguments. */
void init(int argc, char *argv[])
{
	 int i;
	 void help();

	 pname = prog_name(argv[0]);
	 for (i = 1; i < argc; i++) {
	if (*argv[i] == '-') switch (*(argv[i]+1)) {
	  case 'a':	/* annotator names follow */
		 if (++i >= argc-1) {
		(void)fprintf(stderr,
			  "%s: reference and test annotator names must follow -a\n",
				 pname);
		exit(0);
	    }
	    an[0].name = argv[i];
	    an[1].name = argv[++i];
	    break;
	  case 'c':	/* condensed output */
	    if (++i >= argc) {
		(void)fprintf(stderr, "%s: output file name must follow -c\n",
			pname);
		exit(0);
	    }
	    ofname = argv[i];
	    fflag = 1;
	    break;
	  case 'C':	/* condensed output with SVEB statistics */
	    if (++i >= argc) {
		(void)fprintf(stderr, "%s: output file name must follow -C\n",
			pname);
		exit(0);
	    }
	    ofname = argv[i];
	    fflag = 4;
	    break;
	  case 'f':	/* start time follows */
	    if (++i >= argc) {
		(void)fprintf(stderr,"%s: start time must follow -f\n", pname);
		exit(0);
	    }
	    start = i;	/* save arg index, convert to samples later, when
			   record has been opened and sampling frequency is
			   known */
	    break;
	  case 'h':	/* print usage summary */
	    help();
	    exit(0);
	    break;
	  case 'l':	/* line-format output */
	    if (++i >= argc-1) {
		(void)fprintf(stderr,
			      "%s: two output file names must follow -l\n",
			pname);
		exit(0);
	    }
	    ofname = argv[i];
	    sfname = argv[++i];
	    fflag = 2;
	    break;
	  case 'L':	/* line-format output, with SVEB statistics */
	    if (++i >= argc-1) {
		(void)fprintf(stderr,
			      "%s: two output file names must follow -L\n",
			pname);
		exit(0);
	    }
	    ofname = argv[i];
	    sfname = argv[++i];
	    fflag = 5;
	    break;
	  case 'o':	/* generate output annotation file */
	    oflag = 1;
	    break;
	  case 'O':	/* generate expanded output annotation file */
	    oflag = 1;
	    Oflag = 1;
	    fflag = 0;
	    break;
	  case 'r':	/* record name follows */
	    if (++i >= argc) {
		(void)fprintf(stderr,
			      "%s: record name must follow -r\n", pname);
		exit(0);
	    }
	 //	 record = argv[i];
	    break;
	  case 's':	/* standard-format output */
	    if (++i >= argc) {
		(void)fprintf(stderr, "%s: output file name must follow -s\n",
			pname);
		exit(0);
	    }
	    ofname = argv[i];
	    fflag = 3;
	    break;
	  case 'S':	/* standard-format output, with SVEB statistics */
	    if (++i >= argc) {
		(void)fprintf(stderr, "%s: output file name must follow -S\n",
			pname);
		exit(0);
	    }
	    ofname = argv[i];
	    fflag = 6;
	    break;
	  case 't':	/* end time follows */
	    if (++i >= argc) {
		(void)fprintf(stderr, "%s: end time must follow -t\n", pname);
		exit(0);
	    }
	    end_time = i;
	    break;
	  case 'v':	/* verbose mode */
	    verbose = 1;
	    break;
	  case 'w':	/* match window follows */
	    if (++i >= argc) {
		(void)fprintf(stderr,
			      "%s: match window must follow -w\n", pname);
		exit(0);
	    }
	    match_dt = i;
	    break;
	  default:
	    (void)fprintf(stderr,
			  "%s: unrecognized option %s\n", pname, argv[i]);
	    exit(0);
	}
	else {
	    (void)fprintf(stderr,
			  "%s: unrecognized argument %s\n",pname,argv[i]);
		 exit(0);
	}
    }

    if (!record || !an[0].name) {
	help();
	exit(0);
    }

    if (start != 0L || end_time != 0L || match_dt != 0)
	(void)fprintf(stderr,"%s: (warning) nonstandard comparison selected\n",
		pname);

	 if (sampfreq(record) <= 0) {
	(void)fprintf(stderr,
		      "%s: (warning) %g Hz sampling frequency assumed\n",
		pname, WFDB_DEFFREQ);
	(void)setsampfreq(WFDB_DEFFREQ);
    }

    /* Set the match window and the times of the start and end of the test
       period.  Initialize the shutdown tally to 1/2 second so that it will be
       properly rounded to the nearest second at the end. */
    if (match_dt)
	match_dt = (int)strtim(argv[match_dt]);
    else
	match_dt = (int)strtim(".15");		/* 150 milliseconds */
    if (start)
	start = strtim(argv[(int)start]);
    else
	start = strtim("5:0");			/* 5 minutes */
	 if (end_time)
	end_time = strtim(argv[(int)end_time]);
    else if ((end_time = strtim("e")) == 0L)
	end_time = -1L;		/* record length unavailable -- go to end of
				   reference annotation file */
	 if (end_time > 0L && end_time < start) {
	(void)fprintf(stderr, "%s: improper interval specified\n", pname);
	exit(0);
    }
    shut_down = strtim(".5");	/* 1/2 second */

	 an[0].stat = an[1].stat = WFDB_READ;
    if (oflag) {
	an[2].name = "bxb";
	an[2].stat = WFDB_WRITE;
    }
    if (annopen(record, an, 2 + oflag) < 0) exit(0);
}
コード例 #9
0
ファイル: wqrs.c プロジェクト: bemoody/wfdb
main(int argc, char **argv)
{ 
    char *p;
    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 jflag = 0;		     /* if non-zero, annotate J-points */
    int Rflag = 0;		     /* if non-zero, resample at 120 or 150 Hz
				      */
    int EyeClosing;                  /* eye-closing period, related to SR */
    int ExpectPeriod;                /* if no QRS is detected over this period,
					the threshold is automatically reduced
					to a minimum value;  the threshold is
					restored upon a detection */
    double Ta, T0;		     /* high and low detection thresholds */
    WFDB_Anninfo a;
    WFDB_Annotation annot;
    WFDB_Gain gain;
    WFDB_Siginfo *s;
    WFDB_Time from = 0L, next_minute, spm, t, tj, tpq, to = 0L, tt, t1;
    static int gvmode = WFDB_GVPAD | WFDB_LOWRES;
    char *prog_name();
    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_GVPAD | WFDB_HIGHRES;
	    break;
	  case 'j':	/* annotate J-points (ends of QRS complexes) */
	    jflag = 1;
	    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 'p':	/* specify power line (mains) frequency */
	    if (++i >= argc || (PWFreq = atoi(argv[i])) <= 0) {
		(void)fprintf(stderr,
			    "%s: power line frequency ( > 0) must follow -p\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 the argument until the 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);
    }
    if ((nsig = isigopen(record, s, nsig)) < 1) exit(2);
    sps = sampfreq((char *)NULL);
    if (sps < PWFreq) {
	(void)fprintf(stderr, "%s: sampling frequency (%g Hz) is too low%s",
		      pname, sps,
		      (gvmode & WFDB_HIGHRES) ? "\n" : ", try -H option\n");
	exit(3);
    }
    if (gvmode & WFDB_HIGHRES)
	setafreq(sampfreq((char *)NULL));
    a.name = "wqrs"; a.stat = WFDB_WRITE;
    if (annopen(record, &a, 1) < 0) exit(2);
    if (sig >= 0) sig = findsig(argv[sig]);
    if (sig < 0 || sig >= nsig) sig = 0;
    if ((gain = s[sig].gain) == 0.0) gain = WFDB_DEFGAIN;
    if (Rflag) {
    	if (PWFreq == 60.0) setifreq(sps = 120.);
    	else setifreq(sps = 150.);
    }
    if (from > 0L) {
	if ((from = strtim(argv[from])) < 0L)
	from = -from;
    }
    if (to > 0L) {
	if ((to = strtim(argv[to])) < 0L)
	    to = -to;
    }
    else
	to = strtim("e");

    annot.subtyp = annot.num = 0;
    annot.chan = sig;
    annot.aux = NULL;
    Tm = muvadu((unsigned)sig, Tm);
    samplingInterval = 1000.0/sps;
    lfsc = 1.25*gain*gain/sps;	/* length function scale constant */
    spm = 60 * sps;
    next_minute = from + spm;
    LPn = sps/PWFreq; 		/* The LP filter will have a notch at the
				    power line (mains) frequency */
    if (LPn > 8)  LPn = 8;	/* avoid filtering too agressively */
    LP2n = 2 * LPn;
    EyeClosing = sps * EYE_CLS; /* set eye-closing period */
    ExpectPeriod = sps * NDP;	/* maximum expected RR interval */
    LTwindow = sps * MaxQRSw;   /* length transform window size */

    (void)sample(sig, 0L);
    if (dflag) {
	for (t = from; t < to || (to == 0L && sample_valid()); t++)
	    printf("%6d\t%6d\n", sample(sig, t), ltsamp(t));
	exit(0);
    }

    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 A/D units (%d microvolts)\n",
	       Tm, adumuv(sig, Tm));
	printf("Power line frequency:    %d Hz\n", PWFreq);
	printf("\n------------------------------------------------------\n\n");
	printf("Processing:\n");
    }

    /* Average the first 8 seconds of the length-transformed samples
       to determine the initial thresholds Ta and T0. The number of samples
       in the average is limited to half of the ltsamp buffer if the sampling
       frequency exceeds about 2 KHz. */
    if ((t1 = strtim("8")) > BUFLN*0.9)
	t1 = BUFLN/2;
    t1 += from;
    for (T0 = 0, t = from; t < t1 && sample_valid(); t++)
	T0 += ltsamp(t);
    T0 /= t1 - from;
    Ta = 3 * T0;

    /* Main loop */
    for (t = from; t < to || (to == 0L && sample_valid()); t++) {
	static int learning = 1, T1;
	
	if (learning) {
	    if (t > t1) {
		learning = 0;
		T1 = T0;
		t = from;	/* start over */
	    }
	    else
		T1 = 2*T0;
	}
	
	/* Compare a length-transformed sample against T1. */
	if (ltsamp(t) > T1) {	/* found a possible QRS near t */
	    timer = 0; /* used for counting the time after previous QRS */
	    max = min = ltsamp(t);
	    for (tt = t+1; tt < t + EyeClosing/2; tt++)
		if (ltsamp(tt) > max) max = ltsamp(tt);
	    for (tt = t-1; tt > t - EyeClosing/2; tt--)
		if (ltsamp(tt) < min) min = ltsamp(tt);
	    if (max > min+10) { /* There is a QRS near tt */
		/* Find the QRS onset (PQ junction) */
		onset = max/100 + 2;
		tpq = t - 5;
		for (tt = t; tt > t - EyeClosing/2; tt--) {
		    if (ltsamp(tt)   - ltsamp(tt-1) < onset &&
			ltsamp(tt-1) - ltsamp(tt-2) < onset &&
			ltsamp(tt-2) - ltsamp(tt-3) < onset &&
			ltsamp(tt-3) - ltsamp(tt-4) < onset) {
			tpq = tt - LP2n;	/* account for phase shift */
			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 QRS onset */
		    annot.time = tpq;
		    annot.anntyp = NORMAL;
		    if (putann(0, &annot) < 0) { /* write the annotation */
			wfdbquit();	/* close files if an error occurred */
			exit(1);
		    }
		    if (jflag) {
			/* Find the end of the QRS */
			for (tt = t, tj = t + 5; tt < t + EyeClosing/2; tt++) {
			    if (ltsamp(tt) > max - (max/10)) {
				tj = tt;
				break;
			    }
			}
			(void)sample(sig, tj);
			if (sample_valid() == 0) break;
			/* Record an annotation at the J-point */
			annot.time = tj;
			annot.anntyp = JPT;
			if (putann(0, &annot) < 0) {
			    wfdbquit();
			    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 QRS
	       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, " %s\n", timstr(t));
		minutes = 0;
	    }
	}
    }
    if (minutes) (void)fprintf(stderr, " %s\n", timstr(t));

    (void)free(lbuf);
    (void)free(ebuf);
    wfdbquit();		        /* close WFDB files */
    fprintf(stderr, "\n");
    if (vflag) {
	printf("\n\nDone! \n\nResulting annotation file:  %s.wqrs\n\n\n",
	       record);
    }
    exit(0);
}
コード例 #10
0
ファイル: wfdbf.c プロジェクト: cardionetics/wfdb
/* Before using annopen_, set up the annotation information structures using
   setanninfo_. */
INTEGER annopen_(char *record, INTEGER *nann)
{
    return (annopen(fcstring(record), ainfo, (unsigned int)(*nann)));
}
コード例 #11
0
ファイル: easytest.c プロジェクト: TheChetan/ECGCS
MAINTYPE main()
	{
	char record[10], fname[20] ;
	int i, ecg[2], delay, recNum ;
	WFDB_Siginfo s[2] ;
	WFDB_Anninfo a[2] ;
	WFDB_Annotation annot ;

	unsigned char byte ;
	FILE *newAnn0, *newAnn1 ;
	long SampleCount = 0, lTemp, DetectionTime ;
	int beatType, beatMatch ;

	// Set up path to database directory

	setwfdb(ECG_DB_PATH) ;

	// Analyze all 48 MIT/BIH Records.

	for(recNum = 0; recNum < REC_COUNT; ++recNum)
		{
		sprintf(record,"%d",Records[recNum]) ;
		printf("Record %d\n",Records[recNum]) ;

		// Open a 2 channel record

		if(isigopen(record,s,2) < 1)
			{
			printf("Couldn't open %s\n",record) ;
			return ;
			}

		ADCZero = s[0].adczero ;
		ADCUnit = s[0].gain ;
		InputFileSampleFrequency = sampfreq(record) ;

		// Setup for output annotations

		a[0].name = "atest"; a[0].stat = WFDB_WRITE ;

		if(annopen(record, a, 1) < 0)
			return ;

		// Initialize sampling frequency adjustment.

		NextSample(ecg,2,InputFileSampleFrequency,SAMPLE_RATE,1) ;

		// Initialize beat detection and classification.

		ResetBDAC() ;
		SampleCount = 0 ;

		// Read data from MIT/BIH file until there is none left.

		while(NextSample(ecg,2,InputFileSampleFrequency,SAMPLE_RATE,0) >= 0)
			{
			++SampleCount ;

			// Set baseline to 0 and resolution to 5 mV/lsb (200 units/mV)

			lTemp = ecg[0]-ADCZero ;
			lTemp *= 200 ;			lTemp /= ADCUnit ;			ecg[0] = lTemp ;

			// Pass sample to beat detection and classification.

			delay = BeatDetectAndClassify(ecg[0], &beatType, &beatMatch) ;

			// If a beat was detected, annotate the beat location
			// and type.

			if(delay != 0)
				{
				DetectionTime = SampleCount - delay ;

				// Convert sample count to input file sample
				// rate.

				DetectionTime *= InputFileSampleFrequency ;
				DetectionTime /= SAMPLE_RATE ;
				annot.time = DetectionTime ;
				annot.anntyp = beatType ;
				annot.aux = NULL ;
				putann(0,&annot) ;
				}
			}

		// Reset database after record is done.

		wfdbquit() ;

#if 0
		/* This code is obsolete.  The annotation files are always
		   written into "<record>.ate" in the current directory.
                   They do not need to be copied in order to be read by bxbep,
		   if the WFDB path includes both the current current directory
		   and the one containing the .atr reference annotation files.
                 */

		// Copy "atest.<record>" to "<record>.ate" for future ascess.
		// (This is necessary for PC files)

		sprintf(fname,"%s.ate",record) ;
		newAnn0 = fopen(fname,"rb") ;
		sprintf(fname,"%s%s.ate",ECG_DB_PATH,record) ;
		newAnn1 = fopen(fname,"wb") ;

		// Copy byte image of annotation file in this
		// directory to a correctly named file in the
		// database directory.

		while(fread(&byte,sizeof(char),1,newAnn0) == 1)
			fwrite(&byte,sizeof(char),1,newAnn1) ;

		fclose(newAnn0) ;
		fclose(newAnn1) ;
#endif
		}
	}