[Bio] / FigWebServices / RTMg.cgi Repository:
ViewVC logotype

View of /FigWebServices/RTMg.cgi

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (download) (annotate)
Fri May 3 17:21:47 2013 UTC (6 years, 6 months ago) by redwards
Branch: MAIN
CVS Tags: rast_rel_2014_0912, rast_rel_2014_0729, HEAD
Changes since 1.6: +31 -9 lines
adding RTMg pages

use strict;
use CGI qw/:standard/;
use CGI::Carp qw/fatalsToBrowser/;
use raelib;
use lib '/home/redwards/perl/lib/perl5/site_perl/5.8.7/i686-linux/', '/home/redwards/perl/lib/perl5/site_perl/5.8.7';
use JSON::XS;
use File::Slurp;
use LWP::Simple qw/getstore/;


my $jobfn = $$;

# I disabled the upload call back because it is significantly slowing everything down.
#my $cgi=CGI->new(\&_hook, $jobfn);
my $cgi=CGI->new();

my $progressfile = $FIG_Config::temp."/RTMg_progress.txt";
if (-e $progressfile) {
	my @stat = stat($progressfile);
	my $mtime;
	($stat[8] > $stat[9]) ? ($mtime=$stat[8]) : ($mtime=$stat[9]);
	#if ((time - $mtime) > 3600) {unlink $progressfile}
}

my $fullurl = $cgi->url(-full=>1); # http://bioseed.mcs.anl.gov/~redwards/FIG/RTMg2.cgi


# this is the js associated with the call back for uploading. We don't use it anymore, but it is here in case we need it
my $not_used_js = <<EOF;
	
	// var interval = window.setInterval('getUploadPercent()', 4000);


function getUploadPercent() {
	
	var filename = document.getElementsByName('uploadfile')[0].value;
	var url = "${fullurl}?percentdone=1&upload_filename=" + filename;
	var xmlrequest = false; 
	if (window.XMLHttpRequest) {
		xmlrequest = new XMLHttpRequest();
	}
	else if (window.ActiveXObject) {
		xmlrequest = new ActiveXObject("Microsoft.XMLHTTP");
	}
	xmlrequest.open("GET",url,true);

	xmlrequest.onreadystatechange=function() {
		if(xmlrequest.readyState==4 && setPercent) {
			setPercent(xmlrequest.responseText);
		}
	}

	if (window.XMLHttpRequest) {
		xmlrequest.send(null);
	}
	else if (window.ActiveXObject) {
	xmlrequest.send();
        }
}

function setPercent(obj) {
	var perc = JSON.parse(obj);
	document.getElementById('uploading').innerHTML = perc.percent + " percent uploaded";
}


EOF


my $html=[''];
my $error=[''];
my $jobID = $$;
my $dest = $FIG_Config::temp. "/rtmg/$jobID";
unless (-d $dest) {mkdir $dest, 0755}

my $js = <<EOF;
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-9209517-1");
pageTracker._trackPageview();
} catch(err) {}</script>
EOF

my $base = $FIG_Config::cgi_url;
my $upload_js = <<EOF;
<script type="text/javascript">
function uploadingNow() {
	document.getElementById('uploadField').innerHTML = "<p>Uploading your file, " + document.getElementsByName('uploadfile')[0].value + "</p>";
	document.getElementById('cacheImg').style.display="block";
}



function showAdvancedSettings() {
	var id1 = document.getElementById('showadvancedSettings').style;
	var id2 = document.getElementById('advancedSettings').style;
	if (!id1.display) 
		id1.display = "block";
	if (!id2.display) 
		id2.display = "none";
	
	id1.display = (id1.display == "none" ? "block" : "none");
	id2.display = (id2.display == "none" ? "block" : "none");
}
	
	
</script>
EOF




if ($cgi->param('percentdone')) {
	my $id = $cgi->param('upload_filename');
	my $perc = 0;
	# my $of = "/home/redwards/FIGdisk/FIG/Tmp/RTMG.uploads";
	my $of = $progressfile;
	#if (-e $FIG_Config::temp."/$id.uploads") {
	if (-e $of) {
		#open(IN, $FIG_Config::temp."/$id.uploads") || die "can't open temp/$id";
		open(IN, $of) || die "can't open $of";
		while (<IN>) {
			chomp;
			my @a=split /\t/;
			$perc = $a[1] if ($id eq $a[0]);
		}
		close IN;
	}
	
	my $json= new JSON::XS;
	my $result =  $json->encode({percent => $perc});
	
	print $cgi->header('text/plain'), $result, "\n";
	exit(0);
}


