diff --git a/ConductivityGroupBox.py b/ConductivityGroupBox.py index c06757b..0a85b6c 100644 --- a/ConductivityGroupBox.py +++ b/ConductivityGroupBox.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file 'ConductivityGroupBox.ui' # -# Created: Thu Mar 27 13:33:39 2014 -# by: PyQt4 UI code generator 4.10.3 +# Created: Thu Apr 10 21:45:49 2014 +# by: PyQt4 UI code generator 4.10.4 # # WARNING! All changes made in this file will be lost! @@ -40,9 +40,9 @@ class Ui_ConductivityGroupBox(object): self.gridLayout.setSpacing(1) self.gridLayout.setContentsMargins(0, 0, -1, -1) self.gridLayout.setObjectName(_fromUtf8("gridLayout")) - self.label_6 = QtGui.QLabel(ConductivityGroupBox) - self.label_6.setObjectName(_fromUtf8("label_6")) - self.gridLayout.addWidget(self.label_6, 3, 2, 1, 1) + self.pwrSigma_sd = QtGui.QLabel(ConductivityGroupBox) + self.pwrSigma_sd.setObjectName(_fromUtf8("pwrSigma_sd")) + self.gridLayout.addWidget(self.pwrSigma_sd, 3, 2, 1, 1) self.checkBox_2 = QtGui.QCheckBox(ConductivityGroupBox) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) @@ -92,39 +92,39 @@ class Ui_ConductivityGroupBox(object): self.label_4.setAlignment(QtCore.Qt.AlignCenter) self.label_4.setObjectName(_fromUtf8("label_4")) self.gridLayout.addWidget(self.label_4, 3, 0, 1, 1) - self.label_5 = QtGui.QLabel(ConductivityGroupBox) - self.label_5.setObjectName(_fromUtf8("label_5")) - self.gridLayout.addWidget(self.label_5, 2, 2, 1, 1) - self.doubleSpinBox_3 = QtGui.QDoubleSpinBox(ConductivityGroupBox) + self.rSigma_sd = QtGui.QLabel(ConductivityGroupBox) + self.rSigma_sd.setObjectName(_fromUtf8("rSigma_sd")) + self.gridLayout.addWidget(self.rSigma_sd, 2, 2, 1, 1) + self.pwrSigma = QtGui.QDoubleSpinBox(ConductivityGroupBox) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.doubleSpinBox_3.sizePolicy().hasHeightForWidth()) - self.doubleSpinBox_3.setSizePolicy(sizePolicy) - self.doubleSpinBox_3.setSingleStep(0.05) - self.doubleSpinBox_3.setProperty("value", 1.0) - self.doubleSpinBox_3.setObjectName(_fromUtf8("doubleSpinBox_3")) - self.gridLayout.addWidget(self.doubleSpinBox_3, 3, 1, 1, 1) - self.doubleSpinBox_2 = QtGui.QDoubleSpinBox(ConductivityGroupBox) + sizePolicy.setHeightForWidth(self.pwrSigma.sizePolicy().hasHeightForWidth()) + self.pwrSigma.setSizePolicy(sizePolicy) + self.pwrSigma.setSingleStep(0.05) + self.pwrSigma.setProperty("value", 1.0) + self.pwrSigma.setObjectName(_fromUtf8("pwrSigma")) + self.gridLayout.addWidget(self.pwrSigma, 3, 1, 1, 1) + self.rSigma = QtGui.QDoubleSpinBox(ConductivityGroupBox) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.doubleSpinBox_2.sizePolicy().hasHeightForWidth()) - self.doubleSpinBox_2.setSizePolicy(sizePolicy) - self.doubleSpinBox_2.setObjectName(_fromUtf8("doubleSpinBox_2")) - self.gridLayout.addWidget(self.doubleSpinBox_2, 2, 1, 1, 1) + sizePolicy.setHeightForWidth(self.rSigma.sizePolicy().hasHeightForWidth()) + self.rSigma.setSizePolicy(sizePolicy) + self.rSigma.setObjectName(_fromUtf8("rSigma")) + self.gridLayout.addWidget(self.rSigma, 2, 1, 1, 1) self.subtractConductivityButton = QtGui.QPushButton(ConductivityGroupBox) self.subtractConductivityButton.setObjectName(_fromUtf8("subtractConductivityButton")) self.gridLayout.addWidget(self.subtractConductivityButton, 0, 2, 1, 1) self.label_3 = QtGui.QLabel(ConductivityGroupBox) self.label_3.setObjectName(_fromUtf8("label_3")) self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1, QtCore.Qt.AlignHCenter) - self.doubleSpinBox_1 = QtGui.QDoubleSpinBox(ConductivityGroupBox) - self.doubleSpinBox_1.setObjectName(_fromUtf8("doubleSpinBox_1")) - self.gridLayout.addWidget(self.doubleSpinBox_1, 1, 1, 1, 1) - self.label_7 = QtGui.QLabel(ConductivityGroupBox) - self.label_7.setObjectName(_fromUtf8("label_7")) - self.gridLayout.addWidget(self.label_7, 1, 2, 1, 1) + self.iSigma = QtGui.QDoubleSpinBox(ConductivityGroupBox) + self.iSigma.setObjectName(_fromUtf8("iSigma")) + self.gridLayout.addWidget(self.iSigma, 1, 1, 1, 1) + self.iSigma_sd = QtGui.QLabel(ConductivityGroupBox) + self.iSigma_sd.setObjectName(_fromUtf8("iSigma_sd")) + self.gridLayout.addWidget(self.iSigma_sd, 1, 2, 1, 1) self.checkBox_1 = QtGui.QCheckBox(ConductivityGroupBox) self.checkBox_1.setText(_fromUtf8("")) self.checkBox_1.setObjectName(_fromUtf8("checkBox_1")) @@ -138,15 +138,15 @@ class Ui_ConductivityGroupBox(object): def retranslateUi(self, ConductivityGroupBox): ConductivityGroupBox.setWindowTitle(_translate("ConductivityGroupBox", "GroupBox", None)) ConductivityGroupBox.setTitle(_translate("ConductivityGroupBox", "Conductivity", None)) - self.label_6.setText(_translate("ConductivityGroupBox", "TextLabel", None)) + self.pwrSigma_sd.setText(_translate("ConductivityGroupBox", "TextLabel", None)) self.label_2.setText(_translate("ConductivityGroupBox", "

