pymodaq 5.0.17__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 +458 -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 +13 -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 +18 -4
  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.17.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.17.dist-info → pymodaq-5.1.0.dist-info}/entry_points.txt +0 -2
  88. pymodaq/extensions/bayesian/bayesian_optimisation.py +0 -685
  89. pymodaq/utils/leco/desktop.ini +0 -2
  90. pymodaq-5.0.17.dist-info/RECORD +0 -121
  91. {pymodaq-5.0.17.dist-info → pymodaq-5.1.0.dist-info}/WHEEL +0 -0
  92. {pymodaq-5.0.17.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,40 +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], float, 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
- data_act = data_act[0]
522
- if isinstance(data_act, np.ndarray): # backcompatibility
625
+ if isinstance(data_act[0], Number):
626
+ data_act = DataActuator(
627
+ data=[np.atleast_1d(val) for val in data_act], units=self.units
628
+ )
629
+ elif isinstance(data_act[0], np.ndarray):
630
+ data_act = DataActuator(data=data_act, units=self.units)
631
+ elif isinstance(data_act[0], DataActuator):
632
+ data_act = data_act[0]
633
+ else:
634
+ raise TypeError("Unknown data type")
635
+ elif isinstance(data_act, np.ndarray): # backcompatibility
523
636
  data_act = DataActuator(data=[data_act], units=self.units)
524
- data_act.name = self.title # for the DataActuator name to be the title of the DAQ_Move
525
- if (not Unit(self.units).is_compatible_with(Unit(data_act.units)) and
526
- 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
527
644
  # the plugin
528
645
  data_act.force_units(self.units)
529
- return data_act
646
+ return data_act
530
647
 
531
648
  def get_actuator_value(self):
532
649
  """Get the current actuator value via the "get_actuator_value" command send to the hardware
@@ -534,14 +651,16 @@ class DAQ_Move(ParameterControlModule):
534
651
  Returns nothing but the `move_done_signal` will be send once the action is done
535
652
  """
536
653
  try:
537
- self.command_hardware.emit(ThreadCommand(command="get_actuator_value"))
654
+ self.command_hardware.emit(
655
+ ThreadCommand(ControlToHardwareMove.GET_ACTUATOR_VALUE)
656
+ )
538
657
 
539
658
  except Exception as e:
540
659
  self.logger.exception(str(e))
541
660
 
542
661
  def grab(self):
543
662
  if self.ui is not None:
544
- self.manage_ui_actions('refresh_value', 'setChecked', False)
663
+ self.manage_ui_actions("refresh_value", "setChecked", False)
545
664
  self.get_continuous_actuator_value(False)
546
665
 
547
666
  def stop_grab(self):
@@ -550,7 +669,7 @@ class DAQ_Move(ParameterControlModule):
550
669
  First uncheck the ui action if ui is not None, then stop the polling
551
670
  """
552
671
  if self.ui is not None:
553
- self.manage_ui_actions('refresh_value', 'setChecked', False)
672
+ self.manage_ui_actions("refresh_value", "setChecked", False)
554
673
  self.get_continuous_actuator_value(False)
555
674
 
556
675
  def get_continuous_actuator_value(self, get_value=True):
@@ -566,7 +685,9 @@ class DAQ_Move(ParameterControlModule):
566
685
  The current timer period is set by the refresh value *'refresh_timeout'* in the actuator main settings.
567
686
  """
568
687
  if get_value:
569
- self._refresh_timer.setInterval(self.settings['main_settings', 'refresh_timeout'])
688
+ self._refresh_timer.setInterval(
689
+ self.settings["main_settings", "refresh_timeout"]
690
+ )
570
691
  self._refresh_timer.start()
571
692
  else:
572
693
  self._refresh_timer.stop()
@@ -590,33 +711,92 @@ class DAQ_Move(ParameterControlModule):
590
711
  self.ui.actuator = act_type
591
712
  self.update_settings()
592
713
  else:
593
- 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
+ )
594
717
 
595
718
  @property
596
719
  def actuators(self) -> List[str]:
597
- """ Get the list of possible actuators"""
720
+ """Get the list of possible actuators"""
598
721
  return ACTUATOR_TYPES
599
722
 
600
723
  def update_plugin_config(self):
601
- parent_module = utils.find_dict_in_list_from_key_val(DAQ_Move_Actuators, 'name', self.actuator)
602
- mod = import_module(parent_module['module'].__package__.split('.')[0])
603
- 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"):
604
729
  self.plugin_config = mod.config
