def align(self, conf, reflect=False): """ Align the molecule and return the xyz The default CanonicalizeConformer function may also include inversion """ from rdkit.Chem import rdMolTransforms as rdmt #rotation #print("align: "); print(conf.GetPositions()) trans = rdmt.ComputeCanonicalTransform(conf) if np.linalg.det(trans[:3,:3]) < 0: trans[:3,:3] *= -1 if reflect: trans[:3,:3] *= -1 #print(trans) rdmt.TransformConformer(conf, trans) #print("rot", conf.GetPositions()[:3]) #translation pt = rdmt.ComputeCentroid(conf) center = np.array([pt.x, pt.y, pt.z]) xyz = conf.GetPositions() - center #print("return", xyz[:3]) return xyz
def canonicalize_conf_numpy(mol, conf_id=-1): mol = Chem.Mol(mol) conf = mol.GetConformer(conf_id) pos = conf.GetPositions() ctd = pos.mean(axis=0) trans_pos = pos - ctd cov_mat = np.cov(trans_pos, bias=1, rowvar=False) * conf.GetNumAtoms() eigval, eigvect = np.linalg.eig(cov_mat) eigval_sorted = sorted(enumerate(eigval), key=lambda x: x[1], reverse=True) eigvect_sorted = [ eigvect[:, i] * (1.0 if eigvect[:, i].sum() > 0.0 else -1.0) for i, _ in eigval_sorted ] canon_trans = np.array([ [*eigvect_sorted[0], 0.], [*eigvect_sorted[1], 0.], [*eigvect_sorted[2], 0.], [0., 0., 0., 1.], ], dtype=np.double) canon_trans[0:3, 3] = np.array([*ctd, 1.]).dot(canon_trans)[:3] rdmt.TransformConformer(conf, canon_trans) return mol
def canonicalize_conf_rdkit(mol, conf_id=-1): mol = Chem.Mol(mol) conf = mol.GetConformer(conf_id) ctd = rdmt.ComputeCentroid(conf) canon_trans = rdmt.ComputeCanonicalTransform(conf, ctd) rdmt.TransformConformer(conf, canon_trans) return mol
def translate(mol: Chem.rdchem.Mol, new_centroid: Union[np.ndarray, List[int]], conf_id: int = -1): """Move a given conformer of a molecule to a new position. The transformation is performed in place. Args: mol: the molecule. new_centroid: the new position to move to of shape [x, y, z] conf_id: id of the conformer. """ # Get conformer conf = mol.GetConformer(conf_id) # Compute the vector for translation mol_center = rdMolTransforms.ComputeCentroid(conf) mol_center = np.array([mol_center.x, mol_center.y, mol_center.z]) # Make the transformation matrix T = np.eye(4) T[:3, 3] = new_centroid - mol_center # Transform rdMolTransforms.TransformConformer(conf, T)
def transform_embeddings(pharmacophore, embeddings, atom_match): """Transform embeddings. Performs the alignment of the molecules to the pharmacophore. Parameters ---------- pharmacophore: rdkit.Chem.Pharm3D.Pharmacophore A pharmacophore object. embeddings: list of rdkit.Chem.Mol List of molecules with a single conformer. atom_match: list of list List of list of atoms ids that match the pharmacophore. Returns ------- SSDs: list of float List of sum of square deviations (SSD) values for the alignments. """ align_ref = [f.GetPos() for f in pharmacophore.getFeatures()] ssds = [] for embedding in embeddings: conformer = embedding.GetConformer() ssd, transform_matrix = get_transform_matrix(align_ref, conformer, atom_match) # Transform the coordinates of the conformer rdMolTransforms.TransformConformer(conformer, transform_matrix) ssds.append(ssd) return ssds
def test1Canonicalization(self): mol = Chem.MolFromSmiles("C") conf = Chem.Conformer(1) conf.SetAtomPosition(0, (4.0, 5.0, 6.0)) mol.AddConformer(conf, 1) conf = mol.GetConformer() pt = rdmt.ComputeCentroid(conf) self.failUnless(ptEq(pt, geom.Point3D(4.0, 5.0, 6.0))) fileN = os.path.join(RDConfig.RDBaseDir, 'Code', 'GraphMol', 'MolTransforms', 'test_data', '1oir.mol') m = Chem.MolFromMolFile(fileN) cpt = rdmt.ComputeCentroid(m.GetConformer()) trans = rdmt.ComputeCanonicalTransform(m.GetConformer(), cpt) trans2 = rdmt.ComputeCanonicalTransform(m.GetConformer()) for i in range(4): for j in range(4): self.failUnless(feq(trans[i, j], trans2[i, j])) rdmt.TransformConformer(m.GetConformer(), trans2) m2 = Chem.MolFromMolFile(fileN) rdmt.CanonicalizeConformer(m2.GetConformer()) nats = m.GetNumAtoms() cnf1 = m.GetConformer() cnf2 = m2.GetConformer() for i in range(nats): p1 = list(cnf1.GetAtomPosition(i)) p2 = list(cnf2.GetAtomPosition(i)) self.failUnless(feq(p1[0], p2[0])) self.failUnless(feq(p1[1], p2[1])) self.failUnless(feq(p1[2], p2[2])) m3 = Chem.MolFromMolFile(fileN) rdmt.CanonicalizeMol(m3) cnf1 = m.GetConformer() cnf2 = m3.GetConformer() for i in range(nats): p1 = list(cnf1.GetAtomPosition(i)) p2 = list(cnf2.GetAtomPosition(i)) self.failUnless(feq(p1[0], p2[0])) self.failUnless(feq(p1[1], p2[1])) self.failUnless(feq(p1[2], p2[2]))