raccoon.py0000664000175300017650000065412212111754112013320 0ustar entropiaentropia#!/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"