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.

Files changed (92) hide show
  1. pymodaq/__init__.py +23 -11
  2. pymodaq/control_modules/__init__.py +1 -0
  3. pymodaq/control_modules/daq_move.py +451 -246
  4. pymodaq/control_modules/daq_move_ui/__init__.py +0 -0
  5. pymodaq/control_modules/daq_move_ui/factory.py +48 -0
  6. pymodaq/control_modules/{daq_move_ui.py → daq_move_ui/ui_base.py} +168 -210
  7. pymodaq/control_modules/daq_move_ui/uis/__init__.py +0 -0
  8. pymodaq/control_modules/daq_move_ui/uis/binary.py +139 -0
  9. pymodaq/control_modules/daq_move_ui/uis/original.py +120 -0
  10. pymodaq/control_modules/daq_move_ui/uis/relative.py +124 -0
  11. pymodaq/control_modules/daq_move_ui/uis/simple.py +126 -0
  12. pymodaq/control_modules/daq_viewer.py +113 -101
  13. pymodaq/control_modules/daq_viewer_ui.py +41 -31
  14. pymodaq/control_modules/mocks.py +2 -2
  15. pymodaq/control_modules/move_utility_classes.py +113 -41
  16. pymodaq/control_modules/thread_commands.py +137 -0
  17. pymodaq/control_modules/ui_utils.py +72 -0
  18. pymodaq/control_modules/utils.py +107 -63
  19. pymodaq/control_modules/viewer_utility_classes.py +13 -17
  20. pymodaq/dashboard.py +1294 -625
  21. pymodaq/examples/qt_less_standalone_module.py +48 -11
  22. pymodaq/extensions/__init__.py +8 -3
  23. pymodaq/extensions/adaptive/__init__.py +2 -0
  24. pymodaq/extensions/adaptive/adaptive_optimization.py +179 -0
  25. pymodaq/extensions/adaptive/loss_function/_1d_loss_functions.py +73 -0
  26. pymodaq/extensions/adaptive/loss_function/_2d_loss_functions.py +73 -0
  27. pymodaq/extensions/adaptive/loss_function/__init__.py +3 -0
  28. pymodaq/extensions/adaptive/loss_function/loss_factory.py +110 -0
  29. pymodaq/extensions/adaptive/utils.py +123 -0
  30. pymodaq/extensions/bayesian/__init__.py +1 -1
  31. pymodaq/extensions/bayesian/acquisition/__init__.py +2 -0
  32. pymodaq/extensions/bayesian/acquisition/acquisition_function_factory.py +80 -0
  33. pymodaq/extensions/bayesian/acquisition/base_acquisition_function.py +105 -0
  34. pymodaq/extensions/bayesian/bayesian_optimization.py +143 -0
  35. pymodaq/extensions/bayesian/utils.py +71 -297
  36. pymodaq/extensions/daq_logger/daq_logger.py +7 -12
  37. pymodaq/extensions/daq_logger/h5logging.py +1 -1
  38. pymodaq/extensions/daq_scan.py +30 -55
  39. pymodaq/extensions/data_mixer/__init__.py +0 -0
  40. pymodaq/extensions/data_mixer/daq_0Dviewer_DataMixer.py +97 -0
  41. pymodaq/extensions/data_mixer/data_mixer.py +262 -0
  42. pymodaq/extensions/data_mixer/model.py +108 -0
  43. pymodaq/extensions/data_mixer/models/__init__.py +0 -0
  44. pymodaq/extensions/data_mixer/models/equation_model.py +91 -0
  45. pymodaq/extensions/data_mixer/models/gaussian_fit_model.py +65 -0
  46. pymodaq/extensions/data_mixer/parser.py +53 -0
  47. pymodaq/extensions/data_mixer/utils.py +23 -0
  48. pymodaq/extensions/h5browser.py +3 -34
  49. pymodaq/extensions/optimizers_base/__init__.py +0 -0
  50. pymodaq/extensions/optimizers_base/optimizer.py +1016 -0
  51. pymodaq/extensions/optimizers_base/thread_commands.py +22 -0
  52. pymodaq/extensions/optimizers_base/utils.py +427 -0
  53. pymodaq/extensions/pid/actuator_controller.py +3 -2
  54. pymodaq/extensions/pid/daq_move_PID.py +107 -30
  55. pymodaq/extensions/pid/pid_controller.py +613 -287
  56. pymodaq/extensions/pid/utils.py +8 -5
  57. pymodaq/extensions/utils.py +17 -2
  58. pymodaq/resources/config_template.toml +57 -0
  59. pymodaq/resources/preset_default.xml +1 -1
  60. pymodaq/utils/config.py +10 -4
  61. pymodaq/utils/daq_utils.py +14 -0
  62. pymodaq/utils/data.py +1 -0
  63. pymodaq/utils/gui_utils/loader_utils.py +25 -15
  64. pymodaq/utils/h5modules/module_saving.py +134 -22
  65. pymodaq/utils/leco/daq_move_LECODirector.py +123 -84
  66. pymodaq/utils/leco/daq_xDviewer_LECODirector.py +84 -97
  67. pymodaq/utils/leco/director_utils.py +32 -16
  68. pymodaq/utils/leco/leco_director.py +104 -27
  69. pymodaq/utils/leco/pymodaq_listener.py +186 -97
  70. pymodaq/utils/leco/rpc_method_definitions.py +43 -0
  71. pymodaq/utils/leco/utils.py +25 -25
  72. pymodaq/utils/managers/batchscan_manager.py +12 -11
  73. pymodaq/utils/managers/modules_manager.py +74 -33
  74. pymodaq/utils/managers/overshoot_manager.py +11 -10
  75. pymodaq/utils/managers/preset_manager.py +100 -64
  76. pymodaq/utils/managers/preset_manager_utils.py +163 -107
  77. pymodaq/utils/managers/remote_manager.py +21 -16
  78. pymodaq/utils/scanner/scan_factory.py +12 -3
  79. pymodaq/utils/scanner/scan_selector.py +1 -3
  80. pymodaq/utils/scanner/scanner.py +35 -6
  81. pymodaq/utils/scanner/scanners/_1d_scanners.py +15 -46
  82. pymodaq/utils/scanner/scanners/_2d_scanners.py +21 -68
  83. pymodaq/utils/scanner/scanners/sequential.py +50 -31
  84. pymodaq/utils/scanner/scanners/tabular.py +45 -28
  85. {pymodaq-5.0.18.dist-info → pymodaq-5.1.0.dist-info}/METADATA +7 -6
  86. pymodaq-5.1.0.dist-info/RECORD +154 -0
  87. {pymodaq-5.0.18.dist-info → pymodaq-5.1.0.dist-info}/entry_points.txt +0 -2
  88. pymodaq/extensions/bayesian/bayesian_optimisation.py +0 -690
  89. pymodaq/utils/leco/desktop.ini +0 -2
  90. pymodaq-5.0.18.dist-info/RECORD +0 -121
  91. {pymodaq-5.0.18.dist-info → pymodaq-5.1.0.dist-info}/WHEEL +0 -0
  92. {pymodaq-5.0.18.dist-info → pymodaq-5.1.0.dist-info}/licenses/LICENSE +0 -0
@@ -12,7 +12,7 @@ from importlib import import_module
12
12
  from numbers import Number
13
13
 
14
14
  import sys
15
- from typing import List, Tuple, Union, Optional, Type
15
+ from typing import List, Union, Optional, Dict, TypeVar, TYPE_CHECKING
16
16
  import numpy as np
17
17
 
18
18
  from qtpy.QtCore import QObject, Signal, QThread, Slot, Qt, QTimer
@@ -21,7 +21,7 @@ from qtpy import QtWidgets
21
21
  from easydict import EasyDict as edict
22
22
 
23
23
  from pymodaq_utils.logger import set_logger, get_module_name
24
- from pymodaq_utils.utils import ThreadCommand
24
+ from pymodaq_utils.utils import find_keys_from_val
25
25
  from pymodaq_utils import utils
26
26
  from pymodaq.utils.gui_utils import get_splash_sc
