in reply to parsing blast output

First I would suggest simplifying the code. You have a bunch of "if" statements that are essentially "and" conditions. Your code will work, but this introduces more levels of {} which is not good.
if( $hsp->length('total') > 1000 ) { if ( $hsp->percent_identity >= 90 ) { if( $hsp->score ){ if( $hsp->gaps ){ if( $hsp->expect ){ print "Hit= ", $hit->name, " Length=", $hsp->length('total'), " Score=", $hsp->score,"\n"; print "Gaps=", $hsp->gaps, " Expect=", $hsp->expect, " Percent_id=", $hsp->percent_identity, "\n"; my $aln = $hsp->get_aln; my $alnIO = Bio::AlignIO->new(-format =>"clustalw", -file +=> $out); $alnIO->write_aln($aln); } } } } } ## better is to reduce the levels of "if" by using "and" or && if ( ($hsp->length('total') > 1000 ) && ($hsp->percent_identity >= 90 ) && ($hsp->score ) && ($hsp->gaps) && ($hsp->expect) ) { #do your print stuff }
In my opinion when I see eight consecutive "}"'s in a row, I figure that something is wrong with the code - too many levels of indentation!

I was looking at your while loop and it is hard for me to say exactly how to make that better as there can be a lot of cases here and I am unable to run your current code without installing some modules.

Can you simplify your question?

Replies are listed 'Best First'.
Re^2: parsing blast output
by lomSpace (Scribe) on May 04, 2009 at 17:16 UTC
    #!/usr/bin/perl use warnings; use strict; use Bio::SearchIO; use Bio::AlignIO; my $out = ">C:/Documents and Settings/mgavi.brathwaite/Desktop/current +/bl2seq/13117_aln1.out"; my $dir = 'C:/Documents and Settings/mgavi.brathwaite/Desktop/current/ +bl2seq/'; my $in = new Bio::SearchIO(-format => 'blast', -file => $dir.'13117_2.out', -report_type => 'bl2seq'); while( my $result = $in->next_result ) { while( my $hit = $result->next_hit ) { while( my $hsp = $hit->next_hsp ) { if( $hsp->length('total') > 1000 ) { if ( $hsp->percent_identity >= 90 ) { if( $hsp->score ){ if( $hsp->gaps ){ if( $hsp->expect ){ print "Hit= ", $hit->name, " Length=", $hsp->length('total'), " Score=", $hsp->score,"\n"; print " Gaps=", $hsp->gaps, " Expect=", $hsp->expect, " Percent_id=", $hsp->percent_identity, "\n"; =cut # $hit->name, $hit->hsps, $hit->name, $hsp->length('total'), $hsp->score, $hsp->gaps, $hsp->expect, $hsp->percent_identity; =cut my $aln = $hsp->get_aln; my $alnIO = Bio::AlignIO->new(-format =>"clustalw" +, -file => $out); $alnIO->write_aln($aln); } } } } } } } }
    I can get the alignment, but I also need the print data
    to be prepended at the top of the $out file.
      So, if I understand the question, you've got what you want except that instead of print going to screen, you want that print to go to the file that the Bio module is writing to?

      First one thing that might be helpful here is to do a $|=1; at the top of the program, this turns Autoflush on. This slows the output down a bit, but until you get this working, this might be a good idea to do.

      I'm not familiar with the module that you are using, but one suggestion is to see if you can give this Bio thing a filehandle instead of a text filepath. If that's true, then you open the output file, use the handle for your printing and give the handle to Bio for its printing. This is the easiest thing if this module allows it.(eg. open say $outhandle to the $out filepath (open ($outhandle, ">", "path) or die .....) In Perl you can use a scalar as a filehandle instead of a bareword like OUT)..

      Anyway before speculating about more complex scenarios, try the simple approach first.