\documentclass[twoside]{book}
\usepackage{html}
% Recent LaTeX distributions include html.sty (written for latex2html).
% If yours doesn't, get a copy from CTAN (http://www.ctan.org/), from
% the current latex2html package (also available from CTAN), or from
% the wave/misc subdirectory of the directory where you found this
% file, and put the copy into this directory (or into the directory
% that contains the other .sty files referenced below) before attempting
% to process this file using LaTeX.

\pagenumbering{roman}

\title{WFDB\_tools\\A {\sc Matlab} interface to the WFDB library}
\author{Jonas Carlson}

\begin{document}
\maketitle

\pagestyle{empty}
\vspace*{\fill}
\begin{htmlonly}
\noindent
The most recent versions of the software described here may be
freely downloaded from
\htmladdnormallink{PhysioNet}{http://www.physionet.org/}.
\htmladdnormallink{PostScript}{wfdb_tools.ps} and
\htmladdnormallink{PDF}{wfdb_tools.pdf} versions of this guide are available.
The latest versions can be downloaded from
\htmladdnormallink{MIT}{http://www.physionet.org/}.
\end{htmlonly}
\begin{latexonly}
\noindent
The most recent versions of the software described here may be
freely downloaded from PhysioNet (http://www.physionet.org/).
An HTML version of this guide is available at
http://www.\-physio\-net.\-org/\-physio\-tools/\-matlab/\-wfdb\_tools/.
\end{latexonly}

\newpage
\setcounter{page}{1}
\tableofcontents

\newpage
\pagestyle{plain}
\chapter*{Preface}
\addcontentsline{toc}{chapter}{Preface}

The Waveform Database interface library (the WFDB library) is a package of
C-callable functions that provide clean and uniform access to digitized,
annotated signals stored in a variety of formats. These functions, although
originally designed for use with databases of electrocardiograms, are useful
for dealing with any similar collection of digitized signals, which may or may
not be annotated. The WFDB library has evolved to support the development of
numerous databases that include signals such as blood pressure, respiration,
oxygen saturation, EEG, as well as ECGs. Thus the WFDB library is considerably
more than an ECG database interface.

This guide documents WFDB\_tools, a set of {\sc Matlab} functions that
enables the {\sc Matlab} user to take full advantage of the WFDB library and
explore or create databases containing a wide variety of signals.

The WFDB\_tools functions are not self-contained; rather, they are `wrappers'
for the WFDB library functions (i.e. the WFDB library must be installed for the
{\sc Matlab} functions to work).  The wrappers work much in the same way as the
WFDB library functions, and the effort is to keep them as true to their
counterparts as possible. The usual way to work in {\sc Matlab} is to get all
results from one function, and therefore the wrappers may seem `low-level' in
comparison.  Combining just a few of the wrappers in an m-file, however, would
produce the `high-level' way of working in {\sc Matlab} while keeping the full
control of data handling that can only be obtained from the `low-level' C-like
wrappers.

This guide includes several short tutorial examples that illustrate how to read
and write signals and annotations using these wrappers.  It also
contains descriptions of all the wrapper functions available to the {\sc
Matlab} user.  Note that {\sc Matlab} help files for all
of the wrappers are included in the WFDB\_tools package, so it is always
possible within {\sc Matlab} to use a command such as

\begin{verbatim}
    help WFDB_sampfreq
\end{verbatim}
\noindent
to obtain information about how to use any of these wrappers.

The set of wrappers is nearly complete.  WFDB library functions for which
no wrappers currently exist are wfdbinit, ungetann, sample, sample\_valid,
setannstr, setanndesc, setecgstr, calopen, getcal, putcal, newcal, flushcal,
setmsheader, setwfdb, setibsize, and setobsize.

\chapter{Installing the WFDB\_tools wrappers}
\pagenumbering{arabic}

{\em Important: the WFDB\_tools wrappers have been developed and tested with
{\sc Matlab} R13.}  It is highly unlikely that they can be made to work with an
older version of {\sc Matlab}.  Initial development and testing was under Red
Hat Linux 8.0, using WFDB library version 10.3.2; the wrappers have also been
tested under Red Hat Linux 9.0 and WFDB library version 10.3.11.  More
recently, they have also been tested under MS-Windows XP, also with WFDB
library version 10.3.11.  It may be possible to recompile these wrappers and to
use them with {\sc Matlab} R13 on other platforms such as Mac OS/X or Solaris,
but doing so is currently unsupported.

\section{Preparation}

\begin{htmlonly}
Before installing the WFDB\_tools wrappers, install the
\htmladdnormallink{WFDB Software Package}{/physiotools/wfdb.shtml},
and verify that it is working properly on your system.
\end{htmlonly}
\begin{latexonly}
Before installing the WFDB\_tools wrappers, install the WFDB Software Package
(http://www.\-physio\-net.\-org/\-physio\-tools/\-wfdb.\-shtml), and verify
that it is working properly on your system.
\end{latexonly}

\begin{htmlonly}
Download the
\htmladdnormallink{WFDB\_tools package}{/physiotools/matlab/WFDB\_tools.tar.gz}
and unpack it using a command such as
\end{htmlonly}
\begin{latexonly}
Download the WFDB\_tools package
(http://www.\-physio\-net.\-org/\-physio\-tools/\-matlab/\-WFDB\_tools.\-tar.\-gz)
and unpack it using a command such as
\end{latexonly}
\begin{verbatim}
    tar xfvz WFDB_tools.tar.gz
\end{verbatim}
\noindent
This creates a directory named {\tt WFDB\_tools}, which contains the wrapper
source files ({\tt src/*.c}), help files ({\tt help/*.m}), precompiled binary
files ({\tt linux/*.mexglx}, for x86 GNU/Linux, and {\tt windows/*.dll}, for
MS-Windows), documentation (in {\tt doc/}), and tutorial examples (in {\tt
examples/}).

Follow the instructions given in the {\tt 00README} file (in the top-level
{\tt WFDB\_tools} directory) to install the WFDB\_tools on your system.

All functions have explanatory m-files available through {\sc Matlab}'s {\tt
help} function. In the case of toolbox installation (described below) a list of
all functions is found using {\tt help WFDB\_tools}.

\section{Installing WFDB\_tools in a user directory}
The directory {\tt WFDB\_tools} can be put anywhere. All {\sc Matlab} programs
must then use the command {\tt addpath} to make the directory available (it is
probably not a good idea to put other program files inside the {\tt
WFDB\_tools} directory).

\section{Installing WFDB\_tools as a {\sc Matlab} toolbox}
With sufficient write privileges, it should be possible to install the WFDB
tools as a {\sc Matlab} toolbox. It should then be put in the directory:

    {\tt \it{matlabroot}/toolbox/WFDB\_tools}

\noindent
To make it available to {\sc Matlab}, this directory must be added to {\tt
pathdef.m} (in the {\tt toolbox/local} directory) and, if the toolbox path
cache is enabled, the command {\tt rehash toolboxcache} should be issued when
{\sc Matlab} is started.

\section{The WFDB library and applications}
The
\begin{htmlonly}
\htmladdnormallink{WFDB Programmer's Guide}{/physiotools/wpg/},
\end{htmlonly}
\begin{latexonly}
{\em WFDB Programmer's Guide} (http://www.\-physio\-net.\-org/\-physio\-tools/wpg/),
\end{latexonly}
which documents the C-language WFDB library, is recommended as a source of
additional information and examples.  The
\begin{htmlonly}
\htmladdnormallink{WFDB Applications Guide}{/physiotools/wag/}
\end{htmlonly}
\begin{latexonly}
{\em WFDB Applications Guide} (http://www.\-physio\-net.\-org/\-physio\-tools/\-wag/)
\end{latexonly}
describes many stand-alone programs that use the WFDB library to read and write
digitized signals and annotations.  If the WFDB Software Package has been
correctly installed, you can run these programs from a terminal window or from
within {\sc Matlab} to perform a wide variety of signal processing and analysis
tasks.

\section{Sample, signal, and annotator numbers}

Several WFDB library functions, and most of the stand-alone WFDB applications,
accept arguments that specify a specific sample within a digitized signal (a
{\em sample number}, a specific signal within a set of signals (a {\em signal
number}, or a specific set of annotations (an {\em annotator number}).  The
first sample number in a signal has sample number 0, not 1; similarly, the
first signal has signal number 0, and the first annotator has annotator number
0.  The WFDB\_tools functions use the same zero-based sample, signal, and
annotator numbers as the WFDB library functions that they wrap.  This point is
a possible source of confusion if you become accustomed to thinking of these
numbers as array indices (which, in C, is exactly what they are); it may be
best to think of them simply as identification numbers for the objects with
which they are associated.

\chapter{Using the WFDB\_tools library}

Using simple examples, this chapter illustrates how to use the WFDB\_tools
wrappers to read and write signals and annotations.  Additional information
about the wrappers in these examples, and about the other wrappers in the
library, can be found in the next chapter. 

\section{Reading signals}

Assuming that the WFDB Software Package has been installed correctly, the
record ``100s'' should be available.  Reading the first ten samples of this
record using {\sc Matlab} would be done as:

\begin{verbatim}
    >> S = WFDB_isigopen('100s')
    S = 
    2x1 struct array with fields:
        fname
        desc
        units
        gain
        initval
        group
        fmt
        spf
        bsize
        adcres
        adczero
        baseline
        nsamp
        cksum
    >> DATA = WFDB_getvec(length(S), 10)
    DATA =
             995        1011
             995        1011
             995        1011
             995        1011
             995        1011
             995        1011
             995        1011
             995        1011
            1000        1008
             997        1008
\end{verbatim}

The first command, {\tt S = WFDB\_isigopen('100s')}, reads the header file of
record 100s and returns the information in a structure ({\tt S}, in this
case). The length of {\tt S} equals the number of signals in the data file. The
fields of {\tt S} contain the signal settings. To access, for example, the gain
of signal 0 and the description of signal 1, use the commands:

\begin{verbatim}
    >> S(1).gain
    ans =
       200
    >> S(2).desc
    ans =
    V5
\end{verbatim}
\noindent
(Remember:  the first signal is signal 0, not signal 1!  Its attributes are
found in the first structure, {\tt S(1)}.  This will matter in later examples.)

The second command, {\tt DATA = WFDB\_getvec(length(S), 10)}, reads data from
the previously opened record. The two input parameters are the number of
signals (found as {\tt length(S)}) and the desired number of samples (if
omitted, the whole record is read).

Finally, don't forget

\begin{verbatim}
    >> WFDB_wfdbquit
\end{verbatim}
\noindent
to close all open files.

An elaborated version of this example is provided in the {\tt examples}
directory of the WFDB\_tools package (look for {\tt example1.m}).

\section{Reading annotations}
This example illustrates how to open an annotation file, how to read
annotations from it, and how to translate them into their mnemonic and
description strings.

First, we need to create an `Anninfo' structure containing the annotator name
and mode of the annotation file:

\begin{verbatim}
    >> A = WFDB_Anninfo(1)
    A = 
        name: 'a1'
        stat: 'WFDB_READ'
\end{verbatim}

\noindent
This might seem like a complicated way to go, but it reflects the way the
underlying WFDB library works.  The record 100s has an annotator named {\tt
atr}, so we need to change the {\tt name} field of {\tt A} before issuing the
command to open the file.

\begin{verbatim}
    >> A.name = 'atr'
    A = 
        name: 'atr'
        stat: 'WFDB_READ'
    >> WFDB_annopen('100s', A)
\end{verbatim}

\noindent
Now that the annotation file is open, we may read the first two annotations,
and take a closer look at the second one.

\begin{verbatim}
    >> ANNOTATION = WFDB_getann(0, 2)
    ANNOTATION = 
    2x1 struct array with fields:
        time
        anntyp
        subtyp
        chan
        num
        aux
    >> ANNOTATION(2)
    ans = 
          time: 77
        anntyp: 1
        subtyp: 0
          chan: 0
           num: 0
           aux: ''
\end{verbatim}

\noindent
The first argument of WFDB\_getann is the input annotator number.  Since we are
reading only one annotation file, its annotator number is 0.  (If we had opened
a second annotation file for reading, its annotator number would be 1, etc.)
Next, let's see what the annotation type (the {\tt anntyp} field) means, in
mnemonic and description:

\begin{verbatim}
    >> WFDB_annstr(ANNOTATION(2).anntyp)
    ans =
    N
    >> WFDB_anndesc(ANNOTATION(2).anntyp)
    ans =
    Normal beat
\end{verbatim}

\noindent
Finally,

\begin{verbatim}
    >> WFDB_wfdbquit
\end{verbatim}

An elaborated version of this example is provided in the {\tt examples}
directory of the WFDB\_tools package (look for {\tt example2.m}).

\section{Creating an annotation file}
In this example, we will create an annotation file that annotates the first
two P-waves of record 100s. These are located at (roughly) sample numbers 315
and 610.  First, let's find the annotation code for a P-wave:

\begin{verbatim}
    >> WFDB_strann('p')
    ans =
        24
\end{verbatim}

\noindent
The description is:

\begin{verbatim}
    >> WFDB_anndesc(24)
    ans =
    P-wave peak
\end{verbatim}

\noindent
Create the two annotations:

\begin{verbatim}
    >> ANN = WFDB_Annotation(2)
    ANN = 
    1x2 struct array with fields:
        time
        anntyp
        subtyp
        chan
        num
        aux
    >> ANN(1).time = 315;
    >> ANN(1).anntyp = 24;
    >> ANN(1).aux = 'First P-wave';
    >> ANN(2).time = 610;
    >> ANN(2).anntyp = 24;
    >> ANN(2).aux = 'Second P-wave';
\end{verbatim}

\noindent
Now create an annotator structure:

\begin{verbatim}
    >> A = WFDB_Anninfo(1)
    A = 
        name: 'a1'
        stat: 'WFDB_READ'
    >> A.name = 'p';
    >> A.stat = 'WFDB_WRITE';
\end{verbatim}

\noindent
Create an empty annotation file to hold the annotations:

\begin{verbatim}
    >> WFDB_annopen('100s', A)
\end{verbatim}

\noindent
Write the annotations:

\begin{verbatim}
    >> WFDB_putann(0, ANN)
\end{verbatim}

\noindent
The first argument of WFDB\_putann is the output annotator number.  Since
we are writing only one annotation file, its annotator number is 0.

\noindent
Close all open files:

\begin{verbatim}
    >> WFDB_wfdbquit
\end{verbatim}

\noindent
The new annotation file, {\tt 100s.p}, will be located in {\sc Matlab}'s
current directory.  The result may be verified using WAVE, which
can be called from {\sc Matlab} using:

\begin{verbatim}
    >> !wave -r 100s -a p &
\end{verbatim}

\noindent
(Remember the !-sign to call system functions from {\sc Matlab} and the \&-sign
to run WAVE as a background process;  depending on your setup, using \& may
cause an error, however, and you may need to run WAVE as a foreground process
without the final '\&' in the command.)

An elaborated version of this example is provided in the {\tt examples}
directory of the WFDB\_tools package (look for {\tt example3.m}).

\section{Creating a signal file}
\label{Example:output}
Creating an output signal file is made in three steps: create a signal
information structure, write the output signal data, and create the header
file.

Assume we have data from three signals.  We need to create a signal
information structure using:

\begin{verbatim}
    >> S = WFDB_Siginfo(3)
    S = 
    1x3 struct array with fields:
        fname
        desc
        units
        gain
        initval
        group
        fmt
        spf
        bsize
        adcres
        adczero
        baseline
\end{verbatim}

\noindent
Now these fields need to be filled with appropriate values. All of them have
default values to avoid producing errors, but it is unlikely that they will fit
our signals. For example, if signal 0 is the X-lead of a Frank-lead ECG, we may
want its description to be:

\begin{verbatim}
    >> S(1).desc = 'Frank X';
\end{verbatim}

\noindent
and so on for all other fields.  (Remember: the first signal is signal 0; its
attributes are in {\tt S(1)}.)  When done, we create an empty signal file in
which to write the data, using

\begin{verbatim}
    >> WFDB_osigfopen(S)
\end{verbatim}

\noindent
We also need to supply the sampling frequency, for example 1~kHz:

\begin{verbatim}
    >> WFDB_setsampfreq(1000);
\end{verbatim}

\noindent
and the basetime of the recording (i.e. the time of sample number 0). Assuming the recording was started when my oldest daughter was born:

\begin{verbatim}
    >> WFDB_setbasetime('02:19:00 02/09/1999')
\end{verbatim}
\noindent

\noindent
(Dates used by WFDB\_tools are always in DD/MM/YYYY format; 02/09/1999 is
2 September, not February 9.)

Now we're done with providing signal information and it is time to write the
actual signal data. This must be stored column-wise in a matrix (one signal per
column, one sample per row). If our data is stored in the variable {\tt DATA}
we would use:

\begin{verbatim}
    >> WFDB_putvec(DATA)
\end{verbatim}

\noindent
Finally, we need to record the information from {\tt S} into a header
({\tt .hea}) file for later use.  We need to choose a name for the new
record we are creating (avoiding the names of any existing records that
we wish to read in the future);  if we choose {\tt test1} as the record name,
we can create the header file by:

\begin{verbatim}
    >> WFDB_newheader('test1')
\end{verbatim}

\noindent
These operations will create a header file, {\tt test1.hea}, in the current
directory, and a signal file with the name previously specified in the {\tt
fname} fields of the signal information structure, {\tt S}.  (Notice that {\tt
WFDB\_newheader} must always be invoked {\em after} all of the samples have
been written using {\tt WFDB\_putvec}, because the header file includes the
number of samples in the record and checksums for each signal, which are not
known by the WFDB library until all of the samples have been written.)  As
always, we use

\begin{verbatim}
    >> WFDB_wfdbquit
\end{verbatim}

\noindent
to flush all pending output to the files, to close them, and to reset the
internal WFDB library variables.

As in the previous example, we can inspect our results using WAVE:

\begin{verbatim}
    >> !wave -r test1 &
\end{verbatim}

An elaborated version of this example is provided in the {\tt examples}
directory of the WFDB\_tools package (look for {\tt example4.m}).

\chapter{WFDB\_tools library functions}

This chapter describes the functions that are provided by the WFDB\_tools
package.  The arrangement of this chapter parallels that of chapter 2 of the
{\em WFDB Programmer's Guide}, which describes the underlying WFDB library
functions that the WFDB\_tools functions use.

\section{Selecting Database Records}

These functions are used to open input and output signal and annotation files.

\subsection*{WFDB\_annopen}
\label{WFDB_annopen}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_annopen(RECORD, ANNINFO)}\\
{\em Input:} & {\tt RECORD}: (string) record name\\
 & {\tt ANNINFO}: annotator information structure(s)\\
\end{tabular*}

This function opens input and output annotation files for a selected record. If
RECORD begins with `+', previously opened annotation files are left open, and
the record name is taken to be the remainder of RECORD after discarding the
`+'. Otherwise, WFDB\_annopen closes any previously opened annotation files,
and takes all of RECORD as the record name. ANNINFO is a structure array
created by WFDB\_Anninfo (see section \ref{WFDB_Anninfo}), with one array
element for each annotator to be opened. The caller must fill in the
WFDB\_Anninfo structure array to specify the names of the annotators, and to
indicate which annotators are to be read, and which are to be written. Input
and output annotators may be listed in any order in ANNINFO. Annotator numbers
(for both input and output annotators) are assigned in the order in which the
annotators appear in ANNINFO (the first annotator is number 0). For example,
these instructions

\begin{verbatim}
    >> a = WFDB_Anninfo(3);
    >> a(1).name = 'a'; a(1).stat = 'WFDB_READ';
    >> a(2).name = 'b'; a(2).stat = 'WFDB_WRITE';
    >> a(3).name = 'c'; a(3).stat = 'WFDB_READ';
    >> WFDB_annopen('100s', a)
\end{verbatim}

\noindent
attempt to open three annotation files for record `100s'. Annotator `a'
becomes input annotator 0, `b' becomes output annotator 0, and `c' becomes
input annotator 1. Thus WFDB\_getann(1) (see section \ref{WFDB_getann}) will
read all annotations from annotator `c', and WFDB\_putann(0, ANN) (see section
\ref{WFDB_putann}) will write an annotation for annotator `b'. Input annotation
files will be found if they are located in any of the directories in the WFDB
path (see section \ref{WFDB_getwfdb}). Output annotators are created in the
current directory (but note that, under Unix at least, it is possible to
specify annotator names such as `/here' or `zzz/there' or even
`../somewhere/else')

See also: WFDB\_Anninfo (\ref{WFDB_Anninfo}), WFDB\_getann (\ref{WFDB_getann}),
WFDB\_putann (\ref{WFDB_putann})

\subsection*{WFDB\_isigopen}
\label{WFDB_isigopen}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt S = WFDB\_isigopen(RECORD)}\\
{\em Input:} & {\tt RECORD}: (string) record name\\
{\em Output:} & {\tt S}: Siginfo structure(s) \\
\end{tabular*}

This function opens input signal files for a selected record. If RECORD begins
with `+', previously opened input signal files are left open, and the record
name is taken to be the remainder of RECORD after discarding the `+'.
Otherwise, WFDB\_isigopen closes any previously opened input signal files, and
takes all of RECORD as the record name. S is an array of WFDB\_Siginfo
structures (see section \ref{WFDB_Siginfo} for an explanation of the fields),
one for each signal that was opened.

Calling WFDB\_isigopen also sets internal WFDB library variables that record
the base time and date, the length of the record, and the sampling and counter
frequencies, so that time conversion functions such as WFDB\_strtim (see
section \ref{WFDB_strtim}) that depend on these quantities will work properly.

WFDB\_isigopen will fill the structure array S with information about the
signals in the order in which signals are specified in the `hea' file for the
record.  Signal numbers begin with 0, so that fields in S(n) are the attributes
of signal (n-1).  For example, the gain attributes of each signal in record
`100s' can be read like this:

\begin{verbatim}
    >> S = WFDB_isigopen('100s');
    >> for ii = 1:length(S)
    sprintf('Signal %d, gain: %d', ii-1, S(ii).gain)
    end
    ans =
    Signal 0, gain: 200
    ans =
    Signal 1, gain: 200
\end{verbatim}

An error message is produced if WFDB\_isigopen is unable to open any of the
signals listed in the header file, or if it cannot read the header file. It is
not considered an error if only some of the signals can be opened, however.

See also: WFDB\_Siginfo (\ref{WFDB_Siginfo})

\subsection*{WFDB\_osigopen}
\label{WFDB_osigopen}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt S = WFDB\_osigopen(RECORD, NSIG);}\\
{\em Input:} & {\tt RECORD}: (string) record name\\
 & {\tt NSIG}: number of signals to open\\
{\em Output:} & {\tt S}: Siginfo structure(s) \\
\end{tabular*}

This function opens output signal files. Use it only if signals are to be
written using WFDB\_putvec. The signal specifications, including the file
names, are read from the header file for a specified record and returned in the
structure array S.  If RECORD begins with `+', previously opened output signal
files are left open, and the record name is taken to be the remainder of RECORD
after discarding the `+'. Otherwise, osigopen closes any previously opened
output signal files, and takes all of RECORD as the record name. S is a
WFDB\_Siginfo structure array which, on return, will be filled with the signal
specifications.

No more than NSIG (additional) output signals will be opened by {\tt
WFDB\_\-osigopen}, even if the header file contains specifications for more
than NSIG signals.

See also: WFDB\_Siginfo (\ref{WFDB_Siginfo}), WFDB\_putvec (\ref{WFDB_putvec})

\subsection*{WFDB\_osigfopen}
\label{WFDB_osigfopen}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_osigfopen(S);}\\
{\em Input:} & {\tt S}: Siginfo structure(s) \\
\end{tabular*}

This function opens output signals, as does WFDB\_osigopen, but the signal
specifications, including the signal file names, are supplied by the caller to
WFDB\_osigfopen, rather than read from a header file as in WFDB\_osigopen. Any
previously open output signals are closed by WFDB\_osigfopen. S is a
WFDB\_Siginfo structure array (see section \ref{WFDB_Siginfo}), with one
element for each signal to be opened.

Before invoking WFDB\_osigfopen, the caller must fill in the fields of the
WFDB\_Siginfo structure S. To make a multiplexed signal file, specify the same
fname and group for each signal to be included. For ordinary (non-multiplexed)
signal files, specify a unique fname and group for each signal. See section
\ref{Example:output}: Creating a signal file, for an
illustration of the use of WFDB\_osigfopen.

See also: WFDB\_Siginfo (\ref{WFDB_Siginfo})

\subsection*{WFDB\_wfdbinit}

[Not yet implemented]

\section{Special Input Modes}

\subsection*{WFDB\_setifreq}
\label{WFDB_setifreq}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_setifreq(IFREQ);}\\
{\em Input:} & {\tt IFREQ}: desired input sampling frequency\\
\end{tabular*}

This function sets the current input sampling frequency (in samples per second
per signal). It should be invoked after opening the input signals (using
{\tt WFDB\_isigopen}), and before using any of {\tt WFDB\_getvec, WFDB\_getann,
WFDB\_\-putann, WFDB\_isigsettime, WFDB\_isgsettime, WFDB\_timstr,
WFDB\_mstim\-str}, or {\tt WFDB\_strtim}. Note that the operation of 
{\tt WFDB\_getframe} is unaffected by {\tt WFDB\_setifreq}.

Use {\tt WFDB\_setifreq} when your application requires input samples at a
specific frequency. After invoking {\tt WFDB\_setifreq}, {\tt WFDB\_getvec}
resamples the digitized signals from the input signals at the desired frequency
(see section \ref{WFDB_getvec}), and all of the WFDB\_tools functions that
accept or return times in sample intervals automatically convert between the
actual sampling intervals and those corresponding to the desired frequency.

See also: WFDB\_getvec (\ref{WFDB_getvec})

\subsection*{WFDB\_getifreq}
\label{WFDB_getifreq}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt FREQ = WFDB\_getifreq;}\\
{\em Input:} & {\tt FREQ}: input sampling frequency\\
\end{tabular*}

This function returns the current input sampling frequency (in samples per
second per signal), which is either the raw sampling frequency for the record
(as would be returned by WFDB\_sampfreq (see section \ref{WFDB_sampfreq}), or
the frequency chosen using a previous invocation of WFDB\_setifreq.

See also: WFDB\_sampfreq (\ref{WFDB_sampfreq}), WFDB\_setifreq
(\ref{WFDB_setifreq})

\subsection*{WFDB\_setgvmode}
\label{WFDB_setgvmode}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_setgvmode(MODE);}\\
{\em Input:} & {\tt MODE}: (string) either 'WFDB\_LOWRES' (default) or 
 'WFDB\_HIGHRES'.\\
\end{tabular*}
 
Set the mode used by WFDB\_getvec when reading a multi-frequency record. If
MODE is 'WFDB\_LOWRES', WFDB\_getvec decimates oversampled signals. If MODE is
'WFDB\_HIGHRES', WFDB\_getvec interpolates signals sampled at a lower frequency
(repeating the last sample value).
 
{\bf Example}: Signal 0 is sampled using 100 Hz and signal 1 using 200Hz. With
WFDB\_LOWRES, WFDB\_getvec returns samples using 100 Hz and signal 1 is
decimated from 200 Hz to 100 Hz. With WFDB\_HIGHRES, WFDB\_getvec returns
samples using 200 Hz and signal 0 is interpolated from 100 Hz to 200 Hz.

WFDB\_setgvmode also affects how annotations are read and written. If
WFDB\_setgvmode('WFDB\_HIGHRES') is invoked before using any of
WFDB\_\-annopen, WFDB\_getvec, WFDB\_sampfreq, WFDB\_strtim, or WFDB\_timstr,
then all time data (including the time attributes of annotations read by
WFDB\_\-getann or written by WFDB\_putann) visible to the application are in
units of the high-resolution sampling intervals. (Otherwise, time data are in
units of frame intervals.)

\subsection*{WFDB\_getspf}
\label{WFDB_getspf}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt SPF = WFDB\_getspf;}\\
{\em Output:} & {\tt SPF}: samples per frame\\
\end{tabular*}

Unless the application is operating in WFDB\_HIGHRES mode (see section
\ref{WFDB_setgvmode}) and has then opened a multi-frequency record, this
function returns 1. For the case of a multi-frequency record being read in high
resolution mode, however, WFDB\_getspf returns the number of samples per signal
per frame (hence WFDB\_sampfreq/WFDB\_getspf is the number of frames per
second).

\section{Reading and Writing Signals and Annotations}

\subsection*{WFDB\_getvec}
\label{WFDB_getvec}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt DATA = WFDB\_getvec(NSIG);}\\
 & {\tt DATA = WFDB\_getvec(NSIG, NSAMP);}\\
 & {\tt DATA = WFDB\_getvec(NSIG, NSAMP, TSTART);}\\
{\em Input:} & {\tt NSIG}: number of signals\\
 & {\tt NSAMP}: (optional) number of samples to read \\
 & {\tt TSTART}: (optional) sample number of the first sample to read \\
{\em Output:} & {\tt DATA}: sample value(s) \\
\end{tabular*}

This function reads samples from open input signals.
Typically, we prepare to use this function by
\begin{verbatim}
    S = WFDB_isigopen(record);
    NSIG = length(S);
\end{verbatim}
\noindent
to open the signals for a {\tt record} of choice, and to determine {\tt NSIG},
the number of signals available in the record.

To read {\tt NSAMP} samples of each signal, beginning at sample number
{\tt TSTART}:
\begin{verbatim}
   DATA = WFDB_getvec(NSIG, NSAMP, TSTART);
\end{verbatim}
\noindent
The first sample of each signal has sample number 0 (not 1!).

To read the next {\tt NSAMP} samples of each signal:
\begin{verbatim}
   DATA = WFDB_getvec(NSIG, NSAMP);
\end{verbatim}
\noindent
This form returns up to {\tt NSAMP} samples, from sample number {\tt T} to
sample number {\tt T+NSAMP}-1, where {\tt T} is the input pointer (initially
0).  The input pointer is incremented by the number of samples that have been
read, so that a subsequent use of {\tt WFDB\_getvec} returns the next {\tt
NSAMP} samples, etc.  Use {\tt WFDB\_isigsettime} (see section
\ref{WFDB_isigsettime}) to set the input pointer directly.

If the record is not too long, read it all at once by:
\begin{verbatim}
   DATA = WFDB_getvec(NSIG);
\end{verbatim}
\noindent
Note that recordings can be arbitrarily long and are often much larger
than available memory;  also note that there may be a very long delay if an
entire record is read from a remote web server over a slow link.

\subsection*{WFDB\_getframe}
\label{WFDB_getframe}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt DATA = WFDB\_getframe(NSPF);}\\
 & {\tt DATA = WFDB\_getframe(NSPF, NF);}\\
 & {\tt DATA = WFDB\_getframe(NSPF, NF, TSTART);}\\
{\em Input:} & {\tt NSPF}: number of samples per frame\\
 & {\tt NF}: (optional) number of frames to read \\
 & {\tt TSTART}: (optional) frame number of the first frame to read \\
{\em Output:} & {\tt DATA}: sample value(s) \\
\end{tabular*}

This function reads frames from open input signals.  It is very similar
to WFDB\_getvec, and differs only when reading multifrequency records,
which it neither interpolates nor decimates;  rather, it returns all
sample values for each data frame.

For example, if there are two signals, and signal 0 is sampled twice as fast
as signal 1, each frame contains two samples of signal 0 followed by one
sample of signal 1, so NSPF is 3 (two plus one).  Suppose that we run:

\begin{verbatim}
{\tt DATA = WFDB_getframe(3, 5, 10)}
\end{verbatim}

This loads five frames (frame numbers 10 through 14) into DATA, which will be
organized as:

{\small
\begin{verbatim}
   [signal 0, sample 20]  [signal 0, sample 21]  [signal 1, sample 10]
   [signal 0, sample 22]  [signal 0, sample 23]  [signal 1, sample 11]
   [signal 0, sample 24]  [signal 0, sample 25]  [signal 1, sample 12]
   [signal 0, sample 26]  [signal 0, sample 27]  [signal 1, sample 13]
   [signal 0, sample 28]  [signal 0, sample 29]  [signal 1, sample 14]
\end{verbatim}
}

\subsection*{WFDB\_putvec}
\label{WFDB_putvec}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_putvec(DATA))}\\
{\em Input:} & {\tt DATA}: sample(s) to be written\\
\end{tabular*}

This function writes the specified sample(s) to output signal file(s).  Within
DATA, signals are stored as columns. The number of columns must equal the
number of output signals as specified when calling WFDB\_osigfopen or
WFDB\_osigopen.

\subsection*{WFDB\_getann}
\label{WFDB_getann}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt ANNOTATION = WFDB\_getann(ANN\_NUM)}\\
 & {\tt ANNOTATION = WFDB\_getann(ANN\_NUM, NANN)}\\
{\em Input:} & {\tt ANN\_NUM}: annotator number (note: the first input
 annotator is annotator number 0)\\
 & {\tt NANN}: (optional) number of annotations wanted\\
{\em Output:} & {\tt ANNOTATION}: Annotation structure(s) \\
\end{tabular*}

This function reads the next NANN annotations from an open input annotation
file  (designated by its annotator number, ANN\_NUM).  If NANN is omitted,
it reads all annotations at once.  Use WFDB\_iannsettime to set the
file pointer.

See WFDB\_Annotation (section \ref{WFDB_Annotation}) for information on
the contents of the annotation structures.

\subsection*{WFDB\_ungetann}

[Not yet implemented]

\subsection*{WFDB\_putann}
\label{WFDB_putann}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_putann(ANN\_NUM, ANNOTATION)}\\
{\em Input:} & {\tt ANN\_NUM}: annotator number (note: the first output
 annotator is annotator number 0)\\
 & {\tt ANNOTATION}: Annotation structure(s) \\
\end{tabular*}

This function writes annotation(s) to an open output annotation file
(designated by its annotator number, ANN\_NUM, and created using WFDB\_Anninfo
and WFDB\_annopen).  Use WFDB\_Annotation to create the annotation structures,
and fill in their data fields before invoking WFDB\_putann.  If possible,
annotations should be written in canonical (time/chan) order (otherwise, the
annotations will be rewritten in order when WFDB\_wfdbquit is invoked).

\section{Non-Sequential Access to WFDB Files}

The next several functions permit random access to signal and annotation files.

\subsection*{WFDB\_isigsettime}
\label{WFDB_isigsettime}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_isigsettime(TIME)}\\
{\em Input:} & {\tt TIME}: sample number of the next sample to be read\\
\end{tabular*}

Set input signal file pointer to sample number TIME.  (The first sample is
sample 0.)

\subsection*{WFDB\_isgsettime}
\label{WFDB_isgsettime}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_isgsettime(SGROUP, TIME)}\\
{\em Input:} & {\tt SGROUP}: signal group number (note: the first signal group
 is group 0, etc.) \\
 & {\tt TIME}: sample number of the next sample to be read\\
\end{tabular*}

This function does the job of WFDB\_isigsettime, but only for the signal group
SGROUP.  This function may be of use if more than one record is open
simultaneously.

\subsection*{WFDB\_iannsettime}
\label{WFDB_iannsettime}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_iannsettime(TIME)}\\
{\em Input:} & {\tt TIME}: minimum value for the {\tt time} of the next
 annotation to be read\\
\end{tabular*}

This function can be used to skip to a desired TIME in a set of annotations,
so that the next annotation to be read will be the first one occurring at
or after the specified TIME.

\subsection*{WFDB\_sample}

[Not yet implemented]

\subsection*{WFDB\_sample\_valid}

[Not yet implemented]

\section{Conversion Functions}

Functions in this section perform various useful conversions: between
annotation codes and printable strings, between times in sample intervals and
printable strings, between Julian dates and printable strings, and between ADC
units and physical units.

\subsection*{WFDB\_annstr}
\label{WFDB_annstr}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt MNEMONIC = WFDB\_annstr(CODE);} \\
{\em Input:} & {\tt CODE}: (scalar or vector) annotation code(s) \\
{\em Output:} & {\tt MNEMONIC}: (string, if {\tt CODE} is scalar; otherwise,
 a cell of strings) annotation mnemonic(s) \\
\end{tabular*}

{\tt WFDB\_annstr} translates WFDB annotation code(s) to mnemonic(s).

\subsection*{WFDB\_anndesc}
\label{WFDB_anndesc}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt DESC = WFDB\_anndesc(CODE);} \\
{\em Input:} & {\tt CODE}: (scalar or vector) annotation code(s) \\
{\em Output:} & {\tt DESC}: (string, if {\tt CODE} is scalar; otherwise,
 a cell of strings) annotation description string(s) \\
\end{tabular*}

{\tt WFDB\_anndesc} translates WFDB annotation code(s) to description(s).

\subsection*{WFDB\_ecgstr}
\label{WFDB_ecgstr}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt MNEMONIC = WFDB\_ecgstr(CODE);} \\
{\em Input:} & {\tt CODE}: (scalar or vector) annotation code(s) \\
{\em Output:} & {\tt MNEMONIC}: (string, if {\tt CODE} is scalar; otherwise,
 a cell of strings) annotation mnemonic(s) \\
\end{tabular*}

{\tt WFDB\_ecgstr} translates WFDB annotation code(s) to mnemonic(s).
The mnemonics shared by {\tt WFDB\_ecgstr} and {\tt WFDB\_strecg} can
be modified independently of those shared by {\tt WFDB\_annstr} and
{\tt WFDB\_strann}, although both sets of mnemonics are initially
identical.  For further details, see the description of {\tt
setannstr} in the {\em WFDB Programmer's Guide}.

\subsection*{WFDB\_strann}
\label{WFDB_strann}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt MNEMONIC = WFDB\_strann(CODE);} \\
{\em Input:} & {\tt MNEMONIC}: (string, or cell of strings) annotation
 mnemonic(s) \\
{\em Output:} & {\tt CODE}: annotation code(s) \\
\end{tabular*}

This function translates one or more ASCII strings (annotation
mnemonics) to numeric annotation codes.

\subsection*{WFDB\_strecg}
\label{WFDB_strecg}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt MNEMONIC = WFDB\_strecg(CODE);} \\
{\em Input:} & {\tt MNEMONIC}: (string, or cell of strings) annotation
 mnemonic(s) \\
{\em Output:} & {\tt CODE}: annotation code(s) \\
\end{tabular*}

This function translates one or more ASCII strings (annotation
mnemonics) to numeric annotation codes.

\subsection*{WFDB\_setannstr}

[Not yet implemented]

\subsection*{WFDB\_setanndesc}

[Not yet implemented]

\subsection*{WFDB\_setecgstr}

[Not yet implemented]

\subsection*{WFDB\_timstr}
\label{WFDB_timstr}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt STR = WFDB\_timstr(T);} \\
{\em Input:} & {\tt T}: (integer) time, in sample intervals \\
{\em Output:} & {\tt STR}: (string) time, in HH:MM:SS format \\
\end{tabular*}

This function translates a time expressed in sample intervals into a
string indicating time in hours, minutes, and seconds.  If T is
positive, the string indicates the time interval between sample number
T and sample number 0; otherwise, the time interval represented by -T
is added to the base time (as indicated in the `.hea' file or
previously set using {\tt WFDB\_setbasetime}) and the string indicates
the time of day (and the date, if the base date has been set) at the
time of sample number (-T).

\subsection*{WFDB\_mstimstr}
\label{WFDB_mstimstr}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt STR = WFDB\_mstimstr(T);} \\
{\em Input:} & {\tt T}: (integer) time, in sample intervals \\
{\em Output:} & {\tt STR}: (string) time, in HH:MM:SS.sss format \\
\end{tabular*}

This function is similar to {\tt WFDB\_timstr}, except that the
output string specifies the time with a resolution of 1 millisecond.

\subsection*{WFDB\_strtim}
\label{WFDB_strtim}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt T = WFDB\_strtim(STR);} \\
{\em Input:} & {\tt STR}: (string) time, in HH:MM:SS format \\
{\em Output:} & {\tt T}: (integer) time, in sample intervals \\
\end{tabular*}

{\tt WFDB\_strtim} converts an ASCII string to a time in units of sample
intervals.  The string should be supplied in {\em standard time format} (see
http://www.physio\-net\-.org/\-physiotools/wpg/strtim.htm).

\subsection*{WFDB\_datstr}
\label{WFDB_datstr}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt STR = WFDB\_datstr(DATE);} \\
{\em Input:} & {\tt DATE}: (integer) Julian date \\
{\em Output:} & {\tt STR}: (string) date, in DD/MM/YYYY format \\
\end{tabular*}

This function converts the Julian date represented by DATE into an
ASCII string.

\subsection*{WFDB\_strdat}
\label{WFDB_strdat}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt STR = WFDB\_strdat(DATE);} \\
{\em Input:} & {\tt STR}: (string) date, in DD/MM/YYYY format \\
{\em Output:} & {\tt DATE}: (integer) Julian date \\
\end{tabular*}

This function converts an ASCII string in DD/MM/YYYY format into a Julian date.
If the string is improperly formatted, {\tt WFDB\_strdat} returns
zero.  Note that dates such as '15/3/89' refer to the first century
A.D., not the twentieth or twenty-first.

\subsection*{WFDB\_aduphys}
\label{WFDB_aduphys}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt PHYS = WFDB\_aduphys(SIG\_NUM, ADU);} \\
{\em Input:} & {\tt SIG\_NUM}: signal number (note: the first signal is signal
   number 0, etc.) \\
 & ADU: signal values in A/D units (scalar or vector) \\
{\em Output:} & {\tt PHYS}: signal value(s) in physical units \\
\end{tabular*}

{\tt WFDB\_aduphys} converts signal value(s) in ADU from A/D units to physical
units, based on the values of gain and baseline for input signal number
SIG\_NUM.

\subsection*{WFDB\_physadu}
\label{WFDB_physadu}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt ADU = WFDB\_physadu(SIG\_NUM, PHYS);} \\
{\em Input:} & {\tt SIG\_NUM}: signal number (note: the first signal is signal
   number 0, etc.) \\
 & {\tt PHYS}: signal value(s) in physical units (scalar or vector) \\
{\em Output:} & ADU: signal values in A/D units \\
\end{tabular*}

{\tt WFDB\_physadu} converts signal value(s) in PHYS from physical units to ADU
units, based on the values of gain and baseline for input signal number
SIG\_NUM.

\subsection*{WFDB\_adumuv}
\label{WFDB_adumuv}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt MUV = WFDB\_adumuv(SIG\_NUM, ADU);} \\
{\em Input:} & {\tt SIG\_NUM}: signal number (note: the first signal is signal
   number 0, etc.) \\
 & ADU: signal values in A/D units (scalar or vector) \\
{\em Output:} & {\tt MUV}: signal value(s) in microvolts \\
\end{tabular*}

{\tt WFDB\_adumuv} converts signal value(s) in ADU from A/D units to
microvolts, based on the values of gain and baseline for input signal number
SIG\_NUM.

\subsection*{WFDB\_muvadu}
\label{WFDB_muvadu}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt ADU = WFDB\_muvadu(SIG\_NUM, MUV);} \\
{\em Input:} & {\tt SIG\_NUM}: signal number (note: the first signal is signal
   number 0, etc.) \\
 & {\tt MUV}: signal value(s) in microvolts (scalar or vector) \\
{\em Output:} & {\tt ADU}: signal values in A/D units \\
\end{tabular*}

{\tt WFDB\_muvadu} converts signal value(s) in MUV from microvolts to ADU
units, based on the values of gain and baseline for input signal number
SIG\_NUM.

\section{Calibration Functions}

Functions in this section are used to determine specifications for calibration
pulses and customary scales for plotting signals. All of them make use of the
{\em calibration list}, which contains entries for various types of signals.

\subsection*{WFDB\_calopen}

[Not yet implemented]

\subsection*{WFDB\_getcal}

[Not yet implemented]

\subsection*{WFDB\_putcal}

[Not yet implemented]

\subsection*{WFDB\_newcal}

[Not yet implemented]

\subsection*{WFDB\_flushcal}

[Not yet implemented]


\section{Miscellaneous Functions}

\subsection*{WFDB\_newheader}
\label{WFDB_newheader}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_newheader(RECORD);} \\
{\em Input:} & {\tt RECORD}: (string) record name \\
\end{tabular*}

This function creates a '.hea' file. Use WFDB\_newheader just after you have
finished writing the signal files, but before calling WFDB\_wfdbquit. If
RECORD begins with '+', the '+' is discarded and the remainder of RECORD is
taken as the record name.   If the record name is '-', the header file is
written to the standard output.

\subsection*{WFDB\_setheader}
\label{WFDB_setheader}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_setheader(RECORD, S, NSIG)} \\
{\em Input:} & {\tt RECORD}: (string) record name \\
 & {\tt S}:  Siginfo structure(s) \\
 & {\tt NSIG}: number of signals \\
\end{tabular*}

This function creates or recreates a header file for the specified RECORD,
based on the contents of the first NSIG members of S.

\subsection*{WFDB\_setmsheader}

[Not yet implemented]

\subsection*{WFDB\_wfdbquit}
\label{WFDB_wfdbquit}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_wfdbquit;} \\
\end{tabular*}

This function closes all open database files and resets the following:
\begin{itemize}
\item
the factors used for converting between samples, seconds, and counter
values (reset to 1), the base time (reset to 0, i.e., midnight), and
the base counter value (reset to 0); see WFDB\_mstimstr and WFDB\_timstr

\item
the parameters used for converting between adus and physical units (reset
to WFDB\_DEFGAIN adu/mV, a quantity defined in {\tt <wfdb/wfdb.h>});  see
WFDB\_aduphys

\item
internal variables used to determine output signal specifications; see
{\tt WFDB\_\-newheader}
\end{itemize}

If any annotations have been written out-of-order, this function attempts
to run {\tt sortann} (see the {\em WFDB Applications Guide}) as a subprocess to
restore the annotations to canonical order. If this cannot be done, it
prints a warning message indicating that the annotations are not in order,
and providing instructions for putting them in order.

\subsection*{WFDB\_iannclose}
\label{WFDB_iannclose}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_iannclose(ANN);} \\
{\em Input:} & {\tt ANN}: annotator number (note: the first annotator is
  annotator number 0, etc.) \\
\end{tabular*}

This function closes the annotation file associated with input annotator ANN.

\subsection*{WFDB\_oannclose}
\label{WFDB_oannclose}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_oannclose(ANN);} \\
{\em Input:} & {\tt ANN}: annotator number (note: the first annotator is
  annotator number 0, etc.) \\
\end{tabular*}

This function closes the annotation file associated with output annotator ANN.

\subsection*{WFDB\_wfdbquiet}
\label{WFDB_wfdbquiet}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_wfdbquiet;} \\
\end{tabular*}

This function suppresses error reporting on the standard error output
from the WFDB library functions.

\subsection*{WFDB\_wfdbverbose}
\label{WFDB_wfdbverbose}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_wfdbverbose;} \\
\end{tabular*}

This function restores normal error reporting after using
{\tt WFDB\_wfdbquiet}.

\subsection*{WFDB\_wfdberror}
\label{WFDB_wfdberror}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_wfdberror;} \\
\end{tabular*}

This function returns a string containing the text of the most recent WFDB
library error message (or a string containing the WFDB library version number,
if there have been no errors).

\subsection*{WFDB\_sampfreq}
\label{WFDB_sampfreq}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt FREQ = WFDB\_sampfreq;} \\
 & {\tt FREQ = WFDB\_sampfreq(RECORD);} \\
{\em Input:} & {\tt RECORD}: (string) record name \\
{\em Output:} & {\tt FREQ}: (real) sampling frequency \\
\end{tabular*}

This function determines the sampling frequency (in Hz) for the record
specified by its argument, if any. If RECORD is omitted, {\tt WFDB\_sampfreq}
returns the currently defined sampling frequency, if any.

\subsection*{WFDB\_setsampfreq}
\label{WFDB_setsampfreq}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_setsampfreq(FREQ);} \\
{\em Input:} & {\tt FREQ}: (real) sampling frequency \\
\end{tabular*}

This function sets the sampling frequency, in sample intervals per second, used
by the time-conversion functions. Use setsampfreq before creating a new `hea'
file.

\subsection*{WFDB\_setbasetime}
\label{WFDB_setbasetime}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_setbasetime;} \\
 & {\tt WFDB\_setbasetime(BASETIME);} \\
{\em Input:} & {\tt BASETIME}: (string) time of sample 0, in HH:MM:SS format;
  an optional base date in dd/mm/yyyy format can follow the time, separated
  from it by a space or tab character.
\end{tabular*}

This function sets the base time (the time of day corresponding to sample
number 0), used by the time-conversion functions {\tt WFDB\_timstr} and 
{\tt WFDB\_strtim}.  Use {\tt WFDB\_setbasetime} after defining the sampling
frequency and before creating a header file. If called without an argument,
the current date and time are read from the system clock.

\subsection*{WFDB\_getcfreq}
\label{WFDB_getcfreq}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt FREQ = WFDB\_getcfreq;} \\
{\em Output:} & {\tt FREQ}: (real) counter frequency \\
\end{tabular*}

This function returns the currently-defined counter frequency. The counter
frequency is set by the functions that read header files, or by
{\tt WFDB\_setcfreq}. If the counter frequency has not been defined explicitly,
{\tt WFDB\_getcfreq} returns the sampling frequency.

\subsection*{WFDB\_setcfreq}
\label{WFDB_setcfreq}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_setcfreq(FREQ);} \\
{\em Input:} & {\tt FREQ}: (real) counter frequency \\
\end{tabular*}

This function sets the counter frequency, in Hz. Use {\tt WFDB\_setcfreq}
before creating a '.hea' file.  The effect of {\tt WFDB\_setcfreq} is nullified
by later invoking any of the functions that read header files. If FREQ is zero
or negative, the counter frequency is treated as equivalent to the sampling
frequency.

\subsection*{WFDB\_getbasecount}
\label{WFDB_getbasecount}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt BASECOUNT = WFDB\_getbasecount;} \\
{\em Output:} & {\tt BASECOUNT}: (real) base counter value \\
\end{tabular*}

This function gets the base counter value (the counter value corresponding to
sample 0), which is set by the functions that read header files, or by
{\tt WFDB\_setbasecount}.  If the base counter value has not been set
explicitly, {\tt WFDB\_getbasecount} returns zero.

\subsection*{WFDB\_setbasecount}
\label{WFDB_setbasecount}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_setbasecount(BASECOUNT);} \\
{\em Input:} & {\tt BASECOUNT}: (real) base counter value \\
\end{tabular*}

This function sets the base counter value (the counter value corresponding to
sample number 0). Use {\tt WFDB\_setbasecount} before creating a header
file. The effect of {\tt WFDB\_setbasecount} is nullified by later invoking any
of the functions that read '.hea' files.

\subsection*{WFDB\_setwfdb}

[Not yet implemented]

\subsection*{WFDB\_getwfdb}
\label{WFDB_getwfdb}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB = WFDB\_getwfdb} \\
{\em Output:} & {\tt WFDB}: (string) WFDB path \\
\end{tabular*}

This function gets the current database path (the list of locations that
the WFDB library searches to find its input files).

\subsection*{WFDB\_wfdbfile}
\label{WFDB_wfdbfile}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt PATH = WFDB\_wfdbfile(NAME);} \\
 & {\tt PATH = WFDB\_wfdbfile(TYPE, RECORD);} \\
{\em Input:} & {\tt NAME}: (string) file name, e.g. '100s.hea' \\
 & {\tt TYPE}: (string) type of file, e.g. 'hea' or 'atr' \\
 & {\tt RECORD}: (string) record name, e.g. '100s' \\
{\em Output:} & {\tt PATH}: (string) pathname of the file or URL \\
\end{tabular*}

This function locates an existing WFDB file by searching the database path. The
file is specified by TYPE and RECORD, or by its NAME.  On return, PATH includes
the appropriate component of the database path; since the database path may
include empty or non-absolute components, the string is not necessarily an
absolute pathname.  PATH may also be a URL rather than a pathname.  If the file
cannot be found, WFDB\_wfdbfile returns an empty string, ''.

\subsection*{WFDB\_wfdbflush}
\label{WFDB_wfdbflush}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_wfdbflush;} \\
\end{tabular*}

This function brings database output files up-to-date by forcing any output
annotations or samples that are buffered to be written to the output files.

\subsection*{WFDB\_getinfo}
\label{WFDB_getinfo}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt INFO = WFDB\_getinfo(RECORD);} \\
{\em Input:} & {\tt RECORD}: (string) record name \\
{\em Output:} & {\tt INFO}: information string(s). If only one info string is
 found, INFO is a string;  if two or more are found, INFO is a cell of
 strings.  If there are no info strings, INFO is '' (the empty string). \\
\end{tabular*}

This function reads information string(s) from a .hea file.

\subsection*{WFDB\_putinfo}
\label{WFDB_putinfo}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_putinfo(INFO);} \\
{\em Input:} & {\tt INFO}: information string(s) (a string or a cell of
 strings;  no string may be longer than 254 characters) \\
\end{tabular*}

{\tt WFDB\_putinfo} writes ``info'' string(s) into the '.hea' file that was
created by the most recent invocation of {\tt WFDB\_newheader}.  Two or more
info strings may be written to the same header by successive invocations of
{\tt WFDB\_putinfo}, or by passing INFO as a cell of strings.

Note that {\tt WFDB\_newheader} or {\tt WFDB\_setheader} must be used before
{\tt WFDB\_\-put\-info}.

\subsection*{WFDB\_setibsize}

[Not yet implemented]

\subsection*{WFDB\_setobsize}

[Not yet implemented]

\subsection*{WFDB\_wfdbgetskew}
\label{WFDB_wfdbgetskew}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt SKEW = WFDB\_wfdbgetskew(SIG\_NUM);} \\
{\em Input:} & {\tt SIG\_NUM}: signal number (note: the first signal is signal
   number 0, etc.) \\
{\em Output:} & {\tt SKEW}: skew, in frame intervals \\
\end{tabular*}

This function gets the skew (as recorded in the '.hea' file, but in
frame intervals rather than in sample intervals) of the specified
input signal, or 0 if SIG\_NUM is not a valid input signal number.
Since sample vectors returned by {\tt WFDB\_getvec} or
{\tt WFDB\_getframe} are already corrected for skew, 
{\tt WFDB\_wfdbget\-skew} is useful primarily for programs that need to rewrite
existing '.hea' files, where it is necessary to preserve the previously
recorded skews.

\subsection*{WFDB\_wfdbsetskew}
\label{WFDB_wfdbsetskew}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt WFDB\_wfdbsetskew(SIG\_NUM, SKEW);} \\
{\em Input:} & {\tt SIG\_NUM}: signal number (note: the first signal is signal
   number 0, etc.) \\
 & {\tt SKEW}: skew, in frame intervals \\
\end{tabular*}

This function sets the specified skew (in frame intervals) to be recorded by
{\tt WFDB\_newheader} or {\tt WFDB\_setheader} for signal SIG\_NUM. {\tt
WFDB\_wfdbsetskew} has no effect on the skew correction performed by {\tt
WFDB\_getframe} (or {\tt WFDB\_get\-vec}), which is determined solely by the
skews that were recorded in the header file at the time the input signals were
opened.

\subsection*{WFDB\_wfdbgetstart}
\label{WFDB_wfdbgetstart}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt PLENGTH = WFDB\_wfdbgetstart(SIG\_NUM);} \\
{\em Input:} & {\tt SIG\_NUM}: signal number (note: the first signal is signal
   number 0, etc.) \\
{\em Output:} & {\tt PLENGTH}: prolog length, in bytes \\
\end{tabular*}

This function gets the number of bytes in the prolog of the signal file that
contains the specified input signal, as recorded in the header file. Note that
{\tt WFDB\_wfdbgetstart} does not determine the length of the prolog by
inspection of the signal file; it merely reports what has been determined by
other means and recorded in the '.hea' file. Since the prolog is not readable
using the WFDB library, and since functions such as {\tt WFDB\_isigopen} and
{\tt WFDB\_isigsettime} take the prolog into account when calculating byte
offsets for {\tt WFDB\_getframe} and {\tt WFDB\_getvec}, {\tt
WFDB\_wfdbgetstart} is useful primarily for programs that need to rewrite
existing '.hea' files, where it is necessary to preserve the previously
recorded byte offsets.

\subsection*{WFDB\_wfdbsetstart}
\label{WFDB_wfdbsetstart}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt PLENGTH = WFDB\_wfdbgetstart(SIG\_NUM);} \\
{\em Input:} & {\tt SIG\_NUM}: signal number (note: the first signal is signal
   number 0, etc.) \\
{\em Output:} & {\tt PLENGTH}: prolog length, in bytes \\
\end{tabular*}

This function sets the specified prolog length (bytes) to be recorded by
{\tt WFDB\_newheader} or {\tt WFDB\_setheader} for signal {\tt SIG\_NUM}.
{\tt WFDB\_wfdbsetstart} has no effect on the calculations of byte offsets
within signal files as performed by {\tt WFDB\_isigsettime}, which are
determined solely by the contents of the '.hea' file at the time the signals
were opened.

\section{Creating structures}
The WFDB C functions work with different structures of information about
signals, annotators, and annotations. Some of the functions in the previous
sections demand input of such structures. The following structure-creating
functions are not wrappers to any C functions; rather, they are {\sc Matlab}
m-files that create structure arrays containing the required fields, with
working (although not correct in all cases) default values to avoid
hard-to-find errors.

\subsection*{WFDB\_Anninfo}
\label{WFDB_Anninfo}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt A = WFDB\_Anninfo(N);} \\
{\em Input:} & {\tt N}: number of Anninfo structures to be created (number of
		annotation files to be opened) \\
{\em Output:} & {\tt S}: Anninfo structure(s) \\
\end{tabular*}

Use this function to create Anninfo structures to be passed as input
to {\tt WFDB\_annopen}.  Anninfo structures have two fields:

\begin{tabular*}{\textwidth}{l l lp{3 in}}
{\tt name} & string & {annotator name;  defaults set by WFDB\_Anninfo are
{\tt a0}, {\tt a1}, ....} \\
{\tt stat} & string & {input/output indicator (either `{\tt WFDB\_READ}' or
 `{\tt WFDB\_WRITE}'); default is `{\tt WFDB\_READ}'} \\
\end{tabular*}

The annotator name identifies a set of annotations;  usually the name is
that of the creator of the annotations, either a program or a person.
The annotator name is the suffix of the annotation file's name;  for example,
the annotation file {\tt 100s.atr} is a set of annotations for record 100s,
with the annotator name `{\tt atr}'.
The application may change the {\tt name} to any string containing letters,
numerals, and the `\_' (underscore) character.  Avoid names that are used
as a suffix for another file type.
The application should change the {\tt stat} string for any output annotators
to `{\tt WFDB\_WRITE}'.
Any changes must be made before invoking {\tt WFDB\_annopen};  later changes
have no effect.

\subsection*{WFDB\_Siginfo}
\label{WFDB_Siginfo}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt S = WFDB\_Siginfo(N);} \\
{\em Input:} & {\tt N}: number of Siginfo structures to be created (number of
		signals to be written) \\
{\em Output:} & {\tt S}: Siginfo structure(s) \\
\end{tabular*}

Use this function to create Siginfo structures to be passed as input
to {\tt WFDB\_osigfopen}.  Siginfo structures have twelve fields:

\begin{tabular*}{\textwidth}{l l lp{3 in}}
{\tt fname} & string &
{the name of the signal file (may be shared among consecutively numbered
signals); default: {\tt record.dat}} \\
{\tt desc} & string &
{description of the signal (e.g., `{\tt ABP}', `{\tt Resp}');
default: `{\tt Signal 0}', `{\tt Signal 1}', ...} \\
{\tt units} & string &
{physical units of the signal (e.g., `{\tt mmHg}', `{\tt \%}');
default: '{\tt mV}'} \\
{\tt gain} & real &
{number of A/D units per physical unit; default: 200} \\
{\tt initval} & integer &
{value of sample 0, in ADC units; default: 0} \\
{\tt group} & integer &
{group number (all signals sharing a signal file belong to the same group);
default: 0} \\
{\tt fmt} & integer &
{storage format (one of those defined in WFDB\_FMT\_LIST, in
{\tt <wfdb/wfdb.h>}); default: 16} \\
{\tt spf} & integer &
{samples per frame; default: 1} \\
{\tt bsize} & integer &
{bytes per block (for use with tape and other block-structured storage media;
0 for ordinary files); default: 0} \\
{\tt adcres} & integer &
{ADC resolution in bits; default: 12} \\
{\tt adczero} & integer &
{sample value corresponding to the middle of the ADC range; default: 0} \\
{\tt baseline} & real &
{(possibly fictitious) sample value corresponding to an input of 0 in physical
units; default: 0} \\
\end{tabular*}

The default values indicated above are filled in by {\tt WFDB\_Siginfo}.  Any
changes to these values must be made before invoking {\tt WFDB\_osigfopen};
later changes have no effect.

\newpage
\subsection*{WFDB\_Annotation}
\label{WFDB_Annotation}

\begin{tabular*}{\textwidth}{l lp{3.5 in}}
{\em Usage:} & {\tt ANN = WFDB\_Annotation(N);} \\
{\em Input:} & {\tt N}: number of Annotation structures to be created \\
{\em Output:} & {\tt S}: Anninfo structure(s) \\
\end{tabular*}

Use this function to create Annotation structures to be passed as input
to {\tt WFDB\_putann}.  Annotation structures have six fields:

\begin{tabular*}{\textwidth}{l l lp{3 in}}
{\tt time} & integer &
the sample number to which the annotation `points';  defaults set by
WFDB\_Annotation are 1, 2, 3, .... \\
{\tt anntyp} & integer &
the annotation type, an integer between 1 and {\tt ACMAX} (defined in
 `{\tt <wfdb/ecgcodes.h>}');  default is 1 \\
{\tt subtyp} & integer &
the annotation subtype, an integer between -128 and 127;  default is 0 \\
{\tt chan} & integer &
the annotation chan field, an integer between -128 and 127; default is 0 \\
{\tt num} & integer &
the annotation num field, an integer between -128 and 127; default is 0 \\
{\tt aux} & string &
the annotation aux string; default is an empty string \\
\end{tabular*}

The {\tt subtyp}, {\tt chan}, and {\tt num} fields do not have any preassigned
meanings;  they may be used to record any small integers, or left at their
default (0) values, in which case they will not occupy space in the annotation
file.  Note that the length of the {\tt aux} string may not exceed 254
characters.

\chapter*{Support}
If you believe you have found a bug, please send a report including:
\begin{itemize}
\item the name of the wrapper
\item what input you used
\item what result you got
\item what result you expected
\item what platform you used (CPU type, operating system name and
version number, {\sc Matlab} version number, WFDB software package version
number, WFDB\_tools version number)
\end{itemize}

Bug reports, questions, comments, and suggestions should be addressed to:

\begin{description}
\item [Email: ] {\tt Jonas dot Carlson at kard dot lu dot se}
\item [Fax: ] +46 46 157857
\item [Address: ] (postal)\\
Jonas Carlson\\
Department of Cardiology\\
University Hospital\\
SE - 221 85 LUND\\
Sweden
\end{description}

\end{document}
