Skip to content
Snippets Groups Projects
Commit b083bd7d authored by Andy Yates's avatar Andy Yates
Browse files

[ENSCORESW-628]. Supporting a JSON output for GeneTrees.

Finally we have a JSON output for gene trees. it's not done nicely but it works. Also it is very very fast! Support is done using the TreeHash builder and then delegating to the JSON encoder. A custom serialiser has been built in the view layer. Otherwise we would have to do content-type/accepts detection. That's not nice at all!
parent 601a3785
No related branches found
No related tags found
No related merge requests found
package EnsEMBL::REST::Builder::TreeHash;
use Moose;
use namespace::autoclean;
use Bio::EnsEMBL::Utils::Scalar qw(check_ref);
has 'aligned' => ( isa => 'Bool', is => 'ro', default => 0);
has 'cdna' => ( isa => 'Bool', is => 'ro', default => 0);
has 'no_sequences' => ( isa => 'Bool', is => 'ro', default => 0);
has 'source' => ( isa => 'Str', is => 'ro', default => 'ensembl');
has 'type' => ( isa => 'Str', is => 'ro', default => 'gene tree');
sub convert {
my ($self, $tree) = @_;
my $hash = $self->_head_node($tree);
return $self->_recursive_conversion($tree->root(), $hash);
}
sub _head_node {
my ($self, $tree) = @_;
my $hash = {
type => $self->type(),
rooted => 1,
};
if($tree->can('stable_id')) {
$hash->{id} = $tree->stable_id();
}
return $hash;
}
sub _recursive_conversion {
my ($self, $tree, $hash) = @_;;
my $new_hash = $self->_convert_node($tree, $hash);
if($tree->get_child_count()) {
my @converted_children;
foreach my $child (@{$tree->sorted_children()}) {
my $converted_child = $self->_recursive_conversion($child);
push(@converted_children, $converted_child);
}
$new_hash->{children} = \@converted_children;
}
return $new_hash;
}
# If $hash is given we will add attributes to the hash. If not
# then we will create a new one.
sub _convert_node {
my ($self, $node, $hash) = @_;
$hash ||= {};
my $type = $node->get_tagvalue('node_type');
my $boot = $node->get_tagvalue('bootstrap');
my $taxid = $node->get_tagvalue('taxon_id');
my $tax = $node->get_tagvalue('taxon_name');
$hash->{branch_length} = $node->distance_to_parent() + 0;
if($taxid) {
$hash->{taxonomy} = { id => $taxid + 0, scientific_name => $tax };
}
if($boot) {
$hash->{boostrap} = $boot + 0;
}
if($type && $type ~~ [qw/duplication dubious/]) {
$hash->{event} = $type;
}
if(check_ref($node, 'Bio::EnsEMBL::Compara::GeneTreeMember')) {
my $gene = $node->gene_member();
$hash->{name} = $gene->stable_id();
$hash->{genome_db_name} = $node->genome_db()->name();
$hash->{sequence}->{accession} = $node->stable_id();
$hash->{sequence}->{source} = $self->source();
$hash->{sequence}->{name} = $node->display_label() if $node->display_label();
$hash->{sequence}->{location} = sprintf('%s:%d-%d',$gene->chr_name(), $gene->chr_start(), $gene->chr_end());
if(! $self->no_sequences()) {
my $aligned = $self->aligned();
my $mol_seq;
if($aligned) {
$mol_seq = ($self->cdna()) ? $node->alignment_string('cds') : $node->alignment_string();
}
else {
$mol_seq = ($self->cdna()) ? $node->other_sequence('cds') : $node->sequence();
}
$hash->{sequence}->{seq} = $mol_seq;
$hash->{sequence}->{aligned} = $aligned + 0;
}
}
return $hash;
}
__PACKAGE__->meta()->make_immutable();
1;
\ No newline at end of file
......@@ -13,8 +13,7 @@ __PACKAGE__->config(
'text/x-phyloxml+xml' => [qw/View PhyloXML/],
'text/x-phyloxml' => [qw/View PhyloXML/], #naughty but needs must
'text/x-nh' => [qw/View NHTree/],
'application/json' => [],
'text/x-yaml' => [],
'application/json' => [qw/View JSONTree/],
'text/xml' => [qw/View PhyloXML/],
}
);
......
package EnsEMBL::REST::View::JSONTree;
use Moose;
use namespace::autoclean;
use JSON;
use EnsEMBL::REST::Builder::TreeHash;
extends 'Catalyst::View';
sub process {
my ($self, $c, $stash_key) = @_;
$stash_key ||= 'rest';
my $gt = $c->stash()->{$stash_key};
my $builder = EnsEMBL::REST::Builder::TreeHash->new();
$builder->aligned(1) if $c->request()->param('aligned') || $c->request()->param('phyloxml_aligned');
my $sequence = $c->request->param('sequence') || $c->request()->param('phyloxml_sequence') || 'protein';
$builder->cdna(1) if $sequence eq 'cdna';
$builder->no_sequences(1) if $sequence eq 'none';
$gt->preload();
my $hash = $builder->convert($gt);
my $encode = encode_json($hash);
$gt->release_tree();
$c->res->body($encode);
$c->res->headers->header('Content-Type' => 'application/json');
}
__PACKAGE__->meta->make_immutable;
1;
\ No newline at end of file
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment