pymodaq 5.0.18__py3-none-any.whl → 5.1.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.
Potentially problematic release.
This version of pymodaq might be problematic. Click here for more details.
- pymodaq/__init__.py +23 -11
- pymodaq/control_modules/__init__.py +1 -0
- pymodaq/control_modules/daq_move.py +451 -246
- pymodaq/control_modules/daq_move_ui/__init__.py +0 -0
- pymodaq/control_modules/daq_move_ui/factory.py +48 -0
- pymodaq/control_modules/{daq_move_ui.py → daq_move_ui/ui_base.py} +168 -210
- pymodaq/control_modules/daq_move_ui/uis/__init__.py +0 -0
- pymodaq/control_modules/daq_move_ui/uis/binary.py +139 -0
- pymodaq/control_modules/daq_move_ui/uis/original.py +120 -0
- pymodaq/control_modules/daq_move_ui/uis/relative.py +124 -0
- pymodaq/control_modules/daq_move_ui/uis/simple.py +126 -0
- pymodaq/control_modules/daq_viewer.py +113 -101
- pymodaq/control_modules/daq_viewer_ui.py +41 -31
- pymodaq/control_modules/mocks.py +2 -2
- pymodaq/control_modules/move_utility_classes.py +113 -41
- pymodaq/control_modules/thread_commands.py +137 -0
- pymodaq/control_modules/ui_utils.py +72 -0
- pymodaq/control_modules/utils.py +107 -63
- pymodaq/control_modules/viewer_utility_classes.py +13 -17
- pymodaq/dashboard.py +1294 -625
- pymodaq/examples/qt_less_standalone_module.py +48 -11
- pymodaq/extensions/__init__.py +8 -3
- pymodaq/extensions/adaptive/__init__.py +2 -0
- pymodaq/extensions/adaptive/adaptive_optimization.py +179 -0
- pymodaq/extensions/adaptive/loss_function/_1d_loss_functions.py +73 -0
- pymodaq/extensions/adaptive/loss_function/_2d_loss_functions.py +73 -0
- pymodaq/extensions/adaptive/loss_function/__init__.py +3 -0
- pymodaq/extensions/adaptive/loss_function/loss_factory.py +110 -0
- pymodaq/extensions/adaptive/utils.py +123 -0
- pymodaq/extensions/bayesian/__init__.py +1 -1
- pymodaq/extensions/bayesian/acquisition/__init__.py +2 -0
- pymodaq/extensions/bayesian/acquisition/acquisition_function_factory.py +80 -0
- pymodaq/extensions/bayesian/acquisition/base_acquisition_function.py +105 -0
- pymodaq/extensions/bayesian/bayesian_optimization.py +143 -0
- pymodaq/extensions/bayesian/utils.py +71 -297
- pymodaq/extensions/daq_logger/daq_logger.py +7 -12
- pymodaq/extensions/daq_logger/h5logging.py +1 -1
- pymodaq/extensions/daq_scan.py +30 -55
- pymodaq/extensions/data_mixer/__init__.py +0 -0
- pymodaq/extensions/data_mixer/daq_0Dviewer_DataMixer.py +97 -0
- pymodaq/extensions/data_mixer/data_mixer.py +262 -0
- pymodaq/extensions/data_mixer/model.py +108 -0
- pymodaq/extensions/data_mixer/models/__init__.py +0 -0
- pymodaq/extensions/data_mixer/models/equation_model.py +91 -0
- pymodaq/extensions/data_mixer/models/gaussian_fit_model.py +65 -0
- pymodaq/extensions/data_mixer/parser.py +53 -0
- pymodaq/extensions/data_mixer/utils.py +23 -0
- pymodaq/extensions/h5browser.py +3 -34
- pymodaq/extensions/optimizers_base/__init__.py +0 -0
- pymodaq/extensions/optimizers_base/optimizer.py +1016 -0
- pymodaq/extensions/optimizers_base/thread_commands.py +22 -0
- pymodaq/extensions/optimizers_base/utils.py +427 -0
- pymodaq/extensions/pid/actuator_controller.py +3 -2
- pymodaq/extensions/pid/daq_move_PID.py +107 -30
- pymodaq/extensions/pid/pid_controller.py +613 -287
- pymodaq/extensions/pid/utils.py +8 -5
- pymodaq/extensions/utils.py +17 -2
- pymodaq/resources/config_template.toml +57 -0
- pymodaq/resources/preset_default.xml +1 -1
- pymodaq/utils/config.py +10 -4
- pymodaq/utils/daq_utils.py +14 -0
- pymodaq/utils/data.py +1 -0
- pymodaq/utils/gui_utils/loader_utils.py +25 -15
- pymodaq/utils/h5modules/module_saving.py +134 -22
- pymodaq/utils/leco/daq_move_LECODirector.py +123 -84
- pymodaq/utils/leco/daq_xDviewer_LECODirector.py +84 -97
- pymodaq/utils/leco/director_utils.py +32 -16
- pymodaq/utils/leco/leco_director.py +104 -27
- pymodaq/utils/leco/pymodaq_listener.py +186 -97
- pymodaq/utils/leco/rpc_method_definitions.py +43 -0
- pymodaq/utils/leco/utils.py +25 -25
- pymodaq/utils/managers/batchscan_manager.py +12 -11
- pymodaq/utils/managers/modules_manager.py +74 -33
- pymodaq/utils/managers/overshoot_manager.py +11 -10
- pymodaq/utils/managers/preset_manager.py +100 -64
- pymodaq/utils/managers/preset_manager_utils.py +163 -107
- pymodaq/utils/managers/remote_manager.py +21 -16
- pymodaq/utils/scanner/scan_factory.py +12 -3
- pymodaq/utils/scanner/scan_selector.py +1 -3
- pymodaq/utils/scanner/scanner.py +35 -6
- pymodaq/utils/scanner/scanners/_1d_scanners.py +15 -46
- pymodaq/utils/scanner/scanners/_2d_scanners.py +21 -68
- pymodaq/utils/scanner/scanners/sequential.py +50 -31
- pymodaq/utils/scanner/scanners/tabular.py +45 -28
- {pymodaq-5.0.18.dist-info → pymodaq-5.1.0.dist-info}/METADATA +7 -6
- pymodaq-5.1.0.dist-info/RECORD +154 -0
- {pymodaq-5.0.18.dist-info → pymodaq-5.1.0.dist-info}/entry_points.txt +0 -2
- pymodaq/extensions/bayesian/bayesian_optimisation.py +0 -690
- pymodaq/utils/leco/desktop.ini +0 -2
- pymodaq-5.0.18.dist-info/RECORD +0 -121
- {pymodaq-5.0.18.dist-info → pymodaq-5.1.0.dist-info}/WHEEL +0 -0
- {pymodaq-5.0.18.dist-info → pymodaq-5.1.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -4,133 +4,129 @@ Created the 31/08/2023
|
|
|
4
4
|
|
|
5
5
|
@author: Sebastien Weber
|
|
6
6
|
"""
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
from typing import List, TYPE_CHECKING, Union, Dict, Tuple, Iterable
|
|
9
|
-
|
|
10
|
-
import
|
|
11
|
-
import pkgutil
|
|
12
|
-
import inspect
|
|
9
|
+
|
|
10
|
+
import bayes_opt.exception
|
|
13
11
|
import numpy as np
|
|
14
12
|
from collections import namedtuple
|
|
15
13
|
|
|
16
14
|
from bayes_opt import BayesianOptimization
|
|
17
|
-
from bayes_opt import
|
|
15
|
+
from bayes_opt.exception import TargetSpaceEmptyError
|
|
16
|
+
|
|
18
17
|
|
|
19
|
-
from pymodaq_utils.utils import find_dict_in_list_from_key_val, get_entrypoints
|
|
20
18
|
from pymodaq_utils.logger import set_logger, get_module_name
|
|
21
|
-
from pymodaq_utils.enums import BaseEnum
|
|
22
|
-
from pymodaq_utils.config import BaseConfig
|
|
23
19
|
|
|
24
|
-
from pymodaq_gui.parameter import Parameter
|
|
25
|
-
from pymodaq_gui.plotting.data_viewers.viewer import ViewersEnum
|
|
26
20
|
|
|
27
21
|
from pymodaq_data.data import (DataToExport, DataCalculated,
|
|
28
22
|
DataRaw, Axis)
|
|
29
23
|
|
|
30
|
-
from pymodaq.utils.data import DataActuator, DataToActuators
|
|
31
|
-
from pymodaq.utils.managers.modules_manager import ModulesManager
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if TYPE_CHECKING:
|
|
35
|
-
from pymodaq.extensions.bayesian.bayesian_optimisation import BayesianOptimisation
|
|
36
24
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
class StopType(BaseEnum):
|
|
41
|
-
Predict = 0
|
|
25
|
+
from pymodaq.extensions.bayesian.acquisition import GenericAcquisitionFunctionFactory
|
|
42
26
|
|
|
27
|
+
from pymodaq.extensions.optimizers_base.utils import (
|
|
28
|
+
GenericAlgorithm, OptimizerModelDefault, StopType, StoppingParameters,
|
|
29
|
+
OptimizerConfig, PredictionError)
|
|
43
30
|
|
|
44
|
-
class UtilityKind(BaseEnum):
|
|
45
|
-
ucb = 'Upper Confidence Bound'
|
|
46
|
-
ei = 'Expected Improvement'
|
|
47
|
-
poi = 'Probability of Improvement'
|
|
48
31
|
|
|
49
|
-
|
|
50
|
-
UtilityParameters = namedtuple('UtilityParameters',
|
|
51
|
-
['kind', 'kappa', 'xi', 'kappa_decay', 'kappa_decay_delay'])
|
|
32
|
+
logger = set_logger(get_module_name(__file__))
|
|
52
33
|
|
|
53
34
|
|
|
54
|
-
|
|
55
|
-
|
|
35
|
+
class BayesianConfig(OptimizerConfig):
|
|
36
|
+
config_name = f"bayesian_settings"
|
|
56
37
|
|
|
57
38
|
|
|
58
|
-
class BayesianAlgorithm:
|
|
59
39
|
|
|
60
|
-
|
|
40
|
+
class BayesianAlgorithm(GenericAlgorithm):
|
|
61
41
|
|
|
42
|
+
def __init__(self, ini_random: int, bounds: dict[str, tuple[float, float]], actuators: list[str], **kwargs):
|
|
43
|
+
super().__init__(ini_random, bounds, actuators)
|
|
62
44
|
self._algo = BayesianOptimization(f=None,
|
|
63
45
|
pbounds=bounds,
|
|
64
46
|
**kwargs
|
|
65
47
|
)
|
|
66
|
-
self.
|
|
67
|
-
self._suggested_coordinates: List[np.ndarray] = []
|
|
68
|
-
self.ini_random_points = ini_random
|
|
69
|
-
self.kappa = 2.5
|
|
48
|
+
self.sorting_index: list = None
|
|
70
49
|
|
|
71
|
-
|
|
50
|
+
def set_prediction_function(self, kind: str = '', **kwargs):
|
|
51
|
+
self._prediction = GenericAcquisitionFunctionFactory.create(kind, **kwargs)
|
|
72
52
|
|
|
73
|
-
def
|
|
74
|
-
|
|
75
|
-
|
|
53
|
+
def update_prediction_function(self):
|
|
54
|
+
""" Update the parameters of the acquisition function (kappa decay for instance)"""
|
|
55
|
+
self._prediction.decay_exploration()
|
|
76
56
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
self.
|
|
80
|
-
|
|
57
|
+
@property
|
|
58
|
+
def tradeoff(self):
|
|
59
|
+
return self._prediction.tradeoff
|
|
60
|
+
|
|
61
|
+
def get_random_point(self) -> dict[str, float]:
|
|
62
|
+
""" Get a random point coordinates in the defined bounds"""
|
|
63
|
+
point = dict()
|
|
64
|
+
for key, vals in self.bounds.items():
|
|
65
|
+
point[key] = (np.max(vals) - np.min(vals)) * np.random.random_sample() + np.min(vals)
|
|
66
|
+
return point
|
|
81
67
|
|
|
82
68
|
@property
|
|
83
|
-
def bounds(self) ->
|
|
84
|
-
|
|
69
|
+
def bounds(self) -> dict[str, float]:
|
|
70
|
+
""" Return bounds as a dict.
|
|
71
|
+
"""
|
|
72
|
+
return self._algo.space.array_to_params(self._algo.space.bounds)
|
|
85
73
|
|
|
86
74
|
@bounds.setter
|
|
87
|
-
def bounds(self, bounds:
|
|
75
|
+
def bounds(self, bounds: Dict[str, Tuple[float, float]]):
|
|
88
76
|
if isinstance(bounds, dict):
|
|
89
77
|
self._algo.set_bounds(bounds)
|
|
90
78
|
else:
|
|
91
|
-
|
|
79
|
+
raise TypeError('Bounds should be defined as a dictionary')
|
|
80
|
+
|
|
81
|
+
def prediction_ask(self) -> dict[str, float]:
|
|
82
|
+
""" Ask the prediction function or algo to provide the next point to probe
|
|
83
|
+
|
|
84
|
+
Warning the space algo object is sorting by name the bounds...
|
|
85
|
+
"""
|
|
86
|
+
try:
|
|
87
|
+
return self._algo.space.array_to_params(self._prediction.suggest(self._algo._gp, self._algo.space))
|
|
88
|
+
except TargetSpaceEmptyError as e:
|
|
89
|
+
raise PredictionError(str(e))
|
|
92
90
|
|
|
93
|
-
def get_random_point(self) -> np.ndarray:
|
|
94
|
-
""" Get a random point coordinates in the defined bounds"""
|
|
95
|
-
point = []
|
|
96
|
-
for bound in self.bounds:
|
|
97
|
-
point.append((np.max(bound) - np.min(bound)) * np.random.random_sample() +
|
|
98
|
-
np.min(bound))
|
|
99
|
-
return np.array(point)
|
|
100
|
-
|
|
101
|
-
def ask(self) -> np.ndarray:
|
|
102
|
-
if self.ini_random_points > 0:
|
|
103
|
-
self.ini_random_points -= 1
|
|
104
|
-
self._next_point = self.get_random_point()
|
|
105
|
-
else:
|
|
106
|
-
self._next_point = self._algo.space.params_to_array(self._algo.suggest(self._utility))
|
|
107
|
-
self._suggested_coordinates.append(self._next_point)
|
|
108
|
-
return self._next_point
|
|
109
91
|
|
|
110
92
|
def tell(self, function_value: float):
|
|
111
93
|
self._algo.register(params=self._next_point, target=function_value)
|
|
112
|
-
|
|
94
|
+
|
|
113
95
|
@property
|
|
114
96
|
def best_fitness(self) -> float:
|
|
115
|
-
|
|
97
|
+
if self._algo.max is None:
|
|
98
|
+
return 0.001
|
|
99
|
+
else:
|
|
100
|
+
return self._algo.max['target']
|
|
116
101
|
|
|
117
102
|
@property
|
|
118
|
-
def best_individual(self) -> Union[
|
|
103
|
+
def best_individual(self) -> Union[dict[str, float], None]:
|
|
119
104
|
if self._algo.max is None:
|
|
120
105
|
return None
|
|
121
106
|
else:
|
|
122
107
|
max_param = self._algo.max.get('params', None)
|
|
123
108
|
if max_param is None:
|
|
124
109
|
return None
|
|
125
|
-
return
|
|
110
|
+
return max_param
|
|
126
111
|
|
|
127
112
|
def stopping(self, ind_iter: int, stopping_parameters: StoppingParameters):
|
|
128
|
-
if
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
113
|
+
if stopping_parameters.stop_type != StopType.NONE:
|
|
114
|
+
if ind_iter >= stopping_parameters.niter: # For instance StopType.ITER
|
|
115
|
+
return True
|
|
116
|
+
if ind_iter > stopping_parameters.npoints:
|
|
117
|
+
if stopping_parameters.stop_type == StopType.PREDICT:
|
|
118
|
+
coordinates = np.atleast_1d([
|
|
119
|
+
[coordinates[act] for coordinates in self._suggested_coordinates[-stopping_parameters.npoints:]]
|
|
120
|
+
for act in self.actuators])
|
|
121
|
+
return np.all(np.abs((np.std(coordinates, axis=1) / np.mean(coordinates, axis=1)))
|
|
122
|
+
< stopping_parameters.tolerance)
|
|
123
|
+
elif stopping_parameters.stop_type == StopType.BEST:
|
|
124
|
+
coordinates = np.atleast_1d(
|
|
125
|
+
[[best['params'][act] for best in
|
|
126
|
+
sorted(self._algo.res, key=lambda x: x['target'])[-stopping_parameters.npoints:]]
|
|
127
|
+
for act in self.actuators])
|
|
128
|
+
return np.all(np.abs((np.std(coordinates, axis=1) / np.mean(coordinates, axis=1)))
|
|
129
|
+
< stopping_parameters.tolerance)
|
|
134
130
|
return False
|
|
135
131
|
|
|
136
132
|
def _posterior(self, x_obs, y_obs, grid):
|
|
@@ -181,226 +177,4 @@ class BayesianAlgorithm:
|
|
|
181
177
|
return dwa_measured, dwa_prediction
|
|
182
178
|
|
|
183
179
|
|
|
184
|
-
class BayesianModelGeneric(ABC):
|
|
185
|
-
|
|
186
|
-
optimisation_algorithm: BayesianAlgorithm = BayesianAlgorithm
|
|
187
|
-
|
|
188
|
-
actuators_name: List[str] = []
|
|
189
|
-
detectors_name: List[str] = []
|
|
190
|
-
|
|
191
|
-
observables_dim: List[ViewersEnum] = []
|
|
192
|
-
|
|
193
|
-
params = [] # to be subclassed
|
|
194
|
-
|
|
195
|
-
def __init__(self, optimisation_controller: 'BayesianOptimisation'):
|
|
196
|
-
self.optimisation_controller = optimisation_controller # instance of the pid_controller using this model
|
|
197
|
-
self.modules_manager: ModulesManager = optimisation_controller.modules_manager
|
|
198
|
-
|
|
199
|
-
self.settings = self.optimisation_controller.settings.child('models', 'model_params') # set of parameters
|
|
200
|
-
self.check_modules(self.modules_manager)
|
|
201
|
-
|
|
202
|
-
def check_modules(self, modules_manager):
|
|
203
|
-
for act in self.actuators_name:
|
|
204
|
-
if act not in modules_manager.actuators_name:
|
|
205
|
-
logger.warning(f'The actuator {act} defined in the model is'
|
|
206
|
-
f' not present in the Dashboard')
|
|
207
|
-
return False
|
|
208
|
-
for det in self.detectors_name:
|
|
209
|
-
if det not in modules_manager.detectors_name:
|
|
210
|
-
logger.warning(f'The detector {det} defined in the model is'
|
|
211
|
-
f' not present in the Dashboard')
|
|
212
|
-
|
|
213
|
-
def update_detector_names(self):
|
|
214
|
-
names = self.optimisation_controller.settings.child(
|
|
215
|
-
'main_settings', 'detector_modules').value()['selected']
|
|
216
|
-
self.data_names = []
|
|
217
|
-
for name in names:
|
|
218
|
-
name = name.split('//')
|
|
219
|
-
self.data_names.append(name)
|
|
220
|
-
|
|
221
|
-
def update_settings(self, param: Parameter):
|
|
222
|
-
"""
|
|
223
|
-
Get a parameter instance whose value has been modified by a user on the UI
|
|
224
|
-
To be overwritten in child class
|
|
225
|
-
"""
|
|
226
|
-
...
|
|
227
|
-
|
|
228
|
-
def update_plots(self):
|
|
229
|
-
""" Called when updating the live plots """
|
|
230
|
-
pass
|
|
231
|
-
|
|
232
|
-
def ini_model_base(self):
|
|
233
|
-
self.modules_manager.selected_actuators_name = self.actuators_name
|
|
234
|
-
self.modules_manager.selected_detectors_name = self.detectors_name
|
|
235
|
-
|
|
236
|
-
self.ini_model()
|
|
237
|
-
|
|
238
|
-
def ini_model(self):
|
|
239
|
-
""" To be subclassed
|
|
240
180
|
|
|
241
|
-
Initialize whatever is needed by your custom model
|
|
242
|
-
"""
|
|
243
|
-
raise NotImplementedError
|
|
244
|
-
|
|
245
|
-
def runner_initialized(self):
|
|
246
|
-
""" To be subclassed
|
|
247
|
-
|
|
248
|
-
Initialize whatever is needed by your custom model after the optimization runner is
|
|
249
|
-
initialized
|
|
250
|
-
"""
|
|
251
|
-
pass
|
|
252
|
-
|
|
253
|
-
def convert_input(self, measurements: DataToExport) -> float:
|
|
254
|
-
"""
|
|
255
|
-
Convert the measurements in the units to be fed to the Optimisation Controller
|
|
256
|
-
Parameters
|
|
257
|
-
----------
|
|
258
|
-
measurements: DataToExport
|
|
259
|
-
data object exported from the detectors from which the model extract a float value
|
|
260
|
-
(fitness) to be fed to the algorithm
|
|
261
|
-
|
|
262
|
-
Returns
|
|
263
|
-
-------
|
|
264
|
-
float
|
|
265
|
-
|
|
266
|
-
"""
|
|
267
|
-
raise NotImplementedError
|
|
268
|
-
|
|
269
|
-
def convert_output(self, outputs: List[np.ndarray], best_individual=None) -> DataToActuators:
|
|
270
|
-
""" Convert the output of the Optimisation Controller in units to be fed into the actuators
|
|
271
|
-
Parameters
|
|
272
|
-
----------
|
|
273
|
-
outputs: list of numpy ndarray
|
|
274
|
-
output value from the controller from which the model extract a value of the same units as the actuators
|
|
275
|
-
best_individual: np.ndarray
|
|
276
|
-
the coordinates of the best individual so far
|
|
277
|
-
Returns
|
|
278
|
-
-------
|
|
279
|
-
DataToActuatorOpti: derived from DataToExport. Contains value to be fed to the actuators with a a mode
|
|
280
|
-
attribute, either 'rel' for relative or 'abs' for absolute.
|
|
281
|
-
|
|
282
|
-
"""
|
|
283
|
-
raise NotImplementedError
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
class BayesianModelDefault(BayesianModelGeneric):
|
|
287
|
-
|
|
288
|
-
actuators_name: List[str] = [] # to be populated dynamically at instantiation
|
|
289
|
-
detectors_name: List[str] = [] # to be populated dynamically at instantiation
|
|
290
|
-
|
|
291
|
-
params = [{'title': 'Optimizing signal', 'name': 'optimizing_signal', 'type': 'group',
|
|
292
|
-
'children': [
|
|
293
|
-
{'title': 'Get data', 'name': 'data_probe', 'type': 'action'},
|
|
294
|
-
{'title': 'Optimize 0Ds:', 'name': 'optimize_0d', 'type': 'itemselect',
|
|
295
|
-
'checkbox': True},
|
|
296
|
-
]},]
|
|
297
|
-
|
|
298
|
-
def __init__(self, optimisation_controller: 'BayesianOptimisation'):
|
|
299
|
-
self.actuators_name = optimisation_controller.modules_manager.actuators_name
|
|
300
|
-
self.detectors_name = optimisation_controller.modules_manager.detectors_name
|
|
301
|
-
super().__init__(optimisation_controller)
|
|
302
|
-
|
|
303
|
-
self.settings.child('optimizing_signal', 'data_probe').sigActivated.connect(
|
|
304
|
-
self.optimize_from)
|
|
305
|
-
|
|
306
|
-
def ini_model(self):
|
|
307
|
-
pass
|
|
308
|
-
|
|
309
|
-
def optimize_from(self):
|
|
310
|
-
self.modules_manager.get_det_data_list()
|
|
311
|
-
data0D = self.modules_manager.settings['data_dimensions', 'det_data_list0D']
|
|
312
|
-
data0D['selected'] = data0D['all_items']
|
|
313
|
-
self.settings.child('optimizing_signal', 'optimize_0d').setValue(data0D)
|
|
314
|
-
|
|
315
|
-
def update_settings(self, param: Parameter):
|
|
316
|
-
pass
|
|
317
|
-
|
|
318
|
-
def convert_input(self, measurements: DataToExport) -> float:
|
|
319
|
-
""" Convert the measurements in the units to be fed to the Optimisation Controller
|
|
320
|
-
|
|
321
|
-
Parameters
|
|
322
|
-
----------
|
|
323
|
-
measurements: DataToExport
|
|
324
|
-
data object exported from the detectors from which the model extract a float value
|
|
325
|
-
(fitness) to be fed to the algorithm
|
|
326
|
-
|
|
327
|
-
Returns
|
|
328
|
-
-------
|
|
329
|
-
float
|
|
330
|
-
|
|
331
|
-
"""
|
|
332
|
-
data_name: str = self.settings['optimizing_signal', 'optimize_0d']['selected'][0]
|
|
333
|
-
origin, name = data_name.split('/')
|
|
334
|
-
return float(measurements.get_data_from_name_origin(name, origin).data[0][0])
|
|
335
|
-
|
|
336
|
-
def convert_output(self, outputs: List[np.ndarray], best_individual=None) -> DataToActuators:
|
|
337
|
-
""" Convert the output of the Optimisation Controller in units to be fed into the actuators
|
|
338
|
-
Parameters
|
|
339
|
-
----------
|
|
340
|
-
outputs: list of numpy ndarray
|
|
341
|
-
output value from the controller from which the model extract a value of the same units as the actuators
|
|
342
|
-
best_individual: np.ndarray
|
|
343
|
-
the coordinates of the best individual so far
|
|
344
|
-
|
|
345
|
-
Returns
|
|
346
|
-
-------
|
|
347
|
-
DataToActuators: derived from DataToExport. Contains value to be fed to the actuators
|
|
348
|
-
with a mode attribute, either 'rel' for relative or 'abs' for absolute.
|
|
349
|
-
|
|
350
|
-
"""
|
|
351
|
-
return DataToActuators('outputs', mode='abs',
|
|
352
|
-
data=[DataActuator(self.modules_manager.actuators_name[ind],
|
|
353
|
-
data=float(outputs[ind])) for ind in
|
|
354
|
-
range(len(outputs))])
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
def get_bayesian_models(model_name=None):
|
|
358
|
-
"""
|
|
359
|
-
Get PID Models as a list to instantiate Control Actuators per degree of liberty in the model
|
|
360
|
-
|
|
361
|
-
Returns
|
|
362
|
-
-------
|
|
363
|
-
list: list of disct containting the name and python module of the found models
|
|
364
|
-
"""
|
|
365
|
-
models_import = []
|
|
366
|
-
discovered_models = get_entrypoints(group='pymodaq.models')
|
|
367
|
-
if len(discovered_models) > 0:
|
|
368
|
-
for pkg in discovered_models:
|
|
369
|
-
try:
|
|
370
|
-
module = importlib.import_module(pkg.value)
|
|
371
|
-
module_name = pkg.value
|
|
372
|
-
|
|
373
|
-
for mod in pkgutil.iter_modules([
|
|
374
|
-
str(Path(module.__file__).parent.joinpath('models'))]):
|
|
375
|
-
try:
|
|
376
|
-
model_module = importlib.import_module(f'{module_name}.models.{mod.name}',
|
|
377
|
-
module)
|
|
378
|
-
classes = inspect.getmembers(model_module, inspect.isclass)
|
|
379
|
-
for name, klass in classes:
|
|
380
|
-
if issubclass(klass, BayesianModelGeneric):
|
|
381
|
-
if find_dict_in_list_from_key_val(models_import, 'name', mod.name)\
|
|
382
|
-
is None:
|
|
383
|
-
models_import.append({'name': klass.__name__,
|
|
384
|
-
'module': model_module,
|
|
385
|
-
'class': klass})
|
|
386
|
-
|
|
387
|
-
except Exception as e:
|
|
388
|
-
logger.warning(str(e))
|
|
389
|
-
|
|
390
|
-
except Exception as e:
|
|
391
|
-
logger.warning(f'Impossible to import the {pkg.value} bayesian model: {str(e)}')
|
|
392
|
-
if find_dict_in_list_from_key_val(models_import, 'name', 'BayesianModelDefault') \
|
|
393
|
-
is None:
|
|
394
|
-
models_import.append({'name': 'BayesianModelDefault',
|
|
395
|
-
'module': inspect.getmodule(BayesianModelDefault),
|
|
396
|
-
'class': BayesianModelDefault})
|
|
397
|
-
if model_name is None:
|
|
398
|
-
return models_import
|
|
399
|
-
else:
|
|
400
|
-
return find_dict_in_list_from_key_val(models_import, 'name', model_name)
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
class BayesianConfig(BaseConfig):
|
|
404
|
-
"""Main class to deal with configuration values for this plugin"""
|
|
405
|
-
config_template_path = None
|
|
406
|
-
config_name = f"bayesian_settings"
|
|
@@ -75,8 +75,6 @@ class DAQ_Logger(CustomExt):
|
|
|
75
75
|
super().__init__(dockarea, dashboard)
|
|
76
76
|
|
|
77
77
|
self.wait_time = 1000
|
|
78
|
-
|
|
79
|
-
self.logger_thread = None
|
|
80
78
|
self.logger: Union[H5Logger, DataBaseLogger] = None
|
|
81
79
|
self.setup_ui()
|
|
82
80
|
|
|
@@ -293,25 +291,22 @@ class DAQ_Logger(CustomExt):
|
|
|
293
291
|
res = self.set_logging()
|
|
294
292
|
|
|
295
293
|
# mandatory to deal with multithreads
|
|
296
|
-
if self.
|
|
294
|
+
if self.runner_thread is not None:
|
|
297
295
|
self.command_DAQ_signal.disconnect()
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
while not self.logger_thread.isFinished():
|
|
301
|
-
QThread.msleep(100)
|
|
302
|
-
self.logger_thread = None
|
|
296
|
+
self.exit_runner_thread()
|
|
297
|
+
self.runner_thread = None
|
|
303
298
|
|
|
304
|
-
self.
|
|
299
|
+
self.runner_thread = QThread()
|
|
305
300
|
|
|
306
301
|
log_acquisition = DAQ_Logging(self.settings, self.logger, self.modules_manager)
|
|
307
302
|
|
|
308
|
-
log_acquisition.moveToThread(self.
|
|
303
|
+
log_acquisition.moveToThread(self.runner_thread)
|
|
309
304
|
|
|
310
305
|
self.command_DAQ_signal[list].connect(log_acquisition.queue_command)
|
|
311
306
|
log_acquisition.status_sig[list].connect(self.thread_status)
|
|
312
307
|
|
|
313
|
-
self.
|
|
314
|
-
self.
|
|
308
|
+
self.runner_thread.log_acquisition = log_acquisition
|
|
309
|
+
self.runner_thread.start()
|
|
315
310
|
|
|
316
311
|
self._actions['start'].setEnabled(False)
|
|
317
312
|
QtWidgets.QApplication.processEvents()
|
|
@@ -45,7 +45,7 @@ class H5Logger(AbstractLogger):
|
|
|
45
45
|
|
|
46
46
|
self.module_and_data_saver = module_saving.LoggerSaver(self)
|
|
47
47
|
for det in self.modules_manager.detectors_all:
|
|
48
|
-
det.module_and_data_saver = module_saving.
|
|
48
|
+
det.module_and_data_saver = module_saving.DetectorTimeSaver(det)
|
|
49
49
|
self.module_and_data_saver.h5saver = self.h5saver # will update its h5saver and all submodules's h5saver
|
|
50
50
|
|
|
51
51
|
def close(self):
|