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.
Files changed (81) hide show
  1. qubitclient/__init__.py +5 -0
  2. qubitclient/draw/__init__.py +0 -0
  3. qubitclient/draw/optpipulsepltplotter.py +75 -0
  4. qubitclient/draw/optpipulseplyplotter.py +114 -0
  5. qubitclient/draw/pltmanager.py +50 -0
  6. qubitclient/draw/pltplotter.py +20 -0
  7. qubitclient/draw/plymanager.py +57 -0
  8. qubitclient/draw/plyplotter.py +21 -0
  9. qubitclient/draw/powershiftpltplotter.py +108 -0
  10. qubitclient/draw/powershiftplyplotter.py +194 -0
  11. qubitclient/draw/rabicospltplotter.py +74 -0
  12. qubitclient/draw/rabicosplyplotter.py +90 -0
  13. qubitclient/draw/rabipltplotter.py +66 -0
  14. qubitclient/draw/rabiplyplotter.py +86 -0
  15. qubitclient/draw/s21peakpltplotter.py +67 -0
  16. qubitclient/draw/s21peakplyplotter.py +124 -0
  17. qubitclient/draw/s21vfluxpltplotter.py +84 -0
  18. qubitclient/draw/s21vfluxplyplotter.py +163 -0
  19. qubitclient/draw/singleshotpltplotter.py +149 -0
  20. qubitclient/draw/singleshotplyplotter.py +324 -0
  21. qubitclient/draw/spectrum2dpltplotter.py +107 -0
  22. qubitclient/draw/spectrum2dplyplotter.py +244 -0
  23. qubitclient/draw/spectrum2dscopepltplotter.py +72 -0
  24. qubitclient/draw/spectrum2dscopeplyplotter.py +195 -0
  25. qubitclient/draw/spectrumpltplotter.py +106 -0
  26. qubitclient/draw/spectrumplyplotter.py +133 -0
  27. qubitclient/draw/t1fitpltplotter.py +76 -0
  28. qubitclient/draw/t1fitplyplotter.py +109 -0
  29. qubitclient/draw/t2fitpltplotter.py +70 -0
  30. qubitclient/draw/t2fitplyplotter.py +111 -0
  31. qubitclient/nnscope/nnscope.py +51 -0
  32. qubitclient/nnscope/nnscope_api/curve/__init__.py +0 -0
  33. qubitclient/nnscope/nnscope_api/curve/curve_type.py +15 -0
  34. qubitclient/nnscope/task.py +170 -0
  35. qubitclient/nnscope/utils/data_convert.py +114 -0
  36. qubitclient/nnscope/utils/data_parser.py +41 -0
  37. qubitclient/nnscope/utils/request_tool.py +41 -0
  38. qubitclient/nnscope/utils/result_parser.py +55 -0
  39. qubitclient/scope/scope.py +50 -0
  40. qubitclient/scope/scope_api/__init__.py +8 -0
  41. qubitclient/scope/scope_api/api/__init__.py +1 -0
  42. qubitclient/scope/scope_api/api/defined_tasks/__init__.py +1 -0
  43. qubitclient/scope/scope_api/api/defined_tasks/get_task_result_api_v1_tasks_demo_pk_get.py +155 -0
  44. qubitclient/scope/scope_api/api/defined_tasks/get_task_result_api_v1_tasks_scope_pk_get.py +155 -0
  45. qubitclient/scope/scope_api/api/defined_tasks/optpipulse_api_v1_tasks_scope_optpipulse_post.py +218 -0
  46. qubitclient/scope/scope_api/api/defined_tasks/powershift_api_v1_tasks_scope_powershift_post.py +218 -0
  47. qubitclient/scope/scope_api/api/defined_tasks/rabi_api_v1_tasks_scope_rabi_post.py +218 -0
  48. qubitclient/scope/scope_api/api/defined_tasks/rabicos_api_v1_tasks_scope_rabicospeak_post.py +218 -0
  49. qubitclient/scope/scope_api/api/defined_tasks/s21peak_api_v1_tasks_scope_s21peak_post.py +218 -0
  50. qubitclient/scope/scope_api/api/defined_tasks/s21vflux_api_v1_tasks_scope_s21vflux_post.py +218 -0
  51. qubitclient/scope/scope_api/api/defined_tasks/singleshot_api_v1_tasks_scope_singleshot_post.py +218 -0
  52. qubitclient/scope/scope_api/api/defined_tasks/spectrum2d_api_v1_tasks_scope_spectrum2d_post.py +218 -0
  53. qubitclient/scope/scope_api/api/defined_tasks/spectrum_api_v1_tasks_scope_spectrum_post.py +218 -0
  54. qubitclient/scope/scope_api/api/defined_tasks/t1fit_api_v1_tasks_scope_t1fit_post.py +218 -0
  55. qubitclient/scope/scope_api/api/defined_tasks/t1fit_api_v1_tasks_scope_t2fit_post.py +218 -0
  56. qubitclient/scope/scope_api/client.py +268 -0
  57. qubitclient/scope/scope_api/errors.py +16 -0
  58. qubitclient/scope/scope_api/models/__init__.py +31 -0
  59. qubitclient/scope/scope_api/models/body_optpipulse_api_v1_tasks_scope_optpipulse_post.py +83 -0
  60. qubitclient/scope/scope_api/models/body_powershift_api_v1_tasks_scope_powershift_post.py +83 -0
  61. qubitclient/scope/scope_api/models/body_rabi_api_v1_tasks_scope_rabi_post.py +83 -0
  62. qubitclient/scope/scope_api/models/body_rabicos_api_v1_tasks_scope_rabicospeak_post.py +83 -0
  63. qubitclient/scope/scope_api/models/body_s21_peak_api_v1_tasks_scope_s21_peak_post.py +83 -0
  64. qubitclient/scope/scope_api/models/body_s21_vflux_api_v1_tasks_scope_s21_vflux_post.py +83 -0
  65. qubitclient/scope/scope_api/models/body_singleshot_api_v1_tasks_scope_singleshot_post.py +83 -0
  66. qubitclient/scope/scope_api/models/body_spectrum_2d_api_v1_tasks_scope_spectrum_2d_post.py +83 -0
  67. qubitclient/scope/scope_api/models/body_spectrum_api_v1_tasks_scope_spectrum_post.py +83 -0
  68. qubitclient/scope/scope_api/models/body_t1_fit_api_v1_tasks_scope_t1_fit_post.py +83 -0
  69. qubitclient/scope/scope_api/models/body_t1_fit_api_v1_tasks_scope_t2_fit_post.py +83 -0
  70. qubitclient/scope/scope_api/models/http_validation_error.py +75 -0
  71. qubitclient/scope/scope_api/models/validation_error.py +88 -0
  72. qubitclient/scope/scope_api/types.py +54 -0
  73. qubitclient/scope/task.py +163 -0
  74. qubitclient/scope/utils/__init__.py +0 -0
  75. qubitclient/scope/utils/data_parser.py +20 -0
  76. qubitclient-0.1.4.dist-info/METADATA +173 -0
  77. qubitclient-0.1.4.dist-info/RECORD +81 -0
  78. qubitclient-0.1.4.dist-info/WHEEL +5 -0
  79. qubitclient-0.1.4.dist-info/licenses/LICENSE +674 -0
  80. qubitclient-0.1.4.dist-info/top_level.txt +1 -0
  81. 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 对象