OpenStructure
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
init_context_menu.py
Go to the documentation of this file.
1 import platform
2 
3 from PyQt4 import QtCore, QtGui
4 
5 import sip
6 
7 from ost import geom, gfx, gui, seq
8 from ost import settings
9 from ost import LogError, mol
10 from ost.bindings import tmtools
11 from ost.bindings import msms
12 from ost.seq import alg
13 import ost
14 from ost.gui.scene.query_editor import QueryEditorWidget,QueryDialog
15 
16 class SelectRefDialog(QtGui.QDialog):
17  def __init__(self, ent_list, parent=None):
18  QtGui.QDialog.__init__(self, parent)
19  self.ent_list_ = ent_list
20  vb = QtGui.QVBoxLayout()
21  self.setLayout(vb)
22  self.setWindowTitle("Select Reference Object")
23  self.label = QtGui.QLabel("Please Select the Reference Object")
24  self.list = QtGui.QTableWidget(self)
25  self.list.horizontalHeader().setStretchLastSection(True)
26  self.list.setColumnCount(2)
27  self.list.verticalHeader().setVisible(False)
28  self.list.horizontalHeader().setVisible(False)
29  self.list.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
30  self.list.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
31  vb.addWidget(self.label)
32  vb.addWidget(self.list)
33  self.show_scores = QtGui.QCheckBox(self)
34  self.show_scores.setText("Show Scores")
35  self.show_scores.setChecked(True)
36  vb.addWidget(self.show_scores)
37  self.show_alignment = QtGui.QCheckBox(self)
38  self.show_alignment.setText("Display Alignment")
39  self.show_alignment.setChecked(False)
40  vb.addWidget(self.show_alignment)
41  hb = QtGui.QHBoxLayout()
42  hb.setDirection(QtGui.QBoxLayout.LeftToRight)
43  cancel_btn = QtGui.QPushButton("Cancel", self)
44  load_btn = QtGui.QPushButton("Select", self)
45  hb.addStretch(1)
46  hb.addWidget(cancel_btn)
47  hb.addWidget(load_btn)
48  vb.addItem(hb)
49  load_btn.setDefault(True)
50  QtCore.QObject.connect(load_btn, QtCore.SIGNAL("clicked()"), self.Select)
51  QtCore.QObject.connect(cancel_btn, QtCore.SIGNAL("clicked()"), self.reject)
52 
53  row = 0
54  for ent in self.ent_list_:
55  variant = QtCore.QVariant(ent)
56  self.list.insertRow(row)
57  new_item = QtGui.QTableWidgetItem("%i"%(row+1))
58  new_item.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsEnabled)
59  new_item.setData(QtCore.Qt.UserRole,variant)
60  self.list.setItem(row, 0, new_item)
61  new_item = QtGui.QTableWidgetItem(ent.GetName())
62  new_item.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsEnabled)
63  self.list.setItem(row, 1, new_item)
64  row += 1
65 
66  self.list.resizeColumnsToContents()
67 
68  def Select(self):
69  items = self.list.selectedItems()
70  for item in items:
71  if(item.column()==0):
72  ent = item.data(QtCore.Qt.UserRole).toPyObject()
73  self.ent_list_.remove(ent)
74  self.ent_list_.insert(0,ent)
75  self.accept()
76 
77  def GetShowScores(self):
78  return self.show_scores.isChecked()
79 
81  return self.show_alignment.isChecked()
82 
83  def GetEntities(self):
84  return self.ent_list_
85 
86 class ShowResultDialog(QtGui.QDialog):
87  def __init__(self, ent_list, res_list, parent=None):
88  QtGui.QDialog.__init__(self, parent)
89  self.ent_list_ = ent_list
90  vb = QtGui.QVBoxLayout()
91  self.setLayout(vb)
92  self.setWindowTitle("Alignment result")
93  self.label = QtGui.QLabel("Alignment results with %s as reference"%ent_list[0].GetName())
94  self.list = QtGui.QTableWidget(self)
95  self.list.horizontalHeader().setStretchLastSection(True)
96  self.list.setColumnCount(4)
97  self.list.verticalHeader().setVisible(False)
98  self.list.setHorizontalHeaderLabels (["Name","RMSD","TMScore",""])
99  self.list.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
100  vb.addWidget(self.label)
101  vb.addWidget(self.list)
102  hb = QtGui.QHBoxLayout()
103  hb.setDirection(QtGui.QBoxLayout.LeftToRight)
104  ok_btn = QtGui.QPushButton("OK", self)
105  hb.addStretch(1)
106  hb.addWidget(ok_btn)
107  vb.addItem(hb)
108  ok_btn.setDefault(True)
109  QtCore.QObject.connect(ok_btn, QtCore.SIGNAL("clicked()"), self.accept)
110 
111  for i in range(0, len(res_list)):
112  self.list.insertRow(i)
113  new_item = QtGui.QTableWidgetItem(ent_list[i+1].GetName())
114  new_item.setFlags(QtCore.Qt.ItemIsEnabled)
115  self.list.setItem(i, 0, new_item)
116  new_item = QtGui.QTableWidgetItem("%.2f"%res_list[i].rmsd)
117  new_item.setFlags(QtCore.Qt.ItemIsEnabled)
118  self.list.setItem(i, 1, new_item)
119  new_item = QtGui.QTableWidgetItem("%i"%res_list[i].tm_score)
120  new_item.setFlags(QtCore.Qt.ItemIsEnabled)
121  self.list.setItem(i, 2, new_item)
122  new_item = QtGui.QTableWidgetItem()
123  new_item.setFlags(QtCore.Qt.ItemIsEnabled)
124  self.list.setItem(i, 3, new_item)
125 
126  self.list.resizeColumnsToContents()
127 
128 class CalculateSurfaceSettingsDialog(QtGui.QDialog):
129  def __init__(self, executable, parent=None):
130  QtGui.QDialog.__init__(self, parent)
131  vb = QtGui.QGridLayout()
132  self.setLayout(vb)
133  self.setWindowTitle("MSMS Surface Settings")
134  msmsexe_label=QtGui.QLabel("executable")
135  self.msmsexe_field=QtGui.QLineEdit()
136  self.msmsexe_field.setText(executable)
137  msmsexe_browsebutton=QtGui.QPushButton("Browse")
138  vb.addWidget(msmsexe_label, 0, 0)
139  vb.addWidget(self.msmsexe_field, 0, 1)
140  vb.addWidget(msmsexe_browsebutton, 0, 2)
141  surfname_label=QtGui.QLabel("surface name")
142  self.surfname_field=QtGui.QLineEdit()
143  self.surfname_field.setText("surface")
144  vb.addWidget(surfname_label, 1, 0)
145  vb.addWidget(self.surfname_field, 1, 1, 1, 2)
146  density_label=QtGui.QLabel("density")
147  self.density_spinbox=QtGui.QSpinBox()
148  self.density_spinbox.setRange(1, 10)
149  self.density_spinbox.setValue(4)
150  vb.addWidget(density_label, 2, 0)
151  vb.addWidget(self.density_spinbox, 2, 1, 1, 2)
152  probe_label=QtGui.QLabel("probe radius")
153  self.probe_spinbox=QtGui.QDoubleSpinBox()
154  self.probe_spinbox.setDecimals(1)
155  self.probe_spinbox.setSingleStep(0.1)
156  self.probe_spinbox.setRange(0.3, 5.0)
157  self.probe_spinbox.setValue(1.4)
158  vb.addWidget(probe_label, 3, 0)
159  vb.addWidget(self.probe_spinbox, 3, 1, 1, 2)
160  selection_label=QtGui.QLabel("selection")
161  self.selection_field=QtGui.QLineEdit()
162  self.selection_field.setText("")
163  vb.addWidget(selection_label, 4, 0)
164  vb.addWidget(self.selection_field, 4, 1, 1, 2)
165  self.noh_box=QtGui.QCheckBox("no hydrogens")
166  vb.addWidget(self.noh_box, 5, 0)
167  self.nohet_box=QtGui.QCheckBox("no hetatoms")
168  vb.addWidget(self.nohet_box, 5, 1)
169  self.nowat_box=QtGui.QCheckBox("no waters")
170  vb.addWidget(self.nowat_box, 5, 2)
171 
172  cancel_btn = QtGui.QPushButton("Cancel", self)
173  ok_btn = QtGui.QPushButton("OK", self)
174  vb.addWidget(cancel_btn, 6, 1)
175  vb.addWidget(ok_btn, 6, 2)
176 
177  QtCore.QObject.connect(msmsexe_browsebutton, QtCore.SIGNAL("clicked()"), self.GetPath)
178  QtCore.QObject.connect(ok_btn, QtCore.SIGNAL("clicked()"), self.accept)
179  QtCore.QObject.connect(cancel_btn, QtCore.SIGNAL("clicked()"), self.reject)
180 
181  def GetPath(self):
182  path=QtGui.QFileDialog().getOpenFileName(self, "Choose MSMS Executable")
183  if path!='':
184  self.msmsexe_field.setText(path)
185 
186 class SurfaceContextMenu(QtCore.QObject):
187  def __init__(self, context_menu):
188  try:
189  settings_name="msms"
190  self.executable=settings.Locate(settings_name)
191  except settings.FileNotFound:
192  self.executable=""
193  QtCore.QObject.__init__(self, context_menu.qobject)
194  self.action = QtGui.QAction("Calculate Surface", self)
195  QtCore.QObject.connect(self.action, QtCore.SIGNAL("triggered()"),
196  self.CalculateSurface)
197  context_menu.AddAction(self.action, gui.ContextActionType.ENTITY)
198 
199  def CalculateSurface(self):
200  scene_selection = gui.SceneSelection.Instance()
201  ent_list = list()
202  for i in range(0,scene_selection.GetActiveNodeCount()):
203  ent_list.append(scene_selection.GetActiveNode(i))
205  if(cssd.exec_()):
206  self.__CalculateSurface(ent_list,
207  str(cssd.surfname_field.text()),
208  str(cssd.msmsexe_field.text()),
209  cssd.density_spinbox.value(),
210  cssd.probe_spinbox.value(),
211  str(cssd.selection_field.text()),
212  cssd.noh_box.isChecked(),
213  cssd.nohet_box.isChecked(),
214  cssd.nowat_box.isChecked())
215 
216  def __CalculateSurface(self,ent_list,name,msms_exe,density,
217  radius,selection,noh,nohet,nowat):
218  for entity in ent_list:
219  if isinstance(entity, gfx.Entity):
220  try:
221  s=msms.CalculateSurface(entity.view,
222  msms_exe=msms_exe,
223  density=density,
224  radius=radius,
225  selection=selection,
226  no_hydrogens=noh,
227  no_hetatoms=nohet,
228  no_waters=nowat)[0]
229  gfx.Scene().Add(gfx.Surface("%s_%s"%(entity.GetName(),name),s))
230  except (RuntimeError, msms.MsmsProcessError):
231  LogError("WARNING: Surface could not be calculated")
232  return
233  except UserWarning:
234  LogError("WARNING: Entry with the same name already present in scene")
235  return
236 
237 class AlignmentContextMenu(QtCore.QObject):
238 
239  def __init__(self, context_menu):
240  try:
241  try: # workaround for interrupted system call bug on OSX
242  if platform.system() == "Windows":
243  settings_name="tmalign.exe"
244  else:
245  settings_name="tmalign"
246  except IOError:
247  # if platform.system() fails with an IOError we are most likely on a buggy mac an therefore
248  # use "tmalign"
249  settings_name="tmalign"
250 
251  settings.Locate(settings_name)
252  QtCore.QObject.__init__(self, context_menu.qobject)
253 
254  self.action = QtGui.QAction("Align", self)
255  QtCore.QObject.connect(self.action,QtCore.SIGNAL("triggered()"), self.Align)
256  context_menu.AddAction(self.action, gui.ContextActionType.ENTITY | gui.ContextActionType.MULTI)
257  self.seq_viewer = None
258  except settings.FileNotFound:
259  return
260 
261  def Align(self):
262  scene_selection = gui.SceneSelection.Instance()
263  ent_list = list()
264  for i in range(0,scene_selection.GetActiveNodeCount()):
265  ent_list.append(scene_selection.GetActiveNode(i))
266  sd = SelectRefDialog(ent_list)
267  if(sd.exec_()):
268  self.__Align(sd.GetEntities(),sd.GetShowScores(), sd.GetDisplayAlignment())
269 
270  def __Align(self, ent_list,show_scores=True, display_alignment=False):
271  node = ent_list[0]
272  res_list = list()
273  if isinstance(node, gfx.Entity):
274  ref = node.view.handle
275  for i in range(1,len(ent_list)):
276  node = ent_list[i]
277  if isinstance(node, gfx.Entity):
278  res_list.append(tmtools.TMAlign(node.view.handle, ref))
279  node.UpdatePositions()
280  if show_scores:
281  self.__ShowScore(ent_list, res_list)
282  if display_alignment:
283  self.__DisplayAlignment(ent_list, res_list)
284 
285  def __ShowScore(self, ent_list, res_list):
286  if(len(res_list)==1):
287  res = res_list[0]
288  string = "RMSD: %.2f, TMScore: %i"%(res.rmsd, res.tm_score)
289  gui.GostyApp.Instance().perspective.StatusMessage(string)
290  elif(len(res_list)>1):
291  ShowResultDialog(ent_list, res_list).exec_()
292 
293  def __DisplayAlignment(self, ent_list, res_list):
294  if(len(res_list)>0):
295  ref_seq = seq.CreateSequence("%s (ref)"%ent_list[0].GetName(),res_list[0].ref_sequence.GetGaplessString())
296  aln_list = seq.AlignmentList()
297  if(ref_seq.IsValid()):
298  for i in range(0, len(res_list)):
299  res_list[i].alignment.SetSequenceName(1,ent_list[i+1].GetName())
300  aln_list.append(res_list[i].alignment)
301  alignment = alg.MergePairwiseAlignments(aln_list, ref_seq)
302  gosty = gui.GostyApp.Instance()
303  main_area = gosty.perspective.GetMainArea()
304  if self.seq_viewer:
305  self.seq_viewer.qobject.close()
306  self.seq_viewer = gui.SequenceViewer(True)
307  self.seq_viewer.AddAlignment(alignment)
308  self.seq_viewer.ChangeDisplayMode("Highlight conservation 1")
309  self.seq_viewer.Show()
310 
311 class SelectMenuPoints(QtCore.QObject):
312  def __init__(self, context_menu):
313  QtCore.QObject.__init__(self, context_menu.qobject)
314  action=QtGui.QAction("Select...", self)
315  QtCore.QObject.connect(action, QtCore.SIGNAL('triggered()'),
316  self._Select)
317  context_menu.AddAction(action, gui.ENTITY)
318  action=QtGui.QAction("Copy Selection...", self)
319  QtCore.QObject.connect(action, QtCore.SIGNAL('triggered()'),
320  self._CopyViews)
321  context_menu.AddAction(action, gui.ENTITY)
322  action=QtGui.QAction('Select...', self)
323  QtCore.QObject.connect(action, QtCore.SIGNAL('triggered()'),
325  context_menu.AddAction(action, gui.ENTITY_VIEW|gui.VIEWS_SAME_OBJECT)
326  def _Select(self):
327  scene_selection=gui.SceneSelection.Instance()
328  ent=scene_selection.GetActiveNode(0)
329  dialog=QueryDialog('Select...')
330  if dialog.exec_():
331  q=mol.Query(dialog.query)
332  if q.IsValid():
333  ent.selection=ent.view.Select(dialog.query, dialog.query_flags)
334  else:
335  ost.LogError("invalid query: %s" % q.error)
336 
337  def _UniqueName(self, ent):
338  """
339  Returns a name based on ent that is unique within the scene
340  """
341  ent_name=ent.GetName()
342  num=2
343  while True:
344  candidate_name='%s-%d' % (ent_name, num)
345  if not gfx.Scene().HasNode(candidate_name):
346  return candidate_name
347  num+=1
348 
349  def _SelectViewsSameEntity(self):
350 
351  union=gui.SceneSelection.Instance().GetViewUnion()
352  dialog=QueryDialog('Select...')
353  if dialog.exec_():
354  q=mol.Query(dialog.query)
355  if q.IsValid():
356  ve=gui.SceneSelection.Instance().GetViewEntity()
357  ve.selection=union.Select(q, dialog.query_flags)
358  else:
359  ost.LogError("invalid query: %s" % q.error)
360 
361  def _CopyViews(self):
362  views_to_add=[]
363  scene_selection=gui.SceneSelection.Instance()
364  ent=scene_selection.GetActiveNode(0)
365  dialog=QueryDialog('Select...')
366  if dialog.exec_():
367  q=mol.Query(dialog.query)
368  if q.IsValid():
369  for i in range(scene_selection.GetActiveNodeCount()):
370  ent=scene_selection.GetActiveNode(i)
371  selected=ent.view.Select(q, dialog.query_flags)
372  gfx_ent=gfx.Entity(self._UniqueName(ent),selected)
373  gfx.Scene().Add(gfx_ent)
374  else:
375  ost.LogError("invalid query: %s" % q.error)
376 
377 def _InitContextMenu(app):
378  _InitContextMenu.cm=app.scene_win.GetContextMenu()
379  _InitContextMenu.am=AlignmentContextMenu(_InitContextMenu.cm)
380  _InitContextMenu.sc=SurfaceContextMenu(_InitContextMenu.cm)
381  _InitContextMenu.sm=SelectMenuPoints(_InitContextMenu.cm)