207-noncomplex-fits #244

Merged
dominik merged 4 commits from 207-noncomplex-fits into master 2024-02-11 17:40:51 +00:00
20 changed files with 410 additions and 230 deletions
Showing only changes of commit 9a583501bc - Show all commits

View File

@ -17,7 +17,7 @@ body:
description: For which version have you observed this behavior? description: For which version have you observed this behavior?
placeholder: You find the program version in "Help/About" placeholder: You find the program version in "Help/About"
validations: validations:
required: true required: false
- type: textarea - type: textarea
attributes: attributes:
label: Expected behavior label: Expected behavior

View File

@ -365,6 +365,9 @@ class Ui_BaseWindow(object):
self.actionBinning.setObjectName("actionBinning") self.actionBinning.setObjectName("actionBinning")
self.actionTNMH = QtWidgets.QAction(BaseWindow) self.actionTNMH = QtWidgets.QAction(BaseWindow)
self.actionTNMH.setObjectName("actionTNMH") self.actionTNMH.setObjectName("actionTNMH")
self.actionExclude_region = QtWidgets.QAction(BaseWindow)
self.actionExclude_region.setCheckable(True)
self.actionExclude_region.setObjectName("actionExclude_region")
self.menuSave.addAction(self.actionSave) self.menuSave.addAction(self.actionSave)
self.menuSave.addAction(self.actionExportGraphic) self.menuSave.addAction(self.actionExportGraphic)
self.menuSave.addAction(self.action_save_fit_parameter) self.menuSave.addAction(self.action_save_fit_parameter)
@ -419,6 +422,7 @@ class Ui_BaseWindow(object):
self.menuLimits.addAction(self.action_no_range) self.menuLimits.addAction(self.action_no_range)
self.menuLimits.addAction(self.action_x_range) self.menuLimits.addAction(self.action_x_range)
self.menuLimits.addAction(self.action_custom_range) self.menuLimits.addAction(self.action_custom_range)
self.menuLimits.addAction(self.actionExclude_region)
self.menuFit.addAction(self.action_FitWidget) self.menuFit.addAction(self.action_FitWidget)
self.menuFit.addSeparator() self.menuFit.addSeparator()
self.menuFit.addAction(self.action_create_fit_function) self.menuFit.addAction(self.action_create_fit_function)
@ -631,6 +635,7 @@ class Ui_BaseWindow(object):
self.actionTNMH_model.setText(_translate("BaseWindow", "Tg , Hodge, TNMH,,,")) self.actionTNMH_model.setText(_translate("BaseWindow", "Tg , Hodge, TNMH,,,"))
self.actionBinning.setText(_translate("BaseWindow", "Binning...")) self.actionBinning.setText(_translate("BaseWindow", "Binning..."))
self.actionTNMH.setText(_translate("BaseWindow", "TNMH...")) self.actionTNMH.setText(_translate("BaseWindow", "TNMH..."))
self.actionExclude_region.setText(_translate("BaseWindow", "Exclude region"))
from ..data.datawidget.datawidget import DataWidget from ..data.datawidget.datawidget import DataWidget
from ..data.integral_widget import IntegralWidget from ..data.integral_widget import IntegralWidget
from ..data.point_select import PointSelectWidget from ..data.point_select import PointSelectWidget

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'resources/_ui/fitresult.ui' # Form implementation generated from reading ui file 'src/resources/_ui/fitresult.ui'
# #
# Created by: PyQt5 UI code generator 5.15.10 # Created by: PyQt5 UI code generator 5.15.10
# #
@ -157,67 +157,91 @@ class Ui_Dialog(object):
self.gridLayout_2.setContentsMargins(3, 3, 3, 3) self.gridLayout_2.setContentsMargins(3, 3, 3, 3)
self.gridLayout_2.setSpacing(3) self.gridLayout_2.setSpacing(3)
self.gridLayout_2.setObjectName("gridLayout_2") self.gridLayout_2.setObjectName("gridLayout_2")
self.extrapolate_box = QtWidgets.QCheckBox(self.groupBox)
self.extrapolate_box.setObjectName("extrapolate_box")
self.gridLayout_2.addWidget(self.extrapolate_box, 1, 0, 1, 1)
self.parameter_checkbox = QtWidgets.QCheckBox(self.groupBox)
self.parameter_checkbox.setObjectName("parameter_checkbox")
self.gridLayout_2.addWidget(self.parameter_checkbox, 0, 5, 1, 1)
self.graph_comboBox = QtWidgets.QComboBox(self.groupBox) self.graph_comboBox = QtWidgets.QComboBox(self.groupBox)
self.graph_comboBox.setEnabled(False) self.graph_comboBox.setEnabled(False)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.graph_comboBox.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.graph_comboBox.sizePolicy().hasHeightForWidth())
self.graph_comboBox.setSizePolicy(sizePolicy) self.graph_comboBox.setSizePolicy(sizePolicy)
self.graph_comboBox.setObjectName("graph_comboBox") self.graph_comboBox.setObjectName("graph_comboBox")
self.gridLayout_2.addWidget(self.graph_comboBox, 1, 6, 1, 1) self.gridLayout_2.addWidget(self.graph_comboBox, 1, 7, 1, 1)
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, 5, 1, 1)
self.minx_line = QtWidgets.QLineEdit(self.groupBox) self.minx_line = QtWidgets.QLineEdit(self.groupBox)
self.minx_line.setEnabled(False) self.minx_line.setEnabled(False)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.minx_line.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.minx_line.sizePolicy().hasHeightForWidth())
self.minx_line.setSizePolicy(sizePolicy) self.minx_line.setSizePolicy(sizePolicy)
self.minx_line.setObjectName("minx_line") self.minx_line.setObjectName("minx_line")
self.gridLayout_2.addWidget(self.minx_line, 1, 1, 1, 1) self.gridLayout_2.addWidget(self.minx_line, 1, 1, 1, 1)
self.line_2 = QtWidgets.QFrame(self.groupBox) self.extrapolate_box = QtWidgets.QCheckBox(self.groupBox)
self.line_2.setFrameShape(QtWidgets.QFrame.VLine) self.extrapolate_box.setObjectName("extrapolate_box")
self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken) self.gridLayout_2.addWidget(self.extrapolate_box, 1, 0, 1, 1)
self.line_2.setObjectName("line_2") self.numx_line = QtWidgets.QLineEdit(self.groupBox)
self.gridLayout_2.addWidget(self.line_2, 0, 4, 2, 1) self.numx_line.setEnabled(False)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.numx_line.sizePolicy().hasHeightForWidth())
self.numx_line.setSizePolicy(sizePolicy)
self.numx_line.setObjectName("numx_line")
self.gridLayout_2.addWidget(self.numx_line, 1, 3, 1, 1)
self.graph_checkBox = QtWidgets.QCheckBox(self.groupBox)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, 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, 6, 1, 1)
self.maxx_line = QtWidgets.QLineEdit(self.groupBox) self.maxx_line = QtWidgets.QLineEdit(self.groupBox)
self.maxx_line.setEnabled(False) self.maxx_line.setEnabled(False)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.maxx_line.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.maxx_line.sizePolicy().hasHeightForWidth())
self.maxx_line.setSizePolicy(sizePolicy) self.maxx_line.setSizePolicy(sizePolicy)
self.maxx_line.setObjectName("maxx_line") self.maxx_line.setObjectName("maxx_line")
self.gridLayout_2.addWidget(self.maxx_line, 1, 2, 1, 1) self.gridLayout_2.addWidget(self.maxx_line, 1, 2, 1, 1)
self.numx_line = QtWidgets.QLineEdit(self.groupBox) self.line_2 = QtWidgets.QFrame(self.groupBox)
self.numx_line.setEnabled(False) self.line_2.setFrameShape(QtWidgets.QFrame.VLine)
self.numx_line.setObjectName("numx_line") self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
self.gridLayout_2.addWidget(self.numx_line, 1, 3, 1, 1) self.line_2.setObjectName("line_2")
self.gridLayout_2.addWidget(self.line_2, 0, 5, 2, 1)
self.newx_log_checkbox = QtWidgets.QCheckBox(self.groupBox)
self.newx_log_checkbox.setEnabled(False)
self.newx_log_checkbox.setObjectName("newx_log_checkbox")
self.gridLayout_2.addWidget(self.newx_log_checkbox, 1, 4, 1, 1)
self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout") self.horizontalLayout.setObjectName("horizontalLayout")
self.curve_checkbox = QtWidgets.QCheckBox(self.groupBox) self.curve_checkbox = QtWidgets.QCheckBox(self.groupBox)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.curve_checkbox.sizePolicy().hasHeightForWidth())
self.curve_checkbox.setSizePolicy(sizePolicy)
self.curve_checkbox.setChecked(True) self.curve_checkbox.setChecked(True)
self.curve_checkbox.setObjectName("curve_checkbox") self.curve_checkbox.setObjectName("curve_checkbox")
self.horizontalLayout.addWidget(self.curve_checkbox) self.horizontalLayout.addWidget(self.curve_checkbox)
self.partial_checkBox = QtWidgets.QCheckBox(self.groupBox) self.partial_checkBox = QtWidgets.QCheckBox(self.groupBox)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.partial_checkBox.sizePolicy().hasHeightForWidth())
self.partial_checkBox.setSizePolicy(sizePolicy)
self.partial_checkBox.setObjectName("partial_checkBox") self.partial_checkBox.setObjectName("partial_checkBox")
self.horizontalLayout.addWidget(self.partial_checkBox) self.horizontalLayout.addWidget(self.partial_checkBox)
self.gridLayout_2.addLayout(self.horizontalLayout, 0, 0, 1, 4) self.gridLayout_2.addLayout(self.horizontalLayout, 0, 0, 1, 5)
self.parameter_checkbox = QtWidgets.QCheckBox(self.groupBox)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.parameter_checkbox.sizePolicy().hasHeightForWidth())
self.parameter_checkbox.setSizePolicy(sizePolicy)
self.parameter_checkbox.setObjectName("parameter_checkbox")
self.gridLayout_2.addWidget(self.parameter_checkbox, 0, 6, 1, 2)
self.gridLayout.addWidget(self.groupBox, 7, 0, 1, 2) self.gridLayout.addWidget(self.groupBox, 7, 0, 1, 2)
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog) self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok|QtWidgets.QDialogButtonBox.Retry) self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok|QtWidgets.QDialogButtonBox.Retry)
@ -253,16 +277,17 @@ class Ui_Dialog(object):
self.del_prev_checkBox.setText(_translate("Dialog", "Delete previous fits of this set")) self.del_prev_checkBox.setText(_translate("Dialog", "Delete previous fits of this set"))
self.reject_fit_checkBox.setText(_translate("Dialog", "Reject this fit")) self.reject_fit_checkBox.setText(_translate("Dialog", "Reject this fit"))
self.groupBox.setTitle(_translate("Dialog", "Output")) self.groupBox.setTitle(_translate("Dialog", "Output"))
self.extrapolate_box.setToolTip(_translate("Dialog", "Extrapolates only main function"))
self.extrapolate_box.setText(_translate("Dialog", "Extrapolate curves"))
self.parameter_checkbox.setText(_translate("Dialog", "Plot parameter"))
self.graph_checkBox.setText(_translate("Dialog", "New graph for parameter"))
self.minx_line.setToolTip(_translate("Dialog", "Leave empty to start at lowest point")) self.minx_line.setToolTip(_translate("Dialog", "Leave empty to start at lowest point"))
self.minx_line.setPlaceholderText(_translate("Dialog", "min x")) self.minx_line.setPlaceholderText(_translate("Dialog", "min x"))
self.extrapolate_box.setToolTip(_translate("Dialog", "Extrapolates only main function"))
self.extrapolate_box.setText(_translate("Dialog", "Extrapolate curves"))
self.numx_line.setPlaceholderText(_translate("Dialog", "# pts"))
self.graph_checkBox.setText(_translate("Dialog", "New graph for parameter"))
self.maxx_line.setToolTip(_translate("Dialog", "Leave empty to start at highest point")) self.maxx_line.setToolTip(_translate("Dialog", "Leave empty to start at highest point"))
self.maxx_line.setPlaceholderText(_translate("Dialog", "max x")) self.maxx_line.setPlaceholderText(_translate("Dialog", "max x"))
self.numx_line.setPlaceholderText(_translate("Dialog", "# pts")) self.newx_log_checkbox.setText(_translate("Dialog", "log-spaced?"))
self.curve_checkbox.setText(_translate("Dialog", "Plot fit curve")) self.curve_checkbox.setText(_translate("Dialog", "Plot fit curve"))
self.partial_checkBox.setText(_translate("Dialog", "Plot partial functions")) self.partial_checkBox.setText(_translate("Dialog", "Plot partial functions"))
self.parameter_checkbox.setText(_translate("Dialog", "Plot parameter"))
from ..lib.forms import ElideComboBox from ..lib.forms import ElideComboBox
from pyqtgraph import GraphicsLayoutWidget from pyqtgraph import GraphicsLayoutWidget

View File

@ -49,11 +49,16 @@ class DataTree(QtWidgets.QTreeWidget):
def add_graph(self, idd: str, name: str): def add_graph(self, idd: str, name: str):
item = QtWidgets.QTreeWidgetItem() item = QtWidgets.QTreeWidgetItem()
item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsDropEnabled | QtCore.Qt.ItemIsEditable | item.setFlags(
QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable) QtCore.Qt.ItemFlag.ItemIsSelectable |
QtCore.Qt.ItemFlag.ItemIsDropEnabled |
QtCore.Qt.ItemFlag.ItemIsEditable |
QtCore.Qt.ItemFlag.ItemIsEnabled |
QtCore.Qt.ItemFlag.ItemIsUserCheckable
)
item.setText(0, name) item.setText(0, name)
item.setData(0, QtCore.Qt.UserRole, idd) item.setData(0, QtCore.Qt.ItemDataRole.UserRole, idd)
item.setCheckState(0, QtCore.Qt.Checked) item.setCheckState(0, QtCore.Qt.CheckState.Checked)
self.addTopLevelItem(item) self.addTopLevelItem(item)
self._checked_graphs.add(idd) self._checked_graphs.add(idd)
@ -67,14 +72,19 @@ class DataTree(QtWidgets.QTreeWidget):
for row in range(self.invisibleRootItem().childCount()): for row in range(self.invisibleRootItem().childCount()):
graph = self.invisibleRootItem().child(row) graph = self.invisibleRootItem().child(row)
if graph.data(0, QtCore.Qt.UserRole) == gid: if graph.data(0, QtCore.Qt.ItemDataRole.UserRole) == gid:
for (idd, name, value) in items: for (idd, name, value) in items:
item = QtWidgets.QTreeWidgetItem([name]) item = QtWidgets.QTreeWidgetItem([name])
item.setToolTip(0, f'Value: {value}') item.setToolTip(0, f'Value: {value}')
item.setData(0, QtCore.Qt.UserRole, idd) item.setData(0, QtCore.Qt.ItemDataRole.UserRole, idd)
item.setCheckState(0, QtCore.Qt.Checked) item.setCheckState(0, QtCore.Qt.CheckState.Checked)
item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsEditable | item.setFlags(
QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable) QtCore.Qt.ItemFlag.ItemIsSelectable |
QtCore.Qt.ItemFlag.ItemIsDragEnabled |
QtCore.Qt.ItemFlag.ItemIsEditable |
QtCore.Qt.ItemFlag.ItemIsEnabled |
QtCore.Qt.ItemFlag.ItemIsUserCheckable
)
graph.addChild(item) graph.addChild(item)
self._checked_sets.add(idd) self._checked_sets.add(idd)
@ -85,8 +95,8 @@ class DataTree(QtWidgets.QTreeWidget):
@QtCore.pyqtSlot(QtWidgets.QTreeWidgetItem) @QtCore.pyqtSlot(QtWidgets.QTreeWidgetItem)
def data_change(self, item: QtWidgets.QTreeWidgetItem, emit: bool = True) -> tuple[set, set]: def data_change(self, item: QtWidgets.QTreeWidgetItem, emit: bool = True) -> tuple[set, set]:
idd = item.data(0, QtCore.Qt.UserRole) idd = item.data(0, QtCore.Qt.ItemDataRole.UserRole)
is_selected = item.checkState(0) == QtCore.Qt.Checked is_selected = item.checkState(0) == QtCore.Qt.CheckState.Checked
to_be_hidden = set() to_be_hidden = set()
to_be_shown = set() to_be_shown = set()
@ -104,9 +114,9 @@ class DataTree(QtWidgets.QTreeWidget):
self.blockSignals(True) self.blockSignals(True)
for i in range(item.childCount()): for i in range(item.childCount()):
child = item.child(i) child = item.child(i)
child.setCheckState(0, QtCore.Qt.Checked) child.setCheckState(0, QtCore.Qt.CheckState.Checked)
to_be_shown.add(child.data(0, QtCore.Qt.UserRole)) to_be_shown.add(child.data(0, QtCore.Qt.ItemDataRole.UserRole))
self._checked_sets.add(child.data(0, QtCore.Qt.UserRole)) self._checked_sets.add(child.data(0, QtCore.Qt.ItemDataRole.UserRole))
self.blockSignals(False) self.blockSignals(False)
# check state change to unchecked # check state change to unchecked
@ -115,10 +125,10 @@ class DataTree(QtWidgets.QTreeWidget):
self.blockSignals(True) self.blockSignals(True)
for i in range(item.childCount()): for i in range(item.childCount()):
child = item.child(i) child = item.child(i)
child.setCheckState(0, QtCore.Qt.Unchecked) child.setCheckState(0, QtCore.Qt.CheckState.Unchecked)
to_be_hidden.add(child.data(0, QtCore.Qt.UserRole)) to_be_hidden.add(child.data(0, QtCore.Qt.ItemDataRole.UserRole))
try: try:
self._checked_sets.remove(child.data(0, QtCore.Qt.UserRole)) self._checked_sets.remove(child.data(0, QtCore.Qt.ItemDataRole.UserRole))
except KeyError: except KeyError:
pass pass
self.blockSignals(False) self.blockSignals(False)
@ -153,7 +163,7 @@ class DataTree(QtWidgets.QTreeWidget):
@QtCore.pyqtSlot(QtWidgets.QTreeWidgetItem) @QtCore.pyqtSlot(QtWidgets.QTreeWidgetItem)
def new_selection(self, item: QtWidgets.QTreeWidgetItem): def new_selection(self, item: QtWidgets.QTreeWidgetItem):
if item.parent() is None: if item.parent() is None:
self.management.select_window(item.data(0, QtCore.Qt.UserRole)) self.management.select_window(item.data(0, QtCore.Qt.ItemDataRole.UserRole))
def dropEvent(self, evt: QtGui.QDropEvent): def dropEvent(self, evt: QtGui.QDropEvent):
dropped_index = self.indexAt(evt.pos()) dropped_index = self.indexAt(evt.pos())
@ -179,7 +189,7 @@ class DataTree(QtWidgets.QTreeWidget):
from_parent.removeChild(it) from_parent.removeChild(it)
tobemoved.append(it) tobemoved.append(it)
take_from.append(from_parent.data(0, QtCore.Qt.UserRole)) take_from.append(from_parent.data(0, QtCore.Qt.ItemDataRole.UserRole))
pos = QtCore.QModelIndex(persistent_drop) pos = QtCore.QModelIndex(persistent_drop)
if self.dropIndicatorPosition() == QtWidgets.QAbstractItemView.BelowItem: if self.dropIndicatorPosition() == QtWidgets.QAbstractItemView.BelowItem:
@ -191,8 +201,8 @@ class DataTree(QtWidgets.QTreeWidget):
else: else:
to_parent.insertChildren(row, tobemoved) to_parent.insertChildren(row, tobemoved)
self.management.move_sets([it.data(0, QtCore.Qt.UserRole) for it in tobemoved], self.management.move_sets([it.data(0, QtCore.Qt.ItemDataRole.UserRole) for it in tobemoved],
to_parent.data(0, QtCore.Qt.UserRole), take_from, to_parent.data(0, QtCore.Qt.ItemDataRole.UserRole), take_from,
pos=-1 if append else row) pos=-1 if append else row)
self.update_indexes() self.update_indexes()
@ -207,7 +217,7 @@ class DataTree(QtWidgets.QTreeWidget):
while iterator.value(): while iterator.value():
item = iterator.value() item = iterator.value()
if item is not None: if item is not None:
data = item.data(0, QtCore.Qt.UserRole) data = item.data(0, QtCore.Qt.ItemDataRole.UserRole)
if data == gid_out: if data == gid_out:
from_parent = item from_parent = item
@ -231,7 +241,7 @@ class DataTree(QtWidgets.QTreeWidget):
self.blockSignals(False) self.blockSignals(False)
def sort(self, graph_item: QtWidgets.QTreeWidgetItem, mode: str = 'value'): def sort(self, graph_item: QtWidgets.QTreeWidgetItem, mode: str = 'value'):
graph_id = graph_item.data(0, QtCore.Qt.UserRole) graph_id = graph_item.data(0, QtCore.Qt.ItemDataRole.UserRole)
sets = self.management.get_attributes(graph_id, mode) sets = self.management.get_attributes(graph_id, mode)
sets = [el[0] for el in sorted(sets.items(), key=lambda x: x[1])] sets = [el[0] for el in sorted(sets.items(), key=lambda x: x[1])]
@ -243,7 +253,7 @@ class DataTree(QtWidgets.QTreeWidget):
for s in sets: for s in sets:
for c in children: for c in children:
if c.data(0, QtCore.Qt.UserRole) == s: if c.data(0, QtCore.Qt.ItemDataRole.UserRole) == s:
graph_item.addChild(c) graph_item.addChild(c)
self.update_indexes() self.update_indexes()
@ -276,7 +286,7 @@ class DataTree(QtWidgets.QTreeWidget):
while iterator.value(): while iterator.value():
item = iterator.value() item = iterator.value()
if item is not None: if item is not None:
data = item.data(0, QtCore.Qt.UserRole) data = item.data(0, QtCore.Qt.ItemDataRole.UserRole)
if data == sid: if data == sid:
if name != item.text(0): if name != item.text(0):
item.setText(0, name) item.setText(0, name)
@ -285,7 +295,7 @@ class DataTree(QtWidgets.QTreeWidget):
iterator += 1 iterator += 1
def keyPressEvent(self, evt: QtGui.QKeyEvent): def keyPressEvent(self, evt: QtGui.QKeyEvent):
if evt.key() == QtCore.Qt.Key_Delete: if evt.key() == QtCore.Qt.Key.Key_Delete:
rm_sets = [] rm_sets = []
rm_graphs = [] rm_graphs = []
for idx in self.selectedIndexes(): for idx in self.selectedIndexes():
@ -296,20 +306,20 @@ class DataTree(QtWidgets.QTreeWidget):
if item.parent() is None: if item.parent() is None:
for c_i in range(item.childCount()): for c_i in range(item.childCount()):
# add sets inside graph to removal # add sets inside graph to removal
child_data = item.child(c_i).data(0, QtCore.Qt.UserRole) child_data = item.child(c_i).data(0, QtCore.Qt.ItemDataRole.UserRole)
if child_data not in rm_sets: if child_data not in rm_sets:
rm_sets.append(child_data) rm_sets.append(child_data)
rm_graphs.append(item.data(0, QtCore.Qt.UserRole)) rm_graphs.append(item.data(0, QtCore.Qt.ItemDataRole.UserRole))
else: else:
item_data = item.data(0, QtCore.Qt.UserRole) item_data = item.data(0, QtCore.Qt.ItemDataRole.UserRole)
if item_data not in rm_sets: if item_data not in rm_sets:
rm_sets.append(item_data) rm_sets.append(item_data)
# self.deleteItem.emit(rm_sets+rm_graphs) # self.deleteItem.emit(rm_sets+rm_graphs)
self.management.delete_sets(rm_sets+rm_graphs) self.management.delete_sets(rm_sets+rm_graphs)
elif evt.key() == QtCore.Qt.Key_Space: elif evt.key() == QtCore.Qt.Key.Key_Space:
sets = [] sets = []
from_parent = [] from_parent = []
@ -329,7 +339,7 @@ class DataTree(QtWidgets.QTreeWidget):
for it in sets: for it in sets:
if it in from_parent: if it in from_parent:
continue continue
it.setCheckState(0, QtCore.Qt.Unchecked if it.checkState(0) == QtCore.Qt.Checked else QtCore.Qt.Checked) it.setCheckState(0, QtCore.Qt.CheckState.Unchecked if it.checkState(0) == QtCore.Qt.CheckState.Checked else QtCore.Qt.CheckState.Checked)
s1, s2 = self.data_change(it, emit=False) s1, s2 = self.data_change(it, emit=False)
to_be_hidden |= s2 to_be_hidden |= s2
to_be_shown |= s1 to_be_shown |= s1
@ -353,7 +363,7 @@ class DataTree(QtWidgets.QTreeWidget):
# find all items that have to be removed # find all items that have to be removed
while iterator.value(): while iterator.value():
item = iterator.value() item = iterator.value()
_id = item.data(0, QtCore.Qt.UserRole) _id = item.data(0, QtCore.Qt.ItemDataRole.UserRole)
if _id in ids: if _id in ids:
try: try:
item_parent = item.parent() item_parent = item.parent()
@ -431,7 +441,7 @@ class DataTree(QtWidgets.QTreeWidget):
if i.column() == 0: if i.column() == 0:
continue continue
items.append(self.itemFromIndex(i)) items.append(self.itemFromIndex(i))
graphs.append(self.itemFromIndex(i).data(0, QtCore.Qt.UserRole)) graphs.append(self.itemFromIndex(i).data(0, QtCore.Qt.ItemDataRole.UserRole))
if action == del_action: if action == del_action:
for gid in graphs: for gid in graphs:
@ -473,12 +483,12 @@ class DataTree(QtWidgets.QTreeWidget):
continue continue
else: else:
graph_id = parent.data(0, QtCore.Qt.UserRole) graph_id = parent.data(0, QtCore.Qt.ItemDataRole.UserRole)
if graph_id not in idx: if graph_id not in idx:
idx[graph_id] = [] idx[graph_id] = []
# collect sets in their graph # collect sets in their graph
idx[graph_id].append(item.data(0, QtCore.Qt.UserRole)) idx[graph_id].append(item.data(0, QtCore.Qt.ItemDataRole.UserRole))
data = self.management[item.data(0, QtCore.Qt.UserRole)] data = self.management[item.data(0, QtCore.Qt.ItemDataRole.UserRole)]
if data.mode == 'fit': if data.mode == 'fit':
has_fits = True has_fits = True
@ -523,7 +533,7 @@ class DataTree(QtWidgets.QTreeWidget):
while iterator.value(): while iterator.value():
item = iterator.value() item = iterator.value()
if item is not None: if item is not None:
if item.data(0, QtCore.Qt.UserRole) == gid: if item.data(0, QtCore.Qt.ItemDataRole.UserRole) == gid:
item.setBackground(0, QtGui.QBrush(QtGui.QColor('gray'))) item.setBackground(0, QtGui.QBrush(QtGui.QColor('gray')))
else: else:
item.setBackground(0, QtGui.QBrush()) item.setBackground(0, QtGui.QBrush())
@ -536,10 +546,10 @@ class DataTree(QtWidgets.QTreeWidget):
while iterator.value(): while iterator.value():
item = iterator.value() item = iterator.value()
if item is not None: if item is not None:
if item.data(0, QtCore.Qt.UserRole) in sets: if item.data(0, QtCore.Qt.ItemDataRole.UserRole) in sets:
item.setCheckState(0, QtCore.Qt.Unchecked) item.setCheckState(0, QtCore.Qt.CheckState.Unchecked)
else: else:
self._checked_sets.add(item.data(0, QtCore.Qt.UserRole)) self._checked_sets.add(item.data(0, QtCore.Qt.ItemDataRole.UserRole))
iterator += 1 iterator += 1
self.blockSignals(False) self.blockSignals(False)
@ -594,7 +604,7 @@ class DataWidget(QtWidgets.QWidget, Ui_DataWidget):
sid = [] sid = []
for i in self.tree.selectedIndexes(): for i in self.tree.selectedIndexes():
if i.column() == 0: if i.column() == 0:
sid.append(i.data(role=QtCore.Qt.UserRole)) sid.append(i.data(role=QtCore.Qt.ItemDataRole.UserRole))
self.startShowProperty.emit(sid) self.startShowProperty.emit(sid)
@ -603,15 +613,23 @@ class DataWidget(QtWidgets.QWidget, Ui_DataWidget):
self.proptable.populate(props) self.proptable.populate(props)
def change_property(self, key1, key2, value): def change_property(self, key1, key2, value):
ids = [item.data(0, QtCore.Qt.UserRole) for item in self.tree.selectedItems()]
if key2 == 'Value': if key2 == 'Value':
try: try:
value = float(value) value = float(value)
except ValueError: except ValueError:
QtWidgets.QMessageBox.warning(self, 'Invalid entry', QtWidgets.QMessageBox.warning(
'Value %r is not a valid number for `value`.' % value) self,
'Invalid entry',
f'Value {value!r} is not a valid number for `value`.')
return return
ids = []
for item in self.tree.selectedItems():
ids.append(item.data(0, QtCore.Qt.ItemDataRole.UserRole))
item.setToolTip(0, str(value))
else:
ids = [item.data(0, QtCore.Qt.ItemDataRole.UserRole) for item in self.tree.selectedItems()]
self.propertyChanged.emit(ids, key1, key2, value) self.propertyChanged.emit(ids, key1, key2, value)
def uncheck_sets(self, sets: list[str]): def uncheck_sets(self, sets: list[str]):

