|
@@ -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;
|
|
|
-}
|
|
|
+}
|
|
|
+
|