#!/usr/bin/env python
import sys, math, os, random
from PyQt4 import QtGui, QtCore
pattern_count_filename = os.environ.get("PATTERN_COUNT_FILE")
def parse_counts_from_fn(pattern_count_filename):
print "Going to try reading", pattern_count_filename, "..."
inp = open(pattern_count_filename, 'rU')
pcd = [float(i.strip()) for i in inp if i.strip()]
assert len(pcd) > 7
for i in pcd:
assert i >= 0.0
return pcd
if pattern_count_filename:
try:
pattern_count_data = parse_counts_from_fn(pattern_count_filename)
except:
sys.exit("Expecting %s to be a file of pattern counts (one-per line)." % pattern_count_filename)
else:
pattern_count_data = [0]*8
class BranchEnum:
A, B, INTERNAL, C, D = 0, 1, 2, 3, 4
names = ["A", "B", "Internal", "C", "D"]
# ratios of dimensions for 45 degree lines
HYP_OVER_HORIZ = math.sqrt(2)
HORIZ_OVER_HYP = 1/HYP_OVER_HORIZ
HYP_OVER_VERT = math.sqrt(2)
VERT_OVER_HYP = 1/HYP_OVER_VERT
TOL = 0.000001
NUM_STATES = 2
MAX_BRANCH_LEN = (NUM_STATES - 1.0)/NUM_STATES
AS_CENTRAL_WIDGET = False
if AS_CENTRAL_WIDGET:
TreeWindowBase = QtGui.QWorkspace
else:
TreeWindowBase = QtGui.QDialog
class TopologyEnum:
AB, AC, AD = 0, 1, 2
names = ["AB | CD", "AC | BD", "AD | BC"]
colors = [QtCore.Qt.red, QtCore.Qt.blue, QtCore.Qt.green]
txt_fmt = ['%s', '%s', '%s']
best_txt_fmt = ['%s', '%s', '%s']
SHOW_DATA_BARS = [True, True, True, True]
def randomly_choose_indices(p, n):
"""Treats `p` as a list of category probabilities. Returns as list of `n`
indices that were randomly drawn from this discrete probability distribution.
Does not verify that sum(p) == 1.0. All rounding error is "given" to the
list category.
"""
last_ind = len(p) - 1
c = [0]*len(p)
for i in xrange(n):
u = random.random()
ind = 0
while ind < last_ind:
u -= p[ind]
if u < 0.0:
break
ind += 1
c[ind] = c[ind] + 1
return c
class MultiBarWidget(QtGui.QWidget):
def __init__(self, parent):
self.h = []
QtGui.QWidget.__init__(self, parent)
self.max_dim = 300
self.max_prob = 1.0
self.px_per_unit_prob = self.max_dim/self.max_prob
self.bar_dim = 10
self.bar_skip = 0
self.setMinimumHeight(4.5*(self.bar_dim+ self.bar_skip))
self.setMinimumWidth(self.max_dim)
def paintEvent(self, event):
paint = QtGui.QPainter()
paint.begin(self)
colors = [QtCore.Qt.black, QtCore.Qt.red, QtCore.Qt.blue, QtCore.Qt.green, ]
y = 0
for n, b in enumerate(self.h):
if SHOW_DATA_BARS[n]:
w = b*self.px_per_unit_prob
r = QtCore.QRect(0, y, w, self.bar_dim)
curr_color = colors[n]
paint.fillRect(r, curr_color)
#print 0, y, w, self.bar_dim
y += self.bar_dim + self.bar_skip
paint.end()
class LnLWorkspace(TreeWindowBase):
"""Internally the tree calculations are done as if we have a AB|CD tree.
Then patterns and branch lengths are swapped into the correct order.
"""
def __init__(self, prob_sources, parent=None):
QtGui.QWidget.__init__(self, parent)
assert(len(prob_sources) == 3)
self.prob_sources = prob_sources
abp, acp, adp = [i.calc_pat_probs() for i in self.prob_sources]
self.setWindowTitle("Data and Likelihoods")
gridLayout = QtGui.QGridLayout()
dheader = QtGui.QLabel("Data (counts)")
gridLayout.addWidget(dheader, 0, 0)
tax_labels = QtGui.QLabel("A B C D")
gridLayout.addWidget(tax_labels, 0, 1)
self.showDataChkBox = QtGui.QCheckBox("Data")
self.showAB = QtGui.QCheckBox("AB")
self.showAC = QtGui.QCheckBox("AC")
self.showAD = QtGui.QCheckBox("AD")
self.showBarsBoxes = [self.showDataChkBox, self.showAB, self.showAC, self.showAD]
for el in self.showBarsBoxes:
el.setChecked(True)
self.connect(el, QtCore.SIGNAL('stateChanged(int)'), self.show_bars_changed)
gridLayout.addWidget(self.showDataChkBox, 0, 2)
gridLayout.addWidget(self.showAB, 0, 3)
gridLayout.addWidget(self.showAC, 0, 4)
gridLayout.addWidget(self.showAD, 0, 5)
patternCountValidator = QtGui.QDoubleValidator(self)
patternCountValidator.setBottom(0.0)
self.data_labels = []
self.data_counts = []
self.plot_widget_list = []
for i, bits in enumerate(['000', '001', '010', '011', '100', '101', '110', '111']):
lab = QtGui.QLabel("0 %s" % " ".join(bits))
vlab = QtGui.QLineEdit()
vlab.setMaximumWidth(100)
vlab.setText("0")
vlab.setValidator(patternCountValidator)
self.data_labels.append(lab)
self.data_counts.append(vlab)
plot_widget = MultiBarWidget(self)
plot_widget.h = [0.0, abp[i], acp[i], adp[i]]
self.plot_widget_list.append(plot_widget)
gridLayout.addWidget(vlab, 1 + i, 0)
gridLayout.addWidget(lab, 1 + i, 1)
gridLayout.addWidget(plot_widget, 1 + i, 2, 1, 3)
for el in self.data_counts:
self.connect(el, QtCore.SIGNAL('textChanged(QString)'), self.counts_changed)
w = QtGui.QLabel('ln(Likelihood)')
gridLayout.addWidget(w, 9, 0, 1, 2)
w = QtGui.QLabel('Parsimony score')
gridLayout.addWidget(w, 10, 0, 1, 2)
# font for the text boxes for the lnL
self.notBestFont = QtGui.QFont()
self.bestFont = QtGui.QFont()
self.bestFont.setUnderline(True)
self.lnL_labels = [QtGui.QLabel(''), QtGui.QLabel(''), QtGui.QLabel('')]
for n, el in enumerate(self.lnL_labels):
gridLayout.addWidget(el, 9, 2 + n)
self.pars_labels = [QtGui.QLabel(''), QtGui.QLabel(''), QtGui.QLabel('')]
for n, el in enumerate(self.pars_labels):
gridLayout.addWidget(el, 10, 2 + n)
self.setLayout(gridLayout)
self.resize(570, 500)
def show_bars_changed(self):
for n, el in enumerate(self.showBarsBoxes):
if el.isChecked():
SHOW_DATA_BARS[n] = True
else:
SHOW_DATA_BARS[n] = False
self.repaint()
def counts_changed(self):
abp, acp, adp = [i.calc_pat_probs() for i in self.prob_sources]
c = [float(i.text() or 0) for i in self.data_counts]
#print c
t = sum(c)
have_data = True
if t == 0.0:
t = 1.0
have_data = False
for n, el in enumerate(c):
self.plot_widget_list[n].h = [el/t, abp[n], acp[n], adp[n]]
self.plot_widget_list[n].repaint()
if have_data:
lnL_values = self.calc_ln_L()
pars_scores = self.calc_pars_scores()
#print pars_scores
highest_index = lnL_values.index(max(lnL_values))
most_pars_index = pars_scores.index(min(pars_scores))
as_str = ["%6.2f" % i for i in lnL_values]
for n, el in enumerate(self.lnL_labels):
if n == highest_index:
el.setFont(self.bestFont)
else:
el.setFont(self.notBestFont)
fmt_str = TopologyEnum.txt_fmt[n]
txt = TopologyEnum.txt_fmt[n] % as_str[n]
el.setText(txt)
el.show()
as_str = ["%6.2f" % i for i in pars_scores]
for n, el in enumerate(self.pars_labels):
if n == most_pars_index:
el.setFont(self.bestFont)
else:
el.setFont(self.notBestFont)
fmt_str = TopologyEnum.txt_fmt[n]
txt = TopologyEnum.txt_fmt[n] % as_str[n]
el.setText(txt)
el.show()
self.repaint()
def probs_changed(self):
self.counts_changed()
self.repaint()
def get_counts(self):
c = []
for i in self.data_counts:
try:
x = float(i.text())
except:
x = 0.0
c.append(x)
return c
def calc_pars_scores(self):
c = self.get_counts()
non_const = sum(c[1:])
homoplasy_ab = c[5] + c[6]
homoplasy_ac = c[3] + c[6]
homoplasy_ad = c[3] + c[5]
return [non_const + homoplasy_ab, non_const + homoplasy_ac, non_const + homoplasy_ad]
def calc_ln_L(self):
c = self.get_counts()
freqs = [i.calc_pat_probs() for i in self.prob_sources]
return [self.calc_ln_L_from_counts(c, f) for f in freqs]
def calc_ln_L_from_counts(self, counts, freqs):
sum = 0.0
for n, c in enumerate(counts):
if c > 0:
f = freqs[n]
try:
char_ln_l = c*math.log(f)
except ValueError:
return float('-inf')
sum += char_ln_l
return sum
def set_counts(self, pattern_count_data):
for n, x in enumerate(pattern_count_data):
try:
self.data_counts[n].setText(str(int(x)))
except:
self.data_counts[n].setText(str(x))
if n == 7:
break
self.repaint()
def crop_branch_len(x):
if x < 0.0:
return 0.0
if x > MAX_BRANCH_LEN:
return MAX_BRANCH_LEN
return x
class TreeWorkspace(TreeWindowBase):
"""Internally the tree calculations are done as if we have a AB|CD tree.
Then patterns and branch lengths are swapped into the correct order.
"""
def __init__(self, parent=None, topology=TopologyEnum.AB):
QtGui.QWidget.__init__(self, parent)
self.topology = topology
self.lnLPanel = None
self.setWindowTitle(TopologyEnum.names[self.topology])
gridLayout = QtGui.QGridLayout()
self.labels = []
self.spinboxes = []
self.opt_buttons = []
for i in range(5):
lab = QtGui.QLabel("length of '%s'" % BranchEnum.names[i])
sb = QtGui.QDoubleSpinBox()
sb.setRange(0.0, MAX_BRANCH_LEN)
sb.setDecimals(4)
sb.setSingleStep(0.005)
sb.setValue(0.05)
gridLayout.addWidget(lab, i, 2)
gridLayout.addWidget(sb, i, 1)
self.labels.append(lab)
self.spinboxes.append(sb)
self.connect(sb, QtCore.SIGNAL('valueChanged(double)'), self.brlen_changed)
opt = QtGui.QPushButton("Optimize")
self.opt_buttons.append(opt)
gridLayout.addWidget(opt, i, 0)
self.connect(opt, QtCore.SIGNAL('clicked()'), getattr(self, "opt_" + BranchEnum.names[i]))
opt = QtGui.QPushButton("Optimize all")
self.opt_buttons.append(opt)
gridLayout.addWidget(opt, 5, 0)
self.connect(opt, QtCore.SIGNAL('clicked()'), self.opt_all)
pat_pr = self.calc_pat_probs()
self.pr_labels = []
self.pr_values = []
for i, bits in enumerate(['000', '001', '010', '011', '100', '101', '110', '111']):
lab = QtGui.QLabel("Pr(0%s) =" % bits)
vlab = QtGui.QLabel("%0.5f" % pat_pr[i])
self.pr_labels.append(lab)
self.pr_values.append(vlab)
#gridLayout.addWidget(lab, i, 3)
#gridLayout.addWidget(vlab, i, 4)
#gridLayout.setRowStretch(i, 1)
#gridLayout.setColumnStretch(0, .5)
#gridLayout.setColumnStretch(1, .5)
self.treeCanvas = QtGui.QFrame()
gridLayout.setRowMinimumHeight(6, 250)
gridLayout.addWidget(self.treeCanvas, 6, 0, 1, 5)
self.treePaintX, self.treePaintY = (50, 300)
self.treePaintScaler = 300
self.treePen = QtGui.QPen(TopologyEnum.colors[self.topology], 2, QtCore.Qt.SolidLine)
sim = QtGui.QPushButton("Simulate...")
self.load_data_button = QtGui.QPushButton("Load Data")
gridLayout.addWidget(sim, 9, 0)
gridLayout.addWidget(self.load_data_button, 10, 0)
self.num_chars_edit = QtGui.QLineEdit()
num_char_validator = QtGui.QIntValidator(self)
num_char_validator.setBottom(0)
self.num_chars_edit.setText("500")
self.num_chars_edit.setValidator(num_char_validator)
gridLayout.addWidget(self.num_chars_edit, 9, 1)
lab = QtGui.QLabel("... characters")
gridLayout.addWidget(lab, 9, 2)
self.connect(sim, QtCore.SIGNAL('clicked()'), self.simulate)
self.connect(self.load_data_button, QtCore.SIGNAL('clicked()'), self.load_data)
self.setLayout(gridLayout)
self.resize(570, 400)
def simulate(self):
if not self.lnLPanel:
return
try:
t = self.num_chars_edit.text()
n = int(t)
except:
raise
p = self.calc_pat_probs()
c = randomly_choose_indices(p, n)
print "simulated counts = ", c
self.lnLPanel.set_counts(c)
def load_data(self):
if not self.lnLPanel:
return
load_data_filedialog = QtGui.QFileDialog(self)
#sys.stderr.write("\n".join(dir(load_data_filedialog)))
if load_data_filedialog.exec_():
f = load_data_filedialog.selectedFiles()
if f:
pattern_count_filename= f[0]
try:
c = parse_counts_from_fn(pattern_count_filename)
self.lnLPanel.set_counts(c)
except:
sys.stderr.write("Error reading data from %s" % pattern_count_filename)
def do_opt(self, value_holder, curr_step=0.04):
calc = self.lnLPanel
if not calc:
return
data = calc.get_counts()
if sum(data) == 0.0:
return
curr_pat_p = self.calc_pat_probs()
curr_v = value_holder.value()
curr_lnL = calc.calc_ln_L_from_counts(data, curr_pat_p)
best_v, best_lnL = curr_v, curr_lnL
lower_lnL = None
lower_v = curr_v
higher_lnL = None
higher_v = curr_v
while True:
if lower_lnL is not None and lower_lnL - TOL > curr_lnL:
curr_v, curr_lnL = lower_v, lower_lnL
value_holder.setValue(curr_v)
elif higher_lnL is not None and higher_lnL - TOL > curr_lnL:
curr_v, curr_lnL = higher_v, higher_lnL
else:
if (higher_lnL is not None) and (lower_lnL is not None):
if (abs(lower_lnL - curr_lnL) < TOL) and (abs(lower_lnL - curr_lnL) < TOL):
value_holder.setValue(curr_v)
self.repaint()
return curr_v, curr_lnL
if curr_lnL == float('-inf'):
return curr_v, curr_lnL
curr_step /= 2
best_v, best_lnL = curr_v, curr_lnL
lower_v = crop_branch_len(curr_v - curr_step)
value_holder.setValue(lower_v)
p = self.calc_pat_probs()
lower_lnL = calc.calc_ln_L_from_counts(data, p)
self.repaint()
higher_v = crop_branch_len(curr_v + curr_step)
value_holder.setValue(higher_v)
p = self.calc_pat_probs()
higher_lnL = calc.calc_ln_L_from_counts(data, p)
self.repaint()
#print lower_v, "=>", lower_lnL
#print curr_v, "=>", curr_lnL
#print higher_v, "=>", higher_lnL
def opt_all(self):
curr_step = 0.04
v, prev_lnl = self.opt_A(curr_step=curr_step)
same_score_count = 0
while True:
self.opt_Internal(curr_step=curr_step)
self.opt_A(curr_step=curr_step)
self.opt_B(curr_step=curr_step)
self.opt_C(curr_step=curr_step)
v, curr_lnl = self.opt_D(curr_step=curr_step)
#print "prev_lnl, curr_lnl = ", prev_lnl, curr_lnl
if abs(prev_lnl - curr_lnl) < TOL:
same_score_count += 1
else:
same_score_count = 0
if same_score_count > 1:
return
prev_lnl = curr_lnl
curr_step /= 10
def opt_A(self,curr_step=0.04):
return self.do_opt(self.spinboxes[BranchEnum.A], curr_step=curr_step)
def opt_B(self,curr_step=0.04):
return self.do_opt(self.spinboxes[BranchEnum.B], curr_step=curr_step)
def opt_Internal(self,curr_step=0.04):
return self.do_opt(self.spinboxes[BranchEnum.INTERNAL], curr_step=curr_step)
def opt_C(self,curr_step=0.04):
return self.do_opt(self.spinboxes[BranchEnum.C], curr_step=curr_step)
def opt_D(self,curr_step=0.04):
return self.do_opt(self.spinboxes[BranchEnum.D], curr_step=curr_step)
def get_br_lens(self):
return [i.value() for i in self.spinboxes]
def get_funky_ordered_br_lens(self):
if self.topology == TopologyEnum.AB:
return self.get_br_lens()
a_ch, b_ch, int_ch, c_ch, d_ch = self.get_br_lens()
if self.topology == TopologyEnum.AC:
b_ch, c_ch = c_ch, b_ch
else:
b_ch, c_ch, d_ch = d_ch, b_ch, c_ch
return a_ch, b_ch, int_ch, c_ch, d_ch
def calc_pat_p_scores(self):
"""Pattern parsimony scores returned in order:
A 00000000
B 00001111
C 00110011
D 01010101
"""
if self.topology == TopologyEnum.AB:
return (0, 1, 1, 1, 1, 2, 2, 1)
elif self.topology == TopologyEnum.AC:
return (0, 1, 1, 2, 1, 1, 2, 1)
return (0, 1, 1, 2, 1, 2, 1, 1)
def calc_pat_probs(self):
"""Pattern likelihoods returned in order (assumes CFN with A=0),
A 00000000
B 00001111
C 00110011
D 01010101
"""
b = self.get_funky_ordered_br_lens()
a_ch, b_ch, int_ch, c_ch, d_ch = b
a_no_ch, b_no_ch, int_no_ch, c_no_ch, d_no_ch = [1.0 - i for i in b]
# print "b = ", b
# ab anc
ab0, ab1= a_no_ch, a_ch
# ab anc and b
b0ab0 = ab0*b_no_ch
b1ab0 = ab0*b_ch
b0ab1 = ab1*b_ch
b1ab1 = ab1*b_no_ch
# print b0ab0, b1ab0, b0ab1, b1ab1
# ab anc, b and cd anc
b0ab0cd0 = b0ab0*int_no_ch
b0ab0cd1 = b0ab0*int_ch
b1ab0cd0 = b1ab0*int_no_ch
b1ab0cd1 = b1ab0*int_ch
b0ab1cd0 = b0ab1*int_ch
b0ab1cd1 = b0ab1*int_no_ch
b1ab1cd0 = b1ab1*int_ch
b1ab1cd1 = b1ab1*int_no_ch
# b and cd anc
b0cd0 = b0ab0cd0 + b0ab1cd0
b1cd0 = b1ab0cd0 + b1ab1cd0
b0cd1 = b0ab0cd1 + b0ab1cd1
b1cd1 = b1ab0cd1 + b1ab1cd1
# b, c and cd anc
b0cd0c0 = b0cd0*c_no_ch
b0cd0c1 = b0cd0*c_ch
b1cd0c0 = b1cd0*c_no_ch
b1cd0c1 = b1cd0*c_ch
b0cd1c0 = b0cd1*c_ch
b0cd1c1 = b0cd1*c_no_ch
b1cd1c0 = b1cd1*c_ch
b1cd1c1 = b1cd1*c_no_ch
# b, c, d and cd anc
b0cd0c0d0 = b0cd0c0*d_no_ch
b0cd0c0d1 = b0cd0c0*d_ch
b0cd0c1d0 = b0cd0c1*d_no_ch
b0cd0c1d1 = b0cd0c1*d_ch
b1cd0c0d0 = b1cd0c0*d_no_ch
b1cd0c0d1 = b1cd0c0*d_ch
b1cd0c1d0 = b1cd0c1*d_no_ch
b1cd0c1d1 = b1cd0c1*d_ch
b0cd1c0d0 = b0cd1c0*d_ch
b0cd1c0d1 = b0cd1c0*d_no_ch
b0cd1c1d0 = b0cd1c1*d_ch
b0cd1c1d1 = b0cd1c1*d_no_ch
b1cd1c0d0 = b1cd1c0*d_ch
b1cd1c0d1 = b1cd1c0*d_no_ch
b1cd1c1d0 = b1cd1c1*d_ch
b1cd1c1d1 = b1cd1c1*d_no_ch
# b, c, d
b0c0d0 = b0cd0c0d0 + b0cd1c0d0
b0c0d1 = b0cd0c0d1 + b0cd1c0d1
b0c1d0 = b0cd0c1d0 + b0cd1c1d0
b0c1d1 = b0cd0c1d1 + b0cd1c1d1
b1c0d0 = b1cd0c0d0 + b1cd1c0d0
b1c0d1 = b1cd0c0d1 + b1cd1c0d1
b1c1d0 = b1cd0c1d0 + b1cd1c1d0
b1c1d1 = b1cd0c1d1 + b1cd1c1d1
# swap elements
if self.topology == TopologyEnum.AC:
b0c0d0 , b0c0d1 , b0c1d0 , b0c1d1 , b1c0d0 , b1c0d1 , b1c1d0 , b1c1d1 = (b0c0d0 , b0c0d1 , b1c0d0 , b1c0d1 , b0c1d0 , b0c1d1 , b1c1d0 , b1c1d1)
elif self.topology == TopologyEnum.AD:
b0c0d0 , b0c0d1 , b0c1d0 , b0c1d1 , b1c0d0 , b1c0d1 , b1c1d0 , b1c1d1 = (b0c0d0 , b1c0d0 , b0c0d1 , b1c0d1 , b0c1d0 , b1c1d0 , b0c1d1 , b1c1d1)
# return with d = ones bit, c = 2's bit, d = 4's bit
return (b0c0d0 , b0c0d1 , b0c1d0 , b0c1d1 , b1c0d0 , b1c0d1 , b1c1d0 , b1c1d1)
def brlen_changed(self):
self.repaint()
if self.lnLPanel:
self.lnLPanel.probs_changed()
def refresh_pat_prob_GUI(self):
pat_pr = self.calc_pat_probs()
for i, item in enumerate(self.pr_values):
t = "%0.5f" % pat_pr[i]
item.setText(t)
# print i, t
def paintEvent(self, event):
self.refresh_pat_prob_GUI()
paint = QtGui.QPainter()
paint.begin(self)
scaler = self.treePaintScaler
abAncX = (self.treePaintX + MAX_BRANCH_LEN*scaler*HORIZ_OVER_HYP)
abAncY = (self.treePaintY+ MAX_BRANCH_LEN*scaler*VERT_OVER_HYP)
a_len, b_len, int_len, c_len, d_len = self.get_funky_ordered_br_lens()
cdAncX = abAncX + scaler*int_len
cdAncY = abAncY
aX = abAncX - scaler*HORIZ_OVER_HYP*a_len
aY = abAncY - scaler*VERT_OVER_HYP*a_len
bX = abAncX - scaler*HORIZ_OVER_HYP*b_len
bY = abAncY + scaler*VERT_OVER_HYP*b_len
cX = cdAncX + scaler*HORIZ_OVER_HYP*c_len
cY = cdAncY - scaler*VERT_OVER_HYP*c_len
dX = cdAncX + scaler*HORIZ_OVER_HYP*d_len
dY = cdAncY + scaler*VERT_OVER_HYP*d_len
font_x_offset = 10
font_y_offset = 5
if self.topology == TopologyEnum.AB:
b_text, c_text, d_text = "B", "C", "D"
elif self.topology == TopologyEnum.AC:
b_text, c_text, d_text = "C", "B", "D"
else:
b_text, c_text, d_text = "D", "B", "C"
paint.setPen(self.treePen)
paint.drawLine(abAncX, abAncY, cdAncX, cdAncY)
paint.drawLine(abAncX, abAncY, aX, aY)
paint.drawText(aX - font_x_offset, aY + font_y_offset, "A")
paint.drawLine(abAncX, abAncY, bX, bY)
paint.drawText(bX - font_x_offset, bY+ font_y_offset, b_text)
paint.drawLine(cdAncX, cdAncY, cX, cY)
paint.drawText(cX+4, cY + font_y_offset, c_text)
paint.drawLine(cdAncX, cdAncY, dX, dY)
paint.drawText(dX+4, dY+ font_y_offset, d_text)
paint.end()
class LikelihoodApp(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.setWindowTitle('tree likelihood visualizer')
sb = self.statusBar()
self.abTree = TreeWorkspace(topology=TopologyEnum.AB)
if AS_CENTRAL_WIDGET:
self.setCentralWidget = self.abTree
self.resize(self.abTree.width(), self.abTree.height() + sb.height())
else:
self.acTree = TreeWorkspace(topology=TopologyEnum.AC)
self.adTree = TreeWorkspace(topology=TopologyEnum.AD)
self.lnL = LnLWorkspace(prob_sources=[self.abTree, self.acTree, self.adTree])
self.abTree.lnLPanel = self.lnL
self.acTree.lnLPanel = self.lnL
self.adTree.lnLPanel = self.lnL
self.lnL.move(0,0)
self.abTree.move(500,20)
self.acTree.move(520,40)
self.adTree.move(530,50)
def show(self):
if not AS_CENTRAL_WIDGET:
self.acTree.show()
self.abTree.show()
self.adTree.show()
self.lnL.show()
QtGui.QMainWindow.show(self)
app = QtGui.QApplication(sys.argv)
qb = LikelihoodApp()
qb.show()
qb.lnL.set_counts(pattern_count_data)
sys.exit(app.exec_())