View File

@ -41,7 +41,7 @@ class PropWidget(QtWidgets.QWidget):
idx = table.indexFromItem(item) idx = table.indexFromItem(item)
self.propertyChanged.emit(self.tab.tabText(tab_idx), self.propertyChanged.emit(self.tab.tabText(tab_idx),
table.item(idx.row(), idx.column()-1).text(), table.item(idx.row(), idx.column()-1).text(),
item.data(QtCore.Qt.DisplayRole)) item.data(QtCore.Qt.ItemDataRole.DisplayRole))
@QtCore.pyqtSlot(int) @QtCore.pyqtSlot(int)
def tab_change(self, idx: int): def tab_change(self, idx: int):
@ -66,10 +66,10 @@ class PropTable(QtWidgets.QTableWidget):
self.blockSignals(True) self.blockSignals(True)
for k, v in prop.items(): for k, v in prop.items():
value_item = QtWidgets.QTableWidgetItem('') value_item = QtWidgets.QTableWidgetItem('')
value_item.setData(QtCore.Qt.DisplayRole, v) value_item.setData(QtCore.Qt.ItemDataRole.DisplayRole, v)
key_item = QtWidgets.QTableWidgetItem(k) key_item = QtWidgets.QTableWidgetItem(k)
key_item.setFlags(QtCore.Qt.NoItemFlags) key_item.setFlags(QtCore.Qt.ItemFlag.NoItemFlags)
key_item.setForeground(QtGui.QBrush(QtGui.QColor(0, 0, 0))) key_item.setForeground(QtGui.QBrush(QtGui.QColor(0, 0, 0)))
self.setRowCount(self.rowCount()+1) self.setRowCount(self.rowCount()+1)

