File Coverage

Bio/SeqFeature/FeaturePair.pm
Criterion Covered Total %
statement 62 70 88.5
branch 20 24 83.3
condition 8 12 66.6
subroutine 23 29 79.3
pod 22 24 91.6
total 135 159 84.9


line stmt bran cond sub pod time code
1             #
2             # BioPerl module for Bio::SeqFeature::FeaturePair
3             #
4             # Please direct questions and support issues to
5             #
6             # Cared for by Ewan Birney
7             #
8             # Copyright Ewan Birney
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             =head1 NAME
15              
16             Bio::SeqFeature::FeaturePair - hold pair feature information e.g. blast hits
17              
18             =head1 SYNOPSIS
19              
20             my $feat = Bio::SeqFeature::FeaturePair->new(
21             -feature1 => $f1,
22             -feature2 => $f2,
23             );
24              
25             # Bio::SeqFeatureI methods can be used
26              
27             my $start = $feat->start;
28             my $end = $feat->end;
29              
30             # Bio::FeaturePair methods can be used
31             my $hstart = $feat->hstart;
32             my $hend = $feat->hend;
33              
34             my $feature1 = $feat->feature1; # returns feature1 object
35              
36             =head1 DESCRIPTION
37              
38             A sequence feature object where the feature is itself a feature on
39             another sequence - e.g. a blast hit where residues 1-40 of a protein
40             sequence SW:HBA_HUMAN has hit to bases 100 - 220 on a genomic sequence
41             HS120G22. The genomic sequence coordinates are used to create one
42             sequence feature $f1 and the protein coordinates are used to create
43             feature $f2. A FeaturePair object can then be made
44              
45             my $fp = Bio::SeqFeature::FeaturePair->new(
46             -feature1 => $f1, # genomic
47             -feature2 => $f2, # protein
48             );
49              
50             This object can be used as a standard Bio::SeqFeatureI in which case
51              
52             my $gstart = $fp->start # returns start coord on feature1 - genomic seq.
53             my $gend = $fp->end # returns end coord on feature1.
54              
55             In general standard Bio::SeqFeatureI method calls return information
56             in feature1.
57              
58             Data in the feature 2 object are generally obtained using the standard
59             methods prefixed by h (for hit!)
60              
61             my $pstart = $fp->hstart # returns start coord on feature2 = protein seq.
62             my $pend = $fp->hend # returns end coord on feature2.
63              
64             If you wish to swap feature1 and feature2 around :
65              
66             $feat->invert
67              
68             so...
69              
70             $feat->start # etc. returns data in $feature2 object
71              
72              
73             No sub_SeqFeatures or tags can be stored in this object directly. Any
74             features or tags are expected to be stored in the contained objects
75             feature1, and feature2.
76              
77             =head1 CONTACT
78              
79             Ewan Birney Ebirney@sanger.ac.ukE
80              
81             =head1 APPENDIX
82              
83             The rest of the documentation details each of the object
84             methods. Internal methods are usually preceded with a _
85              
86             =cut
87              
88              
89             # Let the code begin...
90              
91              
92             package Bio::SeqFeature::FeaturePair;
93 44     44   1208 use vars qw($AUTOLOAD);
  44         48  
  44         2285  
94 44     44   139 use strict;
  44         50  
  44         622  
95              
96 44     44   1366 use Bio::SeqFeatureI;
  44         44  
  44         895  
97 44     44   3139 use Bio::Factory::ObjectFactory;
  44         973  
  44         822  
98              
99 44     44   179 use base qw(Bio::SeqFeature::Generic);
  44         41  
  44         28297  
