From 8673bdd7ff02d6549abc38e5d849af82186aa7f8 Mon Sep 17 00:00:00 2001 From: Markus Rosenstihl Date: Wed, 5 Mar 2014 18:30:00 +0100 Subject: [PATCH] complex fitting almost working except e_inf --- QDS.py | 36 ++++++++++++++++++++++++------------ data.py | 19 +++++++++++++++---- mathlib.py | 30 +++++++++++++++++++----------- 3 files changed, 58 insertions(+), 27 deletions(-) diff --git a/QDS.py b/QDS.py index 9e81a07..26b8374 100755 --- a/QDS.py +++ b/QDS.py @@ -92,7 +92,8 @@ class AppWindow(QMainWindow): 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_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.setLogMode(x=True, y=True) self.ui.graphicsView.showGrid(x=True, y=True) @@ -253,12 +254,13 @@ class AppWindow(QMainWindow): # check new method if 1: - funcs = ["static","conductivity"] if self.Conductivity != None else [] + funcs = ["static","power"] if self.Conductivity != None else [] for pb in self.peakBoxes.keys(): funcs.append("hn") newres = fit_odr_cmplx(_freq, _fit, start_parameter, fixed_params, funcs) - - print newres + print "Set fit data" + self.data.set_fit(newres.beta, funcs) + print newres.beta,newres.sd_beta self.fitresult = result @@ -307,21 +309,31 @@ class AppWindow(QMainWindow): def updatePlot(self): nu = self.data.frequency 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: print "Cond. given" params = self.Conductivity.getParameter()[1:] fit += conductivity(params, nu) 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.real) - if len(self.peakBoxes) > 0 and self.Conductivity != None: - self.data.fitted_curve.setData(nu, fit) + self.data.data_curve_real.setData(self.data.frequency, self.data.epsilon.real) + if len(self.peakBoxes) > 0 or self.Conductivity != None: + self.data.fitted_curve_imag.setData(nu, fit.imag) + self.data.fitted_curve_real.setData(nu, fit.real) def sigint_handler(*args): diff --git a/data.py b/data.py index 14e4c23..dd4246f 100644 --- a/data.py +++ b/data.py @@ -5,7 +5,7 @@ import PeakWidget import conductivityWidget import pyqtgraph as pg from PyQt4.QtCore import * -from mathlib import id_to_color, hn +from mathlib import id_to_color, hn, FitFunctionCreator class Data: @@ -13,17 +13,28 @@ class Data: self.frequency = frequency self.epsilon = die_real + 1j * die_imag 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', 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', - symbolBrush=(255,127,0,127)) - self.fitted_curve = pg.PlotDataItem(N.array([N.nan]), N.array([N.nan]), pen=myPen) + symbolBrush=(53,159,50,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.length = len(frequency) self.meta = dict() 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): #self.remove_curves() pass diff --git a/mathlib.py b/mathlib.py index f768939..52391b3 100644 --- a/mathlib.py +++ b/mathlib.py @@ -141,27 +141,29 @@ class Functions: om = 2*N.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]) + print p + hn = eps/(1-(1j*om*t)**a)**b + cplx = N.array([hn.real, hn.imag]) + print cplx return cplx def cond_cmplx(self, p, x): om = 2*N.pi*x sgma = p[0] - cond = sgma/(1j*om) - cplx = N.array([cond.real, -cond.imag]) + cond = -sgma/(1j*om) + cplx = N.array([cond.real, cond.imag]) return cplx def power_cmplx(self, p, x): om = 2*N.pi*x sgma,n = p - power = sgma/(om*1j)**n - cplx = N.array([power.real, -power.imag]) + power = -sgma/(om*1j)**n + cplx = N.array([power.real, power.imag]) return cplx def static_cmplx(self, p, x): 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 #cplx = N.array([static.real, static.imag]) return static @@ -176,12 +178,18 @@ class FitFunctionCreator: self.functions = Functions() def fitfcn(self, p0, x, *funcs): - self.data = N.zeros( x.shape ) + if x.ndim == 2: + self.data = N.zeros( x.shape ) + else: + self.data = N.zeros( (2,x.size) ) ndx = 0 for fn in funcs: # loop over functions and add the results up + f,num_p = self.functions.get(fn) - p = p0[ndx:ndx+num_p] - self.data += f(p, x[0]) # fit functions take only 1-dim x + p = p0[ndx:ndx + num_p] + if x.ndim == 2: + x = x[0] + self.data += f(p, x) # fit functions take only 1-dim x ndx += num_p return self.data @@ -197,7 +205,7 @@ def fit_odr_cmplx(x, y, p0, fixed, 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.run() - return fit.output.beta # should return fit.output + return fit.output