Esempio n. 1
0
def test_change_parameters(verbose=False):
    """Test modification of forcefield parameters."""
    from openeye import oechem
    # Load simple OEMol
    ifs = oechem.oemolistream(
        get_data_filename('molecules/AlkEthOH_c100.mol2'))
    mol = oechem.OEMol()
    flavor = oechem.OEIFlavor_Generic_Default | oechem.OEIFlavor_MOL2_Default | oechem.OEIFlavor_MOL2_Forcefield
    ifs.SetFlavor(oechem.OEFormat_MOL2, flavor)
    oechem.OEReadMolecule(ifs, mol)
    oechem.OETriposAtomNames(mol)

    # Load forcefield file
    ffxml = get_data_filename('forcefield/Frosst_AlkEtOH.ffxml')
    ff = ForceField(ffxml)

    from smarty.forcefield import generateTopologyFromOEMol
    topology = generateTopologyFromOEMol(mol)
    # Create initial system
    system = ff.createSystem(topology, [mol], verbose=verbose)
    # Get initial energy before parameter modification
    positions = positions_from_oemol(mol)
    old_energy = get_energy(system, positions)

    # Get params for an angle
    params = ff.getParameter(smirks='[a,A:1]-[#6X4:2]-[a,A:3]')
    # Modify params
    params['k'] = '0.0'
    ff.setParameter(params, smirks='[a,A:1]-[#6X4:2]-[a,A:3]')
    # Write params
    ff.writeFile(tempfile.TemporaryFile(suffix='.ffxml'))
    # Make sure params changed energy! (Test whether they get rebuilt on system creation)
    system = ff.createSystem(topology, [mol], verbose=verbose)
    energy = get_energy(system, positions)
    if verbose:
        print("New energy/old energy:", energy, old_energy)
    if np.abs(energy - old_energy) < 0.1:
        raise Exception("Error: Parameter modification did not change energy.")
Esempio n. 2
0
def main(argv=[__name__]):

    itf = oechem.OEInterface(InterfaceData)

    if oechem.OECheckHelp(itf, argv):
        return 0

    if not oechem.OEParseCommandLine(itf, argv):
        return 1

    ifs = oechem.oemolistream()
    if not ifs.open(itf.GetString("-i")):
        oechem.OEThrow.Fatal("Unable to open %s for reading" %
                             itf.GetString("-i"))

    ofs = oechem.oemolostream()
    if not ofs.open(itf.GetString("-o")):
        oechem.OEThrow.Fatal("Unable to open %s for writing" %
                             itf.GetString("-o"))

    omega = oeomega.OEOmega()
    maxConfs = 0
    omega.SetMaxConfs(maxConfs)
    omega.SetStrictStereo(False)
    omega.SetSampleHydrogens(True)
    omega.SetEnumNitrogen(oeomega.OENitrogenEnumeration_All)
    mol = oechem.OEMol()
    for mol in ifs.GetOEMols():
        #print( mol.GetTitle() )
        if not omega(mol):
            print("omega failed on %s" % mol.GetTitle())
        title = mol.GetTitle()
        oechem.OETriposAtomNames(mol)
        oequacpac.OEAssignPartialCharges(mol, oequacpac.OECharges_AM1BCCSym)
        oechem.OEWriteConstMolecule(ofs, mol)

    ofs.close()
    return 0
Esempio n. 3
0
def createOEMolFromIUPAC(iupac_name='bosutinib'):
    from openeye import oechem, oeiupac, oeomega

    # Create molecule.
    mol = oechem.OEMol()
    oeiupac.OEParseIUPACName(mol, iupac_name)
    mol.SetTitle(iupac_name)

    # Assign aromaticity and hydrogens.
    oechem.OEAssignAromaticFlags(mol, oechem.OEAroModelOpenEye)
    oechem.OEAddExplicitHydrogens(mol)

    # Create atom names.
    oechem.OETriposAtomNames(mol)

    # Assign geometry
    omega = oeomega.OEOmega()
    omega.SetMaxConfs(1)
    omega.SetIncludeInput(False)
    omega.SetStrictStereo(True)
    omega(mol)

    return mol
Esempio n. 4
0
def write_host(host_oemol: oechem.OEMol, filepath: str):
    """
    Write out the host molecule on its own.

    Parameters
    ----------
    host_oemol : oechem.OEMol
        the OEMol containing the host
    filepath : str
        where to write the OEMol
    """
    ostream = oechem.oemolostream()
    ostream.open(filepath)

    # set title to avoid template name collision:
    host_oemol.SetTitle("host")

    # set tripos atom names
    oechem.OETriposAtomNames(host_oemol)

    oechem.OEWriteMolecule(ostream, host_oemol)

    ostream.close()
