bec-widgets 0.99.1__py3-none-any.whl → 0.99.9__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.
Files changed (250) hide show
  1. .gitlab-ci.yml +0 -1
  2. CHANGELOG.md +76 -70
  3. PKG-INFO +2 -2
  4. bec_widgets/cli/client.py +3 -3
  5. bec_widgets/qt_utils/toolbar.py +11 -5
  6. bec_widgets/utils/bec_widget.py +11 -2
  7. bec_widgets/utils/colors.py +18 -2
  8. bec_widgets/utils/plugin_templates/plugin.template +2 -2
  9. bec_widgets/widgets/bec_queue/bec_queue.py +2 -0
  10. bec_widgets/widgets/bec_queue/bec_queue_plugin.py +1 -1
  11. bec_widgets/widgets/bec_status_box/bec_status_box.py +2 -0
  12. bec_widgets/widgets/bec_status_box/bec_status_box_plugin.py +1 -1
  13. bec_widgets/widgets/color_button/color_button.py +2 -0
  14. bec_widgets/widgets/color_button/color_button_plugin.py +1 -1
  15. bec_widgets/widgets/colormap_selector/colormap_selector.py +1 -0
  16. bec_widgets/widgets/colormap_selector/colormap_selector_plugin.py +1 -1
  17. bec_widgets/widgets/dark_mode_button/dark_mode_button.py +12 -3
  18. bec_widgets/widgets/dark_mode_button/dark_mode_button_plugin.py +1 -1
  19. bec_widgets/widgets/device_browser/device_browser.py +2 -0
  20. bec_widgets/widgets/device_browser/device_browser_plugin.py +1 -1
  21. bec_widgets/widgets/device_combobox/device_combo_box_plugin.py +1 -1
  22. bec_widgets/widgets/device_combobox/device_combobox.py +2 -0
  23. bec_widgets/widgets/device_line_edit/device_line_edit.py +2 -0
  24. bec_widgets/widgets/device_line_edit/device_line_edit_plugin.py +1 -1
  25. bec_widgets/widgets/dock/dock.py +1 -0
  26. bec_widgets/widgets/dock/dock_area.py +30 -10
  27. bec_widgets/widgets/dock/dock_area_plugin.py +1 -1
  28. bec_widgets/widgets/figure/figure.py +1 -1
  29. bec_widgets/widgets/figure/plots/waveform/waveform.py +12 -7
  30. bec_widgets/widgets/figure/plots/waveform/waveform_curve.py +3 -3
  31. bec_widgets/widgets/image/bec_image_widget_plugin.py +1 -1
  32. bec_widgets/widgets/image/image_widget.py +1 -0
  33. bec_widgets/widgets/motor_map/bec_motor_map_widget_plugin.py +1 -1
  34. bec_widgets/widgets/motor_map/motor_map_widget.py +1 -0
  35. bec_widgets/widgets/position_indicator/position_indicator.py +2 -0
  36. bec_widgets/widgets/position_indicator/position_indicator_plugin.py +1 -1
  37. bec_widgets/widgets/positioner_box/positioner_box.py +1 -0
  38. bec_widgets/widgets/positioner_box/positioner_box_plugin.py +1 -1
  39. bec_widgets/widgets/positioner_box/positioner_control_line.py +2 -0
  40. bec_widgets/widgets/positioner_box/positioner_control_line_plugin.py +1 -1
  41. bec_widgets/widgets/ring_progress_bar/ring_progress_bar.py +1 -0
  42. bec_widgets/widgets/ring_progress_bar/ring_progress_bar_plugin.py +1 -1
  43. bec_widgets/widgets/scan_control/scan_control.py +2 -0
  44. bec_widgets/widgets/scan_control/scan_control_plugin.py +1 -4
  45. bec_widgets/widgets/spinner/spinner.py +2 -0
  46. bec_widgets/widgets/spinner/spinner_widget_plugin.py +1 -1
  47. bec_widgets/widgets/stop_button/stop_button.py +2 -0
  48. bec_widgets/widgets/stop_button/stop_button_plugin.py +1 -1
  49. bec_widgets/widgets/text_box/text_box.py +1 -0
  50. bec_widgets/widgets/text_box/text_box_plugin.py +1 -1
  51. bec_widgets/widgets/toggle/toggle.py +1 -0
  52. bec_widgets/widgets/toggle/toggle_switch_plugin.py +1 -1
  53. bec_widgets/widgets/vscode/vs_code_editor_plugin.py +1 -1
  54. bec_widgets/widgets/vscode/vscode.py +1 -0
  55. bec_widgets/widgets/waveform/bec_waveform_widget_plugin.py +1 -1
  56. bec_widgets/widgets/waveform/waveform_popups/curve_dialog/curve_dialog.py +14 -13
  57. bec_widgets/widgets/waveform/waveform_widget.py +3 -2
  58. bec_widgets/widgets/website/website.py +42 -10
  59. bec_widgets/widgets/website/website_widget_plugin.py +1 -1
  60. {bec_widgets-0.99.1.dist-info → bec_widgets-0.99.9.dist-info}/METADATA +2 -2
  61. bec_widgets-0.99.9.dist-info/RECORD +231 -0
  62. pyproject.toml +7 -2
  63. bec_widgets/assets/toolbar_icons/add.svg +0 -3
  64. bec_widgets/assets/toolbar_icons/attach_all.svg +0 -3
  65. bec_widgets/assets/toolbar_icons/auto_range.svg +0 -3
  66. bec_widgets/assets/toolbar_icons/compare.svg +0 -3
  67. bec_widgets/assets/toolbar_icons/connection.svg +0 -4
  68. bec_widgets/assets/toolbar_icons/device_line_edit.svg +0 -3
  69. bec_widgets/assets/toolbar_icons/drag_pan_mode.svg +0 -3
  70. bec_widgets/assets/toolbar_icons/export.svg +0 -9
  71. bec_widgets/assets/toolbar_icons/fft.svg +0 -11
  72. bec_widgets/assets/toolbar_icons/fitting_parameters.svg +0 -3
  73. bec_widgets/assets/toolbar_icons/history.svg +0 -4
  74. bec_widgets/assets/toolbar_icons/image.svg +0 -3
  75. bec_widgets/assets/toolbar_icons/image_autorange.svg +0 -3
  76. bec_widgets/assets/toolbar_icons/import.svg +0 -9
  77. bec_widgets/assets/toolbar_icons/line_axis.svg +0 -3
  78. bec_widgets/assets/toolbar_icons/line_curve.svg +0 -3
  79. bec_widgets/assets/toolbar_icons/lock_aspect_ratio.svg +0 -3
  80. bec_widgets/assets/toolbar_icons/log_scale.png +0 -0
  81. bec_widgets/assets/toolbar_icons/motor_map.svg +0 -3
  82. bec_widgets/assets/toolbar_icons/photo_library.svg +0 -3
  83. bec_widgets/assets/toolbar_icons/positioner_box.svg +0 -3
  84. bec_widgets/assets/toolbar_icons/progress.svg +0 -3
  85. bec_widgets/assets/toolbar_icons/queue.svg +0 -3
  86. bec_widgets/assets/toolbar_icons/rectangle_mode.svg +0 -3
  87. bec_widgets/assets/toolbar_icons/remove.svg +0 -5
  88. bec_widgets/assets/toolbar_icons/reset_settings.svg +0 -3
  89. bec_widgets/assets/toolbar_icons/restore_state.svg +0 -3
  90. bec_widgets/assets/toolbar_icons/ring_progress.svg +0 -3
  91. bec_widgets/assets/toolbar_icons/rotate_left.svg +0 -3
  92. bec_widgets/assets/toolbar_icons/rotate_right.svg +0 -3
  93. bec_widgets/assets/toolbar_icons/save.svg +0 -3
  94. bec_widgets/assets/toolbar_icons/save_state.svg +0 -3
  95. bec_widgets/assets/toolbar_icons/scan_control.svg +0 -3
  96. bec_widgets/assets/toolbar_icons/settings.svg +0 -4
  97. bec_widgets/assets/toolbar_icons/status.svg +0 -3
  98. bec_widgets/assets/toolbar_icons/terminal.svg +0 -3
  99. bec_widgets/assets/toolbar_icons/transform.svg +0 -3
  100. bec_widgets/assets/toolbar_icons/waveform.svg +0 -3
  101. bec_widgets-0.99.1.dist-info/RECORD +0 -415
  102. docs/Makefile +0 -20
  103. docs/_static/custom.css +0 -170
  104. docs/_templates/custom-class-template.rst +0 -34
  105. docs/_templates/custom-module-template.rst +0 -66
  106. docs/api_reference/api_reference.md +0 -12
  107. docs/assets/apps_48dp.svg +0 -1
  108. docs/assets/display_settings_48dp.svg +0 -1
  109. docs/assets/index_api.svg +0 -97
  110. docs/assets/index_contribute.svg +0 -76
  111. docs/assets/index_getting_started.svg +0 -66
  112. docs/assets/index_user_guide.svg +0 -67
  113. docs/assets/rocket_launch_48dp.svg +0 -1
  114. docs/assets/widget_screenshots/buttons.png +0 -0
  115. docs/assets/widget_screenshots/device_box.png +0 -0
  116. docs/assets/widget_screenshots/device_browser.png +0 -0
  117. docs/assets/widget_screenshots/device_inputs.png +0 -0
  118. docs/assets/widget_screenshots/dock_area.png +0 -0
  119. docs/assets/widget_screenshots/figure.png +0 -0
  120. docs/assets/widget_screenshots/image_widget.png +0 -0
  121. docs/assets/widget_screenshots/motor_map_widget.png +0 -0
  122. docs/assets/widget_screenshots/position_indicator.png +0 -0
  123. docs/assets/widget_screenshots/queue.png +0 -0
  124. docs/assets/widget_screenshots/ring_progress_bar.png +0 -0
  125. docs/assets/widget_screenshots/scan_controller.png +0 -0
  126. docs/assets/widget_screenshots/spinner.gif +0 -0
  127. docs/assets/widget_screenshots/status_box.png +0 -0
  128. docs/assets/widget_screenshots/text_box.png +0 -0
  129. docs/assets/widget_screenshots/toggle.png +0 -0
  130. docs/assets/widget_screenshots/waveform_widget.png +0 -0
  131. docs/assets/widget_screenshots/website.png +0 -0
  132. docs/conf.py +0 -82
  133. docs/developer/developer.md +0 -52
  134. docs/developer/introduction/concepts.md +0 -14
  135. docs/developer/introduction/contributing.md +0 -28
  136. docs/developer/introduction/introduction.md +0 -16
  137. docs/developer/introduction/useful_links.md +0 -23
  138. docs/developer/widget_development/bec_dispatcher.md +0 -143
  139. docs/developer/widget_development/widget_development.md +0 -13
  140. docs/index.md +0 -74
  141. docs/introduction/introduction.md +0 -18
  142. docs/make.bat +0 -35
  143. docs/requirements.txt +0 -12
  144. docs/user/api_reference/api_reference.md +0 -11
  145. docs/user/applications/applications.md +0 -10
  146. docs/user/customisation.md +0 -123
  147. docs/user/getting_started/BECDockArea.png +0 -0
  148. docs/user/getting_started/auto_updates.md +0 -82
  149. docs/user/getting_started/getting_started.md +0 -15
  150. docs/user/getting_started/gui_complex_gui.gif +0 -0
  151. docs/user/getting_started/installation.md +0 -33
  152. docs/user/getting_started/quick_start.md +0 -110
  153. docs/user/getting_started/video_tutorials.md +0 -17
  154. docs/user/user.md +0 -71
  155. docs/user/widgets/bec_figure/BECFigure.png +0 -0
  156. docs/user/widgets/bec_figure/bec_figure.md +0 -105
  157. docs/user/widgets/bec_status_box/bec_status_box.gif +0 -0
  158. docs/user/widgets/bec_status_box/bec_status_box.md +0 -38
  159. docs/user/widgets/buttons/buttons.md +0 -63
  160. docs/user/widgets/buttons/dark_mode_disabled.png +0 -0
  161. docs/user/widgets/buttons/dark_mode_enabled.png +0 -0
  162. docs/user/widgets/device_browser/device_browser.md +0 -36
  163. docs/user/widgets/device_browser/device_browser.png +0 -0
  164. docs/user/widgets/device_input/device_input.md +0 -100
  165. docs/user/widgets/dock_area/BECDockArea.png +0 -0
  166. docs/user/widgets/dock_area/bec_dock_area.md +0 -107
  167. docs/user/widgets/image/image_plot.gif +0 -0
  168. docs/user/widgets/image/image_widget.md +0 -84
  169. docs/user/widgets/motor_map/motor.gif +0 -0
  170. docs/user/widgets/motor_map/motor_map.md +0 -80
  171. docs/user/widgets/position_indicator/position_indicator.md +0 -76
  172. docs/user/widgets/positioner_box/positioner_box.md +0 -63
  173. docs/user/widgets/progress_bar/progress_bar.gif +0 -0
  174. docs/user/widgets/progress_bar/ring_progress_bar.md +0 -103
  175. docs/user/widgets/queue/queue.md +0 -41
  176. docs/user/widgets/scan_control/hide_scan_control.png +0 -0
  177. docs/user/widgets/scan_control/scan_control.gif +0 -0
  178. docs/user/widgets/scan_control/scan_control.md +0 -54
  179. docs/user/widgets/spinner/spinner.md +0 -75
  180. docs/user/widgets/text_box/text_box.md +0 -74
  181. docs/user/widgets/toggle/toggle.md +0 -66
  182. docs/user/widgets/waveform/bec_figure_dap.gif +0 -0
  183. docs/user/widgets/waveform/scatter_2D.gif +0 -0
  184. docs/user/widgets/waveform/w1D.gif +0 -0
  185. docs/user/widgets/waveform/waveform_widget.md +0 -132
  186. docs/user/widgets/website/website.md +0 -69
  187. docs/user/widgets/widgets.md +0 -220
  188. tests/__init__.py +0 -0
  189. tests/end-2-end/__init__.py +0 -0
  190. tests/end-2-end/conftest.py +0 -53
  191. tests/end-2-end/test_bec_dock_rpc_e2e.py +0 -298
  192. tests/end-2-end/test_bec_figure_rpc_e2e.py +0 -212
  193. tests/end-2-end/test_rpc_register_e2e.py +0 -40
  194. tests/end-2-end/test_scan_control_e2e.py +0 -71
  195. tests/references/SpinnerWidget/SpinnerWidget_darwin.png +0 -0
  196. tests/references/SpinnerWidget/SpinnerWidget_linux.png +0 -0
  197. tests/references/SpinnerWidget/SpinnerWidget_started_darwin.png +0 -0
  198. tests/references/SpinnerWidget/SpinnerWidget_started_linux.png +0 -0
  199. tests/unit_tests/__init__.py +0 -0
  200. tests/unit_tests/client_mocks.py +0 -189
  201. tests/unit_tests/conftest.py +0 -64
  202. tests/unit_tests/test_bec_connector.py +0 -80
  203. tests/unit_tests/test_bec_dispatcher.py +0 -119
  204. tests/unit_tests/test_bec_dock.py +0 -155
  205. tests/unit_tests/test_bec_figure.py +0 -270
  206. tests/unit_tests/test_bec_image.py +0 -63
  207. tests/unit_tests/test_bec_image_widget.py +0 -217
  208. tests/unit_tests/test_bec_motor_map.py +0 -282
  209. tests/unit_tests/test_bec_queue.py +0 -111
  210. tests/unit_tests/test_bec_status_box.py +0 -123
  211. tests/unit_tests/test_client_utils.py +0 -76
  212. tests/unit_tests/test_color_map_selector.py +0 -42
  213. tests/unit_tests/test_color_validation.py +0 -75
  214. tests/unit_tests/test_configs/config_device.yaml +0 -33
  215. tests/unit_tests/test_configs/config_device_no_entry.yaml +0 -27
  216. tests/unit_tests/test_configs/config_scan.yaml +0 -82
  217. tests/unit_tests/test_crosshair.py +0 -143
  218. tests/unit_tests/test_dark_mode_button.py +0 -70
  219. tests/unit_tests/test_device_browser.py +0 -83
  220. tests/unit_tests/test_device_input_base.py +0 -76
  221. tests/unit_tests/test_device_input_widgets.py +0 -178
  222. tests/unit_tests/test_error_utils.py +0 -63
  223. tests/unit_tests/test_generate_cli_client.py +0 -123
  224. tests/unit_tests/test_generate_plugin.py +0 -155
  225. tests/unit_tests/test_motor_map_widget.py +0 -194
  226. tests/unit_tests/test_msgs/__init__.py +0 -0
  227. tests/unit_tests/test_msgs/available_scans_message.py +0 -989
  228. tests/unit_tests/test_plot_base.py +0 -95
  229. tests/unit_tests/test_plugin_utils.py +0 -13
  230. tests/unit_tests/test_positioner_box.py +0 -130
  231. tests/unit_tests/test_ring_progress_bar.py +0 -337
  232. tests/unit_tests/test_rpc_register.py +0 -52
  233. tests/unit_tests/test_rpc_server.py +0 -42
  234. tests/unit_tests/test_rpc_widget_handler.py +0 -7
  235. tests/unit_tests/test_scan_control.py +0 -324
  236. tests/unit_tests/test_scan_control_group_box.py +0 -160
  237. tests/unit_tests/test_setting_dialog.py +0 -96
  238. tests/unit_tests/test_spinner.py +0 -31
  239. tests/unit_tests/test_stop_button.py +0 -27
  240. tests/unit_tests/test_text_box_widget.py +0 -54
  241. tests/unit_tests/test_toggle.py +0 -38
  242. tests/unit_tests/test_vscode_widget.py +0 -75
  243. tests/unit_tests/test_waveform1d.py +0 -712
  244. tests/unit_tests/test_waveform_widget.py +0 -462
  245. tests/unit_tests/test_website_widget.py +0 -25
  246. tests/unit_tests/test_widget_io.py +0 -90
  247. tests/unit_tests/test_yaml_dialog.py +0 -163
  248. {bec_widgets-0.99.1.dist-info → bec_widgets-0.99.9.dist-info}/WHEEL +0 -0
  249. {bec_widgets-0.99.1.dist-info → bec_widgets-0.99.9.dist-info}/entry_points.txt +0 -0
  250. {bec_widgets-0.99.1.dist-info → bec_widgets-0.99.9.dist-info}/licenses/LICENSE +0 -0
