QuLab 2.7.6__tar.gz → 2.7.7__tar.gz
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.
- {qulab-2.7.6 → qulab-2.7.7}/PKG-INFO +1 -1
- {qulab-2.7.6 → qulab-2.7.7}/QuLab.egg-info/PKG-INFO +1 -1
- {qulab-2.7.6 → qulab-2.7.7}/qulab/__init__.py +2 -2
- {qulab-2.7.6 → qulab-2.7.7}/qulab/executor/cli.py +2 -2
- {qulab-2.7.6 → qulab-2.7.7}/qulab/executor/load.py +11 -11
- {qulab-2.7.6 → qulab-2.7.7}/qulab/executor/schedule.py +145 -134
- {qulab-2.7.6 → qulab-2.7.7}/qulab/executor/storage.py +48 -47
- {qulab-2.7.6 → qulab-2.7.7}/qulab/executor/transform.py +5 -5
- {qulab-2.7.6 → qulab-2.7.7}/qulab/executor/utils.py +33 -33
- qulab-2.7.7/qulab/typing.py +2 -0
- qulab-2.7.7/qulab/version.py +1 -0
- qulab-2.7.6/qulab/typing.py +0 -2
- qulab-2.7.6/qulab/version.py +0 -1
- {qulab-2.7.6 → qulab-2.7.7}/LICENSE +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/MANIFEST.in +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/QuLab.egg-info/SOURCES.txt +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/QuLab.egg-info/dependency_links.txt +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/QuLab.egg-info/entry_points.txt +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/QuLab.egg-info/requires.txt +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/QuLab.egg-info/top_level.txt +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/README.md +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/pyproject.toml +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/__main__.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/cli/__init__.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/cli/commands.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/cli/config.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/dicttree.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/executor/__init__.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/monitor/__init__.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/monitor/__main__.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/monitor/config.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/monitor/dataset.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/monitor/event_queue.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/monitor/mainwindow.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/monitor/monitor.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/monitor/ploter.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/monitor/qt_compat.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/monitor/toolbar.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/scan/__init__.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/scan/curd.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/scan/expression.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/scan/models.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/scan/optimize.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/scan/query.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/scan/record.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/scan/scan.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/scan/server.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/scan/space.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/scan/utils.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/storage/__init__.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/storage/__main__.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/storage/backend/__init__.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/storage/backend/redis.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/storage/base_dataset.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/storage/chunk.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/storage/dataset.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/storage/file.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/storage/models/__init__.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/storage/models/base.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/storage/models/config.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/storage/models/file.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/storage/models/ipy.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/storage/models/models.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/storage/models/record.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/storage/models/report.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/storage/models/tag.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/storage/storage.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/__init__.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/chat.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/device/__init__.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/device/basedevice.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/device/loader.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/device/utils.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/drivers/FakeInstrument.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/drivers/__init__.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/ipy_events.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/net/__init__.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/net/bencoder.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/net/cli.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/net/dhcp.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/net/dhcpd.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/net/kad.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/net/kcp.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/net/nginx.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/progress.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/rpc/__init__.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/rpc/client.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/rpc/exceptions.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/rpc/msgpack.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/rpc/msgpack.pyi +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/rpc/router.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/rpc/rpc.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/rpc/serialize.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/rpc/server.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/rpc/socket.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/rpc/utils.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/rpc/worker.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/sys/rpc/zmq_socket.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/utils.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/visualization/__init__.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/visualization/__main__.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/visualization/_autoplot.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/visualization/plot_circ.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/visualization/plot_layout.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/visualization/plot_seq.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/visualization/qdat.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/visualization/rot3d.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/qulab/visualization/widgets.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/setup.cfg +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/setup.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/src/qulab.h +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/tests/test_kad.py +0 -0
- {qulab-2.7.6 → qulab-2.7.7}/tests/test_scan.py +0 -0
@@ -1,5 +1,5 @@
|
|
1
|
-
from .executor.storage import
|
2
|
-
from .executor.storage import
|
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__
|
@@ -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
|
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
|
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):
|
@@ -15,7 +15,7 @@ from typing import Any
|
|
15
15
|
|
16
16
|
from loguru import logger
|
17
17
|
|
18
|
-
from .storage import
|
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:
|
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,
|
49
|
-
|
50
|
-
|
51
|
-
return
|
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,
|
56
|
+
def check_analyze(self, report: Report, history: Report | None):
|
57
57
|
if self.check_state(history):
|
58
|
-
|
59
|
-
|
58
|
+
report.state = 'OK'
|
59
|
+
report.parameters = {self.key: history.data}
|
60
60
|
else:
|
61
|
-
|
62
|
-
return
|
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 (
|
11
|
-
|
10
|
+
from .storage import (Report, find_report, get_heads, renew_report,
|
11
|
+
revoke_report, 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,
|
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
|
25
|
-
__session_cache[key] =
|
24
|
+
if report.workflow.startswith('cfg:'):
|
25
|
+
__session_cache[key] = report
|
26
26
|
else:
|
27
|
-
__session_cache[key] =
|
27
|
+
__session_cache[key] = report.base_path, report.path
|
28
28
|
|
29
29
|
|
30
|
-
def get_cache(session_id, key) ->
|
31
|
-
from .storage import
|
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
|
41
|
-
elif isinstance(index,
|
40
|
+
return load_report(base_path, path)
|
41
|
+
elif isinstance(index, Report):
|
42
42
|
return index
|
43
43
|
else:
|
44
44
|
return None
|
@@ -56,14 +56,14 @@ def is_pickleable(obj) -> bool:
|
|
56
56
|
return False
|
57
57
|
|
58
58
|
|
59
|
-
def
|
60
|
-
if not isinstance(
|
61
|
-
raise TypeError(f'"{script}" : "{method}" must return a
|
62
|
-
if not is_pickleable(
|
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(
|
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
|
)
|
@@ -80,8 +80,8 @@ def check_state(workflow: WorkflowType, code_path: str | Path,
|
|
80
80
|
4. All dependencies pass check state.
|
81
81
|
"""
|
82
82
|
logger.debug(f'check_state: "{workflow.__workflow_id__}"')
|
83
|
-
|
84
|
-
if not
|
83
|
+
report = find_report(workflow.__workflow_id__, state_path)
|
84
|
+
if not report:
|
85
85
|
logger.debug(
|
86
86
|
f'check_state failed: No history found for "{workflow.__workflow_id__}"'
|
87
87
|
)
|
@@ -90,23 +90,23 @@ def check_state(workflow: WorkflowType, code_path: str | Path,
|
|
90
90
|
logger.debug(
|
91
91
|
f'check_state: "{workflow.__workflow_id__}" has custom check_state method'
|
92
92
|
)
|
93
|
-
return workflow.check_state(
|
93
|
+
return workflow.check_state(report)
|
94
94
|
if workflow.__timeout__ is not None and datetime.now(
|
95
|
-
) >
|
95
|
+
) > report.checked_time + timedelta(seconds=workflow.__timeout__):
|
96
96
|
logger.debug(
|
97
97
|
f'check_state failed: "{workflow.__workflow_id__}" has expired')
|
98
98
|
return False
|
99
|
-
if not
|
99
|
+
if not report.in_spec:
|
100
100
|
logger.debug(
|
101
101
|
f'check_state failed: "{workflow.__workflow_id__}" is out of spec')
|
102
102
|
return False
|
103
|
-
if
|
103
|
+
if report.bad_data:
|
104
104
|
logger.debug(
|
105
105
|
f'check_state failed: "{workflow.__workflow_id__}" has bad data')
|
106
106
|
return False
|
107
107
|
for n in get_dependents(workflow, code_path):
|
108
|
-
r =
|
109
|
-
if r is None or r.checked_time >
|
108
|
+
r = find_report(n.__workflow_id__, state_path)
|
109
|
+
if r is None or r.checked_time > report.checked_time:
|
110
110
|
logger.debug(
|
111
111
|
f'check_state failed: "{workflow.__workflow_id__}" has outdated dependencies'
|
112
112
|
)
|
@@ -120,71 +120,115 @@ def check_state(workflow: WorkflowType, code_path: str | Path,
|
|
120
120
|
return True
|
121
121
|
|
122
122
|
|
123
|
-
def call_analyzer(node,
|
124
|
-
|
125
|
-
history:
|
123
|
+
def call_analyzer(node: WorkflowType,
|
124
|
+
report: Report,
|
125
|
+
history: Report | None,
|
126
126
|
check=False,
|
127
|
-
plot=False) ->
|
127
|
+
plot=False) -> Report:
|
128
128
|
if check:
|
129
|
-
|
130
|
-
|
131
|
-
|
129
|
+
report = node.check_analyze(report, history=history)
|
130
|
+
veryfy_analyzed_report(report, node.__workflow_id__, "check_analyze")
|
131
|
+
report.fully_calibrated = False
|
132
132
|
else:
|
133
|
-
|
134
|
-
|
133
|
+
report = node.analyze(report, history=history)
|
134
|
+
veryfy_analyzed_report(report, node.__workflow_id__, "analyze")
|
135
135
|
if hasattr(node, 'oracle') and callable(node.oracle):
|
136
136
|
logger.debug(
|
137
137
|
f'"{node.__workflow_id__}" has oracle method, calling ...')
|
138
138
|
try:
|
139
|
-
|
139
|
+
report = node.oracle(report,
|
140
140
|
history=history,
|
141
|
-
system_state=get_heads(
|
141
|
+
system_state=get_heads(report.base_path))
|
142
142
|
except Exception as e:
|
143
143
|
logger.exception(e)
|
144
|
-
|
145
|
-
if not isinstance(
|
144
|
+
report.oracle = {}
|
145
|
+
if not isinstance(report, Report):
|
146
146
|
raise TypeError(
|
147
|
-
f'"{node.__workflow_id__}" : function "oracle" must return a
|
147
|
+
f'"{node.__workflow_id__}" : function "oracle" must return a Report object'
|
148
148
|
)
|
149
|
-
if not is_pickleable(
|
149
|
+
if not is_pickleable(report.oracle):
|
150
150
|
raise TypeError(
|
151
151
|
f'"{node.__workflow_id__}" : function "oracle" return not pickleable data'
|
152
152
|
)
|
153
|
-
|
153
|
+
report.fully_calibrated = True
|
154
154
|
if plot:
|
155
|
-
call_plot(node,
|
156
|
-
return
|
155
|
+
call_plot(node, report)
|
156
|
+
return report
|
157
157
|
|
158
158
|
|
159
159
|
@logger.catch()
|
160
|
-
def call_plot(node,
|
160
|
+
def call_plot(node: WorkflowType, report: Report, check=False):
|
161
161
|
if hasattr(node, 'plot') and callable(node.plot):
|
162
|
-
node.plot(
|
162
|
+
node.plot(report)
|
163
|
+
|
164
|
+
|
165
|
+
def call_check(workflow: WorkflowType, session_id: str, state_path: Path):
|
166
|
+
report = get_cache(session_id, (workflow, 'check'))
|
167
|
+
if report is not None:
|
168
|
+
logger.debug(f'Cache hit for "{workflow.__workflow_id__}:check"')
|
169
|
+
return report
|
170
|
+
|
171
|
+
data = workflow.check()
|
172
|
+
if not is_pickleable(data):
|
173
|
+
raise TypeError(
|
174
|
+
f'"{workflow.__workflow_id__}" : "check" return not pickleable data'
|
175
|
+
)
|
176
|
+
report = Report(workflow=workflow.__workflow_id__,
|
177
|
+
data=data,
|
178
|
+
config_path=current_config(state_path),
|
179
|
+
base_path=state_path,
|
180
|
+
heads=get_heads(state_path))
|
181
|
+
|
182
|
+
save_report(workflow.__workflow_id__,
|
183
|
+
report,
|
184
|
+
state_path,
|
185
|
+
refresh_heads=False)
|
186
|
+
|
187
|
+
set_cache(session_id, (workflow, 'check'), report)
|
188
|
+
return report
|
189
|
+
|
190
|
+
|
191
|
+
def call_calibrate(workflow: WorkflowType, session_id: str, state_path: Path):
|
192
|
+
report = get_cache(session_id, (workflow, 'calibrate'))
|
193
|
+
if report is not None:
|
194
|
+
logger.debug(f'Cache hit for "{workflow.__workflow_id__}:calibrate"')
|
195
|
+
return report
|
196
|
+
|
197
|
+
data = workflow.calibrate()
|
198
|
+
if not is_pickleable(data):
|
199
|
+
raise TypeError(
|
200
|
+
f'"{workflow.__workflow_id__}" : "calibrate" return not pickleable data'
|
201
|
+
)
|
202
|
+
report = Report(workflow=workflow.__workflow_id__,
|
203
|
+
data=data,
|
204
|
+
config_path=current_config(state_path),
|
205
|
+
base_path=state_path,
|
206
|
+
heads=get_heads(state_path))
|
207
|
+
|
208
|
+
save_report(workflow.__workflow_id__, report, state_path)
|
209
|
+
|
210
|
+
set_cache(session_id, (workflow, 'calibrate'), report)
|
211
|
+
return report
|
163
212
|
|
164
213
|
|
165
214
|
def check_data(workflow: WorkflowType, code_path: str | Path,
|
166
|
-
state_path: str | Path, plot: bool, session_id: str) ->
|
215
|
+
state_path: str | Path, plot: bool, session_id: str) -> Report:
|
167
216
|
"""
|
168
217
|
check data answers two questions:
|
169
218
|
Is the parameter associated with this cal in spec,
|
170
219
|
and is the cal scan working as expected?
|
171
220
|
"""
|
172
|
-
|
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)
|
221
|
+
history = find_report(workflow.__workflow_id__, state_path)
|
178
222
|
|
179
223
|
if history is None:
|
180
224
|
logger.debug(f'No history found for "{workflow.__workflow_id__}"')
|
181
|
-
|
225
|
+
report = Report(workflow=workflow.__workflow_id__,
|
182
226
|
config_path=current_config(state_path),
|
183
227
|
base_path=state_path,
|
184
228
|
heads=get_heads(state_path))
|
185
|
-
|
186
|
-
|
187
|
-
return
|
229
|
+
report.in_spec = False
|
230
|
+
report.bad_data = False
|
231
|
+
return report
|
188
232
|
|
189
233
|
if history.bad_data:
|
190
234
|
logger.debug(
|
@@ -202,92 +246,59 @@ def check_data(workflow: WorkflowType, code_path: str | Path,
|
|
202
246
|
workflow, 'check_analyze') and callable(workflow.check_analyze):
|
203
247
|
logger.debug(
|
204
248
|
f'Checking "{workflow.__workflow_id__}" with "check" method ...')
|
205
|
-
|
206
|
-
|
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)
|
249
|
+
|
250
|
+
report = call_check(workflow, session_id, state_path)
|
216
251
|
|
217
252
|
logger.debug(f'Checked "{workflow.__workflow_id__}" !')
|
218
|
-
|
219
|
-
|
253
|
+
report = call_analyzer(workflow,
|
254
|
+
report,
|
220
255
|
history,
|
221
256
|
check=True,
|
222
257
|
plot=plot)
|
223
|
-
if
|
258
|
+
if report.in_spec:
|
224
259
|
logger.debug(
|
225
|
-
f'"{workflow.__workflow_id__}": checked in spec, renewing
|
260
|
+
f'"{workflow.__workflow_id__}": checked in spec, renewing report'
|
226
261
|
)
|
227
|
-
|
262
|
+
renew_report(workflow.__workflow_id__, report, state_path)
|
228
263
|
else:
|
229
264
|
logger.debug(
|
230
|
-
f'"{workflow.__workflow_id__}": checked out of spec, revoking
|
265
|
+
f'"{workflow.__workflow_id__}": checked out of spec, revoking report'
|
231
266
|
)
|
232
|
-
|
267
|
+
revoke_report(workflow.__workflow_id__, report, state_path)
|
233
268
|
else:
|
234
269
|
logger.debug(
|
235
270
|
f'Checking "{workflow.__workflow_id__}" with "calibrate" method ...'
|
236
271
|
)
|
237
|
-
|
238
|
-
|
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)
|
272
|
+
|
273
|
+
report = call_calibrate(workflow, session_id, state_path)
|
248
274
|
|
249
275
|
logger.debug(f'Calibrated "{workflow.__workflow_id__}" !')
|
250
|
-
|
251
|
-
|
276
|
+
report = call_analyzer(workflow,
|
277
|
+
report,
|
252
278
|
history,
|
253
279
|
check=False,
|
254
280
|
plot=plot)
|
255
|
-
|
256
|
-
|
281
|
+
save_report(workflow.__workflow_id__,
|
282
|
+
report,
|
257
283
|
state_path,
|
258
284
|
overwrite=True)
|
259
|
-
|
260
|
-
set_cache(session_id, (workflow, 'check_data'), result)
|
261
|
-
return result
|
285
|
+
return report
|
262
286
|
|
263
287
|
|
264
288
|
def calibrate(workflow: WorkflowType, code_path: str | Path,
|
265
|
-
state_path: str | Path, plot: bool, session_id: str) ->
|
266
|
-
|
267
|
-
if result is not None:
|
268
|
-
logger.debug(f'Cache hit for "{workflow.__workflow_id__}:calibrate"')
|
269
|
-
return result
|
270
|
-
|
271
|
-
history = find_result(workflow.__workflow_id__, state_path)
|
289
|
+
state_path: str | Path, plot: bool, session_id: str) -> Report:
|
290
|
+
history = find_report(workflow.__workflow_id__, state_path)
|
272
291
|
|
273
292
|
logger.debug(f'Calibrating "{workflow.__workflow_id__}" ...')
|
274
|
-
|
275
|
-
|
276
|
-
|
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)
|
293
|
+
|
294
|
+
report = call_calibrate(workflow, session_id, state_path)
|
295
|
+
|
285
296
|
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
297
|
|
289
|
-
|
290
|
-
|
298
|
+
report = call_analyzer(workflow, report, history, check=False, plot=plot)
|
299
|
+
|
300
|
+
save_report(workflow.__workflow_id__, report, state_path, overwrite=True)
|
301
|
+
return report
|
291
302
|
|
292
303
|
|
293
304
|
def diagnose(workflow: WorkflowType, code_path: str | Path,
|
@@ -297,16 +308,16 @@ def diagnose(workflow: WorkflowType, code_path: str | Path,
|
|
297
308
|
'''
|
298
309
|
logger.debug(f'diagnose "{workflow.__workflow_id__}"')
|
299
310
|
# check_data
|
300
|
-
|
311
|
+
report = check_data(workflow, code_path, state_path, plot, session_id)
|
301
312
|
# in spec case
|
302
|
-
if
|
313
|
+
if report.in_spec:
|
303
314
|
logger.debug(
|
304
315
|
f'"{workflow.__workflow_id__}": Checked! In spec, no need to diagnose'
|
305
316
|
)
|
306
317
|
return False
|
307
318
|
# bad data case
|
308
319
|
recalibrated = []
|
309
|
-
if
|
320
|
+
if report.bad_data:
|
310
321
|
logger.debug(
|
311
322
|
f'"{workflow.__workflow_id__}": Bad data, diagnosing dependents')
|
312
323
|
recalibrated = [
|
@@ -314,7 +325,7 @@ def diagnose(workflow: WorkflowType, code_path: str | Path,
|
|
314
325
|
for n in get_dependents(workflow, code_path)
|
315
326
|
]
|
316
327
|
if not any(recalibrated):
|
317
|
-
if
|
328
|
+
if report.bad_data:
|
318
329
|
raise CalibrationFailedError(
|
319
330
|
f'"{workflow.__workflow_id__}": bad data but no dependents recalibrated.'
|
320
331
|
)
|
@@ -325,27 +336,27 @@ def diagnose(workflow: WorkflowType, code_path: str | Path,
|
|
325
336
|
logger.debug(
|
326
337
|
f'recalibrate "{workflow.__workflow_id__}" because some dependents recalibrated.'
|
327
338
|
)
|
328
|
-
elif not
|
339
|
+
elif not report.in_spec and not report.bad_data:
|
329
340
|
logger.debug(
|
330
341
|
f'recalibrate "{workflow.__workflow_id__}" because out of spec.')
|
331
|
-
elif
|
342
|
+
elif report.in_spec:
|
332
343
|
logger.error(
|
333
344
|
f'Never reach: recalibrate "{workflow.__workflow_id__}" because in spec.'
|
334
345
|
)
|
335
|
-
elif
|
346
|
+
elif report.bad_data:
|
336
347
|
logger.error(
|
337
348
|
f'Never reach: recalibrate "{workflow.__workflow_id__}" because bad data.'
|
338
349
|
)
|
339
350
|
else:
|
340
351
|
logger.error(f'Never reach: recalibrate "{workflow.__workflow_id__}"')
|
341
352
|
|
342
|
-
|
343
|
-
if
|
344
|
-
obey_the_oracle(
|
353
|
+
report = calibrate(workflow, code_path, state_path, plot, session_id)
|
354
|
+
if report.bad_data or not report.in_spec:
|
355
|
+
obey_the_oracle(report, state_path)
|
345
356
|
raise CalibrationFailedError(
|
346
357
|
f'"{workflow.__workflow_id__}": All dependents passed, but calibration failed!'
|
347
358
|
)
|
348
|
-
update_parameters(
|
359
|
+
update_parameters(report, state_path)
|
349
360
|
return True
|
350
361
|
|
351
362
|
|
@@ -382,13 +393,13 @@ def maintain(workflow: WorkflowType,
|
|
382
393
|
f'"{workflow.__workflow_id__}": In spec, no need to maintain')
|
383
394
|
return
|
384
395
|
# check_data
|
385
|
-
|
386
|
-
if
|
396
|
+
report = check_data(workflow, code_path, state_path, plot, session_id)
|
397
|
+
if report.in_spec:
|
387
398
|
if not run:
|
388
399
|
logger.debug(
|
389
400
|
f'"{workflow.__workflow_id__}": In spec, no need to maintain')
|
390
401
|
return
|
391
|
-
elif
|
402
|
+
elif report.bad_data:
|
392
403
|
logger.debug(
|
393
404
|
f'"{workflow.__workflow_id__}": Bad data, diagnosing dependents')
|
394
405
|
for n in get_dependents(workflow, code_path):
|
@@ -401,15 +412,15 @@ def maintain(workflow: WorkflowType,
|
|
401
412
|
f'"{workflow.__workflow_id__}": All dependents diagnosed')
|
402
413
|
# calibrate
|
403
414
|
logger.debug(f'recalibrate "{workflow.__workflow_id__}"')
|
404
|
-
|
405
|
-
if
|
415
|
+
report = calibrate(workflow, code_path, state_path, plot, session_id)
|
416
|
+
if report.bad_data or not report.in_spec:
|
406
417
|
if not freeze:
|
407
|
-
obey_the_oracle(
|
418
|
+
obey_the_oracle(report, state_path)
|
408
419
|
raise CalibrationFailedError(
|
409
420
|
f'"{workflow.__workflow_id__}": All dependents passed, but calibration failed!'
|
410
421
|
)
|
411
422
|
if not freeze:
|
412
|
-
update_parameters(
|
423
|
+
update_parameters(report, state_path)
|
413
424
|
return
|
414
425
|
|
415
426
|
|
@@ -421,17 +432,17 @@ def run(workflow: WorkflowType,
|
|
421
432
|
freeze: bool = False):
|
422
433
|
session_id = uuid.uuid4().hex
|
423
434
|
logger.debug(f'run "{workflow.__workflow_id__}" without dependences.')
|
424
|
-
|
435
|
+
report = calibrate(workflow,
|
425
436
|
code_path,
|
426
437
|
state_path,
|
427
438
|
plot,
|
428
439
|
session_id=session_id)
|
429
|
-
if
|
440
|
+
if report.bad_data or not report.in_spec:
|
430
441
|
if not freeze:
|
431
|
-
obey_the_oracle(
|
442
|
+
obey_the_oracle(report, state_path)
|
432
443
|
raise CalibrationFailedError(
|
433
444
|
f'"{workflow.__workflow_id__}": All dependents passed, but calibration failed!'
|
434
445
|
)
|
435
446
|
if not freeze:
|
436
|
-
update_parameters(
|
447
|
+
update_parameters(report, state_path)
|
437
448
|
return
|