labmate 0.8.2__tar.gz → 0.8.4__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.
Files changed (79) hide show
  1. {labmate-0.8.2/labmate.egg-info → labmate-0.8.4}/PKG-INFO +1 -1
  2. {labmate-0.8.2 → labmate-0.8.4}/labmate/__config__.py +1 -1
  3. {labmate-0.8.2 → labmate-0.8.4}/labmate/acquisition/acquisition_data.py +47 -8
  4. {labmate-0.8.2 → labmate-0.8.4}/labmate/acquisition/acquisition_loop.py +1 -3
  5. {labmate-0.8.2 → labmate-0.8.4}/labmate/acquisition/acquisition_manager.py +32 -10
  6. {labmate-0.8.2 → labmate-0.8.4}/labmate/acquisition/analysis_data.py +36 -18
  7. {labmate-0.8.2 → labmate-0.8.4}/labmate/acquisition/analysis_loop.py +4 -2
  8. {labmate-0.8.2 → labmate-0.8.4}/labmate/acquisition/custom_lint.py +4 -1
  9. {labmate-0.8.2 → labmate-0.8.4}/labmate/acquisition_notebook/acquisition_analysis_manager.py +53 -15
  10. {labmate-0.8.2 → labmate-0.8.4}/labmate/acquisition_notebook/display_widget.py +3 -3
  11. {labmate-0.8.2 → labmate-0.8.4}/labmate/attrdict/attrdict_class.py +15 -11
  12. {labmate-0.8.2 → labmate-0.8.4}/labmate/display/__init__.py +6 -5
  13. {labmate-0.8.2 → labmate-0.8.4}/labmate/display/platform_utils/windows_utils.py +11 -5
  14. {labmate-0.8.2 → labmate-0.8.4}/labmate/parsing/saving.py +8 -2
  15. {labmate-0.8.2 → labmate-0.8.4}/labmate/utils/lint.py +4 -1
  16. {labmate-0.8.2 → labmate-0.8.4}/labmate/utils/random_utils.py +6 -2
  17. {labmate-0.8.2 → labmate-0.8.4}/labmate/utils/title_parsing.py +7 -2
  18. {labmate-0.8.2 → labmate-0.8.4/labmate.egg-info}/PKG-INFO +1 -1
  19. {labmate-0.8.2 → labmate-0.8.4}/LICENCE +0 -0
  20. {labmate-0.8.2 → labmate-0.8.4}/MANIFEST.in +0 -0
  21. {labmate-0.8.2 → labmate-0.8.4}/README.md +0 -0
  22. {labmate-0.8.2 → labmate-0.8.4}/docs/about.md +0 -0
  23. {labmate-0.8.2 → labmate-0.8.4}/docs/acquisition_notebook.md +0 -0
  24. {labmate-0.8.2 → labmate-0.8.4}/docs/code/acquisition_loop.md +0 -0
  25. {labmate-0.8.2 → labmate-0.8.4}/docs/code/acquisition_manager.md +0 -0
  26. {labmate-0.8.2 → labmate-0.8.4}/docs/code/acquisition_notebook_manager.md +0 -0
  27. {labmate-0.8.2 → labmate-0.8.4}/docs/code/analysis_data.md +0 -0
  28. {labmate-0.8.2 → labmate-0.8.4}/docs/code/linting.md +0 -0
  29. {labmate-0.8.2 → labmate-0.8.4}/docs/code/parsing_config.md +0 -0
  30. {labmate-0.8.2 → labmate-0.8.4}/docs/examples/acquisition_and_analysis_notebook.ipynb +0 -0
  31. {labmate-0.8.2 → labmate-0.8.4}/docs/examples/aqm_simple_example.ipynb +0 -0
  32. {labmate-0.8.2 → labmate-0.8.4}/docs/examples/files/cfg.py +0 -0
  33. {labmate-0.8.2 → labmate-0.8.4}/docs/examples/files/dummy_config1.txt +0 -0
  34. {labmate-0.8.2 → labmate-0.8.4}/docs/examples/files/dummy_config2.txt +0 -0
  35. {labmate-0.8.2 → labmate-0.8.4}/docs/examples/files/dummy_config3.py +0 -0
  36. {labmate-0.8.2 → labmate-0.8.4}/docs/examples/files/init_analyse.py +0 -0
  37. {labmate-0.8.2 → labmate-0.8.4}/docs/examples/more/acquisition_and_analysis_notebook_with_magic.ipynb +0 -0
  38. {labmate-0.8.2 → labmate-0.8.4}/docs/examples/more/h5nparray.ipynb +0 -0
  39. {labmate-0.8.2 → labmate-0.8.4}/docs/examples/more/loop_example.ipynb +0 -0
  40. {labmate-0.8.2 → labmate-0.8.4}/docs/h5nparray.md +0 -0
  41. {labmate-0.8.2 → labmate-0.8.4}/docs/index.md +0 -0
  42. {labmate-0.8.2 → labmate-0.8.4}/docs/releases/0.4.0.md +0 -0
  43. {labmate-0.8.2 → labmate-0.8.4}/docs/releases/0.5.0.md +0 -0
  44. {labmate-0.8.2 → labmate-0.8.4}/docs/releases/0.6.0.md +0 -0
  45. {labmate-0.8.2 → labmate-0.8.4}/docs/releases/0.6.1.md +0 -0
  46. {labmate-0.8.2 → labmate-0.8.4}/docs/releases/0.7.0.md +0 -0
  47. {labmate-0.8.2 → labmate-0.8.4}/docs/releases/0.8.0.md +0 -0
  48. {labmate-0.8.2 → labmate-0.8.4}/docs/releases/index.md +0 -0
  49. {labmate-0.8.2 → labmate-0.8.4}/docs/starting_guide/advanced_examples.md +0 -0
  50. {labmate-0.8.2 → labmate-0.8.4}/docs/starting_guide/fine_tune.md +0 -0
  51. {labmate-0.8.2 → labmate-0.8.4}/docs/starting_guide/first_steps.md +0 -0
  52. {labmate-0.8.2 → labmate-0.8.4}/docs/starting_guide/install.md +0 -0
  53. {labmate-0.8.2 → labmate-0.8.4}/labmate/__init__.py +0 -0
  54. {labmate-0.8.2 → labmate-0.8.4}/labmate/acquisition/__init__.py +0 -0
  55. {labmate-0.8.2 → labmate-0.8.4}/labmate/acquisition/config_file.py +0 -0
  56. {labmate-0.8.2 → labmate-0.8.4}/labmate/acquisition/logger_setup.py +0 -0
  57. {labmate-0.8.2 → labmate-0.8.4}/labmate/acquisition_notebook/__init__.py +0 -0
  58. {labmate-0.8.2 → labmate-0.8.4}/labmate/attrdict/__init__.py +0 -0
  59. {labmate-0.8.2 → labmate-0.8.4}/labmate/display/buttons.py +0 -0
  60. {labmate-0.8.2 → labmate-0.8.4}/labmate/display/html_output.py +0 -0
  61. {labmate-0.8.2 → labmate-0.8.4}/labmate/display/links.py +0 -0
  62. {labmate-0.8.2 → labmate-0.8.4}/labmate/display/main.py +0 -0
  63. {labmate-0.8.2 → labmate-0.8.4}/labmate/display/platform_utils/__init__.py +0 -0
  64. {labmate-0.8.2 → labmate-0.8.4}/labmate/parsing/__init__.py +0 -0
  65. {labmate-0.8.2 → labmate-0.8.4}/labmate/parsing/brackets_score.py +0 -0
  66. {labmate-0.8.2 → labmate-0.8.4}/labmate/parsing/parsed_value.py +0 -0
  67. {labmate-0.8.2 → labmate-0.8.4}/labmate/utils/__init__.py +0 -0
  68. {labmate-0.8.2 → labmate-0.8.4}/labmate/utils/async_utils.py +0 -0
  69. {labmate-0.8.2 → labmate-0.8.4}/labmate/utils/autoreload.py +0 -0
  70. {labmate-0.8.2 → labmate-0.8.4}/labmate/utils/errors.py +0 -0
  71. {labmate-0.8.2 → labmate-0.8.4}/labmate/utils/file_read.py +0 -0
  72. {labmate-0.8.2 → labmate-0.8.4}/labmate.egg-info/SOURCES.txt +0 -0
  73. {labmate-0.8.2 → labmate-0.8.4}/labmate.egg-info/dependency_links.txt +0 -0
  74. {labmate-0.8.2 → labmate-0.8.4}/labmate.egg-info/requires.txt +0 -0
  75. {labmate-0.8.2 → labmate-0.8.4}/labmate.egg-info/top_level.txt +0 -0
  76. {labmate-0.8.2 → labmate-0.8.4}/requirements-docs.txt +0 -0
  77. {labmate-0.8.2 → labmate-0.8.4}/requirements.txt +0 -0
  78. {labmate-0.8.2 → labmate-0.8.4}/setup.cfg +0 -0
  79. {labmate-0.8.2 → labmate-0.8.4}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: labmate
3
- Version: 0.8.2
3
+ Version: 0.8.4
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
@@ -1,3 +1,3 @@
1
1
  """This file contains all package constants."""
2
2
 
3
- __version__ = "0.8.2"
3
+ __version__ = "0.8.4"
@@ -1,9 +1,10 @@
1
1
  """Module that contains NotebookAcquisitionData class."""
2
+
2
3
  from typing import Dict, List, Optional, Union
3
4
 
4
5
  from dh5 import DH5
5
- from ..utils.file_read import read_files
6
6
 
7
+ from ..utils.file_read import read_files
7
8
  from .logger_setup import logger
8
9
 
9
10
 
@@ -14,6 +15,9 @@ class NotebookAcquisitionData(DH5):
14
15
  `cell` is a str. It saves using `save_cell` function that will save it to `..._CELL.py` file
15
16
  """
16
17
 
18
+ _current_step: int
19
+ _cells: Dict[int, Optional[str]]
20
+
17
21
  def __init__(
18
22
  self,
19
23
  filepath: str,
@@ -58,10 +62,11 @@ class NotebookAcquisitionData(DH5):
58
62
  self._config = configs
59
63
  self.save_configs()
60
64
 
61
- self._cell = cell
62
- self.save_cell(cell=cell)
65
+ self._cells = {1: cell}
66
+ self.save_cell(cell=cell, suffix="1")
63
67
 
64
68
  self.experiment_name = experiment_name
69
+ self.current_step = 1
65
70
 
66
71
  self["useful"] = False
67
72
 
@@ -95,7 +100,12 @@ class NotebookAcquisitionData(DH5):
95
100
  with open(filepath + "_" + name, "w", encoding="utf-8") as file:
96
101
  file.write(value)
97
102
 
98
- def save_cell(self, cell: Optional[str] = None, filepath: Optional[str] = None):
103
+ def save_cell(
104
+ self,
105
+ cell: Optional[str] = None,
106
+ filepath: Optional[str] = None,
107
+ suffix: Optional[str] = None,
108
+ ):
99
109
  """Save the cell code to the h5 file and possibly to a file.
100
110
 
101
111
  If `save_files` during init was set to True, then it will create a '.py' file near
@@ -108,14 +118,15 @@ class NotebookAcquisitionData(DH5):
108
118
  the desired location, i.e. it should end with the file prefix to which the suffix and
109
119
  'py' extension will be added. Defaults to save filepath as h5 file.
