Autodock plugin: Difference between revisions

From PyMOLWiki
Jump to navigation Jump to search
(Autodock Plugin)
 
No edit summary
 
(62 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{Infobox script-repo
|type      = plugin
|filename  = plugins/autodock_plugin.py
|author    = [[User:Dseelig|Daniel Seeliger]]
|license  = -
}}
== Description ==
== Description ==
This plugin should help to set up docking runs with Autodock and view docking results. It has two features:
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.
# Setup of a docking grid for Autodock with PyMOL.
 
# View the docking results.
2) View the docking results.


== Installation ==
== Installation ==
=== Linux ===
This plugin is ready "out-of-box" for Linux users through the project [[git_intro | Pymol-script-repo]]


1)Download [http://www.mpibpc.mpg.de/groups/grubmueller/start/people/dseelig/autodock.py plugin]
=== Windows ===
This plugin is ready "out-of-box" for win users through the project [[git_intro | Pymol-script-repo]]


2) PyMOL -> Plugin -> Install Plugin
You can download it manually
# Download [http://wwwuser.gwdg.de/~dseelig/adplugin.html plugin]
# '''PyMOL > Plugin > Install Plugin'''
# [http://autodock.scripps.edu/downloads/resources/adt/index_html MGLTools/AutoDockTools ]
# [http://autodock.scripps.edu/downloads/autodock-registration/autodock-4-2-download-page/ AutoDock4.2]
# [http://vina.scripps.edu/download.html AutoDock Vina]


== Author ==
== Tutorial Video ==


[[User:Dseelig|Daniel Seeliger]]
Watch Dan Seeliger's [http://wwwuser.gwdg.de/~dseelig/plugin_tutorial.html autodock plugin tutorial].


[[Category:Plugins]]
== Important ==
# The Autodock tools, does not like funny atoms names like "C1, N13, O28" and so on. Rename them! See example 1.
# Ligands can not be in alternative configuration. Create by: '''create ROC_A, 1HXB and resn ROC and alt a''' . See example 2.


<source lang="python">#!/usr/bin/env python
== Example 1 - Rename of funny atom names ==
Read about the protein here: http://www.proteopedia.org/wiki/index.php/3ig7 <br>
The example of video http://wwwuser.gwdg.de/~dseelig/plugin_tutorial.html <br>
Note, that the module "prepare_ligand4.py" does not like funny names of atoms, so we have to rename them


from __future__ import division
{{Template:PymolScriptRepoDownload|examples/autodock_plugin_1.pml}}
from __future__ import generators
<include src="https://raw.github.com/Pymol-Scripts/Pymol-script-repo/master/examples/autodock_plugin_1.pml" highlight="python" />


import os,math,re
Open the Autodock/Vina plugin. Check/set the executable to folders (they should be automatically found):
import Tkinter
Autodock Tools:      /home/you/another/pymol/Pymol-script-repo/modules/ADT/AutoDockTools/Utilities24
from Tkinter import *
autogrid4 executable: /home/you/another/pymol/Pymol-script-repo/modules/autodock_423/ia64Linux2/autogrid4                    # Platform dependent
import tkMessageBox
autogrid4 executable: /home/you/another/pymol/Pymol-script-repo/modules/autodock_423/ia64Linux2/autodock4                    # Platform dependent
import Pmw
vina executable:      /home/you/another/pymol/Pymol-script-repo/modules/autodock_vina/autodock_vina_1_1_2_linux_x86/vina      # Platform dependent
from pymol import cmd,selector
Working Directory:    /home/you/another/pymol/workingdir
import sys
Enlarge the window and click '''Save Plugin Configuration file'''. Plugin will not work, if you do not save.  
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...
Click tab '''Grid settings'''. In '''Calculate Grid Center by Selection''', write '''EFP'''. <br>
try:
Try clicking '''Wired Box''' in top right, and then '''Show Box''', '''Hide Box''', '''Cylindric Box''', '''Show Box'''.<br>
    True
Then push '''Select binding site'''. In PyMOL, write
except:
show sticks, binding_site
    True = 1
cmd.disable("binding_site")
try:
hide sticks, binding_site
    False
Click tab '''Receptor'''. Mark '''cdk''', and click '''Generate Receptor'''.<br>
except:
Click cdk2 to the "right", and see where the files are located.<br>
    False = 0
