pymodaq 3.6.13__py3-none-any.whl → 4.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.

Files changed (233) hide show
  1. pymodaq/__init__.py +13 -6
  2. pymodaq/control_modules/__init__.py +0 -7
  3. pymodaq/control_modules/daq_move.py +965 -2
  4. pymodaq/control_modules/daq_move_ui.py +319 -0
  5. pymodaq/control_modules/daq_viewer.py +1573 -3
  6. pymodaq/control_modules/daq_viewer_ui.py +393 -0
  7. pymodaq/control_modules/mocks.py +51 -0
  8. pymodaq/control_modules/move_utility_classes.py +709 -8
  9. pymodaq/control_modules/utils.py +256 -0
  10. pymodaq/control_modules/viewer_utility_classes.py +663 -6
  11. pymodaq/daq_utils.py +89 -0
  12. pymodaq/dashboard.py +91 -72
  13. pymodaq/examples/custom_app.py +12 -11
  14. pymodaq/examples/custom_viewer.py +10 -10
  15. pymodaq/examples/function_plotter.py +16 -13
  16. pymodaq/examples/nonlinearscanner.py +8 -6
  17. pymodaq/examples/parameter_ex.py +7 -7
  18. pymodaq/examples/preset_MockCamera.xml +1 -0
  19. pymodaq/extensions/__init__.py +16 -0
  20. pymodaq/extensions/console.py +76 -0
  21. pymodaq/{daq_logger.py → extensions/daq_logger.py} +115 -65
  22. pymodaq/extensions/daq_scan.py +1339 -0
  23. pymodaq/extensions/daq_scan_ui.py +240 -0
  24. pymodaq/extensions/h5browser.py +23 -0
  25. pymodaq/{pid → extensions/pid}/__init__.py +4 -2
  26. pymodaq/{pid → extensions/pid}/daq_move_PID.py +2 -2
  27. pymodaq/{pid → extensions/pid}/pid_controller.py +48 -36
  28. pymodaq/{pid → extensions/pid}/utils.py +52 -6
  29. pymodaq/extensions/utils.py +40 -0
  30. pymodaq/post_treatment/__init__.py +6 -0
  31. pymodaq/{daq_analysis → post_treatment/daq_analysis}/daq_analysis_main.py +17 -17
  32. pymodaq/{daq_measurement → post_treatment/daq_measurement}/daq_measurement_main.py +8 -14
  33. pymodaq/post_treatment/load_and_plot.py +219 -0
  34. pymodaq/post_treatment/process_to_scalar.py +263 -0
  35. pymodaq/resources/QtDesigner_Ressources/Icon_Library/run_all.png +0 -0
  36. pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop_all.png +0 -0
  37. pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.bat +1 -1
  38. pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.qrc +1 -0
  39. pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources_rc.py +109784 -109173
  40. pymodaq/resources/QtDesigner_Ressources/icons.svg +142 -0
  41. pymodaq/resources/VERSION +1 -1
  42. pymodaq/resources/config_template.toml +32 -13
  43. pymodaq/resources/preset_default.xml +1 -1
  44. pymodaq/{daq_utils → utils}/Tuto innosetup/script_full_setup.iss +1 -1
  45. pymodaq/utils/__init__.py +0 -29
  46. pymodaq/utils/abstract/__init__.py +48 -0
  47. pymodaq/{daq_utils → utils}/abstract/logger.py +7 -3
  48. pymodaq/utils/array_manipulation.py +379 -8
  49. pymodaq/{daq_utils → utils}/calibration_camera.py +6 -6
  50. pymodaq/{daq_utils → utils}/chrono_timer.py +1 -1
  51. pymodaq/utils/config.py +448 -0
  52. pymodaq/utils/conftests.py +5 -0
  53. pymodaq/utils/daq_utils.py +828 -8
  54. pymodaq/utils/data.py +1873 -7
  55. pymodaq/{daq_utils → utils}/db/db_logger/db_logger.py +86 -47
  56. pymodaq/{daq_utils → utils}/db/db_logger/db_logger_models.py +31 -10
  57. pymodaq/{daq_utils → utils}/enums.py +12 -7
  58. pymodaq/utils/exceptions.py +37 -0
  59. pymodaq/utils/factory.py +82 -0
  60. pymodaq/{daq_utils → utils}/gui_utils/__init__.py +1 -1
  61. pymodaq/utils/gui_utils/custom_app.py +129 -0
  62. pymodaq/utils/gui_utils/file_io.py +66 -0
  63. pymodaq/{daq_utils → utils}/gui_utils/layout.py +2 -2
  64. pymodaq/{daq_utils → utils}/gui_utils/utils.py +13 -3
  65. pymodaq/{daq_utils → utils}/gui_utils/widgets/__init__.py +2 -2
  66. pymodaq/utils/gui_utils/widgets/label.py +24 -0
  67. pymodaq/{daq_utils → utils}/gui_utils/widgets/lcd.py +12 -7
  68. pymodaq/{daq_utils → utils}/gui_utils/widgets/push.py +66 -2
  69. pymodaq/{daq_utils → utils}/gui_utils/widgets/qled.py +6 -4
  70. pymodaq/utils/gui_utils/widgets/spinbox.py +24 -0
  71. pymodaq/{daq_utils → utils}/gui_utils/widgets/table.py +2 -2
  72. pymodaq/utils/h5modules/__init__.py +1 -0
  73. pymodaq/{daq_utils/h5backend.py → utils/h5modules/backends.py} +200 -112
  74. pymodaq/utils/h5modules/browsing.py +683 -0
  75. pymodaq/utils/h5modules/data_saving.py +839 -0
  76. pymodaq/utils/h5modules/h5logging.py +110 -0
  77. pymodaq/utils/h5modules/module_saving.py +350 -0
  78. pymodaq/utils/h5modules/saving.py +914 -0
  79. pymodaq/utils/h5modules/utils.py +85 -0
  80. pymodaq/utils/logger.py +64 -6
  81. pymodaq/utils/managers/action_manager.py +460 -0
  82. pymodaq/{daq_utils → utils}/managers/batchscan_manager.py +144 -112
  83. pymodaq/{daq_utils → utils}/managers/modules_manager.py +188 -114
  84. pymodaq/{daq_utils → utils}/managers/overshoot_manager.py +3 -3
  85. pymodaq/utils/managers/parameter_manager.py +110 -0
  86. pymodaq/{daq_utils → utils}/managers/preset_manager.py +17 -13
  87. pymodaq/{daq_utils → utils}/managers/preset_manager_utils.py +8 -7
  88. pymodaq/{daq_utils → utils}/managers/remote_manager.py +7 -6
  89. pymodaq/{daq_utils → utils}/managers/roi_manager.py +148 -57
  90. pymodaq/utils/math_utils.py +546 -10
  91. pymodaq/{daq_utils → utils}/messenger.py +5 -1
  92. pymodaq/utils/parameter/__init__.py +2 -15
  93. pymodaq/{daq_utils → utils}/parameter/ioxml.py +12 -6
  94. pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/__init__.py +1 -3
  95. pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/filedir.py +1 -1
  96. pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/itemselect.py +3 -0
  97. pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/led.py +1 -1
  98. pymodaq/utils/parameter/pymodaq_ptypes/pixmap.py +161 -0
  99. pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/slide.py +1 -1
  100. pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/table.py +1 -1
  101. pymodaq/utils/parameter/utils.py +206 -11
  102. pymodaq/utils/plotting/data_viewers/__init__.py +6 -0
  103. pymodaq/utils/plotting/data_viewers/viewer.py +393 -0
  104. pymodaq/utils/plotting/data_viewers/viewer0D.py +251 -0
  105. pymodaq/utils/plotting/data_viewers/viewer1D.py +574 -0
  106. pymodaq/{daq_utils → utils}/plotting/data_viewers/viewer1Dbasic.py +8 -3
  107. pymodaq/{daq_utils → utils}/plotting/data_viewers/viewer2D.py +292 -357
  108. pymodaq/{daq_utils → utils}/plotting/data_viewers/viewer2D_basic.py +58 -75
  109. pymodaq/utils/plotting/data_viewers/viewerND.py +738 -0
  110. pymodaq/{daq_utils → utils}/plotting/gant_chart.py +2 -2
  111. pymodaq/{daq_utils → utils}/plotting/items/axis_scaled.py +4 -2
  112. pymodaq/{daq_utils → utils}/plotting/items/image.py +8 -6
  113. pymodaq/utils/plotting/navigator.py +355 -0
  114. pymodaq/utils/plotting/scan_selector.py +480 -0
  115. pymodaq/utils/plotting/utils/axes_viewer.py +88 -0
  116. pymodaq/utils/plotting/utils/filter.py +538 -0
  117. pymodaq/utils/plotting/utils/lineout.py +224 -0
  118. pymodaq/{daq_utils → utils}/plotting/utils/plot_utils.py +196 -84
  119. pymodaq/{daq_utils → utils}/plotting/utils/signalND.py +21 -13
  120. pymodaq/utils/plotting/widgets.py +76 -0
  121. pymodaq/utils/scanner/__init__.py +10 -0
  122. pymodaq/utils/scanner/scan_factory.py +204 -0
  123. pymodaq/utils/scanner/scanner.py +271 -0
  124. pymodaq/utils/scanner/scanners/_1d_scanners.py +117 -0
  125. pymodaq/utils/scanner/scanners/_2d_scanners.py +293 -0
  126. pymodaq/utils/scanner/scanners/sequential.py +192 -0
  127. pymodaq/utils/scanner/scanners/tabular.py +294 -0
  128. pymodaq/utils/scanner/utils.py +83 -0
  129. pymodaq/utils/slicing.py +47 -0
  130. pymodaq/utils/svg/__init__.py +6 -0
  131. pymodaq/utils/svg/svg_renderer.py +20 -0
  132. pymodaq/utils/svg/svg_view.py +35 -0
  133. pymodaq/utils/svg/svg_viewer2D.py +51 -0
  134. pymodaq/{daq_utils → utils}/tcp_server_client.py +36 -37
  135. pymodaq/{daq_utils → utils}/tree_layout/tree_layout_main.py +50 -35
  136. pymodaq/utils/units.py +216 -0
  137. pymodaq-4.0.1.dist-info/METADATA +159 -0
  138. {pymodaq-3.6.13.dist-info → pymodaq-4.0.1.dist-info}/RECORD +167 -170
  139. {pymodaq-3.6.13.dist-info → pymodaq-4.0.1.dist-info}/WHEEL +1 -2
  140. pymodaq-4.0.1.dist-info/entry_points.txt +8 -0
  141. pymodaq/daq_move/daq_move_gui.py +0 -279
  142. pymodaq/daq_move/daq_move_gui.ui +0 -534
  143. pymodaq/daq_move/daq_move_main.py +0 -1042
  144. pymodaq/daq_move/process_from_QtDesigner_DAQ_Move_GUI.bat +0 -2
  145. pymodaq/daq_move/utility_classes.py +0 -686
  146. pymodaq/daq_scan.py +0 -2160
  147. pymodaq/daq_utils/array_manipulation.py +0 -386
  148. pymodaq/daq_utils/config.py +0 -273
  149. pymodaq/daq_utils/conftests.py +0 -7
  150. pymodaq/daq_utils/custom_parameter_tree.py +0 -9
  151. pymodaq/daq_utils/daq_enums.py +0 -133
  152. pymodaq/daq_utils/daq_utils.py +0 -1402
  153. pymodaq/daq_utils/exceptions.py +0 -71
  154. pymodaq/daq_utils/gui_utils/custom_app.py +0 -103
  155. pymodaq/daq_utils/gui_utils/file_io.py +0 -75
  156. pymodaq/daq_utils/gui_utils/widgets/spinbox.py +0 -9
  157. pymodaq/daq_utils/h5exporter_hyperspy.py +0 -115
  158. pymodaq/daq_utils/h5exporters.py +0 -242
  159. pymodaq/daq_utils/h5modules.py +0 -1559
  160. pymodaq/daq_utils/h5utils.py +0 -241
  161. pymodaq/daq_utils/managers/action_manager.py +0 -236
  162. pymodaq/daq_utils/managers/parameter_manager.py +0 -57
  163. pymodaq/daq_utils/math_utils.py +0 -705
  164. pymodaq/daq_utils/parameter/__init__.py +0 -1
  165. pymodaq/daq_utils/parameter/oldpymodaq_ptypes.py +0 -1626
  166. pymodaq/daq_utils/parameter/pymodaq_ptypes/pixmap.py +0 -85
  167. pymodaq/daq_utils/parameter/utils.py +0 -136
  168. pymodaq/daq_utils/plotting/data_viewers/__init__.py +0 -0
  169. pymodaq/daq_utils/plotting/data_viewers/process_from_QtDesigner_0DViewer_GUI.bat +0 -2
  170. pymodaq/daq_utils/plotting/data_viewers/viewer0D.py +0 -204
  171. pymodaq/daq_utils/plotting/data_viewers/viewer0D_GUI.py +0 -89
  172. pymodaq/daq_utils/plotting/data_viewers/viewer0D_GUI.ui +0 -131
  173. pymodaq/daq_utils/plotting/data_viewers/viewer1D.py +0 -781
  174. pymodaq/daq_utils/plotting/data_viewers/viewerND.py +0 -894
  175. pymodaq/daq_utils/plotting/data_viewers/viewerbase.py +0 -64
  176. pymodaq/daq_utils/plotting/items/__init__.py +0 -0
  177. pymodaq/daq_utils/plotting/navigator.py +0 -500
  178. pymodaq/daq_utils/plotting/scan_selector.py +0 -289
  179. pymodaq/daq_utils/plotting/utils/__init__.py +0 -0
  180. pymodaq/daq_utils/plotting/utils/filter.py +0 -236
  181. pymodaq/daq_utils/plotting/viewer0D/__init__.py +0 -0
  182. pymodaq/daq_utils/plotting/viewer0D/viewer0D_main.py +0 -4
  183. pymodaq/daq_utils/plotting/viewer1D/__init__.py +0 -0
  184. pymodaq/daq_utils/plotting/viewer1D/viewer1D_main.py +0 -4
  185. pymodaq/daq_utils/plotting/viewer1D/viewer1Dbasic.py +0 -4
  186. pymodaq/daq_utils/plotting/viewer2D/viewer_2D_basic.py +0 -4
  187. pymodaq/daq_utils/plotting/viewer2D/viewer_2D_main.py +0 -4
  188. pymodaq/daq_utils/plotting/viewerND/__init__.py +0 -0
  189. pymodaq/daq_utils/plotting/viewerND/viewerND_main.py +0 -4
  190. pymodaq/daq_utils/scanner.py +0 -1289
  191. pymodaq/daq_utils/tree_layout/__init__.py +0 -0
  192. pymodaq/daq_viewer/__init__.py +0 -0
  193. pymodaq/daq_viewer/daq_gui_settings.py +0 -237
  194. pymodaq/daq_viewer/daq_gui_settings.ui +0 -441
  195. pymodaq/daq_viewer/daq_viewer_main.py +0 -2225
  196. pymodaq/daq_viewer/process_from_QtDesigner_DAQ_GUI_settings.bat +0 -2
  197. pymodaq/daq_viewer/utility_classes.py +0 -673
  198. pymodaq/examples/logger_image/__init__.py +0 -0
  199. pymodaq/examples/logger_image/logger_displayer.py +0 -121
  200. pymodaq/examples/logger_image/setup.svg +0 -3119
  201. pymodaq/examples/logger_image/setup_svg.py +0 -114
  202. pymodaq/h5browser.py +0 -39
  203. pymodaq/utils/scanner.py +0 -15
  204. pymodaq-3.6.13.dist-info/METADATA +0 -39
  205. pymodaq-3.6.13.dist-info/entry_points.txt +0 -8
  206. pymodaq-3.6.13.dist-info/top_level.txt +0 -1
  207. /pymodaq/{daq_analysis → post_treatment/daq_analysis}/__init__.py +0 -0
  208. /pymodaq/{daq_measurement → post_treatment/daq_measurement}/__init__.py +0 -0
  209. /pymodaq/{daq_measurement → post_treatment/daq_measurement}/daq_measurement_GUI.py +0 -0
  210. /pymodaq/{daq_measurement → post_treatment/daq_measurement}/daq_measurement_GUI.ui +0 -0
  211. /pymodaq/{daq_measurement → post_treatment/daq_measurement}/process_from_QtDesigner_DAQ_Measurement_GUI.bat +0 -0
  212. /pymodaq/{daq_utils → utils}/Tuto innosetup/Tuto innosetup.odt +0 -0
  213. /pymodaq/{daq_utils → utils}/Tuto innosetup/Tuto innosetup.pdf +0 -0
  214. /pymodaq/{daq_move → utils/db}/__init__.py +0 -0
  215. /pymodaq/{daq_utils → utils/db/db_logger}/__init__.py +0 -0
  216. /pymodaq/{daq_utils → utils}/gui_utils/dock.py +0 -0
  217. /pymodaq/{daq_utils → utils}/gui_utils/list_picker.py +0 -0
  218. /pymodaq/{daq_utils/abstract → utils/managers}/__init__.py +0 -0
  219. /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/bool.py +0 -0
  220. /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/date.py +0 -0
  221. /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/list.py +0 -0
  222. /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/numeric.py +0 -0
  223. /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/tableview.py +0 -0
  224. /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/text.py +0 -0
  225. /pymodaq/{daq_utils/db → utils/plotting}/__init__.py +0 -0
  226. /pymodaq/{daq_utils → utils}/plotting/image_viewer.py +0 -0
  227. /pymodaq/{daq_utils/db/db_logger → utils/plotting/items}/__init__.py +0 -0
  228. /pymodaq/{daq_utils → utils}/plotting/items/crosshair.py +0 -0
  229. /pymodaq/{daq_utils/managers → utils/plotting/utils}/__init__.py +0 -0
  230. /pymodaq/{daq_utils → utils}/qvariant.py +0 -0
  231. /pymodaq/{daq_utils/plotting/viewer2D → utils/scanner/scanners}/__init__.py +0 -0
  232. /pymodaq/{daq_utils/plotting → utils/tree_layout}/__init__.py +0 -0
  233. {pymodaq-3.6.13.dist-info → pymodaq-4.0.1.dist-info/licenses}/LICENSE +0 -0
@@ -1,7 +1,970 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
- Created the 21/10/2022
3
+ Created the 29/07/2022
4
4
 
5
5
  @author: Sebastien Weber
6
6
  """
7
- from pymodaq.daq_move.daq_move_main import DAQ_Move
7
+ import sys
8
+
9
+ from qtpy.QtCore import QObject, Signal, QThread, Slot, Qt, QTimer
10
+ from qtpy import QtWidgets
11
+
12
+ from easydict import EasyDict as edict
13
+
14
+ from pymodaq.utils.logger import set_logger, get_module_name, get_module_name
15
+ from pymodaq.control_modules.utils import ControlModule
16
+ from pymodaq.utils.parameter import ioxml
17
+ from pymodaq.control_modules.daq_move_ui import DAQ_Move_UI, ThreadCommand
18
+ from pymodaq.utils.managers.parameter_manager import ParameterManager, Parameter
19
+ from pymodaq.control_modules.move_utility_classes import MoveCommand
20
+ from pymodaq.utils.tcp_server_client import TCPClient
21
+ from pymodaq.control_modules.move_utility_classes import params as daq_move_params
22
+ from pymodaq.utils import daq_utils as utils
23
+ from pymodaq.utils.parameter import utils as putils
24
+ from pymodaq.utils.gui_utils import get_splash_sc
25
+ from pymodaq.utils import config
26
+ from pymodaq.utils.exceptions import ActuatorError
27
+ from pymodaq.utils.messenger import deprecation_msg
28
+ from pymodaq.utils.h5modules import module_saving
29
+
30
+
31
+ local_path = config.get_set_local_dir()
32
+ sys.path.append(local_path)
33
+ logger = set_logger(get_module_name(__file__))
34
+ DAQ_Move_Actuators = utils.get_plugins('daq_move')
35
+ ACTUATOR_TYPES = [mov['name'] for mov in DAQ_Move_Actuators]
36
+
37
+ STATUS_WAIT_TIME = 1000
38
+
39
+
40
+ class DAQ_Move(ParameterManager, ControlModule):
41
+ """ Main PyMoDAQ class to drive actuators
42
+
43
+ Qt object and generic UI to drive actuators.
44
+
45
+ Attributes
46
+ ----------
47
+ init_signal: Signal[bool]
48
+ This signal is emitted when the chosen actuator is correctly initialized
49
+ move_done_signal: Signal[str, float]
50
+ This signal is emitted when the chosen actuator finished its action. It gives the actuator's name and current
51
+ value
52
+ bounds_signal: Signal[bool]
53
+ This signal is emitted when the actuator reached defined limited boundaries.
54
+
55
+ See Also
56
+ --------
57
+ :class:`ControlModule`, :class:`ParameterManager`
58
+ """
59
+ settings_name = 'daq_move_settings'
60
+
61
+ move_done_signal = Signal(str, float)
62
+ _current_value_signal = Signal(str, float)
63
+ # to be used in external program to make sure the move has been done,
64
+ # export the current position. str refer to the unique title given to the module
65
+ _update_settings_signal = Signal(edict)
66
+ bounds_signal = Signal(bool)
67
+
68
+
69
+ params = daq_move_params
70
+
71
+ def __init__(self, parent=None, title="DAQ Move"):
72
+ """
73
+
74
+ Parameters
75
+ ----------
76
+ parent: QWidget or None
77
+ parent: QWidget or None
78
+ if it is a valid QWidget, it will hold the user interface to drive it
79
+ title: str
80
+ The unique (should be unique) string identifier for the underlying actuator
81
+ """
82
+
83
+ self.logger = set_logger(f'{logger.name}.{title}')
84
+ self.logger.info(f'Initializing DAQ_Move: {title}')
85
+
86
+ QObject.__init__(self)
87
+ ParameterManager.__init__(self)
88
+ ControlModule.__init__(self)
89
+
90
+ self.parent = parent
91
+ if parent is not None:
92
+ self.ui = DAQ_Move_UI(parent, title)
93
+ else:
94
+ self.ui = None
95
+
96
+ if self.ui is not None:
97
+ self.ui.actuators = ACTUATOR_TYPES
98
+ self.ui.set_settings_tree(self.settings_tree)
99
+ self.ui.command_sig.connect(self.process_ui_cmds)
100
+
101
+ self.splash_sc = get_splash_sc()
102
+ self._title = title
103
+ if len(ACTUATOR_TYPES) > 0: # will be 0 if no valid plugins are installed
104
+ self.actuator = ACTUATOR_TYPES[0]
105
+
106
+ self.module_and_data_saver = module_saving.ActuatorSaver(self)
107
+
108
+ self._move_done_bool = True
109
+
110
+ self._current_value = 0.
111
+ self._target_value = 0.
112
+ self._relative_value = 0.
113
+
114
+ self._refresh_timer = QTimer()
115
+ self._refresh_timer.timeout.connect(self.get_actuator_value)
116
+
117
+ def process_ui_cmds(self, cmd: utils.ThreadCommand):
118
+ """Process commands sent by actions done in the ui
119
+
120
+ Parameters
121
+ ----------
122
+ cmd: ThreadCommand
123
+ Possible values are :
124
+ * init
125
+ * quit
126
+ * get_value
127
+ * loop_get_value
128
+ * find_home
129
+ * stop
130
+ * move_abs
131
+ * move_rel
132
+ * show_log
133
+ * actuator_changed
134
+ * rel_value
135
+ """
136
+ if cmd.command == 'init':
137
+ self.init_hardware(cmd.attribute[0])
138
+ elif cmd.command == 'quit':
139
+ self.quit_fun()
140
+ elif cmd.command == 'get_value':
141
+ self.get_actuator_value()
142
+ elif cmd.command == 'loop_get_value':
143
+ self.get_continuous_actuator_value(cmd.attribute)
144
+ elif cmd.command == 'find_home':
145
+ self.move_home()
146
+ elif cmd.command == 'stop':
147
+ self.stop_motion()
148
+ elif cmd.command == 'move_abs':
149
+ self.move_abs(cmd.attribute)
150
+ elif cmd.command == 'move_rel':
151
+ self.move_rel(cmd.attribute)
152
+ elif cmd.command == 'show_log':
153
+ self.show_log()
154
+ elif cmd.command == 'actuator_changed':
155
+ self.actuator = cmd.attribute
156
+ elif cmd.command == 'rel_value':
157
+ self._relative_value = cmd.attribute
158
+
159
+
160
+ def stop_motion(self):
161
+ """Stop any motion
162
+ """
163
+ try:
164
+ self.command_hardware.emit(ThreadCommand(command="stop_motion"))
165
+ except Exception as e:
166
+ self.logger.exception(str(e))
167
+
168
+ def move(self, move_command: MoveCommand):
169
+ """Generic method to trigger the correct action on the actuator
170
+
171
+ Parameters
172
+ ----------
173
+ move_command: MoveCommand
174
+ MoveCommand with move_type attribute either:
175
+ * 'abs': performs an absolute action
176
+ * 'rel': performs a relative action
177
+ * 'home': find the actuator's home
178
+
179
+ See Also
180
+ --------
181
+ :meth:`move_abs`, :meth:`move_rel`, :meth:`move_home`, :class:`..utility_classes.MoveCommand`
182
+
183
+ """
184
+ if move_command.move_type == 'abs':
185
+ self.move_abs(move_command.value)
186
+ elif move_command.move_type == 'rel':
187
+ self.move_rel(move_command.value)
188
+ elif move_command.move_type == 'home':
189
+ self.move_home(move_command.value)
190
+
191
+ def move_Abs(self, value, send_to_tcpip=False):
192
+ deprecation_msg(f'The method *move_Abs* should not be used anymore, use *move_abs*')
193
+ self.move_abs(value, send_to_tcpip=send_to_tcpip)
194
+
195
+ def move_abs(self, value, send_to_tcpip=False):
196
+ """Move the connected hardware to the absolute value
197
+
198
+ Returns nothing but the move_done_signal will be send once the action is done
199
+
200
+ Parameters
201
+ ----------
202
+ value: float
203
+ The value the actuator should reach
204
+ send_to_tcpip: bool
205
+ if True, this position is send through the TCP/IP communication canal
206
+ """
207
+ try:
208
+ self._send_to_tcpip = send_to_tcpip
209
+ if not value == self._current_value:
210
+ if self.ui is not None:
211
+ self.ui.move_done = False
212
+ self._move_done_bool = False
213
+ self._target_value = value
214
+ self.update_status("Moving")
215
+ self.command_hardware.emit(ThreadCommand(command="reset_stop_motion"))
216
+ self.command_hardware.emit(ThreadCommand(command="move_abs", attribute=[value]))
217
+
218
+ except Exception as e:
219
+ self.logger.exception(str(e))
220
+
221
+ def move_Home(self, send_to_tcpip=False):
222
+ self.move_home(send_to_tcpip)
223
+ deprecation_msg(f'The method *move_Home* is deprecated, use *move_home*')
224
+
225
+ def move_home(self, send_to_tcpip=False):
226
+ """Move the connected actuator to its home value (if any)
227
+
228
+ Parameters
229
+ ----------
230
+ send_to_tcpip: bool
231
+ if True, this position is send through the TCP/IP communication canal
232
+ """
233
+ self._send_to_tcpip = send_to_tcpip
234
+ try:
235
+ if self.ui is not None:
236
+ self.ui.move_done = False
237
+ self._move_done_bool = False
238
+ self.update_status("Moving")
239
+ self.command_hardware.emit(ThreadCommand(command="reset_stop_motion"))
240
+ self.command_hardware.emit(ThreadCommand(command="move_Home"))
241
+
242
+ except Exception as e:
243
+ self.logger.exception(str(e))
244
+
245
+ def move_Rel(self, rel_value, send_to_tcpip=False):
246
+ deprecation_msg(f'The method *move_Rel* should not be used anymore, use *move_rel*')
247
+ self.move_rel(rel_value, send_to_tcpip=send_to_tcpip)
248
+
249
+ def move_rel(self, rel_value, send_to_tcpip=False):
250
+ """Move the connected hardware to the relative value
251
+
252
+ Returns nothing but the move_done_signal will be send once the action is done
253
+
254
+ Parameters
255
+ ----------
256
+ value: float
257
+ The relative value the actuator should reach
258
+ send_to_tcpip: bool
259
+ if True, this position is send through the TCP/IP communication canal
260
+ """
261
+
262
+ try:
263
+ self._send_to_tcpip = send_to_tcpip
264
+ if self.ui is not None:
265
+ self.ui.move_done = False
266
+ self._move_done_bool = False
267
+ self._target_value = self._current_value + rel_value
268
+ self.update_status("Moving")
269
+ self.command_hardware.emit(ThreadCommand(command="reset_stop_motion"))
270
+ self.command_hardware.emit(ThreadCommand(command="move_rel", attribute=[rel_value]))
271
+
272
+ except Exception as e:
273
+ self.logger.exception(str(e))
274
+
275
+ def move_Rel_p(self):
276
+ deprecation_msg(f'The method *move_Rel_p* should not be used anymore, use *move_rel_p*')
277
+ self.move_rel_p()
278
+
279
+ def move_Rel_m(self):
280
+ deprecation_msg(f'The method *move_Rel_m* should not be used anymore, use *move_rel_m*')
281
+ self.move_rel_m()
282
+
283
+ def move_rel_p(self):
284
+ self.move_rel(self._relative_value)
285
+
286
+ def move_rel_m(self):
287
+ self.move_rel(-self._relative_value)
288
+
289
+ def quit_fun(self):
290
+ """Programmatic quitting of the current instance of DAQ_Move
291
+
292
+ Des-init the actuator then close the UI parent widget
293
+ """
294
+ # insert anything that needs to be closed before leaving
295
+
296
+ if self._initialized_state:
297
+ self.init_hardware(False)
298
+ if self.ui is not None:
299
+ self.ui.get_action('quit').trigger()
300
+ self.quit_signal.emit()
301
+
302
+ def ini_stage_fun(self):
303
+ deprecation_msg(f'The function *ini_stage_fun* is deprecated, use init_hardware')
304
+ self.init_hardware(True)
305
+
306
+ def init_hardware_ui(self, do_init=True):
307
+ """Programmatic actuator's Initialization
308
+
309
+ Programmatic way to simulate a click on the init button of the UI to initialize the communication with the
310
+ hardware
311
+
312
+ Parameters
313
+ ----------
314
+ do_init: bool
315
+ if the init or des-init should be performed
316
+ """
317
+ self.ui.do_init(do_init)
318
+
319
+ def init_hardware(self, do_init=True):
320
+
321
+ if not do_init:
322
+ try:
323
+ self.command_hardware.emit(ThreadCommand(command="close"))
324
+ if self.ui is not None:
325
+ self.ui.actuator_init = False
326
+ except Exception as e:
327
+ self.logger.exception(str(e))
328
+ else:
329
+ try:
330
+ hardware = DAQ_Move_Hardware(self._actuator_type, self._current_value, self._title)
331
+ self._hardware_thread = QThread()
332
+ hardware.moveToThread(self._hardware_thread)
333
+
334
+ self.command_hardware[ThreadCommand].connect(hardware.queue_command)
335
+ hardware.status_sig[ThreadCommand].connect(self.thread_status)
336
+ self._update_settings_signal[edict].connect(hardware.update_settings)
337
+
338
+ self._hardware_thread.hardware = hardware
339
+ self._hardware_thread.start()
340
+ self.command_hardware.emit(
341
+ ThreadCommand(command="ini_stage", attribute=[self.settings.child(('move_settings')).saveState(),
342
+ self.controller]))
343
+ except Exception as e:
344
+ self.logger.exception(str(e))
345
+
346
+ @property
347
+ def initialized_state(self):
348
+ """bool: status of the actuator's initialization (init or not)"""
349
+ return self._initialized_state
350
+
351
+ @property
352
+ def move_done_bool(self):
353
+ """bool: status of the actuator's action (done or not)"""
354
+ return self._move_done_bool
355
+
356
+ def value_changed(self, param):
357
+ if param.name() == 'connect_server':
358
+ if param.value():
359
+ self.connect_tcp_ip()
360
+ else:
361
+ self._command_tcpip.emit(ThreadCommand('quit', ))
362
+
363
+ elif param.name() == 'ip_address' or param.name == 'port':
364
+ self._command_tcpip.emit(
365
+ ThreadCommand('update_connection', dict(ipaddress=self.settings.child('main_settings', 'tcpip',
366
+ 'ip_address').value(),
367
+ port=self.settings.child('main_settings', 'tcpip',
368
+ 'port').value())))
369
+ elif param.name() == 'refresh_timeout':
370
+ self._refresh_timer.setInterval(param.value())
371
+
372
+ path = self.settings.childPath(param)
373
+ if path is not None:
374
+ if 'main_settings' not in path:
375
+ self._update_settings_signal.emit(edict(path=path, param=param, change='value'))
376
+ if self.settings.child('main_settings', 'tcpip', 'tcp_connected').value():
377
+ self._command_tcpip.emit(ThreadCommand('send_info', dict(path=path, param=param)))
378
+
379
+ def param_deleted(self, param):
380
+ if param.name() not in putils.iter_children(self.settings.child('main_settings'), []):
381
+ self._update_settings_signal.emit(edict(path=['move_settings'], param=param, change='parent'))
382
+
383
+ def child_added(self, param, data):
384
+ path = self.settings.childPath(param)
385
+ if 'main_settings' not in path:
386
+ self._update_settings_signal.emit(edict(path=path, param=data[0].saveState(), change='childAdded'))
387
+
388
+ @Slot()
389
+ def raise_timeout(self):
390
+ """Update status with "Timeout occurred" statement and change the timeout flag.
391
+ """
392
+ self.update_status("Timeout occurred")
393
+ self.wait_position_flag = False
394
+
395
+ @Slot(ThreadCommand)
396
+ def thread_status(self, status): # general function to get datas/infos from all threads back to the main
397
+ """
398
+ | General function to get datas/infos from all threads back to the main0
399
+ |
400
+
401
+ Interpret a command from the command given by the ThreadCommand status :
402
+ * In case of **'Update_status'** command, call the update_status method with status attribute as parameters
403
+ * In case of **'ini_stage'** command, initialise a Stage from status attribute
404
+ * In case of **'close'** command, close the launched stage thread
405
+ * In case of **'check_position'** command, set the current_value value from status attribute
406
+ * In case of **'move_done'** command, set the current_value value, make profile of move_done and send the move done signal with status attribute
407
+ * In case of **'Move_Not_Done'** command, set the current position value from the status attribute, make profile of Not_move_done and send the Thread Command "move_abs"
408
+ * In case of **'update_settings'** command, create child "Move Settings" from status attribute (if possible)
409
+
410
+ ================ ================= ======================================================
411
+ **Parameters** **Type** **Description**
412
+
413
+ *status* ThreadCommand() instance of ThreadCommand containing two attribute :
414
+
415
+ * *command* str
416
+ * *attribute* list
417
+
418
+ ================ ================= ======================================================
419
+
420
+ See Also
421
+ --------
422
+ update_status, set_enabled_move_buttons, get_actuator_value, DAQ_utils.ThreadCommand, parameter_tree_changed, raise_timeout
423
+ """
424
+
425
+ if status.command == "Update_Status":
426
+ if len(status.attribute) > 2:
427
+ self.update_status(status.attribute[0], log=status.attribute[1])
428
+ else:
429
+ self.update_status(status.attribute[0])
430
+
431
+ elif status.command == "ini_stage":
432
+ # status.attribute[0]=edict(initialized=bool,info="", controller=)
433
+ self.update_status("Stage initialized: {:} info: {:}".format(status.attribute[0]['initialized'],
434
+ status.attribute[0]['info']))
435
+ if status.attribute[0]['initialized']:
436
+ self.controller = status.attribute[0]['controller']
437
+ if self.ui is not None:
438
+ self.ui.actuator_init = True
439
+ self._initialized_state = True
440
+ else:
441
+ self._initialized_state = False
442
+ if self._initialized_state:
443
+ self.get_actuator_value()
444
+ self.init_signal.emit(self._initialized_state)
445
+
446
+ elif status.command == "close":
447
+ try:
448
+ self.update_status(status.attribute[0])
449
+ self._hardware_thread.exit()
450
+ self._hardware_thread.wait()
451
+ finished = self._hardware_thread.isFinished()
452
+ if finished:
453
+ pass
454
+ delattr(self, 'hardware_thread')
455
+ else:
456
+ self.update_status('thread is locked?!', STATUS_WAIT_TIME, 'log')
457
+ except Exception as e:
458
+ self.logger.exception(str(e))
459
+ self._initialized_state = False
460
+ self.init_signal.emit(self._initialized_state)
461
+
462
+ elif status.command == "get_actuator_value" or status.command == 'check_position':
463
+ if self.ui is not None:
464
+ self.ui.display_value(status.attribute[0])
465
+ self._current_value = status.attribute[0]
466
+ self._current_value_signal.emit(self.title, self._current_value)
467
+ if self.settings.child('main_settings', 'tcpip', 'tcp_connected').value() and self._send_to_tcpip:
468
+ self._command_tcpip.emit(ThreadCommand('position_is', status.attribute))
469
+
470
+ elif status.command == "move_done":
471
+ if self.ui is not None:
472
+ self.ui.display_value(status.attribute[0])
473
+ self.ui.move_done = True
474
+ self._current_value = status.attribute[0]
475
+ self._move_done_bool = True
476
+ self.move_done_signal.emit(self._title, status.attribute[0])
477
+ if self.settings.child('main_settings', 'tcpip', 'tcp_connected').value() and self._send_to_tcpip:
478
+ self._command_tcpip.emit(ThreadCommand('move_done', status.attribute))
479
+
480
+ elif status.command == "Move_Not_Done":
481
+ if self.ui is not None:
482
+ self.ui.display_value(status.attribute[0])
483
+ self.ui.move_done = False
484
+
485
+ self._current_value = status.attribute[0]
486
+ self._move_done_bool = False
487
+ self.command_hardware.emit(ThreadCommand(command="move_abs", attribute=[self._target_value]))
488
+
489
+ elif status.command == 'update_main_settings':
490
+ # this is a way for the plugins to update main settings of the ui (solely values, limits and options)
491
+ try:
492
+ if status.attribute[2] == 'value':
493
+ self.settings.child('main_settings', *status.attribute[0]).setValue(status.attribute[1])
494
+ elif status.attribute[2] == 'limits':
495
+ self.settings.child('main_settings', *status.attribute[0]).setLimits(status.attribute[1])
496
+ elif status.attribute[2] == 'options':
497
+ self.settings.child('main_settings', *status.attribute[0]).setOpts(**status.attribute[1])
498
+ except Exception as e:
499
+ self.logger.exception(str(e))
500
+
501
+ elif status.command == 'update_settings':
502
+ # ThreadCommand(command='update_settings',attribute=[path,data,change]))
503
+ try:
504
+ self.settings.sigTreeStateChanged.disconnect(
505
+ self.parameter_tree_changed) # any changes on the settings will update accordingly the detector
506
+ except Exception:
507
+ pass
508
+ try:
509
+ if status.attribute[2] == 'value':
510
+ self.settings.child('move_settings', *status.attribute[0]).setValue(status.attribute[1])
511
+ elif status.attribute[2] == 'limits':
512
+ self.settings.child('move_settings', *status.attribute[0]).setLimits(status.attribute[1])
513
+ elif status.attribute[2] == 'options':
514
+ self.settings.child('move_settings', *status.attribute[0]).setOpts(**status.attribute[1])
515
+ elif status.attribute[2] == 'childAdded':
516
+ child = Parameter.create(name='tmp')
517
+ child.restoreState(status.attribute[1][0])
518
+ self.settings.child('move_settings', *status.attribute[0]).addChild(status.attribute[1][0])
519
+
520
+ except Exception as e:
521
+ self.logger.exception(str(e))
522
+ self.settings.sigTreeStateChanged.connect(
523
+ self.parameter_tree_changed) # any changes on the settings will update accordingly the detector
524
+
525
+ elif status.command == 'raise_timeout':
526
+ self.raise_timeout()
527
+
528
+ elif status.command == 'outofbounds':
529
+ self.bounds_signal.emit(True)
530
+
531
+ elif status.command == 'show_splash':
532
+ self.settings_tree.setEnabled(False)
533
+ self.splash_sc.show()
534
+ self.splash_sc.raise_()
535
+ self.splash_sc.showMessage(status.attribute[0], color=Qt.white)
536
+
537
+ elif status.command == 'close_splash':
538
+ self.splash_sc.close()
539
+ self.settings_tree.setEnabled(True)
540
+
541
+ elif status.command == 'set_allowed_values':
542
+ if self.ui is not None:
543
+ self.ui.set_spinbox_properties(**status.attribute)
544
+
545
+ def get_position(self):
546
+ deprecation_msg(f'This method is deprecated , please use `get_actuator_value`')
547
+ self.get_actuator_value()
548
+
549
+ def get_actuator_value(self):
550
+ """Get the current actuator value via the "get_actuator_value" command send to the hardware
551
+
552
+ Returns nothing but the `move_done_signal` will be send once the action is done
553
+ """
554
+ try:
555
+ self.command_hardware.emit(ThreadCommand(command="get_actuator_value"))
556
+
557
+ except Exception as e:
558
+ self.logger.exception(str(e))
559
+
560
+ def grab(self):
561
+ if self.ui is not None:
562
+ self.manage_ui_actions('refresh_value', 'setChecked', 'False')
563
+ self.get_continuous_actuator_value(False)
564
+
565
+ def stop_grab(self):
566
+ """Stop value polling. Mandatory
567
+
568
+ First uncheck the ui action if ui is not None, then stop the polling
569
+ """
570
+ if self.ui is not None:
571
+ self.manage_ui_actions('refresh_value', 'setChecked', 'False')
572
+ self.get_continuous_actuator_value(False)
573
+
574
+ def get_continuous_actuator_value(self, get_value=True):
575
+ """Start the continuous getting of the actuator's value
576
+
577
+ Parameters
578
+ ----------
579
+ get_value: bool
580
+ if True start the timer to periodically fetch the actuator's value, else stop it
581
+
582
+ Notes
583
+ -----
584
+ The current timer period is set by the refresh value *'refresh_timeout'* in the actuator main settings.
585
+ """
586
+ if get_value:
587
+ self._refresh_timer.setInterval(self.settings['main_settings', 'refresh_timeout'])
588
+ self._refresh_timer.start()
589
+ else:
590
+ self._refresh_timer.stop()
591
+
592
+ @property
593
+ def actuator(self):
594
+ """str: the selected actuator's type
595
+
596
+ Returns
597
+ -------
598
+
599
+ """
600
+ return self._actuator_type
601
+
602
+ @actuator.setter
603
+ def actuator(self, act_type):
604
+ if act_type in ACTUATOR_TYPES:
605
+ self._actuator_type = act_type
606
+ if self.ui is not None:
607
+ self.ui.actuator = act_type
608
+ self.update_settings()
609
+ else:
610
+ raise ActuatorError(f'{act_type} is an invalid actuator, should be within {ACTUATOR_TYPES}')
611
+
612
+ @property
613
+ def units(self):
614
+ return self.settings['move_settings', 'units']
615
+
616
+ def update_settings(self):
617
+
618
+ self.settings.child('main_settings', 'move_type').setValue(self._actuator_type)
619
+ self.settings.child('main_settings', 'module_name').setValue(self._title)
620
+ try:
621
+ for child in self.settings.child('move_settings').children():
622
+ child.remove()
623
+ parent_module = utils.find_dict_in_list_from_key_val(DAQ_Move_Actuators, 'name', self._actuator_type)
624
+ class_ = getattr(getattr(parent_module['module'], 'daq_move_' + self._actuator_type),
625
+ 'DAQ_Move_' + self._actuator_type)
626
+ params = getattr(class_, 'params')
627
+ move_params = Parameter.create(name='move_settings', type='group', children=params)
628
+
629
+ self.settings.child('move_settings').addChildren(move_params.children())
630
+
631
+ except Exception as e:
632
+ self.logger.exception(str(e))
633
+
634
+ def connect_tcp_ip(self):
635
+ if self.settings.child('main_settings', 'tcpip', 'connect_server').value():
636
+ self._tcpclient_thread = QThread()
637
+
638
+ tcpclient = TCPClient(self.settings.child('main_settings', 'tcpip', 'ip_address').value(),
639
+ self.settings.child('main_settings', 'tcpip', 'port').value(),
640
+ self.settings.child('move_settings'), client_type="ACTUATOR")
641
+ tcpclient.moveToThread(self._tcpclient_thread)
642
+ self._tcpclient_thread.tcpclient = tcpclient
643
+ tcpclient.cmd_signal.connect(self.process_tcpip_cmds)
644
+
645
+ self._command_tcpip[ThreadCommand].connect(tcpclient.queue_command)
646
+
647
+ self._tcpclient_thread.start()
648
+ tcpclient.init_connection()
649
+
650
+ @Slot(ThreadCommand)
651
+ def process_tcpip_cmds(self, status):
652
+ if 'move_abs' in status.command:
653
+ self.move_abs(status.attribute[0], send_to_tcpip=True)
654
+
655
+ elif 'move_rel' in status.command:
656
+ self.move_rel(status.attribute[0], send_to_tcpip=True)
657
+
658
+ elif 'move_home' in status.command:
659
+ self.move_home(send_to_tcpip=True)
660
+
661
+ elif 'check_position' in status.command:
662
+ deprecation_msg('check_position is deprecated, you should use get_actuator_value')
663
+ self._send_to_tcpip = True
664
+ self.command_hardware.emit(ThreadCommand('get_actuator_value', ))
665
+
666
+ elif 'get_actuator_value' in status.command:
667
+ self._send_to_tcpip = True
668
+ self.command_hardware.emit(ThreadCommand('get_actuator_value', ))
669
+
670
+ elif status.command == 'connected':
671
+ self.settings.child('main_settings', 'tcpip', 'tcp_connected').setValue(True)
672
+
673
+ elif status.command == 'disconnected':
674
+ self.settings.child('main_settings', 'tcpip', 'tcp_connected').setValue(False)
675
+
676
+ elif status.command == 'Update_Status':
677
+ self.thread_status(status)
678
+
679
+ elif status.command == 'set_info':
680
+ param_dict = ioxml.XML_string_to_parameter(status.attribute[1])[0]
681
+ param_tmp = Parameter.create(**param_dict)
682
+ param = self.settings.child('move_settings', *status.attribute[0][1:])
683
+
684
+ param.restoreState(param_tmp.saveState())
685
+
686
+
687
+ class DAQ_Move_Hardware(QObject):
688
+ """
689
+ ================== ========================
690
+ **Attributes** **Type**
691
+ *status_sig* instance of Signal
692
+ *hardware* ???
693
+ *actuator_type* string
694
+ *current_position* float
695
+ *target_value* float
696
+ *hardware_adress* string
697
+ *axis_address* string
698
+ *motion_stoped* boolean
699
+ ================== ========================
700
+ """
701
+ status_sig = Signal(ThreadCommand)
702
+
703
+ def __init__(self, actuator_type, position, title='actuator'):
704
+ super().__init__()
705
+ self.logger = set_logger(f'{logger.name}.{title}.actuator')
706
+ self._title = title
707
+ self.hardware = None
708
+ self.actuator_type = actuator_type
709
+ self.current_position = position
710
+ self._target_value = 0
711
+ self.hardware_adress = None
712
+ self.axis_address = None
713
+ self.motion_stoped = False
714
+
715
+ def close(self):
716
+ """
717
+ Uninitialize the stage closing the hardware.
718
+
719
+ """
720
+ self.hardware.close()
721
+
722
+ return "Stage uninitialized"
723
+
724
+ def get_actuator_value(self):
725
+ """Get the current position checking the hardware value.
726
+ """
727
+ pos = self.hardware.get_actuator_value()
728
+ return pos
729
+
730
+ def check_position(self):
731
+ """Get the current position checking the hardware position (deprecated)
732
+ """
733
+ deprecation_msg('check_position is deprecated, use get_actuator_value')
734
+ pos = self.hardware.get_actuator_value()
735
+ return pos
736
+
737
+ def ini_stage(self, params_state=None, controller=None):
738
+ """
739
+ Init a stage updating the hardware and sending an hardware move_done signal.
740
+
741
+ =============== =================================== ==========================================================================================================================
742
+ **Parameters** **Type** **Description**
743
+
744
+ *params_state* ordered dictionnary list The parameter state of the hardware class composed by a list representing the tree to keep a temporary save of the tree
745
+
746
+ *controller* one or many instance of DAQ_Move The controller id of the hardware
747
+
748
+ *stage* instance of DAQ_Move Defining axes and motors
749
+ =============== =================================== ==========================================================================================================================
750
+
751
+ See Also
752
+ --------
753
+ DAQ_utils.ThreadCommand, DAQ_Move
754
+ """
755
+
756
+ status = edict(initialized=False, info="")
757
+ try:
758
+ parent_module = utils.find_dict_in_list_from_key_val(DAQ_Move_Actuators, 'name', self.actuator_type)
759
+ class_ = getattr(getattr(parent_module['module'], 'daq_move_' + self.actuator_type),
760
+ 'DAQ_Move_' + self.actuator_type)
761
+ self.hardware = class_(self, params_state)
762
+ try:
763
+ infos = self.hardware.ini_stage(controller) # return edict(info="", controller=, stage=)
764
+ except Exception as e:
765
+ logger.exception('Hardware couldn\'t be initialized' + str(e))
766
+ infos = str(e), False
767
+
768
+ if isinstance(infos, edict): # following old plugin templating
769
+ status.update(infos)
770
+ deprecation_msg('Returns from init_stage should now be a string and a boolean,'
771
+ ' see pymodaq_plugins_template', stacklevel=3)
772
+ else:
773
+ status.info = infos[0]
774
+ status.initialized = infos[1]
775
+ status.controller = self.hardware.controller
776
+ self.hardware.move_done_signal.connect(self.move_done)
777
+
778
+ return status
779
+ except Exception as e:
780
+ self.logger.exception(str(e))
781
+ return status
782
+
783
+ def move_abs(self, position, polling=True):
784
+ """
785
+ Make the hardware absolute move from the given position.
786
+
787
+ =============== ========= =======================
788
+ **Parameters** **Type** **Description**
789
+
790
+ *position* float The absolute position
791
+ =============== ========= =======================
792
+
793
+ See Also
794
+ --------
795
+ move_Abs
796
+ """
797
+ position = float(position) # because it may be a numpy float and could cause issues
798
+ # see https://github.com/pythonnet/pythonnet/issues/1833
799
+ self._target_value = position
800
+ self.hardware.move_is_done = False
801
+ self.hardware.ispolling = polling
802
+ pos = self.hardware.move_abs(position)
803
+ self.hardware.poll_moving()
804
+
805
+ def move_rel(self, rel_position, polling=True):
806
+ """
807
+ Make the hardware relative move from the given relative position added to the current one.
808
+
809
+ ================ ========= ======================
810
+ **Parameters** **Type** **Description**
811
+
812
+ *position* float The relative position
813
+ ================ ========= ======================
814
+
815
+ See Also
816
+ --------
817
+ move_Rel
818
+ """
819
+ rel_position = float(rel_position) # because it may be a numpy float and could cause issues
820
+ # see https://github.com/pythonnet/pythonnet/issues/1833
821
+ self.hardware.move_is_done = False
822
+ self._target_value = self.current_position + rel_position
823
+ self.hardware.ispolling = polling
824
+ pos = self.hardware.move_rel(rel_position)
825
+ self.hardware.poll_moving()
826
+
827
+ @Slot(float)
828
+ def Move_Stoped(self, pos):
829
+ """
830
+ Send a "move_done" Thread Command with the given position as an attribute.
831
+
832
+ See Also
833
+ --------
834
+ DAQ_utils.ThreadCommand
835
+ """
836
+ self.status_sig.emit(ThreadCommand("move_done", [pos]))
837
+
838
+ def move_home(self):
839
+ """
840
+ Make the hardware move to the init position.
841
+
842
+ """
843
+ self.hardware.move_is_done = False
844
+ self._target_value = 0
845
+ self.hardware.move_home()
846
+
847
+ @Slot(float)
848
+ def move_done(self, pos):
849
+ """Send the move_done signal back to the main class
850
+ """
851
+ self._current_value = pos
852
+ self.status_sig.emit(ThreadCommand(command="move_done", attribute=[pos]))
853
+
854
+ @Slot(ThreadCommand)
855
+ def queue_command(self, command: ThreadCommand):
856
+ """Interpret command send by DAQ_Move class
857
+ * In case of **'ini_stage'** command, init a stage from command attribute.
858
+ * In case of **'close'** command, unitinalise the stage closing hardware and emitting the corresponding status signal
859
+ * In case of **'move_abs'** command, call the move_Abs method with position from command attribute
860
+ * In case of **'move_rel'** command, call the move_Rel method with the relative position from the command attribute.
861
+ * In case of **'move_home'** command, call the move_Home method
862
+ * In case of **'get_actuator_value'** command, get the current position from the check_position method
863
+ * In case of **'Stop_motion'** command, stop any motion via the stop_Motion method
864
+ * In case of **'reset_stop_motion'** command, set the motion_stopped attribute to false
865
+
866
+ Parameters
867
+ ----------
868
+ command: ThreadCommand
869
+ Possible commands are:
870
+ * **'ini_stage'** command, init a stage from command attribute.
871
+ * **'close'** command, unitinalise the stage closing hardware and emitting the corresponding status signal
872
+ * **'move_abs'** command, call the move_abs method with position from command attribute
873
+ * **'move_rel'** command, call the move_rel method with the relative position from the command attribute.
874
+ * **'move_home'** command, call the move_home method
875
+ * **'get_actuator_value'** command, get the current position from the check_position method
876
+ * **'stop_motion'** command, stop any motion via the stop_Motion method
877
+ * **'reset_stop_motion'** command, set the motion_stopped attribute to false
878
+ """
879
+ try:
880
+ if command.command == "ini_stage":
881
+ status = self.ini_stage(
882
+ *command.attribute) # return edict(initialized=bool,info="", controller=, stage=)
883
+ self.status_sig.emit(ThreadCommand(command=command.command, attribute=[status, 'log']))
884
+
885
+ elif command.command == "close":
886
+ status = self.close()
887
+ self.status_sig.emit(ThreadCommand(command=command.command, attribute=[status]))
888
+
889
+ elif command.command == "move_abs":
890
+ self.move_abs(*command.attribute)
891
+
892
+ elif command.command == "move_rel":
893
+ self.move_rel(*command.attribute)
894
+
895
+ elif command.command == "move_home":
896
+ self.move_home()
897
+
898
+ elif command.command == "get_actuator_value":
899
+ pos = self.get_actuator_value()
900
+ self.status_sig.emit(ThreadCommand('get_actuator_value', [pos]))
901
+
902
+ elif command.command == "stop_motion":
903
+ self.stop_motion()
904
+
905
+ elif command.command == "reset_stop_motion":
906
+ self.motion_stoped = False
907
+
908
+ else: # custom commands for particular plugins (see spectrometer module 'get_spectro_wl' for instance)
909
+ if hasattr(self.hardware, command.command):
910
+ cmd = getattr(self.hardware, command.command)
911
+ cmd(*command.attribute)
912
+ except Exception as e:
913
+ self.logger.exception(str(e))
914
+
915
+
916
+ def stop_motion(self):
917
+ """
918
+ stop hardware motion with motion_stopped attribute updtaed to True and a status signal sended with an "update_status" Thread Command
919
+
920
+ See Also
921
+ --------
922
+ DAQ_utils.ThreadCommand, stop_motion
923
+ """
924
+ self.status_sig.emit(ThreadCommand(command="Update_Status", attribute=["Motion stoping", 'log']))
925
+ self.motion_stoped = True
926
+ self.hardware.stop_motion()
927
+ self.hardware.poll_timer.stop()
928
+
929
+ @Slot(edict)
930
+ def update_settings(self, settings_parameter_dict):
931
+ """
932
+ Update settings of hardware with dictionnary parameters in case of "Move_Settings" path, else update attribute with dictionnary parameters.
933
+
934
+ ========================= =========== ======================================================
935
+ **Parameters** **Type** **Description**
936
+
937
+ *settings_parameter_dict* dictionnary Dictionnary containing the path and linked parameter
938
+ ========================= =========== ======================================================
939
+
940
+ See Also
941
+ --------
942
+ update_settings
943
+ """
944
+ # settings_parameter_dict = edict(path=path,param=param)
945
+ path = settings_parameter_dict['path']
946
+ param = settings_parameter_dict['param']
947
+ if path[0] == 'main_settings':
948
+ if hasattr(self, path[-1]):
949
+ setattr(self, path[-1], param.value())
950
+
951
+ elif path[0] == 'move_settings':
952
+ self.hardware.update_settings(settings_parameter_dict)
953
+
954
+
955
+ def main(init_qt=True):
956
+ if init_qt: # used for the test suite
957
+ app = QtWidgets.QApplication(sys.argv)
958
+
959
+ widget = QtWidgets.QWidget()
960
+ prog = DAQ_Move(widget, title="test")
961
+ widget.show()
962
+
963
+ if init_qt:
964
+ sys.exit(app.exec_())
965
+ return prog, widget
966
+
967
+
968
+ if __name__ == '__main__':
969
+ main()
970
+