QuLab 2.7.9__cp310-cp310-win_amd64.whl → 2.7.11__cp310-cp310-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.7.9
3
+ Version: 2.7.11
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,19 +1,19 @@
1
1
  qulab/__init__.py,sha256=RZme5maBSMZpP6ckXymqZpo2sRYttwEpTYCIzIvys1c,292
2
2
  qulab/__main__.py,sha256=FL4YsGZL1jEtmcPc5WbleArzhOHLMsWl7OH3O-1d1ss,72
3
3
  qulab/dicttree.py,sha256=ZoSJVWK4VMqfzj42gPb_n5RqLlM6K1Me0WmLIfLEYf8,14195
4
- qulab/fun.cp310-win_amd64.pyd,sha256=xX9wtf_Y62Dx3TsBO0pd4HMqmoZqBxKKaO4yJBvlRu0,31232
4
+ qulab/fun.cp310-win_amd64.pyd,sha256=m-A6E32c1JhJC_HVQJ5f2_md1qjsQ_m1EMKXBKwDpiE,31232
5
5
  qulab/typing.py,sha256=PRtwbCHWY2ROKK8GHq4Bo8llXrIGo6xC73DrQf7S9os,71
6
6
  qulab/utils.py,sha256=UyZNPIyvis5t2MJBkXXLO5EmYP3mQZbt87zmYAHgoyk,1291
7
- qulab/version.py,sha256=2Uj8_mq4WyOkRTNLvNp4euDlxbbREHlgUVtU-CUptMY,21
7
+ qulab/version.py,sha256=1KL8md1HXIKNwnebAea7SJ7-uBme-7LHKGfuCG29ZiU,22
8
8
  qulab/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  qulab/cli/commands.py,sha256=6xd2eYw32k1NmfAuYSu__1kaP12Oz1QVqwbkYXdWno4,588
10
10
  qulab/cli/config.py,sha256=tNmH4ggdgrFqcQa2WZKLpidiYTg95_UnT0paDJ4fi4c,3204
11
11
  qulab/executor/__init__.py,sha256=LosPzOMaljSZY1thy_Fxtbrgq7uubJszMABEB7oM7tU,101
12
12
  qulab/executor/cli.py,sha256=gGka2M6xccfM8facsIJ2qZ1y2Yx8C4BRhc1JG6nK9mo,8932
13
13
  qulab/executor/load.py,sha256=4FY_SwumLDUewC265v4j_ZGGpfYOgH4c8PtglYcWpBw,18077
14
- qulab/executor/schedule.py,sha256=A5LOTFFJjU7zNEkv80hnq1cYGG-uPJYrhHO6KPY8pRg,16911
15
- qulab/executor/storage.py,sha256=JH817-d6izBiz6wBGWvWxNEY_IPhRwRmGcB_eUpvE8U,11364
16
- qulab/executor/transform.py,sha256=s0kxWQx8Sr9pMIQke1BLNM6KqrSogAkjB6Zkapl8YSU,2189
14
+ qulab/executor/schedule.py,sha256=137OlWojJICEsq2BSz1ybOa1Gy8-f8U4KSC6YLgdjZ4,18061
15
+ qulab/executor/storage.py,sha256=gI6g28BmKKEZ_Pl-hFwvpiOj3mF8Su-yjj3hfMXs1VY,11630
16
+ qulab/executor/transform.py,sha256=4DyGXv1Iw36cCPqbqXlsn0Lw6gFjQpp_6Hcta50YQxU,2181
17
17
  qulab/executor/utils.py,sha256=cF6-2jlvlHyTjNHdxXKG04Fjfm3_3wfDQAF1G8DQphk,5686
18
18
  qulab/monitor/__init__.py,sha256=xEVDkJF8issrsDeLqQmDsvtRmrf-UiViFcGTWuzdlFU,43
19
19
  qulab/monitor/__main__.py,sha256=k2H1H5Zf9LLXTDLISJkbikLH-z0f1e5i5i6wXXYPOrE,105
@@ -94,9 +94,9 @@ qulab/visualization/plot_seq.py,sha256=Uo1-dB1YE9IN_A9tuaOs9ZG3S5dKDQ_l98iD2Wbxp
94
94
  qulab/visualization/qdat.py,sha256=HubXFu4nfcA7iUzghJGle1C86G6221hicLR0b-GqhKQ,5887
95
95
  qulab/visualization/rot3d.py,sha256=jGHJcqj1lEWBUV-W4GUGONGacqjrYvuFoFCwPse5h1Y,757
96
96
  qulab/visualization/widgets.py,sha256=HcYwdhDtLreJiYaZuN3LfofjJmZcLwjMfP5aasebgDo,3266
