Esempio n. 1
0
def test_amber_binary_mixture():
    sustiva_filename = utils.get_data_filename("chemicals/etoh/etoh.mol2")
    etoh_filename = utils.get_data_filename("chemicals/etoh/etoh_renamed.mol2")

    trj0, trj1 = md.load(sustiva_filename), md.load(etoh_filename)

    # Hack to assign unique residue names that are consistent with contents of mol2 files
    trj0.top.residue(0).name = "LIG"
    trj1.top.residue(0).name = "LI2"

    trj_list = [trj0, trj1]

    with utils.enter_temp_directory(
    ):  # Prevents creating tons of GAFF files everywhere.

        box_filename = "./box.pdb"
        box_trj = packmol.pack_box(trj_list, [25, 50])
        box_trj.save(box_filename)

        gaff_mol2_filename0, frcmod_filename0 = amber.run_antechamber(
            "sustiva", sustiva_filename, charge_method=None)
        gaff_mol2_filename1, frcmod_filename1 = amber.run_antechamber(
            "etoh", etoh_filename, charge_method=None)

        mol2_filenames = [gaff_mol2_filename0, gaff_mol2_filename1]
        frcmod_filenames = [frcmod_filename0, frcmod_filename1]

        prmtop_filename = "./out.prmtop"
        inpcrd_filename = "./out.inpcrd"

        tleap_cmd = amber.build_mixture_prmtop(mol2_filenames,
                                               frcmod_filenames, box_filename,
                                               prmtop_filename,
                                               inpcrd_filename)
        print(tleap_cmd)
Esempio n. 2
0
def test_gromacs_merge():
    etoh_filename = utils.get_data_filename("chemicals/etoh/etoh.mol2")
    benzene_filename = utils.get_data_filename("chemicals/benzene/benzene.mol2")

    with utils.enter_temp_directory(): #Prevents creating lots of tleap/antechamber files everywhere
        #Generate frcmod files, mol2 files
        gaff_mol2_filename1, frcmod_filename1 = amber.run_antechamber( "etoh", etoh_filename, charge_method = None)
        gaff_mol2_filename2, frcmod_filename2 = amber.run_antechamber( "benzene", benzene_filename, charge_method = None)

        #Set file names
        prmtop_filename1 = "./out1.prmtop"
        prmtop_filename2 = "./out2.prmtop"
        crd_filename1 = "./out1.inpcrd"
        crd_filename2 = "./out2.inpcrd"
        top_filename1 = "./out1.top"
        top_filename2 = "./out2.top"
        gro_filename1 = "./out1.gro"
        gro_filename2 = "./out2.gro"

        #Generate AMBER files
        amber.run_tleap( 'etoh', gaff_mol2_filename1, frcmod_filename1, prmtop_filename1, crd_filename1 )
        amber.run_tleap( 'benzene', gaff_mol2_filename2, frcmod_filename2, prmtop_filename2, crd_filename2 )

        #Convert to GROMACS
        utils.convert_via_acpype( "etoh", prmtop_filename1, crd_filename1, out_top = top_filename1, out_gro = gro_filename1 ) 
        utils.convert_via_acpype( "benzene", prmtop_filename2, crd_filename2, out_top = top_filename2, out_gro = gro_filename2 )

        #Merge topologies
        gromacs.merge_topologies( [ top_filename1, top_filename2], './combined.top', 'combined', molecule_numbers = [1, 5], molecule_names = ['etoh', 'benzene'] )

        #Test editing of molecule numbers in topology file
        gromacs.change_molecules_section( './combined.top', './edited.top', ['etoh', 'benzene'], [10, 20] )
Esempio n. 3
0
def test_amber_binary_mixture():
    sustiva_filename = utils.get_data_filename("chemicals/etoh/etoh.mol2")
    etoh_filename = utils.get_data_filename("chemicals/etoh/etoh_renamed.mol2")

    trj0, trj1 = md.load(sustiva_filename), md.load(etoh_filename)
    
    # Hack to assign unique residue names that are consistent with contents of mol2 files
    trj0.top.residue(0).name = "LIG"
    trj1.top.residue(0).name = "LI2"
    
    trj_list = [trj0, trj1]
    
    with utils.enter_temp_directory():  # Prevents creating tons of GAFF files everywhere.
        
        box_filename = "./box.pdb"
        box_trj = packmol.pack_box(trj_list, [25, 50])
        box_trj.save(box_filename)
        
        gaff_mol2_filename0, frcmod_filename0 = amber.run_antechamber("sustiva", sustiva_filename, charge_method=None)
        gaff_mol2_filename1, frcmod_filename1 = amber.run_antechamber("etoh", etoh_filename, charge_method=None)
        
        mol2_filenames = [gaff_mol2_filename0, gaff_mol2_filename1]
        frcmod_filenames = [frcmod_filename0, frcmod_filename1]
        
        
        prmtop_filename = "./out.prmtop"
        inpcrd_filename = "./out.inpcrd"

        tleap_cmd = amber.build_mixture_prmtop(mol2_filenames, frcmod_filenames, box_filename, prmtop_filename, inpcrd_filename)
        print(tleap_cmd)
Esempio n. 4
0
def test_gromacs_merge():
    etoh_filename = utils.get_data_filename("chemicals/etoh/etoh.mol2")
    benzene_filename = utils.get_data_filename("chemicals/benzene/benzene.mol2")

    with utils.enter_temp_directory(): #Prevents creating lots of tleap/antechamber files everywhere
        #Generate frcmod files, mol2 files
        gaff_mol2_filename1, frcmod_filename1 = amber.run_antechamber( "etoh", etoh_filename, charge_method = None)
        gaff_mol2_filename2, frcmod_filename2 = amber.run_antechamber( "benzene", benzene_filename, charge_method = None)

        #Set file names
        prmtop_filename1 = "./out1.prmtop"
        prmtop_filename2 = "./out2.prmtop"
        crd_filename1 = "./out1.inpcrd"
        crd_filename2 = "./out2.inpcrd"
        top_filename1 = "./out1.top"
        top_filename2 = "./out2.top"
        gro_filename1 = "./out1.gro"
        gro_filename2 = "./out2.gro"

        #Generate AMBER files
        amber.run_tleap( 'etoh', gaff_mol2_filename1, frcmod_filename1, prmtop_filename1, crd_filename1 )
        amber.run_tleap( 'benzene', gaff_mol2_filename2, frcmod_filename2, prmtop_filename2, crd_filename2 )

        #Convert to GROMACS
        utils.amber_to_gromacs( "etoh", prmtop_filename1, crd_filename1, out_top = top_filename1, out_gro = gro_filename1 )
        utils.amber_to_gromacs( "benzene", prmtop_filename2, crd_filename2, out_top = top_filename2, out_gro = gro_filename2 )

        #Merge topologies
        gromacs.merge_topologies( [ top_filename1, top_filename2], './combined.top', 'combined', molecule_numbers = [1, 5], molecule_names = ['etoh', 'benzene'] )

        #Test editing of molecule numbers in topology file
        gromacs.change_molecules_section( './combined.top', './edited.top', ['etoh', 'benzene'], [10, 20] )
Esempio n. 5
0
def test_acpype_conversion():
    molecule_name = 'sustiva'
    input_filename = utils.get_data_filename("chemicals/sustiva/sustiva.mol2")
    with utils.enter_temp_directory(): # Prevents creating tons of GAFF files everywhere.
        gaff_mol2_filename, frcmod_filename = amber.run_antechamber(molecule_name, input_filename, charge_method=None)
        prmtop, inpcrd = amber.run_tleap(molecule_name, gaff_mol2_filename, frcmod_filename)
        out_top, out_gro = utils.convert_via_acpype( molecule_name, prmtop, inpcrd ) 
Esempio n. 6
0
def test_amber_box():
    etoh_filename = utils.get_data_filename("chemicals/etoh/etoh.mol2")
    trj_list = [md.load(etoh_filename)]

    with utils.enter_temp_directory(
    ):  # Prevents creating tons of GAFF files everywhere.

        box_filename = "./box.pdb"
        box_trj = packmol.pack_box(trj_list, [50])
        box_trj.save(box_filename)

        gaff_mol2_filename1, frcmod_filename1 = amber.run_antechamber(
            "etoh", etoh_filename, charge_method=None)

        mol2_filenames = [gaff_mol2_filename1]
        frcmod_filenames = [frcmod_filename1]

        prmtop_filename = "./out.prmtop"
        inpcrd_filename = "./out.inpcrd"

        tleap_cmd = amber.build_mixture_prmtop(mol2_filenames,
                                               frcmod_filenames, box_filename,
                                               prmtop_filename,
                                               inpcrd_filename)
        print(tleap_cmd)
Esempio n. 7
0
def test_run_antechamber_charges():
    molecule_name = "acetate"
    input_filename = utils.get_data_filename("chemicals/acetate/acetate.mol2")
    with utils.enter_temp_directory(
    ):  # Prevents creating tons of GAFF files everywhere.
        gaff_mol2_filename, frcmod_filename = amber.run_antechamber(
            molecule_name, input_filename, charge_method=None, net_charge=-1)
