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 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
|
||||||
|
|
Loading…
Reference in New Issue