Source code for schrodinger.application.canvas.similaritygui
"""
Support for Canvas fingerprint similarity operations that use GUI components.
There are classes to perform similarity calculations and to support
graphical interfaces for similarity options.
Copyright Schrodinger, LLC. All rights reserved.
"""
# Contributors: Quentin McDonald
import schrodinger.ui.qt.swidgets as swidgets
from schrodinger.application.canvas import similarity
from schrodinger.Qt import QtWidgets
######################### Qt GUIs begin here #########################
[docs]class CanvasFingerprintSimilarityGUI(similarity.CanvasFingerprintSimilarity):
"""
A subclass of the canvas fingerprint similarity manager which is to be
used from a program with a TKInter interface. This class has methods
for creating a component which displays all the similarity metrics
options and takes care of managing the internal state
"""
[docs] def getGUI(self):
"""
Returns a GUI component which displays the similarity
options
"""
self.base_group = swidgets.SGroupBox("Similarity settings")
# Set up the layouts
self._metric_layout = swidgets.SHBoxLayout()
self._tversky_layout = swidgets.SHBoxLayout()
self.base_group.layout.addLayout(self._metric_layout)
self.base_group.layout.addLayout(self._tversky_layout)
# Now the Tversky parameters
self._tv_alpha_label = QtWidgets.QLabel('Tversky alpha:',
self.base_group)
self._tv_alpha_edit = QtWidgets.QLineEdit(str(self._alpha))
self._tv_alpha_edit.setMaximumWidth(60)
self._tv_alpha_edit.setValidator(swidgets.SNonNegativeRealValidator())
self._tv_beta_label = QtWidgets.QLabel('Tversky beta:', self.base_group)
self._tv_beta_edit = QtWidgets.QLineEdit(str(self._beta))
self._tv_beta_edit.setMaximumWidth(60)
self._tv_beta_edit.setValidator(swidgets.SNonNegativeRealValidator())
# Keep updated with the latest alpha and beta parameters
self._tv_alpha_edit.textChanged[str].connect(self.update)
self._tv_beta_edit.textChanged[str].connect(self.update)
# Lay them out
self._tversky_layout.addWidget(self._tv_alpha_label)
self._tversky_layout.addWidget(self._tv_alpha_edit)
self._tversky_layout.addWidget(self._tv_beta_label)
self._tversky_layout.addWidget(self._tv_beta_edit)
self._tversky_layout.addStretch()
# The metric widgets
self._metric_label = QtWidgets.QLabel('Similarity metric:',
self.base_group)
self.metric_combobox = swidgets.SComboBox(items=self.SIMILARITY_METRICS,
default_item='Tanimoto',
command=self.setMetricCB)
# Lay the metric widgets out
self._metric_layout.addWidget(self._metric_label)
self._metric_layout.addWidget(self.metric_combobox)
self._metric_layout.addStretch()
return self.base_group
[docs] def setMetricCB(self, metric):
"""
A callback for setting the similarity metric - takes care of
enabling the alpha and beta boxes. Also makes sure that the program is
ready to calculate similarity via the chosen metric.
:type metric: str
:param metric: the name of the similarity metric to use
"""
state = metric == "Tversky"
self._tv_alpha_label.setEnabled(state)
self._tv_alpha_edit.setEnabled(state)
self._tv_beta_label.setEnabled(state)
self._tv_beta_edit.setEnabled(state)
self.setMetric(metric)
[docs] def update(self):
"""
Update the internal state to reflect the GUI (used mainly
for alpha and beta values
"""
try:
self._alpha = float(self._tv_alpha_edit.text())
except ValueError:
# Only happens for blank edits
pass
try:
self._beta = float(self._tv_beta_edit.text())
except ValueError:
# Only happens for blank edits
pass
[docs] def getCalculationGUI(self, command, msg=None):
"""
Create the GUI section that has the calculate button
:type command: callable object
:param command: function to be called when the Calculate Similarity
button is pressed.
:type msg: str
:param msg: The message that appears right above the button
:rtype: swidgets.SGroupBox (QGroupBox object)
:return: a groupbox with the calculation widgets
"""
gbox = swidgets.SGroupBox('Similarity Calculation')
if msg is None:
msg = 'Similarity is calculated between the entries included in' + \
' the\nWorkspace and the selected entries in the project'
gbox.layout.addWidget(QtWidgets.QLabel(msg))
if command:
swidgets.SPushButton('Calculate Similarity',
layout=gbox.layout,
command=command)
else:
swidgets.SPushButton('Calculate Similarity', layout=gbox.layout)
self.tab_checkbox = swidgets.SCheckBox(
'Sort selected entries by similarity',
layout=gbox.layout,
checked=True)
return gbox
[docs] def getTab(self, command=None, settings=True, calculation=True, msg=None):
"""
Creates a tab that can be used in a QTabWidget for calculating
similarity. The tab has a CanvasFingerprintSimilarityGUI section and a
Similarity Calculation section (set up here).
:type command: callable object
:param command: function to be called when the Calculate Similarity
button is pressed.
:type settings: bool
:param settings: True if the settings section is included, False if not
:type calculation: bool
:param calculation: True if the calculation section is included,
False if not
:type msg: str
:param msg: The message that appears right above the button in the
Calculation section
:rtype: QWidget
:return: widget containing the clustering gui
Usage: QTabWidget.addTab(fp_sim.getTab(doSimilarity))
"""
widget = QtWidgets.QWidget()
tab_layout = swidgets.SVBoxLayout(widget)
if settings:
tab_layout.addWidget(self.getGUI())
if calculation:
tab_layout.addWidget(self.getCalculationGUI(command, msg))
tab_layout.addStretch()
return widget
[docs] def sortEntryCheck(self):
"""
Check if entries should be sorted or not (based on the toggle state of
the Sort selected entries checkbox on the Similarity Tab.
:rtype: bool
:return: True if the Sort checkbox is checked, False if it is not or it
doesn't exist
"""
try:
return self.tab_checkbox.isChecked()
except AttributeError:
return False