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
:
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?