1 #!/bin/env python 2 # 3 # File: PyMOLVisualizeFpockets.py 4 # Author: Manish Sud <msud@san.rr.com> 5 # 6 # Author: Manish Sud 7 # 8 # Collaborators: Joann Prescott-Roy and Pat Walters 9 # 10 # Copyright (C) 2025 Manish Sud. All rights reserved. 11 # 12 # The functionality available in this script is implemented using PyMOL, a 13 # molecular visualization system on an open source foundation originally 14 # developed by Warren DeLano. 15 # 16 # This file is part of MayaChemTools. 17 # 18 # MayaChemTools is free software; you can redistribute it and/or modify it under 19 # the terms of the GNU Lesser General Public License as published by the Free 20 # Software Foundation; either version 3 of the License, or (at your option) any 21 # later version. 22 # 23 # MayaChemTools is distributed in the hope that it will be useful, but without 24 # any warranty; without even the implied warranty of merchantability of fitness 25 # for a particular purpose. See the GNU Lesser General Public License for more 26 # details. 27 # 28 # You should have received a copy of the GNU Lesser General Public License 29 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or 30 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330, 31 # Boston, MA, 02111-1307, USA. 32 # 33 # 34 35 from __future__ import print_function 36 37 # Add local python path to the global path and import standard library modules... 38 import os 39 import sys; sys.path.insert(0, os.path.join(os.path.dirname(sys.argv[0]), "..", "lib", "Python")) 40 import time 41 import re 42 import glob 43 import shutil 44 45 # PyMOL imports... 46 try: 47 import pymol 48 # Finish launching PyMOL in a command line mode for batch processing (-c) 49 # along with the following options: disable loading of pymolrc and plugins (-k); 50 # suppress start up messages (-q) 51 pymol.finish_launching(['pymol', '-ckq']) 52 except ImportError as ErrMsg: 53 sys.stderr.write("\nFailed to import PyMOL module/package: %s\n" % ErrMsg) 54 sys.stderr.write("Check/update your PyMOL environment and try again.\n\n") 55 sys.exit(1) 56 57 # MayaChemTools imports... 58 try: 59 from docopt import docopt 60 import MiscUtil 61 import PyMOLUtil 62 except ImportError as ErrMsg: 63 sys.stderr.write("\nFailed to import MayaChemTools module/package: %s\n" % ErrMsg) 64 sys.stderr.write("Check/update your MayaChemTools environment and try again.\n\n") 65 sys.exit(1) 66 67 ScriptName = os.path.basename(sys.argv[0]) 68 Options = {} 69 OptionsInfo = {} 70 71 def main(): 72 """Start execution of the script""" 73 74 MiscUtil.PrintInfo("\n%s (PyMOL v%s; MayaChemTools v%s; %s): Starting...\n" % (ScriptName, pymol.cmd.get_version()[0], MiscUtil.GetMayaChemToolsVersion(), time.asctime())) 75 76 (WallClockTime, ProcessorTime) = MiscUtil.GetWallClockAndProcessorTime() 77 78 # Retrieve command line arguments and options... 79 RetrieveOptions() 80 81 # Process and validate command line arguments and options... 82 ProcessOptions() 83 84 # Perform actions required by the script... 85 GenerateFpocketsVisualization() 86 87 MiscUtil.PrintInfo("\n%s: Done...\n" % ScriptName) 88 MiscUtil.PrintInfo("Total time: %s" % MiscUtil.GetFormattedElapsedTime(WallClockTime, ProcessorTime)) 89 90 def GenerateFpocketsVisualization(): 91 """Generate fpockets visualization.""" 92 93 Outfile = OptionsInfo["PMLOutfilePath"] 94 OutFH = open(Outfile, "w") 95 if OutFH is None: 96 MiscUtil.PrintError("Failed to open output fie %s " % Outfile) 97 98 MiscUtil.PrintInfo("\nGenerating file %s..." % Outfile) 99 100 # Setup header... 101 WritePMLHeader(OutFH, ScriptName) 102 WritePyMOLParameters(OutFH) 103 104 if OptionsInfo["Align"]: 105 WriteAlignReference(OutFH) 106 107 # Setup view for each input file... 108 FirstComplex = True 109 FirstComplexFirstChainName = None 110 for FileIndex in range(0, len(OptionsInfo["InfilesInfo"]["InfilesNames"])): 111 # Setup PyMOL object names... 112 PyMOLObjectNames = SetupPyMOLObjectNames(FileIndex) 113 114 # Setup complex view... 115 WriteComplexView(OutFH, FileIndex, PyMOLObjectNames, FirstComplex) 116 117 # Setup chain and pocket views... 118 SpecifiedChainsAndPocketsInfo = OptionsInfo["FpocketInfilesInfo"]["SpecifiedChainsAndPocketsInfo"][FileIndex] 119 FirstChain = True 120 for ChainID in SpecifiedChainsAndPocketsInfo["ChainIDs"]: 121 if FirstComplex and FirstChain: 122 FirstComplexFirstChainName = PyMOLObjectNames["Chains"][ChainID]["ChainAlone"] 123 124 WriteChainView(OutFH, FileIndex, PyMOLObjectNames, ChainID) 125 126 # Setup fpocket views... 127 FirstPocket = True 128 PocketNum = 0 129 for PocketID in SpecifiedChainsAndPocketsInfo["PocketIDs"][ChainID]: 130 PocketNum += 1 131 WriteChainPocketView(OutFH, FileIndex, PyMOLObjectNames, ChainID, PocketID, PocketNum) 132 133 # Set up pocket level group... 134 Enable, Action = [False, "close"] 135 if FirstPocket: 136 FirstPocket = False 137 Enable, Action = [True, "open"] 138 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["Pockets"][ChainID][PocketID]["ChainPocketGroup"], PyMOLObjectNames["Pockets"][ChainID][PocketID]["ChainPocketGroupMembers"], Enable, Action) 139 140 # Setup Chain level group... 141 Enable, Action = [False, "close"] 142 if FirstChain: 143 FirstChain = False 144 Enable, Action = [True, "open"] 145 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["Chains"][ChainID]["ChainGroup"], PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"], Enable, Action) 146 147 # Set up complex level group... 148 Enable, Action = [False, "close"] 149 if FirstComplex: 150 FirstComplex = False 151 Enable, Action = [True, "open"] 152 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["PDBGroup"], PyMOLObjectNames["PDBGroupMembers"], Enable, Action) 153 154 if OptionsInfo["Align"]: 155 DeleteAlignReference(OutFH) 156 157 if FirstComplexFirstChainName is not None: 158 OutFH.write("""\ncmd.orient("%s", animate = -1)\n""" % FirstComplexFirstChainName) 159 else: 160 OutFH.write("""\ncmd.orient("visible", animate = -1)\n""") 161 162 OutFH.close() 163 164 CopyPDBFilesForPML() 165 166 def WritePMLHeader(OutFH, ScriptName): 167 """Write out PML header.""" 168 169 HeaderInfo = PyMOLUtil.SetupPMLHeaderInfo(ScriptName) 170 OutFH.write("%s\n" % HeaderInfo) 171 172 def WritePyMOLParameters(OutFH): 173 """Write out PyMOL global parameters. """ 174 175 PMLCmds = [] 176 PMLCmds.append("""cmd.set("transparency", %.2f, "", 0)""" % (OptionsInfo["SurfaceTransparency"])) 177 PMLCmds.append("""cmd.set("label_font_id", %s)""" % (OptionsInfo["LabelFontID"])) 178 PML = "\n".join(PMLCmds) 179 180 OutFH.write("""\n""\n"Setting up PyMOL gobal parameters..."\n""\n""") 181 OutFH.write("%s\n" % PML) 182 183 def WriteAlignReference(OutFH): 184 """Setup object for alignment reference """ 185 186 RefFileInfo = OptionsInfo["RefFileInfo"] 187 RefFile = RefFileInfo["RefFileName"] 188 RefName = RefFileInfo["PyMOLObjectName"] 189 190 PMLCmds = [] 191 PMLCmds.append("""cmd.load("%s", "%s")""" % (RefFile, RefName)) 192 PMLCmds.append("""cmd.hide("everything", "%s")""" % (RefName)) 193 PMLCmds.append("""cmd.disable("%s")""" % (RefName)) 194 PML = "\n".join(PMLCmds) 195 196 OutFH.write("""\n""\n"Loading %s and setting up view for align reference..."\n""\n""" % RefFile) 197 OutFH.write("%s\n" % PML) 198 199 def WriteAlignComplex(OutFH, FileIndex, FpocketComplexMode, PyMOLObjectNames): 200 """Setup alignment of complex to reference""" 201 202 RefFileInfo = OptionsInfo["RefFileInfo"] 203 RefName = RefFileInfo["PyMOLObjectName"] 204 205 if FpocketComplexMode: 206 ComplexName = PyMOLObjectNames["FpocketComplex"] 207 else: 208 ComplexName = PyMOLObjectNames["InitialComplex"] 209 210 if re.match("^FirstChain$", OptionsInfo["AlignMode"], re.I): 211 RefFirstChainID = RefFileInfo["ChainsAndLigandsInfo"]["ChainIDs"][0] 212 RefAlignSelection = "%s and chain %s" % (RefName, RefFirstChainID) 213 214 ComplexFirstChainID = RetrieveFirstChainID(FileIndex, FpocketComplexMode) 215 ComplexAlignSelection = "%s and chain %s" % (ComplexName, ComplexFirstChainID) 216 else: 217 RefAlignSelection = RefName 218 ComplexAlignSelection = ComplexName 219 220 PML = PyMOLUtil.SetupPMLForAlignment(OptionsInfo["AlignMethod"], RefAlignSelection, ComplexAlignSelection) 221 OutFH.write("""\n""\n"Aligning %s against reference %s ..."\n""\n""" % (ComplexAlignSelection, RefAlignSelection)) 222 OutFH.write("%s\n" % PML) 223 224 def DeleteAlignReference(OutFH): 225 """Delete alignment reference object.""" 226 227 RefName = OptionsInfo["RefFileInfo"]["PyMOLObjectName"] 228 OutFH.write("""\n""\n"Deleting alignment reference object %s..."\n""\n""" % RefName) 229 OutFH.write("""cmd.delete("%s")\n""" % RefName) 230 231 def WriteComplexView(OutFH, FileIndex, PyMOLObjectNames, FirstComplex): 232 """Write out PML for viewing polymer complex.""" 233 234 # Setup initial complex... 235 Infile = OptionsInfo["InfilesInfo"]["InfilesNames"][FileIndex] 236 PML = PyMOLUtil.SetupPMLForPolymerComplexView(PyMOLObjectNames["InitialComplex"], Infile, True) 237 OutFH.write("""\n""\n"Loading %s and setting up view for complex..."\n""\n""" % Infile) 238 OutFH.write("%s\n" % PML) 239 240 if OptionsInfo["Align"]: 241 # No need to align initial complex on to itself... 242 FpocketComplexMode = False 243 if not (re.match("^FirstInputFile$", OptionsInfo["AlignRefFile"], re.I) and FirstComplex): 244 WriteAlignComplex(OutFH, FileIndex, FpocketComplexMode, PyMOLObjectNames) 245 246 # Setup fpocket complex... 247 Infile = OptionsInfo["FpocketInfilesInfo"]["InfilesNames"][FileIndex] 248 PML = PyMOLUtil.SetupPMLForPolymerComplexView(PyMOLObjectNames["FpocketComplex"], Infile, True) 249 250 # Modify default complex view for fpocket complex... 251 PMLModify = SetupPMLModifyDefaultPolymerComplexView(PyMOLObjectNames["FpocketComplex"]) 252 253 OutFH.write("""\n""\n"Loading %s and setting up view for complex..."\n""\n""" % Infile) 254 OutFH.write("%s\n%s\n" % (PML, PMLModify)) 255 256 if OptionsInfo["Align"]: 257 # No need to align initial complex on to itself... 258 FpocketComplexMode = True 259 if not (re.match("^FirstInputFile$", OptionsInfo["AlignRefFile"], re.I) and FirstComplex): 260 WriteAlignComplex(OutFH, FileIndex, FpocketComplexMode, PyMOLObjectNames) 261 262 # Setup complex group... 263 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["ComplexGroup"], PyMOLObjectNames["ComplexGroupMembers"], False, "close") 264 265 def WriteChainView(OutFH, FileIndex, PyMOLObjectNames, ChainID): 266 """Write out PML for viewing chain.""" 267 268 OutFH.write("""\n""\n"Setting up views for chain %s..."\n""\n""" % ChainID) 269 270 ChainComplexName = PyMOLObjectNames["Chains"][ChainID]["ChainComplex"] 271 272 # Setup chain complex group view... 273 WriteChainComplexViews(OutFH, FileIndex, PyMOLObjectNames, ChainID) 274 275 # Setup chain view... 276 WriteChainAloneViews(OutFH, FileIndex, PyMOLObjectNames, ChainID) 277 278 def WriteChainComplexViews(OutFH, FileIndex, PyMOLObjectNames, ChainID): 279 """Write chain complex views. """ 280 281 # Setup chain complex... 282 ChainComplexName = PyMOLObjectNames["Chains"][ChainID]["ChainComplex"] 283 PML = SetupPMLForFpocketChainComplexView(FileIndex, ChainComplexName, PyMOLObjectNames["FpocketComplex"], ChainID, True) 284 285 # Modify default complex view for fpocket chain complex... 286 PMLModify = SetupPMLModifyDefaultPolymerComplexView(ChainComplexName) 287 OutFH.write("%s\n%s\n" % (PML, PMLModify)) 288 289 # Setup chain complex group... 290 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroup"], PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroupMembers"], False, "close") 291 292 def WriteChainAloneViews(OutFH, FileIndex, PyMOLObjectNames, ChainID): 293 """Write individual chain views. """ 294 295 ChainComplexName = PyMOLObjectNames["Chains"][ChainID]["ChainComplex"] 296 297 # Setup chain view... 298 ChainName = PyMOLObjectNames["Chains"][ChainID]["ChainAlone"] 299 PML = PyMOLUtil.SetupPMLForPolymerChainView(ChainName, ChainComplexName, True) 300 OutFH.write("\n%s\n" % PML) 301 302 if GetChainAloneContainsSurfacesStatus(FileIndex, ChainID): 303 # Setup a generic color surface... 304 PML = PyMOLUtil.SetupPMLForSurfaceView(PyMOLObjectNames["Chains"][ChainID]["ChainAloneSurface"], ChainName, Enable = False, Color = OptionsInfo["SurfaceColor"]) 305 OutFH.write("\n%s\n" % PML) 306 307 if GetChainAloneSurfaceChainStatus(FileIndex, ChainID): 308 # Setup surface colored by hydrophobicity... 309 PML = PyMOLUtil.SetupPMLForHydrophobicSurfaceView(PyMOLObjectNames["Chains"][ChainID]["ChainAloneHydrophobicSurface"], ChainName, ColorPalette = OptionsInfo["SurfaceColorPalette"], Enable = False) 310 OutFH.write("\n%s\n" % PML) 311 312 # Setup surface colored by hyrdophobicity and charge... 313 PML = PyMOLUtil.SetupPMLForHydrophobicAndChargeSurfaceView(PyMOLObjectNames["Chains"][ChainID]["ChainAloneHydrophobicChargeSurface"], ChainName, OptionsInfo["AtomTypesColorNames"]["HydrophobicAtomsColor"], OptionsInfo["AtomTypesColorNames"]["NegativelyChargedAtomsColor"], OptionsInfo["AtomTypesColorNames"]["PositivelyChargedAtomsColor"], OptionsInfo["AtomTypesColorNames"]["OtherAtomsColor"], Enable = False, DisplayAs = None) 314 OutFH.write("\n%s\n" % PML) 315 316 # Setup surface group... 317 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["Chains"][ChainID]["ChainAloneSurfaceGroup"], PyMOLObjectNames["Chains"][ChainID]["ChainAloneSurfaceGroupMembers"], True, "open") 318 319 # Setup chain group... 320 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroup"], PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroupMembers"], True, "close") 321 322 def WriteChainPocketView(OutFH, FileIndex, PyMOLObjectNames, ChainID, PocketID, PocketNum): 323 """Write out PML for viewing pocket in a chain.""" 324 325 OutFH.write("""\n""\n"Setting up views for pocket %s in chain %s..."\n""\n""" % (PocketID, ChainID)) 326 327 FpocketComplexName = PyMOLObjectNames["FpocketComplex"] 328 329 # Setup pocket... 330 PML = SetupPMLForFPocketView(PyMOLObjectNames["Pockets"][ChainID][PocketID]["Pocket"], FpocketComplexName, ChainID, PocketID, PocketNum, True) 331 OutFH.write("%s\n" % PML) 332 333 # Setup pocket residues... 334 ChainsAndPocketsInfo = OptionsInfo["FpocketInfilesInfo"]["ChainsAndPocketsInfo"][FileIndex] 335 PocketResNums = ChainsAndPocketsInfo["PocketResNums"][ChainID][PocketID] 336 PocketResiduesName = PyMOLObjectNames["Pockets"][ChainID][PocketID]["PocketResidues"] 337 PML = SetupPMLForFPocketResiduesView(PocketResiduesName, FpocketComplexName, ChainID, PocketID, PocketNum, PocketResNums, True) 338 OutFH.write("%s\n" % PML) 339 340 # Setup pocket surfaces and group... 341 if GetPocketContainsSurfaceStatus(FileIndex, ChainID, PocketID): 342 # Setup a generic color surface... 343 PML = PyMOLUtil.SetupPMLForSurfaceView(PyMOLObjectNames["Pockets"][ChainID][PocketID]["PocketSurface"], PocketResiduesName, Enable = False, Color = OptionsInfo["SurfaceColor"]) 344 OutFH.write("\n%s\n" % PML) 345 346 if GetPocketSurfaceChainStatus(FileIndex, ChainID, PocketID): 347 # Setup surface colored by hydrophobicity... 348 PML = PyMOLUtil.SetupPMLForHydrophobicSurfaceView(PyMOLObjectNames["Pockets"][ChainID][PocketID]["PocketHydrophobicitySurface"], PocketResiduesName, ColorPalette = OptionsInfo["SurfaceColorPalette"], Enable = False) 349 OutFH.write("\n%s\n" % PML) 350 351 # Setup surface colored by hyrdophobicity and charge... 352 PML = PyMOLUtil.SetupPMLForHydrophobicAndChargeSurfaceView(PyMOLObjectNames["Pockets"][ChainID][PocketID]["PocketHydrophobicityChargeSurface"], PocketResiduesName, OptionsInfo["AtomTypesColorNames"]["HydrophobicAtomsColor"], OptionsInfo["AtomTypesColorNames"]["NegativelyChargedAtomsColor"], OptionsInfo["AtomTypesColorNames"]["PositivelyChargedAtomsColor"], OptionsInfo["AtomTypesColorNames"]["OtherAtomsColor"], Enable = False, DisplayAs = None) 353 OutFH.write("\n%s\n" % PML) 354 355 # Setup surface group... 356 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["Pockets"][ChainID][PocketID]["PocketSurfaceGroup"], PyMOLObjectNames["Pockets"][ChainID][PocketID]["PocketSurfaceGroupMembers"], True, "open") 357 358 # Setup pocket group... 359 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["Pockets"][ChainID][PocketID]["ChainPocketGroup"], PyMOLObjectNames["Pockets"][ChainID][PocketID]["ChainPocketGroupMembers"], True, "open") 360 361 def SetupPMLForFpocketChainComplexView(FileIndex, Name, Selection, ChainName, Enable = True): 362 """Setup PML commands for creating a polymer chain complex view 363 including fockets for the chain.""" 364 365 PMLCmds = [] 366 367 # Include fpockets as spheres for the chain complex view... 368 ChainsAndPocketsInfo = OptionsInfo["FpocketInfilesInfo"]["ChainsAndPocketsInfo"][FileIndex] 369 PocketIDs = ChainsAndPocketsInfo["PocketIDs"][ChainName] 370 371 PMLCmds.append("""cmd.create("%s", "((%s and chain %s) or (%s and (resn STP and resi %s)))")""" % (Name, Selection, ChainName, Selection, "+".join(PocketIDs))) 372 PMLCmds.append("""cmd.hide("everything", "%s")""" % (Name)) 373 PMLCmds.append("""cmd.show("cartoon", "%s")""" % (Name)) 374 PMLCmds.append("""util.cba(33, "%s", _self = cmd)""" % (Name)) 375 PMLCmds.append("""cmd.show("sticks", "(organic and (%s))")""" % (Name)) 376 377 PMLCmds.append("""cmd.show("nonbonded", "(solvent and (%s))")""" % (Name)) 378 PMLCmds.append("""cmd.show("nonbonded", "(inorganic and (%s))")""" % (Name)) 379 380 PMLCmds.append("""cmd.show("lines", "%s")""" % (Name)) 381 382 PMLCmds.append("""cmd.set_bond("valence", "1", "%s", quiet = 1)""" % (Name)) 383 PMLCmds.append(PyMOLUtil.SetupPMLForEnableDisable(Name, Enable)) 384 385 PML = "\n".join(PMLCmds) 386 387 return PML 388 389 def SetupPMLModifyDefaultPolymerComplexView(Name): 390 """Setup PML to modify default polymer complex view for fpocket. """ 391 392 PMLCmds = [] 393 PMLCmds.append("""cmd.hide("lines", "%s")""" % (Name)) 394 PMLCmds.append("""cmd.show("lines", "(polymer and (%s))")""" % (Name)) 395 PMLCmds.append("""cmd.show("lines", "(solvent and (%s))")""" % (Name)) 396 PMLCmds.append("""cmd.show("spheres", "(inorganic and (%s))")""" % (Name)) 397 PMLCmds.append("""cmd.set("sphere_scale", "%s", "(inorganic and (%s))")""" % (OptionsInfo["SphereScale"], Name)) 398 PMLCmds.append("""cmd.set("sphere_transparency", "%s", "(inorganic and (%s))")""" % (OptionsInfo["SphereTransparency"], Name)) 399 400 PML = "\n".join(PMLCmds) 401 402 return PML 403 404 def SetupPMLForFPocketView(FpocketName, FpocketComplexName, ChainID, PocketID, PocketNum, Enable = True): 405 """Setup PML to visualize fpocket spheres using fpocket complex.""" 406 407 PMLCmds = [] 408 PMLCmds.append("""cmd.create("%s", "(%s and (resn STP and resi %s))")""" % (FpocketName, FpocketComplexName, PocketID)) 409 if PocketNum == 1: 410 # Skip color index of 1: It is set to black. Use pocket one color name... 411 PMLCmds.append("""cmd.color(%s, "%s")""" % (OptionsInfo["PocketNumOneColor"], FpocketName)) 412 else: 413 PMLCmds.append("""cmd.color(%s, "%s")""" % (PocketNum, FpocketName)) 414 PMLCmds.append("""cmd.show("spheres", "%s")""" % (FpocketName)) 415 PMLCmds.append("""cmd.set("sphere_scale", "%s", "%s")""" % (OptionsInfo["SphereScale"], FpocketName)) 416 PMLCmds.append("""cmd.set("sphere_transparency", "%s", "%s")""" % (OptionsInfo["SphereTransparency"], FpocketName)) 417 418 PMLCmds.append(PyMOLUtil.SetupPMLForEnableDisable(FpocketName, Enable)) 419 420 PML = "\n".join(PMLCmds) 421 return PML 422 423 def SetupPMLForFPocketResiduesView(Name, FpocketComplexName, ChainID, PocketID, PocketNum, PocketResNums, Enable = True): 424 """Setup PML to visualize fpocket residues.""" 425 426 PMLCmds = [] 427 428 PMLCmds.append("""cmd.create("%s", "(%s and (chain %s) and (resi %s))")""" % (Name, FpocketComplexName, ChainID, "+".join(PocketResNums))) 429 PMLCmds.append("""cmd.hide("everything", "%s")""" % (Name)) 430 431 # Setup pocket residue labels... 432 if OptionsInfo["PocketLabel"]: 433 if OptionsInfo["ThreeLetterPocketLabelType"]: 434 LabelFormat = '''"%s-%s"%(resn,resi)''' 435 PMLCmds.append("""cmd.label("(name CA+C1*+C1' and (byres(%s)))", \'\'\'%s\'\'\')""" % (Name, LabelFormat)) 436 else: 437 PMLCmds.append("""cmd.label("byca(%s)", "oneletter+resi")""" % (Name)) 438 439 PocketColor = OptionsInfo["PocketNumOneColor"] if PocketNum == 1 else PocketNum 440 441 if OptionsInfo["PocketColorByPocketNum"]: 442 # Setup color of pocket residues... 443 PMLCmds.append(PyMOLUtil.SetupPMLForDeepColoring(Name, PocketColor)) 444 445 # Setup color of pocket residue labels... 446 PMLCmds.append("""cmd.set("label_color", %s, "%s")""" % (PocketColor, Name)) 447 else: 448 PMLCmds.append("""util.cbag("%s", _self = cmd)""" % (Name)) 449 450 451 PMLCmds.append("""cmd.show("lines", "%s")""" % (Name)) 452 453 PMLCmds.append(PyMOLUtil.SetupPMLForEnableDisable(Name, Enable)) 454 455 PML = "\n".join(PMLCmds) 456 return PML 457 458 def GenerateAndWritePMLForGroup(OutFH, GroupName, GroupMembers, Enable = False, Action = "close"): 459 """Generate and write PML for group. """ 460 461 PML = PyMOLUtil.SetupPMLForGroup(GroupName, GroupMembers, Enable, Action) 462 OutFH.write("""\n""\n"Setting up group %s..."\n""\n""" % GroupName) 463 OutFH.write("%s\n" % PML) 464 465 def WritePMLToCheckAndDeleteEmptyObjects(OutFH, ObjectName, ParentObjectName = None): 466 """Write PML to check and delete empty PyMOL objects. """ 467 468 if ParentObjectName is None: 469 PML = """CheckAndDeleteEmptyObjects("%s")""" % (ObjectName) 470 else: 471 PML = """CheckAndDeleteEmptyObjects("%s", "%s")""" % (ObjectName, ParentObjectName) 472 473 OutFH.write("%s\n" % PML) 474 475 def SetupPyMOLObjectNames(FileIndex): 476 """Setup hierarchy of PyMOL groups and objects for pocket centric views of 477 chains and pockets present in input file. 478 """ 479 480 PyMOLObjectNames = {} 481 PyMOLObjectNames["Chains"] = {} 482 PyMOLObjectNames["Pockets"] = {} 483 484 # Setup groups and objects for complex... 485 SetupPyMOLObjectNamesForComplex(FileIndex, PyMOLObjectNames) 486 487 # Setup groups and objects for chains using fpockets info... 488 SpecifiedChainsAndPocketsInfo = OptionsInfo["FpocketInfilesInfo"]["SpecifiedChainsAndPocketsInfo"][FileIndex] 489 for ChainID in SpecifiedChainsAndPocketsInfo["ChainIDs"]: 490 SetupPyMOLObjectNamesForChain(FileIndex, PyMOLObjectNames, ChainID) 491 492 # Setup groups and objects for pocket... 493 for PocketID in SpecifiedChainsAndPocketsInfo["PocketIDs"][ChainID]: 494 SetupPyMOLObjectNamesForPocket(FileIndex, PyMOLObjectNames, ChainID, PocketID) 495 496 return PyMOLObjectNames 497 498 def SetupPyMOLObjectNamesForComplex(FileIndex, PyMOLObjectNames): 499 """Setup groups and objects for complex. """ 500 501 PDBFileRoot = OptionsInfo["InfilesInfo"]["InfilesRoots"][FileIndex] 502 503 PDBGroupName = "%s" % PDBFileRoot 504 PyMOLObjectNames["PDBGroup"] = PDBGroupName 505 PyMOLObjectNames["PDBGroupMembers"] = [] 506 507 ComplexGroupName = "%s.Complex" % PyMOLObjectNames["PDBGroup"] 508 PyMOLObjectNames["ComplexGroup"] = ComplexGroupName 509 PyMOLObjectNames["ComplexGroupMembers"] = [] 510 511 PyMOLObjectNames["PDBGroupMembers"].append(ComplexGroupName) 512 513 PyMOLObjectNames["InitialComplex"] = "%s.Initial_Complex" % ComplexGroupName 514 PyMOLObjectNames["FpocketComplex"] = "%s.Fpocket_Complex" % ComplexGroupName 515 516 PyMOLObjectNames["ComplexGroupMembers"].append(PyMOLObjectNames["InitialComplex"]) 517 PyMOLObjectNames["ComplexGroupMembers"].append(PyMOLObjectNames["FpocketComplex"]) 518 519 def SetupPyMOLObjectNamesForChain(FileIndex, PyMOLObjectNames, ChainID): 520 """Setup groups and objects for chain.""" 521 522 PDBGroupName = PyMOLObjectNames["PDBGroup"] 523 524 PyMOLObjectNames["Chains"][ChainID] = {} 525 PyMOLObjectNames["Pockets"][ChainID] = {} 526 527 # Set up chain group and chain objects... 528 ChainGroupName = "%s.Chain%s" % (PDBGroupName, ChainID) 529 PyMOLObjectNames["Chains"][ChainID]["ChainGroup"] = ChainGroupName 530 PyMOLObjectNames["PDBGroupMembers"].append(ChainGroupName) 531 PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"] = [] 532 533 # Setup chain complex group and objects... 534 ChainComplexGroupName = "%s.Complex" % (ChainGroupName) 535 PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroup"] = ChainComplexGroupName 536 PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"].append(ChainComplexGroupName) 537 538 PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroupMembers"] = [] 539 540 Name = "%s.Complex" % (ChainComplexGroupName) 541 PyMOLObjectNames["Chains"][ChainID]["ChainComplex"] = Name 542 PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroupMembers"].append(Name) 543 544 # Setup up a group for individual chains... 545 ChainAloneGroupName = "%s.Chain" % (ChainGroupName) 546 PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroup"] = ChainAloneGroupName 547 PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"].append(ChainAloneGroupName) 548 549 PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroupMembers"] = [] 550 551 Name = "%s.Chain" % (ChainAloneGroupName) 552 PyMOLObjectNames["Chains"][ChainID]["ChainAlone"] = Name 553 PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroupMembers"].append(Name) 554 555 if GetChainAloneContainsSurfacesStatus(FileIndex, ChainID): 556 # Setup a surface group and add it to chain alone group... 557 SurfaceGroupName = "%s.Surface" % (ChainAloneGroupName) 558 PyMOLObjectNames["Chains"][ChainID]["ChainAloneSurfaceGroup"] = SurfaceGroupName 559 PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroupMembers"].append(SurfaceGroupName) 560 561 PyMOLObjectNames["Chains"][ChainID]["ChainAloneSurfaceGroupMembers"] = [] 562 563 # Setup a generic color surface... 564 Name = "%s.Surface" % (SurfaceGroupName) 565 PyMOLObjectNames["Chains"][ChainID]["ChainAloneSurface"] = Name 566 PyMOLObjectNames["Chains"][ChainID]["ChainAloneSurfaceGroupMembers"].append(Name) 567 568 if GetChainAloneSurfaceChainStatus(FileIndex, ChainID): 569 # Setup hydrophobicity surface... 570 Name = "%s.Hydrophobicity" % (SurfaceGroupName) 571 PyMOLObjectNames["Chains"][ChainID]["ChainAloneHydrophobicSurface"] = Name 572 PyMOLObjectNames["Chains"][ChainID]["ChainAloneSurfaceGroupMembers"].append(Name) 573 574 # Setup hydrophobicity and charge surface... 575 Name = "%s.Hydrophobicity_Charge" % (SurfaceGroupName) 576 PyMOLObjectNames["Chains"][ChainID]["ChainAloneHydrophobicChargeSurface"] = Name 577 PyMOLObjectNames["Chains"][ChainID]["ChainAloneSurfaceGroupMembers"].append(Name) 578 579 def SetupPyMOLObjectNamesForPocket(FileIndex, PyMOLObjectNames, ChainID, PocketID): 580 """Stetup groups and objects for pocket.""" 581 582 PyMOLObjectNames["Pockets"][ChainID][PocketID] = {} 583 584 ChainGroupName = PyMOLObjectNames["Chains"][ChainID]["ChainGroup"] 585 586 # Setup a chain level pocket group... 587 ChainPocketGroupName = SetupChainPocketGroupName(FileIndex, ChainGroupName, ChainID, PocketID) 588 589 PyMOLObjectNames["Pockets"][ChainID][PocketID]["ChainPocketGroup"] = ChainPocketGroupName 590 PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"].append(ChainPocketGroupName) 591 592 PyMOLObjectNames["Pockets"][ChainID][PocketID]["ChainPocketGroupMembers"] = [] 593 594 # Setup fpocket... 595 Name = "%s.Fpocket" % (ChainPocketGroupName) 596 PyMOLObjectNames["Pockets"][ChainID][PocketID]["Pocket"] = Name 597 PyMOLObjectNames["Pockets"][ChainID][PocketID]["ChainPocketGroupMembers"].append(Name) 598 599 # Setup fpocket residues... 600 Name = "%s.Residues" % (ChainPocketGroupName) 601 PyMOLObjectNames["Pockets"][ChainID][PocketID]["PocketResidues"] = Name 602 PyMOLObjectNames["Pockets"][ChainID][PocketID]["ChainPocketGroupMembers"].append(Name) 603 604 if GetPocketContainsSurfaceStatus(FileIndex, ChainID, PocketID): 605 # Setup a pocket surface group and add it to chain pocket group 606 SurfaceGroupName = "%s.Surface" % (ChainPocketGroupName) 607 PyMOLObjectNames["Pockets"][ChainID][PocketID]["PocketSurfaceGroup"] = SurfaceGroupName 608 PyMOLObjectNames["Pockets"][ChainID][PocketID]["ChainPocketGroupMembers"].append(SurfaceGroupName) 609 610 PyMOLObjectNames["Pockets"][ChainID][PocketID]["PocketSurfaceGroupMembers"] = [] 611 612 # Setup a generic color surface... 613 Name = "%s.Surface" % (SurfaceGroupName) 614 PyMOLObjectNames["Pockets"][ChainID][PocketID]["PocketSurface"] = Name 615 PyMOLObjectNames["Pockets"][ChainID][PocketID]["PocketSurfaceGroupMembers"].append(Name) 616 617 if GetPocketSurfaceChainStatus(FileIndex, ChainID, PocketID): 618 # Surface colored by hydrophobicity... 619 Name = "%s.Hydrophobicity" % (SurfaceGroupName) 620 PyMOLObjectNames["Pockets"][ChainID][PocketID]["PocketHydrophobicitySurface"] = Name 621 PyMOLObjectNames["Pockets"][ChainID][PocketID]["PocketSurfaceGroupMembers"].append(Name) 622 623 # Surface colored by hydrophobicity and charge... 624 Name = "%s.Hydrophobicity_Charge" % (SurfaceGroupName) 625 PyMOLObjectNames["Pockets"][ChainID][PocketID]["PocketHydrophobicityChargeSurface"] = Name 626 PyMOLObjectNames["Pockets"][ChainID][PocketID]["PocketSurfaceGroupMembers"].append(Name) 627 628 def SetupChainPocketGroupName(FileIndex, ChainGroupName, ChainID, PocketID): 629 """Setup pocket group PyMOL object name. """ 630 631 ChainPocketGroupName = "%s.Fpocket%s" % (ChainGroupName, PocketID) 632 633 if not OptionsInfo["FpocketPropertiesAppend"]: 634 return ChainPocketGroupName 635 636 PocketPropertiesName = SetupFpocketPropertiesForGroupName(FileIndex, ChainGroupName, ChainID, PocketID) 637 638 ChainPocketGroupName = "%s_%s" % (ChainPocketGroupName, PocketPropertiesName) 639 640 return ChainPocketGroupName 641 642 def SetupFpocketPropertiesForGroupName(FileIndex, ChainGroupName, ChainID, PocketID): 643 """Setup fpocket properties for PyMOL group name. """ 644 645 ChainsAndPocketsInfo = OptionsInfo["FpocketInfilesInfo"]["ChainsAndPocketsInfo"][FileIndex] 646 647 PocketScore = FormatFpocketPropertyForGroupName(ChainsAndPocketsInfo["PocketScore"][ChainID][PocketID]) 648 DrugScore = FormatFpocketPropertyForGroupName(ChainsAndPocketsInfo["DrugScore"][ChainID][PocketID]) 649 HydrophobicityScore = FormatFpocketPropertyForGroupName(ChainsAndPocketsInfo["HydrophobicityScore"][ChainID][PocketID]) 650 PolarityScore = FormatFpocketPropertyForGroupName(ChainsAndPocketsInfo["PolarityScore"][ChainID][PocketID]) 651 PocketVolume = FormatFpocketPropertyForGroupName(ChainsAndPocketsInfo["PocketVolume"][ChainID][PocketID]) 652 653 PocketProperties = "S%s_D%s_V%s_H%s_P%s" % (PocketScore, DrugScore, PocketVolume, HydrophobicityScore, PolarityScore) 654 655 return PocketProperties 656 657 def FormatFpocketPropertyForGroupName(PocketProperty): 658 """Format fpocket property for PyMOL group name. """ 659 660 if PocketProperty is None: 661 PocketProperty = "NA" 662 else: 663 PocketProperty = "%.2f" % float(PocketProperty) 664 PocketProperty = re.sub("\.", "p", PocketProperty) 665 PocketProperty = re.sub("^-", "neg", PocketProperty) 666 667 return PocketProperty 668 669 def GetChainAloneContainsSurfacesStatus(FileIndex, ChainID): 670 """Get status of surfaces present in chain alone object.""" 671 672 # Always set up generic color surfaces... 673 return True 674 675 def GetChainAloneSurfaceChainStatus(FileIndex, ChainID): 676 """Get status of surfaces for chain alone object.""" 677 678 return OptionsInfo["SurfaceChain"] 679 680 def GetPocketContainsSurfaceStatus(FileIndex, ChainID, PocketID): 681 """Get status of surfaces present in a pocket object.""" 682 683 # Always set up generic color surfaces... 684 return True 685 686 def GetPocketSurfaceChainStatus(FileIndex, ChainID, PocketID): 687 """Get status of surfaces for pocket object.""" 688 689 return OptionsInfo["PocketSurface"] 690 691 def CopyPDBFilesForPML(): 692 """Copy appropriate PDB files for PyMOL to OutfilesDir """ 693 694 OutfilesDir = OptionsInfo["OutfilesDir"] 695 696 MiscUtil.PrintInfo("\nCopying appropriate PDB files to directory %s..." % OutfilesDir) 697 698 # Copy input PDB files... 699 for FileIndex in range(0, len(OptionsInfo["InfilesInfo"]["InfilesNames"])): 700 Infile = OptionsInfo["InfilesInfo"]["InfilesNames"][FileIndex] 701 NewInfilePath = os.path.join(OutfilesDir, Infile) 702 703 shutil.copyfile(Infile, NewInfilePath) 704 705 # Copy fpocket output PDB files... 706 for FileIndex in range(0, len(OptionsInfo["FpocketInfilesInfo"]["InfilesNames"])): 707 Infile = OptionsInfo["FpocketInfilesInfo"]["InfilesNames"][FileIndex] 708 InfilePath = OptionsInfo["FpocketInfilesInfo"]["InfilesPaths"][FileIndex] 709 NewInfilePath = os.path.join(OutfilesDir, Infile) 710 711 shutil.copyfile(InfilePath, NewInfilePath) 712 713 def RetrieveInfilesInfo(): 714 """Retrieve information for input files.""" 715 716 InfilesInfo = {} 717 718 InfilesInfo["InfilesNames"] = [] 719 InfilesInfo["InfilesRoots"] = [] 720 InfilesInfo["ChainsAndLigandsInfo"] = [] 721 722 for Infile in OptionsInfo["InfilesNames"]: 723 FileDir, FileName, FileExt = MiscUtil.ParseFileName(Infile) 724 InfileRoot = FileName 725 726 ChainsAndLigandInfo = PyMOLUtil.GetChainsAndLigandsInfo(Infile, InfileRoot) 727 728 InfilesInfo["InfilesNames"].append(Infile) 729 InfilesInfo["InfilesRoots"].append(InfileRoot) 730 InfilesInfo["ChainsAndLigandsInfo"].append(ChainsAndLigandInfo) 731 732 OptionsInfo["InfilesInfo"] = InfilesInfo 733 734 def RetrieveRefFileInfo(): 735 """Retrieve information for ref file.""" 736 737 RefFileInfo = {} 738 if not OptionsInfo["Align"]: 739 OptionsInfo["RefFileInfo"] = RefFileInfo 740 return 741 742 RefFile = OptionsInfo["RefFileName"] 743 744 FileDir, FileName, FileExt = MiscUtil.ParseFileName(RefFile) 745 RefFileRoot = FileName 746 747 if re.match("^FirstInputFile$", OptionsInfo["AlignRefFile"], re.I): 748 ChainsAndLigandInfo = OptionsInfo["InfilesInfo"]["ChainsAndLigandsInfo"][0] 749 else: 750 MiscUtil.PrintInfo("\nRetrieving chain and ligand information for alignment reference file %s..." % RefFile) 751 ChainsAndLigandInfo = PyMOLUtil.GetChainsAndLigandsInfo(RefFile, RefFileRoot) 752 753 RefFileInfo["RefFileName"] = RefFile 754 RefFileInfo["RefFileRoot"] = RefFileRoot 755 RefFileInfo["PyMOLObjectName"] = "AlignRef_%s" % RefFileRoot 756 RefFileInfo["ChainsAndLigandsInfo"] = ChainsAndLigandInfo 757 758 OptionsInfo["RefFileInfo"] = RefFileInfo 759 760 def RetrieveFpocketResultFilesInfo(): 761 """Check and retrieve information for Fpocket result files.""" 762 763 FpocketInfilesInfo = {} 764 765 FpocketInfilesInfo["InfilesNames"] = [] 766 FpocketInfilesInfo["InfilesRoots"] = [] 767 FpocketInfilesInfo["InfilesPaths"] = [] 768 FpocketInfilesInfo["InfilesDirs"] = [] 769 770 FpocketInfilesInfo["InfilesPocketsDirs"] = [] 771 FpocketInfilesInfo["InfilesPocketsPDBFilesCount"] = [] 772 773 FpocketInfilesInfo["ChainsAndPocketsInfo"] = [] 774 775 for Infile in OptionsInfo["InfilesNames"]: 776 MiscUtil.PrintInfo("\nRetrieving Fpocket result file information for input file %s..." % Infile) 777 778 FileDir, FileName, FileExt = MiscUtil.ParseFileName(Infile) 779 InfileRoot = FileName 780 781 FpocketInfileDir = "%s_out" % InfileRoot 782 FpocketInfileRoot = "%s_out" % InfileRoot 783 FpocketInfileName = "%s.pdb" % FpocketInfileRoot 784 FpocketInfilePath = os.path.join(FpocketInfileDir, FpocketInfileName) 785 786 FpocketInfilePocketsDir = os.path.join(FpocketInfileDir, "pockets") 787 788 if not os.path.isdir(FpocketInfileDir): 789 MiscUtil.PrintError("Fpocket result file directory, %s, is missing for input PDB file, %s." % (FpocketInfileDir, Infile)) 790 791 if not os.path.isfile(FpocketInfilePath): 792 MiscUtil.PrintError("Fpocket result PDB file, %s, is missing for input PDB file, %s." % (FpocketInfilePath, Infile)) 793 794 if not os.path.isdir(FpocketInfilePocketsDir): 795 MiscUtil.PrintError("Fpocket pockets result file directory, %s, is missing for input PDB file, %s." % (FpocketInfilePocketsDir, Infile)) 796 797 PocketsPDBFiles = glob.glob(os.path.join(FpocketInfilePocketsDir, "pocket*_atm.pdb")) 798 PocketsPDBFilesCount = len(PocketsPDBFiles) 799 if PocketsPDBFilesCount == 0: 800 MiscUtil.PrintError("Fpocket pockets result files missing in directory, %s, for input PDB file, %s." % (FpocketInfilePocketsDir, Infile)) 801 802 # Retrieve chains and pockets... 803 ChainsAndPocketsInfo = GetFpocketChainsAndPocketsInfo(FpocketInfileRoot, FpocketInfilePath, FpocketInfileDir, FpocketInfilePocketsDir) 804 805 FpocketInfilesInfo["InfilesNames"].append(FpocketInfileName) 806 FpocketInfilesInfo["InfilesRoots"].append(FpocketInfileRoot) 807 FpocketInfilesInfo["InfilesPaths"].append(FpocketInfilePath) 808 FpocketInfilesInfo["InfilesDirs"].append(FpocketInfileDir) 809 810 FpocketInfilesInfo["InfilesPocketsDirs"].append(FpocketInfilePocketsDir) 811 FpocketInfilesInfo["InfilesPocketsPDBFilesCount"].append(PocketsPDBFilesCount) 812 813 FpocketInfilesInfo["ChainsAndPocketsInfo"].append(ChainsAndPocketsInfo) 814 815 MiscUtil.PrintInfo("PDB result file: %s..." % FpocketInfileName) 816 MiscUtil.PrintInfo("Total number of pockets: %s..." % ChainsAndPocketsInfo["NumOfPockets"]) 817 818 MiscUtil.PrintInfo("Pocket Chain IDs: %s" % " ".join(ChainsAndPocketsInfo["ChainIDs"])) 819 for ChainID in ChainsAndPocketsInfo["ChainIDs"]: 820 MiscUtil.PrintInfo("Pocket Chain ID: %s; NumOfPockets: %s; PocketIDs: %s" % (ChainID, len(ChainsAndPocketsInfo["PocketIDs"][ChainID]), " ".join(ChainsAndPocketsInfo["PocketIDs"][ChainID]))) 821 822 OptionsInfo["FpocketInfilesInfo"] = FpocketInfilesInfo 823 824 def GetFpocketChainsAndPocketsInfo(FpocketInfileRoot, FpocketInfilePath, FpocketInfileDir, FpocketInfilePocketsDir): 825 """Get chains and pockets information for Fpocket result files. """ 826 827 ChainsAndPocketsInfo = {} 828 ChainsAndPocketsInfo["ChainIDs"] = [] 829 ChainsAndPocketsInfo["PocketIDs"] = {} 830 ChainsAndPocketsInfo["PocketResNums"] = {} 831 832 ChainsAndPocketsInfo["DrugScore"] = {} 833 ChainsAndPocketsInfo["PocketScore"] = {} 834 ChainsAndPocketsInfo["HydrophobicityScore"] = {} 835 ChainsAndPocketsInfo["PolarityScore"] = {} 836 ChainsAndPocketsInfo["PocketVolume"] = {} 837 838 ChainsAndPocketsInfo["NumOfPockets"] = 0 839 840 # Retrieve chain IDs corresponding to main chain atoms... 841 ChainIDs = GetPolymerChainIDs(FpocketInfilePath, FpocketInfileRoot) 842 843 # Retrieve number of pockets and pocket IDs... 844 PocketIDs = GetPocketIDs(FpocketInfilePath, FpocketInfileRoot) 845 ChainsAndPocketsInfo["NumOfPockets"] = len(PocketIDs) 846 847 # Retrieve residue numbers for fpockets across the chains... 848 for PocketID in PocketIDs: 849 PocketAtomFile = os.path.join(FpocketInfilePocketsDir, "pocket%s_atm.pdb" % PocketID) 850 851 if not os.path.isfile(PocketAtomFile): 852 MiscUtil.PrintError("Fpocket result PDB file, %s, is missing for pocket ID, %s." % (PocketAtomFile, PocketID)) 853 854 # Retrieve pocket properites for a pocket across chains... 855 PocketScore, DrugScore, HydrophobicityScore, PolarityScore, PocketVolume = GetPocketProperties(PocketAtomFile) 856 857 MolName = "pocket%s_atm" % PocketID 858 pymol.cmd.load(PocketAtomFile, MolName) 859 SelectionCmd = "(%s)" % MolName 860 861 pymol.stored.FpocketInfo = [] 862 pymol.cmd.iterate(SelectionCmd, "pymol.stored.FpocketInfo.append([chain, resi, resn])") 863 pymol.cmd.delete(MolName) 864 865 for ChainID, ResNum, ResName in pymol.stored.FpocketInfo: 866 if ChainID not in ChainsAndPocketsInfo["ChainIDs"]: 867 ChainsAndPocketsInfo["PocketIDs"][ChainID] = [] 868 ChainsAndPocketsInfo["PocketResNums"][ChainID] = {} 869 870 ChainsAndPocketsInfo["DrugScore"][ChainID] = {} 871 ChainsAndPocketsInfo["PocketScore"][ChainID] = {} 872 ChainsAndPocketsInfo["HydrophobicityScore"][ChainID] = {} 873 ChainsAndPocketsInfo["PolarityScore"][ChainID] = {} 874 ChainsAndPocketsInfo["PocketVolume"][ChainID] = {} 875 876 ChainsAndPocketsInfo["ChainIDs"].append(ChainID) 877 878 if PocketID not in ChainsAndPocketsInfo["PocketIDs"][ChainID]: 879 ChainsAndPocketsInfo["PocketResNums"][ChainID][PocketID] = [] 880 ChainsAndPocketsInfo["PocketIDs"][ChainID].append(PocketID) 881 882 # Track pocket and drug score across chains... 883 ChainsAndPocketsInfo["DrugScore"][ChainID][PocketID] = DrugScore 884 ChainsAndPocketsInfo["PocketScore"][ChainID][PocketID] = PocketScore 885 ChainsAndPocketsInfo["HydrophobicityScore"][ChainID][PocketID] = HydrophobicityScore 886 ChainsAndPocketsInfo["PolarityScore"][ChainID][PocketID] = PolarityScore 887 ChainsAndPocketsInfo["PocketVolume"][ChainID][PocketID] = PocketVolume 888 889 890 if ResNum not in ChainsAndPocketsInfo["PocketResNums"][ChainID][PocketID]: 891 ChainsAndPocketsInfo["PocketResNums"][ChainID][PocketID].append(ResNum) 892 893 ChainsAndPocketsInfo["ChainIDs"] = sorted(ChainsAndPocketsInfo["ChainIDs"]) 894 895 return ChainsAndPocketsInfo 896 897 def GetPolymerChainIDs(Infile, MolName): 898 """Get chain IDs for main chain excluding hetero atoms. """ 899 900 pymol.cmd.load(Infile, MolName) 901 ChainIDs = PyMOLUtil.GetChains(MolName) 902 903 # Retrieve polymer chains... 904 SelectedChainIDs = [] 905 for ChainID in ChainIDs: 906 AtomsCount = pymol.cmd.count_atoms("(%s and (chain %s) and (polymer) and (not hetatm))" % (MolName, ChainID)) 907 if AtomsCount > 0: 908 SelectedChainIDs.append(ChainID) 909 910 pymol.cmd.delete(MolName) 911 912 return SelectedChainIDs 913 914 def GetPocketIDs(Infile, MolName): 915 """Get pocket IDs. """ 916 917 # Fpockets are annonated in PDB file as STP residue name and unique residue 918 # numbers... 919 pymol.cmd.load(Infile, MolName) 920 SelectionCmd = "(%s and (resn STP) and hetatm)" % MolName 921 922 pymol.stored.FpocketIDsInfo = [] 923 pymol.cmd.iterate(SelectionCmd, "pymol.stored.FpocketIDsInfo.append(resi)") 924 pymol.cmd.delete(MolName) 925 926 PocketIDs = [] 927 for PocketID in pymol.stored.FpocketIDsInfo: 928 if PocketID not in PocketIDs: 929 PocketIDs.append(PocketID) 930 931 return PocketIDs 932 933 def ProcessChainAndPocketIDs(): 934 """Process specified chain and pocket IDs for infiles.""" 935 936 OptionsInfo["FpocketInfilesInfo"]["SpecifiedChainsAndPocketsInfo"] = [] 937 938 for FileIndex in range(0, len(OptionsInfo["InfilesInfo"]["InfilesNames"])): 939 MiscUtil.PrintInfo("\nProcessing specified chain and Pocket IDs for input file %s..." % OptionsInfo["FpocketInfilesInfo"]["InfilesNames"][FileIndex]) 940 941 ChainsAndPocketsInfo = OptionsInfo["FpocketInfilesInfo"]["ChainsAndPocketsInfo"][FileIndex] 942 943 SpecifiedChainsAndPocketsInfo = ProcessChainsAndPocketsOptionsInfo(ChainsAndPocketsInfo) 944 OptionsInfo["FpocketInfilesInfo"]["SpecifiedChainsAndPocketsInfo"].append(SpecifiedChainsAndPocketsInfo) 945 946 CheckPresenceOfValidPocketIDs(ChainsAndPocketsInfo, SpecifiedChainsAndPocketsInfo) 947 948 def GetPocketProperties(PocketAtomFile): 949 """Get pocket properites from the pocket PDB file. """ 950 951 PocketScore, DrugScore, HydrophobicityScore, PolarityScore, PocketVolume = [None] * 5 952 953 PocketAtomFH = open(PocketAtomFile, "r") 954 if PocketAtomFH is None: 955 return (PocketScore, DrugScore, HydrophobicityScore, PolarityScore, PocketVolume) 956 957 for Line in PocketAtomFH: 958 Line = Line.rstrip() 959 if re.search("Pocket Score", Line, re.I): 960 LineWords = Line.split() 961 PocketScore = LineWords[-1] 962 elif re.search("Drug Score", Line, re.I): 963 LineWords = Line.split() 964 DrugScore = LineWords[-1] 965 elif re.search("Hydrophobicity Score", Line, re.I): 966 LineWords = Line.split() 967 HydrophobicityScore = LineWords[-1] 968 elif re.search("Polarity Score", Line, re.I): 969 LineWords = Line.split() 970 PolarityScore = LineWords[-1] 971 elif re.search("Pocket volume \(Monte Carlo\)", Line, re.I): 972 LineWords = Line.split() 973 PocketVolume = LineWords[-1] 974 975 if not re.match("^HEADER", Line, re.I): 976 break 977 978 PocketAtomFH.close() 979 980 return (PocketScore, DrugScore, HydrophobicityScore, PolarityScore, PocketVolume) 981 982 def ProcessChainsAndPocketsOptionsInfo(ChainsAndPocketsInfo): 983 """Process specified chain and pocket IDs using command line options.""" 984 985 ChainIDs = OptionsInfo["ChainIDs"] 986 FpocketMode = OptionsInfo["FpocketMode"] 987 FpocketIDs = OptionsInfo["FpocketIDs"] 988 989 SpecifiedChainsAndPocketsInfo = {} 990 SpecifiedChainsAndPocketsInfo["ChainIDs"] = [] 991 SpecifiedChainsAndPocketsInfo["PocketIDs"] = {} 992 993 ProcessChainsOptionInfo(ChainsAndPocketsInfo, SpecifiedChainsAndPocketsInfo) 994 ProcessPocketsOptionInfo(ChainsAndPocketsInfo, SpecifiedChainsAndPocketsInfo) 995 996 return SpecifiedChainsAndPocketsInfo 997 998 def ProcessChainsOptionInfo(ChainsAndPocketsInfo, SpecifiedChainsAndPocketsInfo): 999 """Process chain IDs""" 1000 1001 MiscUtil.PrintInfo("Processing chain IDs...") 1002 1003 ChainsOptionName = "-c, --chainIDs" 1004 ChainsOptionValue = OptionsInfo["ChainIDs"] 1005 1006 if re.match("^All$", ChainsOptionValue, re.I): 1007 SpecifiedChainsAndPocketsInfo["ChainIDs"] = ChainsAndPocketsInfo["ChainIDs"] 1008 return 1009 elif re.match("^(First|Auto)$", ChainsOptionValue, re.I): 1010 FirstChainID = ChainsAndPocketsInfo["ChainIDs"][0] if (len(ChainsAndPocketsInfo["ChainIDs"])) else None 1011 if FirstChainID is not None: 1012 SpecifiedChainsAndPocketsInfo["ChainIDs"].append(FirstChainID) 1013 return 1014 1015 ChainIDs = re.sub(" ", "", ChainsOptionValue) 1016 if not ChainIDs: 1017 MiscUtil.PrintError("No valid value specified using \"%s\" option." % ChainsOptionName) 1018 1019 ChainIDsList = ChainsAndPocketsInfo["ChainIDs"] 1020 SpecifiedChainIDsList = [] 1021 1022 ChainIDsWords = ChainIDs.split(",") 1023 for ChainID in ChainIDsWords: 1024 if not ChainID in ChainIDsList: 1025 MiscUtil.PrintWarning("The chain ID, %s, specified using \"%s\" option is not valid. It'll be ignored. Valid chain IDs: %s" % (ChainID, ChainsOptionName, ", ".join(ChainIDsList))) 1026 continue 1027 if ChainID in SpecifiedChainIDsList: 1028 MiscUtil.PrintWarning("The chain ID, %s, has already been specified using \"%s\" option. It'll be ignored." % (ChainID, ChainsOptionName)) 1029 continue 1030 SpecifiedChainIDsList.append(ChainID) 1031 1032 if not len(SpecifiedChainIDsList): 1033 MiscUtil.PrintError("No valid chain IDs \"%s\" specified using \"%s\" option." % (ChainsOptionValue, ChainsOptionName)) 1034 1035 SpecifiedChainsAndPocketsInfo["ChainIDs"] = SpecifiedChainIDsList 1036 1037 def ProcessPocketsOptionInfo(ChainsAndPocketsInfo, SpecifiedChainsAndPocketsInfo): 1038 """Process pocket IDs""" 1039 1040 MiscUtil.PrintInfo("Processing pocket IDs...") 1041 1042 PocketsModeOptionName = "-f, --fpocketMode" 1043 PocketsModeOptionValue = OptionsInfo["FpocketMode"] 1044 1045 PocketsIDsOptionName = "--fpocketIDs" 1046 PocketsIDsOptionValue = OptionsInfo["FpocketIDs"] 1047 1048 # Intialize pocketIDs... 1049 for ChainID in SpecifiedChainsAndPocketsInfo["ChainIDs"]: 1050 SpecifiedChainsAndPocketsInfo["PocketIDs"][ChainID] = [] 1051 1052 if re.match("^All$", PocketsModeOptionValue, re.I): 1053 for ChainID in SpecifiedChainsAndPocketsInfo["ChainIDs"]: 1054 SpecifiedChainsAndPocketsInfo["PocketIDs"][ChainID] = ChainsAndPocketsInfo["PocketIDs"][ChainID] 1055 return 1056 elif re.match("^TopN$", PocketsModeOptionValue, re.I): 1057 # Setup TopN pocket IDs for each chain... 1058 TopNPocketsCount = int(PocketsIDsOptionValue[0]) 1059 for ChainID in SpecifiedChainsAndPocketsInfo["ChainIDs"]: 1060 TopNPocketsIDs = [] 1061 NumOfPockets = len(ChainsAndPocketsInfo["PocketIDs"][ChainID]) 1062 1063 if NumOfPockets: 1064 if TopNPocketsCount > NumOfPockets: 1065 TopNPocketsIDs = ChainsAndPocketsInfo["PocketIDs"][ChainID] 1066 else: 1067 TopNPocketsIDs = ChainsAndPocketsInfo["PocketIDs"][ChainID][0 : TopNPocketsCount] 1068 1069 SpecifiedChainsAndPocketsInfo["PocketIDs"][ChainID] = TopNPocketsIDs 1070 return 1071 1072 # Process explicitly specified pocket IDs... 1073 PocketIDsWords = PocketsIDsOptionValue 1074 if not len(PocketIDsWords): 1075 MiscUtil.PrintError("No valid value specified using \"%s\" option." % PocketsIDsOptionName) 1076 1077 for ChainID in SpecifiedChainsAndPocketsInfo["ChainIDs"]: 1078 PocketIDsList = ChainsAndPocketsInfo["PocketIDs"][ChainID] 1079 SpecifiedPocketIDsList = [] 1080 1081 for PocketID in PocketIDsWords: 1082 if not PocketID in PocketIDsList: 1083 MiscUtil.PrintWarning("The pocket ID, %s, specified using \"%s\" option is not valid for chain, %s. It'll be ignored. Valid pocket IDs are listed earlier." % (PocketID, PocketsIDsOptionName, ChainID)) 1084 continue 1085 1086 if PocketID in SpecifiedPocketIDsList: 1087 MiscUtil.PrintWarning("The pocket ID, %s, has already been specified using \"%s\" option. It'll be ignored." % (PocketID, PocketsIDsOptionName)) 1088 continue 1089 1090 SpecifiedPocketIDsList.append(PocketID) 1091 1092 if not len(SpecifiedPocketIDsList): 1093 MiscUtil.PrintWarning("No valid pocket IDs \"%s\" specified using \"%s\" option for chain ID, %s." % (PocketsIDsOptionValue, PocketsIDsOptionName, ChainID)) 1094 1095 SpecifiedChainsAndPocketsInfo["PocketIDs"][ChainID] = SpecifiedPocketIDsList 1096 1097 def CheckPresenceOfValidPocketIDs(ChainsAndPocketsInfo, SpecifiedChainsAndPocketsInfo): 1098 """Check presence of valid pocket IDs.""" 1099 1100 MiscUtil.PrintInfo("\nSpecified chain IDs: %s" % (", ".join(SpecifiedChainsAndPocketsInfo["ChainIDs"]))) 1101 1102 for ChainID in SpecifiedChainsAndPocketsInfo["ChainIDs"]: 1103 if len (SpecifiedChainsAndPocketsInfo["PocketIDs"][ChainID]): 1104 MiscUtil.PrintInfo("Chain ID: %s; Specified PocketIDs: %s" % (ChainID, ", ".join(SpecifiedChainsAndPocketsInfo["PocketIDs"][ChainID]))) 1105 else: 1106 MiscUtil.PrintInfo("Chain IDs: %s; Specified PocketIDs: None" % (ChainID)) 1107 MiscUtil.PrintWarning("No valid pocket IDs found for chain ID, %s. PyMOL groups and objects related to fpockets won't be created." % (ChainID)) 1108 1109 def RetrieveFirstChainID(FileIndex, FpocketComplexMode): 1110 """Get first chain ID.""" 1111 1112 FirstChainID = None 1113 if FpocketComplexMode: 1114 ChainsAndPocketsInfo = OptionsInfo["FpocketInfilesInfo"]["ChainsAndPocketsInfo"][FileIndex] 1115 if len(ChainsAndPocketsInfo["ChainIDs"]): 1116 FirstChainID = ChainsAndPocketsInfo["ChainIDs"][0] 1117 else: 1118 ChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["ChainsAndLigandsInfo"][FileIndex] 1119 if len(ChainsAndLigandsInfo["ChainIDs"]): 1120 FirstChainID = ChainsAndLigandsInfo["ChainIDs"][0] 1121 1122 return FirstChainID 1123 1124 def ProcessSurfaceAtomTypesColors(): 1125 """Process surface atom types colors. """ 1126 1127 AtomTypesColorNamesInfo = PyMOLUtil.ProcessSurfaceAtomTypesColorsOptionsInfo("--surfaceAtomTypesColors", OptionsInfo["SurfaceAtomTypesColors"]) 1128 OptionsInfo["AtomTypesColorNames"] = AtomTypesColorNamesInfo 1129 1130 def CheckAndSetupOutfilesDir(): 1131 """Check and setup a directory for output files used by PyMOL.""" 1132 1133 Outfile = Options["--outfile"] 1134 OutfilesDir = Options["--outfilesDir"] 1135 1136 FileDir, FileName, FileExt = MiscUtil.ParseFileName(Outfile) 1137 if re.match("^auto$", OutfilesDir, re.I): 1138 OutfilesDir = "%s_out_PyMOL" % FileName 1139 1140 if os.path.isdir(OutfilesDir): 1141 if not OptionsInfo["Overwrite"]: 1142 MiscUtil.PrintError("The output directory, %s, already exists. Use option \"--ov\" or \"--overwrite\" and try again." % OutfilesDir) 1143 MiscUtil.PrintInfo("Using existing outout dir %s..." % OutfilesDir) 1144 else: 1145 MiscUtil.PrintInfo("Creating new output dir %s..." % OutfilesDir) 1146 os.mkdir(OutfilesDir) 1147 1148 OptionsInfo["Outfile"] = Outfile 1149 OptionsInfo["OutfilesDir"] = OutfilesDir 1150 1151 OptionsInfo["PMLOutfile"] = Outfile 1152 OptionsInfo["PMLOutfilePath"] = os.path.join(OutfilesDir, Outfile) 1153 1154 def ProcessOptions(): 1155 """Process and validate command line arguments and options""" 1156 1157 MiscUtil.PrintInfo("Processing options...") 1158 1159 # Validate options... 1160 ValidateOptions() 1161 1162 OptionsInfo["Align"] = True if re.match("^Yes$", Options["--align"], re.I) else False 1163 OptionsInfo["AlignMethod"] = Options["--alignMethod"].lower() 1164 OptionsInfo["AlignMode"] = Options["--alignMode"] 1165 1166 OptionsInfo["FpocketPropertiesAppend"] = True if re.match("^Yes$", Options["--fpocketPropertiesAppend"], re.I) else False 1167 1168 OptionsInfo["Infiles"] = Options["--infiles"] 1169 OptionsInfo["InfilesNames"] = Options["--infileNames"] 1170 1171 OptionsInfo["AlignRefFile"] = Options["--alignRefFile"] 1172 if re.match("^FirstInputFile$", Options["--alignRefFile"], re.I): 1173 OptionsInfo["RefFileName"] = OptionsInfo["InfilesNames"][0] 1174 else: 1175 OptionsInfo["RefFileName"] = Options["--alignRefFile"] 1176 1177 OptionsInfo["ChainIDs"] = Options["--chainIDs"] 1178 1179 OptionsInfo["FpocketMode"] = Options["--fpocketMode"] 1180 OptionsInfo["FpocketIDs"] = Options["--fpocketIDsList"] 1181 1182 OptionsInfo["Overwrite"] = Options["--overwrite"] 1183 1184 OptionsInfo["LabelFontID"] = int(Options["--labelFontID"]) 1185 1186 OptionsInfo["PocketColorByPocketNum"] = True if re.match("^Yes$", Options["--pocketColorByPocketNum"], re.I) else False 1187 OptionsInfo["PocketLabel"] = True if re.match("^Yes$", Options["--pocketLabel"], re.I) else False 1188 OptionsInfo["PocketLabelType"] = Options["--pocketLabelType"] 1189 OptionsInfo["ThreeLetterPocketLabelType"] = True if re.match("^ThreeLetter$", Options["--pocketLabelType"], re.I) else False 1190 1191 OptionsInfo["PocketNumOneColor"] = "gray80" 1192 1193 OptionsInfo["PocketSurface"] = True if re.match("^Yes$", Options["--pocketSurface"], re.I) else False 1194 OptionsInfo["SurfaceChain"] = True if re.match("^Yes$", Options["--surfaceChain"], re.I) else False 1195 1196 OptionsInfo["SurfaceColor"] = Options["--surfaceColor"] 1197 OptionsInfo["SurfaceColorPalette"] = Options["--surfaceColorPalette"] 1198 OptionsInfo["SurfaceAtomTypesColors"] = Options["--surfaceAtomTypesColors"] 1199 ProcessSurfaceAtomTypesColors() 1200 1201 OptionsInfo["SphereScale"] = float(Options["--sphereScale"]) 1202 OptionsInfo["SphereTransparency"] = float(Options["--sphereTransparency"]) 1203 1204 OptionsInfo["SurfaceTransparency"] = float(Options["--surfaceTransparency"]) 1205 1206 # Check and setup outfile dir before processing input files... 1207 CheckAndSetupOutfilesDir() 1208 1209 RetrieveInfilesInfo() 1210 RetrieveRefFileInfo() 1211 RetrieveFpocketResultFilesInfo() 1212 1213 # Process specified chain and pocket IDs.. 1214 ProcessChainAndPocketIDs() 1215 1216 def RetrieveOptions(): 1217 """Retrieve command line arguments and options""" 1218 1219 # Get options... 1220 global Options 1221 Options = docopt(_docoptUsage_) 1222 1223 # Set current working directory to the specified directory... 1224 WorkingDir = Options["--workingdir"] 1225 if WorkingDir: 1226 os.chdir(WorkingDir) 1227 1228 # Handle examples option... 1229 if "--examples" in Options and Options["--examples"]: 1230 MiscUtil.PrintInfo(MiscUtil.GetExamplesTextFromDocOptText(__doc__)) 1231 sys.exit(0) 1232 1233 def ValidateOptions(): 1234 """Validate option values""" 1235 1236 MiscUtil.ValidateOptionTextValue("--align", Options["--align"], "yes no") 1237 MiscUtil.ValidateOptionTextValue("--alignMethod", Options["--alignMethod"], "align cealign super") 1238 MiscUtil.ValidateOptionTextValue("--alignMode", Options["--alignMode"], "FirstChain Complex") 1239 1240 MiscUtil.ValidateOptionTextValue("--fpocketPropertiesAppend", Options["--fpocketPropertiesAppend"], "yes no") 1241 1242 # Expand infiles to handle presence of multiple input files... 1243 InfileNames = MiscUtil.ExpandFileNames(Options["--infiles"], ",") 1244 if not len(InfileNames): 1245 MiscUtil.PrintError("No input files specified for \"-i, --infiles\" option") 1246 1247 # Validate file extensions... 1248 for Infile in InfileNames: 1249 MiscUtil.ValidateOptionFilePath("-i, --infiles", Infile) 1250 MiscUtil.ValidateOptionFileExt("-i, --infiles", Infile, "pdb") 1251 MiscUtil.ValidateOptionsDistinctFileNames("-i, --infiles", Infile, "-o, --outfile", Options["--outfile"]) 1252 Options["--infileNames"] = InfileNames 1253 1254 MiscUtil.ValidateOptionFileExt("-o, --outfile", Options["--outfile"], "pml") 1255 1256 if re.match("^yes$", Options["--align"], re.I): 1257 if not re.match("^FirstInputFile$", Options["--alignRefFile"], re.I): 1258 AlignRefFile = Options["--alignRefFile"] 1259 MiscUtil.ValidateOptionFilePath("--alignRefFile", AlignRefFile) 1260 MiscUtil.ValidateOptionFileExt("--alignRefFile", AlignRefFile, "pdb") 1261 MiscUtil.ValidateOptionsDistinctFileNames("--AlignRefFile", AlignRefFile, "-o, --outfile", Options["--outfile"]) 1262 1263 MiscUtil.ValidateOptionTextValue("--fpocketMode", Options["--fpocketMode"], "All TopN Specify") 1264 1265 FpocketIDsList = [] 1266 if re.match("^(TopN|Specify)$", Options["--fpocketMode"], re.I): 1267 if Options["--fpocketIDs"] is None: 1268 MiscUtil.PrintError("No value specified for \"--fpocketIDs\" during \"%s\" of \"-f, --fpocketMode\" option." % (Options["--fpocketMode"])) 1269 1270 FpocketIDs = re.sub(" ", "", Options["--fpocketIDs"]) 1271 if not FpocketIDs: 1272 MiscUtil.PrintError("No valid value specified for \"--fpocketIDs\" during \"%s\" of \"-f, --fpocketMode\" option." % (Options["--fpocketMode"])) 1273 FpocketIDsWords = FpocketIDs.split(",") 1274 if len(FpocketIDsWords) == 0: 1275 MiscUtil.PrintError("No valid value specified for \"--fpocketIDs\" during \"%s\" of \"-f, --fpocketMode\" option." % (Options["--fpocketMode"])) 1276 1277 if re.match("^TopN$", Options["--fpocketMode"], re.I): 1278 if len(FpocketIDsWords) > 1: 1279 MiscUtil.PrintError("Number of values specified for \"--fpocketIDs\" must be 1 during \"TopN\" of \"-f, --fpocketMode\" option.") 1280 1281 for FpocketID in FpocketIDsWords: 1282 MiscUtil.ValidateOptionIntegerValue("--fpocketIDs", FpocketID, {">": 0}) 1283 FpocketIDsList.append(FpocketID) 1284 1285 Options["--fpocketIDsList"] = FpocketIDsList 1286 1287 MiscUtil.ValidateOptionIntegerValue("--labelFontID", Options["--labelFontID"], {}) 1288 1289 MiscUtil.ValidateOptionTextValue("--pocketColorByPocketNum", Options["--pocketColorByPocketNum"], "yes no") 1290 MiscUtil.ValidateOptionTextValue("--pocketLabel", Options["--pocketLabel"], "yes no") 1291 MiscUtil.ValidateOptionTextValue("--pocketLabelType", Options["--pocketLabelType"], "OneLetter ThreeLetter") 1292 1293 MiscUtil.ValidateOptionTextValue("--pocketSurface", Options["--pocketSurface"], "yes no") 1294 MiscUtil.ValidateOptionTextValue("--surfaceChain", Options["--surfaceChain"], "yes no") 1295 1296 MiscUtil.ValidateOptionFloatValue("--sphereScale", Options["--sphereScale"], {">": 0.0}) 1297 MiscUtil.ValidateOptionFloatValue("--sphereTransparency", Options["--sphereTransparency"], {">=": 0.0, "<=": 1.0}) 1298 1299 MiscUtil.ValidateOptionTextValue("--surfaceColorPalette", Options["--surfaceColorPalette"], "RedToWhite WhiteToGreen") 1300 MiscUtil.ValidateOptionFloatValue("--surfaceTransparency", Options["--surfaceTransparency"], {">=": 0.0, "<=": 1.0}) 1301 1302 # Setup a usage string for docopt... 1303 _docoptUsage_ = """ 1304 PyMOLVisualizeFpockets.py - Visualize fpockets for macromolecules. 1305 1306 Usage: 1307 PyMOLVisualizeFpockets.py [--align <yes or no>] [--alignMethod <align, cealign, super>] 1308 [--alignMode <FirstChain or Complex>] [--alignRefFile <filename>] 1309 [--chainIDs <First, All or ID1,ID2...>] [--fpocketMode <All, TopN, or Specify>] 1310 [--fpocketIDs <Value or Value1,Value2...>] [--fpocketPropertiesAppend <yes or no>] 1311 [--labelFontID <number>] [--outfilesDir <outfilesDir>] [--pocketColorByPocketNum <yes or no>] 1312 [--pocketLabel <yes or no>] [--pocketLabelType <OneLetter or ThreeLetter>] 1313 [--pocketSurface <yes or no>] [--sphereScale <number>] [--sphereTransparency <number>] 1314 [--surfaceChain <yes or no>] [--surfaceAtomTypesColors <ColorType,ColorSpec,...>] 1315 [--surfaceColor <ColorName>] [--surfaceColorPalette <RedToWhite or WhiteToGreen>] 1316 [--surfaceTransparency <number>] [--overwrite] [-w <dir>] -i <infile1,infile2,infile3...> -o <outfile> 1317 PyMOLVisualizeFpockets.py -h | --help | -e | --examples 1318 1319 Description: 1320 Generate a PyMOL visualization file for visualizing pockets in macromolecules 1321 detected by an open source package named Fpocket [ Ref 166 ]. 1322 1323 The results of Fpocket calculations must be available in the current directory 1324 for all input files. A complete set of expected results is shown below: 1325 1326 Dir: <PDBFileRoot>_out 1327 <PDBFileRoot>_out.pdb 1328 ... .. ... 1329 Dir: pockets 1330 <PDBFileRoot><PocketID>_atm.pdb 1331 ... .. ... 1332 1333 The supported input file format is: PDB (.pdb) 1334 1335 The supported output file formats is: PyMOL script file (.pml) 1336 1337 The following directory and files are created for the visualization of pockets 1338 detected by Fpocket: 1339 1340 Dir: <OutFileRoot>_out_PyMOL or <OutfilesDir> 1341 <OutfileRoot>.pml 1342 <PDBFileRoot>.pdb 1343 <PDBFileRoot>_out.pdb 1344 1345 You may visualize pockets in PyMOL by loading <OutfileRoot>.pml from 1346 <OutfileRoot>_out_PyMOL or <OutfilesDir> directory. 1347 1348 A variety of PyMOL groups and objects may be created for visualization of 1349 fpockets in macromolecules. These groups and objects correspond to complexes, 1350 chains, fpockets, and surfaces. A complete hierarchy of all possible PyMOL 1351 groups and objects is shown below: 1352 1353 <PDBFileRoot> 1354 .Complex 1355 .Initial_PDB 1356 .Fpocket_PDB 1357 .Chain<ID> 1358 .Complex 1359 .Complex 1360 .Chain 1361 .Chain 1362 .Surface 1363 .Surface 1364 .Hydrophobicity 1365 .Hydrophobicity_Charge 1366 .FPocket<ID> 1367 .FPocket 1368 .Residues 1369 .Surface 1370 .Surface 1371 .Hydrophobicity 1372 .Hydrophobicity_Charge 1373 .Chain<ID> 1374 ... ... ... 1375 .FPocket<ID> 1376 ... ... ... 1377 .FPocket<ID> 1378 ... ... ... 1379 .Chain<ID> 1380 ... ... ... 1381 <PDBFileRoot> 1382 .Complex 1383 ... ... ... 1384 .Chain<ID> 1385 ... ... ... 1386 .FPocket<ID> 1387 ... ... ... 1388 .FPocket<ID> 1389 ... ... ... 1390 .Chain<ID> 1391 ... ... ... 1392 1393 Options: 1394 -a, --align <yes or no> [default: no] 1395 Align input files to a reference file before visualization. 1396 --alignMethod <align, cealign, super> [default: super] 1397 Alignment methodology to use for aligning input files to a 1398 reference file. 1399 --alignMode <FirstChain or Complex> [default: FirstChain] 1400 Portion of input and reference files to use for spatial alignment of 1401 input files against reference file. Possible values: FirstChain or 1402 Complex. 1403 1404 The FirstChain mode allows alignment of the first chain in each input 1405 file to the first chain in the reference file along with moving the rest 1406 of the complex to coordinate space of the reference file. The complete 1407 complex in each input file is aligned to the complete complex in reference 1408 file for the Complex mode. 1409 --alignRefFile <filename> [default: FirstInputFile] 1410 Reference input file name. The default is to use the first input file 1411 name specified using '-i, --infiles' option. 1412 -c, --chainIDs <First, All or ID1,ID2...> [default: First] 1413 List of chain IDs to use for visualizing fpockets in macromolecules. Possible 1414 values: First, All, or a comma delimited list of chain IDs. The default is to 1415 use the chain ID for the first chain in each input file. 1416 -e, --examples 1417 Print examples. 1418 -f, --fpocketMode <All, TopN, or Specify> [default: All] 1419 Fpockets specification mode for visualizing fpockets across chains in 1420 macromolecules. Possible values: All, TopN, or specify. By default, all 1421 available fpockets are visualized across specified chains. 1422 1423 The fpocket IDs must be specified using '--fpocketIDs' option for 'TopN' 1424 and 'Specifiy' value of '--fpocketMode '. 1425 --fpocketIDs <Value or Value1,Value2...> 1426 List of Fpocket IDs for visualizing fpockets across chains. This value is 1427 dependent on the value of '--fpocketMode'. The possible values are 1428 either a number or a comma delimited list of number for 'TopN' and 1429 'Specify' value '--fpocketMode' option. For example: 1430 1431 This option is ignored during 'All' value of '--fpocketMode' option. 1432 --fpocketPropertiesAppend <yes or no> [default: yes] 1433 Append fpocket properties to names of PyMOL fpocket groups and 1434 objects. The following properties are appended to the names of PyMOL 1435 groups using their abbreviations and values: PocketScore - S; DrugScore - D; 1436 PocketVolume - V; HydrophobicityScore - H; PolarityScore - P. 1437 For example: 1438 1439 Fpocket1_S0p50_D0p00_V638p81_Hneg6p67_P11p00.Fpocket 1440 -h, --help 1441 Print this help message. 1442 -i, --infiles <infile1,infile2,infile3...> 1443 Input PDB file names. The current directory must contain the results from 1444 Fpocket calculations for all the input PDB files. 1445 --labelFontID <number> [default: 7] 1446 Font ID for drawing labels. Default: 7 (Sans Bold). Valid values: 5 to 16. 1447 The specified value must be a valid PyMOL font ID. No validation is 1448 performed. The complete lists of valid font IDs is available at: 1449 pymolwiki.org/index.php/Label_font_id. Examples: 5 - Sans; 1450 7 - Sans Bold; 9 - Serif; 10 - Serif Bold. 1451 -o, --outfile <outfile> 1452 PML output file name for visualizing fpockets. The PML outfile is created 1453 in a new output directory named <OutfileRoot>_out_PyMOL. In addition, the 1454 output directory contains all appropriate PDB files generated by Fpocket for 1455 visualization of fpockets in PyMOL. 1456 --outfilesDir <outfilesDir> [default: auto] 1457 Output files directory name. Default: <OutfileRoot>_out_PyMOL. 1458 --pocketColorByPocketNum <yes or no> [default: yes] 1459 Color fpocket residues and residue labels by pocket number. Otherwise, 1460 the pocket residues are colored by element names using default PyMOL 1461 color scheme. No color is set for residue labels. 1462 --pocketLabel <yes or no> [default: yes] 1463 Display residue labels on fpocket residues. The residue number is always 1464 appended to residue label. You may specify a one or thee letter residue 1465 labels using '--pocketLabelType' option. 1466 --pocketLabelType <OneLetter or ThreeLetter> [default: OneLetter] 1467 Display one or three letter residue labels on fpocket residues 1468 --pocketSurface <yes or no> [default: yes] 1469 Surfaces around fpocket residues colored by hydrophobicity alone and 1470 both hydrophobicity and charge. The hydrophobicity surface is colored 1471 at residue level using Eisenberg hydrophobicity scale for residues and color 1472 gradient specified by '--surfaceColorPalette' option. The hydrophobicity and 1473 charge surface is colored at atom level using colors specified for 1474 groups of atoms by '--surfaceAtomTypesColors' option. This scheme allows 1475 simultaneous mapping of hyrophobicity and charge values on the surfaces. 1476 1477 In addition, generic surfaces colored by '--surfaceColor' are always created 1478 for pockets. 1479 --sphereScale <number> [default: 0.4] 1480 Scaling factor for spheres used to display fpocket alpha spheres. 1481 --sphereTransparency <number> [default: 0.25] 1482 Transparency for spheres used to display fpocket alpha spheres. 1483 --surfaceChain <yes or no> [default: yes] 1484 Surfaces around individual chain colored by hydrophobicity alone and 1485 both hydrophobicity and charge. The hydrophobicity surface is colored 1486 at residue level using Eisenberg hydrophobicity scale for residues and color 1487 gradient specified by '--surfaceColorPalette' option. The hydrophobicity and 1488 charge surface is colored at atom level using colors specified for 1489 groups of atoms by '--surfaceAtomTypesColors' option. This scheme allows 1490 simultaneous mapping of hyrophobicity and charge values on the surfaces. 1491 1492 In addition, generic surfaces colored by '--surfaceColor' are always created 1493 for chains. 1494 --surfaceAtomTypesColors <ColorType,ColorSpec,...> [default: auto] 1495 Atom colors for generating surfaces colored by hyrophobicity and charge 1496 around chains and pockets in proteins. It's a pairwise comma delimited list 1497 of atom color type and color specification for groups of atoms. 1498 1499 The default values for color types along wth color specifications 1500 are shown below: 1501 1502 HydrophobicAtomsColor, yellow, 1503 NegativelyChargedAtomsColor, red, 1504 PositivelyChargedAtomsColor, blue, 1505 OtherAtomsColor, gray90 1506 1507 The color names must be valid PyMOL names. 1508 1509 The color values may also be specified as space delimited RGB triplets: 1510 1511 HydrophobicAtomsColor, 0.95 0.78 0.0, 1512 NegativelyChargedAtomsColor, 1.0 0.4 0.4, 1513 PositivelyChargedAtomsColor, 0.2 0.5 0.8, 1514 OtherAtomsColor, 0.95 0.95 0.95 1515 1516 --surfaceColor <ColorName> [default: lightblue] 1517 Color name for surfaces around chains and pockets. This color is not used 1518 for surfaces colored by hydrophobicity and charge. The color name must be 1519 a valid PyMOL name. 1520 --surfaceColorPalette <RedToWhite or WhiteToGreen> [default: RedToWhite] 1521 Color palette for hydrophobic surfaces around chains and pockets in proteins. 1522 Possible values: RedToWhite or WhiteToGreen from most hydrophobic amino 1523 acid to least hydrophobic. The colors values for amino acids are taken from 1524 color_h script available as part of the Script Library at PyMOL Wiki. 1525 --surfaceTransparency <number> [default: 0.25] 1526 Surface transparency for molecular surfaces. 1527 --overwrite 1528 Overwrite existing files. 1529 -w, --workingdir <dir> 1530 Location of working directory which defaults to the current directory. 1531 1532 Examples: 1533 To visualize all fpockets available in a directory <PDBRoot>_out for the first 1534 chain, along pocket residues and surfaces, in a PDB file, and generate a PML 1535 file in a new directory <PDBRoot>_out_pymol, type: 1536 1537 % PyMOLVisualizeFpockets.py -i Sample5.pdb -o Sample5.pml 1538 1539 To rerun the first example without displaying pocket residue labels, 1540 coloring pockets by element type, and write out a PML file, type: 1541 1542 % PyMOLVisualizeFpockets.py --pocketColorByPocketNum no 1543 --pocketLabel no -i Sample5.pdb -o Sample5.pml 1544 1545 To rerun the first example to visualize only top 5 fpockets and write out a 1546 PML file, type: 1547 1548 % PyMOLVisualizeFpockets.py -f TopN --fpocketIDs 5 -i Sample5.pdb 1549 -o Sample5.pml 1550 1551 To rerun the first example to visualize a specific set of fpockets and write 1552 out a PML file, type: 1553 1554 % PyMOLVisualizeFpockets.py -f Specify --fpocketIDs "1,2,3" -i Sample5.pdb 1555 -o Sample5.pml 1556 1557 To rerun the first example to visualize all fpockets across all chains and write 1558 out a PML file, type: 1559 1560 % PyMOLVisualizeFpockets.py -c All -f All -i Sample5.pdb -o Sample5.pml 1561 1562 To rerun the first example without displaying hydrophobic and charge surfaces 1563 around chain and pockets and and write out a PML file, type: 1564 1565 % PyMOLVisualizeFpockets.py --surfaceChain no --pocketSurface no 1566 -i Sample5.pdb -o Sample5.pml 1567 1568 To visualize top 5 fpockets available in a directories <PDBRoot>_out for the 1569 first chain, along pocket residues and surfaces, in PDB files, aligning first 1570 fchain in each input file to the first chain in first input file, and generate a 1571 PML file in a new directory <PDBRoot>_out_pymol, type: 1572 1573 % PyMOLVisualizeFpockets.py -f TopN --fpocketIDs 5 --align yes 1574 -i "Sample5.pdb,Sample6.pdb" -o Sample5Aligned.pml 1575 1576 To visualize top 5 fpockets available in a directories <PDBRoot>_out for the 1577 first chain, along pocket residues and surfaces, in PDB files, aligning first 1578 chain in each input file to the first chain in first chain in a specified PDB 1579 file using a specified alignment method,, and generate a PML file in a new 1580 directory <PDBRoot>_out_pymol, type: 1581 1582 % PyMOLVisualizeFpockets.py -f TopN --fpocketIDs 5 --align yes 1583 --alignMode FirstChain --alignRefFile Sample6.pdb --alignMethod super 1584 -i "Sample5.pdb,Sample6.pdb" -o Sample5Aligned.pml 1585 1586 Author: 1587 Manish Sud 1588 1589 Collaborators: 1590 Joann Prescott-Roy and Pat Walters 1591 1592 See also: 1593 DownloadPDBFiles.pl, PyMOLVisualizeCavities.py, 1594 PyMOLVisualizeCryoEMDensity.py, PyMOLVisualizeElectronDensity.py, 1595 PyMOLVisualizeInterfaces.py, PyMOLVisualizeMacromolecules.py, 1596 PyMOLVisualizeSurfaceAndBuriedResidues.py 1597 1598 Copyright: 1599 Copyright (C) 2025 Manish Sud. All rights reserved. 1600 1601 The functionality available in this script is implemented using PyMOL, a 1602 molecular visualization system on an open source foundation originally 1603 developed by Warren DeLano. 1604 1605 This file is part of MayaChemTools. 1606 1607 MayaChemTools is free software; you can redistribute it and/or modify it under 1608 the terms of the GNU Lesser General Public License as published by the Free 1609 Software Foundation; either version 3 of the License, or (at your option) any 1610 later version. 1611 1612 """ 1613 1614 if __name__ == "__main__": 1615 main()