Esempio n. 8
0
def oemols_to_ffxml(molecules, base_molecule_name="lig"):
    """Generate an OpenMM ffxml object and MDTraj trajectories from multiple OEMols

    Parameters
    ----------
    molecules : list(OEMole)
        Molecules WITH CHARGES.  Each can have multiple conformations.
        WILL GIVE UNDEFINED RESULTS IF NOT CHARGED.
    base_molecule_name : str, optional, default='lig'
        Base name of molecule to use inside parameter files.

    Returns
    -------
    trajectories : list(mdtraj.Trajectory)
        List of MDTraj Trajectories for molecule.  May contain multiple frames
    ffxml : StringIO
        StringIO representation of ffxml file.

    Notes
    -----
    We allow multiple different molecules at once so that they can all be
    included in a single ffxml file, which is currently the only recommended
    way to simulate multiple GAFF molecules in a single simulation.  For most
    applications, you will have just a single molecule:
    e.g. molecules = [my_oemol]
    The resulting ffxml StringIO object can be directly input to OpenMM e.g.
    `forcefield = app.ForceField(ffxml)`

    This will generate a lot of temporary files, so you may want to use
    utils.enter_temp_directory() to avoid clutter.
    """
    all_trajectories = []
    gaff_mol2_filenames = []
    frcmod_filenames = []

    print(os.getcwd())
    for i, molecule in enumerate(molecules):
        trajectories = []
        for j in range(molecule.NumConfs()):
            molecule_name = "%s-%d-%d" % (base_molecule_name, i, j)
            mol2_filename = "./%s.mol2" % molecule_name
            _unused = molecule_to_mol2(molecule, mol2_filename, conformer=j)
            gaff_mol2_filename, frcmod_filename = run_antechamber(
                molecule_name, mol2_filename, charge_method=None
            )  # It's redundant to run antechamber on each frame, fix me later.

            traj = md.load(gaff_mol2_filename)
            trajectories.append(traj)

            if j == 0:  # Only need 1 frame of forcefield files
                gaff_mol2_filenames.append(gaff_mol2_filename)
                frcmod_filenames.append(frcmod_filename)

        # Create a trajectory with all frames of the current molecule
        traj = trajectories[0].join(trajectories[1:])
        all_trajectories.append(traj)

    ffxml = create_ffxml_file(gaff_mol2_filenames, frcmod_filenames, override_mol2_residue_name=base_molecule_name)

    return all_trajectories, ffxml
Esempio n. 9
0
def test_run_antechamber_resname():
    molecule_name = "sustiva"
    input_filename = utils.get_data_filename("chemicals/sustiva/sustiva.mol2")
    with utils.enter_temp_directory():  # Prevents creating tons of GAFF files everywhere.
        gaff_mol2_filename, frcmod_filename = amber.run_antechamber(molecule_name, input_filename, charge_method=None, resname=True)
        with open(gaff_mol2_filename, 'r') as fin:
            fin.readline()
            assert fin.readline().strip() == molecule_name
Esempio n. 10
0
def oemols_to_ffxml(molecules, base_molecule_name="lig"):
    """Generate an OpenMM ffxml object and MDTraj trajectories from multiple OEMols

    Parameters
    ----------
    molecules : list(OEMole)
        Molecules WITH CHARGES.  Each can have multiple conformations.
        WILL GIVE UNDEFINED RESULTS IF NOT CHARGED.
    base_molecule_name : str, optional, default='lig'
        Base name of molecule to use inside parameter files.

    Returns
    -------
    trajectories : list(mdtraj.Trajectory)
        List of MDTraj Trajectories for molecule.  May contain multiple frames
    ffxml : StringIO
        StringIO representation of ffxml file.

    Notes
    -----
    We allow multiple different molecules at once so that they can all be
    included in a single ffxml file, which is currently the only recommended
    way to simulate multiple GAFF molecules in a single simulation.  For most
    applications, you will have just a single molecule:
    e.g. molecules = [my_oemol]
    The resulting ffxml StringIO object can be directly input to OpenMM e.g.
    `forcefield = app.ForceField(ffxml)`

    This will generate a lot of temporary files, so you may want to use
    utils.enter_temp_directory() to avoid clutter.
    """
    all_trajectories = []
    gaff_mol2_filenames = []
    frcmod_filenames = []

    print(os.getcwd())
    for i, molecule in enumerate(molecules):
        trajectories = []
        for j in range(molecule.NumConfs()):
            molecule_name = "%s-%d-%d" % (base_molecule_name, i, j)
            mol2_filename = "./%s.mol2" % molecule_name
            _unused = molecule_to_mol2(molecule, mol2_filename, conformer=j)
            gaff_mol2_filename, frcmod_filename = run_antechamber(molecule_name, mol2_filename, charge_method=None)  # It's redundant to run antechamber on each frame, fix me later.

            traj = md.load(gaff_mol2_filename)
            trajectories.append(traj)

            if j == 0:  # Only need 1 frame of forcefield files
                gaff_mol2_filenames.append(gaff_mol2_filename)
                frcmod_filenames.append(frcmod_filename)

        # Create a trajectory with all frames of the current molecule
        traj = trajectories[0].join(trajectories[1:])
        all_trajectories.append(traj)

    ffxml = create_ffxml_file(gaff_mol2_filenames, frcmod_filenames, override_mol2_residue_name=base_molecule_name)

    return all_trajectories, ffxml
Esempio n. 11
0
def test_amber_water_mixture():
    water_filename = utils.get_data_filename("chemicals/water/water.mol2")
    etoh_filename = utils.get_data_filename("chemicals/etoh/etoh.mol2")
    sustiva_filename = utils.get_data_filename("chemicals/sustiva/sustiva.mol2")

    with utils.enter_temp_directory():  # Prevents creating tons of GAFF files everywhere.
        shutil.copy( water_filename, 'c1.mol2' )
        shutil.copy( etoh_filename, 'c2.mol2' )
        shutil.copy( sustiva_filename, 'c3.mol2')
        water_filename = 'c1.mol2'
        etoh_filename = 'c2.mol2'
        sustiva_filename = 'c3.mol2'
        #Randomize residue names to avoid clashes
        utils.randomize_mol2_residue_names( [ water_filename, etoh_filename, sustiva_filename] )

        trj0, trj1, trj2 = md.load(water_filename), md.load(etoh_filename), md.load(sustiva_filename)

        trj_list = [trj0, trj1, trj2]
        
        box_filename = "./box.pdb"
        box_trj = packmol.pack_box(trj_list, [300, 25, 3])
        box_trj.save(box_filename)
        
        gaff_mol2_filename0, frcmod_filename0 = amber.run_antechamber("water", water_filename, charge_method=None)
        gaff_mol2_filename1, frcmod_filename1 = amber.run_antechamber("etoh", etoh_filename, charge_method=None)
        gaff_mol2_filename2, frcmod_filename2 = amber.run_antechamber("sustiva", sustiva_filename, charge_method=None)
        
        mol2_filenames = [gaff_mol2_filename0, gaff_mol2_filename1, gaff_mol2_filename2]
        frcmod_filenames = [frcmod_filename0, frcmod_filename1, frcmod_filename2]
        
        
        prmtop_filename = "./out.prmtop"
        inpcrd_filename = "./out.inpcrd"

        shutil.copy(box_filename, 'renamed.pdb')
        tleap_cmd = amber.build_mixture_prmtop(mol2_filenames, frcmod_filenames, 'renamed.pdb', prmtop_filename, inpcrd_filename)
        print(tleap_cmd)

        #Also do here for case of GAFF water
        tleap_cmd = amber.build_mixture_prmtop(mol2_filenames, frcmod_filenames, box_filename, prmtop_filename, inpcrd_filename, water_model = None)
        print(tleap_cmd)

        #Also do here for case of SPC
        tleap_cmd = amber.build_mixture_prmtop(mol2_filenames, frcmod_filenames, 'renamed.pdb', prmtop_filename, inpcrd_filename, water_model = 'SPC')
        print(tleap_cmd)
