complex fitting almost working except e_inf

This commit is contained in:
Markus Rosenstihl 2014-03-05 18:30:00 +01:00
parent df48519f5a
commit 8673bdd7ff
3 changed files with 58 additions and 27 deletions

36
QDS.py
View File

@ -92,7 +92,8 @@ class AppWindow(QMainWindow):
self.fit_boundary = pg.LinearRegionItem(brush=QColor(254,254,254,10)) self.fit_boundary = pg.LinearRegionItem(brush=QColor(254,254,254,10))
self.ui.graphicsView.addItem(self.data.data_curve_imag) self.ui.graphicsView.addItem(self.data.data_curve_imag)
self.ui.graphicsView.addItem(self.data.data_curve_real) self.ui.graphicsView.addItem(self.data.data_curve_real)
self.ui.graphicsView.addItem(self.data.fitted_curve) self.ui.graphicsView.addItem(self.data.fitted_curve_imag)
self.ui.graphicsView.addItem(self.data.fitted_curve_real)
self.ui.graphicsView.addItem(self.fit_boundary) self.ui.graphicsView.addItem(self.fit_boundary)
self.ui.graphicsView.setLogMode(x=True, y=True) self.ui.graphicsView.setLogMode(x=True, y=True)
self.ui.graphicsView.showGrid(x=True, y=True) self.ui.graphicsView.showGrid(x=True, y=True)
@ -253,12 +254,13 @@ class AppWindow(QMainWindow):
# check new method # check new method
if 1: if 1:
funcs = ["static","conductivity"] if self.Conductivity != None else [] funcs = ["static","power"] if self.Conductivity != None else []
for pb in self.peakBoxes.keys(): for pb in self.peakBoxes.keys():
funcs.append("hn") funcs.append("hn")
newres = fit_odr_cmplx(_freq, _fit, start_parameter, fixed_params, funcs) newres = fit_odr_cmplx(_freq, _fit, start_parameter, fixed_params, funcs)
print "Set fit data"
print newres self.data.set_fit(newres.beta, funcs)
print newres.beta,newres.sd_beta
self.fitresult = result self.fitresult = result
@ -307,21 +309,31 @@ class AppWindow(QMainWindow):
def updatePlot(self): def updatePlot(self):
nu = self.data.frequency nu = self.data.frequency
fit = N.zeros(len(nu)) fit = N.zeros(len(nu))
for peak in self.peakBoxes.keys():
params = peak.getParameter()
fit += hn(params, nu)
#fit += peak.get_data()[1]
if self.Conductivity != None: if self.Conductivity != None:
print "Cond. given" print "Cond. given"
params = self.Conductivity.getParameter()[1:] params = self.Conductivity.getParameter()[1:]
fit += conductivity(params, nu) fit += conductivity(params, nu)
fit += self.Conductivity.getParameter()[0] # eps static fit += self.Conductivity.getParameter()[0] # eps static
funcs = ["static", "power"]
p0 = self.Conductivity.getParameter() if self.Conductivity != None else [0.0, 0.0, 1.0]
self.data.epsilon_fit = fit[:] for peak in self.peakBoxes.keys():
params = peak.getParameter()
fit += hn(params, nu)
#fit += peak.get_data()[1]
p0.extend(params)
funcs.append("hn")
#self.data.epsilon_fit = fit[:]
print "p0",p0
self.data.set_fit(p0, funcs)
fit = self.data.epsilon_fit[:]
self.data.data_curve_imag.setData(self.data.frequency, self.data.epsilon.imag) self.data.data_curve_imag.setData(self.data.frequency, self.data.epsilon.imag)
self.data.data_curve_imag.setData(self.data.frequency, self.data.epsilon.real) self.data.data_curve_real.setData(self.data.frequency, self.data.epsilon.real)
if len(self.peakBoxes) > 0 and self.Conductivity != None: if len(self.peakBoxes) > 0 or self.Conductivity != None:
self.data.fitted_curve.setData(nu, fit) self.data.fitted_curve_imag.setData(nu, fit.imag)
self.data.fitted_curve_real.setData(nu, fit.real)
def sigint_handler(*args): def sigint_handler(*args):

19
data.py
View File

