bug-fixer (#40)

fixes #32, #34, #39

Co-authored-by: Dominik Demuth <dominik.demuth@physik.tu-darmstadt.de>
Reviewed-on: #40
This commit is contained in:
Dominik Demuth 2023-04-07 13:45:28 +00:00
parent 43285b4bd5
commit 6b71de8265
7 changed files with 58 additions and 20 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ AppDir
NMReval*.zsync NMReval*.zsync
.idea .idea
*.zs-old *.zs-old
docs

View File

@ -1,10 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'resources/_ui/eval_expr_dialog.ui' # Form implementation generated from reading ui file 'src/resources/_ui/eval_expr_dialog.ui'
# #
# Created by: PyQt5 UI code generator 5.12.3 # Created by: PyQt5 UI code generator 5.15.9
# #
# WARNING! All changes made in this file will be lost! # WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import QtCore, QtGui, QtWidgets
@ -36,14 +37,14 @@ class Ui_CalcDialog(object):
self.label_2 = QtWidgets.QLabel(self.page) self.label_2 = QtWidgets.QLabel(self.page)
self.label_2.setObjectName("label_2") self.label_2.setObjectName("label_2")
self.verticalLayout_2.addWidget(self.label_2) self.verticalLayout_2.addWidget(self.label_2)
self.listWidget = QtWidgets.QListWidget(self.page) self.listWidget = QListWidgetSelect(self.page)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.listWidget.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.listWidget.sizePolicy().hasHeightForWidth())
self.listWidget.setSizePolicy(sizePolicy) self.listWidget.setSizePolicy(sizePolicy)
self.listWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) self.listWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.listWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) self.listWidget.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
self.listWidget.setObjectName("listWidget") self.listWidget.setObjectName("listWidget")
self.verticalLayout_2.addWidget(self.listWidget) self.verticalLayout_2.addWidget(self.listWidget)
self.overwrite_checkbox = QtWidgets.QCheckBox(self.page) self.overwrite_checkbox = QtWidgets.QCheckBox(self.page)
@ -202,7 +203,7 @@ class Ui_CalcDialog(object):
self.label_8.setBuddy(self.line_doubleSpinBox) self.label_8.setBuddy(self.line_doubleSpinBox)
self.retranslateUi(CalcDialog) self.retranslateUi(CalcDialog)
self.stackedWidget.setCurrentIndex(2) self.stackedWidget.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(CalcDialog) QtCore.QMetaObject.connectSlotsByName(CalcDialog)
CalcDialog.setTabOrder(self.calc_edit, self.listWidget) CalcDialog.setTabOrder(self.calc_edit, self.listWidget)
CalcDialog.setTabOrder(self.listWidget, self.overwrite_checkbox) CalcDialog.setTabOrder(self.listWidget, self.overwrite_checkbox)
@ -237,4 +238,5 @@ class Ui_CalcDialog(object):
self.label_11.setText(_translate("CalcDialog", "Style")) self.label_11.setText(_translate("CalcDialog", "Style"))
self.label.setText(_translate("CalcDialog", "Expressions are evaluated line by line and change previous values")) self.label.setText(_translate("CalcDialog", "Expressions are evaluated line by line and change previous values"))
from ..lib.delegates import ColorListEditor, LineStyleEditor, SymbolStyleEditor from ..lib.delegates import ColorListEditor, LineStyleEditor, SymbolStyleEditor
from ..lib.listwidget import QListWidgetSelect
from ..lib.namespace import QNamespaceWidget from ..lib.namespace import QNamespaceWidget

View File

@ -46,7 +46,7 @@ class EditSignalWidget(QtWidgets.QWidget, Ui_Form):
stype = 'pts' stype = 'pts'
else: else:
try: try:
_nop = float(self.lineEdit.text()) _nop = float(self.ls_lineEdit.text())
except ValueError: except ValueError:
_nop = 0.0 _nop = 0.0
stype = 'time' stype = 'time'

View File

@ -0,0 +1,20 @@
from ..Qt import QtWidgets, QtGui, QtCore
class QListWidgetSelect(QtWidgets.QListWidget):
"""
Extension of QListWidget to change the check state of all selected QListWidgetItems with space key
"""
def __init__(self, parent=None):
super().__init__(parent=parent)
def keyPressEvent(self, evt: QtGui.QKeyEvent):
if evt.key() == QtCore.Qt.Key.Key_Space:
for idx in self.selectedIndexes():
item = self.itemFromIndex(idx)
cs = item.checkState()
item.setCheckState(QtCore.Qt.CheckState.Unchecked if cs == QtCore.Qt.CheckState.Checked
else QtCore.Qt.CheckState.Checked)
else:
super().keyPressEvent(evt)

View File