Click tab '''Ligands'''. Mark '''EFP''', and click '''EFP''' in the Ligand list. Here is the files stored. Click '''Generate Ligand'''<br>
#
Click tab '''Docking''', and click '''Run Vina'''. Wait 3-5 minutes, until '''Writing output ... done.'''<br>
# Cheap hack for testing purposes
Click tab '''View poses''', Browse to '''EFP.docked.pdbqt'''. Click '''Load''', '''Show best 10'''. Experiment with "Display options, and click the candidates"<br>
#
Congratulations, you did it!
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):
== Example 2 - Alternative configurations of a Ligand ==
        self.menuBar.addmenuitem('Plugin', 'command',
Read about the protein here: http://www.proteopedia.org/wiki/index.php/1hxb <br>
                                'Launch Autodock',
Ligands can not be in alternative configuration. Create by: create ROC_A, 1HXB and resn ROC and alt a .
                                label='Autodock...',
                                command = lambda s=self: Autodock(s))
       


 
{{Template:PymolScriptRepoDownload|examples/autodock_plugin_2.pml}}
<include src="https://raw.github.com/Pymol-Scripts/Pymol-script-repo/master/examples/autodock_plugin_2.pml" highlight="python" />


# set the defaults
== References and LICENSES ==
=== Vina ===
If you used AutoDock Vina in your work, [http://vina.scripps.edu/ please cite:]<br>
O. Trott, A. J. Olson, ''AutoDock Vina: improving the speed and accuracy of docking with a new scoring function, efficient optimization and multithreading'', '''Journal of Computational Chemistry''' 31 (2010) 455-461


defaults = {
=== MGLTOOLS ===
    "spacing" : '0.375',
LICENSE of MGLTOOLS:
    "xpst":'100',
<syntaxhighlight lang="text">
    "ypst":'100',
This software is copyrighted by Michel F. Sanner (sanner@scripps.edu) and TSRI.
    "zpts":'100',
The following terms apply to all files associated with the software
    "sel":'(all)',
unless explicitly disclaimed in individual files.
    "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'
    }
     


      MGLTOOLS SOFTWARE LICENSE AGREEMENT.


  1. Grant Of Limited License; Software Use Restrictions. The programs
    received by you will be used only for NON COMMERCIAL purposes.
    This license is issued to you as an individual.


class FileDialogButtonClassFactory:
    For COMMERCIAL use done with the software please contact Michel F.
    def get(fn,filter='*'):
    Sanner for details about commercial usage license agreements.
        """This returns a FileDialogButton class that will
   
        call the specified function with the resulting file.
    For any question regarding license agreements, please contact
        """
            Michel Sanner:
        class FileDialogButton(Tkinter.Button):
    TSRI, Molecular Biology Department, TCP 26,
            # This is just an ordinary button with special colors.
    10550 North Torrey Pines Road, La Jolla, CA 92037
    sanner@scripps.edu
    tel (858) 784-7742
    fax (858) 784-2341


            def __init__(self, master=None, cnf={}, **kw):
  2. COMMERCIAL USAGE is defined as revenues generating activities. These
                '''when we get a file, we call fn(filename)'''
    include using this software for consulting activities and selling
                self.fn = fn
    applications built on top of, or using this software. Scientific
                self.__toggle = 0
    research in an academic environment and teaching are considered
                apply(Tkinter.Button.__init__, (self, master, cnf), kw)
    NON COMMERCIAL.
                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)


  3. Copying Restrictions. You will not sell or otherwise distribute commercially
    these programs or derivatives to any other party, whether with or without
    consideration.


  4. Ownership of Software. You will not obtain, and will not attempt to
    obtain copyright coverage thereon without the express purpose written
    consent of The Scripps Research Institute and Dr. Sanner.


  5. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
    FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
    ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
    DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
    POSSIBILITY OF SUCH DAMAGE.


  6. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
    IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
    NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
    MODIFICATIONS.
</syntaxhighlight>


       
[[Category:Plugins]]
class Autodock:
[[Category:Pymol-script-repo]]
 
    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()
</source>

Latest revision as of 10:12, 15 January 2012

Type PyMOL Plugin
Download plugins/autodock_plugin.py
Author(s) Daniel Seeliger
License -
This code has been put under version control in the project Pymol-script-repo

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

Linux

This plugin is ready "out-of-box" for Linux users through the project Pymol-script-repo

Windows

This plugin is ready "out-of-box" for win users through the project Pymol-script-repo

You can download it manually

  1. Download plugin
  2. PyMOL > Plugin > Install Plugin
  3. MGLTools/AutoDockTools
  4. AutoDock4.2
  5. AutoDock Vina

Tutorial Video

Watch Dan Seeliger's autodock plugin tutorial.

Important

  1. The Autodock tools, does not like funny atoms names like "C1, N13, O28" and so on. Rename them! See example 1.
  2. Ligands can not be in alternative configuration. Create by: create ROC_A, 1HXB and resn ROC and alt a . See example 2.

