Package Pmv :: Module pdb2pqrCommands
[hide private]
[frames] | no frames]

Source Code for Module Pmv.pdb2pqrCommands

  1  ############################################################################ 
  2  # 
  3  # Author:  Ruth Huey, Michel Sanner 
  4  # 
  5  # Copyright: M. Sanner TSRI 2004 
  6  # 
  7  ############################################################################# 
  8   
  9  # $Header: /opt/cvs/python/packages/share1.5/Pmv/pdb2pqrCommands.py,v 1.2 2006/04/08 01:09:25 sanner Exp $ 
 10  # 
 11  # $Id: pdb2pqrCommands.py,v 1.2 2006/04/08 01:09:25 sanner Exp $ 
 12  # 
 13   
 14   
 15  """ 
 16  This Module implements 'setup_Pdb2Pqr' a command to process molecules using  
 17      pdb2pqr according to a specified forcefield: 'amber', 'charm' or 'parse' 
 18   
 19      Processing options include: 
 20          'debump': whether to debump heavy atoms 
 21          'hopt': whether to run hydrogen optimization 
 22          'hdebump': whether to debump hydrogens  [if not, they are randomized] 
 23          'watopt': whether to optimize water hydrogens 
 24          'hbond': whether to print hydrogen bonding summary 
 25   
 26      The processed molecule can be written to a pqr file. 
 27   
 28      Additional options include: 
 29          'updateMol': whether to update the current pmv molecule 
 30          'newMol': whether to build a new updated copy of the pmv molecule 
 31       
 32  """ 
 33   
 34  import Tkinter, Pmw 
 35  from string import strip 
 36   
 37  #PMV 
 38  from ViewerFramework.VFCommand import CommandGUI 
 39  from ViewerFramework.VF import AddAtomsEvent 
 40  from Pmv.mvCommand import MVCommand 
 41  from mglutil.gui.InputForm.Tk.gui import InputFormDescr 
 42   
 43  from MolKit.pdbWriter import PdbWriter 
 44  from MolKit.molecule import Atom, Bond, AtomSet, Molecule 
 45  from MolKit.protein import Protein 
 46  from MolKit.pdbParser import PQRParser 
 47   
 48  from PyBabel.babelElements import babel_elements 
 49   
 50  #pdb2pqr: 
 51  from pdb2pqr.pdb import readAtom 
 52  from pdb2pqr.protein import Protein as pdb2pqr_Protein 
 53  from pdb2pqr.definitions import Definition 
 54  from pdb2pqr.routines import Routines 
 55  from pdb2pqr.forcefield import Forcefield 
 56  from pdb2pqr.pdb2pqr import printHeader 
 57   
 58  from Queue import Queue 
 59  import thread  
 60   
 61  import weakref 
 62   
 63   
 64   
