split data at given index

This commit is contained in:
dominik 2022-04-03 16:42:44 +02:00
parent e19d32b736
commit 531eac22b7
16 changed files with 190 additions and 227 deletions

View File

@ -4,27 +4,27 @@
.. autoclass:: {{ objname }} .. autoclass:: {{ objname }}
{% block methods %} {%- block methods %}
{% if methods %} {% if methods %}
.. rubric:: {{ _('Methods') }} .. rubric:: {{ _('Methods') }}
{% for item in methods %} {%- for item in methods %}
{% if not item.startswith('_') %} {% if not item.startswith('_') %}
.. automethod:: {{ item }} .. automethod:: {{ item }}
{%- endif %} {%- endif %}
{%- endfor %} {%- endfor %}
{% endif %} {%- endif %}
{% endblock %} {% endblock %}
{% block attributes %} {%- block attributes %}
{% if attributes %} {%- if attributes %}
.. rubric:: {{ _('Attributes') }} .. rubric:: {{ _('Attributes') }}
{% for item in attributes %} {% for item in attributes %}
.. autoattribute:: {{ item }} .. autoattribute:: {{ item }}
{%- endfor %} {%- endfor %}
{% endif %} {% endif %}
{% endblock %} {% endblock -%}
.. include:: {{ fullname }}.examples .. include:: {{ fullname }}.examples

View File

@ -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:

View File

@ -1,6 +0,0 @@
************************
``nmreval.models.basic``
************************
.. automodule:: nmreval.models.basic
:members:

View File

@ -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:

View File

@ -1,37 +0,0 @@
nmreval.models.basic
====================
.. automodule:: nmreval.models.basic
.. rubric:: Classes
.. autosummary::
Constant
ExpFunc
Linear
Log
MittagLeffler
Parabola
PowerLaw
PowerLawCross
Sine

View File

@ -510,7 +510,7 @@ class Points:
return self return self
def cut(self, low_lim=None, high_lim=None): def cut(self, low_lim: float = None, high_lim: float = None):
""" """
Cut Cut
Args: Args:

View File

@ -18,10 +18,10 @@ class Ui_BaseWindow(object):
BaseWindow.setDockOptions(QtWidgets.QMainWindow.AllowTabbedDocks|QtWidgets.QMainWindow.AnimatedDocks|QtWidgets.QMainWindow.ForceTabbedDocks|QtWidgets.QMainWindow.VerticalTabs) BaseWindow.setDockOptions(QtWidgets.QMainWindow.AllowTabbedDocks|QtWidgets.QMainWindow.AnimatedDocks|QtWidgets.QMainWindow.ForceTabbedDocks|QtWidgets.QMainWindow.VerticalTabs)
self.centralwidget = QtWidgets.QWidget(BaseWindow) self.centralwidget = QtWidgets.QWidget(BaseWindow)
self.centralwidget.setObjectName("centralwidget") self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget) self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
self.verticalLayout.setContentsMargins(3, 3, 3, 3) self.horizontalLayout.setContentsMargins(3, 3, 3, 3)
self.verticalLayout.setSpacing(3) self.horizontalLayout.setSpacing(3)
self.verticalLayout.setObjectName("verticalLayout") self.horizontalLayout.setObjectName("horizontalLayout")
self.splitter = QtWidgets.QSplitter(self.centralwidget) self.splitter = QtWidgets.QSplitter(self.centralwidget)
self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setOrientation(QtCore.Qt.Horizontal)
self.splitter.setObjectName("splitter") self.splitter.setObjectName("splitter")
@ -63,7 +63,7 @@ class Ui_BaseWindow(object):
self.tabWidget.addTab(self.t1tauwidget, icon5, "") self.tabWidget.addTab(self.t1tauwidget, icon5, "")
self.area = QtWidgets.QMdiArea(self.splitter) self.area = QtWidgets.QMdiArea(self.splitter)
self.area.setObjectName("area") self.area.setObjectName("area")
self.verticalLayout.addWidget(self.splitter) self.horizontalLayout.addWidget(self.splitter)
BaseWindow.setCentralWidget(self.centralwidget) BaseWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(BaseWindow) self.menubar = QtWidgets.QMenuBar(BaseWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1388, 30)) self.menubar.setGeometry(QtCore.QRect(0, 0, 1388, 30))
@ -503,11 +503,11 @@ class Ui_BaseWindow(object):
self.menuBDS.setTitle(_translate("BaseWindow", "BDS")) self.menuBDS.setTitle(_translate("BaseWindow", "BDS"))
self.menuSpectrum.setTitle(_translate("BaseWindow", "Spectrum")) self.menuSpectrum.setTitle(_translate("BaseWindow", "Spectrum"))
self.toolBar.setWindowTitle(_translate("BaseWindow", "Main")) 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_nmr.setWindowTitle(_translate("BaseWindow", "NMR"))
self.toolBar_fit.setWindowTitle(_translate("BaseWindow", "Fit")) self.toolBar_fit.setWindowTitle(_translate("BaseWindow", "Fit"))
self.toolBar_spectrum.setWindowTitle(_translate("BaseWindow", "Spectrum")) 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.setText(_translate("BaseWindow", "&Quit"))
self.action_close.setShortcut(_translate("BaseWindow", "Ctrl+Q")) self.action_close.setShortcut(_translate("BaseWindow", "Ctrl+Q"))
self.actionExportGraphic.setText(_translate("BaseWindow", "Export graphic...")) self.actionExportGraphic.setText(_translate("BaseWindow", "Export graphic..."))

