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 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 generic_fns.mol_res_spin import exists_mol_res_spin_data
42 from generic_fns import pipes
43 from generic_fns.result_files import add_result_file
44 from maths_fns.rotation_matrix import euler_to_R_zyz, R_to_axis_angle
45 from relax_errors import RelaxError, RelaxNoPdbError, RelaxNoSequenceError
46 from relax_io import delete, file_root, get_file_path, open_read_file, open_write_file, test_binary
47 from specific_fns.setup import get_specific_fn
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 = mol.file_name
152 if mol.file_path:
153 file = mol.file_path + sep + file
154
155
156 if file in open_files:
157 continue
158
159
160 self.exec_cmd("load " + file)
161
162
163 open_files.append(file)
164
165
167 """Test if PyMOL is running.
168
169 @return: Whether the Molmol pipe is open or not.
170 @rtype: bool
171 """
172
173
174 if self.exec_mode == 'module':
175 return self.open
176
177
178 if self.exec_mode == 'external':
179
180 if not hasattr(self, 'pymol'):
181 return False
182
183
184 try:
185 self.pymol.write('\n')
186 except IOError:
187 return False
188
189
190 return True
191
192
193
194
195 pymol_obj = Pymol('external')
196 """Pymol data container instance."""
197
198
199
201 """Apply the PyMOL cartoon style and colour by secondary structure."""
202
203
204 pipes.test()
205
206
207 if not hasattr(cdp, 'structure'):
208 raise RelaxNoPdbError
209
210
211 open_files = []
212 for model in cdp.structure.structural_data:
213 for mol in model.mol:
214
215 pdb_file = mol.file_name
216 if mol.file_path:
217 pdb_file = mol.file_path + sep + pdb_file
218 id = file_root(pdb_file)
219
220
221 if pdb_file in open_files:
222 continue
223
224
225 open_files.append(pdb_file)
226
227
228 pymol_obj.exec_cmd("cmd.hide('everything'," + repr(id) + ")")
229
230
231 pymol_obj.exec_cmd("cmd.show('cartoon'," + repr(id) + ")")
232
233
234 pymol_obj.exec_cmd("util.cbss(" + repr(id) + ", 'red', 'yellow', 'green')")
235
236
238 """Function for sending PyMOL commands to the program pipe.
239
240 @param command: The command to send into the program.
241 @type command: str
242 """
243
244
245 pymol_obj.exec_cmd(command)
246
247
249 """Display the cone geometric object.
250
251 @keyword file: The name of the file containing the cone geometric object.
252 @type file: str
253 """
254
255
256 pymol_obj.exec_cmd("load " + file)
257
258
259
260
261
262
263 pymol_obj.exec_cmd("select (resn AVE,XAX,YAX,ZAX,SIM)")
264
265
266 pymol_obj.exec_cmd("show stick, 'sele'")
267
268
269 pymol_obj.exec_cmd("color cyan, 'sele'")
270
271
272 pymol_obj.exec_cmd("select (resn AVE,XAX,YAX,ZAX,SIM and symbol N)")
273
274
275 pymol_obj.exec_cmd("hide ('sele')")
276
277
278 pymol_obj.exec_cmd("cmd.label(\"sele\",\"name\")")
279
280
281
282
283
284
285 pymol_obj.exec_cmd("select (resn CON,EDG)")
286
287
288 pymol_obj.exec_cmd("hide ('sele')")
289
290
291 pymol_obj.exec_cmd("show sticks, 'sele'")
292
293
294 pymol_obj.exec_cmd("color white, 'sele'")
295
296
297 pymol_obj.exec_cmd("set stick_radius,0.15000")
298
299
300 pymol_obj.exec_cmd("set stick_transparency, 0.3")
301
302
303
304
305
306
307 pymol_obj.exec_cmd("cmd.delete('sele')")
308
309
310
311
312
313
314 if hasattr(cdp, 'ave_pos_beta'):
315
316 ave_pos_R = zeros((3, 3), float64)
317 ave_pos_alpha = 0.0
318 if hasattr(cdp, 'ave_pos_alpha') and cdp.ave_pos_alpha != None:
319 ave_pos_alpha = cdp.ave_pos_alpha
320 euler_to_R_zyz(ave_pos_alpha, cdp.ave_pos_beta, cdp.ave_pos_gamma, ave_pos_R)
321
322
323 R = transpose(ave_pos_R)
324
325
326 axis, angle = R_to_axis_angle(R)
327
328
329 for i in range(len(cdp.domain_to_pdb)):
330 if cdp.domain_to_pdb[i][0] != cdp.ref_domain:
331 pdb = cdp.domain_to_pdb[i][1]
332
333
334 pymol_obj.exec_cmd("cmd.rotate([%s, %s, %s], %s, '%s', origin=[%s, %s, %s])" % (axis[0], axis[1], axis[2], angle/pi*180.0, pdb, cdp.pivot[0], cdp.pivot[1], cdp.pivot[2]))
335
336
337 -def create_macro(data_type=None, style="classic", colour_start=None, colour_end=None, colour_list=None):
338 """Create an array of PyMOL commands.
339
340 @keyword data_type: The data type to map to the structure.
341 @type data_type: str
342 @keyword style: The style of the macro.
343 @type style: str
344 @keyword colour_start: The starting colour of the linear gradient.
345 @type colour_start: str or RBG colour array (len 3 with vals from 0 to 1)
346 @keyword colour_end: The ending colour of the linear gradient.
347 @type colour_end: str or RBG colour array (len 3 with vals from 0 to 1)
348 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'.
349 @type colour_list: str or None
350 @return: The list of PyMOL commands.
351 @rtype: list of str
352 """
353
354
355 macro = get_specific_fn('pymol_macro', cdp.pipe_type)
356
357
358 commands = macro(data_type, style, colour_start, colour_end, colour_list)
359
360
361 return commands
362
363
364 -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):
365 """Execute a PyMOL macro.
366
367 @keyword data_type: The data type to map to the structure.
368 @type data_type: str
369 @keyword style: The style of the macro.
370 @type style: str
371 @keyword colour_start_name: The name of the starting colour of the linear gradient.
372 @type colour_start_name: str
373 @keyword colour_start_rgb: The RGB array starting colour of the linear gradient.
374 @type colour_start_rgb: RBG colour array (len 3 with vals from 0 to 1)
375 @keyword colour_end_name: The name of the ending colour of the linear gradient.
376 @type colour_end_name: str
377 @keyword colour_end_rgb: The RGB array ending colour of the linear gradient.
378 @type colour_end_rgb: RBG colour array (len 3 with vals from 0 to 1)
379 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'.
380 @type colour_list: str or None
381 """
382
383
384 pipes.test()
385
386
387 if not exists_mol_res_spin_data():
388 raise RelaxNoSequenceError
389
390
391 if colour_start_name != None and colour_start_rgb != None:
392 raise RelaxError("The starting colour name and RGB colour array cannot both be supplied.")
393 if colour_end_name != None and colour_end_rgb != None:
394 raise RelaxError("The ending colour name and RGB colour array cannot both be supplied.")
395
396
397 if colour_start_name != None:
398 colour_start = colour_start_name
399 else:
400 colour_start = colour_start_rgb
401 if colour_end_name != None:
402 colour_end = colour_end_name
403 else:
404 colour_end = colour_end_rgb
405
406
407 pymol_obj.clear_history()
408
409
410 commands = create_macro(data_type=data_type, style=style, colour_start=colour_start, colour_end=colour_end, colour_list=colour_list)
411
412
413 try:
414
415 tmpfile = "%s.pml" % mktemp()
416
417
418 file = open(tmpfile, 'w')
419
420
421 for command in commands:
422 file.write("%s\n" % command)
423 file.close()
424
425
426 pymol_obj.exec_cmd("@%s" % tmpfile)
427
428
429 sleep(3)
430
431
432 finally:
433
434 delete(tmpfile, fail=False)
435
436
453
454
455 -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):
456 """Create a PyMOL macro file.
457
458 @keyword data_type: The data type to map to the structure.
459 @type data_type: str
460 @keyword style: The style of the macro.
461 @type style: str
462 @keyword colour_start_name: The name of the starting colour of the linear gradient.
463 @type colour_start_name: str
464 @keyword colour_start_rgb: The RGB array starting colour of the linear gradient.
465 @type colour_start_rgb: RBG colour array (len 3 with vals from 0 to 1)
466 @keyword colour_end_name: The name of the ending colour of the linear gradient.
467 @type colour_end_name: str
468 @keyword colour_end_rgb: The RGB array ending colour of the linear gradient.
469 @type colour_end_rgb: RBG colour array (len 3 with vals from 0 to 1)
470 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'.
471 @type colour_list: str or None
472 @keyword file: The name of the macro file to create.
473 @type file: str
474 @keyword dir: The name of the directory to place the macro file into.
475 @type dir: str
476 @keyword force: Flag which if set to True will cause any pre-existing file to be overwritten.
477 @type force: bool
478 """
479
480
481 pipes.test()
482
483
484 if not exists_mol_res_spin_data():
485 raise RelaxNoSequenceError
486
487
488 if colour_start_name != None and colour_start_rgb != None:
489 raise RelaxError("The starting colour name and RGB colour array cannot both be supplied.")
490 if colour_end_name != None and colour_end_rgb != None:
491 raise RelaxError("The ending colour name and RGB colour array cannot both be supplied.")
492
493
494 if colour_start_name != None:
495 colour_start = colour_start_name
496 else:
497 colour_start = colour_start_rgb
498 if colour_end_name != None:
499 colour_end = colour_end_name
500 else:
501 colour_end = colour_end_rgb
502
503
504 commands = create_macro(data_type=data_type, style=style, colour_start=colour_start, colour_end=colour_end, colour_list=colour_list)
505
506
507 if file == None:
508 file = data_type + '.pml'
509
510
511 file_path = get_file_path(file, dir)
512 file = open_write_file(file, dir, force)
513
514
515 for command in commands:
516 file.write(command + "\n")
517
518
519 file.close()
520
521
522 add_result_file(type='pymol', label='PyMOL', file=file_path)
523
524
603
604
606 """Display the XH bond vector distribution.
607
608 @keyword file: The vector distribution PDB file.
609 @type file: str
610 """
611
612
613 pipes.test()
614
615
616 id = file_root(file)
617
618
619 pymol_obj.exec_cmd("load " + file)
620
621
622
623
624
625
626 pymol_obj.exec_cmd("cmd.show('surface', " + repr(id) + ")")
627
628
637