View File

@ -3,10 +3,10 @@ from __future__ import annotations
from typing import Any from typing import Any
from numpy import ndarray, iscomplexobj, asarray from numpy import ndarray, iscomplexobj, asarray
from pyqtgraph import PlotDataItem
from ..Qt import QtGui, QtCore, QtWidgets from ..Qt import QtGui, QtCore, QtWidgets
from .._py.valueeditor import Ui_MaskDialog from .._py.valueeditor import Ui_MaskDialog
from ..lib.pg_objects import PlotItem
class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog): class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog):
@ -35,12 +35,12 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog):
self.tableView.setModel(self.model) self.tableView.setModel(self.model)
self.tableView.setSelectionModel(self.selection_model) self.tableView.setSelectionModel(self.selection_model)
self.tableView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.tableView.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.CustomContextMenu)
self.tableView.customContextMenuRequested.connect(self.ctx) self.tableView.customContextMenuRequested.connect(self.ctx)
self.selection_real = PlotDataItem(x=[], y=[], symbolSize=25, symbol='x', self.selection_real = PlotItem(x=[], y=[], symbolSize=25, symbol='x',
pen=None, symbolPen='#c9308e', symbolBrush='#c9308e') pen=None, symbolPen='#c9308e', symbolBrush='#c9308e')
self.selection_imag = PlotDataItem(x=[], y=[], symbolSize=25, symbol='+', self.selection_imag = PlotItem(x=[], y=[], symbolSize=25, symbol='+',
pen=None, symbolPen='#dcdcdc', symbolBrush='#dcdcdc') pen=None, symbolPen='#dcdcdc', symbolBrush='#dcdcdc')
def __call__(self, items: dict): def __call__(self, items: dict):
@ -133,7 +133,7 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog):
def keyPressEvent(self, evt): def keyPressEvent(self, evt):
if evt.matches(QtGui.QKeySequence.Copy): if evt.matches(QtGui.QKeySequence.Copy):
self.copy_selection() self.copy_selection()
elif evt.key() == QtCore.Qt.Key_Delete: elif evt.key() == QtCore.Qt.Key.Key_Delete:
self.delete_item() self.delete_item()
else: else:
super().keyPressEvent(evt) super().keyPressEvent(evt)
@ -229,7 +229,7 @@ class ValueModel(QtCore.QAbstractTableModel):
""" """
itemChanged = QtCore.pyqtSignal(int, int, str) itemChanged = QtCore.pyqtSignal(int, int, str)
load_number = 20 load_number = 20
maskRole = QtCore.Qt.UserRole+321 maskRole = QtCore.Qt.ItemDataRole.UserRole+321
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent=parent) super().__init__(parent=parent)
@ -240,7 +240,7 @@ class ValueModel(QtCore.QAbstractTableModel):
self.mask = None self.mask = None
self.headers = ['x', 'y', '\u0394y'] self.headers = ['x', 'y', '\u0394y']
for i, hd in enumerate(self.headers): for i, hd in enumerate(self.headers):
self.setHeaderData(i, QtCore.Qt.Horizontal, hd) self.setHeaderData(i, QtCore.Qt.Orientation.Horizontal, hd)
def rowCount(self, *args, **kwargs) -> int: def rowCount(self, *args, **kwargs) -> int:
return self.total_rows return self.total_rows
@ -258,25 +258,28 @@ class ValueModel(QtCore.QAbstractTableModel):
self.mask = mask.tolist() self.mask = mask.tolist()
self.endResetModel() self.endResetModel()
self.dataChanged.emit(self.index(0, 0), self.index(0, 1), [QtCore.Qt.DisplayRole]) self.dataChanged.emit(
self.index(0, 0),
self.index(0, 1), [QtCore.Qt.ItemDataRole.DisplayRole]
)
def data(self, idx: QtCore.QModelIndex, role=QtCore.Qt.DisplayRole) -> Any: def data(self, idx: QtCore.QModelIndex, role=QtCore.Qt.ItemDataRole.DisplayRole) -> Any:
if not idx.isValid(): if not idx.isValid():
return return
row = idx.row() row = idx.row()
if role in [QtCore.Qt.DisplayRole, QtCore.Qt.EditRole]: if role in [QtCore.Qt.ItemDataRole.DisplayRole, QtCore.Qt.ItemDataRole.EditRole]:
val = self._data[row][idx.column()] val = self._data[row][idx.column()]
return self.as_string(val) return self.as_string(val)
elif role == QtCore.Qt.BackgroundRole: elif role == QtCore.Qt.ItemDataRole.BackgroundRole:
pal = QtGui.QGuiApplication.palette() pal = QtGui.QGuiApplication.palette()
if not self.mask[row]: if not self.mask[row]:
return pal.color(QtGui.QPalette.Disabled, QtGui.QPalette.Base) return pal.color(QtGui.QPalette.Disabled, QtGui.QPalette.Base)
else: else:
return pal.color(QtGui.QPalette.Base) return pal.color(QtGui.QPalette.Base)
elif role == QtCore.Qt.ForegroundRole: elif role == QtCore.Qt.ItemDataRole.ForegroundRole:
pal = QtGui.QGuiApplication.palette() pal = QtGui.QGuiApplication.palette()
if not self.mask[row]: if not self.mask[row]:
return pal.color(QtGui.QPalette.Disabled, QtGui.QPalette.Text) return pal.color(QtGui.QPalette.Disabled, QtGui.QPalette.Text)
@ -289,7 +292,7 @@ class ValueModel(QtCore.QAbstractTableModel):
else: else:
return return
def setData(self, idx: QtCore.QModelIndex, value: str | bool, role=QtCore.Qt.DisplayRole) -> Any: def setData(self, idx: QtCore.QModelIndex, value: str | bool, role=QtCore.Qt.ItemDataRole.DisplayRole) -> Any:
col, row = idx.column(), idx.row() col, row = idx.column(), idx.row()
if role == ValueModel.maskRole: if role == ValueModel.maskRole:
@ -299,7 +302,7 @@ class ValueModel(QtCore.QAbstractTableModel):
return True return True
if value: if value:
if role == QtCore.Qt.EditRole: if role == QtCore.Qt.ItemDataRole.EditRole:
if value == self.as_string(self._data[row][col]): if value == self.as_string(self._data[row][col]):
return True return True
@ -322,9 +325,9 @@ class ValueModel(QtCore.QAbstractTableModel):
else: else:
return False return False
def headerData(self, section: int, orientation, role=QtCore.Qt.DisplayRole) -> Any: def headerData(self, section: int, orientation, role=QtCore.Qt.ItemDataRole.DisplayRole) -> Any:
if role == QtCore.Qt.DisplayRole: if role == QtCore.Qt.ItemDataRole.DisplayRole:
if orientation == QtCore.Qt.Horizontal: if orientation == QtCore.Qt.Orientation.Horizontal:
return self.headers[section] return self.headers[section]
else: else:
return str(section+1) return str(section+1)
@ -346,7 +349,7 @@ class ValueModel(QtCore.QAbstractTableModel):
self.endInsertRows() self.endInsertRows()
def flags(self, idx: QtCore.QModelIndex) -> QtCore.Qt.ItemFlag: def flags(self, idx: QtCore.QModelIndex) -> QtCore.Qt.ItemFlag:
return QtCore.QAbstractTableModel.flags(self, idx) | QtCore.Qt.ItemIsEditable return QtCore.QAbstractTableModel.flags(self, idx) | QtCore.Qt.ItemFlag.ItemIsEditable
def removeRows(self, pos: int, rows: int, parent=None, *args, **kwargs) -> bool: def removeRows(self, pos: int, rows: int, parent=None, *args, **kwargs) -> bool:
self.beginRemoveRows(parent, pos, pos+rows-1) self.beginRemoveRows(parent, pos, pos+rows-1)