Esempio n. 5
0
def smi2sdf(wdir, smiles):
    """
    From a file containing smiles strings, generate omega conformers,
       resolve steric clashes, do a quick MM opt, and write SDF output.

    Parameters
    ----------
    wdir: str - working directory containing .smi file
    smiles: str - name of the smiles file. E.g. "name.smi"

    """
    sdfout = smiles.split('.')[0] + '.sdf'
    os.chdir(wdir)

    ### Read in smiles file.
    ifs = oechem.oemolistream()
    if not ifs.open(smiles):
        oechem.OEThrow.Warning("Unable to open %s for reading" % smiles)

    ### Open output file to write molecules.
    ofs = oechem.oemolostream()
    if os.path.exists(sdfout):
        #sys.exit("Output .sdf file already exists. Exiting.\n")
        print "Output .sdf file already exists. Exiting.\n"
        return
    if not ofs.open(sdfout):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % sdfout)

    ### For each molecule: label atoms, generate 1 conf, write output.
    for smimol in ifs.GetOEMols():
        oechem.OETriposAtomNames(smimol)
        mol = GenerateConfs(smimol)
        oechem.OEWriteConstMolecule(ofs, mol)

    ### Close files.
    ifs.close()
    ofs.close()
Esempio n. 6
0
def check_boxes(forcefield, description="", chargeMethod=None, verbose=False):
    """Test creation of System from boxes of mixed solvents.
    """
    # Read monomers
    mols = list()
    monomers = ['cyclohexane', 'ethanol', 'propane', 'methane', 'butanol']
    from openeye import oechem
    mol = oechem.OEGraphMol()
    for monomer in monomers:
        filename = get_data_filename(
            os.path.join('systems', 'monomers', monomer + '.sdf'))
        ifs = oechem.oemolistream(filename)
        while oechem.OEReadMolecule(ifs, mol):
            oechem.OETriposAtomNames(mol)
            mols.append(oechem.OEGraphMol(mol))
    if verbose: print('%d reference molecules loaded' % len(mols))

    # Read systems.
    boxes = [
        'cyclohexane_ethanol_0.4_0.6.pdb',
        'propane_methane_butanol_0.2_0.3_0.5.pdb'
    ]
    from simtk.openmm.app import PDBFile
    for box in boxes:
        filename = get_data_filename(
            os.path.join('systems', 'packmol_boxes', box))
        pdbfile = PDBFile(filename)
        f = partial(check_system_creation_from_topology,
                    forcefield,
                    pdbfile.topology,
                    mols,
                    pdbfile.positions,
                    chargeMethod=chargeMethod,
                    verbose=verbose)
        f.description = 'Test creation of System object from %s %s' % (
            box, description)
        yield f