Example 1 - Rename of funny atom names

Read about the protein here: http://www.proteopedia.org/wiki/index.php/3ig7
The example of video http://wwwuser.gwdg.de/~dseelig/plugin_tutorial.html
Note, that the module "prepare_ligand4.py" does not like funny names of atoms, so we have to rename them

Download: examples/autodock_plugin_1.pml
This code has been put under version control in the project Pymol-script-repo

<include src="https://raw.github.com/Pymol-Scripts/Pymol-script-repo/master/examples/autodock_plugin_1.pml" highlight="python" />

Open the Autodock/Vina plugin. Check/set the executable to folders (they should be automatically found):

Autodock Tools:       /home/you/another/pymol/Pymol-script-repo/modules/ADT/AutoDockTools/Utilities24
autogrid4 executable: /home/you/another/pymol/Pymol-script-repo/modules/autodock_423/ia64Linux2/autogrid4                     # Platform dependent
autogrid4 executable: /home/you/another/pymol/Pymol-script-repo/modules/autodock_423/ia64Linux2/autodock4                     # Platform dependent
vina executable:      /home/you/another/pymol/Pymol-script-repo/modules/autodock_vina/autodock_vina_1_1_2_linux_x86/vina      # Platform dependent
Working Directory:    /home/you/another/pymol/workingdir

Enlarge the window and click Save Plugin Configuration file. Plugin will not work, if you do not save.

Click tab Grid settings. In Calculate Grid Center by Selection, write EFP.
Try clicking Wired Box in top right, and then Show Box, Hide Box, Cylindric Box, Show Box.
Then push Select binding site. In PyMOL, write

show sticks, binding_site
cmd.disable("binding_site")
hide sticks, binding_site

Click tab Receptor. Mark cdk, and click Generate Receptor.
Click cdk2 to the "right", and see where the files are located.
Click tab Ligands. Mark EFP, and click EFP in the Ligand list. Here is the files stored. Click Generate Ligand
Click tab Docking, and click Run Vina. Wait 3-5 minutes, until Writing output ... done.
Click tab View poses, Browse to EFP.docked.pdbqt. Click Load, Show best 10. Experiment with "Display options, and click the candidates"
Congratulations, you did it!

Example 2 - Alternative configurations of a Ligand

Read about the protein here: http://www.proteopedia.org/wiki/index.php/1hxb
Ligands can not be in alternative configuration. Create by: create ROC_A, 1HXB and resn ROC and alt a .

Download: examples/autodock_plugin_2.pml
This code has been put under version control in the project Pymol-script-repo

<include src="https://raw.github.com/Pymol-Scripts/Pymol-script-repo/master/examples/autodock_plugin_2.pml" highlight="python" />

References and LICENSES

Vina

If you used AutoDock Vina in your work, please cite:
O. Trott, A. J. Olson, AutoDock Vina: improving the speed and accuracy of docking with a new scoring function, efficient optimization and multithreading, Journal of Computational Chemistry 31 (2010) 455-461

MGLTOOLS

LICENSE of MGLTOOLS:

This software is copyrighted by Michel F. Sanner (sanner@scripps.edu) and TSRI.
The following terms apply to all files associated with the software 
unless explicitly disclaimed in individual files.

       MGLTOOLS SOFTWARE LICENSE AGREEMENT.

  1. Grant Of Limited License; Software Use Restrictions. The programs
     received by you will be used only for NON COMMERCIAL purposes.
     This license is issued to you as an individual.

     For COMMERCIAL use done with the software please contact Michel F. 
     Sanner for details about commercial usage license agreements.
     
     For any question regarding license agreements, please contact
             Michel Sanner:
	     TSRI, Molecular Biology Department, TCP 26,
	     10550 North Torrey Pines Road, La Jolla, CA 92037
	     sanner@scripps.edu
	     tel (858) 784-7742
	     fax (858) 784-2341

  2. COMMERCIAL USAGE is defined as revenues generating activities. These
     include using this software for consulting activities and selling
     applications built on top of, or using this software. Scientific 
     research in an academic environment and teaching are considered 
     NON COMMERCIAL.

  3. Copying Restrictions. You will not sell or otherwise distribute commercially 
     these programs or derivatives to any other party, whether with or without 
     consideration.

  4. Ownership of Software. You will not obtain, and will not attempt to 
     obtain copyright coverage thereon without the express purpose written 
     consent of The Scripps Research Institute and Dr. Sanner.

  5. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
     FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
     ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
     DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
     POSSIBILITY OF SUCH DAMAGE.

  6. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
     FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
     IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
     NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
     MODIFICATIONS.