blast_ui.linkouts.inc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. <?php
  2. /**
  3. * @file
  4. * Provides Link-out functionality for BLAST hits.
  5. *
  6. * Specifically, this is how the URL portion of the hit links in your users
  7. * Blast results is formed.
  8. *
  9. * To implement your own link-out type:
  10. * 1) Register your link-out type by implementing hook_blast_linkout_info().
  11. * Hook blast_linkout_info must return an array of types where each type
  12. * has a name and process function. For exmaple,
  13. * @code
  14. function blast_ui_blast_linkout_info() {
  15. $types = array();
  16. $types['my-link-type'] = array(
  17. 'name' => 'My Amazing Link Type',
  18. 'process function' => 'mymodule_generate_linkout_mylinktype',
  19. );
  20. return $types;
  21. }
  22. * @endcode
  23. *
  24. * 2) Implement the process function you specified to determine the URL
  25. * to be linked to depending on the blast hit. For a full description of
  26. * parameters available to your function, see tripal_blast_generate_linkout_link().
  27. * @code
  28. function mymodule_generate_linkout_mylinktype($url_prefix, $hit, $info, $options = array()) {
  29. // Do some simple steps to generate the suffix based on the $hit.
  30. return $url_prefix . $url_postfix;
  31. }
  32. * @endcode
  33. *
  34. * This module will automatically,
  35. * - Add your custom type to the "Link-out Type" select list on Blast Database
  36. * node add/edit forms.
  37. * - If your type is chosen by the user when the Blast Database is created,
  38. * then your process function will be used by blast_report.tpl.php to
  39. * determine the URL that should be used for each hit link.
  40. */
  41. /**
  42. * Implements hook_blast_linkout_info().
  43. * Provide information on basic link-out types: link, GBrowse, JBrowse.
  44. *
  45. * NOTE: Each item must have a 'name' and 'process function' to indicate the
  46. * human-readable name to be used in the Blast Database add/edit form and the
  47. * function to be used to determine the URL for each hit in BLAST results.
  48. */
  49. function blast_ui_blast_linkout_info() {
  50. $types = array();
  51. $types['link'] = array(
  52. // Human-readable Type name to display to users in the BLAST Database
  53. // create/edit form.
  54. 'name' => 'Generic Link',
  55. // The function used to generate the URL to be linked to.
  56. // This function will have full access to the blast hit and database
  57. // prefix information and is expected to return a URL.
  58. 'process function' => 'tripal_blast_generate_linkout_link',
  59. // Help text to show in the BLAST Database create/edit form so that
  60. // users will know how to use this link-out type. Specifically, info
  61. // about your assumptions for the URL prefix are very helpful.
  62. // HTML is aloud but do not enclose in <p>.
  63. 'help' => 'The External Database choosen below provides its URL prefix when
  64. determining the URL to link-out to. If the link-out type is "Generic Link" then
  65. the hit identifier (determined using fasta header format or regular expression) is
  66. concatenated to the end of the url prefix. For example, if your hit is for "Chr01"
  67. and the URL prefix is "http://myfriendstripalsite.org/name/" then the complete URL
  68. is simply &#60;a href="http://myfriendstripalsite.org/name/Chr01"&#62;Chr01&#60;/a&#62;.',
  69. );
  70. $types['gbrowse'] = array(
  71. 'name' => 'GBrowse',
  72. 'process function' => 'tripal_blast_generate_linkout_gbrowse',
  73. 'help' => 'The link created will add a BLAST track to the GBrowse (specified by the
  74. External Database) that shows the HSPs as well as indicating the overall hit.
  75. <strong><em>It is assumed that the Reference of the GBrowse is the same as this BLAST
  76. database (even the names must be consistent).</em></strong> Furthermore, the URL prefix
  77. supplied is expected to have an empty query (?) or be properly ended (;). For
  78. example, "http://mydomain.com/gb/gbrowse/tripalus_databasica/?" OR
  79. "http://mydomain.com/gb/gbrowse/tripalus_databasica/?label=genes+markers;"',
  80. );
  81. $types['jbrowse'] = array(
  82. 'name' => 'JBrowse',
  83. 'process function' => 'tripal_blast_generate_linkout_jbrowse',
  84. 'help' => 'The link created will add a "Blast Result" track to the JBrowse (specified by the
  85. External Database) that shows the HSPs as well as indicating the overall hit.
  86. <strong><em>It is assumed that the Reference of the JBrowse is the same as this BLAST
  87. database (even the names must be consistent).</em></strong> Furthermore, the URL prefix
  88. supplied is expected to have an empty query (?) or be properly ended (&). For
  89. example, "http://mydomain.com/jbrowse/tripalus_databasica/?" OR
  90. "http://mydomain.com/jbrowse/tripalus_databasica/?tracks=genes,markers,blast&".
  91. Also <strong><em>the Blast Result track is NOT Displayed by default</em></strong>. Either include "blast"
  92. using the "tracks" directive in the URL prefix or specify it in your JBrowse.conf.',
  93. );
  94. return $types;
  95. }
  96. /**
  97. * Generate a basic link-out for a given hit.
  98. *
  99. * Essentially, concatenate the URL prefix with the extracted hit identifier
  100. * and return the URL to be displayed by the BLAST report template.
  101. *
  102. * @param $url_prefix
  103. * The URL prefix for the BLAST Database queried.
  104. * @param $hit
  105. * The blast XML hit object. This object has the following keys based on the
  106. * XML: Hit_num, Hit_id, Hit_def, Hit_accession, Hit_len and Hit_hsps.
  107. * Furthermore, a linkout_id key has beek added that contains the part of the
  108. * Hit_def extracted using a regex provided when the blastdb node was created.
  109. * @param $info
  110. * Additional information that may be useful in creating a link-out. Includes:
  111. * - query_name: the name of the query sequence.
  112. * - score: the score of the blast hit.
  113. * - e-value: the e-value of the blast hit.
  114. * @param $options
  115. * Any additional options needed to determine the type of link-out. None are
  116. * supported by this particular link-out type.
  117. *
  118. * @return
  119. * The URL string to be linked to.
  120. */
  121. function tripal_blast_generate_linkout_link($url_prefix, $hit, $info, $options = array()) {
  122. if (isset($hit->{'linkout_id'})) {
  123. return $url_prefix . $hit->{'linkout_id'};
  124. }
  125. else {
  126. return FALSE;
  127. }
  128. }
  129. /**
  130. * Generate a GBrowse link-out with location information for a given hit.
  131. *
  132. * NOTE: Assumes the hit is a backbone feature in the GBrowse linked to.
  133. * Otherwise, the basic link can be used.
  134. *
  135. * @param $url_prefix
  136. * The URL prefix for the BLAST Database queried.
  137. * @param $hit
  138. * The blast XML hit object. This object has the following keys based on the
  139. * XML: Hit_num, Hit_id, Hit_def, Hit_accession, Hit_len and Hit_hsps.
  140. * Furthermore, a linkout_id key has beek added that contains the part of the
  141. * Hit_def extracted using a regex provided when the blastdb node was created.
  142. * @param $info
  143. * Additional information that may be useful in creating a link-out. Includes:
  144. * - query_name: the name of the query sequence.
  145. * - score: the score of the blast hit.
  146. * - e-value: the e-value of the blast hit.
  147. * @param $options
  148. * Any additional options needed to determine the type of link-out. None are
  149. * supported by this particular link-out type.
  150. *
  151. * @return
  152. * The URL string to be linked to.
  153. */
  154. function tripal_blast_generate_linkout_gbrowse($url_prefix, $hit, $info, $options = array()) {
  155. // First we need to collect the HSPs to define the ranges we want to
  156. // display on the JBrowse.
  157. $ranges = array();
  158. // We also keep track of all the coordinates in order to later
  159. // calculate the smallest and largest coordinate.
  160. $coords = array();
  161. foreach($info['HSPs'] as $hsp) {
  162. $start = min($hsp['Hsp_hit-from'], $hsp['Hsp_hit-to']);
  163. $stop = max($hsp['Hsp_hit-from'], $hsp['Hsp_hit-to']);
  164. // Format the hsp for inclusion in the new track later.
  165. array_push($ranges, "$start..$stop");
  166. // Add both the start & stop to the coordinate list.
  167. array_push($coords, $start, $stop);
  168. }
  169. // Calculate the minimum & maximum coordinates.
  170. $min = min($coords);
  171. $max = max($coords);
  172. // Now we are finally ready to build the URL.
  173. // First lets set the location of the hit so the GBrowse focuses in on the correct region.
  174. $query = array();
  175. $query['ref'] = 'ref=' . $hit->{'linkout_id'};
  176. $query['start'] = 'start=' . $min;
  177. $query['stop'] = 'stop=' . $max;
  178. // Next we want to add our BLAST hit to the GBrowse.
  179. $query['add'] = format_string(
  180. 'add=!ref+!trackname+!featurename+!hspcoords',
  181. array(
  182. '!ref' => $hit->{'linkout_id'},
  183. '!trackname' => 'BLAST',
  184. '!featurename' => 'BlastHit',
  185. '!hspcoords' => join ("," , $ranges),
  186. )
  187. );
  188. // Highlight our newly added feature.
  189. $query['highlight'] = format_string(
  190. 'h_feat=!featurename',
  191. array('!featurename' => 'BlastHit')
  192. );
  193. $url_postfix = implode(';', $query);
  194. return $url_prefix . $url_postfix;
  195. }
  196. /**
  197. * Generate a JBrowse link-out with location information for a given hit.
  198. *
  199. * NOTE: Assumes the hit is a backbone feature in the JBrowse linked to.
  200. * Otherwise, the basic link can be used.
  201. * NOTE: This linkout creates a "blast" track but doesn't make it visible. This is to
  202. * allow your default tracks to be visible and give contect to your blast hit. You
  203. * should include "blast" in your jbrowse.conf default track list to ensure your
  204. * users can always see their hits. If you don't have access to the jbrowse.conf,
  205. * you can place the tracks you want to see including 'blast' in the url prefix
  206. * (see example below under @param $url_prefix).
  207. *
  208. * @param $url_prefix
  209. * The URL prefix for the BLAST Database queried. It is assumed that the url prefix
  210. * includes the ? and if there are any key=vale pairs that the last symbol is &.
  211. * For example,
  212. * http://myserver.com/jbrowse/databasica/?
  213. * http://myserver.com/jbrowse/databasica/?tracks=myfavtrack,anoktrack,blast&
  214. *
  215. * @param $hit
  216. * The blast XML hit object. This object has the following keys based on the
  217. * XML: Hit_num, Hit_id, Hit_def, Hit_accession, Hit_len and Hit_hsps.
  218. * Furthermore, the following keys have been added:
  219. * -linkout_id: the part of the Hit_def extracted using a regex provided
  220. * when the blastdb node was created.
  221. * -hit_name: the name of the hit extracted in the template.
  222. * @param $info
  223. * Additional information that may be useful in creating a link-out. Includes:
  224. * - query_name: the name of the query sequence.
  225. * - score: the score of the blast hit.
  226. * - e-value: the e-value of the blast hit.
  227. * @param $options
  228. * Any additional options needed to determine the type of link-out. None are
  229. * supported by this particular link-out type.
  230. *
  231. * @return
  232. * The URL string to be linked to.
  233. */
  234. function tripal_blast_generate_linkout_jbrowse($url_prefix, $hit, $info, $options = array()) {
  235. // First we need to collect the HSPs to define the ranges we want to
  236. // display on the JBrowse.
  237. $ranges = array();
  238. // We also keep track of all the coordinates in order to later
  239. // calculate the smallest and largest coordinate.
  240. $coords = array();
  241. $count = 0;
  242. foreach($info['HSPs'] as $hsp) {
  243. $count++;
  244. $strand = '1';
  245. $hsp_start = $hsp['Hsp_hit-from'];
  246. $hsp_end = $hsp['Hsp_hit-to'];
  247. // Handle alignments on the negative strand.
  248. if (($hsp_end - $hsp_start) < 0) {
  249. $strand = '-1';
  250. $hsp_start = $hsp['Hsp_hit-to'];
  251. $hsp_end = $hsp['Hsp_hit-from'];
  252. }
  253. // Add both the start & stop to the coordinate list.
  254. array_push($coords,$hsp['Hsp_hit-from'] , $hsp['Hsp_hit-to'] );
  255. // Format the hsp for inclusion in the subfeatures section of the track later.
  256. $hsp_def = format_string(
  257. '{"start":!start,"end":!end,"strand":"!strand","type":"!type"}',
  258. array(
  259. '!start' => $hsp_start,
  260. '!end' => $hsp_end,
  261. '!strand' => $strand,
  262. '!type' => 'match_part'
  263. )
  264. );
  265. array_push($ranges, $hsp_def);
  266. }
  267. // Calculate the minimum & maximum coordinates.
  268. $min = min($coords);
  269. $max = max($coords);
  270. // We also want some white-space on either side of out hit
  271. // when we show it in the JBrowse. To make this generic,
  272. // we want our blast hit to take up 2/3 of the screen thus
  273. // we have 1/6 per side for white-space.
  274. $buffer = round(($max - $min) / 6);
  275. $screen_start = $min - $buffer;
  276. $screen_end = $max + $buffer;
  277. // Now we are finally ready to build the URL.
  278. // First lets set the location of the hit so the JBrowse focuses in on the correct region.
  279. $jbrowse_query = array();
  280. $jbrowse_query['loc'] = format_string(
  281. 'loc=!ref:!start..!stop',
  282. array(
  283. '!ref' => $hit->{'linkout_id'},
  284. '!start' => $screen_start,
  285. '!stop' => $screen_end,
  286. )
  287. );
  288. // Next we want to add our BLAST hit to the JBrowse.
  289. $jbrowse_query['addFeatures'] = format_string(
  290. 'addFeatures=[{"seq_id":"!id","start":!min,"end":!max,"name":"!name","subfeatures":[!hspcoords]}]',
  291. array(
  292. '!id' => $hit->{'linkout_id'},
  293. '!name' => $info['query_name'] . ' Blast Hit',
  294. '!min' => $min,
  295. '!max' => $max,
  296. '!hspcoords' => join ("," , $ranges)
  297. ));
  298. // Then add a track to display our new feature.
  299. $jbrowse_query['addTracks'] = 'addTracks=[{"label":"blast","key":"BLAST Result","type":"JBrowse/View/Track/HTMLFeatures","store":"url"}]';
  300. $url_postfix = implode('&', $jbrowse_query);
  301. return $url_prefix . $url_postfix;
  302. }