QuLab 2.5.0__cp311-cp311-win_amd64.whl → 2.5.2__cp311-cp311-win_amd64.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: QuLab
3
- Version: 2.5.0
3
+ Version: 2.5.2
4
4
  Summary: contral instruments and manage data
5
5
  Author-email: feihoo87 <feihoo87@gmail.com>
6
6
  Maintainer-email: feihoo87 <feihoo87@gmail.com>
@@ -1,18 +1,19 @@
1
1
  qulab/__init__.py,sha256=pdlicy07Dx39pTEGZ0i41Ox9tuuuKKIdsFIrE13bneg,249
2
2
  qulab/__main__.py,sha256=FL4YsGZL1jEtmcPc5WbleArzhOHLMsWl7OH3O-1d1ss,72
3
3
  qulab/dicttree.py,sha256=ZoSJVWK4VMqfzj42gPb_n5RqLlM6K1Me0WmLIfLEYf8,14195
4
- qulab/fun.cp311-win_amd64.pyd,sha256=Ou3oaF6r91_RUTvb-1Qc5yorMZQpcgdsW36pPtNCiN8,31744
5
- qulab/version.py,sha256=b9PgnIDmp0TYLJmDYb-w9iqcfWXZk22bBNQQjBVgaf0,21
4
+ qulab/fun.cp311-win_amd64.pyd,sha256=8Hmaqbu11gSeCoSaAA4pC4Dw-1yDNDLE38JdtpLVTg4,31744
5
+ qulab/typing.py,sha256=3c0eKa1avEHIi5wPvh3-4l6Of5mu5Rn1MWPnMeLGNX0,71
6
+ qulab/version.py,sha256=w6piXlEvrVvbn_4rTzwW2-HxvwxuHYQ5nIl8vcMmXAs,21
6
7
  qulab/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
8
  qulab/cli/commands.py,sha256=6xd2eYw32k1NmfAuYSu__1kaP12Oz1QVqwbkYXdWno4,588
8
9
  qulab/cli/config.py,sha256=tNmH4ggdgrFqcQa2WZKLpidiYTg95_UnT0paDJ4fi4c,3204
9
10
  qulab/executor/__init__.py,sha256=LosPzOMaljSZY1thy_Fxtbrgq7uubJszMABEB7oM7tU,101
10
11
  qulab/executor/cli.py,sha256=owdDSaSuzTPQA5SlNCxX4nHWITU1BF0VZMj7tLqCZhM,5781
11
- qulab/executor/load.py,sha256=4QJI_jWUCrn0MW_ieTAyhUXmujrOU5D9ywSOqzNduu0,11992
12
- qulab/executor/schedule.py,sha256=u-eM9Cw8GrvWmRFhHQWSXcdKomxp6AqSwnSm3gDwkrM,11920
13
- qulab/executor/storage.py,sha256=V91y8z62GseJLm2-1k-empbw68pCq93Lk-nUAwtfVfs,6068
14
- qulab/executor/transform.py,sha256=inaOn6eqCs22ZZ0xAQl8s8YCoEACaXSwFNNu7jqdwAk,2148
15
- qulab/executor/utils.py,sha256=OVBYuAC4Pw8-kT_s0AJUiLAS5QTeV-mXF8zjdQFTwrM,3163
12
+ qulab/executor/load.py,sha256=i2MKxE5kflAGLt3e9LjME59K7IO7s68EUApP9228LhQ,12125
13
+ qulab/executor/schedule.py,sha256=4D8o68Cx6vCkpSTMHzULTwuuq1tS8unc2n8WdBA9oB0,12013
14
+ qulab/executor/storage.py,sha256=s1xrI4bPTnyM4Nj0CkPxr3NdmnSp18LKnwm-ZoxR-Q0,7191
15
+ qulab/executor/transform.py,sha256=AazWdlkEoOBaUJpTYsT5J4f0RanzCEeo-ThwEg8BB4Y,1262
16
+ qulab/executor/utils.py,sha256=RNDEo17M-n_tge7uLITHxmoNNYSTm9OES75wQygR8dM,4065
16
17
  qulab/monitor/__init__.py,sha256=xEVDkJF8issrsDeLqQmDsvtRmrf-UiViFcGTWuzdlFU,43
17
18
  qulab/monitor/__main__.py,sha256=k2H1H5Zf9LLXTDLISJkbikLH-z0f1e5i5i6wXXYPOrE,105
