#!/usr/local/bin/perl # COPYRIGHT NOTICE $TITLE = 'FramePlot'; $VERSION = '2.3'; $COPYRIGHT = '(c) 1996-1999, ISHIKAWA Jun'; $AUTHOR = 'jun@nih.go.jp'; $DATE = '$Date: 1999/06/20 05:11:56 $'; # Permission is hereby granted, free of charge, to use the # software for acadenic purpose and to copy the software provided # that the COPYRIGHT NOTICE remains intact. For commercial use, # you should contact the author for licensing details. The software # is provided "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR # IMPLIED. REDISTRIBUTION NOT PERMITTED. Credit for using this # program must be given in your publication: # # Ishikawa, J. and Hotta, K. FEMS Microbiol. Lett. 174:251-253 (1999) # # REQUIREMENT # # perl version 5.001, 5.003 or later # # fly version 1.6.0 or later # # # INSTALLATION # # 1. Save this file as frameplot.pl, frameplot.cgi, or etc. # Any filename is acceptable, because it is referred # by SCRIPT_NAME environment variable. # 2. Specify following paths: # # Where is your fly binary? $flyprog = "/usr/local/bin/fly"; # Where output image should go $outpath = "/usr/local/apache/share/htdocs/frameplot"; # URL for $outpath $outurl = "/frameplot"; #------------ No further configuration required ----------------- $DEBUG = 0; # 0, 1, or 2 $LOGGING = 0; # 0 or 1 $outfilename = "frame$$.gif"; $bgcolor = "#eeeeff"; $HelpDoc = "http://www.nih.go.jp/~jun/research/frameplot/help.html"; # Timeout: generate SIGALRM after 30 min. alarm(1800); $SIG{'INT'}=$SIG{'TERM'}=$SIG{'STOP'}=$SIG{'QUIT'}=$SIG{'ALRM'} = 'stop'; # clean $PATH for $path (split /:/, $ENV{PATH}) { push @safepath, $path unless (/sbin|etc/oi); } $ENV{PATH} = join ":", @safepath; if ($ENV{'REQUEST_METHOD'} eq "POST") { &getdata; if ($FORM{'x'} && $FORM{'y'}) { ¶m; &feature(split /:/, &findorf(&xy2pos($FORM{'x'}, $FORM{'y'}))); } elsif ($FORM{'orf'}) { &feature(split /:/, $FORM{orf}); } elsif ($FORM{'remove'}) { &removeresult; } else { ¶m; &cook; &drawimage; &resultpage; } } else { &mainpage; } exit; # SUBROUTINES sub getdata { $DEBUG and $StartTime = time; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); %FORM = &cgiparse($buffer); } $FORM{'sequence'} =~ tr/a-z/A-Z/; # convert case $FORM{'sequence'} =~ tr/U/T/; # substitute T for U $FORM{'sequence'} =~ tr/A-Z//cd; # remove non-alphabetical chars $seq = $FORM{'sequence'}; } sub param { @start = @cstart = @orf = @corf = {}; $FORM{'label'} =~ s/[\n\r]/ /go; $seqlen = length($seq); # sequence length (nucleotides) $winlen = $FORM{'window'} * 3; # window length (nucleotides) $steplen = $FORM{'step'} * 3; # step lenth (nucleotides) $minorf = $FORM{'minorf'} * 3; # minimum ORF size (nucleotides) $seqmod3 = $seqlen % 3; # if ($FORM{'width'} =~ /auto/io) { my $buffer = int($seqlen / 4.5); if ($buffer <= 300) { $graphsize{'width'} = 300; # minimum graph size } elsif ($buffer > 7000) { $graphsize{'width'} = 7000; # maximum graph size } else { $graphsize{'width'} = $buffer; } } else { $graphsize{'width'} = $FORM{'width'}; } $graphsize{'height'} = 200; %margin = (left => 20, right => 20, top => 160, bottom => 20); %imagesize = (width => $margin{left}+$graphsize{width}+$margin{right}, height => $margin{top}+$graphsize{height}+$margin{bottom}); # time stamp my($wday, $month, $day, $time, $year) = split /\s+/, localtime; $timestamp = "$month $day $time $year"; $today = "$day-$month-$year"; } sub cook { my($found,$codon,$frame,$pos,$count,$i,$j,@gcmark,$flag); # indexing G/C position (from camel book:-) for $lookfor ("G","C","S") { $pos = -1; while (($pos = index($seq, $lookfor, $pos)) > -1) { $gcmark[$pos]++; # faster than hash $pos++; } } # Average GC% ($DEBUG > 1) and $AvGCStartTime = time; $count = $seq =~ tr/GCS/GCS/; # the fastest method I think:-) $avgc = sprintf("%4.1f", ($count / $seqlen) * 100); ($DEBUG > 1) and $AvGCEndTime = time; # 3rd-letter GC% ($DEBUG > 1) and $ThirdGCStartTime = time; for $frame (0 .. 2) { for ($i = $frame; $i < $seqlen - $winlen; $i += $steplen) { $count = 0; for ($j = $i + 2; $j < $i + $winlen; $j += 3) { $count++ if $gcmark[$j]; } push @{$gc[$frame]}, $count / $FORM{window} * 100; } } ($DEBUG > 1) and $ThirdGCEndTime = time; # Normal strand ($DEBUG > 1) and $NormalStartTime = time; if ($FORM{incorf} eq "ON") { # virtual start codon for $i (1 .. 3) { my $c = substr($seq, $i-1, 3); push @{$start[$i]}, $i unless $FORM{$c} || $c =~ /(TGA|TAG|TAA)/; } } # start codon push @codons, "ATG" if $FORM{'ATG'}; push @codons, "GTG" if $FORM{'GTG'}; push @codons, "TTG" if $FORM{'TTG'}; push @codons, "ATT" if $FORM{'ATT'}; push @codons, "CTG" if $FORM{'CTG'}; push @codons, "ATG" unless $FORM{'ATG'} || $FORM{'GTG'} || $FORM{'TTG'} || $FORM{'ATT'} || $FORM{'CTG'}; for $codon (@codons) { $pos = -1; while (($pos = index($seq, $codon, $pos)) > -1) { push @{$start[$pos % 3 +1]}, $pos + 1; $pos++; } } # stop codon for $codon ("TGA","TAG","TAA") { $pos = -1; while (($pos = index($seq, $codon, $pos)) > -1) { push @{$stop[$pos % 3 +1]}, $pos + 1; $pos++; } } if ($FORM{incorf} eq "ON") { # virtual stop codon for $i (($seqlen-5) .. ($seqlen-3)) { my $c = substr($seq, $i-1, 3); push @{$stop[$i % 3 + 1]}, $i + 1 unless $FORM{$c} || $c =~ /(TGA|TAG|TAA)/; } } ($DEBUG > 1) and $NormalEndTime = time; # Complementary ($DEBUG > 1) and $ComplStartTime = time; # start codon push @ccodons,"CAT" if $FORM{'ATG'}; push @ccodons,"CAC" if $FORM{'GTG'}; push @ccodons,"CAA" if $FORM{'TTG'}; push @ccodons,"AAT" if $FORM{'ATT'}; push @ccodons,"CAG" if $FORM{'CTG'}; push @ccodons,"CAT" unless $FORM{'ATG'} || $FORM{'GTG'} || $FORM{'TTG'} || $FORM{'ATT'} || $FORM{'CTG'}; if ($FORM{incorf} eq "ON") { # virtual start codon for $i (($seqlen-5) .. ($seqlen-3)) { my $c = substr($seq, $i, 3); $flag = 0; for (@ccodons, "TCA", "CTA", "TTA") { $flag = 1 if /$c/; } push @{$cstart[&frameadjust((($i + 2) % 3) + 1)]}, $i + 3 unless $flag; } } for $codon (@ccodons) { $pos = -1; while (($pos = index($seq, $codon, $pos)) > -1) { push @{$cstart[&frameadjust((($pos + 2) % 3) + 1)]}, $pos + 3; $pos++; } } # stop codon for $codon ("TCA","CTA","TTA") { $pos = -1; while (($pos = index($seq, $codon, $pos)) > -1) { push @{$cstop[&frameadjust((($pos + 2) % 3) + 1)]}, $pos + 3; $pos++; } } if ($FORM{incorf} eq "ON") { # virtual stop codon for $i (1 .. 3) { my $c = substr($seq, $i, 3); $flag = 0; for (@ccodons, "TCA", "CTA", "TTA") { $flag = 1 if /$c/; } push @{$cstop[&frameadjust((($i + 2) % 3) + 1)]}, $i + 3 unless $flag; } } for $frame (1 .. 3) { # sort by number for $i ("start","stop") { @{$$i[$frame]} = sort { $a <=> $b } @{$$i[$frame]}; } # sort by number (reverse) for $i ("cstart","cstop") { @{$$i[$frame]} = sort { $b <=> $a } @{$$i[$frame]}; } } ($DEBUG > 1) and $ComplEndTime = time; $DEBUG and $CookTime = time; } # end of cook sub drawimage { my($frame,$showflag,$pos,$i,$j,$x,$y,$x1,$x2,$y1,$y2); my $lm = 20; open(FLY,"| $flyprog -q -o $outpath/$outfilename"); print FLY "new\n"; print FLY "size $imagesize{'width'},$imagesize{'height'}\n"; # color definition $red = "255,0,0"; $green = "0,127,0"; $blue = "0,0,255"; $black = "0,0,0"; $white = "255,255,255"; if ($FORM{'color'} =~ /^c/io) { $BW = 0; @linecolor = ("$red", "$green", "$blue"); @clinecolor = ("$green", "$red", "$blue") if ($seqmod3 == 0); @clinecolor = ("$blue", "$green", "$red") if ($seqmod3 == 1); @clinecolor = ("$red", "$blue", "$green") if ($seqmod3 == 2); } else { $BW = 1; @linecolor = ("$black", "$black", "$black" ); @clinecolor = ("$black", "$black", "$black" ); my $style0 = "$black,$black"; my $style1 = "$black,$black,$black,$white,$white,$white"; my $style2 = "$black,$white,$white"; %linestyle = ( 0 => "$style0", 1 => "$style1", 2 => "$style2" ); %clinestyle = ( 0 => "$style1", 1 => "$style0", 2 => "$style2" ) if ($seqmod3 == 0); %clinestyle = ( 0 => "$style2", 1 => "$style1", 2 => "$style0" ) if ($seqmod3 == 1); %clinestyle = ( 0 => "$style0", 1 => "$style2", 2 => "$style1" ) if ($seqmod3 == 2); } print FLY "fill 1,1,$white\n"; print FLY "string $black,$lm,5,medium,$TITLE $VERSION - $COPYRIGHT\n"; print FLY "string $black,$lm,18,small,", "FEMS Microbiol. Lett. 174:251-253 (1999)\n"; print FLY "string $black,$lm,31,medium,", "Target: $FORM{'label'} $seqlen bp; ", "$avgc% G+C (dashed line)\n"; print FLY "string $black,$lm,44,medium,", "Window: $FORM{'window'}, ", "Step: $FORM{'step'}, ", "Start codon [>]: @codons \n"; print FLY "string $black,$lm,57,medium,", "Minimum ORF: $FORM{'minorf'}, ", "Date: $timestamp\n"; # draw graph $x1 = $margin{'left'}; $y1 = $margin{'top'}; $x2 = $margin{'left'} + $graphsize{'width'}; $y2 = $margin{'top'} + $graphsize{'height'}; print FLY "rect $x1,$y1,$x2,$y2,$black\n"; # X axis for ($i = 100; $i < $seqlen; $i += 100) { $x1 = &xcoord($i); if (($i % 500) == 0) { $y1 = &ycoord(4); } else { $y1 = &ycoord(2); } $y2 = &ycoord(0); print FLY "line $x1,$y1,$x1,$y2,$black\n"; if (($i % 1000) == 0) { $x = $x1 - 10; $y = $margin{'top'} + $graphsize{'height'} + 5; print FLY "string $black,$x,$y,small,$i\n"; } } # Y axis $x = $margin{'left'} - 18 ; $y = &ycoord(45); print FLY "stringup $black,$x,$y,small,G+C(%)\n"; for ($i = 10; $i < 100; $i += 10) { $x1 = &xcoord(0); $y1 = &ycoord($i); if ($i == 50) { $x2 = $x1 + 6; } else { $x2 = $x1 + 3; } print FLY "line $x1,$y1,$x2,$y1,$black\n"; } # draw average GC% $x1 = &xcoord(0); $x2 = &xcoord($seqlen); $y1 = &ycoord($avgc); print FLY "dline $x1,$y1,$x2,$y1,$black\n"; # plot 3rd-letter GC% for $frame (0 .. 2) { print FLY "setstyle $linestyle{$frame}\n" if ($BW); for $i (0 .. ($#{$gc[$frame]} - 1)) { $x1 = &xcoord((($i * 3) * $FORM{step}) + ($winlen / 2)); $y1 = &ycoord($gc[$frame][$i]); $x2 = &xcoord(((($i+1) * 3) * $FORM{step}) + ($winlen / 2)); $y2 = &ycoord($gc[$frame][$i+1]); print FLY "line $x1,$y1,$x2,$y2,@linecolor[$frame]\n"; } print FLY "killstyle\n" if ($BW); } # Start/Stop codon and ORF for $frame (0 .. 2) { # Normal Strand # frame label $x = 4; $y = ($margin{'top'} - 80) + $frame * 12; $c = @linecolor[$frame]; print FLY "string $c,$x,$y,small,",$frame+1,":\n"; # start codon my $prevstop = 0; for $start (@{$start[$frame+1]}) { $x = &xcoord($start) - 5; $y = ($margin{'top'} - 80) + $frame * 12; print FLY "string $c,$x,$y,medium,>\n" if $FORM{substr $seq, $start-1, 3}; # ORF print FLY "setstyle $linestyle{$frame}\n" if ($BW); for $stop (@{$stop[$frame+1]}) { if ($stop > $start) { last if (($stop - $start) <= $minorf); push @{$orf[$frame+1]}, "$start:$stop"; if ($stop > $prevstop) { $x1 = &xcoord($start); $x2 = &xcoord($stop); $y += 6; print FLY "line $x1,$y,$x2,$y,$c\n"; $prevstop = $stop; } last; } } print FLY "killstyle\n" if ($BW); } # stop codon for $stop (@{$stop[$frame+1]}) { $x = &xcoord($stop) - 3; $y = ($margin{'top'} - 80) + $frame * 12; print FLY "string $c,$x,$y,medium,|\n" if substr($seq, $stop-1, 3) =~ /(TGA|TAG|TAA)/; } # Complementary Strand # frame label $x = 4; $y = ($margin{'top'} - 40) + $frame * 12; $c = @clinecolor[$frame]; print FLY "string $c,$x,$y,small,",$frame+1,":\n"; # strat codon my $showflag = 0; my $cdn = substr($seq, $cstart[$frame+1][0]-3, 3); for (@ccodons) { $showflag = 1 if /$cdn/; } my $prevstop = $seqlen; for $start (@{$cstart[$frame+1]}) { $x = &xcoord($start); $y = ($margin{'top'} - 40) + $frame * 12; $showflag ? print FLY "string $c,$x,$y,medium,<\n" : ($showflag = 1); # ORF print FLY "setstyle $clinestyle{$frame}\n" if ($BW); for $stop (@{$cstop[$frame+1]}) { if ($stop < $start) { last if (($start - $stop) <= $minorf); push @{$corf[$frame+1]}, "$start:$stop"; if ($stop < $prevstop) { $x1 = &xcoord($start); $x2 = &xcoord($stop); $y += 6; print FLY "line $x1,$y,$x2,$y,$c\n"; $prevstop = $stop; } last; } } print FLY "killstyle\n" if ($BW); } # stop codon for $stop (@{$cstop[$frame+1]}) { $x = &xcoord($stop) - 2; $y = ($margin{'top'} - 40) + $frame * 12; print FLY "string $c,$x,$y,medium,|\n" if substr($seq, $stop-3, 3) =~ /(TCA|CTA|TTA)/; } } print FLY "interlace\n"; close(FLY); $DEBUG and $DrawTime = time; } # end of drawimage sub resultpage { my($frame,$array); print <<"HTML"; Content-Type: text/html Result HTML print <<"HTML"; Click to show sequence of ORF.
HTML for $i ("orf","corf") { for $frame (1 .. 3) { $array = join("", $i, $frame); my $orfs; for $j (@{$$i[$frame]}) { $orfs .= "$j "; } print "\n"; } } print "
\n"; print <<"HTML"; Graph plotting done with Fly, by Martin Gleeson.
Your result ($outfilename) still remains on our server. Before leaving from this page, click button to remove it (highly recommended).
HTML print <<"HTML";
Normal
Frame Start codon
(@codons)
Stop codon
(TGA TAG TAA)
ORF
(Start:Stop) HTML for $frame (1 .. 3) { print "
$frame\n"; for $item ("start","stop") { print " @{$$item[$frame]}
\n"; } print "
\n"; for $i (@{$orf[$frame]}) { print "\t$i\n"; } print "
\n"; } print <<"HTML";
Complementary
Frame Start codon
(@codons)
Stop codon
(TGA TAG TAA)
ORF
(Start:Stop) HTML for $frame (1 .. 3) { print "
$frame\n"; for $item ("cstart","cstop") { print " @{$$item[$frame]}
\n"; } print "
\n"; for $i (@{$corf[$frame]}) { print "\t$i\n"; } print "
\n"; } print <<"HTML";

Numbers denote the 1st-letter position of each codon.
HTML # DEBUG messages if ($DEBUG) { $EndTime = time; print "Total=",$EndTime-$StartTime; print " [", int($seqlen/($EndTime-$StartTime)), " bases/sec]: "; print "Cook=",$CookTime-$StartTime; if ($DEBUG > 1) { print "("; print "AvGC=",$AvGCEndTime-$AvGCStartTime,"/"; print "3rdGC=",$ThirdGCEndTime-$ThirdGCStartTime,"/"; print "Nrml=",$NormalEndTime-$NormalStartTime,"/"; print "Cmpl=",$ComplEndTime-$ComplStartTime; print ")"; } print "/Draw=",$DrawTime-$CookTime; } if ($LOGGING) { open(LOG, ">>$outpath/frameplot.log"); print LOG "VERSION: $VERSION\n"; print LOG "REMOTE_HOST: $ENV{REMOTE_HOST}\n"; print LOG "REMOTE_ADDR: $ENV{REMOTE_ADDR}\n"; print LOG "HTTP_USER_AGENT: $ENV{HTTP_USER_AGENT}\n"; print LOG "TIME: $timestamp\n"; print LOG "UTC: ",time,"\n"; print LOG "SEQ_LEN: $seqlen\n"; print LOG "STEP: $FORM{'step'}\n"; print LOG "SEQ_LABEL: $FORM{'label'}\n"; print LOG "OUT_IMAGE: $outfilename\n"; $DEBUG and print LOG "RATE: ", int($seqlen/($EndTime-$StartTime))," base/sec\n"; print LOG "\n"; close(LOG); } } # end of resultpage sub removeresult { unlink "$outpath/$FORM{remove}"; print <<"HTML"; Content-Type: text/html Remove Result

Your result ($FORM{'remove'}) was removed.

After clearing the memory cache of your browser, you can confirm the removal of your data by clicking above link.

[Back to the main page]

HTML } sub findorf { my($frame, $pos) = @_; my($start, $end, $hit); if (1 <= $frame && $frame <= 3) { # Normal my @array = split /\s+/, $FORM{"orf$frame"}; for (reverse @array) { ($start, $end) = split /:/; if ($start <= $pos && $pos <= $end) { $hit = 1; last; } } } elsif (4 <= $frame && $frame <= 6) { # Complementary $frame = $frame - 3; my @array = split /\s+/, $FORM{"corf$frame"}; for (reverse @array) { ($start, $end) = split /:/; if ($start >= $pos && $pos >= $end) { $hit = 1; last; } } } $hit ? return "$start:$end:$frame" : return 0; } sub feature { my($start, $end, $frame) = @_; my($nucl, $peptide, $nucheader, $pepheader, $nuclen, $peplen); print "Content-Type: text/html\n\n"; print "Featuers\n"; print "\n"; unless ($frame) { print "No ORF here."; exit; } if ($start < $end) { $nucl = substr($seq, $start-1, $end-$start+3); $nuclen = length($nucl); $nucheader = ">$FORM{label} f$frame ($start. ." . ($end+2) . ")\t" . $nuclen . "bp\t$today"; $peptide = substr($seq, $start-1, $end-$start); $peptide = &translate($peptide); $peplen = length($peptide); $pepheader = ">$FORM{label} f$frame ($start. ." . ($end-1) . ")\t" . $peplen . " aa\t$today"; } elsif ($start > $end) { $nucl = substr($seq, $end-3, $start-$end+3); $nucl = &complement($nucl); $nuclen = length($nucl); $nucheader = ">$FORM{label} f${frame}c ($start. ." . ($end-2) . ")\t" . $nuclen . " bp\t$today"; $peptide = substr($seq, $end, $start-$end); $peptide = &complement($peptide); $peptide = &translate($peptide); $peplen = length($peptide); $pepheader = ">$FORM{label} f${frame}c ($start. ." . ($end+1) . ")\t" . $peplen . " aa\t$today"; } # base composition %basecomposit = &basecomposit($nucl); # 3rd letter GC% $gc3rd = &gc3rd($nucl); # features print "

FEATURES

\n"; print "\n"; print "
3rd-Letter GC:$gc3rd%\n"; print "
Base Composition:$basecomposit{A} A $basecomposit{C} C $basecomposit{G} G $basecomposit{T} T\n"; print "
\n"; print "

\n\n"; # nucleotide print "
"; print "
\n", &fasta($nucl, $nucheader),"
\n"; print "
"; &NCBI_BLAST(&fasta($nucl, $nucheader), "nucleotide"); # peptide print "
"; print "
\n", &fasta($peptide, $pepheader), "
\n"; print "
"; &NCBI_BLAST(&fasta($peptide, $pepheader), "peptide"); print "
"; print "


\n"; print "\n"; print ""; print "What is the BLAST 2.0\n"; print "\n"; } # end of feature sub basecomposit { my $nucl = $_[0]; my %cmpst; $cmpst{A} = $nucl =~ tr/A/A/; $cmpst{C} = $nucl =~ tr/C/C/; $cmpst{G} = $nucl =~ tr/G/G/; $cmpst{T} = $nucl =~ tr/T/T/; return %cmpst; } sub gc3rd { # 3rd letter GC% my $nucl = $_[0]; my $nuclen = length($nucl); my($c, $i); for ($i = 2; $i < $nuclen; $i += 3) { $_ = substr $nucl, $i, 1; $c++ if /[GC]/o; } return sprintf "%4.1f", ($c / ($nuclen / 3)) * 100; } sub complement { my $sequence = $_[0]; $sequence =~ tr [AGCT] [TCGA]; my $complement = reverse $sequence; return $complement; } sub translate { my(@peptide,$i,$a); my $temp = join "", @_; return "Sequence is not multiples of 3" unless ((length($temp) % 3) == 0); my %univcode = ( TTT => "F", TCT => "S", TAT => "Y", TGT => "C", TTC => "F", TCC => "S", TAC => "Y", TGC => "C", TTA => "L", TCA => "S", TAA => "*", TGA => "*", TTG => "L", TCG => "S", TAG => "*", TGG => "W", CTT => "L", CCT => "P", CAT => "H", CGT => "R", CTC => "L", CCC => "P", CAC => "H", CGC => "R", CTA => "L", CCA => "P", CAA => "Q", CGA => "R", CTG => "L", CCG => "P", CAG => "Q", CGG => "R", ATT => "I", ACT => "T", AAT => "N", AGT => "S", ATC => "I", ACC => "T", AAC => "N", AGC => "S", ATA => "I", ACA => "T", AAA => "K", AGA => "R", ATG => "M", ACG => "T", AAG => "K", AGG => "R", GTT => "V", GCT => "A", GAT => "D", GGT => "G", GTC => "V", GCC => "A", GAC => "D", GGC => "G", GTA => "V", GCA => "A", GAA => "E", GGA => "G", GTG => "V", GCG => "A", GAG => "E", GGG => "G", ); # push @peptide, "M"; # for ($i = 3; $i < length($temp); $i += 3) { for ($i = 0; $i < length($temp); $i += 3) { if ($univcode{substr($temp, $i, 3)}) { $a = $univcode{substr($temp, $i, 3)}; } else { $a = "X"; } push @peptide, $a; } return join "", @peptide; } sub fasta { # FASTA format my($sequence, $header) = @_; my @chars = split('',$sequence); my $result .= "$header\n"; my $counter = 0; for $char (@chars) { $result .= "$char"; $counter++; if ($counter == 50) { # 50 column per line $counter = 0; $result .= "\n"; } } $result .= "\n"; return $result; } sub xcoord { my $x = $margin{left} + ($graphsize{width} / $seqlen * $_[0]) ; return $x; } sub ycoord { my $y = ($margin{top} + $graphsize{height}) - (($graphsize{height} / 100) * $_[0]) ; return $y; } sub xy2pos { my($x, $y) = @_; # y to frame my $frame = ($y - ($margin{'top'} - 80)) / 12; $frame = int($frame+1); # x to nucleotide position my $pos = ($x - $margin{left}) / ($graphsize{width} / $seqlen); $pos = int($pos); return ($frame, $pos); } sub frameadjust { if ($seqmod3 == 0) { return 3 if $_[0] == 1; return 2 if $_[0] == 2; return 1 if $_[0] == 3; } elsif ($seqmod3 == 1) { return 1 if $_[0] == 1; return 3 if $_[0] == 2; return 2 if $_[0] == 3; } elsif ($seqmod3 == 2) { return 2 if $_[0] == 1; return 1 if $_[0] == 2; return 3 if $_[0] == 3; } } sub cgiparse { # parse CGI parameters my(%form,$name,$value,@pairs); @pairs = split(/&/,$_[0]); for (@pairs) { ($name, $value) = split /=/; $value =~ tr/\+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $form{$name} = $value; } return %form; } sub stop { unlink("$outpath/$outfilename"); exit 1; } sub NCBI_BLAST { my $URLBASE = "http://www.ncbi.nlm.nih.gov"; my $progs; if ($_[1] =~ /^n/io) { $progs = "