97
- QuLab-2.7.9.dist-info/LICENSE,sha256=b4NRQ-GFVpJMT7RuExW3NwhfbrYsX7AcdB7Gudok-fs,1086
98
- QuLab-2.7.9.dist-info/METADATA,sha256=nayB2CBp0e-8E_7hK5rw-hyIH14dVb1TmIl8w0CCu-E,3803
99
- QuLab-2.7.9.dist-info/WHEEL,sha256=rzGfZgUcGeKSgIHGYMuqg4xE4VPHxnaldXH6BG0zjVk,101
100
- QuLab-2.7.9.dist-info/entry_points.txt,sha256=b0v1GXOwmxY-nCCsPN_rHZZvY9CtTbWqrGj8u1m8yHo,45
101
- QuLab-2.7.9.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
102
- QuLab-2.7.9.dist-info/RECORD,,
97
+ QuLab-2.7.11.dist-info/LICENSE,sha256=b4NRQ-GFVpJMT7RuExW3NwhfbrYsX7AcdB7Gudok-fs,1086
98
+ QuLab-2.7.11.dist-info/METADATA,sha256=ZWK3GzveHjjVhPbhGV2e3XIGxCSbmsU3KgUlb4-nwEo,3804
99
+ QuLab-2.7.11.dist-info/WHEEL,sha256=rzGfZgUcGeKSgIHGYMuqg4xE4VPHxnaldXH6BG0zjVk,101
100
+ QuLab-2.7.11.dist-info/entry_points.txt,sha256=b0v1GXOwmxY-nCCsPN_rHZZvY9CtTbWqrGj8u1m8yHo,45
101
+ QuLab-2.7.11.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
102
+ QuLab-2.7.11.dist-info/RECORD,,
@@ -8,7 +8,7 @@ from loguru import logger
8
8
 
9
9
  from .load import WorkflowType, get_dependents