605
730
 
606
731
  @property
607
732
  def units(self):
608
733
  """Get/Set the units for the controller"""
609
- return self.settings['move_settings', 'units']
734
+ return self.settings["move_settings", "units"]
610
735
 
611
736
  @units.setter
612
737
  def units(self, unit: str):
613
- self.settings.child('move_settings', 'units').setValue(unit)
614
- if self.ui is not None and config('actuator', 'display_units'):
615
- 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])
616
796
 
617
797
  @staticmethod
618
798
  def get_unit_to_display(unit: str) -> str:
619
- """ Get the unit to be displayed in the UI
799
+ """Get the unit to be displayed in the UI
620
800
 
621
801
  If the controller units are in mm the displayed unit will be m
622
802
  because m is the base unit, then the user could ask for mm, km, µm...
@@ -630,94 +810,96 @@ class DAQ_Move(ParameterControlModule):
630
810
  -------
631
811
  str: the unit to be displayed on the ui
632
812
  """
633
- 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:
634
814
  # special cas as pint base unit for angles are radians
635
- return '°'
636
- elif 'W' in unit or 'watt' in unit.lower():
637
- return 'W'
638
- elif '°C' in unit or 'Celsius' in unit:
639
- return '°C'
640
- elif 'V' in unit or 'volt' in unit.lower():
641
- return 'V'
642
- elif 'Hz' in unit:
643
- return 'Hz'
644
- elif 'rpm' in unit or 'revolutions_per_minute' in unit:
645
- return 'rpm'
815
+ return "°"
816
+ elif "°C" in unit:
817
+ return "°C"
646
818
  else:
819
+ for key in config("actuator", "allowed_units"):
820
+ if key in unit:
821
+ return config("actuator", "allowed_units", key)
647
822
  return str(Q_(1, unit).to_base_units().units)
648
823
 
649
824
  def update_settings(self):
650
-
651
- self.settings.child('main_settings', 'move_type').setValue(self._actuator_type)
652
- 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)
653
827
  try:
654
- for child in self.settings.child('move_settings').children():
828
+ for child in self.settings.child("move_settings").children():
655
829
  child.remove()
656
- parent_module = utils.find_dict_in_list_from_key_val(DAQ_Move_Actuators, 'name', self._actuator_type)
657
- class_ = getattr(getattr(parent_module['module'], 'daq_move_' + self._actuator_type),
658
- 'DAQ_Move_' + self._actuator_type)
659
- params = getattr(class_, 'params')
660
- move_params = Parameter.create(name='move_settings', type='group', children=params)
661
-
662
- 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())
663
843
 
664
844
  except Exception as e:
665
845
  self.logger.exception(str(e))
666
846
 
667
847
  def connect_tcp_ip(self):
668
- super().connect_tcp_ip(params_state=self.settings.child('move_settings'),
669
- 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)
670
854
 
671
855
  @Slot(ThreadCommand)
672
856
  def process_tcpip_cmds(self, status: ThreadCommand) -> None:
673
857
  if super().process_tcpip_cmds(status=status) is None:
674
858
  return
675
- if 'move_abs' in status.command:
676
- 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)
677
861
 
678
- elif 'move_rel' in status.command:
679
- 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)
680
864
 
681
- elif 'move_home' in status.command:
865
+ elif LECOMoveCommands.MOVE_HOME == status.command:
682
866
  self.move_home(send_to_tcpip=True)
683
867
 
684
- elif 'check_position' in status.command:
685
- 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
+ )
686
872
  self._send_to_tcpip = True
687
- self.command_hardware.emit(ThreadCommand('get_actuator_value', ))
873
+ self.get_actuator_value()
688
874
 
689
- elif 'get_actuator_value' in status.command:
875
+ elif LECOMoveCommands.GET_ACTUATOR_VALUE in status.command:
690
876
  self._send_to_tcpip = True
691
- self.command_hardware.emit(ThreadCommand('get_actuator_value', ))
877
+ self.get_actuator_value()
692
878
 
693
- elif status.command == 'set_info':
694
- path_in_settings = status.attribute[0]
695
- param_as_xml = status.attribute[1]
696
- param_dict = ioxml.XML_string_to_parameter(param_as_xml)[0]
697
- param_tmp = Parameter.create(**param_dict)
698
- param = self.settings.child('move_settings', *path_in_settings[1:])
699
- param.restoreState(param_tmp.saveState())
879
+ elif status.command == LECOMoveCommands.STOP:
880
+ self.stop_motion()
700
881
 
701
882
 
702
883
  class DAQ_Move_Hardware(QObject):
703
884
  """
