1
2
3
4
5
6
7
8
9
10
11 """ uses DSViewer to interact with molecules
12
13 """
14 from rdkit import Chem
15 from win32com.client import Dispatch
16 import tempfile, os
17
18 _nextDisplayId = 1
19
20
22
33
34 - def Select(self, atoms=[], state=True, recurse=False):
35 if state:
36 selText = 'true'
37 else:
38 selText = 'false'
39 if not atoms or atoms == '*':
40 atomStr = '; atom "*"'
41 else:
42
43 atoms = ['id=%d' % (x) for x in atoms]
44 atomStr = '; atom %s' % ','.join(atoms)
45
46 cmd = 'SetProperty object RD_Visual=%d %s: select=%s' % (self.id, atomStr, selText)
47 r = int(str(self.doc.DoCommand(cmd)))
48 if not r and not atoms:
49
50
51 atomStr = ''
52 cmd = 'SetProperty object RD_Visual=%d %s: select=%s' % (self.id, atomStr, selText)
53 r = int(str(self.doc.DoCommand(cmd)))
54
55
56
57
58
59 if r:
60 cmd = 'SetProperty object RD_Visual=%d; bond index="*": select=off' % (self.id)
61 self.doc.DoCommand(cmd)
62
63 if recurse:
64 for child in self.children:
65 child.Select(atoms=atoms, state=state, recurse=True)
66 return r
67
68 - def Hide(self, recurse=True):
69 self.Select(state=True, recurse=True)
70 self.doc.DoCommand('hide')
71 self.Select(state=False, recurse=True)
72
73 - def Show(self, recurse=True):
74 self.Select(state=True, recurse=True)
75 self.doc.DoCommand('Show')
76 self.Select(state=False, recurse=True)
77
79 self.doc.DoCommand('HideAll')
80 self.Select(state=True, recurse=True)
81 self.doc.DoCommand('Show')
82 self.Select(state=False, recurse=True)
83
85 self.doc.DoCommand('UnselectAll')
86 count = self.Select(state=True, recurse=True)
87 if count:
88 self.doc.DoCommand('Delete')
89
90
92
93 - def __init__(self, force=0, title='Untitled', **kwargs):
94 self.app = Dispatch('WebLabViewerPro.Application')
95 self.app.Visible = 1
96 if force or self.app.ActiveDocument is None:
97 self.doc = self.app.New(title)
98 else:
99 self.doc = self.app.ActiveDocument
100
101 self.displayables = {}
102
104 self.doc.DoCommand('SelectAll')
105 self.doc.DoCommand('Delete')
106 self.displayables = {}
107
109 excludes = [x.lower() for x in excludes]
110 allNames = self.displayables.keys()
111 for nm in allNames:
112 if nm not in excludes:
113 del self.displayables[nm]
114
115 - def ShowMol(self, mol, name='molecule', showOnly=True, highlightFeatures=[], molB="", confId=-1,
116 zoom=True):
117 if showOnly:
118 self.DeleteAll()
119 obj = None
120 else:
121 obj = self.displayables.get(name.lower(), None)
122
123
124
125
126
127 if not molB:
128 molB = Chem.MolToMolBlock(mol, confId=confId)
129
130 tmp = name + "\n" + molB[molB.index('\n') + 1:]
131 molB = tmp
132
133 if not obj:
134 obj = Displayable(self.doc)
135 if not hasattr(obj, '_molBlock') or obj._molBlock != molB:
136 obj._molBlock = molB
137 fN = tempfile.mktemp('.mol')
138 open(fN, 'w+').write(molB)
139 self.doc.DoCommand('PasteFrom %s' % fN)
140 self.doc.DoCommand('SetProperty molecule id=0 : RD_Visual=%d' % (obj.id))
141 self.doc.DoCommand('SetProperty molecule id=0 : id=%d' % (obj.id))
142 self.doc.DoCommand('SetProperty molecule id=0 : select=off')
143 os.unlink(fN)
144 else:
145 obj.Select(state=True)
146 self.doc.DoCommand('Show')
147
148 self.displayables[name.lower()] = obj
149
150 if zoom:
151 self.doc.DoCommand('Center')
152 self.doc.DoCommand('FitView')
153
154 return
155
156 - def LoadFile(self, filename, name, showOnly=False):
157 if showOnly:
158 self.DeleteAll()
159 self.doc.DoCommand('PasteFrom %s' % filename)
160 obj = Displayable(self.doc)
161 self.doc.DoCommand('SetProperty molecule id=0 : id=%d' % (obj.id))
162 self.doc.DoCommand('SetProperty molecule id=0 : select=off')
163 count = self.doc.DoCommand('SetProperty AminoAcidChain id=0 : RD_Visual=%d' % (obj.id))
164 if not count or int(count) <= 0:
165 count = self.doc.DoCommand('SetProperty molecule id=0 : RD_Visual=%d' % (obj.id))
166 self.displayables[name.lower()] = obj
167 return obj
168
170
171 if not whichSelection:
172 d = str(self.doc.DoCommand('GetPropertyValue atom select=true: id=?'))
173 d2 = str(self.doc.DoCommand('GetPropertyValue atom select=true: molecule=?'))
174 if d2:
175 molIds = []
176 tmpD = {}
177 for id in d2.split(','):
178 id = int(id.split('/')[1]) + 1
179 if id in tmpD:
180 molIds.append(tmpD[id])
181 else:
182 for k, v in self.displayables.iteritems():
183 if id == v.id:
184 tmpD[id] = k
185 molIds.append(k)
186 else:
187 molIds = [''] * (d.count(',') + 1)
188 elif whichSelection.lower() in self.displayables:
189 whichSelection = whichSelection.lower()
190 whichSelection = self.displayables[whichSelection].id
191 d = str(
192 self.doc.DoCommand('GetPropertyValue molecule RD_Visual=%d; atom select=true: id=?' %
193 whichSelection))
194 molIds = [whichSelection] * (d.count(',') + 1)
195 else:
196 d = None
197 molIds = None
198
199 if d:
200 splitD = d.split(',')
201
202
203 try:
204 res = []
205 for i in range(len(splitD)):
206
207 idx = int(splitD[i])
208 res.append((molIds[i], idx))
209 except Exception:
210 import traceback
211 traceback.print_exc()
212 res = []
213 else:
214 res = []
215 return res
216
218 self.doc.DoCommand('UnSelectAll')
219 self.SelectAtoms(where, indices)
220
221 - def SelectAtoms(self, itemId, atomIndices, selName='selection'):
222 self.doc.DoCommand('UnSelectAll')
223 self.doc.DoCommand('SetProperty atom id="*": select=off')
224 o = self.displayables.get(itemId.lower(), None)
225
226 if o:
227 o.Select(atoms=atomIndices)
228
230 if not val:
231 self.doc.DoCommand('UpdateView off')
232 else:
233 self.doc.DoCommand('UpdateView on')
234
236 res = {}
237 for label, idx in sels:
238 whichSelection = label.lower()
239 whichSelection = self.displayables[label].id
240
241 idx += 1
242 cmd = 'GetPropertyValue molecule RD_Visual=%d; atom id=%d: xyz=?' % (whichSelection, idx)
243 coords = self.doc.DoCommand(cmd)
244 coords = [float(x) for x in coords.split(' ')]
245 res[(label, idx)] = coords
246
247 return res
248
250 label = label.lower()
251 self.SetDisplayUpdate(False)
252 parent = Displayable(self.doc)
253 for i, loc in enumerate(locs):
254 color = colors[i]
255 color = ' '.join([str(int(255 * x)) for x in color])
256 obj = Displayable(self.doc)
257 nm = 'sphere-%d' % obj.id
258 self.doc.DoCommand('Sphere %s' % nm)
259 self.doc.DoCommand('SetProperty Object name=%s : xyz=%f %f %f' % (nm, loc[0], loc[1], loc[2]))
260 self.doc.DoCommand('SetProperty Object name=%s : radius=%f' % (nm, sphereRad))
261 self.doc.DoCommand('SetProperty Object name=%s : color=%s' % (nm, color))
262 self.doc.DoCommand('SetProperty Object name=%s : RD_Visual=%d' % (nm, parent.id))
263 self.doc.DoCommand('SetProperty Object name=%s : id=%d' % (nm, parent.id))
264
265 self.displayables[label] = parent
266 self.SetDisplayUpdate(True)
267
269 self.doc.DoCommand('UnSelectAll')
270 obj = obj.lower()
271 o = self.displayables.get(obj, None)
272 if o:
273 o.Select(state=True)
274 if style == 'sticks':
275 self.doc.DoCommand('DisplayStyle Atom Stick')
276 elif style == 'lines':
277 self.doc.DoCommand('DisplayStyle Atom Line')
278 elif style == '':
279 self.doc.DoCommand('DisplayStyle Atom Off')
280 o.Select(state=False)
281
283 self.doc.DoCommand('HideAll')
284
286 self.doc.DoCommand('UnSelectAll')
287 objName = objName.lower()
288 o = self.displayables.get(objName, None)
289 if o:
290 o.Hide()
291
293 self.doc.DoCommand('UnSelectAll')
294 objName = objName.lower()
295 o = self.displayables.get(objName, None)
296 if o:
297 o.Show()
298
299 - def Zoom(self, objName):
300 self.doc.DoCommand('UnSelectAll')
301 objName = objName.lower()
302 o = self.displayables.get(objName, None)
303 if o:
304 r = o.Select(state=True)
305 self.doc.DoCommand('Center')
306 self.doc.DoCommand('FitView')
307 o.Select(state=False)
308
311 """ FIX: the surface display stuff here is all screwed up due to
312 differences between the way PyMol and DSViewer handle surfaces.
313 In PyMol they are essentially a display mode for the protein, so
314 they don't need to be managed separately.
315 In DSViewer, on the other hand, the surface is attached to the
316 protein, but it needs to be hidden or shown on its own. I haven't
317 figured out how to do that yet.
318 """
319 self.doc.DoCommand('UnSelectAll')
320 o = self.displayables.get(aroundObj.lower(), None)
321 p = self.displayables.get(inObj.lower(), None)
322 if o and p:
323 self.SetDisplayUpdate(False)
324 p.Show()
325 self.doc.DoCommand('UnSelectAll')
326 tmp = self.doc.DoCommand('SetProperty object RD_Visual=%d;object id="*":select=on' % o.id)
327 tmp = self.doc.DoCommand('SelectByRadius inside %f atom' % distance)
328
329
330 for obj in self.displayables.values():
331 if obj.id != p.id:
332 self.doc.DoCommand('SetProperty object RD_Visual=%d;object id="*":select=off' % obj.id)
333
334
335
336 rs = self.doc.DoCommand('GetPropertyValue atom select=true: parent=?')
337 if rs:
338 rs = rs.split(',')
339 residues = {}
340 for r in rs:
341 residues[r] = 1
342
343
344 parents = ','.join(['parent="%s"' % x for x in residues.keys()])
345 cmd = 'SetProperty atom %s: select=on' % parents
346 tmp = self.doc.DoCommand(cmd)
347 if showSurface:
348
349 self.doc.DoCommand('Surface')
350 obj = Displayable(self.doc)
351 self.displayables[name] = obj
352 self.doc.DoCommand('SetProperty surface id="*":RD_Visual=%d' % obj.id)
353
354 self.doc.DoCommand('UnSelectAll')
355
356 self.SetDisplayUpdate(True)
357
360
361
362 if __name__ == '__main__':
363 from rdkit import Chem
364 from rdkit.Chem import rdDistGeom, rdForceFieldHelpers
365
366 m = Chem.MolFromSmiles('c1cccc2c1cccc2')
367 rdDistGeom.EmbedMolecule(m)
368 rdForceFieldHelpers.UFFOptimizeMolecule(m)
369
370 s = MolViewer()
371 s.ShowMol(m)
372