pymodaq 5.0.5__py3-none-any.whl → 5.1.0a0__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.

Potentially problematic release.


This version of pymodaq might be problematic. Click here for more details.

Files changed (53) hide show
  1. pymodaq/control_modules/daq_move.py +77 -64
  2. pymodaq/control_modules/daq_move_ui.py +16 -15
  3. pymodaq/control_modules/daq_viewer.py +95 -87
  4. pymodaq/control_modules/daq_viewer_ui.py +22 -23
  5. pymodaq/control_modules/mocks.py +2 -2
  6. pymodaq/control_modules/move_utility_classes.py +28 -19
  7. pymodaq/control_modules/thread_commands.py +138 -0
  8. pymodaq/control_modules/utils.py +88 -20
  9. pymodaq/control_modules/viewer_utility_classes.py +8 -17
  10. pymodaq/dashboard.py +90 -27
  11. pymodaq/examples/qt_less_standalone_module.py +48 -11
  12. pymodaq/extensions/__init__.py +7 -3
  13. pymodaq/extensions/adaptive/__init__.py +2 -0
  14. pymodaq/extensions/adaptive/adaptive_optimization.py +159 -0
  15. pymodaq/extensions/adaptive/loss_function/_1d_loss_functions.py +73 -0
  16. pymodaq/extensions/adaptive/loss_function/_2d_loss_functions.py +86 -0
  17. pymodaq/extensions/adaptive/loss_function/__init__.py +3 -0
  18. pymodaq/extensions/adaptive/loss_function/loss_factory.py +106 -0
  19. pymodaq/extensions/adaptive/utils.py +97 -0
  20. pymodaq/extensions/bayesian/__init__.py +1 -1
  21. pymodaq/extensions/bayesian/acquisition/__init__.py +2 -0
  22. pymodaq/extensions/bayesian/acquisition/acquisition_function_factory.py +71 -0
  23. pymodaq/extensions/bayesian/acquisition/base_acquisition_function.py +86 -0
  24. pymodaq/extensions/bayesian/bayesian_optimization.py +121 -0
  25. pymodaq/extensions/bayesian/utils.py +27 -286
  26. pymodaq/extensions/daq_logger/daq_logger.py +7 -12
  27. pymodaq/extensions/daq_logger/h5logging.py +1 -1
  28. pymodaq/extensions/daq_scan.py +18 -47
  29. pymodaq/extensions/h5browser.py +3 -34
  30. pymodaq/extensions/optimizers_base/__init__.py +0 -0
  31. pymodaq/extensions/{bayesian/bayesian_optimisation.py → optimizers_base/optimizer.py} +441 -334
  32. pymodaq/extensions/optimizers_base/thread_commands.py +20 -0
  33. pymodaq/extensions/optimizers_base/utils.py +378 -0
  34. pymodaq/extensions/pid/pid_controller.py +6 -10
  35. pymodaq/extensions/utils.py +12 -0
  36. pymodaq/utils/data.py +1 -0
  37. pymodaq/utils/gui_utils/loader_utils.py +2 -0
  38. pymodaq/utils/h5modules/module_saving.py +134 -22
  39. pymodaq/utils/leco/daq_move_LECODirector.py +73 -73
  40. pymodaq/utils/leco/daq_xDviewer_LECODirector.py +36 -84
  41. pymodaq/utils/leco/director_utils.py +25 -10
  42. pymodaq/utils/leco/leco_director.py +65 -26
  43. pymodaq/utils/leco/pymodaq_listener.py +118 -68
  44. pymodaq/utils/leco/utils.py +24 -24
  45. pymodaq/utils/managers/modules_manager.py +37 -8
  46. pymodaq/utils/scanner/scanners/_1d_scanners.py +0 -38
  47. pymodaq/utils/scanner/scanners/_2d_scanners.py +0 -58
  48. {pymodaq-5.0.5.dist-info → pymodaq-5.1.0a0.dist-info}/METADATA +4 -3
  49. {pymodaq-5.0.5.dist-info → pymodaq-5.1.0a0.dist-info}/RECORD +52 -38
  50. {pymodaq-5.0.5.dist-info → pymodaq-5.1.0a0.dist-info}/entry_points.txt +0 -2
  51. pymodaq/utils/leco/desktop.ini +0 -2
  52. {pymodaq-5.0.5.dist-info → pymodaq-5.1.0a0.dist-info}/WHEEL +0 -0
  53. {pymodaq-5.0.5.dist-info → pymodaq-5.1.0a0.dist-info}/licenses/LICENSE +0 -0
@@ -1,94 +1,75 @@
1
- from typing import List, Union, Optional
1
+ import abc
2
+ from typing import List, Optional
2
3
  import tempfile
3
4
  from pathlib import Path
4
5
 
6
+
5
7
  from qtpy import QtWidgets, QtCore
6
8
  import time
7
9
  import numpy as np
8
10
 
9
- from pymodaq.utils.data import DataToExport, DataToActuators, DataCalculated, DataActuator
11
+ from collections import OrderedDict
12
+
13
+
10
14
  from pymodaq.utils.managers.modules_manager import ModulesManager
11
15
  from pymodaq_utils import utils
12
16
  from pymodaq_utils import config as config_mod
13
- from pymodaq_utils.enums import BaseEnum
14
-
15
- from pymodaq_gui.config import ConfigSaverLoader
17
+ from pymodaq_utils.enums import BaseEnum, StrEnum
16
18
  from pymodaq_utils.logger import set_logger, get_module_name
17
19
 
20
+ from pymodaq_data.h5modules.data_saving import DataEnlargeableSaver
21
+
18
22
  from pymodaq_gui.plotting.data_viewers.viewer0D import Viewer0D
19
- from pymodaq_gui.plotting.data_viewers.viewer import ViewerDispatcher, ViewersEnum
23
+ from pymodaq_gui.plotting.data_viewers.viewer import ViewerDispatcher
20
24
  from pymodaq_gui.utils import QLED
21
- from pymodaq_gui.utils.utils import mkQApp
22
25
  from pymodaq_gui import utils as gutils
23
26
  from pymodaq_gui.parameter import utils as putils
24
27
  from pymodaq_gui.h5modules.saving import H5Saver
28
+ from pymodaq_gui.config import ConfigSaverLoader
25
29
 
26
- from pymodaq_data.h5modules.data_saving import DataEnlargeableSaver
27
-
28
-
29
- from pymodaq.extensions.bayesian.utils import (get_bayesian_models, BayesianModelGeneric,
30
- BayesianAlgorithm, UtilityKind,
31
- UtilityParameters, StopType, StoppingParameters)
30
+ from pymodaq.utils.data import DataToExport, DataToActuators, DataCalculated, DataActuator
32
31
  from pymodaq.post_treatment.load_and_plot import LoaderPlotter
33
- from pymodaq.extensions.bayesian.utils import BayesianConfig
34
32
  from pymodaq.extensions.utils import CustomExt
35
33
 
36
- EXTENSION_NAME = 'BayesianOptimisation'
37
- CLASS_NAME = 'BayesianOptimisation'
34
+ from pymodaq.utils.h5modules import module_saving
35
+
36
+ from pymodaq.extensions.optimizers_base.utils import (
37
+ get_optimizer_models, OptimizerModelGeneric,
38
+ GenericAlgorithm, StopType, StoppingParameters,
39
+ OptimizerConfig)
40
+ from pymodaq.extensions.optimizers_base.thread_commands import OptimizerToRunner, OptimizerThreadStatus
41
+
38
42
 
39
43
  logger = set_logger(get_module_name(__file__))
40
44
  config = config_mod.Config()
41
45
 
46
+ PREDICTION_PARAMS = [] # to be subclassed in ral optimizer implementations
47
+ MODELS = get_optimizer_models()
42
48
 
43
- class DataNames(BaseEnum):
44
- Fitness = 0
45
- Individual = 1
46
- ProbedData = 2
47
- Actuators = 3
48
- Kappa = 4
49
49
 
50
+ class DataNames(StrEnum):
51
+ Fitness = 'fitness'
52
+ Individual = 'individual'
53
+ ProbedData = 'probed_data'
54
+ Actuators = 'actuators'
55
+ Tradeoff = 'tradeoff'
50
56
 
51
- class BayesianOptimisation(CustomExt):
52
- """ PyMoDAQ extension of the DashBoard to perform the optimization of a target signal
53
- taken form the detectors as a function of one or more parameters controlled by the actuators.
54
- """
55
57
 
56
- command_runner = QtCore.Signal(utils.ThreadCommand)
57
- models = get_bayesian_models()
58
- explored_viewer_name = 'algo/ProbedData'
59
- optimisation_done_signal = QtCore.Signal(DataToExport)
60
-
61
- params = [
58
+ def optimizer_params(prediction_params: list[dict]):
59
+ return [
62
60
  {'title': 'Main Settings:', 'name': 'main_settings', 'expanded': True, 'type': 'group',
63
61
  'children': [
64
- {'title': 'Utility Function:', 'name': 'utility', 'expanded': False, 'type': 'group',
65
- 'children': [
66
- {'title': 'Kind', 'name': 'kind', 'type': 'list',
67
- 'limits': UtilityKind.to_dict_value()},
68
- {'title': 'Kappa:', 'name': 'kappa', 'type': 'slide', 'value': 2.576,
69
- 'min': 0.001, 'max': 100, 'subtype': 'log',
70
- 'tip': 'Parameter to indicate how closed are the next parameters sampled.'
71
- 'Higher value = favors spaces that are least explored.'
72
- 'Lower value = favors spaces where the regression function is the '
73
- 'highest.'},
74
- {'title': 'Kappa actual:', 'name': 'kappa_actual', 'type': 'float', 'value': 2.576,
75
- 'tip': 'Current value of the kappa parameter', 'readonly': True},
76
- {'title': 'xi:', 'name': 'xi', 'type': 'slide', 'value': 0,
77
- 'tip': 'Governs the exploration/exploitation tradeoff.'
78
- 'Lower prefers exploitation, higher prefers exploration.'},
79
- {'title': 'Kappa decay:', 'name': 'kappa_decay', 'type': 'float', 'value': 0.9,
80
- 'tip': 'kappa is multiplied by this factor every iteration.'},
81
- {'title': 'Kappa decay delay:', 'name': 'kappa_decay_delay', 'type': 'int',
82
- 'value': 20, 'tip': 'Number of iterations that must have passed before applying '
83
- 'the decay to kappa.'},
84
- ]},
62
+ {'title': 'Prediction Function:', 'name': 'prediction', 'expanded': False, 'type': 'group',
63
+ 'children': prediction_params
64
+
65
+ },
85
66
  {'title': 'Stopping Criteria:', 'name': 'stopping', 'expanded': False, 'type': 'group',
86
67
  'children': [
87
68
  {'title': 'Niteration', 'name': 'niter', 'type': 'int', 'value': 100, 'min': -1},
88
69
  {'title': 'Type:', 'name': 'stop_type', 'type': 'list',
89
70
  'limits': StopType.names()},
90
71
  {'title': 'Tolerance', 'name': 'tolerance', 'type': 'slide', 'value': 1e-2,
91
- 'min': 1e-8, 'max': 1, 'subtype': 'log',},
72
+ 'min': 1e-8, 'max': 1, 'subtype': 'log', },
92
73
  {'title': 'Npoints', 'name': 'npoints', 'type': 'int', 'value': 5, 'min': 1},
93
74
  ]},
94
75
  {'title': 'Ini. State', 'name': 'ini_random', 'type': 'int', 'value': 5},
@@ -97,43 +78,219 @@ class BayesianOptimisation(CustomExt):
97
78
 
98
79
  {'title': 'Models', 'name': 'models', 'type': 'group', 'expanded': True, 'visible': True,
99
80
  'children': [
100
- {'title': 'Models class:', 'name': 'model_class', 'type': 'list',
101
- 'limits': [d['name'] for d in models]},
102
- {'title': 'Ini Model', 'name': 'ini_model', 'type': 'action', },
103
- {'title': 'Ini Algo', 'name': 'ini_runner', 'type': 'action', 'enabled': False},
104
- {'title': 'Model params:', 'name': 'model_params', 'type': 'group', 'children': []},
105
- ]},
81
+ {'title': 'Models class:', 'name': 'model_class', 'type': 'list',
82
+ 'limits': [d['name'] for d in MODELS]},
83
+ {'title': 'Ini Model', 'name': 'ini_model', 'type': 'action', },
84
+ {'title': 'Ini Algo', 'name': 'ini_runner', 'type': 'action', 'enabled': False},
85
+ {'title': 'Model params:', 'name': 'model_params', 'type': 'group', 'children': []},
86
+ ]},
106
87
  {'title': 'Move settings:', 'name': 'move_settings', 'expanded': True, 'type': 'group',
107
88
  'visible': False, 'children': [
108
- {'title': 'Units:', 'name': 'units', 'type': 'str', 'value': ''}]},
89
+ {'title': 'Units:', 'name': 'units', 'type': 'str', 'value': ''}]},
109
90
 
