315 lines
8.8 KiB
Python
315 lines
8.8 KiB
Python
from __future__ import annotations
|
|
|
|
import copy
|
|
|
|
from numpy import argsort
|
|
|
|
from . import Relations
|
|
from ..Qt import QtWidgets, QtCore
|
|
from ..data.container import FitContainer
|
|
from ..graphs.graphwindow import QGraphWindow
|
|
|
|
|
|
class ApodizationCommand(QtWidgets.QUndoCommand):
|
|
def __init__(self, data, apod_values: list, apod_func: object):
|
|
super().__init__('Apodization')
|
|
|
|
self.__data = data
|
|
self.__y = copy.deepcopy(data.data.y)
|
|
self.__apod_func = apod_func
|
|
self.__apod_values = apod_values
|
|
|
|
def undo(self):
|
|
# doing a copy (again) to ensure two different objects
|
|
self.__data.y = copy.deepcopy(self.__y)
|
|
|
|
def redo(self):
|
|
self.__data.apply('ap', (self.__apod_values, self.__apod_func))
|
|
|
|
|
|
class CutCommand(QtWidgets.QUndoCommand):
|
|
def __init__(self, data, *limits):
|
|
super().__init__('Apodization')
|
|
|
|
self.__data = data
|
|
self.__data_data = copy.deepcopy(data.data)
|
|
self.__limits = limits
|
|
|
|
def undo(self):
|
|
# doing a copy (again) to ensure two different objects
|
|
self.__data.data = copy.deepcopy(self.__data_data)
|
|
|
|
def redo(self):
|
|
self.__data.apply('cut', self.__limits)
|
|
|
|
|
|
class PhaseCommand(QtWidgets.QUndoCommand):
|
|
def __init__(self, data, ph0: float, ph1: float, pvt: float):
|
|
super().__init__('Phase correction')
|
|
|
|
self.__phase = (ph0, ph1, pvt)
|
|
self.__data = data
|
|
|
|
def undo(self):
|
|
self.__data.apply('ph', (-self.__phase[0], -self.__phase[1], self.__phase[2]))
|
|
|
|
def redo(self):
|
|
self.__data.apply('ph', self.__phase)
|
|
|
|
|
|
class AutophaseCommand(QtWidgets.QUndoCommand):
|
|
def __init__(self, data, pvt: float):
|
|
super().__init__('Autophase')
|
|
|
|
self.__data = data
|
|
self.__data_data = copy.deepcopy(data.data)
|
|
self.__pvt = pvt
|
|
|
|
def undo(self):
|
|
self.__data.data = copy.deepcopy(self.__data_data)
|
|
|
|
def redo(self):
|
|
self.__data.apply('autoph', (self.__pvt,))
|
|
|
|
|
|
class ShiftCommand(QtWidgets.QUndoCommand):
|
|
def __init__(self, data, value, mode):
|
|
super().__init__('Fourier')
|
|
|
|
self.__data = data
|
|
self.__original = copy.deepcopy(self.__data.data)
|
|
self.__args = (value, mode)
|
|
|
|
def undo(self):
|
|
self.__data.data = copy.deepcopy(self.__original)
|
|
|
|
def redo(self):
|
|
self.__data.apply('ls', self.__args)
|
|
|
|
|
|
class EditCommand(QtWidgets.QUndoCommand):
|
|
def __init__(self, data, *args):
|
|
super().__init__('Edit signal')
|
|
|
|
self.__data = data
|
|
self.__arguments = args
|
|
self.__original = copy.deepcopy(self.__data.data)
|
|
|
|
def undo(self):
|
|
self.__data.data = copy.deepcopy(self.__original)
|
|
|
|
def redo(self):
|
|
self.__data.edit_signal(*self.__arguments)
|
|
|
|
|
|
class NormCommand(QtWidgets.QUndoCommand):
|
|
def __init__(self, data, mode):
|
|
super().__init__('Normalize')
|
|
|
|
self.__data = data
|
|
self.__mode = mode
|
|
self.__scale = 1.
|
|
|
|
def undo(self):
|
|
self.__data.y *= self.__scale
|
|
self.__data.y_err *= self.__scale
|
|
|
|
def redo(self):
|
|
max_value = self.__data.y.max()
|
|
self.__data.apply('norm', (self.__mode,))
|
|
self.__scale = max_value / self.__data.y.max()
|
|
|
|
|
|
class CenterCommand(QtWidgets.QUndoCommand):
|
|
def __init__(self, data):
|
|
super().__init__('Normalize')
|
|
|
|
self.__data = data
|
|
self.__offset = 0.
|
|
|
|
def undo(self):
|
|
_x = self.__data.data.x
|
|
_x += self.__offset
|
|
self.__data.x = _x
|
|
|
|
def redo(self):
|
|
x0 = self.__data.x[0]
|
|
self.__data.apply('center', ())
|
|
self.__offset = x0 - self.__data.x[0]
|
|
|
|
|
|
class ZerofillCommand(QtWidgets.QUndoCommand):
|
|
def __init__(self, data):
|
|
super().__init__('Zero filling')
|
|
|
|
self.__data = data
|
|
|
|
def undo(self):
|
|
self.__data.apply('zf', (-1,))
|
|
|
|
def redo(self):
|
|
self.__data.apply('zf', (1,))
|
|
|
|
|
|
class BaselineCommand(QtWidgets.QUndoCommand):
|
|
def __init__(self, data):
|
|
super().__init__('Baseline correction')
|
|
|
|
self.__baseline = None
|
|
self.__data = data
|
|
|
|
def undo(self):
|
|
self.__data.y += self.__baseline
|
|
|
|
def redo(self):
|
|
y_prev = self.__data.y[-1]
|
|
self.__data.apply('bl', tuple())
|
|
self.__baseline = y_prev - self.__data.y[-1]
|
|
|
|
|
|
class BaselineSplineCommand(QtWidgets.QUndoCommand):
|
|
def __init__(self, data, baseline):
|
|
super().__init__('Baseline correction')
|
|
|
|
self.__baseline = baseline
|
|
self.__data = data
|
|
|
|
def undo(self):
|
|
self.__data.apply('bls', (-self.__baseline,))
|
|
|
|
def redo(self):
|
|
self.__data.apply('bls', (self.__baseline,))
|
|
|
|
|
|
class FourierCommand(QtWidgets.QUndoCommand):
|
|
def __init__(self, data):
|
|
super().__init__('Fourier')
|
|
|
|
self.__data = data
|
|
self.__original = copy.deepcopy(self.__data.data)
|
|
|
|
def undo(self):
|
|
self.__data.data = copy.deepcopy(self.__original)
|
|
|
|
def redo(self):
|
|
self.__data.apply('ft', tuple())
|
|
|
|
|
|
class SortCommand(QtWidgets.QUndoCommand):
|
|
def __init__(self, data):
|
|
super().__init__('Sort')
|
|
|
|
self.__data = data
|
|
self.__sort = None
|
|
|
|
def undo(self):
|
|
self.__data.unsort(self.__sort)
|
|
|
|
def redo(self):
|
|
self.__sort = argsort(argsort(self.__data.data.x))
|
|
self.__data.apply('sort', tuple())
|
|
|
|
|
|
class DeleteGraphCommand(QtWidgets.QUndoCommand):
|
|
def __init__(self, container: dict, key: str,
|
|
signal1: QtCore.pyqtSignal, signal2: QtCore.pyqtSignal):
|
|
super().__init__('Delete graph')
|
|
# Deletion of GraphWindow is more complicated because C++ object is destroyed
|
|
|
|
self.__container = container
|
|
_value = self.__container[key]
|
|
self.__value = self.__container[key].get_state()
|
|
self.__key = key
|
|
self.__signal_add = signal1
|
|
self.__signal_remove = signal2
|
|
|
|
def redo(self):
|
|
self.__signal_remove.emit(self.__key)
|
|
del self.__container[self.__key]
|
|
|
|
def undo(self):
|
|
q = QGraphWindow().set_state(self.__value)
|
|
self.__container[self.__key] = q
|
|
self.__signal_add.emit(self.__key)
|
|
|
|
|
|
class DeleteCommand(QtWidgets.QUndoCommand):
|
|
def __init__(self, container: dict, keys: list[str], graphs: dict, graphid: str,
|
|
signal1: QtCore.pyqtSignal, signal2: QtCore.pyqtSignal):
|
|
super().__init__('Delete data')
|
|
|
|
self.__container = container
|
|
self.__graph_container = graphs
|
|
self.__graph_key = graphid
|
|
self.__value = {}
|
|
for k in keys:
|
|
self.__value[k] = self.__container[k]
|
|
self.__keys = tuple(keys)
|
|
self.__signal_add = signal1
|
|
self.__signal_remove = signal2
|
|
|
|
def redo(self):
|
|
# stop graph from rescaling and updating legend
|
|
self.__graph_container[self.__graph_key].block(True)
|
|
|
|
self.__signal_remove.emit(list(self.__keys[::-1]))
|
|
for sid in self.__keys[::-1]:
|
|
val = self.__value[sid]
|
|
|
|
if isinstance(val, FitContainer):
|
|
try:
|
|
self.__container[val.fitted_key]._fits.remove(sid)
|
|
except KeyError:
|
|
pass
|
|
|
|
for (flag1, flag2) in ((Relations.isFitPartOf, Relations.hasFitPart), (Relations.hasFitPart, Relations.isFitPartOf)):
|
|
for related_item in val.get_relation(flag1):
|
|
try:
|
|
self.__container[related_item].remove_relation(flag2, sid)
|
|
except KeyError:
|
|
pass
|
|
|
|
del self.__container[sid]
|
|
|
|
self.__graph_container[self.__graph_key].block(False)
|
|
|
|
def undo(self):
|
|
# stop graph from rescaling and updating legend
|
|
self.__graph_container[self.__graph_key].block(True)
|
|
|
|
for sid in self.__keys:
|
|
val = self.__value[sid]
|
|
self.__container[sid] = val
|
|
|
|
if isinstance(val, FitContainer):
|
|
try:
|
|
self.__container[val.fitted_key]._fits.append(sid)
|
|
except KeyError:
|
|
pass
|
|
|
|
for (flag1, flag2) in (('isFitPartOf', 'hasFitPartOf'), ('hasFitPartOf', 'isFitPartOf')):
|
|
for related_item in val.get_relation(flag1):
|
|
try:
|
|
self.__container[related_item].add_relation(flag2, sid)
|
|
except KeyError:
|
|
pass
|
|
|
|
self.__signal_add.emit(list(self.__keys), self.__graph_key)
|
|
|
|
self.__graph_container[self.__graph_key].block(False)
|
|
|
|
|
|
class EvalCommand(QtWidgets.QUndoCommand):
|
|
def __init__(self, container: dict, key: str, new_data, title: str):
|
|
super().__init__(title)
|
|
self.__container = container
|
|
self.__value = copy.deepcopy(self.__container[key].data)
|
|
self.__replacement = new_data
|
|
self.__key = key
|
|
|
|
def redo(self):
|
|
self.__container[self.__key].data = self.__replacement
|
|
|
|
def undo(self):
|
|
self.__container[self.__key].data = self.__value
|