diff --git a/doc/source/_templates/autosummary/class_with_attributes.rst b/doc/source/_templates/autosummary/class_with_attributes.rst index 1755a3b..272b80d 100644 --- a/doc/source/_templates/autosummary/class_with_attributes.rst +++ b/doc/source/_templates/autosummary/class_with_attributes.rst @@ -4,27 +4,27 @@ .. autoclass:: {{ objname }} - {% block methods %} + {%- block methods %} {% if methods %} .. rubric:: {{ _('Methods') }} - {% for item in methods %} + {%- for item in methods %} {% if not item.startswith('_') %} .. automethod:: {{ item }} {%- endif %} {%- endfor %} - {% endif %} + {%- endif %} {% endblock %} - {% block attributes %} - {% if attributes %} + {%- block attributes %} + {%- if attributes %} .. rubric:: {{ _('Attributes') }} {% for item in attributes %} .. autoattribute:: {{ item }} {%- endfor %} {% endif %} - {% endblock %} + {% endblock -%} .. include:: {{ fullname }}.examples diff --git a/doc/source/api/distributions2/index.rst b/doc/source/api/distributions2/index.rst deleted file mode 100644 index cf1fadd..0000000 --- a/doc/source/api/distributions2/index.rst +++ /dev/null @@ -1,29 +0,0 @@ -********************************* -Distribution of correlation times -********************************* - -List of all implemented distributions and the associated correlation functions, spectral densities, susceptibilies - -.. contents:: Table of Contents - :depth: 3 - :local: - :backlinks: entry - -Cole-Cole ---------- - -.. automodule:: nmreval.distributions.colecole - :members: - - -Cole-Davidson -------------- - -.. automodule:: nmreval.distributions.coledavidson - :members: - -Havriliak-Negami ----------------- - -.. automodule:: nmreval.distributions.havriliaknegami - :members: diff --git a/doc/source/api/models2/basic.rst b/doc/source/api/models2/basic.rst deleted file mode 100644 index e87e570..0000000 --- a/doc/source/api/models2/basic.rst +++ /dev/null @@ -1,6 +0,0 @@ -************************ -``nmreval.models.basic`` -************************ - -.. automodule:: nmreval.models.basic - :members: \ No newline at end of file diff --git a/doc/source/api/models2/index.rst b/doc/source/api/models2/index.rst deleted file mode 100644 index 006cb95..0000000 --- a/doc/source/api/models2/index.rst +++ /dev/null @@ -1,31 +0,0 @@ -************** -Model function -************** - -List of all implemented functions - -.. contents:: Table of Contents - :depth: 3 - :local: - :backlinks: entry - -Basic functions ---------------- - -.. currentmodule:: nmreval - -.. autosummary:: - :toctree: - - nmreval.models.basic - - - - -NMR relaxation functions ------------------------- - -.. automodule:: nmreval.models.relaxation - :members: - - diff --git a/doc/source/api/models2/nmreval.models.basic.rst b/doc/source/api/models2/nmreval.models.basic.rst deleted file mode 100644 index 17cfa50..0000000 --- a/doc/source/api/models2/nmreval.models.basic.rst +++ /dev/null @@ -1,37 +0,0 @@ -nmreval.models.basic -==================== - -.. automodule:: nmreval.models.basic - - - - - - - - - - - - .. rubric:: Classes - - .. autosummary:: - - Constant - ExpFunc - Linear - Log - MittagLeffler - Parabola - PowerLaw - PowerLawCross - Sine - - - - - - - - - diff --git a/nmreval/data/points.py b/nmreval/data/points.py index 2388486..8ea4630 100644 --- a/nmreval/data/points.py +++ b/nmreval/data/points.py @@ -510,7 +510,7 @@ class Points: return self - def cut(self, low_lim=None, high_lim=None): + def cut(self, low_lim: float = None, high_lim: float = None): """ Cut Args: diff --git a/nmreval/gui_qt/_py/basewindow.py b/nmreval/gui_qt/_py/basewindow.py index b90fa3c..ab7e51c 100644 --- a/nmreval/gui_qt/_py/basewindow.py +++ b/nmreval/gui_qt/_py/basewindow.py @@ -18,10 +18,10 @@ class Ui_BaseWindow(object): BaseWindow.setDockOptions(QtWidgets.QMainWindow.AllowTabbedDocks|QtWidgets.QMainWindow.AnimatedDocks|QtWidgets.QMainWindow.ForceTabbedDocks|QtWidgets.QMainWindow.VerticalTabs) self.centralwidget = QtWidgets.QWidget(BaseWindow) self.centralwidget.setObjectName("centralwidget") - self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget) - self.verticalLayout.setContentsMargins(3, 3, 3, 3) - self.verticalLayout.setSpacing(3) - self.verticalLayout.setObjectName("verticalLayout") + self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget) + self.horizontalLayout.setContentsMargins(3, 3, 3, 3) + self.horizontalLayout.setSpacing(3) + self.horizontalLayout.setObjectName("horizontalLayout") self.splitter = QtWidgets.QSplitter(self.centralwidget) self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setObjectName("splitter") @@ -63,7 +63,7 @@ class Ui_BaseWindow(object): self.tabWidget.addTab(self.t1tauwidget, icon5, "") self.area = QtWidgets.QMdiArea(self.splitter) self.area.setObjectName("area") - self.verticalLayout.addWidget(self.splitter) + self.horizontalLayout.addWidget(self.splitter) BaseWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(BaseWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 1388, 30)) @@ -503,11 +503,11 @@ class Ui_BaseWindow(object): self.menuBDS.setTitle(_translate("BaseWindow", "BDS")) self.menuSpectrum.setTitle(_translate("BaseWindow", "Spectrum")) self.toolBar.setWindowTitle(_translate("BaseWindow", "Main")) - self.toolbar_edit.setWindowTitle(_translate("BaseWindow", "Edit")) + self.toolbar_edit.setWindowTitle(_translate("BaseWindow", "Math")) self.toolBar_nmr.setWindowTitle(_translate("BaseWindow", "NMR")) self.toolBar_fit.setWindowTitle(_translate("BaseWindow", "Fit")) self.toolBar_spectrum.setWindowTitle(_translate("BaseWindow", "Spectrum")) - self.toolBar_data.setWindowTitle(_translate("BaseWindow", "toolBar_2")) + self.toolBar_data.setWindowTitle(_translate("BaseWindow", "Data")) self.action_close.setText(_translate("BaseWindow", "&Quit")) self.action_close.setShortcut(_translate("BaseWindow", "Ctrl+Q")) self.actionExportGraphic.setText(_translate("BaseWindow", "Export graphic...")) diff --git a/nmreval/gui_qt/_py/valueeditor.py b/nmreval/gui_qt/_py/valueeditor.py index bfab40a..1425e0e 100644 --- a/nmreval/gui_qt/_py/valueeditor.py +++ b/nmreval/gui_qt/_py/valueeditor.py @@ -18,12 +18,12 @@ class Ui_MaskDialog(object): self.verticalLayout.setContentsMargins(3, 3, 3, 3) self.verticalLayout.setSpacing(3) self.verticalLayout.setObjectName("verticalLayout") - self.comboBox = QtWidgets.QComboBox(MaskDialog) - self.comboBox.setObjectName("comboBox") - self.verticalLayout.addWidget(self.comboBox) - self.comboBox_2 = QtWidgets.QComboBox(MaskDialog) - self.comboBox_2.setObjectName("comboBox_2") - self.verticalLayout.addWidget(self.comboBox_2) + self.graph_combobox = QtWidgets.QComboBox(MaskDialog) + self.graph_combobox.setObjectName("graph_combobox") + self.verticalLayout.addWidget(self.graph_combobox) + self.set_combobox = QtWidgets.QComboBox(MaskDialog) + self.set_combobox.setObjectName("set_combobox") + self.verticalLayout.addWidget(self.set_combobox) self.tableView = QtWidgets.QTableView(MaskDialog) self.tableView.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.tableView.setObjectName("tableView") @@ -51,22 +51,25 @@ class Ui_MaskDialog(object): self.gridLayout.setContentsMargins(-1, 0, -1, -1) self.gridLayout.setSpacing(3) self.gridLayout.setObjectName("gridLayout") - self.unmaskbutton = QtWidgets.QPushButton(MaskDialog) - self.unmaskbutton.setObjectName("unmaskbutton") - self.gridLayout.addWidget(self.unmaskbutton, 1, 0, 1, 1) - self.delete_button = QtWidgets.QPushButton(MaskDialog) - icon = QtGui.QIcon.fromTheme("list-remove") - self.delete_button.setIcon(icon) - self.delete_button.setObjectName("delete_button") - self.gridLayout.addWidget(self.delete_button, 0, 1, 1, 1) self.add_button = QtWidgets.QPushButton(MaskDialog) icon = QtGui.QIcon.fromTheme("list-add") self.add_button.setIcon(icon) self.add_button.setObjectName("add_button") - self.gridLayout.addWidget(self.add_button, 0, 0, 1, 1) + self.gridLayout.addWidget(self.add_button, 0, 0, 1, 2) + self.delete_button = QtWidgets.QPushButton(MaskDialog) + icon = QtGui.QIcon.fromTheme("list-remove") + self.delete_button.setIcon(icon) + self.delete_button.setObjectName("delete_button") + self.gridLayout.addWidget(self.delete_button, 0, 2, 1, 2) + self.split_button = QtWidgets.QPushButton(MaskDialog) + self.split_button.setObjectName("split_button") + self.gridLayout.addWidget(self.split_button, 0, 4, 1, 2) self.mask_button = QtWidgets.QPushButton(MaskDialog) self.mask_button.setObjectName("mask_button") - self.gridLayout.addWidget(self.mask_button, 1, 1, 1, 1) + self.gridLayout.addWidget(self.mask_button, 1, 0, 1, 3) + self.unmaskbutton = QtWidgets.QPushButton(MaskDialog) + self.unmaskbutton.setObjectName("unmaskbutton") + self.gridLayout.addWidget(self.unmaskbutton, 1, 3, 1, 3) self.verticalLayout.addLayout(self.gridLayout) self.label.setBuddy(self.spinBox) @@ -78,8 +81,9 @@ class Ui_MaskDialog(object): MaskDialog.setWindowTitle(_translate("MaskDialog", "Form")) self.label.setText(_translate("MaskDialog", "Go to line:")) self.toolButton.setText(_translate("MaskDialog", "Go Go Power Rangers!")) - self.unmaskbutton.setText(_translate("MaskDialog", "Show all")) - self.delete_button.setText(_translate("MaskDialog", "Delete rows")) self.add_button.setText(_translate("MaskDialog", "Add row")) + self.delete_button.setText(_translate("MaskDialog", "Delete rows")) + self.split_button.setText(_translate("MaskDialog", "Split after selection")) self.mask_button.setToolTip(_translate("MaskDialog", "
Masked rows are shown in green
")) self.mask_button.setText(_translate("MaskDialog", "Hide/Show selected")) + self.unmaskbutton.setText(_translate("MaskDialog", "Show all")) diff --git a/nmreval/gui_qt/data/valueeditwidget.py b/nmreval/gui_qt/data/valueeditwidget.py index f79e32c..ae13ba9 100644 --- a/nmreval/gui_qt/data/valueeditwidget.py +++ b/nmreval/gui_qt/data/valueeditwidget.py @@ -1,4 +1,6 @@ -from typing import Union, List +from __future__ import annotations + +from typing import Any, List import numpy as np @@ -13,6 +15,7 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog): itemDeleted = QtCore.pyqtSignal(str, list) itemAdded = QtCore.pyqtSignal(str) values_selected = QtCore.pyqtSignal(str, list, list) + split_signal = QtCore.pyqtSignal(str, int) def __init__(self, parent=None): super().__init__(parent=parent) @@ -34,54 +37,54 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog): self.tableView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.tableView.customContextMenuRequested.connect(self.ctx) - self.comboBox.currentIndexChanged.connect(self._populate_sets) - self.comboBox_2.currentIndexChanged.connect(self._populate_table) + self.graph_combobox.currentIndexChanged.connect(self._populate_sets) + self.set_combobox.currentIndexChanged.connect(self._populate_table) def __call__(self, items: dict): self.items = items - self.comboBox.blockSignals(True) - self.comboBox.clear() + self.graph_combobox.blockSignals(True) + self.graph_combobox.clear() for k, v in items.items(): - self.comboBox.addItem(k[1], userData=k[0]) - self.comboBox.blockSignals(False) + self.graph_combobox.addItem(k[1], userData=k[0]) + self.graph_combobox.blockSignals(False) - idx = self.comboBox.findData(self.graph_shown) + idx = self.graph_combobox.findData(self.graph_shown) if idx == -1: idx = 0 - self.comboBox.setCurrentIndex(idx) - self.comboBox.currentIndexChanged.emit(idx) + self.graph_combobox.setCurrentIndex(idx) + self.graph_combobox.currentIndexChanged.emit(idx) return self @QtCore.pyqtSlot(int) def _populate_sets(self, idx: int): if idx == -1: - self.comboBox.setCurrentIndex(0) + self.graph_combobox.setCurrentIndex(0) return - self.comboBox_2.blockSignals(True) - self.comboBox_2.clear() - self.graph_shown = self.comboBox.currentData() + self.set_combobox.blockSignals(True) + self.set_combobox.clear() + self.graph_shown = self.graph_combobox.currentData() if self.items: - for sid, name in self.items[(self.comboBox.currentData(), self.comboBox.currentText())]: - self.comboBox_2.addItem(name, userData=sid) - self.comboBox_2.blockSignals(False) + for sid, name in self.items[(self.graph_combobox.currentData(), self.graph_combobox.currentText())]: + self.set_combobox.addItem(name, userData=sid) + self.set_combobox.blockSignals(False) - sidx = self.comboBox_2.findData(self.shown_set) + sidx = self.set_combobox.findData(self.shown_set) if sidx == -1: sidx = 0 - self.comboBox_2.setCurrentIndex(sidx) - self.comboBox_2.currentIndexChanged.emit(sidx) + self.set_combobox.setCurrentIndex(sidx) + self.set_combobox.currentIndexChanged.emit(sidx) @QtCore.pyqtSlot(int) def _populate_table(self, idx): self.selection_model.clearSelection() - self.shown_set = self.comboBox_2.itemData(idx) - self.requestData.emit(self.comboBox_2.itemData(idx)) + self.shown_set = self.set_combobox.itemData(idx) + self.requestData.emit(self.set_combobox.itemData(idx)) def set_data(self, data: list, mask: np.ndarray): self.selection_model.clearSelection() @@ -97,9 +100,8 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog): menu.addSeparator() hide_action = menu.addAction('Hide/Show') - menu.addSeparator() del_action = menu.addAction('Delete') - menu.addSeparator() + split_action = menu.addAction('Split after selection') cpc_action = menu.addAction('Copy to clipboard') action = menu.exec(self.tableView.viewport().mapToGlobal(pos)) @@ -109,6 +111,8 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog): self.delete_item() elif action == cpc_action: self.copy_selection() + elif action == split_action: + self.split() def keyPressEvent(self, evt): if evt.matches(QtGui.QKeySequence.Copy): @@ -128,16 +132,21 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog): return table + @QtCore.pyqtSlot(name='on_split_button_clicked') + def split(self): + self.split_signal.emit(self.set_combobox.currentData(), + self.selection_model.selectedRows()[-1].row()+1) + @QtCore.pyqtSlot(name='on_mask_button_clicked') def mask_row(self): for r in self.selection_model.selectedRows(): self.model.setData(r, not self.model.data(r, ValueModel.maskRole), ValueModel.maskRole) - self.maskSignal.emit(self.comboBox_2.currentData(), self.model.mask) + self.maskSignal.emit(self.set_combobox.currentData(), self.model.mask) @QtCore.pyqtSlot(name='on_unmaskbutton_clicked') def unmask(self): self.model.unmask() - self.maskSignal.emit(self.comboBox_2.currentData(), self.model.mask) + self.maskSignal.emit(self.set_combobox.currentData(), self.model.mask) @QtCore.pyqtSlot(name='on_delete_button_clicked') def delete_item(self): @@ -147,7 +156,7 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog): success = self.model.removeRow(i) if success: - self.itemDeleted.emit(self.comboBox_2.currentData(), idx) + self.itemDeleted.emit(self.set_combobox.currentData(), idx) self.spinBox.setMaximum(self.spinBox.maximum()-len(idx)) @QtCore.pyqtSlot(name='on_add_button_clicked') @@ -155,18 +164,18 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog): success = self.model.addRows() if success: self.spinBox.setMaximum(self.spinBox.maximum()+1) - self.itemAdded.emit(self.comboBox_2.currentData()) + self.itemAdded.emit(self.set_combobox.currentData()) @QtCore.pyqtSlot(int, int, str) def update_items(self, col, row, val): - sid = self.comboBox_2.currentData() + sid = self.set_combobox.currentData() new_value = complex(val) new_value = new_value.real if new_value.imag == 0 else new_value self.itemChanged.emit(sid, (col, row), new_value) @QtCore.pyqtSlot(QtCore.QItemSelection, QtCore.QItemSelection) - def show_position(self, items_selected, items_deselected): + def show_position(self, *_): xvals = [] yvals = [] for idx in self.selection_model.selectedRows(): @@ -220,7 +229,7 @@ class ValueModel(QtCore.QAbstractTableModel): self.endResetModel() self.dataChanged.emit(self.index(0, 0), self.index(0, 1), [QtCore.Qt.DisplayRole]) - def data(self, idx: QtCore.QModelIndex, role=QtCore.Qt.DisplayRole) -> object: + def data(self, idx: QtCore.QModelIndex, role=QtCore.Qt.DisplayRole) -> Any: if not idx.isValid(): return @@ -252,7 +261,7 @@ class ValueModel(QtCore.QAbstractTableModel): else: return - def setData(self, idx: QtCore.QModelIndex, value: Union[str, bool], role=QtCore.Qt.DisplayRole) -> object: + def setData(self, idx: QtCore.QModelIndex, value: str | bool, role=QtCore.Qt.DisplayRole) -> Any: col, row = idx.column(), idx.row() if role == ValueModel.maskRole: @@ -280,7 +289,7 @@ class ValueModel(QtCore.QAbstractTableModel): else: return False - def headerData(self, section: int, orientation, role=QtCore.Qt.DisplayRole) -> object: + def headerData(self, section: int, orientation, role=QtCore.Qt.DisplayRole) -> Any: if role == QtCore.Qt.DisplayRole: if orientation == QtCore.Qt.Horizontal: return self.headers[section] @@ -303,7 +312,7 @@ class ValueModel(QtCore.QAbstractTableModel): self.rows_loaded += to_be_loaded self.endInsertRows() - def flags(self, idx: QtCore.QModelIndex) -> QtCore.Qt.ItemFlags: + def flags(self, idx: QtCore.QModelIndex) -> QtCore.Qt.ItemFlag: return QtCore.QAbstractTableModel.flags(self, idx) | QtCore.Qt.ItemIsEditable def removeRows(self, pos: int, rows: int, parent=None, *args, **kwargs) -> bool: diff --git a/nmreval/gui_qt/main/mainwindow.py b/nmreval/gui_qt/main/mainwindow.py index e5c6600..5eb8e42 100644 --- a/nmreval/gui_qt/main/mainwindow.py +++ b/nmreval/gui_qt/main/mainwindow.py @@ -193,6 +193,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): self.valuewidget.itemAdded.connect(self.management.append) self.valuewidget.maskSignal.connect(self.management.mask_value) self.valuewidget.values_selected.connect(self.plot_selected_values) + self.valuewidget.split_signal.connect(self.management.split_set) self.actionMaximize.triggered.connect(lambda: self.current_graph_widget.showMaximized()) self.actionNext_window.triggered.connect(lambda: self.area.activateNextSubWindow()) @@ -308,6 +309,9 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): if graph == self.fit_dialog.connected_figure: self.fit_dialog.load(self.management.graphs.active(graph)) + if self.valuewidget.isVisible(): + self.valuewidget(self.management.graphs.tree()) + @QtCore.pyqtSlot(name='on_actionDelete_window_triggered') def delete_windows(self): self.management.delete_sets() @@ -722,10 +726,6 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): for s in sets: self.datawidget.tree.move_sets(s, dest, src) - @QtCore.pyqtSlot(name='on_action_idx_cut_triggered') - def cut_with_idx(self): - print('schnippschnapp') - @QtCore.pyqtSlot(str) def show_data_values(self, sid: str): if sid == '': diff --git a/nmreval/gui_qt/main/management.py b/nmreval/gui_qt/main/management.py index 2b42314..76eced2 100644 --- a/nmreval/gui_qt/main/management.py +++ b/nmreval/gui_qt/main/management.py @@ -1029,12 +1029,25 @@ class UpperManagement(QtCore.QObject): self.newData.emit([self.add(pts)], opts['graph']) self.sender().update_graphs(self.graphs.list()) + @QtCore.pyqtSlot(str, list) def mask_value(self, idx: str, m: list): self.data[idx].mask = m + @QtCore.pyqtSlot(str, list) def remove_values(self, idx: str, m: list): self.data[idx].remove(m) + @QtCore.pyqtSlot(str, int) + def split_set(self, idx: str, row: int): + selected_data = self.data[idx] + popular_front_of_judea = selected_data.copy(full=True) + + selected_data.remove(slice(row, None)) + popular_front_of_judea.remove(slice(None, row)) + + new_id = self.add(popular_front_of_judea) + self.newData.emit([new_id], selected_data.graph) + def set_values(self, idx: str, pos: tuple, value): self.data[idx].setvalues(pos, value) diff --git a/nmreval/io/nmrreader.py b/nmreval/io/nmrreader.py index 0205762..24bd2fe 100644 --- a/nmreval/io/nmrreader.py +++ b/nmreval/io/nmrreader.py @@ -5,7 +5,7 @@ from typing import Tuple, Union from ..data.nmr import FID, Spectrum from ..data.points import Points from ..fit.result import FitResult, FitResultCreator -from .read_old_nmr import _read_file_v1 +from .read_old_nmr import HAS_BSDDB3, _read_file_v1 from ..lib.colors import Colors from ..lib.lines import LineStyle from ..lib.symbols import SymbolStyle @@ -61,6 +61,9 @@ class NMRReader: return datalist, states['graphs'] def _make_old(self, fname: str) -> dict: + if not HAS_BSDDB3: + raise IOError('Legacy .nmr cannot be read without bsddb3') + datadic = _read_file_v1(fname) datalist = OrderedDict() diff --git a/nmreval/io/read_old_nmr.py b/nmreval/io/read_old_nmr.py index 27dab68..fd8f1e4 100644 --- a/nmreval/io/read_old_nmr.py +++ b/nmreval/io/read_old_nmr.py @@ -1,3 +1,4 @@ +import warnings from copyreg import _inverted_registry, _extension_cache import sys from sys import maxsize @@ -8,7 +9,12 @@ import _compat_pickle from pickle import * from pickle import _Unframer, bytes_types, _Stop, _getattribute -import bsddb3 +try: + import bsddb3 + HAS_BSDDB3 = True +except ImportError: + warnings.warn('bsdbb3 is not installed, reading legacy .nmr files is not possible.') + HAS_BSDDB3 = False """ @@ -24,7 +30,7 @@ returns the dicts instead. There are also pickled numpy arrays but they are unpr copied the Unpickler completely. It seems that bsddb3 will be changed to berkeleydb in the future (https://www.jcea.es/programacion/pybsddb.htm) -so this might break eventually. +so this will break in the future. """ diff --git a/nmreval/nmr/relaxation.py b/nmreval/nmr/relaxation.py index 042c9d9..fba9ecb 100755 --- a/nmreval/nmr/relaxation.py +++ b/nmreval/nmr/relaxation.py @@ -358,7 +358,8 @@ class Relaxation: tau (array-like): Correlation times in s *specdens_args (optional): Additional parameter for spectral density. If given this will replace previously set arguments during calculation - inverse (bool): Function returs relaxation time if True else relaxation rate. Default is `True` + inverse (bool): Function returs relaxation time if True else relaxation rate. + Default is `True` prefactor (float, optional): If given it is used as prefactor `C` instead of previously set coupling prefactor. @@ -382,9 +383,17 @@ class Relaxation: else: return rate - def t2_dipolar(self, omega: ArrayLike, tau: ArrayLike, *specdens_args: Any, - inverse: bool = True, prefactor: float = None, omega_coup: ArrayLike = None, - gamma_coup: str = None, gamma_obs: str = None) -> np.ndarray | float: + def t2_dipolar( + self, + omega: ArrayLike, + tau: ArrayLike, + *specdens_args: Any, + inverse: bool = True, + prefactor: float = None, + omega_coup: ArrayLike = None, + gamma_coup: str = None, + gamma_obs: str = None, + ) -> np.ndarray | float: r"""Calculate T2 under heteronuclear dipolar coupling. .. math:: @@ -439,8 +448,14 @@ class Relaxation: else: return rate - def t2_csa(self, omega: ArrayLike, tau: ArrayLike, *specdens_args: Any, - inverse: bool = True, prefactor: float = None) -> np.ndarray | float: + def t2_csa( + self, + omega: ArrayLike, + tau: ArrayLike, + *specdens_args: Any, + inverse: bool = True, + prefactor: float = None, + ) -> np.ndarray | float: r"""Calculate T1 under chemical shift anisotropy. .. math:: @@ -502,9 +517,16 @@ class RelaxationEvaluation(Relaxation): self.y = t1[sortidx] self.calculate_t1_min() - def get_increase(self, height: float = None, idx: int = 0, mode: str = None, omega: float = None, - dist_parameter: tuple | list = None, prefactor: tuple | list | float = None, - coupling_kwargs: dict = None): + def get_increase( + self, + height: float = None, + idx: int = 0, + mode: str = None, + omega: float = None, + dist_parameter: tuple | list = None, + prefactor: tuple | list | float = None, + coupling_kwargs: dict = None, + ) -> None: """ Determine a single parameter from a T1 minimum. It replaces the previously set value. @@ -639,8 +661,12 @@ class RelaxationEvaluation(Relaxation): return stretching, minimon - def calculate_t1_min(self, interpolate: int = None, trange: Tuple[float, float] = None, use_log: bool = False) -> \ - Tuple[Tuple[float, float], Tuple[np.ndarray, np.ndarray] | None]: + def calculate_t1_min( + self, + interpolate: int = None, + trange: Tuple[float, float] = None, + use_log: bool = False, + ) -> Tuple[Tuple[float, float], Tuple[np.ndarray, np.ndarray] | None]: """ Determine a minimum position for given T1 data @@ -707,9 +733,16 @@ class RelaxationEvaluation(Relaxation): return t1_min, parabola - def correlation_from_t1(self, mode: str = 'raw', interpolate: bool = False, omega: float = None, - dist_parameter: list | tuple = None, prefactor: float = None, - coupling_param: list = None, coupling_kwargs: dict = None) -> Tuple[np.ndarray, dict]: + def correlation_from_t1( + self, + mode: str = 'raw', + interpolate: bool = False, + omega: float = None, + dist_parameter: list | tuple = None, + prefactor: float = None, + coupling_param: list = None, + coupling_kwargs: dict = None, + ) -> Tuple[np.ndarray, dict]: """ Calculate correlation times from set T1 data. Optional arguments overwrite previousliy set parameter. @@ -721,10 +754,11 @@ class RelaxationEvaluation(Relaxation): omega (float, optional): Larmor frequency (in 1/s) dist_parameter (list, optional): List of parameter of spectral density prefactor (float, optional): Prefactor of T1 calculation, will - coupling_param (list, optional): Parameter for coupling constant, ignored if `prefactor`is given. - coupling_kwargs (dict, optional): Keyword arguments for coupling constant, ignored if `prefactor`is given. + coupling_param (list, optional): Parameter for coupling constant, ignored if `prefactor` is given. + coupling_kwargs (dict, optional): Keyword arguments for coupling constant, ignored if `prefactor` is given. Returns: + Array of temperature and correlation times and a dictionary of used parameter during calculation. """ if self.x is None: @@ -820,13 +854,3 @@ class RelaxationEvaluation(Relaxation): opts['coupling'] = (self.coupling.name, coupling_param, coupling_kwargs) return np.c_[self.x, self.distribution.mean_value(correlation_times, *dist_parameter, mode=mode)], opts - - def _create_minimum_file(self, filename): - x = np.geomspace(0.1, 1, num=10001) - with Path(filename).open('w') as f: - f.write('# broadening\tT1_min/min_Debye\n') - for i, a in enumerate(np.geomspace(0.1, 10, num=10000)): - alpha = a - t1_i = self.t1_bpp(1, x, alpha) - f.write(f'{alpha}\t{min(t1_i) / 0.701667864144}\n') - f.flush() diff --git a/resources/_ui/basewindow.ui b/resources/_ui/basewindow.ui index 3f79593..7d72d0e 100644 --- a/resources/_ui/basewindow.ui +++ b/resources/_ui/basewindow.ui @@ -21,7 +21,7 @@