long running fits made abortable

This commit is contained in:
Markus Rosenstihl 2014-04-16 17:56:32 +02:00
parent 67fbeffb6f
commit a36f8932f8
12 changed files with 78 additions and 33 deletions

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'ConductivityGroupBox.ui'
#
# Created: Tue Apr 15 15:17:02 2014
# Created: Wed Apr 16 14:28:54 2014
# by: PyQt4 UI code generator 4.10.4
#
# WARNING! All changes made in this file will be lost!

View File

@ -1,6 +1,6 @@
# -*- encoding: utf8 -*-
from PyQt4.QtCore import QObject, pyqtSignal, Qt
from PyQt4.QtCore import QObject, Qt, pyqtSignal, pyqtSlot
from PyQt4.QtGui import QColor
import numpy as np
import pyqtgraph as pg
@ -45,6 +45,11 @@ class BaseObject(QObject):
self._sd_beta = None
self._selector_mask = None
self._param_number = 0
self._abort = False
@pyqtSlot(bool)
def abort(self, abort=False):
self._abort = abort
@property
def param_number(self):
@ -134,7 +139,8 @@ class BaseObject(QObject):
self.data_curve_imag.setData(x=[np.nan], y=[np.nan])
def function(self,p,x):
raise NotImplementedError, "This needs to be implemented in your subclass"
if self._abort: raise StopIteration
#raise NotImplementedError, "This needs to be implemented in your subclass"
class Conductivity(BaseObject):
@ -165,6 +171,7 @@ class PowerComplex(BaseObject):
self.param_number = 2
def function( self, p, x ):
BaseObject.function(self,p,x)
om = 2*np.pi*x
sgma,n = p
power = sgma/(om*1j)**n
@ -182,6 +189,8 @@ class Static(BaseObject):
self.param_number = 1
def function( self, p, x ):
BaseObject.function(self,p,x)
eps_inf = p[0]
static = np.ones( (2,x.size) )*eps_inf
static[1,:] *= 0 # set imag part zero
@ -201,6 +210,7 @@ class Peak(BaseObject):
self.param_number = 4
def function( self, p, x ):
BaseObject.function(self,p,x)
eps,t,a,b = p
om = 2*np.pi*x
hn = eps/(1+(1j*om*t)**a)**b
@ -242,6 +252,7 @@ class YAFF(BaseObject):
self.updateData()
def function( self, p, x ):
BaseObject.function(self,p,x)
ya = self._libyaff.loss( p, x)
cplx = np.array([ya.imag, ya.real])
return cplx

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'PeakGroupBox.ui'
#
# Created: Tue Apr 15 15:17:02 2014
# Created: Wed Apr 16 14:28:54 2014
# by: PyQt4 UI code generator 4.10.4
#
# WARNING! All changes made in this file will be lost!

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'PowerLawGroupBox.ui'
#
# Created: Tue Apr 15 15:17:02 2014
# Created: Wed Apr 16 14:28:54 2014
# by: PyQt4 UI code generator 4.10.4
#
# WARNING! All changes made in this file will be lost!

31
QDS.py
View File

