# Copyright 2008 Nanorex, Inc. See LICENSE file for details.
"""
This is a Property Manager dialog of the Peptide Generator.
@author: Piotr, Urmi
@version: $Id$
@copyright: 2008 Nanorex, Inc. See LICENSE file for details.
History:
Piotr 2008-01-11: Implemented Peptide Generator dialog using PropMgrBaseClass
(just copied most stuff from NanotubeGeneratorPropertyManager).
Piotr 2008-03-02: Re-written the Property Manager dialogs to allow it working in
the interactive mode.
Piotr 080407: Fixed minor bugs in sequence text editor window.
Urmi 20080731: Property Manager updated to support drawing proteins by
clicking on two point
"""
import math
from PyQt4 import QtCore, QtGui
from PyQt4.Qt import SIGNAL
from PyQt4.Qt import Qt
from command_support.EditCommand_PM import EditCommand_PM
from PM.PM_GroupBox import PM_GroupBox
from PM.PM_CheckBox import PM_CheckBox
from PM.PM_ComboBox import PM_ComboBox
from PM.PM_DoubleSpinBox import PM_DoubleSpinBox
from PM.PM_SpinBox import PM_SpinBox
from PM.PM_PushButton import PM_PushButton
from PM.PM_ToolButtonGrid import PM_ToolButtonGrid
from PM.PM_TextEdit import PM_TextEdit
from PM.PM_Constants import PM_DONE_BUTTON
from PM.PM_Constants import PM_WHATS_THIS_BUTTON
from PM.PM_Constants import PM_CANCEL_BUTTON
from PM.PM_Constants import PM_PREVIEW_BUTTON
from utilities.debug import print_compact_traceback
from utilities.Log import orangemsg, greenmsg, redmsg
import foundation.env as env
from protein.model.Residue import Residue
from protein.model.Residue import SS_HELIX, SS_COIL, SS_STRAND
# list of button descriptors for PM_ToolButtonGrid
AA_BUTTON_LIST = [
( "QToolButton", 0, "Ala", "", "Alanine", "A", 0, 0 ),
( "QToolButton", 1, "Arg", "", "Arginine", "R", 1, 0 ),
( "QToolButton", 2, "Asn", "", "Asparagine", "N", 2, 0 ),
( "QToolButton", 3, "Asp", "", "Aspartic Acid", "D", 3, 0 ),
( "QToolButton", 4, "Cys", "", "Cysteine", "C", 4, 0 ),
( "QToolButton", 5, "Glu", "", "Glutamic Acid", "E", 0, 1 ),
( "QToolButton", 6, "Gln", "", "Glutamine", "Q", 1, 1 ),
( "QToolButton", 7, "Gly", "", "Glycine", "G", 2, 1 ),
( "QToolButton", 8, "His", "", "Histidine", "H", 3, 1 ),
( "QToolButton", 9, "Ile", "", "Isoleucine", "I", 4, 1 ),
( "QToolButton", 10, "Leu", "", "Leucine", "L", 0, 2 ),
( "QToolButton", 11, "Lys", "", "Lysine", "K", 1, 2 ),
( "QToolButton", 12, "Met", "", "Methionine", "M", 2, 2 ),
( "QToolButton", 13, "Phe", "", "Phenylalanine", "F", 3, 2 ),
( "QToolButton", 14, "Pro", "", "Proline", "P", 4, 2 ),
( "QToolButton", 15, "Ser", "", "Serine", "S", 0, 3 ),
( "QToolButton", 16, "Thr", "", "Threonine", "T", 1, 3 ),
( "QToolButton", 17, "Trp", "", "Tryptophan" , "W", 2, 3 ),
( "QToolButton", 18, "Tyr", "", "Tyrosine", "Y", 3, 3 ),
( "QToolButton", 19, "Val", "", "Valine", "V", 4, 3 )
]
_superclass = EditCommand_PM
class PeptideGeneratorPropertyManager(EditCommand_PM):
"""
The PeptideGeneratorPropertyManager class provides a Property Manager
for the "Build > Peptide" command.
"""
# The title that appears in the property manager header.
title = "Peptide Generator"
# The name of this property manager. This will be set to
# the name of the PropMgr (this) object via setObjectName().
pmName = title
# The relative path to PNG file that appears in the header.
iconPath = "ui/actions/Tools/Build Structures/Peptide.png"
def __init__( self, win, command ):
"""
Construct the "Build Graphene" Property Manager.
"""
_superclass.__init__( self, win, command )
self.showTopRowButtons( PM_DONE_BUTTON | \
PM_CANCEL_BUTTON | \
PM_PREVIEW_BUTTON | \
PM_WHATS_THIS_BUTTON)
# phi psi angles will define the secondary structure of the peptide chain
self.phi = -57.0
self.psi = -47.0
self.chirality = 1
self.secondary = SS_COIL
self.current_amino_acid = 0
#self.peptide_cache = []
#self.peptide_cache.append((0, 0, 0))
self.updateMessageGroupBox()
def updateMessageGroupBox(self):
msg = "Click on the Amino Acid buttons to add a new residue to " \
"the polypeptide chain. Click Done to insert it into the project."
# This causes the "Message" box to be displayed as well.
# setAsDefault=True causes this message to be reset whenever
# this PropMgr is (re)displayed via show(). Mark 2007-06-01.
self.updateMessage(msg)
def getParameters(self):
"""
Return the parameters from this property manager
to be used to create the peptide.
@return: A tuple containing the parameters
@rtype: tuple
@see: L{Peptide_EditCommand._gatherParameters()} where this is used
"""
#return (self.a1, self.a2, self.a3, self.a4, self.a5, self.a6)
return (self.secondary, self.phi, self.psi, self.current_amino_acid)
def _addGroupBoxes(self):
"""
Add the group boxe to the Peptide Property Manager dialog.
"""
self.pmGroupBox1 = \
PM_GroupBox( self,
title = "Peptide Parameters" )
# Add group box widgets.
self._loadGroupBox1(self.pmGroupBox1)
def _loadGroupBox1(self, inPmGroupBox):
"""
Load widgets in the group box.
"""
memberChoices = ["Custom",
"Alpha helix",
"Beta strand",
"Pi helix",
"3_10 helix",
"Polyproline-II helix",
"Fully extended"]
self.aaTypeComboBox= \
PM_ComboBox( inPmGroupBox,
label = "Conformation :",
choices = memberChoices,
index = 1,
setAsDefault = True,
spanWidth = False )
self.connect( self.aaTypeComboBox,
SIGNAL("currentIndexChanged(int)"),
self._aaTypeChanged)
self.phiAngleField = \
PM_DoubleSpinBox( inPmGroupBox,
label = "Phi angle :",
value = -57.0,
setAsDefault = True,
minimum = -180.0,
maximum = 180.0,
singleStep = 1.0,
decimals = 1,
suffix = " degrees")
self.connect( self.phiAngleField,
SIGNAL("valueChanged(double)"),
self._aaPhiAngleChanged)
self.phiAngleField.setEnabled(False)
self.psiAngleField = \
PM_DoubleSpinBox( inPmGroupBox,
label = "Psi angle :",
value = -47.0,
setAsDefault = True,
minimum = -180.0,
maximum = 180.0,
singleStep = 1.0,
decimals = 1,
suffix = " degrees" )
self.connect( self.psiAngleField,
SIGNAL("valueChanged(double)"),
self._aaPsiAngleChanged)
self.psiAngleField.setEnabled(False)
#self.invertChiralityPushButton = \
# PM_PushButton( inPmGroupBox,
# text = 'Invert chirality' ,
# spanWidth = False
# )
#self.connect(self.invertChiralityPushButton,
# SIGNAL("clicked()"),
# self._aaChiralityChanged)
self.aaTypesButtonGroup = \
PM_ToolButtonGrid( inPmGroupBox,
buttonList = AA_BUTTON_LIST,
label = "Amino acids :",
checkedId = 0,
setAsDefault = True )
self.connect( self.aaTypesButtonGroup.buttonGroup,
SIGNAL("buttonClicked(int)"),
self._setAminoAcidType)
#self.addAminoAcid(0)
def addAminoAcid(self, index):
"""
Adds a new amino acid to the peptide molecule.
This is going to be displayed after user accepts or previews the structure.
"""
# add a new amino acid and chain conformation to the peptide cache
#self.peptide_cache.append((index,self.phi,self.psi))
#self.peptide_cache[0] = (index,self.phi,self.psi)
self.current_amino_acid = index
return
def _addWhatsThisText(self):
"""
What's This text for widgets in this Property Manager.
"""
#from ne1_ui.WhatsThisText_for_PropertyManagers import whatsThis_PeptideGeneratorPropertyManager
#whatsThis_PeptideGeneratorPropertyManager(self)
pass
def _addToolTipText(self):
"""
Tool Tip text for widgets in this Property Manager.
"""
#from ne1_ui.ToolTipText_for_PropertyManagers import ToolTip_PeptideGeneratorPropertyManager
#ToolTip_PeptideGeneratorPropertyManager(self)
pass
def _aaChiralityChanged(self):
"""
Set chirality of the peptide chain.
"""
self.psi *= -1
self.phi *= -1
self.phiAngleField.setValue(self.phi)
self.psiAngleField.setValue(self.psi)
def _aaTypeChanged(self, idx):
"""
Slot for Peptide Structure Type combobox.
Changes phi/psi angles for secondary structure.
"""
print "edit_command = ", self.command
self.ss_idx = idx
if idx == 0:
self.phiAngleField.setEnabled(True)
self.psiAngleField.setEnabled(True)
else:
self.phiAngleField.setEnabled(False)
self.psiAngleField.setEnabled(False)
if idx == 1: # alpha helix
self.phi = -57.0
self.psi = -47.0
self.secondary = SS_HELIX
elif idx == 2: # beta strand
self.phi = -135.0
self.psi = 135.0
self.secondary = SS_STRAND
elif idx == 3: # 3-10 helix
self.phi = -55.0
self.psi = -70.0
self.secondary = SS_HELIX
elif idx == 4: # pi helix
self.phi = -49.0
self.psi = -26.0
self.secondary = SS_HELIX
elif idx == 5: # polyprolin-II
self.phi = -75.0
self.psi = 150.0
self.secondary = SS_COIL
elif idx == 6: # fully extended
self.phi = -180.0
self.psi = 180.0
self.secondary = SS_STRAND
else:
self.phi = self.phiAngleField.value()
self.psi = self.psiAngleField.value()
self.secondary = SS_COIL
self.phi *= self.chirality
self.psi *= self.chirality
self.phiAngleField.setValue(self.phi)
self.psiAngleField.setValue(self.psi)
pass
def _aaPhiAngleChanged(self, phi):
self.phi = self.phiAngleField.value()
pass
def _aaPsiAngleChanged(self, psi):
self.psi = self.psiAngleField.value()
pass
def _setAminoAcidType(self, aaTypeIndex):
"""
Adds a new amino acid to the peptide molecule.
"""
"""
button, idx, short_name, dum, name, symbol, x, y = AA_BUTTON_LIST[aaTypeIndex]
if self.ss_idx==1:
aa_txt = ""
elif self.ss_idx==2:
aa_txt = ""
elif self.ss_idx==3:
aa_txt = ""
elif self.ss_idx==4:
aa_txt = ""
elif self.ss_idx==5:
aa_txt = ""
elif self.ss_idx==6:
aa_txt = ""
else:
aa_txt = ""
aa_txt += symbol+""
#self.sequenceEditor.insertHtml(aa_txt, False, 4, 10, False)
"""
self.current_amino_acid = aaTypeIndex
#self.addAminoAcid(aaTypeIndex)
return
#def _startOverClicked(self):
# """
# Resets a sequence in the sequence editor window.
# """
# self.sequenceEditor.clear()
# self.peptide_cache = []
# pass