~ubuntu-branches/ubuntu/saucy/bioperl/saucy-proposed

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Charles Plessy
  • Date: 2009-03-10 07:19:11 UTC
  • mfrom: (1.2.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090310071911-fukqzw54pyb1f0bd
Tags: 1.6.0-2
* Removed patch system (not used):
  - removed instuctions in debian/rules;
  - removed quilt from Build-Depends in debian/control.
* Re-enabled tests:
  - uncommented test command in debian/rules;
  - uncommented previously missing build-dependencies in debian/control.
  - Re-enabled tests and uncommented build-dependencies accordingly.
* Removed libmodule-build-perl and libtest-harness-perl from
  Build-Depends-Indep (provided by perl-modules).
* Better cleaning of empty directories using find -type d -empty -delete
  instead of rmdir in debian/rules (LP: #324001).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
package Bio::Graphics::Glyph::processed_transcript;
2
 
 
3
 
# $Id: processed_transcript.pm,v 1.12.4.1 2006/10/02 23:10:20 sendu Exp $
4
 
 
5
 
use strict;
6
 
use base qw(Bio::Graphics::Glyph::transcript2);
7
 
use constant DEFAULT_UTR_COLOR => '#D0D0D0';
8
 
 
9
 
sub new {
10
 
  my $class = shift;
11
 
  my $self = $class->SUPER::new(@_);
12
 
  $self->guess_options if !defined $self->option('implied_utrs') 
13
 
    && !defined $self->option('adjust_exons');
14
 
  $self;
15
 
}
16
 
 
17
 
sub guess_options {
18
 
  my $self = shift;
19
 
  my ($exons,$utrs,$cds);
20
 
  foreach ($self->parts) {
21
 
    $exons++ if $_->feature->type =~ /exon/i;
22
 
    $utrs++  if $_->feature->type =~ /utr$/i;
23
 
    $cds++   if $_->feature->type =~ /^cds/i;
24
 
    $self->configure(implied_utrs=>1) if $exons && $cds && !$utrs;
25
 
    $self->configure(adjust_exons=>1) if $exons && $utrs;
26
 
  }
27
 
}
28
 
 
29
 
# this option will generate implied UTRs by subtracting the
30
 
# CDS features from the exons.
31
 
sub create_implied_utrs {
32
 
  my $self = shift;
33
 
  return if $self->{'.implied_utrs'}++;
34
 
 
35
 
  # parts should be ordered from left to right
36
 
  my @features = sort {$a->start <=> $b->start} map {$_->feature} $self->parts;
37
 
  my @exons   = grep {$_->type eq 'exon'} @features;
38
 
  my @cds     = grep {$_->type eq 'CDS'}  @features;
39
 
  my @old_utr = grep {$_->type =~ /UTR/}  @features;
40
 
 
41
 
  # if there are already UTRs then we don't modify anything
42
 
  return if @old_utr;
43
 
 
44
 
  # if exons or CDS features are missing, then we abandon ship
45
 
  return unless @exons && @cds;
46
 
 
47
 
  my $first_cds = $cds[0];
48
 
  my $last_cds  = $cds[-1];
49
 
  my $strand = $self->feature->strand;
50
 
 
51
 
  my $factory    = $self->factory;
52
 
 
53
 
  # make the left-hand UTRs
54
 
  for (my $i=0;$i<@exons;$i++) {
55
 
    my $start = $exons[$i]->start;
56
 
    last if $start >= $first_cds->start;
57
 
    my $end  = $first_cds->start > $exons[$i]->end ? $exons[$i]->end : $first_cds->start-1;
58
 
    my $utr = Bio::Graphics::Feature->new(-start=>$start,
59
 
                                          -end=>$end,
60
 
                                          -strand=>$strand,
61
 
                                          -type=>$strand >= 0 ? 'five_prime_UTR' : 'three_prime_UTR');
62
 
    unshift @{$self->{parts}},$factory->make_glyph($self->{level}+1,$utr);
63
 
  }
64
 
  # make the right-hand UTRs
65
 
  for (my $i=$#exons; $i>=0; $i--) {
66
 
    my $end = $exons[$i]->end;
67
 
    last if $end <= $last_cds->end;
68
 
    my $start = $last_cds->end < $exons[$i]->start ? $exons[$i]->start : $last_cds->end+1;
69
 
    my $utr = Bio::Graphics::Feature->new(-start=>$start,
70
 
                                          -end=>$end,
71
 
                                          -strand=>$strand,
72
 
                                          -type=>$strand >= 0 ? 'three_prime_UTR' : 'five_prime_UTR');
73
 
    push @{$self->{parts}},$factory->make_glyph($self->{level}+1,$utr);
74
 
  }
75
 
}
76
 
 
77
 
# Preprocess the glyph to remove overlaps between UTRs and
78
 
# exons.  The exons are clipped so that UTRs have precedence
79
 
sub adjust_exons {
80
 
  my $self = shift;
81
 
 
82
 
  return if $self->{'.adjust_exons'}++;
83
 
 
84
 
  # find everything that is not an exon (utrs and cds's)
85
 
  my @parts  = sort {$a->{left}<=>$b->{left}} $self->parts;
86
 
  my @exon   = grep {$_->feature->type =~ /exon/i} @parts;
87
 
  my %seen   = map {$_=>1} @exon;
88
 
  my @other  = grep {!$seen{$_}} @parts;
89
 
 
90
 
  my @clipped_parts;
91
 
  my %positions    = map {("$_->{left}:$_->{width}" =>1)} @other;
92
 
  my @unique_exons = grep {!$positions{"$_->{left}:$_->{width}"}} @exon;
93
 
 
94
 
  # the first and last exons may need to be clipped if they overlap
95
 
  # with another feature (CDS or UTR)
96
 
  my $first_exon = $unique_exons[0];
97
 
  my $last_exon  = $unique_exons[-1];
98
 
 
99
 
  # deal with left hand side first
100
 
  my $e_left    = $first_exon->{left};
101
 
  my $e_right   = $e_left + $first_exon->{width};
102
 
  for my $other (@other) {
103
 
    my $o_left  = $other->{left};
104
 
    my $o_right = $o_left + $other->{width};
105
 
    next if $e_left  > $o_right;
106
 
    last if $e_right < $o_left;
107
 
    #dgg- need to skip 3prime/right utr for 1exon; end same as exon
108
 
    last if (@unique_exons == 1 && $o_left > $e_left); #dgg- o_ is 3prime not 5
109
 
    # clip left hand side; may get clipped into oblivion!
110
 
    $first_exon->{left}  = $o_right + 1;
111
 
    $first_exon->{width} = $e_right - $first_exon->{left};
112
 
  }
113
 
 
114
 
  # deal with right hand side
115
 
  $e_left  = $last_exon->{left};
116
 
  $e_right = $e_left + $last_exon->{width};
117
 
  for (my $i=$#other; $i>=0; $i--) {
118
 
    my $o_left  = $other[$i]->{left};
119
 
    my $o_right = $o_left + $other[$i]->{width};
120
 
    next if $e_right < $o_left;
121
 
    last if $e_left  > $o_right;
122
 
    # clip right hand side; may get clipped into oblivion!
123
 
    #dgg- !! this always clips to oblivion: $last_exon->{width} = ($e_left - 1) - $last_exon->{left};
124
 
    $last_exon->{width} = $o_left - $last_exon->{left}; #dgg-
125
 
  }
126
 
 
127
 
  $self->{parts} =  [ grep {$_->width > 0} sort {$a->{left}<=>$b->{left}} (@other,@unique_exons)];
128
 
}
129
 
 
130
 
sub fixup_glyph {
131
 
  my $self = shift;
132
 
  return unless $self->level == 0;
133
 
  $self->create_implied_utrs if $self->option('implied_utrs');
134
 
  $self->adjust_exons        if $self->option('implied_utrs') || $self->option('adjust_exons');
135
 
}
136
 
 
137
 
sub draw {
138
 
  my $self = shift;
139
 
  $self->fixup_glyph();
140
 
  $self->SUPER::draw(@_);
141
 
}
142
 
 
143
 
sub boxes {
144
 
  my $self = shift;
145
 
  $self->fixup_glyph();
146
 
  $self->SUPER::boxes(@_);
147
 
}
148
 
 
149
 
sub is_utr {
150
 
  my $self = shift;
151
 
  return $self->feature->primary_tag =~ /UTR|untranslated_region/i;
152
 
}
153
 
 
154
 
sub thin_utr {
155
 
  my $self = shift;
156
 
  $self->option('thin_utr');
157
 
}
158
 
 
159
 
sub utr_color {
160
 
  my $self = shift;
161
 
  return $self->color('utr_color') if $self->option('utr_color');
162
 
  return $self->factory->translate_color(DEFAULT_UTR_COLOR);
163
 
}
164
 
 
165
 
sub height {
166
 
  my $self = shift;
167
 
  my $height    = $self->SUPER::height;
168
 
  return $height unless $self->thin_utr;
169
 
  return $self->is_utr ? int($height/1.5+0.5) : $height;
170
 
}
171
 
 
172
 
sub pad_top {
173
 
  my $self = shift;
174
 
  my $pad_top = $self->SUPER::pad_top;
175
 
  return $pad_top unless $self->thin_utr && $self->is_utr;
176
 
  return $pad_top + int(0.167*$self->SUPER::height + 0.5);
177
 
}
178
 
 
179
 
sub bgcolor {
180
 
  my $self = shift;
181
 
  return $self->SUPER::bgcolor unless $self->is_utr;
182
 
  return $self->utr_color;
183
 
}
184
 
 
185
 
sub connector {
186
 
  my $self = shift;
187
 
  return 'quill' if $self->option('decorate_introns');
188
 
  return $self->SUPER::connector(@_);
189
 
}
190
 
 
191
 
 
192
 
sub _subfeat {
193
 
  my $self   = shift;
194
 
  return $self->SUPER::_subfeat(@_) unless ref($self) && $self->{level} == 0 && $self->option('one_cds');
195
 
  my $feature = shift;
196
 
 
197
 
  my @subparts = $feature->get_SeqFeatures(qw(CDS five_prime_UTR three_prime_UTR UTR));
198
 
 
199
 
  # The CDS and UTRs may be represented as a single feature with subparts or as several features
200
 
  # that have different IDs. We handle both cases transparently.
201
 
  my @result;
202
 
  foreach (@subparts) {
203
 
    if ($_->primary_tag =~ /CDS|UTR/i) {
204
 
      my @cds_seg = $_->get_SeqFeatures;
205
 
      if (@cds_seg > 0) { push @result,@cds_seg  } else { push @result,$_ }
206
 
    } else {
207
 
      push @result,$_;
208
 
    }
209
 
  }
210
 
  return @result;
211
 
}
212
 
 
213
 
1;
214
 
 
215
 
__END__
216
 
 
217
 
=head1 NAME
218
 
 
219
 
Bio::Graphics::Glyph::processed_transcript - The sequence ontology transcript glyph
220
 
 
221
 
=head1 SYNOPSIS
222
 
 
223
 
  See L<Bio::Graphics::Panel> and L<Bio::Graphics::Glyph>.
224
 
 
225
 
=head1 DESCRIPTION
226
 
 
227
 
This glyph is used for drawing processed transcripts that have both
228
 
CDS and UTR segments.  The CDS is drawn in the background color, and
229
 
the UTRs are drawn in an alternate color selected by the utr_color
230
 
option.  In addition, you can make the UTRs thinner than the CDS by
231
 
setting the "thin_utr" option.
232
 
 
233
 
For this glyph to produce the desired results, you should pass it a
234
 
compound Bio::SeqFeature that has subfeatures of primary_tag "CDS" and
235
 
"UTR".  In fact, you may give it more specific types of UTR, including
236
 
5'-UTR, 3'-UTR, or the Sequence Ontology terms "untranslated_region,"
237
 
"five_prime_untranslated_region," and
238
 
"three_prime_untranslated_region."
239
 
 
240
 
=head2 OPTIONS
241
 
 
242
 
The following options are standard among all Glyphs.  See
243
 
L<Bio::Graphics::Glyph> for a full explanation.
244
 
 
245
 
  Option      Description                      Default
246
 
  ------      -----------                      -------
247
 
 
248
 
  -fgcolor      Foreground color               black
249
 
 
250
 
  -outlinecolor Synonym for -fgcolor
251
 
 
252
 
  -bgcolor      Background color               turquoise
253
 
 
254
 
  -fillcolor    Synonym for -bgcolor
255
 
 
256
 
  -linewidth    Line width                     1
257
 
 
258
 
  -height       Height of glyph                10
259
 
 
260
 
  -font         Glyph font                     gdSmallFont
261
 
 
262
 
  -connector    Connector type                 undef (false)
263
 
 
264
 
  -connector_color
265
 
                Connector color                black
266
 
 
267
 
  -label        Whether to draw a label        undef (false)
268
 
 
269
 
  -description  Whether to draw a description  undef (false)
270
 
 
271
 
  -strand_arrow Whether to indicate            undef (false)
272
 
                 strandedness
273
 
 
274
 
  -hilite       Highlight color                undef (no color)
275
 
 
276
 
In addition, the alignment glyph recognizes the following
277
 
glyph-specific options:
278
 
 
279
 
  Option         Description                  Default
280
 
  ------         -----------                  -------
281
 
 
282
 
  -thin_utr      Flag.  If true, UTRs will      undef (false)
283
 
                 be drawn at 2/3 of the
284
 
                 height of CDS segments.
285
 
 
286
 
  -utr_color     Color of UTR segments.         Gray #D0D0D0
287
 
 
288
 
  -decorate_introns
289
 
                 Draw strand with little arrows undef (false)
290
 
                 on the intron.
291
 
 
292
 
  -adjust_exons  Fix exons so that they don't   undef (false)
293
 
                 overlap UTRs
294
 
 
295
 
  -implied_utrs  Whether UTRs should be implied undef (false)
296
 
                 from exons and CDS features
297
 
 
298
 
  -one_cds       Some databases (e.g. FlyBase) represent their
299
 
                 transcripts as having a single CDS that is
300
 
                 broken up into multiple parts. Set this to
301
 
                 true to display this type of feature.
302
 
 
303
 
The B<-adjust_exons> option is needed to handle features in which the
304
 
exons (SO type "exon") overlaps with the UTRs (SO types
305
 
"five_prime_UTR" and "three_prime_UTR").  The exon parts of the glyph
306
 
will be clipped so that it doesn't overlap with the UTR parts.
307
 
 
308
 
The B<-implied_utrs> option is needed if there are no explicit UTR
309
 
features.  In this case, UTRs are derived by subtracting the positions
310
 
of "CDS" subfeatures from the positions of "exon" subfeatures.
311
 
B<-implied_utrs> implies the B<-adjust_exons> option.
312
 
 
313
 
=head1 BUGS
314
 
 
315
 
Please report them.
316
 
 
317
 
=head1 SEE ALSO
318
 
 
319
 
 
320
 
L<Bio::Graphics::Panel>,
321
 
L<Bio::Graphics::Glyph>,
322
 
L<Bio::Graphics::Glyph::arrow>,
323
 
L<Bio::Graphics::Glyph::cds>,
324
 
L<Bio::Graphics::Glyph::crossbox>,
325
 
L<Bio::Graphics::Glyph::diamond>,
326
 
L<Bio::Graphics::Glyph::dna>,
327
 
L<Bio::Graphics::Glyph::dot>,
328
 
L<Bio::Graphics::Glyph::ellipse>,
329
 
L<Bio::Graphics::Glyph::extending_arrow>,
330
 
L<Bio::Graphics::Glyph::generic>,
331
 
L<Bio::Graphics::Glyph::graded_segments>,
332
 
L<Bio::Graphics::Glyph::heterogeneous_segments>,
333
 
L<Bio::Graphics::Glyph::line>,
334
 
L<Bio::Graphics::Glyph::pinsertion>,
335
 
L<Bio::Graphics::Glyph::primers>,
336
 
L<Bio::Graphics::Glyph::rndrect>,
337
 
L<Bio::Graphics::Glyph::segments>,
338
 
L<Bio::Graphics::Glyph::ruler_arrow>,
339
 
L<Bio::Graphics::Glyph::toomany>,
340
 
L<Bio::Graphics::Glyph::transcript>,
341
 
L<Bio::Graphics::Glyph::transcript2>,
342
 
L<Bio::Graphics::Glyph::translation>,
343
 
L<Bio::Graphics::Glyph::triangle>,
344
 
L<Bio::DB::GFF>,
345
 
L<Bio::SeqI>,
346
 
L<Bio::SeqFeatureI>,
347
 
L<Bio::Das>,
348
 
L<GD>
349
 
 
350
 
=head1 AUTHOR
351
 
 
352
 
Lincoln Stein E<lt>lstein@cshl.orgE<gt>
353
 
 
354
 
Copyright (c) 2001 Cold Spring Harbor Laboratory
355
 
 
356
 
This library is free software; you can redistribute it and/or modify
357
 
it under the same terms as Perl itself.  See DISCLAIMER.txt for
358
 
disclaimers of warranty.
359
 
 
360
 
=cut