Browse Source

Merge pull request #21 from LegumeFederation/safetybrake

Safetybrake
ekcannon 7 years ago
parent
commit
0a2893c38a

+ 4 - 3
api/blast_ui.api.inc

@@ -84,8 +84,8 @@ function get_blast_database_options($type) {
     }
   }
 
+  // Sort alphabetically
   asort($options);
-  $options[0] = 'Select a Dataset';
 
   return $options;
 }
@@ -185,7 +185,8 @@ function run_BLAST_tripal_job($program, $query, $database, $output_filestub, $op
   // Strip the extension off the BLAST target
   $database = preg_replace("/(.*)\.[pn]\w\w$/", '$1', $database);
 
-  // The Blast executeable.
+
+  // The BLAST executeable.
   $program = $blast_path . $program;
   if (!file_exists($program)) {
     tripal_report_error(
@@ -790,7 +791,7 @@ function convert_tsv2gff3($blast_tsv,$blast_gff){
       $hsp=0;
     }
   
-   // every line is a new hsp
+    // every line is a new hsp
     $hsp++;
   
     // determine query strand to use in match_part line, no need to store, just print

+ 32 - 5
includes/blast_ui.admin.inc

@@ -31,7 +31,7 @@ function blast_ui_admin_form($form, $form_state) {
 
    $form['general']['eVal']= array(
     '#type' => 'textfield',
-    '#title' => t('e-Value (Expected Threshold)'),
+    '#title' => t('Default e-Value (Expected Threshold)'),
     '#description' => t('Expected number of chance matches in a random model. This number should be give in a decimal format.'),
      '#default_value' => variable_get('eVal', 0.001),
     //'#default_value' => variable_get('blast_threads', 1),
@@ -39,13 +39,15 @@ function blast_ui_admin_form($form, $form_state) {
 
   $form['general']['qRange']= array(
     '#type' => 'textfield',
-    '#title' => t('Max matches in a query range'),
+    '#title' => t('Default max matches in a query range'),
     '#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.'),
     '#default_value' => variable_get('qRange', 0),
   );
 
   $form['file_upload'] = array(
     '#type' => 'fieldset',
+    '#collapsible' => true,
+    '#collapsed' => true,
     '#title' => 'Allow File Upload',
     '#description' => 'The following options allow you to control whether your users can
       upload files for the query or target respectively. The ability to upload files allows
@@ -71,6 +73,8 @@ function blast_ui_admin_form($form, $form_state) {
 
   $form['example_sequence'] = array(
     '#type' => 'fieldset',
+    '#collapsible' => true,
+    '#collapsed' => true,
     '#title' => 'Set Example Sequences',
     '#description' => 'There is the ability to show example sequences built-in to the various BLAST forms. Use the following fields to set these example sequences. This allows you to provide more relevant examples to your users.'
   );
@@ -106,7 +110,7 @@ CTGTTTTTAT TCAACATATT TAATCACATG GATGAATTTT TGAACTGTTA';
     '#type' => 'textarea',
     '#title' => 'Nucleotide Example',
     '#description' => t('Enter a complete nucleotide FASTA record including the header. More information: <a href="@fasta-format-url" target="_blank">FASTA format</a>.',
-      array('@fasta-format-url' => 'http://www.ncbi.nlm.nih.gov/BLAST/blastcgihelp.shtml')),
+      array('@fasta-format-url' => 'https://www.ncbi.nlm.nih.gov/BLAST/blastcgihelp.shtml')),
     '#default_value' => variable_get(
         'blast_ui_nucleotide_example_sequence',
         $nucleotide_default
@@ -124,13 +128,30 @@ KRSLEEGLKTTGEGLDWGVLFGFGPGLTIETVVLRSVAI';
     '#type' => 'textarea',
     '#title' => 'Protein Example',
     '#description' => t('Enter a complete protein FASTA record including the header. More information: <a href="@fasta-format-url" target="_blank">FASTA format</a>.',
-      array('@fasta-format-url' => 'http://www.ncbi.nlm.nih.gov/BLAST/blastcgihelp.shtml')),
+      array('@fasta-format-url' => 'https://www.ncbi.nlm.nih.gov/BLAST/blastcgihelp.shtml')),
     '#default_value' => variable_get(
         'blast_ui_protein_example_sequence',
         $protein_default
       )
   );
 
+  // PROTECTION
+  $form['protection'] = array(
+    '#type' => 'fieldset',
+    '#collapsible' => true,
+    '#collapsed' => true,
+    '#title' => 'Protect against large jobs',
+    '#description' => 'Depending on the size and nature of your target databases, you may wish to constrain use of this module.',
+  );
+
+  $form['protection']['max_results_displayed'] = array(
+    '#type' => 'textfield',
+    '#title' => 'Maximum number of results to show on report page',
+    '#description' => 'If there are more hits that this, the user is able to download but not visualize the results.',
+    '#default_value' => variable_get('blast_ui_max_results_displayed', 500)
+  );
+
+  // SUBMIT
   $form['submit'] = array(
     '#type' => 'submit',
     '#value' => 'Save Configuration'
@@ -143,6 +164,7 @@ KRSLEEGLKTTGEGLDWGVLFGFGPGLTIETVVLRSVAI';
  * Validate the Admin/Settings form.
  */
 function blast_ui_admin_form_validate($form, &$form_state) {
+  // Check path to BLAST executables
   $blast_path = $form_state['values']['blast_path'];
   $blast_path .= 'blastn';
   if(!empty($form_state['values']['blast_path'])) {
@@ -160,16 +182,21 @@ function blast_ui_admin_form_validate($form, &$form_state) {
  * Submit the Admin/settings form.
  */
 function blast_ui_admin_form_submit($form, $form_state) {
-
+  //General
   variable_set('blast_path', $form_state['values']['blast_path']);
   variable_set('blast_threads', $form_state['values']['blast_threads']);
 
   variable_set('eVal', $form_state['values']['eVal']);
   variable_set('qRange', $form_state['values']['qRange']);
 
+  // Uploads
   variable_set('blast_ui_allow_query_upload', $form_state['values']['query_upload']);
   variable_set('blast_ui_allow_target_upload', $form_state['values']['target_upload']);
 
+  // Example sequence
   variable_set('blast_ui_nucleotide_example_sequence', $form_state['values']['nucleotide_example']);
   variable_set('blast_ui_protein_example_sequence', $form_state['values']['protein_example']);
+  
+/**: added by safetybrake*/
+  variable_set('blast_ui_max_results_displayed', $form_state['values']['max_results_displayed']);
 }

+ 367 - 359
includes/blast_ui.form_advanced_options.inc

@@ -65,7 +65,7 @@ function blast_ui_blastn_advanced_options_form(&$form, $form_state) {
     '#default_value' => $defaults['evalue'],
     '#size' => 12,
     '#maxlength' => 20,
-    '#description' => t('Expected number of chance matches in a random model. This number should be give in a decimal format. <a href="http://www.ncbi.nlm.nih.gov/BLAST/blastcgihelp.shtml#expect" target="_blank">More Information</a> | <a href="https://www.youtube.com/watch?v=nO0wJgZRZJs" target="_blank">Expect value video tutorial</a>'),
+    '#description' => t('Expected number of chance matches in a random model. This number should be give in a decimal format. <a href="https://www.ncbi.nlm.nih.gov/BLAST/blastcgihelp.shtml#expect" target="_blank">More Information</a> | <a href="https://www.youtube.com/watch?v=nO0wJgZRZJs" target="_blank">Expect value video tutorial</a>'),
   );
 
   $form['ALG']['GParam']['wordSize'] = array(
@@ -105,7 +105,7 @@ function blast_ui_blastn_advanced_options_form(&$form, $form_state) {
    $form['ALG']['SParam']['gapCost'] = array(
     '#type' => 'select',
     '#title' => t('Gap Costs:'),
-    '#options' => _get_gap('blastn'),
+    '#options' => _get_gap_options('blastn'),
     '#default_value' => $defaults['gap'],
     '#description' => t('Cost to create and extend a gap in an alignment. Linear costs are available only with megablast and are determined by the match/mismatch scores.'),
   );
@@ -219,7 +219,7 @@ function blast_ui_blastx_advanced_options_form(&$form, $form_state) {
     '#default_value' => $defaults['evalue'],
     '#size' => 12,
     '#maxlength' => 20,
-    '#description' => t('Expected number of chance matches in a random model. This number should be give in a decimal format. <a href="http://www.ncbi.nlm.nih.gov/BLAST/blastcgihelp.shtml#expect" target="_blank">More Information</a> | <a href="https://www.youtube.com/watch?v=nO0wJgZRZJs" target="_blank">Expect value vedio tutorial</a>'),
+    '#description' => t('Expected number of chance matches in a random model. This number should be give in a decimal format. <a href="https://www.ncbi.nlm.nih.gov/BLAST/blastcgihelp.shtml#expect" target="_blank">More Information</a> | <a href="https://www.youtube.com/watch?v=nO0wJgZRZJs" target="_blank">Expect value vedio tutorial</a>'),
   );
 
 /*eksc- need to learn how this is implemented for blastx
@@ -483,6 +483,7 @@ function blast_ui_blastp_advanced_options_form_submit($form, $form_state) {
 
   $eVal = $form_state['values']['eVal'];
 
+
   $trgtKey = $form_state['values']['maxTarget'];
   $numAlign = $form['ALG']['GParam']['maxTarget']['#options'][$trgtKey];
 
@@ -493,360 +494,8 @@ function blast_ui_blastp_advanced_options_form_submit($form, $form_state) {
 
   // Expand Gap Cost key into open and extend penalties
   $matrix = $form_state['values']['Matrix'];
-  switch ($matrix) {
-   case 'PAM30':
-     $gapKey = $form_state['values']['gapCost'];
-     switch ($gapKey) {
-      case 0:
-         $gapOpen = 7;
-         $gapExtend = 2;
-         break;
-      case 1:
-         $gapOpen = 6;
-         $gapExtend = 2;
-         break;
-      case 2:
-         $gapOpen = 5;
-         $gapExtend = 2;
-         break;
-      case 3:
-         $gapOpen = 10;
-         $gapExtend = 1;
-         break;
-      case 4:
-         $gapOpen = 9;
-         $gapExtend = 1;
-         break;
-      case 5:
-         $gapOpen = 8;
-         $gapExtend = 1;
-         break;
-     }
-     break;
-   case 'PAM70':
-     $gapKey = $form_state['values']['gapCost'];
-     switch ($gapKey) {
-      case 0:
-         $gapOpen = 8;
-         $gapExtend = 2;
-         break;
-      case 1:
-         $gapOpen = 7;
-         $gapExtend = 2;
-         break;
-      case 2:
-         $gapOpen = 6;
-         $gapExtend = 2;
-         break;
-      case 3:
-         $gapOpen = 11;
-         $gapExtend = 1;
-         break;
-      case 4:
-         $gapOpen = 10;
-         $gapExtend = 1;
-         break;
-      case 5:
-         $gapOpen = 9;
-         $gapExtend = 1;
-         break;
-     }
-     break;
-   case 'PAM250':
-     $gapKey = $form_state['values']['gapCost'];
-     switch ($gapKey) {
-      case 0:
-         $gapOpen = 15;
-         $gapExtend = 3;
-         break;
-      case 1:
-         $gapOpen = 14;
-         $gapExtend = 3;
-         break;
-      case 2:
-         $gapOpen = 13;
-         $gapExtend = 3;
-         break;
-      case 3:
-         $gapOpen = 12;
-         $gapExtend = 3;
-         break;
-      case 4:
-         $gapOpen = 11;
-         $gapExtend = 3;
-         break;
-      case 5:
-         $gapOpen = 17;
-         $gapExtend = 2;
-         break;
-      case 6:
-         $gapOpen = 16;
-         $gapExtend = 2;
-         break;
-      case 7:
-         $gapOpen = 15;
-         $gapExtend = 2;
-         break;
-      case 8:
-         $gapOpen = 14;
-         $gapExtend = 2;
-         break;
-      case 9:
-         $gapOpen = 13;
-         $gapExtend = 2;
-         break;
-      case 10:
-         $gapOpen = 21;
-         $gapExtend = 1;
-         break;
-      case 11:
-         $gapOpen = 20;
-         $gapExtend = 1;
-         break;
-      case 12:
-         $gapOpen = 19;
-         $gapExtend = 1;
-         break;
-      case 13:
-         $gapOpen = 18;
-         $gapExtend = 1;
-         break;
-      case 14:
-         $gapOpen = 17;
-         $gapExtend = 1;
-         break;
-     }
-     break;
-   case 'BLOSUM80':
-     $gapKey = $form_state['values']['gapCost'];
-     switch ($gapKey) {
-      case 0:
-         $gapOpen = 8;
-         $gapExtend = 2;
-         break;
-      case 1:
-         $gapOpen = 7;
-         $gapExtend = 2;
-         break;
-      case 2:
-         $gapOpen = 6;
-         $gapExtend = 2;
-         break;
-      case 3:
-         $gapOpen = 11;
-         $gapExtend = 1;
-         break;
-      case 4:
-         $gapOpen = 10;
-         $gapExtend = 1;
-         break;
-      case 5:
-         $gapOpen = 9;
-         $gapExtend = 1;
-         break;
-     }
-      break;
-   case 'BLOSUM62':
-     $gapKey = $form_state['values']['gapCost'];
-     switch ($gapKey) {
-      case 0:
-         $gapOpen = 11;
-         $gapExtend = 2;
-         break;
-      case 1:
-         $gapOpen = 10;
-         $gapExtend = 2;
-         break;
-      case 2:
-         $gapOpen = 9;
-         $gapExtend = 2;
-         break;
-      case 3:
-         $gapOpen = 8;
-         $gapExtend = 2;
-         break;
-      case 4:
-         $gapOpen = 7;
-         $gapExtend = 2;
-         break;
-      case 5:
-         $gapOpen = 6;
-         $gapExtend = 2;
-         break;
-      case 6:
-         $gapOpen = 13;
-         $gapExtend = 1;
-         break;
-      case 7:
-         $gapOpen = 12;
-         $gapExtend = 1;
-         break;
-      case 8:
-         $gapOpen = 11;
-         $gapExtend = 1;
-         break;
-      case 9:
-         $gapOpen = 10;
-         $gapExtend = 1;
-         break;
-      case 10:
-         $gapOpen = 9;
-         $gapExtend = 1;
-         break;
-     }
-      break;
-   case 'BLOSUM45':
-     $gapKey = $form_state['values']['gapCost'];
-     switch ($gapKey) {
-      case 0:
-         $gapOpen = 13;
-         $gapExtend = 3;
-         break;
-      case 1:
-         $gapOpen = 12;
-         $gapExtend = 3;
-         break;
-      case 2:
-         $gapOpen = 11;
-         $gapExtend = 3;
-         break;
-      case 3:
-         $gapOpen = 10;
-         $gapExtend = 3;
-         break;
-      case 4:
-         $gapOpen = 15;
-         $gapExtend = 2;
-         break;
-      case 5:
-         $gapOpen = 14;
-         $gapExtend = 2;
-         break;
-      case 6:
-         $gapOpen = 13;
-         $gapExtend = 2;
-         break;
-      case 7:
-         $gapOpen = 12;
-         $gapExtend = 2;
-         break;
-      case 8:
-         $gapOpen = 19;
-         $gapExtend = 1;
-         break;
-      case 9:
-         $gapOpen = 18;
-         $gapExtend = 1;
-         break;
-      case 10:
-         $gapOpen = 17;
-         $gapExtend = 1;
-         break;
-      case 11:
-         $gapOpen = 16;
-         $gapExtend = 1;
-         break;
-     }
-     break;
-   case 'BLOSUM50':
-     $gapKey = $form_state['values']['gapCost'];
-     switch ($gapKey) {
-      case 0:
-         $gapOpen = 13;
-         $gapExtend = 3;
-         break;
-      case 1:
-         $gapOpen = 12;
-         $gapExtend = 3;
-         break;
-      case 2:
-         $gapOpen = 11;
-         $gapExtend = 3;
-         break;
-      case 3:
-         $gapOpen = 10;
-         $gapExtend = 3;
-         break;
-      case 4:
-         $gapOpen = 9;
-         $gapExtend = 3;
-         break;
-      case 5:
-         $gapOpen = 16;
-         $gapExtend = 2;
-         break;
-      case 6:
-         $gapOpen = 15;
-         $gapExtend = 2;
-         break;
-      case 7:
-         $gapOpen = 14;
-         $gapExtend = 2;
-         break;
-      case 8:
-         $gapOpen = 13;
-         $gapExtend = 2;
-         break;
-      case 9:
-         $gapOpen = 12;
-         $gapExtend = 2;
-         break;
-      case 10:
-         $gapOpen = 19;
-         $gapExtend = 1;
-         break;
-      case 11:
-         $gapOpen = 18;
-         $gapExtend = 1;
-         break;
-      case 12:
-         $gapOpen = 17;
-         $gapExtend = 1;
-         break;
-      case 13:
-         $gapOpen = 16;
-         $gapExtend = 1;
-         break;
-      case 14:
-         $gapOpen = 15;
-         $gapExtend = 1;
-         break;
-     }
-     break;
-   case 'BLOSUM90':
-     $gapKey = $form_state['values']['gapCost'];
-     switch ($gapKey) {
-      case 0:
-         $gapOpen = 9;
-         $gapExtend = 2;
-         break;
-      case 1:
-         $gapOpen = 8;
-         $gapExtend = 2;
-         break;
-      case 2:
-         $gapOpen = 7;
-         $gapExtend = 2;
-         break;
-      case 3:
-         $gapOpen = 6;
-         $gapExtend = 2;
-         break;
-      case 4:
-         $gapOpen = 11;
-         $gapExtend = 1;
-         break;
-      case 5:
-         $gapOpen = 10;
-         $gapExtend = 1;
-         break;
-      case 6:
-         $gapOpen = 9;
-         $gapExtend = 1;
-         break;
-     }
-     break;
-  }
+  $gapKey = $form_state['values']['gapCost'];
+  $gap    = getGap($matrix, $gapKey);
 
 //eksc- need to implement query range limit
 //  q_range
@@ -1049,7 +698,7 @@ function blast_ui_tblastn_advanced_options_form(&$form, $form_state) {
     '#default_value' => $defaults['evalue'],
     '#size' => 12,
     '#maxlength' => 20,
-    '#description' => t('Expected number of chance matches in a random model. This number should be give in a decimal format. <a href="http://www.ncbi.nlm.nih.gov/BLAST/blastcgihelp.shtml#expect" target="_blank">More Information</a> | <a href="https://www.youtube.com/watch?v=nO0wJgZRZJs" target="_blank">Expect value vedio tutorial</a>'),
+    '#description' => t('Expected number of chance matches in a random model. This number should be give in a decimal format. <a href="https://www.ncbi.nlm.nih.gov/BLAST/blastcgihelp.shtml#expect" target="_blank">More Information</a> | <a href="https://www.youtube.com/watch?v=nO0wJgZRZJs" target="_blank">Expect value vedio tutorial</a>'),
   );
 
 /*eksc- need to learn how this is implemented for tblastn
@@ -1297,10 +946,369 @@ function _get_match_mismatch($which) {
   }//switch
 }
 
+/** 
+ * Get gap values based on matrix and selected gap "key"
+ */
+function getGap($matrix, $gapkey) {
+   switch ($matrix) {
+      case 'PAM30':
+         switch ($gapKey) {
+            case 0:
+               $gapOpen   = 7;
+               $gapExtend = 2;
+               break;
+            case 1:
+               $gapOpen   = 6;
+               $gapExtend = 2;
+               break;
+            case 2:
+               $gapOpen   = 5;
+               $gapExtend = 2;
+               break;
+            case 3:
+               $gapOpen   = 10;
+               $gapExtend = 1;
+               break;
+            case 4:
+               $gapOpen   = 9;
+               $gapExtend = 1;
+               break;
+            case 5:
+               $gapOpen   = 8;
+               $gapExtend = 1;
+               break;
+         }
+         break;
+      case 'PAM70':
+         switch ($gapKey) {
+            case 0:
+               $gapOpen   = 8;
+               $gapExtend = 2;
+               break;
+            case 1:
+               $gapOpen   = 7;
+               $gapExtend = 2;
+               break;
+            case 2:
+               $gapOpen   = 6;
+               $gapExtend = 2;
+               break;
+            case 3:
+               $gapOpen   = 11;
+               $gapExtend = 1;
+               break;
+            case 4:
+               $gapOpen   = 10;
+               $gapExtend = 1;
+               break;
+            case 5:
+               $gapOpen   = 9;
+               $gapExtend = 1;
+               break;
+         }
+         break;
+      case 'PAM250':
+         switch ($gapKey) {
+            case 0:
+               $gapOpen   = 15;
+               $gapExtend = 3;
+               break;
+            case 1:
+               $gapOpen   = 14;
+               $gapExtend = 3;
+               break;
+            case 2:
+               $gapOpen   = 13;
+               $gapExtend = 3;
+               break;
+            case 3:
+               $gapOpen   = 12;
+               $gapExtend = 3;
+               break;
+            case 4:
+               $gapOpen   = 11;
+               $gapExtend = 3;
+               break;
+            case 5:
+               $gapOpen   = 17;
+               $gapExtend = 2;
+               break;
+            case 6:
+               $gapOpen   = 16;
+               $gapExtend = 2;
+               break;
+            case 7:
+               $gapOpen   = 15;
+               $gapExtend = 2;
+               break;
+            case 8:
+               $gapOpen   = 14;
+               $gapExtend = 2;
+               break;
+            case 9:
+               $gapOpen   = 13;
+               $gapExtend = 2;
+               break;
+            case 10:
+               $gapOpen   = 21;
+               $gapExtend = 1;
+               break;
+            case 11:
+               $gapOpen   = 20;
+               $gapExtend = 1;
+               break;
+            case 12:
+               $gapOpen   = 19;
+               $gapExtend = 1;
+               break;
+            case 13:
+               $gapOpen   = 18;
+               $gapExtend = 1;
+               break;
+            case 14:
+               $gapOpen   = 17;
+               $gapExtend = 1;
+               break;
+         }
+         break;
+      case 'BLOSUM80':
+         switch ($gapKey) {
+            case 0:
+               $gapOpen   = 8;
+               $gapExtend = 2;
+               break;
+            case 1:
+               $gapOpen   = 7;
+               $gapExtend = 2;
+               break;
+            case 2:
+               $gapOpen   = 6;
+               $gapExtend = 2;
+               break;
+            case 3:
+               $gapOpen   = 11;
+               $gapExtend = 1;
+               break;
+            case 4:
+               $gapOpen   = 10;
+               $gapExtend = 1;
+               break;
+            case 5:
+               $gapOpen   = 9;
+               $gapExtend = 1;
+               break;
+         }
+         break;
+      case 'BLOSUM62':
+         switch ($gapKey) {
+            case 0:
+               $gapOpen   = 11;
+               $gapExtend = 2;
+               break;
+            case 1:
+               $gapOpen   = 10;
+               $gapExtend = 2;
+               break;
+            case 2:
+               $gapOpen   = 9;
+               $gapExtend = 2;
+               break;
+            case 3:
+               $gapOpen   = 8;
+               $gapExtend = 2;
+               break;
+            case 4:
+               $gapOpen   = 7;
+               $gapExtend = 2;
+               break;
+            case 5:
+               $gapOpen   = 6;
+               $gapExtend = 2;
+               break;
+            case 6:
+               $gapOpen   = 13;
+               $gapExtend = 1;
+               break;
+            case 7:
+               $gapOpen   = 12;
+               $gapExtend = 1;
+               break;
+            case 8:
+               $gapOpen   = 11;
+               $gapExtend = 1;
+               break;
+            case 9:
+               $gapOpen   = 10;
+               $gapExtend = 1;
+               break;
+            case 10:
+               $gapOpen   = 9;
+               $gapExtend = 1;
+               break;
+         }
+         break;
+      case 'BLOSUM45':
+         switch ($gapKey) {
+            case 0:
+               $gapOpen   = 13;
+               $gapExtend = 3;
+               break;
+            case 1:
+               $gapOpen   = 12;
+               $gapExtend = 3;
+               break;
+            case 2:
+               $gapOpen   = 11;
+               $gapExtend = 3;
+               break;
+            case 3:
+               $gapOpen   = 10;
+               $gapExtend = 3;
+               break;
+            case 4:
+               $gapOpen   = 15;
+               $gapExtend = 2;
+               break;
+            case 5:
+               $gapOpen   = 14;
+               $gapExtend = 2;
+               break;
+            case 6:
+               $gapOpen   = 13;
+               $gapExtend = 2;
+               break;
+            case 7:
+               $gapOpen   = 12;
+               $gapExtend = 2;
+               break;
+            case 8:
+               $gapOpen   = 19;
+               $gapExtend = 1;
+               break;
+            case 9:
+               $gapOpen   = 18;
+               $gapExtend = 1;
+               break;
+            case 10:
+               $gapOpen   = 17;
+               $gapExtend = 1;
+               break;
+            case 11:
+               $gapOpen   = 16;
+               $gapExtend = 1;
+               break;
+         }
+         break;
+      case 'BLOSUM50':
+         switch ($gapKey) {
+            case 0:
+               $gapOpen   = 13;
+               $gapExtend = 3;
+               break;
+            case 1:
+               $gapOpen   = 12;
+               $gapExtend = 3;
+               break;
+            case 2:
+               $gapOpen   = 11;
+               $gapExtend = 3;
+               break;
+            case 3:
+               $gapOpen   = 10;
+               $gapExtend = 3;
+               break;
+            case 4:
+               $gapOpen   = 9;
+               $gapExtend = 3;
+               break;
+            case 5:
+               $gapOpen   = 16;
+               $gapExtend = 2;
+               break;
+            case 6:
+               $gapOpen   = 15;
+               $gapExtend = 2;
+               break;
+            case 7:
+               $gapOpen   = 14;
+               $gapExtend = 2;
+               break;
+            case 8:
+               $gapOpen   = 13;
+               $gapExtend = 2;
+               break;
+            case 9:
+               $gapOpen   = 12;
+               $gapExtend = 2;
+               break;
+            case 10:
+               $gapOpen   = 19;
+               $gapExtend = 1;
+               break;
+            case 11:
+               $gapOpen   = 18;
+               $gapExtend = 1;
+               break;
+            case 12:
+               $gapOpen   = 17;
+               $gapExtend = 1;
+               break;
+            case 13:
+               $gapOpen   = 16;
+               $gapExtend = 1;
+               break;
+            case 14:
+               $gapOpen   = 15;
+               $gapExtend = 1;
+               break;
+         }
+         break;
+      case 'BLOSUM90':
+         switch ($gapKey) {
+            case 0:
+               $gapOpen   = 9;
+               $gapExtend = 2;
+               break;
+            case 1:
+               $gapOpen   = 8;
+               $gapExtend = 2;
+               break;
+            case 2:
+               $gapOpen   = 7;
+               $gapExtend = 2;
+               break;
+            case 3:
+               $gapOpen   = 6;
+               $gapExtend = 2;
+               break;
+            case 4:
+               $gapOpen   = 11;
+               $gapExtend = 1;
+               break;
+            case 5:
+               $gapOpen   = 10;
+               $gapExtend = 1;
+               break;
+            case 6:
+               $gapOpen   = 9;
+               $gapExtend = 1;
+               break;
+         }
+         break;
+         
+   }
+   
+   return array(
+       'gapOpen' => $gapOpen,
+      'gapExtend' => $gapExtend 
+   );
+ }
+
+
 /**
  * Get a list of options for gaps.
  */
-function _get_gap($which) {
+function _get_gap_options($which) {
   switch ($which) {
     case 'blastn':
       return array(

+ 0 - 369
includes/blast_ui.services.inc

@@ -640,375 +640,6 @@ function getBlastData( $job_id )
    return $result;
  }
 
-/*
- **Method Used for tblastn and blastx
- **  @return  int $gapOpen and $gapExtend
- */
-
-function getGap( $matrix, $gapkey )
- {
-   switch ( $matrix )
-   {
-      case 'PAM30':
-         switch ( $gapKey )
-         {
-            case 0:
-               $gapOpen   = 7;
-               $gapExtend = 2;
-               break;
-            case 1:
-               $gapOpen   = 6;
-               $gapExtend = 2;
-               break;
-            case 2:
-               $gapOpen   = 5;
-               $gapExtend = 2;
-               break;
-            case 3:
-               $gapOpen   = 10;
-               $gapExtend = 1;
-               break;
-            case 4:
-               $gapOpen   = 9;
-               $gapExtend = 1;
-               break;
-            case 5:
-               $gapOpen   = 8;
-               $gapExtend = 1;
-               break;
-         }
-         break;
-      case 'PAM70':
-         switch ( $gapKey )
-         {
-            case 0:
-               $gapOpen   = 8;
-               $gapExtend = 2;
-               break;
-            case 1:
-               $gapOpen   = 7;
-               $gapExtend = 2;
-               break;
-            case 2:
-               $gapOpen   = 6;
-               $gapExtend = 2;
-               break;
-            case 3:
-               $gapOpen   = 11;
-               $gapExtend = 1;
-               break;
-            case 4:
-               $gapOpen   = 10;
-               $gapExtend = 1;
-               break;
-            case 5:
-               $gapOpen   = 9;
-               $gapExtend = 1;
-               break;
-         }
-         break;
-      case 'PAM250':
-         switch ( $gapKey )
-         {
-            case 0:
-               $gapOpen   = 15;
-               $gapExtend = 3;
-               break;
-            case 1:
-               $gapOpen   = 14;
-               $gapExtend = 3;
-               break;
-            case 2:
-               $gapOpen   = 13;
-               $gapExtend = 3;
-               break;
-            case 3:
-               $gapOpen   = 12;
-               $gapExtend = 3;
-               break;
-            case 4:
-               $gapOpen   = 11;
-               $gapExtend = 3;
-               break;
-            case 5:
-               $gapOpen   = 17;
-               $gapExtend = 2;
-               break;
-            case 6:
-               $gapOpen   = 16;
-               $gapExtend = 2;
-               break;
-            case 7:
-               $gapOpen   = 15;
-               $gapExtend = 2;
-               break;
-            case 8:
-               $gapOpen   = 14;
-               $gapExtend = 2;
-               break;
-            case 9:
-               $gapOpen   = 13;
-               $gapExtend = 2;
-               break;
-            case 10:
-               $gapOpen   = 21;
-               $gapExtend = 1;
-               break;
-            case 11:
-               $gapOpen   = 20;
-               $gapExtend = 1;
-               break;
-            case 12:
-               $gapOpen   = 19;
-               $gapExtend = 1;
-               break;
-            case 13:
-               $gapOpen   = 18;
-               $gapExtend = 1;
-               break;
-            case 14:
-               $gapOpen   = 17;
-               $gapExtend = 1;
-               break;
-         }
-         break;
-      case 'BLOSUM80':
-         switch ( $gapKey )
-         {
-            case 0:
-               $gapOpen   = 8;
-               $gapExtend = 2;
-               break;
-            case 1:
-               $gapOpen   = 7;
-               $gapExtend = 2;
-               break;
-            case 2:
-               $gapOpen   = 6;
-               $gapExtend = 2;
-               break;
-            case 3:
-               $gapOpen   = 11;
-               $gapExtend = 1;
-               break;
-            case 4:
-               $gapOpen   = 10;
-               $gapExtend = 1;
-               break;
-            case 5:
-               $gapOpen   = 9;
-               $gapExtend = 1;
-               break;
-         }
-         break;
-      case 'BLOSUM62':
-         switch ( $gapKey )
-         {
-            case 0:
-               $gapOpen   = 11;
-               $gapExtend = 2;
-               break;
-            case 1:
-               $gapOpen   = 10;
-               $gapExtend = 2;
-               break;
-            case 2:
-               $gapOpen   = 9;
-               $gapExtend = 2;
-               break;
-            case 3:
-               $gapOpen   = 8;
-               $gapExtend = 2;
-               break;
-            case 4:
-               $gapOpen   = 7;
-               $gapExtend = 2;
-               break;
-            case 5:
-               $gapOpen   = 6;
-               $gapExtend = 2;
-               break;
-            case 6:
-               $gapOpen   = 13;
-               $gapExtend = 1;
-               break;
-            case 7:
-               $gapOpen   = 12;
-               $gapExtend = 1;
-               break;
-            case 8:
-               $gapOpen   = 11;
-               $gapExtend = 1;
-               break;
-            case 9:
-               $gapOpen   = 10;
-               $gapExtend = 1;
-               break;
-            case 10:
-               $gapOpen   = 9;
-               $gapExtend = 1;
-               break;
-         }
-         break;
-      case 'BLOSUM45':
-         switch ( $gapKey )
-         {
-            case 0:
-               $gapOpen   = 13;
-               $gapExtend = 3;
-               break;
-            case 1:
-               $gapOpen   = 12;
-               $gapExtend = 3;
-               break;
-            case 2:
-               $gapOpen   = 11;
-               $gapExtend = 3;
-               break;
-            case 3:
-               $gapOpen   = 10;
-               $gapExtend = 3;
-               break;
-            case 4:
-               $gapOpen   = 15;
-               $gapExtend = 2;
-               break;
-            case 5:
-               $gapOpen   = 14;
-               $gapExtend = 2;
-               break;
-            case 6:
-               $gapOpen   = 13;
-               $gapExtend = 2;
-               break;
-            case 7:
-               $gapOpen   = 12;
-               $gapExtend = 2;
-               break;
-            case 8:
-               $gapOpen   = 19;
-               $gapExtend = 1;
-               break;
-            case 9:
-               $gapOpen   = 18;
-               $gapExtend = 1;
-               break;
-            case 10:
-               $gapOpen   = 17;
-               $gapExtend = 1;
-               break;
-            case 11:
-               $gapOpen   = 16;
-               $gapExtend = 1;
-               break;
-         }
-         break;
-      case 'BLOSUM50':
-         switch ( $gapKey )
-         {
-            case 0:
-               $gapOpen   = 13;
-               $gapExtend = 3;
-               break;
-            case 1:
-               $gapOpen   = 12;
-               $gapExtend = 3;
-               break;
-            case 2:
-               $gapOpen   = 11;
-               $gapExtend = 3;
-               break;
-            case 3:
-               $gapOpen   = 10;
-               $gapExtend = 3;
-               break;
-            case 4:
-               $gapOpen   = 9;
-               $gapExtend = 3;
-               break;
-            case 5:
-               $gapOpen   = 16;
-               $gapExtend = 2;
-               break;
-            case 6:
-               $gapOpen   = 15;
-               $gapExtend = 2;
-               break;
-            case 7:
-               $gapOpen   = 14;
-               $gapExtend = 2;
-               break;
-            case 8:
-               $gapOpen   = 13;
-               $gapExtend = 2;
-               break;
-            case 9:
-               $gapOpen   = 12;
-               $gapExtend = 2;
-               break;
-            case 10:
-               $gapOpen   = 19;
-               $gapExtend = 1;
-               break;
-            case 11:
-               $gapOpen   = 18;
-               $gapExtend = 1;
-               break;
-            case 12:
-               $gapOpen   = 17;
-               $gapExtend = 1;
-               break;
-            case 13:
-               $gapOpen   = 16;
-               $gapExtend = 1;
-               break;
-            case 14:
-               $gapOpen   = 15;
-               $gapExtend = 1;
-               break;
-         }
-         break;
-      case 'BLOSUM90':
-         switch ( $gapKey )
-         {
-            case 0:
-               $gapOpen   = 9;
-               $gapExtend = 2;
-               break;
-            case 1:
-               $gapOpen   = 8;
-               $gapExtend = 2;
-               break;
-            case 2:
-               $gapOpen   = 7;
-               $gapExtend = 2;
-               break;
-            case 3:
-               $gapOpen   = 6;
-               $gapExtend = 2;
-               break;
-            case 4:
-               $gapOpen   = 11;
-               $gapExtend = 1;
-               break;
-            case 5:
-               $gapOpen   = 10;
-               $gapExtend = 1;
-               break;
-            case 6:
-               $gapOpen   = 9;
-               $gapExtend = 1;
-               break;
-         }
-         break;
-
-   }
-   return array(
-       'gapOpen' => $gapOpen,
-      'gapExtend' => $gapExtend
-   );
- }
-
 /*
  ** Used for tblastn
  */

+ 92 - 14
theme/blast_help.tpl.php

@@ -4,26 +4,104 @@
  */
 ?>
 
-<h3>Module Description</h3>
+<style>
+.sub_table {
+  border: 0px;
+  padding:1px 1px;
+  background-color: inherit;
+}
+</style>
+
+<h3>Tripal BLAST Module Description</h3>
 <p>This module provides a basic interface to allow your users to utilize your server's NCBI BLAST+.</p>
 
-<h3>Setup Instructions</h3>
+<p>
+  <a href="#setup">Setup</a> | <a href="#function">Functionality</a>
+</p>
+
+<a name="setup"></a>
+&mdash;
+<h3><b>Setup Instructions</b></h3>
 <ol>
-<li>Install NCBI BLAST+ on your server (Tested with 2.2.26+). There is a <a href="https://launchpad.net/ubuntu/+source/ncbi-blast+">package available for Ubuntu</a> to ease installation. Optionally you can set the path to your BLAST executable <a href="<?php print url('admin/tripal/extension/tripal_blast/blast_ui');?>">in the settings</a>.</li>
-<li>Optionally, create Tripal External Database References to allow you to link the records in your BLAST database to further information. To do this simply go to <a href="<?php print url('admin/tripal/chado/tripal_db/add'); ?>" target="_blank">Tripal > Chado Modules > Databases > Add DB</a> and make sure to fill in the Database prefix which will be concatenated with the record IDs in your BLAST database to determine the link-out to additional information. Note that a regular expression can be used when creating the BLAST database to indicate what the ID is.</li>
-<li><a href="<?php print url('node/add/blastdb');?>">Create "Blast Database" nodes</a> for each dataset you want to make available for your users to BLAST against. BLAST databases should first be created using the command-line <code>makeblastdb</code> program with the <code>-parse_seqids</code> flag.</li>
-<li>It's recommended that you also install the <a href="http://drupal.org/project/tripal_daemon">Tripal Job Daemon</a> to manage BLAST jobs and ensure they are run soon after being submitted by the user. Without this additional module, administrators will have to execute the tripal jobs either manually or through use of cron jobs.</li>
+  <li>
+    Install NCBI BLAST+ on your server (Tested with 2.2.26+). There is a 
+    <a href="https://launchpad.net/ubuntu/+source/ncbi-blast+">package available 
+    for Ubuntu</a> to ease installation. Optionally you can set the path to your 
+    BLAST executable <a href="<?php print url('admin/tripal/extension/tripal_blast/blast_ui');?>">
+    in the settings</a>.
+  </li>
+  <li>
+    Optionally, create Tripal External Database References to allow you to link 
+    the records in your BLAST database to further information. To do this simply 
+    go to <a href="<?php print url('admin/tripal/chado/tripal_db/add'); ?>" target="_blank">Tripal> 
+    Chado Modules > Databases > Add DB</a> and make sure to fill in the Database 
+    prefix which will be concatenated with the record IDs in your BLAST database 
+    to determine the link-out to additional information. Note that a regular 
+    expression can be used when creating the BLAST database to indicate what the 
+    ID is.
+  </li>
+  <li>
+    <a href="<?php print url('node/add/blastdb');?>">Create "Blast Database" 
+    nodes</a> for each dataset you want to make available for your users to BLAST 
+    against. BLAST databases should first be created using the command-line 
+    <code>makeblastdb</code> program with the <code>-parse_seqids</code> flag.  
+  </li>
+  <li>
+    It's recommended that you also install the <a href="http://drupal.org/project/tripal_daemon">Tripal Job Daemon</a> 
+    to manage BLAST jobs and ensure they are run soon after being submitted by the 
+    user. Without this additional module, administrators will have to execute the 
+    tripal jobs either manually or through use of cron jobs.
+  </li>
 </ol>
 
-<h3>Highlighted Functionality</h3>
+<a name="function"></a>
+&mdash;
+<h3><b>Highlighted Functionality</b></h3>
 <ul>
   <li>Supports <a href="<?php print url('blast/nucleotide/nucleotide');?>">blastn</a>, 
     <a href="<?php print url('blast/nucleotide/protein');?>">blastx</a>, 
     <a href="<?php print url('blast/protein/protein');?>">blastp</a> and 
-    <a href="<?php print url('blast/protein/nucleotide');?>">tblastx</a> with separate forms depending upon the database/query type.</li>
-  <li>Simple interface allowing users to paste or upload a query sequence and then select from available databases. Additionally, a FASTA file can be uploaded for use as a database to BLAST against (this functionality can be disabled).</li>
-  <li>Tabular Results listing with alignment information and multiple download formats (HTML, TSV, XML) available.</li>
-  <li>Completely integrated with <a href="<?php print url('admin/tripal/tripal_jobs');?>">Tripal Jobs</a> providing administrators with a way to track BLAST jobs and ensuring long running BLASTs will not cause page time-outs</li>
-  <li>BLAST databases are made available to the module by <a href="<?php print url('node/add/blastdb');?>">creating Drupal Pages</a> describing them. This allows administrators to <a href="<?php print url('admin/structure/types/manage/blastdb/fields');?>">use the Drupal Field API to add any information they want to these pages</a>.</li>
-  <li>BLAST database records can be linked to an external source with more information (ie: NCBI) per BLAST database.</li>
-</ul>
+    <a href="<?php print url('blast/protein/nucleotide');?>">tblastx</a> with separate forms depending upon the database/query type.
+  </li>
+  <li>
+    Simple interface allowing users to paste or upload a query sequence and then 
+    select from available databases. Additionally, a FASTA file can be uploaded 
+    for use as a database to BLAST against (this functionality can be disabled).
+  </li>
+  <li>
+    Tabular Results listing with alignment information and multiple download 
+    formats (HTML, TSV, XML) available.
+  </li>
+  <li>
+    Completely integrated with <a href="<?php print url('admin/tripal/tripal_jobs');?>">Tripal Jobs</a> 
+    providing administrators with a way to track BLAST jobs and ensuring long 
+    running BLASTs will not cause page time-outs
+  </li>
+  <li>
+    BLAST databases are made available to the module by 
+    <a href="<?php print url('node/add/blastdb');?>">creating Drupal Pages</a> 
+    describing them. This allows administrators to 
+    <a href="<?php print url('admin/structure/types/manage/blastdb/fields');?>">use the Drupal Field API to add any information they want to these pages</a>.
+  </li>
+  <li>
+    BLAST database records can be linked to an external source with more 
+    information (ie: NCBI) per BLAST database.
+  </li>
+</ul>
+
+<h3><b>Protection Against Large Jobs</b></h3>
+Depending on the size and nature of your target databases, you may wish to constrain use 
+of this module.
+<ol>
+  <li>Limit the number of results displayed via admin page. The recommended number is 500.</li>
+  <li>
+    Limit the maximum upload file size in php settings. This is less useful because some 
+    very large queries may be manageable, and others not.
+  </li>
+  <li>
+    Repeat-mask your targets, or provide repeat-masked versions. Note that some 
+    researchers may be looking for repeats, so this may limit the usefulness of the BLAST 
+    service.
+  </li>
+</ol>
+

+ 246 - 255
theme/blast_report.tpl.php

@@ -62,273 +62,264 @@ $no_hits = TRUE;
 
 <div class="blast-report">
 
-<!-- Provide Information to the user about their blast job -->
-<div class="blast-job-info">
-<?php 
-  $output_files = array();
-  if (file_exists($blast_job->files->result->html))
-    $output_files['html'] = array('path' => $blast_job->files->result->html, 'title' => 'Alignment');
-  if (file_exists($blast_job->files->result->tsv))
-    $output_files['tsv'] = array('path' => $blast_job->files->result->tsv, 'title' => 'Tab-Delimited');
-  if (file_exists($blast_job->files->result->gff))
-    $output_files['gff'] = array('path' => $blast_job->files->result->gff, 'title' => 'GFF3');
-  if (file_exists($blast_job->files->result->xml))
-    $output_files['xml'] = array('path' => $blast_job->files->result->xml, 'title' => 'XML');
-?>
-  <?php if(!empty($output_files)): ?>
-  <div class="blast-download-info"><strong>Download</strong>:
-    <?php
-      $i = 0;
-      foreach($output_files as $file) {
-        $i++;
-        print l($file['title'], $file['path']);
-        if (sizeof($output_files) != $i) print ', ';
-    } ?>
-  </div>
-  <?php endif; ?>
-  <br />
-  <div class="blast-query-info"><strong>Query Information</strong>:
-    <?php print $blast_job->files->query;?></div>
-  <div class="blast-target-info"><strong>Search Target</strong>:
-    <?php print $blast_job->blastdb->db_name;?></div>
-  <div class="blast-date-info"><strong>Submission Date</strong>:
-    <?php print format_date($blast_job->date_submitted, 'medium');?></div>
-  <div class="blast-cmd-info"><strong>BLAST Command executed</strong>:
-    <?php print $blast_job->blast_cmd;?></div>
+  <div class="blast-job-info">
+    <!-- Provide Information to the user about their blast job -->
+    <div class="blast-job-info">
+      <div class="blast-download-info"><strong>Download</strong>:
+        <a href="<?php print '../../' . $blast_job->files->result->html; ?>">Alignment</a>,
+        <a href="<?php print '../../' . $blast_job->files->result->tsv; ?>">Tab-Delimited</a>,
+        <a href="<?php print '../../' . $blast_job->files->result->xml; ?>">XML</a>,
+        <a href="<?php print '../../' . $blast_job->files->result->gff; ?>">GFF3</a>
+      </div>
+      <br />
+      <div class="blast-query-info"><strong>Query Information</strong>: 
+        <?php print $blast_job->files->query;?></div>
+      <div class="blast-target-info"><strong>Search Target</strong>: 
+        <?php print $blast_job->blastdb->db_name;?></div>
+      <div class="blast-date-info"><strong>Submission Date</strong>: 
+        <?php print format_date($blast_job->date_submitted, 'medium');?></div>
+      <div class="blast-cmd-info"><strong>BLAST Command executed</strong>: 
+        <?php print $blast_job->blast_cmd;?></div>
+      <br />
+      <div class="num-results">
+        <strong>Number of Results</strong>: <?php print $num_results; ?>
+      </div>
+    </div>
+
+    <br />
+    <div class="num-results">
+      <strong>Number of Results</strong>: <?php print $num_results; ?>
+    </div>
 
+  </div>
   <br />
-  <div class="num-results"><strong>Number of Results</strong>: <?php print $num_results; ?></div>
-
-</div>
-<br />
 
-<?php
-
-/**
- * We are using the drupal table theme functionality to create this listing
- * @see theme_table() for additional documentation
- */
+  <div class="report-table">
+    <?php
+    /**
+     * We are using the drupal table theme functionality to create this listing
+     * @see theme_table() for additional documentation
+     */
 
-if ($xml) {
-?>
+    if ($xml) {
+    ?>
 
-<p>The following table summarizes the results of your BLAST.
-Click on a <em>triangle </em> on the left to see the alignment and a visualization of the hit,
-and click the <em>target name </em> to get more information about the target hit.</p>
+    <p>The following table summarizes the results of your BLAST.
+    Click on a <em>triangle </em> on the left to see the alignment and a visualization of the hit,
+    and click the <em>target name </em> to get more information about the target hit.</p>
 
-<?php
-  // Specify the header of the table
-  $header = array(
-    'arrow-col' =>  array('data' => '', 'class' => array('arrow-col')),
-    'number' =>  array('data' => '#', 'class' => array('number')),
-    'query' =>  array('data' => 'Query Name  (Click for alignment & visualization)', 'class' => array('query')),
-    'hit' =>  array('data' => 'Target Name', 'class' => array('hit')),
-    'evalue' =>  array('data' => 'E-Value', 'class' => array('evalue')),
-  );
-
-  $rows = array();
-  $count = 0;
-
-  // Parse the BLAST XML to generate the rows of the table
-  // where each hit results in two rows in the table: 1) A summary of the query/hit and
-  // significance and 2) additional information including the alignment
-  foreach ($xml->{'BlastOutput_iterations'}->children() as $iteration) {
-    $children_count = $iteration->{'Iteration_hits'}->children()->count();
-
-    // Save some information needed for the hit visualization.
-    $target_name = '';
-    $q_name = $xml->{'BlastOutput_query-def'};
-    $query_size = $xml->{'BlastOutput_query-len'};
-    $target_size = $iteration->{'Iteration_stat'}->{'Statistics'}->{'Statistics_db-len'};
-
-    if ($children_count != 0) {
-      foreach ($iteration->{'Iteration_hits'}->children() as $hit) {
-        if (is_object($hit)) {
-          $count +=1;
-          $zebra_class = ($count % 2 == 0) ? 'even' : 'odd';
-          $no_hits = FALSE;
-
-          // SUMMARY ROW
-          // -- Save additional information needed for the summary.
-          $score = (float) $hit->{'Hit_hsps'}->{'Hsp'}->{'Hsp_score'};
-          $evalue = (float) $hit->{'Hit_hsps'}->{'Hsp'}->{'Hsp_evalue'};
-          $query_name = (string) $iteration->{'Iteration_query-def'};
-
-          // If the id is of the form gnl|BL_ORD_ID|### then the parseids flag
-          // to makeblastdb did a really poor job. In thhis case we want to use
-          // the def to provide the original FASTA header.
-          // @todo Deepak changed this to use just the hit_def; inquire as to why.
-          $hit_name = (preg_match('/BL_ORD_ID/', $hit->{'Hit_id'})) ? $hit->{'Hit_def'} : $hit->{'Hit_id'};
-          // Used for the hit visualization to ensure the name isn't truncated.
-          $hit_name_short = (preg_match('/^([^\s]+)/', $hit_name, $matches)) ? $matches[1] : $hit_name;
-
-          // Round e-value to two decimal values.
-          $rounded_evalue = '';
-          if (strpos($evalue,'e') != false) {
-            $evalue_split = explode('e', $evalue);
-            $rounded_evalue = round($evalue_split[0], 2, PHP_ROUND_HALF_EVEN);
-            $rounded_evalue .= 'e' . $evalue_split[1];
-          }
-          else {
-            $rounded_evalue = $evalue;
-          }
-
-          // State what should be in the summary row for theme_table() later.
-          $summary_row = array(
-            'data' => array(
-              'arrow-col' => array('data' => '<div class="arrow"></div>', 'class' => array('arrow-col')),
-              'number' => array('data' => $count, 'class' => array('number')),
-              'query' => array('data' => $query_name, 'class' => array('query')),
-              'hit' => array('data' => $hit_name, 'class' => array('hit')),
-              'evalue' => array('data' => $rounded_evalue, 'class' => array('evalue')),
-            ),
-            'class' => array('result-summary')
-          );
-
-          // ALIGNMENT ROW (collapsed by default)
-          // Process HSPs
-          $HSPs = array();
-
-          // We need to save some additional summary information in order to draw the
-          // hit visualization. First, initialize some variables...
-          $track_start = INF;
-          $track_end = -1;
-          $hsps_range = '';
-          $hit_hsps = '';
-          $hit_hsp_score = '';
-          $target_size = $hit->{'Hit_len'};
-          $Hsp_bit_score = '';
-
-          // Then for each hit hsp, keep track of the start of first hsp and the end of
-          // the last hsp. Keep in mind that hsps might not be recorded in order.
-          foreach ($hit->{'Hit_hsps'}->children() as $hsp_xml) {
-            $HSPs[] = (array) $hsp_xml;
-
-            if ($track_start > $hsp_xml->{'Hsp_hit-from'}) {
-              $track_start = $hsp_xml->{'Hsp_hit-from'} . "";
-            }
-            if ($track_end < $hsp_xml->{'Hsp_hit-to'}) {
-              $track_end = $hsp_xml->{'Hsp_hit-to'} . "";
-            }
-
-            // The BLAST visualization code requires the hsps to be formatted in a
-            // very specific manner. Here we build up the strings to be submitted.
-            // hits=4263001_4262263_1_742;4260037_4259524_895_1411;&scores=722;473;
-            $hit_hsps .=  $hsp_xml->{'Hsp_hit-from'} . '_' .
-                          $hsp_xml->{'Hsp_hit-to'} . '_' .
-                          $hsp_xml->{'Hsp_query-from'} . '_' . $hsp_xml->{'Hsp_query-to'} .
-                          ';';
-            $Hsp_bit_score .=   $hsp_xml->{'Hsp_bit-score'} .';';
-          }
-          // Finally record the range.
-          // @todo figure out why we arbitrarily subtract 50,000 here...
-          // @more removing the 50,000 and using track start/end appears to cause no change...
-          $range_start = (int) $track_start;// - 50000;
-          $range_end = (int) $track_end;// + 50000;
-          if ($range_start < 1) $range_start = 1;
-
-
-          // Call the function to generate the hit image.
-          $hit_img = generate_blast_hit_image($target_name, $Hsp_bit_score, $hit_hsps,
-                                   $target_size, $query_size, $q_name, $hit_name_short);
-
-
-          // State what should be in the alignment row for theme_table() later.
-          $alignment_row = array(
-            'data' => array(
-              'arrow' => array(
-                'data' => theme('blast_report_alignment_row', array('HSPs' => $HSPs, 'hit_visualization' => $hit_img)),
-                'colspan' => 5,
-              ),
-            ),
-            'class' => array('alignment-row', $zebra_class),
-            'no_striping' => TRUE
-          );
-
-          // LINK-OUTS.
-          // It was determined above whether link-outs were supported for the
-          // tripal blast database used as a search target. Thus we only want to
-          // determine a link-out if it's actually supported... ;-)
-          if ($linkout) {
-
-            // First extract the linkout text using the regex provided through
-            // the Tripal blast database node.
-            if (preg_match($linkout_regex, $hit_name, $linkout_match)) {
-              $hit->{'linkout_id'} = $linkout_match[1];
-              $hit->{'hit_name'} = $hit_name;
-
-              // Allow custom functions to determine the URL to support more complicated
-              // link-outs rather than just using the tripal database prefix.
-              $hit_name = call_user_func(
-                $url_function,
-                $linkout_urlprefix,
-                $hit,
-                array(
-                  'query_name' => $query_name,
-                  'score'      => $score,
-                  'e-value'    => $evalue,
-                  'HSPs'       => $HSPs,
-                  'Target'     => $blast_job->blastdb->db_name,
-                )
+    <?php
+      // Specify the header of the table
+      $header = array(
+        'arrow-col' =>  array('data' => '', 'class' => array('arrow-col')),
+        'number' =>  array('data' => '#', 'class' => array('number')),
+        'query' =>  array('data' => 'Query Name  (Click for alignment & visualization)', 'class' => array('query')),
+        'hit' =>  array('data' => 'Target Name', 'class' => array('hit')),
+        'evalue' =>  array('data' => 'E-Value', 'class' => array('evalue')),
+      );
+
+      $rows = array();
+      $count = 0;
+
+      // Parse the BLAST XML to generate the rows of the table
+      // where each hit results in two rows in the table: 1) A summary of the query/hit and
+      // significance and 2) additional information including the alignment
+      foreach ($xml->{'BlastOutput_iterations'}->children() as $iteration) {
+        $children_count = $iteration->{'Iteration_hits'}->children()->count();
+
+        // Save some information needed for the hit visualization.
+        $target_name = '';
+        $q_name = $xml->{'BlastOutput_query-def'};
+        $query_size = $xml->{'BlastOutput_query-len'};
+        $target_size = $iteration->{'Iteration_stat'}->{'Statistics'}->{'Statistics_db-len'};
+
+        if ($children_count != 0) {
+          foreach ($iteration->{'Iteration_hits'}->children() as $hit) {
+            if (is_object($hit)) {
+              $count +=1;
+              $zebra_class = ($count % 2 == 0) ? 'even' : 'odd';
+              $no_hits = FALSE;
+
+              // SUMMARY ROW
+              // -- Save additional information needed for the summary.
+              $score = (float) $hit->{'Hit_hsps'}->{'Hsp'}->{'Hsp_score'};
+              $evalue = (float) $hit->{'Hit_hsps'}->{'Hsp'}->{'Hsp_evalue'};
+              $query_name = (string) $iteration->{'Iteration_query-def'};
+
+              // If the id is of the form gnl|BL_ORD_ID|### then the parseids flag
+              // to makeblastdb did a really poor job. In thhis case we want to use
+              // the def to provide the original FASTA header.
+              // @todo Deepak changed this to use just the hit_def; inquire as to why.
+              $hit_name = (preg_match('/BL_ORD_ID/', $hit->{'Hit_id'})) ? $hit->{'Hit_def'} : $hit->{'Hit_id'};
+              // Used for the hit visualization to ensure the name isn't truncated.
+              $hit_name_short = (preg_match('/^([^\s]+)/', $hit_name, $matches)) ? $matches[1] : $hit_name;
+
+              // Round e-value to two decimal values.
+              $rounded_evalue = '';
+              if (strpos($evalue,'e') != false) {
+                $evalue_split = explode('e', $evalue);
+                $rounded_evalue = round($evalue_split[0], 2, PHP_ROUND_HALF_EVEN);
+                $rounded_evalue .= 'e' . $evalue_split[1];
+              }
+              else {
+                $rounded_evalue = $evalue;
+              }
+
+              // State what should be in the summary row for theme_table() later.
+              $summary_row = array(
+                'data' => array(
+                  'arrow-col' => array('data' => '<div class="arrow"></div>', 'class' => array('arrow-col')),
+                  'number' => array('data' => $count, 'class' => array('number')),
+                  'query' => array('data' => $query_name, 'class' => array('query')),
+                  'hit' => array('data' => $hit_name, 'class' => array('hit')),
+                  'evalue' => array('data' => $rounded_evalue, 'class' => array('evalue')),
+                ),
+                'class' => array('result-summary')
               );
-            }
-
-            // Replace the target name with the link.
-            $summary_row['data']['hit']['data'] = $hit_name;
-          }
-
-          // ADD TO TABLE ROWS
-          $rows[] = $summary_row;
-          $rows[] = $alignment_row;
-
-        }//end of if - checks $hit
-      }//end of foreach - iteration_hits
-    }//end of if - check for iteration_hits
 
-    else {
-      // Currently where the "no results" is added.
-      $query_name = $iteration->{'Iteration_query-def'};
-      $query_with_no_hits[] = $query_name;
-
-    }//no results
-  }//end of foreach - BlastOutput_iterations
+              // ALIGNMENT ROW (collapsed by default)
+              // Process HSPs
+              $HSPs = array();
+
+              // We need to save some additional summary information in order to draw the
+              // hit visualization. First, initialize some variables...
+              $track_start = INF;
+              $track_end = -1;
+              $hsps_range = '';
+              $hit_hsps = '';
+              $hit_hsp_score = '';
+              $target_size = $hit->{'Hit_len'};
+              $Hsp_bit_score = '';
+
+              // Then for each hit hsp, keep track of the start of first hsp and the end of
+              // the last hsp. Keep in mind that hsps might not be recorded in order.
+              foreach ($hit->{'Hit_hsps'}->children() as $hsp_xml) {
+                $HSPs[] = (array) $hsp_xml;
+
+                if ($track_start > $hsp_xml->{'Hsp_hit-from'}) {
+                  $track_start = $hsp_xml->{'Hsp_hit-from'} . "";
+                }
+                if ($track_end < $hsp_xml->{'Hsp_hit-to'}) {
+                  $track_end = $hsp_xml->{'Hsp_hit-to'} . "";
+                }
+
+                // The BLAST visualization code requires the hsps to be formatted in a
+                // very specific manner. Here we build up the strings to be submitted.
+                // hits=4263001_4262263_1_742;4260037_4259524_895_1411;&scores=722;473;
+                $hit_hsps .=  $hsp_xml->{'Hsp_hit-from'} . '_' .
+                              $hsp_xml->{'Hsp_hit-to'} . '_' .
+                              $hsp_xml->{'Hsp_query-from'} . '_' . $hsp_xml->{'Hsp_query-to'} .
+                              ';';
+                $Hsp_bit_score .=   $hsp_xml->{'Hsp_bit-score'} .';';
+              }
+              
+              // Finally record the range.
+              // @todo figure out why we arbitrarily subtract 50,000 here...
+              // @more removing the 50,000 and using track start/end appears to cause no change...
+              $range_start = (int) $track_start;// - 50000;
+              $range_end = (int) $track_end;// + 50000;
+              if ($range_start < 1) $range_start = 1;
+
+              // Call the function to generate the hit image.
+              $hit_img = generate_blast_hit_image($target_name, $Hsp_bit_score, $hit_hsps,
+                                       $target_size, $query_size, $q_name, $hit_name_short);
+
+              // State what should be in the alignment row for theme_table() later.
+              $alignment_row = array(
+                'data' => array(
+                  'arrow' => array(
+                    'data' => theme('blast_report_alignment_row', array('HSPs' => $HSPs, 'hit_visualization' => $hit_img)),
+                    'colspan' => 5,
+                  ),
+                ),
+                'class' => array('alignment-row', $zebra_class),
+                'no_striping' => TRUE
+              );
 
-  if ($no_hits) {
-    print '<p class="no-hits-message">No results found.</p>';
-  }
-  else {
-    // We want to warn the user if some of their query sequences had no hits.
-    if (!empty($query_with_no_hits)) {
-      print '<p class="no-hits-message">Some of your query sequences did not '
-      . 'match to the database/template. They are: '
-      . implode(', ', $query_with_no_hits) . '.</p>';
+              // LINK-OUTS.
+              // It was determined above whether link-outs were supported for the
+              // tripal blast database used as a search target. Thus we only want to
+              // determine a link-out if it's actually supported... ;-)
+              if ($linkout) {
+
+                // First extract the linkout text using the regex provided through
+                // the Tripal blast database node.
+                if (preg_match($linkout_regex, $hit_name, $linkout_match)) {
+                  $hit->{'linkout_id'} = $linkout_match[1];
+                  $hit->{'hit_name'} = $hit_name;
+
+                  // Allow custom functions to determine the URL to support more complicated
+                  // link-outs rather than just using the tripal database prefix.
+                  $hit_name = call_user_func(
+                    $url_function,
+                    $linkout_urlprefix,
+                    $hit,
+                    array(
+                      'query_name' => $query_name,
+                      'score'      => $score,
+                      'e-value'    => $evalue,
+                      'HSPs'       => $HSPs,
+                      'Target'     => $blast_job->blastdb->db_name,
+                    )
+                  );
+                }
+
+                // Replace the target name with the link.
+                $summary_row['data']['hit']['data'] = $hit_name;
+              }
+
+              // ADD TO TABLE ROWS
+              $rows[] = $summary_row;
+              $rows[] = $alignment_row;
+
+            }//end of if - checks $hit
+          }//end of foreach - iteration_hits
+        }//end of if - check for iteration_hits
+
+        else {
+          // Currently where the "no results" is added.
+          $query_name = $iteration->{'Iteration_query-def'};
+          $query_with_no_hits[] = $query_name;
+
+        }//no results
+      }//end of foreach - BlastOutput_iterations
+
+      if ($no_hits) {
+        print '<p class="no-hits-message">No results found.</p>';
+      }
+      else {
+        // We want to warn the user if some of their query sequences had no hits.
+        if (!empty($query_with_no_hits)) {
+          print '<p class="no-hits-message">Some of your query sequences did not '
+          . 'match to the database/template. They are: '
+          . implode(', ', $query_with_no_hits) . '.</p>';
+        }
+
+        // Actually print the table.
+        if (!empty($rows)) {
+          print theme('table', array(
+            'header' => $header,
+            'rows' => $rows,
+            'attributes' => array('id' => 'blast_report'),
+            'sticky' => FALSE
+          ));
+        }
+      }//handle no hits
+    }//XML exists
+    elseif ($too_many_results) {
+      print '<div class="messages error">Your BLAST resulted in '. number_format(floatval($num_results)) .' results which is too many to reasonably display. We have provided the result files for Download at the top of this page; however, we suggest you re-submit your query using a more stringent e-value (i.e. a smaller number).</div>';
     }
-
-    // Actually print the table.
-    if (!empty($rows)) {
-      print theme('table', array(
-        'header' => $header,
-        'rows' => $rows,
-        'attributes' => array('id' => 'blast_report'),
-        'sticky' => FALSE
-      ));
+    else {
+      drupal_set_title('BLAST: Error Encountered');
+      print '<div class="messages error">We encountered an error and are unable to load your BLAST results.</div>';
     }
-  }//handle no hits
-}//XML exists
-elseif ($too_many_results) {
-  print '<div class="messages error">Your BLAST resulted in '. number_format(floatval($num_results)) .' results which is too many to reasonably display. We have provided the result files for Download at the top of this page; however, we suggest you re-submit your query using a more stringent e-value (i.e. a smaller number).</div>';
-}
-else {
-  drupal_set_title('BLAST: Error Encountered');
-  print '<div class="messages error">We encountered an error and are unable to load your BLAST results.</div>';
-}
-?>
+  ?>
 
-<p><?php print l(
-  'Edit this query and re-submit',
-  $blast_form_url,
-  array('query' => array('resubmit' => blast_ui_make_secret($job_id))));
-?></p>
+  <p><?php print l(
+    'Edit this query and re-submit',
+    $blast_form_url,
+    array('query' => array('resubmit' => blast_ui_make_secret($job_id))));
+  ?></p>
 </div>
 
 <?php print theme('blast_recent_jobs', array()); ?>

+ 6 - 3
theme/blast_ui.theme.inc

@@ -57,7 +57,8 @@ function blast_ui_preprocess_show_blast_report(&$vars) {
 
     $vars['num_results'] = shell_exec('grep -c "<Hit>" ' . escapeshellarg($full_path_xml));
 
-    if ($vars['num_results'] < 500) {
+    $max_results = intval(variable_get('blast_ui_max_results_displayed', 500));
+    if ($vars['num_results'] < $max_results) {
       $vars['xml'] = simplexml_load_file($full_path_xml);
     }
     else {
@@ -128,7 +129,8 @@ function blast_ui_reveal_secret($secret) {
   // Check that the job_id exists if it is an integer.
   if (is_numeric($job_id)) {
 
-    $exists = db_query('SELECT job_id FROM {tripal_jobs} WHERE job_id=:id', array(':id' => $job_id))->fetchField();
+    $exists = db_query('SELECT job_id FROM {tripal_jobs} WHERE job_id=:id', 
+                       array(':id' => $job_id))->fetchField();
     if (!$exists) {
       tripal_report_error(
         'blast_ui',
@@ -146,7 +148,8 @@ function blast_ui_reveal_secret($secret) {
 
     $job_id = base64_decode($secret);
     if (is_numeric($job_id)) {
-      $exists = db_query('SELECT job_id FROM {tripal_jobs} WHERE job_id=:id', array(':id' => $job_id))->fetchField();
+      $exists = db_query('SELECT job_id FROM {tripal_jobs} WHERE job_id=:id', 
+                         array(':id' => $job_id))->fetchField();
       if (!$exists) {
         tripal_report_error(
           'blast_ui',