From 784393a21a0db9359e9482b92f30dc2abd3e0b5b Mon Sep 17 00:00:00 2001 From: Markus Rosenstihl Date: Mon, 23 Jun 2014 12:02:49 +0200 Subject: [PATCH] * added "Show Derivative" to approximate imaginary eps without conductivity term * closing matplotlib figure after saving --- ConductivityGroupBox.py | 2 +- ContainerWidgets.py | 5 ++++ ExtraDifferentialWidget.py | 30 ++++++++++++++++++++ Makefile | 1 + PeakGroupBox.py | 2 +- PowerLawGroupBox.py | 2 +- QDS.py | 57 ++++++++++++++++++++++++++++++-------- QDSMain.py | 10 ++++++- QDSMain.ui | 12 ++++++++ StaticGroupBox.py | 2 +- YAFFConfig.py | 2 +- YAFFparameters.py | 2 +- data.py | 9 +++--- images_rc.py | 2 +- 14 files changed, 115 insertions(+), 23 deletions(-) create mode 100644 ExtraDifferentialWidget.py diff --git a/ConductivityGroupBox.py b/ConductivityGroupBox.py index 3431099..ac79f43 100644 --- a/ConductivityGroupBox.py +++ b/ConductivityGroupBox.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'ConductivityGroupBox.ui' # -# Created: Wed Apr 16 14:28:54 2014 +# Created: Mon Jun 2 19:55:32 2014 # by: PyQt4 UI code generator 4.10.4 # # WARNING! All changes made in this file will be lost! diff --git a/ContainerWidgets.py b/ContainerWidgets.py index 4366f94..34209a1 100644 --- a/ContainerWidgets.py +++ b/ContainerWidgets.py @@ -114,6 +114,7 @@ class BaseWidget(QGroupBox): sd = "( --- )" self.errors[i].setStyleSheet(sd_style) self.errors[i].setText(sd) + #self.update() def replaceDoubleSpinBox(self, layout, widget): ndx = layout.indexOf(widget) @@ -512,10 +513,14 @@ class YaffConfigWidget(QDialog): #self.replaceDoubleSpinBox(self.ui.gridLayout_tau, self.ui.doubleSpinBox_taumin) #self.replaceDoubleSpinBox(self.ui.gridLayout_tau, self.ui.doubleSpinBox_taumax) + ndx = self.ui.gridLayout_time.indexOf(self.ui.doubleSpinBox_tmin) row, column, cols, rows = self.ui.gridLayout_time.getItemPosition(ndx) self.ui.doubleSpinBox_tmin.setParent(None) self.ui.doubleSpinBox_tmin = LogFSpinBox(self) + + + self.ui.gridLayout_time.addWidget(self.ui.doubleSpinBox_tmin, row,column) ndx = self.ui.gridLayout_time.indexOf(self.ui.doubleSpinBox_tmax) diff --git a/ExtraDifferentialWidget.py b/ExtraDifferentialWidget.py new file mode 100644 index 0000000..c462b44 --- /dev/null +++ b/ExtraDifferentialWidget.py @@ -0,0 +1,30 @@ +# -*- encoding: utf-8 -*- +__author__ = 'markusro' + +from PyQt4.QtGui import QColor +import ExtraDifferential +import pyqtgraph as pg +import numpy as np + +class DifferentialWidget(ExtraDifferential.PlotWidget): + def __init__(self, parent=None): + super(DifferentialWidget, self).__init__(parent) + self.setLogMode(x=True, y=False) + self.showGrid(x=True, y=True) + self.addLegend() + self.disableAutoRange() + self.setLabel("bottom", "Frequency", units="Hz") + + self.setLabel("left", u"Dielectric loss εder''= ∂ε'/∂log10(v)" , units="Debye") + self.curve_imag = pg.PlotDataItem(x=[np.nan], y=[np.nan],pen=QColor(0,0,0,0), symbol='o', + symbolBrush=(255,127,0,127), name=u"Imaginary ε") + self.curve_real = pg.PlotDataItem(x=[np.nan], y=[np.nan],pen=QColor(0,0,0,0), symbol='s', + symbolBrush=(119,202,92,127), name=u"Real ε") + self.addItem(self.curve_imag) + self.addItem(self.curve_real) + + def plot(self, x,real_y,imag_y): + self.enableAutoRange() + self.curve_real.setData(x, real_y) + self.curve_imag.setData(x, imag_y) + diff --git a/Makefile b/Makefile index 8b92251..a304dd2 100644 --- a/Makefile +++ b/Makefile @@ -7,5 +7,6 @@ all: pyuic4 StaticGroupBox.ui -o StaticGroupBox.py pyuic4 YAFFparameters.ui -o YAFFparameters.py pyuic4 YAFFConfig.ui -o YAFFConfig.py + pyuic4 ExtraDifferential.ui -o ExtraDifferential.py stats: wc -l QDS.py ContainerWidgets.py Container.py libyaff.py Mathlib.py Data.py diff --git a/PeakGroupBox.py b/PeakGroupBox.py index ca5973b..e740dc3 100644 --- a/PeakGroupBox.py +++ b/PeakGroupBox.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'PeakGroupBox.ui' # -# Created: Wed Apr 16 14:28:54 2014 +# Created: Mon Jun 2 19:55:32 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 2a9d71e..4deb049 100644 --- a/PowerLawGroupBox.py +++ b/PowerLawGroupBox.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'PowerLawGroupBox.ui' # -# Created: Wed Apr 16 14:28:54 2014 +# Created: Mon Jun 2 19:55:33 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 70382a8..570045d 100755 --- a/QDS.py +++ b/QDS.py @@ -23,6 +23,7 @@ from Mathlib import FunctionRegister, FitRoutine from Data import Data import QDSMain +import ExtraDifferentialWidget class AppWindow(QMainWindow): @@ -145,6 +146,23 @@ class AppWindow(QMainWindow): fit_action.triggered.connect(self.signalMapper.map) self.signalMapper.mapped.connect(self.fitData_start) + self.ui.actionShow_Derivative.triggered.connect(self.show_derivative) + + + + def show_derivative(self): + self.xtra_wdgt = ExtraDifferentialWidget.DifferentialWidget() + #self.xtra_wdgt.set + deriv_r = np.diff(np.log10(self.data.epsilon.real)) + deriv_i = np.diff(np.log10(self.data.epsilon.imag))*0 + deriv_i = -np.pi/2 * np.diff(np.log10(self.data.epsilon.real))/np.diff(np.log10(self.data.frequency)) + self.xtra_wdgt.plot(self.data.frequency[:-1], deriv_r, deriv_i) + # self.xtra_wdgt.plot([0,1], [0,1], [0,1]) + self.xtra_wdgt.setGeometry(self.ui.pgPlotWidget_real.geometry()) + self.xtra_wdgt.show() + #self.xtra_wdgt.showCenterd() + self.xtra_wdgt.raise_() + def updateCrosshair(self,evt): @@ -215,7 +233,7 @@ class AppWindow(QMainWindow): Saving fit parameters to fitresults.log including temperature """ - self.saveFitFigure() + self._saveFitFigure() if not os.path.exists("fitresults.log"): f = open("fitresults.log", "w") else: @@ -263,7 +281,7 @@ class AppWindow(QMainWindow): np.savetxt(f, pars, fmt = '%-10.3e', delimiter=" ") f.close() - def saveFitFigure(self): + def _saveFitFigure(self): fig = pyplot.figure(figsize=(3.54*1.4, 2.75*1.4)) font = {'family' : 'sans serif', @@ -290,7 +308,13 @@ class AppWindow(QMainWindow): #pyplot.savefig(os.path.splitext(self.filepath)[0]+".png") pyplot.savefig(os.path.splitext(self.filepath)[0]+".pdf") fig.clear() + fig.close() + def _saveFitFigureGrace(self): + #agrtemplate = open('template.agr').read() + agrtemplate = """ + + """ def addYaff(self, pos): _yaff = YAFF(plt_real=self.ui.pgPlotWidget_real, @@ -363,11 +387,12 @@ class AppWindow(QMainWindow): plt_real=self.ui.pgPlotWidget_real, plt_imag=self.ui.pgPlotWidget_imag, limits=self.data.fit_limits) + self.function_registry.register_function(_peak) + _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) + new_peak_beta0 = [2*10**pos.y(), 1 / (2*np.pi*10**pos.x()), 1, 1] + _peak.setParameter(beta = new_peak_beta0) self.parameterWidget.add(_peak.widget) self.updatePlot() @@ -435,27 +460,30 @@ class AppWindow(QMainWindow): self.openFile(path) def nextFile(self): + lim = self.fit_boundary_imag.getRegion() # store limits if len(self._file_paths) > self._current_file_index+1: # wrap around self._current_file_index += 1 else: self._current_file_index = 0 path = unicode(self._file_paths[self._current_file_index]) self.openFile(path) + self.fit_boundary_imag.setRegion(lim) def previousFile(self): + lim = self.fit_boundary_imag.getRegion() # store limits if self._current_file_index == 0: # wrap around self._current_file_index = len(self._file_paths) - 1 else: self._current_file_index -= 1 path = unicode(self._file_paths[self._current_file_index]) self.openFile(path) + self.fit_boundary_imag.setRegion(lim) def openFile(self,path): print "opening: %s"%path self.filepath=path # 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+') try: Temp = None @@ -466,10 +494,15 @@ class AppWindow(QMainWindow): Temp = float(re.search(numpat, line).group()) print "Temperature found in file:", Temp break + search_temp_in_filename = re.search('\d+\.\d+K', path) + if search_temp_in_filename: + Temp = float(search_temp_in_filename.group()[:-1]) if Temp == None: raise ValueError except: Temp = QInputDialog.getDouble(self, "No temperature found in data set", "Temperature/K:", value=0.00)[0] # mask the data to values > 0 (loglog plot) + self.setWindowTitle("%s - %.2f K"%(os.path.basename(path), Temp)) + mask = (data[:, 1] > 0) & (data[:, 2] > 0) #& (data[:,2]>1e-3) & (data[:,0] > 1e-2) _freq = data[mask, 0] _die_stor = data[mask, 1] @@ -501,6 +534,7 @@ class AppWindow(QMainWindow): p0,funcs = [],[] for fcn in self.function_registry.get_registered_functions(): + print fcn p0.extend(fcn.getParameter()) funcs.append(fcn) # calculate parametrized curve @@ -509,13 +543,14 @@ class AppWindow(QMainWindow): # replot data and fit, TODO: replot only if measurement data changed self.data.data_curve_real.setData(self.data.frequency, self.data.epsilon.real) self.data.data_curve_imag.setData(self.data.frequency, self.data.epsilon.imag) - + print "updatePlot: ",self.data.frequency_fit, self.data.epsilon_fit if len(funcs) > 0: - self.data.fitted_curve_real.setData(self.data.frequency_fit, self.data.epsilon_fit.real) - self.data.fitted_curve_imag.setData(self.data.frequency_fit, self.data.epsilon_fit.imag) + print "funcs > 0:",self.data.frequency_fit, self.data.epsilon_fit + self.data.fitted_curve_real.setData(x=self.data.frequency_fit, y=self.data.epsilon_fit.real) + self.data.fitted_curve_imag.setData(x=self.data.frequency_fit, y=self.data.epsilon_fit.imag) else: - self.data.fitted_curve_real.setData([np.nan],[np.nan]) - self.data.fitted_curve_imag.setData([np.nan],[np.nan]) + self.data.fitted_curve_real.setData(x=np.array([np.nan]),y=np.array([np.nan])) + self.data.fitted_curve_imag.setData(x=np.array([np.nan]),y=np.array([np.nan])) def updateIntermediatePlot(self, freq, intermediate_data): diff --git a/QDSMain.py b/QDSMain.py index 1cf385f..f58e0eb 100644 --- a/QDSMain.py +++ b/QDSMain.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'QDSMain.ui' # -# Created: Wed Apr 16 14:28:54 2014 +# Created: Mon Jun 2 19:55:32 2014 # by: PyQt4 UI code generator 4.10.4 # # WARNING! All changes made in this file will be lost! @@ -65,6 +65,8 @@ class Ui_MainWindow(object): self.menubar = QtGui.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 956, 22)) self.menubar.setObjectName(_fromUtf8("menubar")) + self.menuExtras = QtGui.QMenu(self.menubar) + self.menuExtras.setObjectName(_fromUtf8("menuExtras")) MainWindow.setMenuBar(self.menubar) self.statusbar = QtGui.QStatusBar(MainWindow) self.statusbar.setObjectName(_fromUtf8("statusbar")) @@ -119,6 +121,10 @@ class Ui_MainWindow(object): icon5.addPixmap(QtGui.QPixmap(_fromUtf8(":/icons/qds_fit_abort.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionActionAbortFit.setIcon(icon5) self.actionActionAbortFit.setObjectName(_fromUtf8("actionActionAbortFit")) + self.actionShow_Derivative = QtGui.QAction(MainWindow) + self.actionShow_Derivative.setObjectName(_fromUtf8("actionShow_Derivative")) + self.menuExtras.addAction(self.actionShow_Derivative) + self.menubar.addAction(self.menuExtras.menuAction()) self.toolBar.addAction(self.actionAdd_Peak) self.toolBar.addAction(self.actionAdd_Cond) self.toolBar.addAction(self.actionAdd_PowerLaw) @@ -134,6 +140,7 @@ class Ui_MainWindow(object): def retranslateUi(self, MainWindow): MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None)) + self.menuExtras.setTitle(_translate("MainWindow", "Extras", None)) self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar", None)) self.actionAdd_Peak.setText(_translate("MainWindow", "Add Peak", None)) self.actionAdd_Cond.setText(_translate("MainWindow", "Add Cond.", None)) @@ -148,6 +155,7 @@ class Ui_MainWindow(object): self.actionYAFF.setToolTip(_translate("MainWindow", "Fit with YAFF", None)) self.actionActionAbortFit.setText(_translate("MainWindow", "Abort Fit", None)) self.actionActionAbortFit.setShortcut(_translate("MainWindow", "Ctrl+C", None)) + self.actionShow_Derivative.setText(_translate("MainWindow", "Show Derivative", None)) from pyqtgraph import PlotWidget import images_rc diff --git a/QDSMain.ui b/QDSMain.ui index dd25060..7e04d17 100644 --- a/QDSMain.ui +++ b/QDSMain.ui @@ -67,6 +67,13 @@ 22 + + + Extras + + + + @@ -203,6 +210,11 @@ Ctrl+C + + + Show Derivative + + diff --git a/StaticGroupBox.py b/StaticGroupBox.py index 5657101..5e6d11b 100644 --- a/StaticGroupBox.py +++ b/StaticGroupBox.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'StaticGroupBox.ui' # -# Created: Wed Apr 16 14:28:54 2014 +# Created: Mon Jun 2 19:55:33 2014 # by: PyQt4 UI code generator 4.10.4 # # WARNING! All changes made in this file will be lost! diff --git a/YAFFConfig.py b/YAFFConfig.py index 5a8ffca..2920c7d 100644 --- a/YAFFConfig.py +++ b/YAFFConfig.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'YAFFConfig.ui' # -# Created: Wed Apr 16 14:28:55 2014 +# Created: Mon Jun 2 19:55:33 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 083ac1e..1865767 100644 --- a/YAFFparameters.py +++ b/YAFFparameters.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'YAFFparameters.ui' # -# Created: Wed Apr 16 14:28:55 2014 +# Created: Mon Jun 2 19:55:33 2014 # by: PyQt4 UI code generator 4.10.4 # # WARNING! All changes made in this file will be lost! diff --git a/data.py b/data.py index 851f89b..6e55867 100644 --- a/data.py +++ b/data.py @@ -11,8 +11,8 @@ class Data: 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 - self.epsilon_fit = die_real*0 + 1j * die_imag*0 + self.frequency_fit = frequency[:] + 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)) @@ -20,8 +20,8 @@ class Data: symbolBrush=(255,127,0,127)) 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(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.fitted_curve_imag = pg.PlotDataItem(x=[np.nan], y=[np.nan], pen=myPen_imag) + self.fitted_curve_real = pg.PlotDataItem(x=[np.nan], y=[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()] @@ -39,6 +39,7 @@ class Data: def set_data(self,f,e_real,e_imag): self.frequency = f + self.frequency_fit = f[:] self.epsilon = e_real + 1j*e_imag self.epsilon_fit = 0*e_real + 1j*e_imag*0 self.fit_limits = [f.min(), f.max(), e_imag.min(), e_imag.max()] diff --git a/images_rc.py b/images_rc.py index 8984e49..a8dcb5c 100644 --- a/images_rc.py +++ b/images_rc.py @@ -2,7 +2,7 @@ # Resource object code # -# Created: Mi. Apr. 16 14:28:54 2014 +# Created: Mo. Juni 2 19:55:32 2014 # by: The Resource Compiler for PyQt (Qt v4.8.5) # # WARNING! All changes made in this file will be lost!