Difference between revisions of "Autodock plugin"

From PyMOLWiki
Jump to navigation Jump to search
(Autodock Plugin)
 
 
(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 11: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
reinitialize 
fetch 3IG7, async=0
#load 3ig7.pdb, 3IG7
create cdk2, 3IG7 and polymer
create EFP, 3IG7 and organic and not resn ACE
delete 3IG7
 
hide everything, all
#h_add cdk2
#h_add EFP
show_as cartoon, cdk2
show_as sticks, EFP
util.cbay EFP
 
python
# The module "prepare_ligand4.py" does not like funny names of atoms, so we have to rename them
Ligand_prop = []
cmd.iterate("EFP", "Ligand_prop.append((resi, resn, name, elem, ID))")
for resi, resn, name, elem, ID in Ligand_prop:
    print("resi %s, resn %s, name %s, elem %s, ID %s"%(resi, resn, name, elem, ID))
    cmd.alter('%s and id %s'%(resn,ID),'name=%s%s%s'%('"',elem,'"'))
# To see the change, we rewrite the list.
Ligand_prop = []
cmd.iterate("EFP", "Ligand_prop.append((resi, resn, name, elem, ID))")
for resi, resn, name, elem, ID in Ligand_prop:
    print("resi %s, resn %s, name %s, elem %s, ID %s"%(resi, resn, name, elem, ID))
python end
select flexible, byres cdk2 within 3.5 of EFP
show sticks, flexible
util.cbag flexible
disable flexible

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
reinitialize 
fetch 1HXB, async=0
#load 1hxb.pdb, 1HXB
create HIV-1_PROTEINASE, 1HXB and polymer and not resn ROC
create ROC_A, 1HXB and resn ROC and alt a
create ROC_B, 1HXB and resn ROC and alt b
delete 1HXB
 
hide everything, all
#h_add cdk2
#h_add EFP
show_as cartoon, HIV-1_PROTEINASE
show_as sticks, ROC_A or ROC_B
util.cbay ROC_A
util.cbap ROC_B
 
select flexible_A, byres HIV-1_PROTEINASE within 3.5 of ROC_A
select flexible_B, byres HIV-1_PROTEINASE within 3.5 of ROC_B
show sticks, flexible_A or flexible_B
util.cbag flexible_A or flexible_B 
disable flexible_A or flexible_B

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.