Package biana :: Package BianaObjects :: Module Ontology'
[hide private]
[frames] | no frames]

Source Code for Module biana.BianaObjects.Ontology'

  1  """ 
  2      BIANA: Biologic Interactions and Network Analysis 
  3      Copyright (C) 2009  Javier Garcia-Garcia, Emre Guney, Baldo Oliva 
  4   
  5      This program is free software: you can redistribute it and/or modify 
  6      it under the terms of the GNU General Public License as published by 
  7      the Free Software Foundation, either version 3 of the License, or 
  8      (at your option) any later version. 
  9   
 10      This program is distributed in the hope that it will be useful, 
 11      but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 13      GNU General Public License for more details. 
 14   
 15      You should have received a copy of the GNU General Public License 
 16      along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 17   
 18  """ 
 19   
 20  import sets 
 21  import sys 
 22  import ExternalEntity 
 23  import ExternalEntityAttribute 
 24   
 25   
26 -class Ontology(ExternalEntity.ExternalEntity):
27 """ 28 Class to represent a general ontology 29 30 The Ontology is an external entity itself. Each of its elemens is also an ExternalEntityObject 31 32 Each ontology as a "linkedAttribute", which is the primary attribute to represent the ontology (for example, taxID for taxonomy), and a "descriptionAttribute", which is an attribute that describes the external entity element 33 """ 34
35 - def __init__(self, source_database, name, linkedAttribute, descriptionAttribute, id=None, levelAttribute=None ):
36 """ 37 "source_database" is the source database id where this entity is described 38 39 "name" is the name for the ontology. It must be UNIQUE! There cannot be different ontologies with the same name 40 41 "linkedAttribute" is the attribute_identifier for the primary attribute of the ontology (for example, taxID for taxonomy ontology) 42 43 "descriptionAttribute" is the attribute_identifier for representing a human readable description of the element. This attribute is used when showing the ontolgy to users 44 45 "id" is the UNIQUE identifier in the database for this external entity (as the ontology is an External Entity) 46 """ 47 48 self.name = name 49 self.trees = {} # is_a in the first position, is_part_of in the second one 50 self.hierarchy = {} # vertical hierarchy 51 self.root_ids = sets.Set() 52 self.linked_attribute = linkedAttribute 53 self.level_attribute = levelAttribute 54 self.linked_attribute_values = {} 55 self._attrID2id = {} 56 self.description_attribute = descriptionAttribute 57 self.externalEntityObjs = {} 58 self.all_ids = sets.Set() 59 60 self.precalculated_descendants = {} 61 62 ExternalEntity.ExternalEntity.__init__(self, source_database = source_database, type="ontology", id=id)
63 64
65 - def add_element(self, ontologyElementID, isA=[], isPartOf=[], linkedAttributeValue=None):
66 """ 67 Adds an element to the ontology. 68 69 "ontologyElementID": externalEntityID that identifies the externalEntityObject belonging to the ontology 70 71 "isA": list with the externalEntityIDs of the parents of this element 72 73 "isPartOf": list with the externalEntityIDs of the elements to which this element is part of 74 75 "linkedAttributeValue" is the value of the main attribute of the added external entity. Not mandatory. 76 """ 77 78 self.all_ids.add(ontologyElementID) 79 self.linked_attribute_values[ontologyElementID] = linkedAttributeValue 80 self._attrID2id[linkedAttributeValue]=ontologyElementID 81 self.hierarchy.setdefault(ontologyElementID,[]) 82 83 if( len(isA)==0 ): 84 self.root_ids.add(ontologyElementID) 85 86 self.trees[ontologyElementID] = (isA,isPartOf) 87 88 for current_parent in isA: 89 self.hierarchy.setdefault(current_parent,[]).append(ontologyElementID)
90 91
92 - def _set_external_entities_dict(self, externalEntitiesDict):
93 """ 94 Sets the external entity objects corresponding to the elements of the ontology 95 96 "externalEntitiesDict": Dictionary with all the external entities. Key: externalEntityID. Value: externalEntity Object 97 98 Objects are only required for printing the ontology 99 """ 100 self.externalEntityObjs = externalEntitiesDict
101
103 return self.all_ids
104 105
106 - def linkedAttrID2ID(self, attr_id):
107 return self._attrID2id[attr_id] 108 109 110 #def get_descendants(self, ontologyElementID): 111 # """ 112 # Gets all the descendants, using the "is_a" relation 113 # """ 114 115 # result = sets.Set() 116 117 # for current_descendant_id in self.hierarchy[ontologyElementID]: 118 # if current_descendant_id == ontologyElementID: 119 # sys.stderr.write("Ontology has a loop. An element %s [%s] is a child of itsel?\n" %(current_descendant_id,self.linked_attribute_values[current_descendant_id])) 120 # return result 121 # else: 122 # if current_descendant_id not in result: 123 # result.add(current_descendant_id) 124 # result.update(self.get_descendants(current_descendant_id)) 125 # else: 126 # sys.stderr.write("Ontology has a loop, between %s [%s] and %s [%s]\n" %(current_descendant_id, 127 # self.linked_attribute_values[current_descendant_id], 128 # ontologyElementID, 129 # self.linked_attribute_values[ontologyElementID])) 130 131 return result
132 133
134 - def get_descendants(self, ontologyElementID):
135 """ 136 Gets all the descendants, using the "is_a" relation 137 """ 138 139 if self.precalculated_descendants.has_key(ontologyElementID): 140 return self.precalculated_descendants[ontologyElementID] 141 142 result = sets.Set() 143 #result = [] 144 145 for current_descendant_id in self.hierarchy[ontologyElementID]: 146 if current_descendant_id == ontologyElementID: 147 sys.stderr.write("Ontology has a loop. An element %s [%s] is a child of itself?\n" %(current_descendant_id,self.linked_attribute_values[current_descendant_id])) 148 return result 149 else: 150 if current_descendant_id not in result: 151 result.add(current_descendant_id) 152 result.update(self.get_descendants(current_descendant_id)) 153 # result.update(self.get_descendants(current_descendant_id)) 154 else: 155 sys.stderr.write("Ontology has a loop, between %s [%s] and %s [%s]\n" %(current_descendant_id, 156 self.linked_attribute_values[current_descendant_id], 157 ontologyElementID, 158 self.linked_attribute_values[ontologyElementID])) 159 160 self.precalculated_descendants[ontologyElementID] = result 161 162 return result
163 164
166 """ 167 Returns a list of tuples with the format: (linked_attr, descriptive_attr) 168 """ 169 170 return [ ( self.linked_attribute_values[x],"|".join([ y.value for y in self.externalEntityObjs[x].get_attribute(self.description_attribute)]) ) for x in self.linked_attribute_values ]
171
173 """ 174 Returns a list with the main attribute for all the elements in the ontology 175 """ 176 return self.linked_attribute_values.values()
177
179 """ 180 Returns a list with the external entity ids of all the elements in the ontology 181 """ 182 return self.linked_attribute_values.keys()
183
184 - def has_element(self, linkedAttributeID):
185 """ 186 Returns a boolean indicating if an external entity with this attribute is found in the ontology 187 """ 188 return linkedAttributeID in self.linked_attribute_values
189
190 - def get_parents_ids(self, elementID):
191 """ 192 Returns a list with the parents of the element with this externalEntityID (using the relation is_a) 193 """ 194 return self.trees[elementID][0]
195
196 - def get_part_parents_ids(self, elementID):
197 """ 198 Returns a list with the parents of the element with this externalEntityID (using the relation is_part_of) 199 """ 200 return self.trees[elementID][1]
201 202
203 - def _recursive_tree_print(self, id, outmethod, depth=0):
204 """ 205 Prints recursively in stdout a tree representing the ontology, using the external entity id. 206 207 Only for testing purposes 208 """ 209 210 for x in xrange(depth): 211 outmethod("\t") 212 #outmethod(str(id)) 213 outmethod("%s [%s]" %('|'.join([ x.value for x in self.externalEntityObjs[id].get_attribute(self.description_attribute) ]),self.linked_attribute_values[id])) 214 outmethod("\n") 215 depth = depth+1 216 for current_descendant_id in self.hierarchy[id]: 217 self._recursive_tree_print(current_descendant_id, outmethod, depth)
218 219
220 - def print_tree(self, outmethod=sys.stdout.write):
221 """ 222 Prints recursively in stdout a tree representing the ontology, using the external entity id. 223 224 Only for testing purposes 225 """ 226 227 #print self.root_ids 228 229 for x in self.root_ids: 230 self._recursive_tree_print( id = x, 231 depth = 0, 232 outmethod = outmethod )
233 234
235 - def _recursive_tree_xml(self, id):
236 237 nodes_xml = [ "<node ontologyNodeID=\"%s\" id=\"%s\">" %(self.linked_attribute_values[id], 238 '|'.join([ x.value for x in self.externalEntityObjs[id].get_attribute(self.description_attribute) ])) ] 239 240 for current_descendant_id in self.hierarchy[id]: 241 nodes_xml.extend(self._recursive_tree_xml(current_descendant_id)) 242 243 nodes_xml.append("</node>") 244 return nodes_xml
245 246
247 - def get_xml(self):
248 """ 249 Returns a String with an XML representation of the ontology 250 251 To execute this method, is necessary to load in the ontology all the external Entity Objects 252 """ 253 254 nodes_xml = ["<ontology name=\"%s\">" %self.name] 255 256 for x in self.root_ids: 257 nodes_xml.extend(self._recursive_tree_xml( id = x) ) 258 259 nodes_xml.append("</ontology>") 260 261 return "\n".join(nodes_xml)
262 263
264 - def _traverse_tree_for_leafs(self, id):
265 """ 266 Helper function to reach leafs traversing the tree 267 """ 268 if len(self.hierarchy[id]) == 0: 269 #print self.linked_attribute_values[id], self.hierarchy[id], self.trees[id] 270 nodes = [ ", ".join([ x.value for x in self.externalEntityObjs[id].get_attribute(self.description_attribute) ]) ] 271 else: 272 nodes = [] 273 274 for current_descendant_id in self.hierarchy[id]: 275 nodes.extend(self._traverse_tree_for_leafs(current_descendant_id)) 276 277 return nodes
278 279
280 - def get_leafs(self):
281 """ 282 Returns a list of leafs in the ontology tree 283 To execute this method, is necessary to load in the ontology all the external Entity Objects 284 """ 285 leaf_nodes = [] 286 287 for x in self.root_ids: 288 leaf_nodes.extend(self._traverse_tree_for_leafs( id = x) ) 289 290 return leaf_nodes
291