#die Dumper($cgi);

if ($cgi->param('submit') eq "RTMg Lite") {
	my ($filename, $jsondata) = &process_data();

	print $cgi->header('text/html'), start_html(-title=>'Real Time Metagenomics', -style=>'./Html/css/RTMg.css'),
	      html(
			      script({-type=>'text/javascript', -src=>'./Html/css/RTMgLite.js'}, ""),
			      script({-type=>'text/javascript', -src=>'./Html/css/sorttable.js'}, ""),
			      script({-type=>'text/javascript', -src=>'./Html/css/json2.js'}, ""),
		      
		      	      div({id=>"header"}, " &nbsp; "),
			      div({id=>"header"}, 
				      a({class=>"help", href=>"./Html/RTMg.html"}, "Help! What is this?"), "\n",
				 ),
			      div({id=>"title"}, ("Annotating $filename in real time")),

		      

# the FileData div contains JSON formatted data
# but is hidden from the user
			      div({id=>"wsCalls"}, ""), "\n",p,
			      hidden(-id=>"FileData", -value=>$jsondata),
			      popup_menu(-name=>'setDisplay', -values=>[0, 1, 2, 3], 
			      	-labels=>{0=>"Function", 1=>"One level of subsystems", 2=>"Two levels of subsystems",
				3=>"Three levels of subsystems"},
				-onChange=>"getTable(this.value)", 
				-default=>3), p,
# I took out , 4=>"OTU"  
			      div({id=>"frame"}, iframe({name=>"TableIFrame", frameborder=>"0", width=>"100%", height=>"80%"}, " &nbsp; ")), "\n",
			      div({id=>"percent"}, ""), "\n",
			      div({id=>"primary"}, ""), "\n",
			      div({id=>"secondary"}, ""), "\n",
			      div({id=>"saveBox"}, ""), "\n",
			      div({id=>"saveHits"}, ""), "\n",
			      div({id=>"saveJson"}, ""), "\n",
			      div({id=>"errors"}, ""), "\n",
			      div({id=>"caughtErrors"}, ""), "\n",
			      
			      script({-type=>'text/javascript'}, "init();"),
			      # this updates the kmers to use version 49, soon need to take it out
			      # script({-type=>'text/javascript'}, "set_kmerDataset('Release49');"), ## this is handled in RTMg_Lite.js now
			      $js,
		  ), end_html();
	exit(0);
}







if ($cgi->param('submit') eq "Upload") {
	my ($filename, $jsondata) = &process_data();

	print $cgi->header('text/html'), start_html(-title=>'Real Time Metagenomics', -style=>'./Html/css/RTMg.css'),
	      html(
			      script({-type=>'text/javascript', -src=>'./Html/css/RTMg.js'}, ""),
			      script({-type=>'text/javascript', -src=>'./Html/css/sorttable.js'}, ""),
			      script({-type=>'text/javascript', -src=>'./Html/css/json2.js'}, ""),
		      
		      	      div({id=>"header"}, " &nbsp; "),
			      div({id=>"header"}, 
				      a({class=>"help", href=>"./Html/RTMg.html"}, "Help! What is this?"), "\n",
				 ),
			      div({id=>"title"}, ("Annotating $filename in real time")),

		      

# the FileData div contains JSON formatted data
# but is hidden from the user
			      div({id=>"wsCalls"}, ""), "\n",p,
			      hidden(-id=>"FileData", -value=>$jsondata),
			      popup_menu(-name=>'setDisplay', -values=>[0, 1, 2, 3,4], 
			      	-labels=>{0=>"Function", 1=>"One level of subsystems", 2=>"Two levels of subsystems",
				3=>"Three levels of subsystems", 4=>"OTU"}, -onChange=>"setDisplayLevel(this)", 
				-default=>0), p,
			      div({id=>"percent"}, ""), "\n",
			      div({id=>"primary"}, ""), "\n",
			      div({id=>"secondary"}, ""), "\n",
			      div({id=>"saveBox"}, ""), "\n",
			      div({id=>"saveHits"}, ""), "\n",
			      div({id=>"saveJson"}, ""), "\n",
			      div({id=>"errors"}, ""), "\n",
			      div({id=>"caughtErrors"}, ""), "\n",
			      
			      script({-type=>'text/javascript'}, "init();"),
			      $js,
		  ), end_html();
	exit(0);
}


&blank_page();

