コード例 #1
0
ファイル: nonbonded.py プロジェクト: fehomi/timemachine
def oe_assign_charges(mol, charge_model="AM1BCCELF10"):
    """assign partial charges, then premultiply by sqrt(ONE_4PI_EPS0)
    as an optimization"""

    # imported here for optional dependency
    from openeye import oequacpac

    charge_engines = {
        "AM1": oequacpac.OEAM1Charges(symmetrize=True),
        "AM1BCC": oequacpac.OEAM1BCCCharges(symmetrize=True),
        "AM1BCCELF10": oequacpac.OEAM1BCCELF10Charges(),
    }
    charge_engine = charge_engines[charge_model]

    oemol = convert_to_oe(mol)
    result = oequacpac.OEAssignCharges(oemol, charge_engine)
    if result is False:
        raise Exception("Unable to assign charges")

    partial_charges = np.array(
        [atom.GetPartialCharge() for atom in oemol.GetAtoms()])

    # https://github.com/proteneer/timemachine#forcefield-gotchas
    # "The charges have been multiplied by sqrt(ONE_4PI_EPS0) as an optimization."
    inlined_constant = np.sqrt(constants.ONE_4PI_EPS0)

    return inlined_constant * partial_charges
コード例 #2
0
def prep_structure(rdmol):
    mb = Chem.MolToMolBlock(rdmol)
    ims = oechem.oemolistream()
    ims.SetFormat(oechem.OEFormat_SDF)
    ims.openstring(mb)

    for buf_mol in ims.GetOEMols():
        oemol = oechem.OEMol(buf_mol)

    omega = oeomega.OEOmega()
    # omega.SetIncludeInput(True)
    omega.SetMaxSearchTime(30)
    omega.SetCanonOrder(False)
    omega.SetSampleHydrogens(True)
    eWindow = 15.0
    omega.SetEnergyWindow(eWindow)
    # omega.SetMaxConfs(800)
    omega.SetMaxConfs(400)
    omega.SetRMSThreshold(1.0)

    if omega(oemol):
        result = oequacpac.OEAssignCharges(oemol,
                                           oequacpac.OEAM1BCCELF10Charges())
        if result is False:
            return None
        else:
            charges = []
            for index, atom in enumerate(oemol.GetAtoms()):
                q = atom.GetPartialCharge() * np.sqrt(ONE_4PI_EPS0)
                charges.append(q)
            return charges
    else:
        return None
コード例 #3
0
    def static_parameterize(mol):
        """
        Parameters
        ----------

        mol: Chem.ROMol
            molecule to be parameterized.

        """
        # imported here for optional dependency
        from openeye import oechem
        from openeye import oequacpac

        mb = Chem.MolToMolBlock(mol)
        ims = oechem.oemolistream()
        ims.SetFormat(oechem.OEFormat_SDF)
        ims.openstring(mb)

        for buf_mol in ims.GetOEMols():
            oemol = oechem.OEMol(buf_mol)

        result = oequacpac.OEAssignCharges(oemol,
                                           oequacpac.OEAM1BCCELF10Charges())

        if result is False:
            raise Exception('Unable to assign charges')

        charges = []
        for index, atom in enumerate(oemol.GetAtoms()):
            q = atom.GetPartialCharge() * np.sqrt(constants.ONE_4PI_EPS0)
            charges.append(q)

        return np.array(charges)
コード例 #4
0
def prep_structure(rdmol):
    oemol = convert_to_oe(rdmol)
    omega = oeomega.OEOmega()
    # omega.SetIncludeInput(True)
    omega.SetMaxSearchTime(30)
    omega.SetCanonOrder(False)
    omega.SetSampleHydrogens(True)
    eWindow = 15.0
    omega.SetEnergyWindow(eWindow)
    # omega.SetMaxConfs(800)
    omega.SetMaxConfs(400)
    omega.SetRMSThreshold(1.0)

    if omega(oemol):
        result = oequacpac.OEAssignCharges(oemol,
                                           oequacpac.OEAM1BCCELF10Charges())
        if result is False:
            return None
        else:
            charges = []
            for index, atom in enumerate(oemol.GetAtoms()):
                q = atom.GetPartialCharge() * np.sqrt(ONE_4PI_EPS0)
                charges.append(q)
            return charges
    else:
        return None
コード例 #5
0
ファイル: charge_mols.py プロジェクト: vtlim/misc
def charge_mols(infile, outfile, reffile=None):

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

    ### Open output file
    ofs = oechem.oemolostream()
    if not ofs.open(outfile):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % outfile)

    ### Charge the molecules and write output
    if reffile is None:
        for mol in ifs.GetOEMols():
            if not oequacpac.OEAssignCharges(mol,
                                             oequacpac.OEAM1BCCELF10Charges()):
                oechem.OEThrow.Warning("Unable to charge mol {}".format(
                    mol.GetTitle()))
            oechem.OEWriteConstMolecule(ofs, mol)
        ifs.close()
        ofs.close()
    else:
        ### Read in molecules
        rfs = oechem.oemolistream()
        if not rfs.open(reffile):
            oechem.OEThrow.Warning("Unable to open %s for reading" % reffile)
            return
        ### Set coordinates of desired molecule on the mol with charges
        for in_mol, ref_mol in zip(ifs.GetOEMols(), rfs.GetOEMols()):
            ref_mol.SetCoords(in_mol.GetCoords())
            oechem.OEWriteConstMolecule(ofs, ref_mol)
        ifs.close()
        ofs.close()
