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

Source Code for Module pipe_control.molmol

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2004-2013 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 Molmol.""" 
 24   
 25  # Dependencies. 
 26  import dep_check 
 27   
 28  # Python module imports. 
 29  from os import F_OK, access, sep 
 30  PIPE, Popen = None, None 
 31  if dep_check.subprocess_module: 
 32      from subprocess import PIPE, Popen 
 33  from time import sleep 
 34   
 35  # relax module imports. 
 36  from lib.errors import RelaxError, RelaxNoSequenceError 
 37  from lib.io import get_file_path, open_read_file, open_write_file, test_binary 
 38  from pipe_control.mol_res_spin import exists_mol_res_spin_data 
 39  from pipe_control import pipes 
 40  from pipe_control.result_files import add_result_file 
 41  from specific_analyses.setup import get_specific_fn 
 42  from status import Status; status = Status() 
 43   
 44   
45 -class Molmol:
46 """The Molmol execution object.""" 47
48 - def __init__(self):
49 """Set up the Molmol execution object.""" 50 51 # Variable for storing the Molmol command history. 52 self.command_history = ""
53 54
55 - def clear_history(self):
56 """Clear the Molmol command history.""" 57 58 self.command_history = ""
59 60
61 - def exec_cmd(self, command=None, store_command=True):
62 """Write to the Molmol pipe. 63 64 This function is also used to execute a user supplied Molmol command. 65 66 67 @param command: The Molmol command to send into the program. 68 @type command: str 69 @param store_command: A flag specifying if the command should be stored in the history 70 variable. 71 @type store_command: bool 72 """ 73 74 # Reopen the pipe if needed. 75 if not self.running(): 76 self.open_gui() 77 78 # Write the command to the pipe. 79 self.molmol.write(command + '\n') 80 81 # Place the command in the command history. 82 if store_command: 83 self.command_history = self.command_history + command + "\n"
84 85
86 - def open_gui(self):
87 """Open a Molmol pipe.""" 88 89 # Test that the Molmol binary exists. 90 test_binary('molmol') 91 92 # Python 2.3 and earlier. 93 if Popen == None: 94 raise RelaxError("The subprocess module is not available in this version of Python.") 95 96 # Open Molmol as a pipe. 97 self.molmol = Popen(['molmol', '-f', '-'], stdin=PIPE).stdin 98 99 # Execute the command history. 100 if len(self.command_history) > 0: 101 self.exec_cmd(self.command_history, store_command=0) 102 return 103 104 # Wait a little while for Molmol to initialise. 105 sleep(2) 106 107 # Test if the PDB file has been loaded. 108 if hasattr(cdp, 'structure'): 109 self.open_pdb() 110 111 # Run InitAll to remove everything from Molmol. 112 else: 113 self.molmol.write("InitAll yes\n")
114 115
116 - def open_pdb(self):
117 """Open the PDB file in Molmol.""" 118 119 # Test if Molmol is running. 120 if not self.running(): 121 return 122 123 # Run InitAll to remove everything from molmol. 124 self.exec_cmd("InitAll yes") 125 126 # Open the PDB files. 127 open_files = [] 128 for model in cdp.structure.structural_data: 129 for mol in model.mol: 130 # The file path as the current directory. 131 file_path = None 132 if access(mol.file_name, F_OK): 133 file_path = mol.file_name 134 135 # The file path using the relative path. 136 if file_path == None and hasattr(mol, 'file_path') and mol.file_path != None: 137 file_path = mol.file_path + sep + mol.file_name 138 if not access(file_path, F_OK): 139 file_path = None 140 141 # The file path using the absolute path. 142 if file_path == None and hasattr(mol, 'file_path_abs') and mol.file_path_abs != None: 143 file_path = mol.file_path_abs + sep + mol.file_name 144 if not access(file_path, F_OK): 145 file_path = None 146 147 # Hmmm, maybe the absolute path no longer exists and we are in a results subdirectory? 148 if file_path == None and hasattr(mol, 'file_path') and mol.file_path != None: 149 file_path = pardir + sep + mol.file_path + sep + mol.file_name 150 if not access(file_path, F_OK): 151 file_path = None 152 153 # Fall back to the current directory. 154 if file_path == None: 155 file_path = mol.file_name 156 157 # Already loaded. 158 if file_path in open_files: 159 continue 160 161 # Open the file in Molmol. 162 self.exec_cmd("ReadPdb " + file_path) 163 164 # Add to the open file list. 165 open_files.append(file_path)
166 167
168 - def running(self):
169 """Test if Molmol is running. 170 171 @return: Whether the Molmol pipe is open or not. 172 @rtype: bool 173 """ 174 175 # Pipe exists. 176 if not hasattr(self, 'molmol'): 177 return False 178 179 # Test if the pipe has been broken. 180 try: 181 self.molmol.write('\n') 182 except IOError: 183 import sys 184 sys.stderr.write("Broken pipe") 185 return False 186 187 # Molmol is running 188 return True
189 190 191 192 # Initialise the Molmol executable object. 193 molmol_obj = Molmol() 194 """Molmol data container instance.""" 195 196 197 198
199 -def command(command):
200 """Function for sending Molmol commands to the program pipe. 201 202 @param command: The command to send into the program. 203 @type command: str 204 """ 205 206 # Pass the command to Molmol. 207 molmol_obj.exec_cmd(command)
208 209
210 -def create_macro(data_type=None, style="classic", colour_start=None, colour_end=None, colour_list=None):
211 """Create an array of Molmol commands. 212 213 @keyword data_type: The data type to map to the structure. 214 @type data_type: str 215 @keyword style: The style of the macro. 216 @type style: str 217 @keyword colour_start: The starting colour of the linear gradient. 218 @type colour_start: str or RBG colour array (len 3 with vals from 0 to 1) 219 @keyword colour_end: The ending colour of the linear gradient. 220 @type colour_end: str or RBG colour array (len 3 with vals from 0 to 1) 221 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'. 222 @type colour_list: str or None 223 @return: The list of Molmol commands. 224 @rtype: list of str 225 """ 226 227 # Specific Molmol macro creation function. 228 macro = get_specific_fn('molmol_macro', cdp.pipe_type) 229 230 # Get the macro. 231 commands = macro(data_type, style, colour_start, colour_end, colour_list) 232 233 # Return the macro commands. 234 return commands
235 236
237 -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):
238 """Execute a Molmol macro. 239 240 @keyword data_type: The data type to map to the structure. 241 @type data_type: str 242 @keyword style: The style of the macro. 243 @type style: str 244 @keyword colour_start_name: The name of the starting colour of the linear gradient. 245 @type colour_start_name: str 246 @keyword colour_start_rgb: The RGB array starting colour of the linear gradient. 247 @type colour_start_rgb: RBG colour array (len 3 with vals from 0 to 1) 248 @keyword colour_end_name: The name of the ending colour of the linear gradient. 249 @type colour_end_name: str 250 @keyword colour_end_rgb: The RGB array ending colour of the linear gradient. 251 @type colour_end_rgb: RBG colour array (len 3 with vals from 0 to 1) 252 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'. 253 @type colour_list: str or None 254 """ 255 256 # Test if the current data pipe exists. 257 pipes.test() 258 259 # Test if sequence data exists. 260 if not exists_mol_res_spin_data(): 261 raise RelaxNoSequenceError 262 263 # Check the arguments. 264 if colour_start_name != None and colour_start_rgb != None: 265 raise RelaxError("The starting colour name and RGB colour array cannot both be supplied.") 266 if colour_end_name != None and colour_end_rgb != None: 267 raise RelaxError("The ending colour name and RGB colour array cannot both be supplied.") 268 269 # Merge the colour args. 270 if colour_start_name != None: 271 colour_start = colour_start_name 272 else: 273 colour_start = colour_start_rgb 274 if colour_end_name != None: 275 colour_end = colour_end_name 276 else: 277 colour_end = colour_end_rgb 278 279 # Create the macro. 280 commands = create_macro(data_type=data_type, style=style, colour_start=colour_start, colour_end=colour_end, colour_list=colour_list) 281 282 # Loop over the commands and execute them. 283 for command in commands: 284 molmol_obj.exec_cmd(command)
285 286
287 -def macro_run(file=None, dir=None):
288 """Execute the Molmol macro from the given text file. 289 290 @keyword file: The name of the macro file to execute. 291 @type file: str 292 @keyword dir: The name of the directory where the macro file is located. 293 @type dir: str 294 """ 295 296 # Open the file for reading. 297 file_path = get_file_path(file, dir) 298 file = open_read_file(file, dir) 299 300 # Loop over the commands and apply them. 301 for command in file.readlines(): 302 molmol_obj.exec_cmd(command)
303 304
305 -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):
306 """Create a Molmol macro. 307 308 @keyword data_type: The data type to map to the structure. 309 @type data_type: str 310 @keyword style: The style of the macro. 311 @type style: str 312 @keyword colour_start_name: The name of the starting colour of the linear gradient. 313 @type colour_start_name: str 314 @keyword colour_start_rgb: The RGB array starting colour of the linear gradient. 315 @type colour_start_rgb: RBG colour array (len 3 with vals from 0 to 1) 316 @keyword colour_end_name: The name of the ending colour of the linear gradient. 317 @type colour_end_name: str 318 @keyword colour_end_rgb: The RGB array ending colour of the linear gradient. 319 @type colour_end_rgb: RBG colour array (len 3 with vals from 0 to 1) 320 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'. 321 @type colour_list: str or None 322 @keyword file: The name of the macro file to create. 323 @type file: str 324 @keyword dir: The name of the directory to place the macro file into. 325 @type dir: str 326 @keyword force: Flag which if set to True will cause any pre-existing file to be overwritten. 327 @type force: bool 328 """ 329 330 # Test if the current data pipe exists. 331 pipes.test() 332 333 # Test if sequence data exists. 334 if not exists_mol_res_spin_data(): 335 raise RelaxNoSequenceError 336 337 # Check the arguments. 338 if colour_start_name != None and colour_start_rgb != None: 339 raise RelaxError("The starting colour name and RGB colour array cannot both be supplied.") 340 if colour_end_name != None and colour_end_rgb != None: 341 raise RelaxError("The ending colour name and RGB colour array cannot both be supplied.") 342 343 # Merge the colour args. 344 if colour_start_name != None: 345 colour_start = colour_start_name 346 else: 347 colour_start = colour_start_rgb 348 if colour_end_name != None: 349 colour_end = colour_end_name 350 else: 351 colour_end = colour_end_rgb 352 353 # Create the macro. 354 commands = create_macro(data_type=data_type, style=style, colour_start=colour_start, colour_end=colour_end, colour_list=colour_list) 355 356 # File name. 357 if file == None: 358 file = data_type + '.mac' 359 360 # Open the file for writing. 361 file_path = get_file_path(file, dir) 362 file = open_write_file(file, dir, force) 363 364 # Loop over the commands and write them. 365 for command in commands: 366 file.write(command + "\n") 367 368 # Close the file. 369 file.close() 370 371 # Add the file to the results file list. 372 add_result_file(type='molmol', label='Molmol', file=file_path)
373 374
375 -def ribbon():
376 """Apply the Molmol ribbon style.""" 377 378 # Calculate the protons. 379 molmol_obj.exec_cmd("CalcAtom 'H'") 380 molmol_obj.exec_cmd("CalcAtom 'HN'") 381 382 # Calculate the secondary structure. 383 molmol_obj.exec_cmd("CalcSecondary") 384 385 # Execute the ribbon macro. 386 molmol_obj.exec_cmd("XMacStand ribbon.mac")
387 388
389 -def tensor_pdb(file=None):
390 """Display the diffusion tensor geometric structure. 391 392 @keyword file: The name of the PDB file containing the tensor geometric object. 393 @type file: str 394 """ 395 396 # Test if the current data pipe exists. 397 pipes.test() 398 399 # To overlay the structure with the diffusion tensor, select all and reorient to the PDB frame. 400 molmol_obj.exec_cmd("SelectAtom ''") 401 molmol_obj.exec_cmd("SelectBond ''") 402 molmol_obj.exec_cmd("SelectAngle ''") 403 molmol_obj.exec_cmd("SelectDist ''") 404 molmol_obj.exec_cmd("SelectPrim ''") 405 molmol_obj.exec_cmd("RotateInit") 406 molmol_obj.exec_cmd("MoveInit") 407 408 # Read in the tensor PDB file and force Molmol to recognise the CONECT records (not that it will show the bonds)! 409 molmol_obj.exec_cmd("ReadPdb " + file) 410 file_parts = file.split('.') 411 molmol_obj.exec_cmd("SelectMol '@" + file_parts[0] + "'") 412 molmol_obj.exec_cmd("CalcBond 1 1 1") 413 414 # Apply the 'ball/stick' style to the tensor. 415 molmol_obj.exec_cmd("SelectAtom '0'") 416 molmol_obj.exec_cmd("SelectBond '0'") 417 molmol_obj.exec_cmd("SelectAtom ':TNS'") 418 molmol_obj.exec_cmd("SelectBond ':TNS'") 419 molmol_obj.exec_cmd("XMacStand ball_stick.mac") 420 421 # Touch up. 422 molmol_obj.exec_cmd("RadiusAtom 1") 423 molmol_obj.exec_cmd("SelectAtom ':TNS@C*'") 424 molmol_obj.exec_cmd("RadiusAtom 1.5")
425 426
427 -def view():
428 """Start Molmol.""" 429 430 # Open a Molmol pipe. 431 if molmol_obj.running(): 432 raise RelaxError("The Molmol pipe already exists.") 433 else: 434 molmol_obj.open_gui()
435