Package semanticSBML :: Module merge_datamodel
[hide private]
[frames] | no frames]

Source Code for Module semanticSBML.merge_datamodel

  1  ''' 
  2  Datamodel used for the merging 
  3  ''' 
  4  #////////////////////////////////////////////////////////////////////////////////// 
  5  #external libaries 
  6  import libsbml 
  7  import sys  
  8  #semanticSBML libraries 
  9  import libSBAnnotation.config 
 10  import annotate 
 11  import merge_logic 
 12  import sbo 
 13  import xmlobject 
 14   
 15  #////////////////////////////////////////////////////////////////////////////////// 
16 -class MergeError(Exception):
17
18 - def __init__(self,message):
19 self.errorMessage = message
20
21 - def __repr__(self):
22 return self.errorMessage
23
24 - def __str__(self):
25 return self.errorMessage
26
27 -class MergeBioQuantityLocationError(MergeError):
28 - def __init__(self,message):
29 self.errorMessage = 'Error in Merge_BioQuantity: %s'% message
30 #//////////////////////////////////////////////////////////////////////////////////
31 -class MergeBase:
32 ''' 33 The MergeBase provides basic values that are needed to handle libsbml elements 34 - the libsbml element itself 35 - the model representation (L{OriginModel}) belonging to the element 36 - the element type e.g. reaction 37 - a string representation of the element (element name or id) 38 '''
39 - def __init__(self,libsbml_element,merge_model):
40 self.libsbml_element = libsbml_element 41 if not merge_model: self.libsbml_model = None 42 else: self.libsbml_model = merge_model.libsbml_model 43 self.type = libsbml_element.getElementName() 44 self.repr = libsbml_element.getName() or libsbml_element.getId() 45 self.merge_model = merge_model
46 #//////////////////////////////////////////////////////////////////////////////////
47 -class SubBioentity():
48 ''' 49 The external identity of a L{OriginElement} is defined by this class. 50 It stores MIRIAM annotations that links the element to external databases. 51 Functions for getting and removing L{Annotation}s are provided. 52 '''
53 - def __init__(self,libsbml_element):
54 #instance variable 55 self.miriam_annotation_element=annotate.ElementAnnotations(libsbml_element,True) 56 #class methods 57 self.remAnnotation=self.miriam_annotation_element.remAnnotation#remove a single L{Annotation} from the element 58 self.getMiriamAnnotations=self.miriam_annotation_element.getAnnotations 59 self.unsetAnnotations=self.miriam_annotation_element.unsetAnnotations 60 self.addAnnotation=self.miriam_annotation_element.addAnnotation 61 62 self.sbo_annotation_element = sbo.SboElement(libsbml_element) 63 self.getSboTerm = self.sbo_annotation_element.getSboTerm 64 self.setSboAnnotation = self.sbo_annotation_element.setSbo
65 66 #//////////////////////////////////////////////////////////////////////////////////
67 -class SubBioquantity(MergeBase):
68 - def __init__(self,libsbml_element,merge_model):
69 MergeBase.__init__(self,libsbml_element,merge_model) 70 #class method 71 self.searchUnit= lambda x: self.merge_model.global_unit_defs[x]
72 - def getBioEntities(self):
73 raise NotImplementedError
74 - def setBioEntities(self,entities):
75 pass
76 - def getQuantityType(self):
77 return ''
78 - def setQuantityType(self,type):
79 pass
80 - def getUnit(self,refresh=False):
81 raise NotImplementedError
82 - def setUnit(self,unitdef):
83 if self.type != 'reaction':#kinda destroys the sense of this interface but its more visual here 84 self.unit=unitdef
85 - def getLocation(self):
86 raise NotImplementedError
87 - def setLocation(self,location):
88 self.location=location
89 #//////////////////////////////////////////////////////////////////////////////////
90 -class SubBioquantitySpecies(SubBioquantity):
91 ####################################
92 - def getQuantityType(self):
93 #Sarah Keating said only this is needed 94 if self.libsbml_element.getHasOnlySubstanceUnits(): 95 return 'Amount' 96 else:#it is a conentration 97 return 'Concentration'
98 ####################################
99 - def setQuantityType(self,type):
100 if type=='Concentration': 101 self.libsbml_element.setHasOnlySubstanceUnits(False) 102 if type =='Amount': 103 self.libsbml_element.setHasOnlySubstanceUnits(True)
104 ####################################
105 - def getUnit(self):
106 if self.getQuantityType == 'Concentration': 107 substance=self.merge_model.global_unit_defs['substance'] 108 su=self.libsbml_element.getSubstanceUnits() 109 if su: 110 substance = self.searchUnit(su) 111 volume = self.location.getUnit(True)#TODO TODO TODO this is not a solution, why can we not deepcopy the unit?? 112 vo=self.libsbml_element.getSpatialSizeUnits() 113 if vo: 114 volume = self.searchUnit(vo) 115 116 return UnitDef(unit_defs=(substance,volume)) 117 else: 118 units=self.libsbml_element.getUnits() 119 if units: 120 return self.searchUnit(units) 121 else: 122 return self.merge_model.global_unit_defs['substance']
123 ####################################
124 - def getLocation(self):
125 return self.merge_model.id2merge_element[self.libsbml_element.getCompartment()]
126 127 #-----------------------------------------------
128 -class SubBioquantityReaction(SubBioquantity):
129 - def __init__(self,libsbml_element,merge_model):
130 SubBioquantity.__init__(self,libsbml_element,merge_model) 131 self.entity_types=['Reactant','Modifier','Product']
132 133 ####################################
134 - def getBioEntities(self):#good
135 ''' 136 @rtype entities: {'Reactant':[],'Modifier':[],'Product':[]} 137 ''' 138 ret={'Reactant':[],'Modifier':[],'Product':[]} 139 #try: 140 for part in self.entity_types: 141 for i in range(getattr(self.libsbml_element,'getNum%ss'%part)()): 142 ret[part].append(self.merge_model.id2merge_element[getattr(self.libsbml_element,'get%s'%part)(i).getSpecies()]) 143 #except KeyError,e: 144 # tmp=self.merge_model.id2merge_element.keys() 145 # tmp.sort() 146 # print 'grsslsl ',tmp,e 147 # sdlfk 148 return ret
149 150 ####################################
151 - def setBioEntities(self,entities):#TODO check
152 ''' 153 @type entities: {'Reactant':[],'Modifier':[],'Product':[]} 154 ''' 155 for type in self.entity_types: 156 list_of = getattr(self.libsbml_element,'getListOf'+type+'s')() 157 list_of.clear() 158 for me in entities[type]: 159 species_reference=getattr(self.libsbml_element,'create'+type)() 160 if me.getTuple(): 161 species_reference.setSpecies(me.getTuple().getMergedElement().getId()) 162 else: 163 species_reference.setSpecies(me.getId()) 164 165 ####################################
166 - def getUnit(self):
167 time=self.merge_model.global_unit_defs['time'] 168 return UnitDef(unit_defs=(self.merge_model.global_unit_defs['substance'],time))
169 170 ####################################
171 - def getLocation(self):
172 res=[] 173 #tmp=self.merge_model.id2merge_element.keys().sort() 174 #tmp.sort() 175 #print 'id2merge_element ',tmp 176 for type in self.entity_types: 177 tmp_res=set() 178 if getattr(self.libsbml_element,'getNum'+type+'s')()>0: 179 for n in range(getattr(self.libsbml_element,'getNum'+type+'s')()): 180 tmp_res.add(self.merge_model.id2merge_element[getattr(self.libsbml_element,'get'+type)(n).getSpecies()].getLocation()) 181 res.append(list(tmp_res)) 182 return res 183 184 #------------------------------------------------
185 -class SubBioquantityCompartment(SubBioquantity):
186 #####
187 - def __init__(self,libsbml_element,merge_model):
188 SubBioquantity.__init__(self,libsbml_element,merge_model) 189 self.qtypes=['length', 'area', 'volume']
190 191 ####################################
192 - def getQuantityType(self):
193 dim2type=dict(zip(range(1,4),self.qtypes)) 194 try: 195 return dim2type[self.libsbml_element.getSpatialDimensions()] 196 except KeyError: 197 return ''
198 ####################################
199 - def setQuantityType(self,type):
200 type2dim=dict(zip(self.qtypes,range(1,4))) 201 try: 202 self.libsbml_element.setSpatialDimensions(type2dim[type]) 203 except KeyError: 204 raise MergeError('Unknown Quantity Type')
205 ####################################
206 - def getUnit(self):
207 units=self.libsbml_element.getUnits() 208 if not units: 209 dim2type=dict(zip(range(1,4),self.qtypes)) 210 spacialDimension=self.libsbml_element.getSpatialDimensions() 211 return self.merge_model.global_unit_defs[dim2type[spacialDimension]] 212 else: 213 return self.searchUnit(units)
214 ####################################
215 - def getLocation(self):
216 if self.libsbml_element.isSetOutside(): 217 if self.libsbml_element.getOutside(): 218 return self.merge_model.id2merge_element[self.libsbml_element.getOutside()] 219 else: 220 raise MergeBioQuantityLocationError('requeue location since it is linking to a yet unknown location')
221 #------------------------------------------------
222 -class SubBioquantityParameter(SubBioquantity):
223 ####################################
224 - def getUnit(self):
225 unit=self.libsbml_element.getUnits() 226 if not unit: 227 #sys.stderr.write( 'Warning: parameter %s unit not set!'%self.libsbml_element.getId()) 228 return None 229 else: 230 return self.searchUnit(unit)
231 #//////////////////////////////////////////////////////////////////////////////////
232 -class SubModelstatement(MergeBase):
233 - def __init__(self,libsbml_element,merge_model):
234 MergeBase.__init__(self,libsbml_element,merge_model) 235 self.statement=None
236 - def getFast(self):
237 raise NotImplementedError
238 - def setFast(self,val):
239 raise NotImplementedError
240 - def getConstant(self):
241 if self.type in ['species','parameter','compartment']: 242 return self.libsbml_element.getConstant() 243 else: 244 raise NotImplementedError
245 - def setConstant(self,val):
246 if self.type in ['species','parameter','compartment']: 247 if isinstance(val,str): 248 if val=='True': val=True 249 elif val=='False': val=False 250 else: raise MergeError(' setConstant failed because % was inserted'%val) 251 if not isinstance(val, bool):val=bool(val) 252 self.libsbml_element.setConstant(val) 253 self.constant=val 254 else: 255 raise NotImplementedError
256
257 - def getCharge(self):
258 raise NotImplementedError
259 - def setCharge(self,val):
260 raise NotImplementedError
261 - def getReversible(self):
262 raise NotImplementedError
263 - def setReversible(self,val):
264 raise NotImplementedError
265 - def getSize(self):
266 raise NotImplementedError
267 - def setSize(self,val):
268 raise NotImplementedError
269 - def getQuantity(self):
270 raise NotImplementedError
271 - def setQuantity(self,val):
272 raise NotImplementedError
273 - def getStatement(self):
274 ''' 275 overwritten by reaction subclass 276 ''' 277 if self.statement: return self.statement#must return this since only later on statements will be collected 278 math_obj=None 279 if self.merge_model.id2rule.has_key(self.libsbml_element.getId()): 280 #if self.statement: 281 # sys.stderr.wirte('ooops big error, I wasnt sure this will happen, more than one rule for this element',self.libsbml_element.getId()) 282 math_obj = self.merge_model.id2rule[self.libsbml_element.getId()] 283 284 #search for attached function definitions 285 if math_obj: 286 self._attatchFunctionDefinition(math_obj) 287 return math_obj
288
289 - def setStatement(self,math_obj):
290 self.statement = math_obj
291 - def getInitialAssignment(self):
292 if self.merge_model.id2assignment.has_key(self.libsbml_element.getId()): 293 ia=self.merge_model.id2assignment[self.libsbml_element.getId()] 294 self._attatchFunctionDefinition(ia) 295 return ia
296
297 - def setInitialAssignment(self,math_obj):
298 self.initialAssignment=math_obj
299
300 - def _attatchFunctionDefinition(self,math_obj):
301 for en in merge_logic.BioRelations().getMathElementNames(math_obj.getMath()): 302 if self.merge_model.id2function_definition.has_key(en): 303 try: 304 math_obj.functionDefinitions.append(self.merge_model.id2function_definition[en].clone()) 305 except AttributeError,e: 306 math_obj.functionDefinitions=[self.merge_model.id2function_definition[en].clone()]
307 #//////////////////////////////////////////////////////////////////////////////////
308 -class SubModelstatementSpecies(SubModelstatement):
309 ####################################
310 - def getCharge(self):
311 return self.libsbml_element.getCharge()
312 ####################################
313 - def setCharge(self,val):
314 if not isinstance(val,float):val=float(val) 315 return self.libsbml_element.setCharge(val) 316 self.charge=val
317 ####################################
318 - def getQuantity(self):
319 if self.libsbml_element.isSetInitialConcentration(): 320 return ('Concentration',self.libsbml_element.getInitialConcentration()) 321 if self.libsbml_element.isSetInitialAmount(): 322 return ('Amount',self.libsbml_element.getInitialAmount())
323 ####################################
324 - def setQuantity(self,val):
325 if not isinstance(val,tuple): 326 raise OriginModelStatementError('ModelStatement quantity for a species must be a tuple (type,value)') 327 type=val[0] 328 value=val[1] 329 if not isinstance(value, float):value=float(value) 330 if type=='Concentration': 331 self.libsbml_element.setInitialConcentration(value) 332 elif type=='Amount': 333 self.libsbml_element.setInitialAmount(value) 334 else: 335 nononothisisnotright 336 self.quantity=val
337 338 #------------------------------------------------
339 -class SubModelstatementReaction(SubModelstatement):
340 ####################################
341 - def getFast(self):
342 return self.libsbml_element.getFast()
343 ####################################
344 - def setFast(self,val):
345 if not isinstance(val, bool):val=bool(val) 346 self.libsbml_element.setFast(val) 347 self.fast=val
348 349 ####################################
350 - def getReversible(self):
351 return self.libsbml_element.getReversible()
352 ####################################
353 - def setReversible(self,val):
354 if not isinstance(val, bool):val=bool(val) 355 self.libsbml_element.setReversible(val) 356 self.reversible=val
357 358 ####################################
359 - def getStatement(self):
360 math_obj = self.libsbml_element.getKineticLaw() 361 #search for attached function definitions 362 if math_obj: 363 self._attatchFunctionDefinition(math_obj) 364 return math_obj
365 ####################################
366 - def setStatement(self,math_obj):
367 #get the correct rule or kinetic law from other model 368 self.statement = math_obj 369 self.libsbml_element.setKineticLaw(math_obj)
370 371 #------------------------------------------------
372 -class SubModelstatementCompartment(SubModelstatement):
373 ####################################
374 - def getSize(self):
375 if self.libsbml_element.isSetSize(): 376 return self.libsbml_element.getSize()
377 ####################################
378 - def setSize(self,val):
379 if not isinstance(val, float):val=float(val) 380 self.libsbml_element.setSize(val)
381 382 383 #------------------------------------------------
384 -class SubModelstatementParameter(SubModelstatement):
385 ####################################
386 - def getQuantity(self):
387 if self.libsbml_element.isSetValue(): 388 return ('Value',self.libsbml_element.getValue())
389 ####################################
390 - def setQuantity(self,val):
391 if not isinstance(val, float):val=float(val) 392 return self.libsbml_element.setSize(val[1])
393 394 #//////////////////////////////////////////////////////////////////////////////////
395 -class OriginElement(MergeBase):
396 ''' 397 abstraction of a biological entity for merging 398 399 wrap class that consists of three sublcass of the base type 400 - SubBioentity 401 - SubBioquantity 402 - SubModelstatement 403 '''
404 - def __init__(self,libsbml_element,merge_model):
405 406 #..................................... 407 MergeBase.__init__(self,libsbml_element,merge_model) 408 409 410 #..................................... 411 #libsbml metadata in every element TODO kill stuff not needed 412 self.name = libsbml_element.getName() 413 self.id = libsbml_element.getId() 414 self.newid = self.id 415 #global unique idenfier 416 self.mid=self.id 417 #self.mid='%s-%s'%(self.id,str(self.merge_model.mid)) 418 #..................................... 419 #link to OriginElements that show a similarity 420 self._merge_tuple_candidates=set() 421 self.tuple=None 422 #..................................... 423 #signal for messgages to outside funcitons 424 self.sig_tuple_changed=None 425 #..................................... 426 #defined by 427 #use command dispatcher pattern to get the right subclass 428 self._bioentity = SubBioentity(self.libsbml_element) 429 self._bioquantity = globals()['SubBioquantity%s'%self.type.title()](self.libsbml_element,merge_model) 430 self._modelstatement = globals()['SubModelstatement%s'%self.type.title()](self.libsbml_element,merge_model) 431 #create a dictionary of all attributes so they can be directly accessed 432 self._allattributes = dict([(x,self._bioentity) for x in dir(self._bioentity) if not '_' == x[0]]+\ 433 [(x,self._bioquantity) for x in dir(self._bioquantity) if not '_' in x]+\ 434 [(x,self._modelstatement) for x in dir(self._modelstatement) if not '_' in x])
435 #..................................... 436 437
438 - def __getattr__(self, n):
439 ''' 440 realize wrap pattern! 441 make methods of the sub objects 442 - SubBioquantity 443 - SubBioentity 444 - SubModelstatement 445 directly accessible 446 ''' 447 if n in self._allattributes: 448 return getattr(self._allattributes[n], n) 449 else: 450 raise AttributeError, n
451
452 - def getDepends_onElements(self):
453 return self.merge_model.getElementsDependsOn(self)
454
455 - def getDependingElements(self):
456 return self.merge_model.getDependingElements(self)
457
458 - def connect_view_functions(self,tuple_changed_fkt):
459 ''' 460 set an external function that should be executed when the tuple this element belongs to is changed 461 @type tuple_changed_fkt: function pointer 462 ''' 463 #print 'e: connect view fkt'#DEBUG 464 self.sig_tuple_changed=tuple_changed_fkt
465
466 - def addTupleCandidate(self,element,force=False):
467 ''' 468 add and element to the list of similar elements 469 @type element: OriginElement 470 ''' 471 neighbous=[] 472 if self.tuple and not force:neighbous=self.tuple.getElements() 473 if self.merge_model!=element.merge_model and not (element in neighbous): 474 self._merge_tuple_candidates.add(element)
475
476 - def addTupleCandidates(self,elements):
477 ''' 478 update the list of similar elements 479 @type elements: [OriginElement] 480 ''' 481 for e in elements: 482 self.addTupleCandidate(e)
483
484 - def getTupleCanidates(self):
485 ''' 486 returns a list of similar elements, elements that have matching MIRIAM annotations 487 @rtype: [OriginElement] 488 ''' 489 return list(self._merge_tuple_candidates)
490 - def getTuple(self):
491 ''' 492 returns the L{MergeTuple} the element instance belongs to, if it does not belong to an element None is returnend 493 @rtype: MergeTuple or None 494 ''' 495 return self.tuple
496 - def setTuple(self,tuple):
497 ''' 498 set the L{MergeTuple} the element belongs to 499 if an external function of a view is set, call the function so the view can be updated 500 @type tuple: MergeTuple 501 ''' 502 #global vars 503 #print 'tuple set',tuple,self.mid#DEBUG 504 old_tuple=self.tuple 505 self.tuple=tuple 506 if self.sig_tuple_changed and self.tuple!=old_tuple: 507 #TODO bad hack we need a global switch here to check wich merge phase we are!!!!!!!!!!!!!!!!! 508 #add elements to update queue 509 merge_logic.BioRelations().elements_update_queue=merge_logic.BioRelations().elements_update_queue.union(self.getDependingElements()) 510 #update the external view function 511 #print 'sending signal tuple changed'#DEBUG 512 self.sig_tuple_changed(self)
513 #print self.mid,'tuple set:',self.getTuple()
514 - def setId(self,id):
515 ''' 516 set the "new" id, this identifier is globally unique in the merged model 517 @type id: str 518 ''' 519 self.newid=id
520 - def getId(self):
521 return self.newid
522 #////////////////////////////////////////////////////////////////////////////////// 523 #class MergedElement(OriginElement): 524 # pass 525 #////////////////////////////////////////////////////////////////////////////////// 526 #////////////////////////////////////////////////////////////////////////////////// 527 #class MergeTuple: 528 # pass 529 #//////////////////////////////////////////////////////////////////////////////////
530 -class OriginModel:
531 ''' 532 abstraction of a model for merging 533 a model contains biological entities that can be merged 534 '''
535 - def __init__(self,libsbml_model,mid):
536 ''' 537 ''' 538 #-------------------------------------- 539 self.libsbml_model = libsbml_model 540 self.mid = mid 541 self.repr = self.libsbml_model.getName() or self.libsbml_model.getId()# or libsbml_model.fileName 542 #-------------------------------------- 543 self.global_unit_defs={} 544 self._getUnits() 545 #-------------------------------------- 546 #get assignment/rate rules 547 self.id2rule = self._getRules() 548 #-------------------------------------- 549 #get initital assignments 550 self.id2assignment={} 551 for asm in list(self.libsbml_model.getListOfInitialAssignments()): 552 self.id2assignment[asm.getId()]=asm 553 #-------------------------------------- 554 self.id2function_definition={} 555 for fd in list(self.libsbml_model.getListOfFunctionDefinitions()): 556 self.id2function_definition[fd.getId()]=fd 557 self._buildElements()
558
559 - def _buildElements(self):
560 #//////////////////////////////////////////////////////////////////////////// 561 #//////////////////////////////////////////////////////////////////////////// 562 #-------------------------------------- 563 self._merge_elements=[] 564 #process compartments first since they are neede for units etc 565 compartment_queue=list(self.libsbml_model.getListOfCompartments()) 566 while compartment_queue: 567 element = compartment_queue.pop(0) 568 try: 569 self._merge_elements.append(OriginElement(element,self)) 570 except MergeBioQuantityLocationError: 571 compartment_queue.append(element) 572 #get all merge elements 573 for listname in ("Species", "Parameters", "Reactions"):#TODO must extend the list (), outsource to XML file 574 for element in getattr(self.libsbml_model, 'getListOf' + listname)(): 575 self._merge_elements.append(OriginElement(element,self)) 576 #-------------------------------------- 577 self.id2merge_element=dict([(x.id, x) for x in self._merge_elements]) 578 #print 'id2merge_element: ',self.id2merge_element.keys() 579 #-------------------------------------- 580 #build mapping of libsmbl-element-type to merge-elements 581 self._type2merge_elements={'species':[],'parameter':[],'reaction':[],'compartment':[]} 582 for me in self._merge_elements: 583 self._type2merge_elements[me.type].append(me) 584 #-------------------------------------- 585 #build element dependency dicts 586 self.element_depends_on = {} 587 self.elements_depending_on = {} 588 589 for e in self.getElements(): 590 self.element_depends_on[e] = self._dependingElements(e) 591 for de in self.element_depends_on[e]: 592 if de in self.elements_depending_on: self.elements_depending_on[de].add(e) 593 else: self.elements_depending_on[de]=set([e]) 594 for e in [x for x in self.getElements() if not x in self.elements_depending_on.keys()]: 595 self.elements_depending_on[e]=set([])
596
597 - def getElements(self):
598 return self._merge_elements
599
600 - def getElementsByType(self,type):
601 type2compare_types = {#TODO write this into an xml file 602 'species':['species','parameter'], 603 'parameter':['parameter','species','compartment'], 604 'reaction':['reaction'], 605 'compartment':['compartment','parameter'], 606 } 607 res=[] 608 for t in type2compare_types[type]: 609 res+=self._type2merge_elements[t] 610 return res
611
612 - def _getRules(self):
613 out={} 614 for rule in list(self.libsbml_model.getListOfRules()): 615 if isinstance(rule, libsbml.AssignmentRule) or isinstance(rule, libsbml.RateRule): 616 out[rule.getVariable()]=rule 617 elif isinstance(rule, libsbml.AlgebraicRule):#TODO wirte this in merger as check at the beginning 618 raise MergeError('AlgebraicRules are currently not supported.') 619 return out
620
621 - def _getUnits(self):
622 ''' 623 build a list of units defined in the model 624 complete list with standard units 625 this funtion takes no input and creates no output but fills self.global_unit_defs 626 ''' 627 #---------------------------------------- 628 #look up units in the model 629 for ud in list(self.libsbml_model.getListOfUnitDefinitions()): 630 self.global_unit_defs[ud.getId()]=UnitDef(ud) 631 #---------------------------------------- 632 #get standard units, and fill if not already set, check for errors 633 x = xmlobject.XMLFile(path=libSBAnnotation.config.Config().getpath('resources','libsbml_resources')) 634 for unit in x.root.DefaultUnitDefinitions[0].unit: 635 if not self.global_unit_defs.has_key(unit.id): 636 self.global_unit_defs[unit.id]=UnitDef(default_unit_def_name=unit.id) 637 for unit in x.root.knownUnits[0].kinds.split(): 638 if not self.global_unit_defs.has_key(unit): 639 self.global_unit_defs[unit]=UnitDef(default_unit_def_name=unit)
640
641 - def _dependingElements(self,ielement):
642 ''' 643 get a list of elements this element depends on 644 ''' 645 #print 'get dependin on',self.type,self.mid#DEBUG 646 647 out=[] 648 #-------------------------------- 649 #get location elements 650 if ielement.type == 'reaction': 651 for els in ielement.getLocation()+ielement.getBioEntities().values():#get reaction participants and their locations 652 for e in els: 653 if e: out.append(e) 654 else: 655 try: 656 if ielement.getLocation(): out.append(ielement.getLocation()) 657 except NotImplementedError: 658 pass 659 #-------------------------------- 660 #get elements in mathematical statements 661 if ielement.getStatement(): 662 out += [self.id2merge_element[n] for n in merge_logic.BioRelations().getMathElementNames(ielement.getStatement().getMath()) if n in self.id2merge_element] 663 664 return set(out)
665 #print 'a',[e.mid for e in self._depends_on]#DEBUG 666
667 - def getDependingElements(self,element):
668 ''' 669 get a list of elements depending on the inserted element 670 @rtype: set(L{OriginElement}) 671 ''' 672 return [self.id2merge_element[ret] for ret in self.elements_depending_on[element] if isinstance(ret,str)]+[ret for ret in self.elements_depending_on[element] if not isinstance(ret,str)]
673
674 - def getElementsDependsOn(self,element):
675 ''' 676 get e list of elements the inserted element depends on 677 @rtype: set(L{OriginElement}) 678 ''' 679 return [self.id2merge_element[ret] for ret in self.element_depends_on[element] if isinstance(ret,str)]+[ret for ret in self.element_depends_on[element] if not isinstance(ret,str)]
680 #////////////////////////////////////////////////////////////////////////////////// 681
682 -class MergedModel(OriginModel):
683 - def __init__(self,libsbml_model,origin_models):
684 OriginModel.__init__(self,libsbml_model,'M') 685 self.id2merge_element={} 686 self.global_unit_defs={} 687 self.id2rule={} 688 for m in origin_models: #did,doc in enumerate(origin_models): 689 #model = doc.getModel() 690 #m = OriginModel(model,did) 691 self.id2merge_element.update(m.id2merge_element) 692 self.global_unit_defs.update(m.global_unit_defs) 693 self.id2rule.update(m.id2rule)
694
695 - def refresh(self):
696 OriginModel.__init__(self,self.libsbml_model,'M')
697 - def _buildElements(self):
698 pass
699 - def addElement(self,element):
700 self.id2merge_element[element.getId()]=element
701 - def remElement(self,element):
702 self.id2merge_element.pop(element.getId())
703 #////////////////////////////////////////////////////////////////////////////////// 704 #////////////////////////////////////////////////////////////////////////////////// 705 706 707 708 #//////////////////////////////////////////////////////////////////////////////////
709 -class UnitDef:
710 ''' 711 unit definition 712 can contain multiple L{Unit}s 713 '''
714 - def __init__(self,libsbml_unit_definition=None,default_unit_def_name='',unit_defs=[]):
715 ''' 716 either a libsbml.UnitDefinition is inserted or the name of a default unit, 717 the default units are looked up in the libsbmlresource 718 719 @type libsbml_unit_definition: L{libsbml.UnitDefinition} 720 @type default_unit_def_name: str 721 @type unit_items= [Unit] 722 ''' 723 self.id='' 724 self.unit_items=[] 725 self.unit_defs=() 726 self.type='' 727 self.libsbml_ud=None 728 729 if libsbml_unit_definition:#construct unit by libsbml.UnitDefinition 730 self.type='libsbml' 731 self.libsbml_ud=libsbml_unit_definition 732 self.id=libsbml_unit_definition.getId() 733 for unit_item in list(libsbml_unit_definition.getListOfUnits()): 734 self.unit_items.append(Unit(libsbml.UnitKind_toString(unit_item.getKind()),unit_item.getScale() or 0.0 ,unit_item.getMultiplier() or 1.0,unit_item.getExponent())) 735 elif default_unit_def_name:#construct unit by default unit def name 736 self.type='default' 737 x = xmlobject.XMLFile(path=libSBAnnotation.config.Config().getpath('resources','libsbml_resources')) 738 for xml_unit in x.root.DefaultUnitDefinitions[0].unit:#predefined units 739 if xml_unit.id==default_unit_def_name: 740 try: 741 exponent=xml_unit.exponent 742 except: 743 exponent=1.0 744 self.unit_items.append(Unit(kind=xml_unit.kind,exponent=exponent)) 745 break 746 else:#predefined kinds 747 self.unit_items.append(Unit(default_unit_def_name)) 748 elif unit_defs:#contruct unit by 749 self.type='composed' 750 self.unit_defs=unit_defs 751 else: 752 raise MergeError('UnitDef was not properly initialized')
753
754 - def toHTML(self):
755 ''' 756 return a html string representation of the unit definition 757 ''' 758 seperator='*' 759 res='' 760 761 if self.unit_defs and self.unit_items: 762 return self.unit_defs[0].toHTML() + '*' + self.unit_defs[1].unit_items[0].toHTML(-1.0) 763 else: 764 for unit in self.unit_items: 765 res+=unit.toHTML()+seperator 766 return res[:-1]
767
768 - def toStr(self):
769 return str(self)
770 #@toStr
771 - def __str__(self):
772 ''' 773 return a string representation of the unit 774 ''' 775 res='' 776 seperator=' * ' 777 if self.unit_defs: 778 return self.unit_defs[0].toStr()+' * '+self.unit_defs[1].unit_items[0].toStr(-1.0) 779 else: 780 for unit in self.unit_items: 781 res +='%s%s'%(unit.toStr(),seperator) 782 return res[:-3]
783 784 #//////////////////////////////////////////////////////////////////////////////////
785 -class Unit:
786 - def __init__(self,kind,scale=0.0,multiplier=1.0,exponent=1.0):
787 known_units=xmlobject.XMLFile(path=libSBAnnotation.config.Config().getpath('resources','libsbml_resources')).root.knownUnits[0].kinds.split() 788 if kind in known_units: 789 self.kind=kind 790 else: 791 raise MergeError('Unknown unit kind \'%s\' '%kind) 792 self.scale=float(scale) 793 self.multiplier=float(multiplier) 794 self.exponent=exponent
795 - def toStr(self,exponent_mulitiplier=1.0):
796 return 'Kind: %s | Scale: %s | Mulitiplier: %s | Exponent %s'%(self.kind,self.scale,self.multiplier,self.exponent*exponent_mulitiplier)
797 - def toHTML(self,exponent_mulitiplier=1.0):
798 res='' 799 if self.multiplier!=1.0: 800 res+='%s*'%self.multiplier 801 res+=self.kind 802 if self.scale!=0.0: 803 res+='*10<sup>%s</sup>'%self.scale 804 if self.exponent!=1.0 or exponent_mulitiplier!=1: 805 res='(%s)<sup>%s</sup>'%(res,self.exponent*exponent_mulitiplier) 806 return res
807