Esempio n. 7
0
def constructDataFrame(mol_files):
    """ 
    Construct a pandas dataframe to be populated with computed single molecule properties. Each unique bond, angle and torsion has it's own column for a value
    and uncertainty.
    inputs: a list of mol2 files from which we determine connectivity using OpenEye Tools and construct the dataframe using Pandas.
    """

    molnames = []
    for i in mol_files:
        molname = i.replace(' ', '')[:-5]
        molname = molname.rsplit('/', 1)[1]
        print molname
        molnames.append(molname)

    OEMols = []
    for i in mol_files:
        mol = oechem.OEGraphMol()
        ifs = oechem.oemolistream(i)
        flavor = oechem.OEIFlavor_Generic_Default | oechem.OEIFlavor_MOL2_Default | oechem.OEIFlavor_MOL2_Forcefield
        ifs.SetFlavor(oechem.OEFormat_MOL2, flavor)
        oechem.OEReadMolecule(ifs, mol)
        oechem.OETriposAtomNames(mol)
        OEMols.append(mol)

    ff = ForceField(get_data_filename('/data/forcefield/smirff99Frosst.ffxml'))

    labels = []
    lst0 = []
    lst1 = []
    lst2 = []
    lst00 = [[] for i in molnames]
    lst11 = [[] for i in molnames]
    lst22 = [[] for i in molnames]

    for ind, val in enumerate(OEMols):
        label = ff.labelMolecules([val], verbose=False)
        for entry in range(len(label)):
            for bond in label[entry]['HarmonicBondGenerator']:
                lst0.extend([str(bond[0])])
                lst00[ind].extend([str(bond[0])])
            for angle in label[entry]['HarmonicAngleGenerator']:
                lst1.extend([str(angle[0])])
                lst11[ind].extend([str(angle[0])])
            for torsion in label[entry]['PeriodicTorsionGenerator']:
                lst2.extend([str(torsion[0])])
                lst22[ind].extend([str(torsion[0])])

    # Return unique strings from lst0
    cols0 = set()
    for x in lst0:
        cols0.add(x)
    cols0 = list(cols0)

    # Generate data lists to populate dataframe
    data0 = [[] for i in range(len(lst00))]
    for val in cols0:
        for ind, item in enumerate(lst00):
            if val in item:
                data0[ind].append(1)
            else:
                data0[ind].append(0)

    # Return unique strings from lst1
    cols1 = set()
    for x in lst1:
        cols1.add(x)
    cols1 = list(cols1)

    # Generate data lists to populate frame (1 means val in lst11 was in cols1, 0 means it wasn't)
    data1 = [[] for i in range(len(lst11))]
    for val in cols1:
        for ind, item in enumerate(lst11):
            if val in item:
                data1[ind].append(1)
            else:
                data1[ind].append(0)

    # Return unique strings from lst2
    cols2 = set()
    for x in lst2:
        cols2.add(x)
    cols2 = list(cols2)

    # Generate data lists to populate frame (1 means val in lst22 was in cols2, 0 means it wasn't)
    data2 = [[] for i in range(len(lst22))]
    for val in cols2:
        for ind, item in enumerate(lst22):
            if val in item:
                data2[ind].append(1)
            else:
                data2[ind].append(0)

    # Clean up clarity of column headers and molecule names
    cols0t = ["BondEquilibriumLength " + i for i in cols0]
    cols0temp = ["BondEquilibriumLength_std " + i for i in cols0]
    cols0 = cols0t + cols0temp

    cols1t = ["AngleEquilibriumAngle " + i for i in cols1]
    cols1temp = ["AngleEquilibriumAngle_std " + i for i in cols1]
    cols1 = cols1t + cols1temp

    cols2t = ["TorsionFourier1 " + i for i in cols2]
    cols2temp = ["TorsionFourier1_std " + i for i in cols2]
    cols2 = cols2t + cols2temp

    data0 = [i + i for i in data0]
    data1 = [i + i for i in data1]
    data2 = [i + i for i in data2]

    # Construct dataframes
    df0 = pd.DataFrame(data=data0, index=molnames, columns=cols0)
    df0['molecule'] = df0.index
    df1 = pd.DataFrame(data=data1, index=molnames, columns=cols1)
    df1['molecule'] = df1.index
    df2 = pd.DataFrame(data=data2, index=molnames, columns=cols2)
    df2['molecule'] = df2.index

    dftemp = pd.merge(df0, df1, how='outer', on='molecule')
    df = pd.merge(dftemp, df2, how='outer', on='molecule')

    return df, OEMols, cols2
Esempio n. 8
0
def test_component_combination():
    """Test that a system still yields the same energy after building it again out of its components."""

    # We've had issues where subsequent instances of a molecule might have zero charges
    # Here we'll try to catch this (and also explicitly check the charges) by re-building
    # a system out of its components

    forcefield = ForceField(
        get_data_filename('forcefield/Frosst_AlkEthOH.ffxml'))
    filename = get_data_filename(
        os.path.join('systems', 'packmol_boxes',
                     'cyclohexane_ethanol_0.4_0.6.pdb'))
    from simtk.openmm.app import PDBFile
    pdbfile = PDBFile(filename)
    mol2files = [
        get_data_filename(os.path.join('systems', 'monomers', 'ethanol.mol2')),
        get_data_filename(
            os.path.join('systems', 'monomers', 'cyclohexane.mol2'))
    ]

    flavor = oechem.OEIFlavor_Generic_Default | oechem.OEIFlavor_MOL2_Default | oechem.OEIFlavor_MOL2_Forcefield
    mols = []
    mol = oechem.OEMol()
    for mol2file in mol2files:
        ifs = oechem.oemolistream(mol2file)
        ifs.SetFlavor(oechem.OEFormat_MOL2, flavor)
        mol = oechem.OEGraphMol()
        while oechem.OEReadMolecule(ifs, mol):
            oechem.OETriposAtomNames(mol)
            mols.append(oechem.OEGraphMol(mol))

    # setup system
    system = forcefield.createSystem(pdbfile.topology,
                                     mols,
                                     chargeMethod='OECharges_AM1BCCSym')

    # Make parmed structure
    structure = parmed.openmm.topsystem.load_topology(pdbfile.topology, system,
                                                      pdbfile.positions)

    # Split the system, then re-compose it out of its components
    tmp = structure.split()
    strs, nums = [], []
    for s, n in tmp:
        strs.append(s)
        nums.append(n)
    nums = [len(n) for n in nums]

    # Re-compose system from components
    new_structure = strs[0] * nums[0]
    for idx in range(1, len(nums)):
        new_structure += strs[idx] * nums[idx]
    # Swap in coordinates again
    new_structure.positions = structure.positions

    # Create System
    newsys = new_structure.createSystem(nonbondedMethod=app.NoCutoff,
                                        constraints=None,
                                        implicitSolvent=None)

    # Cross check energies
    groups0, groups1, energy0, energy1 = compare_system_energies(
        pdbfile.topology,
        pdbfile.topology,
        system,
        newsys,
        pdbfile.positions,
        verbose=False)

    # Also check that that the number of components is equal to the number I expect
    if not len(nums) == 2:
        print("Error: Test system has incorrect number of components.")
        raise Exception(
            'Incorrect number of components in cyclohexane/ethanol test system.'
        )

    # Also check that none of residues have zero charge
    for resnr in range(len(structure.residues)):
        abscharges = [
            abs(structure.residues[resnr].atoms[idx].charge)
            for idx in range(len(structure.residues[resnr].atoms))
        ]
        if sum(abscharges) == 0:
            raise Exception(
                'Error: Residue %s in cyclohexane-ethanol test system has a charge of zero, which is incorrect.'
                % resnr)