コード例 #6
0
def charge_mol(mol, omega):
    """Generate conformers and assign AM1BCCELF10 charges to mol"""
    if omega(mol):
        #black box function to assign charges to a molecule
        oequacpac.OEAssignCharges(mol, oequacpac.OEAM1BCCELF10Charges())
    else:
        print("Failed to generate conformation(s) for molecule %s" %
              mol.GetTitle())
コード例 #7
0
def ParameterizeOE(path):
    """
    Reads in the PDB from 'RunDocking' and outputs 'charged.mol2' of the ligand
    Then runs antechamber to convert this to coordinate (.inpcrd) and 
    parameter (.prmtop) files.
    """
    from openeye import oechem, oeomega, oequacpac
    mol = oechem.OEMol()
    ifs = oechem.oemolistream()
    if ifs.open(f'{path}/lig.pdb'):
        oechem.OEReadMolecule(ifs, mol)
        ifs.close()
    if not oequacpac.OEAssignCharges(mol, oequacpac.OEAM1BCCCharges()):
        raise (RuntimeError("OEAssignCharges failed."))
    ofs = oechem.oemolostream()
    if ofs.open(f'{path}/charged.mol2'):
        oechem.OEWriteMolecule(ofs, mol)

    import subprocess
    with working_directory(path):
        subprocess.check_output(
            f'antechamber -i lig.pdb -fi pdb -o lig.mol2 -fo mol2 -pf y -an y -a charged.mol2 -fa mol2 -ao crg',
            shell=True)
        subprocess.check_output(f'parmchk2 -i lig.mol2 -f mol2 -o lig.frcmod',
                                shell=True)
        # Wrap tleap
        with open(f'leap.in', 'w+') as leap:
            leap.write("source leaprc.protein.ff14SBonlysc\n")
            leap.write("source leaprc.gaff\n")
            leap.write("source leaprc.water.tip3p\n")
            leap.write("set default PBRadii mbondi3\n")
            leap.write("rec = loadPDB apo.pdb # May need full filepath?\n")
            leap.write("saveAmberParm rec apo.prmtop apo.inpcrd\n")
            leap.write("lig = loadmol2 lig.mol2\n")
            leap.write("loadAmberParams lig.frcmod\n")
            leap.write("com = combine {rec lig}\n")
            leap.write("saveAmberParm lig lig.prmtop lig.inpcrd\n")
            leap.write("saveAmberParm com com.prmtop com.inpcrd\n")
            leap.write("savepdb com com.pdb\n")
            leap.write("addIons2 rec NA 0\n")
            leap.write("addIons2 rec CL 0\n")
            leap.write("solvateBox rec TIP3PBOX 14\n")
            leap.write("savepdb rec apo_sol.pdb\n")
            leap.write("saveAmberParm rec apo_sol.prmtop apo_sol.inpcrd\n")
            leap.write("addIons2 lig NA 0\n")
            leap.write("addIons2 lig CL 0\n")
            leap.write("solvateBox lig TIP3PBOX 14\n")
            leap.write("savepdb lig lig_sol.pdb\n")
            leap.write("saveAmberParm lig lig_sol.prmtop lig_sol.inpcrd\n")
            leap.write("addIons2 com NA 0\n")
            leap.write("addIons2 com CL 0\n")
            leap.write("solvateBox com TIP3PBOX 14\n")
            leap.write("savepdb com com_sol.pdb\n")
            leap.write("saveAmberParm com com_sol.prmtop com_sol.inpcrd\n")
            leap.write("quit\n")
        subprocess.check_output(f'tleap -f leap.in', shell=True)
