MayaChemTools

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