Source code for parmed.scripts

from __future__ import print_function, absolute_import, division

[docs]def clapp(): # Load system modules. from argparse import ArgumentParser import datetime import os try: import readline except ImportError: readline = None import signal import sys import warnings # Load custom modules from parmed.exceptions import ParmedError from parmed.tools.logos import Logo from parmed.tools.exceptions import SeriousParmWarning, InterpreterError from parmed.tools.parmed_cmd import ParmedCmd from parmed.tools.actions import Action from parmed.tools.parmlist import ParmList from parmed import __version__ # Set up new excepthook to clean up fatal exception printouts def interrupted(*args, **kwargs): """ Handle interruptions gracefully """ sys.stdout.write('Interrupted\n') sys.exit(1) signal.signal(signal.SIGINT, interrupted) # Define our own custom warning printer def _print_warnings(message, category, filename, lineno, file=None, line=None): """ Override the default showwarning method """ if file is None: file = sys.stderr try: file.write('%s: %s\n' % (category.__name__, message)) except IOError: pass warnings.showwarning = _print_warnings # Set up parser parser = ArgumentParser() parser.add_argument('-v', '--version', action='version', version='%%(prog)s: Version %s' % __version__) group = parser.add_argument_group('Input Files') group.add_argument('-i', '--input', dest='script', default=[], metavar='FILE', help='''Script with ParmEd commands to execute. Default reads from stdin. Can be specified multiple times to process multiple input files.''', action='append') group.add_argument('-p', '--parm', dest='prmtop', default=[], metavar='<prmtop>', action='append', help='''List of topology files to load into ParmEd. Can be specified multiple times to process multiple topologies.''') group.add_argument('-c', '--inpcrd', dest='inpcrd', default=[], metavar='<inpcrd>', action='append', help='''List of inpcrd files to load into ParmEd. They are paired with the topology files in the same order that each set of files is specified on the command-line.''') group = parser.add_argument_group('Output Files') group.add_argument('-O', '--overwrite', dest='overwrite', default=False, help='Allow ParmEd to overwrite existing files.', action='store_true') group.add_argument('-l', '--logfile', dest='logfile', metavar='FILE', default='parmed.log', help='''Log file with every command executed during an interactive ParmEd session. Default is parmed.log''') group = parser.add_argument_group('Interpreter Options', '''These options affect how the ParmEd interpreter behaves in certain cases.''') group.add_argument('--prompt', dest='prompt', default='>', metavar='PROMPT', help='String to use as a command prompt.') group.add_argument('-n', '--no-splash', dest='printlogo', action='store_false', help='Prevent printing the greeting logo.', default=True) group.add_argument('-e', '--enable-interpreter', dest='interpreter', action='store_true', default=False, help='''Allow arbitrary single Python commands or blocks of Python code to be run. By default Python commands will not be run as a safeguard for your system. Make sure you trust the source of the ParmEd command before turning this option on.''') group = parser.add_argument_group('Error Handling', '''These options control how ParmEd handles various errors and warnings that appear occur during the course of Action execution''') group.add_argument('-s', '--strict', dest='strict', action='store_true', default=True, help='''Prevent scripts from running past unrecognized input and actions that end with an error. In interactive mode, actions with unrecognized inputs and failed actions prevent any changes from being made to the topology, but does not quit the interpreter. This is the default behavior.''') group.add_argument('-r', '--relaxed', dest='strict', action='store_false', help='''Scripts ignore unrecognized input and simply skip over failed actions, executing the rest of the script. Unrecognized input in the interactive interpreter emits a non-fatal warning.''') parser.add_argument('prmtop_cl', nargs='?', metavar='<prmtop>', default=None, help='Topology file to analyze.') parser.add_argument('script_cl', nargs='?', metavar='<script>', default=None, help='File with a series of ParmEd commands to execute.') opt = parser.parse_args() # If the user specified a prmtop and script in the 'old' way, append them to the # list constructed via the --parm and -i flags -- they come at the end if opt.script_cl is not None: opt.script.append(opt.script_cl) if opt.prmtop_cl is not None: opt.prmtop.append(opt.prmtop_cl) # Load the splash screen if opt.printlogo: splash = Logo() print(splash) # Set our warning filter if not opt.strict: warnings.filterwarnings('always', category=SeriousParmWarning) # Set our overwrite preferences Action.overwrite = opt.overwrite amber_prmtop = ParmList() for i, parm in enumerate(opt.prmtop): if i < len(opt.inpcrd): amber_prmtop.add_parm(parm) amber_prmtop.parm.load_rst7(opt.inpcrd[i]) print('Loaded Amber topology file %s with coordinates from %s\n' % (parm, opt.inpcrd[i])) else: amber_prmtop.add_parm(parm) print('Loaded Amber topology file %s' % parm) if len(opt.script) > 0: # Read from the list of scripts print(opt.script) # Make sure that all scripts exist, quitting if we are strict and not all # scripts exist. Don't do anything until we know that all scripts exist. for script in opt.script: if not os.path.exists(script): warnings.warn('Script file %s cannot be found.' % script, SeriousParmWarning) # We have already pre-screened the scripts. for script in opt.script: if not os.path.exists(script): continue print('Reading actions from %s\n' % script) parmed_commands = ParmedCmd(amber_prmtop, stdin=open(script, 'r')) parmed_commands.use_rawinput = 0 parmed_commands.interpreter = opt.interpreter parmed_commands.prompt = '' # Loop through all of the commands try: parmed_commands.cmdloop() except InterpreterError as err: sys.exit('%s: %s' % (type(err).__name__, err)) except ParmedError: # This has already been caught and printed. If it was re-raised, # then that means we wanted to exit sys.exit(1) else: close_log_file = False parmed_commands = ParmedCmd(amber_prmtop) parmed_commands.intro = "Reading input from STDIN..." parmed_commands.interpreter = opt.interpreter parmed_commands.prompt = opt.prompt.strip() + ' ' # Set the log file and logging, but only if interactive if os.isatty(sys.stdin.fileno()): if os.path.exists(opt.logfile) and readline is not None: # Load the logfile as a history, and get rid of any timestamps # from the history try: f = open(opt.logfile, 'r') except IOError: pass # Do not have permission or something else: for line in f: if line.startswith('# Log started on'): continue readline.add_history(line.rstrip()) f.close() try: logfile = open(opt.logfile, 'a') except IOError: print("Could not open logfile. Skip logging", file=sys.stderr) close_log_file = False else: now = datetime.datetime.now() logfile.write('# Log started on %02d/%02d/%d [mm/dd/yyyy] at ' '%02d:%02d:%02d\n' % (now.month, now.day, now.year, now.hour, now.minute, now.second)) if len(sys.argv) > 1: logfile.write('# Command line arguments: %s\n' % ' '.join(sys.argv[1:])) if len(amber_prmtop) > 0: logfile.write('# Loaded topologies: %s\n' % ', '.join( name for name in amber_prmtop._parm_names)) parmed_commands.setlog(logfile) close_log_file = True # Loop through all of the commands try: try: parmed_commands.cmdloop() except InterpreterError as err: sys.exit('%s: %s' % (type(err).__name__, err)) except ParmedError: # This has already been caught and printed. If it was re-raised, # then that means we wanted to exit sys.exit(1) finally: if close_log_file: logfile.close() print('Done!')
[docs]def guiapp(): from parmed import load_file from parmed.utils.six.moves import tkinter as tk from parmed.utils.six.moves.tkinter_messagebox import showerror from optparse import OptionParser from os.path import split from parmed.tools.exceptions import ParmError from parmed.tools.gui.guitools import ParmedApp from parmed.tools.gui.guifiletools import file_chooser from parmed.tools.logos import Logo from parmed.tools.actions import Action from parmed.tools.parmlist import ParmList import sys debug = False def excepthook(exc, msg, tb): """ Default exception handler """ import traceback if debug: traceback.print_tb(tb) showerror('Fatal Error', '%s: %s' % (exc.__name__, msg)) sys.exit(1) # Launch the root window root = tk.Tk() root.resizable(True, True) # Replace the default excepthook with mine sys.excepthook = excepthook # See if we were provided a topology file on the command-line parser = OptionParser(usage = '%prog [<prmtop>]') parser.add_option('-d', '--debug', dest='debug', default=False, action='store_true', help='Show detailed tracebacks ' + 'when an error is detected.') opt, args = parser.parse_args() debug = opt.debug # If the user provided a CL argument, that is the prmtop_name. Otherwise, # open up a file choosing dialog box to get the input from the user if len(args) == 0: prmtop_name = file_chooser('Topology') elif len(args) == 1: prmtop_name = args[0] else: sys.stderr.write('Unknown command-line options. Ignoring\n') prmtop_name = file_chooser('Topology') # If we chose no prmtop file, throw an error if not prmtop_name: raise ParmError('No prmtop chosen!') # Load the amber prmtop and check for errors amber_prmtop = ParmList() parm = load_file(prmtop_name) amber_prmtop.add_parm(parm) # Make this overwritable -- the all of the file save boxes will ask the user # for verification before saving over an existing file. There's no need for # the AmberParm security layer. Action.overwrite = True fname = split(prmtop_name)[1] root.title('xParmED: Editing/viewing [%s] Choose an operation' % fname) # Now build the action list on root app = ParmedApp(root, amber_prmtop) app.pack(fill=tk.BOTH, expand=1) root.mainloop() print('Thank you for using xParmEd!\n%s' % Logo())