Module relax
[hide private]
[frames] | no frames]

Source Code for Module relax

  1  ############################################################################### 
  2  #                                                                             # 
  3  #                                    relax                                    # 
  4  #                                                                             # 
  5  #               Protein dynamics by NMR relaxation data analysis              # 
  6  #                                                                             # 
  7  #                             by Edward d'Auvergne                            # 
  8  #                                                                             # 
  9  ############################################################################### 
 10  #                                                                             # 
 11  #                                   Licence                                   # 
 12  #                                                                             # 
 13  # relax, a program for relaxation data analysis.                              # 
 14  #                                                                             # 
 15  # Copyright (C) 2001-2012  Edward d'Auvergne                                  # 
 16  # Copyright (C) 2006-2012  the relax development team                         # 
 17  #                                                                             # 
 18  # This program is free software; you can redistribute it and/or modify        # 
 19  # it under the terms of the GNU General Public License as published by        # 
 20  # the Free Software Foundation, either version 3 of the License, or           # 
 21  # (at your option) any later version.                                         # 
 22  #                                                                             # 
 23  # This program is distributed in the hope that it will be useful,             # 
 24  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 25  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 26  # GNU Library General Public License for more details.                        # 
 27  #                                                                             # 
 28  # You should have received a copy of the GNU General Public License           # 
 29  # along with this program; if not, write to the Free Software                 # 
 30  #                                                                             # 
 31  ############################################################################### 
 32   
 33  # Python 2 and 3 work-arounds. 
 34  import compat 
 35   
 36  # Dependency checks. 
 37  import dep_check 
 38   
 39  # Python modules. 
 40  from optparse import Option, OptionParser 
 41  from os import F_OK, access, getpid, putenv 
 42  if dep_check.profile_module: 
 43      import profile 
 44  import pstats 
 45  from pydoc import pager 
 46  from re import match 
 47  import sys 
 48   
 49  # relax modules. 
 50  from info import Info_box 
 51  from multi import Application_callback, load_multiprocessor 
 52  from prompt import interpreter 
 53  import relax_errors 
 54  from relax_io import io_streams_log, io_streams_tee 
 55  import relax_warnings 
 56  from status import Status; status = Status() 
 57  import version 
 58   
 59  # Modify the environmental variables. 
 60  putenv('PDBVIEWER', 'vmd') 
 61   
 62   
