#!/usr/bin/perl ############################################## ############################################## # SCRIPT NAME: Page_Do_Blast_Searches.cgi # FUNCTION: Local Blast and Making Blast # Databases ############################################## # MINE: Molecular INformation Explorer # Copyright 2000 Dawn Field. All rights reserved. # The CGI-PERL scripts belonging to MINE # may be used and modified freely, but I do # request that this copyright notice remain attached # to this file/source code. If you make modifications # please do not distribute unless # you fully document the modifications. # This is one of the most complex scripts in MINE # see simpler scripts for more annotation of routinely # used pieces of code (if not annotated here) # It was original taken from the OUBC website (see acknowledgements), and there # is still code that was intended for a different set-up # that still needs to be removed. It all works, though! # search for the text "MACHINE_SPECIFIC" to find the code you need to change # MACHINE_SPECIFIC use CGI; require "CGI-MINE.pl"; # another way to flush the buffer to screen require "flush.pl"; ################# # START EACH MINE CGI SCRIPT ################# # this redirects the error messages to the user's screen # and is useful for debugging CGI scripts! open (STDERR, ">&STDOUT"); # print errors to screen $| = 1; # flush the print buffer continuously # make a new query object using CGI.pm module $query = new CGI; # print the required header and start the web page print $query->header; print $query->start_html('MINE Blast'); # Each time a script is invoked for the first time (or $action undef), # log the visit in the custom MINE server log (see CGI-MINE.pl) # (put this after the header incase an error message is printed) # check value of $action $action = $query->param('action'); if ($action eq undef) {&log();} # or select debugging from the user menu $debug = ""; # "1" to print, "0" to hide print statements # set $write_permission to 1 to allow the use of local fasta files as blast queries # set $write_permission to 0 to disable this functionality # search for the pattern $write_permission to see the effected code # SECURITY VARIABLE $write_permission = 0; # set to 1 to allow use of fasta files as queries and saving of blast files to disk # use a function in CGI-MINE.pl to see if we should allow this IP full permission to submit files # even if $write_permission = 0; &check_permission($write_permission); # initialize all variables (more to add if want to use strict module!) undef (@total_file_list); # MACHINE_SPECIFIC # allow certain remote users access to commerically own (site allowed) blast databases # if the user has a molbiol account, they can use all the GCG databases # if not, they can only use the ones that are not GCG made (commerical) $remote_host = $query->remote_host(); if ($remote_host =~ /ox.ac.uk/ || $remote_host =~ "192.171.160.131") { @Database_array =( # this is the blast database of all the current sequences in the database # go to the see all scripts option in the menu and select the # script Page_Make_Source_ADMIN.cgi: hit the button make fasta file and blast database # and this file will be made ["$blast_database (all current database entries) (N)", $blast_database, 2], ["xylella_blast_database (The Xylella fastidiosa genome sequence (N)", "xylella_blast_database", 2], ["Pseudomonas aeruginosa genome (N)", "ps_aero_genome_blast_database" ,2], ["P. fluorescens DNA sequences from genbank (N)", "GBK_Pf-dna.db_blast_database" ,2], ["Prokaryotic (N)", "pro" ,2], ["Swissprot","swissprot", 1], ["Genpept", "genpept",1], ["Trembl", "trembl" ,1], ["PIR", "pir" ,1], ["Non-redundant Total Peptides", "nraa" ,1], ["Vaccinia proteins", "vacc" ,1], ["GenEMBL", "genembl" ,2], ["EST part1 (1 - 1,000,000)", "est_part1" ,2], ["EST part2 (1,000,001 - 2,200,089 )", "est_part2" ,2], ["EST part3 (2,200,090 - end)", "est_part3" ,2], ["Est new since last release", "estnew" ,2], ["New", "new" ,2], ["Human (N)", "human" ,2], ["Human Repeat Sequences (N)", "humrepeats" ,2], ["Invertebrate (N)", "inv" ,2], ["EMBL last 24 hr update (N)", "last24" ,2], ["Mammalian (N)", "mamm" ,2], ["Mouse Repeat Sequences(N)", "mouse_repeats" ,2], ["EMBL updates (N)", "new" ,2], ["Organelle (N)", "organelle" ,2], ["Non-Primate, Non-Rodent Mammalian (N)", "other_mammal" ,2], ["Non-Mammalian Vertebrate (N)", "other_vert" ,2], ["Plants (incl. some fungi) (N)", "plantnuc" ,2], ["Primate (N)", "primnuc" ,2], ["Repeats (N)", "repbase" ,2], ["Rodent (N)", "rodnuc" ,2], ["Rodent Repeats (N)", "rodrep" ,2], ["Sequence Tagged Sites (N)", "sts" ,2], ["Common Vectors (N)", "vectors" ,2], ["Vertebrate RNA", "vertrna" ,2], ["Viral (incl. phage and unclassified) N", "viralplus" ,2], ["Yeast Orfs (N)", "yeast_orf" ,2] ); # end if ($remote_host =~ /ox.ac.uk/) before else } else { @Database_array =( ["$blast_database (all current database entries) (N)", $blast_database, 2], #["P. fluorescens Pf5 DNA database from TIGR (N)", "p_fluorescens", 2], #["Pseudomonas aeruginosa genome (N)", "AE004091.fna" ,2], #["Pseudomonas putida KT2400 DNA sequences from NCBI (N)", "p_putidaK" ,2], #["Pseudomonas syringae pv.tomato DNA sequences from NCBI (N)", "p_syringae" ,2], ["P. fluorescens Pf-5 DNA sequences from TIGR (N)", "Pf5" ,2] ); } # end if ($remote_host !~ /ox.ac.uk/) else statement # MACHINE_SPECIFIC # these are the environmental variables that a CGI script needs to know # before it can run a blastall search for you...you need to tailor # these paths to reflect how you have blastall installed on your system $ENV{'BLASTFILTER'}="/users/www/htdocs/pseudomonas/blast"; $ENV{'BLASTDB'}="/users/www/htdocs/pseudomonas/cgi-bin/MINE"; $ENV{'BLASTMAT'}="/users/www/htdocs/pseudomonas/blast/data"; $ENV{'PATH'}="/users/www/htdocs/pseudomonas/blast/: users/www/htdocs/pseudomonas/cgi-bin/MINE/"; @Database_trans =( ["EM\\w{2,5}_N:","emblnew"], ["EM\\w{2,3}\\d{0,2}:","embl"], ["SWISS\\w{2,5}:","swissprot"], ["SWNEW\\w{2,5}:","swissprot"], ["GP\\w{2,5}_N:","genpeptnew"], ["GP\\w{2,4}:","genpept"], ["TR\\w{2,5}:","sptrembl"], ["PIR\\w:","pir"], ["LAST\\w+:","emblnew"] ); # remove all the files written to the tmp/ directory that are left over from past searches so they don't accumulate @delete_file = ; # print "deleting all tmp files: ". @delete_file; foreach $delete (@delete_file) { unlink ($delete); } # a tmp directory is needes to keep temp files generated in search if (-d "tmp") { # print "You have a tmp directory"; } else { # print "You don't have a tmp directory:making one"; mkdir ("tmp", 0777)|| die "cannot make your tmp directory"; } ####### # START THE WEBPAGE ####### # print the MINE menu &menu; ############ # START FORM ############ # write a form to get a user input sequence # this option is fully functional because if you selected this, the blast parameters set before are deleted if ($query->param('action') eq "CHECK PARAMETERS BEFORE SUBMITTING") { # if CHECK PARAMETERS BEFORE SUBMITTING, check that the user is happy with all the parameters they filled in # write a simple form to get a user input sequence print $query->startform(); # add the start of background table &table_top(); print "