110
120
  """
111
- cell = cell or self._cell
112
121
  if cell == "none":
113
122
  return
114
123
  if cell is None or cell == "":
115
124
  logger.warning("Acquisition cell is not set. Nothing to save")
116
125
  return
117
-
118
- self["acquisition_cell"] = cell
126
+ if suffix is not None:
127
+ self[f"acquisition_cell/{suffix}"] = cell
128
+ else:
129
+ self["acquisition_cell/0"] = cell
119
130
 
120
131
  if not self._save_files:
121
132
  return
@@ -124,13 +135,26 @@ class NotebookAcquisitionData(DH5):
124
135
  with open(filepath + "_CELL.py", "w", encoding="utf-8") as file:
125
136
  file.write(cell)
126
137
 
138
+ def save_cells(
139
+ self,
140
+ cells: Optional[Dict[int, Optional[str]]] = None,
141
+ filepath: Optional[str] = None,
142
+ ):
143
+ """Save all sells that are provided or pushed into self._cells array."""
144
+ cells = cells or self._cells
145
+ # if len(cells) == 1:
146
+ # self.save_cell(cells.popitem()[1], filepath)
147
+ # return
148
+ for i, cell in cells.items():
149
+ self.save_cell(cell, filepath, suffix=str(i))
150
+
127
151
  def save_additional_info(self):
128
152
  """Save all additional information, i.e. cell code, configs. Put useful key to True."""
129
153
  self["useful"] = True
130
154
 
131
155
  if not self._save_files:
132
156
  return
133
- self.save_cell()
157
+ self.save_cells()
134
158
  self.save_configs()
135
159
 
136
160
  def save_acquisition(self, **kwds) -> "NotebookAcquisitionData":
@@ -140,3 +164,18 @@ class NotebookAcquisitionData(DH5):
140
164
  if self.save_on_edit is False:
141
165
  self.save()
142
166
  return self
167
+
168
+ @property
169
+ def current_step(self):
170
+ """Return the current step of the acquisition."""
171
+ return self._current_step
172
+
173
+ @current_step.setter
174
+ def current_step(self, value: int):
175
+ self._current_step = value
176
+
177
+ def set_cell(self, cell: Optional[str], step: Optional[int] = None):
178
+ """Set the cell code."""
179
+ if step is None:
180
+ step = self.current_step
181
+ self._cells[step] = cell
@@ -185,9 +185,7 @@ class AcquisitionLoop(DH5):
185
185
  )
186
186
  self[key][iteration] = value
187
187
  else:
188
- if isinstance(value, (complex, np.complex_)) or ( # type: ignore
189
- isinstance(value, (np.ndarray,)) and value.dtype == np.complex_
190
- ):
188
+ if np.iscomplexobj(value):
191
189
  self[key] = SyncNp(np.zeros(key_shape, dtype=np.complex128))
192
190
  else:
193
191
  self[key] = SyncNp(np.zeros(key_shape))
@@ -104,9 +104,13 @@ class AcquisitionManager:
104
104
  configs: dict of configurations files to save
105
105
  directory: directory where the data is stored
106
106
  """
107
- acquisition_tmp_data = self._acquisition_tmp_data or self.get_temp_data(self.temp_file_path)
107
+ acquisition_tmp_data = self._acquisition_tmp_data or self.get_temp_data(
108
+ self.temp_file_path
109
+ )
108
110
  if acquisition_tmp_data is None:
109
- raise ValueError("You should create a new acquisition. It will create temp.json file.")
111
+ raise ValueError(
112
+ "You should create a new acquisition. It will create temp.json file."
113
+ )
110
114
  return acquisition_tmp_data
111
115
 
112
116
  @acquisition_tmp_data.setter
@@ -122,11 +126,15 @@ class AcquisitionManager:
122
126
  self, filename: Union[str, List[str], Tuple[str, ...]]
123
127
  ) -> "AcquisitionManager":