27
27
  from pymodaq_utils import config as config_mod
@@ -36,36 +36,63 @@ from pymodaq_gui.utils.utils import mkQApp
36
36
 
37
37
  from pymodaq.utils.h5modules import module_saving
38
38
  from pymodaq.control_modules.utils import ParameterControlModule
39
- from pymodaq.control_modules.daq_move_ui import DAQ_Move_UI, ThreadCommand
40
- from pymodaq.control_modules.move_utility_classes import (MoveCommand, DAQ_Move_base,
41
- DataActuatorType, check_units,
42
- DataUnitError)
39
+ from pymodaq.control_modules.thread_commands import (
40
+ ThreadStatus,
41
+ ThreadStatusMove,
42
+ ControlToHardwareMove,
43
+ UiToMainMove,
44
+ )
45
+
46
+
47
+ from pymodaq.control_modules.move_utility_classes import (
48
+ ThreadCommand,
49
+ MoveCommand,
50
+ DAQ_Move_base,
51
+ DataActuatorType,
52
+ check_units,
53
+ DataUnitError,
54
+ )
43
55
 
44
56
 
45
57
  from pymodaq.control_modules.move_utility_classes import params as daq_move_params
46
- from pymodaq.utils.leco.pymodaq_listener import MoveActorListener, LECOMoveCommands
58
+ from pymodaq.utils.leco.pymodaq_listener import (
59
+ MoveActorListener,
60
+ LECOMoveCommands,
61
+ LECOCommands,
62
+ )
47
63
 
48
64
  from pymodaq.utils.daq_utils import get_plugins
49
65
  from pymodaq import Q_, Unit
50
66
 
51
67
 
68
+ from pymodaq.control_modules.daq_move_ui.factory import ActuatorUIFactory
69
+ from pymodaq.utils.config import Config as ControlModulesConfig
70
+
71
+ if TYPE_CHECKING:
72
+ from pymodaq.control_modules.daq_move_ui.ui_base import DAQ_Move_UI_Base
52
73
 
53
74
  local_path = config_mod.get_set_local_dir()
54
75
  sys.path.append(str(local_path))
55
76
  logger = set_logger(get_module_name(__file__))
56
- config = config_mod.Config()
57
77
 
58
- DAQ_Move_Actuators = get_plugins('daq_move')
59
- ACTUATOR_TYPES = [mov['name'] for mov in DAQ_Move_Actuators]
78
+ config_utils = config_mod.Config()
79
+ config = ControlModulesConfig()
80
+
81
+ HardwareController = TypeVar("HardwareController")
82
+
83
+ HardwareController = TypeVar("HardwareController")
84
+
85
+ DAQ_Move_Actuators = get_plugins("daq_move")
86
+ ACTUATOR_TYPES = [mov["name"] for mov in DAQ_Move_Actuators]
60
87
  if len(ACTUATOR_TYPES) == 0:
61
- raise ActuatorError('No installed Actuator')
88
+ raise ActuatorError("No installed Actuator")
62
89
 
63
90
 
64
91
  STATUS_WAIT_TIME = 1000
65
92
 
66
93
 
67
94
  class DAQ_Move(ParameterControlModule):
68
- """ Main PyMoDAQ class to drive actuators
95
+ """Main PyMoDAQ class to drive actuators
69
96
 
70
97
  Qt object and generic UI to drive actuators.
71
98
 
@@ -83,7 +110,8 @@ class DAQ_Move(ParameterControlModule):
83
110
  --------
84
111
  :class:`ControlModule`, :class:`ParameterManager`
85
112
  """
86
- settings_name = 'daq_move_settings'
113
+
114
+ settings_name = "daq_move_settings"
87
115
 
88
116
  move_done_signal = Signal(DataActuator)
89
117
  current_value_signal = Signal(DataActuator)
@@ -92,8 +120,11 @@ class DAQ_Move(ParameterControlModule):
92
120
  params = daq_move_params
93
121
 
94
122
  listener_class = MoveActorListener
123
+ ui: Optional[DAQ_Move_UI_Base]
95
124
 
96
- def __init__(self, parent=None, title="DAQ Move", **kwargs):
125
+ def __init__(
126
+ self, parent=None, title="DAQ Move", ui_identifier: Optional[str] = None, **kwargs
127
+ ) -> None:
97
128
  """
98
129
 
99
130
  Parameters
@@ -105,16 +136,25 @@ class DAQ_Move(ParameterControlModule):
105
136
  The unique (should be unique) string identifier for the underlying actuator
106
137
  """
107
138
 
108
- self.logger = set_logger(f'{logger.name}.{title}')
109
- self.logger.info(f'Initializing DAQ_Move: {title}')
139
+ self.logger = set_logger(f"{logger.name}.{title}")
140
+ self.logger.info(f"Initializing DAQ_Move: {title}")
141
+
142
+ super().__init__(action_list=("save", "update"), **kwargs)
143
+
144
+ if not (
145
+ ui_identifier is not None and ui_identifier in ActuatorUIFactory.keys()
146
+ ):
147
+ ui_identifier = config("actuator", "ui")
148
+ self.settings.child("main_settings", "ui_type").setValue(ui_identifier)
149
+ self.settings.child("main_settings", "ui_type").setOpts(readonly=True)
110
150
 
111
- super().__init__(action_list=('save', 'update'), **kwargs)
151
+ DAQ_Move_UI = ActuatorUIFactory.get(ui_identifier)
112
152
 
113
153
  self.parent = parent
114
154
  if parent is not None:
115
155
  self.ui = DAQ_Move_UI(parent, title)
116
156
  else:
117
- self.ui: Optional[DAQ_Move_UI] = None
157
+ self.ui = None
118
158
 
119
159
  if self.ui is not None:
120
160
  self.ui.actuators = ACTUATOR_TYPES
@@ -124,9 +164,9 @@ class DAQ_Move(ParameterControlModule):
124
164
  self.splash_sc = get_splash_sc()
125
165
  self._title = title
126
166
  if len(ACTUATOR_TYPES) > 0: # will be 0 if no valid plugins are installed
127
- self.actuator = kwargs.get('actuator', ACTUATOR_TYPES[0])
167
+ self.actuator = kwargs.get("actuator", ACTUATOR_TYPES[0])
128
168
 
129
- self.module_and_data_saver = module_saving.ActuatorSaver(self)
169
+ self.module_and_data_saver = module_saving.ActuatorTimeSaver(self)
130
170
 
131
171
  self._move_done_bool = True
132
172
 
@@ -157,58 +197,69 @@ class DAQ_Move(ParameterControlModule):
157
197
  * rel_value
158
198
  * show_config
159
199
  """
160
- if cmd.command == 'init':
200
+ if cmd.command == UiToMainMove.INIT:
161
201
  self.init_hardware(cmd.attribute[0])
162
- elif cmd.command == 'quit':
202
+ elif cmd.command == UiToMainMove.QUIT:
163
203
  self.quit_fun()
164
- elif cmd.command == 'get_value':
204
+ elif cmd.command == UiToMainMove.GET_VALUE:
165
205
  self.get_actuator_value()
166
- elif cmd.command == 'loop_get_value':
206
+ elif cmd.command == UiToMainMove.LOOP_GET_VALUE:
167
207
  self.get_continuous_actuator_value(cmd.attribute)
168
- elif cmd.command == 'find_home':
208
+ elif cmd.command == UiToMainMove.FIND_HOME:
169
209
  self.move_home()
170
- elif cmd.command == 'stop':
210
+ elif cmd.command == UiToMainMove.STOP:
171
211
  self.stop_motion()
172
- elif cmd.command == 'move_abs':
212
+ elif cmd.command == UiToMainMove.MOVE_ABS:
173
213
  data_act: DataActuator = cmd.attribute
174
- if not Unit(data_act.units).is_compatible_with(self.units) and data_act.units != '':
214
+ if (
215
+ not Unit(data_act.units).is_compatible_with(self.units)
216
+ and data_act.units != ""
217
+ ):
175
218
  data_act.force_units(self.units)
