tripal_analysis_blast.module 63 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643
  1. <?php
  2. // $Id:
  3. // Copyright 2009 Clemson University
  4. /*******************************************************************************
  5. * Tripal Blast Result lets users show/hide blast results associated
  6. * with a tripal feature
  7. ******************************************************************************/
  8. function tripal_analysis_blast_init(){
  9. // Add javascript and style sheet
  10. drupal_add_css(drupal_get_path('theme', 'tripal').
  11. '/css/tripal_analysis_blast.css');
  12. drupal_add_js(drupal_get_path('theme', 'tripal').
  13. '/js/tripal_analysis_blast.js');
  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_blast_results',
  26. 'page arguments' => array(1,2,3,'1'),
  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_blast_regex'] = array(
  32. 'title' => t('Blast Regex'),
  33. 'page callback' => 'tripal_get_blast_regex',
  34. 'page arguments' => array(3),
  35. 'access arguments' => array('administer site configuration'),
  36. 'type' => MENU_CALLBACK
  37. );
  38. return $items;
  39. }
  40. /*******************************************************************************
  41. * tripal_analysis_blast_nodeapi()
  42. * HOOK: Implementation of hook_nodeapi()
  43. * Display blast results for allowed node types
  44. */
  45. function tripal_analysis_blast_nodeapi(&$node, $op, $teaser, $page) {
  46. switch ($op) {
  47. case 'view':
  48. // Find out which node types for showing the blast
  49. $types_to_show = variable_get('tripal_analysis_blast_setting',
  50. array('chado_feature'));
  51. // Abort if this node is not one of the types we should show.
  52. if (!in_array($node->type, $types_to_show, TRUE)) {
  53. break;
  54. }
  55. // Add blast to the content item if it's not a teaser
  56. if (!$teaser && $node->feature->feature_id) {
  57. if($node->build_mode == NODE_BUILD_SEARCH_INDEX){
  58. $node->content['tripal_analysis_blast_index_version'] = array(
  59. '#value' => theme('tripal_analysis_blast_results_index_version',$node),
  60. '#weight' => 8,
  61. );
  62. } else {
  63. // Show blast result if not at teaser view
  64. $node->content['tripal_analysis_blast_form'] = array(
  65. '#value' => theme('tripal_analysis_blast_results', $node),
  66. '#weight' => 8
  67. );
  68. }
  69. }
  70. }
  71. }
  72. /************************************************************************
  73. * We need to let drupal know about our theme functions and their arguments.
  74. * We create theme functions to allow users of the module to customize the
  75. * look and feel of the output generated in this module
  76. */
  77. function tripal_analysis_blast_theme () {
  78. return array(
  79. 'tripal_analysis_blast_results_index_version' => array (
  80. 'arguments' => array('node'),
  81. ),
  82. 'tripal_analysis_blast_results' => array (
  83. 'arguments' => array('node'),
  84. )
  85. );
  86. }
  87. /*******************************************************************************
  88. * Prepare blast result for the feature shown on the page
  89. */
  90. function theme_tripal_analysis_blast_results ($node) {
  91. $feature = $node->feature;
  92. $content = tripal_get_blast_results($feature->feature_id, 0, 10, 0);
  93. return $content;
  94. }
  95. /*******************************************************************************
  96. * Prepare blast result for the feature shown on the page
  97. */
  98. function theme_tripal_analysis_blast_results_index_version ($node) {
  99. $feature = $node->feature;
  100. $content = tripal_get_blast_results_index_version($feature->feature_id);
  101. return $content;
  102. }
  103. /*******************************************************************************
  104. * tripal_get_blast_results()
  105. * Get blast result from featureprop table for the feature
  106. */
  107. function tripal_get_blast_results($feature_id, $db_id, $max,$ajax){
  108. // Get cvterm_id for 'analysis_blast_output_iteration_hits' which is required
  109. // for inserting into the analysisfeatureprop table
  110. $previous_db = tripal_db_set_active('chado');
  111. $sql = "SELECT CVT.cvterm_id FROM {cvterm} CVT ".
  112. "INNER JOIN cv ON cv.cv_id = CVT.cv_id ".
  113. "WHERE CVT.name = 'analysis_blast_output_iteration_hits' ".
  114. "AND CV.name = 'tripal'";
  115. $type_id = db_result(db_query($sql));
  116. // Get xml string from analysisfeatureprop value column, get db_id from analysisprop value column
  117. // , and get analysis_id from analysisfeature table
  118. $sql = "SELECT AP.value AS apvalue, AFP.value AS afpvalue, AF.analysis_id AS aid
  119. FROM {analysisfeatureprop} AFP
  120. INNER JOIN analysisfeature AF ON AF.analysisfeature_id = AFP.analysisfeature_id
  121. INNER JOIN analysisprop AP ON AP.analysis_id = AF.analysis_id
  122. WHERE feature_id = %d
  123. AND AFP.type_id = %d ";
  124. $result = db_query($sql, $feature_id, $type_id);
  125. tripal_db_set_active($previous_db);
  126. // get the HTML content for viewing each of the XML file
  127. while ($analysisfeatureprop = db_fetch_object($result)) {
  128. // get db_id
  129. $blastsettings = explode("|", $analysisfeatureprop->apvalue);
  130. $att_db_id = $blastsettings [0];
  131. // get analysis name and date
  132. $previous_db = tripal_db_set_active('chado');
  133. $sql = "SELECT analysis_id AS aid, name, to_char(timeexecuted, 'MM-DD-YYYY') AS time
  134. FROM {analysis} WHERE analysis_id = %d";
  135. $analysis = db_fetch_object(db_query($sql, $analysisfeatureprop->aid));
  136. tripal_db_set_active($previous_db);
  137. // If not called by ajax, go through all blast hits
  138. if ($ajax == 0) {
  139. // Get db object using the db_id
  140. $previous_db = tripal_db_set_active('chado');
  141. $sql = "SELECT * FROM {db} WHERE db_id=%d";
  142. $db = db_fetch_object(db_query($sql, $att_db_id));
  143. tripal_db_set_active($previous_db);
  144. $content .= parse_NCBI_Blast_XML($analysisfeatureprop->afpvalue,$db,$max,$feature_id,$ajax, $analysis);
  145. // Otherwise, only update expandable box the user has clicked on
  146. } else {
  147. if ($att_db_id == $db_id) {
  148. // Get db object using the db_id
  149. $previous_db = tripal_db_set_active('chado');
  150. $sql = "SELECT * FROM {db} WHERE db_id=%d";
  151. $db = db_fetch_object(db_query($sql, $att_db_id));
  152. tripal_db_set_active($previous_db);
  153. $content .= parse_NCBI_Blast_XML($analysisfeatureprop->afpvalue,$db,$max,$feature_id,$ajax, $analysis);
  154. }
  155. }
  156. }
  157. // since this function provides output for addition into
  158. // a feature page, as well as an AJAX refresh of content
  159. // within the blast hits we need to setup the return
  160. // different depending on the request type
  161. if($ajax){
  162. drupal_json(array('update' => $content));
  163. } else {
  164. return $content;
  165. }
  166. }
  167. /*******************************************************************************
  168. * Scanning the file folder for blast results and prepare content for indexing
  169. */
  170. function tripal_get_blast_results_index_version ($feature_id){
  171. // Get cvterm_id for 'analysis_blast_output_iteration_hits' which is required
  172. // for inserting into the analysisfeatureprop table
  173. $previous_db = tripal_db_set_active('chado');
  174. $sql = "SELECT CVT.cvterm_id FROM {cvterm} CVT ".
  175. "INNER JOIN cv ON cv.cv_id = CVT.cv_id ".
  176. "WHERE CVT.name = 'analysis_blast_output_iteration_hits' ".
  177. "AND CV.name = 'tripal'";
  178. $type_id = db_result(db_query($sql));
  179. // Get xml string from analysisfeatureprop value column, get db_id from analysisprop value column
  180. // , and get analysis_id from analysisfeature table
  181. $sql = "SELECT AP.value AS apvalue, AFP.value AS afpvalue, AF.analysis_id AS aid
  182. FROM {analysisfeatureprop} AFP
  183. INNER JOIN analysisfeature AF ON AF.analysisfeature_id = AFP.analysisfeature_id
  184. INNER JOIN analysisprop AP ON AP.analysis_id = AF.analysis_id
  185. WHERE feature_id = %d
  186. AND AFP.type_id = %d ";
  187. $result = db_query($sql, $feature_id, $type_id);
  188. tripal_db_set_active($previous_db);
  189. // get the HTML content for viewing each of the XML file
  190. while ($analysisfeatureprop = db_fetch_object($result)) {
  191. // get analysis name and date
  192. $previous_db = tripal_db_set_active('chado');
  193. $sql = "SELECT analysis_id AS aid, name, to_char(timeexecuted, 'MM-DD-YYYY') AS time
  194. FROM {analysis} WHERE analysis_id = %d";
  195. $analysis = db_fetch_object(db_query($sql, $analysisfeatureprop->aid));
  196. tripal_db_set_active($previous_db);
  197. $blastsettings = explode("|", $analysisfeatureprop->apvalue);
  198. $att_db_id = $blastsettings [0];
  199. // Get db object using the db_id
  200. $previous_db = tripal_db_set_active('chado');
  201. $sql = "SELECT * FROM {db} WHERE db_id=%d";
  202. $db = db_fetch_object(db_query($sql, $att_db_id));
  203. tripal_db_set_active($previous_db);
  204. // Only index best 10 hits because the default page only shows 10 blast results
  205. $max = 10;
  206. $content .= parse_NCBI_Blast_XML_index_version($analysisfeatureprop->afpvalue,$db,$max,$feature_id,$ajax, $analysis);
  207. }
  208. return $content;
  209. }
  210. /*******************************************************************************
  211. * parse_NCBI_Blast_XML()
  212. * Parse XML BLAST result and generate HTML output
  213. */
  214. function parse_NCBI_Blast_XML($xml_string,$db,$max,$feature_id,$ajax, $analysis) {
  215. // Get the parser using db_id
  216. $sql = "SELECT * FROM {tripal_analysis_blast} WHERE db_id = %d";
  217. $parser = db_fetch_object(db_query($sql, $db->db_id));
  218. $db_name = $parser->displayname;
  219. $is_genbank = $parser->genbank_style;
  220. $regex_hit_id = $parser->regex_hit_id;
  221. $regex_hit_def = $parser->regex_hit_def;
  222. $regex_hit_accession = $parser->regex_hit_accession;
  223. // set default if regular expressions have not been specified
  224. if(!$regex_hit_id){
  225. $regex_hit_id = '/^(.*?)\s.*$/';
  226. } else {
  227. $regex_hit_id = '/'.$regex_hit_id.'/';
  228. }
  229. if(!$regex_hit_def){
  230. $regex_hit_def = '/^.*?\s(.*)$/';
  231. } else {
  232. $regex_hit_def = '/'.$regex_hit_def.'/';
  233. }
  234. if(!$regex_hit_accession){
  235. $regex_hit_accession = '/^(.*?)\s.*$/';
  236. } else {
  237. $regex_hit_accession = '/'.$regex_hit_accession.'/';
  238. }
  239. // add a URL for this database if one exists
  240. if($db->url && $db_name){
  241. $db_name = "<a href=\"$db->url\">$db_name</a>";
  242. }
  243. $url = url("sites/all/themes/theme_tripal/images/ajax-loader.gif");
  244. // generate the HTML header for the table of blast results
  245. if(!$ajax){ // don't regenerate the header divs if this is an ajax request
  246. // add on the ajaxLoading box for use when updating via ajax
  247. $html_out .= "<div id=\"tripal_ajaxLoading\" style=\"display:none\">".
  248. "<div id=\"loadingText\">Loading...</div>".
  249. "<img src=\"$url\"></div>";
  250. if (!$db_name) {
  251. $html_out .= "<div id=\"blast-hits\" class=\"tripal_blast-info-box\">".
  252. "<div class=\"tripal_expandableBox\">".
  253. "<h3>$analysis->name</h3></div>".
  254. "<div class=\"tripal_expandableBoxContent\" ".
  255. "id=\"blast_db_$db->db_id\">";
  256. } else {
  257. $html_out .= "<div id=\"blast-hits\" class=\"tripal_blast-info-box\">".
  258. "<div class=\"tripal_expandableBox\">".
  259. "<h3>$db_name</h3></div>".
  260. "<div class=\"tripal_expandableBoxContent\" ".
  261. "id=\"blast_db_$db->db_id\">";
  262. }
  263. };
  264. // Find node id for the analysis
  265. $ana_nid = db_result(db_query("SELECT nid FROM {chado_analysis} WHERE analysis_id = %d", $analysis->aid));
  266. $ana_url = url("node/".$ana_nid);
  267. // Show analysis date and name
  268. $html_out .= "<strong>Analysis Date: </strong>$analysis->time (<a href=$ana_url>$analysis->name</a>)<br>";
  269. // Load the file. This XML file should be an extract
  270. // of the original XML file with only a single iteration.
  271. // An iteration is essentially all the hits for a single
  272. // query sequence.
  273. $xml_output = simplexml_load_string($xml_string);
  274. $iteration = '';
  275. // new XML file parser has added the feature name within <Iteration_query-def> tags.
  276. if ($xml_output->getName() == 'Iteration') {
  277. foreach ($xml_output->children() as $xml_tag) {
  278. if ($xml_tag->getName() == 'Iteration_query-def') {
  279. // Here we show the feature name again to check if we pull the correct data
  280. $html_out .= "Query: $xml_tag<br>";
  281. } else if ($xml_tag->getName() == 'Iteration_hits') {
  282. $iteration = $xml_tag;
  283. }
  284. }
  285. // This is for the file parsed by the old parser
  286. } else {
  287. $iteration = $xml_output;
  288. }
  289. $number_hits = 0;
  290. foreach($iteration->children() as $hits){
  291. $number_hits ++;
  292. }
  293. // add the links for updating blast info using Ajax
  294. if($max != 10){
  295. $url = url("tripal_top_blast/$feature_id/$db->db_id/10");
  296. $html_out .= "<span><a onclick=\"return tripal_update_blast(".
  297. "this,$db->db_id)\" href=\"$url\">Show Best 10 Hits</a></span>";
  298. } else {
  299. $html_out .= "<span>Best 10 Hits Shown</span>";
  300. }
  301. if($number_hits <= 10){
  302. // Do nothing if number of hits <= 10
  303. } else if ($max != 25) {
  304. $url = url("tripal_top_blast/$feature_id/$db->db_id/25");
  305. $html_out .= "<span> | <a onclick=\"return tripal_update_blast(".
  306. "this,$db->db_id)\" href=\"$url\">Show Best 25 Hits</a></span>";
  307. }else {
  308. $html_out .= "<span> | Best 25 Hits Shown</span>";
  309. }
  310. if($number_hits <= 25){
  311. // Do nothing if number of hits <= 25
  312. } else if ($max != 0) {
  313. $url = url("tripal_top_blast/$feature_id/$db->db_id/0");
  314. $html_out .= "<span> | <a onclick=\"return tripal_update_blast(".
  315. "this,$db->db_id)\" href=\"$url\">Show All Hits</a> </span>";
  316. } else {
  317. $html_out .= "<span> | All Hits Shown</span>";
  318. }
  319. $html_out .= '<br><span><i>Note:</i> Click a description for more details.'.
  320. '</span>';
  321. $html_out .= '<span><table class="tripal_blast_results_table">'.
  322. ' <tr>'.
  323. ' <th nowrap>Match Name</th>'.
  324. ' <th nowrap>E value</th>'.
  325. ' <th nowrap>Identity</th>'.
  326. ' <th nowrap>Description</th>'.
  327. ' </tr>';
  328. // now run through the blast hits/hsps of this iteration
  329. // and generate the rows of the table
  330. foreach($iteration->children() as $hits){
  331. // if we've hit the maximum number of hits then
  332. // return
  333. if($max > 0 && $hit_count >= $max){
  334. $html_out .= '</table></span>';
  335. if(!$ajax){
  336. $html_out .= '</div></div>';
  337. }
  338. return $html_out;
  339. }
  340. $hit_count++;
  341. foreach($hits->children() as $hit){
  342. $best_evalue = 0;
  343. $best_identity = 0;
  344. $best_len = 0;
  345. $element_name = $hit->getName();
  346. if($element_name == 'Hit_id'){
  347. // if parsing "name, acc, desc" from three tags (1/3)
  348. if ($is_genbank) {
  349. $hit_name = $hit;
  350. }
  351. } else if($element_name == 'Hit_def'){
  352. if($is_genbank){
  353. $description = $hit;
  354. } else {
  355. $accession = preg_replace($regex_hit_accession,"$1",$hit);
  356. $hit_name = preg_replace($regex_hit_id,"$1",$hit);
  357. $description = preg_replace($regex_hit_def,"$1",$hit);
  358. }
  359. } else if($element_name == 'Hit_accession'){
  360. // if parsing "name, acc, desc" from three tags (3/3)
  361. if ($is_genbank){
  362. $accession = $hit;
  363. }
  364. // now run through each HSP for this hit
  365. } else if($element_name == 'Hit_hsps'){
  366. foreach($hit->children() as $hsp){
  367. foreach($hsp->children() as $hsp_info){
  368. $element_name = $hsp_info->getName();
  369. if($element_name == 'Hsp_num'){
  370. $hsp_num = $hsp_info;
  371. }
  372. if($element_name == 'Hsp_bit-score'){
  373. $hsp_bit_score = $hsp_info;
  374. }
  375. if($element_name == 'Hsp_score'){
  376. $hsp_score = $hsp_info;
  377. }
  378. if($element_name == 'Hsp_evalue'){
  379. $hsp_evalue = $hsp_info;
  380. // use the first evalue for this set of HSPs
  381. // as the best evalue. This get's shown as
  382. // info for the overall match.
  383. if(!$best_evalue){
  384. $best_evalue = $hsp_evalue;
  385. }
  386. }
  387. if($element_name == 'Hsp_query-from'){
  388. $hsp_query_from = $hsp_info;
  389. }
  390. if($element_name == 'Hsp_query-to'){
  391. $hsp_query_to = $hsp_info;
  392. }
  393. if($element_name == 'Hsp_hit-from'){
  394. $hsp_hit_from = $hsp_info;
  395. }
  396. if($element_name == 'Hsp_hit-to'){
  397. $hsp_hit_to = $hsp_info;
  398. }
  399. if($element_name == 'Hsp_query-frame'){
  400. $hsp_query_frame = $hsp_info;
  401. }
  402. if($element_name == 'Hsp_identity'){
  403. $hsp_identity = $hsp_info;
  404. // use the first evalue for this set of HSPs
  405. // as the best evalue. This get's shown as
  406. // info for the overall match.
  407. if(!$best_identity){
  408. $best_identity = $hsp_identity;
  409. }
  410. }
  411. if($element_name == 'Hsp_positive'){
  412. $hsp_positive = $hsp_info;
  413. }
  414. if($element_name == 'Hsp_align-len'){
  415. $hsp_align_len = $hsp_info;
  416. // use the first evalue for this set of HSPs
  417. // as the best evalue. This get's shown as
  418. // info for the overall match.
  419. if(!$best_len){
  420. $best_len = $hsp_align_len;
  421. }
  422. }
  423. if($element_name == 'Hsp_qseq'){
  424. $hsp_qseq = $hsp_info;
  425. }
  426. if($element_name == 'Hsp_hseq'){
  427. $hsp_hseq = $hsp_info;
  428. }
  429. if($element_name == 'Hsp_midline'){
  430. $hsp_midline = $hsp_info;
  431. }
  432. }
  433. if($hsp_num > 1){
  434. // $html_out .="<br>";
  435. }
  436. $hsp_html_out .="<b>HSP $hsp_num</b> <pre>Score: ".
  437. "$hsp_bit_score bits ($hsp_score), ".
  438. "Expect = $hsp_evalue<br>";
  439. $hsp_html_out .= sprintf("Identity = %d/%d (%.2f%%), ".
  440. "Postives = %d/%d (%.2f%%), ".
  441. "Query Frame = $hsp_query_frame".
  442. "</pre>",
  443. $hsp_identity, $hsp_align_len,
  444. $hsp_identity/$hsp_align_len*100,
  445. $hsp_positive, $hsp_align_len,
  446. $hsp_positive/$hsp_align_len*100);
  447. $hsp_html_out .= sprintf("<pre>Query: %4d $hsp_qseq %d".
  448. "<br>",
  449. $hsp_query_from,$hsp_query_to);
  450. $hsp_html_out .= sprintf(" $hsp_midline<br>");
  451. $hsp_html_out .= sprintf("Sbjct: %4d $hsp_hseq %d</pre>".
  452. "<br>",
  453. $hsp_hit_from,$hsp_hit_to);
  454. }
  455. }
  456. }
  457. $arrowr_url = url(drupal_get_path('theme', 'tripal')."/images/arrow_r.png");
  458. $html_out .= "<tr>";
  459. if($accession && $db->urlprefix){
  460. $html_out .= "<td><a href=\"$db->urlprefix$accession\" target=\"_blank\">$hit_name</a></td>";
  461. } else {
  462. // Test if this is another feature in the database
  463. $sql = "SELECT feature_id FROM {feature} WHERE uniquename = '%s'";
  464. $previous_db = db_set_active('chado');
  465. $hit_feature_id = db_result(db_query($sql, $hit_name));
  466. db_set_active($previous_db);
  467. // If it is, add link to that feature
  468. if ($hit_feature_id) {
  469. $hit_url = url("ID$hit_feature_id");
  470. $html_out .= "<td><a href=\"$hit_url\" target=\"_blank\">$hit_name</a></td>";
  471. } else {
  472. $html_out .= "<td>$hit_name</td>";
  473. }
  474. }
  475. $html_out .= "<td nowrap>$best_evalue</td>";
  476. $percent_identity = number_format($best_identity/$best_len*100, 2);
  477. $html_out .= "<td nowrap>$percent_identity%</td>";
  478. $html_out .= "<td nowrap>$description</td>";
  479. $html_out .= "</tr>
  480. <tr>
  481. <td colspan=4>
  482. <a class=\"blast-hit-arrow-icon\"><img src=$arrowr_url align=\"top\"> View Alignment</a>
  483. <div class=\"tripal_expandableSubBox\"></div>
  484. </td>
  485. </tr>
  486. <tr>
  487. <td colspan=4><div class=\"tripal_expandableSubBoxContent\">$hsp_html_out</div><td>
  488. </tr>";
  489. $hsp_html_out = '';
  490. }
  491. $html_out .= '</table></span>';
  492. if(!$ajax){
  493. // we don't have the header div's when ajax is being used to update
  494. $html_out .= '</div></div>';
  495. }
  496. return $html_out;
  497. }
  498. /*******************************************************************************
  499. * Parse NCBI Blast results for indexing so that user can use blast results to
  500. * find corresponding features
  501. */
  502. function parse_NCBI_Blast_XML_index_version($xml_string,$db,$feature_id) {
  503. // Get the parser using db_id
  504. $sql = "SELECT * FROM {tripal_analysis_blast} WHERE db_id = %d";
  505. $parser = db_fetch_object(db_query($sql, $db->db_id));
  506. $db_name = $parser->displayname;
  507. $is_genbank = $parser->genbank_style;
  508. $regex_hit_id = $parser->regex_hit_id;
  509. $regex_hit_def = $parser->regex_hit_def;
  510. $regex_hit_accession = $parser->regex_hit_accession;
  511. // set default if regular expressions have not been specified
  512. if(!$regex_hit_id){
  513. $regex_hit_id = '/^(.*?)\s.*$/';
  514. } else {
  515. $regex_hit_id = '/'.$regex_hit_id.'/';
  516. }
  517. if(!$regex_hit_def){
  518. $regex_hit_def = '/^.*?\s(.*)$/';
  519. } else {
  520. $regex_hit_def = '/'.$regex_hit_def.'/';
  521. }
  522. if(!$regex_hit_accession){
  523. $regex_hit_accession = '/^(.*?)\s.*$/';
  524. } else {
  525. $regex_hit_accession = '/'.$regex_hit_accession.'/';
  526. }
  527. $html_out .= "<h3>$db_name</h3>";
  528. // Load the file. This XML file should be an extract
  529. // of the original XML file with only a single iteration.
  530. // An iteration is essentially all the hits for a single
  531. // query sequence.
  532. $xml_output = simplexml_load_string($xml_string);
  533. $iteration = '';
  534. // new XML file parser has added the feature name within <Iteration_query-def> tags.
  535. if ($xml_output->getName() == 'Iteration') {
  536. foreach ($xml_output->children() as $xml_tag) {
  537. if ($xml_tag->getName() == 'Iteration_query-def') {
  538. // Here we show the feature name again to check if we pull the correct data
  539. $html_out .= "Query: $xml_tag<br>";
  540. } else if ($xml_tag->getName() == 'Iteration_hits') {
  541. $iteration = $xml_tag;
  542. }
  543. }
  544. // This is for the file parsed by the old parser
  545. } else {
  546. $iteration = $xml_output;
  547. }
  548. // now run through the blast hits/hsps of this iteration
  549. // and generate the rows of the table
  550. foreach($iteration->children() as $hits){
  551. $best_evalue = 0;
  552. foreach($hits->children() as $hit){
  553. $best_evalue = 0;
  554. $element_name = $hit->getName();
  555. if($element_name == 'Hit_id'){
  556. // if parsing "name, acc, desc" from three tags (1/3)
  557. if ($is_genbank) {
  558. $hit_name = $hit;
  559. }
  560. } else if($element_name == 'Hit_def'){
  561. if($is_genbank){
  562. $description = $hit;
  563. } else {
  564. $accession = preg_replace($regex_hit_accession,"$1",$hit);
  565. $hit_name = preg_replace($regex_hit_id,"$1",$hit);
  566. $description = preg_replace($regex_hit_def,"$1",$hit);
  567. }
  568. } else if($element_name == 'Hit_accession'){
  569. // if parsing "name, acc, desc" from three tags (3/3)
  570. if ($is_genbank){
  571. $accession = $hit;
  572. }
  573. // now run through each HSP for this hit
  574. }
  575. }
  576. $html_out .= "<p>$hit_name<br>";
  577. $html_out .= "$accession<br>";
  578. $html_out .= "<b>$description</b></br>";
  579. $hsp_html_out = '';
  580. }
  581. return $html_out;
  582. }
  583. /*******************************************************************************
  584. * Tripal Blast administrative setting form. This function is called by
  585. * tripal_analysis module which asks for an admin form to show on the page
  586. */
  587. function tripal_analysis_blast_get_settings() {
  588. // Get an array of node types with internal names as keys
  589. $options = node_get_types('names');
  590. // Add 'chado_feature' to allowed content types for showing blast results
  591. $allowedoptions ['chado_feature'] = "Show blast results on feature pages";
  592. $form['description'] = array(
  593. '#type' => 'item',
  594. '#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."),
  595. '#weight' => 0,
  596. );
  597. $form['tripal_analysis_blast_setting'] = array(
  598. '#type' => 'checkboxes',
  599. '#options' => $allowedoptions,
  600. '#default_value' => variable_get('tripal_analysis_blast_setting',
  601. array('chado_feature')),
  602. );
  603. $form['blast_parser'] = array(
  604. '#title' => t('Blast Parser Settings'),
  605. '#type' => 'fieldset',
  606. '#description' => t('Configure parsers for showing blast results. Each database is '.
  607. 'allowed to have one xml parser.'),
  608. '#weight' => 10
  609. );
  610. $previous_db = tripal_db_set_active('chado'); // use chado database
  611. // get a list of db from chado for user to choose
  612. $sql = 'SELECT db_id, name FROM {db} ORDER BY lower(name)';
  613. $results = db_query ($sql);
  614. $blastdbs = array();
  615. while ($db = db_fetch_object($results)){
  616. $blastdbs[$db->db_id] = $db->name;
  617. }
  618. $form['db_options'] = array(
  619. '#type' => 'value',
  620. '#value' => $blastdbs
  621. );
  622. $form['blast_parser']['blastdb'] = array(
  623. '#title' => t('Database'),
  624. '#type' => 'select',
  625. '#description' => t('The database used for the blast analysis.'),
  626. '#options' => $form['db_options']['#value'],
  627. '#attributes' => array(
  628. 'onChange' => "return tripal_update_regex(this)",
  629. )
  630. );
  631. $form['blast_parser']['displayname'] = array(
  632. '#title' => t('Title for the blast analysis'),
  633. '#type' => 'textfield',
  634. );
  635. $form['blast_parser']['gb_style_parser'] = array(
  636. '#title' => t('Use Genebank style parser. This will clear all regular expression settings for the selected database.'),
  637. '#type' => 'checkbox',
  638. '#attributes' => array(
  639. 'onClick' => "return tripal_set_genbank_style(this)",
  640. )
  641. );
  642. $form['blast_parser']['hit_id'] = array(
  643. '#title' => t('Regular expression for Hit Name'),
  644. '#type' => 'textfield',
  645. );
  646. $form['blast_parser']['hit_def'] = array(
  647. '#title' => t('Regular expression for Hit Description'),
  648. '#type' => 'textfield',
  649. );
  650. $form['blast_parser']['hit_accession'] = array(
  651. '#title' => t('Regular expression for Hit Accession'),
  652. '#type' => 'textfield',
  653. );
  654. $form['blast_parser']['button'] = array(
  655. '#type' => 'submit',
  656. '#value' => t('Save settings')
  657. );
  658. tripal_db_set_active($previous_db); // use drupal database
  659. $settings->form = $form;
  660. $settings->title = "Tripal Blast";
  661. return $settings;
  662. }
  663. /*******************************************************************************
  664. * Parse Blast XML Output file into analysisfeatureprop table
  665. */
  666. function tripal_analysis_blast_parseXMLFile ($analysis_id, $blastdb, $blastfile, $job_id) {
  667. // Prepare log
  668. $filename = preg_replace("/.*\/(.*)/", "$1", $blastfile);
  669. $logfile = file_directory_path() . "/tripal/tripal_analysis_blast/load_$filename.log";
  670. $log = fopen($logfile, 'a'); // append parsing results to log file
  671. // If user input a file (e.g. blast.xml)
  672. if (is_file($blastfile)) {
  673. // Parsing started
  674. print "Parsing File:".$blastfile." ...\n";
  675. fwrite($log, date("D M j G:i:s Y").". Loading $blastfile\n");
  676. // Get cvterm_id for 'analysis_blast_output_iteration_hits' which is required
  677. // for inserting into the analysisfeatureprop table
  678. $previous_db = tripal_db_set_active('chado'); // use chado database
  679. $sql = "SELECT CVT.cvterm_id FROM {cvterm} CVT ".
  680. "INNER JOIN cv ON cv.cv_id = CVT.cv_id ".
  681. "WHERE CVT.name = 'analysis_blast_output_iteration_hits' ".
  682. "AND CV.name = 'tripal'";
  683. $type_id = db_result(db_query($sql));
  684. // Load the XML file.
  685. $blastoutput = simplexml_load_file($blastfile);
  686. $no_iterations = 0;
  687. foreach($blastoutput->children() as $tmp) {
  688. if ($tmp->getName() == 'BlastOutput_iterations') {
  689. foreach($tmp->children() as $itr) {
  690. if ($itr->getName() == 'Iteration') {
  691. $no_iterations ++;
  692. }
  693. }
  694. }
  695. }
  696. print "$no_iterations iterations to be processed.\n";
  697. $interval = intval($no_iterations * 0.01);
  698. $idx_iterations = 0;
  699. foreach ($blastoutput->children() as $blastoutput_tags) {
  700. if ($blastoutput_tags->getName() == 'BlastOutput_iterations') {
  701. foreach($blastoutput_tags->children() as $iterations) {
  702. if ($iterations->getName() == 'Iteration') {
  703. // Set job status
  704. $idx_iterations ++;
  705. if ($idx_iterations % $interval == 0) {
  706. $percentage = (int) ($idx_iterations / $no_iterations * 100);
  707. tripal_db_set_active($previous_db);
  708. tripal_job_set_progress($job_id, $percentage);
  709. $previous_db = tripal_db_set_active('chado');
  710. print $percentage."% ";
  711. }
  712. // now run through the blast hits/hsps of this iteration
  713. // and generate the rows of the table
  714. $feature_id = 0;
  715. foreach($iterations->children() as $iteration_tags) {
  716. // Match chado feature uniquename with <Iteration_query-def>
  717. // and get the feature_id
  718. $featurenaem_xml = '';
  719. if($iteration_tags->getName() == 'Iteration_query-def'){
  720. // If the Iteration_query-def in the format of "feature_id|uniquename"
  721. // get feature_id from it directly
  722. if (preg_match("/^(\d+)\|.+/", $iteration_tags, $matches)) {
  723. $feature_id = $matches[1];
  724. // If not in above format, try to match <Iteration_query-def> to feature's uniquename
  725. } else {
  726. // treat the first word of <Iteration_query-def> as uniquename
  727. $first_word = $iteration_tags;
  728. if (preg_match('/^(.*?)\s.*$/', $iteration_tags, $matches)) {
  729. $first_word = $matches[1];
  730. }
  731. // Find out how many features match this uniquename
  732. $sql = "SELECT count(feature_id) FROM {feature} ".
  733. "WHERE uniquename = '%s' ";
  734. $no_features = db_result(db_query($sql, $first_word));
  735. // If there is only one match, get the feature_id
  736. if ($no_features == 1) {
  737. $sql = "SELECT feature_id FROM {feature} ".
  738. "WHERE uniquename = '%s' ";
  739. $feature_id = db_result(db_query($sql, $first_word));
  740. // If the uniquename matches more than one features then skip and print 'Ambiguous'
  741. } else if ($no_features > 1) {
  742. fwrite($log, "Ambiguous: ".$first_word." matches more than one feature and is not processed.\n");
  743. continue;
  744. // If the uniquename did not match, skip and print 'Failed'
  745. } else {
  746. fwrite($log, "Failed: ".$first_word."\n");
  747. }
  748. }
  749. // Successfully matched. print 'Succeeded'
  750. if ($feature_id) {
  751. fwrite($log, "Succeeded: ".$first_word." => feature id:".$feature_id);
  752. $featurename_xml = $iteration_tags->asXML();
  753. }
  754. // Insert Iteration_hits into analysisfeatureprop and analysisfeature tables
  755. } else if($iteration_tags->getName() == 'Iteration_hits'){
  756. if ($feature_id) {
  757. // Make sure this iteration doesn't exist in analysisfeatureprop. If it does, update but not insert
  758. $sql = "SELECT analysisfeatureprop_id FROM {analysisfeatureprop} AFP ".
  759. "INNER JOIN analysisfeature AF ON AF.analysisfeature_id = AFP.analysisfeature_id ".
  760. "WHERE feature_id=%d ".
  761. "AND analysis_id=%d ".
  762. "AND type_id=%d ";
  763. $result = db_query($sql, $feature_id, $analysis_id, $type_id);
  764. $analysisfeatureprop = db_fetch_object($result);
  765. $xml_content = "<Iteration>\n".$featurename_xml."\n".$iteration_tags->asXML()."\n</Iteration>";
  766. // If this Iteration_hits already exists, update it
  767. if ($analysisfeatureprop) {
  768. $sql = "UPDATE {analysisfeatureprop} ".
  769. "SET value = '%s' ".
  770. "WHERE analysisfeatureprop_id = %d ";
  771. db_query($sql, $xml_content, $analysisfeatureprop->analysisfeatureprop_id);
  772. fwrite($log, " (Update)\n"); // write to log
  773. // Otherwise, insert the Iteration_hits into analysisfeature and analysisfeatureprop tables
  774. } else {
  775. //------------------------------------------------------
  776. // Insert into analysisfeature table
  777. //------------------------------------------------------
  778. $sql = "INSERT INTO {analysisfeature} (feature_id, analysis_id) ".
  779. "VALUES (%d, %d)";
  780. db_query ($sql, $feature_id, $analysis_id);
  781. // Get the newly inserted analysisfeature_id
  782. $sql = "SELECT analysisfeature_id FROM {analysisfeature} WHERE feature_id = %d AND analysis_id = %d";
  783. $analysisfeature_id = db_result(db_query($sql, $feature_id, $analysis_id));
  784. //------------------------------------------------------
  785. // Insert into analysisfeatureprop table
  786. //------------------------------------------------------
  787. $sql = "INSERT INTO {analysisfeatureprop} (analysisfeature_id, type_id, value, rank)".
  788. "VALUES (%d, %d, '%s', %d)";
  789. db_query($sql, $analysisfeature_id, $type_id, $xml_content, '0');
  790. fwrite($log, " (Insert)\n"); // write to log
  791. }
  792. }
  793. }
  794. }
  795. }
  796. }
  797. }
  798. }
  799. tripal_db_set_active ($previous_db); // Use drupal database
  800. // Otherwise, $blastfile is a directory. Iterate through all xml files in it
  801. } else {
  802. $dir_handle = @opendir($blastfile) or die("Unable to open $blastfile");
  803. $pattern = sql_regcase($blastfile . "/*.XML");
  804. $total_files = count(glob($pattern));
  805. print "$total_files file(s) to be parsed.\n";
  806. $interval = intval($total_files * 0.01);
  807. $no_file = 0;
  808. // Get cvterm_id for 'analysis_blast_output_iteration_hits' which is required
  809. // for inserting into the analysisfeatureprop table
  810. $previous_db = tripal_db_set_active('chado'); // use chado database
  811. $sql = "SELECT CVT.cvterm_id FROM {cvterm} CVT ".
  812. "INNER JOIN cv ON cv.cv_id = CVT.cv_id ".
  813. "WHERE CVT.name = 'analysis_blast_output_iteration_hits' ".
  814. "AND CV.name = 'tripal'";
  815. $type_id = db_result(db_query($sql));
  816. // Parsing all files in the directory
  817. while ($file = readdir($dir_handle)) {
  818. if(preg_match("/^.*\.XML/i",$file)){
  819. // Set job status
  820. if ($no_file % $interval == 0) {
  821. $percentage = (int) ($no_file / $total_files * 100);
  822. tripal_db_set_active($previous_db);
  823. tripal_job_set_progress($job_id, $percentage);
  824. $previous_db = tripal_db_set_active('chado');
  825. print $percentage."% ";
  826. }
  827. // Parsing started
  828. print "Parsing File:".$file.". ";
  829. fwrite($log, date("D M j G:i:s Y").". Loading $file\n");
  830. // Load the XML file.
  831. $blastoutput = simplexml_load_file($blastfile."/".$file);
  832. $no_iterations = 0;
  833. foreach($blastoutput->children() as $tmp) {
  834. if ($tmp->getName() == 'BlastOutput_iterations') {
  835. foreach($tmp->children() as $itr) {
  836. if ($itr->getName() == 'Iteration') {
  837. $no_iterations ++;
  838. }
  839. }
  840. }
  841. }
  842. print "$no_iterations iterations to be processed.\n";
  843. foreach ($blastoutput->children() as $blastoutput_tags) {
  844. if ($blastoutput_tags->getName() == 'BlastOutput_iterations') {
  845. foreach($blastoutput_tags->children() as $iterations) {
  846. if ($iterations->getName() == 'Iteration') {
  847. // now run through the blast hits/hsps of this iteration
  848. // and generate the rows of the table
  849. $feature_id = 0;
  850. foreach($iterations->children() as $iteration_tags) {
  851. // Match chado feature uniquename with <Iteration_query-def>
  852. // and get the feature_id
  853. $featurenaem_xml = '';
  854. if($iteration_tags->getName() == 'Iteration_query-def'){
  855. // If the Iteration_query-def in the format of "feature_id|uniquename"
  856. // get feature_id from it directly
  857. if (preg_match("/^(\d+)\|.+/", $iteration_tags, $matches)) {
  858. $feature_id = $matches[1];
  859. // If not in above format, try to match <Iteration_query-def> to feature's uniquename
  860. } else {
  861. // treat the first word of <Iteration_query-def> as uniquename
  862. $first_word = $iteration_tags;
  863. if (preg_match('/^(.*?)\s.*$/', $iteration_tags, $matches)) {
  864. $first_word = $matches[1];
  865. }
  866. // Find out how many features match this uniquename
  867. $sql = "SELECT count(feature_id) FROM {feature} ".
  868. "WHERE uniquename = '%s' ";
  869. $no_features = db_result(db_query($sql, $first_word));
  870. // If there is only one match, get the feature_id
  871. if ($no_features == 1) {
  872. $sql = "SELECT feature_id FROM {feature} ".
  873. "WHERE uniquename = '%s' ";
  874. $feature_id = db_result(db_query($sql, $first_word));
  875. // If the uniquename matches more than one features then skip and print 'Ambiguous'
  876. } else if ($no_features > 1) {
  877. fwrite($log, "Ambiguous: ".$first_word." matches more than one feature and is not processed.\n");
  878. continue;
  879. // If the uniquename did not match, skip and print 'Failed'
  880. } else {
  881. fwrite($log, "Failed: ".$first_word."\n");
  882. }
  883. }
  884. // Successfully matched. print 'Succeeded'
  885. if ($feature_id) {
  886. fwrite($log, "Succeeded: ".$first_word." => feature id:".$feature_id);
  887. $featurename_xml = $iteration_tags->asXML();
  888. }
  889. // Insert Iteration_hits into analysisfeatureprop and analysisfeature tables
  890. } else if($iteration_tags->getName() == 'Iteration_hits'){
  891. if ($feature_id) {
  892. // Make sure this iteration doesn't exist in analysisfeatureprop. If it does, update but not insert
  893. $sql = "SELECT analysisfeatureprop_id FROM {analysisfeatureprop} AFP ".
  894. "INNER JOIN analysisfeature AF ON AF.analysisfeature_id = AFP.analysisfeature_id ".
  895. "WHERE feature_id=%d ".
  896. "AND analysis_id=%d ".
  897. "AND type_id=%d ";
  898. $result = db_query($sql, $feature_id, $analysis_id, $type_id);
  899. $analysisfeatureprop = db_fetch_object($result);
  900. $xml_content = "<Iteration>\n".$featurename_xml."\n".$iteration_tags->asXML()."\n</Iteration>";
  901. // If this Iteration_hits already exists, update it
  902. if ($analysisfeatureprop) {
  903. $sql = "UPDATE {analysisfeatureprop} ".
  904. "SET value = '%s' ".
  905. "WHERE analysisfeatureprop_id = %d ";
  906. db_query($sql, $xml_content, $analysisfeatureprop->analysisfeatureprop_id);
  907. fwrite($log, " (Update)\n"); // write to log
  908. // Otherwise, insert the Iteration_hits into analysisfeature and analysisfeatureprop tables
  909. } else {
  910. //------------------------------------------------------
  911. // Insert into analysisfeature table
  912. //------------------------------------------------------
  913. $sql = "INSERT INTO {analysisfeature} (feature_id, analysis_id) ".
  914. "VALUES (%d, %d)";
  915. db_query ($sql, $feature_id, $analysis_id);
  916. // Get the newly inserted analysisfeature_id
  917. $sql = "SELECT analysisfeature_id FROM {analysisfeature} WHERE feature_id = %d AND analysis_id = %d";
  918. $analysisfeature_id = db_result(db_query($sql, $feature_id, $analysis_id));
  919. //------------------------------------------------------
  920. // Insert into analysisfeatureprop table
  921. //------------------------------------------------------
  922. $sql = "INSERT INTO {analysisfeatureprop} (analysisfeature_id, type_id, value, rank)".
  923. "VALUES (%d, %d, '%s', %d)";
  924. db_query($sql, $analysisfeature_id, $type_id, $xml_content, '0');
  925. fwrite($log, " (Insert)\n"); // write to log
  926. }
  927. }
  928. }
  929. }
  930. }
  931. }
  932. }
  933. }
  934. $no_file ++;
  935. }
  936. }
  937. tripal_db_set_active ($previous_db); // Use drupal database
  938. }
  939. print "Done.\nSuccessful and failed entries have been saved in the log file:\n $logfile\n";
  940. fwrite($log, "\n");
  941. fclose($log);
  942. return;
  943. }
  944. /*******************************************************************************
  945. * This function is only called by ajax to get regular expressions for blast
  946. * admin page
  947. */
  948. function tripal_get_blast_regex ($db_id) {
  949. $sql = "SELECT * FROM {tripal_analysis_blast} WHERE db_id = %d";
  950. $blast_regexs = db_fetch_object(db_query($sql, $db_id));
  951. drupal_json(
  952. array(
  953. 'name' => $blast_regexs->displayname,
  954. 'genbank_style' => $blast_regexs->genbank_style,
  955. 'reg1' => $blast_regexs->regex_hit_id,
  956. 'reg2' => $blast_regexs->regex_hit_def,
  957. 'reg3' => $blast_regexs->regex_hit_accession,
  958. )
  959. );
  960. }
  961. /*******************************************************************************
  962. * Provide information to drupal about the node types that we're creating
  963. * in this module
  964. */
  965. function tripal_analysis_blast_node_info() {
  966. $nodes = array();
  967. $nodes['chado_analysis_blast'] = array(
  968. 'name' => t('Analysis: Blast'),
  969. 'module' => 'chado_analysis_blast',
  970. 'description' => t('A blast analysis from the chado database'),
  971. 'has_title' => FALSE,
  972. 'title_label' => t('Analysis: Blast'),
  973. 'has_body' => FALSE,
  974. 'body_label' => t('Blast Analysis Description'),
  975. 'locked' => TRUE
  976. );
  977. return $nodes;
  978. }
  979. /*******************************************************************************
  980. * Provide a Blast Analysis form
  981. */
  982. function chado_analysis_blast_form ($node){
  983. //dprint_r($node);
  984. $type = node_get_types('type', $node);
  985. $form = array();
  986. $form['title']= array(
  987. '#type' => 'hidden',
  988. '#default_value' => $node->title,
  989. );
  990. $form['analysisname']= array(
  991. '#type' => 'textfield',
  992. '#title' => t('Analysis Name'),
  993. '#required' => FALSE,
  994. '#default_value' => $node->analysisname,
  995. '#weight' => 1
  996. );
  997. $form['program']= array(
  998. '#type' => 'textfield',
  999. '#title' => t('Program'),
  1000. '#required' => TRUE,
  1001. '#default_value' => $node->program,
  1002. '#weight' => 2
  1003. );
  1004. $form['programversion']= array(
  1005. '#type' => 'textfield',
  1006. '#title' => t('Program Version'),
  1007. '#required' => TRUE,
  1008. '#default_value' => $node->programversion,
  1009. '#weight' => 3
  1010. );
  1011. $form['algorithm']= array(
  1012. '#type' => 'textfield',
  1013. '#title' => t('Algorithm'),
  1014. '#required' => FALSE,
  1015. '#default_value' => $node->algorithm,
  1016. '#weight' => 4
  1017. );
  1018. $form['sourcename']= array(
  1019. '#type' => 'textfield',
  1020. '#title' => t('Source Name'),
  1021. '#required' => FALSE,
  1022. '#default_value' => $node->sourcename,
  1023. '#weight' => 5
  1024. );
  1025. $form['sourceversion']= array(
  1026. '#type' => 'textfield',
  1027. '#title' => t('Source Version'),
  1028. '#required' => FALSE,
  1029. '#default_value' => $node->sourceversion,
  1030. '#weight' => 6
  1031. );
  1032. $form['sourceuri']= array(
  1033. '#type' => 'textfield',
  1034. '#title' => t('Source URI'),
  1035. '#required' => FALSE,
  1036. '#default_value' => $node->sourceuri,
  1037. '#weight' => 7
  1038. );
  1039. // Get time saved in chado
  1040. $default_time = $node->timeexecuted;
  1041. $year = preg_replace("/^(\d+)-\d+-\d+ .*/", "$1", $default_time);
  1042. $month = preg_replace("/^\d+-0?(\d+)-\d+ .*/", "$1", $default_time);
  1043. $day = preg_replace("/^\d+-\d+-0?(\d+) .*/", "$1", $default_time);
  1044. // If the time is not set, use current time
  1045. if (!$default_time) {
  1046. $default_time = time();
  1047. $year = format_date($default_time, 'custom', 'Y');
  1048. $month = format_date($default_time, 'custom', 'n');
  1049. $day = format_date($default_time, 'custom', 'j');
  1050. }
  1051. $form['timeexecuted']= array(
  1052. '#type' => 'date',
  1053. '#title' => t('Time Executed'),
  1054. '#required' => TRUE,
  1055. '#default_value' => array(
  1056. 'year' => $year,
  1057. 'month' => $month,
  1058. 'day' => $day,
  1059. ),
  1060. '#weight' => 8
  1061. );
  1062. $form['description']= array(
  1063. '#type' => 'textarea',
  1064. '#rows' => 15,
  1065. '#title' => t('Description and/or Program Settings'),
  1066. '#required' => FALSE,
  1067. '#default_value' => check_plain($node->description),
  1068. '#weight' => 9
  1069. );
  1070. // Blast specific settings
  1071. if (preg_match("/.*\|.*\|.*/",$node->blastdb)) {
  1072. $prop_values = explode("|", $node->blastdb);
  1073. $node->blastdb = $prop_values[0];
  1074. $node->blastfile = $prop_values[1];
  1075. $node->blastparameters = $prop_values[2];
  1076. }
  1077. $form['blast'] = array(
  1078. '#title' => t('Blast Settings'),
  1079. '#type' => 'fieldset',
  1080. '#description' => t('Specific Settings for Blast Analysis.'),
  1081. '#collapsible' => TRUE,
  1082. '#attributes' => array('id' => 'blast-extra-settings'),
  1083. '#weight' => 11
  1084. );
  1085. $previous_db = tripal_db_set_active('chado'); // use chado database
  1086. // get a list of db from chado for user to choose
  1087. $sql = 'SELECT db_id, name FROM {db} ORDER BY lower(name)';
  1088. $results = db_query ($sql);
  1089. tripal_db_set_active($previous_db);
  1090. $blastdbs = array();
  1091. while ($db = db_fetch_object($results)){
  1092. $blastdbs[$db->db_id] = $db->name;
  1093. }
  1094. $form['db_options'] = array(
  1095. '#type' => 'value',
  1096. '#value' => $blastdbs
  1097. );
  1098. $form['blast']['blastdb'] = array(
  1099. '#title' => t('Database'),
  1100. '#type' => 'select',
  1101. '#description' => t('The database used for the blast analysis.'),
  1102. '#options' => $form['db_options']['#value'],
  1103. '#default_value' => $node->blastdb,
  1104. );
  1105. $form['blast']['blastfile'] = array(
  1106. '#title' => t('Blast xml File: (if you input a directory without the tailing slash, all xml files in the directory will be loaded)'),
  1107. '#type' => 'textfield',
  1108. '#description' => t('The xml output file generated by blast in full path.'),
  1109. '#default_value' => $node->blastfile,
  1110. );
  1111. $form['blast']['blastjob'] = array(
  1112. '#type' => 'checkbox',
  1113. '#title' => t('Submit a job to parse the xml output into analysisfeatureprop table'),
  1114. '#description' => t('Note: features associated with the blast results must '.
  1115. 'exist in chado before parsing the file. Otherwise, blast '.
  1116. 'results that cannot be linked to a feature will be '.
  1117. 'discarded. Also, Triapl Blast module needs to be enabled.'),
  1118. '#default_value' => $node->blastjob
  1119. );
  1120. $form['blast']['blastparameters'] = array(
  1121. '#title' => t('Parameters'),
  1122. '#type' => 'textfield',
  1123. '#description' => t('The parameters for running the blast analysis.'),
  1124. '#default_value' => $node->blastparameters,
  1125. );
  1126. return $form;
  1127. }
  1128. function chado_analysis_blast_validate($node, &$form){
  1129. ##dprint_r($node);
  1130. // This validation is being used for three activities:
  1131. // CASE A: Update a node that exists in both drupal and chado
  1132. // CASE B: Synchronizing a node from chado to drupal
  1133. // CASE C: Inserting a new node that exists in niether drupal nor chado
  1134. // Only nodes being updated will have an nid already
  1135. if($node->nid){
  1136. //---------------------------------------------------
  1137. // CASE A: We are validating a form for updating an existing node
  1138. //---------------------------------------------------
  1139. // TO DO: check that the new fields don't yield a non-unique primary key in chado
  1140. }
  1141. else{
  1142. // To differentiate if we are syncing or creating a new analysis altogther, see if an
  1143. // analysis_id already exists
  1144. if($node->analysis_id){
  1145. //---------------------------------------------------
  1146. // CASE B: Synchronizing a node from chado to drupal
  1147. //---------------------------------------------------
  1148. }
  1149. else{
  1150. //---------------------------------------------------
  1151. // CASE C: We are validating a form for inserting a new node
  1152. //---------------------------------------------------
  1153. // The primary key for the chado analysis table is
  1154. // program, programversion, sourcename
  1155. // Check to see if this analysis really is new -ie, it doesn't have the same
  1156. // primary key as any other analysis
  1157. $sql = "SELECT analysis_id ".
  1158. "FROM {analysis} ".
  1159. "WHERE program='%s'".
  1160. "AND programversion='%s'".
  1161. "AND sourcename='%s'";
  1162. $previous_db = tripal_db_set_active('chado');
  1163. $analysis_id = db_result(db_query($sql, $node->program, $node->programversion, $node->sourcename));
  1164. tripal_db_set_active($previous_db);
  1165. if($analysis_id){
  1166. //---------------------------------------------------
  1167. // this primary key already exists in chado analysis table!
  1168. //---------------------------------------------------
  1169. // check to see if it has also been synced with drupal
  1170. $sql = "SELECT nid FROM {chado_analysis} ".
  1171. "WHERE analysis_id = %d";
  1172. $node_id = db_result(db_query($sql, $analysis_id));
  1173. if($node_id){
  1174. //---------------------------------------------------
  1175. // the analysis has already been synced with drupal, redirect the user
  1176. // to modify that node or start over
  1177. //---------------------------------------------------
  1178. $error = 'This analysis already exists in the chado database (analysis id ';
  1179. $error .= $analysis_id.') and has been synchronized ';
  1180. $error .= 'with drupal. See node '.$node_id.' if you wish to update that analysis. ';
  1181. $error .= ' For a new analysis, please select a unique primary key ';
  1182. $error .= '(primary key consists of sourcename, program and programversion).';
  1183. form_set_error('sourcename', t($error));
  1184. }
  1185. else{
  1186. //---------------------------------------------------
  1187. // the analysis does not exist in drupal - tell the user
  1188. // to sync from chado or create a new unique primary key
  1189. //---------------------------------------------------
  1190. $error = 'This analysis already exists in the chado database (analysis id ';
  1191. $error .= $analysis_id.') but has not been synchronized ';
  1192. $error .= 'with drupal. See the tripal admin pages to synchronize. ';
  1193. $error .= ' For a new analysis, please select a unique primary key ';
  1194. $error .= '(primary key consists of sourcename, program and programversion).';
  1195. form_set_error('sourcename', t($error));
  1196. }
  1197. }
  1198. }
  1199. }
  1200. }
  1201. function chado_analysis_blast_insert($node){
  1202. global $user;
  1203. // Create a timestamp so we can insert it into the chado database
  1204. $time = $node->timeexecuted;
  1205. $month = $time['month'];
  1206. $day = $time['day'];
  1207. $year = $time['year'];
  1208. $timestamp = $month.'/'.$day.'/'.$year;
  1209. //---------------------------------------------------
  1210. // First add the item to the chado analysis table
  1211. //---------------------------------------------------
  1212. $sql = "INSERT INTO {analysis} ".
  1213. " (name, description, program, programversion, algorithm, ".
  1214. " sourcename, sourceversion, sourceuri, timeexecuted) ".
  1215. "VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s')";
  1216. $previous_db = tripal_db_set_active('chado'); // use chado database
  1217. db_query($sql,$node->analysisname, $node->description,
  1218. $node->program,$node->programversion,$node->algorithm,
  1219. $node->sourcename, $node->sourceversion, $node->sourceuri,
  1220. $timestamp);
  1221. // find the newly entered analysis_id
  1222. $sql = "SELECT analysis_id ".
  1223. "FROM {analysis} ".
  1224. "WHERE program='%s'".
  1225. "AND programversion='%s'".
  1226. "AND sourcename='%s'";
  1227. $analysis_id = db_result(db_query($sql, $node->program,
  1228. $node->programversion, $node->sourcename));
  1229. // Get cvterm_id for 'analysis_blast_settings'
  1230. $sql = "SELECT CVT.cvterm_id FROM {cvterm} CVT ".
  1231. "INNER JOIN cv ON cv.cv_id = CVT.cv_id ".
  1232. "WHERE CVT.name = 'analysis_blast_settings' ".
  1233. "AND CV.name = 'tripal'";
  1234. $type_id = db_result(db_query($sql));
  1235. //---------------------------------------------------
  1236. // Insert into chado {analysisprop} table
  1237. //---------------------------------------------------
  1238. $sql = "INSERT INTO {analysisprop} (analysis_id, type_id, value) ".
  1239. "VALUES (%d, %d, '%s')";
  1240. $blastsettings = $node->blastdb."|".$node->blastfile."|".$node->blastparameters;
  1241. db_query($sql, $analysis_id, $type_id, $blastsettings);
  1242. tripal_db_set_active($previous_db); // switch back to drupal database
  1243. //---------------------------------------------------
  1244. // Add a job if the user wants to parse the xml output
  1245. //---------------------------------------------------
  1246. if($node->blastjob) {
  1247. $job_args[0] = $analysis_id;
  1248. $job_args[1] = $node->blastdb;
  1249. $job_args[2] = $node->blastfile;
  1250. if (is_readable($node->blastfile)) {
  1251. $fname = preg_replace("/.*\/(.*)/", "$1", $node->blastfile);
  1252. tripal_add_job("Parse blast: $fname",'tripal_analysis_blast',
  1253. 'tripal_analysis_blast_parseXMLFile', $job_args, $user->uid);
  1254. } else {
  1255. drupal_set_message("Can not open blast output file. Job not scheduled.");
  1256. }
  1257. }
  1258. // next add the item to the drupal table
  1259. $sql = "INSERT INTO {chado_analysis} (nid, vid, analysis_id) ".
  1260. "VALUES (%d, %d, %d)";
  1261. db_query($sql,$node->nid,$node->vid,$analysis_id);
  1262. // Create a title for the analysis node using the unique keys so when the
  1263. // node is saved, it will have a title
  1264. $record = new stdClass();
  1265. // If the analysis has a name, use it as the node title. If not, construct
  1266. // the title using program, programversion, and sourcename
  1267. if ($node->analysisname) {
  1268. $record->title = $node->analysisname;
  1269. } else {
  1270. //Construct node title as "program (version)
  1271. $record->title = "$node->program ($node->programversion)";
  1272. }
  1273. $record->nid = $node->nid;
  1274. drupal_write_record('node',$record,'nid');
  1275. drupal_write_record('node_revisions',$record,'nid');
  1276. }
  1277. /*******************************************************************************
  1278. * Delete blast anlysis
  1279. */
  1280. function chado_analysis_blast_delete($node){
  1281. // Before removing, get analysis_id so we can remove it from chado database
  1282. // later
  1283. $sql_drupal = "SELECT analysis_id ".
  1284. "FROM {chado_analysis} ".
  1285. "WHERE nid = %d ".
  1286. "AND vid = %d";
  1287. $analysis_id = db_result(db_query($sql_drupal, $node->nid, $node->vid));
  1288. // Remove data from the {chado_analysis}, {node}, and {node_revisions} tables
  1289. $sql_del = "DELETE FROM {chado_analysis} ".
  1290. "WHERE nid = %d ".
  1291. "AND vid = %d";
  1292. db_query($sql_del, $node->nid, $node->vid);
  1293. $sql_del = "DELETE FROM {node} ".
  1294. "WHERE nid = %d ".
  1295. "AND vid = %d";
  1296. db_query($sql_del, $node->nid, $node->vid);
  1297. $sql_del = "DELETE FROM {node_revisions} ".
  1298. "WHERE nid = %d ".
  1299. "AND vid = %d";
  1300. db_query($sql_del, $node->nid, $node->vid);
  1301. //Remove from analysisfeatureprop, analysisfeature, analysis, and analysisprop tables
  1302. $previous_db = tripal_db_set_active('chado');
  1303. $sql = "SELECT analysisfeature_id FROM {analysisfeature} WHERE analysis_id=%d";
  1304. $results = db_query($sql, $analysis_id);
  1305. while ($af = db_fetch_object($results)) {
  1306. db_query("DELETE FROM {analysisfeatureprop} WHERE analysisfeature_id = %d", $af->analysisfeature_id);
  1307. }
  1308. db_query("DELETE FROM {analysisfeature} WHERE analysis_id = %d", $analysis_id);
  1309. db_query("DELETE FROM {analysisprop} WHERE analysis_id = %d", $analysis_id);
  1310. db_query("DELETE FROM {analysis} WHERE analysis_id = %d", $analysis_id);
  1311. tripal_db_set_active($previous_db);
  1312. }
  1313. /*******************************************************************************
  1314. * Update blast analysis
  1315. */
  1316. function chado_analysis_blast_update($node){
  1317. global $user;
  1318. if($node->revision){
  1319. // TODO -- decide what to do about revisions
  1320. } else {
  1321. // Create a timestamp so we can insert it into the chado database
  1322. $time = $node->timeexecuted;
  1323. $month = $time['month'];
  1324. $day = $time['day'];
  1325. $year = $time['year'];
  1326. $timestamp = $month.'/'.$day.'/'.$year;
  1327. // get the analysis_id for this node:
  1328. $sql = "SELECT analysis_id ".
  1329. "FROM {chado_analysis} ".
  1330. "WHERE vid = %d";
  1331. $analysis_id = db_fetch_object(db_query($sql, $node->vid))->analysis_id;
  1332. $sql = "UPDATE {analysis} ".
  1333. "SET name = '%s', ".
  1334. " description = '%s', ".
  1335. " program = '%s', ".
  1336. " programversion = '%s', ".
  1337. " algorithm = '%s', ".
  1338. " sourcename = '%s', ".
  1339. " sourceversion = '%s', ".
  1340. " sourceuri = '%s', ".
  1341. " timeexecuted = '%s' ".
  1342. "WHERE analysis_id = %d ";
  1343. $previous_db = tripal_db_set_active('chado'); // use chado database
  1344. db_query($sql, $node->analysisname, $node->description, $node->program,
  1345. $node->programversion,$node->algorithm,$node->sourcename,
  1346. $node->sourceversion, $node->sourceuri, $timestamp, $analysis_id);
  1347. // Get cvterm_id for 'analysis_blast_settings'
  1348. $sql = "SELECT CVT.cvterm_id FROM {cvterm} CVT ".
  1349. "INNER JOIN cv CV ON CV.cv_id = CVT.cv_id ".
  1350. "WHERE CVT.name = 'analysis_blast_settings' ".
  1351. "AND CV.name = 'tripal'";
  1352. $type_id = db_result(db_query($sql));
  1353. $sql = "UPDATE {analysisprop} ".
  1354. "SET value = '%s' ".
  1355. "WHERE analysis_id = %d AND type_id = %d";
  1356. $blastsettings = $node->blastdb."|".$node->blastfile."|".$node->blastparameters;
  1357. db_query($sql, $blastsettings, $analysis_id, $type_id);
  1358. tripal_db_set_active($previous_db); // switch back to drupal database
  1359. // Add a job if the user wants to parse the xml output
  1360. if($node->blastjob) {
  1361. $job_args[0] = $analysis_id;
  1362. $job_args[1] = $node->blastdb;
  1363. $job_args[2] = $node->blastfile;
  1364. if (is_readable($node->blastfile)) {
  1365. $fname = preg_replace("/.*\/(.*)/", "$1", $node->blastfile);
  1366. tripal_add_job("Parse blast: $fname",'tripal_analysis_blast',
  1367. 'tripal_analysis_blast_parseXMLFile', $job_args, $user->uid);
  1368. } else {
  1369. drupal_set_message("Can not open blast output file. Job not scheduled.");
  1370. }
  1371. }
  1372. // Create a title for the analysis node using the unique keys so when the
  1373. // node is saved, it will have a title
  1374. $record = new stdClass();
  1375. // If the analysis has a name, use it as the node title. If not, construct
  1376. // the title using program, programversion, and sourcename
  1377. if ($node->analysisname) {
  1378. $record->title = $node->analysisname;
  1379. } else {
  1380. //Construct node title as "program (version)
  1381. $record->title = "$node->program ($node->programversion)";
  1382. }
  1383. $record->nid = $node->nid;
  1384. drupal_write_record('node',$record,'nid');
  1385. drupal_write_record('node_revisions',$record,'nid');
  1386. }
  1387. }
  1388. /*******************************************************************************
  1389. * When a node is requested by the user this function is called to allow us
  1390. * to add auxiliary data to the node object.
  1391. */
  1392. function chado_analysis_blast_load($node){
  1393. // get the analysis_id for this node:
  1394. $sql = "SELECT analysis_id FROM {chado_analysis} WHERE vid = %d";
  1395. $ana_node = db_fetch_object(db_query($sql, $node->vid));
  1396. $additions = new stdClass();
  1397. if ($ana_node) {
  1398. // get analysis information
  1399. $sql = "SELECT Analysis_id, name AS analysisname, description, program, ".
  1400. " programversion, algorithm, sourcename, sourceversion, ".
  1401. " sourceuri, timeexecuted ".
  1402. "FROM {Analysis} ".
  1403. "WHERE Analysis_id = $ana_node->analysis_id";
  1404. $previous_db = tripal_db_set_active('chado'); // use chado database
  1405. $additions = db_fetch_object(db_query($sql));
  1406. // get number of features assc with this analysis
  1407. $sql = "SELECT count(feature_id) as featurecount ".
  1408. "FROM {Analysisfeature} ".
  1409. "WHERE Analysis_id = %d";
  1410. $additions->featurecount = db_result(db_query($sql, $ana_node->analysis_id));
  1411. // get cvterm_id for 'analysis_blast_settings'
  1412. $sql = "SELECT CVT.cvterm_id FROM {cvterm} CVT ".
  1413. "INNER JOIN cv ON cv.cv_id = CVT.cv_id ".
  1414. "WHERE CVT.name = 'analysis_blast_settings' ".
  1415. "AND CV.name = 'tripal'";
  1416. $type_id = db_result(db_query($sql));
  1417. // get analysisprop information
  1418. $sql = "SELECT value FROM {analysisprop} ".
  1419. "WHERE analysis_id = %d ".
  1420. "AND type_id = %d";
  1421. $analysisprop = db_result(db_query($sql, $ana_node->analysis_id, $type_id));
  1422. $prop_values = explode ("|", $analysisprop, 1);
  1423. $additions->blastdb = $prop_values[0];
  1424. $additions->blastfile = $prop_values[1];
  1425. $additions->blastparameters = $prop_values[2];
  1426. tripal_db_set_active($previous_db); // now use drupal database
  1427. }
  1428. // If the analysis has a name, use it as the node title. If not, construct
  1429. // the title using program programversion, and sourcename
  1430. if ($additions->analysisname) {
  1431. $additions->title = $additions->analysisname;
  1432. } else {
  1433. // Construct node title as "program version (source)
  1434. $additions->title = "$additions->program ($additions->programversion)";
  1435. }
  1436. return $additions;
  1437. }
  1438. /*******************************************************************************
  1439. * This function customizes the view of the chado_analysis node. It allows
  1440. * us to generate the markup.
  1441. */
  1442. function chado_analysis_blast_view ($node, $teaser = FALSE, $page = FALSE) {
  1443. // use drupal's default node view:
  1444. //dprint_r($node);
  1445. if (!$teaser) {
  1446. $node = node_prepare($node, $teaser);
  1447. // When previewing a node submitting form, it shows 'Array' instead of
  1448. // correct date format. We need to format the date here
  1449. $time = $node->timeexecuted;
  1450. if(is_array($time)){
  1451. $month = $time['month'];
  1452. $day = $time['day'];
  1453. $year = $time['year'];
  1454. $timestamp = $year.'-'.$month.'-'.$day;
  1455. $node->timeexecuted = $timestamp;
  1456. }
  1457. // When viewing a node, we need to reformat the analysisprop since we
  1458. // separate each value with a bar |
  1459. if (preg_match("/.*\|.*\|.*/",$node->blastdb)) {
  1460. $prop_values = explode("|", $node->blastdb);
  1461. $node->blastdb = $prop_values[0];
  1462. $node->blastfile = $prop_values[1];
  1463. $node->blastparameters = $prop_values[2];
  1464. }
  1465. }
  1466. return $node;
  1467. }
  1468. /*******************************************************************************
  1469. * Set the permission types that the chado module uses. Essentially we
  1470. * want permissionis that protect creation, editing and deleting of chado
  1471. * data objects
  1472. */
  1473. function tripal_analysis_blast_perm(){
  1474. return array(
  1475. 'access chado_analysis_blast content',
  1476. 'create chado_analysis_blast content',
  1477. 'delete chado_analysis_blast content',
  1478. 'edit chado_analysis_blast content',
  1479. );
  1480. }
  1481. /*******************************************************************************
  1482. * The following function proves access control for users trying to
  1483. * perform actions on data managed by this module
  1484. */
  1485. function chado_analysis_blast_access($op, $node, $account){
  1486. if ($op == 'create') {
  1487. return user_access('create chado_analysis_blast content', $account);
  1488. }
  1489. if ($op == 'update') {
  1490. if (user_access('edit chado_analysis_blast content', $account)) {
  1491. return TRUE;
  1492. }
  1493. }
  1494. if ($op == 'delete') {
  1495. if (user_access('delete chado_analysis_blast content', $account)) {
  1496. return TRUE;
  1497. }
  1498. }
  1499. if ($op == 'view') {
  1500. if (user_access('access chado_analysis_blast content', $account)) {
  1501. return TRUE;
  1502. }
  1503. }
  1504. return FALSE;
  1505. }