def createMolecule(self, mol, molTitle):
        '''
        Get a OE residue, return a OE molecule
        '''
        # Creating a new Res GraphMol
        newMol = oechem.OEGraphMol()
        newMol.SetTitle(molTitle)
        # Create every atom found in the OEHierResidue
        for atom in mol.GetAtoms():
            newMol.NewAtom(atom)

        #---------------------------------------------#
        # Recreate the molecule from atom coordinates #
        #---------------------------------------------#

        # Using OpenEye's charge model. Works on molecules with fully specified
        # hydrogen counts. Charge determined based on atom valence.
        oechem.OEDetermineConnectivity(newMol)
        oechem.OEFindRingAtomsAndBonds(newMol)
        oechem.OEPerceiveBondOrders(newMol)
        oechem.OEAssignImplicitHydrogens(newMol)
        oechem.OEAssignFormalCharges(newMol)

        # Other things to consider
        # Set atom radius
        #oechem.OEAssignBondiVdWRadii(newMol)
        #oechem.OEAssignPartialCharges(newMol,
        #                              oechem.OECharges_None,
        #                              False,
        #                              False)

        return newMol
Beispiel #2
0
def get_ani_mol(coordinates, species, smiles):
    """ Given smiles string and list of elements as reference,
    get the RDKit mol with xyz.

    """

    mol = oechem.OEGraphMol()

    for symbol in species:
        mol.NewAtom(getattr(oechem, 'OEElemNo_' + symbol))

    mol.SetCoords(coordinates.reshape([-1]))
    mol.SetDimension(3)
    oechem.OEDetermineConnectivity(mol)
    oechem.OEFindRingAtomsAndBonds(mol)
    oechem.OEPerceiveBondOrders(mol)

    smiles_can = oechem.OECreateCanSmiString(mol)

    ims = oechem.oemolistream()
    ims.SetFormat(oechem.OEFormat_SMI)
    ims.openstring(smiles)
    mol_ref = next(ims.GetOEMols())
    smiles_ref = oechem.OECreateCanSmiString(mol_ref)

    assert smiles_can == smiles_ref

    g = hgfp.graph.from_oemol(mol, use_fp=True)

    return g, mol
Beispiel #3
0
def mol_from_json(symbols, connectivity, geometry, permute_xyz=False):
    """
    Generate OEMol from QCSchema molecule specs
    Parameters
    ----------
    inp_molecule: dict
        Must have symbols and connectivity and/or geometry
        Note: If geometry is given, the molecule will have a tag indicating that the goemetry came from QCSchema. This
        will ensure that the order of the atoms and configuration is not change for generation of mapped SMILES and
        isomeric SMILES.

    Returns
    -------
    molecule: OEMol

    """

    molecule = oechem.OEMol()
    for s in symbols:
        molecule.NewAtom(_symbols[s])

    # Add connectivity
    for bond in connectivity:
        a1 = molecule.GetAtom(oechem.OEHasAtomIdx(bond[0]))
        a2 = molecule.GetAtom(oechem.OEHasAtomIdx(bond[1]))
        molecule.NewBond(a1, a2, bond[-1])

    # Add geometry
    if molecule.NumAtoms() != geometry.shape[0] / 3:
        raise ValueError(
            "Number of atoms in molecule does not match length of position array"
        )

    molecule.SetCoords(oechem.OEFloatArray(geometry))
    molecule.SetDimension(3)

    if not permute_xyz:
        # Add tag that the geometry is from JSON and shouldn't be changed.
        geom_tag = oechem.OEGetTag("json_geometry")
        molecule.SetData(geom_tag, True)
    oechem.OEDetermineConnectivity(molecule)
    oechem.OEFindRingAtomsAndBonds(molecule)
    oechem.OEPerceiveBondOrders(molecule)
    # This seems to add hydrogens that are not in the json
    #oechem.OEAssignImplicitHydrogens(molecule)
    oechem.OEAssignFormalCharges(molecule)
    oechem.OEAssignAromaticFlags(molecule)
    oechem.OEPerceiveChiral(molecule)
    oechem.OE3DToAtomStereo(molecule)
    oechem.OE3DToBondStereo(molecule)

    return molecule
