[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

Example 1: An Annotation Filter

The following program copies an annotation file, changing all QRS annotations to NORMAL and deleting all non-QRS annotations.

 
 1  #include <stdio.h>
 2  #include <wfdb/wfdb.h>
 3  #include <wfdb/ecgmap.h>
 4
 5  main()
 6  {
 7      WFDB_Anninfo an[2];
 8      char record[8], iann[10], oann[10];
 9      WFDB_Annotation annot;
10
11      printf("Type record name: ");
12      fgets(record, 8, stdin); record[strlen(record)-1] = '\0';
13      printf("Type input annotator name: ");
14      fgets(iann, 10, stdin); iann[strlen(iann)-1] = '\0';
15      printf("Type output annotator name: ");
16      fgets(oann, 10, stdin); oann[strlen(oann)-1] = '\0';
17      an[0].name = iann; an[0].stat = WFDB_READ;
18      an[1].name = oann; an[1].stat = WFDB_WRITE;
19      if (annopen(record, an, 2) < 0) exit(1);
20      while (getann(0, &annot) == 0)
21          if (isqrs(annot.anntyp)) {
22              annot.anntyp = NORMAL;
23              if (putann(0, &annot) < 0) break;
24          }
25      wfdbquit();
26  }

(See http://physionet.org/physiotools/wfdb/examples/example1.c for a copy of this program.)

Notes:

Line 2:

All programs that use the WFDB library must include ‘<wfdb/wfdb.h>’.

Line 3:

The #include statement makes available not only the mapping macros, one of which will be used in line 21, but also the annotation code symbols in ‘<wfdb/ecgcodes.h>’, one of which will be needed in line 22.

Line 7:

Since there will be two annotators (one each for input and output), the array of WFDB_Anninfo objects has two members.

Line 9:

This structure will be filled in by getann, modified, and passed to putann for output.

Lines 11–16:

The record name and the annotator names are filled into the character arrays. The code in lines 12, 14, and 16 illustrates a C idiom for reading a string of limited length; the second statement in each of these lines replaces the trailing newline character (which fgets copies into the string) with a null. String arguments to WFDB library functions should not include newline characters.

Lines 17–18:

Pointers to the character arrays (strings) containing the annotator names are filled into the name fields of the array of WFDB_Anninfo objects. Note that the name fields are only pointers and do not contain storage for the strings themselves. If this is not clear to you, review the discussion of pointers and arrays in K&R, pp. 97–100. The input annotator is to be read, the output annotator is to be written. WFDB_READ and WFDB_WRITE are defined in ‘<wfdb/wfdb.h>’.

Line 19:

Note that the first and second arguments of annopen are the names of the respective arrays; thus annopen receives pointers rather than values in its argument list.

Line 20:

An annotation is read from annotator 0 into annot. The ‘&’ is necessary since getann requires a pointer to the structure in order to be able to modify its contents. When getann returns a negative value, no more annotations remain to be read and the loop ends.

Line 21:

The macro isqrs is defined in ‘<wfdb/ecgmap.h>’; isqrs(x) is true if x is an annotation code that denotes a QRS complex, false if x is not a QRS annotation code.

Line 22:

NORMAL is defined in ‘<wfdb/ecgcodes.h>’.

Line 23:

The call to putann now writes the modified annotation in the output annotator 0 file. As for getann, a pointer to annot must be passed using the ‘&’ operator.

Line 25:

All files are closed prior to exiting. This is mandatory since the program creates an output file with putann.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]

George B. Moody (george@mit.edu)