~ubuntu-branches/ubuntu/raring/bioperl/raring

« back to all changes in this revision

Viewing changes to Bio/Graphics/Glyph/cds.pm

  • Committer: Bazaar Package Importer
  • Author(s): Charles Plessy
  • Date: 2008-03-18 14:44:57 UTC
  • mfrom: (4 hardy)
  • mto: This revision was merged to the branch mainline in revision 6.
  • Revision ID: james.westby@ubuntu.com-20080318144457-1jjoztrvqwf0gruk
* debian/control:
  - Removed MIA Matt Hope (dopey) from the Uploaders field.
    Thank you for your work, Matt. I hope you are doing well.
  - Downgraded some recommended package to the 'Suggests' priority,
    according to the following discussion on Upstream's mail list.
    http://bioperl.org/pipermail/bioperl-l/2008-March/027379.html
    (Closes: #448890)
* debian/copyright converted to machine-readable format.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
use Bio::Graphics::Glyph::segments;
5
5
use Bio::Graphics::Util qw(frame_and_offset);
6
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);
 
7
use base qw(Bio::Graphics::Glyph::segmented_keyglyph Bio::Graphics::Glyph::translation);
10
8
 
11
9
my %default_colors = qw(
12
 
                        frame0f  cadetblue
 
10
                        frame0f  cornflowerblue
13
11
                        frame1f  blue
14
12
                        frame2f  darkblue
15
 
                        frame0r  darkred
 
13
                        frame0r  magenta
16
14
                        frame1r  red
17
 
                        frame2r crimson
 
15
                        frame2r  darkred
18
16
                       );
19
17
 
 
18
my %swap_phase = ( 0  => 0,
 
19
                   1  => 2,
 
20
                   2  => 1,
 
21
                   '' => 0);
 
22
 