Esempio n. 12
0
def smiles_to_antechamber(smiles_string,
                          gaff_mol2_filename,
                          frcmod_filename,
                          residue_name="MOL",
                          strictStereo=False,
                          protonation=False):
    """Build a molecule from a smiles string and run antechamber,
    generating GAFF mol2 and frcmod files from a smiles string.  Charges
    will be generated using the OpenEye QuacPac AM1-BCC implementation.

    Parameters
    ----------
    smiles_string : str
        Smiles string of molecule to construct and charge
    gaff_mol2_filename : str
        Filename of mol2 file output of antechamber, with charges
        created from openeye
    frcmod_filename : str
        Filename of frcmod file output of antechamber.  Most likely
        this file will be almost empty, at least for typical molecules.
    residue_name : str, optional, default="MOL"
        OpenEye writes mol2 files with <0> as the residue / ligand name.
        This chokes many mol2 parsers, so we replace it with a string of
        your choosing.  This might be useful for downstream applications
        if the residue names are required to be unique.
    strictStereo : bool, optional, default=False
        If False, permits smiles strings with unspecified stereochemistry.
        See https://docs.eyesopen.com/omega/usage.html
    protonation : bool, optional, default=False
        If True, uses OESetNeutralpHModel to set a pH model for the molecule
        to attempt to obtain protonation states appropriate for neutral pH.
        Depending on the application this may or may not be what you want, e.g. for
        hydration free energy calculations you may want the typical depicted (neutral) form.
    """
    oechem = import_("openeye.oechem")
    if not oechem.OEChemIsLicensed():
        raise (ImportError("Need License for oechem!"))
    oequacpac = import_("openeye.oequacpac")

    # Get the absolute path so we can find these filenames from inside a temporary directory.
    gaff_mol2_filename = os.path.abspath(gaff_mol2_filename)
    frcmod_filename = os.path.abspath(frcmod_filename)

    m = smiles_to_oemol(smiles_string)
    if protonation:
        oequacpac.OESetNeutralpHModel(m)
    m = get_charges(m, strictStereo=strictStereo, keep_confs=1)

    with enter_temp_directory(
    ):  # Avoid dumping 50 antechamber files in local directory.
        _unused = molecule_to_mol2(m, "./tmp.mol2", residue_name=residue_name)
        net_charge = oechem.OENetCharge(m)
        tmp_gaff_mol2_filename, tmp_frcmod_filename = run_antechamber(
            "tmp", "./tmp.mol2", charge_method=None,
            net_charge=net_charge)  # USE OE AM1BCC charges!
        shutil.copy(tmp_gaff_mol2_filename, gaff_mol2_filename)
        shutil.copy(tmp_frcmod_filename, frcmod_filename)
Esempio n. 13
0
def test_run_tleap():
    molecule_name = "sustiva"
    input_filename = utils.get_data_filename("chemicals/sustiva/sustiva.mol2")
    with utils.enter_temp_directory(
    ):  # Prevents creating tons of GAFF files everywhere.
        gaff_mol2_filename, frcmod_filename = amber.run_antechamber(
            molecule_name, input_filename, charge_method=None)
        prmtop, inpcrd = amber.run_tleap(molecule_name, gaff_mol2_filename,
                                         frcmod_filename)
Esempio n. 14
0
def test_run_antechamber_resname():
    molecule_name = "sustiva"
    input_filename = utils.get_data_filename("chemicals/sustiva/sustiva.mol2")
    with utils.enter_temp_directory(
    ):  # Prevents creating tons of GAFF files everywhere.
        gaff_mol2_filename, frcmod_filename = amber.run_antechamber(
            molecule_name, input_filename, charge_method=None, resname=True)
        with open(gaff_mol2_filename, 'r') as fin:
            fin.readline()
            assert fin.readline().strip() == molecule_name
Esempio n. 15
0
def test_acpype_conversion():
    molecule_name = 'sustiva'
    input_filename = utils.get_data_filename("chemicals/sustiva/sustiva.mol2")
    with utils.enter_temp_directory(
    ):  # Prevents creating tons of GAFF files everywhere.
        gaff_mol2_filename, frcmod_filename = amber.run_antechamber(
            molecule_name, input_filename, charge_method=None)
        prmtop, inpcrd = amber.run_tleap(molecule_name, gaff_mol2_filename,
                                         frcmod_filename)
        out_top, out_gro = utils.convert_via_acpype(molecule_name, prmtop,
                                                    inpcrd)
Esempio n. 16
0
def test_gromacs_solvate():
    etoh_filename = utils.get_data_filename("chemicals/etoh/etoh.mol2")
    with utils.enter_temp_directory(): #Prevents creating lots of tleap/antechamber files everywhere
        #Generate frcmod files, mol2 files
        gaff_mol2_filename, frcmod_filename = amber.run_antechamber( "etoh", etoh_filename, charge_method = None)

        #Amber setup
        amber.run_tleap( 'etoh', gaff_mol2_filename, frcmod_filename, 'etoh.prmtop', 'etoh.crd' )
        #GROMACS conversion
        utils.convert_via_acpype( 'etoh', 'etoh.prmtop', 'etoh.crd', 'etoh.top', 'etoh.gro' )
        #Solvate
        gromacs.do_solvate( 'etoh.top', 'etoh.gro', 'etoh_solvated.top', 'etoh_solvated.gro', 1.2, 'dodecahedron', 'spc216', 'tip3p.itp' )
Esempio n. 17
0
def test_gromacs_solvate():
    etoh_filename = utils.get_data_filename("chemicals/etoh/etoh.mol2")
    with utils.enter_temp_directory(): #Prevents creating lots of tleap/antechamber files everywhere
        #Generate frcmod files, mol2 files
        gaff_mol2_filename, frcmod_filename = amber.run_antechamber( "etoh", etoh_filename, charge_method = None)

        #Amber setup
        amber.run_tleap( 'etoh', gaff_mol2_filename, frcmod_filename, 'etoh.prmtop', 'etoh.crd' )
        #GROMACS conversion
        utils.amber_to_gromacs( 'etoh', 'etoh.prmtop', 'etoh.crd', 'etoh.top', 'etoh.gro' )
        #Solvate
        gromacs.do_solvate( 'etoh.top', 'etoh.gro', 'etoh_solvated.top', 'etoh_solvated.gro', 1.2, 'dodecahedron', 'spc216', 'tip3p.itp' )
Esempio n. 18
0
def smiles_to_antechamber(smiles_string, gaff_mol2_filename, frcmod_filename, residue_name="MOL", strictStereo=False, protonation=False):
    """Build a molecule from a smiles string and run antechamber,
    generating GAFF mol2 and frcmod files from a smiles string.  Charges
    will be generated using the OpenEye QuacPac AM1-BCC implementation.

    Parameters
    ----------
    smiles_string : str
        Smiles string of molecule to construct and charge
    gaff_mol2_filename : str
        Filename of mol2 file output of antechamber, with charges
        created from openeye
    frcmod_filename : str
        Filename of frcmod file output of antechamber.  Most likely
        this file will be almost empty, at least for typical molecules.
    residue_name : str, optional, default="MOL"
        OpenEye writes mol2 files with <0> as the residue / ligand name.
        This chokes many mol2 parsers, so we replace it with a string of
        your choosing.  This might be useful for downstream applications
        if the residue names are required to be unique.
    strictStereo : bool, optional, default=False
        If False, permits smiles strings with unspecified stereochemistry.
        See https://docs.eyesopen.com/omega/usage.html
    protonation : bool, optional, default=False
        If True, uses OESetNeutralpHModel to set a pH model for the molecule
        to attempt to obtain protonation states appropriate for neutral pH.
        Depending on the application this may or may not be what you want, e.g. for
        hydration free energy calculations you may want the typical depicted (neutral) form.
    """
    oechem = import_("openeye.oechem")
    if not oechem.OEChemIsLicensed(): raise(ImportError("Need License for oechem!"))
    oequacpac = import_("openeye.oequacpac")

    # Get the absolute path so we can find these filenames from inside a temporary directory.
    gaff_mol2_filename = os.path.abspath(gaff_mol2_filename)
    frcmod_filename = os.path.abspath(frcmod_filename)

    m = smiles_to_oemol(smiles_string)
    if protonation:
        oequacpac.OESetNeutralpHModel(m)
    m = get_charges(m, strictStereo=strictStereo, keep_confs=1)

    with enter_temp_directory():  # Avoid dumping 50 antechamber files in local directory.
        _unused = molecule_to_mol2(m, "./tmp.mol2", residue_name=residue_name)
        net_charge = oechem.OENetCharge(m)
        tmp_gaff_mol2_filename, tmp_frcmod_filename = run_antechamber("tmp", "./tmp.mol2", charge_method=None, net_charge=net_charge)  # USE OE AM1BCC charges!
        shutil.copy(tmp_gaff_mol2_filename, gaff_mol2_filename)
        shutil.copy(tmp_frcmod_filename, frcmod_filename)
Esempio n. 19
0
def test_parmed_conversion():
    molecule_name = 'sustiva'
    input_filename = utils.get_data_filename("chemicals/sustiva/sustiva.mol2")
    with utils.enter_temp_directory(
    ):  # Prevents creating tons of GAFF files everywhere.
        #Make sure conversion runs
        gaff_mol2_filename, frcmod_filename = amber.run_antechamber(
            molecule_name, input_filename, charge_method=None)
        prmtop, inpcrd = amber.run_tleap(molecule_name, gaff_mol2_filename,
                                         frcmod_filename)
        out_top, out_gro = utils.amber_to_gromacs(molecule_name,
                                                  prmtop,
                                                  inpcrd,
                                                  precision=8)

        #Test energies before and after conversion
        #Set up amber system
        a = parmed.amber.AmberParm(prmtop, inpcrd)
        ambersys = a.createSystem()
        ambercon = mmmm.Context(ambersys, mm.VerletIntegrator(0.001))
        ambercon.setPositions(a.positions)
        #Set up GROMACS system
        g = parmed.load_file(out_top)
        gro = parmed.gromacs.GromacsGroFile.parse(out_gro)
        g.box = gro.box
        g.positions = gro.positions
        gromacssys = g.createSystem()
        gromacscon = mmmm.Context(gromacssys, mm.VerletIntegrator(0.001))
        gromacscon.setPositions(g.positions)

        #Check energies
        a_energies = parmed.openmm.utils.energy_decomposition(a, ambercon)
        g_energies = parmed.openmm.utils.energy_decomposition(g, gromacscon)
        #Check components
        tolerance = 1e-5
        ok = True
        for key in a_energies.keys():
            diff = np.abs(a_energies[key] - g_energies[key])
            if diff / np.abs(a_energies[key]) > tolerance:
                ok = False
                print(
                    "In testing AMBER to GROMACS conversion, %s energy differs by %.5g, which is more than a fraction %.2g of the total, so conversion appears not to be working properly."
                    % (key, diff, tolerance))
        if not ok:
            raise (ValueError(
                "AMBER to GROMACS conversion yields energies which are too different."
            ))
def oemol_to_antechamber(m, gaff_mol2_filename, frcmod_filename, residue_name="MOL", strictStereo=False):
    """
        Build a molecule from a mol2 file and run antechamber,
        generating GAFF mol2 and frcmod files from a smiles string.  Charges
        will be generated using the OpenEye QuacPac AM1-BCC implementation.
        
        Created by hacking openmoltools/openeye.py
        
        Parameters
        ----------
        m : oechem molecule object
        Molecule to construct and charge
        gaff_mol2_filename : str
        Filename of mol2 file output of antechamber, with charges
        created from openeye
        frcmod_filename : str
        Filename of frcmod file output of antechamber.  Most likely
        this file will be almost empty, at least for typical molecules.
        residue_name : str, optional, default="MOL"
        
        OpenEye writes mol2 files with <0> as the residue / ligand name.
        This chokes many mol2 parsers, so we replace it with a string of
        your choosing.  This might be useful for downstream applications
        if the residue names are required to be unique.
        strictStereo : bool, optional, default=False
        If False, permits smiles strings with unspecified stereochemistry.
        See https://docs.eyesopen.com/omega/usage.html
    """
    #oechem = import_("openeye.oechem")
    #if not oechem.OEChemIsLicensed(): raise(ImportError("Need License for oechem!"))
    
    # Get the absolute path so we can find these filenames from inside a temporary directory.
    gaff_mol2_filename = os.path.abspath(gaff_mol2_filename)
    frcmod_filename = os.path.abspath(frcmod_filename)
    
    m = openeye.get_charges(m, strictStereo=strictStereo, keep_confs=1)
    
    with enter_temp_directory():  # Avoid dumping 50 antechamber files in local directory.
        _unused = openeye.molecule_to_mol2(m, "./tmp.mol2", residue_name=residue_name)
        net_charge = oechem.OENetCharge(m)
        tmp_gaff_mol2_filename, tmp_frcmod_filename = amber.run_antechamber("tmp", "./tmp.mol2", charge_method=None, net_charge=net_charge)  # USE OE AM1BCC charges!
        shutil.copy(tmp_gaff_mol2_filename, gaff_mol2_filename)
        shutil.copy(tmp_frcmod_filename, frcmod_filename)
Esempio n. 21
0
def test_amber_box():
    etoh_filename = utils.get_data_filename("chemicals/etoh/etoh.mol2")
    trj_list = [md.load(etoh_filename)]
    
    with utils.enter_temp_directory():  # Prevents creating tons of GAFF files everywhere.
        
        box_filename = "./box.pdb"
        box_trj = packmol.pack_box(trj_list, [50])
        box_trj.save(box_filename)
    
        gaff_mol2_filename1, frcmod_filename1 = amber.run_antechamber("etoh", etoh_filename, charge_method=None)
        
        mol2_filenames = [gaff_mol2_filename1]
        frcmod_filenames =  [frcmod_filename1]
        
        prmtop_filename = "./out.prmtop"
        inpcrd_filename = "./out.inpcrd"

        tleap_cmd = amber.build_mixture_prmtop(mol2_filenames, frcmod_filenames, box_filename, prmtop_filename, inpcrd_filename)
        print(tleap_cmd)
Esempio n. 22
0
    def generate_amber_files(self, ligand_name, file):
        """
        Generates the prmtop and inpcrd files for a ligand.
        Parameters
        ----------
            ligand_name : str
                The name of the ligand.
            file : str
                Mol2 file of the ligand.
        Returns
        -------
            prmtop_filename : str
                Amber prmtop file produced by tleap.
            inpcrd_filename : str
                Amber inpcrd file produced by tleap.
        """
        gaff_mol2_filename1, frcmod_filename1 = amber.run_antechamber(
            ligand_name, file, resname=True, charge_method=None)
        source_mol2 = os.path.abspath(gaff_mol2_filename1)
        source_frcmod = os.path.abspath(frcmod_filename1)
        destination = os.path.abspath('data')
        shutil.move(source_mol2,
                    os.path.join(destination, os.path.basename(source_mol2)))
        shutil.move(source_frcmod,
                    os.path.join(destination, os.path.basename(source_frcmod)))
        amber.run_tleap(
            ligand_name,
            os.path.join(destination, os.path.basename(source_mol2)),
            os.path.join(destination, os.path.basename(source_frcmod)),
            f'{ligand_name}.prmtop', f'{ligand_name}.inpcrd')
        source_prmtop = os.path.abspath(f'{ligand_name}.prmtop')
        source_inpcrd = os.path.abspath(f'{ligand_name}.inpcrd')
        shutil.move(source_prmtop,
                    os.path.join(destination, os.path.basename(source_prmtop)))
        shutil.move(source_inpcrd,
                    os.path.join(destination, os.path.basename(source_inpcrd)))

        return os.path.join(destination,
                            os.path.basename(source_prmtop)), os.path.join(
                                destination, os.path.basename(source_inpcrd))
Esempio n. 23
0
    def _gaff2xml(*filenames, **kwargs):
        """
        Use OpenMolTools wrapper to run antechamber programatically
        and auto parametrize requested molecules.

        Parameters
        ----------
        filenames: list of str
            List of the filenames of the molecules to parametrize

        Returns
        -------
        ffxmls : StringIO
            Compiled ffxml file produced by antechamber and openmoltools converter
        """
        frcmods, gaffmol2s = [], []
        for filename in filenames:
            name = '.'.join(filename.split('.')[:-1])
            gaffmol2, frcmod = run_antechamber(name, filename, **kwargs)
            frcmods.append(frcmod)
            gaffmol2s.append(gaffmol2)
        return create_ffxml_file(gaffmol2s, frcmods)
Esempio n. 24
0
def test_parmed_conversion():
    molecule_name = 'sustiva'
    input_filename = utils.get_data_filename("chemicals/sustiva/sustiva.mol2")
    with utils.enter_temp_directory(): # Prevents creating tons of GAFF files everywhere.
        #Make sure conversion runs
        gaff_mol2_filename, frcmod_filename = amber.run_antechamber(molecule_name, input_filename, charge_method=None)
        prmtop, inpcrd = amber.run_tleap(molecule_name, gaff_mol2_filename, frcmod_filename)
        out_top, out_gro = utils.amber_to_gromacs( molecule_name, prmtop, inpcrd, precision = 8 ) 

        #Test energies before and after conversion
        #Set up amber system
        a = parmed.amber.AmberParm( prmtop, inpcrd )
        ambersys = a.createSystem()
        ambercon = mmmm.Context( ambersys, mm.VerletIntegrator(0.001))
        ambercon.setPositions( a.positions )
        #Set up GROMACS system
        g = parmed.load_file( out_top )
        gro = parmed.gromacs.GromacsGroFile.parse( out_gro ) 
        g.box = gro.box
        g.positions = gro.positions
        gromacssys = g.createSystem()
        gromacscon = mmmm.Context( gromacssys, mm.VerletIntegrator(0.001))
        gromacscon.setPositions( g.positions ) 

        #Check energies
        a_energies = parmed.openmm.utils.energy_decomposition( a, ambercon )    
        g_energies = parmed.openmm.utils.energy_decomposition( g, gromacscon )
        #Check components
        tolerance = 1e-5
        ok = True
        for key in a_energies.keys():
            diff = np.abs(a_energies[key] - g_energies[key] )
            if diff/np.abs(a_energies[key]) > tolerance:
                ok = False
                print("In testing AMBER to GROMACS conversion, %s energy differs by %.5g, which is more than a fraction %.2g of the total, so conversion appears not to be working properly." % ( key, diff, tolerance) )
        if not ok:
            raise(ValueError("AMBER to GROMACS conversion yields energies which are too different.")) 