σ\'(DC)

", None)) self.label.setText(_translate("ConductivityGroupBox", "Fix", None)) self.removeButton.setText(_translate("ConductivityGroupBox", "Remove", None)) self.label_4.setText(_translate("ConductivityGroupBox", "α", None)) - self.label_5.setText(_translate("ConductivityGroupBox", "TextLabel", None)) - self.doubleSpinBox_2.setToolTip(_translate("ConductivityGroupBox", "

DC conductivity, should only be seen in the imaginary permitivity. If there is a Jonscher type of Universal Dielectric Response, the ratio of σ"/σ\'(DC) is a constant

", None)) + self.rSigma_sd.setText(_translate("ConductivityGroupBox", "TextLabel", None)) + self.rSigma.setToolTip(_translate("ConductivityGroupBox", "

DC conductivity, should only be seen in the imaginary permitivity. If there is a Jonscher type of Universal Dielectric Response, the ratio of σ"/σ\'(DC) is a constant

", None)) self.subtractConductivityButton.setText(_translate("ConductivityGroupBox", "Hide", None)) self.label_3.setText(_translate("ConductivityGroupBox", "

σ"

", None)) - self.doubleSpinBox_1.setToolTip(_translate("ConductivityGroupBox", "

If there is a Jonscher type of Universal Dielectric Response, the ratio of σ"/σ\'(DC) is a constant

", None)) - self.label_7.setText(_translate("ConductivityGroupBox", "TextLabel", None)) + self.iSigma.setToolTip(_translate("ConductivityGroupBox", "

If there is a Jonscher type of Universal Dielectric Response, the ratio of σ"/σ\'(DC) is a constant