176
219
  self.move_abs(data_act)
177
- elif cmd.command == 'move_rel':
220
+ elif cmd.command == UiToMainMove.MOVE_REL:
178
221
  data_act: DataActuator = cmd.attribute
179
- if not Unit(data_act.units).is_compatible_with(self.units) and data_act.units != '':
222
+ if (
223
+ not Unit(data_act.units).is_compatible_with(self.units)
224
+ and data_act.units != ""
225
+ ):
180
226
  data_act.force_units(self.units)
181
227
  self.move_rel(data_act)
182
- elif cmd.command == 'show_log':
228
+ elif cmd.command == UiToMainMove.SHOW_LOG:
183
229
  self.show_log()
184
- elif cmd.command == 'show_config':
230
+ elif cmd.command == UiToMainMove.SHOW_CONFIG:
185
231
  self.config = self.show_config(self.config)
186
232
  self.ui.config = self.config
187
- elif cmd.command == 'actuator_changed':
233
+ elif cmd.command == UiToMainMove.ACTUATOR_CHANGED:
188
234
  self.actuator = cmd.attribute
189
- elif cmd.command == 'rel_value':
235
+ elif cmd.command == UiToMainMove.REL_VALUE:
190
236
  self._relative_value = cmd.attribute
191
237
 
192
238
  @property
193
239
  def master(self) -> bool:
194
- """ Get/Set programmatically the Master/Slave status of an actuator"""
240
+ """Get/Set programmatically the Master/Slave status of an actuator"""
195
241
  if self.initialized_state:
196
- return self.settings['move_settings', 'multiaxes', 'multi_status'] == 'Master'
242
+ return (
243
+ self.settings["move_settings", "multiaxes", "multi_status"] == "Master"
244
+ )
197
245
  else:
198
246
  return True
199
247
 
200
248
  @master.setter
201
249
  def master(self, is_master: bool):
202
250
  if self.initialized_state:
203
- self.settings.child('move_settings', 'multiaxes', 'multi_status').setValue(
204
- 'Master' if is_master else 'Slave')
251
+ self.settings.child("move_settings", "multiaxes", "multi_status").setValue(
252
+ "Master" if is_master else "Slave"
253
+ )
205
254
 
206
- def append_data(self, dte: Optional[DataToExport] = None, where: Union[Node, str, None] = None):
255
+ def append_data(
256
+ self, dte: Optional[DataToExport] = None, where: Union[Node, str, None] = None
257
+ ):
207
258
  """Appends current DataToExport to an ActuatorEnlargeableSaver
208
259
 
209
260
  Parameters
210
261
  ----------
211
- data
262
+ dte: DataToExport, optional
212
263
  where: Node or str
213
264
  See Also
214
265
  --------
@@ -236,16 +287,15 @@ class DAQ_Move(ParameterControlModule):
236
287
  DetectorSaver, DetectorEnlargeableSaver, DetectorExtendedSaver
237
288
 
238
289
  """
239
- #todo: test this for logging
290
+ # todo: test this for logging
240
291
 
241
292
  node = self.module_and_data_saver.get_set_node(where)
242
293
  self.module_and_data_saver.add_data(node, data, **kwargs)
243
294
 
244
295
  def stop_motion(self):
245
- """Stop any motion
246
- """
296
+ """Stop any motion"""
247
297
  try:
248
- self.command_hardware.emit(ThreadCommand(command="stop_motion"))
298
+ self.command_hardware.emit(ThreadCommand(ControlToHardwareMove.STOP_MOTION))
249
299
  except Exception as e:
250
300
  self.logger.exception(str(e))
251
301
 
@@ -265,11 +315,11 @@ class DAQ_Move(ParameterControlModule):
265
315
  :meth:`move_abs`, :meth:`move_rel`, :meth:`move_home`, :class:`..utility_classes.MoveCommand`
266
316
 
267
317
  """
268
- if move_command.move_type == 'abs':
318
+ if move_command.move_type == "abs":
269
319
  self.move_abs(move_command.value)
270
- elif move_command.move_type == 'rel':
320
+ elif move_command.move_type == "rel":
271
321
  self.move_rel(move_command.value)
272
- elif move_command.move_type == 'home':
322
+ elif move_command.move_type == "home":
273
323
  self.move_home(move_command.value)
274
324
 
275
325
  def move_abs(self, value: Union[DataActuator, numbers.Number], send_to_tcpip=False):
@@ -286,7 +336,9 @@ class DAQ_Move(ParameterControlModule):
286
336
  """
287
337
  try:
288
338
  if isinstance(value, Number):
289
- value = DataActuator(self.title, data=[np.array([value])], units=self.units)
339
+ value = DataActuator(
340
+ self.title, data=[np.array([value])], units=self.units
341
+ )
290
342
  self._send_to_tcpip = send_to_tcpip
291
343
  if value != self._current_value:
292
344
  if self.ui is not None:
@@ -294,8 +346,12 @@ class DAQ_Move(ParameterControlModule):
294
346
  self._move_done_bool = False
295
347
  self._target_value = value
296
348
  self.update_status("Moving")
297
- self.command_hardware.emit(ThreadCommand(command="reset_stop_motion"))
298
- self.command_hardware.emit(ThreadCommand(command="move_abs", attribute=[value]))
349
+ self.command_hardware.emit(
350
+ ThreadCommand(ControlToHardwareMove.RESET_STOP_MOTION)
351
+ )
352
+ self.command_hardware.emit(
353
+ ThreadCommand(ControlToHardwareMove.MOVE_ABS, attribute=[value])
354
+ )
299
355
 
300
356
  except Exception as e:
301
357
  self.logger.exception(str(e))
@@ -314,13 +370,17 @@ class DAQ_Move(ParameterControlModule):
314
370
  self.ui.move_done = False
315
371
  self._move_done_bool = False
316
372
  self.update_status("Moving")
317
- self.command_hardware.emit(ThreadCommand(command="reset_stop_motion"))
318
- self.command_hardware.emit(ThreadCommand(command="move_home"))
373
+ self.command_hardware.emit(
374
+ ThreadCommand(ControlToHardwareMove.RESET_STOP_MOTION)
375
+ )
376
+ self.command_hardware.emit(ThreadCommand(ControlToHardwareMove.MOVE_HOME))
319
377
 
320
378
  except Exception as e:
321
379
  self.logger.exception(str(e))
322
380
 
