logging, more events, some bugs/regressions fixed
This commit is contained in:
parent
6d8e7580c0
commit
5fbba2a585
|
@ -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
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue