Using the Electron Unload Models

Installation

We recommend using pip, poetry, or uv to install the package.

$pip install conductorquantum

Authentication

The SDK requires an API key for authentication. Sign in and create a new API key. Remember, your API key is your access secret—keep it safe with environment variables.

Using environment variables:

Python
1from dotenv import load_dotenv
2import os
3from conductorquantum import ConductorQuantum
4
5# Load API key from .env file
6load_dotenv()
7TOKEN = os.getenv("CONDUCTOR_API_KEY")
8
9# Initialize client
10client = ConductorQuantum(token=TOKEN)

Or provide the API key directly:

Python
1from conductorquantum import ConductorQuantum
2
3# Initialize client with API key
4client = ConductorQuantum(token="YOUR_API_KEY")

Input Format

Both detectors expect a visualization-ready 2D array shaped (n_bias, n_voltage):

AxisDimensionDescription
Rowsn_biasResonator bias points (y-axis when plotted)
Columnsn_voltageUnload voltage sweep (x-axis when plotted)

This is the same layout you’d pass to imshow() or pcolormesh() — resonator bias on the vertical axis, unload voltage on the horizontal axis.

Coming from acquisition-format data? If your data is stored as (n_voltage, n_bias) — one bias trace per voltage point — transpose before calling the API. This matches the typical visualization convention with unload voltage on the x-axis and resonator bias on the y-axis:

1# If data.shape == (n_voltage, n_bias):
2api_input = data.T # → (n_bias, n_voltage)

Detecting Electron Unload Events

The Electron Unload Detector identifies the column indices in a two-dimensional resonator scan where electron unloading events occur.

Output Format

KeyTypeDescription
unload_indiceslist[int]Column indices where unload events were detected

Usage Example

Supply your own measurement data to follow along.

Python
1import os
2from dotenv import load_dotenv
3import numpy as np
4import matplotlib.pyplot as plt
5from conductorquantum import ConductorQuantum
6
7# Load API key from .env file
8load_dotenv()
9TOKEN = os.getenv("CONDUCTOR_API_KEY")
10client = ConductorQuantum(token=TOKEN)
11
12# Load your resonator measurement (shape: [n_bias, n_voltage])
13data = np.load("path/to/your/data.npy")
14
15# Run inference with the Electron Unload Detector
16results = client.models.execute(
17 model="electron-unload-detector-v0",
18 data=data,
19)
20
21# Access peak locations (column indices)
22unload_indices = results.output["unload_indices"]
23print(f"Detected electron unloading at: {unload_indices}")
24
25# Visualize the measurement and overlay detections
26plt.imshow(data, aspect="auto")
27for unload_index in unload_indices:
28 plt.axvline(x=unload_index, color="red", linewidth=3, alpha=0.8)
29
30plt.title("Electron Unload Detector v0")
31plt.xlabel("Unload voltage (a.u.)")
32plt.ylabel("Resonator bias (a.u.)")
33plt.colorbar(label="Frequency (a.u.)")
34plt.tight_layout()
35plt.show()
Sample output
1Detected electron unloading at: [10, 23, 32, 36, 39, 44, 49]

Using Physical Units

To plot with real voltage and frequency values, convert indices to coordinates:

Python
1# Your physical axes
2unload_voltages = np.linspace(-0.5, 0.5, data.shape[1]) # (n_voltage,)
3resonator_bias = np.linspace(0, 1, data.shape[0]) # (n_bias,)
4
5fig, ax = plt.subplots(figsize=(6, 4))
6im = ax.pcolormesh(
7 unload_voltages,
8 resonator_bias,
9 data / 1e9,
10 cmap="RdYlBu_r",
11 shading="auto",
12)
13
14# Convert indices to physical coordinates
15for unload_index in unload_indices:
16 if unload_index < len(unload_voltages):
17 voltage = unload_voltages[unload_index]
18 ax.axvline(x=voltage, color="black", linewidth=4, alpha=0.8)
19
20ax.set_xlabel("Unload Voltage (V)")
21ax.set_ylabel("Resonator Bias (V)")
22plt.colorbar(im, label="$f_0$ (GHz)")
23plt.title("Electron Unload Detector v0")
24plt.tight_layout()
25plt.show()

Detecting Texture Clusters

The Electron Unload Texture Detector locates contiguous resonator patterns that frequently co-occur with unloading transitions. Each cluster contains the row/column indices of its member pixels so you can overlay the detections directly on your measurement.

Output Format

KeyTypeDescription
texture_clusterslist[dict]List of detected texture regions
texture_clusters[i]["indices"]list[list[int]]Pixel coordinates as [row, col] pairs, matching [bias_idx, voltage_idx] in your input array

Usage Example

Python
1import os
2from dotenv import load_dotenv
3import numpy as np
4import matplotlib.pyplot as plt
5from conductorquantum import ConductorQuantum
6
7# Load API key from .env file
8load_dotenv()
9TOKEN = os.getenv("CONDUCTOR_API_KEY")
10client = ConductorQuantum(token=TOKEN)
11
12# Load your resonator measurement (shape: [n_bias, n_voltage])
13data = np.load("path/to/your/data.npy")
14
15results = client.models.execute(
16 model="electron-unload-texture-detector-v0",
17 data=data,
18)
19
20print("Raw results:", results)
21texture_clusters = results.output["texture_clusters"]
22
23plt.imshow(data, aspect="auto")
24
25for cluster in texture_clusters:
26 indices = np.array(cluster["indices"])
27 x_coords = indices[:, 1] # column = voltage index (x-axis)
28 y_coords = indices[:, 0] # row = bias index (y-axis)
29 plt.scatter(x_coords, y_coords, s=50, alpha=0.8)
30
31plt.title("Electron Unload Texture Detector v0")
32plt.xlabel("Unload voltage (a.u.)")
33plt.ylabel("Resonator bias (a.u.)")
34plt.colorbar(label="Frequency (a.u.)")
35plt.tight_layout()
36plt.savefig("electron-unload-texture-detector-v0.png")
37plt.show()
Sample output
1# 10 texture clusters detected
2texture_clusters = [
3 {"indices": [[2, 1], [3, 3], [4, 4], [7, 4]]},
4 {"indices": [[57, 6], [57, 7], [57, 8], [57, 9], [59, 10], [57, 11]]},
5 {"indices": [[23, 7], [23, 8], [23, 9]]},
6 ...
7]

Using Physical Units

To plot with real voltage and frequency values:

Python
1# Your physical axes
2unload_voltages = np.linspace(-0.5, 0.5, data.shape[1]) # (n_voltage,)
3resonator_bias = np.linspace(0, 1, data.shape[0]) # (n_bias,)
4
5fig, ax = plt.subplots(figsize=(6, 4))
6im = ax.pcolormesh(
7 unload_voltages,
8 resonator_bias,
9 data / 1e9,
10 cmap="magma",
11 shading="auto",
12)
13
14# Convert indices to physical coordinates
15for cluster in texture_clusters:
16 indices = np.array(cluster["indices"])
17 # indices[:, 0] = row = bias index (y-axis)
18 # indices[:, 1] = col = voltage index (x-axis)
19 voltage_coords = unload_voltages[indices[:, 1].astype(int)]
20 bias_coords = resonator_bias[indices[:, 0].astype(int)]
21 ax.scatter(voltage_coords, bias_coords, s=50, alpha=0.8)
22
23ax.set_xlabel("Unload Voltage (V)")
24ax.set_ylabel("Resonator Bias (V)")
25plt.colorbar(im, label="$f_0$ (GHz)")
26plt.title("Electron Unload Texture Detector v0")
27plt.tight_layout()
28plt.show()