1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """
23 This Module facilitates producing a grid parameter file for AutoGrid. The steps in this process are:
24
25 * 'Macromolecule': Selecting the macromolecule:
26 The user can select the macromolecule for autogpf in two ways:
27 - it can be chosen from molecules previously added to the moleculeViewer
28 - it can be read in from a file:
29
30 o Choose Macromol...
31
32 o Read Macromolecule
33
34
35 * 'Set Map Types': Setting the types of maps to generate:
36
37 o Set Map Types Directly
38
39 o By Choosing Ligand
40
41 o By Reading Formatted File
42
43 The user can change the types of maps to be calculated.
44 He decides which types of possible hydrogen bonding he wishes to model.
45 For instance, IF hydrogens are present AND nitrogens, oxygens and /or sulfurs,
46 the user can decide to model N-H bonds, O-H bonds and/or S-H bonds.
47 He sets which type of dielectric to use:
48 -distance-dependent dielectric
49 -constant dielectric
50 (Other ligand-related commands allow the user to set energy parameters for new
51 atom types or to set up a specialized 'covalent' grid-map.)
52
53
54 * 'Set Grid': The user positions the grid and sets its dimensions by:
55
56 o Setting the center of the grid maps:
57
58 - by picking an atom or
59
60 - by entering the full-name of an atom or
61
62 - by entering the desired coordinates in entries 'x center', 'y center',
63 'z center' (NB: ALL entries must be 'activated' by a 'Return')
64
65 - by choosing the 'Center on Macromolecule' option which sets the
66 center of the grid to the geometric center of the macromolecule (obtained by
67 averaging all its coordinates)
68
69 - by choosing the 'Center on Ligand' option which sets the center of
70 the grid to the geometric center of the ligand (obtained by averaging all its
71 coordinates)
72
73 o Setting the number of grid points in each direction (which has to be an
74 even number) and the spacing between the points. This is done by using the
75 corresponding scale widgets.
76
77 o Adjusting the position of the grid using scales for x-offset, y-offset
78 and z-offset. These scales allow the user to move the grid box up to 10 angstroms
79 in any direction along any of the three axes.
80 (NOTE that the units of these scales are tenths of Angstroms and the new coordinates
81 of the center are reflected in the x-center, y-center, z-center entries)
82
83 * 'Set Other Options': The user adjusts these additional parameters:
84
85 o the smoothing factor can be changed from its default 0.5Angstrom value.
86 This changes the radius of the area within which the minimum energy is stored.
87 o electrostatic potential map may or may not be generated by AutoGrid
88
89 o floating point potential map may or may not be generated
90
91 o the user may decide whether or not to use the default distance dependent
92 dielectric constant. If not, he can enter his desired dielectric constant or use
93 the default value, 40. It should be noted that this entered value is multiplied
94 by 0.1146 by the program for input to AutoGrid.
95
96 * 'Write GPF': The results of the previous steps are written to a file.
97 The user selects a filename via a filebrowser. By convention, the file should
98 have a .gpf extension. If no macromolecule has been selected, it is not possible
99 to write a grid parameter file and the user gets a warning message to that effect.
100 Likewise, the types of the maps to be calculated must be set before the grid
101 parameter file is written and a warning message to this effect appears if the
102 types have not been set.
103
104 * 'Edit GPF': Allows user to edit a grid parameter file. If one has been
105 written, it is automatically loaded. Otherwise, the user can select any *.gpf
106 file to edit from a file browser.
107
108 """
109 from ViewerFramework.VFCommand import CommandGUI
110 from ViewerFramework.VF import AddAtomsEvent
111
112
113 from mglutil.gui.InputForm.Tk.gui import InputFormDescr
114
115 from mglutil.util.callback import CallBackFunction
116
117 from MolKit.tree import TreeNode, TreeNodeSet
118 from MolKit.molecule import Atom, AtomSet
119 from MolKit.protein import Residue, ResidueSet
120 from MolKit import Read
121 from Pmv.mvCommand import MVCommand, MVAtomICOM
122 from Pmv.guiTools import MoleculeChooser
123 from Pmv.qkollua import q
124 from SimpleDialog import SimpleDialog
125 import types, Tkinter, Numeric, math, os
126
127
128 from energyConstants import Rij, epsij, SolVol, SolPar, SolCon
129
130 from autotorsCommands import checkMolCharges
131 from autotorsCommands import set_autoMergeNPHS
132 from GridParameters import GridParameters, \
133 grid_parameter_list, grid_parameter_list4
134
135 from mglutil.gui.BasicWidgets.Tk.thumbwheel import ThumbWheel
136 import tkSimpleDialog
137 from string import split, find, join, upper, rfind, replace
138 from MoleculePreparation import ReceptorPreparation, AD4ReceptorPreparation
139
140 from atomTypeTools import AutoDock4_AtomTyper
141
142 from DejaVu.Geom import Geom
143
144
145
147 autogpf_geoms_list = VFGUI.VIEWER.findGeomsByName('autogpf_geoms')
148 if autogpf_geoms_list==[]:
149 autogpf_geoms = Geom("autogpf_geoms", shape=(0,0), protected=True)
150 VFGUI.VIEWER.AddObject(autogpf_geoms, parent=VFGUI.miscGeom)
151 autogpf_geoms_list = [autogpf_geoms]
152 return autogpf_geoms_list[0]
153
154
155
156 from DejaVu.Spheres import Spheres
157 cenSph = Spheres(name='autogpf_cenSph', materials=((0.,1.,0),), shape = (0,3),
158 radii = 0.3, quality = 15, vertices=((0.,0.,0.),), visible=0,
159 pickable=0, inheritMaterial=0)
160 cenSph.in_viewer = False
161
162 from DejaVu.Points import CrossSet
163 cenCross = CrossSet('autogpf_cenCross', materials=((1.,1.,0),),
164 inheritMaterial=0,
165 offset=1.0,lineWidth=2, visible=0, pickable=0)
166 cenCross.in_viewer = False
167
168 from mglutil.gui.BasicWidgets.Tk.customizedWidgets import ExtendedSliderWidget
169
170 from DejaVu.IndexedPolygons import IndexedPolygons
171 from DejaVu.Box import Box
172 from DejaVu import viewerConst
173 from DejaVu.bitPatterns import patternList
174 from opengltk.OpenGL import GL
175 import Numeric
176
177 face=((0,3,2,1),(3,7,6,2),(7,4,5,6),(0,1,5,4),(1,2,6,5),(0,4,7,3))
178 coords=((1,1,-1),(-1,1,-1),(-1,-1,-1),(1,-1,-1),(1,1,1),(-1,1,1),(-1,-1,1),(1,-1,1))
179
180 materials=((0,0,1),(0,1,0),(0,0,1),(0,1,0),(1,0,0),(1,0,0),)
181
182
183 box=IndexedPolygons('box', materials=materials, vertices=coords, faces=face,
184 inheritMaterial=0)
185 box.Set(frontPolyMode=GL.GL_FILL)
186 box.inheritShading=0
187 box.shading=GL.GL_FLAT
188 box.Set(matBind=viewerConst.PER_PART)
189 box.Set(visible=0, inheritStipplePolygons=0)
190 box.polygonstipple.Set(pattern=patternList[0])
191 box.Set(stipplePolygons=1)
192 box.transparent=0
193 box.oldFPM = None
194 box.in_viewer = False
195
196
197
198 menuText = {}
199
200 menuText['AutoGpfMB'] = 'Grid'
201
202 menuText['ReadGpfMB'] = 'Open GPF...'
203 menuText['MacromoleculeMB'] = 'Macromolecule'
204 menuText['ChooseMacro'] = 'Choose...(AG3)'
205 menuText['ReadMacro'] = 'Open...(AG3)'
206 menuText['ChooseMacro4'] = 'Choose...'
207 menuText['ReadMacro4'] = 'Open...'
208 menuText['MergeNPHS'] = 'Merge NonPolar Hydrogens'
209 menuText['AddSol'] = 'Add Solvent Parameters...(AG3)'
210
211 menuText['SetMapTypesMB'] = 'Set Map Types'
212 menuText['SetMapDirectly4'] = 'Directly...'
213 menuText['SetMapDirectly'] = 'Directly...(AG3)'
214 menuText['SetUpCovalentMap'] = 'Set Up Covalent Map...(AG3)'
215 menuText['ByChoosingLigand'] = 'Choose Ligand...(AG3)'
216 menuText['ByReadingFile'] = 'Open Ligand...(AG3)'
217 menuText['ByChoosingLigand4'] = 'Choose Ligand...'
218 menuText['ByReadingFile4'] = 'Open Ligand...'
219 menuText['ByChoosingFlexRes4'] = 'Choose FlexRes Molecule...'
220 menuText['ByReadingFlexResFile4'] = 'Open Flexible Residues...'
221 menuText['SetNewTypeParms'] = 'Set New Atom Type Parameters...(AG3)'
222
223 menuText['SetGridMB'] = 'Grid Box...'
224
225 menuText['SetOtherOptionsMB'] = 'Other Options...'
226 menuText['SetOtherOptionsMB_AG3'] = 'Other Options...(AG3)'
227 menuText['SetParameterFilename'] = 'Parameter Library Filename...'
228
229 menuText['WriteMB'] = 'Output'
230 menuText['WriteGpfMB'] = 'Save GPF...(AG3)'
231 menuText['WriteGpf4MB'] = 'Save GPF...'
232
233 menuText['EditGpfMB'] = 'Edit GPF...'
234
235
236 gridOpts = {}
237 gridOpts['PickCenter'] = 'on picked Atom'
238 gridOpts['CenterLigand'] = "on Ligand"
239 gridOpts['CenterMacro'] = "on Macromolecule\n('auto' option)"
240 gridOpts['EnterCenter'] = "Enter Center Atom\nFull Name:"
241 gridOpts['TotalPtsLabel'] = "Current Total Grid Pts per map:"
242 gridOpts['XNumLabel'] = "number of xpts"
243 gridOpts['YNumLabel'] = "number of ypts"
244 gridOpts['ZNumLabel'] = "number of zpts"
245 gridOpts['gridSpacingLabel'] = "grid spacing:"
246 gridOpts['ShowGridBoxLabel'] = "Show Box"
247 gridOpts['ShowCenterCrossLabel'] = "Show Center Marker"
248 gridOpts['AsLinesLabel'] = "As Lines"
249 gridOpts['AsFacesLabel'] = "As Faces"
250 gridOpts['CenterGridBoxLabel'] = "Center Grid Box: <offset> "
251 gridOpts['XCenterLabel'] = "x center: "
252 gridOpts['YCenterLabel'] = "y center: "
253 gridOpts['ZCenterLabel'] = "z center: "
254 gridOpts['XOffsetLabel'] = "x offset(tenths of Angstrom):"
255 gridOpts['YOffsetLabel'] = "y offset(tenths of Angstrom):"
256 gridOpts['ZOffsetLabel'] = "z offset(tenths of Angstrom):"
257 gridOpts['AcceptBut'] = "Accept"
258 gridOpts['CloseBut'] = "Close"
259
260
261
262 messages = {}
263 messages['unknownExt'] = 'unknown file extension: must be pdbqs or pdbq or pdb'
264 messages['requiredExt'] = "macromolecule type must be 'pdbqs', 'pdbq', 'pdb' or 'mol2'"
265 messages['multipleMols'] = 'more than one molecule in file'
266 messages['multipleLigs'] = 'more than one ligand in file'
267 messages['multipleFlexRes'] = 'more than one flexible residue molecules in file'
268 messages['unknownLigExt'] = "unknown ligand type"
269 messages['unknownFlexResExt'] = "unknown flexible residue filetype"
270 messages['mergeNPHSReqExt'] = "for GpfMergeNonPolarHs: macromolecule type\
271 must be 'pdbqs' or 'pdbq'"
272 messages['noNonPolarHs'] = 'No NonPolarHydrogens Found'
273 messages['nphsOutExt'] = 'must save to pdbqs or pdbq type file'
274 messages['addSolExt'] = "for addsol: macromolecule type must be 'pdbq'"
275 messages['addSolExt'] = "for addsol: macromolecule type must be 'pdbq'"
276
277
279 if not hasattr(vf, 'gpo'):
280 vf.gpo = GridParameters()
281 vf.gpo.vf = vf
282 if vf.hasGui:
283 autogpf_geoms = check_autogpf_geoms(vf.GUI)
284 if not cenSph.in_viewer:
285 vf.GUI.VIEWER.AddObject(cenSph, redo=0, parent=autogpf_geoms)
286 cenSph.in_viewer = True
287 if not cenCross.in_viewer:
288 vf.GUI.VIEWER.AddObject(cenCross, redo=0, parent=autogpf_geoms)
289 cenCross.in_viewer = True
290 if not box.in_viewer:
291 vf.GUI.VIEWER.AddObject(box, redo=0, parent=autogpf_geoms)
292 box.in_viewer = True
293
294
295
297 """ Command to set values in gpo object using gui input results"""
298
299
302
303
304 - def doit(self, *args, **kw):
305 if not len(kw.items()):
306 return 'ERROR'
307
308 for key, val in kw.items():
309 self.vf.gpo[key]['value'] = val
310
311
312
313
315 """ allows user to select a file containing a set of defaults"""
316
317
320
321
323 if not os.path.exists(gpffile):
324 raise IOError
325 apply(self.doitWrapper,(gpffile,),kw)
326
327
328 - def doit(self, gpffile):
329 if not gpffile: return 'ERROR'
330 self.vf.gpo.read(gpffile)
331
332
334 """called each time the 'select defaultList file' button is pressed"""
335 gpfFile = self.vf.askFileOpen(types=[('grid parameter files:', '*.gpf')],
336 title = 'Select GPF File:')
337
338 if gpfFile:
339 self.doitWrapper(gpfFile, log=1, redraw=0)
340
341
342 GpfLoadDefaultsGUI = CommandGUI()
343 GpfLoadDefaultsGUI.addMenuCommand('AutoToolsBar', menuText['AutoGpfMB'], menuText['ReadGpfMB'])
344
345
346
348 """AD3 receptor is initialized as specified in parameters:
349 autodock_element field added
350 whether receptor is a protein is determined
351 if molecule is lacking charges or if charges are all 0.
352 Kollman charges are added to protein receptors
353 and Gasteiger charges are computed for non-protein receptors.
354 a check is made that total charge per residue is an integer.
355 lone pairs merged
356 non-polar hydrogens merged unless userpref set not to merge
357 macro sidelengths set (???????????)
358 types of atoms in receptor added as '.mset'
359 possibility of adding new atom types to Rij/epsij dicts
360 solvation parameter fields are added: AtVol + AtSolPar
361 which is written to newfilename if specified
362 otherwise to mol.name+'.pdbqs'
363 receptor is colored by Atom Type"""
364
365
369
370
372 if self.vf.hasGui:
373 for item in ['writePDB','writePDBQ','writePDBQS']:
374 if not hasattr(self.vf, item):
375 self.vf.loadCommand('fileCommands', item, 'Pmv')
376 self.vf.loadModule('colorCommands','Pmv')
377
378
379 if not hasattr(self.vf, 'editHist_h'):
380 self.vf.loadCommand('repairCommands', 'editHist_h', 'Pmv')
381 self.vf.loadModule('editCommands','Pmv')
382
383 checkHasGpo(self.vf)
384 self.resKeys = q.keys()
385 self.editHISprotonation = None
386 if 'adt_automergeNPHS' not in self.vf.userpref.keys():
387 doc = """Automatically merge non-polar hydrogens in formatting molecules for AutoDock. Valid values are 1 or 0"""
388 self.vf.userpref.add('adt_automergeNPHS', 1, [0,1],
389 callbackFunc = [set_autoMergeNPHS], doc=doc, prefFile =
390 '.adtrc' )
391 if 'adt_editHISprotonation' not in self.vf.userpref.keys():
392 doc = """Automatically set protonation state of all histidine residues in macromolecule. Valid values are 'HD1', 'HE2', 'HD1HE2', 'No change'. Default value is 'No change' which has no effect on macromolecule. Any other choice invokes editHist_h method of repairCommand module to edit hydrogens on histidine ring. For example, if userpref is set to 'HD1' each histidine ring will have hydrogen atom 'HD1' and not 'HE2' hydrogen atom."""
393 self.vf.userpref.add('adt_editHISprotonation', 'No change',
394 ['No change', 'HD1', 'HE2', 'HD1HE2'],
395 callbackFunc = [self.set_editHISprotonation], doc=doc ,
396 prefFile = '.adtrc')
397
398
400 self.editHISprotonation = newval
401 try:
402 self.vf.ADgpf4_initMacro.editHISprotonation = newval
403 except:
404 pass
405
406
408
409
410 dict = {}
411 for r in resSet:
412 dict[r.type] = 0
413 for t in dict.keys():
414 if t not in self.resKeys:
415 return 0
416
417
418 return 1
419
420
421 - def __call__(self, mol, filename=None, **kw):
422 """ """
423 mols = self.vf.expandNodes(mol)
424 if not mols:
425 return 'ERROR'
426
427 kw['filename'] = filename
428 apply(self.doitWrapper,(mols[0],), kw)
429
430
431 - def doit(self, mol, **kw):
432
433
434
435
436
437 msg = 'initializing ' + os.path.basename(mol.parser.filename) + ':\n'
438
439 for at in mol.allAtoms:
440
441 if not hasattr(at, 'autodock_element'):
442 at.autodock_element = at.element
443 needToAddCharges = 0
444 nphs = None
445 lps = None
446 needToAddSolPar = 0
447 basename = os.path.basename(mol.parser.filename)
448 if os.path.splitext(basename)[1]!='.pdbqs':
449
450
451 mol.isPeptide = self.checkIsPeptide(mol.chains.residues)
452 if mol.isPeptide:
453 msg = msg + ' it is a peptide\n'
454 else:
455 msg = msg + ' it is not a peptide\n'
456 chargedAts = mol.allAtoms.get(lambda x: hasattr(x, 'charge'))
457 if not chargedAts:
458 needToAddCharges = 1
459 elif len(chargedAts)!=len(mol.allAtoms):
460 needToAddCharges = 1
461 elif len(filter(lambda x:x.charge==0, chargedAts))==len(chargedAts):
462
463 needToAddCharges = 1
464 if needToAddCharges:
465 if mol.isPeptide:
466 self.vf.addKollmanCharges(mol, topCommand=0, log=0)
467 msg = msg + ' -added Kollman charges\n'
468 else:
469 self.vf.computeGasteiger(mol, topCommand=0, log=0)
470 msg = msg + ' -added gasteiger charges\n'
471
472
473
474 renumber = 0
475 hs = mol.allAtoms.get(lambda x: x.element=='H')
476 hs_with_no_bonds = hs.get(lambda x: len(x.bonds)==0)
477 hs_with_bonds = hs.get(lambda x: len(x.bonds)>0)
478
479
480 nphs = hs_with_bonds.get(lambda x: x.bonds[0].atom1.element=='C' or x.bonds[0].atom2.element=='C')
481 if not nphs:
482 msg = msg + ' -found ' + str(len(nphs)) + ' non-polar hydrogens\n'
483 if hs_with_no_bonds:
484 m3 = "'" + mol.name + "'" + " has one or more hydrogens with no bonds: "
485 for at in hs_with_no_bonds:
486 m3 += at.parent.parent.name + ':'+ at.parent.name +':'+ at.name + ','
487 self.vf.warningMsg(m3[:-1], title='AD3 Receptor Summary:')
488 if len(nphs) and self.vf.userpref['adt_automergeNPHS']['value']:
489
490
491 renumber = 1
492 if self.vf.hasGui:
493 self.vf.mergeNPHSGC(mol, logBaseCmd=0)
494
495 else:
496 self.vf.mergeNPHS(mol)
497 msg = msg + ' -merged nphs\n'
498
499
500 hs = self.vf.allAtoms.get(lambda x: x.element=='H')
501 if hs: self.vf.fixHNames(hs, topCommand=0)
502
503
504 lps = filter(lambda x: x.element=='Xx' and \
505 (x.name[0]=='L' or x.name[1]=='L'),mol.allAtoms)
506 if len(lps):
507 renumber = 1
508 if self.vf.hasGui:
509 self.vf.mergeLPSGC(mol)
510
511 else:
512 self.vf.mergeLPS(mol)
513 msg = msg + ' -merged ' + str(len(lps)) + ' lone pairs\n'
514
515 if renumber:
516 atSet = mol.allAtoms
517 atSet.sort()
518 fst = atSet[0].number
519 atSet.number = range(fst, len(atSet)+fst)
520
521
522
523
524
525
526 solParAts = mol.allAtoms.get(lambda x: hasattr(x, 'AtSolPar'))
527 if not solParAts:
528 needToAddSolPar = 1
529 elif len(solParAts)!=len(mol.allAtoms):
530 needToAddSolPar = 1
531 if needToAddSolPar:
532
533 self.vf.ADgpf_addSolvationParameters(mol, outfile=-1, log=0)
534 msg = msg + ' -added solvation parameters\n'
535
536 errCharge, resList = checkMolCharges(mol, self.vf)
537 mol.checked_charges = 1
538 else:
539 msg = msg + ' -pdbqs file so skip nphs, lps, adding solpar steps\n'
540
541
542 histVal = self.editHISprotonation
543 newHs = AtomSet([])
544 if histVal!='No change':
545 hisRES = mol.chains.residues.get(lambda x: x.type=='HIS')
546 if hisRES:
547 d = {}
548 for res in hisRES:
549 d[res.full_name()] = histVal
550 newHs = self.vf.editHist_h(d)
551 if len(newHs):
552
553 for h in newHs:
554 h.AtVol = 0.0
555 h.AtSolPar = 0.0
556 if self.vf.hasGui:
557 event = AddAtomsEvent(objects=newHs)
558 self.vf.dispatchEvent(event)
559
560
561
562 msg = msg + ' -edited histidine protonation to userpref:' + histVal + '\n'
563 title = mol.name + " Summary"
564 self.vf.warningMsg(msg, title=title)
565
566 update = self.vf.ADgpf_checkMacroTypes(mol, topCommand=0)
567 if update or needToAddSolPar or needToAddCharges or nphs is not None or \
568 lps is not None or len(newHs):
569 filename = kw['filename']
570 if filename is None:
571 filename = self.vf.askFileSave(types=[('PDBQS files', '*.pdbqs')],
572 title = 'Modified AutoDock Macromolecule File:')
573
574 if not filename:
575 msg="AutoGrid requires written pdbqs molecule!"
576 self.vf.warningMsg(msg)
577 else:
578
579 self.vf.writePDBQS( mol, filename=filename,
580 pdbRec=['ATOM','HETATM'],
581 bondOrigin=[])
582
583 elif filename=='auto':
584 fname = os.path.splitext(os.path.basename(mol.parser.filename))[0]
585 filename = fname + '.pdbqs'
586 self.vf.writePDBQS( mol, filename=filename,
587 pdbRec=['ATOM','HETATM'],
588 bondOrigin=[])
589
590 else:
591 self.vf.writePDBQS( mol, filename=filename,
592 pdbRec=['ATOM','HETATM'],
593 bondOrigin=[])
594
595 else:
596 filename = mol.parser.filename
597
598 mol.gpf_init = 1
599 mol.outputfilename = filename
600 if filename is not None:
601 self.vf.gpo.set_receptor(filename)
602 self.vf.gpo.receptor = mol
603 mol.outputfilename = os.path.basename(filename)
604 if not hasattr(mol, 'center'):
605 mol.getCenter()
606
607 if self.vf.hasGui:
608 self.vf.colorByAtomType(mol, ['lines'], topCommand=0, redraw=1)
609
610
611
612
613
614
615
617 """detect types of atoms in receptor;
618 for non-standard types (limited to 2:'X' and 'M'):
619 define new energy parameters:
620 Rij and epsij
621 write file substituting X or M for non-standard element """
622
623
625 if self.vf.hasGui and not hasattr(self.vf, 'writePDBQS'):
626 self.vf.loadCommand('fileCommands', 'writePDBQS', 'Pmv')
627 checkHasGpo(self.vf)
628
629
630 - def __call__(self, mol, newfilename=None, **kw):
631 """len(newtypes)<-mv.ADgpf_checkMacroTypes(mol, newfilename=None)
632 mol: macromolecule to check
633 newfilename:optional argument, outputfile needed if a new type is renamed M or X
634 len(newtypes):number of atom types which had to be changed: to M or X
635 """
636 mols = self.vf.expandNodes(mol)
637 if not mols:
638 return 'ERROR'
639 kw['newfilename'] = newfilename
640 return apply(self.doitWrapper, (mols[0],), kw)
641
642
643 - def doit(self, mol, **kw):
644 newfilename = kw['newfilename']
645 typeList = ['C','N','O','S','H']
646 newAts = ['M','X']
647 newNum = 2
648 num = 0
649
650
651
652 has_ad_element = filter(lambda x: hasattr(x, 'autodock_element'), \
653 mol.allAtoms)
654 if len(has_ad_element)!=len(mol.allAtoms):
655 setAutoDockElements(mol)
656
657
658
659
660 typeD = {}
661 for a in mol.allAtoms:
662 typeD[a.autodock_element[0]] = 0
663 autodockTypes = typeD.keys()
664
665
666
667 updateList = []
668 for ty in autodockTypes:
669 if ty[0] not in typeList:
670 if ty in newAts:
671
672 msg= 'adding ', ty,' to macromolecule types'
673 title = "NEW TYPE "+ ty + " for MACROMOLECULE"
674 self.vf.warningMsg(msg, title=title)
675 typeList.append(ty)
676 newNum = newNum -1
677 newAts.remove(ty)
678 elif num < newNum:
679 if self.vf.hasGui:
680 msg = mol.name + " has unusual atom type:" + ty + "\nDo you want to add this type which means changing " + ty+ " to " + newAts[num] + " and defining new energy parameters?\n(Currently you can define "+str(2-num)+ " types)"
681 d=SimpleDialog(self.vf.GUI.ROOT, text=msg, buttons=['Yes','No'], default=0, title='Define new type?')
682 ok=d.go()
683 if ok==0:
684 updateList.append((ty, newAts[num]))
685
686 typeList.append(newAts[num])
687 num=num+1
688 else:
689 msg = 'no energyConstants entries for '+ ty
690 self.vf.warningMsg(msg)
691 continue
692 else:
693 msg= "Too many new types!: " + ty + " will be mapped to 'C' or first map type)"
694 self.vf.warningMsg(msg)
695
696
697 if len(updateList):
698 self.updateTypes(mol, updateList)
699 delta = 7 - len(typeList)
700 for i in range(delta):
701 typeList.append('H')
702 mol.mset = join(typeList, '')
703
704 if 'X' in mol.mset:
705 if 'M' in mol.mset:
706 mol.mset = 'CNOSHXM'
707 else:
708 mol.mset = 'CNOSHXH'
709 elif 'M' in mol.mset:
710 mol.mset = 'CNOSHHM'
711 else:
712 mol.mset = 'CNOSHHH'
713 self.vf.gpo['mset']['value'] = mol.mset
714
715
716 return len(updateList)
717
718
719 - def updateTypes(self, mol, updateList, newfilename=None):
720
721 for entry in updateList:
722 self.DoNewType(mol, entry[0], entry[1])
723
724
725 return 1
726
727
728 - def DoNewType(self, mol, elemType, newType):
729
730 defineCommand = self.vf.ADgpf_defineAtomParameters
731 defineCommand.elem.set(newType)
732 if hasattr(Rij,newType):
733 defineCommand.Rij.set(Rij[newType])
734 if hasattr(epsij,newType):
735 defineCommand.epsij.set(epsij[newType])
736 defineCommand.guiCallback()
737
738 for at in mol.allAtoms:
739 if at.autodock_element==elemType:
740 at.autodock_element = newType
741
742 if len(at.name)>1:
743 at.name = newType + at.name[1:]
744 else:
745 at.name = newType
746
747
749 mols = self.vf.getSelection()
750 if len(mols):
751 mols = mols.top.uniq()
752 mol = mols[0]
753 kw = {}
754 kw['newfilename'] = None
755 return apply(self.doitWrapper, (mol,), kw)
756
757
758
759 autodockElementDict = {}
760 autodockElementDict['l'] = 'Xx'
761
762
763 autodockElementDict['f'] = 'Fe'
764 autodockElementDict['c'] = 'Cl'
765 autodockElementDict['b'] = 'Br'
766
767
768
770 for item in mol.allAtoms:
771 try:
772 item.autodock_element
773 except AttributeError:
774
775 if item.name=='ZN' or item.name=='Zn':
776 item.autodock_element='Zn'
777 elif len(item.element)>2:
778 item.autodock_element=item.element
779 elif item.element[0] == 'Z':
780
781 item.autodock_element = 'Z'
782 if len(item.element)>1:
783 item.element = item.element[1]
784 else:
785 item.element = 'C'
786 elif item.element not in autodockElementDict.keys():
787 item.autodock_element=item.element
788 else:
789 item.autodock_element = autodockElementDict[item.element]
790
791
792
804
805
806
808 ftype= split(filename,'.')[-1]
809 if ftype== 'pdbqs':
810 return None, None, None, None, None
811 typeCharges = None
812 addSolPar = None
813 mergeNPHS = None
814 mergeLPS = None
815 ifd = InputFormDescr(title = 'Options')
816 mergenphs = Tkinter.IntVar()
817 mergenphs.set(0)
818 mergelps = Tkinter.IntVar()
819 mergelps.set(0)
820 chargeType = Tkinter.IntVar()
821 chargeType.set(3)
822 addSol = Tkinter.IntVar()
823 addSol.set(3)
824 newname = Tkinter.StringVar()
825
826
827 nameParts = os.path.splitext(os.path.basename(filename))
828 newname.set(nameParts[0]+'.pdbqs')
829 if ftype != 'pdbqs':
830 mergenphs.set(1)
831 mergelps.set(1)
832 if ftype != 'pdbq':
833 chargeType.set(0)
834 ifd.append({'name': 'typeChargeLab',
835 'widgetType':Tkinter.Label,
836 'text':'charge type to use:',
837 'gridcfg':{'sticky':Tkinter.W}}),
838 ifd.append({'name': 'gastCharg',
839 'widgetType':Tkinter.Radiobutton,
840 'text':'gasteiger',
841 'variable':chargeType,
842 'value':1,
843 'gridcfg':{'sticky':Tkinter.W,
844 'row':-1,'column':1}}),
845 ifd.append({'name': 'kollCharg',
846 'widgetType':Tkinter.Radiobutton,
847 'text':'Kollman united atom ',
848 'variable':chargeType,
849 'value':0,
850 'gridcfg':{'sticky':Tkinter.W,'row':-1,'column':2}}),
851 if ftype == 'mol2' or ftype == 'pdbq':
852 ifd.append({'name': 'keepCharg',
853 'widgetType':Tkinter.Radiobutton,
854 'text':'keep original charges',
855 'variable':chargeType,
856 'value':3,
857 'gridcfg':{'sticky':Tkinter.W,'column':1}}),
858 addSol.set(1)
859 ifd.append({'name': 'addSolLab',
860 'widgetType':Tkinter.Label,
861 'text':'add solvation parameters?',
862 'gridcfg':{'sticky':Tkinter.W}}),
863 ifd.append({'name': 'yesAddSol',
864 'widgetType':Tkinter.Radiobutton,
865 'wcfg':{'text':'yes',
866 'variable':addSol,
867 'value':1},
868 'gridcfg':{'sticky':Tkinter.W,'row':-1,'column':1}}),
869 ifd.append({'name': 'noAddSol',
870 'widgetType':Tkinter.Radiobutton,
871 'wcfg':{'text':'no',
872 'variable':addSol,
873 'value':0},
874 'gridcfg':{'sticky':Tkinter.W,'row':-1,'column':2}}),
875 ifd.append({'name': 'mergeNPHSLab',
876 'widgetType':Tkinter.Label,
877 'text':'automatically merge non-polar Hs?',
878 'gridcfg':{'sticky':Tkinter.W}}),
879 ifd.append({'name': 'yesMergeNPHs',
880 'widgetType':Tkinter.Radiobutton,
881 'wcfg':{'text':'yes',
882 'variable':mergenphs,
883 'value':1},
884 'gridcfg':{'sticky':Tkinter.W,'row':-1,'column':1}}),
885 ifd.append({'name': 'noMergeNPHs',
886 'widgetType':Tkinter.Radiobutton,
887 'wcfg':{'text':'no',
888 'variable':mergenphs,
889 'value':0},
890 'gridcfg':{'sticky':Tkinter.W,'row':-1,'column':2}}),
891 ifd.append({'name': 'mergeLPSLab',
892 'widgetType':Tkinter.Label,
893 'text':'automatically merge lone pairs?',
894 'gridcfg':{'sticky':Tkinter.W}}),
895 ifd.append({'name': 'yesMergeLPS',
896 'widgetType':Tkinter.Radiobutton,
897 'wcfg':{'text':'yes',
898 'variable':mergelps,
899 'value':1},
900 'gridcfg':{'sticky':Tkinter.W,'row':-1,'column':1}}),
901 ifd.append({'name': 'noMergeLPS',
902 'widgetType':Tkinter.Radiobutton,
903 'wcfg':{'text':'no',
904 'variable':mergelps,
905 'value':0},
906 'gridcfg':{'sticky':Tkinter.W,'row':-1,'column':2}}),
907 ifd.append({'name': 'newfileEnt',
908 'widgetType':Tkinter.Entry,
909 'wcfg':{
910 'label':'save result as:',
911 'textvariable':newname},
912 'gridcfg':{'sticky':Tkinter.E,'columnspan':2}}),
913 vals = vf.getUserInput(ifd)
914
915 if vals:
916 typeCharges = chargeType.get()
917 addSolPar = addSol.get()
918 mergeLPS = mergelps.get()
919 mergeNPHS = mergenphs.get()
920 newfilename = vals['newfileEnt']
921 else:
922 return 0,0,0,0,0
923
924 if chargeType.get()==3:
925 typeCharges = None
926 if addSol.get()==3:
927 addSolPar = None
928
929 return typeCharges, addSolPar, mergeNPHS, mergeLPS, newfilename
930
931
932
934 """ allows user to select the receptor via a file browser"""
935
936
939
940
942 """called each time the 'read macromolecule' button is pressed"""
943 macroFile = self.vf.askFileOpen(types=[('PDBQS files', '*.pdbqs'),
944 ('PDBQ files','*.pdbq'),('PDB files','*.pdb'),('MOL2 files', '*.mol2'),('all files', '*.*')],
945 title = 'Macromolecule File:')
946
947
948 if macroFile:
949 kw = {}
950 apply(self.doitWrapper, (macroFile,), kw)
951
952
954 if not os.path.exists(macroFile):
955 raise IOError
956 apply(self.doitWrapper,(macroFile,),kw)
957
958
959 - def doit(self, macroFile, **kw):
960 mols = Read(macroFile)
961 if len(mols)>1:
962 self.vf.warningMsg(messages['multipleMols'])
963
964 mol = mols[0]
965 self.vf.addMolecule(mol)
966 if not mol.chains[0].hasBonds:
967 mol.buildBondsByDistance()
968 if self.vf.hasGui:
969 self.vf.centerScene(topCommand=0)
970 self.vf.displayLines(mol,topCommand=0,redraw=1)
971
972 kw['topCommand'] = 0
973 apply(self.vf.ADgpf_initMacro, (mol,), kw)
974
975
976 GpfMacroReaderGUI = CommandGUI()
977 GpfMacroReaderGUI.addMenuCommand('AutoToolsBar', menuText['AutoGpfMB'],\
978 menuText['ReadMacro'], cascadeName = menuText['MacromoleculeMB'],
979 separatorAbove=1)
980
981
982
984 """ allows user to choose a molecule already present for the receptor"""
985
986
989
990
991 - def __init__(self, mode='single', title = 'Choose Macromolecule'):
995
996
998 """called each time the 'choose Molecule' button is pressed"""
999 try:
1000 self.chooser.form.withdraw()
1001 except:
1002 pass
1003 mol = self.chooser.getMolSet()
1004 if mol:
1005 macroFile = os.path.basename(mol.parser.filename)
1006 kw = {}
1007 apply(self.doitWrapper, (mol,), kw)
1008
1009
1011 self.chooser = MoleculeChooser(self.vf, self.mode, self.title)
1012 self.chooser.ipf.append({'name':'Select Button',
1013 'widgetType':Tkinter.Button,
1014 'text':'Select Molecule',
1015 'wcfg':{'bd':6},
1016 'gridcfg':{'sticky':Tkinter.E+Tkinter.W},
1017 'command': self.chooseMolecule_cb})
1018 self.form = self.chooser.go(modal=0, blocking=0)
1019 lb = self.chooser.ipf.entryByName['Molecule']['widget'].lb
1020 lb.bind("<Double-Button-1>", self.chooseMolecule_cb)
1021
1022
1024 apply(self.doitWrapper,(nodes,),kw)
1025
1026
1027 - def doit(self, nodes, **kw):
1028 mols = self.vf.expandNodes(nodes)
1029 if not len(mols):
1030 return 'ERROR'
1031 kw['topCommand'] = 0
1032 apply(self.vf.ADgpf_initMacro, (mols[0],), kw)
1033
1034
1035 GpfMacroChooserGUI = CommandGUI()
1036 GpfMacroChooserGUI.addMenuCommand('AutoToolsBar', menuText['AutoGpfMB'], menuText['ChooseMacro'], cascadeName = menuText['MacromoleculeMB'])
1037
1038
1039
1040
1041
1043 """ allows user to add solvation parameters to a receptor """
1044
1045
1047 from AutoDockTools.sol_par import solvs
1048
1049 self.solvs = solvs
1050 if self.vf.hasGui:
1051 for item in ['readMolecule','writePDBQS']:
1052 if not hasattr(self.vf, item):
1053 self.vf.loadCommand('fileCommands', item, 'Pmv')
1054 checkHasGpo(self.vf)
1055
1056
1058 """called each time the 'Add Solvent Parameters' button is pressed"""
1059 t = 'Is Molecule already in the viewer?'
1060 d = SimpleDialog(self.vf.GUI.ROOT, text=t, buttons=['Yes','No'], default=0,title='Select Molecule')
1061 ok = d.go()
1062 if ok==0:
1063 self.chooser = MoleculeChooser(self.vf, 'single', 'Choose Macromolecule')
1064 self.chooser.ipf.append({'name':'Select Button',
1065 'widgetType':Tkinter.Button,
1066 'text':'Select Molecule',
1067 'wcfg':{'bd':6},
1068 'gridcfg':{'sticky':Tkinter.E+Tkinter.W},
1069 'command': self.chooseMolecule_cb})
1070 self.form = self.chooser.go(modal=0, blocking=0)
1071 lb = self.chooser.ipf.entryByName['Molecule']['widget'].lb
1072 lb.bind("<Double-Button-1>", self.chooseMolecule_cb)
1073 else:
1074 macroFile = self.vf.askFileOpen(types=[('PDBQ files', '*.pdbq'),
1075 ('PDB files','*.pdb'),('MOL2 files', '*.mol2'),
1076 ('PDBQS files', '*.pdbqs')], title = 'Macromolecule File:')
1077
1078 if not macroFile:
1079 return 'ERROR'
1080
1081 ftype = os.path.splitext(os.path.basename(macroFile))[-1]
1082
1083
1084 if ftype=='.pdbq' or ftype=='.mol2' or ftype=='.pdbqs'\
1085 or ftype=='.pdb':
1086 mols = self.vf.readMolecule(macroFile, topCommand=0)
1087
1088 if mols is None: return 'ERROR'
1089
1090 mol = mols[0]
1091 if not mol.chains[0].hasBonds:
1092 mol.buildBondsByDistance()
1093 self.vf.centerScene(topCommand=0)
1094 self.vf.displayLines(mol,topCommand=0)
1095 outfile = self.vf.askFileSave(types=[('PDBQS files', '*.pdbqs')],
1096 title = 'Modified Macromolecule File:')
1097 if not outfile:
1098 msg="AutoGrid requires written pdbqs molecule"
1099 self.vf.warningMsg(msg)
1100 return self.doitWrapper(mol, log=0, redraw=0, outfile=outfile)
1101
1102
1104 """called each time the 'choose Molecule' button is pressed"""
1105 mols = self.chooser.getMolSet()
1106 if mols is None: return
1107 if issubclass(mols.__class__, TreeNode):
1108 mols = mols.setClass([mols])
1109 mol = mols[0]
1110 try:
1111 self.chooser.form.withdraw()
1112 except:
1113 pass
1114 kw = {}
1115 kw['log'] = 0
1116 kw['redraw'] = 0
1117 outfile = self.vf.askFileSave(types=[('PDBQS files', '*.pdbqs')],
1118 title = 'Modified Macromolecule File:')
1119 if not outfile:
1120 msg="AutoGrid requires written pdbqs molecule"
1121 self.vf.warningMsg(msg)
1122 kw['outfile'] = outfile
1123 return apply(self.doitWrapper,(mol,), kw)
1124
1125
1126 - def __call__(self, mol, outfile=None , **kw):
1127 """newfileName <-ADgpf_addSolvationParameters(mol, outfile=None)
1128 mol is macromolecule
1129 outfile is new filename"""
1130 kw['outfile'] = outfile
1131 return apply(self.doitWrapper,(mol,),kw)
1132
1133
1134 - def doit(self, mol, **kw):
1135 outfile = kw['outfile']
1136 mols = self.vf.expandNodes(mol)
1137 if not mols: return 'ERROR'
1138 else: mol = mols[0]
1139
1140 chargeAts = mol.allAtoms.get(lambda x: hasattr(x, 'charge'))
1141 if not chargeAts or len(chargeAts)!=len(mol.allAtoms):
1142 t = "for addsol: macromolecule must have charges\ncalling Add Kollman Charges"
1143 self.vf.warningMsg(t)
1144 self.vf.addKollmanCharges(mol, topCommand=0, log=0)
1145
1146
1147 zeroChargeAts = mol.allAtoms.get(lambda x: hasattr(x, 'charge') and x.charge==0)
1148 if zeroChargeAts and len(zeroChargeAts)==len(mol.allAtoms):
1149 t = "all atoms have zero charge"
1150 self.vf.warningMsg(t)
1151
1152 bblist=['C','O','N','CA']
1153 nuc_acid_list = [' A',' C',' G']
1154
1155 atSet = mol.allAtoms
1156 solvsKeys = self.solvs.keys()
1157 for at in atSet:
1158 if at.name in bblist:
1159 atKey = at.name + '---'
1160 elif (at.name=='C2*' or at.name=='C2\'') \
1161 and at.parent.type in nuc_acid_list:
1162 childnames = at.parent.atoms.name
1163 if 'O2*' in childnames or 'O2\'' in childnames:
1164
1165 atKey = at.name + ' R' + at.parent.type[2]
1166 print 'special rna key', atKey
1167 else:
1168 atKey = at.name + at.parent.type
1169 else:
1170 atKey = at.name + at.parent.type
1171
1172
1173
1174 if atKey in solvsKeys:
1175
1176 at.AtVol, at.AtSolPar = self.solvs[atKey]
1177
1178 else:
1179
1180 at.AtVol, at.AtSolPar = (0.00, 0.00)
1181
1182
1183
1184 if outfile is None or outfile is -1 or outfile == ():
1185 return -1
1186
1187
1188 atSet.sort()
1189 fst = atSet[0].number
1190 atSet.number = range(fst, len(atSet)+fst)
1191
1192
1193
1194 self.vf.writePDBQS( mol, filename=outfile,
1195 pdbRec=['ATOM','HETATM'],
1196 bondOrigin=[],
1197 topCommand=0)
1198 outfile = os.path.basename(outfile)
1199 self.vf.gpo.set_receptor(outfile)
1200 self.vf.gpo.receptor = mol
1201 return outfile
1202
1203
1204 GpfAddSolGUI= CommandGUI()
1205 GpfAddSolGUI.addMenuCommand('AutoToolsBar', menuText['AutoGpfMB'], menuText['AddSol'], cascadeName = menuText['MacromoleculeMB'])
1206
1207
1208
1210 """initializes the ligand:
1211 checkCharges
1212 getTypes
1213 getSideLengths
1214 setAutoDockElements
1215 colorByAtom + color aromatic C's green
1216
1217 GUI allows user to:
1218 decide which types of hydrogen bonds to model
1219 modify list of atom types detected in ligand
1220
1221 """
1222
1223
1225 checkHasGpo(self.vf)
1226 if self.vf.hasGui:
1227 self.gtypes = Tkinter.StringVar()
1228 self.gtypes.set('')
1229 self.showLig = Tkinter.IntVar()
1230 self.showLig.set(0)
1231 self.NHBonds = Tkinter.IntVar()
1232 self.OHBonds = Tkinter.IntVar()
1233 self.SHBonds = Tkinter.IntVar()
1234 self.vf.loadModule('colorCommands','Pmv')
1235
1236
1238 apply(self.doitWrapper,(mol,),kw)
1239
1240
1241 - def doit(self, mol):
1242 lig = self.vf.expandNodes(mol)[0]
1243 errCharge, resList = checkMolCharges(lig, self.vf)
1244 if hasattr(lig, 'outputfile'):
1245 filename = lig.outputfile
1246 else:
1247 filename = os.path.basename(lig.parser.filename)
1248 self.vf.gpo.set_ligand(filename)
1249 self.vf.gpo.ligand = lig
1250 spacing = self.vf.gpo['spacing']['value']
1251 getSideLengths(lig, spacing)
1252
1253
1254
1255 lig.center = (round(lig.center[0],3), round(lig.center[1],3), round(lig.center[2],3))
1256
1257 self.getTypes(lig)
1258 setAutoDockElements(lig)
1259
1260 changeVals = {}
1261 typs = lig.types
1262 if self.vf.gpo['types']['value'] != typs:
1263 changeVals['types'] = typs
1264
1265 if self.vf.hasGui:
1266 self.vf.displayLines(lig, topCommand=0)
1267 self.vf.colorByAtomType(lig,['lines'], topCommand=0)
1268
1269
1270 aromCs = AtomSet(filter(lambda x:x.autodock_element=='A',\
1271 lig.allAtoms))
1272 if len(aromCs):
1273 self.vf.color(aromCs,((0.,1.,0.,),),['lines'],\
1274 topCommand=0, redraw=1)
1275 if not hasattr(self, 'form'):
1276 self.buildForm()
1277 self.form = self.vf.getUserInput(self.ifd, modal=0, blocking=0)
1278 self.form.root.protocol('WM_DELETE_WINDOW',self.Close_cb)
1279 else:
1280 self.form.deiconify()
1281 self.showLig.set(1)
1282 self.showLigand(lig)
1283 NHB = 'N' in typs
1284 OHB = 'O' in typs
1285 SHB = 'S' in typs
1286 if 'H' in typs:
1287
1288
1289 NHB = 1
1290 self.NHBonds.set(1)
1291 OHB = 1
1292 self.OHBonds.set(1)
1293 SHB = 1
1294 self.SHBonds.set(1)
1295 else:
1296
1297 self.NHBonds.set(NHB)
1298
1299 self.OHBonds.set(OHB)
1300
1301 self.SHBonds.set(SHB)
1302 for item in ['NHB','OHB','SHB']:
1303 if eval(item) != self.vf.gpo[item]['value']:
1304 changeVals[item] = eval(item)
1305 else:
1306
1307 if 'H' not in typs:
1308 for item in ['NHB','OHB','SHB']:
1309 if self.vf.gpo[item]['value']:
1310 changeVals[item]['value'] = 0
1311 if len(changeVals.items()):
1312 apply(self.vf.ADgpf_setGpo, (), changeVals)
1313
1314
1361
1362
1364 self.form.withdraw()
1365
1366
1368 changeVals = {}
1369 gt = self.gtypes.get()
1370 if gt != self.vf.gpo['types']['value']:
1371 changeVals['types'] = gt
1372 nhb = self.NHBonds.get()
1373 if nhb != self.vf.gpo['NHB']['value']:
1374 changeVals['NHB'] = nhb
1375 ohb = self.OHBonds.get()
1376 if ohb != self.vf.gpo['OHB']['value']:
1377 changeVals['OHB'] = ohb
1378 shb = self.SHBonds.get()
1379 if shb != self.vf.gpo['SHB']['value']:
1380 changeVals['SHB'] = shb
1381 if len(changeVals.items()):
1382 changeVals['topCommand'] = 0
1383 apply(self.vf.ADgpf_setGpo, (), changeVals)
1384 self.form.withdraw()
1385
1386
1388 if self.showLig.get():
1389 self.vf.displayLines(ligand, topCommand=0, redraw=1)
1390 else:
1391 self.vf.displayLines(ligand, negate=1, topCommand=0, redraw=1)
1392
1393
1395 """ligand.types<-getTypes(ligand)"""
1396 ligstring = ''
1397 dict = {}
1398 for at in ligand.allAtoms:
1399 dict[at.autodock_element] = 0
1400
1401 dictKeyList = dict.keys()
1402 for k in dictKeyList:
1403 if k not in ['C','A','N','O','S','P','H','n','f','F','c','b','I','M']:
1404 if self.vf.hasGui:
1405 self.vf.ADgpf_defineAtomParameters.elem.set(at.autodock_element)
1406 self.vf.ADgpf_defineAtomParameters.guiCallback()
1407 sortedList = []
1408 for kk in ['C','A','N','O','S','P','H','n','f','F','c','b','I','M']:
1409 if kk in dictKeyList:
1410 sortedList.append(kk)
1411 for k in dictKeyList:
1412 if k not in sortedList:
1413 print 'unknown autodock_type ', k
1414 sortedList.append(k)
1415 sortedstring = join(sortedList,'')
1416 ligand.types = sortedstring
1417 if self.vf.hasGui:
1418 self.gtypes.set(sortedstring)
1419 self.updateTypes()
1420 return ligand.types
1421
1422
1424 if not hasattr(self, 'ifd'):
1425 return
1426 ll= ['N','S','O']
1427 ligstring = self.gtypes.get()
1428 for item in ll:
1429 w=eval("self.ifd.entryByName['%s-HBonds']"%item)
1430 if item in ligstring:
1431 w['widget'].config(state='normal')
1432 else:
1433 w['widget'].config(state='disabled')
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1449 """ allows user to choose a molecule already present for the ligand"""
1450
1451
1454
1455
1456 - def __init__(self, mode='single', title = 'Choose Ligand'):
1460
1461
1463 """called each time the 'choose Ligand' button is pressed"""
1464 mol = self.chooser.getMolSet()
1465 if mol:
1466 try:
1467 self.chooser.form.withdraw()
1468 except:
1469 pass
1470 dict = self.vf.atorsDict
1471
1472
1473
1474 ok = 0
1475 if hasattr(mol, 'torTree'):
1476 ok = 1
1477 elif dict.has_key('molecule') and mol==dict['molecule']:
1478 ok = hasattr(mol, 'outputfile')
1479 if not ok:
1480 self.vf.warningMsg('can only select molecule with written autotors output file')
1481 return 'ERROR'
1482 self.doitWrapper(