def generateResidueTemplate(molecule, residue_atoms=None):
    """
    Generate an residue template for simtk.openmm.app.ForceField using GAFF/AM1-BCC.

    This requires the OpenEye toolkit.

    Parameters
    ----------
    molecule : openeye.oechem.OEMol
        The molecule to be parameterized.
        The molecule must have explicit hydrogens.
        Charge will be inferred from the net formal charge.
    residue_atomset : set of OEAtom, optional, default=None
        If not None, only the atoms in this set will be used to construct the residue template

    Returns
    -------
    template : simtk.openmm.app.forcefield._TemplateData
        Residue template for ForceField using atom types and parameters from `gaff.xml`.
    additional_parameters_ffxml : str
        Contents of ForceField `ffxml` file defining additional parameters from parmchk(2).

    Note that this method preserves stereochemistry during AM1-BCC charge parameterization.

    """
    # Generate a unique residue template name to avoid namespace collisions.
    # TODO: Can we come up with a more intelligent name?
    #from uuid import uuid4
    #template_name = str(uuid4())
    template_name = molecule.GetTitle()

    # Compute net formal charge.
    from openeye import oechem
    oechem.OEAssignFormalCharges(molecule)
    charges = [ atom.GetFormalCharge() for atom in molecule.GetAtoms() ]
    net_charge = np.array(charges).sum()

    # Generate canonical AM1-BCC charges and a reference conformation.
    molecule = get_charges(molecule, strictStereo=False, keep_confs=1)

    # Create temporary directory for running antechamber.
    import tempfile
    tmpdir = tempfile.mkdtemp()
    input_mol2_filename = os.path.join(tmpdir, template_name + '.tripos.mol2')
    gaff_mol2_filename = os.path.join(tmpdir, template_name + '.gaff.mol2')
    frcmod_filename = os.path.join(tmpdir, template_name + '.frcmod')

    # Write Tripos mol2 file as antechamber input.
    ofs = oechem.oemolostream(input_mol2_filename)
    oechem.OEWriteMolecule(ofs, molecule)
    ofs.close()

    # Parameterize the molecule with antechamber.
    run_antechamber(template_name, input_mol2_filename, charge_method=None, net_charge=net_charge, gaff_mol2_filename=gaff_mol2_filename, frcmod_filename=frcmod_filename)

    # Read the resulting GAFF mol2 file as a ParmEd structure.
    ifs = oechem.oemolistream(gaff_mol2_filename)
    ifs.SetFlavor(oechem.OEFormat_MOL2, oechem.OEIFlavor_MOL2_DEFAULT | oechem.OEIFlavor_MOL2_M2H | oechem.OEIFlavor_MOL2_Forcefield)
    m2h = True
    oechem.OEReadMolecule(ifs, molecule)
    ifs.close()

    # If residue_atoms = None, add all atoms to the residues
    if residue_atoms == None:
        residue_atoms = [ atom for atom in molecule.GetAtoms() ]

    # Modify partial charges so that charge on residue atoms is integral.
    residue_charge = 0.0
    sum_of_absolute_charge = 0.0
    for atom in residue_atoms:
        charge = atom.GetPartialCharge()
        residue_charge += charge
        sum_of_absolute_charge += abs(charge)
    excess_charge = residue_charge - net_charge
    if sum_of_absolute_charge == 0.0:
        sum_of_absolute_charge = 1.0
    for atom in residue_atoms:
        charge = atom.GetPartialCharge()
        atom.SetPartialCharge( charge + excess_charge * (abs(charge) / sum_of_absolute_charge) )

    # Create residue template.
    template = ForceField._TemplateData(template_name)
    for (index, atom) in enumerate(molecule.GetAtoms()):
        atomname = atom.GetName()
        typename = atom.GetType()
        element = Element.getByAtomicNumber(atom.GetAtomicNum())
        charge = atom.GetPartialCharge()
        parameters = { 'charge' : charge }
        atom_template = ForceField._TemplateAtomData(atomname, typename, element, parameters)
        template.atoms.append(atom_template)
    for bond in molecule.GetBonds():
        if (bond.GetBgn() in residue_atoms) and (bond.GetEnd() in residue_atoms):
            template.addBondByName(bond.GetBgn().GetName(), bond.GetEnd().GetName())
        elif (bond.GetBgn() in residue_atoms) and (bond.GetEnd() not in residue_atoms):
            template.addExternalBondByName(bond.GetBgn().GetName())
        elif (bond.GetBgn() not in residue_atoms) and (bond.GetEnd() in residue_atoms):
            template.addExternalBondByName(bond.GetEnd().GetName())

    # Generate ffxml file contents for parmchk-generated frcmod output.
    leaprc = StringIO("parm = loadamberparams %s" % frcmod_filename)
    params = parmed.amber.AmberParameterSet.from_leaprc(leaprc)
    params = parmed.openmm.OpenMMParameterSet.from_parameterset(params)
    ffxml = StringIO()
    params.write(ffxml)

    return template, ffxml.getvalue()
Esempio n. 26
0
def generateForceFieldFromMolecules(molecules,
                                    ignoreFailures=False,
                                    generateUniqueNames=False,
                                    normalize=True,
                                    gaff_version='gaff'):
    """
    Generate ffxml file containing additional parameters and residue templates for simtk.openmm.app.ForceField using GAFF/AM1-BCC.

    This requires the OpenEye toolkit.

    Parameters
    ----------
    molecules : list of openeye.oechem.OEMol
        The molecules to be parameterized.
        All molecules must have explicit hydrogens.
        Net charge will be inferred from the net formal charge on each molecule.
        Partial charges will be determined automatically using oequacpac and canonical AM1-BCC charging rules.
    ignoreFailures: bool, optional, default=False
        Determines whether to add a failed molecule to the list of failed molecules (True),
        or raise an Exception (False).
    generateUniqueNames : bool, optional, default=False
        If True, will generate globally unique names for templates.
    normalize : bool, optional, default=True
        If True, normalize the molecule by checking aromaticity, adding
        explicit hydrogens, and renaming by IUPAC name.        
    gaff_version : str, default = 'gaff'
        One of ['gaff', 'gaff2']; selects which atom types to use.

    Returns
    -------
    ffxml : str
        Contents of ForceField `ffxml` file defining additional parameters from parmchk(2) and residue templates.
    failed_molecule_list : list of openeye.oechem.OEMol
        List of the oemols that could not be parameterized. Only returned if ignoreFailures=True

    Notes
    -----
    This method preserves stereochemistry during AM1-BCC charge parameterization.
    Residue template names will be set from molecule names.
    Atom names in molecules will be assigned Tripos atom names if any are blank or not unique.

    """
    if not generateUniqueNames:
        # Check template names are unique.
        template_names = set()
        for molecule in molecules:
            template_name = molecule.GetTitle()
            if template_name == '<0>':
                raise Exception("Molecule '%s' has invalid name" %
                                template_name)
            if template_name in template_names:
                raise Exception("Molecule '%s' has template name collision." %
                                template_name)
            template_names.add(template_name)

    # Process molecules.
    import tempfile
    tmpdir = tempfile.mkdtemp()
    olddir = os.getcwd()
    os.chdir(tmpdir)
    leaprc = ""
    failed_molecule_list = []
    for (molecule_index, molecule) in enumerate(molecules):
        # Set the template name based on the molecule title.
        if generateUniqueNames:
            from uuid import uuid4
            template_name = molecule.GetTitle() + '-' + str(uuid4())
        else:
            template_name = molecule.GetTitle()

        # If any atom names are not unique, atom names
        _ensureUniqueAtomNames(molecule)

        # Compute net formal charge.
        net_charge = _computeNetCharge(molecule)

        # Generate canonical AM1-BCC charges and a reference conformation.
        if not ignoreFailures:
            molecule = get_charges(molecule,
                                   strictStereo=False,
                                   keep_confs=1,
                                   normalize=normalize)
        else:
            try:
                molecule = get_charges(molecule,
                                       strictStereo=False,
                                       keep_confs=1,
                                       normalize=normalize)
            except:
                failed_molecule_list.append(molecule)

        # Create a unique prefix.
        prefix = 'molecule%010d' % molecule_index

        # Create temporary directory for running antechamber.
        input_mol2_filename = prefix + '.tripos.mol2'
        gaff_mol2_filename = prefix + '.gaff.mol2'
        frcmod_filename = prefix + '.frcmod'

        # Write Tripos mol2 file as antechamber input.
        _writeMolecule(molecule, input_mol2_filename, standardize=normalize)

        # Parameterize the molecule with antechamber.
        run_antechamber(prefix,
                        input_mol2_filename,
                        charge_method=None,
                        net_charge=net_charge,
                        gaff_mol2_filename=gaff_mol2_filename,
                        frcmod_filename=frcmod_filename,
                        gaff_version=gaff_version)

        # Append to leaprc input for parmed.
        leaprc += '%s = loadmol2 %s\n' % (prefix, gaff_mol2_filename)
        leaprc += 'loadamberparams %s\n' % frcmod_filename

    # Generate ffxml file contents for parmchk-generated frcmod output.
    leaprc = StringIO(leaprc)
    params = parmed.amber.AmberParameterSet.from_leaprc(leaprc)
    params = parmed.openmm.OpenMMParameterSet.from_parameterset(params)
    ffxml = StringIO()
    params.write(ffxml)

    # TODO: Clean up temporary directory.
    os.chdir(olddir)

    if ignoreFailures:
        return ffxml.getvalue(), failed_molecule_list
    else:
        return ffxml.getvalue()
