pymodaq 5.0.0__py3-none-any.whl → 5.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pymodaq might be problematic. Click here for more details.
- pymodaq/__init__.py +55 -89
- pymodaq/control_modules/daq_move.py +123 -52
- pymodaq/control_modules/daq_move_ui.py +42 -11
- pymodaq/control_modules/daq_viewer.py +30 -13
- pymodaq/control_modules/move_utility_classes.py +345 -78
- pymodaq/control_modules/utils.py +26 -9
- pymodaq/control_modules/viewer_utility_classes.py +51 -14
- pymodaq/daq_utils/daq_utils.py +6 -0
- pymodaq/dashboard.py +532 -263
- pymodaq/examples/qt_less_standalone_module.py +128 -0
- pymodaq/extensions/bayesian/bayesian_optimisation.py +30 -21
- pymodaq/extensions/bayesian/utils.py +6 -3
- pymodaq/extensions/daq_logger/__init__.py +1 -0
- pymodaq/extensions/daq_logger/daq_logger.py +4 -5
- pymodaq/extensions/daq_scan.py +1 -3
- pymodaq/extensions/daq_scan_ui.py +7 -9
- pymodaq/extensions/pid/__init__.py +0 -1
- pymodaq/extensions/pid/actuator_controller.py +13 -0
- pymodaq/extensions/pid/daq_move_PID.py +25 -46
- pymodaq/extensions/pid/pid_controller.py +48 -40
- pymodaq/extensions/pid/utils.py +3 -2
- pymodaq/extensions/utils.py +41 -7
- pymodaq/resources/setup_plugin.py +1 -0
- pymodaq/updater.py +107 -0
- pymodaq/utils/chrono_timer.py +6 -7
- pymodaq/utils/daq_utils.py +6 -3
- pymodaq/utils/data.py +11 -16
- pymodaq/utils/enums.py +6 -0
- pymodaq/utils/gui_utils/loader_utils.py +27 -2
- pymodaq/utils/gui_utils/utils.py +9 -12
- pymodaq/utils/gui_utils/widgets/lcd.py +8 -0
- pymodaq/utils/leco/daq_move_LECODirector.py +21 -14
- pymodaq/utils/leco/daq_xDviewer_LECODirector.py +13 -8
- pymodaq/utils/leco/pymodaq_listener.py +8 -7
- pymodaq/utils/leco/utils.py +33 -7
- pymodaq/utils/managers/modules_manager.py +20 -10
- pymodaq/utils/managers/overshoot_manager.py +45 -1
- pymodaq/utils/managers/preset_manager.py +22 -46
- pymodaq/utils/managers/preset_manager_utils.py +17 -13
- pymodaq/utils/managers/remote_manager.py +1 -1
- pymodaq/utils/messenger.py +6 -0
- pymodaq/utils/parameter/__init__.py +5 -1
- pymodaq/utils/tcp_ip/mysocket.py +4 -110
- pymodaq/utils/tcp_ip/serializer.py +4 -769
- pymodaq/utils/tcp_ip/tcp_server_client.py +5 -5
- pymodaq-5.0.1.dist-info/METADATA +242 -0
- {pymodaq-5.0.0.dist-info → pymodaq-5.0.1.dist-info}/RECORD +51 -52
- {pymodaq-5.0.0.dist-info → pymodaq-5.0.1.dist-info}/WHEEL +1 -1
- {pymodaq-5.0.0.dist-info → pymodaq-5.0.1.dist-info}/entry_points.txt +1 -0
- pymodaq/examples/custom_app.py +0 -255
- pymodaq/examples/custom_viewer.py +0 -112
- pymodaq/examples/parameter_ex.py +0 -158
- pymodaq/examples/preset_MockCamera.xml +0 -1
- pymodaq/post_treatment/daq_measurement/daq_measurement_GUI.py +0 -142
- pymodaq/post_treatment/daq_measurement/daq_measurement_GUI.ui +0 -232
- pymodaq/post_treatment/daq_measurement/daq_measurement_main.py +0 -391
- pymodaq/post_treatment/daq_measurement/process_from_QtDesigner_DAQ_Measurement_GUI.bat +0 -2
- pymodaq-5.0.0.dist-info/METADATA +0 -166
- /pymodaq/{post_treatment/daq_measurement → daq_utils}/__init__.py +0 -0
- {pymodaq-5.0.0.dist-info → pymodaq-5.0.1.dist-info}/licenses/LICENSE +0 -0
pymodaq/__init__.py
CHANGED
|
@@ -6,23 +6,11 @@ from pathlib import Path
|
|
|
6
6
|
|
|
7
7
|
import warnings
|
|
8
8
|
|
|
9
|
+
import pymodaq_utils # to init stuff related to pymodaq_utils # necessary, leave it there
|
|
10
|
+
import pymodaq_data # to init stuff related to pymodaq_data # necessary, leave it there
|
|
11
|
+
import pymodaq_gui # to init stuff related to pymodaq_gui # necessary, leave it there
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
try:
|
|
12
|
-
from qtpy import QtWidgets
|
|
13
|
-
except ImportError as e:
|
|
14
|
-
msg = f"\n\n" \
|
|
15
|
-
f"****************************************************************************************\n" \
|
|
16
|
-
f"No Qt backend could be found in your system, please install either pyqt5/6 or pyside2/6.\n\n" \
|
|
17
|
-
f"pyqt5 is still preferred, while pyqt6 should mostly work.\n\n" \
|
|
18
|
-
f"do:\n" \
|
|
19
|
-
f"pip install pyqt5\n for instance\n"\
|
|
20
|
-
f"****************************************************************************************\n"
|
|
21
|
-
warnings.warn(msg, FutureWarning, 2)
|
|
22
|
-
sys.exit()
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
check_qt_presence()
|
|
13
|
+
from pymodaq_data import Q_, Unit, ureg # necessary, leave it there
|
|
26
14
|
|
|
27
15
|
|
|
28
16
|
try:
|
|
@@ -31,87 +19,65 @@ try:
|
|
|
31
19
|
|
|
32
20
|
from pymodaq_utils.logger import set_logger
|
|
33
21
|
from pymodaq_utils.utils import get_version
|
|
34
|
-
__version__ = get_version()
|
|
22
|
+
__version__ = get_version('pymodaq')
|
|
35
23
|
try:
|
|
36
24
|
logger = set_logger('pymodaq', add_handler=True, base_logger=True)
|
|
37
|
-
except Exception:
|
|
38
|
-
print("Couldn't create the local folder to store logs , presets...")
|
|
39
25
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
from pymodaq_data.plotting.plotter.plotter import register_plotter, PlotterFactory
|
|
65
|
-
|
|
66
|
-
# issue on windows when using .NET code within multithreads, this below allows it but requires
|
|
67
|
-
# the pywin32 (pythoncom) package
|
|
68
|
-
if importlib.util.find_spec('clr') is not None:
|
|
26
|
+
from pymodaq.utils.daq_utils import copy_preset, get_instrument_plugins
|
|
27
|
+
|
|
28
|
+
from pymodaq_utils.config import Config
|
|
29
|
+
from pymodaq.utils.scanner.utils import register_scanners
|
|
30
|
+
from pymodaq_data.plotting.plotter.plotter import register_plotter, PlotterFactory
|
|
31
|
+
|
|
32
|
+
# issue on windows when using .NET code within multithreads, this below allows it but requires
|
|
33
|
+
# the pywin32 (pythoncom) package
|
|
34
|
+
if importlib.util.find_spec('clr') is not None:
|
|
35
|
+
try:
|
|
36
|
+
import pythoncom
|
|
37
|
+
pythoncom.CoInitialize()
|
|
38
|
+
except ModuleNotFoundError as e:
|
|
39
|
+
infos = "You have installed plugins requiring the pywin32 package to work correctly," \
|
|
40
|
+
" please type in *pip install pywin32* and restart PyMoDAQ"
|
|
41
|
+
print(infos)
|
|
42
|
+
logger.warning(infos)
|
|
43
|
+
|
|
44
|
+
config = Config() # to ckeck for config file existence, otherwise create one
|
|
45
|
+
copy_preset()
|
|
46
|
+
|
|
47
|
+
from pymodaq_utils.config import Config
|
|
48
|
+
from pymodaq.utils.scanner.utils import register_scanners
|
|
49
|
+
|
|
69
50
|
try:
|
|
70
|
-
|
|
71
|
-
|
|
51
|
+
# Need the config to exists before importing
|
|
52
|
+
from pymodaq_utils.environment import EnvironmentBackupManager
|
|
53
|
+
|
|
54
|
+
if config['backup']['keep_backup']:
|
|
55
|
+
ebm = EnvironmentBackupManager()
|
|
56
|
+
ebm.save_backup()
|
|
72
57
|
except ModuleNotFoundError as e:
|
|
73
|
-
infos = "
|
|
74
|
-
"
|
|
58
|
+
infos = "Your pymodaq_utils version is outdated and doesn't allow for automatic backup of pip packages." \
|
|
59
|
+
" You should update it."
|
|
75
60
|
print(infos)
|
|
76
61
|
logger.warning(infos)
|
|
77
62
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
logger.info('')
|
|
97
|
-
get_instrument_plugins()
|
|
98
|
-
logger.info('*************************************************************************')
|
|
99
|
-
|
|
100
|
-
logger.info('')
|
|
101
|
-
logger.info('')
|
|
102
|
-
logger.info('************************')
|
|
103
|
-
logger.info(f"Registering Scanners...")
|
|
104
|
-
register_scanners()
|
|
105
|
-
logger.info(f"Done")
|
|
106
|
-
logger.info('************************')
|
|
107
|
-
|
|
108
|
-
logger.info('')
|
|
109
|
-
logger.info('')
|
|
110
|
-
logger.info('************************')
|
|
111
|
-
logger.info(f"Registering plotters...")
|
|
112
|
-
register_plotter()
|
|
113
|
-
logger.info(f"Done")
|
|
114
|
-
logger.info('************************')
|
|
63
|
+
logger.info('*************************************************************************')
|
|
64
|
+
logger.info(f"Getting the list of instrument plugins...")
|
|
65
|
+
logger.info('')
|
|
66
|
+
get_instrument_plugins()
|
|
67
|
+
logger.info('*************************************************************************')
|
|
68
|
+
|
|
69
|
+
logger.info('')
|
|
70
|
+
logger.info('')
|
|
71
|
+
logger.info('************************')
|
|
72
|
+
logger.info(f"Registering Scanners...")
|
|
73
|
+
register_scanners()
|
|
74
|
+
logger.info(f"Done")
|
|
75
|
+
logger.info('************************')
|
|
76
|
+
|
|
77
|
+
except Exception:
|
|
78
|
+
print("Couldn't create the local folder to store logs , presets...")
|
|
79
|
+
|
|
80
|
+
|
|
115
81
|
|
|
116
82
|
except Exception as e:
|
|
117
83
|
try:
|
|
@@ -32,14 +32,22 @@ from pymodaq_data.h5modules.backends import Node
|
|
|
32
32
|
|
|
33
33
|
from pymodaq_gui.parameter import ioxml, Parameter
|
|
34
34
|
from pymodaq_gui.parameter import utils as putils
|
|
35
|
+
from pymodaq_gui.utils.utils import mkQApp
|
|
35
36
|
|
|
36
37
|
from pymodaq.utils.h5modules import module_saving
|
|
37
38
|
from pymodaq.control_modules.utils import ParameterControlModule
|
|
38
|
-
from pymodaq.control_modules.daq_move_ui import DAQ_Move_UI
|
|
39
|
-
from pymodaq.control_modules.move_utility_classes import MoveCommand, DAQ_Move_base
|
|
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)
|
|
43
|
+
|
|
44
|
+
|
|
40
45
|
from pymodaq.control_modules.move_utility_classes import params as daq_move_params
|
|
41
46
|
from pymodaq.utils.leco.pymodaq_listener import MoveActorListener, LECOMoveCommands
|
|
47
|
+
|
|
42
48
|
from pymodaq.utils.daq_utils import get_plugins
|
|
49
|
+
from pymodaq import Q_, Unit
|
|
50
|
+
|
|
43
51
|
|
|
44
52
|
|
|
45
53
|
local_path = config_mod.get_set_local_dir()
|
|
@@ -116,15 +124,15 @@ class DAQ_Move(ParameterControlModule):
|
|
|
116
124
|
self.splash_sc = get_splash_sc()
|
|
117
125
|
self._title = title
|
|
118
126
|
if len(ACTUATOR_TYPES) > 0: # will be 0 if no valid plugins are installed
|
|
119
|
-
self.actuator = ACTUATOR_TYPES[0]
|
|
127
|
+
self.actuator = kwargs.get('actuator', ACTUATOR_TYPES[0])
|
|
120
128
|
|
|
121
129
|
self.module_and_data_saver = module_saving.ActuatorSaver(self)
|
|
122
130
|
|
|
123
131
|
self._move_done_bool = True
|
|
124
132
|
|
|
125
|
-
self._current_value = DataActuator(title)
|
|
126
|
-
self._target_value
|
|
127
|
-
self._relative_value
|
|
133
|
+
self._current_value = DataActuator(title, units=self.units)
|
|
134
|
+
self._target_value = DataActuator(title, units=self.units)
|
|
135
|
+
self._relative_value = DataActuator(title, units=self.units)
|
|
128
136
|
|
|
129
137
|
self._refresh_timer = QTimer()
|
|
130
138
|
self._refresh_timer.timeout.connect(self.get_actuator_value)
|
|
@@ -162,9 +170,15 @@ class DAQ_Move(ParameterControlModule):
|
|
|
162
170
|
elif cmd.command == 'stop':
|
|
163
171
|
self.stop_motion()
|
|
164
172
|
elif cmd.command == 'move_abs':
|
|
165
|
-
|
|
173
|
+
data_act: DataActuator = cmd.attribute
|
|
174
|
+
if not Unit(data_act.units).is_compatible_with(self.units) and data_act.units != '':
|
|
175
|
+
data_act.force_units(self.units)
|
|
176
|
+
self.move_abs(data_act)
|
|
166
177
|
elif cmd.command == 'move_rel':
|
|
167
|
-
|
|
178
|
+
data_act: DataActuator = cmd.attribute
|
|
179
|
+
if not Unit(data_act.units).is_compatible_with(self.units) and data_act.units != '':
|
|
180
|
+
data_act.force_units(self.units)
|
|
181
|
+
self.move_rel(data_act)
|
|
168
182
|
elif cmd.command == 'show_log':
|
|
169
183
|
self.show_log()
|
|
170
184
|
elif cmd.command == 'show_config':
|
|
@@ -175,6 +189,20 @@ class DAQ_Move(ParameterControlModule):
|
|
|
175
189
|
elif cmd.command == 'rel_value':
|
|
176
190
|
self._relative_value = cmd.attribute
|
|
177
191
|
|
|
192
|
+
@property
|
|
193
|
+
def master(self) -> bool:
|
|
194
|
+
""" Get/Set programmatically the Master/Slave status of an actuator"""
|
|
195
|
+
if self.initialized_state:
|
|
196
|
+
return self.settings['move_settings', 'multiaxes', 'multi_status'] == 'Master'
|
|
197
|
+
else:
|
|
198
|
+
return True
|
|
199
|
+
|
|
200
|
+
@master.setter
|
|
201
|
+
def master(self, is_master: bool):
|
|
202
|
+
if self.initialized_state:
|
|
203
|
+
self.settings.child('move_settings', 'multiaxes', 'multi_status').setValue(
|
|
204
|
+
'Master' if is_master else 'Slave')
|
|
205
|
+
|
|
178
206
|
def append_data(self, dte: Optional[DataToExport] = None, where: Union[Node, str, None] = None):
|
|
179
207
|
"""Appends current DataToExport to an ActuatorEnlargeableSaver
|
|
180
208
|
|
|
@@ -258,7 +286,7 @@ class DAQ_Move(ParameterControlModule):
|
|
|
258
286
|
"""
|
|
259
287
|
try:
|
|
260
288
|
if isinstance(value, Number):
|
|
261
|
-
value = DataActuator(self.title, data=[np.array([value])])
|
|
289
|
+
value = DataActuator(self.title, data=[np.array([value])], units=self.units)
|
|
262
290
|
self._send_to_tcpip = send_to_tcpip
|
|
263
291
|
if value != self._current_value:
|
|
264
292
|
if self.ui is not None:
|
|
@@ -307,7 +335,7 @@ class DAQ_Move(ParameterControlModule):
|
|
|
307
335
|
|
|
308
336
|
try:
|
|
309
337
|
if isinstance(rel_value, Number):
|
|
310
|
-
rel_value = DataActuator(self.title, data=[np.array([rel_value])])
|
|
338
|
+
rel_value = DataActuator(self.title, data=[np.array([rel_value])], units=self.units)
|
|
311
339
|
self._send_to_tcpip = send_to_tcpip
|
|
312
340
|
if self.ui is not None:
|
|
313
341
|
self.ui.move_done = False
|
|
@@ -362,8 +390,9 @@ class DAQ_Move(ParameterControlModule):
|
|
|
362
390
|
self._hardware_thread.hardware = hardware
|
|
363
391
|
self._hardware_thread.start()
|
|
364
392
|
self.command_hardware.emit(
|
|
365
|
-
ThreadCommand(command="ini_stage", attribute=[
|
|
366
|
-
|
|
393
|
+
ThreadCommand(command="ini_stage", attribute=[
|
|
394
|
+
self.settings.child('move_settings').saveState(),
|
|
395
|
+
self.controller]))
|
|
367
396
|
except Exception as e:
|
|
368
397
|
self.logger.exception(str(e))
|
|
369
398
|
|
|
@@ -429,11 +458,10 @@ class DAQ_Move(ParameterControlModule):
|
|
|
429
458
|
super().thread_status(status, 'move')
|
|
430
459
|
|
|
431
460
|
if status.command == "ini_stage":
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
self.controller = status.attribute[0]['controller']
|
|
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']
|
|
437
465
|
if self.ui is not None:
|
|
438
466
|
self.ui.actuator_init = True
|
|
439
467
|
self._initialized_state = True
|
|
@@ -444,8 +472,16 @@ class DAQ_Move(ParameterControlModule):
|
|
|
444
472
|
self.init_signal.emit(self._initialized_state)
|
|
445
473
|
|
|
446
474
|
elif status.command == "get_actuator_value" or status.command == 'check_position':
|
|
447
|
-
|
|
475
|
+
if isinstance(status.attribute, DataActuator):
|
|
476
|
+
data_act: DataActuator = status.attribute
|
|
477
|
+
else:
|
|
478
|
+
data_act: DataActuator = status.attribute[0] # backcompatibility
|
|
448
479
|
data_act.name = self.title # for the DataActuator name to be the title of the DAQ_Move
|
|
480
|
+
if (not Unit(self.units).is_compatible_with(Unit(data_act.units)) and
|
|
481
|
+
data_act.units == ''): #this happens if the units have not been specified in
|
|
482
|
+
# the plugin
|
|
483
|
+
data_act.force_units(self.units)
|
|
484
|
+
|
|
449
485
|
if self.ui is not None:
|
|
450
486
|
self.ui.display_value(data_act)
|
|
451
487
|
if self.ui.is_action_checked('show_graph'):
|
|
@@ -454,12 +490,15 @@ class DAQ_Move(ParameterControlModule):
|
|
|
454
490
|
self._current_value = data_act
|
|
455
491
|
self.current_value_signal.emit(self._current_value)
|
|
456
492
|
if self.settings['main_settings', 'tcpip', 'tcp_connected'] and self._send_to_tcpip:
|
|
457
|
-
self._command_tcpip.emit(ThreadCommand('position_is',
|
|
493
|
+
self._command_tcpip.emit(ThreadCommand('position_is', data_act))
|
|
458
494
|
if self.settings['main_settings', 'leco', 'leco_connected'] and self._send_to_tcpip:
|
|
459
|
-
self._command_tcpip.emit(ThreadCommand(LECOMoveCommands.POSITION,
|
|
495
|
+
self._command_tcpip.emit(ThreadCommand(LECOMoveCommands.POSITION, data_act))
|
|
460
496
|
|
|
461
497
|
elif status.command == "move_done":
|
|
462
|
-
|
|
498
|
+
if isinstance(status.attribute, DataActuator):
|
|
499
|
+
data_act: DataActuator = status.attribute
|
|
500
|
+
else:
|
|
501
|
+
data_act: DataActuator = status.attribute[0] # deprecated
|
|
463
502
|
data_act.name = self.title # for the DataActuator name to be the title of the DAQ_Move
|
|
464
503
|
if self.ui is not None:
|
|
465
504
|
self.ui.display_value(data_act)
|
|
@@ -468,9 +507,9 @@ class DAQ_Move(ParameterControlModule):
|
|
|
468
507
|
self._move_done_bool = True
|
|
469
508
|
self.move_done_signal.emit(data_act)
|
|
470
509
|
if self.settings.child('main_settings', 'tcpip', 'tcp_connected').value() and self._send_to_tcpip:
|
|
471
|
-
self._command_tcpip.emit(ThreadCommand('move_done',
|
|
510
|
+
self._command_tcpip.emit(ThreadCommand('move_done', data_act))
|
|
472
511
|
if self.settings.child('main_settings', 'leco', 'leco_connected').value() and self._send_to_tcpip:
|
|
473
|
-
self._command_tcpip.emit(ThreadCommand(LECOMoveCommands.MOVE_DONE,
|
|
512
|
+
self._command_tcpip.emit(ThreadCommand(LECOMoveCommands.MOVE_DONE, data_act))
|
|
474
513
|
|
|
475
514
|
elif status.command == 'outofbounds':
|
|
476
515
|
self.bounds_signal.emit(True)
|
|
@@ -545,10 +584,15 @@ class DAQ_Move(ParameterControlModule):
|
|
|
545
584
|
self.update_plugin_config()
|
|
546
585
|
if self.ui is not None:
|
|
547
586
|
self.ui.actuator = act_type
|
|
548
|
-
|
|
587
|
+
self.update_settings()
|
|
549
588
|
else:
|
|
550
589
|
raise ActuatorError(f'{act_type} is an invalid actuator, should be within {ACTUATOR_TYPES}')
|
|
551
590
|
|
|
591
|
+
@property
|
|
592
|
+
def actuators(self) -> List[str]:
|
|
593
|
+
""" Get the list of possible actuators"""
|
|
594
|
+
return ACTUATOR_TYPES
|
|
595
|
+
|
|
552
596
|
def update_plugin_config(self):
|
|
553
597
|
parent_module = utils.find_dict_in_list_from_key_val(DAQ_Move_Actuators, 'name', self.actuator)
|
|
554
598
|
mod = import_module(parent_module['module'].__package__.split('.')[0])
|
|
@@ -564,7 +608,35 @@ class DAQ_Move(ParameterControlModule):
|
|
|
564
608
|
def units(self, unit: str):
|
|
565
609
|
self.settings.child('move_settings', 'units').setValue(unit)
|
|
566
610
|
if self.ui is not None and config('actuator', 'display_units'):
|
|
567
|
-
self.ui.set_unit_as_suffix(unit)
|
|
611
|
+
self.ui.set_unit_as_suffix(self.get_unit_to_display(unit))
|
|
612
|
+
|
|
613
|
+
@staticmethod
|
|
614
|
+
def get_unit_to_display(unit: str) -> str:
|
|
615
|
+
""" Get the unit to be displayed in the UI
|
|
616
|
+
|
|
617
|
+
If the controller units are in mm the displayed unit will be m
|
|
618
|
+
because m is the base unit, then the user could ask for mm, km, µm...
|
|
619
|
+
only issue is when the usual displayed unit is not the base one, then add cases below
|
|
620
|
+
|
|
621
|
+
Parameters
|
|
622
|
+
----------
|
|
623
|
+
unit: str
|
|
624
|
+
|
|
625
|
+
Returns
|
|
626
|
+
-------
|
|
627
|
+
str: the unit to be displayed on the ui
|
|
628
|
+
"""
|
|
629
|
+
if ('°' in unit or 'degree' in unit) and not '°C' in unit:
|
|
630
|
+
# special cas as pint base unit for angles are radians
|
|
631
|
+
return '°'
|
|
632
|
+
elif 'W' in unit or 'watt' in unit.lower():
|
|
633
|
+
return 'W'
|
|
634
|
+
elif '°C' in unit or 'Celsius' in unit:
|
|
635
|
+
return '°C'
|
|
636
|
+
elif 'V' in unit or 'volt' in unit.lower():
|
|
637
|
+
return 'V'
|
|
638
|
+
else:
|
|
639
|
+
return str(Q_(1, unit).to_base_units().units)
|
|
568
640
|
|
|
569
641
|
def update_settings(self):
|
|
570
642
|
|
|
@@ -641,8 +713,6 @@ class DAQ_Move_Hardware(QObject):
|
|
|
641
713
|
self._title = title
|
|
642
714
|
self.hardware: Optional[DAQ_Move_base] = None
|
|
643
715
|
self.actuator_type = actuator_type
|
|
644
|
-
self.current_position: DataActuator = position
|
|
645
|
-
self._target_value: Optional[DataActuator] = None
|
|
646
716
|
self.hardware_adress = None
|
|
647
717
|
self.axis_address = None
|
|
648
718
|
self.motion_stoped = False
|
|
@@ -656,17 +726,18 @@ class DAQ_Move_Hardware(QObject):
|
|
|
656
726
|
Uninitialize the stage closing the hardware.
|
|
657
727
|
|
|
658
728
|
"""
|
|
659
|
-
self.hardware.
|
|
729
|
+
if self.hardware is not None and self.hardware.controller is not None:
|
|
730
|
+
self.hardware.close()
|
|
660
731
|
|
|
661
732
|
return "Stage uninitialized"
|
|
662
733
|
|
|
663
734
|
def get_actuator_value(self):
|
|
664
735
|
"""Get the current position checking the hardware value.
|
|
665
736
|
"""
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
737
|
+
if self.hardware is not None:
|
|
738
|
+
pos = self.hardware.get_actuator_value()
|
|
739
|
+
if self.hardware.data_actuator_type == DataActuatorType.float:
|
|
740
|
+
pos = DataActuator(self._title, data=pos, units=self.hardware.axis_unit)
|
|
670
741
|
return pos
|
|
671
742
|
|
|
672
743
|
def check_position(self):
|
|
@@ -716,6 +787,8 @@ class DAQ_Move_Hardware(QObject):
|
|
|
716
787
|
status.initialized = infos[1]
|
|
717
788
|
status.controller = self.hardware.controller
|
|
718
789
|
self.hardware.move_done_signal.connect(self.move_done)
|
|
790
|
+
if status.initialized:
|
|
791
|
+
self.status_sig.emit(ThreadCommand('get_actuator_value', [self.get_actuator_value()]))
|
|
719
792
|
|
|
720
793
|
return status
|
|
721
794
|
except Exception as e:
|
|
@@ -726,15 +799,13 @@ class DAQ_Move_Hardware(QObject):
|
|
|
726
799
|
"""
|
|
727
800
|
|
|
728
801
|
"""
|
|
729
|
-
|
|
730
|
-
# position = float(position) # because it may be a numpy float and could cause issues
|
|
731
|
-
# # see https://github.com/pythonnet/pythonnet/issues/1833
|
|
732
|
-
self._target_value = position
|
|
802
|
+
position = check_units(position, self.hardware.axis_unit)
|
|
733
803
|
self.hardware.move_is_done = False
|
|
734
804
|
self.hardware.ispolling = polling
|
|
735
805
|
if self.hardware.data_actuator_type.name == 'float':
|
|
736
806
|
self.hardware.move_abs(position.value())
|
|
737
807
|
else:
|
|
808
|
+
position.units = self.hardware.axis_unit # convert to plugin controller current axis units
|
|
738
809
|
self.hardware.move_abs(position)
|
|
739
810
|
self.hardware.poll_moving()
|
|
740
811
|
|
|
@@ -742,14 +813,14 @@ class DAQ_Move_Hardware(QObject):
|
|
|
742
813
|
"""
|
|
743
814
|
|
|
744
815
|
"""
|
|
745
|
-
|
|
816
|
+
rel_position = check_units(rel_position, self.hardware.axis_unit)
|
|
746
817
|
self.hardware.move_is_done = False
|
|
747
|
-
self._target_value = self.current_position + rel_position
|
|
748
818
|
self.hardware.ispolling = polling
|
|
749
819
|
|
|
750
820
|
if self.hardware.data_actuator_type.name == 'float':
|
|
751
821
|
self.hardware.move_rel(rel_position.value())
|
|
752
822
|
else:
|
|
823
|
+
rel_position.units = self.hardware.axis_unit # convert to plugin current axis units
|
|
753
824
|
self.hardware.move_rel(rel_position)
|
|
754
825
|
|
|
755
826
|
self.hardware.poll_moving()
|
|
@@ -763,7 +834,7 @@ class DAQ_Move_Hardware(QObject):
|
|
|
763
834
|
--------
|
|
764
835
|
DAQ_utils.ThreadCommand
|
|
765
836
|
"""
|
|
766
|
-
self.status_sig.emit(ThreadCommand("move_done",
|
|
837
|
+
self.status_sig.emit(ThreadCommand("move_done", pos))
|
|
767
838
|
|
|
768
839
|
def move_home(self):
|
|
769
840
|
"""
|
|
@@ -771,7 +842,6 @@ class DAQ_Move_Hardware(QObject):
|
|
|
771
842
|
|
|
772
843
|
"""
|
|
773
844
|
self.hardware.move_is_done = False
|
|
774
|
-
self._target_value = 0
|
|
775
845
|
self.hardware.move_home()
|
|
776
846
|
|
|
777
847
|
@Slot(DataActuator)
|
|
@@ -779,7 +849,7 @@ class DAQ_Move_Hardware(QObject):
|
|
|
779
849
|
"""Send the move_done signal back to the main class
|
|
780
850
|
"""
|
|
781
851
|
self._current_value = pos
|
|
782
|
-
self.status_sig.emit(ThreadCommand(command="move_done", attribute=
|
|
852
|
+
self.status_sig.emit(ThreadCommand(command="move_done", attribute=pos))
|
|
783
853
|
|
|
784
854
|
@Slot(ThreadCommand)
|
|
785
855
|
def queue_command(self, command: ThreadCommand):
|
|
@@ -807,10 +877,10 @@ class DAQ_Move_Hardware(QObject):
|
|
|
807
877
|
* **reset_stop_motion** command, set the motion_stopped attribute to false
|
|
808
878
|
"""
|
|
809
879
|
try:
|
|
880
|
+
logger.debug(f'Threadcommand {command.command} sent to {self.title}')
|
|
810
881
|
if command.command == "ini_stage":
|
|
811
|
-
status = self.ini_stage(
|
|
812
|
-
|
|
813
|
-
self.status_sig.emit(ThreadCommand(command=command.command, attribute=[status, 'log']))
|
|
882
|
+
status: edict = self.ini_stage(*command.attribute)
|
|
883
|
+
self.status_sig.emit(ThreadCommand(command=command.command, attribute=status))
|
|
814
884
|
|
|
815
885
|
elif command.command == "close":
|
|
816
886
|
status = self.close()
|
|
@@ -838,11 +908,13 @@ class DAQ_Move_Hardware(QObject):
|
|
|
838
908
|
else: # custom commands for particular plugins (see spectrometer module 'get_spectro_wl' for instance)
|
|
839
909
|
if hasattr(self.hardware, command.command):
|
|
840
910
|
cmd = getattr(self.hardware, command.command)
|
|
841
|
-
|
|
911
|
+
if isinstance(command.attribute, list):
|
|
912
|
+
cmd(*command.attribute)
|
|
913
|
+
elif isinstance(command.attribute, dict):
|
|
914
|
+
cmd(**command.attribute)
|
|
842
915
|
except Exception as e:
|
|
843
916
|
self.logger.exception(str(e))
|
|
844
917
|
|
|
845
|
-
|
|
846
918
|
def stop_motion(self):
|
|
847
919
|
"""
|
|
848
920
|
stop hardware motion with motion_stopped attribute updtaed to True and a status signal sended with an "update_status" Thread Command
|
|
@@ -853,7 +925,8 @@ class DAQ_Move_Hardware(QObject):
|
|
|
853
925
|
"""
|
|
854
926
|
self.status_sig.emit(ThreadCommand(command="Update_Status", attribute=["Motion stoping", 'log']))
|
|
855
927
|
self.motion_stoped = True
|
|
856
|
-
self.hardware.
|
|
928
|
+
if self.hardware is not None and self.hardware.controller is not None:
|
|
929
|
+
self.hardware.stop_motion()
|
|
857
930
|
self.hardware.poll_timer.stop()
|
|
858
931
|
|
|
859
932
|
@Slot(edict)
|
|
@@ -879,15 +952,13 @@ class DAQ_Move_Hardware(QObject):
|
|
|
879
952
|
setattr(self, path[-1], param.value())
|
|
880
953
|
|
|
881
954
|
elif path[0] == 'move_settings':
|
|
882
|
-
self.hardware
|
|
955
|
+
if self.hardware is not None:
|
|
956
|
+
self.hardware.update_settings(settings_parameter_dict)
|
|
883
957
|
|
|
884
958
|
|
|
885
959
|
def main(init_qt=True):
|
|
886
960
|
if init_qt: # used for the test suite
|
|
887
|
-
app =
|
|
888
|
-
if config('style', 'darkstyle'):
|
|
889
|
-
import qdarkstyle
|
|
890
|
-
app.setStyleSheet(qdarkstyle.load_stylesheet(qdarkstyle.DarkPalette))
|
|
961
|
+
app = mkQApp("PyMoDAQ Move")
|
|
891
962
|
|
|
892
963
|
widget = QtWidgets.QWidget()
|
|
893
964
|
prog = DAQ_Move(widget, title="test")
|