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