File Coverage

Bio/Search/Iteration/GenericIteration.pm
Criterion Covered Total %
statement 167 251 66.5
branch 41 86 47.6
condition 10 23 43.4
subroutine 20 27 74.0
pod 24 24 100.0
total 262 411 63.7


line stmt bran cond sub pod time code
1             #
2             # BioPerl module for Bio::Search::Iteration::GenericIteration
3             #
4             # Please direct questions and support issues to
5             #
6             # Cared for by Steve Chervitz
7             #
8             # Copyright Steve Chervitz
9             #
10             # You may distribute this module under the same terms as perl itself
11              
12             # POD documentation - main docs before the code
13              
14             # TODO: Consider calling this BlastIteration (strongly) and maybe simplifying IterationI.
15              
16             =head1 NAME
17              
18             Bio::Search::Iteration::GenericIteration - A generic implementation of the Bio::Search::Iteration::IterationI interface.
19              
20             =head1 SYNOPSIS
21              
22             use Bio::Search::Iteration::GenericIteration;
23             my $it = Bio::Search::GenericIteration->new(
24             -number => 1,
25             -converged => 0,
26             -newhits_unclassified => [@newhits_unclass],
27             -newhits_below => [@newhits_below_threshold],
28             -newhits_not_below => [@newhits_not_below_threshold],
29             -oldhits_below => [@oldhits_below_threshold],
30             -oldhits_newly_below => [@oldhits_newly_below_threshold],
31             -oldhits_not_below => [@oldhits_not_below_threshold],
32             );
33              
34             # TODO: Describe how to configure a SearchIO stream so that it generates
35             # GenericIteration objects.
36              
37              
38             =head1 DESCRIPTION
39              
40             This module acts as a container for Bio::Search::Hit::HitI objects,
41             allowing a Search::Result::ResultI object to partition its hits based
42             on which iteration the hit occurred in (e.g., a PSI-BLAST round).
43              
44             Unless you're writing a parser, you won't ever need to create a
45             GenericIteration or any other IterationI-implementing object. If you use
46             the SearchIO system, IterationI objects are created automatically from
47             a SearchIO stream which returns Bio::Search::Result::ResultI objects
48             and you get the IterationI objects via the ResultI API.
49              
50             For documentation on what you can do with GenericIteration (and other IterationI
51             objects), please see the API documentation in
52             L.
53              
54             Bio::Search::Iteration::GenericIteration is similar in spirit to the deprecated
55             Bio::Tools::BPlite::Iteration modules in bioperl releases prior to 1.6, except
56             that Bio::Search::Iteration::GenericIteration is a pure container, without any
57             parsing functionality as is in Bio::Tools::BPlite::Iteration.
58              
59             =head1 FEEDBACK
60              
61             =head2 Mailing Lists
62              
63             User feedback is an integral part of the evolution of this and other
64             Bioperl modules. Send your comments and suggestions preferably to
65             the Bioperl mailing list. Your participation is much appreciated.
66              
67             bioperl-l@bioperl.org - General discussion
68             http://bioperl.org/wiki/Mailing_lists - About the mailing lists
69              
70             =head2 Support
71              
72             Please direct usage questions or support issues to the mailing list:
73              
74             I
75              
76             rather than to the module maintainer directly. Many experienced and
77             reponsive experts will be able look at the problem and quickly
78             address it. Please include a thorough description of the problem
79             with code and data examples if at all possible.
80              
81             =head2 Reporting Bugs
82              
83             Report bugs to the Bioperl bug tracking system to help us keep track
84             of the bugs and their resolution. Bug reports can be submitted via the
85             web:
86              
87             https://github.com/bioperl/bioperl-live/issues
88              
89             =head1 AUTHOR - Steve Chervitz
90              
91             Email sac@bioperl.org
92              
93             =head1 APPENDIX
94              
95             The rest of the documentation details each of the object methods.
96             Internal methods are usually preceded with a _
97              
98             =cut
99              
100              
101             # Let the code begin...
102              
103              
104             package Bio::Search::Iteration::GenericIteration;
105 12     12   43 use strict;
  12         15  
  12         312  
