tripal_analysis.module 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098
  1. <?php
  2. /**
  3. * @file
  4. * Contains all the main hook implementations for the tripal_analysis module
  5. *
  6. * @defgroup tripal_analysis Analysis Module
  7. * @{
  8. * Provides functions for managing chado analysis' including creating details pages for each one
  9. * @}
  10. * @ingroup tripal_modules
  11. */
  12. require('tripal_analysis.api.inc');
  13. require('tripal_analysis_privacy.inc');
  14. /**
  15. * Register tripal_analysis sub-modules
  16. *
  17. * @param $modulename
  18. * The name of the module to be registered as a tripal analysis submodule
  19. *
  20. * @ingroup tripal_analysis
  21. */
  22. function tripal_analysis_register_child($modulename) {
  23. $sql = "INSERT INTO {tripal_analysis} (modulename) VALUES ('%s')";
  24. db_query($sql, $modulename);
  25. }
  26. /**
  27. * Un-register a tripal analysis sub-module
  28. *
  29. * @param $modulename
  30. * The name of the module to un-register
  31. *
  32. * @ingroup tripal_analysis
  33. */
  34. function tripal_analysis_unregister_child($modulename) {
  35. if (db_table_exists('tripal_analysis')) {
  36. $sql = "DELETE FROM {tripal_analysis} WHERE modulename = '%s'";
  37. db_query($sql, $modulename);
  38. }
  39. }
  40. /**
  41. * Add tripal javascript to page headers
  42. *
  43. * @ingroup tripal_analysis
  44. */
  45. function tripal_analysis_init() {
  46. drupal_add_js(drupal_get_path('theme', 'tripal') . '/js/tripal_analysis.js');
  47. }
  48. /**
  49. * Implementation of hook_menu().
  50. * Entry points and paths of the module
  51. *
  52. * @ingroup tripal_analysis
  53. */
  54. function tripal_analysis_menu() {
  55. // Display available analyses
  56. $items['analyses'] = array(
  57. 'menu_name' => ('primary-links'), //Enable the 'Analysis' primary link
  58. 'title' => 'Analyses',
  59. 'page callback' => 'tripal_analysis_show_analyses',
  60. 'access arguments' => array('access chado_analysis content'),
  61. 'type' => MENU_NORMAL_ITEM
  62. );
  63. //Sync analysis
  64. $items['chado_sync_analyses'] = array(
  65. 'title' => 'Sync Data',
  66. 'page callback' => 'tripal_analysis_sync_analyses',
  67. 'access arguments' => array('administer site configuration'),
  68. 'type' => MENU_CALLBACK
  69. );
  70. // Tripal Analysis administrative settings
  71. $items['admin/tripal/tripal_analysis'] = array(
  72. 'title' => 'Analyses',
  73. 'description' => 'Basic Description of Tripal Analysis Module Functionality.',
  74. 'page callback' => 'tripal_analysis_module_description_page',
  75. 'access arguments' => array('administer site configuration'),
  76. 'type' => MENU_NORMAL_ITEM,
  77. 'file' => 'tripal_analysis.admin.inc',
  78. );
  79. $items['admin/tripal/tripal_analysis/configuration'] = array(
  80. 'title' => 'Configuration',
  81. 'description' => 'Settings for the displays of analysis results.',
  82. 'page callback' => 'drupal_get_form',
  83. 'page arguments' => array('tripal_analysis_admin'),
  84. 'access arguments' => array('administer site configuration'),
  85. 'type' => MENU_NORMAL_ITEM,
  86. 'file' => 'tripal_analysis.admin.inc',
  87. );
  88. return $items;
  89. }
  90. /**
  91. * Display the summary view of analyses when click on the 'Analyses'
  92. * primary-link
  93. *
  94. * @ingroup tripal_analysis
  95. */
  96. function tripal_analysis_show_analyses() {
  97. // Show libraries stored in Drupal's {chado_analysis} table
  98. $sql = "SELECT COUNT(analysis_id) FROM {chado_analysis}";
  99. $no_ana = db_result(db_query($sql));
  100. if ($no_ana != 0) {
  101. $analyses = get_chado_analyses();
  102. return theme('tripal_analysis_analysis_page', $analyses);
  103. }
  104. else {
  105. return t("No analysis available at this time.");
  106. }
  107. }
  108. /**
  109. * Provide information to drupal about the node types that we're creating
  110. * in this module
  111. *
  112. * @ingroup tripal_analysis
  113. */
  114. function tripal_analysis_node_info() {
  115. $nodes = array();
  116. $nodes['chado_analysis'] = array(
  117. 'name' => t('Analysis'),
  118. 'module' => 'chado_analysis',
  119. 'description' => t('An analysis from the chado database'),
  120. 'has_title' => FALSE,
  121. 'title_label' => t('Analysis'),
  122. 'has_body' => FALSE,
  123. 'body_label' => t('Analysis Description'),
  124. 'locked' => TRUE
  125. );
  126. return $nodes;
  127. }
  128. /**
  129. * When a new chado_analysis node is created we also need to add information
  130. * to our chado_analysis table. This function is called on insert of a new
  131. * node of type 'chado_analysis' and inserts the necessary information.
  132. *
  133. * @ingroup tripal_analysis
  134. */
  135. function chado_analysis_insert($node) {
  136. global $user;
  137. // Create a timestamp so we can insert it into the chado database
  138. $time = $node->timeexecuted;
  139. $month = $time['month'];
  140. $day = $time['day'];
  141. $year = $time['year'];
  142. $timestamp = $month . '/' . $day . '/' . $year;
  143. // If this analysis already exists then don't recreate it in chado
  144. $analysis_id = $node->analysis_id;
  145. if ($analysis_id) {
  146. $sql = "SELECT analysis_id ".
  147. "FROM {Analysis} ".
  148. "WHERE analysis_id = %d ";
  149. $previous_db = tripal_db_set_active('chado');
  150. $analysis = db_fetch_object(db_query($sql, $node->analysis_id));
  151. tripal_db_set_active($previous_db);
  152. }
  153. // If the analysis doesn't exist then let's create it in chado.
  154. if (!$analysis) {
  155. // insert and then get the newly inserted analysis record
  156. $values = array(
  157. 'name' => $node->analysisname,
  158. 'description' => $node->description,
  159. 'program' => $node->program,
  160. 'programversion' => $node->programversion,
  161. 'algorithm' => $node->algorithm,
  162. 'sourcename' => $node->sourcename,
  163. 'sourceversion' => $node->sourceversion,
  164. 'sourceuri' => $node->sourceuri,
  165. 'timeexecuted' => $timestamp
  166. );
  167. if (tripal_core_chado_insert('analysis', $values)) {
  168. $analysis = tripal_core_chado_select('analysis', array('*'), $values);
  169. $analysis_id = $analysis[0]->analysis_id;
  170. }
  171. }
  172. // Make sure the entry for this analysis doesn't already exist in the
  173. // chado_analysis table if it doesn't exist then we want to add it.
  174. $node_check_sql = "SELECT * FROM {chado_analysis} ".
  175. "WHERE analysis_id = %d";
  176. $node_check = db_fetch_object(db_query($node_check_sql, $analysis_id));
  177. if (!$node_check) {
  178. // next add the item to the drupal table
  179. $sql = "INSERT INTO {chado_analysis} (nid, vid, analysis_id) ".
  180. "VALUES (%d, %d, %d)";
  181. db_query($sql, $node->nid, $node->vid, $analysis_id);
  182. // Create a title for the analysis node using the unique keys so when the
  183. // node is saved, it will have a title
  184. $record = new stdClass();
  185. // If the analysis has a name, use it as the node title. If not, construct
  186. // the title using program, programversion, and sourcename
  187. if ($node->analysisname) {
  188. $record->title = $node->analysisname;
  189. }
  190. else {
  191. //Construct node title as "program (version)
  192. $record->title = "$node->program ($node->programversion)";
  193. }
  194. $record->nid = $node->nid;
  195. drupal_write_record('node', $record, 'nid');
  196. drupal_write_record('node_revisions', $record, 'nid');
  197. }
  198. if ($node->setpermissions) {
  199. $job_args[0] = $analysis_id;
  200. $job_args[1] = $node->nid;
  201. tripal_add_job("Set permission for analysis associated features", 'tripal_analysis',
  202. 'tripal_analysis_set_feature_permission', $job_args, $user->uid);
  203. }
  204. // add the analysis to the node object for
  205. // use by other analysis modules that may be using this function
  206. $node->analysis = $analysis;
  207. $node->analysis_id = $analysis_id; // we need to set this for children
  208. }
  209. /**
  210. * Removes analysis from the chado database
  211. *
  212. * @param $node
  213. * The node object specifying which chado record to delete
  214. *
  215. * @ingroup tripal_analysis
  216. */
  217. function chado_analysis_delete($node) {
  218. // Before removing, get analysis_id so we can remove it from chado database
  219. // later
  220. $sql_drupal = "SELECT analysis_id ".
  221. "FROM {chado_analysis} ".
  222. "WHERE nid = %d ".
  223. "AND vid = %d";
  224. $analysis_id = db_result(db_query($sql_drupal, $node->nid, $node->vid));
  225. // Remove data from the {chado_analysis}, {node}, and {node_revisions} tables
  226. $sql_del = "DELETE FROM {chado_analysis} ".
  227. "WHERE nid = %d ".
  228. "AND vid = %d";
  229. db_query($sql_del, $node->nid, $node->vid);
  230. $sql_del = "DELETE FROM {node} ".
  231. "WHERE nid = %d ".
  232. "AND vid = %d";
  233. db_query($sql_del, $node->nid, $node->vid);
  234. $sql_del = "DELETE FROM {node_revisions} ".
  235. "WHERE nid = %d ".
  236. "AND vid = %d";
  237. db_query($sql_del, $node->nid, $node->vid);
  238. //Remove from analysis and analysisprop tables of chado database as well
  239. $previous_db = tripal_db_set_active('chado');
  240. db_query("DELETE FROM {analysis} WHERE analysis_id = %d", $analysis_id);
  241. tripal_db_set_active($previous_db);
  242. }
  243. /**
  244. * Update analyses
  245. *
  246. * @param $node
  247. * The updated node object
  248. *
  249. * @ingroup tripal_analysis
  250. */
  251. function chado_analysis_update($node) {
  252. global $user;
  253. if ($node->revision) {
  254. // TODO -- decide what to do about revisions
  255. }
  256. else {
  257. // Create a timestamp so we can insert it into the chado database
  258. $time = $node->timeexecuted;
  259. $month = $time['month'];
  260. $day = $time['day'];
  261. $year = $time['year'];
  262. $timestamp = $month . '/' . $day . '/' . $year;
  263. // get the analysis_id for this node:
  264. $sql = "SELECT analysis_id ".
  265. "FROM {chado_analysis} ".
  266. "WHERE nid = %d";
  267. $analysis_id = db_fetch_object(db_query($sql, $node->nid))->analysis_id;
  268. $sql = "UPDATE {analysis} ".
  269. "SET name = '%s', ".
  270. " description = '%s', ".
  271. " program = '%s', ".
  272. " programversion = '%s', ".
  273. " algorithm = '%s', ".
  274. " sourcename = '%s', ".
  275. " sourceversion = '%s', ".
  276. " sourceuri = '%s', ".
  277. " timeexecuted = '%s' ".
  278. "WHERE analysis_id = %d ";
  279. $previous_db = tripal_db_set_active('chado'); // use chado database
  280. db_query($sql, $node->analysisname, $node->description, $node->program,
  281. $node->programversion, $node->algorithm, $node->sourcename,
  282. $node->sourceversion, $node->sourceuri, $timestamp, $analysis_id);
  283. tripal_db_set_active($previous_db); // switch back to drupal database
  284. // Create a title for the analysis node using the unique keys so when the
  285. // node is saved, it will have a title
  286. $record = new stdClass();
  287. // If the analysis has a name, use it as the node title. If not, construct
  288. // the title using program, programversion, and sourcename
  289. if ($node->analysisname) {
  290. $record->title = $node->analysisname;
  291. }
  292. else {
  293. //Construct node title as "program (version)
  294. $record->title = "$node->program ($node->programversion)";
  295. }
  296. if ($node->setpermissions) {
  297. $job_args[0] = $analysis_id;
  298. $job_args[1] = $node->nid;
  299. tripal_add_job("Set permission for analysis associated features", 'tripal_analysis',
  300. 'tripal_analysis_set_feature_permission', $job_args, $user->uid);
  301. }
  302. $record->nid = $node->nid;
  303. drupal_write_record('node', $record, 'nid');
  304. drupal_write_record('node_revisions', $record, 'nid');
  305. }
  306. }
  307. /**
  308. * When editing or creating a new node of type 'chado_analysis' we need
  309. * a form. This function creates the form that will be used for this.
  310. *
  311. * @ingroup tripal_analysis
  312. */
  313. function chado_analysis_form($node) {
  314. $analysis = $node->analysis;
  315. // add in the description column. It is a text field and may not be included
  316. // if the text is too big.
  317. $analysis = tripal_core_expand_chado_vars($analysis, 'field', 'analysis.description');
  318. // get form defaults
  319. $analysis_id = $node->analysis_id;
  320. if (!$analysis_id) {
  321. $analysis_id = $analysis->analysis_id;
  322. }
  323. $analysisname = $node->analysisname;
  324. if (!$analysisname) {
  325. $analysisname = $analysis->name;
  326. }
  327. $program = $node->program;
  328. if (!$program) {
  329. $program = $analysis->program;
  330. }
  331. $programversion = $node->programversion;
  332. if (!$programversion) {
  333. $programversion = $analysis->programversion;
  334. }
  335. $algorithm = $node->algorithm;
  336. if (!$algorithm) {
  337. $algorithm = $analysis->algorithm;
  338. }
  339. $sourcename = $node->sourcename;
  340. if (!$sourcename) {
  341. $sourcename = $analysis->sourcename;
  342. }
  343. $sourceversion = $node->sourceversion;
  344. if (!$sourceversion) {
  345. $sourceversion = $analysis->sourceversion;
  346. }
  347. $sourceuri = $node->sourceuri;
  348. if (!$sourceuri) {
  349. $sourceuri = $analysis->sourceuri;
  350. }
  351. $timeexecuted = $node->timeexecuted;
  352. if (!$timeexecuted) {
  353. $timeexecuted = $analysis->timeexecuted;
  354. }
  355. $description = $node->description;
  356. if (!$description) {
  357. $description = $analysis->description;
  358. }
  359. $form = array();
  360. $form['title']= array(
  361. '#type' => 'hidden',
  362. '#default_value' => $node->title,
  363. );
  364. $form['analysis_id']= array(
  365. '#type' => 'hidden',
  366. '#default_value' => $analysis_id,
  367. );
  368. $form['analysisname']= array(
  369. '#type' => 'textfield',
  370. '#title' => t('Analysis Name'),
  371. '#required' => FALSE,
  372. '#default_value' => $analysisname,
  373. '#description' => t("This should be a handy short identifier that
  374. describes the analysis succintly as possible which helps the user find analyses."),
  375. );
  376. $form['program']= array(
  377. '#type' => 'textfield',
  378. '#title' => t('Program'),
  379. '#required' => TRUE,
  380. '#default_value' => $program,
  381. '#description' => t("Program name, e.g. blastx, blastp, sim4, genscan."),
  382. );
  383. $form['programversion']= array(
  384. '#type' => 'textfield',
  385. '#title' => t('Program Version'),
  386. '#required' => TRUE,
  387. '#default_value' => $programversion,
  388. '#description' => t("Version description, e.g. TBLASTX 2.0MP-WashU [09-Nov-2000]"),
  389. );
  390. $form['algorithm']= array(
  391. '#type' => 'textfield',
  392. '#title' => t('Algorithm'),
  393. '#required' => FALSE,
  394. '#default_value' => $algorithm,
  395. '#description' => t("Algorithm name, e.g. blast."),
  396. );
  397. $form['sourcename']= array(
  398. '#type' => 'textfield',
  399. '#title' => t('Source Name'),
  400. '#required' => TRUE,
  401. '#default_value' => $sourcename,
  402. '#description' => t('The name of the source data. This could be a file name, data set name or a
  403. small description for how the data was collected. For long descriptions use the description field below'),
  404. );
  405. $form['sourceversion']= array(
  406. '#type' => 'textfield',
  407. '#title' => t('Source Version'),
  408. '#required' => FALSE,
  409. '#default_value' => $sourceversion,
  410. '#description' => t('If the source dataset has a version, include it here'),
  411. );
  412. $form['sourceuri']= array(
  413. '#type' => 'textfield',
  414. '#title' => t('Source URI'),
  415. '#required' => FALSE,
  416. '#default_value' => $sourceuri,
  417. '#description' => t("This is a permanent URL or URI for the source of the analysis.
  418. Someone could recreate the analysis directly by going to this URI and
  419. fetching the source data (e.g. the blast database, or the training model)."),
  420. );
  421. // Get time saved in chado
  422. $default_time = $timeexecuted;
  423. $year = preg_replace("/^(\d+)-\d+-\d+ .*/", "$1", $default_time);
  424. $month = preg_replace("/^\d+-0?(\d+)-\d+ .*/", "$1", $default_time);
  425. $day = preg_replace("/^\d+-\d+-0?(\d+) .*/", "$1", $default_time);
  426. // If the time is not set, use current time
  427. if (!$default_time) {
  428. $default_time = time();
  429. $year = format_date($default_time, 'custom', 'Y');
  430. $month = format_date($default_time, 'custom', 'n');
  431. $day = format_date($default_time, 'custom', 'j');
  432. }
  433. $form['timeexecuted']= array(
  434. '#type' => 'date',
  435. '#title' => t('Time Executed'),
  436. '#required' => TRUE,
  437. '#default_value' => array(
  438. 'year' => $year,
  439. 'month' => $month,
  440. 'day' => $day,
  441. ),
  442. );
  443. $form['description']= array(
  444. '#type' => 'textarea',
  445. '#rows' => 15,
  446. '#title' => t('Description and/or Program Settings'),
  447. '#required' => FALSE,
  448. '#default_value' => $description,
  449. '#description' => t('Please provide all necessary information to allow
  450. someone to recreate the analysis, including materials and methods
  451. for collection of the source data and performing the analysis'),
  452. );
  453. /* Set permissions for all features associated with this analysis */
  454. if (module_exists('node_privacy_byrole')) {
  455. $form['setpermissions'] = array(
  456. '#type' => 'checkbox',
  457. '#title' => t('Submit a job to set the same permissions for all features associated with this analysis'),
  458. '#default_value' => FALSE,
  459. '#weight' => 10
  460. );
  461. }
  462. return $form;
  463. }
  464. /**
  465. * When a node is requested by the user this function is called to allow us
  466. * to add auxiliary data to the node object.
  467. *
  468. * @ingroup tripal_analysis
  469. */
  470. function chado_analysis_load($node) {
  471. // get the feature details from chado
  472. $analysis_id = chado_get_id_for_node('analysis', $node);
  473. $values = array('analysis_id' => $analysis_id);
  474. $analysis = tripal_core_generate_chado_var('analysis', $values);
  475. $additions = new stdClass();
  476. $additions->analysis = $analysis;
  477. return $additions;
  478. }
  479. /**
  480. * This function customizes the view of the chado_analysis node. It allows
  481. * us to generate the markup.
  482. *
  483. * @ingroup tripal_analysis
  484. */
  485. function chado_analysis_view($node, $teaser = FALSE, $page = FALSE) {
  486. // use drupal's default node view:
  487. if (!$teaser) {
  488. $node = node_prepare($node, $teaser);
  489. // When previewing a node submitting form, it shows 'Array' instead of
  490. // correct date format. We need to format the date here
  491. $time = $node->timeexecuted;
  492. if (is_array($time)) {
  493. $month = $time['month'];
  494. $day = $time['day'];
  495. $year = $time['year'];
  496. $timestamp = $year . '-' . $month . '-' . $day;
  497. $node->timeexecuted = $timestamp;
  498. }
  499. }
  500. return $node;
  501. }
  502. /**
  503. * Synchronize analyses from chado to drupal
  504. *
  505. * @ingroup tripal_analysis
  506. */
  507. function tripal_analysis_sync_analyses($analysis_id = NULL, $job_id = NULL) {
  508. global $user;
  509. $page_content = '';
  510. if (!$analysis_id) {
  511. $sql = "SELECT Analysis_id, name, description, program, ".
  512. " programversion, algorithm, sourcename, sourceversion, sourceuri, ".
  513. " timeexecuted ".
  514. "FROM {Analysis} ";
  515. $previous_db = tripal_db_set_active('chado'); // use chado database
  516. $results = db_query($sql);
  517. tripal_db_set_active($previous_db); // now use drupal database
  518. }
  519. else {
  520. $sql = "SELECT Analysis_id, name, description, program, ".
  521. " programversion, algorithm, sourcename, sourceversion, sourceuri, ".
  522. " timeexecuted ".
  523. "FROM {Analysis} ".
  524. "WHERE analysis_id = %d";
  525. $previous_db = tripal_db_set_active('chado'); // use chado database
  526. $results = db_query($sql, $analysis_id);
  527. tripal_db_set_active($previous_db); // now use drupal database
  528. }
  529. // We'll use the following SQL statement for checking if the analysis
  530. // already exists as a drupal node.
  531. $sql = "SELECT * FROM {chado_analysis} ".
  532. "WHERE analysis_id = %d";
  533. while ($analysis = db_fetch_object($results)) {
  534. print "syncing analysis ";
  535. print $analysis->name;
  536. print ", ";
  537. print $analysis->analysis_id;
  538. print "\n";
  539. // check if this analysis already exists in the drupal database. if it
  540. // does then skip this analysis and go to the next one.
  541. if (!db_fetch_object(db_query($sql, $analysis->analysis_id))) {
  542. $new_node = new stdClass();
  543. // try to access analysis type for this analysis
  544. $sql = "SELECT * FROM {analysisprop}
  545. WHERE analysis_id = %d
  546. AND type_id =
  547. (SELECT cvterm_id from {cvterm} where name = '%s')
  548. ";
  549. $previous_db = tripal_db_set_active('chado');
  550. $analysis_type = db_fetch_object(db_query($sql, $analysis->analysis_id, "analysis_type"));
  551. tripal_db_set_active($previous_db);
  552. // Get the type of analysis using cvterm_id
  553. // Current possibilities: kegg, unigene, interpro, blast
  554. if ($analysis_type) {
  555. // This is a unigene analysis
  556. if ($analysis_type->value == 'tripal_analysis_unigene') {
  557. $new_node->type = 'chado_analysis_unigene';
  558. // This is a blast analysis
  559. }
  560. elseif ($analysis_type->value == 'tripal_analysis_blast') {
  561. $new_node->type = 'chado_analysis_blast';
  562. // This is a interpro analysis
  563. }
  564. elseif ($analysis_type->value == 'tripal_analysis_interpro') {
  565. $new_node->type = 'chado_analysis_interpro';
  566. // This is a kegg analysis
  567. }
  568. elseif ($analysis_type->value == 'tripal_analysis_kegg' ) {
  569. $new_node->type = 'chado_analysis_kegg';
  570. }
  571. else {
  572. $new_node->type = 'chado_analysis';
  573. }
  574. // If it doesn't exist, this analysis is generic
  575. }
  576. else {
  577. $new_node->type = 'chado_analysis';
  578. }
  579. print "analysis type is $new_node->type\n";
  580. $new_node->uid = $user->uid;
  581. $new_node->analysis_id = $analysis->analysis_id;
  582. $new_node->analysisname = $analysis->name;
  583. $new_node->description = $analysis->description;
  584. $new_node->program = $analysis->program;
  585. $new_node->programversion = $analysis->programversion;
  586. $new_node->algorithm = $analysis->algorithm;
  587. $new_node->sourcename = $analysis->sourcename;
  588. $new_node->sourceversion = $analysis->sourceversion;
  589. $new_node->sourceuri = $analysis->sourceuri;
  590. $new_node->timeexecuted = $analysis->timeexecuted;
  591. // If the analysis has a name, use it as the node title. If not,
  592. // construct the title using program, programversion, and sourcename
  593. if ($new_node->analysisname) {
  594. $new_node->title = $new_node->analysisname;
  595. }
  596. else {
  597. //Construct node title as "program (version)"
  598. $new_node->title = "$analysis->program ($analysis->programversion)";
  599. }
  600. node_validate($new_node);
  601. $errors = form_get_errors();
  602. if ($errors) {
  603. print_r($errors);
  604. }
  605. else{
  606. // if(!form_get_errors()){
  607. $node = node_submit($new_node);
  608. node_save($node);
  609. if ($node->nid) {
  610. $page_content .= "Added $new_node->title<br />";
  611. }
  612. }
  613. }
  614. else {
  615. $page_content .= "Skipped $new_node->title<br />";
  616. }
  617. }
  618. return $page_content;
  619. }
  620. /**
  621. * Validates the user input before creating an analysis node
  622. *
  623. * @ingroup tripal_analysis
  624. */
  625. function chado_analysis_validate($node, &$form) {
  626. // use the analysis parent to validate the node
  627. tripal_analysis_validate($node, $form);
  628. }
  629. /**
  630. * This validation is being used for three activities:
  631. * CASE A: Update a node that exists in both drupal and chado
  632. * CASE B: Synchronizing a node from chado to drupal
  633. * CASE C: Inserting a new node that exists in niether drupal nor chado
  634. *
  635. * @ingroup tripal_analysis
  636. */
  637. function tripal_analysis_validate($node, &$form) {
  638. // Only nodes being updated will have an nid already
  639. if ($node->nid) {
  640. //---------------------------------------------------
  641. // CASE A: We are validating a form for updating an existing node
  642. //---------------------------------------------------
  643. // TO DO: check that the new fields don't yield a non-unique primary key in chado
  644. }
  645. else{
  646. // To differentiate if we are syncing or creating a new analysis altogther, see if an
  647. // analysis_id already exists
  648. if ($node->analysis_id) {
  649. //---------------------------------------------------
  650. // CASE B: Synchronizing a node from chado to drupal
  651. //---------------------------------------------------
  652. }
  653. else{
  654. //---------------------------------------------------
  655. // CASE C: We are validating a form for inserting a new node
  656. //---------------------------------------------------
  657. // The primary key for the chado analysis table is
  658. // program, programversion, sourcename
  659. $values = array(
  660. 'program' => $node->program,
  661. 'programversion' => $node->programversion,
  662. 'sourcename' => $node->sourcename,
  663. );
  664. $analysis = tripal_core_chado_select('analysis', array('analysis_id'), $values);
  665. if (sizeof($analysis) > 0) {
  666. form_set_error('program', 'Cannot add the analysis with this program,
  667. program version and source name. An analysis with these values already exists.');
  668. return;
  669. }
  670. }
  671. }
  672. }
  673. /**
  674. * Display help and module information
  675. * @param path which path of the site we're displaying help
  676. * @param arg array that holds the current path as would be returned from arg()
  677. * function
  678. * @return help text for the path
  679. *
  680. * @ingroup tripal_analysis
  681. */
  682. function tripal_analysis_help($path, $arg) {
  683. $output = '';
  684. switch ($path) {
  685. case "admin/help#tripal_analysis":
  686. $output = '<p>' .
  687. t("Displays links to nodes created on this date") .
  688. '</p>';
  689. break;
  690. }
  691. return $output;
  692. }
  693. /**
  694. * The following function proves access control for users trying to
  695. * perform actions on data managed by this module
  696. *
  697. * @ingroup tripal_analysis
  698. */
  699. function chado_analysis_access($op, $node, $account) {
  700. if ($op == 'create') {
  701. if (!user_access('create chado_analysis content', $account)) {
  702. return FALSE;
  703. }
  704. }
  705. if ($op == 'update') {
  706. if (!user_access('edit chado_analysis content', $account)) {
  707. return FALSE;
  708. }
  709. }
  710. if ($op == 'delete') {
  711. if (!user_access('delete chado_analysis content', $account)) {
  712. return FALSE;
  713. }
  714. }
  715. if ($op == 'view') {
  716. if (!user_access('access chado_analysis content', $account)) {
  717. return FALSE;
  718. }
  719. }
  720. return NULL;
  721. }
  722. /**
  723. * Set the permission types that the chado module uses. Essentially we
  724. * want permissionis that protect creation, editing and deleting of chado
  725. * data objects
  726. *
  727. * @ingroup tripal_analysis
  728. */
  729. function tripal_analysis_perm() {
  730. return array(
  731. 'access chado_analysis content',
  732. 'create chado_analysis content',
  733. 'delete chado_analysis content',
  734. 'edit chado_analysis content',
  735. );
  736. }
  737. /**
  738. * We need to let drupal know about our theme functions and their arguments.
  739. * We create theme functions to allow users of the module to customize the
  740. * look and feel of the output generated in this module
  741. *
  742. * @ingroup tripal_analysis
  743. */
  744. function tripal_analysis_theme() {
  745. return array(
  746. 'tripal_analysis_analysis_page' => array(
  747. 'arguments' => array('analyses'),
  748. ),
  749. );
  750. }
  751. /**
  752. * This function uses analysis_id's of all drupal analysis nodes as input and
  753. * pull the analysis information (name, description, program, programversion,
  754. * algorithm, sourcename, sourceversion, sourceuri, timeexecuted) from
  755. * chado database. The return type is an object array that stores $analysis
  756. * objects sorted by program
  757. *
  758. * @ingroup tripal_analysis
  759. */
  760. function get_chado_analyses() {
  761. $sql_drupal = "SELECT COUNT (analysis_id) FROM {chado_analysis}";
  762. $no_orgs = db_result(db_query($sql_drupal));
  763. if ($no_orgs != 0) {
  764. $sql = "SELECT analysis_id, CA.nid, type FROM {chado_analysis} CA INNER JOIN node ON CA.nid = node.nid";
  765. $result = db_query($sql);
  766. $previous_db = tripal_db_set_active('chado');
  767. $sql = "SELECT Analysis_id, name, description, program,
  768. programversion, algorithm, sourcename, sourceversion,
  769. sourceuri, timeexecuted
  770. FROM {Analysis} WHERE analysis_id=%d";
  771. $analyses = array();
  772. $count = 0;
  773. while ($data = db_fetch_object($result)) {
  774. $analysis = db_fetch_object(db_query($sql, $data->analysis_id));
  775. $analysis->node_id = $data->nid;
  776. $analysis->node_type = $data->type;
  777. // Use node_type as the key so we can sort by node type
  778. // Since node_type is not unique by itself, we need to add
  779. // $count to the key
  780. $sortedBy = $analysis->timeexecuted;
  781. $analyses ["$sortedBy$count"] = $analysis;
  782. $count ++;
  783. }
  784. tripal_db_set_active($previous_db);
  785. //Sort analyses by time, descending order
  786. krsort($analyses, SORT_STRING);
  787. return $analyses;
  788. }
  789. }
  790. /**
  791. * Theme the List Analysis page
  792. *
  793. * @param $analyses
  794. * An array of analyses to list
  795. *
  796. * @ingroup tripal_analysis
  797. */
  798. function theme_tripal_analysis_analysis_page($analyses) {
  799. $output = "<br />Analyses are listed in the descending order of their execution time.<br /><a id=\"tripal_expandableBox_toggle_button\" onClick=\"toggleExpandableBoxes()\">[-] Collapse All</a>";
  800. foreach ($analyses as $analysis) {
  801. // Prepare information for html output
  802. $ana_node_url = url("node/$analysis->node_id");
  803. if ($analysis->sourceversion) {
  804. $ver = "($analysis->sourceversion)";
  805. }
  806. $date = preg_replace("/^(\d+-\d+-\d+) .*/", "$1", $analysis->timeexecuted);
  807. // Generate html output
  808. $output .= "<div class=\"tripal_chado_analysis-info-box\" style=\"padding:5px\">
  809. <div class=\"tripal_expandableBox\">
  810. <h3>$analysis->name ($date)</h3>
  811. </div>
  812. <div class=\"tripal_expandableBoxContent\">
  813. <span>
  814. <table class=\"tripal_chado_analysis_content\">
  815. <tr><td>
  816. Name: <a href=\"$ana_node_url\">$analysis->name</a>
  817. </td></tr>
  818. <tr><td>
  819. Program: $analysis->program ($analysis->programversion)
  820. </td></tr>
  821. <tr><td>
  822. Algorithm: $analysis->algorithm
  823. </td></tr>
  824. <tr><td>
  825. Source: $analysis->sourcename $ver
  826. </td></tr>
  827. <tr><td>
  828. Source URI: $analysis->sourceuri
  829. </td></tr>
  830. <tr><td>
  831. Executed Time:$date
  832. </td></tr>
  833. <tr><td>
  834. Description: $analysis->description
  835. </td></tr>
  836. </table>
  837. </span>
  838. </div>
  839. </div>";
  840. }
  841. return $output;
  842. }
  843. /**
  844. * Remove orphaned drupal nodes or chado analysis
  845. *
  846. * @param $dummy
  847. * Not Used -kept for backwards compatibility
  848. * @param $job_id
  849. * The id of the tripal job executing this function
  850. *
  851. * @ingroup tripal_analysis
  852. */
  853. function tripal_analyses_cleanup($dummy = NULL, $job_id = NULL) {
  854. // select each node from node table with chado_analysis as type
  855. // check to make sure it also exists in chado_analysis table, delete if it doesn't
  856. // (this should never, ever happen, but we'll double check anyway)
  857. $sql_drupal_node = "SELECT * FROM {node} WHERE type LIKE 'chado_analysis%' order by nid";
  858. $sql_drupal_ca = "SELECT * from {chado_analysis} WHERE nid = %d";
  859. $results = db_query($sql_drupal_node);
  860. while ($node = db_fetch_object($results)) {
  861. $ca_record = db_fetch_object(db_query($sql_drupal_ca, $node->nid));
  862. if (!$ca_record) {
  863. node_delete($node->nid);
  864. $message = "Missing in chado_analysis table.... DELETING node: $nid->nid\n";
  865. watchdog('tripal_analysis', $message, array(), WATCHDOG_WARNING);
  866. }
  867. }
  868. // get nodes from chado_analysis table and load into array, saving chado analysis_id
  869. // as we iterate through, we'll check that they are actual nodes and
  870. // delete if they aren't
  871. // (this should never, ever happen, but we'll double check anyway)
  872. $sql_drupal_ca2 = "SELECT * FROM {chado_analysis}";
  873. $sql_drupal_node2 = "SELECT * FROM {node} WHERE type LIKE 'chado_analysis%' AND nid = %d";
  874. $results = db_query($sql_drupal_ca2);
  875. $nid2aid = array();
  876. while ($ca_record = db_fetch_object($results)) {
  877. $node = db_fetch_object(db_query($sql_drupal_node2, $ca_record->nid));
  878. if (!$node) {
  879. db_query("DELETE FROM {chado_analysis} WHERE nid = %nid", $ca_record->nid);
  880. $message = "chado_analysis missing node.... DELETING chado_analysis record with nid: $ca_record->nid\n";
  881. watchdog('tripal_analysis', $message, array(), WATCHDOG_WARNING);
  882. }
  883. else{
  884. $nid2aid[$ca_record->nid] = $ca_record->analysis_id;
  885. }
  886. }
  887. // iterate through all of the chado_analysis nodes in drupal
  888. // and delete those that aren't valid in chado
  889. $sql_chado = "SELECT analysis_id from {analysis} WHERE analysis_id = %d";
  890. foreach ($nid2aid as $nid => $aid) {
  891. $previous_db = tripal_db_set_active('chado');
  892. $chado_record = db_fetch_object(db_query($sql_chado, $aid));
  893. tripal_db_set_active($previous_db);
  894. if (!$chado_record) {
  895. node_delete($nid);
  896. $message = "Missing in analysis table in chado.... DELETING node: $nid\n";
  897. watchdog('tripal_analysis', $message, array(), WATCHDOG_WARNING);
  898. }
  899. }
  900. return '';
  901. }
  902. /**
  903. function tripal_analysis_reindex_features ($analysis_id = NULL, $job_id = NULL){
  904. $i = 0;
  905. // if the caller provided a analysis_id then get all of the features
  906. // associated with the analysis. Otherwise get all sequences associated
  907. // with all libraries.
  908. if(!$analysis_id){
  909. $sql = "SELECT Analysis_id, Feature_id ".
  910. "FROM {Analysisfeature} ".
  911. "ORDER BY analysis_id";
  912. $previous_db = tripal_db_set_active('chado'); // use chado database
  913. $results = db_query($sql);
  914. tripal_db_set_active($previous_db); // now use drupal database
  915. } else {
  916. $sql = "SELECT Analysis_id, Feature_id ".
  917. "FROM {Analysisfeature} ".
  918. "WHERE analysis_id = %d";
  919. "ORDER BY analysis_id";
  920. $previous_db = tripal_db_set_active('chado'); // use chado database
  921. $results = db_query($sql,$analysis_id);
  922. tripal_db_set_active($previous_db); // now use drupal database
  923. }
  924. // load into ids array
  925. $count = 0;
  926. $ids = array();
  927. while($id = db_fetch_object($results)){
  928. $ids[$count] = $id->feature_id;
  929. $count++;
  930. }
  931. $interval = intval($count * 0.01);
  932. foreach($ids as $feature_id){
  933. // update the job status every 1% features
  934. if($job_id and $i % interval == 0){
  935. tripal_job_set_progress($job_id,intval(($i/$count)*100));
  936. }
  937. tripal_feature_sync_feature ($feature_id);
  938. $i++;
  939. }
  940. } */
  941. /**
  942. function tripal_analysis_taxonify_features ($analysis_id = NULL, $job_id = NULL){
  943. $i = 0;
  944. // if the caller provided a analysis_id then get all of the features
  945. // associated with the analysis. Otherwise get all sequences assoicated
  946. // with all libraries.
  947. if(!$analysis_id){
  948. $sql = "SELECT Analysis_id, Feature_id ".
  949. "FROM {Analysisfeature} ".
  950. "ORDER BY analysis_id";
  951. $previous_db = tripal_db_set_active('chado'); // use chado database
  952. $results = db_query($sql);
  953. tripal_db_set_active($previous_db); // now use drupal database
  954. } else {
  955. $sql = "SELECT Analysis_id, Feature_id ".
  956. "FROM {Analysisfeature} ".
  957. "WHERE analysis_id = %d";
  958. "ORDER BY analysis_id";
  959. $previous_db = tripal_db_set_active('chado'); // use chado database
  960. $results = db_query($sql,$analysis_id);
  961. tripal_db_set_active($previous_db); // now use drupal database
  962. }
  963. // load into ids array
  964. $count = 0;
  965. $ids = array();
  966. while($id = db_fetch_object($results)){
  967. $ids[$count] = $id->feature_id;
  968. $count++;
  969. }
  970. // make sure our vocabularies are set before proceeding
  971. tripal_feature_set_vocabulary();
  972. // use this SQL for getting the nodes
  973. $nsql = "SELECT * FROM {chado_feature} CF ".
  974. " INNER JOIN {node} N ON N.nid = CF.nid ".
  975. "WHERE feature_id = %d";
  976. // iterate through the features and set the taxonomy
  977. $interval = intval($count * 0.01);
  978. foreach($ids as $feature_id){
  979. // update the job status every 1% features
  980. if($job_id and $i % $interval == 0){
  981. tripal_job_set_progress($job_id,intval(($i/$count)*100));
  982. }
  983. $node = db_fetch_object(db_query($nsql,$feature_id));
  984. tripal_feature_set_taxonomy($node,$feature_id);
  985. $i++;
  986. }
  987. }
  988. */
  989. /**
  990. * Implements hook_views_api()
  991. * Purpose: Essentially this hook tells drupal that there is views support for
  992. * for this module which then includes tripal_analysis.views.inc where all the
  993. * views integration code is
  994. *
  995. * @ingroup tripal_analysis
  996. */
  997. function tripal_analysis_views_api() {
  998. return array(
  999. 'api' => 2.0,
  1000. );
  1001. }