delete and save solders are more robust now, added slope_marker issue workaround for numpy.log10
This commit is contained in:
parent
55581d4063
commit
ccf7ceb037
|
@ -109,8 +109,9 @@ class Solder(QtCore.QObject):
|
||||||
|
|
||||||
log_message = QtCore.pyqtSignal(str)
|
log_message = QtCore.pyqtSignal(str)
|
||||||
|
|
||||||
def __init__(self, name=str(), description=str(), parent=None):
|
def __init__(self, filename, name=str(), description=str(), parent=None):
|
||||||
super(Solder, self).__init__(parent)
|
super(Solder, self).__init__(parent)
|
||||||
|
self.filename = filename
|
||||||
self.name = name
|
self.name = name
|
||||||
self.description = description
|
self.description = description
|
||||||
self.temp_levels = list()
|
self.temp_levels = list()
|
||||||
|
@ -221,81 +222,21 @@ class Solder(QtCore.QObject):
|
||||||
elif len(rate_x) > 0:
|
elif len(rate_x) > 0:
|
||||||
x.extend(rate_x)
|
x.extend(rate_x)
|
||||||
y.extend(rate_y)
|
y.extend(rate_y)
|
||||||
else:
|
elif temp_level not in used:
|
||||||
if temp_level not in used:
|
unused.append(temp_level)
|
||||||
unused.append(temp_level)
|
|
||||||
|
|
||||||
self.log.append("")
|
self.log.append("")
|
||||||
map(self.log.append, ["* Missing Connection: %r" % tl.name for tl in unused])
|
map(self.log.append, ["* Missing Connection: %r" % tl.name for tl in unused])
|
||||||
self.log_message.emit("\n".join(self.log))
|
self.log_message.emit("\n".join(self.log))
|
||||||
del self.log
|
del self.log
|
||||||
return array(map(float, x)), array(map(float, y)), max(x), max(y), used, unused
|
return array(map(float, x)), array(map(float, y)), min(x), max(x), min(y), max(y), used, unused
|
||||||
|
|
||||||
def calc_profile_old(self):
|
|
||||||
|
|
||||||
x = list()
|
|
||||||
y = list()
|
|
||||||
duration_points = dict()
|
|
||||||
rate_points = dict()
|
|
||||||
self.time = 0
|
|
||||||
used_temp_levels = set()
|
|
||||||
for ix, temp_level in enumerate(self.temp_levels):
|
|
||||||
if temp_level != self.temp_levels[0] and temp_level not in used_temp_levels:
|
|
||||||
ix = self.temp_levels.index(temp_level)
|
|
||||||
raise ValueError("TempLevel %r not connected to %r" % (self.temp_levels[ix-1].name, self.temp_levels[ix].name))
|
|
||||||
|
|
||||||
temp_levels = None
|
|
||||||
duration = None
|
|
||||||
for sts, dur in self.durations:
|
|
||||||
if sts and sts[0] == temp_level:
|
|
||||||
duration = dur
|
|
||||||
temp_levels = sts
|
|
||||||
break
|
|
||||||
|
|
||||||
if temp_level not in used_temp_levels:
|
|
||||||
used_temp_levels.add(temp_level)
|
|
||||||
x.append(self.time)
|
|
||||||
y.append(temp_level.temp)
|
|
||||||
|
|
||||||
if duration is not None:
|
|
||||||
if len(temp_levels) == 3:
|
|
||||||
used_temp_levels.add(temp_levels[1])
|
|
||||||
used_temp_levels.add(temp_levels[2])
|
|
||||||
|
|
||||||
self.time += duration / 2
|
|
||||||
x.append(self.time)
|
|
||||||
y.append(temp_levels[1].temp)
|
|
||||||
|
|
||||||
self.time += duration / 2
|
|
||||||
x.append(self.time)
|
|
||||||
y.append(temp_levels[2].temp)
|
|
||||||
|
|
||||||
duration_points[ix] = (x[-3:], y[-3:])
|
|
||||||
else:
|
|
||||||
y.append(temp_levels[1].temp)
|
|
||||||
used_temp_levels.add(temp_levels[1])
|
|
||||||
self.time += duration
|
|
||||||
x.append(self.time)
|
|
||||||
duration_points[ix] = (x[-2:], y[-2:])
|
|
||||||
else:
|
|
||||||
for ex, (sts, rate) in enumerate(self.rates):
|
|
||||||
if sts and sts[0] == temp_level:
|
|
||||||
used_temp_levels.add(sts[1])
|
|
||||||
duration = (sts[1].temp - temp_level.temp) / rate
|
|
||||||
self.time += duration
|
|
||||||
x.append(self.time)
|
|
||||||
y.append(sts[1].temp)
|
|
||||||
rate_points[ex] = (x[-2:], y[-2:])
|
|
||||||
|
|
||||||
return array(map(float, x)), array(map(float, y)), max(x), max(y), duration_points, rate_points
|
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def unpack(filename, parent):
|
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"], parent)
|
s = Solder(filename, 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"]
|
||||||
|
@ -324,7 +265,7 @@ class Solder(QtCore.QObject):
|
||||||
|
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def save(self, filename):
|
def save(self):
|
||||||
if self.changed:
|
if self.changed:
|
||||||
solder_node = etree.Element("solder_type", {"name" : self.name, "description" : self.description})
|
solder_node = etree.Element("solder_type", {"name" : self.name, "description" : self.description})
|
||||||
for temp_level in self.temp_levels:
|
for temp_level in self.temp_levels:
|
||||||
|
@ -344,9 +285,13 @@ class Solder(QtCore.QObject):
|
||||||
dirname = os.path.join(os.path.dirname(__file__), "solder_types")
|
dirname = os.path.join(os.path.dirname(__file__), "solder_types")
|
||||||
root = etree.Element("xml")
|
root = etree.Element("xml")
|
||||||
root.append(solder_node)
|
root.append(solder_node)
|
||||||
etree.ElementTree(root).write(os.path.join(dirname, self.name + ".xml"), "UTF-8", True)
|
etree.ElementTree(root).write(self.filename, "UTF-8", True)
|
||||||
self.changed = False
|
self.changed = False
|
||||||
|
|
||||||
|
def setChanged(self):
|
||||||
|
print self.setChanged
|
||||||
|
self.changed = True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SolderListModel(QtCore.QAbstractListModel):
|
class SolderListModel(QtCore.QAbstractListModel):
|
||||||
|
@ -375,15 +320,16 @@ class SolderListModel(QtCore.QAbstractListModel):
|
||||||
return QtCore.QVariant()
|
return QtCore.QVariant()
|
||||||
|
|
||||||
def data(self, index, role):
|
def data(self, index, role):
|
||||||
if index.isValid() and role == QtCore.Qt.DisplayRole:
|
if not index.isValid():
|
||||||
solder = self.listdata[index.row()]
|
|
||||||
if solder.changed:
|
|
||||||
return QtCore.QVariant(solder.name + " *")
|
|
||||||
else:
|
|
||||||
return QtCore.QVariant(solder.name)
|
|
||||||
else:
|
|
||||||
return QtCore.QVariant()
|
return QtCore.QVariant()
|
||||||
|
|
||||||
|
solder = self.listdata[index.row()]
|
||||||
|
if role == QtCore.Qt.DisplayRole:
|
||||||
|
return QtCore.QVariant(solder.name)
|
||||||
|
|
||||||
|
elif role == QtCore.Qt.DecorationRole and solder.changed:
|
||||||
|
return QtGui.QIcon.fromTheme("document-save")
|
||||||
|
|
||||||
def setData(self, index, variant, role):
|
def setData(self, index, variant, role):
|
||||||
if index.isValid() and role == QtCore.Qt.EditRole:
|
if index.isValid() and role == QtCore.Qt.EditRole:
|
||||||
new_name = str(variant.toString())
|
new_name = str(variant.toString())
|
||||||
|
@ -458,6 +404,7 @@ class TempLevelModel(QtCore.QAbstractTableModel):
|
||||||
self.temp_levels[index.row()].name = str(variant.toString())
|
self.temp_levels[index.row()].name = str(variant.toString())
|
||||||
elif col == 1:
|
elif col == 1:
|
||||||
self.temp_levels[index.row()].temp = variant.toInt()[0]
|
self.temp_levels[index.row()].temp = variant.toInt()[0]
|
||||||
|
print "emit solder_changed"
|
||||||
self.solder_changed.emit()
|
self.solder_changed.emit()
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
@ -525,9 +472,10 @@ class Plotter(FigureCanvas):
|
||||||
|
|
||||||
QtCore.QObject.connect(timer, QtCore.SIGNAL("timeout()"), self.update_figure)
|
QtCore.QObject.connect(timer, QtCore.SIGNAL("timeout()"), self.update_figure)
|
||||||
timer.start(1000)
|
timer.start(1000)
|
||||||
self.updated = True
|
self.updated = False
|
||||||
|
|
||||||
def update_figure(self):
|
def update_figure(self):
|
||||||
|
self.fig.lines = lines = list()
|
||||||
if self.updated:
|
if self.updated:
|
||||||
self.updated = False
|
self.updated = False
|
||||||
self.axes.patches = list()
|
self.axes.patches = list()
|
||||||
|
@ -535,7 +483,16 @@ class Plotter(FigureCanvas):
|
||||||
self.x = list()
|
self.x = list()
|
||||||
self.y = list()
|
self.y = list()
|
||||||
|
|
||||||
self.x, self.y, self.xmax, self.ymax, self.used, self.unused = self.solder.calc_profile()
|
self.x, self.y, self.xmin, self.xmax, self.ymin, self.ymax, self.used, self.unused = self.solder.calc_profile()
|
||||||
|
|
||||||
|
self.plot_data.set_xdata(self.x)
|
||||||
|
self.plot_data.set_ydata(self.y)
|
||||||
|
|
||||||
|
self.axes.set_xbound(lower=self.xmin, upper=self.xmax + 20)
|
||||||
|
self.axes.set_ybound(lower=self.ymin, upper=self.ymax + 20)
|
||||||
|
|
||||||
|
self.axes.set_yticks(self.y)
|
||||||
|
self.axes.set_xticks(self.x)
|
||||||
|
|
||||||
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])):
|
||||||
slope = (self.y[ix+1] - b) / (self.x[ix+1] - a)
|
slope = (self.y[ix+1] - b) / (self.x[ix+1] - a)
|
||||||
|
@ -543,32 +500,19 @@ class Plotter(FigureCanvas):
|
||||||
origin = (a + 10, b)
|
origin = (a + 10, b)
|
||||||
annotation.slope_marker(origin, slope, ax=self.axes)
|
annotation.slope_marker(origin, slope, ax=self.axes)
|
||||||
|
|
||||||
self.plot_data.set_xdata(self.x)
|
self.axes.legend(("Estimated profile",), loc=2)
|
||||||
self.plot_data.set_ydata(self.y)
|
|
||||||
|
|
||||||
self.axes.set_xbound(lower=0, upper=self.xmax + 20)
|
|
||||||
self.axes.set_ybound(lower=0, upper=self.ymax + 20)
|
|
||||||
|
|
||||||
self.axes.set_yticks(self.y)
|
|
||||||
self.axes.set_xticks(self.x)
|
|
||||||
|
|
||||||
#duration_widget = self.myapp.duration_widget
|
|
||||||
|
|
||||||
#self.selection_data.set_xdata(array(da))
|
|
||||||
#self.selection_data.set_ydata(array(db))
|
|
||||||
|
|
||||||
self.fig.lines = lines = list()
|
|
||||||
for temp_level in self.solder.temp_levels:
|
for temp_level in self.solder.temp_levels:
|
||||||
if not temp_level.is_env:
|
if not temp_level.is_env:
|
||||||
line = Line2D([0, self.xmax + 20], [temp_level.temp, temp_level.temp],
|
line = Line2D([0, self.xmax + 20], [temp_level.temp, temp_level.temp],
|
||||||
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",), loc=2)
|
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
def solder_changed(self):
|
def solder_changed(self):
|
||||||
self.solder.changed = True
|
print self.solder_changed
|
||||||
|
self.solder.setChanged()
|
||||||
self.updated = True
|
self.updated = True
|
||||||
|
|
||||||
def setData(self, solder):
|
def setData(self, solder):
|
||||||
|
@ -955,6 +899,7 @@ class TempLevelWidget(QtGui.QWidget):
|
||||||
|
|
||||||
def __init__(self, parent, readonly=False):
|
def __init__(self, parent, readonly=False):
|
||||||
super(TempLevelWidget, self).__init__(parent)
|
super(TempLevelWidget, self).__init__(parent)
|
||||||
|
self.readonly = readonly
|
||||||
self.temp_level_model = TempLevelModel(self)
|
self.temp_level_model = TempLevelModel(self)
|
||||||
|
|
||||||
self.temp_level_view = QtGui.QTableView()
|
self.temp_level_view = QtGui.QTableView()
|
||||||
|
@ -1003,6 +948,7 @@ class TempLevelWidget(QtGui.QWidget):
|
||||||
self._solder_changed)
|
self._solder_changed)
|
||||||
|
|
||||||
def _solder_changed(self):
|
def _solder_changed(self):
|
||||||
|
print self._solder_changed
|
||||||
self.solder_changed.emit()
|
self.solder_changed.emit()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1066,6 +1012,10 @@ class ApplicationWindow(QtGui.QMainWindow):
|
||||||
QtCore.Qt.CTRL + QtCore.Qt.Key_C)
|
QtCore.Qt.CTRL + QtCore.Qt.Key_C)
|
||||||
self.file_menu.addAction('&Save solder', self.save_solder,
|
self.file_menu.addAction('&Save solder', self.save_solder,
|
||||||
QtCore.Qt.CTRL + QtCore.Qt.Key_S)
|
QtCore.Qt.CTRL + QtCore.Qt.Key_S)
|
||||||
|
self.file_menu.addAction('&Reload solder', self.reload_solder,
|
||||||
|
QtCore.Qt.CTRL + QtCore.Qt.Key_R)
|
||||||
|
self.file_menu.addAction('&Delete solder', self.remove_solder,
|
||||||
|
QtCore.Qt.CTRL + QtCore.Qt.Key_D)
|
||||||
self.file_menu.addAction('S&ave plot', self.save_plot,
|
self.file_menu.addAction('S&ave plot', self.save_plot,
|
||||||
QtCore.Qt.CTRL + QtCore.Qt.Key_A)
|
QtCore.Qt.CTRL + QtCore.Qt.Key_A)
|
||||||
self.file_menu.addAction('&Quit', self.fileQuit,
|
self.file_menu.addAction('&Quit', self.fileQuit,
|
||||||
|
@ -1113,7 +1063,7 @@ class ApplicationWindow(QtGui.QMainWindow):
|
||||||
self.temp_level_widget = TempLevelWidget(self)
|
self.temp_level_widget = TempLevelWidget(self)
|
||||||
self.duration_widget = DurationConstraintWidget(u"Duration (s)")
|
self.duration_widget = DurationConstraintWidget(u"Duration (s)")
|
||||||
self.rate_widget = RateConstraintWidget(u"Rate (°C/s)")
|
self.rate_widget = RateConstraintWidget(u"Rate (°C/s)")
|
||||||
self.tab_widget.addTab(self.temp_level_widget, u"Temperature Levels")
|
self.tab_widget.addTab(self.temp_level_widget, u"Temperature Levels (°C)")
|
||||||
self.tab_widget.addTab(self.duration_widget, u"Duration (s)")
|
self.tab_widget.addTab(self.duration_widget, u"Duration (s)")
|
||||||
self.tab_widget.addTab(self.rate_widget, u"Rate (°C/s)")
|
self.tab_widget.addTab(self.rate_widget, u"Rate (°C/s)")
|
||||||
|
|
||||||
|
@ -1210,6 +1160,16 @@ class ApplicationWindow(QtGui.QMainWindow):
|
||||||
self.controls_widget.temp_level_widget.setData(solder)
|
self.controls_widget.temp_level_widget.setData(solder)
|
||||||
solder.log_message.connect(self.profile_log.setPlainText)
|
solder.log_message.connect(self.profile_log.setPlainText)
|
||||||
|
|
||||||
|
def remove_solder(self):
|
||||||
|
index = self.solder_widget.solder_view.currentIndex()
|
||||||
|
solder = self.solder_widget.solder_model.listdata[index.row()]
|
||||||
|
del self.solder_widget.solder_model.listdata[index.row()]
|
||||||
|
self.solder_widget.solder_model.reset()
|
||||||
|
new_index = self.solder_widget.solder_model.index(0)
|
||||||
|
self.solder_widget.solder_view.setCurrentIndex(new_index)
|
||||||
|
self.solder_selected(new_index)
|
||||||
|
os.remove(solder.filename)
|
||||||
|
|
||||||
def open_controls_view(self):
|
def open_controls_view(self):
|
||||||
self.controls_widget.show()
|
self.controls_widget.show()
|
||||||
self.settings_widget.hide()
|
self.settings_widget.hide()
|
||||||
|
@ -1225,9 +1185,18 @@ class ApplicationWindow(QtGui.QMainWindow):
|
||||||
self.plotter.print_figure(str(filename), dpi=self.dpi)
|
self.plotter.print_figure(str(filename), dpi=self.dpi)
|
||||||
|
|
||||||
def save_solder(self):
|
def save_solder(self):
|
||||||
self.plotter.solder.save("foo")
|
self.plotter.solder.save()
|
||||||
self.solder_widget.solder_model.reload()
|
self.solder_widget.solder_model.reload()
|
||||||
|
|
||||||
|
def reload_solder(self):
|
||||||
|
old_index = self.solder_widget.solder_view.currentIndex()
|
||||||
|
solder = Solder.unpack(self.plotter.solder.filename, self.solder_widget.solder_model)
|
||||||
|
self.solder_widget.solder_model.listdata[old_index.row()] = solder
|
||||||
|
self.solder_widget.solder_model.reset()
|
||||||
|
new_index = self.solder_widget.solder_model.index(old_index.row(), 0)
|
||||||
|
self.solder_widget.solder_view.setCurrentIndex(new_index)
|
||||||
|
self.solder_selected(new_index)
|
||||||
|
|
||||||
def fileQuit(self):
|
def fileQuit(self):
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
|
@ -1243,6 +1212,12 @@ class ApplicationWindow(QtGui.QMainWindow):
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
|
# numpy bug workaround
|
||||||
|
try:
|
||||||
|
numpy.log10(0.0)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
qApp = QtGui.QApplication(sys.argv)
|
qApp = QtGui.QApplication(sys.argv)
|
||||||
|
|
||||||
aw = ApplicationWindow()
|
aw = ApplicationWindow()
|
||||||
|
|
Loading…
Reference in New Issue