65 -class SetupPdb2Pqr(MVCommand):
66 """ 67 This command creates an instance of Pdb2Pqr protein class for a MolKit 68 molecule 69 """ 70
71 - def __init__(self):
72 MVCommand.__init__(self) 73 self.writer = PdbWriter() 74 self.processed_mols = {}
75 76
77 - def checkDependencies(self):
78 import pdb2pqr
79 80
81 - def onAddCmdToViewer(self):
82 #makesure fixHNames is loaded 83 if not hasattr(self.vf, 'fixHNames'): 84 self.vf.loadCommand('editCommands', 'fixHNames','Pmv', 85 topCommand=0)
86 87
88 - def __call__(self, mol, forcefield='amber', debump=1, hopt=1, 89 hdebump=1, watopt=1, hbond=1, updateMol=0, 90 newMol=0, filename=None, 91 useThread=1, **kw):
92 """None setup_Pdb2Pqr(mol, forcefield='amber', debump=1, 93 hopt=1, hdebump=1, watopt=1, hbond=1, 94 updateMol=0, newMol=0, filename=None) 95 mol: pmv molecule 96 forcefield: string specifying forcefield to use: 'amber', 'charm' or 'parse' 97 debump: whether to debump heavy atoms 98 hopt: whether to run hydrogen optimization 99 hdebump: whether to debump hydrogens [if not, they are randomized] 100 watopt: whether to optimize water hydrogens 101 hbond: whether to print hydrogen bonding summary 102 updateMol: whether to update the current pmv molecule 103 newMol: whether to build a new updated copy of the pmv molecule 104 filename: if provided, a pqr file is written 105 useThread: allows threads to be turned off for testing purposes 106 107 returns None 108 """ 109 nodes = self.vf.expandNodes(mol) 110 if not len(nodes): 111 return 'ERROR' 112 mol = nodes.findType(Molecule)[0] 113 kw['forcefield'] = forcefield 114 kw['debump'] = debump 115 kw['hopt'] = hopt 116 kw['hdebump'] = hdebump 117 kw['watopt'] = watopt 118 kw['hbond'] = hbond 119 kw['updateMol'] = updateMol 120 kw['newMol'] = newMol 121 kw['filename'] = filename 122 kw['useThread'] = useThread 123 return apply(self.doitWrapper, (mol,), kw)
124 125
126 - def checkForResults(self):
127 if not self.resultQueue.empty(): 128 result = self.resultQueue.get(False) 129 if result: #(pdb2pqrProtein, name of current MolKitMol, newMolFLAG) 130 pdb2pqr_mol = result[0] 131 mol = result[1] 132 print 'for ', mol.name, ' built pdb2pqr molecule:', pdb2pqr_mol 133 #should we keep this? 134 self.processed_mols[mol] = pdb2pqr_mol 135 #self.p2p_mol = result[0] 136 if result[2]: # whether to build a new molkit 137 new_name = mol.name + '_mod' 138 pqrParser = PQRParser(new_name) #??? 139 pqrParser.allLines = pdb2pqr_mol.printAtoms(pdb2pqr_mol.getAtoms()) 140 new_mol = pqrParser.parse()[0] 141 self.vf.addMolecule(new_mol) 142 return #in this case have the molecule so done [no more afters]! 143 self.vf.GUI.ROOT.after(10, self.checkForResults)
144 145
146 - def doit(self, mol, **kw):
147 forcefield = kw['forcefield'] 148 debump = kw['debump'] 149 hopt= kw['hopt'] 150 hdebump= kw['hdebump'] 151 watopt= kw['watopt'] 152 hbond= kw['hbond'] 153 updateMol= kw['updateMol'] 154 newMol= kw['newMol'] 155 filename = kw['filename'] 156 useThread = kw['useThread'] 157 print "mol=", mol 158 print "forcefield=", forcefield 159 print "debump=", debump 160 print "hopt=", hopt 161 print "hdebump=", hdebump 162 print "watopt=", watopt 163 print "hbond=", hbond 164 print "useThread=", useThread 165 166 #setup pdb2pqr objects: 167 #pdb2pqr_Protein created from list of pdb atom records 168 # created from current MolKit protein 169 pdblist = [] 170 for at in mol.allAtoms: 171 ostr = self.writer.defineATOM_HETATMRecord(at) 172 pdblist.append(readAtom(ostr)) 173 print "len(pdblist)=", len(pdblist) 174 175 self.resultQueue = Queue(-1) 176 print "about to start processing ", mol.name 177 #DO ALL THIS STUFF IN A THREAD: 178 if useThread: 179 thread.start_new(self.process, (mol, pdblist, forcefield, debump, hopt, hdebump,\ 180 watopt, hbond, filename, newMol, updateMol)) 181 self.vf.GUI.ROOT.after(10, self.checkForResults) 182 else: 183 self.process(mol, pdblist, forcefield, debump, hopt, hdebump,\ 184 watopt, hbond, filename, newMol, updateMol, \ 185 useThread=0) 186 self.checkForResults() 187 188 print "started process" 189 #self.vf.GUI.ROOT.after(10, self.checkForResults) 190 #does this wait for the queue to be empty??? 191 return
192 193
194 - def process(self, mol, pdblist, forcefield, debump, hopt, hdebump, watopt, \ 195 hbond, filename, newMol, updateMol, useThread=1):
196 print "in process with ", len(pdblist) 197 #pdb2pqr.Definition 198 definition = Definition() 199 p2pProtein = pdb2pqr_Protein(pdblist) 200 201 print "created Definition, p2pProtein" 202 #pdb2pqr.Routines object does The Work: 203 rout = Routines(p2pProtein, True, definition) 204 205 print "created Routines" 206 #initial pdb2pqr_Protein setup: 207 rout.updateResidueTypes() 208 rout.updateSSbridges() 209 rout.updateExtraBonds() 210 rout.correctNames() 211 #keep list of initial pdb2pqr atoms 212 original_atoms = p2pProtein.getAtoms() 213 #build any missing heavy atoms 214 rout.findMissingHeavy() 215 #keep list of original + rebuilt heavy atoms 216 updated_atoms = p2pProtein.getAtoms() 217 #get list of new heavy atoms 218 new_atoms = [] 219 weakrefDict = weakref.WeakValueDictionary() 220 221 if updateMol and len(updated_atoms)!=len(original_atoms): 222 for a in updated_atoms: 223 if a not in original_atoms: 224 new_atoms.append(a) 225 if len(new_atoms): #only do this if updateMol 226 #NOTE this is before the hydrogens are added 227 new_pmv_ats = self.build_missing_atoms(mol, original_atoms, new_atoms, rout, 228 weakrefDict) 229 print "built ", len(new_pmv_ats), " new heavy atoms" 230 231 #possibly try to resolve close contacts 232 if debump: 233 rout.calculateChiangles() 234 rout.debumpProtein() 235 #add pdb2pqr hydrogens 236 rout.addHydrogens() 237 #???? 238 rout.correctNames() 239 print "added hydrogens" 240 #possibly try to optimize them 241 if hopt: 242 rout.optimizeHydrogens() 243 print "optimized hydrogens" 244 #either try to optimize waters OR randomize them 245 print "watopt=", watopt 246 if watopt: 247 if not hopt: rout.optimizeHydrogens() 248 rout.optimizeWaters() 249 else: 250 rout.randomizeWaters() 251 #possibly try to debump the added hydrogens 252 print "hdebump=", hdebump 253 if hdebump: 254 rout.calculateChiangles() 255 rout.debumpProtein() 256 257 #update coords 258 print "forcefield=", forcefield 259 forcefield = Forcefield(forcefield) 260 #!!!non-std atoms/residues will be in misslist 261 #because forcefields do NOT have entries for them 262 #they must be skipped!!! 263 hitlist, misslist = rout.applyForcefield(forcefield) 264 reslist, charge = p2pProtein.getCharge() 265 print "len(misslist)=", len(misslist) 266 267 header = printHeader(misslist, reslist, charge, forcefield, rout.getWarnings()) 268 lines = p2pProtein.printAtoms(hitlist) 269 print "hbond=", hbond 270 if hbond: 271 rout.printHbond() 272 273 print "filename=", filename 274 if filename: 275 fptr = open(filename, 'w') 276 fptr.write(header) 277 for l in lines: 278 fptr.write(l) 279 fptr.close() 280 281 if updateMol: 282 print "updating MolKit molecule" 283 self.update_molecule(mol, weakrefDict, hitlist, misslist, new_pmv_ats) 284 print "putting ", p2pProtein, " onto the queue for ", mol.name, " with newMol=", newMol 285 self.resultQueue.put((p2pProtein, mol, newMol))
286 287
288 - def update_molecule(self, mol, weakrefDict, hitlist, misslist, new_pmv_ats):
289 #in order to update the PMV molecule: 290 #build hydrogens + missing heavy atoms 291 #add ffcharges: 292 #->add _charges['ff'] 293 #->set chargeSet to 'ff' 294 #change coordinates: 295 # due to debumping + optimizing hydrogen bonding networks 296 #->add new coords 297 #->set Conformation to new slot 298 #add/set radius 299 hlist = [] 300 #can only update the atoms which are recognized 301 for a in hitlist: 302 #@@@FIX THIS@@@: why are there some with no intrabonds? 303 #are these always from the termini? 304 if a.isHydrogen(): 305 hlist.append(a) 306 if len(hlist): 307 len_ats = len(mol.allAtoms) 308 new_pmv_hs = self.build_all_hydrogens(mol, hlist, 1, weakrefDict) 309 #len_new_hs = len(mol.allAtoms) - len_ats 310 #@@@FIX THIS@@@ should this be done??? 311 #fix the names of the new hydrogens 312 self.vf.fixHNames(mol) 313 print "built ", len(new_pmv_hs), " hydrogens" 314 else: 315 print "no hydrogens to build" 316 #update charges and coords 317 nterm_h_ctr = 1 318 #find the pmv_at to update 319 for atom in hitlist: 320 res = mol.chains.residues.get(lambda x: strip(x.parent.id)==strip(atom.chainID) and int(x.number)==atom.resSeq)[0] 321 #if hasattr(atom, 'pmv_atom'): #hydrogens + missing heavyAts 322 if weakrefDict.has_key(atom): ##hydrogens + missing heavyAts 323 pmv_at = weakrefDict[atom] 324 #pmv_at = atom.pmv_atom 325 else: 326 pmv_at = mol.allAtoms.get(lambda x: x.parent==res and \ 327 strip(x.parent.parent.id)==strip(atom.chainID) \ 328 and x.name==atom.name)[0] 329 weakrefDict[atom] = pmv_at 330 weakrefDict[pmv_at] = atom 331 #pmv_at.pqr_atom = atom 332 #atom.pmv_atom = pmv_at 333 pmv_at._charges['ff'] = atom.get('ffcharge') 334 pmv_at.chargeSet = 'ff' 335 pmv_at._coords.append([atom.x, atom.y, atom.z]) 336 pmv_at.radius = atom.get('radius') 337 newConfNum = len(mol.allAtoms[0]._coords)-1 338 #need to update the misslist atoms, also, but HOW??? 339 for atom in misslist: 340 res = mol.chains.residues.get(lambda x: strip(x.parent.id)==strip(atom.chainID) and int(x.number)==atom.resSeq)[0] 341 pmv_at = mol.allAtoms.get(lambda x: x.parent==res and \ 342 strip(x.parent.parent.id)==strip(atom.chainID) \ 343 and x.name==atom.name)[0] 344 weakrefDict[atom] = pmv_at 345 weakrefDict[pmv_at] = atom 346 #pmv_at.pqr_atom = atom 347 #atom.pmv_atom = weakref.ref(pmv_at) 348 pmv_at._charges['ff'] = 0.0 349 pmv_at.chargeSet = 'ff' 350 pmv_at._coords.append([atom.x, atom.y, atom.z]) 351 data = babel_elements[pmv_at.chemElem] 352 ###HOW TO FIX THIS??? 353 pmv_at.radius = data['vdw_rad'] 354 ##FIX THIS@@@@@@@ 355 mol.allAtoms.setConformation(newConfNum) 356 #mol.geomContainer.geoms['lines'].RedoDisplayList() 357 #for geom in mol.geomContainer.geoms.values(): 358 #geom.RedoDisplayList() 359 #self.vf.displayLines(mol,negate=True) 360 #self.vf.displayLines(mol,negate=False) 361 modAts = AtomSet(new_pmv_ats + new_pmv_hs) 362 event = AddAtomsEvent(objects=modAts) 363 self.vf.dispatchEvent(event)
364 365
366 - def build_all_hydrogens(self, mol, hlist, renumber, weakrefDict):
367 new_pmv_hs = [] 368 for h in hlist: 369 new_h = self.build_hydrogen(mol, h) 370 new_pmv_hs.append(new_h) 371 weakrefDict[new_h] = h 372 weakrefDict[h] = new_h 373 mol.allAtoms = mol.chains.residues.atoms 374 if renumber: 375 mol.allAtoms.number = range(1, len(mol.allAtoms)+1) 376 return new_pmv_hs
377 378
379 - def build_hydrogen(self, mol, h):
380 res = mol.chains.residues.get(lambda x: x.number==str(h.residue.resSeq) and strip(x.parent.id)==strip(h.chainID))[0] 381 #if len(h.intrabonds)==0 or (res==mol.chains.residues[0] and h.intrabonds[0]=='N'): 382 if res==res.parent.residues[0]: 383 if len(h.intrabonds)==0: 384 #or (res==mol.chains.residues[0] and h.intrabonds[0]=='N'): 385 #bond this hydrogen to the N terminus 386 heavyAtom = res.atoms.get(lambda x: x.name=='N')[0] 387 num = len(heavyAtom.findHydrogens())+1 388 name = 'HN'+ str(num) 389 childIndex = num 390 elif h.intrabonds[0]=='N': 391 heavyAtom = res.atoms.get(lambda x: x.name=='N')[0] 392 childIndex = 1 393 name = 'HN1' 394 else: 395 heavyAtom = res.atoms.get(lambda x: x.name==h.intrabonds[0])[0] 396 childIndex = res.children.index(heavyAtom) + 1 397 num = len(heavyAtom.findHydrogens())+1 398 if heavyAtom.name==1: 399 name = 'H'+ heavyAtom.name 400 else: 401 name = 'H'+ heavyAtom.name[1:] 402 else: 403 heavyAtom = res.atoms.get(lambda x: x.name==h.intrabonds[0])[0] 404 childIndex = res.children.index(heavyAtom) + 1 405 if len(heavyAtom.name)==1: 406 name = 'H' + heavyAtom.name 407 else: 408 name = 'H' + heavyAtom.name[1:] 409 atom = Atom(name, res, top=heavyAtom.top, 410 chemicalElement='H', 411 childIndex=childIndex, assignUniqIndex=0) 412 atom._coords = [h.getCoords()] 413 atom.hetatm = 0 414 atom.alternate = [] 415 #atom.element = 'H' 416 atom.occupancy = 1.0 417 atom.conformation = 0 418 atom.temperatureFactor = 0.0 419 #atom.babel_atomic_number = a[2] 420 #atom.babel_type = a[3] 421 #atom.babel_organic = 1 422 atom.radius = 1.2 423 # create the Bond object bonding Hatom to heavyAtom 424 bond = Bond( heavyAtom, atom, bondOrder=1) 425 # in case this new hydrogen atom ever ends up in pmv 426 # HAVE TO CREATE THESE ENTRIES 427 # create the color entries for all geoemtries 428 # available for the heavyAtom 429 for key, value in heavyAtom.colors.items(): 430 atom.colors[key]=(0.0, 1.0, 1.0) 431 atom.opacities[key]=1.0 432 atom._charges = {'ff':h.ffcharge} 433 atom.chargeSet = 'ff' 434 #h.pmv_atom = weakref.ref(atom) 435 #atom.pqr_atom = h 436 return atom
437 438
439 - def build_missing_atoms(self, mol, original_atoms, updated_atoms,\ 440 rout, weakrefDict):
441 dict = {} 442 for a in original_atoms: 443 dict[a] = 1 444 445 updict = {} 446 for a in updated_atoms: 447 updict[a] = 1 448 449 orig_keys = dict.keys() 450 updated_keys = updict.keys() 451 orig_keys.sort() 452 updated_keys.sort() 453 new_ats = [] 454 for k in updated_keys: 455 if k not in orig_keys: 456 atom = k 457 new_atom = self.build_atom(mol, atom, rout) 458 new_ats.append(new_atom) 459 weakrefDict[new_atom] = atom 460 weakrefDict[atom] = new_atom 461 mol.allAtoms = mol.chains.residues.atoms 462 mol.buildBondsByDistanceOnAtoms(mol.allAtoms) 463 return new_ats
464 465
466 - def build_atom(self, mol, atom, rout):
467 #atom: 468 #atom.name 'CA' 469 #atom.resName 'THR' 470 #atom.resSeq 1 471 #atom.serial 1 this is wrong should be 2 472 #atom.x : 16.9757101481 473 #atom.y : 12.8371271623 474 #atom.z : 4.36351540833 475 #could there be >1??? 476 #atom.chainID : 'A' 477 #molkit residue 478 defRes = rout.aadef.getResidue(atom.resName) 479 #breaks on OXT 480 if atom.name!='OXT': 481 defAtom = defRes.map[atom.name] 482 child_index = defRes.atoms.index(defAtom) 483 occupancy = defAtom.occupancy 484 else: 485 #should it be at the end or after O [N,CA,C,O,CB....] 486 child_index = len(defRes.atoms)-1 487 occupancy = 1.0 #@@@@FIX THIS@@@@ 488 #have to assume the numbers are unique, at least for the moment 489 res = mol.chains.residues.get(lambda x: int(x.number)==atom.resSeq and \ 490 strip(x.parent.id)==strip(atom.chainID))[0] 491 #atom.residue.chainID is '' whereas x.parent.id==' ' (YUK) 492 #res = mol.chains.residues.get(lambda x: int(x.number)==atom.resSeq and \ 493 # x.parent.id==atom.residue.chainID)[0] 494 new_atom = Atom(atom.name, res, top=mol, chemicalElement=atom.name[0], 495 childIndex=child_index) 496 new_atom._coords = [[atom.x, atom.y, atom.z]] 497 new_atom.hetatm = 0 498 new_atom.alternate = [] 499 new_atom.occupancy = occupancy 500 new_atom.conformation = 0 501 new_atom.temperatureFactor = atom.tempFactor 502 #what about bonds?? 503 refatom = mol.allAtoms[0] 504 for key, value in refatom.colors.items(): 505 new_atom.colors[key] = (1.0, 1.0,1.0) 506 new_atom.opacities[key] = 1.0 507 #??? 508 new_atom._charges = {} 509 new_atom.chargeSet = '' 510 #link pmv object to pdb2pqr object + vice versa 511 #atom.pmv_at = new_atom 512 #new_atom.pqr_atom = atom 513 return new_atom
514 515
516 - def buildFormDescr(self, formName):
517 if formName=="pdb2pqrGUI": 518 self.debump = Tkinter.IntVar() 519 self.debump.set(1) 520 self.hopt = Tkinter.IntVar() 521 self.hopt.set(1) 522 self.hdebump = Tkinter.IntVar() 523 self.hdebump.set(1) 524 self.watopt = Tkinter.IntVar() 525 self.watopt.set(1) 526 self.hbond = Tkinter.IntVar() 527 self.hbond.set(1) 528 self.forcefield = Tkinter.StringVar() 529 self.forcefield.set('amber') 530 self.updateMol = Tkinter.IntVar() 531 self.newMol = Tkinter.IntVar() 532 self.newMol.set(1) 533 #options: debump, hopt, hdebump, watopt, hbond, ff 534 ifd = self.ifd = InputFormDescr(title = " Set Up Pdb2Pqr instance:") 535 ifd.append({'name':'debump', 536 'widgetType':Tkinter.Checkbutton, 537 'wcfg':{'text':'Debump protein ', 538 'variable': self.debump, 539 }, 540 'gridcfg':{'sticky':'w'}}) 541 ifd.append({'name':'hopt', 542 'widgetType':Tkinter.Checkbutton, 543 'wcfg':{'text':'Optimize hydrogens ', 544 'variable': self.hopt, 545 }, 546 'gridcfg':{'sticky':'w'}}) 547 ifd.append({'name':'watopt', 548 'widgetType':Tkinter.Checkbutton, 549 'wcfg':{'text':'Optimize waters ', 550 'variable': self.watopt, 551 }, 552 'gridcfg':{'sticky':'w','row':-1, 'column':1}}) 553 #'gridcfg':{'sticky':'w', 'row':-1, 'column':2}}) 554 ifd.append({'name':'hdebump', 555 'widgetType':Tkinter.Checkbutton, 556 'wcfg':{'text':'Debump hydrogens ', 557 'variable': self.hdebump, 558 }, 559 'gridcfg':{'sticky':'w'}}) 560 ifd.append({'name':'hbond', 561 'widgetType':Tkinter.Checkbutton, 562 'wcfg':{'text':'Printout hydrogen bonds ', 563 'variable': self.hbond, 564 }, 565 'gridcfg':{'sticky':'w','row':-1, 'column':1}}) 566 ifd.append({'name':'ffRB0', 567 'widgetType':Tkinter.Radiobutton, 568 'wcfg':{'text':'use amber forcefield', 569 'variable': self.forcefield, 570 'value':"amber", 571 }, 572 'gridcfg':{'sticky':'w'}}) 573 ifd.append({'name':'ffRB1', 574 'widgetType':Tkinter.Radiobutton, 575 'wcfg':{'text':'use charmm forcefield', 576 'variable': self.forcefield, 577 'value':"charmm", 578 }, 579 'gridcfg':{'sticky':'w', 'row':-1, 'column':1}}) 580 ifd.append({'name':'ffRB2', 581 'widgetType':Tkinter.Radiobutton, 582 'wcfg':{'text':'use parse forcefield', 583 'variable': self.forcefield, 584 'value':"parse", 585 }, 586 'gridcfg':{'sticky':'w'}}) 587 ifd.append({'name':'filename', 588 'widgetType':Tkinter.Entry, 589 'wcfg':{'label':'Pqr filename to write:', 590 }, 591 'gridcfg':{'sticky':'we', 'columnspan':2}}) 592 ifd.append({'name':'updateMol', 593 'widgetType':Tkinter.Checkbutton, 594 'wcfg':{'text':'Update Current Pmv Molecule ', 595 'variable': self.updateMol, 596 }, 597 'gridcfg':{'sticky':'w'}}) 598 ifd.append({'name':'newMol', 599 'widgetType':Tkinter.Checkbutton, 600 'wcfg':{'text':'Create New Pmv Molecule ', 601 'variable': self.newMol, 602 }, 603 'gridcfg':{'sticky':'w', 'row':-1, 'column':1}}) 604 return ifd
605 606
607 - def guiCallback(self):
608 # a molecule must present first 609 if not len(self.vf.Mols): 610 self.warningMsg('must load molecule first') 611 return "ERROR" 612 nodes = self.vf.getSelection() 613 if not len(nodes): 614 self.warningMsg('nothing in the selection') 615 return "ERROR" 616 mols = nodes.top.uniq() 617 if len(mols)>1: 618 self.vf.warningMsg("more than one molecule in selection!") 619 return 'ERROR' 620 mol = mols[0] 621 #FIX THIS: need to process atoms in units of whole chains 622 vals = self.showForm("pdb2pqrGUI", scrolledFrame=1, width=500, 623 height=200, force=1) 624 if len(vals)>0: 625 # mol, forcefield, debump, hopt, hdebump, watopt, hbond) 626 #forcefield = self.forcefield.get() 627 #debump = vals['debump'] 628 #hopt = vals['hopt'] 629 #hdebump = vals['hdebump'] 630 #watopt = vals['watopt'] 631 #hbond = vals['hbond'] 632 #updateMol = vals['updateMol'] 633 vals['forcefield'] = self.forcefield.get() 634 for k in ['ffRB0','ffRB1','ffRB2']: 635 del vals[k] 636 return apply(self.doitWrapper, (mol,), vals) 637 else: 638 return 'ERROR'
639 640 641 SetupPdb2PqrCommandGUI = CommandGUI() 642 SetupPdb2PqrCommandGUI.addMenuCommand('menuRoot', 'Pdb2Pqr', 'Setup Pdb2Pqr') 643 644 645 646 647 commandList=[ 648 {'name':'setup_Pdb2Pqr','cmd':SetupPdb2Pqr(),\ 649 'gui': SetupPdb2PqrCommandGUI}, 650 ] 651 652 653
654 -def initModule(viewer):
655 for dict in commandList: 656 viewer.addCommand(dict['cmd'], dict['name'], dict['gui'])
657