323
- def move_rel(self, rel_value: Union[DataActuator, numbers.Number], send_to_tcpip=False):
381
+ def move_rel(
382
+ self, rel_value: Union[DataActuator, numbers.Number], send_to_tcpip=False
383
+ ):
324
384
  """Move the connected hardware to the relative value
325
385
 
326
386
  Returns nothing but the move_done_signal will be send once the action is done
@@ -335,15 +395,21 @@ class DAQ_Move(ParameterControlModule):
335
395
 
336
396
  try:
337
397
  if isinstance(rel_value, Number):
338
- rel_value = DataActuator(self.title, data=[np.array([rel_value])], units=self.units)
398
+ rel_value = DataActuator(
399
+ self.title, data=[np.array([rel_value])], units=self.units
400
+ )
339
401
  self._send_to_tcpip = send_to_tcpip
340
402
  if self.ui is not None:
341
403
  self.ui.move_done = False
342
404
  self._move_done_bool = False
343
405
  self._target_value = self._current_value + rel_value
344
406
  self.update_status("Moving")
345
- self.command_hardware.emit(ThreadCommand(command="reset_stop_motion"))
346
- self.command_hardware.emit(ThreadCommand(command="move_rel", attribute=[rel_value]))
407
+ self.command_hardware.emit(
408
+ ThreadCommand(ControlToHardwareMove.RESET_STOP_MOTION)
409
+ )
410
+ self.command_hardware.emit(
411
+ ThreadCommand(ControlToHardwareMove.MOVE_REL, attribute=[rel_value])
412
+ )
347
413
 
348
414
  except Exception as e:
349
415
  self.logger.exception(str(e))
@@ -369,17 +435,19 @@ class DAQ_Move(ParameterControlModule):
369
435
  # self.parent.close()
370
436
 
371
437
  def init_hardware(self, do_init=True):
372
- """ Init or desinit the selected instrument plugin class """
438
+ """Init or desinit the selected instrument plugin class"""
373
439
  if not do_init:
374
440
  try:
375
- self.command_hardware.emit(ThreadCommand(command="close"))
441
+ self.command_hardware.emit(ThreadCommand(ControlToHardwareMove.CLOSE))
376
442
  if self.ui is not None:
377
443
  self.ui.actuator_init = False
378
444
  except Exception as e:
379
445
  self.logger.exception(str(e))
380
446
  else:
381
447
  try:
382
- hardware = DAQ_Move_Hardware(self._actuator_type, self._current_value, self._title)
448
+ hardware = DAQ_Move_Hardware(
449
+ self._actuator_type, self._current_value, self._title
450
+ )
383
451
  self._hardware_thread = QThread()
384
452
  hardware.moveToThread(self._hardware_thread)
385
453
 
@@ -390,9 +458,14 @@ class DAQ_Move(ParameterControlModule):
390
458
  self._hardware_thread.hardware = hardware
391
459
  self._hardware_thread.start()
392
460
  self.command_hardware.emit(
393
- ThreadCommand(command="ini_stage", attribute=[
394
- self.settings.child('move_settings').saveState(),
395
- self.controller]))
461
+ ThreadCommand(
462
+ ControlToHardwareMove.INI_STAGE,
463
+ attribute=[
464
+ self.settings.child("move_settings").saveState(),
465
+ self.controller,
466
+ ],
467
+ )
468
+ )
396
469
  except Exception as e:
397
470
  self.logger.exception(str(e))
398
471
 
@@ -407,33 +480,40 @@ class DAQ_Move(ParameterControlModule):
407
480
  return self._move_done_bool
408
481
 
409
482
  def value_changed(self, param: Parameter):
410
- """ Apply changes of value in the settings"""
483
+ """Apply changes of value in the settings"""
411
484
  super().value_changed(param=param)
412
485
 
413
- if param.name() == 'refresh_timeout':
486
+ if param.name() == "refresh_timeout":
414
487
  self._refresh_timer.setInterval(param.value())
415
488
 
416
489
  self._update_settings(param=param)
417
490
 
418
491
  def param_deleted(self, param):
419
- """ Apply deletion of settings """
420
- if param.name() not in putils.iter_children(self.settings.child('main_settings'), []):
421
- self._update_settings_signal.emit(edict(path=['move_settings'], param=param, change='parent'))
492
+ """Apply deletion of settings"""
493
+ if param.name() not in putils.iter_children(
494
+ self.settings.child("main_settings"), []
495
+ ):
496
+ self._update_settings_signal.emit(
497
+ edict(path=["move_settings"], param=param, change="parent")
498
+ )
422
499
 
423
500
  def child_added(self, param, data):
424
- """ Apply addition of settings """
501
+ """Apply addition of settings"""
425
502
  path = self.settings.childPath(param)
426
- if 'main_settings' not in path:
427
- self._update_settings_signal.emit(edict(path=path, param=data[0].saveState(), change='childAdded'))
503
+ if "main_settings" not in path:
504
+ self._update_settings_signal.emit(
505
+ edict(path=path, param=data[0].saveState(), change="childAdded")
506
+ )
428
507
 
429
508
  def raise_timeout(self):
430
- """ Update status with "Timeout occurred" statement and change the timeout flag.
431
- """
509
+ """Update status with "Timeout occurred" statement and change the timeout flag."""
432
510
  self.update_status("Timeout occurred")
433
511
  self.wait_position_flag = False
434
512
 
435
513
  @Slot(ThreadCommand)
436
- def thread_status(self, status: ThreadCommand): # general function to get datas/infos from all threads back to the main
514
+ def thread_status(
515
+ self, status: ThreadCommand
516
+ ): # general function to get datas/infos from all threads back to the main
437
517
  """Get back info (using the ThreadCommand object) from the hardware
438
518
 
439
519
  And re-emit this ThreadCommand using the custom_sig signal if it should be used in a higher level module
@@ -455,13 +535,15 @@ class DAQ_Move(ParameterControlModule):
455
535
  * stop: stop the motion
456
536
  """
457
537
 
458
- super().thread_status(status, 'move')
538
+ super().thread_status(status, "move")
459
539
 
460
- if status.command == "ini_stage":
461
- self.update_status(f"Stage initialized: {status.attribute['initialized']} "
462
- f"info: {status.attribute['info']}")
463
- if status.attribute['initialized']:
464
- self.controller = status.attribute['controller']
540
+ if status.command == ThreadStatusMove.INI_STAGE:
541
+ self.update_status(
542
+ f"Stage initialized: {status.attribute['initialized']} "
543
+ f"info: {status.attribute['info']}"
544
+ )
545
+ if status.attribute["initialized"]:
546
+ self.controller = status.attribute["controller"]
465
547
  if self.ui is not None:
466
548
  self.ui.actuator_init = True
467
549
  self._initialized_state = True
@@ -471,21 +553,33 @@ class DAQ_Move(ParameterControlModule):
471
553
  self.get_actuator_value()
472
554
  self.init_signal.emit(self._initialized_state)
473
555
 
474
- elif status.command == "get_actuator_value" or status.command == 'check_position':
556
+ elif (
557
+ status.command == ThreadStatusMove.GET_ACTUATOR_VALUE
558
+ or status.command == "check_position"
559
+ ):
475
560
  data_act = self._check_data_type(status.attribute)
476
561
  if self.ui is not None:
477
562
  self.ui.display_value(data_act)
478
- if self.ui.is_action_checked('show_graph'):
479
- self.ui.show_data(DataToExport(name=self.title,
480
- data=[data_act]))
563
+ if self.ui.has_action("show_graph") and self.ui.is_action_checked(
564
+ "show_graph"
565
+ ):
566
+ self.ui.show_data(DataToExport(name=self.title, data=[data_act]))
481
567
  self._current_value = data_act
482
568
  self.current_value_signal.emit(self._current_value)
483
- if self.settings['main_settings', 'tcpip', 'tcp_connected'] and self._send_to_tcpip:
484
- self._command_tcpip.emit(ThreadCommand('position_is', data_act))
485
- if self.settings['main_settings', 'leco', 'leco_connected'] and self._send_to_tcpip:
486
- self._command_tcpip.emit(ThreadCommand(LECOMoveCommands.POSITION, data_act))
487
-
488
- elif status.command == "move_done":
569
+ if (
570
+ self.settings["main_settings", "tcpip", "tcp_connected"]
571
+ and self._send_to_tcpip
572
+ ):
573
+ self._command_tcpip.emit(ThreadCommand("position_is", data_act))
574
+ if (
575
+ self.settings["main_settings", "leco", "leco_connected"]
576
+ and self._send_to_tcpip
577
+ ):
578
+ self._command_tcpip.emit(
579
+ ThreadCommand(LECOMoveCommands.POSITION, data_act)
580
+ )
581
+
582
+ elif status.command == ThreadStatusMove.MOVE_DONE:
489
583
  data_act = self._check_data_type(status.attribute)
490
584
  if self.ui is not None:
491
585
  self.ui.display_value(data_act)
@@ -493,47 +587,63 @@ class DAQ_Move(ParameterControlModule):
493
587
  self._current_value = data_act
494
588
  self._move_done_bool = True
495
589
  self.move_done_signal.emit(data_act)
496
- if self.settings.child('main_settings', 'tcpip', 'tcp_connected').value() and self._send_to_tcpip:
497
- self._command_tcpip.emit(ThreadCommand('move_done', data_act))
498
- if self.settings.child('main_settings', 'leco', 'leco_connected').value() and self._send_to_tcpip:
499
- self._command_tcpip.emit(ThreadCommand(LECOMoveCommands.MOVE_DONE, data_act))
500
-
501
- elif status.command == 'outofbounds':
502
- logger.warning(f'The Actuator {self.title} has reached its defined bounds')
590
+ if (
591
+ self.settings.child("main_settings", "tcpip", "tcp_connected").value()
592
+ and self._send_to_tcpip
593
+ ):
594
+ self._command_tcpip.emit(ThreadCommand("move_done", data_act))
595
+ if (
596
+ self.settings.child("main_settings", "leco", "leco_connected").value()
597
+ and self._send_to_tcpip
598
+ ):
599
+ self._command_tcpip.emit(
600
+ ThreadCommand(LECOMoveCommands.MOVE_DONE, data_act)
601
+ )
602
+
603
+ elif status.command == ThreadStatusMove.OUT_OF_BOUNDS:
604
+ logger.warning(f"The Actuator {self.title} has reached its defined bounds")
503
605
  self.bounds_signal.emit(True)
504
606
 
505
- elif status.command == 'set_allowed_values':
607
+ elif status.command == ThreadStatusMove.SET_ALLOWED_VALUES:
506
608
  if self.ui is not None:
507
609
  self.ui.set_abs_spinbox_properties(**status.attribute)
508
610
 
509
- elif status.command == 'stop':
611
+ elif status.command == ThreadStatusMove.STOP:
510
612
  self.stop_motion()
511
613
 
512
- elif status.command == 'units':
614
+ elif status.command == ThreadStatusMove.UNITS:
513
615
  self.units = status.attribute
514
616
 
515
- def _check_data_type(self, data_act: Union[list, np.ndarray, Number, DataActuator]) -> DataActuator:
516
- """ Make sure the data is a DataActuator
617
+ def _check_data_type(
618
+ self, data_act: Union[list, np.ndarray, Number, DataActuator]
619
+ ) -> DataActuator:
620
+ """Make sure the data is a DataActuator
517
621
 
518
622
  Mostly to make sure DAQ_Move is backcompatible with old style plugins
519
623
  """
