|  | @@ -45,7 +45,8 @@ function tripal_reverse_compliment_sequence($sequence) {
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /**
 | 
	
		
			
				|  |  | - * Retrieves the sequence for a feature.
 | 
	
		
			
				|  |  | + * 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:
 | 
	
	
		
			
				|  | @@ -59,19 +60,15 @@ function tripal_reverse_compliment_sequence($sequence) {
 | 
	
		
			
				|  |  |   *   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.
 | 
	
		
			
				|  |  | - *    - output_format: The type of format.  Valid formats include 'fasta_html', 'fasta_txt' and
 | 
	
		
			
				|  |  | - *        'raw'.  The format 'fasta_txt' outputs line breaks as <br> tags and the entire
 | 
	
		
			
				|  |  | - *        return value is in a <span> tag with a fixed-width font definition.  'fasta_txt'
 | 
	
		
			
				|  |  | - *        outputs line breaks with windows format carriage returns (e.g. \r\n) with no other
 | 
	
		
			
				|  |  | - *        formatting. The raw format is simply the sequence with no FASTA formatting and no
 | 
	
		
			
				|  |  | - *        line breaks.
 | 
	
		
			
				|  |  | - *    - num_upstream: An integer specifing the number of upstream bases to include in the output
 | 
	
		
			
				|  |  | - *    - num_downstream: An integer specifying the number of downstream bases to include in the
 | 
	
		
			
				|  |  | + *    - 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
 | 
	
	
		
			
				|  | @@ -82,33 +79,39 @@ function tripal_reverse_compliment_sequence($sequence) {
 | 
	
		
			
				|  |  |   *        relationship the matched features belong
 | 
	
		
			
				|  |  |   *
 | 
	
		
			
				|  |  |   * @return
 | 
	
		
			
				|  |  | - *   an array of matching sequence formated as requested.
 | 
	
		
			
				|  |  | + *   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)
 | 
	
		
			
				|  |  | + *      'upstream'      => the number of upstream 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
 | 
	
		
			
				|  |  |   *
 | 
	
		
			
				|  |  |   * @ingroup tripal_feature_api
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  | -function tripal_get_sequence($feature, $options) {
 | 
	
		
			
				|  |  | +function tripal_get_feature_sequences($feature, $options) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // 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']           : '';
 | 
	
		
			
				|  |  | +  $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
 | 
	
		
			
				|  |  |    $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;
 | 
	
		
			
				|  |  | -  $output_format      = array_key_exists('output_format', $options)      ? $options['output_format']      : 'fasta_txt';
 | 
	
		
			
				|  |  | -  $upstream           = array_key_exists('num_upstream', $options)       ? $options['num_upstream']       : 0;
 | 
	
		
			
				|  |  | -  $downstream         = array_key_exists('num_downstream', $options)     ? $options['num_downstream']     : 0;
 | 
	
		
			
				|  |  | +  $upstream           = array_key_exists('upstream', $options)           ? $options['upstream']           : 0;
 | 
	
		
			
				|  |  | +  $downstream         = array_key_exists('downstream', $options)         ? $options['downstream']         : 0;
 | 
	
		
			
				|  |  |    $sub_features       = array_key_exists('sub_feature_types', $options)  ? $options['sub_feature_types']  : array();
 | 
	
		
			
				|  |  |    $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 (!is_array($sub_features)) {
 | 
	
		
			
				|  |  | -    tripal_report_error('tripal_deprecated', TRIPAL_ERROR,
 | 
	
		
			
				|  |  | -      "'sub_features' option must be an array for function tripal_get_sequence().",
 | 
	
		
			
				|  |  | +    tripal_report_error('tripal_feature', TRIPAL_ERROR,
 | 
	
		
			
				|  |  | +      "'sub_features' option must be an array for function tripal_get_feature_sequences().",
 | 
	
		
			
				|  |  |        array()
 | 
	
		
			
				|  |  |      );
 | 
	
		
			
				|  |  |      return array();
 | 
	
	
		
			
				|  | @@ -121,12 +124,12 @@ function tripal_get_sequence($feature, $options) {
 | 
	
		
			
				|  |  |      if ($rel_part == "subject") {
 | 
	
		
			
				|  |  |        $sql = '
 | 
	
		
			
				|  |  |          SELECT FO.feature_id, FO.name, FO.uniquename, CVTO.name as feature_type, O.genus, O.species
 | 
	
		
			
				|  |  | -        FROM feature FS
 | 
	
		
			
				|  |  | -          INNER JOIN feature_relationship FR ON FR.subject_id   = FS.feature_id
 | 
	
		
			
				|  |  | -          INNER JOIN cvterm CVTFR            ON CVTFR.cvterm_id = FR.type_id
 | 
	
		
			
				|  |  | -          INNER JOIN feature FO              ON FO.feature_id   = FR.object_id
 | 
	
		
			
				|  |  | -          INNER JOIN cvterm CVTO             ON CVTO.cvterm_id  = FO.type_id
 | 
	
		
			
				|  |  | -          INNER JOIN organism O              ON O.organism_id   = FO.organism_id
 | 
	
		
			
				|  |  | +        FROM {feature} FS
 | 
	
		
			
				|  |  | +          INNER JOIN {feature_relationship} FR ON FR.subject_id   = FS.feature_id
 | 
	
		
			
				|  |  | +          INNER JOIN {cvterm} CVTFR            ON CVTFR.cvterm_id = FR.type_id
 | 
	
		
			
				|  |  | +          INNER JOIN {feature} FO              ON FO.feature_id   = FR.object_id
 | 
	
		
			
				|  |  | +          INNER JOIN {cvterm} CVTO             ON CVTO.cvterm_id  = FO.type_id
 | 
	
		
			
				|  |  | +          INNER JOIN {organism} O              ON O.organism_id   = FO.organism_id
 | 
	
		
			
				|  |  |          WHERE
 | 
	
		
			
				|  |  |            FS.feature_id = :feature_id AND
 | 
	
		
			
				|  |  |            CVTFR.name    = :relationship
 | 
	
	
		
			
				|  | @@ -136,12 +139,12 @@ function tripal_get_sequence($feature, $options) {
 | 
	
		
			
				|  |  |      if ($rel_part == "object") {
 | 
	
		
			
				|  |  |        $sql = '
 | 
	
		
			
				|  |  |          SELECT FS.feature_id, FS.name, FS.uniquename, CVTO.name as feature_type, O.genus, O.species
 | 
	
		
			
				|  |  | -        FROM feature FO
 | 
	
		
			
				|  |  | -          INNER JOIN feature_relationship FR ON FR.object_id    = FO.feature_id
 | 
	
		
			
				|  |  | -          INNER JOIN cvterm CVTFR            ON CVTFR.cvterm_id = FR.type_id
 | 
	
		
			
				|  |  | -          INNER JOIN feature FS              ON FS.feature_id   = FR.subject_id
 | 
	
		
			
				|  |  | -          INNER JOIN cvterm CVTO             ON CVTO.cvterm_id  = FS.type_id
 | 
	
		
			
				|  |  | -          INNER JOIN organism O              ON O.organism_id   = FS.organism_id
 | 
	
		
			
				|  |  | +        FROM {feature} FO
 | 
	
		
			
				|  |  | +          INNER JOIN {feature_relationship} FR ON FR.object_id    = FO.feature_id
 | 
	
		
			
				|  |  | +          INNER JOIN {cvterm} CVTFR            ON CVTFR.cvterm_id = FR.type_id
 | 
	
		
			
				|  |  | +          INNER JOIN {feature} FS              ON FS.feature_id   = FR.subject_id
 | 
	
		
			
				|  |  | +          INNER JOIN {cvterm} CVTO             ON CVTO.cvterm_id  = FS.type_id
 | 
	
		
			
				|  |  | +          INNER JOIN {organism} O              ON O.organism_id   = FS.organism_id
 | 
	
		
			
				|  |  |          WHERE
 | 
	
		
			
				|  |  |            FO.feature_id = :feature_id AND
 | 
	
		
			
				|  |  |            CVTFR.name    = :relationship
 | 
	
	
		
			
				|  | @@ -158,7 +161,7 @@ function tripal_get_sequence($feature, $options) {
 | 
	
		
			
				|  |  |        if ($rel_part == "object") {
 | 
	
		
			
				|  |  |          $defline = "$feature->uniquename $feature->feature_type ($feature->genus $feature->species), $relationship, $feature_name";
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  | -      return tripal_get_sequence(
 | 
	
		
			
				|  |  | +      return tripal_get_feature_sequences(
 | 
	
		
			
				|  |  |          array(
 | 
	
		
			
				|  |  |            'feature_id' => $feature->feature_id, 
 | 
	
		
			
				|  |  |            'name' => $defline,
 | 
	
	
		
			
				|  | @@ -166,9 +169,8 @@ function tripal_get_sequence($feature, $options) {
 | 
	
		
			
				|  |  |          ),
 | 
	
		
			
				|  |  |          array(
 | 
	
		
			
				|  |  |            'width' => $num_bases_per_line, 
 | 
	
		
			
				|  |  | -          'derive_from_pareht' => $derive_from_parent, 
 | 
	
		
			
				|  |  | +          'derive_from_parent' => $derive_from_parent, 
 | 
	
		
			
				|  |  |            'aggregate' => $aggregate, 
 | 
	
		
			
				|  |  | -          'output_format' => $output_format,
 | 
	
		
			
				|  |  |            'upstream' => $upstream, 
 | 
	
		
			
				|  |  |            'downstream' => $downstream, 
 | 
	
		
			
				|  |  |            'sub_features' => $sub_features, 
 | 
	
	
		
			
				|  | @@ -182,7 +184,7 @@ function tripal_get_sequence($feature, $options) {
 | 
	
		
			
				|  |  |    // cases cases where the alignment is in the reverse direction and when
 | 
	
		
			
				|  |  |    // the upstream and downstream extensions go beyond the lenght of the
 | 
	
		
			
				|  |  |    // parent sequence.
 | 
	
		
			
				|  |  | -  $sql ='
 | 
	
		
			
				|  |  | +  $parent_sql ='
 | 
	
		
			
				|  |  |      SELECT featureloc_id, srcname, srcfeature_id, strand, srctypename, typename,
 | 
	
		
			
				|  |  |        fmin, fmax, upstream, downstream, adjfmin, adjfmax,
 | 
	
		
			
				|  |  |        substring(residues from (adjfmin + 1) for (upstream + (fmax - fmin) + downstream))  as residues,
 | 
	
	
		
			
				|  | @@ -255,10 +257,10 @@ function tripal_get_sequence($feature, $options) {
 | 
	
		
			
				|  |  |    $sfsql = '
 | 
	
		
			
				|  |  |      SELECT SF.feature_id, CVT.name as type_name, SF.type_id
 | 
	
		
			
				|  |  |      FROM {feature_relationship} FR
 | 
	
		
			
				|  |  | -      INNER JOIN {feature} SF on SF.feature_id = FR.subject_id
 | 
	
		
			
				|  |  | -      INNER JOIN {cvterm} CVT on CVT.cvterm_id = SF.type_id
 | 
	
		
			
				|  |  | -      INNER JOIN {featureloc} FL on FL.feature_id = FR.subject_id
 | 
	
		
			
				|  |  | -      INNER JOIN {feature} PF on PF.feature_id = FL.srcfeature_id
 | 
	
		
			
				|  |  | +      INNER JOIN {feature} SF    ON SF.feature_id = FR.subject_id
 | 
	
		
			
				|  |  | +      INNER JOIN {cvterm} CVT    ON CVT.cvterm_id = SF.type_id
 | 
	
		
			
				|  |  | +      INNER JOIN {featureloc} FL ON FL.feature_id = FR.subject_id
 | 
	
		
			
				|  |  | +      INNER JOIN {feature} PF    ON PF.feature_id = FL.srcfeature_id
 | 
	
		
			
				|  |  |      WHERE FR.object_id = :feature_id and PF.feature_id = :srcfeature_id
 | 
	
		
			
				|  |  |      ORDER BY FL.fmin ASC
 | 
	
		
			
				|  |  |    ';
 | 
	
	
		
			
				|  | @@ -266,10 +268,10 @@ function tripal_get_sequence($feature, $options) {
 | 
	
		
			
				|  |  |    $fsql ='
 | 
	
		
			
				|  |  |      SELECT count(*) as num_children
 | 
	
		
			
				|  |  |      FROM {feature_relationship} FR
 | 
	
		
			
				|  |  | -      INNER JOIN {feature} SF on SF.feature_id = FR.subject_id
 | 
	
		
			
				|  |  | -      INNER JOIN {cvterm} CVT on CVT.cvterm_id = SF.type_id
 | 
	
		
			
				|  |  | -      INNER JOIN {featureloc} FL on FL.feature_id = FR.subject_id
 | 
	
		
			
				|  |  | -      INNER JOIN {feature} PF on PF.feature_id = FL.srcfeature_id
 | 
	
		
			
				|  |  | +      INNER JOIN {feature} SF    ON SF.feature_id = FR.subject_id
 | 
	
		
			
				|  |  | +      INNER JOIN {cvterm} CVT    ON CVT.cvterm_id = SF.type_id
 | 
	
		
			
				|  |  | +      INNER JOIN {featureloc} FL ON FL.feature_id = FR.subject_id
 | 
	
		
			
				|  |  | +      INNER JOIN {feature} PF    ON PF.feature_id = FL.srcfeature_id
 | 
	
		
			
				|  |  |      WHERE FR.object_id = :feature_id and PF.feature_id = :srcfeature_id
 | 
	
		
			
				|  |  |    ';
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -280,8 +282,7 @@ function tripal_get_sequence($feature, $options) {
 | 
	
		
			
				|  |  |    if ($derive_from_parent) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      // execute the query to get the sequence from the parent
 | 
	
		
			
				|  |  | -    $parents = chado_query($sql, array(':upstream' => $upstream, ':downstream' => $downstream, ':feature_id' => $feature_id));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +    $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
 | 
	
	
		
			
				|  | @@ -293,6 +294,7 @@ function tripal_get_sequence($feature, $options) {
 | 
	
		
			
				|  |  |          continue;
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |        $seq = '';  // initialize the sequence for each parent
 | 
	
		
			
				|  |  | +      $notes = '';
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |        // if we are to aggregate then we will ignore the feature returned
 | 
	
		
			
				|  |  |        // by the query above and rebuild it using the sub features
 | 
	
	
		
			
				|  | @@ -300,7 +302,7 @@ function tripal_get_sequence($feature, $options) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // now get the sub features that are located on the parent.
 | 
	
		
			
				|  |  |          $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))->fetchObject();
 | 
	
		
			
				|  |  | +        $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
 | 
	
		
			
				|  |  |          // should already be in order.
 | 
	
	
		
			
				|  | @@ -311,6 +313,7 @@ function tripal_get_sequence($feature, $options) {
 | 
	
		
			
				|  |  |            // included then continue if this child is not one of those allowed
 | 
	
		
			
				|  |  |            // subfeatures
 | 
	
		
			
				|  |  |            if (count($sub_features) > 0 and !in_array($child->type_name, $sub_features)) {
 | 
	
		
			
				|  |  | +            $i++;
 | 
	
		
			
				|  |  |               continue;
 | 
	
		
			
				|  |  |            }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -325,40 +328,44 @@ function tripal_get_sequence($feature, $options) {
 | 
	
		
			
				|  |  |              // -------------------------- ref
 | 
	
		
			
				|  |  |              //    ....---->  ---->
 | 
	
		
			
				|  |  |              //     up    1       2
 | 
	
		
			
				|  |  | -            $q = chado_query($sql, array(':upstream' => $upstream, ':downstream' => 0, ':feature_id' => $child->feature_id));
 | 
	
		
			
				|  |  | +            $q = chado_query($parent_sql, array(':upstream' => $upstream, ':downstream' => 0, ':feature_id' => $child->feature_id));
 | 
	
		
			
				|  |  |            }
 | 
	
		
			
				|  |  |            elseif ($i == 0 and $parent->strand < 0) { // reverse direction
 | 
	
		
			
				|  |  |              // -------------------------- ref
 | 
	
		
			
				|  |  |              //    ....<----  <----
 | 
	
		
			
				|  |  |              //    down  1       2
 | 
	
		
			
				|  |  | -            $q = chado_query($sql, array(':upstream' => 0, ':downstream' => $downstream, ':feature_id' => $child->feature_id));
 | 
	
		
			
				|  |  | +            $q = chado_query($parent_sql, array(':upstream' => 0, ':downstream' => $downstream, ':feature_id' => $child->feature_id));
 | 
	
		
			
				|  |  |            }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |            // Next, if the last sub feature we need to include the downstream bases. first check if
 | 
	
		
			
				|  |  |            // the feature is in teh forward direction or the reverse
 | 
	
		
			
				|  |  | -          if ($i == $num_children->num_children - 1 and $parent->strand >= 0) {  // forward direction
 | 
	
		
			
				|  |  | +          elseif ($i == $num_children - 1 and $parent->strand >= 0) {  // forward direction
 | 
	
		
			
				|  |  |              // -------------------------- ref
 | 
	
		
			
				|  |  |              //        ---->  ---->....
 | 
	
		
			
				|  |  |              //          1       2 down
 | 
	
		
			
				|  |  | -            $q = chado_query($sql, array(':upstream' => 0, ':downstream' => $downstream, ':feature_id' => $child->feature_id));
 | 
	
		
			
				|  |  | +            $q = chado_query($parent_sql, array(':upstream' => 0, ':downstream' => $downstream, ':feature_id' => $child->feature_id));
 | 
	
		
			
				|  |  |            }
 | 
	
		
			
				|  |  | -          elseif ($i == $num_children->num_children - 1 and $parent->strand < 0) { // reverse direction
 | 
	
		
			
				|  |  | +          elseif ($i == $num_children - 1 and $parent->strand < 0) { // reverse direction
 | 
	
		
			
				|  |  |              // -------------------------- ref
 | 
	
		
			
				|  |  |              //        <----  <----....
 | 
	
		
			
				|  |  |              //          1       2  up
 | 
	
		
			
				|  |  | -            $q = chado_query($sql, array(':upstream' => $upstream, ':downstream' => 0, ':feature_id' => $child->feature_id));
 | 
	
		
			
				|  |  | +            $q = chado_query($parent_sql, array(':upstream' => $upstream, ':downstream' => 0, ':feature_id' => $child->feature_id));
 | 
	
		
			
				|  |  |            }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |            // for internal sub features we don't want upstream or downstream bases
 | 
	
		
			
				|  |  |            else {
 | 
	
		
			
				|  |  | -            $q = chado_query($sql, array(':upstream' => 0, ':downstream' => 0, ':feature_id' => $child->feature_id));
 | 
	
		
			
				|  |  | +            $q = chado_query($parent_sql, array(':upstream' => 0, ':downstream' => 0, ':feature_id' => $child->feature_id));
 | 
	
		
			
				|  |  |            }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |            while ($subseq = $q->fetchObject()) {
 | 
	
		
			
				|  |  |              // concatenate the sequences of all the sub features
 | 
	
		
			
				|  |  |              if ($subseq->srcfeature_id == $parent->srcfeature_id) {
 | 
	
		
			
				|  |  |                $seq .= $subseq->residues;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | +            if ($subseq->upstream > 0 ) { 
 | 
	
		
			
				|  |  | +              $notes .= "Includes " . $subseq->upstream . " bases upstream.  ";
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            if ($subseq->downstream > 0) {
 | 
	
		
			
				|  |  | +              $notes .= "Includes " . $subseq->downstream . " bases downstream.  ";
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |            }
 | 
	
		
			
				|  |  |            $i++;
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -366,50 +373,62 @@ function tripal_get_sequence($feature, $options) {
 | 
	
		
			
				|  |  |        // if this isn't an aggregate then use the parent residues
 | 
	
		
			
				|  |  |        else {
 | 
	
		
			
				|  |  |           $seq = $parent->residues;
 | 
	
		
			
				|  |  | +         if ($parent->upstream > 0) {
 | 
	
		
			
				|  |  | +           $notes .= "Includes " . $parent->upstream . " bases upstream.  ";
 | 
	
		
			
				|  |  | +         }
 | 
	
		
			
				|  |  | +         if ($parent->downstream > 0) {
 | 
	
		
			
				|  |  | +           $notes .= "Includes " . $parent->downstream . " bases downstream.  ";
 | 
	
		
			
				|  |  | +         }
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |        // get the reverse compliment if feature is on the reverse strand
 | 
	
		
			
				|  |  |        $dir = 'forward';
 | 
	
		
			
				|  |  | -      $notes = '';
 | 
	
		
			
				|  |  | +      $length = strlen($seq);
 | 
	
		
			
				|  |  |        if ($parent->strand < 0) {
 | 
	
		
			
				|  |  |          $seq = tripal_feature_reverse_complement($seq);
 | 
	
		
			
				|  |  |          $dir = 'reverse';
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |        // now format for display
 | 
	
		
			
				|  |  | -      if ($output_format == 'fasta_html') {
 | 
	
		
			
				|  |  | -         $seq = wordwrap($seq, $num_bases_per_line, "<br>", TRUE);
 | 
	
		
			
				|  |  | +      if ($is_html) {
 | 
	
		
			
				|  |  | +        $seq = wordwrap($seq, $num_bases_per_line, "<br>", TRUE);
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  | -      elseif ($output_format == 'fasta_txt') {
 | 
	
		
			
				|  |  | -         $seq = wordwrap($seq, $num_bases_per_line, "\r\n", TRUE);
 | 
	
		
			
				|  |  | +      else {
 | 
	
		
			
				|  |  | +        $seq = wordwrap($seq, $num_bases_per_line, "\r\n", TRUE);
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |        if (!$seq) {
 | 
	
		
			
				|  |  | -        if ($output_format == 'fasta_html') {
 | 
	
		
			
				|  |  | -          $notes .= "No sequence available.</br>";
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        else {
 | 
	
		
			
				|  |  | -          $notes .= "No sequence available.\r\n";
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +        $notes .= "No sequence available.";
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  | -      
 | 
	
		
			
				|  |  | -      $notes = "Sequence derived from feature of type, '$parent->srctypename', of $parent->genus $parent->species: $parent->srcname:" . ($parent->adjfmin + 1) . ".." . $parent->adjfmax . " ($dir). ";
 | 
	
		
			
				|  |  | -      /*
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |        if (count($types) > 0) {
 | 
	
		
			
				|  |  |          $notes .= "Excludes all bases but those of type(s): " . implode(', ', $types) . ". " ;
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  | -      if ($parent->upstream > 0) {
 | 
	
		
			
				|  |  | -         $notes .= "Includes " . $parent->upstream . " bases upstream.  ";
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -      if ($parent->downstream > 0) {
 | 
	
		
			
				|  |  | -         $notes .= "Includes " . $parent->downstream . " bases downstream.  ";
 | 
	
		
			
				|  |  | -      }      
 | 
	
		
			
				|  |  | -      */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // 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;
 | 
	
		
			
				|  |  | +      $featureloc->fmax = $parent->adjfmax;
 | 
	
		
			
				|  |  | +      $featureloc->strand = $parent->strand;
 | 
	
		
			
				|  |  | +      $featureloc->srcfeature_id = new stdClass;
 | 
	
		
			
				|  |  | +      $featureloc->srcfeature_id->name = $parent->srcname;
 | 
	
		
			
				|  |  | +      $featureloc->srcfeature_id->type_id = $parent->srctypename;
 | 
	
		
			
				|  |  | +      $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
 | 
	
		
			
				|  |  | +      $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,
 | 
	
		
			
				|  |  |          'downstream'    => $parent->downstream,
 | 
	
		
			
				|  |  | -        'notes'         => $notes,
 | 
	
		
			
				|  |  | +        'defline'       => $defline,
 | 
	
		
			
				|  |  |          'residues'      => $seq,
 | 
	
		
			
				|  |  |          'featureloc_id' => $parent->featureloc_id,
 | 
	
		
			
				|  |  | +        'length'        => $length,
 | 
	
		
			
				|  |  |        );
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
	
		
			
				|  | @@ -419,19 +438,26 @@ function tripal_get_sequence($feature, $options) {
 | 
	
		
			
				|  |  |      $sql = "SELECT * FROM {feature} F WHERE feature_id = :feature_id";
 | 
	
		
			
				|  |  |      $values = chado_query($sql, array(':feature_id' => $feature_id))->fetchObject();
 | 
	
		
			
				|  |  |      $residues = $values->residues;
 | 
	
		
			
				|  |  | -    if ($output_format == 'fasta_html') {
 | 
	
		
			
				|  |  | -       $residues = wordwrap($residues, $num_bases_per_line, "<br>", TRUE);
 | 
	
		
			
				|  |  | +    $length = strlen($residues);
 | 
	
		
			
				|  |  | +    if ($is_html) {
 | 
	
		
			
				|  |  | +      $residues = wordwrap($residues, $num_bases_per_line, "<br>", TRUE);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    elseif ($output_format == 'fasta_txt') {
 | 
	
		
			
				|  |  | -       $residues = wordwrap($residues, $num_bases_per_line, "\r\n", TRUE);
 | 
	
		
			
				|  |  | +    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,
 | 
	
		
			
				|  |  |        'upstream'   => 0,
 | 
	
		
			
				|  |  |        'downstream' => 0,
 | 
	
		
			
				|  |  | -      'notes'      => '',
 | 
	
		
			
				|  |  | +      'defline'    => $defline,
 | 
	
		
			
				|  |  |        'residues'   => $residues,
 | 
	
		
			
				|  |  | +      'length'     => $length,
 | 
	
		
			
				|  |  |      );
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -439,55 +465,234 @@ function tripal_get_sequence($feature, $options) {
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /**
 | 
	
		
			
				|  |  | - * Returns a fasta record for the passed in feature
 | 
	
		
			
				|  |  | - *
 | 
	
		
			
				|  |  | - * @param $feature
 | 
	
		
			
				|  |  | - *   A single feature object containing all the fields from the chado.feature table
 | 
	
		
			
				|  |  | - * @param $desc
 | 
	
		
			
				|  |  | - *   A string containing any additional details you want added to the definition line of
 | 
	
		
			
				|  |  | - *   the fasta record.
 | 
	
		
			
				|  |  | + * Retreives or prints multiple sequences from features found using the options provided.
 | 
	
		
			
				|  |  |   *
 | 
	
		
			
				|  |  | - * Note: the feature accession and name separated by a | will be added
 | 
	
		
			
				|  |  | - *   before the description but on the same line
 | 
	
		
			
				|  |  | + * @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
 | 
	
		
			
				|  |  | + *    - 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.
 | 
	
		
			
				|  |  | + *    - 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.  
 | 
	
		
			
				|  |  | + * @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
 | 
	
		
			
				|  |  | + *      '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
 | 
	
		
			
				|  |  |   *
 | 
	
		
			
				|  |  |   * @ingroup tripal_feature_api
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  | -function tripal_format_fasta_sequence($feature, $desc) {
 | 
	
		
			
				|  |  | +function tripal_get_bulk_feature_sequences($options) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // default values for building the sequence
 | 
	
		
			
				|  |  | +  $org_commonname     = array_key_exists('org_commonname', $options)     ? $options['org_commonname']    : '';
 | 
	
		
			
				|  |  | +  $genus              = array_key_exists('genus', $options)              ? $options['genus']             : '';
 | 
	
		
			
				|  |  | +  $species            = array_key_exists('species', $options)            ? $options['species']           : '';
 | 
	
		
			
				|  |  | +  $analysis_name      = array_key_exists('analysis_name', $options)      ? $options['analysis_name']     : '';
 | 
	
		
			
				|  |  | +  $type               = array_key_exists('type', $options)               ? $options['type']              : '';
 | 
	
		
			
				|  |  | +  $feature_name       = array_key_exists('feature_name', $options)       ? $options['feature_name']      : '';
 | 
	
		
			
				|  |  | +  $feature_uname      = array_key_exists('feature_uname', $options)      ? $options['feature_uname']     : '';
 | 
	
		
			
				|  |  | +  $derive_from_parent = array_key_exists('derive_from_parent', $options) ? $options['derive_from_parent'] : 0;
 | 
	
		
			
				|  |  | +  $aggregate          = array_key_exists('aggregate', $options)          ? $options['aggregate']          : 0;
 | 
	
		
			
				|  |  | +  $sub_features       = array_key_exists('sub_feature_types', $options)  ? $options['sub_feature_types']  : array();
 | 
	
		
			
				|  |  | +  $relationship       = array_key_exists('relationship_type', $options)  ? $options['relationship_type']  : '';
 | 
	
		
			
				|  |  | +  $rel_part           = array_key_exists('relationship_part', $options)  ? $options['relationship_part']  : '';
 | 
	
		
			
				|  |  | +  $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);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  $fasta  = ">" . variable_get('chado_feature_accession_prefix', 'FID') . "$feature->feature_id|$feature->name";
 | 
	
		
			
				|  |  | -  $fasta .= " $desc\n";
 | 
	
		
			
				|  |  | -  $fasta .= wordwrap($feature->residues, 50, "\n", TRUE);
 | 
	
		
			
				|  |  | -  $fasta .= "\n\n";
 | 
	
		
			
				|  |  | +  if (!$output_format) {
 | 
	
		
			
				|  |  | +    $output_format = 'fasta_txt';
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  return $fasta;
 | 
	
		
			
				|  |  | +  if (!$type and !$feature_name and !$genus) {
 | 
	
		
			
				|  |  | +    print "Please provide a type, feature name or genus\n";
 | 
	
		
			
				|  |  | +    return;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  // 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 ";
 | 
	
		
			
				|  |  | +  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 .= "WHERE (1=1) ";
 | 
	
		
			
				|  |  | +  if ($org_commonname) {
 | 
	
		
			
				|  |  | +    $sql .= "AND O.common_name = :common_name ";
 | 
	
		
			
				|  |  | +    $vars[':common_name'] = $org_commonname;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  if ($genus) {
 | 
	
		
			
				|  |  | +    $sql .= "AND O.genus = :genus ";
 | 
	
		
			
				|  |  | +    $vars[':genus'] = $genus;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  if ($species) {
 | 
	
		
			
				|  |  | +    $sql .= "AND O.species = :species ";
 | 
	
		
			
				|  |  | +    $vars[':species'] = $species;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  if ($type) {
 | 
	
		
			
				|  |  | +    $sql .= "AND CVT.name = :cvtname ";
 | 
	
		
			
				|  |  | +    $vars[':cvtname'] = $type;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  if ($feature_name) {
 | 
	
		
			
				|  |  | +    if (is_array($feature_name)) {
 | 
	
		
			
				|  |  | +      $sql .= "AND F.name IN (";
 | 
	
		
			
				|  |  | +      foreach ($feature_name as $i => $fname) {
 | 
	
		
			
				|  |  | +        $sql .= ":fname$i, ";
 | 
	
		
			
				|  |  | +        $vars[":fname$i"] = $fname;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      // remove the trailing comma and close the paren
 | 
	
		
			
				|  |  | +      $sql = substr($sql, 0, -2) . ")";
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    else {
 | 
	
		
			
				|  |  | +      $sql .= "AND F.name = :fname";
 | 
	
		
			
				|  |  | +      $vars[':fname'] = $feature_name;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  if ($feature_uname) {
 | 
	
		
			
				|  |  | +    if (is_array($feature_uname)) {
 | 
	
		
			
				|  |  | +      $sql .= "AND F.uniquename IN (";
 | 
	
		
			
				|  |  | +      foreach ($feature_uname as $i => $funame) {
 | 
	
		
			
				|  |  | +        $sql .= ":funame$i, ";
 | 
	
		
			
				|  |  | +        $vars[":funame$i"] = $funame;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      // remove the trailing comma and close the paren
 | 
	
		
			
				|  |  | +      $sql = substr($sql, 0, -2) . ")";
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    else {
 | 
	
		
			
				|  |  | +      $sql .= "AND F.uniquename = :funame";
 | 
	
		
			
				|  |  | +      $vars[':funame'] = $feature_uname;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  if ($analysis_name) {
 | 
	
		
			
				|  |  | +    $sql .= "AND A.name = :aname";
 | 
	
		
			
				|  |  | +    $vars[':aname'] = $analysis_name;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  $num_bases_per_line = 50;
 | 
	
		
			
				|  |  | +  $num_seqs = 0;
 | 
	
		
			
				|  |  | +  $q = chado_query($sql, $vars);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  $sequences = array();
 | 
	
		
			
				|  |  | +  while ($feature = $q->fetchObject()) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // 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);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    $num_seqs++;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  if (!$print) {
 | 
	
		
			
				|  |  | +    return $seqs;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  elseif ($num_seqs == 0) {
 | 
	
		
			
				|  |  | +    print "No Sequences Found";
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /**
 | 
	
		
			
				|  |  |   * 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
 | 
	
		
			
				|  |  | + *   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.
 | 
	
		
			
				|  |  | + * @param $notes
 | 
	
		
			
				|  |  | + *   Optional: additional notes to be added to the definition line
 | 
	
		
			
				|  |  |   * @param $featureloc
 | 
	
		
			
				|  |  | - *   Optional: A single featureloc object generated using chado_generate_var that
 | 
	
		
			
				|  |  | - *   contains a record from the chado.featureloc table.
 | 
	
		
			
				|  |  | + *   Optional: a single featureloc object generated using chado_generate_var that
 | 
	
		
			
				|  |  | + *   contains a record from the chado.featureloc table. Provide this if the
 | 
	
		
			
				|  |  | + *   sequence was obtained by using the alignment rather than from the feature.residues
 | 
	
		
			
				|  |  | + *   column
 | 
	
		
			
				|  |  |   * @param $type
 | 
	
		
			
				|  |  |   *   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 
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  | -function tripal_get_fasta_defline($feature, $featureloc = NULL, $type = '') {
 | 
	
		
			
				|  |  | +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)) {
 | 
	
		
			
				|  |  | +      $featureloc->srcfeature_id = chado_generate_var('feature', array('feature_id' => $featureloc->srcfeature_id));
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if (!is_object($featureloc->srcfeature_id->organism_id)) {
 | 
	
		
			
				|  |  | +      $featureloc->srcfeature_id->organism_id = chado_generate_var('organism', array('organism_id' => $featureloc->srcfeature_id->organism_id));
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // make sure the feature object has the organism if not, then add it
 | 
	
		
			
				|  |  | +  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;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  $defline = $feature->uniquename . "|" . $feature->name . "|" . $type . "|" . $feature->feature_id; 
 | 
	
		
			
				|  |  | +  
 | 
	
		
			
				|  |  | +  // construct the definition line
 | 
	
		
			
				|  |  | +  $defline = $feature->uniquename . " " . 
 | 
	
		
			
				|  |  | +             'ID=' . $feature->uniquename . "|" .
 | 
	
		
			
				|  |  | +             'Name=' . $feature->name . "|" . 
 | 
	
		
			
				|  |  | +             'organism=' . $feature->organism_id->genus . " " . $feature->organism_id->species .  "|" .
 | 
	
		
			
				|  |  | +             'type=' . $type . '|'; 
 | 
	
		
			
				|  |  | +  if ($length > 0) {
 | 
	
		
			
				|  |  | +    $defline .= "length=" . $length . "bp|";
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |    if ($featureloc) {
 | 
	
		
			
				|  |  | -    $defline = $defline . "; derived from alignment at " .tripal_get_location_string($featureloc);
 | 
	
		
			
				|  |  | +    $defline .= "location=Sequence derived from alignment at " . tripal_get_location_string($featureloc);
 | 
	
		
			
				|  |  | +    $defline .= " (" . $featureloc->srcfeature_id->organism_id->genus . " " . $featureloc->srcfeature_id->organism_id->species . ")|";
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  
 | 
	
		
			
				|  |  | +  if ($notes) {
 | 
	
		
			
				|  |  | +    $defline .= "Notes=$notes|";
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  $defline = substr($defline, 0, -1); // remove the trailing |
 | 
	
		
			
				|  |  |    return $defline;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -504,7 +709,7 @@ function tripal_get_location_string($featureloc) {
 | 
	
		
			
				|  |  |    if ($featureloc->strand < 0) {
 | 
	
		
			
				|  |  |      $residues = tripal_feature_reverse_complement($residues);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  $strand = '.';
 | 
	
		
			
				|  |  | +  $strand = '';
 | 
	
		
			
				|  |  |    if ($featureloc->strand == 1) {
 | 
	
		
			
				|  |  |      $strand = '+';
 | 
	
		
			
				|  |  |    }
 | 
	
	
		
			
				|  | @@ -513,4 +718,5 @@ function tripal_get_location_string($featureloc) {
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    
 | 
	
		
			
				|  |  |    return $featureloc->srcfeature_id->name . ":" . ($featureloc->fmin + 1) . ".." . $featureloc->fmax .  $strand;  
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 |