Archive Ensembl HomeArchive Ensembl Home
IndividualSlice.pm
Go to the documentation of this file.
00001 =head1 LICENSE
00002 
00003   Copyright (c) 1999-2012 The European Bioinformatics Institute and
00004   Genome Research Limited.  All rights reserved.
00005 
00006   This software is distributed under a modified Apache license.
00007   For license details, please see
00008 
00009     http://www.ensembl.org/info/about/code_licence.html
00010 
00011 =head1 CONTACT
00012 
00013   Please email comments or questions to the public Ensembl
00014   developers list at <dev@ensembl.org>.
00015 
00016   Questions may also be sent to the Ensembl help desk at
00017   <helpdesk@ensembl.org>.
00018 
00019 =cut
00020 
00021 =head1 NAME
00022 
00023 Bio::EnsEMBL::IndividualSlice - SubClass of the Slice. Represents the
00024 slice of the genome for a certain individual (applying the alleles for
00025 this individual)
00026 
00027 =head1 SYNOPSIS
00028 
00029   $sa = $db->get_SliceAdaptor;
00030 
00031   $slice =
00032     $sa->fetch_by_region( 'chromosome', 'X', 1_000_000, 2_000_000 );
00033 
00034   $individualSlice = $slice->get_by_Individual($individual_name);
00035 
00036   # Get the sequence from the Individual Slice: will contain IUPAC codes
00037   # for SNPs and Ensembl ambiguity codes for indels
00038   my $seq = $individualSlice->seq();
00039   print $seq;
00040 
00041   # Get a subSlice of the Strain
00042   my $subSlice_individual =
00043     $individualSlice->sub_Slice( 5_000, 8_000, 1 )
00044 
00045   # Compare two different individuals in the same Slice
00046   my $sliceIndividual2 = $slice->get_by_Individual($individual_name2);
00047   my $differences =
00048     $individualSlice->get_all_differences_IndividualSlice(
00049     $sliceIndividual2);
00050 
00051   foreach my $af ( @{$differences} ) {
00052     print
00053       "There is a difference between $individual_name "
00054       . "and $individual_name2 at ",
00055       $af->start, "-", $af->end,
00056       " with allele ", $af->allele_string(), "\n";
00057   }
00058 
00059 =head1 DESCRIPTION
00060 
00061 A IndividualSlice object represents a region of a genome for a certain
00062 individual.  It can be used to retrieve sequence or features from a
00063 individual.
00064 
00065 =head1 METHODS
00066 
00067 =cut
00068 
00069 package Bio::EnsEMBL::IndividualSlice;
00070 use vars qw(@ISA);
00071 use strict;
00072 
00073 use Bio::EnsEMBL::Utils::Argument qw(rearrange);
00074 use Bio::EnsEMBL::Utils::Sequence qw(reverse_comp);
00075 use Bio::EnsEMBL::Slice;
00076 use Bio::EnsEMBL::Mapper;
00077 use Bio::EnsEMBL::Utils::Exception qw(throw deprecate warning);
00078 
00079 @ISA = qw(Bio::EnsEMBL::Slice);
00080 
00081 
00082 =head2 new
00083 
00084     Arg [1..N]  : List of named arguments
00085                   Bio::EnsEMBL::CoordSystem COORD_SYSTEM
00086                   string SEQ_REGION_NAME,
00087                   int    START,
00088                   int    END,
00089                   string VERSION (optional, defaults to '')
00090                   int    STRAND, (optional, defaults to 1)
00091                   Bio::EnsEMBL::DBSQL::SliceAdaptor ADAPTOR (optional)
00092     Arg[N+1]      : string $individual_name
00093     Example     : $individualSlice = Bio::EnsEMBL::IndividualSlice->new(-coord_system => $cs,
00094                                     -start => 1,
00095                                     -end => 10000,
00096                                     -strand => 1,
00097                                     -seq_region_name => 'X',
00098                                     -seq_region_length => 12e6,
00099                                     -individual_name => $individual_name);
00100     Description : Creates a new Bio::EnsEMBL::IndividualSlice object that will contain a shallow copy of the
00101                   Slice object, plus additional information such as the individual this Slice refers to
00102                   and listref of Bio::EnsEMBL::Variation::AlleleFeatures of differences with the
00103                   reference sequence
00104     ReturnType  : Bio::EnsEMBL::IndividualSlice
00105     Exceptions  : none
00106     Caller      : general
00107 
00108 =cut
00109 
00110 sub new{
00111     my $caller = shift;
00112     my $class = ref($caller) || $caller;
00113 
00114     #create the IndividualSlice object as the Slice, plus the individual attribute
00115     my ($individual_name, $sample_id) = rearrange(['INDIVIDUAL', 'SAMPLE_ID'],@_);
00116 
00117     my $self = $class->SUPER::new(@_);
00118 
00119     $self->{'individual_name'} = $individual_name;
00120     $self->{'sample_id'} = $sample_id;
00121 
00122     return $self;
00123 
00124 }
00125 
00126 =head2 individual_name
00127 
00128     Arg [1]     : (optional) string $individual_name
00129     Example     : my $individual_name = $individualSlice->individual_name();
00130     Description : Getter/Setter for the name of the individual in the slice
00131     ReturnType  : string
00132     Exceptions  : none
00133     Caller      : general
00134 
00135 =cut
00136 
00137 sub individual_name{
00138    my $self = shift;
00139    if (@_){
00140        $self->{'individual_name'} = shift @_;
00141    }
00142    return $self->{'individual_name'};
00143 }
00144 
00145 =head2 seq
00146 
00147   Arg [1]    : none
00148   Example    : print "SEQUENCE = ", $strainSlice->seq();
00149   Description: Returns the sequence of the region represented by this
00150                StrainSlice formatted as a string.
00151   Returntype : string
00152   Exceptions : none
00153   Caller     : general
00154 
00155 =cut
00156 
00157 sub seq {
00158   my $self = shift;
00159 
00160   # special case for in-between (insert) coordinates
00161   return '' if($self->start() == $self->end() + 1);
00162 
00163   return $self->{'seq'} if($self->{'seq'});
00164 
00165   if($self->adaptor()) {
00166     my $seqAdaptor = $self->adaptor()->db()->get_SequenceAdaptor();
00167     my $reference_sequence = $seqAdaptor->fetch_by_Slice_start_end_strand($self,1,undef,1); #get the reference sequence for that slice
00168     #apply all differences to the reference sequence
00169 
00170     # sort edits in reverse order to remove complication of
00171     # adjusting downstream edits
00172     my @allele_features_ordered = sort {$b->start() <=> $a->start() || $b->end() <=> $a->end()} @{$self->{'alleleFeatures'}} if (defined $self->{'alleleFeatures'});
00173 
00174     foreach my $af (@allele_features_ordered){
00175     $af->apply_edit($reference_sequence); #change, in the reference sequence, the af
00176     }
00177 #    return substr(${$reference_sequence},0,1) if ($self->length == 1); 
00178     return ${$reference_sequence}; #returns the reference sequence, applying the alleleFeatures
00179   }
00180 
00181   # no attached sequence, and no db, so just return Ns
00182   return 'N' x $self->length();
00183 }
00184 
00185 =head2 get_all_differences_Slice
00186 
00187     Args        : none
00188     Example     : my $differences = $individualSlice->get_all_differences_Slice()
00189     Description : Gets all differences between the IndividualSlice object and the Slice is defined
00190     ReturnType  : listref of Bio::EnsEMBL::Variation::AlleleFeature
00191     Exceptions  : none
00192     Caller      : general
00193 
00194 =cut
00195 
00196 sub get_all_differences_Slice{
00197     my $self = shift;
00198     my $differences; #reference to the array with the differences between Slice and StrainSlice
00199     my $ref_allele;
00200     foreach my $difference (@{$self->{'alleleFeatures'}}){
00201     if ($difference->length_diff == 0){
00202         #the difference is a SNP, check if it is the same as the reference allele
00203         $ref_allele = $self->SUPER::subseq($difference->start,$difference->end,$difference->strand);
00204         $ref_allele = '-' if ($ref_allele eq '');
00205         if ($ref_allele ne $difference->allele_string){
00206         #when the alleleFeature is different from the reference allele, add to the differences list
00207         push @{$differences},$difference;
00208         }
00209     }
00210     else{
00211         push @{$differences},$difference;
00212     }
00213     }
00214 
00215     return $differences;
00216 
00217 }
00218 
00219 =head2 get_all_differences_IndividualSlice
00220 
00221     Arg[1]      : Bio::EnsEMBL::IndividualSlice $is
00222     Example     : my $differences = $individualSlice->get_all_differences_IndividualSlice($individualslice)
00223     Description : Gets differences between 2 IndividualSlice objects
00224     ReturnType  : listref of Bio::EnsEMBL::Variation::AlleleFeature
00225     Exceptions  : thrown on bad argument
00226     Caller      : general
00227 
00228 =cut
00229 
00230 sub get_all_differences_IndividualSlice{
00231     my $self = shift;
00232     my $individualSlice = shift;
00233 
00234     if (!ref($individualSlice) || !$individualSlice->isa('Bio::EnsEMBL::IndividualSlice')){
00235     throw('Bio::EnsEMBL::IndividualSlice arg expected');
00236     }
00237     if ( @{$self->{'alleleFeatures'}} == 0 && @{$individualSlice->{'alleleFeatures'}} == 0){
00238     return undef; #there are no differences in any of the Individuals
00239     
00240     }
00241     my $differences; #differences between individuals
00242     if (@{$individualSlice->{'alleleFeatures'}} == 0){
00243     #need to create a copy of alleleFeature for the first Individual
00244     foreach my $difference (@{$self->{'alleleFeatures'}}){
00245         my %vf = %$difference;
00246         push @{$differences},bless \%vf,ref($difference);
00247     }
00248     }
00249     elsif (@{$self->{'alleleFeatures'}} == 0){
00250     #need to create a copy of AlleleFeature, but changing the allele by the allele in the reference sequence
00251     foreach my $difference (@{$individualSlice->{'alleleFeatures'}}){
00252         push @{$differences}, $individualSlice->_convert_difference($difference);
00253     }
00254     }
00255     else{
00256     #both individuals have differences
00257     #create a hash with the differences in the first slice
00258     my %allele_features_self = map {$_->start.'-'.$_->end => $_} @{$self->{'alleleFeatures'}};
00259     foreach my $difference (@{$individualSlice->{'alleleFeatures'}}){
00260         #there is no difference in the other individual slice, convert the allele
00261       if (!defined $allele_features_self{$difference->start.'-'.$difference->end}){
00262           push @{$differences},$individualSlice->_convert_difference($difference);
00263         }
00264         else{
00265         #if it is defined and have the same allele, delete from the hash since it is not a difference
00266         #between the individuals
00267         if ($allele_features_self{$difference->start.'-'.$difference->end}->allele_string eq $difference->allele_string){
00268           delete $allele_features_self{$difference->start.'-'.$difference->end};
00269         }
00270         }
00271     }   
00272     #and finally, make a shallow copy of the differences in the first individual
00273     foreach my $difference (values %allele_features_self){
00274       my %vf = %$difference;
00275       push @{$differences},bless \%vf,ref($difference);
00276     }
00277     
00278     }
00279     #need to map differences to the first individual, self, since the coordinates are in the Slice coordinate system
00280     my $mapper = $self->mapper(); #now that we have the differences, map them in the IndividualSlice
00281     my @results;
00282     foreach my $difference (@{$differences}){
00283       @results = $mapper->map_coordinates('Slice',$difference->start,$difference->end,$difference->strand,'Slice');
00284       #we can have 3 possibilities:
00285       #the difference is an insertion and when mapping returns the boundaries of the insertion in the IndividualSlice
00286       if (@results == 2){
00287     #the first position in the result is the beginning of the insertion
00288     if($results[0]->start < $results[1]->start){
00289       $difference->start($results[0]->end+1);
00290       $difference->end($results[1]->start-1);
00291     }
00292     else{
00293       #it is the second position the beginning of the insertion
00294       $difference->start($results[1]->end+1);
00295       $difference->end($results[0]->start-1);
00296     }
00297     $difference->strand($results[0]->strand);
00298       }
00299       else{
00300     #it can be either a SNP or a deletion, and we have the coordinates in the result, etither a Bio::EnsEMBL::Mapper::Coordinate
00301     # or a Bio::EnsEMBL::Mapper::IndelCoordinate
00302     $difference->start($results[0]->start);
00303     $difference->end($results[0]->end);
00304     $difference->strand($results[0]->strand);
00305       }
00306     }
00307     
00308     return $differences;
00309 }
00310 
00311 #for a given AlleleFeature, converts the allele into the reference allele and returns
00312 #the converted AlleleFeature
00313 
00314 sub _convert_difference{
00315     my $self = shift;
00316     my $difference = shift;
00317     my %new_af = %$difference; #make a copy of the alleleFeature
00318     #and change the allele with the one from the reference Slice
00319     $new_af{'allele_string'} = $self->SUPER::subseq($difference->start,$difference->end,$difference->strand);
00320     return bless \%new_af,ref($difference);
00321 }
00322 
00323 =head2 mapper
00324 
00325   Args       : none
00326   Description: Getter for the mapper between the between the IndividualSlice and the Slice it refers to. 
00327                It is done automatically when necessary to create subSlice or to get the differences between individuals
00328   Returntype : Bio::EnsEMBL::Mapper
00329   Exceptions : none
00330   Caller     : Internal function
00331 
00332 =cut
00333 
00334 sub mapper{
00335     my $self = shift;
00336    
00337     if (@_) {
00338     #allow to create again the mapper
00339     delete $self->{'mapper'};
00340     }
00341     if(!defined $self->{'mapper'}){
00342     #create the mapper between the Slice and StrainSlice
00343     my $mapper = Bio::EnsEMBL::Mapper->new('Slice','IndividualSlice');
00344     #align with Slice
00345     #get all the VariationFeatures in the Individual Slice, from start to end in the Slice
00346     my @allele_features_ordered = sort {$a->start() <=> $b->start() || $b->end() <=> $a->end()} @{$self->{'alleleFeatures'}} if (defined $self->{'alleleFeatures'});
00347     
00348     my $start_slice = 1;
00349     my $end_slice;
00350     my $start_individual = 1;
00351     my $end_individual;
00352     my $length_allele;
00353     my $total_length_diff = 0;
00354     #we will walk from left to right in the slice object, updating the start and end individual every time
00355     #there is a new alleleFeature in the Individual
00356     foreach my $allele_feature (@allele_features_ordered){
00357         #we have a insertion/deletion: marks the beginning of new slice move coordinates
00358         if ($allele_feature->length_diff != 0){
00359             $total_length_diff += $allele_feature->length_diff;
00360         $length_allele = $allele_feature->length + $allele_feature->length_diff(); #length of the allele in the Individual
00361         $end_slice = $allele_feature->start() - 1; #set the end of the slice before the alleleFeature
00362         if ($end_slice >= $start_slice){
00363             #normal cases (not with gaps)
00364             $end_individual = $end_slice - $start_slice + $start_individual; #set the end of the individual from the beginning plus the offset
00365             #add the sequence that maps
00366             $mapper->add_map_coordinates('Slice',$start_slice,$end_slice,1,'IndividualSlice',$start_individual,$end_individual);
00367             #and add the indel
00368             $mapper->add_indel_coordinates('Slice',$end_slice+1,$end_slice + $allele_feature->length,1,'IndividualSlice',$end_individual+1,$end_individual + $length_allele);
00369             $start_individual = $end_individual + $length_allele + 1; #set the beginning of the individual after the allele
00370         }
00371         else{
00372             #add the indel
00373             $mapper->add_indel_coordinates('Slice',$end_slice+1,$end_slice + $allele_feature->length,1,'IndividualSlice',$end_individual+1,$end_individual + $length_allele);
00374             $start_individual += $length_allele;
00375         }
00376         $start_slice = $end_slice + $allele_feature->length+ 1; #set the beginning of the slice after the variation feature
00377         }
00378     }
00379     if ($start_slice <= $self->length){
00380         #if we haven't reached the end of the IndividualSlice, add the final map coordinates between the individual and the slice
00381         $mapper->add_map_coordinates('Slice',$start_slice,$self->length,1,'IndividualSlice',$start_individual,$start_individual + $self->length - $start_slice);
00382     }
00383 
00384     $mapper->add_map_coordinates('Slice', -$self->start+1, 0,1, 'IndividualSlice', -$self->start +1,0) if ($self->start > 0); #before individualSlice
00385     $mapper->add_map_coordinates('Slice', $self->length + 1,$self->seq_region_length - ($self->length +1),1, 'IndividualSlice', $self->length + 1 + $total_length_diff,$self->seq_region_length + $total_length_diff - ($self->length +1) ) if ($self->length <= $self->seq_region_length); #after strainSlice
00386     $self->{'mapper'} = $mapper;
00387     }
00388     return $self->{'mapper'};
00389 }
00390 
00391 =head2 sub_Slice
00392 
00393   Arg   1    : int $start
00394   Arg   2    : int $end
00395   Arge [3]   : int $strand
00396   Example    : none
00397   Description: Makes another IndividualSlice that covers only part of this IndividualSlice
00398                with the appropriate differences to the reference Slice
00399                If a slice is requested which lies outside of the boundaries
00400                of this function will return undef.  This means that
00401                behaviour will be consistant whether or not the slice is
00402                attached to the database (i.e. if there is attached sequence
00403                to the slice).  Alternatively the expand() method or the
00404                SliceAdaptor::fetch_by_region method can be used instead.
00405   Returntype : Bio::EnsEMBL::IndividualSlice or undef if arguments are wrong
00406   Exceptions : thrown when trying to get the subSlice in the middle of a
00407                insertion
00408   Caller     : general
00409 
00410 =cut
00411 
00412 sub sub_Slice {
00413   my ( $self, $start, $end, $strand ) = @_;
00414   my $mapper = $self->mapper();
00415   #map from the Individual to the Slice to get the sub_Slice, and then, apply the differences in the subSlice
00416   my @results = $mapper->map_coordinates('IndividualSlice',$start,$end,$strand,'IndividualSlice');
00417   my $new_start;
00418   my $new_end;
00419   my $new_strand;
00420   my $new_seq;
00421   #Get need start and end for the subSlice of the IndividualSlice
00422   my @results_ordered = sort {$a->start <=> $b->start} grep {ref($_) eq 'Bio::EnsEMBL::Mapper::Coordinate'} @results;
00423   $new_start = $results_ordered[0]->start();
00424   $new_strand = $results_ordered[0]->strand() if (ref($results_ordered[0]) eq 'Bio::EnsEMBL::Mapper::Coordinate');
00425 #  $new_strand = $results_ordered[-1]->strand() if (ref($results_ordered[-1]) eq 'Bio::EnsEMBL::Mapper::Coordinate');
00426   $new_end = $results_ordered[-1]->end();  #get last element of the array, the end of the slice
00427 
00428   my $subSlice = $self->SUPER::sub_Slice($new_start,$new_end,$new_strand);
00429   $subSlice->{'individual_name'} = $self->{'individual_name'};
00430 
00431   my $new_alleles; #reference to an array that will contain the variationFeatures in the new subSlice
00432   #update the VariationFeatures in the sub_Slice of the Individual
00433   my %af;
00434   my $new_allele_feature;
00435   foreach my $alleleFeature (@{$self->{'alleleFeatures'}}){      
00436       $new_allele_feature = $alleleFeature->transfer($subSlice);
00437       #only transfer the coordinates to the SubSlice that are within the boundaries
00438       if ($new_allele_feature->start >= 1 && $new_allele_feature->end <= $subSlice->length){
00439       push @{$new_alleles}, $new_allele_feature;
00440       }
00441   }
00442   $subSlice->{'alleleFeatures'} = $new_alleles;
00443   return $subSlice;
00444 
00445 }
00446 
00447 =head2 subseq
00448 
00449   Arg  [1]   : int $startBasePair
00450                relative to start of slice, which is 1.
00451   Arg  [2]   : int $endBasePair
00452                relative to start of slice.
00453   Arg  [3]   : (optional) int $strand
00454                The strand of the individual slice to obtain sequence from. Default
00455                value is 1.
00456   Description: returns string of dna sequence
00457   Returntype : txt
00458   Exceptions : end should be at least as big as start
00459                strand must be set
00460   Caller     : general
00461 
00462 =cut
00463 
00464 sub subseq {
00465   my ( $self, $start, $end, $strand ) = @_;
00466 
00467   if ( $end+1 < $start ) {
00468     throw("End coord + 1 is less then start coord");
00469   }
00470 
00471   # handle 'between' case for insertions
00472   return '' if( $start == $end + 1);
00473 
00474   $strand = 1 unless(defined $strand);
00475 
00476   if ( $strand != -1 && $strand != 1 ) {
00477     throw("Invalid strand [$strand] in call to Slice::subseq.");
00478   }
00479 
00480   my $subseq;
00481   my $seq;
00482   if($self->adaptor){
00483     my $seqAdaptor = $self->adaptor()->db()->get_SequenceAdaptor();
00484     $subseq = ${$seqAdaptor->fetch_by_Slice_start_end_strand($self,$start,$end,$strand)}; #get the reference sequence for that slice
00485     #apply all differences to the reference sequence
00486     # sort edits in reverse order to remove complication of
00487     # adjusting downstream edits
00488     my @allele_features_ordered = sort {$b->start() <=> $a->start() || $b->end() <=> $a->end()} @{$self->{'alleleFeatures'}} if (defined $self->{'alleleFeatures'});
00489     my $af_start;
00490     my $af_end;
00491     foreach my $af (@allele_features_ordered){
00492     if (($af->start - $start +1 > 0) && ($end - $af->end > 0)){
00493         #save the current start and end of the alleleFeature before changing for apply_edit
00494         $af_start = $af->start;
00495         $af_end = $af->end;
00496         #apply the difference if the feature is in the new slice
00497         $af->start($af->start - $start +1);
00498         $af->end($af->end - $start +1);
00499         $af->apply_edit(\$subseq); #change, in the reference sequence, the af
00500         #restore the initial values of alleleFeature start and end
00501         $af->start($af_start);
00502         $af->end($af_end);
00503         
00504     }
00505     }
00506   } 
00507   else {
00508       ## check for gap at the beginning and pad it with Ns
00509       if ($start < 1) {
00510       $subseq = "N" x (1 - $start);
00511       $start = 1;
00512       }
00513       $subseq .= substr ($self->seq(), $start-1, $end - $start + 1);
00514       ## check for gap at the end and pad it with Ns
00515     if ($end > $self->length()) {
00516     $subseq .= "N" x ($end - $self->length());
00517     }
00518       reverse_comp(\$subseq) if($strand == -1);
00519   }
00520   return $subseq;
00521   
00522 }
00523 
00524 =head2 get_all_Transcripts
00525 
00526   Args       : None
00527   Example    : @transcripts = @{$individualslice->get_all_Transcripts)};
00528   Description: Gets all transcripts which overlap this Individual Slice.  If you want to
00529                specify a particular analysis or type, then you are better off
00530                using get_all_Genes or get_all_Genes_by_type and iterating
00531                through the transcripts of each gene.
00532   Returntype : reference to a list of Bio::EnsEMBL::Transcripts
00533   Exceptions : none
00534   Caller     : general
00535 
00536 =cut
00537 
00538 sub get_all_Transcripts {
00539   my $self = shift;
00540 
00541   my $transcripts = $self->SUPER::get_all_Transcripts(1);
00542   $self->map_to_Individual($transcripts);
00543 
00544   return $transcripts;
00545 }
00546 
00547 
00548 =head2 get_all_Exons
00549 
00550   Arg [1]    : (optional) string $dbtype
00551                The dbtype of exons to obtain.  This assumes that the db has
00552                been added to the DBAdaptor under this name (using the
00553                DBConnection::add_db_adaptor method).
00554   Example    : @exons = @{$individualSlice->get_all_Exons};
00555   Description: Gets all exons which overlap this IndividualSlice.  Note that these exons
00556                will not be associated with any transcripts, so this may not
00557                be terribly useful.
00558   Returntype : reference to a list of Bio::EnsEMBL::Exons
00559   Exceptions : none
00560   Caller     : general
00561 
00562 =cut
00563 
00564 sub get_all_Exons {
00565   my $self = shift;
00566   my $dbtype = shift;
00567 
00568   my $exons = $self->SUPER::get_all_Exons($dbtype);
00569   $self->map_to_Individual($exons); #map the exons to the Individual
00570 
00571   return $exons;
00572 }
00573 
00574 =head2 get_all_Genes
00575 
00576   Arg [1]    : (optional) string $logic_name
00577                The name of the analysis used to generate the genes to retrieve
00578   Arg [2]    : (optional) string $dbtype
00579                The dbtype of genes to obtain.  This assumes that the db has
00580                been added to the DBAdaptor under this name (using the
00581                DBConnection::add_db_adaptor method).
00582   Example    : @genes = @{$individualSlice->get_all_Genes};
00583   Description: Retrieves all genes that overlap this slice.
00584   Returntype : listref of Bio::EnsEMBL::Genes
00585   Exceptions : none
00586   Caller     : none
00587 
00588 =cut
00589 
00590 sub get_all_Genes{
00591   my ($self, $logic_name, $dbtype) = @_;
00592 
00593   my $genes = $self->SUPER::get_all_Genes($logic_name, $dbtype, 1);
00594 
00595   $self->map_to_Individual($genes);
00596 
00597   foreach my $gene (@{$genes}){
00598       $self->map_to_Individual($gene->get_all_Exons); #map the Exons to the Individual
00599       $self->map_to_Individual($gene->get_all_Transcripts); #map the Transcripts to the Individual
00600   }
00601 
00602   return $genes;
00603 }
00604 
00605 =head2 map_to_Individual
00606 
00607     Arg[1]      : ref $features
00608     Example     : $individualSlice->map_to_Individual($exons);
00609     Description : Gets the features from the Slice and maps it in the IndividualSlice, using the mapper
00610                   between Slice and IndividualSlice
00611     ReturnType  : None
00612     Exceptions  : None
00613     Caller      : general
00614     
00615 =cut
00616 
00617 sub map_to_Individual{
00618     my $self = shift;
00619     my $features = shift;
00620 
00621     my $mapper = $self->mapper();
00622     my (@results, @results_ordered, $new_start, $new_end, $new_strand);
00623     #foreach of the transcripts, map them to the IndividualSlice and replace the Slice with the IndividualSlice
00624     foreach my $feature (@{$features}){
00625     $feature->slice($self); #replace the IndividualSlice as the Slice for this feature (the Slice plus the AlleleFeatures)
00626     #map from the Slice to the Individual Slice
00627     my @results = $mapper->map_coordinates('Slice',$feature->start,$feature->end,$feature->strand,'Slice');
00628     #from the results, order them but filter out those that are not coordinates
00629     @results_ordered = sort {$a->start <=> $b->start} grep {ref($_) eq 'Bio::EnsEMBL::Mapper::Coordinate'} @results;
00630     $new_start = $results_ordered[0]->start();
00631     $new_strand = $results_ordered[0]->strand();
00632     $new_end = $results_ordered[-1]->end();  #get last element of the array, the end of the slice
00633     $feature->start($new_start);  #update new coordinates
00634     $feature->end($new_end);
00635     $feature->strand($new_strand);
00636   }
00637 }
00638 
00639 sub alleleFeatures{
00640     my $self = shift;
00641     return $self->{'alleleFeatures'};
00642 }
00643 
00644 sub add_AlleleFeature{
00645     my $self = shift;
00646 
00647     if (@_){
00648     if(!ref($_[0]) || !$_[0]->isa('Bio::EnsEMBL::Variation::AlleleFeature')) {
00649         throw("Bio::EnsEMBL::Variation::AlleleFeature argument expected");
00650     }
00651     #add the alleleFeature to the individualSlice
00652     push @{$self->{'alleleFeatures'}},shift;
00653     }
00654 }
00655 1;