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 xml.etree.ElementTree as etree
import pylab import pylab
import numpy
from PyQt4 import QtGui, QtCore from PyQt4 import QtGui, QtCore
from numpy import arange, sin, pi, array, linspace, arange from numpy import arange, sin, pi, array, linspace, arange
@ -96,7 +97,7 @@ def getTemperature():
return 20. return 20.
class TempLevel(object): class TempLevel(QtCore.QObject):
def __init__(self, name, temp, is_env=False): def __init__(self, name, temp, is_env=False):
self.name = name self.name = name
self.temp = temp self.temp = temp
@ -104,9 +105,12 @@ class TempLevel(object):
self.color = None 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.name = name
self.description = description self.description = description
self.temp_levels = list() self.temp_levels = list()
@ -142,8 +146,96 @@ class Solder(object):
assert isinstance(ix, int) assert isinstance(ix, int)
return self.temp_levels[ix] 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): 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() x = list()
y = list() y = list()
duration_points = dict() duration_points = dict()
@ -202,11 +294,11 @@ class Solder(object):
@staticmethod @staticmethod
def unpack(filename): def unpack(filename, parent):
xmltree = etree.parse(filename) xmltree = etree.parse(filename)
root = xmltree.getroot() root = xmltree.getroot()
solder_node = root[0] 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 env_count = 0
for temp_level in solder_node.findall("state"): for temp_level in solder_node.findall("state"):
tstr = temp_level.attrib["temperature"] 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)) dirlisting = filter(lambda x: os.path.splitext(x)[1] == ".xml", os.listdir(dirname))
self.listdata = [] self.listdata = []
for p in dirlisting: 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.listdata.sort(key=lambda x: x.name)
self.reset() self.reset()
@ -390,6 +482,7 @@ class TempLevelModel(QtCore.QAbstractTableModel):
assert isinstance(temp_levels, list) assert isinstance(temp_levels, list)
self.temp_levels = temp_levels self.temp_levels = temp_levels
self.reset() self.reset()
print self.setTempLevels
def clear(self): def clear(self):
@ -404,6 +497,14 @@ class Plotter(FigureCanvas):
self.fig = Figure(figsize=(width, height), dpi=dpi) self.fig = Figure(figsize=(width, height), dpi=dpi)
super(Plotter, self).__init__(self.fig) super(Plotter, self).__init__(self.fig)
self.axes = self.fig.add_subplot(111) 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_axis_bgcolor('white')
self.axes.set_title(u'reflow profile', size=12) self.axes.set_title(u'reflow profile', size=12)
@ -432,20 +533,19 @@ class Plotter(FigureCanvas):
def update_figure(self): def update_figure(self):
if self.updated: if self.updated:
updated = False self.updated = False
self.axes.patches = list() self.axes.patches = list()
self.axes.texts = list() self.axes.texts = list()
self.x = list() self.x = list()
self.y = list() self.y = list()
try: self.x, self.y, self.xmax, self.ymax, self.used, self.unused = self.solder.calc_profile()
self.x, self.y, self.xmax, self.ymax, self.duration_points, self.rate_points = self.solder.calc_profile()
for ix, (a, b) in enumerate(zip(self.x[:-1], self.y[:-1])): 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) slope = (self.y[ix+1] - b) / (self.x[ix+1] - a)
except Exception, e: if not (numpy.isnan(slope) or numpy.isinf(slope)):
self.xmax = 500 origin = (a + 10, b)
self.ymax = 300 annotation.slope_marker(origin, slope, ax=self.axes)
self.plot_data.set_xdata(self.x) self.plot_data.set_xdata(self.x)
self.plot_data.set_ydata(self.y) 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_xbound(lower=0, upper=self.xmax + 20)
self.axes.set_ybound(lower=0, upper=self.ymax + 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) self.axes.set_xticks(self.x)
#duration_widget = self.myapp.duration_widget #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) transform=self.axes.transData, figure=self.fig, color=str(temp_level.color.name()), label="name", zorder=1)
lines.append(line) lines.append(line)
self.axes.legend(("Estimated profile",)) self.axes.legend(("Estimated profile",), loc=2)
self.draw() self.draw()
def solder_changed(self): def solder_changed(self):
self.solder.changed = True self.solder.changed = True
self.updated = True
def setData(self, solder): def setData(self, solder):
self.solder = solder self.solder = solder
@ -731,9 +832,11 @@ class DurationConstraintWidget(ConstraintWidget):
def _set_data(self, solder): def _set_data(self, solder):
self.spinbox_block = True self.spinbox_block = True
self.constraint_model.constraint_list = solder.durations self.constraint_model.constraint_list = solder.durations
self.constraint_model.reset()
ix = self.constraint_model.index(0, 0) ix = self.constraint_model.index(0, 0)
self._constraint_selected(ix) self._constraint_selected(ix)
self.constraint_view.setCurrentIndex(ix) self.constraint_view.setCurrentIndex(ix)
print self._set_data
def _constraint_selected(self, index): def _constraint_selected(self, index):
if index.isValid(): if index.isValid():
@ -743,8 +846,9 @@ class DurationConstraintWidget(ConstraintWidget):
self.controls.value.setValue(value) self.controls.value.setValue(value)
else: else:
self.spinbox_block = True self.spinbox_block = True
self.selected_temp_levels.setTempLevels([]) self.selected_temp_levels.setTempLevels(list())
self.controls.value.setValue(0) self.controls.value.setValue(0)
print self._constraint_selected
class OvenControlsWidget(QtGui.QWidget): class OvenControlsWidget(QtGui.QWidget):
@ -812,7 +916,7 @@ class RateConstraintWidget(ConstraintWidget):
def _set_data(self, solder): def _set_data(self, solder):
self.spinbox_block = True self.spinbox_block = True
self.constraint_model.constraint_list = solder.rates self.constraint_model.constraint_list = solder.rates
self.constraint_model.reset()
ix = self.constraint_model.index(0, 0) ix = self.constraint_model.index(0, 0)
self._constraint_selected(ix) self._constraint_selected(ix)
self.constraint_view.setCurrentIndex(ix) self.constraint_view.setCurrentIndex(ix)
@ -948,6 +1052,12 @@ class TempLevelWidget(QtGui.QWidget):
#self.controls.add_button.setEnabled(not is_end) #self.controls.add_button.setEnabled(not is_end)
self.controls.remove_button.setEnabled(not is_env) 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): class ApplicationWindow(QtGui.QMainWindow):
def __init__(self): def __init__(self):
QtGui.QMainWindow.__init__(self) QtGui.QMainWindow.__init__(self)
@ -1033,6 +1143,16 @@ class ApplicationWindow(QtGui.QMainWindow):
QtCore.SIGNAL("solder_changed()"), QtCore.SIGNAL("solder_changed()"),
self.plotter.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.solder_widget = SolderWidget(self)
self.connect( self.connect(
@ -1048,11 +1168,18 @@ class ApplicationWindow(QtGui.QMainWindow):
self.splitter = QtGui.QSplitter(QtCore.Qt.Vertical, self) 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.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.settings_widget)
self.splitter.addWidget(self.controls_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(0, 2)
self.splitter.setStretchFactor(1, 2) self.splitter.setStretchFactor(1, 2)
self.splitter.setStretchFactor(2, 8) self.splitter.setStretchFactor(2, 8)
@ -1082,10 +1209,13 @@ class ApplicationWindow(QtGui.QMainWindow):
if index.isValid(): if index.isValid():
solder = self.solder_widget.solder_model.listdata[index.row()] solder = self.solder_widget.solder_model.listdata[index.row()]
self.temp_level_widget.setData(solder) self.temp_level_widget.setData(solder)
print "pre duration"
self.duration_widget.setData(solder) self.duration_widget.setData(solder)
print "post duration"
self.rate_widget.setData(solder) self.rate_widget.setData(solder)
self.plotter.setData(solder) self.plotter.setData(solder)
self.controls_widget.temp_level_widget.setData(solder) self.controls_widget.temp_level_widget.setData(solder)
solder.log_message.connect(self.profile_log.setPlainText)
def open_controls_view(self): def open_controls_view(self):
print self.open_controls_view print self.open_controls_view