[Biophp-dev] Re: Working (at least on my system) example tutorial for frontend_blast.php

S Clark biophp-dev@bioinformatics.org
Sat, 22 Nov 2003 21:16:26 -0700


--Boundary-00=_aSDw/DREIqyEjJa
Content-Type: Text/Plain;
  charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

=2D----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hmmm.

Here is another debug version with some more details about the temporary
files enabled.  Also, it will no longer attempt to delete the temporary
files automatically in case of an error, so if/when you try running the=20
command line that it gives you, the input file should still be there.

The output file SHOULD then contain the HTML text of the results, if it wor=
ks.
If not, you should at least be able to see the temporary files to make sure
there is data in them.

Oh, one other thing - when you run the command line from the prompt, you
should do it from the data directory (C:\BLAST in your case, it looks like.=
) -
I don't think I mentioned that before.

On Saturday 22 November 2003 07:00 pm, you wrote:
> hi clark !
> everything seems to be okey here is the debug result :
[...]
> Acc=E9dez au courrier =E9lectronique de La Poste : www.laposte.net ;
> 3615 LAPOSTENET (0,34=80/mn) ; t=E9l : 08 92 68 13 50 (0,34=80/mn)
=2D----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQE/wDSfJ6yQLhNTzSkRAnczAJsHMU67f6HFri31QfUXLIsygk1NGACeJK6o
MVWg28HwuDZRisLLkEEoRmw=3D
=3DoHk0
=2D----END PGP SIGNATURE-----

--Boundary-00=_aSDw/DREIqyEjJa
Content-Type: application/x-php;
  name="frontend_blast_debug.php"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="frontend_blast_debug.php"

<?php
/*
Frontend for 'local' BLAST program(s)
Copyright 2003 by Sean Clark
Consider this released (by default) under the terms of the GPL 2.0
*/

class Frontend_Blast_Debug
{
    var $FRONTEND_BLAST_EXEC_DEFAULTS = Array('-p'=>'','-d'=>'nr',
    '-i'=>'STDIN','-e'=>'10.0','-m'=>'0','-o'=>'STDOUT','-F'=>'T','-G'=>'0','-E'=>'0','-X'=>'0',
    '-I'=>'F','-q'=>'-3','-r'=>'1','-v'=>'500','-b'=>'250','-f'=>'0','-g'=>'T','-Q'=>'1',
    '-D'=>'1','-a'=>'1','-J'=>'F','-M'=>'BLOSUM62','-W'=>'0','-z'=>'0','-K'=>'0','-P'=>'0',
    '-Y'=>'0','-S'=>'3','-T'=>'F','-U'=>'F','-y'=>'0.0','-Z'=>'0.0','-n'=>'F','-A'=>'0',
    '-w'=>'0','-t'=>'0','-B'=>'0');//default values in the BLAST executable for non-optional flags

    var $blastExecDefaults = Array('-p'=>'blastn','-d'=>'nr',
    '-i'=>'./blast-query.txt','-e'=>'10.0','-m'=>'7','-o'=>'./blast-results.xml','-F'=>'T','-G'=>'0','-E'=>'0','-X'=>'0',
    '-I'=>'F','-q'=>'-3','-r'=>'1','-v'=>'25','-b'=>'25','-f'=>'0','-g'=>'T','-Q'=>'1',
    '-D'=>'1','-a'=>'1','-J'=>'F','-M'=>'BLOSUM62','-W'=>'0','-z'=>'0','-K'=>'0','-P'=>'0',
    '-Y'=>'0','-S'=>'3','-T'=>'F','-U'=>'F','-y'=>'0.0','-Z'=>'0.0','-n'=>'F','-A'=>'0',
    '-w'=>'0','-t'=>'0','-B'=>'0'); //default values used by this module

    var $blastExecParams=Array(); //currently-used parameters for blastall executable

    var $blastExecPath; //path to local blastall executable

    var $blastSequence; //string containing sequence to BLAST
    