View File

@ -18,12 +18,12 @@ class Ui_MaskDialog(object):
self.verticalLayout.setContentsMargins(3, 3, 3, 3) self.verticalLayout.setContentsMargins(3, 3, 3, 3)
self.verticalLayout.setSpacing(3) self.verticalLayout.setSpacing(3)
self.verticalLayout.setObjectName("verticalLayout") self.verticalLayout.setObjectName("verticalLayout")
self.comboBox = QtWidgets.QComboBox(MaskDialog) self.graph_combobox = QtWidgets.QComboBox(MaskDialog)
self.comboBox.setObjectName("comboBox") self.graph_combobox.setObjectName("graph_combobox")
self.verticalLayout.addWidget(self.comboBox) self.verticalLayout.addWidget(self.graph_combobox)
self.comboBox_2 = QtWidgets.QComboBox(MaskDialog) self.set_combobox = QtWidgets.QComboBox(MaskDialog)
self.comboBox_2.setObjectName("comboBox_2") self.set_combobox.setObjectName("set_combobox")
self.verticalLayout.addWidget(self.comboBox_2) self.verticalLayout.addWidget(self.set_combobox)
self.tableView = QtWidgets.QTableView(MaskDialog) self.tableView = QtWidgets.QTableView(MaskDialog)
self.tableView.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.tableView.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
self.tableView.setObjectName("tableView") self.tableView.setObjectName("tableView")
@ -51,22 +51,25 @@ class Ui_MaskDialog(object):
self.gridLayout.setContentsMargins(-1, 0, -1, -1) self.gridLayout.setContentsMargins(-1, 0, -1, -1)
self.gridLayout.setSpacing(3) self.gridLayout.setSpacing(3)
self.gridLayout.setObjectName("gridLayout") 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) self.add_button = QtWidgets.QPushButton(MaskDialog)
icon = QtGui.QIcon.fromTheme("list-add") icon = QtGui.QIcon.fromTheme("list-add")
self.add_button.setIcon(icon) self.add_button.setIcon(icon)
self.add_button.setObjectName("add_button") 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 = QtWidgets.QPushButton(MaskDialog)
self.mask_button.setObjectName("mask_button") 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.verticalLayout.addLayout(self.gridLayout)
self.label.setBuddy(self.spinBox) self.label.setBuddy(self.spinBox)
@ -78,8 +81,9 @@ class Ui_MaskDialog(object):
MaskDialog.setWindowTitle(_translate("MaskDialog", "Form")) MaskDialog.setWindowTitle(_translate("MaskDialog", "Form"))
self.label.setText(_translate("MaskDialog", "Go to line:")) self.label.setText(_translate("MaskDialog", "Go to line:"))
self.toolButton.setText(_translate("MaskDialog", "Go Go Power Rangers!")) 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.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", "<html><head/><body><p>Masked rows are shown in green</p></body></html>")) self.mask_button.setToolTip(_translate("MaskDialog", "<html><head/><body><p>Masked rows are shown in green</p></body></html>"))
self.mask_button.setText(_translate("MaskDialog", "Hide/Show selected")) self.mask_button.setText(_translate("MaskDialog", "Hide/Show selected"))
self.unmaskbutton.setText(_translate("MaskDialog", "Show all"))