520
624
  if isinstance(data_act, list): # backcompatibility
521
625
  if isinstance(data_act[0], Number):
522
- data_act = DataActuator(data=[np.atleast_1d(val) for val in data_act], units=self.units)
626
+ data_act = DataActuator(
627
+ data=[np.atleast_1d(val) for val in data_act], units=self.units
628
+ )
523
629
  elif isinstance(data_act[0], np.ndarray):
524
630
  data_act = DataActuator(data=data_act, units=self.units)
525
631
  elif isinstance(data_act[0], DataActuator):
526
632
  data_act = data_act[0]
527
633
  else:
528
- raise TypeError('Unknown data type')
634
+ raise TypeError("Unknown data type")
529
635
  elif isinstance(data_act, np.ndarray): # backcompatibility
530
636
  data_act = DataActuator(data=[data_act], units=self.units)
531
- data_act.name = self.title # for the DataActuator name to be the title of the DAQ_Move
532
- if (not Unit(self.units).is_compatible_with(Unit(data_act.units)) and
533
- data_act.units == ''): #this happens if the units have not been specified in
637
+ data_act.name = (
638
+ self.title
639
+ ) # for the DataActuator name to be the title of the DAQ_Move
640
+ if (
641
+ not Unit(self.units).is_compatible_with(Unit(data_act.units))
642
+ and data_act.units == ""
643
+ ): # this happens if the units have not been specified in
534
644
  # the plugin
535
645
  data_act.force_units(self.units)
536
- return data_act
646
+ return data_act
537
647
 
538
648
  def get_actuator_value(self):
539
649
  """Get the current actuator value via the "get_actuator_value" command send to the hardware
@@ -541,14 +651,16 @@ class DAQ_Move(ParameterControlModule):
541
651
  Returns nothing but the `move_done_signal` will be send once the action is done
542
652
  """
543
653
  try:
544
- self.command_hardware.emit(ThreadCommand(command="get_actuator_value"))
654
+ self.command_hardware.emit(
655
+ ThreadCommand(ControlToHardwareMove.GET_ACTUATOR_VALUE)
656
+ )
545
657
 
546
658
  except Exception as e:
547
659
  self.logger.exception(str(e))
548
660
 
549
661
  def grab(self):
550
662
  if self.ui is not None:
551
- self.manage_ui_actions('refresh_value', 'setChecked', False)
663
+ self.manage_ui_actions("refresh_value", "setChecked", False)
552
664
  self.get_continuous_actuator_value(False)
553
665
 
554
666
  def stop_grab(self):
@@ -557,7 +669,7 @@ class DAQ_Move(ParameterControlModule):
557
669
  First uncheck the ui action if ui is not None, then stop the polling
558
670
  """
559
671
  if self.ui is not None:
560
- self.manage_ui_actions('refresh_value', 'setChecked', False)
672
+ self.manage_ui_actions("refresh_value", "setChecked", False)
561
673
  self.get_continuous_actuator_value(False)
562
674
 
563
675
  def get_continuous_actuator_value(self, get_value=True):
@@ -573,7 +685,9 @@ class DAQ_Move(ParameterControlModule):
573
685
  The current timer period is set by the refresh value *'refresh_timeout'* in the actuator main settings.
574
686
  """
575
687
  if get_value:
576
- self._refresh_timer.setInterval(self.settings['main_settings', 'refresh_timeout'])
688
+ self._refresh_timer.setInterval(
689
+ self.settings["main_settings", "refresh_timeout"]
690
+ )
577
691
  self._refresh_timer.start()
578
692
  else:
579
693
  self._refresh_timer.stop()
@@ -597,33 +711,92 @@ class DAQ_Move(ParameterControlModule):
597
711
  self.ui.actuator = act_type
598
712
  self.update_settings()
599
713
  else:
600
- raise ActuatorError(f'{act_type} is an invalid actuator, should be within {ACTUATOR_TYPES}')
714
+ raise ActuatorError(
715
+ f"{act_type} is an invalid actuator, should be within {ACTUATOR_TYPES}"
716
+ )
601
717
 
602
718
  @property
603
719
  def actuators(self) -> List[str]:
604
- """ Get the list of possible actuators"""
720
+ """Get the list of possible actuators"""
605
721
  return ACTUATOR_TYPES
606
722
 
607
723
  def update_plugin_config(self):
608
- parent_module = utils.find_dict_in_list_from_key_val(DAQ_Move_Actuators, 'name', self.actuator)
609
- mod = import_module(parent_module['module'].__package__.split('.')[0])
610
- if hasattr(mod, 'config'):
724
+ parent_module = utils.find_dict_in_list_from_key_val(
725
+ DAQ_Move_Actuators, "name", self.actuator
726
+ )
727
+ mod = import_module(parent_module["module"].__package__.split(".")[0])
728
+ if hasattr(mod, "config"):
611
729
  self.plugin_config = mod.config
612
730
 
613
731
  @property
614
732
  def units(self):
615
733
  """Get/Set the units for the controller"""
616
- return self.settings['move_settings', 'units']
734
+ return self.settings["move_settings", "units"]
617
735
 
618
736
  @units.setter
619
737
  def units(self, unit: str):
