1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 """
21 This Module facilitates selecting and formatting a ligand for a subsequent
22 AutoDock run. The steps in this process are:
23
24 * The user selects the small molecule from a list of molecules
25 already in the moleculeViewer OR as a PDBQ file, a PDB file or
26 a MOL2 file from a fileBrowser.
27
28 * The user selects the ROOT atom of the ligand either:
29
30 o by picking it or
31
32 o by autoroot which sets the root to be the atom in the
33 molecule which has the smallest 'largest sub-tree.'
34
35 * Next the user decides which possible and active torsions he wants
36 to disallow, changing them from active to inactive. This is done by picking
37 an active 'green' bond which turns it inactive or 'purple'. This is
38 reversible. The user can also disallow all peptide backbone torsions and/or
39 all torsions of amide bonds.
40
41 * Carbons in cycles can be tested for aromaticity. If the angle
42 between the normals to adjacent atoms in the cycle is less than 7.5 Degrees,
43 the cycle is considered aromatic: its carbons are renamed "A.." and their
44 element type set to 'A'. (This is for the force-field calculations done
45 in AutoDock.) This Module does this conversion reversibly. Also, the user
46 is able to select a carbon to convert (reversibly) and he can change the
47 the value of the aromaticity cut-off.
48
49 * Non-polar hydrogens and lone pairs are merged which means that the charge of
50 each is added to its heavy atom and the hydrogen atoms themselves are not written
51 in the output file, thus in some sense 'removing' them from the molecule.
52 'Fewer' atoms simplifies the AutoDock run.
53
54 * The last function of this Module is to write a file which contains
55 the correctly formatted ligand atoms. The ROOT section of the molecule
56 expands from the selected ROOT atom out to include all atoms adjacent to it
57 up to the first active torsion. The active torsions set the position of
58 BRANCH key words in the output pdbq file (and their corresponding
59 ENDBRANCH key words). These keywords are nested to set up a
60 Breadth-First Order Traversal. Autotors also calculates the torsional degrees
61 of freedom (TORSDOF) which is the number of possible torsions less the number of
62 symmetry-equivalent torsions (such as a bond to a NH3). This key word is the
63 last line of the pdbq file.
64 """
65
66
67
68 from MoleculePreparation import LigandPreparation, AD4LigandPreparation
69 from DejaVu import viewerConst
70 from DejaVu.Geom import Geom
71 from PyBabel.cycle import RingFinder
72 from Pmv.mvCommand import MVCommand, MVAtomICOM, MVBondICOM
73
74 from MolKit import Read
75 from MolKit.torTree import TorTree
76 from MolKit.tree import TreeNode, TreeNodeSet
77 from MolKit.molecule import AtomSet, Atom, BondSet
78 from MolKit.protein import Protein, Chain, ChainSet
79 from MolKit.pdbWriter import PdbqWriter, PdbqtWriter
80
81 from MolKit.mol2Parser import Mol2Parser
82
83 from ViewerFramework.VFCommand import Command, CommandGUI
84
85 from mglutil.gui.InputForm.Tk.gui import InputFormDescr
86 from Pmv.guiTools import MoleculeChooser
87 from Pmv.qkollua import q
88 from SimpleDialog import SimpleDialog
89
90 import types, Tkinter, Numeric, math, os, Pmw, tkMessageBox
91 from string import split, find
92
93
94 from DejaVu.Spheres import Spheres
95 rootSph = Spheres(name='autotors_rootSph', materials=((0.,1.,0),),
96 shape = (0,3), radii = 0.3, quality = 15, inheritMaterial=0,
97 vertices=((0.,0.,0.),), visible=0, pickable=0)
98 markSph = Spheres(name='autotors_markSph', materials=((0.,1.,0),),
99 shape = (0,3), radii = 0.15, quality = 15,inheritMaterial=0,
100 vertices=((0.,0.,0.),), visible=0, pickable=0)
101
103 autotors_geoms_list = VFGUI.VIEWER.findGeomsByName('autotors_geoms')
104 if autotors_geoms_list==[]:
105 autotors_geoms = Geom("autotors_geoms", shape=(0,0), protected=True)
106 VFGUI.VIEWER.AddObject(autotors_geoms, parent=VFGUI.miscGeom)
107 autotors_geoms_list = [autotors_geoms]
108 return autotors_geoms_list[0]
109
110
111
112 MAXTORS = 32
113
115 try:
116 print event.widget
117 except:
118 pass
119
120
121
122
123 menuText = {}
124 menuText['AutoTorsMB'] = 'Ligand'
125 menuText['Input Molecule'] = 'Input'
126 menuText['Read Molecule'] = 'Open...(AD3)'
127 menuText['Choose Molecule'] = 'Choose...(AD3)'
128 menuText['Rigid Molecule'] = 'Open as Rigid...(AD3)'
129 menuText['Read Molecule4'] = 'Open...'
130 menuText['Choose Molecule4'] = 'Choose...'
131 menuText['Rigid Molecule4'] = 'Open as Rigid...'
132 menuText['Ref Molecule'] = 'Write Reference File'
133
134 menuText['DefineRigidRootMB'] = 'Torsion Tree'
135 menuText['ByPicking'] = 'Choose Root...'
136 menuText['PickChain'] = 'Add a chain to root'
137 menuText['UnPickChain'] = 'Remove a chain from root'
138 menuText['Automatically'] = 'Detect Root...'
139 menuText['SRA1'] = 'Show Root Expansion'
140 menuText['SRA2'] = 'Hide Root Expansion'
141 menuText['ShowRootAtoms'] = menuText['SRA1']
142 menuText['ShowAutotorsRootSphMB'] = 'Show/Hide Root Marker'
143
144 menuText['DefineRotatableBondsMB'] = 'Rotatable Bonds'
145 menuText['DefineRotatableBonds'] = 'Choose Torsions...'
146 menuText['SetTorsionNumber'] = 'Set Number of Torsions...'
147
148 menuText['MActive1'] = 'Make all rotatable bonds non-rotatable'
149 menuText['MActive2'] = 'Make all rotatable bonds rotatable'
150 menuText['MAmide1'] = 'Make amide bonds non-rotatable'
151 menuText['MAmide2'] = 'Make amide bonds rotatable'
152 menuText['MGuan1'] = 'Make guanidinium bonds non-rotatable'
153 menuText['MGuan2'] = 'Make guanidinium bonds rotatable'
154 menuText['MPeptide1'] = 'Make peptide backbone bonds non-rotatable'
155 menuText['MPeptide2'] = 'Make peptide backbone bonds rotatable'
156 menuText['MAmide'] = menuText['MAmide1']
157 menuText['MPeptide'] = menuText['MPeptide1']
158 menuText['MSelected1'] = 'Make bonds between selected atoms non-rotatable'
159 menuText['MSelected2'] = 'Make rotatable bonds between selected atoms rotatable'
160 menuText['MSelected'] = menuText['MSelected1']
161
162 menuText['AromaticCarbonsMB'] = 'Aromatic Carbons'
163 menuText['RenameAromaticCarbons'] = 'Rename (C>A)'
164 menuText['RestoreAliphaticCarbons'] = 'Restore (A>C)'
165 menuText['SetCarbonNames'] = 'Set Names...'
166 menuText['ChangeAromaticityCriteria'] = 'Aromaticity Criterion...'
167
168 menuText['NonPolarHydrogensMB'] = 'Merge NonPolar Hydrogens'
169 menuText['Merge'] = 'Merge'
170 menuText['Restore'] = 'Restore'
171
172 menuText['WriteMB'] = 'Output'
173 menuText['WritePDBQMB'] = 'Save as PDBQ...(AD3)'
174 menuText['WritePDBQTMB'] = 'Save as PDBQT...'
175
176
177 menuText['AutomaticAutotorsSetupMB'] = 'Quick Setup...'
178
179
180
181 menuText['torStr1'] = 'Number of rotatable bonds = '
182 menuText['torStr2'] = ' / ' + str(MAXTORS) + '\n'
183
184
185
186 warningText= {}
187
188 warningText['noMolecule'] = 'Sorry, you need to read in a molecule first.\n\nUse the menu\n\n"%s:\n %s\n :%s".' %(menuText['AutoTorsMB'],menuText['Input Molecule'], menuText['Read Molecule4'])
189
190 warningText['noAtorsMol'] = 'Sorry, you need to read or choose a molecule first.\n\nUse either:\n\n%s:\n %s:\n %s\n or\n %s' % (menuText['AutoTorsMB'],menuText['Input Molecule'], menuText['Read Molecule4'], menuText['Choose Molecule4'])
191
192 charge_errorfile = None
193
195
196 if not hasattr(vf, 'checkResCharges'):
197 vf.loadCommand('editCommands',['checkResCharges'])
198 totalCharge,resList = vf.checkResCharges(mol, topCommand=0)
199 errCharge = round(totalCharge,0) - totalCharge
200
201 if errCharge < -.07 or errCharge > .07:
202 msg = 'Non-integral charge on '+ mol.name +': '+ \
203 str(totalCharge) + '\n\n'
204 lenres = len(resList)
205 if lenres:
206 msg = msg + 'correct %d residues:\n' %len(resList)
207 truncated = 0
208 if lenres>15:
209 truncated=1
210 msg= msg + '(truncated at 15..)\n'
211 resList = resList[:15]
212 ss = ''
213 for item in resList:
214 ss = ss + item.name + ' '+ str(item.err)+'\n'
215 msg = msg + ss
216 if truncated:
217 msg= msg + '....\n'
218 msg = msg + '\nCharges should be corrected in written output file!'
219 vf.warningMsg(msg)
220 if charge_errorfile is not None: charge_errorfile.write(msg)
221 return errCharge, resList
222
223
224 autoMergeNPHS = 1
225
230
231
232
233 -def initLPO(mol, mode='interactive',repairs="", root=0, outputfilename=None,
234 cleanup='nphs_lps'):
259
260
261
262
263 -def initLPO4(mol, mode='interactive',repairs="", root=0, outputfilename=None,
264 cleanup='nphs_lps'):
287
288
289
291 """allows user to choose as ligand a molecule already in the viewer"""
292
293
295 if not hasattr(self.vf, 'atorsDict'):
296 self.vf.atorsDict={}
297 if not hasattr(self.vf,'readMolecule'):
298 self.vf.loadCommand('fileCommands', 'readMolecule', 'Pmv',
299 topCommand=0)
300
301
302 - def __init__(self, mode='single', title = 'Choose Molecule for AutoDock3'):
306
307
309 """called each time the 'choose Ligand' button is pressed"""
310 mols = self.chooser.getMolSet()
311 if mols is not None:
312 self.chooser.form.withdraw()
313 self.doitWrapper(mols, redraw=0)
314
315
316
318 self.chooser = MoleculeChooser(self.vf, self.mode, self.title)
319 self.chooser.ipf.append({'name':'Select Button',
320 'widgetType':Tkinter.Button,
321 'text':'Select Autotors Molecule',
322 'wcfg':{'bd':6},
323 'gridcfg':{'sticky':'we'},
324 'command': self.chooseLigand_cb})
325 self.form = self.chooser.go(modal=0, blocking=0)
326 lb = self.chooser.ipf.entryByName['Molecule']['widget'].lb
327 lb.bind("<Double-Button-1>",self.chooseLigand_cb)
328
329
331 """None<-ADtors_chooseLigand(nodes)
332 nodes:ligand for autodock
333 """
334 apply(self.doitWrapper, (nodes,), kw)
335
336
337 - def doit(self, nodes, **kw):
338 mol = self.vf.expandNodes(nodes)[0]
339 filename = mol.parser.filename
340 ftype=split(filename,'.')[-1]
341
342
343 if ftype not in ['pdbq', 'pdb', 'pdbqs','pdbqt', 'mol2', 'dlg']:
344 msg = "unknown filetype: "+ ftype
345 self.vf.warningMsg(msg)
346
347 return
348 useTorTree=kw.get('useTorTree', 0)
349 if not useTorTree and hasattr(mol, 'torTree'):
350 msg = mol.name + ' already has a a torsion tree. Do you want to use it to set the activity of rotatable bonds?'
351 d = SimpleDialog(self.vf.GUI.ROOT, text=msg,
352 buttons=['No','Yes'], default=1,
353 title='Use Previous Torsion Tree?')
354 useTorTree=d.go()
355 print 'set useTorTree to', useTorTree
356
357
358
359 self.vf.atorsDict['molecule'] = mol
360 if not hasattr(mol, 'LPO') or mol.LPO.version==4:
361 if useTorTree:
362 root = mol.ROOT
363 cleanup = "nphs_lps"
364 if self.vf.userpref['adt_automergeNPHS']['value']==0:
365 cleanup = "lps"
366 initLPO(mol, cleanup=cleanup)
367 title = "summary for " + mol.name
368 self.vf.warningMsg(mol.LPO.summarize(), title=title)
369 self.vf.allAtoms = self.vf.Mols.chains.residues.atoms
370
371 if useTorTree:
372 self.rebuildTorTree(mol, root)
373
374 if self.vf.hasGui:
375 self.vf.colorByAtomType(mol, ['lines'], topCommand=0)
376
377 self.vf.color(mol.LPO.aromCs,((0,1,0,),), ['lines'], topCommand=0)
378 self.vf.centerScene(topCommand=0)
379 self.vf.displayLines(mol,topCommand=0)
380 self.vf.GUI.VIEWER.Redraw()
381
382
383
384
386
387
388
389 allAts = mol.allAtoms
390 for b in allAts.bonds[0]:
391 if b.activeTors:
392 b.activeTors = 0
393 torscount = 0
394 tM = mol.torTree.torsionMap
395 for i in range(len(tM)):
396 bnum0, bnum1 = tM[i].bond
397 a0 = allAts.get(lambda x: x.number==bnum0+1)[0]
398
399
400 a0.tt_ind = bnum0
401 a1 = allAts.get(lambda x: x.number==bnum1+1)[0]
402
403
404 a1.tt_ind = bnum1
405 b = AtomSet([a0,a1]).bonds[0]
406 assert b is not None
407 if hasattr(b, 'possibleTors'):
408 assert b.possibleTors
409 else:
410 b.possibleTors = 1
411 b.activeTors = 1
412 torscount = torscount + 1
413
414
415 mol.torscount = len(mol.allAtoms.bonds[0].get(lambda x: x.activeTors==1))
416 mol.ROOT = root
417 mol.ROOT.rnum0 = 0
418
419
421 listChooser = self.ipf.entryByName['Molecule']['widget']
422 tkListBox = listChooser.lb
423 atom,geom = self.vf.findPickedAtom(event)
424 if atom is not None:
425 pickedMol = atom.top
426
427 for i in range(len(listChooser.entries)):
428 listChooserlist=split(listChooser.entries[i][0])
429 if pickedMol.name == listChooserlist[0]:
430 self.pickedMolIndex= i
431 tkListBox.select_clear(0,'end')
432 listChooser.select(i)
433 return
434 t= "error: on %s " %pickedMol.name
435 self.vf.warningMsg(t)
436
437
438 AtorsMoleculeChooserGUI=CommandGUI()
439 AtorsMoleculeChooserGUI.addMenuCommand('AutoToolsBar', menuText['AutoTorsMB'], menuText['Choose Molecule'], cascadeName = menuText['Input Molecule'])
440
441
442
444 """allows user to select a file for the ligand via a file browser"""
445
446
448 if not hasattr(self.vf, 'atorsDict'):
449 self.vf.atorsDict={}
450 if not hasattr(self.vf, 'readMolecule'):
451 self.vf.loadCommand('fileCommands', 'readMolecule', 'Pmv')
452
453
455 """called each time the 'select molecule' button is pressed"""
456 molFile = self.vf.askFileOpen(types=[('PDBQ files:', '*.pdbq'),\
457 ('PDB files:', '*.pdb'), ('MOL2 files:','*.mol2'),\
458 ('all files:', '*')],\
459 title = 'Ligand file for AutoDock3:')
460 if not molFile: return
461 self.doitWrapper(molFile, ask=1, redraw=1)
462
463
464 - def __call__(self, filename, log=1, **kw):
465 """None<-ADtors_readLigand(filename)
466 filename:file to read to get ligand for autodock
467 """
468 kw['log'] = log
469 apply(self.doitWrapper, (filename,),kw)
470
471
472 - def doit(self, filename, **kw):
473
474
475
476 ftype = split(filename,'.')[-1]
477 if ftype not in ['pdbq','pdb','pdbqt', 'pdbqs','mol2']:
478 msg = "unknown ligand file type " + ftype
479 self.vf.warningMsg(msg)
480 return
481 mols = self.vf.readMolecule(filename, log=0)
482 if not mols:
483 return 'ERROR'
484 if len(mols)>1:
485 msg = str(len(mols)) + ' molecules in ', filename
486 self.vf.warningMsg(msg)
487 maxAts = 0
488 for m in mols:
489 numAts = len(m.allAtoms)
490 if numAts>maxAts:
491 mol = m
492 maxAts = numAts
493 else:
494 mol = mols[0]
495 if not mol.chains[0].hasBonds:
496 mol.buildBondsByDistance()
497
498 cleanup = "nphs_lps"
499 if self.vf.userpref['adt_automergeNPHS']['value']==0:
500 cleanup = "lps"
501 initLPO(mol, cleanup=cleanup)
502 title = "summary for " + mol.name
503 self.vf.warningMsg(mol.LPO.summarize(), title=title)
504
505 self.vf.allAtoms = self.vf.Mols.chains.residues.atoms
506 self.vf.atorsDict['molecule'] = mol
507
508 if self.vf.hasGui:
509 self.vf.colorByAtomType(mol, ['lines'], topCommand=0)
510
511 self.vf.color(mol.LPO.aromCs,((0,1,0,),), ['lines'], topCommand=0)
512 self.vf.centerScene(topCommand=0)
513 self.vf.displayLines(mol,topCommand=0)
514 self.vf.GUI.VIEWER.Redraw()
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531 AtorsReaderGUI = CommandGUI()
532 AtorsReaderGUI.addMenuCommand('AutoToolsBar', menuText['AutoTorsMB'], menuText['Read Molecule'], cascadeName = menuText['Input Molecule'])
533
534
535
537 """allows user to choose as ligand a molecule already in the viewer"""
538
539
541 if not hasattr(self.vf, 'atorsDict'):
542 self.vf.atorsDict={}
543 if not hasattr(self.vf,'readMolecule'):
544 self.vf.loadCommand('fileCommands', 'readMolecule', 'Pmv',
545 topCommand=0)
546
547
548 - def __init__(self, mode='single', title = 'Choose Molecule for AutoDock4'):
552
553
555 """called each time the 'choose Ligand4' button is pressed"""
556 mols = self.chooser.getMolSet()
557 if mols is not None:
558 self.chooser.form.withdraw()
559 self.doitWrapper(mols, redraw=0)
560
561
562
564 self.chooser = MoleculeChooser(self.vf, self.mode, self.title)
565 self.chooser.ipf.append({'name':'Select Button',
566 'widgetType':Tkinter.Button,
567 'text':'Select Molecule for AutoDock4',
568 'wcfg':{'bd':6},
569 'gridcfg':{'sticky':'we'},
570 'command': self.chooseLigand_cb})
571 self.form = self.chooser.go(modal=0, blocking=0)
572 lb = self.chooser.ipf.entryByName['Molecule']['widget'].lb
573 lb.bind("<Double-Button-1>",self.chooseLigand_cb)
574
575
577 """None<-ADtors4_chooseLigand(nodes)
578 nodes:ligand for autodock4
579 """
580 apply(self.doitWrapper, (nodes,), kw)
581
582
583 - def doit(self, nodes, **kw):
584 mol = self.vf.expandNodes(nodes)[0]
585 filename = mol.parser.filename
586 ftype=split(filename,'.')[-1]
587
588
589 if ftype not in ['pdbq', 'pdb', 'pdbqs','pdbqt', 'mol2', 'dlg']:
590 msg = "unknown filetype: "+ ftype
591 self.vf.warningMsg(msg)
592
593 return
594 useTorTree=0
595 if hasattr(mol, 'torTree'):
596 if 'useTorTree' in kw.keys():
597 useTorTree = kw['useTorTree']
598 else:
599 msg = mol.name + ' already has a a torsion tree. Do you want to use it to set the activity of rotatable bonds?'
600 d = SimpleDialog(self.vf.GUI.ROOT, text=msg,
601 buttons=['No','Yes'], default=1,
602 title='Use Previous Torsion Tree?')
603 useTorTree=d.go()
604 print 'set useTorTree to', useTorTree
605
606
607
608 self.vf.atorsDict['molecule'] = mol
609 if not hasattr(mol, 'LPO') or mol.LPO.version==3:
610 cleanup = "nphs_lps"
611 if self.vf.userpref['adt_automergeNPHS']['value']==0:
612 cleanup = "lps"
613 initLPO4(mol, cleanup=cleanup)
614 title = "summary for " + mol.name
615 self.vf.warningMsg(mol.LPO.summarize(), title=title)
616
617 zero_charge_atoms = mol.allAtoms.get(lambda x: x.charge==0 and x.element!='C')
618 if zero_charge_atoms is not None and len(zero_charge_atoms):
619 msg = "These atoms have zero charge:\n"
620 for a in zero_charge_atoms:
621 msg = msg + a.name + " "
622 self.vf.warningMsg(msg)
623 self.vf.allAtoms = self.vf.Mols.chains.residues.atoms
624
625 if useTorTree:
626 self.rebuildTorTree(mol, mol.ROOT)
627
628
629 if self.vf.hasGui:
630 self.vf.colorByAtomType(mol, ['lines'], topCommand=0)
631
632 self.vf.color(mol.LPO.aromCs,((0,1,0,),), ['lines'], topCommand=0)
633 self.vf.centerScene(topCommand=0)
634 self.vf.displayLines(mol,topCommand=0)
635 self.vf.GUI.VIEWER.Redraw()
636
637
638
639
641
642
643
644 allAts = mol.allAtoms
645 for b in allAts.bonds[0]:
646 if b.activeTors:
647 b.activeTors = 0
648 torscount = 0
649 tM = mol.torTree.torsionMap
650 for i in range(len(tM)):
651 bnum0, bnum1 = tM[i].bond
652 a0 = allAts.get(lambda x: x.number==bnum0 + 1)[0]
653
654 a0.tt_ind = bnum0
655
656 a1 = allAts.get(lambda x: x.number==bnum1 + 1)[0]
657 a1.tt_ind = bnum1
658 b = AtomSet([a0,a1]).bonds[0]
659 if hasattr(b, 'possibleTors'):
660 assert b.possibleTors
661 else:
662 b.possibleTors = 1
663 b.activeTors = 1
664 torscount = torscount + 1
665
666
667 mol.torscount = torscount
668 mol.ROOT = root
669 mol.ROOT.rnum0 = 0
670
671
673 listChooser = self.ipf.entryByName['Molecule']['widget']
674 tkListBox = listChooser.lb
675 atom,geom = self.vf.findPickedAtom(event)
676 if atom is not None:
677 pickedMol = atom.top
678
679 for i in range(len(listChooser.entries)):
680 listChooserlist=split(listChooser.entries[i][0])
681 if pickedMol.name == listChooserlist[0]:
682 self.pickedMolIndex= i
683 tkListBox.select_clear(0,'end')
684 listChooser.select(i)
685 return
686 t= "error: on %s " %pickedMol.name
687 self.vf.warningMsg(t)
688
689
690 Ators4MoleculeChooserGUI=CommandGUI()
691 Ators4MoleculeChooserGUI.addMenuCommand('AutoToolsBar', menuText['AutoTorsMB'], menuText['Choose Molecule4'], cascadeName = menuText['Input Molecule'])
692
693
694
696 """allows user to select a file for the ligand via a file browser"""
697
698
700 if not hasattr(self.vf, 'atorsDict'):
701 self.vf.atorsDict={}
702 if not hasattr(self.vf, 'readMolecule'):
703 self.vf.loadCommand('fileCommands', 'readMolecule', 'Pmv')
704
705
707 """called each time the 'select molecule' button is pressed"""
708 molFile = self.vf.askFileOpen(types=[ ('PDBQT files:', '*.pdbqt'),\
709 ('PDBQ files:', '*.pdbq'),\
710 ('MOL2 files:','*.mol2'), ('PDB files:', '*.pdb'),\
711 ('all files:', '*')],\
712 title = 'Ligand File for AutoDock4:')
713 if not molFile: return
714 self.doitWrapper(molFile, ask=1, redraw=1)
715
716
717 - def __call__(self, filename, log=1, **kw):
718 """None<-ADtors4_readLigand(filename)
719 filename:file to read to get ligand for autodock
720 """
721 kw['log'] = log
722 apply(self.doitWrapper, (filename,),kw)
723
724
725 - def doit(self, filename, **kw):
726
727
728
729 ftype = split(filename,'.')[-1]
730 if ftype not in ['pdbq','pdb','pdbqt', 'pdbqs','mol2']:
731 msg = "unknown ligand file type " + ftype
732 self.vf.warningMsg(msg)
733 return
734 mols = self.vf.readMolecule(filename, log=0)
735 if not mols:
736 return 'ERROR'
737 if len(mols)>1:
738 msg = str(len(mols)) + ' molecules in ', filename
739 self.vf.warningMsg(msg)
740 maxAts = 0
741 for m in mols:
742 numAts = len(m.allAtoms)
743 if numAts>maxAts:
744 mol = m
745 maxAts = numAts
746 else:
747 mol = mols[0]
748 if not mol.chains[0].hasBonds:
749 mol.buildBondsByDistance()
750
751 cleanup = "nphs_lps"
752 if self.vf.userpref['adt_automergeNPHS']['value']==0:
753 cleanup = "lps"
754 initLPO4(mol, cleanup=cleanup)
755 title = "summary for " + mol.name
756 self.vf.warningMsg(mol.LPO.summarize(), title=title)
757
758 self.vf.allAtoms = self.vf.Mols.chains.residues.atoms
759 self.vf.atorsDict['molecule'] = mol
760
761 if self.vf.hasGui:
762 self.vf.colorByAtomType(mol, ['lines'], topCommand=0)
763
764 self.vf.color(mol.LPO.aromCs,((0,1,0,),), ['lines'], topCommand=0)
765 self.vf.centerScene(topCommand=0)
766 self.vf.displayLines(mol,topCommand=0)
767 self.vf.GUI.VIEWER.Redraw()
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784 Ators4ReaderGUI = CommandGUI()
785 Ators4ReaderGUI.addMenuCommand('AutoToolsBar', menuText['AutoTorsMB'], menuText['Read Molecule4'], cascadeName = menuText['Input Molecule'])
786
787
788
790 """allows user to prepare a reference file for the ligand"""
791
792
794 if not hasattr(self.vf, 'atorsDict'):
795 self.vf.atorsDict={}
796 if not hasattr(self.vf, 'readMolecule'):
797 self.vf.loadCommand('fileCommands', 'readMolecule', 'Pmv')
798 self.PdbqWriter = PdbqWriter()
799
800
801
803 """called each time the 'select reference' button is pressed"""
804
805
806 ligfile = self.vf.atorsDict['molecule'].LPO.outputfilename
807 if not ligfile:
808 ligfile = self.vf.askFileOpen(types=[ ('formatted ligand files:', '*.pdbq'),\
809 ('all files:', '*')],\
810 title = 'Formatted Ligand File:')
811
812 if ligfile:
813 reffile = self.vf.askFileOpen(types=[ ('PDB files:', '*.pdb'),\
814 ('all files:', '*')],\
815 title = 'Autotors Reference File:')
816
817 if reffile:
818 self.doitWrapper(ligfile, reffile, ask=1, redraw=1)
819
820
821 - def __call__(self, ligfile, reffile, log=1, **kw):
822 """None<-ADtors_prepRef(ligfile, reffile)
823 ligfile: written output file
824 reffile:input file to reorder to be rms reference for autodock
825 """
826 kw['log'] = log
827 apply(self.doitWrapper, (ligfile, reffile,),kw)
828
829
830 - def doit(self, ligfile, reffile, **kw):
831
832
833
834 ligs = self.vf.readMolecule(ligfile)
835 if not ligs:
836 return 'ERROR'
837 lig = ligs[0]
838 if not lig.chains[0].hasBonds:
839 lig.buildBondsByDistance()
840 refs = self.vf.readMolecule(reffile, log=0)
841 if not refs:
842 return 'ERROR'
843 ref = refs[0]
844 if not ref.chains[0].hasBonds:
845 ref.buildBondsByDistance()
846
847 assert len(lig.allAtoms)==len(ref.allAtoms)
848 refAts = ref.allAtoms
849 refAtNames = refAts.name
850 ref.allAtoms.written = 0
851 lig.allAtoms.written = 0
852 changedAts = []
853 for ligAt in lig.allAtoms:
854
855 if ligAt.name[0]=='A':
856 if len(ligAt.name)==1:
857 ligAt.name = 'C'
858 else:
859 ligAt.name = 'C' + ligAt.name[1:]
860 changedAts.append(ligAt)
861
862 if ligAt.element!='H':
863 assert ligAt.name in refAtNames
864 outfilename = os.path.splitext(os.path.basename(reffile))[0] + '.ref.pdb'
865 fptr = open(outfilename, 'w')
866 ctr = 1
867 for a in lig.allAtoms:
868
869 if a.element!='H' and a.name in refAtNames:
870
871 a2 = refAts.get(lambda x, n=a.name:x.name==n)[0]
872 else:
873
874 foundAt = 0
875 for b in a.bonds:
876
877 neighbor = a.bonds[0].neighborAtom(a)
878
879 n2s = refAts.get(lambda x, n=neighbor.name: x.name==n)
880 if n2s is not None:
881
882 for n2 in n2s:
883 for b in n2.bonds:
884
885 a2 = b.neighborAtom(n2)
886 if a2.written:
887 continue
888
889 elif a2.element==a.element:
890
891 foundAt = 1
892 break
893 if not foundAt:
894 print 'could not match ', a.full_name(), ' ', a.number
895
896 a.written = 1
897 a2.written = 1
898 a2.number = ctr
899 ctr = ctr + 1
900 self.PdbqWriter.write_atom(fptr,a2)
901
902 fptr.close()
903 for a in changedAts:
904 if len(a.name)==1:
905 a.name = 'A'
906 else:
907 a.name = 'A' + a.name[1:]
908
909
910
911 AtorsRefWriterGUI = CommandGUI()
912 AtorsRefWriterGUI.addMenuCommand('AutoToolsBar', menuText['AutoTorsMB'], menuText['Ref Molecule'], cascadeName = menuText['Input Molecule'])
913
914
915
917 """allows user to write molecule with ROOT, ENDROOT + TORSDOF 0 added"""
918
919
921 molFile = self.vf.askFileOpen(types=[('select file:', '*.pdbq')],
922 title = 'Read PDBQ for Rigid Autotors Output:')
923 if not molFile: return
924 outFile = self.vf.askFileSave(types=[('outputfile:', '*.pdbq')],
925 title = 'Rigid Autotors Outputfile:')
926
927 if outFile:
928 self.doitWrapper(molFile, outFile, log=1, redraw=0)
929
930
931
932 - def __call__(self, molFile, outFile, **kw):
933 """None<-ADtors_rigidLigand(molFile, outFile)
934 molFile:file to read to get ligand
935 outFile: file to write formatted rigid ligand
936 """
937 if not molFile:
938 return 'ERROR'
939 if not outFile:
940 return 'ERROR'
941 apply(self.doitWrapper, (molFile, outFile,),kw)
942
943
944
945 - def doit(self, molFile, outFile):
946 molFileptr = open(molFile, 'r')
947 allLines = molFileptr.readlines()
948 molFileptr.close()
949 outfptr = open(outFile, 'w')
950 outstring = 'REMARK 0 active torsions:\n'
951 outfptr.write(outstring)
952 outstring = 'ROOT\n'
953 outfptr.write(outstring)
954 for l in allLines:
955 startLine = l[:4]
956 if startLine == 'ATOM' or startLine == 'HETA':
957 outfptr.write(l)
958 outstring = 'ENDROOT\n'
959 outfptr.write(outstring)
960 outstring = 'TORSDOF 0\n'
961 outfptr.write(outstring)
962 outfptr.close()
963
964
965 RigidMoleculeGUI = CommandGUI()
966 RigidMoleculeGUI.addMenuCommand('AutoToolsBar', menuText['AutoTorsMB'], menuText['Rigid Molecule'], cascadeName = menuText['Input Molecule'], separatorBelow=1)
967
968
969
971 """allows user to write molecule with ROOT, ENDROOT + TORSDOF 0 added"""
972
973
975 molFile = self.vf.askFileOpen(types=[('select file:', '*.pdbqt')],
976 title = 'Read PDBQT for Rigid Autotors Output:')
977 if not molFile: return
978 outFile = self.vf.askFileSave(types=[('outputfile:', '*.pdbqt')],
979 title = 'Rigid Autotors4 Outputfile:')
980
981 if outFile:
982 self.doitWrapper(molFile, outFile, log=1, redraw=0)
983
984
985
986 - def __call__(self, molFile, outFile, **kw):
987 """None<-ADtors4_rigidLigand(molFile, outFile)
988 molFile:file to read to get ligand
989 outFile: file to write formatted rigid ligand
990 """
991 if not molFile:
992 return 'ERROR'
993 if not outFile:
994 return 'ERROR'
995 apply(self.doitWrapper, (molFile, outFile,),kw)
996
997
998
999 - def doit(self, molFile, outFile):
1000 molFileptr = open(molFile, 'r')
1001 allLines = molFileptr.readlines()
1002 molFileptr.close()
1003 outfptr = open(outFile, 'w')
1004 outstring = 'REMARK 0 active torsions:\n'
1005 outfptr.write(outstring)
1006 outstring = 'ROOT\n'
1007 outfptr.write(outstring)
1008 for l in allLines:
1009 startLine = l[:4]
1010 if startLine == 'ATOM' or startLine == 'HETA':
1011 outfptr.write(l)
1012 outstring = 'ENDROOT\n'
1013 outfptr.write(outstring)
1014 outstring = 'TORSDOF 0\n'
1015 outfptr.write(outstring)
1016 outfptr.close()
1017
1018
1019 RigidMolecule4GUI = CommandGUI()
1020 RigidMolecule4GUI.addMenuCommand('AutoToolsBar', menuText['AutoTorsMB'], menuText['Rigid Molecule4'], cascadeName = menuText['Input Molecule'], separatorBelow=1)
1021
1022
1024 """allows user to select and write an output file for the formatted ligand
1025 for AutoDock3
1026 """
1027
1028
1030 if not hasattr(self.vf, 'atorsDict'):
1031 self.vf.atorsDict={}
1032
1033
1034 - def doit(self, filename):
1035
1036 dict = self.vf.atorsDict
1037 if not dict.has_key('molecule'):
1038 self.vf.warningMsg(warningText['noAtorsMol'])
1039 return 'ERROR'
1040 mol = dict['molecule']
1041
1042
1043 if mol.LPO.version==4:
1044 msg = mol.name + " currently formatted for AutoDock4!\nUnable to write AutoDock3 file"
1045 self.vf.warningMsg(msg)
1046 return "ERROR"
1047 mol.LPO.write(filename)
1048 if self.vf.hasGui:
1049 rootSph.Set(visible=0)
1050
1051
1052
1053
1055 """None<-ADtors_writeFormattedPDBQ(filename)
1056 filename: file to write formatted ligand
1057 """
1058 apply(self.doitWrapper, (filename,), kw)
1059
1060
1062 hasGui = self.vf.hasGui
1063 dict = self.vf.atorsDict
1064 if not dict.has_key('molecule'):
1065 self.vf.warningMsg(warningText['noAtorsMol'])
1066 return
1067 mol = dict['molecule']
1068 if not hasattr(mol, 'ROOT'):
1069 self.vf.warningMsg('Must select root before writing file')
1070 return
1071 newfile = self.vf.askFileSave(types=[('PDBQ files:', '*.out.pdbq',)],
1072 title = 'Formatted Autotors Molecule File:')
1073
1074 if newfile:
1075 self.doitWrapper(newfile, log=1, redraw=0)
1076
1077
1078 AUTOTORSWriterGUI=CommandGUI()
1079
1080 AUTOTORSWriterGUI.addMenuCommand('AutoToolsBar', menuText['AutoTorsMB'], menuText['WritePDBQMB'],
1081 cascadeName = menuText['WriteMB'])
1082
1083
1084
1086 """allows user to select and write an output file for the formatted ligand
1087 for AutoDock4
1088 ADD PDBQTWriter switch here-->>>
1089 """
1090
1091
1093 if not hasattr(self.vf, 'atorsDict'):
1094 self.vf.atorsDict={}
1095
1096
1097 - def doit(self, filename):
1098
1099 dict = self.vf.atorsDict
1100 if not dict.has_key('molecule'):
1101 self.vf.warningMsg(warningText['noAtorsMol'])
1102 return 'ERROR'
1103 mol = dict['molecule']
1104
1105
1106 if mol.LPO.version==3:
1107 msg = mol.name + " currently formatted for AutoDock3!\nUnable to write AutoDock4 file"
1108 self.vf.warningMsg(msg)
1109 return "ERROR"
1110 mol.LPO.write(filename)
1111 if self.vf.hasGui:
1112 rootSph.Set(visible=0)
1113
1114
1115
1116
1118 """None<-ADtors4_writeFormattedPDBQT(filename)
1119 filename: file to write formatted ligand
1120 """
1121 apply(self.doitWrapper, (filename,), kw)
1122
1123
1125 hasGui = self.vf.hasGui
1126 dict = self.vf.atorsDict
1127 if not dict.has_key('molecule'):
1128 self.vf.warningMsg(warningText['noAtorsMol'])
1129 return
1130 mol = dict['molecule']
1131 if not hasattr(mol, 'ROOT'):
1132 self.vf.warningMsg('Must select root before writing file')
1133 return
1134 newfile = self.vf.askFileSave(types=[('PDBQT files:', '*.pdbqt',)],
1135 title = 'Formatted Autotors Molecule File:')
1136
1137 if newfile:
1138 self.doitWrapper(newfile, log=1, redraw=0)
1139
1140
1141 AUTOTORS4WriterGUI=CommandGUI()
1142 AUTOTORS4WriterGUI.addMenuCommand('AutoToolsBar', menuText['AutoTorsMB'], menuText['WritePDBQTMB'],
1143 cascadeName = menuText['WriteMB'])
1144
1145
1146
1148 """shows current extent of root portion of the molecule:it includes all contiguous atoms starting with those adjacent to the designated root atom out to first active torsion """
1149
1150
1152 if not hasattr(self.vf, 'atorsDict'):
1153 self.vf.atorsDict={}
1154 self.markonoff = 0
1155 if self.vf.hasGui:
1156 self.markOn_Off = Tkinter.IntVar()
1157 self.markOn_Off.set(0)
1158
1159
1160 miscGeom = self.vf.GUI.miscGeom
1161
1162
1163
1164
1165
1166 parentGeom = Geom("autotorsGeoms", shape=(0,0))
1167 if parentGeom not in self.vf.GUI.VIEWER.rootObject.children:
1168 parentGeom.replace = True
1169 self.vf.GUI.VIEWER.AddObject(parentGeom, redo=0, parent=miscGeom)
1170 if markSph not in self.vf.GUI.VIEWER.rootObject.children:
1171 markSph.replace = True
1172 self.vf.GUI.VIEWER.AddObject(markSph, redo=0, parent=parentGeom)
1173 if not hasattr(self.vf, 'setICOM'):
1174 self.vf.loadCommand('interactiveCommands', 'setICOM', 'Pmv')
1175
1176
1178 """None<-ADtors_markRoot()
1179 starts or stops marking root expansion display:
1180 all atoms in root portion of ligand are marked with small sphere"""
1181 apply(self.doitWrapper,(), kw)
1182
1183
1185 if self.markonoff==0:
1186 return
1187 if not self.vf.atorsDict.has_key('molecule'):
1188 self.vf.warningMsg("you must select a ligand molecule first!")
1189 return "ERROR"
1190 mol = self.vf.atorsDict['molecule']
1191 if not hasattr(mol, 'ROOT'):
1192 rootSph.Set(visible = 0)
1193 return
1194 allBonds = mol.allAtoms.bonds[0]
1195 for b in allBonds:
1196 b.marked = 0
1197
1198 self.neighborList = AtomSet()
1199 self.getNeighbors(mol.ROOT)
1200
1201
1202 delattr(allBonds, 'marked')
1203 activeNeighbors = self.neighborList
1204 if len(activeNeighbors):
1205 markSph.Set(visible=1)
1206 markSph.Set(vertices=activeNeighbors.coords)
1207 else:
1208 markSph.Set(visible=0)
1209 del self.neighborList
1210
1211
1213 numBonds = len(at.bonds)
1214 notActBonds = filter(lambda x: x.activeTors!=1, at.bonds)
1215 numMarkedBonds = filter(lambda x: x.marked==1, at.bonds)
1216 numNotActive = len(notActBonds)
1217 for b in notActBonds:
1218 if b.marked:
1219 continue
1220 if numBonds==numMarkedBonds:
1221 continue
1222 b.marked = 1
1223 if b.atom1!=at:
1224 self.neighborList.append(b.atom1)
1225 self.getNeighbors(b.atom1)
1226 else:
1227 self.neighborList.append(b.atom2)
1228 self.getNeighbors(b.atom2)
1229
1230
1232
1233 if self.markOn_Off.get():
1234 self.markonoff = 0
1235 markSph.Set(visible=0)
1236
1237 menu = self.vf.GUI.menuBars['AutoToolsBar'].menubuttons[menuText['AutoTorsMB']].menu
1238 children = menu.children[menuText['DefineRigidRootMB']]
1239 ind = children.index(menuText['ShowRootAtoms'])
1240 children.entryconfig(ind,{'label':menuText['SRA1']})
1241 menuText['ShowRootAtoms'] = menuText['SRA1']
1242 if self.vf.hasGui:
1243 self.markOn_Off.set(0)
1244 else:
1245 self.markOn_Off.set(1)
1246 self.markonoff = 1
1247 if not self.vf.atorsDict.has_key('molecule'):
1248 self.vf.warningMsg(warningText['noAtorsMol'])
1249 return
1250 molecule = self.vf.atorsDict['molecule']
1251 if not hasattr(molecule, 'ROOT'):
1252 self.vf.warningMsg('select root FIRST!')
1253 return
1254 menu = self.vf.GUI.menuBars['AutoToolsBar'].menubuttons[menuText['AutoTorsMB']].menu
1255 children = menu.children[menuText['DefineRigidRootMB']]
1256 ind = children.index(menuText['ShowRootAtoms'])
1257 children.entryconfig(ind,{'label':menuText['SRA2']})
1258 menuText['ShowRootAtoms'] = menuText['SRA2']
1259 self.doitWrapper(log=1,redraw=1)
1260
1261
1262 MarkRootGUI=CommandGUI()
1263 MarkRootGUI.addMenuCommand('AutoToolsBar', menuText['AutoTorsMB'], menuText['SRA1'],
1264 cascadeName = menuText['DefineRigidRootMB'])
1265
1266
1267
1269 """allows user to pick an atom to be ROOT, the rigid portion
1270 of ligand which has rotatable BRANCHES """
1271
1272
1274 if not hasattr(self.vf, 'atorsDict'):
1275 self.vf.atorsDict={}
1276 if self.vf.hasGui:
1277
1278 parent = check_autotors_geoms(self.vf.GUI)
1279 if rootSph not in self.vf.GUI.VIEWER.rootObject.children:
1280 rootSph.replace = True
1281 self.vf.GUI.VIEWER.AddObject(rootSph,
1282 redo=0, parent=parent)
1283 if not hasattr(self.vf, 'setICOM'):
1284 self.vf.loadCommand('interactiveCommands', 'setICOM', 'Pmv')
1285
1286
1287
1288
1290 MVCommand.__init__(self, func)
1291 MVAtomICOM.