def testOBMolSeparatePreservesAtomOrder(self): """Originally Separate() preserved DFS order rather than atom order""" # First test smi = "C123.F3.Cl2.Br1" mol = pybel.readstring("smi", smi) atomicnums = [atom.OBAtom.GetAtomicNum() for atom in mol] mols = mol.OBMol.Separate() new_atomicnums = [ atom.OBAtom.GetAtomicNum() for atom in pybel.Molecule(mols[0]) ] for x, y in zip(atomicnums, new_atomicnums): self.assertEqual(x, y) # check that the atoms have not been permuted # Second test xyz = """6 examples/water_dimer.xyz O 0.12908 -0.26336 0.64798 H 0.89795 0.28805 0.85518 H 0.10833 -0.20468 -0.33302 O 0.31020 0.07569 -2.07524 H 0.64083 -0.57862 -2.71449 H -0.26065 0.64232 -2.62218 """ mol = pybel.readstring("xyz", xyz) mols = mol.OBMol.Separate() allatoms = pybel.Molecule(mols[0]).atoms + pybel.Molecule( mols[1]).atoms for idx, atom in enumerate(allatoms): xcoord = atom.OBAtom.GetX() orig_xcoord = mol.OBMol.GetAtom(idx + 1).GetX() self.assertEqual(xcoord, orig_xcoord)
def test_rb_basic(): # DNM mol = calc_props.smiles_to_ob("CC(C1=CC(C(C)=CC(N2C)=O)=C2C3=C1N4CO3)=CC4=O") pymol = pybel.Molecule(mol) assert_equals(calc_props.rotatable_bonds(pymol), 0) # Ribocil C mol = calc_props.smiles_to_ob("C1CC(CN(C1)CC2=CN(C=N2)C3=NC=CC=N3)C4=NC(=O)C=C(N4)C5=CC=CS5") pymol = pybel.Molecule(mol) assert_equals(calc_props.rotatable_bonds(pymol), 5) # Triphenylphosphine mol = calc_props.smiles_to_ob("C1(P(C2=CC=CC=C2)C3=CC=CC=C3)=CC=CC=C1") pymol = pybel.Molecule(mol) assert_equals(calc_props.rotatable_bonds(pymol), 3)
def testBondOrders(self): mol = pybel.readstring("smi", "O=C=O") bv = self.createBitVec(3, (2, 3)) bondbv = self.createBitVec(2, (1,)) ans = ["[C].[O]", "C.O", "C(=*)=*.O=*"] for option in range(3): nmol = ob.OBMol() ok = mol.OBMol.CopySubstructure(nmol, bv, bondbv, option) self.assertTrue(ok) self.assertEqual(pybel.Molecule(nmol).write("smi").rstrip(), ans[option]) ans = ["[C]=O", "C=O", "C(=O)=*"] for option in range(3): nmol = ob.OBMol() ok = mol.OBMol.CopySubstructure(nmol, bv, None, option) self.assertTrue(ok) self.assertEqual(pybel.Molecule(nmol).write("smi").rstrip(), ans[option])
def _write_input(self, input_dir="."): """ Write the packmol input file to the input directory. Args: input_dir (string): path to the input directory """ with open(os.path.join(input_dir, self.input_file), "wt", encoding="utf-8") as inp: for k, v in self.control_params.items(): inp.write(f"{k} {self._format_param_val(v)}\n") # write the structures of the constituent molecules to file and set # the molecule id and the corresponding filename in the packmol # input file. for idx, mol in enumerate(self.mols): filename = os.path.join(input_dir, f"{idx}.{self.control_params['filetype']}") # pdb if self.control_params["filetype"] == "pdb": self.write_pdb(mol, filename, num=idx + 1) # all other filetypes else: a = BabelMolAdaptor(mol) pm = pb.Molecule(a.openbabel_mol) pm.write( self.control_params["filetype"], filename=filename, overwrite=True, ) inp.write("\n") inp.write(f"structure {os.path.join(input_dir, str(idx))}.{self.control_params['filetype']}\n") for k, v in self.param_list[idx].items(): inp.write(f" {k} {self._format_param_val(v)}\n") inp.write("end structure\n")
def xyz_to_pyMol(xyz, cluster_bond_path=None): mol = next(pybel.readfile('xyz', xyz)) if cluster_bond_path: m = pybel.ob.OBMol() m.BeginModify() for atom in mol: coords = [coord for coord in atom.coords] atomno = atom.atomicnum obatom = ob.OBAtom() obatom.thisown = 0 obatom.SetAtomicNum(atomno) obatom.SetVector(*coords) m.AddAtom(obatom) del obatom with open(cluster_bond_path, 'r') as f: lines = f.read() cluster_bond = eval(lines) bonds = [(bond.GetBeginAtomIdx(), bond.GetEndAtomIdx(), bond.GetBondOrder()) for bond in pybel.ob.OBMolBondIter(mol.OBMol)] bonds.extend(cluster_bond) for bond in bonds: m.AddBond(bond[0], bond[1], bond[2]) pybelmol = pybel.Molecule(m) return pybelmol else: return mol
def testStereo(self): data = [ ("FC[C@@](Br)(Cl)I", [((2, 3, 4, 5, 6), None, "C[C@@](Br)(Cl)I"), ((2, 3, 4, 5), None, "CC(Br)Cl"), ((1, 2, 3, 4, 5, 6), (4, ), "FCC(Br)Cl.I")]), ("[C@@H](Br)(Cl)I", [((1, 2, 3), None, "C(Br)Cl"), ((1, 2, 3, 4), (2, ), "C(Br)Cl.I")]), ("C[C@@H]1CO1", [ ((2, 3, 4), None, "C1CO1"), ]), ("F/C=C/I", [((1, 2, 3, 4), None, "F/C=C/I"), ((1, 2, 3), None, "FC=C"), ((1, 2, 3, 4), (0, ), "F.C=CI"), ((1, 2, 3, 4), (1, ), "FC.CI")]), ] for smi, d in data: mol = pybel.readstring("smi", smi) for a, b, ans in d: nmol = ob.OBMol() bv = self.createBitVec(7, a) bondbv = None if b is None else self.createBitVec(5, b) ok = mol.OBMol.CopySubstructure(nmol, bv, bondbv) self.assertTrue(ok) if "@" not in ans and "/" not in ans: self.assertFalse(nmol.GetData(ob.StereoData)) self.assertEqual( pybel.Molecule(nmol).write("smi").rstrip(), ans)
def canonicalize(lig, preserve_bond_order=False): """Get the canonical atom order for the ligand.""" atomorder = None # Get canonical atom order lig = pybel.ob.OBMol(lig.OBMol) if not preserve_bond_order: for bond in pybel.ob.OBMolBondIter(lig): if bond.GetBondOrder() != 1: bond.SetBondOrder(1) lig.DeleteData(pybel.ob.StereoData) lig = pybel.Molecule(lig) testcan = lig.write(format='can') try: pybel.readstring('can', testcan) reference = pybel.readstring('can', testcan) except IOError: testcan, reference = '', '' if testcan != '': reference.removeh() isomorphs = get_isomorphisms( reference, lig) # isomorphs now holds all isomorphisms within the molecule if not len(isomorphs) == 0: smi_dict = {} smi_to_can = isomorphs[0] for x in smi_to_can: smi_dict[int(x[1]) + 1] = int(x[0]) + 1 atomorder = [smi_dict[x + 1] for x in range(len(lig.atoms))] else: atomorder = None return atomorder
def testAtomMapsAfterCopying(self): """Copying a molecule should copy the atom maps""" smi = "C[CH2:2]O[Cl:6]" obmol = pybel.readstring("smi", smi).OBMol copy = pybel.ob.OBMol(obmol) copysmi = pybel.Molecule(copy).write("smi", opt={"a": True}) self.assertEqual(copysmi.rstrip(), smi)
def restore_site_properties(self, site_property="ff_map", filename=None): """ Restore the site properties for the final packed molecule. Args: site_property (str): filename (str): path to the final packed molecule. Returns: Molecule """ # only for pdb if not self.control_params["filetype"] == "pdb": raise ValueError() filename = filename or self.control_params["output"] bma = BabelMolAdaptor.from_file(filename, "pdb") pbm = pb.Molecule(bma._obmol) assert len(pbm.residues) == sum(x["number"] for x in self.param_list) packed_mol = self.convert_obatoms_to_molecule( pbm.residues[0].atoms, residue_name=pbm.residues[0].name, site_property=site_property, ) for resid in pbm.residues[1:]: mol = self.convert_obatoms_to_molecule(resid.atoms, residue_name=resid.name, site_property=site_property) for site in mol: packed_mol.append(site.species, site.coords, properties=site.properties) return packed_mol
def add_hydrogen(self): from openbabel import pybel as pb mol_0d = pb.readstring("smi", "CCCC").OBMol self.assertEqual(len(pb.Molecule(mol_0d).atoms), 2) adaptor = BabelMolAdaptor(mol_0d) adaptor.add_hydrogen() self.assertEqual(len(adaptor.pymatgen_mol.sites), 14)
def test_glob(): obmol = openbabel.OBMol() obConv = openbabel.OBConversion() obConv.SetInFormat("mol") obConv.ReadFile(obmol, os.path.join(THIS_DIR, "data/triphenylphosphine.mol")) pymol = pybel.Molecule(obmol) points = calc_props.get_atom_coords(pymol) assert_almost_equal(calc_props.calc_glob(points), 0.245503, 6, 1)
def json_to_pybel(data): """Converts a python data structure to pybel.Molecule. The data structure is a plain python object of the form: ``` { "atoms": [{"location": [0, 0, 0], "element": "H", "label": "H1", "charge": 0}, ...], "bonds": [{"source": 0, "target": 0, "order": 1}, ...], "unitcell": [[0, 0, 0], [0, 0, 0], [0, 0, 0]] } ``` It is referred to as "json" because this data structure is intended to be read from and written to json files or databases. As RASPA makes no use of bond information, this field is ignored. The labels are stripped and replaced with "MOF_{element}", in accordance with the CrystalGenerator forcefield notation. Therefore, labels are also ignored. Args: data: the molecule, as a python object Returns: An instance of `pybel.Molecule` """ if not PYBEL_LOADED: raise ImportError("Open Babel not installed.") if "building_blocks" in data: data["atoms"] = [ a for bb in data["building_blocks"] for a in bb["atoms"] ] obmol = pybel.ob.OBMol() obmol.BeginModify() for atom in data["atoms"]: obatom = obmol.NewAtom() obatom.SetAtomicNum(GetAtomicNum(str(atom["element"]))) obatom.SetVector(*atom["location"]) uc = pybel.ob.OBUnitCell() uc.SetData(*(pybel.ob.vector3(*v) for v in data["unitcell"])) uc.SetSpaceGroup("P1") obmol.CloneData(uc) obmol.EndModify() mol = pybel.Molecule(obmol) # Add partial charges if "charge" in data["atoms"][0]: mol.OBMol.SetPartialChargesPerceived() for atom, pyatom in zip(data["atoms"], mol.atoms): pyatom.OBAtom.SetPartialCharge(atom["charge"]) return mol
def testBasic(self): mol = pybel.readstring("smi", "ICBr") bv = self.createBitVec(4, (1, 3)) nmol = ob.OBMol() ok = mol.OBMol.CopySubstructure(nmol, bv, None, 0) self.assertTrue(ok) self.assertEqual(pybel.Molecule(nmol).write("smi").rstrip(), "[I].[Br]") bv = self.createBitVec(4, (2,)) ok = mol.OBMol.CopySubstructure(nmol, bv, None, 0) self.assertTrue(ok) self.assertEqual(pybel.Molecule(nmol).write("smi").rstrip(), "[I].[Br].[CH2]") mol = pybel.readstring("smi", "CCC") bv = self.createBitVec(4, (1,)) bondv = self.createBitVec(2, (1,)) nmol = ob.OBMol() ok = mol.OBMol.CopySubstructure(nmol, bv, bondv, 0) self.assertTrue(ok)
def testResidueCopying(self): smi = "C[C@@H](C(=O)N[C@@H](CS)C(=O)O)N" # H-Ala-Cys-OH mol = pybel.readstring("smi", smi).OBMol ob.cvar.chainsparser.PerceiveChains(mol) mol.SetChainsPerceived() residues = list(ob.OBResidueIter(mol)) self.assertEqual(len(residues), 2) # Copy just the Cys N bv = self.createBitVec(mol.NumAtoms() + 1, (5, )) nmol = ob.OBMol() mol.CopySubstructure(nmol, bv) self.assertEqual(len(list(ob.OBResidueIter(nmol))), 1) pdb = pybel.Molecule(nmol).write("pdb") atoms = [line for line in pdb.split("\n") if line.startswith("ATOM")] self.assertEqual(len(atoms), 1) cysN = "ATOM 1 N CYS A 2" self.assertTrue(atoms[0].startswith(cysN)) # Copy the Cys N and Ca bv = self.createBitVec(mol.NumAtoms() + 1, (5, 6)) nmol.Clear() mol.CopySubstructure(nmol, bv) self.assertEqual(len(list(ob.OBResidueIter(nmol))), 1) pdb = pybel.Molecule(nmol).write("pdb") atoms = [line for line in pdb.split("\n") if line.startswith("ATOM")] self.assertEqual(len(atoms), 2) self.assertTrue(atoms[0].startswith(cysN)) cysCa = "ATOM 2 CA CYS A 2" self.assertTrue(atoms[1].startswith(cysCa)) # Copy the Ala C and Cys N bv = self.createBitVec(mol.NumAtoms() + 1, (3, 5)) nmol.Clear() mol.CopySubstructure(nmol, bv) self.assertEqual(len(list(ob.OBResidueIter(nmol))), 2) pdb = pybel.Molecule(nmol).write("pdb") atoms = [line for line in pdb.split("\n") if line.startswith("ATOM")] self.assertEqual(len(atoms), 2) alaC = "ATOM 1 C ALA A 1" self.assertTrue(atoms[0].startswith(alaC)) cysN = "ATOM 2 N CYS A 2" self.assertTrue(atoms[1].startswith(cysN))
def write_file(self, filename, file_format="xyz"): """ Uses OpenBabel to output all supported formats. Args: filename: Filename of file to output file_format: String specifying any OpenBabel supported formats. """ mol = pb.Molecule(self._obmol) return mol.write(file_format, filename, overwrite=True)
def testLeaveUnchanged(self): data = [ "CC[N+](=O)[O-]", # nitro "c1ccc[n+]([O-])c1", # pyridine N-oxide "C1=NC(=O)NC(=O)C1=[N+]=N", # diazenium ] for smi in data: mol = pybel.readstring("smi", smi).OBMol neutralize(mol) self.assertEqual(smi, pybel.Molecule(mol).write("smi").rstrip())
def testSpecifyAtomsAndBonds(self): # Now copy just a subset of atoms too mol = pybel.readstring("smi", "ICBr") bv = self.createBitVec(4, (1, 3)) bondbv = self.createBitVec(2, (1,)) ans = ["[I].[Br]", "I.Br", "I*.Br*"] for option in range(3): nmol = ob.OBMol() ok = mol.OBMol.CopySubstructure(nmol, bv, bondbv, option) self.assertTrue(ok) self.assertEqual(pybel.Molecule(nmol).write("smi").rstrip(), ans[option])
def json_to_pybel(data, infer_bonds=False): """Converts python data structure to pybel.Molecule. This will infer bond data if not specified. Args: data: The loaded json data of a molecule, as a Python object infer_bonds (Optional): If no bonds specified in input, infer them Returns: An instance of `pybel.Molecule` """ obmol = ob.OBMol() obmol.BeginModify() for atom in data['atoms']: obatom = obmol.NewAtom() obatom.SetAtomicNum(table.GetAtomicNum(str(atom['element']))) obatom.SetVector(*atom['location']) if 'label' in atom: pd = ob.OBPairData() pd.SetAttribute('_atom_site_label') pd.SetValue(atom['label']) obatom.CloneData(pd) # If there is no bond data, try to infer them if 'bonds' not in data or not data['bonds']: if infer_bonds: obmol.ConnectTheDots() obmol.PerceiveBondOrders() # Otherwise, use the bonds in the data set else: for bond in data['bonds']: if 'atoms' not in bond: continue obmol.AddBond(bond['atoms'][0] + 1, bond['atoms'][1] + 1, bond['order']) # Check for unit cell data if 'unitcell' in data: uc = ob.OBUnitCell() uc.SetData(*(ob.vector3(*v) for v in data['unitcell'])) uc.SetSpaceGroup('P1') obmol.CloneData(uc) obmol.EndModify() mol = pybel.Molecule(obmol) # Add partial charges if 'charge' in data['atoms'][0]: mol.OBMol.SetPartialChargesPerceived() for atom, pyatom in zip(data['atoms'], mol.atoms): pyatom.OBAtom.SetPartialCharge(atom['charge']) return mol
def localopt(self, forcefield='mmff94', steps=500): """ A wrapper to pybel's localopt method to optimize a Molecule. Args: forcefield: Default is mmff94. Options are 'gaff', 'ghemical', 'mmff94', 'mmff94s', and 'uff'. steps: Default is 500. """ pbmol = pb.Molecule(self._obmol) pbmol.localopt(forcefield=forcefield, steps=steps) self._obmol = pbmol.OBMol
def testFacade(self): parts = "CNO" mol = pybel.readstring("smi", ">".join(parts)).OBMol facade = ob.OBReactionFacade(mol) # basic test - copy out each component comps = [ob.REACTANT, ob.AGENT, ob.PRODUCT] for part, comp in zip(parts, comps): nmol = ob.OBMol() facade.GetComponent(nmol, comp, 0) nsmi = pybel.Molecule(nmol).write("smi").rstrip() self.assertEqual(nsmi, part) nmol = ob.OBMol() facade.GetComponent(nmol, ob.NO_REACTIONROLE, 0) self.assertEqual(0, nmol.NumAtoms()) # Reassign role facade.ReassignComponent(ob.AGENT, 0, ob.NO_REACTIONROLE) nsmi = pybel.Molecule(mol).write("smi").rstrip() self.assertEqual("C>>O", nsmi) # ...and back again facade.ReassignComponent(ob.NO_REACTIONROLE, 0, ob.AGENT) # Add a new reactant molb = pybel.readstring("smi", "S").OBMol facade.AddComponent(molb, ob.REACTANT) nsmi = pybel.Molecule(mol).write("smi").rstrip() self.assertEqual("C.S>N>O", nsmi) # ...and copy it back out nmol = ob.OBMol() facade.GetComponent(nmol, ob.REACTANT, 1) nsmi = pybel.Molecule(nmol).write("smi").rstrip() self.assertEqual("S", nsmi) # ...and also copy the O facade.GetComponent(nmol, ob.PRODUCT, 0) nmol.SetIsReaction() nsmi = pybel.Molecule(nmol).write("smi").rstrip() self.assertEqual("S>>O", nsmi)
def draw(self, conformer_num=0, ipython_3d=True) -> None: """Draw a depiction of the molecule for a given conformer. :param conformer_num: conformer number, if larger than number of conformations available, the last is returned :param ipython_3d: if True 3-dim rotatable graphics is generated """ self.mol.SetConformer(conformer_num) pybel.ipython_3d = ipython_3d try: from IPython.core.display import display display(pybel.Molecule(self.mol)) except ImportError as e: logger.warning(f"Import Error: {e}")
def generate_inter_lp(init_str: pybel.Molecule, end_str: pybel.Molecule, inter: int): int_list = [pybel.Molecule(ob.OBMol()) for i in range(inter)] for i, j in zip(init_str.atoms, end_str.atoms): # define the vector for propagation i_coord = np.array(i.coords) j_coord = np.array(j.coords) coord_vector = (j_coord - i_coord) / (inter + 1) for k in range(inter): # define the atomic position for k-th intermediate and write to OBmol object atom_position = i_coord + coord_vector * (k + 1) newatom = ob.OBAtom() newatom.SetAtomicNum(i.OBAtom.GetAtomicNum()) newatom.SetVector(atom_position[0], atom_position[1], atom_position[2]) int_list[k].OBMol.AddAtom(newatom) return int_list
def testOptions(self): mol = pybel.readstring("smi", "ICBr") bv = self.createBitVec(4, (1, 3)) ans = ["[I].[Br]", "I.Br", "I*.Br*"] ans_atomorder = [[1, 3], [1, 3], [1, 3, 2, 2]] ans_bondorder = [ [], [], [0, 1] ] for option in range(3): nmol = ob.OBMol() atomorder = ob.vectorUnsignedInt() bondorder = ob.vectorUnsignedInt() ok = mol.OBMol.CopySubstructure(nmol, bv, None, option, atomorder, bondorder) self.assertTrue(ok) self.assertEqual(pybel.Molecule(nmol).write("smi").rstrip(), ans[option]) self.assertEqual(ans_atomorder[option], list(atomorder)) self.assertEqual(ans_bondorder[option], list(bondorder))
def pybel_opt(smile, steps): obconversion = ob.OBConversion() obconversion.SetInFormat('smi') obmol = ob.OBMol() obconversion.ReadString(obmol, smile) pbmol = pb.Molecule(obmol) pbmol.make3D(forcefield="uff", steps=50) pbmol.localopt(forcefield="gaff", steps=200) pbmol.localopt(forcefield="mmff94", steps=100) f_f = pb._forcefields["uff"] f_f.Setup(pbmol.OBMol) f_f.ConjugateGradients(steps, 1.0e-9) f_f.GetCoordinates(pbmol.OBMol) #print(f_f.Energy(), f_f.GetUnit()) return pybel2ase(pbmol)
def runvina(infile, outfile, receptor, tmp_file='test.pdbqt', vina=None): obconversion = OBConversion() obconversion.SetInFormat("sdf") obconversion.SetOutFormat("pdbqt") obmol = OBMol() notatend = obconversion.ReadFile(obmol, infile) obmol2 = OBMol(obmol) ofs = pybel.Outputfile("sdf", outfile, overwrite=True) pbar = tqdm() while notatend: pbar.update(1) if obconversion.WriteFile(obmol, tmp_file): try: x = subprocess.check_output([ vina, "--score_only", "--receptor", receptor, "--ligand", tmp_file ], shell=False) # x2 = subprocess.check_output(["/Users/austin/Downloads/rf-score-4/rf-score", "/Users/austin/Downloads/rf-score-4/pdbbind-2014-refined.rf", receptor, tmp_file]) # print(x2) mol2 = pybel.Molecule(obmol2) mol2.data.update({'AutodockVinaRescoreOnly': str(get_aff(x))}) ofs.write(mol2) except subprocess.CalledProcessError as e: print(e) ofs.write(obmol) except ValueError as e: print(e) ofs.write(obmol) else: print("error writing") obmol = OBMol() notatend = obconversion.Read(obmol) obmol2 = OBMol(obmol) pbar.close() print("FAILED")
def _make_openbabel_from_ccdata(self): """Create Open Babel and Pybel molecules from ccData.""" if not hasattr(self.ccdata, 'charge'): logging.warning("ccdata object does not have charge, setting to 0") _charge = 0 else: _charge = self.ccdata.charge if not hasattr(self.ccdata, 'mult'): logging.warning( "ccdata object does not have spin multiplicity, setting to 1") _mult = 1 else: _mult = self.ccdata.mult obmol = makeopenbabel(self.ccdata.atomcoords, self.ccdata.atomnos, charge=_charge, mult=_mult) if self.jobfilename is not None: obmol.SetTitle(self.jobfilename) return (obmol, pb.Molecule(obmol))
def atoms_to_pybel(aseatoms, infer_bonds=True): ''' Convert ASE Atoms isntance into the json format compatible with Args: aseatoms : ase.Atoms Instance of Atoms from ase package infer_bonds : bool If `True` bonds will be inferred using openbabel Returns: mol : dist A dictionary with the json format of the molecule ''' from openbabel import pybel from openbabel import openbabel as ob obmol = ob.OBMol() obmol.BeginModify() for atom in aseatoms: obatom = obmol.NewAtom() obatom.SetAtomicNum(int(atom.number)) obatom.SetVector(*atom.position.tolist()) # If there is no bond data, try to infer them if infer_bonds: obmol.ConnectTheDots() obmol.PerceiveBondOrders() # Check for unit cell data if any(aseatoms.pbc): uc = ob.OBUnitCell() uc.SetData(*(ob.vector3(*v) for v in aseatoms.get_cell())) uc.SetSpaceGroup('P1') obmol.CloneData(uc) obmol.EndModify() mol = pybel.Molecule(obmol) return mol
def _pybel_opt(self, smile, steps): """Optimize a molecule using force field and pybel (needed for complex SMILES).""" obconversion = ob.OBConversion() obconversion.SetInFormat("smi") obmol = ob.OBMol() obconversion.ReadString(obmol, smile) pbmol = pb.Molecule(obmol) pbmol.make3D(forcefield="uff", steps=50) pbmol.localopt(forcefield="gaff", steps=200) pbmol.localopt(forcefield="mmff94", steps=100) f_f = pb._forcefields["uff"] # pylint: disable=protected-access f_f.Setup(pbmol.OBMol) f_f.ConjugateGradients(steps, 1.0e-9) f_f.GetCoordinates(pbmol.OBMol) species = [chemical_symbols[atm.atomicnum] for atm in pbmol.atoms] positions = np.asarray([atm.coords for atm in pbmol.atoms]) return self.make_ase(species, positions)
def write_pdb(mol, filename, name=None, num=None): """ dump the molecule into pdb file with custom residue name and number. """ # ugly hack to get around the openbabel issues with inconsistent # residue labelling. scratch = tempfile.gettempdir() with ScratchDir(scratch, copy_to_current_on_exit=False) as _: mol.to(fmt="pdb", filename="tmp.pdb") bma = BabelMolAdaptor.from_file("tmp.pdb", "pdb") num = num or 1 name = name or "ml{}".format(num) # bma = BabelMolAdaptor(mol) pbm = pb.Molecule(bma._obmol) for i, x in enumerate(pbm.residues): x.OBResidue.SetName(name) x.OBResidue.SetNum(num) pbm.write(format="pdb", filename=filename, overwrite=True)
def make3d(self, forcefield="mmff94", steps=50): """ A wrapper to pybel's make3D method generate a 3D structure from a 2D or 0D structure. The 3D structure is made very quickly using a combination of rules (e.g. sp3 atoms should have four bonds arranged in a tetrahedron) and ring templates (e.g. cyclohexane is shaped like a chair). Once 3D coordinates are generated, hydrogens are added and a quick local optimization is carried out as default. The generated 3D structure can have clashes or have high energy structures due to some strain. Please consider to use the conformer search or geometry optimization to further optimize the structure. Args: forcefield: Default is mmff94. Options are 'gaff', 'ghemical', 'mmff94', 'mmff94s', and 'uff'. steps: Default is 50. """ pbmol = pb.Molecule(self._obmol) pbmol.make3D(forcefield=forcefield, steps=steps) self._obmol = pbmol.OBMol