1: <?php
2:
3: namespace webservices\graphs\genome;
4: /**
5: * Return tracks for canvasXpress genome browser
6: * go to http://canvasxpress.org/documentation.html#data , scroll down to "tracks"
7: */
8: class Isoform extends \WebService {
9:
10: /**
11: * returns "right" or "left" depending on $strand>0
12: * @param int $strand
13: * @return String
14: */
15: private static function strand2dir($strand) {
16: return $strand > 0 ? 'right' : 'left';
17: }
18:
19: /**
20: * fill up with two spaces between each char to align protein and nucleotide sequences
21: * canvasXpress SHOULD be able to do that on its own, but fails in its current version
22: * @param String $sequence
23: * @return string
24: */
25: private static function space($sequence) {
26: $ret = "";
27: for ($i = 0; $i < strlen($sequence); $i++)
28: $ret .= $sequence{$i} . ' ';
29: return $ret;
30: }
31:
32: /**
33: * if strand is left, rewind string
34: * @param string $sequence
35: * @param int $strand
36: * @return string
37: */
38: private static function rewinds($sequence, $strand) {
39: if ($strand < 0)
40: return strrev($sequence);
41: return $sequence;
42: }
43:
44: /**
45: * @inheritDoc
46: */
47: public function execute($querydata) {
48: global $db;
49:
50: #UI hint
51: if (false)
52: $db = new \PDO();
53:
54: $stm_get_features = $db->prepare('SELECT * FROM get_isoform_graph(?)');
55: $stm_get_features->execute(array($querydata['query1']));
56:
57: $return = array();
58: $min = 0;
59: $max = 0;
60:
61: $last_row = null;
62:
63: //before reading this code, read the canvasXpress documentation!
64:
65: //(feature_id int, type_id int, residues text, seqlen int, fmin int, fmax int, strand smallint);
66: while ($row = $stm_get_features->fetch(\PDO::FETCH_ASSOC)) {
67: switch ($row['type_id']) {
68: case CV_ISOFORM:
69: $max = $row['seqlen'];
70: $return[] = array(
71: #'name' => 'Isoform',
72: 'type' => 'sequence',
73: 'subtype' => 'DNA',
74: 'data' => array(array(
75: 'id' => $row['name'],
76: 'sequence' => $row['residues'],
77: 'translate' => array(-1, 3),
78: 'dir' => 'right',
79: 'offset' => 1
80: ))
81: );
82: break;
83: case CV_ANNOTATION_REPEATMASKER:
84: // this would look better, but canvasXpress cuts datasets after 8 rows so each bar has to be it's own dataset
85: //if (!isset($return['repeatmasker'])) {
86: $return[] = array(
87: #'name' => 'Repeatmasker',
88: 'type' => 'box',
89: 'fill' => 'rgb(255,25,51)',
90: 'outline' => 'rgb(0,0,0)',
91: 'data' => array()
92: );
93: $current_repeatmasker = &$return[count($return)-1];
94: //}
95:
96: $current_repeatmasker['data'][] = array(
97: 'id' => $row['name'],
98: 'data' => array(array($row['fmin'], $row['fmax'])),
99: 'dir' => self::strand2dir($row['strand'])
100: );
101: break;
102: case CV_PREDPEP:
103: $last_predpep_row = $row;
104: $return[] = array(
105: #'name' => 'Predicted Peptides',
106: 'type' => 'sequence',
107: 'subtype' => 'DNA',
108: 'fill' => 'rgb(255,255,51)',
109: 'outline' => 'rgb(0,0,0)',
110: 'data' => array(array(
111: 'id' => sprintf('predpep %d-%d'
112: , $row['fmin'], $row['fmax']),
113: 'sequence' => self::rewinds(self::space($row['residues']), $row['strand']),
114: 'offset' => $row['fmin'],
115: 'dir' => 'right'#strand2dir($predpep['strand'])
116: ))
117: );
118: break;
119: case CV_ANNOTATION_INTERPRO:
120: // this would look better, but canvasXpress cuts datasets after 8 rows so each bar has to be it's own dataset
121: //if ($last_row['type_id'] != CV_ANNOTATION_INTERPRO) {
122:
123: $return[] = array(
124: #'name' => 'Interpro Domain',
125: 'type' => 'box',
126: 'fill' => 'rgb(20,255,51)',
127: 'outline' => 'rgb(0,0,0)',
128: 'data' => array()
129: );
130: $current_interpro = &$return[count($return)-1];
131: //}
132: $left = $last_predpep_row['fmin'] + ($row['fmin'] - 1) * 3;
133: $right = $left + ($row['fmax'] - $row['fmin'] + 1) * 3;
134: $current_interpro['data'][] = array(
135: 'id' => $row['name'],
136: 'data' => array(array($left, $right)),
137: 'dir' => self::strand2dir($row['strand'])
138: );
139: break;
140: }
141: $last_row = $row;
142: }
143: return array('tracks' => array_values($return), 'min' => $min, 'max' => $max);
144: }
145:
146: }
147:
148: ?>
149: