def test0Conformers(self) : """Test the conformer data structure""" mol = Chem.MolFromSmiles("CC") conf = Chem.Conformer(2) conf.SetAtomPosition(0, (-0.5, 0.0, 0.0)) conf.SetAtomPosition(1, (1.0, 0.0, 0.0)) conf.SetId(0) cid = mol.AddConformer(conf) self.assertTrue(cid == 0) conf2 = mol.GetConformer(0) self.assertTrue(conf2.GetId() == cid) pt1 = conf2.GetAtomPosition(0) self.assertTrue(ptEq(pt1, Point3D(-0.5, 0.0, 0.0))) pt2 = conf2.GetAtomPosition(1) self.assertTrue(ptEq(pt2, Point3D(1.0, 0.0, 0.0))) #changing conf should not change conf2 - related to issue 217 conf.SetAtomPosition(1, Point3D(2.0, 0.0, 0.0)) pt2 = conf2.GetAtomPosition(1) self.assertTrue(feq(pt2[0], 1.0)) conf = Chem.Conformer(2) conf.SetAtomPosition(0, Point3D(-0.5, 0.0, 0.0)) conf.SetAtomPosition(1, Point3D(1.0, 0.0, 0.0)) conf.SetId(2) cid = mol.AddConformer(conf, 0) self.assertTrue(cid == 2) conf3 = mol.GetConformer(2)
def xyz2ac(atomic_num_list, xyz): import numpy as np mol = get_proto_mol(atomic_num_list) conf = Chem.Conformer(mol.GetNumAtoms()) for i in range(mol.GetNumAtoms()): conf.SetAtomPosition(i, (xyz[i][0], xyz[i][1], xyz[i][2])) mol.AddConformer(conf) d_mat = Chem.Get3DDistanceMatrix(mol) pt = Chem.GetPeriodicTable() num_atoms = len(atomic_num_list) ac = np.zeros((num_atoms, num_atoms)).astype(int) for i in range(num_atoms): a_i = mol.GetAtomWithIdx(i) rcov_i = pt.GetRcovalent(a_i.GetAtomicNum()) * 1.24 for j in range(i + 1, num_atoms): a_j = mol.GetAtomWithIdx(j) rcov_j = pt.GetRcovalent(a_j.GetAtomicNum()) * 1.24 if d_mat[i, j] <= rcov_i + rcov_j: ac[i, j] = 1 ac[j, i] = 1 return ac, mol
def make_rd_mol(xyz, c, bonds, channels): rd_mol = Chem.RWMol() for c_ in c: atomic_num = channels[c_].atomic_num rd_atom = Chem.Atom(atomic_num) rd_mol.AddAtom(rd_atom) n_atoms = rd_mol.GetNumAtoms() rd_conf = Chem.Conformer(n_atoms) for i, (x, y, z) in enumerate(xyz): rd_conf.SetAtomPosition(i, (x, y, z)) rd_mol.AddConformer(rd_conf) if np.any(bonds): n_bonds = 0 for i in range(n_atoms): for j in range(i + 1, n_atoms): if bonds[i, j]: rd_mol.AddBond(i, j, Chem.BondType.SINGLE) n_bonds += 1 return rd_mol
def select_conformer(molobj, method=None): """ Find the conformer with lowest energy # TODO Add other energy methods than MMFF # TODO Add interface to ppqm.sqm """ res = AllChem.MMFFOptimizeMoleculeConfs(molobj, numThreads=0) res = np.array(res) energies = res[:,1] not_converged = res[:,1] # TODO Ignore not_converged != 0 idx = np.argmin(energies) coord = molobj_to_coordinates(molobj, idx=idx) conf = Chem.Conformer(len(coord)) for i, xyz in enumerate(coord): conf.SetAtomPosition(i, xyz) molobj = copy.deepcopy(molobj) molobj.RemoveAllConformers() molobj.AddConformer(conf, assignId=True) return molobj
def to_rdmol(plams_mol, sanitize=True): """ Translate a PLAMS molecule into an RDKit molecule type. :parameter plams_mol: PLAMS molecule :type plams_mol: plams.Molecule :return: an RDKit molecule :rtype: rdkit.Chem.Mol """ if isinstance(plams_mol, Chem.Mol): return plams_mol # Create rdkit molecule e = Chem.EditableMol(Chem.Mol()) for atom in plams_mol.atoms: a = Chem.Atom(atom.atnum) if 'charge' in atom.properties: a.SetFormalCharge(atom.properties.charge) if 'pdb_info' in atom.properties: set_PDBresidueInfo(a, atom.properties.pdb_info) e.AddAtom(a) for bond in plams_mol.bonds: a1 = plams_mol.atoms.index(bond.atom1) a2 = plams_mol.atoms.index(bond.atom2) e.AddBond(a1, a2, Chem.BondType(bond.order)) rdmol = e.GetMol() if sanitize: Chem.SanitizeMol(rdmol) conf = Chem.Conformer() for a in range(len(plams_mol.atoms)): atom = plams_mol.atoms[a] p = Geometry.Point3D(atom._getx(), atom._gety(), atom._getz()) conf.SetAtomPosition(a, p) rdmol.AddConformer(conf) return rdmol
def AtomListToSubMol(mol, amap, includeConformer=False): """ Parameters ---------- mol: rdkit.Chem.rdchem.Mol Molecule amap: array-like List of atom indices (zero-based) includeConformer: bool (default=True) Toogle to include atoms coordinates in submolecule. Returns ------- submol: rdkit.Chem.rdchem.RWMol Submol determined by specified atom list """ if not isinstance(amap, list): amap = list(amap) submol = Chem.RWMol(Chem.Mol()) for aix in amap: submol.AddAtom(mol.GetAtomWithIdx(aix)) for i, j in combinations(amap, 2): bond = mol.GetBondBetweenAtoms(i, j) if bond: submol.AddBond(amap.index(i), amap.index(j), bond.GetBondType()) if includeConformer: for conf in mol.GetConformers(): new_conf = Chem.Conformer(len(amap)) for i in range(len(amap)): new_conf.SetAtomPosition(i, conf.GetAtomPosition(amap[i])) new_conf.SetId(conf.GetId()) new_conf.Set3D(conf.Is3D()) submol.AddConformer(new_conf) return submol
def assertBondStereoRoundTrips(self, fname): path = os.path.join(RDConfig.RDCodeDir, 'Chem', 'test_data', fname) mol = Chem.MolFromMolFile(path) refSmiles = mol.GetProp("_Name") self.assertTrue(len(refSmiles) > 0) self.assertEqual(Chem.MolToSmiles(mol, isomericSmiles=True), refSmiles) # now test Chem.DetectBondStereoChemistry more directly by constructing the molecule from scratch oldconf = mol.GetConformer(0) newconf = Chem.Conformer(mol.GetNumAtoms()) newmol = Chem.RWMol() for atm in mol.GetAtoms(): ratm = Chem.Atom(atm.GetAtomicNum()) ratm.SetFormalCharge(atm.GetFormalCharge()) newmol.AddAtom(ratm) atomidx = atm.GetIdx() pos = oldconf.GetAtomPosition(atomidx) newconf.SetAtomPosition(atomidx, pos) for bnd in mol.GetBonds(): newmol.AddBond(bnd.GetBeginAtomIdx(), bnd.GetEndAtomIdx(), Chem.BondType(bnd.GetBondType())) newmol.AddConformer(newconf) Chem.SanitizeMol(newmol) Chem.DetectBondStereoChemistry(newmol, newmol.GetConformer()) # these aren't necessary for this specific test case, but are for # a more general conversion routine, so would like to see them # tested eventually # Chem.AssignAtomChiralTagsFromStructure(newmol) # Chem.AssignStereochemistry(newmol) self.assertEqual(Chem.MolToSmiles(newmol, isomericSmiles=True), refSmiles)
def xyz2AC_huckel(atomicNumList, xyz, charge): import numpy as np mol = get_proto_mol(atomicNumList) conf = Chem.Conformer(mol.GetNumAtoms()) for i in range(mol.GetNumAtoms()): conf.SetAtomPosition(i, (xyz[i][0], xyz[i][1], xyz[i][2])) mol.AddConformer(conf) num_atoms = len(atomicNumList) AC = np.zeros((num_atoms, num_atoms)).astype(int) mol_huckel = Chem.Mol(mol) mol_huckel.GetAtomWithIdx(0).SetFormalCharge( charge) #mol charge arbitrarily added to 1st atom passed, result = rdEHTTools.RunMol(mol_huckel) opop = result.GetReducedOverlapPopulationMatrix() tri = np.zeros((num_atoms, num_atoms)) tri[np.tril(np.ones( (num_atoms, num_atoms), dtype=bool))] = opop #lower triangular to square matrix for i in range(num_atoms): for j in range(i + 1, num_atoms): pair_pop = abs(tri[j, i]) if pair_pop >= 0.15: #arbitry cutoff for bond. May need adjustment AC[i, j] = 1 AC[j, i] = 1 return AC, mol
def createMol(self, resTuples): proteinCoords = getCoordinates(self.protein) asite = Chem.RWMol() self.atomMap['A:P'] = {} for atom in self.protein.GetAtoms(): if atom.GetAtomicNum() == 1: continue res = getIdTupleFromPDBAtom(atom) if res in resTuples: asiteIdx = asite.AddAtom(atom) self.atomMap['A:P'][asiteIdx] = atom.GetIdx() self.atomMap['P:A'] = {v: k for k, v in self.atomMap['A:P'].items()} asiteNatoms = asite.GetNumAtoms() asiteConf = Chem.Conformer(asiteNatoms) for atom in asite.GetAtoms(): asiteConf.SetAtomPosition( atom.GetIdx(), proteinCoords[self.atomMap['A:P'][atom.GetIdx()]]) asite.AddConformer(asiteConf) for atom in asite.GetAtoms(): atom.SetIsAromatic(False) asite = Chem.Mol(asite) return asite
def test0AddHds(self) : mol = Chem.MolFromSmiles("CC") conf = Chem.Conformer(1) conf.SetAtomPosition(0, Point3D(-0.5, 0.0, 0.0)) conf.SetAtomPosition(1, Point3D(1.0, 0.0, 0.0)) cid = mol.AddConformer(conf) conf2 = mol.GetConformer() self.assertTrue(conf2.GetNumAtoms() == 2) nmol = Chem.AddHs(mol, 0,1) conf3 = nmol.GetConformer() self.assertTrue(conf3.GetNumAtoms() == 8) self.assertTrue(conf2.GetNumAtoms() == 2) targetCoords = [[-0.5, 0.0, 0.0], [1.0, 0.0, 0.0], [-0.8667, 0.0, 1.03709], [-0.8667, 0.8981, -0.5185], [-0.8667, -0.8981, -0.5185], [1.3667, 0.0, -1.0371], [1.36667, 0.8981, 0.5185], [1.36667, -0.8981, 0.5185]] for i in range(8) : pt = conf3.GetAtomPosition(i) self.assertTrue(ptEq(pt, Point3D(*tuple(targetCoords[i]))))
def to_RDKMol(self): """Return an RDKMol object for the configuration, template, or subset.""" index = {} indices = [] rdk_mol = Chem.RWMol() for atno, _id in zip(self.atoms.atomic_numbers, self.atoms.ids): idx = rdk_mol.AddAtom(Chem.Atom(atno)) index[_id] = idx indices.append(idx) bond_types = { 1: Chem.BondType.SINGLE, 2: Chem.BondType.DOUBLE, 3: Chem.BondType.TRIPLE, } for row in self.bonds.bonds(): rdk_mol.AddBond(index[row["i"]], index[row["j"]], bond_types[row["bondorder"]]) natom = self.atoms.n_atoms conf = Chem.Conformer(natom) for idx, xyz in zip(indices, self.atoms.coordinates): conf.SetAtomPosition(idx, xyz) rdk_mol.AddConformer(conf) Chem.rdmolops.SanitizeMol(rdk_mol) return rdk_mol
def to_rdmol(plams_mol, sanitize=True): """ Translate a PLAMS molecule into an RDKit molecule type """ # Create rdkit molecule e = Chem.EditableMol(Chem.Mol()) for atom in plams_mol.atoms: a = Chem.Atom(atom.atnum) ch = atom.properties.charge if isinstance(ch, int): a.SetFormalCharge(ch) e.AddAtom(a) for bond in plams_mol.bonds: a1 = plams_mol.atoms.index(bond.atom1) a2 = plams_mol.atoms.index(bond.atom2) e.AddBond(a1, a2, Chem.BondType(bond.order)) rdmol = e.GetMol() if sanitize: Chem.SanitizeMol(rdmol) conf = Chem.Conformer() for a in range(len(plams_mol.atoms)): atom = plams_mol.atoms[a] p = Geometry.Point3D(atom._getx(), atom._gety(), atom._getz()) conf.SetAtomPosition(a, p) rdmol.AddConformer(conf) return rdmol
def xyz2AC(atomicNumList, xyz): mol = get_proto_mol(atomicNumList) conf = Chem.Conformer(mol.GetNumAtoms()) for i in range(mol.GetNumAtoms()): conf.SetAtomPosition(i, (xyz[i][0], xyz[i][1], xyz[i][2])) mol.AddConformer(conf) dMat = Chem.Get3DDistanceMatrix(mol) pt = Chem.GetPeriodicTable() num_atoms = len(atomicNumList) AC = np.zeros((num_atoms, num_atoms)).astype(int) for i in range(num_atoms): a_i = mol.GetAtomWithIdx(i) Rcov_i = pt.GetRcovalent(a_i.GetAtomicNum()) * 1.30 for j in range(i + 1, num_atoms): a_j = mol.GetAtomWithIdx(j) Rcov_j = pt.GetRcovalent(a_j.GetAtomicNum()) * 1.30 if dMat[i, j] <= Rcov_i + Rcov_j: AC[i, j] = 1 AC[j, i] = 1 return AC, mol
def addConf(mol): conf = Chem.Conformer(mol.GetNumAtoms()) for i in range(mol.GetNumAtoms()): conf.SetAtomPosition(i,(0.,0.,0.)) mol.AddConformer(conf) mb = Chem.MolToMolBlock(mol) mb = Chem.MolToMolBlock(mol)
def make_rd_mol(coords, types, bonds, typer): ''' Create an RWMol from numpy arrays of coords and types, optional bonds, and an AtomTyper. No atomic properties other than the elements and coordinates are set. ''' rd_mol = Chem.RWMol() for type_vec in types: atom_type = typer.get_atom_type(type_vec) rd_atom = Chem.Atom(atom_type.atomic_num) rd_mol.AddAtom(rd_atom) n_atoms = rd_mol.GetNumAtoms() rd_conf = Chem.Conformer(n_atoms) for i, coord in enumerate(coords): x, y, z = [float(c) for c in coord] rd_conf.SetAtomPosition(i, (x, y, z)) # must be float64 rd_mol.AddConformer(rd_conf) if bonds is not None and np.any(bonds): n_bonds = 0 for i in range(n_atoms): for j in range(i+1, n_atoms): if bonds[i,j]: rd_mol.AddBond(i, j, Chem.BondType.SINGLE) n_bonds += 1 return rd_mol
def toRDKITmol(mol, protidx, sanitize=True, removeHs=False): # Taken from rdkit/Code/GraphMol/FileParsers/PDBParser.cpp conformer = Chem.Conformer(len(protidx)) conformer.Set3D(True) conformer.SetId(0) rdmol = Chem.RWMol() atomlist = [] for ii, i in enumerate(protidx): a = Chem.Atom(mol.element[i]) a.SetFormalCharge(int(mol.charge[i])) info = Chem.AtomPDBResidueInfo(atomName=mol.name[i], serialNumber=int(mol.serial[i]), altLoc=mol.altloc[i], residueName=mol.resname[i], residueNumber=int(mol.resid[i]), chainId=mol.chain[i], insertionCode=mol.insertion[i], occupancy=float(mol.occupancy[i]), tempFactor=float(mol.beta[i]), isHeteroAtom=mol.record[i] == 'HETATM') a.SetMonomerInfo(info) rdmol.AddAtom(a) atomlist.append(a) coor = [float(c) for c in mol.coords[i, :, mol.frame]] conformer.SetAtomPosition(ii, Point3D(coor[0], coor[1], coor[2])) # Correct the atom idx rdmol.AddConformer(conformer) # Here I diverge from the C++ parser because you cannot instantiate Chem.Bond objects in python # I also don't take into account double/triple bonds etc since I don't think we actually store them in Molecule for b in mol._getBonds(): if b[0] in protidx and b[1] in protidx: bond = rdmol.GetBondBetweenAtoms(int(b[0]), int(b[1])) if bond is None: rdmol.AddBond(int(np.where(protidx == b[0])[0]), int(np.where(protidx == b[1])[0]), Chem.BondType.SINGLE) # Proximitybonds I already did by using _getBonds which calls _guessBonds # TODO: Set PDB double bonds # Calculate explicit valence of atoms for a in atomlist: pass if sanitize: if removeHs: Chem.RemoveHs(rdmol) else: Chem.SanitizeMol(rdmol) else: rdmol.UpdatePropertyCache() # Set tetrahedral chirality from 3D co-ordinates Chem.AssignAtomChiralTagsFromStructure(rdmol) StandardPDBResidueChirality(rdmol) return rdmol
def get_3D_mol(self): mol = Chem.Mol(self.mol) conf = Chem.Conformer(mol.GetNumAtoms()) for i, xyz in enumerate(self.coord): conf.SetAtomPosition(i, xyz) mol.AddConformer(conf) return mol
def EmbedMol(mol, bm, atomMatch=None, weight=2.0, randomSeed=-1, excludedVolumes=None): """ Generates an embedding for a molecule based on a bounds matrix and adds a conformer (id 0) to the molecule if the optional argument atomMatch is provided, it will be used to provide supplemental weights for the embedding routine (used in the optimization phase to ensure that the resulting geometry really does satisfy the pharmacophore). if the excludedVolumes is provided, it should be a sequence of ExcludedVolume objects >>> m = Chem.MolFromSmiles('c1ccccc1C') >>> bounds = MolDG.GetMoleculeBoundsMatrix(m) >>> bounds.shape == (7, 7) True >>> m.GetNumConformers() 0 >>> EmbedMol(m,bounds,randomSeed=23) >>> m.GetNumConformers() 1 """ nAts = mol.GetNumAtoms() weights = [] if (atomMatch): for i in range(len(atomMatch)): for j in range(i + 1, len(atomMatch)): weights.append((i, j, weight)) if (excludedVolumes): for vol in excludedVolumes: idx = vol.index # excluded volumes affect every other atom: for i in range(nAts): weights.append((i, idx, weight)) coords = DG.EmbedBoundsMatrix(bm, weights=weights, numZeroFail=1, randomSeed=randomSeed) #for row in coords: # print(', '.join(['%.2f'%x for x in row])) conf = Chem.Conformer(nAts) conf.SetId(0) for i in range(nAts): conf.SetAtomPosition(i, list(coords[i])) if excludedVolumes: for vol in excludedVolumes: vol.pos = numpy.array(coords[vol.index]) #print(' % 7.4f % 7.4f % 7.4f Ar 0 0 0 0 0 0 0 0 0 0 0 0'%tuple(coords[-1]), file=sys.stderr) mol.AddConformer(conf)
def RDMolFromGraphs(node_list, adjacency_matrix, xyz_coord, remap=None): #xyz_mean = [0.5567917341433811, 0.10013086135351022, 0.006413393431574624] #xyz_std = [3.40762324684836, 2.6455335437418093, 2.3609727916942096] #print(xyz_coord) #xyz_coord = xyz_coord * xyz_std + xyz_mean #print(xyz_coord) # create empty editable mol object mol = Chem.RWMol() conformer = Chem.Conformer(len(node_list)) #print(xyz_coord) # add atoms to mol and keep track of index node_to_idx = {} for i in range(len(node_list)): a = Chem.Atom(node_list[i]) atom_position = Point3D(xyz_coord[i, 0], xyz_coord[i, 1], xyz_coord[i, 2]) #print(a) conformer.SetAtomPosition(i, atom_position) molIdx = mol.AddAtom(a) node_to_idx[i] = molIdx # add bonds between adjacent atoms xx, yy = np.where(np.triu(adjacency_matrix, k=1)) vv = adjacency_matrix[xx, yy] for ix, iy, bond in zip(xx, yy, vv): # add relevant bond type (there are many more of these) if remap is not None: bond = remap[bond] if bond == 1.: bond_type = Chem.rdchem.BondType.SINGLE mol.AddBond(node_to_idx[ix], node_to_idx[iy], bond_type) elif bond == 1.5: bond_type = Chem.rdchem.BondType.AROMATIC mol.AddBond(node_to_idx[ix], node_to_idx[iy], bond_type) elif bond == 2.: bond_type = Chem.rdchem.BondType.DOUBLE mol.AddBond(node_to_idx[ix], node_to_idx[iy], bond_type) elif bond == 3.: bond_type = Chem.rdchem.BondType.TRIPLE mol.AddBond(node_to_idx[ix], node_to_idx[iy], bond_type) else: raise ValueError("Invalid bond type in matrix") # Convert RWMol to Mol object mol = mol.GetMol() Chem.Kekulize(mol) Chem.SanitizeMol(mol) # Convert RWMol to SMILES # Chem.RemoveHs(mol) smiles = Chem.MolToSmiles(mol, kekuleSmiles=False) #print(smiles) # Add 3D conformation to RDKit molecule added_conformer = mol.AddConformer(conformer, assignId=True) return smiles, mol
def mol_from_json(symbols, connectivity, geometry, permute_xyz=False): """ Generate RDkit.Chem.Mol from QCSchema molecule specs. Parameters ---------- inp_molecule: dict Must include symbols and connectivity. Geometry is optional. If geometry is given, stereochemistry will be taken from coordinates Returns ------- molecule: rdkit.Chem.Mol """ from rdkit.Geometry.rdGeometry import Point3D _BO_DISPATCH_TABLE = { 1: Chem.BondType.SINGLE, 2: Chem.BondType.DOUBLE, 3: Chem.BondType.TRIPLE } geometry = geometry.reshape(int(len(geometry) / 3), 3) conformer = Chem.Conformer(len(symbols)) has_geometry = True molecule = Chem.Mol() em = Chem.RWMol(molecule) for i, s in enumerate(symbols): atom = em.AddAtom(Chem.Atom(_symbols[s])) atom_position = Point3D(geometry[i][0], geometry[i][1], geometry[i][2]) conformer.SetAtomPosition(atom, atom_position) # Add connectivity for bond in connectivity: bond_type = _BO_DISPATCH_TABLE[bond[-1]] em.AddBond(bond[0], bond[1], bond_type) molecule = em.GetMol() try: Chem.SanitizeMol(molecule) except: raise RuntimeError("Could not sanitize molecule") # Add coordinates if has_geometry: initial_conformer_id = molecule.AddConformer(conformer, assignId=True) # Assign stereochemistry from coordinates from rdkit.Chem import rdmolops rdmolops.AssignStereochemistryFrom3D(molecule, confId=initial_conformer_id, replaceExistingTags=True) if not permute_xyz: # Add a tag to keep current order molecule.SetProp("_json_geometry", '1') return molecule
def create_rdkit_mol(species, coords, bond_types, formal_charge=None, name=None, force_sanitize=True): """ Create a rdkit mol from scratch. Followed: https://sourceforge.net/p/rdkit/mailman/message/36474923/ Args: species (list): species str of each molecule coords (2D array): positions of atoms bond_types (dict): with bond indices (2 tuple) as key and bond type (e.g. Chem.rdchem.BondType.DOUBLE) as value formal_charge (list): formal charge of each atom name (str): name of the molecule force_sanitize (bool): whether to force the sanitization of molecule. If `True` and the sanitization fails, it generally throw an error and then stops. If `False`, will try to sanitize first, but if it fails, will proceed smoothly giving a warning message. Returns: rdkit Chem.Mol """ m = Chem.Mol() edm = Chem.EditableMol(m) conformer = Chem.Conformer(len(species)) for i, (s, c) in enumerate(zip(species, coords)): atom = Chem.Atom(s) atom.SetNoImplicit(True) if formal_charge is not None: cg = formal_charge[i] if cg is not None: atom.SetFormalCharge(cg) atom_idx = edm.AddAtom(atom) conformer.SetAtomPosition(atom_idx, Point3D(*c)) for b, t in bond_types.items(): edm.AddBond(b[0], b[1], t) m = edm.GetMol() if force_sanitize: Chem.SanitizeMol(m) else: try: Chem.SanitizeMol(m) except Exception as e: warnings.warn(f"Cannot sanitize molecule {name}, because {str(e)}") m.AddConformer(conformer, assignId=False) m.SetProp("_Name", str(name)) return m
def _generate_conformer(coordinates): # generate a conformation object new_conf = Chem.Conformer() for idx, c in enumerate(coordinates): point = Geometry.rdGeometry.Point3D() point.x = float(c[0].value_in_unit(unit.angstrom)) point.y = float(c[1].value_in_unit(unit.angstrom)) point.z = float(c[2].value_in_unit(unit.angstrom)) new_conf.SetAtomPosition(idx, point) return new_conf
def add_conformer(molobj, coordinates): conf = Chem.Conformer(len(coordinates)) for i, coordinate in enumerate(coordinates): conf.SetAtomPosition(i, coordinate) molobj.AddConformer(conf, assignId=True) return
def make_conformer(mol, conf_a, conf_b): mol.RemoveAllConformers() mol = Chem.CombineMols(mol, mol) cc = Chem.Conformer(mol.GetNumAtoms()) conf = np.concatenate([conf_a, conf_b]) conf *= 10 for idx, pos in enumerate(onp.asarray(conf)): cc.SetAtomPosition(idx, (float(pos[0]), float(pos[1]), float(pos[2]))) mol.AddConformer(cc) return mol
def testGithub4167(self): with Chem.SDMolSupplier(os.path.join(self.dataDir, 'github4167.sdf'), removeHs=False, sanitize=True) as suppl: m1 = suppl[0] m2 = suppl[1] m1.AddConformer(Chem.Conformer(m2.GetConformer()), assignId=True) v1_0 = rdMD.CalcSpherocityIndex(m1) v1_1 = rdMD.CalcSpherocityIndex(m1, confId=1, force=True) v2 = rdMD.CalcSpherocityIndex(m2) self.assertNotEqual(v1_0, v1_1) self.assertEqual(v1_1, v2)
def _getRDKitEnv(mol, bondPath, baseRad, aromaticColor, extraColor, nonAromaticColor, **kwargs): if not mol.GetNumConformers(): rdDepictor.Compute2DCoords(mol) # get the atoms for highlighting atomsToUse = set() for b in bondPath: atomsToUse.add(mol.GetBondWithIdx(b).GetBeginAtomIdx()) atomsToUse.add(mol.GetBondWithIdx(b).GetEndAtomIdx()) # set the coordinates of the submol based on the coordinates of the original molecule amap = {} submol = Chem.PathToSubmol(mol, bondPath, atomMap=amap) Chem.FastFindRings(submol) conf = Chem.Conformer(submol.GetNumAtoms()) confOri = mol.GetConformer(0) for i1, i2 in amap.items(): conf.SetAtomPosition(i2, confOri.GetAtomPosition(i1)) submol.AddConformer(conf) envSubmol = [] for i1, i2 in amap.items(): for b in bondPath: beginAtom = amap[mol.GetBondWithIdx(b).GetBeginAtomIdx()] endAtom = amap[mol.GetBondWithIdx(b).GetEndAtomIdx()] envSubmol.append( submol.GetBondBetweenAtoms(beginAtom, endAtom).GetIdx()) # color all atoms of the submol in gray which are not part of the bit # highlight atoms which are in rings atomcolors, bondcolors = {}, {} highlightAtoms, highlightBonds = [], [] highlightRadii = {} for aidx in amap.keys(): if aidx in atomsToUse: color = None if aromaticColor and mol.GetAtomWithIdx(aidx).GetIsAromatic(): color = aromaticColor elif nonAromaticColor and not mol.GetAtomWithIdx( aidx).GetIsAromatic(): color = nonAromaticColor if color is not None: atomcolors[amap[aidx]] = color highlightAtoms.append(amap[aidx]) highlightRadii[amap[aidx]] = baseRad color = extraColor for bid in submol.GetBonds(): bidx = bid.GetIdx() if bidx not in envSubmol: bondcolors[bidx] = color highlightBonds.append(bidx) return FingerprintEnv(submol, highlightAtoms, atomcolors, highlightBonds, bondcolors, highlightRadii)
def ob_mol_to_rd_mol(ob_mol): ''' Convert an OBMol to an RWMol, copying over the elements, coordinates, formal charges, bonds and aromaticity. ''' n_atoms = ob_mol.NumAtoms() rd_mol = Chem.RWMol() rd_conf = Chem.Conformer(n_atoms) for ob_atom in ob.OBMolAtomIter(ob_mol): rd_atom = Chem.Atom(ob_atom.GetAtomicNum()) rd_atom.SetFormalCharge(ob_atom.GetFormalCharge()) rd_atom.SetIsAromatic(ob_atom.IsAromatic()) rd_atom.SetNumExplicitHs(ob_atom.GetImplicitHCount()) rd_atom.SetNoImplicit(True) # don't use rdkit valence model rd_atom.SetHybridization(ob_hyb_to_rd_hyb(ob_atom)) idx = rd_mol.AddAtom(rd_atom) rd_coords = Geometry.Point3D( ob_atom.GetX(), ob_atom.GetY(), ob_atom.GetZ() ) rd_conf.SetAtomPosition(idx, rd_coords) rd_mol.AddConformer(rd_conf) for ob_bond in ob.OBMolBondIter(ob_mol): # OB uses 1-indexing, rdkit uses 0 i = ob_bond.GetBeginAtomIdx() - 1 j = ob_bond.GetEndAtomIdx() - 1 bond_order = ob_bond.GetBondOrder() if bond_order == 1: bond_type = Chem.BondType.SINGLE elif bond_order == 2: bond_type = Chem.BondType.DOUBLE elif bond_order == 3: bond_type = Chem.BondType.TRIPLE else: raise Exception('unknown bond order {}'.format(bond_order)) rd_mol.AddBond(i, j, bond_type) rd_bond = rd_mol.GetBondBetweenAtoms(i, j) rd_bond.SetIsAromatic(ob_bond.IsAromatic()) Chem.GetSSSR(rd_mol) # initialize ring info rd_mol.UpdatePropertyCache(strict=False) # compute valence return rd_mol
def make_conformer(mol, conf_a, conf_b): """Remove all of mol's conformers, make a new mol containing two copies of mol, assign positions to each copy using conf_a and conf_b, respectively, assumed in nanometers""" mol.RemoveAllConformers() mol = Chem.CombineMols(mol, mol) cc = Chem.Conformer(mol.GetNumAtoms()) conf = np.concatenate([conf_a, conf_b]) conf *= 10 # TODO: label this unit conversion? for idx, pos in enumerate(np.asarray(conf)): cc.SetAtomPosition(idx, (float(pos[0]), float(pos[1]), float(pos[2]))) mol.AddConformer(cc) return mol
def xyz2AC_vdW(atoms, xyz): # Get mol template mol = get_proto_mol(atoms) # Set coordinates conf = Chem.Conformer(mol.GetNumAtoms()) for i in range(mol.GetNumAtoms()): conf.SetAtomPosition(i, (xyz[i][0], xyz[i][1], xyz[i][2])) mol.AddConformer(conf) AC = get_AC(mol) return AC, mol
def TransformMol(mol, tform, confId=-1, newConfId=100): """ Applies the transformation to a molecule and sets it up with a single conformer """ newConf = Chem.Conformer() newConf.SetId(0) refConf = mol.GetConformer(confId) for i in range(refConf.GetNumAtoms()): pos = list(refConf.GetAtomPosition(i)) pos.append(1.0) newPos = numpy.dot(tform, numpy.array(pos)) newConf.SetAtomPosition(i, list(newPos)[:3]) newConf.SetId(newConfId) mol.RemoveConformer(newConfId) mol.AddConformer(newConf, assignId=False)