tripal_analysis_blast.module 34 KB

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