View File

@ -136,8 +136,8 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
max_x = max(max_x, data.x.max()) max_x = max(max_x, data.x.max())
item = QtWidgets.QListWidgetItem(name) item = QtWidgets.QListWidgetItem(name)
item.setCheckState(QtCore.Qt.Checked) item.setCheckState(QtCore.Qt.CheckState.Checked)
item.setData(QtCore.Qt.UserRole, key) item.setData(QtCore.Qt.ItemDataRole.UserRole, key)
item.setForeground(mkBrush(c.rgb())) item.setForeground(mkBrush(c.rgb()))
self.listWidget.addItem(item) self.listWidget.addItem(item)
@ -191,10 +191,10 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
for idx in range(self.listWidget.count()): for idx in range(self.listWidget.count()):
item = self.listWidget.item(idx) item = self.listWidget.item(idx)
if item.checkState() == QtCore.Qt.Unchecked: if item.checkState() == QtCore.Qt.CheckState.Unchecked:
continue continue
key = item.data(QtCore.Qt.UserRole) key = item.data(QtCore.Qt.ItemDataRole.UserRole)
plot = self._plots[key] plot = self._plots[key]
data, _ = self._dsc[key] data, _ = self._dsc[key]
@ -214,7 +214,7 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
item = self.listWidget.item(idx) item = self.listWidget.item(idx)
tree_item = QtWidgets.QTreeWidgetItem([item.text()]) tree_item = QtWidgets.QTreeWidgetItem([item.text()])
values = self._tg_value.get(item.data(QtCore.Qt.UserRole)) values = self._tg_value.get(item.data(QtCore.Qt.ItemDataRole.UserRole))
if values is not None: if values is not None:
for name, pos in values.items(): for name, pos in values.items():
@ -223,7 +223,7 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
self.tg_tree.addTopLevelItem(tree_item) self.tg_tree.addTopLevelItem(tree_item)
key = item.data(QtCore.Qt.UserRole) key = item.data(QtCore.Qt.ItemDataRole.UserRole)
plot = self._plots[key] plot = self._plots[key]
data, _ = self._dsc[key] data, _ = self._dsc[key]
@ -251,7 +251,7 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
@QtCore.pyqtSlot(QtWidgets.QListWidgetItem) @QtCore.pyqtSlot(QtWidgets.QListWidgetItem)
def change_visibility(self, item: QtWidgets.QListWidgetItem): def change_visibility(self, item: QtWidgets.QListWidgetItem):
is_checked = bool(item.checkState()) is_checked = bool(item.checkState())
plot = self._plots[item.data(QtCore.Qt.UserRole)] plot = self._plots[item.data(QtCore.Qt.ItemDataRole.UserRole)]
for val in plot: for val in plot:
val.setVisible(is_checked) val.setVisible(is_checked)
@ -275,10 +275,10 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
self.tnmh_tree.clear() self.tnmh_tree.clear()
for idx in range(self.listWidget.count()): for idx in range(self.listWidget.count()):
item = self.listWidget.item(idx) item = self.listWidget.item(idx)
if item.checkState() == QtCore.Qt.Unchecked: if item.checkState() == QtCore.Qt.CheckState.Unchecked:
continue continue
key = item.data(QtCore.Qt.UserRole) key = item.data(QtCore.Qt.ItemDataRole.UserRole)
data = self.get_fictive(key, baselines) data = self.get_fictive(key, baselines)
@ -292,7 +292,7 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
item = self.listWidget.item(idx) item = self.listWidget.item(idx)
tree_item = QtWidgets.QTreeWidgetItem([item.text()]) tree_item = QtWidgets.QTreeWidgetItem([item.text()])
values = self._fit.get(item.data(QtCore.Qt.UserRole)) values = self._fit.get(item.data(QtCore.Qt.ItemDataRole.UserRole))
if values is not None: if values is not None:
child_item = QtWidgets.QTreeWidgetItem([values.parameter_string()]) child_item = QtWidgets.QTreeWidgetItem([values.parameter_string()])
@ -305,10 +305,10 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
ret_dic = {} ret_dic = {}
for idx in range(self.listWidget.count()): for idx in range(self.listWidget.count()):
item = self.listWidget.item(idx) item = self.listWidget.item(idx)
if item.checkState() == QtCore.Qt.Unchecked: if item.checkState() == QtCore.Qt.CheckState.Unchecked:
continue continue
key = item.data(QtCore.Qt.UserRole) key = item.data(QtCore.Qt.ItemDataRole.UserRole)
cp = None cp = None
if self.fictive_export_check.isChecked(): if self.fictive_export_check.isChecked():
@ -332,10 +332,10 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
m = [] m = []
for idx in range(self.listWidget.count()): for idx in range(self.listWidget.count()):
item = self.listWidget.item(idx) item = self.listWidget.item(idx)
if item.checkState() == QtCore.Qt.Unchecked: if item.checkState() == QtCore.Qt.CheckState.Unchecked:
continue continue
key = item.data(QtCore.Qt.UserRole) key = item.data(QtCore.Qt.ItemDataRole.UserRole)
data, _ = self._dsc[key] data, _ = self._dsc[key]
try: try:
tg_value = self._tg_value[key][tg_type][0] tg_value = self._tg_value[key][tg_type][0]

View File

@ -58,7 +58,8 @@ class FitToolbar(QtWidgets.QToolBar):
@QtCore.pyqtSlot(QtWidgets.QAction) @QtCore.pyqtSlot(QtWidgets.QAction)
def change_limit_type(self, action: QtWidgets.QAction): def change_limit_type(self, action: QtWidgets.QAction):
is_custom = (action.text() == 'Custom') is_custom = (action.text() in ['Custom', 'Exclude region'])
print(is_custom)
for w in [self.label, self.label2, self.lineedit, self.lineedit2]: for w in [self.label, self.label2, self.lineedit, self.lineedit2]:
w.setEnabled(is_custom) w.setEnabled(is_custom)
@ -93,5 +94,6 @@ class FitToolbar(QtWidgets.QToolBar):
return { return {
'None': 'none', 'None': 'none',
'Visible x range': 'x', 'Visible x range': 'x',
'Custom': self.region.getRegion(), 'Custom': ('in', self.region.getRegion()),
'Exclude region': ('out', self.region.getRegion()),
}[action_text] }[action_text]

View File