sub blank_page {
	my ($error)=@_;
# this is a subroutine so we can call it as required, and pass in an error message
print $cgi->header('text/html'), start_html(-title=>'Real Time Metagenomics', -style=>'./Html/css/RTMg.css'), 
      html(
		      script({-type=>'text/javascript', -src=>'./Html/css/json2.js'}, ""),
		      div({id=>"header"},
		      start_multipart_form(-name=>"uploadmgx"), "\n",
		      ),
		      div({id=>"header"}, 
		      a({class=>"help", href=>"./Html/RTMg.html"}, "Help! What is this?"), "\n",
		      ),
		      div({id=>"title"}, ("Welcome to <br />Real Time Metagenomics")),
		      (($error) ? (div({id=>"errorMessage"}, $error)) : ""),
		      div({id=>"uploadField"},
		      "Welcome to the next revolution in metagenome annotation: Real time data processing and analysis. ",p,),
		      div({-id=>"cacheImg"}, "<img src='$base/Html/ajax-loader.gif' alt='spinning icon'></img>"),
		      "<div id='directions'>\n",
		        "You can upload DNA sequence data and we will provide an immediate annotation of the sequences there. ",
		        "We accept either fasta or fastq files, although we do not use the quality scores associated with fastq ",
		        "data. We recommend that you prescreen your sequences with <a href='http://edwards.sdsu.edu/prinseq/'>prinseq</a> ",
		        "before uploading those data for annotation.\n",p,

		        "Once your data has been processed you can download the results and load the numbers into Excel or ",
		        "your favorite program for statistical analysis.",p,
		      "</div>\n",
		      "Please let us know your email address. It is optional and is just used so we can contact you if we find an error.",p,
		      textfield(-name=>"email", -size=>"100"), p, "\n",
		      "You can either upload an uncompressed file, or data compressed with either zip or gzip &nbsp; ",p,
		      filefield(-name=>"uploadfile") , " or \n",p, 
		      "if your file is online, paste the url where your file is housed: &nbsp; ", p,
		      textfield(-name=>"fileurl", -size=>"100", -value=>"http://", -onFocus=>"this.value=''; return true;"), p, "\n",
		      submit(-name=>'submit', -value=>'RTMg Lite',  -onClick=>"uploadingNow(); return true;"), 
		      #submit(-name=>'submit', -value=>'Upload',  -onClick=>"uploadingNow(); return true;"),
		      reset, p,"\n",
		      div({id=>"showadvancedSettings"}, a({href=>"#", onClick=>"showAdvancedSettings(); return true;"}, h3("Show advanced settings"))),
		      div({id=>"advancedSettings"}, a({href=>"#", onClick=>"showAdvancedSettings(); return true;"},
		      	h3("Hide advanced settings")), p,
			"File chunks to process : ", 
			popup_menu(-name=>'chunks', -values=>[100, 500, 1000, 5000], -labels=>{100 => 'Extreme', 500=>'Lots', 1000=>'Average', 5000=>'Fewer'}, -default=>1000),
			p,
			"Stringency: ",
			popup_menu(-name=>'reliability',  -values=>[1, 2, 3, 4], -labels=>{1=>'Least stringent', 2=>'Regular', 3=>'Stringent', 4=>'Very stringent'}, -default=>2),
			p,
			"Word size: ",
			popup_menu(-name=>'kmer', -values=>[7, 8, 9, 10, 11, 12], -default=>8),
			p,
			"Maximum gap: ",
			popup_menu(-name=>"maxGap", -values=>[300, 600, 900], -default=>600),
			p,
			),
		      
		      end_form(), 
		      div({-id=>"uploading"}, ""), p,
		      $js,
		      $upload_js,
		      end_html());
exit(0);

		      # hidden(-name=>'file_id', -value=>$$),
		      # submit(-name=>'submit', -value=>'Check Status', -onClick=>"uploadingNow(); return true;"), p,"\n",
}


sub _hook {
	my ($filename, $buffer, $bytes_read, $data) = @_;
	my $of = $FIG_Config::temp."/RTMg_progress.txt";
	my $percent = int(($bytes_read / $ENV{CONTENT_LENGTH}) * 10000);
	$percent = $percent / 100;
	write_file( $of, {append => 1 }, "$filename\t$percent\n" );
	sleep 4;
}