124
128
  """Set self.config_file to filename. Verify if exists.
125
- Only set config file for future acquisition and will not change current acquisition"""
129
+ Only set config file for future acquisition and will not change current acquisition
130
+ """
126
131
  if not isinstance(filename, (list, set, tuple)):
127
132
  filename = [str(filename)]
128
133
 
129
134
  self.config_files = list(filename)
135
+ self._config_files_names_to_path = {
136
+ os.path.basename(file): file for file in self.config_files
137
+ }
130
138
 
131
139
  for config_file in self.config_files:
132
140
  if not os.path.exists(config_file):
@@ -156,9 +164,13 @@ class AcquisitionManager:
156
164
  if not experiment_path.exists():
157
165
  experiment_path.makedirs()
158
166
  if self._init_code and not os.path.exists(experiment_path / "init_analyse.py"):
159
- with open(experiment_path / "init_analyse.py", "w", encoding="utf-8") as file:
167
+ with open(
168
+ experiment_path / "init_analyse.py", "w", encoding="utf-8"
169
+ ) as file:
160
170
  file.write(self._init_code)
161
- filepath_original = filepath = experiment_path / f"{dic.time_stamp}__{dic.experiment_name}"
171
+ filepath_original = filepath = (
172
+ experiment_path / f"{dic.time_stamp}__{dic.experiment_name}"
173
+ )
162
174
  if ignore_existence:
163
175
  return filepath
164
176
 
@@ -183,7 +195,9 @@ class AcquisitionManager:
183
195
  self.cell = cell
184
196
  configs = read_files(self.config_files)
185
197
  if self.config_files_eval:
186
- configs = append_values_from_modules_to_files(configs, self.config_files_eval)
198
+ configs = append_values_from_modules_to_files(
199
+ configs, self.config_files_eval
200
+ )
187
201
 
188
202
  dic = AcquisitionTmpData(
189
203
  experiment_name=name,
@@ -194,7 +208,9 @@ class AcquisitionManager:
194
208
 
195
209
  self.acquisition_tmp_data = dic
196
210
 
197
- self._current_acquisition = self.get_acquisition(replace=True, save_on_edit=save_on_edit)
211
+ self._current_acquisition = self.get_acquisition(
212
+ replace=True, save_on_edit=save_on_edit
213
+ )
198
214
 
199
215
  return self.current_acquisition
200
216
 
@@ -208,7 +224,9 @@ class AcquisitionManager:
208
224
  configs = read_files(self.config_files)
209
225
 
210
226
  if self.config_files_eval:
211
- configs = append_values_from_modules_to_files(configs, self.config_files_eval)
227
+ configs = append_values_from_modules_to_files(
228
+ configs, self.config_files_eval
229
+ )
212
230
 
213
231
  if name is None:
214
232
  name = self.current_experiment_name + "_item"
@@ -252,13 +270,17 @@ class AcquisitionManager:
252
270
 
253
271
  @property
254
272
  def current_experiment_name(self) -> str:
255
- return self.acquisition_tmp_data.experiment_name # self.current_acquisition.name
273
+ return (
274
+ self.acquisition_tmp_data.experiment_name
275
+ ) # self.current_acquisition.name
256
276
 
257
277
  def get_acquisition(
258
278
  self, replace: Optional[bool] = False, save_on_edit: Optional[bool] = None
259
279
  ) -> NotebookAcquisitionData:
260
280
  acquisition_tmp_data = self.acquisition_tmp_data
261
- filepath = self.create_path_from_tmp_data(acquisition_tmp_data, ignore_existence=True)
281
+ filepath = self.create_path_from_tmp_data(
282
+ acquisition_tmp_data, ignore_existence=True
283
+ )
262
284
  configs = acquisition_tmp_data.configs
263
285
  configs = configs if configs else None
264
286
  cell = self.cell
@@ -1,15 +1,14 @@
1
1
  """AnalysisData class."""
2
+
2
3
  import os
3
4
  from typing import List, Literal, Optional, Protocol, Tuple, TypeVar, Union
4
5
 
5
-
6
6
  from dh5 import DH5
7
7
  from dh5.path import Path
8
8
 
9
+ from .. import utils
9
10
  from .analysis_loop import AnalysisLoop
10
-
11
11
  from .config_file import ConfigFile
12
- from .. import utils
13
12
  from .logger_setup import logger
14
13
 
15
14
  _T = TypeVar("_T", bound="AnalysisData")
@@ -95,7 +94,10 @@ class AnalysisData(DH5):
95
94
  raise ValueError(f"File '{filepath}' does not exist.")
96
95
 
97
96
  super().__init__(
98
- filepath=filepath, overwrite=False, read_only=False, save_on_edit=save_on_edit
97
+ filepath=filepath,
98
+ overwrite=False,
99
+ read_only=False,
100
+ save_on_edit=save_on_edit,
99
101
  )
100
102
 
101
103
  self.lock_data()
@@ -146,9 +148,9 @@ class AnalysisData(DH5):
146
148
  logger.warning("Analysis cell is not set. Nothing to save")
147
149
  return self
148
150
 
149
- self.unlock_data(cell_name_key).update({cell_name_key: code}).lock_data(cell_name_key).save(
150
- [cell_name_key]
151
- )
151
+ self.unlock_data(cell_name_key).update({cell_name_key: code}).lock_data(
152
+ cell_name_key
153
+ ).save([cell_name_key])
152
154
 
153
155
  if self._save_files:
154
156
  assert self.filepath, "You must set self.filepath before saving"
@@ -185,13 +187,18 @@ class AnalysisData(DH5):
185
187
  "inside_h5", False
186
188
  ):
187
189
  try:
188
- import pltsave
190
+ raise NotImplementedError(
191
+ "save_fig_inside_h5 is not implemented for the moment."
192
+ )
193
+ # import pltsave
189
194
 
190
- data = pltsave.dumps(fig).to_json()
191
- self[f"figures/{fig_name}"] = data
192
- self.save([f"figures/{fig_name}"])
195
+ # data = pltsave.dumps(fig).to_json()
196
+ # self[f"figures/{fig_name}"] = data
197
+ # self.save([f"figures/{fig_name}"])
193
198
  except Exception as error:
194
- logger.exception("Failed to save the figure inside h5 file due to %s", error)
199
+ logger.exception(
200
+ "Failed to save the figure inside h5 file due to %s", error
201
+ )
195
202
  if tight_layout and hasattr(fig, "tight_layout"):
196
203
  fig.tight_layout() # type: ignore
197
204
  fig.savefig(full_fig_name, **kwargs)
@@ -229,7 +236,9 @@ class AnalysisData(DH5):
229
236
 
230
237
  return "FIG" + name
231
238
 
232
- def parse_config(self, config_files: Optional[Tuple[str, ...]] = None) -> "ConfigFile":
239
+ def parse_config(
240
+ self, config_files: Optional[Tuple[str, ...]] = None
241
+ ) -> "ConfigFile":
233
242
  """Parse config files. If `config_files` are not provided takes `default_config_files`."""
234
243
 
235
244
  config_files = config_files or self._default_config_files
@@ -240,7 +249,8 @@ class AnalysisData(DH5):
240
249
  return self._parsed_configs[hash(config_files)]
241
250
 
242
251
  config_data = sum(
243
- (self.parse_config_file(config_file) for config_file in config_files), ConfigFile()
252
+ (self.parse_config_file(config_file) for config_file in config_files),
253
+ ConfigFile(),
244
254
  )
245
255
 
246
256
  self._parsed_configs[hash(config_files)] = config_data
@@ -263,7 +273,9 @@ class AnalysisData(DH5):
263
273
  if key_value == "filename" or key_value == "file" or key_value == "f":
264
274
  filename = os.path.split(self.filepath)[-1]
265
275
  keys_with_values.append(
266
- utils.title_parsing.ValueForPrint(key_value, filename, key_units, key_format)
276
+ utils.title_parsing.ValueForPrint(
277
+ key_value, filename, key_units, key_format
278
+ )
267
279
  )
268
280
  elif key_value in config_data:
269
281
  keys_with_values.append(
@@ -316,7 +328,9 @@ class AnalysisData(DH5):
316
328
  )
317
329
 
318
330
  if config_file_name in self._parsed_configs:
319
- self._parsed_configs[original_config_name] = self._parsed_configs[config_file_name]
331
+ self._parsed_configs[original_config_name] = self._parsed_configs[
332
+ config_file_name
333
+ ]
320
334
  return self._parsed_configs[config_file_name]
321
335
 
322
336
  else:
@@ -339,7 +353,9 @@ class AnalysisData(DH5):
339
353
  (config_files,) if isinstance(config_files, str) else tuple(config_files)
340
354
  )
341
355
 
342
- def get_analysis_code(self, name: str = "default", /, update_code: bool = True) -> str:
356
+ def get_analysis_code(
357
+ self, name: str = "default", /, update_code: bool = True
358
+ ) -> str:
343
359
  code: Optional[dict] = self.get("analysis_cells")
344
360
  if code is None:
345
361
  raise ValueError(
@@ -350,7 +366,9 @@ class AnalysisData(DH5):
350
366
  # if isinstance(code, bytes):
351
367
  # code = code.decode()
352
368
  if name not in code:
353
- raise KeyError(f"Cannot get cell '{name}'. Possible cells are: {tuple(code.keys())}")
369
+ raise KeyError(
370
+ f"Cannot get cell '{name}'. Possible cells are: {tuple(code.keys())}"
371
+ )
354
372
 
355
373
  code_str: str = code[name]
356
374
  if update_code:
@@ -2,7 +2,7 @@
2
2
  It has mainly __iter__ method and __getitem__ method for slicing.
3
3
  """
