package EnsEMBL::Web::Configuration::Transcript;
use strict;
use EnsEMBL::Web::Document::Panel::SpreadSheet;
use EnsEMBL::Web::Document::Panel::Information;
use EnsEMBL::Web::Document::Panel::Image;
use EnsEMBL::Web::Data::Release;
use EnsEMBL::Web::RegObj;
use Bio::EnsEMBL::Variation::Utils::Sequence qw(ambiguity_code variation_class);
use Data::Dumper;
use base qw(EnsEMBL::Web::Configuration);
sub set_default_action {
my $self = shift;
unless( ref $self->object ) {
$self->{_data}{default} = 'Summary';
return;
}
my $x = $self->object->availability || {};
if( $x->{'either'} ) {
$self->{_data}{default} = 'Summary';
} elsif( $x->{'idhistory'} ) {
$self->{_data}{default} = 'Idhistory';
}
}
sub global_context { return $_[0]->_global_context; }
sub ajax_content { return $_[0]->_ajax_content; }
sub local_context { return $_[0]->_local_context; }
sub local_tools { return $_[0]->_local_tools; }
sub content_panel { return $_[0]->_content_panel; }
sub context_panel { return $_[0]->_context_panel; }
sub export_configurator {
my $self = shift;
my $object = $self->object;
return $self->pop_export_configurator if $object->action eq 'Population';
return $self->_export_configurator;
}
sub pop_export_configurator {
my $self = shift;
my $object = $self->{'object'};
my $time = time;
my $params = {
'time' => $time,
'action' => 'Export',
'output' => 'gen_var'
};
map { $params->{$_} = $object->param($_) unless $object->param($_) eq 'off' } $object->param;
my $href = $object->_url($params);
my @formats = (
[ 'HTML', 'HTML', ' rel="external"' ],
[ 'Text', 'Text', ' rel="external"' ]
);
my $content = qq{
<h2>Export Configuration - Transcript Genetic Variation</h2>
<form id="export_output_configuration" class="std check" method="get" action="#">
<fieldset>
<p>Dump of SNP data per individual (SNPs in rows, individuals in columns). For more advanced data queries use <a href="/biomart/martview">BioMart</a>.</p>
<p>Please choose a format for your exported data</p>
<ul>};
foreach (@formats) {
my $format = ";_format=$_->[1]" if $_->[1];
$content .= qq{
<li><a class="modal_close" href="$href$format"$_->[2]>$_->[0]</a>$_->[3]</li>};
}
$content .= qq{
</ul>
</form>};
my $panel = $self->new_panel(
'Configurator',
'code' => 'configurator',
'object'=> $object
);
$panel->set_content($content);
$self->add_panel($panel);
}
sub ajax_zmenu {
my $self = shift;
my $panel = $self->_ajax_zmenu;
my $obj = $self->object;
my $dest = $obj->action().'/'.$obj->function();
my $action = $obj->action;
if ($dest eq 'SupportingEvidence/Alignment') {
return $self->do_SE_align_menu($panel,$obj);
} elsif ($action eq 'Idhistory_Node'){
return $self->ajax_zmenu_id_history_tree_node();
} elsif ($action eq 'Idhistory_Branch'){
return $self->ajax_zmenu_id_history_tree_branch();
} elsif ($action eq 'Idhistory_Label'){
return $self->ajax_zmenu_id_history_tree_label();
} elsif( $action eq 'Variation'){
return $self->ajax_zmenu_variation($panel, $obj);
} elsif( $action eq 'Variation_transcript'){
return $self->ajax_zmenu_variation_transcript($panel, $obj);
} elsif( $action eq 'Transcript_Variation'){
return $self->_ajax_zmenu_transcript_variation($panel, $obj);
} elsif( $action eq 'ref'){
return $self->_ajax_zmenu_change_reference($panel, $obj);
} elsif( $action eq 'coverage'){
return $self->ajax_zmenu_read_coverage($panel, $obj);
} elsif( $action eq 'ProteinSummary') {
return $self->_ajax_zmenu_protein_feature($panel, $obj);
} else {
my( $disp_id, $X,$Y, $db_label ) = $obj->display_xref;
$panel->{'caption'} = $disp_id ? "$db_label: $disp_id"
: (! $obj->gene ) ? $obj->Obj->stable_id
: 'Novel transcript';
$panel->add_entry({
'type' => 'Transcript',
'label' => $obj->stable_id,
'link' => $obj->_url({'type'=>'Transcript', 'action'=>'Summary'}),
'priority' => 195
});
## Only if there is a gene (not Prediction transcripts)
if( $obj->gene ) {
$panel->add_entry({
'type' => 'Gene',
'label' => $obj->gene->stable_id,
'link' => $obj->_url({'type'=>'Gene', 'action'=>'Summary'}),
'priority' => 190
});
$panel->add_entry({
'type' => 'Gene type',
'label' => $obj->gene_stat_and_biotype,
'priority' => 70,
});
}
$panel->add_entry({
'type' => 'Location',
'label' => sprintf( "%s: %s-%s",
$obj->neat_sr_name($obj->seq_region_type,$obj->seq_region_name),
$obj->thousandify( $obj->seq_region_start ),
$obj->thousandify( $obj->seq_region_end )
),
'link' => $obj->_url({'type'=>'Location', 'action'=>'View', 'r' => $obj->seq_region_name.':'.$obj->seq_region_start.'-'.$obj->seq_region_end })
});
$panel->add_entry({
'type' => 'Strand',
'label' => $obj->seq_region_strand < 0 ? 'Reverse' : 'Forward',
'priority' => 60
});
$panel->add_entry({
'type' => 'Base pairs',
'label' => $obj->thousandify( $obj->Obj->seq->length ),
'priority' => 50
});
if ($obj->get_db eq 'vega') {
$panel->add_entry({
'type' => 'Transcript class',
'label' => $obj->transcript_class,
'priority' => 65
});
}
## Protein coding transcripts only....
if( $obj->Obj->translation ) {
$panel->add_entry({
'type' => 'Protein product',
'label' => $obj->Obj->translation->stable_id || $obj->Obj->stable_id,
'link' => $obj->_url({'type'=>'Transcript', 'action' => 'ProteinSummary'}),
'priority' => 180
});
$panel->add_entry({
'type' => 'Amino acids',
'label' => $obj->thousandify( $obj->Obj->translation->length ),
'priority' => 40
});
}
if( $obj->analysis ) {
$panel->add_entry({
'type' => 'Analysis',
'label' => $obj->analysis->display_label,
'priority' => 2
});
$panel->add_entry({
'label_html' => $obj->analysis->description,
'priority' => 1
});
}
}
return;
}
sub _ajax_zmenu_protein_feature {
my $self = shift;
my $panel = shift;
my $obj = $self->object;
my $id = $obj->param('pf_id');
my $db = $obj->param('db') || 'core';
my $pfa = $obj->database(lc($db))->get_ProteinFeatureAdaptor();
my $pf = $pfa->fetch_by_dbID($id);
my $hit_db = $pf->analysis->db;
my $hit_name = $pf->display_id;
$panel->{'caption'} = "$hit_name ($hit_db)";
$panel->add_entry({
'type' => "View record",
'label' => $hit_name,
'link' => $obj->get_ExtURL($hit_db, $hit_name),
'priority' => 200});
if (my $interpro_ac = $pf->interpro_ac) {
$panel->add_entry({
'type' => 'View InterPro',
'label' => 'InterPro',
'link' => $obj->get_ExtURL('interpro', $interpro_ac),
'priority' => 150});
}
$panel->add_entry({
'type' => 'Description',
'label' => $pf->idesc,
'priority' => 100});
$panel->add_entry({
'type' => 'Position',
'label' => $pf->start.'-'.$pf->end.' aa',
'priority' => 50});
return;
}
sub _ajax_zmenu_change_reference {
my $self = shift;
my $panel = shift;
my $obj = $self->object;
return unless $obj->param('reference');
$panel->add_entry({
'type' => 'Click to compare to ',
'label_html' => $obj->param('reference'),
'link' => $obj->_url({'action' =>'Population/Image', 'reference' => $obj->param('reference') }),
'priority' => 12,
});
return;
}
sub _ajax_zmenu_transcript_variation {
my $self = shift;
my $panel = shift;
my $obj = $self->object;
my $db_adaptor = $obj->database('variation');
my $var_adaptor = $db_adaptor->get_VariationAdaptor();
my $var_feat_adaptor = $db_adaptor->get_VariationFeatureAdaptor();
my $v_id = $obj->param('v');
my $var = $var_adaptor->fetch_by_name($v_id);
my @vf = @{$var_feat_adaptor->fetch_all_by_Variation($var)};
my $feature;
if ( scalar @vf == 1) { $feature = $vf[0];}
else {
foreach (@vf) {
if ($_->dbID eq $obj->param('vf') ) {$feature = $_;}
}
}
my $var_link = my $var_link = $obj->_url({'type' => 'Variation', 'action' => 'Summary', 'v' => $feature->variation_name, 'vf' => $feature->dbID, 'source' => $feature->source });
my $chr_start = $feature->start();
my $chr_end = $feature->end();
my $bp = $chr_start;
if( $chr_end < $chr_start ) {
$bp = "between $chr_end & $chr_start";
} elsif($chr_end > $chr_start ) {
$bp = "$chr_start - $chr_end";
}
my $ref_allele = $feature->ref_allele_string;
$ref_allele = length($ref_allele) <16 ? $ref_allele : substr($ref_allele,0,14).'..';
my $strain = $obj->species_defs->translate("strain");
my $type = $feature->display_consequence;
my $tc;
if ($obj->param('sara')) {$type = 'SARA';}
if ($obj->param('tc') ){
$tc = $obj->param('tc');
if ($tc =~/0|-1/) {$tc=~s/0|-1/-/;}
elsif ($tc =~/1/) {$tc=~s/1/+/;}
}
my $ambig_code = &ambiguity_code(join "|", $ref_allele, $obj->param('alt_allele') ) unless $type eq 'SARA';
my $class = &variation_class(join "|", $ref_allele, $obj->param('alt_allele'));
$panel->{'caption'} = $feature->variation_name;
$panel->add_entry({
'label_html' => 'Variation properties',
'link' => $var_link,
'priority' => 20,
});
$panel->add_entry({
'type' => 'bp:',
'label' => $bp,
'priority' => 18,
});
$panel->add_entry({
'type' => 'class:',
'label' => $class,
'priority' => 16,
});
$panel->add_entry({
'type' => 'reference allele:',
'label' => $ref_allele,
'priority' => 14,
});
$panel->add_entry({
'type' => $strain . ' genotype:',
'label' => $obj->param('alt_allele'),
'priority' => 12,
});
$panel->add_entry({
'type' => 'ambiguity code:',
'label' => $ambig_code,
'priority' => 10,
}) unless $obj->param('sara');
$panel->add_entry({
'label_html' => $tc,
'priority' => 8,
})if $obj->param('tc');
$panel->add_entry({
'type' => 'amino acid:',
'label' => $obj->param('aa_change'),
'priority' => 6,
}) if $obj->param('aa_change');
$panel->add_entry({
'type' => 'resequencing coverage:',
'label' => $obj->param('cov'),
'priority' => 5,
}) if $obj->param('cov');
$panel->add_entry({
'type' => 'source:',
'label' => (join ", ", @{$feature->get_all_sources ||[]}),
'priority' => 4,
});
$panel->add_entry({
'label' => $type,
'priority' => 2,
});
return;
}
sub do_SE_align_menu {
my $self = shift;
my $panel = shift;
my $obj = $self->object;
my $hit_name = $obj->param('id');
my $hit_db = $obj->get_sf_hit_db_name($hit_name);
my $hit_length = $obj->param('hit_length');
my $hit_url = $obj->get_ExtURL_link( $hit_name, $hit_db, $hit_name );
my $tsid = $obj->param('t');
if (my $esid = $obj->param('exon')) {
my $exon_length = $obj->param('exon_length');
#this is drawn for exons
my $align_url = $obj->_url({'type'=>'Transcript', 'action' => 'SupportingEvidence', 'function' => 'Alignment'}).";sequence=$hit_name;exon=$esid";
$panel->{'caption'} = "$hit_name ($hit_db)";
$panel->add_entry({
'type' => 'View alignments',
'label' => "$esid ($tsid)",
'link' => $align_url,
'priority' => 180,
});
$panel->add_entry({
'type' => 'View record',
'label' => $hit_name,
'link' => $hit_url,
'priority' => 100,
'extra' => {'abs_url' => 1},
});
$panel->add_entry({
'type' => 'Exon length',
'label' => $exon_length.' bp',
'priority' => 50,
});
if (my $gap = $obj->param('five_end_mismatch')) {
$panel->add_entry({
'type' => '5\' mismatch',
'label' => $gap.' bp',
'priority' => 40,
});
}
if (my $gap = $obj->param('three_end_mismatch')) {
$panel->add_entry({
'type' => '3\' mismatch',
'label' => $gap.' bp',
'priority' => 35,
});
}
}
else {
$panel->{'caption'} = "$hit_name ($hit_db)";
$panel->add_entry({
'type' => 'View record',
'label' => $hit_name,
'link' => $hit_url,
'priority' => 100,
'extra' => {'abs_url' => 1},
});
}
}
## either - prediction transcript or transcript
## domain - domain only (no transcript)
## history - IDHistory object or transcript
## database:variation - Variation database
sub populate_tree {
my $self = shift;
$self->create_node( 'Summary', "Transcript summary",
[qw(image EnsEMBL::Web::Component::Transcript::TranscriptImage
summary EnsEMBL::Web::Component::Transcript::TranscriptSummary)],
{ 'availability' => 'either', 'concise' => 'Transcript summary'}
);
# $self->create_node( 'Structure', "Transcript Neighbourhood",
# [qw(neighbourhood EnsEMBL::Web::Component::Transcript::TranscriptNeighbourhood)],
# { 'availability' => 1}
# );
my $T = $self->create_node( 'SupportingEvidence', "Supporting evidence ([[counts::evidence]])",
[qw(evidence EnsEMBL::Web::Component::Transcript::SupportingEvidence)],
{ 'availability' => 'transcript', 'concise' => 'Supporting evidence'}
);
$T->append($self->create_subnode( 'SupportingEvidence/Alignment', '',
[qw(alignment EnsEMBL::Web::Component::Transcript::SupportingEvidenceAlignment)],
{ 'no_menu_entry' => 'transcript' }
));
my $seq_menu = $self->create_submenu( 'Sequence', 'Sequence' );
$seq_menu->append($self->create_node( 'Exons', "Exons ([[counts::exons]])",
[qw(exons EnsEMBL::Web::Component::Transcript::ExonsSpreadsheet)],
{ 'availability' => 'either', 'concise' => 'Exons'}
));
$seq_menu->append($self->create_node( 'Sequence_cDNA', 'cDNA',
[qw(sequence EnsEMBL::Web::Component::Transcript::TranscriptSeq)],
{ 'availability' => 'either', 'concise' => 'cDNA sequence' }
));
$seq_menu->append($self->create_node( 'Sequence_Protein', 'Protein',
[qw(sequence EnsEMBL::Web::Component::Transcript::ProteinSeq)],
{ 'availability' => 'either', 'concise' => 'Protein sequence' }
));
my $record_menu = $self->create_submenu( 'ExternalRecords', 'External References' );
my $sim_node = $self->create_node( 'Similarity', "General identifiers ([[counts::similarity_matches]])",
[qw(similarity EnsEMBL::Web::Component::Transcript::SimilarityMatches)],
{ 'availability' => 'transcript', 'concise' => 'General identifiers'}
);
$record_menu->append( $sim_node );
$sim_node->append($self->create_subnode( 'Similarity/Align', '',
[qw(alignment EnsEMBL::Web::Component::Transcript::ExternalRecordAlignment)],
{ 'no_menu_entry' => 'transcript' }
));
$record_menu->append($self->create_node( 'Oligos', "Oligo probes ([[counts::oligos]])",
[qw(arrays EnsEMBL::Web::Component::Transcript::OligoArrays)],
{ 'availability' => 'transcript core', 'concise' => 'Oligo probes'}
));
$record_menu->append($self->create_node( 'GO', "Gene ontology ([[counts::go]])",
[qw(go EnsEMBL::Web::Component::Transcript::Go)],
{ 'availability' => 'transcript', 'concise' => 'Gene ontology'}
));
my $var_menu = $self->create_submenu( 'Variation', 'Genetic Variation' );
$var_menu->append($self->create_node( 'Population', 'Population comparison',
[qw(snptable EnsEMBL::Web::Component::Transcript::TranscriptSNPTable
snpinfo EnsEMBL::Web::Component::Transcript::TranscriptSNPInfo)],
{ 'availability' => 'strains database:variation' }
));
$var_menu->append($self->create_node( 'Population/Image', 'Comparison image',
[qw(snps EnsEMBL::Web::Component::Transcript::SNPView)],
{ 'availability' => 'strains database:variation' }
));
my $prot_menu = $self->create_submenu( 'Protein', 'Protein Information' );
$prot_menu->append($self->create_node( 'ProteinSummary', "Protein summary",
[qw(image EnsEMBL::Web::Component::Transcript::TranslationImage
statistics EnsEMBL::Web::Component::Transcript::PepStats)],
{ 'availability' => 'either', 'concise' => 'Protein summary'}
));
my $D = $self->create_node( 'Domains', "Domains & features ([[counts::prot_domains]])",
[qw(domains EnsEMBL::Web::Component::Transcript::DomainSpreadsheet)],
{ 'availability' => 'transcript', 'concise' => 'Domains & features'}
);
$D->append($self->create_subnode( 'Domains/Genes', 'Genes in domain',
[qw(domaingenes EnsEMBL::Web::Component::Transcript::DomainGenes)],
{ 'availability' => 'transcript|domain', 'no_menu_entry' => 1 }
));
$prot_menu->append($D);
$prot_menu->append($self->create_node( 'ProtVariations', "Variations ([[counts::prot_variations]])",
[qw(protvars EnsEMBL::Web::Component::Transcript::ProteinVariations)],
{ 'availability' => 'either database:variation', 'concise' => 'Variations'}
));
# External Data tree, including non-positional DAS sources
$self->create_node( 'ExternalData', 'External Data',
[qw(external EnsEMBL::Web::Component::Transcript::ExternalData)],
{ 'availability' => 'transcript' }
);
my $history_menu = $self->create_submenu('History', "ID History");
$history_menu->append($self->create_node( 'Idhistory', "Transcript history",
[qw(
display EnsEMBL::Web::Component::Gene::HistoryReport
associated EnsEMBL::Web::Component::Gene::HistoryLinked
map EnsEMBL::Web::Component::Gene::HistoryMap)],
{ 'availability' => 'history', 'concise' => 'ID History' }
));
$history_menu->append($self->create_node( 'Idhistory/Protein', "Protein history",
[qw(
display EnsEMBL::Web::Component::Gene::HistoryReport/protein
associated EnsEMBL::Web::Component::Gene::HistoryLinked/protein
map EnsEMBL::Web::Component::Gene::HistoryMap/protein)],
{ 'availability' => 'history_protein', 'concise' => 'ID History' }
));
$self->create_subnode(
'Export', "Export transcript data",
[ qw( export EnsEMBL::Web::Component::Transcript/export ) ],
{ 'availability' => 'transcript', 'no_menu_entry' => 1 }
);
my $user_menu = $self->create_submenu( 'User', 'User data' );
$user_menu->append( $self->create_node( 'UserAnnotation', "Personal annotation",
[qw(manual_annotation EnsEMBL::Web::Component::Transcript::UserAnnotation)],
{ 'availability' => 1 }
));
}
sub user_populate_tree {
my $self = shift;
return unless $self->object && ref($self->object);
my $all_das = $ENSEMBL_WEB_REGISTRY->get_all_das();
my $vc = $self->object->get_viewconfig( undef, 'ExternalData' );
my @active_das = grep { $vc->get($_) eq 'yes' && $all_das->{$_} } $vc->options;
my $ext_node = $self->tree->get_node( 'ExternalData' );
for my $logic_name (
sort { lc($all_das->{$a}->caption) cmp lc($all_das->{$b}->caption) }
@active_das
) {
my $source = $all_das->{$logic_name};
$ext_node->append($self->create_subnode( "ExternalData/$logic_name", $source->caption,
[qw(textdas EnsEMBL::Web::Component::Transcript::TextDAS)],
{ 'availability' => 'transcript',
'concise' => $source->caption,
'caption' => $source->caption,
'full_caption' => $source->label }
));
}
}
# Transcript: BRCA2_HUMAN
# # Summary
# # Exons (28)
# # Peptide product
# # Similarity matches (32)
# # Oligos (25)
# # GO terms (5)
# # Supporting Evidence (40)
# # Variational genomics (123)
# # Population comparison
# # Marked-up sequence
# # cDNA (1,853 bps)
# # Protein (589 aas)
# # ID History
# # Domain information (6)
# # Protein families (1)
1;