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 math import pi
32 from numpy import float64, transpose, zeros
33 from os import F_OK, access, pardir, sep
34 PIPE, Popen = None, None
35 if dep_check.subprocess_module:
36 from subprocess import PIPE, Popen
37 from tempfile import mktemp
38 from time import sleep
39
40
41 from lib.errors import RelaxError, RelaxNoPdbError, RelaxNoSequenceError
42 from lib.geometry.rotations import euler_to_R_zyz, R_to_axis_angle
43 from lib.io import delete, file_root, get_file_path, open_read_file, open_write_file, test_binary
44 from pipe_control import pipes
45 from pipe_control.mol_res_spin import exists_mol_res_spin_data
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 file_path = None
152 if access(mol.file_name, F_OK):
153 file_path = mol.file_name
154
155
156 if file_path == None and hasattr(mol, 'file_path') and mol.file_path != None:
157 file_path = mol.file_path + sep + mol.file_name
158 if not access(file_path, F_OK):
159 file_path = None
160
161
162 if file_path == None and hasattr(mol, 'file_path_abs') and mol.file_path_abs != None:
163 file_path = mol.file_path_abs + sep + mol.file_name
164 if not access(file_path, F_OK):
165 file_path = None
166
167
168 if file_path == None and hasattr(mol, 'file_path') and mol.file_path != None:
169 file_path = pardir + sep + mol.file_path + sep + mol.file_name
170 if not access(file_path, F_OK):
171 file_path = None
172
173
174 if file_path == None:
175 file_path = mol.file_name
176
177
178 if file_path in open_files:
179 continue
180
181
182 if file_path in open_files:
183 continue
184
185
186 self.exec_cmd("load " + file_path)
187
188
189 open_files.append(file_path)
190
191
193 """Test if PyMOL is running.
194
195 @return: Whether the Molmol pipe is open or not.
196 @rtype: bool
197 """
198
199
200 if self.exec_mode == 'module':
201 return self.open
202
203
204 if self.exec_mode == 'external':
205
206 if not hasattr(self, 'pymol'):
207 return False
208
209
210 try:
211 self.pymol.write('\n')
212 except IOError:
213 return False
214
215
216 return True
217
218
219
220
221 pymol_obj = Pymol('external')
222 """Pymol data container instance."""
223
224
225
227 """Apply the PyMOL cartoon style and colour by secondary structure."""
228
229
230 pipes.test()
231
232
233 if not hasattr(cdp, 'structure'):
234 raise RelaxNoPdbError
235
236
237 open_files = []
238 for model in cdp.structure.structural_data:
239 for mol in model.mol:
240
241 pdb_file = mol.file_name
242 if mol.file_path:
243 pdb_file = mol.file_path + sep + pdb_file
244 id = file_root(pdb_file)
245
246
247 if pdb_file in open_files:
248 continue
249
250
251 open_files.append(pdb_file)
252
253
254 pymol_obj.exec_cmd("cmd.hide('everything'," + repr(id) + ")")
255
256
257 pymol_obj.exec_cmd("cmd.show('cartoon'," + repr(id) + ")")
258
259
260 pymol_obj.exec_cmd("util.cbss(" + repr(id) + ", 'red', 'yellow', 'green')")
261
262
264 """Function for sending PyMOL commands to the program pipe.
265
266 @param command: The command to send into the program.
267 @type command: str
268 """
269
270
271 pymol_obj.exec_cmd(command)
272
273
275 """Display the cone geometric object.
276
277 @keyword file: The name of the file containing the cone geometric object.
278 @type file: str
279 """
280
281
282 pymol_obj.exec_cmd("load " + file)
283
284
285
286
287
288
289 pymol_obj.exec_cmd("select (resn AVE,AXE,SIM)")
290
291
292 pymol_obj.exec_cmd("show stick, 'sele'")
293
294
295 pymol_obj.exec_cmd("color cyan, 'sele'")
296
297
298 pymol_obj.exec_cmd("select (resn AVE,AXE,SIM and symbol N)")
299
300
301 pymol_obj.exec_cmd("hide ('sele')")
302
303
304 pymol_obj.exec_cmd("cmd.label(\"sele\",\"name\")")
305
306
307
308
309
310
311 pymol_obj.exec_cmd("select (resn CON,EDG)")
312
313
314 pymol_obj.exec_cmd("hide ('sele')")
315
316
317 pymol_obj.exec_cmd("show sticks, 'sele'")
318
319
320 pymol_obj.exec_cmd("color white, 'sele'")
321
322
323 pymol_obj.exec_cmd("set stick_radius,0.15000")
324
325
326 pymol_obj.exec_cmd("set stick_transparency, 0.3")
327
328
329
330
331
332
333 pymol_obj.exec_cmd("cmd.delete('sele')")
334
335
336 -def create_macro(data_type=None, style="classic", colour_start=None, colour_end=None, colour_list=None):
337 """Create an array of PyMOL commands.
338
339 @keyword data_type: The data type to map to the structure.
340 @type data_type: str
341 @keyword style: The style of the macro.
342 @type style: str
343 @keyword colour_start: The starting colour of the linear gradient.
344 @type colour_start: str or RBG colour array (len 3 with vals from 0 to 1)
345 @keyword colour_end: The ending colour of the linear gradient.
346 @type colour_end: str or RBG colour array (len 3 with vals from 0 to 1)
347 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'.
348 @type colour_list: str or None
349 @return: The list of PyMOL commands.
350 @rtype: list of str
351 """
352
353
354 api = return_api()
355 commands = api.pymol_macro(data_type, style, colour_start, colour_end, colour_list)
356
357
358 return commands
359
360
361 -def frame_order(ave_pos_file="ave_pos.pdb", rep_file="frame_order.pdb", dist_file="domain_distribution.pdb", dir=None):
362 """Display the frame order results (the geometric object, average position and distribution).
363
364 @keyword ave_pos_file: The name of the file for the average molecule structure.
365 @type ave_pos_file: str or None
366 @keyword rep_file: The name of the file of the PDB representation of the frame order dynamics to create.
367 @type rep_file: str or None
368 @keyword dist_file: The name of the file which will contain multiple models spanning the full dynamics distribution of the frame order model.
369 @type dist_file: str or None
370 @keyword dir: The name of the directory to place the PDB file into.
371 @type dir: str or None
372 """
373
374
375 path = ''
376 if dir != None:
377 path = dir + sep
378
379
380 if ave_pos_file:
381 frame_order_ave_pos(file=path+ave_pos_file)
382 if rep_file:
383 frame_order_geometric(file=path+rep_file)
384 if dist_file:
385 frame_order_distribution(file=path+dist_file)
386
387
389 """Display the PDB structure for the frame order average domain position.
390
391 @keyword file: The name of the PDB file containing the frame order average structure.
392 @type file: str
393 """
394
395
396 pymol_obj.exec_cmd("load " + file)
397
398
399 id = file_root(file)
400
401
403 """Display the PDB structure for the frame order distribution of domain positions.
404
405 @keyword file: The name of the PDB file containing the frame order distribution of domain positions.
406 @type file: str
407 """
408
409
410 pymol_obj.exec_cmd("load " + file)
411
412
413
415 """Display the frame order geometric object.
416
417 @keyword file: The name of the PDB file containing the frame order geometric object.
418 @type file: str
419 """
420
421
422 pymol_obj.exec_cmd("load " + file)
423
424
425 id = file_root(file)
426
427
428
429
430
431
432 pymol_obj.exec_cmd("select (resn AX,PRC)")
433 pymol_obj.exec_cmd("show stick, 'sele'")
434 pymol_obj.exec_cmd("color red, 'sele'")
435 pymol_obj.exec_cmd("cmd.delete('sele')")
436
437
438 pymol_obj.exec_cmd("select (name CTR)")
439 pymol_obj.exec_cmd("show spheres, 'sele'")
440 pymol_obj.exec_cmd("color red, 'sele'")
441 pymol_obj.exec_cmd("set sphere_scale, 0.3, 'sele'")
442 pymol_obj.exec_cmd("cmd.delete('sele')")
443
444
445 pymol_obj.exec_cmd("select (resn PRB)")
446 pymol_obj.exec_cmd("show stick, 'sele'")
447 pymol_obj.exec_cmd("set stick_radius, 0.15, 'sele'")
448 pymol_obj.exec_cmd("cmd.delete('sele')")
449
450
451
452
453 -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):
454 """Execute a PyMOL macro.
455
456 @keyword data_type: The data type to map to the structure.
457 @type data_type: str
458 @keyword style: The style of the macro.
459 @type style: str
460 @keyword colour_start_name: The name of the starting colour of the linear gradient.
461 @type colour_start_name: str
462 @keyword colour_start_rgb: The RGB array starting colour of the linear gradient.
463 @type colour_start_rgb: RBG colour array (len 3 with vals from 0 to 1)
464 @keyword colour_end_name: The name of the ending colour of the linear gradient.
465 @type colour_end_name: str
466 @keyword colour_end_rgb: The RGB array ending colour of the linear gradient.
467 @type colour_end_rgb: RBG colour array (len 3 with vals from 0 to 1)
468 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'.
469 @type colour_list: str or None
470 """
471
472
473 pipes.test()
474
475
476 if not exists_mol_res_spin_data():
477 raise RelaxNoSequenceError
478
479
480 if colour_start_name != None and colour_start_rgb != None:
481 raise RelaxError("The starting colour name and RGB colour array cannot both be supplied.")
482 if colour_end_name != None and colour_end_rgb != None:
483 raise RelaxError("The ending colour name and RGB colour array cannot both be supplied.")
484
485
486 if colour_start_name != None:
487 colour_start = colour_start_name
488 else:
489 colour_start = colour_start_rgb
490 if colour_end_name != None:
491 colour_end = colour_end_name
492 else:
493 colour_end = colour_end_rgb
494
495
496 pymol_obj.clear_history()
497
498
499 commands = create_macro(data_type=data_type, style=style, colour_start=colour_start, colour_end=colour_end, colour_list=colour_list)
500
501
502 try:
503
504 tmpfile = "%s.pml" % mktemp()
505
506
507 file = open(tmpfile, 'w')
508
509
510 for command in commands:
511 file.write("%s\n" % command)
512 file.close()
513
514
515 pymol_obj.exec_cmd("@%s" % tmpfile)
516
517
518 sleep(3)
519
520
521 finally:
522
523 delete(tmpfile, fail=False)
524
525
542
543
544 -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):
545 """Create a PyMOL macro file.
546
547 @keyword data_type: The data type to map to the structure.
548 @type data_type: str
549 @keyword style: The style of the macro.
550 @type style: str
551 @keyword colour_start_name: The name of the starting colour of the linear gradient.
552 @type colour_start_name: str
553 @keyword colour_start_rgb: The RGB array starting colour of the linear gradient.
554 @type colour_start_rgb: RBG colour array (len 3 with vals from 0 to 1)
555 @keyword colour_end_name: The name of the ending colour of the linear gradient.
556 @type colour_end_name: str
557 @keyword colour_end_rgb: The RGB array ending colour of the linear gradient.
558 @type colour_end_rgb: RBG colour array (len 3 with vals from 0 to 1)
559 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'.
560 @type colour_list: str or None
561 @keyword file: The name of the macro file to create.
562 @type file: str
563 @keyword dir: The name of the directory to place the macro file into.
564 @type dir: str
565 @keyword force: Flag which if set to True will cause any pre-existing file to be overwritten.
566 @type force: bool
567 """
568
569
570 pipes.test()
571
572
573 if not exists_mol_res_spin_data():
574 raise RelaxNoSequenceError
575
576
577 if colour_start_name != None and colour_start_rgb != None:
578 raise RelaxError("The starting colour name and RGB colour array cannot both be supplied.")
579 if colour_end_name != None and colour_end_rgb != None:
580 raise RelaxError("The ending colour name and RGB colour array cannot both be supplied.")
581
582
583 if colour_start_name != None:
584 colour_start = colour_start_name
585 else:
586 colour_start = colour_start_rgb
587 if colour_end_name != None:
588 colour_end = colour_end_name
589 else:
590 colour_end = colour_end_rgb
591
592
593 commands = create_macro(data_type=data_type, style=style, colour_start=colour_start, colour_end=colour_end, colour_list=colour_list)
594
595
596 if file == None:
597 file = data_type + '.pml'
598
599
600 file_path = get_file_path(file, dir)
601 file = open_write_file(file, dir, force)
602
603
604 for command in commands:
605 file.write(command + "\n")
606
607
608 file.close()
609
610
611 add_result_file(type='pymol', label='PyMOL', file=file_path)
612
613
692
693
695 """Display the XH bond vector distribution.
696
697 @keyword file: The vector distribution PDB file.
698 @type file: str
699 """
700
701
702 pipes.test()
703
704
705 id = file_root(file)
706
707
708 pymol_obj.exec_cmd("load " + file)
709
710
711
712
713
714
715 pymol_obj.exec_cmd("cmd.show('surface', " + repr(id) + ")")
716
717
726