Here are all the parameters that you will be passing to the blastall program.

If you are satisfied that everything is as you want it, hit Submit! Otherwise, scroll down this page and edit your submission and hit GO! again.

Don't worry. If you have spaces and other non sequence characters in your sequence right now they will be parsed out before the blast query if submitted/

"; # print $query->dump(); # finish the background table &table_bottom(); # dont' end the form, since it needs to be appended with the GO! button below # to keep the query parameters from the original form # print $query->endform(); } elsif ($query->param('action') eq "Submit!") { # erase the tmp file when a blast search is first invoked # it's only open to append to later in the script open ( OUT , ">tmp_blast_results.html") || die "can't open the tmp_blast_results.html files"; close (OUT); if ($debug ==1) {print "you hit Submit!

I will now process your blast request.";} ################# # PROCESS FORM ################ &ProcessForm(); } else { # print "you have not hit any button yet

"; } ############ IF "Submit!" ################## # if a blast search is submitted and the query sequences are in a fasta file.. if ($query->param('action') eq "Submit!" && $query->param('fasta_file')) { &parse_fasta_file(@title, @text); } # end if a blast search is submitted and the query sequences are in a fasta file.. ############ IF "CHECK PARAMETERS BEFORE SUBMITTING" ################## # print the blast web form if the page is entered for the first time, or if the user # is checking their parameters first before submitting the blast search if (($query->param('action') eq "CHECK PARAMETERS BEFORE SUBMITTING") || ($query->param('action') eq undef)) { print $query->startform(); # add the start of background table &table_top(); print "Blast form

