2 # BioPerl module for Bio::Location::Atomic
3 # Please direct questions and support issues to <bioperl-l@bioperl.org>
5 # Cared for by Jason Stajich <jason@bioperl.org>
7 # Copyright Jason Stajich
9 # You may distribute this module under the same terms as perl itself
10 # POD documentation - main docs before the code
14 Bio::Location::Atomic - Implementation of a Atomic Location on a Sequence
18 use Bio::Location::Atomic;
20 my $location = Bio::Location::Atomic->new(-start => 1, -end => 100,
23 if( $location->strand == -1 ) {
24 printf "complement(%d..%d)\n", $location->start, $location->end;
26 printf "%d..%d\n", $location->start, $location->end;
31 This is an implementation of Bio::LocationI to manage simple location
32 information on a Sequence.
36 User feedback is an integral part of the evolution of this and other
37 Bioperl modules. Send your comments and suggestions preferably to one
38 of the Bioperl mailing lists. Your participation is much appreciated.
40 bioperl-l@bioperl.org - General discussion
41 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
45 Please direct usage questions or support issues to the mailing list:
47 I<bioperl-l@bioperl.org>
49 rather than to the module maintainer directly. Many experienced and
50 reponsive experts will be able look at the problem and quickly
51 address it. Please include a thorough description of the problem
52 with code and data examples if at all possible.
56 Report bugs to the Bioperl bug tracking system to help us keep track
57 the bugs and their resolution. Bug reports can be submitted via the
60 https://github.com/bioperl/bioperl-live/issues
62 =head1 AUTHOR - Jason Stajich
64 Email jason-at-bioperl-dot-org
68 The rest of the documentation details each of the object
69 methods. Internal methods are usually preceded with a _
73 # Let the code begin...
76 package Bio
::Location
::Atomic
;
79 use Bio
::Location
::WidestCoordPolicy
;
81 use base
qw(Bio::Root::Root Bio::LocationI);
83 our $coord_policy = Bio
::Location
::WidestCoordPolicy
->new();
86 my ($class, @args) = @_;
87 $class = ref $class || $class;
89 # This is for the case when we've done something like this
90 # get a 2 features from somewhere (like Bio::Tools::GFF)
92 # my $location = $f1->location->union($f2->location);
93 # We get an error without the following code which
94 # explicitly loads the Bio::Location::Simple class
95 unless( $class->can('start') ) {
96 eval { Bio
::Root
::Root
->_load_module($class) };
98 Bio
::Root
::Root
->throw("$class cannot be found\nException $@");
103 my ($v,$start,$end,$strand,$seqid) = $self->_rearrange([qw(VERBOSE
108 defined $v && $self->verbose($v);
109 defined $strand && $self->strand($strand);
111 defined $start && $self->start($start);
112 defined $end && $self->end($end);
113 if( defined $self->start && defined $self->end &&
114 $self->start > $self->end && $self->strand != -1 ) {
115 $self->warn("When building a location, start ($start) is expected to be less than end ($end), ".
116 "however it was not. Switching start and end and setting strand to -1");
120 my $s = $self->start;
124 $seqid && $self->seq_id($seqid);
132 Usage : $start = $loc->start();
133 Function: get/set the start of this range
134 Returns : the start of this range
135 Args : optionally allows the start to be set
136 : using $loc->start($start)
141 my ($self, $value) = @_;
142 $self->min_start($value) if( defined $value );
143 return $self->SUPER::start
();
149 Usage : $end = $loc->end();
150 Function: get/set the end of this range
151 Returns : the end of this range
152 Args : optionally allows the end to be set
153 : using $loc->end($start)
158 my ($self, $value) = @_;
160 $self->min_end($value) if( defined $value );
161 return $self->SUPER::end
();
167 Usage : $strand = $loc->strand();
168 Function: get/set the strand of this range
169 Returns : the strandidness (-1, 0, +1)
170 Args : optionally allows the strand to be set
171 : using $loc->strand($strand)
180 if ( defined($value) ) {
181 if ( $value eq '+' ) { $value = 1; }
182 elsif ( $value eq '-' ) { $value = -1; }
183 elsif ( $value eq '.' ) { $value = 0; }
184 elsif ( $value != -1 && $value != 1 && $value != 0 ) {
185 $self->throw("$value is not a valid strand info");
187 $self->{'_strand'} = $value;
190 # do not pretend the strand has been set if in fact it wasn't
191 return $self->{'_strand'};
192 #return $self->{'_strand'} || 0;
198 Usage : $location->flip_strand();
199 Function: Flip-flop a strand to the opposite
208 # Initialize strand if necessary to flip it
209 if (not defined $self->strand) {
212 $self->strand($self->strand * -1);
219 Usage : my $seqid = $location->seq_id();
220 Function: Get/Set seq_id that location refers to
221 Returns : seq_id (a string)
222 Args : [optional] seq_id value to set
228 my ($self, $seqid) = @_;
229 if( defined $seqid ) {
230 $self->{'_seqid'} = $seqid;
232 return $self->{'_seqid'};
238 Usage : $len = $loc->length();
239 Function: get the length in the coordinate space this location spans
249 return abs($self->end() - $self->start()) + 1;
255 Usage : my $minstart = $location->min_start();
256 Function: Get minimum starting location of feature startpoint
257 Returns : integer or undef if no minimum starting point.
263 my ($self,$value) = @_;
265 if(defined($value)) {
266 $self->{'_start'} = $value;
268 return $self->{'_start'};
274 Usage : my $maxstart = $location->max_start();
275 Function: Get maximum starting location of feature startpoint.
277 In this implementation this is exactly the same as min_start().
279 Returns : integer or undef if no maximum starting point.
285 my ($self,@args) = @_;
286 return $self->min_start(@args);
289 =head2 start_pos_type
291 Title : start_pos_type
292 Usage : my $start_pos_type = $location->start_pos_type();
293 Function: Get start position type (ie <,>, ^).
295 In this implementation this will always be 'EXACT'.
297 Returns : type of position coded as text
298 ('BEFORE', 'AFTER', 'EXACT','WITHIN', 'BETWEEN')
311 Usage : my $minend = $location->min_end();
312 Function: Get minimum ending location of feature endpoint
313 Returns : integer or undef if no minimum ending point.
319 my($self,$value) = @_;
321 if(defined($value)) {
322 $self->{'_end'} = $value;
324 return $self->{'_end'};
330 Usage : my $maxend = $location->max_end();
331 Function: Get maximum ending location of feature endpoint
333 In this implementation this is exactly the same as min_end().
335 Returns : integer or undef if no maximum ending point.
341 my($self,@args) = @_;
342 return $self->min_end(@args);
348 Usage : my $end_pos_type = $location->end_pos_type();
349 Function: Get end position type (ie <,>, ^)
351 In this implementation this will always be 'EXACT'.
353 Returns : type of position coded as text
354 ('BEFORE', 'AFTER', 'EXACT','WITHIN', 'BETWEEN')
366 Title : location_type
367 Usage : my $location_type = $location->location_type();
368 Function: Get location type encoded as text
369 Returns : string ('EXACT', 'WITHIN', 'IN-BETWEEN')
382 Usage : $is_remote_loc = $loc->is_remote()
383 Function: Whether or not a location is a remote location.
385 A location is said to be remote if it is on a different
386 'object' than the object which 'has' this
387 location. Typically, features on a sequence will sometimes
388 have a remote location, which means that the location of
389 the feature is on a different sequence than the one that is
390 attached to the feature. In such a case, $loc->seq_id will
391 be different from $feat->seq_id (usually they will be the
394 While this may sound weird, it reflects the location of the
395 kind of AL445212.9:83662..166657 which can be found in GenBank/EMBL
399 Returns : TRUE if the location is a remote location, and FALSE otherwise
400 Args : Value to set to
408 $self->{'is_remote'} = $value;
410 return $self->{'is_remote'};
415 Title : each_Location
416 Usage : @locations = $locObject->each_Location($order);
417 Function: Conserved function call across Location:: modules - will
418 return an array containing the component Location(s) in
419 that object, regardless if the calling object is itself a
420 single location or one containing sublocations.
421 Returns : an array of Bio::LocationI implementing objects - for
422 Simple locations, the return value is just itself.
435 Usage : my $locstr = $location->to_FTstring()
436 Function: returns the FeatureTable string of this location
444 if( $self->start == $self->end ) {
447 my $str = $self->start . ".." . $self->end;
448 if( $self->strand == -1 ) {
449 $str = sprintf("complement(%s)", $str);
454 =head2 valid_Location
456 Title : valid_Location
457 Usage : if ($location->valid_location) {...};
458 Function: boolean method to determine whether location is considered valid
459 (has minimum requirements for Simple implementation)
460 Returns : Boolean value: true if location is valid, false otherwise
467 return 1 if $self->{'_start'} && $self->{'_end'};
471 =head2 coordinate_policy
473 Title : coordinate_policy
474 Usage : $policy = $location->coordinate_policy();
475 $location->coordinate_policy($mypolicy); # set may not be possible
476 Function: Get the coordinate computing policy employed by this object.
478 See L<Bio::Location::CoordinatePolicyI> for documentation
479 about the policy object and its use.
481 The interface *does not* require implementing classes to
482 accept setting of a different policy. The implementation
483 provided here does, however, allow one to do so.
485 Implementors of this interface are expected to initialize
486 every new instance with a
487 L<Bio::Location::CoordinatePolicyI> object. The
488 implementation provided here will return a default policy
489 object if none has been set yet. To change this default
490 policy object call this method as a class method with an
491 appropriate argument. Note that in this case only
492 subsequently created Location objects will be affected.
494 Returns : A L<Bio::Location::CoordinatePolicyI> implementing object.
495 Args : On set, a L<Bio::Location::CoordinatePolicyI> implementing object.
497 See L<Bio::Location::CoordinatePolicyI> for more information
502 sub coordinate_policy
{
503 my ($self, $policy) = @_;
505 if(defined($policy)) {
506 if(! $policy->isa('Bio::Location::CoordinatePolicyI')) {
507 $self->throw("Object of class ".ref($policy)." does not implement".
508 " Bio::Location::CoordinatePolicyI");
511 $self->{'_coordpolicy'} = $policy;
513 # called as class method
514 $coord_policy = $policy;
517 return (ref($self) && exists($self->{'_coordpolicy'}) ?
518 $self->{'_coordpolicy'} : $coord_policy);
524 Usage : $trunc_location = $location->trunc($start, $end, $relative_ori);
525 Function: To truncate a location and keep annotations and features
526 within the truncated segment intact.
528 This might do things differently where the truncation
529 splits the location in half.
530 CAVEAT : As yet, this is an untested and unannounced method. Use
532 Returns : A L<Bio::Location::Atomic> object.
533 Args : The start and end position for the trunction, and the relative
539 my ($self,$start,$end,$relative_ori) = @_;
541 my $newstart = $self->start - $start+1;
542 my $newend = $self->end - $start+1;
543 my $newstrand = $relative_ori * $self->strand;
546 if( $newstart < 1 || $newend > ($end-$start+1) ) {
547 $out = Bio
::Location
::Atomic
->new();
548 $out->start($self->start);
549 $out->end($self->end);
550 $out->strand($self->strand);
551 $out->seq_id($self->seqid);
554 $out = Bio
::Location
::Atomic
->new();
555 $out->start($newstart);
557 $out->strand($newstrand);