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   77 use strict;
  12         25  
  12         380  
106              
107              
108 12     12   58 use base qw(Bio::Root::Root Bio::Search::Iteration::IterationI);
  12         24  
  12         5249  
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 385 my($class,@args) = @_;
146              
147 93         507 my $self = $class->SUPER::new(@args);
148 93         743 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       375 if( ! defined $number ) {
163 0         0 $self->throw(-class=>'Bio::Root::BadParameter',
164             -text=>"Iteration number not specified.");
165             } else {
166 93         344 $self->number($number);
167             }
168              
169 93 50       223 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       250 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         258 $self->{'_newhits_unclassified'} = [];
185             }
186              
187 93 50       250 if(defined $newhits_below ) {
188 93 50       475 if( ref($newhits_below) =~ /ARRAY/i) {
189 93         156 push @{$self->{'_newhits_below_threshold'}}, @{$newhits_below};
  93         275  
  93         511  
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       219 if(defined $newhits_not_below ) {
199 93 50       333 if( ref($newhits_not_below) =~ /ARRAY/i) {
200 93         141 push @{$self->{'_newhits_not_below_threshold'}}, @{$newhits_not_below};
  93         228  
  93         280  
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       229 if(defined $oldhits_below ) {
210 93 50       333 if( ref($oldhits_below) =~ /ARRAY/i) {
211 93         145 push @{$self->{'_oldhits_below_threshold'}}, @{$oldhits_below};
  93         221  
  93         197  
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       205 if(defined $oldhits_newly_below ) {
221 93 50       340 if( ref($oldhits_newly_below) =~ /ARRAY/i) {
222 93         148 push @{$self->{'_oldhits_newly_below_threshold'}}, @{$oldhits_newly_below};
  93         222  
  93         167  
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       217 if(defined $oldhits_not_below ) {
232 93 50       306 if( ref($oldhits_not_below) =~ /ARRAY/i) {
233 93         152 push @{$self->{'_oldhits_not_below_threshold'}}, @{$oldhits_not_below};
  93         266  
  93         152  
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       465 $self->hit_factory($h_f) if $h_f;
243            
244 93         385 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 216 my ($self,$value) = @_;
256 95         239 my $previous = $self->{'_number'};
257 95 100 66     319 if( defined $value || ! defined $previous ) {
258 93 50       269 $value = $previous = '' unless defined $value;
259 93         195 $self->{'_number'} = $value;
260             }
261 95         181 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 809 my $self = shift;
293 687 100       1145 if (@_) { $self->{_hit_factory} = shift }
  93         221  
294 687   50     1808 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 1950 my ($self) = @_;
308              
309 1349 100       2276 unless($self->{'_hit_queue_started'}) {
310 79         332 $self->{'_hit_queue'} = ( [$self->oldhits(), $self->newhits()] );
311 79         222 $self->{'_hit_queue_started'} = 1;
312             }
313 1349         1474 return shift @{$self->{'_hit_queue'}};
  1349         2940  
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 105 my $self = shift;
361 5         15 $self->{'_hit_queue_started'} = 0;
362 5         10 $self->{'_hit_queue_new_started'} = 0;
363 5         14 $self->{'_hit_queue_old_started'} = 0;
364 5         22 foreach ($self->hits) {
365 82         123 $_->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 5 my $self = shift;
378              
379 2         7 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 9 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 11 my ($self,$found_again) = @_;
402              
403 4         16 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 5 my ($self,@args) = @_;
414 1         8 my( $hit, $old, $below, $newly_below ) =
415             $self->_rearrange([qw(HIT
416             OLD
417             BELOW_THRESHOLD
418             NEWLY_BELOW
419             )], @args);
420 1         4 my $count = 0;
421              
422 1 50 33     13 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       6 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         3 push @{$self->{'_newhits_unclassified'}}, $hit;
  1         4  
455 1         2 $count = scalar @{$self->{'_newhits_unclassified'}};
  1         2  
456             }
457 1         5 return $count;
458             }
459              
460             =head2 hits
461              
462             See Documentation in InterfaceI.
463              
464             =cut
465              
466             sub hits {
467 14     14 1 25 my $self = shift;
468             # print STDERR "Called GenericIteration::hits()\n";
469 14         46 my @new = $self->newhits;
470 14         46 my @old = $self->oldhits;
471 14         89 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 239 my $self = shift;
488 97         309 my @hits = $self->newhits_below_threshold;
489 97         305 push @hits, $self->newhits_not_below_threshold;
490 97         289 push @hits, $self->newhits_unclassified;
491 97         512 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 162 my $self = shift;
502 99 50       258 if (ref $self->{'_newhits_below_threshold'} ) {
503 99   50     227 my $factory = $self->hit_factory || return @{$self->{'_newhits_below_threshold'}};
504 99         205 for (0..$#{$self->{'_newhits_below_threshold'}}) {
  99         275  
505 2376 100       2655 ref(${$self->{'_newhits_below_threshold'}}[$_]) eq 'HASH' || next;
  2376         4506  
506 1641         2152 ${$self->{'_newhits_below_threshold'}}[$_] = $factory->create_object(%{${$self->{'_newhits_below_threshold'}}[$_]});
  1641         4786  
  1641         1738  
  1641         8037  
507             }
508 99         194 return @{$self->{'_newhits_below_threshold'}};
  99         478  
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 181 my $self = shift;
521 99 50       283 if (ref $self->{'_newhits_not_below_threshold'} ) {
522 99   50     253 my $factory = $self->hit_factory || return @{$self->{'_newhits_not_below_threshold'}};
523 99         176 for (0..$#{$self->{'_newhits_not_below_threshold'}}) {
  99         277  
524 832 100       870 ref(${$self->{'_newhits_not_below_threshold'}}[$_]) eq 'HASH' || next;
  832         1647  
525 512         647 ${$self->{'_newhits_not_below_threshold'}}[$_] = $factory->create_object(%{${$self->{'_newhits_not_below_threshold'}}[$_]});
  512         1463  
  512         539  
  512         2520  
526             }
527 99         150 return @{$self->{'_newhits_not_below_threshold'}};
  99         306  
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 148 my $self = shift;
545 99 50       271 if (ref $self->{'_newhits_unclassified'} ) {
546 99   50     282 my $factory = $self->hit_factory || return @{$self->{'_newhits_unclassified'}};
547 99         167 for (0..$#{$self->{'_newhits_unclassified'}}) {
  99         273  
548 1 50       2 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         188 return @{$self->{'_newhits_unclassified'}};
  99         222  
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 183 my $self = shift;
570 97         337 my @hits = $self->oldhits_below_threshold;
571 97         457 push @hits, $self->oldhits_newly_below_threshold;
572 97         286 push @hits, $self->oldhits_not_below_threshold;
573 97         315 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 181 my $self = shift;
584 99 50       292 if (ref $self->{'_oldhits_below_threshold'} ) {
585 99   50     265 my $factory = $self->hit_factory || return @{$self->{'_oldhits_below_threshold'}};
586 99         174 for (0..$#{$self->{'_oldhits_below_threshold'}}) {
  99         337  
587 327 100       300 ref(${$self->{'_oldhits_below_threshold'}}[$_]) eq 'HASH' || next;
  327         555  
588 109         125 ${$self->{'_oldhits_below_threshold'}}[$_] = $factory->create_object(%{${$self->{'_oldhits_below_threshold'}}[$_]});
  109         294  
  109         105  
  109         484  
589             }
590 99         157 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 179 my $self = shift;
603 99 50       300 if (ref $self->{'_oldhits_newly_below_threshold'} ) {
604 99   50     267 my $factory = $self->hit_factory || return @{$self->{'_oldhits_newly_below_threshold'}};
605 99         161 for (0..$#{$self->{'_oldhits_newly_below_threshold'}}) {
  99         222  
606 9 100       10 ref(${$self->{'_oldhits_newly_below_threshold'}}[$_]) eq 'HASH' || next;
  9         20  
607 3         5 ${$self->{'_oldhits_newly_below_threshold'}}[$_] = $factory->create_object(%{${$self->{'_oldhits_newly_below_threshold'}}[$_]});
  3         11  
  3         3  
  3         14  
608             }
609 99         151 return @{$self->{'_oldhits_newly_below_threshold'}};
  99         269  
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 186 my $self = shift;
622 99 50       267 if (ref $self->{'_oldhits_not_below_threshold'} ) {
623 99   50     483 my $factory = $self->hit_factory || return @{$self->{'_oldhits_not_below_threshold'}};
624 99         184 for (0..$#{$self->{'_oldhits_not_below_threshold'}}) {
  99         232  
625 15 100       16 ref(${$self->{'_oldhits_not_below_threshold'}}[$_]) eq 'HASH' || next;
  15         34  
626 5         6 ${$self->{'_oldhits_not_below_threshold'}}[$_] = $factory->create_object(%{${$self->{'_oldhits_not_below_threshold'}}[$_]});
  5         14  
  5         5  
  5         26  
627             }
628 99         307 return @{$self->{'_oldhits_not_below_threshold'}};
  99         321  
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;