620
- self.settings.child('move_settings', 'units').setValue(unit)
621
- if self.ui is not None and config('actuator', 'display_units'):
622
- self.ui.set_unit_as_suffix(self.get_unit_to_display(unit))
738
+ self.settings.child("move_settings", "units").setValue(unit)
739
+ if self.ui is not None and config("actuator", "display_units"):
740
+ unit = self.get_unit_to_display(unit)
741
+ self.ui.set_unit_as_suffix(unit)
742
+ self.ui.set_unit_prefix(
743
+ config("actuator", "siprefix")
744
+ and (unit != "" or config("actuator", "siprefix_even_without_units"))
745
+ )
746
+
747
+ @property
748
+ def axis_names(self) -> Union[List, Dict]:
749
+ """ Get the names of all possible axis"""
750
+ return self.settings.child('move_settings', 'multiaxes', 'axis').opts['limits']
751
+
752
+ @property
753
+ def axis_name(self) -> str:
754
+ """ Get/Set the current axis"""
755
+ limits = self.settings.child('move_settings', 'multiaxes', 'axis').opts['limits']
756
+ if isinstance(limits, list):
757
+ return self.settings['move_settings', 'multiaxes', 'axis']
758
+ elif isinstance(limits, dict):
759
+ return find_keys_from_val(limits,
760
+ val=self.settings['move_settings', 'multiaxes', 'axis'])[0]
761
+
762
+ @axis_name.setter
763
+ def axis_name(self, name: str):
764
+ """ Get/Set the current axis"""
765
+ limits = self.settings.child('move_settings', 'multiaxes', 'axis').opts['limits']
766
+ if name in limits:
767
+ if isinstance(limits, list):
768
+ self.settings.child('move_settings', 'multiaxes', 'axis').setValue(name)
769
+ elif isinstance(limits, dict):
770
+ self.settings.child('move_settings', 'multiaxes', 'axis').setValue(limits[name])
771
+
772
+ @property
773
+ def axis_names(self) -> Union[List, Dict]:
774
+ """ Get the names of all possible axis"""
775
+ return self.settings.child('move_settings', 'multiaxes', 'axis').opts['limits']
776
+
777
+ @property
778
+ def axis_name(self) -> str:
779
+ """ Get/Set the current axis"""
780
+ limits = self.settings.child('move_settings', 'multiaxes', 'axis').opts['limits']
781
+ if isinstance(limits, list):
782
+ return self.settings['move_settings', 'multiaxes', 'axis']
783
+ elif isinstance(limits, dict):
784
+ return find_keys_from_val(limits,
785
+ val=self.settings['move_settings', 'multiaxes', 'axis'])[0]
786
+
787
+ @axis_name.setter
788
+ def axis_name(self, name: str):
789
+ """ Get/Set the current axis"""
790
+ limits = self.settings.child('move_settings', 'multiaxes', 'axis').opts['limits']
791
+ if name in limits:
792
+ if isinstance(limits, list):
793
+ self.settings.child('move_settings', 'multiaxes', 'axis').setValue(name)
794
+ elif isinstance(limits, dict):
795
+ self.settings.child('move_settings', 'multiaxes', 'axis').setValue(limits[name])
623
796
 
624
797
  @staticmethod
625
798
  def get_unit_to_display(unit: str) -> str:
626
- """ Get the unit to be displayed in the UI
799
+ """Get the unit to be displayed in the UI
627
800
 
628
801
  If the controller units are in mm the displayed unit will be m
629
802
  because m is the base unit, then the user could ask for mm, km, µm...
@@ -637,94 +810,96 @@ class DAQ_Move(ParameterControlModule):
637
810
  -------
638
811
  str: the unit to be displayed on the ui
639
812
  """
640
- if ('°' in unit or 'degree' in unit) and not '°C' in unit:
813
+ if ("°" in unit or "degree" in unit) and not "°C" in unit:
641
814
  # special cas as pint base unit for angles are radians
642
- return '°'
643
- elif 'W' in unit or 'watt' in unit.lower():
644
- return 'W'
645
- elif '°C' in unit or 'Celsius' in unit:
646
- return '°C'
647
- elif 'V' in unit or 'volt' in unit.lower():
648
- return 'V'
649
- elif 'Hz' in unit:
650
- return 'Hz'
651
- elif 'rpm' in unit or 'revolutions_per_minute' in unit:
652
- return 'rpm'
815
+ return "°"
816
+ elif "°C" in unit:
817
+ return "°C"
653
818
  else:
819
+ for key in config("actuator", "allowed_units"):
820
+ if key in unit:
821
+ return config("actuator", "allowed_units", key)
654
822
  return str(Q_(1, unit).to_base_units().units)
655
823
 
656
824
  def update_settings(self):
657
-
658
- self.settings.child('main_settings', 'move_type').setValue(self._actuator_type)
659
- self.settings.child('main_settings', 'module_name').setValue(self._title)
825
+ self.settings.child("main_settings", "move_type").setValue(self._actuator_type)
826
+ self.settings.child("main_settings", "module_name").setValue(self._title)
660
827
  try:
661
- for child in self.settings.child('move_settings').children():
828
+ for child in self.settings.child("move_settings").children():
662
829
  child.remove()
663
- parent_module = utils.find_dict_in_list_from_key_val(DAQ_Move_Actuators, 'name', self._actuator_type)
664
- class_ = getattr(getattr(parent_module['module'], 'daq_move_' + self._actuator_type),
665
- 'DAQ_Move_' + self._actuator_type)
666
- params = getattr(class_, 'params')
667
- move_params = Parameter.create(name='move_settings', type='group', children=params)
668
-
669
- self.settings.child('move_settings').addChildren(move_params.children())
830
+ parent_module = utils.find_dict_in_list_from_key_val(
831
+ DAQ_Move_Actuators, "name", self._actuator_type
832
+ )
833
+ class_ = getattr(
834
+ getattr(parent_module["module"], "daq_move_" + self._actuator_type),
835
+ "DAQ_Move_" + self._actuator_type,
836
+ )
837
+ params = getattr(class_, "params")
838
+ move_params = Parameter.create(
839
+ name="move_settings", type="group", children=params
840
+ )
841
+
842
+ self.settings.child("move_settings").addChildren(move_params.children())
670
843
 
671
844
  except Exception as e:
672
845
  self.logger.exception(str(e))
673
846
 
674
847
  def connect_tcp_ip(self):
675
- super().connect_tcp_ip(params_state=self.settings.child('move_settings'),
676
- client_type="ACTUATOR")
848
+ super().connect_tcp_ip(
849
+ params_state=self.settings.child("move_settings"), client_type="ACTUATOR"
850
+ )
851
+
852
+ def connect_leco(self, connect: bool) -> None:
853
+ super().connect_leco(connect)
677
854
 
678
855
  @Slot(ThreadCommand)
679
856
  def process_tcpip_cmds(self, status: ThreadCommand) -> None:
680
857
  if super().process_tcpip_cmds(status=status) is None:
681
858
  return
682
- if 'move_abs' in status.command:
683
- self.move_abs(status.attribute[0], send_to_tcpip=True)
859
+ if LECOMoveCommands.MOVE_ABS == status.command:
860
+ self.move_abs(status.attribute, send_to_tcpip=True)
684
861
 
685
- elif 'move_rel' in status.command:
686
- self.move_rel(status.attribute[0], send_to_tcpip=True)
862
+ elif LECOMoveCommands.MOVE_REL == status.command:
863
+ self.move_rel(status.attribute, send_to_tcpip=True)
687
864
 
688
- elif 'move_home' in status.command:
865
+ elif LECOMoveCommands.MOVE_HOME == status.command:
689
866
  self.move_home(send_to_tcpip=True)
690
867
 
691
- elif 'check_position' in status.command:
692
- deprecation_msg('check_position is deprecated, you should use get_actuator_value')
868
+ elif "check_position" in status.command:
869
+ deprecation_msg(
870
+ "check_position is deprecated, you should use get_actuator_value"
871
+ )
693
872
  self._send_to_tcpip = True
694
- self.command_hardware.emit(ThreadCommand('get_actuator_value', ))
873
+ self.get_actuator_value()
695
874
 
696
- elif 'get_actuator_value' in status.command:
875
+ elif LECOMoveCommands.GET_ACTUATOR_VALUE in status.command:
697
876
  self._send_to_tcpip = True
698
- self.command_hardware.emit(ThreadCommand('get_actuator_value', ))
877
+ self.get_actuator_value()
699
878
 
700
- elif status.command == 'set_info':
701
- path_in_settings = status.attribute[0]
702
- param_as_xml = status.attribute[1]
703
- param_dict = ioxml.XML_string_to_parameter(param_as_xml)[0]
704
- param_tmp = Parameter.create(**param_dict)
705
- param = self.settings.child('move_settings', *path_in_settings[1:])
706
- param.restoreState(param_tmp.saveState())
879
+ elif status.command == LECOMoveCommands.STOP:
880
+ self.stop_motion()
707
881
 
708
882
 
709
883
  class DAQ_Move_Hardware(QObject):
710
884
  """
