Autodock plugin
Jump to navigation
Jump to search
Description
This plugin should help to set up docking runs with Autodock and view docking results. It has two features:
1) Setup of a docking grid for Autodock with PyMOL.
2) View the docking results.
Installation
1)Download plugin
2) PyMOL -> Plugin -> Install Plugin
Author
#!/usr/bin/env python
from __future__ import division
from __future__ import generators
import os,math,re
import Tkinter
from Tkinter import *
import tkMessageBox
import Pmw
from pymol import cmd,selector
import sys
from pymol.cmd import _feedback,fb_module,fb_mask,is_list,_cmd
from pymol.cgo import *
from pymol import stored
from Numeric import *
import tkColorChooser
from pymol.vfont import plain
# Python backward-compatibility...
try:
True
except:
True = 1
try:
False
except:
False = 0
#
# Cheap hack for testing purposes
#
try:
import pymol
REAL_PYMOL = True
except ImportError:
REAL_PYMOL = False
class pymol:
class cmd:
def load(self,name,sel=''):
pass
def get_names(self):
return ['mol1','mol2','map1','map2']
def get_type(self,thing):
if thing.startswith('mol'):
return 'object:molecule'
else:
return 'object:map'
f.close()
cmd = cmd()
pymol = pymol()
def __init__(self):
self.menuBar.addmenuitem('Plugin', 'command',
'Launch Autodock',
label='Autodock...',
command = lambda s=self: Autodock(s))
# set the defaults
defaults = {
"spacing" : '0.375',
"xpst":'100',
"ypst":'100',
"zpts":'100',
"sel":'(all)',
"X":'0',
"Y":'0',
"Z":'0',
"dx":'1.0',
"dy":'1.0',
"dz":'1.0',
"csize":'0.2',
"lwidth":'1',
"grid":'1',
"output":'grid.gpf',
"dlgfile":'dock.dlg'
}
class FileDialogButtonClassFactory:
def get(fn,filter='*'):
"""This returns a FileDialogButton class that will
call the specified function with the resulting file.
"""
class FileDialogButton(Tkinter.Button):
# This is just an ordinary button with special colors.
def __init__(self, master=None, cnf={}, **kw):
'''when we get a file, we call fn(filename)'''
self.fn = fn
self.__toggle = 0
apply(Tkinter.Button.__init__, (self, master, cnf), kw)
self.configure(command=self.set)
def set(self):
fd = PmwFileDialog(self.master,filter=filter)
fd.title('Please choose a file')
n=fd.askfilename()
if n is not None:
self.fn(n)
return FileDialogButton
get = staticmethod(get)
class Autodock:
def __init__(self,app):
parent = app.root
self.parent = parent
self.on_screen = IntVar()
self.on_screen.set(0) # 0 box | 1 wire
self.center = []
self.have_box = 0
self.colorRGB = [1,1,1]
self.dialog = Pmw.Dialog(parent,
buttons = ('Exit',),
title = 'PyMOL Autodock Tools',
command = self.buttonPressed)
self.dialog.withdraw()
Pmw.setbusycursorattributes(self.dialog.component('hull'))
# the title
w = Tkinter.Label(self.dialog.interior(),
text = 'PyMOL Autodock Tools\nDaniel Seeliger\n<http://www.mpibpc.mpg.de/groups/grubmueller/start/people/dseelig/index.html>',
background = 'navy',
foreground = 'white',
#pady = 20,
)
w.pack(expand = 1, fill = 'both', padx = 4, pady = 4)
# the basic notebook
self.notebook = Pmw.NoteBook(self.dialog.interior())
self.notebook.pack(fill='both',expand=0,padx=3,pady=3)
# the grid page
page = self.notebook.add('Grid')
# grid definiton page
group = Pmw.Group(page,tag_text='Grid Definition')
group.pack(fill = 'both', expand = 0, padx = 10, pady = 5)
self.dialog.bind('<Return>',self.buttonPressed)
# we put the parametes on the left side
lgroup = Pmw.Group(group.interior(),tag_text = "Parameters")
lgroup.pack(side='left',fill = 'both', expand = 0, padx = 10, pady = 3)
# ... and the display stuff on the right side
rgroup = Pmw.Group(group.interior(),tag_text = "Display Options")
rgroup.pack(side='right',fill = 'both', expand = 0, padx = 10, pady = 3)
# the left side ...
self.space=DoubleVar()
self.space.set(defaults['spacing'])
self.spacefr = Tkinter.Frame(lgroup.interior())
labSP = Label(self.spacefr,text="Grid:");
self.splocation = Entry(self.spacefr,textvariable=self.space,bg='black',fg='green');
self.scrSP=Scrollbar(self.spacefr,orient="horizontal",command=self.changeValueSpacing)
labSP.pack(side=LEFT)
self.splocation.pack(side=LEFT)
self.scrSP.pack(side=LEFT)
self.spacefr.pack(fill='x',padx=4,pady=1) # vertical
self.xpts=IntVar()
self.xpts.set(100)
self.xptsfr = Tkinter.Frame(lgroup.interior())
labXP = Label(self.xptsfr,text="xpts:");
self.xptslocation = Entry(self.xptsfr,textvariable=self.xpts,bg='black',fg='green');
self.xptsSP=Scrollbar(self.xptsfr,orient="horizontal",command=self.changeValueXpts)
labXP.pack(side=LEFT)
self.xptslocation.pack(side=LEFT)
self.xptsSP.pack(side=LEFT)
self.xptsfr.pack(fill='x',padx=4,pady=1) # vertical
self.ypts=IntVar()
self.ypts.set(100)
self.yptsfr = Tkinter.Frame(lgroup.interior())
labYP = Label(self.yptsfr,text="ypts:");
self.yptslocation = Entry(self.yptsfr,textvariable=self.ypts,bg='black',fg='green');
self.yptsSP=Scrollbar(self.yptsfr,orient="horizontal",command=self.changeValueYpts)
labYP.pack(side=LEFT)
self.yptslocation.pack(side=LEFT)
self.yptsSP.pack(side=LEFT)
self.yptsfr.pack(fill='x',padx=4,pady=1) # vertical
self.zpts=IntVar()
self.zpts.set(100)
self.zptsfr = Tkinter.Frame(lgroup.interior())
labZP = Label(self.zptsfr,text="zpts:");
self.zptslocation = Entry(self.zptsfr,textvariable=self.zpts,bg='black',fg='green');
self.zptsSP=Scrollbar(self.zptsfr,orient="horizontal",command=self.changeValueZpts)
labZP.pack(side=LEFT)
self.zptslocation.pack(side=LEFT)
self.zptsSP.pack(side=LEFT)
self.zptsfr.pack(fill='x',padx=4,pady=1) # vertical
# put a dummy frame
dumframe = Tkinter.Frame(page)
dumframe.pack(fill='x',padx=4,pady=2)
dum1 = Tkinter.Label(dumframe,
justify=LEFT,
text = "",
)
dum1.pack(side='left')
# the center definition
radiogroups = []
self.selmode = Tkinter.IntVar()
self.selmode.set(0)
radioframe = Tkinter.Frame(page)
w = Pmw.Group(radioframe,
tag_pyclass = Tkinter.Radiobutton,
tag_text='Use average coordinates \nof a given selection',
tag_value = 0,
tag_variable = self.selmode)
w.pack(fill = 'x', expand = 1, side='top')
cw = Tkinter.Frame(w.interior())
cw.pack(padx = 2, pady = 2, expand='yes', fill='both')
radiogroups.append(w)
self.selectionlist = Pmw.EntryField(w.interior(),
labelpos='w',
label_text='Selection: ',
value=defaults['sel'],
command = self.changed,
)
self.selectionlist.pack(fill='x',padx=4,pady=1,expand=0) # vertical
w = Pmw.Group(radioframe,
tag_pyclass = Tkinter.Radiobutton,
tag_text='Use coordinates',
tag_value = 1,
tag_variable = self.selmode)
w.pack(fill = 'x', expand = 1, side='top')
cw = Tkinter.Frame(w.interior())
cw.pack(padx = 2, pady = 2, expand='yes', fill='both')
radiogroups.append(w)
radioframe.pack(padx = 6, pady = 6, expand='yes', fill='both')
Pmw.aligngrouptags(radiogroups)
self.x=DoubleVar()
self.x.set(float(defaults["X"]))
self.y=DoubleVar()
self.y.set(float(defaults["Y"]))
self.z=DoubleVar()
self.z.set(float(defaults["Z"]))
self.xfr = Tkinter.Frame(w.interior())
labX = Label(self.xfr,text="X:");
self.xloc = Entry(self.xfr,textvariable=self.x,bg='black',fg='green');
self.scrX=Scrollbar(self.xfr,orient="horizontal",command=self.changeValueX)
self.yfr = Tkinter.Frame(w.interior())
labY = Label(self.yfr,text="Y:");
self.yloc = Entry(self.yfr,textvariable=self.y,bg='black',fg='green');
self.scrY=Scrollbar(self.yfr,orient="horizontal",command=self.changeValueY)
self.zfr = Tkinter.Frame(w.interior())
labZ = Label(self.zfr,text="Z:");
self.zloc = Entry(self.zfr,textvariable=self.z,bg='black',fg='green');
self.scrZ=Scrollbar(self.zfr,orient="horizontal",command=self.changeValueZ)
labX.pack(side=LEFT)
self.xloc.pack(side=LEFT)
self.scrX.pack(side=LEFT)
self.xfr.pack(fill='x',padx=4,pady=1) # vertical
labY.pack(side=LEFT)
self.yloc.pack(side=LEFT)
self.scrY.pack(side=LEFT)
self.yfr.pack(fill='x',padx=4,pady=1) # vertical
labZ.pack(side=LEFT)
self.zloc.pack(side=LEFT)
self.scrZ.pack(side=LEFT)
self.zfr.pack(fill='x',padx=4,pady=1) # vertical
self.butt1 = Pmw.ButtonBox(radioframe, padx=0)
self.butt1.pack(side=TOP)
self.butt1.add('Show Box',command = self.calc_box)
self.butt1.add('Hide Box',command = self.hideBox)
self.butt1.add('Write gpf',command = self.write_gpf)
self.butt1.add('Write Box',command = self.write_box)
self.butt1.add('Change Color',command=self.tk_color_dialog)
# the display options
radiogroups = []
radioframe = Tkinter.Frame(rgroup.interior())
w = Pmw.Group(radioframe,
tag_pyclass = Tkinter.Radiobutton,
tag_text='Cylindric Box',
tag_value = 0,
tag_variable = self.on_screen)
w.pack(fill = 'x', expand = 1, side='top')
cw = Tkinter.Frame(w.interior())
cw.pack(padx = 2, pady = 2, expand='yes', fill='both')
radiogroups.append(w)
self.csize=DoubleVar()
self.csize.set(float(defaults["csize"]))
self.csizefr = Tkinter.Frame(w.interior())
labcsize = Label(self.csizefr,text="size:");
self.csizeloc = Entry(self.csizefr,textvariable=self.csize,bg='black',fg='green',width=15);
self.scrcsize=Scrollbar(self.csizefr,orient="horizontal",command=self.changeValueCsize)
labcsize.pack(side=LEFT)
self.csizeloc.pack(side=LEFT)
self.scrcsize.pack(side=LEFT)
self.csizefr.pack(fill='x',padx=4,pady=1) # vertical
w = Pmw.Group(radioframe,
tag_pyclass = Tkinter.Radiobutton,
tag_text='Wired Box',
tag_value = 1,
tag_variable = self.on_screen)
w.pack(fill = 'x', expand = 1, side='top')
cw = Tkinter.Frame(w.interior())
cw.pack(padx = 2, pady = 2, expand='yes', fill='both')
radiogroups.append(w)
self.lwidth=DoubleVar()
self.lwidth.set(float(defaults["lwidth"]))
self.lwidthfr = Tkinter.Frame(w.interior())
lablwidth = Label(self.lwidthfr,text="line:");
self.lwidthloc = Entry(self.lwidthfr,textvariable=self.lwidth,bg='black',fg='green',width=15);
self.scrlwidth=Scrollbar(self.lwidthfr,orient="horizontal",command=self.changeValueLwidth)
lablwidth.pack(side=LEFT)
self.lwidthloc.pack(side=LEFT)
self.scrlwidth.pack(side=LEFT)
self.lwidthfr.pack(fill='x',padx=4,pady=1) # vertical
self.grid=DoubleVar()
self.grid.set(float(defaults["grid"]))
self.gridfr = Tkinter.Frame(w.interior())
labgrid = Label(self.gridfr,text="grid:");
self.gridloc = Entry(self.gridfr,textvariable=self.grid,bg='black',fg='green',width=15);
self.scrgrid=Scrollbar(self.gridfr,orient="horizontal",command=self.changeValueGrid)
labgrid.pack(side=LEFT)
self.gridloc.pack(side=LEFT)
self.scrgrid.pack(side=LEFT)
self.gridfr.pack(fill='x',padx=4,pady=1) # vertical
radioframe.pack(padx = 6, pady = 6, expand='yes', fill='both')
Pmw.aligngrouptags(radiogroups)
# the output file stuff
self.outfile = StringVar()
self.outfile.set(defaults['output'])
self.outlocation = Pmw.EntryField(page,
labelpos='w',
label_pyclass = FileDialogButtonClassFactory.get(self.set_outfilename,filter=("*.gpf")),
validate = {'validator':self.quickFileValidation,},
value = defaults['output'],
label_text = 'Browse:')
self.outlocation.pack(fill = 'both', expand = 1, padx = 10, pady = 5)
# Docking Results Card
page = self.notebook.add('View Docked')
# the input file
group = Pmw.Group(page,tag_text='File')
group.pack(fill = 'both', expand = 0, padx = 10, pady = 5)
# the structure card
rgroup = Pmw.Group(page,tag_text='Structures')
rgroup.pack(fill = 'both', expand = 1, padx = 10, pady = 5)
self.rgroup = Pmw.NoteBook(rgroup.interior())
self.rgroup.pack(fill='both',expand=1,padx=3,pady=3)
self.pages = {}
self.struct_dic = {}
self.dlgfile = StringVar()
self.dlgfile.set(defaults['dlgfile'])
self.dlglocation = Pmw.EntryField(group.interior(),
labelpos='w',
label_pyclass = FileDialogButtonClassFactory.get(self.set_dlgfilename,filter="*.dlg"),
validate = {'validator':self.quickFileValidation,},
value = defaults['dlgfile'],
label_text = 'Browse:')
self.dlglocation.pack(fill = 'both', expand = 1, padx = 10, pady = 5)
self.load_buttonbox = Pmw.ButtonBox(group.interior(), padx=0)
self.load_buttonbox.pack(side=LEFT,expand = 1, padx = 10, pady = 5)
self.load_buttonbox.add('Load',command=self.load_dlg)
self.mlist = []
self.namelist = []
self.radiobuttons = Pmw.RadioSelect(rgroup.interior(),
buttontype = 'radiobutton',
orient = 'horizontal',
labelpos = 'w',
)
for text in ('Show Selected',
'Delete Selected'):
self.radiobuttons.add(text)
self.radiobuttons.setvalue('Show Selected')
self.radiobuttons.pack(padx=4,pady=1,side='top')
self.status_line = Label(rgroup.interior(), #relief='groove',
relief='sunken',
font='helvetica 12', anchor='w',fg='yellow',bg='black')
self.status_line.pack(side='left', fill='x', expand=True)
# the about card
page = self.notebook.add('About')
group = Pmw.Group(page, tag_text='About PyMOL Autodock Tools')
group.pack(fill = 'both', expand = 1, padx = 10, pady = 5)
text = """
This plugin should help to set up docking runs and view docking results.
To set up a docking grid,
1) Load a protein structure.
2) Select the center of the box either by giving a selection or
the coordinates directly.
3) Adjust the box as needed and save the *.gpf file.
To view docking results,
1) Load the protein structure.
2) Load the *.dlg file (or multiple *dlg files).
For any bug, please send a mail with description to the author.
Many thanks to
- Warren DeLano for everything involving PyMOL
- The PyMOL plugin writers for providing templates
Created by Daniel Seeliger (dseelig@gwdg.de)
<http://www.mpibpc.mpg.de/groups/grubmueller/start/people/dseelig/index.html>
Computational Biomolecular Dynamics Group
<http://www.mpibpc.gwdg.de/abteilungen/073/>
"""
lfre=Frame(group.interior())
bar=Scrollbar(lfre,)
ll=Text(lfre,yscrollcommand=bar.set,background="#ddddff",font="Times 14")
bar.config(command=ll.yview)
ll.insert(END,text)
ll.pack(side=LEFT,expand="yes",fill="both")
bar.pack(side=LEFT,expand="yes",fill="y")
lfre.pack(expand="yes",fill="both")
self.notebook.setnaturalsize()
self.showAppModal()
# functions
def tk_color_dialog(self):
color = tkColorChooser.Chooser(
initialcolor='white',title='Choose box color').show()
if color[0] is not None:
self.colorRGB = [color[0][0]/100.,
color[0][1]/100.,
color[0][2]/100.]
def status_combobox(self, value):
name = value.split('_')[0]
if self.radiobuttons.getvalue()=='Show Selected':
view = cmd.get_view()
cmd.read_pdbstr(self.struct_dic[str(value)].as_string,str(value))
cmd.set_view(view)
text = 'Docked Energy: %8.2f kcal/mol' % self.struct_dic[str(value)].energy
self.status_line.configure(text=text)
usr = self.struct_dic[str(value)].info_as_string.split('\n')
u = ''
for l in usr:
u+=l[8:]+'\n'
atoms = self.struct_dic[str(value)].as_string.split('\n')
at = ''
for a in atoms:
at+=a[8:]+'\n'
self.pages[name]['text'].clear()
self.pages[name]['text'].insert('end',u)
self.pages[name]['text'].insert('end',at)
else:
cmd.delete(str(value))
self.pages[name]['text'].clear()
self.status_line.configure(text='')
def set_outfilename(self,filename):
self.outlocation.setvalue(filename)
def set_dlgfilename(self,filename):
self.dlglocation.setvalue(filename)
def buttonPressed(self,result):
if hasattr(result,'keycode'):
if result.keycode == 36:
if self.notebook.getcurselection()=='Grid':
self.calc_box()
elif self.notebook.getcurselection()=='View Docked':
self.load_dlg()
if result == 'Show Box':
self.calc_box()
elif result == 'Write gpf':
self.write_gpf()
elif result == 'Exit' or result == None:
self.dialog.withdraw()
def write_gpf(self):
fname = self.outlocation.getvalue()
if os.path.isfile(fname):
print "backing up %s to ~%s" % (fname,fname)
os.rename(fname,'~'+fname)
print 'writing file %s' % fname
fp = self.fileopen(fname,'w')
if fp:
print >>fp,"receptor protein.pdbqs #macromolecule"
print >>fp,"gridfld protein.maps.fld #grid_data_file"
print >>fp,"npts %5d %5d %5d #num.grid points in xyz" % \
(self.xpts.get(),self.ypts.get(),self.zpts.get())
print >>fp,"spacing %7.3f #spacing (Angstroms)" % self.space.get()
print >>fp,"gridcenter %6.3f %6.3f %6.3f #xyz-coordinates or \"auto\" "%\
(self.center[0],self.center[1],self.center[2])
self.print_stuff(fp)
fp.close()
def write_box(self):
self.calc_box()
fname = self.outlocation.getvalue()
if os.path.isfile(fname):
print "backing up %s to ~%s" % (fname,fname)
os.rename(fname,'~'+fname)
print 'writing file %s' % fname
fp = self.fileopen(fname,'w')
print >>fp, 'xmin = %8.3f' % self.dbox[0][0]
print >>fp, 'xmax = %8.3f' % self.dbox[0][1]
print >>fp, 'ymin = %8.3f' % self.dbox[1][0]
print >>fp, 'ymax = %8.3f' % self.dbox[1][1]
print >>fp, 'zmin = %8.3f' % self.dbox[2][0]
print >>fp, 'zmax = %8.3f' % self.dbox[2][1]
fp.close()
def print_stuff(self,fp):
print >>fp, """types CANOSH #atom type names
smooth 0.500 #store minimum energy within radius (Ang)
map protein.C.map #filename of grid map
nbp_r_eps 4.00 0.0222750 12 6 #C-C lj
nbp_r_eps 3.75 0.0230026 12 6 #C-N lj
nbp_r_eps 3.60 0.0257202 12 6 #C-O lj
nbp_r_eps 4.00 0.0257202 12 6 #C-S lj
nbp_r_eps 3.00 0.0081378 12 6 #C-H lj
nbp_r_eps 4.10 0.0257202 12 6 #C-X lj (X: Phosphorus in protein-cofactor)
nbp_r_eps 3.70 0.0181874 12 6 #C-M lj (Met: Mg)
sol_par 12.77 0.6844 #C atomic fragmental volume, solv. param.
constant 0.000 #C grid map constant energy
map protein.A.map #filename of grid map
nbp_r_eps 4.00 0.0222750 12 6 #A-C lj
nbp_r_eps 3.75 0.0230026 12 6 #A-N lj
nbp_r_eps 3.60 0.0257202 12 6 #A-O lj
nbp_r_eps 4.00 0.0257202 12 6 #A-S lj
nbp_r_eps 3.00 0.0081378 12 6 #A-H lj
nbp_r_eps 4.10 0.0257202 12 6 #A-X lj (X: Phosphorus in protein-cofactor)
nbp_r_eps 3.70 0.0181874 12 6 #A-M lj (Met: Mg)
sol_par 10.80 0.1027 #A atomic fragmental volume, solv. param.
constant 0.000 #A grid map constant energy
map protein.N.map #filename of grid map
nbp_r_eps 3.75 0.0230026 12 6 #N-C lj
nbp_r_eps 3.50 0.0237600 12 6 #N-N lj
nbp_r_eps 3.35 0.0265667 12 6 #N-O lj
nbp_r_eps 3.75 0.0265667 12 6 #N-S lj
nbp_r_eps 2.75 0.0084051 12 6 #N-H lj
nbp_r_eps 3.85 0.0265667 12 6 #N-X lj (X: Phosphorus in protein-cofactor)
nbp_r_eps 3.45 0.0187839 12 6 #N-M lj (Met: Mg)
sol_par 0.00 0.0000 #N atomic fragmental volume, solv. param.
constant 0.000 #N grid map constant energy
map protein.O.map #filename of grid map
nbp_r_eps 3.60 0.0257202 12 6 #O-C lj
nbp_r_eps 3.35 0.0265667 12 6 #O-N lj
nbp_r_eps 3.20 0.0297000 12 6 #O-O lj
nbp_r_eps 3.60 0.0297000 12 6 #O-S lj
nbp_r_eps 1.90 0.3280000 12 10 #O-H hb
nbp_r_eps 3.70 0.0297000 12 6 #O-X lj (X: Phosphorus in protein-cofactor)
nbp_r_eps 3.30 0.0210010 12 6 #O-M lj (Met: Mg)
sol_par 0.00 0.0000 #O atomic fragmental volume, solv. param.
constant 0.236 #O grid map constant energy
map protein.S.map #filename of grid map
nbp_r_eps 4.00 0.0257202 12 6 #S-C lj
nbp_r_eps 3.75 0.0265667 12 6 #S-N lj
nbp_r_eps 3.60 0.0297000 12 6 #S-O lj
nbp_r_eps 4.00 0.0297000 12 6 #S-S lj
nbp_r_eps 2.50 0.0656000 12 10 #S-H hb
nbp_r_eps 4.10 0.0297000 12 6 #S-X lj (X: Phosphorus in protein-cofactor)
nbp_r_eps 3.70 0.0210010 12 6 #S-M lj (Met: Mg)
sol_par 0.00 0.0000 #S atomic fragmental volume, solv. param.
constant 0.000 #S grid map constant energy
map protein.H.map #filename of grid map
nbp_r_eps 3.00 0.0081378 12 6 #H-C lj
nbp_r_eps 2.75 0.0084051 12 6 #H-N lj
nbp_r_eps 1.90 0.3280000 12 10 #H-O hb
nbp_r_eps 2.50 0.0656000 12 10 #H-S hb
nbp_r_eps 2.00 0.0029700 12 6 #H-H lj
nbp_r_eps 3.10 0.0093920 12 6 #H-X lj (X: Phosphorus in protein-cofactor)
nbp_r_eps 2.70 0.0066411 12 6 #H-M lj (Met: Mg)
sol_par 0.00 0.0000 #H atomic fragmental volume, solv. param.
constant 0.118 #H grid map constant energy
elecmap protein.e.map #electrostatic potential map
dielectric -0.1146 #<0,distance-dep.diel; >0,constant
#fmap ... .f.map #floating grid
"""
def quickFileValidation(self,s):
if s == '': return Pmw.PARTIAL
elif os.path.isfile(s): return Pmw.OK
elif os.path.exists(s): return Pmw.PARTIAL
else: return Pmw.PARTIAL
def changed(self):
self.selmode.set(0)
self.calc_box()
self.showCrisscross()
self.selectionlist.clear()
def calc_center(self):
self.center = []
if self.selmode.get() == 0:
sel = self.selectionlist.getvalue()
if sel:
stored.xyz = []
cmd.iterate_state(1,sel,"stored.xyz.append([x,y,z])")
self.center = average(stored.xyz)
else:
self.selmode.set(1)
self.calc_center()
elif self.selmode.get() == 1:
self.center.append(float(self.x.get()))
self.center.append(float(self.y.get()))
self.center.append(float(self.z.get()))
self.x.set(self.center[0])
self.y.set(self.center[1])
self.z.set(self.center[2])
def showCrisscross(self):
startpoint = (self.center[0],self.center[1],self.center[2])
cmd.delete("crisscross")
self.crisscross(startpoint[0],startpoint[1],startpoint[2],0.5,"crisscross")
def changeValueSpacing(self,a):
val = float(self.space.get())+float(a)*0.005
self.space.set(val)
if self.have_box:
self.selmode.set(1)
self.calc_center()
self.showCrisscross()
self.calc_box()
def changeValueXpts(self,a):
val = int(self.xpts.get())+int(a)
self.xpts.set(val)
if self.have_box:
self.selmode.set(1)
self.calc_center()
self.showCrisscross()
self.calc_box()
def changeValueYpts(self,a):
val = int(self.ypts.get())+int(a)
self.ypts.set(val)
if self.have_box:
self.selmode.set(1)
self.calc_center()
self.showCrisscross()
self.calc_box()
def changeValueZpts(self,a):
val = int(self.zpts.get())+int(a)
self.zpts.set(val)
if self.have_box:
self.selmode.set(1)
self.calc_center()
self.showCrisscross()
self.calc_box()
def changeValueX(self,a):
self.selmode.set(1)
val=float(self.x.get())+float(a)*1.0
self.x.set(val)
self.calc_center()
self.showCrisscross()
self.calc_box()
def changeValueY(self,a):
self.selmode.set(1)
val=float(self.y.get())+float(a)*1.0
self.y.set(val)
self.calc_center()
self.showCrisscross()
self.calc_box()
def changeValueZ(self,a):
self.selmode.set(1)
val=float(self.z.get())+float(a)*1.0
self.z.set(val)
self.calc_center()
self.showCrisscross()
self.calc_box()
def changeValueCsize(self,a):
val=float(self.csize.get())+float(a)*0.1
self.csize.set(val)
self.selmode.set(1)
self.calc_center()
self.showCrisscross()
self.calc_box()
def changeValueLwidth(self,a):
val=float(self.lwidth.get())+float(a)*1.0
self.lwidth.set(val)
self.selmode.set(1)
self.calc_center()
self.showCrisscross()
self.calc_box()
def changeValueGrid(self,a):
val=float(self.grid.get())+float(a)*1.0
self.grid.set(val)
self.selmode.set(1)
self.calc_center()
self.showCrisscross()
self.calc_box()
def calc_box(self):
self.calc_center()
xpts = int(self.xpts.get())
ypts = int(self.ypts.get())
zpts = int(self.zpts.get())
csize = float(self.csize.get())
spacing = float(self.space.get())
size = [xpts*spacing,ypts*spacing,zpts*spacing]
xmax = xmin = ymax = ymin = zmax =zmin = 0
xmax = self.center[0] + size[0]/2.
xmin = self.center[0] - size[0]/2.
ymax = self.center[1] + size[1]/2.
ymin = self.center[1] - size[1]/2.
zmax = self.center[2] + size[2]/2.
zmin = self.center[2] - size[2]/2.
x = [xmin,xmax]
y = [ymin,ymax]
z = [zmin,zmax]
self.dbox = [x,y,z]
if self.on_screen.get()==0:
self.showBox(self.dbox,csize)
elif self.on_screen.get()==1:
self.showWireBox(self.dbox)
self.have_box = 1
def showBox(self,box,size):
view = cmd.get_view()
name =" box"
obj = []
# do the box
for i in range(2):
for k in range (2):
for j in range(2):
if i != 1:
obj.append(CYLINDER)
obj.extend([box[0][i],box[1][j],box[2][k]])
obj.extend([box[0][i+1],box[1][j],box[2][k]])
obj.append(size)
obj.extend(self.colorRGB)
obj.extend(self.colorRGB)
obj.append(COLOR)
obj.extend(self.colorRGB)
obj.append(SPHERE)
obj.extend([box[0][i],box[1][j],box[2][k],size])
if j != 1:
obj.append(CYLINDER)
obj.extend([box[0][i],box[1][j],box[2][k]])
obj.extend([box[0][i],box[1][j+1],box[2][k]])
obj.append(size)
obj.extend(self.colorRGB)
obj.extend(self.colorRGB)
obj.append(COLOR)
obj.extend(self.colorRGB)
obj.append(SPHERE)
obj.extend([box[0][i],box[1][j+1],box[2][k],size])
if k != 1:
obj.append(CYLINDER)
obj.extend([box[0][i],box[1][j],box[2][k]])
obj.extend([box[0][i],box[1][j],box[2][k+1]])
obj.append(size)
obj.extend(self.colorRGB)
obj.extend(self.colorRGB)
obj.append(COLOR)
obj.extend(self.colorRGB)
obj.append(SPHERE)
obj.extend([box[0][i],box[1][j],box[2][k+1],size])
axes = [[2.0,0.0,0.0],[0.0,2.0,0.0],[0.0,0.0,2.0]]
xpos = [box[0][1]+(box[0][1]-box[0][0])/5.,box[1][0],box[2][0]]
cyl_text(obj,plain,xpos,'X',0.10,axes=axes)
ypos = [box[0][0],box[1][1]+(box[1][1]-box[1][0])/5,box[2][0]]
cyl_text(obj,plain,ypos,'Y',0.10,axes=axes)
zpos = [box[0][0],box[1][0],box[2][1]+(box[2][1]-box[2][0])/5]
cyl_text(obj,plain,zpos,'Z',0.10,axes=axes)
cmd.load_cgo(obj,name)
cmd.set_view(view)
def hideBox(self):
cmd.delete("box")
cmd.delete("wirebox")
def showWireBox(self,box):
cmd.delete("wirebox")
view = cmd.get_view()
spacing = float(self.grid.get())
lwidth = float(self.lwidth.get())
xpts = int(round((box[0][1]-box[0][0])/spacing))+1
ypts = int(round((box[1][1]-box[1][0])/spacing))+1
zpts = int(round((box[2][1]-box[2][0])/spacing))+1
obj = []
for i in range(xpts):
for k in range (ypts):
obj.append(BEGIN)
obj.append(LINE_STRIP)
obj.append(COLOR)
obj.extend(self.colorRGB)
for j in range(zpts):
obj.append(VERTEX)
obj.extend([box[0][0]+spacing*i,box[1][0]+spacing*k,\
box[2][0]+spacing*j])
obj.append(END)
for i in range(xpts):
for j in range (zpts):
obj.append(BEGIN)
obj.append(LINE_STRIP)
obj.append(COLOR)
obj.extend(self.colorRGB)
for k in range(ypts):
obj.append(VERTEX)
obj.extend([box[0][0]+spacing*i,box[1][0]+spacing*k,\
box[2][0]+spacing*j])
obj.append(END)
for j in range(zpts):
for i in range (xpts):
obj.append(BEGIN)
obj.append(LINE_STRIP)
obj.append(COLOR)
obj.extend(self.colorRGB)
for k in range(ypts):
obj.append(VERTEX)
obj.extend([box[0][0]+spacing*i,box[1][0]+spacing*k,\
box[2][0]+spacing*j])
obj.append(END)
for j in range(zpts):
for k in range (ypts):
obj.append(BEGIN)
obj.append(LINE_STRIP)
obj.append(COLOR)
obj.extend(self.colorRGB)
for i in range(xpts):
obj.append(VERTEX)
obj.extend([box[0][0]+spacing*i,box[1][0]+spacing*k,\
box[2][0]+spacing*j])
obj.append(END)
cmd.load_cgo(obj,"wirebox")
cmd.set("cgo_line_width",lwidth)
cmd.set_view(view)
def crisscross(self,x,y,z,d,name="crisscross"):
obj = [
LINEWIDTH, 3,
BEGIN, LINE_STRIP,
VERTEX, float(x-d), float(y), float(z),
VERTEX, float(x+d), float(y), float(z),
END,
BEGIN, LINE_STRIP,
VERTEX, float(x), float(y-d), float(z),
VERTEX, float(x), float(y+d), float(z),
END,
BEGIN, LINE_STRIP,
VERTEX, float(x), float(y), float(z-d),
VERTEX, float(x), float(y), float(z+d),
END
]
view = cmd.get_view()
cmd.load_cgo(obj,name)
cmd.set_view(view)
def load_dlg(self):
filename = self.dlglocation.get()
self.namelist = []
name = filename.split('/')[-1].split('.')[0]
fp=self.fileopen(filename,'r')
if fp:
string = fp.read()
newl = []
modlist = []
ex = re.compile('DOCKED:.*')
l = ex.findall(string)
str = ''
mod = []
for i in range(len(l)):
if 'MODEL' in l[i]:
str+=l[i]+'\n'
for k in range(i+1,len(l)):
if 'TER' in l[k]:
str+=l[k]+'\n'
mod.append(str)
str=''
break
else:
str+=l[k]+'\n'
mlist= []
for x in mod:
m = Model()
m.str2mod(x)
mlist.append(m)
self.mlist = sortByEnergy(mlist)
for i in range(len(self.mlist)):
self.namelist.append(name+'_%d'%(i+1))
self.struct_dic[name+'_%d'%(i+1)] = self.mlist[i]
self.update_combo(name)
def update_combo(self,name):
try:
self.rgroup.delete(name)
except:
pass
self.pages[name] = {'name':self.rgroup.add(name)}
self.pages[name].update({'structs':self.namelist})
self.del_buttonbox = Pmw.ButtonBox(self.pages[name]['name'], padx=3)
self.del_buttonbox.pack(fill='x',side=TOP)
self.del_buttonbox.add('Show best 10 %s' % name,command=self.show_best_lig)
self.del_buttonbox.add('Show all %s' % name,command=self.show_all_lig)
self.del_buttonbox.add('Hide all %s' % name,command=self.hide_all_lig)
self.del_buttonbox.add('Delete %s' % name,command=self.del_lig)
self.pages[name]['combo'] = Pmw.ComboBox(self.pages[name]['name'],
label_text='Docked',
labelpos='nw',
scrolledlist_items= self.namelist,
selectioncommand=self.status_combobox,
listbox_height=10,
listbox_width=1,
dropdown=False)
self.pages[name]['combo'].pack(side='left', padx=3, anchor='n')
self.pages[name]['text'] = Pmw.ScrolledText(self.pages[name]['name'],
borderframe=5,
vscrollmode='dynamic',
hscrollmode='dynamic',
labelpos='n',
label_text=name,
text_width=150, text_height=15,
text_wrap='none',
text_background='#000000',
text_foreground='green'
)
self.pages[name]['text'].pack()
self.rgroup.selectpage(name)
self.status_line.configure(text ='Loading %s' % name)
def show_all_lig(self):
name = self.rgroup.getcurselection()
for s in self.pages[name]['structs']:
self.status_combobox(s)
self.status_line.configure(text = 'Showing all %s' % name)
def show_best_lig(self):
name = self.rgroup.getcurselection()
for s in self.pages[name]['structs'][:10]:
self.status_combobox(s)
self.status_line.configure(text = 'Showing best 10 %s' % name)
def hide_all_lig(self):
name = self.rgroup.getcurselection()
cmd.delete(name+'*')
self.status_line.configure(text = 'Deleted all %s' % name)
def del_lig(self):
name = self.rgroup.getcurselection()
cmd.delete(name+'*')
self.rgroup.delete(self.rgroup.getcurselection())
self.status_line.configure(text = 'Deleted %s' % name)
def fileopen(self, filename, mode):
try:
fp = open(filename,mode)
return fp
except:
tkMessageBox.showerror('Error','Could not open file %s' % filename)
return None
def showAppModal(self):
#self.dialog.activate(geometry = 'centerscreenalways', globalMode = 'nograb')
self.dialog.show()
#self.dialog.activate(geometry = 'centerscreenalways')
#
# The classes PmwFileDialog and PmwExistingFileDialog and the _errorpop function
# are taken from the Pmw contrib directory. The attribution given in that file
# is:
################################################################################
# Filename dialogs using Pmw
#
# (C) Rob W.W. Hooft, Nonius BV, 1998
#
# Modifications:
#
# J. Willem M. Nissink, Cambridge Crystallographic Data Centre, 8/2002
# Added optional information pane at top of dialog; if option
# 'info' is specified, the text given will be shown (in blue).
# Modified example to show both file and directory-type dialog
#
# No Guarantees. Distribute Freely.
# Please send bug-fixes/patches/features to <r.hooft@euromail.com>
#
################################################################################
import os,fnmatch,time
import Tkinter,Pmw
#Pmw.setversion("0.8.5")
def _errorpop(master,text):
d=Pmw.MessageDialog(master,
title="Error",
message_text=text,
buttons=("OK",))
d.component('message').pack(ipadx=15,ipady=15)
d.activate()
d.destroy()
class PmwFileDialog(Pmw.Dialog):
"""File Dialog using Pmw"""
def __init__(self, parent = None, **kw):
# Define the megawidget options.
optiondefs = (
('filter', '*', self.newfilter),
('directory', os.getcwd(), self.newdir),
('filename', '', self.newfilename),
('historylen',10, None),
('command', None, None),
('info', None, None),
)
self.defineoptions(kw, optiondefs)
# Initialise base class (after defining options).
Pmw.Dialog.__init__(self, parent)
self.withdraw()
# Create the components.
interior = self.interior()
if self['info'] is not None:
rowoffset=1
dn = self.infotxt()
dn.grid(row=0,column=0,columnspan=2,padx=3,pady=3)
else:
rowoffset=0
dn = self.mkdn()
dn.grid(row=0+rowoffset,column=0,columnspan=2,padx=3,pady=3)
del dn
# Create the directory list component.
dnb = self.mkdnb()
dnb.grid(row=1+rowoffset,column=0,sticky='news',padx=3,pady=3)
del dnb
# Create the filename list component.
fnb = self.mkfnb()
fnb.grid(row=1+rowoffset,column=1,sticky='news',padx=3,pady=3)
del fnb
# Create the filter entry
ft = self.mkft()
ft.grid(row=2+rowoffset,column=0,columnspan=2,padx=3,pady=3)
del ft
# Create the filename entry
fn = self.mkfn()
fn.grid(row=3+rowoffset,column=0,columnspan=2,padx=3,pady=3)
fn.bind('<Return>',self.okbutton)
del fn
# Buttonbox already exists
bb=self.component('buttonbox')
bb.add('OK',command=self.okbutton)
bb.add('Cancel',command=self.cancelbutton)
del bb
Pmw.alignlabels([self.component('filename'),
self.component('filter'),
self.component('dirname')])
def infotxt(self):
""" Make information block component at the top """
return self.createcomponent(
'infobox',
(), None,
Tkinter.Label, (self.interior(),),
width=51,
relief='groove',
foreground='darkblue',
justify='left',
text=self['info']
)
def mkdn(self):
"""Make directory name component"""
return self.createcomponent(
'dirname',
(), None,
Pmw.ComboBox, (self.interior(),),
entryfield_value=self['directory'],
entryfield_entry_width=40,
entryfield_validate=self.dirvalidate,
selectioncommand=self.setdir,
labelpos='w',
label_text='Directory:')
def mkdnb(self):
"""Make directory name box"""
return self.createcomponent(
'dirnamebox',
(), None,
Pmw.ScrolledListBox, (self.interior(),),
label_text='directories',
labelpos='n',
hscrollmode='none',
dblclickcommand=self.selectdir)
def mkft(self):
"""Make filter"""
return self.createcomponent(
'filter',
(), None,
Pmw.ComboBox, (self.interior(),),
entryfield_value=self['filter'],
entryfield_entry_width=40,
selectioncommand=self.setfilter,
labelpos='w',
label_text='Filter:')
def mkfnb(self):
"""Make filename list box"""
return self.createcomponent(
'filenamebox',
(), None,
Pmw.ScrolledListBox, (self.interior(),),
label_text='files',
labelpos='n',
hscrollmode='none',
selectioncommand=self.singleselectfile,
dblclickcommand=self.selectfile)
def mkfn(self):
"""Make file name entry"""
return self.createcomponent(
'filename',
(), None,
Pmw.ComboBox, (self.interior(),),
entryfield_value=self['filename'],
entryfield_entry_width=40,
entryfield_validate=self.filevalidate,
selectioncommand=self.setfilename,
labelpos='w',
label_text='Filename:')
def dirvalidate(self,string):
if os.path.isdir(string):
return Pmw.OK
else:
return Pmw.PARTIAL
def filevalidate(self,string):
if string=='':
return Pmw.PARTIAL
elif os.path.isfile(string):
return Pmw.OK
elif os.path.exists(string):
return Pmw.PARTIAL
else:
return Pmw.OK
def okbutton(self):
"""OK action: user thinks he has input valid data and wants to
proceed. This is also called by <Return> in the filename entry"""
fn=self.component('filename').get()
self.setfilename(fn)
if self.validate(fn):
self.canceled=0
self.deactivate()
def cancelbutton(self):
"""Cancel the operation"""
self.canceled=1
self.deactivate()
def tidy(self,w,v):
"""Insert text v into the entry and at the top of the list of
the combobox w, remove duplicates"""
if not v:
return
entry=w.component('entry')
entry.delete(0,'end')
entry.insert(0,v)
list=w.component('scrolledlist')
list.insert(0,v)
index=1
while index<list.index('end'):
k=list.get(index)
if k==v or index>self['historylen']:
list.delete(index)
else:
index=index+1
w.checkentry()
def setfilename(self,value):
if not value:
return
value=os.path.join(self['directory'],value)
dir,fil=os.path.split(value)
self.configure(directory=dir,filename=value)
c=self['command']
if callable(c):
c()
def newfilename(self):
"""Make sure a newly set filename makes it into the combobox list"""
self.tidy(self.component('filename'),self['filename'])
def setfilter(self,value):
self.configure(filter=value)
def newfilter(self):
"""Make sure a newly set filter makes it into the combobox list"""
self.tidy(self.component('filter'),self['filter'])
self.fillit()
def setdir(self,value):
self.configure(directory=value)
def newdir(self):
"""Make sure a newly set dirname makes it into the combobox list"""
self.tidy(self.component('dirname'),self['directory'])
self.fillit()
def singleselectfile(self):
"""Single click in file listbox. Move file to "filename" combobox"""
cs=self.component('filenamebox').curselection()
if cs!=():
value=self.component('filenamebox').get(cs)
self.setfilename(value)
def selectfile(self):
"""Take the selected file from the filename, normalize it, and OK"""
self.singleselectfile()
value=self.component('filename').get()
self.setfilename(value)
if value:
self.okbutton()
def selectdir(self):
"""Take selected directory from the dirnamebox into the dirname"""
cs=self.component('dirnamebox').curselection()
if cs!=():
value=self.component('dirnamebox').get(cs)
dir=self['directory']
if not dir:
dir=os.getcwd()
if value:
if value=='..':
dir=os.path.split(dir)[0]
else:
dir=os.path.join(dir,value)
self.configure(directory=dir)
self.fillit()
def askfilename(self,directory=None,filter=None):
"""The actual client function. Activates the dialog, and
returns only after a valid filename has been entered
(return value is that filename) or when canceled (return
value is None)"""
if directory!=None:
self.configure(directory=directory)
if filter!=None:
self.configure(filter=filter)
self.fillit()
self.canceled=1 # Needed for when user kills dialog window
self.activate()
if self.canceled:
return None
else:
return self.component('filename').get()
lastdir=""
lastfilter=None
lasttime=0
def fillit(self):
"""Get the directory list and show it in the two listboxes"""
# Do not run unnecesarily
if self.lastdir==self['directory'] and self.lastfilter==self['filter'] and self.lasttime>os.stat(self.lastdir)[8]:
return
self.lastdir=self['directory']
self.lastfilter=self['filter']
self.lasttime=time.time()
dir=self['directory']
if not dir:
dir=os.getcwd()
dirs=['..']
files=[]
try:
fl=os.listdir(dir)
fl.sort()
except os.error,arg:
if arg[0] in (2,20):
return
raise
for f in fl:
if os.path.isdir(os.path.join(dir,f)):
dirs.append(f)
else:
filter=self['filter']
if not filter:
filter='*'
if fnmatch.fnmatch(f,filter):
files.append(f)
self.component('filenamebox').setlist(files)
self.component('dirnamebox').setlist(dirs)
def validate(self,filename):
"""Validation function. Should return 1 if the filename is valid,
0 if invalid. May pop up dialogs to tell user why. Especially
suited to subclasses: i.e. only return 1 if the file does/doesn't
exist"""
return 1
class PmwExistingFileDialog(PmwFileDialog):
def filevalidate(self,string):
if os.path.isfile(string):
return Pmw.OK
else:
return Pmw.PARTIAL
def validate(self,filename):
if os.path.isfile(filename):
return 1
elif os.path.exists(filename):
_errorpop(self.interior(),"This is not a plain file")
return 0
else:
_errorpop(self.interior(),"Please select an existing file")
return 0
#===============================================================
#
# stuff to deal with dlg files
class Model:
def __init__(self):
self.atoms = []
self.energy = 0.
self.info = []
self.num = 0
self.as_string = ''
self.info_as_string = ''
def str2mod(self,string):
list = string.split('\n')
for line in list:
if 'ATOM' in line:
self.atoms.append(line.split(':')[1].strip())
self.as_string+=line.split(':')[1].strip()+'\n'
elif 'USER' in line:
self.info.append(line.split(':')[1].strip())
self.info_as_string+=line.split(':')[1].strip()+'\n'
elif 'MODEL' in line:
self.num = int(line.split()[2])
for line in self.info:
if 'Docked Energy' in line:
x = line.split('=')[1]
self.energy = float(x.split()[0])
def writeMod(self,fp):
print >>fp,'MODEL%8d' % self.num
for at in self.atoms:
print >>fp, at
print >>fp,'ENDMDL'
def sortByEnergy(mlist):
en = []
idx = []
for m in mlist:
en.append(m.energy)
idx.append(mlist.index(m))
changed = True
while changed:
changed = False
for i in range(len(en)-1):
if en[i] > en[i+1]:
dum = en[i+1]
en[i+1] = en[i]
en[i] = dum
dum = idx[i+1]
idx[i+1] = idx[i]
idx[i] = dum
changed = True
new = []
for i in range(len(idx)):
new.append(mlist[idx[i]])
new[i].num=i+1
return new
# Create demo in root window for testing.
if __name__ == '__main__':
class App:
def my_show(self,*args,**kwargs):
pass
app = App()
app.root = Tkinter.Tk()
Pmw.initialise(app.root)
app.root.title('Some Title')
widget = Autodock(app)
exitButton = Tkinter.Button(app.root, text = 'Exit', command = app.root.destroy)
exitButton.pack()
app.root.mainloop()