1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 """
22 This Module facilitates producing a files for AutoDock. The steps in this process are:
23
24 * Set the macromolecule:
25
26 o Read a PDBQT Macromolecule
27
28 o Choose Macromol...
29
30 * Select which residues are to be flexible in macromolecule using Pmv selection tools:
31
32 o ICOM Select
33
34 o SelectFromString
35
36 o Select Spherical Region
37
38 * The results of the previous steps are written to a file. The user selects a filename via a filebrowser.
39
40 """
41 import Numeric
42
43 from DejaVu import viewerConst
44 from ViewerFramework.VFCommand import CommandGUI
45
46 from mglutil.gui.InputForm.Tk.gui import InputFormDescr
47 from mglutil.gui.InputForm.Tk.gui import InputFormDescr
48 from mglutil.gui.BasicWidgets.Tk.thumbwheel import ThumbWheel
49 from mglutil.gui.BasicWidgets.Tk.customizedWidgets import ListChooser,\
50 ExtendedSliderWidget
51
52 from Pmv.mvCommand import MVCommand, MVBondICOM, MVAtomICOM
53 from MolKit.tree import TreeNode, TreeNodeSet
54 from MolKit.molecule import Atom, AtomSet, BondSet
55 from MolKit.protein import Residue, ResidueSet, Chain
56 from MolKit.pdbWriter import PdbqtWriter
57 from MolKit.bondSelector import RotatableBondSelector, AmideBondSelector
58 from MolKit.bondSelector import GuanidiniumBondSelector, LeafBondSelector
59
60 from Pmv.guiTools import MoleculeChooser
61 import types, string, Tkinter, os, Pmw
62 from AutoDockTools.autotorsCommands import MAXTORS, SetRotatableBonds
63 from AutoDockTools.atomTypeTools import AutoDock4_AtomTyper
64
65 from SimpleDialog import SimpleDialog
66
67 menuText = {}
68 menuText['AutoFlexMB'] = 'Flexible Residues'
69 menuText['InputMB'] = 'Input'
70 menuText['Read Macro'] = 'Open Macromolecule...'
71 menuText['Choose Macro'] = 'Choose Macromolecule...'
72 menuText['Set Residues'] = 'Choose Torsions in Currently Selected Residues...'
73 menuText['Set Hinge'] = 'Set up Hinge...'
74 menuText['Edit Hinge'] = 'Edit Hinge...'
75 menuText['Step Back'] = 'Redisplay Macromolecule'
76 menuText['WriteMB'] = 'Output'
77 menuText['writeFlexible'] = 'Save Flexible PDBQT...'
78 menuText['writeRigid'] = 'Save Rigid PDBQT...'
79 menuText['writeDir'] = 'Save Multiple Flexible PDBQTS...'
80
81
82
84 """ allows user to select a filename for the macromolecule"""
85
86
88 if hasattr(self.vf, 'flexDict'):
89 dict = self.vf.flexDict
90 if dict.has_key('macrofilename'):
91 ok = False
92 macrofilename = dict['macrofilename']
93 for m in self.vf.Mols:
94 if m.parser.filename==macrofilename:
95 ok = True
96 break
97 if not ok:
98 del dict['macrofilename']
99 if dict.has_key('macroname') and dict['macroname'] not in self.vf.Mols.name:
100 del dict['macroname']
101 if dict.has_key('macromol') and dict['macromol']:
102 del dict['macromol']
103
104
106 if not hasattr(self.vf, 'flexDict'):
107 self.vf.flexDict={}
108 if not self.vf.commands.has_key('readPDBQT'):
109 self.vf.loadCommand('fileCommands', 'readPDBQT', 'Pmv')
110
111
113 """called each time the 'select pdbqt macromolecule' button is pressed"""
114 macroFile = self.vf.askFileOpen(types=[('PDBQT files', '*.pdbqt')],
115 title = 'PDBQT Macromolecule File:')
116 if macroFile:
117 filename=os.path.split(macroFile)[-1]
118 ext = os.path.splitext(filename)[1]
119 if ext!='.pdbqt':
120 msg = 'File can only be PDBQT format'
121 self.warningMsg(msg)
122 return 'ERROR'
123 self.doitWrapper(macroFile)
124
125
127 """None<-ADflex_readMacro(macroFile)"""
128 if not macroFile: return 'ERROR'
129 ext = os.path.splitext(macroFile)[1]
130 if ext!='.pdbqt':
131 msg = 'File must be PDBQT format'
132 self.warningMsg(msg)
133 return 'ERROR'
134 apply(self.doitWrapper, (macroFile,), kw)
135
136
137 - def doit(self, macroFile):
138 mollist = self.vf.readPDBQT(macroFile)
139 if not len(mollist): return 'ERROR'
140 mol = mollist[0]
141 mol.allAtoms.used = 0
142 dict = self.vf.flexDict
143 dict['macrofilename'] = macroFile
144 dict['macroname'] = mol.name
145 dict['macromol'] = mol
146
147
148 AF_MacroReaderGUI=CommandGUI()
149 AF_MacroReaderGUI.addMenuCommand('AutoToolsBar', menuText['AutoFlexMB'], \
150 menuText['Read Macro'], cascadeName = menuText['InputMB'])
151
152
153
155 """ allows user to choose a molecule already present for the macromolecule"""
156
157
158 - def __init__(self, mode='single', title = 'Choose Macromolecule'):
162
163
165 if hasattr(self.vf, 'flexDict'):
166 dict = self.vf.flexDict
167 if dict.has_key('macrofilename'):
168 ok = False
169 macrofilename = dict['macrofilename']
170 for m in self.vf.Mols:
171 if m.parser.filename==macrofilename:
172 ok = True
173 break
174 if not ok:
175 del dict['macrofilename']
176 if dict.has_key('macroname') and dict['macroname'] not in self.vf.Mols.name:
177 del dict['macroname']
178 if dict.has_key('macromol') and dict['macromol']:
179 del dict['macromol']
180
181
182
184 """called each time the 'choose Molecule' button is pressed"""
185 mols = self.chooser.getMolSet()
186 kw = {'redraw':0}
187 if mols: apply(self.doitWrapper, (mols,), kw)
188 self.chooser.form.withdraw()
189
190
192 self.chooser = MoleculeChooser(self.vf, self.mode, self.title)
193 self.chooser.ipf.append({'name':'Select Button',
194 'widgetType':Tkinter.Button,
195 'text':'Select Molecule',
196 'wcfg':{'bd':6},
197 'gridcfg':{'sticky':Tkinter.E+Tkinter.W},
198 'command': self.chooseMolecule_cb})
199 self.form = self.chooser.go(modal=0, blocking=0)
200 lb = self.chooser.ipf.entryByName['Molecule']['widget'].lb
201 lb.bind("<Double-Button-1>",self.chooseMolecule_cb)
202
203
205 """None<-ADflex_chooseMacro(nodes)"""
206 nodes = self.vf.expandNodes(nodes)
207 if not len(nodes): return 'ERROR'
208 apply(self.doitWrapper, (nodes,), kw)
209
210
211 - def doit(self, nodes, **kw):
212 nodes = self.vf.expandNodes(nodes)
213 if not len(nodes): return 'ERROR'
214 mol = nodes[0]
215 mol.allAtoms.used=0
216
217 filetype = os.path.splitext(os.path.basename(mol.parser.filename))[1]
218 msg = ""
219 chargeMsg = ""
220 typeMsg = ""
221 if filetype!='.pdbqt':
222
223 ats = mol.allAtoms.get(lambda x: x.chargeSet==None)
224 if len(ats):
225 mol.buildBondsByDistance()
226 self.vf.computeGasteiger(mol, topCommand=0)
227 chargeMsg = "added gasteiger charges "
228
229 ats = mol.allAtoms.get(lambda x: hasattr(x, 'autodock_element'))
230 if len(ats)!= len(mol.allAtoms):
231 ad4_typer = AutoDock4_AtomTyper()
232 mol.buildBondsByDistance()
233 ad4_typer.setAutoDockElements(mol)
234 typeMsg = " added autodock4 atom types "
235 if len(chargeMsg):
236 msg += chargeMsg
237 if len(typeMsg):
238 msg = msg + ' and ' + typeMsg + ' to ' + mol.name
239 elif len(typeMsg):
240 msg = typeMsg + ' to ' + mol.name
241 hs = mol.allAtoms.get(lambda x: x.element=='H' and len(x.bonds))
242 nphs = hs.get(lambda x: x.bonds[0].atom1.element=='C' or x.bonds[0].atom2.element=='C')
243 if len(nphs):
244 lenNPHS = 0
245 beforeLen = len(mol.allAtoms)
246 if 'automerge_nphs' in kw.keys():
247 self.vf.mergeNPHSGC(mol.allAtoms)
248 else:
249 nphs_msg="There appear to be some nonpolar hydrogen in "+ mol.name+ " Do you wish to merge them to conform to AutoDock4 atom types? "
250 d = SimpleDialog(self.vf.GUI.ROOT, text=nphs_msg,
251 buttons=['No', 'Yes'], default=1,
252 title="Merge Non-polar Hydrogens?")
253 mergeNPHS = d.go()
254 if mergeNPHS:
255 self.vf.mergeNPHSGC(mol.allAtoms)
256 lenNPHS = beforeLen - len(mol.allAtoms)
257 if lenNPHS:
258 msg = msg + " and merged " + str(lenNPHS) + " non-polar hydrogens"
259 if len(msg):
260 self.warningMsg(msg)
261 dict = self.vf.flexDict
262 dict['macroname'] = mol.name
263 dict['macrofilename'] = mol.parser.filename
264 dict['macromol'] = mol
265 if hasattr(self.vf, 'gpo') and hasattr(self.vf.gpo, 'receptor') and self.vf.gpo.receptor==mol:
266 msg = mol.name + " is currently the 'macromolecule'\nin the Grid menu. Make sure the macromolecule specified in the gpf does not include the flexible residues!!"
267 self.warningMsg(msg)
268
269
271 listChooser = self.ipf.entryByName['Molecule']['widget']
272 tkListBox = listChooser.lb
273 atom,geom = self.vf.findPickedAtom(event)
274 if atom:
275 pickedMol = atom.top
276
277 for i in range(len(listChooser.entries)):
278 listChooserlist=string.split(listChooser.entries[i][0])
279 if pickedMol.name == listChooserlist[0]:
280 self.pickedMolIndex= i
281 tkListBox.select_clear(0,'end')
282 listChooser.select(i)
283 return
284 t= "error: %s not in mv.Mols" %pickedMol.name
285 self.vf.warningMsg(t)
286
287
288 AF_MacroChooserGUI=CommandGUI()
289 AF_MacroChooserGUI.addMenuCommand('AutoToolsBar', menuText['AutoFlexMB'],
290 menuText['Choose Macro'], cascadeName = menuText['InputMB'])
291
292
293
295 """ allows user to set up a set of residues in macromolecule whose sidechains are to be flexed in an autodock run"""
296
297
299 if not hasattr(self.vf, 'flexDict'):
300 self.vf.flexDict={}
301 if not hasattr(self.vf, 'colorByAtomType'):
302 self.vf.loadCommand('colorCommands', 'colorByAtomType', 'Pmv')
303 self.torscount = 0
304
305
307 """called each time the 'Set Selected Residues' button is pressed"""
308 if not self.vf.flexDict.has_key('macroname'):
309 t='select protein first'
310 self.vf.warningMsg(t)
311 return 'ERROR'
312 else: macroname=self.vf.flexDict['macroname']
313 if len(self.vf.selection)==0:
314 msg = "Please select residues to be modelled as flexible first!"
315 self.warningMsg(msg)
316 return 'ERROR'
317 nodes = self.vf.getSelection()
318 nodes = nodes.findType(Residue).uniq()
319 if not len(nodes):
320 t='no current residues selected'
321 self.vf.warningMsg(t)
322 return 'ERROR'
323
324 mol = nodes[0].top
325 title = "Process ALL residues in %s?" %mol.name
326 if len(nodes)==len(mol.chains.residues):
327 msg="CAUTION: currently processing all the residues in "+mol.name+ " will be very time consuming. Do you wish to continue? "
328 d = SimpleDialog(self.vf.GUI.ROOT, text=msg,
329 buttons=['No', 'Yes'], default=1,
330 title=title)
331 useAll = d.go()
332 if not useAll:
333 return "ERROR"
334 if not nodes.__class__==ResidueSet:
335 self.vf.setIcomLevel(Residue, topCommand=0)
336 nodes = nodes.findType(Residue).uniq()
337 mol = nodes[0].top
338 mol.allAtoms.used=0
339 kw = {'redraw':0}
340 self.torscount = 0
341 apply(self.doitWrapper, (nodes,), kw)
342
343
345 nodes = self.vf.expandNodes(nodes)
346 if not len(nodes): return "ERROR"
347 if nodes.__class__ != ResidueSet:
348 nodes = nodes.findType(Residue).uniq()
349 apply(self.doitWrapper, (nodes,), kw)
350
351
352 - def doit(self, nodes):
353 flex_residues = self.vf.expandNodes(nodes)
354 if not len(flex_residues): return 'ERROR'
355
356
357 proList = ResidueSet(filter(lambda x: x.type=='PRO', flex_residues))
358 if proList:
359 flex_residues = flex_residues - proList
360
361
362 h20List = ResidueSet(filter(lambda x: x.type=='HOH', flex_residues))
363 if h20List:
364 flex_residues = flex_residues - h20List
365
366 if not len(flex_residues):
367 t='No non-water and non-proline Residues selected!'
368 self.vf.warningMsg(t)
369 return 'ERROR'
370
371 map(self.setAutoFlexFields, flex_residues)
372
373
374
375
376
377
378 flexList = filter(lambda x: x.torscount!=0, flex_residues)
379 flexList = ResidueSet(flexList)
380 if not len(flexList):
381 t='Current Selected Residues have no active torsions!'
382 self.vf.warningMsg(t)
383 return 'ERROR'
384 self.torscount = Numeric.add.reduce(flexList.torscount)
385 mol = flex_residues[0].top
386 allResidues = mol.findType(Residue)
387 rigidResidues = allResidues-flex_residues
388 dict = self.vf.flexDict
389 dict['flex_residues'] = flex_residues
390 dict['flex_residues_number'] = len(flex_residues)
391 dict['rigidResidues'] = rigidResidues
392 self.vf.ADflex_processResidues.guiCallback()
393
394
396
397 if hasattr(res, 'setup'):
398 return
399 res.setup = 1
400 res.atoms.used = 0
401 res.atoms.bonds[0].possibleTors = 0
402 res.atoms.bonds[0].activeTors = 0
403 backbone_names = ['C','N','O','HN','HN1','HN2', 'HA',
404 'H1','H2','H3','HO', 'H']
405
406 sidechain = res.atoms.get(lambda x: x.name not in backbone_names)
407 res.sideChain = sidechain
408 bondlist = res.bondlist = sidechain.bonds[0]
409 bondlist.leaf = 0
410 bondlist.possibleTors = 0
411 bondlist.activeTors = 0
412 rbs = RotatableBondSelector()
413 rotatables = rbs.select(bondlist)
414 for b in rotatables:
415 b.possibleTors = 1
416 b.activeTors = 1
417 amides = AmideBondSelector().select(bondlist)
418 for b in amides:
419 b.activeTors = 0
420 b.possibleTors = 1
421 guanidiniums = GuanidiniumBondSelector().select(bondlist)
422 for b in guanidiniums:
423 b.activeTors = 0
424 b.possibleTors = 1
425 leaves = LeafBondSelector().select(bondlist)
426 for b in leaves:
427 b.activeTors = 0
428 b.possibleTors = 0
429 res.torscount = len(bondlist.get(lambda x: x.activeTors==1))
430
431 res.torsdof = res.torscount
432 res.torscount = len(bondlist.get(lambda x: x.activeTors==1))
433 res.torsdof = res.torscount
434
435 caAtoms = res.atoms.get(lambda x: x.name=='CA')
436
437 if caAtoms:
438 res.rootlist = caAtoms
439 elif self.vf.hasGui:
440
441 rootname = Tkinter.StringVar()
442 if hasattr(res, 'rootlist'):
443 rootname.set(res.rootlist[0].name)
444 else:
445 at0 = res.atoms.get(lambda x: x._uniqIndex==0)[0]
446 rootname.set(at0.name)
447 s = 'Set Root Atom for ' + res.name
448 ifd = InputFormDescr(title=s)
449 ifd.append({'name':'sideChainLC',
450 'widgetType': 'ListChooser',
451 'mode': 'single',
452 'entries':res.atoms.name,
453 'title': 'Select Root Atom',
454 'lbwcfg':{'height':20,'selectforeground':'red','exportselection':0},
455 'gridcfg':{'sticky':Tkinter.W +Tkinter.E}}),
456 vals= self.vf.getUserInput(ifd, modal=1, blocking=1)
457 if vals:
458 try:
459 atList = vals['sideChainLC']
460 res.rootlist = res.atoms.get(lambda x, atList=atList: x.name==atList[0])
461 res.sideChain = res.atoms
462 except:
463 msg = 'rootatom not in res, using defaults'
464 self.vf.warningMsg(msg)
465 res.rootlist = AtomSet([res.atoms.get(lambda x: x._uniqIndex == 0)[0]])
466 res.sideChain = res.atoms
467 else:
468 msg = 'rootatom not in res, using defaults'
469 self.vf.warningMsg(msg)
470 res.rootlist = AtomSet([res.atoms.get(lambda x: x._uniqIndex == 0)[0]])
471 res.sideChain = res.atoms
472
473 else:
474 res.rootlist = AtomSet([res.atoms.get(lambda x: x._uniqIndex == 0)[0]])
475 res.sideChain = res.atoms
476
477
478 AF_SelectResiduesGUI = CommandGUI()
479 AF_SelectResiduesGUI.addMenuCommand('AutoToolsBar', menuText['AutoFlexMB'],menuText['Set Residues'])
480
481
482
484 """ allows user to process interactively a set of residues in macromolecule whose sidechains are to be flexed in an autodock run"""
485
486
493
494
496 if not hasattr(self.vf, 'flexDict'):
497 self.vf.flexDict = {}
498 if not hasattr(self.vf, 'colorByAtomType'):
499 self.vf.loadCommand('colorCommands', 'colorByAtomType', 'Pmv')
500 if not hasattr(self.vf, 'setICOM'):
501 self.vf.loadCommand('interactiveCommands', 'setICOM', 'Pmv')
502 if self.vf.hasGui and not self.torsStr:
503 self.torsStr = Tkinter.StringVar()
504
505
507 """called INDIRECTLY each time the 'Choose Torsions in Currently Selected Residues...' button is pressed"""
508 if not self.vf.flexDict.has_key('flex_residues'):
509 t='select residues first'
510 self.vf.warningMsg(t)
511 return 'ERROR'
512 nodes = self.vf.flexDict['flex_residues']
513 self.mol = nodes[0].top
514 if not len(nodes):
515 t='no residues selected'
516 self.vf.warningMsg(t)
517 return 'ERROR'
518 if not nodes.__class__==ResidueSet:
519 t='selection must be of type ResidueSet'
520 self.vf.warningMsg(t)
521 return 'ERROR'
522 self.changeFlexResCt(0)
523 if not hasattr(self, 'ifd'):
524 self.torsStr= Tkinter.StringVar()
525 s = 'Number of rotatable bonds ='+str(0)+ ' / '+str(MAXTORS)+'\n'
526 self.torsStr.set(s)
527 self.renameAromatic= Tkinter.IntVar()
528 infoStr = 'Pick or drag-&-pick bonds. \nGreen = rotatable, \nMagenta = non-rotatable, \nRed = unrotatable.\n\n'
529 ifd = self.ifd=InputFormDescr(title='Torsion Count')
530 ifd.append({'name': 'maxTorsLab',
531 'widgetType':Tkinter.Label,
532 'wcfg':{'text':infoStr},
533 'gridcfg':{'sticky':Tkinter.W + Tkinter.E}}),
534 ifd.append({'name':'torsEntryLab',
535 'widgetType':Tkinter.Label,
536 'wcfg':{'textvariable':self.torsStr},
537 'gridcfg':{'sticky':Tkinter.W +Tkinter.E}}),
538 ifd.append({'name': 'noAmideBut',
539 'widgetType':Tkinter.Checkbutton,
540 'wcfg':{'text':'amide torsions are allowed',
541
542 'selectcolor':'white',
543 'indicatoron':0,
544 'command':self.setNoAmideTors_cb},
545 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 'columnspan':2}}),
546 ifd.append({'name': 'closeBut',
547 'widgetType':Tkinter.Button,
548 'wcfg':{'text':'Close','command':self.close_cb},
549 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 'columnspan':2}})
550 self.form= self.vf.getUserInput(self.ifd, modal=0, blocking=0)
551 else:
552 if hasattr(self,'form'):
553 self.form.root.deiconify()
554
555 if hasattr(self.vf.ADflex_setResidues,'torscount'):
556 self.torscount = self.vf.ADflex_setResidues.torscount
557 else:
558 self.torscount = 0
559 self.currentNodes=nodes.sideChain
560 self.vf.displayLines(self.currentNodes, topCommand=0)
561 self.vf.displayLines(self.currentNodes, only=1, topCommand=0, redraw=1)
562 pTbndset = self.currentNodes.bonds[0].get(lambda x:x.activeTors==1)
563 pTatomset = (pTbndset.atom1 + pTbndset.atom2).uniq()
564 if len(pTatomset):
565 geom = self.mol.geomContainer.geoms['AtomLabels']
566 geom.Set(billboard=True, fontStyle='solid', fontScales=(.3,.3,.3,))
567 self.vf.labelByProperty(pTatomset, ('name', ), topCommand=0,location='Last', redraw=1)
568 self.buildCol(self.mol, self.torscount)
569 self.pTatomset = pTatomset
570 self.save = self.vf.ICmdCaller.commands.value[None]
571 self.vf.setICOM(self, topCommand = 0)
572 self.vf.setIcomLevel( Atom )
573 self.vf.flexDict['torscount'] = self.torscount
574
575
576
578
579 dict = self.vf.flexDict
580 flex_residues = dict['flex_residues']
581 badList = []
582 for item in flex_residues:
583 if not hasattr(item,'torscount'):
584 badList.append(item)
585 if not item.torscount:
586 print "eliminating", item.name
587 badList.append(item)
588 badSet = ResidueSet(badList)
589 flex_residues = flex_residues - badSet
590 dict['flex_residues'] = flex_residues
591 dict['rigidResidues'] = dict['rigidResidues']+badSet
592 dict['flex_residues_number'] = len(flex_residues)
593 if len(badSet):
594 badAtoms = badSet.atoms
595 self.currentNodes = self.currentNodes-badAtoms
596 self.changeFlexResCt(0)
597 self.vf.displayLines(self.currentNodes, only=1)
598 self.vf.colorByAtomType(self.currentNodes)
599 self.vf.labelByProperty(self.pTatomset, ('name', ), negate=True, topCommand=0, redraw=1)
600 self.pTatomset = AtomSet()
601
602 self.vf.setICOM(self.save, topCommand = 0)
603 self.vf.GUI.VIEWER.Redraw()
604 self.form.root.withdraw()
605 self.save = None
606
607
611
612
614 self.vf.flexDict['noAmides']=self.hasAmide
615 if self.hasAmide:
616 self.hasAmide = 0
617 self.turnOffAmides()
618 self.ifd.entryByName['noAmideBut']['widget'].config(text='amide torsions are not allowed')
619 else:
620 self.hasAmide = 1
621 self.turnOnAmides()
622 self.ifd.entryByName['noAmideBut']['widget'].config(text='amide torsions are allowed')
623
624
626 map(self.turnOffAmide, self.vf.flexDict['flex_residues'])
627
628
630 map(self.turnOnAmide, self.vf.flexDict['flex_residues'])
631
632
634 if not hasattr(res, 'amidebonds'):
635 return
636 for item in res.amidebonds:
637
638 if item.possibleTors and not item.activeTors:
639 item.activeTors = 1
640 self.torscount = self.torscount + 1
641
642
644 if not hasattr(res, 'amidebonds'):
645 return
646 for item in res.amidebonds:
647
648 if item.possibleTors and item.activeTors:
649 item.activeTors = 0
650 self.torscount = self.torscount - 1
651
652
654
655 s = 'Number of rotatable bonds ='+str(torscount) + ' / '+str(MAXTORS)+'\n'
656 self.torsStr.set(s)
657 currentbonds=mol.geomContainer.atoms['bonded'].bonds[0]
658 col = []
659 for b in currentbonds:
660 if b.possibleTors:
661 if b.activeTors: col.append((0,1,0))
662 else: col.append((1,0,1))
663 else:
664 col.append((1,0,0))
665 mol.geomContainer.geoms['bonded'].Set(materials=col,
666 inheritMaterial=False,
667 matBind=viewerConst.PER_PART)
668 self.vf.GUI.VIEWER.Redraw()
669
670
672 n=self.vf.flexDict['flex_residues_number']
673 n=n+delta
674 self.vf.flexDict['flex_residues_number']=n
675 msg = 'current %d flexible residues'%n
676 self.vf.GUI.pickLabel.configure(text=msg)
677
678
680 if self.renameAromatic.get():
681 self.ifd.entryByName['checkAromBut']['widget'].config(text='aromatic carbons named A..')
682 map(self.nameA,self.vf.flexDict['flex_residues'])
683 else:
684 self.ifd.entryByName['checkAromBut']['widget'].config(text='aromatic carbons named C..')
685 map(self.renameC,self.vf.flexDict['flex_residues'])
686
687
689 print 'changing the names of aromatic carbons is no longer supported'
690 return
691
692
694 print 'changing the names of aromatic carbons is no longer supported'
695 return
696
697
699 kw['topCommand'] = 0
700 kw['busyIdle'] = 1
701 kw['log'] = 0
702
703 apply(self.doitWrapper, (bonds,), kw)
704
705
706 - def doit(self, bonds):
707 if not self.currentNodes:
708 msg='No residues currently processed'
709 self.vf.warningMsg(msg)
710 return 'ERROR'
711 for bond in bonds:
712 if not bond.possibleTors: continue
713 atoms = AtomSet([bond.atom1, bond.atom2])
714 self.vf.ADflex_setBondRotatableFlag(atoms, not bond.activeTors,
715 topCommand = 0, redraw = 1, log =1, setupUndo = 1)
716
717
720
721
723 flexMol = self.vf.flexDict['flex_residues'].top.uniq()[0]
724 flexMolGeom = flexMol.geomContainer.geoms['bonded']
725 for o, val in pick.hits.items():
726 primInd = map(lambda x: x[0], val)
727 if o != flexMolGeom: continue
728 else: g = o.mol.geomContainer
729 if g.geomPickToBonds.has_key(o.name):
730 func = g.geomPickToBonds[o.name]
731 if func: return func(o, primInd)
732 else:
733 l = []
734 bonds = g.atoms[o.name].bonds[0]
735 for i in range(len(primInd)):
736 l.append(bonds[int(primInd[i])])
737 return BondSet(l)
738
739
741 self.guiUp = 0
742 if self.form: self.form.withdraw()
743 self.vf.colorByAtomType(self.vf.flexDict['flex_residues'],
744 topCommand=0, redraw=1)
745
746
748 self.vf.setICOM(self.save, topCommand=0)
749 self.save = None
750 self.done_cb()
751
752
753 AF_ProcessResiduesGUI = CommandGUI()
754
755
756
758 """ allows user to process interactively a set of hinge residues in macromolecule whose sidechains are to be flexed in an autodock run"""
759
760
767
768
770 if not hasattr(self.vf, 'flexDict'):
771 self.vf.flexDict = {}
772 if not hasattr(self.vf, 'colorByAtomType'):
773 self.vf.loadCommand('colorCommands', 'colorByAtomType', 'Pmv')
774 if not hasattr(self.vf, 'setICOM'):
775 self.vf.loadCommand('interactiveCommands', 'setICOM', 'Pmv')
776 if self.vf.hasGui and not self.torsStr:
777 self.torsStr = Tkinter.StringVar()
778
779
781 if hasattr(res, 'processed'):
782 print res.full_name(), ' already has autoflexFields'
783 return
784
785
786 backbone_names = ['C','N','O','HN','HN1','HN2', 'HA',
787 'H1','H2','H3','HO', 'H']
788
789
790 resatoms = res.atoms.get(lambda x: x in atoms)
791 sidechain = resatoms.get(lambda x: x.name not in backbone_names)
792 res.sideChain = sidechain
793 bondlist = res.bondlist = sidechain.bonds[0]
794 bondlist.leaf = 0
795 rbs = RotatableBondSelector()
796 rotatables = rbs.select(bondlist)
797 for b in rotatables:
798 b.possibleTors = 1
799 b.activeTors = 1
800 amides = AmideBondSelector().select(bondlist)
801 for b in amides:
802 b.activeTors = 0
803 b.possibleTors = 1
804 guanidiniums = GuanidiniumBondSelector().select(bondlist)
805 for b in guanidiniums:
806 b.activeTors = 0
807 b.possibleTors = 1
808 leaves = LeafBondSelector().select(bondlist)
809 for b in leaves:
810 b.activeTors = 0
811 b.possibleTors = 0
812 res.torscount = len(bondlist.get(lambda x: x.activeTors==1))
813
814 res.torsdof = res.torscount
815
816
817 res.processed = True
818
819
821 n = self.vf.flexDict.get('flex_residues_number',0)
822 n = n + delta
823 self.vf.flexDict['flex_residues_number'] = n
824 msg = 'current %d flexible residues'%n
825 self.vf.GUI.pickLabel.configure(text=msg)
826
827
829 """called INDIRECTLY each time the 'Set Selected Residues' button is pressed"""
830 if not self.vf.flexDict.has_key('hinge_list'):
831 t='set hinge first'
832 self.vf.warningMsg(t)
833 return 'ERROR'
834 h_list = self.vf.flexDict['hinge_list']
835 if not len(h_list):
836 t='currently hinge list is empty!'
837 self.vf.warningMsg(t)
838 return 'ERROR'
839 if not hasattr(self, 'hinge'):
840 self.hinge_to_process = self.vf.flexDict['hinge_list'][-1]
841 hinge = self.hinge_to_process
842 (atomOne,atomTwo), atoms = hinge
843 self.mol = atoms[0].top
844
845
846 if not len(atoms):
847 t='no hinge atoms specified'
848 self.vf.warningMsg(t)
849 return 'ERROR'
850 self.currentNodes = atoms
851 hinge_resSet = atoms.parent.uniq()
852 for res in hinge_resSet:
853 self.setAutoFlexFieldsHinge(res, atomOne, atomTwo, atoms)
854 self.torscount = Numeric.add.reduce(hinge_resSet.torscount)
855 self.changeHingeFlexResCt(len(hinge_resSet))
856 if not hasattr(self, 'ifdX'):
857 self.torsStr= Tkinter.StringVar()
858 s = 'Number of rotatable bonds ='+str(0)+ ' / '+str(MAXTORS)+'\n'
859 self.torsStr.set(s)
860 self.renameAromatic= Tkinter.IntVar()
861 infoStr = 'Pick or drag-&-pick bonds. \nGreen = rotatable, \nMagenta = non-rotatable, \nRed = unrotatable.\n\n'
862 ifdX = self.ifdX=InputFormDescr(title='Torsion Count')
863 ifdX.append({'name': 'maxTorsLab',
864 'widgetType':Tkinter.Label,
865 'wcfg':{'text':infoStr},
866 'gridcfg':{'sticky':Tkinter.W + Tkinter.E}}),
867 ifdX.append({'name':'torsEntryLab',
868 'widgetType':Tkinter.Label,
869 'wcfg':{'textvariable':self.torsStr},
870 'gridcfg':{'sticky':Tkinter.W +Tkinter.E}}),
871 ifdX.append({'name': 'closeBut',
872 'widgetType':Tkinter.Button,
873 'wcfg':{'text':'Close','command':self.closeX_cb},
874 'gridcfg':{'sticky':Tkinter.W+Tkinter.E, 'columnspan':2}})
875 self.formX= self.vf.getUserInput(self.ifdX, modal=0, blocking=0)
876 else:
877 if hasattr(self,'formX'):
878 self.formX.root.deiconify()
879 self.save = self.vf.ICmdCaller.commands.value[None]
880 self.vf.setICOM(self, topCommand = 0)
881 self.vf.setIcomLevel( Atom )
882
883
884 self.vf.flexDict.setdefault('torscount', 0)
885 if 'flex_residues' in self.vf.flexDict.keys() and \
886 len(self.vf.flexDict['flex_residues']):
887 self.vf.flexDict['torscount'] += self.torscount
888 else:
889 self.vf.flexDict['torscount'] = self.torscount
890 self.vf.displayLines(self.currentNodes, only=1, topCommand=0, redraw=1)
891 self.buildCol(self.mol, self.torscount)
892
893
895 dict = self.vf.flexDict
896 self.vf.displayLines(self.currentNodes, only=1)
897 self.vf.colorByAtomType(self.currentNodes)
898 self.vf.GUI.VIEWER.Redraw()
899 self.formX.root.withdraw()
900 self.vf.flexDict.setdefault('torscount', 0)
901
902
903 flex_residues_torscount = 0
904 if hasattr(self.vf.ADflex_setResidues, 'torscount') and \
905 self.vf.ADflex_setResidues.torscount>0:
906 flex_residues_torscount = self.vf.ADflex_setResidues.torscount
907 self.vf.flexDict['torscount'] = self.torscount + flex_residues_torscount
908 self.vf.setICOM(self.save, topCommand = 0)
909 self.save = None
910 self.dismiss()
911
912
914
915 s = 'Number of rotatable bonds ='+str(torscount) + ' / '+str(MAXTORS)+'\n'
916 self.torsStr.set(s)
917 currentbonds = mol.geomContainer.atoms['bonded'].bonds[0]
918 col = []
919 for b in currentbonds:
920 if hasattr(b, 'possibleTors') and b.possibleTors:
921 if hasattr(b, 'activeTors') and b.activeTors: col.append((0,1,0))
922 else: col.append((1,0,1))
923 else:
924 col.append((1,0,0))
925 mol.geomContainer.geoms['bonded'].Set(materials=col,
926 inheritMaterial=False,
927 matBind=viewerConst.PER_PART)
928 self.vf.GUI.VIEWER.Redraw()
929
930
932 self.vf.flexDict.setdefault('flex_residues_number',0)
933 n = self.vf.flexDict['flex_residues_number']
934 n = n + delta
935 self.vf.flexDict['flex_residues_number'] = n
936 msg = 'current %d flexible residues'%n
937 self.vf.GUI.pickLabel.configure(text=msg)
938
939
941 kw['topCommand'] = 0
942 kw['busyIdle'] = 1
943 kw['log'] = 0
944
945
946 apply(self.doitWrapper, (bonds,), kw)
947
948
949 - def doit(self, bonds, **kw):
950 if not self.currentNodes:
951 msg='No residues currently processed'
952 self.vf.warningMsg(msg)
953 return 'ERROR'
954 for bond in bonds:
955 if not bond.possibleTors:
956 continue
957 atoms = AtomSet([bond.atom1, bond.atom2])
958 self.vf.ADflex_setBondRotatableFlag(atoms, not bond.activeTors,
959 topCommand = 0, redraw = 1, log =1, setupUndo = 1,
960 flexRes=True)
961
962
965
966
968 flexMol = self.mol
969 flexMolGeom = flexMol.geomContainer.geoms['bonded']
970 for o, val in pick.hits.items():
971 primInd = map(lambda x: x[0], val)
972 if o != flexMolGeom: continue
973 else: g = o.mol.geomContainer
974 if g.geomPickToBonds.has_key(o.name):
975 func = g.geomPickToBonds[o.name]
976 if func: return func(o, primInd)
977 else:
978 l = []
979 bonds = g.atoms[o.name].bonds[0]
980 for i in range(len(primInd)):
981 l.append(bonds[int(primInd[i])])
982 return BondSet(l)
983
984
986 self.guiUp = 0
987 if self.form: self.form.withdraw()
988
989 self.vf.GUI.VIEWER.Redraw()
990
991
993 self.vf.setICOM(self.save, topCommand=0)
994 self.save = None
995 self.done_cb()
996
997 AF_ProcessHingeResiduesGUI = CommandGUI()
998
999
1000
1002 """ allows user to remove atoms to be moved from a hinge interactively"""
1003
1004
1006 MVCommand.__init__(self, func)
1007 MVAtomICOM.__init__(self)
1008 self.save = None
1009 self.mode = None
1010 self.atomList = AtomSet([])
1011
1012
1013
1015 if not hasattr(self.vf, 'flexDict'):
1016 self.vf.flexDict = {}
1017 if not hasattr(self.vf, 'colorByAtomType'):
1018 self.vf.loadCommand('colorCommands', 'colorByAtomType', 'Pmv')
1019 if not hasattr(self.vf, 'setICOM'):
1020 self.vf.loadCommand('interactiveCommands', 'setICOM', 'Pmv')
1021 if not hasattr(self.vf, 'ADflex_setHinge'):
1022 self.vf.loadCommand('autoflexCommands', 'ADflex_setHinge', 'AutoDockTools')
1023 if self.vf.hasGui:
1024 self.mode = Tkinter.StringVar()
1025
1026
1028 if newval == 'yes':
1029 self.continuousUpdate = 1
1030 for event in ['<B2-Motion>', '<B3-Motion>', '<Shift-B3-Motion>']:
1031 self.vf.GUI.addCameraCallback(event, self.update_cb)
1032 else:
1033 self.continuousUpdate = 0
1034 for event in ['<B2-Motion>', '<B3-Motion>', '<Shift-B3-Motion>']:
1035 self.vf.GUI.removeCameraCallback(event, self.update_cb)
1036
1037
1041
1042
1043 - def update(self, forward=1, event=None):
1044
1045 if not len(self.atomList):
1046 print 'Currently no atoms: resetting geoms'
1047 return
1048 for at in self.atomList:
1049 c1 = self.getTransformedCoords(at)
1050 self.vf.ADflex_setHinge.lineVertices.append(tuple(c1))
1051 self.vf.ADflex_setHinge.update()
1052
1053
1055 """ """
1056 if not hasattr(self,'form'):
1057 ifd = self.ifd = InputFormDescr(title="Edit Atoms to be moved by current Hinge by:")
1058
1059
1060
1061
1062 ifd.append({'widgetType':Tkinter.Radiobutton,
1063 'wcfg':{'text':'adding Atoms',
1064 'variable':self.mode,
1065 'value': 'add'},
1066 'gridcfg':{'sticky':'we'}})
1067 ifd.append({'widgetType':Tkinter.Radiobutton,
1068 'wcfg':{'text':'removing Atoms',
1069 'variable':self.mode,
1070 'value': 'remove'},
1071 'gridcfg':{'row':-1,'sticky':'we'}})
1072
1073
1074
1075 self.form = self.vf.getUserInput(ifd, modal=0, blocking=0)
1076 self.form.root.protocol('WM_DELETE_WINDOW',self.close_cb)
1077 else:
1078 self.form.root.deiconify()
1079 self.save = self.vf.ICmdCaller.commands.value[None]
1080 self.vf.setICOM(self)
1081
1082
1084
1085 self.stop()
1086 self.form.withdraw()
1087 self.vf.GUI.VIEWER.Redraw()
1088 self.mode.set("")
1089
1090 flexDict = self.vf.flexDict
1091 all = 'all_hinge_atoms'
1092 opp = 'non_hinge_atoms'
1093
1094
1095 flexDict = self.vf.flexDict
1096 flexDict[all], flexDict[opp] = self.vf.ADflex_setHinge.getAllHingeAtoms()
1097
1098
1099
1100
1101
1102 - def doit(self, atoms):
1103 if not hasattr(self.vf, 'flexDict'):
1104 self.warningMsg('no flexDIct!')
1105 return "ERROR"
1106 dict = self.vf.flexDict
1107 if not 'hinge_list' in dict.keys():
1108 self.warningMsg('no hinge_list in flexDict!')
1109 return "ERROR"
1110 hinges = self.vf.flexDict['hinge_list']
1111 if not len(hinges):
1112 self.warningMsg('current hinges in hinge_list !')
1113 return "ERROR"
1114 if len(hinges):
1115 current_hinge = hinges[-1]
1116 if not len(current_hinge)==2:
1117 self.warningMsg('last hinge in hinge_list is ill-formed!')
1118 return 'ERROR'
1119 atoms_to_move = current_hinge[1]
1120 if not len(atoms_to_move):
1121 self.warningMsg("no atoms to move in current hinge!")
1122 return "ERROR"
1123 if self.mode.get()=='remove':
1124 new_atoms_to_move = atoms_to_move - atoms
1125
1126 else:
1127 new_atoms_to_move = atoms_to_move + atoms
1128
1129
1130 new_ats = new_atoms_to_move.uniq()
1131 self.vf.flexDict['hinge_list'][-1][1] = new_ats
1132 self.vf.ADflex_setHinge.atoms = new_ats
1133 if self.vf.hasGui:
1134 self.vf.ADflex_setHinge.hingeAtoms.Set(vertices = new_ats.coords)
1135 self.vf.ADflex_setHinge.hingeAtoms.visible = 1
1136 self.vf.GUI.VIEWER.Redraw()
1137
1138
1140 self.vf.setIcomLevel( Atom )
1141
1142
1144 self.vf.setICOM(self.save, topCommand=0)
1145 self.save = None
1146 self.vf.GUI.VIEWER.Redraw()
1147 self.done_cb()
1148
1151
1153 self.guiUp = 0
1154 if self.form: self.form.withdraw()
1155
1156
1157
1158 AF_EditHingeGUI = CommandGUI()
1159 AF_EditHingeGUI.addMenuCommand('AutoToolsBar', menuText['AutoFlexMB'],\
1160 menuText['Edit Hinge'])
1161
1162
1163
1164
1166 """ allows user to setup a hinge interactively to be flexed in an autodock run"""
1167
1168
1170 MVCommand.__init__(self, func)
1171 MVAtomICOM.