Esempio n. 9
0
def sanitizeSMILES(smiles_list, mode='drop', verbose=False):
    """
    Sanitize set of SMILES strings by ensuring all are canonical isomeric SMILES.
    Duplicates are also removed.

    Parameters
    ----------
    smiles_list : iterable of str
        The set of SMILES strings to sanitize.
    mode : str, optional, default='drop'
        When a SMILES string that does not correspond to canonical isomeric SMILES is found, select the action to be performed.
        'exception' : raise an `Exception`
        'drop' : drop the SMILES string
        'expand' : expand all stereocenters into multiple molecules
    verbose : bool, optional, default=False
        If True, print verbose output.

    Returns
    -------
    sanitized_smiles_list : list of str
         Sanitized list of canonical isomeric SMILES strings.

    Examples
    --------
    Sanitize a simple list.
    >>> smiles_list = ['CC', 'CCC', '[H][C@]1(NC[C@@H](CC1CO[C@H]2CC[C@@H](CC2)O)N)[H]']
    Throw an exception if undefined stereochemistry is present.
    >>> sanitized_smiles_list = sanitizeSMILES(smiles_list, mode='exception')
    Traceback (most recent call last):
      ...
    Exception: Molecule '[H][C@]1(NC[C@@H](CC1CO[C@H]2CC[C@@H](CC2)O)N)[H]' has undefined stereocenters
    Drop molecules iwth undefined stereochemistry.
    >>> sanitized_smiles_list = sanitizeSMILES(smiles_list, mode='drop')
    >>> len(sanitized_smiles_list)
    2
    Expand molecules iwth undefined stereochemistry.
    >>> sanitized_smiles_list = sanitizeSMILES(smiles_list, mode='expand')
    >>> len(sanitized_smiles_list)
    4
    """
    from openeye import oechem
    from openeye.oechem import OEGraphMol, OESmilesToMol, OECreateIsoSmiString
    from perses.tests.utils import has_undefined_stereocenters, enumerate_undefined_stereocenters
    sanitized_smiles_set = set()
    OESMILES_OPTIONS = oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_ISOMERIC | oechem.OESMILESFlag_Hydrogens  ## IVY
    for smiles in smiles_list:
        molecule = OEGraphMol()
        OESmilesToMol(molecule, smiles)

        oechem.OEAddExplicitHydrogens(molecule)

        if verbose:
            molecule.SetTitle(smiles)
            oechem.OETriposAtomNames(molecule)

        if has_undefined_stereocenters(molecule, verbose=verbose):
            if mode == 'drop':
                if verbose:
                    print("Dropping '%s' due to undefined stereocenters." % smiles)
                continue
            elif mode == 'exception':
                raise Exception("Molecule '%s' has undefined stereocenters" % smiles)
            elif mode == 'expand':
                if verbose:
                    print('Expanding stereochemistry:')
                    print('original: %s', smiles)
                molecules = enumerate_undefined_stereocenters(molecule, verbose=verbose)
                for molecule in molecules:
                    smiles_string = oechem.OECreateSmiString(molecule, OESMILES_OPTIONS)  ## IVY
                    sanitized_smiles_set.add(smiles_string)  ## IVY
                    if verbose: print('expanded: %s', smiles_string)
        else:
            # Convert to OpenEye's canonical isomeric SMILES.
            smiles_string = oechem.OECreateSmiString(molecule, OESMILES_OPTIONS) ## IVY
            sanitized_smiles_set.add(smiles_string) ## IVY

    sanitized_smiles_list = list(sanitized_smiles_set)

    return sanitized_smiles_list
