work on updates for release
[bioperl-live.git] / Bio / Map / MapI.pm
blobd8c73ea8f3ae24149db44c1f79b9683c5de187e8
2 # BioPerl module for Bio::Map::MapI
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::MapI - Interface for describing Map objects in bioperl
18 =head1 SYNOPSIS
20 # get a MapI somehow
21 my $name = $map->name(); # string
22 my $length = $map->length(); # integer
23 my $species= $map->species; # Bio::Species
24 my $type = $map->type(); # genetic/sts/rh/
26 =head1 DESCRIPTION
28 This object describes the basic functionality of a Map in bioperl.
29 Maps are anything from Genetic Map to Sequence Map to Assembly Map
30 to Restriction Enzyme to FPC.
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://redmine.open-bio.org/projects/bioperl/
62 =head1 AUTHOR - Jason Stajich
64 Email jason@bioperl.org
66 =head1 CONTRIBUTORS
68 Lincoln Stein, lstein@cshl.org
69 Heikki Lehvaslaiho, heikki-at-bioperl-dot-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::MapI;
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 Maps 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 Maps and other entities, so are
117 implemented at the interface level
119 =cut
121 =head2 get_positions
123 Title : get_positions
124 Usage : my @positions = $mappable->get_positions();
125 Function: Get all the Positions on this Map (sorted).
126 Returns : Array of L<Bio::Map::PositionI> objects
127 Args : none for all, OR
128 L<Bio::Map::MappableI> object for positions of the given Mappable
130 =cut
132 sub get_positions {
133 my ($self, $mappable) = @_;
134 my @positions = $self->get_position_handler->get_positions($mappable);
135 # precompute sortable for effieciency and to avoid bugs
136 @positions = map { $_->[1] }
137 sort { $a->[0] <=> $b->[0] }
138 map { [$_->sortable, $_] }
139 @positions;
140 return @positions;
143 =head2 each_position
145 Title : each_position
146 Function: Synonym of the get_positions() method.
147 Status : deprecated, will be removed in next version
149 =cut
151 *each_position = \&get_positions;
153 =head2 purge_positions
155 Title : purge_positions
156 Usage : $map->purge_position();
157 Function: Remove all positions from this map. Notifies the positions they are
158 no longer on this map.
159 Returns : n/a
160 Args : none to remove all positions, OR
161 L<Bio::Map::PositionI> object to remove just that Position, OR
162 L<Bio::Map::MappableI> object to remove only those positions of the
163 given mappable
165 =cut
167 sub purge_positions {
168 my ($self, $thing) = @_;
169 $self->get_position_handler->purge_positions($thing);
172 =head2 get_elements
174 Title : get_elements
175 Usage : my @elements = $map->get_elements;
176 Function: Retrieves all the elements on a map (unordered)
177 Returns : Array of Map elements (L<Bio::Map::MappableI>)
178 Args : none
180 =cut
182 sub get_elements {
183 my $self = shift;
184 return $self->get_position_handler->get_other_entities;
187 =head2 each_element
189 Title : each_element
190 Function: Synonym of the get_elements() method.
191 Status : deprecated, will be removed in the next version
193 =cut
195 =head2 common_elements
197 Title : common_elements
198 Usage : my @common_elements = $map->common_elements(\@other_maps);
199 my @common_elements = Bio::Map::SimpleMap->common_elements(\@maps);
200 Function: Find the elements that are common to multiple maps.
201 Returns : array of Bio::Map::MappableI
202 Args : arg #1 = L<Bio::Map::MapI> to compare this one to, or an array ref
203 of such objects (mandatory)
204 arg #2 = optionally, one or more of the key => value pairs below
205 -min_num => int : the minimum number of input maps an element
206 must be found on before before returned
207 [default is 1]
208 -min_percent => number : as above, but the minimum percentage of
209 input maps [default is 100 - note that this
210 will effectively override all other options]
211 -require_self => 1|0 : require that all output elements at least
212 be on the calling map [default is 1, has no
213 effect when the second usage form is used]
214 -required => \@maps : require that all output elements be on at
215 least all the maps supplied here
217 =cut
219 sub common_elements {
220 my ($self, $maps_ref, @extra_args) = @_;
221 $self->throw("Must supply a reference first argument") unless ref($maps_ref);
222 my @maps;
223 if (ref($maps_ref) eq 'ARRAY') {
224 @maps = @{$maps_ref};
226 elsif ($maps_ref->isa('Bio::Map::MapI')) {
227 @maps = ($maps_ref);
229 if (ref($self)) {
230 unshift(@maps, $self);
232 $self->throw("Need at least 2 maps") unless @maps >= 2;
234 my %args = (-min_num => 1, -min_percent => 100, -require_self => 1, -required => undef, @extra_args);
235 my $min_num = $args{-min_num};
236 if ($args{-min_percent}) {
237 my $mn = @maps / 100 * $args{-min_percent};
238 if ($mn > $min_num) {
239 $min_num = $mn;
242 my %required = map { $_ => 1 } $args{-required} ? @{$args{-required}} : ();
243 $required{$self} = 1 if ref($self) && $args{-require_self};
244 my @required = keys %required;
246 my %map_elements;
247 my %elements;
248 my %count;
249 foreach my $map (@maps) {
250 $map_elements{$map} = {};
251 foreach my $element ($map->get_elements) {
252 $map_elements{$map}->{$element} = 1;
253 $elements{$element} = $element;
254 $count{$element}++;
258 my @elements;
259 ELEMENT: while (my ($key, $value) = each %elements) {
260 $count{$key} >= $min_num or next;
261 foreach my $required (@required) {
262 exists $map_elements{$required}->{$key} or next ELEMENT;
265 push(@elements, $value);
267 return @elements;
270 =head2 MapI-specific methods
272 =cut
274 =head2 species
276 Title : species
277 Usage : my $species = $map->species;
278 Function: Get/Set Species for a map
279 Returns : L<Bio::Species> object
280 Args : (optional) Bio::Species
282 =cut
284 sub species{
285 my $self = shift;
286 $self->throw_not_implemented();
289 =head2 units
291 Title : units
292 Usage : $map->units('cM');
293 Function: Get/Set units for a map
294 Returns : units for a map
295 Args : units for a map (string)
297 =cut
299 sub units{
300 my $self = shift;
301 $self->throw_not_implemented();
304 =head2 type
306 Title : type
307 Usage : my $type = $map->type
308 Function: Get/Set Map type
309 Returns : String coding map type
310 Args : (optional) string
312 =cut
314 sub type {
315 my $self = shift;
316 $self->throw_not_implemented();
319 =head2 name
321 Title : name
322 Usage : my $name = $map->name
323 Function: Get/Set Map name
324 Returns : Map name
325 Args : (optional) string
327 =cut
329 sub name {
330 my $self = shift;
331 $self->throw_not_implemented();
334 =head2 length
336 Title : length
337 Usage : my $length = $map->length();
338 Function: Retrieves the length of the map.
339 It is possible for the length to be unknown for maps such as
340 Restriction Enzyme, will return 0 in that case
341 Returns : integer representing length of map in current units
342 will return undef if length is not calculateable
343 Args : none
345 =cut
347 sub length {
348 my $self = shift;
349 $self->throw_not_implemented();