Package generic_fns :: Module pymol_control
[hide private]
[frames] | no frames]

Source Code for Module generic_fns.pymol_control

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2006-2011 Edward d'Auvergne                                   # 
  4  #                                                                             # 
  5  # This file is part of the program relax.                                     # 
  6  #                                                                             # 
  7  # relax is free software; you can redistribute it and/or modify               # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation; either version 2 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # relax is distributed in the hope that it will be useful,                    # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with relax; if not, write to the Free Software                        # 
 19  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   # 
 20  #                                                                             # 
 21  ############################################################################### 
 22   
 23  # Module docstring. 
 24  """Module for interfacing with PyMOL.""" 
 25   
 26  # Dependency check module. 
 27  import dep_check 
 28   
 29  # Python module imports. 
 30  if dep_check.pymol_module: 
 31      import pymol 
 32  from math import pi 
 33  from numpy import float64, transpose, zeros 
 34  from os import sep 
 35  from subprocess import PIPE, Popen 
 36  from tempfile import mktemp 
 37  from time import sleep 
 38   
 39  # relax module imports. 
 40  from generic_fns.mol_res_spin import exists_mol_res_spin_data 
 41  from generic_fns import pipes 
 42  from maths_fns.rotation_matrix import euler_to_R_zyz, R_to_axis_angle 
 43  from relax_errors import RelaxError, RelaxNoPdbError, RelaxNoSequenceError 
 44  from relax_io import delete, file_root, get_file_path, open_read_file, open_write_file, test_binary 
 45  from specific_fns.setup import get_specific_fn 
 46  from status import Status; status = Status() 
 47   
 48   