100              
101             =head2 new
102              
103             Title : new
104             Usage :
105             Function: Constructor for this module. Accepts the following parameters:
106              
107             -feature1 Bio::SeqFeatureI-compliant object
108             -feature2 Bio::SeqFeatureI-compliant object
109             -feature_factory Bio::Factory::ObjectFactoryI compliant
110             object to be used when feature1 and/or feature2
111             are accessed without explicitly set before. This
112             is mostly useful for derived classes who want to
113             set their preferred class for feature objects.
114              
115             Example :
116             Returns :
117             Args : see above
118              
119              
120             =cut
121              
122             sub new {
123 4112     4112 1 5369 my ($class, @args) = @_;
124              
125             #
126             # We've got a certain problem here that somewhat relates to chicken and
127             # eggs. The problem is, we override a lot of SeqFeatureI methods here
128             # to delegate them to either feature1 or feature2. If we pass along
129             # those attributes right away, we need feature1 or feature2 or the feature
130             # factory in place, or there is no way around the dreaded default, which
131             # is ugly too (as it necessitates subsequent copying if you wanted a
132             # different feature object class).
133             #
134             # So I decided to go with the lesser of two evils here: we need to assume
135             # here that we can set all attributes through set_attributes(), which we
136             # assume is no different from setting them through the constructor. This
137             # gives us a window to set the feature objects and the factory, such that
138             # any derived class doesn't have to worry about this any more.
139             #
140             # I'm happy to hear a better solution, but I think this one isn't so bad.
141             #
142 4112         8423 my $self = $class->SUPER::new();
143 4112         8552 my ($feature1,$feature2,$featfact) =
144             $self->_rearrange([qw( FEATURE1
145             FEATURE2
146             FEATURE_FACTORY )],@args);
147            
148 4112         8037 $self->_register_for_cleanup(\&cleanup_fp);
149             # initialize the feature object factory if not provided
150 4112 100       6222 if(! $featfact) {
151 2568         7322 $featfact = Bio::Factory::ObjectFactory->new(
152             -type => "Bio::SeqFeature::Generic",
153             -interface => "Bio::SeqFeatureI"
154             );
155             }
156 4112         7203 $self->feature_factory($featfact);
157             # Store the features in the object
158 4112 100       5508 $feature1 && $self->feature1($feature1);
159 4112 100       5009 $feature2 && $self->feature2($feature2);
160            
161             # OK. Now we're setup to store all the attributes, and they'll go right
162             # away into the right objects.
163 4112         7500 $self->set_attributes(@args);
164              
165             # done - we hope
166 4112         6163 return $self;
167             }
168              
169             =head2 feature1
170              
171             Title : feature1
172             Usage : $f = $featpair->feature1
173             $featpair->feature1($feature)
174             Function: Get/set for the query feature
175             Returns : Bio::SeqFeatureI
176             Args : Bio::SeqFeatureI
177              
178              
179             =cut
180              
181             sub feature1 {
182 33065     33065 1 23844 my ($self,$arg) = @_;
183 33065 100 100     86004 if ( defined($arg) || !defined $self->{'feature1'} ) {
184 3999 50       5007 $self->throw("internal error: feature factory not set!")
185             unless $self->feature_factory;
186 3999 100       5553 $arg = $self->feature_factory->create_object() unless( defined $arg);
187 3999 50 33     16829 $self->throw("Argument [$arg] must be a Bio::SeqFeatureI")
188             unless (ref($arg) && $arg->isa("Bio::SeqFeatureI"));
189 3999         4568 $self->{'feature1'} = $arg;
190             }
191 33065         57897 return $self->{'feature1'};
192             }
193              
194             =head2 feature2
195              
196             Title : feature2
197             Usage : $f = $featpair->feature2
198             $featpair->feature2($feature)
199             Function: Get/set for the hit feature
200             Returns : Bio::SeqFeatureI
201             Args : Bio::SeqFeatureI
202              
203              
204             =cut
205              
206             sub feature2 {
207 15230     15230 1 11304 my ($self,$arg) = @_;
208              
209 15230 100 100     38574 if ( defined($arg) || ! defined $self->{'feature2'}) {
210 3207 50       3537 $self->throw("internal error: feature factory not set!")
211             unless $self->feature_factory;
212 3207 100       3964 $arg = $self->feature_factory->create_object() unless( defined $arg);
213 3207 50 33     11421 $self->throw("Argument [$arg] must be a Bio::SeqFeatureI")
214             unless (ref($arg) && $arg->isa("Bio::SeqFeatureI"));
215 3207         3768 $self->{'feature2'} = $arg;
216             }
217 15230         26621 return $self->{'feature2'};
218             }
219              
220             =head2 start
221              
222             Title : start
223             Usage : $start = $featpair->start
224             $featpair->start(20)
225             Function: Get/set on the start coordinate of feature1
226             Returns : integer
227             Args : [optional] beginning of feature
228              
229             =cut
230              
231             sub start {
232 5580     5580 1 6907 return shift->feature1->start(@_);
233             }
234              
235             =head2 end
236              
237             Title : end
238             Usage : $end = $featpair->end
239             $featpair->end($end)
240             Function: get/set on the end coordinate of feature1
241             Returns : integer
242             Args : [optional] ending point of feature
243              
244              
245             =cut
246              
247             sub end {
248 5570     5570 1 7072 return shift->feature1->end(@_);
249             }
250              
251             =head2 strand
252              
253             Title : strand
254             Usage : $strand = $feat->strand()
255             $feat->strand($strand)
256             Function: get/set on strand information, being 1,-1 or 0
257             Returns : -1,1 or 0
258             Args : [optional] strand information to set
259              
260              
261             =cut
262              
263             sub strand {
264 104     104 1 120 return shift->feature1->strand(@_);
265             }
266              
267             =head2 location
268              
269             Title : location
270             Usage : $location = $featpair->location
271             $featpair->location($location)
272             Function: Get/set location object (using feature1)
273             Returns : Bio::LocationI object
274             Args : [optional] LocationI to store
275              
276             =cut
277              
278             sub location {
279 0     0 1 0 return shift->feature1->location(@_);
280             }
281              
282             =head2 score
283              
284             Title : score
285             Usage : $score = $feat->score()
286             $feat->score($score)
287             Function: get/set on score information
288             Returns : float
289             Args : none if get, the new value if set
290              
291              
292             =cut
293              
294             sub score {
295 3146     3146 1 3470 return shift->feature1->score(@_);
296             }
297              
298             =head2 frame
299              
300             Title : frame
301             Usage : $frame = $feat->frame()
302             $feat->frame($frame)
303             Function: get/set on frame information
304             Returns : 0,1,2
305             Args : none if get, the new value if set
306              
307              
308             =cut
309              
310             sub frame {
311 0     0 1 0 return shift->feature1->frame(@_);
312             }
313              
314             =head2 primary_tag
315              
316             Title : primary_tag
317             Usage : $ptag = $featpair->primary_tag
318             Function: get/set on the primary_tag of feature1
319             Returns : 0,1,2
320             Args : none if get, the new value if set
321              
322              
323             =cut
324              
325             sub primary_tag {
326 1666     1666 1 5773 return shift->feature1->primary_tag(@_);
327             }
328              
329             =head2 source_tag
330              
331             Title : source_tag
332             Usage : $tag = $feat->source_tag()
333             $feat->source_tag('genscan');
334             Function: Returns the source tag for a feature,
335             eg, 'genscan'
336             Returns : a string
337             Args : none
338              
339              
340             =cut
341              
342             sub source_tag {
343 25     25 1 35 return shift->feature1->source_tag(@_);
344             }
345              
346             =head2 seqname
347              
348             Title : seqname
349             Usage : $obj->seq_id($newval)
350             Function: There are many cases when you make a feature that you
351             do know the sequence name, but do not know its actual
352             sequence. This is an attribute such that you can store
353             the seqname.
354              
355             This attribute should *not* be used in GFF dumping, as
356             that should come from the collection in which the seq
357             feature was found.
358             Returns : value of seqname
359             Args : newvalue (optional)
360              
361              
362             =cut
363              
364             sub seq_id {
365 8540     8540 1 9472 return shift->feature1->seq_id(@_);
366             }
367              
368             =head2 hseqname
369              
370             Title : hseqname
371             Usage : $featpair->hseqname($newval)
372             Function: Get/set method for the name of
373             feature2.
374             Returns : value of $feature2->seq_id
375             Args : newvalue (optional)
376              
377              
378             =cut
379              
380             sub hseq_id {
381 2437     2437 0 2499 return shift->feature2->seq_id(@_);
382             }
383              
384              
385             =head2 hstart
386              
387             Title : hstart
388             Usage : $start = $featpair->hstart
389             $featpair->hstart(20)
390             Function: Get/set on the start coordinate of feature2
391             Returns : integer
392             Args : none
393              
394             =cut
395              
396             sub hstart {
397 2435     2435 1 2790 return shift->feature2->start(@_);
398             }
399              
400             =head2 hend
401              
402             Title : hend
403             Usage : $end = $featpair->hend
404             $featpair->hend($end)
405             Function: get/set on the end coordinate of feature2
406             Returns : integer
407             Args : none
408              
409              
410             =cut
411              
412             sub hend {
413 2435     2435 1 2816 return shift->feature2->end(@_);
414             }
415              
416              
417             =head2 hstrand
418              
419             Title : hstrand
420             Usage : $strand = $feat->strand()
421             $feat->strand($strand)
422             Function: get/set on strand information, being 1,-1 or 0
423             Returns : -1,1 or 0
424             Args : none
425              
426              
427             =cut
428              
429             sub hstrand {
430 0     0 1 0 return shift->feature2->strand(@_);
431             }
432              
433             =head2 hscore
434              
435             Title : hscore
436             Usage : $score = $feat->score()
437             $feat->score($score)
438             Function: get/set on score information
439             Returns : float
440             Args : none if get, the new value if set
441              
442              
443             =cut
444              
445             sub hscore {
446 0     0 1 0 return shift->feature2->score(@_);
447             }
448              
449             =head2 hframe
450              
451             Title : hframe
452             Usage : $frame = $feat->frame()
453             $feat->frame($frame)
454             Function: get/set on frame information
455             Returns : 0,1,2
456             Args : none if get, the new value if set
457              
458              
459             =cut
460              
461             sub hframe {
462 0     0 1 0 return shift->feature2->frame(@_);
463             }
464              
465             =head2 hprimary_tag
466              
467             Title : hprimary_tag
468             Usage : $ptag = $featpair->hprimary_tag
469             Function: Get/set on the primary_tag of feature2
470             Returns : 0,1,2
471             Args : none if get, the new value if set
472              
473              
474             =cut
475              
476             sub hprimary_tag {
477 1     1 1 4 return shift->feature2->primary_tag(@_);
478             }
479              
480             =head2 hsource_tag
481              
482             Title : hsource_tag
483             Usage : $tag = $feat->hsource_tag()
484             $feat->source_tag('genscan');
485             Function: Returns the source tag for a feature,
486             eg, 'genscan'
487             Returns : a string
488             Args : none
489              
490              
491             =cut
492              
493             sub hsource_tag {
494 1     1 1 3 return shift->feature2->source_tag(@_);
495             }
496              
497             =head2 invert
498              
499             Title : invert
500             Usage : $tag = $feat->invert
501             Function: Swaps feature1 and feature2 around
502             Returns : Nothing
503             Args : none
504              
505              
506             =cut
507              
508             sub invert {
509 1     1 1 2 my ($self) = @_;
510              
511 1         2 my $tmp = $self->feature1;
512            
513 1         2 $self->feature1($self->feature2);
514 1         2 $self->feature2($tmp);
515 1         3 return 1;
516             }
517              
518             =head2 feature_factory
519              
520             Title : feature_factory
521             Usage : $obj->feature_factory($newval)
522             Function: Get/set the feature object factory for this feature pair.
523              
524             The feature object factory will be used to create a feature
525             object if feature1() or feature2() is called in get mode
526             without having been set before.
527              
528             The default is an instance of Bio::Factory::ObjectFactory
529             and hence allows the type to be changed dynamically at any
530             time.
531              
532             Example :
533             Returns : The feature object factory in use (a
534             Bio::Factory::ObjectFactoryI compliant object)
535             Args : on set, a Bio::Factory::ObjectFactoryI compliant object
536              
537              
538             =cut
539              
540             sub feature_factory {
541 11587     11587 1 9032 my $self = shift;
542              
543 11587 100       17622 return $self->{'feature_factory'} = shift if @_;
544 7475         12022 return $self->{'feature_factory'};
545             }
546              
547             #################################################################
548             # aliases for backwards compatibility #
549             #################################################################
550              
551             # seqname() is already aliased in Generic.pm, and we overwrite seq_id
552              
553             sub hseqname {
554 0     0 1 0 my $self = shift;
555 0         0 $self->warn("SeqFeatureI::seqname() is deprecated. Please use seq_id() instead.");
556 0         0 return $self->hseq_id(@_);
557             }
558              
559             sub cleanup_fp {
560 4112     4112 0 2867 my $self = shift;
561 4112         9467 $self->{'feature1'} = $self->{'feature2'} = undef;
562             }
563             1;