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
;
93 use vars
qw($AUTOLOAD);
97 use Bio::Factory::ObjectFactory;
99 use base qw(Bio::SeqFeature::Generic);
105 Function: Constructor for this module. Accepts the following parameters:
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.
123 my ($class, @args) = @_;
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).
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.
140 # I'm happy to hear a better solution, but I think this one isn't so bad.
142 my $self = $class->SUPER::new
();
143 my ($feature1,$feature2,$featfact) =
144 $self->_rearrange([qw( FEATURE1
146 FEATURE_FACTORY )],@args);
148 $self->_register_for_cleanup(\
&cleanup_fp
);
149 # initialize the feature object factory if not provided
151 $featfact = Bio
::Factory
::ObjectFactory
->new(
152 -type
=> "Bio::SeqFeature::Generic",
153 -interface
=> "Bio::SeqFeatureI"
156 $self->feature_factory($featfact);
157 # Store the features in the object
158 $feature1 && $self->feature1($feature1);
159 $feature2 && $self->feature2($feature2);
161 # OK. Now we're setup to store all the attributes, and they'll go right
162 # away into the right objects.
163 $self->set_attributes(@args);
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
182 my ($self,$arg) = @_;
183 if ( defined($arg) || !defined $self->{'feature1'} ) {
184 $self->throw("internal error: feature factory not set!")
185 unless $self->feature_factory;
186 $arg = $self->feature_factory->create_object() unless( defined $arg);
187 $self->throw("Argument [$arg] must be a Bio::SeqFeatureI")
188 unless (ref($arg) && $arg->isa("Bio::SeqFeatureI"));
189 $self->{'feature1'} = $arg;
191 return $self->{'feature1'};
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
207 my ($self,$arg) = @_;
209 if ( defined($arg) || ! defined $self->{'feature2'}) {
210 $self->throw("internal error: feature factory not set!")
211 unless $self->feature_factory;
212 $arg = $self->feature_factory->create_object() unless( defined $arg);
213 $self->throw("Argument [$arg] must be a Bio::SeqFeatureI")
214 unless (ref($arg) && $arg->isa("Bio::SeqFeatureI"));
215 $self->{'feature2'} = $arg;
217 return $self->{'feature2'};
223 Usage : $start = $featpair->start
225 Function: Get/set on the start coordinate of feature1
227 Args : [optional] beginning of feature
232 return shift->feature1->start(@_);
238 Usage : $end = $featpair->end
240 Function: get/set on the end coordinate of feature1
242 Args : [optional] ending point of feature
248 return shift->feature1->end(@_);
254 Usage : $strand = $feat->strand()
255 $feat->strand($strand)
256 Function: get/set on strand information, being 1,-1 or 0
258 Args : [optional] strand information to set
264 return shift->feature1->strand(@_);
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
279 return shift->feature1->location(@_);
285 Usage : $score = $feat->score()
287 Function: get/set on score information
289 Args : none if get, the new value if set
295 return shift->feature1->score(@_);
301 Usage : $frame = $feat->frame()
303 Function: get/set on frame information
305 Args : none if get, the new value if set
311 return shift->feature1->frame(@_);
317 Usage : $ptag = $featpair->primary_tag
318 Function: get/set on the primary_tag of feature1
320 Args : none if get, the new value if set
326 return shift->feature1->primary_tag(@_);
332 Usage : $tag = $feat->source_tag()
333 $feat->source_tag('genscan');
334 Function: Returns the source tag for a feature,
343 return shift->feature1->source_tag(@_);
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
355 This attribute should *not* be used in GFF dumping, as
356 that should come from the collection in which the seq
358 Returns : value of seqname
359 Args : newvalue (optional)
365 return shift->feature1->seq_id(@_);
371 Usage : $featpair->hseqname($newval)
372 Function: Get/set method for the name of
374 Returns : value of $feature2->seq_id
375 Args : newvalue (optional)
381 return shift->feature2->seq_id(@_);
388 Usage : $start = $featpair->hstart
389 $featpair->hstart(20)
390 Function: Get/set on the start coordinate of feature2
397 return shift->feature2->start(@_);
403 Usage : $end = $featpair->hend
404 $featpair->hend($end)
405 Function: get/set on the end coordinate of feature2
413 return shift->feature2->end(@_);
420 Usage : $strand = $feat->strand()
421 $feat->strand($strand)
422 Function: get/set on strand information, being 1,-1 or 0
430 return shift->feature2->strand(@_);
436 Usage : $score = $feat->score()
438 Function: get/set on score information
440 Args : none if get, the new value if set
446 return shift->feature2->score(@_);
452 Usage : $frame = $feat->frame()
454 Function: get/set on frame information
456 Args : none if get, the new value if set
462 return shift->feature2->frame(@_);
468 Usage : $ptag = $featpair->hprimary_tag
469 Function: Get/set on the primary_tag of feature2
471 Args : none if get, the new value if set
477 return shift->feature2->primary_tag(@_);
483 Usage : $tag = $feat->hsource_tag()
484 $feat->source_tag('genscan');
485 Function: Returns the source tag for a feature,
494 return shift->feature2->source_tag(@_);
500 Usage : $tag = $feat->invert
501 Function: Swaps feature1 and feature2 around
511 my $tmp = $self->feature1;
513 $self->feature1($self->feature2);
514 $self->feature2($tmp);
518 =head2 feature_factory
520 Title : feature_factory
521 Usage : $obj->feature_factory($newval)
522 Function: Get/set the feature object factory for this feature pair.
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.
528 The default is an instance of Bio::Factory::ObjectFactory
529 and hence allows the type to be changed dynamically at any
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
540 sub feature_factory
{
543 return $self->{'feature_factory'} = shift if @_;
544 return $self->{'feature_factory'};
547 #################################################################
548 # aliases for backwards compatibility #
549 #################################################################
551 # seqname() is already aliased in Generic.pm, and we overwrite seq_id
555 $self->warn("SeqFeatureI::seqname() is deprecated. Please use seq_id() instead.");
556 return $self->hseq_id(@_);
561 $self->{'feature1'} = $self->{'feature2'} = undef;