View File

@ -1,4 +1,6 @@
from typing import Union, List from __future__ import annotations
from typing import Any, List
import numpy as np import numpy as np
@ -13,6 +15,7 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog):
itemDeleted = QtCore.pyqtSignal(str, list) itemDeleted = QtCore.pyqtSignal(str, list)
itemAdded = QtCore.pyqtSignal(str) itemAdded = QtCore.pyqtSignal(str)
values_selected = QtCore.pyqtSignal(str, list, list) values_selected = QtCore.pyqtSignal(str, list, list)
split_signal = QtCore.pyqtSignal(str, int)
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent=parent) super().__init__(parent=parent)
@ -34,54 +37,54 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog):
self.tableView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.tableView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.tableView.customContextMenuRequested.connect(self.ctx) self.tableView.customContextMenuRequested.connect(self.ctx)
self.comboBox.currentIndexChanged.connect(self._populate_sets) self.graph_combobox.currentIndexChanged.connect(self._populate_sets)
self.comboBox_2.currentIndexChanged.connect(self._populate_table) self.set_combobox.currentIndexChanged.connect(self._populate_table)
def __call__(self, items: dict): def __call__(self, items: dict):
self.items = items self.items = items
self.comboBox.blockSignals(True) self.graph_combobox.blockSignals(True)
self.comboBox.clear() self.graph_combobox.clear()
for k, v in items.items(): for k, v in items.items():
self.comboBox.addItem(k[1], userData=k[0]) self.graph_combobox.addItem(k[1], userData=k[0])
self.comboBox.blockSignals(False) self.graph_combobox.blockSignals(False)
idx = self.comboBox.findData(self.graph_shown) idx = self.graph_combobox.findData(self.graph_shown)
if idx == -1: if idx == -1:
idx = 0 idx = 0
self.comboBox.setCurrentIndex(idx) self.graph_combobox.setCurrentIndex(idx)
self.comboBox.currentIndexChanged.emit(idx) self.graph_combobox.currentIndexChanged.emit(idx)
return self return self
@QtCore.pyqtSlot(int) @QtCore.pyqtSlot(int)
def _populate_sets(self, idx: int): def _populate_sets(self, idx: int):
if idx == -1: if idx == -1:
self.comboBox.setCurrentIndex(0) self.graph_combobox.setCurrentIndex(0)
return return
self.comboBox_2.blockSignals(True) self.set_combobox.blockSignals(True)
self.comboBox_2.clear() self.set_combobox.clear()
self.graph_shown = self.comboBox.currentData() self.graph_shown = self.graph_combobox.currentData()
if self.items: if self.items:
for sid, name in self.items[(self.comboBox.currentData(), self.comboBox.currentText())]: for sid, name in self.items[(self.graph_combobox.currentData(), self.graph_combobox.currentText())]:
self.comboBox_2.addItem(name, userData=sid) self.set_combobox.addItem(name, userData=sid)
self.comboBox_2.blockSignals(False) self.set_combobox.blockSignals(False)
sidx = self.comboBox_2.findData(self.shown_set) sidx = self.set_combobox.findData(self.shown_set)
if sidx == -1: if sidx == -1:
sidx = 0 sidx = 0
self.comboBox_2.setCurrentIndex(sidx) self.set_combobox.setCurrentIndex(sidx)
self.comboBox_2.currentIndexChanged.emit(sidx) self.set_combobox.currentIndexChanged.emit(sidx)
@QtCore.pyqtSlot(int) @QtCore.pyqtSlot(int)
def _populate_table(self, idx): def _populate_table(self, idx):
self.selection_model.clearSelection() self.selection_model.clearSelection()
self.shown_set = self.comboBox_2.itemData(idx) self.shown_set = self.set_combobox.itemData(idx)
self.requestData.emit(self.comboBox_2.itemData(idx)) self.requestData.emit(self.set_combobox.itemData(idx))
def set_data(self, data: list, mask: np.ndarray): def set_data(self, data: list, mask: np.ndarray):
self.selection_model.clearSelection() self.selection_model.clearSelection()
@ -97,9 +100,8 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog):
menu.addSeparator() menu.addSeparator()
hide_action = menu.addAction('Hide/Show') hide_action = menu.addAction('Hide/Show')
menu.addSeparator()
del_action = menu.addAction('Delete') del_action = menu.addAction('Delete')
menu.addSeparator() split_action = menu.addAction('Split after selection')
cpc_action = menu.addAction('Copy to clipboard') cpc_action = menu.addAction('Copy to clipboard')
action = menu.exec(self.tableView.viewport().mapToGlobal(pos)) action = menu.exec(self.tableView.viewport().mapToGlobal(pos))
@ -109,6 +111,8 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog):
self.delete_item() self.delete_item()
elif action == cpc_action: elif action == cpc_action:
self.copy_selection() self.copy_selection()
elif action == split_action:
self.split()
def keyPressEvent(self, evt): def keyPressEvent(self, evt):
if evt.matches(QtGui.QKeySequence.Copy): if evt.matches(QtGui.QKeySequence.Copy):
@ -128,16 +132,21 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog):
return table 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') @QtCore.pyqtSlot(name='on_mask_button_clicked')
def mask_row(self): def mask_row(self):
for r in self.selection_model.selectedRows(): for r in self.selection_model.selectedRows():
self.model.setData(r, not self.model.data(r, ValueModel.maskRole), ValueModel.maskRole) 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') @QtCore.pyqtSlot(name='on_unmaskbutton_clicked')
def unmask(self): def unmask(self):
self.model.unmask() 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') @QtCore.pyqtSlot(name='on_delete_button_clicked')
def delete_item(self): def delete_item(self):
@ -147,7 +156,7 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog):
success = self.model.removeRow(i) success = self.model.removeRow(i)
if success: 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)) self.spinBox.setMaximum(self.spinBox.maximum()-len(idx))
@QtCore.pyqtSlot(name='on_add_button_clicked') @QtCore.pyqtSlot(name='on_add_button_clicked')
@ -155,18 +164,18 @@ class ValueEditWidget(QtWidgets.QWidget, Ui_MaskDialog):
success = self.model.addRows() success = self.model.addRows()
if success: if success:
self.spinBox.setMaximum(self.spinBox.maximum()+1) 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) @QtCore.pyqtSlot(int, int, str)
def update_items(self, col, row, val): def update_items(self, col, row, val):
sid = self.comboBox_2.currentData() sid = self.set_combobox.currentData()
new_value = complex(val) new_value = complex(val)
new_value = new_value.real if new_value.imag == 0 else new_value new_value = new_value.real if new_value.imag == 0 else new_value
self.itemChanged.emit(sid, (col, row), new_value) self.itemChanged.emit(sid, (col, row), new_value)
@QtCore.pyqtSlot(QtCore.QItemSelection, QtCore.QItemSelection) @QtCore.pyqtSlot(QtCore.QItemSelection, QtCore.QItemSelection)
def show_position(self, items_selected, items_deselected): def show_position(self, *_):
xvals = [] xvals = []
yvals = [] yvals = []
for idx in self.selection_model.selectedRows(): for idx in self.selection_model.selectedRows():
@ -220,7 +229,7 @@ class ValueModel(QtCore.QAbstractTableModel):
self.endResetModel() self.endResetModel()
self.dataChanged.emit(self.index(0, 0), self.index(0, 1), [QtCore.Qt.DisplayRole]) self.dataChanged.emit(self.index(0, 0), self.index(0, 1), [QtCore.Qt.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(): if not idx.isValid():
return return
@ -252,7 +261,7 @@ class ValueModel(QtCore.QAbstractTableModel):
else: else:
return 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() col, row = idx.column(), idx.row()
if role == ValueModel.maskRole: if role == ValueModel.maskRole:
@ -280,7 +289,7 @@ class ValueModel(QtCore.QAbstractTableModel):
else: else:
return False 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 role == QtCore.Qt.DisplayRole:
if orientation == QtCore.Qt.Horizontal: if orientation == QtCore.Qt.Horizontal:
return self.headers[section] return self.headers[section]
@ -303,7 +312,7 @@ class ValueModel(QtCore.QAbstractTableModel):
self.rows_loaded += to_be_loaded self.rows_loaded += to_be_loaded
self.endInsertRows() 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 return QtCore.QAbstractTableModel.flags(self, idx) | QtCore.Qt.ItemIsEditable
def removeRows(self, pos: int, rows: int, parent=None, *args, **kwargs) -> bool: def removeRows(self, pos: int, rows: int, parent=None, *args, **kwargs) -> bool:

View File

@ -193,6 +193,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
self.valuewidget.itemAdded.connect(self.management.append) self.valuewidget.itemAdded.connect(self.management.append)
self.valuewidget.maskSignal.connect(self.management.mask_value) self.valuewidget.maskSignal.connect(self.management.mask_value)
self.valuewidget.values_selected.connect(self.plot_selected_values) 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.actionMaximize.triggered.connect(lambda: self.current_graph_widget.showMaximized())
self.actionNext_window.triggered.connect(lambda: self.area.activateNextSubWindow()) 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: if graph == self.fit_dialog.connected_figure:
self.fit_dialog.load(self.management.graphs.active(graph)) 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') @QtCore.pyqtSlot(name='on_actionDelete_window_triggered')
def delete_windows(self): def delete_windows(self):
self.management.delete_sets() self.management.delete_sets()
@ -722,10 +726,6 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
for s in sets: for s in sets:
self.datawidget.tree.move_sets(s, dest, src) 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) @QtCore.pyqtSlot(str)
def show_data_values(self, sid: str): def show_data_values(self, sid: str):
if sid == '': if sid == '':

View File

@ -1029,12 +1029,25 @@ class UpperManagement(QtCore.QObject):
self.newData.emit([self.add(pts)], opts['graph']) self.newData.emit([self.add(pts)], opts['graph'])
self.sender().update_graphs(self.graphs.list()) self.sender().update_graphs(self.graphs.list())
@QtCore.pyqtSlot(str, list)
def mask_value(self, idx: str, m: list): def mask_value(self, idx: str, m: list):
self.data[idx].mask = m self.data[idx].mask = m
@QtCore.pyqtSlot(str, list)
def remove_values(self, idx: str, m: list): def remove_values(self, idx: str, m: list):
self.data[idx].remove(m) 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): def set_values(self, idx: str, pos: tuple, value):
self.data[idx].setvalues(pos, value) self.data[idx].setvalues(pos, value)

