wip
CI for debye_bec / test (push) Failing after 56s

This commit is contained in:
x01da
2026-06-15 12:41:25 +02:00
parent 209a274e11
commit 229981043f
2 changed files with 120 additions and 19 deletions
@@ -2,9 +2,12 @@
Data Viewer: Custom BEC widget to view data from scans.
"""
import os
import subprocess
import sys
from datetime import datetime
from functools import partial
from typing import Literal, Optional, cast
from bec_lib import bec_logger
from bec_lib.endpoints import MessageEndpoints
@@ -36,6 +39,8 @@ from debye_bec.bec_widgets.widgets.data_viewer.viewer import HDF5Viewer
logger = bec_logger.logger
MAX_HIST_LEN = 100
class DataViewer(BECWidget, QWidget):
"""
@@ -43,7 +48,7 @@ class DataViewer(BECWidget, QWidget):
"""
PLUGIN = True
ICON_NAME = "lightbulb"
ICON_NAME = "database_search" # TODO: This does not work, choose correct icon
def __init__(self, *arg, parent=None, **kwargs):
super().__init__(parent=parent, theme_update=True, *arg, **kwargs)
@@ -76,11 +81,33 @@ class DataViewer(BECWidget, QWidget):
self.input.scan_sel.currentItemChanged_connect(self.scan_sel_changed)
self.input.load_button.clicked_connect(self.load_dataset)
self.input.unload_button.clicked_connect(self.unload_all_datasets)
self.input.open_fm_button.clicked_connect(self.open_in_file_manager)
def apply_theme(self, theme: Literal["dark", "light"]):
"""
Apply the theme
Args:
theme (str): Theme, either "dark" or "light"
"""
self.viewer.apply_theme(theme)
@SafeSlot()
def scan_sel_changed(self, *_, **kwargs):
self.current_row = kwargs["value"]().row()
@SafeSlot()
def open_in_file_manager(self, *_):
scan = self.history[self.current_row]
filepath = scan["file_components"][0].decode().rsplit("/", 1)[0]
subprocess.Popen(
["xdg-open", filepath],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
stdin=subprocess.DEVNULL,
start_new_session=True,
)
@SafeSlot()
def load_dataset(
self, *_
@@ -121,12 +148,12 @@ class DataViewer(BECWidget, QWidget):
self.input.scan_sel.clear()
# Get the length of the scan history, which is 0 when the bec server was started
# and no scan has finished yet. Limit the history to the latest 20 scans.
max_scans = min(len(self.client.history), 20)
for n in range(1, max_scans): # last scans, up to 20
max_scans = min(len(self.client.history), MAX_HIST_LEN)
for n in range(1, max_scans): # last scans, limited by MAX_HIST_LEN
# logger.info(self.client.history[-n].metadata["bec"]["status"])
start_time = self.client.history[-n].metadata["start_time"]
end_time = self.client.history[-n].metadata["end_time"]
logger.info(type(start_time))
# logger.info(type(start_time))
scan_data = self.client.history[-n].metadata["bec"]
# logger.info(scan_data)
scan_number = scan_data["scan_number"]
@@ -160,7 +187,7 @@ class DataViewer(BECWidget, QWidget):
tags.append((status, "#656365"))
tags.append((self.duration_string(start_time, end_time), "#656365"))
self.input.scan_sel.addTaggedItem(label=str(scan_number), tags=tags)
logger.info(f"Scan history: {self.history}")
# logger.info(f"Scan history: {self.history}")
class InputPanel(QWidget):
@@ -168,29 +195,44 @@ class InputPanel(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self._layout = QVBoxLayout(self)
self._layout.setSizeConstraint(QLayout.SetFixedSize) # type: ignore
self._layout = QHBoxLayout(self)
# self._layout.setSizeConstraint(QLayout.SetFixedSize) # type: ignore
# Scan selection
self.scan_sel = ListWidget("scan_sel", "Scan", ["Si", "Rh", "Pt"])
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)
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.addStretch()
# Assemble complete scan selection group
self.input_group = Group(
"Scan selection", [self.scan_sel, self.load_button, self.unload_button]
"Scan selection", [self._button_layout, self.scan_sel], orientation="horizontal"
)
self._layout.addWidget(self.input_group)
self._layout.addStretch()
# self._layout.addStretch()
class Group(QGroupBox):
def __init__(self, label, widgets):
def __init__(self, label, objs, orientation="vertical"):
super().__init__(label)
self.layout = QVBoxLayout(self) # type: ignore
for widget in widgets:
self.layout.addWidget(widget) # type: ignore
if orientation == "vertical":
self._layout = QVBoxLayout(self) # type: ignore
elif orientation == "horizontal": # assume horizontal
self._layout = QHBoxLayout(self) # type: ignore
else:
raise ValueError(f"Orientation {orientation} is not supported!")
for obj in objs:
if isinstance(obj, QWidget):
self._layout.addWidget(obj) # type: ignore
elif isinstance(obj, QLayout):
self._layout.addLayout(obj)
class ListWidget(QWidget):
@@ -206,7 +248,7 @@ class ListWidget(QWidget):
# self.label.setWordWrap(True)
# layout.addWidget(self.label)
self.value = TaggedListWidget()
self.value.setFixedWidth(400)
# self.value.setFixedWidth(400)
# for entry in enums:
# self.value.addItem(entry)
layout.addWidget(self.value)
@@ -2,15 +2,19 @@
HDF5 Viewer — qtpy + pyqtgraph + h5py
"""
from typing import Literal, Optional, cast
import h5py
import numpy as np
import pyqtgraph as pg
from bec_lib import bec_logger
from bec_qthemes import material_icon
from bec_widgets.utils.colors import Colors
from qtpy.QtCore import Qt
from qtpy.QtGui import QColor, QFont
from qtpy.QtWidgets import (
QAbstractItemView,
QApplication,
QGroupBox,
QHBoxLayout,
QHeaderView,
@@ -58,9 +62,9 @@ def _styled_plot_widget(**kwargs) -> pg.PlotWidget:
pw = pg.PlotWidget(**kwargs)
# pw.setBackground(pg.mkColor(*PG_PLOT_BG))
ax = pw.getPlotItem()
for side in ("left", "bottom", "right", "top"):
ax.getAxis(side).setPen(pg.mkPen(color=PG_GRID, width=1))
ax.getAxis(side).setTextPen(pg.mkPen(color=PG_TEXT))
# for side in ("left", "bottom", "right", "top"):
# ax.getAxis(side).setPen(pg.mkPen(color=PG_GRID, width=1))
# ax.getAxis(side).setTextPen(pg.mkPen(color=PG_TEXT))
ax.showGrid(x=True, y=True, alpha=0.25)
return pw
@@ -171,6 +175,9 @@ class DataPanel(QWidget):
self.stack_layout.setContentsMargins(0, 0, 0, 0)
self._layout.addWidget(self.stack, 1)
self.plot = None
self.images = []
self._current_data = None
self._show_empty()
@@ -246,6 +253,8 @@ class DataPanel(QWidget):
x = np.arange(row_data.size, dtype=np.float32)
pw = _styled_plot_widget()
self.plot = pw
self.apply_theme()
pw.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
plot_item = pw.getPlotItem()
@@ -308,10 +317,49 @@ class DataPanel(QWidget):
else:
self.stack_layout.addWidget(pw)
def apply_theme(self, theme: Optional[Literal["dark", "light"]] = None):
"""
Apply the theme
Args:
theme (Optional[str]): Theme, either "dark", "light", or None. Defaults to None.
"""
if theme is None:
app = QApplication.instance()
theme = app.theme.theme # type: ignore
bg_color = pg.getConfigOption("background")
fg_color = pg.getConfigOption("foreground")
try: # TODO: Remove try/except (plot or image might already be deleted!)
n_curves = len(self.plot.listDataItems())
colors = Colors.golden_angle_color(
colormap="plasma", num=max(10, n_curves + 1), format="HEX"
)
for idx, curve in enumerate(self.plot.listDataItems()):
curve.setPen(pg.mkPen(color=colors[idx]))
# Background
self.plot.setBackground(bg_color)
# Axes (tick marks, tick labels, axis line)
for axis in ["left", "bottom", "right", "top"]:
ax = self.plot.getAxis(axis)
ax.setPen(pg.mkPen(color=fg_color))
ax.setTextPen(pg.mkPen(color=fg_color))
except:
pass
for image in self.images:
try:
image.getView().setBackgroundColor(bg_color)
image.ui.histogram.setBackground(bg_color)
except:
pass
# ── 2-D image ──────────────────────────────────────────────────────────
def _show_image_2d(self, data):
self._clear_stack()
self.images = []
squeezed = np.squeeze(data)
if squeezed.ndim > 2:
squeezed = squeezed.reshape(-1, squeezed.shape[-1])
@@ -321,8 +369,10 @@ class DataPanel(QWidget):
# ImageView gives us colorbar + histogram + zoom for free
iv = pg.ImageView()
iv.getView().setBackgroundColor(pg.mkColor(*PG_BG))
iv.ui.histogram.setBackground(pg.mkColor(*PG_PLOT_BG))
self.images.append(iv)
self.apply_theme()
# iv.getView().setBackgroundColor(pg.mkColor(*PG_BG))
# iv.ui.histogram.setBackground(pg.mkColor(*PG_PLOT_BG))
iv.ui.roiBtn.hide()
iv.ui.menuBtn.hide()
@@ -396,6 +446,15 @@ class HDF5Viewer(QMainWindow):
if filepath:
self.load_files([filepath])
def apply_theme(self, theme: Literal["dark", "light"]):
"""
Apply the theme
Args:
theme (str): Theme, either "dark" or "light"
"""
self.data_panel.apply_theme(theme)
def load_files(self, filepaths: list[str]):
"""Open one or more HDF5 files and add each as a top-level tree node."""
for f in filepaths: