Source code for schrodinger.application.jaguar.gui.tabs.reaction_molecules_tab

from schrodinger import get_maestro

from .. import ui
from .base_tab import BaseTab
from .molecule_tab import MoleculeTabNoInputSelector

maestro = get_maestro()

REACTANT_PREFIX = "Reactant"
PRODUCT_PREFIX = "Product"

# TODO: Renumber participants when one is deleted?
# TODO: sorting will be broken if the participant numbering goes into
#       double digits, since it's a text sort not a numerical one


[docs]class ReactionMoleculesTab(BaseTab): """" The Molecules tab used in the Reactions panel. :note: This tab does not implement loadSettings() or reset(). However, resetting the Reactions tab will remove all structures, which will result in this tab being cleared. Also note that this tab does not load default mmjag settings into its MoleculeSubTab components. Instead, we assume that the initial settings for MoleculeSubTab conform to mmjag defaults, which they do, assuming that the mmjag defaults for symmetry, charge, and spin multiplicity don't change. """ NAME = "Molecules" HELP_TOPIC = "JAGUAR_TOPIC_MOLECULE_FOLDER" UI_MODULES = (ui.reaction_molecules_tab_ui,)
[docs] def setup(self): self.participant_txt_to_molecule_widget = {} self.ui.molecules_combo.currentTextChanged.connect( self.showMoleculeWidgetForParticipant)
[docs] def newParticipant(self, txt): """ Adds a participant to the combo box, and adds a molecule widget to the stacked widget. :param txt: The txt to show along with the participant in combo :type txt: str """ molecule_widget = MoleculeTabNoInputSelector(self.ui.molecules_stacked) self.participant_txt_to_molecule_widget[txt] = molecule_widget self.ui.molecules_stacked.addWidget(molecule_widget) self.ui.molecules_combo.currentTextChanged.disconnect( self.showMoleculeWidgetForParticipant) # Re-sort to put reactant before product, with ascending #'s current_text = self.ui.molecules_combo.currentText() self.ui.molecules_combo.clear() for txt in sorted(self.participant_txt_to_molecule_widget): if txt.startswith(REACTANT_PREFIX): self.ui.molecules_combo.addItem(txt) for txt in sorted(self.participant_txt_to_molecule_widget): if txt.startswith(PRODUCT_PREFIX): self.ui.molecules_combo.addItem(txt) if current_text: self.ui.molecules_combo.setCurrentIndex( self.ui.molecules_combo.findText(current_text)) self.ui.molecules_combo.currentTextChanged.connect( self.showMoleculeWidgetForParticipant)
[docs] def removeParticipant(self, txt): """ Removes participant from combo box and removes its molecule widget :param txt: Text for molecule matching combo text :type txt: str """ molecule_widget = self.participant_txt_to_molecule_widget[txt] self.ui.molecules_stacked.removeWidget(molecule_widget) del self.participant_txt_to_molecule_widget[txt] self.ui.molecules_combo.removeItem( self.ui.molecules_combo.findText(txt))
[docs] def showMoleculeWidgetForParticipant(self, txt): """ Show a molecule widget in the stackedWidget for a participant :param txt: Text for molecule matching combo text :type txt: str """ molecule_widget = self.participant_txt_to_molecule_widget[txt] self.ui.molecules_stacked.setCurrentWidget(molecule_widget)
[docs] def changeMoleculeForParticipant(self, txt, struct): """ Show a molecule widget in the stackedWidget for a participant :param txt: Text for molecule matching combo text :type txt: str :param struct: The new structure for the participant :type struct: structure.Structure """ molecule_widget = self.participant_txt_to_molecule_widget[txt] molecule_widget.setStructure(struct)
[docs] def getParticipants(self): """ Return structures and keywords for all participants :return: A tuple of: - A list of all reactants - A list of all products Each participant is represented as a tuple of: - The structure (`schrodinger.structure.Structure`) - the molecule mmjag keywords (dict) :rtype: tuple """ reactants = [] products = [] all_participants = self.participant_txt_to_molecule_widget.items() for name, widget in sorted(all_participants): struc = widget.getStructure() keywords = widget.getMmJagKeywords() if name.startswith(REACTANT_PREFIX): reactants.append((struc, keywords)) elif name.startswith(PRODUCT_PREFIX): products.append((struc, keywords)) else: raise RuntimeError("Unrecognized participant: %s" % name) return reactants, products
[docs] def validate(self): """ Make sure that all participants have a valid basis selected :return: None if all participants are valid. An error string otherwise. :rtype: NoneType or str """ all_participants = self.participant_txt_to_molecule_widget.items() for name, widget in sorted(all_participants): msg = widget.validate() if msg: index = self.ui.molecules_combo.findText(name) self.ui.molecules_combo.setCurrentIndex(index) return "The selected basis set for %s is invalid." % name