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
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
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
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)
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
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