Mercurial > repos > mahtabm > ensembl
comparison variant_effect_predictor/Bio/Graphics/Glyph/cds.pm @ 0:1f6dce3d34e0
Uploaded
author | mahtabm |
---|---|
date | Thu, 11 Apr 2013 02:01:53 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1f6dce3d34e0 |
---|---|
1 package Bio::Graphics::Glyph::cds; | |
2 | |
3 use strict; | |
4 use Bio::Graphics::Glyph::segments; | |
5 use Bio::Graphics::Util qw(frame_and_offset); | |
6 use Bio::Tools::CodonTable; | |
7 use Bio::Graphics::Glyph::translation; | |
8 use vars '@ISA'; | |
9 @ISA = qw(Bio::Graphics::Glyph::segmented_keyglyph Bio::Graphics::Glyph::translation); | |
10 | |
11 my %default_colors = qw( | |
12 frame0f cadetblue | |
13 frame1f blue | |
14 frame2f darkblue | |
15 frame0r darkred | |
16 frame1r red | |
17 frame2r crimson | |
18 ); | |
19 | |
20 sub connector { 0 }; | |
21 sub description { | |
22 my $self = shift; | |
23 return if $self->level; | |
24 return $self->SUPER::description; | |
25 }; | |
26 | |
27 sub default_color { | |
28 my ($self,$key) = @_; | |
29 return $self->factory->translate_color($default_colors{$key}); | |
30 } | |
31 | |
32 sub sixframe { | |
33 my $self = shift; | |
34 $self->{sixframe} = $self->option('sixframe') | |
35 unless exists $self->{sixframe}; | |
36 return $self->{sixframe}; | |
37 } | |
38 | |
39 sub require_subparts { | |
40 my $self = shift; | |
41 my $rs = $self->option('require_subparts'); | |
42 $rs = $self->feature->type eq 'coding' if !defined $rs; # shortcut for the "coding" aggregator | |
43 $rs; | |
44 } | |
45 | |
46 # figure out (in advance) the color of each component | |
47 sub draw { | |
48 my $self = shift; | |
49 my ($gd,$left,$top) = @_; | |
50 | |
51 my @parts = $self->parts; | |
52 @parts = $self if !@parts && $self->level == 0 && !$self->require_subparts; | |
53 | |
54 my $fits = $self->protein_fits; | |
55 | |
56 # draw the staff (musically speaking) | |
57 my ($x1,$y1,$x2,$y2) = $self->bounds($left,$top); | |
58 my $line_count = $self->sixframe ? 6 : 3; | |
59 my $height = ($y2-$y1)/$line_count; | |
60 my $grid = $self->gridcolor; | |
61 for (0..$line_count-1) { | |
62 my $offset = $y1+$height*$_+1; | |
63 $gd->line($x1,$offset,$x2,$offset,$grid); | |
64 } | |
65 | |
66 $self->{cds_part2color} ||= {}; | |
67 my $fill = $self->bgcolor; | |
68 my $strand = $self->feature->strand; | |
69 | |
70 # figure out the colors of each part | |
71 # sort minus strand features backward | |
72 @parts = map { $_->[0] } | |
73 sort { $b->[1] <=> $a->[1] } | |
74 map { [$_, $_->left ] } @parts if $strand < 0; | |
75 my $translate_table = Bio::Tools::CodonTable->new; | |
76 | |
77 for (my $i=0; $i < @parts; $i++) { | |
78 my $part = $parts[$i]; | |
79 my $feature = $part->feature; | |
80 my $pos = $strand > 0 ? $feature->start : $feature->end; | |
81 my $phase = eval {$feature->phase} || 0; | |
82 my ($frame,$offset) = frame_and_offset($pos, | |
83 $feature->strand, | |
84 -$phase); | |
85 my $suffix = $strand < 0 ? 'r' : 'f'; | |
86 my $key = "frame$frame$suffix"; | |
87 $self->{cds_frame2color}{$key} ||= $self->color($key) || $self->default_color($key) || $fill; | |
88 $part->{cds_partcolor} = $self->{cds_frame2color}{$key}; | |
89 $part->{cds_frame} = $frame; | |
90 $part->{cds_offset} = $offset; | |
91 | |
92 if ($fits && $part->feature->seq) { | |
93 | |
94 # do in silico splicing in order to find the codon that | |
95 # arises from the splice | |
96 my $protein = $part->feature->translate(undef,undef,$phase)->seq; | |
97 $part->{cds_translation} = $protein; | |
98 | |
99 BLOCK: { | |
100 length $protein >= $feature->length/3 and last BLOCK; | |
101 ($feature->length - $phase) % 3 == 0 and last BLOCK; | |
102 | |
103 my $next_part = $parts[$i+1] | |
104 or do { | |
105 $part->{cds_splice_residue} = '?'; | |
106 last BLOCK; }; | |
107 | |
108 my $next_feature = $next_part->feature or last BLOCK; | |
109 my $next_phase = eval {$next_feature->phase} or last BLOCK; | |
110 my $splice_codon = ''; | |
111 my $left_of_splice = substr($feature->seq,-$next_phase,$next_phase); | |
112 my $right_of_splice = substr($next_feature->seq,0,3-$next_phase); | |
113 $splice_codon = $left_of_splice . $right_of_splice; | |
114 length $splice_codon == 3 or last BLOCK; | |
115 my $amino_acid = $translate_table->translate($splice_codon); | |
116 $part->{cds_splice_residue} = $amino_acid; | |
117 } | |
118 } | |
119 } | |
120 | |
121 $self->Bio::Graphics::Glyph::generic::draw($gd,$left,$top); | |
122 } | |
123 | |
124 | |
125 # draw the notes on the staff | |
126 sub draw_component { | |
127 my $self = shift; | |
128 my $gd = shift; | |
129 my ($x1,$y1,$x2,$y2) = $self->bounds(@_); | |
130 | |
131 my $color = $self->{cds_partcolor} or return; | |
132 my $feature = $self->feature; | |
133 my $frame = $self->{cds_frame}; | |
134 my $linecount = $self->sixframe ? 6 : 3; | |
135 | |
136 unless ($self->protein_fits) { | |
137 my $height = ($y2-$y1)/$linecount; | |
138 my $offset = $y1 + $height*$frame; | |
139 $offset += ($y2-$y1)/2 if $self->sixframe && $self->strand < 0; | |
140 $gd->filledRectangle($x1,$offset,$x2,$offset+2,$color); | |
141 return; | |
142 } | |
143 | |
144 # we get here if there's room to draw the primary sequence | |
145 my $font = $self->font; | |
146 my $pixels_per_residue = $self->pixels_per_residue; | |
147 my $strand = $feature->strand; | |
148 my $y = $y1-1; | |
149 | |
150 $strand *= -1 if $self->{flip}; | |
151 | |
152 # have to remap feature start and end into pixel coords in order to: | |
153 # 1) correctly align the amino acids with the nucleotide seq | |
154 # 2) correct for the phase offset | |
155 my $start = $self->map_no_trunc($feature->start + $self->{cds_offset}); | |
156 my $stop = $self->map_no_trunc($feature->end + $self->{cds_offset}); | |
157 ($start,$stop) = ($stop,$start) if $self->{flip}; | |
158 | |
159 my @residues = split '',$self->{cds_translation}; | |
160 | |
161 push @residues,$self->{cds_splice_residue} if $self->{cds_splice_residue}; | |
162 for (my $i=0;$i<@residues;$i++) { | |
163 my $x = $strand > 0 ? $start + $i * $pixels_per_residue | |
164 : $stop - $i * $pixels_per_residue; | |
165 next unless ($x >= $x1 && $x <= $x2); | |
166 $gd->char($font,$x+1,$y,$residues[$i],$color); | |
167 } | |
168 } | |
169 | |
170 sub make_key_feature { | |
171 my $self = shift; | |
172 my @gatc = qw(g a t c); | |
173 my $offset = $self->panel->offset; | |
174 my $scale = 1/$self->scale; # base pairs/pixel | |
175 my $start = $offset; | |
176 my $stop = $offset + 100 * $scale; | |
177 my $seq = join('',map{$gatc[rand 4]} (1..1500)); | |
178 my $feature = | |
179 Bio::Graphics::Feature->new(-start=> $start, | |
180 -end => $stop, | |
181 -seq => $seq, | |
182 -name => $self->option('key'), | |
183 -strand=> +1, | |
184 ); | |
185 $feature->add_segment(Bio::Graphics::Feature->new( | |
186 -start=> $start, | |
187 -end => $start + ($stop - $start)/2, | |
188 -seq => $seq, | |
189 -name => $self->option('key'), | |
190 -strand=> +1, | |
191 ), | |
192 Bio::Graphics::Feature->new( | |
193 -start=> $start + ($stop - $start)/2+1, | |
194 -end => $stop, | |
195 -seq => $seq, | |
196 -name => $self->option('key'), | |
197 -phase=> 1, | |
198 -strand=> +1, | |
199 )); | |
200 $feature; | |
201 } | |
202 | |
203 # never allow our components to bump | |
204 sub bump { | |
205 my $self = shift; | |
206 return $self->SUPER::bump(@_) if $self->all_callbacks; | |
207 return 0; | |
208 } | |
209 | |
210 1; | |
211 | |
212 __END__ | |
213 | |
214 =head1 NAME | |
215 | |
216 Bio::Graphics::Glyph::cds - The "cds" glyph | |
217 | |
218 =head1 SYNOPSIS | |
219 | |
220 See L<Bio::Graphics::Panel> and L<Bio::Graphics::Glyph>. | |
221 | |
222 =head1 DESCRIPTION | |
223 | |
224 This glyph draws features that are associated with a protein coding | |
225 region. At high magnifications, draws a series of boxes that are | |
226 color-coded to indicate the frame in which the translation occurs. At | |
227 low magnifications, draws the amino acid sequence of the resulting | |
228 protein. Amino acids that are created by a splice are optionally | |
229 shown in a distinctive color. | |
230 | |
231 =head2 OPTIONS | |
232 | |
233 The following options are standard among all Glyphs. See | |
234 L<Bio::Graphics::Glyph> for a full explanation. | |
235 | |
236 Option Description Default | |
237 ------ ----------- ------- | |
238 | |
239 -fgcolor Foreground color black | |
240 | |
241 -outlinecolor Synonym for -fgcolor | |
242 | |
243 -bgcolor Background color turquoise | |
244 | |
245 -fillcolor Synonym for -bgcolor | |
246 | |
247 -linewidth Line width 1 | |
248 | |
249 -height Height of glyph 10 | |
250 | |
251 -font Glyph font gdSmallFont | |
252 | |
253 -connector Connector type 0 (false) | |
254 | |
255 -connector_color | |
256 Connector color black | |
257 | |
258 -label Whether to draw a label 0 (false) | |
259 | |
260 -description Whether to draw a description 0 (false) | |
261 | |
262 -strand_arrow Whether to indicate 0 (false) | |
263 strandedness | |
264 | |
265 In addition, the alignment glyph recognizes the following | |
266 glyph-specific options: | |
267 | |
268 Option Description Default | |
269 ------ ----------- ------- | |
270 | |
271 -frame0f Color for first (+) frame background color | |
272 | |
273 -frame1f Color for second (+) frame background color | |
274 | |
275 -frame2f Color for third (+) frame background color | |
276 | |
277 -frame0r Color for first (-) frame background color | |
278 | |
279 -frame1r Color for second (-) frame background color | |
280 | |
281 -frame2r Color for third (-) frame background color | |
282 | |
283 -gridcolor Color for the "staff" lightslategray | |
284 | |
285 -sixframe Draw a six-frame staff 0 (false; usually draws 3 frame) | |
286 | |
287 -require_subparts | |
288 Don't draw the reading frame 0 (false) | |
289 unless it is a feature | |
290 subpart. | |
291 | |
292 The -require_subparts option is suggested when rendering spliced | |
293 transcripts which contain multiple CDS subparts. Otherwise, the glyph | |
294 will hickup when zoomed way down onto an intron between two CDSs (a | |
295 phantom reading frame will appear). For unspliced sequences, do *not* | |
296 use -require_subparts. | |
297 | |
298 =head1 SUGGESTED STANZA FOR GENOME BROWSER | |
299 | |
300 Using the "coding" aggregator, this produces a nice gbrowse display. | |
301 | |
302 [CDS] | |
303 feature = coding | |
304 glyph = cds | |
305 frame0f = cadetblue | |
306 frame1f = blue | |
307 frame2f = darkblue | |
308 frame0r = darkred | |
309 frame1r = red | |
310 frame2r = crimson | |
311 description = 0 | |
312 height = 13 | |
313 label = CDS frame | |
314 key = CDS | |
315 citation = This track shows CDS reading frames. | |
316 | |
317 =head1 BUGS | |
318 | |
319 Please report them. | |
320 | |
321 =head1 SEE ALSO | |
322 | |
323 L<Bio::Graphics::Panel>, | |
324 L<Bio::Graphics::Glyph>, | |
325 L<Bio::Graphics::Glyph::arrow>, | |
326 L<Bio::Graphics::Glyph::cds>, | |
327 L<Bio::Graphics::Glyph::crossbox>, | |
328 L<Bio::Graphics::Glyph::diamond>, | |
329 L<Bio::Graphics::Glyph::dna>, | |
330 L<Bio::Graphics::Glyph::dot>, | |
331 L<Bio::Graphics::Glyph::ellipse>, | |
332 L<Bio::Graphics::Glyph::extending_arrow>, | |
333 L<Bio::Graphics::Glyph::generic>, | |
334 L<Bio::Graphics::Glyph::graded_segments>, | |
335 L<Bio::Graphics::Glyph::heterogeneous_segments>, | |
336 L<Bio::Graphics::Glyph::line>, | |
337 L<Bio::Graphics::Glyph::pinsertion>, | |
338 L<Bio::Graphics::Glyph::primers>, | |
339 L<Bio::Graphics::Glyph::rndrect>, | |
340 L<Bio::Graphics::Glyph::segments>, | |
341 L<Bio::Graphics::Glyph::ruler_arrow>, | |
342 L<Bio::Graphics::Glyph::toomany>, | |
343 L<Bio::Graphics::Glyph::transcript>, | |
344 L<Bio::Graphics::Glyph::transcript2>, | |
345 L<Bio::Graphics::Glyph::translation>, | |
346 L<Bio::Graphics::Glyph::triangle>, | |
347 L<Bio::DB::GFF>, | |
348 L<Bio::SeqI>, | |
349 L<Bio::SeqFeatureI>, | |
350 L<Bio::Das>, | |
351 L<GD> | |
352 | |
353 =head1 AUTHOR | |
354 | |
355 Lincoln Stein E<lt>lstein@cshl.orgE<gt> | |
356 | |
357 Copyright (c) 2001 Cold Spring Harbor Laboratory | |
358 | |
359 This library is free software; you can redistribute it and/or modify | |
360 it under the same terms as Perl itself. See DISCLAIMER.txt for | |
361 disclaimers of warranty. | |
362 | |
363 =cut |