0
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-07-14 11:41:49 +02:00

fix(cli/rpc): server access children widget.find_widget_by_id(gui_id)

This commit is contained in:
wyzula-jan
2024-02-26 13:26:55 +01:00
parent f71dc5c5ab
commit 57132a4721
4 changed files with 79 additions and 15 deletions

View File

@ -1,9 +1,8 @@
# This file was automatically generated by generate_cli.py # This file was automatically generated by generate_cli.py
from bec_widgets.cli.client_utils import rpc_call, RPCBase, BECFigureClientMixin
from typing import Literal, Optional, overload from typing import Literal, Optional, overload
from bec_widgets.cli.client_utils import BECFigureClientMixin, RPCBase, rpc_call
class BECPlotBase(RPCBase): class BECPlotBase(RPCBase):
@rpc_call @rpc_call
@ -233,6 +232,16 @@ class BECWaveform1D(RPCBase):
replot_last_scan(bool, optional): If True, replot the last scan. Defaults to False. replot_last_scan(bool, optional): If True, replot the last scan. Defaults to False.
""" """
@rpc_call
def get_all_data(self, output: "Literal['dict', 'pandas']" = "dict") -> "dict | pd.DataFrame":
"""
Extract all curve data into a dictionary or a pandas DataFrame.
Args:
output (Literal["dict", "pandas"]): Format of the output data.
Returns:
dict | pd.DataFrame: Data of all curves in the specified format.
"""
class BECFigure(RPCBase, BECFigureClientMixin): class BECFigure(RPCBase, BECFigureClientMixin):
@rpc_call @rpc_call
@ -367,3 +376,11 @@ class BECCurve(RPCBase):
Args: Args:
pen_style(Literal["solid", "dash", "dot", "dashdot"]): Style of the pen. pen_style(Literal["solid", "dash", "dot", "dashdot"]): Style of the pen.
""" """
@rpc_call
def get_data(self) -> "tuple[np.ndarray, np.ndarray]":
"""
Get the data of the curve.
Returns:
tuple[np.ndarray,np.ndarray]: X and Y data of the curve.
"""

View File

@ -5,14 +5,14 @@ from bec_lib import MessageEndpoints, messages
from bec_widgets.utils import BECDispatcher from bec_widgets.utils import BECDispatcher
from bec_widgets.utils.bec_connector import BECConnector from bec_widgets.utils.bec_connector import BECConnector
from bec_widgets.widgets.figure import BECFigure from bec_widgets.widgets.figure import BECFigure
from bec_widgets.widgets.plots import BECCurve, BECPlotBase, BECWaveform1D from bec_widgets.widgets.plots import BECCurve, BECWaveform1D
class BECWidgetsCLIServer: class BECWidgetsCLIServer:
WIDGETS = [BECWaveform1D, BECFigure, BECCurve] WIDGETS = [BECWaveform1D, BECFigure, BECCurve]
def __init__(self, gui_id: str = None) -> None: def __init__(self, gui_id: str = None, dispatcher: BECDispatcher = None) -> None:
self.dispatcher = BECDispatcher() self.dispatcher = BECDispatcher() if dispatcher is None else dispatcher
self.client = self.dispatcher.client self.client = self.dispatcher.client
self.client.start() self.client.start()
self.gui_id = gui_id self.gui_id = gui_id
@ -22,6 +22,9 @@ class BECWidgetsCLIServer:
self.dispatcher.connect_slot( self.dispatcher.connect_slot(
self.on_rpc_update, MessageEndpoints.gui_instructions(self.gui_id) self.on_rpc_update, MessageEndpoints.gui_instructions(self.gui_id)
) )
def start(self):
"""Start the figure window."""
self.fig.start() self.fig.start()
@staticmethod @staticmethod
@ -59,10 +62,9 @@ class BECWidgetsCLIServer:
return obj return obj
if self.fig.widgets: if self.fig.widgets:
for widget in self.fig.widgets.values(): for widget in self.fig.widgets.values():
if isinstance(widget, BECWaveform1D): item = widget.find_widget_by_id(gui_id)
for curve in widget.curves: if item:
if curve.gui_id == gui_id: return item
return curve
raise NotImplementedError( raise NotImplementedError(
f"gui_id lookup for widget of type {widget.__class__.__name__} not implemented" f"gui_id lookup for widget of type {widget.__class__.__name__} not implemented"
) )
@ -107,3 +109,4 @@ if __name__ == "__main__":
server = BECWidgetsCLIServer(gui_id=args.id) server = BECWidgetsCLIServer(gui_id=args.id)
# server = BECWidgetsCLIServer(gui_id="test") # server = BECWidgetsCLIServer(gui_id="test")
server.start()

View File

