tripal_feature_sequence.tpl.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <?php
  2. /*
  3. * There are several ways that sequences can be displayed. They can come from the
  4. * feature.residues column, they can come from an alignment with another feature,
  5. * they can come from a protein sequence that has relationship with this sequence,
  6. * or they can come from sub children (e.g. CDS coding sequences).
  7. *
  8. * This template will show all types depending on the data available.
  9. *
  10. */
  11. $feature = $variables['node']->feature;
  12. // number of bases per line in FASTA format
  13. $num_bases = 50;
  14. // we don't want to get the sequence for traditionally large types. They are
  15. // too big, bog down the web browser, take longer to load and it's not
  16. // reasonable to print them on a page.
  17. $residues = '';
  18. if (strcmp($feature->type_id->name, 'scaffold') != 0 and
  19. strcmp($feature->type_id->name, 'chromosome') != 0 and
  20. strcmp($feature->type_id->name, 'supercontig') != 0 and
  21. strcmp($feature->type_id->name, 'pseudomolecule') != 0) {
  22. $feature = chado_expand_var($feature, 'field', 'feature.residues');
  23. $residues = $feature->residues;
  24. }
  25. // get the sequence derived from alignments
  26. $feature = $variables['node']->feature;
  27. $featureloc_sequences = $feature->featureloc_sequences;
  28. if ($residues or count($featureloc_sequences) > 0) {
  29. $sequences_html = ''; // a variable for holding all sequences HTML text
  30. $list_items = []; // a list to be used for theming of content on this page
  31. // ADD IN RESIDUES FOR THIS FEATURE
  32. // add in the residues if they are present
  33. if ($residues) {
  34. $list_items[] = '<a href="#residues">' . $feature->type_id->name . ' sequence</a>';
  35. // format the sequence to break every 50 residues
  36. $sequences_html .= '<a name="residues"></a>';
  37. $sequences_html .= '<div id="residues" class="tripal_feature-sequence-item">';
  38. $sequences_html .= '<p><b>' . $feature->type_id->name . ' sequence</b></p>';
  39. $sequences_html .= '<pre class="tripal_feature-sequence">';
  40. $sequences_html .= '>' . tripal_get_fasta_defline($feature, '', NULL, '', strlen($feature->residues)) . "<br>";
  41. $sequences_html .= wordwrap($feature->residues, $num_bases, "<br>", TRUE);
  42. $sequences_html .= '</pre>';
  43. $sequences_html .= '<a href="#sequences-top">back to top</a>';
  44. $sequences_html .= '</div>';
  45. }
  46. // ADD IN RELATIONSHIP SEQUENCES (e.g. proteins)
  47. // see the explanation in the tripal_feature_relationships.tpl.php
  48. // template for how the 'all_relationships' is provided. It is this
  49. // variable that we use to get the proteins.
  50. $all_relationships = $feature->all_relationships;
  51. $object_rels = $all_relationships['object'];
  52. $has_coding_seq = 0;
  53. $coding_seq = '';
  54. foreach ($object_rels as $rel_type => $rels) {
  55. foreach ($rels as $subject_type => $subjects) {
  56. foreach ($subjects as $subject) {
  57. // add in protein sequence if it has residues
  58. if ($rel_type == 'derives from' and $subject_type == 'polypeptide') {
  59. $protein = $subject->record->subject_id;
  60. $protein = chado_expand_var($protein, 'field', 'feature.residues');
  61. if ($protein->residues) {
  62. $list_items[] = '<a href="#residues">protein sequence</a>';
  63. $sequences_html .= '<a name="protein-' . $protein->feature_id . '"></a>';
  64. $sequences_html .= '<div id="protein-' . $protein->feature_id . '" class="tripal_feature-sequence-item">';
  65. $sequences_html .= '<p><b>protein sequence of ' . $protein->name . '</b></p>';
  66. $sequences_html .= '<pre class="tripal_feature-sequence">';
  67. $sequences_html .= '>' . tripal_get_fasta_defline($protein, '', NULL, '', strlen($protein->residues)) . "<br>";
  68. $sequences_html .= wordwrap($protein->residues, $num_bases, "<br>", TRUE);
  69. $sequences_html .= '</pre>';
  70. $sequences_html .= '<a href="#sequences-top">back to top</a>';
  71. $sequences_html .= '</div>';
  72. }
  73. }
  74. // If the CDS has sequences then concatenate those. The objects
  75. // should be returned in order of rank
  76. if ($rel_type == 'part of' and $subject_type == 'CDS') {
  77. $cds = $subject->record->subject_id;
  78. $cds = chado_expand_var($cds, 'field', 'feature.residues');
  79. if ($cds->residues) {
  80. $has_coding_seq = 1;
  81. $coding_seq .= $cds->residues;
  82. }
  83. }
  84. // add any other sequences that are related through a relationship
  85. // and that have values in the 'residues' column
  86. }
  87. }
  88. }
  89. // CODING SEQUENCES FROM RELATIONSHIPS
  90. // add in any CDS sequences.
  91. if ($has_coding_seq) {
  92. $list_items[] = '<a href="#coding_sequence">coding sequence </a>';
  93. $sequences_html .= '<a name="coding_sequence"></a>';
  94. $sequences_html .= '<div id="coding_sequence" class="tripal_feature-sequence-item">';
  95. $sequences_html .= '<p><b>coding sequence</b></p>';
  96. $sequences_html .= '<pre class="tripal_feature-sequence">';
  97. $sequences_html .= wordwrap($coding_seq, $num_bases, "<br>", TRUE);
  98. $sequences_html .= '</pre>';
  99. $sequences_html .= '<a href="#sequences-top">back to top</a>';
  100. $sequences_html .= '</div>';
  101. }
  102. /* ADD IN ALIGNMENT SEQUENCES FOR THIS FEATURE
  103. * For retreiving the sequence from an alignment we would typically make a call to
  104. * chado_expand_var function. For example, to retrieve all
  105. * of the featurelocs in order to get the sequences needed for this template, the
  106. * following function call would be made:
  107. *
  108. * $feature = chado_expand_var($feature,'table','featureloc');
  109. *
  110. * Then all of the sequences would need to be retreived from the alignments and
  111. * formatted for display below. However, to simplify this template, this has already
  112. * been done by the tripal_feature module and the sequences are made available in
  113. * the variable:
  114. *
  115. * $feature->featureloc_sequences
  116. */
  117. if (count($featureloc_sequences) > 0) {
  118. foreach ($featureloc_sequences as $src => $attrs) {
  119. // the $attrs array has the following keys
  120. // * id: a unique identifier combining the feature id with the cvterm id
  121. // * type: the type of sequence (e.g. mRNA, etc)
  122. // * location: the alignment location
  123. // * defline: the definition line
  124. // * formatted_seq: the formatted sequences
  125. // * featureloc: the feature object aligned to
  126. $list_items[] = '<a href="#' . $attrs['id'] . '">' . $feature->type_id->name . ' from alignment at ' . $attrs['location'] . "</a>";
  127. $sequences_html .= '<a name="' . $attrs['id'] . '"></a>';
  128. $sequences_html .= '<div id="' . $attrs['id'] . '" class="tripal_feature-sequence-item">';
  129. $sequences_html .= '<p><b>' . $feature->type_id->name . ' from alignment at ' . $attrs['location'] . '</b></p>';
  130. $sequences_html .= $attrs['formatted_seq'];
  131. $sequences_html .= '<a href="#sequences-top">back to top</a>';
  132. $sequences_html .= '</div>';
  133. }
  134. // check to see if this alignment has any CDS. If so, generate a CDS sequence
  135. $cds_sequence = tripal_get_feature_sequences(
  136. [
  137. 'feature_id' => $feature->feature_id,
  138. 'parent_id' => $attrs['featureloc']->srcfeature_id->feature_id,
  139. 'name' => $feature->name,
  140. 'featureloc_id' => $attrs['featureloc']->featureloc_id,
  141. ],
  142. [
  143. 'width' => $num_bases,
  144. // FASTA sequence should have $num_bases chars per line
  145. 'derive_from_parent' => 1,
  146. // CDS are in parent-child relationships so we want to use the sequence from the parent
  147. 'aggregate' => 1,
  148. // we want to combine all CDS for this feature into a single sequence
  149. 'sub_feature_types' => ['CDS'],
  150. // we're looking for CDS features
  151. 'is_html' => 1,
  152. ]
  153. );
  154. if (count($cds_sequence) > 0) {
  155. // the tripal_get_feature_sequences() function can return multiple sequences
  156. // if a feature is aligned to multiple places. In the case of CDSs we expect
  157. // that one mRNA is only aligned to a single location on the assembly so we
  158. // can access the CDS sequence with index 0.
  159. if ($cds_sequence[0]['residues']) {
  160. $list_items[] = '<a href="#coding_' . $attrs['id'] . '">coding sequence from alignment at ' . $attrs['location'] . "</a>";
  161. $sequences_html .= '<a name="ccoding_' . $attrs['id'] . '"></a>';
  162. $sequences_html .= '<div id="coding_' . $attrs['id'] . '" class="tripal_feature-sequence-item">';
  163. $sequences_html .= '<p><b>Coding sequence (CDS) from alignment at ' . $attrs['location'] . '</b></p>';
  164. $sequences_html .= '<pre class="tripal_feature-sequence">';
  165. $sequences_html .= '>' . tripal_get_fasta_defline($feature, '', $attrs['featureloc'], 'CDS', $cds_sequence[0]['length']) . "<br>";
  166. $sequences_html .= $cds_sequence[0]['residues'];
  167. $sequences_html .= '</pre>';
  168. $sequences_html .= '<a href="#sequences-top">back to top</a>';
  169. $sequences_html .= '</div>';
  170. }
  171. }
  172. }
  173. ?>
  174. <div class="tripal_feature-data-block-desc tripal-data-block-desc">The
  175. following sequences are available for this feature:
  176. </div>
  177. <?php
  178. // first add a list at the top of the page that can be formatted as the
  179. // user desires. We use the theme_item_list function of Drupal to create
  180. // the list rather than hard-code the HTML here. Instructions for how
  181. // to create the list can be found here:
  182. // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_item_list/7
  183. print '<a name="sequences-top"></a>';
  184. print theme_item_list([
  185. 'items' => $list_items,
  186. 'title' => '',
  187. 'type' => 'ul',
  188. 'attributes' => [],
  189. ]);
  190. $message = 'Administrators, sequences will appear on this page if:
  191. <br><br><b>For any feature type:</b>
  192. <ul>
  193. <li>This feature has residues stored in the "residues" field of the feature table of Chado.</li>
  194. <li>This feature is aligned to another feature (e.g. scaffold, or chromosome). In this case, the
  195. sequence underlying the alignment will be shown.</li>
  196. </ul>
  197. <br><b>For gene models:</b>
  198. <ul>
  199. <li>This feature has a "polypeptide" (protein) feature associated via the "feature_relationship" table of Chado with a
  200. relationship of type "derives from" and the protein feature has residues. Typically, a protein
  201. is associated with an mRNA feature and protein sequences will appear on the mRNA page.</li>
  202. <li>This feature has one or more CDS features associated via the "feature_relationship" table of Chado with a
  203. relationship of type "part of". If the CDS features have residues then those will be concatenated
  204. and presented as a sequence. Typically, CDSs are associated with an mRNA feature and CDS sequences
  205. will appear on the mRNA page.</li>
  206. <li>This feature is aligned to another feature (e.g. scaffold, or chromosome) and this feature has
  207. one or more CDS features associated. The CDS sequenes underlying the alignment will be
  208. shown.</li>
  209. </ul>
  210. </p>';
  211. print tripal_set_message($message, TRIPAL_INFO, ['return_html' => 1]);
  212. // now print the sequences
  213. print $sequences_html;
  214. }