711
- ================== ========================
712
- **Attributes** **Type**
713
- *status_sig* instance of Signal
714
- *hardware* ???
715
- *actuator_type* string
716
- *current_position* float
717
- *target_value* float
718
- *hardware_adress* string
719
- *axis_address* string
720
- *motion_stoped* boolean
721
- ================== ========================
885
+ ================== ========================
886
+ **Attributes** **Type**
887
+ *status_sig* instance of Signal
888
+ *hardware* ???
889
+ *actuator_type* string
890
+ *current_position* float
891
+ *target_value* float
892
+ *hardware_adress* string
893
+ *axis_address* string
894
+ *motion_stoped* boolean
895
+ ================== ========================
722
896
  """
897
+
723
898
  status_sig = Signal(ThreadCommand)
724
899
 
725
- def __init__(self, actuator_type, position: DataActuator, title='actuator'):
900
+ def __init__(self, actuator_type, position: DataActuator, title="actuator"):
726
901
  super().__init__()
727
- self.logger = set_logger(f'{logger.name}.{title}.actuator')
902
+ self.logger = set_logger(f"{logger.name}.{title}.actuator")
728
903
  self._title = title
729
904
  self.hardware: Optional[DAQ_Move_base] = None
730
905
  self.actuator_type = actuator_type
@@ -738,7 +913,7 @@ class DAQ_Move_Hardware(QObject):
738
913
 
739
914
  def close(self):
740
915
  """
741
- Uninitialize the stage closing the hardware.
916
+ Uninitialize the stage closing the hardware.
742
917
 
743
918
  """
744
919
  if self.hardware is not None and self.hardware.controller is not None:
@@ -747,8 +922,7 @@ class DAQ_Move_Hardware(QObject):
747
922
  return "Stage uninitialized"
748
923
 
749
924
  def get_actuator_value(self):
750
- """Get the current position checking the hardware value.
751
- """
925
+ """Get the current position checking the hardware value."""
752
926
  if self.hardware is not None:
753
927
  pos = self.hardware.get_actuator_value()
754
928
  if self.hardware.data_actuator_type == DataActuatorType.float:
@@ -756,86 +930,107 @@ class DAQ_Move_Hardware(QObject):
756
930
  return pos
757
931
 
758
932
  def check_position(self):
759
- """Get the current position checking the hardware position (deprecated)
760
- """
761
- deprecation_msg('check_position is deprecated, use get_actuator_value')
933
+ """Get the current position checking the hardware position (deprecated)"""
934
+ deprecation_msg("check_position is deprecated, use get_actuator_value")
762
935
  pos = self.hardware.get_actuator_value()
763
936
  return pos
764
937
 
765
- def ini_stage(self, params_state=None, controller=None):
938
+ def ini_stage(self, params_state=None, controller: Optional[HardwareController] = None) -> edict:
766
939
  """
767
- Init a stage updating the hardware and sending an hardware move_done signal.
940
+ Init a stage updating the hardware and sending an hardware move_done signal.
768
941
 
769
- =============== =================================== ==========================================================================================================================
770
- **Parameters** **Type** **Description**
942
+ =============== =================================== ==========================================================================================================================
943
+ **Parameters** **Type** **Description**
771
944
 
772
- *params_state* ordered dictionary list The parameter state of the hardware class composed by a list representing the tree to keep a temporary save of the tree
945
+ *params_state* ordered dictionary list The parameter state of the hardware class composed by a list representing the tree to keep a temporary save of the tree
773
946
 
774
- *controller* one or many instance of DAQ_Move The controller id of the hardware
947
+ *controller* one or many instance of DAQ_Move The controller id of the hardware
775
948
 
776
- *stage* instance of DAQ_Move Defining axes and motors
777
- =============== =================================== ==========================================================================================================================
949
+ *stage* instance of DAQ_Move Defining axes and motors
950
+ =============== =================================== ==========================================================================================================================
778
951
 
779
- See Also
780
- --------
781
- DAQ_utils.ThreadCommand, DAQ_Move
952
+ See Also
953
+ --------
954
+ DAQ_utils.ThreadCommand, DAQ_Move
782
955
  """
783
956
 
784
957
  status = edict(initialized=False, info="")
785
958
  try:
786
- parent_module = utils.find_dict_in_list_from_key_val(DAQ_Move_Actuators, 'name', self.actuator_type)
787
- class_ = getattr(getattr(parent_module['module'], 'daq_move_' + self.actuator_type),
788
- 'DAQ_Move_' + self.actuator_type)
959
+ parent_module = utils.find_dict_in_list_from_key_val(
960
+ DAQ_Move_Actuators, "name", self.actuator_type
961
+ )
962
+ class_ = getattr(
963
+ getattr(parent_module["module"], "daq_move_" + self.actuator_type),
964
+ "DAQ_Move_" + self.actuator_type,
965
+ )
789
966
  self.hardware = class_(self, params_state)
967
+ assert self.hardware is not None
790
968
  try:
791
- infos = self.hardware.ini_stage(controller) # return edict(info="", controller=, stage=)
969
+ infos = self.hardware.ini_stage(
970
+ controller
971
+ ) # return edict(info="", controller=, stage=)
792
972
  except Exception as e:
793
973
  logger.exception("Hardware couldn't be initialized", exc_info=e)
794
974
  infos = str(e), False
795
975
 
796
976
  if isinstance(infos, edict): # following old plugin templating
797
977
  status.update(infos)
798
- deprecation_msg('Returns from init_stage should now be a string and a boolean,'
799
- ' see pymodaq_plugins_template', stacklevel=3)
978
+ deprecation_msg(
979
+ "Returns from init_stage should now be a string and a boolean,"
980
+ " see pymodaq_plugins_template",
981
+ stacklevel=3,
982
+ )
800
983
  else:
801
984
  status.info = infos[0]
802
985
  status.initialized = infos[1]
803
986
  status.controller = self.hardware.controller
804
987
  self.hardware.move_done_signal.connect(self.move_done)
805
988
  if status.initialized:
806
- self.status_sig.emit(ThreadCommand('get_actuator_value', [self.get_actuator_value()]))
989
+ self.status_sig.emit(
990
+ ThreadCommand(
991
+ ThreadStatusMove.GET_ACTUATOR_VALUE, self.get_actuator_value()
992
+ )
993
+ )
807
994
 
808
995
  return status
809
996
  except Exception as e:
810
997
  self.logger.exception(str(e))
811
998
  return status
812
999
 
813
- def move_abs(self, position: DataActuator, polling=True):
1000
+ def move_abs(self, position: DataActuator, polling: bool = True) -> None:
814
1001
  """
815
1002
 
816
1003
  """
1004
+ assert self.hardware is not None
817
1005
  position = check_units(position, self.hardware.axis_unit)
818
1006
  self.hardware.move_is_done = False
819
1007
  self.hardware.ispolling = polling
820
1008
  if self.hardware.data_actuator_type == self.hardware.data_actuator_type.float:
821
- self.hardware.move_abs(position.units_as(self.hardware.axis_unit).value()) # convert to plugin controller current axis units
1009
+ self.hardware.move_abs(
1010
+ position.units_as(self.hardware.axis_unit).value()
1011
+ ) # convert to plugin controller current axis units
822
1012
  else:
823
- position.units = self.hardware.axis_unit # convert to plugin controller current axis units
1013
+ position.units = (
1014
+ self.hardware.axis_unit
1015
+ ) # convert to plugin controller current axis units
824
1016
  self.hardware.move_abs(position)
825
1017
  self.hardware.poll_moving()
826
1018
 
827
- def move_rel(self, rel_position: DataActuator, polling=True):
1019
+ def move_rel(self, rel_position: DataActuator, polling: bool = True) -> None:
828
1020
  """
829
1021
 