Esempio n. 10
0
def generate_complex_topologies_and_positions(ligand_filename,
                                              protein_pdb_filename):
    """
    Generate the topologies and positions for complex phase simulations, given an input ligand file (in supported openeye
    format) and protein pdb file. Note that the input ligand file should have coordinates placing the ligand in the binding
    site.

    Parameters
    ----------
    ligand_filename : str
        Name of the file containing ligands
    protein_pdb_filename : str
        Name of the protein pdb file

    Returns
    -------
    complex_topologies_dict : dict of smiles: md.topology
        Dictionary of topologies for various complex systems
    complex_positions_dict : dict of smiles:  [n, 3] array of Quantity
        Positions for corresponding complexes
    """
    ifs = oechem.oemolistream()
    ifs.open(ligand_filename)

    # get the list of molecules
    mol_list = [oechem.OEMol(mol) for mol in ifs.GetOEMols()]

    for idx, mol in enumerate(mol_list):
        mol.SetTitle("MOL{}".format(idx))
        oechem.OETriposAtomNames(mol)

    mol_dict = {oechem.OEMolToSmiles(mol): mol for mol in mol_list}

    ligand_topology_dict = {
        smiles: forcefield_generators.generateTopologyFromOEMol(mol)
        for smiles, mol in mol_dict.items()
    }

    protein_pdbfile = open(protein_pdb_filename, 'r')
    pdb_file = app.PDBFile(protein_pdbfile)
    protein_pdbfile.close()
    receptor_positions = pdb_file.positions
    receptor_topology = pdb_file.topology
    receptor_md_topology = md.Topology.from_openmm(receptor_topology)

    n_receptor_atoms = receptor_md_topology.n_atoms

    complex_topologies = {}
    complex_positions_dict = {}

    for smiles, ligand_topology in ligand_topology_dict.items():
        ligand_md_topology = md.Topology.from_openmm(ligand_topology)

        n_complex_atoms = ligand_md_topology.n_atoms + n_receptor_atoms
        copy_receptor_md_topology = copy.deepcopy(receptor_md_topology)

        complex_positions = unit.Quantity(np.zeros([n_complex_atoms, 3]),
                                          unit=unit.nanometers)

        complex_topology = copy_receptor_md_topology.join(ligand_md_topology)

        complex_topologies[smiles] = complex_topology

        ligand_positions = extractPositionsFromOEMol(mol_dict[smiles])

        complex_positions[:n_receptor_atoms, :] = receptor_positions
        complex_positions[n_receptor_atoms:, :] = ligand_positions

        complex_positions_dict[smiles] = complex_positions

    return complex_topologies, complex_positions_dict
Esempio n. 11
0
def initialize_confs(smiles, resolve_clash=True, do_opt=True):
    """
    From a file containing smiles strings, generate omega conformers,
       resolve steric clashes, do a quick MM opt, and write SDF output.

    Parameters
    ----------
    smiles : string
        Name of the input molecule file. Note: this isn't strictly limited
        to SMILES files, can also work with SDF, MOL2, etc. The file can be in
        a different location than the directory of which this function is
        called. The output SDF and txt files will be placed in the directory
        of which the function is called.
    resolve_clash : Boolean
        True to resolve steric clashes by geometry optimization using OESzybki
    do_opt : Boolean
        True to run quick geometry optimization using OESzybki with MMFF94S
        force field and Sheffield solvent model

    """
    base, extension = os.path.splitext(os.path.basename(smiles))
    if extension == '.sdf':
        base = base + '_quanformer'
    sdfout = base + '.sdf'

    ### Read in smiles file.
    ifs = oechem.oemolistream()
    if not ifs.open(smiles):
        oechem.OEThrow.Warning("Unable to open %s for reading" % smiles)

    ### Open output file to write molecules.
    ofs = oechem.oemolostream()
    if os.path.exists(sdfout):
        print(
            "Output .sdf file already exists. Exiting initialize_confs.\n{}\n".
            format(os.path.abspath(sdfout)))
        return
    if not ofs.open(sdfout):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % sdfout)

    ### Output files detailing number of resolved clashes
    ###   and original number of conformers before MM opt.
    conffile = open('numConfs.txt', 'a')
    conffile.write("Number of original conformers\n")

    ### For each molecule: label atoms, generate confs, resolve clashes, optimize.
    for smimol in ifs.GetOEMols():
        oechem.OETriposAtomNames(smimol)
        oechem.OEAddExplicitHydrogens(smimol)
        mol = generate_confs(smimol)
        if mol is None:
            continue
        conffile.write("%s\t%s\n" % (mol.GetTitle(), mol.NumConfs()))

        for i, conf in enumerate(mol.GetConfs()):
            print(mol.GetTitle(), i + 1)
            ### Resolve bad clashes.
            if resolve_clash:
                print("Resolving bad clashes...")
                if not resolve_clashes(conf, "numClashes.txt"):
                    print('Resolving bad clashes failed for molecule %s \
conformer %d:' % (mol.GetTitle(), i + 1))
                    continue
            ### MM optimization.
            if do_opt:
                print("Doing a quick MM (SD) optimization...")
                if not quick_opt(conf):
                    print('Quick optimization failed for molecule %s \
conformer %d:' % (mol.GetTitle(), i + 1))
                    continue
        oechem.OEWriteConstMolecule(ofs, mol)

    ### Close files.
    ifs.close()
    ofs.close()
    conffile.close()
