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