forked from IPKM/nmreval
bug-fixer (#40)
fixes #32, #34, #39 Co-authored-by: Dominik Demuth <dominik.demuth@physik.tu-darmstadt.de> Reviewed-on: IPKM/nmreval#40
This commit is contained in:
parent
43285b4bd5
commit
6b71de8265
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@ AppDir
|
|||||||
NMReval*.zsync
|
NMReval*.zsync
|
||||||
.idea
|
.idea
|
||||||
*.zs-old
|
*.zs-old
|
||||||
|
docs
|
||||||
|
@ -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
|
||||||
|
@ -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'
|
||||||
|
20
src/gui_qt/lib/listwidget.py
Normal file
20
src/gui_qt/lib/listwidget.py
Normal 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)
|
@ -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('')
|
||||||
|
@ -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)
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user