def gcrt2prmtop(gcrt_file):
    system_name=gcrt_file.split('.')[0]
    amber.run_antechamber(system_name, gcrt_file, charge_method=None, input_format='gcrt')
    amber.run_tleap(system_name, system_name+'.gaff.mol2',system_name+'.frcmod',system_name+'.prmtop',system_name+'.crd')
    return None
Esempio n. 28
0
def generateResidueTemplate(molecule,
                            residue_atoms=None,
                            normalize=True,
                            gaff_version='gaff'):
    """
    Generate an residue template for simtk.openmm.app.ForceField using GAFF/AM1-BCC.

    This requires the OpenEye toolkit.

    Parameters
    ----------
    molecule : openeye.oechem.OEMol
        The molecule to be parameterized.
        The molecule must have explicit hydrogens.
        Net charge will be inferred from the net formal charge on each molecule.
        Partial charges will be determined automatically using oequacpac and canonical AM1-BCC charging rules.
    residue_atomset : set of OEAtom, optional, default=None
        If not None, only the atoms in this set will be used to construct the residue template
    normalize : bool, optional, default=True
        If True, normalize the molecule by checking aromaticity, adding
        explicit hydrogens, and renaming by IUPAC name.
    gaff_version : str, default = 'gaff'
        One of ['gaff', 'gaff2']; selects which atom types to use.
        

    Returns
    -------
    template : simtk.openmm.app.forcefield._TemplateData
        Residue template for ForceField using atom types and parameters from `gaff.xml` or `gaff2.xml`.
    additional_parameters_ffxml : str
        Contents of ForceField `ffxml` file defining additional parameters from parmchk(2).

    Notes
    -----
    The residue template will be named after the molecule title.
    This method preserves stereochemistry during AM1-BCC charge parameterization.
    Atom names in molecules will be assigned Tripos atom names if any are blank or not unique.

    """
    # Set the template name based on the molecule title plus a globally unique UUID.
    from uuid import uuid4
    template_name = molecule.GetTitle() + '-' + str(uuid4())

    # If any atom names are not unique, atom names
    _ensureUniqueAtomNames(molecule)

    # Compute net formal charge.
    net_charge = _computeNetCharge(molecule)

    # Generate canonical AM1-BCC charges and a reference conformation.
    molecule = get_charges(molecule,
                           strictStereo=False,
                           keep_confs=1,
                           normalize=normalize)

    # DEBUG: This may be necessary.
    molecule.SetTitle('MOL')

    # Create temporary directory for running antechamber.
    import tempfile
    tmpdir = tempfile.mkdtemp()
    prefix = 'molecule'
    input_mol2_filename = os.path.join(tmpdir, prefix + '.tripos.mol2')
    gaff_mol2_filename = os.path.join(tmpdir, prefix + '.gaff.mol2')
    frcmod_filename = os.path.join(tmpdir, prefix + '.frcmod')

    # Write Tripos mol2 file as antechamber input.
    _writeMolecule(molecule, input_mol2_filename, standardize=normalize)

    # Parameterize the molecule with antechamber.
    run_antechamber(template_name,
                    input_mol2_filename,
                    charge_method=None,
                    net_charge=net_charge,
                    gaff_mol2_filename=gaff_mol2_filename,
                    frcmod_filename=frcmod_filename,
                    gaff_version=gaff_version)

    # Read the resulting GAFF mol2 file as a ParmEd structure.
    from openeye import oechem
    ifs = oechem.oemolistream(gaff_mol2_filename)
    ifs.SetFlavor(
        oechem.OEFormat_MOL2, oechem.OEIFlavor_MOL2_DEFAULT
        | oechem.OEIFlavor_MOL2_M2H | oechem.OEIFlavor_MOL2_Forcefield)
    m2h = True
    oechem.OEReadMolecule(ifs, molecule)
    ifs.close()

    # If residue_atoms = None, add all atoms to the residues
    if residue_atoms == None:
        residue_atoms = [atom for atom in molecule.GetAtoms()]

    # Modify partial charges so that charge on residue atoms is integral.
    residue_charge = 0.0
    sum_of_absolute_charge = 0.0
    for atom in residue_atoms:
        charge = atom.GetPartialCharge()
        residue_charge += charge
        sum_of_absolute_charge += abs(charge)
    excess_charge = residue_charge - net_charge
    if sum_of_absolute_charge == 0.0:
        sum_of_absolute_charge = 1.0
    for atom in residue_atoms:
        charge = atom.GetPartialCharge()
        atom.SetPartialCharge(charge + excess_charge *
                              (abs(charge) / sum_of_absolute_charge))

    # Create residue template.
    template = ForceField._TemplateData(template_name)
    for (index, atom) in enumerate(molecule.GetAtoms()):
        atomname = atom.GetName()
        typename = atom.GetType()
        element = Element.getByAtomicNumber(atom.GetAtomicNum())
        charge = atom.GetPartialCharge()
        parameters = {'charge': charge}
        atom_template = ForceField._TemplateAtomData(atomname, typename,
                                                     element, parameters)
        template.atoms.append(atom_template)
    for bond in molecule.GetBonds():
        if (bond.GetBgn() in residue_atoms) and (bond.GetEnd()
                                                 in residue_atoms):
            template.addBondByName(bond.GetBgn().GetName(),
                                   bond.GetEnd().GetName())
        elif (bond.GetBgn() in residue_atoms) and (bond.GetEnd()
                                                   not in residue_atoms):
            template.addExternalBondByName(bond.GetBgn().GetName())
        elif (bond.GetBgn() not in residue_atoms) and (bond.GetEnd()
                                                       in residue_atoms):
            template.addExternalBondByName(bond.GetEnd().GetName())

    # Generate ffxml file contents for parmchk-generated frcmod output.
    leaprc = StringIO('parm = loadamberparams %s' % frcmod_filename)
    params = parmed.amber.AmberParameterSet.from_leaprc(leaprc)
    params = parmed.openmm.OpenMMParameterSet.from_parameterset(params)
    ffxml = StringIO()
    params.write(ffxml)

    return template, ffxml.getvalue()
Esempio n. 29
0
def test_amber_water_mixture():
    water_filename = utils.get_data_filename("chemicals/water/water.mol2")
    etoh_filename = utils.get_data_filename("chemicals/etoh/etoh.mol2")
    sustiva_filename = utils.get_data_filename(
        "chemicals/sustiva/sustiva.mol2")

    with utils.enter_temp_directory(
    ):  # Prevents creating tons of GAFF files everywhere.
        shutil.copy(water_filename, 'c1.mol2')
        shutil.copy(etoh_filename, 'c2.mol2')
        shutil.copy(sustiva_filename, 'c3.mol2')
        water_filename = 'c1.mol2'
        etoh_filename = 'c2.mol2'
        sustiva_filename = 'c3.mol2'
        #Randomize residue names to avoid clashes
        utils.randomize_mol2_residue_names(
            [water_filename, etoh_filename, sustiva_filename])

        trj0, trj1, trj2 = md.load(water_filename), md.load(
            etoh_filename), md.load(sustiva_filename)

        trj_list = [trj0, trj1, trj2]

        box_filename = "./box.pdb"
        box_trj = packmol.pack_box(trj_list, [300, 25, 3])
        box_trj.save(box_filename)

        gaff_mol2_filename0, frcmod_filename0 = amber.run_antechamber(
            "water", water_filename, charge_method=None)
        gaff_mol2_filename1, frcmod_filename1 = amber.run_antechamber(
            "etoh", etoh_filename, charge_method=None)
        gaff_mol2_filename2, frcmod_filename2 = amber.run_antechamber(
            "sustiva", sustiva_filename, charge_method=None)

        mol2_filenames = [
            gaff_mol2_filename0, gaff_mol2_filename1, gaff_mol2_filename2
        ]
        frcmod_filenames = [
            frcmod_filename0, frcmod_filename1, frcmod_filename2
        ]

        prmtop_filename = "./out.prmtop"
        inpcrd_filename = "./out.inpcrd"

        shutil.copy(box_filename, 'renamed.pdb')
        tleap_cmd = amber.build_mixture_prmtop(mol2_filenames,
                                               frcmod_filenames, 'renamed.pdb',
                                               prmtop_filename,
                                               inpcrd_filename)
        print(tleap_cmd)

        #Also do here for case of GAFF water
        tleap_cmd = amber.build_mixture_prmtop(mol2_filenames,
                                               frcmod_filenames,
                                               box_filename,
                                               prmtop_filename,
                                               inpcrd_filename,
                                               water_model=None)
        print(tleap_cmd)

        #Also do here for case of SPC
        tleap_cmd = amber.build_mixture_prmtop(mol2_filenames,
                                               frcmod_filenames,
                                               'renamed.pdb',
                                               prmtop_filename,
                                               inpcrd_filename,
                                               water_model='SPC')
        print(tleap_cmd)
