tripal_chado.semweb.api.inc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. <?php
  2. /**
  3. * @file
  4. * Provides an application programming interface (API) for semantic web support.
  5. *
  6. * @ingroup tripal_chado
  7. */
  8. /**
  9. * @defgroup tripal_chado_semweb_api Semantic Web
  10. * @ingroup tripal_chado_api
  11. * @{
  12. * Provides an application programming interface (API) for semantic web support.
  13. * @}
  14. */
  15. /**
  16. * Adds a new Chado table to the semantic web support for Chado.
  17. *
  18. * Newly added tables (i.e. custom tables) need to be integrated into the
  19. * semantic web infrastructure. After a new table is created and added to
  20. * the Chado schema, this function should be called to indicate that the
  21. * table should be included in the semantic web. No associations are made for
  22. * the columns. The associations should be added using the
  23. * chado_associate_semweb_term() function.
  24. *
  25. * If the table has already been added previously then this function does
  26. * nothing. It will not overwrite existing assocations.
  27. *
  28. * Temporary tables (e.g. Tripal tables that begin with 'tripal_' and end with
  29. * '_temp', are not supported.
  30. *
  31. * @param $chado_table
  32. * The name of the Chado table.
  33. *
  34. * @ingroup tripal_chado_semweb_api
  35. */
  36. function chado_add_semweb_table($chado_table) {
  37. // Don't include the tripal temp tables.
  38. if (preg_match('/tripal_.+_temp/', $chado_table)) {
  39. return;
  40. }
  41. // Get the table's schema and add all of it's fields if they aren't
  42. // already there.
  43. $schema = chado_get_schema($chado_table);
  44. foreach ($schema['fields'] as $chado_column => $details) {
  45. // If the record already exists don't overwrite it.
  46. $record = db_select('chado_semweb', 'CS')
  47. ->fields('CS', array('chado_semweb_id'))
  48. ->condition('CS.chado_table', $chado_table)
  49. ->condition('CS.chado_column', $chado_column)
  50. ->execute()
  51. ->fetchField();
  52. if (!$record) {
  53. $record = array(
  54. 'chado_table' => $chado_table,
  55. 'chado_column' => $chado_column,
  56. );
  57. drupal_write_record('chado_semweb', $record);
  58. }
  59. }
  60. }
  61. /**
  62. * Associates a controlled vocabulary term with a field in a Chado table.
  63. *
  64. * For sharing of data via the semantic web we need to associate a
  65. * term from a controlled vocabulary with every column of every table in Chado.
  66. *
  67. * Temporary tables (e.g. Tripal tables that begin with 'tripal_' and end with
  68. * '_temp', are not supported.
  69. *
  70. * @param $chado_table
  71. * The name of the table in Chado. This argument is optional. If left empty
  72. * or set to NULL then all fields in all Chado tables with that have the
  73. * $column_name will be associated with the provided $term.
  74. * @param $chado_column
  75. * The column name in the Chado table to which the term should be associated.
  76. * @param $term
  77. * A cvterm object as returned by chado_generate_var().
  78. * @param $update
  79. * Set to TRUE if the association should be updated to use the new term
  80. * if a term is already associated with the table and column. Default is
  81. * FALSE. If not TRUE and a term is already associated, then no change
  82. * occurs.
  83. *
  84. * @return boolean
  85. * Returns TRUE if the association was made successfully and FALSE otherwise.
  86. *
  87. * @ingroup tripal_chado_semweb_api
  88. */
  89. function chado_associate_semweb_term($chado_table, $chado_column, $term,
  90. $update = FALSE) {
  91. // Check for required arguments.
  92. if (!$chado_column) {
  93. tripal_set_message('Please provide the $chado_column argument.', TRIPAL_ERROR);
  94. return FALSE;
  95. }
  96. if (!$term) {
  97. tripal_set_message('Please provide the $term argument.', TRIPAL_ERROR);
  98. return FALSE;
  99. }
  100. // Make sure the field is a real field for the table.
  101. if ($chado_table) {
  102. $schema = chado_get_schema($chado_table);
  103. if (!$schema) {
  104. tripal_set_message("Cannot associate the term with the field because the $chado_table is not a known table in Chado.", TRIPAL_ERROR);
  105. return FALSE;
  106. }
  107. if (!array_key_exists($chado_column, $schema['fields'])) {
  108. tripal_set_message("Cannot associate the term with the field because the $chado_column is not a known column in the $chado_table.", TRIPAL_ERROR);
  109. return FALSE;
  110. }
  111. }
  112. // First check to see if a valid record exists that matches the table and
  113. // column indicated. If it doesn't then insert the record.
  114. $query = db_select('chado_semweb', 'CS')
  115. ->fields('CS', array('chado_semweb_id'))
  116. ->condition('chado_column', $chado_column);
  117. if ($chado_table) {
  118. $query->condition('chado_table', $chado_table);
  119. }
  120. $query->range(0,1);
  121. $id = $query->execute()->fetchField();
  122. if (!$id) {
  123. // If no $chado_table record is provided then return FALSE as we can't
  124. // insert a record without a table.
  125. if (!$chado_table) {
  126. tripal_set_message('The provided $chado_column has no match for any
  127. table currently known. This could be because the table has not yet
  128. been added to the semantic web management. Please provide the
  129. $chado_table.', TRIPAL_ERROR);
  130. return FALSE;
  131. }
  132. // Insert the record.
  133. $id = db_insert('chado_semweb')
  134. ->fields(array(
  135. 'chado_table' => $chado_table,
  136. 'chado_column' => $chado_column,
  137. 'cvterm_id' => $term->cvterm_id,
  138. ));
  139. if ($id) {
  140. return TRUE;
  141. }
  142. else {
  143. tripal_set_message('Failure associating term.', TRIPAL_ERROR);
  144. return FALSE;
  145. }
  146. }
  147. // If the $chado_table argument is empty or NULL then the term applies to
  148. // all fields of the specified name.
  149. $update = db_update('chado_semweb')
  150. ->fields(array(
  151. 'cvterm_id' => $term->cvterm_id
  152. ))
  153. ->condition('chado_column', $chado_column);
  154. if ($chado_table) {
  155. $update->condition('chado_table', $chado_table);
  156. }
  157. if (!$update) {
  158. $update->condition('cvterm_id', NULL);
  159. }
  160. $num_updated = $update->execute();
  161. if (!$num_updated) {
  162. tripal_set_message('Failure associating term.', TRIPAL_ERROR);
  163. return FALSE;
  164. }
  165. return TRUE;
  166. }
  167. /**
  168. * Retrieves the term that maps to the given Chado table and field.
  169. *
  170. * @param $chado_table
  171. * The name of the Chado table.
  172. * @param $chado_column
  173. * The name of the Chado field.
  174. * @param $options
  175. * An associative array of one or more of the following keys:
  176. * -return_object: Set to TRUE to return the cvterm object rather than
  177. * the string version of the term.
  178. *
  179. * @return
  180. * Returns a string-based representation of the term (e.g. SO:0000704). If
  181. * the 'return_object' options is provided then a cvterm object is returned.
  182. * returns NULL if no term is mapped to the table and column.
  183. *
  184. * @ingroup tripal_chado_semweb_api
  185. */
  186. function chado_get_semweb_term($chado_table, $chado_column, $options = array()) {
  187. $cvterm_id = db_select('chado_semweb', 'CS')
  188. ->fields('CS', array('cvterm_id'))
  189. ->condition('chado_column', $chado_column)
  190. ->condition('chado_table', $chado_table)
  191. ->execute()
  192. ->fetchField();
  193. if ($cvterm_id) {
  194. $cvterm = chado_generate_var('cvterm', array('cvterm_id' => $cvterm_id));
  195. if (array_key_exists('return_object', $options)) {
  196. return $cvterm;
  197. }
  198. return chado_format_semweb_term($cvterm);
  199. }
  200. }
  201. /**
  202. * Retrieves the terms that maps to the given Chado table.
  203. *
  204. * @param $chado_table
  205. * The name of the Chado table.
  206. * @param $options
  207. * An associative array of one or more of the following keys:
  208. * -return_object: Set to TRUE to return the cvterm object rather than
  209. * the string version of the term.
  210. *
  211. * @return
  212. * An array of terms with the table column name as the key and the term
  213. * details as the avlue. If the 'return_object' options is provided then
  214. * a cvterm object is used as the value. A NULL value is used if no term is
  215. * mapped to a column.
  216. *
  217. * @ingroup tripal_chado_semweb_api
  218. */
  219. function chado_get_semweb_terms($chado_table, $options = array()) {
  220. $terms = [];
  221. $schema = chado_get_schema($chado_table);
  222. foreach ($schema['fields'] as $chado_column => $details) {
  223. $terms[$chado_column] = NULL;
  224. $cvterm_id = db_select('chado_semweb', 'CS')
  225. ->fields('CS', array('cvterm_id'))
  226. ->condition('chado_column', $chado_column)
  227. ->condition('chado_table', $chado_table)
  228. ->execute()
  229. ->fetchField();
  230. if ($cvterm_id) {
  231. $cvterm = chado_generate_var('cvterm', array('cvterm_id' => $cvterm_id));
  232. if (array_key_exists('return_object', $options)) {
  233. $terms[$chado_column] = $cvterm;
  234. }
  235. else {
  236. $terms[$chado_column] = chado_format_semweb_term($cvterm);
  237. }
  238. }
  239. }
  240. return $terms;
  241. }
  242. /**
  243. * Formats a controlled vocabulary term from Chado for use with Tripal.
  244. *
  245. * @param $cvterm
  246. * A cvterm object.
  247. * @return
  248. * The semantic web name for the term.
  249. *
  250. * @ingroup tripal_chado_semweb_api
  251. */
  252. function chado_format_semweb_term($cvterm) {
  253. if ($cvterm) {
  254. return $cvterm->dbxref_id->db_id->name . ':' . $cvterm->dbxref_id->accession;
  255. }
  256. return '';
  257. }
  258. /**
  259. * Retreive the column name in a Chado table that matches a given term.
  260. *
  261. * @param $chado_table
  262. * The name of the Chado table.
  263. * @param $term
  264. * The term. This can be a term name or a unique identifer of the form
  265. * {db}:{accession} or of the form {db}__{term_name}.
  266. *
  267. * @return
  268. * The name of the Chado column that matches the given term or FALSE if the
  269. * term is not mapped to the Chado table.
  270. *
  271. * @ingroup tripal_chado_semweb_api
  272. */
  273. function chado_get_semweb_column($chado_table, $term) {
  274. $columns = db_select('chado_semweb', 'CS')
  275. ->fields('CS')
  276. ->condition('chado_table', $chado_table)
  277. ->execute();
  278. while($column = $columns->fetchObject()) {
  279. $cvterm_id = $column->cvterm_id;
  280. if ($cvterm_id) {
  281. $cvterm = chado_generate_var('cvterm', array('cvterm_id' => $cvterm_id));
  282. $full_accession = strtolower($cvterm->dbxref_id->db_id->name . ':' . $cvterm->dbxref_id->accession);
  283. $full_accession = preg_replace('/ /', '_', $full_accession);
  284. $full_name_uscore = strtolower($cvterm->dbxref_id->db_id->name . '__' . $cvterm->name);
  285. $full_name_uscore = preg_replace('/ /', '_', $full_name_uscore);
  286. $term = preg_replace('/ /', '_', $term);
  287. $term = strtolower(preg_replace('/ /', '_', $term));
  288. // Does the term match identically?
  289. if ($term == $cvterm->name) {
  290. return $column->chado_column;
  291. }
  292. // Is the term a concatenation of the vocab and the accession?
  293. else if ($term == $full_accession) {
  294. return $column->chado_column;
  295. }
  296. // Is the term a concatenation of the vocab and the accession?
  297. else if ($term == $full_name_uscore) {
  298. return $column->chado_column;
  299. }
  300. }
  301. }
  302. return FALSE;
  303. }