MayaChemTools

    1 #!/bin/env python
    2 #
    3 # File: PyMOLVisualizeElectronDensity.py
    4 # Author: Manish Sud <msud@san.rr.com>
    5 #
    6 # Copyright (C) 2026 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 import os
   33 import sys
   34 import time
   35 import re
   36 
   37 # PyMOL imports...
   38 try:
   39     import pymol
   40 
   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 sys.path.insert(0, os.path.join(os.path.dirname(sys.argv[0]), "..", "lib", "Python"))
   52 try:
   53     from docopt import docopt
   54     import MiscUtil
   55     import PyMOLUtil
   56 except ImportError as ErrMsg:
   57     sys.stderr.write("\nFailed to import MayaChemTools module/package: %s\n" % ErrMsg)
   58     sys.stderr.write("Check/update your MayaChemTools environment and try again.\n\n")
   59     sys.exit(1)
   60 
   61 ScriptName = os.path.basename(sys.argv[0])
   62 Options = {}
   63 OptionsInfo = {}
   64 
   65 
   66 def main():
   67     """Start execution of the script."""
   68 
   69     MiscUtil.PrintInfo(
   70         "\n%s (PyMOL v%s; MayaChemTools v%s; %s): Starting...\n"
   71         % (ScriptName, pymol.cmd.get_version()[0], MiscUtil.GetMayaChemToolsVersion(), time.asctime())
   72     )
   73 
   74     (WallClockTime, ProcessorTime) = MiscUtil.GetWallClockAndProcessorTime()
   75 
   76     # Retrieve command line arguments and options...
   77     RetrieveOptions()
   78 
   79     # Process and validate command line arguments and options...
   80     ProcessOptions()
   81 
   82     # Perform actions required by the script...
   83     GenerateElectronDensityVisualization()
   84 
   85     MiscUtil.PrintInfo("\n%s: Done...\n" % ScriptName)
   86     MiscUtil.PrintInfo("Total time: %s" % MiscUtil.GetFormattedElapsedTime(WallClockTime, ProcessorTime))
   87 
   88 
   89 def GenerateElectronDensityVisualization():
   90     """Generate electron density visualization."""
   91 
   92     Outfile = OptionsInfo["PMLOutfile"]
   93     OutFH = open(Outfile, "w")
   94     if OutFH is None:
   95         MiscUtil.PrintError("Failed to open output fie %s " % Outfile)
   96 
   97     MiscUtil.PrintInfo("\nGenerating file %s..." % Outfile)
   98 
   99     # Setup header...
  100     WritePMLHeader(OutFH, ScriptName)
  101     WritePyMOLParameters(OutFH)
  102 
  103     # Load reffile for alignment..
  104     if OptionsInfo["Align"]:
  105         WriteAlignReference(OutFH)
  106 
  107     # Setup view for each input file...
  108     FirstComplex = True
  109     FirstComplexFirstChainName = None
  110     for FileIndex in range(0, len(OptionsInfo["InfilesInfo"]["InfilesNames"])):
  111         # Setup PyMOL object names...
  112         PyMOLObjectNames = SetupPyMOLObjectNames(FileIndex)
  113 
  114         # Setup complex view...
  115         WriteComplexView(OutFH, FileIndex, PyMOLObjectNames, FirstComplex)
  116 
  117         SpecifiedChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex]
  118         FirstChain = True
  119         for ChainID in SpecifiedChainsAndLigandsInfo["ChainIDs"]:
  120             if FirstComplex and FirstChain:
  121                 FirstComplexFirstChainName = PyMOLObjectNames["Chains"][ChainID]["ChainAlone"]
  122 
  123             WriteChainView(OutFH, FileIndex, PyMOLObjectNames, ChainID)
  124 
  125             # Setup ligand views...
  126             FirstLigand = True
  127             for LigandID in SpecifiedChainsAndLigandsInfo["LigandIDs"][ChainID]:
  128                 WriteChainLigandView(OutFH, FileIndex, PyMOLObjectNames, ChainID, LigandID)
  129 
  130                 # Set up ligand level group...
  131                 Enable, Action = [False, "close"]
  132                 if FirstLigand:
  133                     FirstLigand = False
  134                     Enable, Action = [True, "open"]
  135                 GenerateAndWritePMLForGroup(
  136                     OutFH,
  137                     PyMOLObjectNames["Ligands"][ChainID][LigandID]["ChainLigandGroup"],
  138                     PyMOLObjectNames["Ligands"][ChainID][LigandID]["ChainLigandGroupMembers"],
  139                     Enable,
  140                     Action,
  141                 )
  142 
  143             # Setup Chain level group...
  144             Enable, Action = [False, "close"]
  145             if FirstChain:
  146                 FirstChain = False
  147                 Enable, Action = [True, "open"]
  148             GenerateAndWritePMLForGroup(
  149                 OutFH,
  150                 PyMOLObjectNames["Chains"][ChainID]["ChainGroup"],
  151                 PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"],
  152                 Enable,
  153                 Action,
  154             )
  155 
  156         # Set up complex level group...
  157         Enable, Action = [False, "close"]
  158         if FirstComplex:
  159             FirstComplex = False
  160             Enable, Action = [True, "open"]
  161         GenerateAndWritePMLForGroup(
  162             OutFH, PyMOLObjectNames["PDBGroup"], PyMOLObjectNames["PDBGroupMembers"], Enable, Action
  163         )
  164 
  165         # Delete empty PyMOL objects...
  166         DeleteEmptyPyMOLObjects(OutFH, FileIndex, PyMOLObjectNames)
  167 
  168     if OptionsInfo["Align"]:
  169         DeleteAlignReference(OutFH)
  170 
  171     if FirstComplexFirstChainName is not None:
  172         OutFH.write("""\ncmd.orient("%s", animate = -1)\n""" % FirstComplexFirstChainName)
  173     else:
  174         OutFH.write("""\ncmd.orient("visible", animate = -1)\n""")
  175 
  176     OutFH.close()
  177 
  178     # Generate PSE file as needed...
  179     if OptionsInfo["PSEOut"]:
  180         GeneratePyMOLSessionFile()
  181 
  182 
  183 def WritePMLHeader(OutFH, ScriptName):
  184     """Write out PML header for setting up complex view."""
  185 
  186     HeaderInfo = PyMOLUtil.SetupPMLHeaderInfo(ScriptName)
  187     OutFH.write("%s\n" % HeaderInfo)
  188 
  189 
  190 def WritePyMOLParameters(OutFH):
  191     """Write out PyMOL global parameters."""
  192 
  193     PMLCmds = []
  194     PMLCmds.append("""cmd.set("mesh_width", %.2f)""" % (OptionsInfo["MeshWidth"]))
  195     PMLCmds.append("""cmd.set("transparency", %.2f, "", 0)""" % (OptionsInfo["SurfaceTransparency"]))
  196     PMLCmds.append("""cmd.set("label_font_id", %s)""" % (OptionsInfo["LabelFontID"]))
  197     PML = "\n".join(PMLCmds)
  198 
  199     OutFH.write("""\n""\n"Setting up PyMOL gobal parameters..."\n""\n""")
  200     OutFH.write("%s\n" % PML)
  201 
  202 
  203 def WriteAlignReference(OutFH):
  204     """Setup object for alignment reference."""
  205 
  206     RefFileInfo = OptionsInfo["RefFileInfo"]
  207     RefFile = RefFileInfo["RefFileName"]
  208     RefName = RefFileInfo["PyMOLObjectName"]
  209 
  210     PMLCmds = []
  211     PMLCmds.append("""cmd.load("%s", "%s")""" % (RefFile, RefName))
  212     PMLCmds.append("""cmd.hide("everything", "%s")""" % (RefName))
  213     PMLCmds.append("""cmd.disable("%s")""" % (RefName))
  214     PML = "\n".join(PMLCmds)
  215 
  216     OutFH.write("""\n""\n"Loading %s and setting up view for align reference..."\n""\n""" % RefFile)
  217     OutFH.write("%s\n" % PML)
  218 
  219 
  220 def WriteAlignComplex(OutFH, FileIndex, PyMOLObjectNames):
  221     """Setup alignment of complex to reference."""
  222 
  223     RefFileInfo = OptionsInfo["RefFileInfo"]
  224     RefName = RefFileInfo["PyMOLObjectName"]
  225 
  226     ComplexName = PyMOLObjectNames["Complex"]
  227 
  228     if re.match("^FirstChain$", OptionsInfo["AlignMode"], re.I):
  229         RefFirstChainID = RefFileInfo["ChainsAndLigandsInfo"]["ChainIDs"][0]
  230         RefAlignSelection = "%s and chain %s" % (RefName, RefFirstChainID)
  231 
  232         ComplexFirstChainID = RetrieveFirstChainID(FileIndex)
  233         ComplexAlignSelection = "%s and chain %s" % (ComplexName, ComplexFirstChainID)
  234     else:
  235         RefAlignSelection = RefName
  236         ComplexAlignSelection = ComplexName
  237 
  238     PML = PyMOLUtil.SetupPMLForAlignment(OptionsInfo["AlignMethod"], RefAlignSelection, ComplexAlignSelection)
  239     OutFH.write("""\n""\n"Aligning %s against reference %s ..."\n""\n""" % (ComplexAlignSelection, RefAlignSelection))
  240     OutFH.write("%s\n" % PML)
  241 
  242 
  243 def DeleteAlignReference(OutFH):
  244     """Delete alignment reference object."""
  245 
  246     RefName = OptionsInfo["RefFileInfo"]["PyMOLObjectName"]
  247     OutFH.write("""\n""\n"Deleting alignment reference object %s..."\n""\n""" % RefName)
  248     OutFH.write("""cmd.delete("%s")\n""" % RefName)
  249 
  250 
  251 def WriteComplexView(OutFH, FileIndex, PyMOLObjectNames, FirstComplex):
  252     """Write out PML for viewing polymer complex along with electron density."""
  253 
  254     # Setup complex...
  255     Infile = OptionsInfo["InfilesInfo"]["InfilesNames"][FileIndex]
  256     PML = PyMOLUtil.SetupPMLForPolymerComplexView(PyMOLObjectNames["Complex"], Infile, True)
  257     OutFH.write("""\n""\n"Loading %s and setting up view for complex..."\n""\n""" % Infile)
  258     OutFH.write("%s\n" % PML)
  259 
  260     if OptionsInfo["Align"]:
  261         # No need to align complex on to itself...
  262         if not (re.match("^FirstInputFile$", OptionsInfo["AlignRefFile"], re.I) and FirstComplex):
  263             WriteAlignComplex(OutFH, FileIndex, PyMOLObjectNames)
  264 
  265     # Setup electron density maps and meshes...
  266     CompositeEDMapFile = OptionsInfo["CompositeEDMapFiles"][FileIndex]
  267     WriteComplexCompositeElectronDensityMapView(OutFH, PyMOLObjectNames, CompositeEDMapFile)
  268 
  269     if PyMOLObjectNames["SetupDiffEDMapObjects"]:
  270         DifferenceEDMapFile = OptionsInfo["DiffEDMapFiles"][FileIndex]
  271         WriteComplexDifferenceElectronDensityMapView(OutFH, PyMOLObjectNames, DifferenceEDMapFile)
  272 
  273     # Setup complex group...
  274     GenerateAndWritePMLForGroup(
  275         OutFH, PyMOLObjectNames["ComplexGroup"], PyMOLObjectNames["ComplexGroupMembers"], False, "close"
  276     )
  277 
  278 
  279 def WriteComplexCompositeElectronDensityMapView(OutFH, PyMOLObjectNames, MapFileName):
  280     """Write out PML for viewing composite maps."""
  281 
  282     # Load composite map (2Fo - Fc) and setup mesh views...
  283     Info = (
  284         """\
  285 ""
  286 "Loading composite map (2Fo - Fc) %s and setting up mesh view for complex..."
  287 "" """
  288         % MapFileName
  289     )
  290     OutFH.write("\n%s\n" % Info)
  291 
  292     MapName = PyMOLObjectNames["ComplexCompositeEDMap"]
  293     ComplexName = PyMOLObjectNames["Complex"]
  294 
  295     ContourLevel = OptionsInfo["MeshLevelCompositeMap"]
  296     Color = OptionsInfo["MeshColorCompositeMap"]
  297 
  298     VolumeColorRamp = OptionsInfo["VolumeColorRampCompositeMap"]
  299 
  300     VolumeName = PyMOLObjectNames["ComplexCompositeEDVolume"]
  301     MeshName = PyMOLObjectNames["ComplexCompositeEDMesh"]
  302     SurfaceName = PyMOLObjectNames["ComplexCompositeEDSurface"]
  303 
  304     AlignMapToObjectName = ComplexName if OptionsInfo["Align"] else None
  305     EnableMap = True
  306     PML = SetupPMLForElectronDensityMap(MapFileName, MapName, AlignMapToObjectName, EnableMap)
  307     OutFH.write("%s\n" % PML)
  308 
  309     EnableMesh = OptionsInfo["MeshComplex"]
  310 
  311     EnableVolume = OptionsInfo["VolumeComplex"]
  312     if EnableVolume and EnableMesh:
  313         EnableVolume = False
  314 
  315     EnableSurface = OptionsInfo["SurfaceComplex"]
  316     if EnableSurface and (EnableVolume or EnableMesh):
  317         EnableSurface = False
  318 
  319     if OptionsInfo["VolumeComplex"]:
  320         PML = SetupPMLForElectronDensityVolume(
  321             MapName, VolumeName, VolumeColorRamp, Enable=EnableVolume, Selection=ComplexName
  322         )
  323         OutFH.write("\n%s\n" % PML)
  324 
  325     if OptionsInfo["MeshComplex"]:
  326         PML = SetupPMLForElectronDensityMesh(
  327             MapName, MeshName, ContourLevel, Color, Enable=EnableMesh, Selection=ComplexName
  328         )
  329         OutFH.write("\n%s\n" % PML)
  330 
  331     if OptionsInfo["SurfaceComplex"]:
  332         PML = SetupPMLForElectronDensitySurface(
  333             MapName, SurfaceName, ContourLevel, Color, Enable=EnableSurface, Selection=ComplexName
  334         )
  335         OutFH.write("\n%s\n" % PML)
  336 
  337     GenerateAndWritePMLForGroup(
  338         OutFH,
  339         PyMOLObjectNames["ComplexCompositeEDGroup"],
  340         PyMOLObjectNames["ComplexCompositeEDGroupMembers"],
  341         True,
  342         "close",
  343     )
  344 
  345 
  346 def WriteComplexDifferenceElectronDensityMapView(OutFH, PyMOLObjectNames, MapFileName):
  347     """Write out PML for viewing difference maps."""
  348 
  349     # Load difference map (Fo - Fc ) and setup mesh views...
  350     Info = (
  351         """\
  352 ""
  353 "Loading difference map (Fo - Fc ) map %s and setting up mesh views..."
  354 "" """
  355         % MapFileName
  356     )
  357     OutFH.write("\n%s\n" % Info)
  358 
  359     MapName = PyMOLObjectNames["ComplexDiffEDMap"]
  360     ComplexName = PyMOLObjectNames["Complex"]
  361 
  362     ContourLevel1 = OptionsInfo["Mesh1LevelDiffMap"]
  363     ContourLevel2 = OptionsInfo["Mesh2LevelDiffMap"]
  364     Color1 = OptionsInfo["Mesh1ColorDiffMap"]
  365     Color2 = OptionsInfo["Mesh2ColorDiffMap"]
  366 
  367     VolumeColorRamp = OptionsInfo["VolumeColorRampDiffMap"]
  368 
  369     VolumeName = PyMOLObjectNames["ComplexDiffEDVolume"]
  370     Mesh1Name = PyMOLObjectNames["ComplexDiffEDMesh1"]
  371     Surface1Name = PyMOLObjectNames["ComplexDiffEDSurface1"]
  372     Mesh2Name = PyMOLObjectNames["ComplexDiffEDMesh2"]
  373     Surface2Name = PyMOLObjectNames["ComplexDiffEDSurface2"]
  374 
  375     EnableMesh = OptionsInfo["MeshComplex"]
  376 
  377     EnableVolume = OptionsInfo["VolumeComplex"]
  378     if EnableVolume and EnableMesh:
  379         EnableVolume = False
  380 
  381     EnableSurface = OptionsInfo["SurfaceComplex"]
  382     if EnableSurface and (EnableVolume or EnableMesh):
  383         EnableSurface = False
  384 
  385     AlignMapToObjectName = ComplexName if OptionsInfo["Align"] else None
  386     EnableMap = True
  387     PML = SetupPMLForElectronDensityMap(MapFileName, MapName, AlignMapToObjectName, EnableMap)
  388     OutFH.write("%s\n" % PML)
  389 
  390     if OptionsInfo["VolumeComplex"]:
  391         PML = SetupPMLForElectronDensityVolume(
  392             MapName, VolumeName, VolumeColorRamp, Enable=EnableVolume, Selection=ComplexName
  393         )
  394         OutFH.write("\n%s\n" % PML)
  395 
  396     if OptionsInfo["MeshComplex"]:
  397         PML = SetupPMLForElectronDensityMesh(
  398             MapName, Mesh1Name, ContourLevel1, Color1, Enable=EnableMesh, Selection=ComplexName
  399         )
  400         OutFH.write("\n%s\n" % PML)
  401 
  402     if OptionsInfo["SurfaceComplex"]:
  403         PML = SetupPMLForElectronDensitySurface(
  404             MapName, Surface1Name, ContourLevel1, Color1, Enable=EnableSurface, Selection=ComplexName
  405         )
  406         OutFH.write("\n%s\n" % PML)
  407 
  408     if OptionsInfo["MeshComplex"]:
  409         PML = SetupPMLForElectronDensityMesh(
  410             MapName, Mesh2Name, ContourLevel2, Color2, Enable=EnableMesh, Selection=ComplexName
  411         )
  412         OutFH.write("\n%s\n" % PML)
  413 
  414     if OptionsInfo["SurfaceComplex"]:
  415         PML = SetupPMLForElectronDensitySurface(
  416             MapName, Surface2Name, ContourLevel2, Color2, Enable=EnableSurface, Selection=ComplexName
  417         )
  418         OutFH.write("\n%s\n" % PML)
  419 
  420     GenerateAndWritePMLForGroup(
  421         OutFH, PyMOLObjectNames["ComplexDiffEDGroup"], PyMOLObjectNames["ComplexDiffEDGroupMembers"], True, "close"
  422     )
  423 
  424 
  425 def WriteChainView(OutFH, FileIndex, PyMOLObjectNames, ChainID):
  426     """Write out PML for viewing chain."""
  427 
  428     OutFH.write("""\n""\n"Setting up views for chain %s..."\n""\n""" % ChainID)
  429 
  430     ChainComplexName = PyMOLObjectNames["Chains"][ChainID]["ChainComplex"]
  431 
  432     # Setup chain complex group view...
  433     WriteChainComplexAndMeshViews(OutFH, FileIndex, PyMOLObjectNames, ChainID)
  434 
  435     # Setup chain view...
  436     WriteChainAloneViews(OutFH, FileIndex, PyMOLObjectNames, ChainID)
  437 
  438     # Setup chain solvent view...
  439     PML = PyMOLUtil.SetupPMLForSolventView(PyMOLObjectNames["Chains"][ChainID]["Solvent"], ChainComplexName, False)
  440     OutFH.write("\n%s\n" % PML)
  441 
  442     # Setup chain inorganic view...
  443     PML = PyMOLUtil.SetupPMLForInorganicView(PyMOLObjectNames["Chains"][ChainID]["Inorganic"], ChainComplexName, False)
  444     OutFH.write("\n%s\n" % PML)
  445 
  446 
  447 def WriteChainComplexAndMeshViews(OutFH, FileIndex, PyMOLObjectNames, ChainID):
  448     """Write chain complex and mesh views."""
  449 
  450     # Setup chain complex...
  451     ChainComplexName = PyMOLObjectNames["Chains"][ChainID]["ChainComplex"]
  452     PML = PyMOLUtil.SetupPMLForPolymerChainComplexView(ChainComplexName, PyMOLObjectNames["Complex"], ChainID, True)
  453     OutFH.write("%s\n" % PML)
  454 
  455     SpecifiedChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex]
  456 
  457     MeshChainComplex = SpecifiedChainsAndLigandsInfo["MeshChainComplex"][ChainID]
  458     VolumeChainComplex = SpecifiedChainsAndLigandsInfo["VolumeChainComplex"][ChainID]
  459     SurfaceChainComplex = SpecifiedChainsAndLigandsInfo["SurfaceChainComplex"][ChainID]
  460 
  461     EnableVolumeChainComplex = SpecifiedChainsAndLigandsInfo["EnableVolumeChainComplex"][ChainID]
  462     EnableMeshChainComplex = SpecifiedChainsAndLigandsInfo["EnableMeshChainComplex"][ChainID]
  463     EnableSurfaceChainComplex = SpecifiedChainsAndLigandsInfo["EnableSurfaceChainComplex"][ChainID]
  464 
  465     if MeshChainComplex or VolumeChainComplex or SurfaceChainComplex:
  466         # Set up composite mesh and group...
  467         MapName = PyMOLObjectNames["ComplexCompositeEDMap"]
  468         ContourLevel = OptionsInfo["MeshLevelCompositeMap"]
  469         Color = OptionsInfo["MeshColorCompositeMap"]
  470         VolumeColorRamp = OptionsInfo["VolumeColorRampCompositeMap"]
  471 
  472         MeshName = PyMOLObjectNames["Chains"][ChainID]["ChainComplexCompositeEDMesh"]
  473         VolumeName = PyMOLObjectNames["Chains"][ChainID]["ChainComplexCompositeEDVolume"]
  474         SurfaceName = PyMOLObjectNames["Chains"][ChainID]["ChainComplexCompositeEDSurface"]
  475 
  476         if VolumeChainComplex:
  477             PML = SetupPMLForElectronDensityVolume(
  478                 MapName, VolumeName, VolumeColorRamp, Enable=EnableVolumeChainComplex, Selection=ChainComplexName
  479             )
  480             OutFH.write("\n%s\n" % PML)
  481 
  482         if MeshChainComplex:
  483             PML = SetupPMLForElectronDensityMesh(
  484                 MapName, MeshName, ContourLevel, Color, Enable=EnableMeshChainComplex, Selection=ChainComplexName
  485             )
  486             OutFH.write("\n%s\n" % PML)
  487 
  488         if SurfaceChainComplex:
  489             PML = SetupPMLForElectronDensitySurface(
  490                 MapName, SurfaceName, ContourLevel, Color, Enable=EnableSurfaceChainComplex, Selection=ChainComplexName
  491             )
  492             OutFH.write("\n%s\n" % PML)
  493 
  494         GenerateAndWritePMLForGroup(
  495             OutFH,
  496             PyMOLObjectNames["Chains"][ChainID]["ChainComplexCompositeEDGroup"],
  497             PyMOLObjectNames["Chains"][ChainID]["ChainComplexCompositeEDGroupMembers"],
  498             True,
  499             "close",
  500         )
  501         if PyMOLObjectNames["SetupDiffEDMapObjects"]:
  502             # Set up difference meshes and group...
  503             MapName = PyMOLObjectNames["ComplexDiffEDMap"]
  504 
  505             ContourLevel1 = OptionsInfo["Mesh1LevelDiffMap"]
  506             ContourLevel2 = OptionsInfo["Mesh2LevelDiffMap"]
  507             Color1 = OptionsInfo["Mesh1ColorDiffMap"]
  508             Color2 = OptionsInfo["Mesh2ColorDiffMap"]
  509 
  510             VolumeColorRamp = OptionsInfo["VolumeColorRampDiffMap"]
  511             VolumeName = PyMOLObjectNames["Chains"][ChainID]["ChainComplexDiffEDVolume"]
  512 
  513             Mesh1Name = PyMOLObjectNames["Chains"][ChainID]["ChainComplexDiffEDMesh1"]
  514             Surface1Name = PyMOLObjectNames["Chains"][ChainID]["ChainComplexDiffEDSurface1"]
  515             Mesh2Name = PyMOLObjectNames["Chains"][ChainID]["ChainComplexDiffEDMesh2"]
  516             Surface2Name = PyMOLObjectNames["Chains"][ChainID]["ChainComplexDiffEDSurface2"]
  517 
  518             if VolumeChainComplex:
  519                 PML = SetupPMLForElectronDensityVolume(
  520                     MapName, VolumeName, VolumeColorRamp, Enable=EnableVolumeChainComplex, Selection=ChainComplexName
  521                 )
  522                 OutFH.write("\n%s\n" % PML)
  523 
  524             if MeshChainComplex:
  525                 PML = SetupPMLForElectronDensityMesh(
  526                     MapName, Mesh1Name, ContourLevel1, Color1, Enable=EnableMeshChainComplex, Selection=ChainComplexName
  527                 )
  528                 OutFH.write("\n%s\n" % PML)
  529 
  530             if SurfaceChainComplex:
  531                 PML = SetupPMLForElectronDensitySurface(
  532                     MapName,
  533                     Surface1Name,
  534                     ContourLevel1,
  535                     Color1,
  536                     Enable=EnableSurfaceChainComplex,
  537                     Selection=ChainComplexName,
  538                 )
  539                 OutFH.write("\n%s\n" % PML)
  540 
  541             if MeshChainComplex:
  542                 PML = SetupPMLForElectronDensityMesh(
  543                     MapName, Mesh2Name, ContourLevel2, Color2, Enable=EnableMeshChainComplex, Selection=ChainComplexName
  544                 )
  545                 OutFH.write("\n%s\n" % PML)
  546 
  547             if SurfaceChainComplex:
  548                 PML = SetupPMLForElectronDensitySurface(
  549                     MapName,
  550                     Surface2Name,
  551                     ContourLevel2,
  552                     Color2,
  553                     Enable=EnableSurfaceChainComplex,
  554                     Selection=ChainComplexName,
  555                 )
  556                 OutFH.write("\n%s\n" % PML)
  557 
  558             GenerateAndWritePMLForGroup(
  559                 OutFH,
  560                 PyMOLObjectNames["Chains"][ChainID]["ChainComplexDiffEDGroup"],
  561                 PyMOLObjectNames["Chains"][ChainID]["ChainComplexDiffEDGroupMembers"],
  562                 True,
  563                 "close",
  564             )
  565 
  566     # Setup chain complex group...
  567     EnableChainComplexGroup = SpecifiedChainsAndLigandsInfo["EnableChainComplexGroup"][ChainID]
  568     GenerateAndWritePMLForGroup(
  569         OutFH,
  570         PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroup"],
  571         PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroupMembers"],
  572         EnableChainComplexGroup,
  573         "close",
  574     )
  575 
  576 
  577 def WriteChainAloneViews(OutFH, FileIndex, PyMOLObjectNames, ChainID):
  578     """Write individual chain views."""
  579 
  580     ChainComplexName = PyMOLObjectNames["Chains"][ChainID]["ChainComplex"]
  581 
  582     # Setup chain view...
  583     ChainName = PyMOLObjectNames["Chains"][ChainID]["ChainAlone"]
  584     PML = PyMOLUtil.SetupPMLForPolymerChainView(ChainName, ChainComplexName, Enable=True)
  585     OutFH.write("\n%s\n" % PML)
  586 
  587     # Setup chain putty by B-factor view...
  588     if OptionsInfo["BFactorChainCartoonPutty"]:
  589         BFactorPuttyName = PyMOLObjectNames["Chains"][ChainID]["ChainAloneBFactorPutty"]
  590         PML = PyMOLUtil.SetupPMLForBFactorPuttyView(
  591             BFactorPuttyName, ChainName, ColorPalette=OptionsInfo["BFactorColorPalette"], Enable=False
  592         )
  593         OutFH.write("\n%s\n" % PML)
  594 
  595     # Setup chain selections view...
  596     SetupChainSelectionsView(OutFH, FileIndex, PyMOLObjectNames, ChainID)
  597 
  598     # Setup chain group...
  599     SpecifiedChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex]
  600     EnableChainAloneGroup = SpecifiedChainsAndLigandsInfo["EnableChainAloneGroup"][ChainID]
  601     GenerateAndWritePMLForGroup(
  602         OutFH,
  603         PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroup"],
  604         PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroupMembers"],
  605         EnableChainAloneGroup,
  606         "close",
  607     )
  608 
  609 
  610 def SetupChainSelectionsView(OutFH, FileIndex, PyMOLObjectNames, ChainID):
  611     """Setup chain selections view."""
  612 
  613     if not OptionsInfo["ChainSelections"]:
  614         return
  615 
  616     ChainName = PyMOLObjectNames["Chains"][ChainID]["ChainAlone"]
  617     SelectionsGroupIDPrefix = "ChainAloneSelections"
  618 
  619     for Index in range(0, len(OptionsInfo["ChainSelectionsInfo"]["Names"])):
  620         SelectionName = OptionsInfo["ChainSelectionsInfo"]["Names"][Index]
  621         SpecifiedSelection = OptionsInfo["ChainSelectionsInfo"]["Selections"][Index]
  622 
  623         SelectionNameGroupID = SelectionName
  624 
  625         # Setup selection object...
  626         SelectionObjectID = "%s%sSelection" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
  627         SelectionObjectName = PyMOLObjectNames["Chains"][ChainID][SelectionObjectID]
  628         SelectionCmd = "(%s and (%s))" % (ChainName, SpecifiedSelection)
  629         PML = PyMOLUtil.SetupPMLForSelectionDisplayView(
  630             SelectionObjectName, SelectionCmd, OptionsInfo["SelectionsChainStyle"], Enable=True
  631         )
  632         OutFH.write("\n%s\n" % PML)
  633 
  634         # Set up composite mesh and group...
  635         CompositeMeshID = "%s%sCompositeEDMesh" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
  636         CompositeVolumeID = "%s%sCompositeEDVolume" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
  637         CompositeSurfaceID = "%s%sCompositeEDSurface" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
  638         CompositeMeshGroupID = "%s%sCompositeEDGroup" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
  639         CompositeMeshGroupMembersID = "%s%sCompositeEDGroupMembers" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
  640 
  641         CompositeMapName = PyMOLObjectNames["ComplexCompositeEDMap"]
  642         CompositeMeshName = PyMOLObjectNames["Chains"][ChainID][CompositeMeshID]
  643         CompositeVolumeName = PyMOLObjectNames["Chains"][ChainID][CompositeVolumeID]
  644         CompositeSurfaceName = PyMOLObjectNames["Chains"][ChainID][CompositeSurfaceID]
  645         CompositeMeshGroupName = PyMOLObjectNames["Chains"][ChainID][CompositeMeshGroupID]
  646         CompositeMeshGroupMembers = PyMOLObjectNames["Chains"][ChainID][CompositeMeshGroupMembersID]
  647 
  648         PML = SetupPMLForElectronDensityVolume(
  649             CompositeMapName,
  650             CompositeVolumeName,
  651             OptionsInfo["VolumeColorRampCompositeMap"],
  652             Enable=False,
  653             Selection=SelectionObjectName,
  654         )
  655         OutFH.write("\n%s\n" % PML)
  656 
  657         PML = SetupPMLForElectronDensityMesh(
  658             CompositeMapName,
  659             CompositeMeshName,
  660             OptionsInfo["MeshLevelCompositeMap"],
  661             OptionsInfo["MeshColorCompositeMap"],
  662             Enable=True,
  663             Selection=SelectionObjectName,
  664         )
  665         OutFH.write("\n%s\n" % PML)
  666 
  667         PML = SetupPMLForElectronDensitySurface(
  668             CompositeMapName,
  669             CompositeSurfaceName,
  670             OptionsInfo["MeshLevelCompositeMap"],
  671             OptionsInfo["MeshColorCompositeMap"],
  672             Enable=False,
  673             Selection=SelectionObjectName,
  674         )
  675         OutFH.write("\n%s\n" % PML)
  676 
  677         GenerateAndWritePMLForGroup(OutFH, CompositeMeshGroupName, CompositeMeshGroupMembers, True, "close")
  678 
  679         if PyMOLObjectNames["SetupDiffEDMapObjects"]:
  680             # Set up difference meshes and group...
  681             DiffVolumeID = "%s%sDiffEDVolume" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
  682             DiffMesh1ID = "%s%sDiffEDMesh1" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
  683             DiffSurface1ID = "%s%sDiffEDSurface1" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
  684             DiffMesh2ID = "%s%sDiffEDMesh2" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
  685             DiffSurface2ID = "%s%sDiffEDSurface1" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
  686             DiffMeshGroupID = "%s%sDiffEDGroup" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
  687             DiffMeshGroupMembersID = "%s%sDiffEDGroupMembers" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
  688 
  689             DiffMapName = PyMOLObjectNames["ComplexDiffEDMap"]
  690             DiffVolumeName = PyMOLObjectNames["Chains"][ChainID][DiffVolumeID]
  691             DiffMesh1Name = PyMOLObjectNames["Chains"][ChainID][DiffMesh1ID]
  692             DiffSurface1Name = PyMOLObjectNames["Chains"][ChainID][DiffSurface1ID]
  693             DiffMesh2Name = PyMOLObjectNames["Chains"][ChainID][DiffMesh2ID]
  694             DiffSurface2Name = PyMOLObjectNames["Chains"][ChainID][DiffSurface2ID]
  695             DiffMeshGroupName = PyMOLObjectNames["Chains"][ChainID][DiffMeshGroupID]
  696             DiffMeshGroupMembers = PyMOLObjectNames["Chains"][ChainID][DiffMeshGroupMembersID]
  697 
  698             PML = SetupPMLForElectronDensityVolume(
  699                 DiffMapName,
  700                 DiffVolumeName,
  701                 OptionsInfo["VolumeColorRampDiffMap"],
  702                 Enable=False,
  703                 Selection=SelectionObjectName,
  704             )
  705             OutFH.write("\n%s\n" % PML)
  706 
  707             PML = SetupPMLForElectronDensityMesh(
  708                 DiffMapName,
  709                 DiffMesh1Name,
  710                 OptionsInfo["Mesh1LevelDiffMap"],
  711                 OptionsInfo["Mesh1ColorDiffMap"],
  712                 Enable=True,
  713                 Selection=SelectionObjectName,
  714             )
  715             OutFH.write("\n%s\n" % PML)
  716 
  717             PML = SetupPMLForElectronDensitySurface(
  718                 DiffMapName,
  719                 DiffSurface1Name,
  720                 OptionsInfo["Mesh1LevelDiffMap"],
  721                 OptionsInfo["Mesh1ColorDiffMap"],
  722                 Enable=False,
  723                 Selection=SelectionObjectName,
  724             )
  725             OutFH.write("\n%s\n" % PML)
  726 
  727             PML = SetupPMLForElectronDensityMesh(
  728                 DiffMapName,
  729                 DiffMesh2Name,
  730                 OptionsInfo["Mesh2LevelDiffMap"],
  731                 OptionsInfo["Mesh2ColorDiffMap"],
  732                 Enable=True,
  733                 Selection=SelectionObjectName,
  734             )
  735             OutFH.write("\n%s\n" % PML)
  736 
  737             PML = SetupPMLForElectronDensitySurface(
  738                 DiffMapName,
  739                 DiffSurface2Name,
  740                 OptionsInfo["Mesh2LevelDiffMap"],
  741                 OptionsInfo["Mesh2ColorDiffMap"],
  742                 Enable=False,
  743                 Selection=SelectionObjectName,
  744             )
  745             OutFH.write("\n%s\n" % PML)
  746 
  747             GenerateAndWritePMLForGroup(OutFH, DiffMeshGroupName, DiffMeshGroupMembers, True, "close")
  748 
  749         # Setup groups for named selections...
  750         SelectionsNameGroupID = "%s%sGroup" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
  751         SelectionsNameGroupMembersID = "%s%sGroupMembers" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
  752         GenerateAndWritePMLForGroup(
  753             OutFH,
  754             PyMOLObjectNames["Chains"][ChainID][SelectionsNameGroupID],
  755             PyMOLObjectNames["Chains"][ChainID][SelectionsNameGroupMembersID],
  756             True,
  757             "open",
  758         )
  759 
  760     # Setup a group for selections...
  761     SelectionsGroupID = "%sGroup" % (SelectionsGroupIDPrefix)
  762     SelectionsGroupMembersID = "%sGroupMembers" % (SelectionsGroupIDPrefix)
  763     GenerateAndWritePMLForGroup(
  764         OutFH,
  765         PyMOLObjectNames["Chains"][ChainID][SelectionsGroupID],
  766         PyMOLObjectNames["Chains"][ChainID][SelectionsGroupMembersID],
  767         False,
  768         "close",
  769     )
  770 
  771 
  772 def WriteChainLigandView(OutFH, FileIndex, PyMOLObjectNames, ChainID, LigandID):
  773     """Write out PML for viewing ligand in a chain."""
  774 
  775     for GroupID in ["Ligand", "Pocket", "PocketSolvent", "PocketInorganic"]:
  776         ComplexName = PyMOLObjectNames["Chains"][ChainID]["ChainComplex"]
  777         LigandName = PyMOLObjectNames["Ligands"][ChainID][LigandID]["Ligand"]
  778 
  779         # Setup main object...
  780         GroupTypeObjectID = "%s" % (GroupID)
  781         GroupTypeObjectName = PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupTypeObjectID]
  782 
  783         if re.match("^Ligand$", GroupID, re.I):
  784             OutFH.write("""\n""\n"Setting up views for ligand %s in chain %s..."\n""\n""" % (LigandID, ChainID))
  785             PML = PyMOLUtil.SetupPMLForLigandView(
  786                 GroupTypeObjectName, ComplexName, LigandID, Enable=True, IgnoreHydrogens=OptionsInfo["IgnoreHydrogens"]
  787             )
  788             OutFH.write("%s\n" % PML)
  789         elif re.match("^Pocket$", GroupID, re.I):
  790             OutFH.write(
  791                 """\n""\n"Setting up views for pocket around ligand %s in chain %s..."\n""\n""" % (LigandID, ChainID)
  792             )
  793             PML = PyMOLUtil.SetupPMLForLigandPocketView(
  794                 GroupTypeObjectName,
  795                 ComplexName,
  796                 LigandName,
  797                 OptionsInfo["PocketDistanceCutoff"],
  798                 Enable=True,
  799                 IgnoreHydrogens=OptionsInfo["IgnoreHydrogens"],
  800             )
  801             OutFH.write("%s\n" % PML)
  802             OutFH.write(
  803                 """cmd.set("label_color", "%s", "%s")\n""" % (OptionsInfo["PocketLabelColor"], GroupTypeObjectName)
  804             )
  805         elif re.match("^PocketSolvent$", GroupID, re.I):
  806             OutFH.write(
  807                 """\n""\n"Setting up views for solvent in pockect around ligand %s in chain %s..."\n""\n"""
  808                 % (LigandID, ChainID)
  809             )
  810             PML = PyMOLUtil.SetupPMLForLigandPocketSolventView(
  811                 GroupTypeObjectName, ComplexName, LigandName, OptionsInfo["PocketDistanceCutoff"], Enable=True
  812             )
  813             OutFH.write("%s\n" % PML)
  814         elif re.match("^PocketInorganic$", GroupID, re.I):
  815             OutFH.write(
  816                 """\n""\n"Setting up views for inorganic in pockect around ligand %s in chain %s..."\n""\n"""
  817                 % (LigandID, ChainID)
  818             )
  819             PML = PyMOLUtil.SetupPMLForLigandPocketInorganicView(
  820                 GroupTypeObjectName, ComplexName, LigandName, OptionsInfo["PocketDistanceCutoff"], Enable=True
  821             )
  822             OutFH.write("%s\n" % PML)
  823 
  824         # Set up composite mesh and group...
  825         CompositeMeshGroupID = "%sCompositeEDMeshGroup" % (GroupID)
  826         CompositeMeshGroupMembersID = "%sCompositeEDMeshGroupMembers" % (GroupID)
  827         CompositeMeshID = "%sCompositeEDMesh" % (GroupID)
  828         CompositeVolumeID = "%sCompositeEDVolume" % (GroupID)
  829         CompositeSurfaceID = "%sCompositeEDSurface" % (GroupID)
  830 
  831         CompositeMapName = PyMOLObjectNames["ComplexCompositeEDMap"]
  832         CompositeMeshName = PyMOLObjectNames["Ligands"][ChainID][LigandID][CompositeMeshID]
  833         CompositeVolumeName = PyMOLObjectNames["Ligands"][ChainID][LigandID][CompositeVolumeID]
  834         CompositeSurfaceName = PyMOLObjectNames["Ligands"][ChainID][LigandID][CompositeSurfaceID]
  835         CompositeMeshGroupName = PyMOLObjectNames["Ligands"][ChainID][LigandID][CompositeMeshGroupID]
  836         CompositeMeshGroupMembers = PyMOLObjectNames["Ligands"][ChainID][LigandID][CompositeMeshGroupMembersID]
  837 
  838         PML = SetupPMLForElectronDensityVolume(
  839             CompositeMapName,
  840             CompositeVolumeName,
  841             OptionsInfo["VolumeColorRampCompositeMap"],
  842             Enable=False,
  843             Selection=GroupTypeObjectName,
  844         )
  845         OutFH.write("\n%s\n" % PML)
  846 
  847         PML = SetupPMLForElectronDensityMesh(
  848             CompositeMapName,
  849             CompositeMeshName,
  850             OptionsInfo["MeshLevelCompositeMap"],
  851             OptionsInfo["MeshColorCompositeMap"],
  852             Enable=True,
  853             Selection=GroupTypeObjectName,
  854         )
  855         OutFH.write("\n%s\n" % PML)
  856 
  857         PML = SetupPMLForElectronDensitySurface(
  858             CompositeMapName,
  859             CompositeSurfaceName,
  860             OptionsInfo["MeshLevelCompositeMap"],
  861             OptionsInfo["MeshColorCompositeMap"],
  862             Enable=False,
  863             Selection=GroupTypeObjectName,
  864         )
  865         OutFH.write("\n%s\n" % PML)
  866 
  867         GenerateAndWritePMLForGroup(OutFH, CompositeMeshGroupName, CompositeMeshGroupMembers, True, "close")
  868 
  869         if PyMOLObjectNames["SetupDiffEDMapObjects"]:
  870             # Set up difference meshes and group...
  871             DiffMeshGroupID = "%sDiffEDMeshGroup" % (GroupID)
  872             DiffMeshGroupMembersID = "%sDiffEDMeshGroupMembers" % (GroupID)
  873             DiffVolumeID = "%sDiffEDVolume" % (GroupID)
  874             DiffMesh1ID = "%sDiffEDMesh1" % (GroupID)
  875             DiffSurface1ID = "%sDiffEDSurface1" % (GroupID)
  876             DiffMesh2ID = "%sDiffEDMesh2" % (GroupID)
  877             DiffSurface2ID = "%sDiffEDSurface2" % (GroupID)
  878 
  879             DiffMapName = PyMOLObjectNames["ComplexDiffEDMap"]
  880             DiffVolumeName = PyMOLObjectNames["Ligands"][ChainID][LigandID][DiffVolumeID]
  881             DiffMesh1Name = PyMOLObjectNames["Ligands"][ChainID][LigandID][DiffMesh1ID]
  882             DiffSurface1Name = PyMOLObjectNames["Ligands"][ChainID][LigandID][DiffSurface1ID]
  883             DiffMesh2Name = PyMOLObjectNames["Ligands"][ChainID][LigandID][DiffMesh2ID]
  884             DiffSurface2Name = PyMOLObjectNames["Ligands"][ChainID][LigandID][DiffSurface2ID]
  885             DiffMeshGroupName = PyMOLObjectNames["Ligands"][ChainID][LigandID][DiffMeshGroupID]
  886             DiffMeshGroupMembers = PyMOLObjectNames["Ligands"][ChainID][LigandID][DiffMeshGroupMembersID]
  887 
  888             PML = SetupPMLForElectronDensityVolume(
  889                 DiffMapName,
  890                 DiffVolumeName,
  891                 OptionsInfo["VolumeColorRampDiffMap"],
  892                 Enable=False,
  893                 Selection=GroupTypeObjectName,
  894             )
  895             OutFH.write("\n%s\n" % PML)
  896 
  897             PML = SetupPMLForElectronDensityMesh(
  898                 DiffMapName,
  899                 DiffMesh1Name,
  900                 OptionsInfo["Mesh1LevelDiffMap"],
  901                 OptionsInfo["Mesh1ColorDiffMap"],
  902                 Enable=True,
  903                 Selection=GroupTypeObjectName,
  904             )
  905             OutFH.write("\n%s\n" % PML)
  906 
  907             PML = SetupPMLForElectronDensitySurface(
  908                 DiffMapName,
  909                 DiffSurface1Name,
  910                 OptionsInfo["Mesh1LevelDiffMap"],
  911                 OptionsInfo["Mesh1ColorDiffMap"],
  912                 Enable=False,
  913                 Selection=GroupTypeObjectName,
  914             )
  915             OutFH.write("\n%s\n" % PML)
  916 
  917             PML = SetupPMLForElectronDensityMesh(
  918                 DiffMapName,
  919                 DiffMesh2Name,
  920                 OptionsInfo["Mesh2LevelDiffMap"],
  921                 OptionsInfo["Mesh2ColorDiffMap"],
  922                 Enable=True,
  923                 Selection=GroupTypeObjectName,
  924             )
  925             OutFH.write("\n%s\n" % PML)
  926 
  927             PML = SetupPMLForElectronDensitySurface(
  928                 DiffMapName,
  929                 DiffSurface2Name,
  930                 OptionsInfo["Mesh2LevelDiffMap"],
  931                 OptionsInfo["Mesh2ColorDiffMap"],
  932                 Enable=False,
  933                 Selection=GroupTypeObjectName,
  934             )
  935             OutFH.write("\n%s\n" % PML)
  936 
  937             GenerateAndWritePMLForGroup(OutFH, DiffMeshGroupName, DiffMeshGroupMembers, True, "close")
  938 
  939         # Set up polar contacts...
  940         if re.match("^(Pocket|PocketSolvent|PocketInorganic)$", GroupID, re.I):
  941             PolarContactsID = "%sPolarContacts" % (GroupID)
  942             PolarContactsName = PyMOLObjectNames["Ligands"][ChainID][LigandID][PolarContactsID]
  943 
  944             PolarContactsColor = OptionsInfo["PocketContactsLigandColor"]
  945             if re.match("^PocketSolvent$", GroupID, re.I):
  946                 PolarContactsColor = OptionsInfo["PocketContactsSolventColor"]
  947             elif re.match("^PocketInorganic$", GroupID, re.I):
  948                 PolarContactsColor = OptionsInfo["PocketContactsInorganicColor"]
  949 
  950             PML = PyMOLUtil.SetupPMLForPolarContactsView(
  951                 PolarContactsName,
  952                 LigandName,
  953                 GroupTypeObjectName,
  954                 Enable=False,
  955                 Color=PolarContactsColor,
  956                 Cutoff=OptionsInfo["PocketContactsCutoff"],
  957             )
  958             OutFH.write("\n%s\n" % PML)
  959 
  960             OutFH.write("""cmd.set("label_color", "%s", "%s")\n""" % (PolarContactsColor, PolarContactsName))
  961 
  962         # Set up hydrophobic contacts...
  963         if re.match("^Pocket$", GroupID, re.I):
  964             HydrophobicContactsID = "%sHydrophobicContacts" % (GroupID)
  965             HydrophobicContactsName = PyMOLObjectNames["Ligands"][ChainID][LigandID][HydrophobicContactsID]
  966             HydrophobicContactsColor = OptionsInfo["PocketContactsLigandHydrophobicColor"]
  967 
  968             PML = PyMOLUtil.SetupPMLForHydrophobicContactsView(
  969                 HydrophobicContactsName,
  970                 LigandName,
  971                 GroupTypeObjectName,
  972                 Enable=False,
  973                 Color=HydrophobicContactsColor,
  974                 Cutoff=OptionsInfo["PocketContactsCutoff"],
  975             )
  976             OutFH.write("\n%s\n" % PML)
  977             OutFH.write(
  978                 """cmd.set("label_color", "%s", "%s")\n""" % (HydrophobicContactsColor, HydrophobicContactsName)
  979             )
  980 
  981         # Set up hydrophobic surface...
  982         if re.match("^Pocket$", GroupID, re.I) and OptionsInfo["PocketSurface"]:
  983             HydrophobicSurfaceID = "%sHydrophobicSurface" % (GroupID)
  984             HydrophobicSurfaceName = PyMOLObjectNames["Ligands"][ChainID][LigandID][HydrophobicSurfaceID]
  985             PML = PyMOLUtil.SetupPMLForHydrophobicSurfaceView(
  986                 HydrophobicSurfaceName, GroupTypeObjectName, ColorPalette="RedToWhite", Enable=False
  987             )
  988             OutFH.write("\n%s\n" % PML)
  989 
  990             OutFH.write(
  991                 """cmd.set("label_color", "%s", "%s")\n""" % (OptionsInfo["PocketLabelColor"], HydrophobicSurfaceName)
  992             )
  993 
  994         # Setup group....
  995         GroupNameID = "%sGroup" % (GroupID)
  996         GroupMembersID = "%sGroupMembers" % (GroupID)
  997         GroupName = PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupNameID]
  998         GroupMembers = PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupMembersID]
  999 
 1000         Action = "close"
 1001         Enable = False
 1002         if re.match("^(Ligand|Pocket)$", GroupID, re.I):
 1003             Action = "open"
 1004             Enable = True
 1005         GenerateAndWritePMLForGroup(OutFH, GroupName, GroupMembers, Enable, Action)
 1006 
 1007 
 1008 def GenerateAndWritePMLForGroup(OutFH, GroupName, GroupMembers, Enable=False, Action="close"):
 1009     """Generate and write PML for group."""
 1010 
 1011     PML = PyMOLUtil.SetupPMLForGroup(GroupName, GroupMembers, Enable, Action)
 1012     OutFH.write("""\n""\n"Setting up group %s..."\n""\n""" % GroupName)
 1013     OutFH.write("%s\n" % PML)
 1014 
 1015 
 1016 def SetupPMLForElectronDensityMap(MapFileName, MapName, AlignMapToObjectName=None, Enable=True):
 1017     """Setup PML for loading and viewing electron density map."""
 1018 
 1019     PMLCmds = []
 1020     PMLCmds.append("""cmd.load("%s", "%s")""" % (MapFileName, MapName))
 1021     if AlignMapToObjectName is not None:
 1022         PMLCmds.append("""cmd.matrix_copy("%s", "%s")""" % (AlignMapToObjectName, MapName))
 1023 
 1024     PMLCmds.append(PyMOLUtil.SetupPMLForEnableDisable(MapName, Enable))
 1025 
 1026     PML = "\n".join(PMLCmds)
 1027 
 1028     return PML
 1029 
 1030 
 1031 def SetupPMLForElectronDensityMesh(MapName, MeshName, SigmaLevel, Color, Enable=True, Selection=None):
 1032     """Setup PML for electron density mesh."""
 1033 
 1034     Carve = OptionsInfo["MeshCarveRadius"]
 1035 
 1036     PMLCmds = []
 1037     if Selection is None:
 1038         PMLCmds.append("""cmd.isomesh("%s", "%s", %.1f)""" % (MeshName, MapName, SigmaLevel))
 1039     else:
 1040         PMLCmds.append(
 1041             """cmd.isomesh("%s", "%s", %.1f, "(%s)", carve = %.1f)"""
 1042             % (MeshName, MapName, SigmaLevel, Selection, Carve)
 1043         )
 1044     PMLCmds.append(PyMOLUtil.SetupPMLForDeepColoring(MeshName, Color))
 1045     PMLCmds.append(PyMOLUtil.SetupPMLForEnableDisable(MeshName, Enable))
 1046 
 1047     PML = "\n".join(PMLCmds)
 1048 
 1049     return PML
 1050 
 1051 
 1052 def SetupPMLForElectronDensityVolume(MapName, VolumeName, VolumeColorRamp, Enable=True, Selection=None):
 1053     """Setup PML for electron density volume."""
 1054 
 1055     Carve = OptionsInfo["VolumeCarveRadius"]
 1056 
 1057     PMLCmds = []
 1058     if Selection is None:
 1059         PMLCmds.append("""cmd.volume("%s", "%s", "%s")""" % (VolumeName, MapName, VolumeColorRamp))
 1060     else:
 1061         PMLCmds.append(
 1062             """cmd.volume("%s", "%s", "%s", "(%s)", carve = %.1f)"""
 1063             % (VolumeName, MapName, VolumeColorRamp, Selection, Carve)
 1064         )
 1065     PMLCmds.append(PyMOLUtil.SetupPMLForEnableDisable(VolumeName, Enable))
 1066 
 1067     PML = "\n".join(PMLCmds)
 1068 
 1069     return PML
 1070 
 1071 
 1072 def SetupPMLForElectronDensitySurface(MapName, SurfaceName, SigmaLevel, Color, Enable=True, Selection=None):
 1073     """Setup PML for electron density surface."""
 1074 
 1075     Carve = OptionsInfo["MeshCarveRadius"]
 1076 
 1077     PMLCmds = []
 1078     if Selection is None:
 1079         PMLCmds.append("""cmd.isosurface("%s", "%s", %.1f)""" % (SurfaceName, MapName, SigmaLevel))
 1080     else:
 1081         PMLCmds.append(
 1082             """cmd.isosurface("%s", "%s", %.1f, "(%s)", carve = %.1f)"""
 1083             % (SurfaceName, MapName, SigmaLevel, Selection, Carve)
 1084         )
 1085     PMLCmds.append(PyMOLUtil.SetupPMLForDeepColoring(SurfaceName, Color))
 1086     PMLCmds.append(PyMOLUtil.SetupPMLForEnableDisable(SurfaceName, Enable))
 1087 
 1088     PML = "\n".join(PMLCmds)
 1089 
 1090     return PML
 1091 
 1092 
 1093 def GeneratePyMOLSessionFile():
 1094     """Generate PME file from PML file."""
 1095 
 1096     PSEOutfile = OptionsInfo["PSEOutfile"]
 1097     PMLOutfile = OptionsInfo["PMLOutfile"]
 1098 
 1099     MiscUtil.PrintInfo("\nGenerating file %s..." % PSEOutfile)
 1100 
 1101     PyMOLUtil.ConvertPMLFileToPSEFile(PMLOutfile, PSEOutfile)
 1102 
 1103     if not os.path.exists(PSEOutfile):
 1104         MiscUtil.PrintWarning("Failed to generate PSE file, %s..." % (PSEOutfile))
 1105 
 1106     if not OptionsInfo["PMLOut"]:
 1107         MiscUtil.PrintInfo("Deleting file %s..." % PMLOutfile)
 1108         os.remove(PMLOutfile)
 1109 
 1110 
 1111 def DeleteEmptyPyMOLObjects(OutFH, FileIndex, PyMOLObjectNames):
 1112     """Delete empty PyMOL objects."""
 1113 
 1114     if OptionsInfo["AllowEmptyObjects"]:
 1115         return
 1116 
 1117     SpecifiedChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex]
 1118     for ChainID in SpecifiedChainsAndLigandsInfo["ChainIDs"]:
 1119         OutFH.write("""\n""\n"Checking and deleting empty objects for chain %s..."\n""\n""" % (ChainID))
 1120 
 1121         # Delete any chain level objects...
 1122         WritePMLToCheckAndDeleteEmptyObjects(OutFH, PyMOLObjectNames["Chains"][ChainID]["Solvent"])
 1123         WritePMLToCheckAndDeleteEmptyObjects(OutFH, PyMOLObjectNames["Chains"][ChainID]["Inorganic"])
 1124 
 1125         for LigandID in SpecifiedChainsAndLigandsInfo["LigandIDs"][ChainID]:
 1126             # Delete ligand level objects...
 1127             for GroupID in ["Pocket", "PocketSolvent", "PocketInorganic"]:
 1128                 GroupNameID = "%sGroup" % (GroupID)
 1129                 GroupName = PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupNameID]
 1130 
 1131                 GroupTypeObjectID = "%s" % (GroupID)
 1132                 GroupTypeObjectName = PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupTypeObjectID]
 1133 
 1134                 WritePMLToCheckAndDeleteEmptyObjects(OutFH, GroupTypeObjectName, GroupName)
 1135 
 1136 
 1137 def WritePMLToCheckAndDeleteEmptyObjects(OutFH, ObjectName, ParentObjectName=None):
 1138     """Write PML to check and delete empty PyMOL objects."""
 1139 
 1140     if ParentObjectName is None:
 1141         PML = """CheckAndDeleteEmptyObjects("%s")""" % (ObjectName)
 1142     else:
 1143         PML = """CheckAndDeleteEmptyObjects("%s", "%s")""" % (ObjectName, ParentObjectName)
 1144 
 1145     OutFH.write("%s\n" % PML)
 1146 
 1147 
 1148 def SetupPyMOLObjectNames(FileIndex):
 1149     """Setup hierarchy of PyMOL groups and objects for ligand centric views of
 1150     electron density for chains and ligands present in input file.
 1151     """
 1152 
 1153     PyMOLObjectNames = {}
 1154     PyMOLObjectNames["Chains"] = {}
 1155     PyMOLObjectNames["Ligands"] = {}
 1156 
 1157     PyMOLObjectNames["SetupDiffEDMapObjects"] = False if OptionsInfo["DiffEDMapFiles"][FileIndex] is None else True
 1158 
 1159     # Setup groups and objects for complex...
 1160     SetupPyMOLObjectNamesForComplex(FileIndex, PyMOLObjectNames)
 1161 
 1162     # Setup groups and objects for chain...
 1163     SpecifiedChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex]
 1164     for ChainID in SpecifiedChainsAndLigandsInfo["ChainIDs"]:
 1165         SetupPyMOLObjectNamesForChain(FileIndex, PyMOLObjectNames, ChainID)
 1166 
 1167         # Setup groups and objects for ligand...
 1168         for LigandID in SpecifiedChainsAndLigandsInfo["LigandIDs"][ChainID]:
 1169             SetupPyMOLObjectNamesForLigand(FileIndex, PyMOLObjectNames, ChainID, LigandID)
 1170 
 1171     return PyMOLObjectNames
 1172 
 1173 
 1174 def SetupPyMOLObjectNamesForComplex(FileIndex, PyMOLObjectNames):
 1175     """Setup groups and objects for complex."""
 1176 
 1177     PDBFileRoot = OptionsInfo["InfilesInfo"]["InfilesRoots"][FileIndex]
 1178 
 1179     PDBGroupName = "%s" % PDBFileRoot
 1180     PyMOLObjectNames["PDBGroup"] = PDBGroupName
 1181     PyMOLObjectNames["PDBGroupMembers"] = []
 1182 
 1183     ComplexGroupName = "%s.Complex" % PyMOLObjectNames["PDBGroup"]
 1184     PyMOLObjectNames["ComplexGroup"] = ComplexGroupName
 1185     PyMOLObjectNames["PDBGroupMembers"].append(ComplexGroupName)
 1186 
 1187     PyMOLObjectNames["Complex"] = "%s.Complex" % ComplexGroupName
 1188 
 1189     CompositeMeshGroupName = "%s.2Fo-Fc" % (ComplexGroupName)
 1190     CompositeMapName = "%s.Map" % (CompositeMeshGroupName)
 1191     CompositeMeshName = "%s.Mesh" % (CompositeMeshGroupName)
 1192     CompositeVolumeName = "%s.Volume" % (CompositeMeshGroupName)
 1193     CompositeSurfaceName = "%s.Surface" % (CompositeMeshGroupName)
 1194 
 1195     PyMOLObjectNames["ComplexCompositeEDGroup"] = CompositeMeshGroupName
 1196     PyMOLObjectNames["ComplexCompositeEDMap"] = CompositeMapName
 1197     PyMOLObjectNames["ComplexCompositeEDMesh"] = CompositeMeshName
 1198     PyMOLObjectNames["ComplexCompositeEDVolume"] = CompositeVolumeName
 1199     PyMOLObjectNames["ComplexCompositeEDSurface"] = CompositeSurfaceName
 1200 
 1201     PyMOLObjectNames["ComplexCompositeEDGroupMembers"] = []
 1202     PyMOLObjectNames["ComplexCompositeEDGroupMembers"].append(CompositeMapName)
 1203     if OptionsInfo["VolumeComplex"]:
 1204         PyMOLObjectNames["ComplexCompositeEDGroupMembers"].append(CompositeVolumeName)
 1205     if OptionsInfo["MeshComplex"]:
 1206         PyMOLObjectNames["ComplexCompositeEDGroupMembers"].append(CompositeMeshName)
 1207     if OptionsInfo["SurfaceComplex"]:
 1208         PyMOLObjectNames["ComplexCompositeEDGroupMembers"].append(CompositeSurfaceName)
 1209     if PyMOLObjectNames["SetupDiffEDMapObjects"]:
 1210         DiffMeshGroupName = "%s.Fo-Fc" % ComplexGroupName
 1211         DiffMapName = "%s.Map" % DiffMeshGroupName
 1212         DiffVolumeName = "%s.Volume" % DiffMeshGroupName
 1213         DiffMesh1Name = "%s.Mesh1" % DiffMeshGroupName
 1214         DiffSurface1Name = "%s.Surface1" % DiffMeshGroupName
 1215         DiffMesh2Name = "%s.Mesh2" % DiffMeshGroupName
 1216         DiffSurface2Name = "%s.Surface2" % DiffMeshGroupName
 1217 
 1218         PyMOLObjectNames["ComplexDiffEDGroup"] = DiffMeshGroupName
 1219         PyMOLObjectNames["ComplexDiffEDMap"] = DiffMapName
 1220         PyMOLObjectNames["ComplexDiffEDVolume"] = DiffVolumeName
 1221         PyMOLObjectNames["ComplexDiffEDMesh1"] = DiffMesh1Name
 1222         PyMOLObjectNames["ComplexDiffEDSurface1"] = DiffSurface1Name
 1223         PyMOLObjectNames["ComplexDiffEDMesh2"] = DiffMesh2Name
 1224         PyMOLObjectNames["ComplexDiffEDSurface2"] = DiffSurface2Name
 1225 
 1226         PyMOLObjectNames["ComplexDiffEDGroupMembers"] = []
 1227         PyMOLObjectNames["ComplexDiffEDGroupMembers"].append(DiffMapName)
 1228         if OptionsInfo["VolumeComplex"]:
 1229             PyMOLObjectNames["ComplexDiffEDGroupMembers"].append(DiffVolumeName)
 1230         if OptionsInfo["MeshComplex"]:
 1231             PyMOLObjectNames["ComplexDiffEDGroupMembers"].append(DiffMesh1Name)
 1232         if OptionsInfo["SurfaceComplex"]:
 1233             PyMOLObjectNames["ComplexDiffEDGroupMembers"].append(DiffSurface1Name)
 1234         if OptionsInfo["MeshComplex"]:
 1235             PyMOLObjectNames["ComplexDiffEDGroupMembers"].append(DiffMesh2Name)
 1236         if OptionsInfo["SurfaceComplex"]:
 1237             PyMOLObjectNames["ComplexDiffEDGroupMembers"].append(DiffSurface2Name)
 1238 
 1239     PyMOLObjectNames["ComplexGroupMembers"] = []
 1240     PyMOLObjectNames["ComplexGroupMembers"].append(PyMOLObjectNames["Complex"])
 1241     PyMOLObjectNames["ComplexGroupMembers"].append(PyMOLObjectNames["ComplexCompositeEDGroup"])
 1242     if PyMOLObjectNames["SetupDiffEDMapObjects"]:
 1243         PyMOLObjectNames["ComplexGroupMembers"].append(PyMOLObjectNames["ComplexDiffEDGroup"])
 1244 
 1245 
 1246 def SetupPyMOLObjectNamesForChain(FileIndex, PyMOLObjectNames, ChainID):
 1247     """Setup groups and objects for chain."""
 1248 
 1249     PDBGroupName = PyMOLObjectNames["PDBGroup"]
 1250 
 1251     SpecifiedChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"][FileIndex]
 1252     MeshChainComplex = SpecifiedChainsAndLigandsInfo["MeshChainComplex"][ChainID]
 1253     VolumeChainComplex = SpecifiedChainsAndLigandsInfo["VolumeChainComplex"][ChainID]
 1254     SurfaceChainComplex = SpecifiedChainsAndLigandsInfo["SurfaceChainComplex"][ChainID]
 1255 
 1256     PyMOLObjectNames["Chains"][ChainID] = {}
 1257     PyMOLObjectNames["Ligands"][ChainID] = {}
 1258 
 1259     # Set up chain group and chain objects...
 1260     ChainGroupName = "%s.Chain%s" % (PDBGroupName, ChainID)
 1261     PyMOLObjectNames["Chains"][ChainID]["ChainGroup"] = ChainGroupName
 1262     PyMOLObjectNames["PDBGroupMembers"].append(ChainGroupName)
 1263     PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"] = []
 1264 
 1265     # Setup chain complex group and objects...
 1266     ChainComplexGroupName = "%s.Complex" % (ChainGroupName)
 1267     PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroup"] = ChainComplexGroupName
 1268     PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"].append(ChainComplexGroupName)
 1269 
 1270     PyMOLObjectNames["Chains"][ChainID]["ChainComplex"] = "%s.Complex" % (ChainComplexGroupName)
 1271 
 1272     CompositeMeshGroupName = "%s.2Fo-Fc" % (ChainComplexGroupName)
 1273     CompositeMeshName = "%s.Mesh" % (CompositeMeshGroupName)
 1274     CompositeVolumeName = "%s.Volume" % (CompositeMeshGroupName)
 1275     CompositeSurfaceName = "%s.Surface" % (CompositeMeshGroupName)
 1276 
 1277     PyMOLObjectNames["Chains"][ChainID]["ChainComplexCompositeEDGroup"] = CompositeMeshGroupName
 1278     PyMOLObjectNames["Chains"][ChainID]["ChainComplexCompositeEDMesh"] = CompositeMeshName
 1279     PyMOLObjectNames["Chains"][ChainID]["ChainComplexCompositeEDVolume"] = CompositeVolumeName
 1280     PyMOLObjectNames["Chains"][ChainID]["ChainComplexCompositeEDSurface"] = CompositeSurfaceName
 1281 
 1282     PyMOLObjectNames["Chains"][ChainID]["ChainComplexCompositeEDGroupMembers"] = []
 1283     if VolumeChainComplex:
 1284         PyMOLObjectNames["Chains"][ChainID]["ChainComplexCompositeEDGroupMembers"].append(CompositeVolumeName)
 1285     if MeshChainComplex:
 1286         PyMOLObjectNames["Chains"][ChainID]["ChainComplexCompositeEDGroupMembers"].append(CompositeMeshName)
 1287     if SurfaceChainComplex:
 1288         PyMOLObjectNames["Chains"][ChainID]["ChainComplexCompositeEDGroupMembers"].append(CompositeSurfaceName)
 1289 
 1290     if PyMOLObjectNames["SetupDiffEDMapObjects"]:
 1291         DiffMeshGroupName = "%s.Fo-Fc" % (ChainComplexGroupName)
 1292         DiffVolumeName = "%s.Volume" % (DiffMeshGroupName)
 1293         DiffMesh1Name = "%s.Mesh1" % (DiffMeshGroupName)
 1294         DiffSurface1Name = "%s.Surface1" % (DiffMeshGroupName)
 1295         DiffMesh2Name = "%s.Mesh2" % (DiffMeshGroupName)
 1296         DiffSurface2Name = "%s.Surface2" % (DiffMeshGroupName)
 1297 
 1298         PyMOLObjectNames["Chains"][ChainID]["ChainComplexDiffEDGroup"] = DiffMeshGroupName
 1299         PyMOLObjectNames["Chains"][ChainID]["ChainComplexDiffEDVolume"] = DiffVolumeName
 1300         PyMOLObjectNames["Chains"][ChainID]["ChainComplexDiffEDMesh1"] = DiffMesh1Name
 1301         PyMOLObjectNames["Chains"][ChainID]["ChainComplexDiffEDSurface1"] = DiffSurface1Name
 1302         PyMOLObjectNames["Chains"][ChainID]["ChainComplexDiffEDMesh2"] = DiffMesh2Name
 1303         PyMOLObjectNames["Chains"][ChainID]["ChainComplexDiffEDSurface2"] = DiffSurface2Name
 1304 
 1305         PyMOLObjectNames["Chains"][ChainID]["ChainComplexDiffEDGroupMembers"] = []
 1306         if VolumeChainComplex:
 1307             PyMOLObjectNames["Chains"][ChainID]["ChainComplexDiffEDGroupMembers"].append(DiffVolumeName)
 1308         if MeshChainComplex:
 1309             PyMOLObjectNames["Chains"][ChainID]["ChainComplexDiffEDGroupMembers"].append(DiffMesh1Name)
 1310         if SurfaceChainComplex:
 1311             PyMOLObjectNames["Chains"][ChainID]["ChainComplexDiffEDGroupMembers"].append(DiffSurface1Name)
 1312         if MeshChainComplex:
 1313             PyMOLObjectNames["Chains"][ChainID]["ChainComplexDiffEDGroupMembers"].append(DiffMesh2Name)
 1314         if SurfaceChainComplex:
 1315             PyMOLObjectNames["Chains"][ChainID]["ChainComplexDiffEDGroupMembers"].append(DiffSurface2Name)
 1316 
 1317     NameIDs = ["ChainComplex"]
 1318     if MeshChainComplex or VolumeChainComplex or SurfaceChainComplex:
 1319         NameIDs.append("ChainComplexCompositeEDGroup")
 1320         if PyMOLObjectNames["SetupDiffEDMapObjects"]:
 1321             NameIDs.append("ChainComplexDiffEDGroup")
 1322 
 1323     PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroupMembers"] = []
 1324     for NameID in NameIDs:
 1325         Name = PyMOLObjectNames["Chains"][ChainID][NameID]
 1326         PyMOLObjectNames["Chains"][ChainID]["ChainComplexGroupMembers"].append(Name)
 1327 
 1328     # Setup up a group for individual chains...
 1329     ChainAloneGroupName = "%s.Chain" % (ChainGroupName)
 1330     PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroup"] = ChainAloneGroupName
 1331     PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"].append(ChainAloneGroupName)
 1332 
 1333     PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroupMembers"] = []
 1334 
 1335     Name = "%s.Chain" % (ChainAloneGroupName)
 1336     PyMOLObjectNames["Chains"][ChainID]["ChainAlone"] = Name
 1337     PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroupMembers"].append(Name)
 1338 
 1339     if OptionsInfo["BFactorChainCartoonPutty"]:
 1340         Name = "%s.BFactor" % (ChainAloneGroupName)
 1341         PyMOLObjectNames["Chains"][ChainID]["ChainAloneBFactorPutty"] = Name
 1342         PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroupMembers"].append(Name)
 1343 
 1344     if OptionsInfo["ChainSelections"]:
 1345         # Setup selections group and its subgroups..
 1346         SelectionsGroupName = "%s.Selections" % (ChainAloneGroupName)
 1347 
 1348         SelectionsGroupIDPrefix = "ChainAloneSelections"
 1349         SelectionsGroupID = "%sGroup" % SelectionsGroupIDPrefix
 1350 
 1351         # Add selections group to chain alone group...
 1352         PyMOLObjectNames["Chains"][ChainID][SelectionsGroupID] = SelectionsGroupName
 1353         PyMOLObjectNames["Chains"][ChainID]["ChainAloneGroupMembers"].append(SelectionsGroupName)
 1354 
 1355         # Initialize selections group members...
 1356         SelectionsGroupMembersID = "%sGroupMembers" % SelectionsGroupIDPrefix
 1357         PyMOLObjectNames["Chains"][ChainID][SelectionsGroupMembersID] = []
 1358 
 1359         # Setup selections name sub group and its members...
 1360         for SelectionName in OptionsInfo["ChainSelectionsInfo"]["Names"]:
 1361             SelectionNameGroupID = SelectionName
 1362 
 1363             SelectionsNameGroupName = "%s.%s" % (SelectionsGroupName, SelectionName)
 1364             SelectionsNameGroupID = "%s%sGroup" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
 1365 
 1366             # Add selections name sub group to selections group...
 1367             PyMOLObjectNames["Chains"][ChainID][SelectionsNameGroupID] = SelectionsNameGroupName
 1368             PyMOLObjectNames["Chains"][ChainID][SelectionsGroupMembersID].append(SelectionsNameGroupName)
 1369 
 1370             # Initialize selections names sub group members...
 1371             SelectionsNameGroupMembersID = "%s%sGroupMembers" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
 1372             PyMOLObjectNames["Chains"][ChainID][SelectionsNameGroupMembersID] = []
 1373 
 1374             # Add selection object to selections name group...
 1375             SelectionObjectName = "%s.Selection" % (SelectionsNameGroupName)
 1376             SelectionObjectID = "%s%sSelection" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
 1377 
 1378             PyMOLObjectNames["Chains"][ChainID][SelectionObjectID] = SelectionObjectName
 1379             PyMOLObjectNames["Chains"][ChainID][SelectionsNameGroupMembersID].append(SelectionObjectName)
 1380 
 1381             # Setup composite mesh group and add it to selections name group...
 1382             CompositeMeshGroupName = "%s.2Fo-Fc" % (SelectionsNameGroupName)
 1383             CompositeMeshGroupID = "%s%sCompositeEDGroup" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
 1384 
 1385             PyMOLObjectNames["Chains"][ChainID][CompositeMeshGroupID] = CompositeMeshGroupName
 1386             PyMOLObjectNames["Chains"][ChainID][SelectionsNameGroupMembersID].append(CompositeMeshGroupName)
 1387 
 1388             # Initialize composite mesh group members...
 1389             CompositeMeshGroupMembersID = "%s%sCompositeEDGroupMembers" % (
 1390                 SelectionsGroupIDPrefix,
 1391                 SelectionNameGroupID,
 1392             )
 1393             PyMOLObjectNames["Chains"][ChainID][CompositeMeshGroupMembersID] = []
 1394 
 1395             # Setup members of composite mesh group...
 1396             CompositeMeshName = "%s.Mesh" % (CompositeMeshGroupName)
 1397             CompositeMeshID = "%s%sCompositeEDMesh" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
 1398             CompositeVolumeName = "%s.Volume" % (CompositeMeshGroupName)
 1399             CompositeVolumeID = "%s%sCompositeEDVolume" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
 1400             CompositeSurfaceName = "%s.Surface" % (CompositeMeshGroupName)
 1401             CompositeSurfaceID = "%s%sCompositeEDSurface" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
 1402 
 1403             PyMOLObjectNames["Chains"][ChainID][CompositeMeshID] = CompositeMeshName
 1404             PyMOLObjectNames["Chains"][ChainID][CompositeVolumeID] = CompositeVolumeName
 1405             PyMOLObjectNames["Chains"][ChainID][CompositeSurfaceID] = CompositeSurfaceName
 1406 
 1407             PyMOLObjectNames["Chains"][ChainID][CompositeMeshGroupMembersID].append(CompositeMeshName)
 1408             PyMOLObjectNames["Chains"][ChainID][CompositeMeshGroupMembersID].append(CompositeVolumeName)
 1409             PyMOLObjectNames["Chains"][ChainID][CompositeMeshGroupMembersID].append(CompositeSurfaceName)
 1410 
 1411             if PyMOLObjectNames["SetupDiffEDMapObjects"]:
 1412                 # Setup diff mesh group and add it to selections name group...
 1413                 DiffMeshGroupName = "%s.Fo-Fc" % (SelectionsNameGroupName)
 1414                 DiffMeshGroupID = "%s%sDiffEDGroup" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
 1415 
 1416                 PyMOLObjectNames["Chains"][ChainID][DiffMeshGroupID] = DiffMeshGroupName
 1417                 PyMOLObjectNames["Chains"][ChainID][SelectionsNameGroupMembersID].append(DiffMeshGroupName)
 1418 
 1419                 # Initialize diff mesh group members...
 1420                 DiffMeshGroupMembersID = "%s%sDiffEDGroupMembers" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
 1421                 PyMOLObjectNames["Chains"][ChainID][DiffMeshGroupMembersID] = []
 1422 
 1423                 # Setup members of diff mesh group...
 1424                 DiffVolumeName = "%s.Volume" % (DiffMeshGroupName)
 1425                 DiffVolumeID = "%s%sDiffEDVolume" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
 1426 
 1427                 DiffMesh1Name = "%s.Mesh1" % (DiffMeshGroupName)
 1428                 DiffMesh1ID = "%s%sDiffEDMesh1" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
 1429                 DiffSurface1Name = "%s.Surface1" % (DiffMeshGroupName)
 1430                 DiffSurface1ID = "%s%sDiffEDSurface1" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
 1431 
 1432                 DiffMesh2Name = "%s.Mesh2" % (DiffMeshGroupName)
 1433                 DiffMesh2ID = "%s%sDiffEDMesh2" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
 1434                 DiffSurface2Name = "%s.Surface2" % (DiffMeshGroupName)
 1435                 DiffSurface2ID = "%s%sDiffEDSurface1" % (SelectionsGroupIDPrefix, SelectionNameGroupID)
 1436 
 1437                 PyMOLObjectNames["Chains"][ChainID][DiffVolumeID] = DiffVolumeName
 1438                 PyMOLObjectNames["Chains"][ChainID][DiffMesh1ID] = DiffMesh1Name
 1439                 PyMOLObjectNames["Chains"][ChainID][DiffSurface1ID] = DiffSurface1Name
 1440                 PyMOLObjectNames["Chains"][ChainID][DiffMesh2ID] = DiffMesh2Name
 1441                 PyMOLObjectNames["Chains"][ChainID][DiffSurface2ID] = DiffSurface2Name
 1442 
 1443                 PyMOLObjectNames["Chains"][ChainID][DiffMeshGroupMembersID] = []
 1444                 PyMOLObjectNames["Chains"][ChainID][DiffMeshGroupMembersID].append(DiffVolumeName)
 1445                 PyMOLObjectNames["Chains"][ChainID][DiffMeshGroupMembersID].append(DiffMesh1Name)
 1446                 PyMOLObjectNames["Chains"][ChainID][DiffMeshGroupMembersID].append(DiffSurface1Name)
 1447                 PyMOLObjectNames["Chains"][ChainID][DiffMeshGroupMembersID].append(DiffMesh2Name)
 1448                 PyMOLObjectNames["Chains"][ChainID][DiffMeshGroupMembersID].append(DiffSurface2Name)
 1449 
 1450     # Setup solvent and inorganic objects for chain...
 1451     for NameID in ["Solvent", "Inorganic"]:
 1452         Name = "%s.%s" % (ChainGroupName, NameID)
 1453         PyMOLObjectNames["Chains"][ChainID][NameID] = Name
 1454         PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"].append(Name)
 1455 
 1456 
 1457 def SetupPyMOLObjectNamesForLigand(FileIndex, PyMOLObjectNames, ChainID, LigandID):
 1458     """Stetup groups and objects for ligand."""
 1459 
 1460     PyMOLObjectNames["Ligands"][ChainID][LigandID] = {}
 1461 
 1462     ChainGroupName = PyMOLObjectNames["Chains"][ChainID]["ChainGroup"]
 1463 
 1464     # Setup a chain level ligand group...
 1465     ChainLigandGroupName = "%s.Ligand%s" % (ChainGroupName, LigandID)
 1466     PyMOLObjectNames["Ligands"][ChainID][LigandID]["ChainLigandGroup"] = ChainLigandGroupName
 1467     PyMOLObjectNames["Chains"][ChainID]["ChainGroupMembers"].append(ChainLigandGroupName)
 1468 
 1469     PyMOLObjectNames["Ligands"][ChainID][LigandID]["ChainLigandGroupMembers"] = []
 1470 
 1471     # Set up groups and objects for a specific ligand group...
 1472     for GroupType in ["Ligand", "Pocket", "Pocket_Solvent", "Pocket_Inorganic"]:
 1473         GroupID = re.sub("_", "", GroupType)
 1474         GroupName = "%s.%s" % (ChainLigandGroupName, GroupType)
 1475 
 1476         GroupNameID = "%sGroup" % (GroupID)
 1477         GroupMembersID = "%sGroupMembers" % (GroupID)
 1478 
 1479         PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupNameID] = GroupName
 1480         PyMOLObjectNames["Ligands"][ChainID][LigandID]["ChainLigandGroupMembers"].append(GroupName)
 1481 
 1482         GroupTypeObjectName = "%s.%s" % (GroupName, GroupType)
 1483         GroupTypeObjectID = "%s" % (GroupID)
 1484         PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupTypeObjectID] = GroupTypeObjectName
 1485 
 1486         CompositeMeshGroupName = "%s.2Fo-Fc" % (GroupName)
 1487         CompositeMeshName = "%s.Mesh" % (CompositeMeshGroupName)
 1488         CompositeVolumeName = "%s.Volume" % (CompositeMeshGroupName)
 1489         CompositeSurfaceName = "%s.Surface" % (CompositeMeshGroupName)
 1490 
 1491         CompositeMeshGroupID = "%sCompositeEDMeshGroup" % (GroupID)
 1492         CompositeMeshGroupMembersID = "%sCompositeEDMeshGroupMembers" % (GroupID)
 1493         CompositeMeshID = "%sCompositeEDMesh" % (GroupID)
 1494         CompositeVolumeID = "%sCompositeEDVolume" % (GroupID)
 1495         CompositeSurfaceID = "%sCompositeEDSurface" % (GroupID)
 1496 
 1497         PyMOLObjectNames["Ligands"][ChainID][LigandID][CompositeMeshGroupID] = CompositeMeshGroupName
 1498         PyMOLObjectNames["Ligands"][ChainID][LigandID][CompositeMeshID] = CompositeMeshName
 1499         PyMOLObjectNames["Ligands"][ChainID][LigandID][CompositeVolumeID] = CompositeVolumeName
 1500         PyMOLObjectNames["Ligands"][ChainID][LigandID][CompositeSurfaceID] = CompositeSurfaceName
 1501         PyMOLObjectNames["Ligands"][ChainID][LigandID][CompositeMeshGroupMembersID] = []
 1502         PyMOLObjectNames["Ligands"][ChainID][LigandID][CompositeMeshGroupMembersID].append(CompositeVolumeName)
 1503         PyMOLObjectNames["Ligands"][ChainID][LigandID][CompositeMeshGroupMembersID].append(CompositeMeshName)
 1504         PyMOLObjectNames["Ligands"][ChainID][LigandID][CompositeMeshGroupMembersID].append(CompositeSurfaceName)
 1505 
 1506         if PyMOLObjectNames["SetupDiffEDMapObjects"]:
 1507             DiffMeshGroupName = "%s.Fo-Fc" % GroupName
 1508             DiffVolumeName = "%s.Volume" % DiffMeshGroupName
 1509             DiffMesh1Name = "%s.Mesh1" % DiffMeshGroupName
 1510             DiffSurface1Name = "%s.Surface1" % DiffMeshGroupName
 1511             DiffMesh2Name = "%s.Mesh2" % DiffMeshGroupName
 1512             DiffSurface2Name = "%s.Surface2" % DiffMeshGroupName
 1513 
 1514             DiffMeshGroupID = "%sDiffEDMeshGroup" % (GroupID)
 1515             DiffMeshGroupMembersID = "%sDiffEDMeshGroupMembers" % (GroupID)
 1516             DiffVolumeID = "%sDiffEDVolume" % (GroupID)
 1517             DiffMesh1ID = "%sDiffEDMesh1" % (GroupID)
 1518             DiffSurface1ID = "%sDiffEDSurface1" % (GroupID)
 1519             DiffMesh2ID = "%sDiffEDMesh2" % (GroupID)
 1520             DiffSurface2ID = "%sDiffEDSurface2" % (GroupID)
 1521 
 1522             PyMOLObjectNames["Ligands"][ChainID][LigandID][DiffMeshGroupID] = DiffMeshGroupName
 1523             PyMOLObjectNames["Ligands"][ChainID][LigandID][DiffVolumeID] = DiffVolumeName
 1524             PyMOLObjectNames["Ligands"][ChainID][LigandID][DiffMesh1ID] = DiffMesh1Name
 1525             PyMOLObjectNames["Ligands"][ChainID][LigandID][DiffSurface1ID] = DiffSurface1Name
 1526             PyMOLObjectNames["Ligands"][ChainID][LigandID][DiffMesh2ID] = DiffMesh2Name
 1527             PyMOLObjectNames["Ligands"][ChainID][LigandID][DiffSurface2ID] = DiffSurface2Name
 1528             PyMOLObjectNames["Ligands"][ChainID][LigandID][DiffMeshGroupMembersID] = []
 1529             PyMOLObjectNames["Ligands"][ChainID][LigandID][DiffMeshGroupMembersID].extend(
 1530                 [DiffVolumeName, DiffMesh1Name, DiffSurface1Name, DiffMesh2Name, DiffSurface2Name]
 1531             )
 1532 
 1533         PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupMembersID] = []
 1534         NameIDs = [GroupTypeObjectID, CompositeMeshGroupID]
 1535         if PyMOLObjectNames["SetupDiffEDMapObjects"]:
 1536             NameIDs.append(DiffMeshGroupID)
 1537 
 1538         for NameID in NameIDs:
 1539             Name = PyMOLObjectNames["Ligands"][ChainID][LigandID][NameID]
 1540             PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupMembersID].append(Name)
 1541 
 1542         if re.match("^Ligand$", GroupType, re.I):
 1543             # No other object needed for Ligand group...
 1544             continue
 1545 
 1546         PolarContactsName = "%s.Polar_Contacts" % (GroupName)
 1547         PolarContactsID = "%sPolarContacts" % (GroupID)
 1548         PyMOLObjectNames["Ligands"][ChainID][LigandID][PolarContactsID] = PolarContactsName
 1549         PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupMembersID].append(PolarContactsName)
 1550 
 1551         if not re.match("^Pocket$", GroupType, re.I):
 1552             # No other object needed for any other group besides Pocket...
 1553             continue
 1554 
 1555         if not OptionsInfo["PocketSurface"]:
 1556             continue
 1557 
 1558         HydrophobicContactsName = "%s.Hydrophobic_Contacts" % (GroupName)
 1559         HydrophobicContactsID = "%sHydrophobicContacts" % (GroupID)
 1560         PyMOLObjectNames["Ligands"][ChainID][LigandID][HydrophobicContactsID] = HydrophobicContactsName
 1561         PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupMembersID].append(HydrophobicContactsName)
 1562 
 1563         HydrophobicSurfaceName = "%s.Surface" % (GroupName)
 1564         HydrophobicSurfaceID = "%sHydrophobicSurface" % (GroupID)
 1565         PyMOLObjectNames["Ligands"][ChainID][LigandID][HydrophobicSurfaceID] = HydrophobicSurfaceName
 1566         PyMOLObjectNames["Ligands"][ChainID][LigandID][GroupMembersID].append(HydrophobicSurfaceName)
 1567 
 1568 
 1569 def ProcessEDMapFilesAndSuffixes():
 1570     """Process specified ED map files or suffixes for input files."""
 1571 
 1572     EDMapFiles = OptionsInfo["EDMapFiles"]
 1573     EDMapSuffixes = OptionsInfo["EDMapSuffixes"]
 1574 
 1575     if (not re.match("^auto$", EDMapFiles, re.I)) and (not re.match("^auto$", EDMapSuffixes, re.I)):
 1576         MiscUtil.PrintError(
 1577             'The values, "%s" and "%s", specified using "--EDMapFiles" and "--EDMapSuffixes" are not valid. Both of these options can\'t be specified simultaneously.'
 1578             % (EDMapFiles, EDMapSuffixes)
 1579         )
 1580 
 1581     if not re.match("^auto$", EDMapFiles, re.I):
 1582         ProcessEDMapFiles()
 1583     else:
 1584         ProcessEDMapSuffixes()
 1585 
 1586 
 1587 def ProcessEDMapFiles():
 1588     """Process specified ED map files."""
 1589 
 1590     EDMapFiles = re.sub(" ", "", OptionsInfo["EDMapFiles"])
 1591     if not EDMapFiles:
 1592         MiscUtil.PrintError('No valid parameter name and value pairs specified using "--EDMapFiles" option.')
 1593 
 1594     EDMapFilesWords = EDMapFiles.split(",")
 1595     EDMapFilesWordsCount = len(EDMapFilesWords)
 1596     if EDMapFilesWordsCount % 2:
 1597         MiscUtil.PrintError(
 1598             'The number of comma delimited ED map files, %d, specified using "--EDMapFiles" option must be an even number.'
 1599             % (EDMapFilesWordsCount)
 1600         )
 1601 
 1602     InfilesNamesCount = len(OptionsInfo["InfilesNames"])
 1603     if EDMapFilesWordsCount != 2 * InfilesNamesCount:
 1604         MiscUtil.PrintError(
 1605             'The number of comma delimited ED map files, %d, specified using "--EDMapFiles" must be twice the number of input files, %s, specified using "-i, --infiles" option.'
 1606             % (EDMapFilesWordsCount, InfilesNamesCount)
 1607         )
 1608 
 1609     OptionsInfo["CompositeEDMapFiles"] = []
 1610     OptionsInfo["DiffEDMapFiles"] = []
 1611 
 1612     CompositeEDMapFiles = []
 1613     DiffEDMapFiles = []
 1614     for Index in range(0, EDMapFilesWordsCount, 2):
 1615         CompositeEDMapFiles.append(EDMapFilesWords[Index])
 1616         DiffEDMapFiles.append(EDMapFilesWords[Index + 1])
 1617 
 1618     for Index in range(0, InfilesNamesCount):
 1619         Infile = OptionsInfo["InfilesNames"][Index]
 1620         CompositeEDMapFile = CompositeEDMapFiles[Index]
 1621         DiffEDMapFile = DiffEDMapFiles[Index]
 1622 
 1623         if not os.path.exists(CompositeEDMapFile):
 1624             MiscUtil.PrintError(
 1625                 'The composite ED map file, %s, specified using option "--EDMapFiles", corresponding to input file, %s,  doesn\'t exist.\n'
 1626                 % (CompositeEDMapFile, Infile)
 1627             )
 1628 
 1629         DiffEDMapFileExists = False
 1630         if not re.match("^None$", DiffEDMapFile, re.I):
 1631             if os.path.exists(DiffEDMapFile):
 1632                 DiffEDMapFileExists = True
 1633             else:
 1634                 MiscUtil.PrintWarning(
 1635                     "The difference ED map file, %s, specified using option \"--EDMapFiles\", corresponding to input file, %s,  doesn't exist. PyMOL groups and objectes related to difference maps won't be created.\n"
 1636                     % (DiffEDMapFile, Infile)
 1637                 )
 1638 
 1639         OptionsInfo["CompositeEDMapFiles"].append(CompositeEDMapFile)
 1640         if DiffEDMapFileExists:
 1641             OptionsInfo["DiffEDMapFiles"].append(DiffEDMapFile)
 1642         else:
 1643             OptionsInfo["DiffEDMapFiles"].append(None)
 1644 
 1645 
 1646 def ProcessEDMapSuffixes():
 1647     """Process suffixes for ED map files."""
 1648 
 1649     OptionsInfo["EDMapSuffixesMap"] = {"CompositeMap": "", "DifferenceMap": "_diff"}
 1650 
 1651     if re.match("^auto$", OptionsInfo["EDMapSuffixes"], re.I):
 1652         SetupEDMapFileNamesUsingSuffixes()
 1653         return
 1654 
 1655     EDMapSuffixes = re.sub(" ", "", OptionsInfo["EDMapSuffixes"])
 1656     if not EDMapSuffixes:
 1657         MiscUtil.PrintError('No valid parameter name and value pairs specified using "--EDMapSuffixes" option.')
 1658 
 1659     EDMapSuffixesWords = EDMapSuffixes.split(",")
 1660     if len(EDMapSuffixesWords) % 2:
 1661         MiscUtil.PrintError(
 1662             'The number of comma delimited ED map types names and suffixes, %d, specified using "--EDMapSuffixes" option must be an even number.'
 1663             % (len(EDMapSuffixesWords))
 1664         )
 1665 
 1666     for Index in range(0, len(EDMapSuffixesWords), 2):
 1667         EDMapType = EDMapSuffixesWords[Index]
 1668         EDMapSuffix = EDMapSuffixesWords[Index + 1]
 1669 
 1670         if re.match("^CompositeMap$", EDMapType, re.I):
 1671             EDMapType = "CompositeMap"
 1672         elif re.match("^DifferenceMap$", EDMapType, re.I):
 1673             EDMapType = "DifferenceMap"
 1674         else:
 1675             MiscUtil.PrintError(
 1676                 'The ED map type, %s, specified using "--EDMapSuffixes" option is not a valid ED map type. Supported ED map types: CompositeMap, DifferenceMap'
 1677                 % (EDMapType)
 1678             )
 1679 
 1680         if re.match(EDMapSuffix, "None", re.I):
 1681             EDMapSuffix = ""
 1682 
 1683         OptionsInfo["EDMapSuffixesMap"][EDMapType] = EDMapSuffix
 1684 
 1685     SetupEDMapFileNamesUsingSuffixes()
 1686 
 1687 
 1688 def SetupEDMapFileNamesUsingSuffixes():
 1689     """Set up ED map file names."""
 1690 
 1691     OptionsInfo["CompositeEDMapFiles"] = []
 1692     OptionsInfo["DiffEDMapFiles"] = []
 1693 
 1694     CompositeMapSuffix = OptionsInfo["EDMapSuffixesMap"]["CompositeMap"]
 1695     DiffMapSuffix = OptionsInfo["EDMapSuffixesMap"]["DifferenceMap"]
 1696     InfilesNamesCount = len(OptionsInfo["InfilesNames"])
 1697 
 1698     for Index in range(0, InfilesNamesCount):
 1699         Infile = OptionsInfo["InfilesNames"][Index]
 1700         FileDir, FileName, FileExt = MiscUtil.ParseFileName(Infile)
 1701         InfileRoot = FileName
 1702 
 1703         CompositeEDMapFile = "%s%s.ccp4" % (InfileRoot, CompositeMapSuffix)
 1704         DiffEDMapFile = "%s%s.ccp4" % (InfileRoot, DiffMapSuffix)
 1705 
 1706         if not os.path.exists(CompositeEDMapFile):
 1707             MiscUtil.PrintError(
 1708                 'The composite ED map file, %s, for option "--EDMapSuffixes", corresponding to input file, %s, doesn\'t exist.\n'
 1709                 % (CompositeEDMapFile, Infile)
 1710             )
 1711 
 1712         DiffEDMapFileExists = False
 1713         if os.path.exists(DiffEDMapFile):
 1714             DiffEDMapFileExists = True
 1715         else:
 1716             MiscUtil.PrintWarning(
 1717                 "The difference ED map file, %s, for option \"--EDMapSuffixes\", corresponding to input file, %s,  doesn't exist. PyMOL groups and objectes related to difference maps won't be created.\n"
 1718                 % (DiffEDMapFile, Infile)
 1719             )
 1720 
 1721         OptionsInfo["CompositeEDMapFiles"].append(CompositeEDMapFile)
 1722         if DiffEDMapFileExists:
 1723             OptionsInfo["DiffEDMapFiles"].append(DiffEDMapFile)
 1724         else:
 1725             OptionsInfo["DiffEDMapFiles"].append(None)
 1726 
 1727 
 1728 def RetrieveInfilesInfo():
 1729     """Retrieve information for input files."""
 1730 
 1731     InfilesInfo = {}
 1732 
 1733     InfilesInfo["InfilesNames"] = []
 1734     InfilesInfo["InfilesRoots"] = []
 1735     InfilesInfo["ChainsAndLigandsInfo"] = []
 1736 
 1737     for Infile in OptionsInfo["InfilesNames"]:
 1738         FileDir, FileName, FileExt = MiscUtil.ParseFileName(Infile)
 1739         InfileRoot = FileName
 1740 
 1741         ChainsAndLigandInfo = PyMOLUtil.GetChainsAndLigandsInfo(Infile, InfileRoot)
 1742 
 1743         InfilesInfo["InfilesNames"].append(Infile)
 1744         InfilesInfo["InfilesRoots"].append(InfileRoot)
 1745         InfilesInfo["ChainsAndLigandsInfo"].append(ChainsAndLigandInfo)
 1746 
 1747     OptionsInfo["InfilesInfo"] = InfilesInfo
 1748 
 1749 
 1750 def RetrieveRefFileInfo():
 1751     """Retrieve information for ref file."""
 1752 
 1753     RefFileInfo = {}
 1754     if not OptionsInfo["Align"]:
 1755         OptionsInfo["RefFileInfo"] = RefFileInfo
 1756         return
 1757 
 1758     RefFile = OptionsInfo["RefFileName"]
 1759 
 1760     FileDir, FileName, FileExt = MiscUtil.ParseFileName(RefFile)
 1761     RefFileRoot = FileName
 1762 
 1763     if re.match("^FirstInputFile$", OptionsInfo["AlignRefFile"], re.I):
 1764         ChainsAndLigandInfo = OptionsInfo["InfilesInfo"]["ChainsAndLigandsInfo"][0]
 1765     else:
 1766         MiscUtil.PrintInfo("\nRetrieving chain and ligand information for alignment reference file %s..." % RefFile)
 1767         ChainsAndLigandInfo = PyMOLUtil.GetChainsAndLigandsInfo(RefFile, RefFileRoot)
 1768 
 1769     RefFileInfo["RefFileName"] = RefFile
 1770     RefFileInfo["RefFileRoot"] = RefFileRoot
 1771     RefFileInfo["PyMOLObjectName"] = "AlignRef_%s" % RefFileRoot
 1772     RefFileInfo["ChainsAndLigandsInfo"] = ChainsAndLigandInfo
 1773 
 1774     OptionsInfo["RefFileInfo"] = RefFileInfo
 1775 
 1776 
 1777 def ProcessChainAndLigandIDs():
 1778     """Process specified chain and ligand IDs for infiles."""
 1779 
 1780     OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"] = []
 1781 
 1782     for FileIndex in range(0, len(OptionsInfo["InfilesInfo"]["InfilesNames"])):
 1783         MiscUtil.PrintInfo(
 1784             "\nProcessing specified chain and ligand IDs for input file %s..."
 1785             % OptionsInfo["InfilesInfo"]["InfilesNames"][FileIndex]
 1786         )
 1787 
 1788         ChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["ChainsAndLigandsInfo"][FileIndex]
 1789         SpecifiedChainsAndLigandsInfo = PyMOLUtil.ProcessChainsAndLigandsOptionsInfo(
 1790             ChainsAndLigandsInfo, "-c, --chainIDs", OptionsInfo["ChainIDs"], "-l, --ligandIDs", OptionsInfo["LigandIDs"]
 1791         )
 1792         ProcessChainMeshesVolumesAndSurfacesOptions(SpecifiedChainsAndLigandsInfo)
 1793         OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"].append(SpecifiedChainsAndLigandsInfo)
 1794 
 1795         CheckPresenceOfValidLigandIDs(ChainsAndLigandsInfo, SpecifiedChainsAndLigandsInfo)
 1796 
 1797 
 1798 def CheckPresenceOfValidLigandIDs(ChainsAndLigandsInfo, SpecifiedChainsAndLigandsInfo):
 1799     """Check presence of valid ligand IDs."""
 1800 
 1801     MiscUtil.PrintInfo("\nSpecified chain IDs: %s" % (", ".join(SpecifiedChainsAndLigandsInfo["ChainIDs"])))
 1802 
 1803     for ChainID in SpecifiedChainsAndLigandsInfo["ChainIDs"]:
 1804         if len(SpecifiedChainsAndLigandsInfo["LigandIDs"][ChainID]):
 1805             MiscUtil.PrintInfo(
 1806                 "Chain ID: %s; Specified LigandIDs: %s"
 1807                 % (ChainID, ", ".join(SpecifiedChainsAndLigandsInfo["LigandIDs"][ChainID]))
 1808             )
 1809         else:
 1810             MiscUtil.PrintInfo("Chain IDs: %s; Specified LigandIDs: None" % (ChainID))
 1811             MiscUtil.PrintWarning(
 1812                 "No valid ligand IDs found for chain ID, %s. PyMOL groups and objects related to ligand and binding pockect won't be created."
 1813                 % (ChainID)
 1814             )
 1815 
 1816 
 1817 def RetrieveFirstChainID(FileIndex):
 1818     """Get first chain ID."""
 1819 
 1820     ChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["ChainsAndLigandsInfo"][FileIndex]
 1821 
 1822     FirstChainID = None
 1823     if len(ChainsAndLigandsInfo["ChainIDs"]):
 1824         FirstChainID = ChainsAndLigandsInfo["ChainIDs"][0]
 1825 
 1826     return FirstChainID
 1827 
 1828 
 1829 def ProcessChainMeshesVolumesAndSurfacesOptions(SpecifiedChainsAndLigandsInfo):
 1830     """Process options to create meshes and surfaces for chains."""
 1831 
 1832     SpecifiedChainsAndLigandsInfo["VolumeChainComplex"] = {}
 1833     SpecifiedChainsAndLigandsInfo["MeshChainComplex"] = {}
 1834     SpecifiedChainsAndLigandsInfo["SurfaceChainComplex"] = {}
 1835 
 1836     SpecifiedChainsAndLigandsInfo["EnableVolumeChainComplex"] = {}
 1837     SpecifiedChainsAndLigandsInfo["EnableMeshChainComplex"] = {}
 1838     SpecifiedChainsAndLigandsInfo["EnableSurfaceChainComplex"] = {}
 1839 
 1840     SpecifiedChainsAndLigandsInfo["EnableChainComplexGroup"] = {}
 1841     SpecifiedChainsAndLigandsInfo["EnableChainAloneGroup"] = {}
 1842 
 1843     for ChainID in SpecifiedChainsAndLigandsInfo["ChainIDs"]:
 1844         LigandsPresent = True if len(SpecifiedChainsAndLigandsInfo["LigandIDs"][ChainID]) else False
 1845 
 1846         # Create and enable mesh  or volume in auto mode...
 1847         if re.match("^auto$", OptionsInfo["MeshChainComplex"], re.I):
 1848             MeshChainComplex = False if LigandsPresent else True
 1849             EnableMeshChainComplex = False if LigandsPresent else True
 1850         else:
 1851             MeshChainComplex = True if re.match("^Yes$", OptionsInfo["MeshChainComplex"], re.I) else False
 1852             EnableMeshChainComplex = True if re.match("^Yes$", OptionsInfo["MeshChainComplex"], re.I) else False
 1853 
 1854         if re.match("^auto$", OptionsInfo["VolumeChainComplex"], re.I):
 1855             VolumeChainComplex = False if LigandsPresent else True
 1856             EnableVolumeChainComplex = False if LigandsPresent else True
 1857         else:
 1858             VolumeChainComplex = True if re.match("^Yes$", OptionsInfo["VolumeChainComplex"], re.I) else False
 1859             EnableVolumeChainComplex = True if re.match("^Yes$", OptionsInfo["VolumeChainComplex"], re.I) else False
 1860 
 1861         if MeshChainComplex and EnableMeshChainComplex:
 1862             EnableVolumeChainComplex = False
 1863 
 1864         # Create and enable surface in auto mode based on the status of mesh and volume...
 1865         if re.match("^auto$", OptionsInfo["SurfaceChainComplex"], re.I):
 1866             SurfaceChainComplex = False if LigandsPresent else True
 1867             EnableSurfaceChainComplex = False if LigandsPresent else True
 1868 
 1869             if MeshChainComplex or VolumeChainComplex:
 1870                 SurfaceChainComplex = False
 1871                 EnableSurfaceChainComplex = False
 1872         else:
 1873             SurfaceChainComplex = True if re.match("^Yes$", OptionsInfo["SurfaceChainComplex"], re.I) else False
 1874             EnableSurfaceChainComplex = True if re.match("^Yes$", OptionsInfo["SurfaceChainComplex"], re.I) else False
 1875 
 1876         if (MeshChainComplex and EnableMeshChainComplex) or (VolumeChainComplex or EnableVolumeChainComplex):
 1877             EnableSurfaceChainComplex = False
 1878 
 1879         if LigandsPresent:
 1880             EnableChainComplexGroup = False
 1881             EnableChainAloneGroup = True
 1882         else:
 1883             EnableChainComplexGroup = True
 1884             EnableChainAloneGroup = False
 1885 
 1886         SpecifiedChainsAndLigandsInfo["VolumeChainComplex"][ChainID] = VolumeChainComplex
 1887         SpecifiedChainsAndLigandsInfo["MeshChainComplex"][ChainID] = MeshChainComplex
 1888         SpecifiedChainsAndLigandsInfo["SurfaceChainComplex"][ChainID] = SurfaceChainComplex
 1889 
 1890         SpecifiedChainsAndLigandsInfo["EnableVolumeChainComplex"][ChainID] = EnableVolumeChainComplex
 1891         SpecifiedChainsAndLigandsInfo["EnableMeshChainComplex"][ChainID] = EnableMeshChainComplex
 1892         SpecifiedChainsAndLigandsInfo["EnableSurfaceChainComplex"][ChainID] = EnableSurfaceChainComplex
 1893 
 1894         SpecifiedChainsAndLigandsInfo["EnableChainComplexGroup"][ChainID] = EnableChainComplexGroup
 1895         SpecifiedChainsAndLigandsInfo["EnableChainAloneGroup"][ChainID] = EnableChainAloneGroup
 1896 
 1897 
 1898 def ProcessChainSelections():
 1899     """Process custom selections for chains."""
 1900 
 1901     ChainSelectionsInfo = PyMOLUtil.ProcessChainSelectionsOptionsInfo(
 1902         "--selectionsChain", OptionsInfo["SelectionsChain"]
 1903     )
 1904     OptionsInfo["ChainSelectionsInfo"] = ChainSelectionsInfo
 1905 
 1906     ChainSelections = True if len(OptionsInfo["ChainSelectionsInfo"]["Names"]) else False
 1907     OptionsInfo["ChainSelections"] = ChainSelections
 1908 
 1909 
 1910 def ProcessOptions():
 1911     """Process and validate command line arguments and options."""
 1912 
 1913     MiscUtil.PrintInfo("Processing options...")
 1914 
 1915     # Validate options...
 1916     ValidateOptions()
 1917 
 1918     OptionsInfo["Align"] = True if re.match("^Yes$", Options["--align"], re.I) else False
 1919     OptionsInfo["AlignMethod"] = Options["--alignMethod"].lower()
 1920     OptionsInfo["AlignMode"] = Options["--alignMode"]
 1921 
 1922     OptionsInfo["AllowEmptyObjects"] = True if re.match("^Yes$", Options["--allowEmptyObjects"], re.I) else False
 1923 
 1924     OptionsInfo["BFactorChainCartoonPutty"] = (
 1925         True if re.match("^Yes$", Options["--BFactorChainCartoonPutty"], re.I) else False
 1926     )
 1927     OptionsInfo["BFactorColorPalette"] = Options["--BFactorColorPalette"]
 1928 
 1929     OptionsInfo["Infiles"] = Options["--infiles"]
 1930     OptionsInfo["InfilesNames"] = Options["--infileNames"]
 1931 
 1932     OptionsInfo["AlignRefFile"] = Options["--alignRefFile"]
 1933     if re.match("^FirstInputFile$", Options["--alignRefFile"], re.I):
 1934         OptionsInfo["RefFileName"] = OptionsInfo["InfilesNames"][0]
 1935     else:
 1936         OptionsInfo["RefFileName"] = Options["--alignRefFile"]
 1937 
 1938     OptionsInfo["IgnoreHydrogens"] = True if re.match("^Yes$", Options["--ignoreHydrogens"], re.I) else False
 1939 
 1940     OptionsInfo["EDMapFiles"] = Options["--EDMapFiles"]
 1941     OptionsInfo["EDMapSuffixes"] = Options["--EDMapSuffixes"]
 1942     ProcessEDMapFilesAndSuffixes()
 1943 
 1944     OptionsInfo["Overwrite"] = Options["--overwrite"]
 1945     OptionsInfo["PMLOut"] = True if re.match("^Yes$", Options["--PMLOut"], re.I) else False
 1946 
 1947     OptionsInfo["Outfile"] = Options["--outfile"]
 1948     FileDir, FileName, FileExt = MiscUtil.ParseFileName(OptionsInfo["Outfile"])
 1949     OptionsInfo["PSEOut"] = False
 1950     if re.match("^pml$", FileExt, re.I):
 1951         OptionsInfo["PMLOutfile"] = OptionsInfo["Outfile"]
 1952         OptionsInfo["PMEOutfile"] = re.sub(".pml$", ".pme", OptionsInfo["Outfile"])
 1953     elif re.match("^pse$", FileExt, re.I):
 1954         OptionsInfo["PSEOut"] = True
 1955         OptionsInfo["PSEOutfile"] = OptionsInfo["Outfile"]
 1956         OptionsInfo["PMLOutfile"] = re.sub(".pse$", ".pml", OptionsInfo["Outfile"])
 1957         if os.path.exists(OptionsInfo["PMLOutfile"]) and (not OptionsInfo["Overwrite"]):
 1958             MiscUtil.PrintError(
 1959                 'The intermediate output file to be generated, %s, already exist. Use option "--ov" or "--overwrite" and try again.'
 1960                 % OptionsInfo["PMLOutfile"]
 1961             )
 1962 
 1963     OptionsInfo["LabelFontID"] = int(Options["--labelFontID"])
 1964 
 1965     # Process mesh parameters...
 1966     OptionsInfo["MeshCarveRadius"] = float(Options["--meshCarveRadius"])
 1967     OptionsInfo["MeshComplex"] = True if re.match("^Yes$", Options["--meshComplex"], re.I) else False
 1968     OptionsInfo["MeshChainComplex"] = Options["--meshChainComplex"]
 1969     OptionsInfo["MeshWidth"] = float(Options["--meshWidth"])
 1970 
 1971     OptionsInfo["MeshColorCompositeMap"] = Options["--meshColorCompositeMap"]
 1972     OptionsInfo["MeshLevelCompositeMap"] = float(Options["--meshLevelCompositeMap"])
 1973     OptionsInfo["Mesh1ColorDiffMap"] = Options["--mesh1ColorDiffMap"]
 1974     OptionsInfo["Mesh1LevelDiffMap"] = float(Options["--mesh1LevelDiffMap"])
 1975     OptionsInfo["Mesh2ColorDiffMap"] = Options["--mesh2ColorDiffMap"]
 1976     OptionsInfo["Mesh2LevelDiffMap"] = float(Options["--mesh2LevelDiffMap"])
 1977 
 1978     OptionsInfo["SelectionsChain"] = Options["--selectionsChain"]
 1979     OptionsInfo["SelectionsChainStyle"] = Options["--selectionsChainStyle"]
 1980     ProcessChainSelections()
 1981 
 1982     OptionsInfo["SurfaceComplex"] = True if re.match("^Yes$", Options["--surfaceComplex"], re.I) else False
 1983     OptionsInfo["SurfaceChainComplex"] = Options["--surfaceChainComplex"]
 1984     OptionsInfo["SurfaceTransparency"] = float(Options["--surfaceTransparency"])
 1985 
 1986     OptionsInfo["PocketContactsLigandColor"] = Options["--pocketContactsLigandColor"]
 1987     OptionsInfo["PocketContactsLigandHydrophobicColor"] = Options["--pocketContactsLigandHydrophobicColor"]
 1988     OptionsInfo["PocketContactsSolventColor"] = Options["--pocketContactsSolventColor"]
 1989     OptionsInfo["PocketContactsInorganicColor"] = Options["--pocketContactsInorganicColor"]
 1990 
 1991     OptionsInfo["PocketContactsCutoff"] = float(Options["--pocketContactsCutoff"])
 1992     OptionsInfo["PocketDistanceCutoff"] = float(Options["--pocketDistanceCutoff"])
 1993 
 1994     OptionsInfo["PocketLabelColor"] = Options["--pocketLabelColor"]
 1995     OptionsInfo["PocketSurface"] = True if re.match("^Yes$", Options["--pocketSurface"], re.I) else False
 1996 
 1997     OptionsInfo["VolumeCarveRadius"] = float(Options["--volumeCarveRadius"])
 1998     OptionsInfo["VolumeComplex"] = True if re.match("^Yes$", Options["--volumeComplex"], re.I) else False
 1999     OptionsInfo["VolumeChainComplex"] = Options["--volumeChainComplex"]
 2000 
 2001     OptionsInfo["VolumeColorRampCompositeMap"] = Options["--volumeColorRampCompositeMap"]
 2002     OptionsInfo["VolumeColorRampDiffMap"] = Options["--volumeColorRampDiffMap"]
 2003 
 2004     RetrieveInfilesInfo()
 2005     RetrieveRefFileInfo()
 2006 
 2007     OptionsInfo["ChainIDs"] = Options["--chainIDs"]
 2008     OptionsInfo["LigandIDs"] = Options["--ligandIDs"]
 2009 
 2010     ProcessChainAndLigandIDs()
 2011 
 2012 
 2013 def RetrieveOptions():
 2014     """Retrieve command line arguments and options."""
 2015 
 2016     # Get options...
 2017     global Options
 2018     Options = docopt(_docoptUsage_)
 2019 
 2020     # Set current working directory to the specified directory...
 2021     WorkingDir = Options["--workingdir"]
 2022     if WorkingDir:
 2023         os.chdir(WorkingDir)
 2024 
 2025     # Handle examples option...
 2026     if "--examples" in Options and Options["--examples"]:
 2027         MiscUtil.PrintInfo(MiscUtil.GetExamplesTextFromDocOptText(_docoptUsage_))
 2028         sys.exit(0)
 2029 
 2030 
 2031 def ValidateOptions():
 2032     """Validate option values."""
 2033 
 2034     MiscUtil.ValidateOptionTextValue("--align", Options["--align"], "yes no")
 2035     MiscUtil.ValidateOptionTextValue("--alignMethod", Options["--alignMethod"], "align cealign super")
 2036     MiscUtil.ValidateOptionTextValue("--alignMode", Options["--alignMode"], "FirstChain Complex")
 2037 
 2038     MiscUtil.ValidateOptionTextValue("--allowEmptyObjects", Options["--allowEmptyObjects"], "yes no")
 2039 
 2040     MiscUtil.ValidateOptionTextValue("--BFactorChainCartoonPutty", Options["--BFactorChainCartoonPutty"], "yes no")
 2041 
 2042     # Expand infiles to handle presence of multiple input files...
 2043     InfileNames = MiscUtil.ExpandFileNames(Options["--infiles"], ",")
 2044     if not len(InfileNames):
 2045         MiscUtil.PrintError('No input files specified for "-i, --infiles" option')
 2046 
 2047     # Validate file extensions...
 2048     for Infile in InfileNames:
 2049         MiscUtil.ValidateOptionFilePath("-i, --infiles", Infile)
 2050         MiscUtil.ValidateOptionFileExt("-i, --infiles", Infile, "pdb cif")
 2051         MiscUtil.ValidateOptionsDistinctFileNames("-i, --infiles", Infile, "-o, --outfile", Options["--outfile"])
 2052     Options["--infileNames"] = InfileNames
 2053 
 2054     MiscUtil.ValidateOptionFileExt("-o, --outfile", Options["--outfile"], "pml pse")
 2055     MiscUtil.ValidateOptionsOutputFileOverwrite(
 2056         "-o, --outfile", Options["--outfile"], "--overwrite", Options["--overwrite"]
 2057     )
 2058 
 2059     if re.match("^yes$", Options["--align"], re.I):
 2060         if not re.match("^FirstInputFile$", Options["--alignRefFile"], re.I):
 2061             AlignRefFile = Options["--alignRefFile"]
 2062             MiscUtil.ValidateOptionFilePath("--alignRefFile", AlignRefFile)
 2063             MiscUtil.ValidateOptionFileExt("--alignRefFile", AlignRefFile, "pdb cif")
 2064             MiscUtil.ValidateOptionsDistinctFileNames(
 2065                 "--AlignRefFile", AlignRefFile, "-o, --outfile", Options["--outfile"]
 2066             )
 2067 
 2068     MiscUtil.ValidateOptionTextValue("--ignoreHydrogens", Options["--ignoreHydrogens"], "yes no")
 2069 
 2070     MiscUtil.ValidateOptionTextValue("--PMLOut", Options["--PMLOut"], "yes no")
 2071     MiscUtil.ValidateOptionIntegerValue("--labelFontID", Options["--labelFontID"], {})
 2072 
 2073     MiscUtil.ValidateOptionFloatValue("--meshCarveRadius", Options["--meshCarveRadius"], {">": 0.0})
 2074     MiscUtil.ValidateOptionTextValue("--meshComplex", Options["--meshComplex"], "yes no")
 2075     MiscUtil.ValidateOptionTextValue("--meshChainComplex", Options["--meshChainComplex"], "yes no auto")
 2076     MiscUtil.ValidateOptionFloatValue("--meshWidth", Options["--meshWidth"], {">": 0.0})
 2077 
 2078     MiscUtil.ValidateOptionFloatValue("--meshLevelCompositeMap", Options["--meshLevelCompositeMap"], {})
 2079     MiscUtil.ValidateOptionFloatValue("--mesh1LevelDiffMap", Options["--mesh1LevelDiffMap"], {})
 2080     MiscUtil.ValidateOptionFloatValue("--mesh2LevelDiffMap", Options["--mesh2LevelDiffMap"], {})
 2081 
 2082     MiscUtil.ValidateOptionTextValue("--surfaceComplex", Options["--surfaceComplex"], "yes no")
 2083     MiscUtil.ValidateOptionTextValue("--surfaceChainComplex", Options["--surfaceChainComplex"], "yes no auto")
 2084     MiscUtil.ValidateOptionFloatValue("--surfaceTransparency", Options["--surfaceTransparency"], {">=": 0.0, "<=": 1.0})
 2085 
 2086     MiscUtil.ValidateOptionFloatValue("--pocketContactsCutoff", Options["--pocketContactsCutoff"], {">": 0.0})
 2087     MiscUtil.ValidateOptionFloatValue("--pocketDistanceCutoff", Options["--pocketDistanceCutoff"], {">": 0.0})
 2088     if float(Options["--pocketContactsCutoff"]) > float(Options["--pocketDistanceCutoff"]):
 2089         MiscUtil.PrintError(
 2090             'The value, %s, specified using option "--pocketContactsCutoff" must be less than value, %s, specified using "-pocketDistanceCutoff" option.'
 2091             % (Options["--pocketContactsCutoff"], Options["--pocketDistanceCutoff"])
 2092         )
 2093 
 2094     MiscUtil.ValidateOptionTextValue("--pocketSurface", Options["--pocketSurface"], "yes no")
 2095 
 2096     MiscUtil.ValidateOptionFloatValue("--volumeCarveRadius", Options["--volumeCarveRadius"], {">": 0.0})
 2097     MiscUtil.ValidateOptionTextValue("--volumeComplex", Options["--volumeComplex"], "yes no")
 2098     MiscUtil.ValidateOptionTextValue("--volumeChainComplex", Options["--volumeChainComplex"], "yes no auto")
 2099 
 2100 
 2101 # Setup a usage string for docopt...
 2102 _docoptUsage_ = """
 2103 PyMOLVisualizeElectronDensity.py - Visualize electron density
 2104 
 2105 Usage:
 2106     PyMOLVisualizeElectronDensity.py  [--align <yes or no>] [--alignMethod <align, cealign, super>]
 2107                                      [--alignMode <FirstChain or Complex>] [--alignRefFile <filename>]
 2108                                      [--allowEmptyObjects <yes or no>] [--BFactorChainCartoonPutty <yes or no>]
 2109                                      [--BFactorColorPalette <text> ] [--chainIDs <First, All or ID1,ID2...>]
 2110                                      [--EDMapFiles <file1,file2,...>] [--EDMapSuffixes <CompositeMap,None,...>]
 2111                                      [--ignoreHydrogens <yes or no>] [--ligandIDs <Largest, All or ID1,ID2...>] [--labelFontID <number>]
 2112                                      [--meshCarveRadius <number>] [--meshComplex <yes or no>]
 2113                                      [--meshChainComplex <yes or no>] [--meshColorCompositeMap <text>]
 2114                                      [--meshLevelCompositeMap <number>] [--meshWidth <number>]
 2115                                      [--mesh1ColorDiffMap <text>] [--mesh1LevelDiffMap <number>]
 2116                                      [--mesh2ColorDiffMap <text>] [--mesh2LevelDiffMap <number>]
 2117                                      [--PMLOut <yes or no>] [--pocketContactsLigandColor <text>]
 2118                                      [--pocketContactsLigandHydrophobicColor <text>] [--pocketContactsSolventColor <text>]
 2119                                      [--pocketContactsInorganicColor <text>] [--pocketContactsCutoff <number>]
 2120                                      [--pocketDistanceCutoff <number>] [--pocketLabelColor <text>] [--pocketSurface <yes or no>]
 2121                                      [--selectionsChain <ObjectName,SelectionSpec,...>] [--selectionsChainStyle <DisplayStyle>]
 2122                                      [--surfaceComplex <yes or no> ] [--surfaceChainComplex <yes or no>] [--surfaceTransparency <number>]
 2123                                      [--volumeCarveRadius <number>] [--volumeComplex <yes or no>]
 2124                                      [--volumeChainComplex <yes, no, or auto>] [--volumeColorRampCompositeMap <text>]
 2125                                      [--volumeColorRampDiffMap <text> ] [--overwrite] [-w <dir>] -i <infile1,infile2...> -o <outfile>
 2126     PyMOLVisualizeElectronDensity.py -h | --help | -e | --examples
 2127 
 2128 Description:
 2129     Generate PyMOL visualization files for viewing X-ray electron density around
 2130     chains, ligands, and ligand binding pockets in macromolecules including proteins
 2131     and nucleic acids.
 2132 
 2133     The supported input file formats are: Macromolecule - PDB (.pdb) or CIF(.cif),
 2134     Electron Density - Collaborative Computational Project Number 4 (CCP4) ( .ccp4)
 2135 
 2136     The supported output file formats are: PyMOL script file (.pml), PyMOL session
 2137     file (.pse)
 2138 
 2139     Two types of CCP4 electron density map files may be used for visualizing electron
 2140     density. These file types along with default file names are shown below:
 2141     
 2142         CompositeMap (2Fobs - Fcalc) - <InfileRoot>.ccp4 (required)
 2143         DifferenceMap (Fobs - Fcalc) - <InfileRoot>_diff.ccp4 (optional)
 2144     
 2145     The compsite map file must be present. The difference map file is optional.
 2146     The mesh, volume, and surface PyMOL objects are not generated for missing
 2147     difference map file.
 2148 
 2149     The electron density present in a composite map file is generated by adding two
 2150     difference maps to a calculated map (Fcalc) as shown below:
 2151     
 2152         Fcalc + 2(Fobs - Fcalc) = 2Fobs - Fcalc
 2153     
 2154     The following types of meshes and volumes may be created by default for
 2155     electron density present in composite and difference map files:
 2156     
 2157         CompositeVolume - VolumeColorRamp: 2fofc
 2158         CompositeMesh - ContourLevel: 1; Color: Blue
 2159         DiffVolume - VolumeColorRamp: fofc
 2160         DiffMesh1 - ContourLevel: 3; Color: Green
 2161         DiffMesh2 - ContourLevel: -3; Color: Red
 2162 
 2163     The two meshes created for difference maps correspond to false negative and
 2164     false positive in terms of electron density present in the model. The first mesh
 2165     shown in  green color corresponds to observed electron density missing in the
 2166     model. The second mesh in in red color indicates model electron density not
 2167     observed in the experiment.
 2168     
 2169     A variety of PyMOL groups and objects may be  created for visualization of
 2170     electron density present in map files. These groups and objects correspond to
 2171     maps, volumes, meshes, surfaces,chains, ligands, inorganics, ligand binding
 2172     pockets, polar interactions, and pocket hydrophobic surfaces. A complete
 2173     hierarchy of all possible PyMOL groups and objects is shown below:
 2174     
 2175         <PDBFileRoot>
 2176             .Complex
 2177                 .Complex
 2178                 .2Fo-Fc
 2179                     .Map
 2180                     .Volume
 2181                     .Mesh
 2182                     .Surface
 2183                 .Fo-Fc
 2184                     .Map
 2185                     .Volume
 2186                     .Mesh1
 2187                     .Surface1
 2188                     .Mesh2
 2189                     .Surface2
 2190             .Chain<ID>
 2191                 .Complex
 2192                     .Complex
 2193                     .2Fo-Fc
 2194                         .Volume
 2195                         .Mesh
 2196                         .Surface
 2197                     .Fo-Fc
 2198                         .Volume
 2199                         .Mesh1
 2200                         .Surface1
 2201                         .Mesh2
 2202                         .Surface2
 2203                 .Chain
 2204                     .Chain
 2205                     .BFactor
 2206                     .Selections
 2207                         .<Name1>
 2208                             .Selection
 2209                             .2Fo-Fc
 2210                                 .Volume
 2211                                 .Mesh
 2212                                 .Surface
 2213                             .Fo-Fc
 2214                                 .Volume
 2215                                 .Mesh1
 2216                                 .Surface1
 2217                                 .Mesh2
 2218                                 .Surface2
 2219                         .<Name2>
 2220                             ... ... ..
 2221                 .Solvent
 2222                 .Inorganic
 2223                 .Ligand<ID>
 2224                     .Ligand
 2225                         .Ligand
 2226                         .2Fo-Fc
 2227                             .Volume
 2228                             .Mesh
 2229                             .Surface
 2230                         .Fo-Fc
 2231                             .Volume
 2232                             .Mesh1
 2233                             .Surface1
 2234                             .Mesh2
 2235                             .Surface2
 2236                     .Pocket
 2237                         .Pocket
 2238                         .2Fo-Fc
 2239                             .Volume
 2240                             .Mesh
 2241                             .Surface
 2242                         .Fo-Fc
 2243                             .Volume
 2244                             .Mesh1
 2245                             .Surface1
 2246                             .Mesh2
 2247                             .Surface2
 2248                         .Polar_Contacts
 2249                         .Hydrophobic_Contacts
 2250                         .Surface
 2251                     .Pocket_Solvent
 2252                         .Pocket_Solvent
 2253                         .2Fo-Fc
 2254                             .Volume
 2255                             .Mesh
 2256                             .Surface
 2257                         .Fo-Fc
 2258                             .Volume
 2259                             .Mesh1
 2260                             .Surface1
 2261                             .Mesh2
 2262                             .Surface2
 2263                         .Polar_Contacts
 2264                     .Pocket_Inorganic
 2265                         .Pocket_Inorganic
 2266                         .2Fo-Fc
 2267                             .Volume
 2268                             .Mesh
 2269                             .Surface
 2270                         .Fo-Fc
 2271                             .Volume
 2272                             .Mesh1
 2273                             .Surface1
 2274                             .Mesh2
 2275                             .Surface2
 2276                         .Polar_Contacts
 2277                 .Ligand<ID>
 2278                     .Ligand
 2279                         ... ... ...
 2280                     .Pocket
 2281                         ... ... ...
 2282                     .Pocket_Solvent
 2283                         ... ... ...
 2284                     .Pocket_Inorganic
 2285                         ... ... ...
 2286             .Chain<ID>
 2287                 ... ... ...
 2288                 .Ligand<ID>
 2289                     ... ... ...
 2290                 .Ligand<ID>
 2291                     ... ... ...
 2292             .Chain<ID>
 2293                 ... ... ...
 2294         <PDBFileRoot>
 2295             .Complex
 2296                 ... ... ...
 2297             .Chain<ID>
 2298                 ... ... ...
 2299                 .Ligand<ID>
 2300                     ... ... ...
 2301                 .Ligand<ID>
 2302                     ... ... ...
 2303             .Chain<ID>
 2304                 ... ... ...
 2305     
 2306     The meshes, volumes, and surfaces  are not created for complete complex in
 2307     each input file by default. A word to the wise: The creation of these surface, volume,
 2308     and mesh objects may slow down loading of PML file and generation of PSE file,
 2309     based on the size of input complex and map files. The generation of PSE file
 2310     may also fail.
 2311 
 2312 Options:
 2313     -a, --align <yes or no>  [default: no]
 2314         Align input files to a reference file before visualization along with
 2315         available electron density map files.
 2316     --alignMethod <align, cealign, super>  [default: super]
 2317         Alignment methodology to use for aligning input files to a
 2318         reference file.
 2319     --alignMode <FirstChain or Complex>  [default: FirstChain]
 2320         Portion of input and reference files to use for spatial alignment of
 2321         input files against reference file.  Possible values: FirstChain or
 2322         Complex.
 2323         
 2324         The FirstChain mode allows alignment of the first chain in each input
 2325         file to the first chain in the reference file along with moving the rest
 2326         of the complex to coordinate space of the reference file. The complete
 2327         complex in each input file is aligned to the complete complex in reference
 2328         file for the Complex mode.
 2329     --alignRefFile <filename>  [default: FirstInputFile]
 2330         Reference input file name. The default is to use the first input file
 2331         name specified using '-i, --infiles' option.
 2332     --allowEmptyObjects <yes or no>  [default: no]
 2333         Allow creation of empty PyMOL objects corresponding to solvent and
 2334         inorganic atom selections across chains, ligands, and ligand binding pockets
 2335         in input file(s).
 2336     -c, --chainIDs <First, All or ID1,ID2...>  [default: First]
 2337         List of chain IDs to use for visualizing electron density. Possible values:
 2338         First, All, or a comma delimited list of chain IDs. The default is to use the
 2339         chain ID for the first chain in each input file.
 2340     -b, --BFactorChainCartoonPutty <yes or no>  [default: yes]
 2341         A cartoon putty around individual chains colored by B factors. The minimum
 2342         and maximum values for B factors are automatically detected. These values
 2343         indicate spread of electron density around atoms. The 'blue_white_red' color
 2344         palette is deployed for coloring the cartoon putty.
 2345     --BFactorColorPalette <text>  [default: blue_white_red]
 2346         Color palette for coloring cartoon putty around chains generated using B
 2347         factors. Any valid PyMOL color palette name is allowed. No validation is
 2348         performed. The complete list of valid color palette names is a available
 2349         at: pymolwiki.org/index.php/Spectrum. Examples: blue_white_red,
 2350         blue_white_magenta, blue_red, green_white_red, green_red.
 2351     -e, --examples
 2352         Print examples.
 2353     --EDMapFiles <file1,file1,file3...>  [default: auto]
 2354         Pairwise comma delimited list of composite and difference electron
 2355         density map files corresponding to input files. By default, the names
 2356         of electron density files are automatically generated using a combination
 2357         of input file names and file suffixes '--EDMapSuffixes'.
 2358         
 2359         The first file with in each pairs of filenames correspond to composite
 2360         electron density map. A composite file must be present for each input
 2361         file. The second file corresponds to difference electron density map. The
 2362         difference map file is optional. A value of 'None' must be used to represent
 2363         a missing difference map file. 
 2364         
 2365         The number of specified files must be twice the number of input files.
 2366     --EDMapSuffixes <CompositeMap,None,...>  [default: auto]
 2367         Electron density map file suffixes for generating names of map files from
 2368         the root of input files. It is a pairwise comma delimited list of 'EDMapType'
 2369         and file suffix.
 2370         
 2371         This option is ignored during explicit specification of electron density
 2372         map files using '--EDMapFiles'.
 2373         
 2374         Supported values for 'EDMapType': 'CompositeMap, DifferenceMap'.
 2375         Supported value for file suffix: Any valid string.
 2376         
 2377         Default value: 'CompositeMap,None,DifferenceMap,_diff'
 2378         
 2379         This option is only used for 'Auto' value of '--EDMapFilesMode' option.
 2380         
 2381         The default names of the map files, generated form a combination of
 2382         'InfileRoot' and 'EDSMapType' are shown below:
 2383             
 2384             CompositeMap (2Fobs - Fcalc) - <InfileRoot>.ccp4
 2385             DifferenceMap (Fobs - Fcalc) - <InfileRoot>_diff.ccp4
 2386             
 2387         The composite map files must be present. The difference map files are
 2388         optional.
 2389     -h, --help
 2390         Print this help message.
 2391     -i, --infiles <infile1,infile2,infile3...>
 2392         Input file names.
 2393     --ignoreHydrogens <yes or no>  [default: yes]
 2394         Ignore hydrogens for ligand and pocket views.
 2395     -l, --ligandIDs <Largest, All or ID1,ID2...>  [default: Largest]
 2396         List of ligand IDs present in chains for visualizing electron density across
 2397         ligands and ligand binding pockets. Possible values: Largest, All, or a comma
 2398         delimited list of ligand IDs. The default is to use the largest ligand present
 2399         in all or specified chains in each input file.
 2400         
 2401         Ligands are identified using organic selection operator available in PyMOL.
 2402         It'll also  identify buffer molecules as ligands. The largest ligand contains
 2403         the highest number of heavy atoms.
 2404     --labelFontID <number>  [default: 7]
 2405         Font ID for drawing labels. Default: 7 (Sans Bold). Valid values: 5 to 16.
 2406         The specified value must be a valid PyMOL font ID. No validation is
 2407         performed. The complete lists of valid font IDs is available at:
 2408         pymolwiki.org/index.php/Label_font_id. Examples: 5 - Sans;
 2409         7 - Sans Bold; 9 - Serif; 10 - Serif Bold.
 2410     --meshCarveRadius <number>  [default: 1.6]
 2411         Radius in Angstroms around atoms for including electron density.
 2412     --meshComplex <yes or no>  [default: no]
 2413         Create meshes for complete complex in each input file using corresponding
 2414         composite and difference maps. A total of three meshes, one for composite
 2415         map and two for difference map, are created for the complete complex.
 2416         
 2417         The composite and difference maps are always loaded for the complex.
 2418     --meshChainComplex <yes, no, or auto>  [default: auto]
 2419         Create meshes for individual chain complex in each input file using corresponding
 2420         composite and difference maps. A total of three meshes, one for composite map
 2421         map and two for difference map, are created for each chain complex. By default,
 2422         the meshes are automatically created for chain complexes without any ligands. 
 2423     --meshColorCompositeMap <text>  [default: blue]
 2424         Line color for meshes corresponding to composite maps. The specified value
 2425         must be valid color. No validation is performed.
 2426     --meshLevelCompositeMap <number>  [default: 1.0]
 2427         Contour level in sigma units for generating meshes corresponding to composite
 2428         maps.
 2429     --meshWidth <number>  [default: 0.5]
 2430         Line width for mesh lines corresponding to composite and difference maps.
 2431     --mesh1ColorDiffMap <text>  [default: green]
 2432         Line color for first mesh corresponding to difference maps at contour level
 2433         specified by '--mesh1LevelDiffMap'. The specified value must be valid color.
 2434         No validation is performed.
 2435     --mesh1LevelDiffMap <number>  [default: 3.0]
 2436         Contour level in sigma units for generating first mesh corresponding to 
 2437         to  difference maps.
 2438     --mesh2ColorDiffMap <text>  [default: red]
 2439         Line color for second mesh corresponding to difference maps at contour level
 2440         specified by '--mesh2LevelDiffMap'. The specified value must be valid color.
 2441         No validation is performed.
 2442     --mesh2LevelDiffMap <number>  [default: -3.0]
 2443         Contour level in sigma units for generating second mesh corresponding to
 2444         difference maps.
 2445     -o, --outfile <outfile>
 2446         Output file name.
 2447     -p, --PMLOut <yes or no>  [default: yes]
 2448         Save PML file during generation of PSE file.
 2449     --pocketContactsLigandColor <text>  [default: orange]
 2450         Color for drawing polar contacts between ligand and pocket residues.
 2451         The specified value must be valid color. No validation is performed.
 2452     --pocketContactsLigandHydrophobicColor <text>  [default: purpleblue]
 2453         Color for drawing hydrophobic contacts between ligand and pocket residues.
 2454         The specified value must be valid color. No validation is performed. The
 2455         hydrophobic contacts are shown between pairs of carbon atoms not
 2456         connected to hydrogen bond donor or acceptors atoms as identified
 2457         by PyMOL.
 2458     --pocketContactsSolventColor <text>  [default: marine]
 2459         Color for drawing polar contacts between solvent and pocket residues.
 2460         The specified value must be valid color. No validation is performed.
 2461     --pocketContactsInorganicColor <text>  [default: deepsalmon]
 2462         Color for drawing polar contacts between inorganic and pocket residues.
 2463         The specified value must be valid color. No validation is performed.
 2464     --pocketContactsCutoff <number>  [default: 4.0]
 2465         Distance in Angstroms for identifying polar and hyrdophobic contacts
 2466         between atoms in pocket residues and ligands.
 2467     --pocketDistanceCutoff <number>  [default: 5.0]
 2468         Distance in Angstroms for identifying pocket residues around ligands.
 2469     --pocketLabelColor <text>  [default: magenta]
 2470         Color for drawing residue or atom level labels for a pocket. The specified
 2471         value must be valid color. No validation is performed.
 2472     --pocketSurface <yes or no>  [default: yes]
 2473         Hydrophobic surface around pocket. The pocket surface is colored by
 2474         hydrophobicity. It is only valid for proteins. The color of amino acids is
 2475         set using the Eisenberg hydrophobicity scale. The color varies from red
 2476         to white, red being the most hydrophobic amino acid.
 2477     --selectionsChain <ObjectName,SelectionSpec,...>  [default: None]
 2478         Custom selections for chains. It is a pairwise of list comma delimited values
 2479         corresponding to PyMOL object names and selection specifications.  The
 2480         selection specification must be a valid PyMOL specification. No validation is
 2481         performed.
 2482         
 2483         The PyMOL objects are created for each chain corresponding to the
 2484         specified selections. The display style for PyMOL objects is set using
 2485         value of '--selectionsChainStyle' option.
 2486         
 2487         The specified selection specification is automatically appended to appropriate
 2488         chain specification before creating PyMOL objects.
 2489         
 2490         For example, the following specification for '--selectionsChain' option will
 2491         generate PyMOL objects for chains containing Cysteines and Serines:
 2492             
 2493             Cysteines,resn CYS,Serines,resn SER
 2494             
 2495     --selectionsChainStyle <DisplayStyle>  [default: sticks]
 2496         Display style for PyMOL objects created for '--selectionsChain' option. It
 2497         must be a valid PyMOL display style. No validation is performed.
 2498     --surfaceComplex <yes or no>  [default: no]
 2499         Create surfaces for complete complex in each input file using corresponding
 2500         composite and difference maps. A total of three surfaces, one for composite
 2501         map and two for difference map, are created for the complete complex.
 2502         
 2503         The composite and difference maps are always loaded for the complex.
 2504     --surfaceChainComplex <yes, no or auto>  [default: auto]
 2505         Create surfaces for individual chain complexes in each input file using corresponding
 2506         composite and difference maps. A total of three surfaces, one for composite
 2507         map and two for difference map, are created for each chain complex. By default,
 2508         the surfaces are automatically created for chain complexes without any ligands. 
 2509     --surfaceTransparency <number>  [default: 0.25]
 2510         Surface transparency for molecular and electron density surfaces.
 2511     --volumeCarveRadius <number>  [default: 1.6]
 2512         Radius in Angstroms around atoms for including electron density during
 2513         generation of volume objects.
 2514     --volumeComplex <yes or no>  [default: no]
 2515         Create volumes for complete complex in input file using corresponding
 2516         composite and difference maps. A total of two volumes, one each for
 2517         composite and difference maps, are created for the complete complex.
 2518     --volumeChainComplex <yes, no, or auto>  [default: auto]
 2519         Create volumes for individual chain complex in each input file using corresponding
 2520         composite and difference maps. A total of two volumes, one each for composite
 2521         and difference maps, are created for each chain complex. By default, the
 2522         volumes are automatically created for chain complexes without any ligands.
 2523     --volumeColorRampCompositeMap <text>  [default: 2fofc]
 2524         Name of volume color ramp for composite maps. The specified value must
 2525         be a valid name. No validation is performed. The following volume color ramps
 2526         are currently available in PyMOL: default, 2fofc, fofc, rainbow, and rainbow2.
 2527     --volumeColorRampDiffMap <text>  [default: fofc]
 2528         Name of volume color ramp for difference maps. The specified value must
 2529         be a valid name. No validation is performed. The following volume color ramps
 2530         are currently available in PyMOL: default, 2fofc, fofc, rainbow, and rainbow2.
 2531     --overwrite
 2532         Overwrite existing files.
 2533     -w, --workingdir <dir>
 2534         Location of working directory which defaults to the current directory.
 2535 
 2536 Examples:
 2537     To visualize electron density for the largest ligand in the first chain, and
 2538     ligand binding pockets to highlight ligand interactions with pockect residues,
 2539     solvents and inorganics, in a PDB file by using default map files, and generate a
 2540     PML file, type:
 2541 
 2542         % PyMOLVisualizeElectronDensity.py -i Sample3.pdb -o Sample3.pml
 2543 
 2544     To visualize electron density for the largest ligand in the first chain, cysteine
 2545     and serine residues in the chain, and ligand binding pockets to highlight ligand
 2546     interactions with pockect residues, solvents and inorganics, in a PDB file by
 2547     using default map files, and generate a PML file, type:
 2548 
 2549         % PyMOLVisualizeElectronDensity.py -i Sample3.pdb -o Sample3.pml
 2550           --selectionsChain "Cysteines,resn cys,Serines,resn ser"
 2551 
 2552     To visualize electron density for all ligands in all chains, and ligand binding
 2553     pockets to highlight ligand interactions with pockect residues, solvents
 2554     and inorganics, in a PDB file by using default map files, and generate a
 2555     PML file, type:
 2556 
 2557         % PyMOLVisualizeElectronDensity.py -i Sample3.pdb -o Sample3.pml
 2558           -c All -l All
 2559 
 2560     To visualize electron density for all chains and ligands, along with displaying
 2561     meshes, volumes, and surfaces for complete complex and individual chains,
 2562     in a PDB file by using  default map files, and generate a PML file, type:
 2563 
 2564         % PyMOLVisualizeElectronDensity.py -i Sample3.pdb -o Sample3.pml
 2565           --chainIDs All --ligandIDs All --meshComplex yes --surfaceComplex yes
 2566           --volumeComplex yes --meshChainComplex yes --surfaceChainComplex yes
 2567           --volumeChainComplex yes
 2568 
 2569     To visualize electron density for ligand ADP in chain E along with ligand binding
 2570     pocket, in a PDB file by using  default map files, and generate a PSE file, type:
 2571 
 2572         % PyMOLVisualizeElectronDensity.py -i Sample3.pdb -o Sample3.pse
 2573           --chainIDs E --ligandIDs ADP
 2574 
 2575     To visualize electron density for all igands in all chains along with their binding
 2576     pockets in a PDB file and using explicit file name suffixes for map files, and
 2577     generate a PML file, type:
 2578 
 2579         % PyMOLVisualizeElectronDensity.py -i Sample3.pdb -o Sample3.pml
 2580           --chainIDs All --ligandIDs All --EDMapSuffixes "CompositeMap,None,
 2581           DifferenceMap,_diff"
 2582 
 2583     To visualize electron density for all ligands in all chains along with their binding
 2584     pockets in a PDB file by using explicit file names for map files, and generate
 2585     a PML file, type:
 2586 
 2587         % PyMOLVisualizeElectronDensity.py -i Sample3.pdb -o Sample3.pml
 2588           --chainIDs All --ligandIDs All --EDMapFiles "Sample3.ccp4,
 2589           Sample3_diff.ccp4"
 2590 
 2591     To align and visualize electron density for all ligands in all chains along with their
 2592     binding pockets in PDB files by using explicit file names for map files, and generate
 2593     a PML file, type:
 2594 
 2595         % PyMOLVisualizeElectronDensity.py -a yes -i "Sample3.pdb,Sample4.pdb"
 2596           -o SampleOut.pml --chainIDs All --ligandIDs All --EDMapFiles
 2597          "Sample3.ccp4,Sample3_diff.ccp4,Sample4.ccp4,Sample4_diff.ccp4"
 2598 
 2599 Author:
 2600     Manish Sud(msud@san.rr.com)
 2601 
 2602 See also:
 2603     DownloadPDBFiles.pl, PyMOLVisualizeCavities.py,
 2604     PyMOLVisualizeCryoEMDensity.py, PyMOLVisualizeInterfaces.py,
 2605     PyMOLVisualizeMacromolecules.py, PyMOLVisualizeSurfaceAndBuriedResidues.py
 2606 
 2607 Copyright:
 2608     Copyright (C) 2026 Manish Sud. All rights reserved.
 2609 
 2610     The functionality available in this script is implemented using PyMOL, a
 2611     molecular visualization system on an open source foundation originally
 2612     developed by Warren DeLano.
 2613 
 2614     This file is part of MayaChemTools.
 2615 
 2616     MayaChemTools is free software; you can redistribute it and/or modify it under
 2617     the terms of the GNU Lesser General Public License as published by the Free
 2618     Software Foundation; either version 3 of the License, or (at your option) any
 2619     later version.
 2620 
 2621 """
 2622 
 2623 if __name__ == "__main__":
 2624     main()