# explorer_widget.py
#
# This file is part of scqubits: a Python package for superconducting qubits,
# Quantum 5, 583 (2021). https://quantum-journal.org/papers/q-2021-11-17-583/
#
# Copyright (c) 2019 and later, Jens Koch and Peter Groszkowski
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.
############################################################################
import warnings
from typing import Any, Dict, List, Optional, TYPE_CHECKING, Tuple
from distutils.version import StrictVersion
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.axes import Axes
from matplotlib.figure import Figure
from matplotlib import get_backend as get_matplotlib_backend
import scqubits as scq
from scqubits.core.qubit_base import QubitBaseClass
from scqubits.core.param_sweep import ParameterSlice
from scqubits.explorer import explorer_panels as panels
from scqubits.ui.gui_defaults import (
composite_panel_names,
default_panels,
mode_dropdown_list,
subsys_panel_names,
)
from scqubits.utils import misc as utils
if TYPE_CHECKING:
from scqubits.core.param_sweep import ParameterSweep
try:
from IPython.display import display
except ImportError:
_HAS_IPYTHON = False
else:
_HAS_IPYTHON = True
try:
import ipywidgets
except ImportError:
_HAS_IPYWIDGETS = False
else:
_HAS_IPYWIDGETS = True
from ipywidgets import (
BoundedIntText,
Button,
Checkbox,
IntSlider,
Label,
Output,
SelectMultiple,
Tab,
ToggleButtons,
Layout,
Select,
SelectionSlider,
Dropdown,
HBox,
VBox,
HTML,
FloatSlider,
)
SEP = " | "
MATPLOTLIB_WIDGET_BACKEND = "module://ipympl.backend_nbagg"
_HAS_WIDGET_BACKEND = get_matplotlib_backend() == MATPLOTLIB_WIDGET_BACKEND
[docs]@utils.Required(ipywidgets=_HAS_IPYWIDGETS)
def width(pixels: int, justify_content: Optional[str] = None) -> Layout:
if justify_content:
return Layout(width=str(pixels) + "px", justify_content=justify_content)
return Layout(width=str(pixels) + "px")
[docs]@utils.Required(ipywidgets=_HAS_IPYWIDGETS)
def boxed(pixels: int = 900) -> Layout:
return Layout(
width=str(pixels) + "px",
align="top",
border="1px solid lightgrey",
padding="10px 10px 10px 10px",
)
[docs]class Explorer:
"""
Generates the UI for exploring `ParameterSweep` objects.
Parameters
----------
sweep:
the `ParameterSweep` object to be visualized.
"""
@utils.Required(ipywidgets=_HAS_IPYWIDGETS)
def __init__(self, sweep: scq.ParameterSweep):
"""Set up all widget GUI elements and class attributes."""
self.gui_display = ipywidgets.VBox()
self.gui_display.layout.width = "100%"
self.gui_display.layout.height = "1000px"
if _HAS_WIDGET_BACKEND and StrictVersion(
matplotlib.__version__
) < StrictVersion("3.5.1"):
warnings.warn(
"The widget backend requires Matplotlib >=3.5.1 for proper functioning",
UserWarning,
)
self.sweep = sweep
self.subsys_names = [subsys.id_str for subsys in self.sweep.hilbertspace]
self.subsys_types = {
subsys.id_str: type(subsys).__name__ for subsys in self.sweep.hilbertspace
}
self.subsys_types["Composite"] = "Composite" # for use in default_panels
self.ncols = 2 # number of columns used for axes in the figure display
self.fig, self.axes_table = self.build_figure_and_axes_table()
self.figwidth: float
self.figheight: float
# == GUI elements =========================================================
self.ui_hbox: Dict[str, HBox] = {}
self.ui_vbox: Dict[str, VBox] = {}
self.ui: Dict[str, Any] = {}
# +--------+---------+
# | TAB1 | TAB2 |
# +--------+---------+self.ui_main_tab-----------------------------------------+
# | |
# | self.ui_hbox["panels_select_tab"] |
# | - or - |
# | self.ui_vbox["panel_settings_tab"] |
# | |
# +----------------+-----------------------------------------------------------+
# | self.ui_hbox["main_display"] |
# | | |
# | | |
# | | |
# | self.ui_vbox | self["ui_figure_display"] = self.fig.canvas |
# | ["parameters- | - or - |
# | panel_left"] | = Output() |
# | | |
# | | |
# | | |
# +----------------+-----------------------------------------------------------+
self.ui_main_tab = self.build_ui_main_tab()
self.ui_hbox["main_display"] = self.build_ui_main_display()
self.gui_display.children = [self.ui_main_tab, self.ui_hbox["main_display"]]
display(self.gui_display)
def build_figure_and_axes_table(self) -> Tuple[Figure, np.ndarray]:
# the %inline and %widget backends somehow scale differently; try to compensate
if _HAS_WIDGET_BACKEND:
self.figwidth = 6.5 * 1.2
self.figheight = 2.75 * 1.2
else:
self.figwidth = 6.5
self.figheight = 2.75
plt.ioff()
fig = plt.figure(figsize=(self.figwidth, self.figheight))
fig.canvas.toolbar_position = "right"
fig.canvas.header_visible = False
fig.canvas.footer_visible = False
plt.ion()
axes_table = np.array([])
return fig, axes_table
# +--------+---------+
# | TAB1 | TAB2 |
# +--------+---------+self.ui_main_tab-----------------------------------------+
# | |
# | self.ui_hbox["panels_select_tab"] |
# | - or - |
# | self.ui_vbox["panel_settings_tab"] |
# | |
# +----------------+-----------------------------------------------------------+
def build_ui_main_tab(self) -> Tab:
self.ui_hbox["panels_select_tab"] = self.build_ui_panels_select_tab()
self.ui_vbox["panel_settings_tab"] = self.build_ui_settings_tab()
main_tab = Tab(
children=[
self.ui_hbox["panels_select_tab"],
self.ui_vbox["panel_settings_tab"],
]
)
main_tab.set_title(0, "Choose panels")
main_tab.set_title(1, "Panel settings")
return main_tab
# +----------------+-----------------------------------------------------------+
# | self.ui_hbox["main_display"] |
# | | |
# | | |
# | | |
# | self.ui_vbox | self["ui_figure_display"] = self.fig.canvas |
# | ["parameters- | - or - |
# | panel_left"] | = Output() |
# | | |
# | | |
# | | |
# +----------------+-----------------------------------------------------------+
def build_ui_main_display(self) -> HBox:
self.ui_vbox["parameters_panel_left"] = self.build_ui_parameters_panel_left()
self.ui["figure_display"] = self.build_ui_figure_display()
self.update_layout_and_plots(None)
return HBox([self.ui_vbox["parameters_panel_left"], self.ui["figure_display"]])
# +--------+
# | TAB1 |
# +-----------------------------------------------------------------------------+
# | subsys_dropdown html_label +-------------------------+ BTN |
# | | | |
# | checkbox checkbox | panels_list | |
# | checkbox checkbox | | |
# | ... ... +-------------------------+ |
# +-----------------------------------------------------------------------------+
def build_ui_panels_select_tab(self) -> HBox:
self.ui["subsys_dropdown"] = Dropdown(
options=self.subsys_names, layout=width(165)
)
self.ui["subsys_dropdown"].observe(self.on_subsys_change, "value")
ui_panels_checkboxes: Dict[str, Dict[str, Checkbox]] = {}
for subsys_name in self.subsys_names:
ui_panels_checkboxes[subsys_name] = {
panel_name: Checkbox(
value=self.get_toggle_value_default(subsys_name, panel_name),
description=panel_name,
layout=width(185),
style={"description_width": "initial"},
)
for panel_name in subsys_panel_names
}
ui_panels_checkboxes["Composite"] = {
panel_name: Checkbox(
value=self.get_toggle_value_default("Composite", panel_name),
description=panel_name,
layout=width(185),
style={"description_width": "initial"},
)
for panel_name in composite_panel_names
}
self.ui["panels_checkboxes"] = ui_panels_checkboxes
for subsys_name in self.subsys_names:
self.ui_vbox[subsys_name] = VBox(
[
self.ui["panels_checkboxes"][subsys_name][panel_name]
for panel_name in subsys_panel_names
]
)
self.ui_vbox["current_subsys"] = VBox(
children=self.ui_vbox[self.ui["subsys_dropdown"].value].children
)
self.ui_vbox["Composite"] = VBox(
[
self.ui["panels_checkboxes"]["Composite"][panel_name]
for panel_name in composite_panel_names
],
)
for _, checkbox_dict in self.ui["panels_checkboxes"].items():
for checkbox in checkbox_dict.values():
checkbox.observe(self.on_toggle_event, "value")
self.ui["strings_to_panel_checkboxes"] = {}
for name in self.ui["panels_checkboxes"].keys():
for panel_name in self.ui["panels_checkboxes"][name].keys():
string_id = name + SEP + panel_name
checkbox = self.ui["panels_checkboxes"][name][panel_name]
self.ui["strings_to_panel_checkboxes"][string_id] = checkbox
html_label = HTML(
"""<p style="border:1px; border-style:solid; border-color:lightgrey;
padding-left: 1em;">
Multi-system
</p>"""
)
self.ui_hbox["choose_panels_checkboxes_group"] = HBox(
[
VBox([self.ui["subsys_dropdown"], self.ui_vbox["current_subsys"]]),
VBox([html_label, self.ui_vbox["Composite"]]),
],
layout=width(400, justify_content="space-between"),
)
self.ui["panels_list"] = Select(options=self.selected_as_strings(), rows=8)
self.ui["delete_btn"] = Button(icon="trash", layout=width(35))
self.ui["delete_btn"].on_click(self.delete_panel)
self.ui_vbox["panels_list_group"] = VBox(
[HBox([self.ui["panels_list"], self.ui["delete_btn"]])]
)
self.ui_hbox["panels_select_tab_content"] = HBox(
[
self.ui_hbox["choose_panels_checkboxes_group"],
self.ui_vbox["panels_list_group"],
],
layout=width(800, justify_content="space-between"),
)
return self.ui_hbox["panels_select_tab_content"]
# +--------+
# | TAB2 |
# +-----------------------------------------------------------------------------+
# | panel_choice ---------+ |
# | panels_choice_dropdown| |
# | |
# | panel_settings ------------------------------+ |
# | ui["settings"][subsys_name][panel_name] |
# | |
# +-----------------------------------------------------------------------------+
def build_ui_settings_tab(self) -> VBox:
self.ui["subsys_panel_settings"] = {
subsys_name: {
panel_name: self.build_ui_settings_subsys(subsys_index, panel_name)
for panel_name in subsys_panel_names
}
for subsys_index, subsys_name in enumerate(self.subsys_names)
}
self.ui["transitions"] = {}
self.ui["composite_panel_settings"] = {
"Composite": {
panel_name: self.build_ui_settings_composite(panel_name)
for panel_name in composite_panel_names
}
}
self.ui["settings"] = {
**self.ui["subsys_panel_settings"],
**self.ui["composite_panel_settings"],
}
self.ui["panels_choice_dropdown"] = Dropdown(
options=self.get_panels_list(), layout=width(250)
)
self.ui["panels_choice_dropdown"].observe(self.activate_settings, "value")
if self.ui["panels_choice_dropdown"].value:
subsys_name, panel_name = self.ui["panels_choice_dropdown"].value.split(SEP)
self.ui_hbox["panel_settings"] = HBox(
children=self.ui["settings"][subsys_name][panel_name]
)
else:
self.ui_hbox["panel_settings"] = HBox([])
self.ui_hbox["panel_choice"] = HBox([self.ui["panels_choice_dropdown"]])
return VBox(
[
self.ui_hbox["panel_choice"],
HTML("<br>"),
self.ui_hbox["panel_settings"],
],
layout=Layout(width="100%"), # width(900),
)
# +--parameters_panel_left-----+
# | |
# | Active Sweep Parameter |
# | "sweep_param_dropdown" |
# | |
# | Sample Value |
# | "sweep_value_slider" |
# | |
# | Fixed Parameter(s) |
# | "fixed_param_sliders" |
# | ... |
# | |
# +----------------------------+
def build_ui_parameters_panel_left(self) -> VBox:
self.ui["sweep_param_dropdown"] = Dropdown(
options=self.sweep.param_info.keys(), layout=width(150)
)
self.ui["sweep_param_dropdown"].observe(self.update_fixed_sliders, "value")
self.ui["sweep_value_slider"] = SelectionSlider(
description=self.ui["sweep_param_dropdown"].value,
options=self.sweep.param_info[self.ui["sweep_param_dropdown"].value],
continuous_update=False,
style={"description_width": "initial"},
)
self.ui["sweep_value_slider"].layout.object_fit = "contain"
self.ui["sweep_value_slider"].layout.width = "95%"
self.ui["sweep_value_slider"].observe(self.update_plots, "value")
self.ui["fixed_param_sliders"] = None
self.ui_vbox["fixed_param_sliders"] = VBox([])
self.update_fixed_sliders(None)
return VBox(
[
VBox(
[
HTML("<br>Active sweep parameter"),
self.ui["sweep_param_dropdown"],
],
layout=width(185),
),
VBox([HTML("<br>Sample value"), self.ui["sweep_value_slider"]]),
HTML("<br>"),
self.ui_vbox["fixed_param_sliders"],
],
layout=boxed(260),
)
def build_ui_figure_display(self):
if _HAS_WIDGET_BACKEND:
out = self.fig.canvas
self.fig.tight_layout()
else:
out = Output(layout=width(750))
out.layout.object_fit = "contain"
out.layout.width = "100%"
with out:
out.clear_output(wait=True)
self.fig.tight_layout()
display(self.fig)
return out
def display_panel(
self,
full_panel_name: str,
param_slice: ParameterSlice,
fig_ax: Tuple[Figure, Axes],
):
subsys_name, panel_name = full_panel_name.split(SEP)
if subsys_name == "Composite":
subsys = None
else:
subsys = self.sweep.subsys_by_id_str(subsys_name)
if panel_name == "Energy spectrum":
panel_widget = self.ui["subsys_panel_settings"][subsys_name][panel_name]
panels.display_bare_spectrum(
self.sweep,
subsys,
param_slice,
fig_ax,
subtract_ground=panel_widget[1].value,
evals_count=panel_widget[0].value,
)
elif panel_name == "Wavefunctions" and isinstance(subsys, QubitBaseClass):
panels.display_bare_wavefunctions(self.sweep, subsys, param_slice, fig_ax)
elif panel_name == "Matrix elements" and isinstance(subsys, QubitBaseClass):
panel_widgets = self.ui["subsys_panel_settings"][subsys_name][panel_name]
(
opname_dropdown,
matrixscan_toggle,
mode_dropdown,
) = panel_widgets
if matrixscan_toggle.value == "fixed":
panels.display_matrixelements(
sweep=self.sweep,
subsys=subsys,
operator_name=opname_dropdown.value,
mode_str=mode_dropdown.value,
param_slice=param_slice,
fig_ax=fig_ax,
)
else:
panels.display_matrixelement_sweep(
sweep=self.sweep,
subsys=subsys,
operator_name=opname_dropdown.value,
mode_str=mode_dropdown.value,
param_slice=param_slice,
fig_ax=fig_ax,
)
elif panel_name == "Anharmonicity":
panels.display_anharmonicity(self.sweep, subsys, param_slice, fig_ax)
elif panel_name == "Transitions":
if self.ui["transitions"]["initial_dressed_inttext"].disabled:
initial_state = tuple(
inttext.value
for inttext in self.ui["transitions"]["initial_state_inttexts"]
)
else:
initial_state = self.ui["transitions"]["initial_dressed_inttext"].value
subsys_name_tuple = self.ui["transitions"]["highlight_selectmultiple"].value
if subsys_name_tuple == ():
subsys_list = None
else:
subsys_list = [
self.sweep.subsys_by_id_str(subsys_name)
for subsys_name in subsys_name_tuple
]
sidebands = self.ui["transitions"]["sidebands_checkbox"].value
photon_number = self.ui["transitions"]["photons_inttext"].value
panels.display_transitions(
self.sweep,
photon_number,
subsys_list,
initial_state,
sidebands,
param_slice,
fig_ax,
)
elif panel_name == "Self-Kerr":
panels.display_self_kerr(
sweep=self.sweep,
subsys=subsys,
param_slice=param_slice,
fig_ax=fig_ax,
)
elif panel_name == "Cross-Kerr, ac-Stark":
panels.display_cross_kerr(
sweep=self.sweep,
subsys1=self.sweep.get_subsys(0),
subsys2=self.sweep.get_subsys(1),
param_slice=param_slice,
fig_ax=fig_ax,
)
elif panel_name == "Custom data":
pass
@property
def all_selected(self) -> Dict[str, Checkbox]:
"""Returns a dictionary labeling all selected checkboxes by their names."""
return {
name: [
panel
for panel in self.ui["panels_checkboxes"][name].keys()
if self.ui["panels_checkboxes"][name][panel].value
]
for name in self.ui["panels_checkboxes"].keys()
}
[docs] def selected_as_strings(self) -> List[str]:
"""Returns a list of strings capturing the names of all panels selected via
the checkboxes."""
all_selected = self.all_selected
selected = []
for name in all_selected.keys():
for panel in all_selected[name]:
selected.append(name + SEP + panel)
return selected
[docs] def create_sliders(self) -> List[SelectionSlider]:
"""Returns a list of selection sliders, one for each parameter that is part
of the underlying ParameterSweep object."""
sliders = [
SelectionSlider(
description=param_name,
options=param_array,
continuous_update=False,
layout=Layout(width="95%", object_fit="contain"),
style={"description_width": "initial"},
)
for param_name, param_array in self.sweep.param_info.items()
if param_name != self.ui["sweep_param_dropdown"].value
]
for slider in sliders:
slider.observe(self.update_plots, "value")
return sliders
@property
def fixed_params(self) -> Dict[str, float]:
sliders = self.ui["fixed_param_sliders"]
return {slider.description: slider.value for slider in sliders}
def on_toggle_event(self, change):
self.ui["panels_list"].options = self.selected_as_strings()
self.ui["panels_choice_dropdown"].options = self.selected_as_strings()
self.update_layout_and_plots(change)
def on_subsys_change(self, change):
self.ui_vbox["current_subsys"].children = self.ui_vbox[
self.ui["subsys_dropdown"].value
].children
def activate_settings(self, change):
if self.ui["panels_choice_dropdown"].value:
subsys_name, panel_name = self.ui["panels_choice_dropdown"].value.split(SEP)
self.ui_hbox["panel_settings"].children = [
*self.ui["settings"][subsys_name][panel_name]
]
def delete_panel(self, change):
btn_string = self.ui["panels_list"].value
toggle_btn = self.ui["strings_to_panel_checkboxes"][btn_string]
toggle_btn.value = False # this triggers an on_toggle_event
def get_toggle_value_default(self, subsys_name, panel_name):
sys_type = self.subsys_types[subsys_name]
return panel_name in default_panels[sys_type]
def get_panels_list(self):
panels_list: List[str] = []
for subsys_name, btn_dict in self.ui["panels_checkboxes"].items():
for btn_name, btn in btn_dict.items():
if btn.value:
panels_list.append(subsys_name + SEP + btn_name)
return panels_list
def update_fixed_sliders(self, change):
self.ui["fixed_param_sliders"] = self.create_sliders()
self.ui_vbox["fixed_param_sliders"].children = [
HTML("Fixed parameter(s)"),
*self.ui["fixed_param_sliders"],
]
self.ui["sweep_value_slider"].description = self.ui[
"sweep_param_dropdown"
].value
self.ui["sweep_value_slider"].options = self.sweep.param_info[
self.ui["sweep_param_dropdown"].value
]
def bare_dressed_toggle(self, change):
if self.ui["transitions"]["initial_bare_dressed_toggle"].value == "bare":
self.ui["transitions"]["initial_dressed_inttext"].disabled = True
for inttext in self.ui["transitions"]["initial_state_inttexts"]:
inttext.disabled = False
else:
self.ui["transitions"]["initial_dressed_inttext"].disabled = False
for inttext in self.ui["transitions"]["initial_state_inttexts"]:
inttext.disabled = True
self.update_plots(change)
def fig_ax_by_index(self, index):
row_index = index // self.ncols
col_index = index % self.ncols
return self.fig, self.axes_table[row_index, col_index]
@property
def parameter_slice(self):
return ParameterSlice(
self.ui["sweep_param_dropdown"].value,
self.ui["sweep_value_slider"].value,
self.fixed_params,
list(self.sweep.param_info.keys()),
)
def update_layout_and_plots(self: "Explorer", change):
panels = self.get_panels_list()
nrows = len(panels) // self.ncols
if len(panels) % self.ncols != 0:
nrows += 1
for axes in self.fig.axes:
self.fig.delaxes(axes)
plt.ioff()
if len(panels) > 0:
self.axes_table = self.fig.subplots(
ncols=self.ncols,
nrows=nrows,
squeeze=False,
)
self.fig.set_size_inches(1.1 * self.figwidth, self.figheight * nrows)
unfilled_cols_in_last_row = (self.ncols - len(panels) % self.ncols) % self.ncols
if unfilled_cols_in_last_row != 0:
for col in range(self.ncols - unfilled_cols_in_last_row, self.ncols):
self.axes_table[-1, col].remove()
# self.panel_count = len(panels)
self.update_plots(None)
plt.ion()
if not _HAS_WIDGET_BACKEND:
with self.ui["figure_display"]:
self.ui["figure_display"].clear_output(wait=True)
self.fig.tight_layout()
display(self.fig)
def update_plots(self: "Explorer", change):
if not hasattr(self, "fig"):
return
param_val = self.ui["sweep_value_slider"].value
panels = self.get_panels_list()
param_slice = ParameterSlice(
self.ui["sweep_param_dropdown"].value,
param_val,
self.fixed_params,
list(self.sweep.param_info.keys()),
)
for axes in self.axes_table.flatten():
for item in axes.lines + axes.collections:
item.remove()
axes.set_prop_cycle(None)
axes.relim()
axes.autoscale_view()
for index, full_panel_name in enumerate(panels):
self.display_panel(
full_panel_name,
param_slice=param_slice,
fig_ax=self.fig_ax_by_index(index),
)
if not _HAS_WIDGET_BACKEND:
with self.ui["figure_display"]:
self.ui["figure_display"].clear_output(wait=True)
self.fig.tight_layout()
display(self.fig)
else:
self.fig.canvas.draw_idle()
self.fig.tight_layout()
def build_ui_settings_subsys(self, subsys_index: int, panel_name: str):
subsys = self.sweep.get_subsys(subsys_index)
if panel_name == "Energy spectrum":
evals_count = self.sweep.subsys_evals_count(subsys_index)
ui_level_slider = IntSlider(
description="Highest level",
min=1,
max=evals_count,
value=evals_count,
continuous_update=False,
layout=width(300),
)
ui_subtract_ground_checkbox = Checkbox(
description="subtract lowest energy", value=True, layout=width(300)
)
ui_level_slider.observe(self.update_plots, "value")
ui_subtract_ground_checkbox.observe(self.update_plots, "value")
return [ui_level_slider, ui_subtract_ground_checkbox]
if panel_name == "Wavefunctions":
if isinstance(subsys, (scq.FluxQubit, scq.ZeroPi, scq.Cos2PhiQubit)):
self.ui["wavefunction_selector"] = Select(
options=list(range(subsys.truncated_dim)), rows=6
)
else:
self.ui["wavefunction_selector"] = SelectMultiple(
options=list(range(subsys.truncated_dim)), rows=6
)
self.ui["mode_dropdown"] = Dropdown(
options=mode_dropdown_list,
description="Plot as:",
)
return [self.ui["wavefunction_selector"], self.ui["mode_dropdown"]]
if panel_name == "Matrix elements":
ui_mode_dropdown = Dropdown(
options=mode_dropdown_list,
description="Plot as:",
)
ui_matrixscan_toggle = ToggleButtons(options=["fixed", "sweep"])
ui_matrixscan_toggle.style.button_width = "55px"
ui_operator_dropdown = Dropdown(
options=subsys.get_operator_names(),
description="Operator",
)
ui_mode_dropdown.observe(self.update_plots, "value")
ui_operator_dropdown.observe(self.update_plots, "value")
ui_matrixscan_toggle.observe(self.update_layout_and_plots, "value")
return [ui_operator_dropdown, ui_matrixscan_toggle, ui_mode_dropdown]
return [HBox()]
def build_ui_settings_composite(self, panel_name: str):
if panel_name == "Transitions":
self.ui["transitions"]["initial_state_inttexts"] = [
BoundedIntText(
description="",
min=0,
max=subsys.truncated_dim,
value=0,
continuous_update=False,
layout=width(35),
)
for subsys in self.sweep.hilbertspace
]
self.ui["transitions"]["initial_dressed_inttext"] = BoundedIntText(
description="",
min=0,
max=self.sweep.hilbertspace.dimension,
value=0,
continuous_update=False,
layout=width(35),
disabled=True,
)
self.ui["transitions"]["photons_inttext"] = BoundedIntText(
value=1, min=1, max=5, description="", layout=width(35)
)
self.ui["transitions"]["highlight_selectmultiple"] = SelectMultiple(
description="",
options=self.subsys_names,
value=[self.subsys_names[0]],
rows=4,
layout=width(185),
)
self.ui["transitions"]["initial_bare_dressed_toggle"] = ToggleButtons(
options=["bare", "dressed"],
value="bare",
description="",
disable=False,
)
self.ui["transitions"][
"initial_bare_dressed_toggle"
].style.button_width = "45px"
self.ui["transitions"]["sidebands_checkbox"] = Checkbox(
description="show sidebands", value=False, layout=width(250)
)
for inttext in self.ui["transitions"]["initial_state_inttexts"]:
inttext.observe(self.update_plots, "value")
self.ui["transitions"]["initial_dressed_inttext"].observe(
self.update_plots, "value"
)
self.ui["transitions"]["photons_inttext"].observe(
self.update_plots, "value"
)
self.ui["transitions"]["highlight_selectmultiple"].observe(
self.update_plots, "value"
)
self.ui["transitions"]["sidebands_checkbox"].observe(
self.update_plots, "value"
)
self.ui["transitions"]["initial_bare_dressed_toggle"].observe(
self.bare_dressed_toggle, "value"
)
initial_state_selection = HBox(
[
Label("Initial state "),
*self.ui["transitions"]["initial_state_inttexts"],
self.ui["transitions"]["initial_bare_dressed_toggle"],
self.ui["transitions"]["initial_dressed_inttext"],
],
layout=Layout(width="400px", justify_content="flex-end"),
)
photon_options_selection = HBox(
[
Label("photons"),
self.ui["transitions"]["photons_inttext"],
self.ui["transitions"]["sidebands_checkbox"],
],
layout=Layout(width="400px", justify_content="flex-end"),
)
transition_highlighting = HBox(
[
Label("Highlight:"),
self.ui["transitions"]["highlight_selectmultiple"],
],
layout=Layout(width="400px", justify_content="flex-end"),
)
return [
initial_state_selection,
VBox([photon_options_selection, transition_highlighting]),
]