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