<commit_before>import argparse
import logging
import os
import sys
import warnings

import numpy as np

from intermol.gromacs import gromacs_driver
from intermol.lammps import lammps_driver
from intermol.desmond import desmond_driver
from intermol.amber import amber_driver
import intermol.tests
from intermol.tests.testing_tools import which


# Make a global logging object.
logger = logging.getLogger('InterMolLog')
logger.setLevel(logging.DEBUG)
logging.captureWarnings(True)
warning_logger = logging.getLogger('py.warnings')

def record_exception(runtype, logger, e_out, e_outfile, e):
    output_status[runtype] = e
    logger.exception(e)
    e_out.append(-1)
    e_outfile.append(-1)

def parse_args(args):
    parser = argparse.ArgumentParser(description='Perform a file conversion')

    # Input arguments.
    group_in = parser.add_argument_group('Choose input conversion format')
    group_in.add_argument('--des_in', metavar='file',
            help='.cms file for conversion from DESMOND file format')
    group_in.add_argument('--gro_in', nargs=2, metavar='file',
            help='.gro and .top file for conversion from GROMACS file format')
    group_in.add_argument('--lmp_in', metavar='file',
            help='input file for conversion from LAMMPS file format (expects'
                 ' data file in same directory and a read_data call)')
    group_in.add_argument('--amb_in', nargs=2, metavar='file',
            help='input files (.prmtop) and (.crd or equivalent) for conversion from AMBER file format')

    # Output arguments.
    group_out = parser.add_argument_group('Choose output conversion format(s)')
    group_out.add_argument('--desmond', action='store_true',
            help='convert to DESMOND')
    group_out.add_argument('--gromacs', action='store_true',
            help='convert to GROMACS')
    group_out.add_argument('--lammps', action='store_true',
            help='convert to LAMMPS')
    group_out.add_argument('--amber', action='store_true',
            help='convert to AMBER')

    # Other options.
    group_misc = parser.add_argument_group('Other optional arguments')
    group_misc.add_argument('--odir', metavar='directory', default='.',
            help='specification of output directory (default: ./)')
    group_misc.add_argument('--oname', metavar='prefix', default='',
            help='specification of prefix for output filenames '
                 '(default: inputprefix_converted)')

    group_misc.add_argument('-e', '--energy', dest='energy', action='store_true',
            help='evaluate energy of input and output files for comparison')
    group_misc.add_argument('--inefile', default='',
            help='optional run file for input energy evaluation (e.g. .cfg, .mdp, .input)')

    # desmond settings 
    group_misc.add_argument('-dp', '--despath', dest='des_path',
            metavar='path', default='',
            help='path for DESMOND binary, needed for energy evaluation')
    group_misc.add_argument('-ds', '--desmondsettings', dest='desset',
            metavar='settings', default='',
            help='Desmond .cfg settings file used for energy evaluation')

    # gromacs settings
    group_misc.add_argument('-gp', '--gropath', dest='gro_path',
            metavar='path', default='',
            help='path for GROMACS binary, needed for energy evaluation')
    group_misc.add_argument('-gs', '--gromacssettings', dest='gro_set',
            metavar='settings', default='',
            help='Gromacs .mdp settings file used for energy evaluation')

    # lammps settings
    group_misc.add_argument('-lp', '--lmppath', dest='lmp_path',
            metavar='path', default='',
            help='path for LAMMPS binary, needed for energy evaluation')
    group_misc.add_argument('-ls', '--lammpssettings', dest='lmpset',
            metavar='settings', default='',
            help='LAMMPS .input settings file used for energy evaluation. This is simply the pair_style and long range coulomb type to use')

    # amber settings
    group_misc.add_argument('-ap', '--amberpath', dest='amberpath',
            metavar='path', default='',
            help='path for AMBER binary, needed for energy evaluation')
    group_misc.add_argument('-as', '--ambersettings', dest='ambset',
            metavar='settings', default='',
            help='Amber .in settings file used for energy evaluation')

    group_misc.add_argument('-f', '--force', dest='force', action='store_true',
            help='ignore warnings (NOTE: may lead to partially correct topologies)')
    group_misc.add_argument('-v', '--verbose', dest='verbose', action='store_true',
            help='high verbosity, includes DEBUG level output')

    # Prints help if no arguments given.
    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit(1)
    return parser.parse_args(args)

