Source code for schrodinger.application.matsci.cgforcefieldgui

"""
GUI items for use with coarse grain force fields

Copyright Schrodinger, LLC. All rights reserved.
"""

from schrodinger.application.matsci import parserutils
from schrodinger.application.matsci import cgforcefield as cgff
from schrodinger.Qt import QtCore
from schrodinger.Qt import QtWidgets
from schrodinger.ui.qt import swidgets

INSTALLED_FF_LOCATION_TEXT = 'Installation'
LOCAL_FF_LOCATION_TEXT = 'Local'
FF_LOCATION_TEXTS = [INSTALLED_FF_LOCATION_TEXT, LOCAL_FF_LOCATION_TEXT]
FF_LOCATION_TEXT_TO_TYPE_DICT = dict(
    list(zip(FF_LOCATION_TEXTS, parserutils.CG_FF_LOCATION_TYPES)))
FF_LOCATION_TYPE_TO_TEXT_DICT = dict(
    list(zip(parserutils.CG_FF_LOCATION_TYPES, FF_LOCATION_TEXTS)))


[docs]class CGForceFieldSelector(swidgets.SFrame): """ A set of widgets to allow selecting the coarse-grained force field """ # Emitted when the force field selection changes forceFieldChanged = QtCore.pyqtSignal(str)
[docs] def __init__(self, label='Force field:', description=True, stretch=True, layout_type=swidgets.HORIZONTAL, default_ff_location_type=parserutils.LOCAL_CG_FF_LOCATION_TYPE, allow_enc=False, **kwargs): """ Create a CGForceFieldSelector instance The force field picker combobox is automatically populated based on the force field files available. :type description: bool :param description: If True, include a button that pops up a dialog with the decscription for the chosen force field :type stretch: bool :param stretch: Whether to add a stretch in the layout after this widget :type layout_type: int :param layout_type: Whether the widgets lay out horizontally or vertically. Should be swidgets.HORIZONTAL or swidgets.VERTICAL :type default_ff_location_type: str :param default_ff_location_type: specifies the default location to which to look for force field files, one of parserutils.INSTALLED_CG_FF_LOCATION_TYPE or parserutils.LOCAL_CG_FF_LOCATION_TYPE :type allow_enc: bool :param allow_enc: whether to allow encrypted force field files All other keyword args, including layout, are passed to the SFrame parent class """ swidgets.SFrame.__init__(self, layout_type=layout_type, **kwargs) self.allow_enc = allow_enc # Force field picker self.combo = swidgets.SLabeledComboBox( label, layout=self.mylayout, command=self.forceFieldChanged.emit, nocall=True, stretch=False) self.combo.setSizeAdjustPolicy(self.combo.AdjustToContents) # Show description self.description_button = swidgets.SPushButton( 'Description...', layout=self.mylayout, command=self.showDescription) if not description: self.description_button.hide() # Location swidgets.SLabel('Location:', layout=self.mylayout) default_index = parserutils.CG_FF_LOCATION_TYPES.index( default_ff_location_type) installed_tip = ('Select from force field files located in a\n' 'standard directory of the Schrodinger installation.') local_tip = ('Select from force field files located in the\n' 'local directory: %s.') % cgff.FF_PARAMETERS_LOCAL_PATH item_tips = [installed_tip, local_tip] self.location_rbg = swidgets.SRadioButtonGroup( labels=FF_LOCATION_TEXTS, layout=self.mylayout, default_index=default_index, tips=item_tips, command=self.loadFFCombo, nocall=True) self.loadFFCombo() if stretch: self.mylayout.addStretch()
[docs] def numForceFields(self): """ Get the number of currently allowed force fields :rtype: int :return: The number of force fields loaded into the combobox """ return self.combo.count()
[docs] def showDescription(self): """ Pop up a dialog with the description field from the force field """ path = self.getSelectedPath() data = cgff.load_force_field_parameters(path) description = data.get(cgff.DESCRIPTION_INTERNAL_KEY) if not description: description = 'No description available' self.info('Description', description)
[docs] def info(self, caption, msg): """ Pop up an informational dialog with the given message :type caption: str :param caption: The title of the dialog :type msg: str :param msg: The message to display """ QtWidgets.QMessageBox.information(self, caption, msg)
[docs] def getSelectedName(self): """ Get the currently-selected force field name :rtype: str :return: The name of the selected force field """ return self.combo.currentText()
[docs] def getSelectedPath(self): """ Get the path to the currently-selected force field file :rtype: str :return: The path to the selected force field file """ return self.combo.currentData()
[docs] def getSelectedLocationType(self): """ Get the currently-selected location type. :rtype: str :return: the location type """ location_text = self.location_rbg.checkedText() return FF_LOCATION_TEXT_TO_TYPE_DICT[location_text]
[docs] def reset(self): """ Reset all widgets and reload the available force fields """ self.location_rbg.reset() self.loadFFCombo()
[docs] def loadFFCombo(self): """ Find all available force fields and load them into the combobox """ location_type = self.getSelectedLocationType() allffdata = cgff.get_all_force_field_paths(allow_enc=self.allow_enc) ffdata = allffdata.get(location_type, {}) self.combo.clear() self.combo.addItemsFromDict(ffdata) self.description_button.setEnabled(bool(ffdata)) self.forceFieldChanged.emit(self.getSelectedName())
[docs] def getCommandLineFlags(self): """ Gets command line flags for the coarse-grain forcefield file. :rtype: list(str) :return: The command line flags needed to specify the coarse-grain forcefield """ cmd = [] cmd += [parserutils.FLAG_CGFFLD, self.getSelectedName()] cmd += [ parserutils.FLAG_CGFFLD_LOCATION_TYPE, self.getSelectedLocationType() ] return cmd