Merge branch 'master' into 201-colors-partial-fits
This commit is contained in:
commit
42369267c9
@ -17,7 +17,7 @@ body:
|
||||
description: For which version have you observed this behavior?
|
||||
placeholder: You find the program version in "Help/About"
|
||||
validations:
|
||||
required: true
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
|
@ -365,6 +365,9 @@ class Ui_BaseWindow(object):
|
||||
self.actionBinning.setObjectName("actionBinning")
|
||||
self.actionTNMH = QtWidgets.QAction(BaseWindow)
|
||||
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.actionExportGraphic)
|
||||
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_x_range)
|
||||
self.menuLimits.addAction(self.action_custom_range)
|
||||
self.menuLimits.addAction(self.actionExclude_region)
|
||||
self.menuFit.addAction(self.action_FitWidget)
|
||||
self.menuFit.addSeparator()
|
||||
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.actionBinning.setText(_translate("BaseWindow", "Binning..."))
|
||||
self.actionTNMH.setText(_translate("BaseWindow", "TNMH..."))
|
||||
self.actionExclude_region.setText(_translate("BaseWindow", "Exclude region"))
|
||||
from ..data.datawidget.datawidget import DataWidget
|
||||
from ..data.integral_widget import IntegralWidget
|
||||
from ..data.point_select import PointSelectWidget
|
||||
|
@ -1,6 +1,6 @@
|
||||
# -*- 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
|
||||
#
|
||||
@ -157,67 +157,91 @@ class Ui_Dialog(object):
|
||||
self.gridLayout_2.setContentsMargins(3, 3, 3, 3)
|
||||
self.gridLayout_2.setSpacing(3)
|
||||
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.setEnabled(False)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.graph_comboBox.sizePolicy().hasHeightForWidth())
|
||||
self.graph_comboBox.setSizePolicy(sizePolicy)
|
||||
self.graph_comboBox.setObjectName("graph_comboBox")
|
||||
self.gridLayout_2.addWidget(self.graph_comboBox, 1, 6, 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.gridLayout_2.addWidget(self.graph_comboBox, 1, 7, 1, 1)
|
||||
self.minx_line = QtWidgets.QLineEdit(self.groupBox)
|
||||
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.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.minx_line.sizePolicy().hasHeightForWidth())
|
||||
self.minx_line.setSizePolicy(sizePolicy)
|
||||
self.minx_line.setObjectName("minx_line")
|
||||
self.gridLayout_2.addWidget(self.minx_line, 1, 1, 1, 1)
|
||||
self.line_2 = QtWidgets.QFrame(self.groupBox)
|
||||
self.line_2.setFrameShape(QtWidgets.QFrame.VLine)
|
||||
self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
self.line_2.setObjectName("line_2")
|
||||
self.gridLayout_2.addWidget(self.line_2, 0, 4, 2, 1)
|
||||
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.numx_line = QtWidgets.QLineEdit(self.groupBox)
|
||||
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.setEnabled(False)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.maxx_line.sizePolicy().hasHeightForWidth())
|
||||
self.maxx_line.setSizePolicy(sizePolicy)
|
||||
self.maxx_line.setObjectName("maxx_line")
|
||||
self.gridLayout_2.addWidget(self.maxx_line, 1, 2, 1, 1)
|
||||
self.numx_line = QtWidgets.QLineEdit(self.groupBox)
|
||||
self.numx_line.setEnabled(False)
|
||||
self.numx_line.setObjectName("numx_line")
|
||||
self.gridLayout_2.addWidget(self.numx_line, 1, 3, 1, 1)
|
||||
self.line_2 = QtWidgets.QFrame(self.groupBox)
|
||||
self.line_2.setFrameShape(QtWidgets.QFrame.VLine)
|
||||
self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
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.setObjectName("horizontalLayout")
|
||||
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.setObjectName("curve_checkbox")
|
||||
self.horizontalLayout.addWidget(self.curve_checkbox)
|
||||
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.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.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
|
||||
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.reject_fit_checkBox.setText(_translate("Dialog", "Reject this fit"))
|
||||
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.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.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.partial_checkBox.setText(_translate("Dialog", "Plot partial functions"))
|
||||
self.parameter_checkbox.setText(_translate("Dialog", "Plot parameter"))
|
||||
from ..lib.forms import ElideComboBox
|
||||
from pyqtgraph import GraphicsLayoutWidget
|
||||
|
@ -49,11 +49,16 @@ class DataTree(QtWidgets.QTreeWidget):
|
||||
|
||||
def add_graph(self, idd: str, name: str):
|
||||
item = QtWidgets.QTreeWidgetItem()
|
||||
item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsDropEnabled | QtCore.Qt.ItemIsEditable |
|
||||
QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable)
|
||||
item.setFlags(
|
||||
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.setData(0, QtCore.Qt.UserRole, idd)
|
||||
item.setCheckState(0, QtCore.Qt.Checked)
|
||||
item.setData(0, QtCore.Qt.ItemDataRole.UserRole, idd)
|
||||
item.setCheckState(0, QtCore.Qt.CheckState.Checked)
|
||||
|
||||
self.addTopLevelItem(item)
|
||||
self._checked_graphs.add(idd)
|
||||
@ -67,14 +72,19 @@ class DataTree(QtWidgets.QTreeWidget):
|
||||
|
||||
for row in range(self.invisibleRootItem().childCount()):
|
||||
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:
|
||||
item = QtWidgets.QTreeWidgetItem([name])
|
||||
item.setToolTip(0, f'Value: {value}')
|
||||
item.setData(0, QtCore.Qt.UserRole, idd)
|
||||
item.setCheckState(0, QtCore.Qt.Checked)
|
||||
item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsEditable |
|
||||
QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable)
|
||||
item.setData(0, QtCore.Qt.ItemDataRole.UserRole, idd)
|
||||
item.setCheckState(0, QtCore.Qt.CheckState.Checked)
|
||||
item.setFlags(
|
||||
QtCore.Qt.ItemFlag.ItemIsSelectable |
|
||||
QtCore.Qt.ItemFlag.ItemIsDragEnabled |
|
||||
QtCore.Qt.ItemFlag.ItemIsEditable |
|
||||
QtCore.Qt.ItemFlag.ItemIsEnabled |
|
||||
QtCore.Qt.ItemFlag.ItemIsUserCheckable
|
||||
)
|
||||
graph.addChild(item)
|
||||
self._checked_sets.add(idd)
|
||||
|
||||
@ -85,8 +95,8 @@ class DataTree(QtWidgets.QTreeWidget):
|
||||
|
||||
@QtCore.pyqtSlot(QtWidgets.QTreeWidgetItem)
|
||||
def data_change(self, item: QtWidgets.QTreeWidgetItem, emit: bool = True) -> tuple[set, set]:
|
||||
idd = item.data(0, QtCore.Qt.UserRole)
|
||||
is_selected = item.checkState(0) == QtCore.Qt.Checked
|
||||
idd = item.data(0, QtCore.Qt.ItemDataRole.UserRole)
|
||||
is_selected = item.checkState(0) == QtCore.Qt.CheckState.Checked
|
||||
to_be_hidden = set()
|
||||
to_be_shown = set()
|
||||
|
||||
@ -104,9 +114,9 @@ class DataTree(QtWidgets.QTreeWidget):
|
||||
self.blockSignals(True)
|
||||
for i in range(item.childCount()):
|
||||
child = item.child(i)
|
||||
child.setCheckState(0, QtCore.Qt.Checked)
|
||||
to_be_shown.add(child.data(0, QtCore.Qt.UserRole))
|
||||
self._checked_sets.add(child.data(0, QtCore.Qt.UserRole))
|
||||
child.setCheckState(0, QtCore.Qt.CheckState.Checked)
|
||||
to_be_shown.add(child.data(0, QtCore.Qt.ItemDataRole.UserRole))
|
||||
self._checked_sets.add(child.data(0, QtCore.Qt.ItemDataRole.UserRole))
|
||||
self.blockSignals(False)
|
||||
|
||||
# check state change to unchecked
|
||||
@ -115,10 +125,10 @@ class DataTree(QtWidgets.QTreeWidget):
|
||||
self.blockSignals(True)
|
||||
for i in range(item.childCount()):
|
||||
child = item.child(i)
|
||||
child.setCheckState(0, QtCore.Qt.Unchecked)
|
||||
to_be_hidden.add(child.data(0, QtCore.Qt.UserRole))
|
||||
child.setCheckState(0, QtCore.Qt.CheckState.Unchecked)
|
||||
to_be_hidden.add(child.data(0, QtCore.Qt.ItemDataRole.UserRole))
|
||||
try:
|
||||
self._checked_sets.remove(child.data(0, QtCore.Qt.UserRole))
|
||||
self._checked_sets.remove(child.data(0, QtCore.Qt.ItemDataRole.UserRole))
|
||||
except KeyError:
|
||||
pass
|
||||
self.blockSignals(False)
|
||||
@ -153,7 +163,7 @@ class DataTree(QtWidgets.QTreeWidget):
|
||||
@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))
|
||||
self.management.select_window(item.data(0, QtCore.Qt.ItemDataRole.UserRole))
|
||||
|
||||
def dropEvent(self, evt: QtGui.QDropEvent):
|
||||
dropped_index = self.indexAt(evt.pos())
|
||||
@ -179,7 +189,7 @@ class DataTree(QtWidgets.QTreeWidget):
|
||||
|
||||
from_parent.removeChild(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)
|
||||
if self.dropIndicatorPosition() == QtWidgets.QAbstractItemView.BelowItem:
|
||||
@ -191,8 +201,8 @@ class DataTree(QtWidgets.QTreeWidget):
|
||||
else:
|
||||
to_parent.insertChildren(row, tobemoved)
|
||||
|
||||
self.management.move_sets([it.data(0, QtCore.Qt.UserRole) for it in tobemoved],
|
||||
to_parent.data(0, QtCore.Qt.UserRole), take_from,
|
||||
self.management.move_sets([it.data(0, QtCore.Qt.ItemDataRole.UserRole) for it in tobemoved],
|
||||
to_parent.data(0, QtCore.Qt.ItemDataRole.UserRole), take_from,
|
||||
pos=-1 if append else row)
|
||||
|
||||
self.update_indexes()
|
||||
@ -207,7 +217,7 @@ class DataTree(QtWidgets.QTreeWidget):
|
||||
while iterator.value():
|
||||
item = iterator.value()
|
||||
if item is not None:
|
||||
data = item.data(0, QtCore.Qt.UserRole)
|
||||
data = item.data(0, QtCore.Qt.ItemDataRole.UserRole)
|
||||
if data == gid_out:
|
||||
from_parent = item
|
||||
|
||||
@ -231,7 +241,7 @@ class DataTree(QtWidgets.QTreeWidget):
|
||||
self.blockSignals(False)
|
||||
|
||||
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 = [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 c in children:
|
||||
if c.data(0, QtCore.Qt.UserRole) == s:
|
||||
if c.data(0, QtCore.Qt.ItemDataRole.UserRole) == s:
|
||||
graph_item.addChild(c)
|
||||
|
||||
self.update_indexes()
|
||||
@ -276,7 +286,7 @@ class DataTree(QtWidgets.QTreeWidget):
|
||||
while iterator.value():
|
||||
item = iterator.value()
|
||||
if item is not None:
|
||||
data = item.data(0, QtCore.Qt.UserRole)
|
||||
data = item.data(0, QtCore.Qt.ItemDataRole.UserRole)
|
||||
if data == sid:
|
||||
if name != item.text(0):
|
||||
item.setText(0, name)
|
||||
@ -285,7 +295,7 @@ class DataTree(QtWidgets.QTreeWidget):
|
||||
iterator += 1
|
||||
|
||||
def keyPressEvent(self, evt: QtGui.QKeyEvent):
|
||||
if evt.key() == QtCore.Qt.Key_Delete:
|
||||
if evt.key() == QtCore.Qt.Key.Key_Delete:
|
||||
rm_sets = []
|
||||
rm_graphs = []
|
||||
for idx in self.selectedIndexes():
|
||||
@ -296,20 +306,20 @@ class DataTree(QtWidgets.QTreeWidget):
|
||||
if item.parent() is None:
|
||||
for c_i in range(item.childCount()):
|
||||
# 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:
|
||||
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:
|
||||
item_data = item.data(0, QtCore.Qt.UserRole)
|
||||
item_data = item.data(0, QtCore.Qt.ItemDataRole.UserRole)
|
||||
if item_data not in rm_sets:
|
||||
rm_sets.append(item_data)
|
||||
|
||||
# self.deleteItem.emit(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 = []
|
||||
from_parent = []
|
||||
|
||||
@ -329,7 +339,7 @@ class DataTree(QtWidgets.QTreeWidget):
|
||||
for it in sets:
|
||||
if it in from_parent:
|
||||
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)
|
||||
to_be_hidden |= s2
|
||||
to_be_shown |= s1
|
||||
@ -353,7 +363,7 @@ class DataTree(QtWidgets.QTreeWidget):
|
||||
# find all items that have to be removed
|
||||
while iterator.value():
|
||||
item = iterator.value()
|
||||
_id = item.data(0, QtCore.Qt.UserRole)
|
||||
_id = item.data(0, QtCore.Qt.ItemDataRole.UserRole)
|
||||
if _id in ids:
|
||||
try:
|
||||
item_parent = item.parent()
|
||||
@ -431,7 +441,7 @@ class DataTree(QtWidgets.QTreeWidget):
|
||||
if i.column() == 0:
|
||||
continue
|
||||
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:
|
||||
for gid in graphs:
|
||||
@ -473,12 +483,12 @@ class DataTree(QtWidgets.QTreeWidget):
|
||||
continue
|
||||
|
||||
else:
|
||||
graph_id = parent.data(0, QtCore.Qt.UserRole)
|
||||
graph_id = parent.data(0, QtCore.Qt.ItemDataRole.UserRole)
|
||||
if graph_id not in idx:
|
||||
idx[graph_id] = []
|
||||
# collect sets in their graph
|
||||
idx[graph_id].append(item.data(0, QtCore.Qt.UserRole))
|
||||
data = self.management[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.ItemDataRole.UserRole)]
|
||||
if data.mode == 'fit':
|
||||
has_fits = True
|
||||
|
||||
@ -523,7 +533,7 @@ class DataTree(QtWidgets.QTreeWidget):
|
||||
while iterator.value():
|
||||
item = iterator.value()
|
||||
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')))
|
||||
else:
|
||||
item.setBackground(0, QtGui.QBrush())
|
||||
@ -536,10 +546,10 @@ class DataTree(QtWidgets.QTreeWidget):
|
||||
while iterator.value():
|
||||
item = iterator.value()
|
||||
if item is not None:
|
||||
if item.data(0, QtCore.Qt.UserRole) in sets:
|
||||
item.setCheckState(0, QtCore.Qt.Unchecked)
|
||||
if item.data(0, QtCore.Qt.ItemDataRole.UserRole) in sets:
|
||||
item.setCheckState(0, QtCore.Qt.CheckState.Unchecked)
|
||||
else:
|
||||
self._checked_sets.add(item.data(0, QtCore.Qt.UserRole))
|
||||
self._checked_sets.add(item.data(0, QtCore.Qt.ItemDataRole.UserRole))
|
||||
iterator += 1
|
||||
self.blockSignals(False)
|
||||
|
||||
@ -594,7 +604,7 @@ class DataWidget(QtWidgets.QWidget, Ui_DataWidget):
|
||||
sid = []
|
||||
for i in self.tree.selectedIndexes():
|
||||
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)
|
||||
|
||||
@ -603,15 +613,23 @@ class DataWidget(QtWidgets.QWidget, Ui_DataWidget):
|
||||
self.proptable.populate(props)
|
||||
|
||||
def change_property(self, key1, key2, value):
|
||||
ids = [item.data(0, QtCore.Qt.UserRole) for item in self.tree.selectedItems()]
|
||||
if key2 == 'Value':
|
||||
try:
|
||||
value = float(value)
|
||||
except ValueError:
|
||||
QtWidgets.QMessageBox.warning(self, 'Invalid entry',
|
||||
'Value %r is not a valid number for `value`.' % value)
|
||||
QtWidgets.QMessageBox.warning(
|
||||
self,
|
||||
'Invalid entry',
|
||||
f'Value {value!r} is not a valid number for `value`.')
|
||||
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)
|
||||
|
||||
def uncheck_sets(self, sets: list[str]):
|
||||
|
@ -41,7 +41,7 @@ class PropWidget(QtWidgets.QWidget):
|
||||
idx = table.indexFromItem(item)
|
||||
self.propertyChanged.emit(self.tab.tabText(tab_idx),
|
||||
table.item(idx.row(), idx.column()-1).text(),
|
||||
item.data(QtCore.Qt.DisplayRole))
|
||||
item.data(QtCore.Qt.ItemDataRole.DisplayRole))
|
||||
|
||||
@QtCore.pyqtSlot(int)
|
||||
def tab_change(self, idx: int):
|
||||
@ -66,10 +66,10 @@ class PropTable(QtWidgets.QTableWidget):
|
||||
self.blockSignals(True)
|
||||
for k, v in prop.items():
|
||||
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.setFlags(QtCore.Qt.NoItemFlags)
|
||||
key_item.setFlags(QtCore.Qt.ItemFlag.NoItemFlags)
|
||||
key_item.setForeground(QtGui.QBrush(QtGui.QColor(0, 0, 0)))
|
||||
|
||||
self.setRowCount(self.rowCount()+1)
|
||||
|
@ -3,10 +3,10 @@ from __future__ import annotations
|
||||
from typing import Any
|
||||
|
||||
from numpy import ndarray, iscomplexobj, asarray
|
||||
from pyqtgraph import PlotDataItem
|
||||
|
||||
from ..Qt import QtGui, QtCore, QtWidgets
|
||||
from .._py.valueeditor import Ui_MaskDialog
|
||||
from ..lib.pg_objects import PlotItem
|
||||
|
||||
|
||||
class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog):
|
||||
@ -35,13 +35,13 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog):
|
||||
|
||||
self.tableView.setModel(self.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.selection_real = PlotDataItem(x=[], y=[], symbolSize=25, symbol='x',
|
||||
pen=None, symbolPen='#c9308e', symbolBrush='#c9308e')
|
||||
self.selection_imag = PlotDataItem(x=[], y=[], symbolSize=25, symbol='+',
|
||||
pen=None, symbolPen='#dcdcdc', symbolBrush='#dcdcdc')
|
||||
self.selection_real = PlotItem(x=[], y=[], symbolSize=25, symbol='x',
|
||||
pen=None, symbolPen='#c9308e', symbolBrush='#c9308e')
|
||||
self.selection_imag = PlotItem(x=[], y=[], symbolSize=25, symbol='+',
|
||||
pen=None, symbolPen='#dcdcdc', symbolBrush='#dcdcdc')
|
||||
|
||||
def __call__(self, items: dict):
|
||||
self.items = items
|
||||
@ -133,7 +133,7 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog):
|
||||
def keyPressEvent(self, evt):
|
||||
if evt.matches(QtGui.QKeySequence.Copy):
|
||||
self.copy_selection()
|
||||
elif evt.key() == QtCore.Qt.Key_Delete:
|
||||
elif evt.key() == QtCore.Qt.Key.Key_Delete:
|
||||
self.delete_item()
|
||||
else:
|
||||
super().keyPressEvent(evt)
|
||||
@ -229,7 +229,7 @@ class ValueModel(QtCore.QAbstractTableModel):
|
||||
"""
|
||||
itemChanged = QtCore.pyqtSignal(int, int, str)
|
||||
load_number = 20
|
||||
maskRole = QtCore.Qt.UserRole+321
|
||||
maskRole = QtCore.Qt.ItemDataRole.UserRole+321
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
@ -240,7 +240,7 @@ class ValueModel(QtCore.QAbstractTableModel):
|
||||
self.mask = None
|
||||
self.headers = ['x', 'y', '\u0394y']
|
||||
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:
|
||||
return self.total_rows
|
||||
@ -258,25 +258,28 @@ class ValueModel(QtCore.QAbstractTableModel):
|
||||
self.mask = mask.tolist()
|
||||
|
||||
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():
|
||||
return
|
||||
|
||||
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()]
|
||||
return self.as_string(val)
|
||||
|
||||
elif role == QtCore.Qt.BackgroundRole:
|
||||
elif role == QtCore.Qt.ItemDataRole.BackgroundRole:
|
||||
pal = QtGui.QGuiApplication.palette()
|
||||
if not self.mask[row]:
|
||||
return pal.color(QtGui.QPalette.Disabled, QtGui.QPalette.Base)
|
||||
else:
|
||||
return pal.color(QtGui.QPalette.Base)
|
||||
|
||||
elif role == QtCore.Qt.ForegroundRole:
|
||||
elif role == QtCore.Qt.ItemDataRole.ForegroundRole:
|
||||
pal = QtGui.QGuiApplication.palette()
|
||||
if not self.mask[row]:
|
||||
return pal.color(QtGui.QPalette.Disabled, QtGui.QPalette.Text)
|
||||
@ -289,7 +292,7 @@ class ValueModel(QtCore.QAbstractTableModel):
|
||||
else:
|
||||
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()
|
||||
|
||||
if role == ValueModel.maskRole:
|
||||
@ -299,7 +302,7 @@ class ValueModel(QtCore.QAbstractTableModel):
|
||||
return True
|
||||
|
||||
if value:
|
||||
if role == QtCore.Qt.EditRole:
|
||||
if role == QtCore.Qt.ItemDataRole.EditRole:
|
||||
if value == self.as_string(self._data[row][col]):
|
||||
return True
|
||||
|
||||
@ -322,9 +325,9 @@ class ValueModel(QtCore.QAbstractTableModel):
|
||||
else:
|
||||
return False
|
||||
|
||||
def headerData(self, section: int, orientation, role=QtCore.Qt.DisplayRole) -> Any:
|
||||
if role == QtCore.Qt.DisplayRole:
|
||||
if orientation == QtCore.Qt.Horizontal:
|
||||
def headerData(self, section: int, orientation, role=QtCore.Qt.ItemDataRole.DisplayRole) -> Any:
|
||||
if role == QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
if orientation == QtCore.Qt.Orientation.Horizontal:
|
||||
return self.headers[section]
|
||||
else:
|
||||
return str(section+1)
|
||||
@ -346,7 +349,7 @@ class ValueModel(QtCore.QAbstractTableModel):
|
||||
self.endInsertRows()
|
||||
|
||||
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:
|
||||
self.beginRemoveRows(parent, pos, pos+rows-1)
|
||||
|
@ -136,8 +136,8 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
|
||||
max_x = max(max_x, data.x.max())
|
||||
|
||||
item = QtWidgets.QListWidgetItem(name)
|
||||
item.setCheckState(QtCore.Qt.Checked)
|
||||
item.setData(QtCore.Qt.UserRole, key)
|
||||
item.setCheckState(QtCore.Qt.CheckState.Checked)
|
||||
item.setData(QtCore.Qt.ItemDataRole.UserRole, key)
|
||||
item.setForeground(mkBrush(c.rgb()))
|
||||
self.listWidget.addItem(item)
|
||||
|
||||
@ -191,10 +191,10 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
|
||||
|
||||
for idx in range(self.listWidget.count()):
|
||||
item = self.listWidget.item(idx)
|
||||
if item.checkState() == QtCore.Qt.Unchecked:
|
||||
if item.checkState() == QtCore.Qt.CheckState.Unchecked:
|
||||
continue
|
||||
|
||||
key = item.data(QtCore.Qt.UserRole)
|
||||
key = item.data(QtCore.Qt.ItemDataRole.UserRole)
|
||||
plot = self._plots[key]
|
||||
data, _ = self._dsc[key]
|
||||
|
||||
@ -214,7 +214,7 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
|
||||
item = self.listWidget.item(idx)
|
||||
|
||||
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:
|
||||
for name, pos in values.items():
|
||||
@ -223,7 +223,7 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
|
||||
|
||||
self.tg_tree.addTopLevelItem(tree_item)
|
||||
|
||||
key = item.data(QtCore.Qt.UserRole)
|
||||
key = item.data(QtCore.Qt.ItemDataRole.UserRole)
|
||||
plot = self._plots[key]
|
||||
data, _ = self._dsc[key]
|
||||
|
||||
@ -251,7 +251,7 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
|
||||
@QtCore.pyqtSlot(QtWidgets.QListWidgetItem)
|
||||
def change_visibility(self, item: QtWidgets.QListWidgetItem):
|
||||
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:
|
||||
val.setVisible(is_checked)
|
||||
|
||||
@ -275,10 +275,10 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
|
||||
self.tnmh_tree.clear()
|
||||
for idx in range(self.listWidget.count()):
|
||||
item = self.listWidget.item(idx)
|
||||
if item.checkState() == QtCore.Qt.Unchecked:
|
||||
if item.checkState() == QtCore.Qt.CheckState.Unchecked:
|
||||
continue
|
||||
|
||||
key = item.data(QtCore.Qt.UserRole)
|
||||
key = item.data(QtCore.Qt.ItemDataRole.UserRole)
|
||||
|
||||
data = self.get_fictive(key, baselines)
|
||||
|
||||
@ -292,7 +292,7 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
|
||||
item = self.listWidget.item(idx)
|
||||
|
||||
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:
|
||||
child_item = QtWidgets.QTreeWidgetItem([values.parameter_string()])
|
||||
@ -305,10 +305,10 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
|
||||
ret_dic = {}
|
||||
for idx in range(self.listWidget.count()):
|
||||
item = self.listWidget.item(idx)
|
||||
if item.checkState() == QtCore.Qt.Unchecked:
|
||||
if item.checkState() == QtCore.Qt.CheckState.Unchecked:
|
||||
continue
|
||||
|
||||
key = item.data(QtCore.Qt.UserRole)
|
||||
key = item.data(QtCore.Qt.ItemDataRole.UserRole)
|
||||
|
||||
cp = None
|
||||
if self.fictive_export_check.isChecked():
|
||||
@ -332,10 +332,10 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
|
||||
m = []
|
||||
for idx in range(self.listWidget.count()):
|
||||
item = self.listWidget.item(idx)
|
||||
if item.checkState() == QtCore.Qt.Unchecked:
|
||||
if item.checkState() == QtCore.Qt.CheckState.Unchecked:
|
||||
continue
|
||||
|
||||
key = item.data(QtCore.Qt.UserRole)
|
||||
key = item.data(QtCore.Qt.ItemDataRole.UserRole)
|
||||
data, _ = self._dsc[key]
|
||||
try:
|
||||
tg_value = self._tg_value[key][tg_type][0]
|
||||
|
@ -58,7 +58,8 @@ class FitToolbar(QtWidgets.QToolBar):
|
||||
|
||||
@QtCore.pyqtSlot(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]:
|
||||
w.setEnabled(is_custom)
|
||||
@ -93,5 +94,6 @@ class FitToolbar(QtWidgets.QToolBar):
|
||||
return {
|
||||
'None': 'none',
|
||||
'Visible x range': 'x',
|
||||
'Custom': self.region.getRegion(),
|
||||
'Custom': ('in', self.region.getRegion()),
|
||||
'Exclude region': ('out', self.region.getRegion()),
|
||||
}[action_text]
|
||||
|
@ -1,3 +1,5 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from math import isnan
|
||||
|
||||
from pyqtgraph import mkBrush, mkPen, mkColor
|
||||
@ -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.minx_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._opts = []
|
||||
@ -363,7 +366,7 @@ class QFitResult(QtWidgets.QDialog, Ui_Dialog):
|
||||
|
||||
parts = self.partial_checkBox.checkState() == QtCore.Qt.CheckState.Checked
|
||||
|
||||
extrapolate = [None, None, None]
|
||||
extrapolate = [None, None, None, None]
|
||||
error = []
|
||||
if self.extrapolate_box.isChecked():
|
||||
try:
|
||||
@ -379,6 +382,8 @@ class QFitResult(QtWidgets.QDialog, Ui_Dialog):
|
||||
except (TypeError, ValueError):
|
||||
error.append('Number of points is missing')
|
||||
|
||||
extrapolate[3] = self.newx_log_checkbox.isChecked()
|
||||
|
||||
if error:
|
||||
msg = QtWidgets.QMessageBox.warning(self, 'Error', 'Extrapolation failed because:\n' + '\n'.join(error))
|
||||
return
|
||||
@ -416,10 +421,13 @@ class FitExtension(QtWidgets.QDialog):
|
||||
self.num_pts.setValidator(QtGui.QIntValidator())
|
||||
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.setOrientation(QtCore.Qt.Orientation.Horizontal)
|
||||
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)
|
||||
|
||||
@ -427,12 +435,13 @@ class FitExtension(QtWidgets.QDialog):
|
||||
self.buttonBox.rejected.connect(self.reject)
|
||||
|
||||
@property
|
||||
def values(self):
|
||||
def values(self) -> tuple[float, float, int, bool] | None:
|
||||
try:
|
||||
xmin = float(self.min_line.text())
|
||||
xmax = float(self.max_line.text())
|
||||
nums = int(self.num_pts.text())
|
||||
logx = self.logx_checkbox.isChecked()
|
||||
except TypeError:
|
||||
return None
|
||||
|
||||
return xmin, xmax, nums
|
||||
return xmin, xmax, nums, logx
|
||||
|
@ -670,11 +670,14 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow):
|
||||
|
||||
else:
|
||||
if os.path.exists(outfile):
|
||||
if QtWidgets.QMessageBox.warning(self, 'Export graphic',
|
||||
f'{os.path.split(outfile)[1]} already exists.\n'
|
||||
f'Do you REALLY want to replace it?',
|
||||
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
|
||||
QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No:
|
||||
if QtWidgets.QMessageBox.warning(
|
||||
self,
|
||||
'Export graphic',
|
||||
f'{os.path.split(outfile)[1]} already exists.\n'
|
||||
f'Do you REALLY want to replace it?',
|
||||
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
|
||||
QtWidgets.QMessageBox.No
|
||||
) == QtWidgets.QMessageBox.No:
|
||||
return
|
||||
|
||||
bg_color = self._bgcolor
|
||||
@ -716,16 +719,20 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow):
|
||||
logger.exception(f'{item} could not exported because {e.args}')
|
||||
continue
|
||||
|
||||
if len(item) == 2:
|
||||
# plot can show errorbars
|
||||
item_dic['yerr'] = item[1].opts['topData']
|
||||
|
||||
if item_dic:
|
||||
if len(item) == 2:
|
||||
# plot can show errorbars
|
||||
if len(item_dic['x']):
|
||||
item_dic['yerr'] = item[1].opts['topData']
|
||||
else:
|
||||
item_dic['yerr'] = []
|
||||
dic['items'].append(item_dic)
|
||||
|
||||
for item in self._external_items:
|
||||
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:
|
||||
logger.exception(f'{item} could not be exported because {e.args}')
|
||||
continue
|
||||
|
@ -38,7 +38,7 @@ class QAsciiReader(QtWidgets.QDialog, Ui_ascii_reader):
|
||||
self.changestaggeredrange(0)
|
||||
|
||||
self.ascii_table.contextMenuEvent = self.ctx_table
|
||||
self.ascii_table.horizontalHeader().setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
||||
self.ascii_table.horizontalHeader().setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.CustomContextMenu)
|
||||
self.ascii_table.horizontalHeader().customContextMenuRequested.connect(self.ctx_table)
|
||||
|
||||
self.skip = False
|
||||
@ -65,7 +65,7 @@ class QAsciiReader(QtWidgets.QDialog, Ui_ascii_reader):
|
||||
self.set_column_names(1)
|
||||
|
||||
self.skippy_checkbox.blockSignals(True)
|
||||
self.skippy_checkbox.setCheckState(QtCore.Qt.Unchecked)
|
||||
self.skippy_checkbox.setCheckState(QtCore.Qt.CheckState.Unchecked)
|
||||
self.skippy_checkbox.blockSignals(False)
|
||||
|
||||
return self
|
||||
@ -232,7 +232,7 @@ class QAsciiReader(QtWidgets.QDialog, Ui_ascii_reader):
|
||||
|
||||
@QtCore.pyqtSlot(int, name='on_buttonGroup_buttonClicked')
|
||||
def show_error(self, val: int):
|
||||
self.deltay_lineEdit.setEnabled(val == -3)
|
||||
self.deltay_lineEdit.setEnabled(val == -2)
|
||||
|
||||
@QtCore.pyqtSlot(int, name='on_skippy_checkbox_stateChanged')
|
||||
def skip_next_dial(self, _: int):
|
||||
|
@ -78,14 +78,22 @@ class QDSCReader(QtWidgets.QDialog, Ui_Dialog):
|
||||
|
||||
for opts in self.sample.steps:
|
||||
item = QtWidgets.QListWidgetItem()
|
||||
item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable)
|
||||
item.setCheckState(QtCore.Qt.Unchecked)
|
||||
item.setFlags(
|
||||
QtCore.Qt.ItemFlag.ItemIsEnabled |
|
||||
QtCore.Qt.ItemFlag.ItemIsSelectable |
|
||||
QtCore.Qt.ItemFlag.ItemIsUserCheckable
|
||||
)
|
||||
item.setCheckState(QtCore.Qt.CheckState.Unchecked)
|
||||
|
||||
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')
|
||||
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')
|
||||
|
||||
self.step_listWidget.addItem(item)
|
||||
@ -97,7 +105,12 @@ class QDSCReader(QtWidgets.QDialog, Ui_Dialog):
|
||||
|
||||
if empty:
|
||||
self.empty = self.calibrator.set_measurement(empty, mode='empty')
|
||||
self.empty_label.setText('~/' + str(self.empty.fname.relative_to(Path.home())))
|
||||
|
||||
# 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())))
|
||||
else:
|
||||
self.empty_label.setText(str(self.empty.fname))
|
||||
|
||||
self.update_plots()
|
||||
|
||||
@ -118,8 +131,8 @@ class QDSCReader(QtWidgets.QDialog, Ui_Dialog):
|
||||
|
||||
self.references.append(ref)
|
||||
item = QtWidgets.QTableWidgetItem(str(ref.fname.name))
|
||||
item.setData(QtCore.Qt.UserRole, ref.fname)
|
||||
item.setFlags(QtCore.Qt.ItemIsEnabled)
|
||||
item.setData(QtCore.Qt.ItemDataRole.UserRole, ref.fname)
|
||||
item.setFlags(QtCore.Qt.ItemFlag.ItemIsEnabled)
|
||||
|
||||
rowcnt = self.reference_tableWidget.rowCount()
|
||||
self.reference_tableWidget.setRowCount(rowcnt+1)
|
||||
@ -132,7 +145,7 @@ class QDSCReader(QtWidgets.QDialog, Ui_Dialog):
|
||||
@QtCore.pyqtSlot(name='on_ref_remove_pushButton_clicked')
|
||||
def remove_reference(self):
|
||||
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.update_plots()
|
||||
@ -145,10 +158,10 @@ class QDSCReader(QtWidgets.QDialog, Ui_Dialog):
|
||||
for row in range(self.step_listWidget.count()):
|
||||
if idx == row:
|
||||
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)
|
||||
|
||||
if item.checkState() == QtCore.Qt.Checked:
|
||||
if item.checkState() == QtCore.Qt.CheckState.Checked:
|
||||
mode, rate, _, _ = self.sample.steps[idx]
|
||||
self.current_run = (rate, mode)
|
||||
self.sample_idx = idx
|
||||
@ -217,6 +230,8 @@ class QDSCReader(QtWidgets.QDialog, Ui_Dialog):
|
||||
|
||||
if empty_data is not None:
|
||||
self.empty_sample.setData(x=empty_data[0], y=empty_data[1])
|
||||
else:
|
||||
self.empty_sample.setData(x=[], y=[])
|
||||
|
||||
self.calib_graph.clear()
|
||||
|
||||
@ -249,11 +264,16 @@ class QDSCReader(QtWidgets.QDialog, Ui_Dialog):
|
||||
except TypeError:
|
||||
return
|
||||
|
||||
if self.cp_checkBox.isChecked() and self.references:
|
||||
y_label = 'cp'
|
||||
else:
|
||||
y_label = 'q'
|
||||
|
||||
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:
|
||||
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
|
||||
else:
|
||||
self.data_read.emit([new_val])
|
||||
|
@ -1,5 +1,8 @@
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
from .codeeditor import _make_textformats
|
||||
from ..Qt import QtWidgets, QtCore, QtGui
|
||||
from nmreval.configs import config_paths
|
||||
@ -113,3 +116,27 @@ class QLog(QtWidgets.QDialog):
|
||||
|
||||
for lines in text[-100:]:
|
||||
self.plainTextEdit.appendPlainText(lines[:-1])
|
||||
|
||||
|
||||
class ConsoleDock(QtWidgets.QDockWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
|
||||
self.code = QtWidgets.QPlainTextEdit(parent)
|
||||
self.code.highlight = LogHighlighter(self.code.document())
|
||||
self.code.setReadOnly(True)
|
||||
self.code.setMaximumBlockCount(50)
|
||||
self.setWidget(self.code)
|
||||
|
||||
|
||||
class QTextHandler(logging.Handler):
|
||||
def __init__(self, parent):
|
||||
super().__init__()
|
||||
|
||||
self.console = ConsoleDock(parent)
|
||||
self.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
|
||||
|
||||
def emit(self, record):
|
||||
msg = self.format(record)
|
||||
self.console.code.appendPlainText(msg)
|
||||
self.console.show()
|
||||
|
@ -183,6 +183,8 @@ class PlotItem(PlotDataItem):
|
||||
brush = self.opts['symbolBrush']
|
||||
if isinstance(brush, tuple):
|
||||
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:
|
||||
c = brush.color()
|
||||
self.opts['symbolcolor'] = c.red(), c.green(), c.blue()
|
||||
@ -340,7 +342,8 @@ class PlotItem(PlotDataItem):
|
||||
|
||||
opts = self.opts
|
||||
item_dic = {
|
||||
'x': x, 'y': y,
|
||||
'x': x,
|
||||
'y': y,
|
||||
'name': opts.get('name', ''),
|
||||
'symbolsize': opts['symbolSize'],
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ from ..Qt import QtGui, QtWidgets, QtCore
|
||||
@contextmanager
|
||||
def busy_cursor():
|
||||
try:
|
||||
cursor = QtGui.QCursor(QtCore.Qt.ForbiddenCursor)
|
||||
cursor = QtGui.QCursor(QtCore.Qt.CursorShape.ForbiddenCursor)
|
||||
QtWidgets.QApplication.setOverrideCursor(cursor)
|
||||
yield
|
||||
|
||||
|
3
src/gui_qt/main/console.py
Normal file
3
src/gui_qt/main/console.py
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
|
||||
|
@ -12,6 +12,7 @@ from nmreval.lib.logger import logger
|
||||
from nmreval.io.sessionwriter import NMRWriter
|
||||
|
||||
from .management import UpperManagement
|
||||
from ..lib.logger import ConsoleDock, QTextHandler
|
||||
from ..Qt import QtGui, QtPrintSupport
|
||||
from ..data.shift_graphs import QShift
|
||||
from ..data.signaledit import QPreviewDialog, QBaselineDialog
|
||||
@ -62,6 +63,11 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
|
||||
self.eval = None
|
||||
self.editor = None
|
||||
|
||||
self.logtext = QTextHandler(self)
|
||||
logger.addHandler(self.logtext)
|
||||
self.addDockWidget(QtCore.Qt.DockWidgetArea.BottomDockWidgetArea, self.logtext.console)
|
||||
self.logtext.console.hide()
|
||||
|
||||
self.movedialog = QMover(self)
|
||||
|
||||
self.current_graph_widget = None
|
||||
@ -888,7 +894,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
|
||||
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():
|
||||
if self.action_custom_range.isChecked() or self.actionExclude_region.isChecked():
|
||||
self.current_graph_widget.add_external(self.fit_toolbar.region)
|
||||
|
||||
block_window = True
|
||||
@ -904,7 +910,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
|
||||
if self.current_graph_widget is None:
|
||||
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)
|
||||
else:
|
||||
self.current_graph_widget.remove_external(self.fit_toolbar.region)
|
||||
@ -984,7 +990,8 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
|
||||
res = w.exec()
|
||||
if res:
|
||||
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)
|
||||
|
||||
@QtCore.pyqtSlot(name='on_action_create_fit_function_triggered')
|
||||
|
@ -503,27 +503,44 @@ class UpperManagement(QtCore.QObject):
|
||||
we = we_option
|
||||
|
||||
if m_complex is None or m_complex == 1:
|
||||
# model is not complex: m_complex = None
|
||||
# model is complex, fit real part: m_complex = 1
|
||||
_y = data_i.y.real
|
||||
elif m_complex == 2 and np.iscomplexobj(data_i.y):
|
||||
_y = data_i.y.imag
|
||||
data_complex = 1
|
||||
elif m_complex == 2:
|
||||
# model is complex, fit imag part: m_complex = 2
|
||||
if np.iscomplexobj(data_i.y):
|
||||
# data is complex, use imag part
|
||||
_y = data_i.y.imag
|
||||
data_complex = 2
|
||||
else:
|
||||
# data is real
|
||||
_y = data_i.y
|
||||
data_complex = 1
|
||||
else:
|
||||
# model is complex, fit complex: m_complex = 0
|
||||
# use data as given (complex or not)
|
||||
_y = data_i.y
|
||||
data_complex = 0
|
||||
|
||||
_x = data_i.x
|
||||
|
||||
# options for fit limits 'none', 'x', ('in', custom region), ('out', excluded region)
|
||||
if fit_limits == 'none':
|
||||
inside = slice(None)
|
||||
elif fit_limits == 'x':
|
||||
x_lim, _ = self.graphs[self.current_graph].ranges
|
||||
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:
|
||||
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:
|
||||
if isinstance(we, str):
|
||||
d = fit_d.Data(_x[inside], _y[inside], we=we, idx=set_id)
|
||||
d = fit_d.Data(_x[inside], _y[inside], we=we, idx=set_id, complex_type=data_complex)
|
||||
else:
|
||||
d = fit_d.Data(_x[inside], _y[inside], we=we[inside], idx=set_id)
|
||||
d = fit_d.Data(_x[inside], _y[inside], we=we[inside], idx=set_id, complex_type=data_complex)
|
||||
except Exception as e:
|
||||
raise Exception(f'Setting data failed for {set_id}')
|
||||
|
||||
@ -623,7 +640,7 @@ class UpperManagement(QtCore.QObject):
|
||||
continue
|
||||
|
||||
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()
|
||||
xmax = fit.x.max()
|
||||
|
@ -12,10 +12,10 @@ class QSmooth(QtWidgets.QDialog, Ui_SmoothDialog):
|
||||
|
||||
@QtCore.pyqtSlot(int, name='on_comboBox_currentIndexChanged')
|
||||
def change_mode(self, idx: int):
|
||||
if idx == 2:
|
||||
if idx == 1:
|
||||
self.widget.show()
|
||||
self.widget_2.hide()
|
||||
elif idx == 3:
|
||||
elif idx == 2:
|
||||
self.widget.show()
|
||||
self.widget_2.show()
|
||||
else:
|
||||
@ -29,12 +29,24 @@ class QSmooth(QtWidgets.QDialog, Ui_SmoothDialog):
|
||||
idx = self.comboBox.currentIndex()
|
||||
|
||||
# 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()
|
||||
|
||||
if idx == 3:
|
||||
# LOESS needs also polynomial degree and number of iterations
|
||||
if idx == 2:
|
||||
para['deg'] = self.polynom_spinBox.value()
|
||||
para['it'] = self.iter_spinBox.value()
|
||||
|
||||
|
@ -320,7 +320,11 @@ class Points:
|
||||
pts = []
|
||||
|
||||
_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:
|
||||
for idx_i in idx:
|
||||
if isinstance(idx_i, tuple):
|
||||
@ -338,7 +342,7 @@ class Points:
|
||||
right_b = int(min(len(self), x_idx + avg_range[1] + 1))
|
||||
|
||||
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:
|
||||
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]))
|
||||
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
|
||||
|
||||
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':
|
||||
y_mean = np.mean(self._y[self.mask][left:right].real)
|
||||
y_err = np.linalg.norm(self._y_err[self.mask][left:right]) / (right - left)
|
||||
y_mean = np.mean(y[left:right].real)
|
||||
y_err_mean = np.linalg.norm(y_err[left:right]) / (right - left)
|
||||
|
||||
elif mode == 'sum':
|
||||
y_mean = np.sum(self._y[self.mask][left:right].real)
|
||||
y_err = np.linalg.norm(self._y_err[self.mask][left:right])
|
||||
y_mean = np.sum(y[left:right].real)
|
||||
y_err_mean = np.linalg.norm(y_err[left:right])
|
||||
|
||||
elif mode == 'integral':
|
||||
y_mean = simpson(self._y[self.mask][left:right].real, x=self._x[left:right])
|
||||
y_err = np.linalg.norm(cumulative_trapezoid(self._y_err[self.mask][left:right].real, x=self._x[left:right]))
|
||||
y_mean = simpson(y[left:right].real, x=x[left:right])
|
||||
y_err_mean = np.linalg.norm(cumulative_trapezoid(y_err[left:right].real, x=x[left:right]))
|
||||
|
||||
else:
|
||||
y_mean = self._y[self.mask][idx].real
|
||||
y_err = self._y_err[self.mask][idx]
|
||||
y_mean = y[idx].real
|
||||
y_err_mean = y_err[idx]
|
||||
|
||||
return y_mean, y_err
|
||||
return y_mean, y_err_mean
|
||||
|
||||
def concatenate(self, other):
|
||||
"""
|
||||
|
@ -6,8 +6,8 @@ from .model import Model
|
||||
from .parameter import Parameters, Parameter
|
||||
|
||||
|
||||
class Data(object):
|
||||
def __init__(self, x, y, we=None, idx=None):
|
||||
class Data:
|
||||
def __init__(self, x, y, we=None, idx=None, complex_type: int = 0):
|
||||
self.x = np.asarray(x)
|
||||
self.y = np.asarray(y)
|
||||
if self.y.shape[0] != self.x.shape[0]:
|
||||
@ -20,6 +20,7 @@ class Data(object):
|
||||
self.parameter = Parameters()
|
||||
self.para_keys: list = []
|
||||
self.fun_kwargs = {}
|
||||
self.complex_type = complex_type
|
||||
|
||||
def __len__(self):
|
||||
return self.y.shape[0]
|
||||
|
@ -361,7 +361,7 @@ class FitRoutine(object):
|
||||
with np.errstate(all='ignore'):
|
||||
res = optimize.least_squares(cost, p0, bounds=(lb, ub), max_nfev=500 * len(p0))
|
||||
|
||||
err, corr, partial_corr = self._calc_error(res.jac, np.sum(res.fun**2), *res.jac.shape)
|
||||
err, corr, partial_corr = _calc_error(res.jac, np.sum(res.fun**2), *res.jac.shape)
|
||||
self.make_results(data, res.x, var, data.para_keys, res.jac.shape,
|
||||
err=err, corr=corr, partial_corr=partial_corr)
|
||||
|
||||
@ -375,7 +375,7 @@ class FitRoutine(object):
|
||||
with np.errstate(all='ignore'):
|
||||
res = optimize.least_squares(cost, p0, bounds=(lb, ub), max_nfev=500 * len(p0))
|
||||
|
||||
err, corr, partial_corr = self._calc_error(res.jac, np.sum(res.fun**2), *res.jac.shape)
|
||||
err, corr, partial_corr = _calc_error(res.jac, np.sum(res.fun**2), *res.jac.shape)
|
||||
for v, var_pars_k in zip(data, data_pars):
|
||||
self.make_results(v, res.x, var, var_pars_k, res.jac.shape,
|
||||
err=err, corr=corr, partial_corr=partial_corr)
|
||||
@ -458,9 +458,17 @@ class FitRoutine(object):
|
||||
self.make_results(v, res.beta, var, var_pars_k, (sum(len(d) for d in data), len(p0)),
|
||||
err=res.sd_beta, corr=corr, partial_corr=partial_corr)
|
||||
|
||||
def make_results(self, data, p, var_pars, used_pars, shape,
|
||||
err=None, corr=None, partial_corr=None):
|
||||
|
||||
def make_results(
|
||||
self,
|
||||
data: Data,
|
||||
p: list[float],
|
||||
var_pars: list[str],
|
||||
used_pars: list[str],
|
||||
shape: tuple[int, int],
|
||||
err: list[float] = None,
|
||||
corr: np.ndarray = None,
|
||||
partial_corr: np.ndarray = None,
|
||||
):
|
||||
if err is None:
|
||||
err = [0] * len(p)
|
||||
|
||||
@ -498,52 +506,54 @@ class FitRoutine(object):
|
||||
model = data.get_model()
|
||||
|
||||
self.result[idx] = FitResultCreator.make_with_model(
|
||||
model,
|
||||
data.x,
|
||||
data.y,
|
||||
actual_parameters,
|
||||
data.fun_kwargs,
|
||||
data.we_string,
|
||||
data.idx,
|
||||
*shape,
|
||||
model=model,
|
||||
x_orig=data.x,
|
||||
y_orig=data.y,
|
||||
p=actual_parameters,
|
||||
fun_kwargs=data.fun_kwargs,
|
||||
we=data.we_string,
|
||||
idx=data.idx,
|
||||
nobs=shape[0],
|
||||
nvar=shape[1],
|
||||
corr=actual_corr,
|
||||
pcorr=actual_pcorr,
|
||||
data_mode=data.complex_type,
|
||||
)
|
||||
|
||||
return self.result
|
||||
|
||||
@staticmethod
|
||||
def _calc_error(jac, chi, nobs, nvars):
|
||||
# copy of scipy.curve_fit to calculate covariance
|
||||
# noinspection PyTupleAssignmentBalance
|
||||
try:
|
||||
_, s, vt = la.svd(jac, full_matrices=False)
|
||||
except ValueError as e:
|
||||
# this may be issue #39: On entry to DGESSD parameter had an illegal value
|
||||
# catch this exception and ignore error calculation
|
||||
logger.error(f'Error calculation failed with {e.args}')
|
||||
pcov = None
|
||||
else:
|
||||
threshold = EPS * max(jac.shape) * s[0]
|
||||
s = s[s > threshold]
|
||||
vt = vt[:s.size]
|
||||
pcov = np.dot(vt.T / s**2, vt) * chi / (nobs - nvars)
|
||||
|
||||
if pcov is None:
|
||||
_err = np.zeros(nvars)
|
||||
corr = np.zeros((nvars, nvars))
|
||||
else:
|
||||
_err = np.sqrt(np.diag(pcov))
|
||||
corr = pcov / (_err[:, None] * _err[None, :])
|
||||
def _calc_error(jac, chi, nobs, nvars):
|
||||
# copy of scipy.curve_fit to calculate covariance
|
||||
# noinspection PyTupleAssignmentBalance
|
||||
try:
|
||||
_, s, vt = la.svd(jac, full_matrices=False)
|
||||
except ValueError as e:
|
||||
# this may be issue #39: On entry to DGESSD parameter had an illegal value
|
||||
# catch this exception and ignore error calculation
|
||||
logger.error(f'Error calculation failed with {e.args}')
|
||||
pcov = None
|
||||
else:
|
||||
threshold = EPS * max(jac.shape) * s[0]
|
||||
s = s[s > threshold]
|
||||
vt = vt[:s.size]
|
||||
pcov = np.dot(vt.T / s**2, vt) * chi / (nobs - nvars)
|
||||
|
||||
corr = corr.astype(np.float64)
|
||||
try:
|
||||
corr_inv = np.linalg.inv(corr)
|
||||
corr_inv_diag = np.diag(np.sqrt(1 / np.diag(corr_inv)))
|
||||
partial_corr = -1. * np.dot(np.dot(corr_inv_diag, corr_inv), corr_inv_diag) # Partial correlation matrix
|
||||
partial_corr[np.diag_indices_from(partial_corr)] = 1.
|
||||
except np.linalg.LinAlgError:
|
||||
partial_corr = corr
|
||||
if pcov is None:
|
||||
_err = np.zeros(nvars)
|
||||
corr = np.zeros((nvars, nvars))
|
||||
else:
|
||||
_err = np.sqrt(np.diag(pcov))
|
||||
corr = pcov / (_err[:, None] * _err[None, :])
|
||||
|
||||
return _err, corr, partial_corr
|
||||
corr = corr.astype(np.float64)
|
||||
try:
|
||||
corr_inv = np.linalg.inv(corr)
|
||||
corr_inv_diag = np.diag(np.sqrt(1 / np.diag(corr_inv)))
|
||||
partial_corr = -1. * np.dot(np.dot(corr_inv_diag, corr_inv), corr_inv_diag) # Partial correlation matrix
|
||||
partial_corr[np.diag_indices_from(partial_corr)] = 1.
|
||||
except np.linalg.LinAlgError:
|
||||
partial_corr = corr
|
||||
|
||||
return _err, corr, partial_corr
|
||||
|
||||
|
@ -9,7 +9,7 @@ from ._meta import MultiModel
|
||||
from .parameter import Parameters, Parameter
|
||||
|
||||
|
||||
class Model(object):
|
||||
class Model:
|
||||
def __init__(self, model, *args, **kwargs):
|
||||
self.idx = kwargs.pop('idx', None)
|
||||
|
||||
|
@ -11,6 +11,7 @@ from scipy.stats import f as fdist
|
||||
from scipy.interpolate import interp1d
|
||||
|
||||
from ._meta import MultiModel
|
||||
from .model import Model
|
||||
from .parameter import Parameter
|
||||
from ..data.points import Points
|
||||
from ..data.signals import Signal
|
||||
@ -36,17 +37,30 @@ class FitResultCreator:
|
||||
else:
|
||||
resid = kwargs['y'] - y_orig
|
||||
|
||||
stats = FitResultCreator.calc_statistics(resid, _y)
|
||||
stats = calc_statistics(resid, _y)
|
||||
|
||||
return FitResult(kwargs['x'], kwargs['y'], x_orig, y_orig, params, dict(kwargs['choice']), resid, 0, 0,
|
||||
kwargs['name'], stats, idx)
|
||||
return FitResult(
|
||||
x=kwargs['x'],
|
||||
y=kwargs['y'],
|
||||
x_data=x_orig,
|
||||
y_data=y_orig,
|
||||
params=params,
|
||||
fun_kwargs=dict(kwargs['choice']),
|
||||
resid=resid,
|
||||
nobs=0,
|
||||
nvar=0,
|
||||
we='',
|
||||
name=kwargs['name'],
|
||||
stats=stats,
|
||||
idx=idx,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def make_with_model(
|
||||
model: 'Model',
|
||||
x_orig: np.ndarray,
|
||||
y_orig: np.ndarray,
|
||||
p: 'Parameters',
|
||||
p: list,
|
||||
fun_kwargs: dict,
|
||||
we: str,
|
||||
idx: str | None,
|
||||
@ -54,6 +68,7 @@ class FitResultCreator:
|
||||
nvar: int,
|
||||
corr: np.ndarray,
|
||||
pcorr: np.ndarray,
|
||||
data_mode: int,
|
||||
) -> FitResult:
|
||||
if np.all(x_orig > 0) and (np.max(x_orig) > 100 * np.min(x_orig)):
|
||||
islog = True
|
||||
@ -83,17 +98,11 @@ class FitResultCreator:
|
||||
actual_mode = fun_kwargs['complex_mode']
|
||||
fun_kwargs['complex_mode'] = 0
|
||||
|
||||
_y = model.func(p_final, _x, **fun_kwargs)
|
||||
_y = check_complex(model.func(p_final, _x, **fun_kwargs), actual_mode, data_mode)
|
||||
|
||||
if not actual_mode < 0:
|
||||
if actual_mode == 1:
|
||||
_y.imag = 0
|
||||
elif actual_mode == 2:
|
||||
_y.real = 0
|
||||
fun_kwargs['complex_mode'] = actual_mode
|
||||
|
||||
fun_kwargs['complex_mode'] = actual_mode
|
||||
|
||||
stats = FitResultCreator.calc_statistics(_y, resid, nobs, nvar)
|
||||
stats = calc_statistics(_y, resid, nobs, nvar)
|
||||
varied = [p.var for p in parameters.values()]
|
||||
|
||||
if corr is None:
|
||||
@ -134,38 +143,9 @@ class FitResultCreator:
|
||||
pcorr=partial_correlation,
|
||||
islog=islog,
|
||||
func=model,
|
||||
data_complex=data_mode,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def calc_statistics(y, residual, nobs=None, nvar=None):
|
||||
chi = (residual**2).sum()
|
||||
try:
|
||||
r = 1 - chi/((y-np.mean(y))**2).sum()
|
||||
except RuntimeWarning:
|
||||
r = -9999
|
||||
|
||||
if nobs is None:
|
||||
nobs = 1
|
||||
|
||||
if nvar is None:
|
||||
nvar = 0
|
||||
|
||||
dof = nobs - nvar
|
||||
loglikehood = nobs * np.log(chi / nobs)
|
||||
|
||||
stats = {
|
||||
'chi^2': chi,
|
||||
'R^2': r,
|
||||
'AIC': loglikehood + 2 * nvar,
|
||||
'BIC': loglikehood + np.log(nobs) * nvar,
|
||||
'adj. R^2': 1 - (nobs-1) / (dof+1e-13) * (1-r),
|
||||
'red. chi^2': chi / (dof + 1e-13),
|
||||
}
|
||||
|
||||
stats['AICc'] = stats['AIC'] + 2*(nvar+1)*nvar / (dof - 1 + 1e-13)
|
||||
|
||||
return stats
|
||||
|
||||
|
||||
class FitResult(Points):
|
||||
|
||||
@ -188,7 +168,8 @@ class FitResult(Points):
|
||||
pcorr: np.ndarray = None,
|
||||
islog: bool = False,
|
||||
func=None,
|
||||
**kwargs
|
||||
data_complex: int = 1,
|
||||
**kwargs,
|
||||
):
|
||||
|
||||
self.parameter, name = self._prepare_names(params, name)
|
||||
@ -210,6 +191,7 @@ class FitResult(Points):
|
||||
self.y_data = y_data
|
||||
self._model_name = name
|
||||
self._func = func
|
||||
self._data_complex = data_complex
|
||||
|
||||
@staticmethod
|
||||
def _prepare_names(parameter: dict, modelname: str):
|
||||
@ -418,20 +400,12 @@ class FitResult(Points):
|
||||
if self.func is None:
|
||||
raise ValueError('no fit function available to calculate new y values')
|
||||
|
||||
actual_mode = -1
|
||||
if 'complex_mode' in self.fun_kwargs:
|
||||
actual_mode = self.fun_kwargs['complex_mode']
|
||||
self.fun_kwargs['complex_mode'] = 0
|
||||
|
||||
new_fit = self.copy()
|
||||
y_values = self.func.func(self.p_final, x_values, **self.fun_kwargs)
|
||||
if not actual_mode < 0:
|
||||
if actual_mode == 1:
|
||||
y_values.imag = 0
|
||||
elif actual_mode == 2:
|
||||
y_values.real = 0
|
||||
|
||||
self.fun_kwargs['complex_mode'] = actual_mode
|
||||
fun_kwargs = {k: v for k, v in self.fun_kwargs.items()}
|
||||
if self.fun_kwargs.get('complex_mode', -1) == -1:
|
||||
fun_kwargs.pop('complex_mode', None)
|
||||
y_values = self.func.func(self.p_final, x_values, **fun_kwargs)
|
||||
y_values = check_complex(y_values, self.fun_kwargs.get('complex_mode', -1), self._data_complex)
|
||||
|
||||
new_fit.set_data(x_values, y_values, y_err=0.0)
|
||||
|
||||
@ -442,20 +416,16 @@ class FitResult(Points):
|
||||
raise ValueError('no fit function available to calculate new y values')
|
||||
|
||||
part_functions = []
|
||||
actual_mode = -1
|
||||
if 'complex_mode' in self.fun_kwargs:
|
||||
actual_mode = self.fun_kwargs['complex_mode']
|
||||
self.fun_kwargs['complex_mode'] = 0
|
||||
actual_mode = self.fun_kwargs.get('complex_mode', -1)
|
||||
fun_kwargs = {k: v for k, v in self.fun_kwargs.items()}
|
||||
if self.fun_kwargs.get('complex_mode', -1) == -1:
|
||||
fun_kwargs.pop('complex_mode', None)
|
||||
|
||||
for sub_name, sub_y in zip(self.func.sub_name(), self.func.sub(self.p_final, x_values, **self.fun_kwargs)):
|
||||
if not actual_mode < 0:
|
||||
if actual_mode == 1:
|
||||
sub_y.imag = 0
|
||||
elif actual_mode == 2:
|
||||
sub_y.real = 0
|
||||
sub_y = check_complex(sub_y, actual_mode, self._data_complex)
|
||||
|
||||
if np.iscomplexobj(sub_y):
|
||||
part_functions.append(Signal(x_values, sub_y, name=sub_name))
|
||||
|
||||
else:
|
||||
part_functions.append(Points(x_values, sub_y, name=sub_name))
|
||||
|
||||
@ -463,3 +433,49 @@ class FitResult(Points):
|
||||
self.fun_kwargs['complex_mode'] = actual_mode
|
||||
|
||||
return part_functions
|
||||
|
||||
|
||||
def check_complex(y, model_complex, data_complex):
|
||||
if not np.iscomplexobj(y):
|
||||
return y
|
||||
|
||||
if model_complex == 1:
|
||||
y.imag = 0
|
||||
if data_complex == 1:
|
||||
y = y.real
|
||||
elif model_complex == 2:
|
||||
y.real = 0
|
||||
if data_complex == 1:
|
||||
y = y.imag
|
||||
|
||||
return y
|
||||
|
||||
|
||||
def calc_statistics(y, residual, nobs=None, nvar=None):
|
||||
chi = (residual**2).sum()
|
||||
try:
|
||||
r = 1 - chi/((y-np.mean(y))**2).sum()
|
||||
except RuntimeWarning:
|
||||
r = -9999
|
||||
|
||||
if nobs is None:
|
||||
nobs = 1
|
||||
|
||||
if nvar is None:
|
||||
nvar = 0
|
||||
|
||||
dof = nobs - nvar
|
||||
loglikehood = nobs * np.log(chi / nobs)
|
||||
|
||||
stats = {
|
||||
'chi^2': chi,
|
||||
'R^2': r,
|
||||
'AIC': loglikehood + 2 * nvar,
|
||||
'BIC': loglikehood + np.log(nobs) * nvar,
|
||||
'adj. R^2': 1 - (nobs-1) / (dof+1e-13) * (1-r),
|
||||
'red. chi^2': chi / (dof + 1e-13),
|
||||
}
|
||||
|
||||
stats['AICc'] = stats['AIC'] + 2*(nvar+1)*nvar / (dof - 1 + 1e-13)
|
||||
|
||||
return stats
|
||||
|
@ -49,7 +49,7 @@ class AsciiReader:
|
||||
with self.fname.open('r') as f:
|
||||
for i, line in enumerate(islice(f, len(self.header)+len(self.lines), num_lines)):
|
||||
line = line.strip('\n\t\r, ')
|
||||
line = re.sub(r'[\t ;,] *', ';', line)
|
||||
line = re.sub(r'[\t ;,]+', ';', line)
|
||||
line = line.split(';')
|
||||
|
||||
try:
|
||||
@ -183,7 +183,13 @@ class AsciiReader:
|
||||
single_len = 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):
|
||||
if col_names is not None:
|
||||
@ -191,7 +197,7 @@ class AsciiReader:
|
||||
kwargs['name'] = col_names[j-1]
|
||||
elif num_y > single_len:
|
||||
# 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]:
|
||||
kwargs['y_err'] = raw_data[i, :, j+num_y]
|
||||
|
@ -11,7 +11,8 @@ try:
|
||||
from scipy.integrate import simpson
|
||||
except ImportError:
|
||||
from scipy.integrate import simps as simpson
|
||||
from scipy.interpolate import interp1d
|
||||
from scipy.interpolate import CubicSpline
|
||||
|
||||
|
||||
ReferenceValue = namedtuple('Reference', ['name', 'transitions'])
|
||||
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:
|
||||
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:
|
||||
ii = 1
|
||||
for line in f:
|
||||
@ -144,9 +145,12 @@ class DSCCalibrator:
|
||||
self.reference = []
|
||||
self.ref_list = []
|
||||
|
||||
def set_measurement(self,
|
||||
fname: str | Path | DSCSample, mode: str = 'sample',
|
||||
reference: ReferenceValue = Cyclohexane):
|
||||
def set_measurement(
|
||||
self: DSCCalibrator,
|
||||
fname: str | Path | DSCSample,
|
||||
mode: str = 'sample',
|
||||
reference: ReferenceValue = Cyclohexane
|
||||
):
|
||||
if mode not in ['sample', 'empty', 'reference']:
|
||||
raise ValueError(f'Unknown mode {mode}, not "sample", "empty", "reference"')
|
||||
if mode == 'reference' and not isinstance(reference, ReferenceValue):
|
||||
@ -266,7 +270,12 @@ class DSCCalibrator:
|
||||
|
||||
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':
|
||||
raise ValueError('baseline correction is not implemented for isotherms')
|
||||
|
||||
@ -292,7 +301,7 @@ class DSCCalibrator:
|
||||
empty_y = empty_data[1]
|
||||
if self.sample.length(idx) != self.empty.length(idx_empty):
|
||||
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
|
||||
drift_value = sample_data.copy()[(2, 1), :]
|
||||
@ -346,9 +355,10 @@ class DSCCalibrator:
|
||||
|
||||
offset = region[0, 0]
|
||||
sample_data[1] -= m * (sample_data[2] - region[1, 0]) + offset
|
||||
line = np.array([[sample_data[2, 0], sample_data[2, -1]],
|
||||
[m * (sample_data[2, 0] - region[1, 0]) + offset,
|
||||
m * (sample_data[2, -1] - region[1, 0]) + offset]])
|
||||
line = np.array([
|
||||
[sample_data[2, 0], sample_data[2, -1]],
|
||||
[m * (sample_data[2, 0] - region[1, 0]) + offset, m * (sample_data[2, -1] - region[1, 0]) + offset]
|
||||
])
|
||||
|
||||
else:
|
||||
line = np.array([[sample_data[2, 0], sample_data[2, -1]], [0, 0]])
|
||||
|
@ -247,6 +247,7 @@
|
||||
<addaction name="action_no_range"/>
|
||||
<addaction name="action_x_range"/>
|
||||
<addaction name="action_custom_range"/>
|
||||
<addaction name="actionExclude_region"/>
|
||||
</widget>
|
||||
<addaction name="action_FitWidget"/>
|
||||
<addaction name="separator"/>
|
||||
@ -1021,6 +1022,14 @@
|
||||
<string>TNMH...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionExclude_region">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Exclude region</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
@ -354,59 +354,26 @@
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<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">
|
||||
<item row="1" column="7">
|
||||
<widget class="QComboBox" name="graph_comboBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</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">
|
||||
<widget class="QLineEdit" name="minx_line">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@ -419,10 +386,45 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4" rowspan="2">
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<item row="1" column="0">
|
||||
<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="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>
|
||||
</widget>
|
||||
</item>
|
||||
@ -432,7 +434,7 @@
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@ -445,20 +447,33 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLineEdit" name="numx_line">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string># pts</string>
|
||||
<item row="0" column="5" rowspan="2">
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</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">
|
||||
<item>
|
||||
<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">
|
||||
<string>Plot fit curve</string>
|
||||
</property>
|
||||
@ -469,6 +484,12 @@
|
||||
</item>
|
||||
<item>
|
||||
<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">
|
||||
<string>Plot partial functions</string>
|
||||
</property>
|
||||
@ -476,6 +497,19 @@
|
||||
</item>
|
||||
</layout>
|
||||
</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>
|
||||
</widget>
|
||||
</item>
|
||||
|
Loading…
Reference in New Issue
Block a user