175 lines
5.2 KiB
Python
175 lines
5.2 KiB
Python
from PyQt4.QtCore import QObject, pyqtSignal, Qt, pyqtSlot
|
|
from PyQt4.QtGui import QColor
|
|
import numpy as np
|
|
import pyqtgraph as pg
|
|
import abc
|
|
|
|
__author__ = 'markusro'
|
|
|
|
class QABCMeta(abc.ABCMeta, QObject.__class__):
|
|
"""
|
|
Allows us to use abstract base class module to fixate the container API.
|
|
|
|
The metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases.
|
|
|
|
This means the BaseContainer's metaclass must also be a subclass of QObject, as
|
|
the BaseContainer is itself a subclass of QObject.
|
|
|
|
This class provides a suitable metaclass.
|
|
"""
|
|
pass
|
|
|
|
|
|
class BaseContainer(QObject):
|
|
"""
|
|
This class provides placeholders (or default) methods for "container" objects.
|
|
These objects are basically the different fit elements for dielectric spectroscopy.
|
|
Specific containers are implemented in the container.py module.
|
|
|
|
"""
|
|
__metaclass__ = QABCMeta
|
|
|
|
# TODO generalize the base class so that we can use plugins (self-contained fit functions)
|
|
changedData = pyqtSignal()
|
|
removeObj = pyqtSignal(QObject)
|
|
|
|
def __init__( self, plt_real=None, plt_imag=None, limits=None ):
|
|
super(BaseContainer, 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._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
|
|
self._abort = False
|
|
|
|
def set_limits( self, limits ):
|
|
self.limits = limits
|
|
self.update_data()
|
|
|
|
@pyqtSlot(bool)
|
|
def abort( self, abort=False ):
|
|
self._abort = abort
|
|
|
|
@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._id_label = id
|
|
|
|
@property
|
|
def color( self ):
|
|
return self._color
|
|
|
|
@color.setter
|
|
def color( self, c ):
|
|
self._color = 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 ):
|
|
return self._widget
|
|
|
|
@widget.setter
|
|
def widget( self, wdgt ):
|
|
self._widget = wdgt
|
|
self._widget.changedTable.connect(self.update_data) # TODO better to use self.setParameter
|
|
self.removeObj.connect(self._widget.deleteLater)
|
|
self._widget.removeMe.connect(self.removeMe)
|
|
|
|
def get_parameter( self ):
|
|
p = self.widget.getTable() # TODO ugly ... should return self._beta etc ...?
|
|
return p
|
|
|
|
def set_parameter( self, beta, sd_beta=None ):
|
|
self._beta = beta
|
|
self._sd_beta = sd_beta
|
|
self.widget.update_table(beta, sd_beta)
|
|
self.update_data()
|
|
|
|
def get_fixed( self ):
|
|
p = self.widget.fixedParameter()
|
|
return p
|
|
|
|
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 update_data( self ):
|
|
self._frequency = np.logspace(np.log10(self.limits[0]), np.log10(self.limits[1]), 256)
|
|
self._data = self.function(self.get_parameter(), 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.function(self.get_parameter(), x)
|
|
return np.array([x, data[0], data[1]]).T
|
|
|
|
def subtractMe(self, flag):
|
|
print "subtract"
|
|
self._data = -self._data
|
|
self.changedData.emit()
|
|
|
|
def clear_data( self ):
|
|
self.data_curve_real.setData(x=[np.nan], y=[np.nan])
|
|
self.data_curve_imag.setData(x=[np.nan], y=[np.nan])
|
|
|
|
@abc.abstractmethod
|
|
def start_parameter(self, position):
|
|
raise NotImplementedError("This needs to be implemented in your container subclass")
|
|
|
|
@abc.abstractmethod
|
|
def function( self, p, x ):
|
|
if self._abort:
|
|
raise StopIteration
|
|
raise NotImplementedError("This needs to be implemented in your container subclass")
|
|
|
|
|