QuLab 2.7.6__cp310-cp310-macosx_10_9_universal2.whl → 2.7.10__cp310-cp310-macosx_10_9_universal2.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.7.6
3
+ Version: 2.7.10
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,20 +1,20 @@
1
- qulab/__init__.py,sha256=tKRZe2WafDGcwbu7ddlMaePerN842aRbxcrECsu5pas,286
1
+ qulab/__init__.py,sha256=KJcUcZ5qXY6wlAoirzK_B-dgtDjsLmOE671v3gcXO_c,286
2
2
  qulab/__main__.py,sha256=fjaRSL_uUjNIzBGNgjlGswb9TJ2VD5qnkZHW3hItrD4,68
3
3
  qulab/dicttree.py,sha256=tRRMpGZYVOLw0TEByE3_2Ss8FdOmzuGL9e1DWbs8qoY,13684
4
- qulab/fun.cpython-310-darwin.so,sha256=QgEHTFx4ediOVIUKGllGdaak8zXnkawvicMAoWGO33E,126864
5
- qulab/typing.py,sha256=5xCLfrp1aZpKpDy4p2arbFszw2eK3hGUjZa-XSvC_-8,69
4
+ qulab/fun.cpython-310-darwin.so,sha256=onm3XhLaPD33T04UQ2QP32Gkl2E9xWjH45aY_Aqwjc0,126864
5
+ qulab/typing.py,sha256=vg62sGqxuD9CI5677ejlzAmf2fVdAESZCQjAE_xSxPg,69
6
6
  qulab/utils.py,sha256=JIXMSmZU0uYfKG_tzawpK7vRNPRir_hJE8JlqkVLX2o,1260
7
- qulab/version.py,sha256=ElxLmcD9H2GsJrWa-NsuGSxQyl8yztVfJ8oaA66f8oQ,21
7
+ qulab/version.py,sha256=jdPSCkDOwzHQzdidl89buWuyX5dorFZluLWAvXtMdIU,22
8
8
  qulab/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  qulab/cli/commands.py,sha256=tgDIkkeIoasQXAifJZ6NU8jDgpNgb2a-B0C4nF0evrE,559
10
10
  qulab/cli/config.py,sha256=SdNmWzweWAdyk8M2oKYhMxnkaJ0qIayPlsLGCNlVqME,3108
11
11
  qulab/executor/__init__.py,sha256=LosPzOMaljSZY1thy_Fxtbrgq7uubJszMABEB7oM7tU,101
12
- qulab/executor/cli.py,sha256=n0wl27xaiMWg18rVDOaKgLTEXaN0tSv4whTUQxvzBoM,8932
13
- qulab/executor/load.py,sha256=RJpgDuxNc3sUzr65K6a4vO-Qa72_lYsJGrPZDfw9Rus,18077
14
- qulab/executor/schedule.py,sha256=jBUK0vXeu-gbieSaH245exlGu3TW6vg9o0GIEF43IvA,16796
15
- qulab/executor/storage.py,sha256=k8rcyUHaAixMtWRTNfQrjFhingYqBb0fJZwHBLVE_UM,11002
16
- qulab/executor/transform.py,sha256=kaDJePBhVc32gZkQN8YBuA69lYYW9YhDZmCnUKaWuQw,2189
17
- qulab/executor/utils.py,sha256=XDk3duNrqDsCqZyZUmPqIAIIiykiafcOMBpy9NVAOAw,5686
12
+ qulab/executor/cli.py,sha256=gGka2M6xccfM8facsIJ2qZ1y2Yx8C4BRhc1JG6nK9mo,8932
13
+ qulab/executor/load.py,sha256=4FY_SwumLDUewC265v4j_ZGGpfYOgH4c8PtglYcWpBw,18077
14
+ qulab/executor/schedule.py,sha256=S8zRdkM2_I9-EqMUCEGI9boe3sfc68Gn5NRK057ShAw,17997
15
+ qulab/executor/storage.py,sha256=gI6g28BmKKEZ_Pl-hFwvpiOj3mF8Su-yjj3hfMXs1VY,11630
16
+ qulab/executor/transform.py,sha256=4DyGXv1Iw36cCPqbqXlsn0Lw6gFjQpp_6Hcta50YQxU,2181
17
+ qulab/executor/utils.py,sha256=cF6-2jlvlHyTjNHdxXKG04Fjfm3_3wfDQAF1G8DQphk,5686
18
18
  qulab/monitor/__init__.py,sha256=nTHelnDpxRS_fl_B38TsN0njgq8eVTEz9IAnN3NbDlM,42
19
19
  qulab/monitor/__main__.py,sha256=w3yUcqq195LzSnXTkQcuC1RSFRhy4oQ_PEBmucXguME,97
20
20
  qulab/monitor/config.py,sha256=fQ5JcsMApKc1UwANEnIvbDQZl8uYW0tle92SaYtX9lI,744
@@ -94,9 +94,9 @@ qulab/visualization/plot_seq.py,sha256=UWTS6p9nfX_7B8ehcYo6UnSTUCjkBsNU9jiOeW2ca
94
94
  qulab/visualization/qdat.py,sha256=ZeevBYWkzbww4xZnsjHhw7wRorJCBzbG0iEu-XQB4EA,5735
95
95
  qulab/visualization/rot3d.py,sha256=lMrEJlRLwYe6NMBlGkKYpp_V9CTipOAuDy6QW_cQK00,734
96
96
  qulab/visualization/widgets.py,sha256=6KkiTyQ8J-ei70LbPQZAK35wjktY47w2IveOa682ftA,3180
97
- QuLab-2.7.6.dist-info/LICENSE,sha256=PRzIKxZtpQcH7whTG6Egvzl1A0BvnSf30tmR2X2KrpA,1065
98
- QuLab-2.7.6.dist-info/METADATA,sha256=CUCFSSV87lDFOp15xOhzDpvmL3P7TMje6GOlrckku_E,3698
99
- QuLab-2.7.6.dist-info/WHEEL,sha256=Yd3eJSBM2hj8W-ouaiMfFUwQYAS-D6P73Ob9yN5MZd0,114
100
- QuLab-2.7.6.dist-info/entry_points.txt,sha256=b0v1GXOwmxY-nCCsPN_rHZZvY9CtTbWqrGj8u1m8yHo,45
101
- QuLab-2.7.6.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
102
- QuLab-2.7.6.dist-info/RECORD,,
97
+ QuLab-2.7.10.dist-info/LICENSE,sha256=PRzIKxZtpQcH7whTG6Egvzl1A0BvnSf30tmR2X2KrpA,1065
98
+ QuLab-2.7.10.dist-info/METADATA,sha256=-3XSmnAFhNexNzMEufmMAAUF2JfWg2YL_7crqvgyIPg,3699
99
+ QuLab-2.7.10.dist-info/WHEEL,sha256=Yd3eJSBM2hj8W-ouaiMfFUwQYAS-D6P73Ob9yN5MZd0,114
100
+ QuLab-2.7.10.dist-info/entry_points.txt,sha256=b0v1GXOwmxY-nCCsPN_rHZZvY9CtTbWqrGj8u1m8yHo,45
101
+ QuLab-2.7.10.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
102
+ QuLab-2.7.10.dist-info/RECORD,,
qulab/__init__.py CHANGED
@@ -1,5 +1,5 @@
1
- from .executor.storage import find_result
2
- from .executor.storage import get_result_by_index as get_result
1
+ from .executor.storage import find_report
2
+ from .executor.storage import get_report_by_index as get_report
3
3
  from .executor.utils import debug_analyze