def main(args=None):
    logger.info('Beginning InterMol conversion')
    if not args:
        args = vars(parse_args(args))

    if args.get('verbose'):
        h.setLevel(logging.DEBUG)
    # Print warnings.
    warnings.simplefilter("always")
    if not args.get('force'):
        # Warnings will be treated as exceptions unless force flag is used.
        warnings.simplefilter("error")

    # Paths to simulator executables.
    # GROMACS
    gro_path = args.get('gro_path')
    if not gro_path:
        gro_path = ''
    # LAMMPS
    lpm_path = args.get('lpm_path')
    if not lpm_path:
        for exe in ['lmp_mpi', 'lmp_serial', 'lmp_openmpi']:
            if which(exe):
                lpm_path = exe
                break
        else:
            logger.exception('Found no LAMMPS executable.')
    # DESMOND
    des_path = args.get('des_path')

    #AMBERPATH
    amberpath = args.get('amberpath')

    # --------------- PROCESS INPUTS ----------------- #
    if args.get('gro_in'):
        gromacs_files = args['gro_in']

        prefix = os.path.splitext(os.path.basename(gromacs_files[0]))[0]
        # Find the top file since order of inputs is not enforced.
        top_in = [x for x in gromacs_files if x.endswith('.top')]
        assert(len(top_in) == 1)
        top_in = os.path.abspath(top_in[0])

        # Find the gro file since order of inputs is not enforced.
        gro_in = [x for x in gromacs_files if x.endswith('.gro')]
        assert(len(gro_in) == 1)
        gro_in = os.path.abspath(gro_in[0])
        system = gromacs_driver.read_file(top_in, gro_in, gro_path)

    elif args.get('des_in'):
        cms_file = args['des_in']
        prefix = os.path.splitext(os.path.basename(cms_file))[0]
        system = desmond_driver.read_file(cms_file=cms_file)

    elif args.get('lmp_in'):
        lammps_file = args['lmp_in']
        prefix = os.path.splitext(os.path.basename(lammps_file))[0]
        system = lammps_driver.read_file(in_file=lammps_file)

    elif args.get('amb_in'):
        amber_files = args['amb_in']
        prefix = os.path.splitext(os.path.basename(amber_files[0]))[0]

        # Find the prmtop file since order of inputs is not enforced.
        prmtop_in = [x for x in amber_files if x.endswith('.prmtop')]
        assert(len(prmtop_in) == 1)
        prmtop_in = os.path.abspath(prmtop_in[0])

        # Find the crd file since order of inputs is not enforced.
        crd_in = [x for x in amber_files if (x.endswith('.rst7') or x.endswith('.crd') or x.endswith('.rst') or x.endswith('.inpcrd'))]
        assert(len(crd_in) == 1)
        crd_in = os.path.abspath(crd_in[0])

        # next, convert to gromacs with ParmEd
        try:
            import parmed
        except Exception as e:
            record_exception('amber',logger, e_out, e_outfile, e)

        structure = parmed.amber.AmberParm(prmtop_in,crd_in)
        #Make GROMACS topology
        parmed_system = parmed.gromacs.GromacsTopologyFile.from_structure(structure)
        # write out the files
        fromamber_top_in = prefix + '_from_amber.top'
        fromamber_gro_in = prefix + '_from_amber.gro'
        parmed.gromacs.GromacsTopologyFile.write(parmed_system, fromamber_top_in)
        parmed.gromacs.GromacsGroFile.write(parmed_system, fromamber_gro_in, precision = 8)

        # now, read in using gromacs
        system = gromacs_driver.read_file(fromamber_top_in, fromamber_gro_in, gro_path)
    else:
        logger.error('No input file')
        sys.exit(1)

    # --------------- WRITE OUTPUTS ----------------- #
    if not args.get('oname'):
        oname = '{0}_converted'.format(prefix)
    else:
        oname = args['oname']
    oname = os.path.abspath(os.path.join(args['odir'], oname))  # Prepend output directory to oname.

    output_status = dict()
    # TODO: factor out exception handling
    if args.get('gromacs'):
        try:
            gromacs_driver.write_file(system, '{0}.top'.format(oname), '{0}.gro'.format(oname))
        except Exception as e:<commit_msg>Fix for writing out the intermediate gromacs files.<commit_after>import argparse
import logging
import os
import sys
import warnings

import numpy as np

