started to decouple fit routine from ui

This commit is contained in:
Markus Rosenstihl 2014-04-07 13:41:39 +02:00
parent d356585a7e
commit 4a206c0eb6
5 changed files with 202 additions and 181 deletions

59
QDS.py
View File

@ -9,7 +9,7 @@ from PyQt4.QtCore import *
from PyQt4.QtGui import *
import matplotlib
from mathlib import fit_anneal, fit_lbfgsb, fit_odr_cmplx, FunctionRegister
from mathlib import fit_anneal, fit_lbfgsb, fit_odr_cmplx, FunctionRegister, FitRoutine
matplotlib.use('agg')
@ -87,6 +87,17 @@ class AppWindow(QMainWindow):
fit_yaff = QAction("&Fit", self)
yaffMenu.addAction(fit_yaff)
self._fit_thread = QThread()
# self._fit_method = FitRoutine()
# self._fit_method.moveToThread(self._fit_thread)
# self._fit_method.finished.connect(self._fit_thread.quit)
# self._fit_queue = QEventLoop()
# self._fit_timer = QTimer()
# self._fit_timer.setSingleShot(True)
# self._fit_timer.timeout.connect(self._fit_queue.quit)
# self._fit_method.finished.connect(self._fit_queue.quit)
self.signalMapper = QSignalMapper(self)
for i, fit_action in enumerate([fit_lmAction, fit_lbfgsbAction, fit_annealAction
]):
@ -284,7 +295,7 @@ class AppWindow(QMainWindow):
_yaff.removeObj.connect(self.delParamterObject)
gg_y = 10**pos.y()
gg_x = 10**pos.x()*2*N.pi
yaff_par = [ gg_y, gg_x , 1.0, 1.0, 0.5, gg_x/10, 1.0, 1.0]
yaff_par = [ gg_y, gg_x , 20.0, 1.0, 0.5, gg_x/100, 1.0, 1.0]
_yaff.setParameter(beta=yaff_par)
self.parameterWidget.add(_yaff.widget)
self.function_registry.register_function(_yaff)
@ -364,7 +375,6 @@ class AppWindow(QMainWindow):
self.updatePlot()
def delPeak(self):
for i, peak in enumerate(self.peakBoxes.keys()):
if peak.widget.isHidden():
@ -376,6 +386,9 @@ class AppWindow(QMainWindow):
self.parameterWidget.vlayout.update()
self.updatePlot()
def test(self):
print "test"
def fitData(self, method):
fit_methods = [fit_odr_cmplx, fit_lbfgsb, fit_anneal]
@ -387,12 +400,48 @@ class AppWindow(QMainWindow):
fixed_params.extend(fcn.getFixed())
_freq, _fit = self.data.get_data()
odr_result = fit_methods[method](_freq, _fit, p0, fixed_params, funcs)
# Prepare
# self._fit_thread = QThread()
self._fit_method = FitRoutine()
self._fit_method.moveToThread(self._fit_thread)
self._fit_method.finished_fit.connect(self._fit_thread.quit)
self._fit_method.fit_odr_cmplx(_freq, _fit, p0, fixed_params, funcs)
self._fit_thread.started.connect(self.test)
self._fit_thread.started.connect(self._fit_method.fit)
self._fit_thread.start()
#self._fit_thread.wait()
#self._fit_method.moveToThread(self._fit_thread)
#self._fit_thread.start()
#fit_methods[method](_freq, _fit, p0, fixed_params, funcs)
# Run
#el = QEventLoop()
#self._fit_thread.finished.connect(el.quit)
#self._fit_method.fit()
import time
time.sleep(1)
# while True:
# time.sleep(0.5)
# print "waiting..."
# if self._fit_thread.isRunning():
# pass
# else:
odr_result = self._fit_method.result()
# break
print "Set fit data"
self.data.set_fit(odr_result.beta, funcs)
self.ui.statusbar.showMessage(" ".join(odr_result.stopreason))
result = odr_result.beta
i=0
i = 0
for fcn in self.function_registry.get_registered_functions():
num_p = len(fcn.getParameter())
beta = odr_result.beta[i:num_p+i]