"; print "

When you've selected your parameters hit GO!

"; # print some buttons # print a 'submit' button at end of form: script self-calls print $query->submit('action','Submit!'); # print a 'clear' button at end of form: script self-calls print $query->defaults('Clear'); print "

"; ###### call PrintForm function####### &PrintForm; ##################################### print $query->endform(); &table_bottom(); ################# # END FORM ################# } # PRINT BOTTOM OF EACH WEB PAGE # if $show_source is set to 1 show a link # at the bottom of each script to the source # code - pass the name of this script to the # function in CGI-MINE.pl if ($show_source) { $script_name = $query->script_name(); &source ($script_name); } # ATTACH the MINE copywrite &mine_cp; print $query->end_html; ################# # END WEBPAGE ################# ##################### # FUNCTIONS ##################### ############################# # FUNCTION: Parse Fasta File # This function reads the header # and sequence from a fasta formated # file of blast query sequences. # Each header and its sequence is # placed into the arrays @title # (headers) and # @text (sequences) ############################# # Usage: &parse_fasta_file(@title, @text); sub parse_fasta_file { # get the name of the fasta file from the webform $fasta_file = $query->param('fasta_file') || undef; # get $title from file and $text from file $line = undef; $text = undef; open (NEWIN, $fasta_file) || warn "can't open your fasta file"; # get the first line $line = ; chomp($line); die "Sorry file is not in fasta format\n" if $line !~/^>/; $title = ($line) if $line =~/^>/; push(@title, $title) if $line =~/^>/; while ($line = ) { chomp($line); # push title if it equals > (one already in array) $title = ($line) if $line =~/^>/; push(@title, $title) if $line =~/^>/; # push text each time a new header is found push(@text, $text) if $line =~/^>/; # undef $text (the sequence) if a new header is found undef($text) if $line =~/^>/; # otherwise, collect the non-header lines into seq (text) $text .= ($line) if $line !~/^>/; } # push in the last seq at end of file push(@text, $text); # loop overall the titles ($#title is the last title in the array @title) foreach $loop ( 0 .. $#title){ # this is what database files look like #>File:SBW0011.db ID:Cosmid #046/T7 #>File:NNN001.db ID:(anything) $title[$loop] =~ /(ID:)(.*)/; $getid = "$1$2"; $id = $getid; $id =~ s/ID://; if ($debug == "1") { print "your fasta file:$title[$loop]\n$text[$loop]\n"; } } # end foreach $loop } # end sub parse_fasta_file ############################# # FUNCTION: Print Form # Print the entire blast interface # webform. # Uses traditional html # but could eventually be converted # to cgi.pm objects (see first bit # of commented code for an example # This is how the form was orignally # written at OUBC and I didn't want to # introduce any errors by converting it # (using the logic 'if it ain't broke # don't fix it). ############################# sub PrintForm { # example of how to switch the below over to CGI.pm object oriented syntax # the below webform is a big text block that I left because this # script was adapted from an OUCS script (see acknowledgements). If I # had started from scratch on this blast interface it would have all been # written using CGI.pm web form items. # @programs = qw(Blastn Blastp Blastx Tblastn Tblastx); # print "Please choose a program:

