Source code for schrodinger.ui.sequencealignment.associate_gui
from schrodinger.Qt import QtCore
from schrodinger.Qt import QtWidgets
from schrodinger.ui.sequencealignment import align
from schrodinger.ui.sequencealignment import sequence
from . import constants
try:
from schrodinger.maestro import maestro
except:
maestro = None
[docs]class AssociateEntryPanel(QtWidgets.QDialog):
"""
Create script panel.
"""
[docs] def __init__(self, parent):
self.sequence_viewer = parent
QtWidgets.QDialog.__init__(self, parent)
self.setWindowTitle("Associate Maestro Entries with MSV Sequences")
self.dialog_layout = QtWidgets.QVBoxLayout(self)
self.table_layout = QtWidgets.QHBoxLayout()
self.dialog_layout.addLayout(self.table_layout)
self.entry_table_layout = QtWidgets.QVBoxLayout()
self.entry_table_layout.addWidget(QtWidgets.QLabel("Entry Chains"))
self.entry_table = QtWidgets.QTableWidget()
self.entry_table = QtWidgets.QTableWidget(0, 1)
self.entry_table.setAlternatingRowColors(True)
self.entry_table.horizontalHeader().setStretchLastSection(True)
self.entry_table.horizontalHeader().hide()
self.entry_table.verticalHeader().hide()
self.entry_table.setSelectionBehavior(
QtWidgets.QAbstractItemView.SelectItems)
self.entry_table.setSelectionMode(
QtWidgets.QAbstractItemView.SingleSelection)
self.entry_table.selectionModel().selectionChanged.connect(
self.tableSelectionChanged)
self.entry_table_layout.addWidget(self.entry_table)
self.table_layout.addLayout(self.entry_table_layout)
self.sequence_table_layout = QtWidgets.QVBoxLayout()
self.sequence_table_layout.addWidget(QtWidgets.QLabel("MSV Sequences"))
self.sequence_table = QtWidgets.QTableWidget(0, 1)
self.sequence_table.setAlternatingRowColors(True)
self.sequence_table.horizontalHeader().setStretchLastSection(True)
self.sequence_table.horizontalHeader().hide()
self.sequence_table.verticalHeader().hide()
self.sequence_table.setSelectionBehavior(
QtWidgets.QAbstractItemView.SelectItems)
self.sequence_table.setSelectionMode(
QtWidgets.QAbstractItemView.SingleSelection)
self.sequence_table.selectionModel().selectionChanged.connect(
self.tableSelectionChanged)
self.sequence_table_layout.addWidget(self.sequence_table)
self.table_layout.addLayout(self.sequence_table_layout)
self.identity_label = QtWidgets.QLabel()
self.label_layout = QtWidgets.QHBoxLayout()
self.label_layout.setAlignment(QtCore.Qt.AlignCenter)
self.label_layout.addWidget(self.identity_label)
self.dialog_layout.addLayout(self.label_layout)
self.button_layout = QtWidgets.QHBoxLayout()
self.dialog_layout.addLayout(self.button_layout)
self.button_associate = QtWidgets.QPushButton(self)
self.button_associate.setText("Associate Selected Pair")
self.button_associate.setEnabled(False)
self.button_associate.setDefault(False)
self.button_associate.clicked.connect(self.associateCB)
self.button_close = QtWidgets.QPushButton(self)
self.button_close.setText("Close")
self.button_close.setDefault(True)
self.button_close.clicked.connect(self.close)
#self.button_auto = QtWidgets.QPushButton(self)
# self.button_auto.setDefault(False)
#self.button_auto.setText("Auto-associate All Pairs")
# self.button_layout.addWidget(self.button_auto)
self.button_layout.addWidget(self.button_associate)
self.button_layout.addWidget(self.button_close)
[docs] def show(self):
self.entry_table.clearContents()
for row in range(self.entry_table.rowCount()):
self.entry_table.removeRow(0)
self.sequence_table.clearContents()
for row in range(self.sequence_table.rowCount()):
self.sequence_table.removeRow(0)
self.populateEntryTable()
self.populateMSVTable()
QtWidgets.QDialog.show(self)
[docs] def tableSelectionChanged(self, new, prev):
entry_index = -1
msv_index = -1
indices = self.entry_table.selectedIndexes()
if indices:
entry_index = indices[0].row()
indices = self.sequence_table.selectedIndexes()
if indices:
msv_index = indices[0].row()
self.button_associate.setEnabled(False)
if entry_index < 0 or msv_index < 0:
return
self.button_associate.setEnabled(True)
self.alignPair(entry_index, msv_index)
[docs] def alignPair(self, entry_index, msv_index, associate=False):
entry_seq = sequence.Sequence()
entry_id, chain, entry_seq_text = self.entry_list[entry_index]
entry_seq.appendResidues(entry_seq_text)
original_msv_seq = self.msv_list[msv_index]
msv_seq = sequence.Sequence()
msv_seq.appendResidues(original_msv_seq.gaplessText())
align.align(entry_seq, msv_seq)
ids = 0
ali_len = 0
entry_text = entry_seq.text()
msv_text = msv_seq.text()
for index in range(len(entry_text)):
if entry_text[index] != '~' and msv_text[index] != '~':
if entry_text[index] == msv_text[index]:
ids += 1
ali_len += 1
id = 100.0 * float(ids) / float(ali_len)
id_label = "Sequence identity of aligned part: %.2f %%. " % id
cov = 100.0 * float(ali_len) / float(len(msv_text))
if cov > 100.0:
cov = 100.0
cov_label = "Alignment coverage: %.2f %%. " % cov
if id < 95.0:
color = "<font color=red>"
else:
color = "<font color=green>"
self.identity_label.setText(color + id_label + cov_label + "</font>")
if not associate:
return
original_msv_seq.from_maestro = True
original_msv_seq.has_structure = True
original_msv_seq.maestro_included = True
original_msv_seq.maestro_entry_id = entry_id
original_msv_seq.maestro_chain_name = chain.name
for res in original_msv_seq.residues:
res.structureless = True
msv_residues = original_msv_seq.gaplessResidues()
res_list = []
for res in chain.residue:
ca_atom = None
for atom in res.atom:
if "CA" in atom.pdbname:
ca_atom = atom
break
if not ca_atom:
continue
res_list.append(res)
res_index = 0
for index in range(len(entry_text)):
if entry_text[index] != '~':
residue = res_list[res_index]
res_index += 1
ca_atom = None
for atom in residue.atom:
if "CA" in atom.pdbname:
ca_atom = atom
break
if msv_text[index] != '~' and \
entry_text[index] == msv_text[index]:
res = msv_residues[index]
res.structureless = False
res.name = residue.pdbres[:3]
res.num = residue.resnum
res.icode = residue.inscode
if ca_atom:
res.bfactor = ca_atom.temperature_factor
res.maestro_atom_num = ca_atom.index
if ca_atom.secondary_structure == 1:
res.ss_code = 'H'
elif ca_atom.secondary_structure == 2:
res.ss_code = 'E'
else:
res.ss_code = ' '
self.sequence_viewer.contents_changed = True
self.sequence_viewer.updateView()
[docs] def populateMSVTable(self):
global msv
self.msv_list = []
group = self.sequence_viewer.sequence_group
for seq in group.sequences:
if seq.isValidProtein():
row = self.sequence_table.rowCount()
self.sequence_table.insertRow(row)
item = QtWidgets.QTableWidgetItem(seq.short_name + "_" +
seq.chain_id + " : " +
str(len(seq.gaplessText())) +
" residues")
item.setFlags(QtCore.Qt.ItemIsSelectable |
QtCore.Qt.ItemIsEnabled)
self.sequence_table.setItem(row, 0, item)
self.msv_list.append(seq)
[docs] def populateEntryTable(self):
self.entry_list = []
if not maestro:
return
pt = maestro.project_table_get()
valid_amino_acids = list(constants.AMINO_ACIDS_3_TO_1)
rows = pt.included_rows
for row_index, pt_row in enumerate(rows):
try:
st = pt_row.getStructure(props=True, copy=False)
except:
continue
for chain_index, chain in enumerate(st.chain):
is_protein = False
for residue in chain.residue:
if residue.pdbres[:3] in valid_amino_acids:
is_protein = True
break
if not is_protein:
continue
seq = ""
for res in chain.residue:
pdbname = res.pdbres[:3]
ca_atom = None
for atom in res.atom:
if "CA" in atom.pdbname:
ca_atom = atom
break
if not ca_atom:
continue
if (pdbname in valid_amino_acids):
seq += constants.AMINO_ACIDS_3_TO_1[pdbname]
else:
seq += 'X'
if not seq:
continue
title = ""
name = str(pt_row.entry_id) + " : "
if "s_m_title" in st.property:
title = st.property["s_m_title"] + "_"
if title:
name += " : " + title
name += str(chain.name)
name += " : " + str(len(seq)) + " residues"
row = self.entry_table.rowCount()
self.entry_table.insertRow(row)
item = QtWidgets.QTableWidgetItem(name)
item.setFlags(QtCore.Qt.ItemIsSelectable |
QtCore.Qt.ItemIsEnabled)
self.entry_table.setItem(row, 0, item)
self.entry_list.append((pt_row.entry_id, chain, seq))
[docs] def associateCB(self):
entry_index = -1
msv_index = -1
indices = self.entry_table.selectedIndexes()
if indices:
entry_index = indices[0].row()
indices = self.sequence_table.selectedIndexes()
if indices:
msv_index = indices[0].row()
if entry_index < 0 or msv_index < 0:
return
self.alignPair(entry_index, msv_index, associate=True)