View File

@ -5,7 +5,7 @@ from typing import Tuple, Union
from ..data.nmr import FID, Spectrum from ..data.nmr import FID, Spectrum
from ..data.points import Points from ..data.points import Points
from ..fit.result import FitResult, FitResultCreator 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.colors import Colors
from ..lib.lines import LineStyle from ..lib.lines import LineStyle
from ..lib.symbols import SymbolStyle from ..lib.symbols import SymbolStyle
@ -61,6 +61,9 @@ class NMRReader:
return datalist, states['graphs'] return datalist, states['graphs']
def _make_old(self, fname: str) -> dict: 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) datadic = _read_file_v1(fname)
datalist = OrderedDict() datalist = OrderedDict()

View File

@ -1,3 +1,4 @@
import warnings
from copyreg import _inverted_registry, _extension_cache from copyreg import _inverted_registry, _extension_cache
import sys import sys
from sys import maxsize from sys import maxsize
@ -8,7 +9,12 @@ import _compat_pickle
from pickle import * from pickle import *
from pickle import _Unframer, bytes_types, _Stop, _getattribute from pickle import _Unframer, bytes_types, _Stop, _getattribute
try:
import bsddb3 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. copied the Unpickler completely.
It seems that bsddb3 will be changed to berkeleydb in the future (https://www.jcea.es/programacion/pybsddb.htm) 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.
""" """

View File

@ -358,7 +358,8 @@ class Relaxation:
tau (array-like): Correlation times in s tau (array-like): Correlation times in s
*specdens_args (optional): Additional parameter for spectral density. *specdens_args (optional): Additional parameter for spectral density.
If given this will replace previously set arguments during calculation 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` prefactor (float, optional): If given it is used as prefactor `C`
instead of previously set coupling prefactor. instead of previously set coupling prefactor.
@ -382,9 +383,17 @@ class Relaxation:
else: else:
return rate return rate
def t2_dipolar(self, omega: ArrayLike, tau: ArrayLike, *specdens_args: Any, def t2_dipolar(
inverse: bool = True, prefactor: float = None, omega_coup: ArrayLike = None, self,
gamma_coup: str = None, gamma_obs: str = None) -> np.ndarray | float: 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. r"""Calculate T2 under heteronuclear dipolar coupling.
.. math:: .. math::
@ -439,8 +448,14 @@ class Relaxation:
else: else:
return rate return rate
def t2_csa(self, omega: ArrayLike, tau: ArrayLike, *specdens_args: Any, def t2_csa(
inverse: bool = True, prefactor: float = None) -> np.ndarray | float: self,
omega: ArrayLike,
tau: ArrayLike,
*specdens_args: Any,
inverse: bool = True,
prefactor: float = None,
) -> np.ndarray | float:
r"""Calculate T1 under chemical shift anisotropy. r"""Calculate T1 under chemical shift anisotropy.
.. math:: .. math::
@ -502,9 +517,16 @@ class RelaxationEvaluation(Relaxation):
self.y = t1[sortidx] self.y = t1[sortidx]
self.calculate_t1_min() self.calculate_t1_min()
def get_increase(self, height: float = None, idx: int = 0, mode: str = None, omega: float = None, def get_increase(
dist_parameter: tuple | list = None, prefactor: tuple | list | float = None, self,
coupling_kwargs: dict = None): 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. Determine a single parameter from a T1 minimum.
It replaces the previously set value. It replaces the previously set value.
@ -639,8 +661,12 @@ class RelaxationEvaluation(Relaxation):
return stretching, minimon return stretching, minimon
def calculate_t1_min(self, interpolate: int = None, trange: Tuple[float, float] = None, use_log: bool = False) -> \ def calculate_t1_min(
Tuple[Tuple[float, float], Tuple[np.ndarray, np.ndarray] | None]: 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 Determine a minimum position for given T1 data
@ -707,9 +733,16 @@ class RelaxationEvaluation(Relaxation):
return t1_min, parabola return t1_min, parabola
def correlation_from_t1(self, mode: str = 'raw', interpolate: bool = False, omega: float = None, def correlation_from_t1(
dist_parameter: list | tuple = None, prefactor: float = None, self,
coupling_param: list = None, coupling_kwargs: dict = None) -> Tuple[np.ndarray, dict]: 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. Calculate correlation times from set T1 data.
Optional arguments overwrite previousliy set parameter. Optional arguments overwrite previousliy set parameter.
@ -725,6 +758,7 @@ class RelaxationEvaluation(Relaxation):
coupling_kwargs (dict, optional): Keyword arguments for coupling constant, ignored if `prefactor` is given. coupling_kwargs (dict, optional): Keyword arguments for coupling constant, ignored if `prefactor` is given.
Returns: Returns:
Array of temperature and correlation times and a dictionary of used parameter during calculation.
""" """
if self.x is None: if self.x is None:
@ -820,13 +854,3 @@ class RelaxationEvaluation(Relaxation):
opts['coupling'] = (self.coupling.name, coupling_param, coupling_kwargs) 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 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()

View File

@ -21,7 +21,7 @@
<set>QMainWindow::AllowTabbedDocks|QMainWindow::AnimatedDocks|QMainWindow::ForceTabbedDocks|QMainWindow::VerticalTabs</set> <set>QMainWindow::AllowTabbedDocks|QMainWindow::AnimatedDocks|QMainWindow::ForceTabbedDocks|QMainWindow::VerticalTabs</set>
</property> </property>
<widget class="QWidget" name="centralwidget"> <widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing"> <property name="spacing">
<number>3</number> <number>3</number>
</property> </property>
@ -365,7 +365,7 @@
</sizepolicy> </sizepolicy>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Edit</string> <string>Math</string>
</property> </property>
<property name="iconSize"> <property name="iconSize">
<size> <size>
@ -469,7 +469,7 @@
</sizepolicy> </sizepolicy>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>toolBar_2</string> <string>Data</string>
</property> </property>
<property name="iconSize"> <property name="iconSize">
<size> <size>

View File

@ -30,10 +30,10 @@
<number>3</number> <number>3</number>
</property> </property>
<item> <item>
<widget class="QComboBox" name="comboBox"/> <widget class="QComboBox" name="graph_combobox"/>
</item> </item>
<item> <item>
<widget class="QComboBox" name="comboBox_2"/> <widget class="QComboBox" name="set_combobox"/>
</item> </item>
<item> <item>
<widget class="QTableView" name="tableView"> <widget class="QTableView" name="tableView">
@ -103,25 +103,7 @@
<property name="spacing"> <property name="spacing">
<number>3</number> <number>3</number>
</property> </property>
<item row="1" column="0"> <item row="0" column="0" colspan="2">
<widget class="QPushButton" name="unmaskbutton">
<property name="text">
<string>Show all</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="delete_button">
<property name="text">
<string>Delete rows</string>
</property>
<property name="icon">
<iconset theme="list-remove">
<normaloff>../../../auswerteprogramm/auswerten/ui</normaloff>../../../auswerteprogramm/auswerten/ui</iconset>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="add_button"> <widget class="QPushButton" name="add_button">
<property name="text"> <property name="text">
<string>Add row</string> <string>Add row</string>
@ -132,7 +114,25 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="0" column="2" colspan="2">
<widget class="QPushButton" name="delete_button">
<property name="text">
<string>Delete rows</string>
</property>
<property name="icon">
<iconset theme="list-remove">
<normaloff>../../../auswerteprogramm/auswerten/ui</normaloff>../../../auswerteprogramm/auswerten/ui</iconset>
</property>
</widget>
</item>
<item row="0" column="4" colspan="2">
<widget class="QPushButton" name="split_button">
<property name="text">
<string>Split after selection</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="QPushButton" name="mask_button"> <widget class="QPushButton" name="mask_button">
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Masked rows are shown in green&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Masked rows are shown in green&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -142,6 +142,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="3" colspan="3">
<widget class="QPushButton" name="unmaskbutton">
<property name="text">
<string>Show all</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>