1
package Bio::Graphics::Glyph::translation;
4
use Bio::Graphics::Util qw(frame_and_offset);
5
use base qw(Bio::Graphics::Glyph::generic);
7
my %default_colors = qw(
16
# turn off description
24
return $self->factory->translate_color($default_colors{$key});
29
my $font = $self->font;
30
my $lines = $self->translation_type eq '3frame' ? 3
31
: $self->translation_type eq '6frame' ? 6
33
return $self->protein_fits ? $lines*$font->height
34
: $self->SUPER::height;
42
sub pixels_per_residue {
44
return $self->scale * 3;
49
my $color = $self->option('gridcolor') || 'lightgrey';
50
$self->factory->translate_color($color);
55
my $show_sequence = $self->option('show_sequence');
56
return 1 unless defined $show_sequence; # default to true
57
return $show_sequence;
62
my $triletter_code = $self->option("triletter_code");
63
return 0 unless defined $triletter_code; # default to false
64
return $triletter_code;
67
sub longprotein_fits {
69
return unless $self->show_sequence;
71
my $pixels_per_residue = $self->pixels_per_residue;
72
my $font = $self->font;
73
my $font_width = $font->width * 4; # not 3; leave room for whitespace
75
return $pixels_per_residue >= $font_width;
78
sub translation_type {
80
return $self->option('translation') || '1frame';
85
$self->option('arrow_height') || 1;
88
sub show_stop_codons {
90
my $show = $self->option('stop_codons');
91
return $show if defined $show;
95
sub show_start_codons {
97
my $show = $self->option('start_codons');
98
return $show if defined $show;
104
return $self->option('strand') || '+1';
110
my ($x1,$y1,$x2,$y2) = $self->bounds(@_);
112
my $type = $self->translation_type;
113
my $strand = $self->strand;
115
my @strands = $type eq '6frame' ? (1,-1)
119
for my $s (@strands) {
120
for (my $i=0; $i < @phase; $i++) {
121
$self->draw_frame($self->feature,$s,$i,$phase[$i],$gd,$x1,$y1,$x2,$y2);
129
my ($feature,$strand,$base_offset,$phase,$gd,$x1,$y1,$x2,$y2) = @_;
131
$seq = $feature->seq or return; # no sequence, arggh.
133
my $strand0 = $strand;
134
$strand *= -1 if $self->{flip};
136
$pos = $strand < 0 ? $feature->end : $feature->start;
138
my ($frame,$offset) = frame_and_offset($pos,$strand,$phase);
139
# warn "frame=$frame, phase=$phase";
141
my ($x1_orig,$x2_orig) = ($x1,$x2); # remember this for arrowheads
143
($strand >= 0 ? $x1 : $x2) += $self->pixels_per_base * $offset;
146
if ($self->translation_type eq '6frame') {
147
$lh = $self->height / 6;
149
$y1 += $self->height/2 if $strand < 0;
151
$lh = $self->height / 3;
155
$y1 = $y0 + ($self->height - ($y1-$y0)) - $lh if $self->{flip};
159
my $codon_table = $self->option('codontable') || $self->option('geneticcode') || 1;
161
# the dreaded difference between a Bio::SeqFeature and a Bio::Seq
163
my $realseq = $self->get_seq($seq);
164
return unless $realseq;
165
$realseq = $realseq->revcom if $strand < 0;
167
my $protein = $realseq->translate(undef,undef,$base_offset,$codon_table)->seq;
169
my $k = $strand >= 0 ? 'f' : 'r';
171
my $color = $self->color("frame$frame$k") ||
172
$self->color("frame$frame") ||
173
$self->default_color("frame$frame$k") || $self->fgcolor;
176
if ($self->protein_fits) {
177
$self->draw_protein(\$protein,$strand,$color,$gd,$x1,$y1,$x2,$y2);
178
$awo += $self->font->height/2;
180
$self->draw_orfs(\$protein,$strand,$color,$gd,$x1,$y1,$x2,$y2);
183
$strand0 > 0 ? $self->arrowhead($gd,$x2_orig+5,$y1+$awo,3,+1)
184
: $self->arrowhead($gd,$x1_orig-5,$y1+$awo,3,-1)
190
my ($protein,$strand,$color,$gd,$x1,$y1,$x2,$y2) = @_;
191
my $pixels_per_base = $self->pixels_per_base;
192
my $font = $self->font;
193
my $flip = $self->{flip};
194
my $left = $self->panel->left;
195
my $right = $self->panel->right;
197
my $longprotein = $self->triletter_code && $self->longprotein_fits;
199
my %abbrev = ( A => "Ala", B => "Asx", C => "Cys", D => "Asp",
200
E => "Glu", F => "Phe", G => "Gly", H => "His",
201
I => "Ile", J => "???", K => "Lys", L => "Leu",
202
M => "Met", N => "Asn", O => "???", P => "Pro",
203
Q => "Gln", R => "Arg", S => "Ser", T => "Thr",
204
U => "Sec", V => "Val", W => "Trp", X => "Xaa",
205
Y => "Tyr", Z => "Glx", '*' => " * ",
208
my @residues = split '',$$protein;
209
my $fontwidth = $font->width;
210
for (my $i=0;$i<@residues;$i++) {
212
? $x1 + 3 * $i * $pixels_per_base
213
: $x2 - 3 * $i * $pixels_per_base - $pixels_per_base;
217
$x -= $pixels_per_base - $font->width - 1; #align right, not left
219
$gd->string($font,$right-($x-$left+$pixels_per_base)+1,$y1,$abbrev{$residues[$i]},$color);
221
$gd->char($font,$right-($x-$left+$pixels_per_base)+2,$y1,$residues[$i],$color);
225
$gd->string($font, $x+1, $y1, $abbrev{$residues[$i]}, $color);
227
$gd->char($font,$x+2,$y1,$residues[$i],$color);
235
my ($protein,$strand,$color,$gd,$x1,$y1,$x2,$y2) = @_;
236
my $pixels_per_base = $self->pixels_per_base * 3;
238
my $right = $self->panel->right;
239
my $left = $self->panel->left;
240
my $flip = $self->{flip};
242
my $gcolor = $self->gridcolor;
243
$gd->line($x1,$y1,$x2,$y1,$gcolor);
245
if ($self->show_stop_codons) {
246
my $stops = $self->find_codons($protein,'*');
248
for my $stop (@$stops) {
249
my $pos = $strand > 0
250
? $x1 + $stop * $pixels_per_base
251
: $x2 - $stop * $pixels_per_base;
252
next if $pos+1 < $x1;
255
$gd->line($right-($pos-$left),$y1-2,$right-($pos-$left),$y1+2,$color);
257
$gd->line($pos,$y1-2,$pos,$y1+2,$color);
262
my $arrowhead_height = $self->arrow_height;
264
if ($self->show_start_codons) {
265
my $starts = $self->find_codons($protein,'M');
267
for my $start (@$starts) {
268
my $pos = $strand > 0
269
? $x1 + $start * $pixels_per_base
270
: $x2 - $start * $pixels_per_base;
271
next if $pos+1 < $x1;
273
$pos = $self->{flip} ? $right - $pos : $pos;
275
# little arrowheads at the start codons
276
$strand > 0 ? $self->arrowhead($gd,$pos-$arrowhead_height,$y1,
277
$arrowhead_height,+1)
278
: $self->arrowhead($gd,$pos+$arrowhead_height,$y1,
279
$arrowhead_height,-1)
282
$strand *= -1 if $flip;
289
my $codon = shift || '*';
292
while ( ($pos = index($$protein,$codon,$pos+1)) >= 0) {
298
sub make_key_feature {
300
my @gatc = qw(g a t c);
301
my $offset = $self->panel->offset;
302
my $scale = 1/$self->scale; # base pairs/pixel
304
my $stop = $offset + 100 * $scale;
305
my $seq = join('',map{$gatc[rand 4]} (1..500));
307
Bio::Graphics::Feature->new(-start=> $start,
310
-name => $self->option('key')
321
Bio::Graphics::Glyph::translation - The "6-frame translation" glyph
325
See L<Bio::Graphics::Panel> and L<Bio::Graphics::Glyph>.
329
This glyph draws the conceptual translation of DNA sequences. At high
330
magnifications, it simply draws lines indicating open reading frames.
331
At low magnifications, it draws a conceptual protein translation.
332
Options can be used to set 1-frame, 3-frame or 6-frame translations.
336
The following options are standard among all Glyphs. See
337
L<Bio::Graphics::Glyph> for a full explanation.
339
Option Description Default
340
------ ----------- -------
342
-fgcolor Foreground color black
344
-outlinecolor Synonym for -fgcolor
346
-bgcolor Background color turquoise
348
-fillcolor Synonym for -bgcolor
350
-linewidth Line width 1
352
-height Height of glyph 10
354
-font Glyph font gdSmallFont
356
-connector Connector type 0 (false)
359
Connector color black
361
-label Whether to draw a label 0 (false)
363
-description Whether to draw a description 0 (false)
365
-hilite Highlight color undef (no color)
367
In addition to the common options, the following glyph-specific
368
options are recognized:
370
Option Description Default
371
------ ----------- -------
373
-translation Type of translation to 1frame
374
perform. One of "1frame",
375
"3frame", or "6frame"
377
-strand Forward (+1) or reverse (-1) +1
380
-frame0 Color for the first frame fgcolor
382
-frame1 Color for the second frame fgcolor
384
-frame2 Color for the third frame fgcolor
386
-gridcolor Color for the horizontal lightgrey
387
lines of the reading frames
389
-start_codons Draw little arrowheads 0 (false)
390
indicating start codons
392
-stop_codons Draw little vertical ticks 1 (true)
393
indicating stop codons
395
-arrow_height Height of the start codon 1
398
-show_sequence Show the amino acid sequence 1 (true)
401
-triletter_code Show the 3-letter amino acid 0 (false)
404
-codontable Codon table to use 1 (see Bio::Tools::CodonTable)
406
=head1 SUGGESTED STANZA FOR GENOME BROWSER
408
This produces a nice gbrowse display in which the DNA/GC Content glyph
409
is sandwiched between the forward and reverse three-frame
410
translations. The frames are color-coordinated with the example
411
configuration for the "cds" glyph.
423
key = 3-frame translation (forward)
443
key = 3-frame translation (reverse)
452
L<Bio::Graphics::Panel>,
453
L<Bio::Graphics::Glyph>,
454
L<Bio::Graphics::Glyph::arrow>,
455
L<Bio::Graphics::Glyph::cds>,
456
L<Bio::Graphics::Glyph::crossbox>,
457
L<Bio::Graphics::Glyph::diamond>,
458
L<Bio::Graphics::Glyph::dna>,
459
L<Bio::Graphics::Glyph::dot>,
460
L<Bio::Graphics::Glyph::ellipse>,
461
L<Bio::Graphics::Glyph::extending_arrow>,
462
L<Bio::Graphics::Glyph::generic>,
463
L<Bio::Graphics::Glyph::graded_segments>,
464
L<Bio::Graphics::Glyph::heterogeneous_segments>,
465
L<Bio::Graphics::Glyph::line>,
466
L<Bio::Graphics::Glyph::pinsertion>,
467
L<Bio::Graphics::Glyph::primers>,
468
L<Bio::Graphics::Glyph::rndrect>,
469
L<Bio::Graphics::Glyph::segments>,
470
L<Bio::Graphics::Glyph::ruler_arrow>,
471
L<Bio::Graphics::Glyph::toomany>,
472
L<Bio::Graphics::Glyph::transcript>,
473
L<Bio::Graphics::Glyph::transcript2>,
474
L<Bio::Graphics::Glyph::translation>,
475
L<Bio::Graphics::Glyph::triangle>,
484
Lincoln Stein E<lt>lstein@cshl.orgE<gt>.
486
Copyright (c) 2001 Cold Spring Harbor Laboratory
488
This library is free software; you can redistribute it and/or modify
489
it under the same terms as Perl itself. See DISCLAIMER.txt for
490
disclaimers of warranty.