bec-widgets 0.99.8__py3-none-any.whl → 0.99.10__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 (157) hide show
  1. CHANGELOG.md +18 -20
  2. PKG-INFO +1 -1
  3. bec_widgets/widgets/positioner_box/positioner_box.py +23 -11
  4. bec_widgets/widgets/stop_button/stop_button.py +30 -13
  5. {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.10.dist-info}/METADATA +1 -1
  6. {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.10.dist-info}/RECORD +10 -157
  7. pyproject.toml +6 -1
  8. docs/Makefile +0 -20
  9. docs/_static/custom.css +0 -170
  10. docs/_templates/custom-class-template.rst +0 -34
  11. docs/_templates/custom-module-template.rst +0 -66
  12. docs/api_reference/api_reference.md +0 -12
  13. docs/assets/apps_48dp.svg +0 -1
  14. docs/assets/display_settings_48dp.svg +0 -1
  15. docs/assets/index_api.svg +0 -97
  16. docs/assets/index_contribute.svg +0 -76
  17. docs/assets/index_getting_started.svg +0 -66
  18. docs/assets/index_user_guide.svg +0 -67
  19. docs/assets/rocket_launch_48dp.svg +0 -1
  20. docs/assets/widget_screenshots/buttons.png +0 -0
  21. docs/assets/widget_screenshots/device_box.png +0 -0
  22. docs/assets/widget_screenshots/device_browser.png +0 -0
  23. docs/assets/widget_screenshots/device_inputs.png +0 -0
  24. docs/assets/widget_screenshots/dock_area.png +0 -0
  25. docs/assets/widget_screenshots/figure.png +0 -0
  26. docs/assets/widget_screenshots/image_widget.png +0 -0
  27. docs/assets/widget_screenshots/motor_map_widget.png +0 -0
  28. docs/assets/widget_screenshots/position_indicator.png +0 -0
  29. docs/assets/widget_screenshots/queue.png +0 -0
  30. docs/assets/widget_screenshots/ring_progress_bar.png +0 -0
  31. docs/assets/widget_screenshots/scan_controller.png +0 -0
  32. docs/assets/widget_screenshots/spinner.gif +0 -0
  33. docs/assets/widget_screenshots/status_box.png +0 -0
  34. docs/assets/widget_screenshots/text_box.png +0 -0
  35. docs/assets/widget_screenshots/toggle.png +0 -0
  36. docs/assets/widget_screenshots/waveform_widget.png +0 -0
  37. docs/assets/widget_screenshots/website.png +0 -0
  38. docs/conf.py +0 -82
  39. docs/developer/developer.md +0 -52
  40. docs/developer/introduction/concepts.md +0 -14
  41. docs/developer/introduction/contributing.md +0 -28
  42. docs/developer/introduction/introduction.md +0 -16
  43. docs/developer/introduction/useful_links.md +0 -23
  44. docs/developer/widget_development/bec_dispatcher.md +0 -143
  45. docs/developer/widget_development/widget_base_class.md +0 -171
  46. docs/developer/widget_development/widget_development.md +0 -14
  47. docs/index.md +0 -74
  48. docs/introduction/introduction.md +0 -18
  49. docs/make.bat +0 -35
  50. docs/requirements.txt +0 -12
  51. docs/user/api_reference/api_reference.md +0 -11
  52. docs/user/applications/applications.md +0 -10
  53. docs/user/customisation.md +0 -123
  54. docs/user/getting_started/BECDockArea.png +0 -0
  55. docs/user/getting_started/auto_updates.md +0 -82
  56. docs/user/getting_started/getting_started.md +0 -15
  57. docs/user/getting_started/gui_complex_gui.gif +0 -0
  58. docs/user/getting_started/installation.md +0 -33
  59. docs/user/getting_started/quick_start.md +0 -110
  60. docs/user/getting_started/video_tutorials.md +0 -17
  61. docs/user/user.md +0 -71
  62. docs/user/widgets/bec_figure/BECFigure.png +0 -0
  63. docs/user/widgets/bec_figure/bec_figure.md +0 -105
  64. docs/user/widgets/bec_status_box/bec_status_box.gif +0 -0
  65. docs/user/widgets/bec_status_box/bec_status_box.md +0 -38
  66. docs/user/widgets/buttons/buttons.md +0 -90
  67. docs/user/widgets/buttons/dark_mode_disabled.png +0 -0
  68. docs/user/widgets/buttons/dark_mode_enabled.png +0 -0
  69. docs/user/widgets/device_browser/device_browser.md +0 -36
  70. docs/user/widgets/device_browser/device_browser.png +0 -0
  71. docs/user/widgets/device_input/device_input.md +0 -100
  72. docs/user/widgets/dock_area/BECDockArea.png +0 -0
  73. docs/user/widgets/dock_area/bec_dock_area.md +0 -109
  74. docs/user/widgets/image/image_plot.gif +0 -0
  75. docs/user/widgets/image/image_widget.md +0 -84
  76. docs/user/widgets/motor_map/motor.gif +0 -0
  77. docs/user/widgets/motor_map/motor_map.md +0 -80
  78. docs/user/widgets/position_indicator/position_indicator.md +0 -69
  79. docs/user/widgets/positioner_box/positioner_box.md +0 -63
  80. docs/user/widgets/progress_bar/progress_bar.gif +0 -0
  81. docs/user/widgets/progress_bar/ring_progress_bar.md +0 -103
  82. docs/user/widgets/queue/queue.md +0 -41
  83. docs/user/widgets/scan_control/hide_scan_control.png +0 -0
  84. docs/user/widgets/scan_control/scan_control.gif +0 -0
  85. docs/user/widgets/scan_control/scan_control.md +0 -54
  86. docs/user/widgets/spinner/spinner.md +0 -68
  87. docs/user/widgets/text_box/text_box.md +0 -74
  88. docs/user/widgets/toggle/toggle.md +0 -66
  89. docs/user/widgets/waveform/bec_figure_dap.gif +0 -0
  90. docs/user/widgets/waveform/scatter_2D.gif +0 -0
  91. docs/user/widgets/waveform/w1D.gif +0 -0
  92. docs/user/widgets/waveform/waveform_widget.md +0 -132
  93. docs/user/widgets/website/website.md +0 -69
  94. docs/user/widgets/widgets.md +0 -220
  95. tests/__init__.py +0 -0
  96. tests/end-2-end/__init__.py +0 -0
  97. tests/end-2-end/conftest.py +0 -53
  98. tests/end-2-end/test_bec_dock_rpc_e2e.py +0 -298
  99. tests/end-2-end/test_bec_figure_rpc_e2e.py +0 -212
  100. tests/end-2-end/test_rpc_register_e2e.py +0 -40
  101. tests/end-2-end/test_scan_control_e2e.py +0 -71
  102. tests/references/SpinnerWidget/SpinnerWidget_darwin.png +0 -0
  103. tests/references/SpinnerWidget/SpinnerWidget_linux.png +0 -0
  104. tests/references/SpinnerWidget/SpinnerWidget_started_darwin.png +0 -0
  105. tests/references/SpinnerWidget/SpinnerWidget_started_linux.png +0 -0
  106. tests/unit_tests/__init__.py +0 -0
  107. tests/unit_tests/client_mocks.py +0 -189
  108. tests/unit_tests/conftest.py +0 -64
  109. tests/unit_tests/test_bec_connector.py +0 -80
  110. tests/unit_tests/test_bec_dispatcher.py +0 -119
  111. tests/unit_tests/test_bec_dock.py +0 -155
  112. tests/unit_tests/test_bec_figure.py +0 -270
  113. tests/unit_tests/test_bec_image.py +0 -63
  114. tests/unit_tests/test_bec_image_widget.py +0 -217
  115. tests/unit_tests/test_bec_motor_map.py +0 -282
  116. tests/unit_tests/test_bec_queue.py +0 -111
  117. tests/unit_tests/test_bec_status_box.py +0 -123
  118. tests/unit_tests/test_client_utils.py +0 -76
  119. tests/unit_tests/test_color_map_selector.py +0 -42
  120. tests/unit_tests/test_color_validation.py +0 -75
  121. tests/unit_tests/test_configs/config_device.yaml +0 -33
  122. tests/unit_tests/test_configs/config_device_no_entry.yaml +0 -27
  123. tests/unit_tests/test_configs/config_scan.yaml +0 -82
  124. tests/unit_tests/test_crosshair.py +0 -143
  125. tests/unit_tests/test_dark_mode_button.py +0 -70
  126. tests/unit_tests/test_device_browser.py +0 -83
  127. tests/unit_tests/test_device_input_base.py +0 -76
  128. tests/unit_tests/test_device_input_widgets.py +0 -178
  129. tests/unit_tests/test_error_utils.py +0 -63
  130. tests/unit_tests/test_generate_cli_client.py +0 -123
  131. tests/unit_tests/test_generate_plugin.py +0 -155
  132. tests/unit_tests/test_motor_map_widget.py +0 -194
  133. tests/unit_tests/test_msgs/__init__.py +0 -0
  134. tests/unit_tests/test_msgs/available_scans_message.py +0 -989
  135. tests/unit_tests/test_plot_base.py +0 -95
  136. tests/unit_tests/test_plugin_utils.py +0 -13
  137. tests/unit_tests/test_positioner_box.py +0 -130
  138. tests/unit_tests/test_ring_progress_bar.py +0 -337
  139. tests/unit_tests/test_rpc_register.py +0 -52
  140. tests/unit_tests/test_rpc_server.py +0 -42
  141. tests/unit_tests/test_rpc_widget_handler.py +0 -7
  142. tests/unit_tests/test_scan_control.py +0 -324
  143. tests/unit_tests/test_scan_control_group_box.py +0 -160
  144. tests/unit_tests/test_setting_dialog.py +0 -96
  145. tests/unit_tests/test_spinner.py +0 -31
  146. tests/unit_tests/test_stop_button.py +0 -27
  147. tests/unit_tests/test_text_box_widget.py +0 -54
  148. tests/unit_tests/test_toggle.py +0 -38
  149. tests/unit_tests/test_vscode_widget.py +0 -75
  150. tests/unit_tests/test_waveform1d.py +0 -712
  151. tests/unit_tests/test_waveform_widget.py +0 -462
  152. tests/unit_tests/test_website_widget.py +0 -25
  153. tests/unit_tests/test_widget_io.py +0 -90
  154. tests/unit_tests/test_yaml_dialog.py +0 -163
  155. {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.10.dist-info}/WHEEL +0 -0
  156. {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.10.dist-info}/entry_points.txt +0 -0
  157. {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.10.dist-info}/licenses/LICENSE +0 -0
