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
;
80 use Bio
::Location
::WidestCoordPolicy
;
82 use base
qw(Bio::Root::Root Bio::LocationI);
84 our $coord_policy = Bio
::Location
::WidestCoordPolicy
->new();
87 my ($class, @args) = @_;
88 $class = ref $class || $class;
90 # This is for the case when we've done something like this
91 # get a 2 features from somewhere (like Bio::Tools::GFF)
93 # my $location = $f1->location->union($f2->location);
94 # We get an error without the following code which
95 # explicitly loads the Bio::Location::Simple class
96 unless( $class->can('start') ) {
97 eval { Bio
::Root
::Root
->_load_module($class) };
99 Bio
::Root
::Root
->throw("$class cannot be found\nException $@");
104 my ($v,$start,$end,$strand,$seqid) = $self->_rearrange([qw(VERBOSE
109 defined $v && $self->verbose($v);
110 defined $strand && $self->strand($strand);
112 defined $start && $self->start($start);
113 defined $end && $self->end($end);
114 if( defined $self->start && defined $self->end &&
115 $self->start > $self->end && $self->strand != -1 ) {
116 $self->warn("When building a location, start ($start) is expected to be less than end ($end), ".
117 "however it was not. Switching start and end and setting strand to -1");
121 my $s = $self->start;
125 $seqid && $self->seq_id($seqid);
133 Usage : $start = $loc->start();
134 Function: get/set the start of this range
135 Returns : the start of this range
136 Args : optionally allows the start to be set
137 : using $loc->start($start)
142 my ($self, $value) = @_;
143 $self->min_start($value) if( defined $value );
144 return $self->SUPER::start
();
150 Usage : $end = $loc->end();
151 Function: get/set the end of this range
152 Returns : the end of this range
153 Args : optionally allows the end to be set
154 : using $loc->end($start)
159 my ($self, $value) = @_;
161 $self->min_end($value) if( defined $value );
162 return $self->SUPER::end
();
168 Usage : $strand = $loc->strand();
169 Function: get/set the strand of this range
170 Returns : the strandidness (-1, 0, +1)
171 Args : optionally allows the strand to be set
172 : using $loc->strand($strand)
181 if ( defined($value) ) {
182 if ( $value eq '+' ) { $value = 1; }
183 elsif ( $value eq '-' ) { $value = -1; }
184 elsif ( $value eq '.' ) { $value = 0; }
185 elsif ( $value != -1 && $value != 1 && $value != 0 ) {
186 $self->throw("$value is not a valid strand info");
188 $self->{'_strand'} = $value;
191 # do not pretend the strand has been set if in fact it wasn't
192 return $self->{'_strand'};
193 #return $self->{'_strand'} || 0;
199 Usage : $location->flip_strand();
200 Function: Flip-flop a strand to the opposite
209 # Initialize strand if necessary to flip it
210 if (not defined $self->strand) {
213 $self->strand($self->strand * -1);
220 Usage : my $seqid = $location->seq_id();
221 Function: Get/Set seq_id that location refers to
222 Returns : seq_id (a string)
223 Args : [optional] seq_id value to set
229 my ($self, $seqid) = @_;
230 if( defined $seqid ) {
231 $self->{'_seqid'} = $seqid;
233 return $self->{'_seqid'};
239 Usage : $len = $loc->length();
240 Function: get the length in the coordinate space this location spans
250 return abs($self->end() - $self->start()) + 1;
256 Usage : my $minstart = $location->min_start();
257 Function: Get minimum starting location of feature startpoint
258 Returns : integer or undef if no minimum starting point.
264 my ($self,$value) = @_;
266 if(defined($value)) {
267 $self->{'_start'} = $value;
269 return $self->{'_start'};
275 Usage : my $maxstart = $location->max_start();
276 Function: Get maximum starting location of feature startpoint.
278 In this implementation this is exactly the same as min_start().
280 Returns : integer or undef if no maximum starting point.
286 my ($self,@args) = @_;
287 return $self->min_start(@args);
290 =head2 start_pos_type
292 Title : start_pos_type
293 Usage : my $start_pos_type = $location->start_pos_type();
294 Function: Get start position type (ie <,>, ^).
296 In this implementation this will always be 'EXACT'.
298 Returns : type of position coded as text
299 ('BEFORE', 'AFTER', 'EXACT','WITHIN', 'BETWEEN')
312 Usage : my $minend = $location->min_end();
313 Function: Get minimum ending location of feature endpoint
314 Returns : integer or undef if no minimum ending point.
320 my($self,$value) = @_;
322 if(defined($value)) {
323 $self->{'_end'} = $value;
325 return $self->{'_end'};
331 Usage : my $maxend = $location->max_end();
332 Function: Get maximum ending location of feature endpoint
334 In this implementation this is exactly the same as min_end().
336 Returns : integer or undef if no maximum ending point.
342 my($self,@args) = @_;
343 return $self->min_end(@args);
349 Usage : my $end_pos_type = $location->end_pos_type();
350 Function: Get end position type (ie <,>, ^)
352 In this implementation this will always be 'EXACT'.
354 Returns : type of position coded as text
355 ('BEFORE', 'AFTER', 'EXACT','WITHIN', 'BETWEEN')
367 Title : location_type
368 Usage : my $location_type = $location->location_type();
369 Function: Get location type encoded as text
370 Returns : string ('EXACT', 'WITHIN', 'IN-BETWEEN')
383 Usage : $is_remote_loc = $loc->is_remote()
384 Function: Whether or not a location is a remote location.
386 A location is said to be remote if it is on a different
387 'object' than the object which 'has' this
388 location. Typically, features on a sequence will sometimes
389 have a remote location, which means that the location of
390 the feature is on a different sequence than the one that is
391 attached to the feature. In such a case, $loc->seq_id will
392 be different from $feat->seq_id (usually they will be the
395 While this may sound weird, it reflects the location of the
396 kind of AL445212.9:83662..166657 which can be found in GenBank/EMBL
400 Returns : TRUE if the location is a remote location, and FALSE otherwise
401 Args : Value to set to
409 $self->{'is_remote'} = $value;
411 return $self->{'is_remote'};
416 Title : each_Location
417 Usage : @locations = $locObject->each_Location($order);
418 Function: Conserved function call across Location:: modules - will
419 return an array containing the component Location(s) in
420 that object, regardless if the calling object is itself a
421 single location or one containing sublocations.
422 Returns : an array of Bio::LocationI implementing objects - for
423 Simple locations, the return value is just itself.
436 Usage : my $locstr = $location->to_FTstring()
437 Function: returns the FeatureTable string of this location
445 if( $self->start == $self->end ) {
448 my $str = $self->start . ".." . $self->end;
449 if( $self->strand == -1 ) {
450 $str = sprintf("complement(%s)", $str);
455 =head2 valid_Location
457 Title : valid_Location
458 Usage : if ($location->valid_location) {...};
459 Function: boolean method to determine whether location is considered valid
460 (has minimum requirements for Simple implementation)
461 Returns : Boolean value: true if location is valid, false otherwise
468 return 1 if $self->{'_start'} && $self->{'_end'};
472 =head2 coordinate_policy
474 Title : coordinate_policy
475 Usage : $policy = $location->coordinate_policy();
476 $location->coordinate_policy($mypolicy); # set may not be possible
477 Function: Get the coordinate computing policy employed by this object.
479 See L<Bio::Location::CoordinatePolicyI> for documentation
480 about the policy object and its use.
482 The interface *does not* require implementing classes to
483 accept setting of a different policy. The implementation
484 provided here does, however, allow one to do so.
486 Implementors of this interface are expected to initialize
487 every new instance with a
488 L<Bio::Location::CoordinatePolicyI> object. The
489 implementation provided here will return a default policy
490 object if none has been set yet. To change this default
491 policy object call this method as a class method with an
492 appropriate argument. Note that in this case only
493 subsequently created Location objects will be affected.
495 Returns : A L<Bio::Location::CoordinatePolicyI> implementing object.
496 Args : On set, a L<Bio::Location::CoordinatePolicyI> implementing object.
498 See L<Bio::Location::CoordinatePolicyI> for more information
503 sub coordinate_policy
{
504 my ($self, $policy) = @_;
506 if(defined($policy)) {
507 if(! $policy->isa('Bio::Location::CoordinatePolicyI')) {
508 $self->throw("Object of class ".ref($policy)." does not implement".
509 " Bio::Location::CoordinatePolicyI");
512 $self->{'_coordpolicy'} = $policy;
514 # called as class method
515 $coord_policy = $policy;
518 return (ref($self) && exists($self->{'_coordpolicy'}) ?
519 $self->{'_coordpolicy'} : $coord_policy);
525 Usage : $trunc_location = $location->trunc($start, $end, $relative_ori);
526 Function: To truncate a location and keep annotations and features
527 within the truncated segment intact.
529 This might do things differently where the truncation
530 splits the location in half.
531 CAVEAT : As yet, this is an untested and unannounced method. Use
533 Returns : A L<Bio::Location::Atomic> object.
534 Args : The start and end position for the trunction, and the relative
540 my ($self,$start,$end,$relative_ori) = @_;
542 my $newstart = $self->start - $start+1;
543 my $newend = $self->end - $start+1;
544 my $newstrand = $relative_ori * $self->strand;
547 if( $newstart < 1 || $newend > ($end-$start+1) ) {
548 $out = Bio
::Location
::Atomic
->new();
549 $out->start($self->start);
550 $out->end($self->end);
551 $out->strand($self->strand);
552 $out->seq_id($self->seqid);
555 $out = Bio
::Location
::Atomic
->new();
556 $out->start($newstart);
558 $out->strand($newstrand);