Esempio n. 12
0
def smi2confs(smiles, resClash=True, quickOpt=True):
    """
    From a file containing smiles strings, generate omega conformers,
       resolve steric clashes, do a quick MM opt, and write SDF output.

    Parameters
    ----------
    smiles: str - PATH+name of the smiles file.
    resClash: boolean - Resolve steric clashes or not.
    quickOpt: boolean - QuickOpt or not.

    """
    wdir, fname = os.path.split(smiles)
    base, extension = os.path.splitext(fname)
    sdfout = base + '.sdf'
    os.chdir(wdir)

    ### Read in smiles file.
    ifs = oechem.oemolistream()
    if not ifs.open(smiles):
        oechem.OEThrow.Warning("Unable to open %s for reading" % smiles)

    ### Open output file to write molecules.
    ofs = oechem.oemolostream()
    if os.path.exists(sdfout):
        #sys.exit("Output .sdf file already exists. Exiting.\n")
        print("Output .sdf file already exists. Exiting.\n")
        return
    if not ofs.open(sdfout):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % sdfout)

    ### Output files detailing number of resolved clashes
    ###   and original number of conformers before MM opt.
    conffile = open('numConfs.txt', 'a')
    conffile.write("Number of original conformers\n")

    ### For each molecule: label atoms, generate confs, resolve clashes, optimize.
    for smimol in ifs.GetOEMols():
        oechem.OETriposAtomNames(smimol)
        mol = GenerateConfs(smimol)
        conffile.write("%s\t%s\n" % (mol.GetTitle(), mol.NumConfs()))

        for i, conf in enumerate(mol.GetConfs()):
            print(mol.GetTitle(), i + 1)
            ### Resolve bad clashes.
            if resClash:
                print("Resolving bad clashes...")
                if not ResolveBadClashes(conf, "numClashes.txt"):
                    print('Resolving bad clashes failed for molecule %s \
conformer %d:' % (mol.GetTitle(), i + 1))
                    continue
            ### MM optimization.
            if quickOpt:
                print("Doing a quick MM (SD) optimization...")
                if not QuickOpt(conf):
                    print('Quick optimization failed for molecule %s \
conformer %d:' % (mol.GetTitle(), i + 1))
                    continue
        oechem.OEWriteConstMolecule(ofs, mol)

    ### Close files.
    ifs.close()
    ofs.close()
    conffile.close()
            oechem.OEWriteMolecule(ofs, receptor)

    # Filter out receptor atoms with atom names of UNK
    for atom in receptor.GetAtoms():
        if atom.GetName() == 'UNK':
            receptor.DeleteAtom(atom)

    # Write joined PDB with ligand and receptor
    output_filename = os.path.join(docking_basedir, f'{molecule.GetTitle()} - complex.pdb')
    if not os.path.exists(output_filename):
        with oechem.oemolostream(output_filename) as ofs:
            oechem.OEClearResidues(docked_molecule)

            #oechem.OEWriteMolecule(ofs, docked_molecule)

            oechem.OETriposAtomNames(docked_molecule)
            oechem.OEWritePDBFile(ofs, docked_molecule, oechem.OEOFlavor_PDB_Default | oechem.OEOFlavor_PDB_BONDS)

            set_serial(receptor, 'X', docked_molecule.NumAtoms()+1)
            #oechem.OEWritePDBFile(ofs, receptor, oechem.OEOFlavor_PDB_Default | oechem.OEOFlavor_PDB_BONDS)

            oechem.OEWriteMolecule(ofs, receptor)

    # Write PDB of just ligand
    output_filename = os.path.join(docking_basedir, f'{molecule.GetTitle()} - ligand.pdb')
    if not os.path.exists(output_filename):
        with oechem.oemolostream(output_filename) as ofs:
            oechem.OEClearResidues(docked_molecule)

            #oechem.OEWriteMolecule(ofs, docked_molecule)