コード例 #8
0
def test_improper_pyramidal(verbose=False):
    """Test implement of impropers on ammonia."""
    from openeye import oeomega
    from openeye import oequacpac
    from oeommtools.utils import oemol_to_openmmTop, openmmTop_to_oemol
    from openforcefield.utils import get_data_file_path, extractPositionsFromOEMol
    # Prepare ammonia
    mol = oechem.OEMol()
    oechem.OESmilesToMol(mol, 'N')
    oechem.OEAddExplicitHydrogens(mol)
    omega = oeomega.OEOmega()
    omega.SetMaxConfs(100)
    omega.SetIncludeInput(False)
    omega.SetStrictStereo(False)
    # Generate charges
    chargeEngine = oequacpac.OEAM1BCCCharges()
    status = omega(mol)
    oequacpac.OEAssignCharges(mol, chargeEngine)
    # Assign atom names
    oechem.OETriposAtomTypes(mol)
    oechem.OETriposAtomNames(mol)
    # Set up minimization
    ff = ForceField('test_forcefields/ammonia_minimal.offxml')
    topology, positions = oemol_to_openmmTop(mol)
    system = ff.createSystem(topology, [mol], verbose=verbose)
    positions = extractPositionsFromOEMol(mol)
    integrator = openmm.VerletIntegrator(2.0 * unit.femtoseconds)
    simulation = app.Simulation(topology, system, integrator)
    simulation.context.setPositions(positions)
    # Minimize energy
    simulation.minimizeEnergy()
    state = simulation.context.getState(getEnergy=True, getPositions=True)
    energy = state.getPotentialEnergy() / unit.kilocalories_per_mole
    newpositions = state.getPositions()
    outmol = openmmTop_to_oemol(topology, state.getPositions())
    # Sum angles around the N atom
    for atom in outmol.GetAtoms(oechem.OEIsInvertibleNitrogen()):
        aidx = atom.GetIdx()
        nbors = list(atom.GetAtoms())
        ang1 = math.degrees(oechem.OEGetAngle(outmol, nbors[0], atom,
                                              nbors[1]))
        ang2 = math.degrees(oechem.OEGetAngle(outmol, nbors[1], atom,
                                              nbors[2]))
        ang3 = math.degrees(oechem.OEGetAngle(outmol, nbors[2], atom,
                                              nbors[0]))
    ang_sum = math.fsum([ang1, ang2, ang3])
    # Check that sum of angles around N is within 1 degree of 353.5
    if abs(ang_sum - 353.5) > 1.0:
        raise Exception(
            "Improper torsion for ammonia differs too much from reference partly pyramidal geometry."
            "The reference case has a sum of H-N-H angles (3x) at 353.5 degrees; the test case has a sum of {}."
            .format(ang_sum))
コード例 #9
0
ファイル: ff_utils.py プロジェクト: zeromtmu/openmm_orion
def assignELF10charges(molecule, max_confs=800, strictStereo=True):
    """
     This function computes atomic partial charges for an OEMol by
     using the ELF10 method

    Parameters:
    -----------
    molecule : OEMol object
        The molecule that needs to be charged
    max_confs : integer
        The max number of conformers used to calculate the atomic partial charges
    strictStereo : bool
        a flag used to check if atoms need to have assigned stereo chemistry or not

    Return:
    -------
    mol_copy : OEMol
        a copy of the original molecule with assigned atomic partial charges
    """

    mol_copy = molecule.CreateCopy()

    # The passed molecule could have already conformers. If the conformer number
    # does not exceed the max_conf threshold then max_confs conformations will
    # be generated
    if not mol_copy.GetMaxConfIdx() > 200:
        # Generate up to max_confs conformers
        mol_copy = generate_conformers(mol_copy,
                                       max_confs=max_confs,
                                       strictStereo=strictStereo)

    # Assign MMFF Atom types
    if not oechem.OEMMFFAtomTypes(mol_copy):
        raise RuntimeError("MMFF atom type assignment returned errors")

    # ELF10 charges
    status = oequacpac.OEAssignCharges(mol_copy,
                                       oequacpac.OEAM1BCCELF10Charges())

    if not status:
        raise RuntimeError("OEAssignCharges returned error code %d" % status)

    return mol_copy
コード例 #10
0
def AssignChargesByName(mol, name):
    if name == "noop":
        return oequacpac.OEAssignCharges(mol, oequacpac.OEChargeEngineNoOp())
    elif name == "mmff" or name == "mmff94":
        return oequacpac.OEAssignCharges(mol, oequacpac.OEMMFF94Charges())
    elif name == "am1bcc":
        return oequacpac.OEAssignCharges(mol, oequacpac.OEAM1BCCCharges())
    elif name == "am1bccnosymspt":
        optimize = True
        symmetrize = True
        return oequacpac.OEAssignCharges(
            mol, oequacpac.OEAM1BCCCharges(not optimize, not symmetrize))
    elif name == "amber" or name == "amberff94":
        return oequacpac.OEAssignCharges(mol, oequacpac.OEAmberFF94Charges())
    elif name == "am1bccelf10":
        return oequacpac.OEAssignCharges(mol, oequacpac.OEAM1BCCELF10Charges())
    return False
コード例 #11
0
    def prepare_ligand(self, lig):
        with self.logger("prepare_ligand") as logger:
            ## prepare ligand
            oemol = oechem.OEMol(lig)
            oemol.SetTitle("UNL")
            oechem.OEAddExplicitHydrogens(oemol)

            ofs = oechem.oemolostream(f'{self.dirpath}/lig.mol2')
            oechem.OEWriteMolecule(ofs, oemol)
            ofs.close()

            ofs = oechem.oemolostream(f'{self.dirpath}/lig.pdb')
            oechem.OEWriteMolecule(ofs, oemol)
            ofs.close()

            self.lig = oechem.OEMol(oemol)

            oequacpac.OEAssignCharges(oemol, oequacpac.OEAM1BCCCharges())

            ofs = oechem.oemolostream(f'{self.dirpath}/charged.mol2')
            oechem.OEWriteMolecule(ofs, oemol)
            ofs.close()

            self.charged_lig = oechem.OEMol(oemol)
