package Bio::EnsEMBL::GlyphSet::_alignment_pairwise;
use strict;
use base qw(Bio::EnsEMBL::GlyphSet);
sub colour { return $_[0]->{'feature_colour'}, $_[0]->{'label_colour'}, $_[0]->{'part_to_colour'}; }
sub render_normal {
my $self = shift;
return $self->render_text if $self->{'text_export'};
my $WIDTH = 1e5;
my $container = $self->{'container'};
my $strand = $self->strand();
my $strand_flag = $self->my_config('strand');
return if $strand_flag eq 'r' && $strand != -1;
return if $strand_flag eq 'f' && $strand != 1;
my $caption = $self->my_config('caption');
my $depth = $self->my_config('depth') || 6;
$self->_init_bump( undef, $depth ); ## initialize bumping!!
my %highlights; @highlights{$self->highlights()} = ();
my $length = $container->length;
my $pix_per_bp = $self->scalex;
my $DRAW_CIGAR = $pix_per_bp > 0.2 ;
my $feature_key = lc( $self->my_config('type') );
my $feature_colour = $self->my_colour($feature_key);
my $join_col = $self->my_colour($feature_key,'join' ) || 'gold';
my $join_z = $self->my_colour($feature_key,'join_z') || 100;
# warn "... $feature_key [$feature_colour / $join_col / $join_z] ....";
my %id = ();
my $small_contig = 0;
my $h = $self->get_parameter( 'opt_halfheight') ? 4 : 8;
my $chr = $self->{'container'}->seq_region_name;
my $other_species = $self->my_config('species' );
my $species_2 = $self->my_config('species_hr');
my $self_species = $container->{web_species};
my $compara = $self->get_parameter('compara');
my $link = 0;
my $TAG_PREFIX;
my $METHOD = $self->my_config('method' );
# warn "expanded method is $METHOD";
if( $compara) {
$link = $self->my_config('join');
$TAG_PREFIX = uc( $compara eq 'primary' ?
join ( '_', $METHOD, $self_species, $other_species ) :
join ( '_', $METHOD, $other_species, $self_species ) );
}
my $C = 0; ## Diagnostic counters....
my $K = 0;
# warn ">>>>> $other_species $METHOD in expanded init<<<<<";
foreach my $f ( @{$self->features||[]} ){
next if $strand_flag eq 'b' && $strand != $f->hstrand || $f->end < 1 || $f->start > $length ;
push @{$id{$f->hseqname().':'. ($f->group_id||("00".$K++)) }}, [$f->start,$f];
}
## Now go through each feature in turn, drawing them
my @glyphs;
my $BLOCK = 0;
my $script = $ENV{'ENSEMBL_SCRIPT'} eq 'multicontigview' ? 'contigview' : $ENV{'ENSEMBL_SCRIPT'};
my $SHORT = $self->species_defs->ENSEMBL_SHORTEST_ALIAS->{ $self->my_config( 'species' ) };
my $domain = $self->my_config( 'linkto' );
my $HREF = $self->my_config( 'linkto' )."/$SHORT/$script";
# sort alignments by size
my @s_i = sort {($id{$b}[0][1]->hend() - $id{$b}[0][1]->hstart()) <=> ($id{$a}[0][1]->hend() - $id{$a}[0][1]->hstart())} keys %id;
foreach my $i (@s_i){
my @F = sort { $a->[0] <=> $b->[0] } @{$id{$i}};
my( $seqregion,$group ) = split /:/, $i;
my $START = $F[0][0] < 1 ? 1 : $F[0][0];
my $END = $F[-1][1]->end > $length ? $length : $F[-1][1]->end;
my $start = $F[0][1]->hstart();
my $end = $F[0][1]->hend();
my $bump_start = int($START * $pix_per_bp) -1 ;
my $bump_end = int($END * $pix_per_bp);
my $row = $self->bump_row( $bump_start, $bump_end );
next if $row > $depth;
my $y_pos = - $row * int( 1.5 * $h ) * $strand;
my $Composite = $self->Composite({
'x' => $F[0][0]> 1 ? $F[0][0]-1 : 0,
'width' => 0,
'y' => 0
});
my $X = -1000000;
foreach ( @F ){
my $f = $_->[1];
$start = $f->hstart() if $f->hstart < $start;
$end = $f->hend() if $f->hend > $end;
next if int($f->end * $pix_per_bp) <= int( $X * $pix_per_bp );
$C++;
if($DRAW_CIGAR) {
$self->draw_cigar_feature($Composite, $f, $h, $feature_colour, 'black', $pix_per_bp, 1 );
} else {
my $START = $_->[0] < 1 ? 1 : $_->[0];
my $END = $f->end > $length ? $length : $f->end;
$X = $END;
my $BOX = $self->Rect({
'x' => $START-1,
'y' => 0,
'width' => $END-$START+1,
'height' => $h,
'colour' => $feature_colour,
'absolutey' => 1,
});
if( $strand_flag eq 'z' && $join_col) {
$self->join_tag( $BOX, "BLOCK_".$self->_type."$BLOCK", $strand == -1 ? 0 : 1, 0 , $join_col, 'fill', $join_z ) ;
$self->join_tag( $BOX, "BLOCK_".$self->_type."$BLOCK", $strand == -1 ? 1 : 0, 0 , $join_col, 'fill', $join_z ) ;
$BLOCK++;
}
$Composite->push($BOX);
}
}
if( ($compara eq 'primary' || $compara eq 'secondary') && $link ) {
my $Z = $strand == -1 ? 1 : 0;
foreach( @F ) {
my $f = $_->[1];
my( $start, $end, $start2,$end2) = ( $f->hstart, $f->hend, $f->start, $f->end );
my( $start3, $end3 ) = $self->slice2sr( $start2, $end2 );
my $S = $start2 < $Composite->x ? 0 : ( $start2 - $Composite->x ) / $Composite->width;
my $E = $end2 > $Composite->x+$Composite->width ? 1 : ( $end2 - $Composite->x ) / $Composite->width;
if( $strand != -1 ) {
my $TAG = $self->{'config'}{'slice_id'}."$TAG_PREFIX.$start.$end:$start3.$end3.$strand";
$self->join_tag( $Composite, $TAG, $S, $Z, $join_col, 'fill', $join_z );
$self->join_tag( $Composite, $TAG, $E, $Z, $join_col, 'fill', $join_z );
} else {
my $TAG = ($self->{'config'}{'slice_id'}+1)."$TAG_PREFIX.$start3.$end3:$start.$end.".(-$strand);
$self->join_tag( $Composite, $TAG, $E, $Z, $join_col, 'fill', $join_z );
$self->join_tag( $Composite, $TAG, $S, $Z, $join_col, 'fill', $join_z );
}
}
}
$Composite->y( $Composite->y + $y_pos );
$Composite->bordercolour($feature_colour);
my $ZZ;
if($end-$start<$WIDTH) {
my $X =int(( $start + $end - $WIDTH) /2);
my $Y = $X + $WIDTH ;
$ZZ = "l=$seqregion:$X-$Y";
} else {
$ZZ = "l=$seqregion:$start-$end";
}
$Composite->href( "$HREF?$ZZ" );
my $orient = ($F[0][1]->hstrand * $F[0][1]->strand > 0) ? 'Forward' : 'Reverse';
my $chr_2 = $F[0][1]->hseqname;
my $zmenu = {
'type' => 'Location',
'action' => 'ComparaGenomicAlignment',
'r1' => "$chr_2:$start-$end",
's1' => $other_species,
'orient' => $orient,
};
if(exists $highlights{$i}) {
$self->unshift($self->Rect({
'x' => $Composite->x() - 1/$pix_per_bp,
'y' => $Composite->y() - 1,
'width' => $Composite->width() + 2/$pix_per_bp,
'height' => $h + 2,
'colour' => 'highlight1',
'absolutey' => 1,
}));
}
#add more detailed links for non chained alignments
if (scalar(@F) == 1) {
my $chr_2 = $F[0][1]->hseqname;
my $s_2 = $F[0][1]->hstart;
my $e_2 = $F[0][1]->hend;
my $CONTIGVIEW_TEXT_LINK = $compara ? 'Jump to ContigView' : 'Centre on this match' ;
my $END = $F[0][1]->end;
my $START =$F[0][0];
($START,$END) = ($END, $START) if $END<$START; # Flip start end YUK!
my( $rs, $re ) = $self->slice2sr( $START, $END );
my $jump_type = $species_2;
my $short_self = $self->species_defs->ENSEMBL_SHORTEST_ALIAS->{ $self_species };
my $short_other = $self->species_defs->ENSEMBL_SHORTEST_ALIAS->{ $other_species };
my $HREF_TEMPLATE = "/$short_self/dotterview?c=$chr:%d;s1=$other_species;c1=%s:%d";
my $COMPARA_HTML_EXTRA = '';
# my $MCV_TEMPLATE = "/$short_self/multicontigview?c=%s:%d;w=%d;s1=$short_other;c1=%s:%d;w1=%d$COMPARA_HTML_EXTRA";
$zmenu->{'method'} = $self->my_config('type');
my $href = sprintf $HREF_TEMPLATE, ($rs+$re)/2, $chr_2, ($s_2 + $e_2)/2;
my $METHOD = $self->my_config('method' );
my $link = 0;
my $TAG_PREFIX;
if( $compara) {
$link = $self->my_config('join');
$TAG_PREFIX = uc( $compara eq 'primary' ?
join ( '_', $METHOD, $self_species, $other_species ) :
join ( '_', $METHOD, $other_species, $self_species ) );
my $C=1;
foreach my $T ( @{$self->{'config'}{'other_slices'}||[]} ) {
if( $T->{'species'} ne $self_species && $T->{'species'} ne $other_species ) {
$C++;
$COMPARA_HTML_EXTRA.=";s$C=".$self->species_defs->ENSEMBL_SHORTEST_ALIAS->{ $T->{'species'} };
}
}
# $MULTICONTIGVIEW_TEXT_LINK = 'Centre on this match';
}
}
$Composite->href($self->_url($zmenu));
$self->push( $Composite );
}
## No features show "empty track line" if option set....
$self->errorTrack( "No ". $self->my_config('name')." features in this region" ) unless( $C || $self->get_parameter( 'opt_empty_tracks')==0 );
$self->timer_push( 'Features drawn' );
}
sub render_compact {
my $self = shift;
return $self->render_text if $self->{'text_export'};
my $WIDTH = 1e5;
my $container = $self->{'container'};
my $strand = $self->strand();
my $strand_flag = $self->my_config('strand');
return if $strand_flag eq 'r' && $strand != -1;
return if $strand_flag eq 'f' && $strand != 1;
my $caption = $self->my_config('caption');
my $depth = $self->my_config('depth');
$self->_init_bump( undef, $depth ); ## initialize bumping!!
my %highlights; @highlights{$self->highlights()} = ();
my $length = $container->length;
my $pix_per_bp = $self->scalex;
my $DRAW_CIGAR = $pix_per_bp > 0.2 ;
my $feature_key = lc( $self->my_config('type') );
# warn ".... $feature_key ....";
my $feature_colour = $self->my_colour($feature_key);
my $join_col = $self->my_colour($feature_key,'join' ) || 'gold';
my $join_z = $self->my_colour($feature_key,'join_z') || 100;
my %id = ();
my $small_contig = 0;
my $h = $self->get_parameter( 'opt_halfheight') ? 4 : 8;
my $chr = $self->{'container'}->seq_region_name;
my $other_species = $self->my_config('species' );
my $species_2 = $self->my_config('species_hr');
my $self_species = $container->{web_species};
my $compara = $self->get_parameter('compara');
my $link = 0;
my $TAG_PREFIX;
my $METHOD = $self->my_config('method' );
my $short_other = $self->species_defs->ENSEMBL_SHORTEST_ALIAS->{ $other_species };
my $short_self = $self->species_defs->ENSEMBL_SHORTEST_ALIAS->{ $self_species };
# warn "compact method is $METHOD";
my $COMPARA_HTML_EXTRA = '';
# my $MULTICONTIGVIEW_TEXT_LINK = 'MultiContigView';
if( $compara ) {
$link = $self->my_config('join');
$TAG_PREFIX = uc( $compara eq 'primary' ?
join ( '_', $METHOD, $self_species, $other_species ) :
join ( '_', $METHOD, $other_species, $self_species ) );
my $C=1;
foreach my $T ( @{$self->{'config'}{'other_slices'}||[]} ) {
if( $T->{'species'} ne $self_species && $T->{'species'} ne $other_species ) {
$C++;
$COMPARA_HTML_EXTRA.=";s$C=".$self->species_defs->ENSEMBL_SHORTEST_ALIAS->{ $T->{'species'} };
}
}
# $MULTICONTIGVIEW_TEXT_LINK = 'Centre on this match';
}
my $C = 0;
my $domain = $self->my_config('linkto' );
my $HREF_TEMPLATE = "/$short_self/dotterview?c=$chr:%d;s1=$other_species;c1=%s:%d";
my $X = -1e8;
my $CONTIGVIEW_TEXT_LINK = $compara ? 'Jump to ContigView' : 'Centre on this match' ;
# my $MCV_TEMPLATE = "/$short_self/multicontigview?c=%s:%d;w=%d;s1=$short_other;c1=%s:%d;w1=%d$COMPARA_HTML_EXTRA";
# warn "!>>>>> $other_species $METHOD in compact init<<<<<";
my @T = sort { $a->[0] <=> $b->[0] }
map { [$_->start, $_ ] }
grep { !( ($strand_flag eq 'b' && $strand != $_->hstrand) ||
($_->start > $length) ||
($_->end < 1)
) } @{$self->features()||[]};
foreach (@T) {
my($START,$f) = @$_;
my $END = $f->end;
($START,$END) = ($END, $START) if $END<$START; # Flip start end YUK!
my( $rs, $re ) = $self->slice2sr( $START, $END );
$START = 1 if $START < 1;
$END = $length if $END > $length;
next if int( $END * $pix_per_bp ) == int( $X * $pix_per_bp );
$X = $START;
$C++;
my @X = (
[ $chr, int(($rs+$re)/2) ],
[ $f->hseqname, int(($f->hstart + $f->hend)/2) ],
int($WIDTH/2),
"@{[$f->hseqname]}:@{[$f->hstart]}-@{[$f->hend]}",
"$chr:$rs-$re"
);
my $TO_PUSH;
my $chr_2 = $f->hseqname;
my $s_2 = $f->hstart;
my $e_2 = $f->hend;
my $href = '';
#z menu links depend on whether jumping within or between species;
my $jump_type = $species_2;
my $orient = ($f->hstrand * $f->strand > 0) ? 'Forward' : 'Reverse';
my $zmenu = {
'type' => 'Location',
'action' => 'ComparaGenomicAlignment',
'r' => "$chr:$rs-$re",
'r1' => "$chr_2:$s_2-$e_2",
's1' => $other_species,
'method' => $self->my_config('type'),
'orient' => $orient,
};
$href = sprintf $HREF_TEMPLATE, ($rs+$re)/2, $chr_2, ($s_2 + $e_2)/2;
if($DRAW_CIGAR) {
$TO_PUSH = $self->Composite({
'href' => $self->_url($zmenu),
'x' => $START-1,
'width' => 0,
'y' => 0
});
$self->draw_cigar_feature($TO_PUSH, $f, $h, $feature_colour, 'black', $pix_per_bp, 1 );
$TO_PUSH->bordercolour($feature_colour);
} else {
$TO_PUSH = $self->Rect({
'x' => $START-1,
'y' => 0,
'width' => $END-$START+1,
'height' => $h,
'colour' => $feature_colour,
'absolutey' => 1,
'_feature' => $f,
'href' => $self->_url($zmenu),
});
}
if( ($compara eq 'primary' || $compara eq 'secondary') && $link ) {
my( $start, $end, $start2,$end2) = ( $f->hstart, $f->hend, $f->start, $f->end );
my( $start2, $end2 ) = $self->slice2sr( $start2, $end2 );
my $Z = $strand == -1 ? 1 : 0;
if( $strand != -1 ) {
my $TAG = $self->{'config'}{'slice_id'}."$TAG_PREFIX.$start.$end:$start2.$end2.$strand";
$self->join_tag( $TO_PUSH, $TAG, 0, $Z, $join_col, 'fill', $join_z );
$self->join_tag( $TO_PUSH, $TAG, 1, $Z, $join_col, 'fill', $join_z );
} else {
my $TAG = ($self->{'config'}{'slice_id'}+1)."$TAG_PREFIX.$start2.$end2:$start.$end.".(-$strand);
$self->join_tag( $TO_PUSH, $TAG, 1, $Z, $join_col, 'fill', $join_z );
$self->join_tag( $TO_PUSH, $TAG, 0, $Z, $join_col, 'fill', $join_z );
}
}
$self->push( $TO_PUSH );
}
## No features show "empty track line" if option set....
$self->errorTrack( "No ". $self->my_config('name')." features in this region" ) unless( $C || $self->get_parameter( 'opt_empty_tracks')==0 );
}
sub features {
my $self = shift;
return $self->{'container'}->get_all_compara_DnaAlignFeatures(
$self->my_config( 'species_hr' ),
$self->my_config( 'assembly' ),
$self->my_config( 'type' ),
$self->dbadaptor( "multi", $self->my_config('db') )
);
}
sub render_text {
my $self = shift;
my $strand = $self->strand;
my $strand_flag = $self->my_config('strand');
return if $strand_flag eq 'r' && $strand != -1;
return if $strand_flag eq 'f' && $strand != 1;
my $length = $self->{'container'}->length;
my $species = $self->my_config('species');
my $type = $self->my_config('type');
my $export;
foreach my $f (@{$self->features||[]}) {
next if $strand_flag eq 'b' && $strand != $f->hstrand || $f->end < 1 || $f->start > $length;
$export .= $self->_render_text($f, $type, {
'headers' => [ $species ],
'values' => [ $f->hseqname . ':' . $f->hstart . '-' . $f->hend ]
}, {
'strand' => '.',
'frame' => '.'
});
}
return $export;
}
1;