20
23
sub connector   { 0 };
21
24
sub description {
22
25
  my $self = shift;
31
34
 
32
35
sub sixframe {
33
36
  my $self = shift;
34
 
  $self->{sixframe} = $self->option('sixframe')
35
 
    unless exists $self->{sixframe};
36
 
  return $self->{sixframe};
 
37
  return $self->{sixframe} if exists $self->{sixframe};
 
38
  my $sixframe = $self->option('sixframe');
 
39
  $sixframe    = $self->option('translation') eq '6frame' unless defined $sixframe;
 
40
  return $self->{sixframe} = $sixframe;
37
41
}
38
42
 
 
43
sub maxdepth { 1 };
 
44
 
39
45
sub require_subparts {
40
46
  my $self = shift;
41
47
  my $rs   = $self->option('require_subparts');
43
49
  $rs;
44
50
}
45
51
 
 
52
sub ignore_undef_phase {
 
53
  shift->option('ignore_empty_phase');
 
54
}
 
55
 
 
56
sub ignore_non_cds {
 
57
  shift->option('cds_only');
 
58
}
 
59
 
 
60
sub phase_style {
 
61
  shift->option('phase_style') || '012';
 
62
}
 
63
 
46
64
# figure out (in advance) the color of each component
47
65
sub draw {
48
66
  my $self = shift;
52
70
  @parts    = $self if !@parts && $self->level == 0 && !$self->require_subparts;
53
71
 
54
72
  my $fits = $self->protein_fits;
 
73
  my $strand = $self->feature->strand || 1;
55
74
 
56
75
  # 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);
 
76
  if ($self->level == 0) {
 
77
    my ($x1,$y1,$x2,$y2) = $self->bounds($left,$top);
 
78
    my $line_count = $self->sixframe ? 6 : 3;
 
79
    my $height = ($y2-$y1)/$line_count;
 
80
    my $grid  = $self->gridcolor;
 
81
    for (0..$line_count-1) {
 
82
      my $offset = $y1+$height*$_+1;
 
83
      $gd->line($x1,$offset,$x2,$offset,$grid);
 
84
      # with three-frame translation, the position of the arrows changes depending on
 
85
      # the strand of the feature. With six-frame translation, we draw the first three
 
86
      # staff lines with an arrow to the right, and the second three to the left
 
87
      my $forward = ($line_count == 6) ? ($_ < 3) : ($strand > 0);
 
88
      if ($forward) {
 
89
        $gd->line($x2,$offset,$x2-2,$offset-2,$grid);
 
90
        $gd->line($x2,$offset,$x2-2,$offset+2,$grid);
 
91
      } else {
 
92
        $gd->line($x1,$offset,$x1+2,$offset-2,$grid);
 
93
        $gd->line($x1,$offset,$x1+2,$offset+2,$grid);
 
94
      }
 
95
    }
64
96
  }
65
97
 
66
98
  $self->{cds_part2color} ||= {};
67
99
  my $fill   = $self->bgcolor;
68
 
  my $strand = $self->feature->strand;
69
100
 
70
101
  # figure out the colors of each part
71
102
  # sort minus strand features backward
77
108
  $codon_table    = 1 unless defined $codon_table;
78
109
  my $translate_table = Bio::Tools::CodonTable->new(-id=>$codon_table);
79
110
 
 
111
  my $ignore_undef_phase = $self->ignore_undef_phase;
 
112
  my $ignore_non_cds     = $self->ignore_non_cds;
 
113
  my $broken_phase       = $self->phase_style eq '021';
 
114
 
80
115
  for (my $i=0; $i < @parts; $i++) {
81
116
    my $part    = $parts[$i];
82
117
    my $feature = $part->feature;
83
 
    my $pos     = $strand > 0 ? $feature->start : $feature->end;
84
 
    my $phase   = eval {$feature->phase} || 0;
 
118
 
 
119
    my $type = $feature->method;
 
120
    next if ($self->option('sub_part') && $type ne $self->option('sub_part'));
 
121
 
 
122
    next if $ignore_non_cds && lc($type) ne 'cds';
 
123
 
 
124
    my $pos     = $feature->strand >= 0 ? $feature->start : $feature->end;
 
125
    my $phase   = $feature->can('phase') ? $feature->phase  # bioperl uses "frame" but this is incorrect usage
 
126
                 :$feature->can('frame') ? $feature->frame
 
127
                 :undef;
 
128
    next if $ignore_undef_phase && !defined($phase);
 
129
    $phase ||= 0;
 
130
    $phase = $swap_phase{$phase} if $broken_phase;
 
131
    my $strand  = $feature->strand;
85
132
    my ($frame,$offset) = frame_and_offset($pos,
86
 
                                           $feature->strand,
87
 
                                           -$phase);
 
133
                                           $strand,
 
134
                                           $phase);
88
135
    my $suffix = $strand < 0 ? 'r' : 'f';
89
136
    my $key = "frame$frame$suffix";
90
137
    $self->{cds_frame2color}{$key} ||= $self->color($key) || $self->default_color($key) || $fill;
96
143
 
97
144
      # do in silico splicing in order to find the codon that
98
145
      # arises from the splice
99
 
      my $protein = $part->feature->translate(undef,undef,$phase,$codon_table)->seq;
 
146
      my $seq     = $self->get_seq($part->feature->seq);
 
147
      my $protein = $seq->translate(undef,undef,$phase,$codon_table)->seq;
100
148
      $part->{cds_translation}  = $protein;
101
149
 
102
150
    BLOCK: {
103
151
        length $protein >= $feature->length/3           and last BLOCK;
104
152
        ($feature->length - $phase) % 3 == 0            and last BLOCK;
105
 
        
 
153
 
106
154
        my $next_part    = $parts[$i+1]
107
155
          or do {
108
156
            $part->{cds_splice_residue} = '?';
109
157
            last BLOCK; };
110
 
        
 
158
 
111
159
        my $next_feature = $next_part->feature         or  last BLOCK;
112
160
        my $next_phase   = eval {$next_feature->phase} or  last BLOCK;
113
161
        my $splice_codon = '';
114
 
        my $left_of_splice  = substr($feature->seq,-$next_phase,$next_phase);
115
 
        my $right_of_splice = substr($next_feature->seq,0,3-$next_phase);
 
162
        my $left_of_splice  = substr($self->get_seq($feature->seq),    -$next_phase, $next_phase);
 
163
        my $right_of_splice = substr($self->get_seq($next_feature->seq),0          , 3-$next_phase);
116
164
        $splice_codon = $left_of_splice . $right_of_splice;
117
165
        length $splice_codon == 3                      or last BLOCK;
118
166
        my $amino_acid = $translate_table->translate($splice_codon);
140
188
    my $height = ($y2-$y1)/$linecount;
141
189
    my $offset = $y1 + $height*$frame;
142
190
    $offset   += ($y2-$y1)/2 if $self->sixframe && $self->strand < 0;
 
191
    $offset   = $y1 + (($y2-$y1) - ($offset-$y1))-$height if $self->{flip}; # ugh. This works, but I don't know why
143
192
    $gd->filledRectangle($x1,$offset,$x2,$offset+2,$color);
144
193
    return;
145
194
  }
149
198
  my $pixels_per_residue = $self->pixels_per_residue;
150
199
  my $strand = $feature->strand;
151
200
  my $y      = $y1-1;
 
201
  my $fontwidth = $font->width;
152
202
 
153
203
  $strand *= -1 if $self->{flip};
154
204
 
157
207
  # 2) correct for the phase offset
158
208
  my $start = $self->map_no_trunc($feature->start + $self->{cds_offset});
159
209
  my $stop  = $self->map_no_trunc($feature->end   + $self->{cds_offset});
160
 
  ($start,$stop) = ($stop,$start) if $self->{flip};
 
210
 
 
211
  ($start,$stop) = ($stop,$start) if $stop < $start;  # why does this keep happening?
 
212
  #  ($start,$stop) = ($stop,$start) if $self->{flip};
161
213
 
162
214
  my @residues = split '',$self->{cds_translation};
163
215
 
166
218
    my $x = $strand > 0 ? $start + $i * $pixels_per_residue
167
219
                        : $stop  - $i * $pixels_per_residue;
168
220
    next unless ($x >= $x1 && $x <= $x2);
 
221
    $x -= $fontwidth + 1 if $self->{flip}; # align right when flipped
169
222
    $gd->char($font,$x+1,$y,$residues[$i],$color);
170
223
  }
171
224
}
267
320
 