Beispiel #4
0
    def process(self, mol, port):
        try:

            # Split the complex in components in order to apply the FF
            protein, ligand, water, excipients = oeommutils.split(
                mol, ligand_res_name=self.opt['ligand_res_name'])

            self.log.info(
                "\nComplex name: {}\nProtein atom numbers = {}\nLigand atom numbers = {}\n"
                "Water atom numbers = {}\nExcipients atom numbers = {}".format(
                    mol.GetTitle(), protein.NumAtoms(), ligand.NumAtoms(),
                    water.NumAtoms(), excipients.NumAtoms()))

            # Unique prefix name used to output parametrization files
            self.opt['prefix_name'] = mol.GetTitle()

            oe_mol_list = []
            par_mol_list = []

            # Apply FF to the Protein
            if protein.NumAtoms():
                oe_mol_list.append(protein)
                protein_structure = utils.applyffProtein(protein, self.opt)
                par_mol_list.append(protein_structure)

            # Apply FF to the ligand
            if ligand.NumAtoms():
                oe_mol_list.append(ligand)
                ligand_structure = utils.applyffLigand(ligand, self.opt)
                par_mol_list.append(ligand_structure)

            # Apply FF to water molecules
            if water.NumAtoms():
                oe_mol_list.append(water)
                water_structure = utils.applyffWater(water, self.opt)
                par_mol_list.append(water_structure)

            # Apply FF to the excipients
            if excipients.NumAtoms():
                excipient_structure = utils.applyffExcipients(
                    excipients, self.opt)
                par_mol_list.append(excipient_structure)

                # The excipient order is set equal to the order in related
                # parmed structure to avoid possible atom index mismatching
                excipients = oeommutils.openmmTop_to_oemol(
                    excipient_structure.topology,
                    excipient_structure.positions,
                    verbose=False)
                oechem.OEPerceiveBondOrders(excipients)
                oe_mol_list.append(excipients)

            # Build the overall Parmed structure
            complex_structure = parmed.Structure()

            for struc in par_mol_list:
                complex_structure = complex_structure + struc

            complx = oe_mol_list[0].CreateCopy()
            num_atom_system = complx.NumAtoms()

            for idx in range(1, len(oe_mol_list)):
                oechem.OEAddMols(complx, oe_mol_list[idx])
                num_atom_system += oe_mol_list[idx].NumAtoms()

            if not num_atom_system == complex_structure.topology.getNumAtoms():
                oechem.OEThrow.Fatal(
                    "Parmed and OE topologies mismatch atom number error")

            complx.SetTitle(mol.GetTitle())

            # Set Parmed structure box_vectors
            is_periodic = True
            try:
                vec_data = pack_utils.PackageOEMol.getData(complx,
                                                           tag='box_vectors')
                vec = pack_utils.PackageOEMol.decodePyObj(vec_data)
                complex_structure.box_vectors = vec
            except:
                is_periodic = False
                self.log.warn(
                    "System has been parametrize without periodic box vectors for vacuum simulation"
                )

            # Attach the Parmed structure to the complex
            packed_complex = pack_utils.PackageOEMol.pack(
                complx, complex_structure)

            # Attach the reference positions to the complex
            ref_positions = complex_structure.positions
            packedpos = pack_utils.PackageOEMol.encodePyObj(ref_positions)
            packed_complex.SetData(oechem.OEGetTag('OEMDDataRefPositions'),
                                   packedpos)

            # Set atom serial numbers, Ligand name and HETATM flag
            # oechem.OEPerceiveResidues(packed_complex, oechem.OEPreserveResInfo_SerialNumber)
            for at in packed_complex.GetAtoms():
                thisRes = oechem.OEAtomGetResidue(at)
                thisRes.SetSerialNumber(at.GetIdx())
                if thisRes.GetName() == 'UNL':
                    # thisRes.SetName("LIG")
                    thisRes.SetHetAtom(True)
                oechem.OEAtomSetResidue(at, thisRes)

            if packed_complex.GetMaxAtomIdx(
            ) != complex_structure.topology.getNumAtoms():
                raise ValueError(
                    "OEMol complex and Parmed structure mismatch atom numbers")

            # Check if it is possible to create the OpenMM System
            if is_periodic:
                complex_structure.createSystem(
                    nonbondedMethod=app.CutoffPeriodic,
                    nonbondedCutoff=10.0 * unit.angstroms,
                    constraints=app.HBonds,
                    removeCMMotion=False)
            else:
                complex_structure.createSystem(nonbondedMethod=app.NoCutoff,
                                               constraints=app.HBonds,
                                               removeCMMotion=False)

            self.success.emit(packed_complex)
        except Exception as e:
            # Attach error message to the molecule that failed
            self.log.error(traceback.format_exc())
            mol.SetData('error', str(e))
            # Return failed mol
            self.failure.emit(mol)

        return
