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,170 @@
1
+
2
+ import os
3
+ import requests
4
+
5
+ import io
6
+ import numpy as np
7
+
8
+
9
+ from qubitclient.nnscope.utils.data_convert import convert_spectrum_npy2npz,convert_spectrum_dict2npz
10
+
11
+ # load from npz file path
12
+ def load_from_npz_path(file_path_list:list[str]):
13
+ files = []
14
+ npydata = {}
15
+ npydata['id'] = 0
16
+ image_qs = {}
17
+ index = 0
18
+ for file_path in file_path_list:
19
+ if file_path.endswith('.npz'):
20
+ index+=1
21
+ with np.load(file_path, allow_pickle=True) as data: # 修改:添加 allow_pickle=True 参数
22
+ # file_contents[file_name] = dict(data) # 将 .npz 文件内容转换为字典
23
+ content = dict(data) # 将 .npz 文件内容转换为字典
24
+ image_qs[str(index)] = (content['iq_avg'],content['bias'],content['frequency'])
25
+ npydata['image'] = image_qs
26
+ with io.BytesIO() as buffer:
27
+ np.save(buffer, npydata)
28
+ bytes_obj = buffer.getvalue()
29
+ files.append(("request", ("None.npy", bytes_obj, "application/octet-stream")))
30
+ return files
31
+ # def load_from_npz_path(file_path_list:list[str]):
32
+ # files = []
33
+ # npydata = {}
34
+ # npydata['id'] = 0
35
+ # index = 0
36
+ # for file_path in file_path_list:
37
+ # if file_path.endswith('.npz'):
38
+ # index+=1
39
+ # with np.load(file_path, allow_pickle=True) as data: # 修改:添加 allow_pickle=True 参数
40
+ # # file_contents[file_name] = dict(data) # 将 .npz 文件内容转换为字典
41
+ # content = dict(data) # 将 .npz 文件内容转换为字典
42
+ # allq = content['image'].item()
43
+ # allq_downsample={}
44
+ # for q in allq.keys():
45
+ # singleq = allq[q]
46
+ # singleq_downsampe = (singleq[0][::1,::1],singleq[1][::1],singleq[2][::1])
47
+ # # iq = zoom(singleq[0],(2,1),order=1)
48
+ # # zero_arr = np.zeros((45,40))
49
+ # # iq = np.vstack((singleq[0],zero_arr))
50
+ # # # iq = np.vstack((singleq[0],singleq[0]))
51
+ # #
52
+ # # arr_2d = singleq[2].reshape(1,-1)
53
+ # # arr_zoomed = zoom(arr_2d,(1,2),order=1)
54
+ # # freq = arr_zoomed.flatten()
55
+ # #
56
+ # #
57
+ # # singleq_downsampe = (iq[::1,::1],singleq[1][::1],freq)
58
+ #
59
+ #
60
+ # # singleq_downsampe = (singleq[0],singleq[1],singleq[2])
61
+ #
62
+ # allq_downsample[q] = singleq_downsampe
63
+ # # allq_downsample = np.array(allq_downsample,dtype=object).reshape(())
64
+ # # npydata['image'] = (content['image'])
65
+ # npydata['image'] = allq_downsample
66
+ # with io.BytesIO() as buffer:
67
+ # np.save(buffer, npydata)
68
+ # bytes_obj = buffer.getvalue()
69
+ # files.append(("request", ("None.npy", bytes_obj, "application/octet-stream")))
70
+ # return files
71
+ def load_from_npy_path(file_path_list:list[str]):
72
+ files = []
73
+ for file_path in file_path_list:
74
+ if file_path.endswith('.npy'):
75
+ data = np.load(file_path, allow_pickle=True)
76
+ data = data.item() if isinstance(data, np.ndarray) else data
77
+ with io.BytesIO() as buffer:
78
+ np.save(buffer, data)
79
+ bytes_obj = buffer.getvalue()
80
+ files.append(("request", ("None.npy", bytes_obj, "application/octet-stream")))
81
+ return files
82
+ def load_from_npz_dict(dict_list:list[dict]):
83
+ files = []
84
+ npydata = {}
85
+ npydata['id'] = 0
86
+ image_qs = {}
87
+ for index,dict_obj in enumerate(dict_list):
88
+ image_qs[str(index)] = (dict_obj['iq_avg'], dict_obj['bias'], dict_obj['frequency'])
89
+ npydata['image'] = image_qs
90
+ with io.BytesIO() as buffer:
91
+ np.save(buffer, npydata)
92
+ bytes_obj = buffer.getvalue()
93
+ files.append(("request", ("None.npy", bytes_obj, "application/octet-stream")))
94
+ return files
95
+ def load_from_npy_dict(dict_list:list[dict]):
96
+ files = []
97
+ for dict_obj in dict_list:
98
+ with io.BytesIO() as buffer:
99
+ np.save(buffer, dict_obj)
100
+ bytes_obj = buffer.getvalue()
101
+ files.append(("request", ("None.npy",bytes_obj, "application/octet-stream")))
102
+ return files
103
+ def request_task(files,url,api_key,curve_type:str=None):
104
+ headers = {'Authorization': f'Bearer {api_key}'} # 添加API密钥到请求头
105
+ data = {
106
+ "curve_type":curve_type.value if curve_type else None
107
+ }
108
+ response = requests.post(url, files=files, headers=headers,data=data)
109
+ return response
110
+ def load_files(filepath_list: list[str|dict[str,np.ndarray]|np.ndarray]):
111
+ if len(filepath_list)<=0:
112
+ return []
113
+ else:
114
+ if isinstance(filepath_list[0], dict):
115
+ if "image" in filepath_list[0]:
116
+ return load_from_npy_dict(filepath_list)
117
+ else:
118
+ return load_from_npz_dict(filepath_list)
119
+ elif isinstance(filepath_list[0], np.ndarray):
120
+ filepath_list = [filepath_list[i].item() for i in range(len(filepath_list))]
121
+ return load_files(filepath_list)
122
+ elif isinstance(filepath_list[0], str):
123
+ if filepath_list[0].endswith('.npz'):
124
+ return load_from_npz_path(filepath_list)
125
+ elif filepath_list[0].endswith('.npy'):
126
+ return load_from_npy_path(filepath_list)
127
+ else:
128
+ return []
129
+
130
+
131
+
132
+ DEFINED_TASKS = {}
133
+ def task_register(func):
134
+ DEFINED_TASKS[func.__name__.lower()] = func
135
+ return func
136
+
137
+ def run_task(file_list: list[str|dict[str,np.ndarray]|np.ndarray],url,api_key,task_type:str,*args,**kwargs):
138
+ files = load_files(file_list)
139
+ response = DEFINED_TASKS[task_type.value](files,url,api_key,*args,**kwargs)
140
+ return response
141
+
142
+
143
+ @task_register
144
+ def test(files):
145
+
146
+ return "hello"
147
+
148
+ @task_register
149
+ def spectrum2d(files,url,api_key,curve_type):
150
+ spectrum2d_url = url + "/api/v1/tasks/nnscope/seglines"
151
+ response = request_task(files,spectrum2d_url,api_key,curve_type)
152
+ return response
153
+
154
+ from enum import Enum, unique
155
+ @unique
156
+ class NNTaskName(Enum):
157
+ # S21PEAK = "s21peak"
158
+ # OPTPIPULSE = "optpipulse"
159
+ # RABI = "rabi"
160
+ # RABICOS = "rabicos"
161
+ # S21VFLUX = "s21vflux"
162
+ # SINGLESHOT = "singleshot"
163
+ # SPECTRUM = "spectrum"
164
+ # T1FIT = "t1fit"
165
+ # T2FIT = "t2fit"
166
+ SPECTRUM2D = "spectrum2d"
167
+
168
+
169
+
170
+
@@ -0,0 +1,114 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (c) 2025 yaqiang.sun.
3
+ # This source code is licensed under the license found in the LICENSE file
4
+ # in the root directory of this source tree.
5
+ #########################################################################
6
+ # Author: yaqiangsun
7
+ # Created Time: 2025/10/24 15:54:07
8
+ ########################################################################
9
+
10
+
11
+ import numpy as np
12
+ import io
13
+ import os
14
+ import numpy as np
15
+ import cv2
16
+
17
+
18
+ def load_npz_file(file_path):
19
+ with np.load(file_path, allow_pickle=True) as data: # 修改:添加 allow_pickle=True 参数
20
+ # file_contents[file_name] = dict(data) # 将 .npz 文件内容转换为字典
21
+ content = dict(data) # 将 .npz 文件内容转换为字典
22
+ return content
23
+ def convert_data_to_image(npz_content):
24
+ content = npz_content
25
+ iq_avg = content["iq_avg"] # 二维数据
26
+ iq_avg_normalized = convert_complex_map__to_image(iq_avg=iq_avg)
27
+ return iq_avg_normalized
28
+ def convert_complex_map__to_image(iq_avg):
29
+ # 检查并转置
30
+ rows, cols = iq_avg.shape
31
+ if rows < cols:
32
+ iq_avg = iq_avg.T # 转置矩阵
33
+
34
+
35
+ # 取相位
36
+ phase = np.angle(iq_avg)
37
+ phase_normalized = ((phase + np.pi) / (2 * np.pi)) * 255
38
+ # 纵向归一化
39
+ phase_mean = phase_normalized.mean(axis=0, keepdims=True) # 形状(1,30)
40
+ ppase_std = phase_normalized.std(axis=0, keepdims=True) # 形状(1,30)
41
+ phase_normalized = (phase_normalized - phase_mean) / (ppase_std+1e-8)
42
+ # phase_normalized = phase_normalized.astype(np.uint8)
43
+ # 全局归一化
44
+ phase_normalized = cv2.normalize(phase_normalized, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U)
45
+
46
+ # 取幅度
47
+ iq_avg = np.abs(iq_avg)
48
+
49
+ # iq_avg = phase_normalized
50
+ # 纵向归一化
51
+ # mean = iq_avg.mean(axis=0, keepdims=True) # 形状(1,30)
52
+ # std = iq_avg.std(axis=0, keepdims=True) # 形状(1,30)
53
+ # iq_avg = (iq_avg - mean) / (std+1e-8)
54
+ # 幅度全局归一化
55
+ iq_avg_normalized = cv2.normalize(iq_avg, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U)
56
+ # return iq_avg_normalized
57
+
58
+ #取幅度的梯度
59
+ gradient_y, gradient_x = np.gradient(iq_avg)
60
+ gradient_y = np.abs(gradient_y)
61
+ gradient_y_normalized = cv2.normalize(gradient_y, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U)
62
+
63
+ # iq_avg_normalized = cv2.merge([iq_avg_normalized, phase_normalized, gradient_y_normalized])
64
+ iq_avg_normalized = cv2.merge([iq_avg_normalized, iq_avg_normalized, iq_avg_normalized])
65
+ return iq_avg_normalized
66
+
67
+
68
+ def load_npz_to_image(file_path):
69
+ npz_content = load_npz_file(file_path)
70
+ image = convert_data_to_image(npz_content)
71
+ return image
72
+
73
+ def convert_spectrum_npy2npz(npy_file_path:str):
74
+ data = np.load(npy_file_path, allow_pickle=True)
75
+ data = data.item() if isinstance(data, np.ndarray) else data
76
+ dict_list, name_list = convert_spectrum_dict2npz(data,npy_file_path)
77
+ return dict_list, name_list
78
+ def convert_spectrum_dict2npz(data:dict,npy_file_path:str="None.npy"):
79
+ if not isinstance(data, dict) or 'image' not in data:
80
+ raise ValueError("数据格式无效,缺少 'image' 键")
81
+ image = data["image"]
82
+ q_list = image.keys()
83
+
84
+ dict_list = []
85
+ name_list = []
86
+
87
+ for idx, q_name in enumerate(q_list):
88
+ image_q = image[q_name]
89
+
90
+ data = image_q[0]
91
+ if data.ndim != 2:
92
+ raise ValueError("数据格式无效,data不是二维数组")
93
+ data = np.array(data)
94
+ data = np.abs(data)
95
+ height_axis = image_q[1]
96
+ width_axis = image_q[2]
97
+ new_dict = {}
98
+ new_dict["iq_avg"] = data
99
+ new_dict["frequency"] = image_q[2]
100
+ new_dict["bias"] = image_q[1]
101
+
102
+ npz_file_path = npy_file_path.replace(".npy", f"{q_name}.npz")
103
+ dict_list.append(new_dict)
104
+ name_list.append(npz_file_path)
105
+ # npz_file_path = npz_file_path.replace("npyfile","npyconverted")
106
+ # np.savez(npz_file_path,**new_dict)
107
+ # np.savez(npz_file_path,iq_avg=image_q[0],frequency=image_q[2],bias=image_q[1])
108
+ return dict_list, name_list
109
+
110
+ if __name__ == '__main__':
111
+ npy_file_path = "tmp/npyfile/tmp0ffc025b.py_4905.npy"
112
+ convert_spectrum_npy2npz(npy_file_path)
113
+
114
+ image = load_npz_to_image("tmp/npyconverted/tmp0ffc025b.py_4905Q6.npz")
@@ -0,0 +1,41 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (c) 2025 yaqiang.sun.
3
+ # This source code is licensed under the license found in the LICENSE file
4
+ # in the root directory of this source tree.
5
+ #########################################################################
6
+ # Author: yaqiangsun
7
+ # Created Time: 2025/04/11 17:58:29
8
+ ########################################################################
9
+
10
+ import os
11
+ import numpy as np
12
+ import cv2
13
+
14
+
15
+ def load_npz_file(file_path):
16
+ with np.load(file_path, allow_pickle=True) as data:
17
+ content = dict(data)
18
+ return content
19
+ def convert_data_to_image(npz_content):
20
+ content = npz_content
21
+ iq_avg = content["iq_avg"]
22
+ rows, cols = iq_avg.shape
23
+ if rows < cols:
24
+ iq_avg = iq_avg.T
25
+ iq_avg = np.abs(iq_avg)
26
+ iq_avg_normalized = cv2.normalize(iq_avg, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U)
27
+ return iq_avg_normalized
28
+
29
+ def load_npz_to_image(file_path):
30
+ npz_content = load_npz_file(file_path)
31
+ image = convert_data_to_image(npz_content)
32
+ return image
33
+
34
+ def load_npz_to_images(file_path_list):
35
+ images = []
36
+ for file_path in file_path_list:
37
+ print(file_path)
38
+ image = load_npz_to_image(file_path)
39
+ images.append(image)
40
+ # cv2.imwrite("tmp/client/test.jpg",image)
41
+ return images
@@ -0,0 +1,41 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (c) 2025 yaqiang.sun.
3
+ # This source code is licensed under the license found in the LICENSE file
4
+ # in the root directory of this source tree.
5
+ #########################################################################
6
+ # Author: yaqiangsun
7
+ # Created Time: 2025/04/15 10:31:23
8
+ ########################################################################
9
+ import os
10
+ import requests
11
+ import io
12
+ import numpy as np
13
+ from qubitclient.nnscope.nnscope_api.curve.curve_type import CurveType
14
+
15
+
16
+ def file_request(file_path_list,url,api_key,curve_type:CurveType=None):
17
+ files = []
18
+ for file_path in file_path_list:
19
+ if file_path.endswith('.npz'):
20
+ file_name = os.path.basename(file_path)
21
+ files.append(("request", (file_name, open(file_path, "rb"), "image/jpeg")))
22
+ headers = {'Authorization': f'Bearer {api_key}'} # 添加API密钥到请求头
23
+ data = {
24
+ "curve_type":curve_type.value if curve_type else None
25
+ }
26
+ response = requests.post(url, files=files, headers=headers,data=data)
27
+ return response
28
+
29
+ def file_request_with_dict(dict_list,url,api_key,curve_type:str=None):
30
+ files = []
31
+ for index,dict_obj in enumerate(dict_list):
32
+ with io.BytesIO() as buffer:
33
+ np.savez(buffer, **dict_obj)
34
+ bytes_obj = buffer.getvalue()
35
+ files.append(("request", ("None"+str(index)+".npz", bytes_obj, "application/octet-stream")))
36
+ headers = {'Authorization': f'Bearer {api_key}'} # 添加API密钥到请求头
37
+ data = {
38
+ "curve_type":curve_type.value if curve_type else None
39
+ }
40
+ response = requests.post(url, files=files, headers=headers,data=data)
41
+ return response
@@ -0,0 +1,55 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (c) 2025 yaqiang.sun.
3
+ # This source code is licensed under the license found in the LICENSE file
4
+ # in the root directory of this source tree.
5
+ #########################################################################
6
+ # Author: yaqiangsun
7
+ # Created Time: 2025/04/15 10:23:27
8
+ ########################################################################
9
+
10
+ import math
11
+ import cv2
12
+
13
+ def parser_result(result, images):
14
+ result_images = []
15
+ for i in range(len(result)):
16
+ image = images[i]
17
+ if len(image.shape) == 2:
18
+ image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
19
+ # input_image_reshape = (512, 512)
20
+ input_image_reshape = (image.shape[1]*10,image.shape[0])
21
+ image = cv2.resize(image, input_image_reshape, interpolation=cv2.INTER_NEAREST)
22
+
23
+
24
+ image_result = result[i]
25
+ linepoints_list = image_result["linepoints_list"]
26
+ for linepoints in linepoints_list:
27
+ for j in range(len(linepoints) - 1):
28
+ cv2.line(image, tuple([int(linepoints[j][0]*10),int(linepoints[j][1])]), tuple([int(linepoints[j + 1][0]*10),int(linepoints[j + 1][1])]), (0, 255, 0), 2)
29
+
30
+ # cv2.imwrite(f"tmp/client/result_{i}.jpg", image)
31
+ result_images.append(image)
32
+ return result_images
33
+
34
+ def convet_axis(points,x_dim,y_dim):
35
+ reflection_points = []
36
+ for point in points:
37
+ x = point[0]
38
+ y = point[1]
39
+
40
+ x_grid_start = x_dim[int(x)]
41
+ x_grid_end = x_dim[min(int(x)+1,len(x_dim)-1)]
42
+ x_refletion = (x_grid_end-x_grid_start)* math.modf(x)[0] + x_grid_start
43
+
44
+
45
+ # y_index = min(max(0,int(y)),len(y_dim)-2)
46
+ y_index = int(y)
47
+ if y_index<0 or y_index>len(y_dim)-2:
48
+ continue
49
+ y_grid_start = y_dim[y_index]
50
+ y_grid_end = y_dim[y_index+1]
51
+ y_refletion = (y_grid_end-y_grid_start)* math.modf(y)[0] + y_grid_start
52
+ reflection_points.append([x_refletion,y_refletion])
53
+ pass
54
+
55
+ return reflection_points
@@ -0,0 +1,50 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (c) 2025 yaqiang.sun.
3
+ # This source code is licensed under the license found in the LICENSE file
4
+ # in the root directory of this source tree.
5
+ #########################################################################
6
+ # Author: yaqiangsun
7
+ # Created Time: 2025/10/20 18:13:37
8
+ ########################################################################
9
+
10
+
11
+ import os
12
+ # import cv2
13
+ import numpy as np
14
+ import sys
15
+ # 获取当前文件的绝对路径,向上两层就是项目根目录
16
+ project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
17
+ if project_root not in sys.path:
18
+ sys.path.insert(0, project_root)
19
+ #
20
+ # `scope_api_client`: this package is generated by `openapi-python-client`
21
+ from .scope_api import Client, AuthenticatedClient
22
+ from .task import run_task
23
+ import logging
24
+ import numpy as np
25
+
26
+
27
+
28
+ logging.basicConfig(level=logging.INFO)
29
+
30
+
31
+ class QubitScopeClient(object):
32
+ def __init__(self, url, api_key):
33
+ self.url = url
34
+ self.api_key = api_key
35
+ self.client = AuthenticatedClient(base_url=url, token=api_key)
36
+
37
+ def request(self, file_list:list[str|dict[str,np.ndarray]],task_type:str="s21peak"):
38
+ if len(file_list)>0:
39
+ response = run_task(self.client,file_list,task_type)
40
+ else:
41
+ raise ValueError("file_list must not be empty")
42
+ return response
43
+ def get_result(self,response):
44
+ if response.status_code == 200:
45
+ logging.info("Result: %s", response.parsed)
46
+ result = response.parsed
47
+ return result
48
+ else:
49
+ logging.error("Error: %s %s", response.status_code, response.parsed)
50
+ return []
@@ -0,0 +1,8 @@
1
+ """A client library for accessing FastAPI"""
2
+
3
+ from .client import AuthenticatedClient, Client
4
+
5
+ __all__ = (
6
+ "AuthenticatedClient",
7
+ "Client",
8
+ )
@@ -0,0 +1 @@
1
+ """Contains methods for accessing the API"""
@@ -0,0 +1 @@
1
+ """Contains endpoint functions for accessing the API"""
@@ -0,0 +1,155 @@
1
+ from http import HTTPStatus
2
+ from typing import Any, Optional, Union
3
+
4
+ import httpx
5
+
6
+ from ... import errors
7
+ from ...client import AuthenticatedClient, Client
8
+ from ...models.http_validation_error import HTTPValidationError
9
+ from ...types import Response
10
+
11
+
12
+ def _get_kwargs(
13
+ pk: int,
14
+ ) -> dict[str, Any]:
15
+ _kwargs: dict[str, Any] = {
16
+ "method": "get",
17
+ "url": f"/api/v1/tasks/demo/{pk}",
18
+ }
19
+
20
+ return _kwargs
21
+
22
+
23
+ def _parse_response(
24
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
25
+ ) -> Optional[Union[Any, HTTPValidationError]]:
26
+ if response.status_code == 200:
27
+ response_200 = response.json()
28
+ return response_200
29
+
30
+ if response.status_code == 422:
31
+ response_422 = HTTPValidationError.from_dict(response.json())
32
+
33
+ return response_422
34
+
35
+ if client.raise_on_unexpected_status:
36
+ raise errors.UnexpectedStatus(response.status_code, response.content)
37
+ else:
38
+ return None
39
+
40
+
41
+ def _build_response(
42
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
43
+ ) -> Response[Union[Any, HTTPValidationError]]:
44
+ return Response(
45
+ status_code=HTTPStatus(response.status_code),
46
+ content=response.content,
47
+ headers=response.headers,
48
+ parsed=_parse_response(client=client, response=response),
49
+ )
50
+
51
+
52
+ def sync_detailed(
53
+ pk: int,
54
+ *,
55
+ client: Union[AuthenticatedClient, Client],
56
+ ) -> Response[Union[Any, HTTPValidationError]]:
57
+ """获取任务结果详情
58
+
59
+ Args:
60
+ pk (int): 任务结果 ID
61
+
62
+ Raises:
63
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
64
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
65
+
66
+ Returns:
67
+ Response[Union[Any, HTTPValidationError]]
68
+ """
69
+
70
+ kwargs = _get_kwargs(
71
+ pk=pk,
72
+ )
73
+
74
+ response = client.get_httpx_client().request(
75
+ **kwargs,
76
+ )
77
+
78
+ return _build_response(client=client, response=response)
79
+
80
+
81
+ def sync(
82
+ pk: int,
83
+ *,
84
+ client: Union[AuthenticatedClient, Client],
85
+ ) -> Optional[Union[Any, HTTPValidationError]]:
86
+ """获取任务结果详情
87
+
88
+ Args:
89
+ pk (int): 任务结果 ID
90
+
91
+ Raises:
92
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
93
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
94
+
95
+ Returns:
96
+ Union[Any, HTTPValidationError]
97
+ """
98
+
99
+ return sync_detailed(
100
+ pk=pk,
101
+ client=client,
102
+ ).parsed
103
+
104
+
105
+ async def asyncio_detailed(
106
+ pk: int,
107
+ *,
108
+ client: Union[AuthenticatedClient, Client],
109
+ ) -> Response[Union[Any, HTTPValidationError]]:
110
+ """获取任务结果详情
111
+
112
+ Args:
113
+ pk (int): 任务结果 ID
114
+
115
+ Raises:
116
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
117
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
118
+
119
+ Returns:
120
+ Response[Union[Any, HTTPValidationError]]
121
+ """
122
+
123
+ kwargs = _get_kwargs(
124
+ pk=pk,
125
+ )
126
+
127
+ response = await client.get_async_httpx_client().request(**kwargs)
128
+
129
+ return _build_response(client=client, response=response)
130
+
131
+
132
+ async def asyncio(
133
+ pk: int,
134
+ *,
135
+ client: Union[AuthenticatedClient, Client],
136
+ ) -> Optional[Union[Any, HTTPValidationError]]:
137
+ """获取任务结果详情
138
+
139
+ Args:
140
+ pk (int): 任务结果 ID
141
+
142
+ Raises:
143
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
144
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
145
+
146
+ Returns:
147
+ Union[Any, HTTPValidationError]
148
+ """
149
+
150
+ return (
151
+ await asyncio_detailed(
152
+ pk=pk,
153
+ client=client,
154
+ )
155
+ ).parsed