From f0448fac0ff598984d31e237b193cd342ba13b73 Mon Sep 17 00:00:00 2001 From: Dominik Demuth Date: Mon, 6 May 2024 18:46:27 +0200 Subject: [PATCH 1/2] cut data at x and y --- src/gui_qt/_py/basewindow.py | 21 ++++++++++++++++----- src/gui_qt/data/container.py | 28 +++++++++++++++++----------- src/gui_qt/main/mainwindow.py | 3 ++- src/gui_qt/main/management.py | 13 ++++++++++--- src/nmreval/data/points.py | 29 ++++++++++++++++++++--------- src/resources/_ui/basewindow.ui | 31 +++++++++++++++++++++++++------ 6 files changed, 90 insertions(+), 35 deletions(-) diff --git a/src/gui_qt/_py/basewindow.py b/src/gui_qt/_py/basewindow.py index d916548..8d23235 100644 --- a/src/gui_qt/_py/basewindow.py +++ b/src/gui_qt/_py/basewindow.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'src/resources/_ui/basewindow.ui' +# Form implementation generated from reading ui file './nmreval/src/resources/_ui/basewindow.ui' # # Created by: PyQt5 UI code generator 5.15.10 # @@ -87,6 +87,8 @@ class Ui_BaseWindow(object): self.menuSave.setObjectName("menuSave") self.menuData = QtWidgets.QMenu(self.menubar) self.menuData.setObjectName("menuData") + self.menuCut_to_visible_range = QtWidgets.QMenu(self.menuData) + self.menuCut_to_visible_range.setObjectName("menuCut_to_visible_range") self.menuHelp = QtWidgets.QMenu(self.menubar) self.menuHelp.setObjectName("menuHelp") self.menuExtra = QtWidgets.QMenu(self.menubar) @@ -304,8 +306,6 @@ class Ui_BaseWindow(object): self.actionDerivation.setObjectName("actionDerivation") self.actionIntegration = QtWidgets.QAction(BaseWindow) self.actionIntegration.setObjectName("actionIntegration") - self.action_cut = QtWidgets.QAction(BaseWindow) - self.action_cut.setObjectName("action_cut") self.actionMove_between_plots = QtWidgets.QAction(BaseWindow) self.actionMove_between_plots.setObjectName("actionMove_between_plots") self.actionBaseline = QtWidgets.QAction(BaseWindow) @@ -368,6 +368,10 @@ class Ui_BaseWindow(object): self.actionExclude_region = QtWidgets.QAction(BaseWindow) self.actionExclude_region.setCheckable(True) self.actionExclude_region.setObjectName("actionExclude_region") + self.action_cut_xaxis = QtWidgets.QAction(BaseWindow) + self.action_cut_xaxis.setObjectName("action_cut_xaxis") + self.action_cut_yaxis = QtWidgets.QAction(BaseWindow) + self.action_cut_yaxis.setObjectName("action_cut_yaxis") self.menuSave.addAction(self.actionSave) self.menuSave.addAction(self.actionExportGraphic) self.menuSave.addAction(self.action_save_fit_parameter) @@ -380,6 +384,9 @@ class Ui_BaseWindow(object): self.menuFile.addSeparator() self.menuFile.addAction(self.action_close) self.menuFile.addSeparator() + self.menuCut_to_visible_range.addSeparator() + self.menuCut_to_visible_range.addAction(self.action_cut_xaxis) + self.menuCut_to_visible_range.addAction(self.action_cut_yaxis) self.menuData.addAction(self.action_new_set) self.menuData.addAction(self.action_delete_sets) self.menuData.addAction(self.actionMove_between_plots) @@ -389,7 +396,7 @@ class Ui_BaseWindow(object): self.menuData.addAction(self.action_sort_pts) self.menuData.addAction(self.actionSkip_points) self.menuData.addSeparator() - self.menuData.addAction(self.action_cut) + self.menuData.addAction(self.menuCut_to_visible_range.menuAction()) self.menuData.addSeparator() self.menuData.addAction(self.actionChange_datatypes) self.menuHelp.addAction(self.actionShow_error_log) @@ -515,6 +522,7 @@ class Ui_BaseWindow(object): self.menuFile.setTitle(_translate("BaseWindow", "&File")) self.menuSave.setTitle(_translate("BaseWindow", "&Save...")) self.menuData.setTitle(_translate("BaseWindow", "&Data")) + self.menuCut_to_visible_range.setTitle(_translate("BaseWindow", "Cut to visible range")) self.menuHelp.setTitle(_translate("BaseWindow", "&Help")) self.menuExtra.setTitle(_translate("BaseWindow", "Math")) self.menuNormalize.setTitle(_translate("BaseWindow", "&Normalize")) @@ -608,7 +616,6 @@ class Ui_BaseWindow(object): self.actionIntegrate.setText(_translate("BaseWindow", "Integrate")) self.actionDerivation.setText(_translate("BaseWindow", "Differentiation...")) self.actionIntegration.setText(_translate("BaseWindow", "Integration...")) - self.action_cut.setText(_translate("BaseWindow", "Cut to visible range")) self.actionMove_between_plots.setText(_translate("BaseWindow", "Move sets...")) self.actionBaseline.setText(_translate("BaseWindow", "Baseline...")) self.actionCalculateT1.setText(_translate("BaseWindow", "Calculate relaxation...")) @@ -636,6 +643,10 @@ class Ui_BaseWindow(object): self.actionBinning.setText(_translate("BaseWindow", "Binning...")) self.actionTNMH.setText(_translate("BaseWindow", "TNMH...")) self.actionExclude_region.setText(_translate("BaseWindow", "Exclude region")) + self.action_cut_xaxis.setText(_translate("BaseWindow", "x axis")) + self.action_cut_xaxis.setToolTip(_translate("BaseWindow", "Remove data points outside visible x range.")) + self.action_cut_yaxis.setText(_translate("BaseWindow", "y axis")) + self.action_cut_yaxis.setToolTip(_translate("BaseWindow", "Remove data points outside visible y range. Uses real part of points.")) from ..data.datawidget.datawidget import DataWidget from ..data.integral_widget import IntegralWidget from ..data.point_select import PointSelectWidget diff --git a/src/gui_qt/data/container.py b/src/gui_qt/data/container.py index 71bf9f4..7364579 100644 --- a/src/gui_qt/data/container.py +++ b/src/gui_qt/data/container.py @@ -300,10 +300,12 @@ class ExperimentContainer(QtCore.QObject): self._relations.pop(relation_type) def _update_actions(self): - self.actions.update({'sort': self._data.sort, - 'cut': self._data.cut, - 'norm': self._data.normalize, - 'center': self.center}) + self.actions.update({ + 'sort': self._data.sort, + 'cut': self._data.cut, + 'norm': self._data.normalize, + 'center': self.center, + }) @plot_update def update(self, opts: dict): @@ -311,9 +313,11 @@ class ExperimentContainer(QtCore.QObject): def get_properties(self) -> dict: props = OrderedDict() - props['General'] = OrderedDict([('Name', self.name), - ('Value', str(self.value)), - ('Group', str(self.group))]) + props['General'] = OrderedDict([ + ('Name', self.name), + ('Value', str(self.value)), + ('Group', str(self.group)), + ]) props['Symbol'] = OrderedDict() props['Line'] = OrderedDict() @@ -480,10 +484,12 @@ class ExperimentContainer(QtCore.QObject): else: prefix = f'g[{i}].s[{j}].' - namespace = {prefix + 'x': (self.x, 'x values'), - prefix + 'y': [self.y, 'y values'], - prefix + 'y_err': (self.y_err, 'y error values'), - prefix + 'value': (self.value, str(self.value))} + namespace = { + prefix + 'x': (self.x, 'x values'), + prefix + 'y': [self.y, 'y values'], + prefix + 'y_err': (self.y_err, 'y error values'), + prefix + 'value': (self.value, str(self.value)), + } if len(self._fits) == 1: namespace.update({ diff --git a/src/gui_qt/main/mainwindow.py b/src/gui_qt/main/mainwindow.py index 7f6123b..a71ce3a 100644 --- a/src/gui_qt/main/mainwindow.py +++ b/src/gui_qt/main/mainwindow.py @@ -233,7 +233,8 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): self.action_norm_first.triggered.connect(lambda: self.management.apply('norm', ('first',))) self.action_norm_last.triggered.connect(lambda: self.management.apply('norm', ('last',))) self.action_norm_area.triggered.connect(lambda: self.management.apply('norm', ('area',))) - self.action_cut.triggered.connect(lambda: self.management.cut()) + self.action_cut_xaxis.triggered.connect(lambda: self.management.cut(True, False)) + self.action_cut_yaxis.triggered.connect(lambda: self.management.cut(False, True)) self.actionConcatenate_sets.triggered.connect(lambda: self.management.cat()) diff --git a/src/gui_qt/main/management.py b/src/gui_qt/main/management.py index 56c387a..f47362b 100644 --- a/src/gui_qt/main/management.py +++ b/src/gui_qt/main/management.py @@ -450,10 +450,17 @@ class UpperManagement(QtCore.QObject): self.undostack.push(single_undo) self.undostack.endMacro() - def cut(self): + def cut(self, x: bool = False, y: bool = False) -> None: if self.current_graph: - xlim, _ = self.graphs[self.current_graph].ranges - self.apply('cut', xlim) + xlim, ylim = self.graphs[self.current_graph].ranges + + if x is False: + xlim = (None, None) + + if y is False: + ylim = (None, None) + + self.apply('cut', (*xlim, *ylim)) @QtCore.pyqtSlot() def unmask(self): diff --git a/src/nmreval/data/points.py b/src/nmreval/data/points.py index 8332084..1f891ae 100644 --- a/src/nmreval/data/points.py +++ b/src/nmreval/data/points.py @@ -540,26 +540,37 @@ class Points: return self - def cut(self, low_lim: float = None, high_lim: float = None): + def cut(self, x_low: float = None, x_high: float = None, y_low: float = None, y_high: float = None): """ Cut Args: - low_lim: - high_lim: + x_low: Lower limit + x_high: Upper limit for x values + y_low: Lower limit + y_high: Upper limit for x valuew Returns: """ - if low_lim is None and high_lim is None: + + if x_low is None and x_high is None and y_low is None and y_high is None: return self - if low_lim is None: - low_lim = np.min(self._x) + if x_low is None: + x_low = np.min(self._x)-1 - if high_lim is None: - high_lim = np.max(self._x) + if x_high is None: + x_high = np.max(self._x)+1 - _mask = np.ma.masked_inside(self._x, low_lim, high_lim).mask + if y_low is None: + y_low = np.min(self._y.real)-1 + + if y_high is None: + y_high = np.max(self._y.real)+1 + + x_mask = (self._x >= x_low) & (self._x <= x_high) + y_mask = (self._y.real >= y_low) & (self._y.real <= y_high) + _mask = x_mask & y_mask self._x = self._x[_mask] self._y = self._y[_mask] diff --git a/src/resources/_ui/basewindow.ui b/src/resources/_ui/basewindow.ui index 01987b8..85c1f68 100644 --- a/src/resources/_ui/basewindow.ui +++ b/src/resources/_ui/basewindow.ui @@ -172,6 +172,14 @@ &Data + + + Cut to visible range + + + + + @@ -181,7 +189,7 @@ - + @@ -862,11 +870,6 @@ Integration... - - - Cut to visible range - - Move sets... @@ -1030,6 +1033,22 @@ Exclude region + + + x axis + + + Remove data points outside visible x range. + + + + + y axis + + + Remove data points outside visible y range. Uses real part of points. + + From ef66cf584a79c4b843e404e24739f9764617ebb2 Mon Sep 17 00:00:00 2001 From: Dominik Demuth Date: Mon, 6 May 2024 18:52:20 +0200 Subject: [PATCH 2/2] increase precision --- src/gui_qt/data/valueeditwidget.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui_qt/data/valueeditwidget.py b/src/gui_qt/data/valueeditwidget.py index ae95a5f..de2376b 100644 --- a/src/gui_qt/data/valueeditwidget.py +++ b/src/gui_qt/data/valueeditwidget.py @@ -385,6 +385,6 @@ class ValueModel(QtCore.QAbstractTableModel): @staticmethod def as_string(value) -> str: if isinstance(value, complex): - return f'{value.real:.8g}{value.imag:+.8g}j' + return f'{value.real:.13g}{value.imag:+.13g}j' else: - return f'{value:.8g}' + return f'{value:.13g}'