18
19
  qulab/monitor/config.py,sha256=y_5StMkdrbZO1ziyKBrvIkB7Jclp9RCPK1QbsOhCxnY,785
@@ -92,9 +93,9 @@ qulab/visualization/plot_seq.py,sha256=Uo1-dB1YE9IN_A9tuaOs9ZG3S5dKDQ_l98iD2Wbxp
92
93
  qulab/visualization/qdat.py,sha256=HubXFu4nfcA7iUzghJGle1C86G6221hicLR0b-GqhKQ,5887
93
94
  qulab/visualization/rot3d.py,sha256=jGHJcqj1lEWBUV-W4GUGONGacqjrYvuFoFCwPse5h1Y,757
94
95
  qulab/visualization/widgets.py,sha256=HcYwdhDtLreJiYaZuN3LfofjJmZcLwjMfP5aasebgDo,3266
95
- QuLab-2.5.0.dist-info/LICENSE,sha256=b4NRQ-GFVpJMT7RuExW3NwhfbrYsX7AcdB7Gudok-fs,1086
96
- QuLab-2.5.0.dist-info/METADATA,sha256=dUio4DApvpQRgt7j7w3aYyCqfxDqpbsnTmFuMQirwXw,3803
97
- QuLab-2.5.0.dist-info/WHEEL,sha256=yNnHoQL2GZYIUXm9YvoaBpFjGlUoK9qq9oqYeudrWlE,101
98
- QuLab-2.5.0.dist-info/entry_points.txt,sha256=b0v1GXOwmxY-nCCsPN_rHZZvY9CtTbWqrGj8u1m8yHo,45
99
- QuLab-2.5.0.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
100
- QuLab-2.5.0.dist-info/RECORD,,
96
+ QuLab-2.5.2.dist-info/LICENSE,sha256=b4NRQ-GFVpJMT7RuExW3NwhfbrYsX7AcdB7Gudok-fs,1086
97
+ QuLab-2.5.2.dist-info/METADATA,sha256=pnurTFKwe9JZowgcw9DVam-rmQLxNclnXUvWIk314GI,3803
98
+ QuLab-2.5.2.dist-info/WHEEL,sha256=yNnHoQL2GZYIUXm9YvoaBpFjGlUoK9qq9oqYeudrWlE,101
99
+ QuLab-2.5.2.dist-info/entry_points.txt,sha256=b0v1GXOwmxY-nCCsPN_rHZZvY9CtTbWqrGj8u1m8yHo,45
100
+ QuLab-2.5.2.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
101
+ QuLab-2.5.2.dist-info/RECORD,,
qulab/executor/load.py CHANGED
@@ -40,17 +40,21 @@ class SetConfigWorkflow():
40
40
  value = transform.query_config(self.key)
41
41
  except:
42
42
  value = eval(input(f'"{self.key}": '))
43
- return self.key, value
43
+ return value
44
44
 
45
- def analyze(self, key, value, history):
46
- return 'OK', {key: value}, {}
45
+ def analyze(self, result: Result, history: Result):
46
+ result.state = 'OK'
47
+ result.parameters = {self.key: result.data}
48
+ return result
47
49
 
48
50
  def check(self):
49
51
  from .transform import query_config
50
- return self.key, query_config(self.key)
52
+ return query_config(self.key)
51
53
 
52
- def check_analyze(self, key, value, history):
53
- return 'Out of Spec', {key: value}, {}
54
+ def check_analyze(self, result: Result, history: Result):
55
+ result.state = 'Outdated'
56
+ result.parameters = {self.key: result.data}
57
+ return result
54
58
 
55
59
  @staticmethod
56
60
  def _equal(a, b):
@@ -5,10 +5,10 @@ from pathlib import Path
5
5
 
6
6
  from loguru import logger
7
7
 
8
- from . import transform
9
8
  from .load import WorkflowType, get_dependents
10
9
  from .storage import (Result, find_result, renew_result, revoke_result,
11
10
  save_result)
11
+ from .transform import update_parameters
12
12
 
13
13
 
14
14
  class CalibrationFailedError(Exception):
