def printer(tpl,conformer,atom,count): #template = '{0:9}{1:7}{2:5} {3:7}\n' template = '{0:9s}{1:6s}{2:>5s}{3:+012.8f}\n' element = oechem.OEGetAtomicSymbol(atom.GetAtomicNum()).upper() tpl.write(template.format("RADIUS",conformer.name, \ atom.GetName(),vdw_dict[element])) return
def PrintForces(mol, forces): for atom in mol.GetAtoms(): oechem.OEThrow.Info( "%6d %8s %8.2f %8.2f %8.2f" % (atom.GetIdx(), oechem.OEGetAtomicSymbol( atom.GetAtomicNum()), forces[atom.GetIdx()], forces[atom.GetIdx() + 1], forces[atom.GetIdx() + 2]))
def make_ptl_mol(oemol): """Builds a QCPortal Molecule from an OpenEye molecule""" coords = oemol.GetCoords() symbols_list = [ oechem.OEGetAtomicSymbol(atom.GetAtomicNum()) for atom in mol.GetAtoms() ] #convert to bohr print(coords) for key, item in coords.items(): coords[key] = (item[0] * 1.88973, item[1] * 1.88973, item[2] * 1.88973) coord_list = [c for atom in mol.GetAtoms() for c in coords[atom.GetIdx()]] conn_list = np.array( [[bond.GetBgnIdx(), bond.GetEndIdx(), bond.GetOrder()] for bond in mol.GetBonds()]) ptl_mol = ptl.Molecule.from_data({ 'geometry': coord_list, 'symbols': symbols_list, 'connectivity': conn_list }) return ptl_mol
def atom_symbols(self): """ return array of atomic symbols """ atom_sym = [] for at in self._mol.GetAtoms(): atom_sym.append(oechem.OEGetAtomicSymbol(at.GetAtomicNum())) return atom_sym
def GetMolDetails(mol, label): """ Parameters ---------- mol: single OEChem conformer with coordinates label: string - name of the molecule. Can be an empty string. Returns ------- optinfo: string - Turbomole input file for autoDefine.py xinfo: string - XYZ format coordinates to feed into Turbomole's x2t """ optinfo = ("$title %s" % label) optinfo += ("\n$charge %d" % oechem.OENetCharge(mol)) optinfo += ("\n$end") xinfo = ("%d\n" % mol.NumAtoms()) xyz = oechem.OEFloatArray(3) # get coordinates of each atom for atom in mol.GetAtoms(): mol.GetCoords(atom, xyz) xinfo+=( '\n %s %10.4f %10.4f %10.4f' \ %(oechem.OEGetAtomicSymbol(atom.GetAtomicNum()), xyz[0], xyz[1], xyz[2]) ) return optinfo, xinfo
def to_mapped_xyz(molecule, atom_map=None, conformer=None, xyz_format=True, filename=None): """ Generate xyz coordinates for molecule in the order given by the atom_map. atom_map is a dictionary that maps the tag on the SMILES to the atom idex in OEMol. Parameters ---------- molecule: OEMol with conformers atom_map: dict maps tag in SMILES to atom index conformer: int Which conformer to write xyz file for. If None, write out all conformers. Default is None xyz_format: bool If True, will write out number of atoms and molecule name. If false, will only write out elements and coordinates filename: str Name of file to save to. If None, only returns a string. Returns ------- str: elements and xyz coordinates (in angstroms) in order of tagged SMILES """ if not atom_map and not cmiles.utils.has_atom_map(molecule): raise ValueError( "If molecule does not have atom map, you must provide an atom map") if not has_conformer(molecule, check_two_dimension=True): raise ValueError("Molecule must have conformers") xyz = "" for k, mol in enumerate(molecule.GetConfs()): if k == conformer or conformer is None: if xyz_format: xyz += "{}\n".format(mol.GetMaxAtomIdx()) xyz += "{}\n".format(mol.GetTitle()) coords = oechem.OEFloatArray(mol.GetMaxAtomIdx() * 3) mol.GetCoords(coords) if k != 0 and not xyz_format: xyz += "*" for mapping in range(1, molecule.NumAtoms() + 1): if not atom_map: atom = molecule.GetAtom(oechem.OEHasMapIdx(mapping)) idx = atom.GetIdx() else: idx = atom_map[mapping] atom = mol.GetAtom(oechem.OEHasAtomIdx(idx)) syb = oechem.OEGetAtomicSymbol(atom.GetAtomicNum()) xyz += " {} {:05.3f} {:05.3f} {:05.3f}\n".format( syb, coords[idx * 3], coords[idx * 3 + 1], coords[idx * 3 + 2]) if filename: file = open("{}.xyz".format(filename), 'w') file.write(xyz) file.close() else: return xyz
def doAlignSs(self, unique=True, maxMatches=20): """Test the SS comparison between current reference and fit molecules - Return list of corresponding atoms on success or an empty list otherwise. """ atomMapL = [] fitAtomUnMappedL = [] # nAtomsRef = self.__refmol.NumAtoms() nAtomsFit = self.__fitmol.NumAtoms() # ------- oechem.OEAddExplicitHydrogens(self.__refmol) oechem.OEAddExplicitHydrogens(self.__fitmol) fitAtD = {} # for at in self.__fitmol.GetAtoms(): nAtL = at.GetAtoms() neighbors = [nAt.GetName() for nAt in nAtL] atType = oechem.OEGetAtomicSymbol(at.GetAtomicNum()) xyzL = oechem.OEFloatArray(3) self.__fitmol.GetCoords(at, xyzL) fitAtD[at.GetIdx()] = AlignAtomUnMapped( fitId=self.__fitId, fitAtIdx=at.GetIdx(), fitAtName=at.GetName(), fitAtType=atType, fitAtNo=at.GetAtomicNum(), fitAtFormalCharge=at.GetFormalCharge(), x=xyzL[0], y=xyzL[1], z=xyzL[2], fitNeighbors=neighbors, ) # logger.debug("nAtomsRef %d nAtomsFit %d", nAtomsRef, nAtomsFit) # # -------- self.__setupSubStructure(self.__refmol) self.__ss.SetMaxMatches(maxMatches) miter = self.__ss.Match(self.__fitmol, unique) if miter.IsValid(): match = miter.Target() for mAt in match.GetAtoms(): atomMapL.append( AlignAtomMap( refId=self.__refId, refAtIdx=mAt.pattern.GetIdx(), refAtNo=mAt.pattern.GetAtomicNum(), refAtName=mAt.pattern.GetName(), fitId=self.__fitId, fitAtIdx=mAt.target.GetIdx(), fitAtNo=mAt.target.GetAtomicNum(), fitAtName=mAt.target.GetName(), ) ) fitAtD.pop(mAt.target.GetIdx()) logger.debug("fitAtD %r", fitAtD) fitAtomUnMappedL = list(fitAtD.values()) return (nAtomsRef, self.__refFD, nAtomsFit, self.__fitFD, atomMapL, fitAtomUnMappedL)
def doAlignMcss(self, unique=True, minFrac=1.0, useExhaustive=True): """Test the MCSS comparison between current reference and fit molecules - Return list of corresponding atoms on success or an empty list otherwise. """ atomMapL = [] fitAtomUnMappedL = [] # nAtomsRef = self.__refmol.NumAtoms() nAtomsFit = self.__fitmol.NumAtoms() fitAtD = {} for at in self.__fitmol.GetAtoms(): nAtL = at.GetAtoms() neighbors = [nAt.GetName() for nAt in nAtL] atType = oechem.OEGetAtomicSymbol(at.GetAtomicNum()) xyzL = oechem.OEFloatArray(3) self.__fitmol.GetCoords(at, xyzL) fitAtD[at.GetIdx()] = AlignAtomUnMapped( fitId=self.__fitId, fitAtIdx=at.GetIdx(), fitAtName=at.GetName(), fitAtType=atType, fitAtNo=at.GetAtomicNum(), fitAtFormalCharge=at.GetFormalCharge(), x=xyzL[0], y=xyzL[1], z=xyzL[2], fitNeighbors=neighbors, ) minAtoms = int(min(nAtomsRef, nAtomsFit) * minFrac) # ------- self.__setupMCSS(self.__refmol, useExhaustive=useExhaustive) self.__mcss.SetMCSFunc(oechem.OEMCSMaxAtoms()) self.__mcss.SetMinAtoms(minAtoms) oechem.OEAddExplicitHydrogens(self.__refmol) oechem.OEAddExplicitHydrogens(self.__fitmol) # # -------- miter = self.__mcss.Match(self.__fitmol, unique) if miter.IsValid(): match = miter.Target() for mAt in match.GetAtoms(): atomMapL.append( AlignAtomMap( refId=self.__refId, refAtIdx=mAt.pattern.GetIdx(), refAtNo=mAt.pattern.GetAtomicNum(), refAtName=mAt.pattern.GetName(), fitId=self.__fitId, fitAtIdx=mAt.target.GetIdx(), fitAtNo=mAt.target.GetAtomicNum(), fitAtName=mAt.target.GetName(), ) ) fitAtD.pop(mAt.target.GetIdx()) fitAtomUnMappedL = list(fitAtD.values()) return (nAtomsRef, self.__refFD, nAtomsFit, self.__fitFD, atomMapL, fitAtomUnMappedL)
def make_psi_input(mol, label, method, basisset, SPE=False, mem=None): """ Parameters ---------- mol: single OEChem conformer with coordinates label: string - name of the molecule. Can be an empty string. method: string - specification of method (see Psi4 website for options) basisset: string - specification of basis set SPE: boolean - False (default) for geom opt. True for single point E calcns mem: string - specify Psi4 job memory. E.g. "2 Gb" "2000 Mb" "2000000 Kb" Returns ------- inputstring: string - containing contents of whole input file for this conf """ inputstring = "" xyz = oechem.OEFloatArray(3) # specify memory requirements, if defined if mem != None: inputstring += "memory %s\n" % mem inputstring+=( 'molecule %s {\n' % label ) # charge and multiplicity; multiplicity hardwired to singlet (usually is) netCharge = oechem.OENetCharge( mol) inputstring+=( ' %s 1' % netCharge ) # get coordinates of each atom for atom in mol.GetAtoms(): mol.GetCoords( atom, xyz) inputstring+=( '\n %s %10.4f %10.4f %10.4f' \ %(oechem.OEGetAtomicSymbol(atom.GetAtomicNum()), xyz[0], xyz[1], xyz[2]) ) inputstring+=( '\n units angstrom\n}') # check if mol has a "freeze" tag for x in oechem.OEGetSDDataPairs(mol): if "atoms to freeze" in x.GetTag(): freeze_list = x.GetValue() inputstring += "\n\nfreeze_list = \"\"\"\n {} xyz\n {} xyz\n {} xyz\n {} xyz\n\"\"\"".format(freeze_list[1], freeze_list[4], freeze_list[7], freeze_list[10]) inputstring += "\nset optking frozen_cartesian $freeze_list" inputstring += "\nset optking dynamic_level = 1\nset optking consecutive_backsteps = 2\nset optking intrafrag_step_limit = 0.1\nset optking interfrag_step_limit = 0.1" # explicitly specify MP2 RI-auxiliary basis for Ahlrichs basis set # http://www.psicode.org/psi4manual/master/basissets_byfamily.html if method.lower()=='mp2' and 'def' in basisset and basisset.lower()!='def2-qzvpd': inputstring+=('\n\nset basis %s' % (basisset)) inputstring+=('\nset df_basis_mp2 %s-ri' % (basisset)) inputstring+=('\nset freeze_core True') else: inputstring+=('\n\nset basis %s' % (basisset)) inputstring+=('\nset freeze_core True') # specify command for type of calculation if SPE is False: inputstring+=('\noptimize(\'%s\')' % (method)) else: inputstring+=('\nenergy(\'%s\')' % (method)) return inputstring
def printatoms(label, begin): print(label) for atom in begin: print(" atom:", atom.GetIdx(), oechem.OEGetAtomicSymbol(atom.GetAtomicNum()), end=" ") print("in component", atom.GetData(oechem.OEProperty_Component), end=" ") # @ <SNIPPET-RXN-MAPIDX> print("with map index", atom.GetMapIdx())
def to_mapped_xyz(molecule, atom_map, conformer=None, xyz_format=False, filename=None): """ Generate xyz coordinates for molecule in the order given by the atom_map. atom_map is a dictionary that maps the tag on the SMILES to the atom idex in OEMol. Parameters ---------- molecule: OEMol with conformers atom_map: dict maps tag in SMILES to atom index conformer: int Which conformer to write xyz file for. If None, write out all conformers. Default is None xyz_format: bool If True, will write out number of atoms and molecule name. If false, will only write out elements and coordinates filename: str Name of file to save to. If None, only returns a string. Returns ------- str: elements and xyz coordinates in order of tagged SMILES """ xyz = "" for k, mol in enumerate(molecule.GetConfs()): if k == conformer or conformer is None: if xyz_format: xyz += "{}\n".format(mol.GetMaxAtomIdx()) xyz += "{}\n".format(mol.GetTitle()) coords = oechem.OEFloatArray(mol.GetMaxAtomIdx() * 3) mol.GetCoords(coords) if k != 0 and not xyz_format: xyz += "*" for mapping in range(1, len(atom_map) + 1): idx = atom_map[mapping] atom = mol.GetAtom(oechem.OEHasAtomIdx(idx)) syb = oechem.OEGetAtomicSymbol(atom.GetAtomicNum()) xyz += " {} {:05.3f} {:05.3f} {:05.3f}\n".format( syb, coords[idx * 3], coords[idx * 3 + 1], coords[idx * 3 + 2]) if filename: file = open("{}.xyz".format(filename, 'w')) file.write(xyz) file.close() return xyz
def oemol_to_dict(oemol, read_wbo=False): """ Return list of elements, partial charges and connectivity with WBOs for the bonds Parameters ---------- oemol : oechem.OEMol Molecule must have partial charges and Wiberg Bond Orders precalculated. Returns ------- mol_dict: dict dictionary of atomic symbols, partial charges and connectivity with Wiberg Bond Orders """ from openeye import oechem atomic_symbols = [ oechem.OEGetAtomicSymbol(atom.GetAtomicNum()) for atom in oemol.GetAtoms() ] partial_charges = [atom.GetPartialCharge() for atom in oemol.GetAtoms()] # Build connectivity with WBOs connectivity = [] for bond in oemol.GetBonds(): a1 = bond.GetBgn().GetIdx() a2 = bond.GetEnd().GetIdx() if read_wbo == True: if not 'WibergBondOrder' in bond.GetData(): raise RuntimeError('Molecule does not have Wiberg Bond Orders') wbo = bond.GetData('WibergBondOrder') connectivity.append([a1, a2, wbo]) else: bond_order = bond.GetOrder() connectivity.append([a1, a2, bond_order]) mol_dict = { 'atomic_symbols': atomic_symbols, 'partial_charges': partial_charges, 'connectivity': connectivity } return mol_dict
def get_map_ordered_geometry(molecule, atom_map): """ Generate geometry list of size 3*N in the order of the atom map Parameters ---------- molecule: OEMol with 1 conformer or OEConf atom_map: dict map_idx:atom_idx Returns ------- symbols: list of str list of symbols geometry: list of ints xyz geometry. List is length N*3 """ if not molecule.GetDimension() == 3: raise RuntimeError( "Molecule must have 3D coordinates for generating a QCSchema molecule" ) if isinstance(molecule, oechem.OEMol): if molecule.GetMaxConfIdx() != 1: raise Warning( "The molecule must have at least and at most 1 conformation") symbols = [] geometry = [] for mapping in range(1, molecule.NumAtoms() + 1): idx = atom_map[mapping] atom = molecule.GetAtom(oechem.OEHasAtomIdx(idx)) syb = oechem.OEGetAtomicSymbol(atom.GetAtomicNum()) symbols.append(syb) for i in range(3): geometry.append(molecule.GetCoords()[atom.GetIdx()][i] * ANGSROM_2_BOHR) return symbols, geometry
def get_psi4_mol_from_conf(conf): """Use an OEConfBase to construct a psi4 molecule""" xyz = oechem.OEFloatArray(3) mol_str = str() total_charge = 0 for atom in conf.GetAtoms(): total_charge += atom.GetFormalCharge() conf.GetCoords(atom, xyz) # scaled_xyz = [c / psi4.constants.bohr2angstroms for c in xyz] mol_str += "{} {} {} {}\n".format( oechem.OEGetAtomicSymbol(atom.GetAtomicNum()), # scaled_xyz[0], scaled_xyz[1], scaled_xyz[2]) xyz[0], xyz[1], xyz[2], ) psi4_mol = psi4.geometry(mol_str) psi4_mol.set_molecular_charge(total_charge) # psi_mol.set_name('{}, conf {}'.format(conf.GetTitle(), conf.GetIdx())) logging.debug("\n\n\nNew Psi4 molecule created with geometry: \n" + psi4_mol.create_psi4_string_from_molecule()) return psi4_mol
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED. OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT # NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A # PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall OpenEye be # liable for any damages or liability in connection with the Sample Code # or its use. from openeye import oechem from openeye import oegraphsim # @ <SNIPPET-FPOVERLAP> pmol = oechem.OEGraphMol() oechem.OESmilesToMol(pmol, "c1cnc2c(c1)CC(CC2O)CF") tmol = oechem.OEGraphMol() oechem.OESmilesToMol(tmol, "c1cc2c(cc1)CC(CCl)CC2N") fptype = oegraphsim.OEGetFPType("Tree,ver=2.0.0,size=4096,bonds=5-5," "atype=AtmNum|HvyDeg|EqHalo,btype=Order") for idx, match in enumerate(oegraphsim.OEGetFPOverlap(pmol, tmol, fptype)): ostring = "match %2d: " % (idx + 1) for mpair in match.GetAtoms(): p = mpair.pattern t = mpair.target ostring += "%d%s-%d%s " % ( p.GetIdx(), oechem.OEGetAtomicSymbol(p.GetAtomicNum()), t.GetIdx(), oechem.OEGetAtomicSymbol(t.GetAtomicNum())) print(ostring) # @ </SNIPPET-FPOVERLAP>
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall OpenEye be # liable for any damages or liability in connection with the Sample Code # or its use. # @ <SNIPPET> from __future__ import print_function from openeye import oechem qfile = oechem.oemolistream("query.mol") tfile = oechem.oemolistream("targets.sdf") # read MDL query and initialize the substructure search qmol = oechem.OEQMol() oechem.OEReadMDLQueryFile(qfile, qmol) ss = oechem.OESubSearch(qmol) # loop over target structures tindex = 1 for tmol in tfile.GetOEGraphMols(): oechem.OEAddExplicitHydrogens(tmol) oechem.OEPrepareSearch(tmol, ss) for mi in ss.Match(tmol, True): print("hit target = %d" % tindex, end=" ") for ai in mi.GetTargetAtoms(): print("%d%s" % (ai.GetIdx(), oechem.OEGetAtomicSymbol(ai.GetAtomicNum())), end=" ") print() tindex += 1 # @ </SNIPPET>
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED. OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT # NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A # PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall OpenEye be # liable for any damages or liability in connection with the Sample Code # or its use. # @ <SNIPPET> from __future__ import print_function from openeye import oechem IsDonorAtom = oechem.OEMatchAtom("[!H0;#7,#8]") mol = oechem.OEGraphMol() oechem.OESmilesToMol(mol, "c1c(Cl)cncc1C(=O)O") for atom in mol.GetAtoms(): atom.SetData("isdonor", IsDonorAtom(atom)) class IsDonorAtomPred(oechem.OEUnaryAtomPred): def __call__(self, atom): return atom.GetData("isdonor") print("Donor atoms:", end=" ") for atom in mol.GetAtoms(IsDonorAtomPred()): print(atom.GetIdx(), oechem.OEGetAtomicSymbol(atom.GetAtomicNum()), end=" ") print() # @ </SNIPPET>
def symbol(self) -> str: return oechem.OEGetAtomicSymbol(self._at.GetAtomicNum())
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
def make_psi_input(mol, label, method, basisset, calctype='opt', mem=None): """ Get coordinates from input mol, and generate/format input text for Psi4 calculation. Parameters ---------- mol : OpenEye OEMol OEMol with coordinates label : string Name of molecule with integer identifier (for conformers). method: string Name of the method as understood by Psi4. Example: "mp2" basis : string Name of the basis set as understood by Psi4. Example: "def2-sv(p)" calctype : string What kind of Psi4 calculation to run. Supported inputs are: 'opt' for geometry optimization, 'spe' for single point energy calculation, and 'hess' for Hessian calculation. memory : string How much memory each Psi4 job should take. If not specified, the default in Psi4 is 500 Mb. Examples: "2000 MB" "1.5 GB" http://www.psicode.org/psi4manual/master/psithoninput.html Returns ------- inputstring : string Contents of Psi4 input file to be written out """ # check that specified calctype is valid if calctype not in {'opt', 'spe', 'hess'}: sys.exit("Specify a valid calculation type.") inputstring = "" # specify memory requirements, if defined if mem != None: inputstring += "memory %s\n" % mem inputstring += ('molecule %s {\n' % label) # charge and multiplicity; multiplicity hardwired to singlet (usually is) netCharge = oechem.OENetCharge(mol) inputstring += (' %s 1' % netCharge) # get atomic symbol and coordinates of each atom xyz = oechem.OEFloatArray(3) for atom in mol.GetAtoms(): mol.GetCoords(atom, xyz) inputstring+=( '\n %s %10.4f %10.4f %10.4f' \ %(oechem.OEGetAtomicSymbol(atom.GetAtomicNum()), xyz[0], xyz[1], xyz[2]) ) inputstring += ('\n units angstrom\n}') # check if mol has a "freeze" tag for x in oechem.OEGetSDDataPairs(mol): if calctype == "opt" and "atoms to freeze" in x.GetTag(): b = x.GetValue() y = b.replace("[", "") z = y.replace("]", "") a = z.replace(" ", "") freeze_list = a.split(",") inputstring += ( "\n\nfreeze_list = \"\"\"\n {} xyz\n {} xyz\n {} " "xyz\n {} xyz\n\"\"\"".format(freeze_list[0], freeze_list[1], freeze_list[2], freeze_list[3])) inputstring += "\nset optking frozen_cartesian $freeze_list" inputstring += ( "\nset optking dynamic_level = 1\nset optking " "consecutive_backsteps = 2\nset optking intrafrag_step_limit = " "0.1\nset optking interfrag_step_limit = 0.1\n") # best practices for scf calculations # http://www.psicode.org/psi4manual/master/scf.html#recommendations # http://www.psicode.org/psi4manual/master/dft.html#recommendations inputstring += '\n\nset scf_type df' inputstring += '\nset guess sad' # explicitly specify MP2 RI-auxiliary basis for [Ahlrichs] basis set # http://www.psicode.org/psi4manual/master/basissets_byfamily.html # DFMP2 *should* get MP2 aux sets fine for [Pople and Dunning] sets # http://www.psicode.org/psi4manual/master/dfmp2.html if method.lower() == 'mp2' and 'def2' in basisset: if basisset.lower() == 'def2-sv(p)': inputstring += ('\nset df_basis_mp2 def2-sv_p_-ri') elif basisset.lower() != 'def2-qzvpd': # no aux set for qzvpd 10-6-18 inputstring += ('\nset df_basis_mp2 %s-ri' % (basisset)) inputstring += ('\n\nset basis %s' % (basisset)) inputstring += ('\nset freeze_core True') # specify command for type of calculation if calctype == 'opt': inputstring += ('\noptimize(\'%s\')\n\n' % (method)) elif calctype == 'spe': inputstring += ('\nenergy(\'%s\')\n\n' % (method)) elif calctype == 'hess': inputstring += ( '\nH, wfn = hessian(\'%s\', return_wfn=True)\nwfn.hessian().print_out()\n\n' % (method)) return inputstring
def make_psi_json(mol, label, method, basisset, calctype='opt', mem=None): """ THIS FUNCTION IS A WORK IN PROGRESS. Get coordinates from input mol, and generate/format input text for Psi4 calculation via JSON wrapper. Parameters ---------- mol : OpenEye OEMol OEMol with coordinates label : string Name of molecule with integer identifier (for conformers). method: string Name of the method as understood by Psi4. Example: "mp2" basis : string Name of the basis set as understood by Psi4. Example: "def2-sv(p)" calctype : string What kind of Psi4 calculation to run. Supported inputs are: 'opt' for geometry optimization, 'spe' for single point energy calculation, and 'hess' for Hessian calculation. memory : string How much memory each Psi4 job should take. If not specified, the default in Psi4 is 500 Mb. Examples: "2000 MB" "1.5 GB" http://www.psicode.org/psi4manual/master/psithoninput.html Returns ------- inputstring : string Contents of Psi4 input file to be written out """ # check that specified calctype is valid if calctype not in {'opt', 'spe', 'hess'}: sys.exit("Specify a valid calculation type.") inputdict = {} moldict = {} modeldict = {} keydict = {} inputdict["schema_name"] = "qc_schema_input" inputdict["schema_version"] = 1 # specify memory requirements, if defined if mem != None: inputdict["memory"] = mem #TODO -- json version # charge and multiplicity; multiplicity hardwired to singlet (usually is) #inputdict["charge"] = oechem.OENetCharge( mol) #inputdict["multiplicity"] = 1 # get atomic symbol and coordinates of each atom geom_list = [] elem_list = [] xyz = oechem.OEFloatArray(3) for atom in mol.GetAtoms(): mol.GetCoords(atom, xyz) geom_list.append(xyz[0]) geom_list.append(xyz[1]) geom_list.append(xyz[2]) elem_list.append(oechem.OEGetAtomicSymbol(atom.GetAtomicNum())) moldict["geometry"] = geom_list moldict["symbols"] = elem_list inputdict["molecule"] = moldict #TODO -- json version ## check if mol has a "freeze" tag #for x in oechem.OEGetSDDataPairs(mol): # if calctype=="opt" and "atoms to freeze" in x.GetTag(): # b = x.GetValue() # y = b.replace("[", "") # z = y.replace("]", "") # a = z.replace(" ", "") # freeze_list = a.split(",") # inputstring += ("\n\nfreeze_list = \"\"\"\n {} xyz\n {} xyz\n {} " # "xyz\n {} xyz\n\"\"\"".format(freeze_list[0], # freeze_list[1], freeze_list[2], freeze_list[3])) # inputstring += "\nset optking frozen_cartesian $freeze_list" # inputstring += ("\nset optking dynamic_level = 1\nset optking " # "consecutive_backsteps = 2\nset optking intrafrag_step_limit = " # "0.1\nset optking interfrag_step_limit = 0.1\n") #TODO -- json version ## explicitly specify MP2 RI-auxiliary basis for Ahlrichs basis set ## http://www.psicode.org/psi4manual/master/basissets_byfamily.html ## DFMP2 *should* get MP2 aux sets fine for Pople/Dunning ## http://www.psicode.org/psi4manual/master/dfmp2.html #if method.lower()=='mp2' and 'def2' in basisset: # if basisset.lower()=='def2-sv(p)': # inputstring+=('\nset df_basis_mp2 def2-sv_p_-ri') # elif basisset.lower()!='def2-qzvpd': # no aux set for qzvpd 10-6-18 # inputstring+=('\nset df_basis_mp2 %s-ri' % (basisset)) modeldict["basis"] = basisset modeldict["method"] = method inputdict["model"] = modeldict #inputstring+=('\nset freeze_core True') # specify command for type of calculation if calctype == 'opt': # TODO pass elif calctype == 'spe': inputdict["driver"] = 'energy' elif calctype == 'hess': inputdict["driver"] = 'hessian' keydict["return_wfn"] = True inputdict["keywords"] = keydict return inputdict
def __str__(self): return "Atom not assigned: %6d %8s" % ( self.atom.GetIdx(), oechem.OEGetAtomicSymbol(self.atom.GetAtomicNum()))
def __makeChemCompAtomCategory(self, ccId, oeMol, writeIdealXyz=True): """Populate elements of chemical component definition for atoms and bonds.""" # idCode = ccId # rowL = [] for ii, atom in enumerate(oeMol.GetAtoms()): # atRow = {} atRow["comp_id"] = idCode atRow["atom_id"] = atom.GetName().strip() atRow["alt_atom_id"] = atom.GetName().strip() atRow["type_symbol"] = oechem.OEGetAtomicSymbol(atom.GetAtomicNum()) atRow["charge"] = atom.GetFormalCharge() (xC, yC, zC) = oeMol.GetCoords(atom) if writeIdealXyz: atRow["pdbx_model_Cartn_x_ideal"] = "%0.3f" % xC atRow["pdbx_model_Cartn_y_ideal"] = "%0.3f" % yC atRow["pdbx_model_Cartn_z_ideal"] = "%0.3f" % zC else: atRow["model_Cartn_x"] = "%0.3f" % xC atRow["model_Cartn_y"] = "%0.3f" % yC atRow["model_Cartn_z"] = "%0.3f" % zC if atom.GetStringData("pdbx_leaving_atom_flag") in ["Y", "N"]: atRow["pdbx_leaving_atom_flag"] = atom.GetStringData("pdbx_leaving_atom_flag") else: atRow["pdbx_leaving_atom_flag"] = "N" if len(atRow["atom_id"]) > 3 or len(atRow["type_symbol"]) == 2: atRow["pdbx_align"] = 0 else: atRow["pdbx_align"] = 1 if atom.IsAromatic(): atRow["pdbx_aromatic_flag"] = "Y" else: atRow["pdbx_aromatic_flag"] = "N" # oeSt = oechem.OEGetCIPStereo(mol, atom) oeSt = None # if atom.IsChiral(): cip = oechem.OEPerceiveCIPStereo(oeMol, atom) if atom.HasStereoSpecified(): if cip == oechem.OECIPAtomStereo_S: oeSt = "S" if cip == oechem.OECIPAtomStereo_R: oeSt = "R" if cip == oechem.OECIPAtomStereo_NotStereo: oeSt = None if cip == oechem.OECIPAtomStereo_UnspecStereo: oeSt = "U" # oeSt = oechem.OEGetCIPStereo(oeMol, atom) # oeSt = atom.GetCIPStereo() if oeSt is not None and (len(oeSt) > 0) and (oeSt == "R" or oeSt == "S"): atRow["pdbx_stereo_config"] = oeSt else: atRow["pdbx_stereo_config"] = "N" atRow["pdbx_component_atom_id"] = atom.GetName().strip() atRow["pdbx_component_comp_id"] = idCode atRow["pdbx_ordinal"] = str(ii + 1) rowL.append(atRow) # return rowL
'halognes': [], 'P': [], 'S': [], 'all': [], 'all_no_h': []} missing_wbos = set() for m in mols: for bond in m.GetBonds(): if 'WibergBondOrder' not in bond.GetData(): missing_wbos.add(m) continue wbo = bond.GetData('WibergBondOrder') wbos['all'].append(wbo) a1 = bond.GetBgn() a2 = bond.GetEnd() sym1 = oechem.OEGetAtomicSymbol(a1.GetAtomicNum()) sym2 = oechem.OEGetAtomicSymbol(a2.GetAtomicNum()) if bond.IsInRing(): wbos['ring'].append(bond.GetData('WibergBondOrder')) if sym1 == 'N' or sym2 == 'N': wbos['N'].append(wbo) if sym1 == 'S' or sym2 == 'S': wbos['S'].append(wbo) if sym1 == 'P' or sym2 == 'P': wbos['P'].append(wbo) if sym1 == 'O' or sym2 == 'O': wbos['O'].append(wbo) if (sym1 == 'C' and sym2 == 'C') and not bond.IsInRing() and not sym1 == 'H' and not sym2 == 'H': wbos['C-C'].append(wbo) if sym1 == 'H' or sym2 == 'H':
def get_symbols(molecule): return [ oechem.OEGetAtomicSymbol(a.GetAtomicNum()) for a in molecule.GetAtoms() ]
def _featurize_atom(atom: oechem.OEAtomBase) -> np.ndarray: """Get atom feature vector atom (oechem.OEAtomBase): OEAtomBase object """ results = ( Nodes.one_of_k_encoding( oechem.OEGetAtomicSymbol(atom.GetAtomicNum()), [ "C", "N", "O", "S", "F", "Si", "P", "Cl", "Br", "Mg", "Na", "Ca", "Fe", "As", "Al", "I", "B", "V", "K", "Tl", "Yb", "Sb", "Sn", "Ag", "Pd", "Co", "Se", "Ti", "Zn", "H", # H? "Li", "Ge", "Cu", "Au", "Ni", "Cd", "In", "Mn", "Zr", "Cr", "Pt", "Hg", "Pb", "Unknown", ], unk=True ) + Nodes.one_of_k_encoding( atom.GetDegree(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ) + Nodes.one_of_k_encoding( atom.GetImplicitHCount(), [0, 1, 2, 3, 4, 5, 6], unk=True ) + [atom.GetFormalCharge()] + Nodes.one_of_k_encoding( atom.GetHyb(), [ oechem.OEHybridization_Unknown, oechem.OEHybridization_sp, oechem.OEHybridization_sp2, oechem.OEHybridization_sp3, oechem.OEHybridization_sp3d, oechem.OEHybridization_sp3d2, ], ) + [atom.IsAromatic()] + Nodes.one_of_k_encoding( atom.GetExplicitHCount(), [0, 1, 2, 3, 4], unk=True ), ) return np.array(results)
def has_stereo_defined(molecule): """ Check if any stereochemistry in undefined. Parameters ---------- molecule: OEMol Returns ------- bool: True if all stereo chemistry is defined. If any stereochemsitry is undefined, raise and exception. """ # perceive stereochemistry oechem.OEPerceiveChiral(molecule) oechem.OE3DToAtomStereo(molecule) oechem.OE3DToBondStereo(molecule) unspec_chiral = False unspec_db = False problematic_atoms = list() problematic_bonds = list() for atom in molecule.GetAtoms(): if atom.IsChiral() and not atom.HasStereoSpecified( oechem.OEAtomStereo_Tetrahedral): # Check if handness is specified v = [] for nbr in atom.GetAtoms(): v.append(nbr) stereo = atom.GetStereo(v, oechem.OEAtomStereo_Tetrahedral) if stereo == oechem.OEAtomStereo_Undefined: unspec_chiral = True problematic_atoms.append( (atom.GetIdx(), oechem.OEGetAtomicSymbol(atom.GetAtomicNum()))) for bond in molecule.GetBonds(): if bond.IsChiral() and not bond.HasStereoSpecified( oechem.OEBondStereo_CisTrans): v = [] for neigh in bond.GetBgn().GetAtoms(): if neigh != bond.GetEnd(): v.append(neigh) break for neigh in bond.GetEnd().GetAtoms(): if neigh != bond.GetBgn(): v.append(neigh) break stereo = bond.GetStereo(v, oechem.OEBondStereo_CisTrans) if stereo == oechem.OEBondStereo_Undefined: unspec_db = True a1 = bond.GetBgn() a2 = bond.GetEnd() a1_idx = a1.GetIdx() a2_idx = a2.GetIdx() a1_s = oechem.OEGetAtomicSymbol(a1.GetAtomicNum()) a2_s = oechem.OEGetAtomicSymbol(a2.GetAtomicNum()) bond_order = bond.GetOrder() problematic_bonds.append( (a1_idx, a1_s, a2_idx, a2_s, bond_order)) if unspec_chiral or unspec_db: warnings.warn( "Stereochemistry is unspecified. Problematic atoms {}, problematic bonds {}, SMILES: {}" .format(problematic_atoms, problematic_bonds, oechem.OEMolToSmiles(molecule))) return False else: return True
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall OpenEye be # liable for any damages or liability in connection with the Sample Code # or its use. # @ <SNIPPET> from __future__ import print_function from openeye import oechem import sys if len(sys.argv) != 2: oechem.OEThrow.Usage("%s <input>" % sys.argv[0]) ifs = oechem.oemolistream() if not ifs.open(sys.argv[1]): oechem.OEThrow.Fatal("Unable to open %s" % sys.argv[1]) for mol in ifs.GetOEGraphMols(): print(mol.NumAtoms()) print(mol.GetTitle()) coords = oechem.OEFloatArray(mol.GetMaxAtomIdx() * 3) mol.GetCoords(coords) for atom in mol.GetAtoms(): idx = atom.GetIdx() syb = oechem.OEGetAtomicSymbol(atom.GetAtomicNum()) print("%-3s%11.5f%11.5f%11.5f" % (syb, coords[idx * 3], coords[idx * 3 + 1], coords[idx * 3 + 2])) # @ </SNIPPET>
def debugTypes(self, mol): for atom in mol.GetAtoms(): print "%6d %8s %8s" % ( atom.GetIdx(), oechem.OEGetAtomicSymbol( atom.GetAtomicNum()), atom.GetStringData(self.pattyTag))
def __str__(self): return "%i%s" % (self._idx, oechem.OEGetAtomicSymbol(self.atomic_number())) def atomic_number(self): return self.atom.GetAtomicNum()