[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This section may be helpful if you wish to extend the capabilities of the WFDB library, or if you wish to port it to another environment. In order to make use of the information in this section, you should have the WFDB library sources (see section Sources). The sources are distributed among four ‘include’ (‘.h’) files and five ‘.c’ files:
wfdb.h Constant and structure definitions, and function prototypes ecgcodes.h Annotation codes ecgmap.h Annotation code mapping macros wfdblib.h External definitions for private WFDB library functions wfdbinit.c Functions |
The first three of these files are the standard ‘include’ files that are usually obtained by ‘#include <wfdb/file.h>’ statements. When modifying the WFDB library, however, make any necessary changes in the copies of these files that are kept in the library source directory. Install the modified versions of the ‘.h’ files in the system’s ‘include’ directory after installing the modified WFDB library.
The cleanest mechanism for adding additional fields to ‘hea’ files is
to include them in ‘info’ strings
(see section getinfo
),
rather than by modifying the code that reads and writes ‘hea’
files (in ‘signal.c’).
A common problem is the need to import signal files generated by other
software. Often this problem can be solved by writing a format
conversion program that uses input functions provided with the other
software to read the signal files, and putvec
to write them
in one of the formats supported by the WFDB library. This solution is
unlikely to be satisfactory if you have many large signal files to
import, however, and you may wish to arrange for getvec
to read
the imported files directly. This may be done by defining a new signal
file format, as outlined below.
To define a new format for signal files, choose a numeric code to
represent your format. (Values between 900 and 999 are reserved for
user-defined signal file format codes.) In ‘wfdb.h’, add your format
code to FMT_LIST
and increment NFMTS
. In ‘signal.c’,
define functions (macros if possible for efficiency) for reading and
writing single samples; these should be named rnnn
and
wnnn
, where nnn is your format code. Follow the
examples in ‘signal.c’; it will almost certainly be easier to make
use of the existing macros r8
and w8
than to begin from
scratch. Add additional case
statements in getvec
and
putvec
, again following the existing models. You will also need
to add a case
in isgsettime
, including a formula to
determine the number of bytes needed per sample, given the number of
signals multiplexed. (All currently-defined formats use fixed-length
encoding. If you wish to implement variable-length encoding, it may be
easiest to implement an indexed-search method for isgsettime
in
such cases.) If the ADC resolution exceeds the number of bits in a C
int
on your system, change the typedef
for ‘WFDB_Sample’
in ‘<wfdb/wfdb.h>’ as necessary; be aware that this change is likely
to require additional changes to application programs (use ‘lint’
or an ANSI C compiler to check your code).
Although the WFDB library generally assumes that signal files are “pure”, it
is possible to read imported signal files that contain prologs (data that
precede the first sample). To do so, you must construct a header file in which
the format
fields encode the length of the prolog in bytes (you can do
this manually, or use wfdbsetstart
, see section wfdbsetstart, for this
purpose). For example, a signal file with a 512-byte prolog followed by format
16 samples would be specified using ‘16+512’ in the format
field or
fields (if the file contains more than one signal, the format
fields for
all signals in the file must be identical). Note that this facility is
provided only for signal file import; the WFDB library is not equipped to
create signal files with embedded prologs.
In a similar fashion, though with substantially more effort in most
cases, you may define a new format for annotation files. Add additional
stat
values for reading and writing to the list in ‘wfdb.h’.
In ‘annot.c’, add additional case
statements and code to
annopen
, getann
, putann
, and wfdb_anclose
. If
you are designing a new format, you may wish to specify a ‘magic number’
with which your files will begin, to allow annopen
to recognize
the format automatically; a good choice of such a number is one in which
the first byte is non-zero (to distinguish it from AHA format files) and
the high six bits of the second byte are zero (to distinguish it from WFDB
format files).
Some users may wish to define additional annotation codes. An easy and
portable way to accomplish this is to use setannstr
and
setanndesc
within programs that create your annotation files,
before opening them using annopen
(or wfdbinit
). Annotation
files created in this way contain modification labels at the beginning
that document the non-standard code definitions, and that permit them to
be read properly by standard WFDB applications. Another solution is to
modify the WFDB library. This method has the disadvantage that all of
your applications that read annotation files must be recompiled, and
they may no longer read standard annotation files properly. If despite
this disadvantage you prefer to modify the WFDB library, begin by defining
symbolic names and numeric values for your new codes in
‘ecgcodes.h’. (Values between 42 and 49 are reserved for
user-defined annotation codes. Unused values less than 42 may be
assigned in future versions of the WFDB library, and values greater than
49 are reserved to indicate the presence of optional fields such as
subtyp
.) Next, decide how the new codes are to be mapped by
isqrs
, map1
, map2
, mamap
, and annpos
,
and set the appropriate entries in each of the code map arrays in
‘ecgmap.h’. Finally, add mnemonic and descriptive strings for the
new codes in the cstring
, astring
, and tstring
arrays in ‘annot.c’.
The modular design of the library makes it fairly easy to remove unneeded functionality in order to conserve memory for special applications. The ‘calib.c’ package is not referenced by any other WFDB library modules. For signal processing applications that do not involve annotations, the entire ‘annot.c’ package may be removed (with trivial modifications to the functions in ‘wfdbinit.c’). If you wish to add functions to the library, you will find that it will be easier to maintain your modified version and to merge updates if you preserve the existing arrangement of functions, which requires no global variables. Rather than defining global variables, consider implementing query functions (global-scope functions that read or write local variables). If you wish to define new types of binary files, consider using the low-level I/O routines in ‘wfdbio.c’ for reading and writing them in a machine-independent format.
Porting the WFDB library to another environment is a straightforward
operation if an ANSI C compiler is available in the target environment.
Since all direct access to database files is performed using the
(private) function wfdb_open
, it is possible to include file name
translation in that function if needed, to accommodate file naming
schemes that may be imposed by the operating system or other
requirements. If the notion of environment variables is foreign to the
target environment, getwfdb
can be modified to read the WFDB path
from a file. You may wish to modify the private function
wfdb_error
(which is responsible for all error reporting from WFDB
library functions) if the ‘standard error output’ is unavailable or
inadequate for use in the target environment. All of these functions are
contained within ‘wfdbio.c’; it is unlikely that any other code will
require changes for a port.
If you encounter errors while compiling ‘signal.c’, you may wish to try
using the functions provided in that file as alternatives to the standard
macros r16
and w16
; the fully-expanded versions of these macros
are quite complex and are known to cause difficulty for at least one (now
obsolete) C compiler. (Define the symbol ‘BROKEN_CC’ while compiling
‘signal.c’ in order to obtain the function versions of r16
and
w16
.) While compiling ‘signal.c’, it may be necessary to disable
code optimization for some C compilers; no current compilers are known to
have such limitations, however.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] |
PhysioNet (wfdb@physionet.org)