def CalculateTorsionLists(mol, maxDev='equal', symmRadius=2, ignoreColinearBonds=True): """ Calculate a list of torsions for a given molecule. For each torsion the four atom indices are determined and stored in a set. Arguments: - mol: the molecule of interest - maxDev: maximal deviation used for normalization 'equal': all torsions are normalized using 180.0 (default) 'spec': each torsion is normalized using its specific maximal deviation as given in the paper - symmRadius: radius used for calculating the atom invariants (default: 2) - ignoreColinearBonds: if True (default), single bonds adjacent to triple bonds are ignored if False, alternative not-covalently bound atoms are used to define the torsion Return: two lists of torsions: non-ring and ring torsions """ if maxDev not in ['equal', 'spec']: raise ValueError("maxDev must be either equal or spec") # get non-terminal, non-cyclic bonds bonds = _getBondsForTorsions(mol, ignoreColinearBonds) # get atom invariants if symmRadius > 0: inv = _getAtomInvariantsWithRadius(mol, symmRadius) else: inv = rdMolDescriptors.GetConnectivityInvariants(mol) # get the torsions tors_list = [] # to store the atom indices of the torsions for a1, a2, nb1, nb2 in bonds: d1 = _getIndexforTorsion(nb1, inv) d2 = _getIndexforTorsion(nb2, inv) if len(d1) == 1 and len(d2) == 1: # case 1, 2, 4, 5, 7, 10, 16, 12, 17, 19 tors_list.append(([(d1[0].GetIdx(), a1, a2, d2[0].GetIdx())], 180.0)) elif len(d1) == 1: # case 3, 6, 8, 13, 20 if len(nb2) == 2: # two neighbors tors_list.append(([(d1[0].GetIdx(), a1, a2, nb.GetIdx()) for nb in d2], 90.0)) else: # three neighbors tors_list.append(([(d1[0].GetIdx(), a1, a2, nb.GetIdx()) for nb in d2], 60.0)) elif len(d2) == 1: # case 3, 6, 8, 13, 20 if len(nb1) == 2: tors_list.append(([(nb.GetIdx(), a1, a2, d2[0].GetIdx()) for nb in d1], 90.0)) else: # three neighbors tors_list.append(([(nb.GetIdx(), a1, a2, d2[0].GetIdx()) for nb in d1], 60.0)) else: # both symmetric tmp = [] for n1 in d1: for n2 in d2: tmp.append((n1.GetIdx(), a1, a2, n2.GetIdx())) if len(nb1) == 2 and len(nb2) == 2: # case 9 tors_list.append((tmp, 90.0)) elif len(nb1) == 3 and len(nb2) == 3: # case 21 tors_list.append((tmp, 60.0)) else: # case 15 tors_list.append((tmp, 30.0)) # maximal possible deviation for non-cyclic bonds if maxDev == 'equal': tors_list = [(t, 180.0) for t, d in tors_list] # rings rings = Chem.GetSymmSSSR(mol) tors_list_rings = [] for r in rings: # get the torsions tmp = [] num = len(r) maxdev = 180.0 * math.exp(-0.025 * (num - 14) * (num - 14)) for i in range(len(r)): tmp.append((r[i], r[(i + 1) % num], r[(i + 2) % num], r[(i + 3) % num])) tors_list_rings.append((tmp, maxdev)) return tors_list, tors_list_rings
def testMorganFingerprints(self): mol = Chem.MolFromSmiles('CC(F)(Cl)C(F)(Cl)C') fp = rdMD.GetMorganFingerprint(mol, 0) self.assertTrue(len(fp.GetNonzeroElements()) == 4) mol = Chem.MolFromSmiles('CC') fp = rdMD.GetMorganFingerprint(mol, 0) self.assertTrue(len(fp.GetNonzeroElements()) == 1) self.assertTrue(list(fp.GetNonzeroElements().values())[0] == 2) fp = rdMD.GetMorganFingerprint(mol, 0, useCounts=False) self.assertTrue(len(fp.GetNonzeroElements()) == 1) self.assertTrue(list(fp.GetNonzeroElements().values())[0] == 1) mol = Chem.MolFromSmiles('CC(F)(Cl)C(F)(Cl)C') fp = rdMD.GetHashedMorganFingerprint(mol, 0) self.assertTrue(len(fp.GetNonzeroElements()) == 4) fp = rdMD.GetMorganFingerprint(mol, 1) self.assertTrue(len(fp.GetNonzeroElements()) == 8) fp = rdMD.GetHashedMorganFingerprint(mol, 1) self.assertTrue(len(fp.GetNonzeroElements()) == 8) fp = rdMD.GetMorganFingerprint(mol, 2) self.assertTrue(len(fp.GetNonzeroElements()) == 9) mol = Chem.MolFromSmiles('CC(F)(Cl)[C@](F)(Cl)C') fp = rdMD.GetMorganFingerprint(mol, 0) self.assertTrue(len(fp.GetNonzeroElements()) == 4) fp = rdMD.GetMorganFingerprint(mol, 1) self.assertTrue(len(fp.GetNonzeroElements()) == 8) fp = rdMD.GetMorganFingerprint(mol, 2) self.assertTrue(len(fp.GetNonzeroElements()) == 9) fp = rdMD.GetMorganFingerprint(mol, 0, useChirality=True) self.assertTrue(len(fp.GetNonzeroElements()) == 4) fp = rdMD.GetMorganFingerprint(mol, 1, useChirality=True) self.assertTrue(len(fp.GetNonzeroElements()) == 9) fp = rdMD.GetMorganFingerprint(mol, 2, useChirality=True) self.assertTrue(len(fp.GetNonzeroElements()) == 10) mol = Chem.MolFromSmiles('CCCCC') fp = rdMD.GetMorganFingerprint(mol, 0, fromAtoms=(0, )) self.assertTrue(len(fp.GetNonzeroElements()) == 1) mol = Chem.MolFromSmiles('CC1CC1') vs1 = rdMD.GetConnectivityInvariants(mol) self.assertEqual(len(vs1), mol.GetNumAtoms()) fp1 = rdMD.GetMorganFingerprint(mol, 2, invariants=vs1) fp2 = rdMD.GetMorganFingerprint(mol, 2) self.assertEqual(fp1, fp2) vs2 = rdMD.GetConnectivityInvariants(mol, False) self.assertEqual(len(vs2), mol.GetNumAtoms()) self.assertNotEqual(vs1, vs2) fp1 = rdMD.GetMorganFingerprint(mol, 2, invariants=vs2) self.assertNotEqual(fp1, fp2) mol = Chem.MolFromSmiles('Cc1ccccc1') vs1 = rdMD.GetFeatureInvariants(mol) self.assertEqual(len(vs1), mol.GetNumAtoms()) self.assertEqual(vs1[0], 0) self.assertNotEqual(vs1[1], 0) self.assertEqual(vs1[1], vs1[2]) self.assertEqual(vs1[1], vs1[3]) self.assertEqual(vs1[1], vs1[4]) mol = Chem.MolFromSmiles('FCCCl') vs1 = rdMD.GetFeatureInvariants(mol) self.assertEqual(len(vs1), mol.GetNumAtoms()) self.assertEqual(vs1[1], 0) self.assertEqual(vs1[2], 0) self.assertNotEqual(vs1[0], 0) self.assertEqual(vs1[0], vs1[3]) fp1 = rdMD.GetMorganFingerprint(mol, 0, invariants=vs1) fp2 = rdMD.GetMorganFingerprint(mol, 0, useFeatures=True) self.assertEqual(fp1, fp2)