"; # print $query->popup_menu(-name=>'program', # -values=>[@programs], # -default=>'Blastn'); # ONE BIG text block forms the web form for submitting blastall parameters print <<'ENDOFTEXT1';

Please choose a program:
and a database do you want to search: ?

"; ################################################################################### # set the variable $write_permission to 1 at top of script # TO ALLOW BLASTING WITH Fasta FILES (must be same directory # set the variable $write_permission to 0 at top of script # to disable this functionality # SINCE ANY NUMBER OF SEQUENCES CAN BE IN EACH FILE, disabling this function # disallows ENDUSERS (strangers with your URL) from unknowingly lauching computationally intensive blast searches on # lots of sequences, or doing other malicious things to your computer ################################################################################### ########### If $write_permission = 1 write form to allow use of a fasta formatted file ############# # these lines of code print the pieces of the web form that allow user to # enter the name of a fasta file containing sequence(s) if ($write_permission) { print "

Please enter the name of a file containing fasta formatted sequences, or enter a plain DNA or Amino Acid sequence in the box below.

File name:"; print $query->textfield(-name=>'fasta_file', -size=>30, -maxlength=>80); # these lines of code print the pieces of the web form that allow user to # enter the name of a unique identifier for saving blast results print "

Enter a unique identifier (no spaces or metacharacters) to be appended to the file name in the blast archive "; print $query->textfield(-name=>'tag', -size=>15, -maxlength=>80); } # end if allow use of fasta files ################################################################################### print <<'ENDOFTEXT';

Please enter your sequence in free format
?

Options
Filter Query sequence: ?

Query strands to search against database:

Set sensitivity (Word length): For blastn (DNA searches) For blastp etc (protein search)

Set expectation threshold (E parameter): ?

Select alignment view option ?

Maximum number of sequences to display:

Output mode:


MSP processing options ?

MSP display mode

HSP ajacency rejection mode:

HSP bias-ratio rejection threshold:


How do you want to view the results

Do you want debugging output


Version of April 2000.

This blast interface has largely been adapted from the blast2 server interface hosted at the University of Oxford Bioinformatics Center. Original Interface by John Peden. Updated by Nicki Gray. Changes include migration from the cgi-lib.pl module to Lincoln Stein's CGI.pm module and the ability to make and archive 'blast databases' from searches involving multiple query sequ ences. Many thanks to OUCS.


ENDOFTEXT } ############################# # FUNCTION: ProcessForm # Process the web form and # do the blast searches ############################# # USAGE ProcessForm(); sub ProcessForm { print "Processing your Blast search.

"; # get the unique identifier the user selected $tag = $query->param('tag') || undef; # append an underscore to make reading the name of the output file clearer $tag ="_$tag"; $debug = "1" if $query->param('debug') eq "YES"; $debug = "0" if $query->param('debug') eq "NO"; undef(@text); undef(@title); if ($query->param('fasta_file')) { &parse_fasta_file(@title, @text); if ($debug ==1) {print "There are ".@title." titles and ".@text." text

here are the titles: @title

";} if ($debug ==1) {print "The first Fasta file is file: $title[0]

$text[0]

