Preliminary gracedriver works, coloring of the peaks fixed, result output: peaks ordered by tau value

This commit is contained in:
Markus Rosenstihl 2014-09-24 16:25:58 +02:00
parent 30ded06b95
commit fcee731d35
6 changed files with 157 additions and 66 deletions

View File

@ -12,16 +12,18 @@ import libyaff
def id_to_color( id ):
colors = [
QColor(54, 22, 115),
QColor(160, 16, 36),
QColor(45, 142, 15),
QColor(255, 255, 255),
QColor(168, 149, 17),
QColor(45, 142, 15),
QColor(160, 16, 36),
QColor(54, 22, 115),
QColor(36, 10, 85),
QColor(118, 8, 23),
QColor(31, 105, 7),
QColor(124, 109, 8),
]
return colors[id%len(colors)]
chosen_color = colors[id%len(colors)]
return chosen_color
class FitFunctionCreator(QObject):

View File

@ -2,8 +2,8 @@
# Form implementation generated from reading ui file 'ConductivityGroupBox.ui'
#
# Created: Tue Jul 29 08:56:48 2014
# by: PyQt4 UI code generator 4.11.1
# Created: Tue Sep 23 21:38:12 2014
# by: PyQt4 UI code generator 4.11.1
#
# WARNING! All changes made in this file will be lost!
@ -12,21 +12,19 @@ from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8( s ):
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate( context, text, disambig ):
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate( context, text, disambig ):
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_ConductivityGroupBox(object):
def setupUi( self, ConductivityGroupBox ):
def setupUi(self, ConductivityGroupBox):
ConductivityGroupBox.setObjectName(_fromUtf8("ConductivityGroupBox"))
ConductivityGroupBox.resize(253, 156)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
@ -63,7 +61,7 @@ class Ui_ConductivityGroupBox(object):
self.checkBox_3.setText(_fromUtf8(""))
self.checkBox_3.setChecked(True)
self.checkBox_3.setObjectName(_fromUtf8("checkBox_3"))
self.gridLayout.addWidget(self.checkBox_3, 3, 3, 1, 1, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)
self.gridLayout.addWidget(self.checkBox_3, 3, 3, 1, 1, QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter)
self.label_2 = QtGui.QLabel(ConductivityGroupBox)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
@ -137,25 +135,18 @@ class Ui_ConductivityGroupBox(object):
QtCore.QObject.connect(self.removeButton, QtCore.SIGNAL(_fromUtf8("clicked()")), ConductivityGroupBox.hide)
QtCore.QMetaObject.connectSlotsByName(ConductivityGroupBox)
def retranslateUi( self, ConductivityGroupBox ):
def retranslateUi(self, ConductivityGroupBox):
ConductivityGroupBox.setWindowTitle(_translate("ConductivityGroupBox", "GroupBox", None))
ConductivityGroupBox.setTitle(_translate("ConductivityGroupBox", "Conductivity", None))
self.pwrSigma_sd.setText(_translate("ConductivityGroupBox", "TextLabel", None))
self.label_2.setText(_translate("ConductivityGroupBox",
"<html><head/><body><p>σ\'<span style=\" vertical-align:sub;\">(DC)</span></p></body></html>",
None))
self.label_2.setText(_translate("ConductivityGroupBox", "<html><head/><body><p>σ\'<span style=\" vertical-align:sub;\">(DC)</span></p></body></html>", None))
self.label.setText(_translate("ConductivityGroupBox", "Fix", None))
self.removeButton.setText(_translate("ConductivityGroupBox", "Remove", None))
self.label_4.setText(_translate("ConductivityGroupBox", "α", None))
self.rSigma_sd.setText(_translate("ConductivityGroupBox", "TextLabel", None))
self.rSigma.setToolTip(_translate("ConductivityGroupBox",
"<html><head/><body><p>DC conductivity, should only be seen in the imaginary permitivity. 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>",
None))
self.rSigma.setToolTip(_translate("ConductivityGroupBox", "<html><head/><body><p>DC conductivity, should only be seen in the imaginary permitivity. 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>", None))
self.subtractConductivityButton.setText(_translate("ConductivityGroupBox", "Hide", None))
self.label_3.setText(
_translate("ConductivityGroupBox", "<html><head/><body><p>σ&quot;</p></body></html>", None))
self.iSigma.setToolTip(_translate("ConductivityGroupBox",
"<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>",
None))
self.label_3.setText(_translate("ConductivityGroupBox", "<html><head/><body><p>σ&quot;</p></body></html>", None))
self.iSigma.setToolTip(_translate("ConductivityGroupBox", "<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>", None))
self.iSigma_sd.setText(_translate("ConductivityGroupBox", "TextLabel", None))