@ -1,3 +1,5 @@
from __future__ import annotations
from math import isnan from math import isnan
from pyqtgraph import mkBrush, mkPen from pyqtgraph import mkBrush, mkPen
@ -28,6 +30,7 @@ class QFitResult(QtWidgets.QDialog, Ui_Dialog):
self.extrapolate_box.stateChanged.connect(lambda x: self.maxx_line.setEnabled(x)) self.extrapolate_box.stateChanged.connect(lambda x: self.maxx_line.setEnabled(x))
self.extrapolate_box.stateChanged.connect(lambda x: self.minx_line.setEnabled(x)) self.extrapolate_box.stateChanged.connect(lambda x: self.minx_line.setEnabled(x))
self.extrapolate_box.stateChanged.connect(lambda x: self.numx_line.setEnabled(x)) self.extrapolate_box.stateChanged.connect(lambda x: self.numx_line.setEnabled(x))
self.extrapolate_box.stateChanged.connect(lambda x: self.newx_log_checkbox.setEnabled(x))
self._previous_fits = {} self._previous_fits = {}
self._opts = [] self._opts = []
@ -352,7 +355,7 @@ class QFitResult(QtWidgets.QDialog, Ui_Dialog):
parts = self.partial_checkBox.checkState() == QtCore.Qt.CheckState.Checked parts = self.partial_checkBox.checkState() == QtCore.Qt.CheckState.Checked
extrapolate = [None, None, None] extrapolate = [None, None, None, None]
error = [] error = []
if self.extrapolate_box.isChecked(): if self.extrapolate_box.isChecked():
try: try:
@ -368,6 +371,8 @@ class QFitResult(QtWidgets.QDialog, Ui_Dialog):
except (TypeError, ValueError): except (TypeError, ValueError):
error.append('Number of points is missing') error.append('Number of points is missing')
extrapolate[3] = self.newx_log_checkbox.isChecked()
if error: if error:
msg = QtWidgets.QMessageBox.warning(self, 'Error', 'Extrapolation failed because:\n' + '\n'.join(error)) msg = QtWidgets.QMessageBox.warning(self, 'Error', 'Extrapolation failed because:\n' + '\n'.join(error))
return return
@ -405,10 +410,13 @@ class FitExtension(QtWidgets.QDialog):
self.num_pts.setValidator(QtGui.QIntValidator()) self.num_pts.setValidator(QtGui.QIntValidator())
gridLayout.addWidget(self.num_pts, 2, 1, 1, 1) gridLayout.addWidget(self.num_pts, 2, 1, 1, 1)
self.logx_checkbox = QtWidgets.QCheckBox('Log-spaced?')
gridLayout.addWidget(self.logx_checkbox, 3, 0, 1, 2)
self.buttonBox = QtWidgets.QDialogButtonBox() self.buttonBox = QtWidgets.QDialogButtonBox()
self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal) self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel | QtWidgets.QDialogButtonBox.Ok) self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel | QtWidgets.QDialogButtonBox.Ok)
gridLayout.addWidget(self.buttonBox, 3, 0, 1, 2) gridLayout.addWidget(self.buttonBox, 4, 0, 1, 2)
self.setLayout(gridLayout) self.setLayout(gridLayout)
@ -416,12 +424,13 @@ class FitExtension(QtWidgets.QDialog):
self.buttonBox.rejected.connect(self.reject) self.buttonBox.rejected.connect(self.reject)
@property @property
def values(self): def values(self) -> tuple[float, float, int, bool] | None:
try: try:
xmin = float(self.min_line.text()) xmin = float(self.min_line.text())
xmax = float(self.max_line.text()) xmax = float(self.max_line.text())
nums = int(self.num_pts.text()) nums = int(self.num_pts.text())
logx = self.logx_checkbox.isChecked()
except TypeError: except TypeError:
return None return None
return xmin, xmax, nums return xmin, xmax, nums, logx

View File

@ -670,11 +670,14 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow):
else: else:
if os.path.exists(outfile): if os.path.exists(outfile):
if QtWidgets.QMessageBox.warning(self, 'Export graphic', if QtWidgets.QMessageBox.warning(
self,
'Export graphic',
f'{os.path.split(outfile)[1]} already exists.\n' f'{os.path.split(outfile)[1]} already exists.\n'
f'Do you REALLY want to replace it?', f'Do you REALLY want to replace it?',
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No: QtWidgets.QMessageBox.No
) == QtWidgets.QMessageBox.No:
return return
bg_color = self._bgcolor bg_color = self._bgcolor
@ -716,16 +719,20 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow):
logger.exception(f'{item} could not exported because {e.args}') logger.exception(f'{item} could not exported because {e.args}')
continue continue
if item_dic:
if len(item) == 2: if len(item) == 2:
# plot can show errorbars # plot can show errorbars
if len(item_dic['x']):
item_dic['yerr'] = item[1].opts['topData'] item_dic['yerr'] = item[1].opts['topData']
else:
if item_dic: item_dic['yerr'] = []
dic['items'].append(item_dic) dic['items'].append(item_dic)
for item in self._external_items: for item in self._external_items:
try: try:
dic['items'].append(item.get_data_opts()) item_dic = item.get_data_opts()
if item_dic:
dic['items'].append(item_dic)
except Exception as e: except Exception as e:
logger.exception(f'{item} could not be exported because {e.args}') logger.exception(f'{item} could not be exported because {e.args}')
continue continue

View File

@ -78,14 +78,22 @@ class QDSCReader(QtWidgets.QDialog, Ui_Dialog):
for opts in self.sample.steps: for opts in self.sample.steps:
item = QtWidgets.QListWidgetItem() item = QtWidgets.QListWidgetItem()
item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable) item.setFlags(
item.setCheckState(QtCore.Qt.Unchecked) QtCore.Qt.ItemFlag.ItemIsEnabled |
QtCore.Qt.ItemFlag.ItemIsSelectable |
QtCore.Qt.ItemFlag.ItemIsUserCheckable
)
item.setCheckState(QtCore.Qt.CheckState.Unchecked)
if opts[0] == 'i': if opts[0] == 'i':
item.setFlags(QtCore.Qt.NoItemFlags) item.setFlags(QtCore.Qt.ItemFlag.NoItemFlags)
item.setText(f'{opts[1]:.2f} K for {opts[2] / 60:.0f} min') item.setText(f'{opts[1]:.2f} K for {opts[2] / 60:.0f} min')
else: else:
item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable) item.setFlags(
QtCore.Qt.ItemFlag.ItemIsEnabled |
QtCore.Qt.ItemFlag.ItemIsSelectable |
QtCore.Qt.ItemFlag.ItemIsUserCheckable
)
item.setText(f'{opts[2]:.2f} K to {opts[3]:.2f} K with {opts[1]} K/min') item.setText(f'{opts[2]:.2f} K to {opts[3]:.2f} K with {opts[1]} K/min')
self.step_listWidget.addItem(item) self.step_listWidget.addItem(item)
@ -97,7 +105,12 @@ class QDSCReader(QtWidgets.QDialog, Ui_Dialog):
if empty: if empty:
self.empty = self.calibrator.set_measurement(empty, mode='empty') self.empty = self.calibrator.set_measurement(empty, mode='empty')
# avoid ValueError breaking data update
if self.empty.fname.is_relative_to(Path.home()):
self.empty_label.setText('~/' + str(self.empty.fname.relative_to(Path.home()))) self.empty_label.setText('~/' + str(self.empty.fname.relative_to(Path.home())))
else:
self.empty_label.setText(str(self.empty.fname))
self.update_plots() self.update_plots()
@ -118,8 +131,8 @@ class QDSCReader(QtWidgets.QDialog, Ui_Dialog):
self.references.append(ref) self.references.append(ref)
item = QtWidgets.QTableWidgetItem(str(ref.fname.name)) item = QtWidgets.QTableWidgetItem(str(ref.fname.name))
item.setData(QtCore.Qt.UserRole, ref.fname) item.setData(QtCore.Qt.ItemDataRole.UserRole, ref.fname)
item.setFlags(QtCore.Qt.ItemIsEnabled) item.setFlags(QtCore.Qt.ItemFlag.ItemIsEnabled)
rowcnt = self.reference_tableWidget.rowCount() rowcnt = self.reference_tableWidget.rowCount()
self.reference_tableWidget.setRowCount(rowcnt+1) self.reference_tableWidget.setRowCount(rowcnt+1)
@ -132,7 +145,7 @@ class QDSCReader(QtWidgets.QDialog, Ui_Dialog):
@QtCore.pyqtSlot(name='on_ref_remove_pushButton_clicked') @QtCore.pyqtSlot(name='on_ref_remove_pushButton_clicked')
def remove_reference(self): def remove_reference(self):
idx = self.reference_tableWidget.currentRow() idx = self.reference_tableWidget.currentRow()
self.calibrator.remove_reference(self.reference_tableWidget.item(idx, 0).data(QtCore.Qt.UserRole)) self.calibrator.remove_reference(self.reference_tableWidget.item(idx, 0).data(QtCore.Qt.ItemDataRole.UserRole))
self.reference_tableWidget.removeRow(idx) self.reference_tableWidget.removeRow(idx)
self.update_plots() self.update_plots()
@ -145,10 +158,10 @@ class QDSCReader(QtWidgets.QDialog, Ui_Dialog):
for row in range(self.step_listWidget.count()): for row in range(self.step_listWidget.count()):
if idx == row: if idx == row:
continue continue
self.step_listWidget.item(row).setCheckState(QtCore.Qt.Unchecked) self.step_listWidget.item(row).setCheckState(QtCore.Qt.CheckState.Unchecked)
self.step_listWidget.blockSignals(False) self.step_listWidget.blockSignals(False)
if item.checkState() == QtCore.Qt.Checked: if item.checkState() == QtCore.Qt.CheckState.Checked:
mode, rate, _, _ = self.sample.steps[idx] mode, rate, _, _ = self.sample.steps[idx]
self.current_run = (rate, mode) self.current_run = (rate, mode)
self.sample_idx = idx self.sample_idx = idx
@ -217,6 +230,8 @@ class QDSCReader(QtWidgets.QDialog, Ui_Dialog):
if empty_data is not None: if empty_data is not None:
self.empty_sample.setData(x=empty_data[0], y=empty_data[1]) self.empty_sample.setData(x=empty_data[0], y=empty_data[1])
else:
self.empty_sample.setData(x=[], y=[])
self.calib_graph.clear() self.calib_graph.clear()
@ -249,11 +264,16 @@ class QDSCReader(QtWidgets.QDialog, Ui_Dialog):
except TypeError: except TypeError:
return return
if self.cp_checkBox.isChecked() and self.references:
y_label = 'cp'
else:
y_label = 'q'
rate, mode = self.current_run rate, mode = self.current_run
new_val = DSC(sample_data[0], sample_data[1], value=rate, name=f'{self.fname.stem} {rate} ({mode})') new_val = DSC(sample_data[0], sample_data[1], value=rate, name=f'{self.fname.stem} {rate}K-min ({mode}, {y_label})')
if filesave: if filesave:
new_val.savetxt(self.fname.with_name(f'{self.fname.stem} {rate}K-min {mode}.dat'.replace(' ', '_'))) new_val.savetxt(self.fname.with_name(f'{self.fname.stem}_{rate}K-min_{y_label}{mode}.dat'.replace(' ', '_')))
close_after = False close_after = False
else: else:
self.data_read.emit([new_val]) self.data_read.emit([new_val])