4
4
 
5
- from typing import Any, List, Optional, Iterable, Tuple, Union
5
+ from typing import Any, Iterable, List, Optional, Tuple, Union
6
6
 
7
7
  from dh5 import DH5
8
8
 
@@ -39,7 +39,9 @@ class AnalysisLoop(DH5):
39
39
 
40
40
  """
41
41
 
42
- def __init__(self, data: Optional[dict] = None, loop_shape: Optional[List[int]] = None):
42
+ def __init__(
43
+ self, data: Optional[dict] = None, loop_shape: Optional[List[int]] = None
44
+ ):
43
45
  """Initialize an AnalysisLoop object.
44
46
 
45
47
  Args:
@@ -1,4 +1,5 @@
1
1
  """Custom additional linter functions for the acquisition module."""
2
+
2
3
  import ast
3
4
  from typing import Any, Dict
4
5
 
@@ -24,7 +25,9 @@ def on_call_functions(node: ast.Call, db: Dict[str, Any]):
24
25
  h = hash(tuple(get_all_args_from_call(node)))
25
26
  data = db.setdefault("save_fig", [])
26
27
  if h in data:
27
- errors.append("save_fig with the save arguments is used more then ones.")
28
+ errors.append(
29
+ "save_fig with the save arguments is used more then ones."
30
+ )
28
31
 
29
32
  data.append(h)
30
33
  return errors
@@ -264,7 +264,9 @@ class AcquisitionAnalysisManager(AcquisitionManager):
264
264
 
265
265
  def load_file(self, filename) -> "AnalysisData":
266
266
  filename = self._get_full_filename(filename)
267
- if not os.path.exists(filename if filename.endswith(".h5") else filename + ".h5"):
267
+ if not os.path.exists(
268
+ filename if filename.endswith(".h5") else filename + ".h5"
269
+ ):
268
270
  raise ValueError(f"File {filename} cannot be found")
269
271
 
270
272
  data = AnalysisData(
@@ -288,6 +290,7 @@ class AcquisitionAnalysisManager(AcquisitionManager):
288
290
  cell: Optional[str] = None,
289
291
  prerun: Optional[Union[_CallableWithNoArgs, List[_CallableWithNoArgs]]] = None,
290
292
  save_on_edit: Optional[bool] = None,
293
+ step: int = 1,
291
294
  ) -> "AcquisitionAnalysisManager":
292
295
  self._analysis_cell_str = None
293
296
  self._analysis_data = None
@@ -295,8 +298,19 @@ class AcquisitionAnalysisManager(AcquisitionManager):
295
298
  self._acquisition_started = time.time()
296
299
 
297
300
  cell = cell or get_current_cell(self.shell)
298
-
299
- self.new_acquisition(name=name, cell=cell, save_on_edit=save_on_edit)
301
+ if step != 1 and self._current_acquisition is not None:
302
+ if self._current_acquisition.experiment_name != name:
303
+ raise ValueError(
304
+ f"Current acquisition ('{self.current_experiment_name}') "
305
+ f"isn't the one expected ('{name}') for this acquisition. "
306
+ f"Possible solutions: run acquisition '{name}' with step 1; "
307
+ f"or change current acquisition name to '{self.current_experiment_name}'"
308
+ )
309
+ self._current_acquisition.current_step = step
310
+ self._current_acquisition.set_cell(cell, step=step)
311
+ self._current_acquisition.save_cell(cell, suffix=str(step))
312
+ else:
313
+ self.new_acquisition(name=name, cell=cell, save_on_edit=save_on_edit)
300
314
 
301
315
  logger.info(self.current_filepath.basename)
302
316
 
@@ -325,7 +339,9 @@ class AcquisitionAnalysisManager(AcquisitionManager):
325
339
  display_warning("Old data analysis")
326
340
 
