QuLab 2.2.0__cp311-cp311-macosx_10_9_universal2.whl → 2.2.3__cp311-cp311-macosx_10_9_universal2.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: QuLab
3
- Version: 2.2.0
3
+ Version: 2.2.3
4
4
  Summary: contral instruments and manage data
5
5
  Author-email: feihoo87 <feihoo87@gmail.com>
6
6
  Maintainer-email: feihoo87 <feihoo87@gmail.com>
@@ -1,7 +1,7 @@
1
1
  qulab/__init__.py,sha256=P-Mx2p4TVmL91SoxoeXcj8Qm0x4xUf5Q_FLk0Yc_gIQ,138
2
2
  qulab/__main__.py,sha256=ZC1NKaoxKyy60DaCfB8vYnB1z3RXQ2j8E1sRZ4A8sXE,428
3
- qulab/fun.cpython-311-darwin.so,sha256=yvKT1w1sOwwr1ylDsz3k9IhHcVSSatRjKtRbcwAe_7g,159616
4
- qulab/version.py,sha256=j8DDNpniPNhmwry5zUQczzr9Gj6bGU3sUUeXfGl_kKE,21
3
+ qulab/fun.cpython-311-darwin.so,sha256=TQ2exCgdoX4CYlnrBv2JljwDa0H8XwjSCSxOE_wckZQ,159616
4
+ qulab/version.py,sha256=Nt4yGCnk6mAxHxAbWGL2m0dPsKn_yhp3_F9LBmkhnvI,21
5
5
  qulab/monitor/__init__.py,sha256=nTHelnDpxRS_fl_B38TsN0njgq8eVTEz9IAnN3NbDlM,42
6
6
  qulab/monitor/__main__.py,sha256=w3yUcqq195LzSnXTkQcuC1RSFRhy4oQ_PEBmucXguME,97
7
7
  qulab/monitor/config.py,sha256=fQ5JcsMApKc1UwANEnIvbDQZl8uYW0tle92SaYtX9lI,744
@@ -17,10 +17,10 @@ qulab/scan/curd.py,sha256=thq_qfi3qng3Zx-1uhNG64IQhGCuum_LR4MOKnS8cDI,6896
17
17
  qulab/scan/expression.py,sha256=-aTYbjFQNI1mwOcoSBztqhKfGJpu_n4a1QnWro_xnTU,15694
18
18
  qulab/scan/models.py,sha256=5Jpo25WGMWs0GtLzYLsWO61G3-FFYx5BHhBr2b6rOTE,17681
19
19
  qulab/scan/optimize.py,sha256=vErjRTCtn2MwMF5Xyhs1P4gHF2IFHv_EqxsUvH_4y7k,2287
20
- qulab/scan/query.py,sha256=Ct07TGwEedWY8z_Nv_1Y3BHIToli2KG88LB_X5VnZCU,11455
21
- qulab/scan/record.py,sha256=_s2f6hp1poiyOqp81cBzt7EbNmkUPBt08bmmDQYcXaE,18572
22
- qulab/scan/scan.py,sha256=Zdeg5RTKVHEyDWd4z_2xRsnxuNDOm1S2McncVk1jKe8,34774
23
- qulab/scan/server.py,sha256=EiS5hu1YM9e25W2tjekzfJiRkyD9urVLIo1dp3VXiDY,11591
20
+ qulab/scan/query.py,sha256=rDVX5WkKfWcSpLpP55d6FL76xdCFQg7vG_83_IAtgHA,11551
21
+ qulab/scan/record.py,sha256=LDbWPcBzWAmnEAqDv7Oxrwf7a_A29rk_jd9zRqQYOgc,19586
22
+ qulab/scan/scan.py,sha256=dRtXewI8W9Fe5ZQsMz56XU-dopfa-MleEihYS0os7Eg,34422
23
+ qulab/scan/server.py,sha256=EszeCBAHyZDdy-fq3RHPu696Do6qzsXmdamK6nkEIsw,12215
24
24
  qulab/scan/space.py,sha256=XEWQnlRYPix65LyiT6KLOK7WG2a11FJJ_M4H_dZ6Z-E,5209
25
25
  qulab/scan/utils.py,sha256=Pg_tCf3SUKTiPSBqb6Enkgx4bAyQJAkDGe9uYys1xVU,3613
26
26
  qulab/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -78,9 +78,9 @@ qulab/visualization/plot_layout.py,sha256=clNw9QjE_kVNpIIx2Ob4YhAz2fucPGMuzkoIrO
78
78
  qulab/visualization/plot_seq.py,sha256=lphYF4VhkEdc_wWr1kFBwrx2yujkyFPFaJ3pjr61awI,2693
79
79
  qulab/visualization/qdat.py,sha256=ZeevBYWkzbww4xZnsjHhw7wRorJCBzbG0iEu-XQB4EA,5735
80
80
  qulab/visualization/widgets.py,sha256=6KkiTyQ8J-ei70LbPQZAK35wjktY47w2IveOa682ftA,3180
81
- QuLab-2.2.0.dist-info/LICENSE,sha256=PRzIKxZtpQcH7whTG6Egvzl1A0BvnSf30tmR2X2KrpA,1065
82
- QuLab-2.2.0.dist-info/METADATA,sha256=dGfThQKKaP-VcDG5Nj0mSi3Z0gnytkYWShbUelPUm1M,3510
83
- QuLab-2.2.0.dist-info/WHEEL,sha256=eupBwbXGAhwNAPJSvj5BiShZwdZO8jnQ5yHfv-9aUGw,115
84
- QuLab-2.2.0.dist-info/entry_points.txt,sha256=ohBzutEnQimP_BZWiuXdSliu4QAYSHHcN0PZD8c7ZCY,46
85
- QuLab-2.2.0.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
86
- QuLab-2.2.0.dist-info/RECORD,,
81
+ QuLab-2.2.3.dist-info/LICENSE,sha256=PRzIKxZtpQcH7whTG6Egvzl1A0BvnSf30tmR2X2KrpA,1065
82
+ QuLab-2.2.3.dist-info/METADATA,sha256=I-G824CztR72B1Zk6pxWpLzlm4gKjH5qjGmVQzvJumE,3510
83
+ QuLab-2.2.3.dist-info/WHEEL,sha256=eupBwbXGAhwNAPJSvj5BiShZwdZO8jnQ5yHfv-9aUGw,115
84
+ QuLab-2.2.3.dist-info/entry_points.txt,sha256=ohBzutEnQimP_BZWiuXdSliu4QAYSHHcN0PZD8c7ZCY,46
85
+ QuLab-2.2.3.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
86
+ QuLab-2.2.3.dist-info/RECORD,,
Binary file
qulab/scan/query.py CHANGED
@@ -12,8 +12,8 @@ from sqlalchemy.orm import sessionmaker
12
12
  from qulab.sys.rpc.zmq_socket import ZMQContextManager
13
13
 
14
14
  from .record import Record
15
- from .server import get_local_record
16
15
  from .scan import default_server
16
+ from .server import get_local_record
17
17
 
18
18
 
19
19
  def get_record(id, database=default_server) -> Record:
@@ -24,6 +24,8 @@ def get_record(id, database=default_server) -> Record:
24
24
  'record_id': id
25
25
  })
26
26
  d = dill.loads(socket.recv_pyobj())
27
+ if isinstance(d, None):
28
+ raise ValueError(f'No record with id {id}')
27
29
  d.id = id
28
30
  d.database = database
29
31
  d._file = None
qulab/scan/record.py CHANGED
@@ -1,4 +1,6 @@
1
1
  import itertools
2
+ import lzma
3
+ import pickle
2
4
  import sys
3
5
  import uuid
4
6
  import zipfile
@@ -12,6 +14,7 @@ import zmq
12
14
 
13
15
  from qulab.sys.rpc.zmq_socket import ZMQContextManager
14
16
 
17
+ from .curd import get_config
15
18
  from .space import OptimizeSpace, Space
16
19
 
17
20
  _not_given = object()
@@ -326,6 +329,28 @@ class Record():
326
329
  def axis(self):
327
330
  return self.description.get('axis', {})
328
331
 
332
+ def config(self, cls=dict, session=None, datapath=None):
333
+ config_id = self.description.get('config', None)
334
+ if config_id is None:
335
+ return None
336
+ if isinstance(config_id, dict):
337
+ return cls(config_id)
338
+ if self.is_remote_record():
339
+ with ZMQContextManager(zmq.DEALER,
340
+ connect=self.database) as socket:
341
+ socket.send_pyobj({
342
+ 'method': 'config_get',
343
+ 'config_id': config_id
344
+ })
345
+ buf = socket.recv_pyobj()
346
+ return cls(pickle.loads(lzma.decompress(buf)))
347
+ else:
348
+ assert session is not None, "session is required for local record"
349
+ assert datapath is not None, "datapath is required for local record"
350
+ config = get_config(session, config_id, base=datapath / 'objects')
351
+ session.commit()
352
+ return cls(config)
353
+
329
354
  def is_local_record(self):
330
355
  return not self.is_cache_record() and not self.is_remote_record()
331
356
 
qulab/scan/scan.py CHANGED
@@ -145,17 +145,6 @@ async def create_config(config: dict, database=default_server, socket=None):
145
145
  return await socket.recv_pyobj()
146
146
 
147
147
 
148
- async def get_config(config_id: int, database=default_server, socket=None):
149
- async with ZMQContextManager(zmq.DEALER, connect=database,
150
- socket=socket) as socket:
151
- await socket.send_pyobj({
152
- 'method': 'config_get',
153
- 'config_id': config_id
154
- })
155
- buf = await socket.recv_pyobj()
156
- return pickle.loads(lzma.decompress(buf))
157
-
158
-
159
148
  def task_uuid():
160
149
  return uuid.uuid3(__process_uuid, str(next(__task_counter)))
161
150
 
