From 8bf8bec92e0da8c4f1dda1e1d508b1ef84e20125 Mon Sep 17 00:00:00 2001 From: Serwan Asaad Date: Mon, 7 Oct 2024 15:09:41 +0200 Subject: [PATCH] clean up dash components --- .../control_panel/video_mode/__init__.py | 2 +- .../control_panel/video_mode/dash_tools.py | 100 ++++++++++++++ .../control_panel/video_mode/plotly_tools.py | 31 ----- .../video_mode/test_video_mode.py | 46 +++---- .../video_mode/test_video_mode_simulation.py | 2 +- .../control_panel/video_mode/video_mode.py | 124 ++++-------------- 6 files changed, 148 insertions(+), 157 deletions(-) create mode 100644 qualang_tools/control_panel/video_mode/dash_tools.py delete mode 100644 qualang_tools/control_panel/video_mode/plotly_tools.py diff --git a/qualang_tools/control_panel/video_mode/__init__.py b/qualang_tools/control_panel/video_mode/__init__.py index 7cae71ef..9561c5fb 100644 --- a/qualang_tools/control_panel/video_mode/__init__.py +++ b/qualang_tools/control_panel/video_mode/__init__.py @@ -1,4 +1,4 @@ -from qualang_tools.control_panel.video_mode.plotly_tools import * +from qualang_tools.control_panel.video_mode.dash_tools import * from qualang_tools.control_panel.video_mode.voltage_parameters import * from qualang_tools.control_panel.video_mode.inner_loop_actions import * from qualang_tools.control_panel.video_mode.scan_modes import * diff --git a/qualang_tools/control_panel/video_mode/dash_tools.py b/qualang_tools/control_panel/video_mode/dash_tools.py new file mode 100644 index 00000000..52c50244 --- /dev/null +++ b/qualang_tools/control_panel/video_mode/dash_tools.py @@ -0,0 +1,100 @@ +from dash import html +from dash_extensions.enrich import dcc +import plotly.graph_objects as go +import xarray as xr + + +__all__ = ["xarray_to_plotly"] + + +def xarray_to_plotly(da: xr.DataArray): + """Convert an xarray DataArray to a Plotly figure. + + Args: + da (xr.DataArray): The data array to convert. + + Returns: + plotly.graph_objects.Figure: A Plotly figure with the data. + """ + x_label = da.coords["x"].attrs.get("long_name", "x") + x_unit = da.coords["x"].attrs.get("units", "") + y_label = da.coords["y"].attrs.get("long_name", "y") + y_unit = da.coords["y"].attrs.get("units", "") + z_label = da.attrs.get("long_name", da.name or "Value") + z_unit = da.attrs.get("units", "") + + xaxis_label = f"{x_label} ({x_unit})" if x_unit else x_label + yaxis_label = f"{y_label} ({y_unit})" if y_unit else y_label + zaxis_label = f"{z_label} ({z_unit})" if z_unit else z_label + + fig = go.Figure( + go.Heatmap( + z=da.values, + x=da.coords["x"].values, + y=da.coords["y"].values, + colorscale="plasma", + colorbar=dict(title=zaxis_label), + ) + ) + fig.update_layout(xaxis_title=xaxis_label, yaxis_title=yaxis_label) + return fig + + +def create_input_field(id, label, value, debounce=True, input_style=None, div_style=None, unit=None, **kwargs): + if input_style is None: + input_style = {"width": "40px"} + + elements = [ + html.Label( + f"{label}:", + style={ + "text-align": "left", + "white-space": "nowrap", + "margin-left": "15px", + "margin-right": "5px", + }, + ), + dcc.Input( + id=id, + type="number", + value=value, + debounce=debounce, + style=input_style, + **kwargs, + ), + ] + if unit is not None: + elements.append(html.Label(unit, style={"text-align": "left", "margin-left": "15px"})) + + if div_style is not None: + div_style = {"display": "flex", "margin-bottom": "10px"} + + return html.Div(elements, style=div_style) + + +def create_axis_layout(axis, span, points, min_span, max_span): + return html.Div( + [ + html.Label(axis.upper(), style={"text-align": "left"}), + create_input_field( + id=f"{axis.lower()}-span", + label="Span", + value=span, + min=min_span, + max=max_span, + input_style={"width": "55px"}, + div_style={"display": "flex", "margin-bottom": "10px"}, + unit="V", + ), + create_input_field( + id=f"{axis.lower()}-points", + label="Points", + value=points, + min=1, + max=501, + step=1, + div_style={"display": "flex", "margin-bottom": "10px"}, + ), + ], + style={"display": "flex", "flex-direction": "row", "flex-wrap": "wrap"}, + ) diff --git a/qualang_tools/control_panel/video_mode/plotly_tools.py b/qualang_tools/control_panel/video_mode/plotly_tools.py deleted file mode 100644 index 863a6d02..00000000 --- a/qualang_tools/control_panel/video_mode/plotly_tools.py +++ /dev/null @@ -1,31 +0,0 @@ -import plotly.graph_objects as go -import xarray as xr -import logging - - -__all__ = ["xarray_to_plotly"] - - -def xarray_to_plotly(da: xr.DataArray): - x_label = da.coords["x"].attrs.get("long_name", "x") - x_unit = da.coords["x"].attrs.get("units", "") - y_label = da.coords["y"].attrs.get("long_name", "y") - y_unit = da.coords["y"].attrs.get("units", "") - z_label = da.attrs.get("long_name", da.name or "Value") - z_unit = da.attrs.get("units", "") - - xaxis_label = f"{x_label} ({x_unit})" if x_unit else x_label - yaxis_label = f"{y_label} ({y_unit})" if y_unit else y_label - zaxis_label = f"{z_label} ({z_unit})" if z_unit else z_label - - fig = go.Figure( - go.Heatmap( - z=da.values, - x=da.coords["x"].values, - y=da.coords["y"].values, - colorscale="plasma", - colorbar=dict(title=zaxis_label), - ) - ) - fig.update_layout(xaxis_title=xaxis_label, yaxis_title=yaxis_label) - return fig diff --git a/qualang_tools/control_panel/video_mode/test_video_mode.py b/qualang_tools/control_panel/video_mode/test_video_mode.py index e2b1b86a..d9bae899 100644 --- a/qualang_tools/control_panel/video_mode/test_video_mode.py +++ b/qualang_tools/control_panel/video_mode/test_video_mode.py @@ -1,5 +1,5 @@ # %% Imports -from qualang_tools.control_panel.video_mode.plotly_tools import * +from qualang_tools.control_panel.video_mode.dash_tools import * import numpy as np from matplotlib import pyplot as plt from qualang_tools.control_panel.video_mode.voltage_parameters import * @@ -78,32 +78,32 @@ live_plotter = VideoMode(data_acquirer=data_acquirer, update_interval=1) live_plotter.run(use_reloader=False) -# %% -scan_mode.plot_scan(11, 11) +# # %% +# scan_mode.plot_scan(11, 11) -# %% Generate QUA script -from qm import generate_qua_script +# # %% Generate QUA script +# from qm import generate_qua_script -qua_script = generate_qua_script(data_acquirer.generate_program(), config) -print(qua_script) +# qua_script = generate_qua_script(data_acquirer.generate_program(), config) +# print(qua_script) -# %% Simulate results -from qm import SimulationConfig +# # %% Simulate results +# from qm import SimulationConfig -prog = data_acquirer.generate_program() -simulation_config = SimulationConfig(duration=100000) # In clock cycles = 4ns -job = qmm.simulate(config, prog, simulation_config) -con1 = job.get_simulated_samples().con1 +# prog = data_acquirer.generate_program() +# simulation_config = SimulationConfig(duration=100000) # In clock cycles = 4ns +# job = qmm.simulate(config, prog, simulation_config) +# con1 = job.get_simulated_samples().con1 -con1.plot(analog_ports=["1", "2"]) +# con1.plot(analog_ports=["1", "2"]) -plt.figure() -plt.plot(con1.analog["1"], con1.analog["2"]) +# plt.figure() +# plt.plot(con1.analog["1"], con1.analog["2"]) -# %% -from qualang_tools.control_panel.video_mode.scan_modes import SwitchRasterScan -import numpy as np -scan_mode = SwitchRasterScan() -print(scan_mode.interleave_arr(np.arange(10))) -scan_mode.plot_scan(10, 10) -# %% +# # %% +# from qualang_tools.control_panel.video_mode.scan_modes import SwitchRasterScan +# import numpy as np +# scan_mode = SwitchRasterScan() +# print(scan_mode.interleave_arr(np.arange(10))) +# scan_mode.plot_scan(10, 10) +# # %% diff --git a/qualang_tools/control_panel/video_mode/test_video_mode_simulation.py b/qualang_tools/control_panel/video_mode/test_video_mode_simulation.py index 782cdf42..4bc88d27 100644 --- a/qualang_tools/control_panel/video_mode/test_video_mode_simulation.py +++ b/qualang_tools/control_panel/video_mode/test_video_mode_simulation.py @@ -1,4 +1,4 @@ -from qualang_tools.control_panel.video_mode.plotly_tools import * +from qualang_tools.control_panel.video_mode.dash_tools import * from qualang_tools.control_panel.video_mode.voltage_parameters import * from qualang_tools.control_panel.video_mode.data_acquirers import * from qualang_tools.control_panel.video_mode.video_mode import * diff --git a/qualang_tools/control_panel/video_mode/video_mode.py b/qualang_tools/control_panel/video_mode/video_mode.py index 1efef4a9..9388c892 100644 --- a/qualang_tools/control_panel/video_mode/video_mode.py +++ b/qualang_tools/control_panel/video_mode/video_mode.py @@ -7,7 +7,7 @@ import logging from qualang_tools.control_panel.video_mode.data_acquirers import BaseDataAcquirer -from .plotly_tools import xarray_to_plotly +from .dash_tools import create_axis_layout, create_input_field, xarray_to_plotly __all__ = ["VideoMode"] @@ -43,77 +43,6 @@ def __init__( self.app = DashProxy(__name__, title="Video Mode", transforms=[BlockingCallbackTransform(timeout=10)]) self.create_layout() - def _create_axis_layout(self, axis: str): - xy = axis.lower() - XY = axis.upper() - return html.Div( - [ - html.Label(XY, style={"text-align": "left"}), - html.Div( # span - [ - html.Label( - "Span:", - style={ - "text-align": "right", - "white-space": "nowrap", - "margin-left": "15px", - "margin-right": "5px", - }, - ), - dcc.Input( - id=f"{xy}-span", - type="number", - value=getattr(self.data_acquirer, f"{xy}_span"), - min=0.01, - max=getattr(self.data_acquirer, f"{xy}_span") * 2, - debounce=True, - style={ - "width": "55px", - "text-align": "right", - }, - ), - html.Label( - "V", - style={ - "text-align": "left", - "white-space": "nowrap", - "margin-left": "3px", - }, - ), - ], - style={"display": "flex", "margin-bottom": "10px"}, - ), - html.Div( # Points - [ - html.Label( - "Points:", - style={ - "text-align": "right", - "white-space": "nowrap", - "margin-left": "15px", - "margin-right": "5px", - }, - ), - dcc.Input( - id=f"{xy}-points", - type="number", - value=getattr(self.data_acquirer, f"{xy}_points"), - min=1, - max=501, - step=1, - debounce=True, - style={ - "width": "40px", - "text-align": "right", - }, - ), - ], - style={"display": "flex", "margin-bottom": "10px"}, - ), - ], - style={"display": "flex", "flex-direction": "row", "flex-wrap": "wrap"}, - ) - def create_layout(self): """ Create the layout for the video mode dashboard. @@ -164,40 +93,33 @@ def create_layout(self): "margin-bottom": "20px", }, ), - html.Div( # Integration + Averages - [ - html.Div( - [ - html.Label( - "Averages:", - style={ - "text-align": "left", - "white-space": "nowrap", - "margin-left": "15px", - "margin-right": "5px", - }, - ), - dcc.Input( - id="num-averages", - type="number", - value=self.data_acquirer.num_averages, - min=1, - step=1, - debounce=True, - style={"width": "40px"}, - ), - ], - style={"display": "flex", "margin-bottom": "10px"}, - ), - ], - style={ + create_input_field( + "num-averages", + "Averages", + self.data_acquirer.num_averages, + min=1, + step=1, + debounce=True, + div_style={ "display": "flex", "flex-direction": "row", "flex-wrap": "wrap", }, ), - self._create_axis_layout("x"), - self._create_axis_layout("y"), + create_axis_layout( + "x", + span=self.data_acquirer.x_span, + points=self.data_acquirer.x_points, + min_span=0.01, + max_span=self.data_acquirer.x_span * 2, + ), + create_axis_layout( + "y", + span=self.data_acquirer.y_span, + points=self.data_acquirer.y_points, + min_span=0.01, + max_span=self.data_acquirer.y_span * 2, + ), html.Div( # Update and Save buttons [ html.Button(