@ -76,8 +76,8 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
self.look_for_update() self.look_for_update()
self.__timer = QtCore.QTimer() self.__timer = QtCore.QTimer()
self.__savepath = config_paths() / f'{datetime.datetime.now().strftime("%Y-%m-%d_%H%M%S")}.nmr' self.__backup_path = config_paths() / f'{datetime.datetime.now().strftime("%Y-%m-%d_%H%M%S")}.nmr'
self.__timer.start(0.2*60*1000) # every three minutese self.__timer.start(3*60*1000) # every three minutese
self.__timer.timeout.connect(self._autosave) self.__timer.timeout.connect(self._autosave)
def _init_gui(self): def _init_gui(self):
@ -146,7 +146,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
self.actionUndo.setIcon(icon) self.actionUndo.setIcon(icon)
self.menuData.insertAction(self.actionRedo, self.actionUndo) self.menuData.insertAction(self.actionRedo, self.actionUndo)
# # self.actionSave.triggered.connect(lambda: self.management.save('/autohome/dominik/nmreval/testdata/test.nmr', '')) # self.actionSave.triggered.connect(lambda: self.management.save('/autohome/dominik/nmreval/testdata/test.nmr', ''))
# self.actionSave.triggered.connect(self.save) # self.actionSave.triggered.connect(self.save)
self.action_save_fit_parameter.triggered.connect(self.save_fit_parameter) self.action_save_fit_parameter.triggered.connect(self.save_fit_parameter)
self.ac_group2.triggered.connect(self.change_fit_limits) self.ac_group2.triggered.connect(self.change_fit_limits)
@ -269,6 +269,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
selected_filter = save_dialog.selectedNameFilter() selected_filter = save_dialog.selectedNameFilter()
if savefile is not None: if savefile is not None:
self.path = savefile.parent
use_underscore = save_dialog.checkBox.isChecked() use_underscore = save_dialog.checkBox.isChecked()
self.management.save(savefile, selected_filter, strip_spaces=use_underscore) self.management.save(savefile, selected_filter, strip_spaces=use_underscore)
@ -1028,7 +1029,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
write_state({'History': {'recent path': str(self.path)}}) write_state({'History': {'recent path': str(self.path)}})
# remove backup file when closing # remove backup file when closing
self.__savepath.unlink(missing_ok=True) self.__backup_path.unlink(missing_ok=True)
super().close() super().close()
@ -1056,5 +1057,5 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
def _autosave(self): def _autosave(self):
# TODO better separate thread may it takes some time to save # TODO better separate thread may it takes some time to save
self.status.setText('Autosave...') self.status.setText('Autosave...')
NMRWriter(self.management.graphs, self.management.data).export(self.__savepath) NMRWriter(self.management.graphs, self.management.data).export(self.__backup_path)
self.status.setText('') self.status.setText('')

View File

@ -14,6 +14,8 @@ from .result import FitResultCreator
__all__ = ['FitRoutine', 'FitAbortException'] __all__ = ['FitRoutine', 'FitAbortException']
from ..lib.logger import logger
class FitAbortException(Exception): class FitAbortException(Exception):
pass pass
@ -464,11 +466,18 @@ class FitRoutine(object):
def _calc_error(jac, chi, nobs, nvars): def _calc_error(jac, chi, nobs, nvars):
# copy of scipy.curve_fit to calculate covariance # copy of scipy.curve_fit to calculate covariance
# noinspection PyTupleAssignmentBalance # noinspection PyTupleAssignmentBalance
_, s, vt = la.svd(jac, full_matrices=False) try:
threshold = EPS * max(jac.shape) * s[0] _, s, vt = la.svd(jac, full_matrices=False)
s = s[s > threshold] except ValueError as e:
vt = vt[:s.size] # this may be issue #39: On entry to DGESSD parameter had an illegal value
pcov = np.dot(vt.T / s**2, vt) * chi / (nobs - nvars) # 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: if pcov is None:
_err = np.zeros(nvars) _err = np.zeros(nvars)

View File

@ -27,7 +27,7 @@
<item> <item>
<widget class="QStackedWidget" name="stackedWidget"> <widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>2</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="page"> <widget class="QWidget" name="page">
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
@ -54,7 +54,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QListWidget" name="listWidget"> <widget class="QListWidgetSelect" name="listWidget">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding"> <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -65,7 +65,7 @@
<set>QAbstractItemView::NoEditTriggers</set> <set>QAbstractItemView::NoEditTriggers</set>
</property> </property>
<property name="selectionMode"> <property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum> <enum>QAbstractItemView::ExtendedSelection</enum>
</property> </property>
</widget> </widget>
</item> </item>
@ -414,6 +414,11 @@
<header>..lib.namespace</header> <header>..lib.namespace</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget>
<class>QListWidgetSelect</class>
<extends>QListWidget</extends>
<header>..lib.listwidget</header>
</customwidget>
</customwidgets> </customwidgets>
<tabstops> <tabstops>
<tabstop>calc_edit</tabstop> <tabstop>calc_edit</tabstop>