704
- ================== ========================
705
- **Attributes** **Type**
706
- *status_sig* instance of Signal
707
- *hardware* ???
708
- *actuator_type* string
709
- *current_position* float
710
- *target_value* float
711
- *hardware_adress* string
712
- *axis_address* string
713
- *motion_stoped* boolean
714
- ================== ========================
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
+ ================== ========================
715
896
  """
897
+
716
898
  status_sig = Signal(ThreadCommand)
717
899
 
718
- def __init__(self, actuator_type, position: DataActuator, title='actuator'):
900
+ def __init__(self, actuator_type, position: DataActuator, title="actuator"):
719
901
  super().__init__()
720
- self.logger = set_logger(f'{logger.name}.{title}.actuator')
902
+ self.logger = set_logger(f"{logger.name}.{title}.actuator")
721
903
  self._title = title
722
904
  self.hardware: Optional[DAQ_Move_base] = None
723
905
  self.actuator_type = actuator_type
@@ -731,7 +913,7 @@ class DAQ_Move_Hardware(QObject):
731
913
 
732
914
  def close(self):
733
915
  """
734
- Uninitialize the stage closing the hardware.
916
+ Uninitialize the stage closing the hardware.
735
917
 
736
918
  """
737
919
  if self.hardware is not None and self.hardware.controller is not None:
@@ -740,8 +922,7 @@ class DAQ_Move_Hardware(QObject):
740
922
  return "Stage uninitialized"
741
923
 
742
924
  def get_actuator_value(self):
743
- """Get the current position checking the hardware value.
744
- """
925
+ """Get the current position checking the hardware value."""
745
926
  if self.hardware is not None:
746
927
  pos = self.hardware.get_actuator_value()
747
928
  if self.hardware.data_actuator_type == DataActuatorType.float:
@@ -749,86 +930,107 @@ class DAQ_Move_Hardware(QObject):
749
930
  return pos
750
931
 
751
932
  def check_position(self):
752
- """Get the current position checking the hardware position (deprecated)
753
- """
754
- 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")
755
935
  pos = self.hardware.get_actuator_value()
756
936
  return pos
757
937
 
758
- def ini_stage(self, params_state=None, controller=None):
938
+ def ini_stage(self, params_state=None, controller: Optional[HardwareController] = None) -> edict:
759
939
  """
760
- 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.
761
941
 
762
- =============== =================================== ==========================================================================================================================
763
- **Parameters** **Type** **Description**
942
+ =============== =================================== ==========================================================================================================================
943
+ **Parameters** **Type** **Description**
764
944
 
765
- *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
766
946
 
767
- *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
768
948
 
769
- *stage* instance of DAQ_Move Defining axes and motors
770
- =============== =================================== ==========================================================================================================================
949
+ *stage* instance of DAQ_Move Defining axes and motors
950
+ =============== =================================== ==========================================================================================================================
771
951
 
772
- See Also
773
- --------
774
- DAQ_utils.ThreadCommand, DAQ_Move
952
+ See Also
953
+ --------
954
+ DAQ_utils.ThreadCommand, DAQ_Move
775
955
  """
776
956
 
777
957
  status = edict(initialized=False, info="")
778
958
  try:
779
- parent_module = utils.find_dict_in_list_from_key_val(DAQ_Move_Actuators, 'name', self.actuator_type)
780
- class_ = getattr(getattr(parent_module['module'], 'daq_move_' + self.actuator_type),
781
- '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
+ )
782
966
  self.hardware = class_(self, params_state)
967
+ assert self.hardware is not None
783
968
  try:
784
- 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=)
785
972
  except Exception as e:
786
973
  logger.exception("Hardware couldn't be initialized", exc_info=e)
787
974
  infos = str(e), False
788
975
 
789
976
  if isinstance(infos, edict): # following old plugin templating
790
977
  status.update(infos)
791
- deprecation_msg('Returns from init_stage should now be a string and a boolean,'
792
- ' 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
+ )
793
983
  else:
794
984
  status.info = infos[0]
795
985
  status.initialized = infos[1]
796
986
  status.controller = self.hardware.controller
797
987
  self.hardware.move_done_signal.connect(self.move_done)
798
988
  if status.initialized:
799
- 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
+ )
800
994
 
801
995
  return status
802
996
  except Exception as e:
803
997
  self.logger.exception(str(e))
804
998
  return status
805
999
 
806
- def move_abs(self, position: DataActuator, polling=True):
1000
+ def move_abs(self, position: DataActuator, polling: bool = True) -> None:
807
1001
  """
