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

Exercises

These exercises are based on the material in the previous chapters. Answers to some of them are at the back of the book, but try to work through them first.

  1. Type in the first program from the previous chapter, compile it, and run it. If you know that you will need to read WFDB files from non-standard locations, remember to set and export the environment variable WFDB (see section The Database Path and Other Environment Variables). It is a good idea to include this step in your ‘.profile’, ‘.cshrc’, or ‘autoexec.bat’. As input, try record ‘100s’, input annotator ‘atr’, and output annotator ‘normal’. The program should finish in five seconds or less. The annotations will have been written into a file called ‘100s.nor’ in the current directory. Now type “rdann -r 100s -a atr” and observe the output for a few seconds, then try “rdann -r 100s -a nor” and notice the difference.
  2. Modify the program from the previous exercise so that the non-QRS annotations are put into a second output annotation file. Remember that you will need three annotation files in all (one input and two output).
  3. The next five short exercises are to be worked out on paper, although you may wish to check your work on the computer. All of them assume that we are given a signal sampled at 100 Hz with the following specifications:
     
    fname = "signal.dat"
    desc = "BP"
    units = "mmHg"
    gain = 10
    initval = 80
    group = 0
    fmt = 212
    spf = 1
    bsize = 0
    adcres = 12
    adczero = 0
    baseline = -300
    nsamp = 1000000
    cksum = 3109
    

    For starters, convert a sample value of 280 into physical units.

  4. Convert 120 mmHg into adus.
  5. What are the maximum and minimum possible sample values in adu? in mmHg?
  6. How large is ‘signal.dat’, in bytes? How much space could we save if we converted it to format 8 (eight-bit first-differences)? What is the maximum slew rate (in mmHg/second) that we can represent in that format?
  7. Oops! We have just discovered that the maximum slew rate in our signal is 1500 mmHg/sec. Is there any way to store it at full precision in one of the supported formats, that saves space compared to its present format?
  8. Figure out how to plot or display the first 1000 points from signal 0 of a record in amplitude vs. time format. You may wish to begin with the example program from the first chapter. Arrange for the record name to be read from the command line (see K&R, pp. 114–115, if you don’t know how to do this).
  9. Try plotting VCGs by modifying the program from the previous exercise to plot pairs of samples from each of two signals rather than sample number/value pairs.
  10. Modify the program from the previous exercise, or Example 2 from the previous chapter, so that you can specify a segment of the record to be processed with start and end times. For example, the command
     
    your-program record 10:0 10:10
    

    should skip the first ten minutes, then process the next ten seconds of signals from record.

  11. Using isigsettime on a format 8 signal introduces a random offset into the signal, since the contents of a format 8 signal file are first differences rather than amplitudes. For an AC-coupled signal such as an ECG, this is usually inconsequential, but a DC-coupled signal such as a blood pressure signal is usually useful only if absolute levels are known. If we store such a signal in format 8, we must read it sequentially from the beginning in order to get correct sample values. If we intend to do a lot of non-sequential processing of such a signal, it may be worthwhile to build a table containing the correct sample values at periodic intervals; then we can use isigsettime to skip to a sample in the table, and read forward sequentially from that point. Write a program to build such a table, and wrappers for isigsettime and getvec to give random access to format 8 signal files without introducing offset errors. On your system, how many sample intervals should be allowed between table entries in order to obtain an isigsettime equivalent that executes in an average of 100 msec or less?
  12. This exercise and the next assume that you have access to the web, so that you can obtain the freely available input records needed from PhysioNet. Since the 360 Hz sampling frequency used in the MIT-BIH Arrhythmia Database is an integer multiple of the 60 Hz mains frequency, it is quite easy to design a 60 Hz notch filter that can be applied to the database to suppress power-line interference (for example, by averaging pairs of samples that are 180 degrees out of phase). Write a program that filters two input signals and writes out the filtered data using putvec (see section Example 7: A General-Purpose FIR Filter, for a model program). Try it out on MIT DB record ‘122’ (if you have a NETFILES-enabled WFDB library, use the default WFDB path, and open record ‘mitdb/122’; otherwise, download the record from http://physionet.org/physiobank/database/mitdb/.) Use your programs from the previous exercises to display your output and compare it with the original signals.
  13. (Non-trivial) Write a QRS detector that is independent of sampling frequency without using setifreq. Some useful constants (for adult human ECGs): average normal QRS duration = 80 milliseconds, average QRS amplitude = 1 millivolt, average R-R interval = 1 second; assume that upper and lower limits for these quantities are within a factor of 3 of the average values. Run your detector on MIT-BIH Arrhythmia Database record ‘200’. (If you have a NETFILES-enabled WFDB library, use the default WFDB path, and open record ‘mitdb/200’; otherwise, download the record from http://physionet.org/physiobank/database/mitdb/.) Read the documentation on the annotation comparator, ‘bxb’, and figure out how to use it to compare the annotation file produced by your program against the reference annotator ‘atr’. How does your detector compare to Example 10?

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

George B. Moody (george@mit.edu)