Package AutoDockTools :: Module autogpfCommands
[hide private]
[frames] | no frames]

Source Code for Module AutoDockTools.autogpfCommands

   1  ############################################################################# 
   2  # 
   3  # Author: Ruth HUEY, Michel F. SANNER 
   4  # 
   5  # Copyright: M. Sanner TSRI 2000 
   6  # 
   7  ############################################################################# 
   8   
   9   
  10  # $Header: /opt/cvs/python/packages/share1.5/AutoDockTools/autogpfCommands.py,v 1.99.2.1 2007/08/17 17:53:38 sargis Exp $ 
  11  # 
  12  # $Id: autogpfCommands.py,v 1.99.2.1 2007/08/17 17:53:38 sargis Exp $ 
  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  #from ViewerFramework.VF import ModificationEvent 
 112  ##  from ViewerFramework.gui import InputFormDescr 
 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  #from AutoDockTools.Objects.energyConstants import Rij, epsij, SolVol, SolPar, SolCon 
 130  from autotorsCommands import checkMolCharges 
 131  from autotorsCommands import  set_autoMergeNPHS 
 132  from GridParameters import GridParameters, \ 
 133                  grid_parameter_list, grid_parameter_list4 
 134  #from AutoDockTools.Objects.GridParameters import GridParameters, grid_parameter_list 
 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  #create a global geometry for this module 
 145   