110
91
  ]
111
92
 
93
+
94
+ class DataToActuatorsOpti(DataToActuators):
95
+ """ Specific class including the step in the optimization loop for further use"""
96
+ ind_iter: int
97
+ def __init__(self, *args, ind_iter=0, **kwargs):
98
+ super().__init__(*args, ind_iter=ind_iter, **kwargs)
99
+
100
+ def __repr__(self):
101
+ return f'{super().__repr__()} iter:{self.ind_iter}'
102
+
103
+
104
+ class OptimizationRunner(QtCore.QObject):
105
+ algo_output_signal = QtCore.Signal(DataToExport)
106
+ algo_finished = QtCore.Signal(DataToExport)
107
+ saver_signal = QtCore.Signal(DataToActuatorsOpti)
108
+
109
+ runner_command = QtCore.Signal(utils.ThreadCommand)
110
+
111
+ def __init__(self, model_class: OptimizerModelGeneric, modules_manager: ModulesManager,
112
+ algorithm: GenericAlgorithm, stopping_params: StoppingParameters):
113
+ super().__init__()
114
+
115
+ self.det_done_datas: DataToExport = None
116
+ self.input_from_dets: float = None
117
+ self.outputs: List[np.ndarray] = []
118
+ self.output_to_actuators: DataToActuators = None
119
+ self.dte_actuators: DataToExport = None
120
+ self.stopping_params: StoppingParameters = stopping_params
121
+
122
+ self.model_class: OptimizerModelGeneric = model_class
123
+ self.modules_manager: ModulesManager = modules_manager
124
+
125
+ self.running = True
126
+ self._ind_iter = -1
127
+
128
+ self.optimization_algorithm: GenericAlgorithm = algorithm
129
+
130
+
131
+ def queue_command(self, command: utils.ThreadCommand):
132
+ """
133
+ """
134
+ if command.command == OptimizerToRunner.RUN:
135
+ if command.attribute is None:
136
+ command.attribute = {}
137
+ self.run_opti(**command.attribute)
138
+
139
+ elif command.command == OptimizerToRunner.STOP:
140
+ self.running = False
141
+
142
+ elif command.command == OptimizerToRunner.STOPPING:
143
+ self.stopping_params: StoppingParameters = command.attribute
144
+
145
+ elif command.command == OptimizerToRunner.BOUNDS:
146
+ self.optimization_algorithm.bounds = command.attribute
147
+
148
+ def run_opti(self, sync_detectors=True, sync_acts=True):
149
+ """Start the optimization loop
150
+
151
+ Parameters
152
+ ----------
153
+ sync_detectors: (bool) if True will make sure all selected detectors (if any) all got their data before calling
154
+ the model
155
+ sync_acts: (bool) if True will make sure all selected actuators (if any) all reached their target position
156
+ before calling the model
157
+ """
158
+ self.running = True
159
+ converged = False
160
+ try:
161
+ if sync_detectors:
162
+ self.modules_manager.connect_detectors()
163
+ if sync_acts:
164
+ self.modules_manager.connect_actuators()
165
+
166
+ self.current_time = time.perf_counter()
167
+ logger.info('Optimisation loop starting')
168
+ while self.running:
169
+ self._ind_iter += 1
170
+
171
+ next_target = self.optimization_algorithm.ask()
172
+
173
+ self.outputs = next_target
174
+ self.output_to_actuators: DataToActuators = \
175
+ self.model_class.convert_output(
176
+ self.outputs,
177
+ best_individual=self.optimization_algorithm.best_individual
178
+ )
179
+
180
+ self.modules_manager.move_actuators(self.output_to_actuators,
181
+ self.output_to_actuators.mode,
182
+ polling=sync_acts)
183
+
184
+ # Do the evaluation (measurements)
185
+ self.det_done_datas = self.modules_manager.grab_data()
186
+ self.input_from_dets = self.model_class.convert_input(self.det_done_datas)
187
+
188
+ #log data
189
+ self.runner_command.emit(
190
+ utils.ThreadCommand(OptimizerThreadStatus.ADD_DATA,))
191
+
192
+ # Run the algo internal mechanic
193
+ self.optimization_algorithm.tell(float(self.input_from_dets))
194
+
195
+ dte = DataToExport('algo', data=[
196
+ self.individual_as_data(
197
+ np.array([self.optimization_algorithm.best_fitness]),
198
+ DataNames.Fitness),
199
+ self.individual_as_data(
200
+ self.optimization_algorithm.best_individual,
201
+ DataNames.Individual),
202
+ DataCalculated(DataNames.ProbedData,
203
+ data=[np.array([self.input_from_dets])],),
204
+ self.output_to_actuators.merge_as_dwa(
205
+ 'Data0D', DataNames.Actuators),
206
+ DataCalculated(DataNames.Tradeoff,
207
+ data=[np.array([self.optimization_algorithm.tradeoff])])
208
+ ])
209
+ self.algo_output_signal.emit(dte)
210
+ self.saver_signal.emit(DataToActuatorsOpti(DataNames.Actuators,
211
+ data = self.output_to_actuators.deepcopy().data,
212
+ mode=self.output_to_actuators.mode,
213
+ ind_iter=self._ind_iter))
214
+
215
+ self.optimization_algorithm.update_prediction_function()
216
+
217
+ if self.optimization_algorithm.stopping(self._ind_iter, self.stopping_params):
218
+ converged = True
219
+ break
220
+
221
+ self.current_time = time.perf_counter()
222
+ QtWidgets.QApplication.processEvents()
223
+ QtWidgets.QApplication.processEvents()
224
+ logger.info('Optimisation loop exiting')
225
+ self.modules_manager.connect_actuators(False)
226
+ self.modules_manager.connect_detectors(False)
227
+
228
+ if converged:
229
+ self.algo_finished.emit(dte)
230
+
231
+ except Exception as e:
232
+ logger.exception(str(e))
233
+
234
+ @staticmethod
235
+ def individual_as_data(individual: np.ndarray, name: str = 'Individual') -> DataCalculated:
236
+ return DataCalculated(name, data=[np.atleast_1d(np.squeeze(coordinate)) for coordinate in
237
+ np.atleast_1d(np.squeeze(individual))])
238
+
239
+
240
+ class GenericOptimization(CustomExt):
241
+ """ PyMoDAQ extension of the DashBoard to perform the optimization of a target signal
242
+ taken form the detectors as a function of one or more parameters controlled by the actuators.
243
+ """
244
+
245
+ command_runner = QtCore.Signal(utils.ThreadCommand)
246
+ explored_viewer_name = f'algo/{DataNames.ProbedData}'
247
+ optimization_done_signal = QtCore.Signal(DataToExport)
248
+
249
+ runner = OptimizationRunner # replace in real implementation if customization is needed
250
+ DISPLAY_BEST = True
251
+
252
+ params = optimizer_params(PREDICTION_PARAMS)
253
+
254
+ config_saver = OptimizerConfig #to be redefined in real implementation if needed
255
+
112
256
  def __init__(self, dockarea, dashboard):
