3 # BioPerl module for Bio::Map::Relative
5 # Cared for by Sendu Bala <bix@sendu.me.uk>
9 # You may distribute this module under the same terms as perl itself
11 # POD documentation - main docs before the code
15 Bio::Map::Relative - Represents what a Position's coordiantes are relative to.
19 # Get a Bio::Map::PositionI somehow
20 my $pos = Bio::Map::Position->new(-value => 100);
22 # its co-ordinates are implicitly relative to the start of its map
23 my $implicit_relative = $pos->relative;
24 my $type = $implicit_relative->type; # $type eq 'map'
25 my $value = $implicit_relative->$type(); # $value == 0
27 # make its co-ordinates relative to another Position
28 my $pos_we_are_relative_to = Bio::Map::Position->new(-value => 200);
29 my $relative = Bio::Map::Relative->new(-position => $pos_we_are_relative_to);
30 $pos->relative($relative);
32 # Get the start co-ordinate of $pos relative to $pos_we_are_relative_to
33 my $start = $pos->start; # $start == 100
35 # Get the start co-ordinate of $pos relative to the start of the map
36 my $abs_start = $relative->absolute_conversion($pos); # $abs_start == 300
39 my $abs_start = $pos->start; # $abs_start == 300
42 # Get the start co-ordinate of $pos relative to a third Position
43 my $pos_frame_of_reference = Bio::Map::Position->new(-value => 10);
44 my $relative2 = Bio::Map::Relative->new(-position => $pos_frame_of_reference);
45 my $start = $pos->start($relative2); # $start == 290
49 A Relative object is used to describe what the co-ordinates (numerical(),
50 start(), end()) of a Position are relative to. By default they are
51 implicitly assumed to be relative to the start of the map the Position is on.
52 But setting the relative() of a Position to one of these objects lets us
59 User feedback is an integral part of the evolution of this and other
60 Bioperl modules. Send your comments and suggestions preferably to
61 the Bioperl mailing list. Your participation is much appreciated.
63 bioperl-l@bioperl.org - General discussion
64 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
68 Report bugs to the Bioperl bug tracking system to help us keep track
69 of the bugs and their resolution. Bug reports can be submitted via the
72 http://bugzilla.open-bio.org/
74 =head1 AUTHOR - Sendu Bala
80 The rest of the documentation details each of the object methods.
81 Internal methods are usually preceded with a _
85 # Let the code begin...
87 package Bio
::Map
::Relative
;
89 use Scalar
::Util
qw(looks_like_number);
91 use base
qw(Bio::Root::Root Bio::Map::RelativeI);
96 Usage : my $relative = Bio::Map::Relative->new();
97 Function: Build a new Bio::Map::Relative object.
98 Returns : Bio::Map::Relative object
99 Args : -map => int : coordinates are relative to this point on the
100 Position's map [default is map => 0, ie.
101 relative to the start of the map],
102 -element => Mappable : or relative to this element's (a
103 Bio::Map::MappableI) position in the map
104 (only works if the given element has only one
105 position in the map the Position belongs to),
106 -position => Position : or relative to this other Position (a
107 Bio::Map::PositionI, fails if the other
108 Position is on a different map to this map)
110 -description => string: Free text description of what this relative
113 (To say a Position is relative to something and upstream of it,
114 the Position's start() co-ordinate should be set negative)
119 my ($class, @args) = @_;
120 my $self = $class->SUPER::new
(@args);
122 my ($map, $element, $position, $desc) =
123 $self->_rearrange([qw( MAP ELEMENT POSITION DESCRIPTION )], @args);
125 if (defined($map) + defined($element) + defined($position) > 1) {
126 $self->throw("-map, -element and -position are mutually exclusive");
129 defined($map) && $self->map($map);
130 $element && $self->element($element);
131 $position && $self->position($position);
132 $desc && $self->description($desc);
137 =head2 absolute_conversion
139 Title : absolute_conversion
140 Usage : my $absolute_coord = $relative->absolute_conversion($pos);
141 Function: Convert the start co-ordinate of the supplied position into a number
142 relative to the start of its map.
143 Returns : scalar number
144 Args : Bio::Map::PositionI object
148 sub absolute_conversion
{
149 my ($self, $pos) = @_;
150 $self->throw("Must supply an object") unless ref($pos);
151 $self->throw("This is [$pos], not a Bio::Map::PositionI") unless $pos->isa('Bio::Map::PositionI');
153 # get the raw start position of our position
154 my $prior_abs = $pos->absolute;
155 $pos->absolute(0) if $prior_abs;
156 my $raw = $pos->start;
157 $pos->absolute($prior_abs) if $prior_abs;
158 $self->throw("Can't convert co-ordinates when start isn't set") unless defined($raw); #*** needed? return undef?
160 # what are we relative to?
161 my $type = $self->type;
162 my $value = $self->$type;
163 $self->throw("Details not yet set for this Relative, cannot convert") unless $type && defined($value);
165 # get the absolute start of the thing we're relative to
167 if ($type eq 'element') {
168 $self->throw("Relative to a Mappable, but the Position has no map") unless $map;
169 my @positions = $value->get_positions($map);
170 $value = shift(@positions);
171 $self->throw("Relative to a Mappable, but this Mappable has no positions on the supplied Position's map") unless $value;
175 my $rel = $value->relative;
176 $value = $rel->absolute_conversion($value);
179 if (defined($value)) {
180 return $value + $raw;
188 Usage : my $type = $relative->type();
189 Function: Get the type of thing we are relative to. The types correspond
190 to a method name, so the value of what we are relative to can
191 subsequently be found by $value = $relative->$type;
193 Note that type is set by the last method that was set, or during
196 Returns : the string 'map', 'element' or 'position', or undef
203 return $self->{_use
} || return;
209 Usage : my $int = $relative->map();
210 $relative->map($int);
211 Function: Get/set the distance from the start of the map that the Position's
212 co-ordiantes are relative to.
214 Args : none to get, OR
215 int to set; a value of 0 means relative to the start of the map.
220 my ($self, $num) = @_;
222 $self->throw("This is [$num], not a number") unless looks_like_number
($num);
223 $self->{_use
} = 'map';
224 $self->{_map
} = $num;
226 return defined($self->{_map
}) ?
$self->{_map
} : return;
232 Usage : my $element = $relative->element();
233 $relative->element($element);
234 Function: Get/set the map element (Mappable) the Position is relative to. If
235 the Mappable has more than one Position on the Position's map, we
236 will be relative to the Mappable's first Position on the map.
237 Returns : Bio::Map::MappableI
238 Args : none to get, OR
239 Bio::Map::MappableI to set
244 my ($self, $element) = @_;
246 $self->throw("Must supply an object") unless ref($element);
247 $self->throw("This is [$element], not a Bio::Map::MappableI") unless $element->isa('Bio::Map::MappableI');
248 $self->{_use
} = 'element';
249 $self->{_element
} = $element;
251 return $self->{_element
} || return;
257 Usage : my $position = $relative->position();
258 $relative->position($position);
259 Function: Get/set the Position your Position is relative to. Your Position
260 will be made relative to the start of this supplied Position. It
261 makes no difference what maps the Positions are on.
262 Returns : Bio::Map::PositionI
263 Args : none to get, OR
264 Bio::Map::PositionI to set
269 my ($self, $pos) = @_;
271 $self->throw("Must supply an object") unless ref($pos);
272 $self->throw("This is [$pos], not a Bio::Map::PositionI") unless $pos->isa('Bio::Map::PositionI');
273 $self->{_use
} = 'position';
274 $self->{_position
} = $pos;
276 return $self->{_position
} || return;
282 Usage : my $description = $relative->description();
283 $relative->description($description);
284 Function: Get/set a textual description of what this relative describes.
286 Args : none to get, OR
293 if (@_) { $self->{desc
} = shift }
294 return $self->{desc
} || '';