qubitclient 0.1.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qubitclient/__init__.py +5 -0
- qubitclient/draw/__init__.py +0 -0
- qubitclient/draw/optpipulsepltplotter.py +75 -0
- qubitclient/draw/optpipulseplyplotter.py +114 -0
- qubitclient/draw/pltmanager.py +50 -0
- qubitclient/draw/pltplotter.py +20 -0
- qubitclient/draw/plymanager.py +57 -0
- qubitclient/draw/plyplotter.py +21 -0
- qubitclient/draw/powershiftpltplotter.py +108 -0
- qubitclient/draw/powershiftplyplotter.py +194 -0
- qubitclient/draw/rabicospltplotter.py +74 -0
- qubitclient/draw/rabicosplyplotter.py +90 -0
- qubitclient/draw/rabipltplotter.py +66 -0
- qubitclient/draw/rabiplyplotter.py +86 -0
- qubitclient/draw/s21peakpltplotter.py +67 -0
- qubitclient/draw/s21peakplyplotter.py +124 -0
- qubitclient/draw/s21vfluxpltplotter.py +84 -0
- qubitclient/draw/s21vfluxplyplotter.py +163 -0
- qubitclient/draw/singleshotpltplotter.py +149 -0
- qubitclient/draw/singleshotplyplotter.py +324 -0
- qubitclient/draw/spectrum2dpltplotter.py +107 -0
- qubitclient/draw/spectrum2dplyplotter.py +244 -0
- qubitclient/draw/spectrum2dscopepltplotter.py +72 -0
- qubitclient/draw/spectrum2dscopeplyplotter.py +195 -0
- qubitclient/draw/spectrumpltplotter.py +106 -0
- qubitclient/draw/spectrumplyplotter.py +133 -0
- qubitclient/draw/t1fitpltplotter.py +76 -0
- qubitclient/draw/t1fitplyplotter.py +109 -0
- qubitclient/draw/t2fitpltplotter.py +70 -0
- qubitclient/draw/t2fitplyplotter.py +111 -0
- qubitclient/nnscope/nnscope.py +51 -0
- qubitclient/nnscope/nnscope_api/curve/__init__.py +0 -0
- qubitclient/nnscope/nnscope_api/curve/curve_type.py +15 -0
- qubitclient/nnscope/task.py +170 -0
- qubitclient/nnscope/utils/data_convert.py +114 -0
- qubitclient/nnscope/utils/data_parser.py +41 -0
- qubitclient/nnscope/utils/request_tool.py +41 -0
- qubitclient/nnscope/utils/result_parser.py +55 -0
- qubitclient/scope/scope.py +50 -0
- qubitclient/scope/scope_api/__init__.py +8 -0
- qubitclient/scope/scope_api/api/__init__.py +1 -0
- qubitclient/scope/scope_api/api/defined_tasks/__init__.py +1 -0
- qubitclient/scope/scope_api/api/defined_tasks/get_task_result_api_v1_tasks_demo_pk_get.py +155 -0
- qubitclient/scope/scope_api/api/defined_tasks/get_task_result_api_v1_tasks_scope_pk_get.py +155 -0
- qubitclient/scope/scope_api/api/defined_tasks/optpipulse_api_v1_tasks_scope_optpipulse_post.py +218 -0
- qubitclient/scope/scope_api/api/defined_tasks/powershift_api_v1_tasks_scope_powershift_post.py +218 -0
- qubitclient/scope/scope_api/api/defined_tasks/rabi_api_v1_tasks_scope_rabi_post.py +218 -0
- qubitclient/scope/scope_api/api/defined_tasks/rabicos_api_v1_tasks_scope_rabicospeak_post.py +218 -0
- qubitclient/scope/scope_api/api/defined_tasks/s21peak_api_v1_tasks_scope_s21peak_post.py +218 -0
- qubitclient/scope/scope_api/api/defined_tasks/s21vflux_api_v1_tasks_scope_s21vflux_post.py +218 -0
- qubitclient/scope/scope_api/api/defined_tasks/singleshot_api_v1_tasks_scope_singleshot_post.py +218 -0
- qubitclient/scope/scope_api/api/defined_tasks/spectrum2d_api_v1_tasks_scope_spectrum2d_post.py +218 -0
- qubitclient/scope/scope_api/api/defined_tasks/spectrum_api_v1_tasks_scope_spectrum_post.py +218 -0
- qubitclient/scope/scope_api/api/defined_tasks/t1fit_api_v1_tasks_scope_t1fit_post.py +218 -0
- qubitclient/scope/scope_api/api/defined_tasks/t1fit_api_v1_tasks_scope_t2fit_post.py +218 -0
- qubitclient/scope/scope_api/client.py +268 -0
- qubitclient/scope/scope_api/errors.py +16 -0
- qubitclient/scope/scope_api/models/__init__.py +31 -0
- qubitclient/scope/scope_api/models/body_optpipulse_api_v1_tasks_scope_optpipulse_post.py +83 -0
- qubitclient/scope/scope_api/models/body_powershift_api_v1_tasks_scope_powershift_post.py +83 -0
- qubitclient/scope/scope_api/models/body_rabi_api_v1_tasks_scope_rabi_post.py +83 -0
- qubitclient/scope/scope_api/models/body_rabicos_api_v1_tasks_scope_rabicospeak_post.py +83 -0
- qubitclient/scope/scope_api/models/body_s21_peak_api_v1_tasks_scope_s21_peak_post.py +83 -0
- qubitclient/scope/scope_api/models/body_s21_vflux_api_v1_tasks_scope_s21_vflux_post.py +83 -0
- qubitclient/scope/scope_api/models/body_singleshot_api_v1_tasks_scope_singleshot_post.py +83 -0
- qubitclient/scope/scope_api/models/body_spectrum_2d_api_v1_tasks_scope_spectrum_2d_post.py +83 -0
- qubitclient/scope/scope_api/models/body_spectrum_api_v1_tasks_scope_spectrum_post.py +83 -0
- qubitclient/scope/scope_api/models/body_t1_fit_api_v1_tasks_scope_t1_fit_post.py +83 -0
- qubitclient/scope/scope_api/models/body_t1_fit_api_v1_tasks_scope_t2_fit_post.py +83 -0
- qubitclient/scope/scope_api/models/http_validation_error.py +75 -0
- qubitclient/scope/scope_api/models/validation_error.py +88 -0
- qubitclient/scope/scope_api/types.py +54 -0
- qubitclient/scope/task.py +163 -0
- qubitclient/scope/utils/__init__.py +0 -0
- qubitclient/scope/utils/data_parser.py +20 -0
- qubitclient-0.1.4.dist-info/METADATA +173 -0
- qubitclient-0.1.4.dist-info/RECORD +81 -0
- qubitclient-0.1.4.dist-info/WHEEL +5 -0
- qubitclient-0.1.4.dist-info/licenses/LICENSE +674 -0
- qubitclient-0.1.4.dist-info/top_level.txt +1 -0
- qubitclient-0.1.4.dist-info/zip-safe +1 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
from .pltplotter import QuantumDataPltPlotter
|
|
2
|
+
import matplotlib.pyplot as plt
|
|
3
|
+
import numpy as np
|
|
4
|
+
from matplotlib.lines import Line2D
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class RabiCosDataPltPlotter(QuantumDataPltPlotter):
|
|
8
|
+
def __init__(self):
|
|
9
|
+
super().__init__("rabicos")
|
|
10
|
+
|
|
11
|
+
def plot_result_npy(self, **kwargs):
|
|
12
|
+
result = kwargs.get('result')
|
|
13
|
+
dict_param = kwargs.get('dict_param')
|
|
14
|
+
|
|
15
|
+
if not result or not dict_param:
|
|
16
|
+
fig, ax = plt.subplots()
|
|
17
|
+
ax.text(0.5, 0.5, "No data", ha='center', transform=ax.transAxes)
|
|
18
|
+
plt.close(fig)
|
|
19
|
+
return fig
|
|
20
|
+
|
|
21
|
+
data = dict_param.item() if isinstance(dict_param, np.ndarray) else dict_param
|
|
22
|
+
image_dict = data.get("image", {})
|
|
23
|
+
qubit_names = list(image_dict.keys())
|
|
24
|
+
if not qubit_names:
|
|
25
|
+
fig, ax = plt.subplots()
|
|
26
|
+
ax.text(0.5, 0.5, "No qubits", ha='center', transform=ax.transAxes)
|
|
27
|
+
plt.close(fig)
|
|
28
|
+
return fig
|
|
29
|
+
|
|
30
|
+
cols = min(3, len(qubit_names))
|
|
31
|
+
rows = (len(qubit_names) + cols - 1) // cols
|
|
32
|
+
|
|
33
|
+
fig = plt.figure(figsize=(5.8 * cols, 4.5 * rows))
|
|
34
|
+
fig.suptitle("RabiCos Peak Detection", fontsize=14, y=0.96)
|
|
35
|
+
|
|
36
|
+
peaks_list = result.get("peaks", [])
|
|
37
|
+
confs_list = result.get("confs", [])
|
|
38
|
+
|
|
39
|
+
for q_idx, q_name in enumerate(qubit_names):
|
|
40
|
+
ax = fig.add_subplot(rows, cols, q_idx + 1)
|
|
41
|
+
item = image_dict[q_name]
|
|
42
|
+
if not isinstance(item, (list, tuple)) or len(item) < 2:
|
|
43
|
+
continue
|
|
44
|
+
|
|
45
|
+
x = np.asarray(item[0])
|
|
46
|
+
y = np.asarray(item[1])
|
|
47
|
+
|
|
48
|
+
ax.plot(x, y, 'b-', alpha=0.7, linewidth=1.5)
|
|
49
|
+
legend_elements = [Line2D([0], [0], color='blue', lw=1.5, label='Signal')]
|
|
50
|
+
|
|
51
|
+
if q_idx < len(peaks_list):
|
|
52
|
+
peaks = peaks_list[q_idx]
|
|
53
|
+
confs = confs_list[q_idx] if q_idx < len(confs_list) else []
|
|
54
|
+
for p_idx, (p, c) in enumerate(zip(peaks, confs)):
|
|
55
|
+
idx = np.argmin(np.abs(x - p))
|
|
56
|
+
ax.scatter(x[idx], y[idx], color='red', s=80, zorder=5)
|
|
57
|
+
ax.axvline(p, color='red', linestyle='--', alpha=0.8, linewidth=1.2)
|
|
58
|
+
ax.annotate(f"x={p:.4f}\nconf={c:.3f}",
|
|
59
|
+
(x[idx], y[idx]),
|
|
60
|
+
xytext=(8, 8), textcoords='offset points',
|
|
61
|
+
fontsize=8, color='darkred',
|
|
62
|
+
bbox=dict(boxstyle="round,pad=0.3", facecolor="yellow", alpha=0.7))
|
|
63
|
+
if p_idx == 0:
|
|
64
|
+
legend_elements.append(Line2D([0], [0], color='red', linestyle='--', lw=1.2, label='Peak'))
|
|
65
|
+
|
|
66
|
+
ax.set_title(q_name, fontsize=11, pad=10)
|
|
67
|
+
ax.set_xlabel("Time (µs)")
|
|
68
|
+
ax.set_ylabel("P(|1>)")
|
|
69
|
+
ax.grid(True, linestyle='--', alpha=0.5)
|
|
70
|
+
ax.legend(handles=legend_elements, fontsize=8, loc='upper right', framealpha=0.9)
|
|
71
|
+
|
|
72
|
+
plt.tight_layout(rect=[0, 0, 1, 0.94])
|
|
73
|
+
plt.close(fig)
|
|
74
|
+
return fig
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from .plyplotter import QuantumDataPlyPlotter
|
|
2
|
+
import plotly.graph_objects as go
|
|
3
|
+
from plotly.subplots import make_subplots
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class RabiCosDataPlyPlotter(QuantumDataPlyPlotter):
|
|
8
|
+
def __init__(self):
|
|
9
|
+
super().__init__("rabicos")
|
|
10
|
+
|
|
11
|
+
def plot_result_npy(self, **kwargs):
|
|
12
|
+
result = kwargs.get('result')
|
|
13
|
+
dict_param = kwargs.get('dict_param')
|
|
14
|
+
|
|
15
|
+
if not result or not dict_param:
|
|
16
|
+
fig = go.Figure()
|
|
17
|
+
fig.add_annotation(text="No data", xref="paper", yref="paper", x=0.5, y=0.5, showarrow=False)
|
|
18
|
+
return fig
|
|
19
|
+
|
|
20
|
+
data = dict_param.item() if isinstance(dict_param, np.ndarray) else dict_param
|
|
21
|
+
image_dict = data.get("image", {})
|
|
22
|
+
qubit_names = list(image_dict.keys())
|
|
23
|
+
if not qubit_names:
|
|
24
|
+
fig = go.Figure()
|
|
25
|
+
fig.add_annotation(text="No qubits", xref="paper", yref="paper", x=0.5, y=0.5, showarrow=False)
|
|
26
|
+
return fig
|
|
27
|
+
|
|
28
|
+
cols = min(3, len(qubit_names))
|
|
29
|
+
rows = (len(qubit_names) + cols - 1) // cols
|
|
30
|
+
|
|
31
|
+
fig = make_subplots(
|
|
32
|
+
rows=rows, cols=cols,
|
|
33
|
+
subplot_titles=qubit_names,
|
|
34
|
+
vertical_spacing=0.08,
|
|
35
|
+
horizontal_spacing=0.08,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
peaks_list = result.get("peaks", [])
|
|
39
|
+
confs_list = result.get("confs", [])
|
|
40
|
+
|
|
41
|
+
show_legend = True
|
|
42
|
+
for q_idx, q_name in enumerate(qubit_names):
|
|
43
|
+
row = q_idx // cols + 1
|
|
44
|
+
col = q_idx % cols + 1
|
|
45
|
+
|
|
46
|
+
item = image_dict[q_name]
|
|
47
|
+
if not isinstance(item, (list, tuple)) or len(item) < 2:
|
|
48
|
+
continue
|
|
49
|
+
|
|
50
|
+
x = np.asarray(item[0])
|
|
51
|
+
y = np.asarray(item[1])
|
|
52
|
+
|
|
53
|
+
fig.add_trace(
|
|
54
|
+
go.Scatter(x=x, y=y, mode='lines', name='Signal',
|
|
55
|
+
line=dict(color='blue'), showlegend=show_legend),
|
|
56
|
+
row=row, col=col
|
|
57
|
+
)
|
|
58
|
+
if show_legend:
|
|
59
|
+
show_legend = False
|
|
60
|
+
|
|
61
|
+
if q_idx < len(peaks_list):
|
|
62
|
+
peaks = peaks_list[q_idx]
|
|
63
|
+
confs = confs_list[q_idx] if q_idx < len(confs_list) else []
|
|
64
|
+
for p, c in zip(peaks, confs):
|
|
65
|
+
fig.add_trace(
|
|
66
|
+
go.Scatter(x=[p, p], y=[y.min(), y.max()],
|
|
67
|
+
mode='lines', line=dict(color='red', dash='dash'),
|
|
68
|
+
name='Peak', showlegend=(q_idx == 0)),
|
|
69
|
+
row=row, col=col
|
|
70
|
+
)
|
|
71
|
+
fig.add_trace(
|
|
72
|
+
go.Scatter(x=[p], y=[y.max() * 1.05],
|
|
73
|
+
mode='text', text=[f"conf: {c:.3f}"],
|
|
74
|
+
textposition="top center",
|
|
75
|
+
showlegend=False, textfont=dict(color="red", size=10)),
|
|
76
|
+
row=row, col=col
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
if row == rows:
|
|
80
|
+
fig.update_xaxes(title_text="Time", row=row, col=col)
|
|
81
|
+
if col == 1:
|
|
82
|
+
fig.update_yaxes(title_text="Amp", row=row, col=col)
|
|
83
|
+
|
|
84
|
+
fig.update_layout(
|
|
85
|
+
height=400 * rows,
|
|
86
|
+
width=520 * cols,
|
|
87
|
+
title_text="RabiCos – Peak Detection",
|
|
88
|
+
title_x=0.5,
|
|
89
|
+
)
|
|
90
|
+
return fig
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# src/draw/rabipltplotter.py
|
|
2
|
+
from .pltplotter import QuantumDataPltPlotter
|
|
3
|
+
import matplotlib.pyplot as plt
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class RabiDataPltPlotter(QuantumDataPltPlotter):
|
|
8
|
+
def __init__(self):
|
|
9
|
+
super().__init__("rabi")
|
|
10
|
+
|
|
11
|
+
def plot_result_npy(self, **kwargs):
|
|
12
|
+
result = kwargs.get('result')
|
|
13
|
+
dict_param = kwargs.get('dict_param')
|
|
14
|
+
|
|
15
|
+
if not result or not dict_param:
|
|
16
|
+
fig, ax = plt.subplots()
|
|
17
|
+
ax.text(0.5, 0.5, "No data", ha='center', transform=ax.transAxes)
|
|
18
|
+
plt.close(fig)
|
|
19
|
+
return fig
|
|
20
|
+
|
|
21
|
+
data = dict_param.item() if isinstance(dict_param, np.ndarray) else dict_param
|
|
22
|
+
image_dict = data.get('image', {})
|
|
23
|
+
qubit_names = list(image_dict.keys())
|
|
24
|
+
cols = min(3, len(qubit_names))
|
|
25
|
+
rows = (len(qubit_names) + cols - 1) // cols
|
|
26
|
+
|
|
27
|
+
fig = plt.figure(figsize=(5.8 * cols, 4.8 * rows))
|
|
28
|
+
fig.suptitle("Rabi Oscillation Fit", fontsize=14, y=0.96)
|
|
29
|
+
|
|
30
|
+
params_list = result.get("params_list", [])
|
|
31
|
+
r2_list = result.get("r2_list", [])
|
|
32
|
+
fit_data_list = result.get("fit_data_list", [])
|
|
33
|
+
|
|
34
|
+
for q_idx, q_name in enumerate(qubit_names):
|
|
35
|
+
ax = fig.add_subplot(rows, cols, q_idx + 1)
|
|
36
|
+
item = image_dict[q_name]
|
|
37
|
+
if not isinstance(item, (list, tuple)) or len(item) < 2:
|
|
38
|
+
continue
|
|
39
|
+
|
|
40
|
+
x_raw = np.asarray(item[0])
|
|
41
|
+
y_raw = np.asarray(item[1])
|
|
42
|
+
|
|
43
|
+
ax.plot(x_raw, y_raw, 'o', color='orange', markersize=5, label='Data', alpha=0.8)
|
|
44
|
+
|
|
45
|
+
if q_idx < len(fit_data_list):
|
|
46
|
+
y_fit = np.asarray(fit_data_list[q_idx])
|
|
47
|
+
x_fit = x_raw if len(y_fit) == len(x_raw) else np.linspace(x_raw.min(), x_raw.max(), len(y_fit))
|
|
48
|
+
ax.plot(x_fit, y_fit, '-', color='blue', linewidth=2.2, label='Fit')
|
|
49
|
+
|
|
50
|
+
if q_idx < len(params_list):
|
|
51
|
+
A, B, freq, phi, T2 = params_list[q_idx]
|
|
52
|
+
r2 = r2_list[q_idx] if q_idx < len(r2_list) else 0.0
|
|
53
|
+
text = (f"A={A:.3f}\nB={B:.3f}\nf={freq/1e6:.3f}MHz\n"
|
|
54
|
+
f"φ={phi:.3f}\nT2={T2:.1f}µs\nR²={r2:.4f}")
|
|
55
|
+
ax.text(0.04, 0.96, text, transform=ax.transAxes, va='top', fontsize=8,
|
|
56
|
+
bbox=dict(boxstyle="round,pad=0.4", facecolor="white", alpha=0.9))
|
|
57
|
+
|
|
58
|
+
ax.set_title(q_name, fontsize=11)
|
|
59
|
+
ax.set_xlabel("Time (ns)")
|
|
60
|
+
ax.set_ylabel("P(|1>)")
|
|
61
|
+
ax.grid(True, linestyle='--', alpha=0.5)
|
|
62
|
+
ax.legend(fontsize=8)
|
|
63
|
+
|
|
64
|
+
plt.tight_layout(rect=[0, 0, 1, 0.94])
|
|
65
|
+
plt.close(fig)
|
|
66
|
+
return fig
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# src/draw/rabiplyplotter.py
|
|
2
|
+
from .plyplotter import QuantumDataPlyPlotter
|
|
3
|
+
import plotly.graph_objects as go
|
|
4
|
+
from plotly.subplots import make_subplots
|
|
5
|
+
import numpy as np
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class RabiDataPlyPlotter(QuantumDataPlyPlotter):
|
|
9
|
+
def __init__(self):
|
|
10
|
+
super().__init__("rabi")
|
|
11
|
+
|
|
12
|
+
def plot_result_npy(self, **kwargs):
|
|
13
|
+
result = kwargs.get('result')
|
|
14
|
+
dict_param = kwargs.get('dict_param')
|
|
15
|
+
|
|
16
|
+
if not result or not dict_param:
|
|
17
|
+
fig = go.Figure()
|
|
18
|
+
fig.add_annotation(text="Missing data", xref="paper", yref="paper", x=0.5, y=0.5, showarrow=False)
|
|
19
|
+
return fig
|
|
20
|
+
|
|
21
|
+
data = dict_param.item() if isinstance(dict_param, np.ndarray) else dict_param
|
|
22
|
+
image_dict = data.get("image", {})
|
|
23
|
+
if not image_dict:
|
|
24
|
+
fig = go.Figure()
|
|
25
|
+
fig.add_annotation(text="No image data", xref="paper", yref="paper", x=0.5, y=0.5, showarrow=False)
|
|
26
|
+
return fig
|
|
27
|
+
|
|
28
|
+
qubit_names = list(image_dict.keys())
|
|
29
|
+
cols = min(3, len(qubit_names))
|
|
30
|
+
rows = (len(qubit_names) + cols - 1) // cols
|
|
31
|
+
|
|
32
|
+
fig = make_subplots(
|
|
33
|
+
rows=rows, cols=cols,
|
|
34
|
+
subplot_titles=qubit_names,
|
|
35
|
+
vertical_spacing=0.08,
|
|
36
|
+
horizontal_spacing=0.08,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
params_list = result.get("params_list", [])
|
|
40
|
+
r2_list = result.get("r2_list", [])
|
|
41
|
+
fit_data_list = result.get("fit_data_list", [])
|
|
42
|
+
|
|
43
|
+
data_legend = False
|
|
44
|
+
fit_legend = False
|
|
45
|
+
|
|
46
|
+
for q_idx, q_name in enumerate(qubit_names):
|
|
47
|
+
row = q_idx // cols + 1
|
|
48
|
+
col = q_idx % cols + 1
|
|
49
|
+
|
|
50
|
+
item = image_dict[q_name]
|
|
51
|
+
if not isinstance(item, (list, tuple)) or len(item) < 2:
|
|
52
|
+
continue
|
|
53
|
+
|
|
54
|
+
x_raw = np.asarray(item[0])
|
|
55
|
+
y_raw = np.asarray(item[1])
|
|
56
|
+
|
|
57
|
+
fig.add_trace(go.Scatter(x=x_raw, y=y_raw, mode='markers',
|
|
58
|
+
marker=dict(color='orange', size=7),
|
|
59
|
+
name='Data', showlegend=not data_legend), row=row, col=col)
|
|
60
|
+
if not data_legend:
|
|
61
|
+
data_legend = True
|
|
62
|
+
|
|
63
|
+
if q_idx < len(fit_data_list):
|
|
64
|
+
y_fit = np.asarray(fit_data_list[q_idx])
|
|
65
|
+
x_fit = x_raw if len(y_fit) == len(x_raw) else np.linspace(x_raw.min(), x_raw.max(), len(y_fit))
|
|
66
|
+
fig.add_trace(go.Scatter(x=x_fit, y=y_fit, mode='lines',
|
|
67
|
+
line=dict(color='blue', width=2.5),
|
|
68
|
+
name='Fit', showlegend=not fit_legend), row=row, col=col)
|
|
69
|
+
if not fit_legend:
|
|
70
|
+
fit_legend = True
|
|
71
|
+
|
|
72
|
+
if q_idx < len(params_list):
|
|
73
|
+
A, B, freq, phi, T2 = params_list[q_idx]
|
|
74
|
+
r2 = r2_list[q_idx] if q_idx < len(r2_list) else 0.0
|
|
75
|
+
txt = f"A={A:.3f}<br>B={B:.3f}<br>freq={freq/1e6:.3f}MHz<br>φ={phi:.3f}<br>T2={T2:.1f}µs<br>R²={r2:.4f}"
|
|
76
|
+
fig.add_annotation(x=x_raw[0], y=max(y_raw)*1.08, text=txt, showarrow=False,
|
|
77
|
+
font=dict(size=9), align="left",
|
|
78
|
+
bgcolor="rgba(255,255,255,0.8)", row=row, col=col)
|
|
79
|
+
|
|
80
|
+
if row == rows:
|
|
81
|
+
fig.update_xaxes(title_text="Time (ns)", row=row, col=col)
|
|
82
|
+
if col == 1:
|
|
83
|
+
fig.update_yaxes(title_text="P(|1>)", row=row, col=col)
|
|
84
|
+
|
|
85
|
+
fig.update_layout(height=420*rows, width=540*cols, title_text="Rabi Oscillation Fit", title_x=0.5)
|
|
86
|
+
return fig
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import matplotlib.pyplot as plt
|
|
3
|
+
from .pltplotter import QuantumDataPltPlotter
|
|
4
|
+
|
|
5
|
+
class S21PeakDataPltPlotter(QuantumDataPltPlotter):
|
|
6
|
+
def __init__(self):
|
|
7
|
+
super().__init__("s21peak")
|
|
8
|
+
|
|
9
|
+
def plot_result_npy(self, **kwargs):
|
|
10
|
+
result = kwargs.get('result')
|
|
11
|
+
dict_param = kwargs.get('dict_param')
|
|
12
|
+
|
|
13
|
+
dict_param = dict_param.item()
|
|
14
|
+
|
|
15
|
+
image = dict_param["image"]
|
|
16
|
+
q_list = image.keys()
|
|
17
|
+
x_list = []
|
|
18
|
+
amp_list = []
|
|
19
|
+
phi_list = []
|
|
20
|
+
q_name_list =[]
|
|
21
|
+
for idx, q_name in enumerate(q_list):
|
|
22
|
+
image_q = image[q_name]
|
|
23
|
+
x = image_q[0]
|
|
24
|
+
amp = image_q[1]
|
|
25
|
+
phi = image_q[2]
|
|
26
|
+
x_list.append((x))
|
|
27
|
+
amp_list.append((amp))
|
|
28
|
+
phi_list.append((phi))
|
|
29
|
+
q_name_list.append(q_name)
|
|
30
|
+
peaks_list = result['peaks']
|
|
31
|
+
confs_list = result['confs']
|
|
32
|
+
|
|
33
|
+
nums = len(x_list)
|
|
34
|
+
row = (nums // 3) + 1 if nums % 3 != 0 else nums // 3
|
|
35
|
+
col = 3
|
|
36
|
+
|
|
37
|
+
fig = plt.figure(figsize=(20, 20))
|
|
38
|
+
for i in range(len(x_list)):
|
|
39
|
+
x = x_list[i]
|
|
40
|
+
y1 = amp_list[i]
|
|
41
|
+
y2 = phi_list[i]
|
|
42
|
+
peaks = peaks_list[i]
|
|
43
|
+
confs = confs_list[i]
|
|
44
|
+
|
|
45
|
+
ax = fig.add_subplot(row, col, i + 1)
|
|
46
|
+
ax.plot(x, y1, 'b-', label='Amp Curve', linewidth=2)
|
|
47
|
+
ax.plot(x, y2, c='green', label='Phi Curve')
|
|
48
|
+
for j in range(len(peaks)):
|
|
49
|
+
ax.scatter(x[peaks[j]], y1[peaks[j]],
|
|
50
|
+
color = 'red', marker = '*', s = 100,
|
|
51
|
+
label = f'peak (conf: {confs[j]:.2f})',
|
|
52
|
+
zorder = 5)
|
|
53
|
+
ax.annotate(f'{confs[j]:.2f}',
|
|
54
|
+
(x[peaks[j]], y1[peaks[j]]),
|
|
55
|
+
textcoords = "offset points",
|
|
56
|
+
xytext = (0, 15), ha = 'center',
|
|
57
|
+
fontsize = 10, color = 'darkred',
|
|
58
|
+
label = f'(final (conf: {confs[j]:.2f})')
|
|
59
|
+
ax.axvline(x[peaks[j]], color="red", linestyle='--', alpha=0.8)
|
|
60
|
+
ax.set_title(f'{q_name_list[i]}', fontsize=14, fontweight='bold', pad=15)
|
|
61
|
+
# ax.legend()
|
|
62
|
+
plt.tight_layout()
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
return fig
|
|
67
|
+
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
from .plyplotter import QuantumDataPlyPlotter
|
|
2
|
+
import numpy as np
|
|
3
|
+
import plotly.graph_objects as go
|
|
4
|
+
from plotly.subplots import make_subplots
|
|
5
|
+
|
|
6
|
+
class S21PeakDataPlyPlotter(QuantumDataPlyPlotter):
|
|
7
|
+
|
|
8
|
+
def __init__(self):
|
|
9
|
+
super().__init__("s21peak")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def plot_result_npy(self, **kwargs):
|
|
13
|
+
|
|
14
|
+
result_param = kwargs.get('result')
|
|
15
|
+
dict_param = kwargs.get('dict_param')
|
|
16
|
+
dict_param = dict_param.item()
|
|
17
|
+
|
|
18
|
+
image = dict_param["image"]
|
|
19
|
+
q_list = image.keys()
|
|
20
|
+
x_list = []
|
|
21
|
+
amp_list = []
|
|
22
|
+
phi_list = []
|
|
23
|
+
qname_list=[]
|
|
24
|
+
for idx, q_name in enumerate(q_list):
|
|
25
|
+
image_q = image[q_name]
|
|
26
|
+
x = image_q[0]
|
|
27
|
+
amp = image_q[1]
|
|
28
|
+
phi = image_q[2]
|
|
29
|
+
x_list.append((x))
|
|
30
|
+
amp_list.append((amp))
|
|
31
|
+
phi_list.append((phi))
|
|
32
|
+
qname_list.append(q_name)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
peaks_list = result_param['peaks']
|
|
38
|
+
confs_list = result_param['confs']
|
|
39
|
+
|
|
40
|
+
nums = len(x_list)
|
|
41
|
+
row = (nums // 3) + 1 if nums % 3 != 0 else nums // 3
|
|
42
|
+
col = 3
|
|
43
|
+
|
|
44
|
+
fig = make_subplots(
|
|
45
|
+
rows=row, cols=col,
|
|
46
|
+
subplot_titles=qname_list,
|
|
47
|
+
vertical_spacing=0.015,
|
|
48
|
+
horizontal_spacing=0.1
|
|
49
|
+
# x_title="Bias",
|
|
50
|
+
# y_title="Frequency (GHz)"
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
for i in range(len(x_list)):
|
|
54
|
+
x = x_list[i]
|
|
55
|
+
y1 = amp_list[i]
|
|
56
|
+
y2 = phi_list[i]
|
|
57
|
+
peaks = peaks_list[i]
|
|
58
|
+
confs = confs_list[i]
|
|
59
|
+
|
|
60
|
+
current_row = i // col + 1
|
|
61
|
+
current_col = i % col + 1
|
|
62
|
+
|
|
63
|
+
# 添加幅度曲线
|
|
64
|
+
fig.add_trace(
|
|
65
|
+
go.Scatter(x=x, y=y1, mode='lines',
|
|
66
|
+
name='Amp Curve', line=dict(color='blue', width=2)),
|
|
67
|
+
row=current_row, col=current_col
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
# 添加相位曲线
|
|
71
|
+
fig.add_trace(
|
|
72
|
+
go.Scatter(x=x, y=y2, mode='lines',
|
|
73
|
+
name='Phi Curve', line=dict(color='green')),
|
|
74
|
+
row=current_row, col=current_col
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# 添加峰值点
|
|
78
|
+
for j in range(len(peaks)):
|
|
79
|
+
peak_x = x[peaks[j]]
|
|
80
|
+
peak_y = y1[peaks[j]]
|
|
81
|
+
conf = confs[j]
|
|
82
|
+
|
|
83
|
+
fig.add_trace(
|
|
84
|
+
go.Scatter(x=[peak_x], y=[peak_y], mode='markers',
|
|
85
|
+
marker=dict(symbol='star', size=12, color='red')),
|
|
86
|
+
row=current_row, col=current_col
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
# 添加峰值标注
|
|
90
|
+
fig.add_annotation(
|
|
91
|
+
x=peak_x, y=peak_y,
|
|
92
|
+
text=f'{conf:.2f}',
|
|
93
|
+
showarrow=False,
|
|
94
|
+
ax=0, ay=-30,
|
|
95
|
+
font=dict(size=10, color='darkred'),
|
|
96
|
+
row=current_row, col=current_col
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
# 添加垂直线
|
|
100
|
+
fig.add_vline(
|
|
101
|
+
x=peak_x, line_dash="dash",
|
|
102
|
+
line_color="red", opacity=0.8,
|
|
103
|
+
row=current_row, col=current_col
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# 更新布局配置
|
|
107
|
+
fig.update_layout(
|
|
108
|
+
height=500 * row,
|
|
109
|
+
width=900 * col,
|
|
110
|
+
margin=dict(r=60, t=60, b=60, l=60),
|
|
111
|
+
showlegend=False
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
fig.update_xaxes(
|
|
115
|
+
title_text="Bias",
|
|
116
|
+
title_font=dict(size=10), # 缩小字体
|
|
117
|
+
title_standoff=8 # 增加标题与坐标轴的距离(单位:像素)
|
|
118
|
+
)
|
|
119
|
+
fig.update_yaxes(
|
|
120
|
+
title_text="Frequency (GHz)",
|
|
121
|
+
title_font=dict(size=10),
|
|
122
|
+
title_standoff=8
|
|
123
|
+
)
|
|
124
|
+
return fig
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import matplotlib.pyplot as plt
|
|
3
|
+
from .pltplotter import QuantumDataPltPlotter
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class S21VfluxDataPltPlotter(QuantumDataPltPlotter):
|
|
7
|
+
def __init__(self):
|
|
8
|
+
super().__init__("s21vflux")
|
|
9
|
+
|
|
10
|
+
def plot_result_npy(self, **kwargs):
|
|
11
|
+
result = kwargs.get('result')
|
|
12
|
+
dict_param = kwargs.get('dict_param')
|
|
13
|
+
|
|
14
|
+
data = dict_param.item()
|
|
15
|
+
image = data["image"]
|
|
16
|
+
q_list = image.keys()
|
|
17
|
+
volt_list = []
|
|
18
|
+
freq_list = []
|
|
19
|
+
s_list = []
|
|
20
|
+
q_name_list=[]
|
|
21
|
+
for idx, q_name in enumerate(q_list):
|
|
22
|
+
image_q = image[q_name]
|
|
23
|
+
|
|
24
|
+
volt = image_q[0]
|
|
25
|
+
freq = image_q[1]
|
|
26
|
+
s = image_q[2]
|
|
27
|
+
volt_list.append(volt)
|
|
28
|
+
freq_list.append(freq)
|
|
29
|
+
s_list.append(s)
|
|
30
|
+
q_name_list.append(q_name)
|
|
31
|
+
coscurves_list = result['coscurves_list']
|
|
32
|
+
cosconfs_list = result['cosconfs_list']
|
|
33
|
+
lines_list = result['lines_list']
|
|
34
|
+
lineconfs_list = result['lineconfs_list']
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
nums = len(volt_list) * 2
|
|
38
|
+
row = (nums // 2) + 1 if nums % 2 != 0 else nums // 2
|
|
39
|
+
col = 2
|
|
40
|
+
|
|
41
|
+
fig, axes = plt.subplots(row, col, figsize=(10 * col, 4 * row))
|
|
42
|
+
|
|
43
|
+
axes = axes.flatten() # Flatten in case of multiple rows
|
|
44
|
+
|
|
45
|
+
for ii in range(nums):
|
|
46
|
+
ax = axes[ii]
|
|
47
|
+
|
|
48
|
+
volt = volt_list[ii//2]
|
|
49
|
+
freq = freq_list[ii//2]
|
|
50
|
+
s = s_list[ii//2]
|
|
51
|
+
|
|
52
|
+
c = ax.pcolormesh(freq, volt, s.T, shading='auto', cmap='viridis')
|
|
53
|
+
fig.colorbar(c, ax=ax, label='Intensity')
|
|
54
|
+
if (ii % 2 != 0):
|
|
55
|
+
centcol = len(freq) // 2
|
|
56
|
+
|
|
57
|
+
if coscurves_list[ii// 2]:
|
|
58
|
+
for j, curve in enumerate(coscurves_list[ii// 2]):
|
|
59
|
+
final_x_cos = [item[0] for item in curve]
|
|
60
|
+
final_y_cos = [item[1] for item in curve]
|
|
61
|
+
ax.plot(final_x_cos, final_y_cos, 'r')
|
|
62
|
+
if centcol < len(final_x_cos):
|
|
63
|
+
ax.text(final_x_cos[centcol], final_y_cos[centcol],
|
|
64
|
+
f"conf:{cosconfs_list[ii// 2][j]:.2f}", color='r', fontsize=12)
|
|
65
|
+
|
|
66
|
+
if lines_list[ii// 2]:
|
|
67
|
+
for j, line in enumerate(lines_list[ii// 2]):
|
|
68
|
+
final_x_line = [item[0] for item in line]
|
|
69
|
+
final_y_line = [item[1] for item in line]
|
|
70
|
+
ax.plot(final_x_line, final_y_line, 'r')
|
|
71
|
+
if centcol < len(final_x_line):
|
|
72
|
+
ax.text(final_x_line[centcol], final_y_line[centcol],
|
|
73
|
+
f"conf:{lineconfs_list[ii// 2][j]:.2f}", color='r', fontsize=12)
|
|
74
|
+
|
|
75
|
+
# ax.set_title('Smoothed Heatmap')
|
|
76
|
+
ax.set_xlabel('X-axis')
|
|
77
|
+
ax.set_ylabel('Y-axis')
|
|
78
|
+
ax.set_title(f"{q_name_list[ii//2]}")
|
|
79
|
+
# Hide unused subplots if any
|
|
80
|
+
for jj in range(nums, len(axes)):
|
|
81
|
+
fig.delaxes(axes[jj])
|
|
82
|
+
|
|
83
|
+
fig.tight_layout()
|
|
84
|
+
return fig # ✅ 返回 Figure 对象
|