63 -def start(mode=None, profile_flag=False):
64 """Execute relax. 65 66 @keyword mode: Force a relax mode, overriding the command line. 67 @type mode: str 68 @keyword profile_flag: Change this flag to True for code profiling. 69 @type profile_flag: bool 70 """ 71 72 # Normal relax operation. 73 relax = Relax() 74 75 # Override normal operation. 76 if mode: 77 # Override the mode. 78 relax.mode = mode 79 80 # Some defaults. 81 relax.script_file = None 82 relax.log_file = None 83 relax.tee_file = None 84 relax.multiprocessor_type = 'uni' 85 relax.n_processors = 1 86 87 # Process the command line arguments. 88 else: 89 relax.arguments() 90 91 # Store some start up info in the status object. 92 status.relax_mode = relax.mode 93 94 # Set up the multi-processor elements. 95 callbacks = Application_callback(master=relax) 96 verbosity = 0 97 if status.debug: 98 verbosity = 1 99 processor = load_multiprocessor(relax.multiprocessor_type, callbacks, processor_size=relax.n_processors, verbosity=verbosity) 100 101 # Place the processor fabric intro string into the info box. 102 info = Info_box() 103 info.multi_processor_string = processor.get_intro_string() 104 105 # Normal relax operation. 106 if not profile_flag: 107 # Execute relax in multi-processor mode (this includes the uni-processor for normal operation). 108 processor.run() 109 110 # relax in profiling mode. 111 else: 112 def print_stats(stats, status=0): 113 pstats.Stats(stats).sort_stats('cumulative', 'name').print_stats()
114 115 # No profile module. 116 if not dep_check.profile_module: 117 sys.stderr.write("The profile module is not available, please install the Python development packages for profiling.\n\n") 118 sys.exit() 119 120 # Run relax in profiling mode. 121 profile.Profile.print_stats = print_stats 122 profile.runctx('processor.run()', globals(), locals()) 123 124 125
126 -class Relax:
127 """The main relax class. 128 129 This contains information about the running state, for example the mode of operation of relax, 130 whether debugging is turned on, etc. 131 """ 132
133 - def __init__(self):
134 """The top level class for initialising the program. 135 136 @keyword mode: Force a relax mode, overriding the command line. 137 @type mode: str 138 """ 139 140 # Get and store the PID of this process. 141 self.pid = getpid()
142 143
144 - def run(self):
145 """Execute relax. 146 147 This is the application callback method executed by the multi-processor framework. 148 """ 149 150 # Set up the warning system. 151 relax_warnings.setup() 152 153 # Show the version number and exit. 154 if self.mode == 'version': 155 print('relax ' + version.version_full()) 156 return 157 158 # Show the relax info and exit. 159 if self.mode == 'info': 160 # Initialise the information box. 161 info = Info_box() 162 163 # Print the program intro. 164 print(info.intro_text()) 165 166 # Print the system info. 167 print(info.sys_info()) 168 169 # Stop execution. 170 return 171 172 # Logging. 173 if self.log_file: 174 io_streams_log(self.log_file) 175 176 # Tee. 177 elif self.tee_file: 178 io_streams_tee(self.tee_file) 179 180 # Run the interpreter for the prompt or script modes. 181 if self.mode == 'prompt' or self.mode == 'script': 182 # Run the interpreter. 183 self.interpreter = interpreter.Interpreter() 184 self.interpreter.run(self.script_file) 185 186 # Execute the relax GUI. 187 elif self.mode == 'gui': 188 # Dependency check. 189 if not dep_check.wx_module: 190 sys.stderr.write("Please install the wx Python module to access the relax GUI.\n\n") 191 return 192 193 # Only import the module in this mode (to improve program start up speeds). 194 import gui 195 196 # Set the GUI flag in the status object. 197 status.show_gui = True 198 199 # Start the relax GUI wx application. 200 app = gui.App(script_file=self.script_file) 201 app.MainLoop() 202 203 # Execute the relax test suite 204 elif self.mode == 'test suite': 205 # Only import the module in the test modes (to improve program start up speeds). 206 from test_suite.test_suite_runner import Test_suite_runner 207 208 # Load the interpreter and turn intros on. 209 self.interpreter = interpreter.Interpreter(show_script=False, quit=False, raise_relax_error=True) 210 self.interpreter.on() 211 212 # Run the tests. 213 runner = Test_suite_runner(self.tests) 214 runner.run_all_tests() 215 216 # Execute the relax system tests. 217 elif self.mode == 'system tests': 218 # Only import the module in the test modes (to improve program start up speeds). 219 from test_suite.test_suite_runner import Test_suite_runner 220 221 # Load the interpreter and turn intros on. 222 self.interpreter = interpreter.Interpreter(show_script=False, quit=False, raise_relax_error=True) 223 self.interpreter.on() 224 225 # Run the tests. 226 runner = Test_suite_runner(self.tests) 227 runner.run_system_tests() 228 229 # Execute the relax unit tests. 230 elif self.mode == 'unit tests': 231 # Only import the module in the test modes (to improve program start up speeds). 232 from test_suite.test_suite_runner import Test_suite_runner 233 234 # Run the tests. 235 runner = Test_suite_runner(self.tests) 236 runner.run_unit_tests() 237 238 # Execute the relax GUI tests. 239 elif self.mode == 'GUI tests': 240 # Only import the module in the test modes (to improve program start up speeds). 241 from test_suite.test_suite_runner import Test_suite_runner 242 243 # Run the tests. 244 runner = Test_suite_runner(self.tests) 245 runner.run_gui_tests() 246 247 # Test mode. 248 elif self.mode == 'test': 249 self.test_mode() 250 251 # Licence mode. 252 elif self.mode == 'licence': 253 self.licence() 254 255 # Unknown mode. 256 else: 257 raise relax_errors.RelaxError("The '%s' mode is unknown." % self.mode)
258 259
260 - def arguments(self):
261 """Process the command line arguments.""" 262 263 # Parser object. 264 parser = RelaxParser(self, usage="usage: %prog [options] [script_file]") 265 266 # Recognised command line options. 267 parser.add_option('-d', '--debug', action='store_true', dest='debug', default=0, help='enable debugging output') 268 parser.add_option('-l', '--log', action='store', type='string', dest='log', help='log relax output to the file LOG_FILE', metavar='LOG_FILE') 269 parser.add_option('--licence', action='store_true', dest='licence', default=0, help='display the licence') 270 parser.add_option('-t', '--tee', action='store', type='string', dest='tee', help='tee relax output to stdout and the file LOG_FILE', metavar='LOG_FILE') 271 parser.add_option('-g', '--gui', action='store_true', dest='gui', default=0, help='launch the relax GUI') 272 parser.add_option('-p', '--pedantic', action='store_true', dest='pedantic', default=0, help='escalate all warnings to errors') 273 parser.add_option('--test', action='store_true', dest='test', default=0, help='run relax in test mode') 274 parser.add_option('-x', '--test-suite', action='store_true', dest='test_suite', default=0, help='execute the relax test suite') 275 parser.add_option('-s', '--system-tests', action='store_true', dest='system_tests', default=0, help='execute the relax system/functional tests (part of the test suite)') 276 parser.add_option('-u', '--unit-tests', action='store_true', dest='unit_tests', default=0, help='execute the relax unit tests (part of the test suite)') 277 parser.add_option('--gui-tests', action='store_true', dest='gui_tests', default=0, help='execute the relax GUI tests (part of the test suite)') 278 parser.add_option('-i', '--info', action='store_true', dest='info', default=0, help='display information about this version of relax') 279 parser.add_option('-v', '--version', action='store_true', dest='version', default=0, help='show the version number and exit') 280 parser.add_option('-m', '--multi', action='store', type='string', dest='multiprocessor', default='uni', help='set multi processor method') 281 parser.add_option('-n', '--processors', action='store', type='int', dest='n_processors', default=-1, help='set number of processors (may be ignored)') 282 283 # Parse the options. 284 (options, args) = parser.parse_args() 285 286 # Debugging flag. 287 if options.debug: 288 status.debug = True 289 290 # Pedantic flag. 291 if options.pedantic: 292 status.pedantic = True 293 294 # Logging. 295 if options.log: 296 # Exclusive modes. 297 if options.tee: 298 parser.error("the logging and tee options cannot be set simultaneously") 299 300 # The log file. 301 self.log_file = options.log 302 303 # Fail if the file already exists. 304 if access(self.log_file, F_OK): 305 parser.error("the log file " + repr(self.log_file) + " already exists") 306 else: 307 self.log_file = None 308 309 # Tee. 310 if options.tee: 311 # Exclusive modes. 312 if options.log: 313 parser.error("the tee and logging options cannot be set simultaneously") 314 315 # The tee file. 316 self.tee_file = options.tee 317 318 # Fail if the file already exists. 319 if access(self.tee_file, F_OK): 320 parser.error("the tee file " + repr(self.tee_file) + " already exists") 321 else: 322 self.tee_file = None 323 324 # Test suite mode, therefore the args are the tests to run and not a script file. 325 if options.test_suite or options.system_tests or options.unit_tests or options.gui_tests: 326 self.tests = args 327 328 # The argument is a script. 329 else: 330 # Number of positional arguments should only be 0 or 1. 1 should be the script file. 331 if len(args) > 1: 332 parser.error("incorrect number of arguments") 333 334 # Script file. 335 self.script_file = None 336 if len(args) == 1: 337 self.script_file = args[0] 338 339 # Test if the script file exists. 340 if not access(self.script_file, F_OK): 341 parser.error("the script file " + repr(self.script_file) + " does not exist") 342 343 # Set the multi-processor type and number. 344 self.multiprocessor_type = options.multiprocessor 345 self.n_processors = options.n_processors 346 347 # Checks for the multiprocessor mode. 348 if self.multiprocessor_type == 'mpi4py' and not dep_check.mpi4py_module: 349 parser.error(dep_check.mpi4py_message) 350 351 352 # Determine the relax mode and test for mutually exclusive modes. 353 ################################################################# 354 355 # Show the version number. 356 if options.version: 357 self.mode = 'version' 358 359 # Show the info about this relax version. 360 elif options.info: 361 self.mode = 'info' 362 363 # Run the relax tests. 364 elif options.test_suite or options.system_tests or options.unit_tests or options.gui_tests: 365 # Exclusive modes. 366 if options.test: 367 parser.error("executing the relax test suite and running relax in test mode are mutually exclusive") 368 elif options.licence: 369 parser.error("executing the relax test suite and running relax in licence mode are mutually exclusive") 370 371 # Set the mode. 372 if options.test_suite: 373 self.mode = 'test suite' 374 elif options.system_tests: 375 self.mode = 'system tests' 376 elif options.unit_tests: 377 self.mode = 'unit tests' 378 elif options.gui_tests: 379 self.mode = 'GUI tests' 380 381 # Set the status flag. 382 status.test_mode = True 383 384 # Test mode. 385 elif options.test: 386 # Make sure no script is supplied. 387 if self.script_file: 388 parser.error("a script should not be supplied in test mode") 389 390 # Exclusive modes. 391 if options.test_suite or options.system_tests or options.unit_tests or options.gui_tests: 392 parser.error("the relax test mode and executing the test suite are mutually exclusive") 393 elif options.licence: 394 parser.error("the relax modes test and licence are mutually exclusive") 395 396 # Set the mode. 397 self.mode = 'test' 398 399 # Licence mode. 400 elif options.licence: 401 # Make sure no script is supplied. 402 if self.script_file: 403 parser.error("a script should not be supplied in test mode") 404 405 # Exclusive modes. 406 if options.test_suite or options.system_tests or options.unit_tests or options.gui_tests: 407 parser.error("the relax licence mode and executing the test suite are mutually exclusive") 408 elif options.test: 409 parser.error("the relax modes licence and test are mutually exclusive") 410 411 # Set the mode. 412 self.mode = 'licence' 413 414 # GUI. 415 elif options.gui: 416 # Exclusive models. 417 if options.test_suite or options.system_tests or options.unit_tests or options.gui_tests: 418 parser.error("the relax GUI mode and testing modes are mutually exclusive") 419 elif options.licence: 420 parser.error("the relax GUI mode and licence mode are mutually exclusive") 421 422 # Missing wx module. 423 if not dep_check.wx_module: 424 parser.error("To use the GUI, the wx python module must be installed.") 425 426 # Set the mode. 427 self.mode = 'gui' 428 429 # Script mode. 430 elif self.script_file: 431 self.mode = 'script' 432 433 # Prompt mode (default). 434 else: 435 self.mode = 'prompt'
436 437
438 - def licence(self):
439 """Function for displaying the licence.""" 440 441 # Present the GPL using paging. 442 file = open('docs/COPYING') 443 pager(file.read())
444 445
446 - def test_mode(self):
447 """Relax test mode code.""" 448 449 # Don't actually do anything. 450 return
451 452 453
454 -class RelaxParser(OptionParser):
455 - def __init__(self, relax, usage=None, option_list=None, option_class=Option, version=None, conflict_handler="error", description=None, formatter=None, add_help_option=1, prog=None):
456 """Subclassed OptionParser class with a replacement error function.""" 457 458 # Relax base class. 459 self.relax = relax 460 461 # Run the __init__ method of the OptionParser class. 462 OptionParser.__init__(self, usage, option_list, option_class, version, conflict_handler, description, formatter, add_help_option, prog)
463 464
465 - def error(self, message):
466 """Replacement error function.""" 467 468 # Usage message. 469 self.print_usage(sys.stderr) 470 471 # Raise a clean error. 472 try: 473 raise relax_errors.RelaxError(message) 474 except relax_errors.AllRelaxErrors: 475 instance = sys.exc_info()[1] 476 sys.stderr.write(instance.__str__()) 477 478 # Exit. 479 sys.exit()
480 481 482 # Start relax if this file is passed to Python. 483 if __name__ == "__main__": 484 start() 485