コード例 #12
0
    omega.SetCanonOrder(False)

    omega.SetStrictStereo(False)
    omega.SetStrictAtomTypes(False)

    omega.SetSampleHydrogens(
        True
    )  # Word to the wise: skipping this step can lead to significantly different charges!
    omega.SetEnergyWindow(15.0)
    omega.SetRMSThreshold(
        1.0
    )  # Word to the wise: skipping this step can lead to significantly different charges!

    if omega(mol_multiconf):  # generate conformation
        # Generate am1bcc partial charges
        oequacpac.OEAssignCharges(mol_multiconf,
                                  oequacpac.OEAM1BCCELF10Charges())

        # Get total charge
        conf = mol_multiconf.GetConf(oechem.OEHasConfIdx(0))
        absFCharge = 0
        sumFCharge = 0
        sumPCharge = 0.0
        for atm in mol_multiconf.GetAtoms():
            sumFCharge += atm.GetFormalCharge()
            absFCharge += abs(atm.GetFormalCharge())
            sumPCharge += atm.GetPartialCharge()
        oechem.OEThrow.Info(
            "%s: %d formal charges give total charge %d ; Sum of Partial Charges %5.4f"
            % (mol_multiconf.GetTitle(), absFCharge, sumFCharge, sumPCharge))

        # Output file
