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

Uploaded
author mahtabm
date Thu, 11 Apr 2013 02:01:53 -0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/variant_effect_predictor/Bio/Map/Marker.pm	Thu Apr 11 02:01:53 2013 -0400
@@ -0,0 +1,537 @@
+# BioPerl module for Bio::Map::Marker
+#
+# Cared for by Chad Matsalla <bioinformatics1@dieselwurks.com>
+#
+# Copyright Chad Matsalla
+#
+# You may distribute this module under the same terms as perl itself
+
+# POD documentation - main docs before the code
+
+=head1 NAME
+
+Bio::Map::Marker - An central map object representing a generic marker
+that can have multiple location in several maps.
+
+=head1 SYNOPSIS
+
+  # get map objects somehow
+
+  # a marker with complex localisation
+  $o_usat = new Bio::Map::Marker (-name=>'Chad Super Marker 2',
+				  -positions => [ [$map1, $position1], 
+                                                  [$map1, $position2] 
+						] );
+
+  # The markers deal with Bio::Map::Position objects which can also
+  # be explicitely created and passed on to markers as an array ref:
+  $o_usat2 = new Bio::Map::Marker (-name=>'Chad Super Marker 3',
+				  -positions => [ $pos1, 
+                                                  $pos2 
+						] );
+
+  # a marker with unique position in a map
+  $marker1 = new Bio::Map::Marker (-name=>'hypervariable1',
+				   -map => $map1,
+				   -position => 100
+				   )
+
+  # an other way of creating a marker with unique position in a map:
+  $marker2 = new Bio::Map::Marker (-name=>'hypervariable2');
+  $map1->add_marker($marker2);
+  $marker2->position(100);
+
+  # position method is a short cut for get/set'ing  unigue positions
+  # which overwrites previous values
+  # to place a marker to other maps or to have multiple positions 
+  # for a map within the same map use add_position()
+
+  $marker2->add_position(200);	# new position in the same map
+  $marker2->add_position($map2,200); # new map
+
+  # setting a map() in a marker or adding a marker into a map are
+  # identical mathods. Both set the bidirectional connection which is
+  # used by the marker to remember its latest, default map.
+
+  # Regardes of how marker positions are created, they are stored and
+  # returned as Bio::Map::PositionI objects:
+
+  # unique position
+  print $marker1->position->value, "\n";
+  # several positions
+  foreach $pos ($marker2->each_position($map1)) {
+     print $pos->value, "\n";
+  }
+
+See L<Bio::Map::Position> and L<Bio::Map::PositionI> for more information.
+
+=head1 DESCRIPTION
+
+This object handles the notion of a generic marker. This marker will
+have a name and a position in a map.
+
+This object is intended to be used by a marker parser like Mapmaker.pm
+and then blessed into the proper type of marker (ie Microsatellite) by
+the calling script.
+
+=head2 Design principles
+
+A Marker is a central object in Bio::Map name space. A Map is a holder
+class for objects. A Marker has a Position in a Map.  A Marker can be
+compared to an other Markers using boolean methods. Positions can have
+non-numeric values or other methods to store the locations, so they
+have a method numeric() which does the conversion. 
+
+A Marker has a convinience method position() which is able to create
+Positions of required class from scalars by calling method
+get_position_object().
+
+For more complex situations, a Marker can have multiple positions in
+multiple Maps. It is therefore possible to extract Positions (all or
+belonging to certain Map) and compare Markers to them. It is up to the
+programmer to make sure position values and Maps they belong to can be
+sensibly compared.
+
+=head1 FEEDBACK
+
+=head2 Mailing Lists
+
+User feedback is an integral part of the evolution of this and other
+Bioperl modules. Send your comments and suggestions preferably to the
+Bioperl mailing list.  Your participation is much appreciated.
+
+  bioperl-l@bioperl.org              - General discussion
+  http://bioperl.org/MailList.shtml  - About the mailing lists
+
+=head2 Reporting Bugs
+
+Report bugs to the Bioperl bug tracking system to help us keep track
+of the bugs and their resolution. Bug reports can be submitted via
+email or the web:
+
+  bioperl-bugs@bioperl.org
+  http://bugzilla.bioperl.org/
+
+=head1 AUTHOR - Chad Matsalla
+
+Email bioinformatics1@dieselwurks.com
+
+=head1 CONTRIBUTORS
+
+Heikki Lehvaslaiho heikki@ebi.ac.uk
+Lincoln Stein      lstein@cshl.org
+Jason Stajich      jason@bioperl.org
+
+=head1 APPENDIX
+
+The rest of the documentation details each of the object methods.
+Internal methods are usually preceded with a _
+
+=cut
+
+# Let the code begin...
+
+package Bio::Map::Marker;
+use vars qw(@ISA);
+use strict;
+use Bio::Root::Root;
+use Bio::Map::MarkerI;
+use Bio::Map::Position;
+
+@ISA = qw(Bio::Root::Root Bio::Map::MarkerI);
+
+=head2 new
+
+ Title   : new
+ Usage   : $o_marker = new Bio::Map::Marker( -name => 'Whizzy marker',
+	                                     -position => $position);
+ Function: Builds a new Bio::Map::Marker object
+ Returns : Bio::Map::Marker
+ Args    :
+           -name    => name of this microsatellite 
+                       [optional], string,default 'Unknown'
+
+           -positions => map position for this marker, [optional]
+                Bio::Map::PositionI-inherited obj, no default)
+
+=cut
+
+sub new {
+    my ($class,@args) = @_;
+    my $self = $class->SUPER::new(@args);
+    $self->{'_positions'} = [];
+    my ($name, $map, $position, $positions) = 
+	$self->_rearrange([qw(NAME 
+			      MAP
+			      POSITION
+			      POSITIONS
+			      )], @args);
+    if ($name) { $self->name($name); } 
+    else {$self->name('Unnamed marker'); }
+    $position  && $self->position($position); 
+    $positions && $self->positions($positions); 
+    $map       && $self->map($map);
+ 
+    return $self;
+}
+
+=head2 name
+
+ Title   : name
+ Usage   : $o_usat->name($new_name) _or_
+	   my $name = $o_usat->name()
+ Function: Get/Set the name for this Microsatellite
+ Returns : A scalar representing the current name of this marker
+ Args    : If provided, the current name of this marker
+	   will be set to $new_name.
+
+=cut
+
+sub name {
+    my ($self,$name) = @_;
+    my $last = $self->{'_name'};
+    if ($name) {
+	$self->{'_name'} = $name;
+    }
+    return $last;
+}
+
+
+=head2 map
+
+ Title   : map
+ Usage   : my $mymap = $marker->map();
+ Function: Get/Set the default map for the marker.
+           This is set by L<Bio::Map::CytoMap::add_element> method
+ Returns : L<Bio::Map::MapI>
+ Args    : [optional] new L<Bio::Map::MapI>
+
+=cut
+
+sub map {
+   my ($self,$map) = @_;
+   if( defined $map ) {
+       $self->thow('This is [$map], not Bio::Map::MapI object')
+	   unless $map->isa('Bio::Map::MapI');
+       $self->{'_default_map'} = $map;
+   }
+   return $self->{'_default_map'};
+}
+
+
+
+=head2 get_position_object
+
+ Title   : get_position_class
+ Usage   : my $pos = $marker->get_position_object();
+ Function: To get an object of the default Position class
+           for this Marker. Subclasses should redefine this method.
+           The Position needs to be Bio::Map::PositionI.
+ Returns : Bio::Map::Position
+ Args    : none
+
+See L<Bio::Map::Position> and L<Bio::Map::PositionI> for more information.
+
+=cut
+
+sub get_position_object {
+   my ($self) = @_;
+   return new Bio::Map::Position();
+}
+
+
+=head2 position
+
+ Title   : position
+ Usage   : $position = $mappable->position($map); OR
+           $mappable->position($position); # $position can be  Bio::Map::PositionI
+           $mappable->position(100); # or scalar if the marker has a default map
+           $mappable->position($map, 100); # if not give explicit $map
+ Function: Get/Set the Bio::Map::PositionI for a mappable element
+           in a specific Map
+           Adds the marker to a map automatically if Map is given. 
+           Altenaitvely, you can add the merker to the map first 
+           (L<Bio::Map::Map::add_element>) to set the default map
+ Returns : Bio::Map::PositionI
+ Args    : $position - Bio::Map::PositionI # Position we want to set
+            OR
+           $map  - Bio::Map::MapI AND
+           scalar
+            OR
+           scalar, but only if the marker has been added to a map
+
+=cut
+
+sub position {
+    my ($self, $pos, $secondary_pos) = @_;
+    my ($map);
+  POS: {
+      if ($pos) {
+	  if (ref($pos) eq 'SCALAR' || ref($pos) eq '') {
+	      $map = $self->map;
+	  }
+	  elsif (ref($pos) eq 'ARRAY') {
+	      $map = $pos->[0];
+	      $pos = $pos->[1];
+	  }
+	  elsif ($pos->isa('Bio::Map::PositionI')) {
+	      $pos->marker($self);
+
+	      $self->purge_positions;
+	      $self->add_position($pos);
+	      $map = $pos->map;
+	      $map->add_element($self) unless defined($self->map) && $self->map eq $map;
+	      last POS;
+	  }
+
+	  elsif ($pos->isa('Bio::Map::MapI')) {
+	      $map = $pos;
+	      $pos = $secondary_pos;
+	  } else {
+	      $map = $self->map;
+	  }
+	  $self->throw("You need to add a marker to a map before ". 
+		       "you can set positions without explicit map!" )
+	      unless $map;
+	  $self->throw("Position better be scalar, not [$pos=". ref($pos)  ."]")
+	      unless ref($pos) eq 'SCALAR' || ref($pos) eq ''; 
+
+	  my $newpos = $self->get_position_object;
+	  $newpos->map($map);
+	  $newpos->value($pos);
+	  $newpos->marker($self);
+
+	  $map->add_element($self) unless defined($self->map) && $self->map eq $map;
+	  $self->purge_positions;
+	  $self->add_position($newpos)
+	  }
+  }
+    my @array = $self->each_position();
+    $self->warn('More than one value is associated with this position')
+	if scalar @array > 1;
+    return $array[0];
+}
+
+=head2 add_position
+
+ Title   : add_position
+ Usage   : $position->add_position($position)
+ Function: Add the Position to the Marker container.
+           If you are using this method, you need to 
+           add the Marker to the Map yourself
+ Returns : none
+ Args    : Position - Reference to Bio::Map::PositionI 
+
+=cut
+
+sub add_position{
+   my ($self, $pos) = @_;
+   $self->throw("Must give a Position") unless defined $pos;
+
+   $self->throw("Must give a Bio::Map::PositionI, not [". ref($pos) ."]") 
+       unless $pos->isa('Bio::Map::PositionI');
+
+   my $map = $pos->map;
+   $map->add_element($self) unless defined($self->map) && $self->map eq $map;
+
+   push @{$self->{'_positions'}}, $pos;
+
+}
+
+=head2 positions
+
+ Title   : positions
+ Usage   : $mappable->positions([$pos1, $pos2, $pos3]); 
+ Function: Add multiple Bio::Map::PositionI for a mappable element
+           in a Map.
+ Returns : boolean
+ Args    : array ref of $map/value tuples or array ref of Positions
+
+=cut
+
+sub positions {
+    my ($self, $arrayref) = @_;
+    my ($map);
+   $self->throw_not_implemented();
+}
+
+=head2 each_position
+
+ Title   : each_position
+ Usage   : my @positions = $position->each_position('mapname');
+ Function: Retrieve a list of Positions 
+ Returns : Array of L<Bio::Map::PositionI>
+ Args    : none
+
+=cut
+
+sub each_position {
+   my ($self,$mapname) = @_;
+   $self->warn("Retrieving positions in a named map only is  ".
+	       "not implemented. Getting all.") if $mapname;
+   return @{$self->{'_positions'}}; 
+}
+
+=head2 purge_positions
+
+ Title   : purge_positions
+ Usage   : $marker->purge_positions
+ Function: Remove all the position values stored for a Marker
+ Returns : none
+ Args    : [optional] only purge values for a given map
+
+=cut
+
+sub purge_positions{
+    my ($self, $map) = @_;
+    $self->warn("Retrieving positions in a named map only, not implemented ") if $map;
+    $self->{'_positions'} = [];
+}
+
+=head2 known_maps
+
+ Title   : known_maps
+ Usage   : my @maps = $marker->known_maps
+ Function: Returns the list of maps that this position has values for
+ Returns : list of Bio::Map::MapI unique ids
+ Args    : none
+
+=cut
+
+sub known_maps{
+   my ($self) = @_;
+   my %hash;
+   foreach my $pos ($self->each_position) {
+       $hash{$pos->map->unique_id} = 1; 
+   }
+   return keys %hash;
+}
+
+=head2 in_map
+
+ Title   : in_map
+ Usage   : if ( $position->in_map($map) ) {}
+ Function: Tests if a position has values in a specific map
+ Returns : boolean
+ Args    : a map unique id OR Bio::Map::MapI
+
+=cut
+
+sub in_map{
+   my ($self,$map) = @_;
+
+   $self->throw("Need  an argument") unless $map;
+
+   if (ref($map) && $map->isa('Bio::Map::MapI')) {
+       foreach my $pos ($self->each_position) {
+	   return 1 if $pos->map eq $map;
+       }
+   } else { # assuming a scalar
+       foreach my $pos ($self->each_position) {
+	   return 1 if $pos->map->unique_id eq $map;
+       }
+   }
+   return 0;
+}
+
+=head2 Comparison methods
+
+=cut
+
+=head2 tuple
+
+ Title   : tuple
+ Usage   : ($me, $you) = $self->_tuple($compare)
+ Function: Utility ethod to extract numbers and test for missing values.
+ Returns : tuple values
+ Args    : Bio::Map::MappableI or Bio::Map::PositionI
+
+=cut
+
+sub tuple {
+    my ($self,$compare) = @_;
+    my ($me, $you) = (-1, -1);
+
+    $self->warn("Trying to compare [". $self->name. "] to nothing.") &&
+	return ($me, $you) unless defined $compare;
+    $self->warn("[". $self->name. "] has no position.") &&
+	return ($me, $you) unless $self->position;
+
+    $me  = $self->position->numeric;
+
+    if( $compare->isa('Bio::Map::MappableI') ){
+	$self->warn("[". $compare->name. "] has no position.") &&
+	    return ($me, $you) unless $compare->position;
+
+	$you = $compare->position->numeric;
+	return ($me, $you);
+
+    } elsif( $compare->isa('Bio::Map::PositionI') ) {
+
+	$you = $compare->numeric;
+	return ($me, $you);
+
+    } else { 
+	$self->warn("Can only run equals with Bio::Map::MappableI or ".
+		    "Bio::Map::PositionI not [$compare]"); 
+    }
+    return ($me, $you);
+}
+
+
+=head2 equals
+
+ Title   : equals
+ Usage   : if( $mappable->equals($mapable2)) ...
+ Function: Test if a position is equal to another position
+ Returns : boolean
+ Args    : Bio::Map::MappableI or Bio::Map::PositionI
+
+=cut
+
+sub equals {
+    my ($self,$compare) = @_;
+
+    my ($me, $you) = $self->tuple($compare);
+    return 0 if $me == -1 or $you == -1 ;
+    return $me == $you;
+}
+
+=head2 less_than
+
+ Title   : less_than
+ Usage   : if( $mappable->less_than($m2) ) ...
+ Function: Tests if a position is less than another position
+ Returns : boolean
+ Args    : Bio::Map::MappableI  or Bio::Map::PositionI
+
+=cut
+
+sub less_than {
+    my ($self,$compare) = @_;
+
+    my ($me, $you) = $self->tuple($compare);
+    return 0 if $me == -1 or $you == -1 ;
+    return $me < $you;
+}
+
+=head2 greater_than
+
+ Title   : greater_than
+ Usage   : if( $mappable->greater_than($m2) ) ...
+ Function: Tests if position is greater than another position
+ Returns : boolean
+ Args    : Bio::Map::MappableI or Bio::Map::PositionI
+
+=cut
+
+sub greater_than {
+    my ($self,$compare) = @_;
+
+
+    my ($me, $you) = $self->tuple($compare);
+    return 0 if $me == -1 or $you == -1 ;
+    return $me > $you;
+}
+
+1;