diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/app/bxb.c wfdb-10.5.5/app/bxb.c
--- wfdb-10.5.4/app/bxb.c 2002-11-24 15:15:04.000000000 -0500
+++ wfdb-10.5.5/app/bxb.c 2010-08-11 08:51:18.000000000 -0400
@@ -1,9 +1,9 @@
/* file: bxb.c G. Moody 14 December 1987
- Last revised: 24 November 2002
+ Last revised: 10 August 2010
-------------------------------------------------------------------------------
bxb: ANSI/AAMI-standard beat-by-beat annotation file comparator
-Copyright (C) 2002 George B. Moody
+Copyright (C) 2010 George B. Moody
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1074,7 +1074,13 @@
sstat(" F missed in shutdown", "%6.2f", Fx, Fn+Fs+Fv+Ff+Fq+Fo+Fx);
if (fflag == 1 || fflag == 3 || fflag == 4 || fflag == 6)
(void)fprintf(sfile, " Total shutdown time: ");
- (void)fprintf(sfile, "%5ld seconds\n", shut_down);
+ if (fflag != 2 && fflag != 5)
+ (void)fprintf(sfile, "%5ld seconds\n", shut_down);
+ else
+ (void)fprintf(sfile, "%5ld seconds %ld %ld %ld %ld %ld\n", shut_down,
+ Nn+Ns+Nv+Nf+Nq+No+Nx, Sn+Ss+Sv+Sf+Sq+So+Sx,
+ Vn+Vs+Vv+Vf+Vq+Vo+Vx, Fn+Fs+Fv+Ff+Fq+Fo+Fx,
+ Qn+Qs+Qv+Qf+Qq+Qo+Qx);
}
static char *help_strings[] = {
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/app/ecgeval.c wfdb-10.5.5/app/ecgeval.c
--- wfdb-10.5.4/app/ecgeval.c 2006-11-30 10:09:01.000000000 -0500
+++ wfdb-10.5.5/app/ecgeval.c 2010-07-27 13:52:41.000000000 -0400
@@ -1,9 +1,9 @@
/* file: ecgeval.c G. Moody 22 March 1992
- Last revised: 30 November 2006
+ Last revised: 27 July 2010
-------------------------------------------------------------------------------
ecgeval: Generate and run a script of commands to compare sets of annotations
-Copyright (C) 1992-2006 George B. Moody
+Copyright (C) 1992-2010 George B. Moody
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -384,17 +384,19 @@
getans(tans, 20);
if (tans[0] == 'a') {
if ((sfile = fopen(scriptname, "a")) == NULL)
- (void)fprintf(stderr, "Sorry, I can't append to `%s'.\n");
+ (void)fprintf(stderr, "Sorry, I can't append to `%s'.\n",
+ scriptname);
}
else if (tans[0] == 'r') {
if ((sfile = fopen(scriptname, "w")) == NULL)
- (void)fprintf(stderr, "Sorry, I can't replace `%s'.\n");
+ (void)fprintf(stderr, "Sorry, I can't replace `%s'.\n",
+ scriptname);
}
else
sfile = NULL;
}
else if ((sfile = fopen(scriptname, "w")) == NULL)
- (void)fprintf(stderr, "Sorry, I can't create `%s'.\n");
+ (void)fprintf(stderr, "Sorry, I can't create `%s'.\n", scriptname);
if (sfile == NULL)
scriptname[0] = '\0';
@@ -424,17 +426,19 @@
getans(tans, 20);
if (tans[0] == 'a') {
if ((rfile = fopen(reportname, "a")) == NULL)
- (void)fprintf(stderr, "Sorry, I can't append to `%s'.\n");
+ (void)fprintf(stderr, "Sorry, I can't append to `%s'.\n",
+ reportname);
}
else if (tans[0] == 'r') {
if ((rfile = fopen(reportname, "w")) == NULL)
- (void)fprintf(stderr, "Sorry, I can't replace `%s'.\n");
+ (void)fprintf(stderr, "Sorry, I can't replace `%s'.\n",
+ reportname);
}
else
rfile = NULL;
}
else if ((rfile = fopen(reportname, "w")) == NULL)
- (void)fprintf(stderr, "Sorry, I can't create `%s'.\n");
+ (void)fprintf(stderr, "Sorry, I can't create `%s'.\n", reportname);
if (rfile == NULL)
reportname[0] = '\0';
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/app/psfd.c wfdb-10.5.5/app/psfd.c
--- wfdb-10.5.4/app/psfd.c 2009-05-27 15:47:52.000000000 -0400
+++ wfdb-10.5.5/app/psfd.c 2010-07-27 13:53:48.000000000 -0400
@@ -1,9 +1,9 @@
/* file: psfd.c G. Moody 9 August 1988
- Last revised: 27 May 2009
+ Last revised: 27 July 2010
-------------------------------------------------------------------------------
psfd: Produces annotated full-disclosure ECG plots on a PostScript device
-Copyright (C) 1988-2009 George B. Moody
+Copyright (C) 1988-2010 George B. Moody
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -379,7 +379,7 @@
if (Mflag < 0 || Mflag > 3) {
(void)fprintf(stderr,
"%s: incorrect format (%d) specified after -M\n",
- pname);
+ pname, Mflag);
exit(1);
}
}
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/app/rdsamp.c wfdb-10.5.5/app/rdsamp.c
--- wfdb-10.5.4/app/rdsamp.c 2010-07-02 00:39:48.000000000 -0400
+++ wfdb-10.5.5/app/rdsamp.c 2010-10-06 22:01:25.000000000 -0400
@@ -1,5 +1,5 @@
/* file: rdsamp.c G. Moody 23 June 1983
- Last revised: 16 March 2010
+ Last revised: 6 October 2010
-------------------------------------------------------------------------------
rdsamp: Print an arbitrary number of samples from each signal
@@ -38,6 +38,12 @@
#define HHMMSS 7
#define SAMPLES 8
+#define WFDBXMLPROLOG "\n" \
+ "\n" \
+ "\n"
+
char *pname;
main(argc, argv)
@@ -47,7 +53,7 @@
char *record = NULL, *search = NULL, *escapify(), *prog_name();
char *invalid, *snfmt, *tfmt, *tnfmt, *tufmt, *vfmt, speriod[16], tustr[16];
int cflag = 0, highres = 0, i, isiglist, nsig, nosig = 0, pflag = 0, s,
- *sig = NULL, timeunits = SECONDS, vflag = 0;
+ *sig = NULL, timeunits = SECONDS, vflag = 0, xflag = 0;
WFDB_Frequency freq;
WFDB_Sample *v;
WFDB_Siginfo *si;
@@ -132,6 +138,9 @@
case 'v': /* verbose output -- include column headings */
vflag = 1;
break;
+ case 'X': /* output in WFDB-XML format */
+ xflag = cflag = vflag = 1; /* format is CSV inside an XML wrapper */
+ break;
default:
(void)fprintf(stderr, "%s: unrecognized option %s\n", pname,
argv[i]);
@@ -245,7 +254,6 @@
}
else { /* output in raw units */
tnfmt = "'sample #'";
- // sprintf(tufmt, "'%g sec'", 1./freq);
tfmt = "%ld";
vfmt = ",%d";
}
@@ -293,12 +301,20 @@
}
}
+ /* Print WFDB-XML prolog if '-x' option selected. */
+ if (xflag) {
+ printf(WFDBXMLPROLOG);
+ printf("\n"
+ "%g\n"
+ "%d\n",
+ freq, nsig);
+ }
/* Print column headers if '-v' option selected. */
if (vflag) {
char *p, *t;
int j, l;
- (void)printf(tnfmt);
+ (void)printf("%s", tnfmt);
for (i = 0; i < nsig; i++) {
/* Check if a default signal description was provided by looking
@@ -325,7 +341,7 @@
p = escapify(p);
(void)printf(snfmt, p);
}
-
+ if (xflag) (void)printf("");
(void)printf("\n");
}
@@ -338,7 +354,8 @@
if (vflag) {
char s[12];
- (void)printf(tufmt);
+ if (xflag) (void)printf("");
+ (void)printf("%s", tufmt);
for (i = 0; i < nsig; i++) {
p = si[sig[i]].units;
@@ -360,10 +377,11 @@
(void)printf(",'%s'", p);
}
}
-
+ if (xflag) (void)printf("");
(void)printf("\n");
}
+ if (xflag) (void)printf("\n", nsig+1);
while ((to == 0L || from < to) && getvec(v) >= 0) {
if (cflag == 0) {
switch (timeunits) {
@@ -412,13 +430,14 @@
(void)printf(vfmt,
((double)v[sig[i]] - si[sig[i]].baseline)/si[sig[i]].gain);
else
- (void)printf(invalid);
+ (void)printf("%s", invalid);
}
(void)printf("\n");
}
}
else { /* output in raw units */
+ if (xflag) (void)printf("\n", nsig+1);
while ((to == 0L || from < to) && getvec(v) >= 0) {
(void)printf(tfmt, from++);
for (i = 0; i < nsig; i++)
@@ -427,6 +446,9 @@
}
}
+ if (xflag) /* print trailer if WFDB-XML output was selected */
+ printf("\n\n");
+
exit(0);
}
@@ -494,6 +516,7 @@
" the time specified with -f, and begin printing then",
" -t TIME stop at specified time",
" -v print column headings",
+ " -X output in WFDB-XML format",
NULL
};
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/app/snip.c wfdb-10.5.5/app/snip.c
--- wfdb-10.5.4/app/snip.c 2009-04-17 01:50:17.000000000 -0400
+++ wfdb-10.5.5/app/snip.c 2010-07-27 13:59:43.000000000 -0400
@@ -1,8 +1,8 @@
/* file: snip.c G. Moody 30 July 1989
- Last revised: 17 April 2009
+ Last revised: 27 July 2010
-------------------------------------------------------------------------------
snip: Copy an excerpt of a database record
-Copyright (C) 1989-2009 George B. Moody
+Copyright (C) 1989-2010 George B. Moody
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -341,7 +341,7 @@
wfdb_fgets(buf, sizeof(buf), ihfile);
/* Start writing the master output header. */
- fprintf(ohfile, "%s/%d %d %.12g %d", nrec, nseg, nsig, sfreq, to-from);
+ fprintf(ohfile, "%s/%d %d %.12g %ld", nrec, nseg, nsig, sfreq, to-from);
if (tstring[0]) fprintf(ohfile, " %s", tstring);
fprintf(ohfile, "\r\n");
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/app/sortann.c wfdb-10.5.5/app/sortann.c
--- wfdb-10.5.4/app/sortann.c 2009-02-04 10:54:28.000000000 -0500
+++ wfdb-10.5.5/app/sortann.c 2010-10-04 14:06:44.000000000 -0400
@@ -1,8 +1,8 @@
/* file sortann.c G. Moody 7 April 1997
- Last revised: 4 February 2009
+ Last revised: 4 October 2010
-------------------------------------------------------------------------------
sortann: Rearrange annotations in canonical order
-Copyright (C) 1997-2009 George B. Moody
+Copyright (C) 1997-2010 George B. Moody
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -162,9 +162,9 @@
exit(1);
}
- /* By setting WFDBNOSORT, we ensure that wfdbquit won't invoke this program
+ /* By setting WFDBANNSORT, we ensure that wfdbquit won't invoke this program
recursively if something goes wrong. */
- putenv("WFDBNOSORT=1");
+ putenv("WFDBANNSORT=0");
if ((sps = sampfreq(record)) < 0.)
(void)setsampfreq(sps = WFDB_DEFFREQ);
@@ -245,9 +245,12 @@
(newp->annotation).aux = p;
}
if (lastp == &annlist ||
- pa->chan > (lastp->annotation).chan ||
- pa->num > (lastp->annotation).num ||
- pa->time > (lastp->annotation).time) {
+ pa->time > (lastp->annotation).time ||
+ (pa->time == (lastp->annotation).time &&
+ pa->num > (lastp->annotation).num) ||
+ (pa->time == (lastp->annotation).time &&
+ pa->num == (lastp->annotation).num &&
+ pa->chan > (lastp->annotation).chan)) {
/* this annotation is in order -- add to end of list */
newp->prev = lastp;
lastp->next = newp;
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/app/sumstats.c wfdb-10.5.5/app/sumstats.c
--- wfdb-10.5.4/app/sumstats.c 2005-08-19 21:25:59.000000000 -0400
+++ wfdb-10.5.5/app/sumstats.c 2010-08-10 22:28:17.000000000 -0400
@@ -1,8 +1,8 @@
/* file: sumstats.c G. Moody 17 August 1989
- Last revised: 19 August 2005
+ Last revised: 10 August 2010
-------------------------------------------------------------------------------
sumstats: Derive aggregate statistics from bxb, rxr, or epic line-format output
-Copyright (C) 1989-2005 George B. Moody
+Copyright (C) 1989-2010 George B. Moody
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -34,7 +34,8 @@
#include
#include
-static int nrec, NQS, NQP, NVS, NVP, NVF, NSVS, NSVP, NRRE;
+static int nrec, Nrec, Vrec, Frec;
+static int NQS, NQP, NVS, NVP, NVF, NSVS, NSVP, NRRE;
static long Nn, Ns, Nv, No, Nx,
Sn, Ss, Sv, So, Sx,
Vn, Vs, Vv, Vo, Vx,
@@ -45,8 +46,9 @@
static long CTS, CFN, CTP, CFP, STS, SFN, STP, SFP, LTS, LFN, LTP, LFP;
static long ETS, EFN, ETP, EFP;
static long NCS, NCP, NSS, NSP, NLS, NLP, NES, NEP, NDS, NDP;
+static long NT, VT, FT, QT;
static long detected_episode_length, overlap, total_episode_length;
-static double CQS, CQP, CVS, CVP, CVF, CSVS, CSVP, CRRE;
+static double CQS, CQP, CVS, CVP, CVF, CSVS, CSVP, CRRE, CBM, CNM, CVM, CFM;
static double CCS, CCP, CSS, CSP, CLS, CLP, CES, CEP, CDS, CDP, CERR, CMREF;
char *pname; /* name by which this program was invoked */
@@ -178,6 +180,18 @@
(void)printf("______________\n");
(void)printf("Sum %4ld %4ld %4ld %4ld", Nx, Vx, Fx, Qx);
(void)printf(" %4ld seconds\n", ST);
+ (void)printf("Gross ");
+ pstat(" %6.2f", (double)Nx+Vx+Fx+Qx, (double)(NT+VT+FT+QT));
+ pstat(" %6.2f", (double)Nx, (double)(NT));
+ pstat(" %6.2f", (double)Vx, (double)(VT));
+ pstat(" %6.2f", (double)Fx, (double)(FT));
+ (void)printf("\n");
+ (void)printf("Average ");
+ pstat(" %6.2f", CBM, (double)nrec);
+ pstat(" %6.2f", CNM, (double)Nrec);
+ pstat(" %6.2f", CVM, (double)Vrec);
+ pstat(" %6.2f", CFM, (double)Frec);
+ (void)printf("\n");
break;
case 3: /* rxr VE run-by-run table */
case 6: /* rxr SVE run-by-run table */
@@ -287,7 +301,8 @@
static char rts[20], tts[20];
static double rre, ds, dp, err, mref;
static int cts, cfn, ctp, cfp, sts, sfn, stp, sfp, lts, lfn, ltp, lfp;
- static int ets, efn, etp, efp;
+ static int dummy, nt, vt, ft, qt;
+ static long ets, efn, etp, efp;
static long nn, sn, vn, fn, on, ns, ss, vs, fs, os;
static long nv, sv, vv, fv, ov, no, so, vo, fo;
static long nx, sx, vx, fx, qx, st;
@@ -326,11 +341,19 @@
return (1);
case 2: /* bxb -l shutdown report */
st = -1L;
- (void)sscanf(s, "%s%ld%ld%ld%ld%s%s%s%s%ld", rec,
- &nx, &vx, &fx, &qx, mb, mn, mv, mf, &st);
+ (void)sscanf(s, "%s%ld%ld%ld%ld%s%s%s%s%ld seconds %ld%ld%ld%ld%ld",
+ rec, &nx, &vx, &fx, &qx, mb, mn, mv, mf, &st,
+ &nt, &dummy, &vt, &ft, &qt);
if (st < 0L) return (0);
Nx += nx; Vx += vx; Fx += fx; Qx += qx; ST += st;
- nrec++;
+ NT += nt; VT += vt; FT += ft; QT += qt;
+ if (nt + vt + ft + qt) {
+ CBM += (nx + vx + fx + qx)/(double)(nt + vt + ft + qt); nrec++;
+ if (nt) { CNM += nx/(double)nt; Nrec++; NT += nt; }
+ if (vt) { CVM += vx/(double)vt; Vrec++; VT += vt; }
+ if (ft) { CFM += fx/(double)ft; Frec++; FT += ft; }
+ QT += qt;
+ }
return (1);
case 3: /* rxr run-by-run report */
case 6:
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/app/wrann.c wfdb-10.5.5/app/wrann.c
--- wfdb-10.5.4/app/wrann.c 2009-08-06 14:56:35.000000000 -0400
+++ wfdb-10.5.5/app/wrann.c 2010-07-27 14:06:58.000000000 -0400
@@ -1,9 +1,9 @@
/* file wrann.c G. Moody 6 July 1983
- Last revised: 6 August 2009
+ Last revised: 27 July 2010
-------------------------------------------------------------------------------
wrann: Translate an ASCII file in 'rdann' output format to an annotation file
-Copyright (C) 1983-2009 George B. Moody
+Copyright (C) 1983-2010 George B. Moody
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -128,11 +128,11 @@
/* Create an aux string if needed. */
if (*annstr || ap) {
if (*annstr && ap)
- sprintf(a+1, "%s %s\0", annstr, ap+1);
+ sprintf(a+1, "%s %s", annstr, ap+1);
else if (*annstr)
- sprintf(a+1, "%s\0", annstr);
+ sprintf(a+1, "%s", annstr);
else
- sprintf(a+1, "%s\0", ap+1);
+ sprintf(a+1, "%s", ap+1);
*a = strlen(a+1);
annot.aux = a;
}
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/app/wrsamp.c wfdb-10.5.5/app/wrsamp.c
--- wfdb-10.5.4/app/wrsamp.c 2010-07-02 00:17:38.000000000 -0400
+++ wfdb-10.5.5/app/wrsamp.c 2010-10-06 22:04:19.000000000 -0400
@@ -1,5 +1,5 @@
/* file: wrsamp.c G. Moody 10 August 1993
- Last revised: 1 July 2010
+ Last revised: 6 October 2010
-------------------------------------------------------------------------------
wrsamp: Select fields or columns from a file and generate a WFDB record
@@ -33,6 +33,8 @@
#define DITHER (((double)rand() + (double)rand())/RAND_MAX - 1.0)
char *pname;
+unsigned int ncols = 0;
+unsigned int nosig = 0;
char *read_line(FILE *ifile, char rsep)
{
@@ -130,6 +132,8 @@
int i, m = (strlen(line) + 1)/2, n = 0, state = 0;
char d, *p, *q = NULL;
+ if (m < nosig) m = nosig;
+ if (m < ncols) m = ncols;
SSTRCPY(tbuf, line);
p = tbuf-1;
SREALLOC(ta, sizeof(int)*2 + sizeof(char *)*m, 1);
@@ -205,13 +209,13 @@
{
char **ap, *cp, **desc, *gain = "", *ifname = "(stdin)",
*line = NULL, ofname[40], *p, *record = NULL, rsep = '\n',
- *scale = "", sflag = 0, trim = 0, **units, *prog_name();
- static char btime[25];
+ *scale = "", sflag = 0, trim = 0, Xflag = 0, **units, *prog_name();
+ static char btime[25], **dstrings, **ustrings;
double freq = WFDB_DEFFREQ, *scalef, v;
#ifndef atof
double atof();
#endif
- int c, cf = 0, dflag = 0, format = 16, *fv = NULL, i, labels, mf, zflag = 0;
+ int c, cf = 0, dflag = 0, format = 16, *fv = NULL, i, j, mf, zflag = 0;
FILE *ifile = stdin;
long t = 0L, t0 = 0L, t1 = 0L;
#ifndef atol
@@ -220,7 +224,6 @@
Tokenarray *ta;
WFDB_Sample *vout;
WFDB_Siginfo *si;
- unsigned int nf = 0;
void help();
pname = prog_name(argv[0]);
@@ -338,7 +341,11 @@
}
}
- /* read the first line of the input file */
+ nosig = argc - i; /* any remaining arguments are column numbers */
+
+ /* Determine the number of input columns, and (if present) the signal
+ names and the units for each signal. Start by reading the first line
+ of the input file. */
if ((line = read_line(ifile, rsep)) == NULL) {
if (rsep != '\n') {
if (record == NULL)
@@ -355,69 +362,130 @@
(void)fprintf(stderr, "%s: no newlines in input\n", pname);
exit(3);
}
-
- /* unless -s was given, note if it contains any tab characters */
- if (sflag == 0 && line_has_tab(line))
- defpmode.delim = "\t";
-
- /* note if it contains any alphabetic characters */
- labels = line_has_alpha(line);
-
- /* parse it into tokens */
- ta = parseline(line, NULL);
+ /* Recognize WFDB-XML format if present. */
+ if (strncmp(line, " found\n",
+ pname);
+ exit(1);
+ }
+ } while (strcmp(line, ""));
+ do {
+ if ((line = read_line(ifile, rsep)) == NULL) {
+ (void)fprintf(stderr, "%s: empty \n", pname);
+ exit(1);
+ }
+ if (strncmp(line, "", 19) == 0)
+ sscanf(line+19, "%lf", &freq);
+ else if (strncmp(line, "", 13) == 0) {
+ line[strlen(line)-14] = '\0'; /* strip */
+ ta = parseline(line+13, NULL); /* skip */
+ SUALLOC(dstrings, ta->ntokens, sizeof(char *));
+ for (i = 0; i < ta->ntokens; i++)
+ SSTRCPY(dstrings[i], ta->token[i]);
+ ncols = ta->ntokens;
+ }
+ else if (strncmp(line, "", 7) == 0) {
+ line[strlen(line)-8] = '\0'; /* strip */
+ ta = parseline(line+7, NULL); /* skip */
+ SUALLOC(ustrings, ta->ntokens, sizeof(char *));
+ for (i = 0; i < ta->ntokens; i++)
+ SSTRCPY(ustrings[i], ta->token[i]);
+ }
+ } while (strcmp(line, ""));
+ if ((line = read_line(ifile, rsep)) == NULL) {
+ (void)fprintf(stderr, "%s: empty \n", pname);
+ exit(1);
+ }
+ }
+ else { /* non-XML input */
+ /* Unless -s was given, note if line 0 contains any tab characters. */
+ if (sflag == 0 && line_has_tab(line))
+ defpmode.delim = "\t";
+ /* If it contains any alphabetic characters, save the signal names. */
+ if (line_has_alpha(line)) {
+ ta = parseline(line, NULL);
+ SALLOC(dstrings, ta->ntokens, sizeof(char *));
+ for (i = 0; i < ta->ntokens; i++) {
+ while (*(ta->token[i]) == ' ')
+ (ta->token[i])++;
+ SSTRCPY(dstrings[i], ta->token[i]);
+ }
+ ncols = ta->ntokens;
+ /* Read the second line. */
+ if ((line = read_line(ifile, rsep)) == NULL) {
+ (void)fprintf(stderr, "%s: no data\n", pname);
+ exit(1);
+ }
+ /* If it has any alphabetic characters, save the unit strings. */
+ else if (line_has_alpha(line)) {
+ ta = parseline(line, NULL);
+ SALLOC(ustrings, ta->ntokens, sizeof(char *));
+ for (i = 0; i < ta->ntokens; i++) {
+ while (*(ta->token[i]) == ' ')
+ (ta->token[i])++;
+ if (*(ta->token[i]) == '(')
+ (ta->token[i])++;
+ SSTRCPY(ustrings[i], ta->token[i]);
+ }
+ /* Read the third line. */
+ if ((line = read_line(ifile, rsep)) == NULL) {
+ (void)fprintf(stderr, "%s: no data\n", pname);
+ exit(1);
+ }
+ }
+ }
+ }
+
/* read selected column numbers into fv[...] */
- if (i < argc) {
- SUALLOC(fv, argc - i, sizeof(int));
- while (i < argc) {
- if (sscanf(argv[i++], "%d", &fv[nf]) != 1 ||
- fv[nf] < 0 || fv[nf] >= ta->ntokens) {
+ if (nosig) {
+ SUALLOC(fv, nosig, sizeof(int));
+ for (i = argc - nosig, j = 0; i < argc; i++, j++) {
+ if (sscanf(argv[i], "%d", &fv[j]) != 1 ||
+ fv[j] < 0 || fv[j] >= ncols) {
(void)fprintf(stderr, "%s: unrecognized argument %s\n",
- pname, argv[--i]);
+ pname, argv[i]);
exit(1);
}
- nf++;
}
}
- /* if no columns were specified, copy all columns (or all except 0) */
- else {
- int i, j;
-
- nf = ta->ntokens - zflag;
- SUALLOC(fv, nf, sizeof(int));
- for (i = 0, j = zflag; i < nf; i++, j++)
+ else { /* copy all column numbers (or all except 0) into fv[...] */
+ nosig = ncols - zflag;
+ SUALLOC(fv, nosig, sizeof(int));
+ for (i = 0, j = zflag; i < nosig; i++, j++)
fv[i] = j;
}
- /* allocate arrays */
- SUALLOC(vout, nf, sizeof(WFDB_Sample));
- SUALLOC(si, nf, sizeof(WFDB_Siginfo));
- SUALLOC(scalef, nf, sizeof(double));
+ SUALLOC(vout, nosig, sizeof(WFDB_Sample));
+ SUALLOC(si, nosig, sizeof(WFDB_Siginfo));
+ SUALLOC(scalef, nosig, sizeof(double));
- /* open the output record */
+ /* open the output record */
if (record == NULL)
(void)sprintf(ofname, "-");
else
(void)sprintf(ofname, "%s.dat", record);
- for (i = 0; i < nf; i++) {
+
+ for (i = 0; i < nosig; i++) {
si[i].fname = ofname;
- si[i].desc = NULL;
- if (labels) { /* set the signal descriptions from the column headings */
- char *p = ta->token[fv[i]], *q;
-
- while (*p == ' ') p++;
- q = p + strlen(p);
- while (*(q-1) == ' ') q--;
- *q = '\0';
- SSTRCPY(si[i].desc, p);
+ if (dstrings) {
+ SSTRCPY(si[i].desc, dstrings[fv[i]]);
}
else {
char tdesc[16];
-
- (void)sprintf(tdesc, "olumn %d", fv[i]);
+
+ (void)sprintf(tdesc, "col %d", fv[i]);
SSTRCPY(si[i].desc, tdesc);
}
- si[i].units = "";
+ if (ustrings) {
+ SSTRCPY(si[i].units, ustrings[fv[i]]);
+ }
+ else
+ si[i].units = "";
si[i].group = 0;
si[i].fmt = format;
si[i].spf = 1;
@@ -449,39 +517,11 @@
scale++;
}
- if (labels) { /* read the second line of input */
- if ((line = read_line(ifile, rsep)) == NULL) {
- (void)fprintf(stderr, "%s: no input data\n", pname);
- exit(4);
- }
- if (line_has_alpha(line)) {
- ta = parseline(line, NULL);
- /* Copy units strings after trimming any surrounding spaces,
- parentheses, or brackets, and after replacing embedded spaces
- with underscores. */
- for (i = 0; i < nf; i++) {
- char *p = ta->token[fv[i]], *q;
-
- while (*p == ' ') p++;
- if (*p == '(' || *p == '[') p++;
- q = p + strlen(p);
- while (*(q-1) == ' ') q--;
- if (*(q-1) == ')' || *(q-1) == ']') q--;
- *q = '\0';
- while (--q > p)
- if (*q == ' ') *q = '_';
- si[i].units = NULL;
- SSTRCPY(si[i].units, p);
- }
- line = read_line(ifile, rsep);
- }
- }
-
/* discard any additional lines containing text */
while (line_has_alpha(line))
line = read_line(ifile, rsep);
- if (osigfopen(si, nf) < nf || setsampfreq(freq) < 0)
+ if (osigfopen(si, nosig) < nosig || setsampfreq(freq) < 0)
exit(2);
/* skip any unwanted samples at the beginning */
@@ -503,7 +543,8 @@
/* read and copy samples */
while (line != NULL && (t1 == 0L || t++ < t1)) {
ta = parseline(line, NULL);
- for (i = 0; i < nf; i++) {
+
+ for (i = 0; i < nosig; i++) {
double v;
if (sscanf(ta->token[fv[i]], "%lf", &v) == 1) {
@@ -517,7 +558,16 @@
vout[i] = WFDB_INVALID_SAMPLE;
}
if (putvec(vout) < 0) break;
+
line = read_line(ifile, rsep);
+ if (line && Xflag && strncmp(line, "", 16) == 0) {
+ if (line = read_line(ifile, rsep))
+ if (strcmp(line, "")) {
+ fprintf(stderr,
+ "%s: (warning) unexpected EOF in XML input\n", pname);
+ }
+ break;
+ }
}
/* write the header */
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/check-manifest wfdb-10.5.5/check-manifest
--- wfdb-10.5.4/check-manifest 2005-08-12 01:53:16.000000000 -0400
+++ wfdb-10.5.5/check-manifest 2010-07-27 17:17:18.000000000 -0400
@@ -1,14 +1,16 @@
#!/bin/sh
# file: check-manifest G. Moody 14 December 2001
-# Last revised: 1 November 2002
+# Last revised: 27 July 2010
# Verify tarball contents
PACKAGE=$1
-sort -f <../${PACKAGE}-MANIFEST >../sort.$$
+sort -f ../expected-MANIFEST
+sort -f <../${PACKAGE}-MANIFEST | grep . | sed 's+/$++' | \
+ grep -v ${PACKAGE} >../sort.$$
mv ../sort.$$ ../${PACKAGE}-MANIFEST
-if diff MANIFEST ../${PACKAGE}-MANIFEST
+if diff ../expected-MANIFEST ../${PACKAGE}-MANIFEST
then
- rm -f ../${PACKAGE}-MANIFEST
+ rm -f ../expected-MANIFEST ../${PACKAGE}-MANIFEST
cat <lib/Makefile
fi
for D in app checkpkg convert data doc doc/wag-src doc/wpg-src doc/wug-src \
- examples fortran psd wave waverc .
+ examples fortran psd wave waverc xml .
do
if [ -s $D/Makefile.top ]
then
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/convert/a2m.c wfdb-10.5.5/convert/a2m.c
--- wfdb-10.5.4/convert/a2m.c 2002-07-24 23:15:46.000000000 -0400
+++ wfdb-10.5.5/convert/a2m.c 2010-07-27 14:10:16.000000000 -0400
@@ -1,9 +1,9 @@
/* file: a2m.c G. Moody 9 June 1983
- Last revised: 24 July 2002
+ Last revised: 27 July 2010
-------------------------------------------------------------------------------
a2m: Convert an AHA format annotation file to MIT format
-Copyright (C) 2002 George B. Moody
+Copyright (C) 1983-2010 George B. Moody
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -135,7 +135,8 @@
break;
case 't': /* file type follows */
if (++i >= argc || (type = atoi(argv[i])) < 0 || type > 3) {
- (void)fprintf(stderr, "%s: file type (0-3) must follow -t\n");
+ (void)fprintf(stderr, "%s: file type (0-3) must follow -t\n",
+ pname);
exit(1);
}
break;
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/convert/ahaecg2mit.c wfdb-10.5.5/convert/ahaecg2mit.c
--- wfdb-10.5.4/convert/ahaecg2mit.c 2008-07-23 15:03:14.000000000 -0400
+++ wfdb-10.5.5/convert/ahaecg2mit.c 2010-08-24 23:15:06.000000000 -0400
@@ -1,5 +1,5 @@
/* file: ahaecg2mit.c G. Moody 7 May 2008
-
+. Last revised: 24 August 2010
Convert a *.ecg file from an AHA Database DVD to WFDB-compatible format
*/
@@ -10,7 +10,7 @@
main(int argc, char **argv)
{
char *p, *record;
- int i, sflag;
+ int i, sflag = 0;
FILE *ifile;
void process(char *r, FILE *f);
@@ -84,6 +84,6 @@
}
(void)newheader(record);
wfdbquit();
- fprintf(stderr, "wrote %s.atr, $s.dat, and %s.hea\n", record,record,record);
+ fprintf(stderr, "wrote %s.atr, %s.dat, and %s.hea\n", record,record,record);
return;
}
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/convert/mit2edf.c wfdb-10.5.5/convert/mit2edf.c
--- wfdb-10.5.4/convert/mit2edf.c 2009-03-14 23:44:35.000000000 -0400
+++ wfdb-10.5.5/convert/mit2edf.c 2010-07-27 14:13:11.000000000 -0400
@@ -1,8 +1,8 @@
/* file: mit2edf.c G. Moody 2 November 2002
- Last revised: 14 March 2009
+ Last revised: 27 July 2010
-------------------------------------------------------------------------------
Convert MIT format header and signal files to EDF (European Data Format) file
-Copyright (C) 2002-2009 George B. Moody
+Copyright (C) 2002-2010 George B. Moody
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -328,7 +328,7 @@
/* Number of samples per block. */
for (i = 0; i < nsig; i++, p += 8) {
- sprintf(buf, "%d", frames_per_block * si[i].spf);
+ sprintf(buf, "%ld", frames_per_block * si[i].spf);
strncpy(p, buf, strlen(buf));
}
@@ -345,7 +345,7 @@
if (header[i] < 32 || header[i] > 126)
fprintf(stderr,
"WARNING (%s): output contains an invalid character, %d,"
- " at byte %ld\n", pname, header[i], i);
+ " at byte %d\n", pname, header[i], i);
/* In verbose mode, summarize what we've done so far. */
if (vflag) {
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/convert/mit2wav.c wfdb-10.5.5/convert/mit2wav.c
--- wfdb-10.5.4/convert/mit2wav.c 2009-06-10 12:21:03.000000000 -0400
+++ wfdb-10.5.5/convert/mit2wav.c 2010-07-27 14:14:36.000000000 -0400
@@ -1,8 +1,8 @@
/* file: mit2wav.c G. Moody 12 February 2003
-
+ Last revised: 27 July 2010
-------------------------------------------------------------------------------
mit2wav: Convert WFDB format signal file(s) to .wav format
-Copyright (C) 2003 George B. Moody
+Copyright (C) 2003-2010 George B. Moody
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -254,14 +254,15 @@
(void)strcpy(tfname, "wavXXXXXX");
(void)mkstemp(tfname);
if ((ofile = fopen(tfname, "wb")) == NULL) {
- (void)fprintf(stderr, "%s: can't create temporary file %s\n", tfname);
+ (void)fprintf(stderr, "%s: can't create temporary file %s\n",
+ pname, tfname);
exit(1);
}
/* Write the header and format chunks, and the first 8 bytes of the
data chunk, to the temporary file. */
if (fwrite("RIFF", 1, 4, ofile) != 4) {
- fprintf(stderr, "%s: can't write to %s\n", ofname);
+ fprintf(stderr, "%s: can't write to %s\n", pname, ofname);
exit(2);
}
out32(nsamp*framelen + 36); /* nsamp*framelen sample bytes, and 36 more
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/convert/wfdb2mat.c wfdb-10.5.5/convert/wfdb2mat.c
--- wfdb-10.5.4/convert/wfdb2mat.c 2010-03-16 11:37:26.000000000 -0400
+++ wfdb-10.5.5/convert/wfdb2mat.c 2010-07-27 14:16:20.000000000 -0400
@@ -1,5 +1,5 @@
/* file: wfdb2mat.c G. Moody 26 February 2009
- Last revised: 16 March 2010
+ Last revised: 27 July 2010
-------------------------------------------------------------------------------
wfdb2mat: Convert (all or part of) a WFDB signal file to Matlab .mat format
Copyright (C) 2009-2010 George B. Moody
@@ -337,7 +337,7 @@
/* Summarize the contents of the .mat file. */
printf("%s\n", p);
- printf("val has %d row%s (signal%s) and %d column%s (sample%s/signal)\n",
+ printf("val has %d row%s (signal%s) and %ld column%s (sample%s/signal)\n",
nosig, nosig == 1 ? "" : "s", nosig == 1 ? "" : "s",
to-from, to == from+1 ? "" : "s", to == from+1 ? "" : "s");
printf("Duration: %s\n", timstr(to-from));
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/doc/wag-src/rdsamp.1 wfdb-10.5.5/doc/wag-src/rdsamp.1
--- wfdb-10.5.4/doc/wag-src/rdsamp.1 2009-11-06 12:18:06.000000000 -0500
+++ wfdb-10.5.5/doc/wag-src/rdsamp.1 2010-08-25 23:31:06.000000000 -0400
@@ -1,4 +1,4 @@
-.TH RDSAMP 1 "6 November 2009" "WFDB 10.4.25" "WFDB Applications Guide"
+.TH RDSAMP 1 "25 August 2010" "WFDB 10.5.5" "WFDB Applications Guide"
.SH NAME
rdsamp \- read WFDB signal files
.SH SYNOPSIS
@@ -91,6 +91,11 @@
columns identifiable). Names of units are shortened when necessary by
omitting the final characters, since the initial characters are
usually most important for distinguishing different units.
+.TP
+\fB-X\fR
+Produce output in WFDB-XML format (same as the CSV format produced using
+the \fB-c\fR option, but wrapped within an XML header and trailer). This
+format is recognized and parsed automatically by \fBwrsamp\fR.
.SH ENVIRONMENT
.PP
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/lib/wfdb.h wfdb-10.5.5/lib/wfdb.h
--- wfdb-10.5.4/lib/wfdb.h 2010-07-14 01:28:54.000000000 -0400
+++ wfdb-10.5.5/lib/wfdb.h 2010-10-06 22:45:29.000000000 -0400
@@ -32,7 +32,7 @@
/* WFDB library version. */
#define WFDB_MAJOR 10
#define WFDB_MINOR 5
-#define WFDB_RELEASE 4
+#define WFDB_RELEASE 5
#define WFDB_NETFILES 1 /* if 1, library includes code for HTTP, FTP clients */
#define WFDB_NETFILES_LIBCURL 1
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/Makefile.tpl wfdb-10.5.5/Makefile.tpl
--- wfdb-10.5.4/Makefile.tpl 2009-10-28 13:19:00.000000000 -0400
+++ wfdb-10.5.5/Makefile.tpl 2010-10-06 22:30:57.000000000 -0400
@@ -1,5 +1,5 @@
# file: Makefile.tpl G. Moody 24 May 2000
-# Last revised: 10 October 2008
+# Last revised: 6 October 2010
# This section of the Makefile should not need to be changed.
# 'make' or 'make all': compile the WFDB applications without installing them
@@ -16,6 +16,7 @@
cd psd; $(MAKE) install
-( cd wave; $(MAKE) install )
cd waverc; $(MAKE) install
+ -( cd xml; $(MAKE) install )
test -d doc && ( cd doc; $(MAKE) install )
# 'make collect': collect the installed files into /tmp/wfdb/
@@ -28,6 +29,7 @@
cd psd; $(MAKE) collect
-( cd wave; $(MAKE) collect )
cd waverc; $(MAKE) collect
+ -( cd xml; $(MAKE) collect )
test -d doc && ( cd doc; $(MAKE) collect )
uninstall: config.cache
@@ -39,6 +41,7 @@
cd psd; $(MAKE) uninstall
cd wave; $(MAKE) uninstall
cd waverc; $(MAKE) uninstall
+ cd xml; $(MAKE) uninstall
test -d doc && ( cd doc; $(MAKE) uninstall )
./uninstall.sh $(WFDBROOT)
@@ -54,6 +57,7 @@
cd psd; $(MAKE) clean
cd wave; $(MAKE) clean
cd waverc; $(MAKE) clean
+ cd xml; $(MAKE) clean
test -d doc && ( cd doc; $(MAKE) clean )
cd conf; rm -f *~ prompt site.def site-slib.def
rm -f *~ config.cache */*.exe $(PACKAGE)-*.spec
@@ -116,9 +120,11 @@
rm -f ../$(PACKAGE)-MANIFEST ../$(PACKAGE).tar.gz \
../$(PACKAGE)-no-docs.tar.gz
cd lib; $(SETPERMISSIONS) *.h
- cd ..; tar --create --file $(PACKAGE).tar.gz --verbose --gzip \
- '--exclude=$(PACKAGE)/*CVS' $(PACKAGE) | sed s+${PACKAGE}/++ | \
- tee $(PACKAGE)-MANIFEST
+ cd ..; export COPYFILE_DISABLE=true; \
+ tar --create --file $(PACKAGE).tar.gz --verbose --gzip \
+ '--exclude=$(PACKAGE)/*CVS' $(PACKAGE) 2>&1 | \
+ sed "s+^a ++" | sed s+${PACKAGE}/++ | \
+ tee $(PACKAGE)-MANIFEST
cd ..; tar --create --file $(PACKAGE)-no-docs.tar.gz \
--verbose --gzip \
'--exclude=$(PACKAGE)/*doc' \
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/MANIFEST wfdb-10.5.5/MANIFEST
--- wfdb-10.5.4/MANIFEST 2009-05-03 15:22:59.000000000 -0400
+++ wfdb-10.5.5/MANIFEST 2010-10-06 22:38:59.000000000 -0400
@@ -1,5 +1,4 @@
-
-app/
+app
app/12lead.pro
app/ann2rr.c
app/bxb.c
@@ -55,10 +54,10 @@
app/wrsamp.c
app/xform.c
check-manifest
-checkpkg/
+checkpkg
checkpkg/appcheck
checkpkg/checkfile
-checkpkg/expected/
+checkpkg/expected
checkpkg/expected/100a.nguess
checkpkg/expected/100s.a2r
checkpkg/expected/100s.mix
@@ -97,7 +96,7 @@
checkpkg/expected/sumann.out
checkpkg/expected/sumstats.out
checkpkg/expected/tach.out
-checkpkg/expected/udb/
+checkpkg/expected/udb
checkpkg/expected/udb/100z.hea
checkpkg/expected/wfd00001.dat
checkpkg/expected/wfd00001.hea
@@ -113,7 +112,7 @@
checkpkg/expected/xform.dat
checkpkg/expected/xform.hea
checkpkg/expected/xform.wabp
-checkpkg/input/
+checkpkg/input
checkpkg/input/100x.hea
checkpkg/input/ecgeval
checkpkg/input/sumstats
@@ -123,8 +122,8 @@
checkpkg/Makefile
checkpkg/Makefile.top
checkpkg/Makefile.tpl
-checkpkg/mitdb/
-conf/
+checkpkg/mitdb
+conf
conf/archname
conf/collect.sh
conf/cygwin.def
@@ -150,7 +149,7 @@
conf/solaris.def
conf/solaris-slib.def
conf/version.def
-convert/
+convert
convert/a2m.c
convert/ad2m.c
convert/ahaconvert
@@ -171,7 +170,7 @@
convert/wav2mit.c
convert/wfdb2mat.c
COPYING
-data/
+data
data/100a.atr
data/100a.hea
data/100s.atr
@@ -194,7 +193,7 @@
data/multi.hea
data/nstlist
data/null.hea
-data/pipe/
+data/pipe
data/pipe/16x10.hea
data/pipe/16x11.hea
data/pipe/16x12.hea
@@ -228,7 +227,7 @@
data/pipe/8x8.hea
data/pipe/8x9.hea
data/README
-data/tape/
+data/tape
data/tape/10240.hea
data/tape/1024.hea
data/tape/4096.hea
@@ -238,13 +237,13 @@
data/tape/mittape.hea
data/wfdbcal
data/wfdbpath.mac
-doc/
+doc
doc/Makefile
doc/Makefile.top
doc/Makefile.tpl
-doc/misc/
+doc/misc
doc/misc/foot.ht0
-doc/misc/icons/
+doc/misc/icons
doc/misc/icons/contents.png
doc/misc/icons/cross_ref.png
doc/misc/icons/foot.png
@@ -257,8 +256,8 @@
doc/misc/icons/up.png
doc/misc/index.ht0
doc/README
-doc/wag/
-doc/wag-src/
+doc/wag
+doc/wag-src
doc/wag-src/a2m.1
doc/wag-src/ann2rr.1
doc/wag-src/annot.5
@@ -353,10 +352,10 @@
doc/wag-src/wrsamp.1
doc/wag-src/xform.1
doc/wag-src/xview.7
-doc/wpg/
-doc/wpg/info/
+doc/wpg
+doc/wpg/info
doc/wpg/info/README.info
-doc/wpg-src/
+doc/wpg-src
doc/wpg-src/ctotexi.c
doc/wpg-src/dir.top
doc/wpg-src/dir.wpg
@@ -372,25 +371,25 @@
doc/wpg-src/wpg.cover
doc/wpg-src/wpg.hlp
doc/wpg-src/wpg.ht0
-doc/wug/
-doc/wug-src/
+doc/wug
+doc/wug-src
doc/wug-src/fancybox.perl
doc/wug-src/.latex2html-init
doc/wug-src/Makefile
doc/wug-src/Makefile.top
doc/wug-src/Makefile.tpl
doc/wug-src/README
-doc/wug-src/wave/
-doc/wug-src/wave/misc/
+doc/wug-src/wave
+doc/wug-src/wave/misc
doc/wug-src/wave/misc/example.xws
doc/wug-src/wave/misc/html.sty
doc/wug-src/wave/misc/pstoimg
doc/wug-src/wave/misc/wave.inf
-doc/wug-src/wave/png/
+doc/wug-src/wave/png
doc/wug-src/wave/png/chart2.png
doc/wug-src/wave/png/fulldisc.png
doc/wug-src/wave/png/wave.png
-doc/wug-src/wave/ppm/
+doc/wug-src/wave/ppm
doc/wug-src/wave/ppm/allow-edit.ppm.gz
doc/wug-src/wave/ppm/analysis-commands.ppm.gz
doc/wug-src/wave/ppm/analyze-window.ppm.gz
@@ -432,11 +431,11 @@
doc/wug-src/wave/ppm/view-window.ppm.gz
doc/wug-src/wave/ppm/wave-icon.ppm.gz
doc/wug-src/wave/ppm/wave-menu.ppm.gz
-doc/wug-src/wave/ps/
+doc/wug-src/wave/ps
doc/wug-src/wave/ps/chart1.ps
doc/wug-src/wave/ps/chart2.ps
doc/wug-src/wave/ps/fulldisc.ps
-doc/wug-src/wave/scripts/
+doc/wug-src/wave/scripts
doc/wug-src/wave/scripts/dossify-html
doc/wug-src/wave/scripts/fixinfo
doc/wug-src/wave/scripts/fixlinks
@@ -446,7 +445,7 @@
doc/wug-src/wave/scripts/wugfigures
doc/wug-src/wug0.tex
doc/wug-src/wug.cover
-examples/
+examples
examples/example10.c
examples/example1.c
examples/example2.c
@@ -471,7 +470,7 @@
examples/refhr.c
examples/stdev.c
examples/wfdbversion.c
-fortran/
+fortran
fortran/example.f
fortran/fsamples.f
fortran/Makefile
@@ -482,7 +481,7 @@
INSTALL
install.sh
install-wave32
-lib/
+lib
lib/annot.c
lib/calib.c
lib/COPYING.LIB
@@ -504,7 +503,7 @@
Makefile.tpl
MANIFEST
NEWS
-psd/
+psd
psd/coherence.c
psd/fft.c
psd/hrfft
@@ -524,7 +523,7 @@
README.NETFILES
README.WINDOWS
uninstall.sh
-wave/
+wave
wave/analysis.hlp
wave/analyze.c
wave/annot.c
@@ -551,7 +550,7 @@
wave/modepan.c
wave/nomake
wave/printing.hlp
-waverc/
+waverc
waverc/Makefile
waverc/Makefile.top
waverc/Makefile.tpl
@@ -577,3 +576,15 @@
wave/xvwave.c
wave/xvwave.h
wfdb.spec
+xml
+xml/annxml.c
+xml/heaxml.c
+xml/Makefile
+xml/Makefile.top
+xml/Makefile.tpl
+xml/README
+xml/wfdb.dtd
+xml/wfdb.xsl
+xml/xmlann.c
+xml/xmlhea.c
+xml/xmlproc.h
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/NEWS wfdb-10.5.5/NEWS
--- wfdb-10.5.4/NEWS 2010-07-14 02:29:21.000000000 -0400
+++ wfdb-10.5.5/NEWS 2010-10-06 23:37:51.000000000 -0400
@@ -1,3 +1,40 @@
+10.5.5 (6 October 2010):
+ WFDB-compatible signals can now be converted to a simple XML format
+ using rdsamp's new '-X' option, and XML files in this format can be
+ converted to WFDB-compatible format using wrsamp (which recognizes
+ this format automatically, requiring no special option). A document
+ type description of this format, and of XML formats for annotation
+ and header files, is available at
+ http://physionet.org/physiobank/database/XML/wfdb.dtd
+ This file, together with a set of applications (annxml, heaxml, xmlann,
+ and xmlhea) that convert WFDB-compatible annotation and header files
+ to and from these XML formats, are included in the 'xml' subdirectory
+ of this package.
+
+ Since version 10.4.14, app/sortann has not properly sorted annotations
+ containing non-zero 'chan' or 'num' fields. This bug has now been
+ fixed; thanks to Jesus Maria Rodriguez Presedo for reporting it and
+ for providing a test case.
+
+ Changes in conf/darwin.def and conf/darwin-slib.def allow creation
+ of multi-architecture (i386, x86_64, and ppc) binaries on Mac OS X.
+
+ Virginia Faro-Maza pointed out that sumstats did not derive aggregate
+ shutdown statistics described in ANSI/AAMI EC57, and that bxb did not
+ preserve the raw data needed to derive these statistics. Both bxb.c
+ and sumstats.c have been revised in this release to remedy these
+ omissions.
+
+ An uninitialized flag may have made ahaecg2mit behave as if its -s
+ option was always given, and an informational message contained
+ a formatting error; both problems have been corrected, thanks to
+ a report from Isaac Henry.
+
+ Errors in the formatting of a variety of error and warning messages
+ have been corrected in app/ecgeval.c, app/psfd.c, app/rdsamp.c,
+ app/snip.c, app/sumstats.c, app/wrann.c, convert/mit2edf.c,
+ convert/mit2wav.c, convert/wfdb2mat.c, and psd/lomb.c.
+
10.5.4 (13 July 2010):
Function getseginfo() has been introduced in WFDB library version
10.5.4, to allow applications to obtain information about the
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/psd/lomb.c wfdb-10.5.5/psd/lomb.c
--- wfdb-10.5.4/psd/lomb.c 2005-06-10 09:52:21.000000000 -0400
+++ wfdb-10.5.5/psd/lomb.c 2010-07-27 14:20:51.000000000 -0400
@@ -1,9 +1,8 @@
/* file: lomb.c G. Moody 12 February 1992
- Last revised: 10 June 2005
-
+ Last revised: 27 July 2010
-------------------------------------------------------------------------------
lomb: Lomb periodogram of real data
-Copyright (C) 1992-2005 George B. Moody
+Copyright (C) 1992-2010 George B. Moody
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -469,34 +468,34 @@
if (64 * nmaxt * sizeof(float) < nmax) {
fprintf(stderr,
- "%s: insufficient memory, truncating input at row %d\n",
+ "%s: insufficient memory, truncating input at row %lu\n",
pname, npts);
break;
}
if ((xt = (float *)realloc(x, nmaxt * sizeof(float))) == NULL) {
fprintf(stderr,
- "%s: insufficient memory, truncating input at row %d\n",
+ "%s: insufficient memory, truncating input at row %lu\n",
pname, npts);
break;
}
x = xt;
if ((yt = (float *)realloc(y, nmaxt * sizeof(float))) == NULL) {
fprintf(stderr,
- "%s: insufficient memory, truncating input at row %d\n",
+ "%s: insufficient memory, truncating input at row %lu\n",
pname, npts);
break;
}
y = yt;
if ((w1t = (float *)realloc(wk1,64*nmaxt*sizeof(float))) == NULL){
fprintf(stderr,
- "%s: insufficient memory, truncating input at row %d\n",
+ "%s: insufficient memory, truncating input at row %lu\n",
pname, npts);
break;
}
wk1 = w1t;
if ((w2t = (float *)realloc(wk2,64*nmaxt*sizeof(float))) == NULL){
fprintf(stderr,
- "%s: insufficient memory, truncating input at row %d\n",
+ "%s: insufficient memory, truncating input at row %lu\n",
pname, npts);
break;
}
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/wfdb.spec wfdb-10.5.5/wfdb.spec
--- wfdb-10.5.4/wfdb.spec 2009-05-03 23:39:12.000000000 -0400
+++ wfdb-10.5.5/wfdb.spec 2010-10-06 22:45:00.000000000 -0400
@@ -15,6 +15,9 @@
BuildRoot: /var/tmp/%{name}-root
%changelog
+* Wed Oct 6 2010 George B Moody
+- added annxml, heaxml, xmlann, xmlhea
+
* Sun May 3 2009 George B Moody
- moved wfdb-config from devel to apps
@@ -139,6 +142,7 @@
%{_bindir}/ahaconvert
%{_bindir}/ahaecg2mit
%{_bindir}/ann2rr
+%{_bindir}/annxml
%{_bindir}/bxb
%{_bindir}/calsig
%{_bindir}/coherence
@@ -148,6 +152,7 @@
%{_bindir}/epicmp
%{_bindir}/fft
%{_bindir}/fir
+%{_bindir}/heaxml
%{_bindir}/hrfft
%{_bindir}/hrlomb
%{_bindir}/hrmem
@@ -208,6 +213,8 @@
%{_bindir}/wrann
%{_bindir}/wrsamp
%{_bindir}/xform
+%{_bindir}/xmlann
+%{_bindir}/xmlhea
%{_libdir}/ps
%{_mandir}
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/xml/annxml.c wfdb-10.5.5/xml/annxml.c
--- wfdb-10.5.4/xml/annxml.c 1969-12-31 19:00:00.000000000 -0500
+++ wfdb-10.5.5/xml/annxml.c 2010-07-01 21:22:14.000000000 -0400
@@ -0,0 +1,212 @@
+/* file: annxml.c G. Moody 28 June 2010
+
+-------------------------------------------------------------------------------
+heaxml: Convert a WFDB annotation file to XML format
+Copyright (C) 2010 George B. Moody
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place - Suite 330, Boston, MA 02111-1307, USA.
+
+You may contact the author by e-mail (george@mit.edu) or postal mail
+(MIT Room E25-505A, Cambridge, MA 02139 USA). For updates to this software,
+please visit PhysioNet (http://www.physionet.org/).
+_______________________________________________________________________________
+
+*/
+
+
+#include
+#include
+#include
+
+#define WFDBXMLPROLOG "\n" \
+ "\n" \
+ "\n"
+
+char *token(char *p)
+{
+ if (p) {
+ while (*p && *p != ' ' && *p != '\t' && *p != '\n')
+ p++; /* find whitespace */
+ while (*p && (*p == ' ' || *p == '\t' || *p == '\n'))
+ p++; /* find first non-whitespace */
+ if (*p == '\0') p = NULL;
+ }
+ return (p);
+}
+
+void output_xml(FILE *ofile, char *tag, char *p)
+{
+ if (p) {
+ fprintf(ofile, "<%s>", tag);
+ while (*p) {
+ if (*p == '<') fprintf(ofile, "<");
+ else if (*p == '>') fprintf(ofile, ">");
+ else if (*p == '&') fprintf(ofile, "&");
+ else if (*p == '>') fprintf(ofile, ">");
+ else if (*p == '"') fprintf(ofile, """);
+ else if (*p == '\'') fprintf(ofile, "'");
+ else fprintf(ofile, "%c", *p);
+ p++;
+ }
+ fprintf(ofile, "%s>", tag);
+ }
+ return;
+}
+
+int nsig;
+FILE *ofile;
+WFDB_Annotation annot;
+WFDB_Frequency sfreq;
+
+void process_start(char *tstring);
+void process_anntab(void);
+void process_annotation(void);
+
+main(int argc, char **argv)
+{
+ char *annotator, *ofname, *p, *pname, *record, *prog_name();
+ WFDB_Anninfo ai;
+
+ pname = prog_name(argv[0]);
+ if (argc < 3) {
+ (void)fprintf(stderr, "usage: %s RECORD ANNOTATOR\n", pname);
+ exit(1);
+ }
+ record = argv[1];
+ annotator = argv[2];
+
+ /* Discover the number of signals defined in the header. */
+ if ((nsig = isigopen(record, NULL, 0)) < 0) exit(2);
+ sfreq = sampfreq(record);
+
+ /* Open the input annotation file. */
+ ai.name = annotator;
+ ai.stat = WFDB_READ;
+ if (annopen(record, &ai, 1) < 0)
+ exit(3);
+
+ /* The name of the output file is of the form 'RECORD.ANNOTATOR.xml'. Any
+ directory separators (/) in the record name are replaced by hyphens (-)
+ in the output file name, so that the output file is always written into
+ the current directory. */
+ ofname = calloc(strlen(record)+strlen(annotator)+6, sizeof(char));
+ sprintf(ofname, "%s.%s.xml", record, annotator);
+ for (p = ofname; *p; p++)
+ if (*p == '/') *p = '-';
+
+ /* Open the output file and write the XML prolog. */
+ if ((ofile = fopen(ofname, "wt")) == NULL) {
+ fprintf(stderr, "%s: can't create %s\n", pname, ofname);
+ exit(4);
+ }
+ fprintf(ofile, WFDBXMLPROLOG);
+
+ (void)fprintf(ofile, "\n", annotator, record);
+
+ process_start(mstimstr(0));
+
+ (void)fprintf(ofile, "%.12g\n",
+ sfreq);
+
+ while (getann(0, &annot) >= 0)
+ process_annotation();
+
+ process_anntab();
+
+ fprintf(ofile, "\n");
+ wfdbquit();
+ exit(0);
+}
+
+void process_start(char *p)
+{
+ if (*p == '[') {
+ int day = -1, month = -1, year = -1;
+ double hour = -1.0, minute = -1.0, second = -1.0;
+
+ fprintf(ofile, "\n");
+ sscanf(p+1, "%lf:%lf:%lf %d/%d/%d",
+ &hour, &minute, &second, &day, &month, &year);
+ if (year >= 0) {
+ if (year < 100) year += 1900;
+ if (year < 1975) year += 100;
+ fprintf(ofile, "%d\n", year);
+ }
+ if (month > 0) fprintf(ofile, "%d\n", month);
+ if (day > 0) fprintf(ofile, "%d\n", day);
+
+ if (second < 0) { /* incomplete start time in MM:SS or SS format */
+ if (minute < 0) { second = hour; hour = -1; } /* SS format */
+ else { second = minute; minute = hour; hour = -1; } /* MM:SS */
+ }
+
+ if (hour >= 0) fprintf(ofile, "%g\n", hour);
+ if (minute >= 0) fprintf(ofile, "%g\n", minute);
+ if (second >= 0) fprintf(ofile, "%g\n", second);
+ fprintf(ofile, "\n");
+ }
+}
+
+static long anncount[ACMAX+1];
+
+void process_anntab()
+{
+ int i;
+
+ fprintf(ofile, "");
+ for (i = 0; i <= ACMAX; i++) {
+ if (anncount[i]) {
+ fprintf(ofile, "%d", i);
+ output_xml(ofile, "anncode", annstr(i));
+ output_xml(ofile, "anndescription", anndesc(i));
+ fprintf(ofile, "%ld\n", anncount[i]);
+ }
+ }
+ fprintf(ofile, "");
+}
+
+void process_annotation()
+{
+ fprintf(ofile, "%s",
+ annot.time, annstr(annot.anntyp));
+ if (annot.subtyp) fprintf(ofile, "%d", annot.subtyp);
+ if (annot.chan) fprintf(ofile, "%d", annot.chan);
+ if (annot.num) fprintf(ofile, "%d", annot.num);
+ if (annot.aux) output_xml(ofile, "aux", annot.aux+1);
+ fprintf(ofile, "\n");
+ anncount[annot.anntyp]++;
+}
+
+char *prog_name(s)
+char *s;
+{
+ char *p = s + strlen(s);
+
+#ifdef MSDOS
+ while (p >= s && *p != '\\' && *p != ':') {
+ if (*p == '.')
+ *p = '\0'; /* strip off extension */
+ if ('A' <= *p && *p <= 'Z')
+ *p += 'a' - 'A'; /* convert to lower case */
+ p--;
+ }
+#else
+ while (p >= s && *p != '/')
+ p--;
+#endif
+ return (p+1);
+}
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/xml/heaxml.c wfdb-10.5.5/xml/heaxml.c
--- wfdb-10.5.4/xml/heaxml.c 1969-12-31 19:00:00.000000000 -0500
+++ wfdb-10.5.5/xml/heaxml.c 2010-07-01 17:58:42.000000000 -0400
@@ -0,0 +1,400 @@
+/* file: heaxml.c G. Moody 28 June 2010
+ Last revised: 1 July 2010
+-------------------------------------------------------------------------------
+heaxml: Convert a WFDB .hea (header) file to XML format
+Copyright (C) 2010 George B. Moody
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place - Suite 330, Boston, MA 02111-1307, USA.
+
+You may contact the author by e-mail (george@mit.edu) or postal mail
+(MIT Room E25-505A, Cambridge, MA 02139 USA). For updates to this software,
+please visit PhysioNet (http://www.physionet.org/).
+_______________________________________________________________________________
+
+*/
+
+
+#include
+#include
+
+#define WFDBXMLPROLOG "\n" \
+ "\n" \
+ "\n"
+
+char *token(char *p)
+{
+ if (p) {
+ while (*p && *p != ' ' && *p != '\t' && *p != '\n')
+ p++; /* find whitespace */
+ while (*p && (*p == ' ' || *p == '\t' || *p == '\n'))
+ p++; /* find first non-whitespace */
+ if (*p == '\0') p = NULL;
+ }
+ return (p);
+}
+
+void output_xml(FILE *ofile, char *tag, char *p)
+{
+ if (p) {
+ fprintf(ofile, "<%s>", tag);
+ while (*p) {
+ if (*p == '<') fprintf(ofile, "<");
+ else if (*p == '>') fprintf(ofile, ">");
+ else if (*p == '&') fprintf(ofile, "&");
+ else if (*p == '>') fprintf(ofile, ">");
+ else if (*p == '"') fprintf(ofile, """);
+ else if (*p == '\'') fprintf(ofile, "'");
+ else fprintf(ofile, "%c", *p);
+ p++;
+ }
+ fprintf(ofile, "%s>\n", tag);
+ }
+ return;
+}
+
+int nsig;
+FILE *ofile;
+WFDB_Siginfo *s;
+WFDB_Time t;
+
+void process_start(char *tstring);
+
+main(int argc, char **argv)
+{
+ char *ofname, *info, *p, *pname, *record, *prog_name();
+ int i, in_msrec = 0, nsegments;
+ WFDB_Seginfo *seg, *sp;
+
+ pname = prog_name(argv[0]);
+ if (argc < 2) {
+ (void)fprintf(stderr, "usage: %s RECORD\n", pname);
+ exit(1);
+ }
+ record = argv[1];
+
+ /* Discover the number of signals defined in the header. */
+ if ((nsig = isigopen(record, NULL, 0)) < 0) exit(2);
+
+ /* The name of the output file is the record name with an
+ appended ".hea.xml". Any directory separators (/) in
+ the record name are replaced by hyphens (-) in the
+ output file name, so that the output file is always
+ written into the current directory. */
+ ofname = calloc(strlen(record)+9, sizeof(char));
+ strcpy(ofname, record);
+ for (p = ofname; *p; p++)
+ if (*p == '/') *p = '-';
+ strcat(ofname, ".hea.xml");
+
+ /* Open the output file and write the XML prolog. */
+ if ((ofile = fopen(ofname, "wt")) == NULL) {
+ fprintf(stderr, "%s: can't create %s\n", pname, ofname);
+ exit(3);
+ }
+ fprintf(ofile, WFDBXMLPROLOG);
+
+ /* Allocate storage for nsig signal information structures. */
+ if (nsig > 0 && (s = malloc(nsig * sizeof(WFDB_Siginfo))) == NULL) {
+ fprintf(stderr, "%s: insufficient memory\n", pname);
+ exit(4);
+ }
+ nsig = isigopen(record, s, -nsig);
+
+ (void)fprintf(ofile, "\n\n", record);
+ setgvmode(WFDB_LOWRES);
+ t = strtim("e");
+ if (nsig > 0 && (s[0].fmt == 0 || s[0].nsamp != 0) && s[0].nsamp != t) {
+ in_msrec = 1;
+ nsegments = getseginfo(&sp);
+ seg = calloc(nsegments, sizeof(WFDB_Seginfo));
+ for (i = 0; i < nsegments; i++)
+ seg[i] = sp[i];
+ sp = seg;
+ }
+
+ process_record();
+
+ if (in_msrec) {
+ static char *segname, nextts[30];
+
+ segname = calloc(strlen(record)+20, sizeof(char));
+ for (p = record + strlen(record) - 1; p > record && *p != '/'; p--)
+ ;
+ *p = '\0';
+ /* If segment 0 has 0 samples, it's a layout segment, and the information
+ in it has already been output above, so skip it; otherwise, it's a
+ regular segment, so process it. The initialization of i in the for
+ loop below tests for this. */
+ for (i = sp[0].nsamp ? 0 : 1; i < nsegments; i++) {
+ fprintf(stderr, "segment %d: %s\n", i, sp[i].recname);
+ if (strcmp("~", sp[i].recname) == 0) {
+ fprintf(ofile, "\n\n\n", i);
+ process_start(nextts);
+ fprintf(ofile, "%ld\n", sp[i].nsamp);
+ }
+ else {
+ sprintf(segname, "%s/%s", record, sp[i].recname);
+ wfdbquit();
+ nsig = isigopen(segname, NULL, 0);
+ nsig = isigopen(segname, s, -nsig);
+ fprintf(ofile, "\n\n", sp[i].recname);
+ setgvmode(WFDB_LOWRES);
+ t = strtim("e");
+ strcpy(nextts, mstimstr(-t));
+ process_record();
+ }
+ fprintf(ofile, "\n");
+ }
+ }
+ fprintf(ofile, "\n");
+ exit(0);
+}
+
+void process_info(void)
+{
+ char *info, *p;
+
+ if (info = getinfo((char *)NULL)) {
+ double age = -1.0;
+ char *sex = NULL;
+
+ fprintf(ofile, "\n\n");
+ /* Find the first non-space in the first info string. */
+ for (p = info; *p && *p == ' '; p++)
+ ;
+ if ('0' <= *p && *p <= '9') {
+ /* If the first token of the first info string is numeric, the
+ current .hea file does not have tagged info, and the first
+ and second tokens are the age and sex; and the second info
+ string (if present) contains the medications. Handle this
+ case first. */
+ sscanf(p, "%lf", &age);
+ if (age >= 0) fprintf(ofile, "%g\n", age);
+ p = token(p); /* go to the next token */
+ if (p && (*p == 'm' || *p == 'M')) sex = "M";
+ else if (p && (*p == 'f' || *p == 'F')) sex = "F";
+ if (sex) fprintf(ofile, "%s\n", sex);
+ /* If there are any more tokens, save them as 'extra' info. */
+ if (p = token(p))
+ output_xml(ofile, "extra", p);
+ if (info = getinfo((char *)NULL)) {
+ output_xml(ofile, "medication", info);
+ info = getinfo((char *)NULL);
+ }
+ }
+ /* process standard (tagged) info */
+ while (info) {
+ if (age < 0) {
+ if ((p = strstr(info, "age")) || (p = strstr(info, "Age"))) {
+ if (p = token(p)) {
+ sscanf(p, "%lf", &age);
+ if (age >= 0) fprintf(ofile, "%g\n", age);
+ }
+ /* Additional tagged data may follow age. Continue processing
+ the remainder of this info string below. */
+ if (!(info = token(p)))
+ /* If there is nothing else, get the next info if any. */
+ info = getinfo((char *)NULL);
+ }
+ }
+ if (sex == NULL) {
+ if (info &&
+ ((p = strstr(info, "sex"))||(p = strstr(info, "Sex")))) {
+ if ((p = token(p)) && (*p == 'm' || *p == 'M')) sex = "M";
+ else if (p && (*p == 'f' || *p == 'F')) sex = "F";
+ if (sex) fprintf(ofile, "%s\n", sex);
+ /* Additional tagged data may follow sex. Continue processing
+ the remainder of this info string. */
+ if (!(info = token(p)))
+ /* If there is nothing else, get the next info if any. */
+ info = getinfo((char *)NULL);
+ }
+ }
+ /* Diagnoses may be present in more than one info string. */
+ if (info && *info &&
+ ((p=strstr(info,"diagnos")) || (p=strstr(info,"Diagnos")))) {
+ if ((p = token(p)) == NULL)
+ /* If nothing follows the 'diagnosis' tag, assume the next info
+ is the diagnosis. */
+ p = getinfo((char *)NULL);
+ if (p) {
+ output_xml(ofile, "diagnosis", p);
+ /* This info has been consumed; get the next info if any. */
+ info = getinfo((char *)NULL);
+ continue;
+ }
+ }
+ if (info && *info &&
+ ((p=strstr(info,"medication"))||(p=strstr(info,"Medication")))) {
+ if ((p = token(p)) == NULL)
+ /* If nothing follows the 'medication' tag, assume the next info
+ is the medication. */
+ p = getinfo((char *)NULL);
+ if (p) {
+ output_xml(ofile, "medication", p);
+ /* This info has been consumed; get the next info if any. */
+ info = getinfo((char *)NULL);
+ continue;
+ }
+ }
+ /* Process any info that was not identified above. */
+ if (info && *info)
+ output_xml(ofile, "other", info);
+ info = getinfo((char *)NULL);
+ }
+ fprintf(ofile, "\n");
+ }
+}
+
+void process_start(char *p)
+{
+ if (*p == '[') {
+ int day = -1, month = -1, year = -1;
+ double hour = -1.0, minute = -1.0, second = -1.0;
+
+ fprintf(ofile, "\n");
+ sscanf(p+1, "%lf:%lf:%lf %d/%d/%d",
+ &hour, &minute, &second, &day, &month, &year);
+ if (year >= 0) {
+ if (year < 100) year += 1900;
+ if (year < 1975) year += 100;
+ fprintf(ofile, "%d\n", year);
+ }
+ if (month > 0) fprintf(ofile, "%d\n", month);
+ if (day > 0) fprintf(ofile, "%d\n", day);
+
+ if (second < 0) { /* incomplete start time in MM:SS or SS format */
+ if (minute < 0) { second = hour; hour = -1; } /* SS format */
+ else { second = minute; minute = hour; hour = -1; } /* MM:SS */
+ }
+
+ if (hour >= 0) fprintf(ofile, "%g\n", hour);
+ if (minute >= 0) fprintf(ofile, "%g\n", minute);
+ if (second >= 0) fprintf(ofile, "%g\n", second);
+ fprintf(ofile, "\n");
+ }
+}
+
+int process_record(void)
+{
+ char *p;
+ double cfreq, sfreq;
+ int i, skew;
+ FILE *ifile;
+
+ /* Process and output info. */
+ process_info();
+
+ /* Output the section if the starting time is specified. */
+ process_start(mstimstr(0L));
+
+ if (nsig < 1 || t > 0L)
+ (void)fprintf(ofile, "%ld\n", t);
+ else if (s[0].fmt && (ifile = fopen(s[0].fname, "rb")) &&
+ (fseek(ifile, 0L, 2) == 0)) {
+ int framesize = 0;
+ long nbytes = ftell(ifile) - wfdbgetstart(0);
+
+ fclose(ifile);
+ for (i = 0; i < nsig && s[i].group == 0; i++)
+ framesize += s[i].spf;
+ switch (s[0].fmt) {
+ case 8:
+ case 80:
+ t = nbytes / framesize;
+ break;
+ default:
+ case 16:
+ case 61:
+ case 160:
+ t = nbytes / (2*framesize);
+ break;
+ case 212:
+ t = (2L * nbytes) / (3*framesize);
+ break;
+ case 310:
+ case 311:
+ t = (3L * nbytes) / (4*framesize);
+ break;
+ }
+ (void)fprintf(ofile, "%ld\n", t);
+ }
+
+ (void)fprintf(ofile, "%.12g\n",
+ sfreq = sampfreq(NULL));
+ (void)fprintf(ofile, "%d\n", nsig);
+ cfreq = getcfreq();
+ if (sfreq != cfreq) {
+ double basecount = getbasecount();
+ fprintf(ofile, " 0.0) fprintf(ofile, " basecount=\"%g\"", basecount);
+ fprintf(ofile, ">%.12g\n", cfreq);
+ }
+
+ if (nsig > 0) {
+ for (i = 0; i < nsig; i++) {
+ if (i == 0 || s[i].group != s[i-1].group) {
+ long plen;
+
+ if (i > 0) fprintf(ofile, "\n\n");
+ fprintf(ofile, "\n%s\n\n",
+ s[i].fmt ? s[i].fname : "[none]");
+ if (plen = wfdbgetstart(i))
+ fprintf(ofile, "%ld\n", plen);
+ }
+ fprintf(ofile, "\n%s\n",
+ s[i].desc);
+ fprintf(ofile, "%.12g\n",
+ s[i].gain == 0. ? WFDB_DEFGAIN : s[i].gain);
+ fprintf(ofile, "%s\n",
+ s[i].units ? s[i].units : "mV");
+ fprintf(ofile, "%d\n", s[i].initval);
+ fprintf(ofile, "%d\n", s[i].fmt);
+ if (s[i].spf > 1)
+ fprintf(ofile,"%d\n", s[i].spf);
+ if (skew = wfdbgetskew(i))
+ fprintf(ofile, "%ld\n", skew);
+ fprintf(ofile, "%d\n", s[i].bsize);
+ fprintf(ofile, "%d\n", s[i].adcres);
+ fprintf(ofile, "%d\n", s[i].adczero);
+ fprintf(ofile, "%d\n", s[i].baseline);
+ fprintf(ofile, "%d\n", s[i].cksum);
+ fprintf(ofile, "\n\n");
+ }
+ }
+ if (nsig > 0) fprintf(ofile, "\n\n");
+ return (0);
+}
+
+char *prog_name(s)
+char *s;
+{
+ char *p = s + strlen(s);
+
+#ifdef MSDOS
+ while (p >= s && *p != '\\' && *p != ':') {
+ if (*p == '.')
+ *p = '\0'; /* strip off extension */
+ if ('A' <= *p && *p <= 'Z')
+ *p += 'a' - 'A'; /* convert to lower case */
+ p--;
+ }
+#else
+ while (p >= s && *p != '/')
+ p--;
+#endif
+ return (p+1);
+}
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/xml/Makefile.top wfdb-10.5.5/xml/Makefile.top
--- wfdb-10.5.4/xml/Makefile.top 1969-12-31 19:00:00.000000000 -0500
+++ wfdb-10.5.5/xml/Makefile.top 2010-10-06 22:18:20.000000000 -0400
@@ -0,0 +1,30 @@
+# file: Makefile G. Moody 22 August 2010
+#
+# 'make' description file for WFDB-XML applications
+#
+# -----------------------------------------------------------------------------
+# WFDB-XML applications: programs for conversion between WFDB and XML formats
+# Copyright (C) 2010 George B. Moody
+#
+# These programs are free software; you can redistribute them and/or modify
+# them under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# These programs are distributed in the hope that they will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# these programs; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# You may contact the author by e-mail (george@mit.edu) or postal mail
+# (MIT Room E25-505A, Cambridge, MA 02139 USA). For updates to this software,
+# please visit PhysioNet (http://www.physionet.org/).
+# _____________________________________________________________________________
+#
+# All of the converters require the WFDB library, and those that read
+# XML also require libexpat (http://expat.sourceforge.net).
+
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/xml/Makefile.tpl wfdb-10.5.5/xml/Makefile.tpl
--- wfdb-10.5.4/xml/Makefile.tpl 1969-12-31 19:00:00.000000000 -0500
+++ wfdb-10.5.5/xml/Makefile.tpl 2010-10-06 22:26:19.000000000 -0400
@@ -0,0 +1,50 @@
+# file: Makefile.tpl G. Moody 22 August 2010
+#
+# This section of the Makefile should not need to be changed.
+
+CFILES = annxml.c heaxml.c xmlann.c xmlhea.c
+HFILES = xmlproc.h
+MFILES = Makefile
+XFILES = annxml heaxml xmlann xmlhea
+
+# General rule for compiling C sources into executable files. This is
+# redundant for most versions of `make', but at least one System V version
+# needs it.
+.c:
+ $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
+
+# `make all': build applications
+all: $(XFILES)
+ $(STRIP) $(XFILES)
+
+# `make' or `make install': build and install applications
+install: all $(BINDIR)
+ $(SETXPERMISSIONS) $(XFILES)
+ ../install.sh $(BINDIR) $(XFILES)
+
+# 'make collect': retrieve the installed applications
+collect:
+ ../conf/collect.sh $(BINDIR) $(XFILES)
+
+uninstall:
+ ../uninstall.sh $(BINDIR) $(XFILES)
+
+# Create directories for installation if necessary.
+$(BINDIR):
+ mkdir -p $(BINDIR); $(SETDPERMISSIONS) $(BINDIR)
+
+# `make clean': remove intermediate and backup files
+clean:
+ rm -f $(XFILES) *.o *~
+
+# `make listing': print a listing of WFDB-XML applications sources
+listing:
+ $(PRINT) README $(MFILES) $(CFILES) $(HFILES)
+
+# Rules for compiling WFDB-XML applications that require non-standard options
+
+xmlann: xmlann.c xmlproc.h
+ $(CC) $(CFLAGS) xmlann.c -o $@ $(LDFLAGS) -lexpat
+
+xmlhea: xmlhea.c xmlproc.h
+ $(CC) $(CFLAGS) xmlhea.c -o $@ $(LDFLAGS) -lexpat
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/xml/README wfdb-10.5.5/xml/README
--- wfdb-10.5.4/xml/README 1969-12-31 19:00:00.000000000 -0500
+++ wfdb-10.5.5/xml/README 2010-10-06 21:51:04.000000000 -0400
@@ -0,0 +1,86 @@
+file: README G. Moody 2 July 2010
+ Last revised: 6 October 2010
+
+This directory contains software for interchange between WFDB native formats
+and XML formats. It includes:
+
+wfdb.dtd a DTD for WFDB-XML, an XML schema for
+ expressing the contents of WFDB
+ header and annotation files
+
+wfdb.xsl an XSLT style sheet that a web browser
+ (or other XSLT engine) can use to transform
+ a WFDB-XML header or annotation file into
+ a human-readable representation of its
+ contents
+
+heaxml.c a C program that converts a native
+ WFDB .hea file into a WFDB-XML file
+
+annxml.c a C program that converts a native
+ WFDB annotation file into a WFDB-XML file
+
+xmlhea.c a C program that converts a WFDB-XML header
+ file into a native WFDB .hea file
+
+xmlann.c a C program that converts a WFDB-XML annotation
+ file into a native WFDB annotation file
+
+xmlproc.h generic functions for processing XML files, shared by
+ xmlhea and xmlann
+
+Makefile a 'make' description file for automating the
+ process of compiling and installing this software
+
+A copy of the most recent version of wfdb.dtd is posted on PhysioNet at
+ http://physionet.org/physiobank/database/XML/wfdb.dtd
+This on-line copy is referenced in WFDB-XML files generated by heaxml
+and annxml.
+
+Note that these programs require the WFDB library version 10.5.4 or
+later, and that those that read WFDB-XML files also require libexpat
+(http://expat.sourceforge.net/). To compile them, install gcc, make,
+the WFDB software package, and libexpat if you have not already done so,
+then run 'make' from within this directory. If you don't have 'make',
+you can compile these programs manually; see 'Makefile' for the commands
+needed to do so.
+
+It is not necessary to download the native WFDB files in order to use
+heaxml and annxml, since they can obtain their inputs directly from
+the PhysioNet web server via HTTP.
+
+For example, these commands:
+ heaxml mitdb/200
+ annxml mitdb/200 atr
+produce the WFDB-XML files
+ mitdb-200.hea.xml
+ mitdb-200.atr.xml
+in the current directory.
+
+If you put a copy of wfdb.xsl in the same directory with these output
+files, you should be able to view the HTML generated from them via
+wfdb.xsl by opening them with Firefox or another web browser that
+incorporates an XSLT engine.
+
+Try running heaxml on a mimicdb or mimic2db record, for
+example like this:
+ heaxml mimic2db/a40006/a40006
+This command produces
+ mimic2db-a40006-a40006.hea.xml
+which includes information about each segment in the
+multi-segment record as well as a summary of the entire
+record. The inverse operation, which can be performed by reading
+the .xml file using xmlhea, generates a complete set of segment
+headers together with the master header in this case.
+
+Warning: the XML outputs generated by these commands are huge. There is a
+good reason that I don't keep these data in XML format on PhysioBank!
+
+There are no 'datxml' or 'xmldat' applications to convert signal files
+to and from WFDB-XML format, because the standard 'rdsamp' and 'wrsamp'
+can perform these conversions. Use rdsamp's '-X' option to generate
+WFDB-XML output; wrsamp can recognize WFDB-XML input automatically, so
+no special option is required. WFDB-XML signal format is the CSV format
+that can be produced by rdsamp's '-c' option, wrapped within an XML header
+and trailer.
+
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/xml/wfdb.dtd wfdb-10.5.5/xml/wfdb.dtd
--- wfdb-10.5.4/xml/wfdb.dtd 1969-12-31 19:00:00.000000000 -0500
+++ wfdb-10.5.5/xml/wfdb.dtd 2010-10-06 21:58:53.000000000 -0400
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -Naur --exclude Makefile --exclude info wfdb-10.5.4/xml/wfdb.xsl wfdb-10.5.5/xml/wfdb.xsl
--- wfdb-10.5.4/xml/wfdb.xsl 1969-12-31 19:00:00.000000000 -0500
+++ wfdb-10.5.5/xml/wfdb.xsl 2010-07-01 21:51:51.000000000 -0400
@@ -0,0 +1,231 @@
+
+
+
+
+
+
+
+
+
+
+
+
+Description of record
+
+
+Description of record
+
+
General information
+
+
+
+Sampling frequency:
+
+samples per signal per second
+
+Counter frequency:
+
+counts per second (starting from
+)
+
+Signals:
+
+
+
+
+
+
+
+
+
+
+
+Record ,
+Annotator
+
+
+Record ,
+Annotator
+
+
+
+
+
+Time resolution:
+ticks per second
+Annotations:
+
Each of the signals listed below appears in at least one segment
+of this record. See the details for each segment (following this
+list of available signals) for additional information.