Tripal v1.0 (6.x-1.0)
|
00001 <?php 00036 function tripal_feature_analysis_get_property($analysis_id = NULL, $feature_id = NUll, 00037 $analysisfeature_id = NULL, $property, $cv_name = 'tripal') { 00038 00039 // check that the incoming arguments are correct 00040 if (($analysis_id and !$feature_id) or 00041 (!$analysis_id and $feature_id)) { 00042 watchdog('tripal_feature', 00043 'tripal_feature_analysis_get_property: Both an analysis ID and feature ID should be specified', 00044 array(), WATCHDOG_WARNING); 00045 } 00046 00047 // get the analysisfeature_id if one is not provided 00048 if (!$analysisfeature_id) { 00049 $columns = array('analysisfeature_id'); 00050 $values = array('analysis_id' => $analysis_id, 'feature_id' => $feature_id); 00051 $result = tripal_core_chado_select('analysisfeature', $columns, $values); 00052 $analysisfeature_id = $result[0]->analysisfeature_id; 00053 } 00054 00055 // get the property. 00056 return tripal_core_get_property('analysisfeature', $analysisfeature_id, $property, $cv_name); 00057 } 00058 00089 function tripal_feature_analysis_insert_property($analysis_id = NULL, $feature_id = NUll, 00090 $analysisfeature_id = NULL, $property, $value, $update_if_present = 0, 00091 $cv_name = 'tripal') { 00092 00093 // check that the incoming arguments are correct 00094 if (($analysis_id and !$feature_id) or 00095 (!$analysis_id and $feature_id)) { 00096 watchdog('tripal_feature', 00097 'tripal_feature_analysis_insert_property: Both an analysis ID and feature ID should be specified', 00098 array(), WATCHDOG_WARNING); 00099 } 00100 00101 // get the analysisfeature_id if one is not provided 00102 if (!$analysisfeature_id) { 00103 $columns = array('analysisfeature_id'); 00104 $values = array('analysis_id' => $analysis_id, 'feature_id' => $feature_id); 00105 $result = tripal_core_chado_select('analysisfeature', $columns, $values); 00106 $analysisfeature_id = $result[0]->analysisfeature_id; 00107 } 00108 00109 // insert the property. 00110 return tripal_core_insert_property('analysisfeature', $analysisfeature_id, 00111 $property, $cv_name, $value, $update_if_present); 00112 } 00113 00150 function tripal_feature_analysis_update_property($analysis_id = NULL, $feature_id = NUll, 00151 $analysisfeature_id = NULL, $property, $value, $insert_if_missing = 0, 00152 $cv_name = 'tripal') { 00153 00154 // check that the incoming arguments are correct 00155 if (($analysis_id and !$feature_id) or 00156 (!$analysis_id and $feature_id)) { 00157 watchdog('tripal_feature', 00158 'tripal_feature_analysis_update_property: Both an analysis ID and feature ID should be specified', 00159 array(), WATCHDOG_WARNING); 00160 } 00161 00162 // get the analysisfeature_id if one is not provided 00163 if (!$analysisfeature_id) { 00164 $columns = array('analysisfeature_id'); 00165 $values = array('analysis_id' => $analysis_id, 'feature_id' => $feature_id); 00166 $result = tripal_core_chado_select('analysisfeature', $columns, $values); 00167 $analysisfeature_id = $result[0]->analysisfeature_id; 00168 } 00169 00170 // update the property. 00171 return tripal_core_update_property('analysisfeature', $analysisfeature_id, $property, $cv_name, $value, $insert_if_missing); 00172 } 00173 00192 function tripal_feature_analysis_update_property_by_id($analysisfeatureprop_id, 00193 $property, $value, $cv_name = 'tripal') { 00194 00195 // update the property. 00196 return tripal_core_update_property_by_id('analysisfeature', 00197 $analysisfeatureprop_id, $property, $cv_name, $value); 00198 } 00231 function tripal_feature_analysis_delete_property($analysis_id = NULL, $feature_id = NUll, 00232 $analysisfeature_id = NULL, $property, $cv_name = 'tripal') { 00233 // check that the incoming arguments are correct 00234 if (($analysis_id and !$feature_id) or 00235 (!$analysis_id and $feature_id)) { 00236 watchdog('tripal_feature', 00237 'tripal_feature_analysis_delete_property: Both an analysis ID and feature ID should be specified', 00238 array(), WATCHDOG_WARNING); 00239 } 00240 00241 // get the analysisfeature_id if one is not provided 00242 if (!$analysisfeature_id) { 00243 $columns = array('analysisfeature_id'); 00244 $values = array('analysis_id' => $analysis_id, 'feature_id' => $feature_id); 00245 $result = tripal_core_chado_select('analysisfeature', $columns, $values); 00246 $analysisfeature_id = $result[0]->analysisfeature_id; 00247 } 00248 00249 // get the property. 00250 return tripal_core_delete_property('analysisfeature', $analysisfeature_id, $property, $cv_name); 00251 } 00263 function tripal_feature_analysis_delete_property_by_id($analysisfeatureprop_id) { 00264 // get the property. 00265 return tripal_core_delete_property_by_id('analysisfeature', $analysisfeatureprop_id); 00266 } 00283 function tripal_feature_get_property($feature_id, $property, $cv_name='tripal') { 00284 return tripal_core_get_property('feature', $feature_id, $property, $cv_name); 00285 } 00286 00307 function tripal_feature_insert_property($feature_id, $property, $value, 00308 $update_if_present = 0, $cv_name = 'tripal') { 00309 return tripal_core_insert_property('feature', $feature_id, $property, 00310 $cv_name, $value, $update_if_present); 00311 } 00336 function tripal_feature_update_property($feature_id, $property, 00337 $value, $insert_if_missing = 0, $cv_name = 'tripal') { 00338 return tripal_core_update_property('feature', $feature_id, $property, $cv_name, $value, $insert_if_missing); 00339 } 00340 00359 function tripal_feature_update_property_by_id($featureprop_id, $property, 00360 $value, $cv_name = 'tripal') { 00361 return tripal_core_update_property_by_id('feature', $featureprop_id, $property, $cv_name, $value); 00362 } 00363 00384 function tripal_feature_delete_property($feature_id, $property, $cv_name='tripal') { 00385 return tripal_core_delete_property('feature', $feature_id, $property, $cv_name); 00386 } 00398 function tripal_feature_delete_property_by_id($featureprop_id) { 00399 return tripal_core_delete_property_by_id('feature', $featureprop_id); 00400 } 00401 00413 function tripal_feature_reverse_complement($sequence) { 00414 00415 $seq = strtoupper($sequence); 00416 $seq = strrev($seq); 00417 $seq = str_replace("A", "t", $seq); 00418 $seq = str_replace("T", "a", $seq); 00419 $seq = str_replace("G", "c", $seq); 00420 $seq = str_replace("C", "g", $seq); 00421 $seq = str_replace("Y", "r", $seq); 00422 $seq = str_replace("R", "y", $seq); 00423 $seq = str_replace("W", "w", $seq); 00424 $seq = str_replace("S", "s", $seq); 00425 $seq = str_replace("K", "m", $seq); 00426 $seq = str_replace("M", "k", $seq); 00427 $seq = str_replace("D", "h", $seq); 00428 $seq = str_replace("V", "b", $seq); 00429 $seq = str_replace("H", "d", $seq); 00430 $seq = str_replace("B", "v", $seq); 00431 return strtoupper($seq); 00432 } 00469 function tripal_feature_get_formatted_sequence($feature_id, $feature_name, 00470 $num_bases_per_line, $derive_from_parent, $aggregate, $output_format, 00471 $upstream, $downstream, $sub_features = array()) { 00472 00473 // to speed things up we need to make sure we have a persistent connection 00474 $connection = tripal_db_persistent_chado(); 00475 00476 if (!$upstream) { 00477 $upstream = 0; 00478 } 00479 if (!$downstream) { 00480 $downstream = 0; 00481 } 00482 00483 // prepare statements we'll need to use later 00484 if (!tripal_core_is_sql_prepared('sequence_by_parent')) { 00485 // prepare the queries we're going to use later during the render phase 00486 // This SQL statement uses conditionals in the select clause to handle 00487 // cases cases where the alignment is in the reverse direction and when 00488 // the upstream and downstream extensions go beyond the lenght of the 00489 // parent sequence. 00490 $psql ='PREPARE sequence_by_parent (int, int, int) AS 00491 SELECT srcname, srcfeature_id, strand, srctypename, typename, 00492 fmin, fmax, upstream, downstream, adjfmin, adjfmax, 00493 substring(residues from (adjfmin + 1) for (upstream + (fmax - fmin) + downstream)) as residues 00494 FROM ( 00495 SELECT 00496 OF.name srcname, FL.srcfeature_id, FL.strand, 00497 OCVT.name as srctypename, SCVT.name as typename, 00498 FL.fmin, FL.fmax, 00499 CASE 00500 WHEN FL.strand >= 0 THEN 00501 CASE 00502 WHEN FL.fmin - $1 <= 0 THEN 0 00503 ELSE FL.fmin - $1 00504 END 00505 WHEN FL.strand < 0 THEN 00506 CASE 00507 WHEN FL.fmin - $2 <= 0 THEN 0 00508 ELSE FL.fmin - $2 00509 END 00510 END as adjfmin, 00511 CASE 00512 WHEN FL.strand >= 0 THEN 00513 CASE 00514 WHEN FL.fmax + $2 > OF.seqlen THEN OF.seqlen 00515 ELSE FL.fmax + $2 00516 END 00517 WHEN FL.strand < 0 THEN 00518 CASE 00519 WHEN FL.fmax + $1 > OF.seqlen THEN OF.seqlen 00520 ELSE FL.fmax + $1 00521 END 00522 END as adjfmax, 00523 CASE 00524 WHEN FL.strand >= 0 THEN 00525 CASE 00526 WHEN FL.fmin - $1 <= 0 THEN FL.fmin 00527 ELSE $1 00528 END 00529 ELSE 00530 CASE 00531 WHEN FL.fmax + $1 > OF.seqlen THEN OF.seqlen - FL.fmax 00532 ELSE $1 00533 END 00534 END as upstream, 00535 CASE 00536 WHEN FL.strand >= 0 THEN 00537 CASE 00538 WHEN FL.fmax + $2 > OF.seqlen THEN OF.seqlen - FL.fmax 00539 ELSE $2 00540 END 00541 ELSE 00542 CASE 00543 WHEN FL.fmin - $2 <= 0 THEN FL.fmin 00544 ELSE $2 00545 END 00546 END as downstream, 00547 OF.residues 00548 FROM featureloc FL 00549 INNER JOIN feature SF on FL.feature_id = SF.feature_id 00550 INNER JOIN cvterm SCVT on SF.type_id = SCVT.cvterm_id 00551 INNER JOIN feature OF on FL.srcfeature_id = OF.feature_id 00552 INNER JOIN cvterm OCVT on OF.type_id = OCVT.cvterm_id 00553 WHERE SF.feature_id = $3) as tbl1 00554 '; 00555 $status = tripal_core_chado_prepare('sequence_by_parent', $psql, array('int', 'int', 'int')); 00556 if (!$status) { 00557 watchdog('tripal_views_handler_field_sequence', 00558 "init: not able to prepare SQL statement '%name'", 00559 array('%name' => 'sequence_by_parent'), 'WATCHDOG ERROR'); 00560 } 00561 00562 // this query is meant to get all of the sub features of any given 00563 // feature (arg #1) and order them as they appear on the reference 00564 // feature (arg #2). 00565 $psql ='PREPARE sub_features (int, int) AS 00566 SELECT SF.feature_id, CVT.name as type_name, SF.type_id 00567 FROM feature_relationship FR 00568 INNER JOIN feature SF on SF.feature_id = FR.subject_id 00569 INNER JOIN cvterm CVT on CVT.cvterm_id = SF.type_id 00570 INNER JOIN featureloc FL on FL.feature_id = FR.subject_id 00571 INNER JOIN feature PF on PF.feature_id = FL.srcfeature_id 00572 WHERE FR.object_id = $1 and PF.feature_id = $2 00573 ORDER BY FL.fmin ASC'; 00574 $status = tripal_core_chado_prepare('sub_features', $psql, array('int', 'int')); 00575 if (!$status) { 00576 watchdog('tripal_views_handler_field_sequence', 00577 "init: not able to prepare SQL statement '%name'", 00578 array('%name' => 'ssub_features'), 'WATCHDOG ERROR'); 00579 } 00580 $psql ='PREPARE count_sub_features (int, int) AS 00581 SELECT count(*) as num_children 00582 FROM feature_relationship FR 00583 INNER JOIN feature SF on SF.feature_id = FR.subject_id 00584 INNER JOIN cvterm CVT on CVT.cvterm_id = SF.type_id 00585 INNER JOIN featureloc FL on FL.feature_id = FR.subject_id 00586 INNER JOIN feature PF on PF.feature_id = FL.srcfeature_id 00587 WHERE FR.object_id = $1 and PF.feature_id = $2'; 00588 $status = tripal_core_chado_prepare('count_sub_features', $psql, array('int', 'int')); 00589 if (!$status) { 00590 watchdog('tripal_views_handler_field_sequence', 00591 "init: not able to prepare SQL statement '%name'", 00592 array('%name' => 'count_sub_features'), 'WATCHDOG ERROR'); 00593 } 00594 } 00595 00596 // if we need to get the sequence from the parent then do so now. 00597 if ($derive_from_parent) { 00598 00599 // execute the query to get the sequence from the parent 00600 $sql = "EXECUTE sequence_by_parent (%d, %d, %d)"; 00601 $parents = chado_query($sql, $upstream, $downstream, $feature_id); 00602 00603 while ($parent = db_fetch_object($parents)) { 00604 $seq = ''; // initialize the sequence for each parent 00605 00606 // if we are to aggregate then we will ignore the feature returned 00607 // by the query above and rebuild it using the sub features 00608 if ($aggregate) { 00609 00610 // now get the sub features that are located on the parent. 00611 $sql = "EXECUTE sub_features (%d, %d)"; 00612 $children = chado_query($sql, $feature_id, $parent->srcfeature_id); 00613 $sql = "EXECUTE count_sub_features (%d, %d)"; 00614 $num_children = db_fetch_object(chado_query($sql, $feature_id, $parent->srcfeature_id)); 00615 00616 // iterate through the sub features and concat their sequences. They 00617 // should already be in order. 00618 $types = array(); 00619 $i = 0; 00620 while ($child = db_fetch_object($children)) { 00621 // if the callee has specified that only certain sub features should be 00622 // included then continue of this child is not one of those allowed 00623 // subfeatures 00624 if (count($sub_features) > 0 and !in_array($child->type_name, $sub_features)) { 00625 continue; 00626 } 00627 00628 // keep up with the types 00629 if (!in_array($child->type_name, $types)) { 00630 $types[] = $child->type_name; 00631 } 00632 00633 $sql = "EXECUTE sequence_by_parent (%d, %d, %d)"; 00634 00635 // if the first sub feature we need to include the upstream bases 00636 if ($i == 0 and $parent->strand >= 0) { // forward direction 00637 // -------------------------- ref 00638 // ....----> ----> 00639 // up 1 2 00640 $q = chado_query($sql, $upstream, 0, $child->feature_id); 00641 } 00642 elseif ($i == 0 and $parent->strand < 0) { // reverse direction 00643 // -------------------------- ref 00644 // ....<---- <---- 00645 // down 1 2 00646 $q = chado_query($sql, 0, $downstream, $child->feature_id); 00647 } 00648 // if the last sub feature we need to include the downstream bases 00649 elseif ($i == $num_children->num_children - 1 and $parent->strand >= 0) { // forward direction 00650 // -------------------------- ref 00651 // ----> ---->.... 00652 // 1 2 down 00653 $q = chado_query($sql, 0, $downstream, $child->feature_id); 00654 } 00655 elseif ($i == $num_children->num_children - 1 and $parent->strand < 0) { // reverse direction 00656 // -------------------------- ref 00657 // <---- <----.... 00658 // 1 2 up 00659 $q = chado_query($sql, $upstream, 0, $child->feature_id); 00660 } 00661 00662 // for internal sub features we don't want upstream or downstream bases 00663 else { 00664 $sql = "EXECUTE sequence_by_parent (%d, %d, %d)"; 00665 $q = chado_query($sql, 0, 0, $child->feature_id); 00666 } 00667 00668 while ($subseq = db_fetch_object($q)) { 00669 // concatenate the sequences of all the sub features 00670 if ($subseq->srcfeature_id == $parent->srcfeature_id) { 00671 $seq .= $subseq->residues; 00672 } 00673 } 00674 $i++; 00675 } 00676 } 00677 // if this isn't an aggregate then use the parent residues 00678 else { 00679 $seq = $parent->residues; 00680 } 00681 00682 // get the reverse compliment if feature is on the reverse strand 00683 $dir = 'forward'; 00684 if ($parent->strand < 0) { 00685 $seq = tripal_feature_reverse_complement($seq); 00686 $dir = 'reverse'; 00687 } 00688 00689 // now format for display 00690 if ($output_format == 'fasta_html') { 00691 $seq = wordwrap($seq, $num_bases_per_line, "<br>", TRUE); 00692 } 00693 elseif ($output_format == 'fasta_txt') { 00694 $seq = wordwrap($seq, $num_bases_per_line, "\n", TRUE); 00695 } 00696 $residues .= ">$feature_name ($parent->typename) $parent->srcname:" . ($parent->adjfmin + 1) . ".." . $parent->adjfmax ." ($dir). "; 00697 if (count($types) > 0) { 00698 $residues .= "Excludes all bases but those of type(s): " . implode(', ', $types) . ". " ; 00699 } 00700 if ($parent->upstream > 0) { 00701 $residues .= "Includes " . $parent->upstream . " bases upstream. "; 00702 } 00703 if ($parent->downstream > 0) { 00704 $residues .= "Includes " . $parent->downstream . " bases downstream. "; 00705 } 00706 if (!$seq) { 00707 00708 if ($output_format == 'fasta_html') { 00709 $residues .= "No sequence available.</br>"; 00710 } 00711 else { 00712 $residues .= "No sequence available.\n"; 00713 } 00714 } 00715 else { 00716 if ($output_format == 'fasta_html') { 00717 $residues .= "<br>"; 00718 } 00719 $residues .= "\n" . $seq . "\n"; 00720 if ($output_format == 'fasta_html') { 00721 $residues .= "<br>"; 00722 } 00723 } 00724 } 00725 } 00726 // if we are not getting the sequence from the parent sequence then 00727 // use what comes through from the feature record 00728 else { 00729 $sql = "SELECT * FROM feature F WHERE feature_id = %d"; 00730 $values = db_fetch_object(chado_query($sql, $feature_id)); 00731 $residues = $values->residues; 00732 if ($output_format == 'fasta_html') { 00733 $residues = wordwrap($residues, $num_bases_per_line, "<br>", TRUE); 00734 } 00735 elseif ($output_format == 'fasta_txt') { 00736 $residues = wordwrap($residues, $num_bases_per_line, "\n", TRUE); 00737 } 00738 $residues = ">$feature_name\n$residues\n"; 00739 } 00740 00741 // format the residues for display 00742 if ($residues and $num_bases_per_line) { 00743 if ($output_format == 'fasta_html') { 00744 $residues = '<span style="font-family: monospace;">' . $residues . '</span>'; 00745 } 00746 } 00747 return $residues; 00748 } 00749 00750 00757 function tripal_feature_get_custom_tables($table = NULL) { 00758 00759 if (!$table or strcmp($table, 'tripal_gff_temp')==0) { 00760 $schema['tripal_gff_temp'] = array( 00761 'table' => 'tripal_gff_temp', 00762 'fields' => array( 00763 'feature_id' => array( 00764 'type' => 'int', 00765 'not null' => TRUE, 00766 ), 00767 'organism_id' => array( 00768 'type' => 'int', 00769 'not null' => TRUE, 00770 ), 00771 'uniquename' => array( 00772 'type' => 'text', 00773 'not null' => TRUE, 00774 ), 00775 'type_name' => array( 00776 'type' => 'varchar', 00777 'length' => '1024', 00778 'not null' => TRUE, 00779 ), 00780 ), 00781 'indexes' => array( 00782 'tripal_gff_temp_idx0' => array('feature_id'), 00783 'tripal_gff_temp_idx0' => array('organism_id'), 00784 'tripal_gff_temp_idx1' => array('uniquename'), 00785 ), 00786 'unique keys' => array( 00787 'tripal_gff_temp_uq0' => array('feature_id'), 00788 'tripal_gff_temp_uq1' => array('uniquename', 'organism_id', 'type_name'), 00789 ), 00790 ); 00791 } 00792 return $schema; 00793 } 00794 00810 function tripal_feature_get_feature_relationships($feature) { 00811 // expand the feature object to include the feature relationships. 00812 $options = array( 00813 'return_array' => 1, 00814 'order_by' => array('rank' => 'ASC'), 00815 ); 00816 $feature = tripal_core_expand_chado_vars($feature, 'table', 00817 'feature_relationship', $options); 00818 00819 // get the subject relationships 00820 $srelationships = $feature->feature_relationship->subject_id; 00821 $orelationships = $feature->feature_relationship->object_id; 00822 00823 // get alignment as child. The $feature->featureloc element 00824 // is already populated from the alignment preprocess function 00825 $feature = tripal_core_expand_chado_vars($feature, 'table', 'featureloc'); 00826 $cfeaturelocs = $feature->featureloc->feature_id; 00827 if (!$cfeaturelocs) { 00828 $cfeaturelocs = array(); 00829 } 00830 elseif (!is_array($cfeaturelocs)) { 00831 $cfeaturelocs = array($cfeaturelocs); 00832 } 00833 00834 // prepare the SQL statement to get the featureloc for the 00835 // feature in the relationships. 00836 $connection = tripal_db_persistent_chado(); 00837 $psql = " 00838 PREPARE sel_featureloc_preprocess_relationships (int, int) AS 00839 SELECT 00840 FL.featureloc_id, F.name as srcfeature_name, FL.srcfeature_id, 00841 FL.feature_id, FL.fmin, FL.fmax, FL.strand, FL.phase 00842 FROM featureloc FL 00843 INNER JOIN feature F ON F.feature_id = FL.srcfeature_id 00844 WHERE FL.feature_id = $1 and FL.srcfeature_id = $2 00845 "; 00846 tripal_core_chado_prepare('sel_featureloc_preprocess_relationships', $psql, array('int', 'int')); 00847 00848 00849 // combine both object and subject relationshisp into a single array 00850 $relationships = array(); 00851 $relationships['object'] = array(); 00852 $relationships['subject'] = array(); 00853 00854 // iterate through the object relationships 00855 if ($orelationships) { 00856 foreach ($orelationships as $relationship) { 00857 $rel = new stdClass(); 00858 // get locations where the child feature and this feature overlap with the 00859 // same landmark feature. 00860 $rel->child_featurelocs = array(); 00861 foreach ($cfeaturelocs as $featureloc) { 00862 $res = chado_query("EXECUTE sel_featureloc_preprocess_relationships (%d, %d)", 00863 $relationship->subject_id->feature_id, 00864 $featureloc->srcfeature_id->feature_id); 00865 while ($loc = db_fetch_object($res)) { 00866 // add in the node id of the src feature if it exists and save this location 00867 $loc->nid = $featureloc->srcfeature_id->nid; 00868 $rel->child_featurelocs[] = $loc; 00869 } 00870 } 00871 $rel->record = $relationship; 00872 00873 // get the relationship and child types 00874 $rel_type = t(preg_replace('/_/', " ", $relationship->type_id->name)); 00875 $child_type = $relationship->subject_id->type_id->name; 00876 00877 // get the node id of the subject 00878 $sql = "SELECT nid FROM {chado_feature} WHERE feature_id = %d"; 00879 $n = db_fetch_object(db_query($sql, $relationship->subject_id->feature_id)); 00880 if ($n) { 00881 $rel->record->nid = $n->nid; 00882 } 00883 00884 if (!array_key_exists($rel_type, $relationships['object'])) { 00885 $relationships['object'][$rel_type] = array(); 00886 } 00887 if (!array_key_exists($child_type, $relationships['object'][$rel_type])) { 00888 $relationships['object'][$rel_type][$child_type] = array(); 00889 } 00890 $relationships['object'][$rel_type][$child_type][] = $rel; 00891 } 00892 } 00893 00894 // now add in the subject relationships 00895 if ($srelationships) { 00896 foreach ($srelationships as $relationship) { 00897 $rel = new stdClass(); 00898 // get locations where this feature overlaps with the parent 00899 $rel->parent_featurelocs = array(); 00900 foreach ($cfeaturelocs as $featureloc) { 00901 $res = chado_query("EXECUTE sel_featureloc_preprocess_relationships (%d, %d)", 00902 $relationship->object_id->feature_id, 00903 $featureloc->srcfeature_id->feature_id); 00904 while ($loc = db_fetch_object($res)) { 00905 // add in the node id of the src feature if it exists and save this location 00906 $loc->nid = $featureloc->srcfeature_id->nid; 00907 $rel->parent_featurelocs[] = $loc; 00908 } 00909 } 00910 $rel->record = $relationship; 00911 $rel_type = t(preg_replace('/_/', " ", $relationship->type_id->name)); 00912 $parent_type = $relationship->object_id->type_id->name; 00913 00914 // get the node id of the subject 00915 $sql = "SELECT nid FROM {chado_feature} WHERE feature_id = %d"; 00916 $n = db_fetch_object(db_query($sql, $relationship->object_id->feature_id)); 00917 if ($n) { 00918 $rel->record->nid = $n->nid; 00919 } 00920 00921 if (!array_key_exists($rel_type, $relationships['subject'])) { 00922 $relationships['subject'][$rel_type] = array(); 00923 } 00924 if (!array_key_exists($child_type, $relationships['subject'][$rel_type])) { 00925 $relationships['subject'][$rel_type][$parent_type] = array(); 00926 } 00927 $relationships['subject'][$rel_type][$parent_type][] = $rel; 00928 } 00929 } 00930 return $relationships; 00931 }