labmate 0.10.3__tar.gz → 0.10.5__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.
- {labmate-0.10.3/labmate.egg-info → labmate-0.10.5}/PKG-INFO +13 -2
- labmate-0.10.5/docs/starting_guide/advanced_examples.md +74 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/__config__.py +1 -1
- {labmate-0.10.3 → labmate-0.10.5}/labmate/acquisition/__init__.py +3 -2
- {labmate-0.10.3 → labmate-0.10.5}/labmate/acquisition/acquisition_data.py +18 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/acquisition/acquisition_manager.py +83 -3
- labmate-0.10.5/labmate/acquisition/backend.py +22 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/acquisition_notebook/acquisition_analysis_manager.py +11 -3
- {labmate-0.10.3 → labmate-0.10.5}/labmate/parsing/parsed_value.py +21 -5
- {labmate-0.10.3 → labmate-0.10.5}/labmate/utils/lint.py +2 -1
- {labmate-0.10.3 → labmate-0.10.5/labmate.egg-info}/PKG-INFO +13 -2
- {labmate-0.10.3 → labmate-0.10.5}/labmate.egg-info/SOURCES.txt +1 -0
- labmate-0.10.3/docs/starting_guide/advanced_examples.md +0 -31
- {labmate-0.10.3 → labmate-0.10.5}/LICENCE +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/MANIFEST.in +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/README.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/about.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/acquisition_notebook.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/code/acquisition_loop.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/code/acquisition_manager.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/code/acquisition_notebook_manager.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/code/analysis_data.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/code/linting.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/code/parsing_config.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/examples/acquisition_and_analysis_notebook.ipynb +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/examples/aqm_simple_example.ipynb +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/examples/files/cfg.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/examples/files/dummy_config1.txt +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/examples/files/dummy_config2.txt +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/examples/files/dummy_config3.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/examples/files/init_analyse.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/examples/more/acquisition_and_analysis_notebook_with_magic.ipynb +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/examples/more/h5nparray.ipynb +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/examples/more/loop_example.ipynb +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/h5nparray.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/index.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/releases/0.4.0.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/releases/0.5.0.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/releases/0.6.0.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/releases/0.6.1.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/releases/0.7.0.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/releases/0.8.0.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/releases/index.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/starting_guide/fine_tune.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/starting_guide/first_steps.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/docs/starting_guide/install.md +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/__init__.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/acquisition/acquisition_loop.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/acquisition/analysis_data.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/acquisition/analysis_loop.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/acquisition/config_file.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/acquisition/custom_lint.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/acquisition_notebook/__init__.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/acquisition_notebook/display_widget.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/attrdict/__init__.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/attrdict/attrdict_class.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/display/__init__.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/display/buttons.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/display/html_output.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/display/links.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/display/main.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/display/platform_utils/__init__.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/display/platform_utils/windows_utils.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/logger/__init__.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/parsing/__init__.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/parsing/brackets_score.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/parsing/saving.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/utils/__init__.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/utils/async_utils.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/utils/autoreload.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/utils/errors.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/utils/file_read.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/utils/random_utils.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate/utils/title_parsing.py +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate.egg-info/dependency_links.txt +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate.egg-info/requires.txt +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/labmate.egg-info/top_level.txt +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/requirements-docs.txt +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/requirements.txt +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/setup.cfg +0 -0
- {labmate-0.10.3 → labmate-0.10.5}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: labmate
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.5
|
|
4
4
|
Summary: Data management library to save data and plots to hdf5 files
|
|
5
5
|
Home-page: https://github.com/kyrylo-gr/labmate
|
|
6
6
|
Author: kyrylo.gr | LKB-OMQ
|
|
@@ -21,6 +21,17 @@ Requires-Dist: pytest; extra == "dev"
|
|
|
21
21
|
Requires-Dist: check-manifest; extra == "dev"
|
|
22
22
|
Requires-Dist: sphinx; extra == "dev"
|
|
23
23
|
Requires-Dist: sphinx_rtd_theme; extra == "dev"
|
|
24
|
+
Dynamic: author
|
|
25
|
+
Dynamic: author-email
|
|
26
|
+
Dynamic: classifier
|
|
27
|
+
Dynamic: description
|
|
28
|
+
Dynamic: description-content-type
|
|
29
|
+
Dynamic: home-page
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
Dynamic: provides-extra
|
|
32
|
+
Dynamic: requires-dist
|
|
33
|
+
Dynamic: requires-python
|
|
34
|
+
Dynamic: summary
|
|
24
35
|
|
|
25
36
|
# Labmate. The mate that simplifies data management in your lab.
|
|
26
37
|
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Advanced example
|
|
2
|
+
|
|
3
|
+
## Mode understanding
|
|
4
|
+
|
|
5
|
+
Modes can be set by providing `mode=..` keyword or explicitly by specifying `read_only` and `overwrite` options.
|
|
6
|
+
|
|
7
|
+
'w' mode is the same as
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
>>> sd = DH5('somedata.h5', read_only=False)
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
'a' mode is the same as
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
>>> sd = DH5('somedata.h5', read_only=False, overwrite=False)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
'r' mode is the same as
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
>>> sd = DH5('somedata.h5', read_only=True)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
DH5.open_overwrite method is the same as
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
>>> sd = DH5('somedata.h5', read_only=False, overwrite=True)
|
|
29
|
+
or
|
|
30
|
+
>>> sd = DH5('somedata.h5', mode='w', overwrite=True)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Mirroring acquisitions with a custom backend
|
|
34
|
+
|
|
35
|
+
`AcquisitionManager` accepts an optional `AcquisitionBackend`
|
|
36
|
+
implementation. Backends run in the background every time an acquisition is
|
|
37
|
+
saved and can be used to duplicate the generated HDF5 file (and the companion
|
|
38
|
+
Python/configuration files that Labmate writes next to it) to another location.
|
|
39
|
+
|
|
40
|
+
The example below mirrors every saved acquisition into a second directory. It
|
|
41
|
+
does so by copying the HDF5 file and any file that shares the same stem (e.g.
|
|
42
|
+
`*_CELL.py`, copied configuration files, …) to the mirror folder.
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from pathlib import Path
|
|
46
|
+
import shutil
|
|
47
|
+
|
|
48
|
+
from labmate.acquisition import AcquisitionBackend
|
|
49
|
+
from labmate.acquisition_notebook import AcquisitionAnalysisManager
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class MirrorDirectoryBackend(AcquisitionBackend):
|
|
53
|
+
def __init__(self, mirror_root: str):
|
|
54
|
+
self._mirror_root = Path(mirror_root)
|
|
55
|
+
|
|
56
|
+
def save_snapshot(self, acquisition):
|
|
57
|
+
source_prefix = Path(acquisition.filepath)
|
|
58
|
+
destination_dir = self._mirror_root / source_prefix.parent.name
|
|
59
|
+
destination_dir.mkdir(parents=True, exist_ok=True)
|
|
60
|
+
|
|
61
|
+
# Copy the main HDF5 file and any auxiliary files generated by Labmate.
|
|
62
|
+
for source_path in source_prefix.parent.glob(f"{source_prefix.name}*"):
|
|
63
|
+
shutil.copy2(source_path, destination_dir / source_path.name)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
backend = MirrorDirectoryBackend("/mnt/labmate-mirror")
|
|
67
|
+
aqm = AcquisitionAnalysisManager("/data/labmate", backend=backend)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
When `save_acquisition` (or `save_acquisition` on `AcquisitionAnalysisManager`)
|
|
71
|
+
is called, Labmate will asynchronously copy the freshly written files to the
|
|
72
|
+
mirror directory. Should you need to hydrate new local acquisitions from an
|
|
73
|
+
existing mirror, implement `load_snapshot` in the same backend and perform the
|
|
74
|
+
copy in the opposite direction.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# flake8: noqa: F401
|
|
2
|
-
from .acquisition_manager import AcquisitionManager
|
|
3
|
-
from .acquisition_loop import AcquisitionLoop
|
|
4
2
|
from .acquisition_data import NotebookAcquisitionData
|
|
3
|
+
from .acquisition_loop import AcquisitionLoop
|
|
4
|
+
from .acquisition_manager import AcquisitionManager
|
|
5
|
+
from .backend import AcquisitionBackend
|
|
5
6
|
from .analysis_data import AnalysisData, FigureProtocol
|
|
6
7
|
from .analysis_loop import AnalysisLoop
|
|
@@ -179,3 +179,21 @@ class NotebookAcquisitionData(DH5):
|
|
|
179
179
|
if step is None:
|
|
180
180
|
step = self.current_step
|
|
181
181
|
self._cells[step] = cell
|
|
182
|
+
|
|
183
|
+
def backend_save(self) -> None:
|
|
184
|
+
"""Hook for acquisition backends to serialise custom payloads.
|
|
185
|
+
|
|
186
|
+
Custom backends can override this hook to expose data that should be
|
|
187
|
+
included when persisting to a remote store.
|
|
188
|
+
"""
|
|
189
|
+
|
|
190
|
+
pass
|
|
191
|
+
|
|
192
|
+
def backend_load(self) -> None:
|
|
193
|
+
"""Hook for acquisition backends to hydrate from remote state.
|
|
194
|
+
|
|
195
|
+
Custom backends can override this hook to restore local state after a
|
|
196
|
+
backend has fetched remote payloads.
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
pass
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import os
|
|
2
|
-
from
|
|
2
|
+
from concurrent.futures import Future, ThreadPoolExecutor
|
|
3
|
+
from typing import (
|
|
4
|
+
TYPE_CHECKING,
|
|
5
|
+
Dict,
|
|
6
|
+
List,
|
|
7
|
+
NamedTuple,
|
|
8
|
+
Optional,
|
|
9
|
+
Tuple,
|
|
10
|
+
Union,
|
|
11
|
+
Iterable,
|
|
12
|
+
)
|
|
3
13
|
|
|
4
14
|
from dh5 import jsn
|
|
5
15
|
from dh5.path import Path
|
|
@@ -9,6 +19,9 @@ from ..utils import get_timestamp
|
|
|
9
19
|
from ..utils.file_read import read_file, read_files
|
|
10
20
|
from .acquisition_data import NotebookAcquisitionData
|
|
11
21
|
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from .backend import AcquisitionBackend
|
|
24
|
+
|
|
12
25
|
|
|
13
26
|
class AcquisitionTmpData(NamedTuple):
|
|
14
27
|
"""Temporary data that stores inside temp.json."""
|
|
@@ -40,6 +53,8 @@ class AcquisitionManager:
|
|
|
40
53
|
|
|
41
54
|
cell: Optional[str] = None
|
|
42
55
|
|
|
56
|
+
_backend: Optional[Tuple["AcquisitionBackend", ...]] = None
|
|
57
|
+
|
|
43
58
|
def __init__(
|
|
44
59
|
self,
|
|
45
60
|
data_directory: Optional[Union[str, Path]] = None,
|
|
@@ -47,6 +62,9 @@ class AcquisitionManager:
|
|
|
47
62
|
config_files: Optional[List[str]] = None,
|
|
48
63
|
save_files: Optional[bool] = None,
|
|
49
64
|
save_on_edit: Optional[bool] = None,
|
|
65
|
+
backend: Optional[
|
|
66
|
+
Union["AcquisitionBackend", Iterable["AcquisitionBackend"]]
|
|
67
|
+
] = None,
|
|
50
68
|
):
|
|
51
69
|
if save_files is not None:
|
|
52
70
|
self._save_files = save_files
|
|
@@ -58,6 +76,14 @@ class AcquisitionManager:
|
|
|
58
76
|
self._acquisition_tmp_data = None
|
|
59
77
|
self._once_saved = False
|
|
60
78
|
|
|
79
|
+
self._backend = (
|
|
80
|
+
tuple(backend)
|
|
81
|
+
if isinstance(backend, Iterable)
|
|
82
|
+
else (backend,)
|
|
83
|
+
if backend is not None
|
|
84
|
+
else None
|
|
85
|
+
)
|
|
86
|
+
|
|
61
87
|
self.config_files = []
|
|
62
88
|
self.config_files_eval = {}
|
|
63
89
|
self._configs_last_modified = []
|
|
@@ -198,6 +224,48 @@ class AcquisitionManager:
|
|
|
198
224
|
def _get_configs_last_modified(self) -> List[float]:
|
|
199
225
|
return [os.path.getmtime(file) for file in self.config_files]
|
|
200
226
|
|
|
227
|
+
def _schedule_backend_save(
|
|
228
|
+
self, acquisition: NotebookAcquisitionData
|
|
229
|
+
) -> Optional[Future]:
|
|
230
|
+
if self._backend is None:
|
|
231
|
+
return None
|
|
232
|
+
|
|
233
|
+
executor = ThreadPoolExecutor(max_workers=1)
|
|
234
|
+
|
|
235
|
+
def save_snapshot():
|
|
236
|
+
if self._backend is None:
|
|
237
|
+
return
|
|
238
|
+
for backend in self._backend:
|
|
239
|
+
backend.save_snapshot(acquisition)
|
|
240
|
+
|
|
241
|
+
def shutdown_executor(future: Future):
|
|
242
|
+
executor.shutdown(wait=False)
|
|
243
|
+
|
|
244
|
+
future = executor.submit(save_snapshot)
|
|
245
|
+
future.add_done_callback(shutdown_executor)
|
|
246
|
+
return future
|
|
247
|
+
|
|
248
|
+
def _schedule_backend_load(
|
|
249
|
+
self, acquisition: NotebookAcquisitionData
|
|
250
|
+
) -> Optional[Future]:
|
|
251
|
+
if self._backend is None:
|
|
252
|
+
return None
|
|
253
|
+
|
|
254
|
+
executor = ThreadPoolExecutor(max_workers=1)
|
|
255
|
+
|
|
256
|
+
def load_snapshot():
|
|
257
|
+
if self._backend is None:
|
|
258
|
+
return
|
|
259
|
+
for backend in self._backend:
|
|
260
|
+
backend.load_snapshot(acquisition)
|
|
261
|
+
|
|
262
|
+
def shutdown_executor(future: Future):
|
|
263
|
+
executor.shutdown(wait=False)
|
|
264
|
+
|
|
265
|
+
future = executor.submit(load_snapshot)
|
|
266
|
+
future.add_done_callback(shutdown_executor)
|
|
267
|
+
return future
|
|
268
|
+
|
|
201
269
|
def new_acquisition(
|
|
202
270
|
self, name: str, cell: Optional[str] = None, save_on_edit: Optional[bool] = None
|
|
203
271
|
) -> NotebookAcquisitionData:
|
|
@@ -256,7 +324,7 @@ class AcquisitionManager:
|
|
|
256
324
|
configs = configs if configs else None
|
|
257
325
|
save_on_edit = save_on_edit if save_on_edit is not None else self._save_on_edit
|
|
258
326
|
|
|
259
|
-
|
|
327
|
+
acquisition = NotebookAcquisitionData(
|
|
260
328
|
filepath=str(filepath),
|
|
261
329
|
configs=configs,
|
|
262
330
|
cell=cell or self.cell,
|
|
@@ -264,6 +332,10 @@ class AcquisitionManager:
|
|
|
264
332
|
save_on_edit=save_on_edit,
|
|
265
333
|
save_files=self._save_files,
|
|
266
334
|
)
|
|
335
|
+
# TODO: chech if this gives the expected behaviour
|
|
336
|
+
self._schedule_backend_load(acquisition)
|
|
337
|
+
|
|
338
|
+
return acquisition
|
|
267
339
|
|
|
268
340
|
@property
|
|
269
341
|
def current_acquisition(self) -> NotebookAcquisitionData:
|
|
@@ -301,7 +373,7 @@ class AcquisitionManager:
|
|
|
301
373
|
|
|
302
374
|
save_on_edit = save_on_edit if save_on_edit is not None else self._save_on_edit
|
|
303
375
|
|
|
304
|
-
|
|
376
|
+
acquisition = NotebookAcquisitionData(
|
|
305
377
|
filepath=str(filepath),
|
|
306
378
|
configs=configs,
|
|
307
379
|
cell=cell,
|
|
@@ -311,6 +383,10 @@ class AcquisitionManager:
|
|
|
311
383
|
experiment_name=acquisition_tmp_data.experiment_name,
|
|
312
384
|
)
|
|
313
385
|
|
|
386
|
+
self._schedule_backend_load(acquisition)
|
|
387
|
+
|
|
388
|
+
return acquisition
|
|
389
|
+
|
|
314
390
|
def save_acquisition(self, update_: bool = True, /, **kwds) -> "AcquisitionManager":
|
|
315
391
|
acq_data = self.current_acquisition
|
|
316
392
|
if acq_data is None:
|
|
@@ -329,4 +405,8 @@ class AcquisitionManager:
|
|
|
329
405
|
if acq_data.save_on_edit is False:
|
|
330
406
|
acq_data.save()
|
|
331
407
|
self._once_saved = True
|
|
408
|
+
self._schedule_backend_save(acq_data)
|
|
332
409
|
return self
|
|
410
|
+
|
|
411
|
+
def close(self) -> None:
|
|
412
|
+
pass
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
|
|
4
|
+
if TYPE_CHECKING: # pragma: no cover - imported for typing only
|
|
5
|
+
from .acquisition_data import NotebookAcquisitionData
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AcquisitionBackend:
|
|
9
|
+
"""Lightweight backend interface used by :class:`AcquisitionManager`."""
|
|
10
|
+
|
|
11
|
+
def save_snapshot(self, acquisition: "NotebookAcquisitionData") -> None:
|
|
12
|
+
"""Persist a snapshot of the acquisition remotely."""
|
|
13
|
+
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
def load_snapshot(self, acquisition: "NotebookAcquisitionData") -> None:
|
|
17
|
+
"""Hydrate the acquisition from a remote snapshot."""
|
|
18
|
+
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
__all__ = ["AcquisitionBackend"]
|
{labmate-0.10.3 → labmate-0.10.5}/labmate/acquisition_notebook/acquisition_analysis_manager.py
RENAMED
|
@@ -21,7 +21,7 @@ from . import display_widget
|
|
|
21
21
|
|
|
22
22
|
if TYPE_CHECKING:
|
|
23
23
|
from dh5.path import Path
|
|
24
|
-
|
|
24
|
+
from ..acquisition.backend import AcquisitionBackend
|
|
25
25
|
from ..acquisition import FigureProtocol
|
|
26
26
|
from ..acquisition.config_file import ConfigFile
|
|
27
27
|
|
|
@@ -83,6 +83,9 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
83
83
|
save_on_edit_analysis: Optional[bool] = None,
|
|
84
84
|
save_fig_inside_h5: bool = False,
|
|
85
85
|
shell: Any = True,
|
|
86
|
+
backend: Optional[
|
|
87
|
+
Union["AcquisitionBackend", Iterable["AcquisitionBackend"]]
|
|
88
|
+
] = None,
|
|
86
89
|
):
|
|
87
90
|
"""
|
|
88
91
|
AcquisitionAnalysisManager.
|
|
@@ -131,6 +134,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
131
134
|
config_files=config_files,
|
|
132
135
|
save_files=save_files,
|
|
133
136
|
save_on_edit=save_on_edit,
|
|
137
|
+
backend=backend,
|
|
134
138
|
)
|
|
135
139
|
|
|
136
140
|
@property
|
|
@@ -220,6 +224,10 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
220
224
|
fig = fig or fig_or_name
|
|
221
225
|
self.save_fig_only(fig=fig, name=name, **kwds)
|
|
222
226
|
self.save_analysis_cell(name=name, cell=cell)
|
|
227
|
+
|
|
228
|
+
if self.current_acquisition is not None:
|
|
229
|
+
self._schedule_backend_save(self.current_acquisition)
|
|
230
|
+
|
|
223
231
|
if self._connected_widgets:
|
|
224
232
|
display_widget.display_widgets(
|
|
225
233
|
self._connected_widgets,
|
|
@@ -419,8 +427,8 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
419
427
|
(not self._is_old_data)
|
|
420
428
|
and (self.shell is not None)
|
|
421
429
|
and (
|
|
422
|
-
"acquisition_cell(" in self.shell.last_execution_result.info.raw_cell
|
|
423
|
-
and not self.shell.last_execution_result.success
|
|
430
|
+
"acquisition_cell(" in self.shell.last_execution_result.info.raw_cell # type: ignore
|
|
431
|
+
and not self.shell.last_execution_result.success # type: ignore
|
|
424
432
|
)
|
|
425
433
|
):
|
|
426
434
|
raise ChildProcessError(
|
|
@@ -115,45 +115,61 @@ class ParsedValue:
|
|
|
115
115
|
other = self._convert_other(other)
|
|
116
116
|
return self.value / other # type: ignore
|
|
117
117
|
|
|
118
|
+
def __rtruediv__(self, other):
|
|
119
|
+
other = self._convert_other(other)
|
|
120
|
+
return other / self.value # type: ignore
|
|
121
|
+
|
|
118
122
|
def __floordiv__(self, other):
|
|
119
123
|
other = self._convert_other(other)
|
|
120
124
|
return self.value // other # type: ignore
|
|
121
125
|
|
|
126
|
+
def __rfloordiv__(self, other):
|
|
127
|
+
other = self._convert_other(other)
|
|
128
|
+
return other // self.value # type: ignore
|
|
129
|
+
|
|
122
130
|
def __mod__(self, other):
|
|
123
131
|
other = self._convert_other(other)
|
|
124
132
|
return self.value % other
|
|
125
133
|
|
|
134
|
+
def __rmod__(self, other):
|
|
135
|
+
other = self._convert_other(other)
|
|
136
|
+
return other % self.value
|
|
137
|
+
|
|
126
138
|
def __pow__(self, other):
|
|
127
139
|
other = self._convert_other(other)
|
|
128
140
|
return self.value**other
|
|
129
141
|
|
|
142
|
+
def __rpow__(self, other):
|
|
143
|
+
other = self._convert_other(other)
|
|
144
|
+
return other**self.value
|
|
145
|
+
|
|
130
146
|
def __lt__(self, other):
|
|
131
147
|
other = self._convert_other(other)
|
|
132
148
|
if isinstance(self.value, complex):
|
|
133
149
|
raise TypeError("Cannot compare complex values")
|
|
134
|
-
return self.value
|
|
150
|
+
return self.value < other
|
|
135
151
|
|
|
136
152
|
def __gt__(self, other):
|
|
137
153
|
other = self._convert_other(other)
|
|
138
154
|
if isinstance(self.value, complex):
|
|
139
155
|
raise TypeError("Cannot compare complex values")
|
|
140
|
-
return self.value
|
|
156
|
+
return self.value > other
|
|
141
157
|
|
|
142
158
|
def __le__(self, other):
|
|
143
159
|
other = self._convert_other(other)
|
|
144
160
|
if isinstance(self.value, complex):
|
|
145
161
|
raise TypeError("Cannot compare complex values")
|
|
146
|
-
return self.value
|
|
162
|
+
return self.value <= other
|
|
147
163
|
|
|
148
164
|
def __ge__(self, other):
|
|
149
165
|
other = self._convert_other(other)
|
|
150
166
|
if isinstance(self.value, complex):
|
|
151
167
|
raise TypeError("Cannot compare complex values")
|
|
152
|
-
return self.value
|
|
168
|
+
return self.value >= other
|
|
153
169
|
|
|
154
170
|
def __ne__(self, other):
|
|
155
171
|
other = self._convert_other(other)
|
|
156
|
-
return self.value
|
|
172
|
+
return self.value != other
|
|
157
173
|
|
|
158
174
|
@property
|
|
159
175
|
def is_complex(self):
|
|
@@ -137,6 +137,7 @@ class NameVisitor(ast.NodeVisitor):
|
|
|
137
137
|
|
|
138
138
|
if isinstance(node, ast.FunctionDef):
|
|
139
139
|
variables = get_all_args_from_def(node.args)
|
|
140
|
+
self.local_vars.add(node.name)
|
|
140
141
|
node.dont_parse = variables # type: ignore
|
|
141
142
|
|
|
142
143
|
if isinstance(node, ast.Lambda):
|
|
@@ -241,7 +242,7 @@ def find_variables_from_code(
|
|
|
241
242
|
set(),
|
|
242
243
|
[
|
|
243
244
|
"Syntax error is found during linting. Probably because #noqa is used. "
|
|
244
|
-
"#noqa removes line from the
|
|
245
|
+
"#noqa removes line from the analysis, so don't use it with line breaks.\n"
|
|
245
246
|
f"Error at line {exception.lineno} in {exception.text}"
|
|
246
247
|
],
|
|
247
248
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: labmate
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.5
|
|
4
4
|
Summary: Data management library to save data and plots to hdf5 files
|
|
5
5
|
Home-page: https://github.com/kyrylo-gr/labmate
|
|
6
6
|
Author: kyrylo.gr | LKB-OMQ
|
|
@@ -21,6 +21,17 @@ Requires-Dist: pytest; extra == "dev"
|
|
|
21
21
|
Requires-Dist: check-manifest; extra == "dev"
|
|
22
22
|
Requires-Dist: sphinx; extra == "dev"
|
|
23
23
|
Requires-Dist: sphinx_rtd_theme; extra == "dev"
|
|
24
|
+
Dynamic: author
|
|
25
|
+
Dynamic: author-email
|
|
26
|
+
Dynamic: classifier
|
|
27
|
+
Dynamic: description
|
|
28
|
+
Dynamic: description-content-type
|
|
29
|
+
Dynamic: home-page
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
Dynamic: provides-extra
|
|
32
|
+
Dynamic: requires-dist
|
|
33
|
+
Dynamic: requires-python
|
|
34
|
+
Dynamic: summary
|
|
24
35
|
|
|
25
36
|
# Labmate. The mate that simplifies data management in your lab.
|
|
26
37
|
|
|
@@ -48,6 +48,7 @@ labmate/acquisition/acquisition_loop.py
|
|
|
48
48
|
labmate/acquisition/acquisition_manager.py
|
|
49
49
|
labmate/acquisition/analysis_data.py
|
|
50
50
|
labmate/acquisition/analysis_loop.py
|
|
51
|
+
labmate/acquisition/backend.py
|
|
51
52
|
labmate/acquisition/config_file.py
|
|
52
53
|
labmate/acquisition/custom_lint.py
|
|
53
54
|
labmate/acquisition_notebook/__init__.py
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# Advanced example
|
|
2
|
-
|
|
3
|
-
## Mode understanding
|
|
4
|
-
|
|
5
|
-
Modes can be set by providing `mode=..` keyword or explicitly by specifying `read_only` and `overwrite` options.
|
|
6
|
-
|
|
7
|
-
'w' mode is the same as
|
|
8
|
-
|
|
9
|
-
```python
|
|
10
|
-
>>> sd = DH5('somedata.h5', read_only=False)
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
'a' mode is the same as
|
|
14
|
-
|
|
15
|
-
```python
|
|
16
|
-
>>> sd = DH5('somedata.h5', read_only=False, overwrite=False)
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
'r' mode is the same as
|
|
20
|
-
|
|
21
|
-
```python
|
|
22
|
-
>>> sd = DH5('somedata.h5', read_only=True)
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
DH5.open_overwrite method is the same as
|
|
26
|
-
|
|
27
|
-
```python
|
|
28
|
-
>>> sd = DH5('somedata.h5', read_only=False, overwrite=True)
|
|
29
|
-
or
|
|
30
|
-
>>> sd = DH5('somedata.h5', mode='w', overwrite=True)
|
|
31
|
-
```
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|