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, pardir, sep
32 PIPE, Popen = None, None
33 if dep_check.subprocess_module:
34 from subprocess import PIPE, Popen
35 from tempfile import mktemp
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 pipe_control.mol_res_spin import exists_mol_res_spin_data
44 from pipe_control.pipes import check_pipe
45 from pipe_control.result_files import add_result_file
46 from specific_analyses.api import return_api
47 from status import Status; status = Status()
48
49
51 """The PyMOL execution object."""
52
54 """Set up the PyMOL execution object.
55
56 @keyword exec_mode: The execution mode which can be either 'module' or 'external'.
57 @type exec_mode: None or str
58 """
59
60
61 self.command_history = ""
62
63
64 self.exec_mode = exec_mode
65 if not exec_mode:
66 if dep_check.pymol_module:
67 self.exec_mode = 'module'
68 self.open = False
69 else:
70 self.exec_mode = 'external'
71
72
73 - def clear_history(self):
74 """Clear the PyMOL command history."""
75
76 self.command_history = ""
77
78
79 - def exec_cmd(self, command=None, store_command=True):
80 """Execute a PyMOL command.
81
82 @param command: The PyMOL command to send into the program.
83 @type command: str
84 @param store_command: A flag specifying if the command should be stored in the history
85 variable.
86 @type store_command: bool
87 """
88
89
90 if not self.running():
91 self.open_gui()
92
93
94 if self.exec_mode == 'module':
95 pymol.cmd.do(command)
96 else:
97 self.pymol.write(command + '\n')
98
99
100 if store_command:
101 self.command_history = self.command_history + command + "\n"
102
103
105 """Open the PyMOL GUI."""
106
107
108 if self.exec_mode == 'module':
109
110 pymol.finish_launching()
111 self.open = True
112
113
114 if self.exec_mode == 'external':
115
116 test_binary('pymol')
117
118
119 if Popen == None:
120 raise RelaxError("The subprocess module is not available in this version of Python.")
121
122
123 self.pymol = Popen(['pymol', '-qpK'], stdin=PIPE).stdin
124
125
126 if len(self.command_history) > 0:
127 self.exec_cmd(self.command_history, store_command=0)
128 return
129
130
131 if hasattr(cdp, 'structure'):
132 self.open_pdb()
133
134
136 """Open the PDB file in PyMOL."""
137
138
139 if not self.running():
140 return
141
142
143 self.exec_cmd("reinitialize")
144
145
146 open_files = []
147 for model in cdp.structure.structural_data:
148 for mol in model.mol:
149
150 if not hasattr(mol, 'file_name'):
151 warn(RelaxWarning("Cannot display the current molecular data in PyMOL as it has not been exported as a PDB file."))
152 continue
153
154
155 file_path = None
156 if access(mol.file_name, F_OK):
157 file_path = mol.file_name
158
159
160 if file_path == None and hasattr(mol, 'file_path') and mol.file_path != None:
161 file_path = mol.file_path + sep + mol.file_name
162 if not access(file_path, F_OK):
163 file_path = None
164
165
166 if file_path == None and hasattr(mol, 'file_path_abs') and mol.file_path_abs != None:
167 file_path = mol.file_path_abs + sep + mol.file_name
168 if not access(file_path, F_OK):
169 file_path = None
170
171
172 if file_path == None and hasattr(mol, 'file_path') and mol.file_path != None:
173 file_path = pardir + sep + mol.file_path + sep + mol.file_name
174 if not access(file_path, F_OK):
175 file_path = None
176
177
178 if file_path == None:
179 file_path = mol.file_name
180
181
182 if file_path in open_files:
183 continue
184
185
186 if file_path in open_files:
187 continue
188
189
190 self.exec_cmd("load " + file_path)
191
192
193 open_files.append(file_path)
194
195
197 """Test if PyMOL is running.
198
199 @return: Whether the Molmol pipe is open or not.
200 @rtype: bool
201 """
202
203
204 if self.exec_mode == 'module':
205 return self.open
206
207
208 if self.exec_mode == 'external':
209
210 if not hasattr(self, 'pymol'):
211 return False
212
213
214 try:
215 self.pymol.write('\n')
216 except IOError:
217 return False
218
219
220 return True
221
222
223
224
225 pymol_obj = Pymol('external')
226 """Pymol data container instance."""
227
228
229
231 """Apply the PyMOL cartoon style and colour by secondary structure."""
232
233
234 check_pipe()
235
236
237 if not hasattr(cdp, 'structure'):
238 raise RelaxNoPdbError
239
240
241 open_files = []
242 for model in cdp.structure.structural_data:
243 for mol in model.mol:
244
245 pdb_file = mol.file_name
246 if mol.file_path:
247 pdb_file = mol.file_path + sep + pdb_file
248 id = file_root(pdb_file)
249
250
251 if pdb_file in open_files:
252 continue
253
254
255 open_files.append(pdb_file)
256
257
258 pymol_obj.exec_cmd("cmd.hide('everything'," + repr(id) + ")")
259
260
261 pymol_obj.exec_cmd("cmd.show('cartoon'," + repr(id) + ")")
262
263
264 pymol_obj.exec_cmd("util.cbss(" + repr(id) + ", 'red', 'yellow', 'green')")
265
266
268 """Function for sending PyMOL commands to the program pipe.
269
270 @param command: The command to send into the program.
271 @type command: str
272 """
273
274
275 pymol_obj.exec_cmd(command)
276
277
279 """Display the cone geometric object.
280
281 @keyword file: The name of the file containing the cone geometric object.
282 @type file: str
283 """
284
285
286 pymol_obj.exec_cmd("load " + file)
287
288
289
290
291
292
293 pymol_obj.exec_cmd("select (resn AVE,AXE,SIM)")
294
295
296 pymol_obj.exec_cmd("show stick, 'sele'")
297
298
299 pymol_obj.exec_cmd("color cyan, 'sele'")
300
301
302 pymol_obj.exec_cmd("select (resn AVE,AXE,SIM and symbol N)")
303
304
305 pymol_obj.exec_cmd("hide ('sele')")
306
307
308 pymol_obj.exec_cmd("cmd.label(\"sele\",\"name\")")
309
310
311
312
313
314
315 pymol_obj.exec_cmd("select (resn CON,EDG)")
316
317
318 pymol_obj.exec_cmd("hide ('sele')")
319
320
321 pymol_obj.exec_cmd("show sticks, 'sele'")
322
323
324 pymol_obj.exec_cmd("color white, 'sele'")
325
326
327 pymol_obj.exec_cmd("set stick_radius,0.15000")
328
329
330 pymol_obj.exec_cmd("set stick_transparency, 0.3")
331
332
333
334
335
336
337 pymol_obj.exec_cmd("cmd.delete('sele')")
338
339
340 -def create_macro(data_type=None, style="classic", colour_start=None, colour_end=None, colour_list=None):
341 """Create an array of PyMOL commands.
342
343 @keyword data_type: The data type to map to the structure.
344 @type data_type: str
345 @keyword style: The style of the macro.
346 @type style: str
347 @keyword colour_start: The starting colour of the linear gradient.
348 @type colour_start: str or RBG colour array (len 3 with vals from 0 to 1)
349 @keyword colour_end: The ending colour of the linear gradient.
350 @type colour_end: str or RBG colour array (len 3 with vals from 0 to 1)
351 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'.
352 @type colour_list: str or None
353 @return: The list of PyMOL commands.
354 @rtype: list of str
355 """
356
357
358 api = return_api()
359 commands = api.pymol_macro(data_type, style, colour_start, colour_end, colour_list)
360
361
362 return commands
363
364
365 -def frame_order(ave_pos_file="ave_pos.pdb", rep_file="frame_order.pdb", dist_file="domain_distribution.pdb", dir=None):
366 """Display the frame order results (the geometric object, average position and distribution).
367
368 @keyword ave_pos_file: The name of the file for the average molecule structure.
369 @type ave_pos_file: str or None
370 @keyword rep_file: The name of the file of the PDB representation of the frame order dynamics to create.
371 @type rep_file: str or None
372 @keyword dist_file: The name of the file which will contain multiple models spanning the full dynamics distribution of the frame order model.
373 @type dist_file: str or None
374 @keyword dir: The name of the directory to place the PDB file into.
375 @type dir: str or None
376 """
377
378
379 path = ''
380 if dir != None:
381 path = dir + sep
382
383
384 if ave_pos_file:
385 frame_order_ave_pos(file=path+ave_pos_file)
386 if rep_file:
387 frame_order_geometric(file=path+rep_file)
388 if dist_file:
389 frame_order_distribution(file=path+dist_file)
390
391
393 """Display the PDB structure for the frame order average domain position.
394
395 @keyword file: The name of the PDB file containing the frame order average structure.
396 @type file: str
397 """
398
399
400 pymol_obj.exec_cmd("load " + file)
401
402
403 id = file_root(file)
404
405
407 """Display the PDB structure for the frame order distribution of domain positions.
408
409 @keyword file: The name of the PDB file containing the frame order distribution of domain positions.
410 @type file: str
411 """
412
413
414 pymol_obj.exec_cmd("load " + file)
415
416
417
419 """Display the frame order geometric object.
420
421 @keyword file: The name of the PDB file containing the frame order geometric object.
422 @type file: str
423 """
424
425
426 pymol_obj.exec_cmd("load " + file)
427
428
429 id = file_root(file)
430
431
432
433
434
435
436 pymol_obj.exec_cmd("select (resn AX,PRC)")
437 pymol_obj.exec_cmd("show stick, 'sele'")
438 pymol_obj.exec_cmd("color red, 'sele'")
439 pymol_obj.exec_cmd("cmd.delete('sele')")
440
441
442 pymol_obj.exec_cmd("select (name CTR)")
443 pymol_obj.exec_cmd("show spheres, 'sele'")
444 pymol_obj.exec_cmd("color red, 'sele'")
445 pymol_obj.exec_cmd("set sphere_scale, 0.3, 'sele'")
446 pymol_obj.exec_cmd("cmd.delete('sele')")
447
448
449 pymol_obj.exec_cmd("select (resn PRB)")
450 pymol_obj.exec_cmd("show stick, 'sele'")
451 pymol_obj.exec_cmd("set stick_radius, 0.15, 'sele'")
452 pymol_obj.exec_cmd("cmd.delete('sele')")
453
454
455
456
457 -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):
458 """Execute a PyMOL macro.
459
460 @keyword data_type: The data type to map to the structure.
461 @type data_type: str
462 @keyword style: The style of the macro.
463 @type style: str
464 @keyword colour_start_name: The name of the starting colour of the linear gradient.
465 @type colour_start_name: str
466 @keyword colour_start_rgb: The RGB array starting colour of the linear gradient.
467 @type colour_start_rgb: RBG colour array (len 3 with vals from 0 to 1)
468 @keyword colour_end_name: The name of the ending colour of the linear gradient.
469 @type colour_end_name: str
470 @keyword colour_end_rgb: The RGB array ending colour of the linear gradient.
471 @type colour_end_rgb: RBG colour array (len 3 with vals from 0 to 1)
472 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'.
473 @type colour_list: str or None
474 """
475
476
477 check_pipe()
478
479
480 if not exists_mol_res_spin_data():
481 raise RelaxNoSequenceError
482
483
484 if colour_start_name != None and colour_start_rgb != None:
485 raise RelaxError("The starting colour name and RGB colour array cannot both be supplied.")
486 if colour_end_name != None and colour_end_rgb != None:
487 raise RelaxError("The ending colour name and RGB colour array cannot both be supplied.")
488
489
490 if colour_start_name != None:
491 colour_start = colour_start_name
492 else:
493 colour_start = colour_start_rgb
494 if colour_end_name != None:
495 colour_end = colour_end_name
496 else:
497 colour_end = colour_end_rgb
498
499
500 pymol_obj.clear_history()
501
502
503 commands = create_macro(data_type=data_type, style=style, colour_start=colour_start, colour_end=colour_end, colour_list=colour_list)
504
505
506 try:
507
508 tmpfile = "%s.pml" % mktemp()
509
510
511 file = open(tmpfile, 'w')
512
513
514 for command in commands:
515 file.write("%s\n" % command)
516 file.close()
517
518
519 pymol_obj.exec_cmd("@%s" % tmpfile)
520
521
522 sleep(3)
523
524
525 finally:
526
527 delete(tmpfile, fail=False)
528
529
546
547
548 -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):
549 """Create a PyMOL macro file.
550
551 @keyword data_type: The data type to map to the structure.
552 @type data_type: str
553 @keyword style: The style of the macro.
554 @type style: str
555 @keyword colour_start_name: The name of the starting colour of the linear gradient.
556 @type colour_start_name: str
557 @keyword colour_start_rgb: The RGB array starting colour of the linear gradient.
558 @type colour_start_rgb: RBG colour array (len 3 with vals from 0 to 1)
559 @keyword colour_end_name: The name of the ending colour of the linear gradient.
560 @type colour_end_name: str
561 @keyword colour_end_rgb: The RGB array ending colour of the linear gradient.
562 @type colour_end_rgb: RBG colour array (len 3 with vals from 0 to 1)
563 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'.
564 @type colour_list: str or None
565 @keyword file: The name of the macro file to create.
566 @type file: str
567 @keyword dir: The name of the directory to place the macro file into.
568 @type dir: str
569 @keyword force: Flag which if set to True will cause any pre-existing file to be overwritten.
570 @type force: bool
571 """
572
573
574 check_pipe()
575
576
577 if not exists_mol_res_spin_data():
578 raise RelaxNoSequenceError
579
580
581 if colour_start_name != None and colour_start_rgb != None:
582 raise RelaxError("The starting colour name and RGB colour array cannot both be supplied.")
583 if colour_end_name != None and colour_end_rgb != None:
584 raise RelaxError("The ending colour name and RGB colour array cannot both be supplied.")
585
586
587 if colour_start_name != None:
588 colour_start = colour_start_name
589 else:
590 colour_start = colour_start_rgb
591 if colour_end_name != None:
592 colour_end = colour_end_name
593 else:
594 colour_end = colour_end_rgb
595
596
597 commands = create_macro(data_type=data_type, style=style, colour_start=colour_start, colour_end=colour_end, colour_list=colour_list)
598
599
600 if file == None:
601 file = data_type + '.pml'
602
603
604 file_path = get_file_path(file, dir)
605 file = open_write_file(file, dir, force)
606
607
608 for command in commands:
609 file.write(command + "\n")
610
611
612 file.close()
613
614
615 add_result_file(type='pymol', label='PyMOL', file=file_path)
616
617
696
697
699 """Display the XH bond vector distribution.
700
701 @keyword file: The vector distribution PDB file.
702 @type file: str
703 """
704
705
706 check_pipe()
707
708
709 id = file_root(file)
710
711
712 pymol_obj.exec_cmd("load " + file)
713
714
715
716
717
718
719 pymol_obj.exec_cmd("cmd.show('surface', " + repr(id) + ")")
720
721
730