コード例 #13
0
ファイル: utils.py プロジェクト: zeromtmu/openmm_orion
def applyffExcipients(excipients, opt):
    """
    This function applies the selected force field to the
    excipients

    Parameters:
    -----------
    excipients: OEMol molecule
        The excipients molecules to parametrize
    opt: python dictionary
        The options used to parametrize the excipients

    Return:
    -------
    excipient_structure: Parmed structure instance
        The parametrized excipient parmed structure
    """

    # OpenMM topology and positions from OEMol
    topology, positions = oeommutils.oemol_to_openmmTop(excipients)

    # Try to apply the selected FF on the excipients
    forcefield = app.ForceField(opt['protein_forcefield'])

    # List of the unrecognized excipients
    unmatched_res_list = forcefield.getUnmatchedResidues(topology)

    # Unique unrecognized excipient names
    templates = set()
    for res in unmatched_res_list:
        templates.add(res.name)

    if templates:  # Some excipients are not recognized
        oechem.OEThrow.Info("The following excipients are not recognized "
                            "by the protein FF: {}"
                            "\nThey will be parametrized by using the FF: {}".format(templates, opt['other_forcefield']))

        # Create a bit vector mask used to split recognized from un-recognize excipients
        bv = oechem.OEBitVector(excipients.GetMaxAtomIdx())
        bv.NegateBits()

        # Dictionary containing the name and the parmed structures of the unrecognized excipients
        unrc_excipient_structures = {}

        # Dictionary used to skip already selected unrecognized excipients and count them
        unmatched_excp = {}

        # Ordered list of the unrecognized excipients
        unmatched_res_order = []

        for r_name in templates:
            unmatched_excp[r_name] = 0

        hv = oechem.OEHierView(excipients)

        for chain in hv.GetChains():
            for frag in chain.GetFragments():
                for hres in frag.GetResidues():
                    r_name = hres.GetOEResidue().GetName()
                    if r_name not in unmatched_excp:
                        continue
                    else:
                        unmatched_res_order.append(r_name)
                        if unmatched_excp[r_name]:  # Test if we have selected the unknown excipient
                            # Set Bit mask
                            atms = hres.GetAtoms()
                            for at in atms:
                                bv.SetBitOff(at.GetIdx())
                            unmatched_excp[r_name] += 1
                        else:
                            unmatched_excp[r_name] = 1
                            #  Create AtomBondSet to extract from the whole excipient system
                            #  the current selected FF unknown excipient
                            atms = hres.GetAtoms()
                            bond_set = set()
                            for at in atms:
                                bv.SetBitOff(at.GetIdx())
                                bonds = at.GetBonds()
                                for bond in bonds:
                                    bond_set.add(bond)
                            atom_bond_set = oechem.OEAtomBondSet(atms)
                            for bond in bond_set:
                                atom_bond_set.AddBond(bond)

                            # Create the unrecognized excipient OEMol
                            unrc_excp = oechem.OEMol()
                            if not oechem.OESubsetMol(unrc_excp, excipients, atom_bond_set):
                                oechem.OEThrow.Fatal("Is was not possible extract the residue: {}".format(r_name))

                            # Charge the unrecognized excipient
                            if not oequacpac.OEAssignCharges(unrc_excp,
                                                             oequacpac.OEAM1BCCCharges(symmetrize=True)):
                                oechem.OEThrow.Fatal("Is was not possible to "
                                                     "charge the extract residue: {}".format(r_name))

                            # If GAFF or GAFF2 is selected as FF check for tleap command
                            if opt['other_forcefield'] in ['GAFF', 'GAFF2']:
                                ff_utils.ParamLigStructure(oechem.OEMol(), opt['other_forcefield']).checkTleap

                            if opt['other_forcefield'] == 'SMIRNOFF':
                                unrc_excp = oeommutils.sanitizeOEMolecule(unrc_excp)

                            # Parametrize the unrecognized excipient by using the selected FF
                            pmd = ff_utils.ParamLigStructure(unrc_excp, opt['other_forcefield'],
                                                             prefix_name=opt['prefix_name']+'_'+r_name)
                            unrc_excp_struc = pmd.parameterize()
                            unrc_excp_struc.residues[0].name = r_name
                            unrc_excipient_structures[r_name] = unrc_excp_struc

        # Recognized FF excipients
        pred_rec = oechem.OEAtomIdxSelected(bv)
        rec_excp = oechem.OEMol()
        oechem.OESubsetMol(rec_excp, excipients, pred_rec)

        if rec_excp.NumAtoms() > 0:
            top_known, pos_known = oeommutils.oemol_to_openmmTop(rec_excp)
            ff_rec = app.ForceField(opt['protein_forcefield'])
            try:
                omm_system = ff_rec.createSystem(top_known, rigidWater=False)
                rec_struc = parmed.openmm.load_topology(top_known, omm_system, xyz=pos_known)
            except:
                oechem.OEThrow.Fatal("Error in the recognised excipient parametrization")

        # Unrecognized FF excipients
        bv.NegateBits()
        pred_unrc = oechem.OEAtomIdxSelected(bv)
        unrc_excp = oechem.OEMol()
        oechem.OESubsetMol(unrc_excp, excipients, pred_unrc)

        # Unrecognized FF excipients coordinates
        oe_coord_dic = unrc_excp.GetCoords()
        unrc_coords = np.ndarray(shape=(unrc_excp.NumAtoms(), 3))
        for at_idx in oe_coord_dic:
            unrc_coords[at_idx] = oe_coord_dic[at_idx]

        # It is important the order used to assemble the structures. In order to
        # avoid mismatch between the coordinates and the structures, it is convenient
        # to use the unrecognized residue order
        unmatched_res_order_count = []
        i = 0
        while i < len(unmatched_res_order):
            res_name = unmatched_res_order[i]
            for j in range(i+1, len(unmatched_res_order)):
                if unmatched_res_order[j] == res_name:
                    continue
                else:
                    break
            if i == (len(unmatched_res_order) - 1):
                num = 1
                unmatched_res_order_count.append((res_name, num))
                break
            else:
                num = j - i
                unmatched_res_order_count.append((res_name, num))
                i = j

        # Merge all the unrecognized Parmed structure
        unrc_struc = parmed.Structure()

        for pair in unmatched_res_order_count:
            res_name = pair[0]
            nums = pair[1]
            unrc_struc = unrc_struc + nums*unrc_excipient_structures[res_name]

        # Set the unrecognized coordinates
        unrc_struc.coordinates = unrc_coords

        # Set the parmed excipient structure merging
        # the unrecognized and recognized parmed
        # structures together
        if rec_excp.NumAtoms() > 0:
            excipients_structure = unrc_struc + rec_struc
        else:
            excipients_structure = unrc_struc

        return excipients_structure
    else:  # All the excipients are recognized by the selected FF
        omm_system = forcefield.createSystem(topology, rigidWater=False)
        excipients_structure = parmed.openmm.load_topology(topology, omm_system, xyz=positions)

        return excipients_structure
