bug 2549; fixed small bug in Bio::Taxon which doesn't catch -common_name
[bioperl-live.git] / Bio / Map / MapI.pm
blob30279b48bd565314e69516ff6259d412f3579102
1 # $Id$
3 # BioPerl module for Bio::Map::MapI
5 # Cared for by Sendu Bala <bix@sendu.me.uk>
7 # Copyright Jason Stajich
9 # You may distribute this module under the same terms as perl itself
11 # POD documentation - main docs before the code
13 =head1 NAME
15 Bio::Map::MapI - Interface for describing Map objects in bioperl
17 =head1 SYNOPSIS
19 # get a MapI somehow
20 my $name = $map->name(); # string
21 my $length = $map->length(); # integer
22 my $species= $map->species; # Bio::Species
23 my $type = $map->type(); # genetic/sts/rh/
25 =head1 DESCRIPTION
27 This object describes the basic functionality of a Map in bioperl.
28 Maps are anything from Genetic Map to Sequence Map to Assembly Map
29 to Restriction Enzyme to FPC.
31 =head1 FEEDBACK
33 =head2 Mailing Lists
35 User feedback is an integral part of the evolution of this and other
36 Bioperl modules. Send your comments and suggestions preferably to
37 the Bioperl mailing list. Your participation is much appreciated.
39 bioperl-l@bioperl.org - General discussion
40 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
42 =head2 Reporting Bugs
44 Report bugs to the Bioperl bug tracking system to help us keep track
45 of the bugs and their resolution. Bug reports can be submitted via the
46 web:
48 http://bugzilla.open-bio.org/
50 =head1 AUTHOR - Jason Stajich
52 Email jason@bioperl.org
54 =head1 CONTRIBUTORS
56 Lincoln Stein, lstein@cshl.org
57 Heikki Lehvaslaiho, heikki-at-bioperl-dot-org
58 Sendu Bala, bix@sendu.me.uk
60 =head1 APPENDIX
62 The rest of the documentation details each of the object methods.
63 Internal methods are usually preceded with a _
65 =cut
67 # Let the code begin...
69 package Bio::Map::MapI;
70 use strict;
71 use Bio::Map::PositionHandler;
73 use base qw(Bio::Map::EntityI Bio::AnnotatableI);
75 =head2 EntityI methods
77 These are fundamental to coordination of Maps and other entities, so are
78 implemented at the interface level
80 =cut
82 =head2 get_position_handler
84 Title : get_position_handler
85 Usage : my $position_handler = $entity->get_position_handler();
86 Function: Gets a PositionHandlerI that $entity is registered with.
87 Returns : Bio::Map::PositionHandlerI object
88 Args : none
90 =cut
92 sub get_position_handler {
93 my $self = shift;
94 unless (defined $self->{_eh}) {
95 my $ph = Bio::Map::PositionHandler->new(-self => $self);
96 $self->{_eh} = $ph;
97 $ph->register;
99 return $self->{_eh};
102 =head2 PositionHandlerI-related methods
104 These are fundamental to coordination of Maps and other entities, so are
105 implemented at the interface level
107 =cut
109 =head2 get_positions
111 Title : get_positions
112 Usage : my @positions = $mappable->get_positions();
113 Function: Get all the Positions on this Map (sorted).
114 Returns : Array of L<Bio::Map::PositionI> objects
115 Args : none for all, OR
116 L<Bio::Map::MappableI> object for positions of the given Mappable
118 =cut
120 sub get_positions {
121 my ($self, $mappable) = @_;
122 my @positions = $self->get_position_handler->get_positions($mappable);
123 # precompute sortable for effieciency and to avoid bugs
124 @positions = map { $_->[1] }
125 sort { $a->[0] <=> $b->[0] }
126 map { [$_->sortable, $_] }
127 @positions;
128 return @positions;
131 =head2 each_position
133 Title : each_position
134 Function: Synonym of the get_positions() method.
135 Status : deprecated, will be removed in next version
137 =cut
139 *each_position = \&get_positions;
141 =head2 purge_positions
143 Title : purge_positions
144 Usage : $map->purge_position();
145 Function: Remove all positions from this map. Notifies the positions they are
146 no longer on this map.
147 Returns : n/a
148 Args : none to remove all positions, OR
149 L<Bio::Map::PositionI> object to remove just that Position, OR
150 L<Bio::Map::MappableI> object to remove only those positions of the
151 given mappable
153 =cut
155 sub purge_positions {
156 my ($self, $thing) = @_;
157 $self->get_position_handler->purge_positions($thing);
160 =head2 get_elements
162 Title : get_elements
163 Usage : my @elements = $map->get_elements;
164 Function: Retrieves all the elements on a map (unordered)
165 Returns : Array of Map elements (L<Bio::Map::MappableI>)
166 Args : none
168 =cut
170 sub get_elements {
171 my $self = shift;
172 return $self->get_position_handler->get_other_entities;
175 =head2 each_element
177 Title : each_element
178 Function: Synonym of the get_elements() method.
179 Status : deprecated, will be removed in the next version
181 =cut
183 =head2 common_elements
185 Title : common_elements
186 Usage : my @common_elements = $map->common_elements(\@other_maps);
187 my @common_elements = Bio::Map::SimpleMap->common_elements(\@maps);
188 Function: Find the elements that are common to multiple maps.
189 Returns : array of Bio::Map::MappableI
190 Args : arg #1 = L<Bio::Map::MapI> to compare this one to, or an array ref
191 of such objects (mandatory)
192 arg #2 = optionally, one or more of the key => value pairs below
193 -min_num => int : the minimum number of input maps an element
194 must be found on before before returned
195 [default is 1]
196 -min_percent => number : as above, but the minimum percentage of
197 input maps [default is 100 - note that this
198 will effectively override all other options]
199 -require_self => 1|0 : require that all output elements at least
200 be on the calling map [default is 1, has no
201 effect when the second usage form is used]
202 -required => \@maps : require that all output elements be on at
203 least all the maps supplied here
205 =cut
207 sub common_elements {
208 my ($self, $maps_ref, @extra_args) = @_;
209 $self->throw("Must supply a reference first argument") unless ref($maps_ref);
210 my @maps;
211 if (ref($maps_ref) eq 'ARRAY') {
212 @maps = @{$maps_ref};
214 elsif ($maps_ref->isa('Bio::Map::MapI')) {
215 @maps = ($maps_ref);
217 if (ref($self)) {
218 unshift(@maps, $self);
220 $self->throw("Need at least 2 maps") unless @maps >= 2;
222 my %args = (-min_num => 1, -min_percent => 100, -require_self => 1, -required => undef, @extra_args);
223 my $min_num = $args{-min_num};
224 if ($args{-min_percent}) {
225 my $mn = @maps / 100 * $args{-min_percent};
226 if ($mn > $min_num) {
227 $min_num = $mn;
230 my %required = map { $_ => 1 } $args{-required} ? @{$args{-required}} : ();
231 $required{$self} = 1 if ref($self) && $args{-require_self};
232 my @required = keys %required;
234 my %map_elements;
235 my %elements;
236 my %count;
237 foreach my $map (@maps) {
238 $map_elements{$map} = {};
239 foreach my $element ($map->get_elements) {
240 $map_elements{$map}->{$element} = 1;
241 $elements{$element} = $element;
242 $count{$element}++;
246 my @elements;
247 ELEMENT: while (my ($key, $value) = each %elements) {
248 $count{$key} >= $min_num or next;
249 foreach my $required (@required) {
250 exists $map_elements{$required}->{$key} or next ELEMENT;
253 push(@elements, $value);
255 return @elements;
258 =head2 MapI-specific methods
260 =cut
262 =head2 species
264 Title : species
265 Usage : my $species = $map->species;
266 Function: Get/Set Species for a map
267 Returns : L<Bio::Species> object
268 Args : (optional) Bio::Species
270 =cut
272 sub species{
273 my $self = shift;
274 $self->throw_not_implemented();
277 =head2 units
279 Title : units
280 Usage : $map->units('cM');
281 Function: Get/Set units for a map
282 Returns : units for a map
283 Args : units for a map (string)
285 =cut
287 sub units{
288 my $self = shift;
289 $self->throw_not_implemented();
292 =head2 type
294 Title : type
295 Usage : my $type = $map->type
296 Function: Get/Set Map type
297 Returns : String coding map type
298 Args : (optional) string
300 =cut
302 sub type {
303 my $self = shift;
304 $self->throw_not_implemented();
307 =head2 name
309 Title : name
310 Usage : my $name = $map->name
311 Function: Get/Set Map name
312 Returns : Map name
313 Args : (optional) string
315 =cut
317 sub name {
318 my $self = shift;
319 $self->throw_not_implemented();
322 =head2 length
324 Title : length
325 Usage : my $length = $map->length();
326 Function: Retrieves the length of the map.
327 It is possible for the length to be unknown for maps such as
328 Restriction Enzyme, will return 0 in that case
329 Returns : integer representing length of map in current units
330 will return undef if length is not calculateable
331 Args : none
333 =cut
335 sub length {
336 my $self = shift;
337 $self->throw_not_implemented();