1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """Module for interfacing with PyMOL."""
24
25
26 import dep_check
27
28
29 if dep_check.pymol_module:
30 import pymol
31 from os import F_OK, access, close, getcwd, pardir, sep
32 PIPE, Popen = None, None
33 if dep_check.subprocess_module:
34 from subprocess import PIPE, Popen
35 from tempfile import mkstemp
36 from time import sleep
37 from warnings import warn
38
39
40 from lib.errors import RelaxError, RelaxNoPdbError, RelaxNoSequenceError
41 from lib.warnings import RelaxWarning
42 from lib.io import delete, file_root, get_file_path, open_read_file, open_write_file, test_binary
43 from lib.structure.files import find_pdb_files
44 from pipe_control.mol_res_spin import exists_mol_res_spin_data
45 from pipe_control.pipes import check_pipe
46 from pipe_control.result_files import add_result_file
47 from specific_analyses.api import return_api
48 from status import Status; status = Status()
49
50
52 """The PyMOL execution object."""
53
55 """Set up the PyMOL execution object.
56
57 @keyword exec_mode: The execution mode which can be either 'module' or 'external'.
58 @type exec_mode: None or str
59 """
60
61
62 self.command_history = ""
63
64
65 self.exec_mode = exec_mode
66 if not exec_mode:
67 if dep_check.pymol_module:
68 self.exec_mode = 'module'
69 self.open = False
70 else:
71 self.exec_mode = 'external'
72
73
74 - def clear_history(self):
75 """Clear the PyMOL command history."""
76
77 self.command_history = ""
78
79
80 - def exec_cmd(self, command=None, store_command=True):
81 """Execute a PyMOL command.
82
83 @param command: The PyMOL command to send into the program.
84 @type command: str
85 @param store_command: A flag specifying if the command should be stored in the history
86 variable.
87 @type store_command: bool
88 """
89
90
91 if not self.running():
92 self.open_gui()
93
94
95 if self.exec_mode == 'module':
96 pymol.cmd.do(command)
97 else:
98 self.pymol.write(command + '\n')
99
100
101 if store_command:
102 self.command_history = self.command_history + command + "\n"
103
104
106 """Open the PyMOL GUI."""
107
108
109 if self.exec_mode == 'module':
110
111 pymol.finish_launching()
112 self.open = True
113
114
115 if self.exec_mode == 'external':
116
117 test_binary('pymol')
118
119
120 if Popen == None:
121 raise RelaxError("The subprocess module is not available in this version of Python.")
122
123
124 self.pymol = Popen(['pymol', '-qpK'], stdin=PIPE).stdin
125
126
127 if len(self.command_history) > 0:
128 self.exec_cmd(self.command_history, store_command=0)
129 return
130
131
132 if hasattr(cdp, 'structure'):
133 self.open_pdb()
134
135
137 """Open the PDB file in PyMOL."""
138
139
140 if not self.running():
141 return
142
143
144 self.exec_cmd("reinitialize")
145
146
147 open_files = []
148 for model in cdp.structure.structural_data:
149 for mol in model.mol:
150
151 if not hasattr(mol, 'file_name'):
152 warn(RelaxWarning("Cannot display the current molecular data in PyMOL as it has not been exported as a PDB file."))
153 continue
154
155
156 file_path = None
157 if access(mol.file_name, F_OK):
158 file_path = mol.file_name
159
160
161 if file_path == None and hasattr(mol, 'file_path') and mol.file_path != None:
162 file_path = mol.file_path + sep + mol.file_name
163 if not access(file_path, F_OK):
164 file_path = None
165
166
167 if file_path == None and hasattr(mol, 'file_path_abs') and mol.file_path_abs != None:
168 file_path = mol.file_path_abs + sep + mol.file_name
169 if not access(file_path, F_OK):
170 file_path = None
171
172
173 if file_path == None and hasattr(mol, 'file_path') and mol.file_path != None:
174 file_path = pardir + sep + mol.file_path + sep + mol.file_name
175 if not access(file_path, F_OK):
176 file_path = None
177
178
179 if file_path == None:
180 file_path = mol.file_name
181
182
183 if file_path in open_files:
184 continue
185
186
187 if file_path in open_files:
188 continue
189
190
191 self.exec_cmd("load " + file_path)
192
193
194 open_files.append(file_path)
195
196
198 """Test if PyMOL is running.
199
200 @return: Whether the Molmol pipe is open or not.
201 @rtype: bool
202 """
203
204
205 if self.exec_mode == 'module':
206 return self.open
207
208
209 if self.exec_mode == 'external':
210
211 if not hasattr(self, 'pymol'):
212 return False
213
214
215 try:
216 self.pymol.write('\n')
217 except IOError:
218 return False
219
220
221 return True
222
223
224
225
226 pymol_obj = Pymol('external')
227 """Pymol data container instance."""
228
229
230
232 """Apply the PyMOL cartoon style and colour by secondary structure."""
233
234
235 check_pipe()
236
237
238 if not hasattr(cdp, 'structure'):
239 raise RelaxNoPdbError
240
241
242 open_files = []
243 for model in cdp.structure.structural_data:
244 for mol in model.mol:
245
246 pdb_file = mol.file_name
247 if mol.file_path:
248 pdb_file = mol.file_path + sep + pdb_file
249 id = file_root(pdb_file)
250
251
252 if pdb_file in open_files:
253 continue
254
255
256 open_files.append(pdb_file)
257
258
259 pymol_obj.exec_cmd("cmd.hide('everything'," + repr(id) + ")")
260
261
262 pymol_obj.exec_cmd("cmd.show('cartoon'," + repr(id) + ")")
263
264
265 pymol_obj.exec_cmd("util.cbss(" + repr(id) + ", 'red', 'yellow', 'green')")
266
267
269 """Function for sending PyMOL commands to the program pipe.
270
271 @param command: The command to send into the program.
272 @type command: str
273 """
274
275
276 pymol_obj.exec_cmd(command)
277
278
297
298
299 -def create_macro(data_type=None, style="classic", colour_start=None, colour_end=None, colour_list=None):
300 """Create an array of PyMOL commands.
301
302 @keyword data_type: The data type to map to the structure.
303 @type data_type: str
304 @keyword style: The style of the macro.
305 @type style: str
306 @keyword colour_start: The starting colour of the linear gradient.
307 @type colour_start: str or RBG colour array (len 3 with vals from 0 to 1)
308 @keyword colour_end: The ending colour of the linear gradient.
309 @type colour_end: str or RBG colour array (len 3 with vals from 0 to 1)
310 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'.
311 @type colour_list: str or None
312 @return: The list of PyMOL commands.
313 @rtype: list of str
314 """
315
316
317 api = return_api()
318 commands = api.pymol_macro(data_type, style, colour_start, colour_end, colour_list)
319
320
321 return commands
322
323
324 -def frame_order(ave_pos="ave_pos", rep="frame_order", sim="simulation.pdb.gz", dir=None):
325 """Display the frame order results (geometric object, average position and Brownian simulation).
326
327 @keyword ave_pos: The file root of the average molecule structure.
328 @type ave_pos: str or None
329 @keyword rep: The file root of the PDB representation of the frame order dynamics to create.
330 @type rep: str or None
331 @keyword sim: The full Brownian diffusion file name.
332 @type sim: str or None
333 @keyword dir: The name of the directory where the files are located.
334 @type dir: str or None
335 """
336
337
338 path = getcwd()
339 if dir != None:
340 path = dir + sep
341
342
343 pymol_obj.exec_cmd("disable all")
344
345
346 if ave_pos:
347 frame_order_ave_pos(root=ave_pos, path=path)
348 if rep:
349 frame_order_geometric(root=rep, path=path)
350 if sim:
351 frame_order_sim(file=sim, path=path)
352
353
354 pymol_obj.exec_cmd("center animate=3")
355 pymol_obj.exec_cmd("zoom animate=3")
356
357
378
379
381 """Display the PDB structure for the frame order Brownian simulation.
382
383 @keyword root: The full Brownian diffusion file name.
384 @type root: str
385 """
386
387
388 pdb_files = find_pdb_files(path=path, file_root=file)
389
390
391 for file in pdb_files:
392 pymol_obj.exec_cmd("load " + file)
393
394
442
443
444 -def macro_apply(data_type=None, style="classic", colour_start_name=None, colour_start_rgb=None, colour_end_name=None, colour_end_rgb=None, colour_list=None):
445 """Execute a PyMOL macro.
446
447 @keyword data_type: The data type to map to the structure.
448 @type data_type: str
449 @keyword style: The style of the macro.
450 @type style: str
451 @keyword colour_start_name: The name of the starting colour of the linear gradient.
452 @type colour_start_name: str
453 @keyword colour_start_rgb: The RGB array starting colour of the linear gradient.
454 @type colour_start_rgb: RBG colour array (len 3 with vals from 0 to 1)
455 @keyword colour_end_name: The name of the ending colour of the linear gradient.
456 @type colour_end_name: str
457 @keyword colour_end_rgb: The RGB array ending colour of the linear gradient.
458 @type colour_end_rgb: RBG colour array (len 3 with vals from 0 to 1)
459 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'.
460 @type colour_list: str or None
461 """
462
463
464 check_pipe()
465
466
467 if not exists_mol_res_spin_data():
468 raise RelaxNoSequenceError
469
470
471 if colour_start_name != None and colour_start_rgb != None:
472 raise RelaxError("The starting colour name and RGB colour array cannot both be supplied.")
473 if colour_end_name != None and colour_end_rgb != None:
474 raise RelaxError("The ending colour name and RGB colour array cannot both be supplied.")
475
476
477 if colour_start_name != None:
478 colour_start = colour_start_name
479 else:
480 colour_start = colour_start_rgb
481 if colour_end_name != None:
482 colour_end = colour_end_name
483 else:
484 colour_end = colour_end_rgb
485
486
487 pymol_obj.clear_history()
488
489
490 commands = create_macro(data_type=data_type, style=style, colour_start=colour_start, colour_end=colour_end, colour_list=colour_list)
491
492
493 try:
494
495 tmpfile_handle, tmpfile = mkstemp(suffix='.pml')
496
497
498 file = open(tmpfile, 'w')
499
500
501 for command in commands:
502 file.write("%s\n" % command)
503 file.close()
504
505
506 pymol_obj.exec_cmd("@%s" % tmpfile)
507
508
509 sleep(3)
510
511
512 finally:
513
514 close(tmpfile_handle)
515
516
517 delete(tmpfile, fail=False)
518
519
536
537
538 -def macro_write(data_type=None, style="classic", colour_start_name=None, colour_start_rgb=None, colour_end_name=None, colour_end_rgb=None, colour_list=None, file=None, dir=None, force=False):
539 """Create a PyMOL macro file.
540
541 @keyword data_type: The data type to map to the structure.
542 @type data_type: str
543 @keyword style: The style of the macro.
544 @type style: str
545 @keyword colour_start_name: The name of the starting colour of the linear gradient.
546 @type colour_start_name: str
547 @keyword colour_start_rgb: The RGB array starting colour of the linear gradient.
548 @type colour_start_rgb: RBG colour array (len 3 with vals from 0 to 1)
549 @keyword colour_end_name: The name of the ending colour of the linear gradient.
550 @type colour_end_name: str
551 @keyword colour_end_rgb: The RGB array ending colour of the linear gradient.
552 @type colour_end_rgb: RBG colour array (len 3 with vals from 0 to 1)
553 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'.
554 @type colour_list: str or None
555 @keyword file: The name of the macro file to create.
556 @type file: str
557 @keyword dir: The name of the directory to place the macro file into.
558 @type dir: str
559 @keyword force: Flag which if set to True will cause any pre-existing file to be overwritten.
560 @type force: bool
561 """
562
563
564 check_pipe()
565
566
567 if not exists_mol_res_spin_data():
568 raise RelaxNoSequenceError
569
570
571 if colour_start_name != None and colour_start_rgb != None:
572 raise RelaxError("The starting colour name and RGB colour array cannot both be supplied.")
573 if colour_end_name != None and colour_end_rgb != None:
574 raise RelaxError("The ending colour name and RGB colour array cannot both be supplied.")
575
576
577 if colour_start_name != None:
578 colour_start = colour_start_name
579 else:
580 colour_start = colour_start_rgb
581 if colour_end_name != None:
582 colour_end = colour_end_name
583 else:
584 colour_end = colour_end_rgb
585
586
587 commands = create_macro(data_type=data_type, style=style, colour_start=colour_start, colour_end=colour_end, colour_list=colour_list)
588
589
590 if file == None:
591 file = data_type + '.pml'
592
593
594 file_path = get_file_path(file, dir)
595 file = open_write_file(file, dir, force)
596
597
598 for command in commands:
599 file.write(command + "\n")
600
601
602 file.close()
603
604
605 add_result_file(type='pymol', label='PyMOL', file=file_path)
606
607
639
640
672
673
675 """Set up the PyMOL pivot object representation.
676
677 @keyword id: The PyMOL object ID.
678 @type id: str
679 """
680
681
682 if id == None:
683 raise RelaxError("The PyMOL object ID must be supplied.")
684
685
686 pymol_obj.exec_cmd("select (%s & resn PIV)" % id)
687
688
689 pymol_obj.exec_cmd("hide ('sele')")
690
691
692 pymol_obj.exec_cmd("cmd.label(\"sele\",\"name\")")
693
694
695 pymol_obj.exec_cmd("cmd.delete('sele')")
696
697
738
739
741 """Set up the PyMOL rotor object representation.
742
743 @keyword id: The PyMOL object ID.
744 @type id: str
745 """
746
747
748 if id == None:
749 raise RelaxError("The PyMOL object ID must be supplied.")
750
751
752 pymol_obj.exec_cmd("select (%s & resn RTX)" % id)
753 pymol_obj.exec_cmd("show stick, 'sele'")
754 pymol_obj.exec_cmd("color red, 'sele'")
755 pymol_obj.exec_cmd("cmd.delete('sele')")
756
757
758 pymol_obj.exec_cmd("select (%s & name CTR)" % id)
759 pymol_obj.exec_cmd("show spheres, 'sele'")
760 pymol_obj.exec_cmd("color red, 'sele'")
761 pymol_obj.exec_cmd("set sphere_scale, 0.3, 'sele'")
762 pymol_obj.exec_cmd("cmd.delete('sele')")
763
764
765 pymol_obj.exec_cmd("select (%s & resn RTB)" % id)
766 pymol_obj.exec_cmd("show line, 'sele'")
767 pymol_obj.exec_cmd("cmd.delete('sele')")
768 pymol_obj.exec_cmd("select (%s & resn RTB & name BLD)" % id)
769 pymol_obj.exec_cmd("show spheres, 'sele'")
770 pymol_obj.exec_cmd("set sphere_scale, 0.1, 'sele'")
771 pymol_obj.exec_cmd("cmd.delete('sele')")
772
773
774 pymol_obj.exec_cmd("select (%s & resn RTL)" % id)
775 pymol_obj.exec_cmd("cmd.label(\"sele\",\"name\")")
776 pymol_obj.exec_cmd("cmd.delete('sele')")
777
778
857
858
860 """Display the XH bond vector distribution.
861
862 @keyword file: The vector distribution PDB file.
863 @type file: str
864 """
865
866
867 check_pipe()
868
869
870 id = file_root(file)
871
872
873 pymol_obj.exec_cmd("load " + file)
874
875
876
877
878
879
880 pymol_obj.exec_cmd("cmd.show('surface', " + repr(id) + ")")
881
882
891