Parameter are new initial values after fit

This commit is contained in:
dominik 2022-03-28 16:26:10 +02:00
parent 54a23702b6
commit 13de2714b5
25 changed files with 526 additions and 354 deletions

View File

@ -1,2 +0,0 @@
from .version import __version__, __releasename__

View File

@ -12,7 +12,6 @@
#
import os
import sys
import sphinx_bootstrap_theme
sys.path.append('/autohome/dominik/nmreval')
import nmreval

View File

@ -100,12 +100,12 @@ class MultiModel:
if v.default is not Parameter.empty}
for k, v in temp_dic.items():
key_ = '%s_%d' % (k, idx)
key_ = f'{k}_{idx}'
kw_dict[key_] = v
self._fun_kwargs[key_] = v
self._ext_int_kw[key_] = k
strcnt = '(%d)' % idx
strcnt = f'({idx})'
self.params += [pp+strcnt for pp in func.params]
self.name += func.name + strcnt

View File

@ -17,7 +17,7 @@ class Model(object):
elif inspect.isfunction(model):
self._init_from_function(model)
else:
raise ValueError(f'No idea how to use datatype {model}.')
raise ValueError(f'No idea how to use datatype {model!r}.')
self.lb = [i if i is not None else -inf for i in self.lb]
self.ub = [i if i is not None else inf for i in self.ub]
@ -140,7 +140,6 @@ class Model(object):
return [self.func(p, x, **kwargs)]
else:
print('multi model')
if not kwargs:
kwargs = self.fun_kwargs

View File

@ -1,3 +1,5 @@
from __future__ import annotations
from numbers import Number
from itertools import count
@ -115,6 +117,15 @@ class Parameter:
else:
return start + f'{self.value:} (fixed)'
def __add__(self, other: Parameter | float) -> float:
if isinstance(other, float):
return self.value + other
elif isinstance(other, Parameter):
return self.value + other.value
def __radd__(self, other: Parameter | float) -> float:
return self.__add__(other)
@property
def scaled_value(self):
return self.value / self.scale

View File

@ -94,8 +94,13 @@ class FitResultCreator:
correlation = corr
partial_correlation = pcorr
return FitResult(_x, _y, x_orig, y_orig, parameters, fun_kwargs, resid, nobs, nvar, model.name, stats,
idx=idx, corr=correlation, pcorr=partial_correlation, islog=islog, iscomplex=model.is_complex), part_functions
return (
FitResult(_x, _y, x_orig, y_orig, parameters, fun_kwargs, resid,
nobs, nvar, model.name, stats,
idx=idx, corr=correlation, pcorr=partial_correlation,
islog=islog, iscomplex=model.is_complex),
part_functions,
)
@staticmethod
def calc_statistics(y, residual, nobs=None, nvar=None):

View File