from openeye import oechem
from glob import glob

guests = glob("../systems/*/*")
guests = [i for i in guests if os.path.isdir(i)]

for guest in guests:
    guest_mol2 = os.path.basename(guest) + ".mol2"

    ifs = oechem.oemolistream()
    ofs = oechem.oemolostream()

    if ifs.open(os.path.join(guest, guest_mol2)):
        if ofs.open(os.path.join(guest, "tmp.mol2")):
            for mol in ifs.GetOEGraphMols():
                oechem.OEPerceiveBondOrders(mol)
                oechem.OEWriteMolecule(ofs, mol)
                mol.SetTitle(guest.upper())
        else:
            oechem.OEThrow.Fatal("Unable to create 'tmp.mol2'")
    else:
        oechem.OEThrow.Fatal(f"Unable to open '{guest_mol2}'")

    f = open(os.path.join(guest, "tmp.mol2"), 'r')
    file_data = f.read()
    f.close()

    new_data = file_data.replace("<0>", os.path.basename(guest).upper())

    f = open(os.path.join(guest, "tmp.mol2"), 'w')
    f.write(new_data)
Beispiel #6
0
def create_openeye_molecule(pdb, options, verbose=True):
    """
    Create OpenEye molecule from PDB representation.

    The molecule will have hydrogens added and be normalized, but the overall geometry will not be altered.

    Parameters
    ----------
    pdb : Pdb
       The PDB-extracted entries for the ligand.

    Returns
    -------
    molecule : openeye.oechem.OEMol
        Molecule representation.
    options : options struct
        Options structure.

    """

    # Create a molecule container.
    molecule = oechem.OEGraphMol()

    # Open a PDB file reader from the stored PDB string representation of HETATM and CONECT records.
    print pdb.pdb_extract
    ifs = oechem.oemolistream()
    ifs.openstring(pdb.pdb_extract)
    flavor = oechem.OEIFlavor_Generic_Default | oechem.OEIFlavor_PDB_Default | oechem.OEIFlavor_PDB_ALL
    ifs.SetFlavor(oechem.OEFormat_PDB, flavor)
    oechem.OEReadPDBFile(ifs, molecule)

    # Add explicit hydrogens.
    oechem.OEDetermineConnectivity(molecule)
    oechem.OEFindRingAtomsAndBonds(molecule)
    oechem.OEAssignAromaticFlags(molecule) # check aromaticity
    oechem.OEPerceiveBondOrders(molecule)

    # We must assign implicit hydrogens first so that the valence model will be correct.
    oechem.OEAssignImplicitHydrogens(molecule)
    oechem.OEAssignFormalCharges(molecule)

    # Now add explicit hydrogens.
    polarOnly = False
    set3D = True
    oechem.OEAddExplicitHydrogens(molecule, polarOnly, set3D)

    # TODO: Sequentially number hydrogen atoms.

    # Perceive stereochemostry.
    oechem.OEPerceiveChiral(molecule)

    # Set title.
    molecule.SetTitle(options.ligand)

    # Write out PDB form of this molecule.
    # TODO: Fix atom numbering.
    #if verbose: print "Writing input molecule as PDB..."
    #outmol = oechem.OEMol(molecule)
    #ofs = oechem.oemolostream()
    #flavor = oechem.OEOFlavor_Generic_Default | oechem.OEOFlavor_PDB_Default
    #ofs.SetFlavor(oechem.OEFormat_PDB, flavor)
    #ofs.open(options.ligand + '.pdb')
    #oechem.OEWriteMolecule(ofs, outmol)
    #ofs.close()

    # Write mol2 file for this molecule.
    if verbose: print "Writing input molecule as mol2..."
    outmol = oechem.OEMol(molecule)
    ofs = oechem.oemolostream()
    filename = options.ligand + '.mol2'
    ofs.open(filename)
    oechem.OEWriteMolecule(ofs, outmol)
    ofs.close()
    # Use low level writer to get atom names correct.
    ofs = oechem.oemolostream()
    ofs.open(filename)
    for (dest_atom, src_atom) in zip(outmol.GetAtoms(), molecule.GetAtoms()):
        dest_atom.SetName(src_atom.GetName())
    oechem.OEWriteMol2File(ofs, outmol, True)
    ofs.close()
    # Read and write in PDB format.
    if verbose: print "Converting mol2 to PDB..."
    ifs = oechem.oemolistream()
    ofs = oechem.oemolostream()
    if ifs.open(options.ligand + '.mol2'):
        if ofs.open(options.ligand + '.pdb'):
            for mol in ifs.GetOEGraphMols():
                oechem.OEWriteMolecule(ofs, mol)

    return molecule