164
data.py
View File

@ -1,17 +1,15 @@
from PyQt4.QtCore import QObject, pyqtSignal, Qt
from PyQt4.QtGui import QColor
import numpy as N
import numpy as np
import CustomWidgets
import pyqtgraph as pg
from PyQt4.QtCore import *
from mathlib import id_to_color, hn, FitFunctionCreator, Functions
class Data:
def __init__(self, frequency=N.zeros(1), die_real=N.zeros(1), die_imag=N.zeros(1)):
def __init__(self, frequency=np.zeros(1), die_real=np.zeros(1), die_imag=np.zeros(1)):
self.frequency = frequency
self.epsilon = die_real + 1j * die_imag
self.frequency_fit = frequency
@ -20,12 +18,12 @@ class Data:
myPen_real = pg.mkPen(width=3, color=(51,255,127))
#33FF00
self.data_curve_imag = pg.PlotDataItem(x=[N.nan], y=[N.nan],pen=QColor(0,0,0,0), symbol='o',
self.data_curve_imag = pg.PlotDataItem(x=[np.nan], y=[np.nan],pen=QColor(0,0,0,0), symbol='o',
symbolBrush=(255,127,0,127))
self.data_curve_real = pg.PlotDataItem(x=[N.nan], y=[N.nan],pen=QColor(0,0,0,0), symbol='s',
self.data_curve_real = pg.PlotDataItem(x=[np.nan], y=[np.nan],pen=QColor(0,0,0,0), symbol='s',
symbolBrush=(119,202,92,127))
self.fitted_curve_imag = pg.PlotDataItem(N.array([N.nan]), N.array([N.nan]), pen=myPen_imag)
self.fitted_curve_real = pg.PlotDataItem(N.array([N.nan]), N.array([N.nan]), pen=myPen_real)
self.fitted_curve_imag = pg.PlotDataItem(np.array([np.nan]), np.array([np.nan]), pen=myPen_imag)
self.fitted_curve_real = pg.PlotDataItem(np.array([np.nan]), np.array([np.nan]), pen=myPen_real)
self.length = len(frequency)
self.meta = dict()
self.fit_limits = [frequency.min(), frequency.max(), die_imag.min(), die_imag.max()]
@ -41,11 +39,6 @@ class Data:
fit_real, fit_imag = FitFunctionCreator().fitfcn(param, self.frequency_fit, *funcs)
self.epsilon_fit = fit_real + 1j*fit_imag
def __del__(self):
#self.remove_curves()
pass
#def set_fit_limits(self, limits=(None,None,None,None)):
def set_data(self,f,e_real,e_imag):
self.frequency = f
self.epsilon = e_real + 1j*e_imag
@ -63,15 +56,10 @@ class Data:
self.fit_limits[2] = ymin
self.fit_limits[3] = ymax
def get_data(self):
"""
"""
mask = N.ones(len(self.frequency), dtype='bool')
#mask = np.ones(len(self.frequency), dtype='bool')
mask = (self.frequency > self.fit_limits[0]) & (self.frequency < self.fit_limits[1])
#mask &= (self.epsilon.imag > self.fit_limits[2]) & (self.epsilon.imag < self.fit_limits[3])
#mask &= (self.epsilon.real > self.fit_limits[2]) & (self.epsilon.real < self.fit_limits[3])
return self.frequency[mask], self.epsilon[mask]
def remove_curves(self):
@ -80,7 +68,6 @@ class Data:
print "remove fitted_curve"
#if self.fitted_curve is not None: self.fitted_curve.remove()
class BaseObject(QObject):
changedData = pyqtSignal()
removeObj = pyqtSignal(QObject)
@ -91,19 +78,37 @@ class BaseObject(QObject):
myPen = pg.mkPen( style=Qt.DotLine,
width=2.5)
self.data_curve_real = pg.PlotDataItem(x=N.array([N.nan]),y=N.array([N.nan]), pen=myPen)
self.data_curve_real = pg.PlotDataItem(x=np.array([np.nan]),y=np.array([np.nan]), pen=myPen)
self.plt_real = plt_real
self.plt_real.addItem(self.data_curve_real)
self.data_curve_imag = pg.PlotDataItem(x=N.array([N.nan]),y=N.array([N.nan]), pen=myPen)
self.data_curve_imag = pg.PlotDataItem(x=np.array([np.nan]),y=np.array([np.nan]), pen=myPen)
self.plt_imag = plt_imag
self.plt_imag.addItem(self.data_curve_imag)
self.limits = limits
self.f=Functions()
# private varaibles
self.functions = Functions()
#self.functions.step_signal.connect(self.test) # TODO
self._color = QColor("white")
self._id = None
self._widget = None
self._frequency = np.logspace(np.log10(limits[0]), np.log10(limits[1]), 256)
self._data = None
self._func = None
def test(self,p):
print "found:",p
@property
def id_string(self):
return self._id
@id_string.setter
def id_string(self, id):
self._func = self.functions.get_function(id)
self._id = id
@property
def color(self):
@ -115,6 +120,15 @@ class BaseObject(QObject):
self.data_curve_real.setPen(c)
self.data_curve_imag.setPen(c)
@property
def widget(self):
return self._widget
@widget.setter
def widget(self, wdgt):
self._widget = wdgt
self._widget.changedTable.connect(self.updateData)
self._widget.removeMe.connect(self.removeMe)
def getParameter(self):
p = self.widget.getTable()
@ -128,12 +142,8 @@ class BaseObject(QObject):
self.widget.updateTable(beta, sd_beta)
self.updateData()
def get_data(self):
return self.frequency, self.conductivity
def get_epsilon_static(self):
return self.frequency, self.epsilon_static
return self._frequency, self._data
def removeMe(self):
self.plt_imag.removeItem(self.data_curve_imag)
@ -141,130 +151,46 @@ class BaseObject(QObject):
self.removeObj.emit(self)
self.changedData.emit()
def updateData(self):
self._data = self._func(self.getParameter(), self._frequency)
self.data_curve_real.setData(x=self._frequency, y=self._data[0])
self.data_curve_imag.setData(x=self._frequency, y=self._data[1])
self.changedData.emit()
class Conductivity(BaseObject):
def __init__( self, plt_imag=None, plt_real=None, limits=None ):
super(Conductivity, self).__init__(plt_real=plt_real, plt_imag=plt_imag, limits=limits)
self.widget = CustomWidgets.ConductivityWidget()
self.widget.changedTable.connect(self.updateData)
self.widget.removeMe.connect(self.removeMe)
self.color = QColor("blue")
self.frequency = None
self.conductivity = None
self.id_string = "conductivity"
def updateData(self):
# get current axis limits
x_min, x_max, y_min, y_max = self.limits
self.frequency = N.logspace(N.log10(x_min), N.log10(x_max), 254)
p = self.getParameter()
self.conductivity = self.f.cond_cmplx(p, self.frequency)
self.data_curve_real.setData(x=self.frequency, y=self.conductivity[0], label="Cond.")
self.data_curve_imag.setData(x=self.frequency, y=self.conductivity[1], label="Cond.")
self.changedData.emit()
class PowerComplex(BaseObject):
def __init__( self, plt_real=None, plt_imag=None, limits=None ):
super(PowerComplex, self).__init__(plt_real=plt_real, plt_imag=plt_imag, limits=limits)
self.widget = CustomWidgets.PowerLawWidget()
self.widget.changedTable.connect(self.updateData)
self.widget.removeMe.connect(self.removeMe)
self.frequency = None
self.powerlaw = None
self.color = QColor("#ff44c4")
self.id_string = 'power'
def updateData(self):
# get current axis limits
x_min, x_max, y_min, y_max = self.limits
p = self.getParameter()
self.frequency = N.logspace(N.log10(x_min), N.log10(x_max), 1024)
self.powerlaw = self.f.power_cmplx(p, self.frequency) # imaginary part
self.data_curve_real.setData(x=self.frequency, y=self.powerlaw[0], label="Power Law")
self.data_curve_imag.setData(x=self.frequency, y=self.powerlaw[1], label="Power Law")
self.changedData.emit()
class Static(BaseObject):
def __init__( self, plt_real=None, plt_imag=None, limits=None ):
super(Static, self).__init__(plt_real=plt_real, plt_imag=plt_imag, limits=limits)
self.widget = CustomWidgets.StaticWidget()
self.widget.changedTable.connect(self.updateData)
self.widget.removeMe.connect(self.removeMe)
self.frequency = None
self.static = None
self.color = QColor('#FF0F13')
self.id_string = 'static'
def updateData(self):
# get current axis limits
x_min, x_max, y_min, y_max = self.limits
p = self.getParameter()
self.frequency = N.logspace(N.log10(x_min), N.log10(x_max), 1024)
self.static = self.f.static_cmplx(p, self.frequency) [0] # real part
self.data_curve_real.setData(x=self.frequency, y=self.static, label="Power Law")
self.changedData.emit()
class Peak(BaseObject):
def __init__( self, id_num=None, plt_real=None, plt_imag=None, limits=None ):
super(Peak, self).__init__(plt_real=plt_real, plt_imag=plt_imag, limits=limits)
self.widget = CustomWidgets.PeakWidget()
self.widget.setColor(self.color)
self.widget.setId(id_num)
self.color = id_to_color(id_num)
self.id_num = id_num
self.widget.setColor(self.color)
self.widget.changedTable.connect(self.updateData)
self.widget.removeMe.connect(self.removeMe)
self.frequency = None
self.epsilon = None
self.id_string = "hn"
def updateData(self):
x_min,x_max, y_min, y_max = self.limits
self.frequency = N.logspace(N.log10(x_min), N.log10(x_max), 1024)
self.epsilon = self.f.hn_cmplx(self.getParameter(), self.frequency)
self.data_curve_imag.setData(x=self.frequency, y=self.epsilon[1])
self.data_curve_real.setData(x=self.frequency, y=self.epsilon[0])
self.changedData.emit()
class YAFF(BaseObject):
def __init__( self, plt_real=None, plt_imag=None, limits=None ):
super(YAFF, self).__init__(plt_real=plt_real, plt_imag=plt_imag, limits=limits)
self.widget = CustomWidgets.YaffWidget()
self.widget.changedTable.connect(self.updatePeak)
self.widget.removeMe.connect(self.removeMe)
self.frequency = None
self.epsilon = None
self.id_string = "yaff"
def updatePeak(self):
x_min,x_max, y_min, y_max = self.limits
self.frequency = N.logspace(N.log10(x_min), N.log10(x_max), 1024)
self.epsilon = self.f.hn_cmplx(self.getParameter()[:4], self.frequency)
self.data_curve_imag.setData(x=self.frequency, y=self.epsilon[1])
self.data_curve_real.setData(x=self.frequency, y=self.epsilon[0])
self.changedData.emit()

Binary file not shown.

View File

@ -3,37 +3,35 @@ __author__ = 'markusro'
from numpy import *
import mathlib
from PyQt4.QtCore import pyqtSignal, QObject
import scipy.special
import scipy.integrate
#define norm1(a,b) exp(gammln(b/a))/(a*pow(b/a,b/a))
#define glntau1(x,t,a,b) exp( -exp( (log(x)-log(t))*a )*b/a) * pow(x/t,b)
def filon(oms, unsorted_x,unsorted_y):
x = unsorted_x[unsorted_x.argsort()]
y = unsorted_y[unsorted_x.argsort()]
amps = zeros(oms.size, dtype='complex')
for i,om in enumerate(oms):
amps[i] = sum(diff(y)/diff(x)*(cos(om*x[1:])-cos(om*x[:-1])))/om**2
amps[i] += 1j*(y[0]/om + sum(diff(y)/diff(x)*(sin(om*x[1:])-sin(om*x[:-1])))/om**2)
amps[i] = sum(diff(y)/diff(x)*(cos(om*x[1:])-cos(om*x[:-1])))/om**2
amps[i] += 1j*( - sum(diff(y)/diff(x)*(sin(om*x[1:])-sin(om*x[:-1])))/om**2)
#-y[0]/om
return amps
class Yaff:
class Yaff(QObject):
step_signal = pyqtSignal(list)
def __init__(self, dist_type=0):
super(Yaff,self).__init__()
self.dist_x = logspace(-10,5,512)
self.dist_y = zeros(self.dist_x.size)
self.dist_type = [self.yaff,
self.yaff_gg,
][dist_type]
def gg(self, p, tau):
tau0, a, b = p
"""
@ -44,14 +42,12 @@ class Yaff:
g = exp(-b/a*exp( (log(tau)-log(tau0))*a))*(tau/tau0)**b
return g*NGG
def ggb(self, p, tau):
tau0,a,b = p
norm_ggb = a*(1+b)/pi *b**(b/(1+b)) * sin(pi*b/(1+b))
g = (b*exp( (log(tau)-log(tau0)) *a) + exp( (log(tau)-log(tau0))*(-a*b)))**(-1)
return norm_ggb*g
def gg_hw(self, p ,tau):
tau0, a, b, g, s = p
"""
@ -63,7 +59,6 @@ class Yaff:
g = exp(-b/a*exp((log(tau) - log(tau0))*a))*(tau/tau0)**b * (1 + (tau*s/tau0)**(g-b))
return g*NGG
def dist_to_eps(omegas,dist_x,dist_y):
epp = zeros(len(omegas), dtype='complex')
for i,om in enumerate(omegas):
@ -79,13 +74,11 @@ class Yaff:
phi[i] = self.phi_t(t,dist_x,dist_y)
return phi
def phi_t(self, t, dist_x, dist_y):
kern = dist_y*exp(-t/dist_x)
phi = scipy.integrate.simps(kern,log(dist_x))
return phi
def williams_watts(self, phi_1, phi_2, lambd):
return phi_1 * ( (1-lambd) + lambd*phi_2)
@ -114,19 +107,21 @@ class Yaff:
"""
delta_eps, tau1, a1, b1, lambd, tau2, a2, b2 = p
dist_ggb = self.ggb(p=[tau2,a2,b2], tau=self.dist_x)
dist_gg = self.gg(p=[tau1,a1,b1], tau=self.dist_x)
dist_ggb = self.ggb(p=[tau2,a2,b2], tau=self.dist_x)
dist_gg = self.gg (p=[tau1,a1,b1], tau=self.dist_x)
ts = logspace(-10,5,768)
phi_beta = self.dist_to_relax(ts, self.dist_x, dist_ggb).real
phi_alpha = self.dist_to_relax(ts, self.dist_x, dist_gg).real
# William-Watts-Ansatz
phi_tot = (1-lambd) + lambd*phi_beta
phi_tot *= phi_alpha
epp = delta_eps*2*pi*x*filon(2*pi*x, ts, phi_tot )
# William-Watts-Ansatz
phi_tot = (1-lambd) + lambd*phi_beta
phi_tot *= phi_alpha
epp = delta_eps*2*pi*x*filon(2*pi*x, ts, phi_tot)
self.step_signal.emit(list(p))
if cb != None:
cb.next(p,x,epp)
return epp
def yaff_gg(self, p,x, cb=None):
@ -145,7 +140,6 @@ class Yaff:
cb(p,x,epp)
return epp
def show_correlations(cov, ax):
cor = zeros(cov.shape)
for i in range(cor.shape[0]):

View File

@ -2,8 +2,10 @@
__author__ = 'markusro'
from PyQt4.QtGui import QColor
from PyQt4.QtCore import QObject,pyqtSignal,QThread
import numpy as N
import numpy as np
from scipy import optimize as opt, odr
import libyaff
@ -74,12 +76,12 @@ def fit_lbfgsb(x, y, p0, fixed, funcs):
def hn(p, nu):
delta_eps, tau, a, b = p
om = 2 * N.pi * nu
Phi = N.arctan((om * tau) ** a * N.sin(N.pi * a / 2.) / (1. + (om * tau) ** a * N.cos(N.pi * a / 2.)))
e_loss = delta_eps * (1 + 2 * (om * tau) ** a * N.cos(N.pi * a / 2.) + (om * tau) ** (2. * a) ) ** (
-b / 2.) * N.sin(b * Phi)
e_stor = delta_eps * (1 + 2 * (om * tau) ** a * N.cos(N.pi * a / 2.) + (om * tau) ** (2. * a) ) ** (
-b / 2.) * N.cos(b * Phi)
om = 2 * np.pi * nu
Phi = np.arctan((om * tau) ** a * np.sin(np.pi * a / 2.) / (1. + (om * tau) ** a * np.cos(np.pi * a / 2.)))
e_loss = delta_eps * (1 + 2 * (om * tau) ** a * np.cos(np.pi * a / 2.) + (om * tau) ** (2. * a) ) ** (
-b / 2.) * np.sin(b * Phi)
e_stor = delta_eps * (1 + 2 * (om * tau) ** a * np.cos(np.pi * a / 2.) + (om * tau) ** (2. * a) ) ** (
-b / 2.) * np.cos(b * Phi)
return e_loss # 2* oder nicht?
@ -101,13 +103,13 @@ def mini_func(p, x, y):
res = y - multi_hn(p, x)
# apply weights
res /= 1 / y
return N.sqrt(N.dot(res, res))
return np.sqrt(np.dot(res, res))
def multi_hn(p, nu):
conductivity = p[1]
cond_beta = p[2]
om = 2 * N.pi * nu
om = 2 * np.pi * nu
e_loss = conductivity / om ** cond_beta
e_loss += p[0]
#for key, igroup in groupby(p[3:], lambda x: x//4):
@ -117,71 +119,77 @@ def multi_hn(p, nu):
#print delta_eps,tau,a,b
#a = 0.5 *(1 + N.tanh(a))
#b = 0.5 *(1 + N.tanh(b))
Phi = N.arctan((om * tau) ** a * N.sin(N.pi * a / 2.) / (1. + (om * tau) ** a * N.cos(N.pi * a / 2.)))
e_loss += 2 * delta_eps * (1 + 2 * (om * tau) ** a * N.cos(N.pi * a / 2.) + (om * tau) ** (2. * a) ) ** (
-b / 2.) * N.sin(b * Phi)
Phi = np.arctan((om * tau) ** a * np.sin(np.pi * a / 2.) / (1. + (om * tau) ** a * np.cos(np.pi * a / 2.)))
e_loss += 2 * delta_eps * (1 + 2 * (om * tau) ** a * np.cos(np.pi * a / 2.) + (om * tau) ** (2. * a) ) ** (
-b / 2.) * np.sin(b * Phi)
#e_stor = delta_eps * (1+ 2*(om*tau)**a * N.cos(N.pi*a/2.) + (om*tau)**(2.*a) )**(-b/2.)*N.cos(b*Phi)
return e_loss
def tau_peak(f, a, b):
tau = (N.sin(N.pi * a / 2. / (b + 1)) / N.sin(N.pi * a * b / 2. / (b + 1))) ** (1 / a)
tau /= 2 * N.pi * f
tau = (np.sin(np.pi * a / 2. / (b + 1)) / np.sin(np.pi * a * b / 2. / (b + 1))) ** (1 / a)
tau /= 2 * np.pi * f
return tau
### define funcs here
class Functions:
class Functions(QObject):
step_signal = pyqtSignal(list)
def __init__(self):
super(Functions,self).__init__()
self.list = {
# provides functions: "id_string":(function, number_of_parameters)
"hn":(self.hn_cmplx,4),
"conductivity":(self.cond_cmplx,3),
"power":(self.power_cmplx,2),
"static":(self.static_cmplx,1),
"yaff":(self.yaff,8)
"hn":(self.hn_cmplx, 4),
"conductivity":(self.cond_cmplx, 3),
"power":(self.power_cmplx, 2),
"static":(self.static_cmplx, 1),
"yaff":(self.yaff, 8)
}
self.YAFF = libyaff.Yaff()
def hn_cmplx(self, p, x):
om = 2*N.pi*x
om = 2*np.pi*x
#hn = om*1j
eps,t,a,b = p
hn = eps/(1+(1j*om*t)**a)**b
cplx = N.array([hn.real, -hn.imag])
cplx = np.array([hn.real, -hn.imag])
return cplx
def cond_cmplx(self, p, x):
om = 2*N.pi*x
om = 2*np.pi*x
sgma, isgma, n = p
cond = sgma/(om**n) + isgma/(1j*om**n)# Jonscher (Universal Dielectric Response: e",e' prop sigma/omega**n
cplx = N.array([cond.real, -cond.imag])
cplx = np.array([cond.real, -cond.imag])
self.step_signal.emit(list(p))
return cplx
def power_cmplx(self, p, x):
om = 2*N.pi*x
om = 2*np.pi*x
sgma,n = p
power = sgma/(om*1j)**n
cplx = N.array([power.real, -power.imag])
cplx = np.array([power.real, -power.imag])
return cplx
def static_cmplx(self, p, x):
eps_inf = p[0]
static = N.ones( (2,x.size) )*eps_inf
static = np.ones( (2,x.size) )*eps_inf
static[1,:] *= 0 # set imag part zero
#cplx = N.array([static.real, static.imag])
return static
def yaff(self,p,x):
ya = self.YAFF.yaff(p,x)
cplx = N.array([ya.imag[::-1], ya.real])
ya = self.YAFF.yaff(p[:8],x)
cplx = np.array([ya.imag, ya.real])
self.step_signal.emit(list(p))
return cplx
def get(self,name):
return self.list[name]
def get_function(self,name):
return self.list[name][0]
class FitFunctionCreator:
def __init__(self):
@ -190,9 +198,9 @@ class FitFunctionCreator:
def fitfcn(self, p0, x, *funcs):
if x.ndim == 2:
self.data = N.zeros( x.shape )
self.data = np.zeros( x.shape )
else:
self.data = N.zeros( (2,x.size) )
self.data = np.zeros( (2,x.size) )
ndx = 0
for fn in funcs: # loop over functions and add the results
f,num_p = self.functions.get(fn)
@ -204,15 +212,16 @@ class FitFunctionCreator:
ndx += num_p
return self.data
def fit_odr_cmplx(x, y, p0, fixed, fcns):
f = FitFunctionCreator()
#if x.ndim < 2:
# x = N.resize(x, (2,x.size))
if N.iscomplexobj(y) and y.ndim == 1:
weights = 1/N.abs(y)**2
we = N.resize(weights, (2, weights.size))
if np.iscomplexobj(y) and y.ndim == 1:
weights = 1/np.abs(y)**2
we = np.resize(weights, (2, weights.size))
#we = 1/N.array([y.real**2, y.imag**2])
y = N.array([y.real, y.imag])
y = np.array([y.real, y.imag])
else:
raise NotImplementedError, "need complex input for now"
dat = odr.Data(x, y, we=we)
@ -222,6 +231,49 @@ def fit_odr_cmplx(x, y, p0, fixed, fcns):
#print fit.output.pprint()
return fit.output
class FitRoutine(QObject):
finished_fit = pyqtSignal()
data_ready = pyqtSignal([])
def __init__(self):
super(FitRoutine,self).__init__()
self.f = FitFunctionCreator()
self._fitter = self.fit_odr_cmplx
self._odr_fit = None
@property
def fitter(self):
return self._fitter
@fitter.setter
def fitter(self,f):
self._fitter = f
def fit_odr_cmplx(self, x, y, p0, fixed, fcns):
#if x.ndim < 2:
# x = N.resize(x, (2,x.size))
if np.iscomplexobj(y) and y.ndim == 1:
weights = 1/np.abs(y)**2
we = np.resize(weights, (2, weights.size))
#we = 1/N.array([y.real**2, y.imag**2])
y = np.array([y.real, y.imag])
else:
raise NotImplementedError, "need complex input for now"
dat = odr.Data(x, y, we=we)
mod = odr.Model(self.f.fitfcn, extra_args=fcns)
self._odr_fit = odr.ODR(dat, mod, p0, ifixx=(0,), ifixb=fixed, maxit=10)
def fit(self):
#print "TID in FitRoutine", QThread.thread()
self._odr_fit.run()
print "emit finished"
self.finished_fit.emit()
def result(self):
return self._odr_fit.output
class FunctionRegister:
def __init__(self):