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 45     45   1345 use vars qw($AUTOLOAD);
  45         78  
  45         2038  
94 45     45   229 use strict;
  45         74  
  45         828  
95              
96 45     45   1236 use Bio::SeqFeatureI;
  45         88  
  45         1045  
97 45     45   2880 use Bio::Factory::ObjectFactory;
  45         85  
  45         1011  
98              
99 45     45   198 use base qw(Bio::SeqFeature::Generic);
  45         79  
  45         33728  
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 4116     4116 1 7678 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 4116         11563 my $self = $class->SUPER::new();
143 4116         10614 my ($feature1,$feature2,$featfact) =
144             $self->_rearrange([qw( FEATURE1
145             FEATURE2
146             FEATURE_FACTORY )],@args);
147            
148 4116         11468 $self->_register_for_cleanup(\&cleanup_fp);
149             # initialize the feature object factory if not provided
150 4116 100       7086 if(! $featfact) {
151 2572         6484 $featfact = Bio::Factory::ObjectFactory->new(
152             -type => "Bio::SeqFeature::Generic",
153             -interface => "Bio::SeqFeatureI"
154             );
155             }
156 4116         10094 $self->feature_factory($featfact);
157             # Store the features in the object
158 4116 100       7173 $feature1 && $self->feature1($feature1);
159 4116 100       6767 $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 4116         9457 $self->set_attributes(@args);
164              
165             # done - we hope
166 4116         7642 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 33093     33093 1 39307 my ($self,$arg) = @_;
183 33093 100 100     75814 if ( defined($arg) || !defined $self->{'feature1'} ) {
184 4003 50       6484 $self->throw("internal error: feature factory not set!")
185             unless $self->feature_factory;
186 4003 100       6891 $arg = $self->feature_factory->create_object() unless( defined $arg);
187 4003 50 33     15442 $self->throw("Argument [$arg] must be a Bio::SeqFeatureI")
188             unless (ref($arg) && $arg->isa("Bio::SeqFeatureI"));
189 4003         6099 $self->{'feature1'} = $arg;
190             }
191 33093         66772 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 15238     15238 1 19265 my ($self,$arg) = @_;
208              
209 15238 100 100     36062 if ( defined($arg) || ! defined $self->{'feature2'}) {
210 3211 50       4651 $self->throw("internal error: feature factory not set!")
211             unless $self->feature_factory;
212 3211 100       5022 $arg = $self->feature_factory->create_object() unless( defined $arg);
213 3211 50 33     10843 $self->throw("Argument [$arg] must be a Bio::SeqFeatureI")
214             unless (ref($arg) && $arg->isa("Bio::SeqFeatureI"));
215 3211         4550 $self->{'feature2'} = $arg;
216             }
217 15238         30242 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 5588     5588 1 8398 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 5574     5574 1 7825 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 132 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 4130 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 6446 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 43 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 8544     8544 1 11866 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 2441     2441 0 3225 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 3371 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 3603 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 4 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         3 my $tmp = $self->feature1;
512            
513 1         3 $self->feature1($self->feature2);
514 1         3 $self->feature2($tmp);
515 1         4 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 11599     11599 1 12419 my $self = shift;
542              
543 11599 100       20922 return $self->{'feature_factory'} = shift if @_;
544 7483         14056 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 4116     4116 0 4923 my $self = shift;
561 4116         11762 $self->{'feature1'} = $self->{'feature2'} = undef;
562             }
563             1;