diff --git a/modules/EnsEMBL/Draw/GlyphSet/genetree.pm b/modules/EnsEMBL/Draw/GlyphSet/genetree.pm index 34395121a4..1aa2835234 100644 --- a/modules/EnsEMBL/Draw/GlyphSet/genetree.pm +++ b/modules/EnsEMBL/Draw/GlyphSet/genetree.pm @@ -840,7 +840,22 @@ sub features { if ($show_exons) { my $ref_genetree = $tree->tree; - $ref_genetree = $ref_genetree->alternative_trees->{default} if $ref_genetree->ref_root_id; + + if ($ref_genetree->ref_root_id) { + + # If $ref_genetree is a contributing tree, we need to fetch the + # corresponding reference tree in order to get exon boundary data. + my @matching_ref_genetrees = grep { + !$_->ref_root_id && $_->root_id == $ref_genetree->ref_root_id + } values %{$ref_genetree->alternative_trees}; + + # Gene trees are uniquely identified by their root_id, so there can be at + # most one gene tree with a root_id matching $ref_genetree->ref_root_id + if (scalar(@matching_ref_genetrees) > 0) { + $ref_genetree = $matching_ref_genetrees[0]; + } + } + unless ($ref_genetree->{_exon_boundaries_hash}) { my $gtos_adaptor = $tree->adaptor->db->get_GeneTreeObjectStoreAdaptor; my $json_string = $gtos_adaptor->fetch_by_GeneTree_and_label($ref_genetree, 'exon_boundaries'); diff --git a/modules/EnsEMBL/Web/Command/DataExport/Output.pm b/modules/EnsEMBL/Web/Command/DataExport/Output.pm index 89f8e58f8f..17d9f7955b 100644 --- a/modules/EnsEMBL/Web/Command/DataExport/Output.pm +++ b/modules/EnsEMBL/Web/Command/DataExport/Output.pm @@ -157,7 +157,7 @@ sub process { $url_params->{'__clear'} = 1; ## Pass parameters needed for Back button to work my @core_params = keys %{$hub->core_object('parameters')}; - push @core_params, qw(export_action data_type data_action component align g1 node strain hom_id); + push @core_params, qw(export_action data_type data_action component align align_type clusterset_id g1 hom_id node strain); push @core_params, $self->config_params; foreach (@core_params) { my @values = $component->param($_); diff --git a/modules/EnsEMBL/Web/Component/DataExport/GeneTree.pm b/modules/EnsEMBL/Web/Component/DataExport/GeneTree.pm index b6d4fc2612..c851065f15 100644 --- a/modules/EnsEMBL/Web/Component/DataExport/GeneTree.pm +++ b/modules/EnsEMBL/Web/Component/DataExport/GeneTree.pm @@ -41,7 +41,7 @@ sub content { my $view_config = $self->view_config; my $settings = $view_config->form_fields('export'); - $settings->{'Hidden'} = [qw(align align_type node strain)]; + $settings->{'Hidden'} = [qw(align align_type clusterset_id node strain)]; ## Add export-specific settings my $fields_by_format; @@ -87,9 +87,9 @@ sub content { ## Options per format $fields_by_format = [{'Tree formats' => { - 'Newick' => [qw(newick_mode clusterset_id)], - 'NHX' => [qw(nhx_mode clusterset_id)], - 'Text' => [qw(scale clusterset_id)], + 'Newick' => [qw(newick_mode)], + 'NHX' => [qw(nhx_mode)], + 'Text' => [qw(scale)], 'OrthoXML' => [], 'PhyloXML' => $self->phyloxml_fields, }}]; diff --git a/modules/EnsEMBL/Web/Component/Gene/ComparaTree.pm b/modules/EnsEMBL/Web/Component/Gene/ComparaTree.pm index 9e17064bd3..e73028a2c0 100644 --- a/modules/EnsEMBL/Web/Component/Gene/ComparaTree.pm +++ b/modules/EnsEMBL/Web/Component/Gene/ComparaTree.pm @@ -164,12 +164,28 @@ sub content { } if ($hub->type eq 'Gene') { - if ($tree->tree->clusterset_id ne $clusterset_id) { - $html .= $self->_info('Phylogenetic model selection', - sprintf( - 'The phylogenetic model %s is not available for this tree. Showing the %s tree instead.', $clusterset_id, $tree->tree->clusterset_id, - ) - ); + my $tree_clusterset_id = $tree->tree->clusterset_id; + if ($tree_clusterset_id ne $clusterset_id) { + my $strain_clusterset_id = $hub->species_defs->get_config($self->hub->species, 'RELATED_TAXON'); + # When switching between the respective consensus trees of the default and strain gene-tree view + # (e.g. 'default' to 'murinae'), each clusterset_id represents the consensus clusterset for its + # respective view, so we skip the model selection info box in such cases. + unless ( $strain_clusterset_id + && + ( + ($clusterset_id eq 'default' && $tree_clusterset_id eq $strain_clusterset_id) + || + ($clusterset_id eq $strain_clusterset_id && $tree_clusterset_id eq 'default') + ) + ) { + $html .= $self->_info('Phylogenetic model selection', + sprintf( + 'The phylogenetic model %s is not available for this tree. Showing the %s tree instead.', + $clusterset_id, + $tree_clusterset_id, + ) + ); + } } elsif ($tree->tree->ref_root_id) { my $text = sprintf( @@ -177,7 +193,7 @@ sub content { ); my $rank = $tree->tree->get_tagvalue('k_score_rank'); my $score = $tree->tree->get_tagvalue('k_score'); - $text .= sprintf('
This tree is the n°%d closest to the final tree, with a K-distance of %f, as computed by Ktreedist.', $rank, $score) if $rank; + $text .= sprintf('
This tree is the n°%d closest to the final tree, with a K-distance of %f, as computed by Ktreedist.', $rank, $score) if $rank; $html .= $self->_info('Phylogenetic model selection', $text); } } diff --git a/modules/EnsEMBL/Web/Object/Gene.pm b/modules/EnsEMBL/Web/Object/Gene.pm index 1176d717f9..f09bd9d58a 100644 --- a/modules/EnsEMBL/Web/Object/Gene.pm +++ b/modules/EnsEMBL/Web/Object/Gene.pm @@ -936,23 +936,46 @@ sub get_homologue_alignments { } +sub _resolve_clusterset_ids { + my ($self, $strain_tree) = @_; + + my $consensus_clusterset_id = $strain_tree || 'default'; + my $clusterset_id = $self->hub->param('clusterset_id'); + return [$consensus_clusterset_id, $clusterset_id]; +} + + sub get_GeneTree { my $self = shift; my $compara_db = shift || 'compara'; my $whole_tree = shift; my $strain_tree = shift; - my $clusterset_id = $strain_tree || $self->hub->param('clusterset_id') || 'default'; - my $cache_key = sprintf('_protein_tree_%s_%s_%s', $compara_db, $clusterset_id, $strain_tree); + my ($consensus_clusterset_id, $clusterset_id) = @{$self->_resolve_clusterset_ids($strain_tree)}; + + my $cache_key = sprintf('_protein_tree_%s_%s_%s', $compara_db, $clusterset_id, $consensus_clusterset_id); if (!$self->{$cache_key}) { my $args = {'stable_id' => $self->stable_id, 'cdb' => $compara_db}; my $member = $self->get_compara_Member($args) || return; my $adaptor = $member->adaptor->db->get_adaptor('GeneTree') || return; - my $tree = $adaptor->fetch_all_by_Member($member, -clusterset_id => $clusterset_id)->[0]; + + # We fetch the consensus tree in the first instance. This is typically + # the 'default' tree for the current gene-tree view, which is either + # the tree we want, or the reference tree of the tree we want. + my $tree = $adaptor->fetch_default_for_Member($member, $consensus_clusterset_id); + unless ($tree) { $tree = $adaptor->fetch_default_for_Member($member); } return unless $tree; + + # If an alternative clusterset_id has been specified that + # is appropriate to the current gene-tree view, it should + # be one of the alternative trees of the consensus tree. + if ($clusterset_id && exists $tree->alternative_trees->{$clusterset_id}) { + $tree = $tree->alternative_trees->{$clusterset_id}; + } + return $tree if $whole_tree; $tree->preload; diff --git a/modules/EnsEMBL/Web/ViewConfig/Gene/ComparaTree.pm b/modules/EnsEMBL/Web/ViewConfig/Gene/ComparaTree.pm index 0e5bb1f496..5511f65160 100644 --- a/modules/EnsEMBL/Web/ViewConfig/Gene/ComparaTree.pm +++ b/modules/EnsEMBL/Web/ViewConfig/Gene/ComparaTree.pm @@ -155,19 +155,27 @@ sub init_form_non_cacheable { my $form = $self->SUPER::init_form_non_cacheable(@_); my %other_clustersets; + my $page_action = $hub->referer->{'ENSEMBL_ACTION'}; + my $consensus_clusterset_id = $hub->param('strain') || $page_action =~ /^Strain_/ + ? $hub->species_defs->get_config($hub->species, 'RELATED_TAXON') + : 'default' + ; + if($hub->param('g')) { my $database = $hub->database($cdb); my $genome_db = $database->get_GenomeDBAdaptor->fetch_by_name_assembly($hub->species_defs->SPECIES_PRODUCTION_NAME); my $member = $database->get_GeneMemberAdaptor->fetch_by_stable_id_GenomeDB($hub->core_params->{'g'}, $genome_db); my $adaptor = $database->get_GeneTreeAdaptor; - my $gene_tree = $adaptor->fetch_default_for_Member($member); + my $gene_tree = $adaptor->fetch_default_for_Member($member, $consensus_clusterset_id); + $consensus_clusterset_id = $gene_tree->clusterset_id if $gene_tree->clusterset_id ne $consensus_clusterset_id; %other_clustersets = map { $_->clusterset_id => 1 } @{$adaptor->fetch_all_linked_trees($gene_tree)}; - delete $other_clustersets{'default'}; + delete $other_clustersets{$consensus_clusterset_id}; } if (my $dropdown = $form->get_elements_by_name('clusterset_id')->[0]) { + $self->_replace_default_clusterset_id_option($dropdown, $consensus_clusterset_id) if $consensus_clusterset_id ne 'default'; $dropdown->add_option({ 'value' => $_, 'caption' => $_ }) for sort keys %other_clustersets; } @@ -179,4 +187,13 @@ sub _groups { return (@{ $_[0]->species_defs->TAXON_ORDER }); } +sub _replace_default_clusterset_id_option { + my ($self, $cset_id_dropdown, $clusterset_id) = @_; + + my $default_option = $cset_id_dropdown->get_elements_by_attribute({'value' => 'default'})->[0]; + my $cset_id_option = $cset_id_dropdown->dom->create_element('option', {'value' => $clusterset_id, 'inner_HTML' => 'Final (merged) tree'}); + $default_option->after($cset_id_option); + $default_option->remove(); +} + 1;