tripal_analysis_blast.module 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901
  1. <?php
  2. require_once "parse_blast_XML.inc";
  3. /*******************************************************************************
  4. * Tripal Blast Result lets users show/hide blast results associated
  5. * with a tripal feature
  6. ******************************************************************************/
  7. function tripal_analysis_blast_init(){
  8. // Add javascript and style sheet
  9. // drupal_add_css(drupal_get_path('theme', 'tripal').'/css/tripal_analysis_blast.css');
  10. // drupal_add_js( drupal_get_path('theme', 'tripal').'/js/tripal_analysis_blast.js');
  11. drupal_add_css(drupal_get_path('module', 'tripal_analysis_blast') .'/theme/css/tripal_analysis_blast.css');
  12. drupal_add_js(drupal_get_path('module', 'tripal_analysis_blast') .'/theme/js/tripal_analysis_blast.js');
  13. dpm('helloinit', 'hello');
  14. }
  15. /*******************************************************************************
  16. * tripal_analysis_blast_menu()
  17. * HOOK: Implementation of hook_menu()
  18. * Entry points and paths of the module
  19. */
  20. function tripal_analysis_blast_menu() {
  21. // Show top 10/25/all blast results for ajax calls
  22. $items['tripal_top_blast'] = array(
  23. 'path' => 'top_blast',
  24. 'title' => t('Blast Hits'),
  25. 'page callback' => 'tripal_get_feature_blast_results_ajax',
  26. 'page arguments' => array(1,2,3),
  27. 'access arguments' => array('access content'),
  28. 'type' => MENU_CALLBACK
  29. );
  30. // Show regular expressions for selected database in Blast admin page
  31. $items['admin/tripal/tripal_analysis/tripal_blast_regex/%'] = array(
  32. 'title' => t('Blast Regex'),
  33. 'page callback' => 'tripal_get_blast_regex',
  34. 'page arguments' => array(4),
  35. 'access arguments' => array('administer site configuration'),
  36. 'type' => MENU_CALLBACK
  37. );
  38. $items['tripal_blast_report'] = array(
  39. 'title' => t('Homology Report'),
  40. 'page callback' => 'tripal_get_blast_report',
  41. 'page arguments' => array(1,2,3,4,5),
  42. 'access arguments' => array('access chado_analysis_blast content'),
  43. 'type' => MENU_CALLBACK,
  44. 'file' => 'tripal_analysis_blast_htmlreport.inc'
  45. );
  46. return $items;
  47. }
  48. /**
  49. *
  50. *
  51. * @ingroup tripal_analysis_blast
  52. */
  53. function tripal_analysis_blast_block($op = 'list', $delta = 0, $edit=array()){
  54. switch($op) {
  55. case 'list':
  56. $blocks['blast_base']['info'] = t('Analysis: Blast Details');
  57. $blocks['blast_base']['cache'] = BLOCK_NO_CACHE;
  58. $blocks['featureblast']['info'] = t('Tripal Feature Blast Results');
  59. $blocks['featureblast']['cache'] = BLOCK_NO_CACHE;
  60. return $blocks;
  61. case 'view':
  62. if(user_access('access chado_analysis_blast content') and arg(0) == 'node' and is_numeric(arg(1))) {
  63. $nid = arg(1);
  64. $node = node_load($nid);
  65. $block = array();
  66. switch($delta){
  67. case 'blast_base':
  68. $block['subject'] = t('Blast Details');
  69. $block['content'] = theme('tripal_analysis_blast_base',$node);
  70. break;
  71. case 'featureblast':
  72. $block['subject'] = t('Homology');
  73. $block['content'] = theme('tripal_feature_blast_results',$node);
  74. break;
  75. default :
  76. }
  77. return $block;
  78. }
  79. }
  80. }
  81. /*******************************************************************************
  82. * tripal_analysis_blast_nodeapi()
  83. * HOOK: Implementation of hook_nodeapi()
  84. * Display blast results for allowed node types
  85. */
  86. function tripal_analysis_blast_nodeapi(&$node, $op, $teaser, $page) {
  87. switch ($op) {
  88. case 'view':
  89. if($teaser){
  90. return '';
  91. }
  92. // Find out which node types for showing the blast
  93. $types_to_show = variable_get('tripal_analysis_blast_setting',
  94. array('chado_feature'));
  95. // Abort if this node is not one of the types we should show.
  96. if (!in_array($node->type, $types_to_show, TRUE)) {
  97. break;
  98. }
  99. if(strcmp($node->type,'chado_feature')==0){
  100. if($node->build_mode == NODE_BUILD_SEARCH_INDEX){
  101. $node->content['tripal_analysis_blast_index_version'] = array(
  102. '#value' => theme('tripal_analysis_blast_results_index_version',$node),
  103. '#weight' => 8,
  104. );
  105. } else {
  106. // Show blast result if not at teaser view
  107. $node->content['tripal_feature_blast_results'] = array(
  108. '#value' => theme('tripal_feature_blast_results', $node),
  109. '#weight' => 8
  110. );
  111. }
  112. }
  113. break;
  114. }
  115. }
  116. /************************************************************************
  117. * We need to let drupal know about our theme functions and their arguments.
  118. * We create theme functions to allow users of the module to customize the
  119. * look and feel of the output generated in this module
  120. */
  121. function tripal_analysis_blast_theme () {
  122. $path = drupal_get_path('module', 'tripal_analysis_blast') . '/theme';
  123. // $path_feature = $path . '/tripal_feature';
  124. // $path_analysis = $path . '/tripal_analysis_blast';
  125. //dpm($path, 'path');
  126. $theme = array(
  127. 'tripal_analysis_blast_results_index_version' => array (
  128. 'arguments' => array('node'),
  129. 'path' => $path,
  130. 'template' => 'node-chado_analysis_blast',
  131. ),
  132. 'tripal_feature_blast_results' => array(
  133. 'arguments' => array('node'=> null),
  134. 'path' => $path,
  135. 'template' => 'tripal_analysis_blast/tripal_feature_blast_results',
  136. ),
  137. 'tripal_analysis_blast_report' => array(
  138. 'arguments' => array('report_object'=> null),
  139. 'path' => $path,
  140. 'template' => 'tripal_analysis_blast/tripal_analysis_blast_report',
  141. ),
  142. 'tripal_analysis_blast_base' => array(
  143. 'arguments' => array('report_object'=> null),
  144. 'path' => $path,
  145. 'template' => 'tripal_analysis_blast/tripal_analysis_blast_base',
  146. )
  147. );
  148. dpm($theme, 'blast theme');
  149. return $theme;
  150. }
  151. /*******************************************************************************
  152. *
  153. */
  154. function tripal_get_feature_blast_results_ajax($feature_id, $db_id, $max){
  155. $sql = "SELECT nid FROM {chado_feature} WHERE feature_id = %d";
  156. $nid = db_fetch_object(db_query($sql,$feature_id));
  157. $node = node_load($nid->nid);
  158. // add the additional variables that the theme needs to generate the output
  159. $node->db_id = $db_id;
  160. $node->max = $max;
  161. // call the theme to rebuild the blast results
  162. drupal_json(array('update' => theme('tripal_feature_blast_results',$node)));
  163. }
  164. /*******************************************************************************
  165. *
  166. */
  167. function tripal_analysis_blast_preprocess_tripal_feature_blast_results(&$variables){
  168. $feature = $variables['node']->feature;
  169. $db_id = $variables['node']->db_id; // this value only gets set on an ajax call
  170. $max = 10;
  171. if(isset($variables['node']->max)){
  172. $max = $variables['node']->max;
  173. }
  174. $blast_results = tripal_get_feature_blast_results($feature->feature_id, $db_id, $max);
  175. $feature->tripal_analysis_blast->blast_results_list = $blast_results;
  176. }
  177. /*******************************************************************************
  178. * Prepare blast result for the feature shown on the page
  179. */
  180. function theme_tripal_analysis_blast_results_index_version ($node) {
  181. $feature = $node->feature;
  182. $content = tripal_get_blast_results_index_version($feature->feature_id);
  183. return $content;
  184. }
  185. /*******************************************************************************
  186. * tripal_get_feature_blast_results()
  187. * Get blast result from featureprop table for the feature
  188. */
  189. function tripal_get_feature_blast_results($feature_id, $db_id, $max){
  190. // Get the blast results stored as XML from the analysisfeatureprop table
  191. // the type for the property is named 'analysis_blast_output_iteration_hits'
  192. // and is found in the 'tripal' controlled vocabulary. This CV term was
  193. // added by this module.
  194. $select = array(
  195. 'analysisfeature_id' => array(
  196. 'feature_id' => $feature_id,
  197. ),
  198. 'type_id' => array(
  199. 'name' => 'analysis_blast_output_iteration_hits',
  200. 'cv_id' => array(
  201. 'name' => 'tripal'
  202. ),
  203. ),
  204. );
  205. $blast_results = tripal_core_chado_select('analysisfeatureprop',array('*'),$select);
  206. if (!$blast_results){
  207. return;
  208. }
  209. // get the HTML content for viewing each of the XML file
  210. $blast_obj_array = array ();
  211. $blast_obj_counter = 0;
  212. foreach ($blast_results as $index => $analysisfeatureprop) {
  213. // get the blast XML for this feature
  214. $blast_xml = $analysisfeatureprop->value;
  215. // get the analysis record
  216. $analysisfeature_arr = tripal_core_chado_select('analysisfeature',array('analysis_id'),
  217. array('analysisfeature_id' => $analysisfeatureprop->analysisfeature_id));
  218. $analysis_arr = tripal_core_chado_select('analysis',array('*'),
  219. array('analysis_id' => $analysisfeature_arr[0]->analysis_id));
  220. $analysis = $analysis_arr[0];
  221. $analysis_id = $analysis->analysis_id;
  222. // the old style was to store all parameters in a single CV term in the analysisprop
  223. // table. However now each property has it's own CV term in that table. But,
  224. // we still need to support the old method for backwards compatibility.
  225. // so, first get the old style variable and see if it has values. In
  226. // particular we need the database setting
  227. $blast_settings = tripal_analysis_get_property($analysis_id,'analysis_blast_settings');
  228. if($blast_settings){
  229. $blastsettings = explode("|", $blast_settings->value);
  230. // if we don't have the proper number of fields in the value column then
  231. // skip this entry
  232. if(count($blastsettings) != 3){
  233. continue;
  234. }
  235. $adb_id = $blastsettings[0];
  236. }
  237. // if we're not using the old style then try the new method to get the
  238. // database id
  239. else {
  240. $blastdb = tripal_analysis_get_property($analysis_id,'analysis_blast_blastdb');
  241. $adb_id = $blastdb->value;
  242. }
  243. // if the callee specified a database to show then we want to check that
  244. // with the database id of the analysis we're looking at. If they
  245. // don't match then skip this blast. If a database id was not specified
  246. // then continue
  247. if($db_id and $adb_id != $db_id){
  248. continue;
  249. }
  250. // get the database
  251. if($adb_id){
  252. $db_arr = tripal_core_chado_select('db',array('*'),array('db_id' => $adb_id));
  253. $db = $db_arr[0];
  254. }
  255. // parse the XML and add it to the array of blast results to be returned
  256. $blast_obj = tripal_analysis_blast_get_result_object($blast_xml,$db,$max,$feature_id, $analysis);
  257. $blast_obj->analysis = $analysis;
  258. $blast_obj_array [$blast_obj_counter] = $blast_obj;
  259. $blast_obj_counter ++;
  260. }
  261. return $blast_obj_array;
  262. }
  263. /*******************************************************************************
  264. * Scanning the file folder for blast results and prepare content for indexing
  265. */
  266. function tripal_get_blast_results_index_version ($feature_id){
  267. // Get cvterm_id for 'analysis_blast_output_iteration_hits' which is required
  268. // for inserting into the analysisfeatureprop table
  269. $previous_db = tripal_db_set_active('chado');
  270. $sql = "SELECT CVT.cvterm_id FROM {cvterm} CVT ".
  271. "INNER JOIN cv ON cv.cv_id = CVT.cv_id ".
  272. "WHERE CVT.name = 'analysis_blast_output_iteration_hits' ".
  273. "AND CV.name = 'tripal'";
  274. $type_id = db_result(db_query($sql));
  275. // Get xml string from analysisfeatureprop value column, get db_id from analysisprop value column
  276. // , and get analysis_id from analysisfeature table
  277. $sql = "SELECT AP.value AS apvalue, AFP.value AS afpvalue, AF.analysis_id AS aid
  278. FROM {analysisfeatureprop} AFP
  279. INNER JOIN analysisfeature AF ON AF.analysisfeature_id = AFP.analysisfeature_id
  280. INNER JOIN analysisprop AP ON AP.analysis_id = AF.analysis_id
  281. WHERE feature_id = %d
  282. AND AFP.type_id = %d ";
  283. $result = db_query($sql, $feature_id, $type_id);
  284. tripal_db_set_active($previous_db);
  285. // get the HTML content for viewing each of the XML file
  286. while ($analysisfeatureprop = db_fetch_object($result)) {
  287. // get analysis name and date
  288. $previous_db = tripal_db_set_active('chado');
  289. $sql = "SELECT analysis_id AS aid, name, to_char(timeexecuted, 'MM-DD-YYYY') AS time
  290. FROM {analysis} WHERE analysis_id = %d";
  291. $analysis = db_fetch_object(db_query($sql, $analysisfeatureprop->aid));
  292. tripal_db_set_active($previous_db);
  293. $blastsettings = explode("|", $analysisfeatureprop->apvalue);
  294. $att_db_id = $blastsettings [0];
  295. // Get db object using the db_id
  296. $previous_db = tripal_db_set_active('chado');
  297. $sql = "SELECT * FROM {db} WHERE db_id=%d";
  298. $db = db_fetch_object(db_query($sql, $att_db_id));
  299. tripal_db_set_active($previous_db);
  300. // Only index best 10 hits because the default page only shows 10 blast results
  301. $max = 10;
  302. $content .= parse_NCBI_Blast_XML_index_version($analysisfeatureprop->afpvalue,$db,$max,$feature_id,$ajax, $analysis);
  303. }
  304. return $content;
  305. }
  306. /*******************************************************************************
  307. * Tripal Blast administrative setting form. This function is called by
  308. * tripal_analysis module which asks for an admin form to show on the page
  309. */
  310. function tripal_analysis_blast_get_settings() {
  311. // Get an array of node types with internal names as keys
  312. $options = node_get_types('names');
  313. // Add 'chado_feature' to allowed content types for showing blast results
  314. $allowedoptions ['chado_feature'] = "Show blast results on feature pages";
  315. $form['description'] = array(
  316. '#type' => 'item',
  317. '#value' => t("Most chado features were analyzed by blast against major sequence databases. This option allows user to display the blast analysis results. Please read user manual for storage and display of blast files. Check the box to enable the analysis results. Uncheck to disable it."),
  318. '#weight' => 0,
  319. );
  320. $form['tripal_analysis_blast_setting'] = array(
  321. '#type' => 'checkboxes',
  322. '#options' => $allowedoptions,
  323. '#default_value' => variable_get('tripal_analysis_blast_setting',
  324. array('chado_feature')),
  325. );
  326. $form['blast_parser'] = array(
  327. '#title' => t('Blast Parser Settings'),
  328. '#type' => 'fieldset',
  329. '#description' => t('Configure parsers for showing blast results. Each database is '.
  330. 'allowed to have one xml parser.'),
  331. '#weight' => 10
  332. );
  333. $previous_db = tripal_db_set_active('chado'); // use chado database
  334. // get a list of db from chado for user to choose
  335. $sql = 'SELECT db_id, name FROM {db} ORDER BY lower(name)';
  336. $results = db_query ($sql);
  337. $blastdbs = array();
  338. while ($db = db_fetch_object($results)){
  339. $blastdbs[$db->db_id] = $db->name;
  340. }
  341. $form['db_options'] = array(
  342. '#type' => 'value',
  343. '#value' => $blastdbs
  344. );
  345. $form['blast_parser']['blastdb'] = array(
  346. '#title' => t('Database'),
  347. '#type' => 'select',
  348. '#description' => t('The database used for the blast analysis.'),
  349. '#options' => $form['db_options']['#value'],
  350. '#attributes' => array(
  351. 'onChange' => "return tripal_update_regex(this)",
  352. )
  353. );
  354. $form['blast_parser']['displayname'] = array(
  355. '#title' => t('Title for the blast analysis'),
  356. '#type' => 'textfield',
  357. );
  358. $form['blast_parser']['gb_style_parser'] = array(
  359. '#title' => t('Use Genebank style parser. This will clear all regular expression settings for the selected database.'),
  360. '#type' => 'checkbox',
  361. '#attributes' => array(
  362. 'onClick' => "return tripal_set_genbank_style(this)",
  363. )
  364. );
  365. $form['blast_parser']['hit_id'] = array(
  366. '#title' => t('Regular expression for Hit Name'),
  367. '#type' => 'textfield',
  368. );
  369. $form['blast_parser']['hit_def'] = array(
  370. '#title' => t('Regular expression for Hit Description'),
  371. '#type' => 'textfield',
  372. );
  373. $form['blast_parser']['hit_accession'] = array(
  374. '#title' => t('Regular expression for Hit Accession'),
  375. '#type' => 'textfield',
  376. );
  377. $form['blast_parser']['button'] = array(
  378. '#type' => 'submit',
  379. '#value' => t('Save settings')
  380. );
  381. tripal_db_set_active($previous_db); // use drupal database
  382. $settings->form = $form;
  383. $settings->title = "Tripal Blast";
  384. return $settings;
  385. }
  386. /*******************************************************************************
  387. * This function is only called by ajax to get regular expressions for blast
  388. * admin page
  389. */
  390. function tripal_get_blast_regex ($db_id) {
  391. $sql = "SELECT * FROM {tripal_analysis_blast} WHERE db_id = %d";
  392. $blast_regexs = db_fetch_object(db_query($sql, $db_id));
  393. drupal_json(array(
  394. 'name' => $blast_regexs->displayname,
  395. 'genbank_style' => $blast_regexs->genbank_style,
  396. 'reg1' => $blast_regexs->regex_hit_id,
  397. 'reg2' => $blast_regexs->regex_hit_def,
  398. 'reg3' => $blast_regexs->regex_hit_accession)
  399. );
  400. }
  401. /*******************************************************************************
  402. * Provide information to drupal about the node types that we're creating
  403. * in this module
  404. */
  405. function tripal_analysis_blast_node_info() {
  406. $nodes = array();
  407. $nodes['chado_analysis_blast'] = array(
  408. 'name' => t('Analysis: Blast'),
  409. 'module' => 'chado_analysis_blast',
  410. 'description' => t('A blast analysis from the chado database'),
  411. 'has_title' => FALSE,
  412. 'title_label' => t('Analysis: Blast'),
  413. 'has_body' => FALSE,
  414. 'body_label' => t('Blast Analysis Description'),
  415. 'locked' => TRUE
  416. );
  417. return $nodes;
  418. }
  419. /*******************************************************************************
  420. * Provide a Blast Analysis form
  421. */
  422. function chado_analysis_blast_form ($node){
  423. // add in the default fields
  424. $form = chado_analysis_form($node);
  425. // set the default values
  426. $blast = $node->analysis->tripal_analysis_blast;
  427. $blastdb = $blast->blastdb;
  428. $blastfile = $blast->blastfile;
  429. $blastfile_ext = $blast->blastfile_ext;
  430. $blastparameters = $blast->blastparameters;
  431. $query_re = $blast->query_re;
  432. $query_type = $blast->query_type;
  433. $query_uniquename = $blast->query_uniquename;
  434. $is_concat = $blast->is_concat;
  435. $form['blast'] = array(
  436. '#title' => t('Blast Settings'),
  437. '#type' => 'fieldset',
  438. '#description' => t('Specific Settings for Blast Analysis.'),
  439. '#collapsible' => TRUE,
  440. '#attributes' => array('id' => 'blast-extra-settings'),
  441. '#weight' => 11
  442. );
  443. $previous_db = tripal_db_set_active('chado'); // use chado database
  444. // get a list of db from chado for user to choose
  445. $sql = 'SELECT db_id, name FROM {db} ORDER BY lower(name)';
  446. $results = db_query ($sql);
  447. tripal_db_set_active($previous_db);
  448. $blastdbs = array();
  449. while ($db = db_fetch_object($results)){
  450. $blastdbs[$db->db_id] = $db->name;
  451. }
  452. $form['db_options'] = array(
  453. '#type' => 'value',
  454. '#value' => $blastdbs
  455. );
  456. $form['blast']['blastdb'] = array(
  457. '#title' => t('Database'),
  458. '#type' => 'select',
  459. '#description' => t('The database used for the blast analysis. If the database does not appear in this list, please add it.'),
  460. '#options' => $form['db_options']['#value'],
  461. '#default_value' => $blastdb,
  462. );
  463. $form['blast']['blastfile'] = array(
  464. '#title' => t('Blast XML File/Directory: (if you input a directory without the tailing slash, all xml files in the directory will be loaded)'),
  465. '#type' => 'textfield',
  466. '#description' => t('The xml output file generated by blast in full path.'),
  467. '#default_value' => $blastfile,
  468. );
  469. $form['blast']['blastfile_ext'] = array(
  470. '#title' => t('Blast XML file extension'),
  471. '#type' => 'textfield',
  472. '#description' => t('If a directory is provide for the blast file setting above, then a file extension can be provided here. Files with this extension in the directory will be parsed. If no extension is provided then files with a .xml extension will be parsed within the directory. Please provide the extension without the preceeding period (e.g. "out" rather than ".out"'),
  473. '#default_value' => $blastfile_ext,
  474. );
  475. $form['blast']['is_concat'] = array(
  476. '#title' => t('Is the XML file concatenated?'),
  477. '#type' => 'checkbox',
  478. '#description' => t('Is the XML file a set of concatenated XML results? Such is the case, for instance, if
  479. <a href="http://www.blast2go.org/">Blast2GO</a> was used to generate the blast results.'),
  480. '#default_value' => $is_concat,
  481. );
  482. $form['blast']['no_parsed'] = array(
  483. '#title' => t('Number of hits to be parsed'),
  484. '#type' => 'textfield',
  485. '#description' => t("The number of hits to be parsed. Tripal will parse only top 10 hits if you input '10'' in this field."),
  486. '#default_value' => 'all',
  487. );
  488. $form['blast']['query_re'] = array(
  489. '#title' => t('Query Name RE'),
  490. '#type' => 'textfield',
  491. '#description' => t('Enter the regular expression that will extract the '.
  492. 'feature name from the query line in the blast results. This should be '.
  493. 'the same as the definition line in the query FASTA file. This option is '.
  494. 'is only required when the query does not identically match a feature '.
  495. 'in the database.'),
  496. '#default_value' => $query_re,
  497. );
  498. $form['blast']['query_type'] = array(
  499. '#title' => t('Query Type'),
  500. '#type' => 'textfield',
  501. '#description' => t('Please enter the Sequence Ontology term that describes '.
  502. 'the query sequences used for blasting. This is only necessary if two '.
  503. 'or more sequences have the same name.'),
  504. '#default_value' => $query_type,
  505. );
  506. $form['blast']['query_uniquename'] = array(
  507. '#title' => t('Use Unique Name'),
  508. '#type' => 'checkbox',
  509. '#description' => t('Select this checboxk if the query name in the blast file '.
  510. 'matches the uniquename of the feature. By default, the blast results will '.
  511. 'mapped to the "name" of the feature.'),
  512. '#default_value' => $query_uniquename,
  513. );
  514. $form['blast']['blastparameters'] = array(
  515. '#title' => t('Parameters'),
  516. '#type' => 'textfield',
  517. '#description' => t('The parameters for running the blast analysis.'),
  518. '#default_value' => $blastparameters,
  519. );
  520. $form['blast']['blastjob'] = array(
  521. '#type' => 'checkbox',
  522. '#title' => t('Submit a job to parse the xml output into Chado'),
  523. '#description' => t('Note: features associated with the blast results must '.
  524. 'exist in chado before parsing the file. Otherwise, blast '.
  525. 'results that cannot be linked to a feature will be '.
  526. 'discarded. '),
  527. '#default_value' => $blastjob
  528. );
  529. /* $form['blast']['blastbesthit'] = array(
  530. '#type' => 'checkbox',
  531. '#title' => t('Submit a job to generate a "best hits" report.'),
  532. '#description' => t('Note: the checkbox above must also be selected.'),
  533. '#default_value' => $blastbesthit
  534. );
  535. */
  536. return $form;
  537. }
  538. /**
  539. *
  540. */
  541. function chado_analysis_blast_validate($node, &$form){
  542. // use the analysis parent to validate the node
  543. tripal_analysis_validate($node, $form);
  544. }
  545. /*******************************************************************************
  546. * When a node is requested by the user this function is called to allow us
  547. * to add auxiliary data to the node object.
  548. */
  549. function chado_analysis_blast_load($node){
  550. // load the default set of analysis fields
  551. $additions = chado_analysis_load($node);
  552. // create some variables for easier lookup
  553. $analysis = $additions->analysis;
  554. $analysis_id = $analysis->analysis_id;
  555. $blast_settings = tripal_analysis_get_property($analysis->analysis_id,'analysis_blast_settings');
  556. $blastdb = tripal_analysis_get_property($analysis->analysis_id,'analysis_blast_blastdb');
  557. $blastfile = tripal_analysis_get_property($analysis->analysis_id,'analysis_blast_blastfile');
  558. $blastparameters = tripal_analysis_get_property($analysis->analysis_id,'analysis_blast_blastparameters');
  559. $no_parsed = tripal_analysis_get_property($analysis->analysis_id,'analysis_blast_no_parsed');
  560. $query_re = tripal_analysis_get_property($analysis->analysis_id,'analysis_blast_query_re');
  561. $query_type = tripal_analysis_get_property($analysis->analysis_id,'analysis_blast_query_type');
  562. $query_uniquename= tripal_analysis_get_property($analysis->analysis_id,'analysis_blast_query_uniquename');
  563. $blastfile_ext = tripal_analysis_get_property($analysis->analysis_id,'analysis_blast_blastfile_ext');
  564. $is_concat = tripal_analysis_get_property($analysis->analysis_id,'analysis_blast_is_concat');
  565. $analysis->tripal_analysis_blast->blastdb = $blastdb->value;
  566. $analysis->tripal_analysis_blast->blastfile = $blastfile->value;
  567. $analysis->tripal_analysis_blast->blastparameters = $blastparameters->value;
  568. $analysis->tripal_analysis_blast->no_parsed = $no_parsed->value;
  569. $analysis->tripal_analysis_blast->query_re = $query_re->value;
  570. $analysis->tripal_analysis_blast->query_type = $query_type->value;
  571. $analysis->tripal_analysis_blast->query_uniquename= $query_uniquename->value;
  572. $analysis->tripal_analysis_blast->blastfile_ext = $blastfile_ext->value;
  573. $analysis->tripal_analysis_blast->is_concat = $is_concat->value;
  574. // get the database information so that we don't have to require callers
  575. // to do the lookup
  576. $select = array('db_id' => $blastdb->value);
  577. $analysis->tripal_analysis_blast->db = tripal_core_generate_chado_var('db',$select);
  578. // if there is an old style 'blast_settings' array, then break these out for
  579. // use in the new format
  580. if(count($blast_settings)>0){
  581. $prop_values = explode ("|", $blast_settings->value);
  582. $analysis->tripal_analysis_blast->blastdb = $prop_values[0];
  583. $analysis->tripal_analysis_blast->blastfile = $prop_values[1];
  584. $analysis->tripal_analysis_blast->blastparameters = $prop_values[2];
  585. }
  586. /* check if there exists a best hit report. if yes, reuturn the report url
  587. $select = array(
  588. 'analysisfeature_id' => array(
  589. 'analysis_id' => $analysis_id,
  590. ),
  591. 'type_id' => array(
  592. 'name' => 'analysis_blast_besthit_query',
  593. 'cv_id' => array(
  594. 'name' => 'tripal'
  595. ),
  596. ),
  597. );
  598. $blast_report = tripal_core_chado_select('analysisfeatureprop',array('analysisfeatureprop_id'),$select);
  599. */
  600. $sql = "SELECT AFP.analysisfeature_id
  601. FROM {analysisfeature} AF
  602. INNER JOIN {analysisfeatureprop} AFP ON AF.analysisfeature_id = AFP.analysisfeature_id
  603. WHERE analysis_id = %d
  604. AND AFP.type_id = (
  605. SELECT cvterm_id
  606. FROM {cvterm}
  607. WHERE name = '%s'
  608. AND cv_id = (
  609. SELECT cv_id
  610. FROM {cv}
  611. WHERE name = 'tripal'
  612. )
  613. ) LIMIT 1 OFFSET 0";
  614. $blast_report = db_result(chado_query($sql, $analysis_id, 'analysis_blast_besthit_query'));
  615. if ($blast_report) {
  616. $report_url = url("tripal_blast_report/".$analysis->analysis_id."/1/0/0/20");
  617. $analysis->blast_report = $report_url;
  618. }
  619. return $additions;
  620. }
  621. /**
  622. *
  623. */
  624. function chado_analysis_blast_insert($node){
  625. // insert the analysistripal_core_generate_chado_var
  626. chado_analysis_insert($node);
  627. // set the type for this analysis
  628. tripal_analysis_insert_property($node->analysis_id,'analysis_type','tripal_analysis_blast');
  629. // now add in the remaining settings as a single property but separated by bars
  630. tripal_analysis_insert_property($node->analysis_id,'analysis_blast_blastdb',$node->blastdb);
  631. tripal_analysis_insert_property($node->analysis_id,'analysis_blast_blastfile',$node->blastfile);
  632. tripal_analysis_insert_property($node->analysis_id,'analysis_blast_blastparameters',$node->blastparameters);
  633. tripal_analysis_insert_property($node->analysis_id,'analysis_blast_no_parsed',$node->no_parsed);
  634. tripal_analysis_insert_property($node->analysis_id,'analysis_blast_query_re',$node->query_re);
  635. tripal_analysis_insert_property($node->analysis_id,'analysis_blast_query_type',$node->query_type);
  636. tripal_analysis_insert_property($node->analysis_id,'analysis_blast_query_uniquename',$node->query_uniquename);
  637. tripal_analysis_insert_property($node->analysis_id,'analysis_blast_blastfile_ext',$node->blastfile_ext);
  638. tripal_analysis_insert_property($node->analysis_id,'analysis_blast_is_concat',$node->is_concat);
  639. // submit the parsing jobs
  640. chado_analysis_blast_submit_jobs($node);
  641. }
  642. /**
  643. *
  644. */
  645. function chado_analysis_blast_update($node){
  646. // update the anlaysis
  647. chado_analysis_update($node);
  648. // add the blast settings
  649. tripal_analysis_update_property($node->analysis_id,'analysis_type','tripal_analysis_blast',1);
  650. tripal_analysis_update_property($node->analysis_id,'analysis_blast_blastdb',$node->blastdb,1);
  651. tripal_analysis_update_property($node->analysis_id,'analysis_blast_blastfile',$node->blastfile,1);
  652. tripal_analysis_update_property($node->analysis_id,'analysis_blast_blastparameters',$node->blastparameters,1);
  653. tripal_analysis_update_property($node->analysis_id,'analysis_blast_no_parsed',$node->no_parsed,1);
  654. tripal_analysis_update_property($node->analysis_id,'analysis_blast_query_re',$node->query_re,1);
  655. tripal_analysis_update_property($node->analysis_id,'analysis_blast_query_type',$node->query_type,1);
  656. tripal_analysis_update_property($node->analysis_id,'analysis_blast_query_uniquename',$node->query_uniquename,1);
  657. tripal_analysis_update_property($node->analysis_id,'analysis_blast_blastfile_ext',$node->blastfile_ext,1);
  658. tripal_analysis_update_property($node->analysis_id,'analysis_blast_is_concat',$node->is_concat,1);
  659. // if this analysis uses the old style blast settings cvterm then remove that term
  660. $old = tripal_analysis_get_property($node->analysis_id,'analysis_blast_settings');
  661. if(count($old) > 0){
  662. tripal_analysis_delete_property($node->analysis_id,'analysis_blast_settings');
  663. }
  664. // submit the parsing jobs
  665. chado_analysis_blast_submit_jobs($node);
  666. }
  667. /**
  668. *
  669. */
  670. function chado_analysis_blast_submit_jobs($node){
  671. global $user;
  672. // add a job if the user wants to parse the XML
  673. if($node->blastjob) {
  674. $job_args = array(
  675. $node->analysis_id,
  676. $node->blastdb,
  677. $node->blastfile,
  678. $node->no_parsed,
  679. $node->blastfile_ext,
  680. $node->query_re,
  681. $node->query_type,
  682. $node->query_uniquename,
  683. $node->is_concat
  684. );
  685. if (is_readable($node->blastfile)) {
  686. tripal_add_job("Parse blast: $node->blastfile",'tripal_analysis_blast',
  687. 'tripal_analysis_blast_parseXMLFile', $job_args, $user->uid);
  688. } else {
  689. drupal_set_message("Blast output file, $node->blastfile, is not readable
  690. by the server. Check existence of file and file permissions.
  691. Job not scheduled.");
  692. }
  693. }
  694. // add a job if the user wants to create a best hits report.
  695. if($node->blastbesthit) {
  696. $j_args[0] = $node->analysis_id;
  697. tripal_add_job("Parse best hit: $node->blastfile",'tripal_analysis_blast',
  698. 'tripal_analysis_blast_parse_best_hit', $j_args, $user->uid);
  699. }
  700. }
  701. /*******************************************************************************
  702. * Delete blast anlysis
  703. */
  704. function chado_analysis_blast_delete($node){
  705. chado_analysis_delete($node);
  706. }
  707. /*******************************************************************************
  708. * This function customizes the view of the chado_analysis node. It allows
  709. * us to generate the markup.
  710. */
  711. function chado_analysis_blast_view ($node, $teaser = FALSE, $page = FALSE) {
  712. // use drupal's default node view:
  713. //dprint_r($node);
  714. if (!$teaser) {
  715. $node = node_prepare($node, $teaser);
  716. // When previewing a node submitting form, it shows 'Array' instead of
  717. // correct date format. We need to format the date here
  718. $time = $node->timeexecuted;
  719. if(is_array($time)){
  720. $month = $time['month'];
  721. $day = $time['day'];
  722. $year = $time['year'];
  723. $timestamp = $year.'-'.$month.'-'.$day;
  724. $node->timeexecuted = $timestamp;
  725. }
  726. // When viewing a node, we need to reformat the analysisprop since we
  727. // separate each value with a bar |
  728. if (preg_match("/.*\|.*\|.*/",$node->blastdb)) {
  729. $prop_values = explode("|", $node->blastdb);
  730. $node->blastdb = $prop_values[0];
  731. $node->blastfile = $prop_values[1];
  732. $node->blastparameters = $prop_values[2];
  733. }
  734. }
  735. return $node;
  736. }
  737. /*******************************************************************************
  738. * Set the permission types that the chado module uses. Essentially we
  739. * want permissionis that protect creation, editing and deleting of chado
  740. * data objects
  741. */
  742. function tripal_analysis_blast_perm(){
  743. return array(
  744. 'access chado_analysis_blast content',
  745. 'create chado_analysis_blast content',
  746. 'delete chado_analysis_blast content',
  747. 'edit chado_analysis_blast content',
  748. );
  749. }
  750. /*******************************************************************************
  751. * The following function proves access control for users trying to
  752. * perform actions on data managed by this module
  753. */
  754. function chado_analysis_blast_access($op, $node, $account){
  755. if ($op == 'create') {
  756. if(!user_access('create chado_analysis_blast content', $account)){
  757. return FALSE;
  758. }
  759. }
  760. if ($op == 'update') {
  761. if (!user_access('edit chado_analysis_blast content', $account)) {
  762. return FALSE;
  763. }
  764. }
  765. if ($op == 'delete') {
  766. if (!user_access('delete chado_analysis_blast content', $account)) {
  767. return FALSE;
  768. }
  769. }
  770. if ($op == 'view') {
  771. if(!user_access('access chado_analysis_blast content', $account)){
  772. return FALSE;
  773. }
  774. }
  775. return NULL;
  776. }
  777. /**
  778. *
  779. *
  780. * @ingroup tripal_feature
  781. */
  782. function tripal_analysis_blast_job_describe_args($callback,$args){
  783. $new_args = array();
  784. if($callback == 'tripal_analysis_blast_parseXMLFile'){
  785. // add in the analysis
  786. if($args[0]){
  787. $analysis = tripal_core_chado_select('analysis',array('name'),array('analysis_id' => $args[0]));
  788. }
  789. $new_args['Analysis'] = $analysis[0]->name;
  790. // add in the database
  791. if($args[1]){
  792. $db = tripal_core_chado_select('db',array('name'),array('db_id' => $args[1]));
  793. }
  794. $new_args['Database'] = $db[0]->name;
  795. $new_args['File or Directory Name'] = $args[2];
  796. if($args[7] == 1){
  797. $new_args['Is XML file concatenated'] = 'Yes';
  798. } else {
  799. $new_args['Is XML file concatenated'] = 'No';
  800. }
  801. $new_args['File Extension (if directory)'] = $args[4];
  802. $new_args['Number matches parsed per query'] = $args[3];
  803. $new_args['Query name regular expression'] = $args[5];
  804. $new_args['Query type'] = $args[6];
  805. if($args[7] == 1){
  806. $new_args['Feature identifier'] = 'feature unique name';
  807. } else {
  808. $new_args['Feature identifier'] = 'feature name';
  809. }
  810. }
  811. return $new_args;
  812. }