Archive Ensembl HomeArchive Ensembl Home
Homology.pm
Go to the documentation of this file.
00001 package Bio::EnsEMBL::Compara::Homology;
00002 
00003 use strict;
00004 use Bio::EnsEMBL::Compara::BaseRelation;
00005 use Bio::EnsEMBL::Utils::Exception qw( deprecate throw warning );
00006 use Bio::SimpleAlign;
00007 
00008 our @ISA = qw(Bio::EnsEMBL::Compara::BaseRelation);
00009 
00010 =head1 NAME
00011 
00012 Bio::EnsEMBL::Compara::Homology - Homology between two proteins
00013 
00014 =head1 SYNOPSIS
00015 
00016   use Bio::EnsEMBL::Registry;
00017 
00018   my $homology_adaptor = $reg->get_adaptor("Multi", "compara", "Homology");
00019 
00020   ## Please, refer to Bio::EnsEMBL::Compara::DBSQL::MemberAdaptor
00021   ## to see how to get a Member from the database. Also, you can
00022   ## find alternative ways to fetch homologies in the POD for the
00023   ## Bio::EnsEMBL::Compara::DBSQL::HomologyAdaptor module.
00024 
00025   my $homologies = $homology_adaptor->fetch_all_by_Member($member);
00026 
00027   foreach my $this_homology (@$homologies) {
00028     my $homologue_genes = $this_homology->gene_list();
00029     print join(" and ", @$homologue_genes), " are ",
00030         $this_homology->description, "\n";
00031   }
00032 
00033 =head1 AUTHOR
00034 
00035 Ensembl Team
00036 
00037 =head1 COPYRIGHT
00038 
00039 Copyright (c) 1999-2012. Ensembl Team
00040 
00041 You may distribute this module under the same terms as perl itself
00042 
00043 =head1 CONTACT
00044 
00045 This modules is part of the EnsEMBL project (http://www.ensembl.org)
00046 
00047 Questions can be posted to the ensembl-dev mailing list:
00048 dev@ensembl.org
00049 
00050 =head1 INHERITANCE
00051 
00052 This class inherits all the methods and attributes from Bio::EnsEMBL::DBSQL::BaseAdaptor
00053 
00054 =head1 APPENDIX
00055 
00056 The rest of the documentation details each of the object methods. Internal methods are usually preceded with a _
00057 
00058 =cut
00059 
00060 my %TWOD_CODONS = ("TTT" => "Phe",#Phe
00061                    "TTC" => "Phe",
00062                    
00063                    "TTA" => "Leu",#Leu
00064                    "TTG" => "Leu",
00065                    
00066                    "TAT" => "Tyr",#Tyr
00067                    "TAC" => "Tyr",
00068                    
00069                    "CAT" => "His",#His
00070                    "CAC" => "His",
00071 
00072                    "CAA" => "Gln",#Gln
00073                    "CAG" => "Gln",
00074                    
00075                    "AAT" => "Asn",#Asn
00076                    "AAC" => "Asn",
00077                    
00078                    "AAA" => "Lys",#Lys
00079                    "AAG" => "Lys",
00080                    
00081                    "GAT" => "Asp",#Asp
00082                    "GAC" => "Asp",
00083 
00084                    "GAA" => "Glu",#Glu
00085                    "GAG" => "Glu",
00086                    
00087                    "TGT" => "Cys",#Cys
00088                    "TGC" => "Cys",
00089                    
00090                    "AGT" => "Ser",#Ser
00091                    "AGC" => "Ser",
00092                    
00093                    "AGA" => "Arg",#Arg
00094                    "AGG" => "Arg",
00095                    
00096                    "ATT" => "Ile",#Ile
00097                    "ATC" => "Ile",
00098                    "ATA" => "Ile");
00099 
00100 my %FOURD_CODONS = ("CTT" => "Leu",#Leu
00101                     "CTC" => "Leu",
00102                     "CTA" => "Leu",
00103                     "CTG" => "Leu",
00104                     
00105                     "GTT" => "Val",#Val 
00106                     "GTC" => "Val",
00107                     "GTA" => "Val",
00108                     "GTG" => "Val",
00109                     
00110                     "TCT" => "Ser",#Ser
00111                     "TCC" => "Ser",
00112                     "TCA" => "Ser",
00113                     "TCG" => "Ser",
00114                     
00115                     "CCT" => "Pro",#Pro
00116                     "CCC" => "Pro",
00117                     "CCA" => "Pro",
00118                     "CCG" => "Pro",
00119                     
00120                     "ACT" => "Thr",#Thr
00121                     "ACC" => "Thr",
00122                     "ACA" => "Thr",
00123                     "ACG" => "Thr",
00124                     
00125                     "GCT" => "Ala",#Ala
00126                     "GCC" => "Ala",
00127                     "GCA" => "Ala",
00128                     "GCG" => "Ala",
00129                     
00130                     "CGT" => "Arg",#Arg
00131                     "CGC" => "Arg",
00132                     "CGA" => "Arg",
00133                     "CGG" => "Arg",
00134                     
00135                     "GGT" => "Gly",#Gly
00136                     "GGC" => "Gly",
00137                     "GGA" => "Gly",
00138                     "GGG" => "Gly");
00139                     
00140 my %CODONS =   ("ATG" => "Met",
00141                 "TGG" => "Trp",
00142                 "TAA" => "TER",
00143                 "TAG" => "TER",
00144                 "TGA" => "TER",
00145                 "---" => "---");
00146 
00147 foreach my $codon (keys %TWOD_CODONS) {
00148   $CODONS{$codon} = $TWOD_CODONS{$codon};
00149 }
00150 foreach my $codon (keys %FOURD_CODONS) {
00151   $CODONS{$codon} = $FOURD_CODONS{$codon};
00152 }
00153 
00154 =head2 get_SimpleAlign
00155 
00156   Arg [1]    : string 'cdna' (optional)
00157   Example    : $simple_align = $homology->get_SimpleAlign();
00158                $cdna_s_align = $homology->get_SimpleAlign('cdna');
00159   Description: get pairwise simple alignment (from the multialignment)
00160   Returntype : Bio::SimpleAlign
00161 
00162 =cut
00163 
00164 sub get_SimpleAlign {
00165   my $self = shift;
00166   my $alignment = shift;
00167   my $changeSelenos = shift;
00168   unless (defined $changeSelenos) {
00169       $changeSelenos = 0;
00170   }
00171   
00172   my $sa = Bio::SimpleAlign->new();
00173 
00174   #Hack to try to work with both bioperl 0.7 and 1.2:
00175   #Check to see if the method is called 'addSeq' or 'add_seq'
00176   my $bio07 = 0;
00177   if(!$sa->can('add_seq')) {
00178     $bio07 = 1;
00179   }
00180 
00181   my $ma = $self->adaptor->db->get_MemberAdaptor;
00182 
00183   foreach my $member_attribute (@{$self->get_all_Member_Attribute}) {
00184     my ($member, $attribute) = @{$member_attribute};
00185     if ($member->chr_name =~ /mt/i) {
00186       # codeml icodes
00187       #      0:universal code (default)
00188       my $class;
00189       eval {$class = member->taxon->classification;};
00190       unless ($@) {
00191         if ($class =~ /vertebrata/i) {
00192           #      1:mamalian mt
00193           $sa->{_special_codeml_icode} = 1;
00194         } else {
00195           #      4:invertebrate mt
00196           $sa->{_special_codeml_icode} = 4;
00197         }
00198       }
00199     }
00200     my $peptide_member = $ma->fetch_by_dbID($attribute->peptide_member_id);
00201     my $seqstr;
00202     my $alphabet = 'protein';
00203     if (defined $alignment && $alignment =~ /^cdna$/i) {
00204       $seqstr = $attribute->cdna_alignment_string($peptide_member,$changeSelenos);
00205       $seqstr =~ s/\s+//g;
00206       $alphabet = 'dna';
00207     } else {
00208       $seqstr = $attribute->alignment_string($peptide_member);
00209     }
00210     next if(!$seqstr);
00211     my $cigar_start = $attribute->cigar_start;
00212     my $cigar_end = $attribute->cigar_end;
00213     $cigar_start = 1 unless (defined $cigar_start && $cigar_start != 0);
00214     unless (defined $cigar_end && $cigar_end != 0) {
00215       $cigar_end = $peptide_member->seq_length;
00216       $cigar_end = $cigar_end*3 if (defined $alignment && $alignment =~ /^cdna$/i);
00217     }
00218     #print STDERR "cigar_start $cigar_start cigar_end $cigar_end\n";
00219     my $seq = Bio::LocatableSeq->new(-SEQ    => $seqstr,
00220                                      -ALPHABET  => $alphabet,
00221                                      -START  => $cigar_start,
00222                                      -END    => $cigar_end,
00223                                      -ID     => $peptide_member->stable_id,
00224                                      -STRAND => 0);
00225 
00226     if($bio07) {
00227       $sa->addSeq($seq);
00228     } else {
00229       $sa->add_seq($seq);
00230     }
00231   }
00232 
00233   return $sa;
00234 }
00235 
00236 
00237 =head2 subtype
00238 
00239   Arg [1]    : string $subtype (optional)
00240   Example    : $subtype = $homology->subtype();
00241                $homology->subtype($subtype);
00242   Description: getter/setter of string description of homology subtype.
00243                Examples: 'Chordata', 'Euteleostomi', 'Homo sapiens'
00244   Returntype : string
00245   Exceptions : none
00246   Caller     : general
00247 
00248 =cut
00249 
00250 sub subtype {
00251   my $self = shift;
00252   # deprecate("Use taxonomy_level() instead.");
00253   return $self->taxonomy_level(@_);
00254 }
00255 
00256 
00257 =head2 taxonomy_level
00258 
00259   Arg [1]    : string $taxonomy_level (optional)
00260   Example    : $taxonomy_level = $homology->taxonomy_level();
00261                $homology->taxonomy_level($taxonomy_level);
00262   Description: getter/setter of string description of homology taxonomy_level.
00263                Examples: 'Chordata', 'Euteleostomi', 'Homo sapiens'
00264   Returntype : string
00265   Exceptions : none
00266   Caller     : general
00267 
00268 =cut
00269 
00270 sub taxonomy_level {
00271   my $self = shift;
00272   $self->{'_subtype'} = shift if(@_);
00273   $self->{'_subtype'} = '' unless($self->{'_subtype'});
00274   return $self->{'_subtype'};
00275 }
00276 
00277 
00278 =head2 taxonomy_alias
00279 
00280   Arg [1]    : string $taxonomy_alias (optional)
00281   Example    : $taxonomy_alias = $homology->taxonomy_alias();
00282                $homology->taxonomy_alias($taxonomy_alias);
00283   Description: get string description of homology taxonomy_alias.
00284                Examples: 'Chordates', 'Bony vertebrates', 'Homo sapiens'
00285                Defaults to taxonomy_level if alias is not in the db
00286   Returntype : string
00287   Exceptions : none
00288   Caller     : general
00289 
00290 =cut
00291 
00292 sub taxonomy_alias {
00293   my $self = shift;
00294 
00295   my $ancestor_node_id = $self->ancestor_node_id;
00296   my $tree_dba = $self->adaptor->db->get_ProteinTreeAdaptor;
00297   my $ancestor = $tree_dba->fetch_node_by_node_id($ancestor_node_id);
00298 
00299   return $ancestor->get_tagvalue('taxon_alias') || undef;
00300 }
00301 
00302 
00303 =head2 n
00304 
00305   Arg [1]    : float $n (optional)
00306   Example    : $n = $homology->n();
00307                $homology->n(3);
00308   Description: getter/setter of number of nonsynonymous positions for the homology.
00309   Returntype : float
00310   Exceptions : none
00311   Caller     : general
00312 
00313 =cut
00314 
00315 sub n {
00316   my $self = shift;
00317   $self->{'_n'} = shift if(@_);
00318   return $self->{'_n'};
00319 }
00320 
00321 
00322 =head2 s
00323 
00324   Arg [1]    : float $s (optional)
00325   Example    : $s = $homology->s();
00326                $homology->s(4);
00327   Description: getter/setter of number of synonymous positions for the homology.
00328   Returntype : float
00329   Exceptions : none
00330   Caller     : general
00331 
00332 =cut
00333 
00334 sub s {
00335   my $self = shift;
00336   $self->{'_s'} = shift if(@_);
00337   return $self->{'_s'};
00338 }
00339 
00340 
00341 =head2 lnl
00342 
00343   Arg [1]    : float $lnl (optional)
00344   Example    : $lnl = $homology->lnl();
00345                $homology->lnl(-1234.567);
00346   Description: getter/setter of number of the negative log likelihood for the dnds homology calculation.
00347   Returntype : float
00348   Exceptions : none
00349   Caller     : general
00350 
00351 =cut
00352 
00353 sub lnl {
00354   my $self = shift;
00355   $self->{'_lnl'} = shift if(@_);
00356   return $self->{'_lnl'};
00357 }
00358 
00359 =head2 threshold_on_ds
00360 
00361   Arg [1]    : float $threshold_ond_ds (optional)
00362   Example    : $lnl = $homology->threshold_on_ds();
00363                $homology->threshold_on_ds(1.01340);
00364   Description: getter/setter of the threshold on ds for which the dnds ratio still makes sense.
00365   Returntype : float
00366   Exceptions : none
00367   Caller     : general
00368 
00369 =cut
00370 
00371 sub threshold_on_ds {
00372   my $self = shift;
00373   $self->{'_threshold_on_ds'} = shift if(@_);
00374   return $self->{'_threshold_on_ds'};
00375 }
00376 
00377 =head2 dn
00378 
00379   Arg [1]    : floating $dn (can be undef)
00380   Arg [2]    : boolean $apply_threshold_on_ds (optional, default = 1)
00381                Can be 0 or 1.
00382   Example    : $homology->dn or $homology->dn(0.1209)
00383                if you want to retrieve dn without applying threshold_on_ds, the right call
00384                is $homology->dn(undef,0).
00385   Description: set/get the non synonymous subtitution rate
00386   Returntype : floating
00387   Exceptions : 
00388   Caller     : 
00389 
00390 =cut
00391 
00392 
00393 sub dn {
00394   my ($self, $dn, $apply_threshold_on_ds) = @_;
00395 
00396   $self->{'_dn'} = $dn if (defined $dn);
00397   $apply_threshold_on_ds = 1 unless (defined $apply_threshold_on_ds);
00398 
00399   unless (defined $self->ds(undef, $apply_threshold_on_ds)) {
00400     return undef;
00401   }
00402 
00403   return $self->{'_dn'};
00404 }
00405 
00406 =head2 ds
00407 
00408   Arg [1]    : floating $ds (can be undef)
00409   Arg [2]    : boolean $apply_threshold_on_ds (optional, default = 1)
00410                Can be 0 or 1. 
00411   Example    : $homology->ds or $homology->ds(0.9846)
00412                if you want to retrieve ds without applying threshold_on_ds, the right call
00413                is $homology->dn(undef,0).
00414   Description: set/get the synonymous subtitution rate
00415   Returntype : floating
00416   Exceptions : 
00417   Caller     : 
00418 
00419 =cut
00420 
00421 
00422 sub ds {
00423   my ($self, $ds, $apply_threshold_on_ds) = @_;
00424 
00425   $self->{'_ds'} = $ds if (defined $ds);
00426   $apply_threshold_on_ds = 1 unless (defined $apply_threshold_on_ds);
00427 
00428   if (defined $self->{'_ds'} && 
00429       defined $self->{'_threshold_on_ds'} &&
00430       $self->{'_ds'} > $self->{'_threshold_on_ds'}) {
00431     
00432     if ($apply_threshold_on_ds) {
00433       return undef;
00434     } else {
00435       warning("Threshold on ds values is switched off. Be aware that you may obtain saturated ds values that are not to be trusted, neither the dn/ds ratio\n");
00436     }
00437   }
00438 
00439   return $self->{'_ds'};
00440 }
00441 
00442 =head2 dnds_ratio
00443 
00444   Arg [1]    : boolean $apply_threshold_on_ds (optional, default = 1)
00445                Can be 0 or 1. 
00446   Example    : $homology->dnds_ratio or
00447                $homology->dnds_ratio(0) if you want to obtain a result
00448                even when the dS is above the threshold on dS.
00449   Description: return the ratio of dN/dS
00450   Returntype : floating
00451   Exceptions : 
00452   Caller     : 
00453 
00454 =cut
00455 
00456 
00457 sub dnds_ratio {
00458   my $self = shift;
00459   my $apply_threshold_on_ds = shift;
00460   
00461   $apply_threshold_on_ds = 1 unless (defined $apply_threshold_on_ds);
00462 
00463   my $ds = $self->ds(undef, $apply_threshold_on_ds);
00464   my $dn = $self->dn(undef, $apply_threshold_on_ds);
00465 
00466   unless (defined $dn &&
00467           defined $ds &&
00468           $ds !=0) {
00469     return undef;
00470   }
00471 
00472   unless (defined $self->{'_dnds_ratio'}) {
00473     $self->{'_dnds_ratio'} = sprintf("%.5f",$dn/$ds);
00474   }
00475 
00476   return $self->{'_dnds_ratio'};
00477 }
00478 
00479 
00480 =head2 get_4D_SimpleAlign
00481 
00482   Example    : $4d_align = $homology->get_4D_SimpleAlign();
00483   Description: get 4 times degenerate positions pairwise simple alignment
00484   Returntype : Bio::SimpleAlign
00485 
00486 =cut
00487 
00488 sub get_4D_SimpleAlign {
00489   my $self = shift;
00490   
00491   my $sa = Bio::SimpleAlign->new();
00492 
00493   #Hack to try to work with both bioperl 0.7 and 1.2:
00494   #Check to see if the method is called 'addSeq' or 'add_seq'
00495   my $bio07 = 0;
00496   if(!$sa->can('add_seq')) {
00497     $bio07 = 1;
00498   }
00499 
00500   my $ma = $self->adaptor->db->get_MemberAdaptor;
00501 
00502   my %member_seqstr;
00503   foreach my $member_attribute (@{$self->get_all_Member_Attribute}) {
00504     my ($member, $attribute) = @{$member_attribute};
00505     my $peptide_member = $ma->fetch_by_dbID($attribute->peptide_member_id);
00506     my $seqstr;
00507     $seqstr = $attribute->cdna_alignment_string($peptide_member);
00508     next if(!$seqstr);
00509 #    print STDERR $seqstr,"\n";
00510     my @tmp_tab = split /\s+/, $seqstr;
00511 #    print STDERR "tnp_tab 0: ", $tmp_tab[0],"\n";
00512     $member_seqstr{$peptide_member->stable_id} = \@tmp_tab;
00513   }
00514   
00515   my $seqstr_length;
00516   foreach my $seqid (keys %member_seqstr) {
00517     unless (defined $seqstr_length) {
00518  #     print STDERR $member_seqstr{$seqid}->[0],"\n";
00519       $seqstr_length = scalar @{$member_seqstr{$seqid}};
00520       next;
00521     }
00522     unless ($seqstr_length == scalar @{$member_seqstr{$seqid}}) {
00523       die "Length of dna alignment are not the same, $seqstr_length and " . scalar @{$member_seqstr{$seqid}} ." respectively for homology_id " . $self->dbID . "\n";
00524     }
00525   }
00526   
00527   my %FourD_member_seqstr;
00528   for (my $i=0; $i < $seqstr_length; $i++) {
00529     my $FourD_codon = 1;
00530     my $FourD_aminoacid;
00531     foreach my $seqid (keys %member_seqstr) {
00532       if (FourD_codon($member_seqstr{$seqid}->[$i])) {
00533         if (defined $FourD_aminoacid && 
00534             $FourD_aminoacid eq $FOURD_CODONS{$member_seqstr{$seqid}->[$i]}) {
00535 #          print STDERR "YES ",$FOURD_CODONS{$member_seqstr{$seqid}->[$i]}," ",$member_seqstr{$seqid}->[$i],"\n";
00536           next;
00537         } elsif (defined $FourD_aminoacid) {
00538 #          print STDERR "NO ",$FOURD_CODONS{$member_seqstr{$seqid}->[$i]}," ",$member_seqstr{$seqid}->[$i],"\n";
00539           $FourD_codon = 0;
00540           last;
00541         } else {
00542           $FourD_aminoacid = $FOURD_CODONS{$member_seqstr{$seqid}->[$i]};
00543 #          print STDERR $FOURD_CODONS{$member_seqstr{$seqid}->[$i]}," ",$member_seqstr{$seqid}->[$i]," ";
00544         }
00545         next;
00546       } else {
00547 #        print STDERR "NO ",$CODONS{$member_seqstr{$seqid}->[$i]}," ",$member_seqstr{$seqid}->[$i],"\n";
00548         $FourD_codon = 0;
00549         last;
00550       }
00551     }
00552     next unless ($FourD_codon);
00553     foreach my $seqid (keys %member_seqstr) {
00554       $FourD_member_seqstr{$seqid} .= substr($member_seqstr{$seqid}->[$i],2,1);
00555     }
00556   }
00557   
00558   foreach my $seqid (keys %FourD_member_seqstr) {
00559   
00560     my $seq = Bio::LocatableSeq->new(-SEQ    => $FourD_member_seqstr{$seqid},
00561                                      -START  => 1,
00562                                      -END    => length($FourD_member_seqstr{$seqid}),
00563                                      -ID     => $seqid,
00564                                      -STRAND => 0);
00565     
00566     if($bio07) {
00567       $sa->addSeq($seq);
00568     } else {
00569       $sa->add_seq($seq);
00570     }
00571   }
00572   
00573   return $sa;
00574 }
00575 
00576 sub FourD_codon {
00577   my ($codon) = @_;
00578   
00579   if (defined $FOURD_CODONS{$codon}) {
00580     return 1;
00581   }
00582 
00583   return 0;
00584 }
00585 
00586 sub TwoD_codon {
00587   my ($codon) = @_;
00588   
00589   if (defined $TWOD_CODONS{$codon}) {
00590     return 1;
00591   }
00592 
00593   return 0;
00594 }
00595 
00596 =head2 print_homology
00597 
00598  Example    : $homology->print_homology
00599  Description: This method prints a short descriptor of the homology
00600           USE ONLY FOR DEBUGGING not for data output since the
00601           format of this output may change as need dictates.
00602 
00603 =cut
00604 
00605 sub print_homology {
00606   my $self = shift;
00607   
00608   printf("Homology %d,%s,%s : ", $self->dbID, $self->description, $self->subtype);
00609   foreach my $member_attribute (@{$self->get_all_Member_Attribute}) {
00610     my ($member, $attribute) = @{$member_attribute};
00611     printf("%s(%d)\t", $member->stable_id, $member->dbID);
00612   }
00613   print("\n");
00614 }
00615 
00616 
00617 =head2 get_all_PeptideAlignFeature
00618 
00619   Example    : my ($paf) = @{$homology->get_all_PeptideAlignFeature};
00620                my ($paf, $recipPaf) = @{$homology->get_all_PeptideAlignFeature};
00621   Description: return the peptide_align_feature object (and its reciprocal hit)
00622                used to create this homology
00623   Returntype : array ref of peptide_align_feature objects
00624   Exceptions :
00625   Caller     :
00626 
00627 =cut
00628 
00629 sub get_all_PeptideAlignFeature {
00630   my $self = shift;
00631 
00632   my @pafs;
00633   throw("homology must have a valid adaptor and db in order to get peptide_align_features")
00634     unless($self->adaptor and $self->adaptor->db);
00635   my $pafDBA = $self->adaptor->db->get_PeptideAlignFeatureAdaptor;
00636   
00637   foreach my $RefArrayOfMemberAttributeArrayRef ($self->get_Member_Attribute_by_source("ENSEMBLGENE")) {
00638     foreach my $memAttributeArrayRef (@{$RefArrayOfMemberAttributeArrayRef}) {
00639       my $member = $memAttributeArrayRef->[0];
00640       my $attribute = $memAttributeArrayRef->[1];
00641 
00642       if($attribute->peptide_align_feature_id) {
00643         my $paf = $pafDBA->fetch_by_dbID($attribute->peptide_align_feature_id);
00644         push @pafs, $paf;
00645       }
00646     }
00647   }
00648   return \@pafs;
00649 }
00650 
00651 
00652 =head2 has_species_by_name
00653 
00654   Arg [1]    : string $species_name
00655   Example    : my $ret = $homology->has_species_by_name("Homo sapiens");
00656   Description: return TRUE or FALSE whether one of the members in the homology is from the given species
00657   Returntype : 1 or 0
00658   Exceptions :
00659   Caller     :
00660 
00661 =cut
00662 
00663 
00664 sub has_species_by_name {
00665   my $self = shift;
00666   my $species_name = shift;
00667   
00668   foreach my $member_attribute (@{$self->get_all_Member_Attribute}) {
00669     my ($member, $attribute) = @{$member_attribute};
00670     return 1 if($member->genome_db->name eq $species_name);
00671   }
00672   return 0;
00673 }
00674 
00675 
00676 =head2 gene_list
00677 
00678   Example    : my $pair = $homology->gene_list
00679   Description: return the pair of members for the homology
00680   Returntype : array ref of (2) Bio::EnsEMBL::Compara::Member objects
00681   Caller     : general
00682 
00683 =cut
00684 
00685 
00686 sub gene_list {
00687   my $self = shift;
00688   my @genes;
00689   foreach my $member_attribute (@{$self->get_all_Member_Attribute}) {
00690     my ($member, $attribute) = @{$member_attribute};
00691     push @genes, $member;
00692   }
00693   return \@genes;
00694 }
00695 
00696 
00697 =head2 homology_key
00698 
00699   Example    : my $key = $homology->homology_key;
00700   Description: returns a string uniquely identifying this homology in world space.
00701                uses the gene_stable_ids of the members and orders them by taxon_id
00702                and concatonates them together.  
00703   Returntype : string
00704   Exceptions :
00705   Caller     :
00706 
00707 =cut
00708 
00709 sub homology_key {
00710   my $self = shift;
00711   return $self->{'_homology_key'} if(defined($self->{'_homology_key'}));
00712   
00713   my @genes;
00714   foreach my $member_attribute (@{$self->get_all_Member_Attribute}) {
00715     my ($member, $attribute) = @{$member_attribute};
00716     push @genes, $member;
00717   }
00718   @genes = sort {$a->taxon_id <=> $b->taxon_id || $a->stable_id cmp $b->stable_id} @genes;
00719   @genes = map ($_->stable_id, @genes);
00720 
00721   my $homology_key = join('_', @genes);
00722   return $homology_key;
00723 }
00724 
00725 
00726 =head2 node_id
00727 
00728   Arg [1]    : int $node_id (optional)
00729   Example    : $node_id = $homology->node_id();
00730                $homology->subtype($node_id);
00731   Description: getter/setter of integer that refer to a node_id in the protein_tree data.
00732   Returntype : int
00733   Exceptions : none
00734   Caller     : general
00735 
00736 =cut
00737 
00738 sub node_id {
00739   my $self = shift;
00740 
00741   $self->{'_ancestor_node_id'} = shift if(@_);
00742   $self->{'_ancestor_node_id'} = '' unless($self->{'_ancestor_node_id'});
00743   return $self->{'_ancestor_node_id'};
00744   
00745 }
00746 
00747 =head2 ancestor_node_id
00748 
00749   Arg [1]    : int $ancestor_node_id (optional)
00750   Example    : $ancestor_node_id = $homology->ancestor_node_id();
00751                $homology->subtype($ancestor_node_id);
00752   Description: getter/setter of integer that refer to the ancestor_node_id in the protein_tree data.
00753   Returntype : int
00754   Exceptions : none
00755   Caller     : general
00756 
00757 =cut
00758 
00759 sub ancestor_node_id {
00760   my $self = shift;
00761 
00762   $self->{'_ancestor_node_id'} = shift if(@_);
00763   $self->{'_ancestor_node_id'} = '' unless($self->{'_ancestor_node_id'});
00764   return $self->{'_ancestor_node_id'};
00765   
00766 }
00767 
00768 
00769 =head2 tree_node_id
00770 
00771   Arg [1]    : int $tree_node_id (optional)
00772   Example    : $tree_node_id = $homology->tree_node_id();
00773                $homology->subtype($tree_node_id);
00774   Description: getter/setter of integer that refer to the tree node_id in the protein_tree data.
00775   Returntype : int
00776   Exceptions : none
00777   Caller     : general
00778 
00779 =cut
00780 
00781 sub tree_node_id {
00782   my $self = shift;
00783 
00784   $self->{'_tree_node_id'} = shift if(@_);
00785   $self->{'_tree_node_id'} = '' unless($self->{'_tree_node_id'});
00786   return $self->{'_tree_node_id'};
00787   
00788 }
00789 
00790 
00791 1;
00792