Spherical Harmonics Explorer

I have written a neat little Spherical Harmonics explorer. Right now, the projection function has some weird bug still, but the basis functions, and arbitrary combinations of them can be viewed nicely. The tool is written in Python, using PyQt4 and PyOpenGL. Python is excellent for prototyping such a tool. It might not be as fast as C++, but the rendering speed using PyOpenGL is more than enough and very smooth. I might put the small 3D viewer widget online later, because it might be useful for many people. Here’s some eyecandy:

Update: Now the projection also works fine. See the example screenshot of an order 5 approximation. This still needs some more work, still using a very basic Monte Carlo sampling approach, which converges terribly slow. But I can already produce some results.

Selecting between overloaded signals in PyQt

The signal mechanism in Qt allows for overloading. E.g. the QSpinBox comes with two signals called valueChanged(int) and valueChanged(QString). However, since Python is dynamically typed, such overloading gives rise to problems. Here is how you can select which signal you want to connect to your slot:

from PyQt4 import QtCore, QtGui, uic

class MyMainWindow(QtGui.QMainWindow):

def __init__(self):
QtGui.QMainWindow.__init__(self)
self.ui = uic.loadUi("MyMainWindow.ui", self)

# Slot connections
self.ui.spinBox.valueChanged.connect(self.spinBoxChanged)
self.ui.spinBox.setValue(4)

@QtCore.pyqtSlot(int)
def spinBoxChanged(self, i):
# do something...
pass

Notice the (int) in the decorator of the slot. This has to match the signature of the signal. I haven’t dug into more complex signals, passing around arbitrary objects, but I think that is not a problem: Qt datatypes have a Python wrapper, and functions in Python cannot be overloaded anyway, so there won’t be clashes with pure Python signals and slots.

I love Python

It’s so easy to quickly code something and calculate something. The following snippet actually computes the number of possible cards in the game Tsuro. The game ships with 64 cards, but my colleague and I suspected that those were not all possible combinations (eliminating all rotational symmetries). So we did some quick calculations, and came up with 105 possible cards. So I wrote this short Python code to enumerate all possible cards then:

Update: My first algorithm was wrong. The actual number of cards is 35. It is only 105, when the numbering of the conncetion points is of interest. So here is the augmented algorithm, which outputs the 35 unique cards. The game comes with two of every card, except for 6 highly symmetric cards, which are unique in the game.


def makeCards(cards, card, connectionSet):
if connectionSet == set([]):
for i in range(1,4):
c = shiftCard(card, i)
try:
cards.index(c)
return cards
except ValueError:
pass
return cards + [card]
start = connectionSet.pop()
for i in connectionSet:
newConnection = sorted([start, i])
cards = makeCards(cards, sorted(card + [newConnection]), connectionSet - set([i]))
return cards

def shiftCard(card, i):
newCard = []
for c in card:
conn = sorted([(c[0] + 2 * i) % 8, (c[1] + 2 * i) % 8])
newCard = sorted(newCard + [conn])
return newCard

mycards = makeCards([], [], set([0,1,2,3,4,5,6,7]))
print mycards
print len(mycards)

How to duplicate Matlab functionality

Since I am a total Matlab-n00b, I rather write a convoluted Python script instead of using the appropriate Matlab function. And here it is. A small script to compute the standard deviation of two vectors. I guess this would have been one Matlab command.


import sys
import scipy.io
import math

def computeStdDev(file, vec1, vec2):
data = scipy.io.loadmat(file, struct_as_record=True)
vector1 = data[vec1]
vector2 = data[vec2]
if len(vector1) != len(vector2):
print "Error: Vectors do not have matching lengths."
return
diff = vector1
N = len(diff)

for i in range(N):
diff[i] = vector1[i] - vector2[i]

mu = 0
for val in diff:
mu = mu + val
mu = mu / float(N)

sigma = 0
for i in range(N):
sigma = sigma + (diff[i] - mu)**2
sigma = math.sqrt(sigma / float(N))

print "mu: %f" % mu
print "sigma: %f" % sigma

if len(sys.argv) != 4:
print "Usage: %s file vector1 vector2" % sys.argv[0]
sys.exit(0)

computeStdDev(sys.argv[1], sys.argv[2], sys.argv[3])

Elegantly making a dictionary of lists

In Python I sometimes want to make a dictionary of lists. So usually I would write something like:


mydic = {}
for something in somethingelse:
mydic[somekey].append(something)

This however will not work, if somekey did not exist so far, because it will raise an exception. But there is help! You can use a collection:


import collections
mydic = collections.defaultdic(list)
for something in somethingelse:
mydic[somekey].append(something)

PyQt dynamic uic example

Here is a minimal example for PyQt4, to set up a main window and connect a simple action to some slot. The documentation on doing this is sparse to say the least. So I hope this is helpful for anyone trying something similar. I assume that you have created a ui_MainWindow.ui file with Qt Designer, which contains a form derived from QMainWindow.


import sys
from PyQt4 import QtCore, QtGui, uic

class MyMainWindow(QtGui.QMainWindow):

def __init__(self):
QtGui.QMainWindow.__init__(self)
self.ui = uic.loadUi("ui_MainWindow.ui", self)
self.connect(self.ui.actionOpen, QtCore.SIGNAL('triggered()'), self, QtCore.SLOT('open()'))

@QtCore.pyqtSlot()
def open(self):
fileDialog = QtGui.QFileDialog(self, "Open file")
fileDialog.show()

app = QtGui.QApplication(sys.argv)
mainWindow = MyMainWindow()
mainWindow.show()
sys.exit(app.exec_())