QuLab 2.0.1__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.
Files changed (82) hide show
  1. QuLab-2.0.1.dist-info/LICENSE +21 -0
  2. QuLab-2.0.1.dist-info/METADATA +95 -0
  3. QuLab-2.0.1.dist-info/RECORD +82 -0
  4. QuLab-2.0.1.dist-info/WHEEL +5 -0
  5. QuLab-2.0.1.dist-info/entry_points.txt +2 -0
  6. QuLab-2.0.1.dist-info/top_level.txt +1 -0
  7. qulab/__init__.py +1 -0
  8. qulab/__main__.py +24 -0
  9. qulab/fun.cp310-win_amd64.pyd +0 -0
  10. qulab/monitor/__init__.py +1 -0
  11. qulab/monitor/__main__.py +8 -0
  12. qulab/monitor/config.py +41 -0
  13. qulab/monitor/dataset.py +77 -0
  14. qulab/monitor/event_queue.py +54 -0
  15. qulab/monitor/mainwindow.py +234 -0
  16. qulab/monitor/monitor.py +93 -0
  17. qulab/monitor/ploter.py +123 -0
  18. qulab/monitor/qt_compat.py +16 -0
  19. qulab/monitor/toolbar.py +265 -0
  20. qulab/scan/__init__.py +4 -0
  21. qulab/scan/base.py +548 -0
  22. qulab/scan/dataset.py +0 -0
  23. qulab/scan/expression.py +472 -0
  24. qulab/scan/optimize.py +0 -0
  25. qulab/scan/scanner.py +270 -0
  26. qulab/scan/transforms.py +16 -0
  27. qulab/scan/utils.py +37 -0
  28. qulab/storage/__init__.py +0 -0
  29. qulab/storage/__main__.py +51 -0
  30. qulab/storage/backend/__init__.py +0 -0
  31. qulab/storage/backend/redis.py +204 -0
  32. qulab/storage/base_dataset.py +352 -0
  33. qulab/storage/chunk.py +60 -0
  34. qulab/storage/dataset.py +127 -0
  35. qulab/storage/file.py +273 -0
  36. qulab/storage/models/__init__.py +22 -0
  37. qulab/storage/models/base.py +4 -0
  38. qulab/storage/models/config.py +28 -0
  39. qulab/storage/models/file.py +89 -0
  40. qulab/storage/models/ipy.py +58 -0
  41. qulab/storage/models/models.py +88 -0
  42. qulab/storage/models/record.py +161 -0
  43. qulab/storage/models/report.py +22 -0
  44. qulab/storage/models/tag.py +93 -0
  45. qulab/storage/storage.py +95 -0
  46. qulab/sys/__init__.py +0 -0
  47. qulab/sys/chat.py +688 -0
  48. qulab/sys/device/__init__.py +3 -0
  49. qulab/sys/device/basedevice.py +221 -0
  50. qulab/sys/device/loader.py +86 -0
  51. qulab/sys/device/utils.py +46 -0
  52. qulab/sys/drivers/FakeInstrument.py +52 -0
  53. qulab/sys/drivers/__init__.py +0 -0
  54. qulab/sys/ipy_events.py +125 -0
  55. qulab/sys/net/__init__.py +0 -0
  56. qulab/sys/net/bencoder.py +205 -0
  57. qulab/sys/net/cli.py +169 -0
  58. qulab/sys/net/dhcp.py +543 -0
  59. qulab/sys/net/dhcpd.py +176 -0
  60. qulab/sys/net/kad.py +1142 -0
  61. qulab/sys/net/kcp.py +192 -0
  62. qulab/sys/net/nginx.py +192 -0
  63. qulab/sys/progress.py +190 -0
  64. qulab/sys/rpc/__init__.py +0 -0
  65. qulab/sys/rpc/client.py +0 -0
  66. qulab/sys/rpc/exceptions.py +96 -0
  67. qulab/sys/rpc/msgpack.py +1052 -0
  68. qulab/sys/rpc/msgpack.pyi +41 -0
  69. qulab/sys/rpc/rpc.py +412 -0
  70. qulab/sys/rpc/serialize.py +139 -0
  71. qulab/sys/rpc/server.py +29 -0
  72. qulab/sys/rpc/socket.py +29 -0
  73. qulab/sys/rpc/utils.py +25 -0
  74. qulab/sys/rpc/worker.py +0 -0
  75. qulab/version.py +1 -0
  76. qulab/visualization/__init__.py +188 -0
  77. qulab/visualization/__main__.py +71 -0
  78. qulab/visualization/_autoplot.py +457 -0
  79. qulab/visualization/plot_layout.py +408 -0
  80. qulab/visualization/plot_seq.py +90 -0
  81. qulab/visualization/qdat.py +152 -0
  82. qulab/visualization/widgets.py +86 -0
