2 # BioPerl module for Bio::SeqFeature::FeaturePair
4 # Please direct questions and support issues to <bioperl-l@bioperl.org>
6 # Cared for by Ewan Birney <birney@sanger.ac.uk>
8 # Copyright Ewan Birney
10 # You may distribute this module under the same terms as perl itself
12 # POD documentation - main docs before the code
16 Bio::SeqFeature::FeaturePair - hold pair feature information e.g. blast hits
20 my $feat = Bio::SeqFeature::FeaturePair->new(
25 # Bio::SeqFeatureI methods can be used
27 my $start = $feat->start;
30 # Bio::FeaturePair methods can be used
31 my $hstart = $feat->hstart;
32 my $hend = $feat->hend;
34 my $feature1 = $feat->feature1; # returns feature1 object
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
45 my $fp = Bio::SeqFeature::FeaturePair->new(
46 -feature1 => $f1, # genomic
47 -feature2 => $f2, # protein
50 This object can be used as a standard Bio::SeqFeatureI in which case
52 my $gstart = $fp->start # returns start coord on feature1 - genomic seq.
53 my $gend = $fp->end # returns end coord on feature1.
55 In general standard Bio::SeqFeatureI method calls return information
58 Data in the feature 2 object are generally obtained using the standard
59 methods prefixed by h (for hit!)
61 my $pstart = $fp->hstart # returns start coord on feature2 = protein seq.
62 my $pend = $fp->hend # returns end coord on feature2.
64 If you wish to swap feature1 and feature2 around :
70 $feat->start # etc. returns data in $feature2 object
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.
79 Ewan Birney E<lt>birney@sanger.ac.ukE<gt>
83 The rest of the documentation details each of the object
84 methods. Internal methods are usually preceded with a _
89 # Let the code begin...
92 package Bio
::SeqFeature
::FeaturePair
;
94 use vars
qw($AUTOLOAD);
98 use Bio::Factory::ObjectFactory;
100 use base qw(Bio::SeqFeature::Generic);
106 Function: Constructor for this module. Accepts the following parameters:
108 -feature1 Bio::SeqFeatureI-compliant object
109 -feature2 Bio::SeqFeatureI-compliant object
110 -feature_factory Bio::Factory::ObjectFactoryI compliant
111 object to be used when feature1 and/or feature2
112 are accessed without explicitly set before. This
113 is mostly useful for derived classes who want to
114 set their preferred class for feature objects.
124 my ($class, @args) = @_;
127 # We've got a certain problem here that somewhat relates to chicken and
128 # eggs. The problem is, we override a lot of SeqFeatureI methods here
129 # to delegate them to either feature1 or feature2. If we pass along
130 # those attributes right away, we need feature1 or feature2 or the feature
131 # factory in place, or there is no way around the dreaded default, which
132 # is ugly too (as it necessitates subsequent copying if you wanted a
133 # different feature object class).
135 # So I decided to go with the lesser of two evils here: we need to assume
136 # here that we can set all attributes through set_attributes(), which we
137 # assume is no different from setting them through the constructor. This
138 # gives us a window to set the feature objects and the factory, such that
139 # any derived class doesn't have to worry about this any more.
141 # I'm happy to hear a better solution, but I think this one isn't so bad.
143 my $self = $class->SUPER::new
();
144 my ($feature1,$feature2,$featfact) =
145 $self->_rearrange([qw( FEATURE1
147 FEATURE_FACTORY )],@args);
149 $self->_register_for_cleanup(\
&cleanup_fp
);
150 # initialize the feature object factory if not provided
152 $featfact = Bio
::Factory
::ObjectFactory
->new(
153 -type
=> "Bio::SeqFeature::Generic",
154 -interface
=> "Bio::SeqFeatureI"
157 $self->feature_factory($featfact);
158 # Store the features in the object
159 $feature1 && $self->feature1($feature1);
160 $feature2 && $self->feature2($feature2);
162 # OK. Now we're setup to store all the attributes, and they'll go right
163 # away into the right objects.
164 $self->set_attributes(@args);
173 Usage : $f = $featpair->feature1
174 $featpair->feature1($feature)
175 Function: Get/set for the query feature
176 Returns : Bio::SeqFeatureI
177 Args : Bio::SeqFeatureI
183 my ($self,$arg) = @_;
184 if ( defined($arg) || !defined $self->{'feature1'} ) {
185 $self->throw("internal error: feature factory not set!")
186 unless $self->feature_factory;
187 $arg = $self->feature_factory->create_object() unless( defined $arg);
188 $self->throw("Argument [$arg] must be a Bio::SeqFeatureI")
189 unless (ref($arg) && $arg->isa("Bio::SeqFeatureI"));
190 $self->{'feature1'} = $arg;
192 return $self->{'feature1'};
198 Usage : $f = $featpair->feature2
199 $featpair->feature2($feature)
200 Function: Get/set for the hit feature
201 Returns : Bio::SeqFeatureI
202 Args : Bio::SeqFeatureI
208 my ($self,$arg) = @_;
210 if ( defined($arg) || ! defined $self->{'feature2'}) {
211 $self->throw("internal error: feature factory not set!")
212 unless $self->feature_factory;
213 $arg = $self->feature_factory->create_object() unless( defined $arg);
214 $self->throw("Argument [$arg] must be a Bio::SeqFeatureI")
215 unless (ref($arg) && $arg->isa("Bio::SeqFeatureI"));
216 $self->{'feature2'} = $arg;
218 return $self->{'feature2'};
224 Usage : $start = $featpair->start
226 Function: Get/set on the start coordinate of feature1
228 Args : [optional] beginning of feature
233 return shift->feature1->start(@_);
239 Usage : $end = $featpair->end
241 Function: get/set on the end coordinate of feature1
243 Args : [optional] ending point of feature
249 return shift->feature1->end(@_);
255 Usage : $strand = $feat->strand()
256 $feat->strand($strand)
257 Function: get/set on strand information, being 1,-1 or 0
259 Args : [optional] strand information to set
265 return shift->feature1->strand(@_);
271 Usage : $location = $featpair->location
272 $featpair->location($location)
273 Function: Get/set location object (using feature1)
274 Returns : Bio::LocationI object
275 Args : [optional] LocationI to store
280 return shift->feature1->location(@_);
286 Usage : $score = $feat->score()
288 Function: get/set on score information
290 Args : none if get, the new value if set
296 return shift->feature1->score(@_);
302 Usage : $frame = $feat->frame()
304 Function: get/set on frame information
306 Args : none if get, the new value if set
312 return shift->feature1->frame(@_);
318 Usage : $ptag = $featpair->primary_tag
319 Function: get/set on the primary_tag of feature1
321 Args : none if get, the new value if set
327 return shift->feature1->primary_tag(@_);
333 Usage : $tag = $feat->source_tag()
334 $feat->source_tag('genscan');
335 Function: Returns the source tag for a feature,
344 return shift->feature1->source_tag(@_);
350 Usage : $obj->seq_id($newval)
351 Function: There are many cases when you make a feature that you
352 do know the sequence name, but do not know its actual
353 sequence. This is an attribute such that you can store
356 This attribute should *not* be used in GFF dumping, as
357 that should come from the collection in which the seq
359 Returns : value of seqname
360 Args : newvalue (optional)
366 return shift->feature1->seq_id(@_);
372 Usage : $featpair->hseqname($newval)
373 Function: Get/set method for the name of
375 Returns : value of $feature2->seq_id
376 Args : newvalue (optional)
382 return shift->feature2->seq_id(@_);
389 Usage : $start = $featpair->hstart
390 $featpair->hstart(20)
391 Function: Get/set on the start coordinate of feature2
398 return shift->feature2->start(@_);
404 Usage : $end = $featpair->hend
405 $featpair->hend($end)
406 Function: get/set on the end coordinate of feature2
414 return shift->feature2->end(@_);
421 Usage : $strand = $feat->strand()
422 $feat->strand($strand)
423 Function: get/set on strand information, being 1,-1 or 0
431 return shift->feature2->strand(@_);
437 Usage : $score = $feat->score()
439 Function: get/set on score information
441 Args : none if get, the new value if set
447 return shift->feature2->score(@_);
453 Usage : $frame = $feat->frame()
455 Function: get/set on frame information
457 Args : none if get, the new value if set
463 return shift->feature2->frame(@_);
469 Usage : $ptag = $featpair->hprimary_tag
470 Function: Get/set on the primary_tag of feature2
472 Args : none if get, the new value if set
478 return shift->feature2->primary_tag(@_);
484 Usage : $tag = $feat->hsource_tag()
485 $feat->source_tag('genscan');
486 Function: Returns the source tag for a feature,
495 return shift->feature2->source_tag(@_);
501 Usage : $tag = $feat->invert
502 Function: Swaps feature1 and feature2 around
512 my $tmp = $self->feature1;
514 $self->feature1($self->feature2);
515 $self->feature2($tmp);
519 =head2 feature_factory
521 Title : feature_factory
522 Usage : $obj->feature_factory($newval)
523 Function: Get/set the feature object factory for this feature pair.
525 The feature object factory will be used to create a feature
526 object if feature1() or feature2() is called in get mode
527 without having been set before.
529 The default is an instance of Bio::Factory::ObjectFactory
530 and hence allows the type to be changed dynamically at any
534 Returns : The feature object factory in use (a
535 Bio::Factory::ObjectFactoryI compliant object)
536 Args : on set, a Bio::Factory::ObjectFactoryI compliant object
541 sub feature_factory
{
544 return $self->{'feature_factory'} = shift if @_;
545 return $self->{'feature_factory'};
548 #################################################################
549 # aliases for backwards compatibility #
550 #################################################################
552 # seqname() is already aliased in Generic.pm, and we overwrite seq_id
556 $self->warn("SeqFeatureI::seqname() is deprecated. Please use seq_id() instead.");
557 return $self->hseq_id(@_);
562 $self->{'feature1'} = $self->{'feature2'} = undef;