from intermol.gromacs import gromacs_driver
from intermol.lammps import lammps_driver
from intermol.desmond import desmond_driver
from intermol.amber import amber_driver
import intermol.tests
from intermol.tests.testing_tools import which


# Make a global logging object.
logger = logging.getLogger('InterMolLog')
logger.setLevel(logging.DEBUG)
logging.captureWarnings(True)
warning_logger = logging.getLogger('py.warnings')

def record_exception(runtype, logger, e_out, e_outfile, e):
    output_status[runtype] = e
    logger.exception(e)
    e_out.append(-1)
    e_outfile.append(-1)

def parse_args(args):
    parser = argparse.ArgumentParser(description='Perform a file conversion')

    # Input arguments.
    group_in = parser.add_argument_group('Choose input conversion format')
    group_in.add_argument('--des_in', metavar='file',
            help='.cms file for conversion from DESMOND file format')
    group_in.add_argument('--gro_in', nargs=2, metavar='file',
            help='.gro and .top file for conversion from GROMACS file format')
    group_in.add_argument('--lmp_in', metavar='file',
            help='input file for conversion from LAMMPS file format (expects'
                 ' data file in same directory and a read_data call)')
    group_in.add_argument('--amb_in', nargs=2, metavar='file',
            help='input files (.prmtop) and (.crd or equivalent) for conversion from AMBER file format')

    # Output arguments.
    group_out = parser.add_argument_group('Choose output conversion format(s)')
    group_out.add_argument('--desmond', action='store_true',
            help='convert to DESMOND')
    group_out.add_argument('--gromacs', action='store_true',
            help='convert to GROMACS')
    group_out.add_argument('--lammps', action='store_true',
            help='convert to LAMMPS')
    group_out.add_argument('--amber', action='store_true',
            help='convert to AMBER')

    # Other options.
    group_misc = parser.add_argument_group('Other optional arguments')
    group_misc.add_argument('--odir', metavar='directory', default='.',
            help='specification of output directory (default: ./)')
    group_misc.add_argument('--oname', metavar='prefix', default='',
            help='specification of prefix for output filenames '
                 '(default: inputprefix_converted)')

    group_misc.add_argument('-e', '--energy', dest='energy', action='store_true',
            help='evaluate energy of input and output files for comparison')
    group_misc.add_argument('--inefile', default='',
            help='optional run file for input energy evaluation (e.g. .cfg, .mdp, .input)')

    # desmond settings 
    group_misc.add_argument('-dp', '--despath', dest='des_path',
            metavar='path', default='',
            help='path for DESMOND binary, needed for energy evaluation')
    group_misc.add_argument('-ds', '--desmondsettings', dest='desset',
            metavar='settings', default='',
            help='Desmond .cfg settings file used for energy evaluation')

    # gromacs settings
    group_misc.add_argument('-gp', '--gropath', dest='gro_path',
            metavar='path', default='',
            help='path for GROMACS binary, needed for energy evaluation')
    group_misc.add_argument('-gs', '--gromacssettings', dest='gro_set',
            metavar='settings', default='',
            help='Gromacs .mdp settings file used for energy evaluation')

    # lammps settings
    group_misc.add_argument('-lp', '--lmppath', dest='lmp_path',
            metavar='path', default='',
            help='path for LAMMPS binary, needed for energy evaluation')
    group_misc.add_argument('-ls', '--lammpssettings', dest='lmpset',
            metavar='settings', default='',
            help='LAMMPS .input settings file used for energy evaluation. This is simply the pair_style and long range coulomb type to use')

    # amber settings
    group_misc.add_argument('-ap', '--amberpath', dest='amberpath',
            metavar='path', default='',
            help='path for AMBER binary, needed for energy evaluation')
    group_misc.add_argument('-as', '--ambersettings', dest='ambset',
            metavar='settings', default='',
            help='Amber .in settings file used for energy evaluation')

    group_misc.add_argument('-f', '--force', dest='force', action='store_true',
            help='ignore warnings (NOTE: may lead to partially correct topologies)')
    group_misc.add_argument('-v', '--verbose', dest='verbose', action='store_true',
            help='high verbosity, includes DEBUG level output')

    # Prints help if no arguments given.
    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit(1)
    return parser.parse_args(args)