10
10
  from .storage import (Report, find_report, get_head, get_heads, renew_report,
11
- revoke_report, save_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
@@ -69,6 +69,16 @@ def veryfy_analyzed_report(report: Report, script: str, method: str):
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
  """
@@ -91,6 +101,11 @@ def check_state(workflow: WorkflowType, code_path: str | Path,
91
101
  f'check_state: "{workflow.__workflow_id__}" has custom check_state method'
92
102
  )
93
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
110
  ) > report.checked_time + timedelta(seconds=workflow.__timeout__):
96
111
  logger.debug(
@@ -127,7 +142,7 @@ def call_plot(node: WorkflowType, report: Report, check=False):
127
142
 
128
143
 
129
144
  def call_check(workflow: WorkflowType, session_id: str, state_path: Path):
130
- report = get_cache(session_id, (workflow, 'check'))
145
+ report = get_cache(session_id, (workflow.__workflow_id__, 'check'))
131
146
  if report is not None:
132
147
  logger.debug(f'Cache hit for "{workflow.__workflow_id__}:check"')
133
148
  return report
@@ -143,16 +158,18 @@ def call_check(workflow: WorkflowType, session_id: str, state_path: Path):
143
158
  base_path=state_path,
144
159
  heads=get_heads(state_path),
145
160
  previous_path=get_head(workflow.__workflow_id__,
146
- state_path))
161
+ state_path),
162
+ script_path=save_item(get_source(workflow, state_path),
163
+ state_path))
147
164
 
148
165
  save_report(workflow.__workflow_id__, report, state_path)
149
166
 
150
- set_cache(session_id, (workflow, 'check'), report)
167
+ set_cache(session_id, (workflow.__workflow_id__, 'check'), report)
151
168
  return report
152
169
 
153
170
 
154
171
  def call_calibrate(workflow: WorkflowType, session_id: str, state_path: Path):
155
- report = get_cache(session_id, (workflow, 'calibrate'))
172
+ report = get_cache(session_id, (workflow.__workflow_id__, 'calibrate'))
156
173
  if report is not None:
157
174
  logger.debug(f'Cache hit for "{workflow.__workflow_id__}:calibrate"')
158
175
  return report
@@ -168,11 +185,13 @@ def call_calibrate(workflow: WorkflowType, session_id: str, state_path: Path):
168
185
  base_path=state_path,
169
186
  heads=get_heads(state_path),
170
187
  previous_path=get_head(workflow.__workflow_id__,
171
- state_path))
188
+ state_path),
189
+ script_path=save_item(get_source(workflow, state_path),
190
+ state_path))
172
191
 
173
192
  save_report(workflow.__workflow_id__, report, state_path)
174
193
 
175
- set_cache(session_id, (workflow, 'calibrate'), report)
194
+ set_cache(session_id, (workflow.__workflow_id__, 'calibrate'), report)
176
195
  return report
177
196
 
178
197
 
@@ -187,11 +206,17 @@ def call_check_analyzer(node: WorkflowType,
187
206
  if report.in_spec:
188
207
  logger.debug(
189
208
  f'"{node.__workflow_id__}": checked in spec, renewing report')
190
- renew_report(node.__workflow_id__, report.previous, state_path)
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)
191
213
  else:
192
214
  logger.debug(
193
215
  f'"{node.__workflow_id__}": checked out of spec, revoking report')
194
- revoke_report(node.__workflow_id__, report.previous, state_path)
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)
195
220
  return report
196
221
 
197
222
 
@@ -244,7 +269,9 @@ def check_data(workflow: WorkflowType, state_path: str | Path, plot: bool,
244
269
  base_path=state_path,
245
270
  heads=get_heads(state_path),
246
271
  previous_path=get_head(workflow.__workflow_id__,
247
- state_path))
272
+ state_path),
273
+ script_path=save_item(get_source(workflow, state_path),
274
+ state_path))
248
275
  report.in_spec = False
249
276
  report.bad_data = False
250
277
  return report
@@ -300,11 +327,7 @@ def calibrate(workflow: WorkflowType, state_path: str | Path, plot: bool,
300
327
 
301
328
  logger.debug(f'Calibrated "{workflow.__workflow_id__}" !')
302
329
 
303
- report = call_analyzer(workflow,
304
- report,
305
- history,
306
- state_path,
307
- plot=plot)
330
+ report = call_analyzer(workflow, report, history, state_path, plot=plot)
308
331
  return report
309
332
 
310
333
 
qulab/executor/storage.py CHANGED
@@ -34,6 +34,7 @@ class Report():
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):
@@ -54,13 +55,6 @@ class Report():
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 Report():
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:
@@ -157,19 +165,19 @@ def save_report(workflow: str,
157
165
  path = report.path
158
166
  if path is None:
159
167
  raise ValueError("Report path is None, can't overwrite.")
160
- with open(base_path / 'objects' / path, "rb") as f:
168
+ with open(base_path / 'reports' / path, "rb") as f:
161
169
  index = int.from_bytes(f.read(8), 'big')
162
170
  report.index = index
163
171
  else:
164
- path = random_path(base_path / 'objects')
165
- (base_path / 'objects' / path).parent.mkdir(parents=True,
172
+ path = random_path(base_path / 'reports')
173
+ (base_path / 'reports' / path).parent.mkdir(parents=True,
166
174
  exist_ok=True)
167
175
  report.path = path
168
176
  report.index = create_index("report",
169
177
  base_path,
170
178
  context=str(path),
171
179
  width=35)
172
- with open(base_path / 'objects' / path, "wb") as f:
180
+ with open(base_path / 'reports' / path, "wb") as f:
173
181
  f.write(report.index.to_bytes(8, 'big'))
174
182
  f.write(buf)
175
183
  if refresh_heads:
@@ -179,9 +187,9 @@ def save_report(workflow: str,
179
187
 
180
188
  def load_report(path: str | Path, base_path: str | Path) -> Report | None:
181
189
  base_path = Path(base_path)
182
- path = base_path / 'objects' / path
190
+ path = base_path / 'reports' / path
183
191
 
184
- with open(base_path / 'objects' / path, "rb") as f:
192
+ with open(base_path / 'reports' / path, "rb") as f:
185
193
  index = int.from_bytes(f.read(8), 'big')
186
194
  report = pickle.loads(lzma.decompress(f.read()))
187
195
  report.base_path = base_path
@@ -315,18 +323,17 @@ def get_report_by_index(
315
323
  return None
316
324
 
317
325
 
318
- def save_config(cfg, data_path):
319
- i = 0
320
- buf = pickle.dumps(cfg)
326
+ def save_item(item, data_path):
327
+ salt = 0
328
+ buf = pickle.dumps(item)
321
329
  buf = lzma.compress(buf)
322
330
  h = hashlib.md5(buf)
323
331
 
324
332
  while True:
325
- salt = f"{i}".encode()
326
- h.update(salt)
333
+ h.update(f"{salt}".encode())
327
334
  hashstr = h.hexdigest()
328
- cfg_id = Path(hashstr[:2]) / hashstr[2:4] / hashstr[4:]
329
- 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
330
337
  if not path.exists():
331
338
  path.parent.mkdir(parents=True, exist_ok=True)
332
339
  with open(path, 'wb') as f:
@@ -334,13 +341,13 @@ def save_config(cfg, data_path):
334
341
  break
335
342
  elif path.read_bytes() == buf:
336
343
  break
337
- i += 1
338
- return str(cfg_id)
344
+ salt += 1
345
+ return str(item_id)
339
346
 
340
347
 
341
- @lru_cache(maxsize=1024)
342
- def load_config(id, data_path):
343
- 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
344
351
  with open(path, 'rb') as f:
345
352
  buf = f.read()
346
353
  cfg = pickle.loads(lzma.decompress(buf))
@@ -1,4 +1,4 @@
1
- from .storage import Report, save_config
1
+ from .storage import Report, save_item
2
2
 
3
3
  __current_config_id = None
4
4
 
@@ -47,21 +47,21 @@ def obey_the_oracle(report: Report, data_path):
47
47
  global __current_config_id
48
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
53
  def update_parameters(report: Report, data_path):
54
54
  global __current_config_id
55
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
 
Binary file
qulab/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "2.7.9"
1
+ __version__ = "2.7.11"
File without changes