"""
Implementation of Qt dialog boxes used by multiple sequence viewer.
Copyright Schrodinger, LLC. All rights reserved.
"""
# Contributors: Piotr Rotkiewicz
from schrodinger.Qt import QtCore
from schrodinger.Qt import QtGui
from schrodinger.Qt import QtWidgets
from schrodinger.ui.sequencealignment import constants
from schrodinger.ui.sequencealignment import dialogs
from schrodinger.ui.sequencealignment import sequence
from schrodinger.ui.sequencealignment.maestro import getMaestroLigandList
try:
from schrodinger.maestro import maestro
except:
maestro = None
_PRIME_SETTINGS_DIALOG = None
[docs]class PrimeSettingsDialog(QtWidgets.QDockWidget):
"""
This class implements the "Prime Settings" dialog.
"""
[docs] def __init__(self, sequence_group, viewer=None):
# Initialize base class.
QtWidgets.QDockWidget.__init__(self)
self.progress_dialog = None
self.build_model_func = None
self.setAllowedAreas(QtCore.Qt.RightDockWidgetArea)
self.viewer = viewer
if self.viewer and hasattr(self.viewer, "main_window"):
self.viewer.main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea,
self)
self.setWindowTitle("Build Homology Model")
self.setWindowModality(QtCore.Qt.WindowModal)
self.sequence_group = sequence_group
#: "Build model" push button.
self.button_ok = QtWidgets.QPushButton(self)
self.button_ok.setText("Build Model")
self.button_ok.setDefault(True)
self.button_ok.clicked.connect(self.buildModel)
#: "Help" push button.
self.button_help = QtWidgets.QPushButton(self)
self.button_help.setText("Help")
self.button_help.clicked.connect(self.helpCB)
self.visibilityChanged.connect(self._visibilityChanged)
self.button_clear_constraints = QtWidgets.QPushButton(self)
self.button_clear_constraints.setText("Clear All Constraints")
self.button_clear_constraints.setToolTip(
"Remove all proximity constraints")
self.button_clear_constraints.clicked.connect(self.clearConstraints)
self.template_regions_rb = QtWidgets.QRadioButton(self)
self.template_regions_rb.setText("Select sequence regions " +
"to build a composite/chimera model")
self.template_regions_rb.setToolTip(
"Select sequence regions "
"to build a composite model.\n"
"Click on a template name to select "
"entire sequence.")
self.template_regions_rb.clicked.connect(self.buildModeChanged)
self.homomultimers_rb = QtWidgets.QRadioButton(self)
self.homomultimers_rb.setChecked(True)
self.homomultimers_rb.setText("Select multiple templates " +
"to build a homo-multimer model")
self.homomultimers_rb.setToolTip("Select multiple templates.\n"
"Each homo-multimer chain will"
" be built\nusing individual template"
" chains.")
self.homomultimers_rb.clicked.connect(self.buildModeChanged)
self.heteromultimers_cb = QtWidgets.QCheckBox(self)
self.heteromultimers_cb.setChecked(False)
self.heteromultimers_cb.setText("Build a hetero-multimer model")
self.heteromultimers_cb.setToolTip("Create and select new query tab "
"for each hetero-multimer chain.\n"
"Then select them from a list of "
"queries.")
self.heteromultimers_cb.clicked.connect(self.buildHeteroMultimer)
self.single_template_rb = QtWidgets.QRadioButton(self)
self.single_template_rb.setChecked(True)
self.single_template_rb.setText("Select single template " +
"to build a single chain model")
self.single_template_rb.setToolTip("Select single template sequence.\n"
"Otherwise the model will be built "
"using a first available template.")
self.single_template_rb.clicked.connect(self.buildModeChanged)
self.consensus_rb = QtWidgets.QRadioButton(self)
self.consensus_rb.setChecked(False)
self.consensus_rb.setText("Select multiple templates " +
"to build a consensus homology model")
self.consensus_rb.clicked.connect(self.buildModeChanged)
#: Knowledge-based mode radio button.
self.knowledge_based_rb = QtWidgets.QRadioButton()
self.knowledge_based_rb.setText("Knowledge-based (faster)")
self.knowledge_based_rb.setToolTip(
"Construct insertions and close gaps using segments from "
"known structures")
self.knowledge_based_rb.setChecked(True)
self.knowledge_based_rb.clicked.connect(self.buildModeChanged)
#: Energy-based mode radio button.
self.energy_based_rb = QtWidgets.QRadioButton()
self.energy_based_rb.setText("Energy-based")
self.energy_based_rb.setToolTip(
"Energy-based construction and refinement of residues "
"not derived from the template")
self.energy_based_rb.clicked.connect(self.buildModeChanged)
#: Knowledge-based mode line edit.
self.kb_models_le = QtWidgets.QLineEdit()
self.kb_models_le.setText("1")
self.kb_models_le.setValidator(
QtGui.QIntValidator(1, 100, self.kb_models_le))
self.kb_models_le.setMaximumWidth(40)
self.kb_models_le.setAlignment(QtCore.Qt.AlignRight)
#: Number of models layout
self.kb_models_layout = QtWidgets.QHBoxLayout()
self.kb_models_layout.addSpacing(20)
self.kb_models_layout.addWidget(QtWidgets.QLabel("Build"))
self.kb_models_layout.addWidget(self.kb_models_le)
self.kb_models_layout.addWidget(QtWidgets.QLabel("model(s)"))
self.kb_models_layout.addStretch()
#: Method layout
self.method_layout = QtWidgets.QVBoxLayout()
self.method_layout.addWidget(self.single_template_rb)
self.method_layout.addWidget(self.template_regions_rb)
self.method_layout.addWidget(self.homomultimers_rb)
self.method_layout.addWidget(self.consensus_rb)
self.method_layout.addStretch()
#: "Close" push button.
self.button_close = QtWidgets.QPushButton(self)
self.button_close.setText("Close")
self.button_close.clicked.connect(self.close)
spacer = QtWidgets.QWidget()
spacer.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
QtWidgets.QSizePolicy.Preferred)
self.constraints_layout = QtWidgets.QHBoxLayout()
self.constraints_layout.addWidget(self.button_clear_constraints)
self.button_import = QtWidgets.QPushButton(self)
self.button_import.setText("1) Import Sequence")
self.button_import.setToolTip(
"Import the sequence of the model to be built.")
self.button_import.clicked.connect(self.buttonImportCB)
self.button_find = QtWidgets.QPushButton(self)
self.button_find.setText("2) Find Templates")
self.button_find.setToolTip(
"Run a BLAST search to identify potential templates.")
self.button_find.clicked.connect(self.buttonFindCB)
self.button_get = QtWidgets.QPushButton(self)
self.button_get.setText("3) Get Structures")
self.button_get.setToolTip(
"Retrieve structures from the PDB for the current templates.")
self.button_get.clicked.connect(self.buttonGetCB)
#: Top button layout.
self.top_button_layout = QtWidgets.QHBoxLayout()
self.top_button_layout.addWidget(self.button_import)
self.top_button_layout.addWidget(self.button_find)
self.top_button_layout.addWidget(self.button_get)
#: Button layout.
self.button_layout = QtWidgets.QHBoxLayout()
self.button_layout.addWidget(self.button_help)
self.button_layout.addStretch()
self.button_layout.addWidget(self.button_ok)
self.button_layout.addWidget(self.button_close)
#: Main widget.
self.contents = QtWidgets.QWidget(self)
self.contents.setLayout(QtWidgets.QVBoxLayout())
#: Settings tabs.
self.tabs = QtWidgets.QTabWidget()
self.setWidget(self.contents)
#: Retain residue numbers checkbox.
self.retain_numbers_cb = QtWidgets.QCheckBox()
self.retain_numbers_cb.setText(
"Preserve the residue numbers of the template")
self.retain_numbers_cb.setChecked(False)
self.retain_numbers_cb.clicked.connect(self.buildModeChanged)
#: Retain rotamers checkbox.
self.retain_rotamers_cb = QtWidgets.QCheckBox()
self.retain_rotamers_cb.setText(
"Retain rotamers for conserved residues")
self.retain_rotamers_cb.setChecked(True)
#: Optimize side chains checkbox.
self.optimize_side_chains_cb = QtWidgets.QCheckBox()
self.optimize_side_chains_cb.setText("Optimize side chains")
self.optimize_side_chains_cb.setChecked(True)
self.optimize_side_chains_cb.clicked.connect(
self.optimizeSideChainsChanged)
#: Minimize residues not obtained from templates.
self.minimize_residues_cb = QtWidgets.QCheckBox()
self.minimize_residues_cb.setText(
"Minimize residues not obtained from templates")
self.minimize_residues_cb.setChecked(True)
self.insertions_cb = QtWidgets.QCheckBox()
self.insertions_cb.setText("Build insertions of up to")
self.insertions_cb.setChecked(True)
self.insertions_cb.setToolTip(
"Build untemplated loops of less than the given number of residues;\n"
"otherwise delete the loops and cap ends with NMA and ACE")
self.insertions_le = QtWidgets.QLineEdit()
self.insertions_le.setText("20")
self.insertions_le.setValidator(
QtGui.QDoubleValidator(1, 100, 1, self.insertions_le))
self.insertions_le.setMaximumWidth(40)
self.insertions_le.setAlignment(QtCore.Qt.AlignRight)
self.junctions_cb = QtWidgets.QCheckBox()
self.junctions_cb.setText("Close template junctions")
self.junctions_cb.setChecked(True)
self.junctions_cb.setToolTip(
"Build structure through template junctions so that\n"
"there are no gaps; otherwise cap ends with NMA and ACE")
self.insertions_layout = QtWidgets.QHBoxLayout()
self.insertions_layout.setContentsMargins(0, 0, 0, 0)
self.insertions_layout.addWidget(self.insertions_cb)
self.insertions_layout.addWidget(self.insertions_le)
self.insertions_label = QtWidgets.QLabel("residues")
self.insertions_layout.addWidget(self.insertions_label)
self.insertions_layout.addStretch()
self.deletions_cb = QtWidgets.QCheckBox()
self.deletions_cb.setText("Close deletions")
self.deletions_cb.setChecked(True)
self.deletions_cb.setToolTip(
"Build structure through deletions in the template so that\n"
"there are no gaps; otherwise cap ends with NMA and ACE")
self.insertions_cb.setEnabled(False)
self.settings_page = QtWidgets.QWidget()
self.settings_page_layout = QtWidgets.QVBoxLayout()
self.settings_page_layout.addWidget(self.retain_numbers_cb)
self.settings_page_layout.addWidget(self.retain_rotamers_cb)
self.settings_page_layout.addWidget(self.optimize_side_chains_cb)
self.settings_page_layout.addWidget(self.minimize_residues_cb)
self.settings_page_layout.addLayout(self.insertions_layout)
self.settings_page_layout.addWidget(self.junctions_cb)
self.settings_page_layout.addWidget(self.deletions_cb)
self.settings_page_layout.addStretch(1000)
self.settings_page.setLayout(self.settings_page_layout)
self.multimer_page = QtWidgets.QWidget()
self.template_list = QtWidgets.QListWidget()
self.template_list.setSelectionMode(
QtWidgets.QAbstractItemView.MultiSelection)
self.template_list.itemSelectionChanged.connect(
self.templateListSelectionChanged)
self.multimer_page_layout = QtWidgets.QVBoxLayout()
self.multimer_page.setLayout(self.multimer_page_layout)
self.multimer_page_layout.addWidget(
QtWidgets.QLabel(
"Create a new query for each template chain "
"(click '+'\nabove sequence window), then select them from list."
))
self.multimer_page_layout.addWidget(self.template_list)
# Constraints tab.
self.constraints_page = QtWidgets.QWidget()
self.constraints_page_layout = QtWidgets.QVBoxLayout()
self.constraints_page.setLayout(self.constraints_page_layout)
self.constraints_page_layout.addWidget(
QtWidgets.QLabel(
"You can create proximity constraints in order to define "
"<br>pairs of residues to be close in final model."
"<ul><li>Select pairs of query residues to add or remove a constraint.<br>"
"<li>Click 'Clear All Constraints' to remove all constraints.</ul>"
))
self.constraints_page_layout.addStretch()
self.constraints_page_layout.addLayout(self.constraints_layout)
self.tabs.currentChanged.connect(self.tabChanged)
self.ligands_page = QtWidgets.QWidget()
self.ligands_list = QtWidgets.QListWidget()
self.ligands_list.setSelectionMode(
QtWidgets.QAbstractItemView.MultiSelection)
self.ligands_list.itemSelectionChanged.connect(
self.ligandListSelectionChanged)
self.all_ligands_cb = QtWidgets.QCheckBox(self)
self.all_ligands_cb.setText("Show All")
self.all_ligands_cb.clicked.connect(self.refreshLigands)
self.ligands_page_layout = QtWidgets.QVBoxLayout()
self.ligands_page.setLayout(self.ligands_page_layout)
self.ligands_page_layout.addWidget(
QtWidgets.QLabel(
"Select ligands from list "
"to include them in a final model.\n"
"The selected ligands will be highlighted in the workspace.\n\n"
"Click on a position in the ligand annotation row of the sequence viewer \n"
"to set a protein-ligand proximity constraint. The query residue at that \n"
"position will be in close proximity to the ligand in the final model."
))
self.ligands_page_layout.addWidget(self.all_ligands_cb)
self.ligands_page_layout.addWidget(self.ligands_list)
self.method_gb = QtWidgets.QGroupBox()
self.method_gb.setLayout(self.method_layout)
self.mode_page = QtWidgets.QWidget()
self.mode_page_layout = QtWidgets.QVBoxLayout()
self.mode_page.setLayout(self.mode_page_layout)
self.mode_page_layout.addWidget(self.knowledge_based_rb)
self.mode_page_layout.addLayout(self.kb_models_layout)
self.mode_page_layout.addWidget(self.energy_based_rb)
self.mode_page_layout.addStretch()
self.tabs.addTab(self.mode_page, "Method")
self.tabs.addTab(self.settings_page, "Settings")
self.tabs.addTab(self.ligands_page, "Ligands")
self.tabs.addTab(self.constraints_page, "Constraints")
self.tabs.addTab(self.multimer_page, "Hetero-multimer")
self.tabs.setCurrentIndex(0)
self.tabs.setTabToolTip(3, "Energy-based mode only")
self.hetero_layout = QtWidgets.QVBoxLayout()
self.hetero_layout.addWidget(self.heteromultimers_cb)
self.hetero_gb = QtWidgets.QGroupBox(self)
self.hetero_gb.setLayout(self.hetero_layout)
self.hetero_gb.setTitle("")
self.contents.layout().addLayout(self.top_button_layout)
self.contents.layout().addWidget(self.method_gb)
self.contents.layout().addWidget(self.hetero_gb)
self.contents.layout().addWidget(self.tabs)
self.contents.layout().addLayout(self.button_layout)
self.updateWidgets()
self.query_list = []
self.ignore_ligand_selection_change = False
[docs] def optimizeSideChainsChanged(self):
if self.optimize_side_chains_cb.isChecked():
self.minimize_residues_cb.setEnabled(True)
else:
self.minimize_residues_cb.setEnabled(False)
[docs] def toggleConstraints(self, visible):
"""
Toggles visibility of the query constraints.
"""
if visible:
if hasattr(self.sequence_group, 'query_constraints'):
for index, seq in enumerate(self.sequence_group.sequences):
if seq == self.sequence_group.reference:
self.sequence_group.sequences.insert(
index + 1, self.sequence_group.query_constraints)
return
else:
for seq in self.sequence_group.sequences:
if seq.type == constants.SEQ_CONSTRAINTS:
self.sequence_group.query_constraints = seq
self.sequence_group.sequences.remove(seq)
return
def _visibilityChanged(self, visible):
"""
Panel visibility change.
"""
if not visible:
self.viewer.emphasizeArea(0)
self.viewer.build_mode = False
self.viewer.disableQueryConstraints()
self.toggleConstraints(False)
self.removeQueryLigands()
else:
self.viewer.build_mode = True
self.buildModeChanged()
self.tabChanged(0)
self.validateBuildMode()
[docs] def tabChanged(self, index):
"""
Tab changed callback.
"""
page = self.tabs.currentWidget()
if page == self.multimer_page:
self.refreshTemplates()
if page == self.constraints_page:
self.toggleConstraints(True)
self.addConstraints()
else:
self.toggleConstraints(False)
self.viewer.disableQueryConstraints()
if page == self.ligands_page:
self.refreshLigands()
else:
self.removeQueryLigands()
[docs] def removeQueryLigands(self):
"""
Clears the list of query ligand annotations.
Called when ligand tab is closed or the user exits the build mode.
"""
reference = self.sequence_group.reference
if not reference:
return
# Remove all ligand annotations
reference.children = [
child for child in reference.children
if child.annotation_type != constants.ANNOTATION_LIGAND
]
# Repaint viewer
if self.viewer:
self.viewer.alignment_changed = True
self.viewer.updateView()
[docs] def addQueryLigands(self, ligand_name_list):
"""
Creates ligand annotations for the query sequence.
The annotations are used to set ligand-query constraints.
:type ligand_name_list: list(str)
:param ligand_name_list: List of ligand names.
"""
reference = self.sequence_group.reference
if not reference:
return
current_ligand_list = []
for child in reference.children:
if child.annotation_type == constants.ANNOTATION_LIGAND:
current_ligand_list.append(child.name)
if ligand_name_list == current_ligand_list:
# The list did not change; return early.
return
self.removeQueryLigands()
has_ligand_sequences = False
# Check if there are stored ligand annotations
# and use them if they are valid
if hasattr(self.sequence_group, 'ligand_list') and \
self.sequence_group.ligand_list:
group_ligand_names, group_ligand_sequences = list(
zip(*self.sequence_group.ligand_list))
if list(group_ligand_names) == ligand_name_list:
# The ligand name list matches exisiting annotations; reuse.
reference.children += group_ligand_sequences
has_ligand_sequences = True
if not has_ligand_sequences:
group_ligand_list = []
# Create new ligand annotations
for ligand in ligand_name_list:
lig_sequence = sequence.Sequence()
lig_sequence.type = constants.SEQ_ANNOTATION
lig_sequence.annotation_type = constants.ANNOTATION_LIGAND
lig_sequence.name = ligand
lig_sequence.short_name = lig_sequence.name
lig_sequence.appendResidues(reference.gaplessText())
lig_sequence.parent_sequence = reference
for res in lig_sequence.residues:
res.code = ' '
reference.children.append(lig_sequence)
group_ligand_list.append((ligand, lig_sequence))
self.sequence_group.ligand_list = group_ligand_list
# Update gaps in the ligand sequences
reference.propagateGapsToChildren()
# Repaint the viewer
if self.viewer:
self.viewer.alignment_changed = True
self.viewer.updateView()
[docs] def ligandListSelectionChanged(self):
"""
Called when ligand list selection changes.
"""
if self.ignore_ligand_selection_change:
return
selected_items = self.ligands_list.selectedItems()
ligand_name_list = []
if selected_items:
for item in selected_items:
ligand_name_list.append(str(item.text())[5:])
self.addQueryLigands(ligand_name_list)
[docs] def templateListSelectionChanged(self):
"""
Called when template list selection changes.
"""
self.validateBuildMode()
[docs] def refreshLigands(self):
"""
Refreshes contents of the ligand table
"""
if not maestro or not self.isVisible():
return
self.ignore_ligand_selection_change = True
self.ligands_list.clear()
self.ligands_list.setSelectionRectVisible(True)
template_list = self.getTemplateList(selected_only=True)
self.ligand_name_list = []
self.ligand_entry_list = []
if template_list:
# Retrieve the ligands only if there are selected templates in MSV
self.ligand_name_list, self.ligand_entry_list = \
getMaestroLigandList(template_list,
list_all=self.all_ligands_cb.isChecked())
group_ligand_names = []
if hasattr(self.sequence_group, 'ligand_list') and \
self.sequence_group.ligand_list:
group_ligand_names, group_ligand_sequences = list(
zip(*self.sequence_group.ligand_list))
# Restore selection state of individual ligands
for ligand_name in self.ligand_name_list:
item = QtWidgets.QListWidgetItem(ligand_name)
self.ligands_list.addItem(item)
if ligand_name[5:] in group_ligand_names:
item.setSelected(True)
self.ignore_ligand_selection_change = False
self.ligandListSelectionChanged()
[docs] def refreshTemplates(self):
"""
Rebuilds the list of templates.
"""
if not self.isVisible():
return
selected_list = []
# Get list selection status.
for index in range(self.template_list.count()):
if self.template_list.item(index).isSelected():
selected_list.append(True)
else:
selected_list.append(False)
self.template_list.clear()
self.template_list.setSelectionRectVisible(True)
self.query_list = []
for group in self.viewer.sequence_group_list:
group.updateReference()
if len(group.getStructureList(omit_reference=True)) > 0 and \
group.reference:
item = QtWidgets.QListWidgetItem(group.name)
item.setData(1, group)
self.template_list.addItem(item)
self.query_list.append((item, group))
if self.template_list.count() == len(selected_list):
for index in range(self.template_list.count()):
self.template_list.item(index).setSelected(selected_list[index])
if len(self.sequence_group.getStructureList(omit_reference=True)) > 1:
self.consensus_rb.setEnabled(True)
self.homomultimers_rb.setEnabled(True)
self.template_regions_rb.setEnabled(True)
else:
self.consensus_rb.setEnabled(False)
self.homomultimers_rb.setEnabled(False)
self.template_regions_rb.setEnabled(False)
[docs] def getQueryList(self):
"""
Returns list of selected queries for heteromultimer modeling.
"""
selected_items = self.template_list.selectedItems()
if len(selected_items) == 0:
return []
selected_query_list = []
for item, group in self.query_list:
if item in selected_items:
selected_query_list.append(group)
return selected_query_list
[docs] def getTemplateList(self, selected_only=False):
"""
Returns a full list of templates for all queries.
If selected_only is True, returns only selected templates.
"""
template_list = []
query_list = []
if self.heteromultimers_cb.isChecked():
query_list = self.getQueryList()
if query_list == []:
query_list.append(self.sequence_group)
if self.all_ligands_cb.isChecked():
selected_only = False
if self.template_regions_rb.isChecked():
selected_only = False
for group in query_list:
template_list.extend(
group.getTemplates(selected_only=selected_only))
return template_list
[docs] def addConstraints(self):
"""
Enables query-query constraint mode.
"""
self.viewer.enableQueryConstraints()
[docs] def clearConstraints(self):
"""
Clears all constraints.
"""
self.viewer.clearQueryConstraints()
# Clear ligand constraints
self.sequence_group.ligand_list = []
self.ligandListSelectionChanged()
self.removeQueryLigands()
[docs] def buildHeteroMultimer(self):
"""
Enters heteromultimer building mode.
"""
if self.heteromultimers_cb.isChecked():
self.tabs.setTabEnabled(4, True)
self.tabs.setCurrentIndex(4)
else:
self.tabs.setTabEnabled(4, False)
self.buildModeChanged()
self.validateBuildMode()
[docs] def buildModeChanged(self):
"""
Called when build mode changes. Validates and updates GUI settings.
"""
self.heteromultimers_cb.setEnabled(True)
self.kb_models_le.setEnabled(False)
self.tabs.setEnabled(True)
if not self.heteromultimers_cb.isChecked():
self.tabs.setTabEnabled(4, False)
else:
self.tabs.setTabEnabled(4, True)
self.sequence_group.build_mode = constants.PRIME_MODE_HETEROMULTIMER
if self.template_regions_rb.isChecked():
self.sequence_group.build_mode = constants.PRIME_MODE_COMPOSITE
self.viewer.emphasizeArea(2)
self.sequence_group.unselectAllSequences()
self.sequence_group.premarkTemplateRegion()
elif self.homomultimers_rb.isChecked():
self.sequence_group.build_mode = constants.PRIME_MODE_HOMOMULTIMER
if not self.sequence_group.hasSelectedSequences(
exclude_reference=True):
self.sequence_group.selectFirstTemplate(n_templates=2)
self.viewer.emphasizeArea(1)
elif self.consensus_rb.isChecked():
self.sequence_group.build_mode = constants.PRIME_MODE_CONSENSUS
if not self.sequence_group.hasSelectedSequences(
exclude_reference=True):
self.sequence_group.selectFirstTemplate(n_templates=2)
self.viewer.emphasizeArea(1)
self.heteromultimers_cb.setEnabled(False)
self.heteromultimers_cb.setChecked(False)
self.tabs.setEnabled(False)
else:
self.sequence_group.build_mode = constants.PRIME_MODE_SINGLE
if not self.sequence_group.hasSelectedSequences(
exclude_reference=True):
self.sequence_group.selectFirstTemplate()
self.viewer.emphasizeArea(1)
self.updateWidgets()
self.validateBuildMode()
[docs] def getParameters(self):
"""
Returns a dictionary of parameters for the Prime backend.
"""
parameters = {}
parameters["preview_model"] = False
parameters["keep_rotamers"] = self.retain_rotamers_cb.isChecked()
parameters[
"optimize_side_chains"] = self.optimize_side_chains_cb.isChecked()
parameters["minimize_residues"] = self.minimize_residues_cb.isChecked()
parameters["build_insertions"] = self.insertions_cb.isChecked()
parameters["max_insertion_length"] = int(self.insertions_le.text())
parameters["build_transitions"] = self.junctions_cb.isChecked()
parameters["build_deletions"] = self.deletions_cb.isChecked()
parameters["knowledge_based"] = self.knowledge_based_rb.isChecked()
parameters["num_output_struct"] = int(self.kb_models_le.text())
parameters[
"template_residue_numbers"] = self.retain_numbers_cb.isChecked()
return parameters
[docs] def validateQuerySequences(self, group_list):
"""
Tests if all query sequences in the provided list of groups
include only valid characters.
:type group_list: list of `SequenceGroup`
:param group_list: List of groups used to build the model.
:rtype: bool
:return: True if all sequences are valid, False otherwise.
"""
invalid_characters = 'BJOUXZ'
# The assumption here is that the sequence already consists of
# A-Z characters and gap symbols, so we only need to check
# a few disallowed characters.
for group in group_list:
for ch in invalid_characters:
if ch in group.reference.text():
dialogs.error_dialog(
'Invalid Query Sequence',
'Query sequence includes invalid character: \'' + ch +
'\'\n'
'Please modify the query seqeunce before '
'building homology model.')
return False
return True
[docs] def buildModel(self):
"""
Actually launch the model building job.
"""
if self.viewer:
self.viewer.build_mode = False
self.close()
if not self.build_model_func:
return
parameters = self.getParameters()
groups = []
if self.heteromultimers_cb.isChecked():
modeling_mode = constants.PRIME_MODE_HETEROMULTIMER
groups += self.getQueryList()
else:
modeling_mode = self.sequence_group.build_mode
if not groups:
groups = [self.sequence_group]
templates = self.getTemplateList()
if self.viewer:
job_settings = self.viewer.job_settings
else:
job_settings = None
if not self.validateQuerySequences(groups):
return
return self.build_model_func(settings=parameters,
mode=modeling_mode,
group_list=groups,
valid_template_list=templates,
progress_dialog=self.progress_dialog,
viewer=self.viewer,
job_settings=job_settings)
[docs] def previewModel(self):
"""
Launch the model building job in "preview" mode.
"""
if self.viewer:
self.viewer.build_mode = False
self.sequence_group.repaintTemplateStructures()
self.close()
if not self.build_model_func:
return
parameters = self.getParameters()
parameters["preview_model"] = True
groups = []
if self.heteromultimers_cb.isChecked():
modeling_mode = constants.PRIME_MODE_HETEROMULTIMER
groups += self.getQueryList()
else:
modeling_mode = self.sequence_group.build_mode
if not groups:
groups = [self.sequence_group]
templates = self.getTemplateList()
if self.viewer:
job_settings = self.viewer.job_settings
else:
job_settings = None
return self.build_model_func(settings=parameters,
mode=modeling_mode,
group_list=groups,
valid_template_list=templates,
progress_dialog=self.progress_dialog,
job_settings=job_settings)
[docs] def validateBuildMode(self):
"""
Validates current build mode and Sets 'Build model' button status.
"""
valid = True
n_templates = 0
n_selected_templates = 0
for seq in self.sequence_group.sequences:
if seq.isValidTemplate(reference=self.sequence_group.reference):
n_templates += 1
if seq.selected:
n_selected_templates += 1
if self.sequence_group.reference is None:
valid = False
elif self.sequence_group.build_mode == constants.PRIME_MODE_SINGLE and \
n_selected_templates == 0:
valid = False
elif self.sequence_group.build_mode == constants.PRIME_MODE_HOMOMULTIMER and \
n_selected_templates < 2:
valid = False
elif self.sequence_group.build_mode == constants.PRIME_MODE_CONSENSUS \
and n_selected_templates < 2:
valid = False
elif n_templates == 0:
valid = False
if self.heteromultimers_cb.isChecked():
selected_count = 0
# Get list selection status.
for index in range(self.template_list.count()):
if self.template_list.item(index).isSelected():
selected_count += 1
if selected_count < 2:
valid = False
self.button_ok.setEnabled(valid)
[docs] def helpCB(self):
"""
Invokes a Homology Modeling help page.
"""
if maestro:
maestro.command("helptopic TOOLS_MENU_MSV_BUILD_MODEL")
[docs]def showPrimeSettingsDialog(viewer, sequence_group, build_model_func,
progress_dialog):
"""
Opens Prime settings dialog and returns a parameter tuple.
"""
global _PRIME_SETTINGS_DIALOG
if not _PRIME_SETTINGS_DIALOG:
_PRIME_SETTINGS_DIALOG = PrimeSettingsDialog(sequence_group,
viewer=viewer)
setPrimeSequenceGroup(sequence_group)
_PRIME_SETTINGS_DIALOG.build_model_func = build_model_func
_PRIME_SETTINGS_DIALOG.progress_dialog = progress_dialog
_PRIME_SETTINGS_DIALOG.viewer = viewer
_PRIME_SETTINGS_DIALOG.show()
return _PRIME_SETTINGS_DIALOG.getParameters()
[docs]def setPrimeSequenceGroup(sequence_group):
global _PRIME_SETTINGS_DIALOG
if sequence_group.build_mode < 1:
sequence_group.build_mode = constants.PRIME_MODE_SINGLE
if _PRIME_SETTINGS_DIALOG:
_PRIME_SETTINGS_DIALOG.sequence_group = sequence_group
_PRIME_SETTINGS_DIALOG.single_template_rb.setChecked(
sequence_group.build_mode == constants.PRIME_MODE_SINGLE)
_PRIME_SETTINGS_DIALOG.homomultimers_rb.setChecked(
sequence_group.build_mode == constants.PRIME_MODE_HOMOMULTIMER)
_PRIME_SETTINGS_DIALOG.template_regions_rb.setChecked(
sequence_group.build_mode == constants.PRIME_MODE_COMPOSITE)
_PRIME_SETTINGS_DIALOG.consensus_rb.setChecked(
sequence_group.build_mode == constants.PRIME_MODE_CONSENSUS)
_PRIME_SETTINGS_DIALOG.buildModeChanged()
_PRIME_SETTINGS_DIALOG.refreshLigands()
_PRIME_SETTINGS_DIALOG.validateBuildMode()
[docs]def getPrimeLigandsForEntryID(entry_id):
global _PRIME_SETTINGS_DIALOG
dialog = _PRIME_SETTINGS_DIALOG
if not dialog or not maestro:
return []
ligand_list = []
# ligand_name_list, ligand_entry_list = getMaestroLigandList()
for index, ligand_name in enumerate(dialog.ligand_name_list):
item = dialog.ligands_list.item(index)
if item and item.isSelected():
id, pdbres, asl, st = dialog.ligand_entry_list[index]
if entry_id == id:
ligand_list.append(st)
return ligand_list
[docs]def updatePrimeQueryList(refresh_templates=True, refresh_ligands=False):
global _PRIME_SETTINGS_DIALOG
if _PRIME_SETTINGS_DIALOG:
if _PRIME_SETTINGS_DIALOG.isVisible():
_PRIME_SETTINGS_DIALOG.buildModeChanged()
if refresh_ligands and \
_PRIME_SETTINGS_DIALOG.tabs.currentWidget() == \
_PRIME_SETTINGS_DIALOG.ligands_page:
_PRIME_SETTINGS_DIALOG.refreshLigands()
if refresh_templates:
_PRIME_SETTINGS_DIALOG.refreshTemplates()
[docs]def primeValidateBuildMode():
global _PRIME_SETTINGS_DIALOG
if _PRIME_SETTINGS_DIALOG and \
_PRIME_SETTINGS_DIALOG.isVisible():
_PRIME_SETTINGS_DIALOG.validateBuildMode()