bec-widgets 1.25.1__py3-none-any.whl → 2.0.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.
- .gitlab-ci.yml +3 -5
- CHANGELOG.md +631 -0
- PKG-INFO +3 -3
- bec_widgets/__init__.py +4 -0
- bec_widgets/applications/bw_launch.py +23 -0
- bec_widgets/applications/launch_window.py +430 -0
- bec_widgets/assets/app_icons/auto_update.png +0 -0
- bec_widgets/assets/app_icons/ui_loader_tile.png +0 -0
- bec_widgets/cli/__init__.py +0 -1
- bec_widgets/cli/client.py +1779 -2064
- bec_widgets/cli/client_utils.py +346 -174
- bec_widgets/cli/generate_cli.py +143 -37
- bec_widgets/cli/rpc/rpc_base.py +152 -21
- bec_widgets/cli/rpc/rpc_register.py +113 -6
- bec_widgets/cli/rpc/rpc_widget_handler.py +13 -11
- bec_widgets/cli/server.py +125 -239
- bec_widgets/examples/jupyter_console/jupyter_console_window.py +97 -145
- bec_widgets/examples/plugin_example_pyside/tictactoetaskmenu.py +1 -1
- bec_widgets/utils/bec_connector.py +190 -21
- bec_widgets/utils/bec_designer.py +7 -0
- bec_widgets/utils/bec_dispatcher.py +71 -4
- bec_widgets/utils/bec_plugin_helper.py +89 -0
- bec_widgets/utils/bec_signal_proxy.py +1 -1
- bec_widgets/utils/bec_widget.py +26 -10
- bec_widgets/utils/colors.py +1 -1
- bec_widgets/{qt_utils → utils}/compact_popup.py +2 -0
- bec_widgets/utils/container_utils.py +37 -12
- bec_widgets/utils/crosshair.py +25 -8
- bec_widgets/utils/entry_validator.py +3 -1
- bec_widgets/{qt_utils → utils}/error_popups.py +18 -0
- bec_widgets/{qt_utils → utils}/expandable_frame.py +2 -2
- bec_widgets/utils/forms_from_types/forms.py +182 -0
- bec_widgets/{widgets/editors/scan_metadata/_metadata_widgets.py → utils/forms_from_types/items.py} +41 -30
- bec_widgets/utils/generate_designer_plugin.py +40 -36
- bec_widgets/utils/linear_region_selector.py +2 -0
- bec_widgets/utils/name_utils.py +16 -0
- bec_widgets/{qt_utils → utils}/palette_viewer.py +2 -2
- bec_widgets/utils/plot_indicator_items.py +2 -5
- bec_widgets/utils/plugin_utils.py +47 -1
- bec_widgets/{qt_utils → utils}/round_frame.py +14 -14
- bec_widgets/utils/rpc_server.py +277 -0
- bec_widgets/utils/serialization.py +44 -0
- bec_widgets/{qt_utils → utils}/settings_dialog.py +26 -1
- bec_widgets/{qt_utils → utils}/side_panel.py +17 -10
- bec_widgets/{qt_utils → utils}/toolbar.py +69 -25
- bec_widgets/utils/ui_loader.py +8 -8
- bec_widgets/utils/widget_io.py +166 -25
- bec_widgets/widgets/containers/auto_update/auto_updates.py +364 -0
- bec_widgets/widgets/containers/dock/dock.py +157 -49
- bec_widgets/widgets/containers/dock/dock_area.py +186 -138
- bec_widgets/widgets/containers/layout_manager/layout_manager.py +2 -1
- bec_widgets/widgets/containers/main_window/addons/web_links.py +15 -0
- bec_widgets/widgets/containers/main_window/main_window.py +189 -41
- bec_widgets/widgets/control/buttons/button_abort/button_abort.py +3 -4
- bec_widgets/widgets/control/buttons/button_reset/button_reset.py +3 -4
- bec_widgets/widgets/control/buttons/button_resume/button_resume.py +3 -3
- bec_widgets/widgets/control/buttons/stop_button/stop_button.py +18 -7
- bec_widgets/widgets/control/device_control/position_indicator/position_indicator.py +22 -3
- bec_widgets/widgets/control/device_control/positioner_box/_base/positioner_box_base.py +31 -13
- bec_widgets/widgets/control/device_control/positioner_box/positioner_box/positioner_box.py +3 -1
- bec_widgets/widgets/control/device_control/positioner_box/positioner_box/positioner_box.ui +27 -4
- bec_widgets/widgets/control/device_control/positioner_box/positioner_box_2d/positioner_box_2d.py +5 -2
- bec_widgets/widgets/control/device_control/positioner_box/positioner_box_2d/positioner_box_2d.ui +97 -31
- bec_widgets/widgets/control/device_control/positioner_box/positioner_control_line/positioner_control_line.ui +11 -4
- bec_widgets/widgets/control/device_control/positioner_group/positioner_group.py +2 -3
- bec_widgets/widgets/control/device_input/base_classes/device_input_base.py +29 -4
- bec_widgets/widgets/control/device_input/base_classes/device_signal_input_base.py +1 -0
- bec_widgets/widgets/control/device_input/device_combobox/device_combobox.py +2 -2
- bec_widgets/widgets/control/device_input/device_line_edit/device_line_edit.py +2 -2
- bec_widgets/widgets/control/device_input/signal_combobox/signal_combobox.py +1 -2
- bec_widgets/widgets/control/device_input/signal_line_edit/signal_line_edit.py +1 -2
- bec_widgets/widgets/control/scan_control/scan_control.py +7 -5
- bec_widgets/widgets/control/scan_control/scan_group_box.py +28 -5
- bec_widgets/widgets/dap/dap_combo_box/dap_combo_box.py +1 -2
- bec_widgets/widgets/dap/lmfit_dialog/lmfit_dialog.py +3 -4
- bec_widgets/widgets/dap/lmfit_dialog/lmfit_dialog_vertical.ui +14 -8
- bec_widgets/widgets/editors/console/console.py +1 -1
- bec_widgets/widgets/editors/{scan_metadata/additional_metadata_table.py → dict_backed_table.py} +29 -6
- bec_widgets/widgets/editors/scan_metadata/__init__.py +0 -7
- bec_widgets/widgets/editors/scan_metadata/_util.py +1 -1
- bec_widgets/widgets/{plots/motor_map/register_bec_motor_map_widget.py → editors/scan_metadata/register_scan_metadata.py} +2 -4
- bec_widgets/widgets/editors/scan_metadata/scan_metadata.py +42 -136
- bec_widgets/widgets/editors/scan_metadata/scan_metadata.pyproject +1 -0
- bec_widgets/widgets/{plots/multi_waveform/bec_multi_waveform_widget_plugin.py → editors/scan_metadata/scan_metadata_plugin.py} +9 -9
- bec_widgets/widgets/editors/text_box/text_box.py +2 -3
- bec_widgets/widgets/editors/website/website.py +2 -2
- bec_widgets/widgets/games/minesweeper.py +3 -2
- bec_widgets/widgets/plots/image/image.py +960 -0
- bec_widgets/widgets/plots/image/image.pyproject +1 -0
- bec_widgets/widgets/plots/image/image_item.py +279 -0
- bec_widgets/widgets/plots/{motor_map/bec_motor_map_widget_plugin.py → image/image_plugin.py} +11 -13
- bec_widgets/widgets/{containers/figure/plots → plots}/image/image_processor.py +31 -64
- bec_widgets/widgets/plots/image/{register_bec_image_widget.py → register_image.py} +2 -2
- bec_widgets/widgets/plots/image/toolbar_bundles/image_selection.py +59 -0
- bec_widgets/widgets/plots/image/toolbar_bundles/processing.py +79 -0
- bec_widgets/widgets/plots/motor_map/motor_map.py +832 -0
- bec_widgets/widgets/plots/motor_map/motor_map.pyproject +1 -0
- bec_widgets/widgets/plots/motor_map/motor_map_plugin.py +54 -0
- bec_widgets/widgets/plots/{multi_waveform/register_bec_multi_waveform_widget.py → motor_map/register_motor_map.py} +2 -4
- bec_widgets/widgets/plots/motor_map/settings/motor_map_settings.py +129 -0
- bec_widgets/widgets/plots/motor_map/settings/motor_map_settings.ui +120 -0
- bec_widgets/widgets/plots/motor_map/toolbar_bundles/motor_selection.py +70 -0
- bec_widgets/widgets/plots/multi_waveform/multi_waveform.py +508 -0
- bec_widgets/widgets/plots/multi_waveform/multi_waveform.pyproject +1 -0
- bec_widgets/widgets/plots/multi_waveform/multi_waveform_plugin.py +54 -0
- bec_widgets/widgets/plots/multi_waveform/register_multi_waveform.py +15 -0
- bec_widgets/widgets/plots/multi_waveform/settings/control_panel.py +144 -0
- bec_widgets/widgets/plots/multi_waveform/settings/multi_waveform_controls.ui +164 -0
- bec_widgets/widgets/plots/multi_waveform/toolbar_bundles/monitor_selection.py +65 -0
- bec_widgets/widgets/{plots_next_gen → plots}/plot_base.py +321 -40
- bec_widgets/widgets/plots/{waveform/register_bec_waveform_widget.py → scatter_waveform/register_scatter_waveform.py} +3 -3
- bec_widgets/widgets/plots/scatter_waveform/scatter_curve.py +197 -0
- bec_widgets/widgets/plots/scatter_waveform/scatter_waveform.py +553 -0
- bec_widgets/widgets/plots/scatter_waveform/scatter_waveform.pyproject +1 -0
- bec_widgets/widgets/plots/{image/bec_image_widget_plugin.py → scatter_waveform/scatter_waveform_plugin.py} +9 -13
- bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_setting.py +138 -0
- bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_horizontal.ui +195 -0
- bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_vertical.ui +204 -0
- bec_widgets/widgets/{plots_next_gen → plots}/setting_menus/axis_settings.py +8 -8
- bec_widgets/widgets/{plots_next_gen → plots}/toolbar_bundles/mouse_interactions.py +4 -18
- bec_widgets/widgets/{plots_next_gen → plots}/toolbar_bundles/plot_export.py +14 -3
- bec_widgets/widgets/{plots_next_gen → plots}/toolbar_bundles/roi_bundle.py +6 -1
- bec_widgets/widgets/{plots_next_gen → plots}/toolbar_bundles/save_state.py +2 -2
- bec_widgets/widgets/{containers/figure/plots/waveform/waveform_curve.py → plots/waveform/curve.py} +119 -49
- bec_widgets/widgets/plots/waveform/register_waveform.py +15 -0
- bec_widgets/widgets/plots/waveform/settings/curve_settings/curve_setting.py +125 -0
- bec_widgets/widgets/plots/waveform/settings/curve_settings/curve_tree.py +576 -0
- bec_widgets/widgets/plots/waveform/utils/__init__.py +0 -0
- bec_widgets/widgets/plots/waveform/utils/roi_manager.py +84 -0
- bec_widgets/widgets/plots/waveform/waveform.py +1794 -0
- bec_widgets/widgets/plots/waveform/waveform.pyproject +1 -0
- bec_widgets/widgets/plots/waveform/{bec_waveform_widget_plugin.py → waveform_plugin.py} +9 -13
- bec_widgets/widgets/progress/bec_progressbar/bec_progressbar.py +1 -2
- bec_widgets/widgets/progress/ring_progress_bar/ring.py +11 -10
- bec_widgets/widgets/progress/ring_progress_bar/ring_progress_bar.py +24 -14
- bec_widgets/widgets/services/bec_queue/bec_queue.py +13 -11
- bec_widgets/widgets/services/bec_status_box/bec_status_box.py +3 -4
- bec_widgets/widgets/services/device_browser/device_browser.py +5 -2
- bec_widgets/widgets/services/device_browser/device_item/device_item.py +1 -1
- bec_widgets/widgets/utility/logpanel/logpanel.py +36 -17
- bec_widgets/widgets/utility/spinbox/decimal_spinbox.py +3 -3
- bec_widgets/widgets/utility/visual/color_button/color_button.py +1 -1
- bec_widgets/widgets/utility/visual/colormap_widget/colormap_widget.py +4 -6
- bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button.py +4 -8
- {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.0.dist-info}/METADATA +3 -3
- {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.0.dist-info}/RECORD +168 -153
- pyproject.toml +3 -3
- bec_widgets/applications/alignment/alignment_1d/alignment_1d.py +0 -198
- bec_widgets/applications/alignment/alignment_1d/alignment_1d.ui +0 -615
- bec_widgets/applications/bec_app.py +0 -84
- bec_widgets/cli/auto_updates.py +0 -168
- bec_widgets/widgets/containers/figure/__init__.py +0 -1
- bec_widgets/widgets/containers/figure/figure.py +0 -796
- bec_widgets/widgets/containers/figure/plots/axis_settings.py +0 -91
- bec_widgets/widgets/containers/figure/plots/axis_settings.ui +0 -256
- bec_widgets/widgets/containers/figure/plots/image/image.py +0 -772
- bec_widgets/widgets/containers/figure/plots/image/image_item.py +0 -337
- bec_widgets/widgets/containers/figure/plots/motor_map/motor_map.py +0 -525
- bec_widgets/widgets/containers/figure/plots/multi_waveform/multi_waveform.py +0 -340
- bec_widgets/widgets/containers/figure/plots/plot_base.py +0 -505
- bec_widgets/widgets/containers/figure/plots/waveform/waveform.py +0 -1563
- bec_widgets/widgets/plots/image/bec_image_widget.pyproject +0 -1
- bec_widgets/widgets/plots/image/image_widget.py +0 -515
- bec_widgets/widgets/plots/motor_map/bec_motor_map_widget.pyproject +0 -1
- bec_widgets/widgets/plots/motor_map/motor_map_dialog/motor_map_settings.py +0 -56
- bec_widgets/widgets/plots/motor_map/motor_map_dialog/motor_map_settings.ui +0 -108
- bec_widgets/widgets/plots/motor_map/motor_map_widget.py +0 -234
- bec_widgets/widgets/plots/multi_waveform/bec_multi_waveform_widget.pyproject +0 -1
- bec_widgets/widgets/plots/multi_waveform/multi_waveform_controls.ui +0 -99
- bec_widgets/widgets/plots/multi_waveform/multi_waveform_widget.py +0 -536
- bec_widgets/widgets/plots/waveform/bec_waveform_widget.pyproject +0 -1
- bec_widgets/widgets/plots/waveform/waveform_popups/curve_dialog/curve_dialog.py +0 -336
- bec_widgets/widgets/plots/waveform/waveform_popups/curve_dialog/curve_dialog.ui +0 -372
- bec_widgets/widgets/plots/waveform/waveform_popups/dap_summary_dialog/dap_summary_dialog.py +0 -25
- bec_widgets/widgets/plots/waveform/waveform_widget.py +0 -751
- /bec_widgets/{qt_utils → utils}/collapsible_panel_manager.py +0 -0
- /bec_widgets/{applications/alignment → utils/forms_from_types}/__init__.py +0 -0
- /bec_widgets/{qt_utils → utils}/redis_message_waiter.py +0 -0
- /bec_widgets/{applications/alignment/alignment_1d → widgets/containers/auto_update}/__init__.py +0 -0
- /bec_widgets/{qt_utils → widgets/containers/main_window/addons}/__init__.py +0 -0
- /bec_widgets/widgets/{containers/figure/plots → plots/image/toolbar_bundles}/__init__.py +0 -0
- /bec_widgets/widgets/{containers/figure/plots/image → plots/motor_map/settings}/__init__.py +0 -0
- /bec_widgets/widgets/{containers/figure/plots/motor_map → plots/motor_map/toolbar_bundles}/__init__.py +0 -0
- /bec_widgets/widgets/{containers/figure/plots/multi_waveform → plots/multi_waveform/settings}/__init__.py +0 -0
- /bec_widgets/widgets/{containers/figure/plots/waveform → plots/multi_waveform/toolbar_bundles}/__init__.py +0 -0
- /bec_widgets/widgets/plots/{motor_map/motor_map_dialog → scatter_waveform}/__init__.py +0 -0
- /bec_widgets/widgets/plots/{waveform/waveform_popups → scatter_waveform/settings}/__init__.py +0 -0
- /bec_widgets/widgets/plots/{waveform/waveform_popups/curve_dialog → setting_menus}/__init__.py +0 -0
- /bec_widgets/widgets/{plots_next_gen → plots}/setting_menus/axis_settings_horizontal.ui +0 -0
- /bec_widgets/widgets/{plots_next_gen → plots}/setting_menus/axis_settings_vertical.ui +0 -0
- /bec_widgets/widgets/plots/{waveform/waveform_popups/dap_summary_dialog → toolbar_bundles}/__init__.py +0 -0
- /bec_widgets/widgets/{plots_next_gen/setting_menus → plots/waveform/settings}/__init__.py +0 -0
- /bec_widgets/widgets/{plots_next_gen/toolbar_bundles → plots/waveform/settings/curve_settings}/__init__.py +0 -0
- {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.0.dist-info}/WHEEL +0 -0
- {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.0.dist-info}/entry_points.txt +0 -0
- {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,340 +0,0 @@
|
|
1
|
-
from collections import deque
|
2
|
-
from typing import Literal, Optional
|
3
|
-
|
4
|
-
import pyqtgraph as pg
|
5
|
-
from bec_lib.endpoints import MessageEndpoints
|
6
|
-
from bec_lib.logger import bec_logger
|
7
|
-
from pydantic import Field, field_validator
|
8
|
-
from pyqtgraph.exporters import MatplotlibExporter
|
9
|
-
from qtpy.QtCore import Signal, Slot
|
10
|
-
from qtpy.QtWidgets import QWidget
|
11
|
-
|
12
|
-
from bec_widgets.utils import Colors
|
13
|
-
from bec_widgets.widgets.containers.figure.plots.plot_base import BECPlotBase, SubplotConfig
|
14
|
-
|
15
|
-
logger = bec_logger.logger
|
16
|
-
|
17
|
-
|
18
|
-
class BECMultiWaveformConfig(SubplotConfig):
|
19
|
-
color_palette: Optional[str] = Field(
|
20
|
-
"magma", description="The color palette of the figure widget.", validate_default=True
|
21
|
-
)
|
22
|
-
curve_limit: Optional[int] = Field(
|
23
|
-
200, description="The maximum number of curves to display on the plot."
|
24
|
-
)
|
25
|
-
flush_buffer: Optional[bool] = Field(
|
26
|
-
False, description="Flush the buffer of the plot widget when the curve limit is reached."
|
27
|
-
)
|
28
|
-
monitor: Optional[str] = Field(
|
29
|
-
None, description="The monitor to set for the plot widget."
|
30
|
-
) # TODO validate monitor in bec -> maybe make it as SignalData class for validation purpose
|
31
|
-
curve_width: Optional[int] = Field(1, description="The width of the curve on the plot.")
|
32
|
-
opacity: Optional[int] = Field(50, description="The opacity of the curve on the plot.")
|
33
|
-
highlight_last_curve: Optional[bool] = Field(
|
34
|
-
True, description="Highlight the last curve on the plot."
|
35
|
-
)
|
36
|
-
|
37
|
-
model_config: dict = {"validate_assignment": True}
|
38
|
-
_validate_color_map_z = field_validator("color_palette")(Colors.validate_color_map)
|
39
|
-
|
40
|
-
|
41
|
-
class BECMultiWaveform(BECPlotBase):
|
42
|
-
monitor_signal_updated = Signal()
|
43
|
-
highlighted_curve_index_changed = Signal(int)
|
44
|
-
USER_ACCESS = [
|
45
|
-
"_rpc_id",
|
46
|
-
"_config_dict",
|
47
|
-
"curves",
|
48
|
-
"set_monitor",
|
49
|
-
"set_opacity",
|
50
|
-
"set_curve_limit",
|
51
|
-
"set_curve_highlight",
|
52
|
-
"set_colormap",
|
53
|
-
"set",
|
54
|
-
"set_title",
|
55
|
-
"set_x_label",
|
56
|
-
"set_y_label",
|
57
|
-
"set_x_scale",
|
58
|
-
"set_y_scale",
|
59
|
-
"set_x_lim",
|
60
|
-
"set_y_lim",
|
61
|
-
"set_grid",
|
62
|
-
"set_colormap",
|
63
|
-
"enable_fps_monitor",
|
64
|
-
"lock_aspect_ratio",
|
65
|
-
"export",
|
66
|
-
"get_all_data",
|
67
|
-
"remove",
|
68
|
-
]
|
69
|
-
|
70
|
-
def __init__(
|
71
|
-
self,
|
72
|
-
parent: Optional[QWidget] = None,
|
73
|
-
parent_figure=None,
|
74
|
-
config: Optional[BECMultiWaveformConfig] = None,
|
75
|
-
client=None,
|
76
|
-
gui_id: Optional[str] = None,
|
77
|
-
):
|
78
|
-
if config is None:
|
79
|
-
config = BECMultiWaveformConfig(widget_class=self.__class__.__name__)
|
80
|
-
super().__init__(
|
81
|
-
parent=parent, parent_figure=parent_figure, config=config, client=client, gui_id=gui_id
|
82
|
-
)
|
83
|
-
self.old_scan_id = None
|
84
|
-
self.scan_id = None
|
85
|
-
self.monitor = None
|
86
|
-
self.connected = False
|
87
|
-
self.current_highlight_index = 0
|
88
|
-
self._curves = deque()
|
89
|
-
self.visible_curves = []
|
90
|
-
self.number_of_visible_curves = 0
|
91
|
-
|
92
|
-
# Get bec shortcuts dev, scans, queue, scan_storage, dap
|
93
|
-
self.get_bec_shortcuts()
|
94
|
-
|
95
|
-
@property
|
96
|
-
def curves(self) -> deque:
|
97
|
-
"""
|
98
|
-
Get the curves of the plot widget as a deque.
|
99
|
-
Returns:
|
100
|
-
deque: Deque of curves.
|
101
|
-
"""
|
102
|
-
return self._curves
|
103
|
-
|
104
|
-
@curves.setter
|
105
|
-
def curves(self, value: deque):
|
106
|
-
self._curves = value
|
107
|
-
|
108
|
-
@property
|
109
|
-
def highlight_last_curve(self) -> bool:
|
110
|
-
"""
|
111
|
-
Get the highlight_last_curve property.
|
112
|
-
Returns:
|
113
|
-
bool: The highlight_last_curve property.
|
114
|
-
"""
|
115
|
-
return self.config.highlight_last_curve
|
116
|
-
|
117
|
-
@highlight_last_curve.setter
|
118
|
-
def highlight_last_curve(self, value: bool):
|
119
|
-
self.config.highlight_last_curve = value
|
120
|
-
|
121
|
-
def set_monitor(self, monitor: str):
|
122
|
-
"""
|
123
|
-
Set the monitor for the plot widget.
|
124
|
-
Args:
|
125
|
-
monitor (str): The monitor to set.
|
126
|
-
"""
|
127
|
-
self.config.monitor = monitor
|
128
|
-
self._connect_monitor()
|
129
|
-
|
130
|
-
def _connect_monitor(self):
|
131
|
-
"""
|
132
|
-
Connect the monitor to the plot widget.
|
133
|
-
"""
|
134
|
-
try:
|
135
|
-
previous_monitor = self.monitor
|
136
|
-
except AttributeError:
|
137
|
-
previous_monitor = None
|
138
|
-
|
139
|
-
if previous_monitor and self.connected is True:
|
140
|
-
self.bec_dispatcher.disconnect_slot(
|
141
|
-
self.on_monitor_1d_update, MessageEndpoints.device_monitor_1d(previous_monitor)
|
142
|
-
)
|
143
|
-
if self.config.monitor and self.connected is False:
|
144
|
-
self.bec_dispatcher.connect_slot(
|
145
|
-
self.on_monitor_1d_update, MessageEndpoints.device_monitor_1d(self.config.monitor)
|
146
|
-
)
|
147
|
-
self.connected = True
|
148
|
-
self.monitor = self.config.monitor
|
149
|
-
|
150
|
-
@Slot(dict, dict)
|
151
|
-
def on_monitor_1d_update(self, msg: dict, metadata: dict):
|
152
|
-
"""
|
153
|
-
Update the plot widget with the monitor data.
|
154
|
-
|
155
|
-
Args:
|
156
|
-
msg(dict): The message data.
|
157
|
-
metadata(dict): The metadata of the message.
|
158
|
-
"""
|
159
|
-
data = msg.get("data", None)
|
160
|
-
current_scan_id = metadata.get("scan_id", None)
|
161
|
-
|
162
|
-
if current_scan_id != self.scan_id:
|
163
|
-
self.scan_id = current_scan_id
|
164
|
-
self.clear_curves()
|
165
|
-
self.curves.clear()
|
166
|
-
if self.crosshair:
|
167
|
-
self.crosshair.clear_markers()
|
168
|
-
|
169
|
-
# Always create a new curve and add it
|
170
|
-
curve = pg.PlotDataItem()
|
171
|
-
curve.setData(data)
|
172
|
-
self.plot_item.addItem(curve)
|
173
|
-
self.curves.append(curve)
|
174
|
-
|
175
|
-
# Max Trace and scale colors
|
176
|
-
self.set_curve_limit(self.config.curve_limit, self.config.flush_buffer)
|
177
|
-
|
178
|
-
self.monitor_signal_updated.emit()
|
179
|
-
|
180
|
-
@Slot(int)
|
181
|
-
def set_curve_highlight(self, index: int):
|
182
|
-
"""
|
183
|
-
Set the curve highlight based on visible curves.
|
184
|
-
|
185
|
-
Args:
|
186
|
-
index (int): The index of the curve to highlight among visible curves.
|
187
|
-
"""
|
188
|
-
self.plot_item.visible_curves = [curve for curve in self.curves if curve.isVisible()]
|
189
|
-
num_visible_curves = len(self.plot_item.visible_curves)
|
190
|
-
self.number_of_visible_curves = num_visible_curves
|
191
|
-
|
192
|
-
if num_visible_curves == 0:
|
193
|
-
return # No curves to highlight
|
194
|
-
|
195
|
-
if index >= num_visible_curves:
|
196
|
-
index = num_visible_curves - 1
|
197
|
-
elif index < 0:
|
198
|
-
index = num_visible_curves + index
|
199
|
-
self.current_highlight_index = index
|
200
|
-
num_colors = num_visible_curves
|
201
|
-
colors = Colors.evenly_spaced_colors(
|
202
|
-
colormap=self.config.color_palette, num=num_colors, format="HEX"
|
203
|
-
)
|
204
|
-
for i, curve in enumerate(self.plot_item.visible_curves):
|
205
|
-
curve.setPen()
|
206
|
-
if i == self.current_highlight_index:
|
207
|
-
curve.setPen(pg.mkPen(color=colors[i], width=5))
|
208
|
-
curve.setAlpha(alpha=1, auto=False)
|
209
|
-
curve.setZValue(1)
|
210
|
-
else:
|
211
|
-
curve.setPen(pg.mkPen(color=colors[i], width=1))
|
212
|
-
curve.setAlpha(alpha=self.config.opacity / 100, auto=False)
|
213
|
-
curve.setZValue(0)
|
214
|
-
|
215
|
-
self.highlighted_curve_index_changed.emit(self.current_highlight_index)
|
216
|
-
|
217
|
-
@Slot(int)
|
218
|
-
def set_opacity(self, opacity: int):
|
219
|
-
"""
|
220
|
-
Set the opacity of the curve on the plot.
|
221
|
-
|
222
|
-
Args:
|
223
|
-
opacity(int): The opacity of the curve. 0-100.
|
224
|
-
"""
|
225
|
-
self.config.opacity = max(0, min(100, opacity))
|
226
|
-
self.set_curve_highlight(self.current_highlight_index)
|
227
|
-
|
228
|
-
@Slot(int, bool)
|
229
|
-
def set_curve_limit(self, max_trace: int, flush_buffer: bool = False):
|
230
|
-
"""
|
231
|
-
Set the maximum number of traces to display on the plot.
|
232
|
-
|
233
|
-
Args:
|
234
|
-
max_trace (int): The maximum number of traces to display.
|
235
|
-
flush_buffer (bool): Flush the buffer.
|
236
|
-
"""
|
237
|
-
self.config.curve_limit = max_trace
|
238
|
-
self.config.flush_buffer = flush_buffer
|
239
|
-
|
240
|
-
if self.config.curve_limit is None:
|
241
|
-
self.scale_colors()
|
242
|
-
return
|
243
|
-
|
244
|
-
if self.config.flush_buffer:
|
245
|
-
# Remove excess curves from the plot and the deque
|
246
|
-
while len(self.curves) > self.config.curve_limit:
|
247
|
-
curve = self.curves.popleft()
|
248
|
-
self.plot_item.removeItem(curve)
|
249
|
-
else:
|
250
|
-
# Hide or show curves based on the new max_trace
|
251
|
-
num_curves_to_show = min(self.config.curve_limit, len(self.curves))
|
252
|
-
for i, curve in enumerate(self.curves):
|
253
|
-
if i < len(self.curves) - num_curves_to_show:
|
254
|
-
curve.hide()
|
255
|
-
else:
|
256
|
-
curve.show()
|
257
|
-
self.scale_colors()
|
258
|
-
|
259
|
-
def scale_colors(self):
|
260
|
-
"""
|
261
|
-
Scale the colors of the curves based on the current colormap.
|
262
|
-
"""
|
263
|
-
if self.config.highlight_last_curve:
|
264
|
-
self.set_curve_highlight(-1) # Use -1 to highlight the last visible curve
|
265
|
-
else:
|
266
|
-
self.set_curve_highlight(self.current_highlight_index)
|
267
|
-
|
268
|
-
def set_colormap(self, colormap: str):
|
269
|
-
"""
|
270
|
-
Set the colormap for the curves.
|
271
|
-
|
272
|
-
Args:
|
273
|
-
colormap(str): Colormap for the curves.
|
274
|
-
"""
|
275
|
-
self.config.color_palette = colormap
|
276
|
-
self.set_curve_highlight(self.current_highlight_index)
|
277
|
-
|
278
|
-
def hook_crosshair(self) -> None:
|
279
|
-
super().hook_crosshair()
|
280
|
-
if self.crosshair:
|
281
|
-
self.highlighted_curve_index_changed.connect(self.crosshair.update_highlighted_curve)
|
282
|
-
if self.curves:
|
283
|
-
self.crosshair.update_highlighted_curve(self.current_highlight_index)
|
284
|
-
|
285
|
-
def get_all_data(self, output: Literal["dict", "pandas"] = "dict") -> dict:
|
286
|
-
"""
|
287
|
-
Extract all curve data into a dictionary or a pandas DataFrame.
|
288
|
-
|
289
|
-
Args:
|
290
|
-
output (Literal["dict", "pandas"]): Format of the output data.
|
291
|
-
|
292
|
-
Returns:
|
293
|
-
dict | pd.DataFrame: Data of all curves in the specified format.
|
294
|
-
"""
|
295
|
-
data = {}
|
296
|
-
try:
|
297
|
-
import pandas as pd
|
298
|
-
except ImportError:
|
299
|
-
pd = None
|
300
|
-
if output == "pandas":
|
301
|
-
logger.warning(
|
302
|
-
"Pandas is not installed. "
|
303
|
-
"Please install pandas using 'pip install pandas'."
|
304
|
-
"Output will be dictionary instead."
|
305
|
-
)
|
306
|
-
output = "dict"
|
307
|
-
|
308
|
-
curve_keys = []
|
309
|
-
curves_list = list(self.curves)
|
310
|
-
for i, curve in enumerate(curves_list):
|
311
|
-
x_data, y_data = curve.getData()
|
312
|
-
if x_data is not None or y_data is not None:
|
313
|
-
key = f"curve_{i}"
|
314
|
-
curve_keys.append(key)
|
315
|
-
if output == "dict":
|
316
|
-
data[key] = {"x": x_data.tolist(), "y": y_data.tolist()}
|
317
|
-
elif output == "pandas" and pd is not None:
|
318
|
-
data[key] = pd.DataFrame({"x": x_data, "y": y_data})
|
319
|
-
|
320
|
-
if output == "pandas" and pd is not None:
|
321
|
-
combined_data = pd.concat([data[key] for key in curve_keys], axis=1, keys=curve_keys)
|
322
|
-
return combined_data
|
323
|
-
return data
|
324
|
-
|
325
|
-
def clear_curves(self):
|
326
|
-
"""
|
327
|
-
Remove all curves from the plot, excluding crosshair items.
|
328
|
-
"""
|
329
|
-
items_to_remove = []
|
330
|
-
for item in self.plot_item.items:
|
331
|
-
if not getattr(item, "is_crosshair", False) and isinstance(item, pg.PlotDataItem):
|
332
|
-
items_to_remove.append(item)
|
333
|
-
for item in items_to_remove:
|
334
|
-
self.plot_item.removeItem(item)
|
335
|
-
|
336
|
-
def export_to_matplotlib(self):
|
337
|
-
"""
|
338
|
-
Export current waveform to matplotlib GUI. Available only if matplotlib is installed in the environment.
|
339
|
-
"""
|
340
|
-
MatplotlibExporter(self.plot_item).export()
|