diff variant_effect_predictor/Bio/Graphics/Glyph/segments.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/segments.pm	Thu Apr 11 02:01:53 2013 -0400
@@ -0,0 +1,347 @@
+package Bio::Graphics::Glyph::segments;
+#$Id: segments.pm,v 1.21.2.1 2003/07/05 00:32:04 lstein Exp $
+
+use strict;
+use Bio::Location::Simple;
+use Bio::Graphics::Glyph::generic;
+use Bio::Graphics::Glyph::segmented_keyglyph;
+use vars '@ISA';
+
+use constant RAGGED_START_FUZZ => 25;  # will show ragged ends of alignments
+                                       # up to this many bp.
+use constant DEBUG => 0;
+
+@ISA = qw( Bio::Graphics::Glyph::segmented_keyglyph
+	   Bio::Graphics::Glyph::generic
+	 );
+
+my %complement = (g=>'c',a=>'t',t=>'a',c=>'g',n=>'n',
+		  G=>'C',A=>'T',T=>'A',C=>'G',N=>'N');
+
+sub pad_left {
+  my $self = shift;
+  return $self->SUPER::pad_left unless $self->option('draw_target') && $self->option('ragged_start') && $self->dna_fits;
+  return $self->SUPER::pad_left unless $self->level > 0;
+  my $target = eval {$self->feature->hit} or return $self->SUPER::pad_left;
+  return $self->SUPER::pad_left unless $target->start<$target->end && $target->start < RAGGED_START_FUZZ;
+  return ($target->start-1) * $self->scale;
+}
+
+sub pad_right {
+  my $self = shift;
+  return $self->SUPER::pad_right unless $self->level > 0;
+  return $self->SUPER::pad_right unless $self->option('draw_target') && $self->option('ragged_start') && $self->dna_fits;
+  my $target = eval {$self->feature->hit} or return $self->SUPER::pad_right;
+  return $self->SUPER::pad_right unless $target->end < $target->start && $target->start < RAGGED_START_FUZZ;
+  return ($target->end-1) * $self->scale;
+}
+
+# group sets connector to 'solid'
+sub connector {
+  my $self = shift;
+  return $self->SUPER::connector(@_) if $self->all_callbacks;
+  return ($self->SUPER::connector(@_) || 'solid');
+}
+
+# never allow our components to bump
+sub bump {
+  my $self = shift;
+  return $self->SUPER::bump(@_) if $self->all_callbacks;
+  return 0;
+}
+
+sub fontcolor {
+  my $self = shift;
+  return $self->SUPER::fontcolor unless $self->option('draw_target') || $self->option('draw_dna');
+  return $self->SUPER::fontcolor unless $self->dna_fits;
+  return $self->bgcolor;
+}
+
+sub draw_component {
+  my $self = shift;
+  my ($draw_dna,$draw_target) = ($self->option('draw_dna'),$self->option('draw_target'));
+  return $self->SUPER::draw_component(@_)
+    unless $draw_dna || $draw_target;
+  return $self->SUPER::draw_component(@_) unless $self->dna_fits;
+
+  my $dna = $draw_target ? eval {$self->feature->hit->seq}
+                         : eval {$self->feature->seq};
+  return $self->SUPER::draw_component(@_) unless length $dna > 0;  # safety
+
+  my $show_mismatch = $draw_target && $self->option('show_mismatch');
+  my $genomic       = eval {$self->feature->seq} if $show_mismatch;
+
+  my $gd = shift;
+  my ($x1,$y1,$x2,$y2) = $self->bounds(@_);
+
+  # adjust for nonaligned left end (for ESTs...)  The size given here is roughly sufficient
+  # to show a polyA end or a C. elegans trans-spliced leader.
+  my $offset = 0;
+  eval {  # protect against data structures that don't implement the target() method.
+    if ($draw_target && $self->option('ragged_start')){
+      my $target = $self->feature->hit;
+      if ($target->start < $target->end && $target->start < RAGGED_START_FUZZ  
+	  && $self->{partno} == 0) {
+	$offset = $target->start - 1;
+	if ($offset > 0) {
+	  $dna       = $target->subseq(1-$offset,0)->seq        . $dna;
+	  $genomic   = $self->feature->subseq(1-$offset,0)->seq . $genomic;
+	  $x1        -= $offset * $self->scale;
+	}
+      }
+      elsif ($target->end < $target->start && 
+	     $target->end < RAGGED_START_FUZZ && $self->{partno} == $self->{total_parts}) {
+	$offset = $target->end - 1;
+	if ($offset > 0) {
+	  $dna       .= $target->factory->get_dna($target,$offset,1);
+	  $genomic    = $self->feature->subseq(-$offset,0)->seq . $genomic;
+	  $x2        += $offset * $self->scale;
+	  $offset = 0;
+	}
+      }
+    }
+  };
+
+  $self->draw_dna($gd,$offset,lc $dna,lc $genomic,$x1,$y1,$x2,$y2);
+}
+
+sub draw_dna {
+  my $self = shift;
+
+  my ($gd,$start_offset,$dna,$genomic,$x1,$y1,$x2,$y2) = @_;
+  my $pixels_per_base = $self->scale;
+  my $feature         = $self->feature;
+  my $target          = $feature->target;
+  my $strand          = $feature->strand;
+
+  my @segs;
+
+  my $complement      = $strand < 0;
+
+  if ($self->{flip}) {
+    $dna     = $self->reversec($dna);
+    $genomic = $self->reversec($genomic);
+    $strand            *= -1;
+  }
+
+  warn "strand = $strand, complement = $complement" if DEBUG;
+
+  if ($genomic && length($genomic) != length($dna) && eval { require Bio::Graphics::Browser::Realign}) {
+    warn "$genomic\n$dna\n" if DEBUG;
+    warn "strand = $strand" if DEBUG;
+    @segs = Bio::Graphics::Browser::Realign::align_segs($genomic,$dna);
+    for my $seg (@segs) {
+      my $src = substr($genomic,$seg->[0],$seg->[1]-$seg->[0]+1);
+      my $tgt = substr($dna,    $seg->[2],$seg->[3]-$seg->[2]+1);
+      warn "@$seg\n$src\n$tgt" if DEBUG;
+    }
+  } else {
+    @segs = [0,length($genomic)-1,0,length($dna)-1];
+  }
+
+  my $color = $self->fgcolor;
+  my $font  = $self->font;
+  my $lineheight = $font->height;
+  my $fontwidth  = $font->width;
+  $y1 -= $lineheight/2 - 3;
+  my $pink = $self->factory->translate_color('lightpink');
+  my $panel_end = $self->panel->right;
+
+  my $start  = $self->map_no_trunc($self->feature->start- $start_offset);
+  my $end    = $self->map_no_trunc($self->feature->end  - $start_offset);
+
+  my ($last,$tlast);
+  for my $seg (@segs) {
+
+    # fill in misaligned bits with dashes and bases
+    if (defined $last) {
+      my $delta  = $seg->[0] - $last  - 1;
+      my $tdelta = $seg->[2] - $tlast - 1;
+      warn "src gap [$last,$seg->[0]], tgt gap [$tlast,$seg->[2]], delta = $delta, tdelta = $tdelta\n" if DEBUG;
+
+      my $gaps   = $delta - $tdelta;
+      my @fill_in = split '',substr($dna,$tlast+1,$tdelta) if $tdelta > 0;
+      unshift @fill_in,('-')x$gaps if $gaps > 0;
+
+      warn "gaps = $gaps, fill_in = @fill_in\n" if DEBUG;
+
+      my $distance          = $pixels_per_base * ($delta+1);
+      my $pixels_per_target = $gaps >= 0 ? $pixels_per_base : $distance/(@fill_in+1);
+
+      warn "pixels_per_base = $pixels_per_base, pixels_per_target=$pixels_per_target\n" if DEBUG;
+      my $offset = $self->{flip} ?  $end + ($last-1)*$pixels_per_base : $start + $last*$pixels_per_base;
+      
+      for (my $i=0; $i<@fill_in; $i++) {
+
+	my $x = $self->{flip} ? int($offset + ($i+1)*$pixels_per_target + 0.5)
+                              : int($offset + ($i+1)*$pixels_per_target + 0.5);
+
+	$self->filled_box($gd,$x,$y1+3,$x+$fontwidth,$y1+$lineheight-3,$pink,$pink) unless $gaps;
+	$gd->char($font,$x,$y1,$complement? $complement{$fill_in[$i]} : $fill_in[$i],$color); 
+      }
+    }
+
+    my @genomic = split '',substr($genomic,$seg->[0],$seg->[1]-$seg->[0]+1);
+    my @bases   = split '',substr($dna,    $seg->[2],$seg->[3]-$seg->[2]+1);
+    for (my $i = 0; $i<@bases; $i++) {
+      my $x = $self->{flip} ? int($end   + ($seg->[0] + $i - 1)*$pixels_per_base + 0.5)
+                            : int($start + ($seg->[0] + $i)    *$pixels_per_base + 0.5);
+      next if $x+1 < $x1;
+      last if $x+1 > $x2;
+      if ($genomic[$i] && lc($bases[$i]) ne lc($complement ? $complement{$genomic[@genomic - $i - 1]} : $genomic[$i])) {
+	$self->filled_box($gd,$x,$y1+3,$x+$fontwidth,$y1+$lineheight-3,$pink,$pink);
+      }
+      $gd->char($font,$x,$y1,$complement ? $complement{$bases[$i]} || $bases[$i] : $bases[$i],$color);
+    }
+    $last  = $seg->[1];
+    $tlast = $seg->[3];
+  }
+
+}
+
+# Override _subseq() method to make it appear that a top-level feature that
+# has no subfeatures appears as a feature that has a single subfeature.
+# Otherwise at high mags gaps will be drawn as components rather than
+# as connectors.  Because of differing representations of split features
+# in Bio::DB::GFF::Feature and Bio::SeqFeature::Generic, there is
+# some breakage of encapsulation here.
+sub _subseq {
+  my $self    = shift;
+  my $feature = shift;
+  my @subseq  = $self->SUPER::_subseq($feature);
+  return @subseq if @subseq;
+  if ($self->level == 0 && !@subseq && !eval{$feature->compound}) {
+    my($start,$end) = ($feature->start,$feature->end);
+    ($start,$end) = ($end,$start) if $start > $end; # to keep Bio::Location::Simple from bitching
+    #    return Bio::Location::Simple->new(-start=>$start,-end=>$end);
+    return $self->feature;
+  } else {
+    return;
+  }
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Bio::Graphics::Glyph::segments - The "segments" glyph
+
+=head1 SYNOPSIS
+
+  See L<Bio::Graphics::Panel> and L<Bio::Graphics::Glyph>.
+
+=head1 DESCRIPTION
+
+This glyph is used for drawing features that consist of discontinuous
+segments.  Unlike "graded_segments" or "alignment", the segments are a
+uniform color and not dependent on the score of the segment.
+
+=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
+
+  -draw_dna     If true, draw the dna residues 0 (false)
+                 when magnification level
+                 allows.
+
+  -draw_target  If true, draw the dna residues 0 (false)
+                 of the TARGET sequence when
+                 magnification level allows.
+                 SEE NOTE.
+
+  -ragged_start When combined with -draw_target, 0 (false)
+                 draw a few bases beyond the end
+                 of the alignment.  SEE NOTE.
+
+  -show_mismatch When combined with -draw_target, 0 (false)
+                 highlights mismatched bases in
+                 pink.  SEE NOTE.
+
+The -draw_target and -ragged_start options only work with seqfeatures
+that implement the hit() method (Bio::SeqFeature::SimilarityPair).
+The -ragged_start option is mostly useful for looking for polyAs and
+cloning sites at the beginning of ESTs and cDNAs.  Currently there is
+no way of activating ragged ends.  The length of the ragged starts is
+hard-coded at 25 bp, and the color of mismatches is hard-coded as
+light pink.
+
+=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