View File

@ -183,6 +183,8 @@ class PlotItem(PlotDataItem):
brush = self.opts['symbolBrush'] brush = self.opts['symbolBrush']
if isinstance(brush, tuple): if isinstance(brush, tuple):
self.opts['symbolcolor'] = brush self.opts['symbolcolor'] = brush
elif isinstance(brush, str):
self.opts['symbolcolor'] = int(f'0x{brush[1:3]}', 16), int(f'0x{brush[3:5]}', 16), int(f'0x{brush[5:7]}', 16)
else: else:
c = brush.color() c = brush.color()
self.opts['symbolcolor'] = c.red(), c.green(), c.blue() self.opts['symbolcolor'] = c.red(), c.green(), c.blue()
@ -340,7 +342,8 @@ class PlotItem(PlotDataItem):
opts = self.opts opts = self.opts
item_dic = { item_dic = {
'x': x, 'y': y, 'x': x,
'y': y,
'name': opts.get('name', ''), 'name': opts.get('name', ''),
'symbolsize': opts['symbolSize'], 'symbolsize': opts['symbolSize'],
} }

View File

@ -888,7 +888,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
self.fit_dialog.load(self.management.active_sets) self.fit_dialog.load(self.management.active_sets)
for item in self.fit_dialog.preview_lines: for item in self.fit_dialog.preview_lines:
self.current_graph_widget.add_external(item) self.current_graph_widget.add_external(item)
if self.action_custom_range.isChecked(): if self.action_custom_range.isChecked() or self.actionExclude_region.isChecked():
self.current_graph_widget.add_external(self.fit_toolbar.region) self.current_graph_widget.add_external(self.fit_toolbar.region)
block_window = True block_window = True
@ -904,7 +904,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
if self.current_graph_widget is None: if self.current_graph_widget is None:
return return
if action == self.action_custom_range and self.fit_dialog.isVisible(): if action in [self.action_custom_range, self.actionExclude_region] and self.fit_dialog.isVisible():
self.current_graph_widget.add_external(self.fit_toolbar.region) self.current_graph_widget.add_external(self.fit_toolbar.region)
else: else:
self.current_graph_widget.remove_external(self.fit_toolbar.region) self.current_graph_widget.remove_external(self.fit_toolbar.region)
@ -984,7 +984,8 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
res = w.exec() res = w.exec()
if res: if res:
p = w.values p = w.values
x = linspace(p[0], p[1], num=p[2]) spacefunc = geomspace if p[3] else linspace
x = spacefunc(p[0], p[1], num=p[2])
self.management.extend_fits(sets, x) self.management.extend_fits(sets, x)
@QtCore.pyqtSlot(name='on_action_create_fit_function_triggered') @QtCore.pyqtSlot(name='on_action_create_fit_function_triggered')

View File

@ -525,13 +525,16 @@ class UpperManagement(QtCore.QObject):
_x = data_i.x _x = data_i.x
# options for fit limits 'none', 'x', ('in', custom region), ('out', excluded region)
if fit_limits == 'none': if fit_limits == 'none':
inside = slice(None) inside = slice(None)
elif fit_limits == 'x': elif fit_limits == 'x':
x_lim, _ = self.graphs[self.current_graph].ranges x_lim, _ = self.graphs[self.current_graph].ranges
inside = np.where((_x >= x_lim[0]) & (_x <= x_lim[1])) inside = np.where((_x >= x_lim[0]) & (_x <= x_lim[1]))
elif fit_limits[0] == 'in':
inside = np.where((_x >= fit_limits[1][0]) & (_x <= fit_limits[1][1]))
else: else:
inside = np.where((_x >= fit_limits[0]) & (_x <= fit_limits[1])) inside = np.where((_x < fit_limits[1][0]) | (_x > fit_limits[1][1]))
try: try:
if isinstance(we, str): if isinstance(we, str):
@ -627,7 +630,7 @@ class UpperManagement(QtCore.QObject):
continue continue
if not all(e is None for e in extrapolate): if not all(e is None for e in extrapolate):
spacefunc = np.geomspace if fit.islog else np.linspace spacefunc = np.geomspace if extrapolate[3] else np.linspace
xmin = fit.x.min() xmin = fit.x.min()
xmax = fit.x.max() xmax = fit.x.max()

View File

@ -12,10 +12,10 @@ class QSmooth(QtWidgets.QDialog, Ui_SmoothDialog):
@QtCore.pyqtSlot(int, name='on_comboBox_currentIndexChanged') @QtCore.pyqtSlot(int, name='on_comboBox_currentIndexChanged')
def change_mode(self, idx: int): def change_mode(self, idx: int):
if idx == 2: if idx == 1:
self.widget.show() self.widget.show()
self.widget_2.hide() self.widget_2.hide()
elif idx == 3: elif idx == 2:
self.widget.show() self.widget.show()
self.widget_2.show() self.widget_2.show()
else: else:
@ -29,12 +29,24 @@ class QSmooth(QtWidgets.QDialog, Ui_SmoothDialog):
idx = self.comboBox.currentIndex() idx = self.comboBox.currentIndex()
# this order must match the combobox # this order must match the combobox
para['mode'] = ['mean', 'savgol', 'loess', 'median', 'std', 'var', 'max', 'min', 'sum'][idx] para['mode'] = [
'mean',
'savgol',
'loess',
'median',
'std',
'var',
'max',
'min',
'sum',
][idx]
if idx == 2: # Savitzky-Golay needs also polynomial degree
if idx == 1:
para['deg'] = self.polynom_spinBox.value() para['deg'] = self.polynom_spinBox.value()
if idx == 3: # LOESS needs also polynomial degree and number of iterations
if idx == 2:
para['deg'] = self.polynom_spinBox.value() para['deg'] = self.polynom_spinBox.value()
para['it'] = self.iter_spinBox.value() para['it'] = self.iter_spinBox.value()

View File

@ -320,7 +320,11 @@ class Points:
pts = [] pts = []
_tmp_x = self._x[self.mask] _tmp_x = self._x[self.mask]
_tmp_y = self._y[self.mask] x_order = np.argsort(_tmp_x)
_tmp_x = _tmp_x[x_order]
_tmp_y = self._y[self.mask][x_order]
_tmp_yerr = self._y_err[self.mask][x_order]
if idx is not None: if idx is not None:
for idx_i in idx: for idx_i in idx:
if isinstance(idx_i, tuple): if isinstance(idx_i, tuple):
@ -338,7 +342,7 @@ class Points:
right_b = int(min(len(self), x_idx + avg_range[1] + 1)) right_b = int(min(len(self), x_idx + avg_range[1] + 1))
if left_b < right_b: if left_b < right_b:
pts.append([_tmp_x[x_idx], *self._average(avg_mode, x_idx, left_b, right_b)]) pts.append([_tmp_x[x_idx], *self._average(_tmp_x, _tmp_y, _tmp_yerr, avg_mode, x_idx, left_b, right_b)])
else: else:
pts.append([_tmp_x[x_idx], _tmp_y[x_idx], self._y_err[x_idx]]) pts.append([_tmp_x[x_idx], _tmp_y[x_idx], self._y_err[x_idx]])
@ -358,28 +362,37 @@ class Points:
left_b = int(max(0, x_idx - avg_range[0])) left_b = int(max(0, x_idx - avg_range[0]))
right_b = int(min(len(self), x_idx + avg_range[1] + 1)) right_b = int(min(len(self), x_idx + avg_range[1] + 1))
pts.append([_tmp_x[x_idx], *self._average(avg_mode, x_idx, left_b, right_b)]) pts.append([_tmp_x[x_idx], *self._average(_tmp_x, _tmp_y, _tmp_yerr, avg_mode, x_idx, left_b, right_b)])
return pts return pts
def _average(self, mode: str, idx, left: int, right: int) -> tuple[float, float]: @staticmethod
def _average(
x: np.ndarray,
y: np.ndarray,
y_err: np.ndarray,
mode: str,
idx: int,
left: int,
right: int,
) -> tuple[float, float]:
if mode == 'mean': if mode == 'mean':
y_mean = np.mean(self._y[self.mask][left:right].real) y_mean = np.mean(y[left:right].real)
y_err = np.linalg.norm(self._y_err[self.mask][left:right]) / (right - left) y_err_mean = np.linalg.norm(y_err[left:right]) / (right - left)
elif mode == 'sum': elif mode == 'sum':
y_mean = np.sum(self._y[self.mask][left:right].real) y_mean = np.sum(y[left:right].real)
y_err = np.linalg.norm(self._y_err[self.mask][left:right]) y_err_mean = np.linalg.norm(y_err[left:right])
elif mode == 'integral': elif mode == 'integral':
y_mean = simpson(self._y[self.mask][left:right].real, x=self._x[left:right]) y_mean = simpson(y[left:right].real, x=x[left:right])
y_err = np.linalg.norm(cumulative_trapezoid(self._y_err[self.mask][left:right].real, x=self._x[left:right])) y_err_mean = np.linalg.norm(cumulative_trapezoid(y_err[left:right].real, x=x[left:right]))
else: else:
y_mean = self._y[self.mask][idx].real y_mean = y[idx].real
y_err = self._y_err[self.mask][idx] y_err_mean = y_err[idx]
return y_mean, y_err return y_mean, y_err_mean
def concatenate(self, other): def concatenate(self, other):
""" """

