Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
a875580
simulated data acquirer class
domess Jun 16, 2025
d037ff6
gitignore
domess Jun 16, 2025
34ed77e
class SimulatedDataAcquirer
domess Jun 19, 2025
de7e7b2
Merge remote-tracking branch 'upstream/main'
domess Jun 20, 2025
e94d234
Merge branch 'main' into wip/simulated-data-acquirer
domess Jun 20, 2025
0cd2e85
Simulated data acquirer based on QDarts is added.
domess Jun 25, 2025
70a17a0
Included voltage control component
domess Jul 3, 2025
0c9b5e3
Merge remote-tracking branch 'upstream/main'
domess Jul 3, 2025
5f0e37d
Merge branch 'main' into wip/simulated-data-acquirer
domess Jul 3, 2025
eed9cbd
Absolute voltage parameters
domess Jul 3, 2025
919eae4
Adjustments such that the simulated data acquirer both works with and…
domess Jul 4, 2025
2cf27e7
Barrier gates introduced
domess Jul 4, 2025
949df48
Deepcopy issue resolved
domess Jul 7, 2025
57cdb2a
Make simulation faster through slicing
domess Jul 7, 2025
68e5e1a
get_voltage_control_component() takes labels and sensor_number as inp…
domess Jul 7, 2025
e98890a
Put sensor_number into the simulated data acquirer constructor (__ini…
domess Jul 8, 2025
7e438af
Corrected file name (to --> two)
domess Jul 8, 2025
4af7ac2
ValueError in case the user provides labels, but the number of labels…
domess Jul 8, 2025
c0e1151
ValueError if an invalid sensor_number is given. Default sensor_numbe…
domess Jul 8, 2025
0162893
Merge remote-tracking branch 'upstream/main'
domess Jul 8, 2025
d27f034
Merge remote-tracking branch 'origin/main' into wip/simulated-data-ac…
domess Jul 8, 2025
45829ef
Fixed error in ParameterProtocol Definition to make it compatible wit…
Ulfgard Jul 4, 2025
c0be4b3
Added Callback functionality for VoltageControlComponent on setting o…
Ulfgard Jul 4, 2025
166b865
turned the update Delay of BasicParameter into a configurable quantity.
Ulfgard Jul 4, 2025
1bb5769
incorporated suggested changes
Ulfgard Jul 10, 2025
368b0ab
removed warning import
Ulfgard Jul 10, 2025
e4046f1
Merge remote-tracking branch 'ulfgard/parameters' into wip/measuremen…
domess Jul 11, 2025
43d6ba1
Introduces the added callback to VoltageControlComponent
domess Jul 11, 2025
9689a47
Minor comment
domess Jul 11, 2025
891b24d
Merge remote-tracking branch 'upstream/main'
domess Jul 11, 2025
9267db3
Merge branch 'main' into wip/simulated-data-acquirer-with-callback
domess Jul 11, 2025
03ecb8f
Button "compute compensation matrix"
domess Aug 11, 2025
c3d4448
Included the sensor tuning code, such that clicking on the "Compensat…
domess Aug 22, 2025
71b640b
Fixed bug of the sensor compensation button (range is now equal to ce…
domess Sep 2, 2025
ff498fb
For the "Compensate Sensors" button, there are two algorithms impleme…
domess Sep 2, 2025
36106c5
New button in the video mode app: Compute the slopes based on Gradien…
domess Sep 4, 2025
e789b86
Button "Compute Slopes from Image Gradients" is now working (first ve…
domess Sep 5, 2025
d65c7a0
Restructuring
domess Sep 8, 2025
0127aff
The normals are properly computed, the transformation matrix is displ…
domess Sep 17, 2025
d9887b8
Put vertical flip inside function compute_transformation_matrix_from_…
domess Sep 17, 2025
644aa96
Removed plots
domess Sep 17, 2025
d3b19d4
- Corrected the regularization term
domess Sep 18, 2025
39a5ff6
All parameters of the Compute Transformation Matrix button are now in…
domess Sep 18, 2025
6215fa2
Added another parameter to the config.py file. Added more documentation.
domess Sep 19, 2025
7923b65
Added __post_init__ validation inside the config dataclasses
domess Sep 19, 2025
da79e56
Added more documentation
domess Sep 19, 2025
8c7b185
Removed the sensor tuning button from this branch
domess Sep 19, 2025
b457b18
Minor documentation change
domess Sep 19, 2025
7bee971
Include virtualisation matrix in the simulated data acquirer.
domess Sep 22, 2025
20c9195
Adding image transformation after computing the transformation when p…
domess Sep 22, 2025
bc536a8
Button Compute Transformation Matrix can be pressed several times in …
domess Sep 23, 2025
3654be5
In case of exactly two annotated lines: Compute the transformation ma…
domess Sep 23, 2025
ff086d3
Added documentation
domess Sep 23, 2025
0d1afac
dataclasses should not be frozen
domess Sep 24, 2025
87d38e6
Included barrier levers in all (simulated) examples.
domess Sep 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/combined_video_mode_voltage_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ def main():
y_axis = video_mode_component.data_acquirer.y_axis
x_axis.offset_parameter = voltage_control_component.voltage_parameters[0]
y_axis.offset_parameter = voltage_control_component.voltage_parameters[1]
#logger.debug(f"offset parameter x-axis: {x_axis.offset_parameter}")
#logger.debug(f"voltage parameter 0: {voltage_control_component.voltage_parameters[0].get()}")

app = build_dashboard(
components=[video_mode_component, voltage_control_component],
Expand Down
192 changes: 192 additions & 0 deletions examples/combined_video_mode_voltage_control_simulated.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
"""
Example Script:
Video Mode with SimulatedDataAcquirer for a four dot transition with 2 sensors, and voltage control
No barrier gate is used in this example.
"""

from qua_dashboards.core import build_dashboard
from qua_dashboards.utils import setup_logging
from qua_dashboards.video_mode import (
SweepAxis,
SimulatedDataAcquirer,
VideoModeComponent,
)
from qua_dashboards.voltage_control import VoltageControlComponent
from qdarts.experiment import Experiment
import numpy as np

def get_video_mode_component() -> VideoModeComponent:
"""
Creates and returns a VideoModeComponent instance configured with a SimulatedDataAcquirer.

This function encapsulates the setup of the sweep axes and the data acquirer,
making it easy to reuse this configuration or import it into other scripts.

Returns:
VideoModeComponent: The configured video mode component.
"""
# Define the system

#All capacitances are given in aF
N = 6 #number of dots
C_DD=20* np.eye((N))/2 #The self-capacitance of each dot, NOTE: factor of 2 due to symmetrization
C_DD[0,1] = 10 #capacitance between dot 0 and dot 1 (Left double dot)
C_DD[2,3] = 7 #capacitance between dot 3 and dot 4 (Right double dot)

C_DD[0,4] = 1.6 #capacitance between sensor dot 4 and dot 0
C_DD[1,4] = 1.4 #capacitance between sensor dot 4 and dot 1
C_DD[2,5] = 1.4 #capacitance between sensor dot 5 and dot 2
C_DD[3,5] = 2 #capacitance between sensor dot 5 and dot 3
C_DD[1,2] = 6 #capacitance between the middle dots 2 and dot 3
C_DD = C_DD + C_DD.T

C_DG=11*np.eye(N) #dot-to-gate capacitances
#cross-capacitances
C_DG[0,1] = 1.5 #dot 0 from dot 1
C_DG[1,0] = 1.2 #dot 1 from dot 0
C_DG[2,3] = 1.3 #dot 2 from dot 3
C_DG[3,2] = 1.4 #dot 3 from dot 3

# Definition of the tunnel couplings in eV
# NOTE: we use the convention that tc is the energy gap at avoided crossing H = tc/2 sx
tunnel_couplings = np.zeros((N,N))
tunnel_couplings[0,1] = 50*1e-6
tunnel_couplings[1,0] = 50*1e-6
tunnel_couplings[2,3] = 60*1e-6
tunnel_couplings[3,2] = 60*1e-6

# Experiment configurations
capacitance_config = {
"C_DD" : C_DD, #dot-dot capacitance matrix
"C_Dg" : C_DG, #dot-gate capacitance matrix
"ks" : 4, #distortion of Coulomb peaks. NOTE: If None -> constant size of Coublomb peak
}

tunneling_config = {
"tunnel_couplings": tunnel_couplings, #tunnel coupling matrix
"temperature": 0.1, #temperature in Kelvin
"energy_range_factor": 5, #energy scale for the Hamiltonian generation. NOTE: Smaller -> faster but less accurate computation
}
sensor_config = {
"sensor_dot_indices": [4,5], #Indices of the sensor dots
"sensor_detunings": [-0.0005,-0.0005], #Detuning of the sensor dots
"noise_amplitude": {"fast_noise": 0.5*1e-6, "slow_noise": 1e-8}, #Noise amplitude for the sensor dots in eV
"peak_width_multiplier": 15, #Width of the sensor peaks in the units of thermal broadening m *kB*T/0.61.
}

# Set up experiment
experiment = Experiment(capacitance_config, tunneling_config, sensor_config)

# Arguments for the function that renders the capacitance CSD
unit = 'mV'
factor_mV_to_V = 1e-3
span_x = 20
span_y = 20
points_x = 50
points_y = 50

P=np.zeros((6,2))
P[0,0]=1
P[1,1]=1
state_hint_lower_left = [1,1,0,0,3,3]

args_sensor_scan_2D = {
"P": P,
"minV": [-span_x/2.*factor_mV_to_V,-span_y/2.*factor_mV_to_V],
"maxV": [ span_x/2.*factor_mV_to_V, span_y/2.*factor_mV_to_V],
"resolution": [points_x,points_y],
"state_hint_lower_left": state_hint_lower_left,
"cache": True,
"insitu_axis": None,
}

# Define the X-axis for the 2D scan.
x_axis = SweepAxis(
name="x", # Internal identifier for the axis.
label="X Coordinate", # Display label in the UI.
units=unit, # Physical units of the axis.
span=span_x, # The total range of the X-axis sweep.
points=points_x, # The number of points (pixels) along the X-axis.
)

# Define the Y-axis for the 2D scan.
y_axis = SweepAxis(
name="y", # Internal identifier for the axis.
label="Y Coordinate", # Display label in the UI.
units=unit, # Physical units of the axis.
span=span_y, # The total range of the Y-axis sweep.
points=points_y, # The number of points (pixels) along the Y-axis.
)

# Instantiate the SimulatedDataAcquirer.
# This acquirer simulates data fetching by generating random 2D arrays.
simulated_acquirer = SimulatedDataAcquirer(
component_id="simulated-data-acquirer", # Unique ID for Dash elements.
x_axis=x_axis,
y_axis=y_axis,
experiment = experiment,
args_rendering = args_sensor_scan_2D,
conversion_factor_unit_to_volt=factor_mV_to_V,
SNR=20, # Signal-to-noise ratio on simulated images
acquire_time=0.1, # Simulated delay (seconds) for acquiring one raw frame.
num_software_averages=5, # Number of raw frames to average for display.
acquisition_interval_s=0.5, # Target time (seconds) between acquiring raw frames.
sensor_number=1,
)

# Instantiate the VideoModeComponent.
# This is the main UI component that displays the live 2D plot and controls.
video_mode_component = VideoModeComponent(
component_id=VideoModeComponent.DEFAULT_COMPONENT_ID, # Uses a default ID.
data_acquirer=simulated_acquirer, # The source of the data.
# How often the frontend asks for new data (linked to acquirer's interval).
data_polling_interval_s=simulated_acquirer.acquisition_interval_s,
)
return video_mode_component

def get_voltage_control_component(video_mode_component, labels) -> VoltageControlComponent:
voltage_controller = video_mode_component.data_acquirer.get_voltage_control_component(labels=labels)
return voltage_controller


def main() -> None:
"""
Sets up logging, creates the VideoModeComponent, builds the dashboard,
and runs the Dash application server.
"""
# Configure logging for the application.
logger = setup_logging(__name__)
logger.info("Starting Video Mode application with SimulatedDataAcquirer (based on QDarts).")

# Get the configured VideoModeComponent.
video_mode_component = get_video_mode_component()
logger.info(
f"VideoModeComponent instance created: {video_mode_component.component_id}"
)

# Get the VoltageControlComponent
voltage_control_component = get_voltage_control_component(video_mode_component, labels=None)
logger.info(
f"VoltageControlComponent instance created: {voltage_control_component.component_id}"
)

logger.info("Building the dashboard...")
# Use build_dashboard to create the Dash app layout.
app = build_dashboard(
components=[video_mode_component,voltage_control_component], # List of dashboard components to include.
title="Video Mode Simulation (QDarts)", # Browser window title.
)

logger.info("Dashboard built. Starting Dash server on http://localhost:8050")
# Run the Dash server.
app.run(
debug=True, # Enables helpful Dash debugging features.
host="0.0.0.0", # Makes the server accessible on your local network.
port=8050, # Sets the server port.
use_reloader=False, # Often recommended for stability with background threads.
)


if __name__ == "__main__":
# This ensures that main() is called only when the script is executed directly.
main()
Loading