diff --git a/QDS.py b/QDS.py index 4dea6fd..20a17e8 100755 --- a/QDS.py +++ b/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] diff --git a/data.py b/data.py index 2db04dc..79c0a9f 100644 --- a/data.py +++ b/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() - - diff --git a/icons/qds_icons.graffle b/icons/qds_icons.graffle index ed2ae80..14b45c4 100644 Binary files a/icons/qds_icons.graffle and b/icons/qds_icons.graffle differ diff --git a/libyaff.py b/libyaff.py index 4210ced..49c3e9a 100644 --- a/libyaff.py +++ b/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] = 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]): diff --git a/mathlib.py b/mathlib.py index d1df71f..d98ba83 100644 --- a/mathlib.py +++ b/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):