1 #!/bin/env python 2 # 3 # File: PyMOLVisualizeInterfaces.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 GenerateMacromolecularInterfacesVisualization() 79 80 MiscUtil.PrintInfo("\n%s: Done...\n" % ScriptName) 81 MiscUtil.PrintInfo("Total time: %s" % MiscUtil.GetFormattedElapsedTime(WallClockTime, ProcessorTime)) 82 83 def GenerateMacromolecularInterfacesVisualization(): 84 """Generate visualization for macromolecular interfaces.""" 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 WriteComplexesAndChainsViews(OutFH) 98 WriteInterfaceViews(OutFH) 99 100 OutFH.close() 101 102 # Generate PSE file as needed... 103 if OptionsInfo["PSEOut"]: 104 GeneratePyMOLSessionFile() 105 106 def WriteComplexesAndChainsViews(OutFH): 107 """Write out PML for viewing complexes and chains in input files.""" 108 109 # Setup views for input file(s)... 110 for FileIndex in range(0, len(OptionsInfo["InfilesInfo"]["InfilesNames"])): 111 # Setup PyMOL object names... 112 PyMOLObjectNamesInfo = OptionsInfo["InfilesInfo"]["PyMOLObjectNamesInfo"][FileIndex] 113 114 # Setup complex view... 115 WriteComplexView(OutFH, FileIndex, PyMOLObjectNamesInfo) 116 117 # Setup chain views... 118 SpecifiedChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex] 119 120 for ChainID in SpecifiedChainsAndLigandsInfo["ChainIDs"]: 121 WriteChainView(OutFH, FileIndex, PyMOLObjectNamesInfo, ChainID) 122 123 # Setup ligand views... 124 for LigandID in SpecifiedChainsAndLigandsInfo["LigandIDs"][ChainID]: 125 WriteChainLigandView(OutFH, FileIndex, PyMOLObjectNamesInfo, ChainID, LigandID) 126 127 # Set up ligand level group... 128 Enable, Action = [True, "close"] 129 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNamesInfo["Ligands"][ChainID][LigandID]["ChainLigandGroup"], PyMOLObjectNamesInfo["Ligands"][ChainID][LigandID]["ChainLigandGroupMembers"], Enable, Action) 130 131 # Setup Chain level group... 132 Enable, Action = [True, "open"] 133 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNamesInfo["Chains"][ChainID]["ChainGroup"], PyMOLObjectNamesInfo["Chains"][ChainID]["ChainGroupMembers"], Enable, Action) 134 135 # Set up complex level group... 136 Enable, Action = [True, "close"] 137 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNamesInfo["PDBGroup"], PyMOLObjectNamesInfo["PDBGroupMembers"], Enable, Action) 138 139 # Delete empty PyMOL objects... 140 DeleteEmptyPyMOLObjects(OutFH, FileIndex, PyMOLObjectNamesInfo) 141 142 def WriteInterfaceViews(OutFH): 143 """Write out PML for viewing macromolecular interfaces among specified chains.""" 144 145 InterfaceChainsAndResiduesInfo = OptionsInfo["InfilesInfo"]["InterfaceChainsAndResiduesInfo"] 146 if InterfaceChainsAndResiduesInfo is None: 147 return 148 149 PyMOLInterfaceObjectNamesInfo = OptionsInfo["InfilesInfo"]["PyMOLInterfaceObjectNamesInfo"] 150 InterfaceChainPairsAndResiduesInfo = OptionsInfo["InfilesInfo"]["InterfaceChainPairsAndResiduesInfo"] 151 152 FirstInterfaceID = True 153 for InterfaceID in InterfaceChainsAndResiduesInfo["InterfaceIDs"]: 154 WriteInterfacePolarContactsView(OutFH, InterfaceID, InterfaceChainPairsAndResiduesInfo, PyMOLInterfaceObjectNamesInfo) 155 WriteInterfaceHydrophobicContactsView(OutFH, InterfaceID, InterfaceChainPairsAndResiduesInfo, PyMOLInterfaceObjectNamesInfo) 156 157 for InterfaceChainID in InterfaceChainsAndResiduesInfo["InterfaceChainIDs"][InterfaceID]: 158 ChainID = InterfaceChainsAndResiduesInfo["ChainIDs"][InterfaceID][InterfaceChainID] 159 ResNums = InterfaceChainsAndResiduesInfo["ChainIDsResNums"][InterfaceID][InterfaceChainID] 160 ComplexName = InterfaceChainsAndResiduesInfo["ChainIDsComplexNames"][InterfaceID][InterfaceChainID] 161 FileIndex = InterfaceChainsAndResiduesInfo["ChainIDsInfileIndices"][InterfaceID][InterfaceChainID] 162 163 WriteInterfaceChainView(OutFH, FileIndex, InterfaceID, InterfaceChainID, ChainID, ResNums, ComplexName, PyMOLInterfaceObjectNamesInfo) 164 165 # Setup interface Chain level group... 166 Enable, Action = [True, "open"] 167 GenerateAndWritePMLForGroup(OutFH, PyMOLInterfaceObjectNamesInfo["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainGroup"], PyMOLInterfaceObjectNamesInfo["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainGroupMembers"], Enable, Action) 168 169 if FirstInterfaceID: 170 FirstInterfaceID = False 171 Enable, Action = [True, "open"] 172 else: 173 Enable, Action = [True, "close"] 174 175 GenerateAndWritePMLForGroup(OutFH, PyMOLInterfaceObjectNamesInfo["InterfaceIDs"][InterfaceID]["InterfaceIDGroup"], PyMOLInterfaceObjectNamesInfo["InterfaceIDs"][InterfaceID]["InterfaceIDGroupMembers"], Enable, Action) 176 177 # Setup interfaces level group... 178 Enable, Action = [True, "open"] 179 GenerateAndWritePMLForGroup(OutFH, PyMOLInterfaceObjectNamesInfo["InterfacesGroup"], PyMOLInterfaceObjectNamesInfo["InterfacesGroupMembers"], Enable, Action) 180 181 DeleteEmptyPyMOLInterfaceObjects(OutFH) 182 183 # Setup orientation... 184 OutFH.write("""\ncmd.orient("visible", animate = -1)\n""") 185 186 def WritePMLHeader(OutFH, ScriptName): 187 """Write out PML setting up complex view.""" 188 189 HeaderInfo = PyMOLUtil.SetupPMLHeaderInfo(ScriptName) 190 OutFH.write("%s\n" % HeaderInfo) 191 192 def WritePyMOLParameters(OutFH): 193 """Write out PyMOL global parameters.""" 194 195 PMLCmds = [] 196 PMLCmds.append("""cmd.set("transparency", %.2f, "", 0)""" % (OptionsInfo["SurfaceTransparency"])) 197 PMLCmds.append("""cmd.set("label_font_id", %s)""" % (OptionsInfo["LabelFontID"])) 198 PML = "\n".join(PMLCmds) 199 200 OutFH.write("""\n""\n"Setting up PyMOL gobal parameters..."\n""\n""") 201 OutFH.write("%s\n" % PML) 202 203 def WriteComplexView(OutFH, FileIndex, PyMOLObjectNames): 204 """Write out PML for viewing polymer complex.""" 205 206 # Setup complex... 207 Infile = OptionsInfo["InfilesInfo"]["InfilesNames"][FileIndex] 208 PML = PyMOLUtil.SetupPMLForPolymerComplexView(PyMOLObjectNames["Complex"], Infile, True) 209 OutFH.write("""\n""\n"Loading %s and setting up view for complex..."\n""\n""" % Infile) 210 OutFH.write("%s\n" % PML) 211 212 if OptionsInfo["SurfaceComplex"]: 213 # Setup hydrophobic surface... 214 PML = PyMOLUtil.SetupPMLForHydrophobicSurfaceView(PyMOLObjectNames["ComplexHydrophobicSurface"], PyMOLObjectNames["Complex"], ColorPalette = OptionsInfo["SurfaceColorPalette"], Enable = False) 215 OutFH.write("\n%s\n" % PML) 216 217 # Setup complex group... 218 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["ComplexGroup"], PyMOLObjectNames["ComplexGroupMembers"], False, "close") 219 220 def WriteChainView(OutFH, FileIndex, PyMOLObjectNames, ChainID): 221 """Write out PML for viewing chain.""" 222 223 OutFH.write("""\n""\n"Setting up views for chain %s..."\n""\n""" % ChainID) 224 225 ChainComplexName = PyMOLObjectNames["Chains"][ChainID]["ChainComplex"] 226 227 # Setup chain complex group view... 228 WriteChainComplexViews(OutFH, FileIndex, PyMOLObjectNames, ChainID) 229 230 # Setup chain view... 231 WriteChainAloneViews(OutFH, FileIndex, PyMOLObjectNames, ChainID) 232 233 # Setup chain solvent view... 234 PML = PyMOLUtil.SetupPMLForSolventView(PyMOLObjectNames["Chains"][ChainID]["Solvent"], ChainComplexName, False) 235 OutFH.write("\n%s\n" % PML) 236 237 # Setup chain inorganic view... 238 PML = PyMOLUtil.SetupPMLForInorganicView(PyMOLObjectNames["Chains"][ChainID]["Inorganic"], ChainComplexName, False) 239 OutFH.write("\n%s\n" % PML) 240 241 def WriteChainComplexViews(OutFH, FileIndex, PyMOLObjectNames, ChainID): 242 """Write chain complex views.""" 243 244 # Setup chain complex... 245 ChainComplexName = PyMOLObjectNames["Chains"][ChainID]["ChainComplex"] 246 PML = PyMOLUtil.SetupPMLForPolymerChainComplexView(ChainComplexName, PyMOLObjectNames["Complex"], ChainID, True) 247 OutFH.write("%s\n" % PML) 248 249 if OptionsInfo["SurfaceChainComplex"]: 250 # Setup hydrophobic surface... 251 PML = PyMOLUtil.SetupPMLForHydrophobicSurfaceView(PyMOLObjectNames["Chains"][ChainID]["ChainComplexHydrophobicSurface"], ChainComplexName, ColorPalette = OptionsInfo["SurfaceColorPalette"], Enable = False) 252 OutFH.write("\n%s\n" % PML) 253 254 # Setup chain complex group... 255 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroup"], PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroupMembers"], False, "close") 256 257 def WriteChainAloneViews(OutFH, FileIndex, PyMOLObjectNames, ChainID): 258 """Write individual chain views.""" 259 260 ChainComplexName = PyMOLObjectNames["Chains"][ChainID]["ChainComplex"] 261 262 # Setup chain view... 263 ChainName = PyMOLObjectNames["Chains"][ChainID]["ChainAlone"] 264 PML = PyMOLUtil.SetupPMLForPolymerChainView(ChainName, ChainComplexName, True) 265 OutFH.write("\n%s\n" % PML) 266 267 # Setup a non-interface chain view... 268 NonInterfaceChainName = PyMOLObjectNames["Chains"][ChainID]["ChainAloneNonInterface"] 269 270 InterfaceResNums = OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex]["InterfaceResNums"][ChainID] 271 InterfaceResNumsSelection = "+".join(InterfaceResNums) 272 273 Selection = "%s and chain %s and polymer and (not (resi %s))" % (ChainComplexName, ChainID, InterfaceResNumsSelection) 274 PML = PyMOLUtil.SetupPMLForSelectionDisplayView(NonInterfaceChainName, Selection, "cartoon", Enable = False) 275 OutFH.write("\n%s\n" % PML) 276 277 if GetChainAloneContainsSurfacesStatus(FileIndex, ChainID): 278 # Setup a generic colored surface... 279 PML = PyMOLUtil.SetupPMLForSurfaceView(PyMOLObjectNames["Chains"][ChainID]["ChainAloneSurface"], NonInterfaceChainName, Enable = False, Color = OptionsInfo["SurfaceNonInterfaceColor"]) 280 OutFH.write("\n%s\n" % PML) 281 282 if GetChainAloneSurfaceChainStatus(FileIndex, ChainID): 283 # Setup surface colored by hydrophobicity... 284 PML = PyMOLUtil.SetupPMLForHydrophobicSurfaceView(PyMOLObjectNames["Chains"][ChainID]["ChainAloneHydrophobicSurface"], NonInterfaceChainName, ColorPalette = OptionsInfo["SurfaceColorPalette"], Enable = False) 285 OutFH.write("\n%s\n" % PML) 286 287 # Setup surface colored by hyrdophobicity and charge... 288 PML = PyMOLUtil.SetupPMLForHydrophobicAndChargeSurfaceView(PyMOLObjectNames["Chains"][ChainID]["ChainAloneHydrophobicChargeSurface"], NonInterfaceChainName, OptionsInfo["AtomTypesColorNames"]["HydrophobicAtomsColor"], OptionsInfo["AtomTypesColorNames"]["NegativelyChargedAtomsColor"], OptionsInfo["AtomTypesColorNames"]["PositivelyChargedAtomsColor"], OptionsInfo["AtomTypesColorNames"]["OtherAtomsColor"], Enable = False, DisplayAs = None) 289 OutFH.write("\n%s\n" % PML) 290 291 if GetChainAloneSurfaceChainElectrostaticsStatus(FileIndex, ChainID): 292 # Setup electrostatics surface... 293 SelectionObjectName = NonInterfaceChainName 294 ElectrostaticsGroupName = PyMOLObjectNames["Chains"][ChainID]["ChainAloneElectrostaticsGroup"] 295 ElectrostaticsGroupMembers = PyMOLObjectNames["Chains"][ChainID]["ChainAloneElectrostaticsGroupMembers"] 296 WriteSurfaceElectrostaticsView("Chain", OutFH, SelectionObjectName, ElectrostaticsGroupName, ElectrostaticsGroupMembers) 297 298 # Setup surface group... 299 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["Chains"][ChainID]["ChainAloneSurfaceGroup"], PyMOLObjectNames["Chains"][ChainID]["ChainAloneSurfaceGroupMembers"], True, "open") 300 301 # Setup a non-interface group... 302 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["Chains"][ChainID]["ChainAloneNonInterfaceGroup"], PyMOLObjectNames["Chains"][ChainID]["ChainAloneNonInterfaceGroupMembers"], True, "open") 303 304 # Setup chain group... 305 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroup"], PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroupMembers"], True, "close") 306 307 def WriteChainLigandView(OutFH, FileIndex, PyMOLObjectNames, ChainID, LigandID): 308 """Write out PML for viewing ligand in a chain.""" 309 310 GroupID = "Ligand" 311 ComplexName = PyMOLObjectNames["Chains"][ChainID]["ChainComplex"] 312 LigandName = PyMOLObjectNames["Ligands"][ChainID][LigandID]["Ligand"] 313 314 # Setup main object... 315 GroupTypeObjectID = "%s" % (GroupID) 316 GroupTypeObjectName = PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupTypeObjectID] 317 318 OutFH.write("""\n""\n"Setting up views for ligand %s in chain %s..."\n""\n""" % (LigandID, ChainID)) 319 PML = PyMOLUtil.SetupPMLForLigandView(GroupTypeObjectName, ComplexName, LigandID, Enable = True, IgnoreHydrogens = OptionsInfo["IgnoreHydrogens"]) 320 OutFH.write("%s\n" % PML) 321 322 # Setup ball and stick view... 323 BallAndStickNameID = "%sBallAndStick" % (GroupID) 324 BallAndStickName = PyMOLObjectNames["Ligands"][ChainID][LigandID][BallAndStickNameID] 325 PML = PyMOLUtil.SetupPMLForBallAndStickView(BallAndStickName, GroupTypeObjectName, Enable = False) 326 OutFH.write("\n%s\n" % PML) 327 328 # Setup group.... 329 GroupNameID = "%sGroup" % (GroupID) 330 GroupMembersID = "%sGroupMembers" % (GroupID) 331 GroupName = PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupNameID] 332 GroupMembers = PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupMembersID] 333 334 Action = "open" 335 Enable = True 336 GenerateAndWritePMLForGroup(OutFH, GroupName, GroupMembers, Enable, Action) 337 338 def WriteInterfacePolarContactsView(OutFH, InterfaceID, InterfaceChainPairsAndResiduesInfo, PyMOLObjectNames): 339 """Write out PML for viewing polar contacts between interface residues.""" 340 341 if not OptionsInfo["InterfacePolarContacts"]: 342 return 343 344 WriteInterfaceContactsView("InterfacePolarConatcts", OutFH, InterfaceID, InterfaceChainPairsAndResiduesInfo, PyMOLObjectNames) 345 346 def WriteInterfaceHydrophobicContactsView(OutFH, InterfaceID, InterfaceChainPairsAndResiduesInfo, PyMOLObjectNames): 347 """Write out PML for viewing hydrophobic contacts between interface residues.""" 348 349 if not OptionsInfo["InterfaceHydrophobicContacts"]: 350 return 351 352 WriteInterfaceContactsView("InterfaceHydrophobicContacts", OutFH, InterfaceID, InterfaceChainPairsAndResiduesInfo, PyMOLObjectNames) 353 354 def WriteInterfaceContactsView(Mode, OutFH, InterfaceID, InterfaceChainPairsAndResiduesInfo, PyMOLObjectNames): 355 """Write out PML for viewing polar or hydrophobic contacts between interface residues.""" 356 357 InterfacePolarContacts = True if re.match("^InterfacePolarConatcts$", Mode, re.I) else False 358 359 ChainIDs1, ChainIDs2 = InterfaceChainPairsAndResiduesInfo["ChainIDsPairs"][InterfaceID] 360 ResNums1, ResNums2 = InterfaceChainPairsAndResiduesInfo["ChainIDsResNumsPairs"][InterfaceID] 361 362 FileIndex1, FileIndex2 = InterfaceChainPairsAndResiduesInfo["InfileIndicesPairs"][InterfaceID] 363 ComplexName1 = OptionsInfo["InfilesInfo"]["PyMOLObjectNamesInfo"][FileIndex1]["Complex"] 364 ComplexName2 = OptionsInfo["InfilesInfo"]["PyMOLObjectNamesInfo"][FileIndex2]["Complex"] 365 366 Selection1 = SetupSelectionForInterfaceContactsView(ComplexName1, ChainIDs1, ResNums1) 367 Selection2 = SetupSelectionForInterfaceContactsView(ComplexName2, ChainIDs2, ResNums2) 368 369 if InterfacePolarContacts: 370 ContactsName = PyMOLObjectNames["InterfaceIDs"][InterfaceID]["PolarContacts"] 371 ContactsColor = OptionsInfo["InterfacePolarContactsColor"] 372 ContactsCutoff = OptionsInfo["InterfaceContactsCutoff"] 373 374 PML = PyMOLUtil.SetupPMLForPolarContactsView(ContactsName, Selection1, Selection2, Enable = False, Color = ContactsColor, Cutoff = ContactsCutoff) 375 else: 376 ContactsName = PyMOLObjectNames["InterfaceIDs"][InterfaceID]["HydrophobicContacts"] 377 ContactsColor = OptionsInfo["InterfaceHydrophobicContactsColor"] 378 ContactsCutoff = OptionsInfo["InterfaceContactsCutoff"] 379 380 PML = PyMOLUtil.SetupPMLForHydrophobicContactsView(ContactsName, Selection1, Selection2, Enable = False, Color = ContactsColor, Cutoff = ContactsCutoff) 381 382 OutFH.write("\n%s\n" % PML) 383 384 OutFH.write("""cmd.set("label_color", "%s", "%s")\n""" % (ContactsColor, ContactsName)) 385 386 def SetupSelectionForInterfaceContactsView(ComplexName, ChainIDs, ResNums): 387 """Setup a selection for generating polar or hyrophobic contacts for an interface.""" 388 389 ChainSelections = [] 390 391 for ChainID in ChainIDs: 392 ChainResNumsSelection = "+".join(ResNums["ResNums"][ChainID]) 393 Selection = "(%s and chain %s and polymer and (resi %s))" % (ComplexName, ChainID, ChainResNumsSelection) 394 ChainSelections.append(Selection) 395 396 Selection = " or ".join(ChainSelections) 397 398 return Selection 399 400 def WriteInterfaceChainView(OutFH, FileIndex, InterfaceID, InterfaceChainID, ChainID, ResiduesNums, ComplexName, PyMOLObjectNames): 401 """Write out PML for viewing interface residues in a chain.""" 402 403 OutFH.write("""\n""\n"Setting up interface views for interface in %s..."\n""\n""" % InterfaceChainID) 404 405 ResiduesNumsSelection = "+".join(ResiduesNums) 406 407 # Setup a chain for interface residues... 408 ChainName = PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["Chain"] 409 Selection = "%s and chain %s and polymer and (resi %s)" % (ComplexName, ChainID, ResiduesNumsSelection) 410 411 PML = PyMOLUtil.SetupPMLForSelectionDisplayView(ChainName, Selection, "lines", Enable = True) 412 OutFH.write("\n%s\n" % PML) 413 414 OutFH.write("""cmd.set("label_color", "%s", "%s")\n""" % (OptionsInfo["InterfaceLabelColor"], ChainName)) 415 416 WriteInterfaceChainResidueTypesView(OutFH, FileIndex, InterfaceID, InterfaceChainID, ChainID, PyMOLObjectNames) 417 418 if GetInterfaceContainsSurfacesStatus(FileIndex, ChainID): 419 # Setup generic colored surface... 420 PML = PyMOLUtil.SetupPMLForSurfaceView(PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainSurface"], ChainName, Color = OptionsInfo["SurfaceInterfaceColor"], Enable = True, DisplayAs = "lines") 421 OutFH.write("\n%s\n" % PML) 422 423 if GetInterfaceSurfaceChainStatus(FileIndex, ChainID): 424 # Setup surface colored by hydrophobicity... 425 PML = PyMOLUtil.SetupPMLForHydrophobicSurfaceView(PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainHydrophobicSurface"], ChainName, ColorPalette = OptionsInfo["SurfaceColorPalette"], Enable = False, DisplayAs = "lines") 426 OutFH.write("\n%s\n" % PML) 427 428 # Setup surface colored by hyrdophobicity and charge... 429 PML = PyMOLUtil.SetupPMLForHydrophobicAndChargeSurfaceView(PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainHydrophobicChargeSurface"], ChainName, OptionsInfo["AtomTypesColorNames"]["HydrophobicAtomsColor"], OptionsInfo["AtomTypesColorNames"]["NegativelyChargedAtomsColor"], OptionsInfo["AtomTypesColorNames"]["PositivelyChargedAtomsColor"], OptionsInfo["AtomTypesColorNames"]["OtherAtomsColor"], Enable = False, DisplayAs = "lines") 430 OutFH.write("\n%s\n" % PML) 431 432 if GetInterfaceSurfaceChainElectrostaticsStatus(FileIndex, ChainID): 433 # Setup electrostatics surface... 434 SelectionObjectName = ChainName 435 ElectrostaticsGroupName = PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainElectrostaticsGroup"] 436 ElectrostaticsGroupMembers = PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainElectrostaticsGroupMembers"] 437 WriteSurfaceElectrostaticsView("InterfaceResidues", OutFH, SelectionObjectName, ElectrostaticsGroupName, ElectrostaticsGroupMembers) 438 439 # Setup surface group... 440 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainSurfaceGroup"], PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainSurfaceGroupMembers"], True, "open") 441 442 # Setup chain group... 443 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainGroup"], PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainGroupMembers"], True, "close") 444 445 def WriteInterfaceChainResidueTypesView(OutFH, FileIndex, InterfaceID, InterfaceChainID, ChainID, PyMOLObjectNames): 446 """Write out PML for viewing interface residue types for a chain.""" 447 448 if not GetInterfaceResidueTypesStatus(FileIndex, ChainID): 449 return 450 451 ChainName = PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["Chain"] 452 453 # Setup residue types objects... 454 ResiduesGroupIDPrefix = "ChainResidues" 455 for SubGroupType in ["Aromatic", "Hydrophobic", "Polar", "Positively_Charged", "Negatively_Charged", "Other"]: 456 SubGroupID = re.sub("_", "", SubGroupType) 457 458 ResiduesObjectID = "%s%sResidues" % (ResiduesGroupIDPrefix, SubGroupID) 459 ResiduesObjectName = PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID][ResiduesObjectID] 460 461 ResiduesSurfaceObjectID = "%s%sSurface" % (ResiduesGroupIDPrefix, SubGroupID) 462 ResiduesSurfaceObjectName = PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID][ResiduesSurfaceObjectID] 463 464 ResiduesColor = OptionsInfo["ResidueTypesParams"][SubGroupType]["Color"] 465 ResiduesNames = OptionsInfo["ResidueTypesParams"][SubGroupType]["Residues"] 466 467 NegateResidueNames = True if re.match("^Other$", SubGroupType, re.I) else False 468 WriteResidueTypesResiduesAndSurfaceView(OutFH, ChainName, ResiduesObjectName, ResiduesSurfaceObjectName, ResiduesColor, ResiduesNames, NegateResidueNames) 469 470 # Setup residue type sub groups... 471 ResiduesSubGroupID = "%s%sGroup" % (ResiduesGroupIDPrefix, SubGroupID) 472 ResiduesSubGroupMembersID = "%s%sGroupMembers" % (ResiduesGroupIDPrefix, SubGroupID) 473 474 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID][ResiduesSubGroupID], PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID][ResiduesSubGroupMembersID], True, "close") 475 476 # Setup residue types group... 477 GenerateAndWritePMLForGroup(OutFH, PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainResiduesGroup"], PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainResiduesGroupMembers"], False, "close") 478 479 def WriteResidueTypesResiduesAndSurfaceView(OutFH, SelectionObjectName, Name, SurfaceName, ResiduesColor, ResiduesNames, NegateResidueNames): 480 """Write residue types residues and surface view.""" 481 482 ResidueNamesSelection = "+".join(ResiduesNames) 483 if NegateResidueNames: 484 Selection = "%s and (not resn %s)" % (SelectionObjectName, ResidueNamesSelection) 485 else: 486 Selection = "%s and (resn %s)" % (SelectionObjectName, ResidueNamesSelection) 487 488 # Setup residues... 489 PML = PyMOLUtil.SetupPMLForSelectionDisplayView(Name, Selection, "lines", ResiduesColor, True) 490 OutFH.write("\n%s\n" % PML) 491 492 # Setup surface... 493 PML = PyMOLUtil.SetupPMLForSelectionDisplayView(SurfaceName, Selection, "surface", ResiduesColor, True) 494 OutFH.write("\n%s\n" % PML) 495 496 def WriteSurfaceElectrostaticsView(Mode, OutFH, SelectionObjectName, ElectrostaticsGroupName, ElectrostaticsGroupMembers): 497 """Write out PML for viewing surface electrostatics.""" 498 499 if len(ElectrostaticsGroupMembers) == 5: 500 Name, ContactPotentialName, MapName, LegendName, VolumeName = ElectrostaticsGroupMembers 501 else: 502 Name, ContactPotentialName, MapName, LegendName = ElectrostaticsGroupMembers 503 VolumeName = None 504 505 PMLCmds = [] 506 507 # Setup chain... 508 PMLCmds.append("""cmd.create("%s", "(%s)")""" % (Name, SelectionObjectName)) 509 510 # Setup vacuum electrostatics surface along with associated objects... 511 PMLCmds.append("""util.protein_vacuum_esp("%s", mode=2, quiet=0, _self=cmd)""" % (Name)) 512 513 PMLCmds.append("""cmd.set_name("%s_e_chg", "%s")""" % (Name, ContactPotentialName)) 514 if re.match("^Chain$", Mode, re.I): 515 DisplayStyle = "cartoon" 516 else: 517 DisplayStyle = "lines" 518 PMLCmds.append("""cmd.show("%s", "(%s)")""" % (DisplayStyle, ContactPotentialName)) 519 PMLCmds.append(PyMOLUtil.SetupPMLForEnableDisable(ContactPotentialName, Enable = True)) 520 521 PMLCmds.append("""cmd.set_name("%s_e_map", "%s")""" % (Name, MapName)) 522 PMLCmds.append(PyMOLUtil.SetupPMLForEnableDisable(MapName, Enable = False)) 523 524 PMLCmds.append("""cmd.set_name("%s_e_pot", "%s")""" % (Name, LegendName)) 525 PMLCmds.append(PyMOLUtil.SetupPMLForEnableDisable(LegendName, Enable = False)) 526 527 if VolumeName is not None: 528 PMLCmds.append("""cmd.volume("%s", "%s", "%s", "(%s)")""" % (VolumeName, MapName, "esp", Name)) 529 PMLCmds.append(PyMOLUtil.SetupPMLForEnableDisable(VolumeName, Enable = False)) 530 531 # Delete name and take it out from the group membership. It is 532 # is already part of ContactPotential object. 533 PMLCmds.append("""cmd.delete("%s")""" % (Name)) 534 ElectrostaticsGroupMembers.pop(0) 535 536 PML = "\n".join(PMLCmds) 537 538 OutFH.write("\n%s\n" % PML) 539 540 # Setup group... 541 GenerateAndWritePMLForGroup(OutFH, ElectrostaticsGroupName, ElectrostaticsGroupMembers, False, "close") 542 543 def GenerateAndWritePMLForGroup(OutFH, GroupName, GroupMembers, Enable = False, Action = "close"): 544 """Generate and write PML for group.""" 545 546 PML = PyMOLUtil.SetupPMLForGroup(GroupName, GroupMembers, Enable, Action) 547 OutFH.write("""\n""\n"Setting up group %s..."\n""\n""" % GroupName) 548 OutFH.write("%s\n" % PML) 549 550 def GeneratePyMOLSessionFile(): 551 """Generate PME file from PML file.""" 552 553 PSEOutfile = OptionsInfo["PSEOutfile"] 554 PMLOutfile = OptionsInfo["PMLOutfile"] 555 556 MiscUtil.PrintInfo("\nGenerating file %s..." % PSEOutfile) 557 558 PyMOLUtil.ConvertPMLFileToPSEFile(PMLOutfile, PSEOutfile) 559 560 if not os.path.exists(PSEOutfile): 561 MiscUtil.PrintWarning("Failed to generate PSE file, %s..." % (PSEOutfile)) 562 563 if not OptionsInfo["PMLOut"]: 564 MiscUtil.PrintInfo("Deleting file %s..." % PMLOutfile) 565 os.remove(PMLOutfile) 566 567 def DeleteEmptyPyMOLObjects(OutFH, FileIndex, PyMOLObjectNames): 568 """Delete empty PyMOL objects.""" 569 570 if OptionsInfo["AllowEmptyObjects"]: 571 return 572 573 SpecifiedChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex] 574 for ChainID in SpecifiedChainsAndLigandsInfo["ChainIDs"]: 575 OutFH.write("""\n""\n"Checking and deleting empty objects for chain %s..."\n""\n""" % (ChainID)) 576 577 # Delete any chain level objects... 578 WritePMLToCheckAndDeleteEmptyObjects(OutFH, PyMOLObjectNames["Chains"][ChainID]["Solvent"]) 579 WritePMLToCheckAndDeleteEmptyObjects(OutFH, PyMOLObjectNames["Chains"][ChainID]["Inorganic"]) 580 581 def DeleteEmptyPyMOLInterfaceObjects(OutFH): 582 """Delete empty PyMOL interface objects.""" 583 584 if OptionsInfo["AllowEmptyObjects"]: 585 return 586 587 InterfaceChainsAndResiduesInfo = OptionsInfo["InfilesInfo"]["InterfaceChainsAndResiduesInfo"] 588 PyMOLInterfaceObjectNamesInfo = OptionsInfo["InfilesInfo"]["PyMOLInterfaceObjectNamesInfo"] 589 590 if InterfaceChainsAndResiduesInfo is None: 591 return 592 593 for InterfaceID in InterfaceChainsAndResiduesInfo["InterfaceIDs"]: 594 for InterfaceChainID in InterfaceChainsAndResiduesInfo["InterfaceChainIDs"][InterfaceID]: 595 ChainID = InterfaceChainsAndResiduesInfo["ChainIDs"][InterfaceID][InterfaceChainID] 596 FileIndex = InterfaceChainsAndResiduesInfo["ChainIDsInfileIndices"][InterfaceID][InterfaceChainID] 597 598 # Delete interface residue type objects... 599 DeleteEmptyInterfaceChainResidueTypesObjects(OutFH, FileIndex, InterfaceID, InterfaceChainID, ChainID, PyMOLInterfaceObjectNamesInfo) 600 601 def DeleteEmptyInterfaceChainResidueTypesObjects(OutFH, FileIndex, InterfaceID, InterfaceChainID, ChainID, PyMOLObjectNames): 602 """Delete empty interface chain residue objects.""" 603 604 if not GetInterfaceResidueTypesStatus(FileIndex, ChainID): 605 return 606 607 ResiduesGroupIDPrefix = "ChainResidues" 608 for GroupType in ["Aromatic", "Hydrophobic", "Polar", "Positively_Charged", "Negatively_Charged", "Other"]: 609 GroupID = re.sub("_", "", GroupType) 610 611 ResiduesGroupID = "%s%sGroup" % (ResiduesGroupIDPrefix, GroupID) 612 GroupName = PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID][ResiduesGroupID] 613 614 GroupObjectNamesList = [] 615 616 ResiduesObjectID = "%s%sResidues" % (ResiduesGroupIDPrefix, GroupID) 617 ResiduesObjectName = PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID][ResiduesObjectID] 618 GroupObjectNamesList.append(ResiduesObjectName) 619 620 ResiduesSurfaceObjectID = "%s%sSurface" % (ResiduesGroupIDPrefix, GroupID) 621 ResiduesSurfaceObjectName = PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID][ResiduesSurfaceObjectID] 622 GroupObjectNamesList.append(ResiduesSurfaceObjectName) 623 624 GroupObjectNames = ",".join(GroupObjectNamesList) 625 WritePMLToCheckAndDeleteEmptyObjects(OutFH, GroupObjectNames, GroupName) 626 627 def WritePMLToCheckAndDeleteEmptyObjects(OutFH, ObjectName, ParentObjectName = None): 628 """Write PML to check and delete empty PyMOL objects.""" 629 630 if ParentObjectName is None: 631 PML = """CheckAndDeleteEmptyObjects("%s")""" % (ObjectName) 632 else: 633 PML = """CheckAndDeleteEmptyObjects("%s", "%s")""" % (ObjectName, ParentObjectName) 634 635 OutFH.write("%s\n" % PML) 636 637 def RetrieveInfilesInfo(): 638 """Retrieve information for input files.""" 639 640 InfilesInfo = {} 641 642 InfilesInfo["InfilesNames"] = [] 643 InfilesInfo["InfilesRoots"] = [] 644 InfilesInfo["ChainsAndLigandsInfo"] = [] 645 InfilesInfo["SpecifiedChainsAndLigandsInfo"] = [] 646 647 InfilesInfo["PyMOLObjectNamesInfo"] = [] 648 649 InfilesInfo["SingleInfileMode"] = False 650 InfilesInfo["InterfaceChainsAndResiduesInfo"] = None 651 InfilesInfo["InterfaceChainPairsAndResiduesInfo"] = None 652 653 InfilesInfo["PyMOLInterfaceObjectNamesInfo"] = None 654 655 InfilesCount = 0 656 for Infile in OptionsInfo["InfilesNames"]: 657 InfilesCount += 1 658 FileDir, FileName, FileExt = MiscUtil.ParseFileName(Infile) 659 InfileRoot = FileName 660 661 ChainsAndLigandInfo = PyMOLUtil.GetChainsAndLigandsInfo(Infile, InfileRoot) 662 663 InfilesInfo["InfilesNames"].append(Infile) 664 InfilesInfo["InfilesRoots"].append(InfileRoot) 665 InfilesInfo["ChainsAndLigandsInfo"].append(ChainsAndLigandInfo) 666 667 if InfilesCount > 2: 668 MiscUtil.PrintError("Number of input files, %s, specified using \"-i, --infiles\" option is not valid. Number of allowed files: 1 or 2" % (InfilesCount)) 669 670 InfilesInfo["SingleInfileMode"] = True if InfilesCount == 1 else False 671 672 OptionsInfo["InfilesInfo"] = InfilesInfo 673 674 def ProcessInterfaceChainIDs(): 675 """Process specified interface chain IDs for input files.""" 676 677 ValidateInterfaceChainIDs() 678 679 SetupChainsAndLigandsInfo() 680 SetupPyMOLObjectNamesInfo() 681 682 SetupInterfaceChainPairsAndResiduesInfo() 683 ProcessInterfaceChainPairsAndResiduesInfo() 684 685 SetupPyMOLInterfaceObjectNamesInfo() 686 687 def ValidateInterfaceChainIDs(): 688 """Check for the presence of interface IDs in input file(s).""" 689 690 if re.match("^auto$", OptionsInfo["InterfaceChainIDs"], re.I): 691 AutoAssignInterfaceChainIDs() 692 SetupInfilesInterfaceChainIDsLists() 693 return 694 695 MiscUtil.PrintInfo("\nValidating interface chain IDs...") 696 697 # Check for the presences of interface chain IDs across input files.. 698 SingleInfileMode = OptionsInfo["InfilesInfo"]["SingleInfileMode"] 699 Infile1ChainIDs = OptionsInfo["InfilesInfo"]["ChainsAndLigandsInfo"][0]["ChainIDs"] 700 Infile2ChainIDs = [] 701 if not SingleInfileMode: 702 Infile2ChainIDs = OptionsInfo["InfilesInfo"]["ChainsAndLigandsInfo"][1]["ChainIDs"] 703 704 InterfaceChainIDsList = OptionsInfo["InterfaceChainIDsList"] 705 706 for Index in range(0, len(InterfaceChainIDsList), 2): 707 ChainIDs1 = InterfaceChainIDsList[Index] 708 ChainIDs2 = InterfaceChainIDsList[Index + 1] 709 710 for ChainID in ChainIDs1: 711 if not ChainID in Infile1ChainIDs: 712 MiscUtil.PrintError("The chain ID, %s, specified using \"-c, --chainIDs\" for a chain IDs pairs, \"%s,%s\", must be present in first input file." % (ChainID, "+".join(ChainIDs1), "+".join(ChainIDs2))) 713 714 for ChainID in ChainIDs2: 715 if SingleInfileMode: 716 if not ChainID in Infile1ChainIDs: 717 MiscUtil.PrintError("The chain ID, %s, specified using \"-c, --chainIDs\" for a chain IDs pairs, \"%s,%s\", must be present in first input file." % (ChainID, "+".join(ChainIDs1), "+".join(ChainIDs2))) 718 else: 719 if not ChainID in Infile2ChainIDs: 720 MiscUtil.PrintError("The chain ID, %s, specified using \"-c, --chainIDs\" for a chain IDs pairs, \"%s,%s\", must be present in second input file." % (ChainID, "+".join(ChainIDs1), "+".join(ChainIDs2))) 721 722 # Check for any duplicate interface chain IDs specifications... 723 CanonicalInterfaceIDsMap = {} 724 725 for Index in range(0, len(InterfaceChainIDsList), 2): 726 ChainIDs1 = InterfaceChainIDsList[Index] 727 ChainIDs2 = InterfaceChainIDsList[Index + 1] 728 InterfaceID = "%s,%s" % ("+".join(ChainIDs1), "+".join(ChainIDs2)) 729 730 SortedChainIDs1 = sorted(ChainIDs1) 731 SortedChainIDs2 = sorted(ChainIDs2) 732 CanonicalInterfaceID = "%s,%s" % ("+".join(SortedChainIDs1), "+".join(SortedChainIDs2)) 733 734 if CanonicalInterfaceID in CanonicalInterfaceIDsMap: 735 MiscUtil.PrintError("The chain ID pair, \"%s\", using \"-c, --chainIDs\", option has been specified multiple times, \"%s\"." % (CanonicalInterfaceIDsMap[CanonicalInterfaceID], OptionsInfo["InterfaceChainIDs"])) 736 else: 737 CanonicalInterfaceIDsMap[CanonicalInterfaceID] = InterfaceID 738 739 SetupInfilesInterfaceChainIDsLists() 740 741 def SetupInfilesInterfaceChainIDsLists(): 742 """Setup interface chain IDs list for infiles.""" 743 744 Infie1InterfaceChainIDsList = [] 745 Infie2InterfaceChainIDsList = [] 746 747 SingleInfileMode = OptionsInfo["InfilesInfo"]["SingleInfileMode"] 748 InterfaceChainIDsList = OptionsInfo["InterfaceChainIDsList"] 749 750 for Index in range(0, len(InterfaceChainIDsList), 2): 751 ChainIDs1 = InterfaceChainIDsList[Index] 752 ChainIDs2 = InterfaceChainIDsList[Index + 1] 753 754 Infie1InterfaceChainIDsList.extend(ChainIDs1) 755 if SingleInfileMode: 756 Infie1InterfaceChainIDsList.extend(ChainIDs2) 757 else: 758 Infie2InterfaceChainIDsList.extend(ChainIDs2) 759 760 Infie1InterfaceChainIDsList = sorted(Infie1InterfaceChainIDsList) 761 Infie2InterfaceChainIDsList = sorted(Infie2InterfaceChainIDsList) 762 763 OptionsInfo["InfilesInterfaceChainIDsList"] = [Infie1InterfaceChainIDsList, Infie2InterfaceChainIDsList] 764 765 def AutoAssignInterfaceChainIDs(): 766 """Handle automatic assignment of interface chain IDs.""" 767 768 Infile1ChainIDs = OptionsInfo["InfilesInfo"]["ChainsAndLigandsInfo"][0]["ChainIDs"] 769 Infile2ChainIDs = [] 770 if not OptionsInfo["InfilesInfo"]["SingleInfileMode"]: 771 Infile2ChainIDs = OptionsInfo["InfilesInfo"]["ChainsAndLigandsInfo"][1]["ChainIDs"] 772 773 InterfaceChainIDsList = [] 774 if OptionsInfo["InfilesInfo"]["SingleInfileMode"]: 775 # Take first two chains from first input file... 776 if len(Infile1ChainIDs) < 2: 777 MiscUtil.PrintError("Failed to automatically set interface chain IDs. Number of chains, %s, in input file specified using \"-i, --infiles\" option must be >= 2. " % (len(Infile1ChainIDs))) 778 InterfaceChainIDsList.append([Infile1ChainIDs[0]]) 779 InterfaceChainIDsList.append([Infile1ChainIDs[1]]) 780 else: 781 # Take first chain from each input file... 782 if len(Infile1ChainIDs) < 1: 783 MiscUtil.PrintError("Failed to automatically set interface chain IDs. Number of chains, %s, in first input file specified using \"-i, --infiles\" option must be >= 1. " % (len(Infile1ChainIDs))) 784 if len(Infile2ChainIDs) < 1: 785 MiscUtil.PrintError("Failed to automatically set interface chain IDs. Number of chains, %s, in second input file specified using \"-i, --infiles\" option must be >= 1. " % (len(Infile1ChainIDs))) 786 InterfaceChainIDsList.append([Infile1ChainIDs[0]]) 787 InterfaceChainIDsList.append([Infile2ChainIDs[1]]) 788 789 OptionsInfo["InterfaceChainIDsList"] = [] 790 OptionsInfo["InterfaceChainIDsList"].extend(InterfaceChainIDsList) 791 792 return 793 794 def SetupChainsAndLigandsInfo(): 795 """Setup chains and ligands info for input files to visualize macromolecules.""" 796 797 OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"] = [] 798 for FileIndex in range(0, len(OptionsInfo["InfilesInfo"]["InfilesNames"])): 799 Infile = OptionsInfo["InfilesInfo"]["InfilesNames"][FileIndex] 800 MiscUtil.PrintInfo("\nSetting up chain and ligand information for input file %s..." % Infile) 801 802 ChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["ChainsAndLigandsInfo"][FileIndex] 803 InfilesInterfaceChainIDsList = OptionsInfo["InfilesInterfaceChainIDsList"][FileIndex] 804 805 SpecifiedChainsAndLigandsInfo = {} 806 SpecifiedChainsAndLigandsInfo["ChainIDs"] = [] 807 SpecifiedChainsAndLigandsInfo["InterfaceResNums"] = {} 808 SpecifiedChainsAndLigandsInfo["LigandIDs"] = {} 809 810 if len(InfilesInterfaceChainIDsList): 811 # Add unique interface IDs to the chain IDs list for visualization. Interface chain IDs 812 # may contain duplicate chain IDs due to the presence # of same chain in multiple 813 # interfaces. 814 for ChainID in InfilesInterfaceChainIDsList: 815 if not ChainID in SpecifiedChainsAndLigandsInfo["ChainIDs"]: 816 SpecifiedChainsAndLigandsInfo["ChainIDs"].append(ChainID) 817 818 for ChainID in SpecifiedChainsAndLigandsInfo["ChainIDs"]: 819 # Initialize interface residue numbers to be assigned later... 820 SpecifiedChainsAndLigandsInfo["InterfaceResNums"][ChainID] = [] 821 822 # Setup ligand IDs... 823 SpecifiedChainsAndLigandsInfo["LigandIDs"][ChainID] = SetupSpecifiedLigandIDs(FileIndex, ChainID, ChainsAndLigandsInfo) 824 825 ProcessResidueTypesAndSurfaceOptions(FileIndex, SpecifiedChainsAndLigandsInfo) 826 827 OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"].append(SpecifiedChainsAndLigandsInfo) 828 829 def SetupSpecifiedLigandIDs(FileIndex, ChainID, ChainsAndLigandsInfo): 830 """Setup specified ligand IDs for input file.""" 831 832 LigandIDs = [] 833 834 if re.match("^All$", OptionsInfo["LigandIDs"], re.I): 835 LigandIDs = ChainsAndLigandsInfo["LigandIDs"][ChainID] 836 return LigandIDs 837 elif re.match("^Largest|Auto$", OptionsInfo["LigandIDs"], re.I): 838 LargestLigandID = ChainsAndLigandsInfo["LigandIDs"][ChainID][0] if (len(ChainsAndLigandsInfo["LigandIDs"][ChainID])) else None 839 if LargestLigandID is not None: 840 LigandIDs.append(LargestLigandID) 841 return LigandIDs 842 elif re.match("^None$", OptionsInfo["LigandIDs"], re.I): 843 return LigandIDs 844 845 Infile = OptionsInfo["InfilesInfo"]["InfilesNames"][FileIndex] 846 ValidLigandIDs = ChainsAndLigandsInfo["LigandIDs"][ChainID] 847 848 SpecifiedLigandIDs = re.sub(" ", "", OptionsInfo["LigandIDs"]) 849 if not SpecifiedLigandIDs: 850 MiscUtil.PrintError("No valid value specified using \-l, --ligandIDs\" option.") 851 852 LigandIDsWords = SpecifiedLigandIDs.split(",") 853 for LigandID in LigandIDsWords: 854 if not LigandID in ValidLigandIDs: 855 LigandIDsListNames = ",".join(ValidLigandIDs) if len(ValidLigandIDs) else "None" 856 MiscUtil.PrintWarning("The ligand ID, %s, specified using \"-l, --ligandiIDs\" option is not valid for chain, %s, in input file, %s. It'll be ignored. Valid ligand IDs: %s" % (LigandID, ChainID, Infile, LigandIDsListNames)) 857 continue 858 859 if LigandID in LigandIDs: 860 MiscUtil.PrintWarning("The ligand ID, %s, has already been specified using \"-l, --ligandIDs\" option for chain, %s, in input file, %s. It'll be ignored." % (LigandID, ChainID, Infile)) 861 continue 862 863 LigandIDs.append(LigandID) 864 865 if not len(LigandIDs): 866 MiscUtil.PrintWarning("No valid ligand IDs \"%s\" specified using \"-l, --ligandIDs\" option for chain ID, %s, in input file, %s." % (OptionsInfo["LigandIDs"], ChainID, Infile)) 867 868 return LigandIDs 869 870 def SetupInterfaceChainPairsAndResiduesInfo(): 871 """Setup chain and residue pairs corresponding to interfaces.""" 872 873 MiscUtil.PrintInfo("\nIdentifying interface residues...") 874 875 SingleInfileMode = OptionsInfo["InfilesInfo"]["SingleInfileMode"] 876 InterfaceChainIDsList = OptionsInfo["InterfaceChainIDsList"] 877 878 if not len(InterfaceChainIDsList): 879 MiscUtil.PrintError("Failed to identify interface residues: No valid chain ID pairs available for interfaces") 880 881 # Load infiles to identify interface residues... 882 Infile1 = OptionsInfo["InfilesInfo"]["InfilesNames"][0] 883 MolName1 = OptionsInfo["InfilesInfo"]["InfilesRoots"][0] 884 pymol.cmd.load(Infile1, MolName1) 885 if SingleInfileMode: 886 MolName2 = MolName1 887 else: 888 Infile2 = OptionsInfo["InfilesInfo"]["InfilesNames"][1] 889 MolName2 = OptionsInfo["InfilesInfo"]["InfilesRoots"][1] 890 pymol.cmd.load(Infile2, MolName2) 891 892 # Initialize data... 893 InterfaceChainPairsAndResiduesInfo = {} 894 InterfaceChainPairsAndResiduesInfo["InterfaceIDs"] = [] 895 InterfaceChainPairsAndResiduesInfo["ChainIDsPairs"] = {} 896 InterfaceChainPairsAndResiduesInfo["ChainIDsResNumsPairs"] = {} 897 InterfaceChainPairsAndResiduesInfo["InfileIndicesPairs"] = {} 898 899 Method = OptionsInfo["Method"] 900 MethodCutoff = OptionsInfo["MethodCutoff"] 901 MiscUtil.PrintInfo("Methodology: %s; Cutoff: %.2f" % (Method, MethodCutoff)) 902 903 for Index in range(0, len(InterfaceChainIDsList), 2): 904 ChainIDs1 = sorted(InterfaceChainIDsList[Index]) 905 ChainIDs2 = sorted(InterfaceChainIDsList[Index + 1]) 906 907 ChainIDs1Prefix = "Chains" if len(ChainIDs1) > 1 else "Chain" 908 ChainIDs2Prefix = "Chains" if len(ChainIDs2) > 1 else "Chain" 909 InterfaceID = "%s%s_%s%s" % (ChainIDs1Prefix, "+".join(ChainIDs1), ChainIDs2Prefix, "+".join(ChainIDs2)) 910 911 ListInterfaceID = "%s_%s" % ("+".join(ChainIDs1), "+".join(ChainIDs2)) 912 913 FileIndex1 = 0 914 FileIndex2 = 0 if SingleInfileMode else 1 915 916 if InterfaceID in InterfaceChainPairsAndResiduesInfo["InterfaceIDs"]: 917 MiscUtil.PrintInfo("Ignoring interface ID %s: It has already been defined" % InterfaceID) 918 continue 919 920 # Identify and list interface chains and residues... 921 ChainsAndResiduesInfo1, ChainsAndResiduesInfo2 = GetInterfaceChainsAndResiduesInfo(MolName1, ChainIDs1, MolName2, ChainIDs2, Method, MethodCutoff) 922 ListInterfaceChainsAndResidues(ListInterfaceID, MolName1, ChainIDs1, ChainsAndResiduesInfo1, MolName2, ChainIDs2, ChainsAndResiduesInfo2) 923 924 # Check presence of interface residues... 925 if (not (len(ChainsAndResiduesInfo1["ChainIDs"]) and len(ChainsAndResiduesInfo2["ChainIDs"]))): 926 MiscUtil.PrintWarning("Ignoring interface ID %s: Failed to identify any interface residues. PyMOL groups and objects won't be created." % InterfaceID) 927 continue 928 929 # Collect residue numbers for set of interface residues in each chain... 930 InterfaceChainIDs1, InterfaceChainResidueNums1 = GetInterfaceChainsAndResidueNumbers(ChainIDs1, ChainsAndResiduesInfo1) 931 InterfaceChainIDs2, InterfaceChainResidueNums2 = GetInterfaceChainsAndResidueNumbers(ChainIDs2, ChainsAndResiduesInfo2) 932 933 InterfaceChainPairsAndResiduesInfo["InterfaceIDs"].append(InterfaceID) 934 InterfaceChainPairsAndResiduesInfo["ChainIDsPairs"][InterfaceID] = [InterfaceChainIDs1, InterfaceChainIDs2] 935 InterfaceChainPairsAndResiduesInfo["ChainIDsResNumsPairs"][InterfaceID] = [InterfaceChainResidueNums1, InterfaceChainResidueNums2] 936 InterfaceChainPairsAndResiduesInfo["InfileIndicesPairs"][InterfaceID] = [FileIndex1, FileIndex2] 937 938 InterfaceChainPairsAndResiduesInfo["InterfaceIDs"] = sorted(InterfaceChainPairsAndResiduesInfo["InterfaceIDs"]) 939 OptionsInfo["InfilesInfo"]["InterfaceChainPairsAndResiduesInfo"] = InterfaceChainPairsAndResiduesInfo 940 941 # Delete loaded objects... 942 pymol.cmd.delete(MolName1) 943 if not SingleInfileMode: 944 pymol.cmd.delete(MolName2) 945 946 def ProcessInterfaceChainPairsAndResiduesInfo(): 947 """Process chain and residue pairs for visualizing interfaces.""" 948 949 InterfaceChainsAndResiduesInfo = {} 950 InterfaceChainsAndResiduesInfo["InterfaceIDs"] = [] 951 InterfaceChainsAndResiduesInfo["InterfaceChainIDs"] = {} 952 InterfaceChainsAndResiduesInfo["ChainIDs"] = {} 953 InterfaceChainsAndResiduesInfo["ChainIDsResNums"] = {} 954 InterfaceChainsAndResiduesInfo["ChainIDsComplexNames"] = {} 955 InterfaceChainsAndResiduesInfo["ChainIDsInfileIndices"] = {} 956 957 InterfaceChainPairsAndResiduesInfo = OptionsInfo["InfilesInfo"]["InterfaceChainPairsAndResiduesInfo"] 958 959 for InterfaceID in InterfaceChainPairsAndResiduesInfo["InterfaceIDs"]: 960 # Flatten pairwise interface chain and residues info... 961 FlattenedInterfaceChainIDs, FlattenedChainIDs, FlattenedResNums, FlattenedComplexNames, FlattenedInfileIndices = FlattenIntferfaceChainPairsAndResiduesInfo(InterfaceChainPairsAndResiduesInfo, InterfaceID) 962 963 if not InterfaceID in InterfaceChainsAndResiduesInfo["InterfaceIDs"]: 964 InterfaceChainsAndResiduesInfo["InterfaceIDs"].append(InterfaceID) 965 966 InterfaceChainsAndResiduesInfo["InterfaceChainIDs"][InterfaceID] = [] 967 InterfaceChainsAndResiduesInfo["ChainIDs"][InterfaceID] = {} 968 InterfaceChainsAndResiduesInfo["ChainIDsResNums"][InterfaceID] = {} 969 InterfaceChainsAndResiduesInfo["ChainIDsComplexNames"][InterfaceID] = {} 970 InterfaceChainsAndResiduesInfo["ChainIDsInfileIndices"][InterfaceID] = {} 971 972 # Track interface information for visualization... 973 for Index in range(0, len(FlattenedInterfaceChainIDs)): 974 InterfaceChainID = FlattenedInterfaceChainIDs[Index] 975 ChainID = FlattenedChainIDs[Index] 976 ResNums = FlattenedResNums[Index] 977 ComplexName = FlattenedComplexNames[Index] 978 FileIndex = FlattenedInfileIndices[Index] 979 980 if not len(ResNums): 981 continue 982 983 InterfaceChainsAndResiduesInfo["InterfaceChainIDs"][InterfaceID].append(InterfaceChainID) 984 InterfaceChainsAndResiduesInfo["ChainIDs"][InterfaceID][InterfaceChainID] = ChainID 985 InterfaceChainsAndResiduesInfo["ChainIDsResNums"][InterfaceID][InterfaceChainID] = ResNums 986 InterfaceChainsAndResiduesInfo["ChainIDsComplexNames"][InterfaceID][InterfaceChainID] = ComplexName 987 InterfaceChainsAndResiduesInfo["ChainIDsInfileIndices"][InterfaceID][InterfaceChainID] = FileIndex 988 989 OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex]["InterfaceResNums"][ChainID].extend(ResNums) 990 991 OptionsInfo["InfilesInfo"]["InterfaceChainsAndResiduesInfo"] = InterfaceChainsAndResiduesInfo 992 993 def FlattenIntferfaceChainPairsAndResiduesInfo(InterfaceChainPairsAndResiduesInfo, InterfaceID): 994 """Flatten interface chain and residues info.""" 995 996 SingleInfileMode = OptionsInfo["InfilesInfo"]["SingleInfileMode"] 997 998 ChainIDs1, ChainIDs2 = InterfaceChainPairsAndResiduesInfo["ChainIDsPairs"][InterfaceID] 999 ResNums1, ResNums2 = InterfaceChainPairsAndResiduesInfo["ChainIDsResNumsPairs"][InterfaceID] 1000 FileIndex1, FileIndex2 = InterfaceChainPairsAndResiduesInfo["InfileIndicesPairs"][InterfaceID] 1001 1002 # Set complex names.. 1003 PDBGroup1 = OptionsInfo["InfilesInfo"]["PyMOLObjectNamesInfo"][FileIndex1]["PDBGroup"] 1004 ComplexName1 = OptionsInfo["InfilesInfo"]["PyMOLObjectNamesInfo"][FileIndex1]["Complex"] 1005 1006 PDBGroup2 = OptionsInfo["InfilesInfo"]["PyMOLObjectNamesInfo"][FileIndex2]["PDBGroup"] 1007 ComplexName2 = OptionsInfo["InfilesInfo"]["PyMOLObjectNamesInfo"][FileIndex2]["Complex"] 1008 1009 ChainIDs = [] 1010 InterfaceChainIDs = [] 1011 ResNums = [] 1012 ComplexNames = [] 1013 FileIndices = [] 1014 1015 for ChainID in ChainIDs1: 1016 ChainIDs.append(ChainID) 1017 InterfaceChainID = ("Chain%s" % ChainID) if SingleInfileMode else ("Chain%s_%s" % (ChainID, PDBGroup1)) 1018 InterfaceChainIDs.append(InterfaceChainID) 1019 ResNums.append(ResNums1["ResNums"][ChainID]) 1020 ComplexNames.append(ComplexName1) 1021 FileIndices.append(FileIndex1) 1022 1023 for ChainID in ChainIDs2: 1024 ChainIDs.append(ChainID) 1025 InterfaceChainID = ("Chain%s" % ChainID) if SingleInfileMode else ("Chain%s_%s" % (ChainID, PDBGroup2)) 1026 InterfaceChainIDs.append(InterfaceChainID) 1027 ResNums.append(ResNums2["ResNums"][ChainID]) 1028 ComplexNames.append(ComplexName2) 1029 FileIndices.append(FileIndex2) 1030 1031 return InterfaceChainIDs, ChainIDs, ResNums, ComplexNames, FileIndices 1032 1033 def GetInterfaceChainsAndResiduesInfo(MolName1, ChainIDs1, MolName2, ChainIDs2, Method, Cutoff): 1034 """Get interface chains and residues info for chains using a specified methodology.""" 1035 1036 InterfaceChainsResiduesInfo1 = None 1037 InterfaceChainsResiduesInfo2 = None 1038 1039 ChainNames1 = ",".join(ChainIDs1) 1040 ChainNames2 = ",".join(ChainIDs2) 1041 1042 if re.match("^BySASAChange$", Method, re.I): 1043 InterfaceChainsResiduesInfo1, InterfaceChainsResiduesInfo2 = PyMOLUtil.GetInterfaceChainsResiduesBySASAChange(MolName1, ChainNames1, MolName2, ChainNames2, Cutoff) 1044 elif re.match("^ByHeavyAtomsDistance$", Method, re.I): 1045 InterfaceChainsResiduesInfo1, InterfaceChainsResiduesInfo2 = PyMOLUtil.GetInterfaceChainsResiduesByHeavyAtomsDistance(MolName1, ChainNames1, MolName2, ChainNames2, Cutoff) 1046 elif re.match("^ByCAlphaAtomsDistance$", Method, re.I): 1047 InterfaceChainsResiduesInfo1, InterfaceChainsResiduesInfo2 = PyMOLUtil.GetInterfaceChainsResiduesByCAlphaAtomsDistance(MolName1, ChainNames1, MolName2, ChainNames2, Cutoff) 1048 else: 1049 MiscUtil.PrintError("Failed to retrieve interface residues information: Method %s is not valid..." % Method) 1050 1051 return InterfaceChainsResiduesInfo1, InterfaceChainsResiduesInfo2 1052 1053 def ListInterfaceChainsAndResidues(InterfaceID, MolName1, ChainIDs1, ChainsAndResiduesInfo1, MolName2, ChainIDs2, ChainsAndResiduesInfo2): 1054 """List interface chains and residues for an interface.""" 1055 1056 ChainNames1, ResiduesInfo1 = PrepareInterfaceChainsAndResiduesInfo(ChainsAndResiduesInfo1) 1057 ChainNames2, ResiduesInfo2 = PrepareInterfaceChainsAndResiduesInfo(ChainsAndResiduesInfo2) 1058 1059 if len(ChainNames1) and len(ChainNames2): 1060 MiscUtil.PrintInfo("\nListing interface residues for interface chain IDs: %s" % (InterfaceID)) 1061 1062 ListInterfaceChainsAndResiduesInfo(InterfaceID, MolName1, ChainIDs1, ChainNames1, ResiduesInfo1) 1063 ListInterfaceChainsAndResiduesInfo(InterfaceID, MolName2, ChainIDs2, ChainNames2, ResiduesInfo2) 1064 else: 1065 MiscUtil.PrintInfo("\nListing interface residues for interface chain IDs: %s" % (InterfaceID)) 1066 MiscUtil.PrintInfo("Interface chain IDs: None; ChainID: None; Number of interface residues: 0") 1067 1068 def PrepareInterfaceChainsAndResiduesInfo(ChainsAndResiduesInfo): 1069 """Prepare interface chains and residues info for listing.""" 1070 1071 ChainNames = [] 1072 ResiduesInfo = [] 1073 1074 for ChainID in ChainsAndResiduesInfo["ChainIDs"]: 1075 ChainNames.append(ChainID) 1076 1077 # Setup distribution of residues... 1078 LineWords = [] 1079 ResiduesCount = 0 1080 SortedResNames = sorted(ChainsAndResiduesInfo["ResNames"][ChainID], key = lambda ResName: ChainsAndResiduesInfo["ResCount"][ChainID][ResName], reverse = True) 1081 for ResName in SortedResNames: 1082 ResCount = ChainsAndResiduesInfo["ResCount"][ChainID][ResName] 1083 LineWords.append("%s - %s" % (ResName, ResCount)) 1084 ResiduesCount += ResCount 1085 1086 ResiduesDistribution = "; ".join(LineWords) if len(LineWords) else None 1087 1088 # Setup residue IDs sorted by residue numbers... 1089 ResNumMap = {} 1090 for ResName in ChainsAndResiduesInfo["ResNames"][ChainID]: 1091 for ResNum in ChainsAndResiduesInfo["ResNum"][ChainID][ResName]: 1092 ResNumMap[ResNum] = ResName 1093 1094 LineWords = [] 1095 for ResNum in sorted(ResNumMap, key = int): 1096 ResName = ResNumMap[ResNum] 1097 ResID = "%s_%s" % (ResName, ResNum) 1098 LineWords.append(ResID) 1099 ResiduesIDs = ", ".join(LineWords) if len(LineWords) else None 1100 1101 ResiduesInfo.append([ResiduesCount, ResiduesDistribution, ResiduesIDs]) 1102 1103 return ChainNames, ResiduesInfo 1104 1105 def ListInterfaceChainsAndResiduesInfo(InterfaceID, MolName, InterfaceChainIDs, ChainNames, ResiduesInfo): 1106 """List interface chains and residues.""" 1107 1108 for ChainID in InterfaceChainIDs: 1109 if not ChainID in ChainNames: 1110 MiscUtil.PrintWarning("Interface chain IDs: %s; MoleculeID: %s; ChainID: %s; Number of interface residues: 0. PyMOL groups and objects related to chain won't be created." % (InterfaceID, MolName, ChainID)) 1111 continue 1112 1113 for Index in range(0, len(ChainNames)): 1114 ChainName = ChainNames[Index] 1115 ChainResiduesInfo = ResiduesInfo[Index] 1116 if re.match(ChainID, ChainName, re.I): 1117 MiscUtil.PrintInfo("\nInterface chain IDs: %s; MoleculeID: %s; ChainID: %s; Number of interface residues: %d" % (InterfaceID, MolName, ChainName, ChainResiduesInfo[0])) 1118 MiscUtil.PrintInfo("Residue distribution: %s\nResidue IDs: %s" % (ChainResiduesInfo[1], ChainResiduesInfo[2])) 1119 continue 1120 1121 def GetInterfaceChainsAndResidueNumbers(ChainIDs, ChainsAndResiduesInfo): 1122 """Collect interface residue numbers for chains.""" 1123 1124 ChainResidueNums = {} 1125 ChainResidueNums["ChainIDs"] = [] 1126 ChainResidueNums["ResNums"] = {} 1127 1128 for ChainID in ChainIDs: 1129 if not ChainID in ChainsAndResiduesInfo["ChainIDs"]: 1130 continue 1131 1132 ChainResidueNums["ChainIDs"].append(ChainID) 1133 ChainResidueNums["ResNums"][ChainID] = [] 1134 1135 ResNums = [] 1136 for ResName in ChainsAndResiduesInfo["ResNames"][ChainID]: 1137 ResNums.extend(ChainsAndResiduesInfo["ResNum"][ChainID][ResName]) 1138 1139 ChainResidueNums["ResNums"][ChainID] = sorted(ResNums, key = int) 1140 1141 InterfaceChainIDs = ChainResidueNums["ChainIDs"] 1142 1143 return InterfaceChainIDs, ChainResidueNums 1144 1145 def SetupPyMOLObjectNamesInfo(): 1146 """Setup PyMOL object names for displaying macromolecules.""" 1147 1148 OptionsInfo["InfilesInfo"]["PyMOLObjectNamesInfo"] = [] 1149 1150 for FileIndex in range(0, len(OptionsInfo["InfilesInfo"]["InfilesNames"])): 1151 PyMOLObjectNamesInfo = SetupPyMOLObjectNames(FileIndex) 1152 OptionsInfo["InfilesInfo"]["PyMOLObjectNamesInfo"].append(PyMOLObjectNamesInfo) 1153 1154 def SetupPyMOLObjectNames(FileIndex): 1155 """Setup hierarchy of PyMOL groups and objects for ligand centric views of 1156 chains and ligands present in input file. 1157 """ 1158 1159 PyMOLObjectNames = {} 1160 PyMOLObjectNames["Chains"] = {} 1161 PyMOLObjectNames["Ligands"] = {} 1162 1163 # Setup groups and objects for complex... 1164 SetupPyMOLObjectNamesForComplex(FileIndex, PyMOLObjectNames) 1165 1166 # Setup groups and objects for chain... 1167 SpecifiedChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex] 1168 for ChainID in SpecifiedChainsAndLigandsInfo["ChainIDs"]: 1169 SetupPyMOLObjectNamesForChain(FileIndex, PyMOLObjectNames, ChainID) 1170 1171 # Setup groups and objects for ligand... 1172 for LigandID in SpecifiedChainsAndLigandsInfo["LigandIDs"][ChainID]: 1173 SetupPyMOLObjectNamesForLigand(FileIndex, PyMOLObjectNames, ChainID, LigandID) 1174 1175 return PyMOLObjectNames 1176 1177 def SetupPyMOLObjectNamesForComplex(FileIndex, PyMOLObjectNames): 1178 """Setup groups and objects for complex.""" 1179 1180 PDBFileRoot = OptionsInfo["InfilesInfo"]["InfilesRoots"][FileIndex] 1181 1182 PDBGroupName = "%s" % PDBFileRoot 1183 PyMOLObjectNames["PDBGroup"] = PDBGroupName 1184 PyMOLObjectNames["PDBGroupMembers"] = [] 1185 1186 ComplexGroupName = "%s.Complex" % PyMOLObjectNames["PDBGroup"] 1187 PyMOLObjectNames["ComplexGroup"] = ComplexGroupName 1188 PyMOLObjectNames["PDBGroupMembers"].append(ComplexGroupName) 1189 1190 PyMOLObjectNames["Complex"] = "%s.Complex" % ComplexGroupName 1191 if OptionsInfo["SurfaceComplex"]: 1192 PyMOLObjectNames["ComplexHydrophobicSurface"] = "%s.Surface" % ComplexGroupName 1193 1194 PyMOLObjectNames["ComplexGroupMembers"] = [] 1195 PyMOLObjectNames["ComplexGroupMembers"].append(PyMOLObjectNames["Complex"]) 1196 if OptionsInfo["SurfaceComplex"]: 1197 PyMOLObjectNames["ComplexGroupMembers"].append(PyMOLObjectNames["ComplexHydrophobicSurface"]) 1198 1199 def SetupPyMOLObjectNamesForChain(FileIndex, PyMOLObjectNames, ChainID): 1200 """Setup groups and objects for chain.""" 1201 1202 PDBGroupName = PyMOLObjectNames["PDBGroup"] 1203 1204 PyMOLObjectNames["Chains"][ChainID] = {} 1205 PyMOLObjectNames["Ligands"][ChainID] = {} 1206 1207 # Set up chain group and chain objects... 1208 ChainGroupName = "%s.Chain%s" % (PDBGroupName, ChainID) 1209 PyMOLObjectNames["Chains"][ChainID]["ChainGroup"] = ChainGroupName 1210 PyMOLObjectNames["PDBGroupMembers"].append(ChainGroupName) 1211 PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"] = [] 1212 1213 # Setup chain complex group and objects... 1214 ChainComplexGroupName = "%s.Complex" % (ChainGroupName) 1215 PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroup"] = ChainComplexGroupName 1216 PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"].append(ChainComplexGroupName) 1217 1218 PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroupMembers"] = [] 1219 1220 Name = "%s.Complex" % (ChainComplexGroupName) 1221 PyMOLObjectNames["Chains"][ChainID]["ChainComplex"] = Name 1222 PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroupMembers"].append(Name) 1223 1224 if OptionsInfo["SurfaceChainComplex"]: 1225 Name = "%s.Surface" % (ChainComplexGroupName) 1226 PyMOLObjectNames["Chains"][ChainID]["ChainComplexHydrophobicSurface"] = Name 1227 PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroupMembers"].append(Name) 1228 1229 # Setup up a group for individual chains... 1230 ChainAloneGroupName = "%s.Chain" % (ChainGroupName) 1231 PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroup"] = ChainAloneGroupName 1232 PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"].append(ChainAloneGroupName) 1233 1234 PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroupMembers"] = [] 1235 1236 Name = "%s.Chain" % (ChainAloneGroupName) 1237 PyMOLObjectNames["Chains"][ChainID]["ChainAlone"] = Name 1238 PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroupMembers"].append(Name) 1239 1240 # Setup a group for non-interface residues... 1241 NonInterfaceGroupName = "%s.NonInterface" % (ChainAloneGroupName) 1242 PyMOLObjectNames["Chains"][ChainID]["ChainAloneNonInterfaceGroup"] = NonInterfaceGroupName 1243 PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroupMembers"].append(NonInterfaceGroupName) 1244 1245 PyMOLObjectNames["Chains"][ChainID]["ChainAloneNonInterfaceGroupMembers"] = [] 1246 1247 # Setup a chain for non-interface residues... 1248 Name = "%s.Chain" % (NonInterfaceGroupName) 1249 PyMOLObjectNames["Chains"][ChainID]["ChainAloneNonInterface"] = Name 1250 PyMOLObjectNames["Chains"][ChainID]["ChainAloneNonInterfaceGroupMembers"].append(Name) 1251 1252 if GetChainAloneContainsSurfacesStatus(FileIndex, ChainID): 1253 # Setup a surface group and add it to chain alone non-interface group... 1254 SurfaceGroupName = "%s.Surface" % (NonInterfaceGroupName) 1255 PyMOLObjectNames["Chains"][ChainID]["ChainAloneSurfaceGroup"] = SurfaceGroupName 1256 PyMOLObjectNames["Chains"][ChainID]["ChainAloneNonInterfaceGroupMembers"].append(SurfaceGroupName) 1257 1258 PyMOLObjectNames["Chains"][ChainID]["ChainAloneSurfaceGroupMembers"] = [] 1259 1260 # Setup a generic colored surface... 1261 Name = "%s.Surface" % (SurfaceGroupName) 1262 PyMOLObjectNames["Chains"][ChainID]["ChainAloneSurface"] = Name 1263 PyMOLObjectNames["Chains"][ChainID]["ChainAloneSurfaceGroupMembers"].append(Name) 1264 1265 if GetChainAloneSurfaceChainStatus(FileIndex, ChainID): 1266 # Setup hydrophobicity surface... 1267 Name = "%s.Hydrophobicity" % (SurfaceGroupName) 1268 PyMOLObjectNames["Chains"][ChainID]["ChainAloneHydrophobicSurface"] = Name 1269 PyMOLObjectNames["Chains"][ChainID]["ChainAloneSurfaceGroupMembers"].append(Name) 1270 1271 # Setup hydrophobicity and charge surface... 1272 Name = "%s.Hydrophobicity_Charge" % (SurfaceGroupName) 1273 PyMOLObjectNames["Chains"][ChainID]["ChainAloneHydrophobicChargeSurface"] = Name 1274 PyMOLObjectNames["Chains"][ChainID]["ChainAloneSurfaceGroupMembers"].append(Name) 1275 1276 if GetChainAloneSurfaceChainElectrostaticsStatus(FileIndex, ChainID): 1277 # Setup electrostatics group... 1278 GroupName = "%s.Vacuum_Electrostatics" % (SurfaceGroupName) 1279 PyMOLObjectNames["Chains"][ChainID]["ChainAloneElectrostaticsGroup"] = GroupName 1280 PyMOLObjectNames["Chains"][ChainID]["ChainAloneSurfaceGroupMembers"].append(GroupName) 1281 1282 # Setup electrostatics group members... 1283 PyMOLObjectNames["Chains"][ChainID]["ChainAloneElectrostaticsGroupMembers"] = [] 1284 1285 for MemberType in ["Chain", "Contact_Potential", "Map", "Legend", "Volume"]: 1286 MemberID = re.sub("_", "", MemberType) 1287 1288 Name = "%s.%s" % (GroupName, MemberType) 1289 NameID = "ChainAloneElectrostaticsSurface%s" % MemberID 1290 1291 PyMOLObjectNames["Chains"][ChainID][NameID] = Name 1292 PyMOLObjectNames["Chains"][ChainID]["ChainAloneElectrostaticsGroupMembers"].append(Name) 1293 1294 # Setup solvent and inorganic objects for chain... 1295 for NameID in ["Solvent", "Inorganic"]: 1296 Name = "%s.%s" % (ChainGroupName, NameID) 1297 PyMOLObjectNames["Chains"][ChainID][NameID] = Name 1298 PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"].append(Name) 1299 1300 def SetupPyMOLObjectNamesForLigand(FileIndex, PyMOLObjectNames, ChainID, LigandID): 1301 """Stetup groups and objects for ligand.""" 1302 1303 PyMOLObjectNames["Ligands"][ChainID][LigandID] = {} 1304 1305 ChainGroupName = PyMOLObjectNames["Chains"][ChainID]["ChainGroup"] 1306 1307 # Setup a chain level ligand group... 1308 ChainLigandGroupName = "%s.Ligand%s" % (ChainGroupName, LigandID) 1309 PyMOLObjectNames["Ligands"][ChainID][LigandID]["ChainLigandGroup"] = ChainLigandGroupName 1310 PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"].append(ChainLigandGroupName) 1311 1312 PyMOLObjectNames["Ligands"][ChainID][LigandID]["ChainLigandGroupMembers"] = [] 1313 1314 # Set up ligand group and its members... 1315 GroupName = "%s.Ligand" % (ChainLigandGroupName) 1316 GroupNameID = "LigandGroup" 1317 GroupMembersID = "LigandGroupMembers" 1318 1319 PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupNameID] = GroupName 1320 PyMOLObjectNames["Ligands"][ChainID][LigandID]["ChainLigandGroupMembers"].append(GroupName) 1321 1322 LigandName = "%s.Ligand" % (GroupName) 1323 LigandNameID = "Ligand" 1324 PyMOLObjectNames["Ligands"][ChainID][LigandID][LigandNameID] = LigandName 1325 1326 PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupMembersID] = [] 1327 PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupMembersID].append(LigandName) 1328 1329 # Add ball and stick... 1330 BallAndStickName = "%s.BallAndStick" % (GroupName) 1331 BallAndStickID = "LigandBallAndStick" 1332 PyMOLObjectNames["Ligands"][ChainID][LigandID][BallAndStickID] = BallAndStickName 1333 PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupMembersID].append(BallAndStickName) 1334 1335 def SetupPyMOLInterfaceObjectNamesInfo(): 1336 """Setup PyMOL object names for displaying macromolecular interfaces.""" 1337 1338 InterfaceChainsAndResiduesInfo = OptionsInfo["InfilesInfo"]["InterfaceChainsAndResiduesInfo"] 1339 1340 PyMOLObjectNames = {} 1341 PyMOLObjectNames["InterfaceIDs"] = {} 1342 PyMOLObjectNames["InterfaceChainIDs"] = {} 1343 1344 # Setup top level interfaces group... 1345 InterfacesGroupName = "Interfaces" 1346 PyMOLObjectNames["InterfacesGroup"] = InterfacesGroupName 1347 PyMOLObjectNames["InterfacesGroupMembers"] = [] 1348 1349 for InterfaceID in InterfaceChainsAndResiduesInfo["InterfaceIDs"]: 1350 PyMOLObjectNames["InterfaceIDs"][InterfaceID] = {} 1351 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID] = {} 1352 1353 # Setup an interface group... 1354 InterfaceIDGroupName = "%s.%s" % (InterfacesGroupName, InterfaceID) 1355 PyMOLObjectNames["InterfaceIDs"][InterfaceID]["InterfaceIDGroup"] = InterfaceIDGroupName 1356 PyMOLObjectNames["InterfacesGroupMembers"].append(InterfaceIDGroupName) 1357 PyMOLObjectNames["InterfaceIDs"][InterfaceID]["InterfaceIDGroupMembers"] = [] 1358 1359 # Setup a polar contact group... 1360 if OptionsInfo["InterfacePolarContacts"]: 1361 PolarContactName = "%s.Polar_Contacts" % (InterfaceIDGroupName) 1362 PyMOLObjectNames["InterfaceIDs"][InterfaceID]["PolarContacts"] = PolarContactName 1363 PyMOLObjectNames["InterfaceIDs"][InterfaceID]["InterfaceIDGroupMembers"].append(PolarContactName) 1364 1365 # Setup a hydrophobic contact group... 1366 if OptionsInfo["InterfaceHydrophobicContacts"]: 1367 HydrophobicContactsName = "%s.Hydrophobic_Contacts" % (InterfaceIDGroupName) 1368 PyMOLObjectNames["InterfaceIDs"][InterfaceID]["HydrophobicContacts"] = HydrophobicContactsName 1369 PyMOLObjectNames["InterfaceIDs"][InterfaceID]["InterfaceIDGroupMembers"].append(HydrophobicContactsName) 1370 1371 for InterfaceChainID in InterfaceChainsAndResiduesInfo["InterfaceChainIDs"][InterfaceID]: 1372 SetupPyMOLInterfaceObjectNamesForChain(PyMOLObjectNames, InterfaceID, InterfaceChainID) 1373 1374 OptionsInfo["InfilesInfo"]["PyMOLInterfaceObjectNamesInfo"] = PyMOLObjectNames 1375 1376 def SetupPyMOLInterfaceObjectNamesForChain(PyMOLObjectNames, InterfaceID, InterfaceChainID): 1377 """Setup PyMOL interface object names for a chain.""" 1378 1379 InterfaceChainsAndResiduesInfo = OptionsInfo["InfilesInfo"]["InterfaceChainsAndResiduesInfo"] 1380 FileIndex = InterfaceChainsAndResiduesInfo["ChainIDsInfileIndices"][InterfaceID][InterfaceChainID] 1381 ChainID = InterfaceChainsAndResiduesInfo["ChainIDs"][InterfaceID][InterfaceChainID] 1382 1383 InterfaceIDGroupName = PyMOLObjectNames["InterfaceIDs"][InterfaceID]["InterfaceIDGroup"] 1384 1385 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID] = {} 1386 1387 # Setup a chain group... 1388 ChainGroupName = "%s.%s" % (InterfaceIDGroupName, InterfaceChainID) 1389 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainGroup"] = ChainGroupName 1390 PyMOLObjectNames["InterfaceIDs"][InterfaceID]["InterfaceIDGroupMembers"].append(ChainGroupName) 1391 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainGroupMembers"] = [] 1392 1393 # Setup chain... 1394 Name = "%s.Chain" % (ChainGroupName) 1395 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["Chain"] = Name 1396 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainGroupMembers"].append(Name) 1397 1398 if GetInterfaceResidueTypesStatus(FileIndex, ChainID): 1399 # Setup residue type group and its subgroups... 1400 ResiduesGroupName = "%s.Residues" % (ChainGroupName) 1401 1402 ResiduesGroupIDPrefix = "ChainResidues" 1403 ResiduesGroupID = "%sGroup" % ResiduesGroupIDPrefix 1404 1405 # Add residue group to chain group... 1406 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID][ResiduesGroupID] = ResiduesGroupName 1407 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainGroupMembers"].append(ResiduesGroupName) 1408 1409 # Initialize residue group members... 1410 ResiduesGroupMembersID = "%sGroupMembers" % ResiduesGroupIDPrefix 1411 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID][ResiduesGroupMembersID] = [] 1412 1413 # Setup residues sub groups and its members... 1414 for SubGroupType in ["Aromatic", "Hydrophobic", "Polar", "Positively_Charged", "Negatively_Charged", "Other"]: 1415 SubGroupID = re.sub("_", "", SubGroupType) 1416 1417 ResiduesSubGroupName = "%s.%s" % (ResiduesGroupName, SubGroupType) 1418 ResiduesSubGroupID = "%s%sGroup" % (ResiduesGroupIDPrefix, SubGroupID) 1419 1420 # Add sub group to residues group... 1421 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID][ResiduesSubGroupID] = ResiduesSubGroupName 1422 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID][ResiduesGroupMembersID].append(ResiduesSubGroupName) 1423 1424 # Initialize sub group members... 1425 ResiduesSubGroupMembersID = "%s%sGroupMembers" % (ResiduesGroupIDPrefix, SubGroupID) 1426 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID][ResiduesSubGroupMembersID] = [] 1427 1428 # Add sub group members to subgroup... 1429 for MemberType in ["Residues", "Surface"]: 1430 MemberID = re.sub("_", "", MemberType) 1431 1432 SubGroupMemberName = "%s.%s" % (ResiduesSubGroupName, MemberType) 1433 SubGroupMemberID = "%s%s%s" % (ResiduesGroupIDPrefix, SubGroupID, MemberID) 1434 1435 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID][SubGroupMemberID] = SubGroupMemberName 1436 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID][ResiduesSubGroupMembersID].append(SubGroupMemberName) 1437 1438 if GetInterfaceContainsSurfacesStatus(FileIndex, ChainID): 1439 # Setup a surface group and add it to chain group... 1440 SurfaceGroupName = "%s.Surface" % (ChainGroupName) 1441 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainSurfaceGroup"] = SurfaceGroupName 1442 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainGroupMembers"].append(SurfaceGroupName) 1443 1444 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainSurfaceGroupMembers"] = [] 1445 1446 # Setup a generic colored surface... 1447 Name = "%s.Surface" % (SurfaceGroupName) 1448 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainSurface"] = Name 1449 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainSurfaceGroupMembers"].append(Name) 1450 1451 if GetInterfaceSurfaceChainStatus(FileIndex, ChainID): 1452 # Setup hydrophobicity surface... 1453 Name = "%s.Hydrophobicity" % (SurfaceGroupName) 1454 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainHydrophobicSurface"] = Name 1455 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainSurfaceGroupMembers"].append(Name) 1456 1457 # Setup hydrophobicity and charge surface... 1458 Name = "%s.Hydrophobicity_Charge" % (SurfaceGroupName) 1459 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainHydrophobicChargeSurface"] = Name 1460 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainSurfaceGroupMembers"].append(Name) 1461 1462 if GetInterfaceSurfaceChainElectrostaticsStatus(FileIndex, ChainID): 1463 # Setup electrostatics group... 1464 GroupName = "%s.Vacuum_Electrostatics" % (SurfaceGroupName) 1465 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainElectrostaticsGroup"] = GroupName 1466 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainSurfaceGroupMembers"].append(GroupName) 1467 1468 # Setup electrostatics group members... 1469 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainElectrostaticsGroupMembers"] = [] 1470 1471 for MemberType in ["Chain", "Contact_Potential", "Map", "Legend", "Volume"]: 1472 MemberID = re.sub("_", "", MemberType) 1473 1474 Name = "%s.%s" % (GroupName, MemberType) 1475 NameID = "ChainElectrostaticsSurface%s" % MemberID 1476 1477 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID][NameID] = Name 1478 PyMOLObjectNames["InterfaceChainIDs"][InterfaceID][InterfaceChainID]["ChainElectrostaticsGroupMembers"].append(Name) 1479 1480 def ProcessResidueTypesAndSurfaceOptions(FileIndex, SpecifiedChainsAndLigandsInfo): 1481 """Process residue types and surface options for chains and interfaces.""" 1482 1483 SpecifiedChainsAndLigandsInfo["ChainSurfaces"] = {} 1484 SpecifiedChainsAndLigandsInfo["SurfaceChain"] = {} 1485 SpecifiedChainsAndLigandsInfo["SurfaceChainElectrostatics"] = {} 1486 1487 SpecifiedChainsAndLigandsInfo["InterfaceSurfaces"] = {} 1488 SpecifiedChainsAndLigandsInfo["SurfaceInterface"] = {} 1489 SpecifiedChainsAndLigandsInfo["SurfaceInterfaceElectrostatics"] = {} 1490 1491 SpecifiedChainsAndLigandsInfo["ResidueTypesInterface"] = {} 1492 1493 # Load infile... 1494 Infile = OptionsInfo["InfilesInfo"]["InfilesNames"][FileIndex] 1495 MolName = OptionsInfo["InfilesInfo"]["InfilesRoots"][FileIndex] 1496 pymol.cmd.load(Infile, MolName) 1497 1498 for ChainID in SpecifiedChainsAndLigandsInfo["ChainIDs"]: 1499 AminoAcidsPresent = PyMOLUtil.AreAminoAcidResiduesPresent(MolName, ChainID) 1500 1501 # Process surfaces for chains... 1502 if re.match("^auto$", OptionsInfo["SurfaceChain"], re.I): 1503 SurfaceChain = True if AminoAcidsPresent else False 1504 else: 1505 SurfaceChain = True if re.match("^yes$", OptionsInfo["SurfaceChain"], re.I) else False 1506 SpecifiedChainsAndLigandsInfo["SurfaceChain"][ChainID] = SurfaceChain 1507 1508 if re.match("^auto$", OptionsInfo["SurfaceChainElectrostatics"], re.I): 1509 SurfaceChainElectrostatics = True if AminoAcidsPresent else False 1510 else: 1511 SurfaceChainElectrostatics = True if re.match("^yes$", OptionsInfo["SurfaceChainElectrostatics"], re.I) else False 1512 SpecifiedChainsAndLigandsInfo["SurfaceChainElectrostatics"][ChainID] = SurfaceChainElectrostatics 1513 1514 # A colored surface is always created by default... 1515 ChainSurfaces = True 1516 SpecifiedChainsAndLigandsInfo["ChainSurfaces"][ChainID] = ChainSurfaces 1517 1518 # Process residue types and surfaces for interfaces... 1519 if re.match("^auto$", OptionsInfo["InterfaceSurface"], re.I): 1520 InterfaceSurface = True if AminoAcidsPresent else False 1521 else: 1522 InterfaceSurface = True if re.match("^yes$", OptionsInfo["InterfaceSurface"], re.I) else False 1523 SpecifiedChainsAndLigandsInfo["SurfaceInterface"][ChainID] = InterfaceSurface 1524 1525 if re.match("^auto$", OptionsInfo["InterfaceSurfaceElectrostatics"], re.I): 1526 InterfaceSurfaceElectrostatics = True if AminoAcidsPresent else False 1527 else: 1528 InterfaceSurfaceElectrostatics = True if re.match("^yes$", OptionsInfo["InterfaceSurfaceElectrostatics"], re.I) else False 1529 SpecifiedChainsAndLigandsInfo["SurfaceInterfaceElectrostatics"][ChainID] = InterfaceSurfaceElectrostatics 1530 1531 # A colored surface is always created by default... 1532 InterfaceSurfaces = True 1533 SpecifiedChainsAndLigandsInfo["InterfaceSurfaces"][ChainID] = InterfaceSurfaces 1534 1535 if re.match("^auto$", OptionsInfo["InterfaceResidueTypes"], re.I): 1536 InterfaceResidueTypes = True if AminoAcidsPresent else False 1537 else: 1538 InterfaceResidueTypes = True if re.match("^yes$", OptionsInfo["InterfaceResidueTypes"], re.I) else False 1539 SpecifiedChainsAndLigandsInfo["ResidueTypesInterface"][ChainID] = InterfaceResidueTypes 1540 1541 # Delete loaded object... 1542 pymol.cmd.delete(MolName) 1543 1544 def GetInterfaceResidueTypesStatus(FileIndex, ChainID): 1545 """Get status of residue types for an interface.""" 1546 1547 return OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex]["ResidueTypesInterface"][ChainID] 1548 1549 def GetChainAloneContainsSurfacesStatus(FileIndex, ChainID): 1550 """Get status of surfaces present in chain alone object.""" 1551 1552 return OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex]["ChainSurfaces"][ChainID] 1553 1554 def GetInterfaceContainsSurfacesStatus(FileIndex, ChainID): 1555 """Get status of surfaces present in an interface.""" 1556 1557 return OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex]["InterfaceSurfaces"][ChainID] 1558 1559 def GetChainAloneSurfaceChainStatus(FileIndex, ChainID): 1560 """Get status of hydrophobic surfaces for chain alone object.""" 1561 1562 return OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex]["SurfaceChain"][ChainID] 1563 1564 def GetChainAloneSurfaceChainElectrostaticsStatus(FileIndex, ChainID): 1565 """Get status of electrostatics surfaces for chain alone object.""" 1566 1567 return OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex]["SurfaceChainElectrostatics"][ChainID] 1568 1569 def GetInterfaceSurfaceChainStatus(FileIndex, ChainID): 1570 """Get status of hydrophobic surfaces for an interface.""" 1571 1572 return OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex]["SurfaceInterface"][ChainID] 1573 1574 def GetInterfaceSurfaceChainElectrostaticsStatus(FileIndex, ChainID): 1575 """Get status of hydrophobic surfaces for an interface.""" 1576 1577 return OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex]["SurfaceInterfaceElectrostatics"][ChainID] 1578 1579 def CheckPresenceOfValidLigandIDs(ChainsAndLigandsInfo, SpecifiedChainsAndLigandsInfo): 1580 """Check presence of valid ligand IDs.""" 1581 1582 MiscUtil.PrintInfo("\nSpecified chain IDs: %s" % (", ".join(SpecifiedChainsAndLigandsInfo["ChainIDs"]))) 1583 1584 for ChainID in SpecifiedChainsAndLigandsInfo["ChainIDs"]: 1585 if len (SpecifiedChainsAndLigandsInfo["LigandIDs"][ChainID]): 1586 MiscUtil.PrintInfo("Chain ID: %s; Specified LigandIDs: %s" % (ChainID, ", ".join(SpecifiedChainsAndLigandsInfo["LigandIDs"][ChainID]))) 1587 else: 1588 MiscUtil.PrintInfo("Chain IDs: %s; Specified LigandIDs: None" % (ChainID)) 1589 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)) 1590 1591 def RetrieveFirstChainID(FileIndex): 1592 """Get first chain ID.""" 1593 1594 ChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["ChainsAndLigandsInfo"][FileIndex] 1595 1596 FirstChainID = None 1597 if len(ChainsAndLigandsInfo["ChainIDs"]): 1598 FirstChainID = ChainsAndLigandsInfo["ChainIDs"][0] 1599 1600 return FirstChainID 1601 1602 def ProcessResidueTypes(): 1603 """Process residue types.""" 1604 1605 ResidueTypesNamesInfo, ResidueTypesParamsInfo = PyMOLUtil.ProcessResidueTypesOptionsInfo("-r, --residueTypes", OptionsInfo["ResidueTypes"]) 1606 OptionsInfo["ResidueTypesNames"] = ResidueTypesNamesInfo 1607 OptionsInfo["ResidueTypesParams"] = ResidueTypesParamsInfo 1608 1609 def ProcessSurfaceAtomTypesColors(): 1610 """Process surface atom types colors. """ 1611 1612 AtomTypesColorNamesInfo = PyMOLUtil.ProcessSurfaceAtomTypesColorsOptionsInfo("--surfaceAtomTypesColors", OptionsInfo["SurfaceAtomTypesColors"]) 1613 OptionsInfo["AtomTypesColorNames"] = AtomTypesColorNamesInfo 1614 1615 def ProcessOptions(): 1616 """Process and validate command line arguments and options.""" 1617 1618 MiscUtil.PrintInfo("Processing options...") 1619 1620 # Validate options... 1621 ValidateOptions() 1622 1623 OptionsInfo["AllowEmptyObjects"] = True if re.match("^Yes$", Options["--allowEmptyObjects"], re.I) else False 1624 1625 OptionsInfo["Infiles"] = Options["--infiles"] 1626 OptionsInfo["InfilesNames"] = Options["--infileNames"] 1627 1628 OptionsInfo["IgnoreHydrogens"] = True if re.match("^Yes$", Options["--ignoreHydrogens"], re.I) else False 1629 1630 OptionsInfo["Overwrite"] = Options["--overwrite"] 1631 OptionsInfo["PMLOut"] = True if re.match("^Yes$", Options["--PMLOut"], re.I) else False 1632 1633 OptionsInfo["Outfile"] = Options["--outfile"] 1634 FileDir, FileName, FileExt = MiscUtil.ParseFileName(OptionsInfo["Outfile"]) 1635 OptionsInfo["PSEOut"] = False 1636 if re.match("^pml$", FileExt, re.I): 1637 OptionsInfo["PMLOutfile"] = OptionsInfo["Outfile"] 1638 OptionsInfo["PMEOutfile"] = re.sub(".pml$", ".pme", OptionsInfo["Outfile"]) 1639 elif re.match("^pse$", FileExt, re.I): 1640 OptionsInfo["PSEOut"] = True 1641 OptionsInfo["PSEOutfile"] = OptionsInfo["Outfile"] 1642 OptionsInfo["PMLOutfile"] = re.sub(".pse$", ".pml", OptionsInfo["Outfile"]) 1643 if os.path.exists(OptionsInfo["PMLOutfile"]) and (not OptionsInfo["Overwrite"]): 1644 MiscUtil.PrintError("The intermediate output file to be generated, %s, already exist. Use option \"--ov\" or \"--overwrite\" and try again." % OptionsInfo["PMLOutfile"] ) 1645 1646 OptionsInfo["InterfaceLabelColor"] = Options["--interfaceLabelColor"] 1647 1648 OptionsInfo["InterfaceContactsCutoff"] = float(Options["--interfaceContactsCutoff"]) 1649 1650 OptionsInfo["InterfaceHydrophobicContactsColor"] = Options["--interfaceHydrophobicContactsColor"] 1651 OptionsInfo["InterfaceHydrophobicContacts"] = True if re.match("^Yes$", Options["--interfaceHydrophobicContacts"], re.I) else False 1652 1653 OptionsInfo["InterfacePolarContactsColor"] = Options["--interfacePolarContactsColor"] 1654 OptionsInfo["InterfacePolarContacts"] = True if re.match("^Yes$", Options["--interfacePolarContacts"], re.I) else False 1655 1656 OptionsInfo["InterfaceResidueTypes"] = Options["--interfaceResidueTypes"] 1657 OptionsInfo["InterfaceSurface"] = Options["--interfaceSurface"] 1658 OptionsInfo["InterfaceSurfaceElectrostatics"] = Options["--interfaceSurfaceElectrostatics"] 1659 1660 OptionsInfo["LabelFontID"] = int(Options["--labelFontID"]) 1661 1662 Method = Options["--method"] 1663 MethodCutoff = Options["--methodCutoff"] 1664 if re.match("^auto$", MethodCutoff, re.I): 1665 if re.match("BySASAChange", Method, re.I): 1666 MethodCutoff = 1.0 1667 elif re.match("ByHeavyAtomsDistance", Method, re.I): 1668 MethodCutoff = 5.0 1669 elif re.match("ByCAlphaAtomsDistance", Method, re.I): 1670 MethodCutoff = 8.0 1671 else: 1672 MiscUtil.PrintError("The method, %s, specified using \"-m, --method\" option is not a valid method." % (Method)) 1673 else: 1674 MethodCutoff = float(Options["--methodCutoff"]) 1675 OptionsInfo["Method"] = Method 1676 OptionsInfo["MethodCutoff"] = MethodCutoff 1677 1678 OptionsInfo["ResidueTypes"] = Options["--residueTypes"] 1679 ProcessResidueTypes() 1680 1681 OptionsInfo["SurfaceChain"] = Options["--surfaceChain"] 1682 OptionsInfo["SurfaceChainElectrostatics"] = Options["--surfaceChainElectrostatics"] 1683 1684 OptionsInfo["SurfaceChainComplex"] = True if re.match("^Yes$", Options["--surfaceChainComplex"], re.I) else False 1685 OptionsInfo["SurfaceComplex"] = True if re.match("^Yes$", Options["--surfaceComplex"], re.I) else False 1686 1687 # Retrieve surface colors... 1688 SurfaceColors = re.sub(" ", "", Options["--surfaceColors"]) 1689 SurfaceColorsWords = SurfaceColors.split(",") 1690 if len(SurfaceColorsWords) != 2: 1691 MiscUtil.PrintError("The number of comma delinited color names, %d, specified using \"--surfaceColors\" option, \"%s\", must be a 2." % (len(SurfaceColorsWords), Options["--surfaceColors"])) 1692 OptionsInfo["SurfaceColors"] = SurfaceColors 1693 OptionsInfo["SurfaceInterfaceColor"] = SurfaceColorsWords[0] 1694 OptionsInfo["SurfaceNonInterfaceColor"] = SurfaceColorsWords[1] 1695 1696 OptionsInfo["SurfaceColorPalette"] = Options["--surfaceColorPalette"] 1697 OptionsInfo["SurfaceAtomTypesColors"] = Options["--surfaceAtomTypesColors"] 1698 ProcessSurfaceAtomTypesColors() 1699 1700 OptionsInfo["SurfaceTransparency"] = float(Options["--surfaceTransparency"]) 1701 1702 RetrieveInfilesInfo() 1703 1704 # Retrieve interface chain IDs... 1705 InterfaceChainIDs = re.sub(" ", "", Options["--chainIDs"]) 1706 InterfaceChainIDsList = [] 1707 CanonicalInterfaceChainIDsMap = {} 1708 if not re.match("^auto$", InterfaceChainIDs, re.I): 1709 InterfaceChainIDsWords = InterfaceChainIDs.split(",") 1710 if len(InterfaceChainIDsWords) % 2: 1711 MiscUtil.PrintError("The number of comma delimited chain IDs, %d, specified using \"-c, --chainIDs\" option, \"%s\", must be a multple of 2." % (len(InterfaceChainIDsWords), Options["--chainIDs"])) 1712 for ChainID in InterfaceChainIDsWords: 1713 if not len(ChainID): 1714 MiscUtil.PrintError("A chain ID specified, \"%s\" using \"-c, --chainIDs\" option is empty." % (Options["--chainIDs"])) 1715 ChainIDWords = ChainID.split("+") 1716 InterfaceChainIDsList.append(ChainIDWords) 1717 OptionsInfo["InterfaceChainIDs"] = InterfaceChainIDs 1718 OptionsInfo["InterfaceChainIDsList"] = InterfaceChainIDsList 1719 1720 # Process interface chain IDs... 1721 OptionsInfo["LigandIDs"] = Options["--ligandIDs"] 1722 ProcessInterfaceChainIDs() 1723 1724 def RetrieveOptions(): 1725 """Retrieve command line arguments and options.""" 1726 1727 # Get options... 1728 global Options 1729 Options = docopt(_docoptUsage_) 1730 1731 # Set current working directory to the specified directory... 1732 WorkingDir = Options["--workingdir"] 1733 if WorkingDir: 1734 os.chdir(WorkingDir) 1735 1736 # Handle examples option... 1737 if "--examples" in Options and Options["--examples"]: 1738 MiscUtil.PrintInfo(MiscUtil.GetExamplesTextFromDocOptText(_docoptUsage_)) 1739 sys.exit(0) 1740 1741 def ValidateOptions(): 1742 """Validate option values.""" 1743 1744 MiscUtil.ValidateOptionTextValue("--allowEmptyObjects", Options["--allowEmptyObjects"], "yes no") 1745 1746 # Expand infiles to handle presence of multiple input files... 1747 InfileNames = MiscUtil.ExpandFileNames(Options["--infiles"], ",") 1748 InfilesCount = len(InfileNames) 1749 if not InfilesCount: 1750 MiscUtil.PrintError("No input files specified for \"-i, --infiles\" option") 1751 1752 # Validate file extensions... 1753 for Infile in InfileNames: 1754 MiscUtil.ValidateOptionFilePath("-i, --infiles", Infile) 1755 MiscUtil.ValidateOptionFileExt("-i, --infiles", Infile, "pdb cif") 1756 MiscUtil.ValidateOptionsDistinctFileNames("-i, --infiles", Infile, "-o, --outfile", Options["--outfile"]) 1757 1758 # Validate file count... 1759 if InfilesCount > 2: 1760 MiscUtil.PrintError("Number of input files, %s, specified using \"-i, --infiles\" option is not valid. Number of allowed files: 1 or 2" % (InfilesCount)) 1761 1762 # Validate distinct file names... 1763 if InfilesCount == 2: 1764 Infile1Name, Infile2Name = InfileNames 1765 Infile1Pattern = r"^" + re.escape(Infile1Name) + r"$"; 1766 if re.match(Infile1Pattern, Infile2Name, re.I): 1767 MiscUtil.PrintError("The file names specified, \"%s\", for option \"-i, --infiles\" must be different.\n" % (Options["--infiles"])) 1768 1769 Options["--infileNames"] = InfileNames 1770 1771 MiscUtil.ValidateOptionFileExt("-o, --outfile", Options["--outfile"], "pml pse") 1772 MiscUtil.ValidateOptionsOutputFileOverwrite("-o, --outfile", Options["--outfile"], "--overwrite", Options["--overwrite"]) 1773 1774 MiscUtil.ValidateOptionTextValue("--ignoreHydrogens", Options["--ignoreHydrogens"], "yes no") 1775 1776 MiscUtil.ValidateOptionFloatValue("--interfaceContactsCutoff", Options["--interfaceContactsCutoff"], {">": 0.0}) 1777 MiscUtil.ValidateOptionTextValue("--interfaceHydrophobicContacts", Options["--interfaceHydrophobicContacts"], "yes no") 1778 MiscUtil.ValidateOptionTextValue("--interfacePolarContacts", Options["--interfacePolarContacts"], "yes no") 1779 1780 MiscUtil.ValidateOptionTextValue("--interfaceResidueTypes", Options["--interfaceResidueTypes"], "yes no auto") 1781 MiscUtil.ValidateOptionTextValue("--interfaceSurface", Options["--interfaceSurface"], "yes no auto") 1782 MiscUtil.ValidateOptionTextValue("--interfaceSurfaceElectrostatics", Options["--interfaceSurfaceElectrostatics"], "yes no auto") 1783 1784 MiscUtil.ValidateOptionIntegerValue("--labelFontID", Options["--labelFontID"], {}) 1785 1786 MiscUtil.ValidateOptionTextValue("--method", Options["--method"], "BySASAChange ByHeavyAtomsDistance ByCAlphaAtomsDistance") 1787 if not re.match("^auto$", Options["--methodCutoff"], re.I): 1788 MiscUtil.ValidateOptionFloatValue("--methodCutoff", Options["--methodCutoff"], {">": 0.0}) 1789 1790 MiscUtil.ValidateOptionTextValue("--PMLOut", Options["--PMLOut"], "yes no") 1791 1792 MiscUtil.ValidateOptionTextValue("--surfaceChain", Options["--surfaceChain"], "yes no auto") 1793 MiscUtil.ValidateOptionTextValue("--surfaceChainElectrostatics", Options["--surfaceChainElectrostatics"], "yes no auto") 1794 MiscUtil.ValidateOptionTextValue("--surfaceComplex", Options["--surfaceComplex"], "yes no") 1795 MiscUtil.ValidateOptionTextValue("--surfaceChainComplex", Options["--surfaceChainComplex"], "yes no") 1796 1797 MiscUtil.ValidateOptionTextValue("--surfaceColorPalette", Options["--surfaceColorPalette"], "RedToWhite WhiteToGreen") 1798 MiscUtil.ValidateOptionFloatValue("--surfaceTransparency", Options["--surfaceTransparency"], {">=": 0.0, "<=": 1.0}) 1799 1800 # Setup a usage string for docopt... 1801 _docoptUsage_ = """ 1802 PyMOLVisualizeInterfaces.py - Visualize macromolecular interfaces 1803 1804 Usage: 1805 PyMOLVisualizeInterfaces.py [--allowEmptyObjects <yes or no>] [--chainIDs <ChainID1 or ChainID1,ChainID2>] 1806 [--interfaceLabelColor <text>] [ --interfaceContactsCutoff <number>] 1807 [--interfaceHydrophobicContacts <yes or no>] [--interfaceHydrophobicContactsColor <text>] 1808 [--interfacePolarContacts <yes or no>] [--interfacePolarContactsColor <text>] 1809 [--interfaceResidueTypes <yes or no>] [--interfaceSurface <yes or no>] 1810 [--interfaceSurfaceElectrostatics <yes or no>] [--labelFontID <number>] 1811 [--ignoreHydrogens <yes or no>] [--ligandIDs <Largest, All, None or ID1,ID2...>] 1812 [--method <text>] [--methodCutoff <number>] 1813 [--PMLOut <yes or no>] [--residueTypes <Type,Color,ResNames,...>] [--surfaceChain <yes or no>] 1814 [--surfaceChainElectrostatics <yes or no>] [--surfaceChainComplex <yes or no>] 1815 [--surfaceComplex <yes or no>] [--surfaceColors <ColorName1,ColorName2>] 1816 [--surfaceColorPalette <RedToWhite or WhiteToGreen>] 1817 [--surfaceAtomTypesColors <ColorType,ColorSpec,...>] [--surfaceTransparency <number>] 1818 [--overwrite] [-w <dir>] -i <infile1,...> -o <outfile> 1819 PyMOLVisualizeInterfaces.py -h | --help | -e | --examples 1820 1821 Description: 1822 Generate PyMOL visualization files for viewing interfaces between macromolecules 1823 including proteins and nucleic acids. The interfaces may be generated between 1824 pairs of chains in a single file or across two different files. 1825 1826 The supported input file format are: PDB (.pdb), CIF (.cif) 1827 1828 The supported output file formats are: PyMOL script file (.pml), PyMOL session 1829 file (.pse) 1830 1831 A variety of PyMOL groups and objects may be created for visualization of 1832 macromolecular interfaces. These groups and objects correspond to complexes, 1833 surfaces, chains, ligands, and interfaces. A complete hierarchy of all possible 1834 PyMOL groups and objects is shown below: 1835 1836 <PDBFileRoot> 1837 .Complex 1838 .Complex 1839 .Surface 1840 .Chain<ID> 1841 .Complex 1842 .Complex 1843 .Surface 1844 .Chain 1845 .Chain 1846 .NonInterface 1847 .Chain 1848 .Surface 1849 .Surface 1850 .Hydrophobicity 1851 .Hydrophobicity_Charge 1852 .Vacuum_Electrostatics 1853 .Contact_Potentials 1854 .Map 1855 .Legend 1856 .Volume 1857 .Solvent 1858 .Inorganic 1859 .Ligand<ID> 1860 .Ligand 1861 .Ligand 1862 .BallAndStick 1863 .Ligand<ID> 1864 .Ligand 1865 ... ... ... 1866 .Chain<ID> 1867 ... ... ... 1868 .Ligand<ID> 1869 ... ... ... 1870 .Ligand<ID> 1871 ... ... ... 1872 .Chain<ID> 1873 ... ... ... 1874 <PDBFileRoot> 1875 .Complex 1876 ... ... ... 1877 .Chain<ID> 1878 ... ... ... 1879 .Ligand<ID> 1880 ... ... ... 1881 .Ligand<ID> 1882 ... ... ... 1883 .Chain<ID> 1884 ... ... ... 1885 <Interfaces> 1886 .Chain<IDs1>_Chain<IDs2> 1887 .Polar_Contacts 1888 .Hydrophobic_Contacts 1889 .Chain<ID> or Chain<ID>_<PDBFileRoot> 1890 .Chain 1891 .Residues 1892 .Aromatic 1893 .Residues 1894 .Surface 1895 .Hydrophobic 1896 .Residues 1897 .Surface 1898 .Polar 1899 .Residues 1900 .Surface 1901 .Positively_Charged 1902 .Residues 1903 .Surface 1904 .Negatively_Charged 1905 .Residues 1906 .Surface 1907 .Other 1908 .Residues 1909 .Surface 1910 .Surface 1911 .Surface 1912 .Hydrophobicity 1913 .Hydrophobicity_Charge 1914 .Vacuum_Electrostatics 1915 .Contact_Potentials 1916 .Map 1917 .Legend 1918 .Volume 1919 .Chain<ID> or <PDBFileRoot>_Chain<ID> 1920 .Chain 1921 .Residues 1922 ... ... ... 1923 .Surface 1924 ... ... ... 1925 .Chain<IDs>_Chain<IDs> 1926 .Polar_Contacts 1927 .Hydrophobic_Contacts 1928 .Chain<ID> or Chain<ID>_<PDBFileRoot> 1929 .Chain 1930 .Residues 1931 ... ... ... 1932 .Surface 1933 ... ... ... 1934 .Chain<ID> or Chain<ID>_<PDBFileRoot> 1935 .Chain 1936 .Residues 1937 ... ... ... 1938 .Surface 1939 ... ... ... 1940 1941 The hydrophobic and electrostatic surfaces are not created for complete complex 1942 and chain complex in input file(s) by default. A word to the wise: The creation of 1943 surface objects may slow down loading of PML file and generation of PSE file, based 1944 on the size of input complexes. The generation of PSE file may also fail. 1945 1946 Options: 1947 --allowEmptyObjects <yes or no> [default: no] 1948 Allow creation of empty PyMOL objects corresponding to interface, 1949 solvent, and inorganic atom selections across chains and ligands in 1950 input file(s). By default, the empty objects are marked for deletion. 1951 -c, --chainIDs <ChainID1,ChainD2,...> [default: Auto] 1952 Pairwise comma delimited list of chain IDs for the identification of 1953 macromolecular interfaces. All chain IDs must be present in the 1954 same file for a single input file. Otherwise, the first and second 1955 chain ID(s) in a pair belong to the first and second input file. 1956 1957 The default values for interface chain IDs depend on the number 1958 of input files as shown below: 1959 1960 One input file: First two chains 1961 Two input files: First chain in each input file 1962 1963 Each chain may contain multiple chain IDs delimited by a plus sign. For 1964 example, A+B,C+D chain pair specifies interface between chain complexes 1965 A+B and C+D in first input file or across two input files. 1966 -e, --examples 1967 Print examples. 1968 -h, --help 1969 Print this help message. 1970 -i, --infiles <infile or infile1,infile2> 1971 Name of an input file or a comma delmited list of names for two input 1972 files. 1973 --ignoreHydrogens <yes or no> [default: yes] 1974 Ignore hydrogens for ligand views. 1975 --interfaceLabelColor <text> [default: magenta] 1976 Color for drawing residue or atom level labels for residues in an interface. 1977 The specified value must be valid color. No validation is performed. 1978 --interfaceContactsCutoff <number> [default: 4.0] 1979 Distance in Angstroms for identifying polar and hyrdophobic contacts 1980 between atoms in interface reisudes. 1981 --interfaceHydrophobicContacts <yes or no> [default: yes] 1982 Hydrophobic contacts between residues in an interface. The hydrophobic 1983 contacts are shown between pairs of carbon atoms not connected to 1984 hydrogen bond donor or acceptors atoms as identified by PyMOL. 1985 --interfaceHydrophobicContactsColor <text> [default: purpleblue] 1986 Color for drawing hydrophobic contacts between residues in an interface. 1987 The specified value must be valid color. No validation is performed. 1988 --interfacePolarContacts <yes or no> [default: yes] 1989 Polar contacts between residues in an interface. 1990 --interfacePolarContactsColor <text> [default: orange] 1991 Color for drawing polar contacts between residues in an interface. 1992 The specified value must be valid color. No validation is performed. 1993 --interfaceResidueTypes <yes or no> [default: auto] 1994 Interface residue types. The residue groups are generated using residue types, 1995 colors, and names specified by '--residueTypes' option. It is only valid for 1996 amino acids. By default, the residue type groups are automatically created 1997 for interfaces containing amino acids and skipped for chains only containing 1998 nucleic acids. 1999 --interfaceSurface <yes or no> [default: auto] 2000 Surfaces around interface residues colored by hydrophobicity alone and 2001 both hydrophobicity and charge. The hydrophobicity surface is colored 2002 at residue level using Eisenberg hydrophobicity scale for residues and color 2003 gradient specified by '--surfaceColorPalette' option. The hydrophobicity and 2004 charge surface is colored [ Ref 140 ] at atom level using colors specified for 2005 groups of atoms by '--surfaceAtomTypesColors' option. This scheme allows 2006 simultaneous mapping of hyrophobicity and charge values on the surfaces. 2007 2008 This option is only valid for amino acids. By default, both surfaces are 2009 automatically created for pockets containing amino acids and skipped for 2010 pockets containing only nucleic acids. 2011 2012 In addition, generic surfaces colored by '--surfaceColors' are always created 2013 for interface residues containing amino acids and nucleic acids. 2014 --interfaceSurfaceElectrostatics <yes or no> [default: no] 2015 Vacuum electrostatics contact potential surface around interface residues. 2016 A word to the wise from PyMOL documentation: The computed protein 2017 contact potentials are only qualitatively useful, due to short cutoffs, 2018 truncation, and lack of solvent "screening". 2019 2020 This option is only valid for amino acids. By default, the electrostatics surface 2021 is automatically created for chains containing amino acids and skipped for chains 2022 containing only nucleic acids. 2023 --labelFontID <number> [default: 7] 2024 Font ID for drawing labels. Default: 7 (Sans Bold). Valid values: 5 to 16. 2025 The specified value must be a valid PyMOL font ID. No validation is 2026 performed. The complete lists of valid font IDs is available at: 2027 pymolwiki.org/index.php/Label_font_id. Examples: 5 - Sans; 2028 7 - Sans Bold; 9 - Serif; 10 - Serif Bold. 2029 -l, --ligandIDs <Largest, All, None or ID1,ID2...> [default: All] 2030 List of ligand IDs to show in chains during visualization of interfaces. Possible 2031 values: Largest, All, None, or a comma delimited list of ligand IDs. The 2032 default is to show all ligands present in chains involved in interfaces. 2033 2034 Ligands are identified using organic selection operator available in PyMOL. 2035 It'll also identify buffer molecules as ligands. The largest ligand contains 2036 the highest number of heavy atoms. 2037 -m, --method <text> [default: BySASAChange] 2038 Methodology for the identification of interface residues between a pair 2039 of chains in an input file. The interface residues may be identified by 2040 change in solvent accessible surface area (SASA) for a residue between 2041 a chain and chains complex, distance between heavy atoms 2042 in two chains, or distance between CAlpha atoms. Possible values: 2043 BySASAChange, ByHeavyAtomsDistance, or ByCAlphaAtomsDistance. 2044 --methodCutoff <number> [default: auto] 2045 Cutoff value used by different methodologies during the identification of 2046 interface residues between a pair of chains. The default values are 2047 shown below: 2048 2049 BySASAChange: 1.0; Units: Angstrom**2 [ Ref 141 ] 2050 ByHeavyAtomsDistance: 5.0; Units: Angstrom [ Ref 142 ] 2051 ByCAlphaAtomsDistance: 8.0; Units: Angstrom [ Ref 143 ] 2052 2053 -o, --outfile <outfile> 2054 Output file name. 2055 -p, --PMLOut <yes or no> [default: yes] 2056 Save PML file during generation of PSE file. 2057 -r, --residueTypes <Type,Color,ResNames,...> [default: auto] 2058 Residue types, colors, and names to generate for residue groups during 2059 and '--residueTypesChain' option. It is only valid for amino acids. 2060 2061 It is a triplet of comma delimited list of amino acid residues type, residues 2062 color, and a space delimited list three letter residue names. 2063 2064 The default values for residue type, color, and name triplets are shown 2065 below: 2066 2067 Aromatic,brightorange,HIS PHE TRP TYR, 2068 Hydrophobic,orange,ALA GLY VAL LEU ILE PRO MET, 2069 Polar,palegreen,ASN GLN SER THR CYS, 2070 Positively_Charged,marine,ARG LYS, 2071 Negatively_Charged,red,ASP GLU 2072 2073 The color name must be a valid PyMOL name. No validation is performed. 2074 An amino acid name may appear across multiple residue types. All other 2075 residues are grouped under 'Other'. 2076 --surfaceChain <yes or no> [default: auto] 2077 Surfaces around non-interface residues in individual chain colored by 2078 hydrophobicity alone and both hydrophobicity and charge. The hydrophobicity 2079 surface is colored at residue level using Eisenberg hydrophobicity scale for residues 2080 and color gradient specified by '--surfaceColorPalette' option. The hydrophobicity 2081 and charge surface is colored [ Ref 140 ] at atom level using colors specified for 2082 groups of atoms by '--surfaceAtomTypesColors' option. This scheme allows 2083 simultaneous mapping of hyrophobicity and charge values on the surfaces. 2084 2085 This option is only valid for amino acids. By default, both surfaces are 2086 automatically created for chains containing amino acids and skipped for 2087 chains containing only nucleic acids. 2088 2089 In addition, generic surfaces colored by '--surfaceColors' are always created 2090 for non-interface residues containing amino acids and nucleic acids. 2091 --surfaceChainElectrostatics <yes or no> [default: no] 2092 Vacuum electrostatics contact potential surface and volume around non-interface 2093 residues in individual chain. A word to the wise from PyMOL documentation: The 2094 computed protein contact potentials are only qualitatively useful, due to short cutoffs, 2095 truncation, and lack of solvent "screening". 2096 2097 This option is only valid for amino acids. By default, the electrostatics surface 2098 and volume are automatically created for chains containing amino acids and 2099 skipped for chains containing only nucleic acids. 2100 --surfaceChainComplex <yes or no> [default: no] 2101 Hydrophobic surface around chain complex. The surface is colored by 2102 hydrophobicity. It is only valid for amino acids. 2103 --surfaceComplex <yes or no> [default: no] 2104 Hydrophobic surface around complete complex. The surface is colored by 2105 hydrophobicity. It is only valid for amino acids. 2106 --surfaceColors <ColorName1,ColorName2> [default: salmon,lightblue] 2107 Color names for surfaces around interface residues and non-interface 2108 residues in chains. These colors are not used for surfaces colored by 2109 hydrophobicity and charge. The color names must be valid PyMOL names. 2110 --surfaceColorPalette <RedToWhite or WhiteToGreen> [default: RedToWhite] 2111 Color palette for hydrophobic surfaces around chains and interface residues 2112 in proteins. Possible values: RedToWhite or WhiteToGreen from most 2113 hydrophobic amino acid to least hydrophobic. The colors values for amino 2114 acids are taken from color_h script available as part of the Script Library at 2115 PyMOL Wiki. 2116 --surfaceAtomTypesColors <ColorType,ColorSpec,...> [default: auto] 2117 Atom colors for generating surfaces colored by hyrophobicity and charge 2118 around chains and interface residues in proteins. It's a pairwise comma 2119 delimited list of atom color type and color specification for goups of atoms. 2120 2121 The default values for color types [ Ref 140 ] along wth color specifications 2122 are shown below: 2123 2124 HydrophobicAtomsColor, yellow, 2125 NegativelyChargedAtomsColor, red, 2126 PositivelyChargedAtomsColor, blue, 2127 OtherAtomsColor, gray90 2128 2129 The color names must be valid PyMOL names. 2130 2131 The color values may also be specified as space delimited RGB triplets: 2132 2133 HydrophobicAtomsColor, 0.95 0.78 0.0, 2134 NegativelyChargedAtomsColor, 1.0 0.4 0.4, 2135 PositivelyChargedAtomsColor, 0.2 0.5 0.8, 2136 OtherAtomsColor, 0.95 0.95 0.95 2137 2138 --surfaceTransparency <number> [default: 0.25] 2139 Surface transparency for molecular surfaces. 2140 --overwrite 2141 Overwrite existing files. 2142 -w, --workingdir <dir> 2143 Location of working directory which defaults to the current directory. 2144 2145 Examples: 2146 To visualize interface residues between the first two chains in a PDB file, 2147 using default methodology to identify interfaces, and and generate a PML 2148 file, type: 2149 2150 % PyMOLVisualizeInterfaces.py -i Sample8.pdb -o Sample8.pml 2151 2152 To visualize interface residues between a pair of specific chains in a PDB 2153 file using a specific methodology and cutoff value to identify interfaces, and 2154 generate a PML file, type: 2155 2156 % PyMOLVisualizeInterfaces.py -m BySASAChange --methodCutoff 1.0 2157 -c "A,B" -i Sample8.pdb -o Sample8.pml 2158 2159 To visualize interface residues between multiple pairs of specified chains in 2160 a PDB file using a specific methodology and cutoff value to identify interfaces, 2161 and generate a PML file, type: 2162 2163 % PyMOLVisualizeInterfaces.py -m ByHeavyAtomsDistance 2164 --methodCutoff 5.0 -c "A,B,B,D" -i Sample8.pdb -o Sample8.pml 2165 2166 To visualize interface residues between a pair of specified chains, each member 2167 containing multiple chains, a PDB file using a specific methodology and cutoff 2168 value to identify interfaces, and generate a PML file, type: 2169 2170 % PyMOLVisualizeInterfaces.py -m ByCAlphaAtomsDistance 2171 --methodCutoff 8.0 -c "A+C,B+D" -i Sample8.pdb -o Sample8.pml 2172 2173 To visualize interface residues between a pair of specific chains across two PDB 2174 files using a specific methodology and cutoff value to identify interfaces, and 2175 generate a PML file, type: 2176 2177 % PyMOLVisualizeInterfaces.py -m BySASAChange --methodCutoff 1.0 2178 -c "A,B" -i Sample8Part1.pdb,Sample8Part2.pdb 2179 -o Sample8.pml 2180 2181 To visualize interface residues between multiple pairs of specified chains across 2182 two PDB files using a specific methodology and cutoff value to identify interfaces, 2183 and generate a PML file, type: 2184 2185 % PyMOLVisualizeInterfaces.py -m ByHeavyAtomsDistance 2186 --methodCutoff 5.0 -c "A,B,C,B" -i Sample8Part1.pdb,Sample8Part2.pdb 2187 -o Sample8.pml 2188 2189 To visualize interface residues between a pair of specified chains, each member 2190 containing multiple chains, across two PDB files using a specific methodology 2191 and cutoff value to identify interfaces, and generate a PML file, type: 2192 2193 % PyMOLVisualizeInterfaces.py -m ByCAlphaAtomsDistance 2194 --methodCutoff 8.0 -c "A+C,B+D" -i "Sample8Part1.pdb,Sample8Part2.pdb" 2195 -o Sample8.pml 2196 2197 Author: 2198 Manish Sud(msud@san.rr.com) 2199 2200 See also: 2201 DownloadPDBFiles.pl, PyMOLVisualizeCryoEMDensity.py, 2202 PyMOLVisualizeElectronDensity.py, PyMOLVisualizeMacromolecules.py, 2203 PyMOLVisualizeSurfaceAndBuriedResidues.py 2204 2205 Copyright: 2206 Copyright (C) 2024 Manish Sud. All rights reserved. 2207 2208 The functionality available in this script is implemented using PyMOL, a 2209 molecular visualization system on an open source foundation originally 2210 developed by Warren DeLano. 2211 2212 This file is part of MayaChemTools. 2213 2214 MayaChemTools is free software; you can redistribute it and/or modify it under 2215 the terms of the GNU Lesser General Public License as published by the Free 2216 Software Foundation; either version 3 of the License, or (at your option) any 2217 later version. 2218 2219 """ 2220 2221 if __name__ == "__main__": 2222 main()