The plugin allows the user to click through all of the pharmacophores defined in a file and display them one by one. See install instructions in the previous post. The code is kinda rough-and-ready so be prepared to hack around if you need to sort something out:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
from PyQt4.Qt import * | |
import Avogadro as avo | |
from numpy import array | |
# Get JSON from my own Python installation | |
import sys | |
sys.path.append("C:\\Python26\\Lib\\site-packages") | |
sys.path.append("C:\\Python26\\lib") | |
import json | |
colorlookup = { | |
'Hydrophobic': [0, 139, 69], | |
'HydrogenAcceptor': [255, 165, 0], | |
'HydrogenDonor': [211, 211, 211], | |
'Aromatic': [205, 0, 205], | |
'PositiveIon': [0, 0, 238], | |
'NegativeIon': [255, 0, 0], | |
'HybridAromLipo': [205./2., 139/2., (69+205.)/2.] | |
} | |
pharaolookup = { | |
"HYBL": "HybridAromLipo", | |
"HDON": "HydrogenDonor", | |
"HACC": "HydrogenAcceptor", | |
"NEGC": "NegativeIon", | |
"POSC": "PositiveIon", | |
"LIPO": "Hydrophobic", | |
"AROM": "Aromatic", | |
"HYBH": "HyrogenAcceptor" | |
} | |
def debug(text): | |
return | |
filename = os.path.join("C:\\", "Users", "Noel", "Desktop", "tmp.txt") | |
output = open(filename, "a") | |
print >> output, text | |
output.close() | |
def readpharmacophore(filename): | |
NONE, PHARAO, PHARMER = range(3) | |
software = NONE | |
pharmas = [] | |
# Detect whether Pharmer or Pharao | |
with open(filename) as f: | |
line = f.next() | |
if line[0] == "{": | |
software = PHARMER | |
else: | |
software = PHARAO | |
with open(filename) as f: | |
if software == PHARMER: | |
query = json.load(f) | |
pharmas.append(("No title", [x for x in query['points'] if x['enabled']])) | |
else: | |
for line in f: | |
pharma = [] | |
title = line | |
line = f.next() | |
while line.rstrip() != "$$$$": | |
broken = line.rstrip().split() | |
data = {} | |
data["name"] = pharaolookup[broken[0]] | |
for a, b in zip(["x", "y", "z"], broken[1:4]): | |
data[a] = float(b) | |
data["radius"] = float(broken[4]) | |
if broken[5] == "1": | |
tmp = {} | |
for a, b in zip(["x", "y", "z"], broken[6:9]): | |
tmp[a] = (float(b) - data[a])*2.5 + data[a] # Increase length | |
data["vector"] = tmp | |
data["vector_on"] = True | |
pharma.append(data) | |
line = f.next() | |
pharmas.append((title, pharma)) | |
if software == PHARMER: | |
pharma = pharmas[0] | |
if len(pharma) > 0: | |
x = y = z =0 | |
for p in pharma: | |
x += p['x'] | |
y += p['y'] | |
z += p['z'] | |
x /= len(pharma) | |
y /= len(pharma) | |
z /= len(pharma) | |
for p in pharma: | |
p['x'] -= x | |
p['y'] -= y | |
p['z'] -= z | |
return pharmas | |
class Engine(QObject): | |
# declare the changed() signal | |
__pyqtSignals__ = ("changed()",) | |
# constructor | |
def __init__(self): | |
QObject.__init__(self) | |
self.widget = None | |
self.textbox = None | |
self.filename = "" | |
self.pharmas = [] | |
def name(self): | |
return "Pharmacophore" | |
def flags(self): | |
return avo.EngineFlags.NoFlags | |
@pyqtSignature("") | |
def browse(self): | |
self.filename = str(QFileDialog.getOpenFileName()) | |
if not self.filename: | |
return | |
self.textbox.setText(self.filename) | |
self.pharmas = readpharmacophore(self.filename) | |
self.allpharmas.setRowCount(len(self.pharmas)) | |
for i, pharma in enumerate(self.pharmas): | |
newItem = QTableWidgetItem(pharma[0]) | |
self.allpharmas.setItem(0, i, newItem) | |
self.chosenpharma = 0 | |
self.allpharmas.setCurrentCell(0, self.chosenpharma, QItemSelectionModel.ClearAndSelect) | |
self.emit(SIGNAL("changed()")) | |
@pyqtSignature("") | |
def clear(self): | |
self.filename = "" | |
self.textbox.setText(self.filename) | |
self.pharmas = [] | |
self.emit(SIGNAL("changed()")) | |
@pyqtSignature("") | |
def myupdate(self): | |
self.pharmas = readpharmacophore(self.filename) | |
self.allpharmas.setRowCount(len(self.pharmas)) | |
for i, pharma in enumerate(self.pharmas): | |
newItem = QTableWidgetItem(pharma[0]) | |
self.allpharmas.setItem(0, i, newItem) | |
if self.chosenphara > len(self.pharmas): | |
self.chosenpharma = len(self.pharmas) - 1 | |
self.emit(SIGNAL("changed()")) | |
@pyqtSignature("int, int, int, int") | |
def myotherupdate(self, x, y, a, b): | |
debug("value: %d" % self.allpharmas.currentRow()) | |
debug("values: %d %d %d %d" % (x, y, a, b)) | |
self.chosenpharma = self.allpharmas.currentRow() | |
debug("chosenpharma: %d N pharmas: %d" % (self.chosenpharma, len(self.pharmas))) | |
if self.chosenpharma > len(self.pharmas): | |
self.chosenpharma = len(self.pharmas) - 1 | |
self.emit(SIGNAL("changed()")) | |
def settingsWidget(self): | |
self.widget = QWidget() | |
layout = QVBoxLayout(self.widget) | |
self.textbox = QLineEdit(self.filename) | |
self.textbox.setReadOnly(True) | |
layout.addWidget(self.textbox) | |
self.allpharmas = QTableWidget(self.widget) | |
self.allpharmas.setAlternatingRowColors(True) | |
self.allpharmas.setSelectionMode(QAbstractItemView.SingleSelection) | |
layout.addWidget(self.allpharmas) | |
self.allpharmas.clear() | |
self.allpharmas.setRowCount(1) | |
self.allpharmas.setColumnCount(1) | |
self.allpharmas.horizontalHeader().setResizeMode(QHeaderView.Stretch) | |
self.allpharmas.setHorizontalHeaderLabels(["Pharmacophore Title"]) | |
buttons = QHBoxLayout(self.widget) | |
layout.addLayout(buttons) | |
self.browsebtn = QPushButton("Browse") | |
self.updatebtn = QPushButton("Reload") | |
self.clearbtn = QPushButton("Clear") | |
buttons.addWidget(self.browsebtn) | |
buttons.addWidget(self.updatebtn) | |
buttons.addWidget(self.clearbtn) | |
QObject.connect(self.browsebtn,SIGNAL("clicked()"),self, SLOT("browse()")) | |
QObject.connect(self.clearbtn, SIGNAL("clicked()"),self, SLOT("clear()")) | |
QObject.connect(self.updatebtn,SIGNAL("clicked()"),self, SLOT("myupdate()")) | |
QObject.connect(self.allpharmas, | |
SIGNAL("currentCellChanged(int, int, int, int)"), | |
self, SLOT("myotherupdate(int,int,int,int)")) | |
debug("End of widget 2") | |
return self.widget | |
def renderOpaque(self, pd): | |
if len(self.pharmas) == 0: | |
return | |
# Painter | |
painter = pd.painter | |
# Molecule | |
molecule = pd.molecule | |
# Color | |
color = pd.colorMap | |
for point in self.pharmas[self.chosenpharma][1]: | |
if point['name'] in colorlookup: | |
colvals = [float(x) / 255. for x in colorlookup[point['name']]] + [1.0] | |
color.setFromRgba(*colvals) | |
else: | |
color.setFromRgba(0.3, 0.6, 1.0, 1.0) | |
painter.setColor(color) | |
r = point['radius'] | |
x, y, z = point['x'], point['y'], point['z'] | |
painter.drawSphere(array([x, y, z]), r) | |
if "vector" in point and point.get("vector_on") != False: | |
v = point['vector'] | |
a, b, c = v['x'], v['y'], v['z'] | |
painter.drawCylinder(array([x, y, z]), array([a, b, c]), 0.2) | |
painter.drawCone(array([a, b, c]), | |
array([(a-x)*0.1+a,(b-y)*0.1+b,(c-z)*0.1+c]), 0.3) |
No comments:
Post a Comment