diff variant_effect_predictor/Bio/Graphics/Glyph/cds.pm @ 0:1f6dce3d34e0

Uploaded
author mahtabm
date Thu, 11 Apr 2013 02:01:53 -0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/variant_effect_predictor/Bio/Graphics/Glyph/cds.pm	Thu Apr 11 02:01:53 2013 -0400
@@ -0,0 +1,363 @@
+package Bio::Graphics::Glyph::cds;
+
+use strict;
+use Bio::Graphics::Glyph::segments;
+use Bio::Graphics::Util qw(frame_and_offset);
+use Bio::Tools::CodonTable;
+use Bio::Graphics::Glyph::translation;
+use vars '@ISA';
+@ISA = qw(Bio::Graphics::Glyph::segmented_keyglyph Bio::Graphics::Glyph::translation);
+
+my %default_colors = qw(
+			frame0f  cadetblue
+			frame1f  blue
+			frame2f  darkblue
+			frame0r  darkred
+			frame1r  red
+			frame2r crimson
+		       );
+
+sub connector   { 0 };
+sub description {
+  my $self = shift;
+  return if $self->level;
+  return $self->SUPER::description;
+};
+
+sub default_color {
+  my ($self,$key) = @_;
+  return $self->factory->translate_color($default_colors{$key});
+}
+
+sub sixframe {
+  my $self = shift;
+  $self->{sixframe} = $self->option('sixframe')
+    unless exists $self->{sixframe};
+  return $self->{sixframe};
+}
+
+sub require_subparts {
+  my $self = shift;
+  my $rs   = $self->option('require_subparts');
+  $rs      = $self->feature->type eq 'coding' if !defined $rs;  # shortcut for the "coding" aggregator
+  $rs;
+}
+
+# figure out (in advance) the color of each component
+sub draw {
+  my $self = shift;
+  my ($gd,$left,$top) = @_;
+
+  my @parts = $self->parts;
+  @parts    = $self if !@parts && $self->level == 0 && !$self->require_subparts;
+
+  my $fits = $self->protein_fits;
+
+  # draw the staff (musically speaking)
+  my ($x1,$y1,$x2,$y2) = $self->bounds($left,$top);
+  my $line_count = $self->sixframe ? 6 : 3;
+  my $height = ($y2-$y1)/$line_count;
+  my $grid  = $self->gridcolor;
+  for (0..$line_count-1) {
+    my $offset = $y1+$height*$_+1;
+    $gd->line($x1,$offset,$x2,$offset,$grid);
+  }
+
+  $self->{cds_part2color} ||= {};
+  my $fill   = $self->bgcolor;
+  my $strand = $self->feature->strand;
+
+  # figure out the colors of each part
+  # sort minus strand features backward
+  @parts = map { $_->[0] }
+  sort { $b->[1] <=> $a->[1] }
+  map { [$_, $_->left ] } @parts if $strand < 0;
+  my $translate_table = Bio::Tools::CodonTable->new;
+
+  for (my $i=0; $i < @parts; $i++) {
+    my $part    = $parts[$i];
+    my $feature = $part->feature;
+    my $pos     = $strand > 0 ? $feature->start : $feature->end;
+    my $phase   = eval {$feature->phase} || 0;
+    my ($frame,$offset) = frame_and_offset($pos,
+					   $feature->strand,
+					   -$phase);
+    my $suffix = $strand < 0 ? 'r' : 'f';
+    my $key = "frame$frame$suffix";
+    $self->{cds_frame2color}{$key} ||= $self->color($key) || $self->default_color($key) || $fill;
+    $part->{cds_partcolor} = $self->{cds_frame2color}{$key};
+    $part->{cds_frame}     = $frame;
+    $part->{cds_offset}    = $offset;
+
+    if ($fits && $part->feature->seq) {
+
+      # do in silico splicing in order to find the codon that
+      # arises from the splice
+      my $protein = $part->feature->translate(undef,undef,$phase)->seq;
+      $part->{cds_translation}  = $protein;
+
+    BLOCK: {
+	length $protein >= $feature->length/3           and last BLOCK;
+	($feature->length - $phase) % 3 == 0            and last BLOCK;
+	
+	my $next_part    = $parts[$i+1]
+	  or do {
+	    $part->{cds_splice_residue} = '?';
+	    last BLOCK; };
+	
+	my $next_feature = $next_part->feature         or  last BLOCK;
+	my $next_phase   = eval {$next_feature->phase} or  last BLOCK;
+	my $splice_codon = '';
+	my $left_of_splice  = substr($feature->seq,-$next_phase,$next_phase);
+	my $right_of_splice = substr($next_feature->seq,0,3-$next_phase);
+	$splice_codon = $left_of_splice . $right_of_splice;
+	length $splice_codon == 3                      or last BLOCK;
+	my $amino_acid = $translate_table->translate($splice_codon);
+	$part->{cds_splice_residue} = $amino_acid;
+      }
+    }
+  }
+
+  $self->Bio::Graphics::Glyph::generic::draw($gd,$left,$top);
+}
+
+
+# draw the notes on the staff
+sub draw_component {
+  my $self = shift;
+  my $gd = shift;
+  my ($x1,$y1,$x2,$y2) = $self->bounds(@_);
+
+  my $color = $self->{cds_partcolor} or return;
+  my $feature   = $self->feature;
+  my $frame     = $self->{cds_frame};
+  my $linecount = $self->sixframe ? 6 : 3;
+
+  unless ($self->protein_fits) {
+    my $height = ($y2-$y1)/$linecount;
+    my $offset = $y1 + $height*$frame;
+    $offset   += ($y2-$y1)/2 if $self->sixframe && $self->strand < 0;
+    $gd->filledRectangle($x1,$offset,$x2,$offset+2,$color);
+    return;
+  }
+
+  # we get here if there's room to draw the primary sequence
+  my $font  = $self->font;
+  my $pixels_per_residue = $self->pixels_per_residue;
+  my $strand = $feature->strand;
+  my $y      = $y1-1;
+
+  $strand *= -1 if $self->{flip};
+
+  # have to remap feature start and end into pixel coords in order to:
+  # 1) correctly align the amino acids with the nucleotide seq
+  # 2) correct for the phase offset
+  my $start = $self->map_no_trunc($feature->start + $self->{cds_offset});
+  my $stop  = $self->map_no_trunc($feature->end   + $self->{cds_offset});
+  ($start,$stop) = ($stop,$start) if $self->{flip};
+
+  my @residues = split '',$self->{cds_translation};
+
+  push @residues,$self->{cds_splice_residue} if $self->{cds_splice_residue};
+  for (my $i=0;$i<@residues;$i++) {
+    my $x = $strand > 0 ? $start + $i * $pixels_per_residue
+                        : $stop  - $i * $pixels_per_residue;
+    next unless ($x >= $x1 && $x <= $x2);
+    $gd->char($font,$x+1,$y,$residues[$i],$color);
+  }
+}
+
+sub make_key_feature {
+  my $self = shift;
+  my @gatc = qw(g a t c);
+  my $offset = $self->panel->offset;
+  my $scale = 1/$self->scale;  # base pairs/pixel
+  my $start = $offset;
+  my $stop  = $offset + 100 * $scale;
+  my $seq   = join('',map{$gatc[rand 4]} (1..1500));
+  my $feature =
+    Bio::Graphics::Feature->new(-start=> $start,
+				-end  => $stop,
+				-seq  => $seq,
+				-name => $self->option('key'),
+				-strand=> +1,
+			       );
+  $feature->add_segment(Bio::Graphics::Feature->new(
+						    -start=> $start,
+						    -end => $start + ($stop - $start)/2,
+						    -seq  => $seq,
+						    -name => $self->option('key'),
+						    -strand=> +1,
+						   ),
+			Bio::Graphics::Feature->new(
+						    -start=> $start + ($stop - $start)/2+1,
+						    -end => $stop,
+						    -seq  => $seq,
+						    -name => $self->option('key'),
+						    -phase=> 1,
+						    -strand=> +1,
+						   ));
+  $feature;
+}
+
+# never allow our components to bump
+sub bump {
+  my $self = shift;
+  return $self->SUPER::bump(@_) if $self->all_callbacks;
+  return 0;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Bio::Graphics::Glyph::cds - The "cds" glyph
+
+=head1 SYNOPSIS
+
+  See L<Bio::Graphics::Panel> and L<Bio::Graphics::Glyph>.
+
+=head1 DESCRIPTION
+
+This glyph draws features that are associated with a protein coding
+region.  At high magnifications, draws a series of boxes that are
+color-coded to indicate the frame in which the translation occurs.  At
+low magnifications, draws the amino acid sequence of the resulting
+protein.  Amino acids that are created by a splice are optionally
+shown in a distinctive color.
+
+=head2 OPTIONS
+
+The following options are standard among all Glyphs.  See
+L<Bio::Graphics::Glyph> for a full explanation.
+
+  Option      Description                      Default
+  ------      -----------                      -------
+
+  -fgcolor      Foreground color	       black
+
+  -outlinecolor	Synonym for -fgcolor
+
+  -bgcolor      Background color               turquoise
+
+  -fillcolor    Synonym for -bgcolor
+
+  -linewidth    Line width                     1
+
+  -height       Height of glyph		       10
+
+  -font         Glyph font		       gdSmallFont
+
+  -connector    Connector type                 0 (false)
+
+  -connector_color
+                Connector color                black
+
+  -label        Whether to draw a label	       0 (false)
+
+  -description  Whether to draw a description  0 (false)
+
+  -strand_arrow Whether to indicate            0 (false)
+                 strandedness
+
+In addition, the alignment glyph recognizes the following
+glyph-specific options:
+
+  Option      Description                  Default
+  ------      -----------                  -------
+
+  -frame0f    Color for first (+) frame    background color
+
+  -frame1f    Color for second (+) frame   background color
+
+  -frame2f    Color for third (+) frame    background color
+
+  -frame0r    Color for first (-) frame    background color
+
+  -frame1r    Color for second (-) frame   background color
+
+  -frame2r    Color for third (-) frame    background color
+
+  -gridcolor  Color for the "staff"        lightslategray
+
+  -sixframe   Draw a six-frame staff       0 (false; usually draws 3 frame)
+
+  -require_subparts
+              Don't draw the reading frame 0 (false)
+              unless it is a feature
+              subpart.
+
+The -require_subparts option is suggested when rendering spliced
+transcripts which contain multiple CDS subparts.  Otherwise, the glyph
+will hickup when zoomed way down onto an intron between two CDSs (a
+phantom reading frame will appear).  For unspliced sequences, do *not*
+use -require_subparts.
+
+=head1 SUGGESTED STANZA FOR GENOME BROWSER
+
+Using the "coding" aggregator, this produces a nice gbrowse display.
+
+ [CDS]
+ feature      = coding
+ glyph        = cds
+ frame0f      = cadetblue
+ frame1f      = blue
+ frame2f      = darkblue
+ frame0r      = darkred
+ frame1r      = red
+ frame2r      = crimson
+ description  = 0
+ height       = 13
+ label        = CDS frame
+ key          = CDS
+ citation     = This track shows CDS reading frames.
+
+=head1 BUGS
+
+Please report them.
+
+=head1 SEE ALSO
+
+L<Bio::Graphics::Panel>,
+L<Bio::Graphics::Glyph>,
+L<Bio::Graphics::Glyph::arrow>,
+L<Bio::Graphics::Glyph::cds>,
+L<Bio::Graphics::Glyph::crossbox>,
+L<Bio::Graphics::Glyph::diamond>,
+L<Bio::Graphics::Glyph::dna>,
+L<Bio::Graphics::Glyph::dot>,
+L<Bio::Graphics::Glyph::ellipse>,
+L<Bio::Graphics::Glyph::extending_arrow>,
+L<Bio::Graphics::Glyph::generic>,
+L<Bio::Graphics::Glyph::graded_segments>,
+L<Bio::Graphics::Glyph::heterogeneous_segments>,
+L<Bio::Graphics::Glyph::line>,
+L<Bio::Graphics::Glyph::pinsertion>,
+L<Bio::Graphics::Glyph::primers>,
+L<Bio::Graphics::Glyph::rndrect>,
+L<Bio::Graphics::Glyph::segments>,
+L<Bio::Graphics::Glyph::ruler_arrow>,
+L<Bio::Graphics::Glyph::toomany>,
+L<Bio::Graphics::Glyph::transcript>,
+L<Bio::Graphics::Glyph::transcript2>,
+L<Bio::Graphics::Glyph::translation>,
+L<Bio::Graphics::Glyph::triangle>,
+L<Bio::DB::GFF>,
+L<Bio::SeqI>,
+L<Bio::SeqFeatureI>,
+L<Bio::Das>,
+L<GD>
+
+=head1 AUTHOR
+
+Lincoln Stein E<lt>lstein@cshl.orgE<gt>
+
+Copyright (c) 2001 Cold Spring Harbor Laboratory
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.  See DISCLAIMER.txt for
+disclaimers of warranty.
+
+=cut