mirror of
https://github.com/This-weiyuqing/ECG_by_Diffenert_CNN_Test.git
synced 2026-10-19 20:03:39 +08:00
add MIT-BIT
This commit is contained in:
1 parent
fcbea99d01
commit
fdf7d4f840
708 files changed
+11062
-4
No files matched your search
Binary file not shown.
@@ -0,0 +1,46 @@
|
||||
.ce 999
|
||||
.ps 16
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\fBMIT-BIH ARRHYTHMIA DATABASE DIRECTORY
|
||||
|
||||
|
||||
|
||||
|
||||
.ps 14
|
||||
.TS
|
||||
c s
|
||||
l r.
|
||||
Table of Contents
|
||||
|
||||
\fBForeword iii
|
||||
|
||||
Introduction v
|
||||
|
||||
Symbols viii
|
||||
|
||||
\&``Full-Disclosure'' ECG Plots 1
|
||||
|
||||
Examples 98
|
||||
|
||||
Notes 178
|
||||
|
||||
Tables 189
|
||||
|
||||
Index 194
|
||||
.TE
|
||||
Binary file not shown.
@@ -0,0 +1,59 @@
|
||||
.ce 999
|
||||
.ps 12
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\fBHARVARD UNIVERSITY \- MASSACHUSETTS INSTITUTE OF TECHNOLOGY
|
||||
|
||||
DIVISION OF HEALTH SCIENCES AND TECHNOLOGY
|
||||
.ps 24
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
MIT-BIH ARRHYTHMIA DATABASE
|
||||
|
||||
|
||||
|
||||
|
||||
DIRECTORY
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.ps 18
|
||||
JULY 1992
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BMEC TR010 (Revised)
|
||||
@@ -0,0 +1,956 @@
|
||||
/* file: dbnotes.c G. Moody 25 August 1988
|
||||
Last revised: 24 May 1997
|
||||
Create database notes file (HTML format)
|
||||
|
||||
Copyright (C) Massachusetts Institute of Technology 1997. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ecg/db.h>
|
||||
#include <ecg/ecgmap.h>
|
||||
|
||||
/* Rhythm types. These may be rearranged arbitrarily; the order determines
|
||||
the order in which rhythms are printed in the rhythm table. Add a call to
|
||||
`setrtab' and adjust N_RTYPES whenever another rhythm is added. */
|
||||
#define R_UNDEF 0
|
||||
#define NSR 1
|
||||
#define SBR 2
|
||||
#define BII 3
|
||||
#define B22 4
|
||||
#define B3 5
|
||||
#define SAB 6
|
||||
#define PREX 7
|
||||
#define AB 8
|
||||
#define EAR 9
|
||||
#define SVTA 10
|
||||
#define AFL 11
|
||||
#define AFIB 12
|
||||
#define PR 13
|
||||
#define NOD 14
|
||||
#define VBG 15
|
||||
#define VTG 16
|
||||
#define IVR 17
|
||||
#define VT 18
|
||||
#define VFL 19
|
||||
|
||||
#define N_RTYPES 20 /* number of rhythm types, including R_UNDEF */
|
||||
|
||||
/* ST and T change types. */
|
||||
#define STP 0 /* increase in ST level */
|
||||
#define STN 1 /* decrease in ST level */
|
||||
#define TP 2 /* increase in T amplitude */
|
||||
#define TXP 3 /* extreme increase in T amplitude */
|
||||
#define TN 4 /* decrease in T amplitude */
|
||||
#define TXN 5 /* extreme decrease in T amplitude */
|
||||
#define TBP 6 /* biphasic T-wave */
|
||||
|
||||
#define N_STYPES 7 /* number of ST and T change types */
|
||||
|
||||
|
||||
#define PLUS 1 /* positive change */
|
||||
#define MINUS 2 /* negative change */
|
||||
#define XPLUS 3 /* extreme positive change */
|
||||
#define XMINUS 4 /* extreme negative change */
|
||||
#define BIPHASIC 5 /* change to biphasic form */
|
||||
|
||||
#define STCH0 1 /* beginning of ST change episode */
|
||||
#define STCH1 2 /* extremum of ST change */
|
||||
#define STCH2 3 /* end of ST change episode */
|
||||
|
||||
#define TCH0 4 /* beginning of T change episode */
|
||||
#define TCH1 5 /* extremum of T change */
|
||||
#define TCH2 6 /* end of T change episode */
|
||||
|
||||
|
||||
/* Noise type bit masks. */
|
||||
#define C0 0x00 /* signal 0 clean */
|
||||
#define C1 0x00 /* signal 1 clean */
|
||||
#define C2 0x00 /* signal 2 clean */
|
||||
#define C3 0x00 /* signal 3 clean */
|
||||
#define N0 0x01 /* signal 0 noisy */
|
||||
#define N1 0x02 /* signal 1 noisy */
|
||||
#define N2 0x04 /* signal 2 noisy */
|
||||
#define N3 0x08 /* signal 3 noisy */
|
||||
#define U0 0x11 /* signal 0 unreadable */
|
||||
#define U1 0x22 /* signal 1 unreadable */
|
||||
#define U2 0x44 /* signal 2 unreadable */
|
||||
#define U3 0x88 /* signal 3 unreadable */
|
||||
#define UNREADABLE 0xff /* all signals unreadable */
|
||||
|
||||
#define N_NTYPES 256 /* number of noise types */
|
||||
#define N_RLEN 20 /* number of distinct run lengths */
|
||||
|
||||
/* Values for info_type. */
|
||||
#define NO_INFO 0
|
||||
#define MITDB 1
|
||||
#define EDB 2
|
||||
#define VALEDB 3
|
||||
|
||||
struct btabstruct {
|
||||
long lcount; /* number of beats of this type in learning period */
|
||||
long tcount; /* number of beats of this type in test period */
|
||||
} btab[ACMAX+1];
|
||||
|
||||
struct rltabstruct {
|
||||
long len; /* number of beats in run */
|
||||
long nruns; /* number of runs of `len' beats */
|
||||
} artab[N_RLEN], vrtab[N_RLEN];
|
||||
|
||||
struct rtabstruct {
|
||||
long episodes; /* number of episodes of this rhythm */
|
||||
long duration; /* duration of this rhythm (in sample intervals) */
|
||||
char *rstring; /* rhythm string as it appears in annotation file */
|
||||
char *rslong; /* rhythm name as it is printed by this program */
|
||||
int min3r, max3r; /* minimum/maximum length of 3 R-R intervals */
|
||||
} rtab[N_RTYPES];
|
||||
|
||||
struct sttabstruct {
|
||||
long episodes; /* number of episodes of ST or T change of this type */
|
||||
long duration; /* duration of episodes (in sample intervals) */
|
||||
char *ststring; /* description of change as printed by this program */
|
||||
int extremum; /* extreme value of change */
|
||||
} sttab[N_STYPES][MAXSIG];
|
||||
|
||||
struct ntabstruct {
|
||||
long episodes; /* number of episodes of this noise type */
|
||||
long duration; /* duration of this noise type (in sample intervals) */
|
||||
char *nstring; /* noise type as it is printed by this program */
|
||||
} ntab[N_NTYPES];
|
||||
|
||||
long lsum, tsum; /* numbers of beats of all types in the learning and
|
||||
test periods (tallied by `bstats') */
|
||||
long ttest; /* time of the end of the test period */
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
double t3min;
|
||||
int a=0, age, c, i, info_type, magnitude, maxrate, minrate, noise = 0,
|
||||
nsig, rhythm = R_UNDEF, rlen = -1, rr3, sign, st_calibrated = 0,
|
||||
st_data = 0, t_data = 0, type, v=0;
|
||||
static long n0, r0, tq0, tq1, tq2, tq3, s0[N_STYPES][MAXSIG];
|
||||
struct siginfo si[MAXSIG];
|
||||
struct anninfo ai;
|
||||
struct ann annot;
|
||||
static char buf[256], *infop, *p, *record, sex[10], umask;
|
||||
|
||||
/* Check command-line arguments. */
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "usage: %s annotator record\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Open the database files. */
|
||||
ai.name = argv[1]; ai.stat = READ; record = argv[2];
|
||||
if (annopen(record, &ai, 1) < 0 ||
|
||||
(nsig = isigopen(record, si, -MAXSIG)) < 0)
|
||||
exit(2);
|
||||
|
||||
/* Initialize variables. */
|
||||
t3min = strtim("3:0");
|
||||
ttest = strtim("5:0");
|
||||
|
||||
setrtab(R_UNDEF, NULL, "Unspecified rhythm");
|
||||
setrtab(NSR, "N", "Normal sinus rhythm");
|
||||
setrtab(SBR, "SBR", "Sinus bradycardia");
|
||||
setrtab(BII, "BII", "2\\(de heart block");
|
||||
setrtab(B22, "B22", "2\\(de heart block (Mobitz type II)");
|
||||
setrtab(B3, "B3", "3\\(de heart block");
|
||||
setrtab(SAB, "SAB", "Sino-atrial block");
|
||||
setrtab(PREX, "PREX", "Pre-excitation (WPW)");
|
||||
setrtab(AB, "AB", "Atrial bigeminy");
|
||||
setrtab(EAR, "EAR", "Ectopic atrial rhythm");
|
||||
setrtab(SVTA, "SVTA", "SVTA");
|
||||
setrtab(AFL, "AFL", "Atrial flutter");
|
||||
setrtab(AFIB, "AFIB", "Atrial fibrillation");
|
||||
setrtab(PR, "P", "Paced rhythm");
|
||||
setrtab(NOD, "NOD", "Nodal (junctional) rhythm");
|
||||
setrtab(VBG, "B", "Ventricular bigeminy");
|
||||
setrtab(VTG, "T", "Ventricular trigeminy");
|
||||
setrtab(IVR, "IVR", "Idioventricular rhythm");
|
||||
setrtab(VT, "VT", "Ventricular tachycardia");
|
||||
setrtab(VFL, "VFL", "Ventricular flutter");
|
||||
|
||||
for (c = 0; c < nsig; c++) {
|
||||
setstab(STP, c, "Positive ST dev.");
|
||||
setstab(STN, c, "Negative ST dev.");
|
||||
setstab(TP, c, "Positive T dev.");
|
||||
setstab(TXP, c, "T dev. \\(>= 400 \\(*mV");
|
||||
setstab(TN, c, "Negative T dev.");
|
||||
setstab(TXN, c, "T dev. \\(<= \\(mi400 \\(*mV");
|
||||
setstab(TBP, c, "Biphasic T");
|
||||
}
|
||||
|
||||
switch (nsig) {
|
||||
case 1:
|
||||
setntab(C0, "Clean");
|
||||
setntab(N0, "Noisy");
|
||||
setntab(U0, "Unreadable");
|
||||
setntab(UNREADABLE, "Unreadable");
|
||||
umask = U0;
|
||||
break; /* so far, so good ... */
|
||||
case 2:
|
||||
setntab(C0|C1, "Both clean");
|
||||
setntab(C0|N1, "Lower noisy");
|
||||
setntab(C0|U1, "Lower unreadable");
|
||||
setntab(N0|C1, "Upper noisy");
|
||||
setntab(N0|N1, "Both noisy");
|
||||
setntab(N0|U1, "Upper noisy, lower unreadable");
|
||||
setntab(U0|C1, "Upper unreadable");
|
||||
setntab(U0|N1, "Upper unreadable, lower noisy");
|
||||
setntab(U0|U1, "Both unreadable");
|
||||
setntab(UNREADABLE, "Unreadable");
|
||||
umask = U0|U1;
|
||||
break; /* yikes! */
|
||||
case 3:
|
||||
setntab(C0|C1|C2, "All clean");
|
||||
setntab(C0|C1|N2, "Lower noisy");
|
||||
setntab(C0|C1|U2, "Lower unreadable");
|
||||
setntab(C0|N1|C2, "Middle noisy");
|
||||
setntab(C0|N1|N2, "Middle and lower noisy");
|
||||
setntab(C0|N1|U2, "Middle noisy, lower unreadable");
|
||||
setntab(C0|U1|C2, "Middle unreadable");
|
||||
setntab(C0|U1|N2, "Middle unreadable, lower noisy");
|
||||
setntab(C0|U1|U2, "Middle and lower unreadable");
|
||||
setntab(N0|C1|C2, "Upper noisy");
|
||||
setntab(N0|C1|N2, "Upper and lower noisy");
|
||||
setntab(N0|C1|U2, "Upper noisy, lower unreadable");
|
||||
setntab(N0|N1|C2, "Upper and middle noisy");
|
||||
setntab(N0|N1|N2, "All noisy");
|
||||
setntab(N0|N1|U2, "Lower unreadable, others noisy");
|
||||
setntab(N0|U1|C2, "Upper noisy, middle unreadable");
|
||||
setntab(N0|U1|N2, "Middle unreadable, others noisy");
|
||||
setntab(N0|U1|U2, "Upper noisy, others unreadable");
|
||||
setntab(U0|C1|C2, "Upper unreadable");
|
||||
setntab(U0|C1|N2, "Upper unreadable, lower noisy");
|
||||
setntab(U0|C1|U2, "Upper and lower unreadable");
|
||||
setntab(U0|N1|C2, "Upper unreadable, middle noisy");
|
||||
setntab(U0|N1|N2, "Upper unreadable, others noisy");
|
||||
setntab(U0|N1|U2, "Middle noisy, others unreadable");
|
||||
setntab(U0|U1|C2, "Upper and middle unreadable");
|
||||
setntab(U0|U1|N2, "Lower noisy, others unreadable");
|
||||
setntab(U0|U1|U2, "All unreadable");
|
||||
setntab(UNREADABLE, "Unreadable");
|
||||
umask = U0|U1|U2;
|
||||
break; /* arggggh! */
|
||||
/* case 4: nonononononononononono!!!!!!! */
|
||||
default:
|
||||
umask = UNREADABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Read the annotation file. */
|
||||
while (getann(0, &annot) >= 0) {
|
||||
|
||||
/* Count the annotation in the test or learning period as appropriate. */
|
||||
if (annot.time >= ttest) btab[annot.anntyp].tcount++;
|
||||
else btab[annot.anntyp].lcount++;
|
||||
|
||||
if (isqrs(annot.anntyp)) {
|
||||
|
||||
/* Update the ectopic activity tables if appropriate. */
|
||||
switch (map2(annot.anntyp)) {
|
||||
case NORMAL: if (a > 0) { aupdate(a); a = 0; }
|
||||
if (v > 0) { vupdate(v); v = 0; }
|
||||
break;
|
||||
case SVPB: if (v > 0) { vupdate(v); v = 0; }
|
||||
a++;
|
||||
break;
|
||||
case PVC:
|
||||
case FUSION: if (a > 0) { aupdate(a); a = 0; }
|
||||
v++;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Keep track of the times of the last 4 beats. */
|
||||
tq0 = tq1; tq1 = tq2; tq2 = tq3; tq3 = annot.time;
|
||||
|
||||
/* Update the count of consecutive beats in the current rhythm. */
|
||||
rlen++;
|
||||
|
||||
/* Check various conditions which might make a heart rate
|
||||
measurement invalid. */
|
||||
switch (rhythm) {
|
||||
case NSR:
|
||||
case SBR:
|
||||
case BII:
|
||||
case B22:
|
||||
case B3:
|
||||
case SAB:
|
||||
case PREX:
|
||||
if (map2(annot.anntyp) != NORMAL) rlen = -1; break;
|
||||
case AB:
|
||||
case NOD:
|
||||
if (map1(annot.anntyp) != NORMAL) rlen = -1; break;
|
||||
case EAR:
|
||||
case SVTA:
|
||||
if (map2(annot.anntyp) != SVPB) rlen = -1; break;
|
||||
case PR:
|
||||
if (annot.anntyp != PACE) rlen = -1; break;
|
||||
case IVR:
|
||||
case VT:
|
||||
if (map1(annot.anntyp) == NORMAL) rlen = -1; break;
|
||||
case VFL:
|
||||
if (annot.anntyp != FLWAV) rlen = -1; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* If a valid heart rate can be measured, update the records of
|
||||
maximum and minimum rate for the current rhythm. Note that
|
||||
these can be determined from the minimum and maximum R-R
|
||||
intervals; what is actually used here is the sum of three
|
||||
consecutive intervals. */
|
||||
if (rlen >= 3) {
|
||||
rr3 = tq3 - tq0;
|
||||
if (rr3 > rtab[rhythm].max3r) rtab[rhythm].max3r = rr3;
|
||||
if (rr3 < rtab[rhythm].min3r) rtab[rhythm].min3r = rr3;
|
||||
}
|
||||
}
|
||||
else if (annot.anntyp == RHYTHM) {
|
||||
/* Don't count the interval from the beginning of the record to
|
||||
the first rhythm label as `unspecified rhythm' unless the first
|
||||
beat label occurs before the first rhythm label. */
|
||||
if (tq3 > 0L) {
|
||||
rtab[rhythm].episodes++;
|
||||
rtab[rhythm].duration += annot.time - r0;
|
||||
r0 = annot.time;
|
||||
}
|
||||
/* Identify the new rhythm. */
|
||||
for (i = 1, rhythm = R_UNDEF; i < N_RTYPES; i++)
|
||||
if (strcmp(annot.aux+2, rtab[i].rstring) == 0) {
|
||||
rhythm = i;
|
||||
break;
|
||||
}
|
||||
if (rhythm == SVTA || rhythm == VT) rlen = 0;
|
||||
else rlen = -1;
|
||||
}
|
||||
else if (annot.anntyp == STCH || annot.anntyp == TCH) {
|
||||
/* Identify the nature of the ST or T change from the aux field.
|
||||
The syntax of the aux field is one of:
|
||||
"(" <type> [<signal designation>] <sign>
|
||||
"A" <type> [<signal designation>] <sign> [<magnitude>]
|
||||
<type> [<signal designation>] <sign> ")"
|
||||
where <type> is "ST" or "T", <signal designation> is 1 or 2
|
||||
decimal digits, <sign> is "+", "++", "-", "--", or "BP", and
|
||||
<magnitude> is 2-4 decimal digits. ("++" and "--" appear only
|
||||
in T-wave change annotations; they designate extreme (>= 0.4 mV
|
||||
changes in T-wave amplitude.) The signal designation is
|
||||
the signal number (e.g., signal 0 is designated by "0",
|
||||
etc.); in records which contain only one signal (such as those
|
||||
in the VALE DB), the signal designation is omitted. The
|
||||
magnitude is given in microvolts, and may also be omitted (as
|
||||
in the VALE DB).
|
||||
*/
|
||||
if (annot.aux == NULL)
|
||||
fprintf(stderr,
|
||||
"warning: %s annotation without text field at %s\n",
|
||||
ecgstr(annot.anntyp), timstr(annot.time));
|
||||
else {
|
||||
p = annot.aux+1;
|
||||
switch (*p) {
|
||||
case '(':
|
||||
if (annot.anntyp == STCH) {
|
||||
type = STCH0;
|
||||
p += 3; /* skip `(ST' */
|
||||
}
|
||||
else {
|
||||
type = TCH0;
|
||||
p += 2; /* skip `(T' */
|
||||
}
|
||||
break;
|
||||
case 'A':
|
||||
if (annot.anntyp == STCH) {
|
||||
type = STCH1;
|
||||
p += 3; /* skip `(ST' */
|
||||
}
|
||||
else {
|
||||
type = TCH1;
|
||||
p += 2; /* skip `(T' */
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
type = STCH2;
|
||||
p += 2; /* skip `ST' */
|
||||
break;
|
||||
case 'T':
|
||||
type = TCH2;
|
||||
p++; /* skip `T' */
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"warning: %s annotation with text field %s at %s\n",
|
||||
ecgstr(annot.anntyp), annot.aux, timstr(annot.time));
|
||||
type = 0;
|
||||
break;
|
||||
}
|
||||
if (nsig > 1) {
|
||||
if ((c = atoi(p)) > 9) {
|
||||
p++;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
else c = 0;
|
||||
switch (*p++) {
|
||||
case '+':
|
||||
if (*p == '+') {
|
||||
sign = XPLUS;
|
||||
p++;
|
||||
}
|
||||
else
|
||||
sign = PLUS;
|
||||
break;
|
||||
case '-':
|
||||
if (*p == '-') {
|
||||
sign = XMINUS;
|
||||
p++;
|
||||
}
|
||||
else
|
||||
sign = MINUS;
|
||||
break;
|
||||
case 'B':
|
||||
if (*p == 'P') {
|
||||
sign = BIPHASIC;
|
||||
p++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"warning: %s annotation with text field %s at %s\n",
|
||||
ecgstr(annot.anntyp), annot.aux, timstr(annot.time));
|
||||
sign = 0;
|
||||
break;
|
||||
}
|
||||
if (*p && *p != ')') {
|
||||
if ((magnitude = atoi(p)) > 0)
|
||||
st_calibrated = 1;
|
||||
}
|
||||
else magnitude = 0;
|
||||
if (0 <= c && c < MAXSIG) switch (type) {
|
||||
case STCH0: /* beginning of ST change episode */
|
||||
if (sign == PLUS) {
|
||||
st_data = 1;
|
||||
s0[STP][c] = annot.time;
|
||||
}
|
||||
else if (sign == MINUS) {
|
||||
st_data = 1;
|
||||
s0[STN][c] = annot.time;
|
||||
}
|
||||
break;
|
||||
case STCH1: /* extremum of ST change */
|
||||
if (sign == PLUS && magnitude > sttab[STP][c].extremum)
|
||||
sttab[STP][c].extremum = magnitude;
|
||||
else if (sign == MINUS &&
|
||||
magnitude > sttab[STN][c].extremum)
|
||||
sttab[STN][c].extremum = magnitude;
|
||||
break;
|
||||
case STCH2: /* end of ST change episode */
|
||||
if (sign == PLUS) {
|
||||
sttab[STP][c].episodes++;
|
||||
sttab[STP][c].duration += annot.time - s0[STP][c];
|
||||
s0[STP][c] = 0L;
|
||||
}
|
||||
else if (sign == MINUS) {
|
||||
sttab[STN][c].episodes++;
|
||||
sttab[STN][c].duration += annot.time - s0[STN][c];
|
||||
s0[STN][c] = 0L;
|
||||
}
|
||||
break;
|
||||
case TCH0: /* beginning of T change episode */
|
||||
if (sign == PLUS) {
|
||||
t_data = 1;
|
||||
s0[TP][c] = annot.time;
|
||||
}
|
||||
else if (sign == MINUS) {
|
||||
t_data = 1;
|
||||
s0[TN][c] = annot.time;
|
||||
}
|
||||
else if (sign == XPLUS) {
|
||||
t_data = 1;
|
||||
s0[TXP][c] = annot.time;
|
||||
}
|
||||
else if (sign == XMINUS) {
|
||||
t_data = 1;
|
||||
s0[TXN][c] = annot.time;
|
||||
}
|
||||
else if (sign == BIPHASIC) {
|
||||
t_data = 1;
|
||||
s0[TBP][c] = annot.time;
|
||||
}
|
||||
break;
|
||||
case TCH1: /* extremum of T change */
|
||||
if ((sign == PLUS || sign == XPLUS) &&
|
||||
magnitude > sttab[TP][c].extremum)
|
||||
sttab[TP][c].extremum = magnitude;
|
||||
else if ((sign == MINUS || sign == XMINUS) &&
|
||||
magnitude > sttab[TN][c].extremum)
|
||||
sttab[TN][c].extremum = magnitude;
|
||||
break;
|
||||
case TCH2: /* end of T change episode */
|
||||
if (sign == PLUS) {
|
||||
sttab[TP][c].episodes++;
|
||||
sttab[TP][c].duration += annot.time - s0[TP][c];
|
||||
s0[TP][c] = 0L;
|
||||
}
|
||||
else if (sign == MINUS) {
|
||||
sttab[TN][c].episodes++;
|
||||
sttab[TN][c].duration += annot.time - s0[TN][c];
|
||||
s0[TN][c] = 0L;
|
||||
}
|
||||
else if (sign == XPLUS) {
|
||||
sttab[TXP][c].episodes++;
|
||||
sttab[TXP][c].duration += annot.time - s0[TXP][c];
|
||||
s0[TXP][c] = 0L;
|
||||
}
|
||||
else if (sign == XMINUS) {
|
||||
sttab[TXN][c].episodes++;
|
||||
sttab[TXN][c].duration += annot.time - s0[TXN][c];
|
||||
s0[TXN][c] = 0L;
|
||||
}
|
||||
else if (sign == BIPHASIC) {
|
||||
sttab[TBP][c].episodes++;
|
||||
sttab[TBP][c].duration += annot.time - s0[TBP][c];
|
||||
s0[TBP][c] = 0L;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (annot.anntyp == NOISE) {
|
||||
/* Don't count the interval from the beginning of the record to
|
||||
the first signal quality label as `clean' unless the first beat
|
||||
label occurs before the first signal quality label. */
|
||||
if (tq3 > 0L) {
|
||||
ntab[noise].episodes++;
|
||||
ntab[noise].duration += annot.time - n0;
|
||||
n0 = annot.time;
|
||||
}
|
||||
noise = annot.subtyp & 0xff;
|
||||
|
||||
/* Unreadable segments invalidate rate measurements. */
|
||||
if ((noise & umask) == umask) rlen = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* At the end of the annotation file, count any run in progress and adjust
|
||||
the counters for the current rhythm and noise type, and ST and T states.
|
||||
*/
|
||||
if (a) aupdate(a);
|
||||
if (v) aupdate(v);
|
||||
if (strtim("e") > annot.time) annot.time = strtim("e");
|
||||
rtab[rhythm].episodes++;
|
||||
rtab[rhythm].duration += annot.time - r0;
|
||||
for (c = 0; c < nsig; c++) {
|
||||
for (i = 0; i < N_STYPES; i++)
|
||||
if (s0[i][c] > 0L) {
|
||||
sttab[i][c].episodes++;
|
||||
sttab[i][c].duration += annot.time - s0[i][c];
|
||||
}
|
||||
if (sttab[TXP][c].episodes > 0)
|
||||
sttab[TXP][c].extremum = sttab[TP][c].extremum;
|
||||
if (sttab[TXN][c].episodes > 0)
|
||||
sttab[TXN][c].extremum = sttab[TN][c].extremum;
|
||||
}
|
||||
ntab[noise].episodes++;
|
||||
ntab[noise].duration += annot.time - n0;
|
||||
|
||||
/* Read the first line of info, if any. */
|
||||
infop = getinfo(record);
|
||||
if (infop == NULL)
|
||||
info_type = NO_INFO;
|
||||
else {
|
||||
while (*infop == ' ' || *infop == '\t')
|
||||
infop++;
|
||||
if (*infop == 'A') { /* `Age: ...' as in European ST-T DB */
|
||||
sscanf(infop, "Age: %d Sex: %s", &age, sex);
|
||||
info_type = EDB;
|
||||
}
|
||||
else if (*infop == 'R') { /* `Reference: ...' as in VALE DB */
|
||||
age = -1; sex[0] = '?';
|
||||
info_type = VALEDB;
|
||||
}
|
||||
else { /* fixed format as in MIT DB */
|
||||
sscanf(infop, "%d%s", &age, sex);
|
||||
info_type = MITDB;
|
||||
}
|
||||
}
|
||||
|
||||
printf("<h2>Record %s (", record);
|
||||
for (i = 0; i < nsig; i++) {
|
||||
if (i > 0) fputs(", ", stdout);
|
||||
fputs(si[i].desc, stdout);
|
||||
}
|
||||
fputs("; ", stdout);
|
||||
switch (sex[0]) {
|
||||
case 'f':
|
||||
case 'F': fputs("female, age ", stdout); break;
|
||||
case 'm':
|
||||
case 'M': fputs("male, age ", stdout); break;
|
||||
default: fputs("age ", stdout); break;
|
||||
}
|
||||
if (age > 0) printf("%d)</h2>\n", age);
|
||||
else fputs("not recorded)</h2>\n", stdout);
|
||||
|
||||
printf("<p>\n");
|
||||
switch (info_type) {
|
||||
case MITDB:
|
||||
/* Print the medications section (the second line of info). */
|
||||
if (infop = getinfo(NULL)) {
|
||||
while (*infop == ' ' || *infop == '\t')
|
||||
infop++;
|
||||
printf("<i>Medications:</i> %s<br>\n", infop);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Print the beat table. */
|
||||
printf("<p><table>\n");
|
||||
/* printf(".TS\nexpand;\nlw(1i) c c c\nl r r r.\n"); */
|
||||
printf("<tr><th>Beats</th><th>Before 5:00</th><th>After 5:00</th>"
|
||||
"<th>Total</th></tr>\n");
|
||||
/* printf("\\fIBeats\tBefore 5:00\tAfter 5:00\tTotal\\fR\n"); */
|
||||
bstats(NORMAL, "Normal");
|
||||
bstats(LBBB, "Left BBB");
|
||||
bstats(RBBB, "Right BBB");
|
||||
bstats(APC, "APC");
|
||||
bstats(ABERR, "Aberrated APC");
|
||||
bstats(NPC, "Junctional premature");
|
||||
bstats(SVPB, "SVPC");
|
||||
bstats(PVC, "PVC");
|
||||
bstats(RONT, "R-on-T PVC");
|
||||
bstats(FUSION, "Fusion PVC");
|
||||
bstats(FLWAV, "Ventricular flutter wave");
|
||||
bstats(AESC, "Atrial escape");
|
||||
bstats(NESC, "Junctional escape");
|
||||
bstats(SVESC, "Supraventricular escape");
|
||||
bstats(VESC, "Ventricular escape");
|
||||
bstats(PACE, "Paced");
|
||||
bstats(PFUS, "Pacemaker fusion");
|
||||
bstats(NAPC, "Blocked APC");
|
||||
bstats(UNKNOWN, "Unclassifiable");
|
||||
printf("<tr align=right><td>Total</td><td>%ld</td><td>%ld</td>"
|
||||
"<td>%ld</td></tr>\n", lsum, tsum, lsum+tsum);
|
||||
/* printf("\\fITotal\t%ld\t%ld\t%ld\\fR\n", lsum, tsum, lsum+tsum); */
|
||||
printf("</table>\n\n");
|
||||
/* printf(".TE\n.KE\n"); */
|
||||
|
||||
/* Print the supraventricular ectopy table, if necessary. */
|
||||
if (artab[0].len > 1 || artab[0].nruns > 1 || artab[1].len > 0) {
|
||||
int i, j, k, l;
|
||||
|
||||
/* printf(".KS\n.TS\nlw(1.125i) l.\n"); */
|
||||
printf("<p><i>Supraventricular ectopy</i><br>\n<ul>");
|
||||
/* printf("\\fISupraventricular ectopy:\\fR"); */
|
||||
for (i = 0; i < N_RLEN; i++) {
|
||||
for (j = 0, l = 9999; j < N_RLEN; j++)
|
||||
if (0 < artab[j].len && artab[j].len < l) l = artab[k = j].len;
|
||||
if (l == 9999) break;
|
||||
switch (l) {
|
||||
case 1:
|
||||
printf("<li> %d isolated beat%s\n",
|
||||
artab[k].nruns, (artab[k].nruns > 1) ? "s" : "");
|
||||
break;
|
||||
case 2:
|
||||
printf("<li> %d couplet%s\n",
|
||||
artab[k].nruns, (artab[k].nruns > 1) ? "s" : "");
|
||||
break;
|
||||
default:
|
||||
printf("<li> %d run%s of %d beats\n",
|
||||
artab[k].nruns, (artab[k].nruns > 1) ? "s" : "",
|
||||
artab[k].len);
|
||||
break;
|
||||
}
|
||||
artab[k].len = 0;
|
||||
}
|
||||
printf("</ul>\n");
|
||||
/* printf(".TE\n.KE\n"); */
|
||||
}
|
||||
|
||||
/* Print the ventricular ectopy table, if necessary. */
|
||||
if (vrtab[0].len > 1 || vrtab[0].nruns > 1 || vrtab[1].len > 0) {
|
||||
int i, j, k, l;
|
||||
|
||||
/* printf(".KS\n.TS\nlw(1.125i) l.\n"); */
|
||||
printf("<p><i>Ventricular ectopy</i><br>\n<ul>");
|
||||
/* printf("\\fIVentricular ectopy:\\fR"); */
|
||||
for (i = 0; i < N_RLEN; i++) {
|
||||
for (j = 0, l = 9999; j < N_RLEN; j++)
|
||||
if (0 < vrtab[j].len && vrtab[j].len < l) l = vrtab[k = j].len;
|
||||
if (l == 9999) break;
|
||||
switch (l) {
|
||||
case 1:
|
||||
printf("<li> %d isolated beat%s\n",
|
||||
vrtab[k].nruns, (vrtab[k].nruns > 1) ? "s" : "");
|
||||
break;
|
||||
case 2:
|
||||
printf("<li> %d couplet%s\n",
|
||||
vrtab[k].nruns, (vrtab[k].nruns > 1) ? "s" : "");
|
||||
break;
|
||||
default:
|
||||
printf("<li> %d run%s of %d beats\n",
|
||||
vrtab[k].nruns, (vrtab[k].nruns > 1) ? "s" : "",
|
||||
vrtab[k].len);
|
||||
break;
|
||||
}
|
||||
vrtab[k].len = 0;
|
||||
}
|
||||
printf("</ul>\n");
|
||||
/* printf(".TE\n.KE\n"); */
|
||||
}
|
||||
|
||||
/* Print the rhythm table. */
|
||||
printf("<p><table>\n");
|
||||
/* printf(".KS\n.TS\nexpand;\nlw c rw(0.4i) rw(0.4i)\nl c n r.\n"); */
|
||||
printf("<tr><th>Rhythm</th><th>Rate</th><th>Episodes</th>"
|
||||
"<th>Duration</th></tr>\n");
|
||||
/* printf("\\fIRhythm\tRate\tEpisodes\tDuration\\fR\n"); */
|
||||
for (i = 0; i < N_RTYPES; i++)
|
||||
if (rtab[i].episodes != 0L) {
|
||||
printf("<tr><td>%s</td><td align=center>", rtab[i].rslong);
|
||||
if (rtab[i].max3r > 0)
|
||||
printf("%d", minrate = (int)(t3min/rtab[i].max3r + 0.5));
|
||||
else
|
||||
minrate = 0;
|
||||
if (rtab[i].min3r != 0xffff) {
|
||||
maxrate = (int)(t3min/rtab[i].min3r + 0.5);
|
||||
if (maxrate > minrate) printf("-%d", maxrate);
|
||||
}
|
||||
else if (minrate == 0)
|
||||
printf("-");
|
||||
printf("</td><td align=right>%ld</td><td align=right>%s</td>"
|
||||
"</tr>\n", rtab[i].episodes, timstr(rtab[i].duration));
|
||||
}
|
||||
printf("</table>\n\n");
|
||||
/* printf(".TE\n.KE\n"); */
|
||||
|
||||
/* Print the ST and T-change table, if available. */
|
||||
if (st_data || t_data) {
|
||||
printf(".KS\n.TS\nexpand;\nl");
|
||||
if (st_calibrated) printf(" r");
|
||||
printf(" rw(0.4i) rw(0.4i)\nl");
|
||||
if (st_calibrated) printf(" n");
|
||||
printf(" n r.\n\\fIST\\-T state");
|
||||
if (st_calibrated) printf("\tExtremum");
|
||||
printf("\tEpisodes\tDuration\\fR\n");
|
||||
for (c = 0; c < nsig; c++) {
|
||||
int header_printed = 0;
|
||||
|
||||
for (i = 0; i < N_STYPES; i++) {
|
||||
if (sttab[i][c].episodes != 0L) {
|
||||
if (header_printed == 0) {
|
||||
switch (nsig) {
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
if (c == 0) printf("\\fI(upper signal)\\fR\n");
|
||||
else printf("\\fI(lower signal)\\fR\n");
|
||||
break;
|
||||
case 3:
|
||||
if (c == 0) printf("\\fI(upper signal)\\fR\n");
|
||||
else if (c == 1)
|
||||
printf("\\fI(middle signal)\\fR\n");
|
||||
else printf("\\fI(lower signal)\\fR\n");
|
||||
break;
|
||||
default:
|
||||
printf("(signal %d)\n", c);
|
||||
break;
|
||||
}
|
||||
header_printed = 1;
|
||||
}
|
||||
printf("%s\t", sttab[i][c].ststring);
|
||||
if (st_calibrated) {
|
||||
if (sttab[i][c].extremum > 0) {
|
||||
switch (i) {
|
||||
case STP:
|
||||
case TP:
|
||||
case TXP: printf("\\(pl"); break;
|
||||
case STN:
|
||||
case TN:
|
||||
case TXN: printf("\\(mi"); break;
|
||||
}
|
||||
printf("%d\t", sttab[i][c].extremum);
|
||||
}
|
||||
else
|
||||
printf("\\-\t");
|
||||
}
|
||||
printf("%ld\t%s\n", sttab[i][c].episodes,
|
||||
timstr(sttab[i][c].duration));
|
||||
}
|
||||
}
|
||||
}
|
||||
printf(".TE\n.KE\n");
|
||||
}
|
||||
|
||||
/* Print the signal quality table. */
|
||||
printf("<p><table>\n");
|
||||
/* printf(".KS\n.TS\nexpand;\nl rw(0.4i) rw(0.4i)\nl n r.\n"); */
|
||||
printf("<tr><th>Signal quality</th><th>Episodes</th>"
|
||||
"<th>Duration</th></tr>\n");
|
||||
/* printf("\\fISignal quality\tEpisodes\tDuration\\fR\n"); */
|
||||
for (i = 0; i < N_NTYPES; i++)
|
||||
if (ntab[i].episodes != 0L) {
|
||||
if (ntab[i].nstring == NULL) {
|
||||
static char ns[40];
|
||||
|
||||
sprintf(ns, "Signal quality code %d", i);
|
||||
ntab[i].nstring = ns;
|
||||
}
|
||||
printf("<tr><td>%s</td><td align=right>%ld</td>"
|
||||
"<td align=right>%s</td></tr>\n",
|
||||
ntab[i].nstring, ntab[i].episodes,
|
||||
timstr(ntab[i].duration));
|
||||
}
|
||||
printf ("</table>\n\n");
|
||||
/* printf(".TE\n"); */ /* (the "keep" ends after the "notes" section) */
|
||||
|
||||
/* Print a "notes" section if there is any additional info available. */
|
||||
switch (info_type) {
|
||||
case EDB:
|
||||
if (infop = getinfo(NULL)) {
|
||||
while (*infop == ' ' || *infop == '\t')
|
||||
infop++;
|
||||
if ('a' <= *infop && *infop <= 'z') *infop += 'A' - 'a';
|
||||
printf("<p><dl><dt>Notes:</dt>\n<dd>%s", infop);
|
||||
while (infop = getinfo(NULL)) {
|
||||
while (*infop == ' ' || *infop == '\t')
|
||||
infop++;
|
||||
printf("<br>\n%s", infop);
|
||||
}
|
||||
printf("</dd></dl>\n");
|
||||
}
|
||||
/* else
|
||||
printf(".LP\n"); */
|
||||
break;
|
||||
case MITDB:
|
||||
if (infop = getinfo(NULL)) {
|
||||
while (*infop == ' ' || *infop == '\t')
|
||||
infop++;
|
||||
printf("<p><dl><dt>Notes:</dt>\n<dd>%s\n", infop);
|
||||
while (infop = getinfo(NULL)) {
|
||||
while (*infop == ' ' || *infop == '\t')
|
||||
infop++;
|
||||
printf("%s\n", infop);
|
||||
}
|
||||
printf("</dd></dl>\n");
|
||||
}
|
||||
/* else
|
||||
printf(".LP\n"); */
|
||||
break;
|
||||
case VALEDB:
|
||||
if (infop = getinfo(NULL)) {
|
||||
while (*infop == ' ' || *infop == '\t')
|
||||
infop++;
|
||||
if (strncmp(infop, "Reference:", 10) == 0)
|
||||
infop = getinfo(NULL);
|
||||
}
|
||||
if (infop) {
|
||||
while (*infop == ' ' || *infop == '\t')
|
||||
infop++;
|
||||
printf(".IP \\fINotes:\\fR .375i\n%s\n", infop);
|
||||
while (infop = getinfo(NULL)) {
|
||||
while (*infop == ' ' || *infop == '\t')
|
||||
infop++;
|
||||
printf(".br\n%s\n", infop);
|
||||
}
|
||||
}
|
||||
else
|
||||
printf(".LP\n");
|
||||
break;
|
||||
default:
|
||||
printf(".LP\n");
|
||||
break;
|
||||
}
|
||||
/* printf(".KE\n"); */
|
||||
|
||||
/* Close the database files and quit. */
|
||||
dbquit();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
setrtab(i, rst, rsl)
|
||||
int i;
|
||||
char *rst, *rsl;
|
||||
{
|
||||
if (0 <= i && i < N_RTYPES) {
|
||||
rtab[i].episodes = 0L;
|
||||
rtab[i].duration = strtim("0.5");
|
||||
rtab[i].rstring = rst;
|
||||
rtab[i].rslong = rsl;
|
||||
rtab[i].min3r = 0xffff;
|
||||
rtab[i].max3r = 0;
|
||||
}
|
||||
}
|
||||
|
||||
setstab(i, signal, sst)
|
||||
int i, signal;
|
||||
char *sst;
|
||||
{
|
||||
if (0 <= i && i < N_STYPES && 0 <= signal && signal < MAXSIG) {
|
||||
sttab[i][signal].episodes = 0L;
|
||||
sttab[i][signal].duration = strtim("0.5");
|
||||
sttab[i][signal].ststring = sst;
|
||||
sttab[i][signal].extremum = 0;
|
||||
}
|
||||
}
|
||||
|
||||
setntab(i, nst)
|
||||
int i;
|
||||
char *nst;
|
||||
{
|
||||
if (0 <= i && i < N_NTYPES) {
|
||||
ntab[i].episodes = 0L;
|
||||
ntab[i].duration = strtim("0.5");
|
||||
ntab[i].nstring = nst;
|
||||
}
|
||||
}
|
||||
|
||||
bstats(i, s) /* print a line of the beat table if beats of type i were seen */
|
||||
int i;
|
||||
char *s; /* English description of beat type i */
|
||||
{
|
||||
if (btab[i].tcount > 0L || btab[i].lcount > 0L) {
|
||||
printf("<tr align=right><td>%s</td>", s);
|
||||
if (btab[i].lcount > 0L) {
|
||||
printf("<td>%ld</td>", btab[i].lcount);
|
||||
lsum += btab[i].lcount;
|
||||
}
|
||||
else
|
||||
printf("<td>-</td>");
|
||||
if (btab[i].tcount > 0L) {
|
||||
printf("<td>%ld</td>", btab[i].tcount);
|
||||
tsum += btab[i].tcount;
|
||||
}
|
||||
else
|
||||
printf("<td>-</td>");
|
||||
printf("<td>%ld</td></tr>\n", btab[i].lcount + btab[i].tcount);
|
||||
}
|
||||
}
|
||||
|
||||
aupdate(i) /* Record that an i-beat SV run was observed */
|
||||
int i;
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < N_RLEN-1; j++) {
|
||||
if (artab[j].len == i) break;
|
||||
else if (artab[j].len == 0) { artab[j].len = i; break; }
|
||||
}
|
||||
artab[j].nruns++;
|
||||
}
|
||||
|
||||
vupdate(i) /* Record that an i-beat V run was observed */
|
||||
int i;
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < N_RLEN-1; j++) {
|
||||
if (vrtab[j].len == i) break;
|
||||
else if (vrtab[j].len == 0) { vrtab[j].len = i; break; }
|
||||
}
|
||||
vrtab[j].nruns++;
|
||||
}
|
||||
@@ -0,0 +1,936 @@
|
||||
/* file: dbnotes.c G. Moody 25 August 1988
|
||||
Last revised: 6 December 1990
|
||||
Create database notes file (tbl/troff input format)
|
||||
|
||||
Copyright (C) Massachusetts Institute of Technology 1990. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ecg/db.h>
|
||||
#include <ecg/ecgmap.h>
|
||||
|
||||
/* Rhythm types. These may be rearranged arbitrarily; the order determines
|
||||
the order in which rhythms are printed in the rhythm table. Add a call to
|
||||
`setrtab' and adjust N_RTYPES whenever another rhythm is added. */
|
||||
#define R_UNDEF 0
|
||||
#define NSR 1
|
||||
#define SBR 2
|
||||
#define BII 3
|
||||
#define B22 4
|
||||
#define B3 5
|
||||
#define SAB 6
|
||||
#define PREX 7
|
||||
#define AB 8
|
||||
#define EAR 9
|
||||
#define SVTA 10
|
||||
#define AFL 11
|
||||
#define AFIB 12
|
||||
#define PR 13
|
||||
#define NOD 14
|
||||
#define VBG 15
|
||||
#define VTG 16
|
||||
#define IVR 17
|
||||
#define VT 18
|
||||
#define VFL 19
|
||||
|
||||
#define N_RTYPES 20 /* number of rhythm types, including R_UNDEF */
|
||||
|
||||
/* ST and T change types. */
|
||||
#define STP 0 /* increase in ST level */
|
||||
#define STN 1 /* decrease in ST level */
|
||||
#define TP 2 /* increase in T amplitude */
|
||||
#define TXP 3 /* extreme increase in T amplitude */
|
||||
#define TN 4 /* decrease in T amplitude */
|
||||
#define TXN 5 /* extreme decrease in T amplitude */
|
||||
#define TBP 6 /* biphasic T-wave */
|
||||
|
||||
#define N_STYPES 7 /* number of ST and T change types */
|
||||
|
||||
|
||||
#define PLUS 1 /* positive change */
|
||||
#define MINUS 2 /* negative change */
|
||||
#define XPLUS 3 /* extreme positive change */
|
||||
#define XMINUS 4 /* extreme negative change */
|
||||
#define BIPHASIC 5 /* change to biphasic form */
|
||||
|
||||
#define STCH0 1 /* beginning of ST change episode */
|
||||
#define STCH1 2 /* extremum of ST change */
|
||||
#define STCH2 3 /* end of ST change episode */
|
||||
|
||||
#define TCH0 4 /* beginning of T change episode */
|
||||
#define TCH1 5 /* extremum of T change */
|
||||
#define TCH2 6 /* end of T change episode */
|
||||
|
||||
|
||||
/* Noise type bit masks. */
|
||||
#define C0 0x00 /* signal 0 clean */
|
||||
#define C1 0x00 /* signal 1 clean */
|
||||
#define C2 0x00 /* signal 2 clean */
|
||||
#define C3 0x00 /* signal 3 clean */
|
||||
#define N0 0x01 /* signal 0 noisy */
|
||||
#define N1 0x02 /* signal 1 noisy */
|
||||
#define N2 0x04 /* signal 2 noisy */
|
||||
#define N3 0x08 /* signal 3 noisy */
|
||||
#define U0 0x11 /* signal 0 unreadable */
|
||||
#define U1 0x22 /* signal 1 unreadable */
|
||||
#define U2 0x44 /* signal 2 unreadable */
|
||||
#define U3 0x88 /* signal 3 unreadable */
|
||||
#define UNREADABLE 0xff /* all signals unreadable */
|
||||
|
||||
#define N_NTYPES 256 /* number of noise types */
|
||||
#define N_RLEN 20 /* number of distinct run lengths */
|
||||
|
||||
/* Values for info_type. */
|
||||
#define NO_INFO 0
|
||||
#define MITDB 1
|
||||
#define EDB 2
|
||||
#define VALEDB 3
|
||||
|
||||
struct btabstruct {
|
||||
long lcount; /* number of beats of this type in learning period */
|
||||
long tcount; /* number of beats of this type in test period */
|
||||
} btab[ACMAX+1];
|
||||
|
||||
struct rltabstruct {
|
||||
long len; /* number of beats in run */
|
||||
long nruns; /* number of runs of `len' beats */
|
||||
} artab[N_RLEN], vrtab[N_RLEN];
|
||||
|
||||
struct rtabstruct {
|
||||
long episodes; /* number of episodes of this rhythm */
|
||||
long duration; /* duration of this rhythm (in sample intervals) */
|
||||
char *rstring; /* rhythm string as it appears in annotation file */
|
||||
char *rslong; /* rhythm name as it is printed by this program */
|
||||
int min3r, max3r; /* minimum/maximum length of 3 R-R intervals */
|
||||
} rtab[N_RTYPES];
|
||||
|
||||
struct sttabstruct {
|
||||
long episodes; /* number of episodes of ST or T change of this type */
|
||||
long duration; /* duration of episodes (in sample intervals) */
|
||||
char *ststring; /* description of change as printed by this program */
|
||||
int extremum; /* extreme value of change */
|
||||
} sttab[N_STYPES][MAXSIG];
|
||||
|
||||
struct ntabstruct {
|
||||
long episodes; /* number of episodes of this noise type */
|
||||
long duration; /* duration of this noise type (in sample intervals) */
|
||||
char *nstring; /* noise type as it is printed by this program */
|
||||
} ntab[N_NTYPES];
|
||||
|
||||
long lsum, tsum; /* numbers of beats of all types in the learning and
|
||||
test periods (tallied by `bstats') */
|
||||
long ttest; /* time of the end of the test period */
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
double t3min;
|
||||
int a=0, age, c, i, info_type, magnitude, maxrate, minrate, noise = 0,
|
||||
nsig, rhythm = R_UNDEF, rlen = -1, rr3, sign, st_calibrated = 0,
|
||||
st_data = 0, t_data = 0, type, v=0;
|
||||
static long n0, r0, tq0, tq1, tq2, tq3, s0[N_STYPES][MAXSIG];
|
||||
struct siginfo si[MAXSIG];
|
||||
struct anninfo ai;
|
||||
struct ann annot;
|
||||
static char buf[256], *infop, *p, *record, sex[10], umask;
|
||||
|
||||
/* Check command-line arguments. */
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "usage: %s annotator record\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Open the database files. */
|
||||
ai.name = argv[1]; ai.stat = READ; record = argv[2];
|
||||
if (annopen(record, &ai, 1) < 0 ||
|
||||
(nsig = isigopen(record, si, -MAXSIG)) < 0)
|
||||
exit(2);
|
||||
|
||||
/* Initialize variables. */
|
||||
t3min = strtim("3:0");
|
||||
ttest = strtim("5:0");
|
||||
|
||||
setrtab(R_UNDEF, NULL, "Unspecified rhythm");
|
||||
setrtab(NSR, "N", "Normal sinus rhythm");
|
||||
setrtab(SBR, "SBR", "Sinus bradycardia");
|
||||
setrtab(BII, "BII", "2\\(de heart block");
|
||||
setrtab(B22, "B22", "2\\(de heart block (Mobitz type II)");
|
||||
setrtab(B3, "B3", "3\\(de heart block");
|
||||
setrtab(SAB, "SAB", "Sino-atrial block");
|
||||
setrtab(PREX, "PREX", "Pre-excitation (WPW)");
|
||||
setrtab(AB, "AB", "Atrial bigeminy");
|
||||
setrtab(EAR, "EAR", "Ectopic atrial rhythm");
|
||||
setrtab(SVTA, "SVTA", "SVTA");
|
||||
setrtab(AFL, "AFL", "Atrial flutter");
|
||||
setrtab(AFIB, "AFIB", "Atrial fibrillation");
|
||||
setrtab(PR, "P", "Paced rhythm");
|
||||
setrtab(NOD, "NOD", "Nodal (junctional) rhythm");
|
||||
setrtab(VBG, "B", "Ventricular bigeminy");
|
||||
setrtab(VTG, "T", "Ventricular trigeminy");
|
||||
setrtab(IVR, "IVR", "Idioventricular rhythm");
|
||||
setrtab(VT, "VT", "Ventricular tachycardia");
|
||||
setrtab(VFL, "VFL", "Ventricular flutter");
|
||||
|
||||
for (c = 0; c < nsig; c++) {
|
||||
setstab(STP, c, "Positive ST dev.");
|
||||
setstab(STN, c, "Negative ST dev.");
|
||||
setstab(TP, c, "Positive T dev.");
|
||||
setstab(TXP, c, "T dev. \\(>= 400 \\(*mV");
|
||||
setstab(TN, c, "Negative T dev.");
|
||||
setstab(TXN, c, "T dev. \\(<= \\(mi400 \\(*mV");
|
||||
setstab(TBP, c, "Biphasic T");
|
||||
}
|
||||
|
||||
switch (nsig) {
|
||||
case 1:
|
||||
setntab(C0, "Clean");
|
||||
setntab(N0, "Noisy");
|
||||
setntab(U0, "Unreadable");
|
||||
setntab(UNREADABLE, "Unreadable");
|
||||
umask = U0;
|
||||
break; /* so far, so good ... */
|
||||
case 2:
|
||||
setntab(C0|C1, "Both clean");
|
||||
setntab(C0|N1, "Lower noisy");
|
||||
setntab(C0|U1, "Lower unreadable");
|
||||
setntab(N0|C1, "Upper noisy");
|
||||
setntab(N0|N1, "Both noisy");
|
||||
setntab(N0|U1, "Upper noisy, lower unreadable");
|
||||
setntab(U0|C1, "Upper unreadable");
|
||||
setntab(U0|N1, "Upper unreadable, lower noisy");
|
||||
setntab(U0|U1, "Both unreadable");
|
||||
setntab(UNREADABLE, "Unreadable");
|
||||
umask = U0|U1;
|
||||
break; /* yikes! */
|
||||
case 3:
|
||||
setntab(C0|C1|C2, "All clean");
|
||||
setntab(C0|C1|N2, "Lower noisy");
|
||||
setntab(C0|C1|U2, "Lower unreadable");
|
||||
setntab(C0|N1|C2, "Middle noisy");
|
||||
setntab(C0|N1|N2, "Middle and lower noisy");
|
||||
setntab(C0|N1|U2, "Middle noisy, lower unreadable");
|
||||
setntab(C0|U1|C2, "Middle unreadable");
|
||||
setntab(C0|U1|N2, "Middle unreadable, lower noisy");
|
||||
setntab(C0|U1|U2, "Middle and lower unreadable");
|
||||
setntab(N0|C1|C2, "Upper noisy");
|
||||
setntab(N0|C1|N2, "Upper and lower noisy");
|
||||
setntab(N0|C1|U2, "Upper noisy, lower unreadable");
|
||||
setntab(N0|N1|C2, "Upper and middle noisy");
|
||||
setntab(N0|N1|N2, "All noisy");
|
||||
setntab(N0|N1|U2, "Lower unreadable, others noisy");
|
||||
setntab(N0|U1|C2, "Upper noisy, middle unreadable");
|
||||
setntab(N0|U1|N2, "Middle unreadable, others noisy");
|
||||
setntab(N0|U1|U2, "Upper noisy, others unreadable");
|
||||
setntab(U0|C1|C2, "Upper unreadable");
|
||||
setntab(U0|C1|N2, "Upper unreadable, lower noisy");
|
||||
setntab(U0|C1|U2, "Upper and lower unreadable");
|
||||
setntab(U0|N1|C2, "Upper unreadable, middle noisy");
|
||||
setntab(U0|N1|N2, "Upper unreadable, others noisy");
|
||||
setntab(U0|N1|U2, "Middle noisy, others unreadable");
|
||||
setntab(U0|U1|C2, "Upper and middle unreadable");
|
||||
setntab(U0|U1|N2, "Lower noisy, others unreadable");
|
||||
setntab(U0|U1|U2, "All unreadable");
|
||||
setntab(UNREADABLE, "Unreadable");
|
||||
umask = U0|U1|U2;
|
||||
break; /* arggggh! */
|
||||
/* case 4: nonononononononononono!!!!!!! */
|
||||
default:
|
||||
umask = UNREADABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Read the annotation file. */
|
||||
while (getann(0, &annot) >= 0) {
|
||||
|
||||
/* Count the annotation in the test or learning period as appropriate. */
|
||||
if (annot.time >= ttest) btab[annot.anntyp].tcount++;
|
||||
else btab[annot.anntyp].lcount++;
|
||||
|
||||
if (isqrs(annot.anntyp)) {
|
||||
|
||||
/* Update the ectopic activity tables if appropriate. */
|
||||
switch (map2(annot.anntyp)) {
|
||||
case NORMAL: if (a > 0) { aupdate(a); a = 0; }
|
||||
if (v > 0) { vupdate(v); v = 0; }
|
||||
break;
|
||||
case SVPB: if (v > 0) { vupdate(v); v = 0; }
|
||||
a++;
|
||||
break;
|
||||
case PVC:
|
||||
case FUSION: if (a > 0) { aupdate(a); a = 0; }
|
||||
v++;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Keep track of the times of the last 4 beats. */
|
||||
tq0 = tq1; tq1 = tq2; tq2 = tq3; tq3 = annot.time;
|
||||
|
||||
/* Update the count of consecutive beats in the current rhythm. */
|
||||
rlen++;
|
||||
|
||||
/* Check various conditions which might make a heart rate
|
||||
measurement invalid. */
|
||||
switch (rhythm) {
|
||||
case NSR:
|
||||
case SBR:
|
||||
case BII:
|
||||
case B22:
|
||||
case B3:
|
||||
case SAB:
|
||||
case PREX:
|
||||
if (map2(annot.anntyp) != NORMAL) rlen = -1; break;
|
||||
case AB:
|
||||
case NOD:
|
||||
if (map1(annot.anntyp) != NORMAL) rlen = -1; break;
|
||||
case EAR:
|
||||
case SVTA:
|
||||
if (map2(annot.anntyp) != SVPB) rlen = -1; break;
|
||||
case PR:
|
||||
if (annot.anntyp != PACE) rlen = -1; break;
|
||||
case IVR:
|
||||
case VT:
|
||||
if (map1(annot.anntyp) == NORMAL) rlen = -1; break;
|
||||
case VFL:
|
||||
if (annot.anntyp != FLWAV) rlen = -1; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* If a valid heart rate can be measured, update the records of
|
||||
maximum and minimum rate for the current rhythm. Note that
|
||||
these can be determined from the minimum and maximum R-R
|
||||
intervals; what is actually used here is the sum of three
|
||||
consecutive intervals. */
|
||||
if (rlen >= 3) {
|
||||
rr3 = tq3 - tq0;
|
||||
if (rr3 > rtab[rhythm].max3r) rtab[rhythm].max3r = rr3;
|
||||
if (rr3 < rtab[rhythm].min3r) rtab[rhythm].min3r = rr3;
|
||||
}
|
||||
}
|
||||
else if (annot.anntyp == RHYTHM) {
|
||||
/* Don't count the interval from the beginning of the record to
|
||||
the first rhythm label as `unspecified rhythm' unless the first
|
||||
beat label occurs before the first rhythm label. */
|
||||
if (tq3 > 0L) {
|
||||
rtab[rhythm].episodes++;
|
||||
rtab[rhythm].duration += annot.time - r0;
|
||||
r0 = annot.time;
|
||||
}
|
||||
/* Identify the new rhythm. */
|
||||
for (i = 1, rhythm = R_UNDEF; i < N_RTYPES; i++)
|
||||
if (strcmp(annot.aux+2, rtab[i].rstring) == 0) {
|
||||
rhythm = i;
|
||||
break;
|
||||
}
|
||||
if (rhythm == SVTA || rhythm == VT) rlen = 0;
|
||||
else rlen = -1;
|
||||
}
|
||||
else if (annot.anntyp == STCH || annot.anntyp == TCH) {
|
||||
/* Identify the nature of the ST or T change from the aux field.
|
||||
The syntax of the aux field is one of:
|
||||
"(" <type> [<signal designation>] <sign>
|
||||
"A" <type> [<signal designation>] <sign> [<magnitude>]
|
||||
<type> [<signal designation>] <sign> ")"
|
||||
where <type> is "ST" or "T", <signal designation> is 1 or 2
|
||||
decimal digits, <sign> is "+", "++", "-", "--", or "BP", and
|
||||
<magnitude> is 2-4 decimal digits. ("++" and "--" appear only
|
||||
in T-wave change annotations; they designate extreme (>= 0.4 mV
|
||||
changes in T-wave amplitude.) The signal designation is
|
||||
the signal number (e.g., signal 0 is designated by "0",
|
||||
etc.); in records which contain only one signal (such as those
|
||||
in the VALE DB), the signal designation is omitted. The
|
||||
magnitude is given in microvolts, and may also be omitted (as
|
||||
in the VALE DB).
|
||||
*/
|
||||
if (annot.aux == NULL)
|
||||
fprintf(stderr,
|
||||
"warning: %s annotation without text field at %s\n",
|
||||
ecgstr(annot.anntyp), timstr(annot.time));
|
||||
else {
|
||||
p = annot.aux+1;
|
||||
switch (*p) {
|
||||
case '(':
|
||||
if (annot.anntyp == STCH) {
|
||||
type = STCH0;
|
||||
p += 3; /* skip `(ST' */
|
||||
}
|
||||
else {
|
||||
type = TCH0;
|
||||
p += 2; /* skip `(T' */
|
||||
}
|
||||
break;
|
||||
case 'A':
|
||||
if (annot.anntyp == STCH) {
|
||||
type = STCH1;
|
||||
p += 3; /* skip `(ST' */
|
||||
}
|
||||
else {
|
||||
type = TCH1;
|
||||
p += 2; /* skip `(T' */
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
type = STCH2;
|
||||
p += 2; /* skip `ST' */
|
||||
break;
|
||||
case 'T':
|
||||
type = TCH2;
|
||||
p++; /* skip `T' */
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"warning: %s annotation with text field %s at %s\n",
|
||||
ecgstr(annot.anntyp), annot.aux, timstr(annot.time));
|
||||
type = 0;
|
||||
break;
|
||||
}
|
||||
if (nsig > 1) {
|
||||
if ((c = atoi(p)) > 9) {
|
||||
p++;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
else c = 0;
|
||||
switch (*p++) {
|
||||
case '+':
|
||||
if (*p == '+') {
|
||||
sign = XPLUS;
|
||||
p++;
|
||||
}
|
||||
else
|
||||
sign = PLUS;
|
||||
break;
|
||||
case '-':
|
||||
if (*p == '-') {
|
||||
sign = XMINUS;
|
||||
p++;
|
||||
}
|
||||
else
|
||||
sign = MINUS;
|
||||
break;
|
||||
case 'B':
|
||||
if (*p == 'P') {
|
||||
sign = BIPHASIC;
|
||||
p++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"warning: %s annotation with text field %s at %s\n",
|
||||
ecgstr(annot.anntyp), annot.aux, timstr(annot.time));
|
||||
sign = 0;
|
||||
break;
|
||||
}
|
||||
if (*p && *p != ')') {
|
||||
if ((magnitude = atoi(p)) > 0)
|
||||
st_calibrated = 1;
|
||||
}
|
||||
else magnitude = 0;
|
||||
if (0 <= c && c < MAXSIG) switch (type) {
|
||||
case STCH0: /* beginning of ST change episode */
|
||||
if (sign == PLUS) {
|
||||
st_data = 1;
|
||||
s0[STP][c] = annot.time;
|
||||
}
|
||||
else if (sign == MINUS) {
|
||||
st_data = 1;
|
||||
s0[STN][c] = annot.time;
|
||||
}
|
||||
break;
|
||||
case STCH1: /* extremum of ST change */
|
||||
if (sign == PLUS && magnitude > sttab[STP][c].extremum)
|
||||
sttab[STP][c].extremum = magnitude;
|
||||
else if (sign == MINUS &&
|
||||
magnitude > sttab[STN][c].extremum)
|
||||
sttab[STN][c].extremum = magnitude;
|
||||
break;
|
||||
case STCH2: /* end of ST change episode */
|
||||
if (sign == PLUS) {
|
||||
sttab[STP][c].episodes++;
|
||||
sttab[STP][c].duration += annot.time - s0[STP][c];
|
||||
s0[STP][c] = 0L;
|
||||
}
|
||||
else if (sign == MINUS) {
|
||||
sttab[STN][c].episodes++;
|
||||
sttab[STN][c].duration += annot.time - s0[STN][c];
|
||||
s0[STN][c] = 0L;
|
||||
}
|
||||
break;
|
||||
case TCH0: /* beginning of T change episode */
|
||||
if (sign == PLUS) {
|
||||
t_data = 1;
|
||||
s0[TP][c] = annot.time;
|
||||
}
|
||||
else if (sign == MINUS) {
|
||||
t_data = 1;
|
||||
s0[TN][c] = annot.time;
|
||||
}
|
||||
else if (sign == XPLUS) {
|
||||
t_data = 1;
|
||||
s0[TXP][c] = annot.time;
|
||||
}
|
||||
else if (sign == XMINUS) {
|
||||
t_data = 1;
|
||||
s0[TXN][c] = annot.time;
|
||||
}
|
||||
else if (sign == BIPHASIC) {
|
||||
t_data = 1;
|
||||
s0[TBP][c] = annot.time;
|
||||
}
|
||||
break;
|
||||
case TCH1: /* extremum of T change */
|
||||
if ((sign == PLUS || sign == XPLUS) &&
|
||||
magnitude > sttab[TP][c].extremum)
|
||||
sttab[TP][c].extremum = magnitude;
|
||||
else if ((sign == MINUS || sign == XMINUS) &&
|
||||
magnitude > sttab[TN][c].extremum)
|
||||
sttab[TN][c].extremum = magnitude;
|
||||
break;
|
||||
case TCH2: /* end of T change episode */
|
||||
if (sign == PLUS) {
|
||||
sttab[TP][c].episodes++;
|
||||
sttab[TP][c].duration += annot.time - s0[TP][c];
|
||||
s0[TP][c] = 0L;
|
||||
}
|
||||
else if (sign == MINUS) {
|
||||
sttab[TN][c].episodes++;
|
||||
sttab[TN][c].duration += annot.time - s0[TN][c];
|
||||
s0[TN][c] = 0L;
|
||||
}
|
||||
else if (sign == XPLUS) {
|
||||
sttab[TXP][c].episodes++;
|
||||
sttab[TXP][c].duration += annot.time - s0[TXP][c];
|
||||
s0[TXP][c] = 0L;
|
||||
}
|
||||
else if (sign == XMINUS) {
|
||||
sttab[TXN][c].episodes++;
|
||||
sttab[TXN][c].duration += annot.time - s0[TXN][c];
|
||||
s0[TXN][c] = 0L;
|
||||
}
|
||||
else if (sign == BIPHASIC) {
|
||||
sttab[TBP][c].episodes++;
|
||||
sttab[TBP][c].duration += annot.time - s0[TBP][c];
|
||||
s0[TBP][c] = 0L;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (annot.anntyp == NOISE) {
|
||||
/* Don't count the interval from the beginning of the record to
|
||||
the first signal quality label as `clean' unless the first beat
|
||||
label occurs before the first signal quality label. */
|
||||
if (tq3 > 0L) {
|
||||
ntab[noise].episodes++;
|
||||
ntab[noise].duration += annot.time - n0;
|
||||
n0 = annot.time;
|
||||
}
|
||||
noise = annot.subtyp & 0xff;
|
||||
|
||||
/* Unreadable segments invalidate rate measurements. */
|
||||
if ((noise & umask) == umask) rlen = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* At the end of the annotation file, count any run in progress and adjust
|
||||
the counters for the current rhythm and noise type, and ST and T states.
|
||||
*/
|
||||
if (a) aupdate(a);
|
||||
if (v) aupdate(v);
|
||||
if (strtim("e") > annot.time) annot.time = strtim("e");
|
||||
rtab[rhythm].episodes++;
|
||||
rtab[rhythm].duration += annot.time - r0;
|
||||
for (c = 0; c < nsig; c++) {
|
||||
for (i = 0; i < N_STYPES; i++)
|
||||
if (s0[i][c] > 0L) {
|
||||
sttab[i][c].episodes++;
|
||||
sttab[i][c].duration += annot.time - s0[i][c];
|
||||
}
|
||||
if (sttab[TXP][c].episodes > 0)
|
||||
sttab[TXP][c].extremum = sttab[TP][c].extremum;
|
||||
if (sttab[TXN][c].episodes > 0)
|
||||
sttab[TXN][c].extremum = sttab[TN][c].extremum;
|
||||
}
|
||||
ntab[noise].episodes++;
|
||||
ntab[noise].duration += annot.time - n0;
|
||||
|
||||
/* Read the first line of info, if any. */
|
||||
infop = getinfo(record);
|
||||
if (infop == NULL)
|
||||
info_type = NO_INFO;
|
||||
else {
|
||||
while (*infop == ' ' || *infop == '\t')
|
||||
infop++;
|
||||
if (*infop == 'A') { /* `Age: ...' as in European ST-T DB */
|
||||
sscanf(infop, "Age: %d Sex: %s", &age, sex);
|
||||
info_type = EDB;
|
||||
}
|
||||
else if (*infop == 'R') { /* `Reference: ...' as in VALE DB */
|
||||
age = -1; sex[0] = '?';
|
||||
info_type = VALEDB;
|
||||
}
|
||||
else { /* fixed format as in MIT DB */
|
||||
sscanf(infop, "%d%s", &age, sex);
|
||||
info_type = MITDB;
|
||||
}
|
||||
}
|
||||
|
||||
/* Start a "keep" (to force troff to print the following section in a
|
||||
single column), and print the section header line. */
|
||||
printf(".KS\n.SH\n");
|
||||
|
||||
printf("Record %s (", record);
|
||||
for (i = 0; i < nsig; i++) {
|
||||
if (i > 0) fputs(", ", stdout);
|
||||
fputs(si[i].desc, stdout);
|
||||
}
|
||||
fputs("; ", stdout);
|
||||
switch (sex[0]) {
|
||||
case 'f':
|
||||
case 'F': fputs("female, age ", stdout); break;
|
||||
case 'm':
|
||||
case 'M': fputs("male, age ", stdout); break;
|
||||
default: fputs("age ", stdout); break;
|
||||
}
|
||||
if (age > 0) printf("%d)\n", age);
|
||||
else fputs("not recorded)\n", stdout);
|
||||
|
||||
switch (info_type) {
|
||||
case MITDB:
|
||||
/* Print the medications section (the second line of info). */
|
||||
if (infop = getinfo(NULL)) {
|
||||
while (*infop == ' ' || *infop == '\t')
|
||||
infop++;
|
||||
printf(".LP\n\\fIMedications:\\fR %s\n", infop);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Print the beat table. */
|
||||
printf(".TS\nexpand;\nlw(1i) c c c\nl r r r.\n");
|
||||
printf("\\fIBeats\tBefore 5:00\tAfter 5:00\tTotal\\fR\n");
|
||||
bstats(NORMAL, "Normal");
|
||||
bstats(LBBB, "Left BBB");
|
||||
bstats(RBBB, "Right BBB");
|
||||
bstats(APC, "APC");
|
||||
bstats(ABERR, "Aberrated APC");
|
||||
bstats(NPC, "Junctional premature");
|
||||
bstats(SVPB, "SVPC");
|
||||
bstats(PVC, "PVC");
|
||||
bstats(RONT, "R-on-T PVC");
|
||||
bstats(FUSION, "Fusion PVC");
|
||||
bstats(FLWAV, "Ventricular flutter wave");
|
||||
bstats(AESC, "Atrial escape");
|
||||
bstats(NESC, "Junctional escape");
|
||||
bstats(SVESC, "Supraventricular escape");
|
||||
bstats(VESC, "Ventricular escape");
|
||||
bstats(PACE, "Paced");
|
||||
bstats(PFUS, "Pacemaker fusion");
|
||||
bstats(NAPC, "Blocked APC");
|
||||
bstats(UNKNOWN, "Unclassifiable");
|
||||
printf("\\fITotal\t%ld\t%ld\t%ld\\fR\n", lsum, tsum, lsum+tsum);
|
||||
printf(".TE\n.KE\n");
|
||||
|
||||
/* Print the supraventricular ectopy table, if necessary. */
|
||||
if (artab[0].len > 1 || artab[0].nruns > 1 || artab[1].len > 0) {
|
||||
int i, j, k, l;
|
||||
|
||||
printf(".KS\n.TS\nlw(1.125i) l.\n");
|
||||
printf("\\fISupraventricular ectopy:\\fR");
|
||||
for (i = 0; i < N_RLEN; i++) {
|
||||
for (j = 0, l = 9999; j < N_RLEN; j++)
|
||||
if (0 < artab[j].len && artab[j].len < l) l = artab[k = j].len;
|
||||
if (l == 9999) break;
|
||||
switch (l) {
|
||||
case 1:
|
||||
printf("\t%d isolated beat%s\n",
|
||||
artab[k].nruns, (artab[k].nruns > 1) ? "s" : "");
|
||||
break;
|
||||
case 2:
|
||||
printf("\t%d couplet%s\n",
|
||||
artab[k].nruns, (artab[k].nruns > 1) ? "s" : "");
|
||||
break;
|
||||
default:
|
||||
printf("\t%d run%s of %d beats\n",
|
||||
artab[k].nruns, (artab[k].nruns > 1) ? "s" : "",
|
||||
artab[k].len);
|
||||
break;
|
||||
}
|
||||
artab[k].len = 0;
|
||||
}
|
||||
printf(".TE\n.KE\n");
|
||||
}
|
||||
|
||||
/* Print the ventricular ectopy table, if necessary. */
|
||||
if (vrtab[0].len > 1 || vrtab[0].nruns > 1 || vrtab[1].len > 0) {
|
||||
int i, j, k, l;
|
||||
|
||||
printf(".KS\n.TS\nlw(1.125i) l.\n");
|
||||
printf("\\fIVentricular ectopy:\\fR");
|
||||
for (i = 0; i < N_RLEN; i++) {
|
||||
for (j = 0, l = 9999; j < N_RLEN; j++)
|
||||
if (0 < vrtab[j].len && vrtab[j].len < l) l = vrtab[k = j].len;
|
||||
if (l == 9999) break;
|
||||
switch (l) {
|
||||
case 1:
|
||||
printf("\t%d isolated beat%s\n",
|
||||
vrtab[k].nruns, (vrtab[k].nruns > 1) ? "s" : "");
|
||||
break;
|
||||
case 2:
|
||||
printf("\t%d couplet%s\n",
|
||||
vrtab[k].nruns, (vrtab[k].nruns > 1) ? "s" : "");
|
||||
break;
|
||||
default:
|
||||
printf("\t%d run%s of %d beats\n",
|
||||
vrtab[k].nruns, (vrtab[k].nruns > 1) ? "s" : "",
|
||||
vrtab[k].len);
|
||||
break;
|
||||
}
|
||||
vrtab[k].len = 0;
|
||||
}
|
||||
printf(".TE\n.KE\n");
|
||||
}
|
||||
|
||||
/* Print the rhythm table. */
|
||||
printf(".KS\n.TS\nexpand;\nlw c rw(0.4i) rw(0.4i)\nl c n r.\n");
|
||||
printf("\\fIRhythm\tRate\tEpisodes\tDuration\\fR\n");
|
||||
for (i = 0; i < N_RTYPES; i++)
|
||||
if (rtab[i].episodes != 0L) {
|
||||
printf("%s\t", rtab[i].rslong);
|
||||
if (rtab[i].max3r > 0)
|
||||
printf("%d", minrate = (int)(t3min/rtab[i].max3r + 0.5));
|
||||
else
|
||||
minrate = 0;
|
||||
if (rtab[i].min3r != 0xffff) {
|
||||
maxrate = (int)(t3min/rtab[i].min3r + 0.5);
|
||||
if (maxrate > minrate) printf("\\-%d", maxrate);
|
||||
}
|
||||
else if (minrate == 0)
|
||||
printf("\\-");
|
||||
printf("\t%ld\t%s\n", rtab[i].episodes, timstr(rtab[i].duration));
|
||||
}
|
||||
printf(".TE\n.KE\n");
|
||||
|
||||
/* Print the ST and T-change table, if available. */
|
||||
if (st_data || t_data) {
|
||||
printf(".KS\n.TS\nexpand;\nl");
|
||||
if (st_calibrated) printf(" r");
|
||||
printf(" rw(0.4i) rw(0.4i)\nl");
|
||||
if (st_calibrated) printf(" n");
|
||||
printf(" n r.\n\\fIST\\-T state");
|
||||
if (st_calibrated) printf("\tExtremum");
|
||||
printf("\tEpisodes\tDuration\\fR\n");
|
||||
for (c = 0; c < nsig; c++) {
|
||||
int header_printed = 0;
|
||||
|
||||
for (i = 0; i < N_STYPES; i++) {
|
||||
if (sttab[i][c].episodes != 0L) {
|
||||
if (header_printed == 0) {
|
||||
switch (nsig) {
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
if (c == 0) printf("\\fI(upper signal)\\fR\n");
|
||||
else printf("\\fI(lower signal)\\fR\n");
|
||||
break;
|
||||
case 3:
|
||||
if (c == 0) printf("\\fI(upper signal)\\fR\n");
|
||||
else if (c == 1)
|
||||
printf("\\fI(middle signal)\\fR\n");
|
||||
else printf("\\fI(lower signal)\\fR\n");
|
||||
break;
|
||||
default:
|
||||
printf("(signal %d)\n", c);
|
||||
break;
|
||||
}
|
||||
header_printed = 1;
|
||||
}
|
||||
printf("%s\t", sttab[i][c].ststring);
|
||||
if (st_calibrated) {
|
||||
if (sttab[i][c].extremum > 0) {
|
||||
switch (i) {
|
||||
case STP:
|
||||
case TP:
|
||||
case TXP: printf("\\(pl"); break;
|
||||
case STN:
|
||||
case TN:
|
||||
case TXN: printf("\\(mi"); break;
|
||||
}
|
||||
printf("%d\t", sttab[i][c].extremum);
|
||||
}
|
||||
else
|
||||
printf("\\-\t");
|
||||
}
|
||||
printf("%ld\t%s\n", sttab[i][c].episodes,
|
||||
timstr(sttab[i][c].duration));
|
||||
}
|
||||
}
|
||||
}
|
||||
printf(".TE\n.KE\n");
|
||||
}
|
||||
|
||||
/* Print the signal quality table. */
|
||||
printf(".KS\n.TS\nexpand;\nl rw(0.4i) rw(0.4i)\nl n r.\n");
|
||||
printf("\\fISignal quality\tEpisodes\tDuration\\fR\n");
|
||||
for (i = 0; i < N_NTYPES; i++)
|
||||
if (ntab[i].episodes != 0L) {
|
||||
if (ntab[i].nstring == NULL) {
|
||||
static char ns[40];
|
||||
|
||||
sprintf(ns, "Signal quality code %d", i);
|
||||
ntab[i].nstring = ns;
|
||||
}
|
||||
printf("%s\t%ld\t%s\n", ntab[i].nstring, ntab[i].episodes,
|
||||
timstr(ntab[i].duration));
|
||||
}
|
||||
printf(".TE\n"); /* (the "keep" ends after the "notes" section) */
|
||||
|
||||
/* Print a "notes" section if there is any additional info available. */
|
||||
switch (info_type) {
|
||||
case EDB:
|
||||
if (infop = getinfo(NULL)) {
|
||||
while (*infop == ' ' || *infop == '\t')
|
||||
infop++;
|
||||
if ('a' <= *infop && *infop <= 'z') *infop += 'A' - 'a';
|
||||
printf(".IP \\fINotes:\\fR .375i\n%s\n", infop);
|
||||
while (infop = getinfo(NULL)) {
|
||||
while (*infop == ' ' || *infop == '\t')
|
||||
infop++;
|
||||
printf(".br\n%s\n", infop);
|
||||
}
|
||||
}
|
||||
else
|
||||
printf(".LP\n");
|
||||
break;
|
||||
case MITDB:
|
||||
if (infop = getinfo(NULL)) {
|
||||
while (*infop == ' ' || *infop == '\t')
|
||||
infop++;
|
||||
printf(".IP \\fINotes:\\fR .375i\n%s\n", infop);
|
||||
while (infop = getinfo(NULL)) {
|
||||
while (*infop == ' ' || *infop == '\t')
|
||||
infop++;
|
||||
printf("%s\n", infop);
|
||||
}
|
||||
}
|
||||
else
|
||||
printf(".LP\n");
|
||||
break;
|
||||
case VALEDB:
|
||||
if (infop = getinfo(NULL)) {
|
||||
while (*infop == ' ' || *infop == '\t')
|
||||
infop++;
|
||||
if (strncmp(infop, "Reference:", 10) == 0)
|
||||
infop = getinfo(NULL);
|
||||
}
|
||||
if (infop) {
|
||||
while (*infop == ' ' || *infop == '\t')
|
||||
infop++;
|
||||
printf(".IP \\fINotes:\\fR .375i\n%s\n", infop);
|
||||
while (infop = getinfo(NULL)) {
|
||||
while (*infop == ' ' || *infop == '\t')
|
||||
infop++;
|
||||
printf(".br\n%s\n", infop);
|
||||
}
|
||||
}
|
||||
else
|
||||
printf(".LP\n");
|
||||
break;
|
||||
default:
|
||||
printf(".LP\n");
|
||||
break;
|
||||
}
|
||||
printf(".KE\n");
|
||||
|
||||
/* Close the database files and quit. */
|
||||
dbquit();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
setrtab(i, rst, rsl)
|
||||
int i;
|
||||
char *rst, *rsl;
|
||||
{
|
||||
if (0 <= i && i < N_RTYPES) {
|
||||
rtab[i].episodes = 0L;
|
||||
rtab[i].duration = strtim("0.5");
|
||||
rtab[i].rstring = rst;
|
||||
rtab[i].rslong = rsl;
|
||||
rtab[i].min3r = 0xffff;
|
||||
rtab[i].max3r = 0;
|
||||
}
|
||||
}
|
||||
|
||||
setstab(i, signal, sst)
|
||||
int i, signal;
|
||||
char *sst;
|
||||
{
|
||||
if (0 <= i && i < N_STYPES && 0 <= signal && signal < MAXSIG) {
|
||||
sttab[i][signal].episodes = 0L;
|
||||
sttab[i][signal].duration = strtim("0.5");
|
||||
sttab[i][signal].ststring = sst;
|
||||
sttab[i][signal].extremum = 0;
|
||||
}
|
||||
}
|
||||
|
||||
setntab(i, nst)
|
||||
int i;
|
||||
char *nst;
|
||||
{
|
||||
if (0 <= i && i < N_NTYPES) {
|
||||
ntab[i].episodes = 0L;
|
||||
ntab[i].duration = strtim("0.5");
|
||||
ntab[i].nstring = nst;
|
||||
}
|
||||
}
|
||||
|
||||
bstats(i, s) /* print a line of the beat table if beats of type i were seen */
|
||||
int i;
|
||||
char *s; /* English description of beat type i */
|
||||
{
|
||||
if (btab[i].tcount > 0L || btab[i].lcount > 0L) {
|
||||
printf("%s\t", s);
|
||||
if (btab[i].lcount > 0L) {
|
||||
printf("%ld\t", btab[i].lcount);
|
||||
lsum += btab[i].lcount;
|
||||
}
|
||||
else
|
||||
printf("\\-\t");
|
||||
if (btab[i].tcount > 0L) {
|
||||
printf("%ld\t", btab[i].tcount);
|
||||
tsum += btab[i].tcount;
|
||||
}
|
||||
else
|
||||
printf("\\-\t");
|
||||
printf("%ld\n", btab[i].lcount + btab[i].tcount);
|
||||
}
|
||||
}
|
||||
|
||||
aupdate(i) /* Record that an i-beat SV run was observed */
|
||||
int i;
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < N_RLEN-1; j++) {
|
||||
if (artab[j].len == i) break;
|
||||
else if (artab[j].len == 0) { artab[j].len = i; break; }
|
||||
}
|
||||
artab[j].nruns++;
|
||||
}
|
||||
|
||||
vupdate(i) /* Record that an i-beat V run was observed */
|
||||
int i;
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < N_RLEN-1; j++) {
|
||||
if (vrtab[j].len == i) break;
|
||||
else if (vrtab[j].len == 0) { vrtab[j].len = i; break; }
|
||||
}
|
||||
vrtab[j].nruns++;
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/* file: dbtab.c G. Moody 25 August 1988
|
||||
Last revised: 22 July 1992
|
||||
Add a line to the database summary table
|
||||
|
||||
Copyright (C) Massachusetts Institute of Technology 1992. All rights reserved.
|
||||
|
||||
This program generates tabular data that are eventually stuffed into a
|
||||
tbl/troff format file to be printed in the MIT-BIH Arrhythmia Database
|
||||
Directory. The code is *not* pretty. Sorry about that...
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ecg/db.h>
|
||||
#include <ecg/ecgmap.h>
|
||||
|
||||
/* Rhythm codes. These may be rearranged arbitrarily, but the table rstring[]
|
||||
must be kept in agreement. The order of these codes determines the order
|
||||
in which rhythms are printed in the rhythm table. */
|
||||
#define NSR 1
|
||||
#define SBR 2
|
||||
#define BII 3
|
||||
#define PREX 4
|
||||
#define AB 5
|
||||
#define SVTA 6
|
||||
#define AFL 7
|
||||
#define AFIB 8
|
||||
#define PR 9
|
||||
#define NOD 10
|
||||
#define VBG 11
|
||||
#define VTG 12
|
||||
#define IVR 13
|
||||
#define VT 14
|
||||
#define VFL 15
|
||||
|
||||
#define MAXR 15 /* largest assigned rhythm code */
|
||||
|
||||
static char *rstring[] = { /* rhythm strings in DB annotation files */
|
||||
"", "N", "SBR", "BII", "PREX",
|
||||
"AB", "SVTA", "AFL", "AFIB", "P",
|
||||
"NOD", "B", "T", "IVR", "VT",
|
||||
"VFL" };
|
||||
|
||||
/* Beat tables and counters: the number of beats of annotation type i during
|
||||
the learning period (first 5 minutes) is ltab[i], and during the test period
|
||||
(the remainder of the record) is ttab[i]; bstats() accumulates the sum of
|
||||
all elements of ltab[] in lsum, and the sum of all elements of ttab[] in
|
||||
tsum. */
|
||||
static long ltab[ACMAX+1], ttab[ACMAX+1], lsum, tsum;
|
||||
static int tflag = 0;
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int i, rhythm = 0;
|
||||
long r0 = 0L;
|
||||
static struct siginfo si[MAXSIG];
|
||||
struct anninfo af[1];
|
||||
struct ann annot;
|
||||
static char *tape;
|
||||
static long rtab[MAXR+2], rtime[MAXR+2], ttest;
|
||||
|
||||
/* Check command-line arguments. */
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "usage: %s annotator tape [-t]\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Open the database files. */
|
||||
af[0].name = argv[1]; af[0].stat = READ; tape = argv[2];
|
||||
if (dbinit(tape, af, 1, si, MAXSIG) < 0)
|
||||
exit(2);
|
||||
|
||||
/* Initialize variables. */
|
||||
ttest = strtim("5:0");
|
||||
rtime[0] = strtim("0.5");
|
||||
for (i = 1; i <= MAXR; i++)
|
||||
rtime[i] = rtime[0];
|
||||
|
||||
/* If specified, skip the learning period. */
|
||||
if (argc > 3 && strcmp("-t", argv[3]) == 0) {
|
||||
tflag = 1;
|
||||
r0 = ttest;
|
||||
}
|
||||
/* Read the annotation file. */
|
||||
while (getann(0, &annot) >= 0) {
|
||||
|
||||
/* Count the annotation in the test or learning period as appropriate. */
|
||||
if (annot.time >= ttest) ttab[annot.anntyp]++;
|
||||
else ltab[annot.anntyp]++;
|
||||
|
||||
if (annot.anntyp == RHYTHM) {
|
||||
if (rhythm) { /* This condition is true except for the first
|
||||
rhythm label. For the second and subsequent
|
||||
rhythm labels, update the number of episodes
|
||||
and duration of the rhythm just ended. */
|
||||
if (annot.time > r0) {
|
||||
rtab[rhythm]++;
|
||||
rtime[rhythm] += annot.time - r0;
|
||||
r0 = annot.time;
|
||||
}
|
||||
}
|
||||
/* Identify the new rhythm. */
|
||||
for (i = 1, rhythm = MAXR+1; i <= MAXR; i++)
|
||||
if (strcmp(annot.aux+2, rstring[i]) == 0) {
|
||||
rhythm = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* At the end of the annotation file, adjust the counter for the current
|
||||
rhythm. */
|
||||
if (si[0].nsamp > annot.time) annot.time = si[0].nsamp;
|
||||
if (rhythm) {
|
||||
rtab[rhythm]++;
|
||||
rtime[rhythm] += annot.time - r0;
|
||||
}
|
||||
|
||||
printf("%s", tape);
|
||||
|
||||
/* Print the beat table. */
|
||||
bstats(NORMAL);
|
||||
bstats(LBBB);
|
||||
bstats(RBBB);
|
||||
bstats(APC);
|
||||
bstats(ABERR);
|
||||
bstats(NPC);
|
||||
bstats(SVPB);
|
||||
bstats(PVC);
|
||||
bstats(FUSION);
|
||||
bstats(FLWAV);
|
||||
bstats(AESC);
|
||||
bstats(NESC);
|
||||
bstats(VESC);
|
||||
bstats(PACE);
|
||||
bstats(PFUS);
|
||||
bstats(NAPC);
|
||||
bstats(UNKNOWN);
|
||||
|
||||
/* Print the rhythm table. */
|
||||
for (i = 1; i <= MAXR; i++)
|
||||
if (rtab[i] != 0L)
|
||||
printf("\t%s", timstr(rtime[i]));
|
||||
else
|
||||
printf("\t\\-");
|
||||
printf("\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
bstats(i) /* print an entry in the beat table */
|
||||
int i;
|
||||
{
|
||||
if (tflag) ltab[i] = 0L;
|
||||
if (ltab[i] > 0L || ttab[i] > 0L)
|
||||
printf("\t%ld", ltab[i]+ttab[i]);
|
||||
else printf("\t\\-");
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
trap "" 1 15
|
||||
COMMAND=$1
|
||||
shift
|
||||
for R in 100 101 102 103 104 105 106 107 108 109 111 112 113 114 115 116 117 \
|
||||
118 119 121 122 123 124 200 201 202 203 205 207 208 209 210 212 213 214 215 \
|
||||
217 219 220 221 222 223 228 230 231 232 233 234
|
||||
do
|
||||
$COMMAND $R $*
|
||||
done
|
||||
@@ -0,0 +1,469 @@
|
||||
100 11:03 Normal sinus rhythm
|
||||
100 25:13 PVC
|
||||
100 26:09 APCs
|
||||
100 27:55 Normal sinus rhythm
|
||||
101 1:34 Normal sinus rhythm
|
||||
|
||||
101 1:48 Noise
|
||||
101 5:13 Noise/artifact
|
||||
101 9:54 APC
|
||||
101 24:32 APC
|
||||
102 0:55 Paced rhythm
|
||||
|
||||
102 1:12 Transition from paced to normal sinus rhythm
|
||||
102 1:28 PVC
|
||||
102 2:30 Normal sinus rhythm
|
||||
102 4:51 Pacemaker fusion beats
|
||||
102 9:35 PVC
|
||||
|
||||
102 16:12 Paced rhythm
|
||||
103 1:09 Normal sinus rhythm
|
||||
103 17:21 Normal sinus rhythm
|
||||
103 19:15 APC, noise in lower signal
|
||||
103 22:13 Noise in lower signal
|
||||
|
||||
103 23:33 Noise in lower signal
|
||||
103 28:58 Noise in lower signal
|
||||
104 3:42 PVC
|
||||
104 5:13 Noise
|
||||
104 5:52 Transition from paced to normal sinus rhythm
|
||||
|
||||
104 6:17 Noise
|
||||
104 8:22 Noise in lower signal
|
||||
104 26:51 Paced, normal, and pacemaker fusion beats
|
||||
104 29:10 Paced, normal, and pacemaker fusion beats
|
||||
105 5:27 Artifact
|
||||
|
||||
105 7:57 PVC
|
||||
105 15:16 Normal sinus rhythm
|
||||
105 17:52 Artifacts
|
||||
105 22:02 Noise
|
||||
105 26:45 PVC
|
||||
|
||||
105 27:27 Noise
|
||||
105 28:08 Noise
|
||||
105 29:07 Noise
|
||||
106 0:19 Normal sinus rhythm, noise in lower signal
|
||||
106 1:37 Ventricular couplets
|
||||
|
||||
106 2:53 Ventricular tachycardia, 3 beats
|
||||
106 4:23 PVC
|
||||
106 7:57 Noise in lower signal
|
||||
106 10:52 Noise in lower signal
|
||||
106 12:27 Ventricular bigeminy (two types)
|
||||
|
||||
106 16:17 Multiform PVCs, ventricular couplet
|
||||
106 25:13 Ventricular couplet
|
||||
106 25:52 Ventricular couplets
|
||||
107 0:44 Paced rhythm
|
||||
107 12:30 PVC
|
||||
|
||||
107 19:54 PVC
|
||||
107 20:38 Noise
|
||||
107 25:52 PVC
|
||||
108 0:22 PVC, blocked APC, noise
|
||||
108 4:51 Interpolated PVC
|
||||
|
||||
108 7:41 Axis shift
|
||||
108 8:13 PVC, blocked APC, fusion PVC
|
||||
108 10:55 Sinus arrhythmia
|
||||
108 18:08 Fusion PVC-PVC couplet
|
||||
108 20:05 Junctional escape beat
|
||||
|
||||
108 24:20 Blocked APC, APCs
|
||||
108 28:10 Noise
|
||||
108 29:00 Noise
|
||||
109 0:13 Fusion PVC
|
||||
109 1:28 PVC
|
||||
|
||||
109 3:36 Normal sinus rhythm with left bundle branch block
|
||||
109 4:46 PVC
|
||||
109 5:27 Noise
|
||||
109 14:01 PVC
|
||||
109 17:13 PVC
|
||||
|
||||
109 19:21 PVC
|
||||
109 26:09 Noise
|
||||
109 28:03 PVC
|
||||
109 28:28 Normal sinus rhythm with left bundle branch block
|
||||
109 29:10 PVC
|
||||
|
||||
111 0:25 Normal sinus rhythm, first degree AVB
|
||||
111 2:41 Baseline shift noise
|
||||
111 3:52 Noise
|
||||
111 4:04 Axis shift (in upper signal)
|
||||
111 8:31 PVC
|
||||
|
||||
111 11:53 Axis shift
|
||||
111 15:41 Noise
|
||||
111 19:54 Noise
|
||||
111 27:02 Noise
|
||||
112 11:40 APC
|
||||
|
||||
112 12:30 Axis shift
|
||||
112 12:49 APC, noise
|
||||
113 4:20 Moderate baseline wander
|
||||
113 8:22 Aberrated APC
|
||||
113 11:48 Sinus arrhythmia with variation in P-wave morphology
|
||||
|
||||
113 12:27 Sinus arrhythmia
|
||||
113 22:10 Aberrated APC
|
||||
113 29:01 Sinus arrhythmia
|
||||
114 0:00 Normal sinus rhythm
|
||||
114 1:20 PVC
|
||||
|
||||
114 3:39 PVC
|
||||
114 3:56 Late-cycle PVC
|
||||
114 4:35 Late-cycle PVC
|
||||
114 5:36 Ventricular couplet
|
||||
114 8:31 PVCs
|
||||
|
||||
114 9:26 PVC, muscle noise
|
||||
114 11:37 SVTA, PVC, junctional premature beat
|
||||
114 20:02 Noise
|
||||
114 29:29 Baseline artifact
|
||||
115 0:55 Normal sinus rhythm
|
||||
|
||||
115 3:22 Sinus arrhythmia
|
||||
115 15:52 Baseline wander in lower signal
|
||||
115 21:28 Noise in lower signal
|
||||
115 27:05 Artifacts in lower signal
|
||||
115 28:42 Normal sinus rhythm
|
||||
|
||||
116 0:44 Normal sinus rhythm
|
||||
116 1:31 PVCs
|
||||
116 10:00 Ventricular couplet
|
||||
116 12:32 PVC
|
||||
116 16:37 Noise, saturation in upper signal
|
||||
|
||||
116 23:08 Noise, saturation in upper signal
|
||||
116 25:47 Ventricular couplet
|
||||
117 3:56 Normal sinus rhythm
|
||||
117 11:58 Noise, APC
|
||||
117 22:27 Normal sinus rhythm
|
||||
|
||||
118 3:39 PVC
|
||||
118 8:31 Noise
|
||||
118 9:23 PVC
|
||||
118 13:47 Blocked APC
|
||||
118 22:32 APC, blocked APC, PVC
|
||||
|
||||
118 23:25 APCs
|
||||
118 25:41 PVC, APC
|
||||
118 26:23 PVCs
|
||||
118 26:48 Noise
|
||||
118 28:58 Atrial couplet
|
||||
|
||||
118 29:53 APCs
|
||||
119 1:55 PVC
|
||||
119 2:38 Ventricular trigeminy
|
||||
119 4:51 Ventricular bigeminy
|
||||
119 8:42 Normal sinus rhythm
|
||||
|
||||
119 20:05 Noise
|
||||
119 25:33 Noise
|
||||
121 1:06 Normal sinus rhythm
|
||||
121 3:33 Noise in lower signal
|
||||
121 16:48 APC, PVC
|
||||
|
||||
121 24:32 Noise
|
||||
121 26:01 Noise
|
||||
122 1:09 Noise in lower signal
|
||||
122 13:47 Normal sinus rhythm
|
||||
122 28:25 Normal sinus rhythm
|
||||
|
||||
123 22:10 Sinus arrhythmia
|
||||
123 25:11 Interpolated PVC
|
||||
123 27:41 Interpolated PVC
|
||||
123 28:36 Sinus arrhythmia
|
||||
124 4:43 Accelerated junctional rhythm
|
||||
|
||||
124 5:09 Accelerated idioventricular rhythm, 20 beats
|
||||
124 5:21 Accelerated idioventricular rhythm (continued from previous strip)
|
||||
124 9:05 Noise in lower signal
|
||||
124 10:27 Accelerated idioventricular rhythm
|
||||
124 17:38 Accelerated idioventricular rhythm
|
||||
|
||||
124 20:13 APC
|
||||
124 23:22 Ventricular trigeminy
|
||||
124 26:03 PVC
|
||||
124 27:41 PVC, junctional escape beats
|
||||
200 1:42 Ventricular tachycardia, 3 beats
|
||||
|
||||
200 5:38 Noise
|
||||
200 18:14 Ventricular tachycardia, 4 beats
|
||||
200 20:52 Noise
|
||||
200 24:49 Ventricular tachycardia, 3 beats
|
||||
200 26:12 Ventricular couplets
|
||||
|
||||
200 28:31 Ventricular couplet
|
||||
200 29:01 APC, ventricular bigeminy
|
||||
200 29:18 APC, PVC
|
||||
200 29:51 PVCs
|
||||
201 0:00 Atrial fibrillation
|
||||
|
||||
201 6:15 Transition from atrial fibrillation to nodal rhythm
|
||||
201 7:52 Onset of atrial fibrillation with aberrated beats
|
||||
201 8:53 Blocked APCs
|
||||
201 18:14 Noise
|
||||
201 20:16 PVCs, atrial couplet
|
||||
|
||||
201 22:33 Ventricular trigeminy
|
||||
201 23:50 Normal sinus rhythm
|
||||
201 24:15 Aberrated atrial couplet, fusion PVC
|
||||
201 25:19 Aberrated atrial couplets with right and left bundle branch block
|
||||
201 26:20 Supraventricular tachyarrhythmia with aberration, 3 beats
|
||||
|
||||
201 28:03 Atrial fibrillation with aberration
|
||||
202 10:16 Normal sinus rhythm, PVCs
|
||||
202 12:24 APCs, PVC
|
||||
202 12:41 Aberrated APCs, PVC
|
||||
202 18:22 Normal sinus rhythm, bradycardia
|
||||
|
||||
202 18:45 Aberrated APCs
|
||||
202 18:59 Onset of atrial fibrillation with aberrated beats
|
||||
202 21:10 Atrial fibrillation, PVC
|
||||
202 21:26 End of atrial fibrillation
|
||||
202 22:13 Atrial fibrillation, aberrated beats
|
||||
|
||||
202 25:58 Atrial flutter with 2:1 conduction
|
||||
202 27:55 Atrial fibrillation, aberrated beat
|
||||
202 29:35 Atrial fibrillation
|
||||
203 5:00 Ventricular tachycardia, 4 beats and 9 beats
|
||||
203 13:14 Atrial fibrillation, ventricular couplets
|
||||
|
||||
203 15:02 Noise
|
||||
203 22:02 Ventricular couplet, PVCs
|
||||
203 23:25 Noise
|
||||
203 24:04 PVCs
|
||||
203 24:46 Noise
|
||||
|
||||
203 26:39 Ventricular tachycardia, 7 beats
|
||||
203 26:51 Ventricular couplet, PVCs
|
||||
203 27:15 Ventricular tachycardia, 3 beats
|
||||
205 4:57 Ventricular tachycardia, 8 beats and 10 beats
|
||||
205 14:54 Noise in lower signal
|
||||
|
||||
205 15:22 Ventricular tachycardia, 3 beats
|
||||
205 16:03 PVC
|
||||
205 16:15 Fusion PVCs
|
||||
205 19:57 PVC, APC
|
||||
205 24:18 Ventricular tachycardia, 12 beats, start of VR, 13 beats
|
||||
|
||||
205 24:30 End of VR, 3-beat VT (continued from previous strip)
|
||||
205 27:57 PVCs
|
||||
207 0:00 Ventricular bigeminy with right bundle branch block
|
||||
207 0:33 Ventricular couplet, ventricular tachycardia, ventricular flutter
|
||||
207 0:45 Ventricular flutter (continued from previous strip)
|
||||
|
||||
207 0:57 Ventricular flutter, VT (continued from previous strip)
|
||||
207 1:28 Normal sinus rhythm with first degree AV block
|
||||
207 2:07 Ventricular couplet, left and right bundle branch block
|
||||
207 2:41 Ventricular bigeminy with right bundle branch block
|
||||
207 4:25 Ventricular couplet, ventricular flutter
|
||||
|
||||
207 5:19 Noise
|
||||
207 6:56 Noise
|
||||
207 17:35 Normal sinus rhythm with first degree AV block
|
||||
207 25:36 Ventricular bigeminy with LBBB, ventricular flutter
|
||||
207 26:10 Ventricular flutter
|
||||
|
||||
207 27:14 End of ventricular flutter
|
||||
207 29:10 Atrial couplet, SVTA (104 beats, to end of record)
|
||||
208 14:57 Noise/artifact
|
||||
208 17:02 Ventricular couplets
|
||||
208 19:10 Ventricular trigeminy
|
||||
|
||||
208 21:06 Noise
|
||||
208 23:00 Noise
|
||||
208 28:08 Ventricular triplet
|
||||
208 28:58 Ventricular couplets, isolated PVCs
|
||||
208 29:37 Ventricular triplet
|
||||
|
||||
209 0:47 APC
|
||||
209 5:50 Noise
|
||||
209 12:57 PVC
|
||||
209 14:21 SVTA, 14 beats
|
||||
209 23:25 APCs
|
||||
|
||||
209 28:17 Noise, APC
|
||||
209 28:33 SVTA, 4 beats, 13 beats
|
||||
209 29:10 SVTA, 6 beats
|
||||
210 3:47 Noise
|
||||
210 6:56 Ventricular tachycardia, 6 beats
|
||||
|
||||
210 13:14 Ventricular couplets
|
||||
210 15:55 Noise
|
||||
210 17:32 Aberrated beat
|
||||
210 17:57 Ventricular tachycardia, 6 beats
|
||||
210 20:33 PVCs
|
||||
|
||||
210 29:15 PVCs, aberrated beat, ventricular escape beat, fusion PVC
|
||||
212 0:05 Normal sinus rhythm with right bundle branch block
|
||||
212 18:42 Noise
|
||||
212 24:21 End of RBBB in normal sinus rhythm as heart rate decreases
|
||||
212 24:38 Sinus arrhythmia
|
||||
|
||||
212 26:45 Noise
|
||||
212 28:46 Start of RBBB in normal sinus rhythm as heart rate increases
|
||||
213 3:39 Fusion PVC couplet
|
||||
213 14:48 Ventricular tachycardia, 3 beats
|
||||
213 15:05 Fusion PVC/PVC couplet
|
||||
|
||||
213 15:38 APC
|
||||
213 17:30 Ventricular tachycardia, 4 beats
|
||||
213 17:55 PVCs, fusion PVCs, APC
|
||||
213 24:43 Fusion PVC, PVCs, aberrated APC
|
||||
213 25:58 Aberrated atrial couplet
|
||||
|
||||
213 26:51 Ventricular bigeminy
|
||||
213 28:56 Fusion PVCs, PVC
|
||||
214 0:30 Normal sinus rhythm with left bundle branch block, PVC
|
||||
214 2:21 Multiform PVCs
|
||||
214 2:35 Ventricular couplet
|
||||
|
||||
214 3:25 Artifactual amplitude changes
|
||||
214 3:56 Ventricular couplet
|
||||
214 5:08 Tape slippage
|
||||
214 5:38 Ventricular tachycardia, 3 beats
|
||||
214 13:53 Ventricular tachycardia, 3 beats
|
||||
|
||||
214 23:17 Ventricular couplet
|
||||
214 27:52 PVC/fusion PVC couplet
|
||||
215 2:55 Ventricular tachycardia, 3 beats
|
||||
215 3:11 Noise, ventricular couplet
|
||||
215 9:46 PVC, APC
|
||||
|
||||
215 15:58 PVC
|
||||
215 20:25 Ventricular tachycardia, 3 beats
|
||||
215 22:16 Tape slippage
|
||||
215 24:57 Ventricular couplet
|
||||
215 27:30 Ventricular triplet
|
||||
|
||||
215 27:57 Noise in lower signal
|
||||
215 29:42 Tape slippage, ventricular couplet
|
||||
217 0:00 Paced rhythm, pacemaker fusion beat
|
||||
217 0:33 PVC
|
||||
217 1:23 PVCs, pacemaker fusion beats
|
||||
|
||||
217 4:18 Paced beats, pacemaker fusion beats, normal beats, PVCs
|
||||
217 6:12 Ventricular couplet
|
||||
217 6:51 Ventricular couplet
|
||||
217 7:05 Ventricular tachycardia, 3 beats
|
||||
217 12:27 Ventricular bigeminy with paced beats
|
||||
|
||||
217 14:01 Noise
|
||||
217 15:30 Atrial fibrillation
|
||||
217 16:56 Ventricular couplet
|
||||
217 22:27 Atrial fibrillation
|
||||
219 2:49 Fusion PVC
|
||||
|
||||
219 5:08 APC
|
||||
219 5:22 Onset of atrial fibrillation
|
||||
219 13:50 End of atrial fibrillation, conversion pause, APC, blocked APC
|
||||
219 19:00 End of atrial fibrillation
|
||||
219 19:57 Normal sinus rhythm, blocked APCs
|
||||
|
||||
219 22:11 End of atrial fibrillation, conversion pause, blocked APCs
|
||||
219 22:43 Blocked APCs
|
||||
219 24:43 PVC
|
||||
219 26:09 Atrial fibrillation
|
||||
219 28:55 Atrial fibrillation, PVCs
|
||||
|
||||
220 6:46 SVTA (3 runs)
|
||||
220 10:41 SVTA (2 runs)
|
||||
220 18:10 Atrial couplets
|
||||
220 20:29 SVTA, atrial couplets
|
||||
220 23:58 Noise in lower signal
|
||||
|
||||
220 25:44 Atrial couplet
|
||||
220 29:40 APC
|
||||
221 0:00 Atrial fibrillation, PVCs
|
||||
221 2:43 Ventricular couplet
|
||||
221 13:00 Ventricular tachycardia, 3 beats
|
||||
|
||||
221 13:56 Ventricular tachycardia, 3 beats
|
||||
221 17:49 Ventricular couplet
|
||||
221 19:12 PVCs
|
||||
221 19:42 Noise
|
||||
221 20:44 Ventricular couplet
|
||||
|
||||
222 6:45 Normal sinus rhythm
|
||||
222 17:32 Atrial fibrillation
|
||||
222 19:48 Atrial couplet
|
||||
222 20:07 Atrial bigeminy
|
||||
222 22:32 Paroxysmal atrial fibrillation, nodal rhythm
|
||||
|
||||
222 24:43 Noise
|
||||
222 25:43 End of atrial fibrillation, nodal rhythm, normal sinus rhythm
|
||||
222 26:09 Paroxysmal atrial flutter, nodal rhythm
|
||||
223 9:35 Bidirectional ventricular tachycardia
|
||||
223 12:35 Noise in lower signal
|
||||
|
||||
223 13:39 Atrial couplet
|
||||
223 13:51 Ventricular bigeminy
|
||||
223 17:21 Bidirectional ventricular tachycardia
|
||||
223 17:55 End of ventricular tachycardia
|
||||
223 19:07 APC, ventricular couplet, atrial escape beat, aberrated APC
|
||||
|
||||
223 23:58 Ventricular tachycardia, 3 beats
|
||||
223 25:47 Ventricular tachycardia, 5 beats
|
||||
223 29:16 APCs, atrial escape beat, ventricular couplets
|
||||
223 29:51 Multiform ventricular couplets
|
||||
228 0:19 Ventricular bigeminy
|
||||
|
||||
228 0:38 Artifacts
|
||||
228 0:50 PVC, ventricular couplet
|
||||
228 4:35 Noise, PVCs
|
||||
228 19:18 PVC, APC
|
||||
228 20:08 Baseline noise
|
||||
|
||||
228 21:37 Tape slippage
|
||||
228 21:49 Tape slippage
|
||||
228 26:42 Ventricular bigeminy
|
||||
230 0:00 Onset of pre-excitation
|
||||
230 0:12 End of pre-excitation (continued from previous strip)
|
||||
|
||||
230 5:11 WPW
|
||||
230 9:26 Normal sinus rhythm
|
||||
230 29:04 PVC
|
||||
231 0:02 Normal sinus rhythm, Mobitz II block, right bundle branch block
|
||||
231 2:24 Blocked APCs, APC, ventricular couplet
|
||||
|
||||
231 20:11 2:1 heart block with right bundle branch block
|
||||
231 21:10 Onset of 2:1 heart block
|
||||
231 23:22 Transition from 2:1 block with normal conduction to NSR with RBBB
|
||||
232 0:58 Noise
|
||||
232 1:51 Atrial couplets
|
||||
|
||||
232 11:51 Noise
|
||||
232 13:06 Atrial couplets
|
||||
232 15:09 Short runs of SVTA
|
||||
232 18:17 SVTA, pause
|
||||
232 22:31 Pauses
|
||||
|
||||
232 22:47 Pauses
|
||||
232 23:20 Pauses
|
||||
232 23:34 Pause
|
||||
232 23:53 Sinus bradycardia
|
||||
233 0:11 APCs, PVCs
|
||||
|
||||
233 0:25 Ventricular tachycardia, 3 beats
|
||||
233 2:18 Ventricular bigeminy
|
||||
233 2:43 Fusion PVC/PVC couplet
|
||||
233 3:39 Ventricular couplets
|
||||
233 5:02 Transient amplitude decrease on upper signal
|
||||
|
||||
233 9:43 Ventricular tachycardia, 3 beats
|
||||
233 16:20 PVCs, ventricular couplet
|
||||
233 18:02 PVCs, APC
|
||||
233 22:23 Ventricular tachycardia, 2 runs of 3 beats, ventricular couplets
|
||||
234 0:16 Normal sinus rhythm
|
||||
|
||||
234 6:37 Noise
|
||||
234 14:01 Onset of junctional tachycardia
|
||||
234 14:26 End of junctional tachycardia
|
||||
234 17:02 PVC
|
||||
234 21:26 PVC
|
||||
|
||||
234 23:17 Noise
|
||||
@@ -0,0 +1 @@
|
||||
200 18:14 Ventricular tachycardia, 4 beats
|
||||
Binary file not shown.
@@ -0,0 +1,42 @@
|
||||
.LP
|
||||
.ds LH MIT-BIH A\s-2RRHYTHMIA\s+2 D\s-2ATABASE\s+2
|
||||
.ds RH E\s-2XAMPLES\s+2
|
||||
.bp 98
|
||||
.DS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.DE
|
||||
.ce 1
|
||||
\fB\s12EXAMPLES\s10\fP
|
||||
|
||||
|
||||
.PP
|
||||
The following pages contain a set of illustrative examples from each
|
||||
database record, shown at higher resolution than in the preceding
|
||||
``full-disclosure'' plots. Most of these examples are those shown in the
|
||||
first edition of this book.
|
||||
.PP
|
||||
The strips are each 12 seconds long; they cover the interval specified in the
|
||||
margins to the left and right of each strip. The scale is 12.5 mm/sec and
|
||||
5 mm/mV (i.e., half of the standard scale for ECG chart recordings).
|
||||
Grid lines appear at the standard intervals of 0.2 seconds and 0.5 mV.
|
||||
Note that the vertical position of each trace has been adjusted to
|
||||
center it in the available space; thus it is not meaningful to compare
|
||||
absolute voltage levels between strips. Unlike the strips in the first
|
||||
edition, however, no adjustments in gain have been made to compensate for
|
||||
amplitude differences between signals; thus waveform amplitudes can be
|
||||
measured directly from these strips.
|
||||
@@ -0,0 +1,95 @@
|
||||
100 0-e
|
||||
|
||||
101 0-e
|
||||
|
||||
102 0-e
|
||||
|
||||
103 0-e
|
||||
|
||||
104 0-e
|
||||
|
||||
105 0-e
|
||||
|
||||
106 0-e
|
||||
|
||||
107 0-e
|
||||
|
||||
108 0-e
|
||||
|
||||
109 0-e
|
||||
|
||||
111 0-e
|
||||
|
||||
112 0-e
|
||||
|
||||
113 0-e
|
||||
|
||||
114 0-e
|
||||
|
||||
115 0-e
|
||||
|
||||
116 0-e
|
||||
|
||||
117 0-e
|
||||
|
||||
118 0-e
|
||||
|
||||
119 0-e
|
||||
|
||||
121 0-e
|
||||
|
||||
122 0-e
|
||||
|
||||
123 0-e
|
||||
|
||||
124 0-e
|
||||
|
||||
200 0-e
|
||||
|
||||
201 0-e
|
||||
|
||||
202 0-e
|
||||
|
||||
203 0-e
|
||||
|
||||
205 0-e
|
||||
|
||||
207 0-e
|
||||
|
||||
208 0-e
|
||||
|
||||
209 0-e
|
||||
|
||||
210 0-e
|
||||
|
||||
212 0-e
|
||||
|
||||
213 0-e
|
||||
|
||||
214 0-e
|
||||
|
||||
215 0-e
|
||||
|
||||
217 0-e
|
||||
|
||||
219 0-e
|
||||
|
||||
220 0-e
|
||||
|
||||
221 0-e
|
||||
|
||||
222 0-e
|
||||
|
||||
223 0-e
|
||||
|
||||
228 0-e
|
||||
|
||||
230 0-e
|
||||
|
||||
231 0-e
|
||||
|
||||
232 0-e
|
||||
|
||||
233 0-e
|
||||
|
||||
234 0-e
|
||||
Binary file not shown.
@@ -0,0 +1,46 @@
|
||||
.LP
|
||||
.ds LH MIT-BIH A\s-2RRHYTHMIA\s+2 D\s-2ATABASE\s+2
|
||||
.ds CH - 1 -
|
||||
.ds RH F\s-2ULL\-DISCLOSURE \s+2ECG P\s-2LOTS\s+2
|
||||
.bp 2
|
||||
.DS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.DE
|
||||
.ce 1
|
||||
\fB\s+2FULL\-DISCLOSURE ECG PLOTS\s-2\fR
|
||||
|
||||
|
||||
.PP
|
||||
This section contains annotated ``full-disclosure'' ECG plots for the
|
||||
entire database. Each record is presented on two facing pages. Each
|
||||
page contains fifteen one-minute segments. Each segment contains a pair
|
||||
of ECG traces with annotation labels placed between them. Each label is
|
||||
placed so that the fiducial mark for the annotation corresponds to the
|
||||
left edge of the label. The meanings of the various labels are given
|
||||
in the table on page viii.
|
||||
.PP
|
||||
The scale is 2.5 mm/sec and 1 mm/mV (i.e., one-tenth the standard scale
|
||||
for ECG chart recordings). To improve the legibility of these plots, the
|
||||
ECG signals were digitally low-pass filtered with a nine-point moving average
|
||||
filter before plotting them; for this reason, high-frequency noise appears
|
||||
smaller in amplitude in these plots than in the unfiltered high-resolution
|
||||
strips which begin on page 98.
|
||||
.PP
|
||||
At the top and bottom of
|
||||
each page is a time scale with one-second intervals marked; five-second
|
||||
intervals are designated with large ticks on these scales. To the left
|
||||
and right of each segment are the times of the beginning and end
|
||||
of the segment (in minutes and seconds from
|
||||
the beginning of the record). The last segment for each record begins at
|
||||
29 minutes, and ends at 30 minutes and 5.556 seconds (the end of the record).
|
||||
Binary file not shown.
@@ -0,0 +1,63 @@
|
||||
.nr PS 10
|
||||
.nr VS 12
|
||||
.LP
|
||||
.ds LH \s10MIT-BIH A\s8RRHYTHMIA\s10 D\s8ATABASE\s10
|
||||
.ds RH \s10I\s8NDEX\s10
|
||||
.bp 194
|
||||
.ce 1
|
||||
\fB\s12INDEX OF RECORDS IN THE MIT\-BIH ARRHYTHMIA DATABASE\s10\fP
|
||||
.LP
|
||||
.TS
|
||||
center;
|
||||
c c c c
|
||||
c n n n.
|
||||
\fIRecord Full disclosure Examples Notes\fP
|
||||
100 2 99 178
|
||||
101 4 99 178
|
||||
102 6 100 178
|
||||
103 8 102 178
|
||||
104 10 103 178
|
||||
105 12 104 179
|
||||
106 14 106 179
|
||||
107 16 108 179
|
||||
108 18 109 179
|
||||
109 20 111 179
|
||||
111 22 114 180
|
||||
112 24 115 180
|
||||
113 26 116 180
|
||||
114 28 117 180
|
||||
115 30 119 180
|
||||
116 32 121 180
|
||||
117 34 122 181
|
||||
118 36 123 181
|
||||
119 38 125 181
|
||||
121 40 126 181
|
||||
122 42 127 181
|
||||
123 44 128 181
|
||||
124 46 128 182
|
||||
200 48 130 182
|
||||
201 50 132 182
|
||||
202 52 135 182
|
||||
203 54 137 183
|
||||
205 56 139 183
|
||||
207 58 141 183
|
||||
208 60 144 184
|
||||
209 62 146 184
|
||||
210 64 147 184
|
||||
212 66 149 184
|
||||
213 68 150 185
|
||||
214 70 152 185
|
||||
215 72 154 185
|
||||
217 74 156 185
|
||||
219 76 158 186
|
||||
220 78 161 186
|
||||
221 80 162 186
|
||||
222 82 164 186
|
||||
223 84 165 186
|
||||
228 86 167 187
|
||||
230 88 169 187
|
||||
231 90 170 187
|
||||
232 92 171 187
|
||||
233 94 173 188
|
||||
234 96 175 188
|
||||
.TE
|
||||
Binary file not shown.
@@ -0,0 +1,456 @@
|
||||
.LP
|
||||
.af PN i
|
||||
.ds LH MIT-BIH A\s-2RRHYTHMIA\s+2 D\s-2ATABASE\s+2
|
||||
.ds RH F\s-2OREWORD\s+2
|
||||
.bp 3
|
||||
\s+2
|
||||
\fB
|
||||
.ce 1
|
||||
FOREWORD
|
||||
.PP
|
||||
For a number of years our group has been investigating methods for real-time
|
||||
ECG rhythm analysis. In the course of this work, we have developed an
|
||||
extensive annotated digital ECG database. The database has been enormously
|
||||
helpful to us in algorithm development and evaluation. The creation of this
|
||||
resource required a major effort, and was funded, in part, by both government
|
||||
and industry. We feel it is highly desirable to make this database available
|
||||
to other academic and industrial groups, and hence have prepared it for
|
||||
distribution. This catalog contains detailed descriptions of the database
|
||||
tapes.
|
||||
.PP
|
||||
We acknowledge with gratitude the many dedicated hours of work which
|
||||
went into this project on the part of cardiologists, Holter technicians,
|
||||
laboratory assistants, and engineers in our laboratories at MIT and at
|
||||
Beth Israel Hospital. We also acknowledge the help of our colleagues at
|
||||
Washington University, St. Louis (particularly Russell Hermes) in
|
||||
assuring a compatible data format. We especially wish to recognize:
|
||||
.IP \(bu
|
||||
\fIPaul Schluter\fR, who did the original design and implementation of the
|
||||
database.
|
||||
.IP \(bu
|
||||
\fIScott Peterson\fR, who supervised the detailed data selection, digitization,
|
||||
annotation, and editing at Beth Israel Hospital. He also contributed
|
||||
substantially to the development of software needed for using the database in
|
||||
our evaluation.
|
||||
.IP \(bu
|
||||
\fIGeorge Moody\fR, who converted the database to a format compatible with that
|
||||
used by the AHA database, and who contributed in a major way to the directory.
|
||||
.IP \(bu
|
||||
\fILarry Siegal\fR, who contributed to development of the waveform editor
|
||||
system.
|
||||
.IP \(bu
|
||||
\fICheryl Jackson\fR, who was responsible for most of the detailed
|
||||
transcription of cardiologist annotations, the comparison and quality control
|
||||
functions, and who assembled the final manuscript for the directory.
|
||||
.IP \(bu
|
||||
\fIDiane Perry\fR, who as chief technician in the Arrhythmia Laboratory helped
|
||||
to identify suitable data, and who helped in the annotation process.
|
||||
.IP \(bu
|
||||
The group of physicians who helped with the difficult task of beat-by-beat
|
||||
annotation of the ECGs:
|
||||
Dr. Esmerey Acarturk, Dr. John Aumiller, Dr. Sidney Blake, Dr. Alvin
|
||||
Blaustein, Dr. Chester Conrad, Dr. Gary Heller, Dr. Michael Malagold,
|
||||
Dr. Roger Mark, and Dr. Candice Miklozek.
|
||||
|
||||
.nf
|
||||
.in +3i
|
||||
Roger Mark
|
||||
Walter Olson
|
||||
|
||||
Cambridge, Massachusetts
|
||||
September, 1980
|
||||
.in -3i
|
||||
.fi
|
||||
|
||||
\s+2
|
||||
\fB
|
||||
.ce 1
|
||||
NOTES ON THE SECOND EDITION
|
||||
.PP
|
||||
During the eight years since we first published this book, nearly one hundred
|
||||
academic and industrial research groups worldwide have used the MIT-BIH
|
||||
Arrhythmia Database. We thank these organizations for their support.
|
||||
.PP
|
||||
In addition to those listed above, we also wish to recognize the
|
||||
contributions of:
|
||||
.IP \(bu
|
||||
\fIJoe Mietus\fR, who handled correspondence as well as production and
|
||||
distribution of the database from the Beth Israel Hospital, and who analyzed
|
||||
the mechanical sources of analog tape wow and flutter.
|
||||
.IP \(bu
|
||||
\fITed Baker\fR, who helped in the first ``port'' of the database from our
|
||||
homebrew 8080-based systems.
|
||||
.PP
|
||||
In lieu of reprinting the first edition of this volume, we have made use of
|
||||
modern printing technology to produce a far more readable and complete record
|
||||
of the contents of the database.
|
||||
.PP
|
||||
In June, 1987, the Association for the Advancement of Medical Instrumentation
|
||||
published its \fIRecommended Practice for Testing and Reporting
|
||||
Performance Results of Ventricular Arrhythmia Detection Algorithms\fR
|
||||
(AAMI ECAR-1987), which may be obtained from AAMI, 3330 Washington Boulevard,
|
||||
Suite 400, Arlington, VA 22201.
|
||||
The MIT-BIH and AHA Databases provide developers and evaluators of arrhythmia
|
||||
detectors with standard test data; the AAMI Recommended Practice provides
|
||||
guidelines for using these databases in a standard way, and for describing
|
||||
detector performance in a manner that facilitates comparisons between
|
||||
detectors.
|
||||
We urge all users of our database to follow the AAMI recommendations when
|
||||
preparing performance statistics for publication.
|
||||
.PP
|
||||
A package of C-language software for using the MIT-BIH and AHA Databases
|
||||
is available from MIT. The package
|
||||
includes programs for plotting ECGs with annotations, sampling rate
|
||||
conversion, and beat-by-beat comparison of annotation files following the
|
||||
AAMI recommended practice, as well as a variety of other useful programs.
|
||||
All the programs access the database via a common library of subroutines,
|
||||
which are also provided as part of the package and which may be used with
|
||||
user programs.
|
||||
.PP
|
||||
We have made several other sets of ECG recordings available, including
|
||||
specialized databases for ventricular fibrillation, atrial fibrillation,
|
||||
and ST segment changes. These databases are not annotated beat-by-beat.
|
||||
|
||||
.nf
|
||||
.in +3i
|
||||
George Moody
|
||||
Roger Mark
|
||||
|
||||
Cambridge, Massachusetts
|
||||
August, 1988
|
||||
.in -3i
|
||||
.fi
|
||||
|
||||
\s+2
|
||||
\fB
|
||||
.ce 1
|
||||
NOTES ON THE THIRD EDITION
|
||||
.PP
|
||||
Since the publication of the second edition, the database has been made
|
||||
available in CD-ROM format. Continued strong interest in the database has made
|
||||
it possible to prepare a second edition of the CD-ROM and a third edition of
|
||||
this book. The CD-ROM includes the additional specialized databases mentioned
|
||||
above, and the second edition of the CD-ROM also contains the software
|
||||
package mentioned above.
|
||||
.PP
|
||||
Compatible databases of ECGs and other physiologic signals are beginning to
|
||||
appear. Of particular interest to users of our database is the European ST-T
|
||||
Database, which consists of ninety two-hour ECG recordings with beats, rhythms,
|
||||
and signal quality annotated as in the MIT-BIH Arrhythmia Database, and with
|
||||
additional annotations to indicate ST and T-wave morphology changes. For
|
||||
information, write to: CNR Institute of Clinical Physiology, Computer
|
||||
Laboratory, via Trieste, 41, 56100 Pisa, Italy.
|
||||
.PP
|
||||
I wish to thank all of those who have supported this project over these years,
|
||||
especially Roger Mark, who has guided it from its inception in 1975.
|
||||
|
||||
.nf
|
||||
.in +3i
|
||||
George Moody
|
||||
|
||||
Cambridge, Massachusetts
|
||||
July, 1992
|
||||
.in -3i
|
||||
.fi
|
||||
.ds RH I\s-2NTRODUCTION\s+2
|
||||
.bp
|
||||
.SH
|
||||
INTRODUCTION
|
||||
.PP
|
||||
This introduction describes how the database records were
|
||||
obtained, and discusses the characteristics of the recorded signals.
|
||||
Following these notes are annotated ``full disclosure'' plots of the entire
|
||||
database. These can be useful for obtaining an overall
|
||||
impression of the contents of individual records. Following the
|
||||
``full disclosure'' plots are sample ECG strips. These strips
|
||||
were chosen to illustrate the salient features of each record.
|
||||
Next are notes on the important features of each record.
|
||||
These notes also include background information on the subjects,
|
||||
including their medications.
|
||||
At the end of the book are tables of rhythms and annotations, which
|
||||
summarize the contents of the database.
|
||||
These tables can be helpful in finding a record with a specific
|
||||
set of characteristics.
|
||||
.SH
|
||||
Selection criteria
|
||||
.PP
|
||||
The source of the ECGs included in the MIT-BIH Arrhythmia Database is a
|
||||
set of over 4000 long-term Holter recordings that were obtained
|
||||
by the Beth Israel Hospital Arrhythmia Laboratory between 1975 and 1979.
|
||||
Approximately 60% of these recordings were obtained from inpatients.
|
||||
The database contains 23 records
|
||||
(numbered from 100 to 124 inclusive with some numbers missing)
|
||||
chosen at random from this set, and 25 records
|
||||
(numbered from 200 to 234 inclusive, again with some numbers missing)
|
||||
selected from the same set to include a variety of rare but clinically
|
||||
important phenomena that would not be well-represented
|
||||
by a small random sample of Holter recordings.
|
||||
Each of the 48 records is slightly over 30 minutes long.
|
||||
.PP
|
||||
The first group is intended to serve as a representative sample of the
|
||||
variety of waveforms and artifact that an arrhythmia detector might
|
||||
encounter in routine clinical use. A table of random numbers was used
|
||||
to select tapes, and then to select half-hour segments of them.
|
||||
Segments selected in this way were excluded only if neither of the two
|
||||
ECG signals was of adequate quality for analysis by human experts.
|
||||
.PP
|
||||
Records in the second group were chosen to
|
||||
include complex ventricular, junctional,
|
||||
and supraventricular arrhythmias and conduction abnormalities. Several
|
||||
of these records were selected because features of the rhythm, QRS
|
||||
morphology variation, or signal quality may be expected to present
|
||||
significant difficulty to arrhythmia detectors; these records have
|
||||
gained considerable notoriety among database users.
|
||||
.PP
|
||||
The subjects were 25 men aged 32 to 89 years, and 22 women aged 23 to 89
|
||||
years. (Records 201 and 202 came from the same male subject.)
|
||||
.SH
|
||||
ECG lead configuration
|
||||
.PP
|
||||
In most records, the upper signal is a modified limb lead II (MLII),
|
||||
obtained by placing the electrodes on the chest. The lower signal is
|
||||
usually a modified lead V1 (occasionally V2 or V5, and in one instance V4);
|
||||
as for the upper signal, the electrodes are also placed on the chest.
|
||||
This configuration is routinely used by the BIH Arrhythmia Laboratory.
|
||||
Normal QRS complexes are usually prominent in the upper signal.
|
||||
The lead axis for the lower signal may be nearly orthogonal to the mean
|
||||
cardiac electrical axis, however (i.e., normal beats are usually
|
||||
biphasic and may be nearly isoelectric).
|
||||
Thus normal beats are frequently difficult to discern in the lower signal,
|
||||
although ectopic beats will often be more prominent (see, for example, record
|
||||
106).
|
||||
A notable exception is record 114, for which the signals were reversed.
|
||||
Since this happens occasionally in clinical practice, arrhythmia detectors
|
||||
should be equipped to deal with this situation.
|
||||
In records 102 and 104, it was not possible to use modified lead II because of
|
||||
surgical dressings on the patients;
|
||||
modified lead V5 was used for the upper signal in these records.
|
||||
.SH
|
||||
Analog recording and playback
|
||||
.PP
|
||||
The original analog recordings were made using nine Del Mar Avionics
|
||||
model 445 two-channel recorders, designated \fIA\fP through \fII\fP:
|
||||
.TS
|
||||
center box;
|
||||
c | l.
|
||||
\fIRecorder Records\fP
|
||||
_
|
||||
A 102, 107, 111, 115, 121
|
||||
B 212
|
||||
C 203
|
||||
D 118, 124, 217
|
||||
E 101, 103, 106, 108, 112, 117, 119, 122, 209, 219, 220, 223, 233
|
||||
F 104, 109, 123, 205, 207, 210, 215, 221
|
||||
G 100, 105, 114, 116, 213, 214, 222, 228
|
||||
H 113, 201, 202, 231
|
||||
I 200, 230, 232, 234
|
||||
.TE
|
||||
(It is not known which recorder was used for record 208.)
|
||||
.PP
|
||||
During the digitization process, the analog recordings were played back
|
||||
on a Del Mar Avionics model 660 unit. The analog tapes used for records
|
||||
112, 115 through 124, 205, 220, 223, and 230 through 234 were played back
|
||||
and digitized at twice real time; the rest were played back at real time
|
||||
using a specially constructed capstan for the model 660 unit.
|
||||
Skew between the two signals was found to be as great as 40
|
||||
milliseconds for some of the analog recorders.
|
||||
In addition to the fixed skew that results from extremely small differences
|
||||
in the orientations of the tape heads on the recorder and the playback unit,
|
||||
microscopic vertical wobbling of the tape, either during recording or playback,
|
||||
introduces a variable skew, which may be comparable in magnitude to the fixed
|
||||
skew.
|
||||
This problem (which also
|
||||
occurs on the AHA database) may present difficulties for certain two-channel
|
||||
analysis methods designed for real-time applications.
|
||||
.PP
|
||||
Minor tape speed variations should not pose problems for typical arrhythmia
|
||||
detectors. It is difficult to avoid tape sticking or slippage during low-speed
|
||||
playback, and several episodes of tape slippage were noted and marked with
|
||||
comment annotations. Wow and flutter should be studied carefully in the
|
||||
context of heart-rate variability studies, since flutter compensation
|
||||
was not possible in these recordings. A number of frequency-domain artifacts
|
||||
have been identified and related to specific mechanical components of the
|
||||
recorders and the playback unit:
|
||||
.TS
|
||||
center box;
|
||||
c | l.
|
||||
\fIFrequency (Hz) Source\fR
|
||||
_
|
||||
0.042 Recorder pressure wheel
|
||||
0.083 Playback unit capstan (for twice real-time playback)
|
||||
0.090 Recorder capstan
|
||||
0.167 Playback unit capstan (for real-time playback)
|
||||
0.18\-0.10 Takeup reel (frequency decreases over time)
|
||||
0.20\-0.36 Supply reel (frequency increases over time)
|
||||
.TE
|
||||
The most significant of these artifacts by far is the 0.167 Hz artifact on
|
||||
recordings that were played back at real time. The next largest is the
|
||||
0.090 Hz artifact; the 0.083 Hz artifact on recordings that were played back
|
||||
at twice real-time is of roughly the same magnitude as the 0.090 Hz artifact.
|
||||
The 0.042 Hz artifact is of much lower magnitude. Other frequencies
|
||||
related to the drive train (at 0.42 Hz, 1.96 Hz, 9.1 Hz, and
|
||||
42 Hz) do not appear as noticeable artifacts.
|
||||
The frequencies of the last two artifacts listed in the table depend on
|
||||
how much tape is on the supply and takeup reels; the supply reel causes
|
||||
a much more noticeable artifact than does the takeup reel. Other
|
||||
frequency-domain artifacts generated by the supply reel appear in the
|
||||
0.10\-0.18 Hz and 0.30\-0.54 Hz bands.
|
||||
.PP
|
||||
Four of the 48 records (102, 104, 107, and 217) include paced beats.
|
||||
The original analog recordings do not represent the pacemaker artifacts
|
||||
with sufficient fidelity to permit them to be recognized by pulse amplitude
|
||||
(or slew rate) and duration alone, the method commonly used for real-time
|
||||
processing. The database records reproduce the analog recordings with
|
||||
sufficient fidelity to permit use of pacemaker artifact detectors designed for
|
||||
tape analysis, however.
|
||||
.SH
|
||||
Digitization
|
||||
.PP
|
||||
The analog outputs of the playback unit
|
||||
were filtered to limit analog-to-digital converter (ADC)
|
||||
saturation and for anti-aliasing,
|
||||
using a passband from 0.1 to 100 Hz relative to real time, well
|
||||
beyond the lowest and highest frequencies recoverable from the recordings.
|
||||
The bandpass-filtered signals were
|
||||
digitized at 360 Hz per signal relative to real time
|
||||
using hardware constructed at the MIT Biomedical Engineering Center and
|
||||
at the BIH Biomedical Engineering Laboratory.
|
||||
The sampling frequency was chosen to facilitate implementations of 60 Hz
|
||||
(mains frequency) digital notch filters in arrhythmia detectors.
|
||||
Since the recorders were battery-powered, most of the 60 Hz noise present
|
||||
in the database arose during playback.
|
||||
In those records that were digitized at twice real time, this noise appears
|
||||
at 30 Hz (and multiples of 30 Hz) relative to real time.
|
||||
.PP
|
||||
Samples were acquired from each signal almost simultaneously (the intersignal
|
||||
sampling skew was on the order of a few microseconds). As noted above, analog
|
||||
tape skew was several orders of magnitude larger. The ADCs were
|
||||
unipolar, with 11-bit resolution over a \(+-5 mV range. Sample values thus
|
||||
range from 0 to 2047 inclusive, with a value of 1024 corresponding to zero
|
||||
volts.
|
||||
.PP
|
||||
The 11-bit samples were recorded in 8-bit first difference format (this was
|
||||
necessary because of limited mass storage capacity).
|
||||
Given the sampling frequency and the resolution of the ADC,
|
||||
the difference encoding implies a maximum recordable slew rate of \(+-225 mV/s.
|
||||
In practice, this limit was exceeded by the input signals very infrequently,
|
||||
only during severe noise on a small number of records.
|
||||
The effect on the quality of the recorded signals is totally negligible.
|
||||
Since the ECG data files are reconstructed from difference data,
|
||||
no information is lost and considerable savings in storage may be
|
||||
obtained by converting them back into difference form; a program
|
||||
for doing so is included in the package of C-language software available
|
||||
from the BIH Biomedical Engineering Laboratory.
|
||||
.SH
|
||||
Annotations
|
||||
.PP
|
||||
An initial set of beat labels was produced by a simple slope-sensitive
|
||||
QRS detector, which marked each detected event as a normal beat. Two
|
||||
identical 150-foot chart recordings were printed for each 30-minute record,
|
||||
with these initial beat labels in the margin.
|
||||
For each record, the two charts were given to two cardiologists, who worked
|
||||
on them independently. The cardiologists added additional beat labels
|
||||
where the detector missed beats, deleted false detections as necessary,
|
||||
and changed the labels for all abnormal beats. They also added rhythm
|
||||
labels, signal quality labels, and comments.
|
||||
.PP
|
||||
The annotations were transcribed from the paper chart recordings.
|
||||
Once both sets of cardiologists' annotations for a given record
|
||||
had been transcribed and verified, they were automatically compared
|
||||
beat-by-beat, and another chart recording was printed. This chart showed
|
||||
the cardiologists' annotations in the margin, with all discrepancies
|
||||
highlighted. Each discrepancy was reviewed and resolved by consensus.
|
||||
The corrections were transcribed, and the annotations were then analyzed
|
||||
by an auditing program, which checked them for consistency and which
|
||||
located the ten longest and shortest R-R intervals in each record (to
|
||||
identify possible missing or falsely detected beats).
|
||||
.PP
|
||||
In early copies of the database, most beat labels were placed
|
||||
at the R-wave peak, but manually inserted labels were not always
|
||||
located precisely at the peak.
|
||||
In copies of the database made since 1983, the beat labels have been shifted
|
||||
from their original locations.
|
||||
The ECG (usually the upper signal) was digitally bandpass-filtered to
|
||||
emphasize the QRS complexes, and each beat label was moved to the major local
|
||||
extremum, after correction for phase shift in the filter.
|
||||
A few noisy beats were manually realigned.
|
||||
The result is that annotations generally appear at the R-wave peak, and
|
||||
are located with sufficient accuracy to make the reference annotation
|
||||
files usable for studies requiring waveform averaging and for
|
||||
heart rate variability studies (but note the comments
|
||||
with respect to analog tape wow and flutter above).
|
||||
In the annotated ECG plots in this book, each label is placed so that the
|
||||
fiducial mark for the annotation corresponds to the left edge of the label.
|
||||
.PP
|
||||
The database contains approximately 109,000 beat labels. Sixteen
|
||||
have been corrected in the eight years since the database was first
|
||||
released (in records 104, 108, 114, 203, 207, 217, and 222); in addition,
|
||||
all of the left bundle branch block beats in record 214 were originally
|
||||
labelled as normal beats. The rhythm labels
|
||||
have been more substantially revised and now include notations for paced
|
||||
rhythm, bigeminy, and trigeminy, which were missing in early copies.
|
||||
.ds RH S\s-2YMBOLS\s+2
|
||||
.bp
|
||||
.ce 1
|
||||
\fB\s+2SYMBOLS USED IN ECG PLOTS\s-2\fR
|
||||
|
||||
.TS
|
||||
center box;
|
||||
c | lw(4.5i).
|
||||
\fISymbol Meaning\fR
|
||||
_
|
||||
\(bu Normal beat
|
||||
L Left bundle branch block beat
|
||||
R Right bundle branch block beat
|
||||
A Atrial premature beat
|
||||
a Aberrated atrial premature beat
|
||||
J Nodal (junctional) premature beat
|
||||
S Supraventricular premature beat
|
||||
V Premature ventricular contraction
|
||||
F Fusion of ventricular and normal beat
|
||||
[ Start of ventricular flutter/fibrillation
|
||||
! Ventricular flutter wave
|
||||
] End of ventricular flutter/fibrillation
|
||||
e Atrial escape beat
|
||||
j Nodal (junctional) escape beat
|
||||
E Ventricular escape beat
|
||||
P Paced beat
|
||||
f Fusion of paced and normal beat
|
||||
p Non-conducted P-wave (blocked APB)
|
||||
Q Unclassifiable beat
|
||||
| Isolated QRS-like artifact
|
||||
_
|
||||
T{
|
||||
Rhythm annotations appear \fIbelow\fP the level used for beat
|
||||
annotations:
|
||||
T}
|
||||
(AB Atrial bigeminy
|
||||
(AFIB Atrial fibrillation
|
||||
(AFL Atrial flutter
|
||||
(B Ventricular bigeminy
|
||||
(BII 2\(de heart block
|
||||
(IVR Idioventricular rhythm
|
||||
(N Normal sinus rhythm
|
||||
(NOD Nodal (A-V junctional) rhythm
|
||||
(P Paced rhythm
|
||||
(PREX Pre-excitation (WPW)
|
||||
(SBR Sinus bradycardia
|
||||
(SVTA Supraventricular tachyarrhythmia
|
||||
(T Ventricular trigeminy
|
||||
(VFL Ventricular flutter
|
||||
(VT Ventricular tachycardia
|
||||
_
|
||||
T{
|
||||
Signal quality and comment annotations appear \fIabove\fR the level
|
||||
used for beat annotations:
|
||||
T}
|
||||
\fIqq\fR T{
|
||||
Signal quality change: the first character (`c' or `n') indicates the quality
|
||||
of the upper signal (clean or noisy), and the second character indicates the
|
||||
quality of the lower signal
|
||||
T}
|
||||
U Extreme noise or signal loss in both signals: ECG is unreadable
|
||||
M Missed beat (`MISSB' in examples, pp. 99\-177)
|
||||
P Pause (`PSE' in examples)
|
||||
T Tape slippage (`TS' in examples)
|
||||
.TE
|
||||
@@ -0,0 +1,216 @@
|
||||
# file: makefile G. Moody 22 August 1988
|
||||
# Last revised: 19 May 1997
|
||||
# 'make' description file for printing MIT-BIH Arrhythmia Database Directory
|
||||
#
|
||||
# Copyright(C) Massachusetts Institute of Technology 1997. All rights reserved.
|
||||
|
||||
# This file is used with the UNIX `make' command to print a copy of the MIT-BIH
|
||||
# Arrhythmia Database Directory. To do so, you will need a PostScript printer,
|
||||
# the GNU `gzip' utility (see ../../software/gzip124.tar), `pschart' and `psfd'
|
||||
# (sources are in `../../software/db/app'), about 220 sheets of paper, and
|
||||
# about 15 Mb for working space in the file system to which TMP (see below)
|
||||
# belongs. The directory containing the MIT-BIH Arrhythmia Database must be
|
||||
# named in the DB environment variable.
|
||||
|
||||
# If your printer is an Apple LaserWriter or equivalent, it will take about 10
|
||||
# hours to print the entire directory (and you will need to reload the paper
|
||||
# tray after about 5 hours). In theory, at least, a Linotronic phototypesetter
|
||||
# should be able to do the job in about 20 hours (send me a copy of the output
|
||||
# if you try this). Using a Sun SPARCprinter, the directory can be printed in
|
||||
# about 45 minutes. Your printer will not be busy throughout this period; it
|
||||
# will take a significant amount of time to generate the PostScript files to be
|
||||
# printed.
|
||||
|
||||
# To recreate the compressed PostScript files (for example, if you wish to
|
||||
# change the page format), you will also need `troff' and the `ms' macro
|
||||
# package, `tbl', a troff-to-PostScript translator (e.g., GNU `groff' or Adobe
|
||||
# `ptroff'), the System V `cut' command, and a TeX DVI-to-PostScript translator
|
||||
# (such as `dvips', included in the UNIX TeX distribution).
|
||||
|
||||
# Many (perhaps all) versions of the troff `ms' macros will generate a blank
|
||||
# page at the beginning or end of each section. Be sure to pull out the blank
|
||||
# sheets from the printer output before trying to make two-sided photocopies.
|
||||
# (Look for them between pages viii and 1, 97 and 98, 177 and 178, 188 and 189,
|
||||
# and 193 and 194; there should be a blank sheet following the table of
|
||||
# contents, however.) If your printer is capable of two-sided printing, I
|
||||
# suggest printing each section separately; note in particular that the
|
||||
# section of full disclosure plots begins on a left-hand page (so that each
|
||||
# record can be viewed in its entirety without turning the page).
|
||||
|
||||
# Before using this file for the first time, check that the site-specific
|
||||
# variables below are appropriate for your system. If you need to change any
|
||||
# of them, you may either:
|
||||
# 1. copy this entire directory to a writable file system, and edit this
|
||||
# file, or
|
||||
# 2. use command-line options to reset variables when running `make' (for
|
||||
# example, `make "PRINT=bogoprint -with -lots -of -options" ...' resets
|
||||
# the value of the PRINT variable; see your `make' documentation)
|
||||
# Print the test page by typing `make test'; if you get text rather than a
|
||||
# plot, add the `-u' option to variables CO and FO (see below) and try again.
|
||||
# Once you have successfully printed the test page, print the directory, by
|
||||
# typing `make directory'.
|
||||
|
||||
# Printed copies of the directory may also be obtained from MIT (see file
|
||||
# `../../ORDER.4M' for information).
|
||||
|
||||
# Site-specific variables.
|
||||
|
||||
# PRINT is the command that prints Postscript files. If possible, avoid
|
||||
# copying the files to a spooling directory -- this will save a little time
|
||||
# and a lot of space.
|
||||
PRINT = lpr -s
|
||||
|
||||
# TMP is the name of a directory in which temporary files can be written.
|
||||
# The full disclosure plots and the examples are each about 7 Mb; make sure
|
||||
# that TMP's file system has at least 15 Mb free if you are attempting to
|
||||
# print the entire directory in one operation.
|
||||
TMP = /tmp
|
||||
|
||||
# CO specifies options for `pschart'. You might want to remove the `-e' option
|
||||
# if you don't intend to make two-sided copies. Add a `-d' option if your
|
||||
# printer's resolution is higher than 300 dpi (e.g., add `-d 600' for a 600 dpi
|
||||
# printer). Some UNIX print spoolers cannot deal properly with `structured'
|
||||
# PostScript -- if the test page contains text rather than plots, add a `-u'
|
||||
# option (and be prepared to re-order the output if your printer delivers it
|
||||
# printed side down). See the `man' page for `pschart' (in
|
||||
# `../../software/db/doc/pschart.1', or the ECG Database Applications Guide)
|
||||
# for details.
|
||||
CO = -b 5 -e -g -l -r -R -V
|
||||
|
||||
# FO specifies options for `psfd'. As above, you might want to remove
|
||||
# the `-e' option, or add a `-d' or `-u' option.
|
||||
FO = -b 5 -e -g -l -R -V -x -1
|
||||
|
||||
# Uncomment the next line if your printer stacks output printed side up.
|
||||
SECTIONS = index tables notes ex extext fd fdtext intro contents title cover
|
||||
# Uncomment the next line if your printer stacks output printed side down.
|
||||
#SECTIONS = cover title contents intro fdtext fd extext ch notes tables index
|
||||
|
||||
# .............................................................................
|
||||
# Ignore these variables unless you want to regenerate the compressed
|
||||
# PostScript files in this directory.
|
||||
|
||||
# DVITPS is the name of the TeX DVI-to-PostScript translator.
|
||||
# `make title' only).
|
||||
DVITPS = dvitps
|
||||
|
||||
# TROFF is the name of the troff-to-PostScript translator.
|
||||
TROFF = ptroff -t
|
||||
|
||||
# TMS is the TROFF option needed to load the `ms' macro package. This should
|
||||
# not need to be changed unless your system is non-standard.
|
||||
TMS = -ms
|
||||
|
||||
# It should not be necessary to modify anything below this line.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
ZFILES = cover.gz title.gz contents.gz intro.gz fdtext.gz extext.gz \
|
||||
notes.gz tables.gz index.gz
|
||||
|
||||
.IGNORE:
|
||||
|
||||
# `make' or `make explain': describe this file
|
||||
explain:
|
||||
@echo If you have a PostScript printer, you can print a copy of the
|
||||
@echo MIT-BIH Arrhythmia Database Directory by typing:
|
||||
@echo " make directory"
|
||||
@echo Before attempting to doing so, read "'Makefile'" carefully.
|
||||
|
||||
# `make test': print a test page
|
||||
test:
|
||||
pschart $(CO) -n 999 -T "Test Page" extest >$(TMP)/ex.ps
|
||||
$(PRINT) $(TMP)/ex.ps
|
||||
|
||||
# `make directory': print the entire directory
|
||||
directory: $(SECTIONS) clean
|
||||
|
||||
# `make psz': regenerate compressed PostScript files
|
||||
psz: $(ZFILES)
|
||||
|
||||
# `make' targets for printing each section of the directory
|
||||
|
||||
cover: # outside cover
|
||||
gzip -d <cover.gz | $(PRINT)
|
||||
cover.gz: cover.tr
|
||||
$(TROFF) cover.tr | gzip >cover.gz
|
||||
|
||||
title: # title page, copyright notice
|
||||
gzip -d <title.gz | $(PRINT)
|
||||
title.gz: title.dvi
|
||||
dvips title.dvi | gzip >title.gz
|
||||
$(DVIPRINT) title.dvi
|
||||
|
||||
contents: # table of contents
|
||||
gzip -d <contents.gz | $(PRINT)
|
||||
contents.gz: contents.tr
|
||||
tbl contents.tr | $(TROFF) | gzip >contents.gz
|
||||
|
||||
intro: # foreword, introduction, table of symbols
|
||||
gzip -d <intro.gz | $(PRINT)
|
||||
intro.gz:
|
||||
tbl intro.tr | $(TROFF) $(TMS) | gzip >intro.gz
|
||||
|
||||
fdtext: # introduction to section of full disclosures
|
||||
gzip -d <fdtext.gz | $(PRINT)
|
||||
fdtext.gz: fdtext.tr
|
||||
$(TROFF) $(TMS) fdtext.tr | gzip >fdtext.gz
|
||||
|
||||
fd: # annotated full disclosure plots
|
||||
psfd $(FO) -n 2 -T "MIT-BIH Arrhythmia Database" fdlist >$(TMP)/fd.ps
|
||||
$(PRINT) $(TMP)/fd.ps
|
||||
|
||||
extext: # introduction to section of example strips
|
||||
gzip -d <extext.gz | $(PRINT)
|
||||
extext.gz: extext.tr
|
||||
$(TROFF) $(TMS) extext.tr | gzip >extext.gz
|
||||
|
||||
ex: # annotated example strips
|
||||
pschart $(CO) -n 99 -T Examples exlist >$(TMP)/ex.ps
|
||||
$(PRINT) $(TMP)/ex.ps
|
||||
|
||||
notes: # demographic and statistical summaries
|
||||
gzip -d <notes.gz | $(PRINT)
|
||||
notes.gz: $(TMP)/notes.tr
|
||||
tbl $(TMP)/notes.tr | $(TROFF) $(TMS) | gzip >notes.gz
|
||||
$(TMP)/notes.tr: $(TMP)/dbnotes # generate tbl/troff file of notes
|
||||
cp notes.h $(TMP)/notes.tr
|
||||
chmod u+w $(TMP)/notes.tr
|
||||
domit "$(TMP)/dbnotes atruth" >>$(TMP)/notes.tr
|
||||
$(TMP)/dbnotes: dbnotes.c # notes file generating program
|
||||
cp dbnotes.c $(TMP)
|
||||
cd $(TMP); cc -o dbnotes -O dbnotes.c -ldb
|
||||
rm -f $(TMP)/dbnotes.c
|
||||
|
||||
tables: # tables of beats and rhythms
|
||||
gzip -d <tables.gz | $(PRINT)
|
||||
tables.gz: $(TMP)/tables.tr
|
||||
tbl $(TMP)/tables.tr | $(TROFF) $(TMS) | gzip >tables.gz
|
||||
$(TMP)/tables.tr: $(TMP)/dbtab # generate tbl/troff file of tables
|
||||
sh ./domit "$(TMP)/dbtab atruth" >$(TMP)/dbt.out
|
||||
cp tab.1 $(TMP)/tables.tr
|
||||
chmod u+w $(TMP)/tables.tr
|
||||
cut -f1-18 <$(TMP)/dbt.out >>$(TMP)/tables.tr
|
||||
cat tab.2 >>$(TMP)/tables.tr
|
||||
cut -f1,19-33 <$(TMP)/dbt.out | tr -d " " >>$(TMP)/tables.tr
|
||||
sh ./domit "$(TMP)/dbtab atruth" -t >$(TMP)/dbt.out
|
||||
cat tab.3 >>$(TMP)/tables.tr
|
||||
cut -f1-18 <$(TMP)/dbt.out >>$(TMP)/tables.tr
|
||||
cat tab.4 >>$(TMP)/tables.tr
|
||||
cut -f1,19-33 <$(TMP)/dbt.out | tr -d " " >>$(TMP)/tables.tr
|
||||
cat tab.5 >>$(TMP)/tables.tr
|
||||
rm -f $(TMP)/dbt.out
|
||||
|
||||
$(TMP)/dbtab: dbtab.c # table generating program
|
||||
cp dbtab.c $(TMP)
|
||||
cd $(TMP); cc -o dbtab -O dbtab.c -ldb
|
||||
rm -f $(TMP)/dbtab.c
|
||||
|
||||
index: # index of full disclosures, examples, notes
|
||||
gzip -d <index.gz | $(PRINT)
|
||||
index.gz:
|
||||
tbl index.tr | $(TROFF) $(TMS) | gzip >index.gz
|
||||
|
||||
|
||||
# `make clean': remove output files from TMP
|
||||
clean:
|
||||
cd $(TMP); rm -f fd.ps ex.ps notes.tr tables.tr dbnotes dbtab
|
||||
@@ -0,0 +1,222 @@
|
||||
# file: makefile G. Moody 22 August 1988
|
||||
# Last revised: 19 May 1997
|
||||
# 'make' description file for printing MIT-BIH Arrhythmia Database Directory
|
||||
#
|
||||
# Copyright(C) Massachusetts Institute of Technology 1997. All rights reserved.
|
||||
|
||||
# This file is used with the UNIX `make' command to print a copy of the MIT-BIH
|
||||
# Arrhythmia Database Directory. To do so, you will need a PostScript printer,
|
||||
# the GNU `gzip' utility (see ../../software/gzip124.tar), `pschart' and `psfd'
|
||||
# (sources are in `../../software/db/app'), about 220 sheets of paper, and
|
||||
# about 15 Mb for working space in the file system to which TMP (see below)
|
||||
# belongs. The directory containing the MIT-BIH Arrhythmia Database must be
|
||||
# named in the DB environment variable.
|
||||
|
||||
# If your printer is an Apple LaserWriter or equivalent, it will take about 10
|
||||
# hours to print the entire directory (and you will need to reload the paper
|
||||
# tray after about 5 hours). In theory, at least, a Linotronic phototypesetter
|
||||
# should be able to do the job in about 20 hours (send me a copy of the output
|
||||
# if you try this). Using a Sun SPARCprinter, the directory can be printed in
|
||||
# about 45 minutes. Your printer will not be busy throughout this period; it
|
||||
# will take a significant amount of time to generate the PostScript files to be
|
||||
# printed.
|
||||
|
||||
# To recreate the compressed PostScript files (for example, if you wish to
|
||||
# change the page format), you will also need `troff' and the `ms' macro
|
||||
# package, `tbl', a troff-to-PostScript translator (e.g., GNU `groff' or Adobe
|
||||
# `ptroff'), the System V `cut' command, and a TeX DVI-to-PostScript translator
|
||||
# (such as `dvips', included in the UNIX TeX distribution).
|
||||
|
||||
# Many (perhaps all) versions of the troff `ms' macros will generate a blank
|
||||
# page at the beginning or end of each section. Be sure to pull out the blank
|
||||
# sheets from the printer output before trying to make two-sided photocopies.
|
||||
# (Look for them between pages viii and 1, 97 and 98, 177 and 178, 188 and 189,
|
||||
# and 193 and 194; there should be a blank sheet following the table of
|
||||
# contents, however.) If your printer is capable of two-sided printing, I
|
||||
# suggest printing each section separately; note in particular that the
|
||||
# section of full disclosure plots begins on a left-hand page (so that each
|
||||
# record can be viewed in its entirety without turning the page).
|
||||
|
||||
# Before using this file for the first time, check that the site-specific
|
||||
# variables below are appropriate for your system. If you need to change any
|
||||
# of them, you may either:
|
||||
# 1. copy this entire directory to a writable file system, and edit this
|
||||
# file, or
|
||||
# 2. use command-line options to reset variables when running `make' (for
|
||||
# example, `make "PRINT=bogoprint -with -lots -of -options" ...' resets
|
||||
# the value of the PRINT variable; see your `make' documentation)
|
||||
# Print the test page by typing `make test'; if you get text rather than a
|
||||
# plot, add the `-u' option to variables CO and FO (see below) and try again.
|
||||
# Once you have successfully printed the test page, print the directory, by
|
||||
# typing `make directory'.
|
||||
|
||||
# Printed copies of the directory may also be obtained from MIT (see file
|
||||
# `../../ORDER.4M' for information).
|
||||
|
||||
# Site-specific variables.
|
||||
|
||||
# PRINT is the command that prints Postscript files. If possible, avoid
|
||||
# copying the files to a spooling directory -- this will save a little time
|
||||
# and a lot of space.
|
||||
PRINT = lpr -s
|
||||
|
||||
# TMP is the name of a directory in which temporary files can be written.
|
||||
# The full disclosure plots and the examples are each about 7 Mb; make sure
|
||||
# that TMP's file system has at least 15 Mb free if you are attempting to
|
||||
# print the entire directory in one operation.
|
||||
TMP = .
|
||||
|
||||
# CO specifies options for `pschart'. You might want to remove the `-e' option
|
||||
# if you don't intend to make two-sided copies. Add a `-d' option if your
|
||||
# printer's resolution is higher than 300 dpi (e.g., add `-d 600' for a 600 dpi
|
||||
# printer). Some UNIX print spoolers cannot deal properly with `structured'
|
||||
# PostScript -- if the test page contains text rather than plots, add a `-u'
|
||||
# option (and be prepared to re-order the output if your printer delivers it
|
||||
# printed side down). See the `man' page for `pschart' (in
|
||||
# `../../software/db/doc/pschart.1', or the ECG Database Applications Guide)
|
||||
# for details.
|
||||
CO = -b 5 -e -g -l -r -R -V
|
||||
|
||||
# FO specifies options for `psfd'. As above, you might want to remove
|
||||
# the `-e' option, or add a `-d' or `-u' option.
|
||||
FO = -b 5 -e -g -l -R -V -x -1
|
||||
|
||||
# Uncomment the next line if your printer stacks output printed side up.
|
||||
SECTIONS = index tables notes ex extext fd fdtext intro contents title cover
|
||||
# Uncomment the next line if your printer stacks output printed side down.
|
||||
#SECTIONS = cover title contents intro fdtext fd extext ch notes tables index
|
||||
|
||||
# .............................................................................
|
||||
# Ignore these variables unless you want to regenerate the compressed
|
||||
# PostScript files in this directory.
|
||||
|
||||
# DVITPS is the name of the TeX DVI-to-PostScript translator.
|
||||
# `make title' only).
|
||||
DVITPS = dvitps
|
||||
|
||||
# TROFF is the name of the troff-to-PostScript translator.
|
||||
TROFF = ptroff -t
|
||||
|
||||
# TMS is the TROFF option needed to load the `ms' macro package. This should
|
||||
# not need to be changed unless your system is non-standard.
|
||||
TMS = -ms
|
||||
|
||||
# It should not be necessary to modify anything below this line.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
ZFILES = cover.gz title.gz contents.gz intro.gz fdtext.gz extext.gz \
|
||||
notes.gz tables.gz index.gz
|
||||
|
||||
.IGNORE:
|
||||
|
||||
# `make' or `make explain': describe this file
|
||||
explain:
|
||||
@echo If you have a PostScript printer, you can print a copy of the
|
||||
@echo MIT-BIH Arrhythmia Database Directory by typing:
|
||||
@echo " make directory"
|
||||
@echo Before attempting to doing so, read "'Makefile'" carefully.
|
||||
|
||||
# `make test': print a test page
|
||||
test:
|
||||
pschart $(CO) -n 999 -T "Test Page" extest >$(TMP)/ex.ps
|
||||
$(PRINT) $(TMP)/ex.ps
|
||||
|
||||
# `make directory': print the entire directory
|
||||
directory: $(SECTIONS) clean
|
||||
|
||||
# `make psz': regenerate compressed PostScript files
|
||||
psz: $(ZFILES)
|
||||
|
||||
# `make' targets for printing each section of the directory
|
||||
|
||||
cover: # outside cover
|
||||
gzip -d <cover.gz | $(PRINT)
|
||||
cover.gz: cover.tr
|
||||
$(TROFF) cover.tr | gzip >cover.gz
|
||||
|
||||
title: # title page, copyright notice
|
||||
gzip -d <title.gz | $(PRINT)
|
||||
title.gz: title.dvi
|
||||
dvips title.dvi | gzip >title.gz
|
||||
$(DVIPRINT) title.dvi
|
||||
|
||||
contents: # table of contents
|
||||
gzip -d <contents.gz | $(PRINT)
|
||||
contents.gz: contents.tr
|
||||
tbl contents.tr | $(TROFF) | gzip >contents.gz
|
||||
|
||||
intro: # foreword, introduction, table of symbols
|
||||
gzip -d <intro.gz | $(PRINT)
|
||||
intro.gz:
|
||||
tbl intro.tr | $(TROFF) $(TMS) | gzip >intro.gz
|
||||
|
||||
fdtext: # introduction to section of full disclosures
|
||||
gzip -d <fdtext.gz | $(PRINT)
|
||||
fdtext.gz: fdtext.tr
|
||||
$(TROFF) $(TMS) fdtext.tr | gzip >fdtext.gz
|
||||
|
||||
fd: # annotated full disclosure plots
|
||||
psfd $(FO) -n 2 -T "MIT-BIH Arrhythmia Database" fdlist >$(TMP)/fd.ps
|
||||
$(PRINT) $(TMP)/fd.ps
|
||||
|
||||
extext: # introduction to section of example strips
|
||||
gzip -d <extext.gz | $(PRINT)
|
||||
extext.gz: extext.tr
|
||||
$(TROFF) $(TMS) extext.tr | gzip >extext.gz
|
||||
|
||||
ex: # annotated example strips
|
||||
pschart $(CO) -n 99 -T Examples exlist >$(TMP)/ex.ps
|
||||
$(PRINT) $(TMP)/ex.ps
|
||||
|
||||
notes: # demographic and statistical summaries
|
||||
gzip -d <notes.gz | $(PRINT)
|
||||
notes.gz: $(TMP)/notes.tr
|
||||
tbl $(TMP)/notes.tr | $(TROFF) $(TMS) | gzip >notes.gz
|
||||
$(TMP)/notes.tr: $(TMP)/dbnotes # generate tbl/troff file of notes
|
||||
cp notes.h $(TMP)/notes.tr
|
||||
chmod u+w $(TMP)/notes.tr
|
||||
domit "$(TMP)/dbnotes atruth" >>$(TMP)/notes.tr
|
||||
$(TMP)/dbnotes: dbnotes.c # notes file generating program
|
||||
cp dbnotes.c $(TMP)
|
||||
cd $(TMP); cc -o dbnotes -O dbnotes.c -ldb
|
||||
|
||||
$(TMP)/notes.htm: $(TMP)/dbnotes # generate HTML file of notes
|
||||
cp notes.ht0 $(TMP)/notes.htm
|
||||
chmod u+w $(TMP)/notes.htm
|
||||
domit "$(TMP)/dbnotes atruth" >>$(TMP)/notes.htm
|
||||
$(TMP)/dbnotes: dbnotes.c # notes file generating program
|
||||
cp dbnotes.c $(TMP)
|
||||
cd $(TMP); cc -o dbnotes -O dbnotes.c -ldb
|
||||
|
||||
tables: # tables of beats and rhythms
|
||||
gzip -d <tables.gz | $(PRINT)
|
||||
tables.gz: $(TMP)/tables.tr
|
||||
tbl $(TMP)/tables.tr | $(TROFF) $(TMS) | gzip >tables.gz
|
||||
$(TMP)/tables.tr: $(TMP)/dbtab # generate tbl/troff file of tables
|
||||
sh ./domit "$(TMP)/dbtab atruth" >$(TMP)/dbt.out
|
||||
cp tab.1 $(TMP)/tables.tr
|
||||
chmod u+w $(TMP)/tables.tr
|
||||
cut -f1-18 <$(TMP)/dbt.out >>$(TMP)/tables.tr
|
||||
cat tab.2 >>$(TMP)/tables.tr
|
||||
cut -f1,19-33 <$(TMP)/dbt.out | tr -d " " >>$(TMP)/tables.tr
|
||||
sh ./domit "$(TMP)/dbtab atruth" -t >$(TMP)/dbt.out
|
||||
cat tab.3 >>$(TMP)/tables.tr
|
||||
cut -f1-18 <$(TMP)/dbt.out >>$(TMP)/tables.tr
|
||||
cat tab.4 >>$(TMP)/tables.tr
|
||||
cut -f1,19-33 <$(TMP)/dbt.out | tr -d " " >>$(TMP)/tables.tr
|
||||
cat tab.5 >>$(TMP)/tables.tr
|
||||
rm -f $(TMP)/dbt.out
|
||||
|
||||
$(TMP)/dbtab: dbtab.c # table generating program
|
||||
cp dbtab.c $(TMP)
|
||||
cd $(TMP); cc -o dbtab -O dbtab.c -ldb
|
||||
|
||||
index: # index of full disclosures, examples, notes
|
||||
gzip -d <index.gz | $(PRINT)
|
||||
index.gz:
|
||||
tbl index.tr | $(TROFF) $(TMS) | gzip >index.gz
|
||||
|
||||
|
||||
# `make clean': remove output files from TMP
|
||||
clean:
|
||||
cd $(TMP); rm -f fd.ps ex.ps notes.tr tables.tr dbnotes dbtab
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/perl
|
||||
# file: makelinks.pl G. Moody 30 October 1996
|
||||
#
|
||||
# This program rewrites an HTML file of MIMIC database clinical data, adding
|
||||
# links to wavescript .xws files (also generated here) to any flagged date/time
|
||||
# stamps found in the input file. The `@' character should be placed before
|
||||
# and after each date/time stamp in order to flag it for processing. The
|
||||
# rewritten HTML appears on the standard output.
|
||||
#
|
||||
# Note: date/time stamps in the input should be in hh:mm:ss dd/mm/yyyy format.
|
||||
|
||||
while (<>) {
|
||||
if (/\d{3} /) {
|
||||
chop();
|
||||
@fields = split(/ /, $_);
|
||||
$record = shift(@fields);
|
||||
$tstamp = shift(@fields);
|
||||
if (! $tstamp =~ /\d/) {
|
||||
$tstamp = shift(@fields);
|
||||
}
|
||||
@tparts = split(/:/, $tstamp);
|
||||
$minute = shift(@tparts);
|
||||
$second = shift(@tparts);
|
||||
$xws = sprintf("samples/%3d%02d%02d.xws", $record, $minute, $second);
|
||||
print "<a href=\"$xws\">$tstamp</a>";
|
||||
while ($word = shift(@fields)) {
|
||||
print " $word";
|
||||
}
|
||||
print "<br>\n";
|
||||
open(XWS, ">$xws");
|
||||
print XWS "-r $record\n";
|
||||
print XWS "-a atr\n";
|
||||
print XWS "-f $minute:$second\n";
|
||||
close(XWS);
|
||||
} else {
|
||||
print;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,24 @@
|
||||
.LP
|
||||
.ds LH \s10MIT-BIH A\s8RRHYTHMIA\s10 D\s8ATABASE\s10
|
||||
.ds RH \s10N\s8OTES\s10
|
||||
.bp 178
|
||||
.ce 1
|
||||
\fB\s+2NOTES\s-2\fP
|
||||
.PP
|
||||
The following pages contain notes and statistics that describe the contents of
|
||||
each record.
|
||||
The leads used for the upper and lower signals are given for each record
|
||||
immediately following the record number.
|
||||
Beat counts are given for the first five minutes of each record and
|
||||
the remainder of the record (the AAMI-defined ``learning'' and ``test''
|
||||
periods, respectively).
|
||||
Note that the totals include two types of non-beats (blocked APCs and
|
||||
ventricular flutter waves) for those few records in which they occur.
|
||||
The total duration of each record is 30 minutes and 5.556 seconds; durations
|
||||
noted below are rounded to the nearest second, and may not sum to exactly
|
||||
30:06 because of accumulated rounding error.
|
||||
Heart rates are given in beats per minute measured over 3 R-R intervals.
|
||||
.nr PS 8
|
||||
.nr VS 10
|
||||
.LP
|
||||
.2C
|
||||
@@ -0,0 +1,116 @@
|
||||
@echo off
|
||||
: file: printdir.bat G. Moody 11 August 1992
|
||||
|
||||
: MS-DOS batch file for printing the MIT-BIH Arrhythmia Database Directory
|
||||
|
||||
: Copyright(C) Massachusetts Institute of Technology 1992. All rights reserved.
|
||||
|
||||
echo If you have a PostScript printer, you can use this program to print a copy
|
||||
echo of the MIT-BIH Arrhythmia Database Directory on it. It will take about 10
|
||||
echo hours to print the entire 200-page directory. Make sure that the current
|
||||
echo drive contains the MIT-BIH Arrhythmia Database CD-ROM, and that the TEMP
|
||||
echo variable names a writable directory with at least 15 Mb free. The current
|
||||
echo value of TEMP is %TEMP%.
|
||||
|
||||
echo If you want to do anything other than print the entire directory, see the
|
||||
echo UNIX 'makefile' in this directory; it can be used with Microsoft or
|
||||
echo Borland 'make' with only minor changes.
|
||||
pause
|
||||
|
||||
echo This program needs to change the DB and PATH variables. When it finishes,
|
||||
echo you may wish to reset them to their current values, which are
|
||||
echo DB=%DB%
|
||||
echo PATH=%PATH%
|
||||
pause
|
||||
|
||||
: DB gets cleared out, so that 'psfd' and 'pschart' use their built-in default
|
||||
: DB paths to find the records. This works only if the CD-ROM is in the
|
||||
: current drive.
|
||||
set DB=
|
||||
|
||||
: The 'bin' directory of the CD-ROM goes at the front of the new PATH, so that
|
||||
: the correct versions of 'gzip', 'pschart', and 'psfd' will be found.
|
||||
set PATH=\bin;%PATH%
|
||||
|
||||
echo OK, let's see if your printer can print a test page. This may take
|
||||
echo up to 5 minutes ... when it's done, you should get a plot with a 12-second
|
||||
echo ECG strip at the top of a (mostly empty) page. If you get lots of text
|
||||
echo instead, you may need to modify this batch file. CHECK THE OUTPUT BEFORE
|
||||
echo CONTINUING.
|
||||
|
||||
pschart -b 5 -e -g -l -r -R -V -n 999 -T "Test Page" extest >%TEMP%\ex.ps
|
||||
print %TEMP%\ex.ps
|
||||
pause
|
||||
|
||||
echo Now printing the directory ...
|
||||
|
||||
: outside cover
|
||||
copy cover.z %TEMP%
|
||||
gzip -d %TEMP%\cover
|
||||
print %TEMP%\cover
|
||||
|
||||
: title page, copyright notice
|
||||
copy title.z %TEMP%
|
||||
gzip -d %TEMP%\title
|
||||
print %TEMP%\title
|
||||
|
||||
: table of contents
|
||||
copy contents.z %TEMP%
|
||||
gzip -d %TEMP%\contents
|
||||
print %TEMP%\contents
|
||||
|
||||
: foreword, introduction, table of symbols
|
||||
copy intro.z %TEMP%
|
||||
gzip -d %TEMP%\intro
|
||||
print %TEMP%\intro
|
||||
|
||||
: introduction to section of full disclosures
|
||||
copy fdtext.z %TEMP%
|
||||
gzip -d %TEMP%\fdtext
|
||||
print %TEMP%\fdtext
|
||||
|
||||
: annotated full disclosure plots
|
||||
: If disk space is low, you might try sending the output directly to PRN
|
||||
psfd -b 5 -e -g -l -R -V -x -1 -n 2 -T "MIT-BIH Arrhythmia Database" fdlist >%TEMP%\fd.ps
|
||||
print %TEMP%\fd.ps
|
||||
|
||||
: introduction to section of example strips
|
||||
copy extext.z %TEMP%
|
||||
gzip -d %TEMP%\extext
|
||||
print %TEMP%\extext
|
||||
|
||||
: annotated example strips
|
||||
: If disk space is low, you might try sending the output directly to PRN
|
||||
pschart -b 5 -e -g -l -r -R -V -n 99 -T Examples exlist >%TEMP%\ex.ps
|
||||
print %TEMP%\ex.ps
|
||||
|
||||
: demographic and statistical summaries
|
||||
copy notes.z %TEMP%
|
||||
gzip -d %TEMP%\notes
|
||||
print %TEMP%\notes
|
||||
|
||||
: tables of beats and rhythms
|
||||
copy tables.z %TEMP%
|
||||
gzip -d %TEMP%\tables
|
||||
print %TEMP%\tables
|
||||
|
||||
: index of full disclosures, examples, notes
|
||||
copy index.z %TEMP%
|
||||
gzip -d %TEMP%\index
|
||||
print %TEMP%\index
|
||||
|
||||
echo The entire directory has now been printed. Temporary files will be
|
||||
echo removed from %TEMP% next.
|
||||
pause
|
||||
|
||||
del %TEMP%\cover
|
||||
del %TEMP%\title
|
||||
del %TEMP%\contents
|
||||
del %TEMP%\intro
|
||||
del %TEMP%\fdtext
|
||||
del %TEMP%\fd.ps
|
||||
del %TEMP%\extext
|
||||
del %TEMP%\ex.ps
|
||||
del %TEMP%\notes
|
||||
del %TEMP%\tables
|
||||
del %TEMP%\index
|
||||
@@ -0,0 +1,63 @@
|
||||
.nr PS 10
|
||||
.nr VS 12
|
||||
.LP
|
||||
.ds LH \s10MIT-BIH A\s8RRHYTHMIA\s10 D\s8ATABASE\s10
|
||||
.ds RH \s10T\s8ABLES\s10
|
||||
.bp 189
|
||||
.1C
|
||||
.DS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.DE
|
||||
.ce 1
|
||||
\fB\s12TABLES OF BEATS AND RHYTHMS\s10\fP
|
||||
|
||||
|
||||
.PP
|
||||
The following pages contain tables that summarize the contents of the
|
||||
database.
|
||||
These tables duplicate some of the contents of the previous
|
||||
section (Notes), to which reference should be made for more details.
|
||||
The first two tables list the beat types and rhythms for
|
||||
each half-hour record in its entirety. The last two tables show the
|
||||
same information, but for the AAMI-defined ``test periods'' only
|
||||
(i.e., excluding the first five minutes of each record).
|
||||
.PP
|
||||
The column headings for the beat tables show the AHA annotation codes
|
||||
(N, V, F, E, P, Q, and O) above the symbols used for the database annotations
|
||||
elsewhere in this book.
|
||||
A complete list of these symbols, as well as the abbreviations used as
|
||||
the column headings for the rhythm tables, may be found on page viii.
|
||||
.PP
|
||||
The beat tables show the number of beats of each type in each record.
|
||||
The rhythm tables show the total duration of each rhythm observed in each
|
||||
record in minutes and seconds (rounded to the nearest second).
|
||||
.bp
|
||||
.ce 1
|
||||
\fB\s12TABLE OF BEAT TYPES (ENTIRE RECORDS)\s10\fP
|
||||
.nr PS 7
|
||||
.nr VS 9
|
||||
.LP
|
||||
.TS
|
||||
center box;
|
||||
c | ce se se se se se se | ce | ce | ce | ce se | ce | ce | ce | ce | ce
|
||||
c | ce ce ce ce ce ce ce ce ce ce ce ce ce ce ce ce ce
|
||||
c | re re re re re re re re re re re re re re re re re.
|
||||
\fIRecord\fP \fIN V F O N E P F O Q\fP
|
||||
\^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
\^ \fB\(bu L R A a J S V F ! e j E P f p Q\fP
|
||||
_
|
||||
@@ -0,0 +1,12 @@
|
||||
.TE
|
||||
.bp
|
||||
.ce 1
|
||||
\fB\s12TABLE OF RHYTHMS (ENTIRE RECORDS)\s10\fP
|
||||
.nr PS 7
|
||||
.nr VS 9
|
||||
.LP
|
||||
.TS
|
||||
center box;
|
||||
c | re re re re re re re re re re re re re re re.
|
||||
\fIRecord\fB N SBR BII PREX AB SVTA AFL AFIB P NOD B T IVR VT VFL\fR
|
||||
_
|
||||
@@ -0,0 +1,16 @@
|
||||
.TE
|
||||
.bp
|
||||
.ce 1
|
||||
\fB\s12TABLE OF BEAT TYPES (TEST PERIODS ONLY)\s10\fP
|
||||
.nr PS 7
|
||||
.nr VS 9
|
||||
.LP
|
||||
.TS
|
||||
center box;
|
||||
c | ce se se se se se se | ce | ce | ce | ce se | ce | ce | ce | ce | ce
|
||||
c | ce ce ce ce ce ce ce ce ce ce ce ce ce ce ce ce ce
|
||||
c | re re re re re re re re re re re re re re re re re.
|
||||
\fIRecord\fP \fIN V F O N E P F O Q\fP
|
||||
\^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
\^ \fB\(bu L R A a J S V F ! e j E P f p Q\fP
|
||||
_
|
||||
@@ -0,0 +1,12 @@
|
||||
.TE
|
||||
.bp
|
||||
.ce 1
|
||||
\fB\s12TABLE OF RHYTHMS (TEST PERIODS ONLY)\s10\fP
|
||||
.nr PS 7
|
||||
.nr VS 9
|
||||
.LP
|
||||
.TS
|
||||
center box;
|
||||
c | re re re re re re re re re re re re re re re.
|
||||
\fIRecord\fB N SBR BII PREX AB SVTA AFL AFIB P NOD B T IVR VT VFL\fR
|
||||
_
|
||||
@@ -0,0 +1 @@
|
||||
.TE
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in new issue
Block a user