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

Source Code for Module pipe_control.molmol

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2003-2004,2006-2008,2011-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.pipes import check_pipe 
 40  from pipe_control.result_files import add_result_file 
 41  from specific_analyses.api import return_api 
 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 # Get the specific macro. 228 api = return_api() 229 commands = api.molmol_macro(data_type, style, colour_start, colour_end, colour_list) 230 231 # Return the macro commands. 232 return commands
233 234
235 -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):
236 """Execute a Molmol macro. 237 238 @keyword data_type: The data type to map to the structure. 239 @type data_type: str 240 @keyword style: The style of the macro. 241 @type style: str 242 @keyword colour_start_name: The name of the starting colour of the linear gradient. 243 @type colour_start_name: str 244 @keyword colour_start_rgb: The RGB array starting colour of the linear gradient. 245 @type colour_start_rgb: RBG colour array (len 3 with vals from 0 to 1) 246 @keyword colour_end_name: The name of the ending colour of the linear gradient. 247 @type colour_end_name: str 248 @keyword colour_end_rgb: The RGB array ending colour of the linear gradient. 249 @type colour_end_rgb: RBG colour array (len 3 with vals from 0 to 1) 250 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'. 251 @type colour_list: str or None 252 """ 253 254 # Test if the current data pipe exists. 255 check_pipe() 256 257 # Test if sequence data exists. 258 if not exists_mol_res_spin_data(): 259 raise RelaxNoSequenceError 260 261 # Check the arguments. 262 if colour_start_name != None and colour_start_rgb != None: 263 raise RelaxError("The starting colour name and RGB colour array cannot both be supplied.") 264 if colour_end_name != None and colour_end_rgb != None: 265 raise RelaxError("The ending colour name and RGB colour array cannot both be supplied.") 266 267 # Merge the colour args. 268 if colour_start_name != None: 269 colour_start = colour_start_name 270 else: 271 colour_start = colour_start_rgb 272 if colour_end_name != None: 273 colour_end = colour_end_name 274 else: 275 colour_end = colour_end_rgb 276 277 # Create the macro. 278 commands = create_macro(data_type=data_type, style=style, colour_start=colour_start, colour_end=colour_end, colour_list=colour_list) 279 280 # Loop over the commands and execute them. 281 for command in commands: 282 molmol_obj.exec_cmd(command)
283 284
285 -def macro_run(file=None, dir=None):
286 """Execute the Molmol macro from the given text file. 287 288 @keyword file: The name of the macro file to execute. 289 @type file: str 290 @keyword dir: The name of the directory where the macro file is located. 291 @type dir: str 292 """ 293 294 # Open the file for reading. 295 file_path = get_file_path(file, dir) 296 file = open_read_file(file, dir) 297 298 # Loop over the commands and apply them. 299 for command in file.readlines(): 300 molmol_obj.exec_cmd(command)
301 302
303 -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):
304 """Create a Molmol macro. 305 306 @keyword data_type: The data type to map to the structure. 307 @type data_type: str 308 @keyword style: The style of the macro. 309 @type style: str 310 @keyword colour_start_name: The name of the starting colour of the linear gradient. 311 @type colour_start_name: str 312 @keyword colour_start_rgb: The RGB array starting colour of the linear gradient. 313 @type colour_start_rgb: RBG colour array (len 3 with vals from 0 to 1) 314 @keyword colour_end_name: The name of the ending colour of the linear gradient. 315 @type colour_end_name: str 316 @keyword colour_end_rgb: The RGB array ending colour of the linear gradient. 317 @type colour_end_rgb: RBG colour array (len 3 with vals from 0 to 1) 318 @keyword colour_list: The colour list to search for the colour names. Can be either 'molmol' or 'x11'. 319 @type colour_list: str or None 320 @keyword file: The name of the macro file to create. 321 @type file: str 322 @keyword dir: The name of the directory to place the macro file into. 323 @type dir: str 324 @keyword force: Flag which if set to True will cause any pre-existing file to be overwritten. 325 @type force: bool 326 """ 327 328 # Test if the current data pipe exists. 329 check_pipe() 330 331 # Test if sequence data exists. 332 if not exists_mol_res_spin_data(): 333 raise RelaxNoSequenceError 334 335 # Check the arguments. 336 if colour_start_name != None and colour_start_rgb != None: 337 raise RelaxError("The starting colour name and RGB colour array cannot both be supplied.") 338 if colour_end_name != None and colour_end_rgb != None: 339 raise RelaxError("The ending colour name and RGB colour array cannot both be supplied.") 340 341 # Merge the colour args. 342 if colour_start_name != None: 343 colour_start = colour_start_name 344 else: 345 colour_start = colour_start_rgb 346 if colour_end_name != None: 347 colour_end = colour_end_name 348 else: 349 colour_end = colour_end_rgb 350 351 # Create the macro. 352 commands = create_macro(data_type=data_type, style=style, colour_start=colour_start, colour_end=colour_end, colour_list=colour_list) 353 354 # File name. 355 if file == None: 356 file = data_type + '.mac' 357 358 # Open the file for writing. 359 file_path = get_file_path(file, dir) 360 file = open_write_file(file, dir, force) 361 362 # Loop over the commands and write them. 363 for command in commands: 364 file.write(command + "\n") 365 366 # Close the file. 367 file.close() 368 369 # Add the file to the results file list. 370 add_result_file(type='molmol', label='Molmol', file=file_path)
371 372
373 -def ribbon():
374 """Apply the Molmol ribbon style.""" 375 376 # Calculate the protons. 377 molmol_obj.exec_cmd("CalcAtom 'H'") 378 molmol_obj.exec_cmd("CalcAtom 'HN'") 379 380 # Calculate the secondary structure. 381 molmol_obj.exec_cmd("CalcSecondary") 382 383 # Execute the ribbon macro. 384 molmol_obj.exec_cmd("XMacStand ribbon.mac")
385 386
387 -def tensor_pdb(file=None):
388 """Display the diffusion tensor geometric structure. 389 390 @keyword file: The name of the PDB file containing the tensor geometric object. 391 @type file: str 392 """ 393 394 # Test if the current data pipe exists. 395 check_pipe() 396 397 # To overlay the structure with the diffusion tensor, select all and reorient to the PDB frame. 398 molmol_obj.exec_cmd("SelectAtom ''") 399 molmol_obj.exec_cmd("SelectBond ''") 400 molmol_obj.exec_cmd("SelectAngle ''") 401 molmol_obj.exec_cmd("SelectDist ''") 402 molmol_obj.exec_cmd("SelectPrim ''") 403 molmol_obj.exec_cmd("RotateInit") 404 molmol_obj.exec_cmd("MoveInit") 405 406 # Read in the tensor PDB file and force Molmol to recognise the CONECT records (not that it will show the bonds)! 407 molmol_obj.exec_cmd("ReadPdb " + file) 408 file_parts = file.split('.') 409 molmol_obj.exec_cmd("SelectMol '@" + file_parts[0] + "'") 410 molmol_obj.exec_cmd("CalcBond 1 1 1") 411 412 # Apply the 'ball/stick' style to the tensor. 413 molmol_obj.exec_cmd("SelectAtom '0'") 414 molmol_obj.exec_cmd("SelectBond '0'") 415 molmol_obj.exec_cmd("SelectAtom ':TNS'") 416 molmol_obj.exec_cmd("SelectBond ':TNS'") 417 molmol_obj.exec_cmd("XMacStand ball_stick.mac") 418 419 # Touch up. 420 molmol_obj.exec_cmd("RadiusAtom 1") 421 molmol_obj.exec_cmd("SelectAtom ':TNS@C*'") 422 molmol_obj.exec_cmd("RadiusAtom 1.5")
423 424
425 -def view():
426 """Start Molmol.""" 427 428 # Open a Molmol pipe. 429 if molmol_obj.running(): 430 raise RelaxError("The Molmol pipe already exists.") 431 else: 432 molmol_obj.open_gui()
433