next up previous contents
Next: More tools in WFDB Up: PhysioNet, PhysioBank, PhysioToolkit Previous: WFDB: `rdsamp'   Contents

WFDB: `rdann'

WFBD relates signals to annotations on signals. If we are using ECG signals, possibly we are not interested in the form of the complex but in the detection of modifications in frequency or in the comparison of different algorithms designed to the detection of QRS. These files are stored with different extensions. In the considered database the beat and rhythm are annotated with the extension .atr

Let's begin with an example (we assume the same conditions than in the previous chapter)


-->unix_x('rdann -r 100s -a atr')
And we get the result:


    0:00.050       18     +    0    0    0	(N
    0:00.213       77     N    0    0    0
    0:01.027      370     N    0    0    0
    0:01.838      662     N    0    0    0
    0:02.627      946     N    0    0    0
    0:03.419     1231  ...
This complex output represents a beat by line. The first column indicates the time at which the beat happens and the second one the sample at which the beat has been detected. The third column is a mnemonic for the type of annotation (`N' means `normal': a normal beat). Our first task is to extract the second column as a vector of integer values. Since the output mixes characters and values, `fscanfMat' can not be used. Scilab has a lot of possibilities to read files in different ways but we are going to use a simple solution. We create a string matrix, then we extract columns 13 to 21 that correspond to the values in which we are interested:

-->str1 = unix_g('rdann -r 100s -a atr');
 
-->beats = evstr(part(str1,13:21));      
 
-->beats(1:10)                           
 ans  =
 
!   18.   !
!   77.   !
!   370.  !
!   662.  !
!   946.  !
!   1231. !
!   1515. !
!   1809. !
!   2044. !
!   2402. !
We get the same result but we can use this information in many different ways: we can try to calculate the heart rate, etc.

Now we are interested in the other possibilities of `rdann'. If we type


-->unix('rdann')
 ans  =
 
    256.
we get in the terminal where we initiated Scilab:

usage: rdann -r RECORD -a ANNOTATOR [OPTIONS ...]
where RECORD and ANNOTATOR specify the input, and OPTIONS may include:
 -c CHAN             print annotations with specified CHAN only
 -f TIME             start at specified TIME
 -h                  print this usage summary
 -n NUM              print annotations with specified NUM only
 -p TYPE [TYPE ...]  print annotations of specified TYPEs only
 -s SUBTYPE          print annotations with specified SUBTYPE only
 -t TIME             stop at specified TIME
 -x                  use alternate time format (seconds, minutes, hours)
Some of them are options analogous to those used by `rdsamp'. The option `-p' is a very powerful option that allows filtering the annotation. Imagine that we have a long record such as `100.dat' and we want to see whether there is any Premature Ventricular Contraction (they are marked as `V'). We type

-->str1 = unix_g('rdann -r 100 -a atr -p V')
 str1  =
 
    25:18.866   546792     V    1    0    0
So our recording has a Premature Ventricular Contraction. It is a challenge to find the beat by combining the knowledge acquired in the previous chapter with the knowledge of the present one. We try the next code


-->stacksize(20000000)                         // increases storing
 
-->unix('rdsamp -r 100 -p -s 0 > dummy');      // transforms file
 
-->signal = fscanfMat('dummy');                // reads data
 
-->str1 = unix_g('rdann -r 100 -a atr -p V');  // reads annotation
 
-->ndx = evstr(part(str1,13:21));              // extracts index
 
-->wind = ndx-500:ndx+500;                     // prepares window
 
-->plot2d(signal(wind,1),signal(wind,2))       // plots window
And the result is shown in the figure  [*]:

Figure: Plotting of the Ventricular Contraction in `100.dat'
\begin{figure}
\begin{center}
\epsfbox{figures/rdann1.eps}
\end{center}
\end{figure}

Isn't it nice?

Notice that time is properly plotted because we have maintained the original values generated by `rdsamp' with the option `-p' and we have not introduced the sampling period by hand.

Finally we are going to consider a very interesting issue on `rdsamp' and `rdann': it is not strictly necessary to download the various data files, since the WFDB applications include HTTP client code so that they can read the data directly from PhysioNet if there is no local copy available. To do this, just prefix the directory name for the database to the record name, as in these examples (we need to be connected to internet):


-->unix_x('rdann -r mitdb/200 -a atr')
In a new window appears the next result (even although we have not any file called `200' in the directory):


    0:00.186       67     +    0    0    0	(B
    0:00.625      225     V    1    0    0
    0:01.352      487     N    0    0    0
    0:01.913      689     V    1    0    0
    0:02.677      964     N    0    0    0
    0:03.186     1147     V    1    0    0
    0:03.980     1433     N    0    0    0
    0:04.472...
If the input files are not found by starting in the current directory, the WFDB applications look for them on PhysioNet. The result is that we can access to files that are not physically present in our hard disk.

PhysioBank includes larger records (on the order of hundreds of megabytes each), and to explore these it may be convenient to use the HTTP client capabilities of the WFDB applications.

Sounds like magic, doesn't it?


next up previous contents
Next: More tools in WFDB Up: PhysioNet, PhysioBank, PhysioToolkit Previous: WFDB: `rdsamp'   Contents
j 2001-09-16