package EnsEMBL::Web::Object::Chromosome;
use strict;
use warnings;
no warnings "uninitialized";
use EnsEMBL::Web::Object;
use EnsEMBL::Web::Proxy::Object;
our @ISA = qw(EnsEMBL::Web::Object);
use Bio::EnsEMBL::DrawableContainer;
use Bio::EnsEMBL::VDrawableContainer;
use EnsEMBL::Web::TmpFile::Text;
use EnsEMBL::Web::Text::DensityFeatureParser;
use Digest::MD5 ;
#----------------------------------------------------------------------------
# GET FUNCTIONS FOR CHROMOSOME DATA
#----------------------------------------------------------------------------
=head2 is_golden_path
Example :
Description : Gets assembly status, i.e. complete chromosomes or not
Return type : Boolean
=cut
sub is_golden_path {
my $self = shift;
@{ $self->species_defs->ENSEMBL_CHROMOSOMES || [] } ? 1 : 0;
}
#----------------------
=head2 max_chr_length
Example :
Description : Gets length of longest chromosome in this species
Return type : Integer
=cut
sub max_chr_length {
my $self = shift;
return $self->species_defs->MAX_CHR_LENGTH;
}
#----------------------
=head2 length
Example :
Description : Gets length of a given chromosome
Return type : Integer
=cut
sub length {
my $self = shift;
return $self->Obj->length;
}
#----------------------
=head2 chr_name
Example :
Description :
Return type : String
=cut
sub chr_name {
my $self = shift;
return $self->Obj ? $self->Obj->seq_region_name : 'ALL';
}
sub seq_region_name { return $_[0]->Obj ? $_[0]->Obj->seq_region_name : 'ALL'; }
sub seq_region_type { return $_[0]->Obj ? $_[0]->Obj->coord_system->name : ''; }
#----------------------
=head2 all_chromosomes
Example :
Description : Gets the names of all chromosomes for this species
Return type : Array
=cut
sub all_chromosomes{
my $self = shift ;
return $self->species_defs->ENSEMBL_CHROMOSOMES;
}
#----------------------------------------------------------------------------
# WRAPPER FUNCTIONS FOR DATA RETRIEVAL
#----------------------------------------------------------------------------
=head2 get_adaptor
Arg[1] : String $method - name of the adaptor get method
Example : my $sa = $self->get_adaptor('get_SliceAdaptor');
Description : Wrapper to get an adaptor object and throw a fatal error
if the database connection fails
Return type : Adaptor object of type requested
=cut
sub get_adaptor {
my ($self, $method, $db, $species) = @_;
$db = 'core' if !$db;
$species = $self->species if !$species;
my $adaptor;
eval { $adaptor = $self->database($db, $species)->$method(); };
if( $@ ) {
warn ($@);
$self->problem('fatal', "Sorry, can't retrieve required information.",$@);
}
return $adaptor;
}
#----------------------
sub get_synteny_local_genes {
my $self = shift ;
return @{$self->{'_local_genes'}} if $self->{'_local_genes'};
my $slice;
my @localgenes;
my $pre = $self->param('pre');
my $loc = $self->param('loc') ? $self->evaluate_bp($self->param('loc')) : undef ;
my $chr = $self->chr_name;
my $chr_length = $self->length;
my $sliceAdaptor = $self->get_adaptor('get_SliceAdaptor');
my $num = 15; # minus count means count backwards - get previous genes
$num = -$num if $pre;
my $start = $loc < 1 ? 1 : $loc;
$start = $chr_length if $start > $chr_length;
if( $num < 0 ) {
$slice = $sliceAdaptor->fetch_by_region('chromosome', $chr, 1, $start );
@localgenes = _local_genes($slice);
if(@localgenes>-$num) {
@localgenes = @localgenes[$num..-1];
$start = 1;
} elsif(@localgenes==0) {
$slice = $sliceAdaptor->fetch_by_region
('chromosome',$chr, $start ,$chr_length);
@localgenes = _local_genes($slice);
@localgenes = @localgenes[0..(-$num-1)] if(@localgenes>-$num);
} else {
$start = 1;
}
}
else {
$slice = $sliceAdaptor->fetch_by_region( 'chromosome', $chr, $start, $chr_length );
@localgenes = _local_genes($slice);
if(@localgenes>$num) {
@localgenes = @localgenes[0..($num-1)];
}
elsif(@localgenes==0) {
$slice = $sliceAdaptor->fetch_by_region('chromosome', $chr, 1 , $start);
@localgenes = _local_genes($slice);
@localgenes = @localgenes[(-$num)..-1] if(@localgenes>$num);
$start = 1;
}
}
# foreach my $gene( @localgenes ){
# $gene->start( $gene->start + $start - 1 );
# $gene->end( $gene->end + $start - 1 );
# }
$self->{'_local_genes'} = [\@localgenes,$start-1];
return \@localgenes, $start - 1;
}
sub _local_genes {
## Ensures that only protein coding genes are included in syntenyview
my $slice = shift;
my @local_genes;
my @biotypes = ('protein_coding', 'V_segments', 'C_segments');
foreach my $type (@biotypes) {
push @local_genes, @{$slice->get_all_Genes_by_type($type)};
}
return @local_genes;
}
sub get_synteny_matches {
my $self = shift;
my @data;
my $OTHER = $self->param('otherspecies') ||$self->param('species')|| ($ENV{ 'ENSEMBL_SPECIES' } eq 'Homo_sapiens' ? 'Mus_musculus' : 'Homo_sapiens');
my $gene2_adaptor = $self->database('core', $OTHER)->get_GeneAdaptor();
my ($localgenes,$offset ) = $self->get_synteny_local_genes;
foreach my $localgene (@$localgenes){
my ($sppgene, $separate, $syntenygene);
my $data;
my $spp = $ENV{ 'ENSEMBL_SPECIES'};
my $homol_id = "";
my $homologues = $self->fetch_homologues_of_gene_in_species($localgene->stable_id, $OTHER);
my $homol_num = scalar @{$homologues};
my $gene_synonym = $localgene->external_name || $localgene->stable_id;
#warn $localgene->stable_id;
if(@{$homologues}) {
foreach my $homol(@{$homologues}){
#warn ".... ", $homol->stable_id;
my $gene = $gene2_adaptor->fetch_by_stable_id( $homol->stable_id,1 );
$homol_id = $gene->external_name;
$homol_id ||= $gene->stable_id;
my $gene_slice = $gene->slice;
my $H_START = $gene->start;
my $H_CHR;
if( $gene_slice->coord_system->name eq "chromosome" ) {
$H_CHR = $gene_slice->seq_region_name;
}
else {
my $coords =$gene_slice->project("chromosome");
if( @$coords ) {
$H_CHR = $coords->[0]->[2]->seq_region_name();
}
}
my $data_row = {
'sp_stable_id' => $localgene->stable_id,
'sp_synonym' => $gene_synonym,
'sp_length' => $self->bp_to_nearest_unit($localgene->start()+$offset),
'other_stable_id' => $homol->stable_id,
'other_synonym' => $homol_id,
'other_chr' => $H_CHR,
'other_length' => $self->bp_to_nearest_unit($H_START),
'homologue_no' => $homol_num
};
push @data, $data_row;
}
} else {
push @data, { 'sp_stable_id' => $localgene->stable_id,
'sp_synonym' => $gene_synonym,
'sp_length' => $self->bp_to_nearest_unit($localgene->start()+$offset) }
}
}
return \@data;
}
sub get_synteny_nav {
my $object = shift;
my @data;
my ($localgenes,$offset) = $object->get_synteny_local_genes;
my $first_start = @$localgenes ? $localgenes->[0]->start +$offset: 0;
my $last_end = @$localgenes ? $localgenes->[-1]->end +$offset: 0;
my $up_length = $object->bp_to_nearest_unit($first_start);
my $down_length = $object->bp_to_nearest_unit($last_end);
push (@data, $first_start, $last_end, $up_length, $down_length);
return \@data;
}
#----------------------
=head2 parse_user_data
Arg[1] : $parser - a EnsEMBL::Web::Text parser object
Example :
Description : Parses user input and stores each feature as an object
Return type : None
=cut
sub parse_user_data {
my ($self, $parser, $track_id) = @_;
my $data;
if (my $data_file = $self->param("cache_file_$track_id")) {
my $file = new EnsEMBL::Web::TmpFile::Text(
filename => $data_file,
);
$data = $cache->retrieve;
$parser->parse($data);
} elsif ($data = $self->param("url_file_$track_id")) {
$parser->parse_URL($data);
}
else {
$parser->parse($self->param("paste_file_$track_id"));
}
}
=head2 find_available_anchor_points
Arg[1] : EnsEMBL::Web::Object::Chromosome
Example : my @types = @{$object->find_available_anchor_points};
Description : Looks in species_defs for available anchor points, ie non-emprty tables
Return type : Arrayref
=cut
sub find_available_anchor_points {
my $self=shift;
my $species = $self->species;
my $species_defs = $self->species_defs;
#define possible anchor here - where 'table' value is undef then option added by default
my $all_anchor_points = [
{'table'=>'' , 'value'=>'bp', 'name'=>'Base pair'},
{'table'=>'karyotype', 'value'=>'band', 'name'=>'Band'},
{'table'=>'marker_feature', 'value'=>'marker', 'name'=>'Marker'},
{'table'=>'misc_feature', 'value'=>'misc_feature', 'name'=>'Clone'},
{'table'=>'gene' , 'value'=>'gene', 'name'=>'Gene'},
{'table'=>'translation' , 'value'=>'peptide','name'=>'Peptide'},
];
my $avail_anchor_points = [];
foreach my $poss_anchor (@$all_anchor_points) {
if ($poss_anchor->{'table'}) {
if ($species_defs->get_table_size( {-db=>'DATABASE_CORE',-table => $poss_anchor->{'table'}},$species )) {
push @$avail_anchor_points, {'value'=>$poss_anchor->{'value'}, 'name'=>$poss_anchor->{'name'} };
}
}
else {
push @$avail_anchor_points, {'value'=>$poss_anchor->{'value'}, 'name'=>$poss_anchor->{'name'} };
}
}
return $avail_anchor_points;
}
1;