@@ -1,217 +0,0 @@
1
- from unittest.mock import MagicMock, patch
2
-
3
- import pyqtgraph as pg
4
- import pytest
5
-
6
- from bec_widgets.widgets.image.image_widget import BECImageWidget
7
-
8
- from .client_mocks import mocked_client
9
-
10
-
11
- @pytest.fixture
12
- def image_widget(qtbot, mocked_client):
13
- widget = BECImageWidget(client=mocked_client())
14
- widget.toolbar.widgets["monitor"].device_combobox.set_device_filter("FakeDevice")
15
- qtbot.addWidget(widget)
16
- qtbot.waitExposed(widget)
17
- yield widget
18
-
19
-
20
- @pytest.fixture
21
- def mock_image(image_widget):
22
- image_mock = MagicMock()
23
- image_widget._image = image_mock
24
- return image_mock
25
-
26
-
27
- def test_image_widget_init(image_widget):
28
- assert image_widget is not None
29
- assert image_widget.client is not None
30
- assert isinstance(image_widget, BECImageWidget)
31
- assert image_widget.config.widget_class == "BECImageWidget"
32
- assert image_widget._image is not None
33
-
34
- assert (
35
- image_widget.toolbar.widgets["monitor"].device_combobox.config.device_filter == "FakeDevice"
36
- )
37
- assert image_widget.toolbar.widgets["drag_mode"].action.isChecked() == True
38
- assert image_widget.toolbar.widgets["rectangle_mode"].action.isChecked() == False
39
- assert image_widget.toolbar.widgets["auto_range"].action.isChecked() == False
40
- assert image_widget.toolbar.widgets["auto_range_image"].action.isChecked() == True
41
- assert image_widget.toolbar.widgets["FFT"].action.isChecked() == False
42
- assert image_widget.toolbar.widgets["transpose"].action.isChecked() == False
43
- assert image_widget.toolbar.widgets["log"].action.isChecked() == False
44
-
45
-
46
- ###################################
47
- # Toolbar Actions
48
- ###################################
49
- def test_toolbar_connect_action(image_widget, mock_image, qtbot):
50
- combo = image_widget.toolbar.widgets["monitor"].device_combobox
51
- combo.setCurrentText("eiger")
52
- qtbot.wait(200)
53
- assert combo.currentText() == "eiger"
54
- action = image_widget.toolbar.widgets["connect"].action
55
- action.trigger()
56
- image_widget._image.image.assert_called_once_with(
57
- monitor="eiger",
58
- color_map="magma",
59
- color_bar="full",
60
- downsample=True,
61
- opacity=1.0,
62
- vrange=None,
63
- )
64
-
65
-
66
- def test_image_toolbar_drag_mode_action_triggered(image_widget, qtbot):
67
- action_drag = image_widget.toolbar.widgets["drag_mode"].action
68
- action_rectangle = image_widget.toolbar.widgets["rectangle_mode"].action
69
- action_drag.trigger()
70
- assert action_drag.isChecked() == True
71
- assert action_rectangle.isChecked() == False
72
-
73
-
74
- def test_image_toolbar_rectangle_mode_action_triggered(image_widget, qtbot):
75
- action_drag = image_widget.toolbar.widgets["drag_mode"].action
76
- action_rectangle = image_widget.toolbar.widgets["rectangle_mode"].action
77
- action_rectangle.trigger()
78
- assert action_drag.isChecked() == False
79
- assert action_rectangle.isChecked() == True
80
-
81
-
82
- def test_image_toolbar_auto_range(image_widget, mock_image):
83
- action = image_widget.toolbar.widgets["auto_range"].action
84
- action.trigger()
85
- image_widget._image.set_auto_range.assert_called_once_with(True, "xy")
86
-
87
-
88
- def test_image_toolbar_enable_mouse_pan_mode(qtbot, image_widget):
89
- action_drag = image_widget.toolbar.widgets["drag_mode"].action
90
- action_rectangle = image_widget.toolbar.widgets["rectangle_mode"].action
91
-
92
- mock_view_box = MagicMock()
93
- image_widget._image.plot_item.getViewBox = MagicMock(return_value=mock_view_box)
94
-
95
- image_widget.enable_mouse_pan_mode()
96
-
97
- assert action_drag.isChecked() == True
98
- assert action_rectangle.isChecked() == False
99
- mock_view_box.setMouseMode.assert_called_once_with(pg.ViewBox.PanMode)
100
-
101
-
102
- def test_image_toolbar_auto_range_image(image_widget, mock_image):
103
- action = image_widget.toolbar.widgets["auto_range_image"].action
104
- action.trigger()
105
- assert action.isChecked() == False
106
- image_widget._image.set_autorange.assert_called_once_with(False)
107
-
108
-
109
- def test_image_toolbar_FFT(image_widget, mock_image):
110
- action = image_widget.toolbar.widgets["FFT"].action
111
- action.trigger()
112
- assert action.isChecked() == True
113
- image_widget._image.set_fft.assert_called_once_with(True, None)
114
-
115
-
116
- def test_image_toolbar_log(image_widget, mock_image):
117
- action = image_widget.toolbar.widgets["log"].action
118
- action.trigger()
119
- assert action.isChecked() == True
120
- image_widget._image.set_log.assert_called_once_with(True, None)
121
-
122
-
123
- def test_image_toggle_transpose(image_widget, mock_image):
124
- action = image_widget.toolbar.widgets["transpose"].action
125
- action.trigger()
126
- assert action.isChecked() == True
127
- image_widget._image.set_transpose.assert_called_once_with(True, None)
128
-
129
-
130
- def test_image_toolbar_rotation(image_widget, mock_image):
131
- action_left = image_widget.toolbar.widgets["rotate_left"].action
132
- action_right = image_widget.toolbar.widgets["rotate_right"].action
133
-
134
- action_left.trigger()
135
- image_widget._image.set_rotation(1, None)
136
- action_right.trigger()
137
- image_widget._image.set_rotation(2, None)
138
-
139
- action_right.trigger()
140
- image_widget._image.set_rotation(1, None)
141
-
142
-
143
- ###################################
144
- # Wrapper methods for ImageShow
145
- ###################################
146
-
147
-
148
- def test_image_set_image(image_widget, mock_image):
149
- image_widget.image(monitor="image")
150
- image_widget._image.image.assert_called_once_with(
151
- monitor="image",
152
- color_map="magma",
153
- color_bar="full",
154
- downsample=True,
155
- opacity=1.0,
156
- vrange=None,
157
- )
158
-
159
-
160
- def test_image_vrange(image_widget, mock_image):
161
- image_widget.set_vrange(0, 1)
162
- image_widget._image.set_vrange.assert_called_once_with(0, 1, None)
163
-
164
-
165
- def test_image_set_color_map(image_widget, mock_image):
166
- image_widget.set_color_map("viridis")
167
- image_widget._image.set_color_map.assert_called_once_with("viridis", None)
168
-
169
-
170
- def test_image_widget_set_title(image_widget, mock_image):
171
- image_widget.set_title("Title Label")
172
- image_widget._image.set_title.assert_called_once_with("Title Label")
173
-
174
-
175
- def test_image_widget_set_x_label(image_widget, mock_image):
176
- image_widget.set_x_label("X Label")
177
- image_widget._image.set_x_label.assert_called_once_with("X Label")
178
-
179
-
180
- def test_image_widget_set_y_label(image_widget, mock_image):
181
- image_widget.set_y_label("Y Label")
182
- image_widget._image.set_y_label.assert_called_once_with("Y Label")
183
-
184
-
185
- def test_image_widget_set_x_scale(image_widget, mock_image):
186
- image_widget.set_x_scale("linear")
187
- image_widget._image.set_x_scale.assert_called_once_with("linear")
188
-
189
-
190
- def test_image_widget_set_y_scale(image_widget, mock_image):
191
- image_widget.set_y_scale("log")
192
- image_widget._image.set_y_scale.assert_called_once_with("log")
193
-
194
-
195
- def test_image_widget_set_x_lim(image_widget, mock_image):
196
- image_widget.set_x_lim((0, 10))
197
- image_widget._image.set_x_lim.assert_called_once_with((0, 10))
198
-
199
-
200
- def test_image_widget_set_y_lim(image_widget, mock_image):
201
- image_widget.set_y_lim((0, 10))
202
- image_widget._image.set_y_lim.assert_called_once_with((0, 10))
203
-
204
-
205
- def test_image_widget_set_grid(image_widget, mock_image):
206
- image_widget.set_grid(True, False)
207
- image_widget._image.set_grid.assert_called_once_with(True, False)
208
-
209
-
210
- def test_image_widget_lock_aspect_ratio(image_widget, mock_image):
211
- image_widget.lock_aspect_ratio(True)
212
- image_widget._image.lock_aspect_ratio.assert_called_once_with(True)
213
-
214
-
215
- def test_image_widget_export(image_widget, mock_image):
216
- image_widget.export()
217
- image_widget._image.export.assert_called_once()
@@ -1,282 +0,0 @@
1
- import numpy as np
2
- import pytest
3
- from bec_lib.messages import DeviceMessage
4
-
5
- from bec_widgets.widgets.figure import BECFigure
6
- from bec_widgets.widgets.figure.plots.motor_map.motor_map import BECMotorMap, MotorMapConfig
7
- from bec_widgets.widgets.figure.plots.waveform.waveform_curve import SignalData
8
-
9
- from .client_mocks import mocked_client
10
- from .conftest import create_widget
11
-
12
-
13
- def test_motor_map_init(qtbot, mocked_client):
14
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
15
- default_config = MotorMapConfig(widget_class="BECMotorMap")
16
-
17
- mm = bec_figure.motor_map(config=default_config.model_dump())
18
- default_config.gui_id = mm.gui_id
19
-
20
- assert mm.config == default_config
21
-
22
-
23
- def test_motor_map_change_motors(qtbot, mocked_client):
24
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
25
- mm = bec_figure.motor_map("samx", "samy")
26
-
27
- assert mm.motor_x == "samx"
28
- assert mm.motor_y == "samy"
29
- assert mm.config.signals.x == SignalData(name="samx", entry="samx", limits=[-10, 10])
30
- assert mm.config.signals.y == SignalData(name="samy", entry="samy", limits=[-5, 5])
31
-
32
- mm.change_motors("samx", "samz")
33
-
34
- assert mm.config.signals.x == SignalData(name="samx", entry="samx", limits=[-10, 10])
35
- assert mm.config.signals.y == SignalData(name="samz", entry="samz", limits=[-8, 8])
36
-
37
-
38
- def test_motor_map_get_limits(qtbot, mocked_client):
39
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
40
- mm = bec_figure.motor_map("samx", "samy")
41
- expected_limits = {"samx": [-10, 10], "samy": [-5, 5]}
42
-
43
- for motor_name, expected_limit in expected_limits.items():
44
- actual_limit = mm._get_motor_limit(motor_name)
45
- assert actual_limit == expected_limit
46
-
47
-
48
- def test_motor_map_get_init_position(qtbot, mocked_client):
49
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
50
- mm = bec_figure.motor_map("samx", "samy")
51
- mm.set_precision(2)
52
-
53
- motor_map_dev = mm.client.device_manager.devices
54
-
55
- expected_positions = {
56
- ("samx", "samx"): motor_map_dev["samx"].read()["samx"]["value"],
57
- ("samy", "samy"): motor_map_dev["samy"].read()["samy"]["value"],
58
- }
59
-
60
- for (motor_name, entry), expected_position in expected_positions.items():
61
- actual_position = mm._get_motor_init_position(motor_name, entry, 2)
62
- assert actual_position == expected_position
63
-
64
-
65
- def test_motor_movement_updates_position_and_database(qtbot, mocked_client):
66
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
67
- mm = bec_figure.motor_map("samx", "samy")
68
- motor_map_dev = mm.client.device_manager.devices
69
-
70
- init_positions = {
71
- "samx": [motor_map_dev["samx"].read()["samx"]["value"]],
72
- "samy": [motor_map_dev["samy"].read()["samy"]["value"]],
73
- }
74
-
75
- mm.change_motors("samx", "samy")
76
-
77
- assert mm.database_buffer["x"] == init_positions["samx"]
78
- assert mm.database_buffer["y"] == init_positions["samy"]
79
-
80
- # Simulate motor movement for 'samx' only
81
- new_position_samx = 4.0
82
- msg = DeviceMessage(signals={"samx": {"value": new_position_samx}}, metadata={})
83
- mm.on_device_readback(msg.content, msg.metadata)
84
-
85
- init_positions["samx"].append(new_position_samx)
86
- init_positions["samy"].append(init_positions["samy"][-1])
87
- # Verify database update for 'samx'
88
- assert mm.database_buffer["x"] == init_positions["samx"]
89
-
90
- # Verify 'samy' retains its last known position
91
- assert mm.database_buffer["y"] == init_positions["samy"]
92
-
93
-
94
- def test_scatter_plot_rendering(qtbot, mocked_client):
95
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
96
- mm = bec_figure.motor_map("samx", "samy")
97
- motor_map_dev = mm.client.device_manager.devices
98
-
99
- init_positions = {
100
- "samx": [motor_map_dev["samx"].read()["samx"]["value"]],
101
- "samy": [motor_map_dev["samy"].read()["samy"]["value"]],
102
- }
103
-
104
- mm.change_motors("samx", "samy")
105
-
106
- # Simulate motor movement for 'samx' only
107
- new_position_samx = 4.0
108
- msg = DeviceMessage(signals={"samx": {"value": new_position_samx}}, metadata={})
109
- mm.on_device_readback(msg.content, msg.metadata)
110
- mm._update_plot()
111
-
112
- # Get the scatter plot item
113
- scatter_plot_item = mm.plot_components["scatter"]
114
-
115
- # Check the scatter plot item properties
116
- assert len(scatter_plot_item.data) > 0, "Scatter plot data is empty"
117
- x_data = scatter_plot_item.data["x"]
118
- y_data = scatter_plot_item.data["y"]
119
- assert x_data[-1] == new_position_samx, "Scatter plot X data not updated correctly"
120
- assert (
121
- y_data[-1] == init_positions["samy"][-1]
122
- ), "Scatter plot Y data should retain last known position"
123
-
124
-
125
- def test_plot_visualization_consistency(qtbot, mocked_client):
126
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
127
- mm = bec_figure.motor_map("samx", "samy")
128
- mm.change_motors("samx", "samy")
129
- # Simulate updating the plot with new data
130
- msg = DeviceMessage(signals={"samx": {"value": 5}}, metadata={})
131
- mm.on_device_readback(msg.content, msg.metadata)
132
- msg = DeviceMessage(signals={"samy": {"value": 9}}, metadata={})
133
- mm.on_device_readback(msg.content, msg.metadata)
134
- mm._update_plot()
135
-
136
- scatter_plot_item = mm.plot_components["scatter"]
137
-
138
- # Check if the scatter plot reflects the new data correctly
139
- assert (
140
- scatter_plot_item.data["x"][-1] == 5 and scatter_plot_item.data["y"][-1] == 9
141
- ), "Plot not updated correctly with new data"
142
-
143
-
144
- def test_change_background_value(qtbot, mocked_client):
145
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
146
- mm = bec_figure.motor_map("samx", "samy")
147
-
148
- assert mm.config.background_value == 25
149
- assert np.all(mm.plot_components["limit_map"].image == 25.0)
150
-
151
- mm.set_background_value(50)
152
- qtbot.wait(200)
153
-
154
- assert mm.config.background_value == 50
155
- assert np.all(mm.plot_components["limit_map"].image == 50.0)
156
-
157
-
158
- def test_motor_map_init_from_config(qtbot, mocked_client):
159
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
160
- config = {
161
- "widget_class": "BECMotorMap",
162
- "gui_id": "mm_id",
163
- "parent_id": bec_figure.gui_id,
164
- "row": 0,
165
- "col": 0,
166
- "axis": {
167
- "title": "Motor position: (-0.0, 0.0)",
168
- "title_size": None,
169
- "x_label": "Motor X (samx)",
170
- "x_label_size": None,
171
- "y_label": "Motor Y (samy)",
172
- "y_label_size": None,
173
- "legend_label_size": None,
174
- "x_scale": "linear",
175
- "y_scale": "linear",
176
- "x_lim": None,
177
- "y_lim": None,
178
- "x_grid": True,
179
- "y_grid": True,
180
- },
181
- "signals": {
182
- "source": "device_readback",
183
- "x": {
184
- "name": "samx",
185
- "entry": "samx",
186
- "unit": None,
187
- "modifier": None,
188
- "limits": [-10.0, 10.0],
189
- },
190
- "y": {
191
- "name": "samy",
192
- "entry": "samy",
193
- "unit": None,
194
- "modifier": None,
195
- "limits": [-5.0, 5.0],
196
- },
197
- "z": None,
198
- "dap": None,
199
- },
200
- "color": (255, 255, 255, 255),
201
- "scatter_size": 5,
202
- "max_points": 50,
203
- "num_dim_points": 10,
204
- "precision": 5,
205
- "background_value": 50,
206
- }
207
- mm = bec_figure.motor_map(config=config)
208
- config["gui_id"] = mm.gui_id
209
-
210
- assert mm._config_dict == config
211
-
212
-
213
- def test_motor_map_set_scatter_size(qtbot, mocked_client):
214
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
215
- mm = bec_figure.motor_map("samx", "samy")
216
-
217
- assert mm.config.scatter_size == 5
218
- assert mm.plot_components["scatter"].opts["size"] == 5
219
-
220
- mm.set_scatter_size(10)
221
- qtbot.wait(200)
222
-
223
- assert mm.config.scatter_size == 10
224
- assert mm.plot_components["scatter"].opts["size"] == 10
225
-
226
-
227
- def test_motor_map_change_precision(qtbot, mocked_client):
228
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
229
- mm = bec_figure.motor_map("samx", "samy")
230
-
231
- assert mm.config.precision == 2
232
- mm.set_precision(10)
233
- assert mm.config.precision == 10
234
-
235
-
236
- def test_motor_map_set_color(qtbot, mocked_client):
237
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
238
- mm = bec_figure.motor_map("samx", "samy")
239
-
240
- assert mm.config.color == (255, 255, 255, 255)
241
-
242
- mm.set_color((0, 0, 0, 255))
243
- qtbot.wait(200)
244
- assert mm.config.color == (0, 0, 0, 255)
245
-
246
-
247
- def test_motor_map_get_data_max_points(qtbot, mocked_client):
248
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
249
- mm = bec_figure.motor_map("samx", "samy")
250
- motor_map_dev = mm.client.device_manager.devices
251
-
252
- init_positions = {
253
- "samx": [motor_map_dev["samx"].read()["samx"]["value"]],
254
- "samy": [motor_map_dev["samy"].read()["samy"]["value"]],
255
- }
256
- msg = DeviceMessage(signals={"samx": {"value": 5.0}}, metadata={})
257
- mm.on_device_readback(msg.content, msg.metadata)
258
- msg = DeviceMessage(signals={"samy": {"value": 9.0}}, metadata={})
259
- mm.on_device_readback(msg.content, msg.metadata)
260
- msg = DeviceMessage(signals={"samx": {"value": 6.0}}, metadata={})
261
- mm.on_device_readback(msg.content, msg.metadata)
262
- msg = DeviceMessage(signals={"samy": {"value": 7.0}}, metadata={})
263
- mm.on_device_readback(msg.content, msg.metadata)
264
-
265
- expected_x = [init_positions["samx"][-1], 5.0, 5.0, 6.0, 6.0]
266
- expected_y = [init_positions["samy"][-1], init_positions["samy"][-1], 9.0, 9.0, 7.0]
267
- get_data = mm.get_data()
268
-
269
- assert mm.database_buffer["x"] == expected_x
270
- assert mm.database_buffer["y"] == expected_y
271
- assert get_data["x"] == expected_x
272
- assert get_data["y"] == expected_y
273
-
274
- mm.set_max_points(3)
275
- qtbot.wait(200)
276
- get_data = mm.get_data()
277
- assert len(get_data["x"]) == 3
278
- assert len(get_data["y"]) == 3
279
- assert get_data["x"] == expected_x[-3:]
280
- assert get_data["y"] == expected_y[-3:]
281
- assert mm.database_buffer["x"] == expected_x[-3:]
282
- assert mm.database_buffer["y"] == expected_y[-3:]
@@ -1,111 +0,0 @@
1
- import pytest
2
- from bec_lib import messages
3
-
4
- from bec_widgets.widgets.bec_queue.bec_queue import BECQueue
5
-
6
- from .client_mocks import mocked_client
7
-
8
-
9
- @pytest.fixture
10
- def bec_queue_msg_full():
11
- content = {
12
- "primary": {
13
- "info": [
14
- {
15
- "active_request_block": None,
16
- "is_scan": [True],
17
- "queue_id": "600163fc-5e56-4901-af25-14e9ee76817c",
18
- "request_blocks": [
19
- {
20
- "RID": "89a76021-28c0-4297-828e-74ae40b941e5",
21
- "content": {
22
- "parameter": {
23
- "args": {"samx": [-0.1, 0.1]},
24
- "kwargs": {
25
- "exp_time": 0.5,
26
- "relative": True,
27
- "steps": 20,
28
- "system_config": {
29
- "file_directory": None,
30
- "file_suffix": None,
31
- },
32
- },
33
- },
34
- "queue": "primary",
35
- "scan_type": "line_scan",
36
- },
37
- "is_scan": True,
38
- "metadata": {
39
- "RID": "89a76021-28c0-4297-828e-74ae40b941e5",
40
- "file_directory": None,
41
- "file_suffix": None,
42
- "user_metadata": {"sample_name": "testA"},
43
- },
44
- "msg": messages.ScanQueueMessage(
45
- metadata={
46
- "file_suffix": None,
47
- "file_directory": None,
48
- "user_metadata": {"sample_name": "testA"},
49
- "RID": "89a76021-28c0-4297-828e-74ae40b941e5",
50
- },
51
- scan_type="line_scan",
52
- parameter={
53
- "args": {"samx": [-0.1, 0.1]},
54
- "kwargs": {
55
- "steps": 20,
56
- "exp_time": 0.5,
57
- "relative": True,
58
- "system_config": {
59
- "file_suffix": None,
60
- "file_directory": None,
61
- },
62
- },
63
- },
64
- queue="primary",
65
- ),
66
- "readout_priority": {
67
- "async": [],
68
- "baseline": [],
69
- "monitored": ["samx"],
70
- "on_request": [],
71
- },
72
- "report_instructions": [{"scan_progress": 20}],
73
- "scan_id": "2d704cc3-c172-404c-866d-608ce09fce40",
74
- "scan_motors": ["samx"],
75
- "scan_number": 1289,
76
- }
77
- ],
78
- "scan_id": ["2d704cc3-c172-404c-866d-608ce09fce40"],
79
- "scan_number": [1289],
80
- "status": "COMPLETED",
81
- }
82
- ],
83
- "status": "RUNNING",
84
- }
85
- }
86
- msg = messages.ScanQueueStatusMessage(metadata={}, queue=content)
87
- return msg
88
-
89
-
90
- @pytest.fixture
91
- def bec_queue(qtbot, mocked_client):
92
- widget = BECQueue(client=mocked_client)
93
- qtbot.addWidget(widget)
94
- qtbot.waitExposed(widget)
95
- yield widget
96
-
97
-
98
- def test_bec_queue(bec_queue, bec_queue_msg_full):
99
- bec_queue.update_queue(bec_queue_msg_full.content, {})
100
- assert bec_queue.table.rowCount() == 1
101
- assert bec_queue.table.item(0, 0).text() == "1289"
102
- assert bec_queue.table.item(0, 1).text() == "line_scan"
103
- assert bec_queue.table.item(0, 2).text() == "COMPLETED"
104
-
105
-
106
- def test_bec_queue_empty(bec_queue):
107
- bec_queue.update_queue({}, {})
108
- assert bec_queue.table.rowCount() == 1
109
- assert bec_queue.table.item(0, 0).text() == ""
110
- assert bec_queue.table.item(0, 1).text() == ""
111
- assert bec_queue.table.item(0, 2).text() == ""