Esempio n. 30
0
def test_run_tleap():
    molecule_name = "sustiva"
    input_filename = utils.get_data_filename("chemicals/sustiva/sustiva.mol2")
    with utils.enter_temp_directory():  # Prevents creating tons of GAFF files everywhere.
        gaff_mol2_filename, frcmod_filename = amber.run_antechamber(molecule_name, input_filename, charge_method=None)
        prmtop, inpcrd = amber.run_tleap(molecule_name, gaff_mol2_filename, frcmod_filename)
def generateResidueTemplate(molecule, residue_atoms=None, normalize=True, gaff_version='gaff'):
    """
    Generate an residue template for simtk.openmm.app.ForceField using GAFF/AM1-BCC.

    This requires the OpenEye toolkit.

    Parameters
    ----------
    molecule : openeye.oechem.OEMol
        The molecule to be parameterized.
        The molecule must have explicit hydrogens.
        Net charge will be inferred from the net formal charge on each molecule.
        Partial charges will be determined automatically using oequacpac and canonical AM1-BCC charging rules.
    residue_atomset : set of OEAtom, optional, default=None
        If not None, only the atoms in this set will be used to construct the residue template
    normalize : bool, optional, default=True
        If True, normalize the molecule by checking aromaticity, adding
        explicit hydrogens, and renaming by IUPAC name.
    gaff_version : str, default = 'gaff'
        One of ['gaff', 'gaff2']; selects which atom types to use.


    Returns
    -------
    template : simtk.openmm.app.forcefield._TemplateData
        Residue template for ForceField using atom types and parameters from `gaff.xml` or `gaff2.xml`.
    additional_parameters_ffxml : str
        Contents of ForceField `ffxml` file defining additional parameters from parmchk(2).

    Notes
    -----
    The residue template will be named after the molecule title.
    This method preserves stereochemistry during AM1-BCC charge parameterization.
    Atom names in molecules will be assigned Tripos atom names if any are blank or not unique.

    """
    # Set the template name based on the molecule title plus a globally unique UUID.
    from uuid import uuid4
    template_name = molecule.GetTitle() + '-' + str(uuid4())

    # If any atom names are not unique, atom names
    _ensureUniqueAtomNames(molecule)

    # Compute net formal charge.
    net_charge = _computeNetCharge(molecule)

    # Generate canonical AM1-BCC charges and a reference conformation.
    molecule = get_charges(molecule, strictStereo=False, keep_confs=1, normalize=normalize)

    # DEBUG: This may be necessary.
    molecule.SetTitle('MOL')

    # Create temporary directory for running antechamber.
    import tempfile
    tmpdir = tempfile.mkdtemp()
    prefix = 'molecule'
    input_mol2_filename = os.path.join(tmpdir, prefix + '.tripos.mol2')
    gaff_mol2_filename = os.path.join(tmpdir, prefix + '.gaff.mol2')
    frcmod_filename = os.path.join(tmpdir, prefix + '.frcmod')

    # Write Tripos mol2 file as antechamber input.
    _writeMolecule(molecule, input_mol2_filename, standardize=normalize)

    # Parameterize the molecule with antechamber.
    run_antechamber(template_name, input_mol2_filename, charge_method=None, net_charge=net_charge, gaff_mol2_filename=gaff_mol2_filename, frcmod_filename=frcmod_filename, gaff_version=gaff_version)

    # Read the resulting GAFF mol2 file as a ParmEd structure.
    from openeye import oechem
    ifs = oechem.oemolistream(gaff_mol2_filename)
    ifs.SetFlavor(oechem.OEFormat_MOL2, oechem.OEIFlavor_MOL2_DEFAULT | oechem.OEIFlavor_MOL2_M2H | oechem.OEIFlavor_MOL2_Forcefield)
    m2h = True
    oechem.OEReadMolecule(ifs, molecule)
    ifs.close()

    # If residue_atoms = None, add all atoms to the residues
    if residue_atoms == None:
        residue_atoms = [ atom for atom in molecule.GetAtoms() ]

    # Modify partial charges so that charge on residue atoms is integral.
    residue_charge = 0.0
    sum_of_absolute_charge = 0.0
    for atom in residue_atoms:
        charge = atom.GetPartialCharge()
        residue_charge += charge
        sum_of_absolute_charge += abs(charge)
    excess_charge = residue_charge - net_charge
    if sum_of_absolute_charge == 0.0:
        sum_of_absolute_charge = 1.0
    for atom in residue_atoms:
        charge = atom.GetPartialCharge()
        atom.SetPartialCharge( charge + excess_charge * (abs(charge) / sum_of_absolute_charge) )

    # Create residue template.
    template = ForceField._TemplateData(template_name)
    for (index, atom) in enumerate(molecule.GetAtoms()):
        atomname = atom.GetName()
        typename = atom.GetType()
        element = Element.getByAtomicNumber(atom.GetAtomicNum())
        charge = atom.GetPartialCharge()
        parameters = { 'charge' : charge }
        atom_template = ForceField._TemplateAtomData(atomname, typename, element, parameters)
        template.atoms.append(atom_template)
    for bond in molecule.GetBonds():
        if (bond.GetBgn() in residue_atoms) and (bond.GetEnd() in residue_atoms):
            template.addBondByName(bond.GetBgn().GetName(), bond.GetEnd().GetName())
        elif (bond.GetBgn() in residue_atoms) and (bond.GetEnd() not in residue_atoms):
            template.addExternalBondByName(bond.GetBgn().GetName())
        elif (bond.GetBgn() not in residue_atoms) and (bond.GetEnd() in residue_atoms):
            template.addExternalBondByName(bond.GetEnd().GetName())

    # Generate ffxml file contents for parmchk-generated frcmod output.
    leaprc = StringIO('parm = loadamberparams %s' % frcmod_filename)
    params = parmed.amber.AmberParameterSet.from_leaprc(leaprc)
    params = parmed.openmm.OpenMMParameterSet.from_parameterset(params)
    ffxml = StringIO()
    params.write(ffxml)

    return template, ffxml.getvalue()
def generateForceFieldFromMolecules(molecules, ignoreFailures=False, generateUniqueNames=False, normalize=True, gaff_version='gaff'):
    """
    Generate ffxml file containing additional parameters and residue templates for simtk.openmm.app.ForceField using GAFF/AM1-BCC.

    This requires the OpenEye toolkit.

    Parameters
    ----------
    molecules : list of openeye.oechem.OEMol
        The molecules to be parameterized.
        All molecules must have explicit hydrogens.
        Net charge will be inferred from the net formal charge on each molecule.
        Partial charges will be determined automatically using oequacpac and canonical AM1-BCC charging rules.
    ignoreFailures: bool, optional, default=False
        Determines whether to add a failed molecule to the list of failed molecules (True),
        or raise an Exception (False).
    generateUniqueNames : bool, optional, default=False
        If True, will generate globally unique names for templates.
    normalize : bool, optional, default=True
        If True, normalize the molecule by checking aromaticity, adding
        explicit hydrogens, and renaming by IUPAC name.
    gaff_version : str, default = 'gaff'
        One of ['gaff', 'gaff2']; selects which atom types to use.

    Returns
    -------
    ffxml : str
        Contents of ForceField `ffxml` file defining additional parameters from parmchk(2) and residue templates.
    failed_molecule_list : list of openeye.oechem.OEMol
        List of the oemols that could not be parameterized. Only returned if ignoreFailures=True

    Notes
    -----
    This method preserves stereochemistry during AM1-BCC charge parameterization.
    Residue template names will be set from molecule names.
    Atom names in molecules will be assigned Tripos atom names if any are blank or not unique.

    """
    if not generateUniqueNames:
    # Check template names are unique.
        template_names = set()
        for molecule in molecules:
            template_name = molecule.GetTitle()
            if template_name == '<0>':
                raise Exception("Molecule '%s' has invalid name" % template_name)
            if template_name in template_names:
                raise Exception("Molecule '%s' has template name collision." % template_name)
            template_names.add(template_name)

    # Process molecules.
    import tempfile
    tmpdir = tempfile.mkdtemp()
    olddir = os.getcwd()
    os.chdir(tmpdir)
    leaprc = ""
    failed_molecule_list = []
    for (molecule_index, molecule) in enumerate(molecules):
        # Set the template name based on the molecule title.
        if generateUniqueNames:
            from uuid import uuid4
            template_name = molecule.GetTitle() + '-' + str(uuid4())
        else:
            template_name = molecule.GetTitle()

        # If any atom names are not unique, atom names
        _ensureUniqueAtomNames(molecule)

        # Compute net formal charge.
        net_charge = _computeNetCharge(molecule)

        # Generate canonical AM1-BCC charges and a reference conformation.
        if not ignoreFailures:
            molecule = get_charges(molecule, strictStereo=False, keep_confs=1, normalize=normalize)
        else:
            try:
                molecule = get_charges(molecule, strictStereo=False, keep_confs=1, normalize=normalize)
            except:
                failed_molecule_list.append(molecule)

        # Create a unique prefix.
        prefix = 'molecule%010d' % molecule_index

        # Create temporary directory for running antechamber.
        input_mol2_filename = prefix + '.tripos.mol2'
        gaff_mol2_filename  = prefix + '.gaff.mol2'
        frcmod_filename     = prefix + '.frcmod'

        # Write Tripos mol2 file as antechamber input.
        _writeMolecule(molecule, input_mol2_filename, standardize=normalize)

        # Parameterize the molecule with antechamber.
        run_antechamber(prefix, input_mol2_filename, charge_method=None, net_charge=net_charge, gaff_mol2_filename=gaff_mol2_filename, frcmod_filename=frcmod_filename, gaff_version=gaff_version)

        # Append to leaprc input for parmed.
        leaprc += '%s = loadmol2 %s\n' % (prefix, gaff_mol2_filename)
        leaprc += 'loadamberparams %s\n' % frcmod_filename

    # Generate ffxml file contents for parmchk-generated frcmod output.
    leaprc = StringIO(leaprc)
    params = parmed.amber.AmberParameterSet.from_leaprc(leaprc)
    params = parmed.openmm.OpenMMParameterSet.from_parameterset(params)
    ffxml = StringIO()
    params.write(ffxml)

    # TODO: Clean up temporary directory.
    os.chdir(olddir)

    if ignoreFailures:
        return ffxml.getvalue(), failed_molecule_list
    else:
        return ffxml.getvalue()