@@ -1,212 +0,0 @@
1
- import time
2
-
3
- import numpy as np
4
- import pytest
5
- from bec_lib.endpoints import MessageEndpoints
6
-
7
- from bec_widgets.cli.client import BECFigure, BECImageShow, BECMotorMap, BECWaveform
8
-
9
-
10
- def test_rpc_waveform1d_custom_curve(rpc_server_figure):
11
- fig = BECFigure(rpc_server_figure)
12
-
13
- ax = fig.plot()
14
- curve = ax.plot(x=[1, 2, 3], y=[1, 2, 3])
15
- curve.set_color("red")
16
- curve = ax.curves[0]
17
- curve.set_color("blue")
18
-
19
- assert len(fig.widgets) == 1
20
- assert len(fig.widgets[ax._rpc_id].curves) == 1
21
-
22
-
23
- def test_rpc_plotting_shortcuts_init_configs(rpc_server_figure, qtbot):
24
- fig = BECFigure(rpc_server_figure)
25
-
26
- plt = fig.plot(x_name="samx", y_name="bpm4i")
27
- im = fig.image("eiger")
28
- motor_map = fig.motor_map("samx", "samy")
29
- plt_z = fig.plot(x_name="samx", y_name="samy", z_name="bpm4i", new=True)
30
-
31
- # Checking if classes are correctly initialised
32
- assert len(fig.widgets) == 4
33
- assert plt.__class__.__name__ == "BECWaveform"
34
- assert plt.__class__ == BECWaveform
35
- assert im.__class__.__name__ == "BECImageShow"
36
- assert im.__class__ == BECImageShow
37
- assert motor_map.__class__.__name__ == "BECMotorMap"
38
- assert motor_map.__class__ == BECMotorMap
39
-
40
- # check if the correct devices are set
41
- # plot
42
- assert plt._config_dict["curves"]["bpm4i-bpm4i"]["signals"] == {
43
- "dap": None,
44
- "source": "scan_segment",
45
- "x": {"name": "samx", "entry": "samx", "unit": None, "modifier": None, "limits": None},
46
- "y": {"name": "bpm4i", "entry": "bpm4i", "unit": None, "modifier": None, "limits": None},
47
- "z": None,
48
- }
49
- # image
50
- assert im._config_dict["images"]["eiger"]["monitor"] == "eiger"
51
- # motor map
52
- assert motor_map._config_dict["signals"] == {
53
- "dap": None,
54
- "source": "device_readback",
55
- "x": {
56
- "name": "samx",
57
- "entry": "samx",
58
- "unit": None,
59
- "modifier": None,
60
- "limits": [-50.0, 50.0],
61
- },
62
- "y": {
63
- "name": "samy",
64
- "entry": "samy",
65
- "unit": None,
66
- "modifier": None,
67
- "limits": [-50.0, 50.0],
68
- },
69
- "z": None,
70
- }
71
- # plot with z scatter
72
- assert plt_z._config_dict["curves"]["bpm4i-bpm4i"]["signals"] == {
73
- "dap": None,
74
- "source": "scan_segment",
75
- "x": {"name": "samx", "entry": "samx", "unit": None, "modifier": None, "limits": None},
76
- "y": {"name": "samy", "entry": "samy", "unit": None, "modifier": None, "limits": None},
77
- "z": {"name": "bpm4i", "entry": "bpm4i", "unit": None, "modifier": None, "limits": None},
78
- }
79
-
80
-
81
- def test_rpc_waveform_scan(rpc_server_figure, bec_client_lib):
82
- fig = BECFigure(rpc_server_figure)
83
-
84
- # add 3 different curves to track
85
- plt = fig.plot(x_name="samx", y_name="bpm4i")
86
- fig.plot(x_name="samx", y_name="bpm3a")
87
- fig.plot(x_name="samx", y_name="bpm4d")
88
-
89
- client = bec_client_lib
90
- dev = client.device_manager.devices
91
- scans = client.scans
92
- queue = client.queue
93
-
94
- status = scans.line_scan(dev.samx, -5, 5, steps=10, exp_time=0.05, relative=False)
95
- status.wait()
96
-
97
- last_scan_data = queue.scan_storage.storage[-1].data
98
-
99
- # get data from curves
100
- plt_data = plt.get_all_data()
101
-
102
- # check plotted data
103
- assert plt_data["bpm4i-bpm4i"]["x"] == last_scan_data["samx"]["samx"].val
104
- assert plt_data["bpm4i-bpm4i"]["y"] == last_scan_data["bpm4i"]["bpm4i"].val
105
- assert plt_data["bpm3a-bpm3a"]["x"] == last_scan_data["samx"]["samx"].val
106
- assert plt_data["bpm3a-bpm3a"]["y"] == last_scan_data["bpm3a"]["bpm3a"].val
107
- assert plt_data["bpm4d-bpm4d"]["x"] == last_scan_data["samx"]["samx"].val
108
- assert plt_data["bpm4d-bpm4d"]["y"] == last_scan_data["bpm4d"]["bpm4d"].val
109
-
110
-
111
- def test_rpc_image(rpc_server_figure, bec_client_lib):
112
- fig = BECFigure(rpc_server_figure)
113
-
114
- im = fig.image("eiger")
115
-
116
- client = bec_client_lib
117
- dev = client.device_manager.devices
118
- scans = client.scans
119
-
120
- status = scans.line_scan(dev.samx, -5, 5, steps=10, exp_time=0.05, relative=False)
121
- status.wait()
122
-
123
- last_image_device = client.connector.get_last(MessageEndpoints.device_monitor_2d("eiger"))[
124
- "data"
125
- ].data
126
- last_image_plot = im.images[0].get_data()
127
-
128
- # check plotted data
129
- np.testing.assert_equal(last_image_device, last_image_plot)
130
-
131
-
132
- def test_rpc_motor_map(rpc_server_figure, bec_client_lib):
133
- fig = BECFigure(rpc_server_figure)
134
-
135
- motor_map = fig.motor_map("samx", "samy")
136
-
137
- client = bec_client_lib
138
- dev = client.device_manager.devices
139
- scans = client.scans
140
-
141
- initial_pos_x = dev.samx.read()["samx"]["value"]
142
- initial_pos_y = dev.samy.read()["samy"]["value"]
143
-
144
- status = scans.mv(dev.samx, 1, dev.samy, 2, relative=True)
145
- status.wait()
146
-
147
- final_pos_x = dev.samx.read()["samx"]["value"]
148
- final_pos_y = dev.samy.read()["samy"]["value"]
149
-
150
- # check plotted data
151
- motor_map_data = motor_map.get_data()
152
-
153
- np.testing.assert_equal(
154
- [motor_map_data["x"][0], motor_map_data["y"][0]], [initial_pos_x, initial_pos_y]
155
- )
156
- np.testing.assert_equal(
157
- [motor_map_data["x"][-1], motor_map_data["y"][-1]], [final_pos_x, final_pos_y]
158
- )
159
-
160
-
161
- def test_dap_rpc(rpc_server_figure, bec_client_lib, qtbot):
162
-
163
- fig = BECFigure(rpc_server_figure)
164
- plt = fig.plot(x_name="samx", y_name="bpm4i", dap="GaussianModel")
165
-
166
- client = bec_client_lib
167
- dev = client.device_manager.devices
168
- scans = client.scans
169
-
170
- dev.bpm4i.sim.sim_select_model("GaussianModel")
171
- params = dev.bpm4i.sim.sim_params
172
- params.update(
173
- {"noise": "uniform", "noise_multiplier": 10, "center": 5, "sigma": 1, "amplitude": 200}
174
- )
175
- dev.bpm4i.sim.sim_params = params
176
- time.sleep(1)
177
-
178
- res = scans.line_scan(dev.samx, 0, 8, steps=50, relative=False)
179
- res.wait()
180
-
181
- # especially on slow machines, the fit might not be done yet
182
- # so we wait until the fit reaches the expected value
183
- def wait_for_fit():
184
- dap_curve = plt.get_curve("bpm4i-bpm4i-GaussianModel")
185
- fit_params = dap_curve.dap_params
186
- print(fit_params)
187
- return np.isclose(fit_params["center"], 5, atol=0.5)
188
-
189
- qtbot.waitUntil(wait_for_fit, timeout=10000)
190
-
191
-
192
- def test_removing_subplots(rpc_server_figure, bec_client_lib):
193
- fig = BECFigure(rpc_server_figure)
194
- plt = fig.plot(x_name="samx", y_name="bpm4i", dap="GaussianModel")
195
- im = fig.image(monitor="eiger")
196
- mm = fig.motor_map(motor_x="samx", motor_y="samy")
197
-
198
- assert len(fig.widget_list) == 3
199
-
200
- # removing curves
201
- assert len(plt.curves) == 2
202
- plt.curves[0].remove()
203
- assert len(plt.curves) == 1
204
- plt.remove_curve("bpm4i-bpm4i")
205
- assert len(plt.curves) == 0
206
-
207
- # removing all subplots from figure
208
- plt.remove()
209
- im.remove()
210
- mm.remove()
211
-
212
- assert len(fig.widget_list) == 0
@@ -1,40 +0,0 @@
1
- import pytest
2
-
3
- from bec_widgets.cli.client import BECFigure, BECImageShow, BECMotorMap, BECWaveform
4
-
5
-
6
- def test_rpc_register_list_connections(rpc_server_figure):
7
- fig = BECFigure(rpc_server_figure)
8
-
9
- plt = fig.plot(x_name="samx", y_name="bpm4i")
10
- im = fig.image("eiger")
11
- motor_map = fig.motor_map("samx", "samy")
12
- plt_z = fig.plot(x_name="samx", y_name="samy", z_name="bpm4i", new=True)
13
-
14
- # keep only class names from objects, since objects on server and client are different
15
- # so the best we can do is to compare types (rpc register is unit-tested elsewhere)
16
- all_connections = {obj_id: type(obj).__name__ for obj_id, obj in fig._get_all_rpc().items()}
17
-
18
- all_subwidgets_expected = {wid: type(widget).__name__ for wid, widget in fig.widgets.items()}
19
- curve_1D = fig.widgets[plt._rpc_id]
20
- curve_2D = fig.widgets[plt_z._rpc_id]
21
- curves_expected = {
22
- curve_1D._rpc_id: type(curve_1D).__name__,
23
- curve_2D._rpc_id: type(curve_2D).__name__,
24
- }
25
- curves_expected.update({curve._gui_id: type(curve).__name__ for curve in curve_1D.curves})
26
- curves_expected.update({curve._gui_id: type(curve).__name__ for curve in curve_2D.curves})
27
- fig_expected = {fig._rpc_id: type(fig).__name__}
28
- image_item_expected = {
29
- fig.widgets[im._rpc_id].images[0]._rpc_id: type(fig.widgets[im._rpc_id].images[0]).__name__
30
- }
31
-
32
- all_connections_expected = {
33
- **all_subwidgets_expected,
34
- **curves_expected,
35
- **fig_expected,
36
- **image_item_expected,
37
- }
38
-
39
- assert len(all_connections) == 8
40
- assert all_connections == all_connections_expected
@@ -1,71 +0,0 @@
1
- import time
2
-
3
- import pytest
4
-
5
- from bec_widgets.utils.widget_io import WidgetIO
6
- from bec_widgets.widgets.scan_control import ScanControl
7
-
8
-
9
- @pytest.fixture(scope="function")
10
- def scan_control(qtbot, bec_client_lib): # , mock_dev):
11
- widget = ScanControl(client=bec_client_lib)
12
- qtbot.addWidget(widget)
13
- qtbot.waitExposed(widget)
14
- yield widget
15
-
16
-
17
- def test_scan_control_populate_scans_e2e(scan_control):
18
- expected_scans = [
19
- "grid_scan",
20
- "fermat_scan",
21
- "round_scan",
22
- "cont_line_scan",
23
- "cont_line_fly_scan",
24
- "round_scan_fly",
25
- "round_roi_scan",
26
- "time_scan",
27
- "monitor_scan",
28
- "acquire",
29
- "line_scan",
30
- ]
31
- items = [
32
- scan_control.comboBox_scan_selection.itemText(i)
33
- for i in range(scan_control.comboBox_scan_selection.count())
34
- ]
35
- assert scan_control.comboBox_scan_selection.count() == len(expected_scans)
36
- assert sorted(items) == sorted(expected_scans)
37
-
38
-
39
- def test_run_line_scan_with_parameters_e2e(scan_control, bec_client_lib, qtbot):
40
- client = bec_client_lib
41
- queue = client.queue
42
-
43
- scan_name = "line_scan"
44
- kwargs = {"exp_time": 0.01, "steps": 10, "relative": True, "burst_at_each_point": 1}
45
- args = {"device": "samx", "start": -5, "stop": 5}
46
-
47
- scan_control.comboBox_scan_selection.setCurrentText(scan_name)
48
-
49
- # Set kwargs in the UI
50
- for kwarg_box in scan_control.kwarg_boxes:
51
- for widget in kwarg_box.widgets:
52
- for key, value in kwargs.items():
53
- if widget.arg_name == key:
54
- WidgetIO.set_value(widget, value)
55
- break
56
- # Set args in the UI
57
- for widget in scan_control.arg_box.widgets:
58
- for key, value in args.items():
59
- if widget.arg_name == key:
60
- WidgetIO.set_value(widget, value)
61
- break
62
-
63
- # Run the scan
64
- scan_control.button_run_scan.click()
65
- time.sleep(2)
66
-
67
- last_scan = queue.scan_storage.storage[-1]
68
- assert last_scan.status_message.info["scan_name"] == scan_name
69
- assert last_scan.status_message.info["exp_time"] == kwargs["exp_time"]
70
- assert last_scan.status_message.info["scan_motors"] == [args["device"]]
71
- assert last_scan.status_message.info["num_points"] == kwargs["steps"]
File without changes
@@ -1,189 +0,0 @@
1
- # pylint: disable = no-name-in-module,missing-class-docstring, missing-module-docstring
2
- from unittest.mock import MagicMock, patch
3
-
4
- import fakeredis
5
- import pytest
6
- from bec_lib.client import BECClient
7
- from bec_lib.device import Positioner, ReadoutPriority
8
- from bec_lib.devicemanager import DeviceContainer
9
- from bec_lib.redis_connector import RedisConnector
10
-
11
-
12
- class FakeDevice:
13
- """Fake minimal positioner class for testing."""
14
-
15
- def __init__(self, name, enabled=True, readout_priority=ReadoutPriority.MONITORED):
16
- self.name = name
17
- self.enabled = enabled
18
- self.signals = {self.name: {"value": 1.0}}
19
- self.description = {self.name: {"source": self.name, "dtype": "number", "shape": []}}
20
- self.readout_priority = readout_priority
21
- self._config = {
22
- "readoutPriority": "baseline",
23
- "deviceClass": "ophyd_devices.SimPositioner",
24
- "deviceConfig": {
25
- "delay": 1,
26
- "limits": [-50, 50],
27
- "tolerance": 0.01,
28
- "update_frequency": 400,
29
- },
30
- "deviceTags": ["user motors"],
31
- "enabled": enabled,
32
- "readOnly": False,
33
- "name": self.name,
34
- }
35
-
36
- def __contains__(self, item):
37
- return item == self.name
38
-
39
- @property
40
- def _hints(self):
41
- return [self.name]
42
-
43
- def set_value(self, fake_value: float = 1.0) -> None:
44
- """
45
- Setup fake value for device readout
46
- Args:
47
- fake_value(float): Desired fake value
48
- """
49
- self.signals[self.name]["value"] = fake_value
50
-
51
- def describe(self) -> dict:
52
- """
53
- Get the description of the device
54
- Returns:
55
- dict: Description of the device
56
- """
57
- return self.description
58
-
59
-
60
- class FakePositioner(FakeDevice):
61
- def __init__(
62
- self,
63
- name,
64
- enabled=True,
65
- limits=None,
66
- read_value=1.0,
67
- readout_priority=ReadoutPriority.MONITORED,
68
- ):
69
- super().__init__(name, enabled, readout_priority)
70
- self.limits = limits if limits is not None else [0, 0]
71
- self.read_value = read_value
72
- self.name = name
73
-
74
- @property
75
- def precision(self):
76
- return 3
77
-
78
- def set_read_value(self, value):
79
- self.read_value = value
80
-
81
- def read(self):
82
- return {
83
- self.name: {"value": self.read_value},
84
- f"{self.name}_setpoint": {"value": self.read_value},
85
- f"{self.name}_motor_is_moving": {"value": 0},
86
- }
87
-
88
- def set_limits(self, limits):
89
- self.limits = limits
90
-
91
- def move(self, value, relative=False):
92
- """Simulates moving the device to a new position."""
93
- if relative:
94
- self.read_value += value
95
- else:
96
- self.read_value = value
97
- # Respect the limits
98
- self.read_value = max(min(self.read_value, self.limits[1]), self.limits[0])
99
-
100
- @property
101
- def readback(self):
102
- return MagicMock(get=MagicMock(return_value=self.read_value))
103
-
104
-
105
- class Positioner(FakePositioner):
106
- """just placeholder for testing embedded isinstance check in DeviceCombobox"""
107
-
108
- def __init__(self, name="test", limits=None, read_value=1.0):
109
- super().__init__(name, limits, read_value)
110
-
111
-
112
- class Device(FakeDevice):
113
- """just placeholder for testing embedded isinstance check in DeviceCombobox"""
114
-
115
- def __init__(self, name, enabled=True):
116
- super().__init__(name, enabled)
117
-
118
-
119
- class DMMock:
120
- def __init__(self):
121
- self.devices = DeviceContainer()
122
-
123
- def add_devives(self, devices: list):
124
- for device in devices:
125
- self.devices[device.name] = device
126
-
127
-
128
- DEVICES = [
129
- FakePositioner("samx", limits=[-10, 10], read_value=2.0),
130
- FakePositioner("samy", limits=[-5, 5], read_value=3.0),
131
- FakePositioner("samz", limits=[-8, 8], read_value=4.0),
132
- FakePositioner("aptrx", limits=None, read_value=4.0),
133
- FakePositioner("aptry", limits=None, read_value=5.0),
134
- FakeDevice("gauss_bpm"),
135
- FakeDevice("gauss_adc1"),
136
- FakeDevice("gauss_adc2"),
137
- FakeDevice("gauss_adc3"),
138
- FakeDevice("bpm4i"),
139
- FakeDevice("bpm3a"),
140
- FakeDevice("bpm3i"),
141
- FakeDevice("eiger"),
142
- FakeDevice("async_device", readout_priority=ReadoutPriority.ASYNC),
143
- Positioner("test", limits=[-10, 10], read_value=2.0),
144
- Device("test_device"),
145
- ]
146
-
147
-
148
- def fake_redis_server(host, port):
149
- redis = fakeredis.FakeRedis()
150
- return redis
151
-
152
-
153
- @pytest.fixture(scope="function")
154
- def mocked_client(bec_dispatcher):
155
- connector = RedisConnector("localhost:1", redis_cls=fake_redis_server)
156
- # Create a MagicMock object
157
- client = MagicMock() # TODO change to real BECClient
158
-
159
- # Shutdown the original client
160
- bec_dispatcher.client.shutdown()
161
- # Mock the connector attribute
162
- bec_dispatcher.client = client
163
-
164
- # Mock the device_manager.devices attribute
165
- client.connector = connector
166
- client.device_manager = DMMock()
167
- client.device_manager.add_devives(DEVICES)
168
-
169
- def mock_mv(*args, relative=False):
170
- # Extracting motor and value pairs
171
- for i in range(0, len(args), 2):
172
- motor = args[i]
173
- value = args[i + 1]
174
- motor.move(value, relative=relative)
175
- return MagicMock(wait=MagicMock())
176
-
177
- client.scans = MagicMock(mv=mock_mv)
178
-
179
- # Ensure isinstance check for Positioner passes
180
- original_isinstance = isinstance
181
-
182
- def isinstance_mock(obj, class_info):
183
- if class_info == Positioner and isinstance(obj, FakePositioner):
184
- return True
185
- return original_isinstance(obj, class_info)
186
-
187
- with patch("builtins.isinstance", new=isinstance_mock):
188
- yield client
189
- connector.shutdown() # TODO change to real BECClient
@@ -1,64 +0,0 @@
1
- import pytest
2
- from pytestqt.exceptions import TimeoutError as QtBotTimeoutError
3
- from qtpy.QtWidgets import QApplication
4
-
5
- from bec_widgets.cli.rpc_register import RPCRegister
6
- from bec_widgets.qt_utils import error_popups
7
- from bec_widgets.utils import bec_dispatcher as bec_dispatcher_module
8
-
9
-
10
- @pytest.fixture(autouse=True)
11
- def qapplication(qtbot): # pylint: disable=unused-argument
12
- yield
13
-
14
- qapp = QApplication.instance()
15
- # qapp.quit()
16
- qapp.processEvents()
17
- try:
18
- qtbot.waitUntil(lambda: qapp.topLevelWidgets() == [])
19
- except QtBotTimeoutError as exc:
20
- raise TimeoutError(f"Failed to close all widgets: {qapp.topLevelWidgets()}") from exc
21
-
22
-
23
- @pytest.fixture(autouse=True)
24
- def rpc_register():
25
- yield RPCRegister()
26
- RPCRegister.reset_singleton()
27
-
28
-
29
- @pytest.fixture(autouse=True)
30
- def bec_dispatcher(threads_check): # pylint: disable=unused-argument
31
- bec_dispatcher = bec_dispatcher_module.BECDispatcher()
32
- yield bec_dispatcher
33
- bec_dispatcher.disconnect_all()
34
- # clean BEC client
35
- bec_dispatcher.client.shutdown()
36
- # reinitialize singleton for next test
37
- bec_dispatcher_module.BECDispatcher.reset_singleton()
38
-
39
-
40
- @pytest.fixture(autouse=True)
41
- def clean_singleton():
42
- error_popups._popup_utility_instance = None
43
-
44
-
45
- def create_widget(qtbot, widget, *args, **kwargs):
46
- """
47
- Create a widget and add it to the qtbot for testing. This is a helper function that
48
- should be used in all tests that require a widget to be created.
49
- DO NOT CREATE WIDGETS DIRECTLY IN A FIXTURE!
50
-
51
- Args:
52
- qtbot (fixture): pytest-qt fixture
53
- widget (QWidget): widget class to be created
54
- *args: positional arguments for the widget
55
- **kwargs: keyword arguments for the widget
56
-
57
- Returns:
58
- QWidget: the created widget
59
-
60
- """
61
- widget = widget(*args, **kwargs)
62
- qtbot.addWidget(widget)
63
- qtbot.waitExposed(widget)
64
- return widget
@@ -1,80 +0,0 @@
1
- # pylint: disable = no-name-in-module,missing-class-docstring, missing-module-docstring
2
- import time
3
-
4
- import pytest
5
- from qtpy.QtWidgets import QApplication
6
-
7
- from bec_widgets.qt_utils.error_popups import SafeSlot as Slot
8
- from bec_widgets.utils import BECConnector, ConnectionConfig
9
-
10
- from .client_mocks import mocked_client
11
-
12
-
13
- @pytest.fixture
14
- def bec_connector(mocked_client):
15
- connector = BECConnector(client=mocked_client)
16
- return connector
17
-
18
-
19
- def test_bec_connector_init(bec_connector):
20
- assert bec_connector is not None
21
- assert bec_connector.client is not None
22
- assert isinstance(bec_connector, BECConnector)
23
- assert bec_connector.config.widget_class == "BECConnector"
24
-
25
-
26
- def test_bec_connector_init_with_gui_id(mocked_client):
27
- bc = BECConnector(client=mocked_client, gui_id="test_gui_id")
28
- assert bc.config.gui_id == "test_gui_id"
29
- assert bc.gui_id == "test_gui_id"
30
-
31
-
32
- def test_bec_connector_set_gui_id(bec_connector):
33
- bec_connector.set_gui_id("test_gui_id")
34
- assert bec_connector.config.gui_id == "test_gui_id"
35
-
36
-
37
- def test_bec_connector_change_config(bec_connector):
38
- bec_connector.on_config_update({"gui_id": "test_gui_id"})
39
- assert bec_connector.config.gui_id == "test_gui_id"
40
-
41
-
42
- def test_bec_connector_get_obj_by_id(bec_connector):
43
- bec_connector.set_gui_id("test_gui_id")
44
- assert bec_connector.get_obj_by_id("test_gui_id") == bec_connector
45
- assert bec_connector.get_obj_by_id("test_gui_id_2") is None
46
-
47
-
48
- def test_bec_connector_update_client(bec_connector, mocked_client):
49
- client_new = mocked_client
50
- bec_connector.update_client(client_new)
51
- assert bec_connector.client == client_new
52
- assert bec_connector.dev is not None
53
- assert bec_connector.scans is not None
54
- assert bec_connector.queue is not None
55
- assert bec_connector.scan_storage is not None
56
- assert bec_connector.dap is not None
57
-
58
-
59
- def test_bec_connector_get_config(bec_connector):
60
- assert bec_connector.get_config(dict_output=False) == bec_connector.config
61
- assert bec_connector.get_config() == bec_connector.config.model_dump()
62
-
63
-
64
- def test_bec_connector_submit_task(bec_connector):
65
- def test_func():
66
- time.sleep(2)
67
- print("done")
68
-
69
- completed = False
70
-
71
- @Slot()
72
- def complete_func():
73
- nonlocal completed
74
- completed = True
75
-
76
- bec_connector.submit_task(test_func, on_complete=complete_func)
77
- assert not completed
78
- while not completed:
79
- QApplication.processEvents()
80
- time.sleep(0.1)