@@ -332,16 +321,8 @@ class Scan():
332
321
  async def _emit(self, current_level, step, position, variables: dict[str,
333
322
  Any]):
334
323
  for key, value in list(variables.items()):
335
- if key.startswith('**'):
336
- if isinstance(value, dict):
337
- variables.update(value)
338
- del variables[key]
339
- elif inspect.isawaitable(value):
340
- d = await value
341
- assert isinstance(
342
- d, dict), f"Should promise a dict for `**` symbol."
343
- variables.update(d)
344
- del variables[key]
324
+ if key.startswith('*'):
325
+ await _unpack(key, variables)
345
326
  elif inspect.isawaitable(value) and not self.hiden(key):
346
327
  variables[key] = await value
347
328
  if self._sock is not None:
@@ -373,7 +354,7 @@ class Scan():
373
354
 
374
355
  def hiden(self, name: str) -> bool:
375
356
  return bool(
376
- self._hide_pattern_re.match(name)) and not name.startswith('**')
357
+ self._hide_pattern_re.match(name)) and not name.startswith('*')
377
358
 
378
359
  async def _filter(self, variables: dict[str, Any], level: int = 0):
379
360
  try:
@@ -984,14 +965,8 @@ async def _iter_level(variables,
984
965
 
985
966
  if opts:
986
967
  for key in list(variables.keys()):
987
- if key.startswith('**'):
988
- d = variables[key]
989
- if inspect.isawaitable(d):
990
- d = await d
991
- assert isinstance(
992
- d, dict), f"Should promise a dict for `**` symbol."
993
- variables.update(d)
994
- del variables[key]
968
+ if key.startswith('*'):
969
+ await _unpack(key, variables)
995
970
 
996
971
  for name, opt in opts.items():
997
972
  opt_cfg = optimizers[name]
@@ -1035,3 +1010,26 @@ async def call_many_functions(order: list[list[str]],
1035
1010
  results = await asyncio.gather(*coros)
1036
1011
  ret.update(dict(zip(waited, results)))
1037
1012
  return ret
1013
+
1014
+
1015
+ async def _unpack(key, variables):
1016
+ x = variables[key]
1017
+ if inspect.isawaitable(x):
1018
+ x = await x
1019
+ if key.startswith('**'):
1020
+ assert isinstance(x, dict), f"Should promise a dict for `**` symbol."
1021
+ if "{key}" in key:
1022
+ for k, v in x.items():
1023
+ variables[key[2:].format(key=k)] = v
1024
+ else:
1025
+ variables.update(x)
1026
+ elif key.startswith('*'):
1027
+ assert isinstance(
1028
+ x, (list, tuple,
1029
+ np.ndarray)), f"Should promise a list for `*` symbol."
1030
+ for i, v in enumerate(x):
1031
+ k = key[1:].format(i=i)
1032
+ variables[k] = v
1033
+ else:
1034
+ return
1035
+ del variables[key]
qulab/scan/server.py CHANGED
@@ -65,6 +65,8 @@ def flush_cache():
65
65
 
66
66
  def get_local_record(session: Session, id: int, datapath: Path) -> Record:
67
67
  record_in_db = session.get(RecordInDB, id)
68
+ if record_in_db is None:
69
+ return None
68
70
  record_in_db.atime = utcnow()
69
71
 
70
72
  if record_in_db.file.endswith('.zip'):
@@ -220,21 +222,33 @@ async def handle(session: Session, request: Request, datapath: Path):
220
222
  await reply(request, config.id)
221
223
  case 'submit':
222
224
  from .scan import Scan
225
+ finished = [(id, queried) for id, (task, queried) in pool.items()
226
+ if not isinstance(task, int) and task.finished()]
227
+ for id, queried in finished:
228
+ if not queried:
229
+ pool[id] = [pool[id].record.id, False]
230
+ else:
231
+ pool.pop(id)
223
232
  description = dill.loads(msg['description'])
224
233
  task = Scan()
225
234
  task.description = description
226
235
  task.start()
227
- pool[task.id] = task
236
+ pool[task.id] = [task, False]
228
237
  await reply(request, task.id)
229
238
  case 'get_record_id':
230
- task = pool.get(msg['id'])
231
- for _ in range(10):
232
- if task.record:
233
- await reply(request, task.record.id)
234
- break
235
- await asyncio.sleep(1)
239
+ task, queried = pool.get(msg['id'])
240
+ if isinstance(task, int):
241
+ await reply(request, task)
242
+ pool.pop(msg['id'])
236
243
  else:
237
- await reply(request, None)
244
+ for _ in range(10):
245
+ if task.record:
246
+ await reply(request, task.record.id)
247
+ pool[msg['id']] = [task, True]
248
+ break
249
+ await asyncio.sleep(1)
250
+ else:
251
+ await reply(request, None)
238
252
  case _:
239
253
  logger.error(f"Unknown method: {msg['method']}")
240
254
 
qulab/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "2.2.0"
1
+ __version__ = "2.2.3"
File without changes
File without changes