#!/usr/bin/perl # file: rdann G. Moody 9 April 2000 # Last revised: 29 December 2004 # _____________________________________________________________________________ # CGI program to convert PhysioBank signals to text # Copyright (C) 2000-2004 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/). # _____________________________________________________________________________ use CGI qw/:standard/; use CGI::Carp 'fatalsToBrowser'; $| = 1; # _____________________________________________________________________________ # Read the list of databases and their descriptions (once only). if (!$databases[0]) { read_dblist(); } # Decide what is to be done next. if (param) { $action = param('doit'); # the name of the button that was clicked, if any } else { $action = "Select database"; # default: choose a database on entry } if ($action eq "Select database") { choose_db(); } else { # database has been chosen; get list of records $database = param('database'); if (!param('record')) { choose_record(); $action = "Continue"; } $record = param('record'); if ($record =~ /.+\n/) { chop($record); } $annotator = param('annotator'); $tstart = param('tstart'); $tend = param('tend'); if ($action ne 'Continue') { output_results(); # depending on which button clicked, show or email } } # _____________________________________________________________________________ # Read the list of available databases. sub read_dblist { $dblistfile = '/home/physionet/html/physiobank/database/DBS-annotated'; if (open(DBS,$dblistfile)) { @dblist = ; $i = 0; foreach $d (@dblist) { @fields = split(/\t+/,$d); chop($fields[1]); $dblist[$i++] = $fields[0]; $dblabels{$fields[0]} = $fields[1] . " (" . $fields[0] . ")"; } } else { @dblist = (''); } } # _____________________________________________________________________________ # Show the database choice form. sub choose_db { print header, start_html(-dtd=>'-//IETF//DTD HTML//EN', -bgcolor=>'white',-title=>'rdann-O-Matic'); print_header(); print start_form, table({-border=>0,-bgcolor=>'#d0d0ff',-width=>'100%'}, Tr({-align=>CENTER,-valign=>CENTER}, [ th('Database:'. popup_menu(-name=>'database', -value=>[@dblist], -labels=>{%dblabels}). submit(-name=>'doit',-value=>'Continue')) ] )), end_form; print h2('rdann-O-Matic: Convert annotations to text'); print < The rdann-O-Matic allows you to convert binary annotation files from PhysioBank into text form. Please choose a database from the list above, then click on Continue. Once you have done so, you will be able to choose a record, an annotator (a set of annotations), and the starting and ending times for the conversion. You will be able to view the text with your web browser, or you can have it sent to you via e-mail.

A key for the annotation codes is available here. To view the annotations together with the associated signals, try the Chart-O-Matic. To view the digitized signals as text, try the rdsamp-O-Matic.


EOF print_footer(); } # _____________________________________________________________________________ # Read the list of records for the chosen database. sub read_rlist { $rlistfile = '/home/physionet/html/physiobank/database/' . $database . '/RECORDS'; if (open(RECORDS,$rlistfile)) { @rlist = ; } else { @rlist = (''); } } # _____________________________________________________________________________ # Read the list of annotators for the chosen database. sub read_alist { $alistfile = '/home/physionet/html/physiobank/database/' . $database . '/ANNOTATORS'; if (open(ANNOTATORS,$alistfile)) { @annotators = ; $i = 0; foreach $a (@annotators) { @fields = split(/\t+/,$a); chop($fields[1]); $alist[$i++] = $fields[0]; $adlist{$fields[0]} = $fields[0] . " (" . $fields[1] . ")"; } } else { $alist[0] = ''; $adlist{''} = ('(no annotations)'); } } # _____________________________________________________________________________ # Show the record/start/end choice form. sub choose_record { read_rlist(); read_alist(); print header, start_html(-dtd=>'-//IETF//DTD HTML//EN', -bgcolor=>'white',-title=>'rdann-O-Matic'); print_header(); print start_form, table({-border=>0,-bgcolor=>'#d0d0ff',-width=>'100%'}, Tr({-valign=>CENTER}, [ th({-align=>RIGHT}, 'Database:') . td({-align=>LEFT}, '" . $dblabels{$database} . "", submit(-name=>'doit', -value=>'Select database')), th({-align=>RIGHT},'Record:') . td({-align=>LEFT}, popup_menu(-name=>'record', -value=>[@rlist])) . td({-align=>RIGHT}, 'View signals'), th({-align=>RIGHT},'Annotator:') . td({-align=>LEFT},popup_menu(-name=>'annotator', -value=>[@alist], -labels=>{%adlist})), th({-align=>RIGHT},'Start time:') . td({-align=>LEFT},textfield(-name=>'tstart', -size=>40, -value=>'0')) . td({-align=>RIGHT}, 'Annotation key'), th({-align=>RIGHT},'End time:') . td({-align=>LEFT},textfield(-name=>'tend', -size=>40, -value=>'end')), td({-align=>RIGHT}, submit(-name=>'doit',-value=>'Show annotations')) . td({-align=>LEFT},submit(-name=>'doit', -value=>'E-mail annotations to:'), textfield(-name=>'email',-size=>20)) . td({-align=>RIGHT},submit(-name=>'doit', -value=>'rdann-O-Matic Help')) ] )), hidden(-name=>'database',-value=>$database), end_form; } # _____________________________________________________________________________ # Show instructions for filling in the record choice form. sub print_help { print h2('rdann-O-Matic: Convert annotations to text'); print < Please choose a record and an annotator (a set of annotations) from the list above. In the start time field, enter the elapsed time from the beginning of the record, in hh:mm:ss format. For example, to begin two minutes from the beginning of the record, enter 2:0 in the start time field (leading zero digits may be omitted). Enter the end time in the same format. As a special case, use e or end in the end time field to specify that you wish to list annotations until the end of the record. (Four to six hours of annotations typically convert to about one megabyte of text.)

