Advertisement
sentinelwex

hpo

Dec 19th, 2014
228
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 9.89 KB | None | 0 0
  1. <?php
  2. /**
  3.  * A basic Human Phenotype Ontology Class
  4.  *
  5.  * @author Csaba
  6.  *
  7.  */
  8. require_once 'Term.class.php';
  9.  
  10. class HPO {
  11.  
  12.     /**
  13.      * Holds the version of the ontology
  14.      * @type string
  15.      */
  16.     protected $version;
  17.    
  18.     /**
  19.      * Holds the format information of the ontology
  20.      * @type string
  21.      */
  22.     protected $formatInfo;
  23.    
  24.     /**
  25.      * Holds the terms in the ontology
  26.      * @var unknown
  27.      */
  28.     protected $terms = array();
  29.    
  30.     /**
  31.      * Adds an HPO term to the collection
  32.      * @param Term $obj
  33.      * @param string $key
  34.      * @throws KeyHasUseException
  35.      */
  36.     public function addTerm(&$obj, $key) {
  37.  
  38.             if (isset($this->terms[$key])) {
  39.                 throw new KeyHasUseException("Key $key already in use.");
  40.             }
  41.             else {
  42.                 $this->terms[$key] = $obj;
  43.             }
  44.    
  45.     }
  46.    
  47.     /**
  48.      * Removes a Term from the collection
  49.      * @param string $key
  50.      * @throws KeyInvalidException
  51.      */
  52.     public function deleteTerm($key) {
  53.         if (isset($this->terms[$key])) {
  54.             unset($this->terms[$key]);
  55.         }
  56.         else {
  57.             throw new KeyInvalidException("Invalid key $key.");
  58.         }
  59.     }
  60.    
  61.     /**
  62.      * Returns a Term from the collection
  63.      * @param string $key
  64.      * @throws KeyInvalidException
  65.      */
  66.     public function getTerm($key) {
  67.         if (isset($this->terms[$key])) {
  68.             return $this->terms[$key];
  69.         }
  70.         else {
  71.             throw new KeyInvalidException("Invalid key $key.");
  72.         }
  73.     }
  74.     /**
  75.      * Returns the number of Terms in the collection
  76.      */
  77.     public function length() {
  78.         return count($this->terms);
  79.     }
  80.    
  81.     /**
  82.      * Determines whether a given key exists in the collection
  83.      * @param string $key
  84.      */
  85.     public function keyExists($key) {
  86.         return isset($this->terms[$key]);
  87.     }
  88.    
  89.     /**
  90.      * Returns the keys already being in use
  91.      */
  92.     public function keys() {
  93.         return array_keys($this->terms);
  94.     }
  95.    
  96.    
  97.     /**
  98.      * Loads an .obo file and creates the HPO graph
  99.      * @param string $filename
  100.      */
  101.     public function load($filename){
  102.         // determines if the first term was read already
  103.         $firstTermNotRead = true;
  104.         $newTerm = null;
  105.  
  106.         $finishedTerm = false;
  107.         // opens the hp.obo file to read
  108.         $handle = fopen ( $filename, "r" );
  109.         if ($handle) {
  110.             while ( ($line = fgets ( $handle )) !== false) {
  111.                 // remove special characters from the line
  112.                 $line = trim ( str_replace ( PHP_EOL, '', $line ) );
  113.                 $line = trim ( str_replace ( '"', '', $line ) );
  114.                 // read version and format info before finding the first term
  115.                 if ($firstTermNotRead && $line != "[Term]"){
  116.                     $words = explode ( ":", $line, 2 );
  117.                     if ($words[0]=="format-version"){
  118.                         $this->formatInfo=trim($words[1]);
  119.                     }
  120.                     if ($words[0]=="data-version"){
  121.                         $this->version=trim($words[1]);
  122.                     }
  123.                        
  124.                 }
  125.                    
  126.                 // if a term definition is find
  127.                 if ($line == "[Term]") {
  128.                     $firstTermNotRead = false;
  129.                    
  130.                        
  131.                     // if a term is already been finished
  132.                     if ($finishedTerm) {
  133.                         // insert the term to the ontology
  134.                         $this->addTerm($newTerm,$newTerm->getId());
  135.  
  136.                         $finishedTerm = false;
  137.                        
  138.                         //reset newTerm
  139.                         $newTerm = new Term();
  140.        
  141.                        
  142.                     }// if it is a new term
  143.                     else {
  144.                         // create a new term object
  145.  
  146.                         $newTerm = new Term();
  147.                         $finishedTerm = false;
  148.                     }
  149.                 }
  150.                 // if it is a term attribute line
  151.                 if ($line != "[Term]" && strlen ( $line ) > 2) {
  152.                     $words = explode ( ":", $line, 2 );
  153.                     //set object id
  154.                     if (trim($words[0])=="id"){
  155.                         $newTerm->setId(trim($words[1]));
  156.                     }
  157.                     //set object name
  158.                     if (trim($words[0])=="name"){
  159.                         $newTerm->setName(trim($words[1]));
  160.                     }                  
  161.                     //set object def
  162.                     if (trim($words[0])=="def"){
  163.                         //removing "[HPO:...]"
  164.                         $definition = explode("[",$words[1],2);
  165.                        
  166.                         $newTerm->setDef(trim($definition[0]));
  167.                     }
  168.                     //set object comment
  169.                     if (trim($words[0])=="comment"){
  170.                         $newTerm->setComment(trim($words[1]));
  171.                     }
  172.                    
  173.                     //add object synonym
  174.                     if (trim($words[0])=="synonym"){
  175.                         $newTerm->addSynonym(trim($words[1]));
  176.                     }
  177.                     //add object xref
  178.                     if (trim($words[0]) =="xref"){
  179.                         $subString = explode ( " ", trim($words[1]), 2 );
  180.                         //addXref(xrefId,xrefName)
  181.                         if ( ! isset($subString[1])) {
  182.                             $subString[1] = null;
  183.                         }
  184.                         $newTerm->addXref(trim($subString[0]),trim($subString[1]));
  185.                     }
  186.                     //add object is_a
  187.                     if (trim($words[0])=="is_a"){
  188.                         $subString = explode ( "!", trim($words[1]), 2 );
  189.                         //addIs_a(is_aId,is_aName)
  190.                         $newTerm->addIs_a(trim($subString[0]),trim($subString[1]));
  191.                     }                                                          
  192.                 }
  193.                 // if the first term was already been read and it is an empty line
  194.                 if(!($firstTermNotRead) && strlen ( $line ) < 2){
  195.                     //we finished a term, make it ready to insert
  196.                     $finishedTerm = true;
  197.                 }
  198.             }
  199.         } else {
  200.             // error opening the file.
  201.         }
  202.        
  203.         // insert the term to the ontology
  204.         $this->addTerm($newTerm,$newTerm->getId());
  205.     }
  206.  
  207.     /**
  208.      * Performs a search on the terms
  209.      * @param string $subString
  210.      * @param int $maxResults
  211.      */
  212.     function search($subString, $maxResults = 15){
  213.         $resultArray = array();
  214.         $resCount = 0;
  215.        
  216.         $resultTermsInName = array();
  217.         $resultTermsInSynonym = array();
  218.         $resultTermsInDescription = array();
  219.        
  220.         //if the passed value is a number or it starts with "HP:"
  221.         if (is_numeric($subString) || substr(strtolower($subString), 0, 3) === "hp:"){
  222.  
  223.             foreach($this->terms as $t){
  224.                 //match the name
  225.                 if (strpos ( strtolower ($t->getId()), strtolower ($subString) ) !== false) {
  226.                     $resultTermsInName[]=$t;
  227.                     $resCount++;
  228.                     //if the maximum element has been reached, stop the search
  229.                     if ($resCount>=$maxResults) break;
  230.                 }
  231.             }
  232.         }
  233.         // if it is not a number nor starts with "HP:"
  234.         else { 
  235.             //check if a term starts with the substring
  236.             foreach ($this->terms as $t){
  237.                 $length = strlen($subString);
  238.                 if (substr(strtolower($t->getName()), 0, $length) === strtolower($subString)) {
  239.                             $resultTermsInName[]=$t;
  240.                             $resCount++;
  241.                             if ($resCount>=$maxResults) break;
  242.                         }
  243.             }  
  244.            
  245.             foreach($this->terms as $t){
  246.                 //if the maximum element has been reached, stop the search
  247.                 if ($resCount>=$maxResults) break;
  248.                 //match the name
  249.                 if (strpos ( strtolower ($t->getName()), strtolower ( $subString ) ) !== false) {
  250.                     if (!in_array($t,$resultTermsInName)){
  251.                     $resultTermsInName[]=$t;
  252.                     $resCount++;}
  253.                 }
  254.                        
  255.                 else {
  256.                     //match synonyms
  257.                     foreach ($t->getSynonyms() as $key=>$syns){
  258.                         //if the maximum element has been reached, stop the search
  259.                         if ($resCount>=$maxResults) break;
  260.                         if (strpos ( strtolower ($syns), strtolower ( $subString ) ) !== false) {
  261.                             $resultTermsInSynonym[]=$t;
  262.                             $resCount++;   
  263.                         }                  
  264.                     }              
  265.                 }
  266.             }
  267.             // if there were no results in names and synonyms, nor in HPO ids, perform a search on descriptions
  268.             if (count($resultTermsInName)==0 && count($resultTermsInSynonym)==0) { 
  269.  
  270.                 foreach($this->terms as $t){
  271.                     //match the description
  272.                     if (strpos ( strtolower ($t->getDef()), strtolower ( $subString ) ) !== false) {
  273.                         $resultTermsInDescription[]=$t;
  274.                         $resCount++;
  275.                         //if the maximum element has been reached, stop the search
  276.                         if ($resCount>=$maxResults) break;
  277.                     }
  278.                 }              
  279.             }
  280.         }
  281.         $resultArray['serviceProvider']="CIT Cambridge";
  282.         $resultArray['ontology']="Human Phenotype Ontology";
  283.         $resultArray['ontoVersion']=$this->version;    
  284.         $resultArray['result']=$resCount;
  285.         $resultArray['resultsInName']=$resultTermsInName;
  286.         $resultArray['resultsInSynonym']=$resultTermsInSynonym;
  287.         $resultArray['resultsInDescription']=$resultTermsInDescription;
  288.  
  289.         return $resultArray;
  290.     }//end of search
  291.     /**
  292.      * Returns all child element of a parent term
  293.      *
  294.      * @param string $parentTerm
  295.      * @return multitype:array of Terms
  296.      */
  297.     public function getChildren($parentTerm){
  298.         $children = array();
  299.  
  300.         foreach ($this->terms as $t){
  301.             //if there is at least one is_a reference
  302.             if (count($t->getIs_aKeys())>0) {
  303.                 foreach ($t->getIs_aKeys() as $keys){
  304.                     if ($keys==$parentTerm){
  305.                         if (!in_array($t->getId(),$children)){
  306.                             $children[]=$t;
  307.                         }
  308.                     }
  309.                 }
  310.             }
  311.         }
  312.         return $children;
  313.        
  314.     }
  315.    
  316.     /**
  317.      * Returns true if the passed term has got at least one child element
  318.      * @param string $parentTerm
  319.      * @return boolean
  320.      */
  321.     public function hasChild($parentTerm){
  322.         $children = array();
  323.         $children = $this->getChildren($parentTerm);
  324.         if (empty($children)){
  325.             return false;
  326.         }
  327.         return true;
  328.        
  329.     }
  330.    
  331.    
  332.    
  333.     /**
  334.      * Returns the children elements of a term
  335.      * @param string $parentTerm
  336.      */
  337.     public function children($parentTerm){
  338.  
  339.         $resultArray = array();
  340.         $resCount = 0;
  341.         $childall = $this->getChildren($parentTerm);
  342.        
  343.         $resultArray['serviceProvider']="CIT Cambridge";
  344.         $resultArray['ontology']="Human Phenotype Ontology";
  345.         $resultArray['ontoVersion']=$this->version;
  346.         $resultArray['result']= count($childall);
  347.         $resultArray['children']=$childall;
  348.        
  349.     return $resultArray;   
  350.     }//end of children
  351.    
  352.     /**
  353.      * Returns the sub graph of the ontology excluding the parent Term
  354.      * @param string $parentTerm
  355.      * @return array of Terms
  356.      */
  357.     public function subGraph($parentTerm){
  358.         $subGraph = array();
  359.         $keys = array();
  360.         //get the children elements of the parent Term
  361.        
  362.         $tempChildren = array();
  363.         $tempChildren = $this->getChildren($parentTerm);
  364.         for ($i=0;$i<count($tempChildren);$i++){
  365.            
  366.             $subGraph[]=$tempChildren[$i];
  367.             $keys[] = $tempChildren[$i]->getId();
  368.         }
  369.        
  370.  
  371.         //get all the terms and their subterms
  372.         $tempChildren = array();
  373.        
  374.         for ($i=0;$i<count($keys);$i++){
  375.             $tempChildren = $this->getChildren($keys[$i]);
  376.  
  377.             for($j=0;$j<count($tempChildren);$j++){
  378.  
  379.                 $id = $tempChildren[$j]->getId();
  380.  
  381.                 if (!in_array($id,$keys)){
  382.                     $subGraph[]=$tempChildren[$j];
  383.                     $keys[]=$id;
  384.                 }
  385.             }
  386.             $tempChildren = array();
  387.         }
  388.        
  389.         return $subGraph;
  390.     }
  391.    
  392.    
  393.    
  394.    
  395. }//end of class
  396.  
  397.  
  398. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement