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,712 +0,0 @@
1
- # pylint: disable=missing-function-docstring, missing-module-docstring, unused-import
2
- from unittest import mock
3
-
4
- import numpy as np
5
- import pytest
6
-
7
- from bec_widgets.widgets.figure import BECFigure
8
- from bec_widgets.widgets.figure.plots.waveform.waveform_curve import CurveConfig, Signal, SignalData
9
-
10
- from .client_mocks import mocked_client
11
- from .conftest import create_widget
12
-
13
-
14
- def test_adding_curve_to_waveform(qtbot, mocked_client):
15
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
16
- w1 = bec_figure.plot()
17
-
18
- # adding curve which is in bec - only names
19
- c1 = w1.add_curve_bec(x_name="samx", y_name="bpm4i")
20
- assert c1.config.label == "bpm4i-bpm4i"
21
-
22
- # adding curve which is in bec - names and entry
23
- c2 = w1.add_curve_bec(x_name="samx", x_entry="samx", y_name="bpm3a", y_entry="bpm3a")
24
- assert c2.config.label == "bpm3a-bpm3a"
25
-
26
- # adding curve which is not in bec
27
- with pytest.raises(ValueError) as excinfo:
28
- w1.add_curve_bec(x_name="non_existent_device", y_name="non_existent_device")
29
- assert "Device 'non_existent_device' not found in current BEC session" in str(excinfo.value)
30
-
31
- # adding wrong entry for samx
32
- with pytest.raises(ValueError) as excinfo:
33
- w1.add_curve_bec(
34
- x_name="samx", x_entry="non_existent_entry", y_name="bpm3a", y_entry="bpm3a"
35
- )
36
- assert "Entry 'non_existent_entry' not found in device 'samx' signals" in str(excinfo.value)
37
-
38
- # adding wrong device with validation switched off
39
- c3 = w1.add_curve_bec(x_name="samx", y_name="non_existent_device", validate_bec=False)
40
- assert c3.config.label == "non_existent_device-non_existent_device"
41
-
42
-
43
- def test_adding_curve_with_same_id(qtbot, mocked_client):
44
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
45
- w1 = bec_figure.plot()
46
- c1 = w1.add_curve_bec(x_name="samx", y_name="bpm4i", gui_id="test_curve")
47
-
48
- with pytest.raises(ValueError) as excinfo:
49
- w1.add_curve_bec(x_name="samx", y_name="bpm4i", gui_id="test_curve")
50
- assert "Curve with ID 'test_curve' already exists." in str(excinfo.value)
51
-
52
-
53
- def test_create_waveform1D_by_config(qtbot, mocked_client):
54
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
55
- w1_config_input = {
56
- "widget_class": "BECWaveform",
57
- "gui_id": "widget_1",
58
- "parent_id": "BECFigure_1708689320.788527",
59
- "row": 0,
60
- "col": 0,
61
- "axis": {
62
- "title": "Widget 1",
63
- "title_size": None,
64
- "x_label": None,
65
- "x_label_size": None,
66
- "y_label": None,
67
- "y_label_size": None,
68
- "legend_label_size": None,
69
- "x_scale": "linear",
70
- "y_scale": "linear",
71
- "x_lim": (1, 10),
72
- "y_lim": None,
73
- "x_grid": False,
74
- "y_grid": False,
75
- },
76
- "color_palette": "plasma",
77
- "curves": {
78
- "bpm4i-bpm4i": {
79
- "widget_class": "BECCurve",
80
- "gui_id": "BECCurve_1708689321.226847",
81
- "parent_id": "widget_1",
82
- "label": "bpm4i-bpm4i",
83
- "color": "#cc4778",
84
- "color_map_z": "plasma",
85
- "symbol": "o",
86
- "symbol_color": None,
87
- "symbol_size": 5,
88
- "pen_width": 2,
89
- "pen_style": "dash",
90
- "source": "scan_segment",
91
- "signals": {
92
- "dap": None,
93
- "source": "scan_segment",
94
- "x": {
95
- "name": "samx",
96
- "entry": "samx",
97
- "unit": None,
98
- "modifier": None,
99
- "limits": None,
100
- },
101
- "y": {
102
- "name": "bpm4i",
103
- "entry": "bpm4i",
104
- "unit": None,
105
- "modifier": None,
106
- "limits": None,
107
- },
108
- "z": None,
109
- },
110
- },
111
- "curve-custom": {
112
- "widget_class": "BECCurve",
113
- "gui_id": "BECCurve_1708689321.22867",
114
- "parent_id": "widget_1",
115
- "label": "curve-custom",
116
- "color": "blue",
117
- "color_map_z": "plasma",
118
- "symbol": "o",
119
- "symbol_color": None,
120
- "symbol_size": 5,
121
- "pen_width": 2,
122
- "pen_style": "dashdot",
123
- "source": "custom",
124
- "signals": None,
125
- },
126
- },
127
- }
128
-
129
- w1 = bec_figure.plot(config=w1_config_input)
130
-
131
- w1_config_output = w1.get_config()
132
- w1_config_input["gui_id"] = w1.gui_id
133
-
134
- assert w1_config_input == w1_config_output
135
- assert w1.plot_item.titleLabel.text == "Widget 1"
136
- assert w1.config.axis.title == "Widget 1"
137
-
138
-
139
- def test_change_gui_id(qtbot, mocked_client):
140
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
141
- w1 = bec_figure.plot()
142
- c1 = w1.add_curve_bec(x_name="samx", y_name="bpm4i")
143
- w1.change_gui_id("new_id")
144
-
145
- assert w1.config.gui_id == "new_id"
146
- assert c1.config.parent_id == "new_id"
147
-
148
-
149
- def test_getting_curve(qtbot, mocked_client):
150
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
151
- w1 = bec_figure.plot()
152
- c1 = w1.add_curve_bec(x_name="samx", y_name="bpm4i", gui_id="test_curve")
153
- c1_expected_config = CurveConfig(
154
- widget_class="BECCurve",
155
- gui_id="test_curve",
156
- parent_id=w1.gui_id,
157
- label="bpm4i-bpm4i",
158
- color="#cc4778",
159
- symbol="o",
160
- symbol_color=None,
161
- symbol_size=5,
162
- pen_width=2,
163
- pen_style="solid",
164
- source="scan_segment",
165
- signals=Signal(
166
- source="scan_segment",
167
- x=SignalData(name="samx", entry="samx", unit=None, modifier=None),
168
- y=SignalData(name="bpm4i", entry="bpm4i", unit=None, modifier=None),
169
- ),
170
- )
171
-
172
- assert w1.curves[0].config == c1_expected_config
173
- assert w1._curves_data["scan_segment"]["bpm4i-bpm4i"].config == c1_expected_config
174
- assert w1.get_curve(0).config == c1_expected_config
175
- assert w1.get_curve_config("bpm4i-bpm4i", dict_output=True) == c1_expected_config.model_dump()
176
- assert w1.get_curve_config("bpm4i-bpm4i", dict_output=False) == c1_expected_config
177
- assert w1.get_curve("bpm4i-bpm4i").config == c1_expected_config
178
- assert c1.get_config(False) == c1_expected_config
179
- assert c1.get_config() == c1_expected_config.model_dump()
180
-
181
-
182
- def test_getting_curve_errors(qtbot, mocked_client):
183
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
184
- w1 = bec_figure.plot()
185
- c1 = w1.add_curve_bec(x_name="samx", y_name="bpm4i", gui_id="test_curve")
186
-
187
- with pytest.raises(ValueError) as excinfo:
188
- w1.get_curve("non_existent_curve")
189
- assert "Curve with ID 'non_existent_curve' not found." in str(excinfo.value)
190
- with pytest.raises(IndexError) as excinfo:
191
- w1.get_curve(1)
192
- assert "list index out of range" in str(excinfo.value)
193
- with pytest.raises(ValueError) as excinfo:
194
- w1.get_curve(1.2)
195
- assert "Identifier must be either an integer (index) or a string (curve_id)." in str(
196
- excinfo.value
197
- )
198
-
199
-
200
- def test_add_curve(qtbot, mocked_client):
201
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
202
- w1 = bec_figure.plot()
203
-
204
- c1 = w1.add_curve_bec(x_name="samx", y_name="bpm4i")
205
-
206
- assert len(w1.curves) == 1
207
- assert w1._curves_data["scan_segment"] == {"bpm4i-bpm4i": c1}
208
- assert c1.config.label == "bpm4i-bpm4i"
209
- assert c1.config.source == "scan_segment"
210
-
211
-
212
- def test_change_legend_font_size(qtbot, mocked_client):
213
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
214
- plot = bec_figure.plot()
215
-
216
- w1 = plot.add_curve_bec(x_name="samx", y_name="bpm4i")
217
- my_func = plot.plot_item.legend
218
- with mock.patch.object(my_func, "setScale") as mock_set_scale:
219
- plot.set_legend_label_size(18)
220
- assert plot.config.axis.legend_label_size == 18
221
- assert mock_set_scale.call_count == 1
222
- assert mock_set_scale.call_args == mock.call(2)
223
-
224
-
225
- def test_remove_curve(qtbot, mocked_client):
226
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
227
- w1 = bec_figure.plot()
228
-
229
- w1.add_curve_bec(x_name="samx", y_name="bpm4i")
230
- w1.add_curve_bec(x_name="samx", y_name="bpm3a")
231
- w1.remove_curve(0)
232
- w1.remove_curve("bpm3a-bpm3a")
233
-
234
- assert len(w1.plot_item.curves) == 0
235
- assert w1._curves_data["scan_segment"] == {}
236
-
237
- with pytest.raises(ValueError) as excinfo:
238
- w1.remove_curve(1.2)
239
- assert "Each identifier must be either an integer (index) or a string (curve_id)." in str(
240
- excinfo.value
241
- )
242
-
243
-
244
- def test_change_curve_appearance_methods(qtbot, mocked_client):
245
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
246
- w1 = bec_figure.plot()
247
-
248
- c1 = w1.add_curve_bec(x_name="samx", y_name="bpm4i")
249
-
250
- c1.set_color("#0000ff")
251
- c1.set_symbol("x")
252
- c1.set_symbol_color("#ff0000")
253
- c1.set_symbol_size(10)
254
- c1.set_pen_width(3)
255
- c1.set_pen_style("dashdot")
256
-
257
- qtbot.wait(500)
258
- assert c1.config.color == "#0000ff"
259
- assert c1.config.symbol == "x"
260
- assert c1.config.symbol_color == "#ff0000"
261
- assert c1.config.symbol_size == 10
262
- assert c1.config.pen_width == 3
263
- assert c1.config.pen_style == "dashdot"
264
- assert c1.config.source == "scan_segment"
265
- assert c1.config.signals.model_dump() == {
266
- "dap": None,
267
- "source": "scan_segment",
268
- "x": {"name": "samx", "entry": "samx", "unit": None, "modifier": None, "limits": None},
269
- "y": {"name": "bpm4i", "entry": "bpm4i", "unit": None, "modifier": None, "limits": None},
270
- "z": None,
271
- }
272
-
273
-
274
- def test_change_curve_appearance_args(qtbot, mocked_client):
275
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
276
- w1 = bec_figure.plot()
277
-
278
- c1 = w1.add_curve_bec(x_name="samx", y_name="bpm4i")
279
-
280
- c1.set(
281
- color="#0000ff",
282
- symbol="x",
283
- symbol_color="#ff0000",
284
- symbol_size=10,
285
- pen_width=3,
286
- pen_style="dashdot",
287
- )
288
-
289
- assert c1.config.color == "#0000ff"
290
- assert c1.config.symbol == "x"
291
- assert c1.config.symbol_color == "#ff0000"
292
- assert c1.config.symbol_size == 10
293
- assert c1.config.pen_width == 3
294
- assert c1.config.pen_style == "dashdot"
295
- assert c1.config.source == "scan_segment"
296
- assert c1.config.signals.model_dump() == {
297
- "dap": None,
298
- "source": "scan_segment",
299
- "x": {"name": "samx", "entry": "samx", "unit": None, "modifier": None, "limits": None},
300
- "y": {"name": "bpm4i", "entry": "bpm4i", "unit": None, "modifier": None, "limits": None},
301
- "z": None,
302
- }
303
-
304
-
305
- def test_set_custom_curve_data(qtbot, mocked_client):
306
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
307
- w1 = bec_figure.plot()
308
-
309
- c1 = w1.add_curve_custom(
310
- x=[1, 2, 3],
311
- y=[4, 5, 6],
312
- label="custom_curve",
313
- color="#0000ff",
314
- symbol="x",
315
- symbol_color="#ff0000",
316
- symbol_size=10,
317
- pen_width=3,
318
- pen_style="dashdot",
319
- )
320
-
321
- x_init, y_init = c1.get_data()
322
-
323
- assert np.array_equal(x_init, [1, 2, 3])
324
- assert np.array_equal(y_init, [4, 5, 6])
325
- assert c1.config.label == "custom_curve"
326
- assert c1.config.color == "#0000ff"
327
- assert c1.config.symbol == "x"
328
- assert c1.config.symbol_color == "#ff0000"
329
- assert c1.config.symbol_size == 10
330
- assert c1.config.pen_width == 3
331
- assert c1.config.pen_style == "dashdot"
332
- assert c1.config.source == "custom"
333
- assert c1.config.signals == None
334
-
335
- c1.set_data(x=[4, 5, 6], y=[7, 8, 9])
336
-
337
- x_new, y_new = c1.get_data()
338
- assert np.array_equal(x_new, [4, 5, 6])
339
- assert np.array_equal(y_new, [7, 8, 9])
340
-
341
-
342
- def test_custom_data_2D_array(qtbot, mocked_client):
343
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
344
-
345
- data = np.random.rand(10, 2)
346
-
347
- plt = bec_figure.plot(data)
348
-
349
- x, y = plt.curves[0].get_data()
350
-
351
- assert np.array_equal(x, data[:, 0])
352
- assert np.array_equal(y, data[:, 1])
353
-
354
-
355
- def test_get_all_data(qtbot, mocked_client):
356
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
357
- w1 = bec_figure.plot()
358
-
359
- c1 = w1.add_curve_custom(
360
- x=[1, 2, 3],
361
- y=[4, 5, 6],
362
- label="custom_curve-1",
363
- color="#0000ff",
364
- symbol="x",
365
- symbol_color="#ff0000",
366
- symbol_size=10,
367
- pen_width=3,
368
- pen_style="dashdot",
369
- )
370
-
371
- c2 = w1.add_curve_custom(
372
- x=[4, 5, 6],
373
- y=[7, 8, 9],
374
- label="custom_curve-2",
375
- color="#00ff00",
376
- symbol="o",
377
- symbol_color="#00ff00",
378
- symbol_size=20,
379
- pen_width=4,
380
- pen_style="dash",
381
- )
382
-
383
- all_data = w1.get_all_data()
384
-
385
- assert all_data == {
386
- "custom_curve-1": {"x": [1, 2, 3], "y": [4, 5, 6]},
387
- "custom_curve-2": {"x": [4, 5, 6], "y": [7, 8, 9]},
388
- }
389
-
390
-
391
- def test_curve_add_by_config(qtbot, mocked_client):
392
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
393
- w1 = bec_figure.plot()
394
-
395
- c1_config_input = {
396
- "widget_class": "BECCurve",
397
- "gui_id": "BECCurve_1708689321.226847",
398
- "parent_id": "widget_1",
399
- "label": "bpm4i-bpm4i",
400
- "color": "#cc4778",
401
- "color_map_z": "plasma",
402
- "symbol": "o",
403
- "symbol_color": None,
404
- "symbol_size": 5,
405
- "pen_width": 2,
406
- "pen_style": "dash",
407
- "source": "scan_segment",
408
- "signals": {
409
- "dap": None,
410
- "source": "scan_segment",
411
- "x": {"name": "samx", "entry": "samx", "unit": None, "modifier": None, "limits": None},
412
- "y": {
413
- "name": "bpm4i",
414
- "entry": "bpm4i",
415
- "unit": None,
416
- "modifier": None,
417
- "limits": None,
418
- },
419
- "z": None,
420
- },
421
- }
422
-
423
- c1 = w1.add_curve_by_config(c1_config_input)
424
-
425
- c1_config_dict = c1.get_config()
426
-
427
- assert c1_config_dict == c1_config_input
428
- assert c1.config == CurveConfig(**c1_config_input)
429
- assert c1.get_config(False) == CurveConfig(**c1_config_input)
430
-
431
-
432
- def test_scan_update(qtbot, mocked_client):
433
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
434
- w1 = bec_figure.plot()
435
-
436
- c1 = w1.add_curve_bec(x_name="samx", y_name="bpm4i")
437
-
438
- msg_waveform = {
439
- "data": {
440
- "samx": {"samx": {"value": 10}},
441
- "bpm4i": {"bpm4i": {"value": 5}},
442
- "gauss_bpm": {"gauss_bpm": {"value": 6}},
443
- "gauss_adc1": {"gauss_adc1": {"value": 8}},
444
- "gauss_adc2": {"gauss_adc2": {"value": 9}},
445
- },
446
- "scan_id": 1,
447
- }
448
- # Mock scan_storage.find_scan_by_ID
449
- mock_scan_data_waveform = mock.MagicMock()
450
- mock_scan_data_waveform.data = {
451
- device_name: {
452
- entry: mock.MagicMock(val=[msg_waveform["data"][device_name][entry]["value"]])
453
- for entry in msg_waveform["data"][device_name]
454
- }
455
- for device_name in msg_waveform["data"]
456
- }
457
-
458
- metadata_waveform = {"scan_name": "line_scan"}
459
-
460
- w1.queue.scan_storage.find_scan_by_ID.return_value = mock_scan_data_waveform
461
-
462
- w1.on_scan_segment(msg_waveform, metadata_waveform)
463
- qtbot.wait(500)
464
- assert c1.get_data() == ([10], [5])
465
-
466
-
467
- def test_scan_history_with_val_access(qtbot, mocked_client):
468
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
469
- w1 = bec_figure.plot()
470
-
471
- w1.plot(x_name="samx", y_name="bpm4i")
472
-
473
- mock_scan_data = {
474
- "samx": {"samx": mock.MagicMock(val=np.array([1, 2, 3]))}, # Use mock.MagicMock for .val
475
- "bpm4i": {"bpm4i": mock.MagicMock(val=np.array([4, 5, 6]))}, # Use mock.MagicMock for .val
476
- }
477
-
478
- mock_scan_storage = mock.MagicMock()
479
- mock_scan_storage.find_scan_by_ID.return_value = mock.MagicMock(data=mock_scan_data)
480
- w1.queue.scan_storage = mock_scan_storage
481
-
482
- fake_scan_id = "fake_scan_id"
483
- w1.scan_history(scan_id=fake_scan_id)
484
-
485
- qtbot.wait(500)
486
-
487
- x_data, y_data = w1.curves[0].get_data()
488
-
489
- assert np.array_equal(x_data, [1, 2, 3])
490
- assert np.array_equal(y_data, [4, 5, 6])
491
-
492
-
493
- def test_scatter_2d_update(qtbot, mocked_client):
494
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
495
- w1 = bec_figure.plot()
496
-
497
- c1 = w1.add_curve_bec(x_name="samx", y_name="samx", z_name="bpm4i")
498
-
499
- msg = {
500
- "data": {
501
- "samx": {"samx": {"value": [1, 2, 3]}},
502
- "samy": {"samy": {"value": [4, 5, 6]}},
503
- "bpm4i": {"bpm4i": {"value": [1, 3, 2]}},
504
- },
505
- "scan_id": 1,
506
- }
507
- msg_metadata = {"scan_name": "line_scan"}
508
-
509
- mock_scan_item = mock.MagicMock()
510
- mock_scan_item.data = {
511
- device_name: {
512
- entry: mock.MagicMock(val=msg["data"][device_name][entry]["value"])
513
- for entry in msg["data"][device_name]
514
- }
515
- for device_name in msg["data"]
516
- }
517
-
518
- w1.queue.scan_storage.find_scan_by_ID.return_value = mock_scan_item
519
-
520
- w1.on_scan_segment(msg, msg_metadata)
521
- qtbot.wait(500)
522
-
523
- data = c1.get_data()
524
- expected_x_y_data = ([1, 2, 3], [1, 2, 3])
525
- expected_z_colors = w1._make_z_gradient([1, 3, 2], "plasma")
526
-
527
- scatter_points = c1.scatter.points()
528
- colors = [point.brush().color() for point in scatter_points]
529
-
530
- assert np.array_equal(data, expected_x_y_data)
531
- assert colors == expected_z_colors
532
-
533
-
534
- def test_waveform_single_arg_inputs(qtbot, mocked_client):
535
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
536
- w1 = bec_figure.plot()
537
-
538
- w1.plot("bpm4i")
539
- w1.plot([1, 2, 3], label="just_y")
540
- w1.plot([3, 4, 5], [7, 8, 9], label="x_y")
541
- w1.plot(x=[1, 2, 3], y=[4, 5, 6], label="x_y_kwargs")
542
- data_array_1D = np.random.rand(10)
543
- data_array_2D = np.random.rand(10, 2)
544
- w1.plot(data_array_1D, label="np_ndarray 1D")
545
- w1.plot(data_array_2D, label="np_ndarray 2D")
546
-
547
- qtbot.wait(200)
548
-
549
- assert w1._curves_data["scan_segment"]["bpm4i-bpm4i"].config.label == "bpm4i-bpm4i"
550
- assert w1._curves_data["custom"]["just_y"].config.label == "just_y"
551
- assert w1._curves_data["custom"]["x_y"].config.label == "x_y"
552
- assert w1._curves_data["custom"]["x_y_kwargs"].config.label == "x_y_kwargs"
553
-
554
- assert np.array_equal(w1._curves_data["custom"]["just_y"].get_data(), ([0, 1, 2], [1, 2, 3]))
555
- assert np.array_equal(w1._curves_data["custom"]["just_y"].get_data(), ([0, 1, 2], [1, 2, 3]))
556
- assert np.array_equal(w1._curves_data["custom"]["x_y"].get_data(), ([3, 4, 5], [7, 8, 9]))
557
- assert np.array_equal(
558
- w1._curves_data["custom"]["x_y_kwargs"].get_data(), ([1, 2, 3], [4, 5, 6])
559
- )
560
- assert np.array_equal(
561
- w1._curves_data["custom"]["np_ndarray 1D"].get_data(),
562
- (np.arange(data_array_1D.size), data_array_1D.T),
563
- )
564
- assert np.array_equal(w1._curves_data["custom"]["np_ndarray 2D"].get_data(), data_array_2D.T)
565
-
566
-
567
- def test_waveform_set_x_sync(qtbot, mocked_client):
568
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
569
- w1 = bec_figure.plot()
570
- custom_label = "custom_label"
571
- w1.plot("bpm4i")
572
- w1.set_x_label(custom_label)
573
-
574
- scan_item_mock = mock.MagicMock()
575
- mock_data = {
576
- "samx": {"samx": mock.MagicMock(val=np.array([1, 2, 3]))},
577
- "samy": {"samy": mock.MagicMock(val=np.array([4, 5, 6]))},
578
- "bpm4i": {
579
- "bpm4i": mock.MagicMock(
580
- val=np.array([7, 8, 9]),
581
- timestamps=np.array([1720520189.959115, 1720520189.986618, 1720520190.0157812]),
582
- )
583
- },
584
- }
585
-
586
- scan_item_mock.data = mock_data
587
- scan_item_mock.status_message.info = {"scan_report_devices": ["samx"]}
588
-
589
- w1.queue.scan_storage.find_scan_by_ID.return_value = scan_item_mock
590
-
591
- w1.on_scan_segment({"scan_id": 1}, {})
592
- qtbot.wait(200)
593
-
594
- # Best effort - samx
595
- x_data, y_data = w1.curves[0].get_data()
596
- assert np.array_equal(x_data, [1, 2, 3])
597
- assert np.array_equal(y_data, [7, 8, 9])
598
- assert w1.plot_item.getAxis("bottom").labelText == custom_label + " [auto: samx-samx]"
599
-
600
- # Change to samy
601
- w1.set_x("samy")
602
- qtbot.wait(200)
603
- x_data, y_data = w1.curves[0].get_data()
604
- assert np.array_equal(x_data, [4, 5, 6])
605
- assert np.array_equal(y_data, [7, 8, 9])
606
- assert w1.plot_item.getAxis("bottom").labelText == custom_label + " [samy-samy]"
607
-
608
- # change to index
609
- w1.set_x("index")
610
- qtbot.wait(200)
611
- x_data, y_data = w1.curves[0].get_data()
612
- assert np.array_equal(x_data, [0, 1, 2])
613
- assert np.array_equal(y_data, [7, 8, 9])
614
- assert w1.plot_item.getAxis("bottom").labelText == custom_label + " [index]"
615
-
616
- # change to timestamp
617
- w1.set_x("timestamp")
618
- qtbot.wait(200)
619
- x_data, y_data = w1.curves[0].get_data()
620
- assert np.allclose(x_data, np.array([1.72052019e09, 1.72052019e09, 1.72052019e09]))
621
- assert np.array_equal(y_data, [7, 8, 9])
622
- assert w1.plot_item.getAxis("bottom").labelText == custom_label + " [timestamp]"
623
-
624
-
625
- def test_waveform_async_data_update(qtbot, mocked_client):
626
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
627
- w1 = bec_figure.plot("async_device")
628
- custom_label = "custom_label"
629
- w1.set_x_label(custom_label)
630
-
631
- # scan_item_mock = mock.MagicMock()
632
- # mock_data = {
633
- # "async_device": {
634
- # "async_device": mock.MagicMock(
635
- # val=np.array([7, 8, 9]),
636
- # timestamps=np.array([1720520189.959115, 1720520189.986618, 1720520190.0157812]),
637
- # )
638
- # }
639
- # }
640
- #
641
- # scan_item_mock.async_data = mock_data
642
- # w1.queue.scan_storage.find_scan_by_ID.return_value = scan_item_mock
643
-
644
- msg_1 = {"signals": {"async_device": {"value": [7, 8, 9]}}}
645
- w1.on_async_readback(msg_1, {"async_update": "extend"})
646
-
647
- qtbot.wait(200)
648
- x_data, y_data = w1.curves[0].get_data()
649
- assert np.array_equal(x_data, [0, 1, 2])
650
- assert np.array_equal(y_data, [7, 8, 9])
651
- assert w1.plot_item.getAxis("bottom").labelText == custom_label + " [best_effort]"
652
-
653
- msg_2 = {"signals": {"async_device": {"value": [10, 11, 12]}}}
654
- w1.on_async_readback(msg_2, {"async_update": "extend"})
655
-
656
- qtbot.wait(200)
657
- x_data, y_data = w1.curves[0].get_data()
658
- assert np.array_equal(x_data, [0, 1, 2, 3, 4, 5])
659
- assert np.array_equal(y_data, [7, 8, 9, 10, 11, 12])
660
- assert w1.plot_item.getAxis("bottom").labelText == custom_label + " [best_effort]"
661
-
662
- msg_3 = {"signals": {"async_device": {"value": [20, 21, 22]}}}
663
- w1.on_async_readback(msg_3, {"async_update": "replace"})
664
-
665
- qtbot.wait(200)
666
- x_data, y_data = w1.curves[0].get_data()
667
- assert np.array_equal(x_data, [0, 1, 2])
668
- assert np.array_equal(y_data, [20, 21, 22])
669
- assert w1.plot_item.getAxis("bottom").labelText == custom_label + " [best_effort]"
670
-
671
-
672
- def test_waveform_set_x_async(qtbot, mocked_client):
673
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
674
- w1 = bec_figure.plot("async_device")
675
- custom_label = "custom_label"
676
- w1.set_x_label(custom_label)
677
-
678
- scan_item_mock = mock.MagicMock()
679
- mock_data = {
680
- "async_device": {
681
- "async_device": {
682
- "value": np.array([7, 8, 9]),
683
- "timestamp": np.array([1720520189.959115, 1720520189.986618, 1720520190.0157812]),
684
- }
685
- }
686
- }
687
-
688
- scan_item_mock.async_data = mock_data
689
- w1.queue.scan_storage.find_scan_by_ID.return_value = scan_item_mock
690
-
691
- w1.on_scan_status({"scan_id": 1})
692
- w1.replot_async_curve()
693
-
694
- qtbot.wait(200)
695
- x_data, y_data = w1.curves[0].get_data()
696
- assert np.array_equal(x_data, [0, 1, 2])
697
- assert np.array_equal(y_data, [7, 8, 9])
698
- assert w1.plot_item.getAxis("bottom").labelText == custom_label + " [best_effort]"
699
-
700
- w1.set_x("timestamp")
701
- qtbot.wait(200)
702
- x_data, y_data = w1.curves[0].get_data()
703
- assert np.allclose(x_data, np.array([1.72052019e09, 1.72052019e09, 1.72052019e09]))
704
- assert np.array_equal(y_data, [7, 8, 9])
705
- assert w1.plot_item.getAxis("bottom").labelText == custom_label + " [timestamp]"
706
-
707
- w1.set_x("index")
708
- qtbot.wait(200)
709
- x_data, y_data = w1.curves[0].get_data()
710
- assert np.array_equal(x_data, [0, 1, 2])
711
- assert np.array_equal(y_data, [7, 8, 9])
712
- assert w1.plot_item.getAxis("bottom").labelText == custom_label + " [index]"