";} # this sets the first title and text $title = $title[0]; $text = $text[0]; } else { $title = $query->param('title'); unless ($title =~ /\w+/) {$title = "optional";} #Tidy up text pasted in by user if there is a seq $text = $query->param('text'); $text =~ tr/a-zA-Z\n//cd; # add
's after carriage returns $text =~ s/ //g; # to multline input, since HTML does not # preserve line breaks # push a single pasted in sequence into the array that drives the loop # to make the system calls push(@title, $title); push(@text, $text); } # end if ($query->param('fasta_file')) # add some debugging statements if ($debug ==1) {print "The first Fasta file is file: $title[0]

$text[0]

"; print "There are ".@title." sequences total to blast

";} ###### Set $when to be how results are shown - html or email $when = $query->param('when'); if ( $when =~ /html/ ) { $when = "html"; } elsif ( $when =~ /text/ ) { $when = "text"; } else { $when = "now"; } # add some debugging statements print "The value of when is $when

" if ($debug); # get some more variables from the webform $database = $query->param('database'); $filter = $query->param('filter'); $align = $query->param('align'); $output_type = $query->param('output_type'); $strands = $query->param('strands'); $mspmode = $query->param('mspmode'); $mspopt1 = $query->param('mspopt1'); $mspopt2 = $query->param('mspopt2'); $protword = $query->param('protword'); $dnaword = $query->param('dnaword'); $expect = $query->param('expect'); $expect = "-e ".$expect; $maxhits = $query->param('maxhits'); $maxhits = "-K ".$maxhits; $program = $query->param('program'); $program = lc($program); # add some debugging statements print "You chose to debug: $program $when " if ($debug); # print $query->dump(); ####Print to screen name of db selected and query sequence#### { # don't know where this bracket closes, but can't comment out: find!! print "

"; print "

"; # get stamp later $stamp=time(); # only set once if outside loop print "

Stamp was $stamp\n " if ( $debug ) ; if ($program =~ /blastx|tblastx/ ) { $when="html"; print "

Your request is computationally intensive and will be queued

"; } # only print this link (and make file) if not from a file # print the link to the tmp file only if using a paste in sequences (not a fasta file) # if a fasta file is used, a tmp file is not made. All the reports go into files if (!$fasta_file) { if ($write_permission) { # make a url link $source = "tmp_blast_results.html"; print "


The output of this blast report will be saved (with local links added) in the temporary file: $source

"; } # end if ($write_permission) } # if (!$fasta_file) { # print this should be an internal link later! if ($write_permission) { print "The file containing your search archive may be printed at the bottom of the blast report.

"; } print "


"; print "

Blast output with LOCAL SRS links\n"; ####Parse the database#### foreach $loop ( 0 .. $#Database_array){ if ($database eq $Database_array[$loop][0] ) { $searchdb = $Database_array[$loop][1]; $dbtype=$Database_array[$loop][2];last; } } # add some debugging statements print "

Database to be searched is $searchdb , of type $dbtype

" if ( $debug == 1 ); ####Find out if we have a program/database mismatch#### if (($program =~ /blastp|^blastx/ && $dbtype == 2) || ($program =~ /blastn|tblast/ && $dbtype == 1)) { print "

Whoops!!

Your program ($program) wants a "; print " DNA " if $program =~ /blastn|^tblast/ ; print " protein " if $program=~/blastp|blastx/; print "database, but you haven't selected a suitable one. You\n"; print "selected $database, which is of type"; print " DNA." if $dbtype == 2; print " protein." if $dbtype==1; print "

\nClick on the back button and try again.