327
341
  filename = str(filepath or self._get_full_filename(filename)) # type: ignore
328
- filename = (filename.rsplit(".h5", 1)[0]) if filename.endswith(".h5") else filename
342
+ filename = (
343
+ (filename.rsplit(".h5", 1)[0]) if filename.endswith(".h5") else filename
344
+ )
329
345
 
330
346
  else:
331
347
  self._is_old_data = False
@@ -340,7 +356,8 @@ class AcquisitionAnalysisManager(AcquisitionManager):
340
356
  )
341
357
  or (
342
358
  acquisition_name[0] == r"^"
343
- and re.match(acquisition_name, self.current_experiment_name) is None
359
+ and re.match(acquisition_name, self.current_experiment_name)
360
+ is None
344
361
  )
345
362
  ):
346
363
  raise ValueError(
@@ -374,7 +391,9 @@ class AcquisitionAnalysisManager(AcquisitionManager):
374
391
  if cell is not None:
375
392
  self.save_analysis_cell(cell=cell)
376
393
 
377
- if (self._analysis_cell_str is not None) and (self._linting_external_vars is not None):
394
+ if (self._analysis_cell_str is not None) and (
395
+ self._linting_external_vars is not None
396
+ ):
378
397
  from ..acquisition import custom_lint
379
398
  from ..utils import lint
380
399
 
@@ -387,7 +406,9 @@ class AcquisitionAnalysisManager(AcquisitionManager):
387
406
  run_on_call=custom_lint.on_call_functions,
388
407
  )
389
408
  for var in lint_result.external_vars:
390
- logger.warning("External variable used inside the analysis code: %s", var)
409
+ logger.warning(
410
+ "External variable used inside the analysis code: %s", var
411
+ )
391
412
  for error in lint_result.errors:
392
413
  logger.warning(error)
393
414
  utils.run_functions(self._analysis_cell_prerun_hook)
@@ -417,7 +438,9 @@ class AcquisitionAnalysisManager(AcquisitionManager):
417
438
  def parse_config_file(self, config_file_name: str, /) -> "ConfigFile":
418
439
  return self.data.parse_config_file(config_file_name)
419
440
 
420
- def parse_config(self, config_files: Optional[Tuple[str, ...]] = None) -> "ConfigFile":
441
+ def parse_config(
442
+ self, config_files: Optional[Tuple[str, ...]] = None
443
+ ) -> "ConfigFile":
421
444
  return self.data.parse_config(config_files=config_files)
422
445
 
423
446
  @property
@@ -433,16 +456,22 @@ class AcquisitionAnalysisManager(AcquisitionManager):
433
456
  return self.data.parse_config_str(values, max_length=max_length)
434
457
 
435
458
  def linting(
436
- self, allowed_variables: Optional[Iterable[str]] = None, init_file: Optional[str] = None
459
+ self,
460
+ allowed_variables: Optional[Iterable[str]] = None,
461
+ init_file: Optional[str] = None,
437
462
  ):
438
463
  from ..utils import lint
439
464
 
440
- allowed_variables = set() if allowed_variables is None else set(allowed_variables)
465
+ allowed_variables = (
466
+ set() if allowed_variables is None else set(allowed_variables)
467
+ )
441
468
  if init_file is not None:
442
469
  allowed_variables.update(lint.find_variables_from_file(init_file)[0])
443
470
  self._linting_external_vars = allowed_variables
444
471
 
445
- def set_default_config_files(self, config_files: Union[str, Tuple[str, ...], List[str]], /):
472
+ def set_default_config_files(
473
+ self, config_files: Union[str, Tuple[str, ...], List[str]], /
474
+ ):
446
475
  self._default_config_files = (
447
476
  (config_files,) if isinstance(config_files, str) else tuple(config_files)
448
477
  )
@@ -452,7 +481,9 @@ class AcquisitionAnalysisManager(AcquisitionManager):
452
481
  def set_analysis_cell_prerun_hook(
453
482
  self,
454
483
  hook: Union[
455
- _CallableWithNoArgs, List[_CallableWithNoArgs], Tuple[_CallableWithNoArgs, ...]
484
+ _CallableWithNoArgs,
485
+ List[_CallableWithNoArgs],
486
+ Tuple[_CallableWithNoArgs, ...],
456
487
  ],
457
488
  ):