4
4
  from .scan import Scan, get_record, load_record, lookup, lookup_list
5
5
  from .version import __version__
qulab/executor/cli.py CHANGED
@@ -149,7 +149,7 @@ def get(key, api):
149
149
 
150
150
  @click.command()
151
151
  @click.argument('workflow')
152
- @click.option('--plot', '-p', is_flag=True, help='Plot the result.')
152
+ @click.option('--plot', '-p', is_flag=True, help='Plot the report.')
153
153
  @click.option('--no-dependents',
154
154
  '-n',
155
155
  is_flag=True,
@@ -221,7 +221,7 @@ def run(workflow, code, data, api, plot, no_dependents, retry, freeze):
221
221
  @click.command()
222
222
  @click.argument('workflow')
223
223
  @click.option('--retry', '-r', default=1, type=int, help='Retry times.')
224
- @click.option('--plot', '-p', is_flag=True, help='Plot the result.')
224
+ @click.option('--plot', '-p', is_flag=True, help='Plot the report.')
225
225
  @log_options
226
226
  @command_option('maintain')
227
227
  def maintain(workflow, code, data, api, retry, plot):
qulab/executor/load.py CHANGED
@@ -15,7 +15,7 @@ from typing import Any
15
15
 
16
16
  from loguru import logger
17
17
 
18
- from .storage import Result
18
+ from .storage import Report
19
19
 
20
20
 
21
21
  class SetConfigWorkflow():
@@ -29,7 +29,7 @@ class SetConfigWorkflow():
29
29
  def depends(self):
30
30
  return []
31
31
 
32
- def check_state(self, history: Result) -> bool:
32
+ def check_state(self, history: Report) -> bool:
33
33
  from . import transform
34
34
  try:
35
35
  return self._equal(history.parameters[self.key],
@@ -45,21 +45,21 @@ class SetConfigWorkflow():
45
45
  value = eval(input(f'"{self.key}": '))
46
46
  return value
47
47
 
48
- def analyze(self, result: Result, history: Result):
49
- result.state = 'OK'
50
- result.parameters = {self.key: result.data}
51
- return result
48
+ def analyze(self, report: Report, history: Report):
49
+ report.state = 'OK'
50
+ report.parameters = {self.key: report.data}
51
+ return report
52
52
 
53
53
  def check(self):
54
54
  return self.calibrate()
55
55
 
56
- def check_analyze(self, result: Result, history: Result | None):
56
+ def check_analyze(self, report: Report, history: Report | None):
57
57
  if self.check_state(history):
58
- result.state = 'OK'
59
- result.parameters = {self.key: history.data}
58
+ report.state = 'OK'
59
+ report.parameters = {self.key: history.data}
60
60
  else:
61
- result.state = 'Outdated'
62
- return result
61
+ report.state = 'Outdated'
62
+ return report
63
63
 
64
64
  @staticmethod
65
65
  def _equal(a, b):
@@ -7,28 +7,28 @@ from pathlib import Path
7
7
  from loguru import logger
8
8
 
9
9
  from .load import WorkflowType, get_dependents
10
- from .storage import (Result, find_result, get_heads, renew_result,
11
- revoke_result, save_result)
10
+ from .storage import (Report, find_report, get_head, get_heads, renew_report,
11
+ revoke_report, save_item, save_report)
12
12
  from .transform import current_config, obey_the_oracle, update_parameters
13
13
 
14
14
  __session_id = None
15
15
  __session_cache = {}
16
16
 
17
17
 
18
- def set_cache(session_id, key, result: Result):
18
+ def set_cache(session_id, key, report: Report):
19
19
  global __session_id
20
20
  if __session_id is None:
21
21
  __session_id = session_id
22
22
  if __session_id != session_id:
23
23
  __session_cache.clear()
24
- if result.workflow.startswith('cfg:'):
25
- __session_cache[key] = result
24
+ if report.workflow.startswith('cfg:'):
25
+ __session_cache[key] = report
26
26
  else:
27
- __session_cache[key] = result.base_path, result.path
27
+ __session_cache[key] = report.base_path, report.path
28
28
 
29
29
 
30
- def get_cache(session_id, key) -> Result:
31
- from .storage import load_result
30
+ def get_cache(session_id, key) -> Report:
31
+ from .storage import load_report
32
32
  global __session_id
33
33
  if __session_id is None or __session_id != session_id:
34
34
  return None
@@ -37,8 +37,8 @@ def get_cache(session_id, key) -> Result:
37
37
  return None
38
38
  if isinstance(index, tuple):
39
39
  base_path, path = index
40
- return load_result(base_path, path)
41
- elif isinstance(index, Result):
40
+ return load_report(base_path, path)
41
+ elif isinstance(index, Report):
42
42
  return index
43
43
  else:
44
44
  return None
@@ -56,19 +56,29 @@ def is_pickleable(obj) -> bool:
56
56
  return False
57
57
 
58
58
 
59
- def veryfy_analyzed_result(result: Result, script: str, method: str):
60
- if not isinstance(result, Result):
61
- raise TypeError(f'"{script}" : "{method}" must return a Result object')
62
- if not is_pickleable(result.parameters):
59
+ def veryfy_analyzed_report(report: Report, script: str, method: str):
60
+ if not isinstance(report, Report):
61
+ raise TypeError(f'"{script}" : "{method}" must return a Report object')
62
+ if not is_pickleable(report.parameters):
63
63
  raise TypeError(
64
64
  f'"{script}" : "{method}" return not pickleable data in .parameters'
65
65
  )
66
- if not is_pickleable(result.other_infomation):
66
+ if not is_pickleable(report.other_infomation):
67
67
  raise TypeError(
68
68
  f'"{script}" : "{method}" return not pickleable data in .other_infomation'
69
69
  )
70
70
 
71
71
 
72
+ def get_source(workflow: WorkflowType, code_path: str | Path) -> str:
73
+ if isinstance(code_path, str):
74
+ code_path = Path(code_path)
75
+ try:
76
+ with open(code_path / workflow.__workflow_id__, 'r') as f:
77
+ return f.read()
78
+ except:
79
+ return ''
80
+
81
+
72
82
  def check_state(workflow: WorkflowType, code_path: str | Path,
73
83
  state_path: str | Path) -> bool:
74
84
  """
@@ -80,8 +90,8 @@ def check_state(workflow: WorkflowType, code_path: str | Path,
80
90
  4. All dependencies pass check state.
81
91
  """
82
92
  logger.debug(f'check_state: "{workflow.__workflow_id__}"')
83
- result = find_result(workflow.__workflow_id__, state_path)
84
- if not result:
93
+ report = find_report(workflow.__workflow_id__, state_path)
94
+ if not report:
85
95
  logger.debug(
86
96
  f'check_state failed: No history found for "{workflow.__workflow_id__}"'
87
97
  )
@@ -90,23 +100,28 @@ def check_state(workflow: WorkflowType, code_path: str | Path,
90
100
  logger.debug(
91
101
  f'check_state: "{workflow.__workflow_id__}" has custom check_state method'
92
102
  )
93
- return workflow.check_state(result)
103
+ return workflow.check_state(report)
104
+ if datetime.fromtimestamp(workflow.__mtime__) > report.checked_time:
105
+ logger.debug(
106
+ f'check_state failed: "{workflow.__workflow_id__}" has been modified after last calibration'
107
+ )
108
+ return False
94
109
  if workflow.__timeout__ is not None and datetime.now(
95
- ) > result.checked_time + timedelta(seconds=workflow.__timeout__):
110
+ ) > report.checked_time + timedelta(seconds=workflow.__timeout__):
96
111
  logger.debug(
97
112
  f'check_state failed: "{workflow.__workflow_id__}" has expired')
98
113
  return False
99
- if not result.in_spec:
114
+ if not report.in_spec:
100
115
  logger.debug(
101
116
  f'check_state failed: "{workflow.__workflow_id__}" is out of spec')
102
117
  return False
103
- if result.bad_data:
118
+ if report.bad_data:
104
119
  logger.debug(
105
120
  f'check_state failed: "{workflow.__workflow_id__}" has bad data')
106
121
  return False
107
122
  for n in get_dependents(workflow, code_path):
108
- r = find_result(n.__workflow_id__, state_path)
109
- if r is None or r.checked_time > result.checked_time:
123
+ r = find_report(n.__workflow_id__, state_path)
124
+ if r is None or r.checked_time > report.checked_time:
110
125
  logger.debug(
111
126
  f'check_state failed: "{workflow.__workflow_id__}" has outdated dependencies'
112
127
  )
@@ -120,71 +135,146 @@ def check_state(workflow: WorkflowType, code_path: str | Path,
120
135
  return True
121
136
 
122
137
 
123
- def call_analyzer(node,
124
- result: Result,
125
- history: Result | None,
126
- check=False,
127
- plot=False) -> Result:
128
- if check:
129
- result = node.check_analyze(result, history=history)
130
- veryfy_analyzed_result(result, node.__workflow_id__, "check_analyze")
131
- result.fully_calibrated = False
138
+ @logger.catch()
139
+ def call_plot(node: WorkflowType, report: Report, check=False):
140
+ if hasattr(node, 'plot') and callable(node.plot):
141
+ node.plot(report)
142
+
143
+
144
+ def call_check(workflow: WorkflowType, session_id: str, state_path: Path):
145
+ report = get_cache(session_id, (workflow, 'check'))
146
+ if report is not None:
147
+ logger.debug(f'Cache hit for "{workflow.__workflow_id__}:check"')
148
+ return report
149
+
150
+ data = workflow.check()
151
+ if not is_pickleable(data):
152
+ raise TypeError(
153
+ f'"{workflow.__workflow_id__}" : "check" return not pickleable data'
154
+ )
155
+ report = Report(workflow=workflow.__workflow_id__,
156
+ data=data,
157
+ config_path=current_config(state_path),
158
+ base_path=state_path,
159
+ heads=get_heads(state_path),
160
+ previous_path=get_head(workflow.__workflow_id__,
161
+ state_path),
162
+ script_path=save_item(get_source(workflow, state_path),
163
+ state_path))
164
+
165
+ save_report(workflow.__workflow_id__, report, state_path)
166
+
167
+ set_cache(session_id, (workflow, 'check'), report)
168
+ return report
169
+
170
+
171
+ def call_calibrate(workflow: WorkflowType, session_id: str, state_path: Path):
172
+ report = get_cache(session_id, (workflow, 'calibrate'))
173
+ if report is not None:
174
+ logger.debug(f'Cache hit for "{workflow.__workflow_id__}:calibrate"')
175
+ return report
176
+
177
+ data = workflow.calibrate()
178
+ if not is_pickleable(data):
179
+ raise TypeError(
180
+ f'"{workflow.__workflow_id__}" : "calibrate" return not pickleable data'
181
+ )
182
+ report = Report(workflow=workflow.__workflow_id__,
183
+ data=data,
184
+ config_path=current_config(state_path),
185
+ base_path=state_path,
186
+ heads=get_heads(state_path),
187
+ previous_path=get_head(workflow.__workflow_id__,
188
+ state_path),
189
+ script_path=save_item(get_source(workflow, state_path),
190
+ state_path))
191
+
192
+ save_report(workflow.__workflow_id__, report, state_path)
193
+
194
+ set_cache(session_id, (workflow, 'calibrate'), report)
195
+ return report
196
+
197
+
198
+ def call_check_analyzer(node: WorkflowType,
199
+ report: Report,
200
+ history: Report | None,
201
+ state_path: Path,
202
+ plot=False) -> Report:
203
+ report = node.check_analyze(report, history=history)
204
+ veryfy_analyzed_report(report, node.__workflow_id__, "check_analyze")
205
+ report.fully_calibrated = False
206
+ if report.in_spec:
207
+ logger.debug(
208
+ f'"{node.__workflow_id__}": checked in spec, renewing report')
209
+ if report.previous is not None:
210
+ renew_report(node.__workflow_id__, report.previous, state_path)
211
+ else:
212
+ renew_report(node.__workflow_id__, report, state_path)
132
213
  else:
133
- result = node.analyze(result, history=history)
134
- veryfy_analyzed_result(result, node.__workflow_id__, "analyze")
135
- if hasattr(node, 'oracle') and callable(node.oracle):
136
- logger.debug(
137
- f'"{node.__workflow_id__}" has oracle method, calling ...')
138
- try:
139
- result = node.oracle(result,
140
- history=history,
141
- system_state=get_heads(result.base_path))
142
- except Exception as e:
143
- logger.exception(e)
144
- result.oracle = {}
145
- if not isinstance(result, Result):
146
- raise TypeError(
147
- f'"{node.__workflow_id__}" : function "oracle" must return a Result object'
148
- )
149
- if not is_pickleable(result.oracle):
150
- raise TypeError(
151
- f'"{node.__workflow_id__}" : function "oracle" return not pickleable data'
152
- )
153
- result.fully_calibrated = True
154
- if plot:
155
- call_plot(node, result)
156
- return result
214
+ logger.debug(
215
+ f'"{node.__workflow_id__}": checked out of spec, revoking report')
216
+ if report.previous is not None:
217
+ revoke_report(node.__workflow_id__, report.previous, state_path)
218
+ else:
219
+ revoke_report(node.__workflow_id__, report, state_path)
220
+ return report
157
221
 
158
222
 
159
- @logger.catch()
160
- def call_plot(node, result: Result, check=False):
161
- if hasattr(node, 'plot') and callable(node.plot):
162
- node.plot(result)
223
+ def call_analyzer(node: WorkflowType,
224
+ report: Report,
225
+ history: Report | None,
226
+ state_path: Path,
227
+ plot=False) -> Report:
228
+
229
+ report = node.analyze(report, history=history)
230
+ veryfy_analyzed_report(report, node.__workflow_id__, "analyze")
231
+ if hasattr(node, 'oracle') and callable(node.oracle):
232
+ logger.debug(
233
+ f'"{node.__workflow_id__}" has oracle method, calling ...')
234
+ try:
235
+ report = node.oracle(report,
236
+ history=history,
237
+ system_state=get_heads(report.base_path))
238
+ except Exception as e:
239
+ logger.exception(e)
240
+ report.oracle = {}
241
+ if not isinstance(report, Report):
242
+ raise TypeError(
243
+ f'"{node.__workflow_id__}" : function "oracle" must return a Report object'
244
+ )
245
+ if not is_pickleable(report.oracle):
246
+ raise TypeError(
247
+ f'"{node.__workflow_id__}" : function "oracle" return not pickleable data'
248
+ )
249
+ report.fully_calibrated = True
250
+ save_report(node.__workflow_id__, report, state_path, overwrite=True)
251
+ if plot:
252
+ call_plot(node, report)
253
+ return report
163
254
 
164
255
 
165
- def check_data(workflow: WorkflowType, code_path: str | Path,
166
- state_path: str | Path, plot: bool, session_id: str) -> Result:
256
+ def check_data(workflow: WorkflowType, state_path: str | Path, plot: bool,
257
+ session_id: str) -> Report:
167
258
  """
168
259
  check data answers two questions:
169
260
  Is the parameter associated with this cal in spec,
170
261
  and is the cal scan working as expected?
171
262
  """
172
- result = get_cache(session_id, (workflow, 'check_data'))
173
- if result is not None:
174
- logger.debug(f'Cache hit for "{workflow.__workflow_id__}:check_data"')
175
- return result
176
-
177
- history = find_result(workflow.__workflow_id__, state_path)
263
+ history = find_report(workflow.__workflow_id__, state_path)
178
264
 
179
265
  if history is None:
180
266
  logger.debug(f'No history found for "{workflow.__workflow_id__}"')
181
- result = Result(workflow=workflow.__workflow_id__,
267
+ report = Report(workflow=workflow.__workflow_id__,
182
268
  config_path=current_config(state_path),
183
269
  base_path=state_path,
184
- heads=get_heads(state_path))
185
- result.in_spec = False
186
- result.bad_data = False
187
- return result
270
+ heads=get_heads(state_path),
271
+ previous_path=get_head(workflow.__workflow_id__,
272
+ state_path),
273
+ script_path=save_item(get_source(workflow, state_path),
274
+ state_path))
275
+ report.in_spec = False
276
+ report.bad_data = False
277
+ return report
188
278
 
189
279
  if history.bad_data:
190
280
  logger.debug(
@@ -202,92 +292,43 @@ def check_data(workflow: WorkflowType, code_path: str | Path,
202
292
  workflow, 'check_analyze') and callable(workflow.check_analyze):
203
293
  logger.debug(
204
294
  f'Checking "{workflow.__workflow_id__}" with "check" method ...')
205
- data = workflow.check()
206
- if not is_pickleable(data):
207
- raise TypeError(
208
- f'"{workflow.__workflow_id__}" : "check" return not pickleable data'
209
- )
210
- result = Result(workflow=workflow.__workflow_id__,
211
- data=data,
212
- config_path=current_config(state_path),
213
- base_path=state_path,
214
- heads=get_heads(state_path))
215
- #save_result(workflow.__workflow_id__, result, state_path)
295
+
296
+ report = call_check(workflow, session_id, state_path)
216
297
 
217
298
  logger.debug(f'Checked "{workflow.__workflow_id__}" !')
218
- result = call_analyzer(workflow,
219
- result,
220
- history,
221
- check=True,
222
- plot=plot)
223
- if result.in_spec:
224
- logger.debug(
225
- f'"{workflow.__workflow_id__}": checked in spec, renewing result'
226
- )
227
- renew_result(workflow.__workflow_id__, state_path)
228
- else:
229
- logger.debug(
230
- f'"{workflow.__workflow_id__}": checked out of spec, revoking result'
231
- )
232
- revoke_result(workflow.__workflow_id__, state_path)
299
+ report = call_check_analyzer(workflow,
300
+ report,
301
+ history,
302
+ state_path,
303
+ plot=plot)
233
304
  else:
234
305
  logger.debug(
235
306
  f'Checking "{workflow.__workflow_id__}" with "calibrate" method ...'
236
307
  )
237
- data = workflow.calibrate()
238
- if not is_pickleable(data):
239
- raise TypeError(
240
- f'"{workflow.__workflow_id__}" : "calibrate" return not pickleable data'
241
- )
242
- result = Result(workflow=workflow.__workflow_id__,
243
- data=data,
244
- config_path=current_config(state_path),
245
- base_path=state_path,
246
- heads=get_heads(state_path))
247
- save_result(workflow.__workflow_id__, result, state_path)
308
+
309
+ report = call_calibrate(workflow, session_id, state_path)
248
310
 
249
311
  logger.debug(f'Calibrated "{workflow.__workflow_id__}" !')
250
- result = call_analyzer(workflow,
251
- result,
312
+ report = call_analyzer(workflow,
313
+ report,
252
314
  history,
253
- check=False,
315
+ state_path,
254
316
  plot=plot)
255
- save_result(workflow.__workflow_id__,
256
- result,
257
- state_path,
258
- overwrite=True)
317
+ return report
259
318
 
260
- set_cache(session_id, (workflow, 'check_data'), result)
261
- return result
262
319
 
320
+ def calibrate(workflow: WorkflowType, state_path: str | Path, plot: bool,
321
+ session_id: str) -> Report:
322
+ history = find_report(workflow.__workflow_id__, state_path)
263
323
 
264
- def calibrate(workflow: WorkflowType, code_path: str | Path,
265
- state_path: str | Path, plot: bool, session_id: str) -> Result:
266
- result = get_cache(session_id, (workflow, 'calibrate'))
267
- if result is not None:
268
- logger.debug(f'Cache hit for "{workflow.__workflow_id__}:calibrate"')
269
- return result
324
+ logger.debug(f'Calibrating "{workflow.__workflow_id__}" ...')
270
325
 
271
- history = find_result(workflow.__workflow_id__, state_path)
326
+ report = call_calibrate(workflow, session_id, state_path)
272
327
 
273
- logger.debug(f'Calibrating "{workflow.__workflow_id__}" ...')
274
- data = workflow.calibrate()
275
- if not is_pickleable(data):
276
- raise TypeError(
277
- f'"{workflow.__workflow_id__}" : "calibrate" return not pickleable data'
278
- )
279
- result = Result(workflow=workflow.__workflow_id__,
280
- data=data,
281
- config_path=current_config(state_path),
282
- base_path=state_path,
283
- heads=get_heads(state_path))
284
- save_result(workflow.__workflow_id__, result, state_path)
285
328
  logger.debug(f'Calibrated "{workflow.__workflow_id__}" !')
286
- result = call_analyzer(workflow, result, history, check=False, plot=plot)
287
- save_result(workflow.__workflow_id__, result, state_path, overwrite=True)
288
329
 
289
- set_cache(session_id, (workflow, 'calibrate'), result)
290
- return result
330
+ report = call_analyzer(workflow, report, history, state_path, plot=plot)
331
+ return report
291
332
 
292
333
 
293
334
  def diagnose(workflow: WorkflowType, code_path: str | Path,
@@ -297,16 +338,16 @@ def diagnose(workflow: WorkflowType, code_path: str | Path,
297
338
  '''
298
339
  logger.debug(f'diagnose "{workflow.__workflow_id__}"')
299
340
  # check_data
300
- result = check_data(workflow, code_path, state_path, plot, session_id)
341
+ report = check_data(workflow, state_path, plot, session_id)
301
342
  # in spec case
302
- if result.in_spec:
343
+ if report.in_spec:
303
344
  logger.debug(
304
345
  f'"{workflow.__workflow_id__}": Checked! In spec, no need to diagnose'
305
346
  )
306
347
  return False
307
348
  # bad data case
308
349
  recalibrated = []
309
- if result.bad_data:
350
+ if report.bad_data:
310
351
  logger.debug(
311
352
  f'"{workflow.__workflow_id__}": Bad data, diagnosing dependents')
312
353
  recalibrated = [
@@ -314,7 +355,7 @@ def diagnose(workflow: WorkflowType, code_path: str | Path,
314
355
  for n in get_dependents(workflow, code_path)
315
356
  ]
316
357
  if not any(recalibrated):
317
- if result.bad_data:
358
+ if report.bad_data:
318
359
  raise CalibrationFailedError(
319
360
  f'"{workflow.__workflow_id__}": bad data but no dependents recalibrated.'
320
361
  )
@@ -325,27 +366,27 @@ def diagnose(workflow: WorkflowType, code_path: str | Path,
325
366
  logger.debug(
326
367
  f'recalibrate "{workflow.__workflow_id__}" because some dependents recalibrated.'
327
368
  )
328
- elif not result.in_spec and not result.bad_data:
369
+ elif not report.in_spec and not report.bad_data:
329
370
  logger.debug(
330
371
  f'recalibrate "{workflow.__workflow_id__}" because out of spec.')
331
- elif result.in_spec:
372
+ elif report.in_spec:
332
373
  logger.error(
333
374
  f'Never reach: recalibrate "{workflow.__workflow_id__}" because in spec.'
334
375
  )
335
- elif result.bad_data:
376
+ elif report.bad_data:
336
377
  logger.error(
337
378
  f'Never reach: recalibrate "{workflow.__workflow_id__}" because bad data.'
338
379
  )
339
380
  else:
340
381
  logger.error(f'Never reach: recalibrate "{workflow.__workflow_id__}"')
341
382
 
342
- result = calibrate(workflow, code_path, state_path, plot, session_id)
343
- if result.bad_data or not result.in_spec:
344
- obey_the_oracle(result, state_path)
383
+ report = calibrate(workflow, state_path, plot, session_id)
384
+ if report.bad_data or not report.in_spec:
385
+ obey_the_oracle(report, state_path)
345
386
  raise CalibrationFailedError(
346
387
  f'"{workflow.__workflow_id__}": All dependents passed, but calibration failed!'
347
388
  )
348
- update_parameters(result, state_path)
389
+ update_parameters(report, state_path)
349
390
  return True
350
391
 
351
392
 
@@ -382,13 +423,13 @@ def maintain(workflow: WorkflowType,
382
423
  f'"{workflow.__workflow_id__}": In spec, no need to maintain')
383
424
  return
384
425
  # check_data
385
- result = check_data(workflow, code_path, state_path, plot, session_id)
386
- if result.in_spec:
426
+ report = check_data(workflow, state_path, plot, session_id)
427
+ if report.in_spec:
387
428
  if not run:
388
429
  logger.debug(
389
430
  f'"{workflow.__workflow_id__}": In spec, no need to maintain')
390
431
  return
391
- elif result.bad_data:
432
+ elif report.bad_data:
392
433
  logger.debug(
393
434
  f'"{workflow.__workflow_id__}": Bad data, diagnosing dependents')
394
435
  for n in get_dependents(workflow, code_path):
@@ -401,15 +442,15 @@ def maintain(workflow: WorkflowType,
401
442
  f'"{workflow.__workflow_id__}": All dependents diagnosed')
402
443
  # calibrate
403
444
  logger.debug(f'recalibrate "{workflow.__workflow_id__}"')
404
- result = calibrate(workflow, code_path, state_path, plot, session_id)
405
- if result.bad_data or not result.in_spec:
445
+ report = calibrate(workflow, state_path, plot, session_id)
446
+ if report.bad_data or not report.in_spec:
406
447
  if not freeze:
407
- obey_the_oracle(result, state_path)
448
+ obey_the_oracle(report, state_path)
408
449
  raise CalibrationFailedError(
409
450
  f'"{workflow.__workflow_id__}": All dependents passed, but calibration failed!'
410
451
  )
411
452
  if not freeze:
412
- update_parameters(result, state_path)
453
+ update_parameters(report, state_path)
413
454
  return
414
455
 
415
456
 
@@ -421,17 +462,13 @@ def run(workflow: WorkflowType,
421
462
  freeze: bool = False):
422
463
  session_id = uuid.uuid4().hex
423
464
  logger.debug(f'run "{workflow.__workflow_id__}" without dependences.')
424
- result = calibrate(workflow,
425
- code_path,
426
- state_path,
427
- plot,
428
- session_id=session_id)
429
- if result.bad_data or not result.in_spec:
465
+ report = calibrate(workflow, state_path, plot, session_id=session_id)
466
+ if report.bad_data or not report.in_spec:
430
467
  if not freeze:
431
- obey_the_oracle(result, state_path)
468
+ obey_the_oracle(report, state_path)
432
469
  raise CalibrationFailedError(
433
470
  f'"{workflow.__workflow_id__}": All dependents passed, but calibration failed!'
434
471
  )
435
472
  if not freeze:
436
- update_parameters(result, state_path)
473
+ update_parameters(report, state_path)
437
474
  return
qulab/executor/storage.py CHANGED
@@ -16,7 +16,7 @@ __current_config_cache = None
16
16
 
17
17
 
18
18
  @dataclass
19
- class Result():
19
+ class Report():
20
20
  workflow: str = ''
21
21
  in_spec: bool = False
22
22
  bad_data: bool = False
@@ -34,11 +34,12 @@ class Result():
34
34
  base_path: Path | None = field(default=None, repr=False)
35
35
  path: Path | None = field(default=None, repr=False)
36
36
  config_path: Path | None = field(default=None, repr=False)
37
+ script_path: Path | None = field(default=None, repr=False)
37
38
 
38
39
  @property
39
40
  def previous(self):
40
41
  if self.previous_path is not None and self.base_path is not None:
41
- return load_result(self.previous_path, self.base_path)
42
+ return load_report(self.previous_path, self.base_path)
42
43
  else:
43
44
  return None
44
45
 
@@ -54,13 +55,6 @@ class Result():
54
55
  state = 'Outdated'
55
56
  return state
56
57
 
57
- @property
58
- def config(self):
59
- if self.config_path is not None and self.base_path is not None:
60
- return load_config(self.config_path, self.base_path)
61
- else:
62
- return None
63
-
64
58
  @state.setter
65
59
  def state(self, state: Literal['OK', 'Bad', 'Outdated', 'In spec',
66
60
  'Out of spec', 'Bad data']):
@@ -80,6 +74,20 @@ class Result():
80
74
  self.bad_data = False
81
75
  self.in_spec = False
82
76
 
77
+ @property
78
+ def config(self):
79
+ if self.config_path is not None and self.base_path is not None:
80
+ return load_item(self.config_path, self.base_path)
81
+ else:
82
+ return None
83
+
84
+ @property
85
+ def script(self):
86
+ if self.script_path is not None and self.base_path is not None:
87
+ return load_item(self.script_path, self.base_path)
88
+ else:
89
+ return None
90
+
83
91
 
84
92
  def random_path(base: Path) -> Path:
85
93
  while True:
@@ -89,7 +97,7 @@ def random_path(base: Path) -> Path:
89
97
  return path
90
98
 
91
99
 
92
- def save_config_key_history(key: str, result: Result,
100
+ def save_config_key_history(key: str, report: Report,
93
101
  base_path: str | Path) -> int:
94
102
  global __current_config_cache
95
103
  base_path = Path(base_path) / 'state'
@@ -103,14 +111,14 @@ def save_config_key_history(key: str, result: Result,
103
111
  __current_config_cache = {}
104
112
 
105
113
  __current_config_cache[
106
- key] = result.data, result.calibrated_time, result.checked_time
114
+ key] = report.data, report.calibrated_time, report.checked_time
107
115
 
108
116
  with open(base_path / 'parameters.pkl', 'wb') as f:
109
117
  pickle.dump(__current_config_cache, f)
110
118
  return 0
111
119
 
112
120
 
113
- def find_config_key_history(key: str, base_path: str | Path) -> Result | None:
121
+ def find_config_key_history(key: str, base_path: str | Path) -> Report | None:
114
122
  global __current_config_cache
115
123
  base_path = Path(base_path) / 'state'
116
124
  if __current_config_cache is None:
@@ -123,7 +131,7 @@ def find_config_key_history(key: str, base_path: str | Path) -> Result | None:
123
131
  if key in __current_config_cache:
124
132
  value, calibrated_time, checked_time = __current_config_cache.get(
125
133
  key, None)
126
- result = Result(
134
+ report = Report(
127
135
  workflow=f'cfg:{key}',
128
136
  bad_data=False,
129
137
  in_spec=True,
@@ -133,64 +141,65 @@ def find_config_key_history(key: str, base_path: str | Path) -> Result | None:
133
141
  calibrated_time=calibrated_time,
134
142
  checked_time=checked_time,
135
143
  )
136
- return result
144
+ return report
137
145
  return None
138
146
 
139
147
 
140
- def save_result(workflow: str,
141
- result: Result,
148
+ def save_report(workflow: str,
149
+ report: Report,
142
150
  base_path: str | Path,
143
- overwrite: bool = False) -> int:
151
+ overwrite: bool = False,
152
+ refresh_heads: bool = True) -> int:
144
153
  if workflow.startswith("cfg:"):
145
- return save_config_key_history(workflow[4:], result, base_path)
154
+ return save_config_key_history(workflow[4:], report, base_path)
146
155
 
147
156
  logger.debug(
148
- f'Saving result for "{workflow}", {result.in_spec=}, {result.bad_data=}, {result.fully_calibrated=}'
157
+ f'Saving report for "{workflow}", {report.in_spec=}, {report.bad_data=}, {report.fully_calibrated=}'
149
158
  )
150
159
  base_path = Path(base_path)
160
+ try:
161
+ buf = lzma.compress(pickle.dumps(report))
162
+ except:
163
+ raise ValueError(f"Can't pickle report for {workflow}")
151
164
  if overwrite:
152
- buf = lzma.compress(pickle.dumps(result))
153
- path = result.path
165
+ path = report.path
154
166
  if path is None:
155
- path = get_head(workflow, base_path)
156
- result.path = path
157
- with open(base_path / 'objects' / path, "rb") as f:
167
+ raise ValueError("Report path is None, can't overwrite.")
168
+ with open(base_path / 'reports' / path, "rb") as f:
158
169
  index = int.from_bytes(f.read(8), 'big')
159
- result.index = index
170
+ report.index = index
160
171
  else:
161
- result.previous_path = get_head(workflow, base_path)
162
- buf = lzma.compress(pickle.dumps(result))
163
- path = random_path(base_path / 'objects')
164
- (base_path / 'objects' / path).parent.mkdir(parents=True,
172
+ path = random_path(base_path / 'reports')
173
+ (base_path / 'reports' / path).parent.mkdir(parents=True,
165
174
  exist_ok=True)
166
- result.path = path
167
- result.index = create_index("result",
175
+ report.path = path
176
+ report.index = create_index("report",
168
177
  base_path,
169
178
  context=str(path),
170
179
  width=35)
171
-
172
- with open(base_path / 'objects' / path, "wb") as f:
173
- f.write(result.index.to_bytes(8, 'big'))
180
+ with open(base_path / 'reports' / path, "wb") as f:
181
+ f.write(report.index.to_bytes(8, 'big'))
174
182
  f.write(buf)
175
- set_head(workflow, path, base_path)
176
- return result.index
183
+ if refresh_heads:
184
+ set_head(workflow, path, base_path)
185
+ return report.index
177
186
 
178
187
 
179
- def load_result(path: str | Path, base_path: str | Path) -> Result | None:
188
+ def load_report(path: str | Path, base_path: str | Path) -> Report | None:
180
189
  base_path = Path(base_path)
181
- path = base_path / 'objects' / path
190
+ path = base_path / 'reports' / path
182
191
 
183
- with open(base_path / 'objects' / path, "rb") as f:
192
+ with open(base_path / 'reports' / path, "rb") as f:
184
193
  index = int.from_bytes(f.read(8), 'big')
185
- result = pickle.loads(lzma.decompress(f.read()))
186
- result.base_path = base_path
187
- result.index = index
188
- return result
194
+ report = pickle.loads(lzma.decompress(f.read()))
195
+ report.base_path = base_path
196
+ report.index = index
197
+ return report
189
198
 
190
199
 
191
- def find_result(
200
+ def find_report(
192
201
  workflow: str, base_path: str | Path = get_config_value("data", Path)
193
- ) -> Result | None:
202
+ ) -> Report | None:
194
203
  if workflow.startswith("cfg:"):
195
204
  return find_config_key_history(workflow[4:], base_path)
196
205
 
@@ -198,25 +207,33 @@ def find_result(
198
207
  path = get_head(workflow, base_path)
199
208
  if path is None:
200
209
  return None
201
- return load_result(path, base_path)
202
-
203
-
204
- def renew_result(workflow: str, base_path: str | Path):
205
- logger.debug(f'Renewing result for "{workflow}"')
206
- result = find_result(workflow, base_path)
207
- if result is not None:
208
- result.checked_time = datetime.now()
209
- return save_result(workflow, result, base_path)
210
+ return load_report(path, base_path)
211
+
212
+
213
+ def renew_report(workflow: str, report: Report | None, base_path: str | Path):
214
+ logger.debug(f'Renewing report for "{workflow}"')
215
+ if report is not None:
216
+ report.checked_time = datetime.now()
217
+ return save_report(workflow,
218
+ report,
219
+ base_path,
220
+ overwrite=True,
221
+ refresh_heads=True)
222
+ else:
223
+ raise ValueError(f"Can't renew report for {workflow}")
210
224
 
211
225
 
212
- def revoke_result(workflow: str, base_path: str | Path):
213
- logger.debug(f'Revoking result for "{workflow}"')
226
+ def revoke_report(workflow: str, report: Report | None, base_path: str | Path):
227
+ logger.debug(f'Revoking report for "{workflow}"')
214
228
  base_path = Path(base_path)
215
- path = get_head(workflow, base_path)
216
- if path is not None:
217
- result = load_result(path, base_path)
218
- result.in_spec = False
219
- return save_result(workflow, result, base_path)
229
+ if report is not None:
230
+ report.in_spec = False
231
+ report.previous_path = report.path
232
+ return save_report(workflow,
233
+ report,
234
+ base_path,
235
+ overwrite=False,
236
+ refresh_heads=True)
220
237
 
221
238
 
222
239
  def set_head(workflow: str, path: Path, base_path: str | Path):
@@ -296,28 +313,27 @@ def query_index(name: str, base_path: str | Path, index: int):
296
313
  return context.rstrip()
297
314
 
298
315
 
299
- def get_result_by_index(
316
+ def get_report_by_index(
300
317
  index: int, base_path: str | Path = get_config_value("data", Path)
301
- ) -> Result | None:
318
+ ) -> Report | None:
302
319
  try:
303
- path = query_index("result", base_path, index)
304
- return load_result(path, base_path)
320
+ path = query_index("report", base_path, index)
321
+ return load_report(path, base_path)
305
322
  except:
306
323
  return None
307
324
 
308
325
 
309
- def save_config(cfg, data_path):
310
- i = 0
311
- buf = pickle.dumps(cfg)
326
+ def save_item(item, data_path):
327
+ salt = 0
328
+ buf = pickle.dumps(item)
312
329
  buf = lzma.compress(buf)
313
330
  h = hashlib.md5(buf)
314
331
 
315
332
  while True:
316
- salt = f"{i}".encode()
317
- h.update(salt)
333
+ h.update(f"{salt}".encode())
318
334
  hashstr = h.hexdigest()
319
- cfg_id = Path(hashstr[:2]) / hashstr[2:4] / hashstr[4:]
320
- path = Path(data_path) / 'config' / cfg_id
335
+ item_id = Path(hashstr[:2]) / hashstr[2:4] / hashstr[4:]
336
+ path = Path(data_path) / 'items' / item_id
321
337
  if not path.exists():
322
338
  path.parent.mkdir(parents=True, exist_ok=True)
323
339
  with open(path, 'wb') as f:
@@ -325,13 +341,13 @@ def save_config(cfg, data_path):
325
341
  break
326
342
  elif path.read_bytes() == buf:
327
343
  break
328
- i += 1
329
- return str(cfg_id)
344
+ salt += 1
345
+ return str(item_id)
330
346
 
331
347
 
332
- @lru_cache(maxsize=1024)
333
- def load_config(id, data_path):
334
- path = Path(data_path) / 'config' / id
348
+ @lru_cache(maxsize=4096)
349
+ def load_item(id, data_path):
350
+ path = Path(data_path) / 'items' / id
335
351
  with open(path, 'rb') as f:
336
352
  buf = f.read()
337
353
  cfg = pickle.loads(lzma.decompress(buf))
@@ -1,4 +1,4 @@
1
- from .storage import Result, save_config
1
+ from .storage import Report, save_item
2
2
 
3
3
  __current_config_id = None
4
4
 
@@ -43,25 +43,25 @@ def _export_config() -> dict:
43
43
  return parameters
44
44
 
45
45
 
46
- def obey_the_oracle(result: Result, data_path):
46
+ def obey_the_oracle(report: Report, data_path):
47
47
  global __current_config_id
48
- update_config(result.oracle)
48
+ update_config(report.oracle)
49
49
  cfg = export_config()
50
- __current_config_id = save_config(cfg, data_path)
50
+ __current_config_id = save_item(cfg, data_path)
51
51
 
52
52
 
53
- def update_parameters(result: Result, data_path):
53
+ def update_parameters(report: Report, data_path):
54
54
  global __current_config_id
55
- update_config(result.parameters)
55
+ update_config(report.parameters)
56
56
  cfg = export_config()
57
- __current_config_id = save_config(cfg, data_path)
57
+ __current_config_id = save_item(cfg, data_path)
58
58
 
59
59
 
60
60
  def current_config(data_path):
61
61
  global __current_config_id
62
62
  if __current_config_id is None:
63
63
  cfg = export_config()
64
- __current_config_id = save_config(cfg, data_path)
64
+ __current_config_id = save_item(cfg, data_path)
65
65
  return __current_config_id
66
66
 
67
67
 
qulab/executor/utils.py CHANGED
@@ -37,7 +37,7 @@ def workflow_template(workflow: str, deps: list[str]) -> str:
37
37
  import numpy as np
38
38
  from loguru import logger
39
39
 
40
- from qulab.typing import Result
40
+ from qulab.typing import Report
41
41
 
42
42
 
43
43
  # 多长时间应该检查一次校准实验,单位是秒。
@@ -63,35 +63,35 @@ def calibrate():
63
63
  return x, y
64
64
 
65
65
 
66
- def analyze(result: Result, history: Result | None = None) -> Result:
66
+ def analyze(report: Report, history: Report | None = None) -> Report:
67
67
  \"\"\"
68
68
  分析校准结果。
69
69
 
70
- result: Result
70
+ report: Report
71
71
  本次校准实验的数据。
72
- history: Result | None
72
+ history: Report | None
73
73
  上次校准实验数据和分析结果,如果有的话。
74
74
  \"\"\"
75
75
  import random
76
76
 
77
- # 这里添加你的分析过程,运行 calibrate 得到的数据,在 result.data 里
77
+ # 这里添加你的分析过程,运行 calibrate 得到的数据,在 report.data 里
78
78
  # 你可以得到校准的结果,然后根据这个结果进行分析。
79
- x, y = result.data
79
+ x, y = report.data
80
80
 
81
81
  # 完整校准后的状态有两种:OK 和 Bad,分别对应校准成功和校准失败。
82
82
  # 校准失败是指出现坏数据,无法简单通过重新运行本次校准解决,需要
83
83
  # 检查前置步骤。
84
- result.state = random.choice(['OK', 'Bad'])
84
+ report.state = random.choice(['OK', 'Bad'])
85
85
 
86
86
  # 参数是一个字典,包含了本次校准得到的参数,后续会更新到config表中。
87
- result.parameters = {{'gate.R.Q1.params.amp':1}}
87
+ report.parameters = {{'gate.R.Q1.params.amp':1}}
88
88
 
89
89
  # 其他信息可以是任何可序列化的内容,你可以将你想要记录的信息放在这里。
90
90
  # 下次校准分析时,这些信息也会在 history 参数中一起传入,帮助你在下
91
91
  # 次分析时对比参考。
92
- result.other_infomation = {{}}
92
+ report.other_infomation = {{}}
93
93
 
94
- return result
94
+ return report
95
95
 
96
96
 
97
97
  def check():
@@ -111,33 +111,33 @@ def check():
111
111
  return x, y
112
112
 
113
113
 
114
- def check_analyze(result: Result, history: Result | None = None) -> Result:
114
+ def check_analyze(report: Report, history: Report | None = None) -> Report:
115
115
  \"\"\"
116
116
  分析检查结果。
117
117
 
118
- result: Result
118
+ report: Report
119
119
  本次检查实验的数据。
120
- history: Result | None
120
+ history: Report | None
121
121
  上次检查实验数据和分析结果,如果有的话。
122
122
  \"\"\"
123
123
  import random
124
124
 
125
- # 这里添加你的分析过程,运行 check 得到的数据,在 result.data 里
125
+ # 这里添加你的分析过程,运行 check 得到的数据,在 report.data 里
126
126
  # 你可以得到校准的结果,然后根据这个结果进行分析。
127
- x, y = result.data
127
+ x, y = report.data
128
128
 
129
129
  # 状态有三种:Outdated, OK, Bad,分别对应过时、正常、坏数据。
130
130
  # Outdated 是指数据过时,即参数漂了,需要重新校准。
131
131
  # OK 是指数据正常,参数也没漂,不用重新校准。
132
132
  # Bad 是指数据坏了,无法校准,需要检查前置步骤。
133
- result.state = random.choice(['Outdated', 'OK', 'Bad'])
133
+ report.state = random.choice(['Outdated', 'OK', 'Bad'])
134
134
 
135
- return result
135
+ return report
136
136
 
137
137
 
138
- def oracle(result: Result,
139
- history: Result | None = None,
140
- system_state: dict[str:str] | None = None) -> Result:
138
+ def oracle(report: Report,
139
+ history: Report | None = None,
140
+ system_state: dict[str:str] | None = None) -> Report:
141
141
  \"\"\"
142
142
  谕示:指凭直觉或经验判断,改动某些配置,以期望下次校准成功。
143
143
 
@@ -145,31 +145,31 @@ def oracle(result: Result,
145
145
  比如通常我们在死活测不到 rabi 或能谱时,会换一个 idle bias 再试试。这
146
146
  里我们凭直觉设的那个 bias 值,就是一个谕示,可以通过 oracle 来设定。
147
147
 
148
- 该函数代入的参数 result 是 analyze 函数的返回值。
148
+ 该函数代入的参数 report 是 analyze 函数的返回值。
149
149
  \"\"\"
150
150
 
151
- # result.oracle['Q0.bias'] = 0.1
152
- # result.oracle['Q1.bias'] = -0.03
151
+ # report.oracle['Q0.bias'] = 0.1
152
+ # report.oracle['Q1.bias'] = -0.03
153
153
 
154
- return result
154
+ return report
155
155
  """
156
156
 
157
157
 
158
158
  def debug_analyze(
159
- result_index: int,
159
+ report_index: int,
160
160
  code_path: str | Path = get_config_value('code', Path),
161
161
  data_path: str | Path = get_config_value('data', Path),
162
162
  ) -> None:
163
- from .storage import get_result_by_index
163
+ from .storage import get_report_by_index
164
164
 
165
- result = get_result_by_index(result_index, data_path)
166
- if result is None:
167
- raise ValueError(f'Invalid result index: {result_index}')
168
- workflow = result.workflow
165
+ report = get_report_by_index(report_index, data_path)
166
+ if report is None:
167
+ raise ValueError(f'Invalid report index: {report_index}')
168
+ workflow = report.workflow
169
169
  wf = load_workflow(workflow, code_path)
170
170
  if wf is None:
171
171
  raise ValueError(f'Invalid workflow: {workflow}')
172
- result = wf.analyze(result, result.previous)
172
+ report = wf.analyze(report, report.previous)
173
173
  if hasattr(wf, 'plot'):
174
- wf.plot(result)
175
- return result
174
+ wf.plot(report)
175
+ return report
Binary file
qulab/typing.py CHANGED
@@ -1,2 +1,2 @@
1
- from .executor.storage import Result
1
+ from .executor.storage import Report
2
2
  from .scan.record import Record
qulab/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "2.7.6"
1
+ __version__ = "2.7.10"
File without changes