raccoon.py 0000664 0001753 0001765 00000654122 12111754112 013320 0 ustar entropia entropia #!/usr/bin/env python
#
# Raccoon
#
# Tk Virtual Screening Interface for AutoDock
#
# v.1.0.0 Stefano Forli
#
# Copyright 2009, Molecular Graphics Lab
# The Scripps Research Institute
#
#
#################################################################
#
# Hofstadter's Law: It always takes longer than you expect,
# even when you take Hofstadter's Law
# into account.
#
# The Guide is definitive. Reality is frequently inaccurate.
# Douglas Adams
#
#################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
#
#
version = "1.0 "
# enable the Debug mode by setting this to "True"
DEBUG = False
import glob
import os
from Tkinter import *
from tkFileDialog import askopenfilename, askdirectory, asksaveasfilename
import tkMessageBox
import Pmw
import Tkinter
import tarfile
import zipfile
import platform
import shutil # for shutil.copy2
import string
import datetime
from base64 import b64decode
from random import sample # potentially useless
from random import choice
from numpy import sqrt
try:
# MolKit stuff
# from the prepare_ligand code
from MolKit import Read
from AutoDockTools.MoleculePreparation import AD4LigandPreparation, AD4ReceptorPreparation, AD4FlexibleReceptorPreparation
# from the prepare_gpf code
from AutoDockTools.GridParameters import GridParameters, grid_parameter_list4
from AutoDockTools.GridParameters import GridParameter4FileMaker
from AutoDockTools.atomTypeTools import AutoDock4_AtomTyper
# from the prepare_flexres code
from MolKit.protein import ProteinSet, ResidueSet
from MolKit.molecule import BondSet
from MolKit.stringSelector import CompoundStringSelector
from AutoDockTools.MoleculePreparation import AD4FlexibleReceptorPreparation
except:
#print "I'm sorry, MolKit is required for running Raccooon"
tkMessageBox.showerror("MolKit error!", ("Impossible to find the MolKit module.\n\nMGLTools is required to run Raccoon but is either \
misconfigured or not installed.\n\nPlease install it, or try to run Raccoon with:\n\n $MGLROOT/bin/pythonsh raccoon.py"))
exit(1)
try:
# from the prepare_dpf code
from AutoDockTools.DockingParameters import DockingParameters, genetic_algorithm_list4_2, \
genetic_algorithm_local_search_list4_2, local_search_list4_2,\
simulated_annealing_list4_2
except:
tkMessageBox.showerror("MGL Tools error!", ("Raccoon needs a version of MGLTools\n\n>= 1.5.4."))
exit(1)
LOGO_BASE64='''\
R0lGODlhXgFFAPcAAAAAAA4ODg8BABIAAB4AABEPEBERERsbGw8NEB8hICIAAC4AAjAAAT0AAC0b
GiIiIiwsLCcpKDIyMjw8PC4wLyEfIEEAAE4AAFcAAWYAAXEAAHsCA1cvLUA+QUJCQkxMTEZIR1JS
UlxcXFdZWFBQT19gYmJiYmtra2lpZXFwbnJycnx8fHl5dW5vb2BgXjtO+TtS7TpV6ztT9TRL60JM
/EJZ7ERV8kRU/URa/UlV9UpV/EtZ9Uxa+kRZ81Jb/FRa+0ti/U1p/Epj9VNj/lNq/Vps/lhl+VRx
/lxz/V16/lJm7mF0/mN7/Wp8/mZy93J8/GNp/3+AgmWB/WuE/W6I/XOF/XOL/XmO/nqG9nuT/XeS
/YQBAZcAAJUyMqkAAKkWFrQAALsBAboJCrUXFqolJac2N7MoKLQyMrk2Nq0wL65AP5dVVpBxcqpG
RqtWVbRISLdXVrNQT7FgXKdoZ6V6ebpjY7p5ebdvb8IAAcwAAcgJCckZGNQAAdsAAdoLC9kJCdYQ
DtQUE9MYF9MNEM8eIcE6OdIiIuMBAesAAOAHCPIAAP0AAP4ODv8SEc8gHcNWVspmZtF5eNpVVoB/
grt/gYGAfoGBgYyMjIeHiJOTk5ycnJyWlZKOjp+goqSbmreHh7SPj6KgnaOjo6ysrKinp7Snp7Gu
sLOzs729vbi4uK6vsJ6gn4SL+oWa/Yqc/YaU/ZKd/pWY/Yyi/pOj/puk/pur/pam+J6y/L6+waOr
/ams/qSm/KOy/auz/q26/Ki197S7/bm9/LC1/b3AwLzF+7zK/bbC+7/Q/sSHh9GQkMimp8S5uNax
s+Kur8agn8TDv8PCw8vLy8jHxs7Qzc/Q0tHNzdrFwtDRztPT09vb29fX18/O08PL/MrN/cLF/MzS
/cvU+tLV/dTZ/Nrc/dDV9d7f4d7g3tzh/dTh/t/g4uPc2+jFxuDf7+Hh3uPj4+zr7Ofn6OLk/OXp
/ers/O3w7uzx/evy+PDu7vDu9fDw7fPz8/P0/fX5/Pn2+/7+/vj49iH5BAAAAAAALAAAAABeAUUA
AAj+AP0JHEiwoMGDBvshXMiwocOHECNKnEixosWLGDNq3Mhx4j+CHwuGPDiyo8mTKFOqXMmypUuN
JV/KnEmzps2bDRXWPPeNG7hz9vbx+1gyJs6jSJMqhejO3TudK/W9m6oPqktwtWrdusXLWLGv6OrV
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
'''
# System identification
system_info = platform.uname()
if DEBUG: print system_info
system = system_info[0]
root = Tk()
root.title('Raccoon | AutoDock VS')
Pmw.initialise()
nb = Pmw.NoteBook(root)
p1 = nb.add('Ligand(s)')
p2 = nb.add('Receptor(s)')
p3 = nb.add('Maps')
p4 = nb.add('Docking')
p5 = nb.add('VS Generation')
nb.pack(padx=3, pady=5, fill=BOTH, expand=1)
# Font settings
## Courier-related settings
if system == "Windows":
courier = "Courier New"
courier_size = "6"
cygwin = BooleanVar()
cygwin.set(False)
else:
courier = "Courier"
courier_size = "9"
courier_style = "roman"
# For the hand-breake function
StopImmediately = BooleanVar()
StopImmediately.set(False)
receptorFileList = []
DirJournal = []
# Ligand preparation options
# AutoDock atom type list
# this dictionary is updated with the atom types found
# in the selected ligands, and used to evaluate dir's
# of cached maps
## Warning: atomic weights are inaccurate and there
# is no account for merged non-polar H's
#
#
# TODO check for more accurate atomic weights
AtypeList = { # count MW
'H' : [ 0, 1 ],
'HD' : [ 0, 1 ],
'HS' : [ 0, 1 ],
'C' : [ 0, 12 ],
'A' : [ 0, 12 ],
'N' : [ 0, 14 ],
'NA' : [ 0, 14 ],
'NS' : [ 0, 14 ],
'OA' : [ 0, 16 ],
'OS' : [ 0, 16 ],
'F' : [ 0, 19 ],
'Mg' : [ 0, 24 ],
'MG' : [ 0, 24 ],
'P' : [ 0, 31 ],
'SA' : [ 0, 32 ],
'S' : [ 0, 32 ],
'Cl' : [ 0, 35.4 ],
'CL' : [ 0, 35.4 ],
'Ca' : [ 0, 40 ],
'CA' : [ 0, 40 ],
'Mn' : [ 0, 55 ],
'MN' : [ 0, 55 ],
'Fe' : [ 0, 56 ],
'FE' : [ 0, 56 ],
'Zn' : [ 0, 65.4 ],
'ZN' : [ 0, 65.4 ],
'Br' : [ 0, 80 ],
'BR' : [ 0, 80 ],
'I' : [ 0, 126 ],
'e' : [ 1, 0 ], # always 1 by default
'd' : [ 1, 0 ] # always 1 by default
}
# The Great Book of Ligands
LigandDictionary = {}
# its general structure is:
# {'filename' : {
# "Atypes" : list
# "TORSDOF" : int
# "HbD" : int
# "HbA" : int
# "MW" : float
# "Nat" : int
# "NotStdAT" : bool
# "accepted" : bool }
# }
ResidueRotatableBondTable = {
'GLY' : [ 0, [""] ],
'ALA' : [ 0, [""] ],
'PRO' : [ 0, [""] ],
'VAL' : [ 1, ["C"] ],
'LEU' : [ 2, ["C"] ],
'SER' : [ 2, ["C", "OA", "HD"] ],
'THR' : [ 2, ["C", "OA", "HD"] ],
'CYS' : [ 2, ["C", "SA", "HD"] ],
'ASN' : [ 2, ["", "", ""] ],
'PHE' : [ 2, ["A", "C"] ],
'TRP' : [ 2, ["C", "A", "N", "HD"] ],
'HIE' : [ 2, ["C", "A", "NA", "N", "HD"] ],
'HIS' : [ 2, ["C", "A", "NA", "N", "HD"] ],
'ASP' : [ 2, ["C", "OA"] ],
'ILE' : [ 2, ["C"] ],
'GLN' : [ 3, ["C", "OA","N","HD"] ],
'TYR' : [ 3, ["C", "A", "OA", "HD"] ],
'GLU' : [ 3, ["C", "OA"] ],
'MET' : [ 3, ["C", "S"] ],
'ARG' : [ 4, ["C", "N", "HD"] ],
'LYS' : [ 5, ["C", "N", "HD"] ] }
# Filtering preview labels
TotalNumberLigandsMsg = StringVar()
TotAcceptedLigandsMsg = StringVar()
TotRejectedLigandsMsg = StringVar()
TotalAcceptedLigands = IntVar()
AutoDockMaxTORSDOF = IntVar()
AutoDockMaxTORSDOF.set(32)
FlexResTORSDOF = IntVar()
FlexResTORSDOF.set(0)
FlexResTypes = []
seriously = BooleanVar() # filtering or just previewing
DoRejectATypes = BooleanVar()
DoRejectATypes.set(True)
HbDmin = IntVar() # HydBond DONOR
HbDmin.set(0)
HbDmax = IntVar()
HbDmax.set(99)
HbAmin = IntVar() # HydBond ACCEPTOR
HbAmin.set(0)
HbAmax = IntVar()
HbAmax.set(99)
MWmin = IntVar() # Molecular weight
MWmin.set(0)
MWmax = IntVar()
MWmax.set(9999)
NatMin = IntVar() # Number of heavy atoms
NatMin.set(0)
NatMax = IntVar()
NatMax.set(999)
TORSDOFmin = IntVar()
TORSDOFmin.set(0)
TORSDOFmax = IntVar()
TORSDOFmax.set(32)
FilterSet = StringVar()
FilterSet.set("Default")
# Grid settings
AutoGridBin = StringVar()
AutoGridBin.set("")
GPFkeywords = [
'npts',
'parameter_file',
'gridfld',
'spacing',
'receptor_types',
'ligand_types',
'receptor',
'gridcenter',
'smooth',
'map',
'elecmap',
'dsolvmap',
'dielectric'
]
mapDir = None # The path of the cached maps
GPFParameterFile = StringVar()
DPFParameterFile = StringVar()
DPFkeywords = [
'autodock_parameter_version',
'outlev',
'parameter_file',
'intelec',
'seed',
'ligand_types',
'fld',
'map',
'elecmap',
'desolvmap',
'move',
'about',
'axisangle0',
'tran0',
'quat0',
'dihe0',
'ndihe',
'tstep',
'qstep',
'dstep',
'torsdof',
'unbound',
'rmstol',
'extnrg',
'e0max',
'ga_pop_size',
'ga_num_evals',
'ga_num_generations',
'ga_elitism',
'ga_mutation_rate',
'ga_crossover_rate',
'ga_window_size',
'ga_cauchy_alpha',
'ga_cauchy_beta',
'output_pop_file',
'set_ga',
'sw_max_its',
'sw_max_succ',
'sw_max_fail',
'sw_rho',
'sw_lb_rho',
'ls_search_freq',
'set_sw1',
'set_psw1',
'ga_run',
'analysis'
]
# Default DPF
default_docking_parameter_file = """autodock_parameter_version 4.2 # used by autodock to validate parameter set
outlev 1 # diagnostic output level
intelec # calculate internal electrostatics
seed pid time # seeds for random generator
ligand_types HD OA # atoms types in ligand
fld receptor.maps.fld # grid_data_file
map receptor.HD.map # atom-specific affinity map
map receptor.OA.map # atom-specific affinity map
elecmap receptor.e.map # electrostatics map
desolvmap receptor.d.map # desolvation map
move ligand.pdbqt # small molecule
about 0.378 0.6623 0.648 # small molecule center
tran0 random # initial coordinates/A or random
axisangle0 random # initial orientation
dihe0 random # initial dihedrals (relative) or random
tstep 2.0 # translation step/A
qstep 50.0 # quaternion step/deg
dstep 50.0 # torsion step/deg
torsdof 0 # torsional degrees of freedom
rmstol 2.0 # cluster_tolerance/A
extnrg 1000.0 # external grid energy
e0max 0.0 10000 # max initial energy; max number of retries
ga_pop_size 150 # number of individuals in population
ga_num_evals 2500000 # maximum number of energy evaluations
ga_num_generations 27000 # maximum number of generations
ga_elitism 1 # number of top individuals to survive to next generation
ga_mutation_rate 0.02 # rate of gene mutation
ga_crossover_rate 0.8 # rate of crossover
ga_window_size 10 #
ga_cauchy_alpha 0.0 # Alpha parameter of Cauchy distribution
ga_cauchy_beta 1.0 # Beta parameter Cauchy distribution
set_ga # set the above parameters for GA or LGA
sw_max_its 300 # iterations of Solis & Wets local search
sw_max_succ 4 # consecutive successes before changing rho
sw_max_fail 4 # consecutive failures before changing rho
sw_rho 1.0 # size of local search space to sample
sw_lb_rho 0.01 # lower bound on rho
ls_search_freq 0.06 # probability of performing local search on individual
set_psw1 # set the above pseudo-Solis & Wets parameters
unbound_model bound # state of unbound ligand
ga_run 10 # do this many hybrid GA-LS runs
analysis # perform a ranked cluster analysis"""
# Ligand Import default options
LigandListLabel = StringVar()
LigandListLabel.set('Import ligands...')
# PrepareLigand options defaults
ChargeSet = StringVar()
ChargeSet.set("gasteiger")
Repair = StringVar()
Repair.set("")
Cleanup = StringVar()
Cleanup.set("nphs_lps")
BackboneRotatable = BooleanVar()
BackboneRotatable.set(True)
AmideRotatable = BooleanVar()
AmideRotatable.set(False)
GuanidiniumRotatable = BooleanVar()
GuanidiniumRotatable.set(False)
LargestFrag = BooleanVar()
LargestFrag.set(False)
AttachFrag = BooleanVar()
AttachFrag.set(False)
LockTors = BooleanVar()
LockTors.set(False)
LIGAND_SET = False # define if ligand filenames have been set
#### Receptor options
# default receptor structure multiplicity (one/many)
TargetPDBQT = StringVar()
RCstatus = IntVar()
RCstatus.set(0) # Initial option is "single conformation
RecFilename = StringVar()
RecFilename.set("[ none ]")
# Variables defining if either the single or the multiple receptor
# conformations have been defined
SingleReceptorSet = BooleanVar()
SingleReceptorSet.set(False)
MultiReceptorSet = BooleanVar()
MultiReceptorSet.set(False)
RecChargeSet = StringVar()
RecChargeSet.set('gasteiger')
RecCleanNPH = StringVar()
RecCleanNPH.set("_nphs")
RecCleanLP = StringVar()
RecCleanLP.set("_lps")
RecCleanWAT = StringVar()
RecCleanWAT.set("_waters")
RecCleanStdRes = BooleanVar()
RecCleanStdRes.set(False)
RecDelAlternate = StringVar()
RecDelAlternate.set("")
RecRepairOptionsSet = StringVar()
RecRepairOptionsSet.set("add H (if missing)")
# default flexible residues (y/n)
FlexResDefined = BooleanVar()
DoFlex = IntVar()
DoFlex.set(0)
DoFlexFromWhat = IntVar()
DoFlexFromWhat.set(-1) # values are 1 for "from file" and 2 "from selection"
FlexResFileName = StringVar()
FlexResFileName.set("")
ResidueStatusLoaded = StringVar()
ResidueStatusSelected = StringVar()
ResidueStatusLoaded.set("")
ResidueStatusSelected.set("")
ResidueStatus = StringVar()
ListFlexResiduesNames = StringVar()
FlexResSelected = StringVar()
### AutoGrid options
AutoGridWhen1, AutoGridWhen2, AutoGridWhen3 = None, None, None
GPFfilename = StringVar()
GPFfilename.set("[ no GPF loaded ]")
CacheMapDirName = StringVar()
CacheMapDirName.set("[ none ]")
mapFileList = []
MapSource = IntVar()
MapSource.set(0)
CacheMapPolicy = StringVar()
CacheMapFrame, GPFframe, CacheMapHandleNow, CacheMapHandle = None, None, None, None
# values for DoCachedMaps
# 0 : no maps defined
# 1 : maps defined and checked
DoCachedMaps = BooleanVar()
# Docking menu params
dockMenuSettings = None
DPFfilename = StringVar()
DPFfilename.set("[ no DPF loaded ]")
DPFedit, DPFcontent = None, None
# Docking/DPF default settings
DPFgroupTemplate, DPFgroupSimple, DPFgroupSmart, DPFgroupTemplate, DPFgroupComplex = None, None, None, None, None
DPF_group = None
DPF_INFO = None
InfoFrame = None
DockMenuSetting = None
DPFSpeed = IntVar()
Info = None
numGen = None
EnEval = None
simple_settings = None
simple_settings_info = None
EnEval = None
OpenDPF = None
docking_set = None
CheckTDOF = None
CheckVOL = None
complex_gen_info = None
complex_eval_info = None
# Final destination directory
JobDirectory = StringVar()
JobDirectory.set("")
JobDirectoryInfo = StringVar()
JobDirectoryInfo.set("")
# System options
TargetOS = StringVar()
TargetOS.set("lin")
LinuxScriptLevel = StringVar()
LinuxScriptLevel.set("master script for starting the VS")
PBStime = StringVar()
PBStime.set("24:00:00")
PBShowmanyruns = IntVar()
PBShowmanyruns.set(1)
TarFile = StringVar()
TarFile.set('[disabled]')
# Load session defaults
LoadLig = BooleanVar()
LoadLig.set(True)
LoadFilter = BooleanVar()
LoadFilter.set(True)
LoadRec = BooleanVar()
LoadRec.set(True)
LoadFlex = BooleanVar()
LoadFlex.set(True)
LoadMap = BooleanVar()
LoadMap.set(True)
LoadDock = BooleanVar()
LoadDock.set(True)
LoadGen = BooleanVar()
LoadGen.set(True)
# Save session defaults
SaveLig = BooleanVar()
SaveLig.set(True)
SaveFilter = BooleanVar()
SaveFilter.set(True)
SaveRec = BooleanVar()
SaveRec.set(True)
SaveFlex = BooleanVar()
SaveFlex.set(True)
SaveMap = BooleanVar()
SaveMap.set(True)
SaveDock = BooleanVar()
SaveDock.set(True)
SaveGen = BooleanVar()
SaveGen.set(True)
RecStatus = "[ not yet selected ]"
# Summary page variables
LigandSummary = StringVar()
ReceptorSummary = StringVar()
MapsSummary = StringVar()
DockingSummary = StringVar()
JobsSummary = StringVar()
LigandSummary.set(( " [ none ] "))
ReceptorSummary.set( " [ none ] " )
MapsSummary.set((" [ none ] "))
DockingSummary.set(" [ none ] ")
JobsSummary.set(" ")
def InfoInit():
global InfoMessage, InfoBar, InfoText
# Initialize the info-bar at the bottom of the root
InfoMessage = StringVar()
InfoText = Label(root, textvariable = InfoMessage, font=("Helvetica", 10))
InfoText.pack(padx = 2, pady = 2, expand='no', fill='x')
InfoMessage.set('Welcome to Raccoon | AutoDock VS')
def raccoon():
data = [
"UilvYnVzdCBBKXV0b0RvY2sgQyloZW1pY2FsIEMpb21wb3VuZCBPKXJnYW5pemF0aW9uIGFuZCBPKXB0aW1pemF0aW9uIE4pb3RlYm9vaw==",
"Uil1bm5pbmcgQSlmdGVyIEMpaGVtaWNhbCBDKWhpbWVyYXMgTyl2ZXIgTylic2N1cmUgTilpbWJp",
"UilvbWFudGljbHkgQSlkZGljdGVkIEMpYWxjdWxhdGlvbnMgQylhcmVmdWxseSBPKWZmZXJpbmcgTylwZW5pbmcgTilvdmVsdGllcw==",
"UilhcGlkIEEpdXRvbWF0aWMgQylyZWF0aW9uIG9mIEMpbHVzdGVycyBPKWNjYXNpb25hbGx5IE8pYnNlcnZlZCBpbiBOKWF0dXJl",
"UilldHVybmluZyBBKWJyb3VwdGx5IGEgQyktc2hlbGwgQylvbW1hbmQgTyl1dHB1dCBPKXBlcmF0aXZlbHkgTil1bGxpZmllZA==",
"UillZnJhaW4gQSlic3RydXNlIEMpb21tb24gQylvbXB1dGF0aW9ucyBPKWZ0ZW4gTylwZXJhdGlvbmFsbHkgTilveGlvdXM=",
"UillbGVhc2luZyBBKWxsZWdlZGx5IEMpcml0aWNhbCBDKW9tcHJlc3Npb25zIE8pdmVya2lsbHMgTylic3RydWN0ZWQgTillZWRz",
"Uillc3RsZXNzIEEpbmltYWwgQylyYXZpbmcgQyloZW1pY2FscyBPKXV0IE8pZiBOKW93aGVyZQ==",
"UilldHJpZXZpbmcgQSltYXppbmcgQylvbXBvdW5kcyBPKXZlcndoZWxtcyBPKXV0Y3J5aW5nIE4pdW1iZXJz",
"Uil1biBBKXV0b2RvY2ssIEMpaGVjayBDKWx1c3RlcnMsIE8pYnNlcnZlLCBPKXJkZXIgYW5kIE4pb2Q=",
"UilldmVhbGluZyBBKW5vdGhlciBDKW9tcG91bmQgQylhbiBPKWNjdXIgTyliZWRpZW50bHkgTilvdw==",
"UilhY2Nvb24gQSl1dG9tYXRlIEMpb21wdXRhdGlvbmFsIEMpaGVtaXN0cnkgTylwZXJhdGlvbnMgTyluIE4pb2Rlcw==",
"UillbWFyY2FibGUgQSljdGlvbnMgQylvbnN0YW50bHkgQyl1dCBPKWZmIE8pYm5veGlvdXMgTillZ290aWF0aW9ucw==",
"UillZHVuZGFudCBBKWN0aW9ucyBDKWxlYXJseSBDKWF1c2UgTyl2ZXItcHJvZHVjdGlvbiBPKWYgTilvaXNl",
"UilldmlldyBBKWxsIEMpb25zdGFudHMsIEMpaGVjayBPKXV0IE8pcHByZXNzZWQgTil1bWJlcnM=",
"UillbWVtYmVyOiBBKW55IEMpb25jZXB0IEMpb3VsZCBPKXV0c3RhbmQuLi4gTylyIE4pb3Q="
]
return "\n"+b64decode(data[choice(range(0, len(data)))])+"\n"
def about():
GNU=""" This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
"""
logo = StringVar()
logo.set(""" ________________________________________________________________
__________//___________________________/////___________________/____________
_________/__/__________________________/____/__________________/____________
________/____/___________/_____________/_____/_________________/____________
________/____/__/_____/_/////___/////__/_____/__/////___/////__/___/________
_______/______/_/_____/__/_____/_____/_/_____/_/_____/_/_____/_/_//_________
_______////////_/_____/__/_____/_____/_/_____/_/_____/_/_______//_/_________
_______/______/_/____//__/___/_/_____/_/____/__/_____/_/_____/_/___/________
_______/______/__////_/___///___/////__/////____/////___/////__/____/_______
________________________________________________________________
______
/ \\
/ \\
/ \\
\\ /\\ /
\\ / \\ /
\\/ /\\ \\/
/\\ \\
/\\ \\__\\
/ \\__\\
/____\\
______________________________________
| |
| Raccoon | AutoDock VS |
| version %4s |
| (c) 2009 |
| The Scripps Research Institute |
| |
| Stefano Forli, TSRI |
| Ruth Huey, TSRI |
|______________________________________|""" % version )
AboutWin = Toplevel(root)
AboutWin.title("About Raccoon | AutoDockVS")
AboutWin.winfo_toplevel().resizable(NO,NO)
Label(AboutWin, textvar = logo, font = (courier, courier_size, ), justify = LEFT ).pack()
Frame(AboutWin, height = 2, bd = 1, relief = SUNKEN).pack(fill = X, padx = 5 , pady = 3)
Label(AboutWin, text = " "+raccoon()+" ", justify = LEFT, font = ('Courier', 10, 'bold')).pack()
Frame(AboutWin, height = 2, bd = 1, relief = SUNKEN).pack(fill = X, padx = 5 , pady = 3)
Label(AboutWin, text = "Manual pages and version updates could be *potentially* found at this address:", font = ('Helvetica', 9, 'roman')).pack()
Label(AboutWin, text = "http://www.scripps.edu/~forli/").pack(padx = 5)
Button(AboutWin, height = 2, text = "Close", command = lambda: AboutWin.destroy()).pack(fill = X, padx = 15, pady = 3, anchor = S, side = BOTTOM )
return
def makemenu(win):
top = Menu(win)
win.config(menu=top)
file = Menu(top, tearoff=0)
file.add_command(label='Load VS configuration...',command=LoadLogWindow, underline=0)
file.add_command(label='Save VS configuration...',command=SaveLogWindow, underline=0)
file.add_separator()
file.add_command(label='Import ligand list file...',command=ImportLigList, underline=0)
file.add_command(label='Export ligand list file...',command=ExportLigList, underline=0)
file.add_separator()
file.add_command(label='Quit', command=confirm, underline=0)
top.add_cascade(label='File', menu=file, underline=0)
setup = Menu(top, tearoff=0)
setup.add_command(label='Split a MOL2', command=SplitMol2, underline=0)
top.add_cascade(label='Utilities', menu=setup, underline=0)
help = Menu(top, tearoff=0)
help.add_command(label='About Raccoon', command=about, underline=0)
top.add_cascade(label='Help', menu=help, underline=0)
def LoadLogWindow():
def Done():
LoadOptWin.destroy()
LoadLog(logname)
DisableInterface()
logname = askopenfilename(parent = root, title = "Select a Raccoon log to load...", filetypes=[("Raccoon Log", "*.log")])
if not logname:
EnableInterface()
return False
DisableInterface()
LoadOptWin = Toplevel(root)
LoadOptWin.title("LOAD session")
LoadOptWin.winfo_toplevel().resizable(NO,NO)
Label(LoadOptWin, text = "Select data to be imported\nfrom the file:", justify = LEFT).grid(row = 1, column = 0, columnspan = 3, sticky = N, padx = 5, pady = 5)
Checkbutton(LoadOptWin, text = "Ligands list", variable = LoadLig).grid(row = 2, column = 1, columnspan = 2, sticky = W)
Checkbutton(LoadOptWin, text = "Filter set", variable = LoadFilter).grid(row = 3, column = 1, columnspan = 2, sticky = W, padx = 15)
Checkbutton(LoadOptWin, text = "Receptors list", variable = LoadRec).grid(row = 4, column = 1, columnspan = 2, sticky = W)
Checkbutton(LoadOptWin, text = "Flexible residues", variable = LoadFlex).grid(row = 5, column = 1, columnspan = 2, sticky = W, padx = 15)
Checkbutton(LoadOptWin, text = "Map parameters", variable = LoadMap).grid(row = 6, column = 1, columnspan = 2, sticky = W)
Checkbutton(LoadOptWin, text = "Docking parameters", variable = LoadDock).grid(row = 7, column = 1, columnspan = 2, sticky = W)
Button(LoadOptWin, text = "OK", command = Done).grid(row = 10, column = 1, columnspan = 1, sticky = W, padx = 10, pady= 10)
Button(LoadOptWin, text = "Cancel", command = lambda: LoadOptWin.destroy()).grid(row = 10, column = 2, sticky = W, padx = 10, pady= 10)
EnableInterface()
def LoadLog(logname):
# DEBUG = True
if LoadLig.get() + LoadRec.get() + LoadFlex.get() + LoadMap.get() + LoadDock.get() + LoadGen.get() + LoadFilter.get() == 0:
return
logfile = open(logname, 'r').readlines()
# Check that is an original Raccoon(TM) LogFile(TM)
# with an advanced and sofisticated text scanning...
raccoon, virtual, screening = False, False, False
for line in logfile:
if "Raccoon" in line:
raccoon = True
if "Virtual" in line:
virtual = True
if "Screening" in line:
screning = True
if raccoon:
if virtual:
if screening:
pass
else:
tkMessageBox.showerror("Error!", ("The loaded file is not a Raccoon VS file"))
return False
if DEBUG: print logfile[-1]
################################
# Start importing all the params
################################
# Load the filters
if LoadFilter.get():
try:
for index in range(38, 44):
logfile[index] = logfile[index].rsplit() # clean up the line from space and \n's
if DEBUG: print "LOAD_SESSION: filter params => ", logfile[index]
# Hb donor max-min
HbDmin.set(int(logfile[38][-3])), HbDmax.set(int(logfile[38][-1]))
# Hb acceptor max-min
HbAmin.set(int(logfile[39][-3])), HbAmax.set(int(logfile[39][-1]))
# MW max-min
MWmin.set(int(logfile[40][-3])), MWmax.set(int(logfile[40][-1]))
# Nat max-min
NatMin.set(int(logfile[41][-3])), NatMax.set(int(logfile[41][-1]))
# TORSDOF max-min
TORSDOFmin.set(int(logfile[42][-3])), TORSDOFmax.set(int(logfile[42][-1]))
# Filter non-AD atom types
if logfile[43][-1] == "True":
DoRejectATypes.set(True)
else:
DoRejectATypes.set(False)
except:
tkMessageBox.showerror("Error!", ("Problems loading the filter settings."))
if (tkMessageBox.askokcancel("Warning", ("Error while loading the filter settings.\nSkip loading filters and continue loading the log file?") == 0 )):
return False
if LoadRec.get():
# Load the target structure
receptor_list = []
try:
for line in logfile:
if line[0:7] == "TARGET>":
filename = line.split("TARGET>")[-1]
filename = filename.strip()
receptor_list.append(filename)
if DEBUG: print "LOAD_SESSION> found receptor: |%s|" % receptor_list[0]
except:
tkMessageBox.showerror("Error!", ("Unable to load the receptor structure(s)."))
return False
if len(receptor_list) > 1:
RCstatus.set(1)
ReceptorOptions()
try:
openReceptor(receptor_list)
except:
if (tkMessageBox.askokcancel("Warning", ("Error while loading the receptor structures.\nSkip receptor loading and continue loading the log file?") == 0 )):
return False
elif len(receptor_list) == 1:
RCstatus.set(0)
ReceptorOptions()
try:
openSingleReceptor(receptor_list[0])
except:
if (tkMessageBox.askokcancel("Warning", (("Error while loading the receptor structure:\n %s\n\nSkip receptor loading and continue loading the log file?") % receptor_list[0]))) == 0:
return False
# Load flexible residues info
if LoadFlex.get():
try:
for line in logfile:
if line[0:5] == "FLEX>":
DoFlex.set(1)
SetFlexibleMode()
# loaded from file
if "file" in line:
if DEBUG: print "LOAD_SESSION: got flex from file", line.split(":", 1)[1][:-1].split("\t")[1]
DoFlexFromWhat.set(1)
SetFlexibleResidueFile(line.split(":", 1)[1][:-1].split("\t")[1])
break
# generated from selection
if "selection" in line:
if DEBUG: print "LOAD_SESSION: got flex from selection", line.split(":", 1)[1][:-1]
DoFlexFromWhat.set(2)
ListFlexResiduesNames.set(line.split(":", 1)[1][:-1])
ParseFlexSelection()
break
except:
tkMessageBox.showwarning("Flexible residues", ("There is a problem in reading the flexible residues information."))
# Load the GPF setup
defer_map_check = False
if LoadMap.get():
# identify the grid mode
mode = ""
for line in logfile:
if "Grid mode :" in line:
mode = line.split(":")[1]
break
if DEBUG: print "LOAD_SESSION> the grid mode is |%s|"% mode
if "calculated in each job" in mode:
if DEBUG :print " applying map mode 0"
MapMenu()
AutoGridWhen1.invoke()
if "calculated now" in mode:
if DEBUG: print " applying map mode 1"
MapMenu()
if not system == "Windows":
AutoGridWhen2.invoke()
else:
AutoGridWhen1.invoke()
if "use pre-calculated" in mode:
if DEBUG: print " applying map mode 2 ( deferring map check)"
defer_map_check = True
# Cached maps policy
if MapSource.get() >= 1 or defer_map_check:
if ">copied<" in mode:
CacheMapPolicy.set("Make copies [ use more disk space ]")
if DEBUG: print " set map policy to COPIES"
if ">linked<" in mode:
CacheMapPolicy.set("Make symbolic links [ save disk space ]")
if DEBUG: print " set map policy to LINKS"
# load GPF if needed
if MapSource.get() <= 1:
GPFcontent.config(state = NORMAL)
GPFcontent.delete(1.0, END)
for line in logfile:
if line[0:4] == "GPF>":
line = line.split('GPF>\t')[1]
GPFcontent.insert(END, line)
GPFfilename.set((" Grid parms from %s " % logname))
GPFcontent.config(state = DISABLED)
GPFedit.config(state = ACTIVE)
setGPFtags()
# get the autogrid binary specified if needed
if MapSource.get() == 1:
for line in logfile:
if "AutoGrid binary file" in line:
line = line.split("|")
if not line[1] == "":
if not GetAutoGrid(line[1]):
if not (tkMessageBox.askokcancel("Warning", ("Unable to find the AutoGrid binary file specified\
in the log:\n\n%s\n\nSkip the binary specification and continue or cancel log loading?" % line[1]) == 0 )):
return False
if LoadDock.get():
# Load the DPF setup
# identify the docking mode
for line in logfile:
if "Docking mode :" in line:
line = line.split(">")[1]
mode = line.split("<")[0]
break
if mode == "generated from template" in mode:
docking_set.set("From template...")
docking_setup_interface(None)
DPFcontent.config(state = NORMAL)
DPFcontent.delete(1.0, END)
for line in logfile:
if line[0:4] == "DPF>":
line = line.split('DPF>\t')[1]
DPFcontent.insert(END, line)
DPFfilename.set((" Docking parms from %s " % logname))
DPFcontent.config(state = DISABLED)
DPFedit.config(state = ACTIVE)
setDPFtags()
# Add a check for parameter files specified here...
if LoadLig.get():
# Load the ligands
ligand_list = []
for line in logfile:
if line[0:7] == "LIGAND>":
line = line.rsplit("\n", 1)[0]
ligand_list.append(line.split("LIGAND> ")[1])
if len(ligand_list) >= 1:
openLigand(ligand_list)
# define the cached maps dir and test them (it needs to be done *after* ligands
# have been imported to check if maps are missing)
if defer_map_check:
MapMenu()
for line in logfile:
if "Grid cache dir" in line:
cache_dir = line.split(" Grid cache dir : ")[1][:-1]
if DEBUG :
print " (Deferred map checking) found cache dir : |%s|"% cache_dir
print " List of map files:"
print glob.glob(os.path.join(cache_dir, "*map*"))
opendirMaps(cache_dir)
AutoGridWhen3.invoke()
InfoMessage.set("Log file loaded successfully")
def SaveLogWindow():
DisableInterface()
def Done():
SaveOptWin.destroy()
SaveLog(logname)
return True
keepasking = True
while keepasking:
logname = asksaveasfilename(parent = root, title = "Select the Raccoon log filename to save...", filetypes = [('Raccoon log file', '*.log'), ("Any file...", "*")] , defaultextension=".log")
if logname:
if DEBUG: print "here I should save the file log..."
InitializeLog(None, logname)
EnableInterface()
return True
else:
EnableInterface()
return False
DisableInterface()
SaveOptWin = Toplevel(root)
SaveOptWin.title("SAVE session")
SaveOptWin.winfo_toplevel().resizable(NO,NO)
Label(SaveOptWin, text = "Select data to be saved in the file:", justify = LEFT).grid(row = 1, column = 0, columnspan = 3, sticky = N, padx = 5, pady = 5)
Checkbutton(SaveOptWin, text = "Ligands list", variable = SaveLig).grid(row = 2, column = 1, columnspan = 2, sticky = W)
Checkbutton(SaveOptWin, text = "Receptors list", variable = SaveRec).grid(row = 3, column = 1, columnspan = 2, sticky = W)
Checkbutton(SaveOptWin, text = "Flexible residues", variable = SaveFlex).grid(row = 4, column = 1, columnspan = 2, sticky = W, padx = 15)
Checkbutton(SaveOptWin, text = "Map parameters", variable = SaveMap).grid(row = 5, column = 1, columnspan = 2, sticky = W)
Checkbutton(SaveOptWin, text = "Docking parameters", variable = SaveDock).grid(row = 6, column = 1, columnspan = 2, sticky = W)
Checkbutton(SaveOptWin, text = "Generation options", variable = SaveGen).grid(row = 7, column = 1, columnspan = 2, sticky = W)
Button(SaveOptWin, text = "OK", command = Done).grid(row = 9, column = 1, columnspan = 1, sticky = W, padx = 10, pady= 10)
Button(SaveOptWin, text = "Cancel", command = lambda: SaveOptWin.destroy()).grid(row = 9, column = 2, sticky = W, padx = 10, pady= 10)
EnableInterface()
def SetJobDirectory(dir = None):
"""General opendir function useful for setting
the finaloutput dir
"""
dir_accepted = False
if dir:
DirName = dir
else:
while not dir_accepted:
DirName = askdirectory()
if DirName:
try:
if os.path.exists(DirName):
if len(glob.glob(os.path.join(DirName, "*"))):
if tkMessageBox.askyesno('Output directory','The selected directory is not empty.\nAre you sure you want to use it?'):
dir_accepted = True
else:
dir_accepted = True
else:
if tkMessageBox.askokcancel('Output directory','The selected directory doesn\'t exist.\nDo you want to create it?'):
os.makedirs(DirName, 0755)
dir_accepted = True
if dir_accepted:
JobDirectory.set(DirName)
JobDirectoryInfo.set(CheckDiskSpace(DirName))
TheCheck()
return
except:
tkMessageBox.showerror("Error!", ("The directory:\n%s\n is not accessible" % DirName))
JobDirectory.set("")
JobDirectoryInfo.set("")
TheCheck()
return
else:
TheCheck()
return
def CheckDiskSpace(path):
if system == "Windows": # Warning: cover your eyes 'cause this workaround is extremely ugly (...but works)
if DEBUG: print "CHECKDISKSPACE> this is path", path
dir_list = "dir \"%s\"" % path
command = os.popen2(dir_list)
output = command[1].readlines()
if DEBUG: print "CHECKDISKSPACE> output", output
diskspace = output[-1].split()[-3]
if DEBUG: print "CHECKDISKSPACE> diskspace", diskspace
available = str(diskspace.replace(".", "")) # total bytes (for EU support)
available = str(diskspace.replace(",", "")) # total bytes (for USA support)
elif system == "Linux" or system == "Darwin":
disk = os.statvfs(path)
capacity = disk.f_bsize * disk.f_blocks
available = disk.f_bsize * disk.f_bavail
used = disk.f_bsize * (disk.f_blocks - disk.f_bavail)
else:
return "[ disk space not available ]"
if available > 1073741824:
unit = " Gb"
factor = 1073741824
else:
unit = " Mb"
factor = 1048576
calculated_space = "%5.2f" % (float(available)/float(factor))
if DEBUG: print calculated_space
available_space = "[ "+str(calculated_space)+unit+" available disk space ]"
return available_space
#########################################################################################################
#########################################################################################################
#########################################################################################################
#########################################################################################################
#########################################################################################################
#### Ligand (p1) functions #####
def countLigands():
verbose = False
if verbose or DEBUG: print "this would be the dictionary lenght:", len(LigandDictionary)
# If there are no ligands just return
if len(LigandDictionary) < 1:
LigandListLabel.set('Import ligands...')
AutoGridWhen3.config(state = DISABLED)
AutoGridWhen1.invoke()
TotalAcceptedLigands.set(0)
return
# start counting...
ligand_conscription = 0
for item in LigandDictionary.keys():
if LigandDictionary[item]["accepted"]:
ligand_conscription += 1
# choices
if ligand_conscription < 1:
tag = " Ligands accepted : %s / %s " % ( str(ligand_conscription), str(len(LigandDictionary)))
LigandListLabel.set(tag)
# Color the label by red...
AutoGridWhen3.config(state = DISABLED)
AutoGridWhen1.invoke()
return
else:
tag = " Ligands accepted : %s / %s " % ( str(ligand_conscription), str(len(LigandDictionary)))
LigandListLabel.set(tag)
if RCstatus.get() == 0:
if SingleReceptorSet.get():
AutoGridWhen3.config(state = NORMAL)
if RCstatus.get() == 1:
AutoGridWhen3.config(state = NORMAL)
return
def openLigand(ligFile = None): # Now unified loader for all the supported formats
# The input is a list
got_some = False
if not ligFile:
ligFile = askopenfilename(parent = root, title = "Select one or more PDBQT, PDB or (multi)MOL2", filetypes=[("Ligand PDBQT", "*.pdbqt"), ("PDB", "*.pdb"), ("Mol2", "*.mol2"), ("Any file type...", "*")], multiple = 1)
if ligFile:
# now any filter can be applied in the openfilename interface ("*" included)
pdb_list, pdbqt_list, mol2_list = [], [], []
for file in ligFile:
if file.split(".")[-1] == "pdb": pdb_list.append(file)
if file.split(".")[-1] == "pdbqt": pdbqt_list.append(file)
if file.split(".")[-1] == "mol2": mol2_list.append(file)
# PDB
for filename in pdb_list:
output_file = filename[:-3]+"pdbqt" # path/filename.pdbqt
if genPDBQT(filename, output_file):
got_some = True
LigandRegistration(output_file)
# Re-check map cache folder if is defined
if mapDir and MapSource.get() == 2:
openDirMaps(mapDir)
else:
tkMessageBox.showwarning("PDB Error", ("There is a problem in the input, please check the ligand:\n%s" % filename ))
break
# MOL2
for filename in mol2_list:
openMultiMol2(filename)
# PDBQT
if pdbqt_list:
list_of_accepted = checkPDBQTligList(pdbqt_list)
if list_of_accepted:
got_some = True
for ligand in list_of_accepted:
LigandRegistration(ligand)
# Ligands will be filtered every time (at least because of the TDOF)
if got_some:
InfoMessage.set( "Ligands imported successfully.")
FilterLigands(True)
countLigands()
# Re-check map cache folder if is defined
if mapDir and MapSource.get() == 2:
openDirMaps(mapDir)
TheCheck()
def openMultiMol2(ligFile = None):
# -import both single- and multi-MOL2
# -accept both input file or none
# -check for the number of molecules in the MOL2
# -find a suitable place for splitting the molecules
# -convert them
# -add them to the list
#
if not ligFile:
ligFile = askopenfilename(parent = root, title = "Select a Mol2...", filetypes=[("Mol2", "*.mol2", "MOL2")])
if ligFile:
count_mols = CheckMultiMol2(ligFile)
if not count_mols:
tkMessageBox.showwarning("Mol2 Error", ("%s doesn't contain any Mol2 structures." % ligFile))
if count_mols == 1: # it's a single Mol2
output_file = ligFile[:-4]+"pdbqt" # path/filename.pdbqt
if genPDBQT(ligFile, output_file):
LigandRegistration(output_file)
else:
tkMessageBox.showerror("Error!", ("Problems converting the MOL2: %s" % ligFile))
if count_mols > 1: # it's a multiMol2
if count_mols >= 100:
WARNING = "\n\n[ Warning: this will take some time ]"
else:
WARNING = ""
if not tkMessageBox.askokcancel('Multi-structure MOL2 file',('A multi-structure file MOL2 containing %d ligands was found. Proceed to split and convert it to PDBQT?%s' % (count_mols, WARNING))):
return
output_dir = askdirectory(parent = root, title = ("MOL2: Split and convert %d molecules in the following dir..."% count_mols) , initialdir = os.path.dirname(ligFile))
if not output_dir:
tkMessageBox.showinfo(title="MOL2 splitting", message =( "The splitting process of %s has been cancelled by the user" % ligFile))
return
name = os.path.basename(ligFile)[:-5] # get rid of path and extension ".mol2" (stem)
outputDirMOL2 = output_dir+os.sep+name+os.sep+"mol2"
outputDirPDBQT = output_dir+os.sep+name+os.sep+"pdbqt"
# attempt to create the Mol2 output dir
try:
if not os.path.exists(outputDirMOL2):
os.makedirs(outputDirMOL2, 0755)
except:
tkMessageBox.showerror("Error!", ("I can't create the output dir:\n%s" % outputDirMol2))
if DEBUG: print "ERROR> mol2 import process died"
# break
# split the mol2 files
DisableInterface()
to_be_imported = SplitMol2(ligFile, outputDirMOL2)
if to_be_imported:
if DEBUG: print "i'm gong to import", to_be_imported
# attempt to create the PDBQT output dir
try:
if not os.path.exists(outputDirPDBQT):
os.makedirs(outputDirPDBQT, 0755)
except:
tkMessageBox.showerror("Error!", ("I can't create the output dir:\n%s" % outputDirPDBQT))
if DEBUG: print "ERROR> pdbqt import process died"
#break
message = Message(text = "I'm going to convert"+str(count_mols)+"molecules")
processed = 0
for ligand in to_be_imported:
name = os.path.basename(ligand)[:-5]
output_file = outputDirPDBQT+os.sep+name+".pdbqt" # path/filename.pdbqt
InfoMessage.set(("Generating PDBQT for %s ...") % name)
root.update()
if genPDBQT( ligand, output_file ):
LigandRegistration(output_file)
processed += 1
else:
tkMessageBox.showerror("Error!", ("Some problem occurred in converting the file:\n%s\n Import process aborted." % ligand))
break
EnableInterface()
if processed == count_mols:
# Re-check map cache folder if is defined
if mapDir and MapSource.get() == 2:
openDirMaps(mapDir)
tkMessageBox.showinfo(title = "MultiMol2-to-PDBQT", message = ("%d ligands successfully imported from\n%s" % (count_mols, ligFile)))
else:
tkMessageBox.showwarning(title = ligFile, message = ("Some problem occurred.\n %d out of %d structures accepted." % (processed, count_mols) ) )
def CheckMultiMol2(filename):
# simple function for checking the number oou
# multiple structures in the mol2
count = 0
try:
multimol2 = open(filename, 'r')
for line in multimol2:
if "@MOLECULE" in line:
count += 1
if count == 0:
return False
else:
return count
except:
tkMessageBox.showwarning("Mol2 Error", "The file doesn't contain any Mol2 structures.")
return False
def SplitMol2 (filename = None, outdir = None):
# split a multi-mol2 in the specified directory
utility_mode = False
# This is for using the splitting function as an utility:
if not filename:
filename = askopenfilename(parent = root, title = "Select a Mol2...", filetypes=[("Mol2", "*.mol2", "MOL2")])
utility_mode = True
if not filename:
return
# end of utility mode
buffer = []
count = 0
zinc_found = False
splitted_mols = []
total = CheckMultiMol2(filename)
# Also this is for using the splitting function as an utility
if not outdir:
outdir = askdirectory(parent = root, title = ("MOL2: Split and convert %d molecules in the following dir..."% total))
if not outdir:
tkMessageBox.showinfo(title="MOL2 splitting", message =( "The splitting process of %s has been cancelled by the user" % filename))
return
# end of utility mode
multimol2 = open(filename, 'r') # the input
name = os.path.basename(filename)[:-5] # needed for the stem of the output files
try:
if not os.path.exists(outdir):
os.makedirs(outdir, 0755)
InfoMessage.set(("Splitting %s ") % os.path.basename(filename) )
root.update()
for line in multimol2.readlines():
if "@MOLECULE" in line:
if len(buffer) > 1: # INCREASED FROM 0
count += 1
number = "%06d" % count
if zinc_found:
filename = outdir+os.sep+zinc_id+".mol2"
else:
filename = outdir+os.sep+name+"_"+str(number)+".mol2"
output = open(filename, 'w')
for item in buffer:
print >>output, item[:-1]
output.close()
del buffer[:]
splitted_mols.append(filename)
zinc_found = False
buffer.append(line)
else:
buffer.append(line)
if "ZINC" in line[0:5]:
if DEBUG: print "found zinc name |%s|" % line
zinc_id = line.split()[0]
zinc_found = True
if len(buffer) > 0: # Flush the remaining buffer...
count += 1
number = "%06d" % count
if zinc_found:
filename = outdir+os.sep+zinc_id+".mol2"
else:
filename = outdir+os.sep+name+"_"+str(number)+".mol2"
output = open(filename, 'w')
for item in buffer:
print >>output, item[:-1]
output.close()
zinc_found = False
splitted_mols.append(filename)
del buffer[:]
if DEBUG: print "splitted", splitted_mols
if utility_mode:
tkMessageBox.showinfo(title="MOL2 splitting", message =( "%d molecules have been successfully created in:\n %s" % (count, outdir)))
InfoMessage.set(("Splitting %s : DONE ") % os.path.basename(filename) )
root.update()
return splitted_mols
except:
tkMessageBox.showwarning("Error!", ("The selected directory is not accessible: %s"% outdir))
return False
if DEBUG : print count, "molecules processed"
def genPDBQT(infile, outfile):
DisableInterface()
# any resemblance with the prepare_ligand script is accidental
#
# generate a pdbqt from a directory containing the splitted mol2
#
# optional parameters
# PrepareLigand options defaults
verbose = None
add_bonds = False
#-A: repairs to make: add bonds and/or hydrogens
repairs = Repair.get()
#-C default: add gasteiger charges
charges_to_add = ChargeSet.get()
#-p preserve charges on specific atom types
preserve_charge_types=''
#-U: cleanup by merging nphs_lps, nphs, lps
cleanup = Cleanup.get()
#-B named rotatable bond type(s) to allow to rotate
# TODO strip the code doing the incremental addition of options, 'cause most
# likely it uses a split call internally (by Ruth?)
SELECTED_ALLOWED_BONDS = ""
if BackboneRotatable:
SELECTED_ALLOWED_BONDS += "backbone"
if AmideRotatable:
if SELECTED_ALLOWED_BONDS:
SELECTED_ALLOWED_BONDS += "_amide"
else:
SELECTED_ALLOWED_BONDS += "amide"
if GuanidiniumRotatable:
if SELECTED_ALLOWED_BONDS:
SELECTED_ALLOWED_BONDS += "guanidinium"
else:
SELECTED_ALLOWED_BONDS += "_guanidinium"
allowed_bonds = SELECTED_ALLOWED_BONDS
#-r root
root = 'auto'
#-o outputfilename
outputfilename = outfile # GOOD
#-F check_for_fragments
check_for_fragments = LargestFrag.get()
#-I bonds_to_inactivate
bonds_to_inactivate = ""
#-Z inactivate_all_torsions
inactivate_all_torsions = LockTors.get()
#-g attach_nonbonded_fragments
attach_nonbonded_fragments = AttachFrag.get()
#-m mode
mode = 'automatic'
#-d dictionary
dict = None
try:
mols = Read(infile)
mol = mols[0]
except:
return False
if len(mols) > 1:
# put here the filtering
ctr +=1
if len(m.allAtoms) > len(mol.allAtoms):
mol = m
coord_dict = {}
for atom in mol.allAtoms: coord_dict[atom] = atom.coords
mol.buildBondsByDistance()
if charges_to_add is not None:
preserved = {}
preserved_types = preserve_charge_types.split(',')
for type in preserved_types:
if not len(type): continue
ats = mol.allAtoms.get(lambda x: x.autodock_element == type)
for a in ats:
if a.chageSet is not None:
preserved[a] = [a.chargeSet, a.charge]
LPO = AD4LigandPreparation(mol, mode, repairs, charges_to_add,
cleanup, allowed_bonds, root,
outputfilename=outputfilename,
dict=dict, check_for_fragments=check_for_fragments,
bonds_to_inactivate=bonds_to_inactivate,
inactivate_all_torsions=inactivate_all_torsions,
attach_nonbonded_fragments=attach_nonbonded_fragments)
if charges_to_add is not None:
# restore the previous charges
for atom, chargeList in preserved.items():
atom._charges[chargeList[0]] = chargeList[1]
atom.chargeSet = chargeList[0]
bad_list = []
for a in mol.allAtoms:
if a.coords!=coord_dict[a]: bad_list.append(a)
if len(bad_list):
if DEBUG:
print len(bad_list), ' atom coordinates changed!'
for a in bad_list:
print a.name, ":", coord_dict[a], ' -> ', a.coords
if mol.returnCode is not 0:
if DEBUG: print "ERROR IN THE EXITCODE!"
EnableInterface()
return False
else:
InfoMessage.set("%s converted to PDBQT" % os.path.basename(infile))
nb.update() # TODO Update the window with the message... but not the ROOT!
EnableInterface()
return True
def LigandRegistration(filename):
# INPUT : pdbqt file
# OUTPUT : nothing
# EXTRA : append the ligand properties to the Great Book of Ligands
# update the list of total atom types considered (for caching map)
file = open(filename, 'r')
ligand = file.readlines()
file.close()
current_atypes = []
BAD_ATOM_TYPE = False
MW = 0
HbD = 0
HbA = 0
Nat = 0
status = True
hbd_h = []
hbd_candidate = []
# Calculate all the properties
for line in ligand:
if 'TORSDOF' in line:
TORSDOF = int(line.split()[1])
if line[0:6] == 'HETATM' or line[0:4] == 'ATOM':
# Nat += 1 # Consider to remove Hydrogens? (search on PubMed)
atype = line.split()[-1]
if atype not in current_atypes:
current_atypes.append(atype)
# Hb acceptor
if atype == "OA" or atype == "NA" or atype == "SA":
HbA += 1
# Hb donor preparation
if atype == "HD":
#capture the hydrogens that could be bond to the Hb donor...
hbd_h.append(line)
else:
# count heavy atoms
Nat += 1
if atype == "N" or atype == "O" or atype == "OA" or atype == "NA":
hbd_candidate.append(line)
try:
MW += AtypeList[atype][1] # add the atomic weight to the total MW
except:
MW += 10000 # check this if it's reasonable
BAD_ATOM_TYPE = True
status = False # non-standard atom types are rejected by default
# identify HBD by checking if N/O's are bound to H's
for atom in hbd_candidate:
for hydrogen in hbd_h:
if dist(atom, hydrogen) <= 1.1:
HbD += 1
break
if DEBUG: print "I've found %s HBD"% HbD
# Insert the ligand in the Great Book of Ligands
if not LigandDictionary.has_key(filename):
# ligand is registered with properties
LigandDictionary[filename] = {
"Atypes" : current_atypes,
"TORSDOF" : TORSDOF,
"HbD" : HbD,
"HbA" : HbA,
"MW" : MW,
"Nat" : Nat,
"NotStdAT" : BAD_ATOM_TYPE,
"accepted" : status }
LigandScrolledListBox.insert('end', filename)
if not BAD_ATOM_TYPE:
for atype in current_atypes:
AtypeList[atype][0] += 1 # increment the count for this atom type
# Add a list of the non std atomt types and count it (for cached maps purposes)???
if DEBUG:
# Debug function for atom types...
print "#### Atom type-DICTIONARY ####"
for item in AtypeList.keys():
print item, AtypeList[item][0]
print "#### Atom type-DICTIONARY ####"
def dist(firstline, secondline):
# INFO : calculate the atomic distance between two PDB atom lines
# INPUT : two pdb lines
# OUTPUT : a pdb line
coord1=[]
coord2=[]
temp=firstline[28:56]
coord1=temp.split()
temp=secondline[28:56]
coord2=temp.split()
# floating the strings
for index in range(len(coord1)):
coord1[index]=float(coord1[index])
coord2[index]=float(coord2[index])
measure=sqrt((coord1[0]-coord2[0])**2+(coord1[1]-coord2[1])**2+(coord1[2]-coord2[2])**2)
return measure
def UpdateATDict(file_list):
"""
input: list of PDBQT filenames to be excluded
output: (nothing)
operation: update the dictionary of atom types currently
loaded
"""
for ligand in file_list:
atypes_to_be_removed = LigandDictionary[ligand]["Atypes"]
for atype in atypes_to_be_removed:
AtypeList[atype][0] -= 1
def clearATDict():
# set all atom type counts to 0 (except for d and e)
for atom in AtypeList:
AtypeList[atom][0] = 0
AtypeList["e"][0] = 1
AtypeList["d"][0] = 1
if DEBUG:
for atom in AtypeList:
print atom, AtypeList[atom]
def openLigandDir(ligDir = None):
if not ligDir:
ligDir = askdirectory()
if ligDir:
# PDBQT
ligFiles = glob.glob(os.path.join(ligDir, "*.pdbqt"))
if ligFiles:
for item in checkPDBQTligList(ligFiles):
LigandRegistration(item)
# PDB
ligFiles = glob.glob(os.path.join(ligDir, "*.pdb"))
if ligFiles:
openLigand(ligFiles)
# MOL2
ligFiles = glob.glob(os.path.join(ligDir, "*.mol2"))
if ligFiles:
openLigand(ligFiles)
# Re-check map cache folder if is defined
if mapDir and MapSource.get() == 2:
openDirMaps(mapDir)
# Ligands will be filtered every time (at least because of the TDOF)
FilterLigands(True)
countLigands()
TheCheck()
def openLigandDirRecursive():
pdbqt_ligandlist = []
mol2_ligandlist = []
pdb_ligandlist = []
count_pdbqt = 0
count_mol2 = 0
count_pdb = 0
ligDir = askdirectory(title = "Select a directory to be scanned")
if ligDir:
for root, subFolders, files in os.walk(ligDir):
for file in files:
if file[-5:] == "pdbqt":
pdbqt_ligandlist.append(os.path.join(root,file))
if file[-4:] == "mol2":
mol2_ligandlist.append(os.path.join(root,file))
if file[-3:] == "pdb":
pdb_ligandlist.append(os.path.join(root,file))
if DEBUG:
print "This would be the ligand file list"
print "pdbqt", pdbqt_ligandlist
print "mol2", mol2_ligandlist
print "pdb", pdb_ligandlist
count_pdbqt = len(pdbqt_ligandlist)
count_mol2 = len(mol2_ligandlist)
count_pdb = len(pdb_ligandlist)
total = count_pdbqt + count_mol2 + count_pdb
if total > 1:
if not tkMessageBox.askokcancel("Ligands found...", ("The directory contains a total of %s potential ligands:\n\n\t%s pdbqt\n\t%s mol2\n\t%s pdb.\
\n\nStart the import process?" % (total, count_pdbqt, count_mol2, count_pdb) )):
return
# PDBQT
if count_pdbqt:
for item in checkPDBQTligList(pdbqt_ligandlist):
LigandRegistration(item)
# MOL2
if count_mol2:
openLigand(mol2_ligandlist)
# PDB
if count_pdb:
openLigand(pdb_ligandlist)
# Re-check map cache folder if is defined
if mapDir and MapSource.get() == 2:
openDirMaps(mapDir)
# Ligands will be filtered every time (at least because of the TDOF)
FilterLigands(True)
countLigands()
TheCheck()
def removeLigand():
ligand_index = LigandScrolledListBox.curselection() # position of ligands in the list...
ligand_list = []
for item in ligand_index:
# update the list of ligands to be removed from the Great Book of Ligands
ligand_list.append(LigandScrolledListBox.get(item))
# remove the ligands from the visualized list
LigandScrolledListBox.delete(item)
UpdateATDict(ligand_list)
for ligand in ligand_list:
del LigandDictionary[ligand]
countLigands()
FilterLigands(True)
TheCheck()
def removeReceptor():
items = receptorScrolledListBox.getcurselection()
# update the atom type list decrementing the atoms of each ligand
for ligand in items:
receptorFileList.remove(ligand)
receptorScrolledListBox.setlist(receptorFileList) # NOT CLEAR!!!
if len(receptorFileList) == 0:
MultiReceptorSet.set(False)
countReceptors()
TheCheck()
def removeAllLigands():
if len(LigandDictionary) > 1 and not tkMessageBox.askokcancel('Delete all the ligands','Do you really want to\nremove all the ligands\nfrom the list?'):
return
LigandScrolledListBox.delete(0, END)
# Buy a new Great Book of Ligands
for item in LigandDictionary.keys():
del LigandDictionary[item]
countLigands()
clearATDict()
TheCheck()
def checkPDBQTligList(filenamelist):
AcceptedFiles = []
RejectedFiles = []
CountAccepted = 0
CountRejected = 0
for file in filenamelist:
found_ligand = 0
found_residue = 0
try:
for line in open(file, 'r'):
if line[0:4] == "ROOT":
found_ligand = 1
if line[0:9] == "BEGIN_RES":
found_residue = 1
if DEBUG: print "found res"
if found_ligand == 1 and found_residue == 0:
AcceptedFiles.append(file)
CountAccepted += 1
else:
CountRejected += 1
RejectedFiles.append(file)
except:
CountRejected += 1
RejectedFiles.append(file)
if CountAccepted == 0:
if CountRejected == 1:
tkMessageBox.showwarning("Error!", "The ligand is not valid.")
else:
tkMessageBox.showwarning("Ligands error!", "None of %d PDBQT have been accepted.\nPlease check the inputs." % CountRejected)
if CountAccepted > 0 and CountRejected > 0:
if tkMessageBox.askokcancel("Ligands imported", "%d\taccepted.\n%d\trejected.\n\nDo you want to inspect the list of rejected ligands?" % (CountAccepted, CountRejected)):
RejectedWindow = Toplevel()
RejectedWindow.title("List of rejected PDBQT's")
scrollbar = Scrollbar(RejectedWindow)
ListOfRejected = Listbox(RejectedWindow)
CloseButton = Button(RejectedWindow, text = "Close", command = RejectedWindow.destroy)
ListOfRejected.grid(column = 0, sticky = W+N+S+E)
RejectedWindow.grid_rowconfigure(0, minsize = 300, weight = 1)
RejectedWindow.grid_columnconfigure(0, minsize = 330, weight = 1)
scrollbar.grid(row = 0, column = 1, sticky = S+N)
scrollbar.config(command = ListOfRejected.yview)
ListOfRejected.config(yscrollcommand=scrollbar.set)
for item in RejectedFiles:
ListOfRejected.insert(END, item)
CloseButton.grid(row = 2, columnspan = 2, sticky = W+E)
return AcceptedFiles
def checkPDBQTreclist(filenamelist):
AcceptedFiles = []
RejectedFiles = []
CountAccepted = 0
CountRejected = 0
for file in filenamelist:
found_ligand = 0
found_residue = 0
try:
for line in open(file, 'r'):
if line[0:4] == "ROOT":
found_ligand = 1
if line[0:9] == "BEGIN_RES":
found_residue = 1
if found_ligand == 1 or found_residue == 1:
CountRejected += 1
RejectedFiles.append(file)
if DEBUG: print file, "is bad receptor.."
else:
AcceptedFiles.append(file)
CountAccepted += 1
if DEBUG: print file, "a good receptor.."
except:
CountRejected += 1
RejectedFiles.append(file)
if CountRejected == 0:
if CountAccepted > 1: # To suppress messages for a single ligand import
notification = "%d receptors\nhave been accepted." % CountAccepted
tkMessageBox.showinfo(title="PDBQT receptor imported", message=notification)
if CountAccepted == 0:
if CountRejected == 1:
tkMessageBox.showwarning("Error!", "The receptor is not valid.")
else:
tkMessageBox.showwarning("Receptors error!", "None of %d receptors have been accepted.\nPlease check the inputs." % CountRejected)
if CountAccepted > 0 and CountRejected > 0:
if tkMessageBox.askokcancel("Receptors imported", "%d\taccepted.\n%d\trejected.\n\nDo you want to inspect the list of rejected structures?" % (CountAccepted, CountRejected)):
RejectedWindow = Toplevel()
RejectedWindow.title("List of rejected PDBQT's")
scrollbar = Scrollbar(RejectedWindow)
ListOfRejected = Listbox(RejectedWindow)
CloseButton = Button(RejectedWindow, text = "Close", command = RejectedWindow.destroy)
ListOfRejected.grid(column = 0, sticky = W+N+S+E)
RejectedWindow.grid_rowconfigure(0, minsize = 300, weight = 1)
RejectedWindow.grid_columnconfigure(0, minsize = 330, weight = 1)
scrollbar.grid(row = 0, column = 1, sticky = S+N)
scrollbar.config(command = ListOfRejected.yview)
ListOfRejected.config(yscrollcommand=scrollbar.set)
for item in RejectedFiles:
ListOfRejected.insert(END, item)
CloseButton.grid(row = 2, columnspan = 2, sticky = W+E)
return AcceptedFiles
def CheckLigFilterOptions():
for value in HbDmin, HbDmax, HbAmin, HbAmax, MWmin, MWmax, NatMin, NatMax, TORSDOFmin, TORSDOFmax:
try:
value.get()
except:
tkMessageBox.showwarning("Error", "Only numerical values\nare allowed ...\n Try again!\n(resetting to default)")
FilteringDefaults(FilterSet.get())
return False
break
if value.get() < 0:
tkMessageBox.showwarning("Uhmmmm...", "In the current implementation of\nthe Universe negative values\nfor these params are not allowed...\n\nTry one of the following options:\n - recompile the Universe\n - use positive value\n\n[resetting to default]")
FilteringDefaults(FilterSet.get())
return False
break
if TORSDOFmax.get() + FlexResTORSDOF.get() > AutoDockMaxTORSDOF.get():
if DEBUG: print TORSDOFmax.get(), FlexResTORSDOF.get(), AutoDockMaxTORSDOF.get()
if FlexResTORSDOF.get() > 0:
tkMessageBox.showwarning("Torsion Limit Error", "AutoDock is limited to max %s rotatable bonds.\n\nThere are %s rotatable bonds already allotted for the flex residues, therefore the maximum number of rotatable bonds per ligand is set to %s." % ( AutoDockMaxTORSDOF.get(), FlexResTORSDOF.get(), AutoDockMaxTORSDOF.get() - FlexResTORSDOF.get() ))
else:
tkMessageBox.showwarning("Torsion Limit Error", "AutoDock is limited to max %s rotatable bonds." % ( AutoDockMaxTORSDOF.get() ))
FilteringDefaults("TORSDOF")
MinMax = False
if HbDmin.get() <= HbDmax.get():
if HbAmin.get() <= HbAmax.get():
if MWmin.get() <= MWmax.get():
if NatMin.get() <= NatMax.get():
if TORSDOFmin.get() <= TORSDOFmax.get():
MinMax = True
if not MinMax:
FilteringDefaults(FilterSet.get())
tkMessageBox.showwarning("Uhmmmm...", "Guess what?\nMAX must be bigger than or equal to MIN.\n\n[resetting to default]")
return False
else:
return True
def DefaultLigOptions():
ChargeSet.set("gasteiger")
Repair.set("")
Cleanup.set("nphs_lps")
BackboneRotatable.set(True)
AmideRotatable.set(False)
GuanidiniumRotatable.set(False)
LockTors.set(False)
LargestFrag.set(False)
AttachFrag.set(False)
def LigandImportOptions(): # Options for non-PDBQT files only
try:
LigandOptionsWin.lift()
except:
LigandOptionsWin = Toplevel(root)
LigandOptionsWin.title("PDBQT generation options")
LigandOptionsWin.winfo_toplevel().resizable(NO,NO)
ChargeFrame = Pmw.Group(LigandOptionsWin, tag_text = "Partial charges")
Radiobutton(ChargeFrame.interior(), text="Add Gasteiger", variable = ChargeSet, value = "gasteiger").grid(row = 0, column = 0, sticky = W) # Default
Radiobutton(ChargeFrame.interior(), text="Keep original", variable = ChargeSet, value = "").grid(row = 0, column = 1, sticky = W)
ChargeFrame.grid(row = 2, column = 0, padx = 5, pady = 5, sticky = W, columnspan = 2)
RepairFrame = Pmw.Group(LigandOptionsWin, tag_text = "Structure repair ")
Radiobutton(RepairFrame.interior(), text = "none", variable = Repair, value = "").grid(row = 1 , column = 0, sticky = N ) # Default
Radiobutton(RepairFrame.interior(), text = "bonds", variable = Repair, value = "bonds" ).grid(row = 1 , column = 1, sticky = N )
Radiobutton(RepairFrame.interior(), text = "hydrogens", variable = Repair, value = "hydrogens" ).grid(row = 1 , column = 2 , sticky = N )
Radiobutton(RepairFrame.interior(), text = "both", variable = Repair, value = "bond_hydrogens" ).grid(row = 1 , column = 3, sticky = N )
RepairFrame.grid(row = 3, column = 0, padx = 10, pady = 10, sticky = W, columnspan = 2)
CleanupFrame = Pmw.Group(LigandOptionsWin, tag_text = "Structure clean-up ")
Radiobutton(CleanupFrame.interior(), text = "\nboth\n", variable = Cleanup, value = "nphs_lps" ).grid(row = 1 , column = 3, sticky = N ) # Default
Radiobutton(CleanupFrame.interior(), text = "merge\nnon-polar H\n", variable = Cleanup, value = "nphs" ).grid(row = 1 , column = 1, sticky = N )
Radiobutton(CleanupFrame.interior(), text = "delete\nlone pairs\n", variable = Cleanup, value = "lps" ).grid(row = 1 , column = 2 , sticky = N )
Radiobutton(CleanupFrame.interior(), text = "\nnone\n", variable = Cleanup, value = "").grid(row = 1 , column = 0, sticky = N )
CleanupFrame.grid(row = 4, column = 0, padx = 10, pady = 10, sticky = W, columnspan = 2)
RotatableFrame = Pmw.Group(LigandOptionsWin, tag_text = "Activate special\nrotatable bonds")
Label(RotatableFrame.interior(), text = " yes").grid(row = 0, column = 1, sticky = W)
Label(RotatableFrame.interior(), text = " no ").grid(row = 0, column = 2, sticky = W)
Label(RotatableFrame.interior(), text = " backbone ").grid(row = 1, column = 0, sticky = W)
Radiobutton(RotatableFrame.interior(), variable = BackboneRotatable, value = True ).grid(row = 1 , column = 1, sticky = W ) # Default
Radiobutton(RotatableFrame.interior(), variable = BackboneRotatable, value = False ).grid(row = 1 , column = 2, sticky = W )
Label(RotatableFrame.interior(), text = " amide ").grid(row = 2, column = 0, sticky = W)
Radiobutton(RotatableFrame.interior(), variable = AmideRotatable, value = True ).grid(row = 2 , column = 1, sticky = W )
Radiobutton(RotatableFrame.interior(), variable = AmideRotatable, value = False ).grid(row = 2 , column = 2, sticky = W ) # Default
Label(RotatableFrame.interior(), text = " guanidinium ").grid(row = 3, column = 0, sticky = W)
Radiobutton(RotatableFrame.interior(), variable = GuanidiniumRotatable, value = True ).grid(row = 3 , column = 1, sticky = W )
Radiobutton(RotatableFrame.interior(), variable = GuanidiniumRotatable, value = False ).grid(row = 3 , column = 2, sticky = W ) # Default
RotatableFrame.grid(row = 5, column = 0, padx = 10, pady = 10, sticky = W)
Checkbutton(LigandOptionsWin, text = "Inactivate ALL active\ntorsions", variable = LockTors, indicatoron = False ).grid(row = 5 , column = 1, sticky = W)
FragmentFrame = Pmw.Group(LigandOptionsWin, tag_text = "Fragmented structures")
Radiobutton(FragmentFrame.interior(), text = "Keep largest fragment", variable = LargestFrag, value = True ).grid(row = 0 , column = 0, sticky = W )
Radiobutton(FragmentFrame.interior(), text = "Keep all", variable = LargestFrag, value = False ).grid(row = 0 , column = 1, sticky = W ) # Default
Checkbutton(FragmentFrame.interior(), text = "Attach non-bonded fragments", variable = AttachFrag, indicatoron = False).grid(row = 1 , column = 1, sticky = W)
FragmentFrame.grid(row = 6, column = 0, padx = 10, pady = 10, sticky = W, columnspan = 2)
Tkinter.Button(LigandOptionsWin, text="OK", command = LigandOptionsWin.destroy, width = 50 ).grid(row = 9, column = 0, sticky = S, columnspan = 2, pady = 10, padx = 10)
Tkinter.Button(LigandOptionsWin, text="Set defaults", command = DefaultLigOptions, width = 50).grid(row = 1, column = 0, columnspan = 3, sticky = S, pady = 10, padx = 10)
def LigandFilterOptions(): # Filtering files
global LigandFilterWin, FilterSet
try:
LigandFilterWin.lift()
except:
LigandFilterWin = Toplevel(root)
LigandFilterWin.title("Ligand filters")
LigandFilterWin.winfo_toplevel().resizable(NO,NO)
rejected = 0
total = len(LigandDictionary.keys())
for item in LigandDictionary.keys():
if not LigandDictionary[item]["accepted"]:
rejected += 1
accepted = total - rejected
msg = "Total number of ligands: %12s" % str(total)
TotalNumberLigandsMsg.set(msg)
msg = "Accepted ligands: %12s" % str(accepted)
TotAcceptedLigandsMsg.set(msg)
msg = "Rejected ligands: %12s" % str(rejected)
TotRejectedLigandsMsg.set(msg)
# Preset menu
Label(LigandFilterWin, text = "Filter presets :").grid(row = 0, column = 0, columnspan = 1, sticky = W)
PrecannedFilters = OptionMenu(LigandFilterWin, FilterSet, "Default", "Lipinski-like", "DrugLikeness", "DrugLikeness (frag)", command = lambda event : FilteringDefaults())
PrecannedFilters.grid(row = 0, column = 1, columnspan = 1, sticky = W, pady = 10)
FiltersFrame = Pmw.Group(LigandFilterWin, tag_text = "Molecular properties")
Label(FiltersFrame.interior(), text = "MIN").grid(row = 1, column = 1, sticky = N)
Label(FiltersFrame.interior(), text = "MAX").grid(row = 1, column = 2, sticky = N)
Label(FiltersFrame.interior(), text = "H-bond donors").grid(row = 2, column = 0, sticky = W, padx = 10)
HbDonors1 = Entry(FiltersFrame.interior(), width = 4, textvariable=HbDmin).grid(row=2, column = 1, sticky = W, columnspan = 1)
HbDonors2 = Entry(FiltersFrame.interior(), width = 4, textvariable=HbDmax).grid(row=2, column = 2, sticky = W, columnspan = 1)
Button(FiltersFrame.interior(), text = "Default",width = 5, command = lambda : FilteringDefaults("HbD")).grid(row = 2, column = 3, padx = 10, pady = 3)
Label(FiltersFrame.interior(), text = "H-bond acceptors").grid(row = 3, column = 0, sticky = W, padx = 10)
HbAcceptors1 = Entry(FiltersFrame.interior(), width = 4, textvariable=HbAmin).grid(row=3, column = 1, sticky = W, columnspan = 1)
HbAcceptors2 = Entry(FiltersFrame.interior(), width = 4, textvariable=HbAmax).grid(row=3, column = 2, sticky = W, columnspan = 1)
Button(FiltersFrame.interior(), text = "Default",width = 5, command = lambda : FilteringDefaults("HbA")).grid(row = 3, column = 3, padx = 10, pady = 3)
Label(FiltersFrame.interior(), text = "Molecular weight").grid(row = 4, column = 0, sticky = W, padx = 10)
HbAcceptors1 = Entry(FiltersFrame.interior(), width = 4, textvariable=MWmin).grid(row=4, column = 1, sticky = W, columnspan = 1)
HbAcceptors2 = Entry(FiltersFrame.interior(), width = 4, textvariable=MWmax).grid(row=4, column = 2, sticky = W, columnspan = 1)
Button(FiltersFrame.interior(), text = "Default",width = 5, command = lambda : FilteringDefaults("MW")).grid(row = 4, column = 3, padx = 10, pady = 3)
Label(FiltersFrame.interior(), text = "Number of atoms").grid(row = 5, column = 0, sticky = W, padx = 10)
HbAcceptors1 = Entry(FiltersFrame.interior(), width = 4, textvariable=NatMin).grid(row=5, column = 1, sticky = W, columnspan = 1)
HbAcceptors2 = Entry(FiltersFrame.interior(), width = 4, textvariable=NatMax).grid(row=5, column = 2, sticky = W, columnspan = 1)
Button(FiltersFrame.interior(), text = "Default",width = 5, command = lambda : FilteringDefaults("Nat")).grid(row = 5, column = 3, padx = 10, pady = 3)
Label(FiltersFrame.interior(), text = "Rotatable bonds").grid(row = 6, column = 0, sticky = W, padx = 10)
HbAcceptors1 = Entry(FiltersFrame.interior(), width = 4, textvariable=TORSDOFmin).grid(row=6, column = 1, sticky = W, columnspan = 1)
HbAcceptors2 = Entry(FiltersFrame.interior(), width = 4, textvariable=TORSDOFmax).grid(row=6, column = 2, sticky = W, columnspan = 1)
Button(FiltersFrame.interior(), text = "Default",width = 5, command = lambda : FilteringDefaults("TORSDOF")).grid(row = 6, column = 3, padx = 10, pady = 3)
FiltersFrame.grid(row = 1 , column = 0, columnspan = 2, padx = 10)
# Preview info frame
PreviewFrame = Frame(LigandFilterWin, relief=GROOVE, padx = 10, pady = 10, border = 2)
TotalLabel = Label(PreviewFrame, textvariable = TotalNumberLigandsMsg).grid(row = 1, column = 0, sticky = E)
AcceptedLabel = Label(PreviewFrame, textvariable = TotAcceptedLigandsMsg)
AcceptedLabel.grid(row = 2, column = 0, sticky = E)
RejectedLabel = Label(PreviewFrame, textvariable = TotRejectedLigandsMsg)
RejectedLabel.grid(row = 3, column = 0, sticky = E)
PreviewFrame.grid(row = 1, column = 2, padx = 10)
Checkbutton(FiltersFrame.interior(), text = "Filter ligands with non-AD atom types", variable = DoRejectATypes, onvalue = True, offvalue = False).grid(row = 7, column = 0, columnspan = 4, pady = 2)
Button(LigandFilterWin, text = "Preview",width = 30, command = lambda : FilterLigands(False)).grid(row = 1, column = 2, sticky = N, pady = 10) #, columnspan = 3)
Button(LigandFilterWin, text = "Apply",width = 50, height = 2, command = lambda : FilterLigands(True)).grid(row = 5, column = 0, columnspan = 3, pady = 10)
def FilteringDefaults(param = None):
# The function set the default values for all the single parameters
# as well as for the entire sets.
#
verbose = False
if not param:
param = FilterSet.get()
# calculate how many torsions are left counting the flex residues, if present
max_tors = AutoDockMaxTORSDOF.get() - FlexResTORSDOF.get() # Include the FlexResidues into the count of max TORSDOF
if verbose or DEBUG: print "FILTERING DEFAULTS> setting the max TORSDOF to ", max_tors
if param == "HbD":
if FilterSet.get() == "Default":
HbDmin.set(0), HbDmax.set(99)
if FilterSet.get() == "Lipinski-like":
HbDmin.set(0), HbDmax.set(5)
if FilterSet.get() == "DrugLikeness":
HbDmin.set(0), HbDmax.set(5)
if FilterSet.get() == "DrugLikeness (frag)":
HbDmin.set(0), HbDmax.set(3)
if param == "HbA":
if FilterSet.get() == "Default":
HbAmin.set(0), HbAmax.set(99)
if FilterSet.get() == "Lipinski-like":
HbAmin.set(0), HbAmax.set(10)
if FilterSet.get() == "DrugLikeness":
HbAmin.set(0), HbAmax.set(10)
if FilterSet.get() == "DrugLikeness (frag)":
HbAmin.set(0), HbAmax.set(6)
if param == "MW":
if FilterSet.get() == "Default":
MWmin.set(0), MWmax.set(9999)
if FilterSet.get() == "Lipinski-like":
MWmin.set(0), MWmax.set(500)
if FilterSet.get() == "DrugLikeness":
MWmin.set(160), MWmax.set(480)
if FilterSet.get() == "DrugLikeness (frag)":
MWmin.set(160), MWmax.set(300)
if param == "Nat":
if FilterSet.get() == "Default":
NatMin.set(0), NatMax.set(999) # TODO use the right value for unix (2048) or cygwin (128) max atoms ?
if FilterSet.get() == "Lipinski-like":
NatMin.set(0), NatMax.set(999)
if FilterSet.get() == "DrugLikeness":
NatMin.set(20), NatMax.set(70)
if FilterSet.get() == "DrugLikeness (frag)":
NatMin.set(6), NatMax.set(45)
if param == "TORSDOF":
if FilterSet.get() == "Default":
TORSDOFmin.set(0), TORSDOFmax.set(max_tors)
if FilterSet.get() == "Lipinski-like":
TORSDOFmin.set(0), TORSDOFmax.set(max_tors)
if FilterSet.get() == "DrugLikeness":
TORSDOFmin.set(0), TORSDOFmax.set(max_tors)
if FilterSet.get() == "DrugLikeness (frag)":
TORSDOFmin.set(0), TORSDOFmax.set(max_tors)
# set the Raccoon defaults
if not param or param == "Default":
HbDmin.set(0), HbDmax.set(99)
HbAmin.set(0), HbAmax.set(99)
MWmin.set(0), MWmax.set(9999)
NatMin.set(0), NatMax.set(999)
TORSDOFmin.set(0), TORSDOFmax.set(max_tors)
DoRejectATypes.set(True)
# http://en.wikipedia.org/wiki/Lipinski%27s_Rule_of_Five
if param == "Lipinski-like":
HbDmin.set(0), HbDmax.set(5)
HbAmin.set(0), HbAmax.set(10)
MWmin.set(0), MWmax.set(500)
NatMin.set(0), NatMax.set(999)
TORSDOFmin.set(0), TORSDOFmax.set(max_tors)
DoRejectATypes.set(True)
# http://en.wikipedia.org/wiki/Lipinski%27s_Rule_of_Five#cite_note-2
if param == "DrugLikeness":
HbDmin.set(0), HbDmax.set(5)
HbAmin.set(0), HbAmax.set(10)
MWmin.set(160), MWmax.set(480)
NatMin.set(20), NatMax.set(70)
TORSDOFmin.set(0), TORSDOFmax.set(max_tors)
DoRejectATypes.set(True)
# Values from Fattori's paper
if param == "DrugLikeness (frag)":
HbDmin.set(0), HbDmax.set(3)
HbAmin.set(0), HbAmax.set(6)
MWmin.set(160), MWmax.set(250)
NatMin.set(6), NatMax.set(45)
TORSDOFmin.set(0), TORSDOFmax.set(max_tors)
DoRejectATypes.set(True)
def FilterLigands(seriously):
accepted_ligands = []
rejected_ligands = []
verbose = False
# VALIDATE INPUT
if CheckLigFilterOptions():
for lig in LigandDictionary.keys():
lig_hba = LigandDictionary[lig]["HbA"]
lig_hbd = LigandDictionary[lig]["HbD"]
lig_tors = LigandDictionary[lig]["TORSDOF"]
lig_mw = LigandDictionary[lig]["MW"]
lig_nat = LigandDictionary[lig]["Nat"]
lig_notstdat = LigandDictionary[lig]["NotStdAT"]
if lig_notstdat and DoRejectATypes:
rejected_ligands.append(lig)
if verbose or DEBUG: print lig, "rejected by NonSTDatom type", LigandDictionary[lig]["NotStdAT"]
else:
if lig_hba >= HbAmin.get() and lig_hba <= HbAmax.get():
if lig_hbd >= HbDmin.get() and lig_hbd <= HbDmax.get():
if lig_tors >= TORSDOFmin.get() and lig_tors <= TORSDOFmax.get():
if lig_mw >= MWmin.get() and lig_mw <= MWmax.get():
if lig_nat >= NatMin.get() and lig_nat <= NatMax.get():
accepted_ligands.append(lig)
if verbose or DEBUG: print "ACCEPTED", lig
else:
rejected_ligands.append(lig)
if verbose or DEBUG: print lig, "rejected number of atoms", lig_nat
else:
if verbose or DEBUG: print lig, "rejected molecular weight", lig_mw
rejected_ligands.append(lig)
else:
rejected_ligands.append(lig)
if verbose or DEBUG: print lig, "rejected torsions", lig_tors
else:
rejected_ligands.append(lig)
if verbose or DEBUG: print lig, "rejected HBD", lig_hbd
else:
rejected_ligands.append(lig)
if verbose or DEBUG: print lig, "rejected HBA", lig_hba
# summarize the filtering process
total = len(LigandDictionary.keys())
rejected = len(rejected_ligands)
accepted = total - rejected
msg = "Total number of ligands: %12s" % str(total)
TotalNumberLigandsMsg.set(msg)
msg = "Accepted ligands: %12s" % str(accepted)
TotAcceptedLigandsMsg.set(msg)
msg = "Rejected ligands: %12s" % str(rejected)
TotRejectedLigandsMsg.set(msg)
# this variable is set for make TheCheck function quicker
TotalAcceptedLigands.set(accepted)
if seriously:
for lig in rejected_ligands:
LigandDictionary[lig]["accepted"] = False
for lig in accepted_ligands:
LigandDictionary[lig]["accepted"] = True
LigandsTag()
try:
TheCheck()
except:
pass
countLigands()
try:
LigandFilterWin.destroy()
except:
return
def LigandsTag():
# Color ligands basing on their status ACCEPTED/REJECTED
acc_col = 'black'
rej_col = 'red'
for item in range(0, LigandScrolledListBox.size()):
if not LigandDictionary[LigandScrolledListBox.get(item)]["accepted"]:
LigandScrolledListBox.itemconfig(item, fg = 'red') #white', bg = '#aa2200')
else:
LigandScrolledListBox.itemconfig(item, fg = 'black') #white', bg = '#22aa00')
return
#########################################################################################################33
#########################################################################################################33
#########################################################################################################33
#########################################################################################################33
#########################################################################################################33
############################### RECEPTOR STUFF
def countReceptors():
# it works for RC's only
if len(receptorFileList) > 0:
message = "Receptor conformations ("+str(len(receptorFileList))+")"
TargetPDBQT.set(message)
else:
TargetPDBQT.set("Import receptor conformations...")
def openReceptorDir(recDir = None):
if not recDir:
recDir = askdirectory()
if recDir:
queue_in = []
queue_out = []
# PDBQT
recFiles = glob.glob(os.path.join(recDir, "*.pdbqt"))
for item in recFiles:
queue_out.append(item)
# PDB/MOL2
recFiles = glob.glob(os.path.join(recDir, "*.pdb"))
for item in recFiles:
queue_in.append(item)
recFiles = glob.glob(os.path.join(recDir, "*.mol2"))
for item in recFiles:
queue_in.append(item)
if len(queue_in) and not tkMessageBox.askokcancel('Non-PDBQT files found',('The directory contains %d structures to be converted in PDBQT.\nDo you want to proceed?' % len(queue_in))):
tkMessageBox.showwarning("Import skipped", "No structures have been imported")
return
DisableInterface()
for file in queue_in:
output_file = file.rsplit(".", 1)[:-1][0]+".pdbqt" # 'Efficient' way to get the stem
InfoMessage.set( ( "=> Generating PDBQT structure for %s" % (os.path.basename(file)[-5:]) ))
root.update()
genPDBQTrec(file, output_file)
queue_out.append(output_file)
for item in checkPDBQTreclist(queue_out):
if item not in receptorFileList:
receptorFileList.append(item)
receptorScrolledListBox.insert('end', item)
MultiReceptorSet.set(True)
countReceptors()
InfoMessage.set("Receptor structures imported successfully")
EnableInterface()
if DoFlex.get() == 1:
ParseFlexSelection()
TheCheck()
def openReceptor(filename = None):
# the input is a list
if filename:
recFile = filename
else:
recFile = askopenfilename(title = "Select one or more target structures...", filetypes=[("Protein/DNA PDBQT", "*.pdbqt"), ("PDB", "*.pdb"), ("Mol2", "*.mol2")], multiple = 1)
if recFile:
queue_in = []
queue_out = []
for file in recFile:
if file[-3:] == "pdb" or file[-4:] == "mol2":
queue_in.append(file)
if file[-5:] == "pdbqt":
queue_out.append(file)
DisableInterface()
for file in queue_in:
output_file = file.rsplit(".", 1)[:-1][0]+".pdbqt" # 'Efficient' way to get the stem
InfoMessage.set( ( "=> Generating PDBQT structure for %s" % (os.path.basename(SingleRecFileAsk)[-5:]) ))
root.update()
genPDBQTrec(file, output_file)
queue_out.append(output_file)
for item in checkPDBQTreclist(queue_out):
if item not in receptorFileList:
receptorFileList.append(item)
receptorScrolledListBox.insert('end', item)
MultiReceptorSet.set(True)
InfoMessage.set( "Receptor structure imported successfully")
EnableInterface()
countReceptors()
if DoFlex.get() == 1:
ParseFlexSelection()
TheCheck()
def removeAllReceptors():
global receptorFileList
if len(receptorFileList) > 1 and not tkMessageBox.askokcancel('Delete all the receptors.','Do you really want to\nremove all the receptors\nfrom the list?'):
return
del receptorFileList[:]
receptorScrolledListBox.clear()
MultiReceptorSet.set(False)
countReceptors()
TheCheck()
def openSingleReceptor(filename = None):
if filename:
SingleRecFileAsk = filename
else:
SingleRecFileAsk = askopenfilename(filetypes=[("Protein/DNA PDBQT", "*.pdbqt"), ("PDB", "*.pdb"), ("Mol2", "*.mol2")])
if SingleRecFileAsk:
# PDBQT structure
if SingleRecFileAsk[-5:] == "pdbqt":
if checkPDBQTrec(SingleRecFileAsk):
singleRecFile = SingleRecFileAsk
RecFilename.set(SingleRecFileAsk)
SingleRecFilenameLabel.config(font = ("Helvetica", 10, "bold") )
SingleReceptorSet.set(True)
ReceptorOptions()
# PDB/Mol2 receptor
elif SingleRecFileAsk[-3:] == "pdb" or SingleRecFileAsk[-4:] == "mol2":
print "PDB/MOL2 receptor"
output_file = SingleRecFileAsk.rsplit(".", 1)[:-1][0]+".pdbqt" # Efficient way to get the stem
if genPDBQTrec(SingleRecFileAsk, output_file):
if checkPDBQTrec(output_file):
singleRecFile = output_file
RecFilename.set(output_file)
SingleRecFilenameLabel.config(font = ("Helvetica", 10, "bold") )
SingleReceptorSet.set(True)
ReceptorOptions()
else:
RecFilename.set('')
SingleReceptorSet.set(False)
AutoGridWhen3.config(state = DISABLED)
TheCheck()
def genPDBQTrec(infile, outfile):
# If this file closely resemble the Prepare_receptor4.py, it's normal.
receptor_filename = infile
outputfilename = outfile
repair_set = RecRepairOptionsSet.get()
if repair_set == 'none':
repairs = None
if repair_set == 'rebuild bonds':
repairs = 'bonds'
if repair_set == 'add H':
repairs = 'hydrogens'
if repair_set == 'add H (if missing)':
repairs = 'checkhydrogens'
if repair_set == 'rebuild bonds + add H':
repairs = 'bonds_hydrogens'
charges_to_add = RecChargeSet.get()
# preserve_charge_types = a # NEGLECTED AS IN THE LIGANDS
cleanup = RecCleanNPH.get()+RecCleanLP.get()+RecCleanWAT.get()+RecDelAlternate.get()
delete_single_nonstd_residues = RecCleanStdRes.get()
verbose = None
mode = 'automatic'
preserve_charge_types = None
mols = Read(receptor_filename)
if verbose: print 'read ', receptor_filename
try:
mol = mols[0]
except:
return False
preserved = {}
if charges_to_add is not None and preserve_charge_types is not None:
preserved_types = preserve_charge_types.split(',')
if verbose: print "preserved_types=", preserved_types
for t in preserved_types:
if verbose: print 'preserving charges on type->', t
if not len(t): continue
ats = mol.allAtoms.get(lambda x: x.autodock_element==t)
if verbose: print "preserving charges on ", ats.name
for a in ats:
if a.chargeSet is not None:
preserved[a] = [a.chargeSet, a.charge]
if len(mols)>1:
if verbose: print "more than one molecule in file"
#use the molecule with the most atoms
ctr = 1
for m in mols[1:]:
ctr += 1
if len(m.allAtoms)>len(mol.allAtoms):
mol = m
if verbose: print "mol set to ", ctr, "th molecule with", len(mol.allAtoms), "atoms"
mol.buildBondsByDistance()
RPO = AD4ReceptorPreparation(mol, mode, repairs, charges_to_add,
cleanup, outputfilename=outputfilename,
preserved=preserved,
delete_single_nonstd_residues=delete_single_nonstd_residues)
if charges_to_add is not None:
#restore any previous charges
for atom, chargeList in preserved.items():
atom._charges[chargeList[0]] = chargeList[1]
atom.chargeSet = chargeList[0]
return True
def checkPDBQTrec(filename):
found_ligand = 0
found_some_atom = 0
for line in open(filename, 'r'):
if line[0:4] == "ROOT":
found_ligand = 1
if line[0:4] == "ATOM":
found_some_atom = 1
if found_ligand == 0:
if found_some_atom == 1:
return True
else:
tkMessageBox.showerror("Receptor Error", "The file is not a valid PDBQT.")
return False
else:
tkMessageBox.showerror("Receptor Error", "The selected PDBQT file is a ligand file...")
return False
def SetFlexibleResidueFile(get_name = None):
global FlexResFileName, FLEX_SET, ResidueStatus, ResidueStatusLoaded
if not get_name:
get_name = askopenfilename(filetypes=[("Flex residue PDBQT", "*.pdbqt")])
S = ""
if get_name:
FlexResFileName.set("")
ResidueCount = 0
try:
file = open(get_name, 'r')
except:
tkMessageBox.showerror("Flexibile Residue Error", "Error while opening the flexible residue file:\n"+get_name)
return False
for line in file:
if line[0:9] == "BEGIN_RES":
ResidueCount += 1
if ResidueCount:
# Chech that torsions are OK in the flex res file
# update the message bar
if ResidueCount >1: S = "s"
FlexResFileName.set(get_name)
FlexResDefined.set(True)
FlexTorsionCount()
ResidueStatusLoaded.set(str(ResidueCount)+" residue"+S+" loaded [ "+str(FlexResTORSDOF.get())+" rotatable bonds ]")
ResidueStatus.set(ResidueStatusLoaded.get())
else:
tkMessageBox.showerror("Flexibile Residue Error", "The loaded PDBQT file is not a flexible residue.")
ResidueStatus.set("")
else:
FlexResTORSDOF.set(0)
FlexResFileName.set("")
ResidueStatus.set("")
FlexTorsionCount()
TheCheck()
def FlexTorsionCount(force = False):
"""-checks the number of rotatable bonds of selected/loaded flexible residues """
verbose = False
if force:
FlexResTORSDOF.set(0)
TORSDOFmax.set(AutoDockMaxTORSDOF.get())
FilteringDefaults("TORSDOF")
return
found_flex_tors = 0
if FlexResFileName.get() == "" and ListFlexResiduesNames.get() == "":
return
# File mode
if DoFlexFromWhat.get() == 1 and not FlexResFileName.get() == "":
for line in open(FlexResFileName.get(), 'r'):
if "active torsions" in line:
found_flex_tors += int(line.split()[1])
# Selection mode
if DoFlexFromWhat.get() == 2 and not ListFlexResiduesNames.get() == "":
list_of_residues = []
list_of_flex_res_atypes = []
selection = ListFlexResiduesNames.get()
selection = selection.replace(' ', '')
selection = selection.split(',')
for res in set(selection):
res = res.split(':')
res_nam = res[-1][0:3]
list_of_residues.append(res_nam)
for res in list_of_residues:
found_flex_tors += ResidueRotatableBondTable[res][0]
if verbose or DEBUG: print " adding %s rot's for %s" % ( ResidueRotatableBondTable[res_nam][0], res_nam)
if verbose or DEBUG: print "FLEX> this is the final count of rotatable bonds included for the flex res count:", found_flex_tors
# Too many rotatable bonds reached
if found_flex_tors > AutoDockMaxTORSDOF.get():
tkMessageBox.showerror("Too many rotatable bonds", ("The imported flex residues have %s rotatable bonds.\n\
The maximum number of rotatable bonds allowed by AutoDock is %s." % (found_flex_tors, AutoDockMaxTORSDOF.get() )))
FlexResTORSDOF.set(0)
# Remove the flex res settings
if DoFlexFromWhat.get() == 1:
FlexResFileName.set("")
FlexResDefined.set(False)
ResidueStatus.set("")
FlexResTORSDOF.set(0)
TORSDOFmax.set(AutoDockMaxTORSDOF.get())
FilteringDefaults("TORSDOF")
TheCheck()
return False
if DoFlexFromWhat.get() == 2:
ResidueStatus.set("[ none ]")
FlexResDefined.set(False)
FlexResTORSDOF.set(0)
TORSDOFmax.set(AutoDockMaxTORSDOF.get())
FilteringDefaults("TORSDOF")
TheCheck()
return False
# Maximum rotatable bonds limit reached
if found_flex_tors == AutoDockMaxTORSDOF.get():
tkMessageBox.showwarning("Rotatable bonds limit", ("The imported flex residues have the maximum number of allowed rotatable \
bonds (%s).\n\nOnly rigid ligands will be accepted for the docking!" % (AutoDockMaxTORSDOF.get() )))
FlexResTORSDOF.set( found_flex_tors )
if len(LigandDictionary):
tkMessageBox.showinfo("AutoDock rotatable bonds", ("The imported flex residues have %s rotatable bonds.\n\nThe maximum \
number of rotatable bonds for ligands will be set set to %s and the ligand set will be filtered with this \
value." % (found_flex_tors, AutoDockMaxTORSDOF.get()-found_flex_tors ) ))
FilteringDefaults("TORSDOF")
FilterLigands(True)
if DEBUG:
print "FLEX> found a total of %s rotatable bonds in the flexible residue" % found_flex_tors
return True
def EnableFlexFromFile():
global Single_target_radio, Multi_target_radio, SingleTargetPanel, MultiTargetPanel, group_receptor1
global group_receptor2, ResidueOrigin, receptorScrolledListBox
global SingleRecStatus, FlexResFile, ImportFlexResPDBQT, FlexResFileNameLabel, FlexResListEntry
global FlexResStatus, FlexResListSet, DoFlex, ResidueStatus, ResidueStatusLoaded
# Activate all buttons to load and display flex res filename
ImportFlexResPDBQT.config(state=NORMAL)
FlexResFileNameLabel.config(state=NORMAL)
# Deactivate all buttons to select flex res filename
FlexResListEntry.config(state = DISABLED)
FlexResListSet.config(state = DISABLED)
# Check if there was a previous filename defined
# and test the file again, else undefine
# the FlexResDefined (maybe activated from a selection of residues)
if FlexResFileName.get() == '':
FlexResDefined.set(False)
ResidueStatus.set(ResidueStatusLoaded.get())
try:
FlexTorsionCount()
except:
pass
try:
TheCheck()
except:
return
def EnableFlexFromSel():
global Single_target_radio, Multi_target_radio, SingleTargetPanel, MultiTargetPanel, group_receptor1
global group_receptor2, ResidueOrigin, receptorScrolledListBox, SingleRecStatus, FlexResFile, ImportFlexResPDBQT
global FlexResFileNameLabel, FlexResListEntry, FlexResStatus,FlexResListSet, DoFlex, ResidueStatus
# Activate all buttons to load and display flex res filename
ImportFlexResPDBQT.config(state=DISABLED)
FlexResFileNameLabel.config(state=DISABLED)
# Deactivate all buttons to select flex res filename
FlexResListEntry.config(state = NORMAL)
FlexResListSet.config(state = NORMAL)
# Check if there was a previous selection defined and
# test it again, else undefine the FlexResDefined (maybe activated from a filename)
if not ListFlexResiduesNames.get() == '':
FlexResDefined.set(False)
ResidueStatus.set(ResidueStatusSelected.get())
try:
ParseFlexSelection()
except:
pass
try:
TheCheck()
except:
return
def ParseFlexSelection():
verbose = False
if not DoFlexFromWhat.get() == 2:
return
# figure out if the receptor is the single conformation or a multi_snapshot
if RCstatus.get() == 0 and SingleReceptorSet.get():
receptor_list = [RecFilename.get()]
elif RCstatus.get() == 1 and MultiReceptorSet.get():
receptor_list = receptorScrolledListBox.get('0', END)
else:
if RCstatus.get() == 0:
SingleRecButton.flash()
if RCstatus.get() == 1:
AddAReceptorButton.flash()
return
found = []
missing = []
chain_list = []
found_flex_tors = 0
selection = ListFlexResiduesNames.get()
selection = selection.replace(' ', '')
selection = selection.split(',')
# ARG9, B:THR276
if not selection == ['']: # empty residue list... don't waste my time, please...
for receptor in receptor_list:
# File opening
if verbose or DEBUG: print "============> Checking receptor", receptor
file = open(receptor, 'r')
protein = file.readlines()
file.close
del found[:]
for res in set(selection): # changed from "selection" to "set(selection)" to avoid duplicates
FOUND = False
residue = res
if verbose or DEBUG: print "\nThis would be the residue", res
res = res.split(':')
if verbose or DEBUG: print res
res_nam = res[-1][0:3]
if verbose or DEBUG: print "residue name =>", res_nam
res_num = res[-1][3:]
if verbose or DEBUG: print "residue numb =>", res_num
if res_num == '':
if verbose or DEBUG: print "NO NUMBER SPECIFIED!"
tkMessageBox.showwarning("Wrong residue(s) specification", "Residues must be specified using\
the following syntax.\nFor example, 'threonine 276' can be either:\n\n\tTHR276\n\t\
( any )\n\n\tB:THR276\n\t ( chain B only )\n\nMultiple residues can be specified\
by separating them with a comma (',') as:\n\n\tTHR276, HIS229\n\n\tB:THR276, B:HIS229")
FlexResDefined.set(False)
TheCheck()
return False
if len(res) > 1: # there is a chain specification
chain = res[-2]
if verbose or DEBUG: print "chain =>", chain
else:
chain = ''
for line in protein:
if line[0:4] == 'ATOM' or line[0:6] == 'HETATM':
if res_nam == line[17:20].split()[0]:
if res_num == line[22:26].split()[0]:
if chain in line[21]:
FOUND = True
if verbose or DEBUG: print line # useful for debugging, do not remove!
if line[21] not in chain_list:
chain_list.append(line[21])
if FOUND:
if verbose or DEBUG: print "FOUND THE RESIDUE %s in %s" % (res, receptor)
found.append([residue, ( len(chain_list) )])
del chain_list[:]
else:
missing.append(residue)
if verbose or DEBUG: print "XXXX this res is missing: ", res
if verbose or DEBUG: print "this is a window with an error of residue"
if len(missing) > 0:
if verbose or DEBUG: print "XXXX some residues are missing"
if verbose or DEBUG: print "this is a window with an error of residue"
if verbose or DEBUG: print missing
msg_missing = '\n'
for item in missing:
msg_missing = msg_missing+"\t-> "+item+"\n"
tkMessageBox.showwarning("Unable to find residue(s)", ("The following residue(s) \
are missing:\n"+msg_missing+"\n\n - Check the syntax (i.e. \'THR276', 'B:THR276' or 'B:THR276,B:HIS229')\n\n - Specify different residues.\n"))
ResidueStatus.set("[ none ]")
FlexResDefined.set(False)
TheCheck()
return False
if len(selection) == len(found):
total = 0
for i in range(len(found)):
total = total + found[i][1]
# The selection is copied into the variable used at the end
FlexResSelected.set(ListFlexResiduesNames.get())
# here goes the check torsions
if not FlexTorsionCount():
return False
ResidueStatusSelected.set(( str(total)+" residue(s) selected [ "+ str(FlexResTORSDOF.get())+" rotatable bonds ]"))
#EnableFlexFromSel() # TODO Possibly useless here...
ResidueStatus.set(ResidueStatusSelected.get())
FlexResDefined.set(True)
TheCheck()
return True
else:
FlexResDefined.set(False)
ResidueStatusSelected.set("[ none ]")
TheCheck()
return False
else: # empty the residue definition if no argument is present in the entry
if DEBUG: print "no residues"
ResidueStatusSelected.set("[ none ]")
ResidueStatus.set("[ none ]")
FlexResDefined.set(False)
TheCheck()
if DEBUG: print "again, no residues"
return False
def MakeReceptorMenu():
global Single_target_radio, Multi_target_radio, SingleTargetPanel, MultiTargetPanel, group_receptor1, group_receptor2, ResidueOrigin, receptorScrolledListBox, FlexResFile, ImportFlexResPDBQT, FlexResFileName, FlexResFileNameLabel, FlexResList, FlexResListEntry, FlexResStatus, FlexResListSet, DoFlex, ResidueStatus, SingleRecFilenameLabel, SingleRecButton, AddAReceptorButton
ReceptorRadioChoice = Pmw.Group( p2, tag_pyclass = None)
ReceptorRadioChoice.pack()
Single_target_radio = Radiobutton(ReceptorRadioChoice.interior(), text='Single target', value=0, variable=RCstatus, state=ACTIVE, command=ReceptorOptions)
Multi_target_radio = Radiobutton(ReceptorRadioChoice.interior(), text='Multiple conformations', value=1, variable=RCstatus, command=ReceptorOptions)
Single_target_radio.pack(anchor=NW, side = LEFT, expand = 0, padx = 5)
Multi_target_radio.pack(anchor=NW, side = LEFT, expand = 0, padx = 5)
# Group containing the structure(s) choices ###################################
group_receptor1 = Pmw.Group(p2, tag_textvariable = TargetPDBQT)
# Single receptor menu
SingleTargetPanel = Frame(group_receptor1.interior(), relief=FLAT )
SingleRecFilenameLabel = Label(SingleTargetPanel, textvariable = RecFilename)
SingleRecFilenameLabel.pack()
SingleRecButton = Button(SingleTargetPanel, text="Add receptor file...", command = openSingleReceptor)
SingleRecButton.pack(expand=YES, anchor=CENTER, side=LEFT)
# Multi-receptor menu
MultiTargetPanel = Frame(group_receptor1.interior(), relief=FLAT)
receptorScrolledListBox = Pmw.ScrolledListBox(MultiTargetPanel) #, hull_width = 800, hull_height = 200, usehullsize= 1) # THAT's A ugly workaround I should get rid of...
receptorScrolledListBox.grid(row = 0, column = 0, sticky = N+W+E, columnspan = 10)
AddAReceptorButton = Button(MultiTargetPanel, text='Add a structure...', command=openReceptor)
AddAReceptorButton.grid(row = 1, column = 0, padx = 5)
Button(MultiTargetPanel, text='Add a directory...', command=openReceptorDir).grid(row = 1, column = 1, padx = 5)
Button(MultiTargetPanel, text='Remove a structure', command=removeReceptor).grid(row = 1, column = 2, padx = 5)
Button(MultiTargetPanel, text='Remove all', command=removeAllReceptors).grid(row = 1, column = 3, padx = 5)
group_receptor1.pack(fill = BOTH, expand = 1, padx = 10, pady = 10, anchor = N, side = TOP)
# Group containing the flexible residues choice #######################################
group_receptor2 = Pmw.Group(p2, tag_text = 'Flexible residues', tag_pyclass = Tkinter.Checkbutton, tag_variable = DoFlex, tag_command = SetFlexibleMode)
group_receptor2.pack(fill = 'x', expand = 0, padx = 10, pady = 10, anchor = N, side = TOP)
FlexResFile = Radiobutton(group_receptor2.interior(), text='From file', value=1, variable=DoFlexFromWhat, command = EnableFlexFromFile)
FlexResFile.grid(row = 0, column = 0, sticky = W)
ImportFlexResPDBQT = Tkinter.Button(group_receptor2.interior(), text="Import PDBQT", command=SetFlexibleResidueFile)
ImportFlexResPDBQT.grid(row = 0, column = 1, sticky = W)
FlexResFileNameLabel = Label(group_receptor2.interior(), textvariable=FlexResFileName)
FlexResFileNameLabel.grid(row = 0, column = 2, sticky = W)
FlexResList = Radiobutton(group_receptor2.interior(), text='From selection', value=2, variable=DoFlexFromWhat, command = EnableFlexFromSel)
#FlexResList.config(fg = 'red')
FlexResList.grid(row = 1, column = 0, sticky = W)
FlexResListEntry = Tkinter.Entry(group_receptor2.interior(), textvariable=ListFlexResiduesNames)
FlexResListEntry.grid(row = 1, column = 1, sticky = W)
FlexResListSet = Button(group_receptor2.interior(), text='Set', command = ParseFlexSelection)
FlexResListSet.grid(row = 1, column = 2, sticky = W)
FlexResStatus = Label(group_receptor2.interior(), textvariable = ResidueStatus)
FlexResStatus.grid(row = 2, column = 1, sticky = W, columnspan = 3)
DefaultRec = Tkinter.Button(p2, text="PDBQT generation options", command = ReceptorImportOptions).pack()
def ReceptorImportOptions():
global RecRepairOptions
try:
ReceptorOptionsWin.lift()
except:
ReceptorOptionsWin = Toplevel(root)
ReceptorOptionsWin.title("Receptor PDBQT generation options")
ReceptorOptionsWin.winfo_toplevel().resizable(NO,NO)
ChargeFrame = Pmw.Group(ReceptorOptionsWin, tag_text = "Partial charges")
Radiobutton(ChargeFrame.interior(), text="Add Gasteiger", variable = RecChargeSet, value = "gasteiger").grid(row = 0, column = 0, sticky = W, padx = 5) # Default
Radiobutton(ChargeFrame.interior(), text="Keep original", variable = RecChargeSet, value = "").grid(row = 0, column = 1, sticky = W, padx = 5)
ChargeFrame.grid(row = 2, column = 0, padx = 10, pady = 5, sticky = N)
CleanupFrame = Pmw.Group(ReceptorOptionsWin, tag_text = "Remove")
Label(CleanupFrame.interior(), text = "yes").grid(row = 0, column = 1, sticky = W, pady = 2)
Label(CleanupFrame.interior(), text = "no").grid(row = 0, column = 2, sticky = W, pady = 2)
Label(CleanupFrame.interior(), text = "Non-polar H").grid(row = 1, column = 0, sticky = E, pady = 3)
Radiobutton(CleanupFrame.interior(), variable = RecCleanNPH, value = "_nphs" ).grid(row = 1 , column = 1, sticky = N, pady = 3)
Radiobutton(CleanupFrame.interior(), variable = RecCleanNPH, value = "" ).grid(row = 1 , column = 2, sticky = N, pady = 3)
Label(CleanupFrame.interior(), text = "Lone pairs").grid(row = 2, column = 0, sticky = E, pady = 3)
Radiobutton(CleanupFrame.interior(), variable = RecCleanLP, value = "_lps" ).grid(row = 2 , column = 1, sticky = N , pady = 3)
Radiobutton(CleanupFrame.interior(), variable = RecCleanLP, value = "" ).grid(row = 2 , column = 2, sticky = N , pady = 3)
Label(CleanupFrame.interior(), text = "Water mol's").grid(row = 3, column = 0, sticky = E, pady = 3)
Radiobutton(CleanupFrame.interior(), variable = RecCleanWAT, value = "_waters" ).grid(row = 3 , column = 1, sticky = N , pady = 3)
Radiobutton(CleanupFrame.interior(), variable = RecCleanWAT, value = "" ).grid(row = 3 , column = 2, sticky = N , pady = 3)
Label(CleanupFrame.interior(), text = "Not-standard res").grid(row = 4, column = 0, sticky = E, pady = 3)
Radiobutton(CleanupFrame.interior(), variable = RecCleanStdRes, value = True ).grid(row = 4 , column = 1, sticky = N , pady = 3)
Radiobutton(CleanupFrame.interior(), variable = RecCleanStdRes, value = False ).grid(row = 4 , column = 2, sticky = N , pady = 3)
Label(CleanupFrame.interior(), text = "Alternate chains (B)").grid(row = 5, column = 0, sticky = E, pady = 3)
Radiobutton(CleanupFrame.interior(), variable = RecDelAlternate, value = "deleteAltB" ).grid(row = 5 , column = 1, sticky = N , pady = 3)
Radiobutton(CleanupFrame.interior(), variable = RecDelAlternate, value = "" ).grid(row = 5 , column = 2, sticky = N , pady = 3)
CleanupFrame.grid(row = 3, column = 0, padx = 10, pady = 5, sticky = N)
RepairFrame = Pmw.Group(ReceptorOptionsWin, tag_text = "Structure repair")
# label
RecRepairOptions = OptionMenu(RepairFrame.interior(), RecRepairOptionsSet, "none", "rebuild bonds", "add H", "add H (if missing)", "rebuild bonds + add H")
RecRepairOptions.grid(row = 4, padx = 10, sticky = N)
RepairFrame.grid(row = 5, column = 0, padx = 10, pady = 5, sticky = N)
Tkinter.Button(ReceptorOptionsWin, text="OK", command = ReceptorOptionsWin.destroy, width = 20 ).grid(row = 9, column = 0, sticky = S, columnspan = 2, pady = 10, padx = 10)
Tkinter.Button(ReceptorOptionsWin, text="Set defaults", command = ReceptorOptionsDefault, width = 10).grid(row = 0, column = 0, columnspan = 3, sticky = S, pady = 10, padx = 10)
def ReceptorOptionsDefault():
RecChargeSet.set('gasteiger')
RecCleanNPH.set('_nphs')
RecCleanLP.set('_lps')
RecCleanWAT.set('_waters')
RecCleanStdRes.set(False)
RecDelAlternate.set('')
RecRepairOptionsSet.set('add H (if missing)')
def ReceptorOptions():
verbose = False
global SingleTargetPanel, MultiTargetPanel, group_receptor1, group_receptor2, RCstatus, FlexResFile, ImportFlexResPDBQT, FlexResFileNameLabel, FlexResList, FlexResListEntry, AutoGridWhen1, AutoGridWhen2, AutoGridWhen3 #, TargetPDBQT
if RCstatus.get() == 0: # Single Target
if verbose: print "I'm running the RCstatus with this value:", RCstatus.get()
MultiTargetPanel.forget()
SingleTargetPanel.pack(expand = YES, fill = 'x')
TargetPDBQT.set("Receptor structure")
if DoFlex.get() == 1:
FlexResFile.config(state=NORMAL)
ImportFlexResPDBQT.config(state=NORMAL)
FlexResFileNameLabel.config(state=NORMAL)
ParseFlexSelection()
if AutoGridWhen2:
if not system == "Windows":
AutoGridWhen2.config(state = NORMAL)
if AutoGridWhen3 and TotalAcceptedLigands.get():
AutoGridWhen3.config(state = NORMAL)
if RCstatus.get() == 1: # Multiple Targets
if verbose: print "I'm running the RCstatus with this value:", RCstatus.get()
SingleTargetPanel.forget()
FlexResFile.config(state=DISABLED)
FlexResFileNameLabel.config(state=DISABLED)
ImportFlexResPDBQT.config(state=DISABLED)
countReceptors()
if DoFlex.get() == 1:
ParseFlexSelection()
MultiTargetPanel.pack(expand = YES, fill = BOTH)
if AutoGridWhen3:
AutoGridWhen3.config(state = DISABLED)
try:
TheCheck()
except:
return
def SetFlexibleMode():
global Single_target_radio, Multi_target_radio, SingleTargetPanel, MultiTargetPanel, group_receptor1, group_receptor2, ResidueOrigin, receptorScrolledListBox, SingleRecStatus, FlexResFile, ImportFlexResPDBQT, FlexResFileNameLabel, FlexResListEntry, FlexResStatus,FlexResListSet, DoFlex
# To initialize the default flexible option as "from file"
if DoFlexFromWhat.get() == -1:
FlexResFile.invoke()
if DoFlex.get() == 0:
FlexResFile.config(state = DISABLED)
ImportFlexResPDBQT.config(state=DISABLED)
FlexResFileNameLabel.config(state=DISABLED)
FlexResList.config(state = DISABLED)
FlexResListEntry.config(state = DISABLED)
FlexResListSet.config(state = DISABLED)
FlexResStatus.config(state = DISABLED)
FlexResListSet.config(state = DISABLED)
FlexTorsionCount(force = True)
try:
TheCheck()
except:
pass
if DoFlex.get() == 1:
if RCstatus.get() == 0: # Single receptor mode enable the "From file button"
FlexResFile.config(state = NORMAL)
ImportFlexResPDBQT.config(state=NORMAL)
FlexResFileNameLabel.config(state=NORMAL)
FlexResListSet.config(state = NORMAL)
FlexResList.config(state = NORMAL)
FlexResListEntry.config(state = NORMAL)
FlexResStatus.config(state = NORMAL)
FlexResListSet.config(state = NORMAL)
FlexResListSet.config(state = NORMAL)
FlexTorsionCount()
try:
TheCheck()
except:
pass
###### Estetical tricks
def FontSizeInc():
pass
# TODO
def FontSizeDec():
pass
# TODO
#########################
### GPF RELATED FUNCTIONS
def MakeGPFMenu():
global CacheMapFrame, GPFframe, CacheMapHandleNow, CacheMapHandle, GPFcontent, GPFedit, GPFsave, GPFFilenameLabel, GPFload, CacheMapDir, CacheMapDirLabel, MapFolderList
# The GPF management facility is contained here in GPFframe
# GPF edit group
GPFframe = Pmw.Group(p3, tag_text = 'GPF template')
GPFload = Button(GPFframe.interior(), text='Load GPF template...', command=opengpf)
GPFload.grid(row = 0, column = 0, sticky = W, columnspan = 1)
GPFedit = Button(GPFframe.interior(), text='Edit', command=editGPF, state = DISABLED, width = 13)
GPFedit.grid(row = 2, column = 0, sticky = W)
GPFsave = Button(GPFframe.interior(), text='Apply changes', command=saveGPFchanges)#, state = DISABLED)
GPFFilenameLabel = Label(GPFframe.interior(), textvariable=GPFfilename, state = DISABLED)
GPFFilenameLabel.grid(row = 0, column = 1, sticky = E)
# GPF Text editor
GPFcontent = Text(GPFframe.interior(), height=22, width = 100)
GPFscroll = Scrollbar(GPFframe.interior(), command=GPFcontent.yview)
GPFscroll.grid(row = 1, column = 3, sticky = N+S)
GPFcontent.configure(yscrollcommand=GPFscroll.set)
GPFcontent.grid(row = 1, column = 0, columnspan = 3, sticky = N+S+W+E)
GPFcontent.config(fg = 'black', font = ("Courier", 11, "normal"))
CacheMapHandleNow = Pmw.Group(GPFframe.interior(), tag_text="Cached maps")
CacheMapOptionsNow = OptionMenu(CacheMapHandleNow.interior(), CacheMapPolicy, "Make copies [ use more disk space ]", "Make symbolic links [ save disk space ]")
CacheMapPolicy.set('Make copies [ use more disk space ]')
CacheMapOptionsNow.grid(row = 1, column = 3, columnspan = 2)
# The cached maps management facility is contained here in CacheMapFrame
# Cached maps group
CacheMapFrame = Pmw.Group(p3, tag_text = 'Pre-calculated maps')
CacheMapDir = Button(CacheMapFrame.interior(), text='Select the cached maps directory', command=opendirMaps) #, state = DISABLED)
CacheMapDir.grid(row = 0, column = 0)
CacheMapDirLabel = Label(CacheMapFrame.interior(), textvariable = CacheMapDirName, state = DISABLED)
CacheMapDirLabel.grid(row = 0, column = 1)
# Maps folder browser
MapFolderScroll = Scrollbar(CacheMapFrame.interior())
MapFolderList = Listbox(CacheMapFrame.interior(), yscrollcommand = MapFolderScroll.set, width = 90)
MapFolderScroll.config(command = MapFolderList.yview )
# TODO Add an orizontal scroll list?
MapFolderScroll.grid(row = 1, column = 3, sticky = N+S)
MapFolderList.grid(row = 1, column = 0, sticky = W+E, columnspan = 3)
MapFolderList.insert(END, "[no map directory defined yet... ]")
MapFolderScroll = Scrollbar(CacheMapFrame.interior(), command = MapFolderList.yview)
CacheMapHandle = Pmw.Group(CacheMapFrame.interior(), tag_text="Cached maps")
CacheMapOptions = OptionMenu(CacheMapHandle.interior(), CacheMapPolicy, "Make copies [ use more disk space ]", "Make symbolic links [ save disk space ]")
CacheMapPolicy.set('Make copies [ use more disk space ]')
CacheMapOptions.grid(row = 5, column = 1, columnspan = 2)
CacheMapHandle.grid(row = 2, column = 0, columnspan = 2)
if system == "Windows":
CacheMapOptionsNow.config(state = DISABLED)
CacheMapOptions.config(state = DISABLED)
def MapMenu():
for item in CacheMapFrame, GPFframe, CacheMapHandle:
if item:
item.forget()
try:
if AGoptions:
AGoptions.forget()
except:
pass
if CacheMapHandleNow:
CacheMapHandleNow.grid_forget()
state = MapSource.get()
if state == 0: # Use the GPF to run AutoGrid in all the jobs
GPFframe.pack(fill = BOTH, expand = 1, padx = 10, pady = 3, side = TOP, anchor = N)
if state == 1: # Use the GPF to run AutoGrid now, then cache the maps
AGoptions.pack()
GPFframe.pack(fill = BOTH, expand = 1, padx = 10, pady = 10)
CacheMapHandleNow.grid(row = 2, column = 1, sticky = W, columnspan = 1)
if not AutoGridBin.get():
WhichAutoGrid()
if state == 2: # Use the maps in the cache folder
CacheMapFrame.pack(fill = BOTH, expand = 1, padx = 10, pady = 10)
try:
TheCheck()
except:
pass
def setGPFtags(): # Inspired by: http://effbot.org/tkinterbook/text.htm
GPFcontent.tag_remove('keyword', '1.0', END)
GPFcontent.tag_remove('comment', '1.0', END)
for keyw in GPFkeywords:
idx = '1.0'
while 1:
idx = GPFcontent.search(keyw, idx, stopindex=END)
if not idx: break
lastidx = '%s+%dc' % (idx, len(keyw))
if idx.split('.')[1] == "0":
GPFcontent.tag_add('keyword', idx, lastidx)
idx = lastidx
GPFcontent.tag_config('keyword', font = ("Courier", 11, "bold"), foreground = 'blue')
idx = '1.0'
while 1:
idx = GPFcontent.search("#", idx, stopindex=END)
if not idx: break
lastidx = idx.split('.')[0]+".end"
GPFcontent.tag_add('comment', idx, lastidx)
idx = lastidx
GPFcontent.tag_config('comment', foreground = 'gray')
def removeGPFtags(): # Inspired by: http://effbot.org/tkinterbook/text.htm
GPFcontent.tag_remove('keyword', '1.0', END)
GPFcontent.tag_remove('comment', '1.0', END)
def opengpf():
# Provides:
# GPFlines = list of lines contained in the GPF (=> prepare_x scripts)
# GPFParameterFile = filename of the parameter file required by the GPF (if found)
#
global GPFlines, GPFcontent, GPFedit, GPFsave, GPFFilenameLabel, GPFParameterFile
GPFcontent.tag_config("npts", foreground="red")
gpfFile = askopenfilename(filetypes=[("Grid Parameter File", "*.gpf")])
if DEBUG: print gpfFile
if gpfFile:
gpftemplate = gpfFile
ask_for_param_file = 0
GPFParameterFile.set("")
GPFcontent.config(state = NORMAL)
GPFcontent.delete(1.0, END)
for line in open(gpfFile, 'r'): # surprisingly, adding the text to the editor worked at the first attempt....
if line[0:14] == "parameter_file":
if DEBUG: print "I found a param file in %s!" % gpfFile
ask_for_param_file = 1
param_file_name = line.split()[1]
GPFcontent.insert(END, line)
GPFlines = GPFcontent.get(1.0, END)
GPFfilename.set(gpfFile)
GPFFilenameLabel.config(state = NORMAL)
if ask_for_param_file == 1:
tkMessageBox.showwarning("Parameter file required", "A parameter file is required by the GPF:\n => %s \n The filename location must be specified..." % param_file_name)
askGPFParamFile(param_file_name)
else:
GPFcontent.config(state = DISABLED)
GPFedit.config(state = ACTIVE)
setGPFtags()
TheCheck()
def askGPFParamFile(filename):
# ask the user the location of the ADX.X_xxxx.dat file found in the GPF
#
# Provides:
# defines the GPFParameterFile
keepasking = True
while keepasking == True:
parameter_filename = askopenfilename(filetypes=[("AutoDock Parameter File", filename)])
if parameter_filename:
GPFParameterFile.set(parameter_filename)
keepasking = False
GPFcontent.config(state = DISABLED)
GPFedit.config(state = ACTIVE)
return True
else:
answer = tkMessageBox.askquestion('Warning', 'The file is required by the GPF.\nDo you want to define it?')
if answer == "no":
tkMessageBox.showwarning("Error", "The file is essential for this GPF.\nRe-import the GPF and set the correct parameter file.")
# empty the GPF buffer and the entry in GPF the editor
GPFlines = None
GPFcontent.delete(1.0, END)
GPFfilename.set("[ no GPF loaded ]")
keepasking = False
GPFcontent.config(state = DISABLED)
GPFedit.config(state = DISABLED)
return False
def editGPF():
GPFcontent.config(state = NORMAL)
GPFedit.grid_forget()
GPFload.config(state = DISABLED)
GPFcontent.config(fg = 'red', font = ("Courier", 11, "bold"))
GPFsave.config(fg = 'red', width = 13)
GPFsave.grid(row = 2, column = 0, sticky = W)
removeGPFtags()
def saveGPFchanges():
GPFlines = GPFcontent.get(1.0, END)
GPFload.config(state = NORMAL)
GPFcontent.config(fg = 'black', font = ("Courier", 11, "normal"))
GPFcontent.config(state = DISABLED)
GPFsave.grid_forget()
setGPFtags()
GPFedit.grid(row = 2, column = 0, sticky = W)
setGPFtags()
def disableGPF():
GPFcontent.config(fg = 'gray', font = ("Courier", 11, "normal"))
GPFcontent.config(state = DISABLED)
GPFedit.config(state = DISABLED)
GPFload.config(state = DISABLED)
GPFFilenameLabel.config(state = DISABLED)
if not CacheMapDirName.get() == "[ none ]":
CacheMapDir.config(state = NORMAL)
else:
CacheMapDir.config(state = NORMAL)
CacheMapDir.flash()
def enableGPF():
GPFcontent.config(fg = 'black', font = ("Courier", 11, "normal"))
GPFcontent.config(state = NORMAL)
GPFedit.config(state = NORMAL)
GPFload.config(state = NORMAL)
CacheMapDir.config(state = DISABLED)
setGPFtags()
def opendirMaps(mapfolder = None):
# Check map integrity and presence of all maps for all atom types
#
#
#
global LIGAND_SET , mapDir
FldFound, XyzFound = False, False
accepted_maps = []
if not mapfolder:
mapDir = askdirectory(title = "Select the dir containing the grid maps...")
else:
mapDir = mapfolder
if mapDir:
MapFolderList.delete(0, END)
DoCachedMaps.set(False)
# collect all the atomic maps
mapFiles = glob.glob(os.path.join(mapDir, "*.map"))
# add the *.fld and *.xyz maps
for extra_map in glob.glob(os.path.join(mapDir, "*.maps.*")):
mapFiles.append(extra_map)
# Prune possible dirs matching "*map*" pattern
for item in mapFiles:
if os.path.isdir(item):
del mapFiles[mapFiles.index(item)]
if len(mapFiles):
for map in mapFiles:
if map[-8:] == "maps.fld":
FldFound = True
if map[-8:] == "maps.xyz":
XyzFound = True
if not FldFound: # manage possible errors
tkMessageBox.showerror("Map file not found!", "The .fld map is missing.\nSelect another directory.")
elif not XyzFound:
tkMessageBox.showerror("Map file not found!", "The .xyz map is missing.\nSelect another directory.")
# ...then check for necessary atom types if ligands have been set
if XyzFound and FldFound:
CheckFolderMap(mapFiles)
TheCheck()
def CheckFolderMap(MapFileList):
# Check for mapfiles for all the atom types (+e +d) that
# are found in the ligands of the Great Book of Ligands
# and assure that all the maps are consistent
# (same parameters)
MissingMaps = []
FolderIsOk = True
MapConsistency = True
del MissingMaps[:]
missing_files = []
receptor_stem = (os.path.basename(RecFilename.get())).split(".")[0]
if DEBUG: print "CheckFolderMap> RECEPTOR_STEM", receptor_stem
# Check for all atom types maps
for atype in AtypeList:
if AtypeList[atype][0] > 0:
missing = 1
map_file_name = receptor_stem+"."+atype+".map"
print "MISSING", map_file_name
for item in MapFileList:
print "CHECK ITEM", item
if map_file_name in item:
missing = 0
break
else:
print "\t %s is not in %s" % (map_file_name, item)
missing_files.append(map_file_name)
print MapFileList
if missing_files:
miss_text = ""
for file in missing_files:
miss_text += "\n\t"+file
tkMessageBox.showerror("Missing maps", ("The following maps are missing:"+miss_text+"\n\nPlease specify another directory."))
MapFolderList.delete(0, END)
DoCachedMaps.set(False)
CacheMapDirName.set("[ none ]")
CacheMapDirLabel.config(state = DISABLED)
InfoMessage.set("Some maps are missing.")
return False
#GetAtypes(selection = )
# Selection mode
if DoFlexFromWhat.get() == 2 and not ListFlexResiduesNames.get() == "":
for res_type in ListFlexResiduesNames.get():
flex_types += ResidueRotatableBondTable[res_type][0]
for atype in AtypeList:
if AtypeList[atype][0] > 0:
missing = 1
for map in MapFileList:
if atype == map.split(".")[-2]:
missing = 0
if missing == 1:
MissingMaps.append(atype)
# Check for number of points
if len(MissingMaps) == 0:
mapheader = []
mapheader_checking = []
try:
for file in MapFileList:
if file[-3:] == "map":
MAP = open(file, 'r')
# first map populates the map reference dictionary
if len(mapheader) == 0:
line = MAP.next()
for count in '123456':
mapheader.append(line)
line = MAP.next()
MAP.close()
else:
line = MAP.next()
for count in '123456':
mapheader_checking.append(line)
line = MAP.next()
MAP.close()
if not mapheader == mapheader_checking:
MapConsistency == False
else:
MapConsistency == True
del mapheader_checking[:]
except:
if DEBUG: print "CheckFolderMap> Houston, we've got a problem in checking maps..."
MapConsistency = False
if MapConsistency:
for item in MapFileList:
MapFolderList.insert('end', item)
CacheMapDirName.set(mapDir)
CacheMapDirLabel.config(state = NORMAL)
DoCachedMaps.set(True)
return True
else:
tkMessageBox.showwarning("Map files are not coherent!", "The maps doesn't have the same properties\
(i.e npoints, resolution...). Please check them or select another folder")
CacheMapDirName.set("[ none ]")
CacheMapDirLabel.config(state = DISABLED)
AutoGridWhen1.invoke() # Select the default as "Run AG in each job"
return False
else: # One or more maps are missing...
MapFolderList.delete(0, END)
DoCachedMaps.set(False)
message_missing = ""
for mmap in MissingMaps:
message_missing = message_missing+"==> "+mmap+"\n"
CacheMapDirName.set("[ none ]")
CacheMapDirLabel.config(state = DISABLED)
tkMessageBox.showwarning("Map file not found!", "The following maps are missing:\n\n%s\nRe-define \
the directory or use different ligands."% message_missing)
AutoGridWhen1.invoke() # Select the default as "Run AG in each job"
return False
def prepareGPF(output_gpf_filename, receptor_filename, ligand_filename = None, atom_types = None , flexres_filename = None):
# get the vales from the scrollbox
# parse keyword+values
# generate keyword="value[,value,value]"
#
# warning, this is limited to the keywords listed below
# but not others [ to be improved ]
# parse the GPF for keywords
# "input" can be either a ligand or a the dictionary of the atom types
#
parameters = []
list_filename = gpf_filename = None
directory = None
verbose = None
center_on_ligand = False
size_box_to_include_ligand = False
verbose = False
parameters = []
if verbose or DEBUG:
print "I'm trying to generate the GPF using the following params:"
print "output gpf", output_gpf_filename
print "receptor_filename", receptor_filename
print "ligand_filename", ligand_filename
print "atom types", atom_types
print "flexres_filename", flexres_filename
list_of_atom_types = []
if atom_types:
if verbose or DEBUG: print "I'm going to use these atom types to generate the maps...", atom_types
line = "ligand_types="
for atype in atom_types:
if atype not in list_of_atom_types:
line = line+atype+","
list_of_atom_types.append(atype)
line = line.rstrip(',')
parameters.append(line)
if verbose: print "This is the command line", line
# add potential parameter file line
if not GPFParameterFile.get() == "":
parameters.append( ( "parameter_file="+GPFParameterFile.get() ) )
# read the imported GPF and parse the keywords
gpf_lines = GPFcontent.get(1.0, END)
if verbose: print "############################################ GPF ####################\n",gpf_lines, "\n###################################"
for line in gpf_lines.split('\n'):
if verbose: print "======> PROCESSING: ", line
if not line.strip(): # get rid of empty lines
continue
else:
clean_line = line.split("#")[0] # get rid of comments
clean_line = clean_line.split(" ", 1)
keyword = clean_line[0]
try:
argument = clean_line[1]
except:
pass
if verbose: print " keyword = |"+keyword+"|, value = |"+argument+"|"
# try: ?
if keyword == "npts":
value = argument.split()
line = keyword+"="+value[0]+","+value[1]+","+value[2]
if verbose: print "=> found npts, generated this xxxx:", line
parameters.append(line)
if keyword == "parameter_file":
value = argument.replace(" ", "")
line = keyword+"="+value
if verbose: print "=> found parameter file, generated this xxxx:", line
if keyword == "spacing":
value = argument.replace(" ", "")
line = keyword+"="+value
if verbose: print "=> found spacing, generated this xxxx:", line
parameters.append(line)
if keyword == "gridcenter":
value = argument.split()
line = keyword+"="+value[0]+" "+value[1]+" "+value[2]
if verbose: print "=> found gridcenter, generated this xxxx:", line
parameters.append(line)
if keyword == "smooth":
value = argument.replace(" ", "")
line = keyword+"="+value
if verbose: print "=> found smooth, generated this xxxx:", line
parameters.append(line)
if keyword == "dielectric":
value = argument.replace(" ", "")
line = keyword+"='"+value+"'"
if verbose: print "=> found dielectric, generated this xxxx:", line
parameters.append(line)
if verbose: print parameters
gpfm = GridParameter4FileMaker(size_box_to_include_ligand=False,verbose=False)
if ligand_filename:
gpfm.set_ligand(ligand_filename)
gpfm.set_receptor(receptor_filename)
if flexres_filename:
flexmol = Read(flexres_filename)[0]
flexres_types = flexmol.allAtoms.autodock_element
lig_types = gpfm.gpo['ligand_types']['value'].split()
all_types = lig_types
for t in flexres_types:
if t not in all_types:
all_types.append(t)
all_types_string = all_types[0]
if len(all_types)>1:
for t in all_types[1:]:
all_types_string = all_types_string + " " + t
gpfm.gpo['ligand_types']['value'] = all_types_string
for p in parameters:
key,newvalue = string.split(p, '=')
kw = {key:newvalue}
apply(gpfm.set_grid_parameters, (), kw)
gpfm.write_gpf(output_gpf_filename)
return True
def docking_setup_interface(event):
global Info, numGen, EnEval, simple_settings, simple_settings_info, EnEval, OpenDPF, DPF_group, docking_set, CheckTDOF, CheckVOL, complex_gen_info, complex_eval_info, DPF_INFO, InfoFrame, dockMenuSettings
global DPFcontent, DPFscroll, DPFedit, DPFsave, DPFfilename, DPFFilenameLabel, simple_settings_info
global DPFgroupTemplate, DPFgroupSimple, DPFgroupComplex, DPFgroupSmart
if not DPFgroupTemplate:
DPFgroupTemplate = Pmw.Group(p4, tag_text = 'DPF template')
if not DPFgroupSimple:
DPFgroupSimple = Pmw.Group(p4, tag_text = 'DPF simple settings')
if not DPFgroupComplex:
DPFgroupComplex = Pmw.Group(p4, tag_text = 'DPF manual settings')
if not DPFgroupSmart:
DPFgroupSmart = Pmw.Group(p4, tag_text = 'SmartDPF Settings')
DPFgroupNone = Pmw.Group(p4, tag_pyclass = None) # UGLY, VERY UGLY WORKAROUND
DPFgroupTemplate.forget()
DPFgroupSimple.forget()
DPFgroupComplex.forget()
DPFgroupSmart.forget()
if not dockMenuSettings:
dockMenuSettings = OptionMenu(p4, docking_set, "From template...", command=docking_setup_interface)
dockMenuSettings.pack()
if not docking_set.get(): # == Null:
docking_set.set("[ select docking setup ]") # default value
if docking_set.get() == "From template...":
OpenDPF = Button(DPFgroupTemplate.interior(), text='Load DPF template...', command=opendpf)
DPFedit = Button(DPFgroupTemplate.interior(), text='Edit', command=editDPF, state = DISABLED, width = 13)
DPFsave = Button(DPFgroupTemplate.interior(), text='Apply changes', command=saveDPFchanges)
DPFFilenameLabel = Label(DPFgroupTemplate.interior(), textvariable=DPFfilename, state = DISABLED)
DPFdefault = Button(DPFgroupTemplate.interior(), text='Generate default DPF', command = MkDefaultDPF)
# DPF Text editor
if not DPFcontent:
DPFcontent = Text(DPFgroupTemplate.interior(), height=22, width = 100)
DPFscroll = Scrollbar(DPFgroupTemplate.interior(), command=DPFcontent.yview)
DPFcontent.configure(yscrollcommand=DPFscroll.set)
DPFcontent.config(fg = 'black', font = ("Courier", 11, "normal"))
OpenDPF.grid(row = 0, column = 0, sticky = W)
DPFedit.grid(row = 3, column = 0, sticky = W)
DPFFilenameLabel.grid(row = 0, column = 1, sticky = E)
DPFdefault.grid(row = 0, column = 2, sticky = E)
DPFscroll.grid(row = 2, column = 3, sticky = N+S)
DPFcontent.grid(row = 2, column = 0, columnspan = 3, sticky = N+S+W+E)
DPFgroupTemplate.pack()
DPFgroupNone.pack_forget()
def MkDefaultDPF():
# Substitute the current content of the DPF editor
# with the canonical DPF with all default values
# (as from ADT)
if len(DPFcontent.get(1.0, END)) > 1:
if not tkMessageBox.askokcancel("Default DPF", "The default set of parameters will overwrite the current DPF.\n\n\
Are you sure?"):
return
DPFcontent.config(state = NORMAL)
DPFcontent.delete(1.0, END)
DPFfilename.set(" AutoDock default ")
DPFFilenameLabel.config(state = DISABLED)
DPFcontent.insert(END, default_docking_parameter_file)
DPFedit.config(state = NORMAL)
setDPFtags()
TheCheck()
return
def setDPFtags():
DPFcontent.tag_remove('keyword', '1.0', END)
DPFcontent.tag_remove('comment', '1.0', END)
for keyw in DPFkeywords:
idx = '1.0'
while 1:
idx = DPFcontent.search(keyw, idx, stopindex=END)
if not idx: break
lastidx = '%s+%dc' % (idx, len(keyw))
if idx.split('.')[1] == "0":
DPFcontent.tag_add('keyword', idx, lastidx)
idx = lastidx
DPFcontent.tag_config('keyword', font = ("Courier", 11, "bold"), foreground = 'blue')
idx = '1.0'
while 1:
idx = DPFcontent.search("#", idx, stopindex=END)
if not idx: break
lastidx = idx.split('.')[0]+".end"
DPFcontent.tag_add('comment', idx, lastidx)
idx = lastidx
DPFcontent.tag_config('comment', foreground = 'gray')
def removeDPFtags():
DPFcontent.tag_remove('keyword', '1.0', END)
DPFcontent.tag_remove('comment', '1.0', END)
def opendpf():
# Provides:
# GPFlines = list of lines contained in the GPF (=> prepare_x scripts)
# GPFParameterFile = filename of the parameter file required by the GPF (if found)
#
global DPFlines, DPFcontent, DPFedit, DPFsave, DPFFilenameLabel, DPFParameterFile
dpfFile = askopenfilename(filetypes=[("Docking Parameter File", "*.dpf")])
if DEBUG: print dpfFile
if dpfFile:
dpftemplate = dpfFile
ask_for_param_file = 0
DPFParameterFile.set("")
DPFcontent.config(state = NORMAL)
DPFcontent.delete(1.0, END)
for line in open(dpfFile, 'r'):
if line[0:14] == "parameter_file":
print "I found a param file!"
ask_for_param_file = 1
param_file_name = line.split()[1]
DPFcontent.insert(END, line)
DPFlines = DPFcontent.get(1.0, END)
DPFfilename.set(dpfFile)
DPFFilenameLabel.config(state = NORMAL)
if ask_for_param_file == 1:
tkMessageBox.showwarning("Parameter file required", "A parameter file is required by the DPF:\n => %s \n The filename location must be specified..." % param_file_name)
askDPFParamFile(param_file_name)
else:
DPFcontent.config(state = DISABLED)
DPFedit.config(state = NORMAL)
setDPFtags()
TheCheck()
def editDPF():
DPFcontent.config(state = NORMAL)
DPFedit.grid_forget()
DPFcontent.config(fg = 'red', font = ("Courier", 11, "bold"))
OpenDPF.config(state = DISABLED)
DPFsave.config(fg = 'red', width = 13)
DPFsave.grid(row = 3, column = 0, sticky = W)
removeDPFtags()
def saveDPFchanges():
DPFlines = DPFcontent.get(1.0, END)
DPFcontent.config(fg = 'black', font = ("Courier", 11, "normal"))
DPFcontent.config(state = DISABLED)
OpenDPF.config(state = NORMAL)
DPFsave.grid_forget()
DPFedit.grid(row = 3, column = 0, sticky = W)
setDPFtags()
def askDPFParamFile(filename):
# ask the user the location of the ADX.X_xxxx.dat file found in the DPF
#
# Provides:
# defines the GPFParameterFile
keepasking = True
while keepasking == True:
parameter_filename = askopenfilename(filetypes=[("AutoDock Parameter File", filename)])
if parameter_filename:
DPFParameterFile.set(parameter_filename)
keepasking = False
DPFcontent.config(state = DISABLED)
DPFedit.config(state = NORMAL)
break
else:
answer = tkMessageBox.askquestion('Warning', 'The file is required by the DPF.\nDo you want to define it?')
if answer == "no":
tkMessageBox.showwarning("Error", "The file is essential for this DPF.\nRe-import the DPF and set the correct parameter file.")
# empty the GPF buffer and the entry in GPF the editor
DPFlines = None
DPFcontent.delete(1.0, END)
DPFfilename.set("[ no DPF loaded ]")
DPFFilenameLabel.config(state = DISABLED)
DPFedit.config(state = DISABLED)
keepasking = False
##################################### DPF CLASS
class DockingParameter42FileMaker:
"""Accept a .pdbqt and .pdbqt and create
_42.dpf
"""
def __init__(self, verbose = None):
self.verbose = verbose
self.dpo = DockingParameters()
def getTypes(self, molecule):
if not len(molecule.allAtoms.bonds[0]):
molecule.buildBondsByDistance()
ad4_typer = AutoDock4_AtomTyper(verbose=self.verbose)
ad4_typer.setAutoDockElements(molecule)
dict = {}
for a in molecule.allAtoms:
dict[a.autodock_element] = 1
d_types = dict.keys()
d_types.sort()
mol_types = d_types[0]
for t in d_types[1:]:
mol_types = mol_types + " " + t
if self.verbose: print "end of getTypes: types=", mol_types, ' class=', mol_types.__class__
return mol_types
def set_write_all(self, value):
verbose = self.verbose
self.dpo['write_all_flag']['value'] = True
if verbose: print "set write_all_flag to", self.dpo['write_all_flag']['value']
def set_ligand(self, ligand_filename):
verbose = self.verbose
self.ligand_filename = os.path.basename(ligand_filename)
if verbose: print "set ligand_filename to", self.ligand_filename
self.dpo.set_ligand(ligand_filename)
#expect a filename like ind.out.pdbq: get 'ind' from it
self.ligand_stem = string.split(self.ligand_filename,'.')[0]
if verbose: print "set ligand_stem to", self.ligand_stem
self.ligand = Read(ligand_filename)[0]
if self.ligand==None:
print 'ERROR reading: ', ligand_filename
return
if verbose: print "read ", self.ligand.name
#set dpo:
#move
self.dpo['move']['value'] = self.ligand_filename
if verbose: print "set move to ", self.dpo['move']['value']
#ndihe
#assumes ligand has torTree
self.dpo['ndihe']['value'] = self.ligand.parser.keys.count("BRANCH")
#self.dpo['ndihe']['value'] = len(self.ligand.torTree.torsionMap)
if verbose: print "set ndihe to ", self.dpo['ndihe']['value']
#torsdof
#caution dpo['torsdof4']['value'] is a list [ndihe, 0.274]
try:
self.dpo['torsdof4']['value'][0] = self.ligand.TORSDOF
except:
print 'setting torsdof to ligand.ndihe=', self.ligand.ndihe
self.dpo['torsdof4']['value'][0] = self.ligand.ndihe
if verbose: print "set torsdof4 to ", self.dpo['torsdof4']['value']
#types
self.ligand.types = self.getTypes(self.ligand)
self.dpo['ligand_types']['value'] = self.ligand.types
if verbose: print "set types to ", self.dpo['ligand_types']['value']
#about
self.ligand.getCenter()
cen = self.ligand.center
self.dpo['about']['value'] = [round(cen[0],4), round(cen[1],4),\
round(cen[2],4)]
if verbose: print "set about to ", self.dpo['about']['value']
def set_receptor(self, receptor_filename):
self.receptor_filename = os.path.basename(receptor_filename)
self.receptor_stem = string.split(self.receptor_filename, '.')[0]
self.dpo.set_receptor(receptor_filename)
def set_flexres(self, flexres_filename):
flexmol = Read(flexres_filename)[0]
flexres_filename = os.path.basename(flexres_filename)
self.dpo['flexres_flag']['value'] = True
self.dpo['flexres']['value'] = flexres_filename
#make sure each atom type in flexres molecule is in ligand_types
d = {}
current_types = self.dpo['ligand_types']['value'].split()
for t in current_types:
d[t] = 1
for a in flexmol.allAtoms:
d[a.autodock_element] = 1
self.dpo['ligand_types']['value'] = string.join(d.keys())
def set_docking_parameters(self, **kw):
"""Any docking parameters should be set here
"""
# like this:
# newdict = {'ga_num_evals':1750000, 'ga_pop_size':150,
# 'ga_run':20, 'rmstol':2.0}
# self.mv.dpo['']['value'] =
for parm, newvalue in kw.items():
self.dpo[parm]['value'] = newvalue
if parm=='set_sw1':
self.dpo['set_psw1']['value'] = not newvalue
if parm=='set_psw1':
self.dpo['set_sw1']['value'] = not newvalue
if parm=='flexres':
self.set_flexres(newvalue)
if parm=='write_all':
self.set_write_all(newvalue)
def write_dpf(self, dpf_filename,
parm_list = genetic_algorithm_local_search_list4_2,
pop_seed = False):
if not dpf_filename:
dpf_filename = "%s%s%s%s" % \
(self.ligand_stem, "_",
self.receptor_stem, ".dpf")
# now that we have a filename...
# set initial conformation
if pop_seed:
self.dpo['tran0']['value'] = self.dpo['about']['value']
self.dpo['quat0']['value'] = '1.0 0. 0. 0.'
dihe0 = '0. '*self.dpo['ndihe']['value']
dihe0.rstrip()
self.dpo['dihe0']['value'] = dihe0
if self.verbose:
print "writing ", dpf_filename
self.dpo.write42(dpf_filename, parm_list)
########################################################
def prepareDPF(dpf_filename, receptor_filename, ligand_filename, flexres_filename = None, search_algorithm = "GA", parameters = None):
# implement the possibility to define explicit params for the SmartVS?
if search_algorithm == "GA": # GA-only supported keywords
parameter_list = genetic_algorithm_local_search_list4_2
if search_algorithm == "LS":
parameter_list = local_search_list4_2 # not explicitly supported
if search_algorithm == "SA":
parameter_list = simulated_annealing_list4_2 # not explicitly supported
pop_seed = False
verbose = False
template = None
# parameter parser
dpf_lines = DPFcontent.get(1.0, END)
if not parameters:
parameters = []
for line in dpf_lines.split('\n'):
if not line.strip(): # get rid of empty lines
continue
else:
clean_line = line.split("#")[0] # get rid of comments
clean_line = clean_line.split(" ", 1)
keyword = clean_line[0]
try:
argument = clean_line[1]
except:
argument = ""
if keyword == "autodock_parameter_version":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found autodock_param_vers", value[0]
parameters.append(par_line)
if keyword == "parameter_file":
value = argument#.replace(" ", "")
par_line = keyword+"="+value
parameters.append(par_line)
#print "=> found parameter file, generated this xxxx:", value
if keyword == "outlev":
value = argument#.replace(" ", "")
par_line = keyword+"="+value
#print "=> found outlev, generated this xxxx:", par_line
parameters.append(par_line)
if keyword == "seed":
value = argument.split()
par_line = keyword+"="+value[0]+" "+value[1]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "tran0":
value = argument.replace(" ", "")
par_line = keyword+"="+value
#print "=> found smooth, generated this xxxx:", par_line
parameters.append(par_line)
if keyword == "axisangle0":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "dihe":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "tstep":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "qstep":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "dstep":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "unbound":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "rmstol":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "extnrg":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "e0max":
value = argument.split()
par_line = keyword+"="+value[0]+" "+value[1]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "ga_pop_size":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "ga_num_evals":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "ga_num_generations":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "ga_elitism":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "ga_mutation_rate":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "ga_crossover_rate":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "ga_window_size":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "ga_cauchy_alpha":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "ga_cauchy_beta":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "set_ga":
#value = argument.split()
par_line = keyword+"= "#+value[0]+"'"
#print "=> found %s, generated this " % (par_line)
parameters.append(par_line)
if keyword == "sw_max_its":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "sw_max_succ":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "sw_max_fail":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "sw_rho":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "sw_lb_rho":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "ls_search_freq":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "set_psw1":
par_line = keyword+"= "
#par_line = "set_psw1_flag"
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "set_sw1":
par_line = keyword+"= "
#par_line = "set_sw1_flag"
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "unbound_model":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "ga_run":
value = argument.split()
par_line = keyword+"="+value[0]
#print "=> found %s, generated this : %s" % (keyword, par_line)
parameters.append(par_line)
if keyword == "analysis":
#value = argument.split()
par_line = keyword+"= "#+value[0]+"'"
#print "=> found %s, generated this : " % (par_line)
parameters.append(par_line)
if verbose: print "###\n", parameters, "###\n"
dm = DockingParameter42FileMaker(verbose=None)
dm.set_ligand(ligand_filename)
dm.set_receptor(receptor_filename)
if flexres_filename is not None:
flexmol = Read(flexres_filename)[0]
flexres_types = flexmol.allAtoms.autodock_element
lig_types = dm.dpo['ligand_types']['value'].split()
all_types = lig_types
for t in flexres_types:
if t not in all_types:
all_types.append(t)
all_types_string = all_types[0]
if len(all_types)>1:
for t in all_types[1:]:
all_types_string = all_types_string + " " + t
dm.dpo['ligand_types']['value'] = all_types_string
dm.dpo['flexres']['value'] = os.path.basename(flexres_filename)
dm.dpo['flexres_flag']['value'] = True
for p in parameters:
key,newvalue = string.split(p, '=')
if newvalue[0]=='[':
nv = []
for item in newvalue[1:-1].split(','):
nv.append(float(item))
newvalue = nv
elif 'flag' in key:
if newvalue in ['1','0']:
newvalue = int(newvalue)
if newvalue =='False':
newvalue = False
if newvalue =='True':
newvalue = True
kw = {key:newvalue}
apply(dm.set_docking_parameters, (), kw)
if key not in parameter_list:
#special hack for output_pop_file
if key=='output_pop_file':
parameter_list.insert(parameter_list.index('set_ga'), key)
else:
parameter_list.append(key)
dm.write_dpf(dpf_filename, parameter_list, pop_seed)
########################## INFO ###################################
def RMBhelp(aboutwhat = None):
# TODO
pass
def GetOSoption():
global TargetOS, LinuxOptionsPanel, PBSOptionsPanel, WinOptionsPanel
LinMasterBash, LinSingleBash, LinTarGz, LinRunAfter = BooleanVar(),BooleanVar(),BooleanVar(), BooleanVar()
PBScputime = StringVar()
for panel in LinuxOptionsPanel, PBSOptionsPanel, WinOptionsPanel:
panel.grid_forget()
if not TargetOS.get():
print "this is the first time the TargetOS is called"
TargetOS.set('lin')
if TargetOS.get() == "lin":
# Linux/Mac
panel = LinuxOptionsPanel
if system == "Windows":
CygwinOption = Tkinter.Checkbutton(panel.interior(), text = 'Use Cygwin', variable = cygwin)
CygwinOption.grid(row = 0, column = 0, sticky = W)
Label(panel.interior(), text="Script generation ").grid(row = 1, column = 0, sticky = E)
LinuxScriptOption = OptionMenu(panel.interior(), LinuxScriptLevel, "master script for starting the VS",\
"single scripts for each ligand", "[disabled]").grid(row = 1, column = 1, sticky = W)
CheckMakeTarGZ = Tkinter.Label(panel.interior(), text = 'Create a VS package file ').grid(row = 2,\
column = 0, columnspan = 1, sticky = E)
TarCompressionOptions = OptionMenu(panel.interior(), TarFile, "Tar (Bz2 compression)", "Tar (Gzip compression)",\
"Tar (uncompressed)", "Zip compressed", "[disabled]")
TarCompressionOptions.grid(row = 2, column = 1, sticky = W)
if TargetOS.get() == "pbs":
# PBS
panel = PBSOptionsPanel
Label(panel.interior(), text="Script generation ").grid(row = 1, column = 0, sticky = E)
LinuxScriptOption = OptionMenu(panel.interior(), LinuxScriptLevel, "master script for starting the VS",\
"single scripts for each ligand", "[disabled]").grid(row = 1, column = 1, sticky = W, columnspan = 3)
CheckMakeTarGZ = Tkinter.Label(panel.interior(), text = 'Create a VS package file ').grid(row = 2, column = 0, columnspan = 1, sticky = E)
TarCompressionOptions = OptionMenu(panel.interior(), TarFile, "Tar (Bz2 compression)", "Tar (Gzip compression)",\
"Tar (uncompressed)", "[disabled]")
TarCompressionOptions.grid(row = 2, column = 1, sticky = W)
PBSOptionCPUTime = Label(panel.interior(), text='CPU time per job ')
PBSOptionCPUTime.grid(row = 3, column = 0, sticky = E)
PBSOptionCPUTimeEntry = Tkinter.Entry(panel.interior(), textvariable=PBStime, width = 8)
PBSOptionCPUTimeEntry.grid(row = 3, column =1, sticky = W)
PBSOptionCPUset = Button(panel.interior(), text ="Set", command = SetPBStime)
PBSOptionCPUset.grid(row = 3, column =2, sticky = W, columnspan = 1)
Label(panel.interior(), text = "Number of DLG's to run per ligand ").grid(row = 4, column = 0, sticky = E)
Entry(panel.interior(), textvariable = PBShowmanyruns, width = 4).grid(row = 4, column = 1, sticky = W)
PBSOptionCPUset = Button(panel.interior(), text ="Set", command = SetPBShowmanyruns).grid(row = 4, column = 2, sticky = W)
SetPBStime
SetPBShowmanyruns
if TargetOS.get() == "win":
# Win (God bless you)
CheckMasterScript = Tkinter.Checkbutton(panel.interior(), text = 'Generate a master batch script for the VS job')
CheckMasterScript.grid(row = 3, column = 0, sticky = W, columnspan = 3)
CheckMakeTarGZ = Tkinter.Checkbutton(panel.interior(), text = 'Create a compressed file of the VS (.zip)')
CheckMakeTarGZ.grid(row = 4, column = 0, sticky = W, columnspan = 3)
panel.grid(row = 3, column = 0, columnspan = 2)
def SetPBShowmanyruns():
wrong = False
try:
howmany = PBShowmanyruns.get()
if howmany == "":
wrong = True
if howmany <= 0:
wrong = True
except:
wrong = True
if wrong:
nb.tab('VS Generation').invoke()
tkMessageBox.showerror("PBS runs error!", ("The value of runs must be a number bigger than 0 (and smaller than infinite).\n\nReset to default."))
PBShowmanyruns.set(1)
return False
else:
if howmany > 255:
tkMessageBox.showwarning("Warning", ("The number of runs is very high."))
return True
def SetPBStime():
if DEBUG: print "CHECKING TIME FOR PBS", PBStime
time = PBStime.get()
try:
time = time.split(':')
except:
nb.tab('VS Generation').invoke()
tkMessageBox.showerror("PBS time error!", ("The time format must be :\n\n hh:mm:ss\n\n Reset to default."))
PBStime.set("24:00:00")
return False
wrong = False
if len(time) < 3 or len(time) > 3:
nb.tab('VS Generation').focus_set()
nb.tab('VS Generation').invoke()
tkMessageBox.showerror("PBS time error!", ("The time format must be :\n\n hh:mm:ss\n\n Reset to default."))
PBStime.set("24:00:00")
return False
try:
if int(time[0]) < 0:
wrong = True
if int(time[1]) > 59 or int(time[1]) < 0:
wrong = True
if int(time[2]) > 59 or int(time[2]) < 0:
wrong = True
if not int(time[0]) > 0:
if not int(time[1]) > 0:
if not int(time[2]) > 0:
wrong = True
except:
wrong = True
if wrong:
nb.tab('VS Generation').focus_set()
nb.tab('VS Generation').invoke()
tkMessageBox.showerror("PBS time error!", ("The time format must be :\n\n hh:mm:ss\n\n Reset to default."))
PBStime.set("24:00:00")
return False
else:
return True
### CORE FUNCTIONS
def TheCheck():
# Perform the checking for all the
# necessary settings for activating
# the GENERATE button
LIGANDS = False
RECEPTORS = False
MAPS = False
DOCKING = False
FLEXIBLE = False
DESTINATION = False
if DEBUG: print "======= PERFORMING THE CHECK ============"
# Check for ligands
if TotalAcceptedLigands.get() > 0:
LIGANDS = True
count_ligands = TotalAcceptedLigands.get()
LigandSummary.set(( str(count_ligands)+" accepted" ))
LigSummaryLabel.config(fg = '#11bb11')
else:
LigandSummary.set(( " [ none ] "))
LigSummaryLabel.config(fg = "red")
if DEBUG : print "- ligands", TotalAcceptedLigands.get()
# Check for the receptors
if RCstatus.get() == 0:
if SingleReceptorSet.get():
receptor_message = (RecFilename.get())
RECEPTORS = True
count_receptors = 1
if RCstatus.get() == 1:
if MultiReceptorSet.get():
count_receptors = len(receptorScrolledListBox.get('0' , END))
if count_receptors > 0:
receptor_message = ( str(count_receptors)+" structures" )
RECEPTORS = True
# potential flexible residues
#
#
if RECEPTORS:
if DoFlex.get():
if DoFlexFromWhat.get() == 1:
if not FlexResFileName.get() == "":
FLEXIBLE = True
if DoFlexFromWhat.get() == 2:
if FlexResDefined.get():
FLEXIBLE = True
if FLEXIBLE:
if DEBUG: print "THE_CHECK> we're going flexible..."
receptor_message = ("\n"+receptor_message+"\n[ flex: "+ResidueStatus.get()+" ]" )
RecSummaryLabel.config(fg = '#11bb11')
ReceptorSummary.set(receptor_message)
else:
ReceptorSummary.set( " [ none ] " )
RecSummaryLabel.config(fg = 'red')
# Check for maps
if MapSource.get() <= 1:
if len(GPFcontent.get('1.0', END)) > 3:
if MapSource.get() == 0:
MapsSummary.set(("\ncalculated in each job\n[ "+GPFfilename.get()+" ]"))
MAPS = True
if MapSource.get() == 1 and AutoGridBin.get():
MAPS = True
if CacheMapPolicy.get() == "Make copies [ use more disk space ]":
MapsSummary.set(("\n\ncalculated now and copied\n [ Template: "+GPFfilename.get()+" ]\n [ AutoGrid bin: "+AutoGridBin.get()+" ]"))
if CacheMapPolicy.get() == "Make symbolic links [ save disk space ]":
MapsSummary.set(("\n\ncalculated now and linked\n [ "+GPFfilename.get()+" ]\n [ AutoGrid bin: "+AutoGridBin.get()+" ]"))
if MapSource.get() == 2:
if DoCachedMaps.get():
MAPS = True
if CacheMapPolicy.get() == "Make copies [ use more disk space ]":
MapsSummary.set(("\nalready calculated and copied in each ligand directory from:\n[ "+CacheMapDirName.get()+" ]" ))
if CacheMapPolicy.get() == "Make symbolic links [ save disk space ]":
MapsSummary.set(("\nalready calculated and linked in each ligand directory from:\n[ "+CacheMapDirName.get()+" ]" ))
if DEBUG: MapsSummary.set(("\nusing pre-calculated\n\t[ "+CacheMapDirName.get()+" ]"))
if MAPS:
MapsSummaryLabel.config(fg = '#11bb11')
else:
MapsSummary.set((" [ none ] "))
MapsSummaryLabel.config(fg = 'red')
# Check for DPF
if docking_set.get() == "From template...":
if len(DPFcontent.get('1.0', END)) > 3: # three lines arbitrary value
docking_message = ("\nusing DPF template\n[ "+DPFfilename.get()+" ]" )
DOCKING = True
if DOCKING:
DockingSummary.set(docking_message)
DockSummaryLabel.config(fg = '#11bb11')
else:
DockingSummary.set(" [ none ] ")
DockSummaryLabel.config(fg = "red")
# implement with some feedback
if TargetOS.get() == "pbs":
if SetPBStime():
if SetPBShowmanyruns():
pass
else:
return False
#Check for the output directory
if not JobDirectory.get() == "":
DESTINATION = True
SetOutDirButton.config(fg = 'black')
OutputDirLabel.config(fg = '#11bb11')
OutputDirLabel.config(fg = '#11bb11')
else:
SetOutDirButton.config(fg = 'red')
OutputDirLabel.config(fg = 'red')
if LIGANDS and RECEPTORS and MAPS and DOCKING:
# that's why we're here...
JobsSummary.set(("\t"+str(count_receptors * count_ligands)+" jobs will be generated" ))
if DESTINATION:
TheButton.config(state = NORMAL, text = "G E N E R A T E", command = TheFunction)
TheButton.flash()
else:
TheButton.config(state = DISABLED)
JobsSummary.set((""))
def DisableInterface(Tab = None):
if Tab:
nb.tab(Tab).configure(state = 'disabled')
else:
nb.tab('Ligand(s)').configure(state = 'disabled')
nb.tab('Receptor(s)').configure(state = 'disabled')
nb.tab('Maps').configure(state = 'disabled')
nb.tab('Docking').configure(state = 'disabled')
nb.tab('VS Generation').configure(state = 'disabled')
AddLigandsButton.config(state = DISABLED)
AddLigandsDirButton.config(state = DISABLED)
AddLigandsDirRecursiveButton.config(state = DISABLED)
RemoveLigandsButton.config(state = DISABLED)
RemoveAllLigandsButton.config(state = DISABLED)
FilterButton.config(state = DISABLED)
LigandPDBQTOptButton.config(state = DISABLED)
SetOutDirButton.config(state = DISABLED)
def EnableInterface(Tab = None):
if Tab:
nb.tab(Tab).configure(state = 'normal')
else:
nb.tab('Ligand(s)').configure(state = 'normal')
nb.tab('Receptor(s)').configure(state = 'normal')
nb.tab('Maps').configure(state = 'normal')
nb.tab('Docking').configure(state = 'normal')
nb.tab('VS Generation').configure(state = 'normal')
AddLigandsButton.config(state = NORMAL)
AddLigandsDirButton.config(state = NORMAL)
AddLigandsDirRecursiveButton.config(state = NORMAL)
RemoveLigandsButton.config(state = NORMAL)
RemoveAllLigandsButton.config(state = NORMAL)
FilterButton.config(state = NORMAL)
LigandPDBQTOptButton.config(state = NORMAL)
SetOutDirButton.config(state = NORMAL)
def HandBrake():
TheButton.config(state = DISABLED, text = " [ Generation process is paused... ]")
if tkMessageBox.askquestion('Warning', 'Do you really want to interrupt the generation process?') == "yes":
StopImmediately.set(True)
return
else:
TheButton.config(state = NORMAL,text = "> STOPPED <")
return
def TheFunction():
path = JobDirectory.get()
if DEBUG: print "TheFunction> starting the vs creation in ", path
StopImmediately.set(False)
DisableInterface()
EnableInterface('VS Generation')
TheButton.config(state = NORMAL, text = " [ Stop the generation... ]", command = HandBrake)
if DEBUG:
print "\n========================================\n"
print "===== STARTING THE GENERATION ==========\n"
print "========================================\n"
# Initialize the log
log_file = InitializeLog(path)
if not log_file:
if DEBUG: print "[gen+log] => we start very well... :S no logging available!"
EnableInterface()
return False
header = "\n\n ======================================================================================================\n"
header += " ======================================================================================================\n\n"
header += " G E N E R A T I O N S T A R T E D\n\n"
print >> log_file, header
# Define the target(s)
if RCstatus.get() == 0:
if DEBUG: print "[gen] => single receptor NAME = ",
receptor_list = [ RecFilename.get() ]
if DEBUG: print RecFilename.get()
else:
if DEBUG: print "[gen] => multiple receptors",
receptor_list = receptorScrolledListBox.get('0', END)
if DEBUG: print "[ I'm going to use %d receptors ]" % len(receptor_list)
# Get the filtered ligands
ligand_list = []
atomtypes_set = [] #atom types present in the accepted ligands set
for ligand in LigandDictionary.keys():
if LigandDictionary[ligand]["accepted"]:
ligand_list.append(ligand)
for atom in LigandDictionary[ligand]["Atypes"]:
if atom not in atomtypes_set: atomtypes_set.append(atom)
# counters are initialized here
rec_count = len(receptor_list)
lig_count = len(ligand_list)
jobs_todo = rec_count * lig_count
jobs_done = 1
# the Main loop
for receptor in receptor_list:
rec_name = os.path.basename(receptor).rsplit('.', 1)[:-1][0]
current_path = path+os.sep+rec_name
# Flush the list of dir per ligands (this is generated on a per-receptor base)
del DirJournal[:]
# create the directory RECEPTOR/[ligands]
if not os.path.exists(current_path):
try:
os.makedirs(current_path, 0755)
except:
tkMessageBox.showerror("Error!", ("Impossible to create the directory:\n%s\n GIVING UP..." % current_path))
print >> log_file, ("\n\n\n#### ERROR ###\n\nThere was a problem in creating the directory:\n%s\n\n VS generation aborted.\n\n#### ####" % current_path) # End of receptor loop
TheButton.config(state = DISABLED, text = "E R R O R")
EnableInterface()
return False
## Preliminary stuff to do before the ligands get involved
#
#
## 1. define or generate flexible residue files
#
flex_res = None
if DoFlex.get(): #
if FlexResDefined.get(): #
if DEBUG: print "soo.... we want flexible,right?\n\nPREPARING"
if DoFlexFromWhat.get() == 1:
if FlexResFileName.get(): # TODO in theory it shouldn't be necessary
if DEBUG: print "\tcopying the flexible residue in the right place"
if DEBUG: print "\tcp flex.pdbqt working_dir"
flex_res = FlexResFileName.get()
if DoFlexFromWhat.get() == 2:
if FlexResSelected.get(): # TODO in theory it shouldn't be necessary
if DEBUG: print "\tgenerate the flexible residue from the receptor"
if DEBUG: print "\tprepare_flex_receptor blablabla "
InfoMessage.set( ( "[ Generating flex residues for %s... ]" % rec_name ))
receptor, flex_res = genFlex(receptor)
flex_types = GetAtypes(flex_res)
for atom in flex_types:
if atom not in atomtypes_set: atomtypes_set.append(atom)
if DEBUG:
print "[GEN] I've got the flex_res filename", flex_res
print "[GEN] Now the receptor is", receptor
#
## 2. calculate or copy maps now if necessary
#
# create the cached maps folder (for "now" and "already")
CachedMapsDir = None
CacheMapOptions = OptionMenu(CacheMapHandle.interior(), CacheMapPolicy, "Make copies [ use more disk space ]", "Make symbolic links [ save disk space ]")
if CacheMapPolicy.get() == "Make copies [ use more disk space ]":
symlink = False
if CacheMapPolicy.get() == "Make symbolic links [ save disk space ]":
symlink = True
if MapSource.get() >= 1:
CachedMapsDir = current_path+os.sep+"maps"
if not os.path.exists(CachedMapsDir):
try:
os.makedirs(CachedMapsDir, 0755)
except:
tkMessageBox.showerror("Error!", ("Impossible to create the directory:\n%s\n GIVING UP..." % CachedMapsDir))
print >> log_file, ("\n\n\n#### ERROR ###\n\nThere was a problem in creating the directory:\n%s\n\n VS generation aborted.\n\n#### ####" % CachedMapsDir)
EnableInterface()
return False
if MapSource.get() == 1: # populate the dir with AutoGrid
InfoMessage.set( ( "[ Running AutoGrid on %s... ]" % rec_name ))
if not CalcCacheMaps(CachedMapsDir, receptor, flex_res):
tkMessageBox.showerror("Error!", ("Impossible to calculate the cached maps here:\n%s\n GIVING UP..." % CachedMapsDir))
EnableInterface()
return False
if MapSource.get() == 2: # populate the dir by copying the files from the cache
InfoMessage.set( ( "[ Copying cached maps for %s... ]" % rec_name ))
if not CopyMapDir(atomtypes_set, None, CachedMapsDir, symlink = False): # no matter if maps will be eventually copied or linked, now it must be false
tkMessageBox.showerror("Error!", ("Impossible to copy the maps in the VS job master directory \n%s\n GIVING UP..." % CachedMapsDir))
EnableInterface()
return False
# Ligands loop #############################################################################################
for ligand in ligand_list:
if StopImmediately.get():
InfoMessage.set( "Generation process aborted by the user...")
print >> log_file, ("\n\n\n#### ABORT ###\n\nThe generation process was interrupted by the user.\n\n")
TheButton.config(state = DISABLED, text = " [ Generation aborted ]")
EnableInterface()
return False
InfoMessage.set( ( "=> Processing %s | %s \t[ %d | %d ]" % (os.path.basename(receptor), os.path.basename(ligand), jobs_done, jobs_todo ) ))
nb.tab('VS Generation').focus_set()
root.update()
current_atom_types = []
ligand_name = os.path.basename(ligand).rsplit('.', 1)[:-1][0]
# create ligand dir
ligand_dir = MkJobDir(ligand, rec_name, current_path)
if not ligand_dir:
tkMessageBox.showerror("Error!", ("Impossible to create the directory:\n%s\n GIVING UP..." % ligand_dir))
print >> log_file, ("\n\n\n#### ERROR ###\n\nThere was a problem in creating the directory:\n%s\n\n VS generation aborted.\n\n#### ####" % ligand_dir)
EnableInterface()
return False
# copy the ligand in place
if not os.path.dirname(ligand) == ligand_dir:
try:
shutil.copy2(ligand, ligand_dir)
except:
tkMessageBox.showerror("Error!", ("Impossible to copy the ligand:\n%s\n\tto\n%s\n\nGIVING UP..." % (ligand, ligand_dir)))
EnableInterface()
return False
else:
if DEBUG: print "TheFunction> skipped the source/dest ligand copy because they are identical..."
# copy flexres if necessary
if DoFlex.get(): #
if FlexResDefined.get():
if not os.path.dirname(flex_res) == ligand_dir:
try:
shutil.copy2( flex_res, ligand_dir)
except:
tkMessageBox.showerror("Error!", ("Impossible to copy the flex res file:\n%s\n\tto\n%s\n\nGIVING UP..." % (flex_res, ligand_dir)))
EnableInterface()
return False
else:
if DEBUG: print "TheFunction> skipped the source/dest flex_res copy because they are identical..."
# maps management
#
# a. generate GPF
gpf_file = None
if MapSource.get() == 0 : # being in the for loop cached maps will be referred to the receptor
# generate the gpf
gpf_file = ligand_dir+os.sep+rec_name+".gpf"
try:
prepareGPF(gpf_file, receptor, ligand_filename = ligand, atom_types = None, flexres_filename = flex_res)
except:
tkMessageBox.showerror("Error!", ("Impossible to create the gpf file:\n%s\n GIVING UP..." % gpf_file))
EnableInterface()
return False
if not os.path.exists(gpf_file):
tkMessageBox.showerror("Error!", ("Impossible to create the gpf file:\n%s\n GIVING UP..." % gpf_file))
print >> log_file, ("\n\n\n#### ERROR ###\n\nThere was a problem in creating the GPF:\n%s\n\n VS generation aborted.\n\n#### ####" % gpf_file)
EnableInterface()
# error message window
return False
# copy potential parameter files
if not GPFParameterFile.get() == "":
if not os.path.dirname(GPFParameterFile.get()) == ligand_dir:
try:
shutil.copy2( GPFParameterFile.get(), ligand_dir)
except:
tkMessageBox.showerror("Error!", ("Impossible to copy the parameter file required by the\
GPF:\n%s\n\tto\n%s\n\nGIVING UP..." % (GPFParameterFile.get(), ligand_dir)))
EnableInterface()
return False
else:
if DEBUG: print "TheFunction> skipped the source/dest GPFparamfile copy because they are identical..."
# copy the receptor
if not os.path.dirname(receptor) == ligand_dir:
try:
shutil.copy2(receptor, ligand_dir)
except:
tkMessageBox.showerror("Error!", ("Impossible to copy the receptor\n%s\n\tto\n%s\n\nGIVING UP..." % (receptor, ligand_dir)))
EnableInterface()
return False
else:
if DEBUG: print "TheFunction> skipped the source/dest receptor copy because they are identical..."
# b. use cached maps
elif MapSource.get() >= 1:
current_atom_types = GetAtypes(ligand)
# include flex res atoms
if FlexResDefined.get():
for atom in flex_types:
if atom not in current_atom_types: current_atom_types.append(atom)
CopyMapDir(current_atom_types, CachedMapsDir, ligand_dir, symlink = symlink)
# Prepare the DPF
if docking_set.get() == "From template...":
dpf_file = ligand_dir+os.sep+ligand_name+"_"+rec_name+".dpf"
prepareDPF(dpf_file, receptor, ligand, flex_res)
if not os.path.exists(dpf_file):
tkMessageBox.showerror("Error!", ("Impossible to create the DPF file:\n%s\n GIVING UP..." % dpf_file))
print >> log_file, ("\n\n\n#### ERROR ###\n\nThere was a problem in creating the DPF:\n%s\n\n VS generation aborted.\n\n#### ####" % dpf_file)
EnableInterface()
return False
# copy potential parameter files
if not DPFParameterFile.get() == "":
if not os.path.dirname(DPFParameterFile.get()) == ligand_dir:
try:
shutil.copy2( DPFParameterFile.get(), ligand_dir)
except:
tkMessageBox.showerror("Error!", ("Impossible to copy the parameter file required by the\
DPF:\n%s\n\tto\n%s\n\nGIVING UP..." % (DPFParameterFile.get(), ligand_dir)))
EnableInterface()
return False
else:
if DEBUG: print "TheFunction> skipped the source/dest DPFparamfile copy because they are identical..."
jobs_done += 1
if not TargetOS.get() == "win":
if not LinuxScriptLevel.get() == "[disabled]":
MakeJobScript(ligand_dir, dpf_file, gpf_file)
log_file.flush()
if TargetOS.get() == "pbs" or TargetOS.get() == "lin":
if DEBUG: print "Making the master script"
if LinuxScriptLevel.get() == "master script for starting the VS":
MakeMasterJobScript(current_path)
if DEBUG: print "\n\n\n [ GENERATION DONE ]"
if not TarFile.get() == "[disabled]":
InfoMessage.set( ( "[ writing the compressed file... ]") )
TheButton.config(state = DISABLED, text = "...creating the VS package...")
root.update()
# vs pack filename
pack_filename = path+os.sep+"VSpack_"+os.path.basename(path)
if DEBUG:
print "TheFunction> creating the package file", pack_filename, "in ", path
# Zip file format
if TarFile.get() == "Zip compressed":
if not MakeZip(path, pack_filename):
root.update()
return False
# ...anything else
else:
if not MakeTar(path, pack_filename):
root.update()
return False
InfoMessage.set( ( "[ generation completed successfully ]") )
tkMessageBox.showinfo(title="VS generation terminated", message=("%d docking jobs have been successfully \
generated in:\n\n%s\n" % (len(receptor_list) * len(ligand_list), path ) ))
EnableInterface()
# Success! update the log with all the ligands, and close the file
print >> log_file, "\n\t\t\t process completed successfully.\n\n"
print >> log_file, "\n\n\n[DONE]" # End of receptor loop. This line is used in the load function to recognize a successfull VSgeneration when loading it back.
log_file.close()
TheButton.config(state = DISABLED, text = "D O N E")
def CopyMapDir(atomtypes_to_copy, source_dir, destination_dir, symlink = False):
# copy or make symbolic links of map files
#
#
if source_dir == destination_dir:
if DEBUG: print "CopyMapDir> skipping copy/symlink because the directories are the same"
return True
if MapSource.get() == 2:
map_files = MapFolderList.get('0', END)
if MapSource.get() == 1:
map_files = glob.glob(os.path.join(source_dir, "*.map"))
map_files.append(glob.glob(os.path.join(source_dir, "*.xyz"))[0])
map_files.append(glob.glob(os.path.join(source_dir, "*.fld"))[0])
counter = 0
atomtypes_to_copy.append('e')
atomtypes_to_copy.append('d')
atomtypes_to_copy.append('maps')
for atype in atomtypes_to_copy:
for map in map_files:
if atype == map.split(".")[-2]:
try:
if DEBUG: print "CopyMapDir> going to process this file ==>", map
if symlink:
if DEBUG: print " doing symlinking", map, destination_dir
map_filename = os.path.basename(map)
map_dir = os.path.basename(source_dir)
SRC = "../"+map_dir+os.sep+map_filename
DEST = destination_dir+os.sep+map_filename
os.symlink(SRC, DEST)
else:
shutil.copy2( map, destination_dir)
counter = counter + 1 # +1 to account for the two maps.* files
except:
tkMessageBox.showerror(title="Cached maps error", message=(("Some problem occurred when copying or linking the file %s") % map ))
return False
if len(atomtypes_to_copy)+1 == counter:
return True
else:
return False
def GetAtypes(filename = None, selection = None):
# The selection works with selected
# flex residues only
#
if not filename and not selection:
return
atypes = []
if filename:
f = open(filename, 'r')
for line in f.readlines():
if line[0:6] == 'HETATM' or line[0:4] == 'ATOM':
atom = line.split()[-1]
if atom not in atypes:
atypes.append(atom)
f.close()
if selection:
pass
return atypes
def CalcCacheMaps(output_dir, receptor, flexible_residues = None):
# get the atom types for the accepted ligands
atom_types = []
for ligand in LigandDictionary.keys():
if LigandDictionary[ligand]["accepted"]:
for atom in LigandDictionary[ligand]["Atypes"]:
if atom not in atom_types:
atom_types.append(atom)
if not os.path.dirname(receptor) == output_dir:
try:
shutil.copy2( receptor, output_dir)
except:
tkMessageBox.showerror(title="Error", message=(("Impossible to copy the receptor in the target directory for caching the maps.")))
gpf_name = output_dir+os.sep+os.path.basename(receptor).rsplit('.', 1)[:-1][0]+"_all_maps.gpf"
else:
if DEBUG: print "CalcCacheMaps> skipping the receptor copy, because files are identical"
try:
prepareGPF(gpf_name, receptor, atom_types = atom_types , flexres_filename = flexible_residues)
except:
return False
if RunAutoGrid(output_dir, gpf_name):
return True
else:
return False
def RunAutoGrid(working_dir, gpf):
# define AutoGrid
#
if not AutoGridBin.get():
return False
else:
AutoGrid = AutoGridBin.get()
glg = gpf.rsplit('.', 1)[:-1][0]+".glg"
try:
nb.tab('VS Generation').focus_set()
root.update()
#print "Look, mom! I'm running Autogrid from inside Python!!!!"
os.system(("cd %s; %s -p %s -l %s" % (working_dir, AutoGrid, gpf, glg )))
# Check if the calculation succeded
GridLog = open(glg, 'r')
log = GridLog.readlines()
GridLog.close()
if DEBUG: print log[-2]
if "Successful Completion" in log[-2]:
return True
else:
error = ""
for line in log[-7:]:
error += line
tkMessageBox.showerror("AutoGrid error!", ("Maps calculation failed with the following message:\n %s" % error))
return False
except:
return False
def WhichAutoGrid(program = 'autogrid4'):
# Try to check the file path....
def is_exe(fpath):
return os.path.exists(fpath) and os.access(fpath, os.X_OK)
fpath, fname = os.path.split(program)
if fpath:
if is_exe(program):
if CheckExe(program):
AutoGridBin.set(program)
AutoGridExecButton.config(text = "Change the AutoGrid executable", fg = 'black')
TheCheck()
return True
else:
# walks thru the path...
for path in os.environ["PATH"].split(os.pathsep):
exe_file = os.path.join(path, program)
if is_exe(exe_file):
if CheckExe(exe_file):
AutoGridBin.set(exe_file)
AutoGridExecButton.config(text = "Change the AutoGrid executable", fg = 'black')
TheCheck()
return True
# If the function gets here, AG was not found...
AutoGridExecButton.config(text = "Set the AutoGrid executable", fg = 'red')
def GetAutoGrid(filename = None):
keepasking = True
while keepasking == True:
if filename:
AutoGrid = filename
else:
AutoGrid = askopenfilename(title = "Specify the AutoGrid binary file...", filetypes =[("Any file...", '*')])
if AutoGrid:
if CheckExe(AutoGrid):
keepasking = False
AutoGridBin.set(AutoGrid)
AutoGridExecButton.config(text = "Change the AutoGrid executable", fg = 'black')
TheCheck()
return True
else:
tkMessageBox.showwarning("AutoGrid", "The specified file is not an executable.")
AutoGridExecButton.config(text = "Set the AutoGrid executable", fg = 'red')
return False
else:
if not AutoGridBin.get():
answer = tkMessageBox.askquestion('Warning', 'The AutoGrid binary file is required for pre-caching maps.\nDo you want to define it?')
if answer == "no":
tkMessageBox.showwarning("Pre-caching aborted", "The calculations of maps has been aborted by the user.")
keepasking = False
GPFframe.forget()
AutoGridWhen1.invoke() # Select the default as "Run AG in each job"
AutoGridExecButton.config(text = "Set the AutoGrid executable", fg = 'red')
return False
else:
keepasking = False
TheCheck()
return True
def CheckExe(file):
# not working
return True
def genFlex(receptor_filename):
verbose = False
name = os.path.splitext(receptor_filename)[0]
rigid_filename=name+"_rigid.pdbqt"
flexres_filename=name+"_flex.pdbqt"
if verbose or DEBUG: print "[genFlex] rigid = ", rigid_filename
if verbose or DEBUG: print "[genFlex] flexres = ", flexres_filename
residue_selected = ListFlexResiduesNames.get()
residue_selected = residue_selected.replace(" ","")
if verbose or DEBUG: print "[genFlex] gen from ", residue_selected
residue_to_move = residue_selected.replace(',','_')
if verbose or DEBUG: print "These are residues to move", residue_to_move
disallow = ""
disallowed_pairs = ""
r = Read(receptor_filename)[0]
r.buildBondsByDistance()
all_res = ResidueSet()
res_names = residue_to_move.split('_')
res_names = residue_selected.split(',')
if verbose or DEBUG: print "res_names will be", res_names
for n in res_names:
res = r.chains.residues.get(lambda x: x.name==n)
all_res += res
d = {}
for res in all_res: d[res] = 1
all_res = d.keys()
all_res = ResidueSet(all_res)
all_bnds = BondSet()
bnd_pairs = disallowed_pairs.split(':')
for pair in bnd_pairs:
names = pair.split('_')
bnds = all_res.atoms.bonds[0].get(lambda x: x.atom1.name in names and x.atom2.name in names)
all_bnds += bnds
fdp = AD4FlexibleReceptorPreparation(r, residues=all_res, rigid_filename=rigid_filename,
flexres_filename=flexres_filename,
non_rotatable_bonds=all_bnds)
return rigid_filename, flexres_filename
def update_status(status_message):
status = Label(p1, text=status_message, bd=1, relief=SUNKEN, anchor=S)
status.pack(side=BOTTOM, fill=X)
def confirm():
if tkMessageBox.askokcancel("Close Raccoon", "\nAre you sure you want to quit?\n\n(all unsaved data will be lost)\n"):
root.destroy()
def MkJobDir(ligand_filename, receptor_stem, output_dir):
global DirJournal
LigNAME = os.path.basename(ligand_filename).rsplit('.', 1)[:-1][0]
RecNAME = receptor_stem
JobDir = output_dir+os.sep+LigNAME+"_"+RecNAME
if JobDir in DirJournal: # to manage homonimy (same ligand filename from different directories)
DirJournal.append(JobDir)
JobDir = JobDir+"_"+str(DirJournal.count(JobDir))
else:
DirJournal.append(JobDir)
try:
if not os.path.exists(JobDir):
os.makedirs(JobDir, 0755)
else:
return
return JobDir
except:
return False
def MakeJobScript(ligand_dir, dpf_file, gpf_file):
# generate run.sh in the ligand_dir
if TargetOS.get() == "lin":
if system == "Windows" and not cygwin.get():
script_file = ligand_dir+os.sep+"run.bat"
line = "@echo off"
line = "REM Generated by AutoDock Raccoon"
if gpf_file:
gpf = os.path.basename(gpf_file)
glg = gpf[:-3]+"glg"
line += ("\necho Running AutoGrid...\nautogrid4.exe -p %s -l %s" % (gpf, glg) )
dpf = os.path.basename(dpf_file)
dlg = dpf[:-3]+"dlg"
line += ("\necho Running AutoDock...\nautodock4.exe -p %s -l %s\n" % (dpf, dlg) )
else:
script_file = ligand_dir+os.sep+"run.sh"
line = "#!/bin/bash\n# Generated by AutoDock Raccoon\n#\n#"
line += "\n# Specify here the paths for the binaries, if necessary"
if gpf_file:
line += "\n"+"# autogrid = ''"
line += "\n"+"# autodock = ''"
else:
line += "\n"+"# autodock = ''"
if gpf_file:
gpf = os.path.basename(gpf_file)
glg = gpf[:-3]+"glg"
line += ("\necho Running AutoGrid...\nautogrid4 -p %s -l %s" % (gpf, glg) )
dpf = os.path.basename(dpf_file)
dlg = dpf[:-3]+"dlg"
line += ("\necho Running AutoDock...\nautodock4 -p %s -l %s\n" % (dpf, dlg) )
script = open( script_file, 'w')
script.writelines(line)
script.close()
if not system == "Windows": os.system("chmod +x %s" % (script_file))
return True
def MakeMasterJobScript(path):
header = """ ________________________________________________________________
__________//___________________________/////___________________/____________
_________/__/__________________________/____/__________________/____________
________/____/___________/_____________/_____/_________________/____________
________/____/__/_____/_/////___/////__/_____/__/////___/////__/___/________
_______/______/_/_____/__/_____/_____/_/_____/_/_____/_/_____/_/_//_________
_______////////_/_____/__/_____/_____/_/_____/_/_____/_/_______//_/_________
_______/______/_/____//__/___/_/_____/_/____/__/_____/_/_____/_/___/________
_______/______/__////_/___///___/////__/////____/////___/////__/____/_______
________________________________________________________________
______
/ \\
/ \\
/ \\ Raccoon
\\ /\\ / Virtual
\\ / \\ / Screening
\\/ /\\ \\/ Generation
/\\ \\
/\\ \\__\\ version %s
/ \\__\\
/____\\ """ % version
if TargetOS.get() == "lin":
if system == "Windows" and not cygwin.get():
line = "@echo off\nREM Generated by AutoDock Raccoon\necho.\n"
command = "call run.bat"
master_script_name = path+os.sep+"RunVS.bat"
spacer = ""
Q = ""
else:
line = "### Generated by AutoDock Raccoon\n"
command = "./run.sh"
master_script_name = path+os.sep+"RunVS.sh"
Q = "'"
spacer = " "
for i in header.split("\n"): # acrobatic moves for making a unified generator...
line += "echo %s%s%s%s\n" % (Q, spacer, i, Q)
if system == "Windows" and not cygwin.get():
line += "echo.\necho == Press ENTER to start the calculation ==\n"
line += "pause > NUL\n"
else:
line += "\necho -e \"\\n == Press ENTER to start the calculation ==\"\n"
line += "read X\n"
for DIR in DirJournal:
dir = os.path.basename(DIR)
line += ("echo %sDocking %s%s\n"% (Q, dir, Q) )
line += ("cd %s\n%s\ncd ..\n\n" % (dir, command))
line += "echo %sCalculation completed.%s\n" % (Q,Q)
if system == "Windows" and not cygwin.get():
line += "pause > NUL\n"
else:
line += "read X\n"
try:
master_script = open(master_script_name, 'w')
master_script.writelines(line)
master_script.close()
except:
tkMessageBox.showerror("Master script generation.", ("An error occurred when trying to generate the jobs list file."))
return False
if not system == "Windows":
os.system("chmod +x %s" % (master_script_name))
if TargetOS.get() == "pbs":
# create the list of job dirs in which to go
# for submitting the calculation
try:
file = open(path+os.sep+'jobs_list', 'w')
for DIR in DirJournal:
dir = os.path.basename(DIR)
print >> file, dir+"\n"
file.close()
except:
tkMessageBox.showerror("PBS script generation.", ("An error occurred when trying to generate the jobs list file."))
return False
CreateSmuggler(path)
return True
def CreateSmuggler(path):
# this function is called only for
# PBS jobs
if DEBUG: print "Creating the smuggler..."
filename = "vs_submit.sh"
end = PBShowmanyruns.get()
line = "#!/bin/bash\n"
line += "#\n# Generated with Raccoon | AutoDockVS\n#\n\n"
line += "#### PBS jobs parameters"
line += "CPUT=\"%s\"\n" % PBStime.get()
line += "WALLT=\"%s\"\n" % PBStime.get()
line += "#\n# There should be no reason\n"
line += "# for changing the following values\n"
line += "NODES=1\n"
line += "PPN=1\n"
line += "MEM=512mb\n\n\n"
line += "### CUSTOM VARIABLES\n"
line += "#\n"
line += "# use the following line to set special options (e.g. specific queues)\n"
line += "#OPT=\"-q MyPriorQueue\"\n"
line += "OPT=\"\"\n\n\n"
line += "# Paths for executables on the cluster \n"
line += "# Modify them to specify custom executables to be used\n"
line += "QSUB=\"qsub\"\n"
line += "AUTODOCK=\"autodock4\"\n\n"
# Set Autogrid if necessary"
if MapSource.get() == 0:
line += "AUTOGRID=\"autogrid4\"\n\n"
line += "# Special path to move into before running\n"
line += "# the screening. This is very system-specific,\n"
line += "# so unless you're know what are you doing,\n"
line += "# leave it as it is\n"
line += "WORKING_PATH=`pwd`\n\n"
line += "\n\n##################################################################################################\n"
line += "##################################################################################################\n"
line += "####### There should be no need to modify anything below this line ###############################\n"
line += "##################################################################################################\n"
line += "##################################################################################################\n\n\n"
line += "#\n#\n\n"
line += "type $AUTODOCK &> /dev/null || {\n"
line += " echo -e \"\\nError: the file [$AUTODOCK] doesn't exist or is not executable\\n\";\n"
line += " echo -e \"Try to specify the full path to the executable of the AutoDock binary in the script\";\n"
line += " echo -e \"( i.e. AUTODOCK=/usr/bin/autodock4 )\\n\\n\";\n"
line += " echo -e \" [ virtuals screening submission aborted]\\n\"\n"
line += " exit 1; }\n\n"
line += ""
if MapSource.get() == 0:
line += "type $AUTOGRID &> /dev/null || {\n"
line += " echo -e \"\\nError: the file [$AUTOGRID] doesn't exist or is not executable\\n\";\n"
line += " echo -e \"Try to specify the full path to the executable of the AutoGrid binary in the script\";\n"
line += " echo -e \"( i.e. AUTOGRID=/usr/bin/autogrid4 )\\n\\n\";\n"
line += " echo -e \" [ virtuals screening submission aborted]\\n\"\n"
line += " exit 1; }\n\n"
line += "type $QSUB &> /dev/null || {\n"
line += " echo -e \"\\nError: the file [$QSUB] doesn't exist or is not executable\\n\";\n"
line += " echo -e \"Try to specify the full path to the executable of the Qsub command binary in the script\";\n"
line += " echo -e \"( i.e. QSUB=/usr/bin/qsub )\\n\\n\";\n"
line += " echo -e \" [ virtuals screening submission aborted]\\n\"\n"
line += " exit 1; }\n\n"
line += "echo Starting submission...\n"
line += "for NAME in `cat jobs_list`\n"
line += " do\n"
line += " cd $NAME\n"
# Set the extra loop for multiple DLG per ligand
# and specify the name convention: ligand_protein.#.job
if end > 1:
line += " for i in `seq 1 %s`\n" % str(end)
line += " do\n"
job_name = "$NAME.$i.job"
tab = " "
else:
tab = ""
job_name = "$NAME.job"
line += "%s echo \"#!/bin/bash\" > %s\n" % (tab, job_name)
line += "%s echo \"cd $WORKING_PATH/$NAME\" >> %s \n" % (tab, job_name)
if MapSource.get() == 0:
line += "%s echo \"$AUTOGRID -p *.gpf -l grid_out.glg\" >> %s\n" % (tab, job_name)
if end > 1:
line += "%s echo \"$AUTODOCK -p $NAME.dpf -l $NAME.$i.dlg\" >> %s\n" % (tab, job_name)
else:
line += "%s echo \"$AUTODOCK -p $NAME.dpf -l $NAME.dlg\" >> %s\n" % (tab, job_name)
line += "%s chmod +x %s\n" % (tab, job_name)
line += "%s echo -n \"Submitting $NAME : \"\n" % tab
line += "%s $QSUB $OPT -l cput=$CPUT -l nodes=1:ppn=1 -l walltime=$WALLT -l mem=$MEM %s\n" % (tab, job_name) # remove the echo for making it active
if end > 1:
line += " done\n"
line += " cd ..\n"
line += "done\n"
try:
output = open(path+os.sep+filename, 'w')
output.writelines(line)
output.close()
if not system == "Windows":
os.system("chmod +x %s" % (path+os.sep+filename))
return True
except:
tkMessageBox.showerror("PBS script generation.", ("An error occurred when trying to generate the %s file." % filename))
return False
def InitializeLog(outdir = None, filename = None):
if not outdir and not filename:
return False
if not outdir:
outdir = ""
#global LogFile, first_time
if system == "Windows":
os.environ.get("USERNAME")
else:
user = os.environ["USER"]
machine = system_info[1]
operative_system = system_info[0]
if TargetOS.get() == "lin":
target_machine = "Workstation"
if TargetOS.get() == "pbs":
target_machine = "Linux clusters"
if TargetOS.get() == "win":
target_machine = "Windows"
# take a look at the clock
date = datetime.datetime.now()
year = str(date.year)
month = str(date.month)
day = str(date.day)
hour = str(date.hour)
minute = str(date.minute)
second = str(date.second) # too much?
microsecond = str(date.microsecond) # waaay to much!
# VSgen-2009.7.26.log
if not filename:
log_name = outdir+os.sep+"raccoonVS-"+year+"."+month+"."+day+".log"
else:
log_name = filename
full_date = date.strftime("%Y-%B-%d %H:%M")
if RCstatus.get() == 0:
receptor_count = 1
else:
receptor_count = len(receptorScrolledListBox.get('0', END))
ligand_count = str(TotalAcceptedLigands.get())
tot_number_jobs = str( (TotalAcceptedLigands.get() * receptor_count ) )
header = """
________________________________________________________________
__________//___________________________/////___________________/____________
_________/__/__________________________/____/__________________/____________
________/____/___________/_____________/_____/_________________/____________
________/____/__/_____/_/////___/////__/_____/__/////___/////__/___/________
_______/______/_/_____/__/_____/_____/_/_____/_/_____/_/_____/_/_//_________
_______////////_/_____/__/_____/_____/_/_____/_/_____/_/_______//_/_________
_______/______/_/____//__/___/_/_____/_/____/__/_____/_/_____/_/___/________
_______/______/__////_/___///___/////__/////____/////___/////__/____/_______
________________________________________________________________
______
/ \\
/ \\
/ \\ Raccoon
\\ /\\ / Virtual
\\ / \\ / Screening
\\/ /\\ \\/ Generation
/\\ \\
/\\ \\__\\ version %s
/ \\__\\
/____\\
date :\t%s
output directory :\t%s
total docking jobs :\t%s
operative system :\t%s [ %s ]
generating jobs for :\t%s
===================================== Ligand filters =========================================
Filtering criteria
------------------
MIN MAX
Hb donors : %4s - %4s
Hb acceptors : %4s - %4s
Molecular weight : %4s - %4s
Total number of atoms : %4s - %4s
Rotatable bonds : %4s - %4s
Reject non-AD atypes : %s
Ligands accepted for the virtual-screening: %s
""" % ( version, full_date, outdir, tot_number_jobs, operative_system, machine, target_machine , str(HbDmin.get()), str(HbDmax.get()), str(HbAmin.get()), str(HbAmax.get()), str(MWmin.get()), str(MWmax.get()), str(NatMin.get()), str(NatMax.get()), str(TORSDOFmin.get()), str(TORSDOFmax.get()), str(DoRejectATypes.get()), ligand_count)
# receptor
if RCstatus.get() == 0:
receptor_log = "\n ============================= Single target receptor ==========================================\n"
receptor_log = receptor_log+"\n Target structure:\nTARGET>\t"+ RecFilename.get()
else:
receptor_log = "\n =========================== Multiple target receptors =========================================\n"
receptor_log = receptor_log+"\n Total target structures :" + str(receptor_count)+"\n"
# append the list of receptor structures
for rec in receptorScrolledListBox.get('0', END):
receptor_log = receptor_log+"\nTARGET>\t"+rec
header = header + receptor_log
# flexible residues
if DoFlex.get():
if FlexResDefined.get():
flex_log = "\n\n ------------------------------- Flexible residues -----------------------------------\n\n"
if DoFlexFromWhat.get() == 1:
if FlexResFileName.get(): # TODO in theory it shouldn't be necessary
flex_log = flex_log + "FLEX> Flexible residues from the file :\t"+FlexResFileName.get()
else:
if DEBUG : print "RETURNING A SHAMEFUL FALSE: problems in logging the flex residues [FlexResFileName.get() = ", FlexResFileName.get(), "]"
return False
if DoFlexFromWhat.get() == 2:
if FlexResSelected.get(): # TODO in theory it shouldn't be necessary
flex_log = flex_log + "FLEX> Flexible residues generated from the selection : "+ FlexResSelected.get()
else:
if DEBUG :print "RETURNING A SHAMEFUL FALSE: problems in logging the flex residues [FlexResSelected.get() = ", FlexResSelected.get(), "]"
return False
header = header + flex_log + "\n"
# Maps
maps_log = "\n\n ===================================== Maps ====================================================\n"
if MapSource.get() <= 1:
if MapSource.get() == 0:
maps_log = maps_log + "\n Grid mode : calculated in each job.\n"
maps_log = maps_log + " Grid param file template :\n\n"
if MapSource.get() == 1:
if CacheMapPolicy.get() == "Make copies [ use more disk space ]":
maps_log = maps_log + "\n Grid mode : calculated now and >copied< in each ligand job directory.\n"
maps_log = maps_log + " Grid param file template :\n\n"
if CacheMapPolicy.get() == "Make symbolic links [ save disk space ]":
maps_log = maps_log + "\n Grid mode : calculated now and >linked< in each ligand job directory.\n"
maps_log = maps_log + " Grid param file template :\n\n"
maps_log = maps_log+("\t [ AutoGrid binary file used : |%s| ]" % AutoGridBin.get())
# add the gpf lines to the log
for line in GPFcontent.get('1.0', END).split('\n'):
if not line.strip(): # get rid of empty lines
continue
else:
maps_log = maps_log+"\nGPF>\t"+line#"\n"
if GPFParameterFile.get():
maps_log = maps_log+(" [ the parameter file |%s| has been copied ]\n\n" % GPFParameterFile.get())
if MapSource.get() == 2:
if CacheMapPolicy.get() == "Make copies [ use more disk space ]":
cache_policy = " >copied< "
if CacheMapPolicy.get() == "Make symbolic links [ save disk space ]":
cache_policy = " >linked< "
maps_log = maps_log + "\n Grid mode : use pre-calculated"+cache_policy+"in each ligand job directory.\n"
maps_log = maps_log + " Grid cache dir : "+CacheMapDirName.get()
header = header + maps_log
docking_log = "\n\n ================================== Docking parameters ========================================\n"
if docking_set.get() == "From template...":
docking_log = docking_log+"\n Docking mode : docking parameters will be >generated from template< for each ligand.\n"
docking_log = docking_log+" Docking param file template :\n\n"
for line in DPFcontent.get(1.0, END).split('\n'):
if not line.strip(): # get rid of empty lines
continue
else:
docking_log = docking_log+"\nDPF>\t"+line
if DPFParameterFile.get():
docking_log = docking_log+("\n\n[ the parameter file %s has been copied ]" % DPFParameterFile.get())
header = header + docking_log
ligands_log = "\n\n ====================================== Ligands list ============================================\n\n"
for ligand in LigandDictionary.keys():
if LigandDictionary[ligand]["accepted"]:
ligands_log += "\nLIGAND> "+ligand
header += ligands_log
try:
LOG = open(log_name, 'w')
except:
if DEBUG: print "problems in opening the log file"
InfoMessage.set('Problems in opening the log file... generation aborted...')
return False
print >> LOG, header
return LOG
def MakeTar(source_dir, tarfilename):
if DEBUG:
print "MakeTar> creating the tar from the source =>", source_dir
print "MakeTar> The filename is =>", tarfilename
if TarFile.get() == "[disabled]":
return True
if TarFile.get() == "Tar (uncompressed)":
filemode = "w"
ext = ".tar"
if TarFile.get() == "Tar (Bz2 compression)":
filemode = "w:bz2"
ext = ".tar.bz2"
if TarFile.get() == "Tar (Gzip compression)":
filemode = "w:gz"
ext = ".tar.gz"
tarfilename += ext
InfoMessage.set('Writing the VS package...(this could take a while)')
root.update()
short_name = os.path.basename(source_dir)
try:
if DEBUG: print "Trying to generate the tar file", tarfilename
vs_tar = tarfile.open(name = tarfilename, mode = filemode)
root.update()
vs_tar.add(source_dir, arcname = short_name)
root.update()
vs_tar.close()
return True
except:
InfoMessage.set('Error in writing the VS package...')
tkMessageBox.showwarning("Tar file error", "Unable to perform the operation.")
if DEBUG: print "problems in creating the tar file"
return False
def MakeZip(source_dir, zipfilename):
# compression level
compression = zipfile.ZIP_DEFLATED
zipfilename += ".zip"
prefix = os.path.basename(source_dir)
file_list = []
InfoMessage.set('Creating the zip file...')
root.update()
try:
output = zipfile.ZipFile(zipfilename, mode = 'w')
except:
InfoMessage.set('Zip file creation error!')
root.update()
return False
for ROOT, SUBFOLDERS, FILES in os.walk(source_dir):
if DEBUG:
print "=================\nMAKEZIP > "
print "ROOT", ROOT
print "\tSUBFOLDS", SUBFOLDERS
print "\t\tFILES", FILES
for item in FILES:
file_list.append(os.path.join(ROOT,item))
for item in file_list:
if DEBUG: print "Adding |%s| to %s" % (item, zipfilename)
if not zipfilename in item: # to avoid a nice infinite, disk-hungry loop
try:
tmp = item
shortname = tmp.replace(source_dir, prefix)
output.write(item, arcname = shortname, compress_type = compression)
InfoMessage.set('Adding files to the Zip file...(this could take a while)')
root.update()
except:
InfoMessage.set('Error adding files to the Zip archive!')
root.update()
return False
return True
def ImportLigList(filename = None):
if not filename:
filename = askopenfilename(title = "Select a ligand list file......", filetypes =[("Any file...", '*')])
if not filename:
return False
try:
file = open(filename, 'r')
list = file.readlines()
file.close()
except:
tkMessageBox.showwarning("Ligand list", "Warning: unable to open the selected file.")
return False
if len(list)>0:
before = len(LigandDictionary) # this remove spurious counts if there are duplicates in the file
missing = []
found = []
for item in list:
if not item[0] == "#":
item = item.rstrip()
if os.path.isfile(item):
found.append(item)
else:
missing.append(item)
if len(found) == 0:
tkMessageBox.showwarning("Ligand list", "No ligands loaded!\nCheck the list content...\n(maybe it's not a list)")
return False
if len(missing) > 0 and tkMessageBox.askyesno("Ligands imported", "%d ligands have not been found.\n\nDo you want to inspect the list of rejected ligands?" % len(missing)):
RejectedWindow = Toplevel()
RejectedWindow.title("List of discarded ligands")
scrollbar = Scrollbar(RejectedWindow)
ListOfRejected = Listbox(RejectedWindow)
CloseButton = Button(RejectedWindow, text = "Close", command = RejectedWindow.destroy)
ListOfRejected.grid(column = 0, sticky = W+N+S+E)
RejectedWindow.grid_rowconfigure(0, minsize = 300, weight = 1)
RejectedWindow.grid_columnconfigure(0, minsize = 330, weight = 1)
scrollbar.grid(row = 0, column = 1, sticky = S+N)
scrollbar.config(command = ListOfRejected.yview)
ListOfRejected.config(yscrollcommand=scrollbar.set)
for item in missing:
ListOfRejected.insert(END, item)
CloseButton.grid(row = 2, columnspan = 2, sticky = W+E)
return True
else:
openLigand(found)
after = len(LigandDictionary) # this remove spurious counts if there are duplicates in the file
tkMessageBox.showinfo("Ligand list", ("%d new ligands imported." % (after - before)))
return True
else:
tkMessageBox.showwarning("Ligand list", "Empty file... apparently.")
return False
def ExportLigList():
SaveLig = StringVar()
SaveLig.set("all")
header = "# Ligand list saved by Raccoon"
header += "# "
def ExportDone(filename = None):
ExportLigWin.destroy()
list = []
if SaveLig.get() == "all":
for ligand in LigandDictionary:
list.append(ligand)
if SaveLig.get() == "accepted":
for ligand in LigandDictionary:
if LigandDictionary[ligand]["accepted"]: list.append(ligand)
if SaveLig.get() == "rejected":
for ligand in LigandDictionary:
if not LigandDictionary[ligand]["accepted"]: list.append(ligand)
if len(list):
if not filename:
filename = asksaveasfilename(title = "Select a ligand list file......", filetypes = [('Raccoon log file', '*.log'), ("Any file...", "*")] , defaultextension =[("Any file...", '*')])
if not filename:
EnableInterface()
return
file = open(filename, 'w')
for item in list:
print >> file, item
file.close()
EnableInterface()
return
def ExportAbort():
ExportLigWin.destroy()
EnableInterface()
if not len(LigandDictionary):
return
try:
ExportLigWin.lift()
except:
DisableInterface()
rejected = 0
total = len(LigandDictionary.keys())
for item in LigandDictionary.keys():
if not LigandDictionary[item]["accepted"]:
rejected += 1
accepted = total - rejected
all_msg = "All ligands [ %d ]" % total
accepted_msg = "Accepted [ %d ]" % accepted
rejected_msg = "Rejected [ %d ]" % rejected
ExportLigWin = Toplevel(root)
ExportLigWin.title("Export list")
ExportLigWin.winfo_toplevel().resizable(NO,NO)
SelectionLevel = Pmw.Group(ExportLigWin, tag_text = "Select a set...")
SaveLigDefault = Radiobutton(SelectionLevel.interior(), text=all_msg, variable = SaveLig, value = "all" )
SaveLigDefault.grid(row = 0, column = 0, sticky = W) # Default
Radiobutton(SelectionLevel.interior(), text=accepted_msg, variable = SaveLig, value = "accepted").grid(row = 1, column = 0, sticky = W, padx = 15)
Radiobutton(SelectionLevel.interior(), text=rejected_msg, variable = SaveLig, value = "rejected").grid(row = 2, column = 0, sticky = W, padx = 15)
SelectionLevel.grid(row = 0, column = 0, padx = 5, pady = 5, sticky = W, columnspan = 2)
SaveLigDefault.invoke()
Button(ExportLigWin, text = "Save", command = ExportDone).grid(row = 10, column = 0, columnspan = 1, padx = 3, pady= 10)
Button(ExportLigWin, text = "Cancel", command = ExportAbort).grid(row = 10, column = 1, padx = 3, pady= 10)
#EnableInterface()
# Ligand page ############### p1 ################################
LigandButtonsGroup = Frame(p1, relief = FLAT)
AddLigandsButton = Button(LigandButtonsGroup, text='[ + ] Add ligands...', command = openLigand)
AddLigandsButton.pack(expand=YES, anchor=CENTER, side=LEFT)
AddLigandsDirButton = Button(LigandButtonsGroup, text='[ ++ ] Add a directory...', command = openLigandDir)
AddLigandsDirButton.pack(expand=YES, anchor=CENTER, side=LEFT)
AddLigandsDirRecursiveButton = Button(LigandButtonsGroup, text='[ +++ ] Add recursively...', command = openLigandDirRecursive)
AddLigandsDirRecursiveButton.pack(expand=YES, anchor=CENTER, side=LEFT)
LigandButtonsGroup.pack(fill = 'both', expand = 0, padx = 5, pady = 5, anchor = S)
Ligand_group = Pmw.Group(p1, tag_textvariable = LigandListLabel)
LigandScrolledListBox = Listbox(Ligand_group.interior(), selectmode=EXTENDED)
LigandScroll = Scrollbar(Ligand_group.interior(), command=LigandScrolledListBox.yview)
LigandScroll.pack(anchor = N, side = RIGHT, fill = 'y')
LigandScrolledListBox.configure(yscrollcommand=LigandScroll.set)
LigandScrolledListBox.grid(row = 1, column = 0, columnspan = 3, sticky = N+S+W+E)
LigandScrolledListBox.config(fg = 'black', font = ("Helvetica", 11, "bold"))
LigandScrolledListBox.pack(fill = BOTH, expand = 1)
Ligand_group.pack(fill = BOTH, expand = 1, padx = 10, pady = 10, side = TOP , anchor = N)
LigandPDBQTOptButton = Button(p1, text = "PDBQT generation options", command = LigandImportOptions)
LigandPDBQTOptButton.pack(expand = NO, anchor = W, side = LEFT)
FilterButton = Button(p1, text = "Filter ligand list...", command = LigandFilterOptions)
FilterButton.pack(expand = NO, anchor = W, side = LEFT)
RemoveLigandsButton = Button(LigandButtonsGroup, text='[ - ] Remove selected', command=removeLigand)
RemoveLigandsButton.pack(expand=YES, anchor=E, side=LEFT)
RemoveAllLigandsButton = Button(LigandButtonsGroup, text='[ --- ] Remove all', command=removeAllLigands)
RemoveAllLigandsButton.pack(expand=YES, anchor=E, side=LEFT)
# Receptor page ############### p2 ##################################
RCstatus.set(0)
MakeReceptorMenu()
# set defaults
Single_target_radio.invoke()
DoFlex.set(0)
SetFlexibleMode()
# Maps page ################### p3 ##################################
# AutoGrid options
AutoGridMenu = Pmw.Group(p3, tag_text="Run AutoGrid...")
AutoGridWhen1 = Radiobutton(AutoGridMenu.interior(), text='at each job', value=0, variable=MapSource, command = MapMenu)
AutoGridWhen1.grid(row = 1, column = 0, ipadx = 5, ipady = 5)
AutoGridWhen2 = Radiobutton(AutoGridMenu.interior(), text='now (and cache the maps)', value=1, variable=MapSource, command = MapMenu)
AutoGridWhen2.grid(row = 1, column = 1)
AutoGridWhen3 = Radiobutton(AutoGridMenu.interior(), text='never (maps are already calculated)', value=2, variable=MapSource, command = MapMenu)
AutoGridWhen3.grid(row = 1, column = 2)
AutoGridMenu.pack(expand = 1, anchor = NW, padx = 10)
AGoptions = Pmw.Group(p3, tag_pyclass = None)
AutoGridExecButton = Button(AGoptions.interior(), text ="Set the AutoGrid executable", command = GetAutoGrid)
AutoGridExecLabel = Label(AGoptions.interior(),textvariable = AutoGridBin)
AutoGridExecButton.pack(side = TOP, padx = 10)
AutoGridExecLabel.pack(side = TOP, padx = 10)
AGoptions.pack(side = TOP, padx = 10)
MakeGPFMenu()
# set defaults
MapSource.set(0)
AutoGridWhen3.config(state = DISABLED)
AutoGridWhen1.invoke() # Select the default as "Run AG in each job"
# Docking page ########################## p4 ##############################
docking_set = StringVar()
docking_setup_interface("")
# Summary page #################### p5 ###################################
# Create the "Toolbar" contents of the page.
Summary_group = Pmw.Group(p5, tag_text = 'Summary')
Label(Summary_group.interior(), text = "Ligands : ").grid(row = 1, column = 1, padx = 5, sticky = E)
Label(Summary_group.interior(), text = "Receptor(s) : ").grid(row = 2, column = 1, padx = 5, sticky = E)
Label(Summary_group.interior(), text = "Maps : ").grid(row = 3, column = 1, padx = 5, sticky = E)
Label(Summary_group.interior(), text = "Docking : ").grid(row = 4, column = 1, padx = 5, sticky = E)
SetOutDirButton = Button(Summary_group.interior(), text ="Set directory...", command = SetJobDirectory, fg = 'red', justify = LEFT)
SetOutDirButton.grid(row = 5, column = 1, padx = 5, sticky = E)
LigSummaryLabel = Label(Summary_group.interior(), textvariable = LigandSummary, justify = LEFT)
LigSummaryLabel.grid(row = 1, column = 2, padx = 5, sticky = W)
RecSummaryLabel = Label(Summary_group.interior(), textvariable = ReceptorSummary, justify = LEFT)
RecSummaryLabel.grid(row = 2, column = 2, padx = 5, sticky = W)
MapsSummaryLabel = Label(Summary_group.interior(), textvariable = MapsSummary, justify = LEFT)
MapsSummaryLabel.grid(row = 3, column = 2, padx = 5, sticky = W)
DockSummaryLabel = Label(Summary_group.interior(), textvariable = DockingSummary, justify = LEFT)
DockSummaryLabel.grid(row = 4, column = 2, padx = 5, sticky = W)
OutputDirLabel = Label(Summary_group.interior(), textvariable = JobDirectory, justify = LEFT)
OutputDirLabel.grid(row = 5, column = 2, padx = 5, sticky = W)
OutputDirLabelInfo = Label(Summary_group.interior(), textvariable = JobDirectoryInfo)
OutputDirLabelInfo.grid(row = 6, column = 1, columnspan = 3, padx = 5, sticky = S) #, columnspan = 2)
JobsSummaryLabel = Label(Summary_group.interior(), textvariable = JobsSummary)
JobsSummaryLabel.grid(row = 7, column = 1, columnspan = 2, padx = 5, sticky = S)
Summary_group.pack(anchor = N, side = TOP, fill = 'both', expand = 1, padx = 10, pady = 10)#
LigSummaryLabel.config(fg = 'red')
RecSummaryLabel.config(fg = 'red')
MapsSummaryLabel.config(fg = 'red')
DockSummaryLabel.config(fg = 'red')
# OS specific options
Summary_group2 = Pmw.Group(p5, tag_text = 'OS Options')
LinuxOptionsPanel = Pmw.Group(Summary_group2.interior(), tag_pyclass = None)
PBSOptionsPanel = Pmw.Group(Summary_group2.interior(), tag_pyclass = None)
WinOptionsPanel = Pmw.Group(Summary_group2.interior(), tag_pyclass = None)
SystemButton1 = Radiobutton(Summary_group2.interior(), text='Workstation', value='lin', variable=TargetOS, command = GetOSoption)
SystemButton1.grid(row = 1, column = 0, sticky = W)
SystemButton2 = Radiobutton(Summary_group2.interior(), text='Linux cluster', value='pbs', variable=TargetOS, command = GetOSoption)
SystemButton2.grid(row = 1, column = 1, sticky = W)
if system == "Linux" or system == "Darwin":
SystemButton1.invoke()
if system == "Windows":
SystemButton1.invoke()
Summary_group2.pack(anchor = S, side = TOP, fill = 'both', expand = 1, padx = 10, pady = 10)#
# AutoDock Logo
Logo = Canvas(root, width =360, height=73)
logo = Tkinter.PhotoImage(master=root, data=LOGO_BASE64)
Logo.create_image(170,35, image=logo, anchor=CENTER)
Logo.pack(anchor=CENTER, side = BOTTOM)
InfoInit() # Generate the info bar
# Line for avoiding the destruction of the window
root.protocol("WM_DELETE_WINDOW", confirm)
# FINAL GENERATE BUTTON
TheButton = Button(p5, text='G E N E R A T E', fg='black', state = DISABLED, command = TheFunction, height = 3 )
TheButton.pack(pady=2, fill = 'both', padx = 10)
#nb.setnaturalsize() # Resize automatically the window ORIGINAL
makemenu(root)
#root.geometry("800x600")
root.mainloop()
if DEBUG: print "KTHXBY"