| // | Your Name | // +----------------------------------------------------------------------+ // // /** * The class panel is very useful to draw an object sequence and associated features * (for the moment nucleotidic sequence). Part of the code is very similar to Bioperl * code that I read to have a starting point. */ class panel { var $start; var $stop; var $length; var $pad_top; var $pad_bottom; var $pad_left; var $pad_rigth; var $spacebetweentracks; var $scale; var $imagewidth; var $imageheight; var $tracks = array(); var $array_map = array(); var $units = array(); function panel($options) { $this->start = $options[start]; $this->stop = $options[stop]; $this->length = $options[length]; $this->pad_top = $options[pad_top]; $this->pad_bottom = $options[pad_bottom]; $this->pad_left = $options[pad_left]; $this->pad_right = $options[pad_right]; $this->imagewidth = $options[width]; $this->spacebetweentracks = $options[spacebetweentracks]; $this->scale = ($this->imagewidth - $this->pad_left - $this->pad_right) / $this->length; $this->units = array( 'n' => 1e-9, 'u' => 1e-6, 'm' => 0.001, 'c' => 0.01, 'k' => 1000, 'M' => 1000000, 'G' => 1000000000 ); } function add_track($trak) { $this->tracks[] = $trak; } //this function create the image function gd($image_name) { $height = $this->set_height($this->tracks); $width = $this->imagewidth; $y = $this->pad_top; $im = Imagecreate($width, $height); $white = ImageColorAllocate($im, 254, 254, 254); $black = ImageColorAllocate($im, 0, 0, 0); $red_clear = ImageColorAllocate($im, 242, 1919, 113); $red_dark = ImageColorAllocate($im, 192, 18, 10); $red = ImageColorAllocate($im, 247, 46, 38); $brown_clear = ImageColorAllocate($im, 233, 130, 79); $brown = ImageColorAllocate($im, 171, 95, 97); $yellow_clear = ImageColorAllocate($im, 243, 242, 138); $yellow_dark = ImageColorAllocate($im, 211, 229, 8); $yellow = ImageColorAllocate($im, 248, 245, 6); $orange_clear = ImageColorAllocate($im, 243, 205, 122); $orange_dark = ImageColorAllocate($im, 245, 139, 13); $orange = ImageColorAllocate($im, 245, 171, 13); $green_clear = ImageColorAllocate($im, 125, 244, 150); $green_dark = ImageColorAllocate($im, 10, 188, 47); $green = ImageColorAllocate($im, 13, 246, 62); $cyan = ImageColorAllocate($im, 64, 224, 208); $blue_dark = ImageColorAllocate($im, 22, 6, 224); $blue = ImageColorAllocate($im, 0, 0, 255); $rose_clear = ImageColorAllocate($im, 242, 129, 238); $pink = ImageColorAllocate($im, 247, 16, 179); $pink = ImageColorAllocate($im, 242, 11, 234); $gey_clear = ImageColorAllocate($im, 203, 199, 199); $gey_dark = ImageColorAllocate($im, 107, 96, 97); $gey = ImageColorAllocate($im, 169, 156, 158); $purple_clear = ImageColorAllocate($im, 212, 131, 239); $purple_dark = ImageColorAllocate($im, 129, 7, 169); $purple = ImageColorAllocate($im, 184, 17, 239); //draw the tracks foreach($this->tracks as $track) { //this one just write text if($track[type] == 'text') { if($track[position] == 'center') { $lengthtitle = (strlen($track[text])*6) + strlen($track[text]) - 1; $xtitle = ($width - $lengthtitle) / 2; } else { $xtitle = $this->pad_left; } imagestring($im, 4, $xtitle, $y, $track[text], $$track[color]); $y += $this->spacebetweentracks; } //this one draw the scale if($track[type] == 'scale') { //draw the line imageline($im, $this->pad_left, $y, ($this->imagewidth - $this->pad_right) , $y, $black); //draw the heads //lefarrowhead imageline($im, $this->pad_left, $y, $this->pad_left+5 , $y+5, $black); imageline($im, $this->pad_left, $y, $this->pad_left+5 , $y-5, $black); //rightarrowhead imageline($im, ($this->imagewidth - $this->pad_right), $y, ($this->imagewidth - $this->pad_right) - 5 , $y+5, $black); imageline($im, ($this->imagewidth - $this->pad_right), $y, ($this->imagewidth - $this->pad_right) - 5 , $y-5, $black); //First set the units and the divisor $units = $this->calculate_units($this->length); $divisor = $this->units[$units]; //declare the left and rigth limit of the ticks $left = $this->pad_left + 6; $right = $this->imagewidth - $this->pad_right - 6; //calculation of the major interval and the minor interval $biglabel = intval(($this->length / $divisor)) . $units . "b"; $widthbiglabel = (strlen($biglabel)*6) + ((strlen($biglabel) - 1)*2); list($major_interval, $minor_interval) = $this->calculate_intervals($widthbiglabel); //draw the big ticks $first_tick = $major_interval * intval((0.5 + ($this->start/$major_interval))); $last_tick = $major_interval * intval((0.5 + ($this->stop/$major_interval))); for($i = $first_tick; $i <= $last_tick; $i += $major_interval) { //draw the tick $x_tick = $this->pad_left + ($i * $this->scale); if (($x_tick < $left) || ($x_tick > $right)) continue; imageline($im, $x_tick, $y+4, $x_tick, $y-4, $black); //draw the label $label = ($i/$divisor) . $units . "b"; $lengthlabel = (strlen($label)*6) + strlen($label) - 1; $xlabel = $x_tick - ($lengthlabel/2); imagestring($im, 4, $xlabel, $y+6, $label, $black); } //draw the small ticks $first_tick = $minor_interval * intval((0.5 + ($this->start/$minor_interval))); $last_tick = $minor_interval * intval((0.5 + ($this->stop/$minor_interval))); for($i = $first_tick; $i <= $last_tick; $i += $minor_interval) { //draw the tick $x_tick = $this->pad_left + ($i * $this->scale); if (($x_tick < $left) || ($x_tick > $right)) continue; imageline($im, $x_tick, $y+2, $x_tick, $y-2, $black); } $y += $this->spacebetweentracks; } //this one draw the sequence object if($track[type] == 'sequence') { if (isset($track[first_description])) { imagestring($im, 4, $this->pad_left, $y, $track[first_description], $$track[color_first_description]); $y += 15; } imagefilledrectangle($im, $this->pad_left, $y, ($this->imagewidth - $this->pad_right), $y += 8, $$track[color]); if (isset($track[second_description])) { $y += 2; imagestring($im, 4, $this->pad_left, $y, $track[second_description], $$track[color_second_description]); //links for the second description if (ereg("^NT_", $track[second_description])) { $x1 = $this->pad_left; $x2 = $this->pad_left + (strlen($track[second_description])*6) + strlen($track[second_description]) - 1; $y1 = $y; $y2 = $y + 10; $this->array_map[] = ""; } $y += 10; } $y += $this->spacebetweentracks; } //this one draw the mRNA or qualifier features if($track[type] == 'mRNA') { if (isset($track[location])) { //draw the exons if($track[strand] == "minus") $track[location] = array_reverse($track[location]); foreach($track[location] as $exons){//start for list($start_exon,$end_exon) = explode('-', $exons); $xstart_exon = $this->pad_left + ($start_exon * $this->scale); if (!isset($x1links)) $x1links = $xstart_exon; //we use this variable just below $xend_intron = $xstart_exon - 1; $xend_exon = $this->pad_left + ($end_exon * $this->scale); if (isset($xstart_intron) && isset($xend_intron)) { $xmiddle_intron = $xstart_intron + (($xend_intron - $xstart_intron)/2); imageline($im, $xstart_intron , $y+10, $xmiddle_intron, $y, $$track[location_color]); imageline($im, $xmiddle_intron , $y, $xend_intron, $y+10, $$track[location_color]); } $xstart_intron = $xend_exon + 1; imagefilledrectangle($im, $xstart_exon, $y, $xend_exon, $y+20, $$track[location_color]); } //draw the final head_arrow if($track[strand] == "plus") { imageline($im, $xend_exon , $y+10, $xend_exon+10, $y+10, $$track[location_color]); imageline($im, $xend_exon+5, $y+5, $xend_exon+10, $y+10, $$track[location_color]); imageline($im, $xend_exon+5, $y+15, $xend_exon+10, $y+10, $$track[location_color]); } else if($track[strand] == "minus") { imageline($im, $x1links , $y+10, $x1links-10, $y+10, $$track[location_color]); imageline($im, $x1links-5, $y+5, $x1links-10, $y+10, $$track[location_color]); imageline($im, $x1links-5, $y+15, $x1links-10, $y+10, $$track[location_color]); } unset($xstart_intron); //link to the the spidey_result if it exists if($track[spidey]) { $x1 = intval($x1links); $y1 = $y; $x2 = intval($xend_exon+10); $y2 = $y+20; $this->array_map[] = ""; } //draw the accession number $y += 25; imagestring($im, 4, intval($x1links), $y, $track[accession], $$track[accession_color]); //link to the accession number if ($track[accession_link] && (ereg("^[NE][MN][_S]T?", $track[accession]) || ereg("_at", $track[accession])) ) { $x1 = intval($x1links); $x2 = intval($x1links) + (strlen($track[accession])*6) + ((strlen($track[accession]) - 1)*2); $y1 = $y; $y2 = $y + 10; $links = ""; if (ereg("^ENST", $track[accession])) $links .= "href='http://www.ensembl.org/Homo_sapiens/transview?transcript=" . $track[accession] . "&db=core'>"; if (ereg("_at", $track[accession])) $links .= "href='https://www.affymetrix.com/LinkServlet?probeset=" . $track[accession] . "'>"; $this->array_map[] = $links; } $y += $this->spacebetweentracks; unset($x1links); } } } ImagePng($im, $image_name); ImageDestroy($im); } function set_height($track) { $height = $this->pad_top + $this->pad_bottom + (count($track) * $this->spacebetweentracks); foreach($this->tracks as $track) { if($track[type] == 'title') $height += 10; if($track[type] == 'scale') $height += 5; if($track[type] == 'sequence') { $height += 8; if (isset($track[first_description])) $height += 15; if (isset($track[second_description])) $height += 12; } if($track[type] == 'mRNA') $height += 25; } return $height; } function calculate_units($length) { if ($length > 1e9) return 'G'; if ($length > 1e6) return 'M'; if ($length > 1e3) return 'k'; if ($length > 1) return ''; if ($length > 1e-2) return 'c'; if ($length > 1e-3) return 'm'; if ($length > 1e-6) return 'u'; if ($length > 1e-9) return 'n'; } function calculate_intervals($minwidth) { $length = $this->length; $scale = $this->scale; $interval = 1; while(1) { $pixels = $interval * $scale; if ($pixels > $minwidth) break; $interval *= 10; } return array($interval, ($interval/10)); } } ?>