    var $dataDir; //location of BLAST database(s) to be used

    var $results=""; //text of BLAST results
    
    var $errorstr=""; //if blast doesn't execute, error line goes here
    
    var $tempDir="/tmp";
    
//########Class Constructor################
    function Frontend_Blast_Debug($blastpath="")
    {//may be passed a path to the blast executable on instantiation
    //or set later with blastExecPath() method
        if ($blastpath!="") {
            $this->blastExecPath($blastpath);
            $this->blastExecParams=$this->blastExecDefaults; //set default parameters
            }
    }
    
//########Interface methods################
    function blastDataDir($datadir="")
    {//if passed a directory containing BLAST db files, sets it.
    //returns false if passed a dir that doesn't contain db files
    //if no errors, returns current data dir
        if ($datadir!="") {
               ini_set("track_errors","1");
                $this->dataDir=$datadir;
                if (is_dir($datadir)) {
                    print("Found the directory $datadir.<br />\n");
                    print("This directory contains:<br />\n");
                    if ($dirhandle=opendir($datadir)) {
                        while ($name=readdir($dirhandle)) {
                            print("$name<br />\n");
                        }
                    closedir($dirhandle);
                    } else {
                        print("(Couldn't opendir() on $datadir!)<br />\n");
                        print("$php_errormsg <br />\n");
                    }
                    
                } else {
                    print("The data directory \"$datadir\" does not appear to exist!<br />\n");
                }
            
        }
        return $this->dataDir;
    }
    
    function blastExecPath($blastpath="")
    {//if a full path to blastall executable is passed, set it
    //if a path is passed and the file doesn't exist, return false, otherwise
    //return current blastExecPath
    //example: "/usr/local/bin/blastall" or "C:\Blast\BLASTALL.EXE"
        print("blastExecPath called with $blastpath.<br />\n");
        if ($blastpath!="") {
            if (file_exists($blastpath)) {
                $this->blastExecPath=$blastpath;
                print("Found the file in $blastpath successfully.<br />\n");
            } else {
                print("<b>Could not find the specified BLAST executable!</b><br />\n");
                print("$blastpath doesn't seem to exist.  In that path, there exists:<br />\n");
                $dir=dirname($blastpath);
                if ($dirhandle=opendir($dir)) {
                    while ($name=readdir($dirhandle)) {
                        print("$name<br />\n");
                    }
                    closedir($dirhandle);
                } else {
                    print("We couldn't even look in a directory named $dir!<br />\n");
                }
                return false; //could not set path
            }
        }
        return $this->blastExecPath;
    }    

    function blastParam($param="",$value="")
    {//if nothing is passed, return the entire array of currently-set
    //parameters.
    //if a parameter name is passed without a value, return that parameter's current value
    //if both parameter and value are passed, set the parameter to that value, then return that value.
    //return 'false' if passed a non-existent parameter name
    //These are the same as the command-line parameters, so to set the e-value to 1.0, for example, 
    //blastParam("-e","1.0");
    //TODO - add validation of value for parameters passed and return false if invalid
        if ($param=="") {
            return $this->blastExecParams;
        } else if ($value=="") {
            if (isset($this->blastExecParams[$param])) {
                return $this->blastExecParams[$param];
            } else {
                return false;
            }
        } else {
            if ($param=="-d") { //special handler for database file name
                $this->setDB($value);
            } else if (isset($this->blastExecParams[$param])) {
            //only allow 'legal' parameters         
                $this->blastExecParams[$param]=$value;
                print("Setting $param value to $value<br />\n");
                return $this->blastExecParams[$param];
            } else {
                return false;
            }
        }
    }
    
    function blastSequence($sequence="")
    {//if passed a sequence to BLAST, makes a note of it.
    //either way, returns the currently-set sequence-to-blast
        if ($sequence!="") {
            $this->blastSequence=$sequence;
        }
        return $this->blastSequence;
    }
    
    function error()
    {
        return $this->errorstr;
    }
    