コード例 #14
0
ファイル: chemi.py プロジェクト: dgasmith/fragmenter
def get_charges(molecule,
                max_confs=800,
                strict_stereo=True,
                normalize=True,
                keep_confs=None,
                legacy=True):
    """Generate charges for an OpenEye OEMol molecule.
    Parameters
    ----------
    molecule : OEMol
        Molecule for which to generate conformers.
        Omega will be used to generate max_confs conformations.
    max_confs : int, optional, default=800
        Max number of conformers to generate
    strictStereo : bool, optional, default=True
        If False, permits smiles strings with unspecified stereochemistry.
        See https://docs.eyesopen.com/omega/usage.html
    normalize : bool, optional, default=True
        If True, normalize the molecule by checking aromaticity, adding
        explicit hydrogens, and renaming by IUPAC name.
    keep_confs : int, optional, default=None
        If None, apply the charges to the provided conformation and return
        this conformation, unless no conformation is present.
        Otherwise, return some or all of the generated
        conformations. If -1, all generated conformations are returned.
        Otherwise, keep_confs = N will return an OEMol with up to N
        generated conformations.  Multiple conformations are still used to
        *determine* the charges.
    legacy : bool, default=True
        If False, uses the new OpenEye charging engine.
        See https://docs.eyesopen.com/toolkits/python/quacpactk/OEProtonFunctions/OEAssignCharges.html#
    Returns
    -------
    charged_copy : OEMol
        A molecule with OpenEye's recommended AM1BCC charge selection scheme.
    Notes
    -----
    Roughly follows
    http://docs.eyesopen.com/toolkits/cookbook/python/modeling/am1-bcc.html
    """

    # If there is no geometry, return at least one conformation.
    if molecule.GetConfs() == 0:
        keep_confs = 1

    if not oechem.OEChemIsLicensed():
        raise (ImportError("Need License for OEChem!"))
    if not oequacpac.OEQuacPacIsLicensed():
        raise (ImportError("Need License for oequacpac!"))

    if normalize:
        molecule = normalize_molecule(molecule)
    else:
        molecule = oechem.OEMol(molecule)

    charged_copy = generate_conformers(
        molecule, max_confs=max_confs,
        strict_stereo=strict_stereo)  # Generate up to max_confs conformers

    if not legacy:
        # 2017.2.1 OEToolkits new charging function
        status = oequacpac.OEAssignCharges(charged_copy,
                                           oequacpac.OEAM1BCCCharges())
        if not status: raise (RuntimeError("OEAssignCharges failed."))
    else:
        # AM1BCCSym recommended by Chris Bayly to KAB+JDC, Oct. 20 2014.
        status = oequacpac.OEAssignPartialCharges(
            charged_copy, oequacpac.OECharges_AM1BCCSym)
        if not status:
            raise (RuntimeError(
                "OEAssignPartialCharges returned error code %d" % status))

    #Determine conformations to return
    if keep_confs == None:
        #If returning original conformation
        original = molecule.GetCoords()
        #Delete conformers over 1
        for k, conf in enumerate(charged_copy.GetConfs()):
            if k > 0:
                charged_copy.DeleteConf(conf)
        #Copy coordinates to single conformer
        charged_copy.SetCoords(original)
    elif keep_confs > 0:
        logger().debug(
            "keep_confs was set to %s. Molecule positions will be reset." %
            keep_confs)

        #Otherwise if a number is provided, return this many confs if available
        for k, conf in enumerate(charged_copy.GetConfs()):
            if k > keep_confs - 1:
                charged_copy.DeleteConf(conf)
    elif keep_confs == -1:
        #If we want all conformations, continue
        pass
    else:
        #Not a valid option to keep_confs
        raise (ValueError('Not a valid option to keep_confs in get_charges.'))

    return charged_copy
コード例 #15
0
ファイル: nonbonded.py プロジェクト: skye/timemachine
    def parameterize(self, mol):
        """
        Parameters
        ----------

        mol: Chem.ROMol
            molecule to be parameterized.

        """
        # imported here for optional dependency
        from openeye import oechem
        from openeye import oequacpac

        mb = Chem.MolToMolBlock(mol)
        ims = oechem.oemolistream()
        ims.SetFormat(oechem.OEFormat_SDF)
        ims.openstring(mb)

        for buf_mol in ims.GetOEMols():
            oemol = oechem.OEMol(buf_mol)
            # AromaticityModel.assign(oe_molecule, bcc_collection.aromaticity_model)
            AromaticityModel.assign(oemol)

        # check for cache
        cache_key = 'AM1Cache'
        if not mol.HasProp(cache_key):
            result = oequacpac.OEAssignCharges(
                oemol, oequacpac.OEAM1Charges(symmetrize=True))
            if result is False:
                raise Exception('Unable to assign charges')

            am1_charges = []
            for index, atom in enumerate(oemol.GetAtoms()):
                q = atom.GetPartialCharge() * np.sqrt(constants.ONE_4PI_EPS0)
                am1_charges.append(q)

            mol.SetProp(cache_key, base64.b64encode(pickle.dumps(am1_charges)))

        else:
            am1_charges = pickle.loads(base64.b64decode(
                mol.GetProp(cache_key)))

        bond_idxs = []
        bond_idx_params = []

        for index in range(len(self.smirks)):
            smirk = self.smirks[index]
            param = self.params[index]

            substructure_search = oechem.OESubSearch(smirk)
            substructure_search.SetMaxMatches(0)

            matched_bonds = []
            matches = []
            for match in substructure_search.Match(oemol):

                matched_indices = {
                    atom_match.pattern.GetMapIdx() - 1:
                    atom_match.target.GetIdx()
                    for atom_match in match.GetAtoms()
                    if atom_match.pattern.GetMapIdx() != 0
                }

                matches.append(matched_indices)

            for matched_indices in matches:

                forward_matched_bond = [matched_indices[0], matched_indices[1]]
                reverse_matched_bond = [matched_indices[1], matched_indices[0]]

                if (forward_matched_bond in matched_bonds
                        or reverse_matched_bond in matched_bonds
                        or forward_matched_bond in bond_idxs
                        or reverse_matched_bond in bond_idxs):
                    continue

                matched_bonds.append(forward_matched_bond)
                bond_idxs.append(forward_matched_bond)
                bond_idx_params.append(index)

        bcc_fn = functools.partial(apply_bcc,
                                   bond_idxs=np.array(bond_idxs),
                                   bond_idx_params=np.array(bond_idx_params,
                                                            dtype=np.int32),
                                   am1_charges=np.array(am1_charges))

        charges, vjp_fn = jax.vjp(bcc_fn, self.params)

        return np.array(charges, dtype=np.float64), vjp_fn