"; exit; } ####Set $protword or $dnaword to be $word (wordlength)#### if ($dbtype=="2" && $program =~ /^blastn/){ $word=$dnaword;} else {$word=$protword;} ###Set $word to equal -W flag if ( $word == /9/) {$word = "-W 9" ;} elsif ( $word == /11/) {$word = "-W ll" ;} elsif ( $word == /13/) {$word = "-W 13" ;} elsif ( $word == /2/) {$word = "-W 2" ;} elsif ( $word == /3/) {$word = "-W 3" ;} elsif ( $word == /4/) {$word = "-W 4" ;} else {$word = "";} ####Parse DNA options. Add on -S flag to $strands#### if ($strands =~ /Top Strand/) {$strands = "-S 1";} if ($strands =~ /Bottom Strand/) {$strands = "-S 2";} if ($strands =~ /Both Strands/) {$strands = "";} ####Parse filter options. Add on -F flag to $filter#### if ($filter =~ /On/){$filter="";} elsif ($filter =~ /Off/){$filter="-F F";} else {$filter="";} ####Parse output options if ($output_type =~ /Ungapped/){$output_type ="-g F";} else {$output_type ="";} ####Parse align options. Add -m flag. if ($align =~ /0/){$align="";} elsif ($align =~ /1/){$align="-m 1";} elsif ($align =~ /2/){$align="-m 2";} elsif ($align =~ /3/){$align="-m 3";} elsif ($align =~ /4/){$align="-m 4";} elsif ($align =~ /5/){$align="-m 5";} elsif ($align =~ /6/){$align="-m 6";} else {$align = "";} ####Parse MSP options if ($mspmode =~ /Picture/){$mspmode="-P";} if ($mspmode =~ /Gapped/){$mspmode="-G";} if ($mspopt1 =~ /Reject/){$mspopt1="";} if ($mspopt1 =~ /Show/){$mspopt1="-w";} $mspopt2 = "-B 0.".$mspopt2." 5"; ####if ($mspopt2 =~ /No/){$mspopt2="";} #####Parse results location &flush(STDOUT); # look over the numbers from 0 to the number of items in the title array # advanced syntax to do this, but it works! foreach $loop ( 0 .. $#title){ # get the current title and text (the fasta header and sequence) $title = $title[$loop]; $text = $text[$loop]; # get a new time stamp for each tmp file $stamp=time(); # first search the $title (fasta header) for a MINE database entry # meaning, some work with the extension .db # this matches a very general pattern, it finds anything XXX.db # $title =~ /(File:)(\w)*(.db)/; # old and too restrictive # $title =~ /(\w*)(.db)/; $title =~ /File:(.+)(\.db)/; $title =~ /(\w*)(.SEQ)/; # if there is no .db word # take up the first 7 characters as a title. If there are spaces, replace # them with the character X so that unix doesn't complain about weird # characters in file names # test whether we found a file name to call the blast report if ($1 && $2) { # meaning, if word.db as $1 and $2 # e.g. file name is SBW0004.db $filename = $1.$2; } else { # when we couldn't find ".db" name in the fasta formatted sequence header use the first 6 characters instead... # start at 1 because 0 is the > from the fasta file header $filename = substr($title, 1, 6); if ($debug) {print "title is $title ----the filename is $filename after substr

";} my $tmp_filename = $filename; $tmp_filename =~ s/\s/X/; $filename = $tmp_filename; if ($debug) {print "the filename is $filename after replacement

";} } # end if database file: name was not found, and using first 6 characters instead # do I ever use ID? # leave here for now... $title =~ /(ID:)(.*)/; $getid = "$1$2"; $id = $getid; $id =~ s/ID://; # write a fasta formated file as a query sequence into the tmp directory open (SQFILE,">tmp/search$stamp") || die "can't open the file tmp/search$stamp"; print SQFILE ">$title\n"; print SQFILE $text; print SQFILE "\n"; close SQFILE; if ($debug) {print "The title and text $title

$text

were written to file tmp/search$stamp

";} # figure out later why $person is essential, otherwise commands below fail... $person = "dfield\@molbiol.ox.ac.uk"; #system ("blastall -p blastn -d SELF_blast_database -i QBR0099.db.fasta"); #print "
"; ####Submit system call that actually runs program #### # a blast search, html output in the inter queue (blastn) $cmd1 = "/usr/local/lsf/bin/bsub -q inter -I -u $person \"blastall -p $program -d $searchdb -i tmp/search$stamp -o tmp/dbmail$stamp -a 7 $filter -T $expect $align $maxhits $strands $word $output_type\" "; ###REPLACED WITH A NON BATCH QUEUE COMMAND $cmd1 = "blastall -p $program -d $searchdb -i tmp/search$stamp -o tmp/dbmail$stamp -a 7 $filter -T $expect $align $maxhits $strands $word $output_type"; print "COMMAND 1 = $cmd1