146 -def check_autogpf_geoms(VFGUI):
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 #from DejaVu.extendedSlider import ExtendedSlider 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 #new style RGB-> 180 materials=((0,0,1),(0,1,0),(0,0,1),(0,1,0),(1,0,0),(1,0,0),) 181 #box=Box('box', materials=materials, vertices=coords, faces=face, 182 # inheritMaterial=0) 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 #box.oldFPM = GL.GL_LINE 196 197 #these are the texts on menubuttons, menu entries etc: 198 menuText = {} 199 #menuText['AutoGpfMB'] = ' Set Grid Parameters ' 200 menuText['AutoGpfMB'] = 'Grid' 201 202 menuText['ReadGpfMB'] = 'Open GPF...' #CLARIFY THIS 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' #obsolete entry 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 #Set Grid text strings 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 #set warningMsg texts: 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
278 -def checkHasGpo(vf):
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
296 -class GpfSetGpo(MVCommand):
297 """ Command to set values in gpo object using gui input results""" 298 299
300 - def onAddCmdToViewer(self):
301 checkHasGpo(self.vf)
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
314 -class GpfLoadDefaults(MVCommand):
315 """ allows user to select a file containing a set of defaults""" 316 317
318 - def onAddCmdToViewer(self):
319 checkHasGpo(self.vf)
320 321
322 - def __call__(self, gpffile, **kw):
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
333 - def guiCallback(self):
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 #if gpfFile is not None: 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
347 -class GpfMacroInit(MVCommand):
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
366 - def onRemoveObjectFromViewer(self, obj):
367 if hasattr(self.vf.gpo, 'receptor') and obj==self.vf.gpo.receptor: 368 self.vf.gpo.receptor = None
369 370
371 - def onAddCmdToViewer(self):
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 #if not hasattr(self.vf,'add_h'): 378 #self.vf.loadModule('editCommands','Pmv') 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
399 - def set_editHISprotonation(self, name, oldval, newval):
400 self.editHISprotonation = newval 401 try: 402 self.vf.ADgpf4_initMacro.editHISprotonation = newval 403 except: 404 pass
405 406
407 - def checkIsPeptide(self, resSet):
408 #check whether each restype is in std list 409 #if so, mol is a peptide 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 #only get to this point if all 417 #residue types were found 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 #kw should be mol and possibly filename 427 kw['filename'] = filename 428 apply(self.doitWrapper,(mols[0],), kw)
429 430
431 - def doit(self, mol, **kw):
432 #what is its already processed: eg from pdbqs file??? 433 #user might want to do this twice 434 #if hasattr(mol, 'gpf_init'): 435 # print mol.name, ' already initialized' 436 # return 437 msg = 'initializing ' + os.path.basename(mol.parser.filename) + ':\n' 438 #make sure all atoms have autodock_element 439 for at in mol.allAtoms: 440 #FIX THIS: what about Zn 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 #in this case check charges and solvation parameters 450 #CHARGES: decide if its a peptide 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 #this checks that each atom doesn't have charge=0 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 #CHECK FOR NPHS and LPS and merge if found 473 #redisplay = 0 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 #nphs = mol.allAtoms.get(lambda x: x.element=='H' and \ 479 # (x.bonds[0].atom1.element=='C' or x.bonds[0].atom2.element=='C')) 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 #userpref determines whether to automatically merge detected nphs 490 #default is to always merge 491 renumber = 1 492 if self.vf.hasGui: 493 self.vf.mergeNPHSGC(mol, logBaseCmd=0) 494 #redisplay = 1 495 else: 496 self.vf.mergeNPHS(mol) 497 msg = msg + ' -merged nphs\n' 498 499 #SHOULD THIS BE OPTIONAL??? 500 hs = self.vf.allAtoms.get(lambda x: x.element=='H') 501 if hs: self.vf.fixHNames(hs, topCommand=0) 502 503 #always merge lone pairs 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 #redisplay = 1 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 #FIX THIS: CHECK THAT DISPLAY GETS UPDATED 521 #if self.vf.hasGui and redisplay: 522 # self.vf.displayLines(mol, negate=1, topCommand=0, log=0) 523 # self.vf.displayLines(mol, topCommand=0, log=0) 524 525 #add solvation parameters, also 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 #outfile=-1 parameter keeps from writing pdbqs in AddSol 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 # set the protonation state of all the histidines to userpref 541 # unless the preference is None 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 #fix the solvation parameters here 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 #modEvent = ModificationEvent('add', 'coords', newHs) 560 #mol.geomContainer.updateGeoms(modEvent) 561 #self.vf.GUI.VIEWER.Redraw() 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 #if filename is None: 574 if not filename: 575 msg="AutoGrid requires written pdbqs molecule!" 576 self.vf.warningMsg(msg) 577 else: 578 #self.vf.writePDBQS(filename, mol, recType='none') 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 #self.vf.writePDBQS(filename, mol, recType='none') 590 else: 591 self.vf.writePDBQS( mol, filename=filename, 592 pdbRec=['ATOM','HETATM'], 593 bondOrigin=[]) 594 #self.vf.writePDBQS(filename, mol, recType='none') 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 #self.vf.GUI.receptorLabelLabel.config(text='AD3 Receptor:') 610 #self.vf.GUI.receptorLabel.config(text=filename, width=len(filename)) 611 612 #self.vf.warningMsg(msg) 613 614 615
616 -class CheckMacroAtomTypes(MVCommand):
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
624 - def onAddCmdToViewer(self):
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 #make sure every atom has autodock_element field 651 #IS THIS REDUNDANT... ie was it already done before this is called 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 #setAutoDockElements(mol) 658 659 # build a list of uniq autodock_elements in mol.allAtoms 660 typeD = {} 661 for a in mol.allAtoms: 662 typeD[a.autodock_element[0]] = 0 663 autodockTypes = typeD.keys() 664 #NB: made autodockTypes 1 character only 665 #THIS IS PROBABLY WRONG...what about Zn, Mg.... 666 667 updateList = [] 668 for ty in autodockTypes: 669 if ty[0] not in typeList: 670 if ty in newAts: 671 # X or M get added here 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 #= self.DoNewType(mol, ty, newAts[num], newfilename) 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 #at this point if there are any entries in updateList: 696 #do the update (once) 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 #be sure that X preceeds M 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 #return 0 if nothing has been changed 715 #else return 1 to signify need to write new file 716 return len(updateList)
717 718
719 - def updateTypes(self, mol, updateList, newfilename=None):
720 #eg entry in updateList: ('P','M') 721 for entry in updateList: 722 self.DoNewType(mol, entry[0], entry[1]) 723 #FIX THIS: should be able to write pdbqs if have all info; 724 #else pdbq if have charges else pdb 725 return 1
726 727
728 - def DoNewType(self, mol, elemType, newType):
729 #call vf.ADgpf_defineAtomParameters; edit file; save newfile 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 ##at.element = newType 742 if len(at.name)>1: 743 at.name = newType + at.name[1:] 744 else: 745 at.name = newType
746 747
748 - def guiCallback(self):
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 #FIX THIS: it needs updating 759 autodockElementDict = {} 760 autodockElementDict['l'] = 'Xx' 761 #autodockElementDict['A'] = 'C' 762 #autodockElementDict['n'] = 'N' 763 autodockElementDict['f'] = 'Fe' 764 autodockElementDict['c'] = 'Cl' 765 autodockElementDict['b'] = 'Br' 766 767 768 #FIX THIS: it needs updating
769 -def setAutoDockElements(mol):
770 for item in mol.allAtoms: 771 try: 772 item.autodock_element 773 except AttributeError: 774 #check if element is in special list 775 if item.name=='ZN' or item.name=='Zn': 776 item.autodock_element='Zn' 777 elif len(item.element)>2: #Cu,Ca, 778 item.autodock_element=item.element 779 elif item.element[0] == 'Z': 780 #this is for covalentmaps' attached atom 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
793 -def getSideLengths(mol, spacing):
794 c = mol.allAtoms.coords 795 maxo = Numeric.maximum.reduce(c) 796 mino = Numeric.minimum.reduce(c) 797 sideLengths = maxo-mino 798 mol.npts = sideLengths/(spacing*1.0) 799 #FIX THIS: 800 #should use center: 801 #mino+(maxo-mino)/2.0 802 #getCenter sets center to averaged coords 803 mol.center = mino + (maxo - mino)/2.0
804 805 806
807 -def checkFile(vf, filename):
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 #newname.set(os.path.basename(filename[:rfind(filename,'.')]+'.pdbqs')) 826 # eg ('1crn', 'pdbqs')[0]+'.pdbqs' 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
933 -class GpfMacroReader(MVCommand):
934 """ allows user to select the receptor via a file browser""" 935 936
937 - def onAddCmdToViewer(self):
938 checkHasGpo(self.vf)
939 940
941 - def guiCallback(self):
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 #allow user to set typeCharges and addSolPar here 947 #if macroFile is not None: 948 if macroFile: 949 kw = {} 950 apply(self.doitWrapper, (macroFile,), kw)
951 952
953 - def __call__(self, macroFile, **kw):
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
983 -class GpfMacroChooser(MVCommand):
984 """ allows user to choose a molecule already present for the receptor""" 985 986
987 - def onAddCmdToViewer(self):
988 checkHasGpo(self.vf)
989 990
991 - def __init__(self, mode='single', title = 'Choose Macromolecule'):
992 MVCommand.__init__(self) 993 self.mode = mode 994 self.title = title
995 996
997 - def chooseMolecule_cb(self, event = None):
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
1010 - def guiCallback(self):
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
1023 - def __call__(self, nodes, **kw):
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
1042 -class GpfAddSol(MVCommand):
1043 """ allows user to add solvation parameters to a receptor """ 1044 1045
1046 - def onAddCmdToViewer(self):
1047 from AutoDockTools.sol_par import solvs 1048 #from AutoDockTools.Objects.sol_par import * 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
1057 - def guiCallback(self):
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 #if macroFile is None: 1078 if not macroFile: 1079 return 'ERROR' 1080 1081 ftype = os.path.splitext(os.path.basename(macroFile))[-1] 1082 #FIX THIS could it be a pdbqs file ? 1083 #why would you add solvation parameters to a pdbqs file type? 1084 if ftype=='.pdbq' or ftype=='.mol2' or ftype=='.pdbqs'\ 1085 or ftype=='.pdb': 1086 mols = self.vf.readMolecule(macroFile, topCommand=0) 1087 #readMolecule returns None if it has a problem 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
1103 - def chooseMolecule_cb(self, event = None):
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 #check for zeroCharges 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 #build special 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 #try this: 1172 #5/15: these were backwards: 1173 #at.AtSolPar, atAtVol = self.solvs.get(atKey,(0.00,0.00)) 1174 if atKey in solvsKeys: 1175 #FIXED 5/15: 1176 at.AtVol, at.AtSolPar = self.solvs[atKey] 1177 #at.AtSolPar,at.AtVol=self.solvs[atKey] 1178 else: 1179 #FIXED 5/15: 1180 at.AtVol, at.AtSolPar = (0.00, 0.00) 1181 #at.AtSolPar,at.AtVol=(0.00,0.00) 1182 1183 #if not going to write to outfile, return here 1184 if outfile is None or outfile is -1 or outfile == (): 1185 return -1 1186 1187 #Renumber HERE!??! 1188 atSet.sort() 1189 fst = atSet[0].number 1190 atSet.number = range(fst, len(atSet)+fst) 1191 1192 #don't want to write any CONECT records 1193 #self.vf.writePDBQS(outfile, atSet, recType='none', topCommand=0) 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
1209 -class GpfInitLigand(MVCommand):
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
1224 - def onAddCmdToViewer(self):
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
1237 - def __call__(self, mol, **kw):
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 #now getSideLengths also sets center 1253 #lig.getCenter() 1254 #this is bounding box center, not average center 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 #self.vf.GUI.ligandLabelLabel.config(text='AD3 Ligand:') 1269 #self.vf.GUI.ligandLabel.config(text=filename, width=len(filename)) 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 #override NHB,OHB and SHB because 1288 # N,O or S could be in receptor 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 #N could hbond to H in receptor 1297 self.NHBonds.set(NHB) 1298 #O could hbond to H in receptor 1299 self.OHBonds.set(OHB) 1300 #S could hbond to H in receptor 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 #otherwise have to set NHB,OHB and SHB by hand (?) 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
1315 - def buildForm(self):
1316 lig = self.vf.gpo.ligand 1317 ifd = self.ifd = InputFormDescr(title = "AutoGpf Ligand") 1318 ifd.append( {'widgetType':Tkinter.Entry, 1319 'wcfg': { 1320 'label': 'Ligand Atom Types:', 1321 'textvariable': self.gtypes, 1322 'command':self.updateTypes, 1323 'eventType':'<Key>' 1324 }, 1325 'gridcfg':{'sticky':Tkinter.W,'columnspan':2}}) 1326 ifd.append({'name': 'Show Ligand', 1327 'widgetType':Tkinter.Checkbutton, 1328 'text': 'Show Ligand', 1329 'variable': self.showLig, 1330 'gridcfg':{'sticky':Tkinter.W}, 1331 'command': CallBackFunction(self.showLigand, lig)}) 1332 ifd.append({'name': 'HBondsLabel', 1333 'widgetType':Tkinter.Label, 1334 'text': 'Model Hydrogen Bonding', 1335 'gridcfg':{'sticky':Tkinter.W}}) 1336 ifd.append({'name': 'N-HBonds', 1337 'widgetType':Tkinter.Checkbutton, 1338 'text': 'Nitrogens ', 1339 'variable': self.NHBonds, 1340 'gridcfg':{'sticky':Tkinter.W}}) 1341 ifd.append({'name': 'O-HBonds', 1342 'widgetType':Tkinter.Checkbutton, 1343 'text': 'Oxygens ', 1344 'variable': self.OHBonds, 1345 'gridcfg':{'sticky':Tkinter.W}}) 1346 ifd.append({'name': 'S-HBonds', 1347 'widgetType':Tkinter.Checkbutton, 1348 'text': 'Sulphurs ', 1349 'variable': self.SHBonds, 1350 'gridcfg':{'sticky':Tkinter.W}}) 1351 ifd.append({'widgetType': Tkinter.Button, 1352 'text':'Accept', 1353 'wcfg':{'bd':4}, 1354 'gridcfg':{'sticky':Tkinter.E+Tkinter.W, 'columnspan':2}, 1355 'command':self.Accept_cb}) 1356 ifd.append({'widgetType': Tkinter.Button, 1357 'text':'Close', 1358 'wcfg':{'bd':4}, 1359 'gridcfg':{'sticky':Tkinter.E+Tkinter.W, 'column':2, 'row':-1}, 1360 'command':self.Close_cb})
1361 1362
1363 - def Close_cb(self, event=None):
1364 self.form.withdraw()
1365 1366
1367 - def Accept_cb(self, event=None):
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
1387 - def showLigand(self, ligand, event=None):
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
1394 - def getTypes(self, ligand):
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
1423 - def updateTypes(self, event=None):
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 #if 'H' in ligstring: 1435 # self.ifd.entryByName['HBondsLabel']['widget'].config(text ='Model Hydrogen Bonding:') 1436 # if item in ligstring: 1437 # w['widget'].config(state='normal') 1438 # else: 1439 # w['widget'].config(state='disabled') 1440 # w['variable'].set(0) 1441 #else: 1442 # self.ifd.entryByName['HBondsLabel']['widget'].config(text ='No Hydrogen Bonding') 1443 # w['widget'].config(state='disabled') 1444 # w['variable'].set(0) 1445 1446 1447
1448 -class GpfLigandChooser(MVCommand):
1449 """ allows user to choose a molecule already present for the ligand""" 1450 1451
1452 - def onAddCmdToViewer(self):
1453 checkHasGpo(self.vf)
1454 1455
1456 - def __init__(self, mode='single', title = 'Choose Ligand'):
1457 MVCommand.__init__(self) 1458 self.mode = mode 1459 self.title = title
1460 1461
1462 - def chooseLigand_cb(self, event = None):
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 #check that the molecule has a torTree 1472 #OR 1473 #it is current atorsDict['molecule'] and has outputfile 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(