Package semanticSBMLui :: Module console_views
[hide private]
[frames] | no frames]

Source Code for Module semanticSBMLui.console_views

  1  #!/usr/bin/env python 
  2  ''' 
  3  B{Console User Interface Views} 
  4  all views on a SBML file relevant for semantiSBML  
  5  the views also contain the connection to the cotrollers that modifiy a SBML file 
  6  ''' 
  7  import sys, os, re, copy 
  8  from textwrap import fill 
  9  if not hasattr(__builtins__, 'set'):      
 10      from sets import Set as set 
 11  from PyQt4 import QtCore,QtGui 
 12   
 13  FALSE=0 
 14  TRUE=1 
 15  from libSBAnnotation.config import * 
 16  from semanticSBML.kegg2sbml import kegg2sbml,KEGG2sbmlError 
 17  import libsbml 
 18  from semanticSBML.merge import Merger 
 19  from CustomInteractiveConsole import CustomConsole 
 20  #from base_views import * 
 21  from semanticSBML.annotate import StAnError 
 22   
23 -class Merge_view(QtCore.QObject,Base_Merge_view):
24 ''' 25 merge 2 or more sbml models 26 in 2 steps: 27 - resolve conflict 28 - resolve circular rule definitions 29 '''
30 - def __init__(self,documents,parent):
31 ''' 32 get instances of: the database, the merge class 33 create tab and initialize the inherited class 34 ''' 35 self._parent=parent 36 #self._documents=documents#pop 2 docs out and merge 37 #self.docs=[]#TODO ugly make nice for all docs, remember it's yeild so no pop needed 38 #for d in documents: 39 # self.docs.append(d) 40 #self._document=self.docs[0] 41 #self._merger=Merger(self.docs.pop(0).model,self.docs.pop(0).model) 42 #self.dotfilename='dotfile.tmp' 43 #self.uin_id2rule={}#this variable must be used 44 self.desc2choice={} 45 self.collision=None#this varibale must exist 46 #self._cfg = Config() 47 QtCore.QObject.__init__(self) 48 Base_Merge_view.__init__(self,documents) 49 self.no_more_collisions=False 50 self.no_more_circles=False
51
52 - def run(self):
53 ''' 54 start the commandloop 55 56 this means call L{makeCollisionMenu} if a flag is set continue on for the 57 ''' 58 self.makeCollisionMenu() 59 if self.no_more_collisions: 60 print 'no conflicts move on :)' 61 self.circleMenu(self._merger.find_circle(self.dotfilename)) 62 if self.no_more_circles: 63 newmodel=self.finish() 64 #fileName = self._parent.queryFileName() 65 #self._merger._to_file(fileName) 66 #print 'in merge',fileName 67 self.emit(QtCore.SIGNAL("sigDocumentCreated"),newmodel)#emit signal to ouside to add the new document
68
69 - def makeCollisionMenu(self):
70 ''' 71 build the collision menu for two colliding sbml elemntens, display compare and choose new values 72 table 4*n (n=number of element values) 73 - first row: title of columns 74 - first column:description of values 75 - second column: name or id 76 ''' 77 self.collision=self._merger.find_collision() 78 if not self.collision:#if there are no more collisions exit 79 self.no_more_collisions=True 80 #print 'no more collisions'#DEBUG 81 return True 82 (elmA,elmB,original_contentlist)=self.collision 83 contentlist=copy.copy(original_contentlist)#need a copy as pop is used and the original list should not be modified 84 #------------------------------------------------------------ 85 #ignore the MetaId, Reactants and Products 86 contentlist.pop('MetaId') 87 try: 88 contentlist.pop('ListOfProducts') 89 contentlist.pop('ListOfReactants') 90 except: 91 pass 92 #------------------------------------------------------------ 93 print '%-22s%-30s%-16s%-30s'%('Description','Value A','Conflict','Value B') 94 #make a header line with the name or if not set the id 95 for tkey in ['Name','Id']: 96 if contentlist.has_key(tkey): 97 (a,b,tf)=contentlist.pop(tkey) 98 def sh(instr,maxlen): 99 if len(instr)>maxlen: return instr[0:maxlen-4]+'...' 100 else: return instr
101 print '%-22s%-30s%-16s%-30s'%(tkey,sh(a,30),'',sh(b,30)) 102 break 103 104 self.desc2combo=[] 105 self.combovalue={}#format: {conflict_num:(editable_bool,[choice1,choice2])} 106 self.combo2value={} 107 #sort list of values 108 sortedContentList=[] 109 for n in ['Id','Annotation','Compartment','InitialAmount','InitialConcentration','BoundaryCondition','Constant']: 110 if contentlist.has_key(n): 111 sortedContentList.append((n,contentlist.pop(n))) 112 sortedContentList +=sorted(contentlist.items()) 113 ccount=0 114 for i,(desc,(valA,valB,conflicting)) in enumerate(sortedContentList): 115 if (valA or valB) and not (desc.find('Num') == 0 or desc=='Formula'):#filter empty values 116 strA=self.elemval2str(elmA,desc,valA) 117 strB=self.elemval2str(elmB,desc,valB) 118 if desc == 'Annotation': 119 conflicting=0 120 def an2str(an): 121 noa=len(an.split('\n'))-1 122 an=an.split('\n')[0] 123 if noa: 124 an+= '('+str(noa)+' further annotations)' 125 return an
126 strA=an2str(strA) 127 strB=an2str(strB) 128 conflictstr='' 129 if conflicting: 130 if desc == 'KineticLaw':#uneditable elements 131 choose='choose' 132 if self.desc2choice.has_key(desc): 133 choose=self.desc2choice[desc] 134 self.desc2combo.append((desc,self.desc2choice[desc])) 135 else: 136 self.desc2combo.append((desc,self.elemval2str(elmA,desc,valA))) 137 conflictstr=str(ccount)+' ('+choose+')' 138 self.combovalue[ccount]=(desc,0,[self.elemval2str(elmA,desc,valA), self.elemval2str(elmB,desc,valB)]) 139 self.combo2value[self.elemval2str(elmA,desc,valA)]=valA 140 self.combo2value[self.elemval2str(elmB,desc,valB)]=valB 141 else: 142 choose='choose/edit' 143 if self.desc2choice.has_key(desc): 144 choose=self.desc2choice[desc] 145 print choose 146 self.desc2combo.append((desc,self.desc2choice[desc])) 147 else: 148 self.desc2combo.append((desc,self.elemval2str(elmA,desc,valA))) 149 conflictstr=str(ccount)+' ('+choose+')' 150 self.combovalue[ccount]=(desc,1,[self.elemval2str(elmA,desc,valA), self.elemval2str(elmB,desc,valB)]) 151 ccount+=1 152 elif desc == 'Annotation' or desc.find('ListOf') != -1 : 153 conflictstr='?' 154 else: 155 conflictstr='=' 156 def sh(instr,maxlen): 157 if len(instr)>maxlen: return instr[0:maxlen-4]+'...' 158 else: return instr 159 print '%-22s%-30s%-16s%-30s'%(desc,sh(strA,30),sh(conflictstr,16),sh(strB,30)) 160 161 help = ''' 162 <<Merge: Resolve Conflict>> 163 l use A (left element) 164 r use B (right element) 165 m <CONFLICT_NR> resolve conflict manually 166 c use manually edited values 167 k keep both elements (this will result in an errorous SBML file) 168 ''' 169 locals={ 170 'l':(self.slotResolve_left,'use A'), 171 'r':(self.slotResolve_right,'use B'), 172 'm':(self.manualResolve,'resolve manually'), 173 'c':(self.slotResolve_merge,'use manual values'), 174 'k':(self.slotResolve_keep,'keep both') 175 } 176 CustomConsole(locals,help).run('...',1) 177
178 - def manualResolve(self,num,desc=None):
179 if desc: 180 self.desc2choice[desc]=CustomeConsole().raw_input('new value: ') 181 else: 182 num=int(num) 183 if self.combovalue.has_key(num): 184 (desc,editable,choicelist)=self.combovalue[num] 185 i=0 186 num2c={} 187 for c in choicelist: 188 print i,' use: '+c 189 num2c[i]=c 190 i+=1 191 if editable: 192 print i,'enter a new value' 193 rin=CustomConsole().raw_input('??: ') 194 rin=int(rin) 195 if rin==0: 196 self.desc2choice[desc]=num2c[rin] 197 elif rin==1: 198 self.desc2choice[desc]=num2c[rin] 199 elif rin==2: 200 self.manualResolve(-1,desc) 201 return self.makeCollisionMenu()
202
203 - def slotResolve_merge(self):
204 ''' 205 call L{resolve_collision} for the merged values 206 ''' 207 (elmA,elmB,contentlist)=self.collision 208 desc2type={} 209 for desc,(valA,valB,tf) in contentlist.iteritems(): 210 desc2type[desc]=valA 211 #print desc 212 resDict={} 213 for (desc,combo) in self.desc2combo: 214 if desc.find('ListOf') != -1 or desc == 'KineticLaw':#non editable combo boxes 215 resDict[desc]=self.combo2value[combo] 216 #elif desc == 'KineticLaw': 217 # resDict[desc]=libsbml.parseFormula(str(combo))#TODO tell Marvin about dataype 218 elif desc == 'Math': 219 resDict[desc]=libsbml.parseFormula(combo)#TODO tell Marvin about dataype 220 elif isinstance(desc2type[desc], bool):#editable combo boxes #TODO type conversion should be generic 221 resDict[desc]=bool(combo) 222 elif isinstance(desc2type[desc], int): 223 resDict[desc]=int(combo) 224 elif isinstance(desc2type[desc], float): 225 resDict[desc]=float(combo) 226 else:#TODO type conversion should be generic 227 print 'FIXME NOW new type in backconversion of combobox values: ',desc2type[desc],desc2type[desc].__class__ 228 229 #print 'resDict: ',resDict 230 self._merger.resolve_collision(elmA,elmB,resDict) 231 return self.makeCollisionMenu()
232
233 - def circleMenu(self,circle):
234 ''' 235 show circular rule definitions 236 if no circle were found finish the merging process and return true 237 @param circle: output from find_circle 238 @type circle: {str rulename:alternative circle size} 239 @return: are there no more circles 240 @rtype : bool 241 ''' 242 self.circle=circle 243 if self.circle: 244 #print self.circle#DEBUG 245 (rules,picData)=self.circle 246 print 'Choose one of the following Rules to remove a circular Rule definition' 247 print '%-20s%-40s%s' % ('Rule','Size of Circle for Alternative Rule','Alternative') 248 i=0 249 for k,v in rules.iteritems(): 250 self.uin_id2rule[i]=(k,0) 251 ktmp='['+str(i)+'] '+k 252 i+=1 253 alt='-' 254 if v: 255 alt='['+str(i)+']' 256 self.uin_id2rule[i]=(k,1) 257 i+=1 258 print '%-20s%-40s%s' % (ktmp,v or '-',alt) 259 CustomConsole({'r':(self.slot_remove_circle,'remove circle')},'r <CHOICE_NR> resolve').run('...',1) 260 else: 261 self.no_more_circles=True 262 return 1
263
264 - def close(self, destroy=0):
265 pass
266 #########
267 -class Annotation_view:
268 """create a tab that is split into a treeview and an annotation view, when elemtns in the treeveiw items are clicked the annotationview changes, the annotationview uses the sematicSBML.annotate and semanticSBML.annotationparser api, as well as SemanticSbmlGui_doc functions""" 269
270 - def __init__(self,document):
271 '''get the Annotator, Callback and the database 272 print the treeview of annotations 273 start the interactive console 274 @param document: document class instance of the document that should be annotated 275 ''' 276 self._document=document 277 self.cb=StAn_Callback() 278 self._document.set_callback(self.cb) 279 #-------------------------------------------- 280 #add treeview on the left 281 self.makeTreeView(0) 282 #-------------------------------------------- 283 #add annotation menu on the right 284 #self.makeStAnMenu()#initialize with root: stan menu 285 help=''' 286 <<<Annotation Menu>>> 287 l list elements (without annotations) 288 la list elements and their annotations 289 d <ELEMENT_NUM> delete annoation 290 a <ELEMENT_NUM> add suggested annotaion/ automatically annotate "List of .." or whole Model 291 s <ELEMENT_NUM> <QUERY> search and add identifier 292 f <ELEMENT_NUM> <DB> <ID> add an identfier directly (DB: KEGG, GO ...) 293 q back''' 294 cmddir={ 295 'l':(self.list,'list elemts'), 296 'la':(self.listall,'list elemts'), 297 'd':(self.delete,'delete annotation'), 298 'a':(self.add_suggestion,'add suggestion/automatic'), 299 's':(self.add_search,'add from search'), 300 'f':(self.add,'add id direcly') 301 } 302 CustomConsole(cmddir,help).run('...')
303 - def list(self):
304 ''' 305 wrap L{makeTreeView} 306 do not show annotations 307 ''' 308 self.makeTreeView(0)
309 - def listall(self):
310 ''' 311 wrap L{makeTreeView} 312 show annotations 313 ''' 314 self.makeTreeView(1)
315
316 - def makeTreeView(self,show_annotations):
317 '''create a treeview of the sbml model by using the elementns from the Annotator 318 element nodes annotation status is marked 319 @param show_annotations: show the list incuding the annoattions 320 @type show_annotations: bool 321 ''' 322 #-------------------------------------------- 323 #make the treeview 324 #-------------------------------------------- 325 self.treenode2element={} 326 self.treenode2typecode={} 327 annotation_status=['!!! (annoation missing)','(annotation not supported)','','(bad annotation)'] 328 num=0 329 330 #create root node 331 print num,' Model '+self._document.fileName() 332 self.treenode2typecode[num]=0 333 num += 1 334 335 #create annotate element tree view 336 etypecode = '' 337 list_annotated=1 338 for (elmt,anoh) in self._document.getElementAnnotations(): 339 #list.of node 340 if etypecode != elmt.getTypeCode(): 341 etypecode = elmt.getTypeCode() 342 list_annotated=1 343 self.treenode2typecode[num]=etypecode 344 if etypecode == libsbml.SBML_REACTION: 345 print num," List of Reactions" 346 elif etypecode == libsbml.SBML_COMPARTMENT: 347 print num," List of Compartments" 348 elif etypecode == libsbml.SBML_SPECIES: 349 print num," List of Species" 350 num += 1 351 #element node 352 n=elmt.getName() 353 if not n:#unnamed element 354 if anoh:#but annotated -> get a name from the db 355 (k,v)=anoh.items()[0] 356 nm=self._document.id2str(k,v) or 'id not found' 357 n='['+nm+']' 358 else: 359 n='[Unnamed Element]' 360 i=elmt.getId() 361 if i: 362 n+=' [ID:'+i+']' 363 anots=' ' 364 asnum=self._document.getAnnotationStatus(elmt) 365 if not asnum: 366 anots = '*' 367 elif asnum==1: 368 anots = '.' 369 print num,'\t'+anots+n+annotation_status[asnum] 370 self.treenode2element[num]=elmt 371 372 if show_annotations: 373 if self._document.issetAnnotation(elmt): 374 for key,val in anoh.iteritems(): 375 #nm= 376 print '\t\t'+key+': '+val+' ',self._document.id2str(key,val) or 'id not found' 377 else: 378 if elmt.getAnnotation(): 379 print '\t\tannotation not recognized' 380 else: 381 print '\t\tannotation empty' 382 num += 1
383 384
385 - def makeStAnMenu(self,num):
386 ''' 387 invoke the stupid annotator for a list of elements 388 @param num: element number that will be mapped to the according libsbml element 389 @type num: int 390 ''' 391 print '\t<Automatic annotation>\nAnnotate all elements with the first search hit found' 392 if CustomConsole().raw_input('Annotate Now? (y/n):').lower().strip()[0] == 'y':#Custom Console must provide this functiuon 393 for (elmt,anoh) in self._document.getElementAnnotations(): 394 if self.treenode2typecode[num] == elmt.getTypeCode() or not self.treenode2typecode[num]: 395 try: 396 self._document.addStAnAnnotationLink(elmt,self.cb) 397 print self.cb.flush_buffer() 398 except StAnError, e: 399 print e
400
401 - def add_search(self,elemnum,query):
402 ''' 403 make annotation menu with sarch results 404 @param elemnum: element number that will be mapped to the according libsbml element 405 @type elemnum: int 406 @param query: searchsting 407 @type query: string 408 ''' 409 if self.treenode2element.has_key(int(elemnum)): 410 num2anot={} 411 for i,(val,(db,id)) in enumerate(self._document.getAnnotationSuggestions(self.treenode2element[int(elemnum)],query)): 412 i=str(i) 413 print i,' add'+' '+db+' '+id+' : '+' '+val 414 num2anot[i]=(self.treenode2element[int(elemnum)],db,id) 415 n=CustomConsole().raw_input('Add Annotaion Number (leave blank to cancel):') 416 if n: 417 if num2anot.has_key(n): 418 (e,d,i)=num2anot[n] 419 self.add(e,d,i) 420 else: 421 print 'no such element'
422
423 - def add_suggestion(self,elemnum):
424 ''' 425 part of the annotation menu for single elements 426 @param elemnum: element number that will be mapped to the according libsbml element 427 @type elemnum: int 428 ''' 429 elemnum=int(elemnum) 430 if self.treenode2element.has_key(elemnum): 431 num2anot={} 432 for i,(val,(db,id)) in enumerate(self._document.getAnnotationSuggestions(self.treenode2element[elemnum])): 433 i=str(i) 434 print i+' add'+' '+db+' '+id+' : '+' '+val 435 num2anot[i]=(self.treenode2element[int(elemnum)],db,id) 436 n=CustomConsole().raw_input('Add Annotaion Number (leave blank to cancel):') 437 if n: 438 if num2anot.has_key(n): 439 (e,d,i)=num2anot[n] 440 self.add(e,d,i) 441 elif self.treenode2typecode.has_key(elemnum): 442 self.makeStAnMenu(elemnum) 443 else: 444 print 'no such element'
445
446 - def add(self,elm,db,id):
447 ''' 448 add an annotation link or 449 print error message if annotation is invalid 450 ''' 451 if isinstance(elm, str): 452 elm=self.treenode2element[int(elm)] 453 try: 454 self._document.addAnnotationLink(elm,db,id) 455 except InvalidAnnotationError,e: 456 print "Error: ",str(e)
457
458 - def delete(self,elmnum):
459 '''list annotation (if available) delete annotation from users choice''' 460 ap = annotationparser(self.treenode2element[int(elmnum)]) 461 num2anot={} 462 if ap.containsLinks(): 463 for i,(db,id) in enumerate(ap.getLinks().iteritems()): 464 #nm= 465 print str(i)+' delete '+db+': '+id+' ',self._document.id2str(db,id) or 'id not found' 466 num2anot[str(i)]=(self.treenode2element[int(elmnum)],db,id) 467 n=CustomConsole().raw_input('Delete Annotaion Number (leave blank to cancel):') 468 #if n: 469 #print n 470 if num2anot.has_key(n): 471 (e,d,i)=num2anot[n] 472 self._document.delAnnotationLink(e,d,i) 473 else: 474 if elmt.getAnnotation(): 475 print 'annotation not recognized' 476 else: 477 print 'annotation empty'
478 479
480 -class StAn_Callback:
481 '''callback for the annotator'''
482 - def __init__(self):
483 '''initialize the buffer''' 484 self.buffer='' 485 pass
486
487 - def write(self,str):
488 '''write input to a buffer''' 489 self.buffer+=str 490 print str
491
492 - def flush_buffer(self):
493 '''emty the buffer and return its content''' 494 tmp=self.buffer 495 self.buffer='' 496 return tmp
497 498 #########
499 -class Check_view:
500 """ Display results of the sbmlcheck function in a QListView with icons for differnet messages. 501 Results will appear in a new tab of the mainTabWidget (parent) """ 502
503 - def __init__(self,document):
504 ''' 505 display the checkresults in a treelike list 506 - type of check 507 - information, warning, error 508 ''' 509 self._document=document 510 511 #create check items and add messages as children 512 #for cr in self._document.getCheckResults(): 513 for cr in self._document.check(): 514 print '->'+cr.name+" ("+str(cr.errors)+"/"+str(cr.warnings)+"/"+str(cr.infos)+")" 515 for msg in cr.error_messages: 516 print '\terror: '+msg 517 for msg in cr.warning_messages: 518 print '\twarning: '+msg 519 for msg in cr.info_messages: 520 print '\tinformation:'+msg
521 522 523 #########
524 -class Id2Sbml_view(QtCore.QObject):
525 '''contoll and view for the creation of SBML files from a list of KEGG reaction identifiers'''
526 - def __init__(self):
527 ''' 528 initialize the database 529 ''' 530 QtCore.QObject.__init__(self) 531 532 self._cfg = Config() 533 self.k2sDir=self._cfg.getpath('gui','k2sDirOpenPath') 534 self.rawidlist='' 535 self.react2comp={}
536 537 #-----------------------------------------------------------------------------------------------------
538 - def run(self):
539 self.makeInitMenu()
540 - def makeInitMenu(self):
541 ''' 542 create menu with 543 - input box: 544 - file input 545 - text box manual input 546 - output box: 547 - choose folder button 548 - filename text field 549 - next button (slotNext()) 550 ''' 551 552 553 help=''' 554 <<< ID -> SBML >>> 555 o <FILENAME> Open a File Containing KEGG Reaction Identifiers 556 e <ID1 ID2> Enter a List of KEGG Reaction Identifiers 557 q exit this menu''' 558 #print self.rawidlist 559 cc = CustomConsole({'o':(self.slotNext_f,'open file'),'e':(self.slotNext_l,'insert list'),'q':(self.exit,'exit')},help).run('...')
560 - def exit(self):
561 '''do nothing''' 562 pass
563 - def slotNext_l(self,*idlist):
564 '''join args (idlist) and filter all KEGG rection IDs 565 make mext menu slotNext()''' 566 self.rawidlist='\n'.join(set(re.findall('(R\d{5})',' '.join(idlist)))) 567 self.slotNext()
568 - def slotNext_f(self,*fileNames):
569 '''traverse list of fileNames and check if files are existing 570 if the exist parse all KEGG reaction IDs 571 make next menu slotNext()''' 572 self.rawidlist='' 573 self._cfg.set('gui','I2SinfileOpenPath',os.path.dirname(str(fileNames[0]))) 574 self._cfg.write() 575 print 'fn..',fileNames 576 for fn in filter(os.path.exists, fileNames):#TODO will this work 577 print 'o..',fn 578 f=open(str(fn), 'r').read() 579 f = '\n'.join(set(re.findall('(R\d{5})',f))) 580 self.rawidlist+=f 581 self.outfilename=CustomConsole().raw_input('new filename') 582 self.slotNext()
583
584 - def slotNext(self):
585 ''' 586 make a list of all reaction (2 rows per reaction ) 587 - first row: reaction ids and reaction in word:s 588 - second row: selected compartment for rection 589 ''' 590 #----------------------------------------------------------------------------------------------------- 591 if not self.rawidlist: 592 self.makeInitMenu() 593 else: 594 #print 'in next ',self.rawidlist#DEBUG 595 idlist=self.rawidlist.split() 596 self.rId2cIdcomboBox={} 597 print '\nyou have inserted the following IDs' 598 print '%s\n%s\n%s'%('Reaction Number','ID and Formula','Compartment') 599 for id in idlist: 600 self.react2comp[id]='GO:0005623' 601 f=self._document.id2str_reaction(id) or 'id not found' 602 print '-----\n%s\n%s'%(id+': '+f,'GO:0005623') 603 #------------------------------------------------------------------------------------- 604 help=''' 605 s show current reaction list 606 p <REACT_ID> <GO_ID> choose a different compartment 607 l list compartments in local database 608 c create the SBML file 609 q go back into main ID -> SBML menu 610 ''' 611 cc = CustomConsole({'q':(self.makeInitMenu,'Back'),'c':(self.slotKegg2Sbml,'Create'),'l':(self.listCompartments,'List Compatments'),'p':(self.chooseCompartment,'choose compartment'),'s':(self.chooseCompartment,'reaction list')},help).run('...',1)
612
613 - def listCompartments(self):
614 '''list all avialable compartments''' 615 compartmentList=['GO:0005623 (cell)']#first default entry, kinda ugly this way 616 for i,id in enumerate(self._document.compartmentids): 617 print id+' ('+self._document.id2str_compartment(id)+')' 618 if i%30==0: 619 if CustomConsole().raw_input('---more--- (y/n):').lower().strip()[0]=='n': 620 break
621
622 - def chooseCompartment(self,rid=None,cid=None):
623 '''choose a new compartemt for a reaction id and redisplay reactions''' 624 if self.react2comp.has_key(rid): 625 self.react2comp[rid]=cid.strip().split()[0] 626 for rid,cid in self.react2comp.iteritems(): 627 f=self._document.id2str_reaction(id) or 'id not found' 628 print '-----\n%s\n%s'%(rid+': '+f,cid+' ('+self._ldb.id2str_compartment(cid)+')')
629
630 - def slotKegg2Sbml(self):
631 ''' 632 try to create an sbml file 633 catch errors: not internet connection, output file has no xml extension for output file, wrong input, output file already exists 634 ''' 635 if self.rawidlist: 636 try:#catch no internet connection or ??? 637 k2s=kegg2sbml(str(self.rawidlist).split(),self.react2comp) 638 except KEGG2sbmlError, e: 639 print 'KEGG to SBML Error',e 640 return 641 create=True 642 outfile = CustomConsole().raw_input('output file:') 643 (x,extension)=os.path.splitext(outfile) 644 if extension.lower()!='.xml': 645 outfile += '.xml' 646 if os.path.exists(outfile): 647 create=CustomConsole().raw_input('The file already exists! Overwrite? (y/n): ').lower().strip()[0]=='y' 648 if k2s.getErrors() and create: 649 create=CustomConsole().raw_input('KEGG to SBML Errors:\n'+k2s.getErrors()+'\nCreate Anyway? (y/n): ').lower().strip()[0]=='y' 650 if create: 651 #print 'out',k2s.getModel()#DEBUG 652 self.emit(QtCore.SIGNAL("sigDocumentCreated"),k2s.getModel(),outfile)#emit signal to ouside to add the new document 653 else: 654 return
655 656 657 #########
658 -class Console_view(QtCore.QObject):
659 """ SBML-file 660 this is the main view on the file""" 661
662 - def __init__(self,parent,document):
663 ''' 664 initialize database 665 check document 666 connect signals I{sigDocChecked} I{sigDocModified} I{sigDocAnnotate} I{sigDocActive} 667 ''' 668 QtCore.QObject.__init__(self) 669 self._parent =parent 670 self._document=document 671 self._document.check() 672 self.states = ['','-','-','-'] #0 active 1 check errors 2 annotations missing 3 modified 673 self.refresh() 674 self.connect(self._document, QtCore.SIGNAL("sigDocChecked"), self.refresh) 675 self.connect(self._document, QtCore.SIGNAL("sigDocModified"), self.refresh) 676 self.connect(self._document, QtCore.SIGNAL("sigDocAnnotate"), self.refresh) 677 self.connect(self._document, QtCore.SIGNAL("sigDocAcitve"), self.refresh)
678
679 - def refresh(self):
680 '''refresh all information that will be dispayed''' 681 self.states[2]= str(self._document.getNumNotAnnotatedElements()) 682 if self._document.getNumCheckErrors(): 683 self.states[1]=str(self._document.getNumCheckErrors()) 684 if self._document.isModified(): 685 self.states[3]='*' 686 if self._document.isActive():#TODO not used anymore let wolf decide 687 self.states[0]='*' 688 else: 689 self.states[0]=''
690
691 - def __str__(self):
692 '''return information as string''' 693 return '%-30s%-15s%-22s%s\n' % (self._document.fileName(),self.states[1],self.states[2],self.states[3])
694
695 - def header(self):
696 '''return the header line describing the columns''' 697 return '%3s %-30s%-15s%-22s%s\n' % ('!','filename','check errors','missing annotations','modified')
698
699 - def close(self, destroy=0):
700 '''do nothing''' 701 pass
702