blast_report.tpl.php 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. <?php
  2. /**
  3. * Display the results of a BLAST job execution
  4. *
  5. * Variables Available in this template:
  6. * $xml_filename: The full path & filename of XML file containing the BLAST results
  7. */
  8. // Set ourselves up to do link-out if our blast database is configured to do so.
  9. $linkout = FALSE;
  10. if ($blastdb->linkout->none === FALSE) {
  11. $linkout = TRUE;
  12. $linkout_regex = $blastdb->linkout->regex;
  13. if (isset($blastdb->linkout->db_id->urlprefix) AND !empty($blastdb->linkout->db_id->urlprefix)) {
  14. $linkout_urlprefix = $blastdb->linkout->db_id->urlprefix;
  15. // Furthermore, check that we can determine the URL.
  16. // (ie: that the function specified to do so, exists).
  17. if (function_exists($blastdb->linkout->url_function)) {
  18. $url_function = $blastdb->linkout->url_function;
  19. }
  20. else {
  21. $linkout = FALSE;
  22. }
  23. }
  24. else {
  25. $linkout = FALSE;
  26. }
  27. }
  28. // Handle no hits. This following array will hold the names of all query
  29. // sequences which didn't have any hits.
  30. $query_with_no_hits = array();
  31. // Furthermore, if no query sequences have hits we don't want to bother listing
  32. // them all but just want to give a single, all-include "No Results" message.
  33. $no_hits = TRUE;
  34. ?>
  35. <!-- JQuery controlling display of the alignment information (hidden by default) -->
  36. <script type="text/javascript">
  37. $(document).ready(function(){
  38. // Hide the alignment rows in the table
  39. // (ie: all rows not labelled with the class "result-summary" which contains the tabular
  40. // summary of the hit)
  41. $("#blast_report tr:not(.result-summary)").hide();
  42. $("#blast_report tr:first-child").show();
  43. // When a results summary row is clicked then show the next row in the table
  44. // which should be corresponding the alignment information
  45. $("#blast_report tr.result-summary").click(function(){
  46. $(this).next("tr").toggle();
  47. $(this).find(".arrow").toggleClass("up");
  48. });
  49. });
  50. </script>
  51. <style>
  52. .no-hits-message {
  53. color: red;
  54. font-style: italic;
  55. }
  56. </style>
  57. <p><strong>Download</strong>:
  58. <a href="<?php print '../../' . $html_filename; ?>">HTML</a>,
  59. <a href="<?php print '../../' . $tsv_filename; ?>">Tab-Delimited</a>,
  60. <a href="<?php print '../../' . $xml_filename; ?>">XML</a>
  61. </p>
  62. <p>The following table summarizes the results of your BLAST. To see additional information
  63. about each hit including the alignment, click on that row in the table to expand it.</p>
  64. <?php
  65. include_once("blast_align_image.php");
  66. // Load the XML file
  67. $xml = simplexml_load_file($xml_filename);
  68. /**
  69. * We are using the drupal table theme functionality to create this listing
  70. * @see theme_table() for additional documentation
  71. */
  72. if ($xml) {
  73. // Specify the header of the table
  74. $header = array(
  75. 'number' => array('data' => '#', 'class' => array('number')),
  76. 'query' => array('data' => 'Query Name (Click for alignment & visualization)', 'class' => array('query')),
  77. 'hit' => array('data' => 'Hit Name', 'class' => array('hit')),
  78. 'evalue' => array('data' => 'E-Value', 'class' => array('evalue')),
  79. 'arrow-col' => array('data' => '', 'class' => array('arrow-col'))
  80. );
  81. $rows = array();
  82. $count = 0;
  83. // Parse the BLAST XML to generate the rows of the table
  84. // where each hit results in two rows in the table: 1) A summary of the query/hit and
  85. // significance and 2) additional information including the alignment
  86. foreach($xml->{'BlastOutput_iterations'}->children() as $iteration) {
  87. $children_count = $iteration->{'Iteration_hits'}->children()->count();
  88. //@deepaksomanadh: Code added for BLAST visualization
  89. // parameters that need to be passed for BLAST image generation
  90. $target_name = '';
  91. $q_name = $xml->{'BlastOutput_query-def'};
  92. $query_size = $xml->{'BlastOutput_query-len'};
  93. $target_size = $iteration->{'Iteration_stat'}->{'Statistics'}->{'Statistics_db-len'};
  94. if($children_count != 0) {
  95. foreach($iteration->{'Iteration_hits'}->children() as $hit) {
  96. if (is_object($hit)) {
  97. $count +=1;
  98. $zebra_class = ($count % 2 == 0) ? 'even' : 'odd';
  99. $no_hits = FALSE;
  100. // RETRIEVE INFO
  101. $hit_name = (preg_match('/BL_ORD_ID/', $hit->{'Hit_id'})) ? $hit->{'Hit_def'} : $hit->{'Hit_id'};
  102. $score = $hit->{'Hit_hsps'}->{'Hsp'}->{'Hsp_score'};
  103. $evalue = $hit->{'Hit_hsps'}->{'Hsp'}->{'Hsp_evalue'};
  104. $query_name = $iteration->{'Iteration_query-def'};
  105. // Round e-val to two decimal values
  106. $rounded_evalue = '';
  107. if (strpos($evalue,'e') != false) {
  108. $evalue_split = explode('e', $evalue);
  109. $rounded_evalue = round($evalue_split[0], 2, PHP_ROUND_HALF_EVEN);
  110. $rounded_evalue .= 'e' . $evalue_split[1];
  111. }
  112. else {
  113. $rounded_evalue = $evalue;
  114. }
  115. // ALIGNMENT ROW (collapsed by default)
  116. // Process HSPs
  117. // @deepaksomanadh: Code added for BLAST visualization
  118. // hit array and corresponding bit scores
  119. // hits=4263001_4262263_1_742;4260037_4259524_895_1411;&scores=722;473;
  120. $HSPs = array();
  121. $hit_hsps = '';
  122. $hit_hsp_score = '';
  123. foreach ($hit->{'Hit_hsps'}->children() as $hsp_xml) {
  124. $HSPs[] = (array) $hsp_xml;
  125. $hit_hsps .= $hsp_xml->{'Hsp_hit-from'} . '_' . $hsp_xml->{'Hsp_hit-to'}
  126. . '_' . $hsp_xml->{'Hsp_query-from'} . '_'
  127. . $hsp_xml->{'Hsp_query-to'} . ';';
  128. $Hsp_bit_score .= $hsp_xml->{'Hsp_bit-score'} .';';
  129. }
  130. // SUMMARY ROW
  131. // If the id is of the form gnl|BL_ORD_ID|### then the parseids flag
  132. // to makeblastdb did a really poor job. In this case we want to use
  133. // the def to provide the original FASTA header.
  134. // If our BLAST DB is configured to handle link-outs then use the
  135. // regex & URL prefix provided to create one.
  136. if ($linkout) {
  137. if (preg_match($linkout_regex, $hit_name, $linkout_match)) {
  138. $linkout_id = $linkout_match[1];
  139. $hit->{'linkout_id'} = $linkout_id;
  140. $hit->{'hit_name'} = $hit_name;
  141. $hit_url = call_user_func(
  142. $url_function,
  143. $linkout_urlprefix,
  144. $hit,
  145. array(
  146. 'query_name' => $query_name,
  147. 'score' => $score,
  148. 'e-value' => $evalue,
  149. 'HSPs' => $HSPs
  150. )
  151. );
  152. if ($hit_url) {
  153. $hit_name = l(
  154. $linkout_id,
  155. $hit_url,
  156. array('attributes' => array('target' => '_blank'))
  157. );
  158. }
  159. }
  160. }
  161. //@deepaksomanadh: Code added for BLAST visualization
  162. // get the image and display
  163. $hit_img = generateImage($target_name, $Hsp_bit_score, $hit_hsps, $target_size, $query_size, $q_name);
  164. ob_start(); // Start buffering the output
  165. imagepng($hit_img, null, 0, PNG_NO_FILTER);
  166. $b64 = base64_encode(ob_get_contents()); // Get what we've just outputted and base64 it
  167. imagedestroy($hit_img);
  168. ob_end_clean();
  169. // Print the HTML tag with the image embedded
  170. $hit_img = '<h3> Hit Visualization </h3> <br><img src="data:image/png;base64,'.$b64.'"/>';
  171. $row = array(
  172. 'data' => array(
  173. 'number' => array('data' => $count, 'class' => array('number')),
  174. 'query' => array('data' => $query_name, 'class' => array('query')),
  175. 'hit' => array('data' => $hit_name, 'class' => array('hit')),
  176. 'evalue' => array('data' => $rounded_evalue, 'class' => array('evalue')),
  177. 'arrow-col' => array('data' => '<div class="arrow"></div>', 'class' => array('arrow-col'))
  178. ),
  179. 'class' => array('result-summary')
  180. );
  181. $rows[] = $row;
  182. // ALIGNMENT ROW (collapsed by default)
  183. // Process HSPs
  184. $row = array(
  185. 'data' => array(
  186. 'number' => '',
  187. 'query' => array(
  188. 'data' => theme('blast_report_alignment_row', array('HSPs' => $HSPs)),
  189. ),
  190. 'hit' => array(
  191. 'data' => $hit_img,
  192. 'colspan' => 3,
  193. ),
  194. ),
  195. 'class' => array('alignment-row', $zebra_class),
  196. 'no_striping' => TRUE
  197. );
  198. $rows[] = $row;
  199. }// end of if - checks $hit
  200. } //end of foreach - iteration_hits
  201. } // end of if - check for iteration_hits
  202. else {
  203. // Currently where the "no results" is added.
  204. $query_name = $iteration->{'Iteration_query-def'};
  205. $query_with_no_hits[] = $query_name;
  206. } // end of else
  207. }
  208. if ($no_hits) {
  209. print '<p class="no-hits-message">No results found.</p>';
  210. }
  211. else {
  212. // We want to warn the user if some of their query sequences had no hits.
  213. if (!empty($query_with_no_hits)) {
  214. print '<p class="no-hits-message">Some of your query sequences did not '
  215. . 'match to the database/template. They are: '
  216. . implode(', ', $query_with_no_hits) . '.</p>';
  217. }
  218. // Actually print the table.
  219. if (!empty($rows)) {
  220. print theme('table', array(
  221. 'header' => $header,
  222. 'rows' => $rows,
  223. 'attributes' => array('id' => 'blast_report'),
  224. ));
  225. }
  226. }
  227. }
  228. else {
  229. drupal_set_title('BLAST: Error Encountered');
  230. print '<p>We encountered an error and are unable to load your BLAST results.</p>';
  231. }
  232. ?>