qulab/scan/scanner.py ADDED
@@ -0,0 +1,270 @@
1
+ import ast
2
+ import itertools
3
+
4
+ import numpy as np
5
+
6
+ from .base import scan_iters
7
+ from .expression import Env, Expression, Symbol, _empty
8
+
9
+
10
+ def is_valid_identifier(s: str) -> bool:
11
+ try:
12
+ ast.parse(f"f({s}=0)")
13
+ return True
14
+ except SyntaxError:
15
+ return False
16
+
17
+
18
+ class Atom():
19
+ __slots__ = ('value', )
20
+
21
+ def __init__(self, value):
22
+ self.value = value
23
+
24
+
25
+ class MappedSymbol(Symbol):
26
+ pass
27
+
28
+
29
+ class OptimizeSpace():
30
+
31
+ def __init__(self, optimizer, space):
32
+ self.optimizer = optimizer
33
+ self.space = space
34
+ self.name = None
35
+
36
+
37
+ class Optimizer():
38
+
39
+ def __init__(self, cls, *args, **kwds):
40
+ self.cls = cls
41
+ self.args = args
42
+ self.kwds = kwds
43
+ self.dimensions = {}
44
+ self.function = None
45
+
46
+ def Categorical(self, *args, **kwds):
47
+ from skopt.space import Categorical
48
+ return OptimizeSpace(self, Categorical(*args, **kwds))
49
+
50
+ def Integer(self, *args, **kwds):
51
+ from skopt.space import Integer
52
+ return OptimizeSpace(self, Integer(*args, **kwds))
53
+
54
+ def Real(self, *args, **kwds):
55
+ from skopt.space import Real
56
+ return OptimizeSpace(self, Real(*args, **kwds))
57
+
58
+ @property
59
+ def target(self):
60
+ return None
61
+
62
+ @target.setter
63
+ def target(self, fun):
64
+ if isinstance(fun, Symbol):
65
+ self.function = fun.name
66
+ elif isinstance(fun, Expression):
67
+ self.function = fun
68
+ else:
69
+ raise ValueError("Invalid function")
70
+
71
+ def create_optimizer(self):
72
+ dimensions = list(self.dimensions.values())
73
+ return tuple(self.dimensions.keys()), self.cls(dimensions, *self.args,
74
+ **self.kwds)
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
+
90
+ class Scan():
91
+
92
+ def __new__(cls, *args, mixin=None, **kwds):
93
+ if mixin is None:
94
+ return super().__new__(cls)
95
+ for k in dir(mixin):
96
+ if not hasattr(cls, k):
97
+ try:
98
+ setattr(cls, k, getattr(mixin, k))
99
+ except:
100
+ pass
101
+ return super().__new__(cls)
102
+
103
+ def __init__(self, name, *args, env=None, mixin=None, **kwds):
104
+ super().__init__(*args, **kwds)
105
+ self._name = name.replace(' ', '_')
106
+ self.env = Env() if env is None else env
107
+ self.functions = {}
108
+ self.consts = {}
109
+ self.loops = {}
110
+ self.mapping = {}
111
+ self.optimizers = {}
112
+ self._mapping_i = 0
113
+ self.filter = None
114
+ self.scan_info = {'loops': {}}
115
+ self._tmp = {}
116
+ self.actions = {}
117
+ self.iteration = 0
118
+
119
+ @property
120
+ def name(self):
121
+ return f"Scan.{self._name}"
122
+
123
+ def get(self, key, default=_empty):
124
+ if key in self.consts:
125
+ return self.consts[key]
126
+ if key in self.functions:
127
+ return self.functions[key]
128
+ if default is _empty:
129
+ raise KeyError(f"Key {key} not found")
130
+ return default
131
+
132
+ def set(self, key, value):
133
+ self.add_action(Action('set', key, value))
134
+
135
+ def _mapping(self, key, value):
136
+ tmpkey = f"__tmp_{self._mapping_i}__"
137
+ self._mapping_i += 1
138
+ self.__setitem(tmpkey, value)
139
+ self.mapping[key] = tmpkey
140
+
141
+ def __setitem__(self, key, value):
142
+ if is_valid_identifier(key):
143
+ if isinstance(value, Atom):
144
+ self.consts[key] = value.value
145
+ return
146
+ elif isinstance(value, (str, int, float, complex, tuple)):
147
+ self.consts[key] = value
148
+ return
149
+
150
+ if isinstance(value, Expression):
151
+ env = Env()
152
+ env.consts = self.consts
153
+ value = value.value(env)
154
+ if not isinstance(value, Expression):
155
+ self.__setitem__(key, value)
156
+ return
157
+
158
+ self._tmp[key] = value
159
+
160
+ def __setitem(self, key, value):
161
+ if not is_valid_identifier(key):
162
+ self._mapping(key, value)
163
+ return
164
+ if isinstance(value, Expression) or callable(value):
165
+ self.functions[key] = value
166
+ elif isinstance(value, OptimizeSpace):
167
+ self.optimizers[key] = value.optimizer
168
+ value.name = key
169
+ value.optimizer.dimensions[key] = value.space
170
+ self.loops[key] = value.optimizer
171
+ elif isinstance(value, (np.ndarray, list, range)):
172
+ self.loops[key] = value
173
+ elif isinstance(value, Atom):
174
+ self.consts[key] = value.value
175
+ else:
176
+ self.consts[key] = value
177
+
178
+ def __getitem__(self, key):
179
+ if key in self.consts:
180
+ return self.consts[key]
181
+ if is_valid_identifier(key):
182
+ return Symbol(key)
183
+ else:
184
+ if key in self.mapping:
185
+ return Symbol(self.mapping[key])
186
+ return MappedSymbol(key)
187
+
188
+ def assemble(self):
189
+ for key, value in self._tmp.items():
190
+ self.__setitem(key, value)
191
+
192
+ variables = {}
193
+ loops = {}
194
+
195
+ for k, v in self.functions.items():
196
+ if isinstance(v, MappedSymbol):
197
+ variables[k] = eval(
198
+ f"lambda {self.mapping[k]}: {self.mapping[k]}")
199
+ elif isinstance(v, Expression):
200
+ args = v.symbols()
201
+ for x in args:
202
+ if x in self.mapping:
203
+ args.remove(x)
204
+ v = v.value({x: Symbol(self.mapping[x])})
205
+ x = self.mapping[x]
206
+ if x in self.consts:
207
+ args.remove(x)
208
+ v = v.value({x: self.consts[x]})
209
+ if args:
210
+ variables[k] = eval(
211
+ f"lambda {','.join(args)}: expr.value({{{','.join([f'{x!r}:{x}' for x in args])}}})",
212
+ {'expr': v})
213
+ else:
214
+ self.consts[k] = v
215
+ else:
216
+ variables[k] = v
217
+
218
+ for key, value in self.loops.items():
219
+ if isinstance(value, Optimizer):
220
+ #variables[key] = value.create_optimizer()
221
+ pass
222
+ else:
223
+ loops[key] = value
224
+
225
+ self.scan_info = {
226
+ 'loops': loops,
227
+ 'functions': variables,
228
+ 'constants': self.consts
229
+ }
230
+
231
+ if self.filter is not None:
232
+ self.scan_info['filter'] = self.filter
233
+
234
+ def main(self):
235
+ self.assemble()
236
+ for step in self.scan():
237
+ for k, v in self.mapping.items():
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])
243
+ self.process(step)
244
+
245
+ def process(self, step):
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))
249
+
250
+ def scan(self):
251
+ for step in scan_iters(**self.scan_info):
252
+ for k, v in self.mapping.items():
253
+ step.kwds[k] = step.kwds[v]
254
+ yield step
255
+ self.iteration += 1
256
+
257
+ def add_action(self, action: Action):
258
+ self.actions.setdefault(self.iteration, []).append(action)
259
+
260
+ def run(self, dry_run=False):
261
+ pass
262
+
263
+ def plot(self,
264
+ result=None,
265
+ fig=None,
266
+ axis=None,
267
+ data='population',
268
+ T=False,
269
+ **kwds):
270
+ pass
@@ -0,0 +1,16 @@
1
+ class Aggregation():
2
+
3
+ def __init__(self):
4
+ pass
5
+
6
+ def __call__(self, data):
7
+ raise NotImplementedError()
8
+
9
+
10
+ class Transform():
11
+
12
+ def __init__(self):
13
+ pass
14
+
15
+ def __call__(self, data):
16
+ raise NotImplementedError()
qulab/scan/utils.py ADDED
@@ -0,0 +1,37 @@
1
+ import inspect
2
+ from concurrent.futures import Future
3
+
4
+
5
+ def call_func_with_kwds(func, args, kwds, log=None):
6
+ funcname = getattr(func, '__name__', repr(func))
7
+ sig = inspect.signature(func)
8
+ for p in sig.parameters.values():
9
+ if p.kind == p.VAR_KEYWORD:
10
+ return func(*args, **kwds)
11
+ kw = {
12
+ k: v
13
+ for k, v in kwds.items()
14
+ if k in list(sig.parameters.keys())[len(args):]
15
+ }
16
+ try:
17
+ args = [
18
+ arg.result() if isinstance(arg, Future) else arg for arg in args
19
+ ]
20
+ kw = {
21
+ k: v.result() if isinstance(v, Future) else v
22
+ for k, v in kw.items()
23
+ }
24
+ return func(*args, **kw)
25
+ except:
26
+ if log:
27
+ log.exception(f'Call {funcname} with {args} and {kw}')
28
+ raise
29
+ finally:
30
+ if log:
31
+ log.debug(f'Call {funcname} with {args} and {kw}')
32
+
33
+
34
+ def try_to_call(x, args, kwds, log=None):
35
+ if callable(x):
36
+ return call_func_with_kwds(x, args, kwds, log)
37
+ return x
File without changes
@@ -0,0 +1,51 @@
1
+ import click
2
+
3
+
4
+ @click.command()
5
+ @click.option('--executor', default='', help='Executor address to use.')
6
+ @click.option('--port', default=8080, help='Port to run the server on.')
7
+ @click.option('--host', default='127.0.0.1', help='Host to run the server on.')
8
+ @click.option('--db-url', default=None, help='Database URL to use.')
9
+ @click.option('--data-path',
10
+ default='waveforms/data',
11
+ help='Path to the data directory.')
12
+ @click.option('--debug', is_flag=True, help='Run in debug mode.')
13
+ @click.option('--workers',
14
+ default=1,
15
+ help='Number of workers to run the server with.')
16
+ @click.option('--timeout', default=60, help='Timeout for requests.')
17
+ @click.option('--log-level',
18
+ default='INFO',
19
+ help='Log level to run the server with.')
20
+ @click.option('--log-file',
21
+ default='/var/log/waveforms/server.log',
22
+ help='Log file to run the server with.')
23
+ @click.option('--log-format',
24
+ default='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
25
+ help='Log format to run the server with.')
26
+ def main(executor, port, host, db_url, data_path, debug, workers, timeout,
27
+ log_level, log_file, log_format):
28
+ """
29
+ Main entry point for the server.
30
+ """
31
+ from waveforms.server import create_app
32
+
33
+ app = create_app(
34
+ executor=executor,
35
+ port=port,
36
+ host=host,
37
+ db_url=db_url,
38
+ data_path=data_path,
39
+ debug=debug,
40
+ workers=workers,
41
+ timeout=timeout,
42
+ log_level=log_level,
43
+ log_file=log_file,
44
+ log_format=log_format,
45
+ )
46
+ app.run()
47
+
48
+
49
+ if __name__ == '__main__':
50
+ main()
51
+
File without changes
@@ -0,0 +1,204 @@
1
+ import dill
2
+ import numpy as np
3
+ import redis
4
+
5
+
6
+ def try_dumps(value):
7
+ try:
8
+ value_b = dill.dumps(value)
9
+ except:
10
+ value_b = dill.dumps(str(value))
11
+ finally:
12
+ return value_b
13
+
14
+
15
+ class redisClient(object):
16
+
17
+ def __init__(self,
18
+ name,
19
+ server=None,
20
+ addr='redis://localhost:6379/0',
21
+ expire_time=172800):
22
+ self._r = redis.Redis.from_url(addr) if server is None else server
23
+ self.name = name
24
+ self.expire_time = int(expire_time) # 默认数据两天过期,单位秒
25
+
26
+ def delete(self):
27
+ self._r.delete(self.name)
28
+
29
+
30
+ class redisString(redisClient):
31
+ '''Redis String client'''
32
+
33
+ def set(self, value):
34
+ if value is not None:
35
+ value_b = try_dumps(value)
36
+ self._r.set(self.name, value_b, ex=self.expire_time)
37
+
38
+ def get(self):
39
+ v_b = self._r.get(self.name)
40
+ value = dill.loads(v_b) if v_b is not None else None
41
+ return value
42
+
43
+ @property
44
+ def data(self):
45
+ return self.get()
46
+
47
+
48
+ class redisList(redisClient):
49
+ '''Redis List client'''
50
+
51
+ def add(self, *arg):
52
+ arg_b = [dill.dumps(i) for i in arg]
53
+ self._r.rpush(self.name, *arg_b)
54
+ self._r.expire(self.name, self.expire_time)
55
+
56
+ def read(self, start=0, end=-1):
57
+ data_b = self._r.lrange(self.name, start, end)
58
+ data = [dill.loads(i) for i in data_b]
59
+ return data
60
+
61
+ @property
62
+ def size(self):
63
+ return self._r.llen(self.name)
64
+
65
+ @property
66
+ def data(self):
67
+ return self.read()
68
+
69
+
70
+ class redisSet(redisClient):
71
+ '''Redis Set client'''
72
+
73
+ def add(self, *arg):
74
+ arg_b = {dill.dumps(i) for i in arg}
75
+ self._r.sadd(self.name, *arg_b)
76
+ self._r.expire(self.name, self.expire_time)
77
+
78
+ def read(self):
79
+ data_b = self._r.smembers(self.name)
80
+ data = {dill.loads(i) for i in data_b}
81
+ return data
82
+
83
+ @property
84
+ def size(self):
85
+ return self._r.scard(self.name)
86
+
87
+ @property
88
+ def data(self):
89
+ return self.read()
90
+
91
+
92
+ class redisZSet(redisClient):
93
+ '''有序集合'''
94
+
95
+ def __init__(self,
96
+ name,
97
+ server=None,
98
+ addr='redis://localhost:6379/0',
99
+ expire_time=172800):
100
+ super().__init__(name, server, addr, expire_time)
101
+ self.__score = 0
102
+
103
+ def delete(self):
104
+ super().delete()
105
+ self.__score = 0
106
+
107
+ def add(self, *elements):
108
+ mapping = {}
109
+ for ele in elements:
110
+ ele_b = dill.dumps(ele)
111
+ self.__score += 1
112
+ mapping.update({ele_b: self.__score})
113
+ self._r.zadd(self.name, mapping, nx=True) # 只添加新元素
114
+ self._r.expire(self.name, self.expire_time)
115
+
116
+ def read(self, start=0, end=-1):
117
+ data_b = self._r.zrange(self.name, start, end, withscores=False)
118
+ data = [dill.loads(i) for i in data_b]
119
+ return data
120
+
121
+ @property
122
+ def size(self):
123
+ return self._r.zcard(self.name)
124
+
125
+ @property
126
+ def data(self):
127
+ return self.read()
128
+
129
+
130
+ class redisHash(redisClient):
131
+ '''Redis Hash client'''
132
+
133
+ def add(self, **kw):
134
+ kw_b = {k: try_dumps(v) for k, v in kw.items()}
135
+ self._r.hmset(self.name, kw_b)
136
+ self._r.expire(self.name, self.expire_time)
137
+
138
+ def read(self):
139
+ data_b = self._r.hgetall(self.name)
140
+ data = {k_b.decode(): dill.loads(v_b) for k_b, v_b in data_b.items()}
141
+ return data
142
+
143
+ def get(self, key):
144
+ '''读取Hash中的一个key'''
145
+ v_b = self._r.hget(self.name, key)
146
+ value = dill.loads(v_b) if v_b is not None else None
147
+ return value
148
+
149
+ @property
150
+ def size(self):
151
+ return self._r.hlen(self.name)
152
+
153
+ @property
154
+ def data(self):
155
+ return self.read()
156
+
157
+
158
+ class redisArray(redisClient):
159
+ '''Redis np.array client'''
160
+
161
+ def __init__(self,
162
+ name,
163
+ server=None,
164
+ addr='redis://localhost:6379/0',
165
+ expire_time=172800,
166
+ dtype='complex128'):
167
+ super().__init__(name, server, addr, expire_time)
168
+ _r_dtype = self._r.get(f'{name}.dtype')
169
+ if _r_dtype is None:
170
+ self._r.set(f'{name}.dtype', dtype, ex=self.expire_time)
171
+ self.dtype = dtype
172
+ else:
173
+ self.dtype = _r_dtype
174
+
175
+ def delete(self):
176
+ self._r.delete(self.name)
177
+ self._r.delete(f'{self.name}.dtype')
178
+
179
+ def add(self, *args):
180
+ for arg in args:
181
+ buf = np.asarray(arg).astype(self.dtype).tobytes()
182
+ # self._r.append(self.name, buf)
183
+ self._r.rpush(self.name, buf)
184
+ self._r.expire(self.name, self.expire_time)
185
+
186
+ def read(self):
187
+ # buf = self._r.get(self.name)
188
+ buf_list = self._r.lrange(self.name, 0, -1)
189
+ buf = b''.join(buf_list)
190
+ data = np.frombuffer(buf,
191
+ dtype=self.dtype) if buf is not None else None
192
+ return data
193
+
194
+ @property
195
+ def size(self):
196
+ array = self.data
197
+ if array is None:
198
+ return 0
199
+ else:
200
+ return array.size
201
+
202
+ @property
203
+ def data(self):
204
+ return self.read()