diff --git a/Container.py b/Container.py new file mode 100644 index 0000000..429f887 --- /dev/null +++ b/Container.py @@ -0,0 +1,241 @@ +# -*- encoding: utf8 -*- + +from PyQt4.QtCore import QObject, pyqtSignal, Qt +from PyQt4.QtGui import QColor +import numpy as np +import pyqtgraph as pg +import ContainerWidgets +import libyaff +from mathlib import Functions, id_to_color + +__author__ = 'markusro' + + +class BaseObject(QObject): + changedData = pyqtSignal() + removeObj = pyqtSignal(QObject) + + def __init__(self, plt_real=None, plt_imag=None, limits=None): + super(BaseObject, self).__init__() + + myPen = pg.mkPen( style=Qt.DotLine, + width=2.5) + + 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=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 + + # private varaibles + #self.functions = Functions() + + self._color = QColor("white") + self._id_label = None + self._id_string = None + self._widget = None + self._frequency = np.logspace(np.log10(limits[0]), np.log10(limits[1]), 256) + self._data = None + self._func = None + self._beta = None + self._sd_beta = None + self._selector_mask = None + self._param_number = 0 + + @property + def param_number(self): + return self._param_number + + @param_number.setter + def param_number(self, num): + self._param_number = num + + @property + def id_string(self): + return self._id_string + + @id_string.setter + def id_string(self, id): + #self._func = self.functions.get_function(id) + self._id_string = id + + + @property + def id_label(self): + return self._id_label + + @id_label.setter + def id_label(self, id): + #self._func = self.functions.get_function(id) + self._func = self.function + self._id_label = id + + @property + def color(self): + return self._color + + @color.setter + def color(self, c): + self._color = c + 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) # TODO better to use self.setParameter + self.removeObj.connect(self._widget.deleteLater) + self._widget.removeMe.connect(self.removeMe) + + def getParameter(self): + p = self.widget.getTable() # TODO ugly ... should return self._beta etc ...? + return p + + def getFixed(self): + p = self.widget.fixedParameter() + return p + + def setParameter(self, beta, sd_beta=None): + self._beta = beta + self._sd_beta = sd_beta + self.widget.updateTable(beta, sd_beta) + self.updateData() + + def get_data(self): + return self._frequency, self._data + + def removeMe(self): + self.plt_imag.removeItem(self.data_curve_imag) + self.plt_real.removeItem(self.data_curve_real) + 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() + + def resampleData(self, x): + data = self._func(self.getParameter(), x) + return np.array([x,data[0],data[1]]).T + + + def clearData(self): + self.data_curve_real.setData(x=[np.nan], y=[np.nan]) + self.data_curve_imag.setData(x=[np.nan], y=[np.nan]) + + def function(self,p,x): + raise NotImplementedError, "This needs to be implemented in your subclass" + + +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 = ContainerWidgets.ConductivityWidget() + self.color = QColor("blue") + self.id_label = "Cond." + self.id_string = "cond" + + self.param_number = 3 + + def function(self, p, 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 = np.array([cond.real, -cond.imag]) + return cplx + + +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 = ContainerWidgets.PowerLawWidget() + self.color = QColor("#ff44c4") + self.id_label = 'Power Law' + self.id_string = "pwr" + self.param_number = 2 + + def function( self, p, x ): + om = 2*np.pi*x + sgma,n = p + power = sgma/(om*1j)**n + cplx = np.array([power.real, -power.imag]) + return cplx + + +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 = ContainerWidgets.StaticWidget() + self.color = QColor('#FF0F13') + self.id_label = u'ε(∞)' + self.id_string = "eps_infty" + self.param_number = 1 + + def function( self, p, x ): + eps_inf = p[0] + static = np.ones( (2,x.size) )*eps_inf + static[1,:] *= 0 # set imag part zero + return static + + +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 = ContainerWidgets.PeakWidget() + self.widget.setId(id_num) + self.color = id_to_color(id_num) + self.widget.setColor(self.color) + self.id_num = id_num + self.id_label = "Hav-Neg" + self.id_string = "hn" + self.param_number = 4 + + def function( self, p, x ): + eps,t,a,b = p + om = 2*np.pi*x + hn = eps/(1+(1j*om*t)**a)**b + cplx = np.array([hn.real, -hn.imag]) + return cplx + + +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 = ContainerWidgets.YaffWidget() + self.widget.on_model_changed.connect(self.change_model) + self.color = QColor(32, 120, 29, int(255*0.82)) + self._libyaff = libyaff.Yaff(self.widget.getYaffType()) + self.id_label = self._libyaff.label + self.id_string = "yaff" + self._param_number = self._libyaff.params + self._selector_mask = self.widget.selector_mask + + @property + def param_number(self): + return self._param_number + + @param_number.setter + def param_number(self, num=None): + self._param_number = self._libyaff.params + + def change_model(self): + self._libyaff = libyaff.Yaff(self.widget.getYaffType()) + self._selector_mask = self.widget.selector_mask + self.id_label = self._libyaff.label + self.param_number = self._libyaff.params + self.updateData() + + def function( self, p, x ): + ya = self._libyaff.loss( p, x) + cplx = np.array([ya.imag, ya.real]) + return cplx \ No newline at end of file diff --git a/CustomWidgets.py b/ContainerWidgets.py similarity index 99% rename from CustomWidgets.py rename to ContainerWidgets.py index bbccad1..f6b51a0 100644 --- a/CustomWidgets.py +++ b/ContainerWidgets.py @@ -1,5 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +__author__ = 'markusro' + from PyQt4.QtGui import QGroupBox, QPalette, QColor import ConductivityGroupBox import PeakGroupBox @@ -7,18 +9,26 @@ import PowerLawGroupBox import StaticGroupBox import YAFFparameters -__author__ = 'markusro' - -from PyQt4 import QtGui from PyQt4.QtGui import * from PyQt4.QtCore import QRegExp, pyqtSignal,pyqtSlot -#import PeakWidget + + +class ParameterWidget(QWidget): + def __init__(self, parent = None): + super(ParameterWidget, self).__init__(parent) + self.vlayout = QVBoxLayout(self) + self.vlayout.addSpacerItem(QSpacerItem(10,10,QSizePolicy.Minimum, QSizePolicy.Expanding) ) + self.blockSignals(True) + + def add(self, wdgt): + self.vlayout.insertWidget(self.vlayout.count()-1, wdgt) + self.vlayout.update() + class LogFSpinBox(QDoubleSpinBox): scientificNotationValidator = QRegExpValidator(QRegExp("[+-]?(?:0|[1-9]\\d*)(?:\\.\\d*)?(?:[eE][+-]?\\d+)?")) - def __init__(self, parent = None): super(LogFSpinBox, self).__init__(parent) self.setRange(0.0,1e18) @@ -39,19 +49,6 @@ class LogFSpinBox(QDoubleSpinBox): def validate(self, str_value, p_int): return self.scientificNotationValidator.validate(str_value, p_int) -class ParameterWidget(QWidget): - def __init__(self, parent = None): - super(ParameterWidget, self).__init__(parent) - self.vlayout = QVBoxLayout(self) - self.vlayout.addSpacerItem(QSpacerItem(10,10,QSizePolicy.Minimum, QSizePolicy.Expanding) ) - self.blockSignals(True) - - def add(self, wdgt): - self.vlayout.insertWidget(self.vlayout.count()-1, wdgt) - self.vlayout.update() - -if __name__ == "__main__": - app = QApplication([]) class BaseWidget(QGroupBox): @@ -370,19 +367,15 @@ class YaffWidget(BaseWidget): super(YaffWidget, self).__init__(parent) self.ui = YAFFparameters.Ui_Form() self.ui.setupUi(self) - self.ui.doubleSpinBox_1.setParent(None) self.ui.doubleSpinBox_1 = LogFSpinBox(self) self.ui.gridLayout.addWidget(self.ui.doubleSpinBox_1, 2, 1) - self.ui.doubleSpinBox_2.setParent(None) self.ui.doubleSpinBox_2 = LogFSpinBox(self) self.ui.gridLayout.addWidget(self.ui.doubleSpinBox_2, 3, 1) - self.ui.doubleSpinBox_6.setParent(None) self.ui.doubleSpinBox_6 = LogFSpinBox(self) self.ui.gridLayout.addWidget(self.ui.doubleSpinBox_6, 9, 1) - self.ui.doubleSpinBox_9.setParent(None) self.ui.doubleSpinBox_9 = LogFSpinBox(self) self.ui.gridLayout.addWidget(self.ui.doubleSpinBox_9, 12, 1) @@ -452,8 +445,8 @@ class YaffWidget(BaseWidget): ] for dsb in self.inputs: dsb.valueChanged.connect(self.changeValues) - self.change_model(0) + def getYaffType(self): return self.ui.comboBox.currentIndex() diff --git a/Makefile b/Makefile index 13b262a..37f5796 100644 --- a/Makefile +++ b/Makefile @@ -6,3 +6,5 @@ all: pyuic4 PowerLawGroupBox.ui -o PowerLawGroupBox.py pyuic4 StaticGroupBox.ui -o StaticGroupBox.py pyuic4 YAFFparameters.ui -o YAFFparameters.py +stats: + wc -l QDS.py ContainerWidgets.py Container.py libyaff.py mathlib.py data.py diff --git a/QDS.py b/QDS.py index b653806..8a5e4eb 100755 --- a/QDS.py +++ b/QDS.py @@ -8,6 +8,7 @@ import signal from PyQt4.QtCore import * from PyQt4.QtGui import * import matplotlib +from Container import Conductivity, PowerComplex, Static, Peak, YAFF from mathlib import fit_anneal, fit_lbfgsb, fit_odr_cmplx, FunctionRegister, FitRoutine @@ -22,12 +23,12 @@ import numpy as np import QDSMain -from data import Data, Conductivity, Peak, PowerComplex, Static, YAFF +from data import Data import pyqtgraph as pg #import yaff -from CustomWidgets import ParameterWidget, YaffWidget +from ContainerWidgets import ParameterWidget, YaffWidget USE_CROSSH=False @@ -157,10 +158,15 @@ class AppWindow(QMainWindow): sc_imag.sigMouseMoved.connect(self.updateCrosshair) # process cmd line args - if files is not None: + if files != []: self.openFile(files[0]) self._current_file_index = 0 + self._fit_method = FitRoutine() + self._fit_method.moveToThread(self._fit_thread) + self._fit_method.finished_fit.connect(self.fitData_update) + self._fit_method.data_ready.connect(self.updateIntermediatePlot) + self._fit_thread.started.connect(self._fit_method.fit) def updateCrosshair(self,evt): @@ -215,8 +221,6 @@ class AppWindow(QMainWindow): msgBox.setText("Click in imaginary part") msgBox.exec_() - - if self.ui.actionAdd_PowerLaw.isChecked(): if mouse_in_imag: self.addPowerComplex(data_pos) @@ -317,7 +321,6 @@ class AppWindow(QMainWindow): def addYaff(self, pos): - _yaff = YAFF(plt_real=self.ui.pgPlotWidget_real, plt_imag=self.ui.pgPlotWidget_imag, limits=self.data.fit_limits) @@ -341,13 +344,10 @@ class AppWindow(QMainWindow): _conductivity.blockSignals(True) _conductivity.changedData.connect(self.updatePlot) _conductivity.removeObj.connect(self.delParamterObject) - cond_par = [0.0, 10**(pos.y() + pos.x())*2*np.pi , 1.0] _conductivity.setParameter(beta=cond_par) - self.parameterWidget.add(_conductivity.widget) self.function_registry.register_function(_conductivity) ##todo - self.updatePlot() _conductivity.blockSignals(False) @@ -358,10 +358,8 @@ class AppWindow(QMainWindow): limits=self.data.fit_limits) _power_complex.changedData.connect(self.updatePlot) _power_complex.removeObj.connect(self.delParamterObject) - cond_par = [10**(pos.y() + pos.x())*2*np.pi , 1.0] _power_complex.setParameter(beta=cond_par) - self.parameterWidget.add(_power_complex.widget) self.function_registry.register_function(_power_complex) self.updatePlot() @@ -372,10 +370,8 @@ class AppWindow(QMainWindow): limits=self.data.fit_limits) _eps_infty.changedData.connect(self.updatePlot) _eps_infty.removeObj.connect(self.delParamterObject) - cond_par = [10**pos.y()] _eps_infty.setParameter(beta=cond_par) - self.parameterWidget.add(_eps_infty.widget) self.function_registry.register_function(_eps_infty) self.updatePlot() @@ -389,42 +385,21 @@ class AppWindow(QMainWindow): id_list = [ key.id_num for key in self.function_registry.get_registered_functions().keys() if key.id_label == 'hn'] - self.peakId = 1 while self.peakId in id_list: self.peakId += 1 - _peak = Peak(id_num=self.peakId, plt_real=self.ui.pgPlotWidget_real, plt_imag=self.ui.pgPlotWidget_imag, limits=self.data.fit_limits) - _peak.changedData.connect(self.updatePlot) _peak.removeObj.connect(self.delParamterObject) - new_peak = [2*10**pos.y(), 1 / (2*np.pi*10**pos.x()), 1, 1] _peak.setParameter(beta = new_peak) - self.function_registry.register_function(_peak) self.parameterWidget.add(_peak.widget) - self.updatePlot() - def delPeak(self): - for i, peak in enumerate(self.peakBoxes.keys()): - if peak.widget.isHidden(): - self.ui.pgPlotWidget_imag.removeItem(peak.mpl_line) - self.parameterWidget.vlayout.removeWidget(peak.widget) - self.function_registry.unregister_function(peak) - - self.peakBoxes.pop(peak) - self.parameterWidget.vlayout.update() - self.updatePlot() - - @pyqtSlot(np.ndarray) - def test(self, t=None): - print "test",t - def fitData_start(self, method): fit_methods = [fit_odr_cmplx, fit_lbfgsb, fit_anneal] @@ -439,58 +414,40 @@ class AppWindow(QMainWindow): # Prepare if not self._fit_thread.isRunning(): - self._fit_method = FitRoutine() - self._fit_method.moveToThread(self._fit_thread) - self._fit_method.finished_fit.connect(self.fitData_update) +# self._fit_method = FitRoutine() +# self._fit_method.moveToThread(self._fit_thread) +# self._fit_method.finished_fit.connect(self.fitData_update) self._fit_method.fit_odr_cmplx(_freq, _fit, p0, fixed_params, funcs) - self._fit_method.data_ready.connect(self.updateIntermediatePlot) - #for fun in funcs: - # self._fit_method.data_ready.connect(fun.updateData) - self._fit_thread.started.connect(self._fit_method.fit) - self._fit_thread.finished.connect(self._fit_method.deleteLater) + # self._fit_method.data_ready.connect(self.updateIntermediatePlot) + # self._fit_thread.started.connect(self._fit_method.fit) + # self._fit_thread.finished.connect(self._fit_method.deleteLater) self._fit_thread.start() self.ui.statusbar.showMessage("Fitting ...") else: print "fit is still running" - pass def fitData_update(self): - print "before thread.quit" - print "running thread?:",self._fit_thread.isRunning() - self._fit_thread.quit() - print "after thread.quit" - print "running thread?:",self._fit_thread.isRunning() - odr_result = self._fit_method.result() - print odr_result - # build function list p0,funcs,fixed_params = [],[],[] for fcn in self.function_registry.get_registered_functions(): p0.extend(fcn.getParameter()) funcs.append(fcn) fixed_params.extend(fcn.getFixed()) - #print "Set fit data" self.data.set_fit(odr_result.beta, funcs) self.ui.statusbar.showMessage(" ".join(odr_result.stopreason)) - - i = 0 - for fcn in self.function_registry.get_registered_functions(): + for i,fcn in enumerate(self.function_registry.get_registered_functions()): num_p = len(fcn.getParameter()) beta = odr_result.beta[i:num_p+i] sd_beta = odr_result.sd_beta[i:num_p+i] fcn.setParameter(beta, sd_beta) - i += num_p - #self.updatePlot() def getFileNames(self): # TODO: multiple files, advance by button self._file_paths = QFileDialog.getOpenFileNames(self, "Open file", "", '*.dat') - print "here", len(self._file_paths) self._current_file_index = 0 path = unicode(self._file_paths[self._current_file_index]) - self.openFile(path) #path = unicode(QFileDialog.getOpenFileName(self, "Open file")) #path = "MCM42PG0_199.96K.dat" @@ -506,7 +463,7 @@ class AppWindow(QMainWindow): def openFile(self,path): print "opening: %s"%path self.filepath=path - # TODO analyize file (LF,MF, HF) and act accordingly + # TODO analyze file (LF,MF, HF) and act accordingly data = np.loadtxt(path, skiprows=4) self.setWindowTitle(os.path.basename(path)) numpat = re.compile('\d+\.\d+') diff --git a/data.py b/data.py index 101f4c0..5ff85d6 100644 --- a/data.py +++ b/data.py @@ -2,12 +2,8 @@ from PyQt4.QtGui import QColor import numpy as np import pyqtgraph as pg -from PyQt4.QtCore import * -import CustomWidgets - -from mathlib import id_to_color, FitFunctionCreator, Functions -import libyaff +from mathlib import FitFunctionCreator class Data: @@ -69,229 +65,4 @@ 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) - - def __init__(self, plt_real=None, plt_imag=None, limits=None): - super(BaseObject, self).__init__() - - myPen = pg.mkPen( style=Qt.DotLine, - width=2.5) - - 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=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 - - # private varaibles - self.functions = Functions() - self._color = QColor("white") - self._id = None - self._id_string = None - self._widget = None - self._frequency = np.logspace(np.log10(limits[0]), np.log10(limits[1]), 256) - self._data = None - self._func = None - self._beta = None - self._sd_beta = None - self._selector_mask = None - self._param_number = 0 - - @property - def param_number(self): - return self._param_number - - @param_number.setter - def param_number(self, num): - self._param_number = num - - @property - def id_string(self): - return self._id_string - - @id_string.setter - def id_string(self, id): - #self._func = self.functions.get_function(id) - self._id_string = id - - - @property - def id_label(self): - return self._id - - @id_label.setter - def id_label(self, id): - #self._func = self.functions.get_function(id) - self._func = self.function - self._id = id - - @property - def color(self): - return self._color - - @color.setter - def color(self, c): - self._color = c - 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) # TODO better to use self.setParameter - self._widget.removeMe.connect(self.removeMe) - - def getParameter(self): - p = self.widget.getTable() # TODO ugly ... should return self._beta etc ...? - return p - - def getFixed(self): - p = self.widget.fixedParameter() - return p - - def setParameter(self, beta, sd_beta=None): - self._beta = beta - self._sd_beta = sd_beta - self.widget.updateTable(beta, sd_beta) - self.updateData() - - def get_data(self): - return self._frequency, self._data - - def removeMe(self): - self.plt_imag.removeItem(self.data_curve_imag) - self.plt_real.removeItem(self.data_curve_real) - 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() - - def resampleData(self, x): - data = self._func(self.getParameter(), x) - return np.array([x,data[0],data[1]]).T - - - def clearData(self): - self.data_curve_real.setData(x=[np.nan], y=[np.nan]) - self.data_curve_imag.setData(x=[np.nan], y=[np.nan]) - - def function(self,p,x): - raise NotImplementedError, "This needs to be implemented in your subclass" - -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.color = QColor("blue") - self.id_label = "Cond." - self.id_string = "cond" - - self.param_number = 3 - - def function(self, p, 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 = np.array([cond.real, -cond.imag]) - return cplx - - -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.color = QColor("#ff44c4") - self.id_label = 'Power Law' - self.id_string = "pwr" - self.param_number = 2 - - def function( self, p, x ): - om = 2*np.pi*x - sgma,n = p - power = sgma/(om*1j)**n - cplx = np.array([power.real, -power.imag]) - return cplx - - -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.color = QColor('#FF0F13') - self.id_label = u'ε(∞)' - self.id_string = "eps_infty" - self.param_number = 1 - - def function( self, p, x ): - eps_inf = p[0] - static = np.ones( (2,x.size) )*eps_inf - static[1,:] *= 0 # set imag part zero - return static - - -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.setId(id_num) - self.color = id_to_color(id_num) - self.widget.setColor(self.color) - self.id_num = id_num - self.id_label = "Hav-Neg" - self.id_string = "hn" - self.param_number = 4 - - def function( self, p, x ): - eps,t,a,b = p - om = 2*np.pi*x - hn = eps/(1+(1j*om*t)**a)**b - cplx = np.array([hn.real, -hn.imag]) - return cplx - -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.on_model_changed.connect(self.change_model) - self.color = QColor(32, 120, 29, int(255*0.82)) - self._libyaff = libyaff.Yaff(self.widget.getYaffType()) - self.id_label = self._libyaff.label - self.id_string = "yaff" - self._param_number = self._libyaff.params - self._selector_mask = self.widget.selector_mask - - @property - def param_number(self): - return self._param_number - - @param_number.setter - def param_number(self, num=None): - self._param_number = self._libyaff.params - - def change_model(self): - self._libyaff = libyaff.Yaff(self.widget.getYaffType()) - self._selector_mask = self.widget.selector_mask - self.id_label = self._libyaff.label - self.param_number = self._libyaff.params - self.updateData() - - - def function( self, p, x ): - ya = self._libyaff.loss( p, x) - cplx = np.array([ya.imag, ya.real]) - return cplx diff --git a/mathlib.py b/mathlib.py index 948754d..466d97a 100644 --- a/mathlib.py +++ b/mathlib.py @@ -312,6 +312,7 @@ class FunctionRegister: if self.registry.has_key(obj): self.registry.pop(obj) else: + obj.deleteLater() raise AssertionError,"The object is not in the registry! This should NOT happen" #print "FR: ",self.registry