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,686 +0,0 @@
1
- from qtpy import QtWidgets
2
- from qtpy.QtCore import QObject, Slot, QThread, Signal, QTimer
3
-
4
- from easydict import EasyDict as edict
5
- import pymodaq.daq_utils.daq_utils as utils
6
- import pymodaq.daq_utils.parameter.utils as putils
7
- from pymodaq.daq_utils.parameter import ioxml
8
- from pyqtgraph.parametertree import Parameter
9
- from pymodaq.daq_utils.daq_utils import ThreadCommand, getLineInfo
10
- from pymodaq.daq_utils.config import Config
11
- from pymodaq.daq_utils.tcp_server_client import TCPServer, tcp_parameters
12
- from pymodaq.daq_utils.messenger import deprecation_msg
13
- import numpy as np
14
- from time import perf_counter
15
-
16
- logger = utils.set_logger(utils.get_module_name(__file__))
17
- config = Config()
18
-
19
- # comon_parameters will be deprecated in version 4 and following new template. Should use comon_parameters_fun
20
- comon_parameters = [{'title': 'Units:', 'name': 'units', 'type': 'str', 'value': '', 'readonly': True},
21
- {'title': 'Epsilon:', 'name': 'epsilon', 'type': 'float',
22
- 'value': config('actuator', 'epsilon_default'),
23
- 'tip': 'Differential Value at which the controller considers it reached the target position'},
24
- {'title': 'Timeout (s):', 'name': 'timeout', 'type': 'int',
25
- 'value': config('actuator', 'polling_timeout_s')},
26
- {'title': 'Bounds:', 'name': 'bounds', 'type': 'group', 'children': [
27
- {'title': 'Set Bounds:', 'name': 'is_bounds', 'type': 'bool', 'value': False},
28
- {'title': 'Min:', 'name': 'min_bound', 'type': 'float', 'value': 0, 'default': 0},
29
- {'title': 'Max:', 'name': 'max_bound', 'type': 'float', 'value': 1, 'default': 1}, ]},
30
- {'title': 'Scaling:', 'name': 'scaling', 'type': 'group', 'children': [
31
- {'title': 'Use scaling:', 'name': 'use_scaling', 'type': 'bool', 'value': False,
32
- 'default': False},
33
- {'title': 'Scaling factor:', 'name': 'scaling', 'type': 'float', 'value': 1., 'default': 1.},
34
- {'title': 'Offset factor:', 'name': 'offset', 'type': 'float', 'value': 0., 'default': 0.}]}]
35
-
36
-
37
- MOVE_COMMANDS = ['abs', 'rel', 'home']
38
-
39
-
40
- class MoveCommand:
41
- def __init__(self, move_type, value=0):
42
- if move_type not in MOVE_COMMANDS:
43
- raise ValueError(f'The allowed move types fro an actuator are {MOVE_COMMANDS}')
44
- self.move_type = move_type
45
- self.value = value
46
-
47
-
48
- def comon_parameters_fun(is_multiaxes=False, axes_names=[], master=True, epsilon=config('actuator', 'epsilon_default')):
49
- """Function returning the common and mandatory parameters that should be on the actuator plugin level
50
-
51
- Parameters
52
- ----------
53
- is_multiaxes: bool
54
- If True, display the particular settings to define which axis the controller is driving
55
- axes_names: list of str
56
- The string identifier of every axis the controller can drive
57
- master: bool
58
- If True consider this plugin has to init the controller, otherwise use an already initialized instance
59
- epsilon: float
60
- The default or preset value of epsilon, the resolution with which a DAQ_Move should end its move
61
- """
62
- params = \
63
- [{'title': 'MultiAxes:', 'name': 'multiaxes', 'type': 'group', 'visible': is_multiaxes, 'children': [
64
- {'title': 'is Multiaxes:', 'name': 'ismultiaxes', 'type': 'bool', 'value': is_multiaxes,
65
- 'default': False},
66
- {'title': 'Status:', 'name': 'multi_status', 'type': 'list', 'value': 'Master' if master else 'Slave',
67
- 'limits': ['Master', 'Slave']},
68
- {'title': 'Axis:', 'name': 'axis', 'type': 'list', 'limits': axes_names},
69
- ]},
70
- {'title': 'Units:', 'name': 'units', 'type': 'str', 'value': '', 'readonly': True},
71
- {'title': 'Epsilon:', 'name': 'epsilon', 'type': 'float', 'value': epsilon,
72
- 'tip': 'Differential Value at which the controller considers it reached the target position'},
73
- {'title': 'Timeout (s):', 'name': 'timeout', 'type': 'int',
74
- 'value': config('actuator', 'polling_timeout_s')},
75
- {'title': 'Bounds:', 'name': 'bounds', 'type': 'group', 'children': [
76
- {'title': 'Set Bounds:', 'name': 'is_bounds', 'type': 'bool', 'value': False},
77
- {'title': 'Min:', 'name': 'min_bound', 'type': 'float', 'value': 0, 'default': 0},
78
- {'title': 'Max:', 'name': 'max_bound', 'type': 'float', 'value': 1, 'default': 1}, ]},
79
- {'title': 'Scaling:', 'name': 'scaling', 'type': 'group', 'children': [
80
- {'title': 'Use scaling:', 'name': 'use_scaling', 'type': 'bool', 'value': False,
81
- 'default': False},
82
- {'title': 'Scaling factor:', 'name': 'scaling', 'type': 'float', 'value': 1., 'default': 1.},
83
- {'title': 'Offset factor:', 'name': 'offset', 'type': 'float', 'value': 0., 'default': 0.}]}]
84
- return params
85
-
86
-
87
- params = [
88
- {'title': 'Main Settings:', 'name': 'main_settings', 'type': 'group', 'children': [
89
- {'title': 'Actuator type:', 'name': 'move_type', 'type': 'str', 'value': '', 'readonly': True},
90
- {'title': 'Controller ID:', 'name': 'controller_ID', 'type': 'int', 'value': 0, 'default': 0},
91
- {'title': 'TCP/IP options:', 'name': 'tcpip', 'type': 'group', 'visible': True, 'expanded': False,
92
- 'children': [
93
- {'title': 'Connect to server:', 'name': 'connect_server', 'type': 'bool_push', 'label': 'Connect',
94
- 'value': False},
95
- {'title': 'Connected?:', 'name': 'tcp_connected', 'type': 'led', 'value': False},
96
- {'title': 'IP address:', 'name': 'ip_address', 'type': 'str',
97
- 'value': config('network', 'tcp-server', 'ip')},
98
- {'title': 'Port:', 'name': 'port', 'type': 'int', 'value': config('network', 'tcp-server', 'port')},
99
- ]},
100
- ]},
101
- {'title': 'Actuator Settings:', 'name': 'move_settings', 'type': 'group'}
102
- ]
103
-
104
-
105
- def main(plugin_file, init=True, title='test'):
106
- """
107
- this method start a DAQ_Move object with this defined plugin as actuator
108
- Returns
109
- -------
110
-
111
- """
112
- import sys
113
- from qtpy import QtWidgets
114
- from pymodaq.daq_move.daq_move_main import DAQ_Move
115
- from pathlib import Path
116
- app = QtWidgets.QApplication(sys.argv)
117
- if config('style', 'darkstyle'):
118
- import qdarkstyle
119
- app.setStyleSheet(qdarkstyle.load_stylesheet())
120
-
121
- Form = QtWidgets.QWidget()
122
- prog = DAQ_Move(Form, title=title,)
123
- Form.show()
124
- prog.actuator = Path(plugin_file).stem[9:]
125
- if init:
126
- prog.init()
127
-
128
- sys.exit(app.exec_())
129
-
130
-
131
- class DAQ_Move_base(QObject):
132
- """ The base class to be inherited by all actuator modules
133
-
134
- This base class implements all necessary parameters and methods for the plugin to communicate with its parent (the
135
- DAQ_Move module)
136
-
137
- Parameters
138
- ----------
139
- parent : DAQ_Move_stage instance (see daq_viewer_main module)
140
- params_state : Parameter instance (pyqtgraph) from which the module will get the initial settings (as defined in the managers)
141
-
142
-
143
- :ivar Move_Done_signal: Signal signal represented by a float. Is emitted each time the hardware reached the target
144
- position within the epsilon precision (see comon_parameters variable)
145
-
146
- :ivar controller: the object representing the hardware in the plugin. Used to access hardware functionality
147
-
148
- :ivar status: easydict instance to set information (str), controller object, stage object (if required) and initialized
149
- state (bool) to return to parent after initialization
150
-
151
- :ivar settings: Parameter instance representing the hardware settings defined from the params attribute. Modifications
152
- on the GUI settings will be transferred to this attribute. It stores at all times the current state of the hardware/plugin
153
-
154
- :ivar params: class level attribute. List of dict used to create a Parameter object. Its definition on the class level enable
155
- the automatic update of the GUI settings when changing plugins (even in managers mode creation). To be populated
156
- on the plugin level as the base class does't represents a real hardware
157
-
158
- :ivar is_multiaxes: class level attribute (bool). Defines if the plugin controller controls multiple axes. If True, one has to define
159
- a Master instance of this plugin and slave instances of this plugin (all sharing the same controller_ID Parameter)
160
-
161
- :ivar current_position: (float) stores the current position after each call to the get_actuator_value in the child module
162
-
163
- :ivar target_position: (float) stores the target position the controller should reach within epsilon
164
-
165
- """
166
-
167
- Move_Done_signal = Signal(float)
168
- is_multiaxes = False
169
- stage_names = [] #deprecated
170
- axes_names = []
171
- params = []
172
- _controller_units = ''
173
- _epsilon = 1
174
-
175
- def __init__(self, parent=None, params_state=None):
176
- QObject.__init__(self) # to make sure this is the parent class
177
- self.move_is_done = False
178
- self.parent = parent
179
- self.shamrock_controller = None
180
- self.stage = None
181
- self.status = edict(info="", controller=None, stage=None, initialized=False)
182
- self.current_position = 0.
183
- self.target_position = 0.
184
- self._ispolling = True
185
- self.parent_parameters_path = [] # this is to be added in the send_param_status to take into account when the
186
- # current class instance parameter list is a child of some other class
187
- self.settings = Parameter.create(name='Settings', type='group', children=self.params)
188
- if params_state is not None:
189
- if isinstance(params_state, dict):
190
- self.settings.restoreState(params_state)
191
- elif isinstance(params_state, Parameter):
192
- self.settings.restoreState(params_state.saveState())
193
-
194
- self.settings.sigTreeStateChanged.connect(self.send_param_status)
195
- self.controller_units = self._controller_units
196
- self.controller = None
197
- #
198
- # if self.settings['epsilon'] == config('actuator', 'epsilon_default'):
199
- # self.settings.child('epsilon').setValue(self._epsilon)
200
-
201
- self.poll_timer = QTimer()
202
- self.poll_timer.setInterval(config('actuator', 'polling_interval_ms'))
203
- self._poll_timeout = config('actuator', 'polling_timeout_s')
204
- self.poll_timer.timeout.connect(self.check_target_reached)
205
-
206
- self.ini_attributes()
207
-
208
- def ini_attributes(self):
209
- pass
210
-
211
- def ini_stage_init(self, old_controller=None, new_controller=None):
212
- """Manage the Master/Slave controller issue
213
-
214
- First initialize the status dictionnary
215
- Then check whether this stage is controlled by a multiaxe controller (to be defined for each plugin)
216
- if it is a multiaxes controller then:
217
- * if it is Master: init the controller here
218
- * if it is Slave: use an already initialized controller (defined in the preset of the dashboard)
219
-
220
- Parameters
221
- ----------
222
- old_controller: object
223
- The particular object that allow the communication with the hardware, in general a python wrapper around the
224
- hardware library. In case of Slave this one comes from a previously initialized plugin
225
- new_controller: object
226
- The particular object that allow the communication with the hardware, in general a python wrapper around the
227
- hardware library. In case of Master it is the new instance of your plugin controller
228
- """
229
- self.status.update(edict(info="", controller=None, initialized=False))
230
- if self.settings['multiaxes', 'ismultiaxes'] and self.settings['multiaxes', 'multi_status'] == "Slave":
231
- if old_controller is None:
232
- raise Exception('no controller has been defined externally while this axe is a slave one')
233
- else:
234
- controller = old_controller
235
- else: # Master stage
236
- controller = new_controller
237
- self.controller = controller
238
- return controller
239
-
240
- @property
241
- def controller_units(self):
242
- return self._controller_units
243
-
244
- @controller_units.setter
245
- def controller_units(self, units: str = ''):
246
- self._controller_units = units
247
- try:
248
- self.settings.child('units').setValue(units)
249
- except Exception:
250
- pass
251
-
252
- @property
253
- def ispolling(self):
254
- return self._ispolling
255
-
256
- @ispolling.setter
257
- def ispolling(self, polling=True):
258
- self._ispolling = polling
259
-
260
- def check_bound(self, position):
261
- """
262
-
263
- Parameters
264
- ----------
265
- position
266
-
267
- Returns
268
- -------
269
-
270
- """
271
- if self.settings.child('bounds', 'is_bounds').value():
272
- if position > self.settings.child('bounds', 'max_bound').value():
273
- position = self.settings.child('bounds', 'max_bound').value()
274
- self.emit_status(ThreadCommand('outofbounds', []))
275
- elif position < self.settings.child('bounds', 'min_bound').value():
276
- position = self.settings.child('bounds', 'min_bound').value()
277
- self.emit_status(ThreadCommand('outofbounds', []))
278
- return position
279
-
280
- def get_actuator_value(self):
281
- if hasattr(self, 'check_position'):
282
- deprecation_msg('check_position method in plugins is deprecated, use get_actuator_value',3)
283
- return self.check_position()
284
- else:
285
- raise NotImplementedError
286
-
287
- def move_abs(self, value):
288
- if hasattr(self, 'move_Abs'):
289
- deprecation_msg('move_Abs method in plugins is deprecated, use move_abs',3)
290
- self.move_Abs(value)
291
- else:
292
- raise NotImplementedError
293
-
294
- def move_rel(self, value):
295
- if hasattr(self, 'move_Rel'):
296
- deprecation_msg('move_Rel method in plugins is deprecated, use move_rel',3)
297
- self.move_Rel(value)
298
- else:
299
- raise NotImplementedError
300
-
301
- def move_home(self):
302
- if hasattr(self, 'move_Home'):
303
- deprecation_msg('move_Home method in plugins is deprecated, use move_home', 3)
304
- self.move_Home()
305
- else:
306
- raise NotImplementedError
307
-
308
- def emit_status(self, status):
309
- """
310
- | Emit the statut signal from the given status parameter.
311
- |
312
- | The signal is sended to the gui to update the user interface.
313
-
314
- =============== ===================== ========================================================================================================================================
315
- **Parameters** **Type** **Description**
316
- *status* ordered dictionnary dictionnary containing keys:
317
- * *info* : string displaying various info
318
- * *controller*: instance of the controller object in order to control other axes without the need to init the same controller twice
319
- * *stage*: instance of the stage (axis or whatever) object
320
- * *initialized*: boolean indicating if initialization has been done corretly
321
- =============== ===================== ========================================================================================================================================
322
- """
323
- if self.parent is not None:
324
- self.parent.status_sig.emit(status)
325
- QtWidgets.QApplication.processEvents()
326
- else:
327
- print(status)
328
-
329
- def commit_settings(self, param):
330
- """
331
- to subclass to transfer parameters to hardware
332
- """
333
- pass
334
-
335
- def commit_common_settings(self, param):
336
- pass
337
-
338
- def get_position_with_scaling(self, pos):
339
- """
340
- Get the current position from the hardware with scaling conversion.
341
-
342
- =============== ========= =====================
343
- **Parameters** **Type** **Description**
344
- *pos* float the current position
345
- =============== ========= =====================
346
-
347
- Returns
348
- =======
349
- float
350
- the computed position.
351
- """
352
- if self.settings.child('scaling', 'use_scaling').value():
353
- pos = (pos - self.settings.child('scaling', 'offset').value()) * self.settings.child('scaling',
354
- 'scaling').value()
355
- return pos
356
-
357
- def move_done(self, position=None): # the position argument is just there to match some signature of child classes
358
- """
359
- | Emit a move done signal transmitting the float position to hardware.
360
- | The position argument is just there to match some signature of child classes.
361
-
362
- =============== ========== =============================================================================
363
- **Arguments** **Type** **Description**
364
- *position* float The position argument is just there to match some signature of child classes
365
- =============== ========== =============================================================================
366
-
367
- """
368
- if position is None:
369
- position = self.get_actuator_value()
370
- self.Move_Done_signal.emit(position)
371
- self.move_is_done = True
372
-
373
- def poll_moving(self):
374
- """
375
- Poll the current moving. In case of timeout emit the raise timeout Thread command.
376
-
377
- See Also
378
- --------
379
- DAQ_utils.ThreadCommand, move_done
380
- """
381
- if 'TCPServer' not in self.__class__.__name__:
382
- self.start_time = perf_counter()
383
- if self.ispolling:
384
- self.poll_timer.start()
385
- else:
386
- self.current_position = self.get_actuator_value()
387
- logger.debug(f'Current position: {self.current_position}')
388
- self.move_done(self.current_position)
389
-
390
- def check_target_reached(self):
391
- if np.abs(self.current_position - self.target_position) > self.settings.child('epsilon').value():
392
- logger.debug(f'Check move_is_done: {self.move_is_done}')
393
- if self.move_is_done:
394
- self.emit_status(ThreadCommand('Move has been stopped'))
395
- logger.info(f'Move has been stopped')
396
-
397
- self.current_position = self.get_actuator_value()
398
- self.emit_status(ThreadCommand('check_position', [self.current_position]))
399
- logger.debug(f'Current position: {self.current_position}')
400
-
401
- if perf_counter() - self.start_time >= self.settings.child('timeout').value():
402
- self.poll_timer.stop()
403
- self.emit_status(ThreadCommand('raise_timeout'))
404
- logger.info(f'Timeout activated')
405
- else:
406
- self.poll_timer.stop()
407
- logger.debug(f'Current position: {self.current_position}')
408
- self.move_done(self.current_position)
409
-
410
- def send_param_status(self, param, changes):
411
- """
412
- | Send changes value updates to the gui to update consequently the User Interface.
413
- | The message passing is made via the Thread Command "update_settings".
414
-
415
- =============== =================================== ==================================================
416
- **Parameters** **Type** **Description**
417
- *param* instance of pyqtgraph parameter The parameter to be checked
418
- *changes* (parameter,change,infos)tuple list The (parameter,change,infos) list to be treated
419
- =============== =================================== ==================================================
420
-
421
- See Also
422
- ========
423
- DAQ_utils.ThreadCommand
424
- """
425
-
426
- for param, change, data in changes:
427
- path = self.settings.childPath(param)
428
- if change == 'childAdded':
429
- self.emit_status(ThreadCommand('update_settings',
430
- [self.parent_parameters_path + path, [data[0].saveState(), data[1]],
431
- change])) # send parameters values/limits back to the GUI. Send kind of a copy back the GUI otherwise the child reference will be the same in both th eUI and the plugin so one of them will be removed
432
- elif change == 'value' or change == 'limits' or change == 'options':
433
- self.emit_status(ThreadCommand('update_settings', [self.parent_parameters_path + path, data,
434
- change])) # send parameters values/limits back to the GUI
435
- elif change == 'parent':
436
- pass
437
-
438
- def set_position_with_scaling(self, pos):
439
- """
440
- Set the current position from the parameter and hardware with scaling conversion.
441
-
442
- =============== ========= ==========================
443
- **Parameters** **Type** **Description**
444
- *pos* float the position to be setted
445
- =============== ========= ==========================
446
-
447
- Returns
448
- =======
449
- float
450
- the computed position.
451
- """
452
- if self.settings.child('scaling', 'use_scaling').value():
453
- pos = pos / self.settings.child('scaling', 'scaling').value() + self.settings.child('scaling',
454
- 'offset').value()
455
- return pos
456
-
457
- def set_position_relative_with_scaling(self, pos):
458
- """
459
- Set the scaled positions in case of relative moves
460
- """
461
- if self.settings.child('scaling', 'use_scaling').value():
462
- pos = pos / self.settings.child('scaling', 'scaling').value()
463
- return pos
464
-
465
- @Slot(edict)
466
- def update_settings(self, settings_parameter_dict): # settings_parameter_dict=edict(path=path,param=param)
467
- """
468
- Receive the settings_parameter signal from the param_tree_changed method and make hardware updates of mmodified values.
469
-
470
- ========================== =========== ==========================================================================================================
471
- **Arguments** **Type** **Description**
472
- *settings_parameter_dict* dictionnary Dictionnary with the path of the parameter in hardware structure as key and the parameter name as element
473
- ========================== =========== ==========================================================================================================
474
-
475
- See Also
476
- --------
477
- send_param_status, commit_settings
478
- """
479
- path = settings_parameter_dict['path']
480
- param = settings_parameter_dict['param']
481
- change = settings_parameter_dict['change']
482
- try:
483
- self.settings.sigTreeStateChanged.disconnect(self.send_param_status)
484
- except Exception:
485
- pass
486
- if change == 'value':
487
- self.settings.child(*path[1:]).setValue(param.value()) # blocks signal back to main UI
488
- elif change == 'childAdded':
489
- child = Parameter.create(name='tmp')
490
- child.restoreState(param)
491
- self.settings.child(*path[1:]).addChild(child) # blocks signal back to main UI
492
- param = child
493
-
494
- elif change == 'parent':
495
- children = putils.get_param_from_name(self.settings, param.name())
496
-
497
- if children is not None:
498
- path = putils.get_param_path(children)
499
- self.settings.child(*path[1:-1]).removeChild(children)
500
-
501
- self.settings.sigTreeStateChanged.connect(self.send_param_status)
502
- self.commit_common_settings(param)
503
- self.commit_settings(param)
504
-
505
-
506
- class DAQ_Move_TCP_server(DAQ_Move_base, TCPServer):
507
- """
508
- ================= ==============================
509
- **Attributes** **Type**
510
- *command_server* instance of Signal
511
- *x_axis* 1D numpy array
512
- *y_axis* 1D numpy array
513
- *data* double precision float array
514
- ================= ==============================
515
-
516
- See Also
517
- --------
518
- utility_classes.DAQ_TCP_server
519
- """
520
- params_client = [] # parameters of a client grabber
521
- command_server = Signal(list)
522
-
523
- message_list = ["Quit", "Status", "Done", "Server Closed", "Info", "Infos", "Info_xml", "move_abs",
524
- 'move_home', 'move_rel', 'get_actuator_value', 'stop_motion', 'position_is', 'move_done']
525
- socket_types = ["ACTUATOR"]
526
- params = comon_parameters_fun() + tcp_parameters
527
-
528
- def __init__(self, parent=None, params_state=None):
529
- """
530
-
531
- Parameters
532
- ----------
533
- parent
534
- params_state
535
- """
536
- self.client_type = "ACTUATOR"
537
- DAQ_Move_base.__init__(self, parent, params_state) # initialize base class with commom attributes and methods
538
- self.settings.child(('bounds')).hide()
539
- self.settings.child(('scaling')).hide()
540
- self.settings.child(('epsilon')).setValue(1)
541
-
542
- TCPServer.__init__(self, self.client_type)
543
-
544
- def command_to_from_client(self, command):
545
- sock = self.find_socket_within_connected_clients(self.client_type)
546
- if sock is not None: # if client 'ACTUATOR' is connected then send it the command
547
-
548
- if command == 'position_is':
549
- pos = sock.get_scalar()
550
-
551
- pos = self.get_position_with_scaling(pos)
552
- self.current_position = pos
553
- self.emit_status(ThreadCommand('get_actuator_value', [pos]))
554
-
555
- elif command == 'move_done':
556
- pos = sock.get_scalar()
557
- pos = self.get_position_with_scaling(pos)
558
- self.current_position = pos
559
- self.emit_status(ThreadCommand('move_done', [pos]))
560
- else:
561
- self.send_command(sock, command)
562
-
563
- def commit_settings(self, param):
564
-
565
- if param.name() in putils.iter_children(self.settings.child(('settings_client')), []):
566
- actuator_socket = [client['socket'] for client in self.connected_clients if client['type'] == 'ACTUATOR'][0]
567
- actuator_socket.send_string('set_info')
568
- path = putils.get_param_path(param)[2:]
569
- # get the path of this param as a list starting at parent 'infos'
570
-
571
- actuator_socket.send_list(path)
572
-
573
- # send value
574
- data = ioxml.parameter_to_xml_string(param)
575
- actuator_socket.send_string(data)
576
-
577
- def ini_stage(self, controller=None):
578
- """
579
- | Initialisation procedure of the detector updating the status dictionnary.
580
- |
581
- | Init axes from image , here returns only None values (to tricky to di it with the server and not really necessary for images anyway)
582
-
583
- See Also
584
- --------
585
- utility_classes.DAQ_TCP_server.init_server, get_xaxis, get_yaxis
586
- """
587
- self.status.update(edict(initialized=False, info="", x_axis=None, y_axis=None, controller=None))
588
- try:
589
- self.settings.child(('infos')).addChildren(self.params_client)
590
-
591
- self.init_server()
592
-
593
- self.settings.child('units').hide()
594
- self.settings.child('epsilon').hide()
595
-
596
- self.status.info = 'TCP Server actuator'
597
- self.status.initialized = True
598
- self.status.controller = self.serversocket
599
- return self.status
600
-
601
- except Exception as e:
602
- self.status.info = getLineInfo() + str(e)
603
- self.status.initialized = False
604
- return self.status
605
-
606
- def close(self):
607
- """
608
- Should be used to uninitialize hardware.
609
-
610
- See Also
611
- --------
612
- utility_classes.DAQ_TCP_server.close_server
613
- """
614
- self.listening = False
615
- self.close_server()
616
-
617
- def move_Abs(self, position):
618
- """
619
-
620
- """
621
- position = self.check_bound(position)
622
- self.target_position = position
623
-
624
- position = self.set_position_with_scaling(position)
625
-
626
- sock = self.find_socket_within_connected_clients(self.client_type)
627
- if sock is not None: # if client self.client_type is connected then send it the command
628
- sock.send_string('move_abs')
629
- sock.send_scalar(position)
630
-
631
- def move_Rel(self, position):
632
- position = self.check_bound(self.current_position + position) - self.current_position
633
- self.target_position = position + self.current_position
634
-
635
- position = self.set_position_relative_with_scaling(position)
636
- sock = self.find_socket_within_connected_clients(self.client_type)
637
- if sock is not None: # if client self.client_type is connected then send it the command
638
- sock.send_string('move_rel')
639
- sock.send_scalar(position)
640
-
641
- def move_Home(self):
642
- """
643
- Make the absolute move to original position (0).
644
-
645
- See Also
646
- --------
647
- move_Abs
648
- """
649
- sock = self.find_socket_within_connected_clients(self.client_type)
650
- if sock is not None: # if client self.client_type is connected then send it the command
651
- sock.send_string('move_home')
652
-
653
- def get_actuator_value(self):
654
- """
655
- Get the current hardware position with scaling conversion given by get_position_with_scaling.
656
-
657
- See Also
658
- --------
659
- daq_move_base.get_position_with_scaling, daq_utils.ThreadCommand
660
- """
661
- sock = self.find_socket_within_connected_clients(self.client_type)
662
- if sock is not None: # if client self.client_type is connected then send it the command
663
- self.send_command(sock, 'get_actuator_value')
664
-
665
- return self.current_position
666
-
667
- def stop_motion(self):
668
- """
669
- See Also
670
- --------
671
- daq_move_base.move_done
672
- """
673
- sock = self.find_socket_within_connected_clients(self.client_type)
674
- if sock is not None: # if client self.client_type is connected then send it the command
675
- self.send_command(sock, 'stop_motion')
676
-
677
- def stop(self):
678
- """
679
- not implemented.
680
- """
681
- pass
682
- return ""
683
-
684
-
685
- if __name__ == '__main__':
686
- test = DAQ_Move_base()