Tripal v1.0 (6.x-1.0)
tripal_feature.api.inc
Go to the documentation of this file.
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 } 
 All Classes Files Functions Variables