segfault on closing QDS fixed, threading simplified
This commit is contained in:
parent
4913924222
commit
eca637c35a
241
Container.py
Normal file
241
Container.py
Normal file
@ -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
|
@ -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()
|
||||
|
2
Makefile
2
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
|
||||
|
77
QDS.py
77
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+')
|
||||
|
231
data.py
231
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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user