    function results()
    {
        return $this->results;
    }
    
    function setDB($dbname)
    {
        $this->blastExecParams['-d']=$dbname;
    }
//############other stuff###############    
    function doBlast() 
    {//attempts to run the BLAST query
        $returnval=0; //return value of the blast execution - checks for runtime errors
        $execparmstr=""; //will hold 'not blast executable default' parameters
        $lastline="";//last line of BLAST command output (not results)
        ini_set("track_errors","1");
        //create temp files to hold query for blast and text of results
        $queryfname=tempnam($this->tempDir,"BQ");
        $resultfname=tempnam($this->tempDir,"BR");
        print("The query sequence will be stored temporarily in:<br />\n");
        print("<b>$queryfname</b><br/>\n");
        print("The resulting output will be stored temporarily in:<br />\n");
        print("<b>$resultfname</b>\n");
        if ($qhandle=fopen($queryfname,"w")) {
        print("Opened $queryfname to save the sequence to it.<br />\n");
        if ($bytes=fwrite($qhandle,$this->blastSequence."\n")) {
            print("Successfully wrote $bytes characters of data to $queryfname.<br />\n");
        } else {
            print("Problem writing the file $queryfname at handle $qhandle!<br />\n");
            print("<b>$php_errormsg</b><br />\n");
        }
        fclose($qhandle);
        }
        $this->blastParam("-i",$queryfname);
        $this->blastParam("-o",$resultfname);
        
        foreach (array_keys($this->blastExecParams) as $param) {
            if ($this->blastExecParams[$param] != $this->FRONTEND_BLAST_EXEC_DEFAULTS[$param]) {
                $execparmstr.=" $param ".escapeshellarg($this->blastExecParams[$param]);
            }
        }
        
        //now actually attempt to execute
        $cwd=getcwd();
        chdir($this->dataDir);
        print("Preparing to attempt to run ".$this->blastExecPath.$execparmstr." <br />\n");
        print("(If it doesn't work, try running this <b>exact</b> command from a console prompt to see what, if any, the error is.)<br />\n");
        $lastline=system($this->blastExecPath.$execparmstr,$returnval);
        if (filesize($resultfname) > 0) {//shell programs should return 0 on proper execution
            $this->results=file_get_contents($resultfname);
            chdir($cwd);
            
            return true;
        } else {
            $this->errorstr=$lastline;
            //unlink($queryfname);
            //unlink($resultfname);
            chdir($cwd);
            return false;
        }
        
    }
}
?>

--Boundary-00=_aSDw/DREIqyEjJa
Content-Type: application/x-php;
  name="frontend_blast_example.php"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="frontend_blast_example.php"

<html>
<head>
<!-- A simple example of using Sean Clark's frontend_blast class
to handle BLAST queries running on a local system.

I (Sean Clark) wrote this silly little example.  Consider
this example to be released to run free in the public domain, 
though I would appreciate some sort of credit and/or acknowledgement
if this is useful to anyone. -->