49 -class Pymol:
50 """The PyMOL execution object.""" 51
52 - def __init__(self, exec_mode=None):
53 """Set up the PyMOL execution object. 54 55 @keyword exec_mode: The execution mode which can be either 'module' or 'external'. 56 @type exec_mode: None or str 57 """ 58 59 # Variable for storing the pymol command history. 60 self.command_history = "" 61 62 # The pymol mode of operation. 63 self.exec_mode = exec_mode 64 if not exec_mode: 65 if dep_check.pymol_module: 66 self.exec_mode = 'module' 67 self.open = False 68 else: 69 self.exec_mode = 'external'
70 71
72 - def clear_history(self):
73 """Clear the PyMOL command history.""" 74 75 self.command_history = ""
76 77
78 - def exec_cmd(self, command=None, store_command=True):
79 """Execute a PyMOL command. 80 81 @param command: The PyMOL command to send into the program. 82 @type command: str 83 @param store_command: A flag specifying if the command should be stored in the history 84 variable. 85 @type store_command: bool 86 """ 87 88 # Reopen the GUI if needed. 89 if not self.running(): 90 self.open_gui() 91 92 # Execute the command. 93 if self.exec_mode == 'module': 94 pymol.cmd.do(command) 95 else: 96 self.pymol.write(command + '\n') 97 98 # Place the command in the command history. 99 if store_command: 100 self.command_history = self.command_history + command + "\n"
101 102
103 - def open_gui(self):
104 """Open the PyMOL GUI.""" 105 106 # Use the PyMOL python modules. 107 if self.exec_mode == 'module': 108 # Open the GUI. 109 pymol.finish_launching() 110 self.open = True 111 112 # Otherwise execute PyMOL on the command line. 113 if self.exec_mode == 'external': 114 # Test that the PyMOL binary exists. 115 test_binary('pymol') 116 117 # Open PyMOL as a pipe. 118 self.pymol = Popen(['pymol', '-qpK'], stdin=PIPE).stdin 119 120 # Execute the command history. 121 if len(self.command_history) > 0: 122 self.exec_cmd(self.command_history, store_command=0) 123 return 124 125 # Test if the PDB file has been loaded. 126 if hasattr(cdp, 'structure'): 127 self.open_pdb()
128 129
130 - def open_pdb(self):
131 """Open the PDB file in PyMOL.""" 132 133 # Test if PyMOL is running. 134 if not self.running(): 135 return 136 137 # Reinitialise PyMOL. 138 self.exec_cmd("reinitialize") 139 140 # Open the PDB files. 141 open_files = [] 142 for model in cdp.structure.structural_data: 143 for mol in model.mol: 144 # The file path. 145 file = mol.file_name 146 if mol.file_path: 147 file = mol.file_path + sep + file 148 149 # Already loaded. 150 if file in open_files: 151 continue 152 153 # Open the file in PyMOL. 154 self.exec_cmd("load " + file) 155 156 # Add to the open file list. 157 open_files.append(file)
158 159
160 - def running(self):
161 """Test if PyMOL is running. 162 163 @return: Whether the Molmol pipe is open or not. 164 @rtype: bool 165 """ 166 167 # Test if PyMOL module interface is already running. 168 if self.exec_mode == 'module': 169 return self.open 170 171 # Test if command line PyMOL is already running. 172 if self.exec_mode == 'external': 173 # Pipe exists. 174 if not hasattr(self, 'pymol'): 175 return False 176 177 # Test if the pipe has been broken. 178 try: 179 self.pymol.write('\n') 180 except IOError: 181 return False 182 183 # PyMOL is running. 184 return True
185 186 187 188 # Initialise the Pymol executable object. 189 pymol_obj = Pymol('external') 190 """Pymol data container instance.""" 191 192 193
194 -def cartoon():
195 """Apply the PyMOL cartoon style and colour by secondary structure.""" 196 197 # Test if the current data pipe exists. 198 pipes.test() 199 200 # Test for the structure. 201 if not hasattr(cdp, 'structure'): 202 raise RelaxNoPdbError 203 204 # Loop over the PDB files. 205 open_files = [] 206 for model in cdp.structure.structural_data: 207 for mol in model.mol: 208 # Identifier. 209 pdb_file = mol.file_name 210 if mol.file_path: 211 pdb_file = mol.file_path + sep + pdb_file 212 id = file_root(pdb_file) 213 214 # Already loaded. 215 if pdb_file in open_files: 216 continue 217 218 # Add to the open file list. 219 open_files.append(pdb_file) 220 221 # Hide everything. 222 pymol_obj.exec_cmd("cmd.hide('everything'," + repr(id) + ")") 223 224 # Show the cartoon style. 225 pymol_obj.exec_cmd("cmd.show('cartoon'," + repr(id) + ")") 226 227 # Colour by secondary structure. 228 pymol_obj.exec_cmd("util.cbss(" + repr(id) + ", 'red', 'yellow', 'green')")
229 230
231 -def command(command):
232 """Function for sending PyMOL commands to the program pipe. 233 234 @param command: The command to send into the program. 235 @type command: str 236 """ 237 238 # Pass the command to PyMOL. 239 pymol_obj.exec_cmd(command)
240 241
242 -def cone_pdb(file=None):
243 """Display the cone geometric object. 244 245 @keyword file: The name of the file containing the cone geometric object. 246 @type file: str 247 """ 248 249 # Read in the cone PDB file. 250 pymol_obj.exec_cmd("load " + file) 251 252 253 # The cone axes. 254 ################ 255 256 # Select the AVE, XAX, YAX, ZAX, and SIM residues. 257 pymol_obj.exec_cmd("select (resn AVE,XAX,YAX,ZAX,SIM)") 258 259 # Show the vector as a stick. 260 pymol_obj.exec_cmd("show stick, 'sele'") 261 262 # Colour it blue. 263 pymol_obj.exec_cmd("color cyan, 'sele'") 264 265 # Select the atom used for labelling. 266 pymol_obj.exec_cmd("select (resn AVE,XAX,YAX,ZAX,SIM and symbol N)") 267 268 # Hide the atom. 269 pymol_obj.exec_cmd("hide ('sele')") 270 271 # Label using the atom name. 272 pymol_obj.exec_cmd("cmd.label(\"sele\",\"name\")") 273 274 275 # The cone object. 276 ################## 277 278 # Select the CON residue. 279 pymol_obj.exec_cmd("select (resn CON,EDG)") 280 281 # Hide everything. 282 pymol_obj.exec_cmd("hide ('sele')") 283 284 # Show as 'sticks'. 285 pymol_obj.exec_cmd("show sticks, 'sele'") 286 287 # Colour it white. 288 pymol_obj.exec_cmd("color white, 'sele'") 289 290 # Shorten the stick width from 0.25 to 0.15. 291 pymol_obj.exec_cmd("set stick_radius,0.15000") 292 293 # Set a bit of transparency. 294 pymol_obj.exec_cmd("set stick_transparency, 0.3") 295 296 297 # Clean up. 298 ########### 299 300 # Remove the selection. 301 pymol_obj.exec_cmd("cmd.delete('sele')") 302 303 304 # Rotate to the average position. 305 ################################# 306 307 # Check if there is an average position. 308 if hasattr(cdp, 'ave_pos_beta'): 309 # The average position rotation. 310 ave_pos_R = zeros((3, 3), float64) 311 ave_pos_alpha = 0.0 312 if hasattr(cdp, 'ave_pos_alpha') and cdp.ave_pos_alpha != None: 313 ave_pos_alpha = cdp.ave_pos_alpha 314 euler_to_R_zyz(ave_pos_alpha, cdp.ave_pos_beta, cdp.ave_pos_gamma, ave_pos_R) 315 316 # The rotation is passive (need to rotated the moving domain back into the average position defined in the non-moving domain PDB frame). 317 R = transpose(ave_pos_R) 318 319 # Convert to axis-angle notation. 320 axis, angle = R_to_axis_angle(R) 321 322 # The PDB file to rotate. 323 for i in range(len(cdp.domain_to_pdb)): 324 if cdp.domain_to_pdb[i][0] != cdp.ref_domain: 325 pdb = cdp.domain_to_pdb[i][1] 326 327 # Execute the pymol command to rotate. 328 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]))
329 330
331 -def create_macro(data_type=None, style="classic", colour_start=None, colour_end=None, colour_list=None):
332 """Create an array of PyMOL commands. 333 334 @keyword data_type: The data type to map to the structure. 335 @type data_type: str 336 @keyword style: The style of the macro. 337 @type style: str 338 @keyword colour_start: The starting colour of the linear gradient. 339 @type colour_start: str or RBG colour array (len 3 with vals from 0 to 1) 340 @keyword colour_end: The ending colour of the linear gradient. 341 @type colour_end: str or RBG colour array (len 3 with vals from 0 to 1) 342 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'. 343 @type colour_list: str or None 344 @return: The list of PyMOL commands. 345 @rtype: list of str 346 """ 347 348 # Specific PyMOL macro creation function. 349 macro = get_specific_fn('pymol_macro', cdp.pipe_type) 350 351 # Get the macro. 352 commands = macro(data_type, style, colour_start, colour_end, colour_list) 353 354 # Return the macro commands. 355 return commands
356 357
358 -def macro_apply(data_type=None, style="classic", colour_start=None, colour_end=None, colour_list=None):
359 """Execute a PyMOL macro. 360 361 @keyword data_type: The data type to map to the structure. 362 @type data_type: str 363 @keyword style: The style of the macro. 364 @type style: str 365 @keyword colour_start: The starting colour of the linear gradient. 366 @type colour_start: str or RBG colour array (len 3 with vals from 0 to 1) 367 @keyword colour_end: The ending colour of the linear gradient. 368 @type colour_end: str or RBG colour array (len 3 with vals from 0 to 1) 369 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'. 370 @type colour_list: str or None 371 """ 372 373 # Test if the current data pipe exists. 374 pipes.test() 375 376 # Test if sequence data exists. 377 if not exists_mol_res_spin_data(): 378 raise RelaxNoSequenceError 379 380 # Clear the PyMOL history first. 381 pymol_obj.clear_history() 382 383 # Create the macro. 384 commands = create_macro(data_type=data_type, style=style, colour_start=colour_start, colour_end=colour_end, colour_list=colour_list) 385 386 # Save the commands as a temporary file, execute it, then delete it. 387 try: 388 # Temp file name. 389 tmpfile = "%s.pml" % mktemp() 390 391 # Open the file. 392 file = open(tmpfile, 'w') 393 394 # Loop over the commands and write them. 395 for command in commands: 396 file.write("%s\n" % command) 397 file.close() 398 399 # Execute the macro. 400 pymol_obj.exec_cmd("@%s" % tmpfile) 401 402 # Wait a bit for PyMOL to catch up (it takes time for PyMOL to start and the macro to execute). 403 sleep(3) 404 405 # Delete the temporary file (no matter what). 406 finally: 407 # Delete the file. 408 delete(tmpfile, fail=False)
409 410
411 -def macro_run(file=None, dir=None):
412 """Execute the PyMOL macro from the given text file. 413 414 @keyword file: The name of the macro file to execute. 415 @type file: str 416 @keyword dir: The name of the directory where the macro file is located. 417 @type dir: str 418 """ 419 420 # Open the file for reading. 421 file_path = get_file_path(file, dir) 422 file = open_read_file(file, dir) 423 424 # Loop over the commands and apply them. 425 for command in file.readlines(): 426 pymol_obj.exec_cmd(command)
427 428
429 -def macro_write(data_type=None, style="classic", colour_start=None, colour_end=None, colour_list=None, file=None, dir=None, force=False):
430 """Create a PyMOL macro file. 431 432 @keyword data_type: The data type to map to the structure. 433 @type data_type: str 434 @keyword style: The style of the macro. 435 @type style: str 436 @keyword colour_start: The starting colour of the linear gradient. 437 @type colour_start: str or RBG colour array (len 3 with vals from 0 to 1) 438 @keyword colour_end: The ending colour of the linear gradient. 439 @type colour_end: str or RBG colour array (len 3 with vals from 0 to 1) 440 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'. 441 @type colour_list: str or None 442 @keyword file: The name of the macro file to create. 443 @type file: str 444 @keyword dir: The name of the directory to place the macro file into. 445 @type dir: str 446 @keyword force: Flag which if set to True will cause any pre-existing file to be overwritten. 447 @type force: bool 448 """ 449 450 # Test if the current data pipe exists. 451 pipes.test() 452 453 # Test if sequence data exists. 454 if not exists_mol_res_spin_data(): 455 raise RelaxNoSequenceError 456 457 # Create the macro. 458 commands = create_macro(data_type=data_type, style=style, colour_start=colour_start, colour_end=colour_end, colour_list=colour_list) 459 460 # File name. 461 if file == None: 462 file = data_type + '.pml' 463 464 # Open the file for writing. 465 file_path = get_file_path(file, dir) 466 file = open_write_file(file, dir, force) 467 468 # Loop over the commands and write them. 469 for command in commands: 470 file.write(command + "\n") 471 472 # Close the file. 473 file.close() 474 475 # Add the file to the results file list. 476 if not hasattr(cdp, 'result_files'): 477 cdp.result_files = [] 478 cdp.result_files.append(['pymol', 'PyMOL', file_path]) 479 status.observers.result_file.notify()
480 481
482 -def tensor_pdb(file=None):
483 """Display the diffusion tensor geometric structure. 484 485 @keyword file: The name of the file containing the diffusion tensor geometric object. 486 @type file: str 487 """ 488 489 # Test if the current data pipe exists. 490 pipes.test() 491 492 # Read in the tensor PDB file. 493 pymol_obj.exec_cmd("load " + file) 494 495 496 # The tensor object. 497 #################### 498 499 # Select the TNS residue. 500 pymol_obj.exec_cmd("select resn TNS") 501 502 # Hide everything. 503 pymol_obj.exec_cmd("hide ('sele')") 504 505 # Show as 'sticks'. 506 pymol_obj.exec_cmd("show sticks, 'sele'") 507 508 509 # Centre of mass. 510 ################# 511 512 # Select the COM residue. 513 pymol_obj.exec_cmd("select resn COM") 514 515 # Show the centre of mass as the dots representation. 516 pymol_obj.exec_cmd("show dots, 'sele'") 517 518 # Colour it blue. 519 pymol_obj.exec_cmd("color blue, 'sele'") 520 521 522 # The diffusion tensor axes. 523 ############################ 524 525 # Select the AXS residue. 526 pymol_obj.exec_cmd("select resn AXS") 527 528 # Hide everything. 529 pymol_obj.exec_cmd("hide ('sele')") 530 531 # Show as 'sticks'. 532 pymol_obj.exec_cmd("show sticks, 'sele'") 533 534 # Colour it cyan. 535 pymol_obj.exec_cmd("color cyan, 'sele'") 536 537 # Select the N atoms of the AXS residue (used to display the axis labels). 538 pymol_obj.exec_cmd("select (resn AXS and elem N)") 539 540 # Label the atoms. 541 pymol_obj.exec_cmd("label 'sele', name") 542 543 544 545 # Monte Carlo simulations. 546 ########################## 547 548 # Select the SIM residue. 549 pymol_obj.exec_cmd("select resn SIM") 550 551 # Colour it. 552 pymol_obj.exec_cmd("colour cyan, 'sele'") 553 554 555 # Clean up. 556 ########### 557 558 # Remove the selection. 559 pymol_obj.exec_cmd("cmd.delete('sele')")
560 561
562 -def vector_dist(file=None):
563 """Display the XH bond vector distribution. 564 565 @keyword file: The vector distribution PDB file. 566 @type file: str 567 """ 568 569 # Test if the current data pipe exists. 570 pipes.test() 571 572 # The file root. 573 id = file_root(file) 574 575 # Read in the vector distribution PDB file. 576 pymol_obj.exec_cmd("load " + file) 577 578 579 # Create a surface. 580 ################### 581 582 # Select the vector distribution. 583 pymol_obj.exec_cmd("cmd.show('surface', " + repr(id) + ")")
584 585
586 -def view():
587 """Start PyMOL.""" 588 589 # Open PyMOL. 590 if pymol_obj.running(): 591 raise RelaxError("PyMOL is already running.") 592 else: 593 pymol_obj.open_gui()
594