268
321
  -hilite       Highlight color                undef (no color)
269
322
 
270
 
In addition, the alignment glyph recognizes the following
271
 
glyph-specific options:
272
 
 
273
 
  Option      Description                  Default
274
 
  ------      -----------                  -------
275
 
 
276
 
  -frame0f    Color for first (+) frame    background color
277
 
 
278
 
  -frame1f    Color for second (+) frame   background color
279
 
 
280
 
  -frame2f    Color for third (+) frame    background color
281
 
 
282
 
  -frame0r    Color for first (-) frame    background color
283
 
 
284
 
  -frame1r    Color for second (-) frame   background color
285
 
 
286
 
  -frame2r    Color for third (-) frame    background color
287
 
 
288
 
  -gridcolor  Color for the "staff"        lightslategray
289
 
 
290
 
  -sixframe   Draw a six-frame staff       0 (false; usually draws 3 frame)
 
323
In addition, the cds glyph recognizes the following glyph-specific
 
324
options:
 
325
 
 
326
  Option      Description                      Default
 
327
  ------      -----------                      -------
 
328
 
 
329
  -frame0f    Color for first (+) frame        background color
 
330
 
 
331
  -frame1f    Color for second (+) frame       background color
 
332
 
 
333
  -frame2f    Color for third (+) frame        background color
 
334
 
 
335
  -frame0r    Color for first (-) frame        background color
 
336
 
 
337
  -frame1r    Color for second (-) frame       background color
 
338
 
 
339
  -frame2r    Color for third (-) frame        background color
 
340
 
 
341
  -gridcolor  Color for the "staff"            lightslategray
 
342
 
 
343
  -translation Number of lines of reading      3frame
 
344
               frames to show. One of
 
345
               "3frame", or "6frame".
 
346
               For 6frame, specify a height
 
347
               of at least 30 pixels.
 
348
 
 
349
  -sixframe   Draw a six-frame staff           0 (false; usually draws 3 frame)
 
350
              This value overrides
 
351
              -translation, which essentially
 
352
              does the same thing.
291
353
 
292
354
  -require_subparts
293
 
              Don't draw the reading frame 0 (false)
 
355
              Don't draw the reading frame 0   false
294
356
              unless it is a feature
295
357
              subpart.
296
358
 
297
 
  -codontable   Codon table to use           1 (see Bio::Tools::CodonTable)
 
359
  -sub_part   For objects with multiple        undef
 
360
              subpart types, defines which
 
361
              is the CDS part.
 
362
 
 
363
  -codontable   Codon table to use             1 (see Bio::Tools::CodonTable)
 
364
 
 
365
  -phase_style  The way phase is to be
 
366
                interpreted. One of            "012"
 
367
                "012" or "021"
 
368
  -ignore_empty_phase                          false
 
369
              Only draw features that have
 
370
              their phase defined.
 
371
 
 
372
  -cds_only   Only draw features of type       false
 
373
              'CDS'
 
374
 
 
375
This glyph is more sensitive to the underlying data model than usual,
 
376
so there are a few additional options to use to help adapt the glyph
 
377
to different environments.
298
378
 
299
379
The -require_subparts option is suggested when rendering spliced
300
380
transcripts which contain multiple CDS subparts.  Otherwise, the glyph
302
382
phantom reading frame will appear).  For unspliced sequences, do *not*
303
383
use -require_subparts.
304
384
 
 
385
The -phase_style controls how the value returned by the phase() or
 
386
frame() methods is to be interpreted. The official interpretation is
 
387
that the phase value indicates the offset into the feature at which
 
388
the reading frame starts -- e.g. a phase of "2" means the reading
 
389
frame starts after skipping two bases from the beginning of the
 
390
feature.  However, many GFF2 format feature files interpret this field
 
391
to mean the position reading frame of the first base of the feature --
 
392
e.g. a phase of "2" means that the reading frame starts after skipping
 
393
just one base from the beginning of the feature. Specify "012" to
 
394
interpret the phase field in the correct way, and "021" to interpret
 
395
the phase field in the legacy way. The default is "012."
 
396
 
 
397
Here is how the option names were chosen:
 
398
 
 
399
    * * *                  Base the reading frame starts on
 
400
    A B C A B C A B C...
 
401
    0 1 2                  PHASE REPRESENTED CORRECTLY
 
402
    0 2 1                  PHASE REPRESENTED IN THE LEGACY WAY
 
403
 
 
404
Set the -ignore_empty_phase option to true if you wish to skip
 
405
subfeatures that do not have a defined phase() or frame(). This is useful
 
406
if you are rendering exons that have both translated and untranslated
 
407
parts, and you wish to skip the untranslated parts.
 
408
 
 
409
Set the -cds_only option to true if you wish to draw the glyph only
 
410
for subfeatures of type 'CDS'. This is recommended.
 
411
 
305
412
=head1 SUGGESTED STANZA FOR GENOME BROWSER
306
413
 
307
414
Using the "coding" aggregator, this produces a nice gbrowse display.