started to decouple fit routine from ui
This commit is contained in:
parent
d356585a7e
commit
4a206c0eb6
59
QDS.py
59
QDS.py
@ -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
164
data.py
@ -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.
30
libyaff.py
30
libyaff.py
@ -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] += 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)
|
||||
|
||||
@ -115,18 +108,20 @@ 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_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 )
|
||||
|
||||
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]):
|
||||
|
122
mathlib.py
122
mathlib.py
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user