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

Source Code for Module pipe_control.pymol_control

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2006-2014 Edward d'Auvergne                                   # 
  4  #                                                                             # 
  5  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  6  #                                                                             # 
  7  # This program 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 3 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 19  #                                                                             # 
 20  ############################################################################### 
 21   
 22  # Module docstring. 
 23  """Module for interfacing with PyMOL.""" 
 24   
 25  # Dependency check module. 
 26  import dep_check 
 27   
 28  # Python module imports. 
 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  # relax module imports. 
 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   
50 -class Pymol:
51 """The PyMOL execution object.""" 52
53 - def __init__(self, exec_mode=None):
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 # Variable for storing the pymol command history. 61 self.command_history = "" 62 63 # The pymol mode of operation. 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 # Reopen the GUI if needed. 90 if not self.running(): 91 self.open_gui() 92 93 # Execute the command. 94 if self.exec_mode == 'module': 95 pymol.cmd.do(command) 96 else: 97 self.pymol.write(command + '\n') 98 99 # Place the command in the command history. 100 if store_command: 101 self.command_history = self.command_history + command + "\n"
102 103
104 - def open_gui(self):
105 """Open the PyMOL GUI.""" 106 107 # Use the PyMOL python modules. 108 if self.exec_mode == 'module': 109 # Open the GUI. 110 pymol.finish_launching() 111 self.open = True 112 113 # Otherwise execute PyMOL on the command line. 114 if self.exec_mode == 'external': 115 # Test that the PyMOL binary exists. 116 test_binary('pymol') 117 118 # Python 2.3 and earlier. 119 if Popen == None: 120 raise RelaxError("The subprocess module is not available in this version of Python.") 121 122 # Open PyMOL as a pipe. 123 self.pymol = Popen(['pymol', '-qpK'], stdin=PIPE).stdin 124 125 # Execute the command history. 126 if len(self.command_history) > 0: 127 self.exec_cmd(self.command_history, store_command=0) 128 return 129 130 # Test if the PDB file has been loaded. 131 if hasattr(cdp, 'structure'): 132 self.open_pdb()
133 134
135 - def open_pdb(self):
136 """Open the PDB file in PyMOL.""" 137 138 # Test if PyMOL is running. 139 if not self.running(): 140 return 141 142 # Reinitialise PyMOL. 143 self.exec_cmd("reinitialize") 144 145 # Open the PDB files. 146 open_files = [] 147 for model in cdp.structure.structural_data: 148 for mol in model.mol: 149 # No file path. 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 # The file path as the current directory. 155 file_path = None 156 if access(mol.file_name, F_OK): 157 file_path = mol.file_name 158 159 # The file path using the relative path. 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 # The file path using the absolute path. 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 # Hmmm, maybe the absolute path no longer exists and we are in a results subdirectory? 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 # Fall back to the current directory. 178 if file_path == None: 179 file_path = mol.file_name 180 181 # Already loaded. 182 if file_path in open_files: 183 continue 184 185 # Already loaded. 186 if file_path in open_files: 187 continue 188 189 # Open the file in PyMOL. 190 self.exec_cmd("load " + file_path) 191 192 # Add to the open file list. 193 open_files.append(file_path)
194 195
196 - def running(self):
197 """Test if PyMOL is running. 198 199 @return: Whether the Molmol pipe is open or not. 200 @rtype: bool 201 """ 202 203 # Test if PyMOL module interface is already running. 204 if self.exec_mode == 'module': 205 return self.open 206 207 # Test if command line PyMOL is already running. 208 if self.exec_mode == 'external': 209 # Pipe exists. 210 if not hasattr(self, 'pymol'): 211 return False 212 213 # Test if the pipe has been broken. 214 try: 215 self.pymol.write('\n') 216 except IOError: 217 return False 218 219 # PyMOL is running. 220 return True
221 222 223 224 # Initialise the Pymol executable object. 225 pymol_obj = Pymol('external') 226 """Pymol data container instance.""" 227 228 229
230 -def cartoon():
231 """Apply the PyMOL cartoon style and colour by secondary structure.""" 232 233 # Test if the current data pipe exists. 234 check_pipe() 235 236 # Test for the structure. 237 if not hasattr(cdp, 'structure'): 238 raise RelaxNoPdbError 239 240 # Loop over the PDB files. 241 open_files = [] 242 for model in cdp.structure.structural_data: 243 for mol in model.mol: 244 # Identifier. 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 # Already loaded. 251 if pdb_file in open_files: 252 continue 253 254 # Add to the open file list. 255 open_files.append(pdb_file) 256 257 # Hide everything. 258 pymol_obj.exec_cmd("cmd.hide('everything'," + repr(id) + ")") 259 260 # Show the cartoon style. 261 pymol_obj.exec_cmd("cmd.show('cartoon'," + repr(id) + ")") 262 263 # Colour by secondary structure. 264 pymol_obj.exec_cmd("util.cbss(" + repr(id) + ", 'red', 'yellow', 'green')")
265 266
267 -def command(command):
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 # Pass the command to PyMOL. 275 pymol_obj.exec_cmd(command)
276 277
278 -def cone_pdb(file=None):
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 # Read in the cone PDB file. 286 pymol_obj.exec_cmd("load " + file) 287 288 289 # The cone axes. 290 ################ 291 292 # Select the AVE, AXE, and SIM residues. 293 pymol_obj.exec_cmd("select (resn AVE,AXE,SIM)") 294 295 # Show the vector as a stick. 296 pymol_obj.exec_cmd("show stick, 'sele'") 297 298 # Colour it blue. 299 pymol_obj.exec_cmd("color cyan, 'sele'") 300 301 # Select the atom used for labelling. 302 pymol_obj.exec_cmd("select (resn AVE,AXE,SIM and symbol N)") 303 304 # Hide the atom. 305 pymol_obj.exec_cmd("hide ('sele')") 306 307 # Label using the atom name. 308 pymol_obj.exec_cmd("cmd.label(\"sele\",\"name\")") 309 310 311 # The cone object. 312 ################## 313 314 # Select the CON residue. 315 pymol_obj.exec_cmd("select (resn CON,EDG)") 316 317 # Hide everything. 318 pymol_obj.exec_cmd("hide ('sele')") 319 320 # Show as 'sticks'. 321 pymol_obj.exec_cmd("show sticks, 'sele'") 322 323 # Colour it white. 324 pymol_obj.exec_cmd("color white, 'sele'") 325 326 # Shorten the stick width from 0.25 to 0.15. 327 pymol_obj.exec_cmd("set stick_radius,0.15000") 328 329 # Set a bit of transparency. 330 pymol_obj.exec_cmd("set stick_transparency, 0.3") 331 332 333 # Clean up. 334 ########### 335 336 # Remove the selection. 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 # Get the specific macro. 358 api = return_api() 359 commands = api.pymol_macro(data_type, style, colour_start, colour_end, colour_list) 360 361 # Return the macro commands. 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 # The path. 379 path = '' 380 if dir != None: 381 path = dir + sep 382 383 # Set up the respective objects. 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
392 -def frame_order_ave_pos(file=None):
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 # Read in the PDB file. 400 pymol_obj.exec_cmd("load " + file) 401 402 # The object ID. 403 id = file_root(file)
404 405
406 -def frame_order_distribution(file=None):
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 # Read in the PDB file. 414 pymol_obj.exec_cmd("load " + file)
415 416 417
418 -def frame_order_geometric(file=None):
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 # Read in the PDB file. 426 pymol_obj.exec_cmd("load " + file) 427 428 # The object ID. 429 id = file_root(file) 430 431 432 # Rotor objects. 433 ################ 434 435 # Set up the rotor axis (the residues AX and PRC). 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 # Display the central point. 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 # Set up the propellers. 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 # Test if the current data pipe exists. 477 check_pipe() 478 479 # Test if sequence data exists. 480 if not exists_mol_res_spin_data(): 481 raise RelaxNoSequenceError 482 483 # Check the arguments. 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 # Merge the colour args. 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 # Clear the PyMOL history first. 500 pymol_obj.clear_history() 501 502 # Create the macro. 503 commands = create_macro(data_type=data_type, style=style, colour_start=colour_start, colour_end=colour_end, colour_list=colour_list) 504 505 # Save the commands as a temporary file, execute it, then delete it. 506 try: 507 # Temp file name. 508 tmpfile = "%s.pml" % mktemp() 509 510 # Open the file. 511 file = open(tmpfile, 'w') 512 513 # Loop over the commands and write them. 514 for command in commands: 515 file.write("%s\n" % command) 516 file.close() 517 518 # Execute the macro. 519 pymol_obj.exec_cmd("@%s" % tmpfile) 520 521 # Wait a bit for PyMOL to catch up (it takes time for PyMOL to start and the macro to execute). 522 sleep(3) 523 524 # Delete the temporary file (no matter what). 525 finally: 526 # Delete the file. 527 delete(tmpfile, fail=False)
528 529
530 -def macro_run(file=None, dir=None):
531 """Execute the PyMOL macro from the given text file. 532 533 @keyword file: The name of the macro file to execute. 534 @type file: str 535 @keyword dir: The name of the directory where the macro file is located. 536 @type dir: str 537 """ 538 539 # Open the file for reading. 540 file_path = get_file_path(file, dir) 541 file = open_read_file(file, dir) 542 543 # Loop over the commands and apply them. 544 for command in file.readlines(): 545 pymol_obj.exec_cmd(command)
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 # Test if the current data pipe exists. 574 check_pipe() 575 576 # Test if sequence data exists. 577 if not exists_mol_res_spin_data(): 578 raise RelaxNoSequenceError 579 580 # Check the arguments. 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 # Merge the colour args. 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 # Create the macro. 597 commands = create_macro(data_type=data_type, style=style, colour_start=colour_start, colour_end=colour_end, colour_list=colour_list) 598 599 # File name. 600 if file == None: 601 file = data_type + '.pml' 602 603 # Open the file for writing. 604 file_path = get_file_path(file, dir) 605 file = open_write_file(file, dir, force) 606 607 # Loop over the commands and write them. 608 for command in commands: 609 file.write(command + "\n") 610 611 # Close the file. 612 file.close() 613 614 # Add the file to the results file list. 615 add_result_file(type='pymol', label='PyMOL', file=file_path)
616 617
618 -def tensor_pdb(file=None):
619 """Display the diffusion tensor geometric structure. 620 621 @keyword file: The name of the file containing the diffusion tensor geometric object. 622 @type file: str 623 """ 624 625 # Test if the current data pipe exists. 626 check_pipe() 627 628 # Read in the tensor PDB file. 629 pymol_obj.exec_cmd("load " + file) 630 631 632 # The tensor object. 633 #################### 634 635 # Select the TNS residue. 636 pymol_obj.exec_cmd("select resn TNS") 637 638 # Hide everything. 639 pymol_obj.exec_cmd("hide ('sele')") 640 641 # Show as 'sticks'. 642 pymol_obj.exec_cmd("show sticks, 'sele'") 643 644 645 # Centre of mass. 646 ################# 647 648 # Select the COM residue. 649 pymol_obj.exec_cmd("select resn COM") 650 651 # Show the centre of mass as the dots representation. 652 pymol_obj.exec_cmd("show dots, 'sele'") 653 654 # Colour it blue. 655 pymol_obj.exec_cmd("color blue, 'sele'") 656 657 658 # The diffusion tensor axes. 659 ############################ 660 661 # Select the AXS residue. 662 pymol_obj.exec_cmd("select resn AXS") 663 664 # Hide everything. 665 pymol_obj.exec_cmd("hide ('sele')") 666 667 # Show as 'sticks'. 668 pymol_obj.exec_cmd("show sticks, 'sele'") 669 670 # Colour it cyan. 671 pymol_obj.exec_cmd("color cyan, 'sele'") 672 673 # Select the N atoms of the AXS residue (used to display the axis labels). 674 pymol_obj.exec_cmd("select (resn AXS and elem N)") 675 676 # Label the atoms. 677 pymol_obj.exec_cmd("label 'sele', name") 678 679 680 681 # Monte Carlo simulations. 682 ########################## 683 684 # Select the SIM residue. 685 pymol_obj.exec_cmd("select resn SIM") 686 687 # Colour it. 688 pymol_obj.exec_cmd("colour cyan, 'sele'") 689 690 691 # Clean up. 692 ########### 693 694 # Remove the selection. 695 pymol_obj.exec_cmd("cmd.delete('sele')")
696 697
698 -def vector_dist(file=None):
699 """Display the XH bond vector distribution. 700 701 @keyword file: The vector distribution PDB file. 702 @type file: str 703 """ 704 705 # Test if the current data pipe exists. 706 check_pipe() 707 708 # The file root. 709 id = file_root(file) 710 711 # Read in the vector distribution PDB file. 712 pymol_obj.exec_cmd("load " + file) 713 714 715 # Create a surface. 716 ################### 717 718 # Select the vector distribution. 719 pymol_obj.exec_cmd("cmd.show('surface', " + repr(id) + ")")
720 721
722 -def view():
723 """Start PyMOL.""" 724 725 # Open PyMOL. 726 if pymol_obj.running(): 727 raise RelaxError("PyMOL is already running.") 728 else: 729 pymol_obj.open_gui()
730