113
257
  super().__init__(dockarea, dashboard)
114
258
 
115
- self.algorithm: Optional[BayesianAlgorithm] = None
259
+ self._ini_runner = False
260
+
261
+ self.algorithm: Optional[GenericAlgorithm] = None
116
262
  self.viewer_fitness: Optional[Viewer0D] = None
117
263
  self.viewer_observable: Optional[ViewerDispatcher] = None
118
- self.model_class: Optional[BayesianModelGeneric] = None
264
+ self.model_class: Optional[OptimizerModelGeneric] = None
119
265
  self._save_main_settings = True
120
266
  self._modules_manager = ModulesManager(self.dashboard.detector_modules,
121
267
  self.dashboard.actuators_modules)
122
268
  self.modules_manager.actuators_changed[list].connect(self.update_actuators)
123
269
  self.modules_manager.settings.child('data_dimensions').setOpts(expanded=False)
124
270
  self.modules_manager.settings.child('actuators_positions').setOpts(expanded=False)
271
+
272
+ self._h5saver: H5Saver = None
273
+ self.h5saver.settings.child('do_save').hide()
274
+ self.h5saver.settings.child('custom_name').hide()
275
+ self.h5saver.new_file_sig.connect(self.create_new_file)
276
+
125
277
  self.setup_ui()
126
278
 
127
- self.bayesian_config = BayesianConfig()
279
+ self.optimizer_config = self.config_saver()
280
+
128
281
  self.mainsettings_saver_loader = ConfigSaverLoader(
129
- self.settings.child('main_settings'), self.bayesian_config)
282
+ self.settings.child('main_settings'), self.optimizer_config)
283
+
284
+ self._base_name: str = None
130
285
 
131
286
  self.h5temp: H5Saver = None
132
287
  self.temp_path: tempfile.TemporaryDirectory = None
133
-
134
288
  self.enlargeable_saver: DataEnlargeableSaver = None
135
289
  self.live_plotter = LoaderPlotter(self.dockarea)
136
290
 
291
+ self._module_and_data_saver: module_saving.OptimizerSaver = None
292
+
293
+ self._ind_iter: int = 0
137
294
  self.enl_index = 0
138
295
 