" if( $debug == 1 ) ; # a blast search, html output in the infinite queue (e.g. tblastx) $cmd2 = "/usr/local/lsf/bin/bsub -q infinite -u $person -J blastall \"blastall -p $program -d $searchdb -i tmp/search$stamp -a 7 $filter $expect $maxhits $strands -T $word $output_type > tmp/dbmail$stamp\" "; ###REPLACED WITH A NON BATCH QUEUE COMMAND $cmd2 = "blastall -p $program -d $searchdb -i tmp/search$stamp -a 7 $filter $expect $maxhits $strands -T $word $output_type > tmp/dbmail$stamp"; print "COMMAND 2 = $cmd2

" if( $debug == 1 ) ; # take out! do MSP crunch (only on the web version, not in the hard copies) after blast $cmd3 = "/usr/mbin/MSPcrunch $mspmode $mspopt1 $mspopt2 tmp/dbmail$stamp > tmp/msp$stamp\n"; # finish up cleanly from the infinite queue $cmd4 = "/usr/local/lsf/bin/bsub -q inter -I -u $person -w \"ended(blastall)\" /usr/bin/sleep"; ###REPLACED WITH A NON BATCH QUEUE COMMAND ###?? print "COMMAND 4 = $cmd4

" if( $debug == 1 ) ; # decide which blast command to send based on which blastall program has been selected # ($cmd1 and $cmd2 commands differ only in which work queue they go into) if ( $when eq "now" ) { print "$cmd1" if( $debug == 1 ) ; system ($cmd1); $out = *STDOUT; # use the program tee to write standard out to as many files as you like.... # write to screen and to the file tmp_blast_results.html # must be opened here, is not opened below, is not causing to outputs to screen # append to it, don't erase (is erased above the first time the SUBMIT! button is hit # use the -a flag to append instead of overwriting the temp file open ( OUT , "| /usr/bin/tee -a tmp_blast_results.html"); $out = *OUT; } else { print "Search now submitted to the queue infinite it may take a while, but"; print ", it will eventually appear on this page\n" ; print "$cmd2" if( $debug == 1 ) ; print "

"; &flush(STDOUT); system ($cmd2); ### system ($cmd4); ####### this is where the output file is opened for e-mailing the search results... # use the program tee to write standard out to as many files as you like.... # tmp_blast_results.html comes into life here... open ( OUT , "| /usr/bin/tee tmp_blast_results.html"); $out = *OUT; # tee is a program that copies standard out # the *OUT filehandle is just because there are multiple files that the handle writes on. } ######## can't open the tmp/file here if ($write_permission && $fasta_file) { # open the temporary blast report in the /tmp directory and rewrite it in a nicer way # and save it to the proper place with a proper name # the tmp/dbmail$stamp file has no links in it # the tmp_blast_results.html file does not exist at this point.... open (MYBLAST, "tmp/dbmail$stamp") || die "can't open tmp/dbmail$stamp"; open (MYBLAST1, ">$filename$tag.blast.html")|| die "can't open $filename_$tag.blast.html for writing"; # print a nice html header to the page print MYBLAST1 $query->start_html; # could add the database header if wanted # &footer(); # easiest piece of code to copy contents of tmp file into the new file while () { print MYBLAST1;} # finish it off by ending the web page with print MYBLAST1 $query->end_html; # tidy up by closing files close (MYBLAST); close (MYBLAST1); # add remote links to the blast report: includes links to SBW* files, embl and swissprot # it open the file, then rewrites the contents with the appropriate links &add_html_links("$filename$tag.blast.html"); # show the user what the link is to the new file print "