458
489
  self._analysis_cell_prerun_hook = (
@@ -462,7 +493,9 @@ class AcquisitionAnalysisManager(AcquisitionManager):
462
493
  def set_acquisition_cell_prerun_hook(
463
494
  self,
464
495
  hook: Union[
465
- _CallableWithNoArgs, List[_CallableWithNoArgs], Tuple[_CallableWithNoArgs, ...]
496
+ _CallableWithNoArgs,
497
+ List[_CallableWithNoArgs],
498
+ Tuple[_CallableWithNoArgs, ...],
466
499
  ],
467
500
  ):
468
501
  self._acquisition_cell_prerun_hook = (
@@ -502,16 +535,21 @@ class AcquisitionAnalysisManager(AcquisitionManager):
502
535
 
503
536
  res = self.find_param_in_config(param_text)
504
537
  if res is None:
505
- logger.warning("Parameter '%s' cannot be found in default config files.", param)
538
+ logger.warning(
539
+ "Parameter '%s' cannot be found in default config files.", param
540
+ )
506
541
  continue
507
542
  file, line_no = res
543
+ file = self._config_files_names_to_path.get(file, file)
508
544
  link = display.links.create_link(param_text, file, line_no, after_text)
509
545
  links += link + "<br/>"
510
546
  return display.display_html(links)
511
547
 
512
548
  def connect_default_widget(
513
549
  self,
514
- objs: Union["display_widget.WidgetProtocol", List["display_widget.WidgetProtocol"]],
550
+ objs: Union[
551
+ "display_widget.WidgetProtocol", List["display_widget.WidgetProtocol"]
552
+ ],
515
553
  ):
516
554
  if not isinstance(objs, (list, tuple)):
517
555
  objs = [objs]
@@ -198,9 +198,9 @@ def _create_file_link(aqm: "AcquisitionAnalysisManager", level_up) -> str:
198
198
  if filepath is None:
199
199
  return ""
200
200
  link_name = os.path.basename(filepath)
201
- link = "/".join(os.path.abspath(filepath).replace("\\", "/").split("/")[-level_up:]).replace(
202
- " ", "%20"
203
- )
201
+ link = "/".join(
202
+ os.path.abspath(filepath).replace("\\", "/").split("/")[-level_up:]
203
+ ).replace(" ", "%20")
204
204
  link = f"[{link_name}](//kyrylo-gr.github.io/h5viewer/open?url={link})"
205
205
  return link
206
206
 
@@ -1,5 +1,7 @@
1
1
  """This module contains the AttrDict class."""
2
+
2
3
  from typing import Any, List, Optional, Tuple, Union, overload
4
+
3
5
  from ..utils import title_parsing as utils_parse
4
6
 
5
7
 
@@ -30,12 +32,10 @@ class AttrDict(dict):
30
32
  return type(self)(result)
31
33
 
32
34
  @overload
33
- def find_all(self, key: str) -> List[Tuple[str, Any]]:
34
- ...
35
+ def find_all(self, key: str) -> List[Tuple[str, Any]]: ... # noqa
35
36
 
36
37
  @overload
37
- def find_all(self, key: list) -> List[List[Tuple[str, Any]]]:
38
- ...
38
+ def find_all(self, key: list) -> List[List[Tuple[str, Any]]]: ... # noqa
39
39
 
40
40
  def find_all(self, key: Union[str, list]):
41
41
  """Find all keys that contain the given string.
@@ -54,12 +54,10 @@ class AttrDict(dict):
54
54
  return elms
55
55
 
56
56
  @overload
57
- def find(self, key: str) -> Optional[Tuple[str, Any]]:
58
- ...
57
+ def find(self, key: str) -> Optional[Tuple[str, Any]]: ... # noqa
59
58
 
60
59
  @overload
61
- def find(self, key: list) -> List[Optional[Tuple[str, Any]]]:
62
- ...
60
+ def find(self, key: list) -> List[Optional[Tuple[str, Any]]]: ... # noqa
63
61
 
64
62
  def find(self, key: Union[str, list]) -> Union[Optional[tuple], list]:
65
63
  """Find the first key that contain the given string.
@@ -94,15 +92,21 @@ class AttrDict(dict):
94
92
  keys_with_values = self.__get_value_for_output(keys)
95
93
  return utils_parse.format_title(keys_with_values, max_length=max_length)
96
94
 
97
- def __get_value_for_output(self, keys: List[str]) -> List[utils_parse.ValueForPrint]:
95
+ def __get_value_for_output(
96
+ self, keys: List[str]
97
+ ) -> List[utils_parse.ValueForPrint]:
98
98
  """Prepare the values for output. Returns list of ValueForPrint(key, value, unit, format))."""
99
99
  keys_with_values = []
100
100
  for key in keys:
101
101
  key_value, key_units, key_format = utils_parse.parse_get_format(key)
102
102
  if key_value in self:
103
103
  keys_with_values.append(
104
- utils_parse.ValueForPrint(key_value, self[key_value], key_units, key_format)
104
+ utils_parse.ValueForPrint(
105
+ key_value, self[key_value], key_units, key_format
106
+ )
105
107
  )
106
108
  else:
107
- raise ValueError(f"Cannot find key={key} inside {self.__class__.__name__}")
109
+ raise ValueError(
110
+ f"Cannot find key={key} inside {self.__class__.__name__}"
111
+ )
108
112
  return keys_with_values
@@ -1,8 +1,8 @@
1
1
  # flake8: noqa: F401
2
- from typing import Any, TYPE_CHECKING
3
2
  import importlib
3
+ from typing import TYPE_CHECKING, Any
4
4
 
5
- from .main import display_html, display, logger, display_widgets
5
+ from .main import display, display_html, display_widgets, logger
6
6
 
7
7
  __all__ = ["links", "buttons", "logger"]
8
8
 
@@ -14,7 +14,9 @@ class _LazyModule:
14
14
 
15
15
  def __getattr__(self, name):
16
16
  if self.__module is None:
17
- self.__module = importlib.import_module(f".{self.__name}", package=__package__)
17
+ self.__module = importlib.import_module(
18
+ f".{self.__name}", package=__package__
19
+ )
18
20
  return getattr(self.__module, name)
19
21
 
20
22
  # @property
@@ -29,5 +31,4 @@ buttons = _LazyModule("buttons")
29
31
 
30
32
 
31
33
  if TYPE_CHECKING:
32
- from . import links
33
- from . import buttons
34
+ from . import buttons, links
@@ -1,7 +1,9 @@
1
1
  """This submodule contains functions that are specific for windows."""
2
2
 
3
3
 
4
- def copy_fig(fig=None, format_=None, text_to_copy=None, **kwargs): # pragma: no cover <--
4
+ def copy_fig(
5
+ fig=None, format_=None, text_to_copy=None, **kwargs
6
+ ): # pragma: no cover <--
5
7
  """Copy fig to the clipboard.
6
8
 
7
9
  Parameters
@@ -24,10 +26,10 @@ def copy_fig(fig=None, format_=None, text_to_copy=None, **kwargs): # pragma: no
24
26
  If no figure is found
25
27
  """
26
28
  # from win32gui import GetWindowText, GetForegroundWindow # type: ignore import warnings
27
- import win32clipboard # type: ignore import warnings
29
+ from io import BytesIO
28
30
 
29
31
  import matplotlib.pyplot as plt
30
- from io import BytesIO
32
+ import win32clipboard # type: ignore import warnings
31
33
 
32
34
  # Determined available values by digging into windows API
33
35
  format_map = {
@@ -71,7 +73,9 @@ def copy_fig(fig=None, format_=None, text_to_copy=None, **kwargs): # pragma: no
71
73
  im = Image.open(buf)
72
74
  with BytesIO() as output:
73
75
  im.convert("RGB").save(output, "BMP")
74
- data = output.getvalue()[14:] # The file header off-set of BMP is 14 bytes
76
+ data = output.getvalue()[
77
+ 14:
78
+ ] # The file header off-set of BMP is 14 bytes
75
79
  format_id = win32clipboard.CF_DIB # DIB = device independent bitmap
76
80
 
77
81
  except ImportError:
@@ -85,6 +89,8 @@ def copy_fig(fig=None, format_=None, text_to_copy=None, **kwargs): # pragma: no
85
89
  win32clipboard.EmptyClipboard()
86
90
  win32clipboard.SetClipboardData(format_id, data)
87
91
  if text_to_copy:
88
- win32clipboard.SetClipboardData(win32clipboard.CF_TEXT, text_to_copy.encode("utf-8"))
92
+ win32clipboard.SetClipboardData(
93
+ win32clipboard.CF_TEXT, text_to_copy.encode("utf-8")
94
+ )
89
95
 
90
96
  win32clipboard.CloseClipboard()
@@ -1,5 +1,7 @@
1
1
  """This file contains functions that prepare file for saving for further parsing."""
2
+
2
3
  from typing import Dict
4
+
3
5
  from . import parse_str
4
6
 
5
7
 
@@ -25,7 +27,9 @@ def append_values_from_modules_to_files(
25
27
  return configs
26
28
 
27
29
 
28
- def append_values_from_module_to_file(body: str, module, separator=" # value: ") -> str:
30
+ def append_values_from_module_to_file(
31
+ body: str, module, separator=" # value: "
32
+ ) -> str:
29
33
  """Add values from a module to a given file body.
30
34
 
31
35
  Args:
@@ -64,7 +68,9 @@ def append_values_from_module_to_file(body: str, module, separator=" # value: "
64
68
  for key, (val, _) in parse_str(line).items():
65
69
  real_val = variables.get(key, "")
66
70
  if (
67
- isinstance(val, str) and isinstance(real_val, str) and real_val != val.strip("\"'")
71
+ isinstance(val, str)
72
+ and isinstance(real_val, str)
73
+ and real_val != val.strip("\"'")
68
74
  ) or (
69
75
  isinstance(val, str)
70
76
  and isinstance(real_val, (float, int, complex))
@@ -1,4 +1,5 @@
1
1
  """Linting module that detects bad practice with AcquisitionAnalysisManager."""
2
+
2
3
  import ast
3
4
  from typing import Any, Callable, Dict, List, NamedTuple, Optional, Set
4
5
 
@@ -197,7 +198,9 @@ class LintResult(NamedTuple):
197
198
  errors: List[str]
198
199
 
199
200
 
200
- def find_variables_from_node(node, ignore_var: Optional[set] = None, **kwargs) -> LintResult:
201
+ def find_variables_from_node(
202
+ node, ignore_var: Optional[set] = None, **kwargs
203
+ ) -> LintResult:
201
204
  """Walk through ast.node and find the variable that was never declared inside this node, but used.
202
205
 
203
206
  Variables from ingore_var set is allowed external variables to use.
@@ -1,4 +1,5 @@
1
1
  """Random utilities."""
2
+
2
3
  from typing import Any, Callable, List, Optional, Tuple, Union
3
4
 
4
5
  from dh5.utils.random_utils import ( # pylint: disable=unused-import # noqa: F401
@@ -6,13 +7,16 @@ from dh5.utils.random_utils import ( # pylint: disable=unused-import # noqa: F4
6
7
  get_timestamp,
7
8
  )
8
9
 
9
-
10
10
  _CallableWithNoArgs = Callable[[], Any]
11
11
 
12
12
 
13
13
  def run_functions(
14
14
  functions: Optional[
15
- Union[_CallableWithNoArgs, List[_CallableWithNoArgs], Tuple[_CallableWithNoArgs, ...]]
15
+ Union[
16
+ _CallableWithNoArgs,
17
+ List[_CallableWithNoArgs],
18
+ Tuple[_CallableWithNoArgs, ...],
19
+ ]
16
20
  ] = None,
17
21
  /,
18
22
  ):
@@ -1,6 +1,7 @@
1
1
  """This file contains function of title generation.
2
2
  (parsing expected units and format, creating title)
3
3
  """
4
+
4
5
  from typing import Any, List, NamedTuple, Optional, Tuple
5
6
 
6
7
 
@@ -47,10 +48,14 @@ def format_title(values: List[ValueForPrint], max_length: Optional[int] = None)
47
48
  for value in values:
48
49
  units = f" ({value.units})" if value.units is not None else ""
49
50
  value_str = (
50
- value.value if value.format is None else value.value.__format__(f".{value.format}")
51
+ value.value
52
+ if value.format is None
53
+ else value.value.__format__(f".{value.format}")
51
54
  )
52
55
  new_txt = f"{value.key} = {value_str}{units}"
53
- if not max_length or ((last_line_len + len(new_txt) < max_length) or last_line_len == 0):
56
+ if not max_length or (
57
+ (last_line_len + len(new_txt) < max_length) or last_line_len == 0
58
+ ):
54
59
  txt += ("; " if txt != "" else "") + new_txt
55
60
  last_line_len += len(new_txt) + 2
56
61
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: labmate
3
- Version: 0.8.2
3
+ Version: 0.8.4
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
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