1 #!/bin/env python 2 # 3 # File: PyMOLVisualizeCavities.py 4 # Author: Manish Sud <msud@san.rr.com> 5 # 6 # Copyright (C) 2024 Manish Sud. All rights reserved. 7 # 8 # The functionality available in this script is implemented using PyMOL, a 9 # molecular visualization system on an open source foundation originally 10 # developed by Warren DeLano. 11 # 12 # This file is part of MayaChemTools. 13 # 14 # MayaChemTools is free software; you can redistribute it and/or modify it under 15 # the terms of the GNU Lesser General Public License as published by the Free 16 # Software Foundation; either version 3 of the License, or (at your option) any 17 # later version. 18 # 19 # MayaChemTools is distributed in the hope that it will be useful, but without 20 # any warranty; without even the implied warranty of merchantability of fitness 21 # for a particular purpose. See the GNU Lesser General Public License for more 22 # details. 23 # 24 # You should have received a copy of the GNU Lesser General Public License 25 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or 26 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330, 27 # Boston, MA, 02111-1307, USA. 28 # 29 30 from __future__ import print_function 31 32 # Add local python path to the global path and import standard library modules... 33 import os 34 import sys; sys.path.insert(0, os.path.join(os.path.dirname(sys.argv[0]), "..", "lib", "Python")) 35 import time 36 import re 37 38 # PyMOL imports... 39 try: 40 import pymol 41 # Finish launching PyMOL in a command line mode for batch processing (-c) 42 # along with the following options: disable loading of pymolrc and plugins (-k); 43 # suppress start up messages (-q) 44 pymol.finish_launching(['pymol', '-ckq']) 45 except ImportError as ErrMsg: 46 sys.stderr.write("\nFailed to import PyMOL module/package: %s\n" % ErrMsg) 47 sys.stderr.write("Check/update your PyMOL environment and try again.\n\n") 48 sys.exit(1) 49 50 # MayaChemTools imports... 51 try: 52 from docopt import docopt 53 import MiscUtil 54 import PyMOLUtil 55 except ImportError as ErrMsg: 56 sys.stderr.write("\nFailed to import MayaChemTools module/package: %s\n" % ErrMsg) 57 sys.stderr.write("Check/update your MayaChemTools environment and try again.\n\n") 58 sys.exit(1) 59 60 ScriptName = os.path.basename(sys.argv[0]) 61 Options = {} 62 OptionsInfo = {} 63 64 def main(): 65 """Start execution of the script.""" 66 67 MiscUtil.PrintInfo("\n%s (PyMOL v%s; MayaChemTools v%s; %s): Starting...\n" % (ScriptName, pymol.cmd.get_version()[0], MiscUtil.GetMayaChemToolsVersion(), time.asctime())) 68 69 (WallClockTime, ProcessorTime) = MiscUtil.GetWallClockAndProcessorTime() 70 71 # Retrieve command line arguments and options... 72 RetrieveOptions() 73 74 # Process and validate command line arguments and options... 75 ProcessOptions() 76 77 # Perform actions required by the script... 78 GenerateCavitiesVisualization() 79 80 MiscUtil.PrintInfo("\n%s: Done...\n" % ScriptName) 81 MiscUtil.PrintInfo("Total time: %s" % MiscUtil.GetFormattedElapsedTime(WallClockTime, ProcessorTime)) 82 83 def GenerateCavitiesVisualization(): 84 """Generate visualization for cavities.""" 85 86 Outfile = OptionsInfo["PMLOutfile"] 87 OutFH = open(Outfile, "w") 88 if OutFH is None: 89 MiscUtil.PrintError("Failed to open output fie %s " % Outfile) 90 91 MiscUtil.PrintInfo("\nGenerating file %s..." % Outfile) 92 93 # Setup header... 94 WritePMLHeader(OutFH, ScriptName) 95 WritePyMOLParameters(OutFH) 96 97 # Load reffile for alignment.. 98 if OptionsInfo["Align"]: 99 WriteAlignReference(OutFH) 100 101 # Setup view for each input file... 102 FirstComplex = True 103 FirstComplexFirstChainName = None 104 for FileIndex in range(0, len(OptionsInfo["InfilesInfo"]["InfilesNames"])): 105 # Setup PyMOL object names... 106 PyMOLObjectNames = SetupPyMOLObjectNames(FileIndex) 107 108 # Setup complex view... 109 WriteComplexView(OutFH, FileIndex, PyMOLObjectNames, FirstComplex) 110 111 SpecifiedChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex] 112 FirstChain = True 113 for ChainID in SpecifiedChainsAndLigandsInfo["ChainIDs"]: 114 if FirstComplex and FirstChain: 115 FirstComplexFirstChainName = PyMOLObjectNames["Chains"][ChainID]["ChainAlone"] 116 117 WriteChainView(OutFH, FileIndex, PyMOLObjectNames, ChainID) 118 119 # Setup ligand views... 120 FirstLigand = True 121 for LigandID in SpecifiedChainsAndLigandsInfo["LigandIDs"][ChainID]: 122 WriteChainLigandView(OutFH, FileIndex, PyMOLObjectNames, ChainID, LigandID) 123 124 # Set up ligand level group... 125 Enable, Action = [False, "close"] 126 if FirstLigand: 127 FirstLigand = False 128 Enable, Action = [True, "open"] 129 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["Ligands"][ChainID][LigandID]["ChainLigandGroup"], PyMOLObjectNames["Ligands"][ChainID][LigandID]["ChainLigandGroupMembers"], Enable, Action) 130 131 # Setup Chain level group... 132 Enable, Action = [False, "close"] 133 if FirstChain: 134 FirstChain = False 135 Enable, Action = [True, "open"] 136 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["Chains"][ChainID]["ChainGroup"], PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"], Enable, Action) 137 138 # Set up complex level group... 139 Enable, Action = [False, "close"] 140 if FirstComplex: 141 FirstComplex = False 142 Enable, Action = [True, "open"] 143 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["PDBGroup"], PyMOLObjectNames["PDBGroupMembers"], Enable, Action) 144 145 # Delete empty PyMOL objects... 146 DeleteEmptyPyMOLObjects(OutFH, FileIndex, PyMOLObjectNames) 147 148 if OptionsInfo["Align"]: 149 DeleteAlignReference(OutFH) 150 151 if FirstComplexFirstChainName is not None: 152 OutFH.write("""\ncmd.orient("%s", animate = -1)\n""" % FirstComplexFirstChainName) 153 else: 154 OutFH.write("""\ncmd.orient("visible", animate = -1)\n""") 155 156 OutFH.close() 157 158 # Generate PSE file as needed... 159 if OptionsInfo["PSEOut"]: 160 GeneratePyMOLSessionFile() 161 162 def WritePMLHeader(OutFH, ScriptName): 163 """Write out PML setting up complex view.""" 164 165 HeaderInfo = PyMOLUtil.SetupPMLHeaderInfo(ScriptName) 166 OutFH.write("%s\n" % HeaderInfo) 167 168 def WritePyMOLParameters(OutFH): 169 """Write out PyMOL global parameters.""" 170 171 PMLCmds = [] 172 PMLCmds.append("""cmd.set("transparency", %.2f, "", 0)""" % (OptionsInfo["SurfaceTransparency"])) 173 PMLCmds.append("""cmd.set("label_font_id", %s)""" % (OptionsInfo["LabelFontID"])) 174 175 PMLCmds.append("""cmd.set("cavity_cull", %.1f, "", 0)""" % (OptionsInfo["CavityCullSize"])) 176 PMLCmds.append("""cmd.set("surface_cavity_radius", -%.1f, "", 0)""" % (OptionsInfo["CavityRadius"])) 177 PMLCmds.append("""cmd.set("surface_cavity_cutoff", -%.1f, "", 0)""" % (OptionsInfo["CavityCutoff"])) 178 179 PML = "\n".join(PMLCmds) 180 181 OutFH.write("""\n""\n"Setting up PyMOL gobal parameters..."\n""\n""") 182 OutFH.write("%s\n" % PML) 183 184 def WriteAlignReference(OutFH): 185 """Setup object for alignment reference.""" 186 187 RefFileInfo = OptionsInfo["RefFileInfo"] 188 RefFile = RefFileInfo["RefFileName"] 189 RefName = RefFileInfo["PyMOLObjectName"] 190 191 PMLCmds = [] 192 PMLCmds.append("""cmd.load("%s", "%s")""" % (RefFile, RefName)) 193 PMLCmds.append("""cmd.hide("everything", "%s")""" % (RefName)) 194 PMLCmds.append("""cmd.disable("%s")""" % (RefName)) 195 PML = "\n".join(PMLCmds) 196 197 OutFH.write("""\n""\n"Loading %s and setting up view for align reference..."\n""\n""" % RefFile) 198 OutFH.write("%s\n" % PML) 199 200 def WriteAlignComplex(OutFH, FileIndex, PyMOLObjectNames): 201 """Setup alignment of complex to reference.""" 202 203 RefFileInfo = OptionsInfo["RefFileInfo"] 204 RefName = RefFileInfo["PyMOLObjectName"] 205 206 ComplexName = PyMOLObjectNames["Complex"] 207 208 if re.match("^FirstChain$", OptionsInfo["AlignMode"], re.I): 209 RefFirstChainID = RefFileInfo["ChainsAndLigandsInfo"]["ChainIDs"][0] 210 RefAlignSelection = "%s and chain %s" % (RefName, RefFirstChainID) 211 212 ComplexFirstChainID = RetrieveFirstChainID(FileIndex) 213 ComplexAlignSelection = "%s and chain %s" % (ComplexName, ComplexFirstChainID) 214 else: 215 RefAlignSelection = RefName 216 ComplexAlignSelection = ComplexName 217 218 PML = PyMOLUtil.SetupPMLForAlignment(OptionsInfo["AlignMethod"], RefAlignSelection, ComplexAlignSelection) 219 OutFH.write("""\n""\n"Aligning %s against reference %s ..."\n""\n""" % (ComplexAlignSelection, RefAlignSelection)) 220 OutFH.write("%s\n" % PML) 221 222 def DeleteAlignReference(OutFH): 223 """Delete alignment reference object.""" 224 225 RefName = OptionsInfo["RefFileInfo"]["PyMOLObjectName"] 226 OutFH.write("""\n""\n"Deleting alignment reference object %s..."\n""\n""" % RefName) 227 OutFH.write("""cmd.delete("%s")\n""" % RefName) 228 229 def WriteComplexView(OutFH, FileIndex, PyMOLObjectNames, FirstComplex): 230 """Write out PML for viewing polymer complex.""" 231 232 # Setup complex... 233 Infile = OptionsInfo["InfilesInfo"]["InfilesNames"][FileIndex] 234 PML = PyMOLUtil.SetupPMLForPolymerComplexView(PyMOLObjectNames["Complex"], Infile, True) 235 OutFH.write("""\n""\n"Loading %s and setting up view for complex..."\n""\n""" % Infile) 236 OutFH.write("%s\n" % PML) 237 238 if OptionsInfo["Align"]: 239 # No need to align complex on to itself... 240 if not (re.match("^FirstInputFile$", OptionsInfo["AlignRefFile"], re.I) and FirstComplex): 241 WriteAlignComplex(OutFH, FileIndex, PyMOLObjectNames) 242 243 if OptionsInfo["SurfaceComplex"]: 244 # Setup hydrophobic surface... 245 PML = PyMOLUtil.SetupPMLForHydrophobicSurfaceView(PyMOLObjectNames["ComplexHydrophobicSurface"], PyMOLObjectNames["Complex"], ColorPalette = OptionsInfo["SurfaceColorPalette"], Enable = False) 246 OutFH.write("\n%s\n" % PML) 247 248 # Setup complex group... 249 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["ComplexGroup"], PyMOLObjectNames["ComplexGroupMembers"], False, "close") 250 251 def WriteChainView(OutFH, FileIndex, PyMOLObjectNames, ChainID): 252 """Write out PML for viewing chain.""" 253 254 OutFH.write("""\n""\n"Setting up views for chain %s..."\n""\n""" % ChainID) 255 256 ChainComplexName = PyMOLObjectNames["Chains"][ChainID]["ChainComplex"] 257 258 # Setup chain complex group view... 259 WriteChainComplexViews(OutFH, FileIndex, PyMOLObjectNames, ChainID) 260 261 # Setup chain view... 262 WriteChainAloneViews(OutFH, FileIndex, PyMOLObjectNames, ChainID) 263 264 # Setup chain solvent view... 265 PML = PyMOLUtil.SetupPMLForSolventView(PyMOLObjectNames["Chains"][ChainID]["Solvent"], ChainComplexName, False) 266 OutFH.write("\n%s\n" % PML) 267 268 # Setup chain inorganic view... 269 PML = PyMOLUtil.SetupPMLForInorganicView(PyMOLObjectNames["Chains"][ChainID]["Inorganic"], ChainComplexName, False) 270 OutFH.write("\n%s\n" % PML) 271 272 def WriteChainComplexViews(OutFH, FileIndex, PyMOLObjectNames, ChainID): 273 """Write chain complex views.""" 274 275 # Setup chain complex... 276 ChainComplexName = PyMOLObjectNames["Chains"][ChainID]["ChainComplex"] 277 PML = PyMOLUtil.SetupPMLForPolymerChainComplexView(ChainComplexName, PyMOLObjectNames["Complex"], ChainID, True) 278 OutFH.write("%s\n" % PML) 279 280 if OptionsInfo["SurfaceChainComplex"]: 281 # Setup hydrophobic surface... 282 PML = PyMOLUtil.SetupPMLForHydrophobicSurfaceView(PyMOLObjectNames["Chains"][ChainID]["ChainComplexHydrophobicSurface"], ChainComplexName, ColorPalette = OptionsInfo["SurfaceColorPalette"], Enable = False) 283 OutFH.write("\n%s\n" % PML) 284 285 # Setup chain complex group... 286 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroup"], PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroupMembers"], False, "close") 287 288 def WriteChainAloneViews(OutFH, FileIndex, PyMOLObjectNames, ChainID): 289 """Write individual chain views.""" 290 291 ChainComplexName = PyMOLObjectNames["Chains"][ChainID]["ChainComplex"] 292 293 # Setup chain view... 294 ChainName = PyMOLObjectNames["Chains"][ChainID]["ChainAlone"] 295 PML = PyMOLUtil.SetupPMLForPolymerChainView(ChainName, ChainComplexName, True) 296 OutFH.write("\n%s\n" % PML) 297 298 WriteChainAloneResidueTypesView(OutFH, FileIndex, PyMOLObjectNames, ChainID) 299 WriteChainAloneCavitiesAndSurfacesView(OutFH, FileIndex, PyMOLObjectNames, ChainID) 300 301 # Setup chain group... 302 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroup"], PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroupMembers"], True, "open") 303 304 def WriteChainLigandView(OutFH, FileIndex, PyMOLObjectNames, ChainID, LigandID): 305 """Write out PML for viewing ligand in a chain.""" 306 307 GroupID = "Ligand" 308 ComplexName = PyMOLObjectNames["Chains"][ChainID]["ChainComplex"] 309 LigandName = PyMOLObjectNames["Ligands"][ChainID][LigandID]["Ligand"] 310 311 # Setup main object... 312 GroupTypeObjectID = "%s" % (GroupID) 313 GroupTypeObjectName = PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupTypeObjectID] 314 315 OutFH.write("""\n""\n"Setting up views for ligand %s in chain %s..."\n""\n""" % (LigandID, ChainID)) 316 PML = PyMOLUtil.SetupPMLForLigandView(GroupTypeObjectName, ComplexName, LigandID, Enable = True, IgnoreHydrogens = OptionsInfo["IgnoreHydrogens"]) 317 OutFH.write("%s\n" % PML) 318 319 # Setup ball and stick view... 320 BallAndStickNameID = "%sBallAndStick" % (GroupID) 321 BallAndStickName = PyMOLObjectNames["Ligands"][ChainID][LigandID][BallAndStickNameID] 322 PML = PyMOLUtil.SetupPMLForBallAndStickView(BallAndStickName, GroupTypeObjectName, Enable = False) 323 OutFH.write("\n%s\n" % PML) 324 325 # Setup group.... 326 GroupNameID = "%sGroup" % (GroupID) 327 GroupMembersID = "%sGroupMembers" % (GroupID) 328 GroupName = PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupNameID] 329 GroupMembers = PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupMembersID] 330 331 Action = "close" 332 Enable = True 333 GenerateAndWritePMLForGroup(OutFH, GroupName, GroupMembers, Enable, Action) 334 335 def WriteChainAloneCavitiesAndSurfacesView(OutFH, FileIndex, PyMOLObjectNames, ChainID): 336 """Write out PML for viewing cavities and pockets in chains.""" 337 338 if not GetChainAloneContainsSurfacesStatus(FileIndex, ChainID): 339 return 340 341 ChainName = PyMOLObjectNames["Chains"][ChainID]["ChainAlone"] 342 343 for SubGroupType in ["Cavities", "Surface"]: 344 SubGroupID = "ChainAlone%sGroup" % (SubGroupType) 345 SubGroupMembersID = "%sMembers" % (SubGroupID) 346 347 ProcessingCavities = True if re.match("^Cavities$", SubGroupType, re.I) else False 348 349 # Turn off lines display for cavity surfaces... 350 DisplayStyle = None if ProcessingCavities else "cartoon" 351 352 # Setup a generic color surface... 353 SurfaceID = "%sSurface" % (SubGroupID) 354 SurfaceName = PyMOLObjectNames["Chains"][ChainID][SurfaceID] 355 ColorName = OptionsInfo["SurfaceCavityColor"] if ProcessingCavities else OptionsInfo["SurfaceColor"] 356 EnableStatus = True if ProcessingCavities else False 357 PML = PyMOLUtil.SetupPMLForSurfaceView(SurfaceName, ChainName, Enable = EnableStatus, Color = ColorName) 358 OutFH.write("\n%s\n" % PML) 359 360 if ProcessingCavities: 361 OutFH.write("""cmd.set("surface_cavity_mode", %d, "%s")\n""" % (OptionsInfo["SurfaceCavityMode"], SurfaceName)) 362 363 if GetChainAloneSurfaceChainStatus(FileIndex, ChainID): 364 # Setup surface colored by hydrophobicity... 365 HydrophobicSurfaceID = "%sHydrophobicSurface" % (SubGroupID) 366 HydrophobicSurfaceName = PyMOLObjectNames["Chains"][ChainID][HydrophobicSurfaceID] 367 PML = PyMOLUtil.SetupPMLForHydrophobicSurfaceView(HydrophobicSurfaceName, ChainName, ColorPalette = OptionsInfo["SurfaceColorPalette"], Enable = False) 368 OutFH.write("\n%s\n" % PML) 369 370 if ProcessingCavities: 371 OutFH.write("""cmd.set("surface_cavity_mode", %d, "%s")\n""" % (OptionsInfo["SurfaceCavityMode"], HydrophobicSurfaceName)) 372 373 # Setup surface colored by hyrdophobicity and charge... 374 HydrophobicChargeSurfaceID = "%sHydrophobicChargeSurface" % (SubGroupID) 375 HydrophobicChargeSurfaceName = PyMOLObjectNames["Chains"][ChainID][HydrophobicChargeSurfaceID] 376 PML = PyMOLUtil.SetupPMLForHydrophobicAndChargeSurfaceView(HydrophobicChargeSurfaceName, ChainName, OptionsInfo["AtomTypesColorNames"]["HydrophobicAtomsColor"], OptionsInfo["AtomTypesColorNames"]["NegativelyChargedAtomsColor"], OptionsInfo["AtomTypesColorNames"]["PositivelyChargedAtomsColor"], OptionsInfo["AtomTypesColorNames"]["OtherAtomsColor"], Enable = False, DisplayAs = None) 377 OutFH.write("\n%s\n" % PML) 378 379 if ProcessingCavities: 380 OutFH.write("""cmd.set("surface_cavity_mode", %d, "%s")\n""" % (OptionsInfo["SurfaceCavityMode"], HydrophobicChargeSurfaceName)) 381 382 if GetChainAloneSurfaceChainElectrostaticsStatus(FileIndex, ChainID): 383 # Setup electrostatics surface... 384 ElectrostaticsGroupID = "%sElectrostaticsGroup" % (SubGroupID) 385 ElectrostaticsGroupMembersID = "%sElectrostaticsGroupMembers" % (SubGroupID) 386 ElectrostaticsGroupName = PyMOLObjectNames["Chains"][ChainID][ElectrostaticsGroupID] 387 ElectrostaticsGroupMembers = PyMOLObjectNames["Chains"][ChainID][ElectrostaticsGroupMembersID] 388 WriteSurfaceElectrostaticsView(SubGroupType, OutFH, ChainName, ElectrostaticsGroupName, ElectrostaticsGroupMembers, DisplayAs = DisplayStyle, SurfaceCavityMode = OptionsInfo["SurfaceCavityMode"]) 389 390 # Setup surface group... 391 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["Chains"][ChainID][SubGroupID], PyMOLObjectNames["Chains"][ChainID][SubGroupMembersID], True, "open") 392 393 def WriteChainAloneResidueTypesView(OutFH, FileIndex, PyMOLObjectNames, ChainID): 394 """Write out PML for viewing residue types for a chain.""" 395 396 if not GetChainAloneResidueTypesStatus(FileIndex, ChainID): 397 return 398 399 ChainName = PyMOLObjectNames["Chains"][ChainID]["ChainAlone"] 400 401 # Setup residue types objects... 402 ResiduesGroupIDPrefix = "ChainAloneResidues" 403 for SubGroupType in ["Aromatic", "Hydrophobic", "Polar", "Positively_Charged", "Negatively_Charged", "Other"]: 404 SubGroupID = re.sub("_", "", SubGroupType) 405 406 ResiduesObjectID = "%s%sResidues" % (ResiduesGroupIDPrefix, SubGroupID) 407 ResiduesObjectName = PyMOLObjectNames["Chains"][ChainID][ResiduesObjectID] 408 409 ResiduesSurfaceObjectID = "%s%sSurface" % (ResiduesGroupIDPrefix, SubGroupID) 410 ResiduesSurfaceObjectName = PyMOLObjectNames["Chains"][ChainID][ResiduesSurfaceObjectID] 411 412 ResiduesColor = OptionsInfo["ResidueTypesParams"][SubGroupType]["Color"] 413 ResiduesNames = OptionsInfo["ResidueTypesParams"][SubGroupType]["Residues"] 414 415 NegateResidueNames = True if re.match("^Other$", SubGroupType, re.I) else False 416 WriteResidueTypesResiduesAndSurfaceView(OutFH, ChainName, ResiduesObjectName, ResiduesSurfaceObjectName, ResiduesColor, ResiduesNames, NegateResidueNames) 417 418 # Setup sub groups for residue types.. 419 ResiduesSubGroupID = "%s%sGroup" % (ResiduesGroupIDPrefix, SubGroupID) 420 ResiduesSubGroupMembersID = "%s%sGroupMembers" % (ResiduesGroupIDPrefix, SubGroupID) 421 422 # Setup residue type sub groups... 423 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["Chains"][ChainID][ResiduesSubGroupID], PyMOLObjectNames["Chains"][ChainID][ResiduesSubGroupMembersID], True, "close") 424 425 # Setup residue types group... 426 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["Chains"][ChainID]["ChainAloneResiduesGroup"], PyMOLObjectNames["Chains"][ChainID]["ChainAloneResiduesGroupMembers"], False, "close") 427 428 def WriteResidueTypesResiduesAndSurfaceView(OutFH, SelectionObjectName, Name, SurfaceName, ResiduesColor, ResiduesNames, NegateResidueNames): 429 """Write residue types residues and surface view.""" 430 431 ResidueNamesSelection = "+".join(ResiduesNames) 432 if NegateResidueNames: 433 Selection = "%s and (not resn %s)" % (SelectionObjectName, ResidueNamesSelection) 434 else: 435 Selection = "%s and (resn %s)" % (SelectionObjectName, ResidueNamesSelection) 436 437 # Setup residues... 438 PML = PyMOLUtil.SetupPMLForSelectionDisplayView(Name, Selection, "lines", ResiduesColor, True) 439 OutFH.write("\n%s\n" % PML) 440 441 # Setup surface... 442 PML = PyMOLUtil.SetupPMLForSelectionDisplayView(SurfaceName, Selection, "surface", ResiduesColor, True) 443 OutFH.write("\n%s\n" % PML) 444 445 def WriteSurfaceElectrostaticsView(Mode, OutFH, SelectionObjectName, ElectrostaticsGroupName, ElectrostaticsGroupMembers, DisplayAs = None, SurfaceCavityMode = 2): 446 """Write out PML for viewing surface electrostatics.""" 447 448 if len(ElectrostaticsGroupMembers) == 5: 449 Name, ContactPotentialName, MapName, LegendName, VolumeName = ElectrostaticsGroupMembers 450 else: 451 Name, ContactPotentialName, MapName, LegendName = ElectrostaticsGroupMembers 452 VolumeName = None 453 454 PMLCmds = [] 455 456 # Setup chain... 457 PMLCmds.append("""cmd.create("%s", "(%s)")""" % (Name, SelectionObjectName)) 458 459 # Setup vacuum electrostatics surface along with associated objects... 460 PMLCmds.append("""util.protein_vacuum_esp("%s", mode=2, quiet=0, _self=cmd)""" % (Name)) 461 PMLCmds.append("""cmd.set_name("%s_e_chg", "%s")""" % (Name, ContactPotentialName)) 462 463 if DisplayAs is not None: 464 PMLCmds.append("""cmd.show("%s", "(%s)")""" % (DisplayAs, ContactPotentialName)) 465 466 if re.match("^Cavities$", Mode, re.I): 467 if SurfaceCavityMode is not None: 468 PMLCmds.append("""cmd.set("surface_cavity_mode", %d, "%s")\n""" % (SurfaceCavityMode, ContactPotentialName)) 469 470 PMLCmds.append(PyMOLUtil.SetupPMLForEnableDisable(ContactPotentialName, Enable = True)) 471 472 PMLCmds.append("""cmd.set_name("%s_e_map", "%s")""" % (Name, MapName)) 473 PMLCmds.append(PyMOLUtil.SetupPMLForEnableDisable(MapName, Enable = False)) 474 475 PMLCmds.append("""cmd.set_name("%s_e_pot", "%s")""" % (Name, LegendName)) 476 PMLCmds.append(PyMOLUtil.SetupPMLForEnableDisable(LegendName, Enable = False)) 477 478 if VolumeName is not None: 479 PMLCmds.append("""cmd.volume("%s", "%s", "%s", "(%s)")""" % (VolumeName, MapName, "esp", Name)) 480 PMLCmds.append(PyMOLUtil.SetupPMLForEnableDisable(VolumeName, Enable = False)) 481 482 # Delete name and take it out from the group membership. It is 483 # is already part of ContactPotential object. 484 PMLCmds.append("""cmd.delete("%s")""" % (Name)) 485 ElectrostaticsGroupMembers.pop(0) 486 487 PML = "\n".join(PMLCmds) 488 489 OutFH.write("\n%s\n" % PML) 490 491 # Setup group... 492 GenerateAndWritePMLForGroup(OutFH, ElectrostaticsGroupName, ElectrostaticsGroupMembers, False, "close") 493 494 def GenerateAndWritePMLForGroup(OutFH, GroupName, GroupMembers, Enable = False, Action = "close"): 495 """Generate and write PML for group.""" 496 497 PML = PyMOLUtil.SetupPMLForGroup(GroupName, GroupMembers, Enable, Action) 498 OutFH.write("""\n""\n"Setting up group %s..."\n""\n""" % GroupName) 499 OutFH.write("%s\n" % PML) 500 501 def GeneratePyMOLSessionFile(): 502 """Generate PME file from PML file.""" 503 504 PSEOutfile = OptionsInfo["PSEOutfile"] 505 PMLOutfile = OptionsInfo["PMLOutfile"] 506 507 MiscUtil.PrintInfo("\nGenerating file %s..." % PSEOutfile) 508 509 PyMOLUtil.ConvertPMLFileToPSEFile(PMLOutfile, PSEOutfile) 510 511 if not os.path.exists(PSEOutfile): 512 MiscUtil.PrintWarning("Failed to generate PSE file, %s..." % (PSEOutfile)) 513 514 if not OptionsInfo["PMLOut"]: 515 MiscUtil.PrintInfo("Deleting file %s..." % PMLOutfile) 516 os.remove(PMLOutfile) 517 518 def DeleteEmptyPyMOLObjects(OutFH, FileIndex, PyMOLObjectNames): 519 """Delete empty PyMOL objects.""" 520 521 if OptionsInfo["AllowEmptyObjects"]: 522 return 523 524 SpecifiedChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex] 525 for ChainID in SpecifiedChainsAndLigandsInfo["ChainIDs"]: 526 OutFH.write("""\n""\n"Checking and deleting empty objects for chain %s..."\n""\n""" % (ChainID)) 527 528 # Delete any chain level objects... 529 WritePMLToCheckAndDeleteEmptyObjects(OutFH, PyMOLObjectNames["Chains"][ChainID]["Solvent"]) 530 WritePMLToCheckAndDeleteEmptyObjects(OutFH, PyMOLObjectNames["Chains"][ChainID]["Inorganic"]) 531 532 # Delete residue type objects... 533 DeleteEmptyChainResidueTypesObjects(OutFH, FileIndex, PyMOLObjectNames, ChainID) 534 535 def DeleteEmptyChainResidueTypesObjects(OutFH, FileIndex, PyMOLObjectNames, ChainID): 536 """Delete empty chain residue objects.""" 537 538 if not GetChainAloneResidueTypesStatus(FileIndex, ChainID): 539 return 540 541 ResiduesGroupIDPrefix = "ChainAloneResidues" 542 for GroupType in ["Aromatic", "Hydrophobic", "Polar", "Positively_Charged", "Negatively_Charged", "Other"]: 543 GroupID = re.sub("_", "", GroupType) 544 545 ResiduesGroupID = "%s%sGroup" % (ResiduesGroupIDPrefix, GroupID) 546 GroupName = PyMOLObjectNames["Chains"][ChainID][ResiduesGroupID] 547 548 GroupObjectNamesList = [] 549 550 ResiduesObjectID = "%s%sResidues" % (ResiduesGroupIDPrefix, GroupID) 551 ResiduesObjectName = PyMOLObjectNames["Chains"][ChainID][ResiduesObjectID] 552 GroupObjectNamesList.append(ResiduesObjectName) 553 554 ResiduesSurfaceObjectID = "%s%sSurface" % (ResiduesGroupIDPrefix, GroupID) 555 ResiduesSurfaceObjectName = PyMOLObjectNames["Chains"][ChainID][ResiduesSurfaceObjectID] 556 GroupObjectNamesList.append(ResiduesSurfaceObjectName) 557 558 GroupObjectNames = ",".join(GroupObjectNamesList) 559 WritePMLToCheckAndDeleteEmptyObjects(OutFH, GroupObjectNames, GroupName) 560 561 def WritePMLToCheckAndDeleteEmptyObjects(OutFH, ObjectName, ParentObjectName = None): 562 """Write PML to check and delete empty PyMOL objects.""" 563 564 if ParentObjectName is None: 565 PML = """CheckAndDeleteEmptyObjects("%s")""" % (ObjectName) 566 else: 567 PML = """CheckAndDeleteEmptyObjects("%s", "%s")""" % (ObjectName, ParentObjectName) 568 569 OutFH.write("%s\n" % PML) 570 571 def SetupPyMOLObjectNames(FileIndex): 572 """Setup hierarchy of PyMOL groups and objects for ligand centric views of 573 chains and ligands present in input file. 574 """ 575 576 PyMOLObjectNames = {} 577 PyMOLObjectNames["Chains"] = {} 578 PyMOLObjectNames["Ligands"] = {} 579 580 # Setup groups and objects for complex... 581 SetupPyMOLObjectNamesForComplex(FileIndex, PyMOLObjectNames) 582 583 # Setup groups and objects for chain... 584 SpecifiedChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex] 585 for ChainID in SpecifiedChainsAndLigandsInfo["ChainIDs"]: 586 SetupPyMOLObjectNamesForChain(FileIndex, PyMOLObjectNames, ChainID) 587 588 # Setup groups and objects for ligand... 589 for LigandID in SpecifiedChainsAndLigandsInfo["LigandIDs"][ChainID]: 590 SetupPyMOLObjectNamesForLigand(FileIndex, PyMOLObjectNames, ChainID, LigandID) 591 592 return PyMOLObjectNames 593 594 def SetupPyMOLObjectNamesForComplex(FileIndex, PyMOLObjectNames): 595 """Setup groups and objects for complex.""" 596 597 PDBFileRoot = OptionsInfo["InfilesInfo"]["InfilesRoots"][FileIndex] 598 599 PDBGroupName = "%s" % PDBFileRoot 600 PyMOLObjectNames["PDBGroup"] = PDBGroupName 601 PyMOLObjectNames["PDBGroupMembers"] = [] 602 603 ComplexGroupName = "%s.Complex" % PyMOLObjectNames["PDBGroup"] 604 PyMOLObjectNames["ComplexGroup"] = ComplexGroupName 605 PyMOLObjectNames["PDBGroupMembers"].append(ComplexGroupName) 606 607 PyMOLObjectNames["Complex"] = "%s.Complex" % ComplexGroupName 608 if OptionsInfo["SurfaceComplex"]: 609 PyMOLObjectNames["ComplexHydrophobicSurface"] = "%s.Surface" % ComplexGroupName 610 611 PyMOLObjectNames["ComplexGroupMembers"] = [] 612 PyMOLObjectNames["ComplexGroupMembers"].append(PyMOLObjectNames["Complex"]) 613 if OptionsInfo["SurfaceComplex"]: 614 PyMOLObjectNames["ComplexGroupMembers"].append(PyMOLObjectNames["ComplexHydrophobicSurface"]) 615 616 def SetupPyMOLObjectNamesForChain(FileIndex, PyMOLObjectNames, ChainID): 617 """Setup groups and objects for chain.""" 618 619 PDBGroupName = PyMOLObjectNames["PDBGroup"] 620 621 PyMOLObjectNames["Chains"][ChainID] = {} 622 PyMOLObjectNames["Ligands"][ChainID] = {} 623 624 # Set up chain group and chain objects... 625 ChainGroupName = "%s.Chain%s" % (PDBGroupName, ChainID) 626 PyMOLObjectNames["Chains"][ChainID]["ChainGroup"] = ChainGroupName 627 PyMOLObjectNames["PDBGroupMembers"].append(ChainGroupName) 628 PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"] = [] 629 630 # Setup chain complex group and objects... 631 ChainComplexGroupName = "%s.Complex" % (ChainGroupName) 632 PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroup"] = ChainComplexGroupName 633 PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"].append(ChainComplexGroupName) 634 635 PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroupMembers"] = [] 636 637 Name = "%s.Complex" % (ChainComplexGroupName) 638 PyMOLObjectNames["Chains"][ChainID]["ChainComplex"] = Name 639 PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroupMembers"].append(Name) 640 641 if OptionsInfo["SurfaceChainComplex"]: 642 Name = "%s.Surface" % (ChainComplexGroupName) 643 PyMOLObjectNames["Chains"][ChainID]["ChainComplexHydrophobicSurface"] = Name 644 PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroupMembers"].append(Name) 645 646 # Setup up a group for individual chains... 647 ChainAloneGroupName = "%s.Chain" % (ChainGroupName) 648 PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroup"] = ChainAloneGroupName 649 PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"].append(ChainAloneGroupName) 650 651 PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroupMembers"] = [] 652 653 Name = "%s.Chain" % (ChainAloneGroupName) 654 PyMOLObjectNames["Chains"][ChainID]["ChainAlone"] = Name 655 PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroupMembers"].append(Name) 656 657 if GetChainAloneResidueTypesStatus(FileIndex, ChainID): 658 # Setup residue type group and its subgroups... 659 ResiduesGroupName = "%s.Residues" % (ChainAloneGroupName) 660 661 ResiduesGroupIDPrefix = "ChainAloneResidues" 662 ResiduesGroupID = "%sGroup" % ResiduesGroupIDPrefix 663 664 # Add residue group to chain alone group... 665 PyMOLObjectNames["Chains"][ChainID][ResiduesGroupID] = ResiduesGroupName 666 PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroupMembers"].append(ResiduesGroupName) 667 668 # Initialize residue group members... 669 ResiduesGroupMembersID = "%sGroupMembers" % ResiduesGroupIDPrefix 670 PyMOLObjectNames["Chains"][ChainID][ResiduesGroupMembersID] = [] 671 672 # Setup residues sub groups and its members... 673 for SubGroupType in ["Aromatic", "Hydrophobic", "Polar", "Positively_Charged", "Negatively_Charged", "Other"]: 674 SubGroupID = re.sub("_", "", SubGroupType) 675 676 ResiduesSubGroupName = "%s.%s" % (ResiduesGroupName, SubGroupType) 677 ResiduesSubGroupID = "%s%sGroup" % (ResiduesGroupIDPrefix, SubGroupID) 678 679 # Add sub group to residues group... 680 PyMOLObjectNames["Chains"][ChainID][ResiduesSubGroupID] = ResiduesSubGroupName 681 PyMOLObjectNames["Chains"][ChainID][ResiduesGroupMembersID].append(ResiduesSubGroupName) 682 683 # Initialize sub group members... 684 ResiduesSubGroupMembersID = "%s%sGroupMembers" % (ResiduesGroupIDPrefix, SubGroupID) 685 PyMOLObjectNames["Chains"][ChainID][ResiduesSubGroupMembersID] = [] 686 687 # Add sub group members to subgroup... 688 for MemberType in ["Residues", "Surface"]: 689 MemberID = re.sub("_", "", MemberType) 690 691 SubGroupMemberName = "%s.%s" % (ResiduesSubGroupName, MemberType) 692 SubGroupMemberID = "%s%s%s" % (ResiduesGroupIDPrefix, SubGroupID, MemberID) 693 694 PyMOLObjectNames["Chains"][ChainID][SubGroupMemberID] = SubGroupMemberName 695 PyMOLObjectNames["Chains"][ChainID][ResiduesSubGroupMembersID].append(SubGroupMemberName) 696 697 if GetChainAloneContainsSurfacesStatus(FileIndex, ChainID): 698 # Setup cavity and surface groups... 699 for SubGroupType in ["Cavities", "Surface"]: 700 SubGroupName = "%s.%s" % (ChainAloneGroupName, SubGroupType) 701 SubGroupID = "ChainAlone%sGroup" % (SubGroupType) 702 SubGroupMembersID = "%sMembers" % (SubGroupID) 703 704 PyMOLObjectNames["Chains"][ChainID][SubGroupID] = SubGroupName 705 PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroupMembers"].append(SubGroupName) 706 707 PyMOLObjectNames["Chains"][ChainID][SubGroupMembersID] = [] 708 709 # Setup a generic color surface... 710 SurfaceName = "%s.Surface" % (SubGroupName) 711 SurfaceID = "%sSurface" % (SubGroupID) 712 PyMOLObjectNames["Chains"][ChainID][SurfaceID] = SurfaceName 713 PyMOLObjectNames["Chains"][ChainID][SubGroupMembersID].append(SurfaceName) 714 715 if GetChainAloneSurfaceChainStatus(FileIndex, ChainID): 716 # Setup hydrophobicity surface... 717 HydrophobicSurfaceName = "%s.Hydrophobicity" % (SubGroupName) 718 HydrophobicSurfaceID = "%sHydrophobicSurface" % (SubGroupID) 719 PyMOLObjectNames["Chains"][ChainID][HydrophobicSurfaceID] = HydrophobicSurfaceName 720 PyMOLObjectNames["Chains"][ChainID][SubGroupMembersID].append(HydrophobicSurfaceName) 721 722 # Setup hydrophobicity and charge surface... 723 HydrophobicChargeSurfaceName = "%s.Hydrophobicity_Charge" % (SubGroupName) 724 HydrophobicChargeSurfaceID = "%sHydrophobicChargeSurface" % (SubGroupID) 725 PyMOLObjectNames["Chains"][ChainID][HydrophobicChargeSurfaceID] = HydrophobicChargeSurfaceName 726 PyMOLObjectNames["Chains"][ChainID][SubGroupMembersID].append(HydrophobicChargeSurfaceName) 727 728 if GetChainAloneSurfaceChainElectrostaticsStatus(FileIndex, ChainID): 729 # Setup electrostatics group... 730 ElectrostaticsGroupName = "%s.Vacuum_Electrostatics" % (SubGroupName) 731 ElectrostaticsGroupID = "%sElectrostaticsGroup" % (SubGroupID) 732 ElectrostaticsGroupMembersID = "%sElectrostaticsGroupMembers" % (SubGroupID) 733 734 PyMOLObjectNames["Chains"][ChainID][ElectrostaticsGroupID] = ElectrostaticsGroupName 735 PyMOLObjectNames["Chains"][ChainID][SubGroupMembersID].append(ElectrostaticsGroupName) 736 737 # Setup electrostatics group members... 738 PyMOLObjectNames["Chains"][ChainID][ElectrostaticsGroupMembersID] = [] 739 740 for MemberType in ["Chain", "Contact_Potential", "Map", "Legend"]: 741 MemberID = re.sub("_", "", MemberType) 742 743 Name = "%s.%s" % (ElectrostaticsGroupName, MemberType) 744 NameID = "%s%s" % (ElectrostaticsGroupID, MemberID) 745 746 PyMOLObjectNames["Chains"][ChainID][NameID] = Name 747 PyMOLObjectNames["Chains"][ChainID][ElectrostaticsGroupMembersID].append(Name) 748 749 # Setup solvent and inorganic objects for chain... 750 for NameID in ["Solvent", "Inorganic"]: 751 Name = "%s.%s" % (ChainGroupName, NameID) 752 PyMOLObjectNames["Chains"][ChainID][NameID] = Name 753 PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"].append(Name) 754 755 def SetupPyMOLObjectNamesForLigand(FileIndex, PyMOLObjectNames, ChainID, LigandID): 756 """Stetup groups and objects for ligand.""" 757 758 PyMOLObjectNames["Ligands"][ChainID][LigandID] = {} 759 760 ChainGroupName = PyMOLObjectNames["Chains"][ChainID]["ChainGroup"] 761 762 # Setup a chain level ligand group... 763 ChainLigandGroupName = "%s.Ligand%s" % (ChainGroupName, LigandID) 764 PyMOLObjectNames["Ligands"][ChainID][LigandID]["ChainLigandGroup"] = ChainLigandGroupName 765 PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"].append(ChainLigandGroupName) 766 767 PyMOLObjectNames["Ligands"][ChainID][LigandID]["ChainLigandGroupMembers"] = [] 768 769 # Set up ligand group and its members... 770 GroupName = "%s.Ligand" % (ChainLigandGroupName) 771 GroupNameID = "LigandGroup" 772 GroupMembersID = "LigandGroupMembers" 773 774 PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupNameID] = GroupName 775 PyMOLObjectNames["Ligands"][ChainID][LigandID]["ChainLigandGroupMembers"].append(GroupName) 776 777 LigandName = "%s.Ligand" % (GroupName) 778 LigandNameID = "Ligand" 779 PyMOLObjectNames["Ligands"][ChainID][LigandID][LigandNameID] = LigandName 780 781 PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupMembersID] = [] 782 PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupMembersID].append(LigandName) 783 784 # Add ball and stick... 785 BallAndStickName = "%s.BallAndStick" % (GroupName) 786 BallAndStickID = "LigandBallAndStick" 787 PyMOLObjectNames["Ligands"][ChainID][LigandID][BallAndStickID] = BallAndStickName 788 PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupMembersID].append(BallAndStickName) 789 790 def RetrieveInfilesInfo(): 791 """Retrieve information for input files.""" 792 793 InfilesInfo = {} 794 795 InfilesInfo["InfilesNames"] = [] 796 InfilesInfo["InfilesRoots"] = [] 797 InfilesInfo["ChainsAndLigandsInfo"] = [] 798 799 for Infile in OptionsInfo["InfilesNames"]: 800 FileDir, FileName, FileExt = MiscUtil.ParseFileName(Infile) 801 InfileRoot = FileName 802 803 ChainsAndLigandInfo = PyMOLUtil.GetChainsAndLigandsInfo(Infile, InfileRoot) 804 805 InfilesInfo["InfilesNames"].append(Infile) 806 InfilesInfo["InfilesRoots"].append(InfileRoot) 807 InfilesInfo["ChainsAndLigandsInfo"].append(ChainsAndLigandInfo) 808 809 OptionsInfo["InfilesInfo"] = InfilesInfo 810 811 def RetrieveRefFileInfo(): 812 """Retrieve information for ref file.""" 813 814 RefFileInfo = {} 815 if not OptionsInfo["Align"]: 816 OptionsInfo["RefFileInfo"] = RefFileInfo 817 return 818 819 RefFile = OptionsInfo["RefFileName"] 820 821 FileDir, FileName, FileExt = MiscUtil.ParseFileName(RefFile) 822 RefFileRoot = FileName 823 824 if re.match("^FirstInputFile$", OptionsInfo["AlignRefFile"], re.I): 825 ChainsAndLigandInfo = OptionsInfo["InfilesInfo"]["ChainsAndLigandsInfo"][0] 826 else: 827 MiscUtil.PrintInfo("\nRetrieving chain and ligand information for alignment reference file %s..." % RefFile) 828 ChainsAndLigandInfo = PyMOLUtil.GetChainsAndLigandsInfo(RefFile, RefFileRoot) 829 830 RefFileInfo["RefFileName"] = RefFile 831 RefFileInfo["RefFileRoot"] = RefFileRoot 832 RefFileInfo["PyMOLObjectName"] = "AlignRef_%s" % RefFileRoot 833 RefFileInfo["ChainsAndLigandsInfo"] = ChainsAndLigandInfo 834 835 OptionsInfo["RefFileInfo"] = RefFileInfo 836 837 def ProcessChainAndLigandIDs(): 838 """Process specified chain and ligand IDs for infiles.""" 839 840 OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"] = [] 841 842 for FileIndex in range(0, len(OptionsInfo["InfilesInfo"]["InfilesNames"])): 843 MiscUtil.PrintInfo("\nProcessing specified chain and ligand IDs for input file %s..." % OptionsInfo["InfilesInfo"]["InfilesNames"][FileIndex]) 844 845 ChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["ChainsAndLigandsInfo"][FileIndex] 846 SpecifiedChainsAndLigandsInfo = PyMOLUtil.ProcessChainsAndLigandsOptionsInfo(ChainsAndLigandsInfo, "-c, --chainIDs", OptionsInfo["ChainIDs"], "-l, --ligandIDs", OptionsInfo["LigandIDs"]) 847 ProcessResidueTypesAndSurfaceOptions(FileIndex, SpecifiedChainsAndLigandsInfo) 848 OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"].append(SpecifiedChainsAndLigandsInfo) 849 850 CheckPresenceOfValidLigandIDs(ChainsAndLigandsInfo, SpecifiedChainsAndLigandsInfo) 851 852 def ProcessResidueTypesAndSurfaceOptions(FileIndex, SpecifiedChainsAndLigandsInfo): 853 """Process residue types and surface options for chains.""" 854 855 SpecifiedChainsAndLigandsInfo["ChainSurfaces"] = {} 856 SpecifiedChainsAndLigandsInfo["SurfaceChain"] = {} 857 SpecifiedChainsAndLigandsInfo["SurfaceChainElectrostatics"] = {} 858 859 SpecifiedChainsAndLigandsInfo["ResidueTypesChain"] = {} 860 861 # Load infile... 862 Infile = OptionsInfo["InfilesInfo"]["InfilesNames"][FileIndex] 863 MolName = OptionsInfo["InfilesInfo"]["InfilesRoots"][FileIndex] 864 pymol.cmd.load(Infile, MolName) 865 866 for ChainID in SpecifiedChainsAndLigandsInfo["ChainIDs"]: 867 AminoAcidsPresent = PyMOLUtil.AreAminoAcidResiduesPresent(MolName, ChainID) 868 869 # Process surfaces for chains... 870 if re.match("^auto$", OptionsInfo["SurfaceChain"], re.I): 871 SurfaceChain = True if AminoAcidsPresent else False 872 else: 873 SurfaceChain = True if re.match("^yes$", OptionsInfo["SurfaceChain"], re.I) else False 874 SpecifiedChainsAndLigandsInfo["SurfaceChain"][ChainID] = SurfaceChain 875 876 if re.match("^auto$", OptionsInfo["SurfaceChainElectrostatics"], re.I): 877 SurfaceChainElectrostatics = True if AminoAcidsPresent else False 878 else: 879 SurfaceChainElectrostatics = True if re.match("^yes$", OptionsInfo["SurfaceChainElectrostatics"], re.I) else False 880 SpecifiedChainsAndLigandsInfo["SurfaceChainElectrostatics"][ChainID] = SurfaceChainElectrostatics 881 882 # A generic color surface is always created... 883 ChainSurfaces = True 884 SpecifiedChainsAndLigandsInfo["ChainSurfaces"][ChainID] = ChainSurfaces 885 886 # Process residue types for chains... 887 if re.match("^auto$", OptionsInfo["ResidueTypesChain"], re.I): 888 ResidueTypesChain = True if AminoAcidsPresent else False 889 else: 890 ResidueTypesChain = True if re.match("^yes$", OptionsInfo["ResidueTypesChain"], re.I) else False 891 SpecifiedChainsAndLigandsInfo["ResidueTypesChain"][ChainID] = ResidueTypesChain 892 893 # Delete loaded object... 894 pymol.cmd.delete(MolName) 895 896 def GetChainAloneResidueTypesStatus(FileIndex, ChainID): 897 """Get status of residue types for chain alone object.""" 898 899 Status = True if OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex]["ResidueTypesChain"][ChainID] else False 900 901 return Status 902 903 def GetChainAloneContainsSurfacesStatus(FileIndex, ChainID): 904 """Get status of surfaces present in chain alone object.""" 905 906 return OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex]["ChainSurfaces"][ChainID] 907 908 def GetChainAloneSurfaceChainStatus(FileIndex, ChainID): 909 """Get status of hydrophobic surfaces for chain alone object.""" 910 911 return OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex]["SurfaceChain"][ChainID] 912 913 def GetChainAloneSurfaceChainElectrostaticsStatus(FileIndex, ChainID): 914 """Get status of electrostatics surfaces for chain alone object.""" 915 916 return OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex]["SurfaceChainElectrostatics"][ChainID] 917 918 def CheckPresenceOfValidLigandIDs(ChainsAndLigandsInfo, SpecifiedChainsAndLigandsInfo): 919 """Check presence of valid ligand IDs.""" 920 921 MiscUtil.PrintInfo("\nSpecified chain IDs: %s" % (", ".join(SpecifiedChainsAndLigandsInfo["ChainIDs"]))) 922 923 for ChainID in SpecifiedChainsAndLigandsInfo["ChainIDs"]: 924 if len (SpecifiedChainsAndLigandsInfo["LigandIDs"][ChainID]): 925 MiscUtil.PrintInfo("Chain ID: %s; Specified LigandIDs: %s" % (ChainID, ", ".join(SpecifiedChainsAndLigandsInfo["LigandIDs"][ChainID]))) 926 else: 927 MiscUtil.PrintInfo("Chain IDs: %s; Specified LigandIDs: None" % (ChainID)) 928 MiscUtil.PrintWarning("No valid ligand IDs found for chain ID, %s. PyMOL groups and objects related to ligand and binding pockect won't be created." % (ChainID)) 929 930 def RetrieveFirstChainID(FileIndex): 931 """Get first chain ID.""" 932 933 ChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["ChainsAndLigandsInfo"][FileIndex] 934 935 FirstChainID = None 936 if len(ChainsAndLigandsInfo["ChainIDs"]): 937 FirstChainID = ChainsAndLigandsInfo["ChainIDs"][0] 938 939 return FirstChainID 940 941 def ProcessResidueTypes(): 942 """Process residue types.""" 943 944 ResidueTypesNamesInfo, ResidueTypesParamsInfo = PyMOLUtil.ProcessResidueTypesOptionsInfo("-r, --residueTypes", OptionsInfo["ResidueTypes"]) 945 OptionsInfo["ResidueTypesNames"] = ResidueTypesNamesInfo 946 OptionsInfo["ResidueTypesParams"] = ResidueTypesParamsInfo 947 948 def ProcessSurfaceAtomTypesColors(): 949 """Process surface atom types colors.""" 950 951 AtomTypesColorNamesInfo = PyMOLUtil.ProcessSurfaceAtomTypesColorsOptionsInfo("--surfaceAtomTypesColors", OptionsInfo["SurfaceAtomTypesColors"]) 952 OptionsInfo["AtomTypesColorNames"] = AtomTypesColorNamesInfo 953 954 def ProcessOptions(): 955 """Process and validate command line arguments and options.""" 956 957 MiscUtil.PrintInfo("Processing options...") 958 959 # Validate options... 960 ValidateOptions() 961 962 OptionsInfo["Align"] = True if re.match("^Yes$", Options["--align"], re.I) else False 963 OptionsInfo["AlignMethod"] = Options["--alignMethod"].lower() 964 OptionsInfo["AlignMode"] = Options["--alignMode"] 965 966 OptionsInfo["AllowEmptyObjects"] = True if re.match("^Yes$", Options["--allowEmptyObjects"], re.I) else False 967 968 OptionsInfo["CavityCulled"] = True if re.match("^Yes$", Options["--cavityCulled"], re.I) else False 969 OptionsInfo["SurfaceCavityMode"] = 2 if OptionsInfo["CavityCulled"] else 1 970 971 OptionsInfo["CavityCullSize"] = float(Options["--cavityCullSize"]) 972 OptionsInfo["CavityCutoff"] = float(Options["--cavityCutoff"]) 973 OptionsInfo["CavityRadius"] = float(Options["--cavityRadius"]) 974 975 OptionsInfo["Infiles"] = Options["--infiles"] 976 OptionsInfo["InfilesNames"] = Options["--infileNames"] 977 978 OptionsInfo["AlignRefFile"] = Options["--alignRefFile"] 979 if re.match("^FirstInputFile$", Options["--alignRefFile"], re.I): 980 OptionsInfo["RefFileName"] = OptionsInfo["InfilesNames"][0] 981 else: 982 OptionsInfo["RefFileName"] = Options["--alignRefFile"] 983 984 OptionsInfo["IgnoreHydrogens"] = True if re.match("^Yes$", Options["--ignoreHydrogens"], re.I) else False 985 986 OptionsInfo["Overwrite"] = Options["--overwrite"] 987 OptionsInfo["PMLOut"] = True if re.match("^Yes$", Options["--PMLOut"], re.I) else False 988 989 OptionsInfo["Outfile"] = Options["--outfile"] 990 FileDir, FileName, FileExt = MiscUtil.ParseFileName(OptionsInfo["Outfile"]) 991 OptionsInfo["PSEOut"] = False 992 if re.match("^pml$", FileExt, re.I): 993 OptionsInfo["PMLOutfile"] = OptionsInfo["Outfile"] 994 OptionsInfo["PMEOutfile"] = re.sub(".pml$", ".pme", OptionsInfo["Outfile"]) 995 elif re.match("^pse$", FileExt, re.I): 996 OptionsInfo["PSEOut"] = True 997 OptionsInfo["PSEOutfile"] = OptionsInfo["Outfile"] 998 OptionsInfo["PMLOutfile"] = re.sub(".pse$", ".pml", OptionsInfo["Outfile"]) 999 if os.path.exists(OptionsInfo["PMLOutfile"]) and (not OptionsInfo["Overwrite"]): 1000 MiscUtil.PrintError("The intermediate output file to be generated, %s, already exist. Use option \"--ov\" or \"--overwrite\" and try again." % OptionsInfo["PMLOutfile"] ) 1001 1002 OptionsInfo["LabelFontID"] = int(Options["--labelFontID"]) 1003 1004 OptionsInfo["ResidueTypesChain"] = Options["--residueTypesChain"] 1005 OptionsInfo["ResidueTypes"] = Options["--residueTypes"] 1006 ProcessResidueTypes() 1007 1008 OptionsInfo["SurfaceChain"] = Options["--surfaceChain"] 1009 OptionsInfo["SurfaceChainElectrostatics"] = Options["--surfaceChainElectrostatics"] 1010 1011 OptionsInfo["SurfaceChainComplex"] = True if re.match("^Yes$", Options["--surfaceChainComplex"], re.I) else False 1012 OptionsInfo["SurfaceComplex"] = True if re.match("^Yes$", Options["--surfaceComplex"], re.I) else False 1013 1014 # Retrieve surface colors for generic surfaces.. 1015 SurfaceColors = re.sub(" ", "", Options["--surfaceColors"]) 1016 SurfaceColorsWords = SurfaceColors.split(",") 1017 if len(SurfaceColorsWords) != 2: 1018 MiscUtil.PrintError("The number of comma delinited color names, %d, specified using \"--surfaceColors\" option, \"%s\", must be a 2." % (len(SurfaceColorsWords), Options["--surfaceColors"])) 1019 OptionsInfo["SurfaceColors"] = SurfaceColors 1020 OptionsInfo["SurfaceCavityColor"] = SurfaceColorsWords[0] 1021 OptionsInfo["SurfaceColor"] = SurfaceColorsWords[1] 1022 1023 OptionsInfo["SurfaceColorPalette"] = Options["--surfaceColorPalette"] 1024 OptionsInfo["SurfaceAtomTypesColors"] = Options["--surfaceAtomTypesColors"] 1025 ProcessSurfaceAtomTypesColors() 1026 1027 OptionsInfo["SurfaceTransparency"] = float(Options["--surfaceTransparency"]) 1028 1029 RetrieveInfilesInfo() 1030 RetrieveRefFileInfo() 1031 1032 OptionsInfo["ChainIDs"] = Options["--chainIDs"] 1033 OptionsInfo["LigandIDs"] = Options["--ligandIDs"] 1034 1035 ProcessChainAndLigandIDs() 1036 1037 def RetrieveOptions(): 1038 """Retrieve command line arguments and options.""" 1039 1040 # Get options... 1041 global Options 1042 Options = docopt(_docoptUsage_) 1043 1044 # Set current working directory to the specified directory... 1045 WorkingDir = Options["--workingdir"] 1046 if WorkingDir: 1047 os.chdir(WorkingDir) 1048 1049 # Handle examples option... 1050 if "--examples" in Options and Options["--examples"]: 1051 MiscUtil.PrintInfo(MiscUtil.GetExamplesTextFromDocOptText(_docoptUsage_)) 1052 sys.exit(0) 1053 1054 def ValidateOptions(): 1055 """Validate option values.""" 1056 1057 MiscUtil.ValidateOptionTextValue("--align", Options["--align"], "yes no") 1058 MiscUtil.ValidateOptionTextValue("--alignMethod", Options["--alignMethod"], "align cealign super") 1059 MiscUtil.ValidateOptionTextValue("--alignMode", Options["--alignMode"], "FirstChain Complex") 1060 1061 MiscUtil.ValidateOptionTextValue("--allowEmptyObjects", Options["--allowEmptyObjects"], "yes no") 1062 1063 MiscUtil.ValidateOptionTextValue("--cavityCulled", Options["--cavityCulled"], "yes no") 1064 MiscUtil.ValidateOptionFloatValue("--cavityCullSize", Options["--cavityCullSize"], {">": 0.0}) 1065 MiscUtil.ValidateOptionFloatValue("--cavityCutoff", Options["--cavityCutoff"], {">": 0.0}) 1066 MiscUtil.ValidateOptionFloatValue("--cavityRadius", Options["--cavityRadius"], {">": 0.0}) 1067 1068 # Expand infiles to handle presence of multiple input files... 1069 InfileNames = MiscUtil.ExpandFileNames(Options["--infiles"], ",") 1070 if not len(InfileNames): 1071 MiscUtil.PrintError("No input files specified for \"-i, --infiles\" option") 1072 1073 # Validate file extensions... 1074 for Infile in InfileNames: 1075 MiscUtil.ValidateOptionFilePath("-i, --infiles", Infile) 1076 MiscUtil.ValidateOptionFileExt("-i, --infiles", Infile, "pdb cif") 1077 MiscUtil.ValidateOptionsDistinctFileNames("-i, --infiles", Infile, "-o, --outfile", Options["--outfile"]) 1078 Options["--infileNames"] = InfileNames 1079 1080 MiscUtil.ValidateOptionFileExt("-o, --outfile", Options["--outfile"], "pml pse") 1081 MiscUtil.ValidateOptionsOutputFileOverwrite("-o, --outfile", Options["--outfile"], "--overwrite", Options["--overwrite"]) 1082 1083 if re.match("^yes$", Options["--align"], re.I): 1084 if not re.match("^FirstInputFile$", Options["--alignRefFile"], re.I): 1085 AlignRefFile = Options["--alignRefFile"] 1086 MiscUtil.ValidateOptionFilePath("--alignRefFile", AlignRefFile) 1087 MiscUtil.ValidateOptionFileExt("--alignRefFile", AlignRefFile, "pdb cif") 1088 MiscUtil.ValidateOptionsDistinctFileNames("--AlignRefFile", AlignRefFile, "-o, --outfile", Options["--outfile"]) 1089 1090 MiscUtil.ValidateOptionTextValue("--ignoreHydrogens", Options["--ignoreHydrogens"], "yes no") 1091 1092 MiscUtil.ValidateOptionTextValue("--PMLOut", Options["--PMLOut"], "yes no") 1093 MiscUtil.ValidateOptionIntegerValue("--labelFontID", Options["--labelFontID"], {}) 1094 1095 MiscUtil.ValidateOptionTextValue("--residueTypesChain", Options["--residueTypesChain"], "yes no auto") 1096 1097 MiscUtil.ValidateOptionTextValue("--surfaceChain", Options["--surfaceChain"], "yes no auto") 1098 MiscUtil.ValidateOptionTextValue("--surfaceComplex", Options["--surfaceComplex"], "yes no") 1099 MiscUtil.ValidateOptionTextValue("--surfaceChainComplex", Options["--surfaceChainComplex"], "yes no") 1100 MiscUtil.ValidateOptionTextValue("--surfaceChainElectrostatics", Options["--surfaceChainElectrostatics"], "yes no auto") 1101 1102 MiscUtil.ValidateOptionTextValue("--surfaceColorPalette", Options["--surfaceColorPalette"], "RedToWhite WhiteToGreen") 1103 MiscUtil.ValidateOptionFloatValue("--surfaceTransparency", Options["--surfaceTransparency"], {">=": 0.0, "<=": 1.0}) 1104 1105 # Setup a usage string for docopt... 1106 _docoptUsage_ = """ 1107 PyMOLVisualizeCavities.py - Visualize cavities and pockets in macromolecules 1108 1109 Usage: 1110 PyMOLVisualizeCavities.py [--align <yes or no>] [--alignMethod <align, cealign, super>] 1111 [--alignMode <FirstChain or Complex>] [--alignRefFile <filename>] 1112 [--allowEmptyObjects <yes or no>] [--cavityCulled <Yes or No>] 1113 [--cavityCullSize <number>] [--cavityCutoff <number>] [--cavityRadius <number>] 1114 [--chainIDs <First, All or ID1,ID2...>] [--labelFontID <number>] 1115 [--ignoreHydrogens <yes or no>] [--ligandIDs <Largest, All or ID1,ID2...> ] [--PMLOut <yes or no>] 1116 [--residueTypes <Type,Color,ResNames,...>] [--residueTypesChain <yes or no>] 1117 [--surfaceChain <yes or no>] [--surfaceChainElectrostatics <yes or no>] 1118 [--surfaceChainComplex <yes or no>] [--surfaceComplex <yes or no>] 1119 [--surfaceAtomTypesColors <ColorType,ColorSpec,...>] 1120 [--surfaceColors <ColorName1,ColorName2>] [--surfaceColorPalette <RedToWhite or WhiteToGreen>] 1121 [--surfaceTransparency <number>] [--overwrite] [-w <dir>] -i <infile1,infile2,infile3...> -o <outfile> 1122 PyMOLVisualizeCavities.py -h | --help | -e | --examples 1123 1124 Description: 1125 Generate PyMOL visualization files for viewing cavities and pockets in 1126 macromolecules including proteins and nucleic acids. 1127 1128 The supported input file format are: PDB (.pdb), CIF (.cif) 1129 1130 The supported output file formats are: PyMOL script file (.pml), PyMOL session 1131 file (.pse) 1132 1133 A variety of PyMOL groups and objects may be created for visualization of 1134 cavities and pockets in macromolecules. These groups and objects correspond 1135 to complexes, surfaces, chains, ligands, inorganics, cavities, and pockets. 1136 A complete hierarchy of all possible PyMOL groups and objects is shown below: 1137 1138 <PDBFileRoot> 1139 .Complex 1140 .Complex 1141 .Surface 1142 .Chain<ID> 1143 .Complex 1144 .Complex 1145 .Surface 1146 .Chain 1147 .Chain 1148 .Residues 1149 .Aromatic 1150 .Residues 1151 .Surface 1152 .Hydrophobic 1153 .Residues 1154 .Surface 1155 .Polar 1156 .Residues 1157 .Surface 1158 .Positively_Charged 1159 .Residues 1160 .Surface 1161 .Negatively_Charged 1162 .Residues 1163 .Surface 1164 .Other 1165 .Residues 1166 .Surface 1167 .Cavities 1168 .Surface 1169 .Hydrophobicity 1170 .Hydrophobicity_Charge 1171 .Vacuum_Electrostatics 1172 .Contact_Potentials 1173 .Map 1174 .Legend 1175 .Surface 1176 .Surface 1177 .Hydrophobicity 1178 .Hydrophobicity_Charge 1179 .Vacuum_Electrostatics 1180 .Contact_Potentials 1181 .Map 1182 .Legend 1183 .Solvent 1184 .Inorganic 1185 .Ligand<ID> 1186 .Ligand 1187 .Ligand 1188 .BallAndStick 1189 .Ligand<ID> 1190 .Ligand 1191 ... ... ... 1192 .Chain<ID> 1193 ... ... ... 1194 .Ligand<ID> 1195 ... ... ... 1196 .Ligand<ID> 1197 ... ... ... 1198 .Chain<ID> 1199 ... ... ... 1200 <PDBFileRoot> 1201 .Complex 1202 ... ... ... 1203 .Chain<ID> 1204 ... ... ... 1205 .Ligand<ID> 1206 ... ... ... 1207 .Ligand<ID> 1208 ... ... ... 1209 .Chain<ID> 1210 ... ... ... 1211 1212 The hydrophobic and electrostatic surfaces are not created for complete complex 1213 and chain complex in input file(s) by default. A word to the wise: The creation of 1214 surface objects may slow down loading of PML file and generation of PSE file, based 1215 on the size of input complexes. The generation of PSE file may also fail. 1216 1217 Options: 1218 -a, --align <yes or no> [default: no] 1219 Align input files to a reference file before visualization. 1220 --alignMethod <align, cealign, super> [default: super] 1221 Alignment methodology to use for aligning input files to a 1222 reference file. 1223 --alignMode <FirstChain or Complex> [default: FirstChain] 1224 Portion of input and reference files to use for spatial alignment of 1225 input files against reference file. Possible values: FirstChain or 1226 Complex. 1227 1228 The FirstChain mode allows alignment of the first chain in each input 1229 file to the first chain in the reference file along with moving the rest 1230 of the complex to coordinate space of the reference file. The complete 1231 complex in each input file is aligned to the complete complex in reference 1232 file for the Complex mode. 1233 --alignRefFile <filename> [default: FirstInputFile] 1234 Reference input file name. The default is to use the first input file 1235 name specified using '-i, --infiles' option. 1236 --allowEmptyObjects <yes or no> [default: no] 1237 Allow creation of empty PyMOL objects corresponding to solvent and 1238 inorganic atom selections across chains and ligands in input file(s). By 1239 default, the empty objects are marked for deletion. 1240 --cavityCulled <Yes or No> [default: Yes] 1241 Cull cavities and pockets. The cavities and pockets are culled by default. 1242 This value is used to set of PyMOL parameter surface_cavity_mode as 1243 shown below: 1244 1245 No: 1 (Cavities and Pockets Only) 1246 Yes: 2 (Cavities and Pockets Culled) 1247 1248 --cavityCullSize <number> [default: 2.0] 1249 Approximate dimension of the cavity in Angstroms for detecting cavities and 1250 pockets in the interior of a macromolecule. The higher value makes PyMOL less 1251 sensitive to detection of smaller cavities. 1252 --cavityCutoff <number> [default: 3.0] 1253 Cavity cutoff in terms of number of solvent radii for detecting cavities 1254 and pockets. This value is used to set value of PyMOL parameter 1255 surface_cavity_cutoff. 1256 --cavityRadius <number> [default: 5.0] 1257 Cavity detection radius in terms of number of solvent radii for detecting 1258 cavities and pockets. The detection of larger pockets is ignored for lower 1259 value for the cavity radius. This value is used to set of PyMOL parameter 1260 surface_cavity_radius. 1261 -c, --chainIDs <First, All or ID1,ID2...> [default: First] 1262 List of chain IDs to use for visualizing macromolecules. Possible values: 1263 First, All, or a comma delimited list of chain IDs. The default is to use the 1264 chain ID for the first chain in each input file. 1265 -e, --examples 1266 Print examples. 1267 -h, --help 1268 Print this help message. 1269 -i, --infiles <infile1,infile2,infile3...> 1270 Input file names. 1271 --ignoreHydrogens <yes or no> [default: yes] 1272 Ignore hydrogens for ligand views. 1273 --labelFontID <number> [default: 7] 1274 Font ID for drawing labels. Default: 7 (Sans Bold). Valid values: 5 to 16. 1275 The specified value must be a valid PyMOL font ID. No validation is 1276 performed. The complete lists of valid font IDs is available at: 1277 pymolwiki.org/index.php/Label_font_id. Examples: 5 - Sans; 1278 7 - Sans Bold; 9 - Serif; 10 - Serif Bold. 1279 -l, --ligandIDs <Largest, All or ID1,ID2...> [default: All] 1280 List of ligand IDs to show in chains during visualizing of cavities in 1281 macromolecules. Possible values: Largest, All, or a comma delimited 1282 list of ligand IDs. The default is to show all ligands present in all or 1283 specified chains in each input file. 1284 1285 Ligands are identified using organic selection operator available in PyMOL. 1286 It'll also identify buffer molecules as ligands. The largest ligand contains 1287 the highest number of heavy atoms. 1288 -o, --outfile <outfile> 1289 Output file name. 1290 -p, --PMLOut <yes or no> [default: yes] 1291 Save PML file during generation of PSE file. 1292 -r, --residueTypes <Type,Color,ResNames,...> [default: auto] 1293 Residue types, colors, and names to generate for residue groups during 1294 '--residueTypesChain' option. It is only valid for amino acids. 1295 1296 It is a triplet of comma delimited list of amino acid residues type, residues 1297 color, and a space delimited list three letter residue names. 1298 1299 The default values for residue type, color, and name triplets are shown 1300 below: 1301 1302 Aromatic,brightorange,HIS PHE TRP TYR, 1303 Hydrophobic,orange,ALA GLY VAL LEU ILE PRO MET, 1304 Polar,palegreen,ASN GLN SER THR CYS, 1305 Positively_Charged,marine,ARG LYS, 1306 Negatively_Charged,red,ASP GLU 1307 1308 The color name must be a valid PyMOL name. No validation is performed. 1309 An amino acid name may appear across multiple residue types. All other 1310 residues are grouped under 'Other'. 1311 --residueTypesChain <yes or no> [default: auto] 1312 Chain residue types. The residue groups are generated using residue types, 1313 colors, and names specified by '--residueTypes' option. It is only valid for 1314 amino acids. By default, the residue type groups are automatically created 1315 for chains containing amino acids and skipped for chains only containing 1316 nucleic acids. 1317 --surfaceChain <yes or no> [default: auto] 1318 Surfaces around individual chain colored by hydrophobicity alone and 1319 both hydrophobicity and charge. The hydrophobicity surface is colored 1320 at residue level using Eisenberg hydrophobicity scale for residues and color 1321 gradient specified by '--surfaceColorPalette' option. The hydrophobicity and 1322 charge surface is colored [ Ref 140 ] at atom level using colors specified for 1323 groups of atoms by '--surfaceAtomTypesColors' option. This scheme allows 1324 simultaneous mapping of hyrophobicity and charge values on the surfaces. 1325 1326 This option is only valid for amino acids. By default, both surfaces are 1327 automatically created for chains containing amino acids and skipped for 1328 chains containing only nucleic acids. 1329 1330 In addition, generic surfaces colored by '--surfaceColor' are always created 1331 for chain residues containing amino acids and nucleic acids. 1332 --surfaceChainElectrostatics <yes or no> [default: no] 1333 Vacuum electrostatics contact potential surface around individual 1334 chain. A word to the wise from PyMOL documentation: The computed protein 1335 contact potentials are only qualitatively useful, due to short cutoffs, 1336 truncation, and lack of solvent "screening". 1337 1338 This option is only valid for amino acids. By default, the electrostatics surface 1339 is automatically created for chains containing amino acids and 1340 skipped for chains containing only nucleic acids. 1341 --surfaceChainComplex <yes or no> [default: no] 1342 Hydrophobic surface around chain complex. The surface is colored by 1343 hydrophobicity. It is only valid for amino acids. 1344 --surfaceComplex <yes or no> [default: no] 1345 Hydrophobic surface around complete complex. The surface is colored by 1346 hydrophobicity. It is only valid for amino acids. 1347 --surfaceAtomTypesColors <ColorType,ColorSpec,...> [default: auto] 1348 Atom colors for generating surfaces colored by hyrophobicity and charge 1349 around chains and pockets in proteins. It's a pairwise comma delimited list 1350 of atom color type and color specification for goups of atoms. 1351 1352 The default values for color types [ Ref 140 ] along wth color specifications 1353 are shown below: 1354 1355 HydrophobicAtomsColor, yellow, 1356 NegativelyChargedAtomsColor, red, 1357 PositivelyChargedAtomsColor, blue, 1358 OtherAtomsColor, gray90 1359 1360 The color names must be valid PyMOL names. 1361 1362 The color values may also be specified as space delimited RGB triplets: 1363 1364 HydrophobicAtomsColor, 0.95 0.78 0.0, 1365 NegativelyChargedAtomsColor, 1.0 0.4 0.4, 1366 PositivelyChargedAtomsColor, 0.2 0.5 0.8, 1367 OtherAtomsColor, 0.95 0.95 0.95 1368 1369 --surfaceColors <ColorName1,ColorName2> [default: salmon,lightblue] 1370 Color names for surfaces around cavities and chains. These colors are not 1371 used for surfaces and cavities colored by hydrophobicity and charge. The 1372 color names must be valid PyMOL names. 1373 --surfaceColorPalette <RedToWhite or WhiteToGreen> [default: RedToWhite] 1374 Color palette for hydrophobic surfaces around chains and pockets in proteins. 1375 Possible values: RedToWhite or WhiteToGreen from most hydrophobic amino 1376 acid to least hydrophobic. The colors values for amino acids are taken from 1377 color_h script available as part of the Script Library at PyMOL Wiki. 1378 --surfaceTransparency <number> [default: 0.25] 1379 Surface transparency for molecular surfaces. 1380 --overwrite 1381 Overwrite existing files. 1382 -w, --workingdir <dir> 1383 Location of working directory which defaults to the current directory. 1384 1385 Examples: 1386 To visualize cavities in the first chain along with the largest ligand in the 1387 first chain, solvents, and inorganics, in a PDB file, and generate a PML 1388 file, type: 1389 1390 % PyMOLVisualizeCavities.py -i Sample4.pdb -o Sample4.pml 1391 1392 To visualize cavities in all chain along with all ligands, solvents, 1393 and inorganics, in a PDB file, and generate a PML file, type: 1394 1395 % PyMOLVisualizeCavities.py -c All -l All -i Sample4.pdb 1396 -o Sample4.pml 1397 1398 To visualize cavities in the first chain at a specific cavity radius and cutoff 1399 using specifc colors for surfaces corresponding to cavities and non-cavities, 1400 and generate a PML file, type: 1401 1402 % PyMOLVisualizeCavities.py --cavityRadius 3 --cavityCutoff 5 1403 --surfaceColors "red,blue" -i Sample4.pdb -o Sample4.pml 1404 1405 To visualize cavities in the first chain along with the largest ligand in the 1406 first chain, solvents, and inorganics, in PDB files, along with aligning first 1407 chain in each input file to the first chain inand generate a PML file, type: 1408 1409 % PyMOLVisualizeCavities.py --align yes 1410 -i "Sample5.pdb,Sample6.pdb,Sample7.pdb" 1411 -o SampleOut.pml 1412 1413 Author: 1414 Manish Sud(msud@san.rr.com) 1415 1416 See also: 1417 DownloadPDBFiles.pl, PyMOLVisualizeCryoEMDensity.py, 1418 PyMOLVisualizeElectronDensity.py, PyMOLVisualizeInterfaces.py 1419 PyMOLVisualizeMacromolecules.py, PyMOLVisualizeSurfaceAndBuriedResidues.py 1420 1421 Copyright: 1422 Copyright (C) 2024 Manish Sud. All rights reserved. 1423 1424 The functionality available in this script is implemented using PyMOL, a 1425 molecular visualization system on an open source foundation originally 1426 developed by Warren DeLano. 1427 1428 This file is part of MayaChemTools. 1429 1430 MayaChemTools is free software; you can redistribute it and/or modify it under 1431 the terms of the GNU Lesser General Public License as published by the Free 1432 Software Foundation; either version 3 of the License, or (at your option) any 1433 later version. 1434 1435 """ 1436 1437 if __name__ == "__main__": 1438 main()