"""
This class implements a sequence viewer main window, all menus, toolbars and
associated actions.
Copyright Schrodinger, LLC. All rights reserved.
"""
# Contributors: Deacon Sweeney, Piotr Rotkiewicz
import collections
import itertools
import os
import sys
from schrodinger import get_maestro
from schrodinger.Qt import QtCore
from schrodinger.Qt import QtGui
from schrodinger.Qt import QtWidgets
# Schrodinger Qt Widgets
from schrodinger.ui.qt.appframework import AppFramework
from schrodinger.ui.qt.filedialog import FileDialog
from schrodinger.ui.sequencealignment.msv_menu import MAESTRO_MENU_LIST
from schrodinger.ui.sequencealignment.msv_menu import MENU_LIST
from schrodinger.ui.sequencealignment.msv_menu import SEPARATOR
from schrodinger.utils import fileutils
# This import is required for icons
from . import constants
from . import dialogs
from . import maestro as maestro_helpers
from . import predictors
from . import sequencealignment_rc # noqa: F401, pylint: disable=unused-import
from .find_gui import createFindToolbar
from .prime_gui import updatePrimeQueryList
from .sequence_viewer import SequenceViewer
maestro = get_maestro()
try:
from schrodinger.infra.mm import mmfile_schrodinger_appdata_dir
except:
mmfile_schrodinger_appdata_dir = None
#Paths to setChecked to False at start:
START_UNCHECKED_PATHS = [
"&Sequences/Sort by &Tree Order",
"Sett&ings/&Display Percentage Similarity", "&Alignment/Use Constraints",
"Color/&Weight Colors by Alignment Quality", "&Alignment/Track Changes",
"Color/&Average Colors In Columns", "Color/Color Matching Residues Only",
"Sett&ings/&Display Percentage Identity", "Color/Adjust Text Contrast",
"Sett&ings/&Display Sequence Boundaries",
"Color/Color Different Residues Only",
"Sett&ings/Group Annotations by Type", "Sett&ings/&Display Header Row",
"Sett&ings/&Replace Identities With Dots",
"Sett&ings/&Display Percentage Homology", "Sett&ings/&Display Score",
"Sett&ings/Calculate Sequence Identity Only in Selected Columns"
]
#Paths to setChecked to True at start:
START_CHECKED_PATHS = [
"Color/Color Sequences", "Sett&ings/&Display Ruler",
"Sett&ings/&Font Size/12", "Sett&ings/&Display Alignment Tooltips",
"Sett&ings/Include Gaps in Sequence Identity Calculations",
"Sett&ings/Automatically Update Sequence Profile",
"Sett&ings/Ask Before Accessing a Remote Server"
]
START_UNCHECKED_PATHS_MAESTRO = [
"&Annotations/Ligand Contacts", "&Maestro/Allow Structural Changes"
]
START_CHECKED_PATHS_MAESTRO = [
"&Maestro/&Update Automatically from Maestro",
"&Maestro/Include Incorporated Entries in Workspace",
"&Annotations/Antibody Numbering Scheme/Chothia"
]
[docs]class AlignmentWindow(AppFramework):
"""
AlignmentWindow class implements a main window of the sequence viewer.
"""
[docs] def __init__(self, filename=None):
# Initialize base class.
AppFramework.__init__(self)
self.sequence_viewer = SequenceViewer(self) #widget
self.sequence_viewer.main_window = self
# These toggles are specific to standalone MSV (not SSV)
self.sequence_viewer.save_state = True
self.sequence_viewer.incorporate_scratch_entry = False
self.sequence_viewer.update_annotations_menu = True
#: Current project name.
self.project_name = None
self.query_tabs = QtWidgets.QTabBar(self)
self.query_tabs.setExpanding(False)
self.query_tabs.setTabsClosable(True)
self.query_tabs.setMovable(False)
self.query_tabs.setAutoFillBackground(False)
self.query_tabs.setDrawBase(False)
self.query_tabs.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.query_tabs.currentChanged.connect(self.queryTabChanged)
self.query_tabs.tabCloseRequested.connect(self.queryTabClose)
self.query_tabs.customContextMenuRequested.connect(
self.queryContextMenu)
self.ignore_tab_change = False
self.central_frame = QtWidgets.QWidget()
self.central_frame.setContentsMargins(0, 0, 0, 0)
vlayout = QtWidgets.QVBoxLayout()
vlayout.setSpacing(0)
self.central_frame.setLayout(vlayout)
self.new_tab_button = QtWidgets.QToolButton()
self.new_tab_button.setText("+")
self.new_tab_button.setToolTip("Add a New Tab")
self.new_tab_button.setToolButtonStyle(QtCore.Qt.ToolButtonTextOnly)
self.new_tab_button.clicked.connect(self.addNewQueryTab)
self.query_tabs_layout = QtWidgets.QHBoxLayout()
self.query_tabs_layout.setSpacing(0)
self.query_tabs_layout.addWidget(self.query_tabs)
self.query_tabs_layout.addSpacing(5)
self.query_tabs_layout.addWidget(self.new_tab_button)
self.query_tabs_layout.addStretch(100)
vlayout.addLayout(self.query_tabs_layout)
vlayout.addWidget(self.sequence_viewer)
# Set the sequence viewer as a central widget.
self.setCentralWidget(self.central_frame)
self.createActions()
self.createMenus()
self.createToolBars() #window toolbars
self.createStatusBar() #at the bottom
self.viewerNewSet()
self.resize(QtCore.QSize(900, 250)) # Resize window to a default size.
# File dialogs.
self.file_import_dialog = None
self.file_export_dialog = None
self.project_open_dialog = None
self.project_save_dialog = None
self.image_export_dialog = None
self.knime_output_file = None
# File dialogs custom widgets.
self.file_import_opt_merge = QtWidgets.QCheckBox(
"Align to query sequence")
self.file_import_opt_merge.setChecked(False)
self.file_import_opt_replace = QtWidgets.QCheckBox(
"Replace matching sequences")
self.file_import_opt_replace.setChecked(False)
self.file_import_opt_incorporate = QtWidgets.QCheckBox(
"Incorporate imported structures into Maestro project")
self.file_import_opt_incorporate.setChecked(True)
self.file_import_opt_translate = QtWidgets.QCheckBox(
"Translate DNA / RNA sequences")
self.file_import_opt_translate.setChecked(False)
self.image_export_opt_save_visible = QtWidgets.QCheckBox(
"Export image of the entire alignment")
self.image_export_opt_save_visible.setChecked(True)
self.file_export_opt_save_annotations = QtWidgets.QCheckBox(
"Save annotations")
self.file_export_opt_save_annotations.setChecked(False)
self.file_export_opt_save_similarity = QtWidgets.QCheckBox(
"Save similarity values")
self.file_export_opt_save_similarity.setChecked(False)
self.file_export_opt_selected_only = QtWidgets.QCheckBox(
"Export only selected part of the alignment")
self.file_export_opt_selected_only.setChecked(False)
# Create settings
if mmfile_schrodinger_appdata_dir:
settings_path = mmfile_schrodinger_appdata_dir()
QtCore.QSettings.setPath(QtCore.QSettings.IniFormat,
QtCore.QSettings.UserScope, settings_path)
self.settings = QtCore.QSettings(QtCore.QSettings.IniFormat,
QtCore.QSettings.UserScope,
"multiple_sequence_viewer")
# Read and apply settings. The settings are stored using Qt mechanism.
# On Unix they are stored in ~/.config/Schrodinger/
# On Windows they are stored in the registry.
self.readSettings(self.settings)
self.setWindowTitle("Multiple Sequence Viewer (Deprecated)")
# Hide tree viewer pane.
sizes_list = self.sequence_viewer.sizes()
sizes_list[0] = 0
self.sequence_viewer.setSizes(sizes_list)
self.sequence_viewer.setUndoRedoActions(self.actions["&Edit/&Undo"],
self.actions["&Edit/&Redo"])
# Make sure the font size is up-to-date.
self.sequence_viewer.updateFontSize(self.sequence_viewer.font_size)
# If running from Maestro, synchronize with workspace contents.
if maestro:
self.viewerSynchronizeWithMaestro()
if filename:
self.sequence_viewer.loadProject(filename)
self.queryTabChanged(0)
self.sequence_viewer.always_ask_action = \
self.actions["Sett&ings/Ask Before Accessing a Remote Server"]
self.sequence_viewer.query_tabs = self.query_tabs
self.sequence_viewer.setPopupMenus(self.nameMenuCB, self.sequenceMenuCB,
self.treeMenuCB)
self.actions["&File/Send Back to &Knime"].setVisible(False)
self.picked_query = -1
# Do not replace main menu bar on Darwin
if sys.platform == "darwin":
self.menuBar().setNativeMenuBar(False)
self.build_model_mode = False
[docs] def closeEvent(self, event):
"""
Called when the main window is about to be closed.
"""
self.writeSettings(self.settings)
# Remove Maestro callbacks, they will be restored when the
# window is re-opened.
self.sequence_viewer.removeMaestroCallbacks()
# This preserves MSV state in current Maestro project
self.sequence_viewer.closeEvent(event)
event.accept()
[docs] def showEvent(self, event):
"""
Synchronize with Maestro whenever the MSV window is opened
and the sequence group is empty.
"""
if self.sequence_viewer and maestro:
if not self.sequence_viewer.sequence_group.sequences:
self.sequence_viewer.incorporateIncludedEntries(
incorporate_scratch_entry=True)
self.sequence_viewer.maestroProjectChanged()
if self.build_model_mode:
self.build_model_mode = False
self.sequence_viewer.buildModel()
self.sequence_viewer.contents_changed = True
self.sequence_viewer.updateView()
# Initialize Maestro callbacks.
if self.sequence_viewer:
self.sequence_viewer.initMaestro()
[docs] def setBuildModel(self):
"""
Called in multiseqviewer.py
"""
self.build_model_mode = True
[docs] def newFile(self):
"""
Creates a new project. Deletes all contents and sets a default
window title.
"""
self.project_name = None
self.fetchLineEdit.setText("")
self.findLineEdit.setText("")
self.sequence_viewer.clearSet()
self.setWindowTitle("Multiple Sequence Viewer")
[docs] def open(self):
"""
Opens a sequence file. Currently supported formats are FASTA, PDB
and SwissProt.
:rtype: bool
:return: True if operation succeeded, False otherwise
"""
result = False
if not self.file_import_dialog:
self.file_import_dialog = FileDialog()
self.file_import_dialog.setFileMode(
QtWidgets.QFileDialog.ExistingFiles)
self.file_import_dialog.setOption(
QtWidgets.QFileDialog.DontUseNativeDialog)
self.file_import_dialog.setViewMode(QtWidgets.QFileDialog.Detail)
self.file_import_dialog.setWindowTitle("Import Sequences")
file_formats = [
("FASTA", [fileutils.SeqFormat.fasta]),
("PDB", [fileutils.PDB]),
("SWISSPROT", [fileutils.SeqFormat.swissprot]),
("GCG", [fileutils.SeqFormat.gcg]),
("EMBL", [fileutils.SeqFormat.embl]),
("PIR", [fileutils.SeqFormat.pir]),
]
if maestro:
file_formats.insert(1, ("Maestro", [fileutils.MAESTRO]))
all_formats = ("All supported formats",
list(
itertools.chain(*(v for __, v in file_formats))))
file_formats.insert(0, all_formats)
file_formats.append(("Any file", ['ALL']))
self.file_import_dialog.setNameFilters(
fileutils.get_name_filter(
collections.OrderedDict(file_formats)))
self.options_layout = QtWidgets.QVBoxLayout()
self.options_layout.addWidget(self.file_import_opt_merge)
self.options_layout.addWidget(self.file_import_opt_replace)
self.options_layout.addWidget(self.file_import_opt_translate)
if maestro:
self.options_layout.addWidget(self.file_import_opt_incorporate)
self.file_import_dialog.layout().addLayout(
self.options_layout,
self.file_import_dialog.layout().rowCount(), 1)
self.file_import_dialog.exec_()
if self.file_import_dialog.result():
file_names = self.file_import_dialog.selectedFiles()
for name in file_names:
to_maestro = False
include = False
if maestro:
to_maestro = self.file_import_opt_incorporate.isChecked()
include = self.actions[
"&Maestro/Include Incorporated Entries in Workspace"].isChecked(
)
result = self.sequence_viewer.loadFile(
str(name),
merge=self.file_import_opt_merge.isChecked(),
replace=self.file_import_opt_replace.isChecked(),
translate=self.file_import_opt_translate.isChecked(),
to_maestro=to_maestro,
maestro_include=include) or result
if result:
self.setWindowTitle("Multiple Sequence Viewer -" + name)
return result
[docs] def processCommandLine(self, cmdline):
"""
This processes the command line.
"""
input_file = None
command_file = None
knime_file = None
if len(cmdline) > 1:
if cmdline[1][0] != '-':
self.loadFiles([cmdline[1]])
return
this_cmd = None
for cmd in cmdline:
if cmd[0] == '-':
this_cmd = cmd
else:
if this_cmd:
if this_cmd[1] == 'c':
command_file = cmd
elif this_cmd[1] == 'i':
input_file = cmd
elif this_cmd[1] == 'k':
knime_file = cmd
this_cmd = None
if input_file:
self.loadFiles([input_file])
if knime_file:
self.knime_output_file = knime_file
self.actions["&File/Send Back to &Knime"].setVisible(True)
if command_file:
self.sequence_viewer.executeCommandFile(command_file)
[docs] def loadFiles(self, file_list):
for name in file_list:
self.sequence_viewer.loadFile(
str(name),
merge=self.file_import_opt_merge.isChecked(),
replace=self.file_import_opt_replace.isChecked(),
translate=self.file_import_opt_translate.isChecked(),
to_maestro=True)
[docs] def loadProject(self):
"""
Loads a MSV project.
"""
result = False
if not self.project_open_dialog:
self.project_open_dialog = FileDialog()
self.project_open_dialog.setOption(
QtWidgets.QFileDialog.DontUseNativeDialog)
self.project_open_dialog.setViewMode(QtWidgets.QFileDialog.Detail)
self.project_open_dialog.setWindowTitle("Open Project")
self.project_open_dialog.setNameFilters(
["Multiple Sequence Viewer (*.msv)"])
self.project_open_dialog.exec_()
if self.project_open_dialog.result():
file_names = self.project_open_dialog.selectedFiles()
for name in file_names:
result = result or self.sequence_viewer.loadProject(str(name))
if result:
self.setWindowTitle("Multiple Sequence Viewer -" + name)
return result
[docs] def saveAs(self):
"""
Opens "Export Sequences" file dialog.
"""
result = False
if not self.file_export_dialog:
self.file_export_dialog = FileDialog()
self.file_export_dialog.setAcceptMode(
QtWidgets.QFileDialog.AcceptSave)
self.file_export_dialog.setOption(
QtWidgets.QFileDialog.DontUseNativeDialog)
self.file_export_dialog.setWindowTitle("Export Sequences")
self.file_export_dialog.setViewMode(QtWidgets.QFileDialog.Detail)
self.file_export_dialog.setNameFilters(
["FASTA (*.fasta *.fst *.fas *.seq)", "Text (*.*)"])
self.file_export_dialog.layout().addWidget(
self.file_export_opt_save_annotations)
self.file_export_dialog.layout().addWidget(
self.file_export_opt_save_similarity)
self.file_export_dialog.layout().addWidget(
self.file_export_opt_selected_only)
self.file_export_dialog.exec_()
if self.file_export_dialog.result():
file_names = self.file_export_dialog.selectedFiles()
if len(file_names) < 1:
return False
format = str(self.file_export_dialog.selectedNameFilter())[:3]
result = self.sequence_viewer.saveFile(
file_names[0],
save_annotations=self.file_export_opt_save_annotations.
isChecked(),
selected_only=self.file_export_opt_selected_only.isChecked(),
save_similarity=self.file_export_opt_save_similarity.isChecked(
),
format=format)
if result:
self.setWindowTitle("Multiple Sequence Viewer -" + file_names[0])
return result
[docs] def saveProject(self):
"""
Saves the project.
"""
if self.project_name:
self.sequence_viewer.saveProject(self.project_name)
else:
self.saveProjectAs()
[docs] def saveProjectAs(self):
"""
Saves MSV project.
"""
result = False
if not self.project_save_dialog:
self.project_save_dialog = FileDialog()
self.project_save_dialog.setAcceptMode(
QtWidgets.QFileDialog.AcceptSave)
self.project_save_dialog.setOption(
QtWidgets.QFileDialog.DontUseNativeDialog)
self.project_save_dialog.setWindowTitle("Save Project")
self.project_save_dialog.setViewMode(QtWidgets.QFileDialog.Detail)
self.project_save_dialog.setNameFilters(
["Sequence viewer project (*.msv)"])
self.project_save_dialog.exec_()
if self.project_save_dialog.result():
file_names = self.project_save_dialog.selectedFiles()
if len(file_names) < 1:
return False
file_name = file_names[0]
if len(file_name) == 0:
return False
name, ext = os.path.splitext(str(file_name))
if (not ext) or (ext != ".msv"):
file_name += ".msv"
result = self.sequence_viewer.saveProject(file_name)
if result:
self.setWindowTitle("Multiple Sequence Viewer -" + file_name)
self.project_name = file_name
return result
[docs] def backToKnime(self):
"""
Sends the alignment back to a specified output file for KNIME.
"""
if self.knime_output_file:
self.sequence_viewer.saveFile(self.knime_output_file)
self.close()
[docs] def saveImageAs(self):
"""
Export image file dialog.
"""
result = False
if not self.image_export_dialog:
self.image_export_dialog = FileDialog()
self.image_export_dialog.setAcceptMode(
QtWidgets.QFileDialog.AcceptSave)
self.image_export_dialog.setOption(
QtWidgets.QFileDialog.DontUseNativeDialog)
self.image_export_dialog.setWindowTitle("Export Image")
self.image_export_dialog.setViewMode(QtWidgets.QFileDialog.Detail)
self.image_export_dialog.setNameFilters(
["PNG Image (*.png)", "PDF Image (*.pdf)"])
self.image_export_dialog.layout().addWidget(
self.image_export_opt_save_visible)
self.image_export_dialog.exec_()
if self.image_export_dialog.result():
file_names = self.image_export_dialog.selectedFiles()
if len(file_names) < 1:
return False
file_name = file_names[0]
if len(file_name) == 0:
return False
name, ext = os.path.splitext(str(file_name))
format = str(self.image_export_dialog.selectedNameFilter())[:3]
if (not ext) or (ext != "." + format.lower()):
file_name += "." + format.lower()
result = self.sequence_viewer.saveImage(
file_name,
save_all=self.image_export_opt_save_visible.isChecked(),
format=format)
return result
[docs] def createActionsAndMenu(self, list):
"""
Creates all menus and their actions. Sets their slots, short cuts,
tool tips, and checkable. Also creates self.actions = {labels: QActions}
All base components of MENU_LIST are strings.
:param list: MENU_LIST of all the menus, actions, and slots.
:type list: list of never ending lists with strings inside
"""
self.actions = {} #holds all created actions
self.menus = {} #holds all created menus
for menu_list in list:
menu_name = menu_list[0]
menu = self.menuBar().addMenu(self.tr(menu_name))
self.menus[menu_name] = menu
for action_list in menu_list[1:]:
if action_list[0] == SEPARATOR:
menu.addSeparator()
else:
if hasattr(action_list[1], "__iter__") and not isinstance(
action_list[1], str):
sub_menu_name = action_list[0]
sub_menu = menu.addMenu(self.tr(sub_menu_name))
sub_menu_key = "/".join([menu_name, sub_menu_name])
self.menus[sub_menu_key] = sub_menu
for sub_action_list in action_list[1:]:
if sub_action_list[0] == SEPARATOR:
sub_menu.addSeparator()
else:
(key_value, action) = self.createAction(
sub_action_list, sub_menu_name, sub_menu)
key_value = "/".join([menu_name, key_value])
self.actions[key_value] = action
else:
(key_value,
action) = self.createAction(action_list, menu_name,
menu)
self.actions[key_value] = action
[docs] def createAction(self, action_list, menu_name, menu):
"""
Creates actions from sublists of msv_menu
:param action_list: ['action label', 'slot method name', 'tool tip',
'shortcut', 'set checkable', 'icon'] or [SEPARATOR]
:param menu_name: string name of Menu label
:param menu: menu item to add action to
:return: (key_value, action) for self.actions
"""
action_name = action_list[0]
icon = action_list[5]
if icon:
action = QtWidgets.QAction(QtGui.QIcon(icon), self.tr(action_name),
self)
else:
action = QtWidgets.QAction(action_name, self)
slot = getattr(self, action_list[1])
tooltip = action_list[2]
shortcut = action_list[3]
checkable = action_list[4]
action.triggered.connect(slot)
if tooltip:
action.setStatusTip(self.tr(tooltip))
if shortcut:
action.setShortcut(self.tr(shortcut))
if checkable:
action.setCheckable(True)
menu.addAction(action)
key_value = "/".join([menu_name, action_name])
return (key_value, action)
[docs] def setUpActionsDisabled(self):
""" Disables desired actions for setup. """
self.actions["&Edit/&Undo"].setEnabled(False)
self.actions["&Edit/&Redo"].setEnabled(False)
self.actions["&Alignment/Clear Constraints"].setEnabled(False)
[docs] def fixShortCuts(self):
""" Sets shortcuts that were not set by createActionsAndMenu """
self.actions["&Sequences/&Collapse All"].setShortcut(QtCore.Qt.CTRL +
QtCore.Qt.Key_Up)
self.actions["&Sequences/&Expand All"].setShortcut(QtCore.Qt.CTRL +
QtCore.Qt.Key_Down)
self.actions["&Alignment/Delete"].setShortcut(QtCore.Qt.SHIFT +
QtCore.Qt.Key_Backspace)
[docs] def createActions(self):
"""
Create Qt actions.
"""
if maestro:
self.createActionsAndMenu(MAESTRO_MENU_LIST)
else:
self.createActionsAndMenu(MENU_LIST)
self.setUpActionsDisabled()
self.setUpMenuActionsChecked()
self.fixShortCuts()
self.addColorIconsToMenu()
self.cutAct = QtWidgets.QAction(self.tr("Cu&t"), self)
self.cutAct.setShortcut(self.tr("Ctrl+X"))
self.cutAct.setStatusTip(
self.tr("Cut the current selection's contents to the clipboard"))
self.cutAct.setEnabled(False)
self.copyAct = QtWidgets.QAction(self.tr("&Copy"), self)
self.copyAct.setShortcut(self.tr("Ctrl+C"))
self.copyAct.setStatusTip(
self.tr("Copy the current selection's contents to the clipboard"))
self.copyAct.setEnabled(False)
self.pasteAct = QtWidgets.QAction(self.tr("&Paste"), self)
self.pasteAct.setShortcut(self.tr("Ctrl+V"))
self.pasteAct.setStatusTip(
self.tr("Paste the clipboard's contents into the current "
" selection"))
self.anchorAct = QtWidgets.QAction(
self.tr("Anchor Residues Outside Selection"), self)
self.anchorAct.setStatusTip(
self.tr("Preserve alignment outside of the selection"))
self.anchorAct.triggered.connect(self.viewerAnchorSelection)
self.clearAnchorsAct = QtWidgets.QAction(
QtGui.QIcon(), self.tr("Clear Restricted Region"), self)
self.clearAnchorsAct.setStatusTip(
self.tr("Clear the restricted region"))
self.clearAnchorsAct.triggered.connect(self.viewerClearAnchors)
self.lockDownstreamAct = QtWidgets.QAction(
QtGui.QIcon(":/icons/icon_lock_downstream.png"),
self.tr("&Lock Sequence Downstream"), self)
self.lockDownstreamAct.setCheckable(True)
self.lockDownstreamAct.setEnabled(True)
self.lockDownstreamAct.setStatusTip(
self.tr("Toggle Downstream Sequence Locking"))
self.lockDownstreamAct.triggered.connect(
self.viewerToggleLockDownstream)
self.colorGrayscaleAct = QtWidgets.QAction(QtGui.QIcon(""),
self.tr("Grayscale"), self)
self.colorGrayscaleAct.triggered.connect(self.viewerColorGrayscale)
self.colorWhiteAct = QtWidgets.QAction(QtGui.QIcon(""),
self.tr("White"), self)
self.colorWhiteAct.triggered.connect(self.viewerColorWhite)
self.findPreviousAct = QtWidgets.QAction(
QtGui.QIcon(":/icons/icon_left_arrow.png"),
self.tr("&Previous Pattern"), self)
self.findPreviousAct.setStatusTip(
self.tr("Find Previous Pattern Occurence"))
self.findPreviousAct.triggered.connect(self.viewerFindPrevious)
self.findNextAct = QtWidgets.QAction(
QtGui.QIcon(":/icons/icon_right_arrow.png"),
self.tr("&Next Pattern"), self)
self.findNextAct.setStatusTip(self.tr("Find Next Pattern Occurence"))
self.findNextAct.triggered.connect(self.viewerFindNext)
self.fetchAct = QtWidgets.QAction(self.tr("&Fetch A Sequence"), self)
self.fetchAct.setStatusTip(
self.tr("Fetch a sequence from a local or online database"))
self.fetchAct.triggered.connect(self.viewerFetchSequence)
self.addIdentityAct = QtWidgets.QAction(self.tr("Identity"), self)
self.addIdentityAct.triggered.connect(self.viewerAddIdentityAnnotation)
self.addSimilarityAct = QtWidgets.QAction(self.tr("Similarity"), self)
self.addSimilarityAct.triggered.connect(
self.viewerAddSimilarityAnnotation)
self.colorHelixTerminatorsAct = QtWidgets.QAction(
self.tr("Helix Termination"), self)
self.colorHelixTerminatorsAct.triggered.connect(
self.viewerColorHelixTerminators)
self.selectLigandContactsAct = QtWidgets.QAction(
self.tr("&Select Ligand Contacts"), self)
self.selectLigandContactsAct.triggered.connect(
self.viewerSelectLigandContacts)
self.antibodyActionGroup = QtWidgets.QActionGroup(self)
self.antibodyActionGroup.setExclusive(True)
self.antibodyActionGroup.addAction(
self.actions["&Annotations/Antibody Numbering Scheme/Kabat"])
self.antibodyActionGroup.addAction(
self.actions["&Annotations/Antibody Numbering Scheme/Chothia"])
self.antibodyActionGroup.addAction(
self.
actions["&Annotations/Antibody Numbering Scheme/Enhanced Chothia"])
self.antibodyActionGroup.addAction(
self.actions["&Annotations/Antibody Numbering Scheme/IMGT"])
self.antibodyActionGroup.addAction(
self.actions["&Annotations/Antibody Numbering Scheme/AHo"])
self.mouseAcrossAct = QtWidgets.QAction(
self.tr("Allow Selection Across Rows"), self)
self.mouseAcrossAct.setCheckable(True)
self.mouseAcrossAct.triggered.connect(self.viewerToggleMouseAcross)
self.zoomInAct = QtWidgets.QAction(
QtGui.QIcon(":/icons/icon_zoom_in.png"), self.tr("Zoom &In"), self)
self.zoomInAct.triggered.connect(self.viewerZoomIn)
self.zoomOutAct = QtWidgets.QAction(
QtGui.QIcon(":/icons/icon_zoom_out.png"), self.tr("Zoom &Out"),
self)
self.zoomOutAct.triggered.connect(self.viewerZoomOut)
self.treeSwapBranchesAct = QtWidgets.QAction(self.tr("&Swap Branches"),
self)
self.treeSwapBranchesAct.triggered.connect(self.treeSwapBranches)
self.treeSelectSequencesAct = QtWidgets.QAction(
self.tr("&Select Sequences"), self)
self.treeSelectSequencesAct.triggered.connect(self.treeSelectSequences)
self.treeHideBranchesAct = QtWidgets.QAction(self.tr("&Hide Branch"),
self)
self.treeHideBranchesAct.triggered.connect(self.treeHideBranches)
self.maestroAlignStructuresAct = QtWidgets.QAction(
QtGui.QIcon(""), self.tr("Structure Alignment"), self)
self.maestroAlignStructuresAct.triggered.connect(
self.viewerSynchronizeWithMaestro)
self.propagateColorsToMaestroAct = QtWidgets.QAction(
QtGui.QIcon(""), self.tr("Apply to Maestro Workspace"), self)
self.propagateColorsToMaestroAct.triggered.connect(
self.viewerPropagateColors)
self.setAsReferenceAct = QtWidgets.QAction(
QtGui.QIcon(""), self.tr("Set as Query Sequence"), self)
self.setAsReferenceAct.triggered.connect(self.viewerSetAsReference)
self.alwaysAskAnswer = QtWidgets.QAction(self)
self.alwaysAskAnswer.setCheckable(True)
self.alwaysAskAnswer.setChecked(True)
self.helpAct = QtWidgets.QAction(
QtGui.QIcon(""), self.tr("Multiple Sequence Viewer Help"), self)
self.helpAct.triggered.connect(self.viewerHelp)
self.renameSequenceAct = QtWidgets.QAction(QtGui.QIcon(""),
self.tr("Rename Sequence"),
self)
self.renameSequenceAct.triggered.connect(self.viewerRenameSequence)
# Font size actions.
self.fontActionGroup = QtWidgets.QActionGroup(self)
self.fontActionGroup.setExclusive(True)
self.fontActionGroup.triggered.connect(self.viewerSetFontSize)
self.connectFontActions()
# Connect splitter moved event.
self.sequence_viewer.splitterMoved.connect(self.viewerSplitterMoved)
self.translateAct = QtWidgets.QAction(
QtGui.QIcon(""), self.tr("Translate DNA / RNA Sequence"), self)
self.translateAct.triggered.connect(self.viewerTranslate)
[docs] def connectFontActions(self):
font_sizes = [4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24]
for size in font_sizes:
path = "/".join(["Sett&ings/&Font Size", str(size)])
self.actions[path].setActionGroup(self.fontActionGroup)
[docs] def viewerSetFontSize(self, action):
"""
Set font size action callback.
:type action: QAction
:param action: Qt action
"""
font_size = int(action.text())
self.sequence_viewer.updateFontSize(font_size)
path = "/".join(["Sett&ings/&Font Size", str(font_size)])
self.actions[path].setChecked(True)
self.sequence_viewer.generateRows()
self.sequence_viewer.repaint()
[docs] def createStatusBar(self):
"""
Creates a status bar.
"""
self.status_bar_message = QtWidgets.QLabel("Ready")
self.statusBar().addPermanentWidget(self.status_bar_message, 2)
self.sequence_viewer.message_status_bar = self.status_bar_message
self.sequence_viewer.statistics_status_bar = QtWidgets.QLabel(
"0 sequences total, 0 selected, 0 hidden.")
self.sequence_viewer.statistics_status_bar.setAlignment(
QtCore.Qt.AlignRight)
self.statusBar().addPermanentWidget(
self.sequence_viewer.statistics_status_bar, 2)
self.statusBar().messageChanged[str].connect(
self.statusBarMessageChanged)
[docs] def statusBarMessageChanged(self, message):
if message == "":
message = "Ready"
self.status_bar_message.setText(message)
[docs] def readSettings(self, settings):
"""
Reads sequence viewer user settings.
"""
pos = settings.value("pos", QtCore.QPoint(100, 100), type=QtCore.QPoint)
size = settings.value("size", QtCore.QSize(800, 350), type=QtCore.QSize)
# Apply size and position settings
self.resize(size)
self.move(pos)
tree_width = settings.value("viewer_tree_width", 50, type=int)
ann_width = settings.value("viewer_ann_width", 100, type=int)
seq_width = settings.value("viewer_seq_width", 500, type=int)
self.sequence_viewer.setSizes([tree_width, ann_width, seq_width])
try:
size = settings.value("viewer_font_size", 12, type=int)
path = "/".join(["Sett&ings/&Font Size", str(size)])
self.actions[path].setChecked(True)
self.sequence_viewer.updateFontSize(size)
except ValueError:
pass
mode = settings.value("viewer_mode", 0, type=int)
mode_to_index = {
constants.MODE_SELECT_ONLY: 0,
constants.MODE_SELECT_AND_SLIDE: 1,
constants.MODE_GRAB_AND_DRAG: 2,
constants.MODE_EDIT: 3,
constants.MODE_INSERT_GAPS: 4
}
self.modeComboBox.setCurrentIndex(mode_to_index[mode])
self.sequence_viewer.mode = mode
color = settings.value("viewer_custom_color",
(255 << 16) + (255 << 8) + 255,
type=int)
self.sequence_viewer.sequence_group.custom_color = \
((color >> 16) & 255, (color >> 8) & 255, color & 255)
color = settings.value("viewer_background_color",
(255 << 16) + (255 << 8) + 255,
type=int)
self.sequence_viewer.setBackgroundColor(
((color >> 16) & 255, (color >> 8) & 255, color & 255))
index = settings.value("viewer_color_mode",
constants.COLOR_SIDECHAIN_CHEMISTRY,
type=int)
if index == constants.COLOR_MAESTRO and not maestro:
index = constants.COLOR_SIDECHAIN_CHEMISTRY
self.sequence_viewer.sequence_group.color_mode = index
wrapped = settings.value("viewer_wrapped",
self.sequence_viewer.wrapped,
type=bool)
self.sequence_viewer.setWrapped(wrapped)
self.actions["Sett&ings/&Wrap Sequences"].setChecked(wrapped)
self.mouseAcrossAct.setEnabled(wrapped)
auto_color = settings.value("viewer_auto_color",
self.sequence_viewer.auto_color,
type=bool)
self.sequence_viewer.auto_color = auto_color
self.actions["Color/Adjust Text Contrast"].setChecked(auto_color)
padded = settings.value("viewer_padded",
self.sequence_viewer.padded,
type=bool)
self.sequence_viewer.setPadded(padded)
self.actions["Sett&ings/&Pad Alignment with Gaps"].setChecked(padded)
tooltips = settings.value("viewer_tooltips",
self.sequence_viewer.has_tooltips,
type=bool)
self.actions["Sett&ings/&Display Alignment Tooltips"].setChecked(
tooltips)
self.sequence_viewer.setHasTooltips(tooltips)
ruler = settings.value("viewer_ruler",
self.sequence_viewer.has_ruler,
type=bool)
self.actions["Sett&ings/&Display Ruler"].setChecked(ruler)
self.sequence_viewer.setHasRuler(ruler)
lock = settings.value("viewer_lock",
self.sequence_viewer.lock_downstream,
type=bool)
self.lockDownstreamAct.setChecked(lock)
self.sequence_viewer.lock_downstream = lock
boundaries = settings.value("viewer_boundaries",
self.sequence_viewer.display_boundaries,
type=bool)
self.actions["Sett&ings/&Display Sequence Boundaries"].setChecked(
boundaries)
self.sequence_viewer.setBoundaries(boundaries)
perc_id = settings.value("viewer_percentage_identity",
self.sequence_viewer.display_identity,
type=bool)
self.actions["Sett&ings/&Display Percentage Identity"].setChecked(
perc_id)
self.sequence_viewer.setDisplayIdentity(perc_id)
perc_hom = settings.value("viewer_percentage_homology",
self.sequence_viewer.display_homology,
type=bool)
self.actions["Sett&ings/&Display Percentage Homology"].setChecked(
perc_hom)
self.sequence_viewer.setDisplayHomology(perc_hom)
perc_sim = settings.value("viewer_percentage_similarity",
self.sequence_viewer.display_similarity,
type=bool)
self.actions["Sett&ings/&Display Percentage Similarity"].setChecked(
perc_sim)
self.sequence_viewer.setDisplaySimilarity(perc_sim)
score = settings.value("viewer_score",
self.sequence_viewer.display_score,
type=bool)
self.actions["Sett&ings/&Display Score"].setChecked(score)
self.sequence_viewer.setDisplayScore(score)
mouse_across = settings.value("viewer_mouse_across",
self.sequence_viewer.use_mouse_across,
type=bool)
self.mouseAcrossAct.setChecked(mouse_across)
self.sequence_viewer.setMouseAcross(mouse_across)
use_colors = settings.value("viewer_use_colors",
self.sequence_viewer.use_colors,
type=bool)
self.actions["Color/Color Sequences"].setChecked(use_colors)
self.sequence_viewer.setUseColors(use_colors)
lock_down = settings.value("viewer_lock_downstream",
self.sequence_viewer.lock_downstream,
type=bool)
self.sequence_viewer.lock_downstream = lock_down
self.lockDownstreamAct.setChecked(lock_down)
mutate = settings.value("viewer_mutate_residues",
self.sequence_viewer.mutate,
type=bool)
self.sequence_viewer.mutate = mutate
self.actions["&Maestro/Allow Structural Changes"].setChecked(mutate)
average_columns = settings.value("viewer_average_columns",
self.sequence_viewer.average_columns,
type=bool)
self.sequence_viewer.average_columns = average_columns
self.actions["Color/&Average Colors In Columns"].setChecked(
average_columns)
weight_colors = settings.value("viewer_weight_colors",
self.sequence_viewer.weight_colors,
type=bool)
self.sequence_viewer.weight_colors = weight_colors
self.actions["Color/&Weight Colors by Alignment Quality"].setChecked(
weight_colors)
group_annotations = settings.value(
"viewer_group_annotations",
self.sequence_viewer.group_annotations,
type=bool)
self.sequence_viewer.group_annotations = group_annotations
self.actions["Sett&ings/Group Annotations by Type"].setChecked(
group_annotations)
weight_colors_by_identity = settings.value(
"viewer_weight_colors_identity",
self.sequence_viewer.weight_colors_by_identity,
type=bool)
self.sequence_viewer.weight_colors_by_identity = \
weight_colors_by_identity
self.actions["Color/Color Matching Residues Only"].setChecked(
weight_colors_by_identity)
weight_colors_by_difference = settings.value(
"viewer_weight_colors_difference",
self.sequence_viewer.weight_colors_by_difference,
type=bool)
self.sequence_viewer.weight_colors_by_difference = \
weight_colors_by_difference
self.actions["Color/Color Different Residues Only"].setChecked(
weight_colors_by_difference)
consider_gaps = settings.value("viewer_consider_gaps",
self.sequence_viewer.getConsiderGaps(),
type=bool)
self.sequence_viewer.setConsiderGaps(consider_gaps)
self.actions[
"Sett&ings/Include Gaps in Sequence Identity Calculations"].setChecked(
consider_gaps)
auto_synchronize = settings.value("viewer_auto_synchronize",
self.sequence_viewer.auto_synchronize,
type=bool)
self.sequence_viewer.auto_synchronize = auto_synchronize
self.actions["&Maestro/&Update Automatically from Maestro"].setChecked(
auto_synchronize)
auto_profile = settings.value("viewer_auto_profile",
self.sequence_viewer.auto_profile,
type=bool)
self.sequence_viewer.auto_profile = auto_profile
self.actions[
"Sett&ings/Automatically Update Sequence Profile"].setChecked(
auto_profile)
self.actions["Sett&ings/Update Sequence Profile"].setEnabled(
not auto_profile)
value = settings.value("viewer_file_import_opt_merge",
self.file_import_opt_merge.isChecked(),
type=bool)
self.file_import_opt_merge.setChecked(value)
value = settings.value("viewer_file_import_opt_translate",
self.file_import_opt_translate.isChecked(),
type=bool)
self.file_import_opt_translate.setChecked(value)
value = settings.value("viewer_file_import_opt_replace",
self.file_import_opt_replace.isChecked(),
type=bool)
self.file_import_opt_replace.setChecked(value)
value = settings.value("viewer_file_import_opt_incorporate",
self.file_import_opt_incorporate.isChecked(),
type=bool)
self.file_import_opt_incorporate.setChecked(value)
incorporate_action = "&Maestro/Include Incorporated Entries in Workspace"
do_incorporate = self.actions[incorporate_action].isChecked()
value = settings.value("viewer_file_import_opt_include",
do_incorporate,
type=bool)
self.actions[incorporate_action].setChecked(value)
value = settings.value(
"viewer_file_export_opt_save_annotations",
self.file_export_opt_save_annotations.isChecked(),
type=bool)
self.file_export_opt_save_annotations.setChecked(value)
value = settings.value("viewer_file_export_opt_selected_only",
self.file_export_opt_selected_only.isChecked(),
type=bool)
self.file_export_opt_selected_only.setChecked(value)
value = settings.value("viewer_image_export_opt_save_visible",
self.image_export_opt_save_visible.isChecked(),
type=bool)
self.image_export_opt_save_visible.setChecked(value)
ask_before_remote = "Sett&ings/Ask Before Accessing a Remote Server"
value = settings.value("viewer_ask_before_remote_access",
self.actions[ask_before_remote].isChecked(),
type=bool)
self.actions[ask_before_remote].setChecked(value)
[docs] def writeSettings(self, settings):
"""
Writes sequence viewer user settings.
"""
settings.setValue("pos", self.pos())
settings.setValue("size", self.size())
tree_width, ann_width, seq_width = self.sequence_viewer.sizes()
settings.setValue("viewer_tree_width", tree_width)
settings.setValue("viewer_ann_width", ann_width)
settings.setValue("viewer_seq_width", seq_width)
settings.setValue("viewer_mode", self.sequence_viewer.mode)
if self.sequence_viewer.sequence_group.color_mode == \
constants.COLOR_MAESTRO:
settings.setValue("viewer_color_mode",
constants.COLOR_SIDECHAIN_CHEMISTRY)
else:
settings.setValue("viewer_color_mode",
self.sequence_viewer.sequence_group.color_mode)
r, g, b = self.sequence_viewer.sequence_group.custom_color
settings.setValue("viewer_custom_color", (r << 16) + (g << 8) + b)
r = self.sequence_viewer.background_color.red()
g = self.sequence_viewer.background_color.green()
b = self.sequence_viewer.background_color.blue()
settings.setValue("viewer_background_color", (r << 16) + (g << 8) + b)
settings.setValue("viewer_wrapped", self.sequence_viewer.wrapped)
settings.setValue("viewer_auto_color", self.sequence_viewer.auto_color)
settings.setValue("viewer_padded", self.sequence_viewer.padded)
settings.setValue("viewer_tooltips", self.sequence_viewer.has_tooltips)
settings.setValue("viewer_ruler", self.sequence_viewer.has_ruler)
settings.setValue("viewer_lock_downstream",
self.sequence_viewer.lock_downstream)
settings.setValue("viewer_average_columns",
self.sequence_viewer.average_columns)
settings.setValue("viewer_weight_colors",
self.sequence_viewer.weight_colors)
settings.setValue("viewer_weight_colors_identity",
self.sequence_viewer.weight_colors_by_identity)
settings.setValue("viewer_mouse_across",
self.sequence_viewer.use_mouse_across)
settings.setValue("viewer_use_colors", self.sequence_viewer.use_colors)
settings.setValue("viewer_font_size", self.sequence_viewer.font_size)
settings.setValue("viewer_mutate_residues", self.sequence_viewer.mutate)
settings.setValue("viewer_boundaries",
self.sequence_viewer.display_boundaries)
settings.setValue("viewer_percentage_identity",
self.sequence_viewer.display_identity)
settings.setValue("viewer_percentage_similarity",
self.sequence_viewer.display_similarity)
settings.setValue("viewer_score", self.sequence_viewer.display_score)
settings.setValue("viewer_group_annotations",
self.sequence_viewer.group_annotations)
settings.setValue("viewer_lock", self.sequence_viewer.lock_downstream)
settings.setValue("viewer_consider_gaps",
self.sequence_viewer.getConsiderGaps())
settings.setValue("viewer_auto_synchronize",
self.sequence_viewer.auto_synchronize)
settings.setValue("viewer_auto_profile",
self.sequence_viewer.auto_profile)
settings.setValue("viewer_file_import_opt_merge",
self.file_import_opt_merge.isChecked())
settings.setValue("viewer_file_import_opt_translate",
self.file_import_opt_translate.isChecked())
settings.setValue("viewer_file_import_opt_replace",
self.file_import_opt_replace.isChecked())
settings.setValue("viewer_file_import_opt_incorporate",
self.file_import_opt_incorporate.isChecked())
settings.setValue(
"viewer_file_import_opt_include",
self.actions["&Maestro/Include Incorporated Entries in Workspace"].
isChecked())
settings.setValue("viewer_file_export_opt_save_annotations",
self.file_export_opt_save_annotations.isChecked())
settings.setValue("viewer_file_export_opt_selected_only",
self.file_export_opt_selected_only.isChecked())
settings.setValue("viewer_image_export_opt_save_visible",
self.image_export_opt_save_visible.isChecked())
settings.setValue(
"viewer_ask_before_remote_access",
self.actions["Sett&ings/Ask Before Accessing a Remote Server"].
isChecked())
settings.sync()
[docs] def viewerModeChanged(self, value):
"""
Mode changed action callback.
:type value: int
:param value: Sequence viewer mode, same as Mode combo box item index.
"""
index_to_mode = {
0: constants.MODE_SELECT_ONLY,
1: constants.MODE_SELECT_AND_SLIDE,
2: constants.MODE_GRAB_AND_DRAG,
3: constants.MODE_EDIT,
4: constants.MODE_INSERT_GAPS
}
self.sequence_viewer.setMode(index_to_mode[value])
[docs] def viewerTranslate(self):
""" Translates DNA / RNA sequence to amino acids. """
self.sequence_viewer.translate()
[docs] def viewerWrapSequences(self):
""" Toggle wrap sequences action callback. """
self.sequence_viewer.setWrapped(not self.sequence_viewer.wrapped)
if self.sequence_viewer.wrapped:
self.mouseAcrossAct.setEnabled(True)
else:
self.mouseAcrossAct.setEnabled(False)
[docs] def viewerToggleMouseAcross(self):
""" Toggle mouse across rows action callback. """
self.sequence_viewer.setMouseAcross(
not self.sequence_viewer.use_mouse_across)
[docs] def viewerToggleIdentityInColumns(self):
""" Toggle mouse across rows action callback. """
self.sequence_viewer.setIdentityInColumns(self.actions[
"Sett&ings/Calculate Sequence Identity Only in Selected Columns"].
isChecked())
[docs] def viewerToggleColors(self):
""" Toggle mouse across rows action callback. """
self.sequence_viewer.setUseColors(not self.sequence_viewer.use_colors)
[docs] def viewerPadAlignment(self):
""" Pad alignment action callback. """
self.sequence_viewer.setPadded(not self.sequence_viewer.padded)
[docs] def viewerHideEmptyLines(self):
""" Hide empty lines action callback. """
self.sequence_viewer.hide_empty_lines = \
self.actions["Sett&ings/Hide Empty Lines"].isChecked()
self.sequence_viewer.updateView()
[docs] def viewerHideSelected(self):
""" Hide selected sequences action callback. """
self.sequence_viewer.hideSelectedSequences()
[docs] def viewerDeleteSelected(self):
""" Delete selected sequences action callback. """
all = self.sequence_viewer.deleteSelectedSequences()
if all:
self.setWindowTitle("Multiple Sequence Viewer")
[docs] def viewerShowAll(self):
""" Show all sequences action callback. """
self.sequence_viewer.showAllSequences()
[docs] def viewerFillGaps(self):
""" Fill gaps action callback. """
self.sequence_viewer.fillGaps()
[docs] def viewerRemoveGaps(self):
""" Remove gaps action callback. """
self.sequence_viewer.removeGaps()
[docs] def viewerDeleteSelectedResidues(self):
""" Delete selected residues action callback. """
self.sequence_viewer.deleteSelectedResidues()
[docs] def viewerMinimizeAlignment(self):
""" Minimize alignment action callback. """
self.sequence_viewer.minimizeAlignment()
[docs] def viewerToggleRuler(self):
""" Toggle ruler action callback. """
self.sequence_viewer.setHasRuler(not self.sequence_viewer.has_ruler)
[docs] def viewerToggleDisplayIdentity(self):
"""
Toggle display percentage identity action callback.
"""
self.actions["Sett&ings/&Display Percentage Similarity"].setChecked(
False)
self.actions["Sett&ings/&Display Score"].setChecked(False)
self.actions["Sett&ings/&Display Percentage Homology"].setChecked(False)
self.sequence_viewer.setDisplayIdentity(
not self.sequence_viewer.display_identity)
self.sequence_viewer.setDisplaySimilarity(False)
self.sequence_viewer.setDisplayHomology(False)
self.sequence_viewer.setDisplayScore(False)
[docs] def viewerToggleDisplaySimilarity(self):
"""
Toggle display percentage similarity action callback.
"""
self.actions["Sett&ings/&Display Percentage Identity"].setChecked(False)
self.actions["Sett&ings/&Display Score"].setChecked(False)
self.actions["Sett&ings/&Display Percentage Homology"].setChecked(False)
self.sequence_viewer.setDisplaySimilarity(
not self.sequence_viewer.display_similarity)
self.sequence_viewer.setDisplayIdentity(False)
self.sequence_viewer.setDisplayHomology(False)
self.sequence_viewer.setDisplayScore(False)
[docs] def viewerToggleDisplayScore(self):
""" Toggle display score action callback. """
self.actions["Sett&ings/&Display Percentage Identity"].setChecked(False)
self.actions["Sett&ings/&Display Percentage Similarity"].setChecked(
False)
self.actions["Sett&ings/&Display Percentage Homology"].setChecked(False)
self.sequence_viewer.setDisplayScore(
not self.sequence_viewer.display_score)
self.sequence_viewer.setDisplayIdentity(False)
self.sequence_viewer.setDisplayHomology(False)
self.sequence_viewer.setDisplaySimilarity(False)
[docs] def viewerToggleDisplayHomology(self):
""" Toggle display homology action callback. """
self.actions["Sett&ings/&Display Percentage Identity"].setChecked(False)
self.actions["Sett&ings/&Display Percentage Similarity"].setChecked(
False)
self.sequence_viewer.setDisplayHomology(
not self.sequence_viewer.display_homology)
self.sequence_viewer.setDisplayIdentity(False)
self.sequence_viewer.setDisplayScore(False)
self.sequence_viewer.setDisplaySimilarity(False)
[docs] def viewerToggleDisplayBoundaries(self):
""" Toggle display score action callback. """
self.sequence_viewer.setBoundaries(
not self.sequence_viewer.display_boundaries)
[docs] def viewerLockGaps(self):
""" Lock gaps action callback. """
self.sequence_viewer.lockGaps()
[docs] def viewerExpandAll(self):
""" Expand all action callback. """
self.sequence_viewer.expandAllSequences()
[docs] def viewerCollapseAll(self):
""" Collapse all action callback. """
self.sequence_viewer.collapseAllSequences()
[docs] def viewerAddAllColorBlocks(self):
""" Adds all color block annotations. """
self.sequence_viewer.addAllColorBlocks()
[docs] def viewerRemoveAllColorBlocks(self):
""" Adds all color block annotations. """
self.sequence_viewer.removeAllColorBlocks()
[docs] def viewerUnlockGaps(self):
""" Unlock gaps action callback. """
self.sequence_viewer.unlockGaps()
[docs] def viewerSelectBlocks(self):
""" Select blocks action callback. """
self.sequence_viewer.selectAlignedBlocks()
[docs] def viewerSelectStructure(self):
""" Select structure action callback. """
self.sequence_viewer.selectStructureBlocks()
[docs] def viewerSelectIdentities(self):
""" Select identities action callback. """
self.sequence_viewer.selectIdentities()
[docs] def viewerToggleLockDownstream(self):
""" Toggle lock downstream action callback. """
self.sequence_viewer.lock_downstream = \
not self.sequence_viewer.lock_downstream
[docs] def viewerRunClustal(self):
""" Run Clustal action callback. """
self.sequence_viewer.runClustal()
[docs] def viewerRunPfam(self):
""" Run Pfam action callback. """
self.sequence_viewer.runPfam()
[docs] def viewerRunSSP(self):
""" Run SSP action callback. """
if predictors.has_predictor("sspro"):
self.sequence_viewer.runPredictors(['sspro'])
else:
self.sequence_viewer.runSSP()
[docs] def viewerRunBlast(self):
""" Run Blast action callback. """
self.sequence_viewer.runBlast()
[docs] def viewerShowBlast(self):
""" Show Blast action callback. """
self.sequence_viewer.showBlastResults()
[docs] def viewerZoomIn(self):
""" Zoom in action callback. """
self.sequence_viewer.zoomIn()
[docs] def viewerZoomOut(self):
""" Zoom out action callback. """
self.sequence_viewer.zoomOut()
[docs] def viewerHelp(self):
""" Invokes MSV help. """
if maestro:
maestro.command("helptopic TOOLS_MENU_MULTIPLE_SEQUENCE_VIEWER")
[docs] def viewerAddConsensus(self):
""" Add conesensus action callback. """
self.sequence_viewer.addConsensus(toggle=True)
[docs] def viewerAddSymbols(self):
""" Add symbols action callback. """
self.sequence_viewer.addSymbols(toggle=True)
[docs] def viewerAddGlobal(self):
""" Add global annotations action callback. """
self.actions["&Annotations/Consensus Sequence"].setChecked(True)
self.actions["&Annotations/Consensus Symbols"].setChecked(True)
self.actions["&Annotations/Mean Hydrophobicity"].setChecked(True)
self.actions["&Annotations/Mean Isoelectric Point"].setChecked(True)
self.actions["&Annotations/Sequence Logo"].setChecked(True)
self.sequence_viewer.addGlobalAnnotations()
[docs] def viewerRemoveGlobal(self):
""" Add global annotations action callback. """
self.actions["&Annotations/Consensus Sequence"].setChecked(False)
self.actions["&Annotations/Consensus Symbols"].setChecked(False)
self.actions["&Annotations/Mean Hydrophobicity"].setChecked(False)
self.actions["&Annotations/Mean Isoelectric Point"].setChecked(False)
self.actions["&Annotations/Sequence Logo"].setChecked(False)
self.sequence_viewer.removeGlobalAnnotations()
[docs] def viewerAddHistory(self):
""" Add history action callback. """
self.sequence_viewer.toggleHistory()
[docs] def viewerSetAlwaysAsk(self):
self.settings.setValue(
"viewer_ask_before_remote_access",
self.actions["Sett&ings/Ask Before Accessing a Remote Server"].
isChecked())
[docs] def viewerResetHistory(self):
""" Reset history action callback. """
self.sequence_viewer.resetHistory()
[docs] def viewerAddMeanHydrophobicity(self):
""" Add mean hydrophobicity action callback. """
self.sequence_viewer.addMeanHydrophobicity(toggle=True)
[docs] def viewerAddMeanPI(self):
""" Add mean isoelectric point action callback. """
self.sequence_viewer.addMeanPI(toggle=True)
[docs] def viewerAddSequenceLogo(self):
""" Add sequence logo action callback. """
self.sequence_viewer.addSequenceLogo(toggle=True)
[docs] def viewerDeleteAnnotations(self):
""" Delete annotations action callback. """
self.actions["&Annotations/Consensus Sequence"].setChecked(False)
self.actions["&Annotations/Consensus Symbols"].setChecked(False)
self.actions["&Annotations/Sequence Logo"].setChecked(False)
self.actions["&Annotations/Mean Hydrophobicity"].setChecked(False)
self.actions["&Annotations/Mean Isoelectric Point"].setChecked(False)
self.sequence_viewer.deleteAnnotations()
[docs] def viewerDeletePredictions(self):
""" Delete predictions action callback. """
self.sequence_viewer.deletePredictions()
[docs] def viewerGroupAnnotations(self):
""" Group annotations action callback. """
self.sequence_viewer.group_annotations = \
not self.sequence_viewer.group_annotations
self.sequence_viewer.updateView()
[docs] def viewerAverageColumns(self):
""" Average columns action callback. """
self.sequence_viewer.average_columns = \
not self.sequence_viewer.average_columns
self.sequence_viewer.updateView(update_colors=True)
[docs] def viewerWeightColors(self):
""" Weight colors action callback. """
self.sequence_viewer.weight_colors = \
not self.sequence_viewer.weight_colors
self.sequence_viewer.updateView(update_colors=True)
[docs] def viewerWeightColorsIdentity(self):
""" Weight colors by identity action callback. """
self.sequence_viewer.weight_colors_by_identity = \
bool(self.actions["Color/Color Matching Residues Only"].isChecked())
if self.sequence_viewer.weight_colors_by_identity:
self.actions["Color/Color Different Residues Only"].setChecked(
False)
self.sequence_viewer.weight_colors_by_difference = False
self.sequence_viewer.updateView(update_colors=True)
[docs] def viewerWeightColorsDifference(self):
""" Weight colors by difference action callback. """
self.sequence_viewer.weight_colors_by_difference = \
bool(self.actions["Color/Color Different Residues Only"].isChecked(
))
if self.sequence_viewer.weight_colors_by_difference:
self.actions["Color/Color Matching Residues Only"].setChecked(False)
self.sequence_viewer.weight_colors_by_identity = False
self.sequence_viewer.updateView(update_colors=True)
[docs] def findTextChanged(self):
"""
Called whenever text in "Find pattern" widget has changed.
:type string: str
:param string: pattern string
"""
text = self.findLineEdit.text()
self.sequence_viewer.findPattern(str(text))
[docs] def clearPattern(self):
"""
Called whenever user clicks on 'Clear Pattern' button.
:type string: str
:param string: pattern string
"""
self.findLineEdit.setText("")
self.sequence_viewer.findPattern("")
[docs] def viewerFindPrevious(self):
""" Find previous action callback. """
self.sequence_viewer.findPrevious()
[docs] def viewerFindNext(self):
""" Find next action callback. """
self.sequence_viewer.findNext()
[docs] def viewerRenumberResidues(self):
""" Renumber residues action callback. """
self.sequence_viewer.renumberResidues()
[docs] def viewerUndo(self):
""" Undo action callback. """
undo, redo = self.sequence_viewer.undo()
[docs] def viewerRedo(self):
""" Redo action callback. """
undo, redo = self.sequence_viewer.redo()
[docs] def viewerAddSimilarityAnnotation(self):
""" Add similarity action callback. """
self.sequence_viewer.addAnnotation(constants.ANNOTATION_SIMILARITY)
[docs] def viewerAddResnumAnnotation(self):
""" Add residue number annotation. """
self.sequence_viewer.addAnnotation(
constants.ANNOTATION_RESNUM,
remove=not self.actions["&Annotations/Residue Numbers"].isChecked())
[docs] def viewerAddIdentityAnnotation(self):
""" Add identity annotation action callback. """
self.sequence_viewer.addAnnotation(constants.ANNOTATION_IDENTITY)
[docs] def viewerAddHydrophobicityAnnotation(self):
""" Add helix propensity action callback. """
self.sequence_viewer.addAnnotation(
constants.ANNOTATION_HYDROPHOBICITY,
remove=not self.actions["&Annotations/Hydrophobicity"].isChecked())
[docs] def viewerAddPIAnnotation(self):
""" Add helix propensity action callback. """
self.sequence_viewer.addAnnotation(
constants.ANNOTATION_PI,
remove=not self.actions["&Annotations/Isoelectric Point"].isChecked(
))
[docs] def viewerAddBFactorAnnotation(self):
""" Add helix propensity action callback. """
self.sequence_viewer.addAnnotation(
constants.ANNOTATION_BFACTOR,
remove=not self.actions["&Annotations/B factor"].isChecked())
[docs] def viewerAddSSBondAnnotation(self):
""" Add helix propensity action callback. """
self.sequence_viewer.addAnnotation(
constants.ANNOTATION_SSBOND,
remove=not self.actions["&Annotations/Disulfide Bonds"].isChecked())
[docs] def viewerAddHelixPropensityAnnotation(self):
""" Add helix propensity action callback. """
self.sequence_viewer.addAnnotation(
constants.ANNOTATION_HELIX_PROPENSITY,
remove=not self.
actions["&Annotations/Color Blocks/&Helix Propensity"].isChecked())
[docs] def viewerAddStrandPropensityAnnotation(self):
""" Add strand propensity action annotation callback. """
self.sequence_viewer.addAnnotation(
constants.ANNOTATION_STRAND_PROPENSITY,
remove=not self.
actions["&Annotations/Color Blocks/&Strand Propensity"].isChecked())
[docs] def viewerAddTurnPropensityAnnotation(self):
""" Add strand propensity annotation action callback. """
self.sequence_viewer.addAnnotation(
constants.ANNOTATION_TURN_PROPENSITY,
remove=not self.
actions["&Annotations/Color Blocks/&Turn Propensity"].isChecked())
[docs] def viewerAddStericGroupAnnotation(self):
""" Add steric group action annotation callback. """
self.sequence_viewer.addAnnotation(
constants.ANNOTATION_STERIC_GROUP,
remove=not self.
actions["&Annotations/Color Blocks/&Steric Propensity"].isChecked())
[docs] def viewerAddExposureTendencyAnnotation(self):
""" Add steric group action annotation callback. """
self.sequence_viewer.addAnnotation(
constants.ANNOTATION_EXPOSURE_TENDENCY,
remove=not self.
actions["&Annotations/Color Blocks/Exposure Tendency"].isChecked())
[docs] def viewerAddHelixTerminatorsAnnotation(self):
""" Add helix terminators annotation action callback. """
self.sequence_viewer.addAnnotation(
constants.ANNOTATION_HELIX_TERMINATORS,
remove=not self.
actions["&Annotations/Color Blocks/Helix Termination"].isChecked())
[docs] def viewerAddSidechainChemistryAnnotation(self):
""" Add sidechain chemistry annotation action callback. """
self.sequence_viewer.addAnnotation(
constants.ANNOTATION_SIDECHAIN_CHEMISTRY,
remove=not self.actions[
"&Annotations/Color Blocks/Side-Chain Chemistry"].isChecked())
[docs] def viewerColorHelixPropensity(self):
""" Add helix propensity action callback. """
self.sequence_viewer.setColorMode(constants.COLOR_HELIX_PROPENSITY)
[docs] def viewerColorStrandPropensity(self):
""" Add strand propensity action annotation callback. """
self.sequence_viewer.setColorMode(constants.COLOR_STRAND_PROPENSITY)
[docs] def viewerColorTurnPropensity(self):
""" Add strand propensity annotation action callback. """
self.sequence_viewer.setColorMode(constants.COLOR_TURN_PROPENSITY)
[docs] def viewerColorStericGroup(self):
""" Add steric group action annotation callback. """
self.sequence_viewer.setColorMode(constants.COLOR_STERIC_GROUP)
[docs] def viewerColorExposureTendency(self):
""" Add steric group action annotation callback. """
self.sequence_viewer.setColorMode(constants.COLOR_EXPOSURE_TENDENCY)
[docs] def viewerColorHelixTerminators(self):
""" Add helix terminators annotation action callback. """
self.sequence_viewer.setColorMode(constants.COLOR_HELIX_TERMINATORS)
[docs] def viewerColorSidechainChemistry(self):
""" Add sidechain chemistry annotation action callback. """
self.sequence_viewer.setColorMode(constants.COLOR_SIDECHAIN_CHEMISTRY)
[docs] def viewerAnchorSelection(self):
self.sequence_viewer.anchorSelection()
[docs] def viewerClearAnchors(self):
self.sequence_viewer.clearAnchors()
[docs] def sortByName(self):
""" Sort by name action callback. """
self.sequence_viewer.sequence_group.sort(constants.SORT_NAME)
self.sequence_viewer.updateView()
[docs] def sortByChain(self):
""" Sort by chain ID action callback. """
self.sequence_viewer.sequence_group.sort(constants.SORT_CHAIN)
self.sequence_viewer.updateView()
[docs] def sortByLength(self):
""" Sort by length action callback. """
self.sequence_viewer.sequence_group.sort(constants.SORT_LENGTH)
self.sequence_viewer.updateView()
[docs] def sortByGaps(self):
""" Sort by gaps action callback. """
self.sequence_viewer.sequence_group.sort(constants.SORT_GAPS)
self.sequence_viewer.updateView()
[docs] def sortByIdentity(self):
""" Sort by identity action callback. """
self.sequence_viewer.sequence_group.sort(constants.SORT_IDENTITY)
self.sequence_viewer.updateView()
[docs] def sortBySimilarity(self):
""" Sort by similarity action callback. """
self.sequence_viewer.sequence_group.sort(constants.SORT_SIMILARITY)
self.sequence_viewer.updateView()
[docs] def sortByHomology(self):
""" Sort by similarity action callback. """
self.sequence_viewer.sequence_group.sort(constants.SORT_HOMOLOGY)
self.sequence_viewer.updateView()
[docs] def sortByScore(self):
""" Sort by score action callback. """
self.sequence_viewer.sequence_group.sort(constants.SORT_SCORE)
self.sequence_viewer.updateView()
[docs] def sortByNameReverse(self):
""" Reverse sort by name action callback. """
self.sequence_viewer.sequence_group.sort(constants.SORT_NAME,
reverse_order=True)
self.sequence_viewer.updateView()
[docs] def sortByChainReverse(self):
""" Reverse sort by name action callback. """
self.sequence_viewer.sequence_group.sort(constants.SORT_CHAIN,
reverse_order=True)
self.sequence_viewer.updateView()
[docs] def sortByLengthReverse(self):
""" Reverse sort by length action callback. """
self.sequence_viewer.sequence_group.sort(constants.SORT_LENGTH,
reverse_order=True)
self.sequence_viewer.updateView()
[docs] def sortByGapsReverse(self):
""" Reverse sort by gaps action callback. """
self.sequence_viewer.sequence_group.sort(constants.SORT_GAPS,
reverse_order=True)
self.sequence_viewer.updateView()
[docs] def sortByIdentityReverse(self):
""" Reverse sort by identity action callback. """
self.sequence_viewer.sequence_group.sort(constants.SORT_IDENTITY,
reverse_order=True)
self.sequence_viewer.updateView()
[docs] def sortBySimilarityReverse(self):
""" Reverse sort by identity action callback. """
self.sequence_viewer.sequence_group.sort(constants.SORT_SIMILARITY,
reverse_order=True)
self.sequence_viewer.updateView()
[docs] def sortByHomologyReverse(self):
""" Reverse sort by identity action callback. """
self.sequence_viewer.sequence_group.sort(constants.SORT_HOMOLOGY,
reverse_order=True)
self.sequence_viewer.updateView()
[docs] def sortByScoreReverse(self):
""" Reverse sort by identity action callback. """
self.sequence_viewer.sequence_group.sort(constants.SORT_SCORE,
reverse_order=True)
self.sequence_viewer.updateView()
[docs] def treeSwapBranches(self):
""" Swap tree branches action callback. """
self.sequence_viewer.tree_area.swapBranches()
[docs] def treeHideBranches(self):
""" Hide tree branches action callback. """
self.sequence_viewer.tree_area.hideSequences()
[docs] def treeSelectSequences(self):
""" Select tree branches action callback. """
self.sequence_viewer.tree_area.selectSequences()
[docs] def sortByTreeOrder(self):
""" Sort by tree order action callback. """
if self.actions["&Sequences/Sort by &Tree Order"].isChecked():
sizes_list = self.sequence_viewer.sizes()
sizes_list[0] = 200
self.sequence_viewer.setSizes(sizes_list)
self.menus["&Sequences/Sort &Ascending"].setEnabled(False)
self.menus["&Sequences/Sort &Descending"].setEnabled(False)
self.actions["&Sequences/&Move to Top"].setEnabled(False)
self.actions["&Sequences/&Move Down"].setEnabled(False)
self.actions["&Sequences/&Move to Top"].setEnabled(False)
self.actions["&Sequences/&Move to Bottom"].setEnabled(False)
self.sequence_viewer.sequence_group.sortByTreeOrder()
self.sequence_viewer.updateView()
else:
sizes_list = self.sequence_viewer.sizes()
sizes_list[0] = 0
self.sequence_viewer.setSizes(sizes_list)
self.menus["&Sequences/Sort &Ascending"].setEnabled(True)
self.menus["&Sequences/Sort &Descending"].setEnabled(True)
self.actions["&Sequences/&Move to Top"].setEnabled(True)
self.actions["&Sequences/&Move Down"].setEnabled(True)
self.actions["&Sequences/&Move to Top"].setEnabled(True)
self.actions["&Sequences/&Move to Bottom"].setEnabled(True)
[docs] def viewerSplitterMoved(self, pos, index):
"""
Splitter moved action callback.
:type pos: int
:param pos: new splitter position
:type index: int
:param index: splitter index
"""
if index == 1:
if pos == 1:
self.menus["&Sequences/Sort &Ascending"].setEnabled(True)
self.menus["&Sequences/Sort &Descending"].setEnabled(True)
self.actions["&Sequences/&Move to Top"].setEnabled(True)
self.actions["&Sequences/&Move Down"].setEnabled(True)
self.actions["&Sequences/&Move to Top"].setEnabled(True)
self.actions["&Sequences/&Move to Bottom"].setEnabled(True)
self.actions["&Sequences/Sort by &Tree Order"].setChecked(False)
else:
self.menus["&Sequences/Sort &Ascending"].setEnabled(False)
self.menus["&Sequences/Sort &Descending"].setEnabled(False)
self.actions["&Sequences/&Move to Top"].setEnabled(False)
self.actions["&Sequences/&Move Down"].setEnabled(False)
self.actions["&Sequences/&Move to Top"].setEnabled(False)
self.actions["&Sequences/&Move to Bottom"].setEnabled(False)
self.actions["&Sequences/Sort by &Tree Order"].setChecked(True)
[docs] def viewerFetchSequence(self):
""" Fetch sequence action callback. """
entry_id = self.fetchLineEdit.text()
self.sequence_viewer.fetchSequence(
str(entry_id),
maestro_include=self.
actions["&Maestro/Include Incorporated Entries in Workspace"].
isChecked(),
maestro_incorporate=self.file_import_opt_incorporate.isChecked())
[docs] def viewerEditSequence(self):
""" Edits a sequence as a text. """
self.sequence_viewer.editSequence()
[docs] def viewerCreateSequence(self):
""" Creates a new sequence. """
self.sequence_viewer.createSequence()
[docs] def viewerMoveUp(self):
""" Move sequences up action callback. """
self.sequence_viewer.moveUp()
[docs] def viewerMoveDown(self):
""" Move sequences down action callback. """
self.sequence_viewer.moveDown()
[docs] def viewerMoveTop(self):
""" Move sequences up action callback. """
self.sequence_viewer.moveTop()
[docs] def viewerMoveBottom(self):
""" Move sequences down action callback. """
self.sequence_viewer.moveBottom()
[docs] def viewerInvertSelection(self):
""" Invert residue selection range action callback. """
self.sequence_viewer.invertSelection()
[docs] def viewerSelectAll(self):
""" Select all residues action callback. """
self.sequence_viewer.selectAll()
[docs] def viewerDeselectAll(self):
""" Deselect all residues action callback. """
self.sequence_viewer.deselectAll()
[docs] def viewerSynchronizeWithMaestro(self):
""" Synchronize with Maestro action callback. """
self.sequence_viewer.synchronizeWithMaestro()
[docs] def viewerPassSelectionToMaestro(self):
self.sequence_viewer.passSelectionToMaestro()
[docs] def viewerAutoSynchronizeWithMaestro(self):
""" Synchronize with Maestro action callback. """
self.sequence_viewer.auto_synchronize = \
not self.sequence_viewer.auto_synchronize
if self.sequence_viewer.auto_synchronize:
self.sequence_viewer.synchronizeWithMaestro()
[docs] def viewerComputeSequenceProfile(self):
""" Synchronize with Maestro action callback. """
self.sequence_viewer.computeSequenceProfile()
[docs] def viewerAutoComputeSequenceProfile(self):
""" Synchronize with Maestro action callback. """
self.sequence_viewer.auto_profile = \
not self.sequence_viewer.auto_profile
if self.sequence_viewer.auto_profile:
self.sequence_viewer.computeSequenceProfile()
self.actions["Sett&ings/Update Sequence Profile"].setEnabled(False)
else:
self.actions["Sett&ings/Update Sequence Profile"].setEnabled(True)
[docs] def viewerMutateWhileTyping(self):
""" Mutate sequence while typing action callback. """
self.sequence_viewer.mutate = not self.sequence_viewer.mutate
[docs] def viewerRemoveRedundancy(self):
self.sequence_viewer.removeRedundancy()
[docs] def viewerDuplicate(self):
""" Duplicates currently selected sequences. """
self.sequence_viewer.duplicateSequences()
[docs] def viewerPairwiseAlignment(self):
self.sequence_viewer.pairwiseAlignment()
[docs] def viewerAlignMerge(self):
self.sequence_viewer.alignMerge()
[docs] def viewerAlignByResidueNumbers(self):
self.sequence_viewer.alignByResidueNumbers()
[docs] def viewerRenumberToAntibody(self):
scheme = 'Chothia'
if self.actions[
"&Annotations/Antibody Numbering Scheme/Enhanced Chothia"].isChecked(
):
scheme = 'EnhancedChothia'
elif self.actions[
"&Annotations/Antibody Numbering Scheme/Kabat"].isChecked():
scheme = 'Kabat'
elif self.actions[
"&Annotations/Antibody Numbering Scheme/IMGT"].isChecked():
scheme = 'IMGT'
elif self.actions[
"&Annotations/Antibody Numbering Scheme/AHo"].isChecked():
scheme = 'AHo'
self.sequence_viewer.assignAntibodyScheme(
scheme=scheme,
remove=not self.actions["&Annotations/&Antibody CDRs"].isChecked())
[docs] def viewerSelectAntibodyRegions(self):
scheme = 'Chothia'
if self.actions[
"&Annotations/Antibody Numbering Scheme/Enhanced Chothia"].isChecked(
):
scheme = 'EnhancedChothia'
elif self.actions[
"&Annotations/Antibody Numbering Scheme/Kabat"].isChecked():
scheme = 'Kabat'
elif self.actions[
"&Annotations/Antibody Numbering Scheme/IMGT"].isChecked():
scheme = 'IMGT'
elif self.actions[
"&Annotations/Antibody Numbering Scheme/AHo"].isChecked():
scheme = 'AHo'
self.sequence_viewer.assignAntibodyScheme(remove=False,
renumber=False,
renumber_entry=False,
annotate=False,
select=True,
scheme=scheme)
[docs] def viewerSetAsReference(self):
self.sequence_viewer.setAsReference()
[docs] def viewerSelectAllSequences(self):
self.sequence_viewer.selectAllSequences()
[docs] def viewerUnselectAllSequences(self):
self.sequence_viewer.unselectAllSequences()
[docs] def viewerInvertSequenceSelection(self):
self.sequence_viewer.invertSequenceSelection()
[docs] def viewerPasteFasta(self):
self.sequence_viewer.pasteFasta()
[docs] def viewerColorResidueType(self):
self.sequence_viewer.setColorMode(constants.COLOR_RESIDUE_TYPE)
[docs] def viewerColorSecondary(self):
self.sequence_viewer.setColorMode(constants.COLOR_SECONDARY)
[docs] def viewerColorBfactor(self):
self.sequence_viewer.setColorMode(constants.COLOR_BFACTOR)
[docs] def viewerColorPosition(self):
self.sequence_viewer.setColorMode(constants.COLOR_POSITION)
[docs] def viewerToggleUseDots(self):
self.sequence_viewer.display_dots = not self.sequence_viewer.display_dots
self.sequence_viewer.updateView()
[docs] def viewerToggleAutoColor(self):
self.sequence_viewer.auto_color = not self.sequence_viewer.auto_color
self.sequence_viewer.updateView()
[docs] def viewerColorSimilarity(self):
self.sequence_viewer.setColorMode(constants.COLOR_SIMILARITY)
[docs] def viewerColorKyteDoolittle(self):
self.sequence_viewer.setColorMode(constants.COLOR_KYTE_DOOLITTLE)
[docs] def viewerColorHoppWoods(self):
self.sequence_viewer.setColorMode(constants.COLOR_HOPP_WOODS)
[docs] def viewerColorGrayscale(self):
self.sequence_viewer.setColorMode(constants.COLOR_BLACK)
[docs] def viewerColorWhite(self):
self.sequence_viewer.setColorMode(constants.COLOR_WHITE)
[docs] def viewerColorTaylor(self):
self.sequence_viewer.setColorMode(constants.COLOR_TAYLOR)
[docs] def viewerColorMaestro(self):
maestro_helpers.synchronizePropertiesWithMaestro(self.sequence_viewer,
colors=True,
selection=False)
self.sequence_viewer.setColorMode(constants.COLOR_MAESTRO)
[docs] def viewerPropagateColors(self):
""" Propagates colors to Maestro workspace. """
self.sequence_viewer.propagateColors()
[docs] def viewerConsiderGaps(self):
self.sequence_viewer.setConsiderGaps(
not self.sequence_viewer.getConsiderGaps())
[docs] def viewerClearConstraints(self):
self.sequence_viewer.clearConstraints()
[docs] def viewerSetConstraints(self):
result = self.sequence_viewer.toggleConstraints()
self.actions["&Alignment/Clear Constraints"].setEnabled(result)
self.actions["&Alignment/Use Constraints"].setChecked(result)
[docs] def viewerAddSSA(self):
if self.actions[
"&Annotations/Secondary Structure Assignment"].isChecked():
self.sequence_viewer.sequence_group.updateSSA()
else:
self.sequence_viewer.sequence_group.updateSSA(remove=True)
[docs] def viewerRunACCpro(self):
""" Run solvent accessibility prediction. """
self.sequence_viewer.runPredictors(['accpro'])
[docs] def viewerRunDOMpro(self):
""" Run domain arrangement prediction. """
self.sequence_viewer.runPredictors(['dompro'])
[docs] def viewerRunDISpro(self):
""" Run disordered region prediction. """
self.sequence_viewer.runPredictors(['dispro'])
[docs] def viewerRunDIpro(self):
""" Run disulfide bridges prediction. """
self.sequence_viewer.runPredictors(['dipro'])
[docs] def viewerRunBETApro(self):
""" Run beta sheet prediction. """
self.sequence_viewer.runPredictors(['betapro'])
[docs] def viewerRunAllPredictions(self):
self.sequence_viewer.runPredictors(
["sspro", "accpro", "dispro", "dompro", "dipro"])
[docs] def viewerExpandSelection(self):
self.sequence_viewer.expandSelection()
[docs] def viewerHideColumns(self):
self.sequence_viewer.hideColumns()
[docs] def viewerHideUnselectedColumns(self):
self.sequence_viewer.hideColumns(unselected=True)
[docs] def viewerShowColumns(self):
self.sequence_viewer.showColumns()
[docs] def viewerExpandSelectionRef(self):
self.sequence_viewer.expandSelectionRef()
[docs] def viewerMarkColorCustom(self):
color = QtWidgets.QColorDialog.getColor()
if color:
color = (color.red(), color.green(), color.blue())
self.sequence_viewer.markResidues(color)
[docs] def viewerBackgroundColorCustom(self):
color = QtWidgets.QColorDialog.getColor()
if color:
color = (color.red(), color.green(), color.blue())
self.sequence_viewer.setBackgroundColor(color)
[docs] def viewerConstantColorCustom(self):
color = QtWidgets.QColorDialog.getColor()
if color:
color = (color.red(), color.green(), color.blue())
self.sequence_viewer.colorSequences(color)
[docs] def viewerMaestroSuperposition(self):
"""
Superposes structures in Maestro workspace according to the
current alignment.
"""
if maestro:
maestro_helpers.maestroSuperposition(self.sequence_viewer)
[docs] def viewerAlignmentSettings(self):
""" Displays alignment setting dialog. """
self.sequence_viewer.alignmentSettingsDialog()
[docs] def viewerDownloadPDB(self):
""" Downloads a corresponding PDB structure. """
self.sequence_viewer.downloadPDB(
maestro_include=self.
actions["&Maestro/Include Incorporated Entries in Workspace"].
isChecked(),
maestro_incorporate=self.file_import_opt_incorporate.isChecked())
[docs] def viewerMarkResidues(self):
color_actions = {
"Red": (255, 32, 32),
"Green": (32, 255, 32),
"Blue": (32, 32, 255),
"Cyan": (32, 255, 255),
"Magenta": (255, 32, 255),
"Yellow": (255, 255, 32),
"Orange": (255, 127, 32),
"Teal": (32, 127, 127),
"Black": (0, 0, 0),
"Dark Gray": (63, 63, 63),
"Light Gray": (191, 191, 191),
"White": (255, 255, 255)
}
action = QtCore.QObject.sender(self)
if action:
color = action.text()
rgb = color_actions[str(color)]
self.sequence_viewer.markResidues(rgb)
[docs] def viewerBackgroundColor(self):
rgb_values = {
"Black": (0, 0, 0),
"Dark Gray": (63, 63, 63),
"Light Gray": (191, 191, 191),
"White": (255, 255, 255)
}
action = QtCore.QObject.sender(self)
if action:
color = action.text()
rgb = rgb_values[str(color)]
self.sequence_viewer.setBackgroundColor(rgb)
[docs] def viewerColorResidues(self):
color_actions = {
"Red": (255, 32, 32),
"Green": (32, 255, 32),
"Blue": (32, 32, 255),
"Cyan": (32, 255, 255),
"Magenta": (255, 32, 255),
"Yellow": (255, 255, 32),
"Orange": (255, 127, 32),
"Teal": (32, 127, 127),
"Black": (0, 0, 0),
"Dark Gray": (63, 63, 63),
"Light Gray": (191, 191, 191),
"White": (255, 255, 255)
}
action = QtCore.QObject.sender(self)
if action:
color = action.text()
rgb = color_actions[str(color)]
self.sequence_viewer.colorSequences(rgb)
[docs] def viewerClearMarkedResidues(self):
self.sequence_viewer.clearMarkedResidues()
[docs] def viewerShowJobLog(self):
""" Shows job log window. """
self.sequence_viewer.showJobLog()
[docs] def viewerShowJobSettings(self):
""" Shows job settings window. """
self.sequence_viewer.showJobSettings()
[docs] def viewerBuildModel(self):
""" Builds a 3D model of the reference sequence. """
self.sequence_viewer.buildModel()
[docs] def connectNoSlot(self):
""" Hacker fix to not connecting
"Include Incorporated Entries in Workspace" to anything"""
[docs] def viewerColorEntrySurface(self):
self.sequence_viewer.colorEntrySurface()
[docs] def viewerAssociateMaestroEntries(self):
self.sequence_viewer.associateMaestroEntries()
[docs] def viewerAlignStructures(self):
""" Aligns 3D protein structures. """
self.sequence_viewer.alignStructures()
[docs] def viewerGetStructureAlignment(self):
""" Aligns 3D protein structures. """
self.sequence_viewer.getStructureAlignment()
[docs] def viewerCropSelectedResidues(self):
""" Crops the residues in the selected area. """
self.sequence_viewer.cropSelectedResidues()
[docs] def viewerShowLigands(self):
""" Displays Maestro ligand interaction fingerprints. """
remove = not self.actions["&Annotations/Ligand Contacts"].isChecked()
self.sequence_viewer.addAnnotation(constants.ANNOTATION_LIGAND,
remove=remove)
if not remove:
self.sequence_viewer.displayLigands()
[docs] def viewerFindPattern(self):
""" Switch focus to Find Pattern input box. """
self.findToolBar.show()
self.findLineEdit.setFocus()
[docs] def viewerNewSet(self):
self.sequence_viewer.excludeQueryEntries()
set_name = self.sequence_viewer.newSet()
self.query_tabs.insertTab(self.query_tabs.count(), set_name)
self.query_tabs.setCurrentIndex(self.query_tabs.count() - 1)
return set_name
[docs] def viewerDuplicateSet(self):
self.queryDuplicate()
[docs] def addNewQueryTab(self, open_file=True):
""" Adds a new query tab. """
self.viewerNewSet()
if open_file:
self.open()
[docs] def queryTabChanged(self, index):
if self.ignore_tab_change:
self.ignore_tab_change = False
return
self.sequence_viewer.excludeQueryEntries()
self.sequence_viewer.changeQuery(index)
self.sequence_viewer.includeQueryEntries()
self.sequence_viewer.setBackgroundColor(
(self.sequence_viewer.background_color.red(),
self.sequence_viewer.background_color.green(),
self.sequence_viewer.background_color.blue()))
updatePrimeQueryList()
[docs] def queryDelete(self):
if self.picked_query >= 0:
index = self.picked_query
else:
index = self.query_tabs.currentIndex()
self.picked_query = -1
self.queryTabClose(index)
[docs] def queryTabClose(self, index):
if self.query_tabs.count() == 1:
return False
answer = dialogs.question_dialog("Deleting Query Tab",
"This operation cannot be undone.\n"
"Do you wish to continue?",
buttons=["yes", "no"])
if answer != "yes":
return False
action = QtCore.QObject.sender(self)
if action:
self.ignore_tab_change = True
self.sequence_viewer.excludeQueryEntries()
self.query_tabs.removeTab(index)
self.sequence_viewer.deleteSet(index)
self.sequence_viewer.includeQueryEntries()
self.ignore_tab_change = False
return True
return False
[docs] def queryDuplicate(self):
""" Duplicates the picked query. """
if self.picked_query >= 0:
index = self.picked_query
else:
index = self.query_tabs.currentIndex()
self.picked_query = -1
# Get the source group (pointed by the user)
group1 = self.sequence_viewer.sequence_group_list[index]
# Create new empty group
self.addNewQueryTab(open_file=False)
# Copy the contents
self.sequence_viewer.copySequences(group1)
[docs] def queryRename(self):
""" Renames the picked query. """
if self.picked_query >= 0:
index = self.picked_query
else:
index = self.query_tabs.currentIndex()
self.picked_query = -1
name, ok = dialogs.string_input_dialog("Rename Query",
"Enter new query name",
self.query_tabs.tabText(index))
if name and ok:
self.query_tabs.setTabText(index, name)
self.sequence_viewer.sequence_group.name = name
[docs] def viewerSetSequenceColor(self):
color = QtWidgets.QColorDialog.getColor()
if color:
color = (color.red(), color.green(), color.blue())
self.sequence_viewer.colorSequenceNames(color)
[docs] def viewerIncorporateSelected(self):
self.sequence_viewer.incorporateSelectedEntries()
[docs] def viewerIncorporateIncluded(self):
self.sequence_viewer.incorporateIncludedEntries()
[docs] def viewerRenameSequence(self):
self.sequence_viewer.renameSequence()
[docs] def viewerAnalyzeBindingSite(self):
self.sequence_viewer.analyzeBindingSite()
[docs] def viewerCompareSequences(self):
""" Open 'Compare sequences' dialog. """
self.sequence_viewer.showCompareSequencesDialog()
[docs] def viewerUserAddRectangle(self):
self.sequence_viewer.addUserAnnotation(annotation_type="rectangle")
[docs] def viewerUserAddAlignmentRegion(self):
self.sequence_viewer.addUserAnnotation(annotation_type="region")
[docs] def viewerUserAddCustomAnnotation(self):
self.sequence_viewer.addUserAnnotation(
annotation_type="custom_sequence")
[docs] def viewerUserRemoveAll(self):
self.sequence_viewer.removeUserAnnotations()
[docs] def viewerResetSettings(self):
""" Resets all user settings to default. """
activate_if_checked = [
"Sett&ings/&Display Percentage Similarity",
"Sett&ings/&Wrap Sequences", "Sett&ings/Group Annotations by Type",
"Sett&ings/&Display Ruler", "Sett&ings/&Display Score",
"Sett&ings/&Display Percentage Identity",
"Sett&ings/&Display Percentage Homology",
"Sett&ings/&Display Sequence Boundaries",
"Sett&ings/&Display Alignment Tooltips",
"Sett&ings/&Pad Alignment with Gaps",
"Sett&ings/&Display Header Row", "Sett&ings/&Display Header Row",
"Sett&ings/&Replace Identities With Dots",
"Sett&ings/Include Gaps in Sequence Identity Calculations",
"Sett&ings/Calculate Sequence Identity Only in Selected Columns",
"Color/&Average Colors In Columns",
"Color/&Weight Colors by Alignment Quality",
"Color/Color Matching Residues Only",
"Color/Color Different Residues Only", "Color/Color Sequences",
"Color/Adjust Text Contrast", "&Alignment/Use Constraints"
]
for action_path in activate_if_checked:
if self.actions[action_path].isChecked():
self.actions[action_path].activate(QtWidgets.QAction.Trigger)
if not self.lockDownstreamAct.isChecked():
self.lockDownstreamAct.activate(QtWidgets.QAction.Trigger)
if not self.mouseAcrossAct.isChecked():
self.mouseAcrossAct.activate(QtWidgets.QAction.Trigger)
self.actions["Sett&ings/&Font Size/10"].activate(
QtWidgets.QAction.Trigger)
# The application main loop.
# Used when the viewer is called as an standalone app and for debugging
# purposes. When invoked from Maestro, the main loop is included in
# multiseqviewer.panel function.
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
app.setAttribute(QtCore.Qt.AA_DontShowIconsInMenus)
mainWin = AlignmentWindow()
mainWin.show()
mainWin.raise_()
sys.exit(app.exec_())