808
1002
 
809
1003
  """
1004
+ assert self.hardware is not None
810
1005
  position = check_units(position, self.hardware.axis_unit)
811
1006
  self.hardware.move_is_done = False
812
1007
  self.hardware.ispolling = polling
813
1008
  if self.hardware.data_actuator_type == self.hardware.data_actuator_type.float:
814
- 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
815
1012
  else:
816
- 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
817
1016
  self.hardware.move_abs(position)
818
1017
  self.hardware.poll_moving()
819
1018
 
820
- def move_rel(self, rel_position: DataActuator, polling=True):
1019
+ def move_rel(self, rel_position: DataActuator, polling: bool = True) -> None:
821
1020
  """
822
1021
 
823
1022
  """
1023
+ assert self.hardware is not None
824
1024
  rel_position = check_units(rel_position, self.hardware.axis_unit)
825
1025
  self.hardware.move_is_done = False
826
1026
  self.hardware.ispolling = polling
827
1027
 
828
1028
  if self.hardware.data_actuator_type.name == 'float':
829
- self.hardware.move_rel(rel_position.value())
1029
+ self.hardware.move_rel(rel_position.units_as(self.hardware.axis_unit).value())
830
1030
  else:
831
- 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
832
1034
  self.hardware.move_rel(rel_position)
833
1035
 
834
1036
  self.hardware.poll_moving()
@@ -836,28 +1038,30 @@ class DAQ_Move_Hardware(QObject):
836
1038
  @Slot(float)
837
1039
  def Move_Stoped(self, pos):
838
1040
  """
839
- 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.
840
1042
 
841
- See Also
842
- --------
843
- DAQ_utils.ThreadCommand
1043
+ See Also
1044
+ --------
1045
+ DAQ_utils.ThreadCommand
844
1046
  """
845
- self.status_sig.emit(ThreadCommand("move_done", pos))
1047
+ self.status_sig.emit(ThreadCommand(ThreadStatusMove.MOVE_DONE, pos))
846
1048
 
847
1049
  def move_home(self):
848
1050
  """
849
- Make the hardware move to the init position.
1051
+ Make the hardware move to the init position.
850
1052
 
851
1053
  """
1054
+ assert self.hardware is not None
852
1055
  self.hardware.move_is_done = False
853
1056
  self.hardware.move_home()
854
1057
 
855
1058
  @Slot(DataActuator)
856
1059
  def move_done(self, pos: DataActuator):
857
- """Send the move_done signal back to the main class
858
- """
1060
+ """Send the move_done signal back to the main class"""
859
1061
  self._current_value = pos
860
- self.status_sig.emit(ThreadCommand(command="move_done", attribute=pos))
1062
+ self.status_sig.emit(
1063
+ ThreadCommand(command=ThreadStatusMove.MOVE_DONE, attribute=pos)
1064
+ )
861
1065
 
862
1066
  @Slot(ThreadCommand)
863
1067
  def queue_command(self, command: ThreadCommand):
@@ -885,32 +1089,38 @@ class DAQ_Move_Hardware(QObject):
885
1089
  * **reset_stop_motion** command, set the motion_stopped attribute to false
886
1090
  """
887
1091
  try:
888
- logger.debug(f'Threadcommand {command.command} sent to {self.title}')
889
- if command.command == "ini_stage":
1092
+ logger.debug(f"Threadcommand {command.command} sent to {self.title}")
1093
+ if command.command == ControlToHardwareMove.INI_STAGE:
890
1094
  status: edict = self.ini_stage(*command.attribute)
891
- self.status_sig.emit(ThreadCommand(command=command.command, attribute=status))
1095
+ self.status_sig.emit(
1096
+ ThreadCommand(command=ThreadStatusMove.INI_STAGE, attribute=status)
1097
+ )
892
1098
 
