From bc034cf4f459bbc65b2587a159e625c06585e4d2 Mon Sep 17 00:00:00 2001 From: Dominik Demuth Date: Wed, 12 Apr 2023 17:27:05 +0200 Subject: [PATCH 1/9] set region flag correctly --- src/gui_qt/io/fcbatchreader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui_qt/io/fcbatchreader.py b/src/gui_qt/io/fcbatchreader.py index 0cffdd2..007de7e 100644 --- a/src/gui_qt/io/fcbatchreader.py +++ b/src/gui_qt/io/fcbatchreader.py @@ -72,7 +72,7 @@ class QFCReader(QtWidgets.QDialog, Ui_FCEval_dialog): self.close() def read(self, items): - region = (None, None) + region = None if self.region_box.isChecked(): start = None if self.start_lineedit.text(): From 0251dea5637c372c7ee8cc79514e8ce0e66d1ee9 Mon Sep 17 00:00:00 2001 From: Dominik Demuth Date: Wed, 12 Apr 2023 17:28:12 +0200 Subject: [PATCH 2/9] uncheck fits in data_table --- src/gui_qt/fit/fitwindow.py | 7 +++++++ src/gui_qt/main/management.py | 1 + 2 files changed, 8 insertions(+) diff --git a/src/gui_qt/fit/fitwindow.py b/src/gui_qt/fit/fitwindow.py index 60ea5b2..f258dda 100644 --- a/src/gui_qt/fit/fitwindow.py +++ b/src/gui_qt/fit/fitwindow.py @@ -148,6 +148,13 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog): Add name and id of dataset to list. """ self.data_table.load(ids) + + # deselect all fit sets + for i in range(self.data_table.rowCount()): + data_id = self.data_table.item(i, 0).data(QtCore.Qt.UserRole+1) + if self._management[data_id].mode == 'fit': + self.data_table.item(i, 0).setCheckState(QtCore.Qt.Unchecked) + if self.models: for m in self.models.keys(): self.data_table.add_model(m) diff --git a/src/gui_qt/main/management.py b/src/gui_qt/main/management.py index 1c7000b..c8c21e1 100644 --- a/src/gui_qt/main/management.py +++ b/src/gui_qt/main/management.py @@ -605,6 +605,7 @@ class UpperManagement(QtCore.QObject): if not graph_id: graph_id = '' + # TODO add flag that new window will not get focus, because it messes up the data_table in fitwindow self.newData.emit(p_id_list, graph_id) def save_fit_parameter(self, fname: str | pathlib.Path, fit_sets: list[str] = None): From 3793f67951e73200250915033adf1c4e07533a90 Mon Sep 17 00:00:00 2001 From: Dominik Demuth Date: Wed, 12 Apr 2023 20:01:27 +0200 Subject: [PATCH 3/9] rate and time in exponential function was switched --- src/nmreval/models/basic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nmreval/models/basic.py b/src/nmreval/models/basic.py index 6ce6c3b..98be0f8 100644 --- a/src/nmreval/models/basic.py +++ b/src/nmreval/models/basic.py @@ -224,9 +224,9 @@ class ExpFunc: @staticmethod def func(x, c, x0, beta, pm: int = -1, mode: str = 'time'): if mode == 'time': - return c * np.exp(np.sign(pm) * (x0 * x) ** beta) - elif mode == 'rate': return c * np.exp(np.sign(pm) * (x / x0) ** beta) + elif mode == 'rate': + return c * np.exp(np.sign(pm) * (x * x0) ** beta) else: raise ValueError('Unknown mode %s. Use either "rate" or "time".' % str(mode)) From 29518b9ea0962952913ac32f4470ec5633ddaf1f Mon Sep 17 00:00:00 2001 From: Dominik Demuth Date: Wed, 12 Apr 2023 20:42:33 +0200 Subject: [PATCH 4/9] newer FC scripts are working, now older ones fail --- AppImageBuilder.yml | 2 +- src/nmreval/io/fcbatchreader.py | 268 ++++++++++++-------------------- src/nmreval/io/hdfreader.py | 11 +- 3 files changed, 106 insertions(+), 175 deletions(-) diff --git a/AppImageBuilder.yml b/AppImageBuilder.yml index dae00b6..7611f65 100644 --- a/AppImageBuilder.yml +++ b/AppImageBuilder.yml @@ -42,6 +42,7 @@ AppDir: - python3.9-minimal - python3-numpy - python3-scipy + - gnuplot-nox - python3-bsddb3 - python3-h5py - python3-pyqt5 @@ -57,7 +58,6 @@ AppDir: - qtbase5-dev-tools - qtchooser - pyqt5-dev-tools - - qtchooser - libavahi-client3 - libavahi-common-data - libavahi-common3 diff --git a/src/nmreval/io/fcbatchreader.py b/src/nmreval/io/fcbatchreader.py index 8c1258b..e27be6f 100644 --- a/src/nmreval/io/fcbatchreader.py +++ b/src/nmreval/io/fcbatchreader.py @@ -2,6 +2,7 @@ from __future__ import annotations import pathlib +from matplotlib import pyplot as plt # import matplotlib.pyplot as plt from scipy.optimize import curve_fit import numpy as np @@ -14,6 +15,7 @@ from nmreval.utils.utils import get_temperature, roundrobin class FCReader: def __init__(self, fname: (list | str | pathlib.Path)): + print('Hello') if isinstance(fname, (str, pathlib.Path)): self.fnames = [fname] else: @@ -25,8 +27,6 @@ class FCReader: self.t_params = {} self.f_params = {} - self._scipt_type = 'old' - def __call__(self, fname: (list | str | pathlib.Path)): if isinstance(fname, (str, pathlib.Path)): self.fnames = [fname] @@ -77,7 +77,14 @@ class FCReader: def _read_from_hdf(self, filename: (str | pathlib.Path)) -> dict: _temp = {} reader = HdfReader(filename) - mag_directory = 'mag' if self._scipt_type == 'old' else 'Magnetization' + + mag_directory = 'Magnetization' + for m in ['Magnetization', 'mag']: + try: + mag_directory = m + except KeyError: + continue + for mag in reader.get_selected(mag_directory, dtype='points'): _temp[mag.value] = mag @@ -97,21 +104,15 @@ class FCReader: return _temp - @staticmethod - def _read_signals(filename, region: tuple = None) -> dict: + def _read_signals(self, filename, region: tuple = None) -> dict: reader = HdfReader(filename) - start = 0 - stop = 30e-5 - # This is one set with attributes to find default start:stop values - try: - p = reader.parameters('/ABS_ACC_FID') - start = p['start'] - stop = p['stop'] - except: - pass + # This is one set with attributes to find default start:stop values (with some + p = reader.parameters('/ABS_ACC_FID') + start = p.get('stainte') or p.get('start') or 0 + stop = p.get('stointe') or p.get('stop') or 30e-5 - if region is None: + if region == (None, None) or region is None: region = (start, stop) if region[0] is None: @@ -119,15 +120,35 @@ class FCReader: if region[1] is None: region = (region[0], stop) - sig = reader.get_selected('/data/B=*/ACC_ABS_FID*', dtype='signal') _temp = {} - for s in sig: - pts = s.points([region]) - b = s.group - if b not in _temp: - _temp[b] = [] + bevo_groups = reader['data'].children + for grp in bevo_groups.values(): + for k in grp.data(): + print(k) + if str(k.parent) != 'ACC_ABS_FID_sig (group)': + continue - _temp[b].append([s.value, *[pp[1] for pp in pts]]) + print(k.path, k, k.parent, k.parameter['bevo'], k.parameter['tevo']) + bevo = k.parameter['bevo'] + tevo = k.parameter['tevo'] + + s = reader.make_signal(k, flag='fid', value='tevo', group='bevo') + pts = s.points([region]) + + if bevo not in _temp: + _temp[bevo] = [] + + _temp[bevo].append((tevo, *[pp[1] for pp in pts])) + + # sig = reader.get_selected('/data/B=*/ACC_ABS_FID*', dtype='signal') + # _temp = {} + # for s in sig: + # pts = s.points([region]) + # b = s.group + # if b not in _temp: + # _temp[b] = [] + # + # _temp[b].append([s.value, *[pp[1] for pp in pts]]) for b, m in sorted(_temp.items()): m = np.array(m) @@ -148,9 +169,9 @@ class FCReader: fit_path = fname_no_ext.joinpath('fit') fit_path.mkdir(parents=True, exist_ok=True) - # if save_fig: - # image_path = fname_no_ext.joinpath('png') - # image_path.mkdir(parents=True, exist_ok=True) + if save_fig: + image_path = fname_no_ext.joinpath('png') + image_path.mkdir(parents=True, exist_ok=True) header = 'm0\tt1\tbeta\toff\n' @@ -189,16 +210,16 @@ class FCReader: np.savetxt(fit_path.joinpath(save_name), np.c_[xplot, yplot], header=header+'\t'.join([f'{p}+/-{err}' for p, err in zip(p0, perr)])) - # if save_fig: - # fig, ax = plt.subplots() - # ax.set_xlabel('t / s') - # ax.set_ylabel('M') - # axheader = f'T1: {p0[2]:.4g}(+/-{perr[2]:.4g}) beta: {p0[3]:.4g}(+/-{perr[3]:.4g})' - # ax.set_title(f'f = {k:.4g} Hz\n{axheader}') - # ax.semilogx(v.x, v.y, 'o') - # ax.semilogx(xplot, yplot, '-') - # fig.savefig(image_path.joinpath(save_name).with_suffix('.png')) - # plt.close(fig) + if save_fig: + fig, ax = plt.subplots() + ax.set_xlabel('t / s') + ax.set_ylabel('M') + axheader = f'T1: {p0[2]:.4g}(+/-{perr[2]:.4g}) beta: {p0[3]:.4g}(+/-{perr[3]:.4g})' + ax.set_title(f'f = {k:.4g} Hz\n{axheader}') + ax.semilogx(v.x, v.y, 'o') + ax.semilogx(xplot, yplot, '-') + fig.savefig(image_path.joinpath(save_name).with_suffix('.png')) + plt.close(fig) freqs = np.asanyarray(freqs) params = np.asanyarray(params) @@ -290,45 +311,45 @@ class FCReader: path = pathlib.Path(path) path.mkdir(parents=True, exist_ok=True) - # fig_mag, ax_mag = plt.subplots() - # fig_t1, ax_t1 = plt.subplots() - # fig_beta, ax_beta = plt.subplots() - # - # if kind == 'temp': - # _params = self.t_params - # else: - # _params = self.f_params - # - # save_path = path.joinpath(kind) - # if not save_path.exists(): - # save_path.mkdir(parents=True) - # - # for key, par in _params.items(): - # pl, = ax_mag.plot(par[:, 0], par[:, 1], 'o', label=key) - # ax_mag.plot(par[:, 0], par[:, 3], 's', color=pl.get_color()) - # ax_t1.plot(par[:, 0], par[:, 5], 'o', label=key) - # ax_beta.plot(par[:, 0], par[:, 7], 'o', label=key) - # - # for a in [ax_mag, ax_t1, ax_beta]: - # if kind == 'freq': - # a.legend(loc='upper left', bbox_to_anchor=(1, 1), ncol=2) - # a.set_xlabel('T / K') - # else: - # a.set_xscale('log') - # a.legend(loc='upper left', bbox_to_anchor=(1, 1)) - # a.set_xlabel('f / Hz') - # - # ax_t1.set_yscale('log') - # ax_t1.set_ylabel('T1 / s') - # ax_beta.set_ylabel('beta') - # ax_mag.set_ylabel('M0 (squares), Offset (circles)') - # - # fig_beta.savefig(path.joinpath(f'beta_{kind}.png'), bbox_inches="tight") - # fig_mag.savefig(path.joinpath(f'mag_{kind}.png'), bbox_inches="tight") - # fig_t1.savefig(path.joinpath(f't1_{kind}.png'), bbox_inches="tight") - # plt.close(fig_mag) - # plt.close(fig_beta) - # plt.close(fig_t1) + fig_mag, ax_mag = plt.subplots() + fig_t1, ax_t1 = plt.subplots() + fig_beta, ax_beta = plt.subplots() + + if kind == 'temp': + _params = self.t_params + else: + _params = self.f_params + + save_path = path.joinpath(kind) + if not save_path.exists(): + save_path.mkdir(parents=True) + + for key, par in _params.items(): + pl, = ax_mag.plot(par[:, 0], par[:, 1], 'o', label=key) + ax_mag.plot(par[:, 0], par[:, 3], 's', color=pl.get_color()) + ax_t1.plot(par[:, 0], par[:, 5], 'o', label=key) + ax_beta.plot(par[:, 0], par[:, 7], 'o', label=key) + + for a in [ax_mag, ax_t1, ax_beta]: + if kind == 'freq': + a.legend(loc='upper left', bbox_to_anchor=(1, 1), ncol=2) + a.set_xlabel('T / K') + else: + a.set_xscale('log') + a.legend(loc='upper left', bbox_to_anchor=(1, 1)) + a.set_xlabel('f / Hz') + + ax_t1.set_yscale('log') + ax_t1.set_ylabel('T1 / s') + ax_beta.set_ylabel('beta') + ax_mag.set_ylabel('M0 (squares), Offset (circles)') + + fig_beta.savefig(path.joinpath(f'beta_{kind}.png'), bbox_inches="tight") + fig_mag.savefig(path.joinpath(f'mag_{kind}.png'), bbox_inches="tight") + fig_t1.savefig(path.joinpath(f't1_{kind}.png'), bbox_inches="tight") + plt.close(fig_mag) + plt.close(fig_beta) + plt.close(fig_t1) def get_parameter(self, parameter='all', kind='freq', path=None, write=True, plot=True): param_list = [] @@ -391,99 +412,10 @@ class FCReader: return m0 * np.exp(-(x/t1)**beta) + off -class FCFileReader: - def __init__(self, fname: str): - self.filename = pathlib.Path(fname) - self._is_dir = self.filename.is_dir() - self._script_type = None - self.reader = None - if not self._is_dir: - self.reader = HdfReader(self.filename) - if 'mag' in self.reader: - self._script_type = 'old' - elif 'Magnetization' in self.reader: - self._script_type = '2022_09' - - self._temperature = get_temperature(self.filename.stem) - - def load_magnetization(self, region=None): - if self._is_dir: - _temp = self._read_from_dir() - - else: - if region is None: - _temp = self._read_from_hdf() - else: - _temp = self._read_signals(region) - - if not _temp: - raise OSError(-666, f'No magnetization found for {self.filename.name}.', self.filename.name) - - - def _read_from_hdf(self) -> dict: - _temp = {} - mag_directory = 'mag' if self._script_type == 'old' else 'Magnetization' - for mag in self.reader.get_selected(mag_directory, dtype='points'): - _temp[mag.value] = mag - - return _temp - - def _read_from_dir(self) -> dict: - fname_no_ext = self.filename.with_suffix('') - data_path = fname_no_ext / 'data' - _temp = {} - - for mag in data_path.glob('*.dat'): - d = AsciiReader(mag).export() - for v in d: - _temp[v.value] = v - break - - return _temp - - def _read_signals(self, region: tuple = None) -> dict: - start = 0 - stop = 30e-5 - - # This is one set with attributes to find default start:stop values - try: - p = self.reader.parameters('/ABS_ACC_FID') - start = p['start'] - stop = p['stop'] - except: - pass - - if region is None: - region = (start, stop) - - if region[0] is None: - region = (start, region[1]) - if region[1] is None: - region = (region[0], stop) - - sig = self.reader.get_selected('/data/B=*/ACC_ABS_FID*', dtype='signal') - _temp = {} - for s in sig: - pts = s.points([region]) - b = s.group - if b not in _temp: - _temp[b] = [] - - _temp[b].append([s.value, *[pp[1] for pp in pts]]) - - for b, m in sorted(_temp.items()): - m = np.array(m) - _temp[b] = Points(x=m[:, 0], y=m[:, 1], value=b, name=f'B={b}').sort() - - return _temp - - - if __name__ == '__main__': - from pprint import pprint - test = FCReader('/autohome/dominik/nmreval/testdata/fc_test/2022-09-15_1344_new_script.h5') - # test = FCReader('/autohome/dominik/nmreval/testdata/fc_test/314K_2015-09-03_1605.h5') + test = FCReader('/autohome/dominik/nmreval/testdata/fc_test/314K_2015-09-03_1605.h5') + test.load_magnetization(region=(None, None)) - test.load_magnetization() - test.load_magnetization(region=(0, 10e-6)) - # pprint(test.data) + # test = FCReader('/autohome/dominik/nmreval/testdata/fc_test/2023-03-16_1423.h5') + # test.load_magnetization(region=(None, None)) + print(test.data) diff --git a/src/nmreval/io/hdfreader.py b/src/nmreval/io/hdfreader.py index ce2d0ef..b5b85cb 100644 --- a/src/nmreval/io/hdfreader.py +++ b/src/nmreval/io/hdfreader.py @@ -27,7 +27,7 @@ class HdfNode: 'num_signals', 'num_pts', 'num_grp', 'title_parameter', 'parameter'] - def __init__(self, name, ref, parent): + def __init__(self, name: str, ref, parent: HdfNode | None): self.name = name self.type = 'group' self.reference = ref @@ -59,7 +59,6 @@ class HdfNode: return key in self.children - def clear(self): self.name = '' self.type = 'group' @@ -281,16 +280,16 @@ class HdfReader(HdfNode): for child in val.data(dtype=dtype): try: if child.type == 'points': - ret_val.append(self._make_point(child)) + ret_val.append(self.make_point(child)) elif child.type == 'signal': - ret_val.append(self._make_signal(child, flag=flag, value=value, group=group)) + ret_val.append(self.make_signal(child, flag=flag, value=value, group=group)) except IOError: print('something went wrong for ' + child.name) continue return ret_val - def _make_point(self, node): + def make_point(self, node): data = self.file[node.reference] val = None @@ -300,7 +299,7 @@ class HdfReader(HdfNode): return Points(x=data['x'], y=data['y'], yerr=data['y_err'], name=node.name, value=val) - def _make_signal(self, node, flag: str = 'fid', value: str = None, group: str = None): + def make_signal(self, node, flag: str = 'fid', value: str = None, group: str = None): if value is None: value = self._get_parameter_values(node, node.parameter) else: From e5563d55d5a48772698b72b6405e5b5a17874ee4 Mon Sep 17 00:00:00 2001 From: Dominik Demuth Date: Fri, 14 Apr 2023 17:58:14 +0200 Subject: [PATCH 5/9] set graphs in fc reader --- src/gui_qt/io/fcbatchreader.py | 17 +++++++++++------ src/gui_qt/main/mainwindow.py | 1 + 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/gui_qt/io/fcbatchreader.py b/src/gui_qt/io/fcbatchreader.py index 007de7e..c94dfed 100644 --- a/src/gui_qt/io/fcbatchreader.py +++ b/src/gui_qt/io/fcbatchreader.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import pathlib from nmreval.io.fcbatchreader import FCReader @@ -31,6 +33,10 @@ class QFCReader(QtWidgets.QDialog, Ui_FCEval_dialog): return super().eventFilter(src, evt) + def add_graphs(self, graphs: list[tuple[str, str]]): + for gid, graph_name in graphs: + self.graph_comboBox.addItem(graph_name, gid) + @QtCore.pyqtSlot(int, name='on_region_checkBox_stateChanged') def use_region(self, state: int): self.start_lineedit.setEnabled(state == QtCore.Qt.Checked) @@ -43,17 +49,16 @@ class QFCReader(QtWidgets.QDialog, Ui_FCEval_dialog): infiles, _ = QtWidgets.QFileDialog.getOpenFileNames(caption='Select HDF files', directory=str(self.path), filter='HDF files (*.h5)') - if infiles: - self.listWidget.addItems(infiles) - self.label.setText(str(pathlib.Path(infiles[-1]).parent)) + else: infiles = QtWidgets.QFileDialog.getExistingDirectory(caption='Select input directory', directory=str(self.path), options=QtWidgets.QFileDialog.ShowDirsOnly) - if infiles: - self.listWidget.addItem(infiles) - self.label.setText(str(pathlib.Path(infiles).parent)) + if infiles: + self.listWidget.addItems(infiles) + self.path = pathlib.Path(infiles[-1]).parent + self.label.setText(str(self.path)) @QtCore.pyqtSlot(name='on_savebutton_clicked') def save_path(self): diff --git a/src/gui_qt/main/mainwindow.py b/src/gui_qt/main/mainwindow.py index 77bc0c2..29fa278 100644 --- a/src/gui_qt/main/mainwindow.py +++ b/src/gui_qt/main/mainwindow.py @@ -254,6 +254,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): @QtCore.pyqtSlot(name='on_actionOpen_FC_triggered') def read_fc(self): reader = QFCReader(path=self.path, parent=self) + reader.add_graphs(self.management.graphs.list()) reader.data_read.connect(self.management.add_new_data) reader.exec() From 99bb196e5cd9833697efd30f31cb5813bbd1e12d Mon Sep 17 00:00:00 2001 From: Dominik Demuth Date: Fri, 14 Apr 2023 19:17:05 +0200 Subject: [PATCH 6/9] basic FC reading is working for different script version --- src/gui_qt/data/datawidget/datawidget.py | 6 ++- src/gui_qt/io/fcbatchreader.py | 1 + src/nmreval/io/fcbatchreader.py | 56 ++++++++++++------------ 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/src/gui_qt/data/datawidget/datawidget.py b/src/gui_qt/data/datawidget/datawidget.py index cf4b741..d3a4df3 100644 --- a/src/gui_qt/data/datawidget/datawidget.py +++ b/src/gui_qt/data/datawidget/datawidget.py @@ -1,5 +1,6 @@ from __future__ import annotations +from nmreval.lib.logger import logger from nmreval.lib.colors import available_cycles from .properties import PropWidget @@ -356,7 +357,10 @@ class DataTree(QtWidgets.QTreeWidget): except AttributeError: idx = self.invisibleRootItem().indexOfChild(item) self.invisibleRootItem().takeChild(idx) - self._checked_graphs.remove(_id) + try: + self._checked_graphs.remove(_id) + except KeyError: + logger.warn(f'Graph {_id} already removed, skip') iterator += 1 diff --git a/src/gui_qt/io/fcbatchreader.py b/src/gui_qt/io/fcbatchreader.py index c94dfed..c2a498e 100644 --- a/src/gui_qt/io/fcbatchreader.py +++ b/src/gui_qt/io/fcbatchreader.py @@ -54,6 +54,7 @@ class QFCReader(QtWidgets.QDialog, Ui_FCEval_dialog): infiles = QtWidgets.QFileDialog.getExistingDirectory(caption='Select input directory', directory=str(self.path), options=QtWidgets.QFileDialog.ShowDirsOnly) + infiles = [infiles] if infiles else infiles if infiles: self.listWidget.addItems(infiles) diff --git a/src/nmreval/io/fcbatchreader.py b/src/nmreval/io/fcbatchreader.py index e27be6f..7d17c00 100644 --- a/src/nmreval/io/fcbatchreader.py +++ b/src/nmreval/io/fcbatchreader.py @@ -15,7 +15,6 @@ from nmreval.utils.utils import get_temperature, roundrobin class FCReader: def __init__(self, fname: (list | str | pathlib.Path)): - print('Hello') if isinstance(fname, (str, pathlib.Path)): self.fnames = [fname] else: @@ -78,15 +77,15 @@ class FCReader: _temp = {} reader = HdfReader(filename) - mag_directory = 'Magnetization' + mag_directory = None for m in ['Magnetization', 'mag']: - try: + if m in reader: mag_directory = m - except KeyError: - continue + break - for mag in reader.get_selected(mag_directory, dtype='points'): - _temp[mag.value] = mag + if m is not None: + for mag in reader.get_selected(mag_directory, dtype='points'): + _temp[mag.value] = mag return _temp @@ -122,14 +121,19 @@ class FCReader: _temp = {} bevo_groups = reader['data'].children + no_bevo = False for grp in bevo_groups.values(): for k in grp.data(): - print(k) + try: + # look for parameter, should be missing in older scripts + bevo = k.parameter['bevo'] + except KeyError: + no_bevo = True + break + if str(k.parent) != 'ACC_ABS_FID_sig (group)': continue - print(k.path, k, k.parent, k.parameter['bevo'], k.parameter['tevo']) - bevo = k.parameter['bevo'] tevo = k.parameter['tevo'] s = reader.make_signal(k, flag='fid', value='tevo', group='bevo') @@ -140,15 +144,20 @@ class FCReader: _temp[bevo].append((tevo, *[pp[1] for pp in pts])) - # sig = reader.get_selected('/data/B=*/ACC_ABS_FID*', dtype='signal') - # _temp = {} - # for s in sig: - # pts = s.points([region]) - # b = s.group - # if b not in _temp: - # _temp[b] = [] - # - # _temp[b].append([s.value, *[pp[1] for pp in pts]]) + if no_bevo: + break + + if no_bevo: + # hopefully only for old scripts + sig = reader.get_selected('/data/B=*/ACC_ABS_FID*', dtype='signal') + _temp = {} + for s in sig: + pts = s.points([region]) + b = s.group + if b not in _temp: + _temp[b] = [] + + _temp[b].append([s.value, *[pp[1] for pp in pts]]) for b, m in sorted(_temp.items()): m = np.array(m) @@ -410,12 +419,3 @@ class FCReader: @staticmethod def kww(x, m0, off, t1, beta): return m0 * np.exp(-(x/t1)**beta) + off - - -if __name__ == '__main__': - test = FCReader('/autohome/dominik/nmreval/testdata/fc_test/314K_2015-09-03_1605.h5') - test.load_magnetization(region=(None, None)) - - # test = FCReader('/autohome/dominik/nmreval/testdata/fc_test/2023-03-16_1423.h5') - # test.load_magnetization(region=(None, None)) - print(test.data) From c94231f9d9f206477a7490097aad64d5b4e70281 Mon Sep 17 00:00:00 2001 From: Dominik Demuth Date: Sat, 15 Apr 2023 14:54:25 +0200 Subject: [PATCH 7/9] add block to graphwindow to stop rescale/legend uupdates --- src/gui_qt/graphs/graphwindow.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/gui_qt/graphs/graphwindow.py b/src/gui_qt/graphs/graphwindow.py index b0dee37..5c182ca 100644 --- a/src/gui_qt/graphs/graphwindow.py +++ b/src/gui_qt/graphs/graphwindow.py @@ -54,6 +54,8 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow): self._external_items = [] self.closable = True + self._block = False + self.log = [False, False] self.scene = self.plotItem.scene() @@ -150,6 +152,16 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow): return tuple(r) + def block(self, state: bool): + self._block = state + + if not self._block: + self.graphic.enableAutoRange() + self._update_zorder() + self.show_legend() + else: + self.graphic.disableAutoRange() + def add(self, name: str | list, plots: list): if isinstance(name, str): name = [name] @@ -201,8 +213,9 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow): self.listWidget.blockSignals(False) - self._update_zorder() - self.show_legend() + if not self._block: + self._update_zorder() + self.show_legend() def move_sets(self, sets: list, position: int): move_plots = [] @@ -484,6 +497,7 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow): self.ymax_lineedit.setText('%.5g' % r[1][1]) def _update_zorder(self): + print('update yorder') for i, sid in enumerate(self.sets): plt = self.real_plots[sid] if plt.zValue() != 2*i+1: @@ -501,6 +515,10 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow): self.checkBox.setVisible(visible) def update_legend(self, sid, name): + if self._block: + return + + print('update legend') self.listWidget.blockSignals(True) for i in range(self.listWidget.count()): @@ -512,6 +530,7 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow): self.show_legend() def show_legend(self): + print('show legend') if not self.legend.isVisible(): return From e41c42d573a72f5b05ba17c9cf2d2e73ed7b55cd Mon Sep 17 00:00:00 2001 From: Dominik Demuth Date: Sat, 15 Apr 2023 14:55:14 +0200 Subject: [PATCH 8/9] move iteration of deleting sets inside undo --- src/gui_qt/lib/undos.py | 58 +++++++++++++++++++++++++---------- src/gui_qt/main/management.py | 15 +++++++-- 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/src/gui_qt/lib/undos.py b/src/gui_qt/lib/undos.py index 9ee255c..86714a6 100644 --- a/src/gui_qt/lib/undos.py +++ b/src/gui_qt/lib/undos.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import copy from numpy import argsort @@ -216,33 +218,55 @@ class DeleteGraphCommand(QtWidgets.QUndoCommand): class DeleteCommand(QtWidgets.QUndoCommand): - def __init__(self, container, key, signal1, signal2): + def __init__(self, container: dict, keys: list[str], graphs: dict, graphid: str, + signal1: QtCore.pyqtSignal, signal2: QtCore.pyqtSignal): super().__init__('Delete data') self.__container = container - self.__value = self.__container[key] - self.__key = key + self.__graph_container = graphs + self.__graph_key = graphid + self.__value = {} + for k in keys: + self.__value[k] = self.__container[k] + self.__keys = tuple(keys) self.__signal_add = signal1 self.__signal_remove = signal2 def redo(self): - self.__signal_remove.emit(self.__key) - if isinstance(self.__value, FitContainer): - try: - self.__container[self.__value.fitted_key]._fits.remove(self.__key) - except KeyError: - pass - del self.__container[self.__key] + # stop graph from rescaling and updating legend + self.__graph_container[self.__graph_key].block(True) + + for sid in self.__keys[::-1]: + val = self.__value[sid] + self.__signal_remove.emit(sid) + + if isinstance(val, FitContainer): + try: + self.__container[sid].fitted_key._fits.remove(sid) + except KeyError: + pass + + del self.__container[sid] + + self.__graph_container[self.__graph_key].block(False) def undo(self): - self.__container[self.__key] = self.__value - if isinstance(self.__value, FitContainer): - try: - self.__container[self.__value.fitted_key]._fits.append(self.__key) - except KeyError: - pass + # stop graph from rescaling and updating legend + self.__graph_container[self.__graph_key].block(True) - self.__signal_add.emit([self.__key], self.__value.graph) + for sid in self.__keys: + val = self.__value[sid] + self.__container[sid] = val + + if isinstance(val, FitContainer): + try: + self.__container[val.fitted_key]._fits.append(sid) + except KeyError: + pass + + self.__signal_add.emit([sid], val.graph) + + self.__graph_container[self.__graph_key].block(False) class EvalCommand(QtWidgets.QUndoCommand): diff --git a/src/gui_qt/main/management.py b/src/gui_qt/main/management.py index 1c7000b..edbb032 100644 --- a/src/gui_qt/main/management.py +++ b/src/gui_qt/main/management.py @@ -287,15 +287,26 @@ class UpperManagement(QtCore.QObject): self.undostack.beginMacro('Delete') + rm_set_by_graph = {} + for k in rm_sets[::-1]: if k in self.data: - cmd = DeleteCommand(self.data, k, self.newData, self.deleteData) - self.undostack.push(cmd) + parent_graph = self.data[k].graph + if parent_graph not in rm_set_by_graph: + rm_set_by_graph[parent_graph] = [] + + rm_set_by_graph[parent_graph].append(k) + elif k in self.graphs: rm_graphs.append(k) + else: logger.warning(f'delete_sets: {k} is not in data or graph found') + for gid, sid_list in rm_set_by_graph.items(): + cmd = DeleteCommand(self.data, sid_list, self.graphs, gid, self.newData, self.deleteData) + self.undostack.push(cmd) + for k in rm_graphs: cmd = DeleteGraphCommand(self.graphs, k, self.restoreGraph, self.deleteGraph) self.undostack.push(cmd) From bd8a4f16ea6d74dfbbe2a0ac76508ed51a3baa9c Mon Sep 17 00:00:00 2001 From: Dominik Demuth Date: Sat, 15 Apr 2023 15:40:49 +0200 Subject: [PATCH 9/9] UpperManagement.deleteDate emits list of sets, indexes in datawidget are now only updated once --- src/gui_qt/data/datawidget/datawidget.py | 9 +++++---- src/gui_qt/lib/undos.py | 4 ++-- src/gui_qt/main/mainwindow.py | 11 ++++++----- src/gui_qt/main/management.py | 16 ++++++++++++---- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/gui_qt/data/datawidget/datawidget.py b/src/gui_qt/data/datawidget/datawidget.py index d3a4df3..515506e 100644 --- a/src/gui_qt/data/datawidget/datawidget.py +++ b/src/gui_qt/data/datawidget/datawidget.py @@ -20,6 +20,7 @@ class DataTree(QtWidgets.QTreeWidget): saveFits = QtCore.pyqtSignal(list) extendFits = QtCore.pyqtSignal(list) + # noinspection PyUnresolvedReferences def __init__(self, parent=None): super().__init__(parent=parent) @@ -230,7 +231,7 @@ class DataTree(QtWidgets.QTreeWidget): def sort(self, graph_item: QtWidgets.QTreeWidgetItem, mode: str = 'value'): graph_id = graph_item.data(0, QtCore.Qt.UserRole) - sets = self.management.get_attributes(graph_id, mode) + sets = self.management.get_attributes(graph_id, mode) sets = [el[0] for el in sorted(sets.items(), key=lambda x: x[1])] self.management.move_sets(sets, graph_id, graph_id, pos=-1) @@ -248,7 +249,6 @@ class DataTree(QtWidgets.QTreeWidget): self.blockSignals(False) - def update_indexes(self): graph_cnt = -1 set_cnt = 0 @@ -343,7 +343,7 @@ class DataTree(QtWidgets.QTreeWidget): self.setDragEnabled(idx.column() == 0) super().mousePressEvent(evt) - def remove_item(self, ids: list): + def remove_item(self, ids: list[str]): iterator = QtWidgets.QTreeWidgetItemIterator(self) while iterator.value(): item = iterator.value() @@ -527,6 +527,7 @@ class DataWidget(QtWidgets.QWidget, Ui_DataWidget): self.setupUi(self) self.tree = DataTree(self) self.verticalLayout.addWidget(self.tree) + # noinspection PyUnresolvedReferences self.tree.selectionModel().selectionChanged.connect(lambda x, y: self.show_property(x)) self.tree.keyChanged.connect(lambda x, y: self.keyChanged.emit(x, y)) @@ -554,7 +555,7 @@ class DataWidget(QtWidgets.QWidget, Ui_DataWidget): self.tree.add_item(loi, gid) self.tree.blockSignals(False) - def remove_item(self, key): + def remove_item(self, key: list[str]): self.tree.remove_item(key) def show_property(self, _: QtCore.QModelIndex = None): diff --git a/src/gui_qt/lib/undos.py b/src/gui_qt/lib/undos.py index 86714a6..acc1f37 100644 --- a/src/gui_qt/lib/undos.py +++ b/src/gui_qt/lib/undos.py @@ -236,9 +236,9 @@ class DeleteCommand(QtWidgets.QUndoCommand): # stop graph from rescaling and updating legend self.__graph_container[self.__graph_key].block(True) + self.__signal_remove.emit(list(self.__keys[::-1])) for sid in self.__keys[::-1]: val = self.__value[sid] - self.__signal_remove.emit(sid) if isinstance(val, FitContainer): try: @@ -264,7 +264,7 @@ class DeleteCommand(QtWidgets.QUndoCommand): except KeyError: pass - self.__signal_add.emit([sid], val.graph) + self.__signal_add.emit(list(self.__keys), self.__graph_key) self.__graph_container[self.__graph_key].block(False) diff --git a/src/gui_qt/main/mainwindow.py b/src/gui_qt/main/mainwindow.py index 29fa278..1680f41 100644 --- a/src/gui_qt/main/mainwindow.py +++ b/src/gui_qt/main/mainwindow.py @@ -348,7 +348,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): @QtCore.pyqtSlot(str) def remove_graph(self, gid: str): - self.datawidget.remove_item(gid) + self.datawidget.remove_item([gid]) val_figure = self.valuewidget.connected_figure self.valuewidget.remove_graph() @@ -733,10 +733,11 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): self.datawidget.set_name(sid, self.management[sid].name) - @QtCore.pyqtSlot(str) - def delete_data(self, sid): - if self.valuewidget.shown_set == sid: - self.tabWidget.setCurrentIndex(0) + @QtCore.pyqtSlot(list) + def delete_data(self, sid: list[str]): + for key in sid: + if self.valuewidget.shown_set == key: + self.tabWidget.setCurrentIndex(0) self.datawidget.remove_item(sid) diff --git a/src/gui_qt/main/management.py b/src/gui_qt/main/management.py index edbb032..594afe4 100644 --- a/src/gui_qt/main/management.py +++ b/src/gui_qt/main/management.py @@ -75,7 +75,7 @@ class UpperManagement(QtCore.QObject): restoreGraph = QtCore.pyqtSignal(str) deleteGraph = QtCore.pyqtSignal(str) newData = QtCore.pyqtSignal(list, str) - deleteData = QtCore.pyqtSignal(str) + deleteData = QtCore.pyqtSignal(list) dataChanged = QtCore.pyqtSignal(str) fitFinished = QtCore.pyqtSignal(list) stopFit = QtCore.pyqtSignal() @@ -234,9 +234,17 @@ class UpperManagement(QtCore.QObject): for k in plotkeys: self.data[k].graph = gid - @QtCore.pyqtSlot(str) - def plot_from_graph(self, key: str): - self.graphs[self.data[key].graph].remove(key) + @QtCore.pyqtSlot(list) + def plot_from_graph(self, key: list[str]): + sort_graph = {} + for sid in key: + v = self.data[sid].graph + if v not in sort_graph: + sort_graph[v] = [] + sort_graph[v].append(sid) + + for gid, sets in sort_graph.items(): + self.graphs[gid].remove(sets) @QtCore.pyqtSlot(list, str, str) def move_sets(self, sets: list, dest: str, src: (str|list), pos: int = -1):