From a36f8932f818aaaf3d05e13a78c9d5712f5190e6 Mon Sep 17 00:00:00 2001
From: Markus Rosenstihl
Date: Wed, 16 Apr 2014 17:56:32 +0200
Subject: [PATCH] long running fits made abortable
---
ConductivityGroupBox.py | 2 +-
Container.py | 15 +++++++++++++--
PeakGroupBox.py | 2 +-
PowerLawGroupBox.py | 2 +-
QDS.py | 31 +++++++++++++++++++++++++------
QDSMain.py | 2 +-
StaticGroupBox.py | 2 +-
YAFFConfig.py | 2 +-
YAFFparameters.py | 16 ++++++++--------
YAFFparameters.ui | 14 +++++++-------
images_rc.py | 2 +-
mathlib.py | 21 ++++++++++++++++++---
12 files changed, 78 insertions(+), 33 deletions(-)
diff --git a/ConductivityGroupBox.py b/ConductivityGroupBox.py
index 0839720..3431099 100644
--- a/ConductivityGroupBox.py
+++ b/ConductivityGroupBox.py
@@ -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!
diff --git a/Container.py b/Container.py
index 85a3406..920f851 100644
--- a/Container.py
+++ b/Container.py
@@ -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
\ No newline at end of file
diff --git a/PeakGroupBox.py b/PeakGroupBox.py
index d0a92eb..ca5973b 100644
--- a/PeakGroupBox.py
+++ b/PeakGroupBox.py
@@ -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!
diff --git a/PowerLawGroupBox.py b/PowerLawGroupBox.py
index 8d6f6c1..2a9d71e 100644
--- a/PowerLawGroupBox.py
+++ b/PowerLawGroupBox.py
@@ -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!
diff --git a/QDS.py b/QDS.py
index 2222ada..70382a8 100755
--- a/QDS.py
+++ b/QDS.py
@@ -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()
diff --git a/QDSMain.py b/QDSMain.py
index dec1a3b..1cf385f 100644
--- a/QDSMain.py
+++ b/QDSMain.py
@@ -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!
diff --git a/StaticGroupBox.py b/StaticGroupBox.py
index 2e8605d..5657101 100644
--- a/StaticGroupBox.py
+++ b/StaticGroupBox.py
@@ -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!
diff --git a/YAFFConfig.py b/YAFFConfig.py
index a2c190b..5a8ffca 100644
--- a/YAFFConfig.py
+++ b/YAFFConfig.py
@@ -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!
diff --git a/YAFFparameters.py b/YAFFparameters.py
index 6c61bcb..083ac1e 100644
--- a/YAFFparameters.py
+++ b/YAFFparameters.py
@@ -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", "
τα
", 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", "τβ
", 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))
diff --git a/YAFFparameters.ui b/YAFFparameters.ui
index bb165ec..ed8fa34 100644
--- a/YAFFparameters.ui
+++ b/YAFFparameters.ui
@@ -6,7 +6,7 @@
0
0
- 271
+ 300
322
@@ -37,7 +37,7 @@
-
- b
+ β
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
@@ -73,7 +73,7 @@
-
- eps
+ Δε
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
@@ -112,7 +112,7 @@
-
- lambda
+ λ
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
@@ -208,7 +208,7 @@
-
- tau_a
+ <html><head/><body><p>τ<span style=" vertical-align:sub;">α</span></p></body></html>
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
@@ -218,7 +218,7 @@
-
- a
+ α
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
@@ -287,7 +287,7 @@
-
- tau_b
+ <html><head/><body><p>τ<span style=" vertical-align:sub;">β</span></p></body></html>
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
diff --git a/images_rc.py b/images_rc.py
index 25d5c10..8984e49 100644
--- a/images_rc.py
+++ b/images_rc.py
@@ -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!
diff --git a/mathlib.py b/mathlib.py
index 9120166..5cce244 100644
--- a/mathlib.py
+++ b/mathlib.py
@@ -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