@ -1,7 +1,7 @@
from __future__ import annotations from __future__ import annotations
from collections import defaultdict from collections import defaultdict
from typing import Any, Literal, Optional from typing import Literal, Optional, Any
import numpy as np import numpy as np
import pyqtgraph as pg import pyqtgraph as pg
@ -72,6 +72,7 @@ class BECCurve(BECConnector, pg.PlotDataItem):
"set_symbol_size", "set_symbol_size",
"set_pen_width", "set_pen_width",
"set_pen_style", "set_pen_style",
"get_data",
] ]
def __init__( def __init__(
@ -204,6 +205,15 @@ class BECCurve(BECConnector, pg.PlotDataItem):
self.config.pen_style = pen_style self.config.pen_style = pen_style
self.apply_config() self.apply_config()
def get_data(self) -> tuple[np.ndarray, np.ndarray]:
"""
Get the data of the curve.
Returns:
tuple[np.ndarray,np.ndarray]: X and Y data of the curve.
"""
x_data, y_data = self.getData()
return x_data, y_data
class BECWaveform1D(BECPlotBase): class BECWaveform1D(BECPlotBase):
USER_ACCESS = [ USER_ACCESS = [
@ -216,6 +226,7 @@ class BECWaveform1D(BECPlotBase):
"get_curve", "get_curve",
"get_curve_config", "get_curve_config",
"apply_config", "apply_config",
"get_all_data",
] ]
scan_signal_update = pyqtSignal() scan_signal_update = pyqtSignal()
@ -254,6 +265,13 @@ class BECWaveform1D(BECPlotBase):
# TODO check config assigning # TODO check config assigning
# TODO check the functionality of config generator # TODO check the functionality of config generator
def find_widget_by_id(
self, item_id: str
): # TODO implement this on level of BECConnector and all other widgets
for curve in self.curves:
if curve.gui_id == item_id:
return curve
def apply_config(self, config: dict | WidgetConfig, replot_last_scan: bool = False): def apply_config(self, config: dict | WidgetConfig, replot_last_scan: bool = False):
""" """
Apply the configuration to the 1D waveform widget. Apply the configuration to the 1D waveform widget.
@ -273,8 +291,8 @@ class BECWaveform1D(BECPlotBase):
self.apply_axis_config() self.apply_axis_config()
# Reset curves # Reset curves
self.curves_data = defaultdict(dict) self._curves_data = defaultdict(dict)
self.curves = [] self._curves = []
for curve_id, curve_config in self.config.curves.items(): for curve_id, curve_config in self.config.curves.items():
self.add_curve_by_config(curve_config) self.add_curve_by_config(curve_config)
if replot_last_scan: if replot_last_scan:
@ -291,7 +309,7 @@ class BECWaveform1D(BECPlotBase):
self.gui_id = new_gui_id self.gui_id = new_gui_id
self.config.gui_id = new_gui_id self.config.gui_id = new_gui_id
for curve_id, curve in self.curves_data.items(): for curve in self.curves:
curve.config.parent_id = new_gui_id curve.config.parent_id = new_gui_id
def add_curve_by_config(self, curve_config: CurveConfig | dict) -> BECCurve: def add_curve_by_config(self, curve_config: CurveConfig | dict) -> BECCurve:
@ -324,6 +342,31 @@ class BECWaveform1D(BECPlotBase):
else: else:
return curves[curve_id].config return curves[curve_id].config
@property
def curves(self) -> list[BECCurve]: # TODO discuss if it should be marked as @property for RPC
"""
Get the curves of the plot widget as a list
Returns:
list: List of curves.
"""
return self._curves
@curves.setter
def curves(self, value: list[BECCurve]):
self._curves = value
@property
def curves_data(self) -> dict: # TODO discuss if it should be marked as @property for RPC
"""
Get the curves data of the plot widget as a dictionary
Returns:
dict: Dictionary of curves data.
"""
return self._curves_data
@curves_data.setter
def curves_data(self, value: dict):
self._curves_data = value
def get_curve(self, identifier) -> BECCurve: def get_curve(self, identifier) -> BECCurve:
""" """

View File

@ -140,8 +140,9 @@ def test_getting_curve(bec_figure):
y=SignalData(name="bpm4i", entry="bpm4i", unit=None, modifier=None), y=SignalData(name="bpm4i", entry="bpm4i", unit=None, modifier=None),
), ),
) )
assert w1.get_curves()[0].config == c1_expected_config
assert w1.get_curves_data()["scan_segment"]["bpm4i-bpm4i"].config == c1_expected_config assert w1.curves[0].config == c1_expected_config
assert w1.curves_data["scan_segment"]["bpm4i-bpm4i"].config == c1_expected_config
assert w1.get_curve(0).config == c1_expected_config assert w1.get_curve(0).config == c1_expected_config
assert w1.get_curve("bpm4i-bpm4i").config == c1_expected_config assert w1.get_curve("bpm4i-bpm4i").config == c1_expected_config
assert c1.get_config(False) == c1_expected_config assert c1.get_config(False) == c1_expected_config