コード例 #16
0
ファイル: systemloader.py プロジェクト: dallonasnes/RLMM
    def __setup_system_im(self, pdbfile: str = None):
        with self.logger("__setup_system_im") as logger:
            try:
                with tempfile.TemporaryDirectory() as dirpath:
                    dirpath = self.config.tempdir()

                    # Move inital file over to new system.
                    shutil.copy(pdbfile, f"{dirpath}/init.pdb")

                    # Assign charges and extract new ligand
                    cmd.reinitialize()
                    cmd.load(f'{dirpath}/init.pdb')
                    cmd.remove("polymer")
                    cmd.remove("resn HOH or resn Cl or resn Na")
                    cmd.save(f'{dirpath}/lig.pdb')
                    cmd.save(f'{dirpath}/lig.mol2')
                    ifs = oechem.oemolistream(f'{dirpath}/lig.pdb')
                    oemol = oechem.OEMol()
                    oechem.OEReadMolecule(ifs, oemol)
                    ifs.close()
                    ofs = oechem.oemolostream()
                    oemol.SetTitle("UNL")
                    oechem.OEAddExplicitHydrogens(oemol)
                    oequacpac.OEAssignCharges(oemol, oequacpac.OEAM1BCCCharges())
                    if ofs.open(f'{dirpath}/charged.mol2'):
                        oechem.OEWriteMolecule(ofs, oemol)
                    ofs.close()

                    # remove hydrogens and ligand from PDB
                    cmd.reinitialize()
                    cmd.load(f'{dirpath}/init.pdb')
                    cmd.remove("not polymer")
                    cmd.remove("hydrogens")
                    cmd.save(f'{dirpath}/apo.pdb')

                    with working_directory(dirpath):
                        subprocess.run(
                            f'antechamber -i lig.pdb -fi pdb -o lig.mol2 -fo mol2 -pf y -an y -a charged.mol2 -fa mol2 -ao crg'.split(
                                " "), check=True, capture_output=True)
                        subprocess.run(f'parmchk2 -i lig.mol2 -f mol2 -o lig.frcmod'.split(" "), check=True,
                                       capture_output=True)
                        try:
                            subprocess.run('pdb4amber -i apo.pdb -o apo_new.pdb --reduce --dry'.split(" "), check=True,
                                           capture_output=True)
                        except subprocess.CalledProcessError as e:
                            logger.error("Known bug, pdb4amber returns error when there was no error", e.stdout, e.stderr)
                            pass

                        # Wrap tleap
                        with open('leap.in', 'w+') as leap:
                            leap.write("source leaprc.protein.ff14SBonlysc\n")
                            leap.write("source leaprc.phosaa10\n")
                            leap.write("source leaprc.gaff2\n")
                            leap.write("set default PBRadii mbondi3\n")
                            leap.write("rec = loadPDB apo_new.pdb # May need full filepath?\n")
                            leap.write("saveAmberParm rec apo.prmtop apo.inpcrd\n")
                            leap.write("lig = loadmol2 lig.mol2\n")
                            leap.write("loadAmberParams lig.frcmod\n")
                            leap.write("saveAmberParm lig lig.prmtop lig.inpcrd\n")
                            leap.write("com = combine {rec lig}\n")
                            leap.write("saveAmberParm com com.prmtop com.inpcrd\n")
                            leap.write("quit\n")
                        try:
                            subprocess.run('tleap -f leap.in'.split(" "), check=True, capture_output=True)
                        except subprocess.CalledProcessError as e:
                            logger.error("tleap error", e.output.decode("UTF-8"))
                            exit()

                        prmtop = app.AmberPrmtopFile(f'com.prmtop')
                        inpcrd = app.AmberInpcrdFile(f'com.inpcrd')

                    for comp in ['com', 'apo', 'lig']:
                        for ext in ['prmtop', 'inpcrd']:
                            shutil.copy(f'{dirpath}/{comp}.{ext}',
                                        f"{self.config.tempdir()}/{comp}_{self.params_written}.{ext}")

                    self.system = prmtop.createSystem(**self.params)

                    if self.config.relax_ligand:
                        mod_parms = copy.deepcopy(self.params)
                        mod_parms['constraints'] = None
                        self._unconstrained_system = prmtop.createSystem(**mod_parms)
                    self.boxvec = self.system.getDefaultPeriodicBoxVectors()
                    self.topology, self.positions = prmtop.topology, inpcrd.positions
                    with open("{}".format(self.config.pdb_file_name), 'w') as f:
                        app.PDBFile.writeFile(self.topology, self.positions, file=f, keepIds=True)
                        logger.log("wrote ", "{}".format(self.config.pdb_file_name))
                    with open("{}".format(self.config.pdb_file_name), 'r') as f:
                        self.pdb = app.PDBFile(f)
                    self.params_written += 1

                    return self.system, self.topology, self.positions
            except Exception as e:
                logger.error("EXCEPTION CAUGHT BAD SPOT", e)
