package EnsEMBL::Web::Component::Go;
use EnsEMBL::Web::Component;
use EnsEMBL::Web::Component::Feature;
use EnsEMBL::Web::Document::SpreadSheet;
our @ISA = qw( EnsEMBL::Web::Component);
use strict;
use warnings;
no warnings "uninitialized";
sub accession {
my( $panel, $object ) = @_;
my $acc_id = $object->param('display') || $object->param('acc');
my $label = 'GO Accession';
my $name;
return unless $object->name;
my $html = '<p>';
if ( $object->param('display') ) {
$name = $object->name;
$html .= qq(The following genes have been mapped to Gene Ontology ID: <a href="goview?acc=$acc_id">$acc_id</a> [$name]);
} elsif ($acc_id) {
$name = $object->name;
$html .= qq(<strong>$acc_id</strong> [$name]);
} else {
$html .= '(none selected)';
}
$html .= '</p>';
$panel->add_row( $label, $html );
return 1;
}
sub gene_acc {
my( $panel, $object ) = @_;
my $acc_id = $object->acc_id;
return unless $object->name;
my $name = $object->name;
$panel->add_row( 'GO Accession', $acc_id ? "<p><strong>$acc_id</strong> ($name)</p>" : "<p>(none selected)</p>" );
return 1;
}
sub database {
my( $panel, $object ) = @_;
my $label = 'GO Database';
my $html = qq(
<p>GO data is provided by the <a href="http://www.geneontology.org/">Gene Ontology Consortium</a></p>
);
$panel->add_row( $label, $html );
return 1;
}
# goview needs its own search box, as the sitewide search doesn't have
# a connection to the GO database
sub search {
my( $panel, $object ) = @_;
$panel->add_row( 'Search GO', "@{[ $panel->form( 'search' )->render ]}" );
return 1;
}
sub search_form {
my( $panel, $object ) = @_;
my $go_id = $object->param('acc');
my $go_str = '';
if ($go_id) {
$go_str = $go_id.',';
}
my $form = EnsEMBL::Web::Form->new( 'gosearch', "/@{[$object->species]}/goview", 'get' );
$form->add_element(
'type' => 'String', 'required' => 'yes',
'label' => "Search GO database for:", 'name' => 'query',
'value' => $go_id, 'style' => 'medium',
'notes' => "[ e.g. $go_str *vesicle, *calcium binding* ]"
);
$form->add_element('type' => 'Submit', 'value' => 'Search');
return $form;
}
sub show_karyotype {
my( $panel, $object ) = @_;
$object->load_genes();
my $karyotype = EnsEMBL::Web::Component::Feature::create_karyotype($panel, $object);
$panel->add_row( 'Gene Location', $karyotype->render );
return 1;
}
#-----------------------------------------------------------------------------
# draws a table-style tree
sub tree {
my( $panel, $object ) = @_;
my $species = $object->species;
if ($object->param('acc') || $object->param('query')) {
# start building spreadsheet
my $table = EnsEMBL::Web::Document::SpreadSheet->new();
$table->add_columns(
{'key' => 'tree', 'title' => "", 'width' => '60%', 'align' => 'left' },
{'key' => 'genes', 'title' => "Gene Matches", 'width' => '40%', 'align' => 'center'
},
);
# create tree
my $it = $object->iterator;
return unless $it;
my %families = %{$object->families};
my $id = $object->acc_id;
my $query = $object->param('query');
my ($class, $tree, $genes);
my $depth_limit = 10000;
while (my $ni = $it->next_node_instance) {
$tree = '';
$genes = ''; # clear strings
my $depth = 2 * $ni->depth;
my $term = $ni->term;
my $localid = $term->public_acc();
my $name = $term->name;
next if ($ni->depth >= $depth_limit + 1);
# set highlight styles
my $is_head = 0;
my $is_match = 0;
if ($name eq "biological_process" || $name eq "cellular_component" || $name eq "molecular_function"){
$is_head = 1;
}
my $current_style = 'bg3';
# do tree indent
$tree .= '<div style="padding-left:'.$depth.'em';
if ($is_head) {
$tree .= qq(;font-weight:bold);
}
$tree .= '">';
# highlight current GO
if ($localid eq $id) { # also check for matching IDs
$is_match = 1;
} elsif($query) { # check match between name and query string
my @words = split(/\s+/, $name);
foreach my $word (@words) {
$word =~ s/[\(\)]//g; # remove chars that might break regex
if ($query =~ /$word/) {
$is_match = 1;
}
}
}
if ($is_match) {
$depth_limit = $ni->depth() + 1;
$tree .= qq(<span class="$current_style">$name</span>);
} else {
$tree .= $name;
}
$tree .= qq( [<a href="/$species/goview?acc=$localid">$localid</a>]</div>);
# now get gene info
# my @extgenes = @{$families{$localid}};
my $count = $object->count_genes( $localid );
# $count = scalar(@extgenes);
if($count>0){
$genes .= qq(<a href="/$species/goview?display=$localid;chr_length=200">$count gene(s) </a>\n);
} else {
$genes .= ' ';
}
# add completed row to table
my $data_row = { 'tree' => $tree, 'genes' => $genes};
$table->add_row( $data_row );
}
$panel->add_row('Go Graph', $table->render);
}
return 1;
}
sub family {
my( $panel, $object ) = @_;
my $id = $object->param('display');
my $species = $object->species;
if ($id) {
return unless $object->load_genes();
my $table = EnsEMBL::Web::Document::SpreadSheet->new();
$table->add_columns(
{'key' => 'id', 'title' => "Ensembl Gene ID", 'width' => '25%', 'align' => 'left' },
{'key' => 'desc', 'title' => "Gene Description", 'width' => '35%', 'align' => 'left'},
{'key' => 'family', 'title' => "Protein Family/Family Description", 'width' => '40%', 'align' => 'left'},
);
my @gene_info = @{$object->get_geneinfo};
my @family_info = @{$object->get_faminfo};
my $gene_total = scalar(@gene_info);
for (my $i=0; $i<$gene_total; $i++) {
my %gene = %{$gene_info[$i]};
my %family = %{$family_info[$i]||{}};
# start paragraphs for content
my $id_txt = '<p>';
my $desc_txt = '<p>';
my $fam_txt = '<p>';
# gene ID and evidence
my $gid = $gene{'stable_id'};
my $ev = $gene{'evidence'};
$id_txt .= qq(<a href="/$species/geneview?gene=$gid">$gid</a> <span class="small">Evidence:$ev</span>);
# gene description
$desc_txt .= $gene{'description'};
# family ID and description
if( $family{'stable_id'} ) {
my $fid = $family{'stable_id'};
my $desc = $family{'description'};
$fam_txt .= qq(<a href="/$species/familyview?family=$fid">$fid</a><br /><em>$desc</em>);
} else {
$fam_txt .= '--';
}
# close all paragraphs
$id_txt .= '</p>';
$desc_txt .= '</p>';
$fam_txt .= '</p>';
# add completed row to table
my $data_row = { 'id' => $id_txt, 'desc' => $desc_txt, 'family'=>$fam_txt};
$table->add_row( $data_row );
}
# add table to panel
$panel->add_row('Gene and Protein Family Information', $table->render);
}
return 1;
}
1;