893
- elif command.command == "close":
1099
+ elif command.command == ControlToHardwareMove.CLOSE:
894
1100
  status = self.close()
895
- self.status_sig.emit(ThreadCommand(command=command.command, attribute=[status]))
1101
+ self.status_sig.emit(
1102
+ ThreadCommand(command=ThreadStatus.CLOSE, attribute=[status])
1103
+ )
896
1104
 
897
- elif command.command == "move_abs":
1105
+ elif command.command == ControlToHardwareMove.MOVE_ABS:
898
1106
  self.move_abs(*command.attribute)
899
1107
 
900
- elif command.command == "move_rel":
1108
+ elif command.command == ControlToHardwareMove.MOVE_REL:
901
1109
  self.move_rel(*command.attribute)
902
1110
 
903
- elif command.command == "move_home":
1111
+ elif command.command == ControlToHardwareMove.MOVE_HOME:
904
1112
  self.move_home()
905
1113
 
906
- elif command.command == "get_actuator_value":
1114
+ elif command.command == ControlToHardwareMove.GET_ACTUATOR_VALUE:
907
1115
  pos = self.get_actuator_value()
908
- self.status_sig.emit(ThreadCommand('get_actuator_value', [pos]))
1116
+ self.status_sig.emit(
1117
+ ThreadCommand(ThreadStatusMove.GET_ACTUATOR_VALUE, pos)
1118
+ )
909
1119
 
910
- elif command.command == "stop_motion":
1120
+ elif command.command == ControlToHardwareMove.STOP_MOTION:
911
1121
  self.stop_motion()
912
1122
 
913
- elif command.command == "reset_stop_motion":
1123
+ elif command.command == ControlToHardwareMove.RESET_STOP_MOTION:
914
1124
  self.motion_stoped = False
915
1125
 
916
1126
  else: # custom commands for particular plugins (see spectrometer module 'get_spectro_wl' for instance)
@@ -925,14 +1135,17 @@ class DAQ_Move_Hardware(QObject):
925
1135
 
926
1136
  def stop_motion(self):
927
1137
  """
928
- 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
929
1139
 
930
- See Also
931
- --------
932
- DAQ_utils.ThreadCommand, stop_motion
1140
+ See Also
1141
+ --------
1142
+ DAQ_utils.ThreadCommand, stop_motion
933
1143
  """
934
- 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
+ )
935
1147
  self.motion_stoped = True
1148
+ assert self.hardware is not None
936
1149
  if self.hardware is not None and self.hardware.controller is not None:
937
1150
  self.hardware.stop_motion()
938
1151
  self.hardware.poll_timer.stop()
@@ -940,26 +1153,26 @@ class DAQ_Move_Hardware(QObject):
940
1153
  @Slot(edict)
941
1154
  def update_settings(self, settings_parameter_dict):
942
1155
  """
943
- 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.
944
1157
 
945
- ========================= =========== ======================================================
946
- **Parameters** **Type** **Description**
1158
+ ========================= =========== ======================================================
1159
+ **Parameters** **Type** **Description**
947
1160
 
948
- *settings_parameter_dict* dictionary Dictionary containing the path and linked parameter
949
- ========================= =========== ======================================================
1161
+ *settings_parameter_dict* dictionary Dictionary containing the path and linked parameter
1162
+ ========================= =========== ======================================================
950
1163
 
951
- See Also
952
- --------
953
- update_settings
1164
+ See Also
1165
+ --------
1166
+ update_settings
954
1167
  """
955
1168
  # settings_parameter_dict = edict(path=path,param=param)
956
- path = settings_parameter_dict['path']
957
- param = settings_parameter_dict['param']
958
- if path[0] == 'main_settings':
1169
+ path = settings_parameter_dict["path"]
1170
+ param = settings_parameter_dict["param"]
1171
+ if path[0] == "main_settings":
959
1172
  if hasattr(self, path[-1]):
960
1173
  setattr(self, path[-1], param.value())
961
1174
 
962
- elif path[0] == 'move_settings':
1175
+ elif path[0] == "move_settings":
963
1176
  if self.hardware is not None:
964
1177
  self.hardware.update_settings(settings_parameter_dict)
965
1178
 
@@ -977,6 +1190,5 @@ def main(init_qt=True):
977
1190
  return prog, widget
978
1191
 
979
1192
 
980
- if __name__ == '__main__':
1193
+ if __name__ == "__main__":
981
1194
  main()
982
-