Esempio n. 14
0
# Load molecule and create pdb object
pdb = PDBFile(pdb_filename)

# Load a SMIRNOFF force field
forcefield = ForceField(
    get_data_file_path('test_forcefields/Frosst_AlkEthOH_parmAtFrosst.offxml'))

# Load molecule using OpenEye tools
mol = oechem.OEGraphMol()
ifs = oechem.oemolistream(mol_filename)
# LPW: I don't understand the meaning of these lines.
# flavor = oechem.OEIFlavor_Generic_Default | oechem.OEIFlavor_MOL2_Default | oechem.OEIFlavor_MOL2_Forcefield
# ifs.SetFlavor( oechem.OEFormat_MOL2, flavor)
oechem.OEReadMolecule(ifs, mol)
oechem.OETriposAtomNames(mol)

# Create the OpenMM system
system = forcefield.createSystem(pdb.topology, [mol],
                                 nonbondedMethod=PME,
                                 nonbondedCutoff=1.0 * unit.nanometers,
                                 rigidWater=True)

# Set up an OpenMM simulation
integrator = openmm.LangevinIntegrator(temperature, friction, time_step)
platform = openmm.Platform.getPlatformByName('CUDA')
simulation = Simulation(pdb.topology, system, integrator)
simulation.context.setPositions(pdb.positions)
simulation.context.setVelocitiesToTemperature(temperature)
netcdf_reporter = NetCDFReporter('water_traj.nc', trj_freq)
simulation.reporters.append(netcdf_reporter)
Esempio n. 15
0
from openeye import oeiupac
from openeye import oequacpac

# Create molecules.
for resname in molecules:
    name = molecules[resname]
    print name

    # Create molecule from IUPAC name.
    molecule = oechem.OEMol()
    oeiupac.OEParseIUPACName(molecule, name)
    molecule.SetTitle(name)

    # Normalize molecule.
    oechem.OEAddExplicitHydrogens(molecule)
    oechem.OETriposAtomNames(molecule)
    oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye)

    # Create configuration.
    omega = oeomega.OEOmega()
    omega.SetStrictStereo(True)
    omega.SetIncludeInput(False)
    omega(molecule)

    # Create charges.
    oequacpac.OEAssignPartialCharges(molecule, oequacpac.OECharges_AM1BCCSym)

    # Write molecule.
    filename = '%s.tripos.mol2' % name
    print filename
    ofs = oechem.oemolostream()