def main(args=None):
    logger.info('Beginning InterMol conversion')
    if not args:
        args = vars(parse_args(args))

    if args.get('verbose'):
        h.setLevel(logging.DEBUG)
    # Print warnings.
    warnings.simplefilter("always")
    if not args.get('force'):
        # Warnings will be treated as exceptions unless force flag is used.
        warnings.simplefilter("error")

    # Paths to simulator executables.
    # GROMACS
    gro_path = args.get('gro_path')
    if not gro_path:
        gro_path = ''
    # LAMMPS
    lpm_path = args.get('lpm_path')
    if not lpm_path:
        for exe in ['lmp_mpi', 'lmp_serial', 'lmp_openmpi']:
            if which(exe):
                lpm_path = exe
                break
        else:
            logger.exception('Found no LAMMPS executable.')
    # DESMOND
    des_path = args.get('des_path')

    #AMBERPATH
    amberpath = args.get('amberpath')

    # --------------- PROCESS INPUTS ----------------- #
    if args.get('gro_in'):
        gromacs_files = args['gro_in']

        prefix = os.path.splitext(os.path.basename(gromacs_files[0]))[0]
        # Find the top file since order of inputs is not enforced.
        top_in = [x for x in gromacs_files if x.endswith('.top')]
        assert(len(top_in) == 1)
        top_in = os.path.abspath(top_in[0])

        # Find the gro file since order of inputs is not enforced.
        gro_in = [x for x in gromacs_files if x.endswith('.gro')]
        assert(len(gro_in) == 1)
        gro_in = os.path.abspath(gro_in[0])
        system = gromacs_driver.read_file(top_in, gro_in, gro_path)

    elif args.get('des_in'):
        cms_file = args['des_in']
        prefix = os.path.splitext(os.path.basename(cms_file))[0]
        system = desmond_driver.read_file(cms_file=cms_file)

    elif args.get('lmp_in'):
        lammps_file = args['lmp_in']
        prefix = os.path.splitext(os.path.basename(lammps_file))[0]
        system = lammps_driver.read_file(in_file=lammps_file)

    elif args.get('amb_in'):

        amber_files = args['amb_in']
        prefix = os.path.splitext(os.path.basename(amber_files[0]))[0]

        # Find the prmtop file since order of inputs is not enforced.
        prmtop_in = [x for x in amber_files if x.endswith('.prmtop')]
        assert(len(prmtop_in) == 1)
        prmtop_in = os.path.abspath(prmtop_in[0])

        # Find the crd file since order of inputs is not enforced.
        crd_in = [x for x in amber_files if (x.endswith('.rst7') or x.endswith('.crd') or x.endswith('.rst') or x.endswith('.inpcrd'))]
        assert(len(crd_in) == 1)
        crd_in = os.path.abspath(crd_in[0])

        # next, convert to gromacs with ParmEd
        try:
            import parmed
        except Exception as e:
            record_exception('amber',logger, e_out, e_outfile, e)

        structure = parmed.amber.AmberParm(prmtop_in,crd_in)
        #Make GROMACS topology
        parmed_system = parmed.gromacs.GromacsTopologyFile.from_structure(structure)

        # write out the files.  Should write them out in the proper directory (the one reading in)
        pathprefix = os.path.dirname(prmtop_in)
        fromamber_top_in = os.path.join(pathprefix, prefix + '_from_amber.top')
        fromamber_gro_in = os.path.join(pathprefix,prefix + '_from_amber.gro')
        parmed.gromacs.GromacsTopologyFile.write(parmed_system, fromamber_top_in)
        parmed.gromacs.GromacsGroFile.write(parmed_system, fromamber_gro_in, precision = 8)

        # now, read in using gromacs
        system = gromacs_driver.read_file(fromamber_top_in, fromamber_gro_in, gro_path)
    else:
        logger.error('No input file')
        sys.exit(1)

    # --------------- WRITE OUTPUTS ----------------- #
    if not args.get('oname'):
        oname = '{0}_converted'.format(prefix)
    else:
        oname = args['oname']
    oname = os.path.abspath(os.path.join(args['odir'], oname))  # Prepend output directory to oname.

    output_status = dict()
    # TODO: factor out exception handling
    if args.get('gromacs'):
        try:
            gromacs_driver.write_file(system, '{0}.top'.format(oname), '{0}.gro'.format(oname))
        except Exception as e:
{'fraction_non_alphanumeric': 0.12906639928698752, 'fraction_numerical': 0.002896613190730838, 'mean_word_length': 2.917303076587388, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4183907', 'n_tokens_mistral': 5769, 'n_tokens_neox': 5578, 'n_words': 1341}