@ -206,7 +206,9 @@ class AppWindow(QMainWindow):
def abortFit(self):
self._fit_thread.quit()
for container in self.function_registry.get_registered_functions():
container.abort(True)
self._fit_thread.terminate()
def saveFitResult(self):
"""
@ -347,7 +349,6 @@ class AppWindow(QMainWindow):
self.updatePlot()
def delParamterObject(self, obj):
print "unregister",obj
self.function_registry.unregister_function(obj)
self.updatePlot()
@ -405,13 +406,20 @@ class AppWindow(QMainWindow):
funcs.append(fcn)
fixed_params.extend(fcn.getFixed())
for container in self.function_registry.get_registered_functions():
container.abort(False)
self.data.set_fit(odr_result.beta, funcs)
self.ui.statusbar.showMessage(" ".join(odr_result.stopreason))
ndx = 0
for i,fcn in enumerate(self.function_registry.get_registered_functions()):
num_p = len(fcn.getParameter())
beta = odr_result.beta[ndx:num_p+ndx]
sd_beta = odr_result.sd_beta[ndx:num_p+ndx]
if odr_result.sd_beta is not None:
sd_beta = odr_result.sd_beta[ndx:num_p+ndx]
else:
sd_beta = None
fcn.setParameter(beta, sd_beta)
ndx += num_p
@ -469,12 +477,23 @@ class AppWindow(QMainWindow):
self.data.set_data(_freq, _die_stor, _die_loss)
self.data.meta["T"] = Temp
self.fit_boundary_imag.setRegion([np.log10(_freq.min()), np.log10(_freq.max())])
self.ui.pgPlotWidget_imag.enableAutoRange()
self.ui.pgPlotWidget_real.enableAutoRange()
self.updatePlot()
# self.ui.pgPlotWidget_imag.enableAutoRange()
# self.ui.pgPlotWidget_real.enableAutoRange()
self.ui.pgPlotWidget_imag.disableAutoRange()
self.ui.pgPlotWidget_real.disableAutoRange()
self.ui.pgPlotWidget_imag.setXRange(np.log10(_freq.min()), np.log10(_freq.max()))
self.ui.pgPlotWidget_imag.setYRange(np.log10(_die_loss.min()), np.log10(_die_loss.max()))
self.ui.pgPlotWidget_real.setXRange(np.log10(_freq.min()), np.log10(_freq.max()))
self.ui.pgPlotWidget_real.setYRange(np.log10(_die_stor.min()), np.log10(_die_stor.max()))
#self.ui.pgPlotWidget_real.setRange(xRange=(_freq.min(), _freq.max()),
# yRange=(_die_stor.min(), _die_stor.max()) )
self.updatePlot()
def updatePlot(self):
log10fmin, log10fmax = self.fit_boundary_imag.getRegion()

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'QDSMain.ui'
#
# Created: Tue Apr 15 15:17:02 2014
# Created: Wed Apr 16 14:28:54 2014
# by: PyQt4 UI code generator 4.10.4
#
# WARNING! All changes made in this file will be lost!

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'StaticGroupBox.ui'
#
# Created: Tue Apr 15 15:17:03 2014
# Created: Wed Apr 16 14:28:54 2014
# by: PyQt4 UI code generator 4.10.4
#
# WARNING! All changes made in this file will be lost!

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'YAFFConfig.ui'
#
# Created: Tue Apr 15 15:17:03 2014
# Created: Wed Apr 16 14:28:55 2014
# by: PyQt4 UI code generator 4.10.4
#
# WARNING! All changes made in this file will be lost!

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'YAFFparameters.ui'
#
# Created: Tue Apr 15 15:17:03 2014
# Created: Wed Apr 16 14:28:55 2014
# by: PyQt4 UI code generator 4.10.4
#
# WARNING! All changes made in this file will be lost!
@ -26,7 +26,7 @@ except AttributeError:
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName(_fromUtf8("Form"))
Form.resize(271, 322)
Form.resize(300, 322)
self.gridLayout = QtGui.QGridLayout(Form)
self.gridLayout.setMargin(0)
self.gridLayout.setSpacing(1)
@ -268,12 +268,12 @@ class Ui_Form(object):
def retranslateUi(self, Form):
Form.setWindowTitle(_translate("Form", "Form", None))
self.label_422.setText(_translate("Form", "b", None))
self.label_422.setText(_translate("Form", "β", None))
self.label_10.setText(_translate("Form", "TextLabel", None))
self.label_111.setText(_translate("Form", "eps", None))
self.label_111.setText(_translate("Form", "Δε", None))
self.label_4.setText(_translate("Form", "TextLabel", None))
self.label_5.setText(_translate("Form", "TextLabel", None))
self.label_522.setText(_translate("Form", "lambda", None))
self.label_522.setText(_translate("Form", "λ", None))
self.label_112.setText(_translate("Form", "s", None))
self.label_9.setText(_translate("Form", "TextLabel", None))
self.label_6.setText(_translate("Form", "TextLabel", None))
@ -281,13 +281,13 @@ class Ui_Form(object):
self.label_huh.setText(_translate("Form", "TextLabel", None))
self.label_2.setText(_translate("Form", "TextLabel", None))
self.label_102.setText(_translate("Form", "g", None))
self.label_222.setText(_translate("Form", "tau_a", None))
self.label_322.setText(_translate("Form", "a", None))
self.label_222.setText(_translate("Form", "<html><head/><body><p>τ<span style=\" vertical-align:sub;\">α</span></p></body></html>", None))
self.label_322.setText(_translate("Form", "α", None))
self.label_8.setText(_translate("Form", "TextLabel", None))
self.label_1.setText(_translate("Form", "TextLabel", None))
self.label_3.setText(_translate("Form", "TextLabel", None))
self.label_82.setText(_translate("Form", "b", None))
self.label_622.setText(_translate("Form", "tau_b", None))
self.label_622.setText(_translate("Form", "<html><head/><body><p>τ<span style=\" vertical-align:sub;\">β</span></p></body></html>", None))
self.label_7.setText(_translate("Form", "TextLabel", None))
self.label_72.setText(_translate("Form", "a", None))
self.label_23.setText(_translate("Form", "Fix", None))

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>271</width>
<width>300</width>
<height>322</height>
</rect>
</property>
@ -37,7 +37,7 @@
<item row="7" column="0">
<widget class="QLabel" name="label_422">
<property name="text">
<string>b</string>
<string>β</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -73,7 +73,7 @@
<item row="2" column="0">
<widget class="QLabel" name="label_111">
<property name="text">
<string>eps</string>
<string>Δε</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -112,7 +112,7 @@
<item row="8" column="0">
<widget class="QLabel" name="label_522">
<property name="text">
<string>lambda</string>
<string>λ</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -208,7 +208,7 @@
<item row="3" column="0">
<widget class="QLabel" name="label_222">
<property name="text">
<string>tau_a</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;τ&lt;span style=&quot; vertical-align:sub;&quot;&gt;α&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -218,7 +218,7 @@
<item row="5" column="0">
<widget class="QLabel" name="label_322">
<property name="text">
<string>a</string>
<string>α</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -287,7 +287,7 @@
<item row="9" column="0">
<widget class="QLabel" name="label_622">
<property name="text">
<string>tau_b</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;τ&lt;span style=&quot; vertical-align:sub;&quot;&gt;β&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>

View File

@ -2,7 +2,7 @@
# Resource object code
#
# Created: Di. Apr. 15 15:17:02 2014
# Created: Mi. Apr. 16 14:28:54 2014
# by: The Resource Compiler for PyQt (Qt v4.8.5)
#
# WARNING! All changes made in this file will be lost!

View File

@ -48,6 +48,7 @@ class FitFunctionCreator(QObject):
if x.ndim == 2:
x = x[0]
result = f(p, x)
#fn.widget.updateTable(p)
self.data += result # fit functions take only 1-dim x
ndx += num_p
self.new_data.emit(x, self.data)
@ -74,13 +75,21 @@ class FitFunctionCreator(QObject):
class FitRoutine(QObject):
finished_fit = pyqtSignal()
data_ready = pyqtSignal(np.ndarray, np.ndarray)
def __init__(self):
super(FitRoutine,self).__init__()
self.f = FitFunctionCreator()
self.f.new_data.connect(self.data_ready.emit)
self._fitter = self.fit_odr_cmplx
self._odr_fit = None
self._start_parameter = None
@property
def start_parameter(self):
return self._start_parameter
@start_parameter.setter
def start_paramter(self, p0):
self._start_parameter = p0
@property
def fitter(self):
return self._fitter
@ -90,8 +99,7 @@ class FitRoutine(QObject):
self._fitter = f
def fit_odr_cmplx(self, x, y, p0, fixed, fcns):
#if x.ndim < 2:
# x = N.resize(x, (2,x.size))
self._start_parameter = p0
if np.iscomplexobj(y) and y.ndim == 1:
weights = 1/np.abs(y)**2
we = np.resize(weights, (2, weights.size))
@ -104,6 +112,7 @@ class FitRoutine(QObject):
self._odr_fit = odr.ODR(dat, mod, p0, ifixx=(0,), ifixb=fixed, maxit=800)
def fit_odr_imag(self, x, y, p0, fixed, fcns):
self._start_parameter = p0
if np.iscomplexobj(y) and y.ndim == 1:
we = 1/np.imag(y)**2
else:
@ -115,10 +124,16 @@ class FitRoutine(QObject):
@pyqtSlot()
def fit(self):
#print "TID in FitRoutine", QThread.thread()
self._odr_fit.run()
try:
self._odr_fit.run()
except RuntimeError:
print "muh"
self.finished_fit.emit()
def result(self):
if self._odr_fit.output is None:
self._odr_fit.output = odr.Output([self.start_parameter, None, None ])
self._odr_fit.output.stopreason = ["Aborted by user"]
return self._odr_fit.output