#!/usr/bin/env python # gui_example.py # # Copyright 2007 Frank Eisenmenger, U.H.E. Hansmann, # Jan H. Meinke, Sandipan Mohanty # # Display the Calpha trace and energy of a Monte Carlo simulation of a protein using Qt4. import sys sys.path.append("../../") import universe import protein import algorithms from PyQt4 import QtCore, QtGui class CAlphaTraceWidget(QtGui.QWidget): """Displays a 2D projection of the Calpha trace of the protein p. The projection simply drops the z coordinate. """ def __init__(self, protein, parent = 0): """Initialize the widget. @param p the protein.Protein to be displayed @param parent parent widget if applicable. """ QtGui.QWidget.__init__(self) self.protein = protein self.calphaList = [] for a in self.protein.atoms(): if a.name().lower().strip() == 'ca': self.calphaList.append(a) self.centralAtom = self.calphaList[len(self.calphaList) / 2] def paintEvent(self, event): """Draw little circles in the position of the Calpha atoms of p.""" diameter = 2 avgCalphaDistance = 4 zmin = -avgCalphaDistance * len(self.protein) zmax = avgCalphaDistance * len(self.protein) self.calphaList.sort(self.atomZSort) painter = QtGui.QPainter(self) painter.setRenderHint(QtGui.QPainter.Antialiasing, 1) painter.translate(self.width() / 2, self.height() / 2) xscale = 1.5 * self.width() / (avgCalphaDistance * len(self.protein)) yscale = 1.5 * self.height() / (avgCalphaDistance * len(self.protein)) scale = min(xscale, yscale) painter.scale(scale, scale) myGradient = QtGui.QRadialGradient(QtCore.QPointF(0, 0), 72) myGradient.setColorAt(0, QtCore.Qt.white) myGradient.setColorAt(1, QtCore.Qt.black) painter.setBrush(QtGui.QBrush(myGradient)) painter.translate(-self.centralAtom.position()[0], -self.centralAtom.position()[1]) for a in self.calphaList: pos = a.position() if pos[2] < zmin: zscale = 0.1 elif pos[2] > zmax: zscale = 5.0 else: zscale = (pos[2] - zmin) / (zmax - zmin) * 4.9 + 0.1 painter.save() painter.translate(pos[0], pos[1]) painter.scale(zscale * diameter / 100, zscale * diameter / 100) painter.drawEllipse(-50, -50, 100, 100) painter.restore() painter.setWorldMatrixEnabled(0) painter.drawText(5,self.height() -5 , QtCore.QString("E=%s" % self.protein.energy())) painter.setWorldMatrixEnabled(1) def atomZSort(self, a, b): za = a.position()[2] zb = b.position()[2] if za < zb: return -1 elif za > zb: return 1 else: return 0 class WorkThread(QtCore.QThread): def __init__(self, f): QtCore.QThread.__init__(self) self.function= f def run(self): import os.path from os import system for i in range(0, 1000): print "Performing sweep %s." % i self.function() try: print os.path.getmtime('best.png'), os.path.getmtime('best.pdb') if os.path.getmtime('best.png') < os.path.getmtime('best.pdb'): os.system('pymol -c best.pml') except os.error,e: os.system('pymol -c best.pml') self.emit(QtCore.SIGNAL('finishedSweep(int)'), i) class TemperatureDial(QtGui.QDial): def __init__(self, Tmin, Tmax): QtGui.QDial.__init__(self) self.setMinimum(Tmin) self.setMaximum(Tmax) self.setNotchTarget(60) self.setNotchesVisible(1) class MainWidget(QtGui.QWidget): def __init__(self): QtGui.QWidget.__init__(self) self.resize(640,480) self.setWindowTitle("MC Simulation of Protein A (1BDD)") topLevelLayout = QtGui.QHBoxLayout() sideBarLayout = QtGui.QVBoxLayout() self.maxSweeps = 1000 self.myU = universe.Universe() self.p = protein.Protein('../1bdd.seq') self.myMC = algorithms.CanonicalMonteCarlo(self.myU, 1, self.maxSweeps) self.myWorkThread = WorkThread(self.myMC.sweep) self.labelList = [['E', self.p.energy], ['Rgyr', self.p.rgyr, 0], ['hb' ,self.p.hbond]] myCAlphaTraceWidget = CAlphaTraceWidget(self.p) topLevelLayout.addWidget(myCAlphaTraceWidget, 1) self.createSideBar(sideBarLayout) topLevelLayout.addLayout(sideBarLayout) self.setLayout(topLevelLayout) self.myWorkThread.start() self.connect(self.myWorkThread, QtCore.SIGNAL("finishedSweep(int)"), self.finishedSweep) self.connect(self.myWorkThread, QtCore.SIGNAL("finishedSweep(int)"), self.myProgressBar, QtCore.SLOT("setValue(int)")) def createSideBar(self, sideBarLayout): myTDial = TemperatureDial(1, 1200) myTDial.setValue(self.myU.temperature()) sideBarLayout.addWidget(myTDial) temperatureLabel = QtGui.QLabel("%s" % myTDial.value()) self.connect(myTDial, QtCore.SIGNAL("valueChanged(int)"), temperatureLabel, QtCore.SLOT("setNum(int)")) self.connect(myTDial, QtCore.SIGNAL("valueChanged(int)"), self.myU.setTemperature) sideBarLayout.addWidget(temperatureLabel) sideBarLayout.addStretch(1) self.labels = {} for name in self.labelList: if len(name) > 2: labelText = "%s: %8.3f" % (name[0], name[1]()[name[2]]) else: labelText = "%s: %8.3f" % (name[0], name[1]()) self.labels[name[0]] = QtGui.QLabel(labelText) sideBarLayout.addWidget(self.labels[name[0]]) sideBarLayout.addStretch(2) self.bestImageLabel = QtGui.QLabel() self.bestImageLabel.setText('Waiting...') self.bestImageLabel.setToolTip('Waiting ...') sideBarLayout.addWidget(self.bestImageLabel) self.myProgressBar = QtGui.QProgressBar() self.myProgressBar.setRange(0, self.maxSweeps - 1) self.myProgressBar.setValue(0) sideBarLayout.addWidget(self.myProgressBar) def finishedSweep(self, sweep): for name in self.labelList: if len(name) > 2: labelText = "%s: %8.3f" % (name[0], name[1]()[name[2]]) else: labelText = "%s: %8.3f" % (name[0], name[1]()) self.labels[name[0]].setText(labelText) bestPix = QtGui.QPixmap("best.png") scaledPix = bestPix.scaledToWidth(100) self.bestImageLabel.setPixmap(scaledPix) self.bestImageLabel.setToolTip(' E=%s at t=%s' % self.myMC.minimumEnergy()) self.setWindowIcon(QtGui.QIcon(scaledPix)) self.update() if __name__ == "__main__": myApp = QtGui.QApplication(sys.argv) myMain = MainWidget() myMain.show() sys.exit(myApp.exec_())