From 26c3ff36770feb1dff5951170bf83a2d7728198d Mon Sep 17 00:00:00 2001 From: sldesnoo-Delft <s.l.desnoo@tudelft.nl> Date: Mon, 20 Jan 2025 18:00:09 +0100 Subject: [PATCH] Fix update of general settings in VideoMode. --- CHANGELOG.md | 4 + LICENSE | 38 +- .../data_getter/scan_generator_Qblox.py | 27 +- .../GUI/keysight_videomaps/liveplotting.py | 384 +++++++++--------- 4 files changed, 233 insertions(+), 220 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b27e2a2..f0d55e39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog All notable changes to core_tools will be documented in this file. +## \[1.5.7] - 2025-01-19 + +- Fix update of general settings in VideoMode. + ## \[1.5.6] - 2025-01-14 - Always use package h5netcdf to load data from HDF5 file. diff --git a/LICENSE b/LICENSE index 33e8dd57..c1def32d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,25 +1,21 @@ -BSD 2-Clause License +MIT License -Copyright (c) 2020, stephanlphilips -All rights reserved. +Copyright (c) 2021 QuTech -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/core_tools/GUI/keysight_videomaps/data_getter/scan_generator_Qblox.py b/core_tools/GUI/keysight_videomaps/data_getter/scan_generator_Qblox.py index 641544d7..884118d6 100644 --- a/core_tools/GUI/keysight_videomaps/data_getter/scan_generator_Qblox.py +++ b/core_tools/GUI/keysight_videomaps/data_getter/scan_generator_Qblox.py @@ -17,7 +17,7 @@ class QbloxFastScanParameter(FastScanParameterBase): scan_config: ScanConfigBase, pulse_lib, pulse_sequence, - ): + ): """ args: pulse_lib (pulselib): pulse library object @@ -75,7 +75,7 @@ class FastScanGenerator(FastScanGeneratorBase): gate: str, swing: float, n_pt: int, t_measure: float, pulse_gates: dict[str, float] = {}, biasT_corr: bool = False, - ) -> FastScanParameterBase: + ) -> FastScanParameterBase: """Creates 1D fast scan parameter. Args: @@ -106,7 +106,7 @@ class FastScanGenerator(FastScanGeneratorBase): acq_channels = set(v[0] for v in config.channel_map.values()) - seg = self.pulse_lib.mk_segment() + seg = self.pulse_lib.mk_segment() g1 = seg[gate] pulse_channels = [] for ch, v in pulse_gates.items(): @@ -158,15 +158,15 @@ class FastScanGenerator(FastScanGeneratorBase): config, pulse_lib=self.pulse_lib, pulse_sequence=my_seq, - ) + ) def create_2D_scan(self, - gate1: str, swing1: float, n_pt1: int, - gate2: str, swing2: float, n_pt2: int, - t_measure: float, - pulse_gates: dict[str, float] = {}, - biasT_corr: bool = True, - ) -> FastScanParameterBase: + gate1: str, swing1: float, n_pt1: int, + gate2: str, swing2: float, n_pt2: int, + t_measure: float, + pulse_gates: dict[str, float] = {}, + biasT_corr: bool = True, + ) -> FastScanParameterBase: """Creates 2D fast scan parameter. Args: @@ -205,7 +205,7 @@ class FastScanGenerator(FastScanGeneratorBase): add_pulse_gate_correction = biasT_corr and len(pulse_gates) > 0 - seg = self.pulse_lib.mk_segment() + seg = self.pulse_lib.mk_segment() g1 = seg[gate1] g2 = seg[gate2] @@ -233,7 +233,8 @@ class FastScanGenerator(FastScanGeneratorBase): g1.add_ramp_ss(0, step_eff*config.n_ptx, -config.vpx, config.vpx) g2.add_block(0, step_eff*config.n_ptx, v2) for acq_ch in acq_channels: - seg[acq_ch].acquire(step_eff*config.line_margin+config.acquisition_delay_ns, n_repeat=n_pt1, interval=step_eff) + seg[acq_ch].acquire(step_eff*config.line_margin+config.acquisition_delay_ns, + n_repeat=n_pt1, interval=step_eff) for g, v in pulse_channels: g.add_block(0, step_eff*config.n_ptx, v) seg.reset_time() @@ -273,7 +274,7 @@ class FastScanGenerator(FastScanGeneratorBase): config, pulse_lib=self.pulse_lib, pulse_sequence=my_seq - ) + ) def construct_1D_scan_fast(gate, swing, n_pt, t_step, biasT_corr, pulse_lib, diff --git a/core_tools/GUI/keysight_videomaps/liveplotting.py b/core_tools/GUI/keysight_videomaps/liveplotting.py index 98b9adc3..9d4eaca7 100644 --- a/core_tools/GUI/keysight_videomaps/liveplotting.py +++ b/core_tools/GUI/keysight_videomaps/liveplotting.py @@ -14,7 +14,7 @@ from core_tools.GUI.keysight_videomaps.data_saver.native import CoreToolsDataSav from core_tools.GUI.keysight_videomaps.data_getter.scan_generator_base import ( FastScanParameterBase, FastScanGeneratorBase, - ) +) from core_tools.GUI.keysight_videomaps.data_getter.iq_modes import get_channel_map, get_channel_map_dig_4ch from core_tools.GUI.keysight_videomaps.data_getter import scan_generator_Virtual from core_tools.GUI.keysight_videomaps.GUI.favorites import Favorites @@ -25,7 +25,7 @@ from core_tools.GUI.qt_util import qt_log_exception from core_tools.utility.powerpoint import addPPTslide from core_tools.GUI.keysight_videomaps.GUI.gui_components import ( Settings, CheckboxList, OffsetsList - ) +) logger = logging.getLogger(__name__) @@ -57,7 +57,7 @@ def _try_get_gates(): try: from qcodes import Station return Station.default.gates - except: + except Exception: return None @@ -84,41 +84,43 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): pulse_lib (pulselib) : provide the pulse library object. This is used to generate the sequences. digitizer (QCodes Instrument) : digitizer to use. If None uses digitizers configured in pulse-lib. scan_type (str) : AWG and digitizer used: 'Keysight', 'Qblox', 'Tektronix' or 'Virtual'. - cust_defaults (dict of dicts): Dictionary to supply custom starting defaults. Any parameters/dicts that are not defined will resort to defaults. - Format is {'1D': dict, '2D': dict, 'gen': dict} - 1D = {'gate_name': str, - 'V_swing': float, - 'npt': int, - 't_meas': float, - 'biasT_corr': bool, - 'average': int, - 'diff': bool, - 'offsets': dict[str, float]} - 2D = {'gate1_name': str, - 'gate2_name': str, - 'V1_swing': float, - 'V2_swing': float, - 'npt': int, - 't_meas': float, - 'biasT_corr': bool, - 'average': int, - 'gradient': str, # 'Off', 'Magnitude', or 'Mag & angle' - 'filter_background': bool, - 'background_sigma': float, - 'filter_noise': bool, - 'noise_sigma': float, - 'cross': bool, - 'colorbar': bool, - 'offsets': dict[str, float]} - gen = { - 'enabled_channels': list[str], - 'enabled_markers': list[str], - 'n_columns': int, - 'line_margin': int, - 'bias_T_RC': float, - 'acquisition_delay_ns': float, # Time in ns between AWG output change and digitizer acquisition start. - 'max_V_swing': float, # maximum voltage swing for 1D and 2D - } + cust_defaults (dict of dicts): + Dictionary to supply custom starting defaults. + Any parameters/dicts that are not defined will resort to defaults. + Format is {'1D': dict, '2D': dict, 'gen': dict} + 1D = {'gate_name': str, + 'V_swing': float, + 'npt': int, + 't_meas': float, + 'biasT_corr': bool, + 'average': int, + 'diff': bool, + 'offsets': dict[str, float]} + 2D = {'gate1_name': str, + 'gate2_name': str, + 'V1_swing': float, + 'V2_swing': float, + 'npt': int, + 't_meas': float, + 'biasT_corr': bool, + 'average': int, + 'gradient': str, # 'Off', 'Magnitude', or 'Mag & angle' + 'filter_background': bool, + 'background_sigma': float, + 'filter_noise': bool, + 'noise_sigma': float, + 'cross': bool, + 'colorbar': bool, + 'offsets': dict[str, float]} + gen = { + 'enabled_channels': list[str], + 'enabled_markers': list[str], + 'n_columns': int, + 'line_margin': int, + 'bias_T_RC': float, + 'acquisition_delay_ns': float, # ns between AWG output change and digitizer acquisition start. + 'max_V_swing': float, # maximum voltage swing for 1D and 2D + } iq_mode (str): when digitizer is in MODE.IQ_DEMODULATION then this parameter specifies how the complex I/Q value should be plotted: 'I', 'Q', 'amplitude', 'phase', 'phase_deg', 'I+Q', 'amplitude+phase'. In the latter two cases 2 charts will be shown for each channel. @@ -208,7 +210,7 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): liveplotting._all_instances.append(self) self.show() - if instance_ready == False: + if instance_ready is False: print('APP EXEC') self.app.exec() @@ -232,7 +234,7 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): from .data_getter import scan_generator_Qblox if self.digitizer is not None: logger.error('liveplotting parameter digitizer should be None for Qblox. ' - 'QRM must be added to pulse_lib with `add_digitizer`.') + 'QRM must be added to pulse_lib with `add_digitizer`.') scan_generator = scan_generator_Qblox.FastScanGenerator() else: raise ValueError("Unsupported argument for scan type.") @@ -240,10 +242,10 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): return scan_generator def setup_statusbar(self): - self.statusbar.setContentsMargins(8,0,4,4) + self.statusbar.setContentsMargins(8, 0, 4, 4) self.bias_T_warning_label = QtWidgets.QLabel("") self.bias_T_warning_label.setMargin(2) - self.bias_T_warning_label.setContentsMargins(QtCore.QMargins(6,0,6,0)) + self.bias_T_warning_label.setContentsMargins(QtCore.QMargins(6, 0, 6, 0)) self.bias_T_warning_label.setMinimumWidth(300) self.statusbar.addWidget(self.bias_T_warning_label) @@ -272,39 +274,39 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): self._2D_settings = Settings("2D", self.update_plot_properties_2D) sensor_checkboxes = CheckboxList( - "enabled_channels", - self._gen_settings, - list(self.channel_map.keys()), - self.horizontalLayout_channel_labels, - self.horizontalLayout_channel_checkboxes, - default=True, - ) + "enabled_channels", + self._gen_settings, + list(self.channel_map.keys()), + self.horizontalLayout_channel_labels, + self.horizontalLayout_channel_checkboxes, + default=True, + ) marker_checkboxes = CheckboxList( - "enabled_markers", - self._gen_settings, - sorted(self.pulse_lib.marker_channels, key=str.lower), - self.horizontalLayout_markers, - self.horizontalLayout_markers_checks, - default=False, - ) + "enabled_markers", + self._gen_settings, + sorted(self.pulse_lib.marker_channels, key=str.lower), + self.horizontalLayout_markers, + self.horizontalLayout_markers_checks, + default=False, + ) self._gen_settings.add("acquisition_delay_ns", self._gen_acquisition_delay_ns) self._gen_settings.add("n_columns", self._gen_n_columns) self._gen_settings.add("line_margin", self._gen_line_margin) - self._gen_settings.add("max_V_swing", self._gen_max_V_swing) - self._gen_settings.add("bias_T_RC", self._gen_bias_T_RC) + self._gen_settings.add("max_V_swing", self._gen_max_V_swing, plot_setting=True) + self._gen_settings.add("bias_T_RC", self._gen_bias_T_RC, plot_setting=True) self._gen_settings.add("enabled_channels", sensor_checkboxes) self._gen_settings.add("enabled_markers", marker_checkboxes) self._gen_settings.add("virtual_matrix_auto_recompile", self._gen_vm_auto_recompile) offset_gate_voltages_1D = OffsetsList( - "offsets", - self._1D_settings, - self.formLayout_1D, - 11, - self.n_pulse_gates, - gate_names) + "offsets", + self._1D_settings, + self.formLayout_1D, + 11, + self.n_pulse_gates, + gate_names) self._1D_settings.add("gate_name", self._1D_gate_name) self._1D_settings.add("V_swing", self._1D_V_swing) @@ -316,12 +318,12 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): self._1D_settings.add("offsets", offset_gate_voltages_1D) offset_gate_voltages_2D = OffsetsList( - "offsets", - self._2D_settings, - self.formLayout_2D, - 11, - self.n_pulse_gates, - gate_names) + "offsets", + self._2D_settings, + self.formLayout_2D, + 11, + self.n_pulse_gates, + gate_names) self._2D_settings.add("gate1_name", self._2D_gate1_name) self._2D_settings.add("V1_swing", self._2D_V1_swing) @@ -340,28 +342,28 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): self._2D_settings.add("colorbar", self._gen_2D_colorbar) self._2D_settings.add("offsets", offset_gate_voltages_2D) - self._1D_play.clicked.connect(lambda:self._start_1D()) - self._2D_play.clicked.connect(lambda:self._start_2D()) - self._1D_pause.clicked.connect(lambda:self._stop_1D()) - self._2D_pause.clicked.connect(lambda:self._stop_2D()) - self._1D_step.clicked.connect(lambda:self._step_1D()) - self._2D_step.clicked.connect(lambda:self._step_2D()) - self._1D_reload.clicked.connect(lambda:self.reload_1D()) - self._2D_reload.clicked.connect(lambda:self.reload_2D()) - self._flip_axes.clicked.connect(lambda:self.do_flip_axes()) - self.tabWidget.currentChanged.connect(lambda:self.tab_changed()) + self._1D_play.clicked.connect(lambda: self._start_1D()) + self._2D_play.clicked.connect(lambda: self._start_2D()) + self._1D_pause.clicked.connect(lambda: self._stop_1D()) + self._2D_pause.clicked.connect(lambda: self._stop_2D()) + self._1D_step.clicked.connect(lambda: self._step_1D()) + self._2D_step.clicked.connect(lambda: self._step_2D()) + self._1D_reload.clicked.connect(lambda: self.reload_1D()) + self._2D_reload.clicked.connect(lambda: self.reload_2D()) + self._flip_axes.clicked.connect(lambda: self.do_flip_axes()) + self.tabWidget.currentChanged.connect(lambda: self.tab_changed()) - self._1D_reset_average.clicked.connect(lambda:self._reset_1D_average()) - self._2D_reset_average.clicked.connect(lambda:self._reset_2D_average()) + self._1D_reset_average.clicked.connect(lambda: self._reset_1D_average()) + self._2D_reset_average.clicked.connect(lambda: self._reset_2D_average()) - self._1D_save_data.clicked.connect(lambda:self.save_data()) - self._2D_save_data.clicked.connect(lambda:self.save_data()) + self._1D_save_data.clicked.connect(lambda: self.save_data()) + self._2D_save_data.clicked.connect(lambda: self.save_data()) - self._1D_ppt_save.clicked.connect(lambda:self.copy_ppt()) - self._2D_ppt_save.clicked.connect(lambda:self.copy_ppt()) + self._1D_ppt_save.clicked.connect(lambda: self.copy_ppt()) + self._2D_ppt_save.clicked.connect(lambda: self.copy_ppt()) - self._1D_copy.clicked.connect(lambda:self.copy_to_clipboard()) - self._2D_copy.clicked.connect(lambda:self.copy_to_clipboard()) + self._1D_copy.clicked.connect(lambda: self.copy_to_clipboard()) + self._2D_copy.clicked.connect(lambda: self.copy_to_clipboard()) self._1D_set_DC.setEnabled(self.gates is not None) self._1D_set_DC.setStyleSheet("QPushButton:checked { background-color: #ffc000; color: black }") @@ -445,7 +447,7 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): 'average': 1, 'diff': False, 'biasT_corr': False, - } + } self.defaults_2D = { 'gate1_name': self.gate_names[0], @@ -463,7 +465,7 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): 'noise_sigma': 1.0, 'cross': False, 'colorbar': False, - } + } self.defaults_gen = { 'acquisition_delay_ns': 500, @@ -472,7 +474,7 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): 'max_V_swing': 1000.0, 'bias_T_RC': 100, 'virtual_matrix_auto_recompile': False, - } + } self._1D_settings.update(self.defaults_1D) self._2D_settings.update(self.defaults_2D) @@ -517,7 +519,7 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): "1D": self._1D_settings.to_dict(), "2D": self._2D_settings.to_dict(), "gen": self._gen_settings.to_dict(), - } + } self._favorites.load_selected(active_settings) @qt_log_exception @@ -529,7 +531,7 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): ''' update properties in the liveplot without reloading the sequences (e.g. averaging/differentation of data) ''' - if self._plot1D is not None: + if self._plot1D is not None: settings = self._1D_settings self._plot1D.averaging = settings["average"] self._plot1D.gradient = settings["diff"] @@ -539,18 +541,18 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): ''' update properties in the liveplot without reloading the sequences (e.g. averaging/gradient of data) ''' - if self._plot2D is not None: + if self._plot2D is not None: settings = self._2D_settings self._plot2D.averaging = settings["average"] self._plot2D.gradient = settings["gradient"] self._plot2D.set_background_filter( - settings["filter_background"], - settings["background_sigma"], - ) + settings["filter_background"], + settings["background_sigma"], + ) self._plot2D.set_noise_filter( - settings["filter_noise"], - settings["noise_sigma"], - ) + settings["filter_noise"], + settings["noise_sigma"], + ) def _update_gui_1D(self): settings = self._1D_settings @@ -595,7 +597,7 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): self._update_bias_T_message(t_bias_charging, settings["V2_swing"]) def _update_bias_T_message(self, t_bias_charging, v_swing): - biasTrc = self._gen_settings["bias_T_RC"] * 1000 # microseconds + biasTrc = self._gen_settings["bias_T_RC"] * 1000 # microseconds biasTerror = t_bias_charging/biasTrc v_error = biasTerror * v_swing / 2 @@ -614,6 +616,7 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): def _requires_build(self, param: FastScanParameterBase, settings: Settings): build = param is None or settings.update_scan + if not build and self._pulselib_settings.has_changes(): if not self._recompile_sequence(param): build = True @@ -622,41 +625,44 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): def _prepare_scan(self): settings = self._gen_settings active_channel_map = { - name: self.channel_map[name] - for name in settings["enabled_channels"] - } + name: self.channel_map[name] + for name in settings["enabled_channels"] + } self._scan_generator.configure( - acquisition_delay_ns=settings["acquisition_delay_ns"], - enabled_markers=settings["enabled_markers"], - line_margin=settings["line_margin"]) + acquisition_delay_ns=settings["acquisition_delay_ns"], + enabled_markers=settings["enabled_markers"], + line_margin=settings["line_margin"]) self._scan_generator.set_iq_mode(self.iq_mode) self._scan_generator.set_channel_map(active_channel_map) def _prepare_1D_scan(self): - settings = self._1D_settings gen_settings = self._gen_settings + if gen_settings.update_scan: + self._1D_settings.update_scan = True + self._2D_settings.update_scan = True + gen_settings.update_scan = False + settings = self._1D_settings self._stop_other() if self._requires_build(self._param1D, settings): logger.debug('Creating 1D scan') - self._update_gui_1D() self._prepare_scan() self._param1D = self._scan_generator.create_1D_scan( - settings["gate_name"], - settings["V_swing"], - settings["npt"], - settings["t_meas"]*1000, - pulse_gates=settings["offsets"], - biasT_corr=settings["biasT_corr"]) + settings["gate_name"], + settings["V_swing"], + settings["npt"], + settings["t_meas"]*1000, + pulse_gates=settings["offsets"], + biasT_corr=settings["biasT_corr"]) self._plot1D = _1D_live_plot( - self._1D_plotter_layout, - self._param1D, - gen_settings["n_columns"], - self._1D_av_progress, - gates=self.gates, - gate_values_label=self.gate_values_label, - on_mouse_moved=self._on_mouse_moved_1D, - on_mouse_clicked=self._on_mouse_clicked_1D) + self._1D_plotter_layout, + self._param1D, + gen_settings["n_columns"], + self._1D_av_progress, + gates=self.gates, + gate_values_label=self.gate_values_label, + on_mouse_moved=self._on_mouse_moved_1D, + on_mouse_clicked=self._on_mouse_clicked_1D) self.update_plot_properties_1D() self._set_metadata(1) settings.update_scan = False @@ -664,6 +670,7 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): else: self._param1D.restart() + self._update_gui_1D() self.vm_data_param_1D = vm_data_param(self._param1D, self._plot1D, self.metadata) @qt_log_exception @@ -693,34 +700,37 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): self._plot1D.stop() def _prepare_2D_scan(self): - settings = self._2D_settings gen_settings = self._gen_settings + if gen_settings.update_scan: + self._1D_settings.update_scan = True + self._2D_settings.update_scan = True + gen_settings.update_scan = False + settings = self._2D_settings self._stop_other() if self._requires_build(self._param2D, settings): logger.debug('Creating 2D scan') - self._update_gui_1D() self._prepare_scan() self._param2D = self._scan_generator.create_2D_scan( - settings["gate1_name"], - settings["V1_swing"], - settings["npt"], - settings["gate2_name"], - settings["V2_swing"], - settings["npt"], - settings["t_meas"]*1000, - pulse_gates=settings["offsets"], - biasT_corr=settings["biasT_corr"]) + settings["gate1_name"], + settings["V1_swing"], + settings["npt"], + settings["gate2_name"], + settings["V2_swing"], + settings["npt"], + settings["t_meas"]*1000, + pulse_gates=settings["offsets"], + biasT_corr=settings["biasT_corr"]) self._plot2D = _2D_live_plot( - self._2D_plotter_layout, - self._param2D, - gen_settings["n_columns"], - self._2D_av_progress, - gates=self.gates, - gate_values_label=self.gate_values_label, - on_mouse_moved=self._on_mouse_moved_2D, - on_mouse_clicked=self._on_mouse_clicked_2D) - self._plot2D.set_cross(settings["cross"]) # TODO make dynamic - self._plot2D.set_colorbar(settings["colorbar"]) # TODO make dynamic + self._2D_plotter_layout, + self._param2D, + gen_settings["n_columns"], + self._2D_av_progress, + gates=self.gates, + gate_values_label=self.gate_values_label, + on_mouse_moved=self._on_mouse_moved_2D, + on_mouse_clicked=self._on_mouse_clicked_2D) + self._plot2D.set_cross(settings["cross"]) # TODO make dynamic + self._plot2D.set_colorbar(settings["colorbar"]) # TODO make dynamic self.update_plot_properties_2D() self._set_metadata(2) settings.update_scan = False @@ -729,6 +739,7 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): else: self._param2D.restart() + self._update_gui_2D() self.vm_data_param_2D = vm_data_param(self._param2D, self._plot2D, self.metadata) @qt_log_exception @@ -793,9 +804,9 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): self._stop_1D() def _step(self): - if self.tab_id == 0: # 1D + if self.tab_id == 0: # 1D self._step_1D() - elif self.tab_id == 1: # 2D + elif self.tab_id == 1: # 2D self._step_2D() def _update_active_state(self): @@ -809,19 +820,19 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): self._stop_2D() if (self._gen_settings["virtual_matrix_auto_recompile"] - and self._pulselib_settings.has_changes()): - state = self.is_running - param = None - if state == "1D": - param = self._param1D - elif state == "2D": - param = self._param2D - else: - # not running - pass - if param: - if self._recompile_sequence(param): - self._pulselib_settings.store() + and self._pulselib_settings.has_changes()): + state = self.is_running + param = None + if state == "1D": + param = self._param1D + elif state == "2D": + param = self._param2D + else: + # not running + pass + if param: + if self._recompile_sequence(param): + self._pulselib_settings.store() def _stop_other(self): if not liveplotting.auto_stop_other: @@ -848,15 +859,15 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): return False def _play(self): - if self.tab_id == 0: # 1D + if self.tab_id == 0: # 1D self._start_1D() - elif self.tab_id == 1: # 2D + elif self.tab_id == 1: # 2D self.start_2D() def _reload(self): - if self.tab_id == 0: # 1D + if self.tab_id == 0: # 1D self.reload_1D() - elif self.tab_id == 1: # 2D + elif self.tab_id == 1: # 2D self.reload_2D() @qt_log_exception @@ -873,7 +884,7 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): self._param1D = None self._start_1D() - except: + except Exception: logger.error('Update plot failed', exc_info=True) @qt_log_exception @@ -890,7 +901,7 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): self._param2D = None self._start_2D() - except: + except Exception: logger.error('Update plot failed', exc_info=True) @qt_log_exception @@ -915,7 +926,7 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): max_swing = self._gen_settings["max_V_swing"] for v_spinner in [self._1D_V_swing, self._2D_V1_swing, self._2D_V2_swing]: v_spinner.setRange(-max_swing, max_swing) - if self.tab_id == 3: # favorites + if self.tab_id == 3: # favorites self._favorites._load_favorites() @qt_log_exception @@ -943,7 +954,8 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): # TODO improve HVI2 scheduler. Make it a qcodes instrument from core_tools.HVI2.scheduler_hardware import default_scheduler_hardware default_scheduler_hardware.release_schedule() - except: pass + except Exception: + pass if liveplotting.last_instance == self: liveplotting.last_instance = None @@ -966,14 +978,14 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): @property def vm_data_param(self): - if self.tab_id == 0: # 1D + if self.tab_id == 0: # 1D return self.vm_data_param_1D - if self.tab_id == 1: # 2D + if self.tab_id == 1: # 2D return self.vm_data_param_2D return None @qt_log_exception - def copy_ppt(self, inp_title = ''): + def copy_ppt(self, inp_title=''): """ ppt the data """ @@ -993,14 +1005,14 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): if type(inp_title) is not str: inp_title = '' - if self.tab_id == 0: # 1D + if self.tab_id == 0: # 1D figure_hand = self._plot1D.plot_widgets[0].plot_widget.parent() settings = self._1D_settings gate_x = settings["gate_name"] range_x = settings["V_swing"] channels = ','.join(self._param1D.channel_names) title = f'{gate_x} ({range_x:.0f} mV), m:{channels}' - elif self.tab_id == 1: # 2D + elif self.tab_id == 1: # 2D figure_hand = self._plot2D.plot_widgets[0].plot_widget.parent() settings = self._2D_settings gate_y = settings["gate2_name"] @@ -1018,9 +1030,9 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): def copy_to_clipboard(self): if self.vm_data_param is None: return - if self.tab_id == 0: # 1D + if self.tab_id == 0: # 1D frame = self._1D_plotter_frame - elif self.tab_id == 1: # 2D + elif self.tab_id == 1: # 2D frame = self._2D_plotter_frame else: return @@ -1036,9 +1048,9 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): if self.vm_data_param is None: print('no data to save') return - if self.tab_id == 0: # 1D + if self.tab_id == 0: # 1D label = self._1D_settings["gate_name"] - elif self.tab_id == 1: # 2D + elif self.tab_id == 1: # 2D settings = self._2D_settings label = settings["gate1_name"] + '_vs_' + settings["gate2_name"] else: @@ -1047,7 +1059,7 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): update = { "average": self.vm_data_param.plot.average_scans, "differentiate": self.vm_data_param.plot.gradient - } + } self.metadata.update(update) self.vm_data_param.load_metadata(update) @@ -1084,8 +1096,8 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): x_total = '' gate_name = self._1D_settings["gate_name"] self.cursor_value_label.setText( - f'{gate_name}:{x:7.2f}{x_total} mV, ' - f'{ch}:{v:7.2f} mV') + f'{gate_name}:{x:7.2f}{x_total} mV, ' + f'{ch}:{v:7.2f} mV') @qt_log_exception def _on_mouse_clicked_2D(self, x, y): @@ -1115,9 +1127,9 @@ class liveplotting(QtWidgets.QMainWindow, Ui_MainWindow): y_total = '' settings = self._2D_settings self.cursor_value_label.setText( - f'{settings["gate1_name"]}:{x:7.2f}{x_total} mV, ' - f'{settings["gate2_name"]}:{y:7.2f}{y_total} mV, ' - f'{ch}:{v:7.2f} mV') + f'{settings["gate1_name"]}:{x:7.2f}{x_total} mV, ' + f'{settings["gate2_name"]}:{y:7.2f}{y_total} mV, ' + f'{ch}:{v:7.2f} mV') class vm_data_param(MultiParameter): @@ -1134,10 +1146,10 @@ class vm_data_param(MultiParameter): self.param = param self.plot = plot super().__init__(name='video_mode_data', instrument=None, - names=names, labels=labels, units=units, - shapes=shapes, setpoints=setpoints, setpoint_names=setpoint_names, - setpoint_labels=setpoint_labels, setpoint_units=setpoint_units, - metadata=metadata) + names=names, labels=labels, units=units, + shapes=shapes, setpoints=setpoints, setpoint_names=setpoint_names, + setpoint_labels=setpoint_labels, setpoint_units=setpoint_units, + metadata=metadata) def snapshot_base(self, update: bool | None = True, -- GitLab