<title>Example Local Blast Frontend Page - with 'debug' output</title>
</head>
<body>
<?php
if (isset($_POST['sequence'])) {
//DEBUG STUFF
print("The following information was passed by the form:<br />\n");
print("Sequence: ".$_POST['sequence']." <br />\n");
print("Database name: ".$_POST['database']."<br />\n");
print("Program: ".$_POST['program']."<br />\n");
print("Maximum \"e-value\": ".$_POST['evalue']."<br />\n");
//if there's a sequence, show BLAST result output
//First, we set some defaults here
//make sure you set the correct path and filename for your system here
$blast_path="/usr/local/bin/ncbi/blastall";
//$blast_path="C:\BLAST\BLASTALL.EXE"; 
//set the correct path for your blast database files below
$blast_database_directory="/usr/local/lib/blastdata";
//$blast_database_directory="C:\BLAST";

//load in the frontend - here we assume frontend_blast.php is in the same
//directory as this page, or is in the default PHP search path
include('frontend_blast_debug.php');
//now we create an instance of the frontend
$blaster = new Frontend_Blast_Debug($blast_path);

//tell the frontend where to find the database files
$blaster->blastDataDir($blast_database_directory);

//$blaster->blastExecPath($blast_path);
//set the sequence to be checked to whatever was sent
$blaster->blastSequence($_POST['sequence']);

//now the other parameters - note that Real Soon Now there will
//be 'prettier', more intuitive interface methods for setting these, 
//e.g. an "evalue()" method for setting the e-value parameter, but
//I haven't had time to sit down and do this yet, so for now we have
//to use the 'bare' parameter-setting method

//set the 'e-value' passed from the form
$blaster->blastParam("-e",$_POST['evalue']);

//set the database name from the form
$blaster->blastParam("-d",$_POST['database']);


//set the program type from the form
$blaster->blastParam("-p",$_POST['program']);

//these are the only options on this form, so we stop here...
//...except the DEFAULT frontend_blast is set to use XML mode output,
//in case you want to also use the blast results parser.  For this 
//example, we just want the web-page to display the exact output
//from the blast program and we don't care about otherwise parsing
//or analyzing the data, so we need to set the output mode back to
//HTML text instead:
$blaster->blastParam("-m","0"); //pairwise alignment view
$blaster->blastParam("-T","T"); //HTML output TRUE

//Everything should now be set.  If the correct path to BLAST
//has been set, and the correct path to the database files, and
//the correct database file names have been chosen, this should work...

//first, we extend the allowed run time of the script, since BLAST
//can sometimes take a while to run on a large database.  Here
//we will give the script a full minute to finish.  If you find that
//it takes more than a minute to run BLAST, you will obviously need
//to increase this number.
set_time_limit(60); //60 seconds

print("(Now attempting to run ".$_POST['program']." query on the ".$_POST['database']." database.)<br />\n");
//GO!
if ($blaster->doBlast()) {
    print("Got results!  The results are:<br />\n");
    print($blaster->results());
} else {
//Some kind of problem running the BLAST query.
    print("<b>Like, Dude!  Something went wrong!</b><br />\n");
    print("If there is a line of output from the attempt, you'll see it here:<br />\n".$blaster->error()."<br />\n");
}
}

?>
<h1>Example BLAST Frontend Page</h1>
<!-- Obviously this form has a bare minimum of options - there are plenty more that you
could include, such as number of alignments and/or descriptions, and so on, but this
should give you a good start -->

<form name="blast_form" id="blast_form" method="post" action="frontend_blast_example.php">
<b>Paste sequence to be BLASTED below:<br />
</b>
<textarea name="sequence" id="sequence" cols="72" rows="4" wrap="virtual">
</textarea>
Highest "E-value" allowed:<input type="text" name="evalue" id="evalue" size="5" maxlength="7" value="10.0" /><br />
<!-- Obviously, edit the database names/selections to match your own data -->
<!-- this example uses the amino acid and nuceotide patent databases available from NCBI -->
BLAST against which database?:<br />
<select name="database" id="database">
  <option value="pataa" selected>pataa - amino acid/protein patent database</option>
  <option value="patnt">patnt - nucleotide patent database</option>
</select><br />
Use which comparison matrix?:<br />
<select name="matrix" id="matrix">
  <option value="BLOSUM62">BLOSUM62</option>
  <option value="PAM30">PAM30</option>
</select><br />
Use which BLAST program?:<br />
<select name="program" id="program">
  <option value="blastp" selected>BLASTP - peptide/protein BLAST</option>
  <option value="blastn">BLASTN - nucleotide BLAST</option>
  <option value="tblastn">TBLASTN - BLAST a protein sequence against a nucleotide database</option>
  <option value="blastx">BLASTX - BLAST a nucleotide sequence against a protein database</option>
</select>
<input type="submit" value="Run BLAST" />
</form>
</body>
</html>

--Boundary-00=_aSDw/DREIqyEjJa--