@ -5,7 +5,7 @@ import PeakWidget
import conductivityWidget import conductivityWidget
import pyqtgraph as pg import pyqtgraph as pg
from PyQt4.QtCore import * from PyQt4.QtCore import *
from mathlib import id_to_color, hn from mathlib import id_to_color, hn, FitFunctionCreator
class Data: class Data:
@ -13,17 +13,28 @@ class Data:
self.frequency = frequency self.frequency = frequency
self.epsilon = die_real + 1j * die_imag self.epsilon = die_real + 1j * die_imag
self.epsilon_fit = die_real*0 + 1j * die_imag*0 self.epsilon_fit = die_real*0 + 1j * die_imag*0
myPen = pg.mkPen(width=3, color=(255,255,127)) myPen_imag = pg.mkPen(width=3, color=(255,255,127))
myPen_real = pg.mkPen(width=3, color=(255,127,127))
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=[N.nan], y=[N.nan],pen=QColor(0,0,0,0), symbol='o',
symbolBrush=(255,127,0,127)) 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=[N.nan], y=[N.nan],pen=QColor(0,0,0,0), symbol='s',
symbolBrush=(255,127,0,127)) symbolBrush=(53,159,50,127))
self.fitted_curve = pg.PlotDataItem(N.array([N.nan]), N.array([N.nan]), pen=myPen) 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.length = len(frequency) self.length = len(frequency)
self.meta = dict() self.meta = dict()
self.fit_limits = [frequency.min(), frequency.max(), die_imag.min(), die_imag.max()] self.fit_limits = [frequency.min(), frequency.max(), die_imag.min(), die_imag.max()]
self.fit_param = None
self.fit_funcs = None
def set_fit(self, param, funcs):
self.fit_funcs = funcs
self.fit_param = param
fit_real, fit_imag = FitFunctionCreator().fitfcn(param, self.frequency, *funcs)
self.epsilon_fit = fit_real + 1j*fit_imag
def __del__(self): def __del__(self):
#self.remove_curves() #self.remove_curves()
pass pass

View File

@ -141,27 +141,29 @@ class Functions:
om = 2*N.pi*x om = 2*N.pi*x
hn = om*1j hn = om*1j
eps,t,a,b = p eps,t,a,b = p
hn = eps/(1+(1j*om*t)**a)**b print p
cplx = N.array([hn.real, -hn.imag]) hn = eps/(1-(1j*om*t)**a)**b
cplx = N.array([hn.real, hn.imag])
print cplx
return cplx return cplx
def cond_cmplx(self, p, x): def cond_cmplx(self, p, x):
om = 2*N.pi*x om = 2*N.pi*x
sgma = p[0] sgma = p[0]
cond = sgma/(1j*om) cond = -sgma/(1j*om)
cplx = N.array([cond.real, -cond.imag]) cplx = N.array([cond.real, cond.imag])
return cplx return cplx
def power_cmplx(self, p, x): def power_cmplx(self, p, x):
om = 2*N.pi*x om = 2*N.pi*x
sgma,n = p sgma,n = p
power = sgma/(om*1j)**n power = -sgma/(om*1j)**n
cplx = N.array([power.real, -power.imag]) cplx = N.array([power.real, power.imag])
return cplx return cplx
def static_cmplx(self, p, x): def static_cmplx(self, p, x):
eps_inf = p[0] eps_inf = p[0]
static = N.ones((2, len(x)))*eps_inf static = N.ones( (2,x.size) )*eps_inf
static[:,1] *= 0 # set imag part zero static[:,1] *= 0 # set imag part zero
#cplx = N.array([static.real, static.imag]) #cplx = N.array([static.real, static.imag])
return static return static
@ -176,12 +178,18 @@ class FitFunctionCreator:
self.functions = Functions() self.functions = Functions()
def fitfcn(self, p0, x, *funcs): def fitfcn(self, p0, x, *funcs):
if x.ndim == 2:
self.data = N.zeros( x.shape ) self.data = N.zeros( x.shape )
else:
self.data = N.zeros( (2,x.size) )
ndx = 0 ndx = 0
for fn in funcs: # loop over functions and add the results up for fn in funcs: # loop over functions and add the results up
f,num_p = self.functions.get(fn) f,num_p = self.functions.get(fn)
p = p0[ndx:ndx+num_p] p = p0[ndx:ndx + num_p]
self.data += f(p, x[0]) # fit functions take only 1-dim x if x.ndim == 2:
x = x[0]
self.data += f(p, x) # fit functions take only 1-dim x
ndx += num_p ndx += num_p
return self.data return self.data
@ -197,7 +205,7 @@ def fit_odr_cmplx(x, y, p0, fixed, fcns):
mod = odr.Model(f.fitfcn, extra_args=fcns) mod = odr.Model(f.fitfcn, extra_args=fcns)
fit = odr.ODR(dat, mod, p0, ifixx=N.zeros(x.ndim), ifixb=fixed, maxit=5000) fit = odr.ODR(dat, mod, p0, ifixx=N.zeros(x.ndim), ifixb=fixed, maxit=5000)
fit.run() fit.run()
return fit.output.beta # should return fit.output return fit.output