Archive Ensembl HomeArchive Ensembl Home
GenomicAlignBlockAdaptor.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::DBSQL::Compara::GenomicAlignBlockAdaptor
00022 
00023 =head1 SYNOPSIS
00024 
00025 =head2 Connecting to the database using the Registry
00026 
00027   use Bio::EnsEMBL::Registry;
00028 
00029   my $reg = "Bio::EnsEMBL::Registry";
00030 
00031   $reg->load_registry_from_db(-host=>"ensembldb.ensembl.org", -user=>"anonymous");
00032 
00033   my $genomic_align_block_adaptor = $reg->get_adaptor(
00034       "Multi", "compara", "GenomicAlignBlock");
00035 
00036 =head2 Store/Delete data from the database
00037 
00038   $genomic_align_block_adaptor->store($genomic_align_block);
00039 
00040   $genomic_align_block_adaptor->delete_by_dbID($genomic_align_block->dbID);
00041 
00042 =head2 Retrieve data from the database
00043 
00044   $genomic_align_block = $genomic_align_block_adaptor->fetch_by_dbID(12);
00045 
00046   $genomic_align_blocks = $genomic_align_block_adaptor->fetch_all_by_MethodLinkSpeciesSet(
00047       $method_link_species_set);
00048 
00049   $genomic_align_blocks = $genomic_align_block_adaptor->fetch_all_by_MethodLinkSpeciesSet_Slice(
00050       $method_link_species_set, $human_slice);
00051 
00052   $genomic_align_blocks = $genomic_align_block_adaptor->fetch_all_by_MethodLinkSpeciesSet_DnaFrag(
00053       $method_link_species_set, $human_dnafrag);
00054 
00055   $genomic_align_blocks = $genomic_align_block_adaptor->fetch_all_by_MethodLinkSpeciesSet_DnaFrag_DnaFrag(
00056       $method_link_species_set, $human_dnafrag, $mouse_dnafrag);
00057 
00058 =head2 Other methods
00059 
00060 $genomic_align_block = $genomic_align_block_adaptor->
00061     retrieve_all_direct_attributes($genomic_align_block);
00062 
00063 $genomic_align_block_adaptor->lazy_loading(1);
00064 
00065 $genomic_align_block_adaptor->use_autoincrement
00066 
00067 =head1 DESCRIPTION
00068 
00069 This module is intended to access data in the genomic_align_block table.
00070 
00071 Each alignment is represented by Bio::EnsEMBL::Compara::GenomicAlignBlock. Each GenomicAlignBlock
00072 contains several Bio::EnsEMBL::Compara::GenomicAlign, one per sequence included in the alignment.
00073 The GenomicAlign contains information about the coordinates of the sequence and the sequence of
00074 gaps, information needed to rebuild the aligned sequence. By combining all the aligned sequences
00075 of the GenomicAlignBlock, it is possible to get the orignal alignment back.
00076 
00077 =head1 INHERITANCE
00078 
00079 This class inherits all the methods and attributes from Bio::EnsEMBL::DBSQL::BaseAdaptor
00080 
00081 =head1 SEE ALSO
00082 
00083  - Bio::EnsEMBL::Registry
00084  - Bio::EnsEMBL::DBSQL::BaseAdaptor
00085  - Bio::EnsEMBL::BaseAdaptor
00086  - Bio::EnsEMBL::Compara::GenomicAlignBlock
00087  - Bio::EnsEMBL::Compara::GenomicAlign
00088  - Bio::EnsEMBL::Compara::GenomicAlignGroup,
00089  - Bio::EnsEMBL::Compara::MethodLinkSpeciesSet
00090  - Bio::EnsEMBL::Compara::DBSQL::MethodLinkSpeciesSetAdaptor
00091  - Bio::EnsEMBL::Slice
00092  - Bio::EnsEMBL::SliceAdaptor
00093  - Bio::EnsEMBL::Compara::DnaFrag
00094  - Bio::EnsEMBL::Compara::DBSQL::DnaFragAdaptor
00095 
00096 =head1 APPENDIX
00097 
00098 The rest of the documentation details each of the object methods. Internal methods are usually preceded with a _
00099 
00100 =cut
00101 
00102 
00103 # Let the code begin...
00104 
00105 
00106 package Bio::EnsEMBL::Compara::DBSQL::GenomicAlignBlockAdaptor;
00107 use vars qw(@ISA);
00108 use strict;
00109 
00110 use Bio::EnsEMBL::DBSQL::BaseAdaptor;
00111 use Bio::EnsEMBL::Compara::GenomicAlignBlock;
00112 use Bio::EnsEMBL::Compara::GenomicAlign;
00113 use Bio::EnsEMBL::Compara::DnaFrag;
00114 use Bio::EnsEMBL::Feature;
00115 use Bio::EnsEMBL::Utils::Exception;
00116 
00117 @ISA = qw(Bio::EnsEMBL::DBSQL::BaseAdaptor);
00118 
00119 =head2 new
00120 
00121   Arg [1]    : list of args to super class constructor
00122   Example    : $ga_a = new Bio::EnsEMBL::Compara::GenomicAlignBlockAdaptor($dbobj);
00123   Description: Creates a new GenomicAlignBlockAdaptor.  The superclass 
00124                constructor is extended to initialise an internal cache.  This
00125                class should be instantiated through the get method on the 
00126                DBAdaptor rather than calling this method directly.
00127   Returntype : none
00128   Exceptions : none
00129   Caller     : Bio::EnsEMBL::DBSQL::DBConnection
00130   Status     : Stable
00131 
00132 =cut
00133 
00134 sub new {
00135   my $class = shift;
00136 
00137   my $self = $class->SUPER::new(@_);
00138 
00139   $self->{_lazy_loading} = 0;
00140   $self->{_use_autoincrement} = 1;
00141 
00142   return $self;
00143 }
00144 
00145 =head2 store
00146 
00147   Arg  1     : Bio::EnsEMBL::Compara::GenomicAlignBlock
00148                The things you want to store
00149   Example    : $gen_ali_blk_adaptor->store($genomic_align_block);
00150   Description: It stores the given GenomicAlginBlock in the database as well
00151                as the GenomicAlign objects it contains
00152   Returntype : Bio::EnsEMBL::Compara::GenomicAlignBlock object
00153   Exceptions : - no Bio::EnsEMBL::Compara::MethodLinkSpeciesSet is linked
00154                - no Bio::EnsEMBL::Compara::GenomicAlign object is linked
00155                - no Bio::EnsEMBL::Compara::DnaFrag object is linked 
00156                - unknown method link
00157                - cannot lock tables
00158                - cannot store GenomicAlignBlock object
00159                - cannot store corresponding GenomicAlign objects
00160   Caller     : general
00161   Status     : Stable
00162 
00163 =cut
00164 
00165 sub store {
00166   my ($self, $genomic_align_block) = @_;
00167 
00168   my $genomic_align_block_sql =
00169         qq{INSERT INTO genomic_align_block (
00170                 genomic_align_block_id,
00171                 method_link_species_set_id,
00172                 score,
00173                 perc_id,
00174                 length,
00175                 group_id,
00176                 level_id
00177         ) VALUES (?,?,?,?,?,?,?)};
00178   
00179   my @values;
00180   
00181   ## CHECKING
00182   if (!defined($genomic_align_block) or
00183       !$genomic_align_block->isa("Bio::EnsEMBL::Compara::GenomicAlignBlock")) {
00184     throw("[$genomic_align_block] is not a Bio::EnsEMBL::Compara::GenomicAlignBlock");
00185   }
00186   if (!defined($genomic_align_block->method_link_species_set)) {
00187     throw("There is no Bio::EnsEMBL::Compara::MethodLinkSpeciesSet object attached to this".
00188         " Bio::EnsEMBL::Compara::GenomicAlignBlock object [$self]");
00189   }
00190   if (!defined($genomic_align_block->method_link_species_set->dbID)) {
00191     throw("Attached Bio::EnsEMBL::Compara::MethodLinkSpeciesSet object has no dbID");
00192   }
00193   if (!$genomic_align_block->genomic_align_array or !@{$genomic_align_block->genomic_align_array}) {
00194     throw("This block does not contain any GenomicAlign. Nothing to store!");
00195   }
00196   foreach my $genomic_align (@{$genomic_align_block->genomic_align_array}) {
00197     # check if every GenomicAlgin has a dbID
00198     if (!defined($genomic_align->dnafrag->dbID)) {
00199       throw("dna_fragment in GenomicAlignBlock is not in DB");
00200     }
00201   }
00202   
00203   my $lock_tables = 0;
00204   if (!$genomic_align_block->dbID and !$self->use_autoincrement()) {
00205     ## Lock tables
00206     $lock_tables = 1;
00207     $self->dbc->do(qq{ LOCK TABLES genomic_align_block WRITE });
00208 
00209     ## Get max genomic_align_block_id for the corresponding range of ids
00210     my $sql = 
00211             "SELECT MAX(genomic_align_block_id) FROM genomic_align_block WHERE".
00212             " genomic_align_block_id > ".$genomic_align_block->method_link_species_set->dbID.
00213             "0000000000 AND genomic_align_block_id < ".
00214             ($genomic_align_block->method_link_species_set->dbID + 1)."0000000000";
00215     my $sth = $self->prepare($sql);
00216     $sth->execute();
00217     my $genomic_align_block_id = ($sth->fetchrow_array() or
00218         ($genomic_align_block->method_link_species_set->dbID * 10000000000));
00219 
00220     ## Set the genomic_align_block_id
00221     $genomic_align_block->dbID($genomic_align_block_id+1);
00222   }
00223 
00224   ## Stores data, all of them with the same id
00225   my $sth = $self->prepare($genomic_align_block_sql);
00226   #print $align_block_id, "\n";
00227   $sth->execute(
00228                 ($genomic_align_block->dbID or undef),
00229                 $genomic_align_block->method_link_species_set->dbID,
00230                 $genomic_align_block->score,
00231                 $genomic_align_block->perc_id,
00232                 $genomic_align_block->length,
00233                 $genomic_align_block->group_id,
00234         ($genomic_align_block->level_id or 1)
00235         );
00236   if ($lock_tables) {
00237     ## Unlock tables
00238     $self->dbc->do("UNLOCK TABLES");
00239   }
00240   if (!$genomic_align_block->dbID) {
00241     $genomic_align_block->dbID($sth->{'mysql_insertid'});
00242   }
00243   info("Stored Bio::EnsEMBL::Compara::GenomicAlignBlock ".
00244         ($genomic_align_block->dbID or "NULL").
00245         ", mlss=".$genomic_align_block->method_link_species_set->dbID.
00246         ", scr=".($genomic_align_block->score or "NA").
00247         ", id=".($genomic_align_block->perc_id or "NA")."\%".
00248         ", l=".($genomic_align_block->length or "NA").
00249         ", lvl=".($genomic_align_block->level_id or 1).
00250         "");
00251 
00252   ## Stores genomic_align entries
00253   my $genomic_align_adaptor = $self->db->get_GenomicAlignAdaptor;
00254   $genomic_align_adaptor->store($genomic_align_block->genomic_align_array);
00255 
00256   return $genomic_align_block;
00257 }
00258 
00259 
00260 =head2 delete_by_dbID
00261 
00262   Arg  1     : integer $genomic_align_block_id
00263   Example    : $gen_ali_blk_adaptor->delete_by_dbID(352158763);
00264   Description: It removes the given GenomicAlginBlock in the database as well
00265                as the GenomicAlign objects it contains
00266   Returntype : none
00267   Exceptions : 
00268   Caller     : general
00269   Status     : Stable
00270 
00271 =cut
00272 
00273 sub delete_by_dbID {
00274   my ($self, $genomic_align_block_id) = @_;
00275 
00276   my $genomic_align_block_sql =
00277         qq{DELETE FROM genomic_align_block WHERE genomic_align_block_id = ?};
00278   
00279   ## Deletes genomic_align_block entry 
00280   my $sth = $self->prepare($genomic_align_block_sql);
00281   $sth->execute($genomic_align_block_id);
00282   $sth->finish();
00283   
00284   ## Deletes corresponding genomic_align entries
00285   my $genomic_align_adaptor = $self->db->get_GenomicAlignAdaptor;
00286   $genomic_align_adaptor->delete_by_genomic_align_block_id($genomic_align_block_id);
00287 }
00288 
00289 
00290 =head2 fetch_by_dbID
00291 
00292   Arg  1     : integer $genomic_align_block_id
00293   Example    : my $genomic_align_block = $genomic_align_block_adaptor->fetch_by_dbID(1)
00294   Description: Retrieve the corresponding
00295                Bio::EnsEMBL::Compara::GenomicAlignBlock object
00296   Returntype : Bio::EnsEMBL::Compara::GenomicAlignBlock object
00297   Exceptions : Returns undef if no matching
00298                Bio::EnsEMBL::Compara::GenomicAlignBlock object can be retrieved
00299   Caller     : none
00300   Status     : Stable
00301 
00302 =cut
00303 
00304 sub fetch_by_dbID {
00305   my ($self, $dbID) = @_;
00306   my $genomic_align_block; # returned object
00307 
00308   my $sql = qq{
00309           SELECT
00310               method_link_species_set_id,
00311               score,
00312               perc_id,
00313               length,
00314               group_id
00315           FROM
00316               genomic_align_block
00317           WHERE
00318               genomic_align_block_id = ?
00319       };
00320 
00321   my $sth = $self->prepare($sql);
00322   $sth->execute($dbID);
00323   my $array_ref = $sth->fetchrow_arrayref();
00324   $sth->finish();
00325   
00326   if ($array_ref) {
00327     my ($method_link_species_set_id, $score, $perc_id, $length, $group_id) = @$array_ref;
00328   
00329     ## Create the object
00330     # Lazy loading of genomic_align objects. They are fetched only when needed.
00331     $genomic_align_block = new Bio::EnsEMBL::Compara::GenomicAlignBlock(
00332                           -adaptor => $self,
00333                           -dbID => $dbID,
00334                           -method_link_species_set_id => $method_link_species_set_id,
00335                           -score => $score,
00336               -perc_id => $perc_id,
00337               -length => $length,
00338                           -group_id => $group_id
00339                   );
00340     if (!$self->lazy_loading) {
00341       $genomic_align_block = $self->retrieve_all_direct_attributes($genomic_align_block);
00342     }
00343   }
00344 
00345   return $genomic_align_block;
00346 }
00347 
00348 
00349 =head2 fetch_all_by_MethodLinkSpeciesSet
00350 
00351   Arg  1     : Bio::EnsEMBL::Compara::MethodLinkSpeciesSet $method_link_species_set
00352   Arg  2     : integer $limit_number [optional]
00353   Arg  3     : integer $limit_index_start [optional]
00354   Example    : my $genomic_align_blocks =
00355                   $genomic_align_block_adaptor->
00356                       fetch_all_by_MethodLinkSpeciesSet($mlss);
00357   Description: Retrieve the corresponding
00358                Bio::EnsEMBL::Compara::GenomicAlignBlock objects. Objects 
00359   Returntype : ref. to an array of Bio::EnsEMBL::Compara::GenomicAlignBlock objects.
00360                Corresponding Bio::EnsEMBL::Compara::GenomicAlign are only retrieved
00361                when required.
00362   Exceptions : Returns ref. to an empty array if no matching
00363                Bio::EnsEMBL::Compara::GenomicAlignBlock object can be retrieved
00364   Caller     : none
00365   Status     : Stable
00366 
00367 =cut
00368 
00369 sub fetch_all_by_MethodLinkSpeciesSet {
00370   my ($self, $method_link_species_set, $limit_number, $limit_index_start) = @_;
00371 
00372   my $genomic_align_blocks = []; # returned object
00373 
00374   throw("[$method_link_species_set] is not a Bio::EnsEMBL::Compara::MethodLinkSpeciesSet object")
00375       unless ($method_link_species_set and ref $method_link_species_set and
00376           $method_link_species_set->isa("Bio::EnsEMBL::Compara::MethodLinkSpeciesSet"));
00377   my $method_link_species_set_id = $method_link_species_set->dbID;
00378   throw("[$method_link_species_set_id] has no dbID") if (!$method_link_species_set_id);
00379 
00380   my $sql = qq{
00381           SELECT
00382               gab.genomic_align_block_id,
00383               gab.score,
00384               gab.perc_id,
00385               gab.length,
00386               gab.group_id
00387           FROM
00388               genomic_align_block gab
00389           WHERE 
00390               gab.method_link_species_set_id = $method_link_species_set_id
00391       };
00392   if ($limit_number && $limit_index_start) {
00393     $sql .= qq{ LIMIT $limit_index_start , $limit_number };
00394   } elsif ($limit_number) {
00395     $sql .= qq{ LIMIT $limit_number };
00396   }
00397 
00398   my $sth = $self->prepare($sql);
00399   $sth->execute();
00400   my ($genomic_align_block_id, $score, $perc_id, $length, $group_id);
00401   $sth->bind_columns(\$genomic_align_block_id, \$score, \$perc_id, \$length, \$group_id);
00402   
00403   while ($sth->fetch) {
00404     my $this_genomic_align_block = new Bio::EnsEMBL::Compara::GenomicAlignBlock(
00405             -adaptor => $self,
00406             -dbID => $genomic_align_block_id,
00407             -method_link_species_set_id => $method_link_species_set_id,
00408             -score => $score,
00409             -perc_id => $perc_id,
00410             -length => $length,
00411         -group_id => $group_id
00412         );
00413     push(@$genomic_align_blocks, $this_genomic_align_block);
00414   }
00415   
00416   $sth->finish();
00417   
00418   return $genomic_align_blocks;
00419 }
00420 
00421 
00422 =head2 fetch_all_by_MethodLinkSpeciesSet_Slice
00423 
00424   Arg  1     : Bio::EnsEMBL::Compara::MethodLinkSpeciesSet $method_link_species_set
00425   Arg  2     : Bio::EnsEMBL::Slice $original_slice
00426   Arg  3     : integer $limit_number [optional]
00427   Arg  4     : integer $limit_index_start [optional]
00428   Arg  5     : boolean $restrict_resulting_blocks [optional]
00429   Example    : my $genomic_align_blocks =
00430                   $genomic_align_block_adaptor->fetch_all_by_MethodLinkSpeciesSet_Slice(
00431                       $method_link_species_set, $original_slice);
00432   Description: Retrieve the corresponding
00433                Bio::EnsEMBL::Compara::GenomicAlignBlock objects. The alignments may be
00434                reverse-complemented in order to match the strand of the original slice.
00435   Returntype : ref. to an array of Bio::EnsEMBL::Compara::GenomicAlignBlock objects. Only dbID,
00436                adaptor and method_link_species_set are actually stored in the objects. The remaining
00437                attributes are only retrieved when required.
00438   Exceptions : Returns ref. to an empty array if no matching
00439                Bio::EnsEMBL::Compara::GenomicAlignBlock object can be retrieved
00440   Caller     : $object->method_name
00441   Status     : Stable
00442 
00443 =cut
00444 
00445 sub fetch_all_by_MethodLinkSpeciesSet_Slice {
00446   my ($self, $method_link_species_set, $reference_slice, $limit_number, $limit_index_start, $restrict) = @_;
00447   my $all_genomic_align_blocks = []; # Returned value
00448 
00449   ## method_link_species_set will be checked in the fetch_all_by_MethodLinkSpeciesSet_DnaFrag method
00450 
00451   ## Check original_slice
00452   unless($reference_slice && ref $reference_slice && 
00453          $reference_slice->isa('Bio::EnsEMBL::Slice')) {
00454     throw("[$reference_slice] should be a Bio::EnsEMBL::Slice object\n");
00455   }
00456 
00457   $limit_number = 0 if (!defined($limit_number));
00458   $limit_index_start = 0 if (!defined($limit_index_start));
00459 
00460   if ($reference_slice->isa("Bio::EnsEMBL::Compara::AlignSlice::Slice")) {
00461     return $reference_slice->get_all_GenomicAlignBlocks(
00462         $method_link_species_set->method_link_type, $method_link_species_set->species_set);
00463   }
00464 
00465   ## Get the Bio::EnsEMBL::Compara::GenomeDB object corresponding to the
00466   ## $reference_slice
00467   my $slice_adaptor = $reference_slice->adaptor();
00468   if(!$slice_adaptor) {
00469     warning("Slice has no attached adaptor. Cannot get Compara alignments.");
00470     return $all_genomic_align_blocks;
00471   }
00472 
00473   my $gdb_a = $self->db->get_GenomeDBAdaptor();
00474     my $meta_container = $reference_slice->adaptor->db->get_MetaContainer();
00475     my $primary_species_name = $gdb_a->get_species_name_from_core_MetaContainer($meta_container);
00476   my ($highest_cs) = @{$slice_adaptor->db->get_CoordSystemAdaptor->fetch_all()};
00477   my $primary_species_assembly = $highest_cs->version();
00478   my $genome_db_adaptor = $self->db->get_GenomeDBAdaptor;
00479   my $genome_db = $genome_db_adaptor->fetch_by_name_assembly(
00480           $primary_species_name,
00481           $primary_species_assembly
00482       );
00483 
00484 #   my $dnafrag_adaptor = $self->db->get_DnaFragAdaptor;
00485 #   my $this_dnafrag = $dnafrag_adaptor->fetch_by_GenomeDB_and_name(
00486 #           $genome_db, $reference_slice->seq_region_name
00487 #       );
00488 #   if ($this_dnafrag) {
00489 #     my $these_genomic_align_blocks = $self->fetch_all_by_MethodLinkSpeciesSet_DnaFrag(
00490 #             $method_link_species_set,
00491 #             $this_dnafrag,
00492 #             $reference_slice->start,
00493 #             $reference_slice->end,
00494 #             $limit_number,
00495 #             $limit_index_start,
00496 #             $restrict
00497 #         );
00498 #     foreach my $this_genomic_align_block (@$these_genomic_align_blocks) {
00499 #       $this_genomic_align_block->reference_slice($reference_slice);
00500 #       $this_genomic_align_block->reference_slice_start(
00501 #           $this_genomic_align_block->reference_genomic_align->dnafrag_start - $reference_slice->start + 1);
00502 #       $this_genomic_align_block->reference_slice_end(
00503 #           $this_genomic_align_block->reference_genomic_align->dnafrag_end - $reference_slice->start + 1);
00504 #       $this_genomic_align_block->reference_slice_strand($reference_slice->strand);
00505 #       $this_genomic_align_block->reverse_complement()
00506 #           if ($reference_slice->strand != $this_genomic_align_block->reference_genomic_align->dnafrag_strand);
00507 #       push (@$all_genomic_align_blocks, $this_genomic_align_block);
00508 #     }
00509 #     return $all_genomic_align_blocks;
00510 #   }
00511   my $projection_segments = $reference_slice->project('toplevel');
00512   return [] if(!@$projection_segments);
00513 
00514   foreach my $this_projection_segment (@$projection_segments) {
00515     my $this_slice = $this_projection_segment->to_Slice;
00516     my $dnafrag_type = $this_slice->coord_system->name;
00517     my $dnafrag_adaptor = $self->db->get_DnaFragAdaptor;
00518     my $this_dnafrag = $dnafrag_adaptor->fetch_by_GenomeDB_and_name(
00519             $genome_db, $this_slice->seq_region_name
00520         );
00521     next if (!$this_dnafrag);
00522 
00523     my $these_genomic_align_blocks = $self->fetch_all_by_MethodLinkSpeciesSet_DnaFrag(
00524             $method_link_species_set,
00525             $this_dnafrag,
00526             $this_slice->start,
00527             $this_slice->end,
00528             $limit_number,
00529             $limit_index_start,
00530             $restrict
00531         );
00532 
00533     #If the GenomicAlignBlock has been restricted, set up the correct values 
00534     #for restricted_aln_start and restricted_aln_end
00535     foreach my $this_genomic_align_block (@$these_genomic_align_blocks) {
00536 
00537     #print "GAB restricted start " . $this_genomic_align_block->{'restricted_aln_start'} . " end " . $this_genomic_align_block->{'restricted_aln_end'} . " length " . $this_genomic_align_block->{'original_length'} . "\n";
00538     
00539     
00540     if (defined $this_genomic_align_block->{'restricted_aln_start'}) {
00541         my $tmp_start = $this_genomic_align_block->{'restricted_aln_start'};
00542         #if ($reference_slice->strand != $this_genomic_align_block->reference_genomic_align->dnafrag_strand) {
00543 
00544         #the start and end are always calculated for the forward strand
00545         if ($reference_slice->strand == 1) {
00546         $this_genomic_align_block->{'restricted_aln_start'}++;
00547         $this_genomic_align_block->{'restricted_aln_end'} = $this_genomic_align_block->{'original_length'} - $this_genomic_align_block->{'restricted_aln_end'};
00548         } else {
00549         $this_genomic_align_block->{'restricted_aln_start'} = $this_genomic_align_block->{'restricted_aln_end'} + 1;
00550         $this_genomic_align_block->{'restricted_aln_end'} = $this_genomic_align_block->{'original_length'} - $tmp_start;
00551         }
00552         #print "GAB after restricted start " . $this_genomic_align_block->{'restricted_aln_start'} . " end " . $this_genomic_align_block->{'restricted_aln_end'} . " length " . $this_genomic_align_block->{'original_length'} . "\n";
00553     }
00554     }
00555 
00556     my $top_slice = $slice_adaptor->fetch_by_region($dnafrag_type, 
00557                                                     $this_slice->seq_region_name);
00558 
00559     # need to convert features to requested coord system
00560     # if it was different then the one we used for fetching
00561 
00562     if($top_slice->name ne $reference_slice->name) {
00563       foreach my $this_genomic_align_block (@$these_genomic_align_blocks) {
00564         my $feature = new Bio::EnsEMBL::Feature(
00565                 -slice => $top_slice,
00566                 -start => $this_genomic_align_block->reference_genomic_align->dnafrag_start,
00567                 -end => $this_genomic_align_block->reference_genomic_align->dnafrag_end,
00568                 -strand => $this_genomic_align_block->reference_genomic_align->dnafrag_strand
00569             );
00570         $feature = $feature->transfer($reference_slice);
00571     next if (!$feature);
00572         $this_genomic_align_block->reference_slice($reference_slice);
00573         $this_genomic_align_block->reference_slice_start($feature->start);
00574         $this_genomic_align_block->reference_slice_end($feature->end);
00575         $this_genomic_align_block->reference_slice_strand($reference_slice->strand);
00576         $this_genomic_align_block->reverse_complement()
00577             if ($reference_slice->strand != $this_genomic_align_block->reference_genomic_align->dnafrag_strand);
00578         push (@$all_genomic_align_blocks, $this_genomic_align_block);
00579       }
00580     } else {
00581       foreach my $this_genomic_align_block (@$these_genomic_align_blocks) {
00582         $this_genomic_align_block->reference_slice($top_slice);
00583         $this_genomic_align_block->reference_slice_start(
00584             $this_genomic_align_block->reference_genomic_align->dnafrag_start);
00585         $this_genomic_align_block->reference_slice_end(
00586             $this_genomic_align_block->reference_genomic_align->dnafrag_end);
00587         $this_genomic_align_block->reference_slice_strand($reference_slice->strand);
00588         $this_genomic_align_block->reverse_complement()
00589             if ($reference_slice->strand != $this_genomic_align_block->reference_genomic_align->dnafrag_strand);
00590         push (@$all_genomic_align_blocks, $this_genomic_align_block);
00591       }
00592     }
00593   }
00594 
00595   return $all_genomic_align_blocks;
00596 }
00597 
00598 
00599 =head2 fetch_all_by_MethodLinkSpeciesSet_DnaFrag
00600 
00601   Arg  1     : Bio::EnsEMBL::Compara::MethodLinkSpeciesSet $method_link_species_set
00602   Arg  2     : Bio::EnsEMBL::Compara::DnaFrag $dnafrag
00603   Arg  3     : integer $start [optional, default = 1]
00604   Arg  4     : integer $end [optional, default = dnafrag_length]
00605   Arg  5     : integer $limit_number [optional, default = no limit]
00606   Arg  6     : integer $limit_index_start [optional, default = 0]
00607   Arg  7     : boolean $restrict_resulting_blocks [optional, default = no restriction]
00608   Arg  8     : boolean $view_visible [optional, default = all visible]
00609   Example    : my $genomic_align_blocks =
00610                   $genomic_align_block_adaptor->fetch_all_by_MethodLinkSpeciesSet_DnaFrag(
00611                       $mlss, $dnafrag, 50000000, 50250000);
00612   Description: Retrieve the corresponding
00613                Bio::EnsEMBL::Compara::GenomicAlignBlock objects.
00614   Returntype : ref. to an array of Bio::EnsEMBL::Compara::GenomicAlignBlock objects. Only dbID,
00615                adaptor and method_link_species_set are actually stored in the objects. The remaining
00616                attributes are only retrieved when requiered.
00617   Exceptions : Returns ref. to an empty array if no matching
00618                Bio::EnsEMBL::Compara::GenomicAlignBlock object can be retrieved
00619   Caller     : none
00620   Status     : Stable
00621 
00622 =cut
00623 
00624 sub fetch_all_by_MethodLinkSpeciesSet_DnaFrag {
00625   my ($self, $method_link_species_set, $dnafrag, $start, $end, $limit_number, $limit_index_start, $restrict, $view_visible) = @_;
00626 
00627   my $genomic_align_blocks = []; # returned object
00628 
00629   throw("[$dnafrag] is not a Bio::EnsEMBL::Compara::DnaFrag object")
00630       unless ($dnafrag and ref $dnafrag and $dnafrag->isa("Bio::EnsEMBL::Compara::DnaFrag"));
00631   my $query_dnafrag_id = $dnafrag->dbID;
00632   throw("[$dnafrag] has no dbID") if (!$query_dnafrag_id);
00633 
00634   throw("[$method_link_species_set] is not a Bio::EnsEMBL::Compara::MethodLinkSpeciesSet object")
00635       unless ($method_link_species_set and ref $method_link_species_set and
00636           $method_link_species_set->isa("Bio::EnsEMBL::Compara::MethodLinkSpeciesSet"));
00637   my $query_method_link_species_set_id = $method_link_species_set->dbID;
00638   throw("[$method_link_species_set] has no dbID") if (!$query_method_link_species_set_id);
00639 
00640   if ($limit_number) {
00641     return $self->_fetch_all_by_MethodLinkSpeciesSet_DnaFrag_with_limit($method_link_species_set,
00642         $dnafrag, $start, $end, $limit_number, $limit_index_start, $restrict);
00643   }
00644   
00645   $view_visible = 1 if (!defined $view_visible);
00646 
00647   #Create this here to pass into _create_GenomicAlign module
00648   my $genomic_align_adaptor = $self->db->get_GenomicAlignAdaptor;
00649 
00650   my $sql = qq{
00651           SELECT
00652               ga1.genomic_align_id,
00653               ga1.genomic_align_block_id,
00654               ga1.method_link_species_set_id,
00655               ga1.dnafrag_id,
00656               ga1.dnafrag_start,
00657               ga1.dnafrag_end,
00658               ga1.dnafrag_strand,
00659               ga1.cigar_line,
00660               ga1.visible,
00661               ga2.genomic_align_id,
00662               gab.score,
00663               gab.perc_id,
00664               gab.length,
00665               gab.group_id,
00666               gab.level_id
00667           FROM
00668               genomic_align ga1, genomic_align_block gab, genomic_align ga2
00669           WHERE 
00670               ga1.genomic_align_block_id = ga2.genomic_align_block_id
00671               AND gab.genomic_align_block_id = ga1.genomic_align_block_id
00672               AND ga2.method_link_species_set_id = $query_method_link_species_set_id
00673               AND ga2.dnafrag_id = $query_dnafrag_id 
00674               AND ga2.visible = $view_visible
00675       };
00676   if (defined($start) and defined($end)) {
00677     my $max_alignment_length = $method_link_species_set->max_alignment_length;
00678     my $lower_bound = $start - $max_alignment_length;
00679     $sql .= qq{
00680             AND ga2.dnafrag_start <= $end
00681             AND ga2.dnafrag_start >= $lower_bound
00682             AND ga2.dnafrag_end >= $start
00683         };
00684   }
00685   my $sth = $self->prepare($sql);
00686 
00687   $sth->execute();
00688   
00689   my $all_genomic_align_blocks;
00690   my $genomic_align_groups = {};
00691   my ($genomic_align_id, $genomic_align_block_id, $method_link_species_set_id,
00692       $dnafrag_id, $dnafrag_start, $dnafrag_end, $dnafrag_strand, $cigar_line, $visible,
00693       $query_genomic_align_id, $score, $perc_id, $length, $group_id, $level_id,);
00694   $sth->bind_columns(\$genomic_align_id, \$genomic_align_block_id, \$method_link_species_set_id,
00695       \$dnafrag_id, \$dnafrag_start, \$dnafrag_end, \$dnafrag_strand, \$cigar_line, \$visible,
00696       \$query_genomic_align_id, \$score, \$perc_id, \$length, \$group_id, \$level_id);
00697   while ($sth->fetch) {
00698 
00699     ## Index GenomicAlign by ga2.genomic_align_id ($query_genomic_align). All the GenomicAlign
00700     ##   with the same ga2.genomic_align_id correspond to the same GenomicAlignBlock.
00701     if (!defined($all_genomic_align_blocks->{$query_genomic_align_id})) {
00702       # Lazy loading of genomic_align_blocks. All remaining attributes are loaded on demand.
00703       $all_genomic_align_blocks->{$query_genomic_align_id} = new Bio::EnsEMBL::Compara::GenomicAlignBlock(
00704               -adaptor => $self,
00705               -dbID => $genomic_align_block_id,
00706               -method_link_species_set_id => $method_link_species_set_id,
00707               -score => $score,
00708               -perc_id => $perc_id,
00709               -length => $length,
00710               -group_id => $group_id,
00711               -reference_genomic_align_id => $query_genomic_align_id,
00712           -level_id => $level_id,
00713           );
00714       push(@$genomic_align_blocks, $all_genomic_align_blocks->{$query_genomic_align_id});
00715     }
00716 
00717 # # #     ## Avoids to create 1 GenomicAlignGroup object per composite segment (see below)
00718 # # #     next if ($genomic_align_groups->{$query_genomic_align_id}->{$genomic_align_id});
00719     my $this_genomic_align = $self->_create_GenomicAlign($genomic_align_id,
00720         $genomic_align_block_id, $method_link_species_set_id, $dnafrag_id,
00721         $dnafrag_start, $dnafrag_end, $dnafrag_strand, $cigar_line, $visible,
00722     $genomic_align_adaptor);
00723 # # #     ## Set the flag to avoid creating 1 GenomicAlignGroup object per composite segment
00724 # # #     if ($this_genomic_align->isa("Bio::EnsEMBL::Compara::GenomicAlignGroup")) {
00725 # # #       foreach my $this_genomic_align (@{$this_genomic_align->genomic_align_array}) {
00726 # # #         $genomic_align_groups->{$query_genomic_align_id}->{$this_genomic_align->dbID} = 1;
00727 # # #       }
00728 # # #     }
00729     $all_genomic_align_blocks->{$query_genomic_align_id}->add_GenomicAlign($this_genomic_align);
00730   }
00731 
00732   foreach my $this_genomic_align_block (@$genomic_align_blocks) {
00733     my $ref_genomic_align = $this_genomic_align_block->reference_genomic_align;
00734     if ($ref_genomic_align->cigar_line =~ /X/) {
00735       # The reference GenomicAlign is part of a composite segment. We have to restrict it
00736       $this_genomic_align_block = $this_genomic_align_block->restrict_between_reference_positions(
00737           $ref_genomic_align->dnafrag_start, $ref_genomic_align->dnafrag_end, undef,
00738           "skip_empty_genomic_aligns");
00739     }
00740   }
00741 
00742   if (defined($start) and defined($end) and $restrict) {
00743     my $restricted_genomic_align_blocks = [];
00744     foreach my $this_genomic_align_block (@$genomic_align_blocks) {
00745       $this_genomic_align_block = $this_genomic_align_block->restrict_between_reference_positions(
00746           $start, $end, undef, "skip_empty_genomic_aligns");
00747       if (@{$this_genomic_align_block->get_all_GenomicAligns()} > 1) {
00748         push(@$restricted_genomic_align_blocks, $this_genomic_align_block);
00749       }
00750     }
00751     $genomic_align_blocks = $restricted_genomic_align_blocks;
00752   }
00753 
00754   if (!$self->lazy_loading) {
00755     $self->_load_DnaFrags($genomic_align_blocks);
00756   }
00757 
00758   return $genomic_align_blocks;
00759 }
00760 
00761 sub fetch_all_by_MethodLinkSpeciesSet_DnaFragORIG {
00762      my ($self, $method_link_species_set, $dnafrag, $start, $end, $limit_number, $limit_index_start, $restrict) = @_;
00763 
00764   my $genomic_align_blocks = []; # returned object
00765   print STDERR $dnafrag."\n";
00766   throw("[$dnafrag] is not a Bio::EnsEMBL::Compara::DnaFrag object")
00767       unless ($dnafrag and ref $dnafrag and $dnafrag->isa("Bio::EnsEMBL::Compara::DnaFrag"));
00768   my $dnafrag_id = $dnafrag->dbID;
00769   throw("[$dnafrag] has no dbID") if (!$dnafrag_id);
00770 
00771   throw("[$method_link_species_set] is not a Bio::EnsEMBL::Compara::MethodLinkSpeciesSet object")
00772       unless ($method_link_species_set and ref $method_link_species_set and
00773           $method_link_species_set->isa("Bio::EnsEMBL::Compara::MethodLinkSpeciesSet"));
00774   my $method_link_species_set_id = $method_link_species_set->dbID;
00775   throw("[$method_link_species_set_id] has no dbID") if (!$method_link_species_set_id);
00776 
00777   if ($limit_number) {
00778     return $self->_fetch_all_by_MethodLinkSpeciesSet_DnaFrag_with_limit($method_link_species_set,
00779         $dnafrag, $start, $end, $limit_number, $limit_index_start, $restrict);
00780   }
00781 
00782   #Create this here to pass into _create_GenomicAlign module
00783   my $genomic_align_adaptor = $self->db->get_GenomicAlignAdaptor;
00784 
00785   my $sql = qq{
00786           SELECT
00787               ga1.genomic_align_id,
00788               ga1.genomic_align_block_id,
00789               ga1.method_link_species_set_id,
00790               ga1.dnafrag_id,
00791               ga1.dnafrag_start,
00792               ga1.dnafrag_end,
00793               ga1.dnafrag_strand,
00794               ga1.cigar_line,
00795               ga1.level_id,
00796               ga2.genomic_align_id
00797           FROM
00798               genomic_align ga1, genomic_align ga2
00799           WHERE 
00800               ga1.genomic_align_block_id = ga2.genomic_align_block_id
00801               AND ga2.method_link_species_set_id = $method_link_species_set_id
00802               AND ga2.dnafrag_id = $dnafrag_id
00803       };
00804   if (defined($start) and defined($end)) {
00805     my $max_alignment_length = $method_link_species_set->max_alignment_length;
00806     my $lower_bound = $start - $max_alignment_length;
00807     $sql .= qq{
00808             AND ga2.dnafrag_start <= $end
00809             AND ga2.dnafrag_start >= $lower_bound
00810             AND ga2.dnafrag_end >= $start
00811         };
00812   }
00813 
00814   my $sth = $self->prepare($sql);
00815   $sth->execute();
00816   
00817   my $all_genomic_align_blocks;
00818   my $genomic_align_groups = {};
00819   # SMJS Removed already declared variables from this my list ($method_link_species_set_id and $dnafrag_id)
00820   my ($genomic_align_id, $genomic_align_block_id, $dnafrag_start, $dnafrag_end, $dnafrag_strand, $cigar_line, $level_id,
00821       $query_genomic_align_id);
00822   $sth->bind_columns(\$genomic_align_id, \$genomic_align_block_id, \$method_link_species_set_id,
00823       \$dnafrag_id, \$dnafrag_start, \$dnafrag_end, \$dnafrag_strand, \$cigar_line, \$level_id,
00824       \$query_genomic_align_id);
00825   while ($sth->fetchrow_array) {
00826 
00827     ## Index GenomicAlign by ga2.genomic_align_id ($query_genomic_align). All the GenomicAlign
00828     ##   with the same ga2.genomic_align_id correspond to the same GenomicAlignBlock.
00829     if (!defined($all_genomic_align_blocks->{$query_genomic_align_id})) {
00830       # Lazy loading of genomic_align_blocks. All remaining attributes are loaded on demand.
00831       $all_genomic_align_blocks->{$query_genomic_align_id} = new Bio::EnsEMBL::Compara::GenomicAlignBlock(
00832               -adaptor => $self,
00833               -dbID => $genomic_align_block_id,
00834               -method_link_species_set_id => $method_link_species_set_id,
00835               -reference_genomic_align_id => $query_genomic_align_id,
00836           );
00837       push(@$genomic_align_blocks, $all_genomic_align_blocks->{$query_genomic_align_id});
00838     }
00839 
00840 # # #     ## Avoids to create 1 GenomicAlignGroup object per composite segment (see below)
00841 # # #     next if ($genomic_align_groups->{$query_genomic_align_id}->{$genomic_align_id});
00842     my $this_genomic_align = $self->_create_GenomicAlign($genomic_align_id,
00843         $genomic_align_block_id, $method_link_species_set_id, $dnafrag_id,
00844         $dnafrag_start, $dnafrag_end, $dnafrag_strand, $cigar_line, $level_id, $genomic_align_adaptor);
00845 # # #     ## Set the flag to avoid creating 1 GenomicAlignGroup object per composite segment
00846 # # #     if ($this_genomic_align->isa("Bio::EnsEMBL::Compara::GenomicAlignGroup")) {
00847 # # #       foreach my $this_genomic_align (@{$this_genomic_align->genomic_align_array}) {
00848 # # #         $genomic_align_groups->{$query_genomic_align_id}->{$this_genomic_align->dbID} = 1;
00849 # # #       }
00850 # # #     }
00851     $all_genomic_align_blocks->{$query_genomic_align_id}->add_GenomicAlign($this_genomic_align);
00852   }
00853 
00854   if (defined($start) and defined($end) and $restrict) {
00855     my $restricted_genomic_align_blocks = [];
00856     foreach my $this_genomic_align_block (@$genomic_align_blocks) {
00857       $this_genomic_align_block = $this_genomic_align_block->restrict_between_reference_positions(
00858           $start, $end, undef, "skip_empty_genomic_aligns");
00859       if (@{$this_genomic_align_block->get_all_GenomicAligns()} > 1) {
00860         push(@$restricted_genomic_align_blocks, $this_genomic_align_block);
00861       }
00862     }
00863     $genomic_align_blocks = $restricted_genomic_align_blocks;
00864   }
00865   
00866   return $genomic_align_blocks;
00867 }
00868 
00869 
00870 =head2 _fetch_all_by_MethodLinkSpeciesSet_DnaFrag_with_limit
00871 
00872   This is an internal method. Please, use the fetch_all_by_MethodLinkSpeciesSet_DnaFrag() method instead.
00873 
00874   Arg  1     : Bio::EnsEMBL::Compara::MethodLinkSpeciesSet $method_link_species_set
00875   Arg  2     : Bio::EnsEMBL::Compara::DnaFrag $dnafrag
00876   Arg  3     : integer $start [optional]
00877   Arg  4     : integer $end [optional]
00878   Arg  5     : integer $limit_number
00879   Arg  6     : integer $limit_index_start [optional, default = 0]
00880   Arg  7     : boolean $restrict_resulting_blocks [optional, default = no restriction]
00881   Example    : my $genomic_align_blocks =
00882                   $genomic_align_block_adaptor->_fetch_all_by_MethodLinkSpeciesSet_DnaFrag_with_limit(
00883                       $mlss, $dnafrag, 50000000, 50250000);
00884   Description: Retrieve the corresponding
00885                Bio::EnsEMBL::Compara::GenomicAlignBlock objects. Objects 
00886   Returntype : ref. to an array of Bio::EnsEMBL::Compara::GenomicAlignBlock objects. Only dbID,
00887                adaptor and method_link_species_set are actually stored in the objects. The remaining
00888                attributes are only retrieved when requiered.
00889   Exceptions : Returns ref. to an empty array if no matching
00890                Bio::EnsEMBL::Compara::GenomicAlignBlock object can be retrieved
00891   Caller     : fetch_all_by_MethodLinkSpeciesSet_DnaFrag
00892   Status     : Stable
00893 
00894 =cut
00895 
00896 sub _fetch_all_by_MethodLinkSpeciesSet_DnaFrag_with_limit {
00897   my ($self, $method_link_species_set, $dnafrag, $start, $end, $limit_number, $limit_index_start, $restrict) = @_;
00898 
00899   my $genomic_align_blocks = []; # returned object
00900 
00901   my $dnafrag_id = $dnafrag->dbID;
00902   my $method_link_species_set_id = $method_link_species_set->dbID;
00903 
00904   my $sql = qq{
00905           SELECT
00906               ga2.genomic_align_block_id,
00907               ga2.genomic_align_id
00908           FROM
00909               genomic_align ga2
00910           WHERE 
00911               ga2.method_link_species_set_id = $method_link_species_set_id
00912               AND ga2.dnafrag_id = $dnafrag_id
00913       };
00914   if (defined($start) and defined($end)) {
00915     my $max_alignment_length = $method_link_species_set->max_alignment_length;
00916     my $lower_bound = $start - $max_alignment_length;
00917     $sql .= qq{
00918             AND ga2.dnafrag_start <= $end
00919             AND ga2.dnafrag_start >= $lower_bound
00920             AND ga2.dnafrag_end >= $start
00921         };
00922   }
00923   $limit_index_start = 0 if (!$limit_index_start);
00924   $sql .= qq{ LIMIT $limit_index_start , $limit_number };
00925 
00926   my $sth = $self->prepare($sql);
00927   $sth->execute();
00928   
00929   while (my ($genomic_align_block_id, $query_genomic_align_id) = $sth->fetchrow_array) {
00930     # Lazy loading of genomic_align_blocks. All remaining attributes are loaded on demand.
00931     my $this_genomic_align_block = new Bio::EnsEMBL::Compara::GenomicAlignBlock(
00932             -adaptor => $self,
00933             -dbID => $genomic_align_block_id,
00934             -method_link_species_set_id => $method_link_species_set_id,
00935             -reference_genomic_align_id => $query_genomic_align_id,
00936         );
00937     push(@$genomic_align_blocks, $this_genomic_align_block);
00938   }
00939   if (defined($start) and defined($end) and $restrict) {
00940     my $restricted_genomic_align_blocks = [];
00941     foreach my $this_genomic_align_block (@$genomic_align_blocks) {
00942       $this_genomic_align_block = $this_genomic_align_block->restrict_between_reference_positions(
00943           $start, $end, undef, "skip_empty_genomic_aligns");
00944       if (@{$this_genomic_align_block->get_all_GenomicAligns()} > 1) {
00945         push(@$restricted_genomic_align_blocks, $this_genomic_align_block);
00946       }
00947     }
00948     $genomic_align_blocks = $restricted_genomic_align_blocks;
00949   }
00950   
00951   return $genomic_align_blocks;
00952 }
00953 
00954 
00955 =head2 fetch_all_by_MethodLinkSpeciesSet_DnaFrag_DnaFrag
00956 
00957   Arg  1     : Bio::EnsEMBL::Compara::MethodLinkSpeciesSet $method_link_species_set
00958   Arg  2     : Bio::EnsEMBL::Compara::DnaFrag $dnafrag (query)
00959   Arg  3     : integer $start [optional]
00960   Arg  4     : integer $end [optional]
00961   Arg  5     : Bio::EnsEMBL::Compara::DnaFrag $dnafrag (target)
00962   Arg  6     : integer $limit_number [optional]
00963   Arg  7     : integer $limit_index_start [optional]
00964   Example    : my $genomic_align_blocks =
00965                   $genomic_align_block_adaptor->fetch_all_by_MethodLinkSpeciesSet_DnaFrag_DnaFrag(
00966                       $mlss, $qy_dnafrag, 50000000, 50250000,$tg_dnafrag);
00967   Description: Retrieve the corresponding
00968                Bio::EnsEMBL::Compara::GenomicAlignBlock objects.
00969   Returntype : ref. to an array of Bio::EnsEMBL::Compara::GenomicAlignBlock objects.
00970   Exceptions : Returns ref. to an empty array if no matching
00971                Bio::EnsEMBL::Compara::GenomicAlignBlock object can be retrieved
00972   Caller     : none
00973   Status     : Stable
00974 
00975 =cut
00976 
00977 sub fetch_all_by_MethodLinkSpeciesSet_DnaFrag_DnaFrag {
00978   my ($self, $method_link_species_set, $dnafrag1, $start, $end, $dnafrag2, $limit_number, $limit_index_start) = @_;
00979 
00980   my $genomic_align_blocks = []; # returned object
00981 
00982   throw("[$dnafrag1] is not a Bio::EnsEMBL::Compara::DnaFrag object")
00983       unless ($dnafrag1 and ref $dnafrag1 and $dnafrag1->isa("Bio::EnsEMBL::Compara::DnaFrag"));
00984   my $dnafrag_id1 = $dnafrag1->dbID;
00985   throw("[$dnafrag1] has no dbID") if (!$dnafrag_id1);
00986 
00987   throw("[$dnafrag2] is not a Bio::EnsEMBL::Compara::DnaFrag object")
00988       unless ($dnafrag2 and ref $dnafrag2 and $dnafrag2->isa("Bio::EnsEMBL::Compara::DnaFrag"));
00989   my $dnafrag_id2 = $dnafrag2->dbID;
00990   throw("[$dnafrag2] has no dbID") if (!$dnafrag_id2);
00991 
00992   throw("[$method_link_species_set] is not a Bio::EnsEMBL::Compara::MethodLinkSpeciesSet object")
00993       unless ($method_link_species_set and ref $method_link_species_set and
00994           $method_link_species_set->isa("Bio::EnsEMBL::Compara::MethodLinkSpeciesSet"));
00995   my $method_link_species_set_id = $method_link_species_set->dbID;
00996   throw("[$method_link_species_set_id] has no dbID") if (!$method_link_species_set_id);
00997 
00998   #Create this here to pass into _create_GenomicAlign module
00999   my $genomic_align_adaptor = $self->db->get_GenomicAlignAdaptor;
01000 
01001   my $sql = qq{
01002           SELECT
01003               ga1.genomic_align_id,
01004               ga1.genomic_align_block_id,
01005               ga1.method_link_species_set_id,
01006               ga1.dnafrag_id,
01007               ga1.dnafrag_start,
01008               ga1.dnafrag_end,
01009               ga1.dnafrag_strand,
01010               ga1.cigar_line,
01011               ga1.visible,
01012               ga2.genomic_align_id,
01013               ga2.genomic_align_block_id,
01014               ga2.method_link_species_set_id,
01015               ga2.dnafrag_id,
01016               ga2.dnafrag_start,
01017               ga2.dnafrag_end,
01018               ga2.dnafrag_strand,
01019               ga2.cigar_line,
01020               ga2.visible
01021           FROM
01022               genomic_align ga1, genomic_align ga2
01023           WHERE 
01024               ga1.genomic_align_block_id = ga2.genomic_align_block_id
01025               AND ga1.genomic_align_id != ga2.genomic_align_id
01026               AND ga2.method_link_species_set_id = $method_link_species_set_id
01027               AND ga1.dnafrag_id = $dnafrag_id1 AND ga2.dnafrag_id = $dnafrag_id2
01028       };
01029   if (defined($start) and defined($end)) {
01030     my $max_alignment_length = $method_link_species_set->max_alignment_length;
01031     my $lower_bound = $start - $max_alignment_length;
01032     $sql .= qq{
01033             AND ga1.dnafrag_start <= $end
01034             AND ga1.dnafrag_start >= $lower_bound
01035             AND ga1.dnafrag_end >= $start
01036         };
01037   }
01038   if ($limit_number && $limit_index_start) {
01039     $sql .= qq{ LIMIT $limit_index_start , $limit_number };
01040   } elsif ($limit_number) {
01041     $sql .= qq{ LIMIT $limit_number };
01042   }
01043 
01044   my $sth = $self->prepare($sql);
01045   $sth->execute();
01046   
01047   my $all_genomic_align_blocks;
01048   while (my ($genomic_align_id1, $genomic_align_block_id1, $method_link_species_set_id1,
01049              $dnafrag_id1, $dnafrag_start1, $dnafrag_end1, $dnafrag_strand1, $cigar_line1, $visible1,
01050              $genomic_align_id2, $genomic_align_block_id2, $method_link_species_set_id2,
01051              $dnafrag_id2, $dnafrag_start2, $dnafrag_end2, $dnafrag_strand2, $cigar_line2, $visible2) = $sth->fetchrow_array) {
01052     ## Skip if this genomic_align_block has been defined already
01053     next if (defined($all_genomic_align_blocks->{$genomic_align_block_id1}));
01054     $all_genomic_align_blocks->{$genomic_align_block_id1} = 1;
01055     my $gab = new Bio::EnsEMBL::Compara::GenomicAlignBlock
01056       (-adaptor => $self,
01057        -dbID => $genomic_align_block_id1,
01058        -method_link_species_set_id => $method_link_species_set_id1,
01059        -reference_genomic_align_id => $genomic_align_id1);
01060 
01061     # If set up, lazy loading of genomic_align
01062     unless ($self->lazy_loading) {
01063       ## Create a Bio::EnsEMBL::Compara::GenomicAlign corresponding to ga1.*
01064       my $this_genomic_align1 = $self->_create_GenomicAlign($genomic_align_id1,
01065           $genomic_align_block_id1, $method_link_species_set_id1, $dnafrag_id1,
01066           $dnafrag_start1, $dnafrag_end1, $dnafrag_strand1, $cigar_line1, $visible1, $genomic_align_adaptor);
01067       ## ... attach it to the corresponding Bio::EnsEMBL::Compara::GenomicAlignBlock
01068       $gab->add_GenomicAlign($this_genomic_align1);
01069 
01070       ## Create a Bio::EnsEMBL::Compara::GenomicAlign correponding to ga2.*
01071       my $this_genomic_align2 = $self->_create_GenomicAlign($genomic_align_id2,
01072           $genomic_align_block_id2, $method_link_species_set_id2, $dnafrag_id2,
01073           $dnafrag_start2, $dnafrag_end2, $dnafrag_strand2, $cigar_line2, $visible2, $genomic_align_adaptor);
01074       ## ... attach it to the corresponding Bio::EnsEMBL::Compara::GenomicAlignBlock
01075       $gab->add_GenomicAlign($this_genomic_align2);
01076     }
01077     push(@$genomic_align_blocks, $gab);
01078   }
01079 
01080   return $genomic_align_blocks;
01081 }
01082 
01083 
01084 =head2 fetch_all_by_MethodLinkSpeciesSet_DnaFrag_GroupType (DEPRECATED)
01085   DEPRECATED! Use Bio::EnsEMBL::Compara::GenomicAlignBlockAdaptor->fetch_all_by_MethodLinkSpeciesSet_DnaFrag method instead
01086 
01087   Arg  1     : Bio::EnsEMBL::Compara::MethodLinkSpeciesSet $method_link_species_set
01088   Arg  2     : Bio::EnsEMBL::Compara::DnaFrag $dnafrag (query)
01089   Arg  3     : integer $start [optional]
01090   Arg  4     : integer $end [optional]
01091   Arg  5     : string $group_type
01092   Example    : my $genomic_align_blocks =
01093                   $genomic_align_block_adaptor->fetch_all_by_MethodLinkSpeciesSet_DnaFrag_GroupType(
01094                       $mlss, $qy_dnafrag, 50000000, 50250000,"chain");
01095   Description: Retrieve the corresponding
01096                Bio::EnsEMBL::Compara::GenomicAlignBlock objects.
01097   Returntype : ref. to an array of Bio::EnsEMBL::Compara::GenomicAlignBlock objects. 
01098   Exceptions : Returns ref. to an empty array if no matching
01099                Bio::EnsEMBL::Compara::GenomicAlignBlock object can be retrieved
01100   Caller     : none
01101   Status     : Deprecated
01102 
01103 =cut
01104 
01105 sub fetch_all_by_MethodLinkSpeciesSet_DnaFrag_GroupType {
01106   my ($self, $method_link_species_set, $dnafrag, $start, $end, $group_type) = @_;
01107 
01108   deprecate("There is no longer any GroupType defined. Use Bio::EnsEMBL::Compara::GenomicAlignBlockAdpator->fetch_all_by_MethodLinkSpeciesSet_DnaFrag method instead");
01109 
01110   my $genomic_align_blocks = []; # returned object  
01111   return $genomic_align_blocks;
01112 }
01113 
01114 =head2 fetch_all_by_MethodLinkSpeciesSet_GroupID
01115 
01116   Arg  1     : Bio::EnsEMBL::Compara::MethodLinkSpeciesSet $method_link_species_set
01117   Arg  2     : integer $group_id
01118   Example    : my $genomic_align_blocks =
01119                   $genomic_align_block_adaptor->fetch_all_by_MethodLinkSpeciesSet_GroupID($mlss, $group_id);
01120   Description: Retrieve the corresponding
01121                Bio::EnsEMBL::Compara::GenomicAlignBlock objects.
01122   Returntype : ref. to an array of Bio::EnsEMBL::Compara::GenomicAlignBlock objects. 
01123   Exceptions : Returns ref. to an empty array if no matching
01124                Bio::EnsEMBL::Compara::GenomicAlignBlock object can be retrieved
01125   Caller     : none
01126   Status     : Stable
01127 
01128 =cut
01129 
01130 sub fetch_all_by_MethodLinkSpeciesSet_GroupID {
01131   my ($self, $method_link_species_set, $group_id) = @_;
01132 
01133   my $genomic_align_blocks = []; # returned object
01134 
01135   throw("[$method_link_species_set] is not a Bio::EnsEMBL::Compara::MethodLinkSpeciesSet object")
01136       unless ($method_link_species_set and ref $method_link_species_set and
01137           $method_link_species_set->isa("Bio::EnsEMBL::Compara::MethodLinkSpeciesSet"));
01138   my $method_link_species_set_id = $method_link_species_set->dbID;
01139   throw("[$method_link_species_set_id] has no dbID") if (!$method_link_species_set_id);
01140 
01141   unless (defined $group_id) {
01142       throw("group_id is not defined");
01143   }
01144 
01145   my $sql = qq{
01146           SELECT
01147               gab.genomic_align_block_id,
01148               gab.score,
01149               gab.perc_id,
01150               gab.length
01151           FROM
01152               genomic_align_block gab
01153           WHERE 
01154               gab.method_link_species_set_id = $method_link_species_set_id
01155               AND gab.group_id = $group_id
01156       };
01157 
01158   my $sth = $self->prepare($sql);
01159   $sth->execute();
01160   my ($genomic_align_block_id, $score, $perc_id, $length);
01161   $sth->bind_columns(\$genomic_align_block_id, \$score, \$perc_id, \$length);
01162   
01163   while ($sth->fetch) {
01164     my $this_genomic_align_block = new Bio::EnsEMBL::Compara::GenomicAlignBlock(
01165             -adaptor => $self,
01166             -dbID => $genomic_align_block_id,
01167             -method_link_species_set_id => $method_link_species_set_id,
01168             -score => $score,
01169             -perc_id => $perc_id,
01170             -length => $length,
01171         -group_id => $group_id
01172         );
01173     push(@$genomic_align_blocks, $this_genomic_align_block);
01174   }
01175   
01176   return $genomic_align_blocks;
01177 }
01178 
01179 
01180 =head2 retrieve_all_direct_attributes
01181 
01182   Arg  1     : Bio::EnsEMBL::Compara::GenomicAlignBlock $genomic_align_block
01183   Example    : $genomic_align_block_adaptor->retrieve_all_direct_attributes($genomic_align_block)
01184   Description: Retrieve the all the direct attibutes corresponding to the dbID of the
01185                Bio::EnsEMBL::Compara::GenomicAlignBlock object. It is used after lazy fetching
01186                of the object for populating it when required.
01187   Returntype : Bio::EnsEMBL::Compara::GenomicAlignBlock object
01188   Exceptions : 
01189   Caller     : none
01190   Status     : Stable
01191 
01192 =cut
01193 
01194 sub retrieve_all_direct_attributes {
01195   my ($self, $genomic_align_block) = @_;
01196 
01197   my $sql = qq{
01198           SELECT
01199             method_link_species_set_id,
01200             score,
01201             perc_id,
01202             length,
01203             group_id,
01204             level_id
01205           FROM
01206             genomic_align_block
01207           WHERE
01208             genomic_align_block_id = ?
01209       };
01210 
01211   my $sth = $self->prepare($sql);
01212 
01213   $sth->execute($genomic_align_block->dbID);
01214 
01215   my ($method_link_species_set_id, $score, $perc_id, $length, $group_id, $level_id) = $sth->fetchrow_array();
01216   $sth->finish();
01217   
01218   ## Populate the object
01219   $genomic_align_block->adaptor($self);
01220   $genomic_align_block->method_link_species_set_id($method_link_species_set_id)
01221       if (defined($method_link_species_set_id));
01222   $genomic_align_block->score($score) if (defined($score));
01223   $genomic_align_block->perc_id($perc_id) if (defined($perc_id));
01224   $genomic_align_block->length($length) if (defined($length));
01225   $genomic_align_block->group_id($group_id) if (defined($group_id));
01226   $genomic_align_block->level_id($level_id) if (defined($level_id));
01227 
01228   return $genomic_align_block;
01229 }
01230 
01231 sub retrieve_all_direct_attributesORIG {
01232   my ($self, $genomic_align_block) = @_;
01233 
01234   my $sql = qq{
01235           SELECT
01236             method_link_species_set_id,
01237             score,
01238             perc_id,
01239             length,
01240             group_id
01241           FROM
01242             genomic_align_block
01243           WHERE
01244             genomic_align_block_id = ?
01245       };
01246 
01247   my $sth = $self->prepare($sql);
01248   $sth->execute($genomic_align_block->dbID);
01249   my ($method_link_species_set_id, $score, $perc_id, $length, $group_id) = $sth->fetchrow_array();
01250   $sth->finish();
01251   
01252   ## Populate the object
01253   $genomic_align_block->adaptor($self);
01254   $genomic_align_block->method_link_species_set_id($method_link_species_set_id)
01255       if (defined($method_link_species_set_id));
01256   $genomic_align_block->score($score) if (defined($score));
01257   $genomic_align_block->perc_id($perc_id) if (defined($perc_id));
01258   $genomic_align_block->length($length) if (defined($length));
01259   $genomic_align_block->group_id($group_id) if (defined($group_id));
01260 
01261   return $genomic_align_block;
01262 }
01263 
01264 
01265 =head2 store_group_id
01266 
01267   Arg  1     : reference to Bio::EnsEMBL::Compara::GenomicAlignBlock
01268   Arg  2     : group_id
01269   Example    : $genomic_align_block_adaptor->store_group_id($genomic_align_block, $group_id);
01270   Description: Method for storing the group_id for a genomic_align_block
01271   Returntype : 
01272   Exceptions : - cannot lock tables
01273                - cannot update GenomicAlignBlock object
01274   Caller     : none
01275   Status     : Stable
01276 
01277 =cut
01278 
01279 sub store_group_id {
01280     my ($self, $genomic_align_block, $group_id) = @_;
01281     
01282     my $sth = $self->prepare("UPDATE genomic_align_block SET group_id=? WHERE genomic_align_block_id=?;");
01283     $sth->execute($group_id, $genomic_align_block->dbID);
01284     $sth->finish();
01285 }
01286 
01287 =head2 lazy_loading
01288 
01289   [Arg  1]   : (optional)int $value
01290   Example    : $genomic_align_block_adaptor->lazy_loading(1);
01291   Description: Getter/setter for the _lazy_loading flag. This flag
01292                is used when fetching objects from the database. If
01293                the flag is OFF (default), the adaptor will fetch the
01294                all the attributes of the object. This is usually faster
01295                unless you run in some memory limitation problem. This
01296                happens typically when fetching loads of objects in one
01297                go.In this case you might want to consider using the
01298                lazy_loading option which return lighter objects and
01299                deleting objects as you use them:
01300                $gaba->lazy_loading(1);
01301                my $all_gabs = $gaba->fetch_all_by_MethodLinkSpeciesSet($mlss);
01302                foreach my $this_gab (@$all_gabs) {
01303                  # do something
01304                  ...
01305                  # delete object
01306                  undef($this_gab);
01307                }
01308   Returntype : integer
01309   Exceptions :
01310   Caller     : none
01311   Status     : Stable
01312 
01313 =cut
01314 
01315 sub lazy_loading {
01316   my ($self, $value) = @_;
01317 
01318   if (defined $value) {
01319     $self->{_lazy_loading} = $value;
01320   }
01321 
01322   return $self->{_lazy_loading};
01323 }
01324 
01325 
01326 =head2 use_autoincrement
01327 
01328   [Arg  1]   : (optional)int value
01329   Example    : $genomic_align_block_adaptor->use_autoincrement(0);
01330   Description: Getter/setter for the _use_autoincrement flag. This flag
01331                is used when storing new objects with no dbID in the
01332                database. If the flag is ON (default), the adaptor will
01333                let the DB set the dbID using the AUTO_INCREMENT ability.
01334                If you unset the flag, then the adaptor will look for the
01335                first available dbID after 10^10 times the
01336                method_link_species_set_id.
01337   Returntype : integer
01338   Exceptions : 
01339   Caller     : none
01340   Status     : Stable
01341 
01342 =cut
01343 
01344 sub use_autoincrement {
01345   my ($self, $value) = @_;
01346 
01347   if (defined $value) {
01348     $self->{_use_autoincrement} = $value;
01349   }
01350 
01351   return $self->{_use_autoincrement};
01352 }
01353 
01354 =head2 _create_GenomicAlign
01355 
01356   [Arg  1]   : int genomic_align_id
01357   [Arg  2]   : int genomic_align_block_id
01358   [Arg  3]   : int method_link_species_set_id
01359   [Arg  4]   : int dnafrag_id
01360   [Arg  5]   : int dnafrag_start
01361   [Arg  6]   : int dnafrag_end
01362   [Arg  7]   : int dnafrag_strand
01363   [Arg  8]   : string cigar_line
01364   [Arg  9]   : int visible
01365   Example    : my $this_genomic_align1 = $self->_create_GenomicAlign(
01366                   $genomic_align_id, $genomic_align_block_id,
01367                   $method_link_species_set_id, $dnafrag_id,
01368                   $dnafrag_start, $dnafrag_end, $dnafrag_strand,
01369                   $cigar_line, $visible);
01370   Description: Creates a new Bio::EnsEMBL::Compara::GenomicAlign object
01371                with the values provided as arguments. If this GenomicAlign
01372                is part of a composite GenomicAlign, the method will return
01373                a Bio::EnsEMBL::Compara::GenomicAlignGroup containing all the
01374                underlying Bio::EnsEMBL::Compara::GenomicAlign objects instead
01375   Returntype : Bio::EnsEMBL::Compara::GenomicAlign object or
01376                Bio::EnsEMBL::Compara::GenomicAlignGroup object
01377   Exceptions : 
01378   Caller     : internal
01379   Status     : stable
01380 
01381 =cut
01382 
01383 sub _create_GenomicAlign {
01384   my ($self, $genomic_align_id, $genomic_align_block_id, $method_link_species_set_id,
01385       $dnafrag_id, $dnafrag_start, $dnafrag_end, $dnafrag_strand, $cigar_line, 
01386       $visible, $adaptor) = @_;
01387 
01388   my $new_genomic_align = Bio::EnsEMBL::Compara::GenomicAlign->new_fast
01389     ({'dbID' => $genomic_align_id,
01390       'adaptor' => $adaptor,
01391      'genomic_align_block_id' => $genomic_align_block_id,
01392      'method_link_species_set_id' => $method_link_species_set_id,
01393      'dnafrag_id' => $dnafrag_id,
01394      'dnafrag_start' => $dnafrag_start,
01395      'dnafrag_end' => $dnafrag_end,
01396      'dnafrag_strand' => $dnafrag_strand,
01397      'cigar_line' => $cigar_line,
01398      'visible' => $visible}
01399     );
01400 
01401   return $new_genomic_align;
01402 }
01403 
01404 =head2 _load_DnaFrags
01405 
01406   [Arg  1]   : listref Bio::EnsEMBL::Compara::GenomicAlignBlock objects
01407   Example    : $self->_load_DnaFrags($genomic_align_blocks);
01408   Description: Load the DnaFrags for all the GenomicAligns in these
01409                GenomicAlignBlock objects. This is much faster, especially
01410                for a large number of objects, as we fetch all the DnaFrags
01411                at once. Note: These DnaFrags are not cached by the
01412                DnaFragAdaptor at the moment
01413   Returntype : -none-
01414   Exceptions : 
01415   Caller     : fetch_all_* methods
01416   Status     : at risk
01417 
01418 =cut
01419 
01420 sub _load_DnaFrags {
01421   my ($self, $genomic_align_blocks) = @_;
01422 
01423   # 1. Collect all the dnafrag_ids
01424   my $dnafrag_ids = {};
01425   foreach my $this_genomic_align_block (@$genomic_align_blocks) {
01426     foreach my $this_genomic_align (@{$this_genomic_align_block->get_all_GenomicAligns}) {
01427       $dnafrag_ids->{$this_genomic_align->{dnafrag_id}} = 1;
01428     }
01429   }
01430 
01431   # 2. Fetch all the DnaFrags
01432   my %dnafrags = map {$_->{dbID}, $_}
01433       @{$self->db->get_DnaFragAdaptor->fetch_all_by_dbID_list([keys %$dnafrag_ids])};
01434 
01435   # 3. Assign the DnaFrags to the GenomicAligns
01436   foreach my $this_genomic_align_block (@$genomic_align_blocks) {
01437     foreach my $this_genomic_align (@{$this_genomic_align_block->get_all_GenomicAligns}) {
01438       $this_genomic_align->{'dnafrag'} = $dnafrags{$this_genomic_align->{dnafrag_id}};
01439     }
01440   }
01441 }
01442 
01443 1;