labmate 0.9.0__py3-none-any.whl → 0.10.0__py3-none-any.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.
- labmate/__config__.py +1 -1
- labmate/acquisition/acquisition_data.py +1 -1
- labmate/acquisition/acquisition_manager.py +17 -6
- labmate/acquisition/analysis_data.py +4 -2
- labmate/acquisition_notebook/acquisition_analysis_manager.py +40 -19
- labmate/logger/__init__.py +79 -0
- {labmate-0.9.0.dist-info → labmate-0.10.0.dist-info}/METADATA +1 -1
- {labmate-0.9.0.dist-info → labmate-0.10.0.dist-info}/RECORD +11 -11
- {labmate-0.9.0.dist-info → labmate-0.10.0.dist-info}/WHEEL +1 -1
- labmate/acquisition/logger_setup.py +0 -5
- {labmate-0.9.0.dist-info → labmate-0.10.0.dist-info}/LICENCE +0 -0
- {labmate-0.9.0.dist-info → labmate-0.10.0.dist-info}/top_level.txt +0 -0
labmate/__config__.py
CHANGED
|
@@ -26,15 +26,17 @@ class AcquisitionManager:
|
|
|
26
26
|
"""AcquisitionManager."""
|
|
27
27
|
|
|
28
28
|
_data_directory: Path
|
|
29
|
-
config_files = []
|
|
30
|
-
config_files_eval = {}
|
|
29
|
+
config_files: List[str] = []
|
|
30
|
+
config_files_eval: Dict[str, str] = {}
|
|
31
|
+
_configs_last_modified: List[float] = []
|
|
31
32
|
|
|
32
|
-
_current_acquisition = None
|
|
33
|
-
_current_filepath = None
|
|
33
|
+
_current_acquisition: Optional[NotebookAcquisitionData] = None
|
|
34
|
+
_current_filepath: Optional[str] = None
|
|
34
35
|
|
|
35
|
-
_save_files = False
|
|
36
|
-
_save_on_edit = True
|
|
36
|
+
_save_files: bool = False
|
|
37
|
+
_save_on_edit: bool = True
|
|
37
38
|
_init_code = None
|
|
39
|
+
_once_saved: bool
|
|
38
40
|
|
|
39
41
|
cell: Optional[str] = None
|
|
40
42
|
|
|
@@ -54,9 +56,11 @@ class AcquisitionManager:
|
|
|
54
56
|
|
|
55
57
|
self._current_acquisition = None
|
|
56
58
|
self._acquisition_tmp_data = None
|
|
59
|
+
self._once_saved = False
|
|
57
60
|
|
|
58
61
|
self.config_files = []
|
|
59
62
|
self.config_files_eval = {}
|
|
63
|
+
self._configs_last_modified = []
|
|
60
64
|
|
|
61
65
|
if data_directory is not None:
|
|
62
66
|
self.data_directory = Path(data_directory)
|
|
@@ -187,13 +191,19 @@ class AcquisitionManager:
|
|
|
187
191
|
return None
|
|
188
192
|
return AcquisitionTmpData(**jsn.read(path))
|
|
189
193
|
|
|
194
|
+
def _get_configs_last_modified(self) -> List[float]:
|
|
195
|
+
return [os.path.getmtime(file) for file in self.config_files]
|
|
196
|
+
|
|
190
197
|
def new_acquisition(
|
|
191
198
|
self, name: str, cell: Optional[str] = None, save_on_edit: Optional[bool] = None
|
|
192
199
|
) -> NotebookAcquisitionData:
|
|
193
200
|
"""Create a new acquisition with the given experiment name."""
|
|
194
201
|
self._current_acquisition = None
|
|
202
|
+
self._once_saved = False
|
|
195
203
|
self.cell = cell
|
|
196
204
|
configs = read_files(self.config_files)
|
|
205
|
+
self._configs_last_modified = self._get_configs_last_modified()
|
|
206
|
+
|
|
197
207
|
if self.config_files_eval:
|
|
198
208
|
configs = append_values_from_modules_to_files(
|
|
199
209
|
configs, self.config_files_eval
|
|
@@ -310,4 +320,5 @@ class AcquisitionManager:
|
|
|
310
320
|
acq_data.save_additional_info()
|
|
311
321
|
if acq_data.save_on_edit is False:
|
|
312
322
|
acq_data.save()
|
|
323
|
+
self._once_saved = True
|
|
313
324
|
return self
|
|
@@ -6,12 +6,11 @@ from typing import List, Literal, Optional, Protocol, Tuple, TypedDict, TypeVar,
|
|
|
6
6
|
|
|
7
7
|
from dh5 import DH5
|
|
8
8
|
from dh5.path import Path
|
|
9
|
-
from matplotlib.backends.backend_pdf import PdfPages
|
|
10
9
|
|
|
11
10
|
from .. import utils
|
|
11
|
+
from ..logger import logger
|
|
12
12
|
from .analysis_loop import AnalysisLoop
|
|
13
13
|
from .config_file import ConfigFile
|
|
14
|
-
from .logger_setup import logger
|
|
15
14
|
|
|
16
15
|
_T = TypeVar("_T", bound="AnalysisData")
|
|
17
16
|
|
|
@@ -216,6 +215,9 @@ class AnalysisData(DH5):
|
|
|
216
215
|
else:
|
|
217
216
|
if not full_fig_name.endswith(".pdf"):
|
|
218
217
|
raise ValueError("Metadata can be added only to pdf files.")
|
|
218
|
+
|
|
219
|
+
from matplotlib.backends.backend_pdf import PdfPages
|
|
220
|
+
|
|
219
221
|
pdf_fig = PdfPages(full_fig_name)
|
|
220
222
|
fig.savefig(pdf_fig, format="pdf", **kwargs) # type: ignore
|
|
221
223
|
metadata = metadata or {}
|
|
@@ -16,6 +16,7 @@ from typing import (
|
|
|
16
16
|
|
|
17
17
|
from .. import display, utils
|
|
18
18
|
from ..acquisition import AcquisitionManager, AnalysisData
|
|
19
|
+
from ..logger import logger
|
|
19
20
|
from . import display_widget
|
|
20
21
|
|
|
21
22
|
if TYPE_CHECKING:
|
|
@@ -24,19 +25,17 @@ if TYPE_CHECKING:
|
|
|
24
25
|
from ..acquisition import FigureProtocol
|
|
25
26
|
from ..acquisition.config_file import ConfigFile
|
|
26
27
|
|
|
28
|
+
# from ..logger import Logger
|
|
29
|
+
|
|
27
30
|
|
|
28
31
|
logging.basicConfig(format="%(levelname)s:%(message)s", level=logging.INFO)
|
|
29
|
-
logger = logging.getLogger(__name__)
|
|
30
|
-
handler = logging.StreamHandler()
|
|
31
|
-
formatter = logging.Formatter("%(levelname)s:%(message)s")
|
|
32
|
-
handler.setFormatter(formatter)
|
|
33
|
-
logger.addHandler(handler)
|
|
34
|
-
logger.setLevel(logging.INFO)
|
|
35
|
-
logger.propagate = False
|
|
36
32
|
|
|
37
33
|
_CallableWithNoArgs = Callable[[], Any]
|
|
38
34
|
|
|
39
35
|
|
|
36
|
+
CATCH_PRINT = True
|
|
37
|
+
|
|
38
|
+
|
|
40
39
|
class AcquisitionAnalysisManager(AcquisitionManager):
|
|
41
40
|
"""AcquisitionAnalysisManager.
|
|
42
41
|
|
|
@@ -126,6 +125,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
126
125
|
self._save_on_edit_analysis = save_on_edit_analysis
|
|
127
126
|
self._save_fig_inside_h5 = save_fig_inside_h5
|
|
128
127
|
|
|
128
|
+
self._logger = logger
|
|
129
129
|
super().__init__(
|
|
130
130
|
data_directory=str(data_directory),
|
|
131
131
|
config_files=config_files,
|
|
@@ -133,6 +133,10 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
133
133
|
save_on_edit=save_on_edit,
|
|
134
134
|
)
|
|
135
135
|
|
|
136
|
+
@property
|
|
137
|
+
def logger(self):
|
|
138
|
+
return self._logger
|
|
139
|
+
|
|
136
140
|
@property
|
|
137
141
|
def current_acquisition(self):
|
|
138
142
|
"""Return current acquisition if it's not an old data analyses."""
|
|
@@ -240,13 +244,19 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
240
244
|
|
|
241
245
|
def save_acquisition(self, **kwds) -> "AcquisitionAnalysisManager":
|
|
242
246
|
acquisition_finished = time.time()
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
247
|
+
if not self._once_saved:
|
|
248
|
+
additional_info: Dict[str, Any] = {
|
|
249
|
+
"acquisition_duration": acquisition_finished
|
|
250
|
+
- self._acquisition_started,
|
|
251
|
+
"logs": self.logger.getvalue(),
|
|
252
|
+
"prints": self.logger.get_stdout(),
|
|
253
|
+
}
|
|
254
|
+
if self._default_config_files:
|
|
255
|
+
additional_info.update(
|
|
256
|
+
{"default_config_files": self._default_config_files}
|
|
257
|
+
)
|
|
248
258
|
|
|
249
|
-
|
|
259
|
+
kwds.update({"info": additional_info})
|
|
250
260
|
|
|
251
261
|
super().save_acquisition(**kwds)
|
|
252
262
|
self._load_analysis_data()
|
|
@@ -309,10 +319,20 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
309
319
|
self._current_acquisition.current_step = step
|
|
310
320
|
self._current_acquisition.set_cell(cell, step=step)
|
|
311
321
|
self._current_acquisition.save_cell(cell, suffix=str(step))
|
|
322
|
+
configs_modified = self._get_configs_last_modified()
|
|
323
|
+
if configs_modified != self._configs_last_modified:
|
|
324
|
+
raise ValueError(
|
|
325
|
+
"Config files were modified since the previous acquisition step. "
|
|
326
|
+
"Please rerun the acquisition from the first step."
|
|
327
|
+
)
|
|
328
|
+
self.logger.stdout_flush()
|
|
312
329
|
else:
|
|
330
|
+
self.logger.reset()
|
|
313
331
|
self.new_acquisition(name=name, cell=cell, save_on_edit=save_on_edit)
|
|
314
332
|
|
|
315
|
-
logger.info(
|
|
333
|
+
self.logger.info( # pylint: disable=W1203
|
|
334
|
+
f"{step}:{self.current_filepath.basename}"
|
|
335
|
+
)
|
|
316
336
|
|
|
317
337
|
if step == 1:
|
|
318
338
|
utils.run_functions(self._acquisition_cell_prerun_hook)
|
|
@@ -368,7 +388,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
368
388
|
)
|
|
369
389
|
|
|
370
390
|
filename = str(self.current_filepath) # without h5
|
|
371
|
-
logger.info(os.path.basename(filename))
|
|
391
|
+
self.logger.info(os.path.basename(filename))
|
|
372
392
|
|
|
373
393
|
if (
|
|
374
394
|
(not self._is_old_data)
|
|
@@ -408,11 +428,12 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
408
428
|
run_on_call=custom_lint.on_call_functions,
|
|
409
429
|
)
|
|
410
430
|
for var in lint_result.external_vars:
|
|
411
|
-
logger.warning(
|
|
431
|
+
self.logger.warning(
|
|
412
432
|
"External variable used inside the analysis code: %s", var
|
|
413
433
|
)
|
|
414
434
|
for error in lint_result.errors:
|
|
415
|
-
logger.warning(error)
|
|
435
|
+
self.logger.warning(error)
|
|
436
|
+
|
|
416
437
|
utils.run_functions(self._analysis_cell_prerun_hook)
|
|
417
438
|
utils.run_functions(prerun)
|
|
418
439
|
|
|
@@ -537,7 +558,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
537
558
|
|
|
538
559
|
res = self.find_param_in_config(param_text)
|
|
539
560
|
if res is None:
|
|
540
|
-
logger.warning(
|
|
561
|
+
self.logger.warning(
|
|
541
562
|
"Parameter '%s' cannot be found in default config files.", param
|
|
542
563
|
)
|
|
543
564
|
continue
|
|
@@ -558,7 +579,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
|
|
|
558
579
|
param_eq = f"{param.strip()} = "
|
|
559
580
|
res = self.find_param_in_config(param_eq)
|
|
560
581
|
if res is None:
|
|
561
|
-
logger.warning(
|
|
582
|
+
self.logger.warning(
|
|
562
583
|
"Parameter '%s' cannot be found in default config files.", param
|
|
563
584
|
)
|
|
564
585
|
continue
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import logging
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class BufferCatcher(io.StringIO):
|
|
7
|
+
_last_value = None
|
|
8
|
+
|
|
9
|
+
@property
|
|
10
|
+
def last_value(self):
|
|
11
|
+
if self._last_value is None:
|
|
12
|
+
return self.getvalue()
|
|
13
|
+
return self._last_value
|
|
14
|
+
|
|
15
|
+
def close(self) -> None:
|
|
16
|
+
self._last_value = self.getvalue()
|
|
17
|
+
return super().close()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class StreamHandler(logging.StreamHandler):
|
|
21
|
+
stream: io.StringIO
|
|
22
|
+
|
|
23
|
+
def __init__(self, stream=None):
|
|
24
|
+
if stream is None:
|
|
25
|
+
stream = io.StringIO()
|
|
26
|
+
super().__init__(stream)
|
|
27
|
+
|
|
28
|
+
def reset(self):
|
|
29
|
+
self.stream.close()
|
|
30
|
+
stream = io.StringIO()
|
|
31
|
+
self.setStream(stream)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Logger(logging.Logger):
|
|
35
|
+
stdout_message: str
|
|
36
|
+
|
|
37
|
+
def __init__(self, name, level=logging.NOTSET):
|
|
38
|
+
super().__init__(name, level)
|
|
39
|
+
|
|
40
|
+
self.logger_handler = StreamHandler()
|
|
41
|
+
logger_formatter = logging.Formatter(
|
|
42
|
+
"%(name)s:%(filename)s:%(asctime)s:\n%(levelname)s:%(message)s"
|
|
43
|
+
)
|
|
44
|
+
self.logger_handler.setFormatter(logger_formatter)
|
|
45
|
+
self.logger_handler.setLevel(logging.DEBUG)
|
|
46
|
+
self.addHandler(self.logger_handler)
|
|
47
|
+
|
|
48
|
+
logger_handler_short = logging.StreamHandler()
|
|
49
|
+
logger_formatter_short = logging.Formatter("%(levelname)s:%(message)s")
|
|
50
|
+
logger_handler_short.setFormatter(logger_formatter_short)
|
|
51
|
+
logger_handler_short.setLevel(logging.INFO)
|
|
52
|
+
self.addHandler(logger_handler_short)
|
|
53
|
+
|
|
54
|
+
self.propagate = False
|
|
55
|
+
self.stdout_buffer = BufferCatcher()
|
|
56
|
+
self.stdout_message = ""
|
|
57
|
+
|
|
58
|
+
def reset(self):
|
|
59
|
+
self.logger_handler.reset()
|
|
60
|
+
|
|
61
|
+
self.stdout_setup()
|
|
62
|
+
self.stdout_message = ""
|
|
63
|
+
|
|
64
|
+
def stdout_flush(self):
|
|
65
|
+
self.stdout_message += f"\n{self.stdout_buffer.last_value}"
|
|
66
|
+
self.stdout_setup()
|
|
67
|
+
|
|
68
|
+
def stdout_setup(self):
|
|
69
|
+
self.stdout_buffer = BufferCatcher()
|
|
70
|
+
sys.stdout._buffer = self.stdout_buffer # type: ignore # pylint: disable=protected-access
|
|
71
|
+
|
|
72
|
+
def getvalue(self):
|
|
73
|
+
return self.logger_handler.stream.getvalue()
|
|
74
|
+
|
|
75
|
+
def get_stdout(self):
|
|
76
|
+
return self.stdout_message + f"\n{self.stdout_buffer.last_value}"
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
logger = Logger("Labmate")
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
labmate/__config__.py,sha256=
|
|
1
|
+
labmate/__config__.py,sha256=klTEHuAm-AhAQg9qYq-W6YyefUJiHBGfIPWnRQr-eT0,72
|
|
2
2
|
labmate/__init__.py,sha256=aHQiPLldCXIJqz6wwcfyFU9sGLofUR3W5sXBIRzK2n4,182
|
|
3
3
|
labmate/acquisition/__init__.py,sha256=8q3dy18lL32A9y_Du8GggpLgJqDMFcFKddHrySMavrM,269
|
|
4
|
-
labmate/acquisition/acquisition_data.py,sha256=
|
|
4
|
+
labmate/acquisition/acquisition_data.py,sha256=UcpUaT1SkmnqGMyzP8cgH2JjLRtWZZdTk5S0JHf-v9c,6681
|
|
5
5
|
labmate/acquisition/acquisition_loop.py,sha256=fiiseV21GB7pczHSEJrlLPiTSQ2u9y5VMDyCO7Hn0vY,11106
|
|
6
|
-
labmate/acquisition/acquisition_manager.py,sha256=
|
|
7
|
-
labmate/acquisition/analysis_data.py,sha256=
|
|
6
|
+
labmate/acquisition/acquisition_manager.py,sha256=D94ahyQuzsEZdJzEUHJcN2aRwGoVYu4YDMKDCa7JnCU,10992
|
|
7
|
+
labmate/acquisition/analysis_data.py,sha256=svpkOp12iMhBlR7nBgCFQXiOzQtwiQ3v2wXrZNpYdmk,15711
|
|
8
8
|
labmate/acquisition/analysis_loop.py,sha256=1Y8lyPkTCNwskM8DkwrMXSOt0hNmBHcWJaQjdVZ81Hs,5075
|
|
9
9
|
labmate/acquisition/config_file.py,sha256=1WwqaKTM-R5xZQHqqqGUi2QCF0PC1ag2mFgPOJuEdWI,2212
|
|
10
10
|
labmate/acquisition/custom_lint.py,sha256=x4vNoOnbH3A4Odu2DQVtBsuSPo5JfvRpo8_EP0EOmgM,1005
|
|
11
|
-
labmate/acquisition/logger_setup.py,sha256=udTp-0S4cqhGdUGQlk3G3Eg51wePEGraNG-69P9fTOo,129
|
|
12
11
|
labmate/acquisition_notebook/__init__.py,sha256=ZtOGQtmPqEM1IRrL-_JYo4xYA87lFQ5JY5GmKcZz9z0,251
|
|
13
|
-
labmate/acquisition_notebook/acquisition_analysis_manager.py,sha256=
|
|
12
|
+
labmate/acquisition_notebook/acquisition_analysis_manager.py,sha256=cnsaIxgJc0yU1odPbqFY1VCmVVZT9Lwyyt6KWdkC4_U,22615
|
|
14
13
|
labmate/acquisition_notebook/display_widget.py,sha256=yS7KeZ362djhHYFldQMpz8keVT7G2MgHsCmGMlXT81s,6858
|
|
15
14
|
labmate/attrdict/__init__.py,sha256=MvuZVe7j4a0HxGMxim_K2cv-dhqZOfzdeMiTX-SRgDg,58
|
|
16
15
|
labmate/attrdict/attrdict_class.py,sha256=4lKXe7oZo_lLHefmf5vAOKhibWgGDffJcxMhaWLvGs4,4047
|
|
@@ -21,6 +20,7 @@ labmate/display/links.py,sha256=YgCNxowca-oHxqozGWbe4oGLzwltnZ-C0v3E5fQnK0U,746
|
|
|
21
20
|
labmate/display/main.py,sha256=2bjLbRmK5H1PYhtoiyZHzisu6CyQ6AmzlFtEhFZkStg,2354
|
|
22
21
|
labmate/display/platform_utils/__init__.py,sha256=GOWB9vXF-wxGZfdHQJlQWy-hy2V2KXUP3JwxgN91Fq4,1136
|
|
23
22
|
labmate/display/platform_utils/windows_utils.py,sha256=4Z_avuJIZ_KoXkuRZOH2667t2wEljzNBMP6fbNDknuk,3268
|
|
23
|
+
labmate/logger/__init__.py,sha256=Ks4bUNO_rNTFsw0Sh3JAfK1tZq8mqHoqXHP89xpexp0,2177
|
|
24
24
|
labmate/parsing/__init__.py,sha256=AHNB502jlm6PGd49_PJjvSxt97fxJeXnIfXYh8HV5x0,1312
|
|
25
25
|
labmate/parsing/brackets_score.py,sha256=zzup7z6o57YUGeMr5FOSTo3nz9Z62s2omxqFV3M9MmI,988
|
|
26
26
|
labmate/parsing/parsed_value.py,sha256=UYB_gCkV3DiFQRjcprnQUPw--FqYPqb3pii-PQsbHf0,5261
|
|
@@ -33,8 +33,8 @@ labmate/utils/file_read.py,sha256=mRHRIyqejtDlfLuPyafEYcfKfb4bac7zHbt-DW091Vg,31
|
|
|
33
33
|
labmate/utils/lint.py,sha256=7llJbZUAM-ikEpmU_ZzraqOwGUuJPgk1wAf3aYMJdxg,9312
|
|
34
34
|
labmate/utils/random_utils.py,sha256=ZA3gK9P-eTcd_a3BTS_ZeJI5A0GM_GXL7X3yUqnPTO4,690
|
|
35
35
|
labmate/utils/title_parsing.py,sha256=5csdqiD6w6pzyqRon38V2WeGA00CifSrMMtoWZmk0Ok,2644
|
|
36
|
-
labmate-0.
|
|
37
|
-
labmate-0.
|
|
38
|
-
labmate-0.
|
|
39
|
-
labmate-0.
|
|
40
|
-
labmate-0.
|
|
36
|
+
labmate-0.10.0.dist-info/LICENCE,sha256=J9XIxdJExlWYZuxhhKtk4oYILvUz8-JM0y_leRQCKUE,7488
|
|
37
|
+
labmate-0.10.0.dist-info/METADATA,sha256=_8Qsw4NxSoayjiPoPvdunyV-a_ovkwjxYaqThycQvVQ,3211
|
|
38
|
+
labmate-0.10.0.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
|
39
|
+
labmate-0.10.0.dist-info/top_level.txt,sha256=WWAn6t2zNWsp02gRq6f5cSsGebcs-4L6HBFk0XrcY0o,8
|
|
40
|
+
labmate-0.10.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|