diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/app/Makefile.tpl wfdb-10.5.14/app/Makefile.tpl --- wfdb-10.5.13/app/Makefile.tpl 2012-05-07 03:59:57.000000000 -0400 +++ wfdb-10.5.14/app/Makefile.tpl 2012-08-12 16:34:42.000000000 -0400 @@ -1,5 +1,5 @@ # file: Makefile.tpl G. Moody 23 May 2000 -# Last revised: 7 May 2012 +# Last revised: 10 August 2012 # This section of the Makefile should not need to be changed. CFILES = ann2rr.c bxb.c calsig.c ecgeval.c epicmp.c fir.c gqfuse.c gqpost.c \ @@ -18,7 +18,7 @@ sumann sumstats tach time2sec wabp wfdb-config wfdbcat \ wfdbcollate wfdbdesc wfdbmap wfdbsignals wfdbtime wfdbwhich \ wqrs wrann wrsamp xform -SCRIPTS = cshsetwfdb setwfdb +SCRIPTS = cshsetwfdb setwfdb pnwlogin PSFILES = pschart.pro psfd.pro 12lead.pro MFILES = Makefile @@ -51,7 +51,8 @@ scripts: sed s+/usr/local/database+$(DBDIR)+g $(BINDIR)/setwfdb sed s+/usr/local/database+$(DBDIR)+g $(BINDIR)/cshsetwfdb - $(SETPERMISSIONS) $(SCRIPTS) + sed s+/usr/local/database+$(DBDIR)+g $(BINDIR)/pnwlogin + cd $(BINDIR); $(SETPERMISSIONS) *setwfdb; $(SETXPERMISSIONS) pnwlogin uninstall: ../uninstall.sh $(PSPDIR) $(PSFILES) diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/app/pnwlogin wfdb-10.5.14/app/pnwlogin --- wfdb-10.5.13/app/pnwlogin 1969-12-31 19:00:00.000000000 -0500 +++ wfdb-10.5.14/app/pnwlogin 2012-08-12 16:23:07.000000000 -0400 @@ -0,0 +1,49 @@ +#! /bin/bash + +# file: pnwlogin G. Moody 12 August 2012 +# +# Log in to PhysioNetWorks +# +# After successfully entering your user name and password, WFDB applications +# run in this shell have access to files belonging to your projects. + +if (! curl-config --features | grep -q SSL) +then +echo "Access to PhysioNetWorks requires SSL." +echo "Install a version of libcurl with SSL support and try again." +exit +fi + +read -p "PhysioNetWorks user name (email address): " PNWUSER +stty -echo +read -p "Password: " PNWPASS +stty echo +echo + +export PNWUSER PNWPASS +( WFDB=https://physionet.org/users + export WFDB + wfdbcat $PNWUSER/index.shtml >.pnwhome 2>/dev/null ) + +if [ ! -s .pnwhome ] +then + echo "No response from server: check network connection" + exit +elif (! grep -q Review/ .pnwhome) +then + echo "Access denied" + rm -f .pnwhome + exit +fi + +rm -f .pnwhome +if [ -z "${WFDB+xxx}" ] +then + WFDB=". /usr/database http://physionet.org/physiobank/database" +fi +WFDB="$WFDB https://physionet.org/works/\ + https://physionet.org/users/$PNWUSER/works/" +PS1="<$PNWUSER \\h:\\W>\\$ " +export WFDB PS1 +echo "PhysioNetWorks access enabled; disable with ^D or exit" +/bin/bash diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/app/sampfreq.c wfdb-10.5.14/app/sampfreq.c --- wfdb-10.5.13/app/sampfreq.c 2010-12-05 09:37:28.000000000 -0500 +++ wfdb-10.5.14/app/sampfreq.c 2012-07-30 09:14:10.000000000 -0400 @@ -1,9 +1,9 @@ /* file: sampfreq.c G. Moody 7 June 1998 - Last revised: 5 October 2001 + Last revised: 29 July 2012 ------------------------------------------------------------------------------- sampfreq: Print the sampling frequency of a record -Copyright (C) 2001 George B. Moody +Copyright (C) 1998-2012 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 @@ -28,29 +28,58 @@ #include #include +char *pname; + main(argc, argv) int argc; char **argv; { - if (argc == 3 && strcmp(argv[1], "-H") == 0) { - int nsig; - WFDB_Siginfo *si; - - if ((nsig = isigopen(argv[2], NULL, 0)) > 0) { - SUALLOC(si, nsig, sizeof(WFDB_Siginfo)); - isigopen(argv[2], si, nsig); - setgvmode(WFDB_HIGHRES); - printf("%g\n", sampfreq(NULL)); - exit(0); - } - } - else if (argc == 2) { - printf("%g\n", sampfreq(argv[1])); - exit(0); + void help(); + + pname = argv[0]; + switch (argc) { + case 1: + help(); + exit(1); + break; + case 2: + printf("%g\n", sampfreq(argv[1])); + exit(0); + break; + case 3: + if (strcmp(argv[1], "-a") == 0 || + strcmp(argv[1], "-H") == 0) { + int i, nsig; + double freq; + WFDB_Siginfo *si; + + if ((nsig = isigopen(argv[2], NULL, 0)) > 0) { + SUALLOC(si, nsig, sizeof(WFDB_Siginfo)); + isigopen(argv[2], si, nsig); + } + if (argv[1][1] == 'H') { + setgvmode(WFDB_HIGHRES); + printf("%g\n", sampfreq(NULL)); + exit(0); + } + else { + setgvmode(WFDB_LOWRES); + freq = sampfreq(NULL); + for (i = 0; i < nsig; i++) + printf("%s\t%g\n", si[i].desc, si[i].spf * freq); + } + } } +} - fprintf(stderr, "usage: %s [-H] RECORD\n", argv[0]); - fprintf(stderr, " where RECORD is the name of the input record\n"); - fprintf(stderr, " (use -H to get the maximum sampling frequency of a multifrequency record)\n"); - exit(1); +void help() +{ + fprintf(stderr, "usage: %s [OPTION] RECORD\n", pname); + fprintf(stderr, + " where RECORD is the name of the input record\n" + " and OPTION may be either of:\n" + " -a list all signals and their sampling frequencies\n" + " -h show this help\n" + " -H show the maximum sampling frequency of a multifrequency record)\n" + " If no OPTION is used, show the base sampling frequency (frame rate).\n"); } diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/app/sumann.c wfdb-10.5.14/app/sumann.c --- wfdb-10.5.13/app/sumann.c 2002-11-14 19:21:01.000000000 -0500 +++ wfdb-10.5.14/app/sumann.c 2012-08-02 13:02:31.000000000 -0400 @@ -1,9 +1,9 @@ /* file: sumann.c G. Moody 5 February 1982 - Last revised: 14 November 2002 + Last revised: 2 August 2012 ------------------------------------------------------------------------------- sumann: Tabulates annotations -Copyright (C) 2002 George B. Moody +Copyright (C) 1982-2012 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 @@ -51,10 +51,11 @@ { static WFDB_Anninfo ai; WFDB_Annotation annot; - int i, rhythm = 0, noise = 2, qflag = 0; - static long tab[64], rtab[MAXR+1], ntab[6]; + int i, j, rhythm = 0, noise = 2, qflag = 0; + static long tab[ACMAX+1], rtab[MAXR+1], ntab[6]; static long rtime[MAXR+1], ntime[6], r0, n0, from_time, to_time; char *record = NULL, *prog_name(); + FILE *bfile = NULL, *rfile = NULL; void help(); pname = prog_name(argv[0]); @@ -91,6 +92,58 @@ help(); exit(0); break; + case 'o': + if (++i >= argc+1) { + (void)fprintf(stderr, + "%s: beat and rhythm file names must follow -o\n", + pname); + exit(1); + } + /* check if files exist already, create them as needed */ + if (bfile = fopen(argv[i], "r")) { + fclose(bfile); + if ((bfile = fopen(argv[i], "a")) == NULL) { + (void)fprintf(stderr, + "%s: can't append to %s\n", pname, argv[i]); + exit(1); + } + } + else { + if ((bfile = fopen(argv[i], "w")) == NULL) { + (void)fprintf(stderr, + "%s: can't append to %s\n", pname, argv[i]); + exit(1); + } + fprintf(bfile, "Record"); + for (j = 1; j < ACMAX+1; j++) + if (qflag == 0 || isqrs(j)) + (void)fprintf(bfile, ",%s", annstr(j)); + fprintf(bfile, "\n"); + } + i++; + if (rfile = fopen(argv[i], "r")) { + fclose(rfile); + if ((rfile = fopen(argv[i], "a")) == NULL) { + (void)fprintf(stderr, + "%s: can't append to %s\n", pname, argv[i]); + fclose(bfile); + exit(1); + } + } + else { + if ((rfile = fopen(argv[i], "w")) == NULL) { + (void)fprintf(stderr, + "%s: can't append to %s\n", pname, argv[i]); + fclose(bfile); + exit(1); + } + fprintf(rfile, "Record"); + for (j = 1; j <= MAXR; j++) + if (rstring[j]) + (void)fprintf(rfile, ",%s", rstring[j]); + fprintf(rfile, "\n"); + } + break; case 'q': /* list only QRS annotations in event table */ qflag = 1; break; @@ -123,6 +176,8 @@ } if (record == NULL || ai.name == NULL) { help(); + if (bfile) fclose(bfile); + if (rfile) fclose(rfile); exit(1); } @@ -222,21 +277,56 @@ ntab[noise]++; ntime[noise] += to_time - n0; } - for (i = 0; i < 64; i++) - if (tab[i] != 0L && (qflag == 0 || isqrs(i))) - (void)printf("%s\t%6ld\n", annstr(i), tab[i]); - (void)printf("\n"); - for (i = 1; i <= MAXR; i++) - if (rtab[i] != 0L) - (void)printf("%s\t%6ld episode%c %s\n", - rstring[i], rtab[i], - rtab[i] == 1L ? ' ' : 's', timstr(rtime[i])); - (void)printf("\n"); - for (i = 1; i <= 5; i++) - if (ntab[i] != 0L) - (void)printf("%s\t%6ld episode%c %s\n", - nstring[i], ntab[i], - ntab[i] == 1L ? ' ' : 's', timstr(ntime[i])); + + if (bfile == NULL) { + for (i = 1; i < ACMAX+1; i++) + if (tab[i] != 0L && (qflag == 0 || isqrs(i))) + (void)printf("%s\t%6ld\n", annstr(i), tab[i]); + (void)printf("\n"); + } + else { + (void)fprintf(bfile, "%s", record); + tab[RHYTHM] = tab[NOISE] = 0; + for (i = 1; i < ACMAX+1; i++) { + (void)fprintf(bfile, ","); + if (tab[i] && (qflag == 0 || isqrs(i))) + (void)fprintf(bfile, "%ld", tab[i]); + } + (void)fprintf(bfile, "\n"); + fclose(bfile); + } + + if (rfile == NULL) { + for (i = 1; i <= MAXR; i++) + if (rtab[i] != 0L) + (void)printf("%s\t%6ld episode%c %s\n", + rstring[i], rtab[i], + rtab[i] == 1L ? ' ' : 's', timstr(rtime[i])); + (void)printf("\n"); + } + else { + (void)fprintf(rfile, "%s", record); + for (i = 1; i <= MAXR; i++) { + if (rstring[i]) { + (void)fprintf(rfile, ","); + if (rtab[i]) { + char *p = timstr(rtime[i]); + while (*p == ' ') p++; + (void)fprintf(rfile, "%ld (%s)", rtab[i], p); + } + } + } + (void)fprintf(rfile, "\n"); + fclose(rfile); + } + + if (bfile == NULL) { + for (i = 1; i <= 5; i++) + if (ntab[i] != 0L) + (void)printf("%s\t%6ld episode%c %s\n", + nstring[i], ntab[i], + ntab[i] == 1L ? ' ' : 's', timstr(ntime[i])); + } exit(0); /*NOTREACHED*/ } @@ -263,10 +353,17 @@ static char *help_strings[] = { "usage: %s -r RECORD -a ANNOTATOR [OPTIONS ...]\n", "where RECORD and ANNOTATOR specify the input, and OPTIONS may include:", - " -f TIME start at specified TIME", - " -h print this usage summary", - " -q list only QRS annotations in the event table", - " -t TIME stop at specified TIME", + " -f TIME start at specified TIME", + " -h print this usage summary", + " -o BTAB RTAB add summaries of beat and rhythm annotations to BTAB and RTAB", + " -q list only QRS annotations in the event table", + " -t TIME stop at specified TIME", + "If -o is not used, a readable summary is written to the standard output.", + "", + "Otherwise, BTAB and RTAB are names of files containing CSV-format tables.", + "If these files don't exist, they will be created, and the column headings", + "will be written in the first line of each. If they do exist, this program's", + "output is appended to them. Each line after the first summarizes 1 record.", NULL }; diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/checkpkg/expected/lcheck_cal wfdb-10.5.14/checkpkg/expected/lcheck_cal --- wfdb-10.5.13/checkpkg/expected/lcheck_cal 2012-04-06 13:13:06.000000000 -0400 +++ wfdb-10.5.14/checkpkg/expected/lcheck_cal 2012-08-09 23:51:34.000000000 -0400 @@ -41,10 +41,12 @@ Atip - - undefined 1 mV HVA - - undefined 5 mV Vtip - - undefined 10 mV -CS - - undefined 1 mV +AV - 1 square 1 mV Thorax - - undefined 2 mV Abdomen - - undefined 200 uV -AV - 1 square 1 mV +FECG - - undefined 1 mV +Direct - - undefined 200 uV +CS - - undefined 1 mV F - - undefined 100 uV C - - undefined 100 uV A - - undefined 100 uV diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/configure wfdb-10.5.14/configure --- wfdb-10.5.13/configure 2011-02-18 12:28:12.000000000 -0500 +++ wfdb-10.5.14/configure 2012-08-12 10:56:27.000000000 -0400 @@ -38,6 +38,7 @@ fi ;; --mandir=*) MANDIR=`echo $i | sed 's/[-a-zA-Z0-9]*=//'` ;; --prefix=*) DIR=`echo $i | sed 's/[-a-zA-Z0-9]*=//'` ;; + -q) ;; # ignored --shared) LIBTYPE=dynamic ;; --static) LIBTYPE=static ;; --static_only) LIBTYPE=static diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/convert/ahaecg2mit.c wfdb-10.5.14/convert/ahaecg2mit.c --- wfdb-10.5.13/convert/ahaecg2mit.c 2010-08-24 23:15:06.000000000 -0400 +++ wfdb-10.5.14/convert/ahaecg2mit.c 2012-07-11 17:07:54.000000000 -0400 @@ -1,22 +1,80 @@ /* 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 + Last revised: 11 July 2012 +Convert *.ecg or *.txt files from an AHA Database DVD to WFDB-compatible format */ #include #include #include +int format; +FILE *ifile; +WFDB_Annotation a; +WFDB_Sample v[2]; + +void process(char *r); +int readbindata(void) +{ + char data[5]; + + if (fread(data, 1, 5, ifile) != 5) + return (0); /* EOF */ + v[0] = (data[0] & 0xff) | ((data[1] << 8) & 0xff00); + v[1] = (data[2] & 0xff) | ((data[3] << 8) & 0xff00); + if (data[4] == '.') + return (1); /* samples, no annotation */ + a.anntyp = ammap(data[4]); + a.subtyp = (data[4] == 'U' ? -1 : 0); + return (2); /* samples and annotation */ +} + +int readtxtdata(void) +{ + char buf[16]; + int c, i, n; + + for (i = 0; i < sizeof(buf); i++) { + c = getc(ifile); + if (c == '\r' || c == EOF || c == '\n') break; + buf[i] = c; + } + if (c == EOF) return (0); + n = sscanf(buf, "%d,%d,\"%c", v, v+1, &c); + if (n < 3) { + fprintf(stderr, "Error: improperly formatted input!\n"); + fprintf(stderr, + " n = %d, buf = |%s|, v[0] = %d, v[1] = %d, c = |%c|\n", + n, buf, v[0], v[1], c); + return (0); + } + if (c == '"') + return (1); /* samples, no annotation */ + a.anntyp = ammap(c); + a.subtyp = (c == 'U' ? -1 : 0); + return (2); /* samples and annotation */ +} + main(int argc, char **argv) { char *p, *record; int i, sflag = 0; - FILE *ifile; - void process(char *r, FILE *f); if (argc < 2 || strcmp(argv[1], "-h") == 0) { - fprintf(stderr, "usage: %s [-s] RECORD.ecg [RECORD.ecg]...\n", argv[0]); - fprintf(stderr, " (use -s to make short-format 35-minute records)\n"); + fprintf(stderr, "usage: %s [-s] RECORD.XXX [RECORD.XXX]...\n", + argv[0]); + fprintf(stderr, + " where RECORD.XXX is the name of the AHA DVD input file to" + " be converted\n" + " ('RECORD' is one of the 4-digit AHA DB record names, and" + " 'XXX' may be either\n 'ecg' or 'txt', depending on the" + " version of the AHA DVD.)\n" + " Output files are RECORD.hea (text), RECORD.atr (binary)," + " RECORD.dat (binary).\n" + " Two or more input files may be converted in a single run.\n" + " Use -s to make short-format (35-minute) records from" + " long-format (2.5 hour)\n input files. When using -s, the" + " second digit in the output record name is\n" + " incremented by 2.\n"); exit(1); } if (strcmp(argv[i = 1], "-s") == 0) { @@ -24,10 +82,14 @@ i = 2; } for ( ; i < argc; i++) { - p = argv[i] + strlen(argv[i]) - 4; /* pointer to '.ecg' */ - if (strcmp(".ecg", p) && strcmp(".ECG", p)) { + p = argv[i] + strlen(argv[i]) - 4; /* pointer to '.ecg' or '.txt' */ + if (strcmp(".ecg", p) == 0 || strcmp(".ECG", p) == 0) + format = 1; + else if (strcmp(".txt", p) == 0 || strcmp(".TXT", p) == 0) + format = 2; + else { fprintf(stderr, "%s: ignoring '%s'\n", argv[0], argv[i]); - continue; /* not an .ecg or .ECG file */ + continue; /* not an .ecg or .txt file */ } if ((ifile = fopen(argv[i], "rb")) == NULL) { fprintf(stderr, "%s: can't open '%s'\n", argv[0], argv[1]); @@ -36,23 +98,29 @@ *p = '\0'; /* strip off extension */ record = p - 4; /* AHA record names are 4 (ASCII) digits */ if (sflag) {/* skip first 145 minutes if making a short-format record */ - fseek(ifile, 145L*60L*250L*5L, SEEK_SET); + if (format == 1) + fseek(ifile, 145L*60L*250L*5L, SEEK_SET); + else if (format == 2) { + long t; + + for (t = 0; t < 145L*60L*250L; t++) + (void)readtxtdata(); + } record[1] += 2; /* fix record name (n0nn->n2nn, n1nn->n3nn) */ } - process(record, ifile); + process(record); fclose(ifile); } exit(0); } -void process(char *record, FILE *ifile) +void process(char *record) { - char ofname[10], data[5]; + char ofname[10]; + int stat; WFDB_Time t = -1; static WFDB_Siginfo si[2]; static WFDB_Anninfo ai; - static WFDB_Sample v[2]; - static WFDB_Annotation a; setsampfreq(250.0); /* AHA DB is sampled at 250 Hz for each signal */ sprintf(ofname, "%s.dat", record); @@ -70,17 +138,25 @@ wfdbquit(); return; } - while (fread(data, 1, 5, ifile) == 5) { - v[0] = (data[0] & 0xff) | ((data[1] << 8) & 0xff00); - v[1] = (data[2] & 0xff) | ((data[3] << 8) & 0xff00); - (void)putvec(v); - if (data[4] != '.') { - a.anntyp = ammap(data[4]); - a.subtyp = (data[4] == 'U' ? -1 : 0); - a.time = t; - (void)putann(0, &a); + if (format == 1) { + while (stat = readbindata()) { + (void)putvec(v); + if (stat > 1) { + a.time = t; + (void)putann(0, &a); + } + t++; + } + } + else { + while (stat = readtxtdata()) { + t++; + (void)putvec(v); + if (stat > 1) { + a.time = t; + (void)putann(0, &a); + } } - t++; } (void)newheader(record); wfdbquit(); diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/data/wfdbcal wfdb-10.5.14/data/wfdbcal --- wfdb-10.5.13/data/wfdbcal 2012-03-21 09:51:31.000000000 -0400 +++ wfdb-10.5.14/data/wfdbcal 2012-08-09 23:27:29.000000000 -0400 @@ -1,5 +1,5 @@ # file: wfdbcal G. Moody June 1991 -# Last revised: 21 March 2012 +# Last revised: 31 July 2012 # Default calibration database for WFDB library # # Format: @@ -68,15 +68,17 @@ HVA - - undefined 5 mV Vtip - - undefined 10 mV -# Intracardiac electrograms -CS - - undefined 1 mV +# ECG from INCART database +AV - 1 square 1 mV -# ECG from Non-Invasive Fetal ECG Database +# Fetal ECG Thorax - - undefined 2 mV Abdomen - - undefined 200 uV +FECG - - undefined 1 mV +Direct - - undefined 200 uV -# ECG from INCART database -AV - 1 square 1 mV +# Intracardiac electrograms +CS - - undefined 1 mV # EEG F - - undefined 100 uV diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/doc/wag-src/a2m.1 wfdb-10.5.14/doc/wag-src/a2m.1 --- wfdb-10.5.13/doc/wag-src/a2m.1 2009-10-28 09:31:15.000000000 -0400 +++ wfdb-10.5.14/doc/wag-src/a2m.1 2012-08-02 13:06:43.000000000 -0400 @@ -1,11 +1,11 @@ -.TH A2M 1 "23 July 2008" "WFDB 10.4.8" "WFDB Applications Guide" +.TH A2M 1 "2 August 2012" "WFDB 10.5.14" "WFDB Applications Guide" .SH NAME a2m, ad2m, ahaconvert, ahaecg2mit, m2a, md2a \- converting between AHA DB and WFDB formats .SH SYNOPSIS To read from an AHA DB DVD: .br - \fBahaecg2mit\fR [ \fB-s\fR ] \fIahafile\fB.ecg\fR ... + \fBahaecg2mit\fR [ \fB-s\fR ] \fIahafile\fB.*\fR ... .br To read from an AHA DB CD: .br @@ -26,7 +26,12 @@ .PP The AHA Database for Evaluation of Ventricular Arrhythmia Detectors (AHA DB) has been distributed since 1983 by ECRI (http://www.ecri.org), in -at least three formats: +at least four formats: +.TP +\fBsingle-file (.txt) format\fR +Developed by ECRI for distributions of the AHA DB on DVDs (ca. 2012) as a +successor to the earlier .ecg format (below); this format can be read by +\fBahaecg2mit\fR. .TP \fBsingle-file (.ecg) format\fR Developed by ECRI for distributions of the AHA DB on DVDs (ca. 2008); this @@ -77,7 +82,7 @@ .SH DVD FORMAT .SS ahaecg2mit .PP -Use \fBahaecg2mit\fR to convert .ecg files from the AHA DB DVD into +Use \fBahaecg2mit\fR to convert .txt or .ecg files from an AHA DB DVD into WFDB-compatible records. One or more input filenames may be supplied as command-line arguments; each specified input file is converted into a WFDB record, including a .hea (header) file, a .dat (signal) file, @@ -85,7 +90,7 @@ argument is \fB-s\fR, then \fBahaecg2mit\fR produces short-form records with the correct (n2nn or n3nn) record names. -If the .ecg files are not in the current directory, give their +If the .txt or .ecg files are not in the current directory, give their full pathnames. The output files are always written to the current directory, so be sure that the current directory is writeable (it should not be the DVD) and that has sufficient free space (roughly @@ -173,7 +178,11 @@ .SH EXAMPLES .SS "AHA Database DVD" -If the DVD is accessible as \fB/media/dvd/\fR, the command +If the DVD is accessible as \fB/media/dvd/\fR, either +.br + \fBahaecg2mit -s /media/dvd/*.txt\fR +.br +or (for DVDs written in the older format): .br \fBahaecg2mit -s /media/dvd/*.ecg\fR .br @@ -184,7 +193,7 @@ drive letter that Windows has assigned), so the same task can be done under Windows by .br - \fBahaecg2mit -s /cygdrive/d/*.ecg\fR + \fBahaecg2mit -s /cygdrive/d/*.txt\fR .SS "AHA Database CD" AHA DB CDs contain both long and short versions of each record. In diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/doc/wag-src/pnwlogin.1 wfdb-10.5.14/doc/wag-src/pnwlogin.1 --- wfdb-10.5.13/doc/wag-src/pnwlogin.1 1969-12-31 19:00:00.000000000 -0500 +++ wfdb-10.5.14/doc/wag-src/pnwlogin.1 2012-08-13 19:00:20.000000000 -0400 @@ -0,0 +1,52 @@ +.TH PNWLOGIN 1 "13 August 2012" "WFDB 10.5.14" "WFDB Applications Guide" +.SH NAME +pnwlogin \- provide direct access to PhysioNetWorks for WFDB applications +.SH SYNOPSIS +\fBpnwlogin\fR +.SH DESCRIPTION +.PP +\fBpnwlogin\fR is a \fBbash\fR shell script that collects user credentials +needed to access files in PhysioNetWorks projects, and provides them to WFDB +applications. It also provides convenience functions, including validation of +credentials and modification of the WFDB path (see \fBsetdb\fR(1)) for +convenient access to your private PhysioNetWorks projects as well as any +active (shared) projects to which you belong. +.PP +After prompting for your PhysioNetWorks user name and password, \fBpnwlogin\fR +starts a shell, making the login credentials available to any commands run +within the shell. Applications that use WFDB library version 10.5.14 or later +and libcurl 7.12.0 or later can make use of these credentials automatically +with no modifications; you will not be prompted to enter them again while +running within \fBpnwlogin\fR's shell. Exit from the shell by typing a +control-D or \fBexit\fR (as for any \fBbash\fR shell). Your credentials are +never written to permanent storage, and \fBpnwlogin\fR's in-memory copy of them +is destroyed on exit. +.SS First-time use: +.PP +You must be a member of an active project, or you must have created a private +project, in order to use \fBpnwlogin\fR successfully. You cannot \fIcreate\fR +a PhysioNetWorks account or join a PhysioNetWorks project using \fBpnwlogin\fR. +.PP +To get started, use your web browser to go to +\fBhttps://physionet.org/users/\fR, click on "Create account", and follow the +instructions. The process can be completed in a minute or two. Once you have +an account, you will need to join an active project (follow the links on your +PhysioNetWorks home page to visit the main pages of projects of interest for +further information), or create a private project before you will be able to +use \fBpnwlogin\fR. +.SH ENVIRONMENT +.TP +\fBPNWUSER\fR +Your PhysioNetWorks user name (your email address). +.TP +\fBPNWPASS\fR +Your PhysioNetWorks password. +.TP +\fBWFDB\fR +The database path: a list of locations (which may include names of local +directories as well as URL prefixes) where WFDB-compatible input files may +be found. +.SH AUTHOR +George B. Moody (george@mit.edu) +.SH SOURCES +http://physionet.org/physiotools/wfdb/app/pnwlogin diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/doc/wag-src/rdedfann.1 wfdb-10.5.14/doc/wag-src/rdedfann.1 --- wfdb-10.5.13/doc/wag-src/rdedfann.1 2008-04-09 15:54:39.000000000 -0400 +++ wfdb-10.5.14/doc/wag-src/rdedfann.1 2012-05-24 16:30:12.000000000 -0400 @@ -12,6 +12,7 @@ .TP \fB-h\fR Print a brief usage summary. +.TP \fB-v\fR Verbose mode (print column headings). diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/doc/wag-src/sampfreq.1 wfdb-10.5.14/doc/wag-src/sampfreq.1 --- wfdb-10.5.13/doc/wag-src/sampfreq.1 2002-07-31 14:34:22.000000000 -0400 +++ wfdb-10.5.14/doc/wag-src/sampfreq.1 2012-08-02 13:07:28.000000000 -0400 @@ -1,14 +1,30 @@ -.TH SAMPFREQ 1 "31 July 2002" "WFDB 10.2.7" "WFDB Applications Guide" +.TH SAMPFREQ 1 "2 August 2012" "WFDB 10.5.14" "WFDB Applications Guide" .SH NAME sampfreq \- show sampling frequency for a record .SH SYNOPSIS -\fBsampfreq\fR [ \fB-H\fR ] \fIrecord \fR +\fBsampfreq\fR [ \fIoption\fR ] \fIrecord \fR .SH DESCRIPTION -This program shows the sampling frequency for the specified \fIrecord\fR. -By default, \fBsampfreq\fR shows the base sampling frequency (frame rate) -for multi-frequency records; if the \fB-H\fR option is present, -\fBsampfreq\fR shows the highest sampling frequency used for any signal -in a multi-frequency record. +This program shows the sampling frequency (in samples per second per signal) +for the specified \fIrecord\fR. A record may contain multiple signals sampled +at different frequencies; in this case, the signals are stored in \fIframes\fR +each containing at least one sample of each signal, and (by default, if no +\fIoption\fR is specified) \fBsampfreq\fR shows the number of frames per +second. This is the number of samples per second returned for each signal +when the record is read using the WFDB library function \fBgetvec\fR +in standard (low-resolution) mode; see \fBrdsamp\fR(1), for example. +.PP +If specified, the \fIoption\fR may be one of: +.TP +\fB-a\fR +List all signals in the record and their respective sampling frequencies. +.TP +\fB-h\fR +Print a usage summary. +.TP +\fB-H\fR +Show the highest frequency used for any signal in a multi-frequency record. +This is the number of samples per second returned by \fBgetvec\fR when the +record is read in high-resolution mode; see \fBrdsamp\fR(1), for example. .SH ENVIRONMENT .PP It may be necessary to set and export the shell variable \fBWFDB\fR (see @@ -18,7 +34,7 @@ \fIrecord\fR.hea header file .SH SEE ALSO -\fBsetwfdb\fR(1) +\fBrdsamp\fR(1), \fBsetwfdb\fR(1) .SH AUTHOR George B. Moody (george@mit.edu) .SH SOURCE diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/doc/wag-src/sumann.1 wfdb-10.5.14/doc/wag-src/sumann.1 --- wfdb-10.5.13/doc/wag-src/sumann.1 2002-07-31 23:17:23.000000000 -0400 +++ wfdb-10.5.14/doc/wag-src/sumann.1 2012-08-02 13:02:20.000000000 -0400 @@ -1,4 +1,4 @@ -.TH SUMANN 1 "31 July 2002" "WFDB 10.2.7" "WFDB Applications Guide" +.TH SUMANN 1 "2 August 2012" "WFDB 10.5.14" "WFDB Applications Guide" .SH NAME sumann \- summarize the contents of a WFDB annotation file .SH SYNOPSIS @@ -17,6 +17,15 @@ \fB-h\fR Print a usage summary. .TP +\fB-o\fR \fIbeat-table rhythm-table\fR +Append summaries of beat and rhythm annotations to the specified +\fIbeat-table\fR and \fIrhythm-table\fR files. +The summaries for the specified \fIrecord\fR are written as a single line in +CSV (comma-separated value) format in each file. If either file does not +exist, it is created, and a header line containing column names is written to +it. If the \fB-o\fR option is omitted, a more easily readable summary is +written to the standard output instead. +.TP \fB-q\fR Summarize QRS annotations only. .TP diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/doc/wpg-src/wpg0.tex wfdb-10.5.14/doc/wpg-src/wpg0.tex --- wfdb-10.5.13/doc/wpg-src/wpg0.tex 2012-05-13 15:10:53.000000000 -0400 +++ wfdb-10.5.14/doc/wpg-src/wpg0.tex 2012-08-13 17:35:48.000000000 -0400 @@ -9049,6 +9049,17 @@ @unnumberedsec WFDB 10.5 +@unnumberedsubsec Changes in version 10.5.14 (13 August 2012) + +WFDB applications can now read shared and private PhysioNetWorks projects +securely, just as they have been able to read PhysioBank data since version +10.0.1 (November 1999). Low-level functions wfdb_open (in lib/wfdbio.c) and +readheader (in lib/signal.c) incorporate changes to implement this new +capability, as well as another new feature that allows record names to be +specified using absolute pathnames or URLs. As always, a final '.hea' is not +considered to be part of a record name, but it may be included or omitted as +desired. + @unnumberedsubsec Changes in version 10.5.13 (13 May 2012) Versions of the WFDB library up to 10.5.10 ignored embedded empty lines diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/lib/signal.c wfdb-10.5.14/lib/signal.c --- wfdb-10.5.13/lib/signal.c 2012-05-04 13:24:59.000000000 -0400 +++ wfdb-10.5.14/lib/signal.c 2012-08-13 15:09:20.000000000 -0400 @@ -1,5 +1,5 @@ /* file: signal.c G. Moody 13 April 1989 - Last revised: 4 May 2012 wfdblib 10.5.13 + Last revised: 13 August 2012 wfdblib 10.5.14 WFDB library functions for signals _______________________________________________________________________________ @@ -804,14 +804,18 @@ return (0); } - /* If the record name includes a '.', assume it is a file name. */ - if (p = strstr(record, ".")) { - if ((hheader = wfdb_open(NULL, record, WFDB_READ)) == NULL) { + /* If the final component of the record name includes a '.', assume it is a + file name. */ + q = record + strlen(record) - 1; + while (p > q && *q != '.' && *q != '/' && *q != ':' && *q != '\\') + q--; + if (*q == '.') { + if (strcmp(q+1, "hea")) /* assume EDF if suffix is not '.hea' */ + return (edfparse(hheader)); + else if ((hheader = wfdb_open(NULL, record, WFDB_READ)) == NULL) { wfdb_error("init: can't open %s\n", record); return (-1); } - else if (strcmp(p+1, "hea")) /* assume EDF if suffix is not '.hea' */ - return (edfparse(hheader)); } /* Otherwise, assume the file name is record.hea. */ diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/lib/wfdb.h wfdb-10.5.14/lib/wfdb.h --- wfdb-10.5.13/lib/wfdb.h 2012-05-13 15:11:24.000000000 -0400 +++ wfdb-10.5.14/lib/wfdb.h 2012-08-13 15:23:30.000000000 -0400 @@ -32,7 +32,7 @@ /* WFDB library version. */ #define WFDB_MAJOR 10 #define WFDB_MINOR 5 -#define WFDB_RELEASE 13 +#define WFDB_RELEASE 14 #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.13/lib/wfdbinit.c wfdb-10.5.14/lib/wfdbinit.c --- wfdb-10.5.13/lib/wfdbinit.c 2012-04-06 14:17:31.000000000 -0400 +++ wfdb-10.5.14/lib/wfdbinit.c 2012-08-02 11:11:16.000000000 -0400 @@ -1,5 +1,5 @@ /* file: wfdbinit.c G. Moody 23 May 1983 - Last revised: 6 April 2012 wfdblib 10.5.11 + Last revised: 2 August 2012 wfdblib 10.5.14 WFDB library functions wfdbinit, wfdbquit, and wfdbflush _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) @@ -49,9 +49,6 @@ resetwfdb(); /* restore the WFDB path */ wfdb_sampquit(); /* release sample data buffer */ wfdb_freeinfo(); /* release info strings */ -#if WFDB_NETFILES - wfdb_wwwquit(); /* release resources allocated by libcurl or libwww */ -#endif } FVOID wfdbflush(void) /* write all buffered output to files */ diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/lib/wfdbio.c wfdb-10.5.14/lib/wfdbio.c --- wfdb-10.5.13/lib/wfdbio.c 2012-04-24 16:18:31.000000000 -0400 +++ wfdb-10.5.14/lib/wfdbio.c 2012-08-13 15:21:53.000000000 -0400 @@ -1,5 +1,5 @@ /* file: wfdbio.c G. Moody 18 November 1988 - Last revised: 24 April 2012 wfdblib 10.5.12 + Last revised: 13 August 2012 wfdblib 10.5.14 Low-level I/O functions for the WFDB library _______________________________________________________________________________ @@ -77,9 +77,9 @@ Dakin. Thanks, Mike! These functions, defined here if WFDB_NETFILES is non-zero, are intended only -for the use of the functions in the next group below (except for wfdb_wwwquit, -their definitions are not visible outside of this file): - wfdb_wwwquit * (shut down libcurl or libwww cleanly) +for the use of the functions in the next group below (their definitions are not +visible outside of this file): + wfdb_wwwquit (shut down libcurl or libwww cleanly) www_init (initialize libcurl or libwww) www_get_cont_len (find length of data for a given url) www_get_url_range_chunk (get a block of data from a given url) @@ -103,12 +103,6 @@ nf_putc (emulates putc, for netfiles) [stub] nf_vfprintf (emulates fprintf, for netfiles) [stub] -* wfdb_wwwquit is available outside of this file; it is invoked by wfdbquit -(defined in wfdbinit.c) to permit an application to release resources used -by libcurl or libwww before exiting. wfdb_wwwquit is also registered (by -www_init) as a function to be invoked on exit from an application, so it is not -necessary for applications to invoke wfdb_wwwquit (or wfdbquit) explicitly. - In the current version of the WFDB library, output to remote files is not implemented; for this reason, several of the functions listed above are stubs (placeholders) only, as noted. @@ -958,11 +952,25 @@ return (wfdb_fopen(wfdb_filename, AB)); } - /* If the file is to be opened for input, prepare to search the database - directories. */ - + /* Parse the WFDB path if not done previously. */ if (wfdb_path_list == NULL) (void)getwfdb(); + /* If the filename contains '://', or if it begins with a directory + separator, it's an absolute URL or pathname. In this case, don't search + the WFDB path, but add its parent directory to the path if the file can + be read. */ + if (strstr(r, "://") || *r == DSEP) { + if (strlen(r) + strlen(s) >= MFNLEN) + return (NULL); /* name too long */ + spr1(wfdb_filename, r, s); + if ((ifile = wfdb_fopen(wfdb_filename, RB)) != NULL) { + /* Found it! Add its path info to the WFDB path. */ + wfdb_addtopath(wfdb_filename); + SFREE(r); + return (ifile); + } + } + for (c0 = wfdb_path_list; c0; c0 = c0->next) { static char long_filename[MFNLEN]; @@ -1208,7 +1216,7 @@ #define chunk_putb HTChunk_putb #endif -void wfdb_wwwquit(void) +static void wfdb_wwwquit(void) { if (www_done_init) { #if WFDB_NETFILES_LIBCURL @@ -1228,7 +1236,7 @@ static void www_init(void) { if (!www_done_init) { - char *p, version[20]; + char *p, *u, version[20]; if ((p = getenv("WFDB_PAGESIZE")) && *p) page_size = atol(p); @@ -1242,11 +1250,23 @@ curl_easy_setopt(curl_ua, CURLOPT_FAILONERROR, 1L); /* String to send as a User-Agent header */ curl_easy_setopt(curl_ua, CURLOPT_USERAGENT, curl_get_ua_string()); +#ifdef USE_NETRC /* Search $HOME/.netrc for passwords */ curl_easy_setopt(curl_ua, CURLOPT_NETRC, CURL_NETRC_OPTIONAL); +#endif + /* Get user name and password from the environment if available */ + if ((u = getenv("PNWUSER")) && *u && + (p = getenv("PNWPASS")) && *p) { + char *userpwd = (char *)malloc(strlen(u) + strlen(p) + 2); + sprintf(userpwd, "%s:%s", u, p); + curl_easy_setopt(curl_ua, CURLOPT_USERPWD, userpwd); + for (p = userpwd; *p; p++) + *p = ' '; + free(userpwd); + } + /* Use any available authentication method */ curl_easy_setopt(curl_ua, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - /* (Uncomment this line to enable tons of debugging information from libcurl) */ /* curl_easy_setopt(curl_ua, CURLOPT_VERBOSE, 1L); */ diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/lib/wfdblib.h wfdb-10.5.14/lib/wfdblib.h --- wfdb-10.5.13/lib/wfdblib.h 2012-05-05 19:48:04.000000000 -0400 +++ wfdb-10.5.14/lib/wfdblib.h 2012-08-13 15:34:10.000000000 -0400 @@ -1,5 +1,5 @@ /* file: wfdblib.h G. Moody 13 April 1989 - Last revised: 24 April 2012 wfdblib 10.5.12 + Last revised: 2 August 2012 wfdblib 10.5.14 External definitions for WFDB library private functions _______________________________________________________________________________ @@ -96,9 +96,9 @@ variable is not set. This value is edited by the configuration script (../configure), which also edits this block of comments to match. - If WFDB_NETFILES support is disabled, the string ". /usr/local/database" is + If WFDB_NETFILES support is disabled, the string ". /home/george/Desktop/wfdb-10.5.14/build/database" is usually sufficient for a default WFDB path, thus restricting the search for - WFDB files to the current directory ("."), followed by /usr/local/database). + WFDB files to the current directory ("."), followed by /home/george/Desktop/wfdb-10.5.14/build/database). If WFDB_NETFILES support is enabled, the first setting below adds the web-accessible PhysioBank databases to the default path; you may wish to @@ -107,9 +107,9 @@ */ #ifndef WFDB_NETFILES -# define DEFWFDB ". /usr/local/database" +# define DEFWFDB ". /home/george/Desktop/wfdb-10.5.14/build/database" #else -# define DEFWFDB ". /usr/local/database http://physionet.org/physiobank/database" +# define DEFWFDB ". /home/george/Desktop/wfdb-10.5.14/build/database http://physionet.org/physiobank/database" #endif /* Mac OS 9 and earlier, only: The value of DEFWFDB given below specifies @@ -337,7 +337,6 @@ extern size_t wfdb_fwrite(void *ptr, size_t size, size_t nmemb, WFDB_FILE *fp); extern int wfdb_getc(WFDB_FILE *fp); extern int wfdb_putc(int c, WFDB_FILE *fp); -extern void wfdb_wwwquit(void); #endif /* These functions are defined in signal.c */ @@ -369,7 +368,7 @@ wfdb_getc(), wfdb_putc(); extern long wfdb_ftell(); extern size_t wfdb_fread(), wfdb_fwrite(); -extern void wfdb_clearerr(), wfdb_wwwquit(); +extern void wfdb_clearerr(); # endif /* Some non-ANSI C libraries (e.g., version 7, BSD 4.2) lack an implementation diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/lib/wfdblib.h0 wfdb-10.5.14/lib/wfdblib.h0 --- wfdb-10.5.13/lib/wfdblib.h0 2012-04-24 16:23:20.000000000 -0400 +++ wfdb-10.5.14/lib/wfdblib.h0 2012-08-02 11:34:37.000000000 -0400 @@ -1,5 +1,5 @@ /* file: wfdblib.h G. Moody 13 April 1989 - Last revised: 24 April 2012 wfdblib 10.5.12 + Last revised: 2 August 2012 wfdblib 10.5.14 External definitions for WFDB library private functions _______________________________________________________________________________ @@ -337,7 +337,6 @@ extern size_t wfdb_fwrite(void *ptr, size_t size, size_t nmemb, WFDB_FILE *fp); extern int wfdb_getc(WFDB_FILE *fp); extern int wfdb_putc(int c, WFDB_FILE *fp); -extern void wfdb_wwwquit(void); #endif /* These functions are defined in signal.c */ @@ -369,7 +368,7 @@ wfdb_getc(), wfdb_putc(); extern long wfdb_ftell(); extern size_t wfdb_fread(), wfdb_fwrite(); -extern void wfdb_clearerr(), wfdb_wwwquit(); +extern void wfdb_clearerr(); # endif /* Some non-ANSI C libraries (e.g., version 7, BSD 4.2) lack an implementation diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/MANIFEST wfdb-10.5.14/MANIFEST --- wfdb-10.5.13/MANIFEST 2012-05-07 04:02:50.000000000 -0400 +++ wfdb-10.5.14/MANIFEST 2012-08-13 19:02:14.000000000 -0400 @@ -23,6 +23,7 @@ app/nguess.c app/nst.c app/plotstm.c +app/pnwlogin app/pscgen.c app/pschart.c app/pschart.pro @@ -318,6 +319,7 @@ doc/wag-src/plt.1 doc/wag-src/pltf.1 doc/wag-src/pnnlist.1 +doc/wag-src/pnwlogin.1 doc/wag-src/pschart.1 doc/wag-src/psfd.1 doc/wag-src/rdann.1 diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/NEWS wfdb-10.5.14/NEWS --- wfdb-10.5.13/NEWS 2012-05-13 16:03:06.861389753 -0400 +++ wfdb-10.5.14/NEWS 2012-08-13 19:54:56.659010975 -0400 @@ -1,3 +1,22 @@ +10.5.14 (2 August 2012): + WFDB applications can now read shared and private PhysioNetWorks + projects securely, just as they have been able to read PhysioBank + data since version 10.0.1 (November 1999). A new shell script + (app/pnwlogin) simplifies access to PhysioNetWorks projects. Low-level + functions wfdb_open (in lib/wfdbio.c) and readheader (in lib/signal.c) + incorporate changes to implement this new capability, as well as + another new feature that allows record names to be specified using + absolute pathnames or URLs. As always, a final '.hea' is not + considered to be part of a record name, but it may be included or + omitted as desired. + + WFDB library function wfdbquit() no longer frees resources allocated + by libcurl or libwww, in order to avoid doing so more than once in + programs that use wfdbquit() to reset state before opening a new record. + + Updates to app/sampfreq, app/sumann, and convert/ahaecg2mit provide + new features. See the WFDB Applications Guide for details. + 10.5.13 (13 May 2012): A flexible high-sensitivity QRS detector for research (app/gqrs.c), and a companion post-processor (app/gqpost.c) for improving its positive diff -Naur --exclude Makefile --exclude info wfdb-10.5.13/README.NETFILES wfdb-10.5.14/README.NETFILES --- wfdb-10.5.13/README.NETFILES 2005-06-01 14:23:48.000000000 -0400 +++ wfdb-10.5.14/README.NETFILES 2012-08-13 18:18:49.000000000 -0400 @@ -1,5 +1,5 @@ file: README.NETFILES G. Moody 14 September 1999 - Last revised: 27 May 2005 + Last revised: 13 August 2012 WFDB software reads its input from files that can be located on local disks or (if NETFILES support is present) on remote web and FTP servers. @@ -14,7 +14,7 @@ path should contain one or more components that refer to remote files available via http or ftp. If NETFILES support is included, the default WFDB path (defined in lib/wfdblib.h) is - . /usr/database http://www.physionet.org/physiobank/database + . /usr/database http://physionet.org/physiobank/database (i.e., the first component is the current (local) directory, the second is /usr/database in the local file system, and the third component is the top-level PhysioBank database directory). If you use a local PhysioBank @@ -37,41 +37,34 @@ own subdirectory of mimicdb, two levels of additional path information are necessary) - -If you have built the WFDB library using libcurl, version 7.12.0 or later, -then WFDB applications can also read password-protected files. The simplest -way to use this feature is to create a text file named .netrc containing -entries such as - - machine www.physionet.org - login testuser - password PhysioNet - -If your .netrc contains the three lines as shown above, and your WFDB library -was compiled with libcurl 7.12.0 or later, you can test this feature with a -command such as: - - rdann -r access-demo/100s -a atr - -which will read 'atr' annotations from a password-protected copy of the -sample record (100s) on the master PhysioNet server. Your browser can read the -same files at http://physionet.org/physiobank/database/access-demo/ (enter -"testuser" and "PhysioNet" respectively when prompted for a user name and -a password). This demo uses digest authentication (the password is transmitted -in encrypted form, and compared against an encrypted copy on the server), but -basic authentication (in which the password is transmitted in cleartext) is -also supported. Note, however that the data retrieved from the server travel -across the net in cleartext. If you wish to provide restricted access to -protected health information on your server to WFDB applications, we recommend -seting up SSL on your server, and using the SSL-enabled version of libcurl; -using SSL, the data travel in encrypted form across the net. + wave -r mimicdb/237/ -a al (MIMIC Database, record 237, as above; + allowed as a shortcut beginning in + version 10.5.6, November 2010) NETFILES support was originally implemented by Michael Dakin as part of his -summer 1999 UROP project at MIT. Mike used the W3C's libwww in his original -implementation. The libwww maintainers last updated the library in June, 2002, -and in January, 2004, the W3C formally announced that it would not continue -development of libwww, although the library remains freely available. In May, -2005, Benjamin Moody reimplemented NETFILES using libcurl. The primary -advantages of libcurl over libwww are that libcurl is smaller and faster, it -supports access to password-protected files, and it is actively maintained. -Both libraries are freely available on all popular platforms. +summer 1999 UROP project at MIT; version 10.0.1 of the WFDB library was the +first release to include this feature, in November, 1999. Mike used the W3C's +libwww in his original implementation. The libwww maintainers last updated the +library in June, 2002, and in January, 2004, the W3C formally announced that it +would not continue development of libwww, although the library remains freely +available. In May, 2005, Benjamin Moody reimplemented NETFILES using libcurl. +The primary advantages of libcurl over libwww are that libcurl is smaller and +faster, it supports access to password-protected files (see below), and it is +actively maintained. Both libraries are freely available on all popular +platforms. + + +Direct access from WFDB applications to password-protected files +---------------------------------------------------------------- + +If you have built the WFDB library using libcurl, version 7.12.0 or later, +then WFDB applications can also read password-protected files, such as those +within PhysioNetWorks shared or private projects. The preferred way to do +this is to set the PNWUSER and PNWPASS environment variables as is done by +the pnwlogin script (see app/pnwlogin). This method is usable with WFDB +library version 10.5.14 (August 2012) and later. Versions 10.3.16 (June 2005) +through 10.5.13 can also provide access to password-protected files by use of +a text file named .netrc, but this method is less secure than the newer method, +which does not require the credentials to be kept in permanent storage. The +use of .netrc is described in previous versions of this file; it is not +recommended or supported in current installations.