1
2
3
4
5
6
7
8
9
10
11 from rdkit import Geometry
12 from rdkit.Chem.FeatMaps import FeatMaps, FeatMapPoint
13 import re
14 """
15
16 ScoreMode=All
17 DirScoreMode=Ignore
18
19 BeginParams
20 family=Aromatic radius=2.5 width=1.0 profile=Gaussian
21 family=Acceptor radius=1.5
22 EndParams
23
24 # optional
25 BeginPoints
26 family=Acceptor pos=(1.0, 0.0, 5.0) weight=1.25 dir=(1, 1, 0)
27 family=Aromatic pos=(0.0,1.0,0.0) weight=2.0 dir=(0,0,1) dir=(0,0,-1)
28 family=Acceptor pos=(1.0,1.0,2.0) weight=1.25
29 EndPoints
30
31 """
32
33
36
37
39 data = None
40
41 - def __init__(self, file=None, data=None):
47
49 if isinstance(data, str):
50 self.data = data.split('\n')
51 else:
52 self.data = data
53 self._lineNum = 0
54
56 txt = ''
57 while 1:
58 try:
59 l = self.data[self._lineNum].split('#')[0].strip()
60 except IndexError:
61 break
62 self._lineNum += 1
63 if l:
64 txt += l
65 if l[-1] != '\\':
66 break
67 return txt
68
69 - def Parse(self, featMap=None):
104
106 paramLineSplitter = re.compile(r'([a-zA-Z]+) *= *(\S+)')
107 params = {}
108
109 l = self._NextLine()
110 while l and l != 'EndParams':
111 param = FeatMaps.FeatMapParams()
112 vals = paramLineSplitter.findall(l)
113 for name, val in vals:
114 name = name.lower()
115 if name == 'family':
116 family = val
117 elif name == 'radius':
118 param.radius = float(val)
119 elif name == 'width':
120 param.width = float(val)
121 elif name == 'profile':
122 try:
123 param.featProfile = getattr(param.FeatProfile, val)
124 except AttributeError:
125 raise FeatMapParseError('Profile %s not recognized on line %d' % (val, self._lineNum))
126 else:
127 raise FeatMapParseError('FeatMapParam option %s not recognized on line %d' %
128 (name, self._lineNum))
129 params[family] = param
130 l = self._NextLine()
131
132 if l != 'EndParams':
133 raise FeatMapParseError('EndParams line not found')
134
135 return params
136
138 txt = txt.strip()
139 startP = 0
140 endP = len(txt)
141 if txt[0] == '(':
142 startP += 1
143 if txt[-1] == ')':
144 endP -= 1
145 txt = txt[startP:endP]
146 splitL = txt.split(',')
147 if len(splitL) != 3:
148 raise ValueError('Bad location string')
149 vs = [float(x) for x in splitL]
150 pt = Geometry.Point3D(vs[0], vs[1], vs[2])
151 return pt
152
154 featLineSplitter = re.compile(r'([a-zA-Z]+) *= *')
155 feats = []
156
157 l = self._NextLine()
158 while l and l != 'EndPoints':
159 vals = featLineSplitter.split(l)
160 while vals.count(''):
161 vals.remove('')
162 p = FeatMapPoint.FeatMapPoint()
163
164 i = 0
165 while i < len(vals):
166 name = vals[i].lower()
167 if name == 'family':
168 i += 1
169 val = vals[i].strip()
170 p.SetFamily(val)
171 elif name == 'weight':
172 i += 1
173 val = float(vals[i])
174 p.weight = val
175 elif name == 'pos':
176 i += 1
177 val = vals[i]
178 pos = self._parsePoint(val)
179 p.SetPos(pos)
180 elif name == 'dir':
181 i += 1
182 val = vals[i]
183 pos = self._parsePoint(val)
184 p.featDirs.append(pos)
185 else:
186 raise FeatMapParseError('FeatPoint option %s not recognized on line %d' %
187 (name, self._lineNum))
188 i += 1
189 feats.append(p)
190 l = self._NextLine()
191 return feats
192