bec-widgets 0.52.0__py3-none-any.whl → 0.53.0__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.
- .git_hooks/pre-commit +3 -0
- .gitignore +177 -0
- .gitlab/issue_templates/bug_report_template.md +17 -0
- .gitlab/issue_templates/documentation_update_template.md +27 -0
- .gitlab/issue_templates/feature_request_template.md +40 -0
- .gitlab/merge_request_templates/default.md +28 -0
- .gitlab-ci.yml +225 -0
- .pylintrc +581 -0
- .readthedocs.yaml +25 -0
- CHANGELOG.md +176 -0
- PKG-INFO +33 -0
- bec_widgets-0.52.0.dist-info/METADATA → README.md +6 -42
- bec_widgets/cli/client.py +132 -17
- bec_widgets/cli/client_utils.py +1 -0
- bec_widgets/cli/generate_cli.py +1 -0
- bec_widgets/cli/rpc_register.py +4 -0
- bec_widgets/cli/rpc_wigdet_handler.py +2 -3
- bec_widgets/examples/modular_app/modular.ui +92 -0
- bec_widgets/examples/modular_app/modular_app.py +197 -0
- bec_widgets/examples/motor_movement/motor_control_compilations.py +1 -1
- bec_widgets/examples/motor_movement/motor_example.py +3 -12
- bec_widgets/utils/bec_connector.py +7 -0
- bec_widgets/utils/bec_dispatcher.py +1 -3
- bec_widgets/utils/bec_table.py +1 -0
- bec_widgets/utils/container_utils.py +3 -0
- bec_widgets/utils/crosshair.py +1 -0
- bec_widgets/utils/entry_validator.py +2 -0
- bec_widgets/utils/layout_manager.py +4 -0
- bec_widgets/utils/widget_io.py +5 -0
- bec_widgets/utils/yaml_dialog.py +2 -0
- bec_widgets/validation/monitor_config_validator.py +2 -1
- bec_widgets/widgets/dock/dock_area.py +6 -4
- bec_widgets/widgets/figure/figure.py +15 -15
- bec_widgets/widgets/monitor/config_dialog.py +3 -19
- bec_widgets/widgets/monitor/example_configs/config_device.yaml +60 -0
- bec_widgets/widgets/monitor/example_configs/config_scans.yaml +92 -0
- bec_widgets/widgets/motor_map/motor_map.py +3 -14
- bec_widgets/widgets/plots/image.py +41 -0
- bec_widgets/widgets/plots/motor_map.py +16 -9
- bec_widgets/widgets/plots/plot_base.py +10 -0
- bec_widgets/widgets/plots/waveform.py +31 -0
- bec_widgets/widgets/scan_control/scan_control.py +11 -5
- bec_widgets/widgets/toolbar/toolbar.py +1 -0
- bec_widgets-0.53.0.dist-info/METADATA +33 -0
- bec_widgets-0.53.0.dist-info/RECORD +156 -0
- {bec_widgets-0.52.0.dist-info → bec_widgets-0.53.0.dist-info}/WHEEL +1 -2
- bec_widgets-0.53.0.dist-info/licenses/LICENSE +29 -0
- docs/Makefile +20 -0
- docs/_templates/custom-class-template.rst +34 -0
- docs/_templates/custom-module-template.rst +66 -0
- docs/conf.py +81 -0
- docs/developer/developer.md +26 -0
- docs/developer/reference.md +10 -0
- docs/index.md +39 -0
- docs/introduction/introduction.md +18 -0
- docs/make.bat +35 -0
- docs/requirements.txt +10 -0
- docs/user/apps/modular_app.md +6 -0
- docs/user/apps/motor_app.md +34 -0
- docs/user/apps/motor_app_10fps.gif +0 -0
- docs/user/apps/plot_app.md +6 -0
- docs/user/apps.md +39 -0
- docs/user/customisation.md +13 -0
- docs/user/installation.md +46 -0
- docs/user/user.md +38 -0
- docs/user/widgets/motor.gif +0 -0
- docs/user/widgets/scatter_2D.gif +0 -0
- docs/user/widgets/w1D.gif +0 -0
- docs/user/widgets.md +41 -0
- pyproject.toml +94 -0
- tests/unit_tests/test_bec_dispatcher.py +3 -26
- tests/unit_tests/test_bec_figure.py +1 -5
- tests/unit_tests/test_bec_motor_map.py +1 -4
- tests/unit_tests/test_config_dialog.py +1 -5
- tests/unit_tests/test_configs/config_device.yaml +33 -0
- tests/unit_tests/test_configs/config_device_no_entry.yaml +27 -0
- tests/unit_tests/test_configs/config_scan.yaml +82 -0
- tests/unit_tests/test_motor_control.py +1 -1
- tests/unit_tests/test_motor_map.py +5 -20
- tests/unit_tests/test_stream_plot.py +2 -12
- bec_widgets/utils/ctrl_c.py +0 -39
- bec_widgets-0.52.0.dist-info/RECORD +0 -115
- bec_widgets-0.52.0.dist-info/top_level.txt +0 -2
- /bec_widgets-0.52.0.dist-info/LICENSE → /LICENSE +0 -0
- /bec_widgets/{simulations/__init__.py → examples/modular_app/___init__.py} +0 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
(user.installation)=
|
2
|
+
# Installation
|
3
|
+
|
4
|
+
|
5
|
+
**Prerequisites**
|
6
|
+
|
7
|
+
Before installing BEC Widgets, please ensure the following requirements are met:
|
8
|
+
|
9
|
+
1. **Python Version:** BEC Widgets requires Python version 3.10 or higher. Verify your Python version to ensure compatibility.
|
10
|
+
2. **BEC Installation:** BEC Widgets works in conjunction with BEC. While BEC is a dependency and will be installed automatically, you can find more information about BEC and its installation process in the [BEC documentation](https://beamline-experiment-control.readthedocs.io/en/latest/).
|
11
|
+
|
12
|
+
**Standard Installation**
|
13
|
+
|
14
|
+
Install BEC Widgets using the pip package manager. Open your terminal and execute:
|
15
|
+
|
16
|
+
```bash
|
17
|
+
pip install bec_widgets
|
18
|
+
```
|
19
|
+
|
20
|
+
This command installs BEC Widgets along with its dependencies, including the default PyQt6.
|
21
|
+
|
22
|
+
**Selecting a PyQt Version**
|
23
|
+
|
24
|
+
BEC Widgets supports both PyQt5 and PyQt6. To install a specific version, use:
|
25
|
+
|
26
|
+
For PyQt6:
|
27
|
+
|
28
|
+
```bash
|
29
|
+
pip install bec_widgets[pyqt6]
|
30
|
+
```
|
31
|
+
|
32
|
+
For PyQt5:
|
33
|
+
|
34
|
+
```bash
|
35
|
+
pip install bec_widgets[pyqt5]
|
36
|
+
```
|
37
|
+
|
38
|
+
**Troubleshooting**
|
39
|
+
|
40
|
+
If you encounter issues during installation, particularly with PyQt, try purging the pip cache:
|
41
|
+
|
42
|
+
```bash
|
43
|
+
pip cache purge
|
44
|
+
```
|
45
|
+
|
46
|
+
This can resolve conflicts or issues with package installations.
|
docs/user/user.md
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
(user)=
|
2
|
+
# User
|
3
|
+
|
4
|
+
**Overview**
|
5
|
+
|
6
|
+
Welcome to the User section of the BEC Widgets documentation! BEC Widgets is a versatile GUI framework tailored for beamline scientists, enabling efficient and intuitive interaction with beamline experiments. This section is designed to guide both new and experienced users through the essential aspects of utilizing BEC Widgets.
|
7
|
+
|
8
|
+
**Key Topics**
|
9
|
+
|
10
|
+
- [Installing BEC Widgets](#user.installation): Instructions for installing BEC Widgets on your system.
|
11
|
+
|
12
|
+
- [Example Applications](#user.apps): Overview of bespoke applications and demonstrations of BEC Widgets in action, showcasing its use in real-world beamline scenarios.
|
13
|
+
|
14
|
+
- [Widgets Overview](#user.widgets): Detailed information on the variety of widgets available, their functions, and how to use them effectively.
|
15
|
+
|
16
|
+
- [Customization and Configuration](#user.customisation): Tips on customizing and configuring BEC Widgets to suit your specific experimental needs using Qt Designer.
|
17
|
+
|
18
|
+
**Bug Reports and Feature Requests**
|
19
|
+
|
20
|
+
We value your feedback and contributions to improving BEC Widgets. If you encounter any issues or have ideas for new features, we encourage you to report them.
|
21
|
+
|
22
|
+
- **Bug Reports:** If you find a bug or an issue, please report it on our repository's [Issues page](https://gitlab.psi.ch/bec/bec-widgets/-/issues?sort=created_date&state=opened). We have a template for bug reporting to help you provide all necessary information.
|
23
|
+
- **Feature Requests:** Have an idea for a new feature or an enhancement? Share it with us on the [Issues page](https://gitlab.psi.ch/bec/bec-widgets/-/issues?sort=created_date&state=opened) of our repository. We have a feature request template that you can use to describe your proposal.
|
24
|
+
|
25
|
+
**Development**
|
26
|
+
|
27
|
+
For advanced details about BEC Widgets’ internal architecture, development contributions, or customization techniques, please explore the [Developer](#developer) section.
|
28
|
+
|
29
|
+
```{toctree}
|
30
|
+
---
|
31
|
+
maxdepth: 3
|
32
|
+
hidden: true
|
33
|
+
---
|
34
|
+
|
35
|
+
installation
|
36
|
+
apps
|
37
|
+
widgets
|
38
|
+
customisation
|
Binary file
|
Binary file
|
Binary file
|
docs/user/widgets.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
(user.widgets)=
|
2
|
+
# Widgets
|
3
|
+
|
4
|
+
## Visualization Widgets
|
5
|
+
|
6
|
+
BEC Widgets includes a variety of visualization widgets designed to cater to diverse data representation needs in beamline experiments. These widgets enhance the user experience by providing intuitive and interactive data visualizations.
|
7
|
+
|
8
|
+
### 1D Waveform Widget
|
9
|
+
|
10
|
+
**Purpose:** This widget provides a straightforward visualization of 1D data. It is particularly useful for plotting positioner movements against detector readings, enabling users to observe correlations and patterns in a simple, linear format.
|
11
|
+
|
12
|
+
**Key Features:**
|
13
|
+
- Real-time plotting of positioner versus detector values.
|
14
|
+
- Interactive controls for zooming and panning through the data.
|
15
|
+
- Customizable visual elements such as line color and style.
|
16
|
+
|
17
|
+
**Example of Use:**
|
18
|
+

|
19
|
+
### 2D Scatter Plot
|
20
|
+
|
21
|
+
**Purpose:** The 2D scatter plot widget is designed for more complex data visualization. It employs a false color map to represent a third dimension (z-axis), making it an ideal tool for visualizing multidimensional data sets.
|
22
|
+
|
23
|
+
**Key Features:**
|
24
|
+
|
25
|
+
- 2D scatter plot with color-coded data points based on a third variable (two positioners for x/y vs. one detector for colormap).
|
26
|
+
- Interactive false color map for enhanced data interpretation.
|
27
|
+
- Tools for selecting and inspecting specific data points.
|
28
|
+
|
29
|
+
**Example of Use:**
|
30
|
+

|
31
|
+
### Motor Position Map
|
32
|
+
|
33
|
+
**Purpose:** A specialized component derived from the Motor Alignment Tool. It's focused on tracking and visualizing the position of motors, crucial for precise alignment and movement tracking during scans.
|
34
|
+
|
35
|
+
**Key Features:**
|
36
|
+
- Real-time tracking of motor positions.
|
37
|
+
- Visual representation of motor trajectories, aiding in alignment tasks.
|
38
|
+
- Ability to record and recall specific motor positions for repetitive tasks.
|
39
|
+
|
40
|
+
**Example of Use:**
|
41
|
+

|
pyproject.toml
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
[build-system]
|
2
|
+
requires = ["hatchling"]
|
3
|
+
build-backend = "hatchling.build"
|
4
|
+
|
5
|
+
[project]
|
6
|
+
name = "bec_widgets"
|
7
|
+
version = "0.53.0"
|
8
|
+
description = "BEC Widgets"
|
9
|
+
requires-python = ">=3.10"
|
10
|
+
classifiers = [
|
11
|
+
"Development Status :: 3 - Alpha",
|
12
|
+
"Programming Language :: Python :: 3",
|
13
|
+
"Topic :: Scientific/Engineering",
|
14
|
+
]
|
15
|
+
dependencies = [
|
16
|
+
"pydantic",
|
17
|
+
"qtconsole",
|
18
|
+
"jedi",
|
19
|
+
"qtpy",
|
20
|
+
"pyqtgraph",
|
21
|
+
"bec_lib",
|
22
|
+
"zmq",
|
23
|
+
"h5py",
|
24
|
+
"pyqtdarktheme",
|
25
|
+
"black",
|
26
|
+
]
|
27
|
+
|
28
|
+
|
29
|
+
[project.optional-dependencies]
|
30
|
+
dev = [
|
31
|
+
"pytest",
|
32
|
+
"pytest-random-order",
|
33
|
+
"pytest-timeout",
|
34
|
+
"coverage",
|
35
|
+
"pytest-qt",
|
36
|
+
"isort",
|
37
|
+
"fakeredis",
|
38
|
+
]
|
39
|
+
pyqt5 = ["PyQt5>=5.9"]
|
40
|
+
pyqt6 = ["PyQt6>=6.7"]
|
41
|
+
|
42
|
+
[project.urls]
|
43
|
+
"Bug Tracker" = "https://gitlab.psi.ch/bec/bec_widgets/issues"
|
44
|
+
Homepage = "https://gitlab.psi.ch/bec/bec_widgets"
|
45
|
+
|
46
|
+
[tool.hatch.build.targets.wheel]
|
47
|
+
include = ["*"]
|
48
|
+
|
49
|
+
[tool.black]
|
50
|
+
line-length = 100
|
51
|
+
skip-magic-trailing-comma = true
|
52
|
+
|
53
|
+
[tool.isort]
|
54
|
+
profile = "black"
|
55
|
+
line_length = 100
|
56
|
+
multi_line_output = 3
|
57
|
+
include_trailing_comma = true
|
58
|
+
|
59
|
+
[tool.semantic_release]
|
60
|
+
build_command = "python -m build"
|
61
|
+
version_toml = ["pyproject.toml:project.version"]
|
62
|
+
|
63
|
+
[tool.semantic_release.commit_author]
|
64
|
+
env = "GIT_COMMIT_AUTHOR"
|
65
|
+
default = "semantic-release <semantic-release>"
|
66
|
+
|
67
|
+
[tool.semantic_release.commit_parser_options]
|
68
|
+
allowed_tags = [
|
69
|
+
"build",
|
70
|
+
"chore",
|
71
|
+
"ci",
|
72
|
+
"docs",
|
73
|
+
"feat",
|
74
|
+
"fix",
|
75
|
+
"perf",
|
76
|
+
"style",
|
77
|
+
"refactor",
|
78
|
+
"test",
|
79
|
+
]
|
80
|
+
minor_tags = ["feat"]
|
81
|
+
patch_tags = ["fix", "perf"]
|
82
|
+
default_bump_level = 0
|
83
|
+
|
84
|
+
[tool.semantic_release.remote]
|
85
|
+
name = "origin"
|
86
|
+
type = "gitlab"
|
87
|
+
ignore_token_for_push = false
|
88
|
+
|
89
|
+
[tool.semantic_release.remote.token]
|
90
|
+
env = "GL_TOKEN"
|
91
|
+
|
92
|
+
[tool.semantic_release.publish]
|
93
|
+
dist_glob_patterns = ["dist/*"]
|
94
|
+
upload_to_vcs_release = true
|
@@ -41,14 +41,7 @@ def send_msg_event():
|
|
41
41
|
|
42
42
|
|
43
43
|
@pytest.mark.parametrize(
|
44
|
-
"topics_msg_list",
|
45
|
-
[
|
46
|
-
(
|
47
|
-
("topic1", dummy_msg),
|
48
|
-
("topic2", dummy_msg),
|
49
|
-
("topic3", dummy_msg),
|
50
|
-
)
|
51
|
-
],
|
44
|
+
"topics_msg_list", [(("topic1", dummy_msg), ("topic2", dummy_msg), ("topic3", dummy_msg))]
|
52
45
|
)
|
53
46
|
def test_dispatcher_disconnect_all(bec_dispatcher_w_connector, qtbot, send_msg_event):
|
54
47
|
bec_dispatcher = bec_dispatcher_w_connector
|
@@ -70,15 +63,7 @@ def test_dispatcher_disconnect_all(bec_dispatcher_w_connector, qtbot, send_msg_e
|
|
70
63
|
assert len(bec_dispatcher.client.connector._topics_cb) == 0
|
71
64
|
|
72
65
|
|
73
|
-
@pytest.mark.parametrize(
|
74
|
-
"topics_msg_list",
|
75
|
-
[
|
76
|
-
(
|
77
|
-
("topic1", dummy_msg),
|
78
|
-
("topic2", dummy_msg),
|
79
|
-
)
|
80
|
-
],
|
81
|
-
)
|
66
|
+
@pytest.mark.parametrize("topics_msg_list", [(("topic1", dummy_msg), ("topic2", dummy_msg))])
|
82
67
|
def test_dispatcher_disconnect_one(bec_dispatcher_w_connector, qtbot, send_msg_event):
|
83
68
|
# test for BEC issue #276
|
84
69
|
bec_dispatcher = bec_dispatcher_w_connector
|
@@ -115,15 +100,7 @@ def test_dispatcher_2_cb_same_topic(bec_dispatcher_w_connector, qtbot, send_msg_
|
|
115
100
|
cb2.assert_called_once()
|
116
101
|
|
117
102
|
|
118
|
-
@pytest.mark.parametrize(
|
119
|
-
"topics_msg_list",
|
120
|
-
[
|
121
|
-
(
|
122
|
-
("topic1", dummy_msg),
|
123
|
-
("topic2", dummy_msg),
|
124
|
-
)
|
125
|
-
],
|
126
|
-
)
|
103
|
+
@pytest.mark.parametrize("topics_msg_list", [(("topic1", dummy_msg), ("topic2", dummy_msg))])
|
127
104
|
def test_dispatcher_2_topic_same_cb(bec_dispatcher_w_connector, qtbot, send_msg_event):
|
128
105
|
# test for BEC issue #276
|
129
106
|
bec_dispatcher = bec_dispatcher_w_connector
|
@@ -26,11 +26,7 @@ def test_bec_figure_init(bec_figure):
|
|
26
26
|
|
27
27
|
|
28
28
|
def test_bec_figure_init_with_config(mocked_client):
|
29
|
-
config = {
|
30
|
-
"widget_class": "BECFigure",
|
31
|
-
"gui_id": "test_gui_id",
|
32
|
-
"theme": "dark",
|
33
|
-
}
|
29
|
+
config = {"widget_class": "BECFigure", "gui_id": "test_gui_id", "theme": "dark"}
|
34
30
|
widget = BECFigure(client=mocked_client, config=config)
|
35
31
|
assert widget.config.gui_id == "test_gui_id"
|
36
32
|
assert widget.config.theme == "dark"
|
@@ -29,10 +29,7 @@ def test_motor_map_change_motors(bec_motor_map):
|
|
29
29
|
|
30
30
|
|
31
31
|
def test_motor_map_get_limits(bec_motor_map):
|
32
|
-
expected_limits = {
|
33
|
-
"samx": [-10, 10],
|
34
|
-
"samy": [-5, 5],
|
35
|
-
}
|
32
|
+
expected_limits = {"samx": [-10, 10], "samy": [-5, 5]}
|
36
33
|
|
37
34
|
for motor_name, expected_limit in expected_limits.items():
|
38
35
|
actual_limit = bec_motor_map._get_motor_limit(motor_name)
|
@@ -43,11 +43,7 @@ def test_load_config(config_dialog, config_name):
|
|
43
43
|
|
44
44
|
@pytest.mark.parametrize(
|
45
45
|
"config_name, scan_mode",
|
46
|
-
[
|
47
|
-
("config_device", False),
|
48
|
-
("config_scan", True),
|
49
|
-
("config_device_no_entry", False),
|
50
|
-
],
|
46
|
+
[("config_device", False), ("config_scan", True), ("config_device_no_entry", False)],
|
51
47
|
)
|
52
48
|
def test_initialization(config_dialog, config_name, scan_mode):
|
53
49
|
config = load_test_config(config_name)
|
@@ -0,0 +1,33 @@
|
|
1
|
+
plot_settings:
|
2
|
+
background_color: "black"
|
3
|
+
num_columns: 1
|
4
|
+
colormap: "plasma"
|
5
|
+
scan_types: false
|
6
|
+
plot_data:
|
7
|
+
- plot_name: "BPM4i plots vs samx"
|
8
|
+
x_label: "Motor X"
|
9
|
+
y_label: "bpm4i"
|
10
|
+
sources:
|
11
|
+
- type: "scan_segment"
|
12
|
+
signals:
|
13
|
+
x:
|
14
|
+
- name : "samx"
|
15
|
+
entry: "samx"
|
16
|
+
y:
|
17
|
+
- name : "bpm4i"
|
18
|
+
entry: "bpm4i"
|
19
|
+
|
20
|
+
- plot_name: "Gauss plots vs samx"
|
21
|
+
x_label: "Motor X"
|
22
|
+
y_label: "Gauss"
|
23
|
+
sources:
|
24
|
+
- type: "scan_segment"
|
25
|
+
signals:
|
26
|
+
x:
|
27
|
+
- name: "samx"
|
28
|
+
entry: "samx"
|
29
|
+
y:
|
30
|
+
- name: "gauss_adc1"
|
31
|
+
entry: "gauss_adc1"
|
32
|
+
- name: "gauss_adc2"
|
33
|
+
entry: "gauss_adc2"
|
@@ -0,0 +1,27 @@
|
|
1
|
+
plot_settings:
|
2
|
+
background_color: "black"
|
3
|
+
num_columns: 1
|
4
|
+
colormap: "plasma"
|
5
|
+
scan_types: false
|
6
|
+
plot_data:
|
7
|
+
- plot_name: "BPM4i plots vs samx"
|
8
|
+
x_label: "Motor X"
|
9
|
+
y_label: "bpm4i"
|
10
|
+
sources:
|
11
|
+
- type: "scan_segment"
|
12
|
+
signals:
|
13
|
+
x:
|
14
|
+
- name : "samx"
|
15
|
+
y:
|
16
|
+
- name : "bpm4i"
|
17
|
+
|
18
|
+
- plot_name: "Gauss plots vs samx"
|
19
|
+
x_label: "Motor X"
|
20
|
+
y_label: "Gauss"
|
21
|
+
sources:
|
22
|
+
- type: "scan_segment"
|
23
|
+
signals:
|
24
|
+
x:
|
25
|
+
- name: "samx"
|
26
|
+
y:
|
27
|
+
- name: "gauss_bpm"
|
@@ -0,0 +1,82 @@
|
|
1
|
+
plot_settings:
|
2
|
+
background_color: "white"
|
3
|
+
num_columns: 3
|
4
|
+
colormap: "plasma"
|
5
|
+
scan_types: true
|
6
|
+
plot_data:
|
7
|
+
grid_scan:
|
8
|
+
- plot_name: "Grid plot 1"
|
9
|
+
x_label: "Motor X"
|
10
|
+
y_label: "BPM"
|
11
|
+
sources:
|
12
|
+
- type: "scan_segment"
|
13
|
+
signals:
|
14
|
+
x:
|
15
|
+
- name: "samx"
|
16
|
+
entry: "samx"
|
17
|
+
y:
|
18
|
+
- name: "gauss_bpm"
|
19
|
+
entry: "gauss_bpm"
|
20
|
+
- plot_name: "Grid plot 2"
|
21
|
+
x_label: "Motor X"
|
22
|
+
y_label: "BPM"
|
23
|
+
sources:
|
24
|
+
- type: "scan_segment"
|
25
|
+
signals:
|
26
|
+
x:
|
27
|
+
- name: "samx"
|
28
|
+
entry: "samx"
|
29
|
+
y:
|
30
|
+
- name: "gauss_adc1"
|
31
|
+
entry: "gauss_adc1"
|
32
|
+
- plot_name: "Grid plot 3"
|
33
|
+
x_label: "Motor X"
|
34
|
+
y_label: "BPM"
|
35
|
+
sources:
|
36
|
+
- type: "scan_segment"
|
37
|
+
signals:
|
38
|
+
x:
|
39
|
+
- name: "samx"
|
40
|
+
entry: "samx"
|
41
|
+
y:
|
42
|
+
- name: "gauss_adc2"
|
43
|
+
entry: "gauss_adc2"
|
44
|
+
- plot_name: "Grid plot 4"
|
45
|
+
x_label: "Motor X"
|
46
|
+
y_label: "BPM"
|
47
|
+
sources:
|
48
|
+
- type: "scan_segment"
|
49
|
+
signals:
|
50
|
+
x:
|
51
|
+
- name: "samx"
|
52
|
+
entry: "samx"
|
53
|
+
y:
|
54
|
+
- name: "bpm4i"
|
55
|
+
entry: "bpm4i"
|
56
|
+
line_scan:
|
57
|
+
- plot_name: "Multiple Gauss Plot"
|
58
|
+
x_label: "Motor X"
|
59
|
+
y_label: "BPM"
|
60
|
+
sources:
|
61
|
+
- type: "scan_segment"
|
62
|
+
signals:
|
63
|
+
x:
|
64
|
+
- name: "samx"
|
65
|
+
y:
|
66
|
+
- name: "gauss_bpm"
|
67
|
+
entry: "gauss_bpm"
|
68
|
+
- name: "gauss_adc1"
|
69
|
+
entry: "gauss_adc1"
|
70
|
+
- name: "gauss_adc2"
|
71
|
+
entry: "gauss_adc2"
|
72
|
+
- plot_name: "BPM Plot"
|
73
|
+
x_label: "Motor X"
|
74
|
+
y_label: "BPM"
|
75
|
+
sources:
|
76
|
+
- type: "scan_segment"
|
77
|
+
signals:
|
78
|
+
x:
|
79
|
+
- name: "samx"
|
80
|
+
y:
|
81
|
+
- name: "bpm4i"
|
82
|
+
entry: "bpm4i"
|
@@ -58,7 +58,7 @@ CONFIG_ONE_DEVICE = {
|
|
58
58
|
"x": [{"name": "samx", "entry": "samx"}],
|
59
59
|
"y": [{"name": "samy", "entry": "samy"}],
|
60
60
|
},
|
61
|
-
}
|
61
|
+
}
|
62
62
|
],
|
63
63
|
}
|
64
64
|
|
@@ -73,10 +73,7 @@ def motor_map(qtbot, mocked_client):
|
|
73
73
|
|
74
74
|
def test_motor_limits_initialization(motor_map):
|
75
75
|
# Example test to check if motor limits are correctly initialized
|
76
|
-
expected_limits = {
|
77
|
-
"samx": [-10, 10],
|
78
|
-
"samy": [-5, 5],
|
79
|
-
}
|
76
|
+
expected_limits = {"samx": [-10, 10], "samy": [-5, 5]}
|
80
77
|
for motor_name, expected_limit in expected_limits.items():
|
81
78
|
actual_limit = motor_map._get_motor_limit(motor_name)
|
82
79
|
assert actual_limit == expected_limit
|
@@ -99,13 +96,7 @@ def test_motor_initial_position(motor_map):
|
|
99
96
|
assert actual_position == expected_position
|
100
97
|
|
101
98
|
|
102
|
-
@pytest.mark.parametrize(
|
103
|
-
"config, number_of_plots",
|
104
|
-
[
|
105
|
-
(CONFIG_DEFAULT, 2),
|
106
|
-
(CONFIG_ONE_DEVICE, 1),
|
107
|
-
],
|
108
|
-
)
|
99
|
+
@pytest.mark.parametrize("config, number_of_plots", [(CONFIG_DEFAULT, 2), (CONFIG_ONE_DEVICE, 1)])
|
109
100
|
def test_initialization(motor_map, config, number_of_plots):
|
110
101
|
config_load = config
|
111
102
|
motor_map.on_config_update(config_load)
|
@@ -131,16 +122,10 @@ def test_motor_movement_updates_position_and_database(motor_map):
|
|
131
122
|
motor_map.on_device_readback({"signals": {"samx": {"value": new_position_samx}}})
|
132
123
|
|
133
124
|
# Verify database update for 'samx'
|
134
|
-
assert motor_map.database["samx"]["samx"] == [
|
135
|
-
initial_position_samx,
|
136
|
-
new_position_samx,
|
137
|
-
]
|
125
|
+
assert motor_map.database["samx"]["samx"] == [initial_position_samx, new_position_samx]
|
138
126
|
|
139
127
|
# Verify 'samy' retains its last known position
|
140
|
-
assert motor_map.database["samy"]["samy"] == [
|
141
|
-
initial_position_samy,
|
142
|
-
initial_position_samy,
|
143
|
-
]
|
128
|
+
assert motor_map.database["samy"]["samy"] == [initial_position_samy, initial_position_samy]
|
144
129
|
|
145
130
|
|
146
131
|
def test_scatter_plot_rendering(motor_map):
|
@@ -85,12 +85,7 @@ def test_1d_plotting_data(qtbot, stream_app):
|
|
85
85
|
def test_flip_even_rows(qtbot, stream_app):
|
86
86
|
# Create a numpy array with some known data
|
87
87
|
original_array = np.array(
|
88
|
-
[
|
89
|
-
[1, 2, 3, 4, 5],
|
90
|
-
[6, 7, 8, 9, 10],
|
91
|
-
[11, 12, 13, 14, 15],
|
92
|
-
[16, 17, 18, 19, 20],
|
93
|
-
]
|
88
|
+
[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]]
|
94
89
|
)
|
95
90
|
|
96
91
|
# Call flip_even_rows on the original array
|
@@ -98,12 +93,7 @@ def test_flip_even_rows(qtbot, stream_app):
|
|
98
93
|
|
99
94
|
# Expected array flipped along the rows with even indices
|
100
95
|
expected_array = np.array(
|
101
|
-
[
|
102
|
-
[1, 2, 3, 4, 5],
|
103
|
-
[10, 9, 8, 7, 6],
|
104
|
-
[11, 12, 13, 14, 15],
|
105
|
-
[20, 19, 18, 17, 16],
|
106
|
-
]
|
96
|
+
[[1, 2, 3, 4, 5], [10, 9, 8, 7, 6], [11, 12, 13, 14, 15], [20, 19, 18, 17, 16]]
|
107
97
|
)
|
108
98
|
|
109
99
|
# Check that flip_even_rows returned the expected result
|
bec_widgets/utils/ctrl_c.py
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
# TODO haven't found yet how to deal with QAbstractSocket in qtpy
|
2
|
-
# import signal
|
3
|
-
# import socket
|
4
|
-
# from PyQt5.QtNetwork import QAbstractSocket
|
5
|
-
#
|
6
|
-
#
|
7
|
-
# def setup(app):
|
8
|
-
# app.signalwatchdog = SignalWatchdog() # need to store to keep socket pair alive
|
9
|
-
# signal.signal(signal.SIGINT, make_quit_handler(app))
|
10
|
-
#
|
11
|
-
#
|
12
|
-
# def make_quit_handler(app):
|
13
|
-
# def handler(*args):
|
14
|
-
# print() # make ^C appear on its own line
|
15
|
-
# app.quit()
|
16
|
-
#
|
17
|
-
# return handler
|
18
|
-
#
|
19
|
-
#
|
20
|
-
# class SignalWatchdog(QAbstractSocket):
|
21
|
-
# def __init__(self):
|
22
|
-
# """
|
23
|
-
# Propagates system signals from Python to QEventLoop
|
24
|
-
# adapted from https://stackoverflow.com/a/65802260/655404
|
25
|
-
# """
|
26
|
-
# super().__init__(QAbstractSocket.SctpSocket, None)
|
27
|
-
#
|
28
|
-
# self.writer, self.reader = writer, reader = socket.socketpair()
|
29
|
-
# writer.setblocking(False)
|
30
|
-
#
|
31
|
-
# fd_writer = writer.fileno()
|
32
|
-
# fd_reader = reader.fileno()
|
33
|
-
#
|
34
|
-
# signal.set_wakeup_fd(fd_writer) # Python hook
|
35
|
-
# self.setSocketDescriptor(fd_reader) # Qt hook
|
36
|
-
#
|
37
|
-
# self.readyRead.connect(
|
38
|
-
# lambda: None
|
39
|
-
# ) # dummy function call that lets the Python interpreter run
|