@ -27,6 +27,69 @@ class Ui_Dialog(object):
self.sets_comboBox.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToMinimumContentsLength)
self.sets_comboBox.setObjectName("sets_comboBox")
self.gridLayout.addWidget(self.sets_comboBox, 0, 0, 1, 1)
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok|QtWidgets.QDialogButtonBox.Retry)
self.buttonBox.setObjectName("buttonBox")
self.gridLayout.addWidget(self.buttonBox, 6, 0, 1, 2)
self.param_tableWidget = QtWidgets.QTableWidget(Dialog)
self.param_tableWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
self.param_tableWidget.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustIgnored)
self.param_tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.param_tableWidget.setAlternatingRowColors(True)
self.param_tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
self.param_tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectColumns)
self.param_tableWidget.setShowGrid(False)
self.param_tableWidget.setColumnCount(0)
self.param_tableWidget.setObjectName("param_tableWidget")
self.param_tableWidget.setRowCount(0)
self.param_tableWidget.horizontalHeader().setStretchLastSection(False)
self.gridLayout.addWidget(self.param_tableWidget, 1, 0, 1, 1)
self.groupBox = QtWidgets.QGroupBox(Dialog)
self.groupBox.setObjectName("groupBox")
self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox)
self.gridLayout_2.setContentsMargins(3, 3, 3, 3)
self.gridLayout_2.setSpacing(3)
self.gridLayout_2.setObjectName("gridLayout_2")
self.graph_checkBox = QtWidgets.QCheckBox(self.groupBox)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.graph_checkBox.sizePolicy().hasHeightForWidth())
self.graph_checkBox.setSizePolicy(sizePolicy)
self.graph_checkBox.setChecked(True)
self.graph_checkBox.setObjectName("graph_checkBox")
self.gridLayout_2.addWidget(self.graph_checkBox, 1, 1, 1, 1)
self.graph_comboBox = QtWidgets.QComboBox(self.groupBox)
self.graph_comboBox.setEnabled(False)
self.graph_comboBox.setObjectName("graph_comboBox")
self.gridLayout_2.addWidget(self.graph_comboBox, 1, 2, 1, 1)
self.curve_checkbox = QtWidgets.QCheckBox(self.groupBox)
self.curve_checkbox.setChecked(True)
self.curve_checkbox.setObjectName("curve_checkbox")
self.gridLayout_2.addWidget(self.curve_checkbox, 0, 0, 1, 1)
self.partial_checkBox = QtWidgets.QCheckBox(self.groupBox)
self.partial_checkBox.setObjectName("partial_checkBox")
self.gridLayout_2.addWidget(self.partial_checkBox, 1, 0, 1, 1)
self.parameter_checkbox = QtWidgets.QCheckBox(self.groupBox)
self.parameter_checkbox.setChecked(True)
self.parameter_checkbox.setObjectName("parameter_checkbox")
self.gridLayout_2.addWidget(self.parameter_checkbox, 0, 1, 1, 1)
self.gridLayout.addWidget(self.groupBox, 5, 0, 1, 2)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setSpacing(3)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.reject_fit_checkBox = QtWidgets.QCheckBox(Dialog)
self.reject_fit_checkBox.setObjectName("reject_fit_checkBox")
self.horizontalLayout_2.addWidget(self.reject_fit_checkBox)
self.del_prev_checkBox = QtWidgets.QCheckBox(Dialog)
self.del_prev_checkBox.setObjectName("del_prev_checkBox")
self.horizontalLayout_2.addWidget(self.del_prev_checkBox)
self.gridLayout.addLayout(self.horizontalLayout_2, 2, 0, 1, 1)
self.line = QtWidgets.QFrame(Dialog)
self.line.setFrameShape(QtWidgets.QFrame.HLine)
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line.setObjectName("line")
self.gridLayout.addWidget(self.line, 3, 0, 1, 2)
self.stack = QtWidgets.QToolBox(Dialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
@ -35,7 +98,7 @@ class Ui_Dialog(object):
self.stack.setSizePolicy(sizePolicy)
self.stack.setObjectName("stack")
self.page = QtWidgets.QWidget()
self.page.setGeometry(QtCore.QRect(0, 0, 399, 414))
self.page.setGeometry(QtCore.QRect(0, 0, 399, 346))
self.page.setObjectName("page")
self.verticalLayout = QtWidgets.QVBoxLayout(self.page)
self.verticalLayout.setContentsMargins(3, 3, 3, 3)
@ -50,7 +113,7 @@ class Ui_Dialog(object):
self.verticalLayout.addWidget(self.logy_box)
self.stack.addItem(self.page, "")
self.page_2 = QtWidgets.QWidget()
self.page_2.setGeometry(QtCore.QRect(0, 0, 399, 414))
self.page_2.setGeometry(QtCore.QRect(0, 0, 399, 346))
self.page_2.setObjectName("page_2")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.page_2)
self.verticalLayout_2.setContentsMargins(3, 3, 3, 3)
@ -67,7 +130,7 @@ class Ui_Dialog(object):
self.verticalLayout_2.addWidget(self.stats_tableWidget)
self.stack.addItem(self.page_2, "")
self.page_3 = QtWidgets.QWidget()
self.page_3.setGeometry(QtCore.QRect(0, 0, 399, 414))
self.page_3.setGeometry(QtCore.QRect(0, 0, 399, 346))
self.page_3.setObjectName("page_3")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.page_3)
self.verticalLayout_3.setContentsMargins(3, 3, 3, 3)
@ -92,64 +155,7 @@ class Ui_Dialog(object):
self.corr_tableWidget.verticalHeader().setVisible(False)
self.verticalLayout_3.addWidget(self.corr_tableWidget)
self.stack.addItem(self.page_3, "")
self.gridLayout.addWidget(self.stack, 0, 1, 4, 1)
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setSpacing(3)
self.horizontalLayout.setObjectName("horizontalLayout")
self.partial_checkBox = QtWidgets.QCheckBox(Dialog)
self.partial_checkBox.setObjectName("partial_checkBox")
self.horizontalLayout.addWidget(self.partial_checkBox)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.label_2 = QtWidgets.QLabel(Dialog)
self.label_2.setObjectName("label_2")
self.horizontalLayout.addWidget(self.label_2)
self.graph_checkBox = QtWidgets.QCheckBox(Dialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.graph_checkBox.sizePolicy().hasHeightForWidth())
self.graph_checkBox.setSizePolicy(sizePolicy)
self.graph_checkBox.setChecked(True)
self.graph_checkBox.setObjectName("graph_checkBox")
self.horizontalLayout.addWidget(self.graph_checkBox)
self.graph_comboBox = QtWidgets.QComboBox(Dialog)
self.graph_comboBox.setEnabled(False)
self.graph_comboBox.setObjectName("graph_comboBox")
self.horizontalLayout.addWidget(self.graph_comboBox)
self.gridLayout.addLayout(self.horizontalLayout, 5, 0, 1, 2)
self.line_2 = QtWidgets.QFrame(Dialog)
self.line_2.setFrameShape(QtWidgets.QFrame.HLine)
self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_2.setObjectName("line_2")
self.gridLayout.addWidget(self.line_2, 3, 0, 1, 1)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setSpacing(3)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.reject_fit_checkBox = QtWidgets.QCheckBox(Dialog)
self.reject_fit_checkBox.setObjectName("reject_fit_checkBox")
self.horizontalLayout_2.addWidget(self.reject_fit_checkBox)
self.del_prev_checkBox = QtWidgets.QCheckBox(Dialog)
self.del_prev_checkBox.setObjectName("del_prev_checkBox")
self.horizontalLayout_2.addWidget(self.del_prev_checkBox)
self.gridLayout.addLayout(self.horizontalLayout_2, 2, 0, 1, 1)
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok|QtWidgets.QDialogButtonBox.Retry)
self.buttonBox.setObjectName("buttonBox")
self.gridLayout.addWidget(self.buttonBox, 6, 0, 1, 2)
self.param_tableWidget = QtWidgets.QTableWidget(Dialog)
self.param_tableWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
self.param_tableWidget.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustIgnored)
self.param_tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.param_tableWidget.setAlternatingRowColors(True)
self.param_tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
self.param_tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectColumns)
self.param_tableWidget.setShowGrid(False)
self.param_tableWidget.setColumnCount(0)
self.param_tableWidget.setObjectName("param_tableWidget")
self.param_tableWidget.setRowCount(0)
self.param_tableWidget.horizontalHeader().setStretchLastSection(False)
self.gridLayout.addWidget(self.param_tableWidget, 1, 0, 1, 1)
self.gridLayout.addWidget(self.stack, 0, 1, 3, 1)
self.retranslateUi(Dialog)
self.stack.setCurrentIndex(0)
@ -159,6 +165,13 @@ class Ui_Dialog(object):
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Fit results"))
self.groupBox.setTitle(_translate("Dialog", "Output"))
self.graph_checkBox.setText(_translate("Dialog", "New graph"))
self.curve_checkbox.setText(_translate("Dialog", "Plot fit curve"))
self.partial_checkBox.setText(_translate("Dialog", "Plot partial functions"))
self.parameter_checkbox.setText(_translate("Dialog", "Plot parameter"))
self.reject_fit_checkBox.setText(_translate("Dialog", "Reject this fit"))
self.del_prev_checkBox.setText(_translate("Dialog", "Delete previous fits"))
self.logy_box.setText(_translate("Dialog", "logarithmic y axis"))
self.stack.setItemText(self.stack.indexOf(self.page), _translate("Dialog", "Plot"))
self.stack.setItemText(self.stack.indexOf(self.page_2), _translate("Dialog", "Statistics"))
@ -171,10 +184,5 @@ class Ui_Dialog(object):
item = self.corr_tableWidget.horizontalHeaderItem(3)
item.setText(_translate("Dialog", "Partial Corr."))
self.stack.setItemText(self.stack.indexOf(self.page_3), _translate("Dialog", "Correlations"))
self.partial_checkBox.setText(_translate("Dialog", "Plot partial functions"))
self.label_2.setText(_translate("Dialog", "Location of parameters:"))
self.graph_checkBox.setText(_translate("Dialog", "New graph"))
self.reject_fit_checkBox.setText(_translate("Dialog", "Reject this fit"))
self.del_prev_checkBox.setText(_translate("Dialog", "Delete previous fits"))
from ..lib.forms import ElideComboBox
from pyqtgraph import GraphicsLayoutWidget

View File

