2 # BioPerl module for Bio::Search::Result::BlastResult
4 # Please direct questions and support issues to <bioperl-l@bioperl.org>
6 # Cared for by Steve Chervitz <sac@bioperl.org>
8 # Copyright Steve Chervitz
10 # You may distribute this module under the same terms as perl itself
12 # POD documentation - main docs before the code
16 Bio::Search::Result::BlastResult - Blast-specific subclass of Bio::Search::Result::GenericResult
20 # Working with iterations (PSI-BLAST results)
22 $result->next_iteration();
23 $result->num_iterations();
25 $result->iterations();
27 # See Bio::Search::Result::GenericResult for information about working with Results.
29 # See L<Bio::Search::Iteration::IterationI|Bio::Search::Iteration::IterationI>
30 # for details about working with iterations.
33 # * Show how to configure a SearchIO stream so that it generates
34 # BlastResult objects.
39 This object is a subclass of Bio::Search::Result::GenericResult
40 and provides some operations that facilitate working with BLAST
41 and PSI-BLAST results.
43 For general information about working with Results, see
44 Bio::Search::Result::GenericResult.
50 User feedback is an integral part of the evolution of this and other
51 Bioperl modules. Send your comments and suggestions preferably to
52 the Bioperl mailing list. Your participation is much appreciated.
54 bioperl-l@bioperl.org - General discussion
55 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
59 Please direct usage questions or support issues to the mailing list:
61 I<bioperl-l@bioperl.org>
63 rather than to the module maintainer directly. Many experienced and
64 reponsive experts will be able look at the problem and quickly
65 address it. Please include a thorough description of the problem
66 with code and data examples if at all possible.
70 Report bugs to the Bioperl bug tracking system to help us keep track
71 of the bugs and their resolution. Bug reports can be submitted via the
74 https://github.com/bioperl/bioperl-live/issues
76 =head1 AUTHOR - Steve Chervitz
82 The rest of the documentation details each of the object methods.
83 Internal methods are usually preceded with a _
88 # Let the code begin...
91 package Bio
::Search
::Result
::BlastResult
;
94 use Bio
::Search
::BlastStatistics
;
96 use base
qw(Bio::Search::Result::GenericResult);
101 Usage : my $obj = Bio::Search::Result::BlastResult->new();
102 Function: Builds a new Bio::Search::Result::BlastResult object
103 Returns : Bio::Search::Result::BlastResult
104 Args : See Bio::Search::Result::GenericResult();
105 The following parameters are specific to BlastResult:
106 -iterations => array ref of Bio::Search::Iteration::IterationI objects
107 -inclusion_threshold => e-value threshold for inclusion in the
108 PSI-BLAST score matrix model (blastpgp)
113 my($class,@args) = @_;
115 my $self = $class->SUPER::new
(@args);
117 $self->{'_iterations'} = [];
118 $self->{'_iteration_index'} = 0;
119 $self->{'_iteration_count'} = 0;
121 my( $iters, $ithresh ) = $self->_rearrange([qw(ITERATIONS
122 INCLUSION_THRESHOLD)],@args);
124 $self->{'_inclusion_threshold'} = $ithresh; # This is a read-only variable
126 if( defined $iters ) {
127 $self->throw("Must define arrayref of Iterations when initializing a $class\n") unless ref($iters) =~ /array/i;
129 foreach my $i ( @
{$iters} ) {
130 $self->add_iteration($i);
134 # This shouldn't get called with the new SearchIO::blast.
135 print STDERR
"BlastResult::new(): Not adding iterations.\n";
136 $self->{'_no_iterations'} = 1;
146 Usage : my @hits = $result->hits
147 Function: Returns the available hits for this Result
148 Returns : Array of L<Bio::Search::Hit::HitI> objects
150 Note : This method overrides L<Bio::Search::Result::GenericResult::hits> to
151 take into account the possibility of multiple iterations, as occurs
152 in PSI-BLAST reports.
153 If there are multiple iterations, all 'new' hits for all iterations
154 are returned. These are the hits that did not occur in a previous
157 See Also: L<Bio::Search::Result::GenericResult::hits>
163 if ($self->{'_no_iterations'}) {
164 return $self->SUPER::hits
;
167 foreach my $it ($self->iterations) {
168 push @hits, $it->hits;
176 Usage : while( $hit = $result->next_hit()) { ... }
177 Function: Returns the next available Hit object, representing potential
178 matches between the query and various entities from the database.
179 Returns : a Bio::Search::Hit::HitI object or undef if there are no more.
181 Note : This method overrides L<Bio::Search::Result::GenericResult::next_hit>
182 to take into account the possibility of multiple iterations, as
183 occurs in PSI-BLAST reports.
185 If there are multiple iterations, calling next_hit() traverses the
186 all of the hits, old and new, for each iteration, calling next_hit()
189 See Also: L<Bio::Search::Iteration::GenericIteration::next_hit>
194 my ($self,@args) = @_;
195 if ($self->{'_no_iterations'}) {
196 return $self->SUPER::next_hit
(@args);
200 if (not defined $self->{'_last_hit'}) {
201 $iter_index = $self->{'_iter_index'} = $self->_next_iteration_index;
203 $iter_index = $self->{'_iter_index'};
206 return if $iter_index >= scalar @
{$self->{'_iterations'}};
208 my $it = $self->{'_iterations'}->[$iter_index];
209 my $hit = $self->{'_last_hit'} = $it->next_hit;
211 return defined($hit) ?
$hit : $self->next_hit;
218 Usage : my $hitcount= $result->num_hits
219 Function: returns the number of hits for this query result
222 Note : This method overrides L<Bio::Search::Result::GenericResult::num_hits>
223 to take into account the possibility of multiple iterations, as
224 occurs in PSI-BLAST reports.
226 If there are multiple iterations, calling num_hits() returns the
227 number of 'new' hits for each iteration. These are the hits that did
228 not occur in a previous iteration.
230 See Also: L<Bio::Search::Result::GenericResult::num_hits>
236 if ($self->{'_no_iterations'}) {
237 return $self->SUPER::num_hits
;
239 if (not defined $self->{'_iterations'}) {
240 $self->throw("Can't get Hits: data not collected.");
242 return scalar( $self->hits );
248 Usage : $report->add_hit($hit)
249 Function: Adds a HitI to the stored list of hits
250 Returns : Number of HitI currently stored
251 Args : Bio::Search::Hit::HitI
256 my ($self,$hit) = @_;
257 my $iter = $self->iteration;
258 if( $hit->isa('Bio::Search::Hit::HitI') ) {
259 return $iter->add_hit(-hit
=> $hit);
261 $self->throw("Passed in a " .ref($hit).
262 " as a Iteration which is not a Bio::Search::Hit::HitI.");
264 return $iter->num_hits;
269 Title : add_iteration
270 Usage : $report->add_iteration($iteration)
271 Function: Adds a IterationI to the stored list of iterations
272 Returns : Number of IterationI currently stored
273 Args : Bio::Search::Iteration::IterationI
279 if( $i->isa('Bio::Search::Iteration::IterationI') ) {
280 push @
{$self->{'_iterations'}}, $i;
281 $self->{'_iteration_count'}++;
283 $self->throw("Passed in a " .ref($i).
284 " as a Iteration which is not a Bio::Search::Iteration::IterationI.");
286 return scalar @
{$self->{'_iterations'}};
290 =head2 next_iteration
292 Title : next_iteration
293 Usage : while( $it = $result->next_iteration()) { ... }
294 Function: Returns the next Iteration object, representing all hits
295 found within a given PSI-Blast iteration.
296 Returns : a Bio::Search::Iteration::IterationI object or undef if there are no more.
304 unless($self->{'_iter_queue_started'}) {
305 $self->{'_iter_queue'} = [$self->iterations()];
306 $self->{'_iter_queue_started'} = 1;
308 return shift @
{$self->{'_iter_queue'}};
313 Usage : $iteration = $blast->iteration( $number );
314 Purpose : Get an IterationI object for the specified iteration
315 in the search result (PSI-BLAST).
316 Returns : Bio::Search::Iteration::IterationI object
317 Throws : Bio::Root::NoSuchThing exception if $number is not within
318 range of the number of iterations in this report.
319 Argument : integer (optional, if not specified get the last iteration)
325 my ($self,$num) = @_;
326 $num = scalar @
{$self->{'_iterations'}} unless defined $num;
327 unless ($num >= 1 and $num <= scalar $self->{'_iteration_count'}) {
328 $self->throw(-class=>'Bio::Root::NoSuchThing',
329 -text
=>"No such iteration number: $num. Valid range=1-$self->{'_iteration_count'}",
332 return $self->{'_iterations'}->[$num-1];
335 =head2 num_iterations
337 Usage : $num_iterations = $blast->num_iterations;
338 Purpose : Get the number of iterations in the search result (PSI-BLAST).
339 Returns : Total number of iterations in the report
340 Argument : none (read-only)
344 sub num_iterations
{ shift->{'_iteration_count'} }
346 # Methods provided for consistency with BPpsilite.pm (now deprecated);
347 # these are now merely synonyms
349 =head2 number_of_iterations
351 Usage : $num_iterations = $blast->number_of_iterations;
352 Purpose : Get the number of iterations in the search result (PSI-BLAST).
353 Returns : Total number of iterations in the report
354 Argument : none (read-only)
355 Note : Alias of L<num_iterations>.
359 sub number_of_iterations
{ shift->num_iterations }
363 Usage : $round = $blast->round( $number );
364 Purpose : Get an IterationI object for the specified iteration
365 in the search result (PSI-BLAST).
366 Returns : Bio::Search::Iteration::IterationI object
367 Throws : Bio::Root::NoSuchThing exception if $number is not within
368 range of the number of iterations in this report.
369 Argument : integer (optional, if not specified get the last iteration)
371 Note : Alias of L<iteration>.
375 sub round
{ shift->iteration(@_) }
381 Usage : my @iterations = $result->iterations
382 Function: Returns the IterationI objects contained within this Result
383 Returns : Array of L<Bio::Search::Iteration::IterationI> objects
391 if( ref($self->{'_iterations'}) =~ /ARRAY/i ) {
392 @its = @
{$self->{'_iterations'}};
399 Usage : if( $blast->psiblast ) { ... }
400 Purpose : Set/get a boolean indicator whether or not the report
401 is a PSI-BLAST report.
402 Returns : 1 if PSI-BLAST, undef if not.
403 Argument : 1 (when setting)
410 my ($self, $val ) = @_;
412 $self->{'_psiblast'} = 1;
414 return $self->{'_psiblast'};
420 Usage : $nohits = $blast->no_hits_found( $iteration_number );
421 Purpose : Get boolean indicator indicating whether or not any hits
422 were present in the report.
424 This is NOT the same as determining the number of hits via
425 the hits() method, which will return zero hits if there were no
426 hits in the report or if all hits were filtered out during the parse.
428 Thus, this method can be used to distinguish these possibilities
429 for hitless reports generated when filtering.
432 Argument : (optional) integer indicating the iteration number (PSI-BLAST)
433 If iteration number is not specified and this is a PSI-BLAST result,
434 then this method will return true only if all iterations had
440 my ($self, $round) = @_;
442 my $result = 0; # final return value of this method.
443 # Watch the double negative!
444 # result = 0 means "yes hits were found"
445 # result = 1 means "no hits were found" (for the indicated iteration or all iterations)
447 # If a iteration was not specified and there were multiple iterations,
448 # this method should return true only if all iterations had no hits found.
449 if( not defined $round ) {
450 if( $self->{'_iterations'} > 1) {
452 foreach my $i( 1..$self->{'_iterations'} ) {
453 if( not defined $self->{"_iteration_$i"}->{'_no_hits_found'} ) {
460 $result = $self->{"_iteration_1"}->{'_no_hits_found'};
464 $result = $self->{"_iteration_$round"}->{'_no_hits_found'};
471 =head2 set_no_hits_found
473 Usage : $blast->set_no_hits_found( $iteration_number );
474 Purpose : Set boolean indicator indicating whether or not any hits
475 were present in the report.
477 Argument : (optional) integer indicating the iteration number (PSI-BLAST)
481 sub set_no_hits_found
{
482 my ($self, $round) = @_;
484 $self->{"_iteration_$round"}->{'_no_hits_found'} = 1;
487 =head2 _next_iteration_index
489 Title : _next_iteration_index
494 sub _next_iteration_index
{
495 my ($self,@args) = @_;
496 return $self->{'_iteration_index'}++;
503 Usage : $result->rewind;
504 Function: Allow one to reset the Iteration iterator to the beginning
505 Since this is an in-memory implementation
513 $self->SUPER::rewind
(@_);
514 $self->{'_iteration_index'} = 0;
515 foreach ($self->iterations) {
521 =head2 inclusion_threshold
523 Title : inclusion_threshold
524 Usage : my $incl_thresh = $result->inclusion_threshold; (read-only)
525 Function: Gets the e-value threshold for inclusion in the PSI-BLAST
526 score matrix model (blastpgp) that was used for generating the report
528 Returns : number (real) or undef if not a PSI-BLAST report.
533 sub inclusion_threshold
{
535 return $self->{'_inclusion_threshold'};