comparison variant_effect_predictor/Bio/Map/Marker.pm @ 0:1f6dce3d34e0

Uploaded
author mahtabm
date Thu, 11 Apr 2013 02:01:53 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1f6dce3d34e0
1 # BioPerl module for Bio::Map::Marker
2 #
3 # Cared for by Chad Matsalla <bioinformatics1@dieselwurks.com>
4 #
5 # Copyright Chad Matsalla
6 #
7 # You may distribute this module under the same terms as perl itself
8
9 # POD documentation - main docs before the code
10
11 =head1 NAME
12
13 Bio::Map::Marker - An central map object representing a generic marker
14 that can have multiple location in several maps.
15
16 =head1 SYNOPSIS
17
18 # get map objects somehow
19
20 # a marker with complex localisation
21 $o_usat = new Bio::Map::Marker (-name=>'Chad Super Marker 2',
22 -positions => [ [$map1, $position1],
23 [$map1, $position2]
24 ] );
25
26 # The markers deal with Bio::Map::Position objects which can also
27 # be explicitely created and passed on to markers as an array ref:
28 $o_usat2 = new Bio::Map::Marker (-name=>'Chad Super Marker 3',
29 -positions => [ $pos1,
30 $pos2
31 ] );
32
33 # a marker with unique position in a map
34 $marker1 = new Bio::Map::Marker (-name=>'hypervariable1',
35 -map => $map1,
36 -position => 100
37 )
38
39 # an other way of creating a marker with unique position in a map:
40 $marker2 = new Bio::Map::Marker (-name=>'hypervariable2');
41 $map1->add_marker($marker2);
42 $marker2->position(100);
43
44 # position method is a short cut for get/set'ing unigue positions
45 # which overwrites previous values
46 # to place a marker to other maps or to have multiple positions
47 # for a map within the same map use add_position()
48
49 $marker2->add_position(200); # new position in the same map
50 $marker2->add_position($map2,200); # new map
51
52 # setting a map() in a marker or adding a marker into a map are
53 # identical mathods. Both set the bidirectional connection which is
54 # used by the marker to remember its latest, default map.
55
56 # Regardes of how marker positions are created, they are stored and
57 # returned as Bio::Map::PositionI objects:
58
59 # unique position
60 print $marker1->position->value, "\n";
61 # several positions
62 foreach $pos ($marker2->each_position($map1)) {
63 print $pos->value, "\n";
64 }
65
66 See L<Bio::Map::Position> and L<Bio::Map::PositionI> for more information.
67
68 =head1 DESCRIPTION
69
70 This object handles the notion of a generic marker. This marker will
71 have a name and a position in a map.
72
73 This object is intended to be used by a marker parser like Mapmaker.pm
74 and then blessed into the proper type of marker (ie Microsatellite) by
75 the calling script.
76
77 =head2 Design principles
78
79 A Marker is a central object in Bio::Map name space. A Map is a holder
80 class for objects. A Marker has a Position in a Map. A Marker can be
81 compared to an other Markers using boolean methods. Positions can have
82 non-numeric values or other methods to store the locations, so they
83 have a method numeric() which does the conversion.
84
85 A Marker has a convinience method position() which is able to create
86 Positions of required class from scalars by calling method
87 get_position_object().
88
89 For more complex situations, a Marker can have multiple positions in
90 multiple Maps. It is therefore possible to extract Positions (all or
91 belonging to certain Map) and compare Markers to them. It is up to the
92 programmer to make sure position values and Maps they belong to can be
93 sensibly compared.
94
95 =head1 FEEDBACK
96
97 =head2 Mailing Lists
98
99 User feedback is an integral part of the evolution of this and other
100 Bioperl modules. Send your comments and suggestions preferably to the
101 Bioperl mailing list. Your participation is much appreciated.
102
103 bioperl-l@bioperl.org - General discussion
104 http://bioperl.org/MailList.shtml - About the mailing lists
105
106 =head2 Reporting Bugs
107
108 Report bugs to the Bioperl bug tracking system to help us keep track
109 of the bugs and their resolution. Bug reports can be submitted via
110 email or the web:
111
112 bioperl-bugs@bioperl.org
113 http://bugzilla.bioperl.org/
114
115 =head1 AUTHOR - Chad Matsalla
116
117 Email bioinformatics1@dieselwurks.com
118
119 =head1 CONTRIBUTORS
120
121 Heikki Lehvaslaiho heikki@ebi.ac.uk
122 Lincoln Stein lstein@cshl.org
123 Jason Stajich jason@bioperl.org
124
125 =head1 APPENDIX
126
127 The rest of the documentation details each of the object methods.
128 Internal methods are usually preceded with a _
129
130 =cut
131
132 # Let the code begin...
133
134 package Bio::Map::Marker;
135 use vars qw(@ISA);
136 use strict;
137 use Bio::Root::Root;
138 use Bio::Map::MarkerI;
139 use Bio::Map::Position;
140
141 @ISA = qw(Bio::Root::Root Bio::Map::MarkerI);
142
143 =head2 new
144
145 Title : new
146 Usage : $o_marker = new Bio::Map::Marker( -name => 'Whizzy marker',
147 -position => $position);
148 Function: Builds a new Bio::Map::Marker object
149 Returns : Bio::Map::Marker
150 Args :
151 -name => name of this microsatellite
152 [optional], string,default 'Unknown'
153
154 -positions => map position for this marker, [optional]
155 Bio::Map::PositionI-inherited obj, no default)
156
157 =cut
158
159 sub new {
160 my ($class,@args) = @_;
161 my $self = $class->SUPER::new(@args);
162 $self->{'_positions'} = [];
163 my ($name, $map, $position, $positions) =
164 $self->_rearrange([qw(NAME
165 MAP
166 POSITION
167 POSITIONS
168 )], @args);
169 if ($name) { $self->name($name); }
170 else {$self->name('Unnamed marker'); }
171 $position && $self->position($position);
172 $positions && $self->positions($positions);
173 $map && $self->map($map);
174
175 return $self;
176 }
177
178 =head2 name
179
180 Title : name
181 Usage : $o_usat->name($new_name) _or_
182 my $name = $o_usat->name()
183 Function: Get/Set the name for this Microsatellite
184 Returns : A scalar representing the current name of this marker
185 Args : If provided, the current name of this marker
186 will be set to $new_name.
187
188 =cut
189
190 sub name {
191 my ($self,$name) = @_;
192 my $last = $self->{'_name'};
193 if ($name) {
194 $self->{'_name'} = $name;
195 }
196 return $last;
197 }
198
199
200 =head2 map
201
202 Title : map
203 Usage : my $mymap = $marker->map();
204 Function: Get/Set the default map for the marker.
205 This is set by L<Bio::Map::CytoMap::add_element> method
206 Returns : L<Bio::Map::MapI>
207 Args : [optional] new L<Bio::Map::MapI>
208
209 =cut
210
211 sub map {
212 my ($self,$map) = @_;
213 if( defined $map ) {
214 $self->thow('This is [$map], not Bio::Map::MapI object')
215 unless $map->isa('Bio::Map::MapI');
216 $self->{'_default_map'} = $map;
217 }
218 return $self->{'_default_map'};
219 }
220
221
222
223 =head2 get_position_object
224
225 Title : get_position_class
226 Usage : my $pos = $marker->get_position_object();
227 Function: To get an object of the default Position class
228 for this Marker. Subclasses should redefine this method.
229 The Position needs to be Bio::Map::PositionI.
230 Returns : Bio::Map::Position
231 Args : none
232
233 See L<Bio::Map::Position> and L<Bio::Map::PositionI> for more information.
234
235 =cut
236
237 sub get_position_object {
238 my ($self) = @_;
239 return new Bio::Map::Position();
240 }
241
242
243 =head2 position
244
245 Title : position
246 Usage : $position = $mappable->position($map); OR
247 $mappable->position($position); # $position can be Bio::Map::PositionI
248 $mappable->position(100); # or scalar if the marker has a default map
249 $mappable->position($map, 100); # if not give explicit $map
250 Function: Get/Set the Bio::Map::PositionI for a mappable element
251 in a specific Map
252 Adds the marker to a map automatically if Map is given.
253 Altenaitvely, you can add the merker to the map first
254 (L<Bio::Map::Map::add_element>) to set the default map
255 Returns : Bio::Map::PositionI
256 Args : $position - Bio::Map::PositionI # Position we want to set
257 OR
258 $map - Bio::Map::MapI AND
259 scalar
260 OR
261 scalar, but only if the marker has been added to a map
262
263 =cut
264
265 sub position {
266 my ($self, $pos, $secondary_pos) = @_;
267 my ($map);
268 POS: {
269 if ($pos) {
270 if (ref($pos) eq 'SCALAR' || ref($pos) eq '') {
271 $map = $self->map;
272 }
273 elsif (ref($pos) eq 'ARRAY') {
274 $map = $pos->[0];
275 $pos = $pos->[1];
276 }
277 elsif ($pos->isa('Bio::Map::PositionI')) {
278 $pos->marker($self);
279
280 $self->purge_positions;
281 $self->add_position($pos);
282 $map = $pos->map;
283 $map->add_element($self) unless defined($self->map) && $self->map eq $map;
284 last POS;
285 }
286
287 elsif ($pos->isa('Bio::Map::MapI')) {
288 $map = $pos;
289 $pos = $secondary_pos;
290 } else {
291 $map = $self->map;
292 }
293 $self->throw("You need to add a marker to a map before ".
294 "you can set positions without explicit map!" )
295 unless $map;
296 $self->throw("Position better be scalar, not [$pos=". ref($pos) ."]")
297 unless ref($pos) eq 'SCALAR' || ref($pos) eq '';
298
299 my $newpos = $self->get_position_object;
300 $newpos->map($map);
301 $newpos->value($pos);
302 $newpos->marker($self);
303
304 $map->add_element($self) unless defined($self->map) && $self->map eq $map;
305 $self->purge_positions;
306 $self->add_position($newpos)
307 }
308 }
309 my @array = $self->each_position();
310 $self->warn('More than one value is associated with this position')
311 if scalar @array > 1;
312 return $array[0];
313 }
314
315 =head2 add_position
316
317 Title : add_position
318 Usage : $position->add_position($position)
319 Function: Add the Position to the Marker container.
320 If you are using this method, you need to
321 add the Marker to the Map yourself
322 Returns : none
323 Args : Position - Reference to Bio::Map::PositionI
324
325 =cut
326
327 sub add_position{
328 my ($self, $pos) = @_;
329 $self->throw("Must give a Position") unless defined $pos;
330
331 $self->throw("Must give a Bio::Map::PositionI, not [". ref($pos) ."]")
332 unless $pos->isa('Bio::Map::PositionI');
333
334 my $map = $pos->map;
335 $map->add_element($self) unless defined($self->map) && $self->map eq $map;
336
337 push @{$self->{'_positions'}}, $pos;
338
339 }
340
341 =head2 positions
342
343 Title : positions
344 Usage : $mappable->positions([$pos1, $pos2, $pos3]);
345 Function: Add multiple Bio::Map::PositionI for a mappable element
346 in a Map.
347 Returns : boolean
348 Args : array ref of $map/value tuples or array ref of Positions
349
350 =cut
351
352 sub positions {
353 my ($self, $arrayref) = @_;
354 my ($map);
355 $self->throw_not_implemented();
356 }
357
358 =head2 each_position
359
360 Title : each_position
361 Usage : my @positions = $position->each_position('mapname');
362 Function: Retrieve a list of Positions
363 Returns : Array of L<Bio::Map::PositionI>
364 Args : none
365
366 =cut
367
368 sub each_position {
369 my ($self,$mapname) = @_;
370 $self->warn("Retrieving positions in a named map only is ".
371 "not implemented. Getting all.") if $mapname;
372 return @{$self->{'_positions'}};
373 }
374
375 =head2 purge_positions
376
377 Title : purge_positions
378 Usage : $marker->purge_positions
379 Function: Remove all the position values stored for a Marker
380 Returns : none
381 Args : [optional] only purge values for a given map
382
383 =cut
384
385 sub purge_positions{
386 my ($self, $map) = @_;
387 $self->warn("Retrieving positions in a named map only, not implemented ") if $map;
388 $self->{'_positions'} = [];
389 }
390
391 =head2 known_maps
392
393 Title : known_maps
394 Usage : my @maps = $marker->known_maps
395 Function: Returns the list of maps that this position has values for
396 Returns : list of Bio::Map::MapI unique ids
397 Args : none
398
399 =cut
400
401 sub known_maps{
402 my ($self) = @_;
403 my %hash;
404 foreach my $pos ($self->each_position) {
405 $hash{$pos->map->unique_id} = 1;
406 }
407 return keys %hash;
408 }
409
410 =head2 in_map
411
412 Title : in_map
413 Usage : if ( $position->in_map($map) ) {}
414 Function: Tests if a position has values in a specific map
415 Returns : boolean
416 Args : a map unique id OR Bio::Map::MapI
417
418 =cut
419
420 sub in_map{
421 my ($self,$map) = @_;
422
423 $self->throw("Need an argument") unless $map;
424
425 if (ref($map) && $map->isa('Bio::Map::MapI')) {
426 foreach my $pos ($self->each_position) {
427 return 1 if $pos->map eq $map;
428 }
429 } else { # assuming a scalar
430 foreach my $pos ($self->each_position) {
431 return 1 if $pos->map->unique_id eq $map;
432 }
433 }
434 return 0;
435 }
436
437 =head2 Comparison methods
438
439 =cut
440
441 =head2 tuple
442
443 Title : tuple
444 Usage : ($me, $you) = $self->_tuple($compare)
445 Function: Utility ethod to extract numbers and test for missing values.
446 Returns : tuple values
447 Args : Bio::Map::MappableI or Bio::Map::PositionI
448
449 =cut
450
451 sub tuple {
452 my ($self,$compare) = @_;
453 my ($me, $you) = (-1, -1);
454
455 $self->warn("Trying to compare [". $self->name. "] to nothing.") &&
456 return ($me, $you) unless defined $compare;
457 $self->warn("[". $self->name. "] has no position.") &&
458 return ($me, $you) unless $self->position;
459
460 $me = $self->position->numeric;
461
462 if( $compare->isa('Bio::Map::MappableI') ){
463 $self->warn("[". $compare->name. "] has no position.") &&
464 return ($me, $you) unless $compare->position;
465
466 $you = $compare->position->numeric;
467 return ($me, $you);
468
469 } elsif( $compare->isa('Bio::Map::PositionI') ) {
470
471 $you = $compare->numeric;
472 return ($me, $you);
473
474 } else {
475 $self->warn("Can only run equals with Bio::Map::MappableI or ".
476 "Bio::Map::PositionI not [$compare]");
477 }
478 return ($me, $you);
479 }
480
481
482 =head2 equals
483
484 Title : equals
485 Usage : if( $mappable->equals($mapable2)) ...
486 Function: Test if a position is equal to another position
487 Returns : boolean
488 Args : Bio::Map::MappableI or Bio::Map::PositionI
489
490 =cut
491
492 sub equals {
493 my ($self,$compare) = @_;
494
495 my ($me, $you) = $self->tuple($compare);
496 return 0 if $me == -1 or $you == -1 ;
497 return $me == $you;
498 }
499
500 =head2 less_than
501
502 Title : less_than
503 Usage : if( $mappable->less_than($m2) ) ...
504 Function: Tests if a position is less than another position
505 Returns : boolean
506 Args : Bio::Map::MappableI or Bio::Map::PositionI
507
508 =cut
509
510 sub less_than {
511 my ($self,$compare) = @_;
512
513 my ($me, $you) = $self->tuple($compare);
514 return 0 if $me == -1 or $you == -1 ;
515 return $me < $you;
516 }
517
518 =head2 greater_than
519
520 Title : greater_than
521 Usage : if( $mappable->greater_than($m2) ) ...
522 Function: Tests if position is greater than another position
523 Returns : boolean
524 Args : Bio::Map::MappableI or Bio::Map::PositionI
525
526 =cut
527
528 sub greater_than {
529 my ($self,$compare) = @_;
530
531
532 my ($me, $you) = $self->tuple($compare);
533 return 0 if $me == -1 or $you == -1 ;
534 return $me > $you;
535 }
536
537 1;