1
2
3
4
5
6
7
8
9 """ lazy generator of 2D pharmacophore signature data
10
11 """
12 import Chem
13 from Chem.Pharm2D import SigFactory,Matcher
14
16 """
17
18 Important attributes:
19
20 - mol: the molecules whose signature is being worked with
21
22 - sig: the signature to be used to decide what bits are set in the
23 molecule. This signature can be considered to be constant in
24 this class, none of the class methods modify sig
25
26 """
27 - def __init__(self,sig,mol,dMat=None,bitCache=1):
28 """ constructor
29
30 **Arguments**
31
32 - sig: a signature, see class docs
33
34 - mol: a molecule, see class docs
35
36 - dMat: (optional) a distance matrix for the molecule. If this
37 is not provided, one will be calculated
38
39 - bitCache: (optional) if nonzero, a local cache of which bits
40 have been queried will be maintained. Otherwise things must
41 be recalculate each time a bit is queried.
42
43 """
44 if isinstance(sig,SigFactory.SigFactory):
45 sig = sig.GetSignature()
46 self.sig = sig
47 self.mol = mol
48
49 if dMat is None:
50 useBO = self.sig.GetIncludeBondOrder()
51 dMat = Chem.GetDistanceMatrix(mol,useBO)
52
53 self.dMat = dMat
54
55 if bitCache:
56 self.bits = {}
57 else:
58 self.bits = None
59
60 nPatts = self.sig.GetNumPatterns()
61 pattMatches = [None]*nPatts
62 for i in range(nPatts):
63 patt = self.sig.GetPattern(i)
64 pattMatches[i]=self.mol.GetSubstructMatches(patt)
65 self.pattMatches = pattMatches
66
68 """ returns a bool indicating whether or not the bit is set
69
70 """
71 if idx < 0 or idx >= self.sig.GetSize():
72 raise IndexError,'Index %d invalid'%(idx)
73 if self.bits is not None and self.bits.has_key(idx):
74 return self.bits[idx]
75
76 tmp = Matcher.GetAtomsMatchingBit(self.sig,idx,self.mol,
77 dMat=self.dMat,justOne=1,
78 matchingAtoms=self.pattMatches)
79 if not tmp or len(tmp)==0: res = 0
80 else: res = 1
81
82 if self.bits is not None:
83 self.bits[idx] = res
84 return res
85
87 """ allows class to support len()
88
89 """
90 return self.sig.GetSize()
92 """ allows class to support random access.
93 Calls self.GetBit()
94
95 """
96 return self.GetBit(itm)
97
98
99
100
101 if __name__ == '__main__':
102 import time
103 import RDConfig,Chem
104 from Chem.Pharm2D import Gobbi_Pharm2D,Generate
105 import random
106
107 factory = Gobbi_Pharm2D.factory
108 nToDo=100
109 inD = open(RDConfig.RDDataDir+"/NCI/first_5K.smi",'r').readlines()[:nToDo]
110 mols = [None]*len(inD)
111 for i in range(len(inD)):
112 smi = inD[i].split('\t')[0]
113 smi.strip()
114 mols[i] = Chem.MolFromSmiles(smi)
115
116 sig = factory.GetSignature()
117
118 nBits = 300
119 random.seed(23)
120 bits = [random.randint(0,sig.GetSize()-1) for x in range(nBits)]
121
122 print 'Using the Lazy Generator'
123 t1 = time.time()
124 for i in range(len(mols)):
125 if not i % 10: print 'done mol %d of %d'%(i,len(mols))
126 gen = Generator(factory,mols[i])
127 for bit in bits:
128 v = gen[bit]
129 t2 = time.time()
130 print '\tthat took %4.2f seconds'%(t2-t1)
131
132
133 print 'Generating and checking signatures'
134 t1 = time.time()
135 for i in range(len(mols)):
136 if not i % 10: print 'done mol %d of %d'%(i,len(mols))
137 sig = Generate.Gen2DFingerprint(mols[i],factory)
138 for bit in bits:
139 v = sig[bit]
140 t2 = time.time()
141 print '\tthat took %4.2f seconds'%(t2-t1)
142