Sfoglia il codice sorgente

Fixing bug in sequence extractor

Stephen Ficklin 9 anni fa
parent
commit
04fdc885fd

+ 158 - 152
tripal_feature/api/tripal_feature.api.inc

@@ -45,59 +45,67 @@ function tripal_reverse_compliment_sequence($sequence) {
 }
 
 /**
- * Retrieves the sequences for a given feature. If a feature has multiple alignments
- *  or multiple relationships then multiple sequences will be returned.
+ * Retrieves the sequences for a given feature.
+ *
+ * If a feature has multiple alignments or multiple relationships then
+ * multiple sequences will be returned.
  *
  * @param $feature
  *   An associative array describing the feature. Valid keys include:
- *    - feature_id: The feature_id of the feature for which the sequence will be retrieved
+ *    - feature_id: The feature_id of the feature for which the sequence will
+ *      be retrieved
  *    - name: The feature name. This will appear on the FASTA definition line
- *    - parent_id:  (optional) only retrieve a sequence if 'derive_from_parent' is true 
- *        and the parent matches this ID.
- *    - featureloc_id: (optional) only retrieve a sequence if 'derive_from_parent' is 
- *        true and the alignment is defined with this featureloc_id
+ *    - parent_id:  (optional) only retrieve a sequence if 'derive_from_parent'
+ *      is true and the parent matches this ID.
+ *    - featureloc_id: (optional) only retrieve a sequence if 'derive_from_parent' is
+ *      true and the alignment is defined with this featureloc_id
  * @param $options
  *   An associative array of options. Valid keys include:
- *    - width: Indicate the number of bases to use per line.  A new line will be added
- *        after the specified number of bases on each line.
- *    - is_html: Set to '1' if  the sequence is meant to be displayed on a web page.
- *        This will cause a <br> tag to separate lines of the FASTA sequence. 
- *    - derive_from_parent: Set to '1' if the sequence should be obtained from the parent
- *        to which this feature is aligned.
- *    - aggregate: Set to '1' if the sequence should only contain sub features, excluding
- *        intro sub feature sequence.  For example, set this option to obtain just
- *        the coding sequence of an mRNA.
- *    - upstream: An integer specifing the number of upstream bases to include in the output
- *    - downstream: An integer specifying the number of downstream bases to include in the
- *        output.
- *    - sub_feature_types: Only include sub features (or child features) of the types
- *        provided in the array
- *    - relationship_type: If a relationship name is provided (e.g. sequence_of) then any
- *        sequences that are in relationships of this type with matched sequences are also included
- *    - relationship_part: If a relationship is provided in the preceeding argument then
- *        the rel_part must be either 'object' or 'subject' to indicate which side of the
- *        relationship the matched features belong
+ *    - width: Indicate the number of bases to use per line.  A new line will
+ *      be added after the specified number of bases on each line.
+ *    - is_html: Set to '1' if  the sequence is meant to be displayed on a web
+ *      page. This will cause a <br> tag to separate lines of the FASTA sequence.
+ *    - derive_from_parent: Set to '1' if the sequence should be obtained from
+ *      the parent to which this feature is aligned.
+ *    - aggregate: Set to '1' if the sequence should only contain sub features,
+ *      excluding intro sub feature sequence.  For example, set this option to
+ *      obtain just the coding sequence of an mRNA.
+ *    - upstream: An integer specifing the number of upstream bases to include
+ *      in the output
+ *    - downstream: An integer specifying the number of downstream bases to
+ *      include in the output.
+ *    - sub_feature_types: Only include sub features (or child features) of
+ *      the types provided in the array
+ *    - relationship_type: If a relationship name is provided (e.g. sequence_of)
+ *      then any sequences that are in relationships of this type with matched
+ *      sequences are also included
+ *    - relationship_part: If a relationship is provided in the preceeding
+ *      argument then the rel_part must be either 'object' or 'subject' to
+ *      indicate which side of the relationship the matched features belong
  *
  * @return
  *   an array of matching sequence in the following keys for each sequence:
- *      'types'         => an array of feature types that were used to derive the sequence (e.g. from an aggregated sequence)
+ *      'types'         => an array of feature types that were used to derive
+ *         the sequence (e.g. from an aggregated sequence)
  *      'upstream'      => the number of upstream bases included in the sequence
- *      'downstream'    => the number of downstream bases included in the sequence
+ *      'downstream'    => the number of downstream bases included in the
+ *        sequence
  *      'defline'       => the definintion line used to create a FASTA sequence
  *      'residues'      => the residues
- *      'featureloc_id' => the featureloc_id if the sequences is from an alignment
+ *      'featureloc_id' => the featureloc_id if the sequences is from an
+ *        alignment
  *
  * @ingroup tripal_feature_api
  */
 function tripal_get_feature_sequences($feature, $options) {
 
-  // default values for finding the feature
+  // Default values for finding the feature.
   $feature_id         = array_key_exists('feature_id', $feature)     ? $feature['feature_id']     : 0;
   $parent_id          = array_key_exists('parent_id', $feature)      ? $feature['parent_id']      : 0;
   $featureloc_id      = array_key_exists('featureloc_id', $feature)  ? $feature['featureloc_id']  : 0;
   $feature_name       = array_key_exists('name', $feature)           ? $feature['name']           : '';
 
-  // default values for building the sequence
+  // Default values for building the sequence.
   $num_bases_per_line = array_key_exists('width', $options)              ? $options['width']              : 50;
   $derive_from_parent = array_key_exists('derive_from_parent', $options) ? $options['derive_from_parent'] : 0;
   $aggregate          = array_key_exists('aggregate', $options)          ? $options['aggregate']          : 0;
@@ -107,8 +115,15 @@ function tripal_get_feature_sequences($feature, $options) {
   $relationship       = array_key_exists('relationship_type', $options)  ? $options['relationship_type']  : '';
   $rel_part           = array_key_exists('relationship_part', $options)  ? $options['relationship_part']  : '';
   $is_html            = array_key_exists('is_html', $options)            ? $options['is_html']            : 0;
-  
-  // make sure the sub_features variable is an array
+
+  if (!$upstream) {
+    $upstream = 0;
+  }
+  if (!$downstream) {
+    $downstream = 0;
+  }
+
+  // Make sure the sub_features variable is an array.
   if (!is_array($sub_features)) {
     tripal_report_error('tripal_feature', TRIPAL_ERROR,
       "'sub_features' option must be an array for function tripal_get_feature_sequences().",
@@ -117,9 +132,9 @@ function tripal_get_feature_sequences($feature, $options) {
     return array();
   }
 
-  // if a relationship was specified then retreive and the sequences that
-  // have the given relationship and the recurse to extract the appropriate 
-  // sequence
+  // If a relationship was specified then retreive and the sequences that
+  // have the given relationship and the recurse to extract the appropriate
+  // sequence.
   if ($rel_part == "object" or $rel_part == "subject") {
     if ($rel_part == "subject") {
       $sql = '
@@ -154,7 +169,7 @@ function tripal_get_feature_sequences($feature, $options) {
     $sequences = '';
     while ($feature = $features->fetchObject()) {
 
-      // recurse and get the sequences for these in the relationship
+      // Recurse and get the sequences for these in the relationship.
       if ($rel_part == "subject") {
         $defline = "$feature_name, $relationship, $feature->uniquename $feature->feature_type ($feature->genus $feature->species)";
       }
@@ -163,23 +178,23 @@ function tripal_get_feature_sequences($feature, $options) {
       }
       return tripal_get_feature_sequences(
         array(
-          'feature_id' => $feature->feature_id, 
+          'feature_id' => $feature->feature_id,
           'name' => $defline,
           'parent_id' => $parent_id,
         ),
         array(
-          'width' => $num_bases_per_line, 
-          'derive_from_parent' => $derive_from_parent, 
-          'aggregate' => $aggregate, 
-          'upstream' => $upstream, 
-          'downstream' => $downstream, 
-          'sub_features' => $sub_features, 
+          'width' => $num_bases_per_line,
+          'derive_from_parent' => $derive_from_parent,
+          'aggregate' => $aggregate,
+          'upstream' => $upstream,
+          'downstream' => $downstream,
+          'sub_features' => $sub_features,
         )
       );
     }
   }
 
-  // prepare the queries we're going to use later during the render phase
+  // Prepare the queries we're going to use later during the render phase
   // This SQL statement uses conditionals in the select clause to handle
   // cases cases where the alignment is in the reverse direction and when
   // the upstream and downstream extensions go beyond the lenght of the
@@ -251,7 +266,7 @@ function tripal_get_feature_sequences($feature, $options) {
         INNER JOIN {organism} OO  on OF.organism_id   = OO.organism_id
       WHERE SF.feature_id = :feature_id and NOT (OF.residues = \'\' or OF.residues IS NULL)) as tbl1
   ';
-  // this query is meant to get all of the sub features of any given
+  // This query is meant to get all of the sub features of any given
   // feature (arg #1) and order them as they appear on the reference
   // feature (arg #2).
   $sfsql = '
@@ -264,7 +279,7 @@ function tripal_get_feature_sequences($feature, $options) {
     WHERE FR.object_id = :feature_id and PF.feature_id = :srcfeature_id
     ORDER BY FL.fmin ASC
   ';
-  // for counting the number of children
+  // For counting the number of children.
   $fsql ='
     SELECT count(*) as num_children
     FROM {feature_relationship} FR
@@ -275,26 +290,30 @@ function tripal_get_feature_sequences($feature, $options) {
     WHERE FR.object_id = :feature_id and PF.feature_id = :srcfeature_id
   ';
 
-  // the array to be returned
+  // The array to be returned.
   $sequences = array();
-  
-  // if we need to get the sequence from the parent then do so now.
+
+  // If we need to get the sequence from the parent then do so now.
   if ($derive_from_parent) {
 
-    // execute the query to get the sequence from the parent
+    // Execute the query to get the sequence from the parent.
     $parents = chado_query($parent_sql, array(':upstream' => $upstream, ':downstream' => $downstream, ':feature_id' => $feature_id));
     while ($parent = $parents->fetchObject()) {
-      
-      // if the user specified a particular parent and this one doesn't match then skip it
+
+      // If the user specified a particular parent and this one doesn't
+      // match then skip it.
       if ($parent_id and $parent_id != $parent->srcfeature_id) {
         continue;
       }
-      // if the user specified a particular featureloc_id and this one doesn't match then skip it
+      // if the user specified a particular featureloc_id and this one
+      // doesn't match then skip it.
       if ($featureloc_id and $featureloc_id != $parent->featureloc_id) {
         continue;
       }
-      $seq = '';  // initialize the sequence for each parent
+      // Initialize the sequence for each parent.
+      $seq = '';
       $notes = '';
+      $types = array();
 
       // if we are to aggregate then we will ignore the feature returned
       // by the query above and rebuild it using the sub features
@@ -304,17 +323,16 @@ function tripal_get_feature_sequences($feature, $options) {
         $children = chado_query($sfsql, array(':feature_id' => $feature_id, ':srcfeature_id' => $parent->srcfeature_id));
         $num_children = chado_query($fsql, array(':feature_id' => $feature_id, ':srcfeature_id' => $parent->srcfeature_id))->fetchField();
 
-        // iterate through the sub features and concat their sequences. They
+        // Iterate through the sub features and concat their sequences. They
         // should already be in order.
-        $types = array();
         $i = 0;
         while ($child = $children->fetchObject()) {
-          // if the callee has specified that only certain sub features should be
+          // If the callee has specified that only certain sub features should be
           // included then continue if this child is not one of those allowed
-          // subfeatures
+          // subfeatures.
           if (count($sub_features) > 0 and !in_array($child->type_name, $sub_features)) {
             $i++;
-             continue;
+            continue;
           }
 
           // keep up with the types
@@ -360,7 +378,7 @@ function tripal_get_feature_sequences($feature, $options) {
             if ($subseq->srcfeature_id == $parent->srcfeature_id) {
               $seq .= $subseq->residues;
             }
-            if ($subseq->upstream > 0 ) { 
+            if ($subseq->upstream > 0 ) {
               $notes .= "Includes " . $subseq->upstream . " bases upstream.  ";
             }
             if ($subseq->downstream > 0) {
@@ -403,9 +421,9 @@ function tripal_get_feature_sequences($feature, $options) {
         $notes .= "Excludes all bases but those of type(s): " . implode(', ', $types) . ". " ;
       }
 
-      // construct the definition line for this feature.
-      // to construct the defline we need a featureloc record, so we'll create one using
-      // the information we have
+      // Construct the definition line for this feature. To construct the
+      // defline we need a featureloc record, so we'll create one using
+      // the information we have.
       $featureloc = new stdClass;
       $featureloc->feature_id = $feature;
       $featureloc->fmin = $parent->adjfmin;
@@ -417,10 +435,10 @@ function tripal_get_feature_sequences($feature, $options) {
       $featureloc->srcfeature_id->organism_id = new stdClass;
       $featureloc->srcfeature_id->organism_id->genus = $parent->genus;
       $featureloc->srcfeature_id->organism_id->species = $parent->species;
-      // get a proper feature object
+      // Get a proper feature object.
       $f = chado_generate_var('feature', array('feature_id' => $feature_id));
       $defline = tripal_get_fasta_defline($f, $notes, $featureloc, '', $length);
-      
+
       $sequences[] = array(
         'types'         => $types,
         'upstream'      => $parent->upstream,
@@ -432,12 +450,14 @@ function tripal_get_feature_sequences($feature, $options) {
       );
     }
   }
-  // if we are not getting the sequence from the parent sequence then
-  // use what comes through from the feature record
+  // If we are not getting the sequence from the parent sequence then
+  // use what comes through from the feature record.
   else {
-    $sql = "SELECT * FROM {feature} F WHERE feature_id = :feature_id";
-    $values = chado_query($sql, array(':feature_id' => $feature_id))->fetchObject();
-    $residues = $values->residues;
+
+    $f = chado_generate_var('feature', array('feature_id' => $feature_id));
+    $f = chado_expand_var($f, 'field', 'feature.residues');
+
+    $residues = $f->residues;
     $length = strlen($residues);
     if ($is_html) {
       $residues = wordwrap($residues, $num_bases_per_line, "<br>", TRUE);
@@ -445,14 +465,13 @@ function tripal_get_feature_sequences($feature, $options) {
     else {
       $residues = wordwrap($residues, $num_bases_per_line, "\r\n", TRUE);
     }
-    
+
     // get the definintion line for this feature
-    $f = chado_generate_var('feature', array('feature_id' => $feature_id));
     $defline = tripal_get_fasta_defline($f, '', NULL, '', $length);
 
     // add to the sequence array
     $sequences[] = array(
-      'types'      => $values->type,
+      'types'      => $f->type_id->name,
       'upstream'   => 0,
       'downstream' => 0,
       'defline'    => $defline,
@@ -465,49 +484,52 @@ function tripal_get_feature_sequences($feature, $options) {
 }
 
 /**
- * Retreives or prints multiple sequences from features found using the options provided.
  *
  * @param $options
  *   An associative array of options for selecting a feature. Valid keys include:
- *    - org_commonname: The common name of the organism for which sequences should be retrieved
+ *    - org_commonname: The common name of the organism for which sequences
+ *      should be retrieved
  *    - genus: The genus of the organism for which sequences should be retrieved
- *    - species: The species of the organism for which sequences should be retrieved
- *    - analysis_name: The name of an analysis to which sequences belong. Only those that are
- *        associated with the analysis will be retrieved.
+ *    - species: The species of the organism for which sequences should be
+ *      retrieved
+ *    - analysis_name: The name of an analysis to which sequences belong. Only
+ *      those that are associated with the analysis will be retrieved.
  *    - type: The type of feature (a sequence ontology term).
  *    - feature_name: the name of the feature. Can be an array of feature names.
- *    - feature_uname: the uniquename of the feature.  Can be an array of feature unique names.
- *    - upstream: An integer specifing the number of upstream bases to include in the output
- *    - downstream: An integer specifying the number of downstream bases to include in the
- *        output.
- *    - derive_from_parent: Set to '1' if the sequence should be obtained from the parent
- *        to which this feature is aligned.
- *    - aggregate: Set to '1' if the sequence should only contain sub features, excluding
- *        intro sub feature sequence.  For example, set this option to obtain just
- *        the coding sequence of an mRNA.
- *    - sub_feature_types: Only include sub features (or child features) of the types
- *        provided in the array
- *    - relationship_type: If a relationship name is provided (e.g. sequence_of) then any
- *        sequences that are in relationships of this type with matched sequences are also included
- *    - relationship_part: If a relationship is provided in the preceeding argument then
- *        the rel_part must be either 'object' or 'subject' to indicate which side of the
- *        relationship the matched features belong
- *    - width: Indicate the number of bases to use per line.  A new line will be added
- *        after the specified number of bases on each line.
- *    - is_html: Set to '1' if  the sequence is meant to be displayed on a web page.
- *        This will cause a <br> tag to separate lines of the FASTA sequence. 
- *    - print: Set to TRUE to print the sequences rather otherwise an array
- *        of sequences will be returned.  
+ *    - feature_uname: the uniquename of the feature.  Can be an array of
+ *      feature unique names.
+ *    - upstream: An integer specifing the number of upstream bases to include
+ *      in the output
+ *    - downstream: An integer specifying the number of downstream bases to
+ *      include in the output.
+ *    - derive_from_parent: Set to '1' if the sequence should be obtained from
+ *      the parent to which this feature is aligned.
+ *    - aggregate: Set to '1' if the sequence should only contain sub features,
+ *      excluding intro sub feature sequence.  For example, set this option to
+ *      obtain just the coding sequence of an mRNA.
+ *    - sub_feature_types: Only include sub features (or child features) of
+ *      the types provided in the array
+ *    - relationship_type: If a relationship name is provided (e.g. sequence_of)
+ *      then any sequences that are in relationships of this type with matched
+ *      sequences are also included
+ *    - relationship_part: If a relationship is provided in the preceeding
+ *      argument then the rel_part must be either 'object' or 'subject' to
+ *      indicate which side of the relationship the matched features belong
+ *    - width: Indicate the number of bases to use per line.  A new line will
+ *      be added after the specified number of bases on each line.
+ *    - is_html: Set to '1' if  the sequence is meant to be displayed on a
+ *      web page. This will cause a <br> tag to separate lines of the FASTA
+ *      sequence.
  * @return
- *   Returns an array of sequences unless the option 'print' is used.  If 'print is used
- *   then nothing is returned but sequences are printed to STDOUT.  If returned, the 
- *   sequences will be in an array with the following keys for each sequence:
- *      'types'         => an array of feature types that were used to derive the sequence (e.g. from an aggregated sequence)
- *      'upstream'      => the number of upstream bases included in the sequence
- *      'downstream'    => the number of downstream bases included in the sequence
+ *   Returns an array of sequences. The sequences will be in an array with the
+ *   following keys for each sequence:
+ *      'types'         => an array of feature types that were used to derive
+ *         the sequence (e.g. from an aggregated sequence)
+ *      'upstream'      => the number of upstream bases in the sequence
+ *      'downstream'    => the number of downstream bases in the sequence
  *      'defline'       => the definintion line used to create a FASTA sequence
  *      'residues'      => the residues
- *      'featureloc_id' => the featureloc_id if the sequences is from an alignment
+ *      'featureloc_id' => the featureloc_id if from an alignment
  *
  * @ingroup tripal_feature_api
  */
@@ -529,13 +551,6 @@ function tripal_get_bulk_feature_sequences($options) {
   $num_bases_per_line = array_key_exists('width', $options)              ? $options['width']              : 50;
   $upstream           = array_key_exists('upstream', $options)           ? $options['upstream']       : 0;
   $downstream         = array_key_exists('downstream', $options)         ? $options['downstream']     : 0;
-  $print              = array_key_exists('print', $options)              ? $options['print']              : FALSE;
-
-  $sub_features = explode(',', $child);
-
-  if (!$output_format) {
-    $output_format = 'fasta_txt';
-  }
 
   if (!$type and !$feature_name and !$genus) {
     print "Please provide a type, feature name or genus\n";
@@ -544,13 +559,18 @@ function tripal_get_bulk_feature_sequences($options) {
 
   // get the list of features
   $vars = array();
-  $sql  = "SELECT DISTINCT F.feature_id, F.name, F.uniquename, O.genus, O.species, CVT.name as feature_type " .
-      "FROM {feature} F " .
-      "  INNER JOIN {organism} O on O.organism_id = F.organism_id " .
-      "  INNER JOIN {cvterm} CVT on CVT.cvterm_id = F.type_id ";
+  $sql  = "
+    SELECT DISTINCT F.feature_id, F.name, F.uniquename,
+      O.genus, O.species, CVT.name as feature_type
+    FROM {feature} F
+      INNER JOIN {organism} O on O.organism_id = F.organism_id
+      INNER JOIN {cvterm} CVT on CVT.cvterm_id = F.type_id
+  ";
   if ($analysis_name) {
-    $sql .= "  INNER JOIN {analysisfeature} AF on AF.feature_id = F.feature_id " .
-        "  INNER JOIN {analysis} A on AF.analysis_id = A.analysis_id ";
+    $sql .= "
+      INNER JOIN {analysisfeature} AF on AF.feature_id = F.feature_id
+      INNER JOIN {analysis} A on AF.analysis_id = A.analysis_id
+    ";
   }
   $sql .= "WHERE (1=1) ";
   if ($org_commonname) {
@@ -607,35 +627,21 @@ function tripal_get_bulk_feature_sequences($options) {
   $num_seqs = 0;
   $q = chado_query($sql, $vars);
 
-
   $sequences = array();
   while ($feature = $q->fetchObject()) {
-
+    dpm($feature);
     // get the sequences
     $seqs = tripal_get_feature_sequences(array('feature_id' => $feature->feature_id), $options);
-
-    if ($print) {
-      foreach ($seqs as $seq) {
-        print ">" . $seq['defline'] . "\n";
-        print $seq['residues'] . "\n";
-      }
-    }
-    else {
-      $sequences = array_merge($sequences, $seqs);
-    }
+    $sequences = array_merge($sequences, $seqs);
     $num_seqs++;
   }
-  if (!$print) {
-    return $seqs;
-  }
-  elseif ($num_seqs == 0) {
-    print "No Sequences Found";
-  }
+
+  return $sequences;
 }
 
 /**
  * Returns a definition line that can be used in a FASTA file
- * 
+ *
  * @param $feature
  *   A single feature object containing all the fields from the chado.feature table.
  *   Best case is to provide an object generated by the chado_generate_var() function.
@@ -650,13 +656,13 @@ function tripal_get_bulk_feature_sequences($options) {
  *   Optional: the type of sequence. By default the feature type is used.
  * @param $length
  *   Optional: the length of the sequence
- *   
+ *
  * @return
  *   A string of the format: uniquename|name|type|feature_id
- *   or if an alignment:  srcfeature_name:fmin..fmax[+-]; alignment of uniquename|name|type|feature_id 
+ *   or if an alignment:  srcfeature_name:fmin..fmax[+-]; alignment of uniquename|name|type|feature_id
  */
 function tripal_get_fasta_defline($feature, $notes = '', $featureloc = NULL, $type = '', $length = 0) {
-    
+
   // make sure the featureloc object has the srcfeature if not, then add it
   if ($featureloc) {
     if (!is_object($featureloc->srcfeature_id)) {
@@ -670,18 +676,18 @@ function tripal_get_fasta_defline($feature, $notes = '', $featureloc = NULL, $ty
   if (!is_object($feature->organism_id)) {
     $feature->organism_id = chado_generate_var('organism', array('organism_id' => $feature->organism_id));
   }
-  
+
   // if a type is not provided then use the default type
   if (!$type) {
     $type = $feature->type_id->name;
   }
-  
+
   // construct the definition line
-  $defline = $feature->uniquename . " " . 
+  $defline = $feature->uniquename . " " .
              'ID=' . $feature->uniquename . "|" .
-             'Name=' . $feature->name . "|" . 
+             'Name=' . $feature->name . "|" .
              'organism=' . $feature->organism_id->genus . " " . $feature->organism_id->species .  "|" .
-             'type=' . $type . '|'; 
+             'type=' . $type . '|';
   if ($length > 0) {
     $defline .= "length=" . $length . "bp|";
   }
@@ -698,14 +704,14 @@ function tripal_get_fasta_defline($feature, $notes = '', $featureloc = NULL, $ty
 
 /**
  * Returns a string representing a feature location in an alignment
- *  
+ *
  * @param unknown $featureloc
  *   A single featureloc object generated using chado_generate_var that
  *   contains a record from the chado.featureloc table.
  */
 function tripal_get_location_string($featureloc) {
   $feature = $featureloc->feature_id;
-  
+
   $strand = '';
   if ($featureloc->strand == 1) {
     $strand = '+';
@@ -713,7 +719,7 @@ function tripal_get_location_string($featureloc) {
   elseif ($featureloc->strand == -1) {
     $strand = '-';
   }
-  
-  return $featureloc->srcfeature_id->name . ":" . ($featureloc->fmin + 1) . ".." . $featureloc->fmax .  $strand;  
+
+  return $featureloc->srcfeature_id->name . ":" . ($featureloc->fmin + 1) . ".." . $featureloc->fmax .  $strand;
 }
 

+ 239 - 208
tripal_feature/includes/tripal_feature.seq_extract.inc

@@ -9,169 +9,149 @@
  *
  * @ingroup tripal_feature
  */
-function tripal_feature_seq_extract_page() {
-
-  if ($_SESSION['tripal_feature_seq_extract']['download']) {
-    $genus      = $_SESSION['tripal_feature_seq_extract']['genus'];
-    $species    = $_SESSION['tripal_feature_seq_extract']['species'];
-    $analysis   = $_SESSION['tripal_feature_seq_extract']['analysis'];
-    $ftype      = $_SESSION['tripal_feature_seq_extract']['ftype'];
-    $fnames     = $_SESSION['tripal_feature_seq_extract']['fnames'];
-    $upstream   = $_SESSION['tripal_feature_seq_extract']['upstream'];
-    $downstream = $_SESSION['tripal_feature_seq_extract']['downstream'];
-    $format     = $_SESSION['tripal_feature_seq_extract']['format'];
-    $use_parent = $_SESSION['tripal_feature_seq_extract']['use_parent'];
-    $aggregate  = $_SESSION['tripal_feature_seq_extract']['aggregate'];
-    $agg_types  = $_SESSION['tripal_feature_seq_extract']['agg_types'];
-
-    unset($_SESSION['tripal_feature_seq_extract']['download']);
-
-    if ($format == 'fasta_html') {
-      drupal_add_http_header('Content-Type: text/html');
-    }
-    else {
-      drupal_add_http_header('Content-Type: text');
-      drupal_add_http_header('Content-Disposition: attachment; filename="sequences.fasta.txt"');
-    }
+function tripal_feature_seq_extract_download() {
 
-    tripal_get_bulk_feature_sequences(array(
-      'genus' => $genus, 
-      'species' => $species, 
-      'analysis_name' => $analysis,
-      'type' => $ftype, 
-      'feature_name' => $fnames['items_array'], 
-      'upstream' => $upstream, 
-      'downstream' => $downstream, 
-      'print' => 1,
-      'output_format' => $format, 
-      'derive_from_parent' => $use_parent, 
-      'aggregate' => $aggregate,
-      'sub_feature_types' => $agg_types
-    ));
-
-    return;
+  if (!array_key_exists('tripal_feature_seq_extract', $_SESSION)) {
+    drupal_goto('find/sequences');
   }
 
+  $genus      = $_SESSION['tripal_feature_seq_extract']['genus'];
+  $species    = $_SESSION['tripal_feature_seq_extract']['species'];
+  $analysis   = $_SESSION['tripal_feature_seq_extract']['analysis'];
+  $ftype      = $_SESSION['tripal_feature_seq_extract']['ftype'];
+  $fnames     = $_SESSION['tripal_feature_seq_extract']['fnames'];
+  $upstream   = $_SESSION['tripal_feature_seq_extract']['upstream'];
+  $downstream = $_SESSION['tripal_feature_seq_extract']['downstream'];
+  $format     = $_SESSION['tripal_feature_seq_extract']['format'];
+  $use_parent = $_SESSION['tripal_feature_seq_extract']['use_parent'];
+  $aggregate  = $_SESSION['tripal_feature_seq_extract']['aggregate'];
+  $agg_types  = $_SESSION['tripal_feature_seq_extract']['agg_types'];
+
+  // Split the sub features and remove any surrounding white space
+  $agg_types = preg_split("/[\n|,]/", $agg_types);
+  for ($i = 0; $i < count($agg_types); $i++) {
+    $agg_types[$i] = trim($agg_types[$i]);
+  }
 
-  // generate the search form
-  $output .= '';
-  if (user_access('administer tripal')) {
-    $output .= tripal_set_message("Administrators, the " . 
-        l('organism_feature_count', 'admin/tripal/schema/mviews') . " and " .
-        l('analysis_organism', 'admin/tripal/schema/mviews') . " materialized
-        views must be populated before using this form.  Those views should be re-populated
-        when new data is added.");
+
+
+  header('Content-Type: text; utf-8');
+  if ($ftype == 'polypeptide') {
+    header('Content-Disposition: attachment; filename="sequences.fna"');
+  }
+  else {
+    header('Content-Disposition: attachment; filename="sequences.fnn"');
   }
-  $output .= "<div id=\"tripal-feature-seq-extract-form-block\">";
-  $output .= drupal_get_form('tripal_feature_seq_extract_form');
-  $output .= "</div>";
-  return $output;
-}
 
-/**
- * Theme the Form to choose which features to extract sequence for
- *
- * @ingroup tripal_feature
- */
-function theme_tripal_feature_seq_extract_form($form, &$form_state) {
-  $rows = array(
-    0 => array(
-      array('data' => drupal_render($form['description']), 'colspan' => 3),
-    ),
-    1 => array(
-      drupal_render($form['genus']),
-      drupal_render($form['species']) ,
-      drupal_render($form['ftype']),
-    ),
-    2 => array(
-      array('data' => drupal_render($form['analysis']), 'colspan' => 3),
-      //drupal_render($form['format']),
-    ),
-    3 => array(
-      array('data' =>  drupal_render($form['fnames']), 'colspan' => 2),
-      drupal_render($form['upstream']) . drupal_render($form['downstream']) ,
-    ),
-    4 => array(
-      array(
-        'data' =>  drupal_render($form['advanced']),
-        'colspan' => 3,
-      ),
-    ),
-    5 => array(
-      array(
-        'data' =>  drupal_render($form['retrieve_btn']) . drupal_render($form['reset_btn']),
-        'colspan' => 3,
-      ),
-    ),
-  );
-  $headers = array();
-  $table = theme('table', $headers, $rows, array('id' => 'tripal-feature-seq-extract-form-table', 'border' => '0'));
+  $seqs = tripal_get_bulk_feature_sequences(array(
+    'genus' => $genus,
+    'species' => $species,
+    'analysis_name' => $analysis,
+    'type' => $ftype,
+    'feature_name' => $fnames['items_array'],
+    'upstream' => $upstream,
+    'downstream' => $downstream,
+    'output_format' => $format,
+    'derive_from_parent' => $use_parent,
+    'aggregate' => $aggregate,
+    'sub_feature_types' => $agg_types,
+    'width' => 60
+  ));
+
+  if (count($seqs) == 0) {
+    print ">No sequences found that match the criteria.";
+  }
 
-  $markup .= $table;
-  $form['criteria'] = array(
-    '#markup' =>  $markup,
-    '#weight' => -10,
-  );
-  return drupal_render($form);
+  foreach ($seqs as $seq) {
+    print ">" . $seq['defline'] . "\r\n";
+    print $seq['residues'] . "\r\n";
+  }
 }
 
+
+
 /**
  * Form to choose which features to extract sequence for
  *
  * @ingroup tripal_feature
  */
-function tripal_feature_seq_extract_form(&$form_state = NULL) {
-  tripal_core_ahah_init_form();
+function tripal_feature_seq_extract_form($form, &$form_state) {
+
+  $form['#true'] = TRUE;
+
+  // Intialize the defaults
+  $dgenus      = '';
+  $dspecies    = '';
+  $danalysis   = '';
+  $dftype      = '';
+  $dfnames     = '';
+  $dupstream   = '';
+  $ddownstream = '';
+  $duse_parent = '';
+  $daggregate  = '';
+  $dagg_types  = '';
+
+  if (array_key_exists('tripal_feature_seq_extract', $_SESSION)) {
+    $dgenus      = $_SESSION['tripal_feature_seq_extract']['genus'];
+    $dspecies    = $_SESSION['tripal_feature_seq_extract']['species'];
+    $danalysis   = $_SESSION['tripal_feature_seq_extract']['analysis'];
+    $dftype      = $_SESSION['tripal_feature_seq_extract']['ftype'];
+    $dfnames     = $_SESSION['tripal_feature_seq_extract']['fnames'];
+    $dupstream   = $_SESSION['tripal_feature_seq_extract']['upstream'];
+    $ddownstream = $_SESSION['tripal_feature_seq_extract']['downstream'];
+    $duse_parent = $_SESSION['tripal_feature_seq_extract']['use_parent'];
+    $daggregate  = $_SESSION['tripal_feature_seq_extract']['aggregate'];
+    $dagg_types  = $_SESSION['tripal_feature_seq_extract']['agg_types'];
+  }
 
   // we want to allow the query string to provide values for the form
-  if ($_GET['fnames']) {
-    $form_state['values']['fnames']['items'] = $_GET['fnames'];
+  if (array_key_exists('fnames', $_GET) and $_GET['fnames']) {
+    $dfnames = $_GET['fnames'];
   }
-  if ($_GET['genus']) {
-    $form_state['values']['genus'] = $_GET['genus'];
+  if (array_key_exists('genus', $_GET) and $_GET['genus']) {
+    $dgenus = $_GET['genus'];
   }
-  if ($_GET['species']) {
-    $form_state['values']['species'] = $_GET['species'];
+  if (array_key_exists('species', $_GET) and $_GET['species']) {
+    $dspecies = $_GET['species'];
   }
-  if ($_GET['ftype']) {
-    $form_state['values']['ftype'] = $_GET['ftype'];
+  if (array_key_exists('ftype', $_GET) and $_GET['ftype']) {
+    $dftype = $_GET['ftype'];
   }
-  if ($_GET['analysis']) {
-    $form_state['values']['analysis'] = $_GET['analysis'];
+  if (array_key_exists('analysis', $_GET) and $_GET['analysis']) {
+    $danalysis = $_GET['analysis'];
   }
-  if ($_GET['upstream']) {
-    $form_state['values']['upstream'] = $_GET['upstream'];
+  if (array_key_exists('upstream', $_GET) and $_GET['upstream']) {
+    $dupstream = $_GET['upstream'];
   }
-  if ($_GET['downstream']) {
-    $form_state['values']['downstream'] = $_GET['downstream'];
+  if (array_key_exists('downstream', $_GET) and $_GET['downstream']) {
+    $ddownstream = $_GET['downstream'];
   }
-  if ($_GET['use_parent']) {
-    $form_state['values']['use_parent'] = $_GET['use_parent'];
+  if (array_key_exists('use_parent', $_GET) and $_GET['use_parent']) {
+    $duse_parent = $_GET['use_parent'];
   }
-  if ($_GET['aggregate']) {
-    $form_state['values']['aggregate'] = $_GET['aggregate'];
+  if (array_key_exists('aggregate', $_GET) and $_GET['aggregate']) {
+    $daggregate = $_GET['aggregate'];
   }
-  if ($_GET['agg_types']) {
-    $form_state['values']['agg_types'] = $_GET['agg_types'];
+  if (array_key_exists('agg_types', $_GET) and $_GET['agg_types']) {
+    $dagg_types = $_GET['agg_types'];
   }
 
-  // get defaults
-  $dgenus      = isset($form_state['values']['genus'])      ? $form_state['values']['genus']      : $_SESSION['tripal_feature_seq_extract']['genus'];
-  $dspecies    = isset($form_state['values']['species'])    ? $form_state['values']['species']    : $_SESSION['tripal_feature_seq_extract']['species'];
-  $danalysis   = isset($form_state['values']['analysis'])   ? $form_state['values']['analysis']   : $_SESSION['tripal_feature_seq_extract']['analysis'];
-  $dftype      = isset($form_state['values']['ftype'])      ? $form_state['values']['ftype']      : $_SESSION['tripal_feature_seq_extract']['ftype'];
-  $dfnames     = isset($form_state['values']['fnames'])     ? $form_state['values']['fnames']     : $_SESSION['tripal_feature_seq_extract']['fnames'];
-  $dupstream   = isset($form_state['values']['upstream'])   ? $form_state['values']['upstream']   : $_SESSION['tripal_feature_seq_extract']['upstream'];
-  $ddownstream = isset($form_state['values']['downstream']) ? $form_state['values']['downstream'] : $_SESSION['tripal_feature_seq_extract']['downstream'];
-  $dformat     = isset($form_state['values']['format'])     ? $form_state['values']['format']     : 'fasta_txt';
-  $duse_parent = isset($form_state['values']['use_parent']) ? $form_state['values']['use_parent'] : $_SESSION['tripal_feature_seq_extract']['use_parent'];
-  $daggregate  = isset($form_state['values']['aggregate'])  ? $form_state['values']['aggregate']  : $_SESSION['tripal_feature_seq_extract']['aggregate'];
-  $dagg_types  = isset($form_state['values']['agg_types'])  ? $form_state['values']['agg_types']  : $_SESSION['tripal_feature_seq_extract']['agg_types'];
-
-
-  $form = array();
+  // get defaults from the form state
+  if (array_key_exists('values', $form_state)) {
+    $dgenus      = $form_state['values']['genus'];
+    $dspecies    = $form_state['values']['species'];
+    $danalysis   = $form_state['values']['analysis'];
+    $dftype      = $form_state['values']['ftype'];
+    $dfnames     = $form_state['values']['fnames'];
+    $dupstream   = $form_state['values']['upstream'];
+    $ddownstream = $form_state['values']['downstream'];
+    $dformat     = $form_state['values']['format'];
+    $duse_parent = $form_state['values']['use_parent'];
+    $daggregate  = $form_state['values']['aggregate'];
+    $dagg_types  = $form_state['values']['agg_types'];
+  }
 
-  // because we're using Tripal's file_upload_combo form element we
+  // Because we're using Tripal's file_upload_combo form element we
   // need to allow the form to upload files
   $form['#attributes']['enctype'] = 'multipart/form-data';
   $form['#method'] = 'POST';
@@ -199,9 +179,9 @@ function tripal_feature_seq_extract_form(&$form_state = NULL) {
     '#default_value' => $dgenus,
     '#multiple'      => FALSE,
     '#description'   => t('The organism\'s genus. If specified, features for all organism with this genus will be retrieved.'),
-    '#ahah' => array(
-      'path'    => 'find/sequences/ajax',
-      'wrapper' => 'tripal-feature-seq-extract-form-block',
+    '#ajax' => array(
+      'callback'    => 'tripal_feature_seq_extract_form_ajax_callback',
+      'wrapper' => 'tripal-feature-seq-extract-form',
       'event'   => 'change',
       'method'  => 'replace',
     ),
@@ -228,9 +208,9 @@ function tripal_feature_seq_extract_form(&$form_state = NULL) {
     '#default_value' => $dspecies,
     '#multiple'      => FALSE,
     '#description'   => t('The organism\'s species name. If specified, features for all organisms with this species will be retrieved.  Please first select a genus'),
-    '#ahah' => array(
-      'path'    => 'find/sequences/ajax',
-      'wrapper' => 'tripal-feature-seq-extract-form-block',
+    '#ajax' => array(
+      'callback'    => 'tripal_feature_seq_extract_form_ajax_callback',
+      'wrapper' => 'tripal-feature-seq-extract-form',
       'event'   => 'change',
       'method'  => 'replace',
     ),
@@ -294,39 +274,37 @@ function tripal_feature_seq_extract_form(&$form_state = NULL) {
     '#options'       => $ftype,
     '#multiple'      => FALSE,
     '#default_value' => $dftype,
-    '#description'   => t('The type of feature to retrieve (e.g. mRNA). All features that match this type will be retrieved.'),
+    '#description'   => t('The type of feature to retrieve (e.g. mRNA). All
+        features that match this type will be retrieved.'),
   );
 
   $form['fnames'] = array(
     '#title'         => t('Feature Name'),
     '#type'          => 'file_upload_combo',
     '#default_value' => $dfnames,
-    '#description'   => t('The names of the features to retrieve. Separate each with a new line or comma. Leave blank to retrieve all features matching other criteria.'),
+    '#description'   => t('The names of the features to retrieve. Separate each
+         with a new line or comma. Leave blank to retrieve all features
+        matching other criteria.'),
     '#rows'          => 8
   );
   $form['upstream'] = array(
     '#title'         => t('Upstream Bases'),
     '#type'          => 'textfield',
-    '#description'   => t('A numeric value specifying the number of upstream bases to include. Only works if the feature is aligned to a larger sequence.'),
+    '#description'   => t('A numeric value specifying the number of upstream
+         bases to include. Only works if the feature is aligned to a larger
+         sequence.'),
     '#default_value' => $dupstream,
     '#size'          => 5,
   );
   $form['downstream'] = array(
     '#title'         => t('Downstream Bases'),
     '#type'          => 'textfield',
-    '#description'   => t('A numeric value specifying the number of downstream bases to incldue.  Only works if the feature is aligned to a larger sequence.'),
+    '#description'   => t('A numeric value specifying the number of downstream
+        bases to incldue.  Only works if the feature is aligned to a larger
+        sequence.'),
     '#default_value' => $ddownstream,
     '#size'          => 5,
   );
-  $form['format'] = array(
-    '#title'         => t('Output Format'),
-    '#type'          => 'hidden',
-    '#default_value' => $dformat,
-    '#options'       => array(
-      'fasta_html'  => 'FASTA (in browser)',
-      'fasta_txt'   => 'FASTA (download)',
-    ),
-  );
   $form['advanced'] = array(
     '#type' => 'fieldset',
     '#title' => 'Advanced',
@@ -338,64 +316,115 @@ function tripal_feature_seq_extract_form(&$form_state = NULL) {
     '#title'         => t('Use Parent'),
     '#type'          => 'checkbox',
     '#default_value' => $duse_parent,
-    '#description'   => t('Check this box to retrieve the sequence from the parent in an alignment rather than the feature itself. This is useful if the same feature is aligned to multiple parents and you would like to retrieve the underlying sequence from each parent.'),
+    '#description'   => t('Check this box to retrieve the sequence from the
+        parent in an alignment rather than the feature itself. This is useful
+        if the same feature is aligned to multiple parents and you would like
+        to retrieve the underlying sequence from each parent.'),
   );
   $form['advanced']['aggregate'] = array(
     '#title'         => t('Aggregate'),
     '#type'          => 'checkbox',
     '#default_value' => $daggregate,
-    '#description'   => t('Check this box to aggregate sub features into a single sequence.  This is useful, for example, for obtaining CDS sequence from an mRNA. Rather than retrieve the mRNA sequence, the sub features of the mRNA will be aggregated and that will be returned.')
+    '#description'   => t('Check this box to aggregate sub features into a
+        single sequence.  This is useful, for example, for obtaining CDS
+        sequence from an mRNA. Rather than retrieve the mRNA sequence, the
+        sub features of the mRNA will be aggregated and that will be returned.')
   );
   $form['advanced']['agg_types'] = array(
     '#title'         => t('Types to aggregate'),
     '#type'          => 'textarea',
     '#default_value' => $dagg_types,
-    '#description'   => t('Set this argument to the type of children to aggregate.  This is useful in the case where a gene has exons, CDSs and UTRs.  In this case, you may only want to aggregate CDSs and exclude exons.  If you want to aggregate both CDSs and UTRs you could specify both.')
+    '#description'   => t('Set this argument to the type of children to
+        aggregate.  This is useful in the case where a gene has exons, CDSs
+        and UTRs.  In this case, you may only want to aggregate CDSs and
+        exclude exons.  If you want to aggregate both CDSs and UTRs you
+        could specify both.  Please place each type on a new line.')
   );
   $form['retrieve_btn'] = array(
     '#type' => 'submit',
-    '#value' => 'Retrieve',
-  );
-  $form['reset_btn'] = array(
-    '#type' => 'submit',
-    '#value' => 'Reset',
+    '#name' => 'retrieve',
+    '#value' => 'Retrieve Sequences',
   );
+
+  if (user_access('administer tripal')) {
+    $notice = tripal_set_message("Administrators, the " .
+        l('organism_feature_count', 'admin/tripal/schema/mviews') . " and " .
+        l('analysis_organism', 'admin/tripal/schema/mviews') . " materialized
+        views must be populated before using this form.  Those views should be re-populated
+        when new data is added.", TRIPAL_NOTICE, array('return_html' => TRUE));
+  }
+
+  $form['#prefix'] = '<div id="tripal-feature-seq-extract-form">';
+  $form['#suffix'] = $notice . '</div>';
+
   return $form;
 }
 
 /**
- * AJAX callback
+ * Theme the Form to choose which features to extract sequence for
  *
  * @ingroup tripal_feature
  */
-function tripal_feature_seq_extract_form_ahah_update() {
-  $status = TRUE;
-
-  // prepare and render the form. If no form is returned that means
-  // we got here by an AHAH call after the form has been submitted.  This
-  // is possible because results are downloaded and the page is not refreshed
-  // but the form_id goes away.  So, we need to rebuild the form in this case.
-  // otherwise, if the form already exists we just theme it.
-  $form = tripal_core_ahah_prepare_form();
-  if ($form) {
-    $data = theme('tripal_feature_seq_extract_form', $form);
-  }
-  else {
-    $data = drupal_get_form('tripal_feature_seq_extract_form');
-  }
+function theme_tripal_feature_seq_extract_form(&$variables) {
+  $form = $variables['form'];
+
+  $headers = array();
+  $rows = array(
+    0 => array(
+      array('data' => drupal_render($form['description']), 'colspan' => 3),
+    ),
+    1 => array(
+      drupal_render($form['genus']),
+      drupal_render($form['species']) ,
+      drupal_render($form['ftype']),
+    ),
+    2 => array(
+      array('data' => drupal_render($form['analysis']), 'colspan' => 3),
+      //drupal_render($form['format']),
+    ),
+    3 => array(
+      array('data' =>  drupal_render($form['fnames']), 'colspan' => 2),
+      drupal_render($form['upstream']) .
+      drupal_render($form['downstream']) .
+      drupal_render($form['format']),
+    ),
+    4 => array(
+      array(
+        'data' =>  drupal_render($form['advanced']),
+        'colspan' => 3,
+      ),
+    ),
+    5 => array(
+      array(
+        'data' =>  drupal_render($form['retrieve_btn']) . drupal_render($form['reset_btn']),
+        'colspan' => 3,
+      ),
+    ),
+  );
+
+  $table_vars = array(
+    'header' => $headers,
+    'rows' => $rows,
+    'attributes' => array(
+      'id' => 'tripal-feature-seq-extract-form-table',
+      'border' => '0'
+    ),
+    'sticky' => FALSE,
+    'colgroups' => array(),
+    'empty' => '',
+  );
 
-  // bind javascript events to the new objects that will be returned
-  // so that AHAH enabled elements will work.
-  $settings = tripal_core_ahah_bind_events();
-
-  // return the updated JSON
-  drupal_json(
-    array(
-      'status'   => $status,
-      'data'     => $data,
-      'settings' => $settings,
-    )
+  $form['rendered_form'] = array(
+    '#type' => 'item',
+    '#markup' => theme('table', $table_vars),
   );
+  return drupal_render_children($form);
+}
+/**
+ * Ajax function which returns the form via ajax
+ */
+function tripal_feature_seq_extract_form_ajax_callback($form, &$form_state) {
+  return $form;
 }
 
 /**
@@ -411,22 +440,27 @@ function tripal_feature_seq_extract_form_validate($form, &$form_state) {
   $fnames     = $form_state['values']['fnames'];
   $upstream   = $form_state['values']['upstream'];
   $downstream = $form_state['values']['downstream'];
-  $format     = $form_state['values']['format'];
   $use_parent = $form_state['values']['use_parent'];
   $aggregate  = $form_state['values']['aggregate'];
   $agg_types  = $form_state['values']['agg_types'];
-  $op         = $form_state['values']['op'];
 
-  if ($op == 'Retrieve') {
-    if ($upstream and !preg_match('/^\d+$/', $upstream)) {
-      form_set_error('upstream', 'Please enter a positive numeric value for the upstream bases');
-    }
-     if ($downstream and !preg_match('/^\d+$/', $downstream)) {
-      form_set_error('downstream', 'Please enter a positive numeric value for the downstream bases');
-    }
-    if (!$genus and !$species and !$ftype and !$fnames) {
-      form_set_error('', 'Please provide a feature name, a feature type or a genus.');
-    }
+  if ($upstream and !preg_match('/^\d+$/', $upstream)) {
+    form_set_error('upstream', 'Please enter a positive numeric value for the upstream bases');
+  }
+   if ($downstream and !preg_match('/^\d+$/', $downstream)) {
+    form_set_error('downstream', 'Please enter a positive numeric value for the downstream bases');
+  }
+  if (!$genus and !$species and !$ftype and !$fnames) {
+    form_set_error('', 'Please provide a feature name, a feature type or a genus.');
+  }
+  if ($ftype == 'polypeptide' and $upstream) {
+    form_set_error('upstream', 'When the sequence type is protein the upstream value must be unset.');
+  }
+  if ($ftype == 'polypeptide' and $downstream) {
+    form_set_error('downstream', 'When the sequence type is protein the downstream value must be unset.');
+  }
+  if ($ftype == 'polypeptide' and $use_parent) {
+    form_set_error('use_parent', 'When the sequence type is protein the "Use Parent" option must not be set.');
   }
 }
 
@@ -443,11 +477,9 @@ function tripal_feature_seq_extract_form_submit($form, &$form_state) {
   $fnames     = $form_state['values']['fnames'];
   $upstream   = $form_state['values']['upstream'];
   $downstream = $form_state['values']['downstream'];
-  $format     = $form_state['values']['format'];
   $use_parent = $form_state['values']['use_parent'];
   $aggregate  = $form_state['values']['aggregate'];
   $agg_types  = $form_state['values']['agg_types'];
-  $op         = $form_state['values']['op'];
 
   // we must use the parent sequence if the user has selected
   // the upstream, downstream or to aggregate
@@ -455,7 +487,7 @@ function tripal_feature_seq_extract_form_submit($form, &$form_state) {
     $use_parent = 1;
   }
 
-  if ($op == 'Retrieve') {
+  if ($form_state['clicked_button']['#name'] == 'retrieve') {
     $_SESSION['tripal_feature_seq_extract']['genus']      = $genus;
     $_SESSION['tripal_feature_seq_extract']['species']    = $species;
     $_SESSION['tripal_feature_seq_extract']['analysis']   = $analysis;
@@ -463,13 +495,12 @@ function tripal_feature_seq_extract_form_submit($form, &$form_state) {
     $_SESSION['tripal_feature_seq_extract']['fnames']     = $fnames;
     $_SESSION['tripal_feature_seq_extract']['upstream']   = $upstream;
     $_SESSION['tripal_feature_seq_extract']['downstream'] = $downstream;
-    $_SESSION['tripal_feature_seq_extract']['format']     = $format;
+    $_SESSION['tripal_feature_seq_extract']['format']     = 'fasta_txt';
     $_SESSION['tripal_feature_seq_extract']['use_parent'] = $use_parent;
     $_SESSION['tripal_feature_seq_extract']['aggregate']  = $aggregate;
     $_SESSION['tripal_feature_seq_extract']['agg_types']  = $agg_types;
     $_SESSION['tripal_feature_seq_extract']['download']   = 1;
-  }
-  if ($op == 'Reset') {
-    unset($_SESSION['tripal_feature_seq_extract']);
+
+    drupal_goto('find/sequences/download');
   }
 }

+ 5 - 12
tripal_feature/tripal_feature.module

@@ -114,14 +114,13 @@ function tripal_feature_menu() {
   $items['find/sequences'] = array(
     'title' => 'Sequence Retrieval',
     'description' => 'Download a file of sequences',
-    'page callback' => 'tripal_feature_seq_extract_page',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('tripal_feature_seq_extract_form'),
     'access arguments' => array('access chado_feature content'),
     'type' => MENU_CALLBACK,
   );
-
-  $items['find/sequences/ajax'] = array(
-    'title' => 'Sequence Retrieval',
-    'page callback' => 'tripal_feature_seq_extract_form_ahah_update',
+  $items['find/sequences/download'] = array(
+    'page callback' => 'tripal_feature_seq_extract_download',
     'access arguments' => array('access chado_feature content'),
     'type' => MENU_CALLBACK,
   );
@@ -343,7 +342,7 @@ function tripal_feature_theme($existing, $type, $theme, $path) {
 
   // Themed Forms
   $items['tripal_feature_seq_extract_form'] = array(
-     'arguments' => array('form'),
+    'render element' => 'form',
   );
 
   // D3 Charts.
@@ -551,12 +550,6 @@ function tripal_feature_match_features_page($id) {
  * @ingroup tripal_feature
  */
 function tripal_feature_form_alter(&$form, &$form_state, $form_id) {
-  if ($form_id == "tripal_feature_seq_extract_form") {
-    // updating the form through the ahah callback sets the action of
-    // the form to the ahah callback URL. We need to set it back
-    // to the normal form URL
-    $form['#action'] = url("find/sequences");
-  }
   // turn off preview button for insert/updates
   if ($form_id == "chado_feature_node_form") {
     $form['actions']['preview']['#access'] = FALSE;