Bio-BioStudio
view release on metacpan or search on metacpan
bin/BS_Cartoonist.pl view on Meta::CPAN
die ("BSERROR: Factor must be at least 2.\n")
if ($p{FACTOR} && $p{FACTOR} < 2);
################################################################################
################################# CONFIGURING ##################################
################################################################################
my $chrseq = $chr->sequence;
my $chrlen = length $chrseq;
my @features = $chr->db->features;
$p{DATAEND} = $p{DATAEND} && $p{DATAEND} <= $chrlen
? $p{DATAEND}
: $chrlen;
$p{DATASTART} = $p{DATASTART} && $p{DATASTART} >= 1 && $p{DATASTART} < $p{DATAEND}
? $p{DATASTART}
: 1;
#Scaling factor
$p{FACTOR} = $p{FACTOR} ? $p{FACTOR} : 10;
#PDF margins
$p{LEFT_MARGIN} = 100;
$p{RIGHT_MARGIN} = 100;
#Each level represent 50kb of data, with a height of 400
$p{LEVEL_WIDTH} = $p{LEVEL_WIDTH} ? $p{LEVEL_WIDTH} : 50000;
$p{LEVEL_HEIGHT} = 460;
#Left Freedom Data: amount of data that will repeat from the last line
$p{LEFT_REPEAT} = $p{LEFT_REPEAT} ? $p{LEFT_REPEAT} : 1000; # 1000 = 1kb @ factor 10
$p{LEFT_REP_WIDTH} = int($p{LEFT_REPEAT} / $p{FACTOR});
$p{LEFT_DATA_MARGIN} = $p{LEFT_MARGIN} + $p{LEFT_REP_WIDTH};
#Right Freedom Data: amount of data that will repeat on the next line
$p{RIGHT_REPEAT} = $p{RIGHT_REPEAT} ? $p{RIGHT_REPEAT} : 1000; # 1000 = 1kb @ factor 10
$p{RIGHT_REP_WIDTH} = int($p{RIGHT_REPEAT} / $p{FACTOR});
#Scale Height and Width
$p{SCALE_HEIGHT} = 150;
$p{SCALE_WIDTH} = int($p{LEVEL_WIDTH} / $p{FACTOR}) + $p{LEFT_REP_WIDTH} + $p{RIGHT_REP_WIDTH};
$p{SCALE_LENGTH} = $p{SCALE_WIDTH}-$p{RIGHT_REP_WIDTH}-$p{LEFT_REP_WIDTH};
#intial feature y position and y distance between W/C strands
$p{STRAND_Y_POS} = 245;
$p{STRAND_DISTANCE} = 70;
$p{FEAT_RGB} = parse_colors();
$p{U_BIG_SCALE_MARK} = ceil(.2*$p{LEVEL_WIDTH});
my %drawing = ("stop_retained_variant" => 1, "CDS" => 1, "PCR_product" => 1,
"centromere" => 1, "ARS" => 1, "restriction_enzyme_recognition_site" => 1,
"enzyme_recognition_site" => 1,
"site_specific_recombination_target_region" => 1, "intron" => 1,
"repeat_family" => 1, "universal_telomere_cap" => 1, "deletion" => 1);
my %labeling = ("gene" => 1, "centromere" => 1, "ARS" => 1);
my %legending = (
"stop_retained_variant" => "stop swap",
"PCR_product" => "PCRTag amplicon",
"ARS" => "ARS",
"intron" => 0, "centromere" => 0,
"universal_telomere_cap" => "Telomere seed sequence",
"site_specific_recombination_target_region" => "loxPsym site",
"repeat_family" => 0,
"deletion" => 0,
"CDS" => 0
);
################################################################################
################################### Drawing ####################################
################################################################################
my $width = int($p{LEFT_MARGIN} + $p{RIGHT_MARGIN} + $p{SCALE_WIDTH});
my $height = ceil(($p{DATAEND} - $p{DATASTART}) / $p{LEVEL_WIDTH}) * $p{LEVEL_HEIGHT};
my $filename = $chr->name . ".pdf";
my $outputloc = $filename;
my $surface = Cairo::PdfSurface->create($outputloc, $width, $height)
|| croak "$OS_ERROR";
my $ctx = Cairo::Context->create($surface);
#Set fonts
my $fonts = parse_fonts();
my $fontfile = $fonts->{Inconsolata};
my $ftfont = Font::FreeType->new->face($fontfile);
my $fontface = Cairo::FtFontFace->create($ftfont);
$ctx->set_font_face($fontface);
my $fontsize = 500 / $p{FACTOR};
$fontsize = 7 if ($fontsize < 7);
$ctx->set_font_size($fontsize);
#Draw white background
$ctx->set_source_rgb(1, 1, 1);
$ctx->rectangle(0, 0, $width, $height);
$ctx->fill;
#Draw backbone and scale marks
$p{LEVEL_COUNT} = draw_scale($ctx, \%p);
$ctx->set_line_width(5);
#Draw name of file
$ctx->save();
my $thref = $ctx->text_extents($chr->name);
$ctx->move_to($p{LEFT_MARGIN} / 2, $height / 2 + ($thref->{width} / 2));
$ctx->rotate(-1.57079633);
$ctx->show_text($chr->name);
$ctx->restore();
#length of the Last level
my $LastScaleMidLen = fmod(($p{DATAEND} - $p{DATASTART}), $p{LEVEL_WIDTH}) / $p{FACTOR};
#Set font Size for other feature (Restriction Enzymes)
my $fontSize = 450 / $p{FACTOR};
$fontSize = 20 if ($fontSize < 20);
$ctx->set_font_size ($fontSize);
$p{FEATURES} = {};
bin/BS_Cartoonist.pl view on Meta::CPAN
if ($i == $p{LEVEL_COUNT})
{
$midEnd = $p{LEFT_DATA_MARGIN} + $LastScaleMidLen;
$rightEnd = $p{LEFT_DATA_MARGIN} + $LastScaleMidLen + $p{RIGHT_REP_WIDTH};
}
$obj->{DrawStart} = $obj->{scaledStart} - ($i - $obj->{LevelNumStart}) * $p{SCALE_LENGTH};
$obj->{DrawEnd} = $obj->{scaledEnd} + ($obj->{LevelNumEnd} - $i) * $p{SCALE_LENGTH};
$obj->{LevelNum} = $i;
#Draw left freedom dashed,
if ($obj->{DrawStart} <= $p{LEFT_DATA_MARGIN})
{
draw_feature($ctx, $obj, $p{LEFT_MARGIN}, $p{LEFT_DATA_MARGIN}, 1, \%p);
}
#Draw middle solid
if ($obj->{DrawStart} <= $midEnd) #&& $obj->{DrawEnd} >= $p{LEFT_DATA_MARGIN}
{
draw_feature($ctx, $obj, $p{LEFT_DATA_MARGIN}, $midEnd, 0, \%p);
}
#Draw right freedom dashed
if ($obj->{DrawEnd} >= $midEnd || $obj->{LevelNumStart} > $i)
{
draw_feature($ctx, $obj, $midEnd, $rightEnd, 1, \%p);
}
}
}
$surface->flush();
$surface->finish();
#Draw Labels and Key
my $lloc = q{./} . $chr->name . "_key.pdf";
my $lsurface = Cairo::PdfSurface->create($lloc, $width, $height) || croak $OS_ERROR;
my $key = Cairo::Context->create($lsurface);
$key->set_font_face($fontface);
$key->set_font_size ($fontSize);
my @labellist = grep {exists $labeling{$_->primary_tag}} @labels;
my $y = 200;
my $x = 500;
#Draw Feature Labels
foreach my $feat (sort {$a->start <=> $b->start} @labellist)
{
my $text = $feat->Tag_load_id;
my $thref = ($key->text_extents($text));
if ($x + $thref->{width} > $width)
{
$x = 500;
$y = $y+100;
}
my $tx = $x - $thref->{width}/2;
$key->move_to($tx, $y);
$key->show_text($text);
$y = ($x+(2*$thref->{width}) > $width - 500) ? $y+100 : $y + 2;
$x = ($x+(2*$thref->{width}) > $width - 500) ? 500 : $x+(2*$thref->{width});
}
#Draw Key
$x = 500;
$y += 100;
foreach my $type (grep {exists $legending{$_}} keys %index)
{
print "got a $type!\n";
my %objs;
if ($type eq 'CDS')
{
my @CDSes = @{$index{$type}};
if ($CDSes[0]->{feat}->has_tag('essential_status') && $CDSes[0]->{feat}->has_tag('orf_classification'))
{
$objs{"essential ORF"} = first {$_->{feat}->Tag_essential_status eq "Essential"} @{$index{$type}};
$objs{"slow growth ORF"} = first {$_->{feat}->Tag_essential_status eq "fast_growth"} @{$index{$type}};
$objs{"non-essential ORF"} = first {$_->{feat}->Tag_orf_classification eq "Verified"} @{$index{$type}};
$objs{"uncharacterized ORF"} = first {$_->{feat}->Tag_orf_classification eq "Uncharacterized"} @{$index{$type}};
$objs{"dubious ORF"} = first {$_->{feat}->Tag_orf_classification eq "Dubious"} @{$index{$type}};
}
else
{
$objs{"ORF"} = $CDSes[0];
}
}
else
{
$objs{$type} = first {1} @{$index{$type}};
}
foreach my $text (keys %objs)
{
my $xywref = [$x, $y, 50];
my $obj = $objs{$text};
$text = $legending{$type} if ($legending{$type});
print "keying $text\n";
my $thref = ($key->text_extents($text));
my $xbeg = $p{LEFT_MARGIN};
my $xend = $p{LEFT_DATA_MARGIN} + $LastScaleMidLen + $p{RIGHT_REP_WIDTH};
draw_feature($key, $obj, $xbeg, $xend, 0, \%p, $xywref);
$key->move_to($x + 50 + ($thref->{width} / 2), $y);
$key->show_text($text);
$y = $y + 100;
$x = 500;
}
}
$lsurface->flush();
$lsurface->finish();
print "See " . q{./} . $chr->name . ".pdf\n\n";
exit;
__END__
=head1 NAME
BS_Cartoonist.pl
=head1 VERSION
Version 2.10
=head1 DESCRIPTION
This utility takes a chromosome from the BioStudio genome repository and makes
a vector image of its annotations.
=head1 ARGUMENTS
Required arguments:
-C, --CHROMOSOME : The chromosome to be rendered. Must be in the BioStudio
genome repository.
Optional arguments:
-F, --FACTOR : [def 10] The factor by which data will be scaled. Must be at
least 2 - do you really want a 1:1 diagram of a chromosome?
-L, --LEVELWIDTH : [def 50000] The bases represented per level of the diagram.
A width of 50000 with a scaling factor of 10 will result in an image about
5000 pixels wide.
--REPEATLEFT : [def 1000] The number of bases from the previous level of the
diagram that will be repeated in dashed lines, on the next level.
--REPEATRIGHT : [def 1000] The number of bases at the end of each level of the
diagram that will be repeated in dashed lines, on the next level.
--START : [def 1] The first base to be displayed in the diagram. If it is not
less than the length and equal to or greater than 1, it will default to 1.
--STOP : [def chromosome length] The last base to be displayed in the
diagram. If this number is larger than the length of the chromosome, it
will default to chromosome length.
-h, --help : Display this message
=head1 COPYRIGHT AND LICENSE
( run in 0.644 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )