file: OLDNEWS.TXT G. Moody 11 August 1993 Last revised: 7 August 1995 Not-so-recent changes in the DB Software Package Copyright (C) Massachusetts Institute of Technology 1995. All rights reserved. This file summarizes changes made to the DB Software Package up to version 9.0. For more recent changes, refer to `NEWS.TXT' and `NEWNEWS.TXT'. ======== Contents ======== A. Changes in the DB library 9.0: new functions getframe(), setgvmode() support for multi-frequency records 8.3: default DB calibration file new annotation codes WFON, WFOFF, PWAVE, TWAVE, UWAVE new annotation mnemonics for PQ, JPT, TCH, NAPC 8.2: alternate structure/constant names in db.h for Solaris compatibility 8.1: bug fix in iannsettime 8.0.1: workaround for ISO 9660 file system warts on Macintosh, HP/UX, ... 8.0: indirect DB path assignment 7.1: porting to Macintosh simplified 7.0.1: bug fixes in annot.c, checksum output in signal.c time_t declaration made conditional on __STDC__ 7.0: C++ bindings added to db.h new annotation codes SYSTOLE, DIASTOLE, MEASURE 6.2.1: format 61 support added 6.2: automatic appending of named directories in header files to DB path 6.1: header and calibration files now use MS-DOS style CR+LF line separators BSD compatibility change in dblib.h simultaneous annotations with different chan fields now permitted 6.0: new functions aduphys, physadu, calopen, getcal, putcal, newcal, flushcal support for calibration files 5.3: new functions ungetann, annstr, strann, setannstr, anndesc, setanndesc support for modification labels 5.2: new functions getcfreq, setcfreq, getbasecount, setbasecount counter format supported by strtim 5.1: baseline and units fields added to signal information structure 5.0: new functions setibsize, setobsize, setheader support for reading signal files with embedded prologs added support for old-style header files removed (`revise' application provided for format conversion) obsolete functions getval, putval, gvskip, gvskp1, gaskip removed 4.5: new function dberror B. Changes in DB applications app: ANSI/AAMI test suite for arrhythmia and ischemia detectors -h (help) option now standard in almost all DB applications new applications ecgeval, epic, mfilt, mxm, plotstm, wrsamp revised command-line syntax in rdann, rdsamp, snip, sqrs, sqrs, sumann, tach, wrann bug fixes in bxb, nst, snip, sqrs, sumstats, view new features in nst, pschart, psfd, sample, tach, view, vsetup contrib:new application macview convert:bug fixes in m2a, md2a support for ECRI floppy disk formats in a2m, ad2m examples: new example refhr C. Other files ============================ A. Changes in the DB library ============================ Changes in version 9.0 ---------------------- The DB library now supports records containing signals digitized at multiple sampling frequencies. A new function, `getframe' (in `signal.c') is used to read the signal files of such records, in much the same way as `getvec'; it returns a `frame' containing one *or more* samples from each signal on each invocation. The sampling frequency of the record is now defined as the number of frames per second; for each signal, a frequency multiplier (attached to the format field in the header file) specifies how many samples are included in each frame. The frequency multiplier must be an integer (1 by default). As always, `getvec' returns exactly one sample per signal on each invocation. It now uses `getframe' to read the signal files, and (by default) averages all samples for each signal in each frame in order to obtain the sample values it returns. Thus existing applications can be used to read multi-frequency records without source changes, once they have been recompiled and linked with the version 9.0 DB library. Another new function, `setgvmode', changes the behavior of `getvec' so that each sample read by `getframe' appears in at least one sample vector returned by `getvec'; in this mode, samples of signals digitized at less than the maximum rate are replicated as necessary (i.e., using zero-order interpolation). This permits existing applications to read multi-frequency records with the highest possible resolution, with only a one-line change in the source. For further details on creating and using multi-frequency records, see `signal.c' (sorry, the Programmer's Guide does not document these features yet.) Many users have requested support for multi-frequency records. If you are among those with an interest, please let me know if this implementation meets your needs. Changes in version 8.3 ---------------------- The symbol DEFDBC is now defined (in `dblib.h') as the name of the default DB calibration file; `calopen' attempts to open this file if the caller does not specify the name of the calibration file to be opened, and if the DBCAL environment variable has not been set. The meanings of the `PQ' and `JPT' annotation codes have been generalized, and new symbols, `WFON' and `WFOFF', have been added to `ecgcodes.h' to reflect the new meanings. These codes are now intended to label the beginning and end of any waveform (of a type specified by the annotation or annotations appearing between WFON and WFOFF). For compatibility with existing software, the symbols `PQ' and `JPT' have been retained as aliases for `WFON' and `WFOFF' respectively. The mnemonics assigned to these codes (as returned by `annstr' and `ecgstr') have been changed (to `(' and `)' respectively) to improve readability. (This change required modifications in `pschart.c' and `psfd.c', since these characters must be treated specially in order to print them using PostScript.) Three new annotation codes (`PWAVE', `TWAVE', and `UWAVE') have been added to `ecgcodes.h', and the code maps in `ecgmap.h' have been updated to reflect these additions. These codes are intended to be used in annotations that mark P-wave, T-wave, and U-wave peaks in the ECG; the corresponding mnemonics are `p', `t', and `u'. The mnemonic for code TCH has been changed from `t' to `T', and that for NAPC has been changed from `p' to `x'. Changes in version 8.2 ---------------------- Namespace conflicts with Solaris 2.x system `.h' files have been resolved by renaming many of the data structures and constants defined in `db.h'. For compatibility with existing code, the old names are retained as aliases for the new ones, unless the symbol SOLARIS is defined. All references to the old names have been updated throughout the DB software package. Changes in version 8.1 ---------------------- A minor bug in `iannsettime' has been fixed; it caused incorrect results if `iannsettime(t)' was called before using `getann' and if the first annotation in the input file was at or after t. Changes in version 8.0.1 ------------------------ Several users have reported problems with reading ISO 9660-format CD-ROMs (such as the second editions of the MIT-BIH Arrhythmia Database and the MIT-BIH Polysomnographic Database CD-ROMs) using the Macintosh OS, HP/UX, and other operating systems that do not strip the ISO 9660 version number suffix (`;1') from CD-ROM file names. These problems do not occur on systems running MS-DOS or SunOS. File `dbio.c' contains a fix for the Macintosh, which may work on other systems as well. See the file `MAC' in this directory for further information. Please report any such problems encountered on other systems to me so I can make a more general fix if one is needed. For other possible solutions, see the file `UNIX' in this directory. Changes in version 8.0 ---------------------- The Eighth Edition of the ECG Database Programmer's Guide does not document the new `indirect' DB path assignment capability introduced in DB library version # 8.0. If the value of DB is of the form `@FILE', the DB path is read from the specified FILE. Indirect DB path files may be nested up to ten levels. A default DB path may be specified at the time the DB library is compiled, by setting DEFDBP in `dblib.h'. See `dbio.c' and `dblib.h' for details. These features were introduced to provide better support for the DB library on the Macintosh, for which the concept of environment variables as in UNIX or MS-DOS is foreign. A sample file to be used for this purpose on the Macintosh is provided as `udb/dbpath.mac'. This feature may also be useful under MS-DOS if the length of the command needed to set the DB path approaches the 128-byte limit for MS-DOS commands. Changes in version 7.1 ---------------------- Several files incorporate changes suggested by Patrick Hamilton to make it simpler to compile the DB library under the Macintosh OS. The symbol MAC, if defined in dblib.h, enables conditional compilation of new support for the Mac in dbio.c. The type previously named `Time' in annot.c, db.h, and signal.c has been renamed `SITime' to avoid a conflict with standard Macintosh header files. If you have written applications that make use of the old `Time' type, change them to use `SITime' instead. Changes in version 7.0.1 ------------------------ A bug in annot.c was corrected. If annopen(), dbquit(), and annopen() were invoked in that order (with no call to getann() before the dbquit(), or with a call to ungetann() immediately before the dbquit()), getann() did not always work properly after the second annopen(). This bug affected DB library versions 5.3 through 7.0. A trivial bug in signal.c was also corrected. On machines with 32-bit ints, newheader() and setheader() wrote signal checksums between 0 and 65535, rather than between -32768 and 32767 (i.e., the checksums were written as if they were 16-bit unsigned ints, rather than as 16-bit signed ints). No serious problems resulted, since both forms are acceptable, irrespective of sizeof(int). To reduce future confusion, however, the code that writes the checksums was modified so that on any machine with 16-bit short ints (including most if not all common 16- and 32-bit machines), checksums will be written in the range between -32768 and 32767, as documented elsewhere. Microsoft C/C++ 7.0 defines time_t (in ) as unsigned long, requiring conditional compilation of the declaration of time() within signal.c (since many UNIX versions of , including those of BSD 4.2, Ultrix, SVR2, and SunOS 4.0.x, do not define time_t at all, and all other known implementations of time() return a signed long). Since time_t must be defined in by ANSI C compilers, the declaration has been made conditional on __STDC__ (a symbol that must be defined by all ANSI C compilers). Changes in version 7.0 ---------------------- C++ bindings have been added in `db.h'. The library sources must still be compiled by a C compiler, but the `#include' files are now compatible with C++ compilers, so that C++ programs may be linked with the DB library. Annotation types SYSTOLE, DIASTOLE, and MEASURE were added (see ). Changes in version 6.2.1 ------------------------ `signal.c' now includes support for format 61 (same as format 16 but with the bytes swapped, i.e., the high byte first in each pair). Changes in version 6.2 ---------------------- If a DB header file specifies that a signal file is to be found in a directory that is not already in the DB path, that directory is appended to the end of the DB path; if the DB path is not set, it is created with an initial null component followed by the directory that contains the signal file. All DB library functions that read header files do so using the private function readheader() (defined in `signal.c'), which invokes another function in `dbio.c' that manipulates the DB path as described. The intent of this is to permit header files from many databases to be collected in a small number of directories (perhaps only one). If the header files are then edited so that absolute pathnames are given for signal files, the directories in which the signal files reside need not be included in the DB path, and annotation files in the same directories can still be found (provided that the header file has been read first). This arrangement may significantly reduce the number of directories to be searched when opening DB files, thereby improving efficiency slightly. It will be especially useful under MS-DOS, to keep the length of the DB environment variable within the MS-DOS-imposed limit even when multiple CD-ROM databases are in use. Although it has been possible to achieve the same result with previous versions of the library, this change means that it is no longer necessary to copy reference annotation files from the CD-ROM directories to do so; the much shorter header files are now sufficient. Changes in version 6.1 ---------------------- Beginning with version 6.1, DB library functions that generate header and calibration files use carriage returns and linefeeds as line separators. Header and calibration files generated by earlier versions of the DB library contain linefeeds without carriage returns; these files remain readable by version 6.1 (and later) functions. Newly-generated files are not completely compatible with programs compiled with older versions of the library; these programs will attach carriage returns to the ends of signal descriptions, and they may not succeed in matching signal descriptions to calibration file entries. This change was made so that header and calibration files can be more easily viewed and edited under MS-DOS. File `dblib.h' now contains a BSD-compatible definition of the ANSI C function `strchr'. Function `putann' now allows annotations with the same time but different `chan' fields to be written to the same file, provided only that such annotations are written in order of their `chan' fields (from smallest to largest). This change was made to support future applications requiring annotation of many signals. Changes in version 6.0 ---------------------- The functions `aduphys', `physadu', `calopen', `getcal', `putcal', `newcal', and `flushcal' were introduced in version 6.0. `aduphys' and `physadu' are similar to the older `adumuv' and `muvadu', but convert between integer sample values and double precision floating point physical values, with correction for non-zero `baseline' values (see the comments below for version 5.1 changes for information about the `baseline' field of the `siginfo' structure). The other new functions manipulate calibration files and `calinfo' (calibration information) structures, which are newly introduced to accommodate signals other than ECGs. `calinfo' structures can be defined for each signal type, and characterize the size and shape of any calibration pulses that may be present as well as the customary scales for plotting the signals. See `doc/dbu.tex' for details on the functions, and `doc/dbcal.5' for a specification of the calibration file format. Changes in version 5.3 ---------------------- The functions `ungetann', `annstr', `strann', `setannstr', `anndesc', and `setanndesc' were introduced in version 5.3. `ungetann' provides a method for pushing an annotation into an input stream, so that the next invocation of `getann' on the specified input stream will return the annotation pushed back by `ungetann'. The pushed-back annotation need not have been read by `getann' originally, but its `aux' field, if not null, must be maintained by the caller until `getann' has been invoked again. `annstr' and `strann' usually behave identically to `ecgstr' and `strecg', but use their own translation table. `anndesc' is similar to `annstr', but its translation table is intended to contain brief descriptions rather than mnemonics. If the `annstr' or `anndesc' translation tables are modified (using `setannstr' or `setanndesc') before calling `annopen', modification labels are written at the beginning of any output annotation files. If `annopen' opens an annotation file containing these modification labels, it modifies the `annstr' and `anndesc' translation tables automatically. Modification labels are encoded as NOTE annotations attached to sample 0; `getann' normally does not return them (since they are read by `annopen'), but they can be read by `getann' if `setanntime' is used to seek to sample 0 first. These features are intended to provide transparent support for custom annotation tables. DB library versions 5.2 and earlier can read annotation files containing modification labels, but the modification labels are treated as ordinary annotations. Changes in version 5.2 ---------------------- The functions `getcfreq', `setcfreq', `getbasecount', and `setbasecount' were introduced in version 5.2. These functions read and set the `counter frequency' and the `base counter value', which specify the basis for converting certain `strtim' arguments into sample intervals. Database records are sometimes obtained from analog tapes for which a tape counter is available. Since many analog tape recorders lack elapsed time indicators, it is often useful to identify events in the analog tape using counter values. To simplify cross-referencing between the analog tape and the digital database record, the DB library now supports conversion of counter values to time. For this to be possible, the counter must be linear (i.e., it must change at the same rate throughout the tape; this is not true of those that count the number of revolutions of the supply or takeup reel), and the base counter value (the counter value corresponding to sample 0) and the counter frequency (the difference between counter values separated by a one-second interval) must be defined. Doing so permits one to use `strtim' to convert tape counter values (passed as string arguments of the form `cNNNN' where `NNNN' is the counter value) to times in units of sample intervals. The counter frequency is reset whenever a header file is read; it can be stored in the header file by appending a `/' and the counter frequency to the sampling frequency field. DB library versions 5.1 and earlier ignore the counter frequency field if it is present in a header file, and return zero if `strtim' is given a `cNNNN'-format argument. See `signal.c' for details. Changes in version 5.1 ---------------------- Two new fields have been added to the signal information (`siginfo') structure. An integer field (`baseline') specifies the amplitude (in adu) that corresponds to the physical zero level of the signal. A character string field (`units') specifies the physical units of the signal. If the `units' field of a `siginfo' structure is NULL, the units are assumed to be millivolts. The definition of the `gain' field has been slightly changed; gain is now defined as the number of ADC units (adu) per physical unit. (Originally, gain was the number of ADC units per millivolt; the new definition simply allows for the possibility of physical units other than millivolts.) In header files, `baseline' values (enclosed in parentheses) and `units' strings (prefixed by '/') are appended to gain specifications, as in these examples: 100(840)/degree_C (100 ADC units per degree Celsius; 0 degrees Celsius is represented by a sample value of 840) 2.531/mmHg (253.1 ADC units per millimeter of mercury; since no baseline is specified, 0 mmHg is represented by the sample value specified by the `adczero' field) 0/ml (an uncalibrated signal with units of milliliters; for purposes of scaling, DEFGAIN ADC units/ml) 400(100) (400 ADC units per millivolt; baseline = 100) 400 (400 ADC units per millivolt; baseline = adczero) As these examples illustrate, the `baseline' and `units' fields are optional; thus existing header files need not be modified. Since these optional fields cannot contain whitespace, pre-version 5.1 DB applications can read header files that contain `baseline' and `units' fields without difficulty (although they cannot retrieve the `baseline' or `units' fields themselves). See `db.h' and `signal.c' for details. Changes in version 5.0 ---------------------- The functions `setibsize', and `setobsize' were introduced in version 5.0. Each takes an integer argument, which specifies the default size (in bytes) for the input or output sample data buffers used by `getvec' and `putvec'. These functions can be used before opening signal files only. Using large buffers can significantly improve the speed of I/O-intensive signal processing applications. See `signal.c' for details. The function `setheader' was also introduced in version 5.0. It takes three arguments: setheader(record, siarray, nsig) char *record struct siginfo siarray[]; unsigned int nsig; and creates or recreates a header file for the specified record containing information from siarray. This function is not intended to take the place of `newheader', which remains the preferred way to generate header files. `setheader' is intended primarily for editing header files, for example to change the gain fields from a calibration program, or to add signal descriptions or info strings. See `signal.c' for details. Support for reading old-style header files has been removed from the DB library as of version 5.0. The `convert' directory contains a program called `revise', which can be used to generate new-style header files from old-style header files. Functions that have been marked as obsolete since version 3.0 (getval, putval, gvskip, gvskp1, and gaskip) have been removed from the DB library as of version 5.0. Support for reading signal files with embedded prologs has been added to the DB library. This feature is described in `header.5' in the `doc' directory. Changes in version 4.5 ---------------------- The function `dberror' was introduced in version 4.5. It takes no arguments, but returns a pointer to a string containing the text of the most recent DB library error message (or to an empty string, if there have been no errors). `dberror' is intended for use in applications for which standard error output is unavailable or inadequate (such as in X window system applications). ============================= B. Changes in DB applications ============================= app/ bxb, rxr, mxm, epic, sumstats, plotstm These programs have been extensively revised, with new capabilities added to support the draft AAMI ambulatory ECG standard of March, 1992 [now an American National Standard: ANSI/AAMI EC38-1994] (they remain compatible with the 1987 AAMI recommended practice). `mxm' is a new program for comparing heart rate or HRV measurements, and `epic' is a new program for performing episode-by-episode comparisons of annotation files to assess VF, AF, and ST episode detection. `plotstm' reads a file of ST measurement comparisons generated by `epic', and produces a scatter plot of them on a PostScript device. Run any of these programs without command-line arguments to get usage summaries, or refer to the `man' pages (bxb.1, rxr.1, mxm.1, epic.1, sumstats.1, plotstm.1) in the `doc' directory. bxb Two bugs that affected shutdown accounting were fixed (thanks to Don Brodnick). calibrate, fir, pschart, psfd, rdann, rdsamp, sigamp, snip, sqrs, sumann, tach, wrann, xform Each of these programs now prints a usage summary if invoked with a `-h' option. The command-line syntax has been revised for `rdann', `rdsamp', `snip', `sqrs', `sumann', `tach', and `wrann' for consistency with other DB applications (see the revised `man' pages in the `doc' directory for details). The `-s' option for `sqrs' now works as documented. The declarations for time() in pschart.c and psfd.c have been changed as noted above for lib/signal.c. A new option, `-M', causes `pschart' to print marker bars for each beat annotation. A new option, `-V', causes `tach' to print the output sample time in seconds before each output sample. ecgeval This new program generates scripts for evaluating ECG analyzers using the programs above. Run it (no command-line arguments are needed) for further information. mfilt This program is new with DB software version 8.1. It performs median filtering on DB signal files. The command syntax is similar to that of fir. nst This program has been completely rewritten for ease of use and flexibility. Among its new features are capabilities to handle records that do not have exactly two signals, and to resample the noise record (using `xform') if its sampling rate does not match that of the ECG record. `nst' can now generate its own protocol annotation file if none is supplied, using `sigamp' to determine signal-to-noise ratios automatically. A bug that caused nst to dump core if it had been compiled using gcc has been fixed. Another bug, reported by Farzin Guilak, caused nst to fail if the current directory was not in the DB path; this bug has also been fixed. A new `-F' option specifies the format of the output signal file generated by `nst'. Format 16 is the default, and is recommended in most cases, since the output range may exceed the range of values representable in most other supported formats. pschart, psfd These programs now include built-in PostScript prologs, which they use if the external prolog files are unreadable. The PSCHARTPRO and PSFDPRO environment variables may still be used to specify a custom prolog if desired. sample `sample' now identifies the type of analog interface board automatically. Digital-to-analog conversion now works reliably at sustained speeds up to 3000 12-bit samples per second from disk or CD-ROM with a DAP 2400/6 (previous versions were limited to about 1200 samples per second). The maximum sustained rate for analog-to-digital conversion to disk files is still about 100000 12-bit samples per second. snip Bugs that caused snip to generate incomplete or empty output annotation files have been fixed. sumstats A bug that resulted in incorrect output if sumstats had been compiled using gcc has been fixed. view, vsetup `vsetup' and `view' now support VESA-compatible SVGAs in 800x600, 1024x768, and 1280x1024 modes (with 16 or 256 colors). These modes must be selected manually (see `view.1' in the `doc' directory for details on this and other new features of `view'). `view' now works properly when the record name is supplied interactively (rather than on the command line). wrsamp This program is new with DB software version 8.1. It converts text files into DB signal files (thus performing the inverse of rdsamp's function). contrib/ macview This program, for viewing DB records on a Macintosh, was contributed by Patrick Hamilton. See the source (macview.c) for details. Thanks, Pat! convert/ a2m, ad2m, m2a, md2a The first two of these programs can now read and reformat AHA DB files as distributed by ECRI on diskettes as well as files in the original tape distribution format. The command syntax has been changed to be more consistent with that of other DB applications. Run these programs without arguments to get usage summaries, or read the new `man' page (`doc/a2m.1') for details. m2a, md2a Bugs that caused incorrect interpretation of the -r option have been fixed. examples/ refhr This new program illustrates how to prepare a reference heart rate annotation file for use with `mxm'. ============== C. Other files ============== udb/ dblist This is a list of available ECG databases, in a format to be read by `ecgeval'. See `doc/ecgval.1' for details. dbpath.mac This file lists the database directories on the MIT-BIH Arrhythmia Database CD-ROM (second edition), in a format suitable for use by DB library-based applications running under the Macintosh OS. mitlist, mitxlist, ahalist, ahaxlist, esclist, nstlist, culist These files are named in `dblist'; each is a complete list of record names from the database with which it is associated in `dblist'.