The output of this blast report is saved (with remote links added) in the file: "; undef @file_list; @file_list = "$filename$tag.blast.html"; get_log_array(@file_list); # push all the file names onto an array to fetch links to at the end of the program run push (@total_file_list, "$filename$tag.blast.html"); print "

"; } ### Results #### ###Open the output file. Parse in local database links.#### open (BLASTFILE,"tmp/dbmail$stamp"); undef $new_file; undef $new_line; # go through the file line by line while ($line = ) { # grab a line from the file and look to change links # copy $line to a new variable ($new_line) as needed for using the s/// operator $new_line = $line; # add links to the local file in the database # this database currently uses the following patterns by convention for local entries # 1) XXX.db # add the database links to the file # this matches a very general pattern, it finds anything XXX.db # BUT will match some things you don't want if you use blastall with the option # to output blast reports in html! # $new_line =~ s/(\s)(\w*)(.db)/$2$3<\/a>/g; # Add links to the MINE database entries - use prefix as apattern anchor foreach $link_ext (@link_extensions) { $new_line =~ s/(($link_ext)([0-9]*)(.db))/$1<\/a>/g; } # $new_line =~ s/((SBW)([0-9]*)(.db))/$1<\/a>/g; # $new_line =~ s/((QBR)([0-9]*)(.db))/$1<\/a>/g; # $new_line =~ s/((StrepB)([0-9]*)(.db))/$1<\/a>/g; # concatenate the lines as they are changed to a new version of the file # in the variable $new_file $new_file .= $new_line; } # end while BLASTFILE close (IN); # reopen IN (using > for read and write, erases the file) to overwrite its contents this time! open (IN, ">tmp/dbmail$stamp"); print IN $new_file; # close files to keep everything tidy close (IN); #################everything below this is OUBC##################### ###Open the output file. Parse in SRS links.#### # this file already has the SBW database links in it from the above code # this is where it gets printed to screen? # if a fasta file has been submitted (potentially with lots of sequences) # DON'T print the blast results to screen or the file become huge # it will still exist behind the tmp file... if (!$fasta_file) { open (BLASTFILE,") { chomp; $prevline=$inline; $inline=$_; if ($inline=~/Sequences producing /) { $heading=1; print $out "

" if $database =~ /Swissprot|PIR| Genpept/; } if ($heading eq 1 && $prevline !~ /Sequences producing/ && $inline eq ""){ $heading=0; print $out "\n"; print $out "" } foreach $x ( 0 .. $#Database_trans ){ if ($inline =~ /($Database_trans[$x][0])(\w+)(\s+.+)/) { $db=$1; $id=$2; $rest=$3; if ( $rest =~ /\w+[e|.|-]\d+$/) { print $out "$db
"; print $out "$id$rest "; print $out "Alignment "; print $out "Select

"; $V_line=1; } else { print $out ""; print $out "$db$id $rest

"; $V_line=1; } } } print $out $inline,"\n","

" if ($V_line==0); $V_line=0; } } # end print to screen close BLASTFILE; # remove all the files written to the tmp/ directory after each search unlink ("tmp/search*"); unlink ("tmp/dbmail*"); print $out ""; } # Close the document cleanly. close $out; ############################## ### do the final bits, like print ### a full list of blast archive files, ### or e-mail results ### (if these functions are enabled) ############################### ###### SHOW user full list of blast archive files made ##### if ($write_permission && $fasta_file) { # show the user all links to blast archive files print "


All blast reports (with remote links added) are saved as: "; get_log_array(@total_file_list); print "

"; } ####### OPTIONAL CODE: EMAIL the results to users ##### # uncomment the below system call to your mailer and pipe through user's # e-mail address to send the results by e-mail if ( $when ne "now" ){ # e-mail the file tmp_blast_results.html # write the code to get the user's e-mail...this is sample working code. # $person = "dfield\@molbiol.ox.ac.uk"; # system ("/usr/bin/mailx -s \"Your search results $title\" < tmp_blast_results.html $person"); } # end if want to send e-mail } # end foreach $loop ( 0 .. $#title){ }