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

S Clark biophp-dev@bioinformatics.org
Sun, 16 Nov 2003 00:52:07 -0700


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

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

I suspect that you may have missed one of the implied "extra" things
that would need to be set to use the incomplete example I posted before.

I did not get time today to add "nicer" interface methods for the
options, but I DID just get a chance to sit down and write a 'working'
example, with copious comments to hopefully explain what it is doing.
The example does work on my system here, so I know that it SHOULD work
on your own system (but I have not been able to test on Windows).

I did spot one problem in my own frontend_blast.php class that I somehow
didn't notice when I used it before, which is that if you tried to
use 'blastn' as the program, it wouldn't work (for some reason I=20
believed that blast "defaulted" to using blastn if you didn't
specify a program, but it appears I was wrong...)  That problem
is fixed now.

Attached is the fixed frontend_blast.php plus the example
script (frontend_blast_example.php).

Obviously the example paths in this tutorial/example are for my
own system, so you'll need to change them to match your own system's
settings, and change the database names to match the ones you
have installed (I think that is what you are intending to choose
in your own form when you are selecting 'organism' - the 'values' of
the options should be the literal 'base' names of the databases but
the 'description' between the option tags can be whatever you want.)

The only 'obvious' problem that I see that you might have is
the 'default' temporary directory is set to "/tmp", unix-style.
The PHP manual seems to imply that the function I am using to
create a temporary file SHOULD revert to the 'default' system
temporary directory (C:\WINDOWS\TEMP on windows, I think)
automatically if the specified directory doesn't exist, but
maybe it doesn't.  If you still can't make this work, try=20
editing the=20
var $tempDir=3D"/tmp";
line in frontend_blast.php to say
var $tempDir=3D"C:\WINDOWS\TEMP";
instead, and let me know if that fixes it - if so I'll add=20
some code later on to more 'automatically' choose a temporary
directory.

One final thing - I don't recall what version of PHP they started
using the $_POST array for posted form data.  If you are using an
older version of PHP, you may need to change the example to say
$HTTP_POST_VARS wherever it says $_POST.

Good luck!

Sean


On Saturday 15 November 2003 09:34 pm, you wrote:
> dear clark !
> i followed your instructions and i have no more error messages but i still
> have not results i mean there is no html output, i precise that i done yo=
ur
> instructions and did not forget nothing ! what do you think the problem is
> ?? thank you very much i appreciate your help !
> ANIBA
=2D----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQE/tyysJ6yQLhNTzSkRAhvXAKDPUmgP5V61VjcRBoe9GPnnwSXxMwCgiPr8
kR9d5YX6/1dbAoxX3e8SSak=3D
=3DtVPd
=2D----END PGP SIGNATURE-----

--Boundary-00=_nyyt/QdEntNzPnI
Content-Type: application/x-php;
  name="frontend_blast.php"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="frontend_blast.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
{
    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($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!="") {
   
                $this->dataDir=$datadir;
            
        }
        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"
        if ($blastpath!="") {
            if (file_exists($blastpath)) {
                $this->blastExecPath=$blastpath;
            } else {
                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);
            }
            if (isset($this->blastExecParams[$param])) {
            //only allow 'legal' parameters         
                $this->blastExecParams[$param]=$value;
                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)
        
        //create temp files to hold query for blast and text of results
        $queryfname=tempnam($this->tempDir,"BQ");
        $resultfname=tempnam($this->tempDir,"BR");
        
        $qhandle=fopen($queryfname,"w");
        fwrite($qhandle,$this->blastSequence."\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);
        $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=_nyyt/QdEntNzPnI
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</title>
</head>
<body>
<?php
if (isset($_POST['sequence'])) {
//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.php');
//now we create an instance of the frontend
$blaster = new Frontend_Blast($blast_path);

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

//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=_nyyt/QdEntNzPnI--