tripal_analysis_kegg.module 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890
  1. <?php
  2. /*******************************************************************************
  3. *
  4. ******************************************************************************/
  5. function tripal_analysis_kegg_init(){
  6. // add the tripal_analysis_kegg JS and CSS
  7. drupal_add_js(drupal_get_path('theme', 'tripal').'/js/tripal_analysis_kegg.js');
  8. drupal_add_css(drupal_get_path('theme', 'tripal').'/css/tripal_analysis_kegg.css');
  9. // add the jsTree JS and CSS
  10. drupal_add_css(drupal_get_path('theme', 'tripal').'/js/jsTree/source/tree_component.css');
  11. drupal_add_js (drupal_get_path('theme', 'tripal').'/js/jsTree/source/_lib.js');
  12. drupal_add_js (drupal_get_path('theme', 'tripal').'/js/jsTree/source/tree_component.js');
  13. }
  14. /*******************************************************************************
  15. * Provide information to drupal about the node types that we're creating
  16. * in this module
  17. */
  18. function tripal_analysis_kegg_node_info() {
  19. $nodes = array();
  20. $nodes['chado_analysis_kegg'] = array(
  21. 'name' => t('Analysis: KEGG'),
  22. 'module' => 'chado_analysis_kegg',
  23. 'description' => t('Results from a KEGG/KAAS analysis'),
  24. 'has_title' => FALSE,
  25. 'title_label' => t('Analysis: KEGG'),
  26. 'has_body' => FALSE,
  27. 'body_label' => t('KEGG Analysis Description'),
  28. 'locked' => TRUE
  29. );
  30. return $nodes;
  31. }
  32. /*******************************************************************************
  33. * Menu items are automatically added for the new node types created
  34. * by this module to the 'Create Content' Navigation menu item. This function
  35. * adds more menu items needed for this module.
  36. */
  37. function tripal_analysis_kegg_menu() {
  38. $items['brite/%'] = array(
  39. 'title' => t('KEGG BRITE'),
  40. 'page callback' => 'tripal_analysis_kegg_brite',
  41. 'page arguments' => array(1, 2),
  42. 'access arguments' => array('access content'),
  43. 'type' => MENU_CALLBACK
  44. );
  45. $items['tripal_analysis_kegg_org_report'] = array(
  46. 'path' => 'tripal_analysis_kegg_org_report',
  47. 'title' => t('Analysis KEGG report'),
  48. 'page callback' => 'f',
  49. 'page arguments' => array(1),
  50. 'access arguments' => array('access chado_analysis_kegg content'),
  51. 'type' => MENU_CALLBACK
  52. );
  53. return $items;
  54. }
  55. /*******************************************************************************
  56. * Set the permission types that the chado module uses. Essentially we
  57. * want permissionis that protect creation, editing and deleting of chado
  58. * data objects
  59. */
  60. function tripal_analysis_kegg_perm(){
  61. return array(
  62. 'access chado_analysis_kegg content',
  63. 'create chado_analysis_kegg content',
  64. 'delete chado_analysis_kegg content',
  65. 'edit chado_analysis_kegg content',
  66. );
  67. }
  68. /*******************************************************************************
  69. * The following function proves access control for users trying to
  70. * perform actions on data managed by this module
  71. */
  72. function chado_analysis_kegg_access($op, $node, $account){
  73. if ($op == 'create') {
  74. return user_access('create chado_analysis_kegg content', $account);
  75. }
  76. if ($op == 'update') {
  77. if (user_access('edit chado_analysis_kegg content', $account)) {
  78. return TRUE;
  79. }
  80. }
  81. if ($op == 'delete') {
  82. if (user_access('delete chado_analysis_kegg content', $account)) {
  83. return TRUE;
  84. }
  85. }
  86. if ($op == 'view') {
  87. if (user_access('access chado_analysis_kegg content', $account)) {
  88. return TRUE;
  89. }
  90. }
  91. return FALSE;
  92. }
  93. /*******************************************************************************
  94. */
  95. function tripal_analysis_kegg_brite($analysis_id, $type_id, $ajax){
  96. // If not called by ajax
  97. if (!$ajax) {
  98. $content .=
  99. "<div id=\"tripal_kegg_brite_results\" class=\"tripal_kegg_brite-info-box\">
  100. <table>
  101. <tr>
  102. <th>KEGG BRITE</th>
  103. <th id=\"tripal_kegg_brite_header\">Hierarchy:</th>
  104. </tr>
  105. <tr>
  106. <td nowrap valign=\"top\">
  107. ";
  108. // List all BRITE terms on the left
  109. $sql = "SELECT CVT.name, CVT.cvterm_id
  110. FROM {cvterm} CVT
  111. INNER JOIN analysisprop AP ON CVT.cvterm_id = AP.type_id
  112. WHERE AP.analysis_id = %d AND CVT.definition LIKE 'KEGG BRITE term: %'
  113. ORDER BY CVT.cvterm_id";
  114. $previous_db = tripal_db_set_active('chado');
  115. $result = db_query($sql, $analysis_id);
  116. tripal_db_set_active($previous_db);
  117. while ($brite_term = db_fetch_object($result)) {
  118. $url = url("brite/$analysis_id/$brite_term->cvterm_id/1");
  119. $content .= "<li class=\"tripal_kegg_brite_terms\"><a onclick=\"return tripal_update_brite(".
  120. "this,$brite_term->cvterm_id)\" href=\"$url\">
  121. $brite_term->name
  122. </a></li>";
  123. }
  124. // Show the hierarchy tree
  125. $content .="</td>
  126. <td nowrap id=\"tripal_kegg_brite_hierarchy\" valign=\"top\">";
  127. $content .= "<i>Note:</i> Click a BRITE term for its functional hierarchy";
  128. // If called by ajax, generate tree structure
  129. } else {
  130. // Get BRITE term from cvterm table
  131. $previous_db = tripal_db_set_active('chado');
  132. $sql = 'SELECT name FROM {cvterm} WHERE cvterm_id=%d';
  133. $brite_term = db_result(db_query($sql, $type_id));
  134. // Get BRITE hierarchy tree
  135. $sql = "SELECT value
  136. FROM {analysisprop} AP
  137. INNER JOIN CVterm CVT on AP.type_id = CVT.cvterm_id
  138. INNER JOIN CV on CVT.cv_id = CV.cv_id
  139. WHERE CV.name = 'tripal' and CVT.name = '%s'
  140. AND AP.analysis_id = %d";
  141. $result = db_fetch_object(db_query($sql, $brite_term, $analysis_id));
  142. tripal_db_set_active($previous_db);
  143. $content .= "<div class=\"tripal_kegg_brite_tree\" id=\"tripal_kegg_brite_tree_$type_id\">$result->value</div>";
  144. }
  145. if (!$ajax) {
  146. $content .= " </td>
  147. </tr>
  148. </table>
  149. </div>";
  150. }
  151. // since this function provides output for addition into
  152. // an analysis page, as well as an AJAX refresh of content
  153. // within the BRITE hierarchy we need to setup the return
  154. // different depending on the request type
  155. if($ajax){
  156. drupal_json(array('update' => $content,
  157. 'id' => "tripal_kegg_brite_tree_$type_id",
  158. 'brite_term' => "Hierarchy: $brite_term"));
  159. } else {
  160. return $content;
  161. }
  162. }
  163. /*******************************************************************************
  164. * Provide a KEGG Analysis form
  165. */
  166. function chado_analysis_kegg_form ($node){
  167. // add in the default fields
  168. $form = chado_analysis_form($node);
  169. // set the defaults
  170. $kegg = $node->analysis->tripal_analysis_kegg;
  171. $hierfile = $kegg->hierfile;
  172. $moreSettings ['kegg'] = 'KEGG Analysis Settings';
  173. $form['kegg'] = array(
  174. '#title' => t('KEGG Settings'),
  175. '#type' => 'fieldset',
  176. '#description' => t('Specific Settings for KEGG Analysis.'),
  177. '#collapsible' => TRUE,
  178. '#attributes' => array('id' => 'kegg-extra-settings'),
  179. '#weight' => 11
  180. );
  181. $form['kegg']['hierfile'] = array(
  182. '#title' => t('KAAS hier.tar.gz Output File'),
  183. '#type' => 'textfield',
  184. '#description' => t('The full path to the hier.tar.gz file generated by KAAS.
  185. Alternatively, you can input the full path to the directory
  186. that contains decompressed kegg files.'),
  187. '#default_value' => $hierfile,
  188. );
  189. $form['kegg']['keggjob'] = array(
  190. '#type' => 'checkbox',
  191. '#title' => t('Submit a job to parse the kegg output into analysisfeatureprop table'),
  192. '#description' => t('Note: features associated with the KAAS results must '.
  193. 'exist in chado before parsing the file. Otherwise, KEGG '.
  194. 'results that cannot be linked to a feature will be '.
  195. 'discarded.'),
  196. );
  197. return $form;
  198. }
  199. /*******************************************************************************
  200. *
  201. */
  202. function chado_analysis_kegg_insert($node){
  203. // insert the analysis
  204. chado_analysis_insert($node);
  205. // set the type for this analysis
  206. tripal_analysis_insert_property($node->analysis->analysis_id,'analysis_type','tripal_analysis_kegg');
  207. // now add in the remaining settings as a single property but separated by bars
  208. tripal_analysis_insert_property($node->analysis_id,'analysis_kegg_settings',$node->hierfile);
  209. // Add a job if the user wants to parse the html output
  210. chado_analysis_kegg_submit_job($node);
  211. }
  212. /**
  213. *
  214. */
  215. function chado_analysis_kegg_submit_job($node){
  216. global $user;
  217. if($node->keggjob) {
  218. $job_args[0] = $analysis_id;
  219. $job_args[1] = $node->hierfile;
  220. $job_args[2] = base_path();
  221. if (is_readable($node->hierfile)) {
  222. $fname = preg_replace("/.*\/(.*)/", "$1", $node->hierfile);
  223. tripal_add_job("Parse KAAS output: $fname",'tripal_analysis_kegg',
  224. 'tripal_analysis_kegg_parseHierFile', $job_args, $user->uid);
  225. } else {
  226. drupal_set_message("Can not open KAAS hier.tar.gz output file. Job not scheduled.");
  227. }
  228. }
  229. }
  230. /*******************************************************************************
  231. * Delete KEGG anlysis
  232. */
  233. function chado_analysis_kegg_delete($node){
  234. chado_analysis_delete($node);
  235. }
  236. /*******************************************************************************
  237. * Update KEGG analysis
  238. */
  239. function chado_analysis_kegg_update($node){
  240. // insert the analysis
  241. chado_analysis_update($node);
  242. // set the type for this analysis
  243. tripal_analysis_update_property($node->analysis->analysis_id,'analysis_type','tripal_analysis_kegg',1);
  244. // now add in the remaining settings as a single property but separated by bars
  245. tripal_analysis_update_property($node->analysis_id,'analysis_kegg_settings',$node->hierfile,1);
  246. // Add a job if the user wants to parse the html output
  247. chado_analysis_kegg_submit_job($node);
  248. }
  249. /*******************************************************************************
  250. * When a node is requested by the user this function is called to allow us
  251. * to add auxiliary data to the node object.
  252. */
  253. function chado_analysis_kegg_load($node){
  254. // load the default set of analysis fields
  255. $additions = chado_analysis_load($node);
  256. // create some variables for easier lookup
  257. $analysis = $additions->analysis;
  258. $analysis_id = $analysis->analysis_id;
  259. // get the heirfile name
  260. $hierfile = tripal_analysis_get_property($analysis_id,'analysis_kegg_settings');
  261. $analysis->tripal_analysis_kegg->hierfile = $hierfile->value;
  262. return $additions;
  263. }
  264. /*******************************************************************************
  265. * This function customizes the view of the chado_analysis node. It allows
  266. * us to generate the markup.
  267. */
  268. function chado_analysis_kegg_view ($node, $teaser = FALSE, $page = FALSE) {
  269. // use drupal's default node view:
  270. if (!$teaser) {
  271. $node = node_prepare($node, $teaser);
  272. // When previewing a node submitting form, it shows 'Array' instead of
  273. // correct date format. We need to format the date here
  274. $time = $node->timeexecuted;
  275. if(is_array($time)){
  276. $month = $time['month'];
  277. $day = $time['day'];
  278. $year = $time['year'];
  279. $timestamp = $year.'-'.$month.'-'.$day;
  280. $node->timeexecuted = $timestamp;
  281. }
  282. }
  283. return $node;
  284. }
  285. /********************************************************************************
  286. */
  287. function tripal_analysis_kegg_parseHierFile ($analysis_id, $hierfile, $base_path, $job_id) {
  288. // If user input a file (e.g. hier.tar.gz), decompress it first
  289. if (is_file($hierfile)) {
  290. $data_dir = file_directory_path() . "/tripal/tripal_analysis_kegg";
  291. $stderr = shell_exec("cd $data_dir; tar -zxf $hierfile;");
  292. print "$stderr\n";
  293. $hierdir = $data_dir."/hier";
  294. // Otherwise, treat it as a directory
  295. } else {
  296. $hierdir = $hierfile;
  297. }
  298. $dir_handle = @opendir($hierdir) or die("Unable to open $hierdir");
  299. $total_files = count(glob($hierdir . '/*.*'));
  300. print "There are $total_files keg file(s).\n";
  301. $interval = intval($total_files * 0.01);
  302. $no_file = 0;
  303. while ($file = readdir($dir_handle)) {
  304. if(preg_match("/^.*\.keg/",$file)){
  305. // Update the progress
  306. if ($no_file % $interval == 0) {
  307. $percentage = (int) ($no_file / $total_files * 100);
  308. tripal_job_set_progress($job_id, $percentage);
  309. print $percentage."% ";
  310. }
  311. $no_file ++;
  312. # $type variable will be set in tripal_analysis_kegg_parse_kegg_file()
  313. $content = tripal_analysis_kegg_parse_kegg_file("$hierdir/$file",$type,$analysis_id, $base_path);
  314. # add the item to the database
  315. if($content){
  316. //------------------------------------------------------
  317. // Insert into analysisprop table
  318. //------------------------------------------------------
  319. // Make sure the same value doesn't exist before inserting into chado
  320. $sql = "SELECT value
  321. FROM {analysisprop}
  322. WHERE analysis_id = %d
  323. AND type_id = (SELECT cvterm_id
  324. FROM {cvterm} CVT
  325. INNER JOIN CV ON CVT.cv_id = CV.cv_id
  326. WHERE CV.name = 'tripal' AND CVT.name = '%s'
  327. )
  328. ";
  329. $previous_db = tripal_db_set_active('chado');
  330. $oldvalue = db_result(db_query($sql, $analysis_id, $type));
  331. tripal_db_set_active($previous_db);
  332. // Insert the content
  333. if ($oldvalue != $content) {
  334. $previous_db = tripal_db_set_active('chado'); // Use chado database
  335. // Get type_id for the BRITE term
  336. $sql = "SELECT cvterm_id
  337. FROM {cvterm} CVT
  338. INNER JOIN CV ON CVT.cv_id = CV.cv_id
  339. WHERE CV.name = 'tripal' AND CVT.name = '%s'";
  340. $brite_cvterm_id = db_result(db_query($sql, $type));
  341. // Replace all single quote as HTML code before insert
  342. $content = preg_replace("/\'/", "&#39;", $content);
  343. // Insert the value
  344. $sql = "INSERT INTO {analysisprop} (analysis_id, type_id, value)
  345. VALUES (%d, %d,'$content')";
  346. db_query($sql, $analysis_id, $brite_cvterm_id);
  347. tripal_db_set_active($previous_db); // Use drupal database
  348. }
  349. }
  350. }
  351. }
  352. print "Done.\n";
  353. closedir($dir_handle);
  354. // If user input a file, remove decompressed files after parsing
  355. if (is_file($hierfile)) {
  356. $stderr = shell_exec("rm -r $hierdir;");
  357. print "$stderr\n";
  358. }
  359. return;
  360. }
  361. /*******************************************************************************
  362. * Parse *.keg files.
  363. * Each file has a definition line. BRITE term is extracted * from this line
  364. * and added to chado as a cvterm. Tree structure for this cvterm is then
  365. * generated and saved to analysisfeature and analysisfeatureprop tables.
  366. */
  367. function tripal_analysis_kegg_parse_kegg_file ($file,&$type,$analysis_id, $base_path){
  368. $handle = fopen($file,'r');
  369. $depth = array();
  370. $current = '@'; # this is one character below 'A' in the ASCII table
  371. $prev = '@';
  372. $id = 0;
  373. $type_id = 0;
  374. $no_line = 0;
  375. $prefix = variable_get('chado_feature_accession_prefix','ID');
  376. while($line = fgets($handle)){
  377. $no_line ++;
  378. // Find out what kind of file we're looking at.
  379. if(preg_match("/#DEFINITION\s+(.*)\s+.+?$/",$line,$matches)){
  380. // Set type as the matched term in the DEFINITION line and add it as a new cvterm
  381. $type = $matches[1];
  382. // Before inserting, make sure this cvterm doesn't exist
  383. $previous_db = tripal_db_set_active('chado');
  384. $sql = "SELECT cvterm_id
  385. FROM {cvterm} CVT
  386. INNER JOIN cv ON cv.cv_id = CVT.cv_id
  387. WHERE cv.name = 'tripal'
  388. AND CVT.name = '%s'";
  389. $type_id = db_result(db_query($sql, $type));
  390. tripal_db_set_active($previous_db);
  391. if (!$type_id) {
  392. tripal_add_cvterms($type, "KEGG BRITE term: $type");
  393. // Get newly added type_id
  394. $sql = "SELECT cvterm_id
  395. FROM {cvterm} CVT
  396. INNER JOIN cv ON cv.cv_id = CVT.cv_id
  397. WHERE cv.name = 'tripal'
  398. AND CVT.name = '%s'";
  399. $previous_db = tripal_db_set_active('chado');
  400. $type_id = db_result(db_query($sql, $type));
  401. tripal_db_set_active($previous_db);
  402. }
  403. }
  404. // get the depth of the hierarch (e.g. A,B,C or D);
  405. preg_match("/^([ABCDEFGHIJKLMNOP])\s*(.*)/",$line,$matches);
  406. # skip lines that aren't data or are empty
  407. if(!$matches[1] or !$matches[2]){continue;}
  408. $prev = $current;
  409. $current = $matches[1];
  410. for($i = (ord($current) - ord($prev)); $i < 0; $i++){
  411. $content .= "</li></ul>\n";
  412. }
  413. for($i = 0; $i < (ord($current) - ord($prev)); $i++){
  414. $content .= "<ul>\n";
  415. }
  416. // change all relative paths to absolute paths pointing to KEGG (www.genome.jp)
  417. $matches[2] = preg_replace("/<a href=\"\//i","<a href=\"http://www.genome.jp/",$matches[2]);
  418. // add id to <a> tags so we can link kegg.gif to it in tripal_analysis_kegg.css
  419. $matches[2] = preg_replace("/<a href=\"/i","<a id=\"tripal_kegg_brite_links\" target=\"_blank\" href=\"",$matches[2]);
  420. // extract the features that have been mapped to the KEGG IDs
  421. if(preg_match("/^(.*?);\s*(\<a.+)/",$matches[2],$mat)){
  422. // Find cvterm_id for 'kegg_brite_data'
  423. $sql = "SELECT cvterm_id
  424. FROM {cvterm} CVT
  425. INNER JOIN cv ON cv.cv_id = CVT.cv_id
  426. WHERE cv.name = 'tripal'
  427. AND CVT.name = '%s'";
  428. $previous_db = tripal_db_set_active('chado');
  429. $brite_data_type_id = db_result(db_query($sql, 'kegg_brite_data'));
  430. tripal_db_set_active($previous_db);
  431. $uniquename = $mat[1];
  432. // Find feature_id using uniquename
  433. $sql = "SELECT feature_id FROM {feature} WHERE uniquename = '%s'";
  434. $previous_db = tripal_db_set_active('chado');
  435. $feature_id = db_result(db_query($sql, $uniquename)); // retrive first returned feature_id (assuming uniquename is unique)
  436. tripal_db_set_active($previous_db);
  437. // Get the higest rank for this feature_id in analysisfeatureprop table
  438. $sql = "SELECT MAX(rank) FROM {analysisfeatureprop} AFP ".
  439. "INNER JOIN analysisfeature AF ON AF.analysisfeature_id = AFP.analysisfeature_id ".
  440. "WHERE feature_id=%d ".
  441. "AND analysis_id=%d ".
  442. "AND type_id=%d ";
  443. $previous_db = tripal_db_set_active('chado');
  444. $afp = db_fetch_object(db_query($sql, $feature_id, $analysis_id, $brite_data_type_id));
  445. tripal_db_set_active($prevous_db);
  446. $hi_rank = 0;
  447. if ($afp) {
  448. $hi_rank = $afp->max + 1;
  449. }
  450. //------------------------------------------------------
  451. // Insert into analysisfeature table
  452. //------------------------------------------------------
  453. $sql = "INSERT INTO {analysisfeature} (feature_id, analysis_id) ".
  454. "VALUES (%d, %d)";
  455. $previous_db = tripal_db_set_active('chado');
  456. db_query ($sql, $feature_id, $analysis_id);
  457. tripal_db_set_active($previous_db);
  458. // Get the newly inserted analysisfeature_id
  459. $sql = "SELECT analysisfeature_id FROM {analysisfeature} WHERE feature_id = %d AND analysis_id = %d";
  460. $previous_db = tripal_db_set_active('chado');
  461. $analysisfeature_id = db_result(db_query($sql, $feature_id, $analysis_id));
  462. tripal_db_set_active($previous_db);
  463. //------------------------------------------------------
  464. // Insert into analysisfeatureprop table
  465. //------------------------------------------------------
  466. // Before inserting, make sure it's not a duplicate
  467. $sql = "SELECT value FROM {analysisfeatureprop} WHERE analysisfeature_id = %d AND type_id = %d";
  468. $previous_db = tripal_db_set_active('chado');
  469. $result = db_query($sql, $analysisfeature_id, $brite_data_type_id);
  470. tripal_db_set_active($previous_db);
  471. $duplicate = 0;
  472. while ($afp_value = db_fetch_object($result)) {
  473. preg_match("/<a.+?>(.+)<\/a>/",$afp_value->value,$old_ids);
  474. preg_match("/<a.+?>(.+)<\/a>/",$mat[2], $new_ids);
  475. if ($old_ids[1] && $old_ids[1] == $new_ids[1]) {
  476. $duplicate = 1;
  477. }
  478. }
  479. if (!$duplicate) {
  480. $sql = "INSERT INTO {analysisfeatureprop} (analysisfeature_id, type_id, value, rank)".
  481. "VALUES (%d, %d, '%s', %d)";
  482. $previous_db = tripal_db_set_active('chado');
  483. db_query($sql, $analysisfeature_id, $brite_data_type_id, $mat[2], $hi_rank);
  484. tripal_db_set_active($previous_db);
  485. }
  486. // Add link to each matched feature
  487. $feature_url = url("$prefix$feature_id");
  488. $matches[2] = preg_replace("/^(.*?)(;\s*\<a)/","<a id=\"tripal_kegg_feature_links\" target=\"_blank\" href=\"$base_path$prefix$feature_id\">"."$1"."</a>"."$2",$matches[2]);
  489. }
  490. $content .= "<li id=\"term_$id\"><a></a>$matches[2]\n";
  491. $id++;
  492. }
  493. $content .= "</ul>";
  494. fclose($handle);
  495. return $content;
  496. }
  497. /*******************************************************************************
  498. * HOOK: Implementation of hook_nodeapi()
  499. * Display library information for associated features or organisms
  500. * This function also provides contents for indexing
  501. */
  502. function tripal_analysis_kegg_nodeapi(&$node, $op, $teaser, $page) {
  503. switch ($op) {
  504. case 'view':
  505. // add the library to the organism/feature search indexing
  506. if($node->build_mode == NODE_BUILD_SEARCH_INDEX){
  507. $node->content['tripal_analysis_kegg_search_index'] = array(
  508. '#value' => theme('tripal_analysis_kegg_search_index',$node),
  509. '#weight' => 6,
  510. );
  511. } else if ($node->build_mode == NODE_BUILD_SEARCH_RESULT) {
  512. $node->content['tripal_analysis_kegg_search_result'] = array(
  513. '#value' => theme('tripal_analysis_kegg_search_result',$node),
  514. '#weight' => 6,
  515. );
  516. } else {
  517. switch($node->type){
  518. case 'chado_organism':
  519. // Show KEGG BRITE on an analysis page OR KEGG info box on a feature page
  520. $node->content['tripal_organism_kegg_summary'] = array(
  521. '#value' => theme('tripal_organism_kegg_summary', $node),
  522. '#weight' => 6
  523. );
  524. break;
  525. }
  526. }
  527. break;
  528. }
  529. }
  530. /************************************************************************
  531. * We need to let drupal know about our theme functions and their arguments.
  532. * We create theme functions to allow users of the module to customize the
  533. * look and feel of the output generated in this module
  534. */
  535. function tripal_analysis_kegg_theme () {
  536. return array(
  537. 'tripal_analysis_kegg_search_index' => array (
  538. 'arguments' => array('node'),
  539. ),
  540. 'tripal_analysis_kegg_search_result' => array (
  541. 'arguments' => array('node'),
  542. ),
  543. 'tripal_organism_kegg_summary' => array (
  544. 'arguments' => array('node'=> null),
  545. 'template' => 'tripal_organism_kegg_summary',
  546. ),
  547. 'tripal_analysis_kegg_report' => array (
  548. 'arguments' => array('node'=> null),
  549. 'template' => 'tripal_analysis_kegg_report',
  550. ),
  551. );
  552. }
  553. /**
  554. *
  555. *
  556. * @ingroup tripal_analysis_kegg
  557. */
  558. function tripal_analysis_kegg_preprocess(&$variables){
  559. // if the template file is the default node template file then we want
  560. // to add all of our variables.
  561. if($variables['template_files'][0] == 'node-chado_analysis_kegg'){
  562. $analysis = $variables['node']->analysis;
  563. $report = tripal_analysis_kegg_full_report($analysis->analysis_id);
  564. $analysis->tripal_analysis_kegg->kegg_report = $report;
  565. }
  566. }
  567. /*******************************************************************************
  568. *
  569. */
  570. function tripal_analysis_kegg_preprocess_tripal_organism_kegg_summary(&$variables){
  571. $node = $variables['node'];
  572. $variables['tripal_analysis_kegg']['select_form'] = tripal_analysis_kegg_load_organism_kegg_summary($node);
  573. }
  574. /************************************************************************
  575. */
  576. function theme_tripal_analysis_kegg_search_index($node){
  577. if ($node->type == 'chado_feature') {
  578. // Find cvterm_id for 'kegg_brite_data'
  579. $sql = "SELECT cvterm_id
  580. FROM {cvterm} CVT
  581. INNER JOIN cv ON cv.cv_id = CVT.cv_id
  582. WHERE cv.name = 'tripal'
  583. AND CVT.name = '%s'";
  584. $previous_db = tripal_db_set_active('chado');
  585. $brite_data_type_id = db_result(db_query($sql, 'kegg_brite_data'));
  586. // Get analysis id
  587. $sql = "SELECT analysis_id AS aid
  588. FROM {analysisfeature} AF
  589. INNER JOIN analysisfeatureprop AFP ON AF.analysisfeature_id = AFP.analysisfeature_id
  590. WHERE feature_id = %d
  591. AND AFP.type_id = %d
  592. GROUP BY analysis_id";
  593. $feature = $node->feature;
  594. $feature_id = $feature->feature_id;
  595. $hasResult = db_result(db_query($sql, $feature_id, $brite_data_type_id));
  596. $result = db_query($sql, $feature->feature_id, $brite_data_type_id);
  597. // Show kegg result ORDER BY time
  598. if ($hasResult) { // If there is any result, show expandable box
  599. $content = "";
  600. while ($ana = db_fetch_object($result)) {
  601. // Show analysis date
  602. $sql = "SELECT name, to_char(timeexecuted, 'MM-DD-YYYY') AS time
  603. FROM {analysis}
  604. WHERE analysis_id = %d";
  605. $ana_details = db_fetch_object(db_query($sql, $ana->aid));
  606. // Find node id for the analysis
  607. tripal_db_set_active($previous_db);
  608. $ana_nid = db_result(db_query("SELECT nid FROM {chado_analysis} WHERE analysis_id = %d", $ana->aid));
  609. $ana_url = url("node/".$ana_nid);
  610. $previous_db = tripal_db_set_active('chado');
  611. // Show content
  612. $content .= "$ana_details->name";
  613. // Show Kegg results
  614. $sql = "SELECT AFP.value AS afpvalue
  615. FROM {analysisfeatureprop} AFP
  616. INNER JOIN analysisfeature AF on AF.analysisfeature_id = AFP.analysisfeature_id
  617. WHERE AF.analysis_id = %d
  618. AND AF.feature_id = %d
  619. ";
  620. $kegg_results = db_query($sql, $ana->aid, $feature_id);
  621. while ($afp = db_fetch_object($kegg_results)) {
  622. $content .= " $afp->afpvalue";
  623. }
  624. }
  625. }
  626. tripal_db_set_active($previous_db);
  627. return $content;
  628. }
  629. }
  630. /************************************************************************
  631. */
  632. function theme_tripal_analysis_kegg_search_result($node){
  633. $content = theme_tripal_analysis_kegg_node_add($node);
  634. return $content;
  635. }
  636. /************************************************************************
  637. */
  638. function tripal_analysis_kegg_load_organism_kegg_summary($node) {
  639. $organism = $node->organism;
  640. // find analyses that have KEGG terms
  641. $sql = "
  642. SELECT *
  643. FROM {kegg_by_organism} KBO
  644. WHERE organism_id = %d
  645. ORDER BY analysis_id DESC
  646. ";
  647. $previous_db = tripal_db_set_active('chado');
  648. $results = db_fetch_object(db_query($sql,$organism->organism_id));
  649. tripal_db_set_active($previous_db);
  650. $has_results = 0;
  651. if($results){
  652. $has_results = 1;
  653. }
  654. return array (
  655. 'has_results' => $has_results,
  656. 'form' => drupal_get_form('tripal_analysis_kegg_select_form',$node),
  657. );
  658. }
  659. /************************************************************************
  660. // Show Kegg additional information on a KEGG Analysis page
  661. if ($node->type == 'chado_analysis_kegg') {
  662. return tripal_analysis_kegg_full_report($node->analysis_id);
  663. }
  664. // Show Kegg-info-box on a Feature page
  665. else if ($node->type == 'chado_feature') {
  666. return tripal_analysis_kegg_feature_add($node);
  667. }
  668. return $content;
  669. }
  670. */
  671. function tripal_analysis_kegg_org_report($analysis_id){
  672. $content = tripal_analysis_kegg_full_report($analysis_id);
  673. $opt = array($content);
  674. return drupal_json($opt);
  675. }
  676. /************************************************************************
  677. */
  678. function tripal_analysis_kegg_full_report($analysis_id){
  679. // Test if brite data have been parsed into the database
  680. $sql = "SELECT CVT.name, CVT.cvterm_id
  681. FROM {cvterm} CVT
  682. INNER JOIN analysisprop AP ON CVT.cvterm_id = AP.type_id
  683. WHERE AP.analysis_id = %d
  684. AND CVT.definition LIKE 'KEGG BRITE term: %'
  685. ORDER BY CVT.cvterm_id";
  686. $previous_db = tripal_db_set_active('chado');
  687. $result = db_query($sql, $analysis_id);
  688. tripal_db_set_active($previous_db);
  689. if (db_result($result)) {
  690. $content = tripal_analysis_kegg_brite($analysis_id, $type_id, 0);
  691. } else {
  692. $content = "<i>Note:</i> Analysis result is not available. Please schedule and run the job to parse the kegg output.";
  693. }
  694. return $content;
  695. }
  696. /*******************************************************************************
  697. * Tripal Kegg administrative setting form. This function is called by
  698. * tripal_analysis module which asks for an admin form to show on the page
  699. */
  700. function tripal_analysis_kegg_get_settings() {
  701. // Get an array of node types with internal names as keys
  702. $options = node_get_types('names');
  703. // Add 'chado_feature' to allowed content types for showing kegg results
  704. $allowedoptions ['chado_feature'] = "Show KEGG results on feature pages";
  705. $allowedoptions ['chado_analysis_kegg'] = "Show KEGG BRITE results on the analysis page.";
  706. $allowedoptions ['chado_organism'] = "Show KEGG BRITE results on the organism pages.";
  707. $form['description'] = array(
  708. '#type' => 'item',
  709. '#value' => t("Some chado features were analyzed by KEGG automatic annotation server (KAAS). This option allows user to display the kegg analysis results. Please read user manual for storage and display of kegg files. Check the box to enable the analysis results. Uncheck to disable it."),
  710. '#weight' => 0,
  711. );
  712. $form['tripal_analysis_kegg_setting'] = array(
  713. '#type' => 'checkboxes',
  714. '#options' => $allowedoptions,
  715. '#default_value' => variable_get('tripal_analysis_kegg_setting',
  716. array('chado_feature', 'chado_analysis_kegg')),
  717. );
  718. $settings->form = $form;
  719. $settings->title = "Tripal Kegg";
  720. return $settings;
  721. }
  722. /************************************************************************
  723. */
  724. function tripal_analysis_kegg_organism_results($node) {
  725. $node = node_load($node);
  726. return tripal_analysis_kegg_organism_add($node);
  727. }
  728. /************************************************************************
  729. */
  730. function tripal_analysis_kegg_feature_add($node) {
  731. // Find cvterm_id for 'kegg_brite_data'
  732. $sql = "SELECT cvterm_id
  733. FROM {cvterm} CVT
  734. INNER JOIN cv ON cv.cv_id = CVT.cv_id
  735. WHERE cv.name = 'tripal'
  736. AND CVT.name = '%s'";
  737. $previous_db = tripal_db_set_active('chado');
  738. $brite_data_type_id = db_result(db_query($sql, 'kegg_brite_data'));
  739. // Get analysis id
  740. $sql = "SELECT analysis_id AS aid
  741. FROM {analysisfeature} AF
  742. INNER JOIN analysisfeatureprop AFP ON AF.analysisfeature_id = AFP.analysisfeature_id
  743. WHERE feature_id = %d
  744. AND AFP.type_id = %d
  745. GROUP BY analysis_id";
  746. $feature = $node->feature;
  747. $feature_id = $feature->feature_id;
  748. $hasResult = db_result(db_query($sql, $feature_id, $brite_data_type_id));
  749. $result = db_query($sql, $feature->feature_id, $brite_data_type_id);
  750. // Show kegg result ORDER BY time
  751. if ($hasResult) { // If there is any result, show expandable box
  752. $content .= "<div id=\"tripal_kegg-hits\" class=\"tripal_kegg-info-box\">
  753. <table class=\"tripal_kegg_results_table\">
  754. <tr><td>";
  755. while ($ana = db_fetch_object($result)) {
  756. // Show analysis date
  757. $sql = "SELECT name, to_char(timeexecuted, 'MM-DD-YYYY') AS time
  758. FROM {analysis}
  759. WHERE analysis_id = %d";
  760. $ana_details = db_fetch_object(db_query($sql, $ana->aid));
  761. // Find node id for the analysis
  762. tripal_db_set_active($previous_db);
  763. $ana_nid = db_result(db_query("SELECT nid FROM {chado_analysis} WHERE analysis_id = %d", $ana->aid));
  764. $ana_url = url("node/".$ana_nid);
  765. $previous_db = tripal_db_set_active('chado');
  766. // Show content
  767. $content .= "<strong>Analysis Date:</strong> $ana_details->time
  768. (<a href=$ana_url>$ana_details->name</a>)<br>";
  769. // Show Kegg results
  770. $sql = "SELECT AFP.value AS afpvalue
  771. FROM {analysisfeatureprop} AFP
  772. INNER JOIN analysisfeature AF on AF.analysisfeature_id = AFP.analysisfeature_id
  773. WHERE AF.analysis_id = %d
  774. AND AF.feature_id = %d
  775. ";
  776. $kegg_results = db_query($sql, $ana->aid, $feature_id);
  777. while ($afp = db_fetch_object($kegg_results)) {
  778. $content .= "$afp->afpvalue<br>";
  779. }
  780. $content .= "<br>";
  781. }
  782. $content .= '</td></tr></table></div>';
  783. }
  784. tripal_db_set_active($previous_db);
  785. return $content;
  786. }
  787. /************************************************************************
  788. */
  789. function tripal_analysis_kegg_select_form(&$form_state = NULL,$node){
  790. $form = array();
  791. // find analyses that have KEGG terms
  792. $sql = "
  793. SELECT *
  794. FROM {kegg_by_organism} KBO
  795. WHERE organism_id = %d
  796. ORDER BY analysis_id DESC
  797. ";
  798. $previous_db = tripal_db_set_active('chado');
  799. $results = db_query($sql,$node->organism->organism_id);
  800. tripal_db_set_active($previous_db);
  801. $analyses = array();
  802. $analyses[''] = '';
  803. while($analysis = db_fetch_object($results)){
  804. $analyses[$analysis->analysis_id] = "$analysis->analysis_name";
  805. }
  806. # create the select box
  807. $form['tripal_analysis_kegg_select'] = array(
  808. '#title' => t('Select a KEGG report to view'),
  809. '#description' => t('Any analysis with KEGG results related to this organism are available for viewing. For further information, see the analysis information page.'),
  810. '#type' => 'select',
  811. '#options' => $analyses,
  812. '#attributes' => array (
  813. 'onchange' => 'tripal_analysis_kegg_org_report(this.options[this.selectedIndex].value)'
  814. ),
  815. );
  816. return $form;
  817. }