To view the requested data with your web browser, click on Show annotations. Cut and paste the text or use the Save or Save As features provided by your browser to copy the output to a file on your disk.

To transmit the requested data via e-mail, enter your e-mail address in the space provided above, then click on E-mail annotations to:. The e-mail will be sent within a few seconds, although your mail server may take a few minutes to transfer it to your mailbox. If you do not receive it within a reasonable time, try specifying a shorter segment, since your mail server may reject very long messages.

The output is generated by rdann, which is freely available in portable C source form and in precompiled binary versions for several popular operating systems. You may run rdann on your own computer to convert annotation files from PhysioNet and other sources into text form.


EOF } # _____________________________________________________________________________ # Show or email the selected data. sub output_results { choose_record(); set_rdann_variables(); if ($action eq 'rdann-O-Matic Help') { print_help(); print_footer(); return; } # Convert the selected data and save in a temporary file. $tfile = "/tmp/rdann.$$"; unless (fork) { open(STDOUT, ">$tfile"); exec("/usr/bin/rdann", "-r", $database . "/" . $record, "-a", $annotator, "-f", $tstart, "-t", $tend, "-v"); } # When rdann is finished, check if it wrote anything. wait; open(RDANN, $tfile); $annotations = ; if (!$annotations) { print h1('No annotations!'); print < No annotations were read. This might occur if the record or annotator name is incorrect, if the start or end time is improperly formatted, or if no annotations exist between the start and end times specified. Please check and correct your entries above.

If you are using one of the PhysioNet mirrors, it may not be able to convert annotations to text; in this case, try using the rdann-O-Matic on the master PhysioNet server.


EOF print_footer(); } else { # rdann was successful! if ($action eq 'E-mail annotations to:') { output_email(); } else { print '
';
	    print $annotations;
	    while ($annotations = ) {
		print $annotations;
	    }
	    print '
'; } } unlink($tfile); } # _____________________________________________________________________________ # Set variables for the rdann command-line options. sub set_rdann_variables { $database = param('database'); $record = param('record'); $annotator = param('annotator'); if ($record =~ /.+\n/) { chop($record); } $tstart = param('tstart'); $tend = param('tend'); if (!$database) { $database = "mitdb"; } if (!$record) { $record = "100"; } if (!$annotator) { $annotator = "atr"; } if (!$tstart) { $tstart = 0; } if (!$tend) { $tend = "end"; } if (!$action) { $action = "Show samples"; } } # _____________________________________________________________________________ # Send the output as email. sub output_email { my $email = param('email'); # Check that the user entered a plausible email address. if ($email =~ /^([-\w.]+)@([-\w]+)\.([-\w.]+)$/) { my $subject = 'Annotations of record ' . $database . '/' . $record . ', annotator ' . $annotator; system("/bin/mail -s '$subject' $email <$tfile"); print h1('Data sent'); print < The requested data have been sent to $email. EOF } else { print h1('E-mail address needed'); print < If you wish to transmit the requested data via e-mail, enter your e-mail address in the space provided on the form, then click again on E-mail annotations to:.

If you wish to view the requested data with your web browser, click on Show annotations. The data will appear in another window.


EOF } print_footer(); o} # _____________________________________________________________________________ # Boilerplate header. sub print_header { if (open(HEADER,"/home/physionet/html/links-physiobank.html")) { while (
) { print $_; } } } # _____________________________________________________________________________ # Boilerplate footer. sub print_footer { print <

Please e-mail your comments and suggestions to webmaster\@physionet.org, or post them to:

PhysioNet
MIT Room E25-505A
77 Massachusetts Avenue
Cambridge, MA 02139 USA

Updated Friday, 10 September 2004 at 11:28 EDT EOF print end_html; }