sub notfasta {
	my $f=shift;
	print $cgi->header('text/html'), start_html(-title=>'Real Time Metagenomics', -style=>'./Html/css/RTMg.css'),
	      html(
		      	      div({id=>"header"}, " &nbsp; "),
			      div({id=>"header"}, 
				      a({class=>"help", href=>"./Html/RTMg.html"}, "Help! What is this?"), "\n",
				 ),
			      div({id=>"title"}, ("Annotating $f in real time")),
			      div("Sorry, the file $f does not appear to be a fasta format file. Please ",
			      " check the ", a({href=>"./Html/RTMg.html"}, "help pages "), " and try again."
			      ),
		);
	exit(0);
}

		      
sub process_data {
	my $file_id = $jobfn;
	my $of=$file_id;
	$of =~ s/\s+//g;
	$of =~ s/[^\w\.]*//g;
	my $filename;
	if ($cgi->param('uploadfile')) {
		$filename=$cgi->param('uploadfile');  
		no strict;
		if ($filename =~ /\.gz$/) {
			$of .= ".gz";
		}
		if ($filename =~ /\.zip$/) {
			$of .= ".zip";
		}

		open(OUT, ">$dest/$of") || die "Can't open $dest/$of for writing";
		my $bytesread; my $buffer;
		while ($bytesread=read($filename,$buffer,1024)) {print OUT $buffer}
		close OUT;

		strict;
	}
	elsif ($cgi->param('fileurl')) {
		my $url = $cgi->param('fileurl');
		$filename = $url; 
		$filename =~ s/^.*\///;

		if ($url =~ /\.gz$/) {
			$of .= ".gz";
		}
		if ($url =~ /\.zip$/) {
			$of .= ".zip";
		}
		my $retval = getstore($url, "$dest/$of");
		unless ($retval == 200) {
			&blank_page("Sorry, there was an error retrieving data from $url. Please check the URL and try again.");
		}
	}
	else {
		die "No data provided!";
	}

	open(MDT, ">>$dest/metadata.txt") || die "can't append to $dest/metadata.txt";
	print MDT "time\t", time, "\n";
	print MDT "localtime\t", scalar(localtime(time)), "\n";
	print MDT "ip_address\t", $ENV{REMOTE_ADDR}, "\n";
	print MDT "http_ua\t", $ENV{HTTP_USER_AGENT}, "\n";

	if ($cgi->param('email')) {
		print MDT "email\t", $cgi->param('email'), "\n";
	}
	close MDT;

	# check and see what kind of file it is
	{ # scope this block
		if ($of =~ /gz/) {
			open(IN, "gunzip -c $dest/$of|") || die "can't open $dest/$of";
		} 
		elsif ($of =~ /zip$/) {
			open(IN, "unzip -p $dest/$of|") || die "can't open $dest/$of";
		} 
		else {
			open (IN, "$dest/$of") || die "Can't open $dest/$of that we saved";
		}
		my $in = <IN>;
		if (index($in, "@") == 0) {
# this is a fastq file, and we need to convert it to a fasta file.
			$of .= ".fasta";
			open(OUT, ">$dest/$of") || die "CAn't open $dest/$of";
			$in =~ s/^\@/>/;
			print OUT $in;
			my $linecount=1;
			while ($in = <IN>) {
				$linecount++;
				if ($linecount==1) {$in =~ s/^\@/>/; print OUT $in;}
				elsif ($linecount==2) {print OUT $in;}
				elsif ($linecount==4) {$linecount=0}
			}
			close OUT;
		}
		if ($of =~ /gz/) {1 while (<IN>)} # this should stop an error being reported to the system logs

		close IN;
	}

	my $reliability = $cgi->param('reliability');
	my $kmer = $cgi->param('kmer');
	my $maxGap = $cgi->param('maxGap');

	my $fa = raelib->read_fasta("$dest/$of");
# we could let the user set this to increase or decrease the delay
	my $chunks = $cgi->param('chunks') || 100;
	my $count=0;
	my @keys=keys %$fa;
	if (!scalar(@keys) || (scalar(@keys) == 1 && $keys[0] !~ /\S/)) {
		&notfasta($filename);
	}
	while (@keys) {
		$count++;
		my @parts=splice(@keys, 0, $chunks);
		open(OUT, ">$dest/$of.$count") || die "can't write to dest/$of.$count";
		map { print OUT ">$_\n", $fa->{$_}, "\n" } @parts;
		close OUT;
	}
	#unlink("$dest/$of");

	# the json data to be sent out
	my $jsondata = '{"filename" : "'.$of.'", "nseqs" : "'.$count. '", "reliability" : "' . $reliability . '", "kmer" : "' . $kmer . '", "maxGap" : "' . $maxGap . '", "jobID" : "' . $jobID . '"}';
	return ($filename, $jsondata);
}



MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3