1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 """The main module for relax execution."""
26
27
28 import dep_check
29
30
31 import os
32 if 'TERM' in os.environ and os.environ['TERM'] == 'xterm':
33 os.environ['TERM'] = 'linux'
34
35
36 import lib.compat
37
38
39 from argparse import ArgumentParser
40 import numpy
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
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
63 user_functions.initialise()
64
65
66 putenv('PDBVIEWER', 'vmd')
67
68
69 -def start(mode=None, profile_flag=False):
121
122
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
128 profile.Profile.print_stats = print_stats
129 profile.runctx('processor.run()', globals(), locals())
130
131
132
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
141 """The top level class for initialising the program."""
142
143
144 self.pid = getpid()
145
146
147 self.exit_code = 0
148
149
151 """Execute relax.
152
153 This is the application callback method executed by the multi-processor framework.
154 """
155
156
157 lib.warnings.setup()
158
159
160 if self.log_file:
161 io_streams_log(self.log_file)
162
163
164 elif self.tee_file:
165 io_streams_tee(self.tee_file)
166
167
168 if self.mode == 'version':
169 print('relax ' + version.version_full())
170 return
171
172
173 if self.mode == 'info':
174
175 info = Info_box()
176
177
178 print(info.intro_text())
179
180
181 print(info.sys_info())
182
183
184 return
185
186
187 if self.mode == 'prompt' or self.mode == 'script':
188
189 self.interpreter = interpreter.Interpreter()
190 self.interpreter.run(self.script_file)
191
192
193 elif self.mode == 'gui':
194
195 if not dep_check.wx_module:
196 sys.stderr.write("Please install the wx Python module to access the relax GUI.\n\n")
197 return
198
199
200 import gui
201
202
203 status.show_gui = True
204
205
206 app = gui.App(script_file=self.script_file)
207 app.MainLoop()
208
209
210 elif self.mode == 'test suite':
211
212 from test_suite.test_suite_runner import Test_suite_runner
213
214
215 self.interpreter = interpreter.Interpreter(show_script=False, raise_relax_error=True)
216 self.interpreter.on()
217
218
219 runner = Test_suite_runner(self.tests, timing=self.test_timings, io_capture=self.io_capture, list_tests=self.list_tests)
220 self.exit_code = int(not runner.run_all_tests())
221
222
223 elif self.mode == 'system tests':
224
225 from test_suite.test_suite_runner import Test_suite_runner
226
227
228 self.interpreter = interpreter.Interpreter(show_script=False, raise_relax_error=True)
229 self.interpreter.on()
230
231
232 runner = Test_suite_runner(self.tests, timing=self.test_timings, io_capture=self.io_capture, list_tests=self.list_tests)
233 self.exit_code = int(not runner.run_system_tests())
234
235
236 elif self.mode == 'unit tests':
237
238 from test_suite.test_suite_runner import Test_suite_runner
239
240
241 runner = Test_suite_runner(self.tests, timing=self.test_timings, io_capture=self.io_capture, list_tests=self.list_tests)
242 self.exit_code = int(not runner.run_unit_tests())
243
244
245 elif self.mode == 'GUI tests':
246
247 from test_suite.test_suite_runner import Test_suite_runner
248
249
250 runner = Test_suite_runner(self.tests, timing=self.test_timings, io_capture=self.io_capture, list_tests=self.list_tests)
251 self.exit_code = int(not runner.run_gui_tests())
252
253
254 elif self.mode == 'verification tests':
255
256 from test_suite.test_suite_runner import Test_suite_runner
257
258
259 runner = Test_suite_runner(self.tests, timing=self.test_timings, io_capture=self.io_capture, list_tests=self.list_tests)
260 self.exit_code = int(not runner.run_verification_tests())
261
262
263 elif self.mode == 'test':
264 self.test_mode()
265
266
267 elif self.mode == 'licence':
268 self.licence()
269
270
271 else:
272 raise lib.errors.RelaxError("The '%s' mode is unknown." % self.mode)
273
274
276 """Process the command line arguments."""
277
278
279 parser = RelaxParser(description="Molecular dynamics by NMR data analysis.")
280
281
282 group = parser.add_argument_group('UI arguments', description="The arguments for selecting between the different user interfaces (UI) of relax. If none of these arguments are supplied relax will default into prompt mode or, if a script is supplied, into script mode.")
283 group.add_argument('-p', '--prompt', action='store_true', dest='prompt', default=0, help='launch relax in prompt mode after running any optionally supplied scripts')
284 group.add_argument('-g', '--gui', action='store_true', dest='gui', default=0, help='launch the relax graphical user interface (GUI)')
285 group.add_argument('-i', '--info', action='store_true', dest='info', default=0, help='display information about this version of relax')
286 group.add_argument('-v', '--version', action='store_true', dest='version', default=0, help='show the version number and exit')
287 group.add_argument('--licence', action='store_true', dest='licence', default=0, help='display the licence')
288 group.add_argument('--test', action='store_true', dest='test', default=0, help='run relax in test mode')
289
290
291 group = parser.add_argument_group('Multi-processor arguments', description="The arguments allowing relax to run in multi-processor environments.")
292 group.add_argument('-m', '--multi', action='store', type=str, dest='multiprocessor', default='uni', help='set multi processor method to one of \'uni\' or \'mpi4py\'')
293 group.add_argument('-n', '--processors', action='store', type=int, dest='n_processors', default=-1, help='set number of processors (may be ignored)')
294
295
296 group = parser.add_argument_group('IO redirection arguments', description="The arguments for sending relax output into a file.")
297 group.add_argument('-l', '--log', action='store', type=str, dest='log', help='log relax output to the file LOG_FILE', metavar='LOG_FILE')
298 group.add_argument('-t', '--tee', action='store', type=str, dest='tee', help='tee relax output to both stdout and the file LOG_FILE', metavar='LOG_FILE')
299
300
301 group = parser.add_argument_group('Test suite arguments', description="The arguments for activating the relax test suite. A subset of tests can be selected by providing the name of one or more test classes, test modules, or individual tests. The names of the tests are shown if the test fails, errors, when the test timings are active, or when IO capture is disabled.")
302 group.add_argument('-x', '--test-suite', action='store_true', dest='test_suite', default=0, help='execute the full relax test suite')
303 group.add_argument('-s', '--system-tests', action='store_true', dest='system_tests', default=0, help='execute the system/functional tests')
304 group.add_argument('-u', '--unit-tests', action='store_true', dest='unit_tests', default=0, help='execute the unit tests')
305 group.add_argument('--gui-tests', action='store_true', dest='gui_tests', default=0, help='execute the GUI tests')
306 group.add_argument('--verification-tests', action='store_true', dest='verification_tests', default=0, help='execute the software verification tests')
307 group.add_argument('--time', action='store_true', dest='tt', default=0, help='print out the timings of individual tests in the test suite')
308 group.add_argument('--no-capt', '--no-capture', action='store_true', dest='no_capture', default=0, help='disable IO capture in the test suite')
309 group.add_argument('--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')
310 group.add_argument('--list-tests', action='store_true', dest='list_tests', default=0, help='list the selected tests instead of executing them')
311
312
313 group = parser.add_argument_group('Debugging arguments', "The arguments for helping to debug relax.")
314 group.add_argument('-d', '--debug', action='store_true', dest='debug', default=0, help='enable verbose debugging output')
315 group.add_argument('--error-state', action='store_true', dest='error_state', default=0, help='save a pickled state file when a RelaxError occurs')
316 group.add_argument('--traceback', action='store_true', dest='traceback', default=0, help='show stack tracebacks on all RelaxErrors and RelaxWarnings')
317 group.add_argument('-e', '--escalate', action='store_true', dest='escalate', default=0, help='escalate all warnings into errors')
318 group.add_argument('--numpy-raise', action='store_true', dest='numpy_raise', default=0, help='convert numpy warnings into errors')
319
320
321 parser.add_argument('script', nargs='*', help='the script file or one or more test classes or individual tests to run')
322
323
324 args = parser.parse_args()
325
326
327 if args.debug:
328 status.debug = True
329 if args.escalate:
330 lib.warnings.ESCALATE = True
331 if args.traceback:
332 status.traceback = True
333 lib.warnings.TRACEBACK = True
334 if args.numpy_raise:
335 numpy.seterr(all='raise')
336 if args.error_state:
337 lib.errors.SAVE_ERROR_STATE = True
338
339
340 if args.prompt:
341 status.prompt = True
342
343
344 if args.log:
345
346 if args.tee:
347 parser.error("The logging and tee arguments cannot be set simultaneously.")
348
349
350 self.log_file = args.log
351
352
353 if access(self.log_file, F_OK):
354 parser.error("The log file '%s' already exists." % self.log_file)
355 else:
356 self.log_file = None
357
358
359 if args.tee:
360
361 if args.log:
362 parser.error("The tee and logging options cannot be set simultaneously.")
363
364
365 self.tee_file = args.tee
366
367
368 if access(self.tee_file, F_OK):
369 parser.error("The tee file '%s' already exists." % self.tee_file)
370 else:
371 self.tee_file = None
372
373
374 if args.test_suite or args.system_tests or args.unit_tests or args.gui_tests or args.verification_tests:
375
376 self.tests = args.script
377 self.io_capture = not args.no_capture
378 self.list_tests = args.list_tests
379
380
381 self.test_timings = False
382 if args.tt:
383 self.test_timings = True
384
385
386 status.skip_blacklisted_tests = True
387 if args.no_skip:
388 status.skip_blacklisted_tests = False
389
390
391 else:
392
393 if len(args.script) > 1:
394 parser.error("Incorrect number of arguments.")
395
396
397 self.script_file = None
398 if len(args.script) == 1:
399 self.script_file = args.script[0]
400
401
402 if not access(self.script_file, F_OK):
403 parser.error("The script file '%s' does not exist." % self.script_file)
404
405
406 if args.multiprocessor not in ['uni', 'mpi4py']:
407 parser.error("The processor type '%s' is not supported.\n" % args.multiprocessor)
408 self.multiprocessor_type = args.multiprocessor
409 self.n_processors = args.n_processors
410
411
412 if self.multiprocessor_type == 'mpi4py' and not dep_check.mpi4py_module:
413 parser.error(dep_check.mpi4py_message)
414
415
416
417
418
419
420 if args.version:
421 self.mode = 'version'
422
423
424 elif args.info:
425 self.mode = 'info'
426
427
428 elif args.test_suite or args.system_tests or args.unit_tests or args.gui_tests or args.verification_tests:
429
430 if args.test:
431 parser.error("Executing the relax test suite and running relax in test mode are mutually exclusive.")
432 elif args.licence:
433 parser.error("Executing the relax test suite and running relax in licence mode are mutually exclusive.")
434
435
436 if args.test_suite:
437 self.mode = 'test suite'
438 elif args.system_tests:
439 self.mode = 'system tests'
440 elif args.unit_tests:
441 self.mode = 'unit tests'
442 elif args.gui_tests:
443 self.mode = 'GUI tests'
444 elif args.verification_tests:
445 self.mode = 'verification tests'
446
447
448 status.test_mode = True
449
450
451 elif args.test:
452
453 if self.script_file:
454 parser.error("A script should not be supplied in test mode.")
455
456
457 if args.test_suite or args.system_tests or args.unit_tests or args.gui_tests or args.verification_tests:
458 parser.error("The relax test mode and executing the test suite are mutually exclusive.")
459 elif args.licence:
460 parser.error("The relax modes test and licence are mutually exclusive.")
461
462
463 self.mode = 'test'
464
465
466 elif args.licence:
467
468 if self.script_file:
469 parser.error("A script should not be supplied in test mode.")
470
471
472 if args.test_suite or args.system_tests or args.unit_tests or args.gui_tests or args.verification_tests:
473 parser.error("The relax licence mode and executing the test suite are mutually exclusive.")
474 elif args.test:
475 parser.error("The relax modes licence and test are mutually exclusive.")
476
477
478 self.mode = 'licence'
479
480
481 elif args.gui:
482
483 if args.test_suite or args.system_tests or args.unit_tests or args.gui_tests or args.verification_tests:
484 parser.error("The relax GUI mode and testing modes are mutually exclusive.")
485 elif args.licence:
486 parser.error("The relax GUI mode and licence mode are mutually exclusive.")
487
488
489 if not dep_check.wx_module:
490
491 if dep_check.wx_module_message == "No module named 'wx'":
492 parser.error("To use the GUI, the wxPython module must be installed.")
493
494
495 else:
496 parser.error("The wxPython installation is broken:\n%s." % dep_check.wx_module_message)
497
498
499 self.mode = 'gui'
500
501
502 elif self.script_file:
503 self.mode = 'script'
504
505
506 else:
507 self.mode = 'prompt'
508
509
511 """Function for displaying the licence."""
512
513
514 file = open('docs/COPYING')
515 pager(file.read())
516
517
519 """Relax test mode code."""
520
521
522 return
523
524
525
527 """A custom ArgumentParser class."""
528
529 - def error(self, message):
530 """Replace ArgumentParser.error() with a custom function, enabling the use of RelaxErrors.
531
532 @param message: The error message to output.
533 @type message: str
534 """
535
536
537 self.print_usage(sys.stderr)
538
539
540 try:
541 raise lib.errors.RelaxError(message)
542 except lib.errors.AllRelaxErrors:
543 instance = sys.exc_info()[1]
544 sys.stderr.write(instance.__str__())
545
546
547 sys.exit(2)
548
549
550
551 if __name__ == "__main__":
552 start()
553