View File

@ -32,7 +32,6 @@ class BaseObject(QObject):
self.limits = limits
# private varaibles
#self.functions = Functions()
self._color = QColor("white")
self._id_label = None
@ -47,6 +46,10 @@ class BaseObject(QObject):
self._param_number = 0
self._abort = False
def set_limits(self, limits):
self.limits = limits
self.updateData()
@pyqtSlot(bool)
def abort(self, abort=False):
self._abort = abort
@ -86,8 +89,9 @@ class BaseObject(QObject):
@color.setter
def color(self, c):
self._color = c
self.data_curve_real.setPen(c)
self.data_curve_imag.setPen(c)
print c
self.data_curve_real.setPen(color=c, style=Qt.DotLine, width=2.5)
self.data_curve_imag.setPen(color=c, style=Qt.DotLine, width=2.5)
@property
def widget(self):
@ -124,6 +128,7 @@ class BaseObject(QObject):
self.changedData.emit()
def updateData(self):
self._frequency = np.logspace(np.log10(self.limits[0]), np.log10(self.limits[1]), 256)
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])
@ -190,7 +195,6 @@ class Static(BaseObject):
def function( self, p, x ):
BaseObject.function(self,p,x)
eps_inf = p[0]
static = np.ones( (2,x.size) )*eps_inf
static[1,:] *= 0 # set imag part zero

View File

