QuLab 2.0.0__tar.gz → 2.0.1__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.0.0 → QuLab-2.0.1}/PKG-INFO +1 -1
- {QuLab-2.0.0 → QuLab-2.0.1}/QuLab.egg-info/PKG-INFO +1 -1
- {QuLab-2.0.0 → QuLab-2.0.1}/QuLab.egg-info/SOURCES.txt +18 -8
- QuLab-2.0.1/QuLab.egg-info/entry_points.txt +2 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/pyproject.toml +3 -0
- QuLab-2.0.1/qulab/__main__.py +24 -0
- QuLab-2.0.1/qulab/monitor/__init__.py +1 -0
- QuLab-2.0.1/qulab/monitor/__main__.py +8 -0
- QuLab-2.0.0/qulab/monitor/__init__.py → QuLab-2.0.1/qulab/monitor/monitor.py +2 -2
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/scan/base.py +13 -9
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/scan/expression.py +117 -5
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/scan/scanner.py +30 -4
- QuLab-2.0.1/qulab/version.py +1 -0
- QuLab-2.0.1/qulab/visualization/__init__.py +188 -0
- QuLab-2.0.1/qulab/visualization/__main__.py +71 -0
- QuLab-2.0.1/qulab/visualization/_autoplot.py +457 -0
- QuLab-2.0.1/qulab/visualization/plot_layout.py +408 -0
- QuLab-2.0.1/qulab/visualization/plot_seq.py +90 -0
- QuLab-2.0.1/qulab/visualization/qdat.py +152 -0
- QuLab-2.0.1/qulab/visualization/widgets.py +86 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/setup.py +1 -1
- QuLab-2.0.0/qulab/monitor/multiploter/__init__.py +0 -1
- QuLab-2.0.0/qulab/version.py +0 -1
- {QuLab-2.0.0 → QuLab-2.0.1}/LICENSE +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/MANIFEST.in +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/QuLab.egg-info/dependency_links.txt +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/QuLab.egg-info/requires.txt +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/QuLab.egg-info/top_level.txt +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/README.md +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/__init__.py +0 -0
- {QuLab-2.0.0/qulab/monitor/multiploter → QuLab-2.0.1/qulab/monitor}/config.py +0 -0
- {QuLab-2.0.0/qulab/monitor/multiploter → QuLab-2.0.1/qulab/monitor}/dataset.py +0 -0
- {QuLab-2.0.0/qulab/monitor/multiploter → QuLab-2.0.1/qulab/monitor}/event_queue.py +0 -0
- /QuLab-2.0.0/qulab/monitor/multiploter/main.py → /QuLab-2.0.1/qulab/monitor/mainwindow.py +0 -0
- {QuLab-2.0.0/qulab/monitor/multiploter → QuLab-2.0.1/qulab/monitor}/ploter.py +0 -0
- {QuLab-2.0.0/qulab/monitor/multiploter → QuLab-2.0.1/qulab/monitor}/qt_compat.py +0 -0
- {QuLab-2.0.0/qulab/monitor/multiploter → QuLab-2.0.1/qulab/monitor}/toolbar.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/scan/__init__.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/scan/dataset.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/scan/optimize.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/scan/transforms.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/scan/utils.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/storage/__init__.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/storage/__main__.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/storage/backend/__init__.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/storage/backend/redis.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/storage/base_dataset.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/storage/chunk.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/storage/dataset.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/storage/file.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/storage/models/__init__.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/storage/models/base.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/storage/models/config.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/storage/models/file.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/storage/models/ipy.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/storage/models/models.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/storage/models/record.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/storage/models/report.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/storage/models/tag.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/storage/storage.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/__init__.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/chat.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/device/__init__.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/device/basedevice.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/device/loader.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/device/utils.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/drivers/FakeInstrument.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/drivers/__init__.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/ipy_events.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/net/__init__.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/net/bencoder.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/net/cli.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/net/dhcp.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/net/dhcpd.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/net/kad.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/net/kcp.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/net/nginx.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/progress.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/rpc/__init__.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/rpc/client.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/rpc/exceptions.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/rpc/msgpack.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/rpc/msgpack.pyi +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/rpc/rpc.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/rpc/serialize.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/rpc/server.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/rpc/socket.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/rpc/utils.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/qulab/sys/rpc/worker.py +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/setup.cfg +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/src/qulab.h +0 -0
- {QuLab-2.0.0 → QuLab-2.0.1}/tests/test_scan_iter.py +0 -0
|
@@ -6,19 +6,22 @@ setup.py
|
|
|
6
6
|
QuLab.egg-info/PKG-INFO
|
|
7
7
|
QuLab.egg-info/SOURCES.txt
|
|
8
8
|
QuLab.egg-info/dependency_links.txt
|
|
9
|
+
QuLab.egg-info/entry_points.txt
|
|
9
10
|
QuLab.egg-info/requires.txt
|
|
10
11
|
QuLab.egg-info/top_level.txt
|
|
11
12
|
qulab/__init__.py
|
|
13
|
+
qulab/__main__.py
|
|
12
14
|
qulab/version.py
|
|
13
15
|
qulab/monitor/__init__.py
|
|
14
|
-
qulab/monitor/
|
|
15
|
-
qulab/monitor/
|
|
16
|
-
qulab/monitor/
|
|
17
|
-
qulab/monitor/
|
|
18
|
-
qulab/monitor/
|
|
19
|
-
qulab/monitor/
|
|
20
|
-
qulab/monitor/
|
|
21
|
-
qulab/monitor/
|
|
16
|
+
qulab/monitor/__main__.py
|
|
17
|
+
qulab/monitor/config.py
|
|
18
|
+
qulab/monitor/dataset.py
|
|
19
|
+
qulab/monitor/event_queue.py
|
|
20
|
+
qulab/monitor/mainwindow.py
|
|
21
|
+
qulab/monitor/monitor.py
|
|
22
|
+
qulab/monitor/ploter.py
|
|
23
|
+
qulab/monitor/qt_compat.py
|
|
24
|
+
qulab/monitor/toolbar.py
|
|
22
25
|
qulab/scan/__init__.py
|
|
23
26
|
qulab/scan/base.py
|
|
24
27
|
qulab/scan/dataset.py
|
|
@@ -74,5 +77,12 @@ qulab/sys/rpc/server.py
|
|
|
74
77
|
qulab/sys/rpc/socket.py
|
|
75
78
|
qulab/sys/rpc/utils.py
|
|
76
79
|
qulab/sys/rpc/worker.py
|
|
80
|
+
qulab/visualization/__init__.py
|
|
81
|
+
qulab/visualization/__main__.py
|
|
82
|
+
qulab/visualization/_autoplot.py
|
|
83
|
+
qulab/visualization/plot_layout.py
|
|
84
|
+
qulab/visualization/plot_seq.py
|
|
85
|
+
qulab/visualization/qdat.py
|
|
86
|
+
qulab/visualization/widgets.py
|
|
77
87
|
src/qulab.h
|
|
78
88
|
tests/test_scan_iter.py
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from .monitor.__main__ import main as monitor
|
|
4
|
+
from .sys.net.cli import dht
|
|
5
|
+
from .visualization.__main__ import plot
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@click.group()
|
|
9
|
+
def main():
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@main.command()
|
|
14
|
+
def hello():
|
|
15
|
+
"""Print hello world."""
|
|
16
|
+
click.echo('hello, world')
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
main.add_command(monitor)
|
|
20
|
+
main.add_command(plot)
|
|
21
|
+
main.add_command(dht)
|
|
22
|
+
|
|
23
|
+
if __name__ == '__main__':
|
|
24
|
+
main()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .monitor import Monitor, get_monitor
|
|
@@ -11,8 +11,8 @@ def main(queue: mp.Queue,
|
|
|
11
11
|
ncols: int = 4,
|
|
12
12
|
minimum_height: int = 400,
|
|
13
13
|
colors: list[tuple[int, int, int]] = []):
|
|
14
|
-
from .
|
|
15
|
-
from .
|
|
14
|
+
from .mainwindow import MainWindow
|
|
15
|
+
from .qt_compat import QtWidgets
|
|
16
16
|
|
|
17
17
|
app = QtWidgets.QApplication(sys.argv)
|
|
18
18
|
main = MainWindow(queue, ncols, minimum_height, colors)
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import inspect
|
|
3
2
|
import logging
|
|
4
3
|
import warnings
|
|
@@ -7,7 +6,6 @@ from concurrent.futures import Executor, Future
|
|
|
7
6
|
from dataclasses import dataclass, field
|
|
8
7
|
from graphlib import TopologicalSorter
|
|
9
8
|
from itertools import chain, count
|
|
10
|
-
|
|
11
9
|
from queue import Empty, Queue
|
|
12
10
|
from typing import Any, Callable, Iterable, Sequence, Type
|
|
13
11
|
|
|
@@ -323,20 +321,27 @@ def _args_generator(loops: list,
|
|
|
323
321
|
kw = _generate_kwds(keys, current_iters, kwds, i, limit)
|
|
324
322
|
except StopIteration:
|
|
325
323
|
break
|
|
324
|
+
if vars:
|
|
325
|
+
vars2 = [
|
|
326
|
+
*vars[:-1],
|
|
327
|
+
tuple([*vars[-1], *local_vars]),
|
|
328
|
+
tuple(kw.keys())
|
|
329
|
+
]
|
|
330
|
+
else:
|
|
331
|
+
vars2 = [tuple([*local_vars, *kw.keys()])]
|
|
326
332
|
yield Begin(level=level,
|
|
327
333
|
pos=pos + (i, ),
|
|
328
334
|
kwds=kwds | kw,
|
|
329
|
-
vars=
|
|
335
|
+
vars=vars2,
|
|
330
336
|
_pipes=pipes,
|
|
331
337
|
_trackers=trackers)
|
|
332
|
-
yield from _args_generator(
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
trackers, pipes, order)
|
|
338
|
+
yield from _args_generator(loops, kwds | kw, level + 1, pos + (i, ),
|
|
339
|
+
vars2, filter, functions, trackers, pipes,
|
|
340
|
+
order)
|
|
336
341
|
yield End(level=level,
|
|
337
342
|
pos=pos + (i, ),
|
|
338
343
|
kwds=kwds | kw,
|
|
339
|
-
vars=
|
|
344
|
+
vars=vars2,
|
|
340
345
|
_pipes=pipes,
|
|
341
346
|
_trackers=trackers)
|
|
342
347
|
_feedback(current_iters)
|
|
@@ -541,4 +546,3 @@ def scan_iters(loops: dict[str | tuple[str, ...],
|
|
|
541
546
|
step.unchanged = i
|
|
542
547
|
yield step
|
|
543
548
|
last_step = step
|
|
544
|
-
|
|
@@ -8,6 +8,7 @@ from pyparsing import (CaselessKeyword, Combine, Forward, Group, Keyword,
|
|
|
8
8
|
alphanums, alphas, delimitedList, nums, oneOf, opAssoc,
|
|
9
9
|
pyparsing_common, restOfLine, srange, stringEnd,
|
|
10
10
|
stringStart)
|
|
11
|
+
from scipy import special
|
|
11
12
|
|
|
12
13
|
LPAREN, RPAREN, LBRACK, RBRACK, LBRACE, RBRACE, DOT, TILDE, BANG, PLUS, MINUS = map(
|
|
13
14
|
Suppress, "()[]{}.~!+-")
|
|
@@ -60,15 +61,45 @@ class Env():
|
|
|
60
61
|
self.consts = {}
|
|
61
62
|
self.variables = {}
|
|
62
63
|
self.refs = {}
|
|
64
|
+
self.functions = {
|
|
65
|
+
'sin': np.sin,
|
|
66
|
+
'cos': np.cos,
|
|
67
|
+
'tan': np.tan,
|
|
68
|
+
'pi': np.pi,
|
|
69
|
+
'e': np.e,
|
|
70
|
+
'log': np.log,
|
|
71
|
+
'log2': np.log2,
|
|
72
|
+
'log10': np.log10,
|
|
73
|
+
'exp': np.exp,
|
|
74
|
+
'sqrt': np.sqrt,
|
|
75
|
+
'abs': np.abs,
|
|
76
|
+
'sinh': np.sinh,
|
|
77
|
+
'cosh': np.cosh,
|
|
78
|
+
'tanh': np.tanh,
|
|
79
|
+
'arcsin': np.arcsin,
|
|
80
|
+
'arccos': np.arccos,
|
|
81
|
+
'arctan': np.arctan,
|
|
82
|
+
'arctan2': np.arctan2,
|
|
83
|
+
'arcsinh': np.arcsinh,
|
|
84
|
+
'arccosh': np.arccosh,
|
|
85
|
+
'arctanh': np.arctanh,
|
|
86
|
+
'sinc': np.sinc,
|
|
87
|
+
'sign': np.sign,
|
|
88
|
+
'heaviside': np.heaviside,
|
|
89
|
+
'erf': special.erf,
|
|
90
|
+
'erfc': special.erfc,
|
|
91
|
+
}
|
|
63
92
|
|
|
64
93
|
def __contains__(self, key):
|
|
65
|
-
return key in self.consts or key in self.variables or key in self.refs
|
|
94
|
+
return key in self.consts or key in self.variables or key in self.functions or key in self.refs
|
|
66
95
|
|
|
67
96
|
def __getitem__(self, key):
|
|
68
97
|
if key in self.consts:
|
|
69
98
|
return self.consts[key]
|
|
70
99
|
if key in self.variables:
|
|
71
100
|
return self.variables[key]
|
|
101
|
+
if key in self.functions:
|
|
102
|
+
return self.functions[key]
|
|
72
103
|
if key in self.refs:
|
|
73
104
|
return self[self.refs[key]]
|
|
74
105
|
raise KeyError(f"Key {key} not found")
|
|
@@ -110,6 +141,9 @@ class Env():
|
|
|
110
141
|
return key in self.consts
|
|
111
142
|
|
|
112
143
|
|
|
144
|
+
_default_env = Env()
|
|
145
|
+
|
|
146
|
+
|
|
113
147
|
class Expression():
|
|
114
148
|
|
|
115
149
|
def __init__(self):
|
|
@@ -127,33 +161,85 @@ class Expression():
|
|
|
127
161
|
raise NotImplementedError
|
|
128
162
|
|
|
129
163
|
def __add__(self, other):
|
|
164
|
+
if isinstance(other, Expression):
|
|
165
|
+
other = other.eval(_default_env)
|
|
166
|
+
if isinstance(other, ConstType) and other == 0:
|
|
167
|
+
return self
|
|
130
168
|
return BinaryExpression(self, other, operator.add)
|
|
131
169
|
|
|
132
170
|
def __radd__(self, other):
|
|
171
|
+
if isinstance(other, Expression):
|
|
172
|
+
other = other.eval(_default_env)
|
|
173
|
+
if isinstance(other, ConstType) and other == 0:
|
|
174
|
+
return self
|
|
133
175
|
return BinaryExpression(other, self, operator.add)
|
|
134
176
|
|
|
135
177
|
def __sub__(self, other):
|
|
178
|
+
if isinstance(other, Expression):
|
|
179
|
+
other = other.eval(_default_env)
|
|
180
|
+
if isinstance(other, ConstType) and other == 0:
|
|
181
|
+
return self
|
|
136
182
|
return BinaryExpression(self, other, operator.sub)
|
|
137
183
|
|
|
138
184
|
def __rsub__(self, other):
|
|
185
|
+
if isinstance(other, Expression):
|
|
186
|
+
other = other.eval(_default_env)
|
|
187
|
+
if isinstance(other, ConstType) and other == 0:
|
|
188
|
+
return -self
|
|
139
189
|
return BinaryExpression(other, self, operator.sub)
|
|
140
190
|
|
|
141
191
|
def __mul__(self, other):
|
|
192
|
+
if isinstance(other, Expression):
|
|
193
|
+
other = other.eval(_default_env)
|
|
194
|
+
if isinstance(other, ConstType) and other == 0:
|
|
195
|
+
return 0
|
|
196
|
+
if isinstance(other, ConstType) and other == 1:
|
|
197
|
+
return self
|
|
198
|
+
if isinstance(other, ConstType) and other == -1:
|
|
199
|
+
return -self
|
|
142
200
|
return BinaryExpression(self, other, operator.mul)
|
|
143
201
|
|
|
144
202
|
def __rmul__(self, other):
|
|
203
|
+
if isinstance(other, Expression):
|
|
204
|
+
other = other.eval(_default_env)
|
|
205
|
+
if isinstance(other, ConstType) and other == 0:
|
|
206
|
+
return 0
|
|
207
|
+
if isinstance(other, ConstType) and other == 1:
|
|
208
|
+
return self
|
|
209
|
+
if isinstance(other, ConstType) and other == -1:
|
|
210
|
+
return -self
|
|
145
211
|
return BinaryExpression(other, self, operator.mul)
|
|
146
212
|
|
|
147
213
|
def __truediv__(self, other):
|
|
214
|
+
if isinstance(other, Expression):
|
|
215
|
+
other = other.eval(_default_env)
|
|
216
|
+
if isinstance(other, ConstType) and other == 1:
|
|
217
|
+
return self
|
|
218
|
+
if isinstance(other, ConstType) and other == -1:
|
|
219
|
+
return -self
|
|
148
220
|
return BinaryExpression(self, other, operator.truediv)
|
|
149
221
|
|
|
150
222
|
def __rtruediv__(self, other):
|
|
223
|
+
if isinstance(other, Expression):
|
|
224
|
+
other = other.eval(_default_env)
|
|
225
|
+
if isinstance(other, ConstType) and other == 0:
|
|
226
|
+
return 0
|
|
151
227
|
return BinaryExpression(other, self, operator.truediv)
|
|
152
228
|
|
|
153
229
|
def __pow__(self, other):
|
|
230
|
+
if isinstance(other, Expression):
|
|
231
|
+
other = other.eval(_default_env)
|
|
232
|
+
if isinstance(other, ConstType) and other == 0:
|
|
233
|
+
return 1
|
|
234
|
+
if isinstance(other, ConstType) and other == 1:
|
|
235
|
+
return self
|
|
154
236
|
return BinaryExpression(self, other, operator.pow)
|
|
155
237
|
|
|
156
238
|
def __rpow__(self, other):
|
|
239
|
+
if isinstance(other, Expression):
|
|
240
|
+
other = other.eval(_default_env)
|
|
241
|
+
if isinstance(other, ConstType) and other == 0:
|
|
242
|
+
return 0
|
|
157
243
|
return BinaryExpression(other, self, operator.pow)
|
|
158
244
|
|
|
159
245
|
def __neg__(self):
|
|
@@ -163,32 +249,52 @@ class Expression():
|
|
|
163
249
|
return UnaryExpression(self, operator.pos)
|
|
164
250
|
|
|
165
251
|
def __eq__(self, other):
|
|
252
|
+
if isinstance(other, Expression):
|
|
253
|
+
other = other.eval(_default_env)
|
|
166
254
|
return BinaryExpression(self, other, operator.eq)
|
|
167
255
|
|
|
168
256
|
def __ne__(self, other):
|
|
257
|
+
if isinstance(other, Expression):
|
|
258
|
+
other = other.eval(_default_env)
|
|
169
259
|
return BinaryExpression(self, other, operator.ne)
|
|
170
260
|
|
|
171
261
|
def __lt__(self, other):
|
|
262
|
+
if isinstance(other, Expression):
|
|
263
|
+
other = other.eval(_default_env)
|
|
172
264
|
return BinaryExpression(self, other, operator.lt)
|
|
173
265
|
|
|
174
266
|
def __le__(self, other):
|
|
267
|
+
if isinstance(other, Expression):
|
|
268
|
+
other = other.eval(_default_env)
|
|
175
269
|
return BinaryExpression(self, other, operator.le)
|
|
176
270
|
|
|
177
271
|
def __gt__(self, other):
|
|
272
|
+
if isinstance(other, Expression):
|
|
273
|
+
other = other.eval(_default_env)
|
|
178
274
|
return BinaryExpression(self, other, operator.gt)
|
|
179
275
|
|
|
180
276
|
def __ge__(self, other):
|
|
277
|
+
if isinstance(other, Expression):
|
|
278
|
+
other = other.eval(_default_env)
|
|
181
279
|
return BinaryExpression(self, other, operator.ge)
|
|
182
280
|
|
|
183
281
|
def __getitem__(self, other):
|
|
282
|
+
if isinstance(other, Expression):
|
|
283
|
+
other = other.eval(_default_env)
|
|
184
284
|
return ObjectMethod(self, '__getitem__', other)
|
|
185
285
|
|
|
186
286
|
def __getattr__(self, other):
|
|
287
|
+
if isinstance(other, Expression):
|
|
288
|
+
other = other.eval(_default_env)
|
|
187
289
|
return ObjectMethod(self, '__getattr__', other)
|
|
188
290
|
|
|
189
291
|
def __call__(self, *args):
|
|
292
|
+
args = [
|
|
293
|
+
o.eval(_default_env) if isinstance(o, Expression) else o
|
|
294
|
+
for o in args
|
|
295
|
+
]
|
|
190
296
|
return ObjectMethod(self, '__call__', *args)
|
|
191
|
-
|
|
297
|
+
|
|
192
298
|
def __round__(self, n=None):
|
|
193
299
|
return self
|
|
194
300
|
|
|
@@ -243,7 +349,7 @@ class UnaryExpression(Expression):
|
|
|
243
349
|
return self.op(self.a.d(x))
|
|
244
350
|
else:
|
|
245
351
|
return 0
|
|
246
|
-
|
|
352
|
+
|
|
247
353
|
def __repr__(self) -> str:
|
|
248
354
|
return f"{self.op.__name__}({self.a!r})"
|
|
249
355
|
|
|
@@ -300,7 +406,7 @@ class BinaryExpression(Expression):
|
|
|
300
406
|
return 0
|
|
301
407
|
else:
|
|
302
408
|
return 0
|
|
303
|
-
|
|
409
|
+
|
|
304
410
|
def __repr__(self) -> str:
|
|
305
411
|
return f"({self.a!r} {self.op.__name__} {self.b!r})"
|
|
306
412
|
|
|
@@ -333,6 +439,12 @@ class ObjectMethod(Expression):
|
|
|
333
439
|
return ObjectMethod(obj, self.method, *args)
|
|
334
440
|
else:
|
|
335
441
|
return getattr(obj, self.method)(*args)
|
|
442
|
+
|
|
443
|
+
def __repr__(self):
|
|
444
|
+
if self.method == '__call__':
|
|
445
|
+
return f"{self.obj!r}({', '.join(map(repr, self.args))})"
|
|
446
|
+
else:
|
|
447
|
+
return f"{self.obj!r}.{self.method}({', '.join(map(repr, self.args))})"
|
|
336
448
|
|
|
337
449
|
|
|
338
450
|
class Symbol(Expression):
|
|
@@ -355,6 +467,6 @@ class Symbol(Expression):
|
|
|
355
467
|
return 1
|
|
356
468
|
else:
|
|
357
469
|
return 0
|
|
358
|
-
|
|
470
|
+
|
|
359
471
|
def __repr__(self) -> str:
|
|
360
472
|
return self.name
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import ast
|
|
2
|
+
import itertools
|
|
2
3
|
|
|
3
4
|
import numpy as np
|
|
4
5
|
|
|
@@ -73,6 +74,19 @@ class Optimizer():
|
|
|
73
74
|
**self.kwds)
|
|
74
75
|
|
|
75
76
|
|
|
77
|
+
class Action():
|
|
78
|
+
|
|
79
|
+
__slots__ = ('name', 'args', 'kwds')
|
|
80
|
+
|
|
81
|
+
def __init__(self, name, *args, **kwds):
|
|
82
|
+
self.name = name
|
|
83
|
+
self.args = args
|
|
84
|
+
self.kwds = kwds
|
|
85
|
+
|
|
86
|
+
def __repr__(self):
|
|
87
|
+
return f"Action({self.name!r}, {self.args}, {self.kwds})"
|
|
88
|
+
|
|
89
|
+
|
|
76
90
|
class Scan():
|
|
77
91
|
|
|
78
92
|
def __new__(cls, *args, mixin=None, **kwds):
|
|
@@ -99,6 +113,8 @@ class Scan():
|
|
|
99
113
|
self.filter = None
|
|
100
114
|
self.scan_info = {'loops': {}}
|
|
101
115
|
self._tmp = {}
|
|
116
|
+
self.actions = {}
|
|
117
|
+
self.iteration = 0
|
|
102
118
|
|
|
103
119
|
@property
|
|
104
120
|
def name(self):
|
|
@@ -114,12 +130,12 @@ class Scan():
|
|
|
114
130
|
return default
|
|
115
131
|
|
|
116
132
|
def set(self, key, value):
|
|
117
|
-
|
|
133
|
+
self.add_action(Action('set', key, value))
|
|
118
134
|
|
|
119
135
|
def _mapping(self, key, value):
|
|
120
136
|
tmpkey = f"__tmp_{self._mapping_i}__"
|
|
121
137
|
self._mapping_i += 1
|
|
122
|
-
self
|
|
138
|
+
self.__setitem(tmpkey, value)
|
|
123
139
|
self.mapping[key] = tmpkey
|
|
124
140
|
|
|
125
141
|
def __setitem__(self, key, value):
|
|
@@ -219,17 +235,27 @@ class Scan():
|
|
|
219
235
|
self.assemble()
|
|
220
236
|
for step in self.scan():
|
|
221
237
|
for k, v in self.mapping.items():
|
|
222
|
-
|
|
238
|
+
if v in set(
|
|
239
|
+
itertools.chain.from_iterable(
|
|
240
|
+
step.vars[step.unchanged:])
|
|
241
|
+
) or step.iteration == 0:
|
|
242
|
+
self.set(k, step.kwds[v])
|
|
223
243
|
self.process(step)
|
|
224
244
|
|
|
225
245
|
def process(self, step):
|
|
226
|
-
|
|
246
|
+
for k, v in step.kwds.items():
|
|
247
|
+
if not k.startswith('__tmp_') and not k.startswith('__'):
|
|
248
|
+
self.add_action(Action('write', k, v))
|
|
227
249
|
|
|
228
250
|
def scan(self):
|
|
229
251
|
for step in scan_iters(**self.scan_info):
|
|
230
252
|
for k, v in self.mapping.items():
|
|
231
253
|
step.kwds[k] = step.kwds[v]
|
|
232
254
|
yield step
|
|
255
|
+
self.iteration += 1
|
|
256
|
+
|
|
257
|
+
def add_action(self, action: Action):
|
|
258
|
+
self.actions.setdefault(self.iteration, []).append(action)
|
|
233
259
|
|
|
234
260
|
def run(self, dry_run=False):
|
|
235
261
|
pass
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.0.1"
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import matplotlib.pyplot as plt
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
from ._autoplot import autoplot
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def plotLine(c0, c1, ax, **kwargs):
|
|
8
|
+
t = np.linspace(0, 1, 11)
|
|
9
|
+
c = (c1 - c0) * t + c0
|
|
10
|
+
ax.plot(c.real, c.imag, **kwargs)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def plotCircle(c0, r, ax, **kwargs):
|
|
14
|
+
t = np.linspace(0, 1, 1001) * 2 * np.pi
|
|
15
|
+
s = c0 + r * np.exp(1j * t)
|
|
16
|
+
ax.plot(s.real, s.imag, **kwargs)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def plotEllipse(c0, a, b, phi, ax, **kwargs):
|
|
20
|
+
t = np.linspace(0, 1, 1001) * 2 * np.pi
|
|
21
|
+
c = np.exp(1j * t)
|
|
22
|
+
s = c0 + (c.real * a + 1j * c.imag * b) * np.exp(1j * phi)
|
|
23
|
+
ax.plot(s.real, s.imag, **kwargs)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def plotDistribution(s0,
|
|
27
|
+
s1,
|
|
28
|
+
fig=None,
|
|
29
|
+
axes=None,
|
|
30
|
+
info=None,
|
|
31
|
+
hotThresh=10000,
|
|
32
|
+
logy=False):
|
|
33
|
+
from waveforms.math.fit import get_threshold_info, mult_gaussian_pdf
|
|
34
|
+
|
|
35
|
+
if info is None:
|
|
36
|
+
info = get_threshold_info(s0, s1)
|
|
37
|
+
else:
|
|
38
|
+
info = get_threshold_info(s0, s1, info['threshold'], info['phi'])
|
|
39
|
+
thr, phi = info['threshold'], info['phi']
|
|
40
|
+
# visibility, p0, p1 = info['visibility']
|
|
41
|
+
# print(
|
|
42
|
+
# f"thr={thr:.6f}, phi={phi:.6f}, visibility={visibility:.3f}, {p0}, {1-p1}"
|
|
43
|
+
# )
|
|
44
|
+
|
|
45
|
+
if axes is not None:
|
|
46
|
+
ax1, ax2 = axes
|
|
47
|
+
else:
|
|
48
|
+
if fig is None:
|
|
49
|
+
fig = plt.figure()
|
|
50
|
+
ax1 = fig.add_subplot(121)
|
|
51
|
+
ax2 = fig.add_subplot(122)
|
|
52
|
+
|
|
53
|
+
if (len(s0) + len(s1)) < hotThresh:
|
|
54
|
+
ax1.plot(np.real(s0), np.imag(s0), '.', alpha=0.2)
|
|
55
|
+
ax1.plot(np.real(s1), np.imag(s1), '.', alpha=0.2)
|
|
56
|
+
else:
|
|
57
|
+
_, *bins = np.histogram2d(np.real(np.hstack([s0, s1])),
|
|
58
|
+
np.imag(np.hstack([s0, s1])),
|
|
59
|
+
bins=50)
|
|
60
|
+
|
|
61
|
+
H0, *_ = np.histogram2d(np.real(s0),
|
|
62
|
+
np.imag(s0),
|
|
63
|
+
bins=bins,
|
|
64
|
+
density=True)
|
|
65
|
+
H1, *_ = np.histogram2d(np.real(s1),
|
|
66
|
+
np.imag(s1),
|
|
67
|
+
bins=bins,
|
|
68
|
+
density=True)
|
|
69
|
+
vlim = max(np.max(np.abs(H0)), np.max(np.abs(H1)))
|
|
70
|
+
|
|
71
|
+
ax1.imshow(H1.T - H0.T,
|
|
72
|
+
alpha=(np.fmax(H0.T, H1.T) / vlim).clip(0, 1),
|
|
73
|
+
interpolation='nearest',
|
|
74
|
+
origin='lower',
|
|
75
|
+
cmap='coolwarm',
|
|
76
|
+
vmin=-vlim,
|
|
77
|
+
vmax=vlim,
|
|
78
|
+
extent=(bins[0][0], bins[0][-1], bins[1][0], bins[1][-1]))
|
|
79
|
+
|
|
80
|
+
ax1.axis('equal')
|
|
81
|
+
ax1.set_xticks([])
|
|
82
|
+
ax1.set_yticks([])
|
|
83
|
+
for s in ax1.spines.values():
|
|
84
|
+
s.set_visible(False)
|
|
85
|
+
|
|
86
|
+
# c0, c1 = info['center']
|
|
87
|
+
# a0, b0, a1, b1 = info['std']
|
|
88
|
+
params = info['params']
|
|
89
|
+
r0, i0, r1, i1 = params[0][0], params[1][0], params[0][1], params[1][1]
|
|
90
|
+
a0, b0, a1, b1 = params[0][2], params[1][2], params[0][3], params[1][3]
|
|
91
|
+
c0 = (r0 + 1j * i0) * np.exp(1j * phi)
|
|
92
|
+
c1 = (r1 + 1j * i1) * np.exp(1j * phi)
|
|
93
|
+
phi0 = phi + params[0][6]
|
|
94
|
+
phi1 = phi + params[1][6]
|
|
95
|
+
plotEllipse(c0, 2 * a0, 2 * b0, phi0, ax1)
|
|
96
|
+
plotEllipse(c1, 2 * a1, 2 * b1, phi1, ax1)
|
|
97
|
+
|
|
98
|
+
im0, im1 = info['idle']
|
|
99
|
+
lim = min(im0.min(), im1.min()), max(im0.max(), im1.max())
|
|
100
|
+
t = (np.linspace(lim[0], lim[1], 3) + 1j * thr) * np.exp(-1j * phi)
|
|
101
|
+
ax1.plot(t.imag, t.real, 'k--')
|
|
102
|
+
|
|
103
|
+
ax1.plot(np.real(c0), np.imag(c0), 'o', color='C3')
|
|
104
|
+
ax1.plot(np.real(c1), np.imag(c1), 'o', color='C4')
|
|
105
|
+
|
|
106
|
+
re0, re1 = info['signal']
|
|
107
|
+
x, a, b, c = info['cdf']
|
|
108
|
+
|
|
109
|
+
xrange = (min(re0.min(), re1.min()), max(re0.max(), re1.max()))
|
|
110
|
+
|
|
111
|
+
n0, bins0, *_ = ax2.hist(re0, bins=80, range=xrange, alpha=0.5)
|
|
112
|
+
n1, bins1, *_ = ax2.hist(re1, bins=80, range=xrange, alpha=0.5)
|
|
113
|
+
|
|
114
|
+
x_range = np.linspace(x.min(), x.max(), 1001)
|
|
115
|
+
*_, cov0, cov1 = info['std']
|
|
116
|
+
ax2.plot(
|
|
117
|
+
x_range,
|
|
118
|
+
np.sum(n0) * (bins0[1] - bins0[0]) *
|
|
119
|
+
mult_gaussian_pdf(x_range, [r0, r1], [
|
|
120
|
+
np.sqrt(cov0[0, 0]), np.sqrt(cov1[0, 0])
|
|
121
|
+
], [params[0][4], 1 - params[0][4]]))
|
|
122
|
+
ax2.plot(
|
|
123
|
+
x_range,
|
|
124
|
+
np.sum(n1) * (bins1[1] - bins1[0]) *
|
|
125
|
+
mult_gaussian_pdf(x_range, [r0, r1], [
|
|
126
|
+
np.sqrt(cov0[0, 0]), np.sqrt(cov1[0, 0])
|
|
127
|
+
], [params[0][5], 1 - params[0][5]]))
|
|
128
|
+
ax2.set_ylabel('Count')
|
|
129
|
+
ax2.set_xlabel('Projection Axes')
|
|
130
|
+
if logy:
|
|
131
|
+
ax2.set_yscale('log')
|
|
132
|
+
ax2.set_ylim(0.1, max(np.sum(n0), np.sum(n1)))
|
|
133
|
+
|
|
134
|
+
ax3 = ax2.twinx()
|
|
135
|
+
ax3.plot(x, a, '--', lw=1, color='C0')
|
|
136
|
+
ax3.plot(x, b, '--', lw=1, color='C1')
|
|
137
|
+
ax3.plot(x, c, 'k--', alpha=0.5, lw=1)
|
|
138
|
+
ax3.set_ylim(0, 1.1)
|
|
139
|
+
ax3.vlines(thr, 0, 1.1, 'k', alpha=0.5)
|
|
140
|
+
ax3.set_ylabel('Integral Probability')
|
|
141
|
+
|
|
142
|
+
return info
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
ALLXYSeq = [('I', 'I'), ('X', 'X'), ('Y', 'Y'), ('X', 'Y'), ('Y', 'X'),
|
|
146
|
+
('X/2', 'I'), ('Y/2', 'I'), ('X/2', 'Y/2'), ('Y/2', 'X/2'),
|
|
147
|
+
('X/2', 'Y'), ('Y/2', 'X'), ('X', 'Y/2'), ('Y', 'X/2'),
|
|
148
|
+
('X/2', 'X'), ('X', 'X/2'), ('Y/2', 'Y'), ('Y', 'Y/2'), ('X', 'I'),
|
|
149
|
+
('Y', 'I'), ('X/2', 'X/2'), ('Y/2', 'Y/2')]
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def plotALLXY(data, ax=None):
|
|
153
|
+
assert len(data) % len(ALLXYSeq) == 0
|
|
154
|
+
|
|
155
|
+
if ax is None:
|
|
156
|
+
ax = plt.gca()
|
|
157
|
+
|
|
158
|
+
ax.plot(np.array(data), 'o-')
|
|
159
|
+
repeat = len(data) // len(ALLXYSeq)
|
|
160
|
+
ax.set_xticks(np.arange(len(ALLXYSeq)) * repeat + 0.5 * (repeat - 1))
|
|
161
|
+
ax.set_xticklabels([','.join(seq) for seq in ALLXYSeq], rotation=60)
|
|
162
|
+
ax.grid(which='major')
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def plot_mat(rho, title='$\\chi$', cmap='coolwarm'):
|
|
166
|
+
lim = np.abs(rho).max()
|
|
167
|
+
N = rho.shape[0]
|
|
168
|
+
|
|
169
|
+
fig = plt.figure(figsize=(6, 4))
|
|
170
|
+
fig.suptitle(title)
|
|
171
|
+
|
|
172
|
+
ax1 = plt.subplot(121)
|
|
173
|
+
cax1 = ax1.imshow(rho.real, vmin=-lim, vmax=lim, cmap=cmap)
|
|
174
|
+
ax1.set_title('Re')
|
|
175
|
+
ax1.set_xticks(np.arange(N))
|
|
176
|
+
ax1.set_yticks(np.arange(N))
|
|
177
|
+
|
|
178
|
+
ax2 = plt.subplot(122)
|
|
179
|
+
cax2 = ax2.imshow(rho.imag, vmin=-lim, vmax=lim, cmap=cmap)
|
|
180
|
+
ax2.set_title('Im')
|
|
181
|
+
ax2.set_xticks(np.arange(N))
|
|
182
|
+
ax2.set_yticks(np.arange(N))
|
|
183
|
+
|
|
184
|
+
plt.subplots_adjust(bottom=0.2, right=0.9, top=0.95)
|
|
185
|
+
|
|
186
|
+
cbar_ax = fig.add_axes([0.15, 0.15, 0.7, 0.05])
|
|
187
|
+
cb = fig.colorbar(cax1, cax=cbar_ax, orientation='horizontal')
|
|
188
|
+
plt.show()
|