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

Source Code for Module relax

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