@ -9,7 +9,7 @@ from ...data.points import Points
from ...data.signals import Signal
from ...utils.text import convert
from ...data.bds import BDS
from ...lib.colors import Colors
from ...lib.colors import BaseColor, TUColors
from ...lib.lines import LineStyle
from ...lib.symbols import SymbolStyle, symbolcycle
from ...data.nmr import Spectrum, FID
@ -24,7 +24,7 @@ class ExperimentContainer(QtCore.QObject):
dataChanged = QtCore.pyqtSignal(str)
labelChanged = QtCore.pyqtSignal(str, str)
groupChanged = QtCore.pyqtSignal(str, str)
colors = cycle(Colors)
colors = cycle(TUColors)
def __init__(self, identifier, data, **kwargs):
super().__init__()
@ -63,25 +63,27 @@ class ExperimentContainer(QtCore.QObject):
def __len__(self):
return len(self._data)
def copy(self, full: bool = False):
def copy(self, full: bool = False, keep_color: bool = True):
if full:
# pen_dict = {
# 'symbol': self.plot_real.symbol,
# 'symbolcolor': self.plot_real.symbolcolor,
# 'symbolsize': self.plot_real.symbolsize,
# 'linestyle': self.plot_real.linestyle,
# 'linecolor': self.plot_real.linecolor,
# 'linewidth': self.plot_real.linewidth,
# }
pen_dict = {}
if keep_color:
pen_dict = {
'symbol': self.plot_real.symbol,
'symbolcolor': self.plot_real.symbolcolor,
'symbolsize': self.plot_real.symbolsize,
'linestyle': self.plot_real.linestyle,
'linecolor': self.plot_real.linecolor,
'linewidth': self.plot_real.linewidth,
}
new_data = type(self)(str(self.id), self._data.copy(), manager=self._manager)
new_data = type(self)(str(self.id), self._data.copy(), manager=self._manager, **pen_dict)
new_data.mode = self.mode
# if self.plot_imag is not None:
# new_data.plot_imag.set_symbol(symbol=self.plot_imag.symbol, size=self.plot_imag.symbolsize,
# color=self.plot_imag.symbolcolor)
# new_data.plot_imag.set_line(style=self.plot_imag.linestyle, width=self.plot_imag.linewidth,
# color=self.plot_imag.linecolor)
if keep_color and self.plot_imag is not None:
new_data.plot_imag.set_symbol(symbol=self.plot_imag.symbol, size=self.plot_imag.symbolsize,
color=self.plot_imag.symbolcolor)
new_data.plot_imag.set_line(style=self.plot_imag.linestyle, width=self.plot_imag.linewidth,
color=self.plot_imag.linecolor)
return new_data
@ -548,7 +550,7 @@ class FitContainer(ExperimentContainer):
def _init_plot(self, **kwargs):
color = kwargs.get('color', (0, 0, 0))
if isinstance(color, Colors):
if isinstance(color, BaseColor):
color = color.rgb()
self.plot_real = PlotItem(x=self._data.x, y=self._data.y.real, name=self.name,

View File

@ -23,6 +23,7 @@ class DataTree(QtWidgets.QTreeWidget):
self.invisibleRootItem().setFlags(self.invisibleRootItem().flags() ^ QtCore.Qt.ItemIsDropEnabled)
self.itemChanged.connect(self.data_change)
self.itemClicked.connect(self.new_selection)
self.setColumnCount(2)
@ -76,7 +77,7 @@ class DataTree(QtWidgets.QTreeWidget):
break
@QtCore.pyqtSlot(QtWidgets.QTreeWidgetItem)
def data_change(self, item: QtWidgets.QTreeWidgetItem) -> (list, list):
def data_change(self, item: QtWidgets.QTreeWidgetItem) -> tuple[set, set]:
idd = item.data(0, QtCore.Qt.UserRole)
is_selected = item.checkState(0) == QtCore.Qt.Checked
to_be_hidden = set()
@ -140,6 +141,11 @@ class DataTree(QtWidgets.QTreeWidget):
return to_be_shown, to_be_hidden
@QtCore.pyqtSlot(QtWidgets.QTreeWidgetItem)
def new_selection(self, item: QtWidgets.QTreeWidgetItem):
if item.parent() is None:
self.management.select_window(item.data(0, QtCore.Qt.UserRole))
def dropEvent(self, evt: QtGui.QDropEvent):
dropped_index = self.indexAt(evt.pos())
if not dropped_index.isValid():

View File

@ -1,4 +1,6 @@
from typing import Tuple, Union
from __future__ import annotations
from typing import List, Tuple, Union
from ...utils.text import convert
from ..Qt import QtCore, QtWidgets, QtGui
@ -51,8 +53,8 @@ class FitModelWidget(QtWidgets.QWidget, Ui_FitParameter):
return convert(self.parametername.text().strip(), old='html', new='str')
def set_parameter_string(self, p: str):
self.parameter_line.setText(str(p))
self.parameter_line.setToolTip(str(p))
self.parameter_line.setText(p)
self.parameter_line.setToolTip(p)
def set_bounds(self, lb: float, ub: float, cbox: bool = True):
self.checkBox.setCheckState(QtCore.Qt.Checked if cbox else QtCore.Qt.Unchecked)
@ -66,21 +68,25 @@ class FitModelWidget(QtWidgets.QWidget, Ui_FitParameter):
self.lineEdit.setEnabled(value == 2)
self.lineEdit_2.setEnabled(value == 2)
def set_parameter(self, p: list, bds: Tuple[float, float, bool] = (None, None, False),
fixed: bool = False, glob: bool = False):
def set_parameter(self, p: float | None, bds: Tuple[float, float, bool] = None,
fixed: bool = None, glob: bool = None):
if p is None:
# bad hack: linked parameter return (None, linked parameter)
# if p is None -> parameter is linked to argument given by bds
self.link_parameter(linkto=bds)
else:
ptext = ' '.join([f'{pp:.4g}' for pp in p])
ptext = f'{p:.4g}'
self.set_parameter_string(ptext)
self.set_bounds(*bds)
if bds is not None:
self.set_bounds(*bds)
self.fixed_check.setCheckState(QtCore.Qt.Unchecked if fixed else QtCore.Qt.Checked)
self.global_checkbox.setCheckState(QtCore.Qt.Checked if glob else QtCore.Qt.Unchecked)
if fixed is not None:
self.fixed_check.setCheckState(QtCore.Qt.Unchecked if fixed else QtCore.Qt.Checked)
if glob is not None:
self.global_checkbox.setCheckState(QtCore.Qt.Checked if glob else QtCore.Qt.Unchecked)
def get_parameter(self):
if self.is_linked:
@ -323,7 +329,7 @@ class FitModelTree(QtWidgets.QTreeWidget):
return function_nr, idx
def get_functions(self, full=True, parent=None, pos=-1, return_pos=False):
def get_functions(self, full: bool = True, pos: int = -1, return_pos: bool = False, parent=None):
"""
Create nested list of functions in tree. Parameters saved are idx (Index of function in list of all functions),
cnt (counter of number to associate with functione values), ops (+, -, *, /), and maybe children.
@ -397,7 +403,7 @@ class FitTableWidget(QtWidgets.QTableWidget):
self.hideColumn(1)
self.resizeColumnToContents(0)
def load(self, set_ids: list):
def load(self, set_ids: List[str]):
self.blockSignals(True)
while self.rowCount():
@ -419,8 +425,7 @@ class FitTableWidget(QtWidgets.QTableWidget):
self.blockSignals(False)
def collect_data(self, default=None, include_name=False):
def collect_data(self, default: str = None, include_name: bool = False) -> dict:
data = {}
for i in range(self.rowCount()):

View File

@ -1,3 +1,7 @@
from __future__ import annotations
from typing import List
from ...utils.text import convert
from ..Qt import QtWidgets, QtCore, QtGui
from .._py.fitfuncwidget import Ui_FormFit
@ -50,6 +54,7 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit):
self.comboBox.addItem(name, userData=sid)
self._make_parameter(sid)
self.comboBox.blockSignals(False)
self.change_data(0)
def set_function(self, func, idx):
self.func = func
@ -71,7 +76,7 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit):
if self.max_width.width() < size.width():
self.max_width = size
widgt.state_changed.connect(self.set_global)
widgt.state_changed.connect(self.make_global)
widgt.value_requested.connect(self.look_for_value)
widgt.value_changed.connect(self.change_global_parameter)
@ -115,12 +120,14 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit):
w.add_links(parameter)
@QtCore.pyqtSlot(str)
def change_global_parameter(self, value: str):
idx = self.global_parameter.index(self.sender())
def change_global_parameter(self, value: str, idx: int = None):
if idx is None:
idx = self.global_parameter.index(self.sender())
self.glob_values[idx] = float(value)
if self.data_values[self.comboBox.currentData()][idx] is None:
self.data_parameter[idx].blockSignals(True)
self.data_parameter[idx].value = value
self.data_parameter[idx].value = float(value)
self.data_parameter[idx].blockSignals(False)
@QtCore.pyqtSlot(str, object)
@ -138,7 +145,7 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit):
idx = self.data_parameter.index(sender)
self.data_values[self.comboBox.currentData()][idx] = value
def change_single_choice(self, argname, value, sender=None):
def change_single_choice(self, _, value, sender=None):
if sender is None:
sender = self.sender()
idx = self.data_parameter.index(sender)
@ -149,7 +156,7 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit):
self.value_requested.emit(self.global_parameter.index(sender))
@QtCore.pyqtSlot()
def set_global(self):
def make_global(self):
# disable single parameter if it is set global, enable if global is unset
widget = self.sender()
idx = self.global_parameter.index(widget)
@ -233,6 +240,7 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit):
raise ValueError(f'Parameter {g.name} is outside bounds ({lb[i]}, {ub[i]})')
except TypeError:
pass
try:
if p[i] < lb[i]:
raise ValueError(f'Parameter {g.name} is outside bounds ({lb[i]}, {ub[i]})')
@ -250,3 +258,19 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit):
data_parameter[sid] = (p, kw_p)
return data_parameter, lb, ub, is_fixed, global_p, is_linked
def set_parameter(self, set_id: str | None, parameter: List[float]) -> int:
if set_id is None:
for val, g in zip(parameter, self.global_parameter):
if isinstance(g, SelectionWidget):
continue
g.set_parameter(val)
else:
new_param = self.data_values[set_id]
for i in range(len(new_param)):
new_param[i] = parameter[i]
self.change_data(self.comboBox.currentIndex())
return len(self.global_parameter)

View File

@ -1,5 +1,10 @@
from __future__ import annotations
from functools import reduce
from itertools import count, cycle
from operator import add
from string import ascii_letters
from typing import Dict, List, Tuple
from pyqtgraph import mkPen
@ -9,6 +14,7 @@ from ..lib.pg_objects import PlotItem
from ..Qt import QtGui, QtCore, QtWidgets
from .._py.fitdialog import Ui_FitDialog
from ...fit._meta import MultiModel, ModelFactory
from ...fit.result import FitResult
class QFitDialog(QtWidgets.QWidget, Ui_FitDialog):
@ -27,7 +33,7 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog):
self.parameters = {}
self.preview_lines = []
self._current_function = None
self.function_widgets = {}
self.param_widgets = {}
self._management = mgmt
self._current_model = next(QFitDialog.model_cnt)
@ -63,10 +69,10 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog):
"""
Remove function and children from tree and dictionary
"""
w = self.function_widgets[idx]
w = self.param_widgets[idx]
self.stackedWidget.removeWidget(w)
w.deleteLater()
del self.function_widgets[idx]
del self.param_widgets[idx]
if len(self.functionwidget) == 0:
# empty model
@ -82,8 +88,8 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog):
"""
Display parameter associated with selected function.
"""
if function_id in self.function_widgets:
dialog = self.function_widgets[function_id]
if function_id in self.param_widgets:
dialog = self.param_widgets[function_id]
else:
# create new widget for function
@ -103,7 +109,7 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog):
dialog.value_requested.connect(self.look_value)
self.stackedWidget.addWidget(dialog)
self.function_widgets[function_id] = dialog
self.param_widgets[function_id] = dialog
self.stackedWidget.setCurrentWidget(dialog)
@ -114,13 +120,13 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog):
# show same tab (general parameter/Data parameter)
tab_idx = 0
if self._current_function is not None:
tab_idx = self.function_widgets[self._current_function].tabWidget.currentIndex()
tab_idx = self.param_widgets[self._current_function].tabWidget.currentIndex()
dialog.tabWidget.setCurrentIndex(tab_idx)
self._current_function = function_id
def look_value(self, idx):
func_widget = self.function_widgets[self._current_function]
def look_value(self, idx: int):
func_widget = self.param_widgets[self._current_function]
set_ids = [func_widget.comboBox.itemData(i) for i in range(func_widget.comboBox.count())]
for s in set_ids:
func_widget.data_values[s][idx] = self._management[s].value
@ -132,7 +138,7 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog):
self._complex[self._current_model] = self.functionwidget.get_complex_state()
self._func_list[self._current_model] = self.functionwidget.get_parameter_list()
def load(self, ids: list):
def load(self, ids: List[str]):
"""
Add name and id of dataset to list.
"""
@ -143,7 +149,7 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog):
else:
self.data_table.add_model(self._current_model)
for dialog in self.function_widgets.values():
for dialog in self.param_widgets.values():
dialog.load(ids)
@QtCore.pyqtSlot(name='on_newmodel_button_clicked')
@ -190,9 +196,9 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog):
for m in self.models[model_id]:
func_id = m['cnt']
self.stackedWidget.removeWidget(self.function_widgets[func_id])
self.stackedWidget.removeWidget(self.param_widgets[func_id])
self.function_widgets.pop(func_id)
self.param_widgets.pop(func_id)
self._complex.pop(model_id)
self._func_list.pop(model_id)
@ -203,7 +209,8 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog):
if len(self.models) == 1:
self.model_frame.hide()
def _prepare(self, model: list, function_use=None, parameter=None, add_idx=False, cnt=0):
def _prepare(self, model: list, function_use: list = None,
parameter: dict = None, add_idx: bool = False, cnt: int = 0) -> Tuple[dict, int]:
if parameter is None:
parameter = {'parameter': {}, 'lb': (), 'ub': (), 'var': [],
'glob': {'idx': [], 'p': [], 'var': [], 'lb': [], 'ub': []},
@ -212,12 +219,13 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog):
for i, f in enumerate(model):
if not f['active']:
continue
try:
p, lb, ub, var, glob, links = self.function_widgets[f['cnt']].get_parameter(function_use)
p, lb, ub, var, glob, links = self.param_widgets[f['cnt']].get_parameter(function_use)
except ValueError as e:
_ = QtWidgets.QMessageBox().warning(self, 'Invalid value', str(e),
QtWidgets.QMessageBox.Ok)
return None, -1
return {}, -1
p_len = len(parameter['lb'])
@ -337,7 +345,6 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog):
@QtCore.pyqtSlot(int, name='on_preview_checkbox_stateChanged')
def show_preview(self, state: int):
print('state', state)
if state:
self.preview_button.show()
self.preview_checkbox.setText('')
@ -405,13 +412,9 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog):
y = f.func(x, *p, **kwargs)
if is_complex is None:
self.preview_lines.append(PlotItem(x=x, y=y, pen=mkPen(width=3)))
elif is_complex == 0:
if is_complex in [0, 1]:
self.preview_lines.append(PlotItem(x=x, y=y.real, pen=mkPen(width=3)))
self.preview_lines.append(PlotItem(x=x, y=y.imag, pen=mkPen(width=3)))
elif is_complex == 1:
self.preview_lines.append(PlotItem(x=x, y=y.real, pen=mkPen(width=3)))
else:
if is_complex in [0, 2]:
self.preview_lines.append(PlotItem(x=x, y=y.imag, pen=mkPen(width=3)))
if isinstance(f, MultiModel):
@ -419,16 +422,39 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog):
pen_i = mkPen(QtGui.QColor.fromRgbF(*color[i]))
if is_complex is None:
self.preview_lines.append(PlotItem(x=x, y=s, pen=pen_i))
elif is_complex == 0:
if is_complex in [0, 1]:
self.preview_lines.append(PlotItem(x=x, y=s.real, pen=pen_i))
self.preview_lines.append(PlotItem(x=x, y=s.imag, pen=pen_i))
elif is_complex == 1:
self.preview_lines.append(PlotItem(x=x, y=s.real, pen=pen_i))
else:
if is_complex in [0, 2]:
self.preview_lines.append(PlotItem(x=x, y=s.imag, pen=pen_i))
return self.preview_lines
def set_parameter(self, parameter: Dict[str, FitResult]):
# which data uses which model
data = self.data_table.collect_data(default=self.default_combobox.currentData())
glob_fit_parameter = []
for fitted_model, fitted_data in data.items():
for fit_id, fit_curve in parameter.items():
if fit_id in fitted_data:
fit_parameter = list(fit_curve.parameter.values())
glob_fit_parameter.append(fit_parameter)
self.set_parameter_iter(fit_id, [p.value for p in fit_parameter], self.models[fitted_model])
mean_parameter = [reduce(add, p)/len(p) for p in zip(*glob_fit_parameter)]
self.set_parameter_iter(None, mean_parameter, self.models[fitted_model])
def set_parameter_iter(self, fit_id: str | None, param: List[float], functions: List, cnt: int = 0):
for model_p in functions:
cnt += self.param_widgets[model_p['cnt']].set_parameter(fit_id, param[cnt:])
if model_p['children']:
cnt += self.set_parameter_iter(fit_id, param, model_p['children'], cnt=cnt)
return cnt
def closeEvent(self, evt: QtGui.QCloseEvent):
self.preview_emit.emit({}, -1, False)
self.preview_lines = []

View File

@ -11,7 +11,7 @@ from ..lib.pg_objects import PlotItem
class QFitResult(QtWidgets.QDialog, Ui_Dialog):
closed = QtCore.pyqtSignal(dict, list)
closed = QtCore.pyqtSignal(dict, list, str, bool, dict)
redoFit = QtCore.pyqtSignal(dict)
def __init__(self, results: list, management, parent=None):
@ -25,7 +25,6 @@ class QFitResult(QtWidgets.QDialog, Ui_Dialog):
for (res, parts) in results:
idx = res.idx
print(parts)
data_k = management.data[idx]
if res.name not in self._models:
@ -64,7 +63,11 @@ class QFitResult(QtWidgets.QDialog, Ui_Dialog):
self.set_parameter(0)
self.buttonBox.accepted.connect(self.accept)
self.param_tableWidget.horizontalHeader().sectionClicked.connect(self.show_results)
self.param_tableWidget.itemClicked.connect(self.show_results)
self.param_tableWidget.horizontalHeader().sectionClicked.connect(lambda i: self.show_results(None, idx=i))
self.graph_checkBox.stateChanged.connect(lambda x: self.graph_comboBox.setEnabled(x == QtCore.Qt.Unchecked))
self.logy_box.stateChanged.connect(lambda x: self.fitplot.setLogMode(y=bool(x)))
def add_graphs(self, graphs: list):
@ -72,10 +75,6 @@ class QFitResult(QtWidgets.QDialog, Ui_Dialog):
for (graph_id, graph_name) in graphs:
self.graph_comboBox.addItem(graph_name, userData=graph_id)
@QtCore.pyqtSlot(int, name='on_graph_checkBox_stateChanged')
def change_graph(self, state: int):
self.graph_comboBox.setEnabled(state == QtCore.Qt.Unchecked)
@QtCore.pyqtSlot(int, name='on_sets_comboBox_currentIndexChanged')
def set_parameter(self, idx: int):
model_name = self.sets_comboBox.itemText(idx)
@ -109,22 +108,32 @@ class QFitResult(QtWidgets.QDialog, Ui_Dialog):
self.param_tableWidget.resizeColumnsToContents()
self.param_tableWidget.selectColumn(0)
self.show_results(0)
self.show_results(None, idx=0)
@QtCore.pyqtSlot(int, name='on_reject_fit_checkBox_stateChanged')
@QtCore.pyqtSlot(int, name='on_del_prev_checkBox_stateChanged')
def change_opts(self, _):
idx = self.sets_comboBox.currentIndex()
idx = self.param_tableWidget.currentIndex().column()
self._opts[idx] = (self.reject_fit_checkBox.checkState() == QtCore.Qt.Checked,
self.del_prev_checkBox.checkState() == QtCore.Qt.Checked)
def show_results(self, idx: int):
def show_results(self, item, idx=None):
if item is not None:
idx = self.param_tableWidget.indexFromItem(item).column()
set_id = self.param_tableWidget.horizontalHeaderItem(idx).data(QtCore.Qt.UserRole)
self.set_plot(set_id)
self.set_correlation(set_id)
self.set_statistics(set_id)
self.reject_fit_checkBox.blockSignals(True)
self.reject_fit_checkBox.setChecked(self._opts[idx][0])
self.reject_fit_checkBox.blockSignals(False)
self.del_prev_checkBox.blockSignals(True)
self.del_prev_checkBox.setChecked(self._opts[idx][1])
self.del_prev_checkBox.blockSignals(False)
def set_plot(self, idx: str):
res = self._results[idx]
iscomplex = res.iscomplex
@ -234,10 +243,19 @@ class QFitResult(QtWidgets.QDialog, Ui_Dialog):
self.redoFit.emit(self._results)
elif button_type == self.buttonBox.Ok:
graph = '' if self.graph_checkBox.checkState() == QtCore.Qt.Checked else self.graph_comboBox.currentData()
subplots = self.partial_checkBox.checkState() == QtCore.Qt.Checked
self._opts.extend([graph, subplots])
self.closed.emit(self._results, self._opts)
graph = None
if self.parameter_checkbox.isChecked():
if self.graph_checkBox.checkState() == QtCore.Qt.Checked:
graph = ''
else:
graph = self.graph_comboBox.currentData()
plot_fits = self.curve_checkbox.isChecked()
if self.partial_checkBox.checkState() == QtCore.Qt.Checked:
self.closed.emit(self._results, self._opts, graph, plot_fits, self._parts)
else:
self.closed.emit(self._results, self._opts, graph, plot_fits, {})
self.accept()

View File

@ -15,6 +15,11 @@ class QAsciiReader(QtWidgets.QDialog, Ui_ascii_reader):
self.reader = AsciiReader(fname)
pal = QtWidgets.QApplication.instance().palette()
rgb = pal.color(pal.Base).getRgb()[:3]
rgb2 = pal.color(pal.Text).getRgb()[:3]
self.plainTextEdit_2.setStyleSheet(f'QPlainTextEdit {{ background-color: rgb{rgb} ; color: rgb{rgb2}; }}')
self.ascii_table.horizontalHeader().setStretchLastSection(True)
self.buttonbox.button(QtWidgets.QDialogButtonBox.Apply).clicked.connect(self.apply)
self.buttonbox.button(QtWidgets.QDialogButtonBox.Ok).clicked.connect(self.accept)

View File

@ -61,7 +61,11 @@ def get_icon(icon_name):
global HAS_IMPORTLIB_RESOURCE
dirname = 'resources.icons.%s_light' % icon_type
if icon_name != 'logo':
dirname = f'resources.icons.{icon_type}_light'
else:
dirname = 'resources.icons'
if HAS_IMPORTLIB_RESOURCE:
with path(dirname, icon_name+'.png') as imgpath:
icon = QtGui.QIcon()

View File

@ -2,7 +2,7 @@ import re
from ..Qt import QtWidgets, QtGui, QtCore
from ...lib.colors import BaseColor, Colors
from ...lib.colors import BaseColor, TUColors
from ...lib.lines import LineStyle
from ...lib.symbols import SymbolStyle, make_symbol_pixmap
@ -101,12 +101,12 @@ class ColorListEditor(QtWidgets.QComboBox):
@value.setter
def value(self, val):
for i in range(self.count()):
if val == self.itemData(i):
if val.name == self.itemData(i).name:
self.setCurrentIndex(i)
break
def populateList(self):
for i, colorName in enumerate(Colors):
for i, colorName in enumerate(TUColors):
color = QtGui.QColor(*colorName.value)
self.insertItem(i, colorName.name)
self.setItemData(i, colorName)

View File

@ -56,7 +56,7 @@ class LineEdit(QtWidgets.QLineEdit):
def contextMenuEvent(self, evt):
menu = self.createStandardContextMenu()
request_action = menu.addAction('Use value of set(s)')
request_action = menu.addAction('Use value of sets')
action = menu.exec(evt.globalPos())
@ -89,9 +89,11 @@ class LineEditPost(QtWidgets.QLineEdit):
class FormWidget(QtWidgets.QWidget):
types = {'float': (float, QtGui.QDoubleValidator),
'int': (int, QtGui.QIntValidator),
'str': (str, lambda: 0)}
types = {
'float': (float, QtGui.QDoubleValidator),
'int': (int, QtGui.QIntValidator),
'str': (str, lambda: 0),
}
valueChanged = QtCore.pyqtSignal(object)
stateChanged = QtCore.pyqtSignal(bool)
@ -140,7 +142,12 @@ class FormWidget(QtWidgets.QWidget):
@value.setter
def value(self, val):
self.vals.setText(str(val))
if self._type == 'str':
self.vals.setText(val)
elif self._type == 'int':
self.vals.setText(f'{val:.0f}')
else:
self.vals.setText(f'{val:.5g}')
def setChecked(self, enable):
if self._checkable:

View File

@ -4,10 +4,10 @@ from pyqtgraph import (
ErrorBarItem,
LinearRegionItem, mkBrush,
mkColor, mkPen,
PlotDataItem
PlotDataItem,
)
from ...lib.colors import BaseColor, Colors
from ...lib.colors import BaseColor, Colors, TUColors
from ...lib.lines import LineStyle
from ...lib.symbols import SymbolStyle

View File

@ -391,6 +391,8 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
self.management.current_graph = wd.widget().id
self.current_plotitem = self.current_graph_widget.graphic
self.change_mouse_mode(self.actionMouse_behaviour.isChecked())
pick = False
block = False
if self.ptsselectwidget.isVisible():
@ -720,6 +722,10 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
for s in sets:
self.datawidget.tree.move_sets(s, dest, src)
@QtCore.pyqtSlot(name='on_action_idx_cut_triggered')
def cut_with_idx(self):
print('schnippschnapp')
@QtCore.pyqtSlot(str)
def show_data_values(self, sid: str):
if sid == '':
@ -776,19 +782,18 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
pass
if onoff:
if self.management.active_sets:
self.fit_dialog.connected_figure = self.management.current_graph
self.fit_dialog.load(self.management.active_sets)
for item in self.fit_dialog.preview_lines:
self.current_graph_widget.add_external(item)
if self.action_custom_range.isChecked():
self.current_graph_widget.add_external(self.fitregion)
self.fit_dialog.connected_figure = self.management.current_graph
self.fit_dialog.load(self.management.active_sets)
for item in self.fit_dialog.preview_lines:
self.current_graph_widget.add_external(item)
if self.action_custom_range.isChecked():
self.current_graph_widget.add_external(self.fitregion)
block_window = True
else:
for item in self.fit_dialog.preview_lines:
self.current_graph_widget.remove_external(item)
self.current_graph_widget.remove_external(self.fitregion)
block_window = True
else:
for item in self.fit_dialog.preview_lines:
self.current_graph_widget.remove_external(item)
self.current_graph_widget.remove_external(self.fitregion)
return block_window
@ -834,18 +839,21 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
for item in self.fit_dialog.preview_lines:
g.add_external(item)
self.raise_()
@QtCore.pyqtSlot(list)
def show_fit_results(self, results: list):
self.fit_dialog.fit_button.setEnabled(True)
if results:
res_dialog = QFitResult(results, self.management, parent=self)
res_dialog.add_graphs(self.management.graphs.list())
res_dialog.closed.connect(self.management.make_fits)
res_dialog.closed.connect(self.accepts_fit)
res_dialog.redoFit.connect(self.management.redo_fits)
res_dialog.show()
@QtCore.pyqtSlot(dict, list, str, bool, dict)
def accepts_fit(self, res: dict, opts: list, param_graph: str, show_fit: bool, parts: dict) -> None:
self.fit_dialog.set_parameter(res)
self.management.make_fits(res, opts, param_graph, show_fit, parts)
@QtCore.pyqtSlot(name='on_actionFunction_editor_triggered')
def edit_models(self):
if self.editor is None:
@ -885,14 +893,14 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
evt.accept()
@QtCore.pyqtSlot(bool, name='on_actionMouse_behaviour_toggled')
def change_mouse_mode(self, is_checked):
def change_mouse_mode(self, is_checked: bool):
if is_checked:
self.current_plotitem.plotItem.vb.setMouseMode(ViewBox.RectMode)
else:
self.current_plotitem.plotItem.vb.setMouseMode(ViewBox.PanMode)
def mousemoved(self, xpos, ypos):
self.mousepos.setText('x={:.3g}; y={:.3g}'.format(xpos, ypos))
self.mousepos.setText(f'x={xpos:.3g}; y={ypos:.3g}')
@QtCore.pyqtSlot(name='on_actionSnake_triggered')
@QtCore.pyqtSlot(name='on_actionTetris_triggered')

View File

@ -9,6 +9,7 @@ from ...fit import data as fit_d
from ...fit.model import Model
from ...fit.result import FitResult
from ...fit.minimizer import FitRoutine
from ...lib.colors import TUColorsC
from ...math.interpol import interpolate
from ...math.logfourier import logft
from ...math.smooth import smooth
@ -78,8 +79,7 @@ class UpperManagement(QtCore.QObject):
properties_collected = QtCore.pyqtSignal(dict)
unset_state = QtCore.pyqtSignal(list)
_colors = cycle(Colors)
_colors = cycle(TUColors)
_actions = {
'ls': (ShiftCommand, 'Left shift'),
@ -238,6 +238,11 @@ class UpperManagement(QtCore.QObject):
# move to correct position
self.graphs[dest].move_sets(sets, pos)
def select_window(self, gid: str):
for key, plot in self.graphs.items():
if key == gid:
self.window.area.setActiveSubWindow(plot.parent())
@QtCore.pyqtSlot()
@QtCore.pyqtSlot(list, str)
def copy_sets(self, sets: list = None, src: str = None):
@ -466,14 +471,22 @@ class UpperManagement(QtCore.QObject):
parameter[set_id] = (new_values, set_parameter[1])
self.start_fit(*self.__fit_options)
@QtCore.pyqtSlot(dict, list)
def make_fits(self, res: dict, opts: list):
def make_fits(self, res: dict, opts: list, param_graph: str, show_fit: bool, parts: dict) -> None:
"""
Args:
res: key is that of original data, value is FitResult
opts: (ignore this fits, delete previous fits)
param_graph: None if no parameter to plot, '' for new graph, or id of existig graph
show_fit: plot fit curve?
parts: key is that of original data, value is list of subplots
"""
f_id_list = []
gid = ''
subplots = opts.pop(-1)
param_graph = opts.pop(-1)
tobedeleted = []
accepted = []
for i, (k, fit) in enumerate(res.items()):
reject, delete_prev = opts[i]
if reject:
@ -493,19 +506,31 @@ class UpperManagement(QtCore.QObject):
fit.value = data_k.value
fit.group = data_k.group
f_id = self.add(fit, color=color, src=k)
accepted.append(fit)
if show_fit:
f_id = self.add(fit, color=color, src=k)
f_id_list.append(f_id)
data_k.set_fits(f_id)
f_id_list.append(f_id)
data_k.set_fits(f_id)
gid = data_k.graph
if k in parts and show_fit:
for subfunc, col in zip(parts[k], TUColorsC):
sub_f_id = self.add(subfunc, color=col, linestyle=LineStyle.Dashed, symbol=SymbolStyle.No)
subfunc.value = data_k.value
subfunc.group = data_k.group
f_id_list.append(sub_f_id)
self.delete_sets(tobedeleted)
if f_id_list:
self.newData.emit(f_id_list, gid)
self.make_fit_parameter(f_id_list, graph_id=param_graph)
if accepted and param_graph is not None:
self.make_fit_parameter(accepted, graph_id=param_graph)
def make_fit_parameter(self, fit_sets: List[str], graph_id: str = None):
self.newData.emit(f_id_list, gid)
def make_fit_parameter(self, fit_sets: List[str | FitResult], graph_id: str = None):
fit_dict = self._collect_fit_parameter(fit_sets)
if fit_dict:
@ -530,12 +555,17 @@ class UpperManagement(QtCore.QObject):
data.data.save_parameter(fname)
def _collect_fit_parameter(self, fit_sets: List[str]) -> dict:
def _collect_fit_parameter(self, fit_sets: List[str | FitResult]) -> dict:
fit_dict = {}
for set_id in fit_sets:
data = self.data[set_id]
if data.mode != 'fit':
if isinstance(set_id, str):
data = self.data[set_id]
if data.mode != 'fit':
continue
elif isinstance(set_id, FitResult):
data = set_id
else:
continue
for key, pvalue in data.parameter.items():
@ -811,7 +841,6 @@ class UpperManagement(QtCore.QObject):
err_msg.exec()
self.sender().success = not failures
self.sender().add_data(self.active_sets)
@QtCore.pyqtSlot(list, dict)

View File

@ -147,7 +147,7 @@ class BaseColor(enum.Enum):
return cls((r, g, b))
class TuColorsA(BaseColor):
class TUColorsA(BaseColor):
TuDa1a = (93, 133, 195)
TuDa2a = (0, 156, 218)
TuDa3a = (80, 182, 149)
@ -161,7 +161,7 @@ class TuColorsA(BaseColor):
TuDa11a = (128, 69, 151)
class TuColorsB(BaseColor):
class TUColorsB(BaseColor):
TuDa1b = (0, 90, 169)
TuDa2b = (0, 131, 204)
TuDa3b = (0, 157, 129)
@ -175,7 +175,7 @@ class TuColorsB(BaseColor):
TuDa11b = (114, 16, 133)
class TuColorsC(BaseColor):
class TUColorsC(BaseColor):
TuDa1c = (0, 78, 138)
TuDa2c = (0, 104, 157)
TuDa3c = (0, 136, 119)
@ -243,28 +243,26 @@ class Tab20(BaseColor):
TabBlue = (31, 119, 180)
TabBlue2 = (174, 199, 232)
TabOrange = (255, 127, 14)
TabOrange2 = (255, 127, 14)
TabOrange2 = (255, 187, 120)
TabGreen = (44, 160, 44)
TabGreen2 = (44, 160, 44)
TabGreen2 = (152, 223, 138)
TabRed = (214, 39, 40)
TabRed2 = (214, 39, 40)
TabRed2 = (255, 152, 150)
TabPurple = (148, 103, 189)
TabPurple2 = (148, 103, 189)
TabPurple2 = (197, 176, 213)
TabBrown = (140, 86, 75)
TabBrown2 = (140, 86, 75)
TabBrown2 = (196, 156, 148)
TabRose = (227, 119, 194)
TabRose2 = (227, 119, 194)
TabRose2 = (247, 182, 210)
TabGrey = (220, 220, 220)
TabGrey2 = (220, 220, 220)
TabGrey2 = (199, 199, 199)
TabChartreuse = (188, 189, 34)
TabChartreuse2 = (188, 189, 34)
TabChartreuse2 = (219, 219, 141)
TabTurquoise = (23, 190, 207)
TabTurquoise2 = (23, 190, 207)
TabTurquoise2 = (158, 218, 229)
class GraceColors(BaseColor):
White = (255, 255, 255)
Black = (0, 0, 0)
Red = (255, 0, 0)
Green = (0, 255, 0)
Blue = (0, 0, 255)
@ -281,25 +279,30 @@ class GraceColors(BaseColor):
Green4 = (0, 139, 0)
class BlackWhite(BaseColor):
White = (255, 255, 255)
Black = (0, 0, 0)
TUColors = enum.Enum(
value='TUColors',
names={member.name: member.value for palette in [TuColorsA, TuColorsB, TuColorsC, TUColorsD, TUGrays] for member in palette},
type=BaseColor
names={member.name: member.value for palette in [TUColorsA, TUColorsB, TUColorsC, TUColorsD] for member in palette},
type=BaseColor,
)
Colors = enum.Enum(
value='Colors',
names={member.name: member.value for palette in [TUColors, GraceColors, Tab10] for member in palette},
type=BaseColor
names={member.name: member.value for palette in [TUColors, TUGrays, GraceColors, Tab10, BlackWhite] for member in palette},
type=BaseColor,
)
def get_palettes():
palettes = {
'Full': Colors,
'TuDa:a': TuColorsA,
'TuDa:b': TuColorsB,
'TuDa:c': TuColorsC,
'TuDa:a': TUColorsA,
'TuDa:b': TUColorsB,
'TuDa:c': TUColorsC,
'TuDa:d': TUColorsD,
'Tab10': Tab10,
'Grace': GraceColors

View File

@ -31,12 +31,12 @@ big_greek = [
'Nu Xi Omicron Pi Rho Sigma Tau Ypsilon Phi Chi Psi Omega',
]
special_chars = [
r'\infty \int \sum \langle \rangle \pm \perp \para \leftarrow \rightarrow \leftrightarrow \cdot \hbar',
'\u221e \u222b \u2211 \u27e8 \u27e9 \u00b1 \u27c2 \u2225 \u21d0 \u21d2 \u21d4 \u00b7 \u0127',
r'\f{Symbol}¥\f{} \f{Symbol}ò\f{} \f{Symbol}å\f{} \f{Symbol}á\f{} \f{Symbol}ñ\f{} \f{Symbol}±\f{} '
r'\infty \int \sum \langle \rangle \pm \perp \para \leftarrow \rightarrow \leftrightarrow \cdot \hbar \n',
'\u221e \u222b \u2211 \u27e8 \u27e9 \u00b1 \u27c2 \u2225 \u21d0 \u21d2 \u21d4 \u00b7 \u0127 <br>',
r'\f{Symbol}¥\f{} \f{Symbol}ò\f{} \f{Symbol}å\f{} \f{Symbol}á\f{} \f{Symbol}ñ\f{} \f{Symbol}±\f{} \n'
r'\f{Symbol}^\f{} \f{Symbol}||\f{} \f{Symbol}¬\f{} \f{Symbol}®\f{} \f{Symbol}«\f{} \f{Symbol}×\f{Symbol} '
r'h\h{-0.6}\v{0.3}-\v{-0.3}\h{0.3}',
r'infty int sum < > \+- perp para <- -> <-> \* hbar',
r'infty int sum < > \+- perp para <- -> <-> \* hbar \s',
]
funcs = [
r'\exp \log \ln \sin \cos \tan',

View File

@ -39,7 +39,147 @@
</property>
</widget>
</item>
<item row="0" column="1" rowspan="4">
<item row="6" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Retry</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QTableWidget" name="param_tableWidget">
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustIgnored</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectColumns</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="columnCount">
<number>0</number>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Output</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="1" column="1">
<widget class="QCheckBox" name="graph_checkBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>New graph</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QComboBox" name="graph_comboBox">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="curve_checkbox">
<property name="text">
<string>Plot fit curve</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="partial_checkBox">
<property name="text">
<string>Plot partial functions</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="parameter_checkbox">
<property name="text">
<string>Plot parameter</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>3</number>
</property>
<item>
<widget class="QCheckBox" name="reject_fit_checkBox">
<property name="text">
<string>Reject this fit</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="del_prev_checkBox">
<property name="text">
<string>Delete previous fits</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0" colspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="3">
<widget class="QToolBox" name="stack">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
@ -59,7 +199,7 @@
<x>0</x>
<y>0</y>
<width>399</width>
<height>414</height>
<height>346</height>
</rect>
</property>
<attribute name="label">
@ -102,7 +242,7 @@
<x>0</x>
<y>0</y>
<width>399</width>
<height>414</height>
<height>346</height>
</rect>
</property>
<attribute name="label">
@ -152,7 +292,7 @@
<x>0</x>
<y>0</y>
<width>399</width>
<height>414</height>
<height>346</height>
</rect>
</property>
<attribute name="label">
@ -217,129 +357,6 @@
</widget>
</widget>
</item>
<item row="5" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>3</number>
</property>
<item>
<widget class="QCheckBox" name="partial_checkBox">
<property name="text">
<string>Plot partial functions</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Location of parameters:</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="graph_checkBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>New graph</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="graph_comboBox">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>3</number>
</property>
<item>
<widget class="QCheckBox" name="reject_fit_checkBox">
<property name="text">
<string>Reject this fit</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="del_prev_checkBox">
<property name="text">
<string>Delete previous fits</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Retry</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QTableWidget" name="param_tableWidget">
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustIgnored</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectColumns</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="columnCount">
<number>0</number>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
<customwidgets>

View File

@ -1 +0,0 @@
/autohome/dominik/nmreval/resources/icons/logo.png

View File

@ -1 +0,0 @@
/autohome/dominik/nmreval/resources/icons/logo.png