Beispiel #7
0
def infer_mol_from_coordinates(
    coordinates,
    species,
    smiles_ref=None,
    coordinates_unit="angstrom",
):

    # local import
    from openeye import oechem
    from simtk import unit
    from simtk.unit import Quantity

    if isinstance(coordinates_unit, str):
        coordinates_unit = getattr(unit, coordinates_unit)

    # make sure we have the coordinates
    # in the unit system
    coordinates = Quantity(coordinates, coordinates_unit).value_in_unit(
        unit.angstrom  # to make openeye happy
    )

    # initialize molecule
    mol = oechem.OEGraphMol()

    if all(isinstance(symbol, str) for symbol in species):
        [
            mol.NewAtom(getattr(oechem, "OEElemNo_" + symbol))
            for symbol in species
        ]

    elif all(isinstance(symbol, int) for symbol in species):
        [
            mol.NewAtom(
                getattr(oechem,
                        "OEElemNo_" + oechem.OEGetAtomicSymbol(symbol)))
            for symbol in species
        ]

    else:
        raise RuntimeError(
            "The species can only be all strings or all integers.")

    mol.SetCoords(coordinates.reshape([-1]))
    mol.SetDimension(3)
    oechem.OEDetermineConnectivity(mol)
    oechem.OEFindRingAtomsAndBonds(mol)
    oechem.OEPerceiveBondOrders(mol)

    if smiles_ref is not None:
        smiles_can = oechem.OECreateCanSmiString(mol)
        ims = oechem.oemolistream()
        ims.SetFormat(oechem.OEFormat_SMI)
        ims.openstring(smiles_ref)
        mol_ref = next(ims.GetOEMols())
        smiles_ref = oechem.OECreateCanSmiString(mol_ref)
        assert (smiles_ref == smiles_can
                ), "SMILES different. Input is %s, ref is %s" % (
                    smiles_can,
                    smiles_ref,
                )

    from openff.toolkit.topology import Molecule

    _mol = Molecule.from_openeye(mol, allow_undefined_stereo=True)
    g = esp.Graph(_mol)

    return g