logging, more events, some bugs/regressions fixed

This commit is contained in:
Stefan Kögl 2012-11-22 07:22:33 +01:00
parent 6d8e7580c0
commit 5fbba2a585
1 changed files with 149 additions and 19 deletions

View File

@ -9,6 +9,7 @@ from operator import attrgetter
import xml.etree.ElementTree as etree
import pylab
import numpy
from PyQt4 import QtGui, QtCore
from numpy import arange, sin, pi, array, linspace, arange
@ -96,7 +97,7 @@ def getTemperature():
return 20.
class TempLevel(object):
class TempLevel(QtCore.QObject):
def __init__(self, name, temp, is_env=False):
self.name = name
self.temp = temp
@ -104,9 +105,12 @@ class TempLevel(object):
self.color = None
class Solder(object):
class Solder(QtCore.QObject):
def __init__(self, name=str(), description=str()):
log_message = QtCore.pyqtSignal(str)
def __init__(self, name=str(), description=str(), parent=None):
super(Solder, self).__init__(parent)
self.name = name
self.description = description
self.temp_levels = list()
@ -142,8 +146,96 @@ class Solder(object):
assert isinstance(ix, int)
return self.temp_levels[ix]
def calc_rate(self, x1, y1, x2, y2):
return (y2 - y1) / (x2 - x1)
def check_duration_constraints(self, temp_level, used):
x = list()
y = list()
temp_levels = None
value = None
for temp_levels, value in self.durations:
tl_len = len(temp_levels)
if temp_levels and temp_levels[0] == temp_level and tl_len > 1:
if temp_level not in used:
used.add(temp_level)
x.append(self.time)
y.append(temp_level.temp)
if tl_len == 2:
y.append(temp_levels[1].temp)
used.add(temp_levels[1])
self.time += value
x.append(self.time)
elif tl_len >= 3:
part = value / (tl_len - 1)
for tl in temp_levels[1:]:
used.add(tl)
self.time += part
x.append(self.time)
y.append(tl.temp)
self.log.append("* Duration connection: TempLevel %r connected to TempLevels %r" % (temp_level.name, [tl.name for tl in temp_levels[1:]]))
return x, y
def check_rate_constraints(self, temp_level, used):
x = list()
y = list()
for temp_levels, value in self.rates:
tl_len = len(temp_levels)
if temp_levels and temp_levels[0] == temp_level and tl_len > 1:
if temp_level not in used:
used.add(temp_level)
x.append(self.time)
y.append(temp_level.temp)
self.time += (temp_levels[1].temp - temp_level.temp) / value
used.add(temp_levels[1])
x.append(self.time)
y.append(temp_levels[1].temp)
self.log.append("* Rate connection: TempLevel %r connected to TempLevels %r" % (temp_level.name, [tl.name for tl in temp_levels[1:]]))
return x, y
def calc_profile(self):
self.log = list()
x = list()
y = list()
duration_points = dict()
rate_points = dict()
self.time = 0
used = set()
unused = list()
for temp_level in self.temp_levels:
dur_x, dur_y = self.check_duration_constraints(temp_level, used)
rate_x, rate_y = self.check_rate_constraints(temp_level, used)
print dur_x, dur_y
print rate_x, rate_y
print
if len(dur_x) > 0:
x.extend(dur_x)
y.extend(dur_y)
elif len(rate_x) > 0:
x.extend(rate_x)
y.extend(rate_y)
else:
if temp_level not in used:
unused.append(temp_level)
self.log.append("")
map(self.log.append, ["* Missing Connection: %r" % tl.name for tl in unused])
self.log_message.emit("\n".join(self.log))
del self.log
return array(map(float, x)), array(map(float, y)), max(x), max(y), used, unused
def calc_profile_old(self):
x = list()
y = list()
duration_points = dict()
@ -202,11 +294,11 @@ class Solder(object):
@staticmethod
def unpack(filename):
def unpack(filename, parent):
xmltree = etree.parse(filename)
root = xmltree.getroot()
solder_node = root[0]
s = Solder(solder_node.attrib["name"], solder_node.attrib["description"])
s = Solder(solder_node.attrib["name"], solder_node.attrib["description"], parent)
env_count = 0
for temp_level in solder_node.findall("state"):
tstr = temp_level.attrib["temperature"]
@ -276,7 +368,7 @@ class SolderListModel(QtCore.QAbstractListModel):
dirlisting = filter(lambda x: os.path.splitext(x)[1] == ".xml", os.listdir(dirname))
self.listdata = []
for p in dirlisting:
self.listdata.append(Solder.unpack(os.path.join(dirname, p)))
self.listdata.append(Solder.unpack(os.path.join(dirname, p), self))
self.listdata.sort(key=lambda x: x.name)
self.reset()
@ -390,6 +482,7 @@ class TempLevelModel(QtCore.QAbstractTableModel):
assert isinstance(temp_levels, list)
self.temp_levels = temp_levels
self.reset()
print self.setTempLevels
def clear(self):
@ -404,6 +497,14 @@ class Plotter(FigureCanvas):
self.fig = Figure(figsize=(width, height), dpi=dpi)
super(Plotter, self).__init__(self.fig)
self.axes = self.fig.add_subplot(111)
#self.fig.subplots_adjust(
#left=0.1,
#bottom=0.05,
#right=0.9,
#top=0.95,
#wspace=0,
#hspace=0
#)
self.axes.set_axis_bgcolor('white')
self.axes.set_title(u'reflow profile', size=12)
@ -432,20 +533,19 @@ class Plotter(FigureCanvas):
def update_figure(self):
if self.updated:
updated = False
self.updated = False
self.axes.patches = list()
self.axes.texts = list()
self.x = list()
self.y = list()
try:
self.x, self.y, self.xmax, self.ymax, self.duration_points, self.rate_points = self.solder.calc_profile()
self.x, self.y, self.xmax, self.ymax, self.used, self.unused = self.solder.calc_profile()
for ix, (a, b) in enumerate(zip(self.x[:-1], self.y[:-1])):
annotation.slope_marker((a + 10, b), (self.y[ix+1] - b) / (self.x[ix+1] - a), ax=self.axes)
except Exception, e:
self.xmax = 500
self.ymax = 300
for ix, (a, b) in enumerate(zip(self.x[:-1], self.y[:-1])):
slope = (self.y[ix+1] - b) / (self.x[ix+1] - a)
if not (numpy.isnan(slope) or numpy.isinf(slope)):
origin = (a + 10, b)
annotation.slope_marker(origin, slope, ax=self.axes)
self.plot_data.set_xdata(self.x)
self.plot_data.set_ydata(self.y)
@ -453,7 +553,7 @@ class Plotter(FigureCanvas):
self.axes.set_xbound(lower=0, upper=self.xmax + 20)
self.axes.set_ybound(lower=0, upper=self.ymax + 20)
self.axes.set_yticks([state.temp for state in self.solder.temp_levels])
self.axes.set_yticks(self.y)
self.axes.set_xticks(self.x)
#duration_widget = self.myapp.duration_widget
@ -468,11 +568,12 @@ class Plotter(FigureCanvas):
transform=self.axes.transData, figure=self.fig, color=str(temp_level.color.name()), label="name", zorder=1)
lines.append(line)
self.axes.legend(("Estimated profile",))
self.axes.legend(("Estimated profile",), loc=2)
self.draw()
def solder_changed(self):
self.solder.changed = True
self.updated = True
def setData(self, solder):
self.solder = solder
@ -731,9 +832,11 @@ class DurationConstraintWidget(ConstraintWidget):
def _set_data(self, solder):
self.spinbox_block = True
self.constraint_model.constraint_list = solder.durations
self.constraint_model.reset()
ix = self.constraint_model.index(0, 0)
self._constraint_selected(ix)
self.constraint_view.setCurrentIndex(ix)
print self._set_data
def _constraint_selected(self, index):
if index.isValid():
@ -743,8 +846,9 @@ class DurationConstraintWidget(ConstraintWidget):
self.controls.value.setValue(value)
else:
self.spinbox_block = True
self.selected_temp_levels.setTempLevels([])
self.selected_temp_levels.setTempLevels(list())
self.controls.value.setValue(0)
print self._constraint_selected
class OvenControlsWidget(QtGui.QWidget):
@ -812,7 +916,7 @@ class RateConstraintWidget(ConstraintWidget):
def _set_data(self, solder):
self.spinbox_block = True
self.constraint_model.constraint_list = solder.rates
self.constraint_model.reset()
ix = self.constraint_model.index(0, 0)
self._constraint_selected(ix)
self.constraint_view.setCurrentIndex(ix)
@ -948,6 +1052,12 @@ class TempLevelWidget(QtGui.QWidget):
#self.controls.add_button.setEnabled(not is_end)
self.controls.remove_button.setEnabled(not is_env)
class Report(QtGui.QWidget):
def __init__(self, parent=None):
super(Report, self).__init__(parent)
class ApplicationWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
@ -1033,6 +1143,16 @@ class ApplicationWindow(QtGui.QMainWindow):
QtCore.SIGNAL("solder_changed()"),
self.plotter.solder_changed)
self.connect(
self.duration_widget,
QtCore.SIGNAL("solder_changed()"),
self.plotter.solder_changed)
self.connect(
self.rate_widget,
QtCore.SIGNAL("solder_changed()"),
self.plotter.solder_changed)
self.solder_widget = SolderWidget(self)
self.connect(
@ -1048,11 +1168,18 @@ class ApplicationWindow(QtGui.QMainWindow):
self.splitter = QtGui.QSplitter(QtCore.Qt.Vertical, self)
self.plotter_splitter = QtGui.QSplitter(self)
self.profile_log = QtGui.QTextEdit(self)
self.solder_selected(self.solder_widget.solder_model.index(0,0))
self.plotter_splitter.addWidget(self.plotter)
self.plotter_splitter.addWidget(self.profile_log)
self.splitter.addWidget(self.settings_widget)
self.splitter.addWidget(self.controls_widget)
self.splitter.addWidget(self.plotter)
self.splitter.addWidget(self.plotter_splitter)
self.splitter.setStretchFactor(0, 2)
self.splitter.setStretchFactor(1, 2)
self.splitter.setStretchFactor(2, 8)
@ -1082,10 +1209,13 @@ class ApplicationWindow(QtGui.QMainWindow):
if index.isValid():
solder = self.solder_widget.solder_model.listdata[index.row()]
self.temp_level_widget.setData(solder)
print "pre duration"
self.duration_widget.setData(solder)
print "post duration"
self.rate_widget.setData(solder)
self.plotter.setData(solder)
self.controls_widget.temp_level_widget.setData(solder)
solder.log_message.connect(self.profile_log.setPlainText)
def open_controls_view(self):
print self.open_controls_view