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