Esempio n. 33
0
def generateForceFieldFromMolecules(molecules):
    """
    Generate ffxml file containing additional parameters and residue templates for simtk.openmm.app.ForceField using GAFF/AM1-BCC.

    This requires the OpenEye toolkit.

    Parameters
    ----------
    molecules : list of openeye.oechem.OEMol
        The molecules to be parameterized.
        All molecules must have explicit hydrogens.
        Net charge will be inferred from the net formal charge on each molecule.
        Partial charges will be determined automatically using oequacpac and canonical AM1-BCC charging rules.

    Returns
    -------
    ffxml : str
        Contents of ForceField `ffxml` file defining additional parameters from parmchk(2) and residue templates.

    Notes
    -----
    This method preserves stereochemistry during AM1-BCC charge parameterization.
    Residue template names will be set from molecule names.
    Atom names in molecules will be assigned Tripos atom names if any are blank or not unique.

    """
    # Check template names are unique.
    template_names = set()
    for molecule in molecules:
        template_name = molecule.GetTitle()
        if template_name == '<0>':
            raise Exception("Molecule '%s' has invalid name" % template_name)
        if template_name in template_names:
            raise Exception("Molecule '%s' has template name collision." %
                            template_name)
        template_names.add(template_name)

    # Process molecules.
    import tempfile
    tmpdir = tempfile.mkdtemp()
    olddir = os.getcwd()
    os.chdir(tmpdir)
    leaprc = ""
    for (molecule_index, molecule) in enumerate(molecules):
        # Set the template name based on the molecule title.
        template_name = molecule.GetTitle()

        # If any atom names are not unique, atom names
        _ensureUniqueAtomNames(molecule)

        # Compute net formal charge.
        net_charge = _computeNetCharge(molecule)

        # Generate canonical AM1-BCC charges and a reference conformation.
        molecule = get_charges(molecule, strictStereo=False, keep_confs=1)

        # Create a unique prefix.
        prefix = 'molecule%010d' % molecule_index

        # Create temporary directory for running antechamber.
        input_mol2_filename = prefix + '.tripos.mol2'
        gaff_mol2_filename = prefix + '.gaff.mol2'
        frcmod_filename = prefix + '.frcmod'

        # Write Tripos mol2 file as antechamber input.
        _writeMolecule(molecule, input_mol2_filename)

        # Parameterize the molecule with antechamber.
        run_antechamber(prefix,
                        input_mol2_filename,
                        charge_method=None,
                        net_charge=net_charge,
                        gaff_mol2_filename=gaff_mol2_filename,
                        frcmod_filename=frcmod_filename)

        # Append to leaprc input for parmed.
        leaprc += '%s = loadmol2 %s\n' % (prefix, gaff_mol2_filename)
        leaprc += 'loadamberparams %s\n' % frcmod_filename

    # Generate ffxml file contents for parmchk-generated frcmod output.
    leaprc = StringIO(leaprc)
    params = parmed.amber.AmberParameterSet.from_leaprc(leaprc)
    params = parmed.openmm.OpenMMParameterSet.from_parameterset(params)
    ffxml = StringIO()
    params.write(ffxml)

    # TODO: Clean up temporary directory.
    os.chdir(olddir)

    return ffxml.getvalue()
def generateForceFieldFromMolecules(molecules):
    """
    Generate ffxml file containing additional parameters and residue templates for simtk.openmm.app.ForceField using GAFF/AM1-BCC.

    This requires the OpenEye toolkit.

    Parameters
    ----------
    molecules : list of openeye.oechem.OEMol
        The molecules to be parameterized.
        All molecules must have explicit hydrogens.
        Net charge will be inferred from the net formal charge on each molecule.
        Partial charges will be determined automatically using oequacpac and canonical AM1-BCC charging rules.

    Returns
    -------
    ffxml : str
        Contents of ForceField `ffxml` file defining additional parameters from parmchk(2) and residue templates.

    Notes
    -----
    This method preserves stereochemistry during AM1-BCC charge parameterization.
    Residue template names will be set from molecule names.
    Atom names in molecules will be assigned Tripos atom names if any are blank or not unique.

    """
    # Check template names are unique.
    template_names = set()
    for molecule in molecules:
        template_name = molecule.GetTitle()
        if template_name == '<0>':
            raise Exception("Molecule '%s' has invalid name" % template_name)
        if template_name in template_names:
            raise Exception("Molecule '%s' has template name collision." % template_name)
        template_names.add(template_name)

    # Process molecules.
    import tempfile
    tmpdir = tempfile.mkdtemp()
    olddir = os.getcwd()
    os.chdir(tmpdir)
    leaprc = ""
    for (molecule_index, molecule) in enumerate(molecules):
        # Set the template name based on the molecule title.
        template_name = molecule.GetTitle()

        # If any atom names are not unique, atom names
        _ensureUniqueAtomNames(molecule)

        # Compute net formal charge.
        net_charge = _computeNetCharge(molecule)

        # Generate canonical AM1-BCC charges and a reference conformation.
        molecule = get_charges(molecule, strictStereo=False, keep_confs=1)

        # Create a unique prefix.
        prefix = 'molecule%010d' % molecule_index

        # Create temporary directory for running antechamber.
        input_mol2_filename = prefix + '.tripos.mol2'
        gaff_mol2_filename  = prefix + '.gaff.mol2'
        frcmod_filename     = prefix + '.frcmod'

        # Write Tripos mol2 file as antechamber input.
        _writeMolecule(molecule, input_mol2_filename)

        # Parameterize the molecule with antechamber.
        run_antechamber(prefix, input_mol2_filename, charge_method=None, net_charge=net_charge, gaff_mol2_filename=gaff_mol2_filename, frcmod_filename=frcmod_filename)

        # Append to leaprc input for parmed.
        leaprc += '%s = loadmol2 %s\n' % (prefix, gaff_mol2_filename)
        leaprc += 'loadamberparams %s\n' % frcmod_filename

    # Generate ffxml file contents for parmchk-generated frcmod output.
    leaprc = StringIO(leaprc)
    params = parmed.amber.AmberParameterSet.from_leaprc(leaprc)
    params = parmed.openmm.OpenMMParameterSet.from_parameterset(params)
    ffxml = StringIO()
    params.write(ffxml)

    # TODO: Clean up temporary directory.
    os.chdir(olddir)

    return ffxml.getvalue()
Esempio n. 35
0
def test_run_antechamber_charges():
    molecule_name = "acetate"
    input_filename = utils.get_data_filename("chemicals/acetate/acetate.mol2")
    with utils.enter_temp_directory():  # Prevents creating tons of GAFF files everywhere.
        gaff_mol2_filename, frcmod_filename = amber.run_antechamber(molecule_name, input_filename, charge_method=None, net_charge=-1)