1
2
3
4
5
6
7 """ functionality for finding pharmacophore matches in molecules
8
9
10 See Docs/Chem/Pharm2D.triangles.jpg for an illustration of the way
11 pharmacophores are broken into triangles and labelled.
12
13 See Docs/Chem/Pharm2D.signatures.jpg for an illustration of bit
14 numbering
15
16 """
17 import Chem
18 from Chem.Pharm2D import Utils
19
20 import types
21 import exceptions
24
25 _verbose = 0
27 """ Returns a list of lists of atom indices for a bit
28
29 **Arguments**
30
31 - sig: a signature
32
33 - bitIdx: the bit to be queried
34
35 - mol: the molecule to be examined
36
37 - dMat: (optional) the distance matrix of the molecule
38
39 - justOne: (optional) if this is nonzero, only the first match
40 will be returned.
41
42 - matchingAtoms: (optional) if this is nonzero, it should
43 contain a sequence of sequences with the indices of atoms in
44 the molecule which match each of the patterns used by the
45 signature.
46
47 **Returns**
48
49 a list of tuples with the matching atoms
50 """
51 assert sig.GetShortestPathsOnly(),'not implemented for non-shortest path signatures'
52 nPts,pattCombo,scaffold = sig.GetBitInfo(bitIdx)
53 if _verbose:
54 print 'info:',nPts
55 print '\t',pattCombo
56 print '\t',scaffold
57
58
59 choices = []
60 for pattIdx in pattCombo:
61 tmp = None
62 if matchingAtoms is not None:
63 tmp = matchingAtoms[pattIdx]
64 else:
65 patt = sig.GetPattern(pattIdx)
66 tmp = mol.GetSubstructMatches(patt)
67 if tmp:
68 choices.append(tmp)
69 else:
70
71
72 if _verbose: print 'no match found for pattern:',pattIdx
73 return []
74
75 if _verbose:
76 print 'choices:'
77 print choices
78
79 if dMat is None:
80 useBO = sig.GetIncludeBondOrder()
81 dMat = Chem.GetDistanceMatrix(mol,useBO)
82
83 matches = []
84 distsToCheck = Utils.nPointDistDict[nPts]
85
86 protoPharmacophores = Utils.GetAllCombinations(choices,noDups=1)
87
88 res = []
89 for protoPharm in protoPharmacophores:
90 if _verbose: print 'protoPharm:',protoPharm
91 for i in range(len(distsToCheck)):
92 dLow,dHigh = sig.GetBin(scaffold[i])
93 a1,a2 = distsToCheck[i]
94
95
96
97
98
99 idx1,idx2 = protoPharm[a1][0],protoPharm[a2][0]
100 dist = dMat[idx1,idx2]
101 if _verbose: print '\t dist: %d->%d = %d (%d,%d)'%(idx1,idx2,dist,dLow,dHigh)
102 if dist < dLow or dist >= dHigh:
103 break
104 else:
105 if _verbose: print 'Found one'
106
107 protoPharm.sort()
108 protoPharm = tuple(protoPharm)
109 if protoPharm not in res:
110 res.append(protoPharm)
111 if justOne: break
112 return res
113
114 if __name__ == '__main__':
115 import Chem
116 from Chem.Pharm2D import SigFactory,Generate
117
118 factory = SigFactory.SigFactory()
119 factory.SetBins([(1,2),(2,5),(5,8)])
120 factory.SetPatternsFromSmarts(['O','N'])
121 factory.SetMinCount(2)
122 factory.SetMaxCount(3)
123 sig = factory.GetSignature()
124
125 mol = Chem.MolFromSmiles('OCC(=O)CCCN')
126 Generate.Gen2DFingerprint(mol,sig)
127 print 'onbits:',list(sig.GetOnBits())
128
129 _verbose=0
130 for bit in sig.GetOnBits():
131 as = GetAtomsMatchingBit(sig,bit,mol)
132 print '\tBit %d: '%(bit),as
133
134
135 print '--------------------------'
136 sig = factory.GetSignature()
137 sig.SetIncludeBondOrder(1)
138 Generate.Gen2DFingerprint(mol,sig)
139 print 'onbits:',list(sig.GetOnBits())
140
141 for bit in sig.GetOnBits():
142 as = GetAtomsMatchingBit(sig,bit,mol)
143 print '\tBit %d: '%(bit),as
144