diff --git a/bec_widgets/applications/views/device_manager_view/device_manager_dialogs/upload_redis_dialog.py b/bec_widgets/applications/views/device_manager_view/device_manager_dialogs/upload_redis_dialog.py
index ec4e7f014..a192a7482 100644
--- a/bec_widgets/applications/views/device_manager_view/device_manager_dialogs/upload_redis_dialog.py
+++ b/bec_widgets/applications/views/device_manager_view/device_manager_dialogs/upload_redis_dialog.py
@@ -4,7 +4,7 @@
from enum import IntEnum
from functools import partial
-from typing import TYPE_CHECKING, List, Tuple
+from typing import TYPE_CHECKING, Any, List, Tuple
from bec_lib.logger import bec_logger
from bec_qthemes import apply_theme, material_icon
diff --git a/bec_widgets/applications/views/view.py b/bec_widgets/applications/views/view.py
index 3b98f7568..c1351aa60 100644
--- a/bec_widgets/applications/views/view.py
+++ b/bec_widgets/applications/views/view.py
@@ -102,17 +102,17 @@ def on_enter(self) -> None:
self.device_edit.insertItem(0, "")
self.device_edit.setEditable(True)
self.device_edit.setCurrentIndex(0)
- self.entry_edit = SignalComboBox(parent=self)
- self.entry_edit.include_config_signals = False
- self.entry_edit.insertItem(0, "")
- self.entry_edit.setEditable(True)
- self.device_edit.currentTextChanged.connect(self.entry_edit.set_device)
- self.device_edit.device_reset.connect(self.entry_edit.reset_selection)
+ self.signal_edit = SignalComboBox(parent=self)
+ self.signal_edit.include_config_signals = False
+ self.signal_edit.insertItem(0, "")
+ self.signal_edit.setEditable(True)
+ self.device_edit.currentTextChanged.connect(self.signal_edit.set_device)
+ self.device_edit.device_reset.connect(self.signal_edit.reset_selection)
form = QFormLayout()
form.addRow(label)
form.addRow("Device", self.device_edit)
- form.addRow("Signal", self.entry_edit)
+ form.addRow("Signal", self.signal_edit)
buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, parent=dialog)
buttons.accepted.connect(dialog.accept)
@@ -124,7 +124,7 @@ def on_enter(self) -> None:
if dialog.exec_() == QDialog.Accepted:
self.waveform.plot(
- y_name=self.device_edit.currentText(), y_entry=self.entry_edit.currentText()
+ device_y=self.device_edit.currentText(), signal_y=self.signal_edit.currentText()
)
@SafeSlot()
@@ -249,7 +249,7 @@ def _apply_settings_and_show_waveform(self):
dev = self.device_edit.currentText()
sig = self.entry_edit.currentText()
if dev and sig:
- self.waveform.plot(y_name=dev, y_entry=sig)
+ self.waveform.plot(device_y=dev, signal_y=sig)
self.stack.setCurrentIndex(1)
def _show_waveform_without_changes(self):
diff --git a/bec_widgets/cli/client.py b/bec_widgets/cli/client.py
index cf6eb1726..e9e157630 100644
--- a/bec_widgets/cli/client.py
+++ b/bec_widgets/cli/client.py
@@ -1965,12 +1965,12 @@ def rois(self) -> "list[BaseROI]":
@rpc_call
def plot(
self,
- x_name: "str",
- y_name: "str",
- z_name: "str",
- x_entry: "None | str" = None,
- y_entry: "None | str" = None,
- z_entry: "None | str" = None,
+ device_x: "str",
+ device_y: "str",
+ device_z: "str",
+ signal_x: "None | str" = None,
+ signal_y: "None | str" = None,
+ signal_z: "None | str" = None,
color_map: "str | None" = "plasma",
validate_bec: "bool" = True,
interpolation: "Literal['linear', 'nearest'] | None" = None,
@@ -1984,12 +1984,12 @@ def plot(
Plot the heatmap with the given x, y, and z data.
Args:
- x_name (str): The name of the x-axis signal.
- y_name (str): The name of the y-axis signal.
- z_name (str): The name of the z-axis signal.
- x_entry (str | None): The entry for the x-axis signal.
- y_entry (str | None): The entry for the y-axis signal.
- z_entry (str | None): The entry for the z-axis signal.
+ device_x (str): The name of the x-axis device signal.
+ device_y (str): The name of the y-axis device signal.
+ device_z (str): The name of the z-axis device signal.
+ signal_x (str | None): The entry for the x-axis device signal.
+ signal_y (str | None): The entry for the y-axis device signal.
+ signal_z (str | None): The entry for the z-axis device signal.
color_map (str | None): The color map to use for the heatmap.
validate_bec (bool): Whether to validate the entries against BEC signals.
interpolation (Literal["linear", "nearest"] | None): The interpolation method to use.
@@ -2002,84 +2002,84 @@ def plot(
@property
@rpc_call
- def x_device_name(self) -> "str":
+ def device_x(self) -> "str":
"""
Device name for the X axis.
"""
- @x_device_name.setter
+ @device_x.setter
@rpc_call
- def x_device_name(self) -> "str":
+ def device_x(self) -> "str":
"""
Device name for the X axis.
"""
@property
@rpc_call
- def x_device_entry(self) -> "str":
+ def signal_x(self) -> "str":
"""
Signal entry for the X axis device.
"""
- @x_device_entry.setter
+ @signal_x.setter
@rpc_call
- def x_device_entry(self) -> "str":
+ def signal_x(self) -> "str":
"""
Signal entry for the X axis device.
"""
@property
@rpc_call
- def y_device_name(self) -> "str":
+ def device_y(self) -> "str":
"""
Device name for the Y axis.
"""
- @y_device_name.setter
+ @device_y.setter
@rpc_call
- def y_device_name(self) -> "str":
+ def device_y(self) -> "str":
"""
Device name for the Y axis.
"""
@property
@rpc_call
- def y_device_entry(self) -> "str":
+ def signal_y(self) -> "str":
"""
Signal entry for the Y axis device.
"""
- @y_device_entry.setter
+ @signal_y.setter
@rpc_call
- def y_device_entry(self) -> "str":
+ def signal_y(self) -> "str":
"""
Signal entry for the Y axis device.
"""
@property
@rpc_call
- def z_device_name(self) -> "str":
+ def device_z(self) -> "str":
"""
Device name for the Z (color) axis.
"""
- @z_device_name.setter
+ @device_z.setter
@rpc_call
- def z_device_name(self) -> "str":
+ def device_z(self) -> "str":
"""
Device name for the Z (color) axis.
"""
@property
@rpc_call
- def z_device_entry(self) -> "str":
+ def signal_z(self) -> "str":
"""
Signal entry for the Z (color) axis device.
"""
- @z_device_entry.setter
+ @signal_z.setter
@rpc_call
- def z_device_entry(self) -> "str":
+ def signal_z(self) -> "str":
"""
Signal entry for the Z (color) axis device.
"""
@@ -2501,28 +2501,28 @@ def autorange_mode(self) -> "str":
@property
@rpc_call
- def device_name(self) -> "str":
+ def device(self) -> "str":
"""
The name of the device to monitor for image data.
"""
- @device_name.setter
+ @device.setter
@rpc_call
- def device_name(self) -> "str":
+ def device(self) -> "str":
"""
The name of the device to monitor for image data.
"""
@property
@rpc_call
- def device_entry(self) -> "str":
+ def signal(self) -> "str":
"""
The signal/entry name to monitor on the device.
"""
- @device_entry.setter
+ @signal.setter
@rpc_call
- def device_entry(self) -> "str":
+ def signal(self) -> "str":
"""
The signal/entry name to monitor on the device.
"""
@@ -2630,8 +2630,8 @@ def transpose(self) -> "bool":
@rpc_call
def image(
self,
- device_name: "str | None" = None,
- device_entry: "str | None" = None,
+ device: "str | None" = None,
+ signal: "str | None" = None,
color_map: "str | None" = None,
color_bar: "Literal['simple', 'full'] | None" = None,
vrange: "tuple[int, int] | None" = None,
@@ -2640,8 +2640,8 @@ def image(
Set the image source and update the image.
Args:
- device_name(str|None): The name of the device to monitor. If None or empty string, the current monitor will be disconnected.
- device_entry(str|None): The signal/entry name to monitor on the device.
+ device(str|None): The name of the device to monitor. If None or empty string, the current monitor will be disconnected.
+ signal(str|None): The signal/entry name to monitor on the device.
color_map(str): The color map to use for the image.
color_bar(str): The type of color bar to use. Options are "simple" or "full".
vrange(tuple): The range of values to use for the color map.
@@ -3653,14 +3653,14 @@ def scatter_size(self) -> "int":
@rpc_call
def map(
- self, x_name: "str", y_name: "str", validate_bec: "bool" = True, suppress_errors=False
+ self, device_x: "str", device_y: "str", validate_bec: "bool" = True, suppress_errors=False
) -> "None":
"""
Set the x and y motor names.
Args:
- x_name(str): The name of the x motor.
- y_name(str): The name of the y motor.
+ device_x(str): The name of the x motor.
+ device_y(str): The name of the y motor.
validate_bec(bool, optional): If True, validate the signal with BEC. Defaults to True.
suppress_errors(bool, optional): If True, suppress errors during validation. Defaults to False. Used for properties setting. If the validation fails, the changes are not applied.
"""
@@ -3682,28 +3682,28 @@ def get_data(self) -> "dict":
@property
@rpc_call
- def x_motor(self) -> "str":
+ def device_x(self) -> "str":
"""
Name of the motor shown on the X axis.
"""
- @x_motor.setter
+ @device_x.setter
@rpc_call
- def x_motor(self) -> "str":
+ def device_x(self) -> "str":
"""
Name of the motor shown on the X axis.
"""
@property
@rpc_call
- def y_motor(self) -> "str":
+ def device_y(self) -> "str":
"""
Name of the motor shown on the Y axis.
"""
- @y_motor.setter
+ @device_y.setter
@rpc_call
- def y_motor(self) -> "str":
+ def device_y(self) -> "str":
"""
Name of the motor shown on the Y axis.
"""
@@ -5248,12 +5248,12 @@ def color_map(self) -> "str":
@rpc_call
def plot(
self,
- x_name: "str",
- y_name: "str",
- z_name: "str",
- x_entry: "None | str" = None,
- y_entry: "None | str" = None,
- z_entry: "None | str" = None,
+ device_x: "str",
+ device_y: "str",
+ device_z: "str",
+ signal_x: "None | str" = None,
+ signal_y: "None | str" = None,
+ signal_z: "None | str" = None,
color_map: "str | None" = "plasma",
label: "str | None" = None,
validate_bec: "bool" = True,
@@ -5262,12 +5262,12 @@ def plot(
Plot the data from the device signals.
Args:
- x_name (str): The name of the x device signal.
- y_name (str): The name of the y device signal.
- z_name (str): The name of the z device signal.
- x_entry (None | str): The x entry of the device signal.
- y_entry (None | str): The y entry of the device signal.
- z_entry (None | str): The z entry of the device signal.
+ device_x (str): The name of the x device signal.
+ device_y (str): The name of the y device signal.
+ device_z (str): The name of the z device signal.
+ signal_x (None | str): The x entry of the device signal.
+ signal_y (None | str): The y entry of the device signal.
+ signal_z (None | str): The z entry of the device signal.
color_map (str | None): The color map of the scatter waveform.
label (str | None): The label of the curve.
validate_bec (bool): Whether to validate the device signals with current BEC instance.
@@ -5295,84 +5295,84 @@ def clear_all(self):
@property
@rpc_call
- def x_device_name(self) -> "str":
+ def device_x(self) -> "str":
"""
Device name for the X axis.
"""
- @x_device_name.setter
+ @device_x.setter
@rpc_call
- def x_device_name(self) -> "str":
+ def device_x(self) -> "str":
"""
Device name for the X axis.
"""
@property
@rpc_call
- def x_device_entry(self) -> "str":
+ def signal_x(self) -> "str":
"""
Signal entry for the X axis device.
"""
- @x_device_entry.setter
+ @signal_x.setter
@rpc_call
- def x_device_entry(self) -> "str":
+ def signal_x(self) -> "str":
"""
Signal entry for the X axis device.
"""
@property
@rpc_call
- def y_device_name(self) -> "str":
+ def device_y(self) -> "str":
"""
Device name for the Y axis.
"""
- @y_device_name.setter
+ @device_y.setter
@rpc_call
- def y_device_name(self) -> "str":
+ def device_y(self) -> "str":
"""
Device name for the Y axis.
"""
@property
@rpc_call
- def y_device_entry(self) -> "str":
+ def signal_y(self) -> "str":
"""
Signal entry for the Y axis device.
"""
- @y_device_entry.setter
+ @signal_y.setter
@rpc_call
- def y_device_entry(self) -> "str":
+ def signal_y(self) -> "str":
"""
Signal entry for the Y axis device.
"""
@property
@rpc_call
- def z_device_name(self) -> "str":
+ def device_z(self) -> "str":
"""
Device name for the Z (color) axis.
"""
- @z_device_name.setter
+ @device_z.setter
@rpc_call
- def z_device_name(self) -> "str":
+ def device_z(self) -> "str":
"""
Device name for the Z (color) axis.
"""
@property
@rpc_call
- def z_device_entry(self) -> "str":
+ def signal_z(self) -> "str":
"""
Signal entry for the Z (color) axis device.
"""
- @z_device_entry.setter
+ @signal_z.setter
@rpc_call
- def z_device_entry(self) -> "str":
+ def signal_z(self) -> "str":
"""
Signal entry for the Z (color) axis device.
"""
@@ -5900,14 +5900,14 @@ def x_mode(self) -> "str":
@property
@rpc_call
- def x_entry(self) -> "str | None":
+ def signal_x(self) -> "str | None":
"""
The x signal name.
"""
- @x_entry.setter
+ @signal_x.setter
@rpc_call
- def x_entry(self) -> "str | None":
+ def signal_x(self) -> "str | None":
"""
The x signal name.
"""
@@ -5974,10 +5974,10 @@ def plot(
arg1: "list | np.ndarray | str | None" = None,
y: "list | np.ndarray | None" = None,
x: "list | np.ndarray | None" = None,
- x_name: "str | None" = None,
- y_name: "str | None" = None,
- x_entry: "str | None" = None,
- y_entry: "str | None" = None,
+ device_x: "str | None" = None,
+ device_y: "str | None" = None,
+ signal_x: "str | None" = None,
+ signal_y: "str | None" = None,
color: "str | None" = None,
label: "str | None" = None,
dap: "str | None" = None,
@@ -5989,17 +5989,17 @@ def plot(
Plot a curve to the plot widget.
Args:
- arg1(list | np.ndarray | str | None): First argument, which can be x data, y data, or y_name.
+ arg1(list | np.ndarray | str | None): First argument, which can be x data, y data, or device_y.
y(list | np.ndarray): Custom y data to plot.
x(list | np.ndarray): Custom y data to plot.
- x_name(str): Name of the x signal.
+ device_x(str): Name of the x signal.
- "auto": Use the best effort signal.
- "timestamp": Use the timestamp signal.
- "index": Use the index signal.
- Custom signal name of a device from BEC.
- y_name(str): The name of the device for the y-axis.
- x_entry(str): The name of the entry for the x-axis.
- y_entry(str): The name of the entry for the y-axis.
+ device_y(str): The name of the device for the y-axis.
+ signal_x(str): The name of the entry for the x-axis.
+ signal_y(str): The name of the entry for the y-axis.
color(str): The color of the curve.
label(str): The label of the curve.
dap(str): The dap model to use for the curve. When provided, a DAP curve is
diff --git a/bec_widgets/widgets/containers/auto_update/auto_updates.py b/bec_widgets/widgets/containers/auto_update/auto_updates.py
index e3c7a7092..856de98ed 100644
--- a/bec_widgets/widgets/containers/auto_update/auto_updates.py
+++ b/bec_widgets/widgets/containers/auto_update/auto_updates.py
@@ -256,8 +256,8 @@ def simple_line_scan(self, info: ScanStatusMessage) -> None:
# as the label and title
wf.clear_all()
wf.plot(
- x_name=dev_x,
- y_name=dev_y,
+ device_x=dev_x,
+ device_y=dev_y,
label=f"Scan {info.scan_number} - {dev_y}",
title=f"Scan {info.scan_number}",
x_label=dev_x,
@@ -265,7 +265,7 @@ def simple_line_scan(self, info: ScanStatusMessage) -> None:
)
logger.info(
- f"Auto Update [simple_line_scan]: Started plot with: x_name={dev_x}, y_name={dev_y}"
+ f"Auto Update [simple_line_scan]: Started plot with: device_x={dev_x}, device_y={dev_y}"
)
def simple_grid_scan(self, info: ScanStatusMessage) -> None:
@@ -288,11 +288,14 @@ def simple_grid_scan(self, info: ScanStatusMessage) -> None:
# Clear the scatter waveform widget and plot the data
scatter.clear_all()
scatter.plot(
- x_name=dev_x, y_name=dev_y, z_name=dev_z, label=f"Scan {info.scan_number} - {dev_z}"
+ device_x=dev_x,
+ device_y=dev_y,
+ device_z=dev_z,
+ label=f"Scan {info.scan_number} - {dev_z}",
)
logger.info(
- f"Auto Update [simple_grid_scan]: Started plot with: x_name={dev_x}, y_name={dev_y}, z_name={dev_z}"
+ f"Auto Update [simple_grid_scan]: Started plot with: device_x={dev_x}, device_y={dev_y}, device_z={dev_z}"
)
def best_effort(self, info: ScanStatusMessage) -> None:
@@ -317,15 +320,17 @@ def best_effort(self, info: ScanStatusMessage) -> None:
# Clear the waveform widget and plot the data
wf.clear_all()
wf.plot(
- x_name=dev_x,
- y_name=dev_y,
+ device_x=dev_x,
+ device_y=dev_y,
label=f"Scan {info.scan_number} - {dev_y}",
title=f"Scan {info.scan_number}",
x_label=dev_x,
y_label=dev_y,
)
- logger.info(f"Auto Update [best_effort]: Started plot with: x_name={dev_x}, y_name={dev_y}")
+ logger.info(
+ f"Auto Update [best_effort]: Started plot with: device_x={dev_x}, device_y={dev_y}"
+ )
#######################################################################
################# GUI Callbacks #######################################
diff --git a/bec_widgets/widgets/control/device_input/base_classes/device_signal_input_base.py b/bec_widgets/widgets/control/device_input/base_classes/device_signal_input_base.py
index 07e993e3d..cc03c9a31 100644
--- a/bec_widgets/widgets/control/device_input/base_classes/device_signal_input_base.py
+++ b/bec_widgets/widgets/control/device_input/base_classes/device_signal_input_base.py
@@ -266,6 +266,7 @@ def validate_device(self, device: str | None, raise_on_false: bool = False) -> b
Args:
device(str): Device to validate.
+ raise_on_false(bool): Raise ValueError if device is not found.
"""
if device in self.dev:
return True
diff --git a/bec_widgets/widgets/plots/heatmap/heatmap.py b/bec_widgets/widgets/plots/heatmap/heatmap.py
index 3266d9b74..22287ca3f 100644
--- a/bec_widgets/widgets/plots/heatmap/heatmap.py
+++ b/bec_widgets/widgets/plots/heatmap/heatmap.py
@@ -35,8 +35,8 @@
class HeatmapDeviceSignal(BaseModel):
"""The configuration of a signal in the scatter waveform widget."""
- name: str
- entry: str
+ device: str
+ signal: str
model_config: dict = {"validate_assignment": True}
@@ -65,13 +65,13 @@ class HeatmapConfig(ConnectionConfig):
lock_aspect_ratio: bool = Field(
False, description="Whether to lock the aspect ratio of the image."
)
- x_device: HeatmapDeviceSignal | None = Field(
+ device_x: HeatmapDeviceSignal | None = Field(
None, description="The x device signal of the heatmap."
)
- y_device: HeatmapDeviceSignal | None = Field(
+ device_y: HeatmapDeviceSignal | None = Field(
None, description="The y device signal of the heatmap."
)
- z_device: HeatmapDeviceSignal | None = Field(
+ device_z: HeatmapDeviceSignal | None = Field(
None, description="The z device signal of the heatmap."
)
@@ -204,18 +204,18 @@ class Heatmap(ImageBase):
"rois",
"plot",
# Device properties
- "x_device_name",
- "x_device_name.setter",
- "x_device_entry",
- "x_device_entry.setter",
- "y_device_name",
- "y_device_name.setter",
- "y_device_entry",
- "y_device_entry.setter",
- "z_device_name",
- "z_device_name.setter",
- "z_device_entry",
- "z_device_entry.setter",
+ "device_x",
+ "device_x.setter",
+ "signal_x",
+ "signal_x.setter",
+ "device_y",
+ "device_y.setter",
+ "signal_y",
+ "signal_y.setter",
+ "device_z",
+ "device_z.setter",
+ "signal_z",
+ "signal_z.setter",
]
PLUGIN = True
@@ -238,9 +238,9 @@ def __init__(self, parent=None, config: HeatmapConfig | None = None, **kwargs):
interpolation="linear",
oversampling_factor=1.0,
lock_aspect_ratio=False,
- x_device=None,
- y_device=None,
- z_device=None,
+ device_x=None,
+ device_y=None,
+ device_z=None,
)
super().__init__(parent=parent, config=config, theme_update=True, **kwargs)
self._image_config = config
@@ -314,12 +314,12 @@ def apply_theme(self, theme: str):
@SafeSlot(popup_error=True)
def plot(
self,
- x_name: str,
- y_name: str,
- z_name: str,
- x_entry: None | str = None,
- y_entry: None | str = None,
- z_entry: None | str = None,
+ device_x: str,
+ device_y: str,
+ device_z: str,
+ signal_x: None | str = None,
+ signal_y: None | str = None,
+ signal_z: None | str = None,
color_map: str | None = "plasma",
validate_bec: bool = True,
interpolation: Literal["linear", "nearest"] | None = None,
@@ -333,12 +333,12 @@ def plot(
Plot the heatmap with the given x, y, and z data.
Args:
- x_name (str): The name of the x-axis signal.
- y_name (str): The name of the y-axis signal.
- z_name (str): The name of the z-axis signal.
- x_entry (str | None): The entry for the x-axis signal.
- y_entry (str | None): The entry for the y-axis signal.
- z_entry (str | None): The entry for the z-axis signal.
+ device_x (str): The name of the x-axis device signal.
+ device_y (str): The name of the y-axis device signal.
+ device_z (str): The name of the z-axis device signal.
+ signal_x (str | None): The entry for the x-axis device signal.
+ signal_y (str | None): The entry for the y-axis device signal.
+ signal_z (str | None): The entry for the z-axis device signal.
color_map (str | None): The color map to use for the heatmap.
validate_bec (bool): Whether to validate the entries against BEC signals.
interpolation (Literal["linear", "nearest"] | None): The interpolation method to use.
@@ -349,13 +349,13 @@ def plot(
reload (bool): Whether to reload the heatmap with new data.
"""
if validate_bec:
- x_entry = self.entry_validator.validate_signal(x_name, x_entry)
- y_entry = self.entry_validator.validate_signal(y_name, y_entry)
- z_entry = self.entry_validator.validate_signal(z_name, z_entry)
+ signal_x = self.entry_validator.validate_signal(device_x, signal_x)
+ signal_y = self.entry_validator.validate_signal(device_y, signal_y)
+ signal_z = self.entry_validator.validate_signal(device_z, signal_z)
- if x_entry is None or y_entry is None or z_entry is None:
+ if signal_x is None or signal_y is None or signal_z is None:
raise ValueError("x, y, and z entries must be provided.")
- if x_name is None or y_name is None or z_name is None:
+ if device_x is None or device_y is None or device_z is None:
raise ValueError("x, y, and z names must be provided.")
if interpolation is None:
@@ -374,24 +374,24 @@ def plot(
show_config_label = self._image_config.show_config_label
def _device_key(device: HeatmapDeviceSignal | None) -> tuple[str | None, str | None]:
- return (device.name if device else None, device.entry if device else None)
+ return (device.device if device else None, device.signal if device else None)
prev_cfg = getattr(self, "_image_config", None)
config_changed = False
- if prev_cfg and prev_cfg.x_device and prev_cfg.y_device and prev_cfg.z_device:
+ if prev_cfg and prev_cfg.device_x and prev_cfg.device_y and prev_cfg.device_z:
config_changed = any(
(
- _device_key(prev_cfg.x_device) != (x_name, x_entry),
- _device_key(prev_cfg.y_device) != (y_name, y_entry),
- _device_key(prev_cfg.z_device) != (z_name, z_entry),
+ _device_key(prev_cfg.device_x) != (device_x, signal_x),
+ _device_key(prev_cfg.device_y) != (device_y, signal_y),
+ _device_key(prev_cfg.device_z) != (device_z, signal_z),
)
)
self._image_config = HeatmapConfig(
parent_id=self.gui_id,
- x_device=HeatmapDeviceSignal(name=x_name, entry=x_entry),
- y_device=HeatmapDeviceSignal(name=y_name, entry=y_entry),
- z_device=HeatmapDeviceSignal(name=z_name, entry=z_entry),
+ device_x=HeatmapDeviceSignal(device=device_x, signal=signal_x),
+ device_y=HeatmapDeviceSignal(device=device_y, signal=signal_y),
+ device_z=HeatmapDeviceSignal(device=device_z, signal=signal_z),
color_map=color_map,
color_bar=None,
interpolation=interpolation,
@@ -428,26 +428,26 @@ def update_labels(self):
return
# Safely get device names (might be None if not yet configured)
- x_device = self._image_config.x_device
- y_device = self._image_config.y_device
- z_device = self._image_config.z_device
+ device_x = self._image_config.device_x
+ device_y = self._image_config.device_y
+ device_z = self._image_config.device_z
- x_name = x_device.name if x_device else None
- y_name = y_device.name if y_device else None
- z_name = z_device.name if z_device else None
+ device_x_name = device_x.device if device_x else None
+ device_y_name = device_y.device if device_y else None
+ device_z_name = device_z.device if device_z else None
- if x_name is not None:
- self.x_label = x_name # type: ignore
- x_dev = self.dev.get(x_name)
+ if device_x_name is not None:
+ self.x_label = device_x_name # type: ignore
+ x_dev = self.dev.get(device_x_name)
if x_dev and hasattr(x_dev, "egu"):
self.x_label_units = x_dev.egu()
- if y_name is not None:
- self.y_label = y_name # type: ignore
- y_dev = self.dev.get(y_name)
+ if device_y_name is not None:
+ self.y_label = device_y_name # type: ignore
+ y_dev = self.dev.get(device_y_name)
if y_dev and hasattr(y_dev, "egu"):
self.y_label_units = y_dev.egu()
- if z_name is not None:
- self.title = z_name
+ if device_z_name is not None:
+ self.title = device_z_name
def _init_toolbar_heatmap(self):
"""
@@ -572,23 +572,23 @@ def update_plot(self, _=None) -> None:
if self._image_config is None:
return
try:
- x_name = self._image_config.x_device.name
- x_entry = self._image_config.x_device.entry
- y_name = self._image_config.y_device.name
- y_entry = self._image_config.y_device.entry
- z_name = self._image_config.z_device.name
- z_entry = self._image_config.z_device.entry
+ device_x = self._image_config.device_x.device
+ signal_x = self._image_config.device_x.signal
+ device_y = self._image_config.device_y.device
+ signal_y = self._image_config.device_y.signal
+ device_z = self._image_config.device_z.device
+ signal_z = self._image_config.device_z.signal
except AttributeError:
return
if access_key == "val":
- x_data = data.get(x_name, {}).get(x_entry, {}).get(access_key, None)
- y_data = data.get(y_name, {}).get(y_entry, {}).get(access_key, None)
- z_data = data.get(z_name, {}).get(z_entry, {}).get(access_key, None)
+ x_data = data.get(device_x, {}).get(signal_x, {}).get(access_key, None)
+ y_data = data.get(device_y, {}).get(signal_y, {}).get(access_key, None)
+ z_data = data.get(device_z, {}).get(signal_z, {}).get(access_key, None)
else:
- x_data = data.get(x_name, {}).get(x_entry, {}).read().get("value", None)
- y_data = data.get(y_name, {}).get(y_entry, {}).read().get("value", None)
- z_data = data.get(z_name, {}).get(z_entry, {}).read().get("value", None)
+ x_data = data.get(device_x, {}).get(signal_x, {}).read().get("value", None)
+ y_data = data.get(device_y, {}).get(signal_y, {}).read().get("value", None)
+ z_data = data.get(device_z, {}).get(signal_z, {}).read().get("value", None)
if not isinstance(x_data, list):
x_data = x_data.tolist() if isinstance(x_data, np.ndarray) else None
@@ -839,7 +839,6 @@ def get_image_data(
x_data (np.ndarray): The x data.
y_data (np.ndarray): The y data.
z_data (np.ndarray): The z data.
- msg (messages.ScanStatusMessage): The scan status message.
Returns:
tuple[np.ndarray, QTransform]: The image data and the QTransform.
@@ -854,7 +853,7 @@ def get_image_data(
if len(z_data) < 4:
# LinearNDInterpolator requires at least 4 points to interpolate
return None, None
- return self.get_step_scan_image(x_data, y_data, z_data, msg)
+ return self.get_step_scan_image(x_data, y_data, z_data)
def _is_grid_scan_supported(self, msg: messages.ScanStatusMessage) -> bool:
"""Check if the scan can use optimized grid_scan rendering.
@@ -871,11 +870,11 @@ def _is_grid_scan_supported(self, msg: messages.ScanStatusMessage) -> bool:
if msg.scan_name != "grid_scan" or self._image_config.enforce_interpolation:
return False
- device_x = self._image_config.x_device.entry
- device_y = self._image_config.y_device.entry
+ signal_x = self._image_config.device_x.signal
+ signal_y = self._image_config.device_y.signal
return (
- device_x in msg.request_inputs["arg_bundle"]
- and device_y in msg.request_inputs["arg_bundle"]
+ signal_x in msg.request_inputs["arg_bundle"]
+ and signal_y in msg.request_inputs["arg_bundle"]
)
def get_grid_scan_image(
@@ -893,9 +892,9 @@ def get_grid_scan_image(
args = self.arg_bundle_to_dict(4, msg.request_inputs["arg_bundle"])
- x_entry = self._image_config.x_device.entry
- y_entry = self._image_config.y_device.entry
- shape = (args[x_entry][-1], args[y_entry][-1])
+ signal_x = self._image_config.device_x.signal
+ signal_y = self._image_config.device_y.signal
+ shape = (args[signal_x][-1], args[signal_y][-1])
data = self.main_image.raw_data
@@ -925,8 +924,8 @@ def _axis_levels(entry: str, npts: int) -> np.ndarray:
return origin + np.linspace(start, stop, npts)
return np.linspace(start, stop, npts)
- x_levels = _axis_levels(x_entry, shape[0])
- y_levels = _axis_levels(y_entry, shape[1])
+ x_levels = _axis_levels(signal_x, shape[0])
+ y_levels = _axis_levels(signal_y, shape[1])
pixel_size_x = (
float(x_levels[-1] - x_levels[0]) / max(shape[0] - 1, 1) if shape[0] > 1 else 1.0
@@ -949,7 +948,7 @@ def _axis_levels(entry: str, npts: int) -> np.ndarray:
if snaked and (slow_i % 2 == 1):
fast_i = args[fast_entry][-1] - 1 - fast_i
- if x_entry == fast_entry:
+ if signal_x == fast_entry:
x_i, y_i = fast_i, slow_i
else:
x_i, y_i = slow_i, fast_i
@@ -959,11 +958,7 @@ def _axis_levels(entry: str, npts: int) -> np.ndarray:
return data, transform
def get_step_scan_image(
- self,
- x_data: list[float],
- y_data: list[float],
- z_data: list[float],
- msg: messages.ScanStatusMessage,
+ self, x_data: list[float], y_data: list[float], z_data: list[float]
) -> tuple[np.ndarray, QTransform]:
"""
Get the image data for an arbitrary step scan.
@@ -972,7 +967,6 @@ def get_step_scan_image(
x_data (list[float]): The x data.
y_data (list[float]): The y data.
z_data (list[float]): The z data.
- msg (messages.ScanStatusMessage): The scan status message.
Returns:
tuple[np.ndarray, QTransform]: The image data and the QTransform.
@@ -1033,7 +1027,7 @@ def get_image_grid(self, positions) -> tuple[np.ndarray, np.ndarray, QTransform]
to avoid recalculating the grid for the same scan.
Args:
- _scan_id (str): The scan ID. Needed for caching but not used in the function.
+ positions: positions of the data points.
Returns:
tuple[np.ndarray, np.ndarray, QTransform]: The grid x and y coordinates and the QTransform.
@@ -1108,11 +1102,13 @@ def estimate_image_resolution(coords: np.ndarray) -> tuple[int, int]:
return max(1, width_pixels), max(1, height_pixels)
- def arg_bundle_to_dict(self, bundle_size: int, args: list) -> dict:
+ @staticmethod
+ def arg_bundle_to_dict(bundle_size: int, args: list) -> dict:
"""
Convert the argument bundle to a dictionary.
Args:
+ bundle_size (int): The size of each argument bundle.
args (list): The argument bundle.
Returns:
@@ -1160,14 +1156,14 @@ def reset(self):
################################################################################
@SafeProperty(str)
- def x_device_name(self) -> str:
+ def device_x(self) -> str:
"""Device name for the X axis."""
- if self._image_config.x_device is None:
+ if self._image_config.device_x is None:
return ""
- return self._image_config.x_device.name or ""
+ return self._image_config.device_x.device or ""
- @x_device_name.setter
- def x_device_name(self, device_name: str) -> None:
+ @device_x.setter
+ def device_x(self, device_name: str) -> None:
"""
Set the X device name.
@@ -1179,27 +1175,27 @@ def x_device_name(self, device_name: str) -> None:
# Get current entry or validate
if device_name:
try:
- entry = self.entry_validator.validate_signal(device_name, None)
- self._image_config.x_device = HeatmapDeviceSignal(name=device_name, entry=entry)
- self.property_changed.emit("x_device_name", device_name)
+ signal = self.entry_validator.validate_signal(device_name, None)
+ self._image_config.device_x = HeatmapDeviceSignal(device=device_name, signal=signal)
+ self.property_changed.emit("device_x", device_name)
self.update_labels() # Update axis labels
self._try_auto_plot()
except Exception:
pass # Silently fail if device is not available yet
else:
- self._image_config.x_device = None
- self.property_changed.emit("x_device_name", "")
+ self._image_config.device_x = None
+ self.property_changed.emit("device_x", "")
self.update_labels() # Clear axis labels
@SafeProperty(str)
- def x_device_entry(self) -> str:
+ def signal_x(self) -> str:
"""Signal entry for the X axis device."""
- if self._image_config.x_device is None:
+ if self._image_config.device_x is None:
return ""
- return self._image_config.x_device.entry or ""
+ return self._image_config.device_x.signal or ""
- @x_device_entry.setter
- def x_device_entry(self, entry: str) -> None:
+ @signal_x.setter
+ def signal_x(self, entry: str) -> None:
"""
Set the X device entry.
@@ -1209,32 +1205,32 @@ def x_device_entry(self, entry: str) -> None:
if not entry:
return
- if self._image_config.x_device is None:
- logger.warning("Cannot set x_device_entry without x_device_name set first.")
+ if self._image_config.device_x is None:
+ logger.warning("Cannot set signal_x without device_x set first.")
return
- device_name = self._image_config.x_device.name
+ device_name = self._image_config.device_x.device
try:
# Validate the entry for this device
- validated_entry = self.entry_validator.validate_signal(device_name, entry)
- self._image_config.x_device = HeatmapDeviceSignal(
- name=device_name, entry=validated_entry
+ validated_signal = self.entry_validator.validate_signal(device_name, entry)
+ self._image_config.device_x = HeatmapDeviceSignal(
+ device=device_name, signal=validated_signal
)
- self.property_changed.emit("x_device_entry", validated_entry)
+ self.property_changed.emit("signal_x", validated_signal)
self.update_labels() # Update axis labels
self._try_auto_plot()
except Exception:
pass # Silently fail if validation fails
@SafeProperty(str)
- def y_device_name(self) -> str:
+ def device_y(self) -> str:
"""Device name for the Y axis."""
- if self._image_config.y_device is None:
+ if self._image_config.device_y is None:
return ""
- return self._image_config.y_device.name or ""
+ return self._image_config.device_y.device or ""
- @y_device_name.setter
- def y_device_name(self, device_name: str) -> None:
+ @device_y.setter
+ def device_y(self, device_name: str) -> None:
"""
Set the Y device name.
@@ -1246,27 +1242,27 @@ def y_device_name(self, device_name: str) -> None:
# Get current entry or validate
if device_name:
try:
- entry = self.entry_validator.validate_signal(device_name, None)
- self._image_config.y_device = HeatmapDeviceSignal(name=device_name, entry=entry)
- self.property_changed.emit("y_device_name", device_name)
+ signal = self.entry_validator.validate_signal(device_name, None)
+ self._image_config.device_y = HeatmapDeviceSignal(device=device_name, signal=signal)
+ self.property_changed.emit("device_y", device_name)
self.update_labels() # Update axis labels
self._try_auto_plot()
except Exception:
pass # Silently fail if device is not available yet
else:
- self._image_config.y_device = None
- self.property_changed.emit("y_device_name", "")
+ self._image_config.device_y = None
+ self.property_changed.emit("device_y", "")
self.update_labels() # Clear axis labels
@SafeProperty(str)
- def y_device_entry(self) -> str:
+ def signal_y(self) -> str:
"""Signal entry for the Y axis device."""
- if self._image_config.y_device is None:
+ if self._image_config.device_y is None:
return ""
- return self._image_config.y_device.entry or ""
+ return self._image_config.device_y.signal or ""
- @y_device_entry.setter
- def y_device_entry(self, entry: str) -> None:
+ @signal_y.setter
+ def signal_y(self, entry: str) -> None:
"""
Set the Y device entry.
@@ -1276,18 +1272,18 @@ def y_device_entry(self, entry: str) -> None:
if not entry:
return
- if self._image_config.y_device is None:
- logger.warning("Cannot set y_device_entry without y_device_name set first.")
+ if self._image_config.device_y is None:
+ logger.warning("Cannot set signal_y without device_y set first.")
return
- device_name = self._image_config.y_device.name
+ device_name = self._image_config.device_y.device
try:
# Validate the entry for this device
- validated_entry = self.entry_validator.validate_signal(device_name, entry)
- self._image_config.y_device = HeatmapDeviceSignal(
- name=device_name, entry=validated_entry
+ validated_signal = self.entry_validator.validate_signal(device_name, entry)
+ self._image_config.device_y = HeatmapDeviceSignal(
+ device=device_name, signal=validated_signal
)
- self.property_changed.emit("y_device_entry", validated_entry)
+ self.property_changed.emit("signal_y", validated_signal)
self.update_labels() # Update axis labels
self._try_auto_plot()
except Exception as e:
@@ -1295,14 +1291,14 @@ def y_device_entry(self, entry: str) -> None:
pass # Silently fail if validation fails
@SafeProperty(str)
- def z_device_name(self) -> str:
+ def device_z(self) -> str:
"""Device name for the Z (color) axis."""
- if self._image_config.z_device is None:
+ if self._image_config.device_z is None:
return ""
- return self._image_config.z_device.name or ""
+ return self._image_config.device_z.device or ""
- @z_device_name.setter
- def z_device_name(self, device_name: str) -> None:
+ @device_z.setter
+ def device_z(self, device_name: str) -> None:
"""
Set the Z device name.
@@ -1314,28 +1310,28 @@ def z_device_name(self, device_name: str) -> None:
# Get current entry or validate
if device_name:
try:
- entry = self.entry_validator.validate_signal(device_name, None)
- self._image_config.z_device = HeatmapDeviceSignal(name=device_name, entry=entry)
- self.property_changed.emit("z_device_name", device_name)
+ signal = self.entry_validator.validate_signal(device_name, None)
+ self._image_config.device_z = HeatmapDeviceSignal(device=device_name, signal=signal)
+ self.property_changed.emit("device_z", device_name)
self.update_labels() # Update axis labels (title)
self._try_auto_plot()
except Exception as e:
logger.debug(f"Z device name validation failed: {e}")
pass # Silently fail if device is not available yet
else:
- self._image_config.z_device = None
- self.property_changed.emit("z_device_name", "")
+ self._image_config.device_z = None
+ self.property_changed.emit("device_z", "")
self.update_labels() # Clear axis labels
@SafeProperty(str)
- def z_device_entry(self) -> str:
+ def signal_z(self) -> str:
"""Signal entry for the Z (color) axis device."""
- if self._image_config.z_device is None:
+ if self._image_config.device_z is None:
return ""
- return self._image_config.z_device.entry or ""
+ return self._image_config.device_z.signal or ""
- @z_device_entry.setter
- def z_device_entry(self, entry: str) -> None:
+ @signal_z.setter
+ def signal_z(self, entry: str) -> None:
"""
Set the Z device entry.
@@ -1345,18 +1341,18 @@ def z_device_entry(self, entry: str) -> None:
if not entry:
return
- if self._image_config.z_device is None:
- logger.warning("Cannot set z_device_entry without z_device_name set first.")
+ if self._image_config.device_z is None:
+ logger.warning("Cannot set signal_z without device_z set first.")
return
- device_name = self._image_config.z_device.name
+ device_name = self._image_config.device_z.device
try:
# Validate the entry for this device
- validated_entry = self.entry_validator.validate_signal(device_name, entry)
- self._image_config.z_device = HeatmapDeviceSignal(
- name=device_name, entry=validated_entry
+ validated_signal = self.entry_validator.validate_signal(device_name, entry)
+ self._image_config.device_z = HeatmapDeviceSignal(
+ device=device_name, signal=validated_signal
)
- self.property_changed.emit("z_device_entry", validated_entry)
+ self.property_changed.emit("signal_z", validated_signal)
self.update_labels() # Update axis labels (title)
self._try_auto_plot()
except Exception as e:
@@ -1368,25 +1364,25 @@ def _try_auto_plot(self) -> None:
Attempt to automatically call plot() if all three devices are set.
Similar to waveform's approach but requires all three devices.
"""
- has_x = self._image_config.x_device is not None
- has_y = self._image_config.y_device is not None
- has_z = self._image_config.z_device is not None
+ has_x = self._image_config.device_x is not None
+ has_y = self._image_config.device_y is not None
+ has_z = self._image_config.device_z is not None
if has_x and has_y and has_z:
- x_name = self._image_config.x_device.name
- x_entry = self._image_config.x_device.entry
- y_name = self._image_config.y_device.name
- y_entry = self._image_config.y_device.entry
- z_name = self._image_config.z_device.name
- z_entry = self._image_config.z_device.entry
+ device_x = self._image_config.device_x.device
+ signal_x = self._image_config.device_x.signal
+ device_y = self._image_config.device_y.device
+ signal_y = self._image_config.device_y.signal
+ device_z = self._image_config.device_z.device
+ signal_z = self._image_config.device_z.signal
try:
self.plot(
- x_name=x_name,
- y_name=y_name,
- z_name=z_name,
- x_entry=x_entry,
- y_entry=y_entry,
- z_entry=z_entry,
+ device_x=device_x,
+ device_y=device_y,
+ device_z=device_z,
+ signal_x=signal_x,
+ signal_y=signal_y,
+ signal_z=signal_z,
validate_bec=False, # Don't validate - entries already validated
)
except Exception as e:
@@ -1533,6 +1529,6 @@ def cleanup(self):
app = QApplication(sys.argv)
heatmap = Heatmap()
- heatmap.plot(x_name="samx", y_name="samy", z_name="bpm4i", oversampling_factor=5.0)
+ heatmap.plot(device_x="samx", device_y="samy", device_z="bpm4i", oversampling_factor=5.0)
heatmap.show()
sys.exit(app.exec_())
diff --git a/bec_widgets/widgets/plots/heatmap/settings/heatmap_setting.py b/bec_widgets/widgets/plots/heatmap/settings/heatmap_setting.py
index c55d34064..8238caa77 100644
--- a/bec_widgets/widgets/plots/heatmap/settings/heatmap_setting.py
+++ b/bec_widgets/widgets/plots/heatmap/settings/heatmap_setting.py
@@ -48,7 +48,7 @@ def __init__(self, parent=None, target_widget=None, popup=False, *args, **kwargs
if popup is False:
self.ui.button_apply.clicked.connect(self.accept_changes)
- self.ui.x_name.setFocus()
+ self.ui.device_x.setFocus()
@SafeSlot()
def fetch_all_properties(self):
@@ -62,44 +62,44 @@ def fetch_all_properties(self):
color_map = getattr(self.target_widget, "color_map", None)
# Default values for device properties
- x_name, x_entry = None, None
- y_name, y_entry = None, None
- z_name, z_entry = None, None
+ device_x, signal_x = None, None
+ device_y, signal_y = None, None
+ device_z, signal_z = None, None
# Safely access device properties
if hasattr(self.target_widget, "_image_config") and self.target_widget._image_config:
config = self.target_widget._image_config
- if hasattr(config, "x_device") and config.x_device:
- x_name = getattr(config.x_device, "name", None)
- x_entry = getattr(config.x_device, "entry", None)
+ if hasattr(config, "device_x") and config.device_x:
+ device_x = getattr(config.device_x, "device", None)
+ signal_x = getattr(config.device_x, "signal", None)
- if hasattr(config, "y_device") and config.y_device:
- y_name = getattr(config.y_device, "name", None)
- y_entry = getattr(config.y_device, "entry", None)
+ if hasattr(config, "device_y") and config.device_y:
+ device_y = getattr(config.device_y, "device", None)
+ signal_y = getattr(config.device_y, "signal", None)
- if hasattr(config, "z_device") and config.z_device:
- z_name = getattr(config.z_device, "name", None)
- z_entry = getattr(config.z_device, "entry", None)
+ if hasattr(config, "device_z") and config.device_z:
+ device_z = getattr(config.device_z, "device", None)
+ signal_z = getattr(config.device_z, "signal", None)
# Apply the properties to the settings widget
if hasattr(self.ui, "color_map"):
self.ui.color_map.colormap = color_map
- if hasattr(self.ui, "x_name"):
- self.ui.x_name.set_device(x_name)
- if hasattr(self.ui, "x_entry") and x_entry is not None:
- self.ui.x_entry.set_to_obj_name(x_entry)
+ if hasattr(self.ui, "device_x"):
+ self.ui.device_x.set_device(device_x)
+ if hasattr(self.ui, "signal_x") and signal_x is not None:
+ self.ui.signal_x.set_to_obj_name(signal_x)
- if hasattr(self.ui, "y_name"):
- self.ui.y_name.set_device(y_name)
- if hasattr(self.ui, "y_entry") and y_entry is not None:
- self.ui.y_entry.set_to_obj_name(y_entry)
+ if hasattr(self.ui, "device_y"):
+ self.ui.device_y.set_device(device_y)
+ if hasattr(self.ui, "signal_y") and signal_y is not None:
+ self.ui.signal_y.set_to_obj_name(signal_y)
- if hasattr(self.ui, "z_name"):
- self.ui.z_name.set_device(z_name)
- if hasattr(self.ui, "z_entry") and z_entry is not None:
- self.ui.z_entry.set_to_obj_name(z_entry)
+ if hasattr(self.ui, "device_z"):
+ self.ui.device_z.set_device(device_z)
+ if hasattr(self.ui, "signal_z") and signal_z is not None:
+ self.ui.signal_z.set_to_obj_name(signal_z)
if hasattr(self.ui, "interpolation"):
self.ui.interpolation.setCurrentText(
@@ -119,12 +119,12 @@ def accept_changes(self):
"""
Apply all properties from the settings widget to the target widget.
"""
- x_name = self.ui.x_name.currentText()
- x_entry = self.ui.x_entry.get_signal_name()
- y_name = self.ui.y_name.currentText()
- y_entry = self.ui.y_entry.get_signal_name()
- z_name = self.ui.z_name.currentText()
- z_entry = self.ui.z_entry.get_signal_name()
+ device_x = self.ui.device_x.currentText()
+ signal_x = self.ui.signal_x.get_signal_name()
+ device_y = self.ui.device_y.currentText()
+ signal_y = self.ui.signal_y.get_signal_name()
+ device_z = self.ui.device_z.currentText()
+ signal_z = self.ui.signal_z.get_signal_name()
validate_bec = self.ui.validate_bec.checked
color_map = self.ui.color_map.colormap
interpolation = self.ui.interpolation.currentText()
@@ -132,12 +132,12 @@ def accept_changes(self):
enforce_interpolation = self.ui.enforce_interpolation.isChecked()
self.target_widget.plot(
- x_name=x_name,
- y_name=y_name,
- z_name=z_name,
- x_entry=x_entry,
- y_entry=y_entry,
- z_entry=z_entry,
+ device_x=device_x,
+ device_y=device_y,
+ device_z=device_z,
+ signal_x=signal_x,
+ signal_y=signal_y,
+ signal_z=signal_z,
color_map=color_map,
validate_bec=validate_bec,
interpolation=interpolation,
@@ -147,17 +147,17 @@ def accept_changes(self):
)
def cleanup(self):
- self.ui.x_name.close()
- self.ui.x_name.deleteLater()
- self.ui.x_entry.close()
- self.ui.x_entry.deleteLater()
- self.ui.y_name.close()
- self.ui.y_name.deleteLater()
- self.ui.y_entry.close()
- self.ui.y_entry.deleteLater()
- self.ui.z_name.close()
- self.ui.z_name.deleteLater()
- self.ui.z_entry.close()
- self.ui.z_entry.deleteLater()
+ self.ui.device_x.close()
+ self.ui.device_x.deleteLater()
+ self.ui.signal_x.close()
+ self.ui.signal_x.deleteLater()
+ self.ui.device_y.close()
+ self.ui.device_y.deleteLater()
+ self.ui.signal_y.close()
+ self.ui.signal_y.deleteLater()
+ self.ui.device_z.close()
+ self.ui.device_z.deleteLater()
+ self.ui.signal_z.close()
+ self.ui.signal_z.deleteLater()
self.ui.interpolation.close()
self.ui.interpolation.deleteLater()
diff --git a/bec_widgets/widgets/plots/heatmap/settings/heatmap_settings_horizontal.ui b/bec_widgets/widgets/plots/heatmap/settings/heatmap_settings_horizontal.ui
index 7fe057def..801f11367 100644
--- a/bec_widgets/widgets/plots/heatmap/settings/heatmap_settings_horizontal.ui
+++ b/bec_widgets/widgets/plots/heatmap/settings/heatmap_settings_horizontal.ui
@@ -196,7 +196,7 @@
-
-
+
true
@@ -206,7 +206,7 @@
-
-
+
true
@@ -236,7 +236,7 @@
-
-
+
true
@@ -246,7 +246,7 @@
-
-
+
true
@@ -276,7 +276,7 @@
-
-
+
true
@@ -286,7 +286,7 @@
-
-
+
true
@@ -322,21 +322,21 @@
- x_name
- y_name
- z_name
- x_entry
- y_entry
- z_entry
+ device_x
+ device_y
+ device_z
+ signal_x
+ signal_y
+ signal_z
interpolation
oversampling_factor
- x_name
+ device_x
device_reset()
- x_entry
+ signal_x
reset_selection()
@@ -350,9 +350,9 @@
- x_name
+ device_x
currentTextChanged(QString)
- x_entry
+ signal_x
set_device(QString)
@@ -366,9 +366,9 @@
- y_name
+ device_y
device_reset()
- y_entry
+ signal_y
reset_selection()
@@ -382,9 +382,9 @@
- y_name
+ device_y
currentTextChanged(QString)
- y_entry
+ signal_y
set_device(QString)
@@ -398,9 +398,9 @@
- z_name
+ device_z
device_reset()
- z_entry
+ signal_z
reset_selection()
@@ -414,9 +414,9 @@
- z_name
+ device_z
currentTextChanged(QString)
- z_entry
+ signal_z
set_device(QString)
diff --git a/bec_widgets/widgets/plots/heatmap/settings/heatmap_settings_vertical.ui b/bec_widgets/widgets/plots/heatmap/settings/heatmap_settings_vertical.ui
index 2835306be..dce274f25 100644
--- a/bec_widgets/widgets/plots/heatmap/settings/heatmap_settings_vertical.ui
+++ b/bec_widgets/widgets/plots/heatmap/settings/heatmap_settings_vertical.ui
@@ -69,7 +69,7 @@
-
-
+
true
@@ -79,7 +79,7 @@
-
-
+
true
@@ -109,7 +109,7 @@
-
-
+
true
@@ -119,7 +119,7 @@
-
-
+
true
@@ -142,7 +142,7 @@
-
-
+
true
@@ -152,7 +152,7 @@
-
-
+
true
@@ -264,20 +264,20 @@
- x_name
- y_name
- z_name
+ device_x
+ device_y
+ device_z
button_apply
- x_entry
- y_entry
- z_entry
+ signal_x
+ signal_y
+ signal_z
- x_name
+ device_x
device_reset()
- x_entry
+ signal_x
reset_selection()
@@ -291,9 +291,9 @@
- x_name
+ device_x
currentTextChanged(QString)
- x_entry
+ signal_x
set_device(QString)
@@ -307,9 +307,9 @@
- y_name
+ device_y
device_reset()
- y_entry
+ signal_y
reset_selection()
@@ -323,9 +323,9 @@
- y_name
+ device_y
currentTextChanged(QString)
- y_entry
+ signal_y
set_device(QString)
@@ -339,9 +339,9 @@
- z_name
+ device_z
device_reset()
- z_entry
+ signal_z
reset_selection()
@@ -355,9 +355,9 @@
- z_name
+ device_z
currentTextChanged(QString)
- z_entry
+ signal_z
set_device(QString)
diff --git a/bec_widgets/widgets/plots/image/image.py b/bec_widgets/widgets/plots/image/image.py
index a8e9b3b16..1fdc010b0 100644
--- a/bec_widgets/widgets/plots/image/image.py
+++ b/bec_widgets/widgets/plots/image/image.py
@@ -42,8 +42,8 @@ class ImageConfig(ConnectionConfig):
class ImageLayerConfig(BaseModel):
- device_name: str = Field("", description="The device name to monitor.")
- device_entry: str = Field("", description="The signal/entry name to monitor on the device.")
+ device: str = Field("", description="The device name to monitor.")
+ signal: str = Field("", description="The signal/entry name to monitor on the device.")
monitor_type: Literal["1d", "2d"] | None = Field(None, description="The type of monitor.")
source: Literal["device_monitor_1d", "device_monitor_2d"] | None = Field(
None, description="The source of the image data."
@@ -80,10 +80,10 @@ class Image(ImageBase):
"autorange.setter",
"autorange_mode",
"autorange_mode.setter",
- "device_name",
- "device_name.setter",
- "device_entry",
- "device_entry.setter",
+ "device",
+ "device.setter",
+ "signal",
+ "signal.setter",
"enable_colorbar",
"enable_simple_colorbar",
"enable_simple_colorbar.setter",
@@ -206,19 +206,19 @@ def on_device_selection_changed(self, _):
signal_text = device_selection.signal_combo_box.currentText()
if not device:
- self.device_name = ""
+ self.device = ""
return
if not device_selection.device_combo_box.is_valid_input:
return
if not device_selection.signal_combo_box.is_valid_input:
- if self._config.device_entry:
- self.device_entry = ""
- if device != self._config.device_name:
- self.device_name = device
+ if self._config.signal:
+ self.signal = ""
+ if device != self._config.device:
+ self.device = device
return
- if device == self._config.device_name and signal_text == self._config.device_entry:
+ if device == self._config.device and signal_text == self._config.signal:
return
# Get the signal config stored in the combobox
@@ -235,8 +235,8 @@ def on_device_selection_changed(self, _):
# Store signal config and set properties which will trigger the connection
self._signal_configs["main"] = signal_config
- self.device_name = device
- self.device_entry = signal_text
+ self.device = device
+ self.signal = signal_text
finally:
self._device_selection_updating = False
@@ -244,55 +244,53 @@ def on_device_selection_changed(self, _):
# Data Acquisition
@SafeProperty(str, auto_emit=True)
- def device_name(self) -> str:
+ def device(self) -> str:
"""
The name of the device to monitor for image data.
"""
- return self._config.device_name
+ return self._config.device
- @device_name.setter
- def device_name(self, value: str):
+ @device.setter
+ def device(self, value: str):
"""
- Set the device name for the image. This should be used together with device_entry.
- When both device_name and device_entry are set, the widget connects to that device signal.
+ Set the device name for the image. This should be used together with signal.
+ When both device and signal are set, the widget connects to that device signal.
Args:
value(str): The name of the device to monitor.
"""
if not value:
# Clear the monitor if empty device name
- if self._config.device_name:
+ if self._config.device:
self._disconnect_current_monitor()
- self._config.device_name = ""
- self._config.device_entry = ""
+ self._config.device = ""
+ self._config.signal = ""
self._signal_configs.pop("main", None)
self._set_connection_status("disconnected")
return
- old_device = self._config.device_name
- self._config.device_name = value
+ old_device = self._config.device
+ self._config.device = value
- # If we have a device_entry, reconnect with the new device
- if self._config.device_entry:
+ # If we have a signal, reconnect with the new device
+ if self._config.signal:
# Try to get fresh signal config for the new device
try:
device_obj = self.dev[value]
# Try to get signal config for the current entry
- if self._config.device_entry in device_obj._info.get("signals", {}):
- self._signal_configs["main"] = device_obj._info["signals"][
- self._config.device_entry
- ]
+ if self._config.signal in device_obj._info.get("signals", {}):
+ self._signal_configs["main"] = device_obj._info["signals"][self._config.signal]
self._setup_connection()
else:
# Signal doesn't exist on new device
logger.warning(
- f"Signal '{self._config.device_entry}' doesn't exist on device '{value}'"
+ f"Signal '{self._config.signal}' doesn't exist on device '{value}'"
)
self._disconnect_current_monitor()
- self._config.device_entry = ""
+ self._config.signal = ""
self._signal_configs.pop("main", None)
self._set_connection_status(
- "error", f"Signal '{self._config.device_entry}' doesn't exist"
+ "error", f"Signal '{self._config.signal}' doesn't exist"
)
except (KeyError, AttributeError):
# Device doesn't exist
@@ -304,40 +302,40 @@ def device_name(self, value: str):
# Toolbar sync happens via SafeProperty auto_emit property_changed handling.
@SafeProperty(str, auto_emit=True)
- def device_entry(self) -> str:
+ def signal(self) -> str:
"""
The signal/entry name to monitor on the device.
"""
- return self._config.device_entry
+ return self._config.signal
- @device_entry.setter
- def device_entry(self, value: str):
+ @signal.setter
+ def signal(self, value: str):
"""
- Set the device entry (signal) for the image. This should be used together with device_name.
+ Set the device signal for the image. This should be used together with device.
When set, it will connect to updates from that device signal.
Args:
value(str): The signal name to monitor.
"""
if not value:
- if self._config.device_entry:
+ if self._config.signal:
self._disconnect_current_monitor()
- self._config.device_entry = ""
+ self._config.signal = ""
self._signal_configs.pop("main", None)
self._set_connection_status("disconnected")
return
- self._config.device_entry = value
+ self._config.signal = value
- # If we have a device_name, try to connect
- if self._config.device_name:
+ # If we have a device, try to connect
+ if self._config.device:
try:
- device_obj = self.dev[self._config.device_name]
+ device_obj = self.dev[self._config.device]
signal_config = device_obj._info["signals"].get(value)
if not isinstance(signal_config, dict) or not signal_config.get("signal_class"):
logger.warning(
f"Could not find valid configuration for signal '{value}' "
- f"on device '{self._config.device_name}'."
+ f"on device '{self._config.device}'."
)
self._signal_configs.pop("main", None)
self._set_connection_status("error", f"Signal '{value}' not found")
@@ -347,14 +345,14 @@ def device_entry(self, value: str):
self._setup_connection()
except (KeyError, AttributeError):
logger.warning(
- f"Could not find signal '{value}' on device '{self._config.device_name}'."
+ f"Could not find signal '{value}' on device '{self._config.device}'."
)
# Remove signal config if it can't be fetched
self._signal_configs.pop("main", None)
self._set_connection_status("error", f"Signal '{value}' not found")
else:
- logger.debug(f"device_entry setter: No device set yet for signal '{value}'")
+ logger.debug(f"signal setter: No device set yet for signal '{value}'")
@property
def main_image(self) -> ImageItem:
@@ -363,17 +361,17 @@ def main_image(self) -> ImageItem:
def _setup_connection(self):
"""
- Internal method to setup connection based on current device_name, device_entry, and signal_config.
+ Internal method to setup connection based on current device, signal, and signal_config.
"""
- if not self._config.device_name or not self._config.device_entry:
- logger.warning("Cannot setup connection without both device_name and device_entry")
+ if not self._config.device or not self._config.signal:
+ logger.warning("Cannot setup connection without both device and signal")
self._set_connection_status("disconnected")
return
signal_config = self._signal_configs.get("main")
if not signal_config:
logger.warning(
- f"Cannot setup connection for {self._config.device_name}.{self._config.device_entry} without signal_config"
+ f"Cannot setup connection for {self._config.device}.{self._config.signal} without signal_config"
)
self._set_connection_status("error", "Missing signal config")
return
@@ -387,7 +385,7 @@ def _setup_connection(self):
if signal_class not in supported_classes:
logger.warning(
- f"Signal '{self._config.device_name}.{self._config.device_entry}' has unsupported signal class '{signal_class}'. "
+ f"Signal '{self._config.device}.{self._config.signal}' has unsupported signal class '{signal_class}'. "
f"Supported classes: {supported_classes}"
)
self._set_connection_status("error", f"Unsupported signal class '{signal_class}'")
@@ -399,7 +397,7 @@ def _setup_connection(self):
if ndim is None:
logger.warning(
- f"Signal '{self._config.device_name}.{self._config.device_entry}' does not have a valid 'ndim' in its signal_info."
+ f"Signal '{self._config.device}.{self._config.signal}' does not have a valid 'ndim' in its signal_info."
)
self._set_connection_status("error", "Missing ndim in signal_info")
return
@@ -414,14 +412,12 @@ def _setup_connection(self):
if signal_class == "PreviewSignal":
self.bec_dispatcher.connect_slot(
self.on_image_update_1d,
- MessageEndpoints.device_preview(
- self._config.device_name, self._config.device_entry
- ),
+ MessageEndpoints.device_preview(self._config.device, self._config.signal),
)
elif signal_class in self.SUPPORTED_SIGNALS:
self.async_update = True
config.async_signal_name = signal_config.get(
- "obj_name", f"{self._config.device_name}_{self._config.device_entry}"
+ "obj_name", f"{self._config.device}_{self._config.signal}"
)
self._setup_async_image(self.scan_id)
elif ndim == 2:
@@ -430,26 +426,24 @@ def _setup_connection(self):
if signal_class == "PreviewSignal":
self.bec_dispatcher.connect_slot(
self.on_image_update_2d,
- MessageEndpoints.device_preview(
- self._config.device_name, self._config.device_entry
- ),
+ MessageEndpoints.device_preview(self._config.device, self._config.signal),
)
elif signal_class in self.SUPPORTED_SIGNALS:
self.async_update = True
config.async_signal_name = signal_config.get(
- "obj_name", f"{self._config.device_name}_{self._config.device_entry}"
+ "obj_name", f"{self._config.device}_{self._config.signal}"
)
self._setup_async_image(self.scan_id)
else:
logger.warning(
- f"Unsupported ndim '{ndim}' for monitor '{self._config.device_name}.{self._config.device_entry}'."
+ f"Unsupported ndim '{ndim}' for monitor '{self._config.device}.{self._config.signal}'."
)
self._set_connection_status("error", f"Unsupported ndim '{ndim}'")
return
self._set_connection_status("connected")
logger.info(
- f"Connected to {self._config.device_name}.{self._config.device_entry} with type {config.monitor_type}"
+ f"Connected to {self._config.device}.{self._config.signal} with type {config.monitor_type}"
)
self._autorange_on_next_update = True
@@ -457,13 +451,13 @@ def _disconnect_current_monitor(self):
"""
Internal method to disconnect the current monitor subscriptions.
"""
- if not self._config.device_name or not self._config.device_entry:
+ if not self._config.device or not self._config.signal:
return
config = self.subscriptions["main"]
if self.async_update:
- async_signal_name = config.async_signal_name or self._config.device_entry
+ async_signal_name = config.async_signal_name or self._config.signal
ids_to_check = [self.scan_id, self.old_scan_id]
if config.source == "device_monitor_1d":
@@ -473,11 +467,11 @@ def _disconnect_current_monitor(self):
self.bec_dispatcher.disconnect_slot(
self.on_image_update_1d,
MessageEndpoints.device_async_signal(
- scan_id, self._config.device_name, async_signal_name
+ scan_id, self._config.device, async_signal_name
),
)
logger.info(
- f"Disconnecting 1d update ScanID:{scan_id}, Device Name:{self._config.device_name},Device Entry:{async_signal_name}"
+ f"Disconnecting 1d update ScanID:{scan_id}, Device Name:{self._config.device},Device Entry:{async_signal_name}"
)
elif config.source == "device_monitor_2d":
for scan_id in ids_to_check:
@@ -486,33 +480,29 @@ def _disconnect_current_monitor(self):
self.bec_dispatcher.disconnect_slot(
self.on_image_update_2d,
MessageEndpoints.device_async_signal(
- scan_id, self._config.device_name, async_signal_name
+ scan_id, self._config.device, async_signal_name
),
)
logger.info(
- f"Disconnecting 2d update ScanID:{scan_id}, Device Name:{self._config.device_name},Device Entry:{async_signal_name}"
+ f"Disconnecting 2d update ScanID:{scan_id}, Device Name:{self._config.device},Device Entry:{async_signal_name}"
)
else:
if config.source == "device_monitor_1d":
self.bec_dispatcher.disconnect_slot(
self.on_image_update_1d,
- MessageEndpoints.device_preview(
- self._config.device_name, self._config.device_entry
- ),
+ MessageEndpoints.device_preview(self._config.device, self._config.signal),
)
logger.info(
- f"Disconnecting preview 1d update Device Name:{self._config.device_name}, Device Entry:{self._config.device_entry}"
+ f"Disconnecting preview 1d update Device Name:{self._config.device}, Device Entry:{self._config.signal}"
)
elif config.source == "device_monitor_2d":
self.bec_dispatcher.disconnect_slot(
self.on_image_update_2d,
- MessageEndpoints.device_preview(
- self._config.device_name, self._config.device_entry
- ),
+ MessageEndpoints.device_preview(self._config.device, self._config.signal),
)
logger.info(
- f"Disconnecting preview 2d update Device Name:{self._config.device_name}, Device Entry:{self._config.device_entry}"
+ f"Disconnecting preview 2d update Device Name:{self._config.device}, Device Entry:{self._config.signal}"
)
# Reset async state
@@ -526,8 +516,8 @@ def _disconnect_current_monitor(self):
@SafeSlot(popup_error=True)
def image(
self,
- device_name: str | None = None,
- device_entry: str | None = None,
+ device: str | None = None,
+ signal: str | None = None,
color_map: str | None = None,
color_bar: Literal["simple", "full"] | None = None,
vrange: tuple[int, int] | None = None,
@@ -536,8 +526,8 @@ def image(
Set the image source and update the image.
Args:
- device_name(str|None): The name of the device to monitor. If None or empty string, the current monitor will be disconnected.
- device_entry(str|None): The signal/entry name to monitor on the device.
+ device(str|None): The name of the device to monitor. If None or empty string, the current monitor will be disconnected.
+ signal(str|None): The signal/entry name to monitor on the device.
color_map(str): The color map to use for the image.
color_bar(str): The type of color bar to use. Options are "simple" or "full".
vrange(tuple): The range of values to use for the color map.
@@ -546,27 +536,27 @@ def image(
ImageItem: The image object, or None if connection failed.
"""
# Disconnect existing monitor if any
- if self._config.device_name and self._config.device_entry:
+ if self._config.device and self._config.signal:
self._disconnect_current_monitor()
- if not device_name or not device_entry:
- if device_name or device_entry:
- logger.warning("Both device_name and device_entry must be specified")
+ if not device or not signal:
+ if device or signal:
+ logger.warning("Both device and signal must be specified")
else:
logger.info("Disconnecting image monitor")
- self.device_name = ""
+ self.device = ""
return None
# Validate device
- self.entry_validator.validate_monitor(device_name)
+ self.entry_validator.validate_monitor(device)
# Clear old entry first to avoid reconnect attempts on the new device
- if self._config.device_entry:
- self.device_entry = ""
+ if self._config.signal:
+ self.signal = ""
# Set properties to trigger connection
- self.device_name = device_name
- self.device_entry = device_entry
+ self.device = device
+ self.signal = signal
# Apply visual settings
if color_map is not None:
@@ -581,7 +571,7 @@ def image(
def _sync_device_selection(self):
"""
Synchronize the device and signal comboboxes with the current monitor state.
- This ensures the toolbar reflects the device_name and device_entry properties.
+ This ensures the toolbar reflects the device and signal properties.
"""
try:
device_selection_action = self.toolbar.components.get_action("device_selection")
@@ -593,8 +583,8 @@ def _sync_device_selection(self):
return
device_selection: DeviceSelection = device_selection_action.widget
- target_device = self._config.device_name or ""
- target_entry = self._config.device_entry or ""
+ target_device = self._config.device or ""
+ target_entry = self._config.signal or ""
# Check if already synced
if (
@@ -605,15 +595,15 @@ def _sync_device_selection(self):
device_selection.set_device_and_signal(target_device, target_entry)
- def _sync_device_entry_from_toolbar(self) -> None:
+ def _sync_signal_from_toolbar(self) -> None:
"""
- Pull the signal selection from the toolbar if it differs from the current device_entry.
- This keeps CLI-driven device_name updates in sync with the signal combobox state.
+ Pull the signal selection from the toolbar if it differs from the current signal.
+ This keeps CLI-driven device updates in sync with the signal combobox state.
"""
if self._device_selection_updating:
return
- if not self._config.device_name:
+ if not self._config.device:
return
try:
@@ -625,17 +615,17 @@ def _sync_device_entry_from_toolbar(self) -> None:
return
device_selection: DeviceSelection = device_selection_action.widget
- if device_selection.device_combo_box.currentText() != self._config.device_name:
+ if device_selection.device_combo_box.currentText() != self._config.device:
return
signal_text = device_selection.signal_combo_box.currentText()
- if not signal_text or signal_text == self._config.device_entry:
+ if not signal_text or signal_text == self._config.signal:
return
signal_config = device_selection.signal_combo_box.get_signal_config()
if not signal_config:
try:
- device_obj = self.dev[self._config.device_name]
+ device_obj = self.dev[self._config.device]
signal_config = device_obj._info["signals"].get(signal_text, {})
except (KeyError, AttributeError):
signal_config = None
@@ -646,7 +636,7 @@ def _sync_device_entry_from_toolbar(self) -> None:
self._signal_configs["main"] = signal_config
self._device_selection_updating = True
try:
- self.device_entry = signal_text
+ self.signal = signal_text
finally:
self._device_selection_updating = False
@@ -795,17 +785,17 @@ def _handle_scan_change(self, current_scan_id: str):
def _get_async_signal_name(self) -> tuple[str, str] | None:
"""
- Returns device name and async signal name used for endpoints/messages.
+ Returns device and async signal names used for endpoints/messages.
Returns:
- tuple[str, str] | None: (device_name, async_signal_name) or None if not available.
+ tuple[str, str] | None: (device, async_signal_name) or None if not available.
"""
- if not self._config.device_name or not self._config.device_entry:
+ if not self._config.device or not self._config.signal:
return None
config = self.subscriptions["main"]
- async_signal = config.async_signal_name or self._config.device_entry
- return self._config.device_name, async_signal
+ async_signal = config.async_signal_name or self._config.signal
+ return self._config.device, async_signal
def _setup_async_image(self, scan_id: str | None):
"""
@@ -823,7 +813,7 @@ def _setup_async_image(self, scan_id: str | None):
logger.info("Async image setup skipped because monitor information is incomplete.")
return
- device_name, async_signal = async_names
+ device, async_signal = async_names
if config.monitor_type == "1d":
slot = self.on_image_update_1d
elif config.monitor_type == "2d":
@@ -839,7 +829,7 @@ def _setup_async_image(self, scan_id: str | None):
if prev_scan_id is None:
continue
self.bec_dispatcher.disconnect_slot(
- slot, MessageEndpoints.device_async_signal(prev_scan_id, device_name, async_signal)
+ slot, MessageEndpoints.device_async_signal(prev_scan_id, device, async_signal)
)
if scan_id is None:
@@ -848,26 +838,26 @@ def _setup_async_image(self, scan_id: str | None):
self.bec_dispatcher.connect_slot(
slot,
- MessageEndpoints.device_async_signal(scan_id, device_name, async_signal),
+ MessageEndpoints.device_async_signal(scan_id, device, async_signal),
from_start=True,
cb_info={"scan_id": scan_id},
)
- logger.info(f"Setup async image for {device_name}.{async_signal} and scan {scan_id}.")
+ logger.info(f"Setup async image for {device}.{async_signal} and scan {scan_id}.")
- def disconnect_monitor(self, device_name: str | None = None, device_entry: str | None = None):
+ def disconnect_monitor(self, device: str | None = None, signal: str | None = None):
"""
Disconnect the monitor from the image update signals, both 1D and 2D.
Args:
- device_name(str|None): The name of the device to disconnect. Defaults to current device.
- device_entry(str|None): The signal/entry name to disconnect. Defaults to current entry.
+ device(str|None): The name of the device to disconnect. Defaults to current device.
+ signal(str|None): The signal/entry name to disconnect. Defaults to current signal.
"""
config = self.subscriptions["main"]
- target_device = device_name or self._config.device_name
- target_entry = device_entry or self._config.device_entry
+ target_device = device or self._config.device
+ target_entry = signal or self._config.signal
if not target_device or not target_entry:
- logger.warning("Cannot disconnect monitor without both device_name and device_entry")
+ logger.warning("Cannot disconnect monitor without both device and signal")
return
if self.async_update:
@@ -1045,10 +1035,10 @@ def _on_layer_removed(self, layer_name: str):
if layer_name not in self.subscriptions:
return
# For the main layer, disconnect current monitor
- if layer_name == "main" and self._config.device_name and self._config.device_entry:
+ if layer_name == "main" and self._config.device and self._config.signal:
self._disconnect_current_monitor()
- self._config.device_name = ""
- self._config.device_entry = ""
+ self._config.device = ""
+ self._config.signal = ""
self._signal_configs.pop("main", None)
def cleanup(self):
@@ -1058,7 +1048,7 @@ def cleanup(self):
self.layer_removed.disconnect(self._on_layer_removed)
# Disconnect current monitor
- if self._config.device_name and self._config.device_entry:
+ if self._config.device and self._config.signal:
self._disconnect_current_monitor()
self.subscriptions.clear()
diff --git a/bec_widgets/widgets/plots/image/toolbar_components/device_selection.py b/bec_widgets/widgets/plots/image/toolbar_components/device_selection.py
index caef8657a..b9746f530 100644
--- a/bec_widgets/widgets/plots/image/toolbar_components/device_selection.py
+++ b/bec_widgets/widgets/plots/image/toolbar_components/device_selection.py
@@ -64,32 +64,32 @@ def __init__(self, parent=None, client=None):
layout.addWidget(self.device_combo_box, stretch=1)
layout.addWidget(self.signal_combo_box, stretch=1)
- def set_device_and_signal(self, device_name: str | None, device_entry: str | None) -> None:
+ def set_device_and_signal(self, device: str | None, signal: str | None) -> None:
"""Set the displayed device and signal without emitting selection signals."""
- device_name = device_name or ""
- device_entry = device_entry or ""
+ device = device or ""
+ signal = signal or ""
self.device_combo_box.blockSignals(True)
self.signal_combo_box.blockSignals(True)
try:
- if device_name:
+ if device:
# Set device in device_combo_box
- index = self.device_combo_box.findText(device_name)
+ index = self.device_combo_box.findText(device)
if index >= 0:
self.device_combo_box.setCurrentIndex(index)
else:
# Device not found in list, but still set it
- self.device_combo_box.setCurrentText(device_name)
+ self.device_combo_box.setCurrentText(device)
# Only update signal combobox device filter if it's actually changing
# This prevents redundant repopulation which can cause duplicates !!!!
current_device = getattr(self.signal_combo_box, "_device", None)
- if current_device != device_name:
- self.signal_combo_box.set_device(device_name)
+ if current_device != device:
+ self.signal_combo_box.set_device(device)
# Sync signal combobox selection
- if device_entry:
+ if signal:
# Try to find the signal by component_name (which is what's displayed)
found = False
for i in range(self.signal_combo_box.count()):
@@ -99,14 +99,14 @@ def set_device_and_signal(self, device_name: str | None, device_entry: str | Non
# Check if this matches our signal
if config_data:
component_name = config_data.get("component_name", "")
- if text == component_name or text == device_entry:
+ if text == component_name or text == signal:
self.signal_combo_box.setCurrentIndex(i)
found = True
break
if not found:
- # Fallback: try to match the device_entry directly
- index = self.signal_combo_box.findText(device_entry)
+ # Fallback: try to match the signal directly
+ index = self.signal_combo_box.findText(signal)
if index >= 0:
self.signal_combo_box.setCurrentIndex(index)
else:
@@ -187,8 +187,8 @@ def __init__(self, components: ToolbarComponents, target_widget=None):
self.components = components
self.target_widget = target_widget
self._connected = False
- self.register_property_sync("device_name", self._sync_from_device_name)
- self.register_property_sync("device_entry", self._sync_from_device_entry)
+ self.register_property_sync("device", self._sync_from_device)
+ self.register_property_sync("signal", self._sync_from_signal)
self.register_property_sync("connection_status", self._sync_connection_status)
self.register_property_sync("connection_error", self._sync_connection_status)
@@ -222,26 +222,22 @@ def disconnect(self):
self._connected = False
widget.cleanup()
- def _sync_from_device_name(self, _):
+ def _sync_from_device(self, _):
try:
widget = self._widget()
except Exception:
return
- widget.set_device_and_signal(
- self.target_widget.device_name, self.target_widget.device_entry
- )
- self.target_widget._sync_device_entry_from_toolbar()
+ widget.set_device_and_signal(self.target_widget.device, self.target_widget.signal)
+ self.target_widget._sync_signal_from_toolbar()
- def _sync_from_device_entry(self, _):
+ def _sync_from_signal(self, _):
try:
widget = self._widget()
except Exception:
return
- widget.set_device_and_signal(
- self.target_widget.device_name, self.target_widget.device_entry
- )
+ widget.set_device_and_signal(self.target_widget.device, self.target_widget.signal)
def _sync_connection_status(self, _):
try:
diff --git a/bec_widgets/widgets/plots/motor_map/motor_map.py b/bec_widgets/widgets/plots/motor_map/motor_map.py
index 7073bedc4..d2f014866 100644
--- a/bec_widgets/widgets/plots/motor_map/motor_map.py
+++ b/bec_widgets/widgets/plots/motor_map/motor_map.py
@@ -48,14 +48,14 @@ def paint(self, painter, *args):
class MotorConfig(BaseModel):
- name: str | None = Field(None, description="Motor name.")
+ device: str | None = Field(None, description="Motor name.")
limits: list[float] | None = Field(None, description="Motor limits.")
# noinspection PyDataclass
class MotorMapConfig(ConnectionConfig):
- x_motor: MotorConfig = Field(default_factory=MotorConfig, description="Motor X name.")
- y_motor: MotorConfig = Field(default_factory=MotorConfig, description="Motor Y name.")
+ device_x: MotorConfig = Field(default_factory=MotorConfig, description="Motor X name.")
+ device_y: MotorConfig = Field(default_factory=MotorConfig, description="Motor Y name.")
color: str | tuple | None = Field(
(255, 255, 255, 255), description="The color of the last point of current position."
)
@@ -109,10 +109,10 @@ class MotorMap(PlotBase):
"map",
"reset_history",
"get_data",
- "x_motor",
- "x_motor.setter",
- "y_motor",
- "y_motor.setter",
+ "device_x",
+ "device_x.setter",
+ "device_y",
+ "device_y.setter",
]
update_signal = Signal()
@@ -208,7 +208,7 @@ def on_motor_selection_changed(self, _):
return
if motor_x != "" and motor_y != "":
- if motor_x != self.config.x_motor.name or motor_y != self.config.y_motor.name:
+ if motor_x != self.config.device_x.device or motor_y != self.config.device_y.device:
self.map(motor_x, motor_y)
def _add_motor_map_settings(self):
@@ -259,32 +259,32 @@ def _motor_map_settings_closed(self):
################################################################################
@SafeProperty(str)
- def x_motor(self) -> str:
+ def device_x(self) -> str:
"""Name of the motor shown on the X axis."""
- return self.config.x_motor.name or ""
+ return self.config.device_x.device or ""
- @x_motor.setter
- def x_motor(self, motor_name: str) -> None:
+ @device_x.setter
+ def device_x(self, motor_name: str) -> None:
motor_name = motor_name or ""
- if motor_name == (self.config.x_motor.name or ""):
+ if motor_name == (self.config.device_x.device or ""):
return
- if motor_name and self.y_motor:
- self.map(motor_name, self.y_motor, suppress_errors=True)
+ if motor_name and self.device_y:
+ self.map(motor_name, self.device_y, suppress_errors=True)
return
self._set_motor_name(axis="x", motor_name=motor_name)
@SafeProperty(str)
- def y_motor(self) -> str:
+ def device_y(self) -> str:
"""Name of the motor shown on the Y axis."""
- return self.config.y_motor.name or ""
+ return self.config.device_y.device or ""
- @y_motor.setter
- def y_motor(self, motor_name: str) -> None:
+ @device_y.setter
+ def device_y(self, motor_name: str) -> None:
motor_name = motor_name or ""
- if motor_name == (self.config.y_motor.name or ""):
+ if motor_name == (self.config.device_y.device or ""):
return
- if motor_name and self.x_motor:
- self.map(self.x_motor, motor_name, suppress_errors=True)
+ if motor_name and self.device_x:
+ self.map(self.device_x, motor_name, suppress_errors=True)
return
self._set_motor_name(axis="y", motor_name=motor_name)
@@ -452,13 +452,13 @@ def _set_motor_name(self, axis: str, motor_name: str, *, sync_toolbar: bool = Tr
Update stored motor name for given axis and optionally refresh the toolbar selection.
"""
motor_name = motor_name or ""
- motor_config = self.config.x_motor if axis == "x" else self.config.y_motor
+ motor_config = self.config.device_x if axis == "x" else self.config.device_y
- if motor_config.name == motor_name:
+ if motor_config.device == motor_name:
return
- motor_config.name = motor_name
- self.property_changed.emit(f"{axis}_motor", motor_name)
+ motor_config.device = motor_name
+ self.property_changed.emit(f"device_{axis}", motor_name)
if sync_toolbar:
self._sync_motor_map_selection_toolbar()
@@ -468,14 +468,14 @@ def _set_motor_name(self, axis: str, motor_name: str, *, sync_toolbar: bool = Tr
################################################################################
@SafeSlot()
def map(
- self, x_name: str, y_name: str, validate_bec: bool = True, suppress_errors=False
+ self, device_x: str, device_y: str, validate_bec: bool = True, suppress_errors=False
) -> None:
"""
Set the x and y motor names.
Args:
- x_name(str): The name of the x motor.
- y_name(str): The name of the y motor.
+ device_x(str): The name of the x motor.
+ device_y(str): The name of the y motor.
validate_bec(bool, optional): If True, validate the signal with BEC. Defaults to True.
suppress_errors(bool, optional): If True, suppress errors during validation. Defaults to False. Used for properties setting. If the validation fails, the changes are not applied.
"""
@@ -484,22 +484,22 @@ def map(
if validate_bec:
if suppress_errors:
try:
- self.entry_validator.validate_signal(x_name, None)
- self.entry_validator.validate_signal(y_name, None)
+ self.entry_validator.validate_signal(device_x, None)
+ self.entry_validator.validate_signal(device_y, None)
except Exception:
return
else:
- self.entry_validator.validate_signal(x_name, None)
- self.entry_validator.validate_signal(y_name, None)
+ self.entry_validator.validate_signal(device_x, None)
+ self.entry_validator.validate_signal(device_y, None)
- self._set_motor_name(axis="x", motor_name=x_name, sync_toolbar=False)
- self._set_motor_name(axis="y", motor_name=y_name, sync_toolbar=False)
+ self._set_motor_name(axis="x", motor_name=device_x, sync_toolbar=False)
+ self._set_motor_name(axis="y", motor_name=device_y, sync_toolbar=False)
- motor_x_limit = self._get_motor_limit(self.config.x_motor.name)
- motor_y_limit = self._get_motor_limit(self.config.y_motor.name)
+ motor_x_limit = self._get_motor_limit(self.config.device_x.device)
+ motor_y_limit = self._get_motor_limit(self.config.device_y.device)
- self.config.x_motor.limits = motor_x_limit
- self.config.y_motor.limits = motor_y_limit
+ self.config.device_x.limits = motor_x_limit
+ self.config.device_y.limits = motor_y_limit
# reconnect the signals
self._connect_motor_to_slots()
@@ -574,19 +574,19 @@ def on_device_readback(self, msg: dict, metadata: dict) -> None:
msg(dict): Message from the device readback.
metadata(dict): Metadata of the message.
"""
- x_motor = self.config.x_motor.name
- y_motor = self.config.y_motor.name
+ device_x = self.config.device_x.device
+ device_y = self.config.device_y.device
- if x_motor is None or y_motor is None:
+ if device_x is None or device_y is None:
return
- if x_motor in msg["signals"]:
- x = msg["signals"][x_motor]["value"]
+ if device_x in msg["signals"]:
+ x = msg["signals"][device_x]["value"]
self._buffer["x"].append(x)
self._buffer["y"].append(self._buffer["y"][-1])
- elif y_motor in msg["signals"]:
- y = msg["signals"][y_motor]["value"]
+ elif device_y in msg["signals"]:
+ y = msg["signals"][device_y]["value"]
self._buffer["y"].append(y)
self._buffer["x"].append(self._buffer["x"][-1])
@@ -597,12 +597,12 @@ def _connect_motor_to_slots(self):
self._disconnect_current_motors()
endpoints_readback = [
- MessageEndpoints.device_readback(self.config.x_motor.name),
- MessageEndpoints.device_readback(self.config.y_motor.name),
+ MessageEndpoints.device_readback(self.config.device_x.device),
+ MessageEndpoints.device_readback(self.config.device_y.device),
]
endpoints_limits = [
- MessageEndpoints.device_limits(self.config.x_motor.name),
- MessageEndpoints.device_limits(self.config.y_motor.name),
+ MessageEndpoints.device_limits(self.config.device_x.device),
+ MessageEndpoints.device_limits(self.config.device_y.device),
]
self.bec_dispatcher.connect_slot(self.on_device_readback, endpoints_readback)
@@ -610,14 +610,14 @@ def _connect_motor_to_slots(self):
def _disconnect_current_motors(self):
"""Disconnect the current motors from the slots."""
- if self.config.x_motor.name is not None and self.config.y_motor.name is not None:
+ if self.config.device_x.device is not None and self.config.device_y.device is not None:
endpoints_readback = [
- MessageEndpoints.device_readback(self.config.x_motor.name),
- MessageEndpoints.device_readback(self.config.y_motor.name),
+ MessageEndpoints.device_readback(self.config.device_x.device),
+ MessageEndpoints.device_readback(self.config.device_y.device),
]
endpoints_limits = [
- MessageEndpoints.device_limits(self.config.x_motor.name),
- MessageEndpoints.device_limits(self.config.y_motor.name),
+ MessageEndpoints.device_limits(self.config.device_x.device),
+ MessageEndpoints.device_limits(self.config.device_y.device),
]
self.bec_dispatcher.disconnect_slot(self.on_device_readback, endpoints_readback)
self.bec_dispatcher.disconnect_slot(self.on_device_limits, endpoints_limits)
@@ -634,8 +634,8 @@ def on_device_limits(self, msg: dict, metadata: dict) -> None:
msg(dict): Message from the device limits.
metadata(dict): Metadata of the message.
"""
- self.config.x_motor.limits = self._get_motor_limit(self.config.x_motor.name)
- self.config.y_motor.limits = self._get_motor_limit(self.config.y_motor.name)
+ self.config.device_x.limits = self._get_motor_limit(self.config.device_x.device)
+ self.config.device_y.limits = self._get_motor_limit(self.config.device_y.device)
self._swap_limit_map()
def _get_motor_limit(self, motor: str) -> list | None:
@@ -663,8 +663,8 @@ def _make_motor_map(self) -> None:
Make the motor map.
"""
- motor_x_limit = self.config.x_motor.limits
- motor_y_limit = self.config.y_motor.limits
+ motor_x_limit = self.config.device_x.limits
+ motor_y_limit = self.config.device_y.limits
self._limit_map = self._make_limit_map(motor_x_limit, motor_y_limit)
self.plot_item.addItem(self._limit_map)
@@ -678,10 +678,10 @@ def _make_motor_map(self) -> None:
# Add the crosshair for initial motor coordinates
initial_position_x = self._get_motor_init_position(
- self.config.x_motor.name, self.config.precision
+ self.config.device_x.device, self.config.precision
)
initial_position_y = self._get_motor_init_position(
- self.config.y_motor.name, self.config.precision
+ self.config.device_y.device, self.config.precision
)
self._buffer["x"] = [initial_position_x]
@@ -693,8 +693,8 @@ def _make_motor_map(self) -> None:
self._add_coordinates_crosshair(initial_position_x, initial_position_y)
# Set default labels for the plot
- self.set_x_label_suffix(f"[{self.config.x_motor.name}-{self.config.x_motor.name}]")
- self.set_y_label_suffix(f"[{self.config.y_motor.name}-{self.config.y_motor.name}]")
+ self.set_x_label_suffix(f"[{self.config.device_x.device}-{self.config.device_x.device}]")
+ self.set_y_label_suffix(f"[{self.config.device_y.device}-{self.config.device_y.device}]")
self.update_signal.emit()
@@ -794,8 +794,8 @@ def fix_limit_pair(limits):
def _swap_limit_map(self):
"""Swap the limit map."""
self.plot_item.removeItem(self._limit_map)
- x_limits = self.config.x_motor.limits
- y_limits = self.config.y_motor.limits
+ x_limits = self.config.device_x.limits
+ y_limits = self.config.device_y.limits
if x_limits is not None and y_limits is not None:
self._limit_map = self._make_limit_map(x_limits, y_limits)
self._limit_map.setZValue(-1)
@@ -828,8 +828,8 @@ def _sync_motor_map_selection_toolbar(self):
if motor_selection_action is None:
return
motor_selection: MotorSelection = motor_selection_action.widget
- target_x = self.config.x_motor.name or ""
- target_y = self.config.y_motor.name or ""
+ target_x = self.config.device_x.device or ""
+ target_y = self.config.device_y.device or ""
if (
motor_selection.motor_x.currentText() == target_x
@@ -864,10 +864,10 @@ def __init__(self):
self.setCentralWidget(self.main_widget)
self.motor_map_popup = MotorMap(popups=True)
- self.motor_map_popup.map(x_name="samx", y_name="samy", validate_bec=True)
+ self.motor_map_popup.map(device_x="samx", device_y="samy", validate_bec=True)
self.motor_map_side = MotorMap(popups=False)
- self.motor_map_side.map(x_name="samx", y_name="samy", validate_bec=True)
+ self.motor_map_side.map(device_x="samx", device_y="samy", validate_bec=True)
self.layout.addWidget(self.motor_map_side)
self.layout.addWidget(self.motor_map_popup)
diff --git a/bec_widgets/widgets/plots/scatter_waveform/scatter_curve.py b/bec_widgets/widgets/plots/scatter_waveform/scatter_curve.py
index bd12e6487..4624e50cb 100644
--- a/bec_widgets/widgets/plots/scatter_waveform/scatter_curve.py
+++ b/bec_widgets/widgets/plots/scatter_waveform/scatter_curve.py
@@ -20,8 +20,8 @@
class ScatterDeviceSignal(BaseModel):
"""The configuration of a signal in the scatter waveform widget."""
- name: str
- entry: str
+ device: str
+ signal: str
model_config: dict = {"validate_assignment": True}
@@ -40,13 +40,13 @@ class ScatterCurveConfig(ConnectionConfig):
color_map: str | None = Field(
"plasma", description="The color palette of the figure widget.", validate_default=True
)
- x_device: ScatterDeviceSignal | None = Field(
+ device_x: ScatterDeviceSignal | None = Field(
None, description="The x device signal of the scatter waveform."
)
- y_device: ScatterDeviceSignal | None = Field(
+ device_y: ScatterDeviceSignal | None = Field(
None, description="The y device signal of the scatter waveform."
)
- z_device: ScatterDeviceSignal | None = Field(
+ device_z: ScatterDeviceSignal | None = Field(
None, description="The z device signal of the scatter waveform."
)
diff --git a/bec_widgets/widgets/plots/scatter_waveform/scatter_waveform.py b/bec_widgets/widgets/plots/scatter_waveform/scatter_waveform.py
index 48a20f147..94fb063f7 100644
--- a/bec_widgets/widgets/plots/scatter_waveform/scatter_waveform.py
+++ b/bec_widgets/widgets/plots/scatter_waveform/scatter_waveform.py
@@ -49,18 +49,18 @@ class ScatterWaveform(PlotBase):
"update_with_scan_history",
"clear_all",
# Device properties
- "x_device_name",
- "x_device_name.setter",
- "x_device_entry",
- "x_device_entry.setter",
- "y_device_name",
- "y_device_name.setter",
- "y_device_entry",
- "y_device_entry.setter",
- "z_device_name",
- "z_device_name.setter",
- "z_device_entry",
- "z_device_entry.setter",
+ "device_x",
+ "device_x.setter",
+ "signal_x",
+ "signal_x.setter",
+ "device_y",
+ "device_y.setter",
+ "signal_y",
+ "signal_y.setter",
+ "device_z",
+ "device_z.setter",
+ "signal_z",
+ "signal_z.setter",
]
sync_signal_update = Signal()
@@ -208,12 +208,12 @@ def color_map(self, value: str):
@SafeSlot(popup_error=True)
def plot(
self,
- x_name: str,
- y_name: str,
- z_name: str,
- x_entry: None | str = None,
- y_entry: None | str = None,
- z_entry: None | str = None,
+ device_x: str,
+ device_y: str,
+ device_z: str,
+ signal_x: None | str = None,
+ signal_y: None | str = None,
+ signal_z: None | str = None,
color_map: str | None = "plasma",
label: str | None = None,
validate_bec: bool = True,
@@ -222,12 +222,12 @@ def plot(
Plot the data from the device signals.
Args:
- x_name (str): The name of the x device signal.
- y_name (str): The name of the y device signal.
- z_name (str): The name of the z device signal.
- x_entry (None | str): The x entry of the device signal.
- y_entry (None | str): The y entry of the device signal.
- z_entry (None | str): The z entry of the device signal.
+ device_x (str): The name of the x device signal.
+ device_y (str): The name of the y device signal.
+ device_z (str): The name of the z device signal.
+ signal_x (None | str): The x entry of the device signal.
+ signal_y (None | str): The y entry of the device signal.
+ signal_z (None | str): The z entry of the device signal.
color_map (str | None): The color map of the scatter waveform.
label (str | None): The label of the curve.
validate_bec (bool): Whether to validate the device signals with current BEC instance.
@@ -237,9 +237,9 @@ def plot(
"""
if validate_bec:
- x_entry = self.entry_validator.validate_signal(x_name, x_entry)
- y_entry = self.entry_validator.validate_signal(y_name, y_entry)
- z_entry = self.entry_validator.validate_signal(z_name, z_entry)
+ signal_x = self.entry_validator.validate_signal(device_x, signal_x)
+ signal_y = self.entry_validator.validate_signal(device_y, signal_y)
+ signal_z = self.entry_validator.validate_signal(device_z, signal_z)
if color_map is not None:
try:
@@ -250,15 +250,15 @@ def plot(
)
if label is None:
- label = f"{z_name}-{z_entry}"
+ label = f"{device_z}-{signal_z}"
config = ScatterCurveConfig(
parent_id=self.gui_id,
label=label,
color_map=color_map,
- x_device=ScatterDeviceSignal(name=x_name, entry=x_entry),
- y_device=ScatterDeviceSignal(name=y_name, entry=y_entry),
- z_device=ScatterDeviceSignal(name=z_name, entry=z_entry),
+ device_x=ScatterDeviceSignal(device=device_x, signal=signal_x),
+ device_y=ScatterDeviceSignal(device=device_y, signal=signal_y),
+ device_z=ScatterDeviceSignal(device=device_z, signal=signal_z),
)
# Add Curve
@@ -350,23 +350,23 @@ def update_sync_curves(self, _=None):
return "none"
try:
- x_name = self._main_curve.config.x_device.name
- x_entry = self._main_curve.config.x_device.entry
- y_name = self._main_curve.config.y_device.name
- y_entry = self._main_curve.config.y_device.entry
- z_name = self._main_curve.config.z_device.name
- z_entry = self._main_curve.config.z_device.entry
+ device_x = self._main_curve.config.device_x.device
+ signal_x = self._main_curve.config.device_x.signal
+ device_y = self._main_curve.config.device_y.device
+ signal_y = self._main_curve.config.device_y.signal
+ device_z = self._main_curve.config.device_z.device
+ signal_z = self._main_curve.config.device_z.signal
except AttributeError:
return
if access_key == "val":
- x_data = data.get(x_name, {}).get(x_entry, {}).get(access_key, None)
- y_data = data.get(y_name, {}).get(y_entry, {}).get(access_key, None)
- z_data = data.get(z_name, {}).get(z_entry, {}).get(access_key, None)
+ x_data = data.get(device_x, {}).get(signal_x, {}).get(access_key, None)
+ y_data = data.get(device_y, {}).get(signal_y, {}).get(access_key, None)
+ z_data = data.get(device_z, {}).get(signal_z, {}).get(access_key, None)
else:
- x_data = data.get(x_name, {}).get(x_entry, {}).read().get("value", None)
- y_data = data.get(y_name, {}).get(y_entry, {}).read().get("value", None)
- z_data = data.get(z_name, {}).get(z_entry, {}).read().get("value", None)
+ x_data = data.get(device_x, {}).get(signal_x, {}).read().get("value", None)
+ y_data = data.get(device_y, {}).get(signal_y, {}).read().get("value", None)
+ z_data = data.get(device_z, {}).get(signal_z, {}).read().get("value", None)
self._main_curve.set_data(x=x_data, y=y_data, z=z_data)
@@ -399,14 +399,14 @@ def _fetch_scan_data_and_access(self):
################################################################################
@SafeProperty(str)
- def x_device_name(self) -> str:
+ def device_x(self) -> str:
"""Device name for the X axis."""
- if self._main_curve is None or self._main_curve.config.x_device is None:
+ if self._main_curve is None or self._main_curve.config.device_x is None:
return ""
- return self._main_curve.config.x_device.name or ""
+ return self._main_curve.config.device_x.device or ""
- @x_device_name.setter
- def x_device_name(self, device_name: str) -> None:
+ @device_x.setter
+ def device_x(self, device_name: str) -> None:
"""
Set the X device name.
@@ -419,33 +419,33 @@ def x_device_name(self, device_name: str) -> None:
try:
entry = self.entry_validator.validate_signal(device_name, None)
# Update or create config
- if self._main_curve.config.x_device is None:
- self._main_curve.config.x_device = ScatterDeviceSignal(
- name=device_name, entry=entry
+ if self._main_curve.config.device_x is None:
+ self._main_curve.config.device_x = ScatterDeviceSignal(
+ device=device_name, signal=entry
)
else:
- self._main_curve.config.x_device.name = device_name
- self._main_curve.config.x_device.entry = entry
- self.property_changed.emit("x_device_name", device_name)
+ self._main_curve.config.device_x.device = device_name
+ self._main_curve.config.device_x.signal = entry
+ self.property_changed.emit("device_x", device_name)
self.update_labels()
self._try_auto_plot()
except Exception:
pass # Silently fail if device is not available yet
else:
- if self._main_curve.config.x_device is not None:
- self._main_curve.config.x_device = None
- self.property_changed.emit("x_device_name", "")
+ if self._main_curve.config.device_x is not None:
+ self._main_curve.config.device_x = None
+ self.property_changed.emit("device_x", "")
self.update_labels()
@SafeProperty(str)
- def x_device_entry(self) -> str:
+ def signal_x(self) -> str:
"""Signal entry for the X axis device."""
- if self._main_curve is None or self._main_curve.config.x_device is None:
+ if self._main_curve is None or self._main_curve.config.device_x is None:
return ""
- return self._main_curve.config.x_device.entry or ""
+ return self._main_curve.config.device_x.signal or ""
- @x_device_entry.setter
- def x_device_entry(self, entry: str) -> None:
+ @signal_x.setter
+ def signal_x(self, entry: str) -> None:
"""
Set the X device entry.
@@ -455,29 +455,29 @@ def x_device_entry(self, entry: str) -> None:
if not entry:
return
- if self._main_curve.config.x_device is None:
- logger.warning("Cannot set x_device_entry without x_device_name set first.")
+ if self._main_curve.config.device_x is None:
+ logger.warning("Cannot set signal_x without device_x set first.")
return
- device_name = self._main_curve.config.x_device.name
+ device_name = self._main_curve.config.device_x.device
try:
- validated_entry = self.entry_validator.validate_signal(device_name, entry)
- self._main_curve.config.x_device.entry = validated_entry
- self.property_changed.emit("x_device_entry", validated_entry)
+ validated_signal = self.entry_validator.validate_signal(device_name, entry)
+ self._main_curve.config.device_x.signal = validated_signal
+ self.property_changed.emit("signal_x", validated_signal)
self.update_labels()
self._try_auto_plot()
except Exception:
pass # Silently fail if validation fails
@SafeProperty(str)
- def y_device_name(self) -> str:
+ def device_y(self) -> str:
"""Device name for the Y axis."""
- if self._main_curve is None or self._main_curve.config.y_device is None:
+ if self._main_curve is None or self._main_curve.config.device_y is None:
return ""
- return self._main_curve.config.y_device.name or ""
+ return self._main_curve.config.device_y.device or ""
- @y_device_name.setter
- def y_device_name(self, device_name: str) -> None:
+ @device_y.setter
+ def device_y(self, device_name: str) -> None:
"""
Set the Y device name.
@@ -490,33 +490,33 @@ def y_device_name(self, device_name: str) -> None:
try:
entry = self.entry_validator.validate_signal(device_name, None)
# Update or create config
- if self._main_curve.config.y_device is None:
- self._main_curve.config.y_device = ScatterDeviceSignal(
- name=device_name, entry=entry
+ if self._main_curve.config.device_y is None:
+ self._main_curve.config.device_y = ScatterDeviceSignal(
+ device=device_name, signal=entry
)
else:
- self._main_curve.config.y_device.name = device_name
- self._main_curve.config.y_device.entry = entry
- self.property_changed.emit("y_device_name", device_name)
+ self._main_curve.config.device_y.device = device_name
+ self._main_curve.config.device_y.signal = entry
+ self.property_changed.emit("device_y", device_name)
self.update_labels()
self._try_auto_plot()
except Exception:
pass # Silently fail if device is not available yet
else:
- if self._main_curve.config.y_device is not None:
- self._main_curve.config.y_device = None
- self.property_changed.emit("y_device_name", "")
+ if self._main_curve.config.device_y is not None:
+ self._main_curve.config.device_y = None
+ self.property_changed.emit("device_y", "")
self.update_labels()
@SafeProperty(str)
- def y_device_entry(self) -> str:
+ def signal_y(self) -> str:
"""Signal entry for the Y axis device."""
- if self._main_curve is None or self._main_curve.config.y_device is None:
+ if self._main_curve is None or self._main_curve.config.device_y is None:
return ""
- return self._main_curve.config.y_device.entry or ""
+ return self._main_curve.config.device_y.signal or ""
- @y_device_entry.setter
- def y_device_entry(self, entry: str) -> None:
+ @signal_y.setter
+ def signal_y(self, entry: str) -> None:
"""
Set the Y device entry.
@@ -526,29 +526,29 @@ def y_device_entry(self, entry: str) -> None:
if not entry:
return
- if self._main_curve.config.y_device is None:
- logger.warning("Cannot set y_device_entry without y_device_name set first.")
+ if self._main_curve.config.device_y is None:
+ logger.warning("Cannot set signal_y without device_y set first.")
return
- device_name = self._main_curve.config.y_device.name
+ device_name = self._main_curve.config.device_y.device
try:
- validated_entry = self.entry_validator.validate_signal(device_name, entry)
- self._main_curve.config.y_device.entry = validated_entry
- self.property_changed.emit("y_device_entry", validated_entry)
+ validated_signal = self.entry_validator.validate_signal(device_name, entry)
+ self._main_curve.config.device_y.signal = validated_signal
+ self.property_changed.emit("signal_y", validated_signal)
self.update_labels()
self._try_auto_plot()
except Exception:
pass # Silently fail if validation fails
@SafeProperty(str)
- def z_device_name(self) -> str:
+ def device_z(self) -> str:
"""Device name for the Z (color) axis."""
- if self._main_curve is None or self._main_curve.config.z_device is None:
+ if self._main_curve is None or self._main_curve.config.device_z is None:
return ""
- return self._main_curve.config.z_device.name or ""
+ return self._main_curve.config.device_z.device or ""
- @z_device_name.setter
- def z_device_name(self, device_name: str) -> None:
+ @device_z.setter
+ def device_z(self, device_name: str) -> None:
"""
Set the Z device name.
@@ -561,33 +561,33 @@ def z_device_name(self, device_name: str) -> None:
try:
entry = self.entry_validator.validate_signal(device_name, None)
# Update or create config
- if self._main_curve.config.z_device is None:
- self._main_curve.config.z_device = ScatterDeviceSignal(
- name=device_name, entry=entry
+ if self._main_curve.config.device_z is None:
+ self._main_curve.config.device_z = ScatterDeviceSignal(
+ device=device_name, signal=entry
)
else:
- self._main_curve.config.z_device.name = device_name
- self._main_curve.config.z_device.entry = entry
- self.property_changed.emit("z_device_name", device_name)
+ self._main_curve.config.device_z.device = device_name
+ self._main_curve.config.device_z.signal = entry
+ self.property_changed.emit("device_z", device_name)
self.update_labels()
self._try_auto_plot()
except Exception:
pass # Silently fail if device is not available yet
else:
- if self._main_curve.config.z_device is not None:
- self._main_curve.config.z_device = None
- self.property_changed.emit("z_device_name", "")
+ if self._main_curve.config.device_z is not None:
+ self._main_curve.config.device_z = None
+ self.property_changed.emit("device_z", "")
self.update_labels()
@SafeProperty(str)
- def z_device_entry(self) -> str:
+ def signal_z(self) -> str:
"""Signal entry for the Z (color) axis device."""
- if self._main_curve is None or self._main_curve.config.z_device is None:
+ if self._main_curve is None or self._main_curve.config.device_z is None:
return ""
- return self._main_curve.config.z_device.entry or ""
+ return self._main_curve.config.device_z.signal or ""
- @z_device_entry.setter
- def z_device_entry(self, entry: str) -> None:
+ @signal_z.setter
+ def signal_z(self, entry: str) -> None:
"""
Set the Z device entry.
@@ -597,15 +597,15 @@ def z_device_entry(self, entry: str) -> None:
if not entry:
return
- if self._main_curve.config.z_device is None:
- logger.warning("Cannot set z_device_entry without z_device_name set first.")
+ if self._main_curve.config.device_z is None:
+ logger.warning("Cannot set signal_z without device_z set first.")
return
- device_name = self._main_curve.config.z_device.name
+ device_name = self._main_curve.config.device_z.device
try:
- validated_entry = self.entry_validator.validate_signal(device_name, entry)
- self._main_curve.config.z_device.entry = validated_entry
- self.property_changed.emit("z_device_entry", validated_entry)
+ validated_signal = self.entry_validator.validate_signal(device_name, entry)
+ self._main_curve.config.device_z.signal = validated_signal
+ self.property_changed.emit("signal_z", validated_signal)
self.update_labels()
self._try_auto_plot()
except Exception:
@@ -615,25 +615,25 @@ def _try_auto_plot(self) -> None:
"""
Attempt to automatically call plot() if all three devices are set.
"""
- has_x = self._main_curve.config.x_device is not None
- has_y = self._main_curve.config.y_device is not None
- has_z = self._main_curve.config.z_device is not None
+ has_x = self._main_curve.config.device_x is not None
+ has_y = self._main_curve.config.device_y is not None
+ has_z = self._main_curve.config.device_z is not None
if has_x and has_y and has_z:
- x_name = self._main_curve.config.x_device.name
- x_entry = self._main_curve.config.x_device.entry
- y_name = self._main_curve.config.y_device.name
- y_entry = self._main_curve.config.y_device.entry
- z_name = self._main_curve.config.z_device.name
- z_entry = self._main_curve.config.z_device.entry
+ device_x = self._main_curve.config.device_x.device
+ signal_x = self._main_curve.config.device_x.signal
+ device_y = self._main_curve.config.device_y.device
+ signal_y = self._main_curve.config.device_y.signal
+ device_z = self._main_curve.config.device_z.device
+ signal_z = self._main_curve.config.device_z.signal
try:
self.plot(
- x_name=x_name,
- y_name=y_name,
- z_name=z_name,
- x_entry=x_entry,
- y_entry=y_entry,
- z_entry=z_entry,
+ device_x=device_x,
+ device_y=device_y,
+ device_z=device_z,
+ signal_x=signal_x,
+ signal_y=signal_y,
+ signal_z=signal_z,
validate_bec=False, # Don't validate - entries already validated
)
except Exception as e:
@@ -650,21 +650,21 @@ def update_labels(self):
config = self._main_curve.config
# Safely get device names
- x_device = config.x_device
- y_device = config.y_device
+ device_x = config.device_x
+ device_y = config.device_y
- x_name = x_device.name if x_device else None
- y_name = y_device.name if y_device else None
+ device_x = device_x.device if device_x else None
+ device_y = device_y.device if device_y else None
- if x_name is not None:
- self.x_label = x_name # type: ignore
- x_dev = self.dev.get(x_name)
+ if device_x is not None:
+ self.x_label = device_x # type: ignore
+ x_dev = self.dev.get(device_x)
if x_dev and hasattr(x_dev, "egu"):
self.x_label_units = x_dev.egu()
- if y_name is not None:
- self.y_label = y_name # type: ignore
- y_dev = self.dev.get(y_name)
+ if device_y is not None:
+ self.y_label = device_y # type: ignore
+ y_dev = self.dev.get(device_y)
if y_dev and hasattr(y_dev, "egu"):
self.y_label_units = y_dev.egu()
@@ -756,7 +756,7 @@ def __init__(self):
self.setCentralWidget(self.main_widget)
self.waveform_popup = ScatterWaveform(popups=True)
- self.waveform_popup.plot("samx", "samy", "bpm4i")
+ self.waveform_popup.plot(device_x="samx", device_y="samy", device_z="bpm4i")
self.waveform_side = ScatterWaveform(popups=False)
self.waveform_popup.plot("samx", "samy", "bpm3a")
diff --git a/bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_setting.py b/bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_setting.py
index 475181c51..46f211f55 100644
--- a/bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_setting.py
+++ b/bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_setting.py
@@ -58,81 +58,81 @@ def fetch_all_properties(self):
color_map = getattr(self.target_widget, "color_map", None)
# Default values for device properties
- x_name, x_entry = None, None
- y_name, y_entry = None, None
- z_name, z_entry = None, None
+ device_x, signal_x = None, None
+ device_y, signal_y = None, None
+ device_z, signal_z = None, None
# Safely access device properties
if hasattr(self.target_widget, "main_curve") and self.target_widget.main_curve:
if hasattr(self.target_widget.main_curve, "config"):
config = self.target_widget.main_curve.config
- if hasattr(config, "x_device") and config.x_device:
- x_name = getattr(config.x_device, "name", None)
- x_entry = getattr(config.x_device, "entry", None)
+ if hasattr(config, "device_x") and config.device_x:
+ device_x = getattr(config.device_x, "device", None)
+ signal_x = getattr(config.device_x, "signal", None)
- if hasattr(config, "y_device") and config.y_device:
- y_name = getattr(config.y_device, "name", None)
- y_entry = getattr(config.y_device, "entry", None)
+ if hasattr(config, "device_y") and config.device_y:
+ device_y = getattr(config.device_y, "device", None)
+ signal_y = getattr(config.device_y, "signal", None)
- if hasattr(config, "z_device") and config.z_device:
- z_name = getattr(config.z_device, "name", None)
- z_entry = getattr(config.z_device, "entry", None)
+ if hasattr(config, "device_z") and config.device_z:
+ device_z = getattr(config.device_z, "device", None)
+ signal_z = getattr(config.device_z, "signal", None)
# Apply the properties to the settings widget
if hasattr(self.ui, "color_map"):
self.ui.color_map.colormap = color_map
- if hasattr(self.ui, "x_name"):
- self.ui.x_name.set_device(x_name)
- if hasattr(self.ui, "x_entry") and x_entry is not None:
- self.ui.x_entry.set_to_obj_name(x_entry)
+ if hasattr(self.ui, "device_x"):
+ self.ui.device_x.set_device(device_x)
+ if hasattr(self.ui, "signal_x") and signal_x is not None:
+ self.ui.signal_x.set_to_obj_name(signal_x)
- if hasattr(self.ui, "y_name"):
- self.ui.y_name.set_device(y_name)
- if hasattr(self.ui, "y_entry") and y_entry is not None:
- self.ui.y_entry.set_to_obj_name(y_entry)
+ if hasattr(self.ui, "device_y"):
+ self.ui.device_y.set_device(device_y)
+ if hasattr(self.ui, "signal_y") and signal_y is not None:
+ self.ui.signal_y.set_to_obj_name(signal_y)
- if hasattr(self.ui, "z_name"):
- self.ui.z_name.set_device(z_name)
- if hasattr(self.ui, "z_entry") and z_entry is not None:
- self.ui.z_entry.set_to_obj_name(z_entry)
+ if hasattr(self.ui, "device_z"):
+ self.ui.device_z.set_device(device_z)
+ if hasattr(self.ui, "signal_z") and signal_z is not None:
+ self.ui.signal_z.set_to_obj_name(signal_z)
@SafeSlot()
def accept_changes(self):
"""
Apply all properties from the settings widget to the target widget.
"""
- x_name = self.ui.x_name.currentText()
- x_entry = self.ui.x_entry.get_signal_name()
- y_name = self.ui.y_name.currentText()
- y_entry = self.ui.y_entry.get_signal_name()
- z_name = self.ui.z_name.currentText()
- z_entry = self.ui.z_entry.get_signal_name()
+ device_x = self.ui.device_x.currentText()
+ signal_x = self.ui.signal_x.get_signal_name()
+ device_y = self.ui.device_y.currentText()
+ signal_y = self.ui.signal_y.get_signal_name()
+ device_z = self.ui.device_z.currentText()
+ signal_z = self.ui.signal_z.get_signal_name()
validate_bec = self.ui.validate_bec.checked
color_map = self.ui.color_map.colormap
self.target_widget.plot(
- x_name=x_name,
- y_name=y_name,
- z_name=z_name,
- x_entry=x_entry,
- y_entry=y_entry,
- z_entry=z_entry,
+ device_x=device_x,
+ device_y=device_y,
+ device_z=device_z,
+ signal_x=signal_x,
+ signal_y=signal_y,
+ signal_z=signal_z,
color_map=color_map,
validate_bec=validate_bec,
)
def cleanup(self):
- self.ui.x_name.close()
- self.ui.x_name.deleteLater()
- self.ui.x_entry.close()
- self.ui.x_entry.deleteLater()
- self.ui.y_name.close()
- self.ui.y_name.deleteLater()
- self.ui.y_entry.close()
- self.ui.y_entry.deleteLater()
- self.ui.z_name.close()
- self.ui.z_name.deleteLater()
- self.ui.z_entry.close()
- self.ui.z_entry.deleteLater()
+ self.ui.device_x.close()
+ self.ui.device_x.deleteLater()
+ self.ui.signal_x.close()
+ self.ui.signal_x.deleteLater()
+ self.ui.device_y.close()
+ self.ui.device_y.deleteLater()
+ self.ui.signal_y.close()
+ self.ui.signal_y.deleteLater()
+ self.ui.device_z.close()
+ self.ui.device_z.deleteLater()
+ self.ui.signal_z.close()
+ self.ui.signal_z.deleteLater()
diff --git a/bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_horizontal.ui b/bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_horizontal.ui
index c8527291c..7a9addf06 100644
--- a/bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_horizontal.ui
+++ b/bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_horizontal.ui
@@ -61,7 +61,7 @@
-
-
+
true
@@ -71,7 +71,7 @@
-
-
+
true
@@ -101,7 +101,7 @@
-
-
+
true
@@ -111,7 +111,7 @@
-
-
+
true
@@ -141,7 +141,7 @@
-
-
+
true
@@ -151,7 +151,7 @@
-
-
+
true
@@ -187,19 +187,19 @@
- x_name
- y_name
- z_name
- x_entry
- y_entry
- z_entry
+ device_x
+ device_y
+ device_z
+ signal_x
+ signal_y
+ signal_z
- x_name
+ device_x
device_reset()
- x_entry
+ signal_x
reset_selection()
@@ -213,9 +213,9 @@
- y_name
+ device_y
device_reset()
- y_entry
+ signal_y
reset_selection()
@@ -229,9 +229,9 @@
- z_name
+ device_z
device_reset()
- z_entry
+ signal_z
reset_selection()
@@ -245,9 +245,9 @@
- x_name
+ device_x
currentTextChanged(QString)
- x_entry
+ signal_x
set_device(QString)
@@ -261,9 +261,9 @@
- y_name
+ device_y
currentTextChanged(QString)
- y_entry
+ signal_y
set_device(QString)
@@ -277,9 +277,9 @@
- z_name
+ device_z
currentTextChanged(QString)
- z_entry
+ signal_z
set_device(QString)
diff --git a/bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_vertical.ui b/bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_vertical.ui
index 3529de4a5..27d47885f 100644
--- a/bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_vertical.ui
+++ b/bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_vertical.ui
@@ -58,7 +58,7 @@
-
-
+
-
@@ -68,7 +68,7 @@
-
-
+
@@ -87,7 +87,7 @@
-
-
+
-
@@ -97,7 +97,7 @@
-
-
+
@@ -116,7 +116,7 @@
-
-
+
-
@@ -126,7 +126,7 @@
-
-
+
@@ -153,9 +153,9 @@
- x_name
+ device_x
textChanged(QString)
- x_entry
+ signal_x
clear()
@@ -169,9 +169,9 @@
- y_name
+ device_y
textChanged(QString)
- y_entry
+ signal_y
clear()
@@ -185,9 +185,9 @@
- z_name
+ device_z
textChanged(QString)
- z_entry
+ signal_z
clear()
diff --git a/bec_widgets/widgets/plots/waveform/curve.py b/bec_widgets/widgets/plots/waveform/curve.py
index 250a83e2f..6f2894590 100644
--- a/bec_widgets/widgets/plots/waveform/curve.py
+++ b/bec_widgets/widgets/plots/waveform/curve.py
@@ -20,8 +20,8 @@
class DeviceSignal(BaseModel):
"""The configuration of a signal in the 1D waveform widget."""
- name: str
- entry: str
+ device: str
+ signal: str
dap: str | None = None
dap_oversample: int = 1
diff --git a/bec_widgets/widgets/plots/waveform/settings/curve_settings/curve_setting.py b/bec_widgets/widgets/plots/waveform/settings/curve_settings/curve_setting.py
index a5a0e0f71..3f3693177 100644
--- a/bec_widgets/widgets/plots/waveform/settings/curve_settings/curve_setting.py
+++ b/bec_widgets/widgets/plots/waveform/settings/curve_settings/curve_setting.py
@@ -140,7 +140,7 @@ def accept_changes(self):
signal_x = self.signal_x.currentText()
signal_data = self.signal_x.itemData(self.signal_x.currentIndex())
if signal_x != "":
- self.target_widget.x_entry = signal_data.get("obj_name", signal_x)
+ self.target_widget.signal_x = signal_data.get("obj_name", signal_x)
else:
self.target_widget.x_mode = self.mode_combo.currentText()
self.curve_manager.send_curve_json()
diff --git a/bec_widgets/widgets/plots/waveform/settings/curve_settings/curve_tree.py b/bec_widgets/widgets/plots/waveform/settings/curve_settings/curve_tree.py
index ac4469799..10c78b461 100644
--- a/bec_widgets/widgets/plots/waveform/settings/curve_settings/curve_tree.py
+++ b/bec_widgets/widgets/plots/waveform/settings/curve_settings/curve_tree.py
@@ -6,7 +6,6 @@
from bec_lib.logger import bec_logger
from bec_qthemes._icon.material_icons import material_icon
from qtpy.QtGui import QValidator
-from qtpy.QtWidgets import QApplication
class ScanIndexValidator(QValidator):
@@ -226,7 +225,7 @@ def _init_source_ui(self):
self.device_edit.currentTextChanged.connect(self.entry_edit.set_device)
self.device_edit.device_reset.connect(self.entry_edit.reset_selection)
if self.config.signal:
- device_index = self.device_edit.findText(self.config.signal.name or "")
+ device_index = self.device_edit.findText(self.config.signal.device or "")
if device_index >= 0:
self.device_edit.setCurrentIndex(device_index)
# Force the entry_edit to update based on the device name
@@ -235,7 +234,7 @@ def _init_source_ui(self):
# If the device name is not found, set the first enabled item
self.device_edit.setCurrentIndex(0)
- if not self.entry_edit.set_to_obj_name(self.config.signal.entry):
+ if not self.entry_edit.set_to_obj_name(self.config.signal.signal):
# If the entry is not found, try to set it to the first enabled item
if not self.entry_edit.set_to_first_enabled():
# If no enabled item is found, set to the first item
@@ -309,15 +308,15 @@ def add_dap_row(self):
dev_name = ""
dev_entry = ""
if self.config.signal:
- dev_name = self.config.signal.name
- dev_entry = self.config.signal.entry
+ dev_name = self.config.signal.device
+ dev_entry = self.config.signal.signal
# Create a new config for the DAP row
dap_cfg = CurveConfig(
widget_class="Curve",
source="dap",
parent_label=parent_label,
- signal=DeviceSignal(name=dev_name, entry=dev_entry),
+ signal=DeviceSignal(device=dev_name, signal=dev_entry),
)
new_dap = CurveRow(self.tree, parent_item=self, config=dap_cfg, device_manager=self.dev)
# Expand device row to show new child
@@ -395,10 +394,10 @@ def export_data(self) -> dict:
device_entry = device_entry_info.get("obj_name", device_entry)
else:
device_entry = self.entry_validator.validate_signal(
- name=device_name, entry=device_entry
+ device=device_name, signal=device_entry
)
- self.config.signal = DeviceSignal(name=device_name, entry=device_entry)
+ self.config.signal = DeviceSignal(device=device_name, signal=device_entry)
scan_combo_text = self.scan_index_combo.currentText()
if scan_combo_text == "live" or scan_combo_text == "":
self.config.scan_number = None
@@ -422,16 +421,16 @@ def export_data(self) -> dict:
if self.parent_item:
parent_conf_dict = self.parent_item.export_data()
parent_conf = CurveConfig(**parent_conf_dict)
- dev_name = ""
- dev_entry = ""
+ device = ""
+ signal = ""
if parent_conf.signal:
- dev_name = parent_conf.signal.name
- dev_entry = parent_conf.signal.entry
+ device = parent_conf.signal.device
+ signal = parent_conf.signal.signal
# Dap from the DapComboBox
new_dap = "GaussianModel"
if hasattr(self, "dap_combo"):
new_dap = self.dap_combo.fit_model_combobox.currentText()
- self.config.signal = DeviceSignal(name=dev_name, entry=dev_entry, dap=new_dap)
+ self.config.signal = DeviceSignal(device=device, signal=signal, dap=new_dap)
self.config.source = "dap"
self.config.parent_label = parent_conf.label
self.config.label = f"{parent_conf.label}-{new_dap}"
@@ -613,15 +612,12 @@ def renormalize_colors(self):
item.config.color = new_col
item.config.symbol_color = new_col
- def add_new_curve(self, name: str = None, entry: str = None):
+ def add_new_curve(self, device: str = None, signal: str = None):
"""Add a new device-type CurveRow with an assigned colormap color.
Args:
- name (str, optional): Device name.
- entry (str, optional): Device entry.
- style (str, optional): Pen style. Defaults to "solid".
- width (int, optional): Pen width. Defaults to 4.
- symbol_size (int, optional): Symbol size. Defaults to 7.
+ device (str, optional): Device name.
+ signal (str, optional): Device entry.
Returns:
CurveRow: The newly created top-level row.
@@ -630,7 +626,7 @@ def add_new_curve(self, name: str = None, entry: str = None):
widget_class="Curve",
parent_id=self.waveform.gui_id,
source="device",
- signal=DeviceSignal(name=name or "", entry=entry or ""),
+ signal=DeviceSignal(device=device or "", signal=signal or ""),
)
new_row = CurveRow(self.tree, parent_item=None, config=cfg, device_manager=self.dev)
diff --git a/bec_widgets/widgets/plots/waveform/waveform.py b/bec_widgets/widgets/plots/waveform/waveform.py
index 51223ebd7..603a0952b 100644
--- a/bec_widgets/widgets/plots/waveform/waveform.py
+++ b/bec_widgets/widgets/plots/waveform/waveform.py
@@ -73,8 +73,8 @@ class Waveform(PlotBase):
"curves",
"x_mode",
"x_mode.setter",
- "x_entry",
- "x_entry.setter",
+ "signal_x",
+ "signal_x.setter",
"color_palette",
"color_palette.setter",
"skip_large_dataset_warning",
@@ -409,7 +409,7 @@ def show_scan_history_popup(self):
self.scan_history_dialog.layout.addWidget(self.scan_history_widget)
self.scan_history_widget.scan_history_device_viewer.request_history_plot.connect(
lambda scan_id, device_name, signal_name: self.plot(
- y_name=device_name, y_entry=signal_name, scan_id=scan_id
+ device_y=device_name, signal_y=signal_name, scan_id=scan_id
)
)
self.scan_history_dialog.finished.connect(self._scan_history_closed)
@@ -534,14 +534,14 @@ def x_mode(self, value: str):
self.round_plot_widget.apply_plot_widget_style() # To keep the correct theme
@SafeProperty(str)
- def x_entry(self) -> str | None:
+ def signal_x(self) -> str | None:
"""
The x signal name.
"""
return self.x_axis_mode["entry"]
- @x_entry.setter
- def x_entry(self, value: str | None):
+ @signal_x.setter
+ def signal_x(self, value: str | None):
"""
Set the x signal name.
@@ -551,7 +551,7 @@ def x_entry(self, value: str | None):
if value is None:
return
if self.x_axis_mode["name"] in ["auto", "index", "timestamp"]:
- logger.warning("Cannot set x_entry when x_mode is not 'device'.")
+ logger.warning("Cannot set signal_x when x_mode is not 'device'.")
return
self.x_axis_mode["entry"] = self.entry_validator.validate_signal(self.x_mode, value)
self._switch_x_axis_item(mode="device")
@@ -690,10 +690,10 @@ def plot(
arg1: list | np.ndarray | str | None = None,
y: list | np.ndarray | None = None,
x: list | np.ndarray | None = None,
- x_name: str | None = None,
- y_name: str | None = None,
- x_entry: str | None = None,
- y_entry: str | None = None,
+ device_x: str | None = None,
+ device_y: str | None = None,
+ signal_x: str | None = None,
+ signal_y: str | None = None,
color: str | None = None,
label: str | None = None,
dap: str | None = None,
@@ -705,17 +705,17 @@ def plot(
Plot a curve to the plot widget.
Args:
- arg1(list | np.ndarray | str | None): First argument, which can be x data, y data, or y_name.
+ arg1(list | np.ndarray | str | None): First argument, which can be x data, y data, or device_y.
y(list | np.ndarray): Custom y data to plot.
x(list | np.ndarray): Custom y data to plot.
- x_name(str): Name of the x signal.
+ device_x(str): Name of the x signal.
- "auto": Use the best effort signal.
- "timestamp": Use the timestamp signal.
- "index": Use the index signal.
- Custom signal name of a device from BEC.
- y_name(str): The name of the device for the y-axis.
- x_entry(str): The name of the entry for the x-axis.
- y_entry(str): The name of the entry for the y-axis.
+ device_y(str): The name of the device for the y-axis.
+ signal_x(str): The name of the entry for the x-axis.
+ signal_y(str): The name of the entry for the y-axis.
color(str): The color of the curve.
label(str): The label of the curve.
dap(str): The dap model to use for the curve. When provided, a DAP curve is
@@ -741,7 +741,7 @@ def plot(
y_data = np.asarray(y)
if isinstance(arg1, str):
- y_name = arg1
+ device_y = arg1
elif isinstance(arg1, list):
if isinstance(y, list):
source = "custom"
@@ -762,17 +762,17 @@ def plot(
x_data = arg1[:, 0]
y_data = arg1[:, 1]
- # If y_name is set => device data
- if y_name is not None and x_data is None and y_data is None:
+ # If device_y is set => device data
+ if device_y is not None and x_data is None and y_data is None:
source = "device"
# Validate or obtain entry
- y_entry = self.entry_validator.validate_signal(name=y_name, entry=y_entry)
+ signal_y = self.entry_validator.validate_signal(device_y, signal_y)
- # If user gave x_name => store in x_axis_mode, but do not set data here
- if x_name is not None:
- self.x_mode = x_name
- if x_name not in ["timestamp", "index", "auto"]:
- self.x_axis_mode["entry"] = self.entry_validator.validate_signal(x_name, x_entry)
+ # If user gave device_x => store in x_axis_mode, but do not set data here
+ if device_x is not None:
+ self.x_mode = device_x
+ if device_x not in ["timestamp", "index", "auto"]:
+ self.x_axis_mode["entry"] = self.entry_validator.validate_signal(device_x, signal_x)
# Decide label if not provided
if label is None:
@@ -781,7 +781,7 @@ def plot(
"Curve", [c.object_name for c in self.curves]
)
else:
- label = f"{y_name}-{y_entry}"
+ label = f"{device_y}-{signal_y}"
# If color not provided, generate from palette
if color is None:
@@ -801,7 +801,7 @@ def plot(
# If it's device-based, attach DeviceSignal
if source == "device":
- config.signal = DeviceSignal(name=y_name, entry=y_entry)
+ config.signal = DeviceSignal(device=device_y, signal=signal_y)
if scan_id is not None or scan_number is not None:
config.source = "history"
@@ -851,8 +851,8 @@ def add_dap_curve(
f"Only device, history, or custom curves support fitting."
)
- dev_name = getattr(getattr(device_curve.config, "signal", None), "name", None)
- dev_entry = getattr(getattr(device_curve.config, "signal", None), "entry", None)
+ dev_name = getattr(getattr(device_curve.config, "signal", None), "device", None)
+ dev_entry = getattr(getattr(device_curve.config, "signal", None), "signal", None)
if dev_name is None:
dev_name = device_label
if dev_entry is None:
@@ -882,7 +882,7 @@ def add_dap_curve(
# Attach device signal with DAP
config.signal = DeviceSignal(
- name=dev_name, entry=dev_entry, dap=dap_name, dap_oversample=dap_oversample
+ device=dev_name, signal=dev_entry, dap=dap_name, dap_oversample=dap_oversample
)
# 4) Create the DAP curve config using `_add_curve(...)`
@@ -927,7 +927,7 @@ def _add_curve(
label = config.label
if config.source == "history":
- label = f"{config.signal.name}-{config.signal.entry}-scan-{config.scan_number}"
+ label = f"{config.signal.device}-{config.signal.signal}-scan-{config.scan_number}"
config.label = label
if not label:
# Fallback label
@@ -1003,8 +1003,8 @@ def _fetch_history_data_for_curve(
self, curve: Curve, scan_item: ScanDataContainer
) -> Curve | None:
# Check if the data are already set
- device = curve.config.signal.name
- entry = curve.config.signal.entry
+ device = curve.config.signal.device
+ entry = curve.config.signal.signal
all_devices_used = getattr(
getattr(scan_item, "_msg", None), "stored_data_info", None
@@ -1043,20 +1043,20 @@ def _fetch_history_data_for_curve(
)
curve.setVisible(False)
return
- x_entry_custom = self.x_axis_mode.get("entry")
- if x_entry_custom is None:
- x_entry_custom = self.entry_validator.validate_signal(
+ signal_x_custom = self.x_axis_mode.get("entry")
+ if signal_x_custom is None:
+ signal_x_custom = self.entry_validator.validate_signal(
self.x_axis_mode["name"], None
)
- if x_entry_custom not in all_devices_used[self.x_axis_mode["name"]]:
+ if signal_x_custom not in all_devices_used[self.x_axis_mode["name"]]:
logger.warning(
- f"Custom entry '{x_entry_custom}' for device '{self.x_axis_mode['name']}' not found in scan item of history curve '{curve.name()}'; scan ID: {curve.config.scan_id}."
+ f"Custom entry '{signal_x_custom}' for device '{self.x_axis_mode['name']}' not found in scan item of history curve '{curve.name()}'; scan ID: {curve.config.scan_id}."
)
curve.setVisible(False)
return
x_shape = (
scan_item._msg.stored_data_info.get(self.x_axis_mode["name"])
- .get(x_entry_custom)
+ .get(signal_x_custom)
.shape[0]
)
if x_shape != y_shape:
@@ -1066,9 +1066,9 @@ def _fetch_history_data_for_curve(
curve.setVisible(False)
return
x_device = scan_item.devices.get(self.x_axis_mode["name"])
- x_data = x_device.get(x_entry_custom).read().get("value")
+ x_data = x_device.get(signal_x_custom).read().get("value")
curve.config.current_x_mode = self.x_axis_mode["name"]
- self._update_x_label_suffix(f" (custom: {self.x_axis_mode['name']}-{x_entry_custom})")
+ self._update_x_label_suffix(f" (custom: {self.x_axis_mode['name']}-{signal_x_custom})")
elif self.x_axis_mode["name"] == "auto":
if (
self._current_x_device is None
@@ -1083,24 +1083,24 @@ def _fetch_history_data_for_curve(
curve.set_data(x=x_data, y=y_data)
self._update_x_label_suffix(" (auto: index)")
return curve
- x_entry = self.entry_validator.validate_signal(scan_motors[0], None)
- if x_entry not in all_devices_used.get(scan_motors[0], {}):
+ signal_x = self.entry_validator.validate_signal(scan_motors[0], None)
+ if signal_x not in all_devices_used.get(scan_motors[0], {}):
logger.warning(
- f"Auto x entry '{x_entry}' for device '{scan_motors[0]}' not found in scan item of history curve '{curve.name()}'; scan ID: {curve.config.scan_id}."
+ f"Auto x entry '{signal_x}' for device '{scan_motors[0]}' not found in scan item of history curve '{curve.name()}'; scan ID: {curve.config.scan_id}."
)
curve.setVisible(False)
return
- if y_shape != all_devices_used.get(scan_motors[0]).get(x_entry, {}).shape[0]:
+ if y_shape != all_devices_used.get(scan_motors[0]).get(signal_x, {}).shape[0]:
logger.warning(
- f"Shape mismatch for x data '{all_devices_used.get(scan_motors[0]).get(x_entry, {}).get('shape', [0])[0]}' and y data '{y_shape}' in history curve '{curve.name()}'; scan ID: {curve.config.scan_id}."
+ f"Shape mismatch for x data '{all_devices_used.get(scan_motors[0]).get(signal_x, {}).get('shape', [0])[0]}' and y data '{y_shape}' in history curve '{curve.name()}'; scan ID: {curve.config.scan_id}."
)
curve.setVisible(False)
return
- x_data = scan_item.devices.get(scan_motors[0]).get(x_entry).read().get("value")
- self._current_x_device = (scan_motors[0], x_entry)
- self._update_x_label_suffix(f" (auto: {scan_motors[0]}-{x_entry})")
+ x_data = scan_item.devices.get(scan_motors[0]).get(signal_x).read().get("value")
+ self._current_x_device = (scan_motors[0], signal_x)
+ self._update_x_label_suffix(f" (auto: {scan_motors[0]}-{signal_x})")
curve.config.current_x_mode = "auto"
- self._update_x_label_suffix(f" (auto: {scan_motors[0]}-{x_entry})")
+ self._update_x_label_suffix(f" (auto: {scan_motors[0]}-{signal_x})")
else: # Scan in auto mode was done and live scan already set the current x device
if self._current_x_device[0] not in all_devices_used:
logger.warning(
@@ -1446,8 +1446,8 @@ def update_sync_curves(self):
return
data, access_key = self._fetch_scan_data_and_access()
for curve in self._sync_curves:
- device_name = curve.config.signal.name
- device_entry = curve.config.signal.entry
+ device_name = curve.config.signal.device
+ device_entry = curve.config.signal.signal
if access_key == "val":
device_data = data.get(device_name, {}).get(device_entry, {}).get(access_key, None)
else:
@@ -1481,8 +1481,8 @@ def update_async_curves(self):
data, access_key = self._fetch_scan_data_and_access()
for curve in self._async_curves:
- device_name = curve.config.signal.name
- device_entry = curve.config.signal.entry
+ device_name = curve.config.signal.device
+ device_entry = curve.config.signal.signal
if access_key == "val": # live access
device_data = data.get(device_name, {}).get(device_entry, {}).get(access_key, None)
else: # history access
@@ -1535,8 +1535,8 @@ def _check_async_signal_found(self, name: str, signal: str) -> tuple[bool, str]:
bec_async_signals = self.client.device_manager.get_bec_signals(
["AsyncSignal", "AsyncMultiSignal"]
)
- for entry_name, _, entry_data in bec_async_signals:
- if entry_name == name and entry_data.get("obj_name") == signal:
+ for signal_name, _, entry_data in bec_async_signals:
+ if signal_name == name and entry_data.get("obj_name") == signal:
return True, entry_data.get("storage_name")
return False, signal
@@ -1547,8 +1547,8 @@ def _setup_async_curve(self, curve: Curve):
Args:
curve(Curve): The curve to set up.
"""
- name = curve.config.signal.name
- signal = curve.config.signal.entry
+ name = curve.config.signal.device
+ signal = curve.config.signal.signal
async_signal_found, signal = self._check_async_signal_found(name, signal)
try:
@@ -1621,7 +1621,7 @@ def on_async_readback(self, msg, metadata):
x_data = None # Reset x_data
y_data = None # Reset y_data
# Get the curve data
- async_data = msg["signals"].get(curve.config.signal.entry, None)
+ async_data = msg["signals"].get(curve.config.signal.signal, None)
if async_data is None:
continue
# y-data
@@ -1665,12 +1665,12 @@ def on_async_readback(self, msg, metadata):
# x_axis_mode is device signal
# Only consider device signals that are async for now, fallback is index
- x_device_entry = self.x_axis_mode["entry"]
- async_data = msg["signals"].get(x_device_entry, None)
+ signal_x = self.x_axis_mode["entry"]
+ async_data = msg["signals"].get(signal_x, None)
# Make sure the signal exists, otherwise fall back to index
if async_data is None:
# Try to grab the data from device signals
- data_plot_x = self._get_x_data(plot_mode, x_device_entry)
+ data_plot_x = self._get_x_data(plot_mode, signal_x)
else:
data_plot_x = np.asarray(async_data["value"])
if x_data is not None:
@@ -1678,7 +1678,7 @@ def on_async_readback(self, msg, metadata):
# Fallback incase data is not of equal length
if len(data_plot_x) != len(data_plot_y):
logger.warning(
- f"Async data for curve {curve.name()} and x_axis {x_device_entry} is not of equal length. Falling back to 'index' plotting."
+ f"Async data for curve {curve.name()} and x_axis {signal_x} is not of equal length. Falling back to 'index' plotting."
)
data_plot_x = np.linspace(0, len(data_plot_y) - 1, len(data_plot_y))
@@ -1858,18 +1858,18 @@ def _get_x_data(self, device_name: str, device_entry: str) -> list | np.ndarray
# 1 User wants custom signal
if self.x_axis_mode["name"] not in ["timestamp", "index", "auto"]:
- x_name = self.x_axis_mode["name"]
- x_entry = self.x_axis_mode.get("entry", None)
- if x_entry is None:
- x_entry = self.entry_validator.validate_signal(x_name, None)
+ device_x = self.x_axis_mode["name"]
+ signal_x = self.x_axis_mode.get("entry", None)
+ if signal_x is None:
+ signal_x = self.entry_validator.validate_signal(device_x, None)
# if the motor was not scanned, an empty list is returned and curves are not updated
if access_key == "val": # live data
- x_data = data.get(x_name, {}).get(x_entry, {}).get(access_key, [0])
+ x_data = data.get(device_x, {}).get(signal_x, {}).get(access_key, [0])
else: # history data
- entry_obj = data.get(x_name, {}).get(x_entry)
+ entry_obj = data.get(device_x, {}).get(signal_x)
x_data = entry_obj.read()["value"] if entry_obj else [0]
- new_suffix = f" (custom: {x_name}-{x_entry})"
- self._current_x_device = (x_name, x_entry)
+ new_suffix = f" (custom: {device_x}-{signal_x})"
+ self._current_x_device = (device_x, signal_x)
# 2 User wants timestamp
if self.x_axis_mode["name"] == "timestamp":
@@ -1913,15 +1913,15 @@ def _get_x_data(self, device_name: str, device_entry: str) -> list | np.ndarray
x_data = None
new_suffix = " (auto: index)"
else:
- x_name = scan_report_devices[0]
- x_entry = self.entry_validator.validate_signal(x_name, None)
+ device_x = scan_report_devices[0]
+ signal_x = self.entry_validator.validate_signal(device_x, None)
if access_key == "val":
- x_data = data.get(x_name, {}).get(x_entry, {}).get(access_key, None)
+ x_data = data.get(device_x, {}).get(signal_x, {}).get(access_key, None)
else:
- entry_obj = data.get(x_name, {}).get(x_entry)
+ entry_obj = data.get(device_x, {}).get(signal_x)
x_data = entry_obj.read()["value"] if entry_obj else None
- new_suffix = f" (auto: {x_name}-{x_entry})"
- self._current_x_device = (x_name, x_entry)
+ new_suffix = f" (auto: {device_x}-{signal_x})"
+ self._current_x_device = (device_x, signal_x)
self._update_x_label_suffix(new_suffix)
return x_data
@@ -1999,7 +1999,7 @@ def _categorise_device_curves(self) -> str:
for curve in self.curves:
if curve.config.source != "device":
continue
- dev_name = curve.config.signal.name
+ dev_name = curve.config.signal.device
if dev_name in readout_priority_async:
self._async_curves.append(curve)
if hasattr(self.scan_item, "live_data"):
@@ -2347,11 +2347,11 @@ def __init__(self):
self.setCentralWidget(self.main_widget)
self.waveform_popup = Waveform(popups=True)
- self.waveform_popup.plot(y_name="waveform")
+ self.waveform_popup.plot(device_y="waveform")
self.waveform_side = Waveform(popups=False)
- self.waveform_side.plot(y_name="bpm4i", y_entry="bpm4i", dap="GaussianModel")
- self.waveform_side.plot(y_name="bpm3a", y_entry="bpm3a")
+ self.waveform_side.plot(device_y="bpm4i", signal_y="bpm4i", dap="GaussianModel")
+ self.waveform_side.plot(device_y="bpm3a", signal_y="bpm3a")
self.custom_waveform = Waveform(popups=True)
self._populate_custom_curve_demo()
diff --git a/docs/user/customisation.md b/docs/user/customisation.md
index d724ba55f..15a2dfd58 100644
--- a/docs/user/customisation.md
+++ b/docs/user/customisation.md
@@ -55,7 +55,7 @@ bec_figure = BECFigure(gui_id="my_gui_app_id")
window.setCentralWidget(bec_figure)
# prepare to plot samx motor vs bpm4i value
-bec_figure.plot(x_name="samx", y_name="bpm4i")
+bec_figure.plot(device_x="samx", device_y="bpm4i")
```
In the example just above, the resulting application will show a plot of samx
@@ -96,7 +96,7 @@ window = QMainWindow()
bec_figure = BECFigure(parent=window, gui_id="my_gui_app_id")
window.setCentralWidget(bec_figure)
-bec_figure.plot(x_name="samx", y_name="bpm4i")
+bec_figure.plot(device_x="samx", device_y="bpm4i")
# ensuring proper cleanup
def final_cleanup():
diff --git a/docs/user/getting_started/quick_start.md b/docs/user/getting_started/quick_start.md
index f0bfa7460..c2263e4fd 100644
--- a/docs/user/getting_started/quick_start.md
+++ b/docs/user/getting_started/quick_start.md
@@ -45,7 +45,7 @@ For the introduction given here, we will focus on the plotting widgets of BECWid
```python
plt = gui.new().new().new(gui.available_widgets.Waveform)
-plt.plot(x_name='samx', y_name='bpm4i')
+plt.plot(device_x='samx', device_y='bpm4i')
```
Here, we create a new plot with a subscription to the devices `samx` and `bpm4i` and assign the plot to the object `plt`. We can now use this object to further customize the plot, e.g. changing the title (`title`), axis labels (`x_label`)
@@ -112,7 +112,7 @@ Let's assume BEC was just started and the `gui` object is available in the clien
```python
dock_area = gui.new()
plt = dock_area.new().new(gui.available_widgets.Waveform)
-plt.plot(x_name='samx', y_name='bpm4i')
+plt.plot(device_x='samx', device_y='bpm4i')
plt.curves[0].set_color(color="white")
plt.title = '1D Waveform'
```
diff --git a/docs/user/widgets/heatmap/heatmap_widget.md b/docs/user/widgets/heatmap/heatmap_widget.md
index 77d8a9949..d019f9951 100644
--- a/docs/user/widgets/heatmap/heatmap_widget.md
+++ b/docs/user/widgets/heatmap/heatmap_widget.md
@@ -47,9 +47,9 @@ heatmap_widget = dock_area.new().new(gui.available_widgets.Heatmap)
# Plot a heatmap with x and y motor positions and z detector signal
heatmap_widget.plot(
- x_name='samx', # X-axis motor
- y_name='samy', # Y-axis motor
- z_name='bpm4i', # Z-axis detector signal
+ device_x='samx', # X-axis motor
+ device_y='samy', # Y-axis motor
+ device_z='bpm4i', # Z-axis detector signal
color_map='plasma'
)
heatmap_widget.title = "Grid Scan - Sample Position vs BPM Intensity"
@@ -66,12 +66,12 @@ heatmap_widget = dock_area.new().new(gui.available_widgets.Heatmap)
# Plot heatmap with specific data entries
heatmap_widget.plot(
- x_name='motor1',
- y_name='motor2',
- z_name='detector1',
- x_entry='RBV', # Use readback value for x
- y_entry='RBV', # Use readback value for y
- z_entry='value', # Use main value for z
+ device_x='motor1',
+ device_y='motor2',
+ device_z='detector1',
+ signal_x='RBV', # Use readback value for x
+ signal_y='RBV', # Use readback value for y
+ signal_z='value', # Use main value for z
color_map='viridis',
reload=True # Force reload of data
)
diff --git a/docs/user/widgets/image/image_widget.md b/docs/user/widgets/image/image_widget.md
index cc02dbd6d..52e6a0ffe 100644
--- a/docs/user/widgets/image/image_widget.md
+++ b/docs/user/widgets/image/image_widget.md
@@ -32,7 +32,7 @@ dock_area = gui.new()
img_widget = dock_area.new().new(gui.available_widgets.Image)
# Add an ImageWidget to the BECFigure for a 2D detector
-img_widget.image(device_name='eiger', device_entry='preview')
+img_widget.image(device='eiger', signal='preview')
img_widget.title = "Camera Image - Eiger Detector"
```
@@ -46,7 +46,7 @@ dock_area = gui.new()
img_widget = dock_area.new().new(gui.available_widgets.Image)
# Add an ImageWidget to the BECFigure for a 2D detector
-img_widget.image(device_name='waveform', device_entry='data')
+img_widget.image(device='waveform', signal='data')
img_widget.title = "Line Detector Data"
# Optional: Set the color map and value range
@@ -84,7 +84,7 @@ The Image Widget can be configured for different detectors by specifying the cor
```python
# For a 2D camera detector
-img_widget = fig.image(device_name='eiger', device_entry='preview')
+img_widget = fig.image(device='eiger', signal='preview')
img_widget.set_title("Eiger Camera Image")
```
@@ -92,7 +92,7 @@ img_widget.set_title("Eiger Camera Image")
```python
# For a 1D line detector
-img_widget = fig.image(device_name='waveform', device_entry='data')
+img_widget = fig.image(device='waveform', signal='data')
img_widget.set_title("Line Detector Data")
```
diff --git a/docs/user/widgets/motor_map/motor_map.md b/docs/user/widgets/motor_map/motor_map.md
index 4b42e2466..09e51a7f1 100644
--- a/docs/user/widgets/motor_map/motor_map.md
+++ b/docs/user/widgets/motor_map/motor_map.md
@@ -29,8 +29,8 @@ mm1 = dock_area.new().new(gui.available_widgets.MotorMap)
mm2 = dock_area.new().new(gui.available_widgets.MotorMap)
# Add signals to the MotorMaps
-mm1.map(x_name='samx', y_name='samy')
-mm2.map(x_name='aptrx', y_name='aptry')
+mm1.map(device_x='samx', device_y='samy')
+mm2.map(device_x='aptrx', device_y='aptry')
```
## Example 2 - Customizing Motor Map Display
@@ -57,7 +57,7 @@ You can dynamically change the motors being tracked and reset the history of the
mm1.reset_history()
# Change the motors being tracked
-mm1.map(x_name='aptrx', y_name='aptry')
+mm1.map(device_x='aptrx', device_y='aptry')
```
````
diff --git a/docs/user/widgets/scatter_waveform/scatter_waveform.md b/docs/user/widgets/scatter_waveform/scatter_waveform.md
index 4c9ffce68..10426cdae 100644
--- a/docs/user/widgets/scatter_waveform/scatter_waveform.md
+++ b/docs/user/widgets/scatter_waveform/scatter_waveform.md
@@ -20,7 +20,7 @@ The 2D scatter plot widget is designed for more complex data visualization. It e
```python
# Add a new dock_area, a new dock and a BECWaveForm to the dock
plt = gui.new().new().new(gui.available_widgets.ScatterWaveform)
-plt.plot(x_name='samx', y_name='samy', z_name='bpm4i')
+plt.plot(device_x='samx', device_y='samy', device_z='bpm4i')
```
diff --git a/docs/user/widgets/waveform/waveform_widget.md b/docs/user/widgets/waveform/waveform_widget.md
index a896bccb0..c1d68e966 100644
--- a/docs/user/widgets/waveform/waveform_widget.md
+++ b/docs/user/widgets/waveform/waveform_widget.md
@@ -32,8 +32,8 @@ plt1 = dock_area.new().new('Waveform')
plt2 = gui.my_new_dock_area.new().new(gui.available_widgets.Waveform) # as an alternative example via dynamic name space
# Add signals to the WaveformWidget
-plt1.plot(x_name='samx', y_name='bpm4i')
-plt2.plot(x_name='samx', y_name='bpm3i')
+plt1.plot(device_x='samx', device_y='bpm4i')
+plt2.plot(device_x='samx', device_y='bpm3i')
# set axis labels
plt1.title = "Gauss plots vs. samx"
@@ -60,10 +60,10 @@ In addition to the scan curve, you can also add a second curve that fits the sig
```python
# Add a new dock_area, dock and Waveform and plot bpm4i vs samx with a GaussianModel DAP
plt = gui.new().new().new('Waveform')
-plt.plot(x_name='samx', y_name='bpm4i', dap="GaussianModel")
+plt.plot(device_x='samx', device_y='bpm4i', dap="GaussianModel")
# Add a second curve to the same plot without DAP
-plt.plot(x_name='samx', y_name='bpm3a')
+plt.plot(device_x='samx', device_y='bpm3a')
# Add DAP to the second curve
plt.add_dap_curve(device_label='bpm3a-bpm3a', dap_name='GaussianModel')
diff --git a/tests/end-2-end/test_bec_dock_rpc_e2e.py b/tests/end-2-end/test_bec_dock_rpc_e2e.py
index 55c45a8dd..300605b5c 100644
--- a/tests/end-2-end/test_bec_dock_rpc_e2e.py
+++ b/tests/end-2-end/test_bec_dock_rpc_e2e.py
@@ -58,8 +58,8 @@ def check_widgets_registered():
assert gui._ipython_registry[mm._gui_id].__class__ == MotorMap
mm.map("samx", "samy")
- curve = wf.plot(x_name="samx", y_name="bpm4i")
- im_item = im.image(device_name="eiger", device_entry="preview")
+ curve = wf.plot(device_x="samx", device_y="bpm4i")
+ im_item = im.image(device="eiger", signal="preview")
assert curve.__class__.__name__ == "RPCReference"
assert curve.__class__ == RPCReference
diff --git a/tests/end-2-end/test_plotting_framework_e2e.py b/tests/end-2-end/test_plotting_framework_e2e.py
index e98c9236c..a5a57a5cd 100644
--- a/tests/end-2-end/test_plotting_framework_e2e.py
+++ b/tests/end-2-end/test_plotting_framework_e2e.py
@@ -34,7 +34,7 @@ def test_rpc_plotting_shortcuts_init_configs(qtbot, connected_client_gui_obj):
sw = dock_area.new("ScatterWaveform")
mw = dock_area.new("MultiWaveform")
- c1 = wf.plot(x_name="samx", y_name="bpm4i")
+ c1 = wf.plot(device_x="samx", device_y="bpm4i")
# Adding custom curves, removing one and adding it again should not crash
c2 = wf.plot(y=[1, 2, 3], x=[1, 2, 3])
assert c2.object_name == "Curve_0"
@@ -42,9 +42,9 @@ def test_rpc_plotting_shortcuts_init_configs(qtbot, connected_client_gui_obj):
c3 = wf.plot(y=[1, 2, 3], x=[1, 2, 3])
assert c3.object_name == "Curve_0"
- im.image(device_name="eiger", device_entry="preview")
- mm.map(x_name="samx", y_name="samy")
- sw.plot(x_name="samx", y_name="samy", z_name="bpm4a")
+ im.image(device="eiger", signal="preview")
+ mm.map(device_x="samx", device_y="samy")
+ sw.plot(device_x="samx", device_y="samy", device_z="bpm4a")
mw.plot(monitor="waveform")
# Adding multiple custom curves sho
@@ -70,8 +70,8 @@ def test_rpc_plotting_shortcuts_init_configs(qtbot, connected_client_gui_obj):
# Curve
assert c1._config_dict["signal"] == {
"dap": None,
- "name": "bpm4i",
- "entry": "bpm4i",
+ "device": "bpm4i",
+ "signal": "bpm4i",
"dap_oversample": 1,
}
assert c1._config_dict["source"] == "device"
@@ -90,9 +90,9 @@ def test_rpc_waveform_scan(qtbot, bec_client_lib, connected_client_gui_obj):
wf = dock_area.new("Waveform")
# add 3 different curves to track
- wf.plot(x_name="samx", y_name="bpm4i")
- wf.plot(x_name="samx", y_name="bpm3a")
- wf.plot(x_name="samx", y_name="bpm4d")
+ wf.plot(device_x="samx", device_y="bpm4i")
+ wf.plot(device_x="samx", device_y="bpm3a")
+ wf.plot(device_x="samx", device_y="bpm4d")
status = scans.line_scan(dev.samx, -5, 5, steps=10, exp_time=0.05, relative=False)
status.wait()
@@ -133,7 +133,7 @@ def test_async_plotting(qtbot, bec_client_lib, connected_client_gui_obj):
dev.waveform.async_update.set("add").wait()
dev.waveform.waveform_shape.set(10000).wait()
wf = dock_area.new("Waveform")
- curve = wf.plot(y_name="waveform")
+ curve = wf.plot(device_y="waveform")
status = scans.line_scan(dev.samx, -5, 5, steps=5, exp_time=0.05, relative=False)
status.wait()
@@ -165,7 +165,7 @@ def test_rpc_image(qtbot, bec_client_lib, connected_client_gui_obj):
scans = client.scans
im = dock_area.new("Image")
- im.image(device_name="eiger", device_entry="preview")
+ im.image(device="eiger", signal="preview")
status = scans.line_scan(dev.samx, -5, 5, steps=10, exp_time=0.05, relative=False)
status.wait()
@@ -188,7 +188,7 @@ def test_rpc_motor_map(qtbot, bec_client_lib, connected_client_gui_obj):
dock_area = gui.bec
motor_map = dock_area.new("MotorMap")
- motor_map.map(x_name="samx", y_name="samy")
+ motor_map.map(device_x="samx", device_y="samy")
initial_pos_x = dev.samx.read()["samx"]["value"]
initial_pos_y = dev.samy.read()["samy"]["value"]
@@ -219,7 +219,7 @@ def test_dap_rpc(qtbot, bec_client_lib, connected_client_gui_obj):
dock_area = gui.bec
wf = dock_area.new("Waveform")
- wf.plot(x_name="samx", y_name="bpm4i", dap="GaussianModel")
+ wf.plot(device_x="samx", device_y="bpm4i", dap="GaussianModel")
dev.bpm4i.sim.select_model("GaussianModel")
params = dev.bpm4i.sim.params
@@ -262,7 +262,7 @@ def test_waveform_passing_device(qtbot, bec_client_lib, connected_client_gui_obj
wf = dock_area.new("Waveform")
c1 = wf.plot(
- y_name=dev.samx, y_entry=dev.samx.setpoint
+ device_y=dev.samx, signal_y=dev.samx.setpoint
) # using setpoint to not use readback signal
assert c1.object_name == "samx_samx_setpoint"
@@ -342,7 +342,7 @@ def _wait_for_scan_in_history():
# Add curve from history using the chosen selector; single curve per scan to avoid duplicates
kwargs = {history_selector: sel_value}
- curve = wf.plot(x_name="samx", y_name="bpm4i", **kwargs)
+ curve = wf.plot(device_x="samx", device_y="bpm4i", **kwargs)
num_elements = 10
diff --git a/tests/end-2-end/test_rpc_register_e2e.py b/tests/end-2-end/test_rpc_register_e2e.py
index 3e1bfca3d..aeb42a025 100644
--- a/tests/end-2-end/test_rpc_register_e2e.py
+++ b/tests/end-2-end/test_rpc_register_e2e.py
@@ -12,19 +12,19 @@ def test_rpc_reference_objects(connected_client_gui_obj):
dock_area = gui.window_list[0]
plt = dock_area.new("Waveform", object_name="fig")
- plt.plot(x_name="samx", y_name="bpm4i")
+ plt.plot(device_x="samx", device_y="bpm4i")
im = dock_area.new("Image")
- im.image(device_name="eiger", device_entry="preview")
+ im.image(device="eiger", signal="preview")
motor_map = dock_area.new("MotorMap")
motor_map.map("samx", "samy")
plt_z = dock_area.new("Waveform")
- plt_z.plot(x_name="samx", y_name="samy", z_name="bpm4i")
+ plt_z.plot(device_x="samx", device_y="samy", device_z="bpm4i")
assert len(plt_z.curves) == 1
assert len(plt.curves) == 1
- assert im.device_name == "eiger"
- assert im.device_entry == "preview"
+ assert im.device == "eiger"
+ assert im.signal == "preview"
assert isinstance(im.main_image, RPCReference)
image_item = gui._ipython_registry.get(im.main_image._gui_id, None)
diff --git a/tests/end-2-end/user_interaction/test_user_interaction_e2e.py b/tests/end-2-end/user_interaction/test_user_interaction_e2e.py
index cb5d85b57..e4b0b480f 100644
--- a/tests/end-2-end/user_interaction/test_user_interaction_e2e.py
+++ b/tests/end-2-end/user_interaction/test_user_interaction_e2e.py
@@ -234,7 +234,7 @@ def test_widgets_e2e_image(qtbot, connected_client_gui_obj, random_generator_fro
scans = bec.scans
dev = bec.device_manager.devices
# Test rpc calls
- img = widget.image(device_name=dev.eiger.name, device_entry="preview")
+ img = widget.image(device=dev.eiger.name, signal="preview")
assert img.get_data() is None
# Run a scan and plot the image
s = scans.line_scan(dev.samx, -3, 3, steps=50, exp_time=0.01, relative=False)
@@ -254,7 +254,7 @@ def _wait_for_scan_in_history():
assert np.allclose(img.get_data(), last_img)
# Now add a device with a preview signal
- img = widget.image(device_name="eiger", device_entry="preview")
+ img = widget.image(device="eiger", signal="preview")
s = scans.line_scan(dev.samx, -3, 3, steps=50, exp_time=0.01, relative=False)
s.wait()
diff --git a/tests/unit_tests/test_curve_settings.py b/tests/unit_tests/test_curve_settings.py
index 7c630bd28..faaaa89cf 100644
--- a/tests/unit_tests/test_curve_settings.py
+++ b/tests/unit_tests/test_curve_settings.py
@@ -179,15 +179,15 @@ def test_add_new_curve(curve_tree_fixture):
assert curve_tree.tree.topLevelItemCount() == 0
with patch.object(curve_tree, "_ensure_color_buffer_size") as ensure_spy:
- new_item = curve_tree.add_new_curve(name="bpm4i", entry="bpm4i")
+ new_item = curve_tree.add_new_curve(device="bpm4i", signal="bpm4i")
ensure_spy.assert_called_once()
assert curve_tree.tree.topLevelItemCount() == 1
last_item = curve_tree.all_items[-1]
assert last_item is new_item
assert new_item.config.source == "device"
- assert new_item.config.signal.name == "bpm4i"
- assert new_item.config.signal.entry == "bpm4i"
+ assert new_item.config.signal.device == "bpm4i"
+ assert new_item.config.signal.signal == "bpm4i"
assert new_item.config.color in curve_tree.color_buffer
@@ -197,8 +197,8 @@ def test_renormalize_colors(curve_tree_fixture):
"""
curve_tree, wf = curve_tree_fixture
# Add multiple curves
- c1 = curve_tree.add_new_curve(name="bpm4i", entry="bpm4i")
- c2 = curve_tree.add_new_curve(name="bpm3a", entry="bpm3a")
+ c1 = curve_tree.add_new_curve(device="bpm4i", signal="bpm4i")
+ c2 = curve_tree.add_new_curve(device="bpm3a", signal="bpm3a")
curve_tree.color_buffer = []
set_color_spy_c1 = patch.object(c1.color_button, "set_color")
@@ -215,7 +215,7 @@ def test_expand_collapse(curve_tree_fixture):
Test expand_all_daps() and collapse_all_daps() calls expand/collapse on every top-level item.
"""
curve_tree, wf = curve_tree_fixture
- c1 = curve_tree.add_new_curve(name="bpm4i", entry="bpm4i")
+ c1 = curve_tree.add_new_curve(device="bpm4i", signal="bpm4i")
curve_tree.tree.expandAll()
expand_spy = patch.object(curve_tree.tree, "expandItem")
collapse_spy = patch.object(curve_tree.tree, "collapseItem")
@@ -236,8 +236,8 @@ def test_send_curve_json(curve_tree_fixture, monkeypatch):
"""
curve_tree, wf = curve_tree_fixture
# Add multiple curves
- curve_tree.add_new_curve(name="bpm4i", entry="bpm4i")
- curve_tree.add_new_curve(name="bpm3a", entry="bpm3a")
+ curve_tree.add_new_curve(device="bpm4i", signal="bpm4i")
+ curve_tree.add_new_curve(device="bpm3a", signal="bpm3a")
curve_tree.color_palette = "viridis"
curve_tree.send_curve_json()
@@ -282,7 +282,7 @@ def test_add_dap_row(curve_tree_fixture):
curve_tree, wf = curve_tree_fixture
# Add a device curve first
- device_row = curve_tree.add_new_curve(name="bpm4i", entry="bpm4i")
+ device_row = curve_tree.add_new_curve(device="bpm4i", signal="bpm4i")
assert device_row.source == "device"
assert curve_tree.tree.topLevelItemCount() == 1
assert device_row.childCount() == 0
@@ -299,8 +299,8 @@ def test_add_dap_row(curve_tree_fixture):
assert dap_child.config.parent_label == device_row.config.label
# Check that the DAP inherits device name/entry from parent
- assert dap_child.config.signal.name == "bpm4i"
- assert dap_child.config.signal.entry == "bpm4i"
+ assert dap_child.config.signal.device == "bpm4i"
+ assert dap_child.config.signal.signal == "bpm4i"
# Check that the item is in the curve_tree's all_items list
assert dap_child in curve_tree.all_items
@@ -313,8 +313,8 @@ def test_remove_self_top_level(curve_tree_fixture):
curve_tree, wf = curve_tree_fixture
# Add two device curves
- row1 = curve_tree.add_new_curve(name="bpm4i", entry="bpm4i")
- row2 = curve_tree.add_new_curve(name="bpm3a", entry="bpm3a")
+ row1 = curve_tree.add_new_curve(device="bpm4i", signal="bpm4i")
+ row2 = curve_tree.add_new_curve(device="bpm3a", signal="bpm3a")
assert curve_tree.tree.topLevelItemCount() == 2
assert len(curve_tree.all_items) == 2
@@ -335,7 +335,7 @@ def test_remove_self_child(curve_tree_fixture):
curve_tree, wf = curve_tree_fixture
# Add a device curve and a DAP child
- device_row = curve_tree.add_new_curve(name="bpm4i", entry="bpm4i")
+ device_row = curve_tree.add_new_curve(device="bpm4i", signal="bpm4i")
device_row.add_dap_row()
dap_child = device_row.child(0)
@@ -360,7 +360,7 @@ def test_export_data_dap(curve_tree_fixture):
curve_tree, wf = curve_tree_fixture
# Add a device curve with specific parameters
- device_row = curve_tree.add_new_curve(name="bpm4i", entry="bpm4i")
+ device_row = curve_tree.add_new_curve(device="bpm4i", signal="bpm4i")
# Add a DAP child
device_row.add_dap_row()
@@ -375,8 +375,8 @@ def test_export_data_dap(curve_tree_fixture):
# Check the exported data
assert exported["source"] == "dap"
assert exported["parent_label"] == "bpm4i-bpm4i"
- assert exported["signal"]["name"] == "bpm4i"
- assert exported["signal"]["entry"] == "bpm4i"
+ assert exported["signal"]["device"] == "bpm4i"
+ assert exported["signal"]["signal"] == "bpm4i"
assert exported["signal"]["dap"] == "GaussianModel"
assert exported["label"] == "bpm4i-bpm4i-GaussianModel"
@@ -422,7 +422,7 @@ def test_export_data_history_curve(curve_tree_fixture, scan_history_factory):
wf.client.queue.scan_storage.current_scan = None
# Create a device row and select scan index "2"
- device_row = curve_tree.add_new_curve(name="bpm4i", entry="bpm4i")
+ device_row = curve_tree.add_new_curve(device="bpm4i", signal="bpm4i")
device_row.scan_index_combo.setCurrentText("2")
exported = device_row.export_data()
diff --git a/tests/unit_tests/test_heatmap_widget.py b/tests/unit_tests/test_heatmap_widget.py
index fe8e0ee87..ef5f09efe 100644
--- a/tests/unit_tests/test_heatmap_widget.py
+++ b/tests/unit_tests/test_heatmap_widget.py
@@ -30,11 +30,11 @@ def heatmap_widget(qtbot, mocked_client):
def test_heatmap_plot(heatmap_widget):
- heatmap_widget.plot(x_name="samx", y_name="samy", z_name="bpm4i")
+ heatmap_widget.plot(device_x="samx", device_y="samy", device_z="bpm4i")
- assert heatmap_widget._image_config.x_device.name == "samx"
- assert heatmap_widget._image_config.y_device.name == "samy"
- assert heatmap_widget._image_config.z_device.name == "bpm4i"
+ assert heatmap_widget._image_config.device_x.device == "samx"
+ assert heatmap_widget._image_config.device_y.device == "samy"
+ assert heatmap_widget._image_config.device_z.device == "bpm4i"
def test_heatmap_on_scan_status_no_scan_id(heatmap_widget):
@@ -78,7 +78,7 @@ def test_heatmap_get_image_data_grid_scan(heatmap_widget):
info={},
request_inputs={"arg_bundle": ["samx", -5, 5, 10, "samy", -5, 5, 10], "kwargs": {}},
)
- heatmap_widget.plot(x_name="samx", y_name="samy", z_name="bpm4i")
+ heatmap_widget.plot(device_x="samx", device_y="samy", device_z="bpm4i")
heatmap_widget.status_message = scan_msg
with mock.patch.object(heatmap_widget, "get_grid_scan_image") as mock_get_grid_scan_image:
@@ -147,9 +147,9 @@ def test_heatmap_get_grid_scan_image(heatmap_widget):
)
heatmap_widget._image_config = HeatmapConfig(
parent_id="parent_id",
- x_device=HeatmapDeviceSignal(name="samx", entry="samx"),
- y_device=HeatmapDeviceSignal(name="samy", entry="samy"),
- z_device=HeatmapDeviceSignal(name="bpm4i", entry="bpm4i"),
+ device_x=HeatmapDeviceSignal(device="samx", signal="samx"),
+ device_y=HeatmapDeviceSignal(device="samy", signal="samy"),
+ device_z=HeatmapDeviceSignal(device="bpm4i", signal="bpm4i"),
color_map="viridis",
)
img, _ = heatmap_widget.get_grid_scan_image(list(range(100)), msg=scan_msg)
@@ -174,9 +174,9 @@ def _grid_positions(
def test_heatmap_grid_scan_direction_and_snaking_x_fast(heatmap_widget):
heatmap_widget._image_config = HeatmapConfig(
parent_id="parent_id",
- x_device=HeatmapDeviceSignal(name="samx", entry="samx"),
- y_device=HeatmapDeviceSignal(name="samy", entry="samy"),
- z_device=HeatmapDeviceSignal(name="bpm4i", entry="bpm4i"),
+ device_x=HeatmapDeviceSignal(device="samx", signal="samx"),
+ device_y=HeatmapDeviceSignal(device="samy", signal="samy"),
+ device_z=HeatmapDeviceSignal(device="bpm4i", signal="bpm4i"),
color_map="viridis",
)
@@ -219,9 +219,9 @@ def test_heatmap_grid_scan_direction_and_snaking_x_fast(heatmap_widget):
def test_heatmap_grid_scan_direction_and_snaking_y_fast(heatmap_widget):
heatmap_widget._image_config = HeatmapConfig(
parent_id="parent_id",
- x_device=HeatmapDeviceSignal(name="samx", entry="samx"),
- y_device=HeatmapDeviceSignal(name="samy", entry="samy"),
- z_device=HeatmapDeviceSignal(name="bpm4i", entry="bpm4i"),
+ device_x=HeatmapDeviceSignal(device="samx", signal="samx"),
+ device_y=HeatmapDeviceSignal(device="samy", signal="samy"),
+ device_z=HeatmapDeviceSignal(device="bpm4i", signal="bpm4i"),
color_map="viridis",
)
@@ -277,13 +277,13 @@ def test_heatmap_get_step_scan_image(heatmap_widget):
heatmap_widget.scan_item.status_message = scan_msg
heatmap_widget._image_config = HeatmapConfig(
parent_id="parent_id",
- x_device=HeatmapDeviceSignal(name="samx", entry="samx"),
- y_device=HeatmapDeviceSignal(name="samy", entry="samy"),
- z_device=HeatmapDeviceSignal(name="bpm4i", entry="bpm4i"),
+ device_x=HeatmapDeviceSignal(device="samx", signal="samx"),
+ device_y=HeatmapDeviceSignal(device="samy", signal="samy"),
+ device_z=HeatmapDeviceSignal(device="bpm4i", signal="bpm4i"),
color_map="viridis",
)
img, _ = heatmap_widget.get_step_scan_image(
- list(np.random.rand(100)), list(np.random.rand(100)), list(range(100)), msg=scan_msg
+ list(np.random.rand(100)), list(np.random.rand(100)), list(range(100))
)
assert img.shape > (10, 10)
@@ -291,9 +291,9 @@ def test_heatmap_get_step_scan_image(heatmap_widget):
def test_heatmap_update_plot_no_scan_item(heatmap_widget):
heatmap_widget._image_config = HeatmapConfig(
parent_id="parent_id",
- x_device=HeatmapDeviceSignal(name="samx", entry="samx"),
- y_device=HeatmapDeviceSignal(name="samy", entry="samy"),
- z_device=HeatmapDeviceSignal(name="bpm4i", entry="bpm4i"),
+ device_x=HeatmapDeviceSignal(device="samx", signal="samx"),
+ device_y=HeatmapDeviceSignal(device="samy", signal="samy"),
+ device_z=HeatmapDeviceSignal(device="bpm4i", signal="bpm4i"),
color_map="viridis",
)
with mock.patch.object(heatmap_widget.main_image, "setImage") as mock_set_image:
@@ -304,9 +304,9 @@ def test_heatmap_update_plot_no_scan_item(heatmap_widget):
def test_heatmap_update_plot(heatmap_widget):
heatmap_widget._image_config = HeatmapConfig(
parent_id="parent_id",
- x_device=HeatmapDeviceSignal(name="samx", entry="samx"),
- y_device=HeatmapDeviceSignal(name="samy", entry="samy"),
- z_device=HeatmapDeviceSignal(name="bpm4i", entry="bpm4i"),
+ device_x=HeatmapDeviceSignal(device="samx", signal="samx"),
+ device_y=HeatmapDeviceSignal(device="samy", signal="samy"),
+ device_z=HeatmapDeviceSignal(device="bpm4i", signal="bpm4i"),
color_map="viridis",
)
heatmap_widget.scan_item = create_dummy_scan_item()
@@ -331,9 +331,9 @@ def test_heatmap_update_plot(heatmap_widget):
def test_heatmap_update_plot_without_status_message(heatmap_widget):
heatmap_widget._image_config = HeatmapConfig(
parent_id="parent_id",
- x_device=HeatmapDeviceSignal(name="samx", entry="samx"),
- y_device=HeatmapDeviceSignal(name="samy", entry="samy"),
- z_device=HeatmapDeviceSignal(name="bpm4i", entry="bpm4i"),
+ device_x=HeatmapDeviceSignal(device="samx", signal="samx"),
+ device_y=HeatmapDeviceSignal(device="samy", signal="samy"),
+ device_z=HeatmapDeviceSignal(device="bpm4i", signal="bpm4i"),
color_map="viridis",
)
heatmap_widget.scan_item = create_dummy_scan_item()
@@ -346,9 +346,9 @@ def test_heatmap_update_plot_without_status_message(heatmap_widget):
def test_heatmap_update_plot_no_img_data(heatmap_widget):
heatmap_widget._image_config = HeatmapConfig(
parent_id="parent_id",
- x_device=HeatmapDeviceSignal(name="samx", entry="samx"),
- y_device=HeatmapDeviceSignal(name="samy", entry="samy"),
- z_device=HeatmapDeviceSignal(name="bpm4i", entry="bpm4i"),
+ device_x=HeatmapDeviceSignal(device="samx", signal="samx"),
+ device_y=HeatmapDeviceSignal(device="samy", signal="samy"),
+ device_z=HeatmapDeviceSignal(device="bpm4i", signal="bpm4i"),
color_map="viridis",
)
heatmap_widget.scan_item = create_dummy_scan_item()
@@ -407,7 +407,7 @@ def test_heatmap_settings_popup_accept_changes(heatmap_widget, qtbot):
"""
Test that changes made in the settings dialog are applied correctly.
"""
- heatmap_widget.plot(x_name="samx", y_name="samy", z_name="bpm4i")
+ heatmap_widget.plot(device_x="samx", device_y="samy", device_z="bpm4i")
assert heatmap_widget.color_map == "plasma" # Default colormap
heatmap_widget.show_heatmap_settings()
qtbot.waitUntil(lambda: heatmap_widget.heatmap_dialog is not None)
@@ -431,7 +431,7 @@ def test_heatmap_settings_popup_show_settings(heatmap_widget, qtbot):
"""
Test that the settings dialog opens and contains the expected elements.
"""
- heatmap_widget.plot(x_name="samx", y_name="samy", z_name="bpm4i")
+ heatmap_widget.plot(device_x="samx", device_y="samy", device_z="bpm4i")
heatmap_widget.show_heatmap_settings()
qtbot.waitUntil(lambda: heatmap_widget.heatmap_dialog is not None)
@@ -439,13 +439,13 @@ def test_heatmap_settings_popup_show_settings(heatmap_widget, qtbot):
assert dialog.isVisible()
assert dialog.widget is not None
assert hasattr(dialog.widget.ui, "color_map")
- assert hasattr(dialog.widget.ui, "x_name")
- assert hasattr(dialog.widget.ui, "y_name")
- assert hasattr(dialog.widget.ui, "z_name")
+ assert hasattr(dialog.widget.ui, "device_x")
+ assert hasattr(dialog.widget.ui, "device_y")
+ assert hasattr(dialog.widget.ui, "device_z")
# Check that the ui elements are correctly initialized
assert dialog.widget.ui.color_map.colormap == heatmap_widget.color_map
- assert dialog.widget.ui.x_name.currentText() == heatmap_widget._image_config.x_device.name
+ assert dialog.widget.ui.device_x.currentText() == heatmap_widget._image_config.device_x.device
dialog.reject()
qtbot.waitUntil(lambda: heatmap_widget.heatmap_dialog is None)
@@ -458,7 +458,7 @@ def test_heatmap_widget_reset(heatmap_widget):
heatmap_widget._pending_interpolation_request = object()
heatmap_widget._latest_interpolation_version = 5
heatmap_widget.scan_item = create_dummy_scan_item()
- heatmap_widget.plot(x_name="samx", y_name="samy", z_name="bpm4i")
+ heatmap_widget.plot(device_x="samx", device_y="samy", device_z="bpm4i")
heatmap_widget.reset()
assert heatmap_widget._grid_index is None
@@ -476,12 +476,12 @@ def test_heatmap_widget_update_plot_with_scan_history(heatmap_widget, grid_scan_
heatmap_widget.client.history._scan_ids.append(grid_scan_history_msg.scan_id)
heatmap_widget.client.queue.scan_storage.current_scan = None
heatmap_widget.plot(
- x_name="samx",
- y_name="samy",
- z_name="bpm4i",
- x_entry="samx",
- y_entry="samy",
- z_entry="bpm4i",
+ device_x="samx",
+ device_y="samy",
+ device_z="bpm4i",
+ signal_x="samx",
+ signal_y="samy",
+ signal_z="bpm4i",
)
qtbot.waitUntil(lambda: heatmap_widget.main_image.raw_data is not None)
qtbot.waitUntil(lambda: heatmap_widget.main_image.raw_data.shape == (10, 10))
@@ -602,219 +602,219 @@ def test_finish_interpolation_thread_cleans_references(heatmap_widget):
def test_device_safe_properties_get(heatmap_widget):
"""Test that device SafeProperty getters work correctly."""
# Initially devices should be empty
- assert heatmap_widget.x_device_name == ""
- assert heatmap_widget.x_device_entry == ""
- assert heatmap_widget.y_device_name == ""
- assert heatmap_widget.y_device_entry == ""
- assert heatmap_widget.z_device_name == ""
- assert heatmap_widget.z_device_entry == ""
+ assert heatmap_widget.device_x == ""
+ assert heatmap_widget.signal_x == ""
+ assert heatmap_widget.device_y == ""
+ assert heatmap_widget.signal_y == ""
+ assert heatmap_widget.device_z == ""
+ assert heatmap_widget.signal_z == ""
# Set devices via plot
- heatmap_widget.plot(x_name="samx", y_name="samy", z_name="bpm4i")
+ heatmap_widget.plot(device_x="samx", device_y="samy", device_z="bpm4i")
# Check properties return device names and entries separately
- assert heatmap_widget.x_device_name == "samx"
- assert heatmap_widget.x_device_entry # Should have some entry
- assert heatmap_widget.y_device_name == "samy"
- assert heatmap_widget.y_device_entry # Should have some entry
- assert heatmap_widget.z_device_name == "bpm4i"
- assert heatmap_widget.z_device_entry # Should have some entry
+ assert heatmap_widget.device_x == "samx"
+ assert heatmap_widget.signal_x # Should have some entry
+ assert heatmap_widget.device_y == "samy"
+ assert heatmap_widget.signal_y # Should have some entry
+ assert heatmap_widget.device_z == "bpm4i"
+ assert heatmap_widget.signal_z # Should have some entry
def test_device_safe_properties_set_name(heatmap_widget):
"""Test that device SafeProperty setters work for device names."""
- # Set x_device_name - should auto-validate entry
- heatmap_widget.x_device_name = "samx"
- assert heatmap_widget._image_config.x_device is not None
- assert heatmap_widget._image_config.x_device.name == "samx"
- assert heatmap_widget._image_config.x_device.entry is not None # Entry should be validated
- assert heatmap_widget.x_device_name == "samx"
-
- # Set y_device_name
- heatmap_widget.y_device_name = "samy"
- assert heatmap_widget._image_config.y_device is not None
- assert heatmap_widget._image_config.y_device.name == "samy"
- assert heatmap_widget._image_config.y_device.entry is not None
- assert heatmap_widget.y_device_name == "samy"
-
- # Set z_device_name
- heatmap_widget.z_device_name = "bpm4i"
- assert heatmap_widget._image_config.z_device is not None
- assert heatmap_widget._image_config.z_device.name == "bpm4i"
- assert heatmap_widget._image_config.z_device.entry is not None
- assert heatmap_widget.z_device_name == "bpm4i"
+ # Set device_x - should auto-validate entry
+ heatmap_widget.device_x = "samx"
+ assert heatmap_widget._image_config.device_x is not None
+ assert heatmap_widget._image_config.device_x.device == "samx"
+ assert heatmap_widget._image_config.device_x.signal is not None # Entry should be validated
+ assert heatmap_widget.device_x == "samx"
+
+ # Set device_y
+ heatmap_widget.device_y = "samy"
+ assert heatmap_widget._image_config.device_y is not None
+ assert heatmap_widget._image_config.device_y.device == "samy"
+ assert heatmap_widget._image_config.device_y.signal is not None
+ assert heatmap_widget.device_y == "samy"
+
+ # Set device_z
+ heatmap_widget.device_z = "bpm4i"
+ assert heatmap_widget._image_config.device_z is not None
+ assert heatmap_widget._image_config.device_z.device == "bpm4i"
+ assert heatmap_widget._image_config.device_z.signal is not None
+ assert heatmap_widget.device_z == "bpm4i"
def test_device_safe_properties_set_entry(heatmap_widget):
"""Test that device entry properties can override default entries."""
# Set device name first - this auto-validates entry
- heatmap_widget.x_device_name = "samx"
- initial_entry = heatmap_widget.x_device_entry
+ heatmap_widget.device_x = "samx"
+ initial_entry = heatmap_widget.signal_x
assert initial_entry # Should have auto-validated entry
# Override with specific entry
- heatmap_widget.x_device_entry = "samx"
- assert heatmap_widget._image_config.x_device.entry == "samx"
- assert heatmap_widget.x_device_entry == "samx"
+ heatmap_widget.signal_x = "samx"
+ assert heatmap_widget._image_config.device_x.signal == "samx"
+ assert heatmap_widget.signal_x == "samx"
# Same for y device
- heatmap_widget.y_device_name = "samy"
- heatmap_widget.y_device_entry = "samy_setpoint"
- assert heatmap_widget._image_config.y_device.entry == "samy_setpoint"
+ heatmap_widget.device_y = "samy"
+ heatmap_widget.signal_y = "samy_setpoint"
+ assert heatmap_widget._image_config.device_y.signal == "samy_setpoint"
# Same for z device
- heatmap_widget.z_device_name = "bpm4i"
- heatmap_widget.z_device_entry = "bpm4i"
- assert heatmap_widget._image_config.z_device.entry == "bpm4i"
+ heatmap_widget.device_z = "bpm4i"
+ heatmap_widget.signal_z = "bpm4i"
+ assert heatmap_widget._image_config.device_z.signal == "bpm4i"
def test_device_entry_cannot_be_set_without_name(heatmap_widget):
"""Test that setting entry without device name logs warning and does nothing."""
# Try to set entry without device name
- heatmap_widget.x_device_entry = "some_entry"
+ heatmap_widget.signal_x = "some_entry"
# Should not crash, entry should remain empty
- assert heatmap_widget.x_device_entry == ""
- assert heatmap_widget._image_config.x_device is None
+ assert heatmap_widget.signal_x == ""
+ assert heatmap_widget._image_config.device_x is None
def test_device_safe_properties_set_empty(heatmap_widget):
"""Test that device SafeProperty setters handle empty strings."""
# Set device first
- heatmap_widget.x_device_name = "samx"
- assert heatmap_widget._image_config.x_device is not None
+ heatmap_widget.device_x = "samx"
+ assert heatmap_widget._image_config.device_x is not None
# Set to empty string - should clear the device
- heatmap_widget.x_device_name = ""
- assert heatmap_widget.x_device_name == ""
- assert heatmap_widget._image_config.x_device is None
+ heatmap_widget.device_x = ""
+ assert heatmap_widget.device_x == ""
+ assert heatmap_widget._image_config.device_x is None
def test_device_safe_properties_auto_plot(heatmap_widget):
"""Test that setting all three devices triggers auto-plot."""
# Set all three devices
- heatmap_widget.x_device_name = "samx"
- heatmap_widget.y_device_name = "samy"
- heatmap_widget.z_device_name = "bpm4i"
+ heatmap_widget.device_x = "samx"
+ heatmap_widget.device_y = "samy"
+ heatmap_widget.device_z = "bpm4i"
# Check that plot was called (image_config should be updated)
- assert heatmap_widget._image_config.x_device is not None
- assert heatmap_widget._image_config.y_device is not None
- assert heatmap_widget._image_config.z_device is not None
+ assert heatmap_widget._image_config.device_x is not None
+ assert heatmap_widget._image_config.device_y is not None
+ assert heatmap_widget._image_config.device_z is not None
def test_device_properties_update_labels(heatmap_widget):
"""Test that setting device properties updates axis labels."""
# Set x device - should update x label
- heatmap_widget.x_device_name = "samx"
+ heatmap_widget.device_x = "samx"
assert heatmap_widget.x_label == "samx"
# Set y device - should update y label
- heatmap_widget.y_device_name = "samy"
+ heatmap_widget.device_y = "samy"
assert heatmap_widget.y_label == "samy"
# Set z device - should update title
- heatmap_widget.z_device_name = "bpm4i"
+ heatmap_widget.device_z = "bpm4i"
assert heatmap_widget.title == "bpm4i"
def test_device_properties_partial_configuration(heatmap_widget):
"""Test that widget handles partial device configuration gracefully."""
# Set only x device
- heatmap_widget.x_device_name = "samx"
- assert heatmap_widget.x_device_name == "samx"
- assert heatmap_widget.y_device_name == ""
- assert heatmap_widget.z_device_name == ""
+ heatmap_widget.device_x = "samx"
+ assert heatmap_widget.device_x == "samx"
+ assert heatmap_widget.device_y == ""
+ assert heatmap_widget.device_z == ""
# Set only y device (x already set)
- heatmap_widget.y_device_name = "samy"
- assert heatmap_widget.x_device_name == "samx"
- assert heatmap_widget.y_device_name == "samy"
- assert heatmap_widget.z_device_name == ""
+ heatmap_widget.device_y = "samy"
+ assert heatmap_widget.device_x == "samx"
+ assert heatmap_widget.device_y == "samy"
+ assert heatmap_widget.device_z == ""
# Auto-plot should not trigger yet (z missing)
# But devices should be configured
- assert heatmap_widget._image_config.x_device is not None
- assert heatmap_widget._image_config.y_device is not None
+ assert heatmap_widget._image_config.device_x is not None
+ assert heatmap_widget._image_config.device_y is not None
def test_device_properties_in_user_access(heatmap_widget):
"""Test that device properties are exposed in USER_ACCESS for RPC."""
from bec_widgets.widgets.plots.heatmap.heatmap import Heatmap
- assert "x_device_name" in Heatmap.USER_ACCESS
- assert "x_device_name.setter" in Heatmap.USER_ACCESS
- assert "x_device_entry" in Heatmap.USER_ACCESS
- assert "x_device_entry.setter" in Heatmap.USER_ACCESS
- assert "y_device_name" in Heatmap.USER_ACCESS
- assert "y_device_name.setter" in Heatmap.USER_ACCESS
- assert "y_device_entry" in Heatmap.USER_ACCESS
- assert "y_device_entry.setter" in Heatmap.USER_ACCESS
- assert "z_device_name" in Heatmap.USER_ACCESS
- assert "z_device_name.setter" in Heatmap.USER_ACCESS
- assert "z_device_entry" in Heatmap.USER_ACCESS
- assert "z_device_entry.setter" in Heatmap.USER_ACCESS
+ assert "device_x" in Heatmap.USER_ACCESS
+ assert "device_x.setter" in Heatmap.USER_ACCESS
+ assert "signal_x" in Heatmap.USER_ACCESS
+ assert "signal_x.setter" in Heatmap.USER_ACCESS
+ assert "device_y" in Heatmap.USER_ACCESS
+ assert "device_y.setter" in Heatmap.USER_ACCESS
+ assert "signal_y" in Heatmap.USER_ACCESS
+ assert "signal_y.setter" in Heatmap.USER_ACCESS
+ assert "device_z" in Heatmap.USER_ACCESS
+ assert "device_z.setter" in Heatmap.USER_ACCESS
+ assert "signal_z" in Heatmap.USER_ACCESS
+ assert "signal_z.setter" in Heatmap.USER_ACCESS
def test_device_properties_validation(heatmap_widget):
"""Test that device entries are validated through entry_validator."""
# Set device name - entry should be auto-validated
- heatmap_widget.x_device_name = "samx"
- initial_entry = heatmap_widget.x_device_entry
+ heatmap_widget.device_x = "samx"
+ initial_entry = heatmap_widget.signal_x
# The entry should be validated (will be "samx" in the mock)
assert initial_entry == "samx"
# Set a different entry - should also be validated
- heatmap_widget.x_device_entry = "samx" # Use same name as validated entry
- assert heatmap_widget.x_device_entry == "samx"
+ heatmap_widget.signal_x = "samx" # Use same name as validated entry
+ assert heatmap_widget.signal_x == "samx"
def test_device_properties_with_plot_method(heatmap_widget):
"""Test that device properties reflect values set via plot() method."""
# Use plot method
- heatmap_widget.plot(x_name="samx", y_name="samy", z_name="bpm4i")
+ heatmap_widget.plot(device_x="samx", device_y="samy", device_z="bpm4i")
# Properties should reflect the plotted devices
- assert heatmap_widget.x_device_name == "samx"
- assert heatmap_widget.y_device_name == "samy"
- assert heatmap_widget.z_device_name == "bpm4i"
+ assert heatmap_widget.device_x == "samx"
+ assert heatmap_widget.device_y == "samy"
+ assert heatmap_widget.device_z == "bpm4i"
# Entries should be validated
- assert heatmap_widget.x_device_entry == "samx"
- assert heatmap_widget.y_device_entry == "samy"
- assert heatmap_widget.z_device_entry == "bpm4i"
+ assert heatmap_widget.signal_x == "samx"
+ assert heatmap_widget.signal_y == "samy"
+ assert heatmap_widget.signal_z == "bpm4i"
def test_device_properties_overwrite_via_properties(heatmap_widget):
"""Test that device properties can overwrite values set via plot()."""
# First set via plot
- heatmap_widget.plot(x_name="samx", y_name="samy", z_name="bpm4i")
+ heatmap_widget.plot(device_x="samx", device_y="samy", device_z="bpm4i")
# Overwrite x device via properties
- heatmap_widget.x_device_name = "samz"
- assert heatmap_widget.x_device_name == "samz"
- assert heatmap_widget._image_config.x_device.name == "samz"
+ heatmap_widget.device_x = "samz"
+ assert heatmap_widget.device_x == "samz"
+ assert heatmap_widget._image_config.device_x.device == "samz"
# Overwrite y device entry
- heatmap_widget.y_device_entry = "samy"
- assert heatmap_widget.y_device_entry == "samy"
+ heatmap_widget.signal_y = "samy"
+ assert heatmap_widget.signal_y == "samy"
def test_device_properties_clearing_devices(heatmap_widget):
"""Test clearing devices by setting to empty string."""
# Set all devices
- heatmap_widget.x_device_name = "samx"
- heatmap_widget.y_device_name = "samy"
- heatmap_widget.z_device_name = "bpm4i"
+ heatmap_widget.device_x = "samx"
+ heatmap_widget.device_y = "samy"
+ heatmap_widget.device_z = "bpm4i"
# Clear x device
- heatmap_widget.x_device_name = ""
- assert heatmap_widget.x_device_name == ""
- assert heatmap_widget._image_config.x_device is None
+ heatmap_widget.device_x = ""
+ assert heatmap_widget.device_x == ""
+ assert heatmap_widget._image_config.device_x is None
# Y and Z should still be set
- assert heatmap_widget.y_device_name == "samy"
- assert heatmap_widget.z_device_name == "bpm4i"
+ assert heatmap_widget.device_y == "samy"
+ assert heatmap_widget.device_z == "bpm4i"
def test_device_properties_property_changed_signal(heatmap_widget):
@@ -826,12 +826,12 @@ def test_device_properties_property_changed_signal(heatmap_widget):
heatmap_widget.property_changed.connect(mock_handler)
# Set device name
- heatmap_widget.x_device_name = "samx"
+ heatmap_widget.device_x = "samx"
# Signal should have been emitted
assert mock_handler.called
# Check it was called with correct arguments
- mock_handler.assert_any_call("x_device_name", "samx")
+ mock_handler.assert_any_call("device_x", "samx")
def test_auto_emit_syncs_heatmap_toolbar_actions(heatmap_widget):
@@ -855,7 +855,7 @@ def test_auto_emit_syncs_heatmap_toolbar_actions(heatmap_widget):
def test_device_entry_validation_with_invalid_device(heatmap_widget):
"""Test that invalid device names are handled gracefully."""
# Try to set invalid device name
- heatmap_widget.x_device_name = "nonexistent_device"
+ heatmap_widget.device_x = "nonexistent_device"
# Should not crash, but device might not be set if validation fails
# The implementation silently fails, so we just check it doesn't crash
@@ -864,28 +864,28 @@ def test_device_entry_validation_with_invalid_device(heatmap_widget):
def test_device_properties_sequential_entry_changes(heatmap_widget):
"""Test changing device entry multiple times."""
# Set device
- heatmap_widget.x_device_name = "samx"
+ heatmap_widget.device_x = "samx"
# Change entry multiple times
- heatmap_widget.x_device_entry = "samx_velocity"
- assert heatmap_widget.x_device_entry == "samx_velocity"
+ heatmap_widget.signal_x = "samx_velocity"
+ assert heatmap_widget.signal_x == "samx_velocity"
- heatmap_widget.x_device_entry = "samx_setpoint"
- assert heatmap_widget.x_device_entry == "samx_setpoint"
+ heatmap_widget.signal_x = "samx_setpoint"
+ assert heatmap_widget.signal_x == "samx_setpoint"
- heatmap_widget.x_device_entry = "samx"
- assert heatmap_widget.x_device_entry == "samx"
+ heatmap_widget.signal_x = "samx"
+ assert heatmap_widget.signal_x == "samx"
def test_device_properties_with_none_values(heatmap_widget):
"""Test that None values are handled as empty strings."""
# Device name None should be treated as empty
- heatmap_widget.x_device_name = None
- assert heatmap_widget.x_device_name == ""
+ heatmap_widget.device_x = None
+ assert heatmap_widget.device_x == ""
# Set a device first
- heatmap_widget.y_device_name = "samy"
+ heatmap_widget.device_y = "samy"
# Entry None should not change anything
- heatmap_widget.y_device_entry = None
- assert heatmap_widget.y_device_entry # Should still have validated entry
+ heatmap_widget.signal_y = None
+ assert heatmap_widget.signal_y # Should still have validated entry
diff --git a/tests/unit_tests/test_image_view_next_gen.py b/tests/unit_tests/test_image_view_next_gen.py
index 6144468d8..dfdb4f983 100644
--- a/tests/unit_tests/test_image_view_next_gen.py
+++ b/tests/unit_tests/test_image_view_next_gen.py
@@ -14,14 +14,9 @@
def _set_signal_config(
- client,
- device_name: str,
- signal_name: str,
- signal_class: str,
- ndim: int,
- obj_name: str | None = None,
+ client, device: str, signal_name: str, signal_class: str, ndim: int, obj_name: str | None = None
):
- device = client.device_manager.devices[device_name]
+ device = client.device_manager.devices[device]
device._info["signals"][signal_name] = {
"obj_name": obj_name or signal_name,
"signal_class": signal_class,
@@ -153,14 +148,14 @@ def test_image_setup_preview_signal_1d(qtbot, mocked_client):
obj_name="waveform1d_img",
)
- view.image(device_name="waveform1d", device_entry="img")
+ view.image(device="waveform1d", signal="img")
# Subscriptions should indicate 1‑D preview connection
sub = view.subscriptions["main"]
assert sub.source == "device_monitor_1d"
assert sub.monitor_type == "1d"
- assert view.device_name == "waveform1d"
- assert view.device_entry == "img"
+ assert view.device == "waveform1d"
+ assert view.signal == "img"
# Simulate a waveform update from the dispatcher
waveform = np.arange(25, dtype=float)
@@ -187,14 +182,14 @@ def test_image_setup_preview_signal_2d(qtbot, mocked_client):
obj_name="eiger_img2d",
)
- view.image(device_name="eiger", device_entry="img2d")
+ view.image(device="eiger", signal="img2d")
# Subscriptions should indicate 2‑D preview connection
sub = view.subscriptions["main"]
assert sub.source == "device_monitor_2d"
assert sub.monitor_type == "2d"
- assert view.device_name == "eiger"
- assert view.device_entry == "img2d"
+ assert view.device == "eiger"
+ assert view.signal == "img2d"
# Simulate a 2‑D image update
test_data = np.arange(16, dtype=float).reshape(4, 4)
@@ -259,7 +254,7 @@ def test_image_async_signal_uses_obj_name(qtbot, mocked_client, monkeypatch):
mocked_client, "eiger", "img", signal_class="AsyncSignal", ndim=1, obj_name="async_obj"
)
- view.image(device_name="eiger", device_entry="img")
+ view.image(device="eiger", signal="img")
assert view.subscriptions["main"].async_signal_name == "async_obj"
assert view.async_update is True
@@ -300,7 +295,7 @@ def test_disconnect_clears_async_state(qtbot, mocked_client, monkeypatch):
mocked_client, "eiger", "img", signal_class="AsyncSignal", ndim=2, obj_name="async_obj"
)
- view.image(device_name="eiger", device_entry="img")
+ view.image(device="eiger", signal="img")
view.scan_id = "scan_x"
view.old_scan_id = "scan_y"
view.subscriptions["main"].async_signal_name = "async_obj"
@@ -308,7 +303,7 @@ def test_disconnect_clears_async_state(qtbot, mocked_client, monkeypatch):
# Avoid touching real dispatcher
monkeypatch.setattr(view.bec_dispatcher, "disconnect_slot", lambda *args, **kwargs: None)
- view.disconnect_monitor(device_name="eiger", device_entry="img")
+ view.disconnect_monitor(device="eiger", signal="img")
assert view.subscriptions["main"].async_signal_name is None
assert view.async_update is False
@@ -322,7 +317,7 @@ def test_image_setup_rejects_unsupported_signal_class(qtbot, mocked_client):
view = create_widget(qtbot, Image, client=mocked_client)
_set_signal_config(mocked_client, "eiger", "img", signal_class="Signal", ndim=2)
- view.image(device_name="eiger", device_entry="img")
+ view.image(device="eiger", signal="img")
assert view.subscriptions["main"].source is None
assert view.subscriptions["main"].monitor_type is None
@@ -333,13 +328,13 @@ def test_image_disconnects_with_missing_entry(qtbot, mocked_client):
view = create_widget(qtbot, Image, client=mocked_client)
_set_signal_config(mocked_client, "eiger", "img", signal_class="PreviewSignal", ndim=2)
- view.image(device_name="eiger", device_entry="img")
- assert view.device_name == "eiger"
- assert view.device_entry == "img"
+ view.image(device="eiger", signal="img")
+ assert view.device == "eiger"
+ assert view.signal == "img"
- view.image(device_name="eiger", device_entry=None)
- assert view.device_name == ""
- assert view.device_entry == ""
+ view.image(device="eiger", signal=None)
+ assert view.device == ""
+ assert view.signal == ""
def test_handle_scan_change_clears_buffers_and_resets_crosshair(qtbot, mocked_client, monkeypatch):
@@ -541,8 +536,8 @@ def test_setup_image_from_toolbar(qtbot, mocked_client, monkeypatch):
bec_image_view.on_device_selection_changed(None)
qtbot.wait(200)
- assert bec_image_view.device_name == "eiger"
- assert bec_image_view.device_entry == "img"
+ assert bec_image_view.device == "eiger"
+ assert bec_image_view.signal == "img"
assert bec_image_view.subscriptions["main"].source == "device_monitor_2d"
assert bec_image_view.subscriptions["main"].monitor_type == "2d"
assert bec_image_view.main_image.raw_data is None
@@ -834,8 +829,8 @@ def test_device_selection_syncs_from_properties(qtbot, mocked_client, monkeypatc
),
)
- view.device_name = "eiger"
- view.device_entry = "img2d"
+ view.device = "eiger"
+ view.signal = "img2d"
qtbot.wait(200) # Allow signal processing
@@ -847,19 +842,19 @@ def test_device_selection_syncs_from_properties(qtbot, mocked_client, monkeypatc
)
-def test_device_entry_syncs_from_toolbar(qtbot, mocked_client):
+def test_signal_syncs_from_toolbar(qtbot, mocked_client):
view = create_widget(qtbot, Image, client=mocked_client)
_set_signal_config(mocked_client, "eiger", "img_a", signal_class="PreviewSignal", ndim=2)
_set_signal_config(mocked_client, "eiger", "img_b", signal_class="PreviewSignal", ndim=2)
- view.device_name = "eiger"
- view.device_entry = "img_a"
+ view.device = "eiger"
+ view.signal = "img_a"
device_selection = view.toolbar.components.get_action("device_selection").widget
device_selection.signal_combo_box.blockSignals(True)
device_selection.signal_combo_box.setCurrentText("img_b")
device_selection.signal_combo_box.blockSignals(False)
- view._sync_device_entry_from_toolbar()
+ view._sync_signal_from_toolbar()
- assert view.device_entry == "img_b"
+ assert view.signal == "img_b"
diff --git a/tests/unit_tests/test_motor_map_next_gen.py b/tests/unit_tests/test_motor_map_next_gen.py
index 4e296f63d..5a348675a 100644
--- a/tests/unit_tests/test_motor_map_next_gen.py
+++ b/tests/unit_tests/test_motor_map_next_gen.py
@@ -23,12 +23,12 @@ def test_motor_map_select_motor(qtbot, mocked_client):
"""Test selecting motors for the motor map."""
mm = create_widget(qtbot, MotorMap, client=mocked_client)
- mm.map(x_name="samx", y_name="samy", validate_bec=True)
+ mm.map(device_x="samx", device_y="samy", validate_bec=True)
- assert mm.config.x_motor.name == "samx"
- assert mm.config.y_motor.name == "samy"
- assert mm.config.x_motor.limits == [-10, 10]
- assert mm.config.y_motor.limits == [-5, 5]
+ assert mm.config.device_x.device == "samx"
+ assert mm.config.device_y.device == "samy"
+ assert mm.config.device_x.limits == [-10, 10]
+ assert mm.config.device_y.limits == [-5, 5]
assert mm.config.scatter_size == 5
assert mm.config.max_points == 5000
assert mm.config.num_dim_points == 100
@@ -39,7 +39,7 @@ def test_motor_map_select_motor(qtbot, mocked_client):
def test_motor_map_properties(qtbot, mocked_client):
"""Test setting and getting properties of MotorMap."""
mm = create_widget(qtbot, MotorMap, client=mocked_client)
- mm.map(x_name="samx", y_name="samy")
+ mm.map(device_x="samx", device_y="samy")
# Test color property
mm.color = (100, 150, 200, 255)
@@ -86,7 +86,7 @@ def test_motor_map_properties(qtbot, mocked_client):
def test_motor_map_get_limits(qtbot, mocked_client):
"""Test getting motor limits."""
mm = create_widget(qtbot, MotorMap, client=mocked_client)
- mm.map(x_name="samx", y_name="samy")
+ mm.map(device_x="samx", device_y="samy")
expected_limits = {"samx": [-10, 10], "samy": [-5, 5]}
for motor_name, expected_limit in expected_limits.items():
@@ -133,7 +133,7 @@ def test_motor_map_reset_history(qtbot, mocked_client):
def test_motor_map_on_device_readback(qtbot, mocked_client):
"""Test the motor map updates when receiving device readback."""
mm = create_widget(qtbot, MotorMap, client=mocked_client)
- mm.map(x_name="samx", y_name="samy")
+ mm.map(device_x="samx", device_y="samy")
# Clear the buffer and add initial position
mm._buffer = {"x": [1.0], "y": [2.0]}
@@ -161,7 +161,7 @@ def test_motor_map_on_device_readback(qtbot, mocked_client):
def test_motor_map_max_points_limit(qtbot, mocked_client):
"""Test that the buffer doesn't exceed max_points."""
mm = create_widget(qtbot, MotorMap, client=mocked_client)
- mm.map(x_name="samx", y_name="samy")
+ mm.map(device_x="samx", device_y="samy")
# Add more points than max_points
mm._buffer = {"x": [1.0, 2.0, 3.0, 4.0], "y": [5.0, 6.0, 7.0, 8.0]}
@@ -219,7 +219,7 @@ def test_motor_map_limit_map(qtbot, mocked_client):
def test_motor_map_change_limits(qtbot, mocked_client):
mm = create_widget(qtbot, MotorMap, client=mocked_client)
- mm.map(x_name="samx", y_name="samy")
+ mm.map(device_x="samx", device_y="samy")
# Original mocked limits are
# samx: [-10, 10]
@@ -229,8 +229,8 @@ def test_motor_map_change_limits(qtbot, mocked_client):
rect = mm._limit_map.boundingRect()
assert rect.width() == 20 # -10 to 10 inclusive
assert rect.height() == 10 # -5 to 5 inclusive
- assert mm.config.x_motor.limits == [-10, 10]
- assert mm.config.y_motor.limits == [-5, 5]
+ assert mm.config.device_x.limits == [-10, 10]
+ assert mm.config.device_y.limits == [-5, 5]
# Change the limits of the samx motor
mm.dev["samx"].limits = [-20, 20]
@@ -239,8 +239,8 @@ def test_motor_map_change_limits(qtbot, mocked_client):
qtbot.wait(200) # Allow time for the update to process
# Check that the limits map was updated
- assert mm.config.x_motor.limits == [-20, 20]
- assert mm.config.y_motor.limits == [-5, 5]
+ assert mm.config.device_x.limits == [-20, 20]
+ assert mm.config.device_y.limits == [-5, 5]
rect = mm._limit_map.boundingRect()
assert rect.width() == 40 # -20 to 20 inclusive
assert rect.height() == 10 # -5 to 5 inclusive -> same as before
@@ -276,13 +276,13 @@ def test_motor_map_toolbar_selection(qtbot, mocked_client):
motor_selection.widget.motor_x.setCurrentText("samx")
motor_selection.widget.motor_y.setCurrentText("samy")
- assert mm.config.x_motor.name == "samx"
- assert mm.config.y_motor.name == "samy"
+ assert mm.config.device_x.device == "samx"
+ assert mm.config.device_y.device == "samy"
motor_selection.widget.motor_y.setCurrentText("samz")
- assert mm.config.x_motor.name == "samx"
- assert mm.config.y_motor.name == "samz"
+ assert mm.config.device_x.device == "samx"
+ assert mm.config.device_y.device == "samz"
def test_motor_selection_set_motors_blocks_signals(qtbot, mocked_client):
@@ -306,19 +306,19 @@ def test_motor_properties_partial_then_complete_map(qtbot, mocked_client):
mm = create_widget(qtbot, MotorMap, client=mocked_client)
spy = QSignalSpy(mm.property_changed)
- mm.x_motor = "samx"
+ mm.device_x = "samx"
- assert mm.config.x_motor.name == "samx"
- assert mm.config.y_motor.name is None
+ assert mm.config.device_x.device == "samx"
+ assert mm.config.device_y.device is None
assert mm._trace is None # map not triggered yet
- assert spy.at(0) == ["x_motor", "samx"]
+ assert spy.at(0) == ["device_x", "samx"]
- mm.y_motor = "samy"
+ mm.device_y = "samy"
- assert mm.config.x_motor.name == "samx"
- assert mm.config.y_motor.name == "samy"
+ assert mm.config.device_x.device == "samx"
+ assert mm.config.device_y.device == "samy"
assert mm._trace is not None # map called once both valid
- assert spy.at(1) == ["y_motor", "samy"]
+ assert spy.at(1) == ["device_y", "samy"]
assert len(mm._buffer["x"]) == 1
assert len(mm._buffer["y"]) == 1
@@ -331,9 +331,9 @@ def test_set_motor_name_emits_and_syncs_toolbar(qtbot, mocked_client):
spy = QSignalSpy(mm.property_changed)
mm._set_motor_name("x", "samx")
- assert mm.config.x_motor.name == "samx"
+ assert mm.config.device_x.device == "samx"
assert motor_selection.motor_x.currentText() == "samx"
- assert spy.at(0) == ["x_motor", "samx"]
+ assert spy.at(0) == ["device_x", "samx"]
# Calling with same name should be a no-op
initial_count = spy.count()
@@ -350,7 +350,7 @@ def test_motor_map_settings_dialog(qtbot, mocked_client):
assert action_ref().action.isVisible()
# set properties to be fetched by dialog
- mm.map(x_name="samx", y_name="samy")
+ mm.map(device_x="samx", device_y="samy")
mm.precision = 2
mm.max_points = 1000
mm.scatter_size = 10
diff --git a/tests/unit_tests/test_scatter_waveform.py b/tests/unit_tests/test_scatter_waveform.py
index f0ba5620a..a34e12d37 100644
--- a/tests/unit_tests/test_scatter_waveform.py
+++ b/tests/unit_tests/test_scatter_waveform.py
@@ -37,7 +37,7 @@ def test_scatter_waveform_plot(qtbot, mocked_client):
assert curve is not None
assert isinstance(curve.config, ScatterCurveConfig)
- assert curve.config.x_device == ScatterDeviceSignal(name="samx", entry="samx")
+ assert curve.config.device_x == ScatterDeviceSignal(device="samx", signal="samx")
assert curve.config.label == "bpm4i-bpm4i"
@@ -144,49 +144,49 @@ def test_device_safe_properties_get(qtbot, mocked_client):
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
# Initially devices should be empty
- assert swf.x_device_name == ""
- assert swf.x_device_entry == ""
- assert swf.y_device_name == ""
- assert swf.y_device_entry == ""
- assert swf.z_device_name == ""
- assert swf.z_device_entry == ""
+ assert swf.device_x == ""
+ assert swf.signal_x == ""
+ assert swf.device_y == ""
+ assert swf.signal_y == ""
+ assert swf.device_z == ""
+ assert swf.signal_z == ""
# Set devices via plot
- swf.plot(x_name="samx", y_name="samy", z_name="bpm4i")
+ swf.plot(device_x="samx", device_y="samy", device_z="bpm4i")
# Check properties return device names and entries separately
- assert swf.x_device_name == "samx"
- assert swf.x_device_entry # Should have some entry
- assert swf.y_device_name == "samy"
- assert swf.y_device_entry # Should have some entry
- assert swf.z_device_name == "bpm4i"
- assert swf.z_device_entry # Should have some entry
+ assert swf.device_x == "samx"
+ assert swf.signal_x # Should have some entry
+ assert swf.device_y == "samy"
+ assert swf.signal_y # Should have some entry
+ assert swf.device_z == "bpm4i"
+ assert swf.signal_z # Should have some entry
def test_device_safe_properties_set_name(qtbot, mocked_client):
"""Test that device SafeProperty setters work for device names."""
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
- # Set x_device_name - should auto-validate entry
- swf.x_device_name = "samx"
- assert swf._main_curve.config.x_device is not None
- assert swf._main_curve.config.x_device.name == "samx"
- assert swf._main_curve.config.x_device.entry is not None # Entry should be validated
- assert swf.x_device_name == "samx"
+ # Set device_x - should auto-validate entry
+ swf.device_x = "samx"
+ assert swf._main_curve.config.device_x is not None
+ assert swf._main_curve.config.device_x.device == "samx"
+ assert swf._main_curve.config.device_x.signal is not None # Entry should be validated
+ assert swf.device_x == "samx"
- # Set y_device_name
- swf.y_device_name = "samy"
- assert swf._main_curve.config.y_device is not None
- assert swf._main_curve.config.y_device.name == "samy"
- assert swf._main_curve.config.y_device.entry is not None
- assert swf.y_device_name == "samy"
+ # Set device_y
+ swf.device_y = "samy"
+ assert swf._main_curve.config.device_y is not None
+ assert swf._main_curve.config.device_y.device == "samy"
+ assert swf._main_curve.config.device_y.signal is not None
+ assert swf.device_y == "samy"
- # Set z_device_name
- swf.z_device_name = "bpm4i"
- assert swf._main_curve.config.z_device is not None
- assert swf._main_curve.config.z_device.name == "bpm4i"
- assert swf._main_curve.config.z_device.entry is not None
- assert swf.z_device_name == "bpm4i"
+ # Set device_z
+ swf.device_z = "bpm4i"
+ assert swf._main_curve.config.device_z is not None
+ assert swf._main_curve.config.device_z.device == "bpm4i"
+ assert swf._main_curve.config.device_z.signal is not None
+ assert swf.device_z == "bpm4i"
def test_device_safe_properties_set_entry(qtbot, mocked_client):
@@ -194,24 +194,24 @@ def test_device_safe_properties_set_entry(qtbot, mocked_client):
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
# Set device name first - this auto-validates entry
- swf.x_device_name = "samx"
- initial_entry = swf.x_device_entry
+ swf.device_x = "samx"
+ initial_entry = swf.signal_x
assert initial_entry # Should have auto-validated entry
# Override with specific entry
- swf.x_device_entry = "samx"
- assert swf._main_curve.config.x_device.entry == "samx"
- assert swf.x_device_entry == "samx"
+ swf.signal_x = "samx"
+ assert swf._main_curve.config.device_x.signal == "samx"
+ assert swf.signal_x == "samx"
# Same for y device
- swf.y_device_name = "samy"
- swf.y_device_entry = "samy_setpoint"
- assert swf._main_curve.config.y_device.entry == "samy_setpoint"
+ swf.device_y = "samy"
+ swf.signal_y = "samy_setpoint"
+ assert swf._main_curve.config.device_y.signal == "samy_setpoint"
# Same for z device
- swf.z_device_name = "bpm4i"
- swf.z_device_entry = "bpm4i"
- assert swf._main_curve.config.z_device.entry == "bpm4i"
+ swf.device_z = "bpm4i"
+ swf.signal_z = "bpm4i"
+ assert swf._main_curve.config.device_z.signal == "bpm4i"
def test_device_entry_cannot_be_set_without_name(qtbot, mocked_client):
@@ -219,10 +219,10 @@ def test_device_entry_cannot_be_set_without_name(qtbot, mocked_client):
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
# Try to set entry without device name
- swf.x_device_entry = "some_entry"
+ swf.signal_x = "some_entry"
# Should not crash, entry should remain empty
- assert swf.x_device_entry == ""
- assert swf._main_curve.config.x_device is None
+ assert swf.signal_x == ""
+ assert swf._main_curve.config.device_x is None
def test_device_safe_properties_set_empty(qtbot, mocked_client):
@@ -230,13 +230,13 @@ def test_device_safe_properties_set_empty(qtbot, mocked_client):
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
# Set device first
- swf.x_device_name = "samx"
- assert swf._main_curve.config.x_device is not None
+ swf.device_x = "samx"
+ assert swf._main_curve.config.device_x is not None
# Set to empty string - should clear the device
- swf.x_device_name = ""
- assert swf.x_device_name == ""
- assert swf._main_curve.config.x_device is None
+ swf.device_x = ""
+ assert swf.device_x == ""
+ assert swf._main_curve.config.device_x is None
def test_device_safe_properties_auto_plot(qtbot, mocked_client):
@@ -244,14 +244,14 @@ def test_device_safe_properties_auto_plot(qtbot, mocked_client):
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
# Set all three devices
- swf.x_device_name = "samx"
- swf.y_device_name = "samy"
- swf.z_device_name = "bpm4i"
+ swf.device_x = "samx"
+ swf.device_y = "samy"
+ swf.device_z = "bpm4i"
# Check that plot was called (config should be updated)
- assert swf._main_curve.config.x_device is not None
- assert swf._main_curve.config.y_device is not None
- assert swf._main_curve.config.z_device is not None
+ assert swf._main_curve.config.device_x is not None
+ assert swf._main_curve.config.device_y is not None
+ assert swf._main_curve.config.device_z is not None
def test_device_properties_update_labels(qtbot, mocked_client):
@@ -259,11 +259,11 @@ def test_device_properties_update_labels(qtbot, mocked_client):
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
# Set x device - should update x label
- swf.x_device_name = "samx"
+ swf.device_x = "samx"
assert swf.x_label == "samx"
# Set y device - should update y label
- swf.y_device_name = "samy"
+ swf.device_y = "samy"
assert swf.y_label == "samy"
# Note: ScatterWaveform doesn't have a title like Heatmap does for z_device
@@ -274,39 +274,39 @@ def test_device_properties_partial_configuration(qtbot, mocked_client):
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
# Set only x device
- swf.x_device_name = "samx"
- assert swf.x_device_name == "samx"
- assert swf.y_device_name == ""
- assert swf.z_device_name == ""
+ swf.device_x = "samx"
+ assert swf.device_x == "samx"
+ assert swf.device_y == ""
+ assert swf.device_z == ""
# Set only y device (x already set)
- swf.y_device_name = "samy"
- assert swf.x_device_name == "samx"
- assert swf.y_device_name == "samy"
- assert swf.z_device_name == ""
+ swf.device_y = "samy"
+ assert swf.device_x == "samx"
+ assert swf.device_y == "samy"
+ assert swf.device_z == ""
# Auto-plot should not trigger yet (z missing)
# But devices should be configured
- assert swf._main_curve.config.x_device is not None
- assert swf._main_curve.config.y_device is not None
+ assert swf._main_curve.config.device_x is not None
+ assert swf._main_curve.config.device_y is not None
def test_device_properties_in_user_access(qtbot, mocked_client):
"""Test that device properties are exposed in USER_ACCESS for RPC."""
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
- assert "x_device_name" in ScatterWaveform.USER_ACCESS
- assert "x_device_name.setter" in ScatterWaveform.USER_ACCESS
- assert "x_device_entry" in ScatterWaveform.USER_ACCESS
- assert "x_device_entry.setter" in ScatterWaveform.USER_ACCESS
- assert "y_device_name" in ScatterWaveform.USER_ACCESS
- assert "y_device_name.setter" in ScatterWaveform.USER_ACCESS
- assert "y_device_entry" in ScatterWaveform.USER_ACCESS
- assert "y_device_entry.setter" in ScatterWaveform.USER_ACCESS
- assert "z_device_name" in ScatterWaveform.USER_ACCESS
- assert "z_device_name.setter" in ScatterWaveform.USER_ACCESS
- assert "z_device_entry" in ScatterWaveform.USER_ACCESS
- assert "z_device_entry.setter" in ScatterWaveform.USER_ACCESS
+ assert "device_x" in ScatterWaveform.USER_ACCESS
+ assert "device_x.setter" in ScatterWaveform.USER_ACCESS
+ assert "signal_x" in ScatterWaveform.USER_ACCESS
+ assert "signal_x.setter" in ScatterWaveform.USER_ACCESS
+ assert "device_y" in ScatterWaveform.USER_ACCESS
+ assert "device_y.setter" in ScatterWaveform.USER_ACCESS
+ assert "signal_y" in ScatterWaveform.USER_ACCESS
+ assert "signal_y.setter" in ScatterWaveform.USER_ACCESS
+ assert "device_z" in ScatterWaveform.USER_ACCESS
+ assert "device_z.setter" in ScatterWaveform.USER_ACCESS
+ assert "signal_z" in ScatterWaveform.USER_ACCESS
+ assert "signal_z.setter" in ScatterWaveform.USER_ACCESS
def test_device_properties_validation(qtbot, mocked_client):
@@ -314,15 +314,15 @@ def test_device_properties_validation(qtbot, mocked_client):
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
# Set device name - entry should be auto-validated
- swf.x_device_name = "samx"
- initial_entry = swf.x_device_entry
+ swf.device_x = "samx"
+ initial_entry = swf.signal_x
# The entry should be validated (will be "samx" in the mock)
assert initial_entry == "samx"
# Set a different entry - should also be validated
- swf.x_device_entry = "samx" # Use same name as validated entry
- assert swf.x_device_entry == "samx"
+ swf.signal_x = "samx" # Use same name as validated entry
+ assert swf.signal_x == "samx"
def test_device_properties_with_plot_method(qtbot, mocked_client):
@@ -330,17 +330,17 @@ def test_device_properties_with_plot_method(qtbot, mocked_client):
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
# Use plot method
- swf.plot(x_name="samx", y_name="samy", z_name="bpm4i")
+ swf.plot(device_x="samx", device_y="samy", device_z="bpm4i")
# Properties should reflect the plotted devices
- assert swf.x_device_name == "samx"
- assert swf.y_device_name == "samy"
- assert swf.z_device_name == "bpm4i"
+ assert swf.device_x == "samx"
+ assert swf.device_y == "samy"
+ assert swf.device_z == "bpm4i"
# Entries should be validated
- assert swf.x_device_entry == "samx"
- assert swf.y_device_entry == "samy"
- assert swf.z_device_entry == "bpm4i"
+ assert swf.signal_x == "samx"
+ assert swf.signal_y == "samy"
+ assert swf.signal_z == "bpm4i"
def test_device_properties_overwrite_via_properties(qtbot, mocked_client):
@@ -348,16 +348,16 @@ def test_device_properties_overwrite_via_properties(qtbot, mocked_client):
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
# First set via plot
- swf.plot(x_name="samx", y_name="samy", z_name="bpm4i")
+ swf.plot(device_x="samx", device_y="samy", device_z="bpm4i")
# Overwrite x device via properties
- swf.x_device_name = "samz"
- assert swf.x_device_name == "samz"
- assert swf._main_curve.config.x_device.name == "samz"
+ swf.device_x = "samz"
+ assert swf.device_x == "samz"
+ assert swf._main_curve.config.device_x.device == "samz"
# Overwrite y device entry
- swf.y_device_entry = "samy"
- assert swf.y_device_entry == "samy"
+ swf.signal_y = "samy"
+ assert swf.signal_y == "samy"
def test_device_properties_clearing_devices(qtbot, mocked_client):
@@ -365,18 +365,18 @@ def test_device_properties_clearing_devices(qtbot, mocked_client):
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
# Set all devices
- swf.x_device_name = "samx"
- swf.y_device_name = "samy"
- swf.z_device_name = "bpm4i"
+ swf.device_x = "samx"
+ swf.device_y = "samy"
+ swf.device_z = "bpm4i"
# Clear x device
- swf.x_device_name = ""
- assert swf.x_device_name == ""
- assert swf._main_curve.config.x_device is None
+ swf.device_x = ""
+ assert swf.device_x == ""
+ assert swf._main_curve.config.device_x is None
# Y and Z should still be set
- assert swf.y_device_name == "samy"
- assert swf.z_device_name == "bpm4i"
+ assert swf.device_y == "samy"
+ assert swf.device_z == "bpm4i"
def test_device_properties_property_changed_signal(qtbot, mocked_client):
@@ -390,12 +390,12 @@ def test_device_properties_property_changed_signal(qtbot, mocked_client):
swf.property_changed.connect(mock_handler)
# Set device name
- swf.x_device_name = "samx"
+ swf.device_x = "samx"
# Signal should have been emitted
assert mock_handler.called
# Check it was called with correct arguments
- mock_handler.assert_any_call("x_device_name", "samx")
+ mock_handler.assert_any_call("device_x", "samx")
def test_device_entry_validation_with_invalid_device(qtbot, mocked_client):
@@ -403,7 +403,7 @@ def test_device_entry_validation_with_invalid_device(qtbot, mocked_client):
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
# Try to set invalid device name
- swf.x_device_name = "nonexistent_device"
+ swf.device_x = "nonexistent_device"
# Should not crash, but device might not be set if validation fails
# The implementation silently fails, so we just check it doesn't crash
@@ -414,17 +414,17 @@ def test_device_properties_sequential_entry_changes(qtbot, mocked_client):
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
# Set device
- swf.x_device_name = "samx"
+ swf.device_x = "samx"
# Change entry multiple times
- swf.x_device_entry = "samx_velocity"
- assert swf.x_device_entry == "samx_velocity"
+ swf.signal_x = "samx_velocity"
+ assert swf.signal_x == "samx_velocity"
- swf.x_device_entry = "samx_setpoint"
- assert swf.x_device_entry == "samx_setpoint"
+ swf.signal_x = "samx_setpoint"
+ assert swf.signal_x == "samx_setpoint"
- swf.x_device_entry = "samx"
- assert swf.x_device_entry == "samx"
+ swf.signal_x = "samx"
+ assert swf.signal_x == "samx"
def test_device_properties_with_none_values(qtbot, mocked_client):
@@ -432,15 +432,15 @@ def test_device_properties_with_none_values(qtbot, mocked_client):
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
# Device name None should be treated as empty
- swf.x_device_name = None
- assert swf.x_device_name == ""
+ swf.device_x = None
+ assert swf.device_x == ""
# Set a device first
- swf.y_device_name = "samy"
+ swf.device_y = "samy"
# Entry None should not change anything
- swf.y_device_entry = None
- assert swf.y_device_entry # Should still have validated entry
+ swf.signal_y = None
+ assert swf.signal_y # Should still have validated entry
################################################################################
@@ -457,9 +457,9 @@ def test_scatter_curve_settings_accept_changes(qtbot, mocked_client):
qtbot.addWidget(settings)
# Set up the widgets with test values
- settings.ui.x_name.set_device("samx")
- settings.ui.y_name.set_device("samy")
- settings.ui.z_name.set_device("bpm4i")
+ settings.ui.device_x.set_device("samx")
+ settings.ui.device_y.set_device("samy")
+ settings.ui.device_z.set_device("bpm4i")
# Mock the plot method to verify it gets called with correct arguments
with patch.object(swf, "plot") as mock_plot:
@@ -472,9 +472,9 @@ def test_scatter_curve_settings_accept_changes(qtbot, mocked_client):
call_kwargs = mock_plot.call_args[1]
# Verify device names were extracted correctly
- assert call_kwargs["x_name"] == "samx"
- assert call_kwargs["y_name"] == "samy"
- assert call_kwargs["z_name"] == "bpm4i"
+ assert call_kwargs["device_x"] == "samx"
+ assert call_kwargs["device_y"] == "samy"
+ assert call_kwargs["device_z"] == "bpm4i"
def test_scatter_curve_settings_accept_changes_with_entries(qtbot, mocked_client):
@@ -486,9 +486,9 @@ def test_scatter_curve_settings_accept_changes_with_entries(qtbot, mocked_client
qtbot.addWidget(settings)
# Set devices first to populate signal comboboxes
- settings.ui.x_name.set_device("samx")
- settings.ui.y_name.set_device("samy")
- settings.ui.z_name.set_device("bpm4i")
+ settings.ui.device_x.set_device("samx")
+ settings.ui.device_y.set_device("samy")
+ settings.ui.device_z.set_device("bpm4i")
qtbot.wait(100) # Allow time for signals to populate
# Mock the plot method
@@ -499,9 +499,9 @@ def test_scatter_curve_settings_accept_changes_with_entries(qtbot, mocked_client
call_kwargs = mock_plot.call_args[1]
# Verify entries are extracted (will use get_signal_name())
- assert "x_entry" in call_kwargs
- assert "y_entry" in call_kwargs
- assert "z_entry" in call_kwargs
+ assert "signal_x" in call_kwargs
+ assert "signal_y" in call_kwargs
+ assert "signal_z" in call_kwargs
def test_scatter_curve_settings_accept_changes_color_map(qtbot, mocked_client):
@@ -514,9 +514,9 @@ def test_scatter_curve_settings_accept_changes_color_map(qtbot, mocked_client):
qtbot.addWidget(settings)
# Set devices
- settings.ui.x_name.set_device("samx")
- settings.ui.y_name.set_device("samy")
- settings.ui.z_name.set_device("bpm4i")
+ settings.ui.device_x.set_device("samx")
+ settings.ui.device_y.set_device("samy")
+ settings.ui.device_z.set_device("bpm4i")
# Get the current colormap
color_map = settings.ui.color_map.colormap
@@ -532,13 +532,13 @@ def test_scatter_curve_settings_fetch_all_properties(qtbot, mocked_client):
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
# First set up the scatter waveform with some data
- swf.plot(x_name="samx", y_name="samy", z_name="bpm4i")
+ swf.plot(device_x="samx", device_y="samy", device_z="bpm4i")
# Create the settings widget - it should fetch properties automatically
settings = ScatterCurveSettings(parent=None, target_widget=swf, popup=True)
qtbot.addWidget(settings)
# Verify the settings widget has fetched the values
- assert settings.ui.x_name.currentText() == "samx"
- assert settings.ui.y_name.currentText() == "samy"
- assert settings.ui.z_name.currentText() == "bpm4i"
+ assert settings.ui.device_x.currentText() == "samx"
+ assert settings.ui.device_y.currentText() == "samy"
+ assert settings.ui.device_z.currentText() == "bpm4i"
diff --git a/tests/unit_tests/test_waveform.py b/tests/unit_tests/test_waveform.py
index 142b0e73b..a749a4cad 100644
--- a/tests/unit_tests/test_waveform.py
+++ b/tests/unit_tests/test_waveform.py
@@ -107,8 +107,8 @@ def test_plot_single_arg_input_sync(qtbot, mocked_client):
assert c1.config.source == "device"
assert c2.config.source == "device"
- assert c1.config.signal == DeviceSignal(name="bpm4i", entry="bpm4i", dap=None)
- assert c2.config.signal == DeviceSignal(name="bpm3a", entry="bpm3a", dap=None)
+ assert c1.config.signal == DeviceSignal(device="bpm4i", signal="bpm4i", dap=None)
+ assert c2.config.signal == DeviceSignal(device="bpm3a", signal="bpm3a", dap=None)
# Check that the curve is added to the plot
assert len(wf.plot_item.curves) == 2
@@ -122,8 +122,8 @@ def test_plot_single_arg_input_async(qtbot, mocked_client):
assert c1.config.source == "device"
assert c2.config.source == "device"
- assert c1.config.signal == DeviceSignal(name="eiger", entry="eiger", dap=None)
- assert c2.config.signal == DeviceSignal(name="async_device", entry="async_device", dap=None)
+ assert c1.config.signal == DeviceSignal(device="eiger", signal="eiger", dap=None)
+ assert c2.config.signal == DeviceSignal(device="async_device", signal="async_device", dap=None)
# Check that the curve is added to the plot
assert len(wf.plot_item.curves) == 2
@@ -305,7 +305,7 @@ def test_curve_json_setter_ignores_custom(qtbot, mocked_client):
"label": "device_curve",
"color": "#ff0000",
"source": "device",
- "signal": {"name": "bpm4i", "entry": "bpm4i", "dap": None},
+ "signal": {"device": "bpm4i", "signal": "bpm4i", "dap": None},
}
custom_curve_config = {
"widget_class": "Curve",
@@ -475,7 +475,7 @@ def test_add_dap_curve(qtbot, mocked_client_with_dap, monkeypatch):
dap_curve = wf.add_dap_curve(device_label="bpm4i-bpm4i", dap_name="GaussianModel")
assert dap_curve is not None
assert dap_curve.config.source == "dap"
- assert dap_curve.config.signal.name == "bpm4i"
+ assert dap_curve.config.signal.device == "bpm4i"
assert dap_curve.config.signal.dap == "GaussianModel"
@@ -491,8 +491,8 @@ def test_add_dap_curve_custom_source(qtbot, mocked_client_with_dap):
dap_curve = wf.add_dap_curve(device_label=custom_curve.name(), dap_name="GaussianModel")
assert dap_curve.config.source == "dap"
assert dap_curve.config.parent_label == custom_curve.name()
- assert dap_curve.config.signal.name == custom_curve.name()
- assert dap_curve.config.signal.entry == "custom"
+ assert dap_curve.config.signal.device == custom_curve.name()
+ assert dap_curve.config.signal.signal == "custom"
assert dap_curve.config.signal.dap == "GaussianModel"
@@ -764,7 +764,7 @@ def test_curve_set_data_error_non_custom(qtbot, mocked_client):
Test that calling set_data on a non-custom (device) curve raises a ValueError.
"""
wf = create_widget(qtbot, Waveform, client=mocked_client)
- # Create a device curve by providing y_name (which makes source 'device')
+ # Create a device curve by providing device_y (which makes source 'device')
# Assume that entry_validator returns a valid entry.
c = wf.plot(arg1="bpm4i", label="device_curve")
with pytest.raises(ValueError):
@@ -1136,20 +1136,20 @@ def test_update_with_scan_history_by_index(qtbot, mocked_client, scan_history_fa
assert len(wf.client.history._scan_ids) == 2, "Expected two history scans"
# Do history curve plotting
- wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id="hist1")
- wf.plot(y_name="bpm4i", scan_number=2)
+ wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id="hist1")
+ wf.plot(device_y="bpm4i", scan_number=2)
assert len(wf.plot_item.curves) == 2, "Expected two curves for history scans"
c1, c2 = wf.plot_item.curves
# First curve should be for hist1, second for hist2
- assert c1.config.signal.name == "bpm4i"
- assert c1.config.signal.entry == "bpm4i"
+ assert c1.config.signal.device == "bpm4i"
+ assert c1.config.signal.signal == "bpm4i"
assert c1.config.scan_id == "hist1"
assert c1.config.scan_number == 1
assert c1.name() == "bpm4i-bpm4i-scan-1"
- assert c2.config.signal.name == "bpm4i"
- assert c2.config.signal.entry == "bpm4i"
+ assert c2.config.signal.device == "bpm4i"
+ assert c2.config.signal.signal == "bpm4i"
assert c2.config.scan_id == "hist2"
assert c2.config.scan_number == 2
assert c2.name() == "bpm4i-bpm4i-scan-2"
@@ -1163,7 +1163,7 @@ def test_history_curve_x_modes_pre_plot(qtbot, mocked_client, scan_history_facto
wf = create_widget(qtbot, Waveform, client=mocked_client)
hist1, hist2 = inject_scan_history(wf, scan_history_factory, ("hist1", 1), ("hist2", 2))
wf.x_mode = mode
- c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id="hist1")
+ c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id="hist1")
assert c.config.current_x_mode == mode
@@ -1174,7 +1174,7 @@ def test_history_curve_x_modes_post_plot(qtbot, mocked_client, scan_history_fact
"""
wf = create_widget(qtbot, Waveform, client=mocked_client)
hist1, hist2 = inject_scan_history(wf, scan_history_factory, ("hist1", 1), ("hist2", 2))
- c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id="hist1")
+ c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id="hist1")
# Change x_mode after plotting
wf.x_mode = mode
# Refresh history curves
@@ -1191,7 +1191,7 @@ def test_history_curve_incompatible_x_mode_hides_curve(qtbot, mocked_client, sca
# Inject history scan for this test
[history_msg] = inject_scan_history(wf, scan_history_factory, ("hist_bad", 1))
# Plot history curve
- c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id=history_msg.scan_id)
+ c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id=history_msg.scan_id)
# Curve should be hidden due to incompatible x_mode
assert not c.isVisible()
@@ -1212,7 +1212,7 @@ def test_fetch_history_data_no_stored_data_raises(
# Force get_history_scan_item to return our dummy
monkeypatch.setattr(wf, "get_history_scan_item", lambda scan_id, scan_index: dummy_scan)
# Attempt to plot history curve should be suppressed by SafeSlot and return None
- c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id="dummy", scan_number=1)
+ c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id="dummy", scan_number=1)
assert c is None
assert len(wf.curves) == 0
@@ -1224,7 +1224,7 @@ def test_history_curve_device_missing_returns_none(qtbot, mocked_client, scan_hi
wf = create_widget(qtbot, Waveform, client=mocked_client)
wf.x_mode = "index"
[history_msg] = inject_scan_history(wf, scan_history_factory, ("hist_dev_missing", 1))
- c = wf.plot(y_name="non-existing", y_entry="non-existing", scan_id=history_msg.scan_id)
+ c = wf.plot(device_y="non-existing", signal_y="non-existing", scan_id=history_msg.scan_id)
assert c is None
@@ -1238,7 +1238,7 @@ def test_history_curve_custom_shape_mismatch_hides_curve(
wf.x_mode = "async_device"
[history_msg] = inject_scan_history(wf, scan_history_factory, ("hist_custom_shape", 1))
# Force shape mismatch for x-data
- c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id=history_msg.scan_id)
+ c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id=history_msg.scan_id)
assert c is not None
assert not c.isVisible()
@@ -1250,7 +1250,7 @@ def test_history_curve_index_mode_plots_curve(qtbot, mocked_client, scan_history
wf = create_widget(qtbot, Waveform, client=mocked_client)
wf.x_mode = "index"
[history_msg] = inject_scan_history(wf, scan_history_factory, ("hist_index", 1))
- c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id=history_msg.scan_id)
+ c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id=history_msg.scan_id)
assert c is not None
assert c.isVisible()
assert c.config.current_x_mode == "index"
@@ -1263,7 +1263,7 @@ def test_history_curve_timestamp_mode_plots_curve(qtbot, mocked_client, scan_his
wf = create_widget(qtbot, Waveform, client=mocked_client)
wf.x_mode = "timestamp"
[history_msg] = inject_scan_history(wf, scan_history_factory, ("hist_time", 1))
- c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id=history_msg.scan_id)
+ c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id=history_msg.scan_id)
assert c is not None
assert c.isVisible()
assert c.config.current_x_mode == "timestamp"
@@ -1279,7 +1279,7 @@ def test_history_curve_auto_valid_uses_first_report_device(
wf.x_mode = "auto"
[history_msg] = inject_scan_history(wf, scan_history_factory, ("hist_auto_valid", 1))
# Plot history curve
- c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id=history_msg.scan_id)
+ c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id=history_msg.scan_id)
assert c is not None
assert c.isVisible()
# Should have fallen back to the first scan_report_device
@@ -1295,7 +1295,7 @@ def test_history_curve_file_not_found_returns_none(qtbot, mocked_client, scan_hi
# Inject a valid history message then corrupt its file_path
[history_msg] = inject_scan_history(wf, scan_history_factory, ("bad_file", 1))
history_msg.file_path = "/nonexistent/path.h5"
- c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id=history_msg.scan_id)
+ c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id=history_msg.scan_id)
assert c is None
@@ -1306,5 +1306,5 @@ def test_history_curve_scan_not_found_returns_none(qtbot, mocked_client):
wf = create_widget(qtbot, Waveform, client=mocked_client)
wf.x_mode = "index"
# No history scans injected for this widget
- c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id="unknown_scan")
+ c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id="unknown_scan")
assert c is None