コード例 #17
0
ファイル: hybrid.py プロジェクト: jaimergp/kinomodel
def hybrid_docking(receptor_path,
                   molecules_path,
                   docked_molecules_path,
                   n_poses=10):
    """Automated hybrid docking of small molecules to a receptor.

    Parameters
    ----------
    receptor_path : str
        Path to PDB file containing receptor and reference ligand, or pre-prepared receptor for docking
    molecules_path : str
        Path to file containing one or more molecules (in OpenEye readable format) to be docked.
        (For example, list of SMILES)
    docked_molecules_path : str
        Path to output file to be created to contain docked molecules
        Uses OpenEye recognized file extension, such as .mol2 or .sdf
    n_poses : int, optional, default=1
        Number of docked poses to generate
    receptor_filename : str, optional, default=None
        If not None, the pre-prepared receptor is loaded

    TODO: How can this API be improved?

    """
    from .docking import create_receptor, load_receptor, pose_molecule
    from openeye import oedocking, oechem
    #import openmoltools as moltools # TODO: Bring these methods into this module

    # Try to load pre-prepared receptor from specified file
    receptor = oechem.OEGraphMol()
    print('Attempting to load receptor from {}...'.format(receptor_path))
    if not oedocking.OEReadReceptorFile(receptor, receptor_path):
        # Load complex of receptor and reference ligand
        complex_istream = oechem.oemolistream(receptor_path)
        complex = oechem.OEGraphMol()
        oechem.OEReadMolecule(complex_istream, complex)

        # Attempt to split into components and build receptor based on reference ligand
        print('Attempting to split complex into components...')
        ligand = oechem.OEGraphMol()
        protein = oechem.OEGraphMol()
        water = oechem.OEGraphMol()
        other = oechem.OEGraphMol()
        if oechem.OESplitMolComplex(ligand, protein, water, other, complex):
            # Create receptor using bound ligand reference
            print('Creating receptor using reference ligand...')
            oedocking.OEMakeReceptor(receptor, protein, ligand)
            # TODO: We can store prepared receptor file if desired
            oedocking.OEWriteReceptorFile(
                receptor,
                '/home/guoj1/projects/INSPIRE/kinomodel/kinomodel/data/docking/prepared_receptor.oeb'
            )

        else:
            raise Exception(
                'Could not split specified PDB file {} into receptor and reference ligand'
                .format(receptor_path))

    # Open file for writing docked molecules
    docked_molecules_ostream = oechem.oemolostream(docked_molecules_path)

    # Configure omega
    # From canonical recipe: https://docs.eyesopen.com/toolkits/cookbook/python/modeling/am1-bcc.html
    from openeye import oeomega
    omega = oeomega.OEOmega()
    omega.SetIncludeInput(False)
    omega.SetCanonOrder(False)
    omega.SetSampleHydrogens(True)
    eWindow = 15.0
    omega.SetEnergyWindow(eWindow)
    omega.SetMaxConfs(800)
    omega.SetRMSThreshold(1.0)

    # Dock all molecules requested
    dock_method = oedocking.OEDockMethod_Hybrid2
    dock_resolution = oedocking.OESearchResolution_Standard
    dock = oedocking.OEDock(dock_method, dock_resolution)
    dock.Initialize(receptor)
    molecules_istream = oechem.oemolistream(molecules_path)
    molecule = oechem.OEGraphMol()
    for molecule in molecules_istream.GetOEMols():
        print("docking", molecule.GetTitle())
        #docked_molecules = pose_molecule(receptor, molecule, n_poses=n_poses)
        #molecule = moltools.openeye.get_charges(molecule, keep_confs=10)

        # Generate conformers
        if not omega(molecule):
            continue

        # Apply charges
        from openeye import oequacpac
        oequacpac.OEAssignCharges(molecule, oequacpac.OEAM1BCCELF10Charges())

        # Dock
        docked_molecule = oechem.OEGraphMol()
        dock.DockMultiConformerMolecule(docked_molecule, molecule)
        sdtag = oedocking.OEDockMethodGetName(dock_method)
        oedocking.OESetSDScore(docked_molecule, dock, sdtag)
        dock.AnnotatePose(docked_molecule)
        oechem.OEWriteMolecule(docked_molecules_ostream, docked_molecule)