@@ -66,27 +66,26 @@ def check_state(workflow: WorkflowType, code_path: str | Path,
66
66
  return True
67
67
 
68
68
 
69
- def call_analyzer(node, data, history, check=False, plot=False):
69
+ def call_analyzer(node,
70
+ result: Result,
71
+ history: Result | None,
72
+ check=False,
73
+ plot=False) -> Result:
70
74
  if check:
71
- result = transform.params_to_result(
72
- node.check_analyze(*data,
73
- history=transform.result_to_params(history)))
75
+ result = node.check_analyze(result, history=history)
74
76
  result.fully_calibrated = False
75
77
  else:
76
- result = transform.params_to_result(
77
- node.analyze(*data, history=transform.result_to_params(history)))
78
+ result = node.analyze(result, history=history)
78
79
  result.fully_calibrated = True
79
80
  if plot:
80
81
  call_plot(node, result)
81
- result.data = data
82
82
  return result
83
83
 
84
84
 
85
85
  @logger.catch()
86
- def call_plot(node, result, check=False):
86
+ def call_plot(node, result: Result, check=False):
87
87
  if hasattr(node, 'plot') and callable(node.plot):
88
- state, params, other = transform.result_to_params(result)
89
- node.plot(state, params, other)
88
+ node.plot(result)
90
89
 
91
90
 
92
91
  @functools.lru_cache(maxsize=128)
@@ -128,7 +127,11 @@ def check_data(workflow: WorkflowType, code_path: str | Path,
128
127
  #save_result(workflow.__workflow_id__, result, state_path)
129
128
 
130
129
  logger.debug(f'Checked "{workflow.__workflow_id__}" !')
131
- result = call_analyzer(workflow, data, history, check=True, plot=plot)
130
+ result = call_analyzer(workflow,
131
+ result,
132
+ history,
133
+ check=True,
134
+ plot=plot)
132
135
  if result.in_spec:
133
136
  logger.debug(
134
137
  f'"{workflow.__workflow_id__}": checked in spec, renewing result'
@@ -149,7 +152,11 @@ def check_data(workflow: WorkflowType, code_path: str | Path,
149
152
  save_result(workflow.__workflow_id__, result, state_path)
150
153
 
151
154
  logger.debug(f'Calibrated "{workflow}" !')
152
- result = call_analyzer(workflow, data, history, check=False, plot=plot)
155
+ result = call_analyzer(workflow,
156
+ result,
157
+ history,
158
+ check=False,
159
+ plot=plot)
153
160
  save_result(workflow.__workflow_id__,
154
161
  result,
155
162
  state_path,
@@ -169,7 +176,7 @@ def calibrate(workflow: WorkflowType, code_path: str | Path,
169
176
  result.data = data
170
177
  save_result(workflow.__workflow_id__, result, state_path)
171
178
  logger.debug(f'Calibrated "{workflow.__workflow_id__}" !')
172
- result = call_analyzer(workflow, data, history, check=False, plot=plot)
179
+ result = call_analyzer(workflow, result, history, check=False, plot=plot)
173
180
  save_result(workflow.__workflow_id__, result, state_path, overwrite=True)
174
181
  return result
175
182
 
@@ -228,7 +235,7 @@ def diagnose(workflow: WorkflowType, code_path: str | Path,
228
235
  raise CalibrationFailedError(
229
236
  f'"{workflow.__workflow_id__}": All dependents passed, but calibration failed!'
230
237
  )
231
- transform.update_parameters(result)
238
+ update_parameters(result)
232
239
  return True
233
240
 
234
241
 
@@ -284,7 +291,7 @@ def maintain(workflow: WorkflowType,
284
291
  f'"{workflow.__workflow_id__}": All dependents passed, but calibration failed!'
285
292
  )
286
293
  if update:
287
- transform.update_parameters(result)
294
+ update_parameters(result)
288
295
  return
289
296
 
290
297
 
@@ -306,5 +313,5 @@ def run(workflow: WorkflowType,
306
313
  f'"{workflow.__workflow_id__}": All dependents passed, but calibration failed!'
307
314
  )
308
315
  if update:
309
- transform.update_parameters(result)
316
+ update_parameters(result)
310
317
  return
qulab/executor/storage.py CHANGED
@@ -4,6 +4,7 @@ import uuid
4
4
  from dataclasses import dataclass, field
5
5
  from datetime import datetime, timedelta
6
6
  from pathlib import Path
7
+ from typing import Any, Literal
7
8
 
8
9
  from loguru import logger
9
10
 
@@ -18,9 +19,9 @@ class Result():
18
19
  calibrated_time: datetime = field(default_factory=datetime.now)
19
20
  checked_time: datetime = field(default_factory=datetime.now)
20
21
  ttl: timedelta = timedelta(days=3650)
21
- params: dict = field(default_factory=dict)
22
- info: dict = field(default_factory=dict)
23
- data: tuple = field(default_factory=tuple)
22
+ parameters: dict = field(default_factory=dict)
23
+ other_infomation: dict = field(default_factory=dict)
24
+ data: Any = field(default_factory=tuple)
24
25
  index: int = -1
25
26
  previous_path: Path | None = None
26
27
  base_path: Path | None = None
@@ -32,6 +33,37 @@ class Result():
32
33
  else:
33
34
  return None
34
35
 
36
+ @property
37
+ def state(self) -> Literal['OK', 'Bad', 'Outdated']:
38
+ state = 'Bad'
39
+ match (self.in_spec, self.bad_data):
40
+ case (True, False):
41
+ state = 'OK'
42
+ case (False, True):
43
+ state = 'Bad'
44
+ case (False, False):
45
+ state = 'Outdated'
46
+ return state
47
+
48
+ @state.setter
49
+ def state(self, state: Literal['OK', 'Bad', 'Outdated', 'In spec',
50
+ 'Out of spec', 'Bad data']):
51
+ if state not in [
52
+ 'OK', 'Bad', 'Outdated', 'In spec', 'Out of spec', 'Bad data'
53
+ ]:
54
+ raise ValueError(
55
+ f'Invalid state: {state}, state must be one of "OK", "Bad" and "Outdated"'
56
+ )
57
+ if state in ['In spec', 'OK']:
58
+ self.in_spec = True
59
+ self.bad_data = False
60
+ elif state in ['Bad data', 'Bad']:
61
+ self.bad_data = True
62
+ self.in_spec = False
63
+ else:
64
+ self.bad_data = False
65
+ self.in_spec = False
66
+
35
67
 
36
68
  def random_path(base: Path) -> Path:
37
69
  while True:
@@ -44,7 +76,7 @@ def random_path(base: Path) -> Path:
44
76
  def save_result(workflow: str,
45
77
  result: Result,
46
78
  base_path: str | Path,
47
- overwrite: bool = False):
79
+ overwrite: bool = False) -> int:
48
80
  logger.debug(
49
81
  f'Saving result for "{workflow}", {result.in_spec=}, {result.bad_data=}, {result.fully_calibrated=}'
50
82
  )
@@ -70,6 +102,7 @@ def save_result(workflow: str,
70
102
  f.write(result.index.to_bytes(8, 'big'))
71
103
  f.write(buf)
72
104
  set_head(workflow, path, base_path)
105
+ return result.index
73
106
 
74
107
 
75
108
  def load_result(path: str | Path, base_path: str | Path) -> Result | None:
@@ -99,7 +132,7 @@ def renew_result(workflow: str, base_path: str | Path):
99
132
  result = find_result(workflow, base_path)
100
133
  if result is not None:
101
134
  result.checked_time = datetime.now()
102
- save_result(workflow, result, base_path)
135
+ return save_result(workflow, result, base_path)
103
136
 
104
137
 
105
138
  def revoke_result(workflow: str, base_path: str | Path):
@@ -107,10 +140,9 @@ def revoke_result(workflow: str, base_path: str | Path):
107
140
  base_path = Path(base_path)
108
141
  path = get_head(workflow, base_path)
109
142
  if path is not None:
110
- with open(base_path / 'objects' / path, "rb") as f:
111
- result = pickle.load(f)
143
+ result = load_result(path, base_path)
112
144
  result.in_spec = False
113
- save_result(workflow, result, base_path)
145
+ return save_result(workflow, result, base_path)
114
146
 
115
147
 
116
148
  def set_head(workflow: str, path: Path, base_path: str | Path):
@@ -1,5 +1,3 @@
1
- import loguru
2
-
3
1
  from .storage import Result
4
2
 
5
3
 
@@ -32,40 +30,7 @@ def _update_config(updates):
32
30
 
33
31
 
34
32
  def update_parameters(result: Result):
35
- update_config(result.params)
36
-
37
-
38
- def result_to_params(result: Result | None) -> tuple | None:
39
- if result is None:
40
- return None
41
-
42
- state = 'Bad data'
43
- match (result.in_spec, result.bad_data):
44
- case (True, False):
45
- state = 'In spec'
46
- case (False, True):
47
- state = 'Bad data'
48
- case (False, False):
49
- state = 'Out of spec'
50
-
51
- return state, result.params, result.info
52
-
53
-
54
- def params_to_result(params: tuple) -> Result:
55
- state, cali, info = params
56
- result = Result()
57
- if state in ['In spec', 'OK']:
58
- result.in_spec = True
59
- result.bad_data = False
60
- elif state in ['Bad data', 'Bad']:
61
- result.bad_data = True
62
- result.in_spec = False
63
- else:
64
- result.bad_data = False
65
- result.in_spec = False
66
- result.params = cali
67
- result.info = info
68
- return result
33
+ update_config(result.parameters)
69
34
 
70
35
 
71
36
  query_config = _query_config
qulab/executor/utils.py CHANGED
@@ -31,11 +31,12 @@ def dependent_tree(node: str, code_path: str | Path) -> dict[str, list[str]]:
31
31
 
32
32
 
33
33
  def workflow_template(deps: list[str]) -> str:
34
- return f"""from loguru import logger
35
-
36
- def VAR(s): pass # 没有实际作用,只是用来抑制编辑器的警告。
34
+ return f"""def VAR(s): pass # 没有实际作用,只是用来抑制编辑器的警告。
37
35
 
38
36
  import numpy as np
37
+ from loguru import logger
38
+
39
+ from qulab.typing import Result
39
40
 
40
41
 
41
42
  # 多长时间应该检查一次校准实验,单位是秒。
@@ -60,23 +61,35 @@ def calibrate():
60
61
  return x, y
61
62
 
62
63
 
63
- def analyze(*args, history):
64
+ def analyze(result: Result, history: Result | None) -> Result:
65
+ \"\"\"
66
+ 分析校准结果。
67
+
68
+ result: Result
69
+ 本次校准实验的数据。
70
+ history: Result | None
71
+ 上次校准实验数据和分析结果,如果有的话。
72
+ \"\"\"
64
73
  import random
65
74
 
75
+ # 这里添加你的分析过程,运行 calibrate 得到的数据,在 result.data 里
76
+ # 你可以得到校准的结果,然后根据这个结果进行分析。
77
+ x, y = result.data
78
+
66
79
  # 完整校准后的状态有两种:OK 和 Bad,分别对应校准成功和校准失败。
67
80
  # 校准失败是指出现坏数据,无法简单通过重新运行本次校准解决,需要
68
81
  # 检查前置步骤。
69
- state = random.choice(['OK', 'Bad'])
82
+ result.state = random.choice(['OK', 'Bad'])
70
83
 
71
84
  # 参数是一个字典,包含了本次校准得到的参数,后续会更新到config表中。
72
- parameters = {{'gate.R.Q1.params.amp':1}}
85
+ result.parameters = {{'gate.R.Q1.params.amp':1}}
73
86
 
74
87
  # 其他信息可以是任何可序列化的内容,你可以将你想要记录的信息放在这里。
75
88
  # 下次校准分析时,这些信息也会在 history 参数中一起传入,帮助你在下
76
89
  # 次分析时对比参考。
77
- other_infomation = {{}}
90
+ result.other_infomation = {{}}
78
91
 
79
- return state, parameters, other_infomation
92
+ return result
80
93
 
81
94
 
82
95
  def check():
@@ -95,14 +108,26 @@ def check():
95
108
  return x, y
96
109
 
97
110
 
98
- def check_analyze(*args, history):
111
+ def check_analyze(result: Result, history: Result) -> Result:
112
+ \"\"\"
113
+ 分析检查结果。
114
+
115
+ result: Result
116
+ 本次检查实验的数据。
117
+ history: Result | None
118
+ 上次检查实验数据和分析结果,如果有的话。
119
+ \"\"\"
99
120
  import random
100
121
 
122
+ # 这里添加你的分析过程,运行 check 得到的数据,在 result.data 里
123
+ # 你可以得到校准的结果,然后根据这个结果进行分析。
124
+ x, y = result.data
125
+
101
126
  # 状态有三种:Outdated, OK, Bad,分别对应过时、正常、坏数据。
102
127
  # Outdated 是指数据过时,即参数漂了,需要重新校准。
103
128
  # OK 是指数据正常,参数也没漂,不用重新校准。
104
129
  # Bad 是指数据坏了,无法校准,需要检查前置步骤。
105
- state = random.choice(['Outdated', 'OK', 'Bad'])
130
+ result.state = random.choice(['Outdated', 'OK', 'Bad'])
106
131
 
107
- return state, {{}}, {{}}
132
+ return result
108
133
  """
Binary file
qulab/typing.py ADDED
@@ -0,0 +1,2 @@
1
+ from .executor.storage import Result
2
+ from .scan.record import Record
qulab/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "2.5.0"
1
+ __version__ = "2.5.2"
File without changes
File without changes