Add tests for memory leaks and weaken for Issue #81
[bioperl-live.git] / Bio / Map / MappableI.pm
bloba64aead9429d54a40aa055dd8cdc0b73250710fa
2 # BioPerl module for Bio::Map::MappableI
4 # Please direct questions and support issues to <bioperl-l@bioperl.org>
6 # Cared for by Sendu Bala <bix@sendu.me.uk>
8 # Copyright Jason Stajich
10 # You may distribute this module under the same terms as perl itself
12 # POD documentation - main docs before the code
14 =head1 NAME
16 Bio::Map::MappableI - An object that can be placed in a map
18 =head1 SYNOPSIS
20 # do not use this module directly
21 # See Bio::Map::Mappable for an example of
22 # implementation.
24 =head1 DESCRIPTION
26 This object handles the generic notion of an element placed on a
27 (linear) Map. A Mappable can have multiple positions in multiple maps, such as
28 is the case of Restriction enzyme cut sites on sequence maps. For exact
29 information about a mappable's position in a map one must query the associate
30 PositionI objects which are accessible through the get_positions() method.
32 =head1 FEEDBACK
34 =head2 Mailing Lists
36 User feedback is an integral part of the evolution of this and other
37 Bioperl modules. Send your comments and suggestions preferably to
38 the Bioperl mailing list. Your participation is much appreciated.
40 bioperl-l@bioperl.org - General discussion
41 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
43 =head2 Support
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.
54 =head2 Reporting Bugs
56 Report bugs to the Bioperl bug tracking system to help us keep track
57 of the bugs and their resolution. Bug reports can be submitted via the
58 web:
60 https://github.com/bioperl/bioperl-live/issues
62 =head1 AUTHOR - Jason Stajich
64 Email jason@bioperl.org
66 =head1 CONTRIBUTORS
68 Heikki Lehvaslaiho heikki-at-bioperl-dot-org
69 Lincoln Stein lstein@cshl.org
70 Sendu Bala bix@sendu.me.uk
72 =head1 APPENDIX
74 The rest of the documentation details each of the object methods.
75 Internal methods are usually preceded with a _
77 =cut
79 # Let the code begin...
81 package Bio::Map::MappableI;
82 use strict;
83 use Bio::Map::PositionHandler;
85 use base qw(Bio::Map::EntityI Bio::AnnotatableI);
87 =head2 EntityI methods
89 These are fundamental to coordination of Mappables and other entities, so are
90 implemented at the interface level
92 =cut
94 =head2 get_position_handler
96 Title : get_position_handler
97 Usage : my $position_handler = $entity->get_position_handler();
98 Function: Gets a PositionHandlerI that $entity is registered with.
99 Returns : Bio::Map::PositionHandlerI object
100 Args : none
102 =cut
104 sub get_position_handler {
105 my $self = shift;
106 unless (defined $self->{_eh}) {
107 my $ph = Bio::Map::PositionHandler->new(-self => $self);
108 $self->{_eh} = $ph;
109 $ph->register;
111 return $self->{_eh};
114 =head2 PositionHandlerI-related methods
116 These are fundamental to coordination of Mappables and other entities, so are
117 implemented at the interface level
119 =cut
121 =head2 add_position
123 Title : add_position
124 Usage : $mappable->add_position($position);
125 Function: Add a position to this mappable (defining where on which map it is).
126 Returns : n/a
127 Args : L<Bio::Map::PositionI> object
129 =cut
131 sub add_position {
132 my $self = shift;
133 # actually, we allow multiple positions to be set at once
134 $self->get_position_handler->add_positions(@_);
137 =head2 get_positions
139 Title : get_positions
140 Usage : my @positions = $mappable->get_positions();
141 Function: Get all the Positions of this Mappable (sorted).
142 Returns : Array of L<Bio::Map::PositionI> objects
143 Args : none for all, OR
144 L<Bio::Map::MapI> object for positions on the given map, AND/OR some
145 other true value to avoid sorting
147 =cut
149 sub get_positions {
150 my ($self, $thing, $no_sort) = @_;
151 my $map;
152 if (ref($thing) && $thing->isa('Bio::Map::MapI')) {
153 $map = $thing;
155 else {
156 $no_sort = $thing;
158 my @positions = $self->get_position_handler->get_positions($map);
159 return @positions if @positions == 1;
161 unless ($no_sort) {
162 # don't do
163 # @positions = sort { $a->sortable <=> $b->sortable } @positions;
164 # directly since sortable() can result in the call of another sort
165 # routine and cause problems; pre-compute sortable values instead
166 # (which is also more efficient)
167 @positions = map { $_->[1] }
168 sort { $a->[0] <=> $b->[0] }
169 map { [$_->sortable, $_] }
170 @positions;
172 return @positions;
175 =head2 each_position
177 Title : each_position
178 Function: Synonym of the get_positions() method.
179 Status : deprecated, will be removed in next version
181 =cut
183 *each_position = \&get_positions;
185 =head2 purge_positions
187 Title : purge_positions
188 Usage : $mappable->purge_positions();
189 Function: Remove positions from this mappable.
190 Returns : n/a
191 Args : none to remove all positions, OR
192 L<Bio::Map::PositionI> object to remove just that Position, OR
193 L<Bio::Map::MapI> object to remove only those positions on the given
196 =cut
198 sub purge_positions {
199 my ($self, $thing) = @_;
200 $self->get_position_handler->purge_positions($thing);
203 =head2 known_maps
205 Title : known_maps
206 Usage : my @maps = $marker->known_maps()
207 Function: Returns the maps that this mappable is found on
208 Returns : Array of L<Bio::Map::MapI> objects
209 Args : none
211 =cut
213 sub known_maps {
214 my $self = shift;
215 return $self->get_position_handler->get_other_entities;
218 =head2 MappableI-specific methods
220 =cut
222 =head2 name
224 Title : name
225 Usage : my $name = $marker->name();
226 $marker->name($new_name);
227 Function: Get/Set the name for this Mappable.
228 Returns : A scalar representing the current name of this Mappable
229 Args : none to get
230 string to set
232 =cut
234 sub name {
235 my $self = shift;
236 $self->throw_not_implemented();
239 =head2 id
241 Title : id
242 Usage : my $id = $marker->id();
243 $marker->id($new_id);
244 Function: Get/Set the id for this Mappable.
245 Returns : A scalar representing the current id of this Mappable
246 Args : none to get
247 string to set
249 =cut
251 sub id {
252 my $self = shift;
253 $self->throw_not_implemented();
256 =head2 in_map
258 Title : in_map
259 Usage : if ($marker->in_map($map)) {...}
260 Function: Tests if this mappable is found on a specific map
261 Returns : boolean
262 Args : L<Bio::Map::MapI>
264 =cut
266 sub in_map {
267 my $self = shift;
268 $self->throw_not_implemented();
271 =head1 RangeI-related Methods
273 They throw an error if start and end are not defined in the Positions of the
274 Mappables supplied.
276 =cut
278 =head2 equals
280 Title : equals
281 Usage : if ($mappable->equals($other_mappable)) {...}
282 my @equal_positions = $mappable->equals($other_mappable);
283 Function: Finds the positions in this mappable that are equal to any
284 comparison positions.
285 Returns : array of L<Bio::Map::PositionI> objects
286 Args : arg #1 = L<Bio::Map::MappableI> OR L<Bio::Map::PositionI> to compare
287 this one to (mandatory)
288 arg #2 = optionally, the key => value pairs below
289 -map => Bio::Map::MapI : optionally a Map to only consider
290 positions on the given map
291 -relative => Bio::Map::RelativeI : optionally a Relative to ask if
292 the Positions equal in terms of
293 their relative position to the
294 thing described by that Relative
296 =cut
298 sub equals {
299 my $self = shift;
300 $self->throw_not_implemented();
303 =head2 overlaps
305 Title : overlaps
306 Usage : if ($mappable->overlaps($other_mappable)) {...}
307 my @overlapping_positions = $mappable->overlaps($other_mappable);
308 Function: Finds the positions in this mappable that overlap with any
309 comparison positions.
310 Returns : array of L<Bio::Map::PositionI> objects
311 Args : arg #1 = L<Bio::Map::MappableI> OR L<Bio::Map::PositionI> to compare
312 this one to (mandatory)
313 arg #2 = optionally, the key => value pairs below
314 -map => Bio::Map::MapI : optionally a Map to only consider
315 positions on the given map
316 -relative => Bio::Map::RelativeI : optionally a Relative to ask if
317 the Positions overlap in terms of
318 their relative position to the
319 thing described by that Relative
321 =cut
323 sub overlaps {
324 my $self = shift;
325 $self->throw_not_implemented();
328 =head2 contains
330 Title : contains
331 Usage : if ($mappable->contains($other_mappable)) {...}
332 my @container_positions = $mappable->contains($other_mappable);
333 Function: Finds the positions in this mappable that contain any comparison
334 positions.
335 Returns : array of L<Bio::Map::PositionI> objects
336 Args : arg #1 = L<Bio::Map::MappableI> OR L<Bio::Map::PositionI> to compare
337 this one to (mandatory)
338 arg #2 = optionally, the key => value pairs below
339 -map => Bio::Map::MapI : optionally a Map to only consider
340 positions on the given map
341 -relative => Bio::Map::RelativeI : optionally a Relative to ask if
342 the Positions contains in terms of
343 their relative position to the
344 thing described by that Relative
346 =cut
348 sub contains {
349 my $self = shift;
350 $self->throw_not_implemented();
353 =head2 intersection
355 Title : intersection
356 Usage : my $position = $mappable->intersection($other_mappable);
357 my $position = Bio::Map::Mappable->intersection(\@mappables);
358 Function: Make the position that is at the intersection of all positions of all
359 supplied mappables.
360 Returns : L<Bio::Map::PositionI> object or undef (if not all positions overlap)
361 Args : arg #1 = L<Bio::Map::MappableI> OR L<Bio::Map::PositionI> to compare
362 this one to, or an array ref of such objects (mandatory)
363 arg #2 = optionally, the key => value pairs below
364 -map => Bio::Map::MapI : optionally a Map to only consider
365 positions on the given map
366 -relative => Bio::Map::RelativeI : optionally a Relative to to ask
367 how the Positions intersect in
368 terms of their relative position
369 to the thing described by that
370 Relative
372 =cut
374 sub intersection {
375 my $self = shift;
376 $self->throw_not_implemented();
379 =head2 union
381 Title : union
382 Usage : my $position = $mappable->union($other_mappable);
383 my $position = Bio::Map::Mappable->union(@mappables);
384 Function: Make the minimal position that contains all of the positions of all
385 supplied mappables.
386 Returns : L<Bio::Map::PositionI> object or undef (if not all positions overlap)
387 Args : arg #1 = L<Bio::Map::MappableI> OR L<Bio::Map::PositionI> to compare
388 this one to, or an array ref of such objects (mandatory)
389 arg #2 = optionally, the key => value pairs below
390 -map => Bio::Map::MapI : optionally a Map to only consider
391 positions on the given map
392 -relative => Bio::Map::RelativeI : optionally a Relative to to ask
393 if the union of the Positions in
394 terms of their relative position
395 to the thing described by that
396 Relative
398 =cut
400 sub union {
401 my $self = shift;
402 $self->throw_not_implemented();