139
296
  self.settings.child('models', 'ini_model').sigActivated.connect(
@@ -141,6 +298,62 @@ class BayesianOptimisation(CustomExt):
141
298
 
142
299
  self.settings.child('models', 'ini_runner').sigActivated.connect(
143
300
  self.get_action('ini_runner').trigger)
301
+ self.ini_custom_attributes()
302
+
303
+ @property
304
+ def title(self):
305
+ return f'{self.__class__.__name__}'
306
+
307
+ def ini_custom_attributes(self):
308
+ """ Here you can reimplement specific attributes"""
309
+ self._base_name: str = 'Optimizer' # base name used for naming the hdf5 file
310
+
311
+ @property
312
+ def h5saver(self):
313
+ if self._h5saver is None:
314
+ self._h5saver = H5Saver(save_type='optimizer', backend=config('general', 'hdf5_backend'))
315
+ self._h5saver.settings.child('base_name').setValue('Optimizer')
316
+ if self._h5saver.h5_file is None:
317
+ self._h5saver.init_file(update_h5=True)
318
+ if not self._h5saver.isopen():
319
+ self._h5saver.init_file(addhoc_file_path=self._h5saver.settings['current_h5_file'])
320
+ return self._h5saver
321
+
322
+ @h5saver.setter
323
+ def h5saver(self, h5saver_temp: H5Saver):
324
+ self._h5saver = h5saver_temp
325
+
326
+ @property
327
+ def module_and_data_saver(self):
328
+ if not self._module_and_data_saver.h5saver.isopen():
329
+ self._module_and_data_saver.h5saver = self.h5saver
330
+ return self._module_and_data_saver
331
+
332
+ @module_and_data_saver.setter
333
+ def module_and_data_saver(self, mod: module_saving.OptimizerSaver):
334
+ self._module_and_data_saver = mod
335
+ self._module_and_data_saver.h5saver = self.h5saver
336
+
337
+ def create_new_file(self, new_file):
338
+ if new_file:
339
+ self.close_file()
340
+ self.module_and_data_saver.h5saver = self.h5saver # force all control modules to update their h5saver
341
+
342
+ def close_file(self):
343
+ self.h5saver.close_file()
344
+
345
+ def add_data(self, dta: DataToActuatorsOpti):
346
+ if self.is_action_checked('save'):
347
+ self.module_and_data_saver.add_data(axis_values=[dwa[0] for dwa in dta],
348
+ init_step=dta.ind_iter == 0)
349
+
350
+ @abc.abstractmethod
351
+ def validate_config(self) -> bool:
352
+ pass
353
+
354
+ @property
355
+ def config_path(self) -> Path:
356
+ return self.optimizer_config.config_path
144
357
 
145
358
  @property
146
359
  def modules_manager(self) -> ModulesManager:
@@ -160,32 +373,37 @@ class BayesianOptimisation(CustomExt):
160
373
  ########
161
374
  pyqtgraph.dockarea.Dock
162
375
  """
376
+ self.docks['saving'] = gutils.Dock('Saving')
377
+ self.docks['saving'].addWidget(self.h5saver.settings_tree)
378
+ self.dockarea.addDock(self.docks['saving'])
379
+
163
380
  self.docks['settings'] = gutils.Dock('Settings')
164
- self.dockarea.addDock(self.docks['settings'])
165
- splitter = QtWidgets.QSplitter(QtCore.Qt.Vertical)
381
+ self.dockarea.addDock(self.docks['settings'], 'below', self.docks['saving'])
382
+ splitter = QtWidgets.QSplitter(QtCore.Qt.Orientation.Vertical)
166
383
  self.docks['settings'].addWidget(splitter)
167
384
  splitter.addWidget(self.settings_tree)
168
385
  splitter.addWidget(self.modules_manager.settings_tree)
169
- self.modules_manager.show_only_control_modules(False)
386
+ self.modules_manager.show_only_control_modules(True)
387
+
170
388
  splitter.setSizes((int(self.dockarea.height() / 2),
171
389
  int(self.dockarea.height() / 2)))
172
-
173
- widget_observable = QtWidgets.QWidget()
174
- widget_observable.setLayout(QtWidgets.QHBoxLayout())
175
- observable_dockarea = gutils.DockArea()
176
- widget_observable.layout().addWidget(observable_dockarea)
177
- self.viewer_observable = ViewerDispatcher(observable_dockarea, direction='bottom')
178
- self.docks['observable'] = gutils.Dock('Observable')
179
- self.dockarea.addDock(self.docks['observable'], 'right', self.docks['settings'])
180
- self.docks['observable'].addWidget(widget_observable)
181
-
182
- if len(self.models) != 0:
183
- self.get_set_model_params(self.models[0]['name'])
390
+ if self.DISPLAY_BEST:
391
+ widget_observable = QtWidgets.QWidget()
392
+ widget_observable.setLayout(QtWidgets.QHBoxLayout())
393
+ observable_dockarea = gutils.DockArea()
394
+ widget_observable.layout().addWidget(observable_dockarea)
395
+ self.viewer_observable = ViewerDispatcher(observable_dockarea, direction='bottom')
396
+ self.docks['observable'] = gutils.Dock('Observable')
397
+ self.dockarea.addDock(self.docks['observable'], 'right', self.docks['settings'])
398
+ self.docks['observable'].addWidget(widget_observable)
399
+
400
+ if len(MODELS) != 0:
401
+ self.get_set_model_params(MODELS[0]['name'])
184
402
 
185
403
  def get_set_model_params(self, model_name):
186
404
  self.settings.child('models', 'model_params').clearChildren()
187
- if len(self.models) > 0:
188
- model_class = utils.find_dict_in_list_from_key_val(self.models, 'name', model_name)['class']
405
+ if len(MODELS) > 0:
406
+ model_class = utils.find_dict_in_list_from_key_val(MODELS, 'name', model_name)['class']
189
407
  params = getattr(model_class, 'params')
190
408
  self.settings.child('models', 'model_params').addChildren(params)
191
409
 
@@ -223,26 +441,26 @@ class BayesianOptimisation(CustomExt):
223
441
  elif param.name() in putils.iter_children(self.settings.child('models', 'model_params'), []):
224
442
  if self.model_class is not None:
225
443
  self.model_class.update_settings(param)
226
- elif param.name() in putils.iter_children(
227
- self.settings.child('main_settings', 'utility'), []):
228
- if param.name() != 'kappa_actual':
229
- self.update_utility_function()
230
444
  elif param.name() in putils.iter_children(
231
445
  self.settings.child('main_settings', 'bounds'), []):
232
446
  self.update_bounds()
233
447
  elif param.name() in putils.iter_children(
234
448
  self.settings.child('main_settings', 'stopping'), []):
235
449
  self.update_stopping_criteria()
236
- if self._save_main_settings and param.name() in putils.iter_children(
237
- self.settings.child('main_settings'), []):
450
+ elif param.name() in putils.iter_children(
451
+ self.settings.child('main_settings', 'prediction'), []):
452
+ if param.name() != 'tradeoff_actual':
453
+ self.update_prediction_function()
454
+
455
+ if self._save_main_settings and self.model_class is not None and param.name() in putils.iter_children(
456
+ self.settings.child('main_settings'), []):
238
457
  self.mainsettings_saver_loader.save_config()
239
458
 
240
- def update_utility_function(self):
241
- utility_settings = self.settings.child('main_settings', 'utility')
242
- uparams = UtilityParameters(utility_settings['kind'], utility_settings['kappa'],
243
- utility_settings['xi'], utility_settings['kappa_decay'],
244
- utility_settings['kappa_decay_delay'])
245
- self.command_runner.emit(utils.ThreadCommand('utility', uparams))
459
+ def update_prediction_function(self):
460
+ utility_settings = self.settings.child('main_settings', 'prediction')
461
+ uparams = {child.name() : child.value() for child in utility_settings.children()}
462
+ self.command_runner.emit(
463
+ utils.ThreadCommand(OptimizerToRunner.PREDICTION, uparams))
246
464
 
247
465
  def get_stopping_parameters(self) -> StoppingParameters:
248
466
  stopping_settings = self.settings.child('main_settings', 'stopping')
@@ -253,20 +471,23 @@ class BayesianOptimisation(CustomExt):
253
471
  return stopping_params
254
472
 
255
473
  def update_stopping_criteria(self):
256
- self.command_runner.emit(utils.ThreadCommand('stopping', self.get_stopping_parameters()))
474
+ self.command_runner.emit(
475
+ utils.ThreadCommand(OptimizerToRunner.STOPPING, self.get_stopping_parameters()))
257
476
 
258
477
  def update_bounds(self):
259
478
  bounds = {}
260
479
  for child in self.settings.child('main_settings', 'bounds').children():
261
480
  bounds[child.name()] = (child['min'], child['max'])
262
481
 
263
- self.command_runner.emit(utils.ThreadCommand('bounds', bounds))
482
+ self.command_runner.emit(utils.ThreadCommand(OptimizerToRunner.BOUNDS, bounds))
264
483
 
265
484
  def setup_actions(self):
266
485
  logger.debug('setting actions')
267
486
  self.add_action('quit', 'Quit', 'close2', "Quit program")
268
487
  self.add_action('ini_model', 'Init Model', 'ini')
269
488
  self.add_widget('model_led', QLED, toolbar=self.toolbar)
489
+ self.add_action('save', 'Save?', 'SaveAs', tip='If checked, data will be saved',
490
+ checkable=True)
270
491
  self.add_action('ini_runner', 'Init the Optimisation Algorithm', 'ini', checkable=True,
271
492
  enabled=False)
272
493
  self.add_widget('runner_led', QLED, toolbar=self.toolbar)
@@ -277,24 +498,30 @@ class BayesianOptimisation(CustomExt):
277
498
 
278
499
  def connect_things(self):
279
500
  logger.debug('connecting things')
280
- self.connect_action('quit', self.quit, )
501
+ self.connect_action('quit', self.quit)
281
502
  self.connect_action('ini_model', self.ini_model)
282
- self.connect_action('ini_runner', self.ini_optimisation_runner)
283
- self.connect_action('run', self.run_optimisation)
503
+ self.connect_action('ini_runner', self.ini_optimization_runner)
504
+ self.connect_action('run', self.run_optimization)
284
505
  self.connect_action('gotobest', self.go_to_best)
506
+ self.connect_action('save', self.ini_saver)
507
+ self.h5saver.new_file_sig.connect(self.create_new_file)
285
508
 
286
509
  def go_to_best(self):
287
510
  best_individual = self.algorithm.best_individual
288
- actuators = self.modules_manager.selected_actuators_name
289
- dte_act = DataToActuators('best', data=[
290
- DataActuator(actuators[ind], data=float(best_individual[ind])) for ind in range(len(best_individual))
291
- ],
292
- mode='abs')
293
- self.modules_manager.connect_actuators(True)
294
- self.modules_manager.move_actuators(dte_act, polling=True)
295
- self.modules_manager.connect_actuators(False)
511
+ if best_individual is not None:
512
+ actuators = self.modules_manager.selected_actuators_name
513
+ dte_act = DataToActuators('best',
514
+ data=[
515
+ DataActuator(actuators[ind],
516
+ data=float(best_individual[ind]))
517
+ for ind in range(len(best_individual))
518
+ ],
519
+ mode='abs')
520
+ self.modules_manager.connect_actuators(True)
521
+ self.modules_manager.move_actuators(dte_act, polling=True)
522
+ self.modules_manager.connect_actuators(False)
296
523
 
297
- self.modules_manager.grab_datas()
524
+ self.modules_manager.grab_datas()
298
525
 
299
526
  def quit(self):
300
527
  self.dockarea.parent().close()
@@ -303,7 +530,7 @@ class BayesianOptimisation(CustomExt):
303
530
  def set_model(self):
304
531
  model_name = self.settings.child('models', 'model_class').value()
305
532
  self.model_class = utils.find_dict_in_list_from_key_val(
306
- self.models, 'name', model_name)['class'](self)
533
+ MODELS, 'name', model_name)['class'](self)
307
534
  self.model_class.ini_model_base()
308
535
 
309
536
  def ini_temp_file(self):
@@ -350,7 +577,7 @@ class BayesianOptimisation(CustomExt):
350
577
 
351
578
  QtWidgets.QApplication.processEvents()
352
579
  win_width = self.dockarea.width()
353
- self.docks['settings'].container().setSizes((int(win_width / 5),
580
+ self.docks['settings'].container().parent().setSizes((int(win_width / 5),
354
581
  int(2 * win_width / 5),
355
582
  int(2 * win_width / 5), 10, 10))
356
583
 
@@ -370,21 +597,34 @@ class BayesianOptimisation(CustomExt):
370
597
  {'title': 'max', 'name': 'max', 'type': 'float', 'value': 5},
371
598
  ]})
372
599
  self.settings.child('main_settings', 'bounds').addChildren(params)
373
- self.mainsettings_saver_loader.base_path = [self.model_class.__class__.__name__] + \
374
- self.modules_manager.selected_actuators_name
375
- self.mainsettings_saver_loader.load_config()
376
- self._save_main_settings = True
600
+
601
+ try:
602
+ self.mainsettings_saver_loader.base_path = [self.model_class.__class__.__name__] + \
603
+ self.modules_manager.selected_actuators_name
604
+ self.mainsettings_saver_loader.load_config()
605
+ self._save_main_settings = True
606
+ except Exception as e:
607
+ logger.exception(f'Could not load the configuration')
608
+
609
+ self.update_after_actuators_changed(self.modules_manager.selected_actuators_name)
610
+
611
+ @abc.abstractmethod
612
+ def update_after_actuators_changed(self, actuators: list[str]):
613
+ """ Actions to do after the actuators have been updated
614
+
615
+ To be implemented
616
+ """
617
+ ...
377
618
 
378
619
  def format_bounds(self):
379
- bound_dict = {}
620
+ bound_dict = OrderedDict([])
380
621
  for bound in self.settings.child('main_settings', 'bounds').children():
381
622
  bound_dict.update({bound.name(): (bound['min'], bound['max'])})
382
623
  return bound_dict
383
624
 
625
+ @abc.abstractmethod
384
626
  def set_algorithm(self):
385
- self.algorithm = BayesianAlgorithm(
386
- ini_random=self.settings['main_settings', 'ini_random'],
387
- bounds=self.format_bounds(),)
627
+ self.algorithm = ...
388
628
 
389
629
  def ini_model(self):
390
630
  try:
@@ -398,8 +638,9 @@ class BayesianOptimisation(CustomExt):
398
638
  self.get_action('model_led').set_as_true()
399
639
  self.set_action_enabled('ini_model', False)
400
640
 
401
- self.viewer_observable.update_viewers(['Viewer0D', 'Viewer0D'],
402
- ['Fitness', 'Individual'])
641
+ if self.DISPLAY_BEST:
642
+ self.viewer_observable.update_viewers(['Viewer0D', 'Viewer0D'],
643
+ ['Fitness', 'Individual'])
403
644
  self.settings.child('models', 'ini_model').setValue(True)
404
645
  self.settings.child('models', 'ini_runner').setOpts(enabled=True)
405
646
  self.set_action_enabled('ini_runner', True)
@@ -416,37 +657,68 @@ class BayesianOptimisation(CustomExt):
416
657
  except Exception as e:
417
658
  logger.exception(str(e))
418
659
 
419
- def ini_optimisation_runner(self):
420
- if self.is_action_checked('ini_runner'):
421
- self.set_algorithm()
422
-
423
- self.settings.child('models', 'ini_runner').setValue(True)
424
- self.enl_index = 0
425
-
426
- self.ini_temp_file()
427
- self.ini_live_plot()
428
-
429
- self.runner_thread = QtCore.QThread()
430
- runner = OptimisationRunner(self.model_class, self.modules_manager, self.algorithm,
431
- self.get_stopping_parameters())
432
- self.runner_thread.runner = runner
433
- runner.algo_output_signal.connect(self.process_output)
434
- runner.algo_finished.connect(self.optimisation_done)
435
- self.command_runner.connect(runner.queue_command)
660
+ def ini_saver(self):
661
+ if self.is_action_checked('save'):
662
+ self.module_and_data_saver = module_saving.OptimizerSaver(
663
+ self, enl_axis_names=self.modules_manager.selected_actuators_name,
664
+ enl_axis_units=[act.units for act in self.modules_manager.actuators])
665
+ self.create_new_file(True)
666
+ self.module_and_data_saver.h5saver = self.h5saver
436
667
 
437
- runner.moveToThread(self.runner_thread)
668
+ def ini_optimization_runner(self):
669
+ if self.is_action_checked('ini_runner'):
438
670
 
439
- self.runner_thread.start()
440
- self.get_action('runner_led').set_as_true()
441
- self.set_action_enabled('run', True)
442
- self.model_class.runner_initialized()
443
- self.update_utility_function()
671
+ if not self._ini_runner:
672
+ self._ini_runner = True
673
+ self.set_algorithm()
674
+
675
+ if self.is_action_checked('save'):
676
+ node = self.module_and_data_saver.get_set_node(new=True)
677
+ self.h5saver.settings.child('current_scan_name').setValue(node.name)
678
+
679
+ self.settings.child('models', 'ini_runner').setValue(True)
680
+ self.enl_index = 0
681
+
682
+ self.ini_temp_file()
683
+ self.ini_live_plot()
684
+
685
+ self.runner_thread = QtCore.QThread()
686
+ runner = self.runner(self.model_class, self.modules_manager, self.algorithm,
687
+ self.get_stopping_parameters())
688
+ self.runner_thread.runner = runner
689
+ runner.algo_output_signal.connect(self.process_output)
690
+ runner.algo_finished.connect(self.optimization_done)
691
+ runner.runner_command.connect(self.thread_status)
692
+ runner.saver_signal.connect(self.add_data)
693
+ self.command_runner.connect(runner.queue_command)
694
+
695
+ runner.moveToThread(self.runner_thread)
696
+
697
+ self.runner_thread.start()
698
+ self.get_action('runner_led').set_as_true()
699
+ self.set_action_enabled('run', True)
700
+ self.model_class.runner_initialized()
701
+ self.update_prediction_function()
444
702
  else:
445
703
  if self.is_action_checked('run'):
446
704
  self.get_action('run').trigger()
447
705
  QtWidgets.QApplication.processEvents()
448
- self.runner_thread.terminate()
706
+
707
+ self.splash.setVisible(True)
708
+ self.splash.showMessage('Quitting Runner Thread')
709
+ try:
710
+ self.command_runner.disconnect()
711
+ except TypeError:
712
+ pass
713
+ self.runner_thread.quit()
714
+ self.runner_thread.wait(5000)
715
+ if not self.runner_thread.isFinished():
716
+ self.runner_thread.terminate()
717
+ self.runner_thread.wait()
718
+ self.runner_thread = None
719
+ self.splash.setVisible(False)
449
720
  self.get_action('runner_led').set_as_false()
721
+ self._ini_runner = False
450
722
 
451
723
  def clean_h5_temp(self):
452
724
  if self.temp_path is not None:
@@ -456,30 +728,30 @@ class BayesianOptimisation(CustomExt):
456
728
  except Exception as e:
457
729
  logger.exception(str(e))
458
730
 
459
- def optimisation_done(self, dte: DataToExport):
731
+ def optimization_done(self, dte: DataToExport):
460
732
  self.go_to_best()
461
- self.optimisation_done_signal.emit(dte)
733
+ self.optimization_done_signal.emit(dte)
462
734
 
463
735
  def process_output(self, dte: DataToExport):
464
736
 
465
737
  self.enl_index += 1
466
- dwa_kappa = dte.remove(dte.get_data_from_name(DataNames.Kappa.name))
467
- self.settings.child('main_settings', 'utility', 'kappa_actual').setValue(
468
- float(dwa_kappa[0][0])
469
- )
470
-
471
- dwa_data = dte.remove(dte.get_data_from_name(DataNames.ProbedData.name))
472
- dwa_actuators: DataActuator = dte.remove(dte.get_data_from_name(DataNames.Actuators.name))
473
- self.viewer_observable.show_data(dte)
738
+ try:
739
+ dwa_tradeoff = dte.remove(dte.get_data_from_name(DataNames.Tradeoff))
740
+ self.settings.child('main_settings', 'prediction', 'tradeoff_actual').setValue(
741
+ float(dwa_tradeoff[0][0])
742
+ )
743
+ except KeyError:
744
+ pass
745
+ dwa_data = dte.remove(dte.get_data_from_name(DataNames.ProbedData))
746
+ dwa_actuators: DataActuator = dte.remove(dte.get_data_from_name(DataNames.Actuators))
747
+ if self.DISPLAY_BEST:
748
+ self.viewer_observable.show_data(dte)
474
749
 
475
- # dwa_observations = self.algorithm.get_dwa_obervations(
476
- # self.modules_manager.selected_actuators_name)
477
750
  self.model_class.update_plots()
478
751
 
479
- best_individual = dte.get_data_from_name(DataNames.Individual.name)
752
+ best_individual = dte.get_data_from_name(DataNames.Individual)
480
753
  best_indiv_as_list = [float(best_individual[ind][0]) for ind in range(len(best_individual))]
481
754
 
482
-
483
755
  self.enlargeable_saver.add_data('/RawData', dwa_data,
484
756
  axis_values=dwa_actuators.values())
485
757
  if len(best_indiv_as_list) == 1 or (
@@ -495,191 +767,26 @@ class BayesianOptimisation(CustomExt):
495
767
  def enable_controls_opti(self, enable: bool):
496
768
  pass
497
769
 
498
- def run_optimisation(self):
770
+ def run_optimization(self):
499
771
  if self.is_action_checked('run'):
772
+ self.set_action_enabled('save', False)
500
773
  self.get_action('run').set_icon('pause')
501
- self.command_runner.emit(utils.ThreadCommand('start', {}))
774
+ self.set_action_checked('gotobest', False)
775
+ self.set_action_enabled('gotobest', False)
776
+ self.command_runner.emit(utils.ThreadCommand(OptimizerToRunner.START))
502
777
  QtWidgets.QApplication.processEvents()
503
778
  QtWidgets.QApplication.processEvents()
504
- self.command_runner.emit(utils.ThreadCommand('run', {}))
779
+ self.command_runner.emit(utils.ThreadCommand(OptimizerToRunner.RUN))
505
780
  else:
506
781
  self.get_action('run').set_icon('run2')
507
- self.command_runner.emit(utils.ThreadCommand('stop', {}))
782
+ self.set_action_enabled('save', True)
783
+ self.command_runner.emit(utils.ThreadCommand(OptimizerToRunner.STOP))
508
784
  self.set_action_enabled('gotobest', True)
509
-
510
- QtWidgets.QApplication.processEvents()
511
-
512
-
513
- class OptimisationRunner(QtCore.QObject):
514
- algo_output_signal = QtCore.Signal(DataToExport)
515
- algo_finished = QtCore.Signal(DataToExport)
516
-
517
- def __init__(self, model_class: BayesianModelGeneric, modules_manager: ModulesManager,
518
- algorithm: BayesianAlgorithm, stopping_params: StoppingParameters):
519
- super().__init__()
520
-
521
- self.det_done_datas: DataToExport = None
522
- self.input_from_dets: float = None
523
- self.outputs: List[np.ndarray] = []
524
- self.dte_actuators: DataToExport = None
525
- self.stopping_params: StoppingParameters = stopping_params
526
-
527
- self.model_class: BayesianModelGeneric = model_class
528
- self.modules_manager: ModulesManager = modules_manager
529
-
530
- self.running = True
531
-
532
- self.optimisation_algorithm: BayesianAlgorithm = algorithm
533
-
534
- self._ind_iter: int = 0
535
-
536
- @QtCore.Slot(utils.ThreadCommand)
537
- def queue_command(self, command: utils.ThreadCommand):
538
- """
539
- """
540
- if command.command == "run":
541
- self.run_opti(**command.attribute)
542
-
543
- elif command.command == "stop":
544
- self.running = False
545
-
546
- elif command.command == 'utility':
547
- utility_params: UtilityParameters = command.attribute
548
- self.optimisation_algorithm.set_utility_function(
549
- utility_params.kind,
550
- kappa=utility_params.kappa,
551
- xi=utility_params.xi,
552
- kappa_decay=utility_params.kappa_decay,
553
- kappa_decay_delay=utility_params.kappa_decay_delay)
554
-
555
- elif command.command == 'stopping':
556
- self.stopping_params: StoppingParameters = command.attribute
557
-
558
- elif command.command == 'bounds':
559
- self.optimisation_algorithm.set_bounds(command.attribute)
560
-
561
- def run_opti(self, sync_detectors=True, sync_acts=True):
562
- """Start the optimisation loop
563
-
564
- Parameters
565
- ----------
566
- sync_detectors: (bool) if True will make sure all selected detectors (if any) all got their data before calling
567
- the model
568
- sync_acts: (bool) if True will make sure all selected actuators (if any) all reached their target position
569
- before calling the model
570
- """
571
- self.running = True
572
- converged = False
573
- try:
574
- if sync_detectors:
575
- self.modules_manager.connect_detectors()
576
- if sync_acts:
577
- self.modules_manager.connect_actuators()
578
-
579
- self.current_time = time.perf_counter()
580
- logger.info('Optimisation loop starting')
581
- while self.running:
582
- self._ind_iter += 1
583
-
584
- next_target = self.optimisation_algorithm.ask()
585
-
586
- self.outputs = next_target
587
- self.output_to_actuators: DataToActuators =\
588
- self.model_class.convert_output(
589
- self.outputs,
590
- best_individual=self.optimisation_algorithm.best_individual
591
- )
592
-
593
- self.modules_manager.move_actuators(self.output_to_actuators,
594
- self.output_to_actuators.mode,
595
- polling=sync_acts)
596
-
597
- # Do the evaluation (measurements)
598
- self.det_done_datas = self.modules_manager.grab_data()
599
- self.input_from_dets = self.model_class.convert_input(self.det_done_datas)
600
-
601
- # Run the algo internal mechanic
602
- self.optimisation_algorithm.tell(float(self.input_from_dets))
603
-
604
- dte = DataToExport('algo',
605
- data=[self.individual_as_data(
606
- np.array([self.optimisation_algorithm.best_fitness]),
607
- DataNames.Fitness.name),
608
- self.individual_as_data(
609
- self.optimisation_algorithm.best_individual,
610
- DataNames.Individual.name),
611
- DataCalculated(DataNames.ProbedData.name,
612
- data=[np.array([self.input_from_dets])],
613
- ),
614
- self.output_to_actuators.merge_as_dwa(
615
- 'Data0D', DataNames.Actuators.name),
616
- DataCalculated(
617
- DataNames.Kappa.name,
618
- data=[
619
- np.array([self.optimisation_algorithm.kappa])])
620
- ])
621
- self.algo_output_signal.emit(dte)
622
-
623
- self.optimisation_algorithm.update_utility_function()
624
-
625
- if self.optimisation_algorithm.stopping(self._ind_iter, self.stopping_params):
626
- converged = True
627
- break
628
-
629
- self.current_time = time.perf_counter()
630
785
  QtWidgets.QApplication.processEvents()
631
786
 
632
- logger.info('Optimisation loop exiting')
633
- self.modules_manager.connect_actuators(False)
634
- self.modules_manager.connect_detectors(False)
635
-
636
- if converged:
637
- self.algo_finished.emit(dte)
638
-
639
- except Exception as e:
640
- logger.exception(str(e))
641
-
642
- @staticmethod
643
- def individual_as_data(individual: np.ndarray, name: str = 'Individual') -> DataCalculated:
644
- return DataCalculated(name, data=[np.atleast_1d(np.squeeze(coordinate)) for coordinate in
645
- np.atleast_1d(np.squeeze(individual))])
646
-
647
-
648
- def main(init_qt=True):
649
- import sys
650
- from pathlib import Path
651
- from pymodaq.utils.daq_utils import get_set_preset_path
652
-
653
- if init_qt: # used for the test suite
654
- app = mkQApp("PyMoDAQ Dashboard")
655
-
656
- from pymodaq.dashboard import DashBoard
657
-
658
- win = QtWidgets.QMainWindow()
659
- area = gutils.dock.DockArea()
660
- win.setCentralWidget(area)
661
- win.resize(1000, 500)
662
-
663
- dashboard = DashBoard(area)
664
- daq_scan = None
665
- file = Path(get_set_preset_path()).joinpath(f"{'beam_steering_mock'}.xml")
666
-
667
- if file.exists():
668
- dashboard.set_preset_mode(file)
669
- daq_scan = dashboard.load_bayesian()
670
- else:
671
- msgBox = QtWidgets.QMessageBox()
672
- msgBox.setText(f"The default file specified in the configuration file does not exists!\n"
673
- f"{file}\n"
674
- f"Impossible to load the DAQScan Module")
675
- msgBox.setStandardButtons(msgBox.Ok)
676
- ret = msgBox.exec()
787
+ def thread_status(self, status: utils.ThreadCommand):
788
+ pass
677
789
 
678
- if init_qt:
679
- sys.exit(app.exec_())
680
- return dashboard, daq_scan, win
681
790
 
682
791
 
683
- if __name__ == '__main__':
684
- main()
685
792