Archive Ensembl HomeArchive Ensembl Home
AlignSliceAdaptor.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 =head1 NAME
00020 
00021 Bio::EnsEMBL::Compara::DBSQL::AlignSliceAdaptor - An AlignSlice can be used to map genes from one species onto another one. This adaptor is used to fetch all the data needed for an AlignSlice from the database.
00022 
00023 =head1 INHERITANCE
00024 
00025 This module inherits attributes and methods from Bio::EnsEMBL::DBSQL::BaseAdaptor
00026 
00027 =head1 SYNOPSIS
00028   
00029   use Bio::EnsEMBL::Registry;
00030 
00031   ## Load adaptors using the Registry
00032   Bio::EnsEMBL::Registry->load_all();
00033 
00034   ## Fetch the query slice
00035   my $query_slice_adaptor = Bio::EnsEMBL::Registry->get_adaptor(
00036           "Homo sapiens", "core", "Slice");
00037   my $query_slice = $query_slice_adaptor->fetch_by_region(
00038           "chromosome", "14", 50000001, 50010001);
00039 
00040   ## Fetch the method_link_species_set
00041   my $mlss_adaptor = Bio::EnsEMBL::Registry->get_adaptor(
00042           "Compara26", "compara", "MethodLinkSpeciesSet");
00043   my $method_link_species_set = $mlss_adaptor->fetch_by_method_link_type_registry_aliases(
00044           "BLASTZ_NET", ["Homo sapiens", "Rattus norvegicus"]);
00045 
00046   ## Fetch the align_slice
00047   my $align_slice_adaptor = Bio::EnsEMBL::Registry->get_adaptor(
00048           "Compara26",
00049           "compara",
00050           "AlignSlice"
00051       );
00052   my $align_slice = $align_slice_adaptor->fetch_by_Slice_MethodLinkSpeciesSet(
00053           $query_slice,
00054           $method_link_species_set,
00055           "expanded"
00056       );
00057 
00058 =head1 OBJECT ATTRIBUTES
00059 
00060 =over
00061 
00062 =item db (from SUPER class)
00063 
00064 =back
00065 
00066 =head1 APPENDIX
00067 
00068 The rest of the documentation details each of the object methods. Internal methods are usually preceded with a _
00069 
00070 =cut
00071 
00072 
00073 # Let the code begin...
00074 
00075 package Bio::EnsEMBL::Compara::DBSQL::AlignSliceAdaptor;
00076 
00077 use strict;
00078 use Bio::EnsEMBL::DBSQL::BaseAdaptor;
00079 use Bio::EnsEMBL::Utils::Exception qw(throw warning info);
00080 use Bio::EnsEMBL::Compara::AlignSlice;
00081 
00082 our @ISA = qw(Bio::EnsEMBL::DBSQL::BaseAdaptor);
00083 
00084 =head2 new (CONSTRUCTOR)
00085 
00086   Arg        : 
00087   Example    : 
00088   Description: Creates a new AlignSliceAdaptor object
00089   Returntype : Bio::EnsEMBL::Compara::DBSQL::AlignSliceAdaptor
00090   Exceptions : none
00091   Caller     : Bio::EnsEMBL::Registry->get_adaptor
00092 
00093 =cut
00094 
00095 sub new {
00096   my $class = shift;
00097 
00098   my $self = $class->SUPER::new(@_);
00099 
00100   return $self;
00101 }
00102 
00103 
00104 =head2 fetch_by_Slice_MethodLinkSpeciesSet
00105 
00106   Arg[1]     : Bio::EnsEMBL::Slice $query_slice
00107   Arg[2]     : Bio::EnsEMBL::Compara::MethodLinkSpeciesSet $method_link_species_set
00108   Arg[3]     : [optional] boolean $expanded (def. FALSE)
00109   Arg[4]     : [optional] boolean $solve_overlapping (def. FALSE)
00110   Arg[5]     : [optional] Bio::EnsEMBL::Slice $target_slice
00111   Example    :
00112       my $align_slice = $align_slice_adaptor->fetch_by_Slice_MethodLinkSpeciesSet(
00113               $query_slice, $method_link_species_set);
00114   Description: Fetches from the database all the data needed for the AlignSlice
00115                corresponding to the $query_slice and the given
00116                $method_link_species_set. Setting $expanded to anything different
00117                from 0 or "" will create an AlignSlice in "expanded" mode. This means
00118                that gaps are allowed in the reference species in order to allocate
00119                insertions from other species.
00120                By default overlapping alignments are ignored. You can choose to
00121                reconciliate the alignments by means of a fake alignment setting the
00122                solve_overlapping option to TRUE.
00123                In order to restrict the AlignSlice to alignments with a given
00124                genomic region, you can specify a target_slice. All alignments which
00125                do not match this slice will be ignored.
00126   Returntype : Bio::EnsEMBL::Compara::AlignSlice
00127   Exceptions : thrown if wrong arguments are given
00128   Caller     : $object->methodname
00129 
00130 =cut
00131 
00132 sub fetch_by_Slice_MethodLinkSpeciesSet {
00133   my ($self, $reference_slice, $method_link_species_set, $expanded, $solve_overlapping, $target_slice) = @_;
00134 
00135   throw("[$reference_slice] is not a Bio::EnsEMBL::Slice")
00136       unless ($reference_slice and ref($reference_slice) and
00137           $reference_slice->isa("Bio::EnsEMBL::Slice"));
00138   throw("[$method_link_species_set] is not a Bio::EnsEMBL::Compara::MethodLinkSpeciesSet")
00139       unless ($method_link_species_set and ref($method_link_species_set) and
00140           $method_link_species_set->isa("Bio::EnsEMBL::Compara::MethodLinkSpeciesSet"));
00141 
00142   # Use cache whenever possible
00143   my $key = $reference_slice->name.":".$method_link_species_set->dbID.":".($expanded?"exp":"cond").
00144       ":".($solve_overlapping?"fake-overlap":"non-overlap");
00145   if (defined($target_slice)) {
00146     throw("[$target_slice] is not a Bio::EnsEMBL::Slice")
00147         unless ($target_slice and ref($target_slice) and
00148             $target_slice->isa("Bio::EnsEMBL::Slice"));
00149     $key .= ":".$target_slice->name();
00150   }
00151   return $self->{'_cache'}->{$key} if (defined($self->{'_cache'}->{$key}));
00152 
00153   my $genomic_align_block_adaptor = $self->db->get_GenomicAlignBlockAdaptor;
00154   my $genomic_align_blocks = $genomic_align_block_adaptor->fetch_all_by_MethodLinkSpeciesSet_Slice(
00155           $method_link_species_set,
00156           $reference_slice
00157       );
00158 
00159   ## Remove all alignments not matching the target slice if any
00160   if (defined($target_slice)) {
00161     ## Get the DnaFrag for the target Slice
00162     my $target_dnafrag = $self->db->get_DnaFragAdaptor->fetch_by_Slice($target_slice);
00163     if (!$target_dnafrag) {
00164       throw("Cannot get a DnaFrag for the target Slice");
00165     }
00166 
00167     ## Loop through all the alignment blocks and test whether they match the target slice or not
00168     for (my $i = 0; $i < @$genomic_align_blocks; $i++) {
00169       my $this_genomic_align_block = $genomic_align_blocks->[$i];
00170       my $hits_the_target_slice = 0;
00171       foreach my $this_genomic_align (@{$this_genomic_align_block->get_all_non_reference_genomic_aligns}) {
00172         if ($this_genomic_align->dnafrag->dbID == $target_dnafrag->dbID and
00173             $this_genomic_align->dnafrag_start <= $target_slice->end and
00174             $this_genomic_align->dnafrag_end >= $target_slice->start) {
00175           $hits_the_target_slice = 1;
00176           last;
00177         }
00178       }
00179       if (!$hits_the_target_slice) {
00180         splice(@$genomic_align_blocks, $i, 1);
00181         $i--;
00182       }
00183     }
00184   }
00185 
00186   my $genomic_align_trees = ();
00187   my $species_order;
00188   if ($method_link_species_set->method_link_class =~ /GenomicAlignTree/ and @$genomic_align_blocks) {
00189     my $genomic_align_tree_adaptor = $self->db->get_GenomicAlignTreeAdaptor;
00190     foreach my $this_genomic_align_block (@$genomic_align_blocks) {
00191 #       print $this_genomic_align_block->reference_genomic_align, "\n";
00192       my $this_genomic_align_tree = $genomic_align_tree_adaptor->
00193           fetch_by_GenomicAlignBlock($this_genomic_align_block);
00194       push(@$genomic_align_trees, $this_genomic_align_tree);
00195 #       $this_genomic_align_tree->print();
00196 #       foreach my $this_ga (@{$this_genomic_align_tree->get_all_sorted_genomic_align_nodes}) {
00197 #         print $this_ga->genomic_align->genome_db->name(), "\n";
00198 #       }
00199 
00200     }
00201     my $last_node_id = undef;
00202     my $tree_order;
00203     foreach my $this_genomic_align_tree (@$genomic_align_trees) {
00204       if ($last_node_id) {
00205         $tree_order->{$this_genomic_align_tree->node_id}->{prev} = $last_node_id;
00206         $tree_order->{$last_node_id}->{next} = $this_genomic_align_tree;
00207       }
00208       $last_node_id = $this_genomic_align_tree->node_id;
00209     }
00210 
00211     ## First tree. Build the species order using the first tree only
00212     foreach my $this_genomic_align_node (@{$genomic_align_trees->[0]->get_all_sorted_genomic_align_nodes}) {
00213       next if (!@{$this_genomic_align_node->get_all_genomic_aligns_for_node});
00214       my $this_genomic_align = $this_genomic_align_node->get_all_genomic_aligns_for_node->[0];
00215       my $genome_db = $this_genomic_align->genome_db;
00216       my $this_node_id = $this_genomic_align_node->node_id;
00217       my $right_node_id = _get_right_node_id($this_genomic_align_node);
00218       my $genomic_align_ids = [];
00219       foreach my $each_genomic_align (@{$this_genomic_align_node->get_all_genomic_aligns_for_node}) {
00220         push (@$genomic_align_ids, $each_genomic_align->dbID);
00221       }
00222       push(@$species_order,
00223             {
00224             genome_db => $genome_db,
00225             right_node_id => $right_node_id,
00226             genomic_align_ids => $genomic_align_ids,
00227             # #               last_node => $this_genomic_align_node,
00228             });
00229   }
00230     $| = 1;
00231     ## Combine the first tree with the second, the resulting order with the third and so on
00232     foreach my $this_genomic_align_tree (@$genomic_align_trees) {
00233       my $next_genomic_align_tree = $tree_order->{$this_genomic_align_tree->node_id}->{next};
00234       next if (!$next_genomic_align_tree);
00235 # # #       print STDERR "\nBEFORE:\n - ", join("\n - ", map {
00236 # # #               $_->{genome_db}->name." (".($_->{right_node_id} or "***").")  [".
00237 # # #               join(" : ", @{$_->{genomic_align_ids}})."]"
00238 # # #           } @$species_order), "\n";
00239       _combine_genomic_align_trees($species_order, $this_genomic_align_tree, $next_genomic_align_tree);
00240 #       $next_genomic_align_tree->print();
00241 # # #       print STDERR "\nAFTER:\n - ", join("\n - ", map {
00242 # # #               $_->{genome_db}->name." (".($_->{right_node_id} or "***").")  [".
00243 # # #               join(" : ", @{$_->{genomic_align_ids}})."]"
00244 # # #           } @$species_order), "\n";
00245 # # #       <STDIN>;
00246 
00247     }
00248   }
00249   my $align_slice = new Bio::EnsEMBL::Compara::AlignSlice(
00250           -adaptor => $self,
00251           -reference_Slice => $reference_slice,
00252           -Genomic_Align_Blocks => $genomic_align_blocks,
00253           -Genomic_Align_Trees => $genomic_align_trees,
00254           -species_order => $species_order,
00255           -method_link_species_set => $method_link_species_set,
00256           -expanded => $expanded,
00257           -solve_overlapping => $solve_overlapping,
00258       );
00259   $self->{'_cache'}->{$key} = $align_slice;
00260 
00261   return $align_slice;
00262 }
00263 
00264 
00265 =head2 fetch_by_GenomicAlignBlock
00266 
00267   Arg[1]     : Bio::EnsEMBL::Compara::GenomicAlignBlock $genomic_align_block
00268   Arg[2]     : [optional] boolean $expanded (def. FALSE)
00269   Arg[3]     : [optional] boolean $solve_overlapping (def. FALSE)
00270   Example    :
00271       my $align_slice = $align_slice_adaptor->fetch_by_GenomicAlignBlock(
00272               $genomic_align_block);
00273   Description: Uses this genomic_aling_block to create an AlignSlice.
00274                Setting $expanded to anything different
00275                from 0 or "" will create an AlignSlice in "expanded" mode. This means
00276                that gaps are allowed in the reference species in order to allocate
00277                insertions from other species.
00278                By default overlapping alignments are ignored. You can choose to
00279                reconciliate the alignments by means of a fake alignment setting the
00280                solve_overlapping option to TRUE.
00281   Returntype : Bio::EnsEMBL::Compara::AlignSlice
00282   Exceptions : thrown if arg[1] is not a Bio::EnsEMBL::Compara::GenomicAlignBlock
00283   Exceptions : thrown if $genomic_align_block has no method_link_species_set
00284   Caller     : $object->methodname
00285 
00286 =cut
00287 
00288 sub fetch_by_GenomicAlignBlock {
00289   my ($self, $genomic_align_block, $expanded, $solve_overlapping) = @_;
00290 
00291   throw("[$genomic_align_block] is not a Bio::EnsEMBL::Compara::GenomicAlignBlock")
00292       unless (UNIVERSAL::isa($genomic_align_block, "Bio::EnsEMBL::Compara::GenomicAlignBlock"));
00293   my $method_link_species_set = $genomic_align_block->method_link_species_set();
00294   throw("GenomicAlignBlock [$genomic_align_block] has no MethodLinkSpeciesSet")
00295       unless ($method_link_species_set);
00296   my $reference_genomic_align = $genomic_align_block->reference_genomic_align;
00297   if (!$reference_genomic_align) {
00298     $genomic_align_block->reference_genomic_align($genomic_align_block->get_all_GenomicAligns->[0]);
00299     $reference_genomic_align = $genomic_align_block->reference_genomic_align;
00300   }
00301   my $reference_slice = $reference_genomic_align->get_Slice();
00302 
00303   # Use cache whenever possible
00304   my $key;
00305   if ($genomic_align_block->dbID) {
00306     $key = "gab_".$genomic_align_block->dbID.":".($expanded?"exp":"cond").
00307         ":".($solve_overlapping?"fake-overlap":"non-overlap");
00308   } else {
00309     $key = "gab_".$genomic_align_block.":".($expanded?"exp":"cond").
00310         ":".($solve_overlapping?"fake-overlap":"non-overlap");
00311   }
00312   return $self->{'_cache'}->{$key} if (defined($self->{'_cache'}->{$key}));
00313 
00314   my $align_slice = new Bio::EnsEMBL::Compara::AlignSlice(
00315           -adaptor => $self,
00316           -reference_Slice => $reference_slice,
00317           -Genomic_Align_Blocks => [$genomic_align_block],
00318           -method_link_species_set => $method_link_species_set,
00319           -expanded => $expanded,
00320           -solve_overlapping => $solve_overlapping,
00321           -preserve_blocks => 1,
00322       );
00323   $self->{'_cache'}->{$key} = $align_slice;
00324 
00325   return $align_slice;
00326 }
00327 
00328 
00329 =head2 flush_cache
00330 
00331   Arg[1]     : none
00332   Example    : $align_slice_adaptor->flush_cache()
00333   Description: Destroy the cache
00334   Returntype : none
00335   Exceptions : none
00336   Caller     : $object->methodname
00337 
00338 =cut
00339 
00340 sub flush_cache {
00341   my ($self) = @_;
00342   foreach my $align_slice (values (%{$self->{'_cache'}})) {
00343     $align_slice->DESTROY;
00344   }
00345   undef $self->{'_cache'};
00346 }
00347 
00348 
00349 =head2 _combine_genomic_align_trees
00350 
00351   Arg[1]     : listref $species_order
00352   Arg[2]     : Bio::EnsEMBL::Compara::GenomicAlignTree $this_tree
00353   Arg[3]     : Bio::EnsEMBL::Compara::GenomicAlignTree $next_tree
00354   Example    :
00355   Description: This method tries to accommodate the nodes in $next_tree
00356                into $species_order. It uses several approaches. If there
00357                is information available about left and right node IDs, it
00358                will use it to link the nodes. Alternatively, it will rely
00359                on the species names to do its best. When a new species name
00360                appears in the $next_tree, it will try to insert it in the right
00361                position.
00362   Returntype : none
00363   Exceptions : none
00364   Caller     : $object->methodname
00365 
00366 =cut
00367 
00368 sub _combine_genomic_align_trees {
00369   my ($species_order, $this_tree, $next_tree) = @_;
00370 
00371   # $this_tree is already taken into account in the species_order. $next_tree is the new info to combine
00372   my $species_counter = 0;
00373   my $existing_node_ids; # Lists all node_ids in the next tree
00374   my $existing_right_node_ids;
00375   my $next_species_names; # Lists all species names in the next tree
00376   my $existing_species_names; # Lists all species names in the $species_order tracks
00377 
00378   ## Initialise values
00379   foreach my $this_genomic_align_node (@{$next_tree->get_all_sorted_genomic_align_nodes}) {
00380     my $this_node_id = $this_genomic_align_node->node_id;
00381     $existing_node_ids->{$this_node_id} = 1;
00382     push(@$next_species_names, $this_genomic_align_node->genomic_align_group->genome_db->name)
00383         if ($this_genomic_align_node->genomic_align_group and 
00384             $this_genomic_align_node->genomic_align_group->genome_db->name ne "ancestral_sequences");
00385   }
00386   foreach my $species_def (@$species_order) {
00387     my $right_node_id = $species_def->{right_node_id};
00388     $existing_right_node_ids->{$right_node_id} = 1 if ($right_node_id);
00389     push(@$existing_species_names, $species_def->{genome_db}->name);
00390   }
00391 
00392   ## MAIN LOOP. For each of the nodes in $next_tree, try to find the best position in $species_order.
00393   ## First, rely on the right_node_id, then on the species_name. If $next_tree has a new species_name,
00394   ## include it. If no good position has been found, append the node to the end of the $species_order.
00395   foreach my $this_genomic_align_node (@{$next_tree->get_all_sorted_genomic_align_nodes}) {
00396     next if (!@{$this_genomic_align_node->get_all_genomic_aligns_for_node});
00397     my $this_genomic_align = $this_genomic_align_node->get_all_genomic_aligns_for_node->[0];
00398     my $this_genome_db = $this_genomic_align->genome_db;
00399     my $this_node_id = $this_genomic_align_node->node_id;
00400     my $this_right_node_id = _get_right_node_id($this_genomic_align_node);
00401     my $these_genomic_align_ids = [];
00402     foreach my $each_genomic_align (@{$this_genomic_align_node->get_all_genomic_aligns_for_node}) {
00403       push (@$these_genomic_align_ids, $each_genomic_align->dbID);
00404     }
00405     ## DEBUG info
00406     # print "Inserting ", $this_genome_db->name, " into the species_order\n";
00407 
00408     my $match = 0;
00409     ## SECONDARY LOOP. Note that the $species_counter is not reset at the end of the loop.
00410     ## This ensures that we do not add two nodes to the same species_order track and that we
00411     ## preserve the order in all existing and in the new tree.
00412     while (!$match and $species_counter < @$species_order) {
00413       my $species_genome_db = $species_order->[$species_counter]->{genome_db};
00414       my $species_right_node_id = $species_order->[$species_counter]->{right_node_id};
00415       $match = 1;
00416 
00417       ## 1. Use info from species_right_node_id if available
00418       if (defined($species_right_node_id) and $species_right_node_id == $this_node_id) {
00419           $species_order->[$species_counter]->{right_node_id} = $this_right_node_id;
00420           # #         $species_order->[$species_counter]->{last_node} = $this_genomic_align_node;
00421         push (@{$species_order->[$species_counter]->{genomic_align_ids}}, @$these_genomic_align_ids);
00422         ## DEBUG info
00423         # print "NODE LINK!\n";
00424         # for (my $i = 0; $i<@$species_order; $i++) {
00425         #   if ($i == $species_counter) {
00426         #     print $species_order->[$i]->{genome_db}->name, "***\n";
00427         #   } else {
00428         #     print $species_order->[$i]->{genome_db}->name, "\n";
00429         #   }
00430         # }
00431 
00432       ## 2. Force insertions in a math to the next right_node is expected
00433       } elsif (defined($species_right_node_id) and exists($existing_node_ids->{$species_right_node_id})) {
00434         splice(@$species_order, $species_counter, 0, {
00435             genome_db => $this_genome_db,
00436             right_node_id => $this_right_node_id,
00437             genomic_align_ids => [@$these_genomic_align_ids],
00438           });
00439         ## DEBUG info
00440         # print "FORCE INSERT!\n";
00441         # for (my $i = 0; $i<@$species_order; $i++) {
00442         #   if ($i == $species_counter) {
00443         #     print $species_order->[$i]->{genome_db}->name, "***\n";
00444         #   } else {
00445         #     print $species_order->[$i]->{genome_db}->name, "\n";
00446         #   }
00447         # }
00448 
00449       ## 3. If there is no info about right node or this points to a node not found in next tree,
00450       ## rely on the species name
00451       } elsif ($this_genome_db->name eq $species_genome_db->name
00452                 and (!defined($species_right_node_id) or
00453                     !defined($existing_node_ids->{$species_right_node_id}))
00454           ) {
00455         $species_order->[$species_counter]->{right_node_id} = $this_right_node_id;
00456         push (@{$species_order->[$species_counter]->{genomic_align_ids}}, @$these_genomic_align_ids);
00457         ## DEBUG info
00458         # print "MATCH!\n";
00459         # for (my $i = 0; $i<@$species_order; $i++) {
00460         #   if ($i == $species_counter) {
00461         #     print $species_order->[$i]->{genome_db}->name, "***\n";
00462         #   } else {
00463         #     print $species_order->[$i]->{genome_db}->name, "\n";
00464         #   }
00465         # }
00466 
00467       ## 4. Insert this species if not found in the remaining set of existing species (in species_order)
00468       } elsif (!defined($existing_right_node_ids->{$this_node_id})
00469           and !grep {$_ eq $this_genome_db->name} @$existing_species_names) {
00470         splice(@$species_order, $species_counter, 0, {
00471             genome_db => $this_genome_db,
00472             right_node_id => $this_right_node_id,
00473             genomic_align_ids => [@$these_genomic_align_ids],
00474           });
00475         ## DEBUG info
00476         # print "INSERT!\n";
00477         # for (my $i = 0; $i<@$species_order; $i++) {
00478         #   if ($i == $species_counter) {
00479         #     print $species_order->[$i]->{genome_db}->name, "***\n";
00480         #   } else {
00481         #     print $species_order->[$i]->{genome_db}->name, "\n";
00482         #   }
00483         # }
00484 
00485       ## Unset $match, try with the next $species_order track.
00486       } else {
00487         $match = 0;
00488       }
00489       $species_counter++;
00490       shift(@$existing_species_names);
00491     }
00492 
00493     ## 5. We have not found any good position for this node: add a new track to the $species_order
00494     if (!$match) {
00495       push(@$species_order, {
00496             genome_db => $this_genome_db,
00497             right_node_id => $this_right_node_id,
00498             genomic_align_ids => [@$these_genomic_align_ids],
00499         });
00500       $species_counter++;
00501       ## DEBUG info
00502       # print "APPEND!\n";
00503       # for (my $i = 0; $i<@$species_order; $i++) {
00504       #   if ($i == $species_counter) {
00505       #     print $species_order->[$i]->{genome_db}->name, "***\n";
00506       #   } else {
00507       #    print $species_order->[$i]->{genome_db}->name, "\n";
00508       #   }
00509       # }
00510     }
00511     ## DEBUG info
00512     # print "[ENTER]";
00513     # <STDIN>;
00514     shift(@$next_species_names);
00515   }
00516 
00517   return;
00518 }
00519 
00520 sub _get_right_node_id {
00521   my ($this_genomic_align_node) = @_;
00522 
00523   my $use_right = 1;
00524   $use_right = 1 - $use_right if (!$this_genomic_align_node->root->get_original_strand);
00525 
00526   my $neighbour_node;
00527   if ($use_right) {
00528     $neighbour_node = $this_genomic_align_node->right_node;
00529   } else {
00530     $neighbour_node = $this_genomic_align_node->left_node;
00531   }
00532   if ($neighbour_node) {
00533     return $neighbour_node->node_id;
00534   }
00535 
00536   return undef;
00537 }
00538 
00539 
00540 1;