blast_ui.blastp.inc 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969
  1. <?php
  2. /**
  3. * @file
  4. * Contains all functions for the Protein BLAST
  5. */
  6. /**
  7. * Protein BLAST Submission Form
  8. *
  9. * @see blast_protein_form_validate()
  10. * @see blast_protein_form_submit()
  11. */
  12. function blast_protein_form($form, &$form_state) {
  13. // CSS support to the form
  14. $form['#attached']['css'] = array(
  15. drupal_get_path('module', 'blast_ui') . '/css/form.css',
  16. );
  17. // PROTEIN QUERY
  18. //.........................
  19. $form['query'] = array(
  20. '#type' => 'fieldset',
  21. '#title' => t('Enter Query Sequence'),
  22. '#description' => t('Enter one or more queries in the top text box or use the browse button to upload a file from your local disk. The file may contain a single sequence or a list of sequences. In both cases, the data must be in FASTA format. <a href="http://www.ncbi.nlm.nih.gov/BLAST/blastcgihelp.shtml" target="_blank">More information..</a> '),
  23. '#collapsible' => TRUE,
  24. '#collapsed' => FALSE,
  25. '#prefix' => '<div class="two-col">',
  26. '#suffix' => '</div>',
  27. );
  28. $form['query']['example_sequence'] = array(
  29. '#type' => 'button',
  30. '#button_type'=> 'button',
  31. '#limit_validation_errors' => array(),
  32. '#value' => t('Example Sequence'),
  33. '#prefix' => '<div class="center">',
  34. '#suffix' => '</div>',
  35. '#validate' => array(),
  36. '#ajax' => array(
  37. 'callback' => 'ajax_nucleotide_text_area_callback',
  38. 'wrapper' => 'fasta_seq',
  39. 'method' => 'replace',
  40. 'effect' => 'fade',
  41. ),
  42. '#attributes' => array('onclick' => 'return false;'),
  43. );
  44. $form['query']['FASTA'] = array(
  45. '#type' => 'textarea',
  46. '#title' => t('Enter FASTA sequence(s)'),
  47. '#description'=>t('Enter query sequence(s) in the text area.'),
  48. '#prefix' => '<div id="fasta_seq">',
  49. '#suffix' => '</div>',
  50. );
  51. // Upload a file as an alternative to enter a query sequence
  52. $form['#attributes']['enctype'] = 'multipart/form-data';
  53. $form['query']['UPLOAD'] = array(
  54. '#title' => 'Or upload your own query FASTA: ',
  55. '#type' => 'managed_file',
  56. '#description' => t('The file should be a plain-text FASTA
  57. (.fasta, .fna, .fa) file. In other words, it cannot have formatting as is the
  58. case with MS Word (.doc, .docx) or Rich Text Format (.rtf). It cannot be greater
  59. than %max_size in size. <strong>Don\'t forget to press the Upload button before
  60. attempting to submit your BLAST.</strong>',
  61. array(
  62. '%max_size' => round(file_upload_max_size() / 1024 / 1024,1) . 'MB'
  63. )
  64. ),
  65. '#upload_validators' => array(
  66. 'file_validate_extensions' => array('fasta fna fa'),
  67. 'file_validate_size' => array(file_upload_max_size()),
  68. ),
  69. );
  70. $form['query']['example_sequence'] = array(
  71. '#type' => 'button',
  72. '#button_type'=> 'button',
  73. '#limit_validation_errors' => array(),
  74. '#value' => t('Example Sequence'),
  75. '#prefix' => '<div class="center">',
  76. '#suffix' => '</div>',
  77. '#validate' => array(),
  78. '#ajax' => array(
  79. 'callback' => 'ajax_protein_text_area_callback',
  80. 'wrapper' => 'fasta_seq',
  81. 'method' => 'replace',
  82. 'effect' => 'fade',
  83. ),
  84. '#attributes' => array('onclick' => 'return false;'),
  85. );
  86. // BLAST DATABASE
  87. //.........................
  88. $form['DB'] = array(
  89. '#type' => 'fieldset',
  90. '#title' => t('Choose Search Set'),
  91. '#description' => t('Choose from one of the protein BLAST databases listed below. You can also use the browse button to upload a file from your local disk. The file may contain a single sequence or a list of sequences. '),
  92. '#collapsible' => TRUE,
  93. '#collapsed' => FALSE,
  94. );
  95. $options = get_blast_database_options('p');
  96. $form['DB']['SELECT_DB'] = array(
  97. '#type' => 'select',
  98. '#title' => t('Protein BLAST Databases:'),
  99. '#options' => $options,
  100. '#default_value' => t('Select a database'),
  101. );
  102. // Upload a file as an alternative to enter a query sequence
  103. $form['#attributes']['enctype'] = 'multipart/form-data';
  104. $form['DB']['DBUPLOAD'] = array(
  105. '#title' => 'Or upload your own dataset: ',
  106. '#type' => 'managed_file',
  107. '#description' => t('The file should be a plain-text FASTA
  108. (.fasta, .fna, .fa) file. In other words, it cannot have formatting as is the
  109. case with MS Word (.doc, .docx) or Rich Text Format (.rtf). It cannot be greater
  110. than %max_size in size. <strong>Don\'t forget to press the Upload button before
  111. attempting to submit your BLAST.</strong>',
  112. array(
  113. '%max_size' => round(file_upload_max_size() / 1024 / 1024,1) . 'MB'
  114. )
  115. ),
  116. '#upload_validators' => array(
  117. 'file_validate_extensions' => array('fasta fna fa'),
  118. 'file_validate_size' => array(file_upload_max_size()),
  119. ),
  120. );
  121. // ALGORITHM PARAMETERS
  122. //.........................
  123. $form['ALG'] = array(
  124. '#type' => 'fieldset',
  125. '#title' => t('Algorithm parameters'),
  126. '#collapsible' => TRUE,
  127. '#collapsed' => TRUE,
  128. );
  129. //General parameters
  130. $form['ALG']['GParam'] = array(
  131. '#type' => 'fieldset',
  132. '#title' => t('General parameters'),
  133. '#collapsible' => FALSE,
  134. );
  135. $form['ALG']['GParam']['maxTarget'] = array(
  136. '#type' => 'select',
  137. '#title' => t('Max target sequences:'),
  138. '#options' => array(
  139. 0 => t('10'),
  140. 1 => t('50'),
  141. 2 => t('100'),
  142. 3 => t('250'),
  143. 4 => t('500'),
  144. 5 => t('1000'),
  145. 6 => t('5000'),
  146. 7 => t('10000'),
  147. 8 => t('20000'),
  148. ),
  149. '#default_value' => 2,
  150. '#description' => t('Select the maximum number of aligned sequences to display'),
  151. );
  152. $form['ALG']['GParam']['shortQueries'] = array(
  153. '#type' => 'checkbox',
  154. '#title' => t('Automatically adjust parameters for short input sequences'),
  155. '#default_value' => TRUE,
  156. );
  157. $form['ALG']['GParam']['eVal'] = array(
  158. '#type' => 'textfield',
  159. '#title' => t('e-value(Expect threshold)'),
  160. '#default_value' => 10,
  161. '#size' => 12,
  162. '#maxlength' => 20,
  163. '#description' => t('Expected number of chance matches in a random model.'),
  164. );
  165. $form['ALG']['GParam']['wordSize'] = array(
  166. '#type' => 'select',
  167. '#title' => t('Word size:'),
  168. '#options' => array(
  169. 0 => t('2'),
  170. 1 => t('3'),
  171. ),
  172. '#default_value' => 1,
  173. '#description' => t('The length of the seed that initiates an alignment'),
  174. );
  175. $form['ALG']['GParam']['qRange'] = array(
  176. '#type' => 'textfield',
  177. '#title' => t('Max matches in a query range'),
  178. '#default_value' => 0,
  179. '#size' => 12,
  180. '#maxlength' => 20,
  181. '#description' => t('Limit the number of matches to a query range. This option is useful if many strong matches to one part of a query may prevent BLAST from presenting weaker matches to another part of the query.'),
  182. );
  183. // Scoring parameters
  184. $form['ALG']['SParam'] = array(
  185. '#type' => 'fieldset',
  186. '#title' => t('Scoring parameters'),
  187. '#collapsible' => FALSE,
  188. );
  189. $options_first = _ajax_example_get_first_dropdown_options();
  190. $selected = isset($form_state['values']['MATRIX'] ) ? $form_state['values']['MATRIX'] : key($options_first);
  191. $form['ALG']['SParam']['MATRIX'] = array(
  192. '#type' => 'select',
  193. '#title' => 'Matrix',
  194. '#options' => $options_first,
  195. '#default_value' => $selected,
  196. '#description' => t('Assigns a score for aligning pairs of residues, and determines overall alignment score..'),
  197. '#ajax' => array(
  198. 'callback' => 'ajax_example_dependent_dropdown_callback',
  199. 'wrapper' => 'dropdown-second-replace',
  200. ),
  201. );
  202. $form['ALG']['SParam']['gapCost'] = array(
  203. '#type' => 'select',
  204. '#title' => t('Gap Costs:'),
  205. '#prefix' => '<div id="dropdown-second-replace">',
  206. '#suffix' => '</div>',
  207. '#options' => _ajax_example_get_second_dropdown_options($selected),
  208. '#default_value' => 2,
  209. '#description' => t('Cost to create and extend a gap in an alignment.'),
  210. );
  211. $form['ALG']['SParam']['M&MScores'] = array(
  212. '#type' => 'select',
  213. '#title' => t('Match/Mismatch Scores:'),
  214. '#options' => array(
  215. 0 => t('No adjustment'),
  216. 1 => t('Composition-based statistics'),
  217. 2 => t('Conditional compositional score matrix adjustment'),
  218. 3 => t('Universal composition score matrix adjustment '),
  219. ),
  220. '#default_value' => 2,
  221. '#description' => t('Matrix adjustment method to compensate for amino acid composition of sequences'),
  222. );
  223. //Submit
  224. $form['submit'] = array(
  225. '#type' => 'submit',
  226. '#default_value' => ' BLAST ',
  227. );
  228. return $form;
  229. }
  230. /**
  231. * Form validation handler for blast_protein_form().
  232. *
  233. * @see blast_protein_form_validate()
  234. */
  235. function blast_protein_form_validate($form, &$form_state) {
  236. // Validate Query
  237. //----------------
  238. // @todo: We are currently not validating uploaded files are valid FASTA.
  239. // First check to see if we have an upload & if so then validate it.
  240. $file = file_load($form_state['values']['UPLOAD']);
  241. // If the $file is populated then this is a newly uploaded, temporary file.
  242. if (is_object($file)) {
  243. $form_state['qFlag'] = 'upQuery';
  244. $form_state['upQuery_path'] = drupal_realpath($file->uri);
  245. }
  246. // Otherwise there was no file uploaded.
  247. // Check if there was a query sequence entered in the texfield.
  248. elseif (!empty($form_state['input']['FASTA'])) {
  249. // Check to ensure that the query sequence entered is valid FASTA.
  250. if (validateFasta($form_state['input']['FASTA'])){
  251. form_set_error('query', t('No query sequence given. Only raw sequence or
  252. sequence of type FASTA can be read. Enter sequence in the box provided or
  253. upload a plain text file.'));
  254. }
  255. else {
  256. $form_state['qFlag'] = 'seqQuery';
  257. }
  258. }
  259. // Otherwise they didn't enter a query!!
  260. else {
  261. form_set_error('pBLAST', t('You must either enter a FASTA sequence in the
  262. text field or upload one of your own.'));
  263. }
  264. // Validate Database
  265. //-------------------
  266. // @todo: We are currently not validating uploaded files are valid FASTA.
  267. // First check to see if we have an upload & if so then validate it.
  268. $file = file_load($form_state['values']['DBUPLOAD']);
  269. // If the $file is populated then this is a newly uploaded, temporary file.
  270. if (is_object($file)) {
  271. $form_state['dbFlag'] = 'upDB';
  272. $form_state['upDB_path'] = drupal_realpath($file->uri);
  273. }
  274. // Otherwise there was no file uploaded
  275. // Check if there was a database choosen from the list instead
  276. elseif (!empty($form_state['values']['SELECT_DB'])) {
  277. $form_state['dbFlag'] = 'blastdb';
  278. }
  279. // Otherwise they didn't select a database!!
  280. else {
  281. form_set_error('DB', t('No database selected. Either choose a database from
  282. the list or upload one of your own.'));
  283. }
  284. }
  285. /**
  286. * Form submition handler for blast_protein_form().
  287. *
  288. * @see blast_protein_form_submit()
  289. */
  290. function blast_protein_form_submit($form, &$form_state) {
  291. $error = FALSE;
  292. $eVal = $form_state['values']['eVal'];
  293. $trgtKey = $form_state['values']['maxTarget'];
  294. $numAlign = $form['ALG']['GParam']['maxTarget']['#options'][$trgtKey];
  295. $wsKey = $form_state['values']['wordSize'];
  296. $wordSize = $form['ALG']['GParam']['wordSize']['#options'][$wsKey];
  297. // Expand Gap Cost key into open and extend penalties
  298. $gapKey = $form_state['values']['MATRIX'];
  299. switch ($gapKey) {
  300. case 0:
  301. $matrix ="PAM30";
  302. $gapKey = $form_state['values']['gapCost'];
  303. switch ($gapKey) {
  304. case 0:
  305. $gapOpen = 7;
  306. $gapExtend = 2;
  307. break;
  308. case 1:
  309. $gapOpen = 6;
  310. $gapExtend = 2;
  311. break;
  312. case 2:
  313. $gapOpen = 5;
  314. $gapExtend = 2;
  315. break;
  316. case 3:
  317. $gapOpen = 10;
  318. $gapExtend = 1;
  319. break;
  320. case 4:
  321. $gapOpen = 9;
  322. $gapExtend = 1;
  323. break;
  324. case 5:
  325. $gapOpen = 8;
  326. $gapExtend = 1;
  327. break;
  328. }
  329. break;
  330. case 1:
  331. $matrix ="PAM70";
  332. $gapKey = $form_state['values']['gapCost'];
  333. switch ($gapKey) {
  334. case 0:
  335. $gapOpen = 8;
  336. $gapExtend = 2;
  337. break;
  338. case 1:
  339. $gapOpen = 7;
  340. $gapExtend = 2;
  341. break;
  342. case 2:
  343. $gapOpen = 6;
  344. $gapExtend = 2;
  345. break;
  346. case 3:
  347. $gapOpen = 11;
  348. $gapExtend = 1;
  349. break;
  350. case 4:
  351. $gapOpen = 10;
  352. $gapExtend = 1;
  353. break;
  354. case 5:
  355. $gapOpen = 9;
  356. $gapExtend = 1;
  357. break;
  358. }
  359. break;
  360. case 2:
  361. $matrix ="PAM250";
  362. $gapKey = $form_state['values']['gapCost'];
  363. switch ($gapKey) {
  364. case 0:
  365. $gapOpen = 15;
  366. $gapExtend = 3;
  367. break;
  368. case 1:
  369. $gapOpen = 14;
  370. $gapExtend = 3;
  371. break;
  372. case 2:
  373. $gapOpen = 13;
  374. $gapExtend = 3;
  375. break;
  376. case 3:
  377. $gapOpen = 12;
  378. $gapExtend = 3;
  379. break;
  380. case 4:
  381. $gapOpen = 11;
  382. $gapExtend = 3;
  383. break;
  384. case 5:
  385. $gapOpen = 17;
  386. $gapExtend = 2;
  387. break;
  388. case 6:
  389. $gapOpen = 16;
  390. $gapExtend = 2;
  391. break;
  392. case 7:
  393. $gapOpen = 15;
  394. $gapExtend = 2;
  395. break;
  396. case 8:
  397. $gapOpen = 14;
  398. $gapExtend = 2;
  399. break;
  400. case 9:
  401. $gapOpen = 13;
  402. $gapExtend = 2;
  403. break;
  404. case 10:
  405. $gapOpen = 21;
  406. $gapExtend = 1;
  407. break;
  408. case 11:
  409. $gapOpen = 20;
  410. $gapExtend = 1;
  411. break;
  412. case 12:
  413. $gapOpen = 19;
  414. $gapExtend = 1;
  415. break;
  416. case 13:
  417. $gapOpen = 18;
  418. $gapExtend = 1;
  419. break;
  420. case 14:
  421. $gapOpen = 17;
  422. $gapExtend = 1;
  423. break;
  424. }
  425. break;
  426. case 3:
  427. $matrix ="BLOSUM80";
  428. $gapKey = $form_state['values']['gapCost'];
  429. switch ($gapKey) {
  430. case 0:
  431. $gapOpen = 8;
  432. $gapExtend = 2;
  433. break;
  434. case 1:
  435. $gapOpen = 7;
  436. $gapExtend = 2;
  437. break;
  438. case 2:
  439. $gapOpen = 6;
  440. $gapExtend = 2;
  441. break;
  442. case 3:
  443. $gapOpen = 11;
  444. $gapExtend = 1;
  445. break;
  446. case 4:
  447. $gapOpen = 10;
  448. $gapExtend = 1;
  449. break;
  450. case 5:
  451. $gapOpen = 9;
  452. $gapExtend = 1;
  453. break;
  454. }
  455. break;
  456. case 4:
  457. $matrix ="BLOSUM62";
  458. $gapKey = $form_state['values']['gapCost'];
  459. switch ($gapKey) {
  460. case 0:
  461. $gapOpen = 11;
  462. $gapExtend = 2;
  463. break;
  464. case 1:
  465. $gapOpen = 10;
  466. $gapExtend = 2;
  467. break;
  468. case 2:
  469. $gapOpen = 9;
  470. $gapExtend = 2;
  471. break;
  472. case 3:
  473. $gapOpen = 8;
  474. $gapExtend = 2;
  475. break;
  476. case 4:
  477. $gapOpen = 7;
  478. $gapExtend = 2;
  479. break;
  480. case 5:
  481. $gapOpen = 6;
  482. $gapExtend = 2;
  483. break;
  484. case 6:
  485. $gapOpen = 13;
  486. $gapExtend = 1;
  487. break;
  488. case 7:
  489. $gapOpen = 12;
  490. $gapExtend = 1;
  491. break;
  492. case 8:
  493. $gapOpen = 11;
  494. $gapExtend = 1;
  495. break;
  496. case 9:
  497. $gapOpen = 10;
  498. $gapExtend = 1;
  499. break;
  500. case 10:
  501. $gapOpen = 9;
  502. $gapExtend = 1;
  503. break;
  504. }
  505. break;
  506. case 5:
  507. $matrix ="BLOSUM45";
  508. $gapKey = $form_state['values']['gapCost'];
  509. switch ($gapKey) {
  510. case 0:
  511. $gapOpen = 13;
  512. $gapExtend = 3;
  513. break;
  514. case 1:
  515. $gapOpen = 12;
  516. $gapExtend = 3;
  517. break;
  518. case 2:
  519. $gapOpen = 11;
  520. $gapExtend = 3;
  521. break;
  522. case 3:
  523. $gapOpen = 10;
  524. $gapExtend = 3;
  525. break;
  526. case 4:
  527. $gapOpen = 15;
  528. $gapExtend = 2;
  529. break;
  530. case 5:
  531. $gapOpen = 14;
  532. $gapExtend = 2;
  533. break;
  534. case 6:
  535. $gapOpen = 13;
  536. $gapExtend = 2;
  537. break;
  538. case 7:
  539. $gapOpen = 12;
  540. $gapExtend = 2;
  541. break;
  542. case 8:
  543. $gapOpen = 19;
  544. $gapExtend = 1;
  545. break;
  546. case 9:
  547. $gapOpen = 18;
  548. $gapExtend = 1;
  549. break;
  550. case 10:
  551. $gapOpen = 17;
  552. $gapExtend = 1;
  553. break;
  554. case 11:
  555. $gapOpen = 16;
  556. $gapExtend = 1;
  557. break;
  558. }
  559. break;
  560. case 6:
  561. $matrix ="BLOSUM50";
  562. $gapKey = $form_state['values']['gapCost'];
  563. switch ($gapKey) {
  564. case 0:
  565. $gapOpen = 13;
  566. $gapExtend = 3;
  567. break;
  568. case 1:
  569. $gapOpen = 12;
  570. $gapExtend = 3;
  571. break;
  572. case 2:
  573. $gapOpen = 11;
  574. $gapExtend = 3;
  575. break;
  576. case 3:
  577. $gapOpen = 10;
  578. $gapExtend = 3;
  579. break;
  580. case 4:
  581. $gapOpen = 9;
  582. $gapExtend = 3;
  583. break;
  584. case 5:
  585. $gapOpen = 16;
  586. $gapExtend = 2;
  587. break;
  588. case 6:
  589. $gapOpen = 15;
  590. $gapExtend = 2;
  591. break;
  592. case 7:
  593. $gapOpen = 14;
  594. $gapExtend = 2;
  595. break;
  596. case 8:
  597. $gapOpen = 13;
  598. $gapExtend = 2;
  599. break;
  600. case 9:
  601. $gapOpen = 12;
  602. $gapExtend = 2;
  603. break;
  604. case 10:
  605. $gapOpen = 19;
  606. $gapExtend = 1;
  607. break;
  608. case 11:
  609. $gapOpen = 18;
  610. $gapExtend = 1;
  611. break;
  612. case 12:
  613. $gapOpen = 17;
  614. $gapExtend = 1;
  615. break;
  616. case 13:
  617. $gapOpen = 16;
  618. $gapExtend = 1;
  619. break;
  620. case 14:
  621. $gapOpen = 15;
  622. $gapExtend = 1;
  623. break;
  624. }
  625. break;
  626. case 7:
  627. $matrix ="BLOSUM90";
  628. $gapKey = $form_state['values']['gapCost'];
  629. switch ($gapKey) {
  630. case 0:
  631. $gapOpen = 9;
  632. $gapExtend = 2;
  633. break;
  634. case 1:
  635. $gapOpen = 8;
  636. $gapExtend = 2;
  637. break;
  638. case 2:
  639. $gapOpen = 7;
  640. $gapExtend = 2;
  641. break;
  642. case 3:
  643. $gapOpen = 6;
  644. $gapExtend = 2;
  645. break;
  646. case 4:
  647. $gapOpen = 11;
  648. $gapExtend = 1;
  649. break;
  650. case 5:
  651. $gapOpen = 10;
  652. $gapExtend = 1;
  653. break;
  654. case 6:
  655. $gapOpen = 9;
  656. $gapExtend = 1;
  657. break;
  658. }
  659. break;
  660. }
  661. // If the query was submitted via the texrfield then create a file containing it
  662. if ( isset($form_state['qFlag']) ) {
  663. if ( $form_state['qFlag'] == 'seqQuery' ) {
  664. $seq_content = $form_state['values']['FASTA'];
  665. $query = '/tmp/' . date('YMd_His') . '_query.fasta';
  666. file_put_contents ( $query , $seq_content);
  667. }
  668. elseif ( $form_state['qFlag'] == 'upQuery' ) {
  669. $query = $form_state['upQuery_path'];
  670. }
  671. }
  672. // If the BLAST database was uploaded then use it to run the BLAST
  673. if ($form_state['dbFlag'] == 'upDB') {
  674. // Since we only support using the -db flag (not -subject) we need to create a
  675. // blast database for the FASTA uploaded.
  676. // NOTE: We can't support subject because we need to generate the ASN.1+ format
  677. // to provide multiple download type options from the same BLAST
  678. $blastdb_with_path = $form_state['upDB_path'];
  679. $result = NULL;
  680. exec("makeblastdb -in $blastdb_with_path -dbtype prot -parse_seqids 2>&1", $result);
  681. // Check that the BLAST database was made correctly.
  682. $result = implode('<br />', $result);
  683. if (preg_match('/Error/', $result)) {
  684. drupal_set_message('Unable to generate a BLAST database from your uploaded
  685. FASTA sequence. Please check that your file is a valid FASTA file and that if
  686. your sequence headers include pipes (i.e.: | ) they adhere to '
  687. . l('NCBI standards.', 'http://www.ncbi.nlm.nih.gov/books/NBK21097/table/A632/?report=objectonly', array('attributes' => array('target' => '_blank'))),
  688. 'error'
  689. );
  690. $error = TRUE;
  691. }
  692. }
  693. // Otherwise, we are using one of the website provided BLAST databases so form the
  694. // BLAST command accordingly
  695. elseif ($form_state['dbFlag'] == 'blastdb') {
  696. $selected_db = $form_state['values']['SELECT_DB'];
  697. $blastdb_node = node_load($selected_db);
  698. $blastdb_with_path = $blastdb_node->db_path;
  699. }
  700. // Actually submit the BLAST Tripal Job
  701. // NOTE: Tripal jobs needs to be executed from the command-line before it will be run!!
  702. $blastdb_with_suffix = $blastdb_with_path . '.psq';
  703. if (is_readable($blastdb_with_suffix)) {
  704. global $user;
  705. $output_filestub = date('YMd_His');
  706. $job_args = array(
  707. 'program' => 'blastp',
  708. 'query' => $query,
  709. 'database' => $blastdb_with_path,
  710. 'output_filename' => $output_filestub,
  711. 'options' => array(
  712. 'evalue' => $eVal,
  713. 'word_size' => $wordSize,
  714. 'gapopen' => $gapOpen,
  715. 'gapextend' => $gapExtend,
  716. 'matrix' => $matrix
  717. )
  718. );
  719. $job_id = tripal_add_job("BLAST (blastp): $query",'blast_job','run_BLAST_tripal_job', $job_args, $user->uid);
  720. // Redirect to the BLAST results page
  721. drupal_goto("blast/report/$job_id");
  722. }
  723. // We check if $error is set to TRUE because if so then the error has already
  724. // been reported.
  725. elseif (!$error) {
  726. $dbfile_uploaded_msg = ($form_state['dbFlag'] == 'upDB') ? 'The BLAST database was submitted via user upload.' : 'Existing BLAST Database was chosen';
  727. tripal_report_error(
  728. 'blast_ui',
  729. TRIPAL_ERROR,
  730. "BLAST database %db unaccessible. $dbfile_uploaded_msg",
  731. array('%db' => $blastdb_with_path)
  732. );
  733. drupal_set_message('BLAST database unaccessible. Please contact the site administrator.','error');
  734. }
  735. }
  736. /**
  737. * FASTA validating parser
  738. *
  739. * @param $sequence
  740. * A string of characters to be validated. A sequence in FASTA format begins with a single-line description, followed by lines of sequence data.
  741. * The description line is distinguished from the sequence data by a greater-than (">") symbol in the first column.
  742. * The word following the ">" symbol is the identifier of the sequence, and the rest of the line is the description (both are optional).
  743. * There should be no space between the ">" and the first letter of the identifier. The sequence ends if another line starting with a ">" appears;
  744. * this indicates the start of another sequence.
  745. *
  746. * @return
  747. * Return a boolean. 1 if the sequence does not pass the format valifation stage and 0 otherwise.
  748. *
  749. */
  750. function validateFasta($sequence) {
  751. $fastaIdRegEx = '/^>.*(\\n|\\r)/';
  752. $fastaSeqRegEx = '/[^acgturykmswbdhvnxACGTURYKMSWBDHVNX\*\-\n\r]/';
  753. if ( preg_match($fastaSeqRegEx,$sequence) && !(preg_match($fastaIdRegEx,$sequence)) ) {
  754. $flag = 1;
  755. } else {
  756. $flag = 0;
  757. }
  758. return $flag;
  759. }
  760. /**
  761. * Fill the first dropdown list with appropriate options
  762. *
  763. * @return
  764. * An array consisting of matrices name for the first dropdown list
  765. */
  766. function _ajax_example_get_first_dropdown_options() {
  767. return drupal_map_assoc(array(
  768. t('PAM30'),
  769. t('PAM70'),
  770. t('PAM250'),
  771. t('BLOSUM80'),
  772. t('BLOSUM62'),
  773. t('BLOSUM45'),
  774. t('BLOSUM50'),
  775. t('BLOSUM90'),
  776. ));
  777. }
  778. /**
  779. * Fill the second dropdown list with appropriate options
  780. *
  781. * @return
  782. * An array containing open and extension gap values for the chosen matrix (to fill the second dropdown list)
  783. */
  784. function _ajax_example_get_second_dropdown_options($key = '') {
  785. $options = array(
  786. t('PAM30') => drupal_map_assoc(array(
  787. t('Existence: 7 Extension: 2'),
  788. t('Existence: 6 Extension: 2'),
  789. t('Existence: 5 Extension: 2'),
  790. t('Existence: 10 Extension: 1'),
  791. t('Existence: 9 Extension: 1'),
  792. t('Existence: 8 Extension: 1'),
  793. )),
  794. t('PAM70') => drupal_map_assoc(array(
  795. t('Existence: 8 Extension: 2'),
  796. t('Existence: 7 Extension: 2'),
  797. t('Existence: 6 Extension: 2'),
  798. t('Existence: 11 Extension: 1'),
  799. t('Existence: 10 Extension: 1'),
  800. t('Existence: 9 Extension: 1'),
  801. )),
  802. t('PAM250') => drupal_map_assoc(array(
  803. t('Existence: 15 Extension: 3'),
  804. t('Existence: 14 Extension: 3'),
  805. t('Existence: 13 Extension: 3'),
  806. t('Existence: 12 Extension: 3'),
  807. t('Existence: 11 Extension: 3'),
  808. t('Existence: 17 Extension: 2'),
  809. t('Existence: 16 Extension: 2'),
  810. t('Existence: 15 Extension: 2'),
  811. t('Existence: 14 Extension: 2'),
  812. t('Existence: 13 Extension: 2'),
  813. t('Existence: 21 Extension: 1'),
  814. t('Existence: 20 Extension: 1'),
  815. t('Existence: 19 Extension: 1'),
  816. t('Existence: 18 Extension: 1'),
  817. t('Existence: 17 Extension: 1'),
  818. )),
  819. t('BLOSUM80') => drupal_map_assoc(array(
  820. t('Existence: 8 Extension: 2'),
  821. t('Existence: 7 Extension: 2'),
  822. t('Existence: 6 Extension: 2'),
  823. t('Existence: 11 Extension: 1'),
  824. t('Existence: 10 Extension: 1'),
  825. t('Existence: 9 Extension: 1'),
  826. )),
  827. t('BLOSUM62') => drupal_map_assoc(array(
  828. t('Existence: 11 Extension: 2'),
  829. t('Existence: 10 Extension: 2'),
  830. t('Existence: 9 Extension: 2'),
  831. t('Existence: 8 Extension: 2'),
  832. t('Existence: 7 Extension: 2'),
  833. t('Existence: 6 Extension: 2'),
  834. t('Existence: 13 Extension: 1'),
  835. t('Existence: 12 Extension: 1'),
  836. t('Existence: 11 Extension: 1'),
  837. t('Existence: 10 Extension: 1'),
  838. t('Existence: 9 Extension: 1'),
  839. )),
  840. t('BLOSUM45') => drupal_map_assoc(array(
  841. t('Existence: 13 Extension: 3'),
  842. t('Existence: 12 Extension: 3'),
  843. t('Existence: 11 Extension: 3'),
  844. t('Existence: 10 Extension: 3'),
  845. t('Existence: 15 Extension: 2'),
  846. t('Existence: 14 Extension: 2'),
  847. t('Existence: 13 Extension: 2'),
  848. t('Existence: 12 Extension: 2'),
  849. t('Existence: 19 Extension: 1'),
  850. t('Existence: 18 Extension: 1'),
  851. t('Existence: 17 Extension: 1'),
  852. t('Existence: 16 Extension: 1'),
  853. )),
  854. t('BLOSUM50') => drupal_map_assoc(array(
  855. t('Existence: 13 Extension: 3'),
  856. t('Existence: 12 Extension: 3'),
  857. t('Existence: 11 Extension: 3'),
  858. t('Existence: 10 Extension: 3'),
  859. t('Existence: 9 Extension: 3'),
  860. t('Existence: 16 Extension: 2'),
  861. t('Existence: 15 Extension: 2'),
  862. t('Existence: 14 Extension: 2'),
  863. t('Existence: 13 Extension: 2'),
  864. t('Existence: 12 Extension: 2'),
  865. t('Existence: 19 Extension: 1'),
  866. t('Existence: 18 Extension: 1'),
  867. t('Existence: 17 Extension: 1'),
  868. t('Existence: 16 Extension: 1'),
  869. t('Existence: 15 Extension: 1'),
  870. )),
  871. t('BLOSUM90') => drupal_map_assoc(array(
  872. t('Existence: 9 Extension: 2'),
  873. t('Existence: 8 Extension: 2'),
  874. t('Existence: 7 Extension: 2'),
  875. t('Existence: 6 Extension: 2'),
  876. t('Existence: 11 Extension: 1'),
  877. t('Existence: 10 Extension: 1'),
  878. t('Existence: 9 Extension: 1'),
  879. )),
  880. );
  881. if (isset($options[$key])) {
  882. return $options[$key];
  883. } else {
  884. return array();
  885. }
  886. }
  887. /**
  888. * Respond to Ajax dropdown call
  889. */
  890. function ajax_example_dependent_dropdown_callback($form, $form_state) {
  891. return $form['ALG']['SParam']['gapCost'];
  892. }
  893. // call back function for example sequence
  894. function ajax_protein_text_area_callback($form, $form_state) {
  895. $element = $form['query']['FASTA']; // Get example Protein sequence
  896. $element['#value'] =
  897. '>gi|166477|gb|AAA96434.1| resveratrol synthase [Arachis hypogaea]
  898. MVSVSGIRKVQRAEGPATVLAIGTANPPNCIDQSTYADYYFRVTNSEHMTDLKKKFQRICERTQIKNRHM
  899. YLTEEILKENPNMCAYKAPSLDAREDMMIREVPRVGKEAATKAIKEWGQPMSKITHLIFCTTSGVALPGV
  900. DYELIVLLGLDPCVKRYMMYHQGCFAGGTVLRLAKDLAENNKDARVLIVCSENTAVTFRGPSETDMDSLV
  901. GQALFADGAAAIIIGSDPVPEVEKPIFELVSTDQKLVPGSHGAIGGLLREVGLTFYLNKSVPDIISQNIN
  902. DALNKAFDPLGISDYNSIFWIAHPGGRAILDQVEQKVNLKPEKMKATRDVLSNYGNMSSACVFFIMDLMR
  903. KRSLEEGLKTTGEGLDWGVLFGFGPGLTIETVVLRSVAI';
  904. return $element;
  905. }