@ -63,6 +63,7 @@ class BaseWidget(QGroupBox):
self.errors = []
self.names = []
self.selector_mask = None # TODO: clean up
self.func_type="None"
def remove(self):
self.removeMe.emit()
@ -149,6 +150,8 @@ class PeakWidget(BaseWidget,QGroupBox):
"beta"
]
self.func_type="HN"
self.inputs = [
self.ui.doubleSpinBox_1,
self.ui.doubleSpinBox_2,
@ -163,9 +166,6 @@ class PeakWidget(BaseWidget,QGroupBox):
self.ui.label_8,
]
for dsb in self.inputs:
dsb.valueChanged.connect(self.changeValues)
@ -183,7 +183,7 @@ class PeakWidget(BaseWidget,QGroupBox):
self.ui.checkBox_3.setChecked(False)
self.ui.checkBox_3.setDisabled(False)
self.ui.checkBox_4.setChecked(False)
self.ui.checkBox_3.setDisabled(False)
self.ui.checkBox_4.setDisabled(False)
self.ui.doubleSpinBox_3.setDisabled(False)
self.ui.doubleSpinBox_4.setDisabled(False)
@ -202,8 +202,10 @@ class PeakWidget(BaseWidget,QGroupBox):
self.ui.checkBox_3.setChecked(True)
self.ui.checkBox_3.setDisabled(True)
self.ui.checkBox_4.setChecked(False)
self.func_type = "CD"
else:
self.ui.doubleSpinBox_3.setDisabled(False)
self.func_type = "HN"
def _distrib_debye(self, state):
if state:
@ -215,10 +217,12 @@ class PeakWidget(BaseWidget,QGroupBox):
self.ui.checkBox_3.setDisabled(True)
self.ui.checkBox_4.setChecked(True)
self.ui.checkBox_4.setDisabled(True)
self.func_type = "Debye"
else:
self.ui.doubleSpinBox_3.setDisabled(False)
self.ui.doubleSpinBox_4.setDisabled(False)
self.func_type = "HN"
def _distrib_cc(self, state):
@ -229,8 +233,12 @@ class PeakWidget(BaseWidget,QGroupBox):
self.ui.checkBox_3.setChecked(False)
self.ui.checkBox_4.setChecked(True)
self.ui.checkBox_4.setDisabled(True)
self.func_type = "CC"
else:
self.ui.doubleSpinBox_4.setDisabled(False)
self.func_type = "HN"
def setId(self, id):
@ -291,6 +299,7 @@ class StaticWidget(BaseWidget, QGroupBox):
dsb.valueChanged.connect(self.changeValues)
self.ui.removeButton.clicked.connect(self.remove)
self.func_type=r"$\epsilon_\infty$"
@ -314,11 +323,12 @@ class ConductivityWidget(BaseWidget, QGroupBox):
self.ui.removeButton.clicked.connect(self.remove)
#self.ui.subtractConductivityButton.connect(self.subtract)
self.func_type="Cond."
self.names = [
"iSigma",
"rSigma",
"pwrSigma",
"iSig",
"rSig",
"pwrSig",
]
self.errors = [self.ui.iSigma_sd,
self.ui.rSigma_sd,
@ -350,6 +360,7 @@ class PowerLawWidget(BaseWidget):
self.ui.doubleSpinBox_2 = LogFSpinBox(self)
self.ui.gridLayout.addWidget(self.ui.doubleSpinBox_2,1,1)
self.ui.removeButton.clicked.connect(self.remove)
self.func_type="Power Law"
self.names = ["Amp", "pwrAmp"]
self.errors = [self.ui.label_5,
@ -371,8 +382,10 @@ class YaffWidget(BaseWidget):
def __init__(self, parent=None):
#QGroupBox.__init__(self)
BaseWidget.__init__(self)
super(YaffWidget, self).__init__(parent)
self.func_type="YAFF" # Todo wie bei peak für gg gb gge etc.
self.ui = YAFFparameters.Ui_Form()
self.ui.setupUi(self)
self.ui.doubleSpinBox_1.setParent(None)
@ -473,11 +486,13 @@ class YaffWidget(BaseWidget):
@pyqtSlot(int)
def change_model(self,ndx):
#ndx = self.ui.comboBox.currentIndex()
mask = [
(0,0,0,0,1,1,1,1,1,1),
(0,0,0,0,1,1,1,1,0,0),
(0,0,0,0,0,0,0,0,1,1),
(0,0,0,0,0,0,0,0,0,0),
mask = [ # 0 show, 1 hide
(0,0,0,0,1,1,1,1,1,1), # GG
(0,0,0,0,1,1,1,1,0,0), # GGe
(0,1,1,1,1,0,0,0,1,1), # Gb
(0,0,0,0,0,0,0,0,1,1), # GG + Gb
(0,0,0,0,0,0,0,0,0,0), # GGe + Gb
]
self.names = []

110
QDS.py
View File

@ -2,10 +2,13 @@
# -*- encoding: utf-8 -*-
_author_ = "Markus Rosenstihl"
import hashlib,uuid
import time
import os,sys,re,signal
import matplotlib
matplotlib.use('agg')
from matplotlib import pyplot
from matplotlib.colors import hex2color
#matplotlib.rc_file("default.mplrc")
@ -15,7 +18,6 @@ from PyQt4.QtCore import *
from PyQt4.QtGui import *
import numpy as np
import time
import pyqtgraph as pg
from Container import Conductivity, PowerComplex, Static, Peak, YAFF
@ -48,7 +50,7 @@ class AppWindow(QMainWindow):
self._init_menu()
self.function_registry = FunctionRegister()
self.session_id = uuid.uuid4()
self.peakId = 0
self.parameterWidget = ParameterWidget()
@ -68,8 +70,11 @@ class AppWindow(QMainWindow):
self.ui.pgPlotWidget_imag.addItem(self.fit_boundary_imag)
self.ui.pgPlotWidget_real.addItem(self.fit_boundary_real)
self.fit_boundary_imag.sigRegionChanged.connect(self._update_fit_boundary)
self.fit_boundary_real.sigRegionChanged.connect(self._update_fit_boundary)
# fit boundary signals
self.fit_boundary_imag.sigRegionChanged.connect(self._update_fit_boundary_imag)
self.fit_boundary_imag.sigRegionChangeFinished.connect(self.updatePlot)
self.fit_boundary_real.sigRegionChanged.connect(self._update_fit_boundary_real)
self.fit_boundary_real.sigRegionChangeFinished.connect(self.updatePlot)
for pltwidgt in (self.ui.pgPlotWidget_real, self.ui.pgPlotWidget_imag):
pltwidgt.setLogMode(x=True, y=True)
@ -240,40 +245,86 @@ class AppWindow(QMainWindow):
else:
f = open("fitresults.log", "a")
# prepare header
header = "# Date: {date}\n".format(date=time.ctime())
header += "{n1:13}{n2:13}".format(n1="# 0:T", n2="1:invT")
file_id = hashlib.md5(open(self._file_paths[self._current_file_index]).read()).hexdigest()
pre_header = "# Date: {date}\n".format(date=time.strftime("%Y-%m-%d"))
pre_header += "# Time: {time}\n# SessionID={id}\n".format(time=time.strftime("%H:%M:%S"), id=self.session_id)
pars = []
base_filename = os.path.splitext(self.filepath)[0]
base_filename, file_ext = os.path.splitext(self.filepath)
# print "Registered Functions (saveFitResult): ",self.function_registry.get_registered_functions()
header = "{n1:13}{n2:13}".format(n1="# 0:T", n2="1:invT")
varnum = 2 # T, invT are the first two columns
# sort peaks by time constant tau
sorted_functions = list()
tau_comp = 0
for i_fcn, fcn in enumerate(self.function_registry.get_registered_functions()):
if fcn.id_string == "hn":
for i,varname in enumerate(fcn.widget.names):
if varname == "tau":
if fcn._beta[i] <= tau_comp:
sorted_functions.append(fcn)
else:
sorted_functions.insert(0,fcn)
tau_comp = fcn._beta[i]
# eps_infty to the front
for a in self.function_registry.get_registered_functions():
print a.id_string
if a.id_string == "eps_infty":
sorted_functions.insert(0,a)
print a
# sort the rest lexigraphically
for a in self.function_registry.get_registered_functions():
if a.id_string == "pwr":
sorted_functions.append(a)
print a
for a in self.function_registry.get_registered_functions():
if a.id_string == "cond":
sorted_functions.append(a)
print a
for a in self.function_registry.get_registered_functions():
if a.id_string == "yaff":
print a
sorted_functions.append(a)
print sorted_functions
for i_fcn, fcn in enumerate(sorted_functions):
fit_function_name = fcn.id_string
for i, name in enumerate(fcn.widget.names): # get variable names
header += "{n:13}{n_sd:13}".format(n="%i:%s"%(varnum, name), n_sd="%i:%s_sd"%(varnum+1, name))
varnum += 2
# write for each function extra file
# write for each function an extra file
fit_filename = "%s_%i.fit"%(base_filename, i_fcn)
f_fcn = open(fit_filename, 'w')
f_fcn.write("# %s\n"%fit_function_name)
f_fcn.flush()
np.savetxt(f_fcn, fcn.resampleData(self.data.frequency))
f_fcn.close()
# retrieve correct function type peak
#if fit_function_name == "hn":
f_fcn.write("# type=%s\n"%fcn.widget.func_type)
f_fcn.write("# SourceID=%s\n"%file_id)
#else:
# f_fcn.write("# type=%s\n"%fit_function_name)
for i,par in enumerate(fcn._beta): # params # TODO: ughh
if fcn._selector_mask is not None:
if fcn._selector_mask[i]:
pars.extend([par])
pars.extend([fcn._sd_beta[i]])
f_fcn.write('# param=%s %e %e\n'%(fcn.widget.names[i], par, fcn._sd_beta[i]))
else:
pars.extend([par])
pars.extend([fcn._sd_beta[i]])
f_fcn.write('# param=%s %e %e\n'%(fcn.widget.names[i], par, fcn._sd_beta[i]))
# finish writing fit function file
f_fcn.flush()
np.savetxt(f_fcn, fcn.resampleData(self.data.frequency))
f_fcn.close()
# append fit limits header
header += "%-13s%-13s\n"%("fit_xlow", "fit_xhigh")
# write new header if fit model changed
# write new header if fit model changed TODO: more robust detection
if self._last_written_header != header:
f.write(pre_header)
f.write(header)
f.flush()
self._last_written_header = header
@ -387,9 +438,12 @@ class AppWindow(QMainWindow):
def addPeak(self, pos):
id_list = [ key.id_num for key in
self.function_registry.get_registered_functions().keys()
if key.id_label == 'hn']
self.function_registry.get_registered_functions()
if key.id_string == 'hn']
for k in self.function_registry.get_registered_functions():
print k.id_num,k.id_label
self.peakId = 1
print id_list
while self.peakId in id_list:
self.peakId += 1
_peak = Peak(id_num=self.peakId,
@ -549,9 +603,12 @@ class AppWindow(QMainWindow):
for fcn in self.function_registry.get_registered_functions():
p0.extend(fcn.getParameter())
funcs.append(fcn)
# calculate parametrized curve
self.data.set_fit(p0, funcs)
# 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)
@ -569,10 +626,27 @@ class AppWindow(QMainWindow):
self.data.fitted_curve_real.setData(freq, intermediate_data[0])
self.data.fitted_curve_imag.setData(freq, intermediate_data[1])
def _update_fit_boundary( self ):
def _update_fit_boundary_imag( self ):
"""
Update real region when with imag reagion
"""
self.fit_boundary_real.setRegion(self.fit_boundary_imag.getRegion())
self.fit_boundary_imag.setRegion(self.fit_boundary_real.getRegion())
self._update_fit_boundary()
def _update_fit_boundary_real( self ):
"""
Update imag region when with real reagion
"""
self.fit_boundary_imag.setRegion(self.fit_boundary_real.getRegion())
self._update_fit_boundary()
def _update_fit_boundary(self):
"""
Update limits in container.
"""
for container in self.function_registry.get_registered_functions():
lims = [10**i for i in self.fit_boundary_real.getRegion()]
container.set_limits(lims)
def sigint_handler(*args):
"""

View File

@ -28,10 +28,9 @@ class grace:
np.savetxt(tmp_name, np.array([x, y]).T)
#tmp_fd.close()
self.cmds.append('READ NXY "%s"\n'%tmp_name)
self.cmds.append('S%i SYMBOL SIZE 0.6\n'%(self.data_counter))
self.cmds.append('S%i SYMBOL SIZE 0.7\n'%(self.data_counter))
self.cmds.append('S%i SYMBOL COLOR 1\n'%(self.data_counter))
#self.cmds.append('S%i SYMBOL FILL COLOR %i\n'%(self.data_counter, self.data_counter))
self.cmds.append('S%i SYMBOL FILL PATTERN 1\n'%(self.data_counter))
self.cmds.append('S%i SYMBOL 1\n'%(self.data_counter)) # No line
@ -49,6 +48,8 @@ class grace:
sym = kwds["sym"]
if sym in self.sym_map.keys():
self.cmds.append('S%i SYMBOL %i\n'%(self.data_counter, self.sym_map[sym]))
if sym in ['+', 'x', '*']:
self.cmds.append('S%i SYMBOL COLOR %i\n'%(self.data_counter, self.data_counter))
else:
print "Symbol not known: %s"%sym
@ -93,16 +94,20 @@ class grace:
if __name__ == "__main__":
print "Testing Grace driver"
nums = 50
np.random.seed(1337) # make it reproducible
nums = 30
gr = grace()
for i in xrange(20):
gr.plot(np.arange(nums), np.random.random(nums), label="label %i"%i,
t = np.linspace(0,1,nums)
for i in xrange(30):
gr.plot(t, i + np.sin(2*np.pi * 3 * t + i*0.33 ) + 0.3*np.random.random(nums),
label="label %i"%i,
ls=gr.ls_map.keys()[i%(len(gr.ls_map))],
sym=gr.sym_map.keys()[i%(len(gr.sym_map))],
)
gr.xlabel(r"xlabel / \xm\sl\N\0")
gr.ylabel(r"ylabel / \xt\sS\N\0")
gr.save("test.agr")
print "created test.agr"
os.system("xmgrace test.agr")
print "deleting test.agr"
os.remove("test.agr")