Esempio n. 16
0
def generateOEMolFromTopologyResidue(residue,
                                     geometry=False,
                                     tripos_atom_names=False):
    """
    Generate an OpenEye OEMol molecule from an OpenMM Topology Residue.

    Parameters
    ----------
    residue : simtk.openmm.app.topology.Residue
        The topology Residue from which an OEMol is to be created.
        An Exception will be thrown if this residue has external bonds.
    geometry : bool, optional, default=False
        If True, will generate a single configuration with OEOmega.
        Note that stereochemistry will be *random*.
    tripos_atom_names : bool, optional, default=False
        If True, will generate and assign Tripos atom names.

    Returns
    -------
    molecule : openeye.oechem.OEMol
        The OEMol molecule corresponding to the topology.
        Atom order will be preserved and bond orders assigned.

    The Antechamber `bondtype` program will be used to assign bond orders, and these
    will be converted back into OEMol bond type assignments.

    Note that there is no way to preserve stereochemistry since `Residue` does
    not note stereochemistry in any way.

    """
    # Raise an Exception if this residue has external bonds.
    if len(list(residue.external_bonds())) > 0:
        raise Exception(
            "Cannot generate an OEMol from residue '%s' because it has external bonds."
            % residue.name)

    from openeye import oechem
    # Create OEMol where all atoms have bond order 1.
    molecule = oechem.OEMol()
    molecule.SetTitle(residue.name)  # name molecule after first residue
    for atom in residue.atoms():
        oeatom = molecule.NewAtom(atom.element.atomic_number)
        oeatom.SetName(atom.name)
        oeatom.AddData("topology_index", atom.index)
    oeatoms = {oeatom.GetName(): oeatom for oeatom in molecule.GetAtoms()}
    for (atom1, atom2) in residue.bonds():
        order = 1
        molecule.NewBond(oeatoms[atom1.name], oeatoms[atom2.name], order)

    # Write out a mol2 file without altering molecule.
    import tempfile
    tmpdir = tempfile.mkdtemp()
    mol2_input_filename = os.path.join(tmpdir,
                                       'molecule-before-bond-perception.mol2')
    ac_output_filename = os.path.join(tmpdir,
                                      'molecule-after-bond-perception.ac')
    ofs = oechem.oemolostream(mol2_input_filename)
    m2h = True
    substruct = False
    oechem.OEWriteMol2File(ofs, molecule, m2h, substruct)
    ofs.close()
    # Run Antechamber bondtype
    import subprocess
    #command = 'bondtype -i %s -o %s -f mol2 -j full' % (mol2_input_filename, ac_output_filename)
    command = 'antechamber -i %s -fi mol2 -o %s -fo ac -j 2' % (
        mol2_input_filename, ac_output_filename)
    [status, output] = getstatusoutput(command)

    # Define mapping from GAFF bond orders to OpenEye bond orders.
    order_map = {1: 1, 2: 2, 3: 3, 7: 1, 8: 2, 9: 5, 10: 5}
    # Read bonds.
    infile = open(ac_output_filename)
    lines = infile.readlines()
    infile.close()
    antechamber_bond_types = list()
    for line in lines:
        elements = line.split()
        if elements[0] == 'BOND':
            antechamber_bond_types.append(int(elements[4]))
    oechem.OEClearAromaticFlags(molecule)
    for (bond, antechamber_bond_type) in zip(molecule.GetBonds(),
                                             antechamber_bond_types):
        #bond.SetOrder(order_map[antechamber_bond_type])
        bond.SetIntType(order_map[antechamber_bond_type])
    oechem.OEFindRingAtomsAndBonds(molecule)
    oechem.OEKekulize(molecule)
    oechem.OEAssignFormalCharges(molecule)
    oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye)

    # Clean up.
    os.unlink(mol2_input_filename)
    os.unlink(ac_output_filename)
    os.rmdir(tmpdir)

    # Generate Tripos atom names if requested.
    if tripos_atom_names:
        oechem.OETriposAtomNames(molecule)

    # Assign geometry
    if geometry:
        from openeye import oeomega
        omega = oeomega.OEOmega()
        omega.SetMaxConfs(1)
        omega.SetIncludeInput(False)
        omega.SetStrictStereo(False)
        omega(molecule)

    return molecule
def build_mixture_prmtop(gaff_mol2_filenames, box_filename, out_top, out_gro,
                         ffxml):
    """Analog of openmoltools.amber.build_mixture_prmtop which uses SMIRNOFF forcefield (from github.com/open-forcefield-group/smarty) to parameterize small molecules, rather than GAFF.

Parameters
----------
mol2_filenames : list(str)
    Filenames of GAFF flavored mol2 files.  Each must contain exactly
    ONE solute.
box_filename : str
    Filename of PDB containing an arbitrary box of the mol2 molecules.
out_top : str
    output GROMACS topology filename.  Should have suffix .top
out_gro : str
    output gro filename.  Should have suffix .gro
ffxml : str
    filename containing input SMIRNOFF FFXML file for use in parameterizing the system


Returns
-------
success : bool
    True or False as to success of operation

Notes
-----
This can be easily broken if there are missing, duplicated, or
inconsistent ligand residue names in your box, mol2, and frcmod files.
You can use mdtraj to edit the residue names with something like
this: trj.top.residue(0).name = "L1"
"""
    from openeye import oechem
    from openforcefield.typing.engines.smirnoff import ForceField, PME
    from openforcefield.utils import read_molecules, get_data_filename, generateTopologyFromOEMol

    # Read in molecules
    oemols = []
    for mol2file in set(gaff_mol2_filenames):
        mol = oechem.OEGraphMol()
        ifs = oechem.oemolistream(mol2file)
        flavor = oechem.OEIFlavor_Generic_Default | oechem.OEIFlavor_MOL2_Default | oechem.OEIFlavor_MOL2_Forcefield
        ifs.SetFlavor(oechem.OEFormat_MOL2, flavor)
        oechem.OEReadMolecule(ifs, mol)
        oechem.OETriposAtomNames(mol)
        oemols.append(mol)

    # Read in PDB file to get topology
    pdb = app.PDBFile(box_filename)

    # Load forcefield
    ff = ForceField(ffxml)

    # Construct system; charging not needed as mol2 files already have charges here
    system = ff.createSystem(pdb.topology,
                             oemols,
                             nonbondedMethod=PME,
                             nonbondedCutoff=CUTOFF)

    # Dump to AMBER format
    structure = parmed.openmm.topsystem.load_topology(pdb.topology, system,
                                                      pdb.positions)
    structure.save(out_top, overwrite=True)
    structure.save(out_gro, overwrite=True)

    return True