830
1022
  """
1023
+ assert self.hardware is not None
831
1024
  rel_position = check_units(rel_position, self.hardware.axis_unit)
832
1025
  self.hardware.move_is_done = False
833
1026
  self.hardware.ispolling = polling
834
1027
 
835
1028
  if self.hardware.data_actuator_type.name == 'float':
836
- self.hardware.move_rel(rel_position.value())
1029
+ self.hardware.move_rel(rel_position.units_as(self.hardware.axis_unit).value())
837
1030
  else:
838
- rel_position.units = self.hardware.axis_unit # convert to plugin current axis units
1031
+ rel_position.units = (
1032
+ self.hardware.axis_unit
1033
+ ) # convert to plugin current axis units
839
1034
  self.hardware.move_rel(rel_position)
840
1035
 
841
1036
  self.hardware.poll_moving()
@@ -843,28 +1038,30 @@ class DAQ_Move_Hardware(QObject):
843
1038
  @Slot(float)
844
1039
  def Move_Stoped(self, pos):
845
1040
  """
846
- Send a "move_done" Thread Command with the given position as an attribute.
1041
+ Send a "move_done" Thread Command with the given position as an attribute.
847
1042
 
848
- See Also
849
- --------
850
- DAQ_utils.ThreadCommand
1043
+ See Also
1044
+ --------
1045
+ DAQ_utils.ThreadCommand
851
1046
  """
852
- self.status_sig.emit(ThreadCommand("move_done", pos))
1047
+ self.status_sig.emit(ThreadCommand(ThreadStatusMove.MOVE_DONE, pos))
853
1048
 
854
1049
  def move_home(self):
855
1050
  """
856
- Make the hardware move to the init position.
1051
+ Make the hardware move to the init position.
857
1052
 
858
1053
  """
1054
+ assert self.hardware is not None
859
1055
  self.hardware.move_is_done = False
860
1056
  self.hardware.move_home()
861
1057
 
862
1058
  @Slot(DataActuator)
863
1059
  def move_done(self, pos: DataActuator):
864
- """Send the move_done signal back to the main class
865
- """
1060
+ """Send the move_done signal back to the main class"""
866
1061
  self._current_value = pos
867
- self.status_sig.emit(ThreadCommand(command="move_done", attribute=pos))
1062
+ self.status_sig.emit(
1063
+ ThreadCommand(command=ThreadStatusMove.MOVE_DONE, attribute=pos)
1064
+ )
868
1065
 
869
1066
  @Slot(ThreadCommand)
870
1067
  def queue_command(self, command: ThreadCommand):
@@ -892,32 +1089,38 @@ class DAQ_Move_Hardware(QObject):
892
1089
  * **reset_stop_motion** command, set the motion_stopped attribute to false
893
1090
  """
894
1091
  try:
895
- logger.debug(f'Threadcommand {command.command} sent to {self.title}')
896
- if command.command == "ini_stage":
1092
+ logger.debug(f"Threadcommand {command.command} sent to {self.title}")
1093
+ if command.command == ControlToHardwareMove.INI_STAGE:
897
1094
  status: edict = self.ini_stage(*command.attribute)
898
- self.status_sig.emit(ThreadCommand(command=command.command, attribute=status))
1095
+ self.status_sig.emit(
1096
+ ThreadCommand(command=ThreadStatusMove.INI_STAGE, attribute=status)
1097
+ )
899
1098
 
900
- elif command.command == "close":
1099
+ elif command.command == ControlToHardwareMove.CLOSE:
901
1100
  status = self.close()
902
- self.status_sig.emit(ThreadCommand(command=command.command, attribute=[status]))
1101
+ self.status_sig.emit(
1102
+ ThreadCommand(command=ThreadStatus.CLOSE, attribute=[status])
1103
+ )
903
1104
 
904
- elif command.command == "move_abs":
1105
+ elif command.command == ControlToHardwareMove.MOVE_ABS:
905
1106
  self.move_abs(*command.attribute)
906
1107
 
907
- elif command.command == "move_rel":
1108
+ elif command.command == ControlToHardwareMove.MOVE_REL:
908
1109
  self.move_rel(*command.attribute)
909
1110
 
910
- elif command.command == "move_home":
1111
+ elif command.command == ControlToHardwareMove.MOVE_HOME:
911
1112
  self.move_home()
912
1113
 
913
- elif command.command == "get_actuator_value":
1114
+ elif command.command == ControlToHardwareMove.GET_ACTUATOR_VALUE:
914
1115
  pos = self.get_actuator_value()
915
- self.status_sig.emit(ThreadCommand('get_actuator_value', [pos]))
1116
+ self.status_sig.emit(
1117
+ ThreadCommand(ThreadStatusMove.GET_ACTUATOR_VALUE, pos)
1118
+ )
916
1119
 
917
- elif command.command == "stop_motion":
1120
+ elif command.command == ControlToHardwareMove.STOP_MOTION:
918
1121
  self.stop_motion()
919
1122
 
920
- elif command.command == "reset_stop_motion":
1123
+ elif command.command == ControlToHardwareMove.RESET_STOP_MOTION:
921
1124
  self.motion_stoped = False
922
1125
 
923
1126
  else: # custom commands for particular plugins (see spectrometer module 'get_spectro_wl' for instance)
@@ -932,14 +1135,17 @@ class DAQ_Move_Hardware(QObject):
932
1135
 
933
1136
  def stop_motion(self):
934
1137
  """
935
- stop hardware motion with motion_stopped attribute updtaed to True and a status signal sended with an "update_status" Thread Command
1138
+ stop hardware motion with motion_stopped attribute updtaed to True and a status signal sended with an "update_status" Thread Command
936
1139
 
937
- See Also
938
- --------
939
- DAQ_utils.ThreadCommand, stop_motion
1140
+ See Also
1141
+ --------
1142
+ DAQ_utils.ThreadCommand, stop_motion
940
1143
  """
941
- self.status_sig.emit(ThreadCommand(command="Update_Status", attribute=["Motion stoping", 'log']))
1144
+ self.status_sig.emit(
1145
+ ThreadCommand(command="Update_Status", attribute=["Motion stoping", "log"])
1146
+ )
942
1147
  self.motion_stoped = True
1148
+ assert self.hardware is not None
943
1149
  if self.hardware is not None and self.hardware.controller is not None:
944
1150
  self.hardware.stop_motion()
945
1151
  self.hardware.poll_timer.stop()
@@ -947,26 +1153,26 @@ class DAQ_Move_Hardware(QObject):
947
1153
  @Slot(edict)
948
1154
  def update_settings(self, settings_parameter_dict):
949
1155
  """
950
- Update settings of hardware with dictionary parameters in case of "Move_Settings" path, else update attribute with dictionnary parameters.
1156
+ Update settings of hardware with dictionary parameters in case of "Move_Settings" path, else update attribute with dictionnary parameters.
951
1157
 
952
- ========================= =========== ======================================================
953
- **Parameters** **Type** **Description**
1158
+ ========================= =========== ======================================================
1159
+ **Parameters** **Type** **Description**
954
1160
 
955
- *settings_parameter_dict* dictionary Dictionary containing the path and linked parameter
956
- ========================= =========== ======================================================
1161
+ *settings_parameter_dict* dictionary Dictionary containing the path and linked parameter
1162
+ ========================= =========== ======================================================
957
1163
 
958
- See Also
959
- --------
960
- update_settings
1164
+ See Also
1165
+ --------
1166
+ update_settings
961
1167
  """
962
1168
  # settings_parameter_dict = edict(path=path,param=param)
963
- path = settings_parameter_dict['path']
964
- param = settings_parameter_dict['param']
965
- if path[0] == 'main_settings':
1169
+ path = settings_parameter_dict["path"]
1170
+ param = settings_parameter_dict["param"]
1171
+ if path[0] == "main_settings":
966
1172
  if hasattr(self, path[-1]):
967
1173
  setattr(self, path[-1], param.value())
968
1174
 
969
- elif path[0] == 'move_settings':
1175
+ elif path[0] == "move_settings":
970
1176
  if self.hardware is not None:
971
1177
  self.hardware.update_settings(settings_parameter_dict)
972
1178
 
@@ -984,6 +1190,5 @@ def main(init_qt=True):
984
1190
  return prog, widget
985
1191
 
986
1192
 
987
- if __name__ == '__main__':
1193
+ if __name__ == "__main__":
988
1194
  main()
989
-