106              
107              
108 12     12   36 use base qw(Bio::Root::Root Bio::Search::Iteration::IterationI);
  12         14  
  12         5694  
109              
110             =head2 new
111              
112             Title : new
113             Usage : my $obj = Bio::Search::Iteration->new(%args);
114             Function: Builds a new Bio::Search::Iteration object
115             Returns : Bio::Search::Iteration::GenericIteration object
116             Args : -number => integer for the number of this iteration (required)
117             -converged => boolean value whether or not the iteration converged
118             -newhits_unclassified => array reference to hits that were not found
119             in a previous iteration for the iteration and have not been
120             classified with regard to the inclusion threshold
121              
122             # The following are only used for PSI-BLAST reports:
123              
124             -newhits_below => array reference to hits were not found in a
125             previous iteration and are below the inclusion threshold.
126             -newhits_not_below => array reference to hits that were not found in a
127             previous iteration below threshold that and are not below
128             the inclusion threshold threshold.
129             -oldhits_below => array reference to hits that were found
130             in a previous iteration below inclusion threshold and are
131             still below threshold in the current iteration.
132             -oldhits_newly_below => array reference to hits that were found
133             in a previous iteration above threshold but are below
134             threshold in the current iteration.
135             -oldhits_not_below => array reference to hits that were found in a
136             previous iteration above threshold that and are still above
137             the inclusion threshold threshold.
138              
139             -hit_factory => Bio::Factory::ObjectFactoryI capable of making
140             Bio::Search::Hit::HitI objects
141              
142             =cut
143              
144             sub new {
145 93     93 1 287 my($class,@args) = @_;
146              
147 93         469 my $self = $class->SUPER::new(@args);
148 93         819 my ($number, $newhits_unclassified, $newhits_below, $newhits_not_below,
149             $oldhits_below, $oldhits_newly_below, $oldhits_not_below, $converged,
150             $h_f) =
151             $self->_rearrange([qw(NUMBER
152             NEWHITS_UNCLASSIFIED
153             NEWHITS_BELOW
154             NEWHITS_NOT_BELOW
155             OLDHITS_BELOW
156             OLDHITS_NEWLY_BELOW
157             OLDHITS_NOT_BELOW
158             CONVERGED
159             HIT_FACTORY
160             )], @args);
161              
162 93 50       431 if( ! defined $number ) {
163 0         0 $self->throw(-class=>'Bio::Root::BadParameter',
164             -text=>"Iteration number not specified.");
165             } else {
166 93         273 $self->number($number);
167             }
168              
169 93 50       232 defined $converged && $self->converged($converged);
170              
171             # TODO: Performance optimization test calling add_hit() vs. simple assignment:
172             # push @{$self->{'_hits_new'}}, @{$newhits};
173             # vs.
174             # foreach(@{$newhits_below}) {$self->add_hit(-hit=>$_, -old=>0, -below=>1);}
175              
176 93 50       214 if(defined $newhits_unclassified ) {
177 0 0       0 if( ref($newhits_unclassified) =~ /ARRAY/i) {
178 0         0 push @{$self->{'_newhits_unclassified'}}, @{$newhits_unclassified};
  0         0  
  0         0  
179             } else {
180 0         0 $self->throw(-class=>'Bio::Root::BadParameter',
181             -text=>"Parameter NEWHITS is not an array ref: $newhits_unclassified");
182             }
183             } else {
184 93         205 $self->{'_newhits_unclassified'} = [];
185             }
186              
187 93 50       238 if(defined $newhits_below ) {
188 93 50       461 if( ref($newhits_below) =~ /ARRAY/i) {
189 93         150 push @{$self->{'_newhits_below_threshold'}}, @{$newhits_below};
  93         211  
  93         555  
190             } else {
191 0         0 $self->throw(-class=>'Bio::Root::BadParameter',
192             -text=>"Parameter NEWHITS_BELOW is not an array ref: $newhits_below");
193             }
194             } else {
195 0         0 $self->{'_newhits_below_threshold'} = [];
196             }
197              
198 93 50       264 if(defined $newhits_not_below ) {
199 93 50       369 if( ref($newhits_not_below) =~ /ARRAY/i) {
200 93         130 push @{$self->{'_newhits_not_below_threshold'}}, @{$newhits_not_below};
  93         211  
  93         266  
201             } else {
202 0         0 $self->throw(-class=>'Bio::Root::BadParameter',
203             -text=>"Parameter NEWHITS_NOT_BELOW is not an array ref: $newhits_not_below");
204             }
205             } else {
206 0         0 $self->{'_newhits_not_below_threshold'} = [];
207             }
208              
209 93 50       249 if(defined $oldhits_below ) {
210 93 50       320 if( ref($oldhits_below) =~ /ARRAY/i) {
211 93         140 push @{$self->{'_oldhits_below_threshold'}}, @{$oldhits_below};
  93         257  
  93         177  
212             } else {
213 0         0 $self->throw(-class=>'Bio::Root::BadParameter',
214             -text=>"Parameter OLDHITS_BELOW is not an array ref: $oldhits_below");
215             }
216             } else {
217 0         0 $self->{'_oldhits_below_threshold'} = [];
218             }
219              
220 93 50       213 if(defined $oldhits_newly_below ) {
221 93 50       329 if( ref($oldhits_newly_below) =~ /ARRAY/i) {
222 93         162 push @{$self->{'_oldhits_newly_below_threshold'}}, @{$oldhits_newly_below};
  93         198  
  93         159  
223             } else {
224 0         0 $self->throw(-class=>'Bio::Root::BadParameter',
225             -text=>"Parameter OLDHITS_NEWLY_BELOW is not an array ref: $oldhits_newly_below");
226             }
227             } else {
228 0         0 $self->{'_oldhits_newly_below_threshold'} = [];
229             }
230              
231 93 50       216 if(defined $oldhits_not_below ) {
232 93 50       311 if( ref($oldhits_not_below) =~ /ARRAY/i) {
233 93         122 push @{$self->{'_oldhits_not_below_threshold'}}, @{$oldhits_not_below};
  93         282  
  93         149  
234             } else {
235 0         0 $self->throw(-class=>'Bio::Root::BadParameter',
236             -text=>"Parameter OLDHITS_NOT_BELOW is not an array ref: $oldhits_not_below");
237             }
238             } else {
239 0         0 $self->{'_oldhits_not_below_threshold'} = [];
240             }
241            
242 93 50       474 $self->hit_factory($h_f) if $h_f;
243            
244 93         328 return $self;
245             }
246              
247              
248             =head2 number
249              
250             See documentation in Bio::Search::Iteration::IterationI.
251              
252             =cut
253              
254             sub number {
255 95     95 1 163 my ($self,$value) = @_;
256 95         199 my $previous = $self->{'_number'};
257 95 100 66     335 if( defined $value || ! defined $previous ) {
258 93 50       246 $value = $previous = '' unless defined $value;
259 93         183 $self->{'_number'} = $value;
260             }
261 95         148 return $previous;
262             }
263              
264             =head2 converged
265              
266             See documentation in Bio::Search::Iteration::IterationI.
267              
268             =cut
269              
270             sub converged {
271 0     0 1 0 my ($self,$value) = @_;
272 0         0 my $previous = $self->{'_converged'};
273 0 0 0     0 if( defined $value || ! defined $previous ) {
274 0 0       0 $value = $previous = '' unless defined $value;
275 0         0 $self->{'_converged'} = $value;
276             }
277 0         0 return $previous;
278             }
279              
280              
281             =head2 hit_factory
282              
283             Title : hit_factory
284             Usage : $hit->hit_factory($hit_factory)
285             Function: Get/set the factory used to build HitI objects if necessary.
286             Returns : Bio::Factory::ObjectFactoryI
287             Args : Bio::Factory::ObjectFactoryI
288              
289             =cut
290              
291             sub hit_factory {
292 687     687 1 623 my $self = shift;
293 687 100       1041 if (@_) { $self->{_hit_factory} = shift }
  93         236  
294 687   50     1916 return $self->{_hit_factory} || return;
295             }
296              
297             =head2 next_hit
298              
299             This iterates through all old hits as returned by L
300             followed by all new hits as returned by L.
301              
302             For more documentation see L.
303              
304             =cut
305              
306             sub next_hit {
307 1349     1349 1 1102 my ($self) = @_;
308              
309 1349 100       1911 unless($self->{'_hit_queue_started'}) {
310 79         261 $self->{'_hit_queue'} = ( [$self->oldhits(), $self->newhits()] );
311 79         189 $self->{'_hit_queue_started'} = 1;
312             }
313 1349         962 return shift @{$self->{'_hit_queue'}};
  1349         2469  
314             }
315              
316             =head2 next_hit_new
317              
318             See documentation in L.
319              
320             =cut
321              
322             sub next_hit_new {
323 0     0 1 0 my ($self) = @_;
324              
325 0 0       0 unless($self->{'_hit_queue_new_started'}) {
326 0         0 $self->{'_hit_queue_new'} = [$self->newhits()];
327 0         0 $self->{'_hit_queue_new_started'} = 1;
328             }
329 0         0 return shift @{$self->{'_hit_queue_new'}};
  0         0  
330             }
331              
332             =head2 next_hit_old
333              
334             See documentation in L.
335              
336             =cut
337              
338             sub next_hit_old {
339 0     0 1 0 my ($self,$found_again) = @_;
340              
341 0 0       0 unless($self->{'_hit_queue_old_started'}) {
342 0         0 $self->{'_hit_queue_old'} = [$self->oldhits()];
343 0         0 $self->{'_hit_queue_old_started'} = 1;
344             }
345 0         0 return shift @{$self->{'_hit_queue_old'}};
  0         0  
346             }
347              
348             =head2 rewind
349              
350             Title : rewind
351             Usage : $iteration->rewind;
352             Function: Allow one to reset the Hit iterators to the beginning
353             Since this is an in-memory implementation
354             Returns : none
355             Args : none
356              
357             =cut
358              
359             sub rewind {
360 5     5 1 11 my $self = shift;
361 5         11 $self->{'_hit_queue_started'} = 0;
362 5         9 $self->{'_hit_queue_new_started'} = 0;
363 5         10 $self->{'_hit_queue_old_started'} = 0;
364 5         19 foreach ($self->hits) {
365 82         104 $_->rewind;
366             }
367             }
368              
369              
370             =head2 num_hits
371              
372             See documentation in L.
373              
374             =cut
375              
376             sub num_hits {
377 2     2 1 4 my $self = shift;
378              
379 2         8 return $self->num_hits_old + $self->num_hits_new;
380             }
381              
382             =head2 num_hits_new
383              
384             See documentation in L.
385              
386             =cut
387              
388             sub num_hits_new {
389 4     4 1 10 my $self = shift;
390              
391 4         17 return scalar $self->newhits();
392             }
393              
394             =head2 num_hits_old
395              
396             See documentation in L.
397              
398             =cut
399              
400             sub num_hits_old {
401 4     4 1 9 my ($self,$found_again) = @_;
402              
403 4         14 return scalar $self->oldhits();
404             }
405              
406             =head2 add_hit
407              
408             See documentation in L.
409              
410             =cut
411              
412             sub add_hit {
413 1     1 1 3 my ($self,@args) = @_;
414 1         6 my( $hit, $old, $below, $newly_below ) =
415             $self->_rearrange([qw(HIT
416             OLD
417             BELOW_THRESHOLD
418             NEWLY_BELOW
419             )], @args);
420 1         2 my $count = 0;
421              
422 1 50 33     9 unless( ref($hit) eq 'HASH' || $hit->isa('Bio::Search::Hit::HitI') ) {
423 0         0 $self->throw(-class=>'Bio::Root::BadParameter',
424             -text=>"Passed in " .ref($hit).
425             " as a Hit which is not a Bio::Search::Hit::HitI.");
426             }
427              
428 1 50       4 if($old) {
    50          
429 0 0       0 if ($newly_below) {
    0          
430 0         0 push @{$self->{'_oldhits_newly_below_threshold'}}, $hit;
  0         0  
431 0         0 $count = scalar @{$self->{'_oldhits_newly_below_threshold'}};
  0         0  
432             } elsif ($below) {
433 0         0 push @{$self->{'_oldhits_below_threshold'}}, $hit;
  0         0  
434 0         0 $count = scalar @{$self->{'_oldhits_below_threshold'}};
  0         0  
435             } else {
436 0         0 push @{$self->{'_oldhits_not_below_threshold'}}, $hit;
  0         0  
437 0         0 $count = scalar @{$self->{'_oldhits_not_below_threshold'}};
  0         0  
438             }
439             } elsif (defined $old) {
440             # -old is defined but false, so this is a new PSI-BLAST hit
441 0 0       0 if ($below) {
    0          
442 0         0 push @{$self->{'_newhits_below_threshold'}}, $hit;
  0         0  
443 0         0 $count = scalar @{$self->{'_newhits_below_threshold'}};
  0         0  
444             } elsif (defined $below) {
445 0         0 push @{$self->{'_newhits_not_below_threshold'}}, $hit;
  0         0  
446 0         0 $count = scalar @{$self->{'_newhits_not_below_threshold'}};
  0         0  
447             } else {
448             # -below not defined, PSI-BLAST threshold may not be known
449 0         0 push @{$self->{'_newhits_unclassified'}}, $hit;
  0         0  
450 0         0 $count = scalar @{$self->{'_newhits_unclassified'}};
  0         0  
451             }
452             } else {
453             # -old not defined, so it's non-PSI-BLAST
454 1         1 push @{$self->{'_newhits_unclassified'}}, $hit;
  1         3  
455 1         1 $count = scalar @{$self->{'_newhits_unclassified'}};
  1         2  
456             }
457 1         3 return $count;
458             }
459              
460             =head2 hits
461              
462             See Documentation in InterfaceI.
463              
464             =cut
465              
466             sub hits {
467 14     14 1 19 my $self = shift;
468             # print STDERR "Called GenericIteration::hits()\n";
469 14         43 my @new = $self->newhits;
470 14         47 my @old = $self->oldhits;
471 14         109 return ( @new, @old );
472             }
473              
474             =head2 newhits
475              
476             Returns a list containing all newhits in this order:
477              
478             newhits_below_threshold
479             newhits_not_below_threshold
480             newhits_unclassified
481              
482             See more documentation in InterfaceI.
483              
484             =cut
485              
486             sub newhits {
487 97     97 1 131 my $self = shift;
488 97         337 my @hits = $self->newhits_below_threshold;
489 97         339 push @hits, $self->newhits_not_below_threshold;
490 97         310 push @hits, $self->newhits_unclassified;
491 97         505 return @hits;
492             }
493              
494             =head2 newhits_below_threshold
495              
496             See documentation in L.
497              
498             =cut
499              
500             sub newhits_below_threshold {
501 99     99 1 152 my $self = shift;
502 99 50       281 if (ref $self->{'_newhits_below_threshold'} ) {
503 99   50     202 my $factory = $self->hit_factory || return @{$self->{'_newhits_below_threshold'}};
504 99         141 for (0..$#{$self->{'_newhits_below_threshold'}}) {
  99         304  
505 2376 100       1611 ref(${$self->{'_newhits_below_threshold'}}[$_]) eq 'HASH' || next;
  2376         4176  
506 1641         1198 ${$self->{'_newhits_below_threshold'}}[$_] = $factory->create_object(%{${$self->{'_newhits_below_threshold'}}[$_]});
  1641         3850  
  1641         971  
  1641         7923  
507             }
508 99         172 return @{$self->{'_newhits_below_threshold'}};
  99         707  
509             }
510 0         0 return;
511             }
512              
513             =head2 newhits_not_below_threshold
514              
515             See documentation in L.
516              
517             =cut
518              
519             sub newhits_not_below_threshold {
520 99     99 1 141 my $self = shift;
521 99 50       309 if (ref $self->{'_newhits_not_below_threshold'} ) {
522 99   50     224 my $factory = $self->hit_factory || return @{$self->{'_newhits_not_below_threshold'}};
523 99         141 for (0..$#{$self->{'_newhits_not_below_threshold'}}) {
  99         299  
524 832 100       552 ref(${$self->{'_newhits_not_below_threshold'}}[$_]) eq 'HASH' || next;
  832         1542  
525 512         421 ${$self->{'_newhits_not_below_threshold'}}[$_] = $factory->create_object(%{${$self->{'_newhits_not_below_threshold'}}[$_]});
  512         1155  
  512         329  
  512         2377  
526             }
527 99         130 return @{$self->{'_newhits_not_below_threshold'}};
  99         305  
528             }
529 0         0 return;
530             }
531              
532             =head2 newhits_unclassified
533              
534             Title : newhits_unclassified
535             Usage : foreach( $iteration->hits_unclassified ) {...}
536             Function: Gets all newhits that have not been partitioned into
537             sets relative to the inclusion threshold.
538             Returns : Array of Bio::Search::Hit::HitI objects.
539             Args : none
540              
541             =cut
542              
543             sub newhits_unclassified {
544 99     99 1 122 my $self = shift;
545 99 50       271 if (ref $self->{'_newhits_unclassified'} ) {
546 99   50     197 my $factory = $self->hit_factory || return @{$self->{'_newhits_unclassified'}};
547 99         136 for (0..$#{$self->{'_newhits_unclassified'}}) {
  99         319  
548 1 50       1 ref(${$self->{'_newhits_unclassified'}}[$_]) eq 'HASH' || next;
  1         4  
549 0         0 ${$self->{'_newhits_unclassified'}}[$_] = $factory->create_object(%{${$self->{'_newhits_unclassified'}}[$_]});
  0         0  
  0         0  
  0         0  
550             }
551 99         111 return @{$self->{'_newhits_unclassified'}};
  99         191  
552             }
553 0         0 return;
554             }
555              
556             =head2 oldhits
557              
558             Returns a list containing all oldhits in this order:
559              
560             oldhits_below_threshold
561             oldhits_newly_below_threshold
562             oldhits_not_below_threshold
563              
564             See more documentation in InterfaceI.
565              
566             =cut
567              
568             sub oldhits {
569 97     97 1 151 my $self = shift;
570 97         295 my @hits = $self->oldhits_below_threshold;
571 97         427 push @hits, $self->oldhits_newly_below_threshold;
572 97         252 push @hits, $self->oldhits_not_below_threshold;
573 97         304 return @hits;
574             }
575              
576             =head2 oldhits_below_threshold
577              
578             See documentation in L.
579              
580             =cut
581              
582             sub oldhits_below_threshold {
583 99     99 1 147 my $self = shift;
584 99 50       276 if (ref $self->{'_oldhits_below_threshold'} ) {
585 99   50     236 my $factory = $self->hit_factory || return @{$self->{'_oldhits_below_threshold'}};
586 99         156 for (0..$#{$self->{'_oldhits_below_threshold'}}) {
  99         372  
587 327 100       198 ref(${$self->{'_oldhits_below_threshold'}}[$_]) eq 'HASH' || next;
  327         532  
588 109         74 ${$self->{'_oldhits_below_threshold'}}[$_] = $factory->create_object(%{${$self->{'_oldhits_below_threshold'}}[$_]});
  109         232  
  109         80  
  109         525  
589             }
590 99         149 return @{$self->{'_oldhits_below_threshold'}};
  99         290  
591             }
592 0         0 return;
593             }
594              
595             =head2 oldhits_newly_below_threshold
596              
597             See documentation in L.
598              
599             =cut
600              
601             sub oldhits_newly_below_threshold {
602 99     99 1 136 my $self = shift;
603 99 50       316 if (ref $self->{'_oldhits_newly_below_threshold'} ) {
604 99   50     217 my $factory = $self->hit_factory || return @{$self->{'_oldhits_newly_below_threshold'}};
605 99         152 for (0..$#{$self->{'_oldhits_newly_below_threshold'}}) {
  99         272  
606 9 100       5 ref(${$self->{'_oldhits_newly_below_threshold'}}[$_]) eq 'HASH' || next;
  9         23  
607 3         5 ${$self->{'_oldhits_newly_below_threshold'}}[$_] = $factory->create_object(%{${$self->{'_oldhits_newly_below_threshold'}}[$_]});
  3         10  
  3         4  
  3         15  
608             }
609 99         123 return @{$self->{'_oldhits_newly_below_threshold'}};
  99         210  
610             }
611 0         0 return;
612             }
613              
614             =head2 oldhits_not_below_threshold
615              
616             See documentation in L.
617              
618             =cut
619              
620             sub oldhits_not_below_threshold {
621 99     99 1 125 my $self = shift;
622 99 50       269 if (ref $self->{'_oldhits_not_below_threshold'} ) {
623 99   50     227 my $factory = $self->hit_factory || return @{$self->{'_oldhits_not_below_threshold'}};
624 99         427 for (0..$#{$self->{'_oldhits_not_below_threshold'}}) {
  99         253  
625 15 100       14 ref(${$self->{'_oldhits_not_below_threshold'}}[$_]) eq 'HASH' || next;
  15         28  
626 5         6 ${$self->{'_oldhits_not_below_threshold'}}[$_] = $factory->create_object(%{${$self->{'_oldhits_not_below_threshold'}}[$_]});
  5         11  
  5         2  
  5         21  
627             }
628 99         331 return @{$self->{'_oldhits_not_below_threshold'}};
  99         214  
629             }
630 0           return;
631             }
632              
633             =head2 hits_below_threshold
634              
635             See documentation in L.
636              
637             =cut
638              
639             sub hits_below_threshold {
640 0     0 1   my $self = shift;
641 0           my @hits = $self->newhits_below_threshold;
642 0           push @hits, $self->oldhits_newly_below_threshold;
643 0           return @hits;
644             }
645              
646             =head2 get_hit
647              
648             See documentation in L.
649              
650             To free up the memory used by the get_hit() functionality, call free_hit_lookup().
651              
652             This functionality might be useful at the Result level, too.
653             BlastResult::get_hit() would return a list of HitI objects for hits
654             that occur in multiple iterations.
655              
656             =cut
657              
658             sub get_hit {
659 0     0 1   my ($self,$name) = @_;
660 0 0         $self->_create_hit_lookup() unless defined $self->{'_hit_lookup'};
661              
662 0           return $self->{'_hit_lookup'}->{"\U$name"};
663             }
664              
665             # Internal method.
666             sub _create_hit_lookup {
667 0     0     my $self = shift;
668 0           foreach ($self->hits) {
669 0           my $hname = $_->name;
670 0           $self->{'_hit_lookup'}->{"\U$hname"} = $_;
671             }
672             }
673              
674             =head2 free_hit_lookup
675              
676             Purpose : Frees up the memory used by the get_hit() functionality.
677             For the memory-conscious.
678              
679             =cut
680              
681             sub free_hit_lookup {
682 0     0 1   my $self = shift;
683 0           undef $self->{'_hit_lookup'};
684             }
685              
686             1;