QuLab 2.0.1__cp312-cp312-win_amd64.whl → 2.0.3__cp312-cp312-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.0.1.dist-info → QuLab-2.0.3.dist-info}/METADATA +5 -1
- {QuLab-2.0.1.dist-info → QuLab-2.0.3.dist-info}/RECORD +20 -18
- qulab/__main__.py +2 -0
- qulab/fun.cp312-win_amd64.pyd +0 -0
- qulab/scan/__init__.py +2 -3
- qulab/scan/curd.py +144 -0
- qulab/scan/expression.py +34 -1
- qulab/scan/models.py +540 -0
- qulab/scan/optimize.py +69 -0
- qulab/scan/query_record.py +361 -0
- qulab/scan/recorder.py +447 -0
- qulab/scan/scan.py +693 -0
- qulab/scan/utils.py +80 -34
- qulab/sys/rpc/zmq_socket.py +209 -0
- qulab/version.py +1 -1
- qulab/visualization/_autoplot.py +11 -5
- qulab/scan/base.py +0 -548
- qulab/scan/dataset.py +0 -0
- qulab/scan/scanner.py +0 -270
- qulab/scan/transforms.py +0 -16
- {QuLab-2.0.1.dist-info → QuLab-2.0.3.dist-info}/LICENSE +0 -0
- {QuLab-2.0.1.dist-info → QuLab-2.0.3.dist-info}/WHEEL +0 -0
- {QuLab-2.0.1.dist-info → QuLab-2.0.3.dist-info}/entry_points.txt +0 -0
- {QuLab-2.0.1.dist-info → QuLab-2.0.3.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: QuLab
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.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>
|
|
@@ -30,10 +30,14 @@ Requires-Dist: dill >=0.3.6
|
|
|
30
30
|
Requires-Dist: GitPython >=3.1.14
|
|
31
31
|
Requires-Dist: ipython >=7.4.0
|
|
32
32
|
Requires-Dist: ipywidgets >=7.4.2
|
|
33
|
+
Requires-Dist: loguru >=0.7.2
|
|
33
34
|
Requires-Dist: matplotlib >=3.7.2
|
|
35
|
+
Requires-Dist: nevergrad >=1.0.2
|
|
34
36
|
Requires-Dist: numpy >=1.13.3
|
|
35
37
|
Requires-Dist: ply >=3.11
|
|
38
|
+
Requires-Dist: pyzmq >=25.1.0
|
|
36
39
|
Requires-Dist: scipy >=1.0.0
|
|
40
|
+
Requires-Dist: watchdog >=4.0.0
|
|
37
41
|
|
|
38
42
|
# QuLab
|
|
39
43
|
[](https://travis-ci.org/feihoo87/QuLab)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
qulab/__init__.py,sha256=8zLGg-DfQhnDl2Ky0n-zXpN-8e-g7iR0AcaI4l4Vvpk,32
|
|
2
|
-
qulab/__main__.py,sha256=
|
|
3
|
-
qulab/fun.cp312-win_amd64.pyd,sha256=
|
|
4
|
-
qulab/version.py,sha256=
|
|
2
|
+
qulab/__main__.py,sha256=OlYQe7go_eFLKR0uU6D1kIpTKvbpx3WRJFFdoYoFjdE,456
|
|
3
|
+
qulab/fun.cp312-win_amd64.pyd,sha256=4ghmy5r4ChEBtHCxCgcY2vxKup1TFqdUtG-n9T9Aqi0,31744
|
|
4
|
+
qulab/version.py,sha256=HFL2NgNf74s56viRPRlgp_rAmKP1MzrtnJeQ8LxF_8M,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
|
|
@@ -12,14 +12,15 @@ qulab/monitor/monitor.py,sha256=2AP-hhg1T6-38mieDm5_ONTIXnXYlIrSyOiAOxDKy0I,2398
|
|
|
12
12
|
qulab/monitor/ploter.py,sha256=dg7W28XTwEbBxHVtdPkFV135OQgoQwTi-NJCZQF-HYU,3724
|
|
13
13
|
qulab/monitor/qt_compat.py,sha256=Eq7zlA4_XstB92NhtAqebtWU_Btw4lcwFO30YxZ-TPE,804
|
|
14
14
|
qulab/monitor/toolbar.py,sha256=HxqG6ywKFyQJM2Q1s7SnhuzjbyeROczAZKwxztD1WJ8,8213
|
|
15
|
-
qulab/scan/__init__.py,sha256=
|
|
16
|
-
qulab/scan/
|
|
17
|
-
qulab/scan/
|
|
18
|
-
qulab/scan/
|
|
19
|
-
qulab/scan/optimize.py,sha256=
|
|
20
|
-
qulab/scan/
|
|
21
|
-
qulab/scan/
|
|
22
|
-
qulab/scan/
|
|
15
|
+
qulab/scan/__init__.py,sha256=O_m7HAjbavGUxl7MayY-PCGCXfzoASmeE-FX5zEIjCs,127
|
|
16
|
+
qulab/scan/curd.py,sha256=bEXtcmiaoAv5APToXx5O5tvmqAhE2_LkvdwLsI_8D5M,4662
|
|
17
|
+
qulab/scan/expression.py,sha256=vwUM9E0OFQal4bljlUtLR3NJu4zGRyuWYrdyZSs3QTU,16199
|
|
18
|
+
qulab/scan/models.py,sha256=TkiVHF_fUZzYHs4MsCTRh391thpf4Ozd3R_LAU0Gxkg,17657
|
|
19
|
+
qulab/scan/optimize.py,sha256=MlT4y422CnP961IR384UKryyZh8riNvrPSd2z_MXLEg,2356
|
|
20
|
+
qulab/scan/query_record.py,sha256=gRUBjablvjWhDM-nZEunMVxQbUeaFF8qG7sROy9kIbs,11882
|
|
21
|
+
qulab/scan/recorder.py,sha256=EgS7NzARFqZeWUJp188iFQWr-_fa7Akm0Op-tvGqh7A,15849
|
|
22
|
+
qulab/scan/scan.py,sha256=jDsjyOPf15DV8rk1q2CYH7aDO6ypaP6n7t3LmNaY03o,23187
|
|
23
|
+
qulab/scan/utils.py,sha256=XM-eKL5Xkm0hihhGS7Kq4g654Ye7n7TcU_f95gxtXq8,2634
|
|
23
24
|
qulab/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
25
|
qulab/storage/__main__.py,sha256=6-EjN0waX1yfcMPJXqpIr9UlrIEsSCFApm5G-ZeaPMQ,1742
|
|
25
26
|
qulab/storage/base_dataset.py,sha256=28y3-OZrqJ52p5sbirEpUgjb7hqwLLpd38KU9DCkD24,12217
|
|
@@ -67,16 +68,17 @@ qulab/sys/rpc/server.py,sha256=W3bPwe8um1IeR_3HLx-ad6iCcbeuUQcSg11Ze4w6DJg,742
|
|
|
67
68
|
qulab/sys/rpc/socket.py,sha256=W3bPwe8um1IeR_3HLx-ad6iCcbeuUQcSg11Ze4w6DJg,742
|
|
68
69
|
qulab/sys/rpc/utils.py,sha256=BurIcqh8CS-Hsk1dYP6IiefK4qHivaEqD9_rBY083SA,619
|
|
69
70
|
qulab/sys/rpc/worker.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
71
|
+
qulab/sys/rpc/zmq_socket.py,sha256=Ep4Uy36mV04tkzKtLsRSu5dQ0AT7cPeLhqZxRYgaxTQ,8135
|
|
70
72
|
qulab/visualization/__init__.py,sha256=Bkt9AK5c45d6HFLlT-f8cIppywXziHtJqhDtVxOoKKo,6317
|
|
71
73
|
qulab/visualization/__main__.py,sha256=WduINFl21B-XMsi2rg2cVhIyU11hKKX3zOsjc56QLiQ,1710
|
|
72
|
-
qulab/visualization/_autoplot.py,sha256=
|
|
74
|
+
qulab/visualization/_autoplot.py,sha256=JFLR3e71bryPaUkOCWFzD9C4Nk-ulqIdBb1YN4QnZic,14562
|
|
73
75
|
qulab/visualization/plot_layout.py,sha256=yAnMONOms7_szCdng-8wPpUMPis5UnbaNNzV4KFBgso,13941
|
|
74
76
|
qulab/visualization/plot_seq.py,sha256=h9D0Yl_yO64IwlvBgzMu9EBKr9gg6y8QE55gu2PfTns,2783
|
|
75
77
|
qulab/visualization/qdat.py,sha256=HubXFu4nfcA7iUzghJGle1C86G6221hicLR0b-GqhKQ,5887
|
|
76
78
|
qulab/visualization/widgets.py,sha256=HcYwdhDtLreJiYaZuN3LfofjJmZcLwjMfP5aasebgDo,3266
|
|
77
|
-
QuLab-2.0.
|
|
78
|
-
QuLab-2.0.
|
|
79
|
-
QuLab-2.0.
|
|
80
|
-
QuLab-2.0.
|
|
81
|
-
QuLab-2.0.
|
|
82
|
-
QuLab-2.0.
|
|
79
|
+
QuLab-2.0.3.dist-info/LICENSE,sha256=b4NRQ-GFVpJMT7RuExW3NwhfbrYsX7AcdB7Gudok-fs,1086
|
|
80
|
+
QuLab-2.0.3.dist-info/METADATA,sha256=CBLJJtH8PMO1np50hxS8-Xbs1Bj4lFN1T7AwYCFI47Q,3609
|
|
81
|
+
QuLab-2.0.3.dist-info/WHEEL,sha256=fZWyj_84lK0cA-ZNCsdwhbJl0OTrpWkxInEn424qrSs,102
|
|
82
|
+
QuLab-2.0.3.dist-info/entry_points.txt,sha256=ohBzutEnQimP_BZWiuXdSliu4QAYSHHcN0PZD8c7ZCY,46
|
|
83
|
+
QuLab-2.0.3.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
|
|
84
|
+
QuLab-2.0.3.dist-info/RECORD,,
|
qulab/__main__.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import click
|
|
2
2
|
|
|
3
3
|
from .monitor.__main__ import main as monitor
|
|
4
|
+
from .scan.recorder import record
|
|
4
5
|
from .sys.net.cli import dht
|
|
5
6
|
from .visualization.__main__ import plot
|
|
6
7
|
|
|
@@ -19,6 +20,7 @@ def hello():
|
|
|
19
20
|
main.add_command(monitor)
|
|
20
21
|
main.add_command(plot)
|
|
21
22
|
main.add_command(dht)
|
|
23
|
+
main.add_command(record)
|
|
22
24
|
|
|
23
25
|
if __name__ == '__main__':
|
|
24
26
|
main()
|
qulab/fun.cp312-win_amd64.pyd
CHANGED
|
Binary file
|
qulab/scan/__init__.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from .base import (BaseOptimizer, Begin, End, OptimizerConfig, StepStatus,
|
|
2
|
-
Tracker, scan_iters)
|
|
3
1
|
from .expression import Expression, Symbol
|
|
4
|
-
from .
|
|
2
|
+
from .query_record import get_record, lookup, lookup_list
|
|
3
|
+
from .scan import Scan
|
qulab/scan/curd.py
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
from datetime import date, datetime, timezone
|
|
2
|
+
from typing import Sequence, Type, Union
|
|
3
|
+
|
|
4
|
+
from sqlalchemy.orm import Query, Session, aliased
|
|
5
|
+
from sqlalchemy.orm.exc import NoResultFound
|
|
6
|
+
from sqlalchemy.orm.session import Session
|
|
7
|
+
from waveforms.dicttree import foldDict
|
|
8
|
+
|
|
9
|
+
from .models import Comment, Record, Report, Sample, Tag
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def tag(session: Session, tag_text: str) -> Tag:
|
|
13
|
+
"""Get a tag from the database or create a new if not exists."""
|
|
14
|
+
try:
|
|
15
|
+
return session.query(Tag).filter(Tag.text == tag_text).one()
|
|
16
|
+
except NoResultFound:
|
|
17
|
+
tag = Tag(text=tag_text)
|
|
18
|
+
return tag
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def tag_it(session: Session, tag_text: str, obj: Union[Sample, Record,
|
|
22
|
+
Report]) -> Tag:
|
|
23
|
+
"""Tag an object."""
|
|
24
|
+
if obj.id is None:
|
|
25
|
+
session.add(obj)
|
|
26
|
+
obj.tags.append(tag(session, tag_text))
|
|
27
|
+
else:
|
|
28
|
+
session.query(type(obj)).filter(
|
|
29
|
+
type(obj).id == obj.id).one().tags.append(tag(session, tag_text))
|
|
30
|
+
session.commit()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def get_object_with_tags(session: Session,
|
|
34
|
+
cls: Union[Type[Comment], Type[Sample], Type[Record],
|
|
35
|
+
Type[Report]], *tags: str) -> Query:
|
|
36
|
+
"""
|
|
37
|
+
Query objects with the given tags.
|
|
38
|
+
|
|
39
|
+
Parameters
|
|
40
|
+
----------
|
|
41
|
+
session : :class:`sqlalchemy.orm.Session`
|
|
42
|
+
The database session.
|
|
43
|
+
cls : :class:`sqlalchemy.orm.Mapper`
|
|
44
|
+
The object class.
|
|
45
|
+
tags : str
|
|
46
|
+
The tags.
|
|
47
|
+
|
|
48
|
+
Returns
|
|
49
|
+
-------
|
|
50
|
+
:class:`sqlalchemy.orm.Query`
|
|
51
|
+
The query.
|
|
52
|
+
"""
|
|
53
|
+
if isinstance(session, Query):
|
|
54
|
+
q = session
|
|
55
|
+
else:
|
|
56
|
+
q = session.query(cls)
|
|
57
|
+
if not hasattr(cls, 'tags'):
|
|
58
|
+
return []
|
|
59
|
+
|
|
60
|
+
aliase = {tag: aliased(Tag) for tag in tags}
|
|
61
|
+
|
|
62
|
+
for tag, a in aliase.items():
|
|
63
|
+
q = q.join(a, cls.tags)
|
|
64
|
+
if '*' in tag:
|
|
65
|
+
q = q.filter(a.text.like(tag.replace('*', '%')))
|
|
66
|
+
else:
|
|
67
|
+
q = q.filter(a.text == tag)
|
|
68
|
+
return q
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def query_record(session: Session,
|
|
72
|
+
offset: int = 0,
|
|
73
|
+
limit: int = 10,
|
|
74
|
+
app: str | None = None,
|
|
75
|
+
tags: Sequence[str] = (),
|
|
76
|
+
before: datetime | date | None = None,
|
|
77
|
+
after: datetime | date | None = None):
|
|
78
|
+
tz_offset = datetime.now(timezone.utc).astimezone().utcoffset()
|
|
79
|
+
table = {'header': ['ID', 'App', 'tags', 'created time'], 'body': []}
|
|
80
|
+
apps = sorted(
|
|
81
|
+
set([
|
|
82
|
+
n for n, *_ in get_object_with_tags(session.query(Record.app),
|
|
83
|
+
Record, *tags).all()
|
|
84
|
+
]))
|
|
85
|
+
apps = foldDict(dict([(app, None) for app in apps]))
|
|
86
|
+
|
|
87
|
+
query = get_object_with_tags(session, Record, *tags)
|
|
88
|
+
|
|
89
|
+
if app is not None:
|
|
90
|
+
if app.endswith('*'):
|
|
91
|
+
query = query.filter(Record.app.like(app[:-1] + '%'))
|
|
92
|
+
else:
|
|
93
|
+
query = query.filter(Record.app == app)
|
|
94
|
+
if before is not None:
|
|
95
|
+
if isinstance(before, date):
|
|
96
|
+
before = datetime(before.year, before.month, before.day)
|
|
97
|
+
query = query.filter(Record.ctime <= before - tz_offset)
|
|
98
|
+
if after is not None:
|
|
99
|
+
if isinstance(after, date):
|
|
100
|
+
after = datetime(after.year, after.month, after.day)
|
|
101
|
+
query = query.filter(Record.ctime >= after - tz_offset)
|
|
102
|
+
total = query.count()
|
|
103
|
+
for r in query.order_by(Record.ctime.desc()).limit(limit).offset(offset):
|
|
104
|
+
tags = sorted([t.text for t in r.tags])
|
|
105
|
+
ctime = r.ctime + tz_offset
|
|
106
|
+
row = [r.id, r.app, tags, ctime]
|
|
107
|
+
table['body'].append(row)
|
|
108
|
+
|
|
109
|
+
return total, apps, table
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def update_tags(session: Session,
|
|
113
|
+
record_id: int,
|
|
114
|
+
tags: Sequence[str],
|
|
115
|
+
append: bool = False):
|
|
116
|
+
record = session.get(Record, record_id)
|
|
117
|
+
if record is None:
|
|
118
|
+
return False
|
|
119
|
+
if append:
|
|
120
|
+
old = [t.text for t in record.tags]
|
|
121
|
+
for t in old:
|
|
122
|
+
if t not in tags:
|
|
123
|
+
tags.append(t)
|
|
124
|
+
record.tags = [tag(session, t) for t in tags]
|
|
125
|
+
try:
|
|
126
|
+
session.commit()
|
|
127
|
+
except Exception:
|
|
128
|
+
session.rollback()
|
|
129
|
+
return False
|
|
130
|
+
return True
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def remove_tags(session: Session, record_id: int, tags: Sequence[str]):
|
|
134
|
+
record = session.get(Record, record_id)
|
|
135
|
+
if record is None:
|
|
136
|
+
return False
|
|
137
|
+
old = [t.text for t in record.tags]
|
|
138
|
+
record.tags = [tag(session, t) for t in old if t not in tags]
|
|
139
|
+
try:
|
|
140
|
+
session.commit()
|
|
141
|
+
except Exception:
|
|
142
|
+
session.rollback()
|
|
143
|
+
return False
|
|
144
|
+
return True
|
qulab/scan/expression.py
CHANGED
|
@@ -323,6 +323,14 @@ class UnaryExpression(Expression):
|
|
|
323
323
|
self.a = a
|
|
324
324
|
self.op = op
|
|
325
325
|
|
|
326
|
+
def __getstate__(self) -> dict:
|
|
327
|
+
return {'a': self.a, 'op': self.op}
|
|
328
|
+
|
|
329
|
+
def __setstate__(self, state: dict):
|
|
330
|
+
self.a = state['a']
|
|
331
|
+
self.op = state['op']
|
|
332
|
+
self.cache = _empty
|
|
333
|
+
|
|
326
334
|
def symbols(self) -> list[str]:
|
|
327
335
|
if isinstance(self.a, Expression):
|
|
328
336
|
return self.a.symbols()
|
|
@@ -362,6 +370,15 @@ class BinaryExpression(Expression):
|
|
|
362
370
|
self.b = b
|
|
363
371
|
self.op = op
|
|
364
372
|
|
|
373
|
+
def __getstate__(self) -> dict:
|
|
374
|
+
return {'a': self.a, 'b': self.b, 'op': self.op}
|
|
375
|
+
|
|
376
|
+
def __setstate__(self, state: dict):
|
|
377
|
+
self.a = state['a']
|
|
378
|
+
self.b = state['b']
|
|
379
|
+
self.op = state['op']
|
|
380
|
+
self.cache = _empty
|
|
381
|
+
|
|
365
382
|
def symbols(self) -> list[str]:
|
|
366
383
|
symbs = set()
|
|
367
384
|
if isinstance(self.a, Expression):
|
|
@@ -419,6 +436,15 @@ class ObjectMethod(Expression):
|
|
|
419
436
|
self.method = method
|
|
420
437
|
self.args = args
|
|
421
438
|
|
|
439
|
+
def __getstate__(self) -> dict:
|
|
440
|
+
return {'obj': self.obj, 'method': self.method, 'args': self.args}
|
|
441
|
+
|
|
442
|
+
def __setstate__(self, state: dict):
|
|
443
|
+
self.obj = state['obj']
|
|
444
|
+
self.method = state['method']
|
|
445
|
+
self.args = state['args']
|
|
446
|
+
self.cache = _empty
|
|
447
|
+
|
|
422
448
|
def symbols(self) -> list[str]:
|
|
423
449
|
symbs = set()
|
|
424
450
|
if isinstance(self.obj, Expression):
|
|
@@ -439,7 +465,7 @@ class ObjectMethod(Expression):
|
|
|
439
465
|
return ObjectMethod(obj, self.method, *args)
|
|
440
466
|
else:
|
|
441
467
|
return getattr(obj, self.method)(*args)
|
|
442
|
-
|
|
468
|
+
|
|
443
469
|
def __repr__(self):
|
|
444
470
|
if self.method == '__call__':
|
|
445
471
|
return f"{self.obj!r}({', '.join(map(repr, self.args))})"
|
|
@@ -453,6 +479,13 @@ class Symbol(Expression):
|
|
|
453
479
|
super().__init__()
|
|
454
480
|
self.name = name
|
|
455
481
|
|
|
482
|
+
def __getstate__(self) -> dict:
|
|
483
|
+
return {'name': self.name}
|
|
484
|
+
|
|
485
|
+
def __setstate__(self, state: dict):
|
|
486
|
+
self.name = state['name']
|
|
487
|
+
self.cache = _empty
|
|
488
|
+
|
|
456
489
|
def symbols(self) -> list[str]:
|
|
457
490
|
return [self.name]
|
|
458
491
|
|