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