Merge branch 'main' into feat/direct-mono-acs-comm
CI for debye_bec / test (pull_request) Failing after 49s
CI for debye_bec / test (push) Failing after 1m12s

This commit is contained in:
2026-08-04 12:33:20 +02:00
5 changed files with 76 additions and 45 deletions
@@ -16,7 +16,7 @@ from bec_widgets.utils.colors import apply_theme, get_accent_colors
from bec_widgets.utils.error_popups import SafeSlot
# pylint: disable=E0611
from qtpy.QtWidgets import QApplication, QVBoxLayout, QWidget
from qtpy.QtWidgets import QApplication, QFileDialog, QVBoxLayout, QWidget
from .panels.input_panel import InputPanel
from .panels.scan_view import ScanViewer
@@ -55,8 +55,9 @@ class DataViewer(BECWidget, QWidget):
self.current_row = 0
self.input.scan_sel.currentItemChanged_connect(self.scan_sel_changed)
self.input.load_button.clicked_connect(self.load_scan)
self.input.unload_button.clicked_connect(self.unload_all_scans)
self.input.load_button.clicked_connect(self.load_scan_from_history)
self.input.load_from_folder_button.clicked_connect(self.load_scan_from_folder)
self.viewer.unload_button.clicked_connect(self.unload_all_scans)
self.input.open_fm_button.clicked_connect(self.open_in_file_manager)
def apply_theme(self, theme: Literal["dark", "light"]):
@@ -89,7 +90,7 @@ class DataViewer(BECWidget, QWidget):
)
@SafeSlot()
def load_scan(self, *_):
def load_scan_from_history(self, *_):
"""
Loads a scan. Find all files within the scan folder, sort them and
then load the files in the scan view
@@ -97,23 +98,46 @@ class DataViewer(BECWidget, QWidget):
if len(self.history) > 0:
scan = self.history[self.current_row]
base_filepath = scan["file_components"][0].decode().rsplit("/", 1)[0]
filenames = [
f
for f in os.listdir(base_filepath)
if os.path.isfile(os.path.join(base_filepath, f))
]
self.load_scan(base_filepath)
def sort_priority(name):
if "master" in name:
return 0
if name.endswith(".h5"):
return 1
return 2
@SafeSlot()
def load_scan_from_folder(self, *_):
"""
Loads a scan from a folder. Find all files within the scan folder, sort them and
then load the files in the scan view
"""
sorted_files = [
f"{base_filepath}/{name}" for name in sorted(filenames, key=sort_priority)
]
self.viewer.load_files(sorted_files)
hostname = self.client._hostname
start = hostname.find("x")
if start != -1:
beamline = hostname[start : start + 5]
active_account = self.client.active_account
start_folder = f"/sls/{beamline}/data/{active_account}/raw"
else:
start_folder = "/sls"
base_filepath = QFileDialog.getExistingDirectory(self, "Open Scan Folder", start_folder)
if base_filepath != "":
self.load_scan(base_filepath)
def load_scan(self, base_filepath):
"""
Loads a scan from a base_filepath. Find all files within the scan folder, sort them and
then load the files in the scan view
"""
filenames = [
f for f in os.listdir(base_filepath) if os.path.isfile(os.path.join(base_filepath, f))
]
def sort_priority(name):
if "master" in name:
return 0
if name.endswith(".h5"):
return 1
return 2
sorted_files = [f"{base_filepath}/{name}" for name in sorted(filenames, key=sort_priority)]
self.viewer.load_files(sorted_files)
@SafeSlot()
def unload_all_scans(self, *_):
@@ -176,13 +200,21 @@ class DataViewer(BECWidget, QWidget):
start_time = self.client.history[-n].metadata["start_time"] # type: ignore
end_time = self.client.history[-n].metadata["end_time"] # type: ignore
scan_data = self.client.history[-n].metadata["bec"] # type: ignore
# logger.info(f"scan_data: {scan_data}")
scan_number = scan_data["scan_number"]
scan_name = scan_data["scan_name"]
if "metadata" in scan_data:
comment = scan_data["metadata"]["user_metadata"]["comment"]
sample_name = scan_data["metadata"]["user_metadata"]["sample_name"]
else:
comment, sample_name = "", ""
comment, sample_name = "", ""
user_metadata = scan_data.get("user_metadata", {})
comment = user_metadata.get("comment", comment)
sample_name = user_metadata.get("sample_name", sample_name)
if comment == "":
metadata_user = scan_data.get("metadata", {}).get("user_metadata", {})
comment = metadata_user.get("comment", comment)
if sample_name == "":
metadata_user = scan_data.get("metadata", {}).get("user_metadata", {})
sample_name = metadata_user.get("sample_name", sample_name)
status = scan_data["status"]
self.history.append(
{
@@ -1,5 +1,5 @@
# pylint: disable=E0611
from qtpy.QtWidgets import QHBoxLayout, QVBoxLayout, QWidget
from qtpy.QtWidgets import QFrame, QHBoxLayout, QVBoxLayout, QWidget
# pylint: disable=E0402
from ..widgets.qt_widgets import Button, Group, ListWidget
@@ -15,13 +15,21 @@ class InputPanel(QWidget):
# Scan selection
self.scan_sel = ListWidget("scan_sel")
self.load_button = Button(label_button="Load Dataset", enabled=True)
self.unload_button = Button(label_button="Unload all", enabled=True)
self.open_fm_button = Button(label_button="Open in File Manager", enabled=True)
line = QFrame()
line.setFrameShape(QFrame.HLine)
line.setFrameShadow(QFrame.Sunken)
self.load_from_folder_button = Button(
label_button="Load Dataset from File Manager", enabled=True
)
self._button_layout = QVBoxLayout()
self._button_layout.addWidget(self.load_button)
self._button_layout.addWidget(self.unload_button)
self._button_layout.addWidget(self.open_fm_button)
self._button_layout.addWidget(line)
self._button_layout.addWidget(self.load_from_folder_button)
self._button_layout.addStretch()
# Assemble complete scan selection group
@@ -27,7 +27,7 @@ from qtpy.QtWidgets import (
# pylint: disable=E0402
from ..loaders import BaseFileLoader, registry
from ..widgets.qt_widgets import Group
from ..widgets.qt_widgets import Button, Group
from .data_view import DataView
logger = bec_logger.logger
@@ -59,6 +59,7 @@ class ScanViewer(QMainWindow):
left_pane = QWidget()
left_layout = QVBoxLayout(left_pane)
self.unload_button = Button(label_button="Unload all", enabled=True)
self.tree = QTreeWidget()
self.tree.setMinimumWidth(250)
self.tree.setHeaderLabels(["Name", "Type", "Shape"])
@@ -68,6 +69,7 @@ class ScanViewer(QMainWindow):
self.tree.header().setSectionResizeMode(2, QHeaderView.ResizeMode.ResizeToContents)
self.tree.itemClicked.connect(self._on_item_clicked)
left_layout.addWidget(self.unload_button)
left_layout.addWidget(self.tree, 1)
self.data_panel = DataView()
@@ -45,15 +45,13 @@ class Button(QWidget):
def __init__(self, label=None, label_button: str = "", enabled=False):
super().__init__()
layout = QHBoxLayout(self)
layout.setContentsMargins(10, 0, 0, 0)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(0)
if label is not None:
self.label = QLabel(label)
self.label.setFixedWidth(140)
self.label.setFixedWidth(160)
layout.addWidget(self.label)
self.button = QPushButton(label_button)
if label is not None:
self.button.setFixedWidth(160)
self.enable_button(enabled)
layout.addWidget(self.button)
+4 -13
View File
@@ -6,23 +6,14 @@ from unittest import mock
import ophyd
import pytest
from bec_lib.messages import ScanStatusMessage
from bec_server.scan_server.scan_worker import ScanWorker
from bec_server.scan_server.scans.scan_base import ScanInfo as ScanServerScanInfo
from bec_server.scan_server.tests.scan_fixtures import *
from bec_server.scan_server.tests.scan_fixtures import _MockDevice
from ophyd_devices import CompareStatus, DeviceStatus
from ophyd_devices import DeviceStatus
from ophyd_devices.interfaces.base_classes.psi_device_base import DeviceStoppedError
from ophyd_devices.tests.utils import MockPV, patch_dual_pvs
from ophyd_devices.utils.psi_device_base_utils import TaskStatus
from debye_bec.devices.pilatus.pilatus import (
ACQUIREMODE,
COMPRESSIONALGORITHM,
DETECTORSTATE,
FILEWRITEMODE,
TRIGGERMODE,
Pilatus,
)
from debye_bec.devices.pilatus.pilatus import ACQUIREMODE, DETECTORSTATE, Pilatus
from debye_bec.devices.utils.utils import fetch_scan_info
if TYPE_CHECKING: # pragma no cover
@@ -38,8 +29,8 @@ if TYPE_CHECKING: # pragma no cover
@pytest.fixture(
scope="function",
params=[
(("samx", 0.1, 1, 5, "samy", 0, 1, 5), {"relative": True}, "_v4_hexagonal_scan"),
((1, 0.2), {}, "_v4_time_scan"),
(("samx", 0.1, 1, 5, "samy", 0, 1, 5), {"relative": True}, "hexagonal_scan"),
((1, 0.2), {}, "time_scan"),
((9000, 10000, 1, 20, 0.1, 9500), {}, "xas_advanced_scan"),
],
)