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 PyQt5 import QtCore, QtWidgets
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 WrappedTMAlign
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(QtWidgets.QDialog):
17  def __init__(self, ent_list, parent=None):
18  QtWidgets.QDialog.__init__(self, parent)
19  self.ent_list_ = ent_list
20  vb = QtWidgets.QVBoxLayout()
21  self.setLayout(vb)
22  self.setWindowTitle("Select Reference Object")
23  self.label = QtWidgets.QLabel("Please Select the Reference Object")
24  self.list = QtWidgets.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(QtWidgets.QAbstractItemView.SelectRows)
30  self.list.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
31  vb.addWidget(self.label)
32  vb.addWidget(self.list)
33  self.show_scores = QtWidgets.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 = QtWidgets.QCheckBox(self)
38  self.show_alignment.setText("Display Alignment")
39  self.show_alignment.setChecked(False)
40  vb.addWidget(self.show_alignment)
41  hb = QtWidgets.QHBoxLayout()
42  hb.setDirection(QtWidgets.QBoxLayout.LeftToRight)
43  cancel_btn = QtWidgets.QPushButton("Cancel", self)
44  load_btn = QtWidgets.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  load_btn.clicked.connect(self.Select)
51  cancel_btn.clicked.connect(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 = QtWidgets.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 = QtWidgets.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)
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(QtWidgets.QDialog):
87  def __init__(self, ent_list, res_list, parent=None):
88  QtWidgets.QDialog.__init__(self, parent)
89  self.ent_list_ = ent_list
90  vb = QtWidgets.QVBoxLayout()
91  self.setLayout(vb)
92  self.setWindowTitle("Alignment result")
93  self.label = QtWidgets.QLabel("Alignment results with %s as reference"%ent_list[0].GetName())
94  self.list = QtWidgets.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(QtWidgets.QAbstractItemView.SelectRows)
100  vb.addWidget(self.label)
101  vb.addWidget(self.list)
102  hb = QtWidgets.QHBoxLayout()
103  hb.setDirection(QtWidgets.QBoxLayout.LeftToRight)
104  ok_btn = QtWidgets.QPushButton("OK", self)
105  hb.addStretch(1)
106  hb.addWidget(ok_btn)
107  vb.addItem(hb)
108  ok_btn.setDefault(True)
109  ok_btn.clicked.connect(self.accept)
110 
111  for i in range(0, len(res_list)):
112  self.list.insertRow(i)
113  new_item = QtWidgets.QTableWidgetItem(ent_list[i+1].GetName())
114  new_item.setFlags(QtCore.Qt.ItemIsEnabled)
115  self.list.setItem(i, 0, new_item)
116  new_item = QtWidgets.QTableWidgetItem("%.2f"%res_list[i].rmsd)
117  new_item.setFlags(QtCore.Qt.ItemIsEnabled)
118  self.list.setItem(i, 1, new_item)
119  new_item = QtWidgets.QTableWidgetItem("%.2f"%res_list[i].tm_score)
120  new_item.setFlags(QtCore.Qt.ItemIsEnabled)
121  self.list.setItem(i, 2, new_item)
122  new_item = QtWidgets.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(QtWidgets.QDialog):
129  def __init__(self, executable, parent=None):
130  QtWidgets.QDialog.__init__(self, parent)
131  vb = QtWidgets.QGridLayout()
132  self.setLayout(vb)
133  self.setWindowTitle("MSMS Surface Settings")
134  msmsexe_label=QtWidgets.QLabel("executable")
135  self.msmsexe_field=QtWidgets.QLineEdit()
136  self.msmsexe_field.setText(executable)
137  msmsexe_browsebutton=QtWidgets.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=QtWidgets.QLabel("surface name")
142  self.surfname_field=QtWidgets.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=QtWidgets.QLabel("density")
147  self.density_spinbox=QtWidgets.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=QtWidgets.QLabel("probe radius")
153  self.probe_spinbox=QtWidgets.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=QtWidgets.QLabel("selection")
161  self.selection_field=QtWidgets.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=QtWidgets.QCheckBox("no hydrogens")
166  vb.addWidget(self.noh_box, 5, 0)
167  self.nohet_box=QtWidgets.QCheckBox("no hetatoms")
168  vb.addWidget(self.nohet_box, 5, 1)
169  self.nowat_box=QtWidgets.QCheckBox("no waters")
170  vb.addWidget(self.nowat_box, 5, 2)
171 
172  cancel_btn = QtWidgets.QPushButton("Cancel", self)
173  ok_btn = QtWidgets.QPushButton("OK", self)
174  vb.addWidget(cancel_btn, 6, 1)
175  vb.addWidget(ok_btn, 6, 2)
176 
177  msmsexe_browsebutton.clicked.connect(self.GetPath)
178  ok_btn.clicked.connect(self.accept)
179  cancel_btn.clicked.connect(self.reject)
180 
181  def GetPath(self):
182  path, _ =QtWidgets.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 = QtWidgets.QAction("Calculate Surface", self)
195  self.action.triggered.connect(self.CalculateSurface)
196  context_menu.AddAction(self.action, gui.ContextActionType.ENTITY)
197 
198  def CalculateSurface(self):
199  scene_selection = gui.SceneSelection.Instance()
200  ent_list = list()
201  for i in range(0,scene_selection.GetActiveNodeCount()):
202  ent_list.append(scene_selection.GetActiveNode(i))
204  if(cssd.exec_()):
205  self.__CalculateSurface(ent_list,
206  str(cssd.surfname_field.text()),
207  str(cssd.msmsexe_field.text()),
208  cssd.density_spinbox.value(),
209  cssd.probe_spinbox.value(),
210  str(cssd.selection_field.text()),
211  cssd.noh_box.isChecked(),
212  cssd.nohet_box.isChecked(),
213  cssd.nowat_box.isChecked())
214 
215  def __CalculateSurface(self,ent_list,name,msms_exe,density,
216  radius,selection,noh,nohet,nowat):
217  for entity in ent_list:
218  if isinstance(entity, gfx.Entity):
219  try:
220  s=msms.CalculateSurface(entity.view,
221  msms_exe=msms_exe,
222  density=density,
223  radius=radius,
224  selection=selection,
225  no_hydrogens=noh,
226  no_hetatoms=nohet,
227  no_waters=nowat)[0]
228  gfx.Scene().Add(gfx.Surface("%s_%s"%(entity.GetName(),name),s))
229  except (RuntimeError, msms.MsmsProcessError):
230  LogError("WARNING: Surface could not be calculated")
231  return
232  except UserWarning:
233  LogError("WARNING: Entry with the same name already present in scene")
234  return
235 
236 
237 class SecStructContextMenu(QtCore.QObject):
238  def __init__(self, context_menu):
239  QtCore.QObject.__init__(self, context_menu.qobject)
240  self.action = QtWidgets.QAction("Assign Secondary Structure", self)
241  self.action.triggered.connect(self.AssignSecondaryStructure)
242  context_menu.AddAction(self.action, gui.ContextActionType.ENTITY)
243 
245  scene_selection = gui.SceneSelection.Instance()
246  ent_list = list()
247  for i in range(0,scene_selection.GetActiveNodeCount()):
248  node = scene_selection.GetActiveNode(i)
249  mol.alg.AssignSecStruct(node.view)
250  node.UpdateView()
251 
252 
253 class AlignmentContextMenu(QtCore.QObject):
254 
255  def __init__(self, context_menu):
256 
257  QtCore.QObject.__init__(self, context_menu.qobject)
258  self.action = QtWidgets.QAction("Align", self)
259  self.action.triggered.connect(self.Align)
260  context_menu.AddAction(self.action, gui.ContextActionType.ENTITY | gui.ContextActionType.MULTI)
261  self.seq_viewer = None
262 
263  def Align(self):
264  scene_selection = gui.SceneSelection.Instance()
265  ent_list = list()
266  for i in range(0,scene_selection.GetActiveNodeCount()):
267  ent_list.append(scene_selection.GetActiveNode(i))
268  sd = SelectRefDialog(ent_list)
269  if(sd.exec_()):
270  self.__Align(sd.GetEntities(),sd.GetShowScores(), sd.GetDisplayAlignment())
271 
272  def __Align(self, ent_list,show_scores=True, display_alignment=False):
273  node = ent_list[0]
274  res_list = list()
275  if isinstance(node, gfx.Entity):
276  ref = node.view.chains[0]
277  for i in range(1,len(ent_list)):
278  node = ent_list[i]
279  if isinstance(node, gfx.Entity):
280  res_list.append(WrappedTMAlign(node.view.chains[0], ref))
281  node.UpdatePositions()
282  if show_scores:
283  self.__ShowScore(ent_list, res_list)
284  if display_alignment:
285  self.__DisplayAlignment(ent_list, res_list)
286 
287  def __ShowScore(self, ent_list, res_list):
288  if(len(res_list)==1):
289  res = res_list[0]
290  string = "RMSD: %.2f, TMScore: %.2f"%(res.rmsd, res.tm_score)
291  gui.GostyApp.Instance().perspective.StatusMessage(string)
292  elif(len(res_list)>1):
293  ShowResultDialog(ent_list, res_list).exec_()
294 
295  def __DisplayAlignment(self, ent_list, res_list):
296  if(len(res_list)>0):
297  ref_seq = seq.CreateSequence("%s (ref)"%ent_list[0].GetName(),
298  res_list[0].alignment.GetSequence(1).GetGaplessString())
299  aln_list = seq.AlignmentList()
300  if(ref_seq.IsValid()):
301  for i in range(0, len(res_list)):
302  # WrappedTMAlign returns an alignment with second sequence
303  # being reference... let's swap...
304  new_aln = seq.CreateAlignment()
305  new_aln.AddSequence(res_list[i].alignment.GetSequence(1))
306  new_aln.AddSequence(res_list[i].alignment.GetSequence(0))
307  new_aln.SetSequenceName(1, ent_list[i+1].GetName())
308  aln_list.append(new_aln)
309  alignment = alg.MergePairwiseAlignments(aln_list, ref_seq)
310  gosty = gui.GostyApp.Instance()
311  main_area = gosty.perspective.GetMainArea()
312  if self.seq_viewer:
313  self.seq_viewer.qobject.close()
314  self.seq_viewer = gui.SequenceViewer(True)
315  self.seq_viewer.AddAlignment(alignment)
316  self.seq_viewer.ChangeDisplayMode("Highlight conservation 1")
317  self.seq_viewer.Show()
318 
319 class SelectMenuPoints(QtCore.QObject):
320  def __init__(self, context_menu):
321  QtCore.QObject.__init__(self, context_menu.qobject)
322  action=QtWidgets.QAction("Select...", self)
323  action.triggered.connect(self._Select)
324  context_menu.AddAction(action, gui.ENTITY)
325  action=QtWidgets.QAction("Copy Selection...", self)
326  action.triggered.connect(self._CopyViews)
327  context_menu.AddAction(action, gui.ENTITY)
328  action=QtWidgets.QAction('Select...', self)
329  action.triggered.connect(self._SelectViewsSameEntity)
330  context_menu.AddAction(action, gui.ENTITY_VIEW|gui.VIEWS_SAME_OBJECT)
331  def _Select(self):
332  scene_selection=gui.SceneSelection.Instance()
333  ent=scene_selection.GetActiveNode(0)
334  dialog=QueryDialog('Select...')
335  if dialog.exec_():
336  q=mol.Query(dialog.query)
337  if q.IsValid():
338  ent.selection=ent.view.Select(dialog.query, dialog.query_flags)
339  else:
340  ost.LogError("invalid query: %s" % q.error)
341 
342  def _UniqueName(self, ent):
343  """
344  Returns a name based on ent that is unique within the scene
345  """
346  ent_name=ent.GetName()
347  num=2
348  while True:
349  candidate_name='%s-%d' % (ent_name, num)
350  if not gfx.Scene().HasNode(candidate_name):
351  return candidate_name
352  num+=1
353 
354  def _SelectViewsSameEntity(self):
355 
356  union=gui.SceneSelection.Instance().GetViewUnion()
357  dialog=QueryDialog('Select...')
358  if dialog.exec_():
359  q=mol.Query(dialog.query)
360  if q.IsValid():
361  ve=gui.SceneSelection.Instance().GetViewEntity()
362  ve.selection=union.Select(q, dialog.query_flags)
363  else:
364  ost.LogError("invalid query: %s" % q.error)
365 
366  def _CopyViews(self):
367  views_to_add=[]
368  scene_selection=gui.SceneSelection.Instance()
369  ent=scene_selection.GetActiveNode(0)
370  dialog=QueryDialog('Select...')
371  if dialog.exec_():
372  q=mol.Query(dialog.query)
373  if q.IsValid():
374  for i in range(scene_selection.GetActiveNodeCount()):
375  ent=scene_selection.GetActiveNode(i)
376  selected=ent.view.Select(q, dialog.query_flags)
377  gfx_ent=gfx.Entity(self._UniqueName(ent),selected)
378  gfx.Scene().Add(gfx_ent)
379  else:
380  ost.LogError("invalid query: %s" % q.error)
381 
382 def _InitContextMenu(app):
383  _InitContextMenu.cm=app.scene_win.GetContextMenu()
384  _InitContextMenu.am=AlignmentContextMenu(_InitContextMenu.cm)
385  _InitContextMenu.sec=SecStructContextMenu(_InitContextMenu.cm)
386  _InitContextMenu.sc=SurfaceContextMenu(_InitContextMenu.cm)
387  _InitContextMenu.sm=SelectMenuPoints(_InitContextMenu.cm)
Definition: seq.dox:1
main class for organization and root for the graphical display
Definition: scene.hh:80
graphical rendering of mol::EntityHandle entites
Definition: entity.hh:63
Selection Query.
Definition: query.hh:74
TMAlignResult WrappedTMAlign(const geom::Vec3List &pos_one, const geom::Vec3List &pos_two, const ost::seq::SequenceHandle &seq1, const ost::seq::SequenceHandle &seq2, bool fast=false)
QTableView with first column not moving.