", None)) + self.iSigma_sd.setText(_translate("ConductivityGroupBox", "TextLabel", None)) diff --git a/ConductivityGroupBox.ui b/ConductivityGroupBox.ui index 1f2d9e4..d3a69f8 100644 --- a/ConductivityGroupBox.ui +++ b/ConductivityGroupBox.ui @@ -44,7 +44,7 @@ 1 - + TextLabel @@ -135,14 +135,14 @@ - + TextLabel - + 0 @@ -158,7 +158,7 @@ - + 0 @@ -185,14 +185,14 @@ - + <html><head/><body><p>If there is a Jonscher type of U<span style=" font-style:italic;">niversal Dielectric Response, </span>the ratio of σ&quot;/σ'<span style=" vertical-align:sub;">(DC)</span> is a constant</p></body></html> - + TextLabel diff --git a/CustomWidgets.py b/CustomWidgets.py index c84bac3..5b59f17 100644 --- a/CustomWidgets.py +++ b/CustomWidgets.py @@ -43,9 +43,8 @@ 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.vlayout.addSpacerItem(QSpacerItem(10,10,QSizePolicy.Minimum, QSizePolicy.Expanding) ) - #self.vlayout.addStretch(1) + self.blockSignals(True) def add(self, wdgt): self.vlayout.insertWidget(self.vlayout.count()-1, wdgt) @@ -59,11 +58,13 @@ class BaseWidget(QGroupBox): changedTable = pyqtSignal() removeMe = pyqtSignal() subtract = pyqtSignal() + def __init__(self, parent=None): super(BaseWidget, self).__init__(parent) self.fixedCheckBoxes = [] self.inputs = [] self.errors = [] + self.names = [] def remove(self): self.removeMe.emit() @@ -120,8 +121,6 @@ class BaseWidget(QGroupBox): class PeakWidget(BaseWidget,QGroupBox): - - def __init__(self, parent=None): QGroupBox.__init__(self) BaseWidget.__init__(self) @@ -138,6 +137,13 @@ class PeakWidget(BaseWidget,QGroupBox): self.ui.removeButton.clicked.connect(self.remove) + self.names = [ + "Deps", + "tau", + "alpha", + "beta" + ] + self.inputs = [ self.ui.doubleSpinBox_1, self.ui.doubleSpinBox_2, @@ -154,6 +160,7 @@ class PeakWidget(BaseWidget,QGroupBox): + for dsb in self.inputs: dsb.valueChanged.connect(self.changeValues) @@ -270,7 +277,7 @@ class StaticWidget(BaseWidget, QGroupBox): #self.ui.doubleSpinBox_2 = LogFSpinBox(self) #self.ui.gridLayout.addWidget(self.ui.doubleSpinBox_2,1,1) - + self.names = ["e_infty"] self.errors = [self.ui.label_4] self.inputs = [self.ui.doubleSpinBox_1] @@ -292,24 +299,29 @@ class ConductivityWidget(BaseWidget, QGroupBox): self.ui = ConductivityGroupBox.Ui_ConductivityGroupBox() self.ui.setupUi(self) - self.ui.doubleSpinBox_1.setParent(None) - self.ui.doubleSpinBox_1 = LogFSpinBox(self) - self.ui.gridLayout.addWidget(self.ui.doubleSpinBox_1,1,1) + self.ui.iSigma.setParent(None) + self.ui.iSigma = LogFSpinBox(self) + self.ui.gridLayout.addWidget(self.ui.iSigma,1,1) - self.ui.doubleSpinBox_2.setParent(None) - self.ui.doubleSpinBox_2 = LogFSpinBox(self) - self.ui.gridLayout.addWidget(self.ui.doubleSpinBox_2,2,1) + self.ui.rSigma.setParent(None) + self.ui.rSigma = LogFSpinBox(self) + self.ui.gridLayout.addWidget(self.ui.rSigma,2,1) self.ui.removeButton.clicked.connect(self.remove) #self.ui.subtractConductivityButton.connect(self.subtract) - self.errors = [self.ui.label_7, - self.ui.label_5, - self.ui.label_6] + self.names = [ + "iSigma", + "rSigma", + "pwrSigma", + ] + self.errors = [self.ui.iSigma_sd, + self.ui.rSigma_sd, + self.ui.pwrSigma_sd] - self.inputs = [self.ui.doubleSpinBox_1, - self.ui.doubleSpinBox_2, - self.ui.doubleSpinBox_3] + self.inputs = [self.ui.iSigma, + self.ui.rSigma, + self.ui.pwrSigma] self.fixedCheckBoxes = [self.ui.checkBox_1, self.ui.checkBox_2, @@ -318,6 +330,7 @@ class ConductivityWidget(BaseWidget, QGroupBox): dsb.valueChanged.connect(self.changeValues) + class PowerLawWidget(BaseWidget, QGroupBox): def __init__(self, parent=None): @@ -333,6 +346,7 @@ class PowerLawWidget(BaseWidget, QGroupBox): self.ui.gridLayout.addWidget(self.ui.doubleSpinBox_2,1,1) self.ui.removeButton.clicked.connect(self.remove) + self.names = ["Amp", "pwrAmp"] self.errors = [self.ui.label_5, self.ui.label_6] @@ -345,10 +359,11 @@ class PowerLawWidget(BaseWidget, QGroupBox): dsb.valueChanged.connect(self.changeValues) -class YaffWidget(BaseWidget, QGroupBox): +class YaffWidget(BaseWidget): + on_model_changed = pyqtSignal() def __init__(self, parent=None): - QGroupBox.__init__(self) + #QGroupBox.__init__(self) BaseWidget.__init__(self) super(YaffWidget, self).__init__(parent) @@ -367,8 +382,28 @@ class YaffWidget(BaseWidget, QGroupBox): 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) + self.ui.removeButton.clicked.connect(self.remove) + self.ui.comboBox.currentIndexChanged.connect(self.change_model) + + self.change_model() + self.names = [ + "Deps", + "tau_a", + "alpha", + "beta", + "lambda", + "tau_b", + "a", + "b", + "none", + "none" + ] + self.errors = [self.ui.label_1, self.ui.label_2, self.ui.label_3, @@ -406,3 +441,21 @@ class YaffWidget(BaseWidget, QGroupBox): ] for dsb in self.inputs: dsb.valueChanged.connect(self.changeValues) + + def getYaffType(self): + return self.ui.comboBox.currentIndex() + + def change_model(self): + ndx = self.ui.comboBox.currentIndex() + mask = [ + (0,0,0,0,1,1,1,1,1,1), + (0,0,0,0,0,0,1,1,1,1), + (0,0,0,0,0,0,0,0,1,1), + (0,0,0,0,0,0,0,0,0,0), + ] + for i,inp in enumerate(self.inputs): + self.inputs[i].setDisabled(mask[ndx][i]) + self.errors[i].setDisabled(mask[ndx][i]) + self.fixedCheckBoxes[i].setDisabled(mask[ndx][i]) + self.errors[i].setText("(---)") + self.on_model_changed.emit() diff --git a/PeakGroupBox.py b/PeakGroupBox.py index a7acc95..6a78b27 100644 --- a/PeakGroupBox.py +++ b/PeakGroupBox.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file 'PeakGroupBox.ui' # -# Created: Thu Mar 27 13:33:39 2014 -# by: PyQt4 UI code generator 4.10.3 +# Created: Thu Apr 10 21:45:49 2014 +# by: PyQt4 UI code generator 4.10.4 # # WARNING! All changes made in this file will be lost! diff --git a/PowerLawGroupBox.py b/PowerLawGroupBox.py index dc3df8b..7e42e22 100644 --- a/PowerLawGroupBox.py +++ b/PowerLawGroupBox.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file 'PowerLawGroupBox.ui' # -# Created: Thu Mar 27 13:33:39 2014 -# by: PyQt4 UI code generator 4.10.3 +# Created: Thu Apr 10 21:45:49 2014 +# by: PyQt4 UI code generator 4.10.4 # # WARNING! All changes made in this file will be lost! diff --git a/QDS.py b/QDS.py index 20a17e8..2d7036e 100755 --- a/QDS.py +++ b/QDS.py @@ -18,7 +18,7 @@ from matplotlib import pyplot from matplotlib.colors import hex2color #matplotlib.rc_file("default.mplrc") -import numpy as N +import numpy as np import QDSMain @@ -37,6 +37,8 @@ class AppWindow(QMainWindow): self.ui = QDSMain.Ui_MainWindow() self.ui.setupUi(self) + + self._last_written_header = None actions = { self.ui.actionAdd_Peak:self.addPeak, self.ui.actionAdd_Cond:self.addCond, @@ -103,7 +105,7 @@ class AppWindow(QMainWindow): ]): self.signalMapper.setMapping(fit_action, i) fit_action.triggered.connect(self.signalMapper.map) - self.signalMapper.mapped.connect(self.fitData) + self.signalMapper.mapped.connect(self.fitData_start) # save fitted values @@ -136,8 +138,8 @@ class AppWindow(QMainWindow): pltwidgt.disableAutoRange() pltwidgt.setLabel("bottom", "Frequency", units="Hz") - self.ui.pgPlotWidget_imag.setLabel("left", "(I) Dielectric loss", units="Debye") - self.ui.pgPlotWidget_real.setLabel("left", "(R) Dielectric loss", units="Debye") + self.ui.pgPlotWidget_imag.setLabel("left", u'Dielectric loss ε"' , units="Debye") + self.ui.pgPlotWidget_real.setLabel("left", u"Dielectric loss ε' ", units="Debye") sc_real = self.ui.pgPlotWidget_real.scene() sc_real.sigMouseClicked.connect(self.mousePress) @@ -231,58 +233,59 @@ class AppWindow(QMainWindow): f = open("fitresults.log", "w") else: f = open("fitresults.log", "a") - # write header - f.write("#%7s"%('T')) - parfmt = "%8.2f" # T formatting - # if self.Conductivity != None: pass# always true - f.write("%9s%9s%9s " % ("e_s", "sig", "pow_sig")) - parfmt += "%9.3g%9.3g%9.2f " # conductivity formatting - for i, pb in enumerate(self.peakBoxes): - enum_peak = ("e_inf_%i" % i, "tau_%i" % i, "alpha_%i" % i, "beta_%i" % i) - f.write("%9s%9s%9s%9s " % enum_peak) - print enum_peak - parfmt += "%9.3g%9.3g%9.2f%9.2f" # peak formatting - f.write("fit_xlow fit_xhigh") # TODO: store limits - parfmt += "%9.3g%9.3g" - f.write('\n') - f.flush() - #f.write("%3.2f "%(self.data.meta["T"])) - pars = list(self.fitresult) + + + # prepare header + header="# T " + pars = [] + for fcn in self.function_registry.get_registered_functions(): + for name in fcn.widget.names: # variable names + header += "{n:11}{n_sd:11}".format(n=name, n_sd=name+"_sd") + for i,par in enumerate(fcn._beta): # params + pars.extend([par]) + pars.extend([fcn._sd_beta[i]]) + + header += "%-11s%-11s\n"%("fit_xlow","fit_xhigh") + + # write new header if fit model changed + if self._last_written_header != header: + f.write(header) + f.flush() + self._last_written_header = header + else: + pass + pars.insert(0, self.data.meta["T"]) pars.append(self.data.fit_limits[0]) pars.append(self.data.fit_limits[1]) - N.savetxt(f, N.array([pars, ]), fmt=parfmt, delimiter=" ") + pars = np.array([pars]) + np.savetxt(f, pars, fmt = '%-10.3e', delimiter=" ") f.close() def saveFitFigure(self): fig = pyplot.figure(figsize=(3.54, 2.75)) + font = {'family' : 'sans serif', 'weight' : 'normal', 'size' : 8} matplotlib.rc('font', **font) + pyplot.grid(linestyle="solid",alpha=0.3, color="0.5") pyplot.loglog(self.data.frequency, self.data.epsilon.imag, 'bo', markersize=3, label="Data") - pyplot.loglog(self.data.frequency, self.data.epsilon_fit, 'r-', lw=1, label="Fit") + pyplot.loglog(self.data.frequency_fit, self.data.epsilon_fit.imag, 'r-', lw=1.2, label="Fit") - for i,peak in enumerate(self.peakBoxes): - f,eps = peak.get_data() - color = hex2color(str(peak.get_color().name())) - pyplot.loglog(f,eps, ls="--", color=color , lw=0.75, label="Peak %i"%i) + for fcn in self.function_registry.get_registered_functions(): + f,eps = fcn.get_data() + pyplot.loglog(f,eps[1], ls=":", color=hex2color(str(fcn.color.name())) , lw=1, dashes=(1,2)) - if self.Conductivity != None: - f,eps = self.Conductivity.get_data() - color = hex2color(str(self.Conductivity.get_color().name())) - pyplot.loglog(f,eps, ls="-.", color=color, lw=0.75, label="Cond.") - f,eps = self.Conductivity.get_epsilon_static() - pyplot.loglog(f,eps, ls=":", color=color, lw=0.75, label=r'$\epsilon_0$') - - for i in (0,1): pyplot.axvline(x=self.data.fit_limits[i], color='g', ls="--") + for i in (0,1): pyplot.axvline(x=self.data.fit_limits[i], color='b', ls="-", lw=0.5) pyplot.legend(title = "T=%.1f K"%(self.data.meta["T"])) - pyplot.grid() pyplot.xlabel('f/Hz') - pyplot.ylabel('eps"') - pyplot.savefig(os.path.splitext(self.filepath)[0]+".png") + pyplot.ylabel(u'ε"') + pyplot.ylim(self.data.epsilon.imag.min(), self.data.epsilon.imag.max() ) + #pyplot.savefig(os.path.splitext(self.filepath)[0]+".png") + pyplot.savefig(os.path.splitext(self.filepath)[0]+".pdf") fig.clear() @@ -291,30 +294,35 @@ class AppWindow(QMainWindow): _yaff = YAFF(plt_real=self.ui.pgPlotWidget_real, plt_imag=self.ui.pgPlotWidget_imag, limits=self.data.fit_limits) + _yaff.blockSignals(True) _yaff.changedData.connect(self.updatePlot) _yaff.removeObj.connect(self.delParamterObject) gg_y = 10**pos.y() - gg_x = 10**pos.x()*2*N.pi + gg_x = 10**pos.x()*2*np.pi 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) self.updatePlot() + _yaff.blockSignals(False) def addCond(self, pos): _conductivity = Conductivity(plt_real=self.ui.pgPlotWidget_real, plt_imag=self.ui.pgPlotWidget_imag, limits=self.data.fit_limits) + _conductivity.blockSignals(True) _conductivity.changedData.connect(self.updatePlot) _conductivity.removeObj.connect(self.delParamterObject) - cond_par = [0.0, 10**(pos.y() + pos.x())*2*N.pi , 1.0] + 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) + self.function_registry.register_function(_conductivity) ##todo + self.updatePlot() + _conductivity.blockSignals(False) def addPowerComplex(self, pos): @@ -324,7 +332,7 @@ class AppWindow(QMainWindow): _power_complex.changedData.connect(self.updatePlot) _power_complex.removeObj.connect(self.delParamterObject) - cond_par = [10**(pos.y() + pos.x())*2*N.pi , 1.0] + cond_par = [10**(pos.y() + pos.x())*2*np.pi , 1.0] _power_complex.setParameter(beta=cond_par) self.parameterWidget.add(_power_complex.widget) @@ -367,7 +375,7 @@ class AppWindow(QMainWindow): _peak.changedData.connect(self.updatePlot) _peak.removeObj.connect(self.delParamterObject) - new_peak = [2*10**pos.y(), 1 / (2*N.pi*10**pos.x()), 1, 1] + 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) @@ -386,61 +394,54 @@ class AppWindow(QMainWindow): self.parameterWidget.vlayout.update() self.updatePlot() - def test(self): - print "test" + @pyqtSlot(np.ndarray) + def test(self, t=None): + print "test",t - def fitData(self, method): + def fitData_start(self, method): fit_methods = [fit_odr_cmplx, fit_lbfgsb, fit_anneal] # build function list p0,funcs,fixed_params = [],[],[] for fcn in self.function_registry.get_registered_functions(): p0.extend(fcn.getParameter()) - funcs.append(fcn.id_string) + #funcs.append(fcn.id_string) + funcs.append(fcn) fixed_params.extend(fcn.getFixed()) _freq, _fit = self.data.get_data() # 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.finished_fit.connect(self.fitData_update) self._fit_method.fit_odr_cmplx(_freq, _fit, p0, fixed_params, funcs) - self._fit_thread.started.connect(self.test) + self._fit_method.data_ready.connect(self.updateIntermediatePlot) self._fit_thread.started.connect(self._fit_method.fit) self._fit_thread.start() - #self._fit_thread.wait() + self.ui.statusbar.showMessage("Fitting ...") - #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: + def fitData_update(self): + self._fit_thread.quit() odr_result = self._fit_method.result() - # break - print "Set fit data" + # 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)) - result = odr_result.beta + i = 0 for fcn in self.function_registry.get_registered_functions(): num_p = len(fcn.getParameter()) @@ -448,15 +449,14 @@ class AppWindow(QMainWindow): sd_beta = odr_result.sd_beta[i:num_p+i] fcn.setParameter(beta, sd_beta) i += num_p - - self.updatePlot() + #self.updatePlot() def openFile(self): #path = unicode(QFileDialog.getOpenFileName(self, "Open file")) path = "MCM42PG0_199.96K.dat" self.filepath=path # TODO analyize file (LF,MF, HF) and act accordingly - data = N.loadtxt(path, skiprows=4) + data = np.loadtxt(path, skiprows=4) self.setWindowTitle(os.path.basename(path)) numpat = re.compile('\d+\.\d+') try: @@ -477,7 +477,7 @@ class AppWindow(QMainWindow): _die_loss = data[mask, 2] self.data.set_data(_freq, _die_stor, _die_loss) self.data.meta["T"] = Temp - self.fit_boundary.setRegion([N.log10(_freq.min()), N.log10(_freq.max())]) + self.fit_boundary.setRegion([np.log10(_freq.min()), np.log10(_freq.max())]) self.ui.pgPlotWidget_imag.enableAutoRange() self.ui.pgPlotWidget_real.enableAutoRange() self.updatePlot() @@ -488,10 +488,11 @@ class AppWindow(QMainWindow): def updatePlot(self): log10fmin, log10fmax = self.fit_boundary.getRegion() self.data.set_fit_xlimits(10**log10fmin, 10**log10fmax) + p0,funcs = [],[] for fcn in self.function_registry.get_registered_functions(): p0.extend(fcn.getParameter()) - funcs.append(fcn.id_string) + funcs.append(fcn) # calculate parametrized curve self.data.set_fit(p0, funcs) @@ -504,8 +505,14 @@ class AppWindow(QMainWindow): self.data.fitted_curve_imag.setData(self.data.frequency_fit, self.data.epsilon_fit.imag) else: - self.data.fitted_curve_real.setData([N.nan],[N.nan]) - self.data.fitted_curve_imag.setData([N.nan],[N.nan]) + self.data.fitted_curve_real.setData([np.nan],[np.nan]) + self.data.fitted_curve_imag.setData([np.nan],[np.nan]) + + + def updateIntermediatePlot(self, freq, intermediate_data): + self.data.fitted_curve_real.setData(freq, intermediate_data[0]) + self.data.fitted_curve_imag.setData(freq, intermediate_data[1]) + def sigint_handler(*args): """Handler for the SIGINT signal (CTRL + C). diff --git a/QDSMain.py b/QDSMain.py index e45015f..f936dac 100644 --- a/QDSMain.py +++ b/QDSMain.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file 'QDSMain.ui' # -# Created: Thu Mar 27 13:33:39 2014 -# by: PyQt4 UI code generator 4.10.3 +# Created: Thu Apr 10 21:45:49 2014 +# by: PyQt4 UI code generator 4.10.4 # # WARNING! All changes made in this file will be lost! diff --git a/StaticGroupBox.py b/StaticGroupBox.py index 87a0eaa..5da50df 100644 --- a/StaticGroupBox.py +++ b/StaticGroupBox.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file 'StaticGroupBox.ui' # -# Created: Thu Mar 27 13:33:39 2014 -# by: PyQt4 UI code generator 4.10.3 +# Created: Thu Apr 10 21:45:49 2014 +# by: PyQt4 UI code generator 4.10.4 # # WARNING! All changes made in this file will be lost! diff --git a/YAFFparameters.py b/YAFFparameters.py index ad01523..f507580 100644 --- a/YAFFparameters.py +++ b/YAFFparameters.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file 'YAFFparameters.ui' # -# Created: Thu Mar 27 13:33:39 2014 -# by: PyQt4 UI code generator 4.10.3 +# Created: Thu Apr 10 21:45:49 2014 +# by: PyQt4 UI code generator 4.10.4 # # WARNING! All changes made in this file will be lost! @@ -56,6 +56,7 @@ class Ui_Form(object): self.gridLayout.addWidget(self.doubleSpinBox_1, 2, 1, 1, 1) self.doubleSpinBox_4 = QtGui.QDoubleSpinBox(Form) self.doubleSpinBox_4.setSingleStep(0.05) + self.doubleSpinBox_4.setProperty("value", 1.0) self.doubleSpinBox_4.setObjectName(_fromUtf8("doubleSpinBox_4")) self.gridLayout.addWidget(self.doubleSpinBox_4, 7, 1, 1, 1) self.label_111 = QtGui.QLabel(Form) @@ -111,6 +112,7 @@ class Ui_Form(object): self.gridLayout.addWidget(self.label_type, 0, 0, 1, 1) self.doubleSpinBox_3 = QtGui.QDoubleSpinBox(Form) self.doubleSpinBox_3.setSingleStep(0.05) + self.doubleSpinBox_3.setProperty("value", 1.0) self.doubleSpinBox_3.setObjectName(_fromUtf8("doubleSpinBox_3")) self.gridLayout.addWidget(self.doubleSpinBox_3, 5, 1, 1, 1) self.label_huh = QtGui.QLabel(Form) @@ -137,6 +139,8 @@ class Ui_Form(object): self.label_322.setObjectName(_fromUtf8("label_322")) self.gridLayout.addWidget(self.label_322, 5, 0, 1, 1) self.doubleSpinBox_9 = QtGui.QDoubleSpinBox(Form) + self.doubleSpinBox_9.setMinimum(1.0) + self.doubleSpinBox_9.setProperty("value", 1.0) self.doubleSpinBox_9.setObjectName(_fromUtf8("doubleSpinBox_9")) self.gridLayout.addWidget(self.doubleSpinBox_9, 12, 1, 1, 1) self.label_8 = QtGui.QLabel(Form) @@ -173,6 +177,7 @@ class Ui_Form(object): self.gridLayout.addWidget(self.label_622, 9, 0, 1, 1) self.doubleSpinBox_7 = QtGui.QDoubleSpinBox(Form) self.doubleSpinBox_7.setSingleStep(0.05) + self.doubleSpinBox_7.setProperty("value", 1.0) self.doubleSpinBox_7.setObjectName(_fromUtf8("doubleSpinBox_7")) self.gridLayout.addWidget(self.doubleSpinBox_7, 10, 1, 1, 1) self.label_7 = QtGui.QLabel(Form) @@ -189,13 +194,18 @@ class Ui_Form(object): self.gridLayout.addWidget(self.label_72, 10, 0, 1, 1) self.doubleSpinBox_8 = QtGui.QDoubleSpinBox(Form) self.doubleSpinBox_8.setSingleStep(0.05) + self.doubleSpinBox_8.setProperty("value", 1.0) self.doubleSpinBox_8.setObjectName(_fromUtf8("doubleSpinBox_8")) self.gridLayout.addWidget(self.doubleSpinBox_8, 11, 1, 1, 1) self.doubleSpinBox_10 = QtGui.QDoubleSpinBox(Form) + self.doubleSpinBox_10.setMaximum(1.0) + self.doubleSpinBox_10.setSingleStep(0.05) + self.doubleSpinBox_10.setProperty("value", 1.0) self.doubleSpinBox_10.setObjectName(_fromUtf8("doubleSpinBox_10")) self.gridLayout.addWidget(self.doubleSpinBox_10, 13, 1, 1, 1) self.doubleSpinBox_5 = QtGui.QDoubleSpinBox(Form) self.doubleSpinBox_5.setSingleStep(0.05) + self.doubleSpinBox_5.setProperty("value", 0.8) self.doubleSpinBox_5.setObjectName(_fromUtf8("doubleSpinBox_5")) self.gridLayout.addWidget(self.doubleSpinBox_5, 8, 1, 1, 1) self.doubleSpinBox_2 = QtGui.QDoubleSpinBox(Form) @@ -261,13 +271,13 @@ class Ui_Form(object): self.label_4.setText(_translate("Form", "TextLabel", None)) self.label_5.setText(_translate("Form", "TextLabel", None)) self.label_522.setText(_translate("Form", "lambda", None)) - self.label_112.setText(_translate("Form", "TextLabel", None)) + self.label_112.setText(_translate("Form", "s", None)) self.label_9.setText(_translate("Form", "TextLabel", None)) self.label_6.setText(_translate("Form", "TextLabel", None)) self.label_type.setText(_translate("Form", "Type", None)) self.label_huh.setText(_translate("Form", "TextLabel", None)) self.label_2.setText(_translate("Form", "TextLabel", None)) - self.label_102.setText(_translate("Form", "TextLabel", None)) + self.label_102.setText(_translate("Form", "g", None)) self.label_222.setText(_translate("Form", "tau_a", None)) self.label_322.setText(_translate("Form", "a", None)) self.label_8.setText(_translate("Form", "TextLabel", None)) diff --git a/YAFFparameters.ui b/YAFFparameters.ui index 704d210..f306f84 100644 --- a/YAFFparameters.ui +++ b/YAFFparameters.ui @@ -65,6 +65,9 @@ 0.050000000000000 + + 1.000000000000000 + @@ -119,7 +122,7 @@ - TextLabel + s Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -167,6 +170,9 @@ 0.050000000000000 + + 1.000000000000000 + @@ -192,7 +198,7 @@ - TextLabel + g Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -220,7 +226,14 @@ - + + + 1.000000000000000 + + + 1.000000000000000 + + @@ -286,6 +299,9 @@ 0.050000000000000 + + 1.000000000000000 + @@ -316,16 +332,32 @@ 0.050000000000000 + + 1.000000000000000 + - + + + 1.000000000000000 + + + 0.050000000000000 + + + 1.000000000000000 + + 0.050000000000000 + + 0.800000000000000 + diff --git a/data.py b/data.py index 79c0a9f..b013acb 100644 --- a/data.py +++ b/data.py @@ -1,12 +1,13 @@ -from PyQt4.QtCore import QObject, pyqtSignal, Qt from PyQt4.QtGui import QColor import numpy as np +import pyqtgraph as pg +from PyQt4.QtCore import * import CustomWidgets -import pyqtgraph as pg -from PyQt4.QtCore import * -from mathlib import id_to_color, hn, FitFunctionCreator, Functions +from mathlib import id_to_color, FitFunctionCreator, Functions +import libyaff + class Data: def __init__(self, frequency=np.zeros(1), die_real=np.zeros(1), die_imag=np.zeros(1)): @@ -16,7 +17,6 @@ class Data: self.epsilon_fit = die_real*0 + 1j * die_imag*0 myPen_imag = pg.mkPen(width=3, color=(255,255,127)) myPen_real = pg.mkPen(width=3, color=(51,255,127)) - #33FF00 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)) @@ -90,16 +90,23 @@ class BaseObject(QObject): # 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 + self._beta = None + self._sd_beta = None + self._param_number = 0 - def test(self,p): - print "found:",p + @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): @@ -127,11 +134,11 @@ class BaseObject(QObject): @widget.setter def widget(self, wdgt): self._widget = wdgt - self._widget.changedTable.connect(self.updateData) + 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() + p = self.widget.getTable() # TODO ugly ... should return self._beta etc ...? return p def getFixed(self): @@ -139,6 +146,8 @@ class BaseObject(QObject): 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() @@ -157,6 +166,9 @@ class BaseObject(QObject): self.data_curve_imag.setData(x=self._frequency, y=self._data[1]) self.changedData.emit() + 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) @@ -164,12 +176,31 @@ class Conductivity(BaseObject): self.color = QColor("blue") self.id_string = "conductivity" + 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_string = 'power' + 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 ): @@ -177,20 +208,59 @@ class Static(BaseObject): self.widget = CustomWidgets.StaticWidget() self.color = QColor('#FF0F13') self.id_string = 'static' + 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.setColor(self.color) self.widget.setId(id_num) self.color = id_to_color(id_num) + self.widget.setColor(self.color) self.id_num = id_num 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.id_string = "yaff" + self._libyaff = libyaff.Yaff(self.widget.getYaffType()) + self._param_number = self._libyaff.params + + @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.param_number = self._libyaff.params + self.updateData() + + + def function( self, p, x ): + ya = self._libyaff.loss( p[:self.param_number], x) + cplx = np.array([ya.imag, ya.real]) + return cplx + diff --git a/images_rc.py b/images_rc.py index cbb085d..15ff4a4 100644 --- a/images_rc.py +++ b/images_rc.py @@ -2,7 +2,7 @@ # Resource object code # -# Created: Do. Mär. 27 13:33:39 2014 +# Created: Do. Apr. 10 21:45:48 2014 # by: The Resource Compiler for PyQt (Qt v4.8.5) # # WARNING! All changes made in this file will be lost! diff --git a/libyaff.py b/libyaff.py index 49c3e9a..3cfa33a 100644 --- a/libyaff.py +++ b/libyaff.py @@ -1,7 +1,7 @@ __author__ = 'markusro' from numpy import * -import mathlib +import multiprocessing from PyQt4.QtCore import pyqtSignal, QObject @@ -22,15 +22,30 @@ def filon(oms, unsorted_x,unsorted_y): #-y[0]/om return amps +class PhiT: + def __init__(self, dist_x, dist_y): + self.dist_x = dist_x + self.dist_y = dist_y + def __call__(self,t): + kern = self.dist_y*exp(-t/self.dist_x) + phi = scipy.integrate.simps(kern,log(self.dist_x)) + return phi + + 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] + yaff = [ + (self.yaff_gg, 4), + (self.yaff_gge, 6), + (self.yaff, 8), + (self.yaff_extended, 10), + + ] + self.loss, self.params = yaff[dist_type] def gg(self, p, tau): tau0, a, b = p @@ -68,12 +83,24 @@ class Yaff(QObject): epp[i] += 1j*scipy.integrate.simps(kern_imag,log(dist_x)) return epp - def dist_to_relax(self, ts,dist_x,dist_y): + def dist_to_relax_(self, ts,dist_x,dist_y): phi = zeros(len(ts)) for i,t in enumerate(ts): phi[i] = self.phi_t(t,dist_x,dist_y) return phi + def dist_to_relax(self, ts,dist_x,dist_y): + phi = zeros(len(ts)) + pool = multiprocessing.Pool() + result = pool.map(PhiT(dist_x,dist_y), ts) + pool.close() + pool.terminate() + pool.join() + return array(result) + + + + def phi_t(self, t, dist_x, dist_y): kern = dist_y*exp(-t/dist_x) phi = scipy.integrate.simps(kern,log(dist_x)) @@ -101,6 +128,31 @@ class Yaff(QObject): epp += s_c/(2*pi*x) return epp + def yaff_extended(self, p,x, cb=None): + """ + GG + GB + """ + delta_eps, tau1, a1, b1, lambd, tau2, a2, b2, s, g = p + + dist_ggb = self.ggb(p=[tau2,a2,b2], tau=self.dist_x) + dist_gg = self.gg_hw (p=[tau1,a1,b1,s,g], tau=self.dist_x) + + ts = logspace(-10,5,512) + + self.dist_y = dist_ggb + phi_beta = self.dist_to_relax(ts, self.dist_x, self.dist_y).real + + self.dist_y = dist_gg + phi_alpha = self.dist_to_relax(ts, self.dist_x, self.dist_y).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) + + self.step_signal.emit(list(p)) + return epp + def yaff(self, p,x, cb=None): """ GG + GB @@ -110,36 +162,49 @@ class Yaff(QObject): 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 + ts = logspace(-10,5,512) + + self.dist_y = dist_ggb + phi_beta = self.dist_to_relax(ts, self.dist_x, self.dist_y).real + + self.dist_y = dist_gg + phi_alpha = self.dist_to_relax(ts, self.dist_x, self.dist_y).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) - self.step_signal.emit(list(p)) - if cb != None: - cb.next(p,x,epp) + self.step_signal.emit(list(p)) return epp def yaff_gg(self, p,x, cb=None): """ GG """ - delta_eps, s_c, tau1,a1,b1 = p - - dist_gg = gg(dist_t,tau1,a1,b1) - - phi_alpha = dist_to_relax(ts, dist_t, dist_gg).real - epp = delta_eps*2*pi*x*filon(2*pi*x, ts, phi_alpha ).real - # epp = dist_to_eps(2*pi*x, dist_t, dist_gg ).real - epp += s_c/(2*pi*x) - if cb != None: - cb(p,x,epp) + delta_eps, tau1,a1,b1 = p + ts = logspace(-10,5,512) + dist_gg = self.gg(p=[tau1,a1,b1], tau=self.dist_x) + self.dist_y = dist_gg + phi_alpha = self.dist_to_relax(ts, self.dist_x, self.dist_y).real + epp = delta_eps*2*pi*x*filon(2*pi*x, ts, phi_alpha ) + self.step_signal.emit(list(p)) return epp + def yaff_gge(self, p,x): + """ + GG + """ + delta_eps, tau1, a1, b1, s, g = p + ts = logspace(-10,5,512) + dist_gg = self.gg_hw(p=[tau1, a1, b1, s, g], tau=self.dist_x) + self.dist_y = dist_gg + phi_alpha = self.dist_to_relax(ts, self.dist_x, self.dist_y).real + epp = delta_eps*2*pi*x*filon(2*pi*x, ts, phi_alpha ) + self.step_signal.emit(list(p)) + 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 d98ba83..e90bc68 100644 --- a/mathlib.py +++ b/mathlib.py @@ -2,7 +2,7 @@ __author__ = 'markusro' from PyQt4.QtGui import QColor -from PyQt4.QtCore import QObject,pyqtSignal,QThread +from PyQt4.QtCore import QObject,pyqtSignal,QThread,pyqtSlot import numpy as np @@ -136,7 +136,6 @@ def tau_peak(f, a, b): ### define funcs here class Functions(QObject): - step_signal = pyqtSignal(list) def __init__(self): super(Functions,self).__init__() self.list = { @@ -160,9 +159,8 @@ class Functions(QObject): def cond_cmplx(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 + 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]) - self.step_signal.emit(list(p)) return cplx def power_cmplx(self, p, x): @@ -182,7 +180,6 @@ class Functions(QObject): def yaff(self,p,x): 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): @@ -191,12 +188,34 @@ class Functions(QObject): def get_function(self,name): return self.list[name][0] -class FitFunctionCreator: + +class FitFunctionCreator(QObject): + new_data = pyqtSignal(np.ndarray, np.ndarray) + def __init__(self): + super(FitFunctionCreator,self).__init__() self.data = None self.functions = Functions() + def fitfcn(self, p0, x, *funcs): + if x.ndim == 2: + self.data = np.zeros( x.shape ) + else: + self.data = np.zeros( (2,x.size) ) + ndx = 0 + for fn in funcs: # loop over functions and add the results + f, num_p = fn.function, fn.param_number + p = p0[ndx:ndx + num_p] + if x.ndim == 2: + x = x[0] + result = f(p, x) + self.data += result # fit functions take only 1-dim x + ndx += num_p + self.new_data.emit(x, self.data) + return self.data + + def _fitfcn(self, p0, x, *funcs): if x.ndim == 2: self.data = np.zeros( x.shape ) else: @@ -210,6 +229,7 @@ class FitFunctionCreator: result = f(p, x) self.data += result # fit functions take only 1-dim x ndx += num_p + self.new_data.emit(x, self.data) return self.data @@ -233,10 +253,11 @@ def fit_odr_cmplx(x, y, p0, fixed, fcns): class FitRoutine(QObject): finished_fit = pyqtSignal() - data_ready = pyqtSignal([]) + data_ready = pyqtSignal(np.ndarray, np.ndarray) def __init__(self): super(FitRoutine,self).__init__() self.f = FitFunctionCreator() + self.f.new_data.connect(self.data_ready.emit) self._fitter = self.fit_odr_cmplx self._odr_fit = None @@ -248,7 +269,6 @@ class FitRoutine(QObject): 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)) @@ -264,10 +284,10 @@ class FitRoutine(QObject): mod = odr.Model(self.f.fitfcn, extra_args=fcns) self._odr_fit = odr.ODR(dat, mod, p0, ifixx=(0,), ifixb=fixed, maxit=10) + @pyqtSlot() def fit(self): #print "TID in FitRoutine", QThread.thread() self._odr_fit.run() - print "emit finished" self.finished_fit.emit() def result(self): @@ -279,7 +299,7 @@ class FunctionRegister: def __init__(self): self.registry = {} - def register_function(self,obj): + def register_function(self, obj): #print "FR: Registering:",obj id_string = obj.id_string if self.registry.has_key(obj):