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 from ost import geom, gfx, gui, seq
6 from ost import settings
7 from ost import LogError, mol
8 from ost.bindings import WrappedTMAlign
9 from ost.bindings import msms
10 from ost.seq import alg
11 import ost
12 from ost.gui.scene.query_editor import QueryEditorWidget,QueryDialog
13 
14 class SelectRefDialog(QtWidgets.QDialog):
15  def __init__(self, ent_list, parent=None):
16  QtWidgets.QDialog.__init__(self, parent)
17  self.ent_list_ = ent_list
18  vb = QtWidgets.QVBoxLayout()
19  self.setLayout(vb)
20  self.setWindowTitle("Select Reference Object")
21  self.label = QtWidgets.QLabel("Please Select the Reference Object")
22  self.list = QtWidgets.QTableWidget(self)
23  self.list.horizontalHeader().setStretchLastSection(True)
24  self.list.setColumnCount(2)
25  self.list.verticalHeader().setVisible(False)
26  self.list.horizontalHeader().setVisible(False)
27  self.list.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
28  self.list.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
29  vb.addWidget(self.label)
30  vb.addWidget(self.list)
31  self.show_scores = QtWidgets.QCheckBox(self)
32  self.show_scores.setText("Show Scores")
33  self.show_scores.setChecked(True)
34  vb.addWidget(self.show_scores)
35  self.show_alignment = QtWidgets.QCheckBox(self)
36  self.show_alignment.setText("Display Alignment")
37  self.show_alignment.setChecked(False)
38  vb.addWidget(self.show_alignment)
39  hb = QtWidgets.QHBoxLayout()
40  hb.setDirection(QtWidgets.QBoxLayout.LeftToRight)
41  cancel_btn = QtWidgets.QPushButton("Cancel", self)
42  load_btn = QtWidgets.QPushButton("Select", self)
43  hb.addStretch(1)
44  hb.addWidget(cancel_btn)
45  hb.addWidget(load_btn)
46  vb.addItem(hb)
47  load_btn.setDefault(True)
48  load_btn.clicked.connect(self.Select)
49  cancel_btn.clicked.connect(self.reject)
50 
51  row = 0
52  for ent in self.ent_list_:
53  variant = QtCore.QVariant(ent)
54  self.list.insertRow(row)
55  new_item = QtWidgets.QTableWidgetItem("%i"%(row+1))
56  new_item.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsEnabled)
57  new_item.setData(QtCore.Qt.UserRole,variant)
58  self.list.setItem(row, 0, new_item)
59  new_item = QtWidgets.QTableWidgetItem(ent.GetName())
60  new_item.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsEnabled)
61  self.list.setItem(row, 1, new_item)
62  row += 1
63 
64  self.list.resizeColumnsToContents()
65 
66  def Select(self):
67  items = self.list.selectedItems()
68  for item in items:
69  if(item.column()==0):
70  ent = item.data(QtCore.Qt.UserRole)
71  self.ent_list_.remove(ent)
72  self.ent_list_.insert(0,ent)
73  self.accept()
74 
75  def GetShowScores(self):
76  return self.show_scores.isChecked()
77 
79  return self.show_alignment.isChecked()
80 
81  def GetEntities(self):
82  return self.ent_list_
83 
84 class ShowResultDialog(QtWidgets.QDialog):
85  def __init__(self, ent_list, res_list, parent=None):
86  QtWidgets.QDialog.__init__(self, parent)
87  self.ent_list_ = ent_list
88  vb = QtWidgets.QVBoxLayout()
89  self.setLayout(vb)
90  self.setWindowTitle("Alignment result")
91  self.label = QtWidgets.QLabel("Alignment results with %s as reference"%ent_list[0].GetName())
92  self.list = QtWidgets.QTableWidget(self)
93  self.list.horizontalHeader().setStretchLastSection(True)
94  self.list.setColumnCount(4)
95  self.list.verticalHeader().setVisible(False)
96  self.list.setHorizontalHeaderLabels (["Name","RMSD","TMScore",""])
97  self.list.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
98  vb.addWidget(self.label)
99  vb.addWidget(self.list)
100  hb = QtWidgets.QHBoxLayout()
101  hb.setDirection(QtWidgets.QBoxLayout.LeftToRight)
102  ok_btn = QtWidgets.QPushButton("OK", self)
103  hb.addStretch(1)
104  hb.addWidget(ok_btn)
105  vb.addItem(hb)
106  ok_btn.setDefault(True)
107  ok_btn.clicked.connect(self.accept)
108 
109  for i in range(0, len(res_list)):
110  self.list.insertRow(i)
111  new_item = QtWidgets.QTableWidgetItem(ent_list[i+1].GetName())
112  new_item.setFlags(QtCore.Qt.ItemIsEnabled)
113  self.list.setItem(i, 0, new_item)
114  new_item = QtWidgets.QTableWidgetItem("%.2f"%res_list[i].rmsd)
115  new_item.setFlags(QtCore.Qt.ItemIsEnabled)
116  self.list.setItem(i, 1, new_item)
117  new_item = QtWidgets.QTableWidgetItem("%.2f"%res_list[i].tm_score)
118  new_item.setFlags(QtCore.Qt.ItemIsEnabled)
119  self.list.setItem(i, 2, new_item)
120  new_item = QtWidgets.QTableWidgetItem()
121  new_item.setFlags(QtCore.Qt.ItemIsEnabled)
122  self.list.setItem(i, 3, new_item)
123 
124  self.list.resizeColumnsToContents()
125 
126 class CalculateSurfaceSettingsDialog(QtWidgets.QDialog):
127  def __init__(self, executable, parent=None):
128  QtWidgets.QDialog.__init__(self, parent)
129  vb = QtWidgets.QGridLayout()
130  self.setLayout(vb)
131  self.setWindowTitle("MSMS Surface Settings")
132  msmsexe_label=QtWidgets.QLabel("executable")
133  self.msmsexe_field=QtWidgets.QLineEdit()
134  self.msmsexe_field.setText(executable)
135  msmsexe_browsebutton=QtWidgets.QPushButton("Browse")
136  vb.addWidget(msmsexe_label, 0, 0)
137  vb.addWidget(self.msmsexe_field, 0, 1)
138  vb.addWidget(msmsexe_browsebutton, 0, 2)
139  surfname_label=QtWidgets.QLabel("surface name")
140  self.surfname_field=QtWidgets.QLineEdit()
141  self.surfname_field.setText("surface")
142  vb.addWidget(surfname_label, 1, 0)
143  vb.addWidget(self.surfname_field, 1, 1, 1, 2)
144  density_label=QtWidgets.QLabel("density")
145  self.density_spinbox=QtWidgets.QSpinBox()
146  self.density_spinbox.setRange(1, 10)
147  self.density_spinbox.setValue(4)
148  vb.addWidget(density_label, 2, 0)
149  vb.addWidget(self.density_spinbox, 2, 1, 1, 2)
150  probe_label=QtWidgets.QLabel("probe radius")
151  self.probe_spinbox=QtWidgets.QDoubleSpinBox()
152  self.probe_spinbox.setDecimals(1)
153  self.probe_spinbox.setSingleStep(0.1)
154  self.probe_spinbox.setRange(0.3, 5.0)
155  self.probe_spinbox.setValue(1.4)
156  vb.addWidget(probe_label, 3, 0)
157  vb.addWidget(self.probe_spinbox, 3, 1, 1, 2)
158  selection_label=QtWidgets.QLabel("selection")
159  self.selection_field=QtWidgets.QLineEdit()
160  self.selection_field.setText("")
161  vb.addWidget(selection_label, 4, 0)
162  vb.addWidget(self.selection_field, 4, 1, 1, 2)
163  self.noh_box=QtWidgets.QCheckBox("no hydrogens")
164  vb.addWidget(self.noh_box, 5, 0)
165  self.nohet_box=QtWidgets.QCheckBox("no hetatoms")
166  vb.addWidget(self.nohet_box, 5, 1)
167  self.nowat_box=QtWidgets.QCheckBox("no waters")
168  vb.addWidget(self.nowat_box, 5, 2)
169 
170  cancel_btn = QtWidgets.QPushButton("Cancel", self)
171  ok_btn = QtWidgets.QPushButton("OK", self)
172  vb.addWidget(cancel_btn, 6, 1)
173  vb.addWidget(ok_btn, 6, 2)
174 
175  msmsexe_browsebutton.clicked.connect(self.GetPath)
176  ok_btn.clicked.connect(self.accept)
177  cancel_btn.clicked.connect(self.reject)
178 
179  def GetPath(self):
180  path, _ =QtWidgets.QFileDialog.getOpenFileName(self, "Choose MSMS Executable")
181  if path!='':
182  self.msmsexe_field.setText(path)
183 
184 class SurfaceContextMenu(QtCore.QObject):
185  def __init__(self, context_menu):
186  try:
187  settings_name="msms"
188  self.executable=settings.Locate(settings_name)
189  except settings.FileNotFound:
190  self.executable=""
191  QtCore.QObject.__init__(self, context_menu.qobject)
192  self.action = QtWidgets.QAction("Calculate Surface", self)
193  self.action.triggered.connect(self.CalculateSurface)
194  context_menu.AddAction(self.action, gui.ContextActionType.ENTITY)
195 
196  def CalculateSurface(self):
197  scene_selection = gui.SceneSelection.Instance()
198  ent_list = list()
199  for i in range(0,scene_selection.GetActiveNodeCount()):
200  ent_list.append(scene_selection.GetActiveNode(i))
202  if(cssd.exec_()):
203  self.__CalculateSurface(ent_list,
204  str(cssd.surfname_field.text()),
205  str(cssd.msmsexe_field.text()),
206  cssd.density_spinbox.value(),
207  cssd.probe_spinbox.value(),
208  str(cssd.selection_field.text()),
209  cssd.noh_box.isChecked(),
210  cssd.nohet_box.isChecked(),
211  cssd.nowat_box.isChecked())
212 
213  def __CalculateSurface(self,ent_list,name,msms_exe,density,
214  radius,selection,noh,nohet,nowat):
215  for entity in ent_list:
216  if isinstance(entity, gfx.Entity):
217  try:
218  s=msms.CalculateSurface(entity.view,
219  msms_exe=msms_exe,
220  density=density,
221  radius=radius,
222  selection=selection,
223  no_hydrogens=noh,
224  no_hetatoms=nohet,
225  no_waters=nowat)[0]
226  gfx.Scene().Add(gfx.Surface("%s_%s"%(entity.GetName(),name),s))
227  except (RuntimeError, msms.MsmsProcessError):
228  LogError("WARNING: Surface could not be calculated")
229  return
230  except UserWarning:
231  LogError("WARNING: Entry with the same name already present in scene")
232  return
233 
234 
235 class SecStructContextMenu(QtCore.QObject):
236  def __init__(self, context_menu):
237  QtCore.QObject.__init__(self, context_menu.qobject)
238  self.action = QtWidgets.QAction("Assign Secondary Structure", self)
239  self.action.triggered.connect(self.AssignSecondaryStructure)
240  context_menu.AddAction(self.action, gui.ContextActionType.ENTITY)
241 
243  scene_selection = gui.SceneSelection.Instance()
244  ent_list = list()
245  for i in range(0,scene_selection.GetActiveNodeCount()):
246  node = scene_selection.GetActiveNode(i)
247  mol.alg.AssignSecStruct(node.view)
248  node.UpdateView()
249 
250 
251 class AlignmentContextMenu(QtCore.QObject):
252 
253  def __init__(self, context_menu):
254 
255  QtCore.QObject.__init__(self, context_menu.qobject)
256  self.action = QtWidgets.QAction("Align", self)
257  self.action.triggered.connect(self.Align)
258  context_menu.AddAction(self.action, gui.ContextActionType.ENTITY | gui.ContextActionType.MULTI)
259  self.seq_viewer = None
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.chains[0]
275  for i in range(1,len(ent_list)):
276  node = ent_list[i]
277  if isinstance(node, gfx.Entity):
278  tm_result = WrappedTMAlign(node.view.chains[0], ref)
279  res_list.append(tm_result)
280  node.view.handle.EditXCS().ApplyTransform(tm_result.transform)
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:60
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, bool rna=false)
QTableView with first column not moving.