#!/usr/bin/perl
# file: samples_to_mat.pm      	G. Moody         5 March 2009
#				Last revised:  11 February 2014
# _____________________________________________________________________________
# samples_to_mat module for PhysioBank's Automated Teller Machine
# Copyright (C) 2009-2014 George B. Moody

use File::Basename;

sub mod_samples_to_mat {

    # Set the path, URL, and final output filenames and URLs for this request.
    $wd =    "export/matlab";
    $wu =    "$baseurl/$wd";
    $wp =    "$basepath/$wd";
    $orec =  basename($record);
    $orec =~ tr/./_/;
    $info =  "$orec" . "m.info";
    $mat =   "$orec" . "m.mat";
    $hea =   "$orec" . "m.hea";
    $pinfo = "$wp/$info";
    $pmat =  "$wp/$mat";
    $phea =  "$wp/$hea";
    $uinfo = "$wu/$info";
    $umat =  "$wu/$mat";
    $uhea =  "$wu/$hea";

    # Set up the command for this request.
    @w2m_args = ("-r", "$database/$record", "-f", $tstart, "-t", $tend,
		 "-l", "s1000000");
    if (defined $signal_num) { push(@w2m_args, "-s", $signal_num); }

    # If results for this request are already in the cache, return them.
    if (-s $pinfo && -s $pmat && -s $phea) {
	mod_mat_out();
	return;
    }

    # Create the scratch directory for this request.
    $wt = "/ptmp/atm/scratch/$$/";
    mkpath($wt);

    # Make temporary filenames.
    $tinfo = "$wt/$info";
    $tmat =  "$wt/$mat";
    $thea =  "$wt/$hea";

    unless (fork) {
	chdir $wt;
	open(STDOUT, ">$tinfo");
	exec($WFDB2MAT, @w2m_args);
    }

    # Wait until wfdb2mat is finished.
    wait;

    if (-s $phea) {  # there was a race, and this process lost!
	unlink($tinfo);
	unlink($tmat);
	unlink($thea);
	# cron will remove $wt
    }
    else {
	# make sure path to $pmat exists ($record might include path info)
	mkpath("$wp/$record");
	rename($tinfo, $pinfo);
	rename($tmat, $pmat);
	rename($thea, $phea);
	rmdir("$wp/$record"); # safe since files are kept one level above this
    }
    mod_mat_out();
}

sub mod_mat_out {
    # Show the command and the info.
    if (-s $pinfo) {
	# if ($signal =~ / /) { pop(@w2m_args); push(@w2m_args, "'$signal'"); }
	$tmsize = -s $pmat;
	$thsize = -s $phea;
	$tisize = -s $pinfo;
	$mrec = $orec . 'm';
	print '<font size=-1><b>The output below was prepared using this',
        ' command:</b><br> <pre><a href=/physiotools/wag/wfdb2m-1.htm' .
	    ' title="wfdb2mat is a WFDB application">wfdb2mat</a>' .
	    " @w2m_args", " &gt;<a href=$uinfo ".
	    'title="a text file containing the summary below">' .
	    "$mrec.info</a>",
	    '</pre>';
	print "<p><b>Download these files</b>:" .
	      " <ul><li><a href=$umat>$mrec.mat</a>" .
	      " (binary, $tmsize bytes; the matrix of raw signal values)" .
	      " <li><a href=$uinfo>$mrec.info</a> (text, $tisize bytes;" .
	      " signal names and other information about $mrec.mat)" .
	      " <li><a href=$uhea>$mrec.hea</a> (text, $thsize bytes;" .
	      " needed to read $mrec.mat using applications in the" .
	      " <a href=/physiotools/wfdb.shtml>WFDB Software Package</a> or" .
	      " functions in the <a href=/physiotools/matlab/wfdb-app-matlab" .
	      " >WFDB Toolbox for MATLAB</a>)" .
	      " <li><a href=/physiotools/matlab/plotATM.m>plotATM.m</a>" .
	      " (m-code text;  a function that reads $mrec.mat and $mrec.info" .
	      " and plots the converted data.)</ul>" .
	      " <p><b>How to read these files in MATLAB or Octave:</b><br>" .
	      " <em>Download both $mrec.mat and $mrec.info.</em>  Also" .
	      " download plotATM.m if you have not done so previously." .
	      " <p>Each <em>row</em> of $mrec.mat contains the samples of one" .
	      " signal.  Each <em>column</em> contains a sample of each" .
	      " signal observed at the same time.  The time intervals between" .
	      " consecutive columns are equal and specified in $mrec.info." .
	      " <p>In MATLAB or Octave, run the command<pre>" .
	      "   plotATM('$mrec')</pre>" .
	      " to view the signals.  Inspect plotATM.m to see how use the" .
	      " information from $mrec.info to convert the raw samples from" .
	      " $mrec.mat into values in calibrated physical units.",
	      " <p><b>Note</b>:  This is a conversion of signals only," .
	      " <em>not</em> annotations.  The amount of data converted is" .
	      " limited to 1 million samples per signal since larger amounts" .
	      " may be difficult to manipulate using MATLAB or Octave.</font>";
    }
    else {
	show_html("no-samples");
    }
}

1;