View File

@ -183,7 +183,13 @@ class AsciiReader:
single_len = 2 single_len = 2
stepsize = 2 stepsize = 2
cls = {'points': Points, 'fid': FID, 'spectrum': Spectrum, 'bds': BDS, 'dsc': DSC}[mode] cls = {
'points': Points,
'fid': FID,
'spectrum': Spectrum,
'bds': BDS,
'dsc': DSC,
}[mode]
for j in range(1, num_y+1, stepsize): for j in range(1, num_y+1, stepsize):
if col_names is not None: if col_names is not None:
@ -191,7 +197,7 @@ class AsciiReader:
kwargs['name'] = col_names[j-1] kwargs['name'] = col_names[j-1]
elif num_y > single_len: elif num_y > single_len:
# more than one axis, append column number # more than one axis, append column number
kwargs['name'] = filename + '_' + str(y[j-1]) kwargs['name'] = f'{filename}_{y[j-1]+1}'
if j+num_y < raw_data.shape[2]: if j+num_y < raw_data.shape[2]:
kwargs['y_err'] = raw_data[i, :, j+num_y] kwargs['y_err'] = raw_data[i, :, j+num_y]

View File

@ -11,7 +11,8 @@ try:
from scipy.integrate import simpson from scipy.integrate import simpson
except ImportError: except ImportError:
from scipy.integrate import simps as simpson from scipy.integrate import simps as simpson
from scipy.interpolate import interp1d from scipy.interpolate import CubicSpline
ReferenceValue = namedtuple('Reference', ['name', 'transitions']) ReferenceValue = namedtuple('Reference', ['name', 'transitions'])
Cyclohexane = ReferenceValue('Cyclohexane', [(-87.06+273.15, 79.58), (6.54+273.15, None)]) Cyclohexane = ReferenceValue('Cyclohexane', [(-87.06+273.15, 79.58), (6.54+273.15, None)])
@ -38,7 +39,7 @@ class DSCSample:
def read_file(self, fname: str | Path) -> None: def read_file(self, fname: str | Path) -> None:
fname = Path(fname) fname = Path(fname)
# file contains weird deg C character in stupiod ISO encoding # file contains weird deg C character in stupid ISO encoding
with fname.open('r', encoding='iso-8859-15') as f: with fname.open('r', encoding='iso-8859-15') as f:
ii = 1 ii = 1
for line in f: for line in f:
@ -144,9 +145,12 @@ class DSCCalibrator:
self.reference = [] self.reference = []
self.ref_list = [] self.ref_list = []
def set_measurement(self, def set_measurement(
fname: str | Path | DSCSample, mode: str = 'sample', self: DSCCalibrator,
reference: ReferenceValue = Cyclohexane): fname: str | Path | DSCSample,
mode: str = 'sample',
reference: ReferenceValue = Cyclohexane
):
if mode not in ['sample', 'empty', 'reference']: if mode not in ['sample', 'empty', 'reference']:
raise ValueError(f'Unknown mode {mode}, not "sample", "empty", "reference"') raise ValueError(f'Unknown mode {mode}, not "sample", "empty", "reference"')
if mode == 'reference' and not isinstance(reference, ReferenceValue): if mode == 'reference' and not isinstance(reference, ReferenceValue):
@ -266,7 +270,12 @@ class DSCCalibrator:
return sol return sol
def get_data(self, idx: int, slope: str = 'iso', limits: tuple[float, float] = None): def get_data(
self: DSCCalibrator,
idx: int,
slope: str = 'iso',
limits: tuple[float, float] = None
) -> tuple[np.ndarray, np.ndarray, np.ndarray,np.ndarray | None, np.ndarray]:
if self.sample.steps[idx][0] == 'i': if self.sample.steps[idx][0] == 'i':
raise ValueError('baseline correction is not implemented for isotherms') raise ValueError('baseline correction is not implemented for isotherms')
@ -292,7 +301,7 @@ class DSCCalibrator:
empty_y = empty_data[1] empty_y = empty_data[1]
if self.sample.length(idx) != self.empty.length(idx_empty): if self.sample.length(idx) != self.empty.length(idx_empty):
with np.errstate(all='ignore'): with np.errstate(all='ignore'):
empty_y = interp1d(empty_data[2]-empty_data[2, 0], empty_data[1], fill_value='extrapolate')(sample_data[2, 0]) empty_y = CubicSpline(empty_data[2]-empty_data[2, 0], empty_data[1], extrapolate=True)(sample_data[2] - sample_data[2, 0])
sample_data[1] -= empty_y sample_data[1] -= empty_y
drift_value = sample_data.copy()[(2, 1), :] drift_value = sample_data.copy()[(2, 1), :]
@ -346,9 +355,10 @@ class DSCCalibrator:
offset = region[0, 0] offset = region[0, 0]
sample_data[1] -= m * (sample_data[2] - region[1, 0]) + offset sample_data[1] -= m * (sample_data[2] - region[1, 0]) + offset
line = np.array([[sample_data[2, 0], sample_data[2, -1]], line = np.array([
[m * (sample_data[2, 0] - region[1, 0]) + offset, [sample_data[2, 0], sample_data[2, -1]],
m * (sample_data[2, -1] - region[1, 0]) + offset]]) [m * (sample_data[2, 0] - region[1, 0]) + offset, m * (sample_data[2, -1] - region[1, 0]) + offset]
])
else: else:
line = np.array([[sample_data[2, 0], sample_data[2, -1]], [0, 0]]) line = np.array([[sample_data[2, 0], sample_data[2, -1]], [0, 0]])

View File

@ -247,6 +247,7 @@
<addaction name="action_no_range"/> <addaction name="action_no_range"/>
<addaction name="action_x_range"/> <addaction name="action_x_range"/>
<addaction name="action_custom_range"/> <addaction name="action_custom_range"/>
<addaction name="actionExclude_region"/>
</widget> </widget>
<addaction name="action_FitWidget"/> <addaction name="action_FitWidget"/>
<addaction name="separator"/> <addaction name="separator"/>
@ -1021,6 +1022,14 @@
<string>TNMH...</string> <string>TNMH...</string>
</property> </property>
</action> </action>
<action name="actionExclude_region">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Exclude region</string>
</property>
</action>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>

View File

@ -354,59 +354,26 @@
<property name="spacing"> <property name="spacing">
<number>3</number> <number>3</number>
</property> </property>
<item row="1" column="0"> <item row="1" column="7">
<widget class="QCheckBox" name="extrapolate_box">
<property name="toolTip">
<string>Extrapolates only main function</string>
</property>
<property name="text">
<string>Extrapolate curves</string>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QCheckBox" name="parameter_checkbox">
<property name="text">
<string>Plot parameter</string>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QComboBox" name="graph_comboBox"> <widget class="QComboBox" name="graph_comboBox">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="5">
<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 for parameter</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1"> <item row="1" column="1">
<widget class="QLineEdit" name="minx_line"> <widget class="QLineEdit" name="minx_line">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
@ -419,10 +386,45 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="4" rowspan="2"> <item row="1" column="0">
<widget class="Line" name="line_2"> <widget class="QCheckBox" name="extrapolate_box">
<property name="orientation"> <property name="toolTip">
<enum>Qt::Vertical</enum> <string>Extrapolates only main function</string>
</property>
<property name="text">
<string>Extrapolate curves</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLineEdit" name="numx_line">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="placeholderText">
<string># pts</string>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QCheckBox" name="graph_checkBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>New graph for parameter</string>
</property>
<property name="checked">
<bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
@ -432,7 +434,7 @@
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
@ -445,20 +447,33 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="3"> <item row="0" column="5" rowspan="2">
<widget class="QLineEdit" name="numx_line"> <widget class="Line" name="line_2">
<property name="enabled"> <property name="orientation">
<bool>false</bool> <enum>Qt::Vertical</enum>
</property>
<property name="placeholderText">
<string># pts</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0" colspan="4"> <item row="1" column="4">
<widget class="QCheckBox" name="newx_log_checkbox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>log-spaced?</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="5">
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<widget class="QCheckBox" name="curve_checkbox"> <widget class="QCheckBox" name="curve_checkbox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text"> <property name="text">
<string>Plot fit curve</string> <string>Plot fit curve</string>
</property> </property>
@ -469,6 +484,12 @@
</item> </item>
<item> <item>
<widget class="QCheckBox" name="partial_checkBox"> <widget class="QCheckBox" name="partial_checkBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text"> <property name="text">
<string>Plot partial functions</string> <string>Plot partial functions</string>
</property> </property>
@ -476,6 +497,19 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="0" column="6" colspan="2">
<widget class="QCheckBox" name="parameter_checkbox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Plot parameter</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>