QuLab 2.2.5__cp310-cp310-win_amd64.whl → 2.2.7__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.
- {QuLab-2.2.5.dist-info → QuLab-2.2.7.dist-info}/METADATA +1 -1
- {QuLab-2.2.5.dist-info → QuLab-2.2.7.dist-info}/RECORD +13 -13
- qulab/fun.cp310-win_amd64.pyd +0 -0
- qulab/scan/query.py +14 -6
- qulab/scan/record.py +52 -53
- qulab/scan/scan.py +60 -12
- qulab/scan/server.py +3 -2
- qulab/sys/rpc/zmq_socket.py +6 -1
- qulab/version.py +1 -1
- {QuLab-2.2.5.dist-info → QuLab-2.2.7.dist-info}/LICENSE +0 -0
- {QuLab-2.2.5.dist-info → QuLab-2.2.7.dist-info}/WHEEL +0 -0
- {QuLab-2.2.5.dist-info → QuLab-2.2.7.dist-info}/entry_points.txt +0 -0
- {QuLab-2.2.5.dist-info → QuLab-2.2.7.dist-info}/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
qulab/__init__.py,sha256=vkFybY8YSsQilYdThPRD83-btPAR41sy_WCXiM-6mME,141
|
|
2
2
|
qulab/__main__.py,sha256=V7iokU7awstgjCeiF_hoOdFyrqJwC_4QetiLe7cWvOQ,454
|
|
3
|
-
qulab/fun.cp310-win_amd64.pyd,sha256=
|
|
4
|
-
qulab/version.py,sha256=
|
|
3
|
+
qulab/fun.cp310-win_amd64.pyd,sha256=HhDHwlovmbtFML-GZmXElJ4iouH5WffpId7e6GRBf1s,31744
|
|
4
|
+
qulab/version.py,sha256=I501tBgxLlOMpveUyk065aIcjgpxqCi7zjY3gqoar7c,21
|
|
5
5
|
qulab/monitor/__init__.py,sha256=xEVDkJF8issrsDeLqQmDsvtRmrf-UiViFcGTWuzdlFU,43
|
|
6
6
|
qulab/monitor/__main__.py,sha256=k2H1H5Zf9LLXTDLISJkbikLH-z0f1e5i5i6wXXYPOrE,105
|
|
7
7
|
qulab/monitor/config.py,sha256=y_5StMkdrbZO1ziyKBrvIkB7Jclp9RCPK1QbsOhCxnY,785
|
|
@@ -17,10 +17,10 @@ qulab/scan/curd.py,sha256=yaTglGiS6mlk0GqDHi_w8T02XGBMvDZtXSdML7zDywk,7117
|
|
|
17
17
|
qulab/scan/expression.py,sha256=vwUM9E0OFQal4bljlUtLR3NJu4zGRyuWYrdyZSs3QTU,16199
|
|
18
18
|
qulab/scan/models.py,sha256=ZvXkJEt5Yz3Sjx0JKzYka-q2Uo-w_iVzHgH8A6DbjF0,18236
|
|
19
19
|
qulab/scan/optimize.py,sha256=MlT4y422CnP961IR384UKryyZh8riNvrPSd2z_MXLEg,2356
|
|
20
|
-
qulab/scan/query.py,sha256=
|
|
21
|
-
qulab/scan/record.py,sha256=
|
|
22
|
-
qulab/scan/scan.py,sha256=
|
|
23
|
-
qulab/scan/server.py,sha256=
|
|
20
|
+
qulab/scan/query.py,sha256=RM8bG4Tcx_PaNk8tv9HdlTZ1dGuuSr3sZVkYVq2BtfQ,12183
|
|
21
|
+
qulab/scan/record.py,sha256=aBpUllhKsBRhPOwZwsp3rcw2HB-3ne9yLYHLBeXXM-M,21669
|
|
22
|
+
qulab/scan/scan.py,sha256=hYTEEa4frIN6HraNleoytnCZjZ0c_XWOI1DSLchkpuE,37589
|
|
23
|
+
qulab/scan/server.py,sha256=GTV9wzlFTmG6YUj_8WwR4e6uvaq9AgdearLh3i3YAfw,14569
|
|
24
24
|
qulab/scan/space.py,sha256=fWsY99HDauk89f5ygqnJYBoeNFGTUkAGFssrw-YMHok,5453
|
|
25
25
|
qulab/scan/utils.py,sha256=30qnYvyFyctwcWxOCUpCNxXgGysA7xdIDzYbjwxGUzA,3744
|
|
26
26
|
qulab/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -70,7 +70,7 @@ qulab/sys/rpc/server.py,sha256=W3bPwe8um1IeR_3HLx-ad6iCcbeuUQcSg11Ze4w6DJg,742
|
|
|
70
70
|
qulab/sys/rpc/socket.py,sha256=W3bPwe8um1IeR_3HLx-ad6iCcbeuUQcSg11Ze4w6DJg,742
|
|
71
71
|
qulab/sys/rpc/utils.py,sha256=BurIcqh8CS-Hsk1dYP6IiefK4qHivaEqD9_rBY083SA,619
|
|
72
72
|
qulab/sys/rpc/worker.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
73
|
-
qulab/sys/rpc/zmq_socket.py,sha256=
|
|
73
|
+
qulab/sys/rpc/zmq_socket.py,sha256=aoIm-C-IdJjm9_PQXckvbqTxc9kCeJrT4PyYytoDIHo,8492
|
|
74
74
|
qulab/visualization/__init__.py,sha256=Bkt9AK5c45d6HFLlT-f8cIppywXziHtJqhDtVxOoKKo,6317
|
|
75
75
|
qulab/visualization/__main__.py,sha256=WduINFl21B-XMsi2rg2cVhIyU11hKKX3zOsjc56QLiQ,1710
|
|
76
76
|
qulab/visualization/_autoplot.py,sha256=JFLR3e71bryPaUkOCWFzD9C4Nk-ulqIdBb1YN4QnZic,14562
|
|
@@ -78,9 +78,9 @@ qulab/visualization/plot_layout.py,sha256=yAnMONOms7_szCdng-8wPpUMPis5UnbaNNzV4K
|
|
|
78
78
|
qulab/visualization/plot_seq.py,sha256=h9D0Yl_yO64IwlvBgzMu9EBKr9gg6y8QE55gu2PfTns,2783
|
|
79
79
|
qulab/visualization/qdat.py,sha256=HubXFu4nfcA7iUzghJGle1C86G6221hicLR0b-GqhKQ,5887
|
|
80
80
|
qulab/visualization/widgets.py,sha256=HcYwdhDtLreJiYaZuN3LfofjJmZcLwjMfP5aasebgDo,3266
|
|
81
|
-
QuLab-2.2.
|
|
82
|
-
QuLab-2.2.
|
|
83
|
-
QuLab-2.2.
|
|
84
|
-
QuLab-2.2.
|
|
85
|
-
QuLab-2.2.
|
|
86
|
-
QuLab-2.2.
|
|
81
|
+
QuLab-2.2.7.dist-info/LICENSE,sha256=b4NRQ-GFVpJMT7RuExW3NwhfbrYsX7AcdB7Gudok-fs,1086
|
|
82
|
+
QuLab-2.2.7.dist-info/METADATA,sha256=uMz3KTAANhe7RMJa0Y-Q0LXISTG98aYohmRRA05bSK4,3609
|
|
83
|
+
QuLab-2.2.7.dist-info/WHEEL,sha256=lO6CqtLHCAi38X3Es1a4R1lAjZFvN010IMRCFo2S7Mc,102
|
|
84
|
+
QuLab-2.2.7.dist-info/entry_points.txt,sha256=ohBzutEnQimP_BZWiuXdSliu4QAYSHHcN0PZD8c7ZCY,46
|
|
85
|
+
QuLab-2.2.7.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
|
|
86
|
+
QuLab-2.2.7.dist-info/RECORD,,
|
qulab/fun.cp310-win_amd64.pyd
CHANGED
|
Binary file
|
qulab/scan/query.py
CHANGED
|
@@ -16,9 +16,13 @@ from .scan import default_server
|
|
|
16
16
|
from .server import get_local_record
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
def get_record(id,
|
|
19
|
+
def get_record(id,
|
|
20
|
+
database=default_server,
|
|
21
|
+
socket=None,
|
|
22
|
+
session=None) -> Record:
|
|
20
23
|
if isinstance(database, str) and database.startswith('tcp://'):
|
|
21
|
-
with ZMQContextManager(zmq.DEALER, connect=database
|
|
24
|
+
with ZMQContextManager(zmq.DEALER, connect=database,
|
|
25
|
+
socket=socket) as socket:
|
|
22
26
|
socket.send_pyobj({
|
|
23
27
|
'method': 'record_description',
|
|
24
28
|
'record_id': id
|
|
@@ -29,12 +33,16 @@ def get_record(id, database=default_server) -> Record:
|
|
|
29
33
|
d.id = id
|
|
30
34
|
d.database = database
|
|
31
35
|
d._file = None
|
|
36
|
+
d._sock = socket
|
|
32
37
|
return d
|
|
33
38
|
else:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
if session is None:
|
|
40
|
+
db_file = Path(database) / 'data.db'
|
|
41
|
+
engine = create_engine(f'sqlite:///{db_file}')
|
|
42
|
+
Session = sessionmaker(bind=engine)
|
|
43
|
+
with Session() as session:
|
|
44
|
+
return get_local_record(session, id, database)
|
|
45
|
+
else:
|
|
38
46
|
return get_local_record(session, id, database)
|
|
39
47
|
|
|
40
48
|
|
qulab/scan/record.py
CHANGED
|
@@ -56,6 +56,7 @@ class BufferList():
|
|
|
56
56
|
self._slice = slice
|
|
57
57
|
self._lock = Lock()
|
|
58
58
|
self._data_id = None
|
|
59
|
+
self._sock = None
|
|
59
60
|
|
|
60
61
|
def __repr__(self):
|
|
61
62
|
return f"<BufferList: shape={self.shape}, lu={self.lu}, rd={self.rd}, slice={self._slice}>"
|
|
@@ -82,6 +83,7 @@ class BufferList():
|
|
|
82
83
|
self._slice = None
|
|
83
84
|
self._lock = Lock()
|
|
84
85
|
self._data_id = None
|
|
86
|
+
self._sock = None
|
|
85
87
|
|
|
86
88
|
@property
|
|
87
89
|
def shape(self):
|
|
@@ -156,7 +158,9 @@ class BufferList():
|
|
|
156
158
|
yield pos, value
|
|
157
159
|
else:
|
|
158
160
|
server, record_id, key = self._data_id
|
|
159
|
-
with ZMQContextManager(zmq.DEALER,
|
|
161
|
+
with ZMQContextManager(zmq.DEALER,
|
|
162
|
+
connect=server,
|
|
163
|
+
socket=self._sock) as socket:
|
|
160
164
|
iter_id = b''
|
|
161
165
|
start = 0
|
|
162
166
|
try:
|
|
@@ -200,7 +204,7 @@ class BufferList():
|
|
|
200
204
|
d.append(value)
|
|
201
205
|
return p, d
|
|
202
206
|
|
|
203
|
-
def
|
|
207
|
+
def toarray(self):
|
|
204
208
|
pos, data = self.items()
|
|
205
209
|
if self._slice:
|
|
206
210
|
pos = np.asarray(pos)
|
|
@@ -294,7 +298,7 @@ class BufferList():
|
|
|
294
298
|
def __getitem__(self, slice_tuple: slice | EllipsisType
|
|
295
299
|
| tuple[slice | int | EllipsisType, ...]):
|
|
296
300
|
self._slice, contract, reversed = self._full_slice(slice_tuple)
|
|
297
|
-
ret = self.
|
|
301
|
+
ret = self.toarray()
|
|
298
302
|
slices = []
|
|
299
303
|
for i, s in enumerate(self._slice):
|
|
300
304
|
if i in contract:
|
|
@@ -319,6 +323,7 @@ class Record():
|
|
|
319
323
|
self._pos = []
|
|
320
324
|
self._last_vars = set()
|
|
321
325
|
self._file = None
|
|
326
|
+
self._sock = None
|
|
322
327
|
|
|
323
328
|
for name, value in self.description['intrinsic_loops'].items():
|
|
324
329
|
self._items[name] = value
|
|
@@ -348,6 +353,7 @@ class Record():
|
|
|
348
353
|
self._last_vars = set()
|
|
349
354
|
self.database = None
|
|
350
355
|
self._file = None
|
|
356
|
+
self._sock = None
|
|
351
357
|
|
|
352
358
|
@property
|
|
353
359
|
def axis(self):
|
|
@@ -361,7 +367,8 @@ class Record():
|
|
|
361
367
|
return cls(config_id)
|
|
362
368
|
if self.is_remote_record():
|
|
363
369
|
with ZMQContextManager(zmq.DEALER,
|
|
364
|
-
connect=self.database
|
|
370
|
+
connect=self.database,
|
|
371
|
+
socket=self._sock) as socket:
|
|
365
372
|
socket.send_pyobj({
|
|
366
373
|
'method': 'config_get',
|
|
367
374
|
'config_id': config_id
|
|
@@ -375,6 +382,31 @@ class Record():
|
|
|
375
382
|
session.commit()
|
|
376
383
|
return cls(config)
|
|
377
384
|
|
|
385
|
+
def scripts(self, session=None):
|
|
386
|
+
scripts = self.description['entry']['scripts']
|
|
387
|
+
if isinstance(scripts, list):
|
|
388
|
+
return scripts
|
|
389
|
+
else:
|
|
390
|
+
cell_id = scripts
|
|
391
|
+
|
|
392
|
+
if self.is_remote_record():
|
|
393
|
+
with ZMQContextManager(zmq.DEALER,
|
|
394
|
+
connect=self.database,
|
|
395
|
+
socket=self._sock) as socket:
|
|
396
|
+
socket.send_pyobj({
|
|
397
|
+
'method': 'notebook_history',
|
|
398
|
+
'cell_id': cell_id
|
|
399
|
+
})
|
|
400
|
+
return socket.recv_pyobj()
|
|
401
|
+
elif self.is_local_record():
|
|
402
|
+
from .models import Cell
|
|
403
|
+
assert session is not None, "session is required for local record"
|
|
404
|
+
cell = session.get(Cell, cell_id)
|
|
405
|
+
return [
|
|
406
|
+
cell.input.text
|
|
407
|
+
for cell in cell.notebook.cells[1:cell.index + 2]
|
|
408
|
+
]
|
|
409
|
+
|
|
378
410
|
def is_local_record(self):
|
|
379
411
|
return not self.is_cache_record() and not self.is_remote_record()
|
|
380
412
|
|
|
@@ -389,15 +421,13 @@ class Record():
|
|
|
389
421
|
self.flush()
|
|
390
422
|
|
|
391
423
|
def __getitem__(self, key):
|
|
392
|
-
|
|
393
|
-
if isinstance(ret, Space):
|
|
394
|
-
ret = ret.toarray()
|
|
395
|
-
return ret
|
|
424
|
+
return self.get(key, buffer_to_array=True)
|
|
396
425
|
|
|
397
|
-
def get(self, key, default=_not_given, buffer_to_array=False
|
|
426
|
+
def get(self, key, default=_not_given, buffer_to_array=False):
|
|
398
427
|
if self.is_remote_record():
|
|
399
428
|
with ZMQContextManager(zmq.DEALER,
|
|
400
|
-
connect=self.database
|
|
429
|
+
connect=self.database,
|
|
430
|
+
socket=self._sock) as socket:
|
|
401
431
|
socket.send_pyobj({
|
|
402
432
|
'method': 'record_getitem',
|
|
403
433
|
'record_id': self.id,
|
|
@@ -405,25 +435,14 @@ class Record():
|
|
|
405
435
|
})
|
|
406
436
|
ret = socket.recv_pyobj()
|
|
407
437
|
if isinstance(ret, BufferList):
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
'method': 'bufferlist_slice',
|
|
411
|
-
'record_id': self.id,
|
|
412
|
-
'key': key,
|
|
413
|
-
'slice': slice
|
|
414
|
-
})
|
|
415
|
-
lst = socket.recv_pyobj()
|
|
416
|
-
ret._list = lst
|
|
417
|
-
ret._slice = slice
|
|
418
|
-
return ret.array()
|
|
419
|
-
else:
|
|
420
|
-
ret._data_id = self.database, self.id, key
|
|
421
|
-
return ret
|
|
422
|
-
elif isinstance(ret, Space):
|
|
438
|
+
ret._data_id = self.database, self.id, key
|
|
439
|
+
ret._sock = socket
|
|
423
440
|
if buffer_to_array:
|
|
424
441
|
return ret.toarray()
|
|
425
442
|
else:
|
|
426
443
|
return ret
|
|
444
|
+
elif isinstance(ret, Space) and buffer_to_array:
|
|
445
|
+
return ret.toarray()
|
|
427
446
|
else:
|
|
428
447
|
return ret
|
|
429
448
|
else:
|
|
@@ -434,9 +453,8 @@ class Record():
|
|
|
434
453
|
if isinstance(d, BufferList):
|
|
435
454
|
if isinstance(d.file, str):
|
|
436
455
|
d.file = self._file.parent.parent.parent.parent / d.file
|
|
437
|
-
d._slice = slice
|
|
438
456
|
if buffer_to_array:
|
|
439
|
-
return d.
|
|
457
|
+
return d.toarray()
|
|
440
458
|
else:
|
|
441
459
|
return d
|
|
442
460
|
elif isinstance(d, Space):
|
|
@@ -450,7 +468,8 @@ class Record():
|
|
|
450
468
|
def keys(self):
|
|
451
469
|
if self.is_remote_record():
|
|
452
470
|
with ZMQContextManager(zmq.DEALER,
|
|
453
|
-
connect=self.database
|
|
471
|
+
connect=self.database,
|
|
472
|
+
socket=self._sock) as socket:
|
|
454
473
|
socket.send_pyobj({
|
|
455
474
|
'method': 'record_keys',
|
|
456
475
|
'record_id': self.id
|
|
@@ -517,7 +536,8 @@ class Record():
|
|
|
517
536
|
def delete(self):
|
|
518
537
|
if self.is_remote_record():
|
|
519
538
|
with ZMQContextManager(zmq.DEALER,
|
|
520
|
-
connect=self.database
|
|
539
|
+
connect=self.database,
|
|
540
|
+
socket=self._sock) as socket:
|
|
521
541
|
socket.send_pyobj({
|
|
522
542
|
'method': 'record_delete',
|
|
523
543
|
'record_id': self.id
|
|
@@ -553,35 +573,14 @@ class Record():
|
|
|
553
573
|
with z.open('config.pkl', 'w') as f:
|
|
554
574
|
f.write(dill.dumps(self.config()))
|
|
555
575
|
|
|
556
|
-
def scripts(self, session=None):
|
|
557
|
-
scripts = self.description['entry']['scripts']
|
|
558
|
-
if isinstance(scripts, list):
|
|
559
|
-
return scripts
|
|
560
|
-
else:
|
|
561
|
-
cell_id = scripts
|
|
562
|
-
|
|
563
|
-
if self.is_remote_record():
|
|
564
|
-
with ZMQContextManager(zmq.DEALER,
|
|
565
|
-
connect=self.database) as socket:
|
|
566
|
-
socket.send_pyobj({
|
|
567
|
-
'method': 'notebook_history',
|
|
568
|
-
'cell_id': cell_id
|
|
569
|
-
})
|
|
570
|
-
return socket.recv_pyobj()
|
|
571
|
-
elif self.is_local_record():
|
|
572
|
-
from .models import Cell
|
|
573
|
-
assert session is not None, "session is required for local record"
|
|
574
|
-
cell = session.get(Cell, cell_id)
|
|
575
|
-
return [
|
|
576
|
-
cell.input.text
|
|
577
|
-
for cell in cell.notebook.cells[1:cell.index + 2]
|
|
578
|
-
]
|
|
579
|
-
|
|
580
576
|
@classmethod
|
|
581
577
|
def load(cls, file: str):
|
|
582
578
|
with zipfile.ZipFile(file, 'r') as z:
|
|
583
579
|
with z.open('record.pkl', 'r') as f:
|
|
584
580
|
description, items = dill.load(f)
|
|
581
|
+
with z.open('config.pkl', 'r') as f:
|
|
582
|
+
config = dill.load(f)
|
|
583
|
+
description['config'] = config
|
|
585
584
|
record = cls(None, None, description)
|
|
586
585
|
for key, value in items.items():
|
|
587
586
|
if isinstance(value, BufferList):
|
qulab/scan/scan.py
CHANGED
|
@@ -310,7 +310,10 @@ class Scan():
|
|
|
310
310
|
self._main_task.cancel()
|
|
311
311
|
except:
|
|
312
312
|
pass
|
|
313
|
-
|
|
313
|
+
try:
|
|
314
|
+
self._executors.shutdown()
|
|
315
|
+
except:
|
|
316
|
+
pass
|
|
314
317
|
|
|
315
318
|
@property
|
|
316
319
|
def current_level(self):
|
|
@@ -323,7 +326,7 @@ class Scan():
|
|
|
323
326
|
async def _emit(self, current_level, step, position, variables: dict[str,
|
|
324
327
|
Any]):
|
|
325
328
|
for key, value in list(variables.items()):
|
|
326
|
-
if key.startswith('*'):
|
|
329
|
+
if key.startswith('*') or ',' in key:
|
|
327
330
|
await _unpack(key, variables)
|
|
328
331
|
elif inspect.isawaitable(value) and not self.hiden(key):
|
|
329
332
|
variables[key] = await value
|
|
@@ -356,8 +359,8 @@ class Scan():
|
|
|
356
359
|
self._hide_pattern_re = re.compile('|'.join(self.description['hiden']))
|
|
357
360
|
|
|
358
361
|
def hiden(self, name: str) -> bool:
|
|
359
|
-
return bool(
|
|
360
|
-
|
|
362
|
+
return bool(self._hide_pattern_re.match(name)) or name.startswith(
|
|
363
|
+
'*') or ',' in name
|
|
361
364
|
|
|
362
365
|
async def _filter(self, variables: dict[str, Any], level: int = 0):
|
|
363
366
|
try:
|
|
@@ -444,6 +447,11 @@ class Scan():
|
|
|
444
447
|
except:
|
|
445
448
|
pass
|
|
446
449
|
self.description['consts'][name] = value
|
|
450
|
+
|
|
451
|
+
if ',' in name:
|
|
452
|
+
for key in name.split(','):
|
|
453
|
+
if not key.startswith('*'):
|
|
454
|
+
self.add_depends(key, [name])
|
|
447
455
|
if setter:
|
|
448
456
|
self.description['setters'][name] = setter
|
|
449
457
|
|
|
@@ -555,9 +563,9 @@ class Scan():
|
|
|
555
563
|
if isinstance(
|
|
556
564
|
self.description['database'],
|
|
557
565
|
str) and self.description['database'].startswith("tcp://"):
|
|
558
|
-
async with ZMQContextManager(
|
|
559
|
-
|
|
560
|
-
|
|
566
|
+
async with ZMQContextManager(zmq.DEALER,
|
|
567
|
+
connect=self.description['database'],
|
|
568
|
+
socket=self._sock) as socket:
|
|
561
569
|
self._sock = socket
|
|
562
570
|
await self._run()
|
|
563
571
|
else:
|
|
@@ -624,7 +632,9 @@ class Scan():
|
|
|
624
632
|
|
|
625
633
|
async def submit(self, server=default_executor):
|
|
626
634
|
assymbly(self.description)
|
|
627
|
-
async with ZMQContextManager(zmq.DEALER,
|
|
635
|
+
async with ZMQContextManager(zmq.DEALER,
|
|
636
|
+
connect=server,
|
|
637
|
+
socket=self._sock) as socket:
|
|
628
638
|
await socket.send_pyobj({
|
|
629
639
|
'method': 'task_submit',
|
|
630
640
|
'description': dill.dumps(self.description)
|
|
@@ -901,7 +911,10 @@ def assymbly(description):
|
|
|
901
911
|
axis[name] = tuple(sorted(d))
|
|
902
912
|
else:
|
|
903
913
|
axis[name] = tuple(sorted(set(axis[name]) | d))
|
|
904
|
-
description['axis'] =
|
|
914
|
+
description['axis'] = {
|
|
915
|
+
k: tuple([x for x in v if x >= 0])
|
|
916
|
+
for k, v in axis.items()
|
|
917
|
+
}
|
|
905
918
|
description['independent_variables'] = independent_variables
|
|
906
919
|
|
|
907
920
|
return description
|
|
@@ -972,7 +985,7 @@ async def _iter_level(variables,
|
|
|
972
985
|
|
|
973
986
|
if opts:
|
|
974
987
|
for key in list(variables.keys()):
|
|
975
|
-
if key.startswith('*'):
|
|
988
|
+
if key.startswith('*') or ',' in key:
|
|
976
989
|
await _unpack(key, variables)
|
|
977
990
|
|
|
978
991
|
for name, opt in opts.items():
|
|
@@ -1024,7 +1037,8 @@ async def _unpack(key, variables):
|
|
|
1024
1037
|
if inspect.isawaitable(x):
|
|
1025
1038
|
x = await x
|
|
1026
1039
|
if key.startswith('**'):
|
|
1027
|
-
assert isinstance(
|
|
1040
|
+
assert isinstance(
|
|
1041
|
+
x, dict), f"Should promise a dict for `**` symbol. {key}"
|
|
1028
1042
|
if "{key}" in key:
|
|
1029
1043
|
for k, v in x.items():
|
|
1030
1044
|
variables[key[2:].format(key=k)] = v
|
|
@@ -1033,10 +1047,44 @@ async def _unpack(key, variables):
|
|
|
1033
1047
|
elif key.startswith('*'):
|
|
1034
1048
|
assert isinstance(
|
|
1035
1049
|
x, (list, tuple,
|
|
1036
|
-
np.ndarray)), f"Should promise a list for `*` symbol."
|
|
1050
|
+
np.ndarray)), f"Should promise a list for `*` symbol. {key}"
|
|
1037
1051
|
for i, v in enumerate(x):
|
|
1038
1052
|
k = key[1:].format(i=i)
|
|
1039
1053
|
variables[k] = v
|
|
1054
|
+
elif ',' in key:
|
|
1055
|
+
keys1, keys2 = [], []
|
|
1056
|
+
args = None
|
|
1057
|
+
for k in key.split(','):
|
|
1058
|
+
if k.startswith('*'):
|
|
1059
|
+
if args is None:
|
|
1060
|
+
args = k
|
|
1061
|
+
else:
|
|
1062
|
+
raise ValueError(f'Only one `*` symbol is allowed. {key}')
|
|
1063
|
+
elif args is None:
|
|
1064
|
+
keys1.append(k)
|
|
1065
|
+
else:
|
|
1066
|
+
keys2.append(k)
|
|
1067
|
+
assert isinstance(
|
|
1068
|
+
x,
|
|
1069
|
+
(list, tuple,
|
|
1070
|
+
np.ndarray)), f"Should promise a list for multiple symbols. {key}"
|
|
1071
|
+
if args is None:
|
|
1072
|
+
assert len(keys1) == len(
|
|
1073
|
+
x), f"Length of keys and values should be equal. {key}"
|
|
1074
|
+
for k, v in zip(keys1, x):
|
|
1075
|
+
variables[k] = v
|
|
1076
|
+
else:
|
|
1077
|
+
assert len(keys1) + len(keys2) <= len(
|
|
1078
|
+
x), f"Too many values for unpacking. {key}"
|
|
1079
|
+
for k, v in zip(keys1, x[:len(keys1)]):
|
|
1080
|
+
variables[k] = v
|
|
1081
|
+
end = -len(keys2) if keys2 else None
|
|
1082
|
+
for i, v in enumerate(x[len(keys1):end]):
|
|
1083
|
+
k = args[1:].format(i=i)
|
|
1084
|
+
variables[k] = v
|
|
1085
|
+
if keys2:
|
|
1086
|
+
for k, v in zip(keys2, x[end:]):
|
|
1087
|
+
variables[k] = v
|
|
1040
1088
|
else:
|
|
1041
1089
|
return
|
|
1042
1090
|
del variables[key]
|
qulab/scan/server.py
CHANGED
|
@@ -161,8 +161,9 @@ async def handle(session: Session, request: Request, datapath: Path):
|
|
|
161
161
|
iter_id = uuid.uuid3(namespace, str(time.time_ns())).bytes
|
|
162
162
|
record = get_record(session, msg['record_id'], datapath)
|
|
163
163
|
bufferlist = record.get(msg['key'],
|
|
164
|
-
buffer_to_array=False
|
|
165
|
-
|
|
164
|
+
buffer_to_array=False)
|
|
165
|
+
if msg['slice']:
|
|
166
|
+
bufferlist._slice = msg['slice']
|
|
166
167
|
it = bufferlist.iter()
|
|
167
168
|
for _, _ in zip(range(msg['start']), it):
|
|
168
169
|
pass
|
qulab/sys/rpc/zmq_socket.py
CHANGED
|
@@ -130,7 +130,12 @@ class ZMQContextManager:
|
|
|
130
130
|
self.auth = None
|
|
131
131
|
self.context = None
|
|
132
132
|
self.socket = None
|
|
133
|
-
self._external_socket =
|
|
133
|
+
self._external_socket = None
|
|
134
|
+
try:
|
|
135
|
+
if not socket.closed:
|
|
136
|
+
self._external_socket = socket
|
|
137
|
+
except:
|
|
138
|
+
pass
|
|
134
139
|
|
|
135
140
|
def _create_socket(self, asyncio=False) -> zmq.Socket:
|
|
136
141
|
"""
|
qulab/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "2.2.
|
|
1
|
+
__version__ = "2.2.7"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|