added check so gui only works with flomni

This commit is contained in:
x12sa
2026-07-07 10:41:40 +02:00
committed by holler
co-authored by holler
parent a718772e96
commit 5c4d405d7b
@@ -162,16 +162,30 @@ class TomoParamsWidget(BECWidget, QWidget):
super().__init__(parent=parent, **kwargs)
self.get_bec_shortcuts()
self._edit_mode = False
# widget refs populated by _build_params_panel
self._pw: dict[str, QWidget] = {} # key -> input widget
self._queue_dlg: Optional["TomoQueueDialog"] = None
# check whether the FlOMNI setup is active before building the UI
self._flomni_available = self._check_flomni_available()
self._build_ui()
# polling timer does NOT refresh params (avoid overwriting edits)
self._poll_timer = QTimer(self)
self._poll_timer.setInterval(self._POLL_INTERVAL_MS)
self._poll_timer.timeout.connect(self._on_poll)
self._poll_timer.start()
# initial load
self.refresh()
if self._flomni_available:
self._poll_timer.start()
self.refresh()
# ── setup detection ──────────────────────────────────────────────────────
def _check_flomni_available(self) -> bool:
"""
Return True if the FlOMNI setup is active in this BEC session.
Uses ``fsamroy`` (the FlOMNI-specific rotation stage) as the
discriminator — it is absent in OMNY and LamNI sessions.
"""
try:
return getattr(self.dev, "fsamroy", None) is not None
except Exception:
return False
# ── global-var I/O ───────────────────────────────────────────────────────
@@ -212,6 +226,19 @@ class TomoParamsWidget(BECWidget, QWidget):
root = QVBoxLayout(self)
root.setSpacing(6)
if not self._flomni_available:
lbl = QLabel(
"⚠ FlOMNI setup not detected in this BEC session.\n\n"
"This widget is only meaningful when the FlOMNI\n"
"BEC session is active (fsamroy device present)."
)
lbl.setAlignment(Qt.AlignmentFlag.AlignCenter)
lbl.setWordWrap(True)
root.addStretch()
root.addWidget(lbl)
root.addStretch()
return
# scrollable params panel
params_scroll = QScrollArea()
params_scroll.setWidgetResizable(True)
@@ -230,7 +257,6 @@ class TomoParamsWidget(BECWidget, QWidget):
self._btn_queue.setToolTip("Open the tomo queue manager")
self._btn_queue.clicked.connect(self._show_queue_dialog)
root.addWidget(self._btn_queue)
self._queue_dlg: Optional["TomoQueueDialog"] = None
def _build_header(self) -> QGroupBox:
box = QGroupBox("Sample")
@@ -340,6 +366,13 @@ class TomoParamsWidget(BECWidget, QWidget):
form = QFormLayout(box)
form.setLabelAlignment(Qt.AlignmentFlag.AlignRight)
self._add_int(
form,
"_numprj_type3",
"Projections per sub-tomo (type 3)",
min_=1,
max_=10000,
)
self._add_int(
form, "golden_ratio_bunch_size", "Bunch size (type 2 only)", min_=1, max_=10000
)
@@ -448,6 +481,15 @@ class TomoParamsWidget(BECWidget, QWidget):
self._pw["_requested_total"].blockSignals(False)
self._update_projection_preview()
# type-3: derive projections-per-subtomo from stored tomo_angle_stepsize
# (flomni uses 180 / tomo_angle_stepsize for type 3, hardcoded to 180)
stepsize = float(params.get("tomo_angle_stepsize", 10.0))
numprj_t3 = int(180.0 / stepsize) if stepsize > 0 else 18
self._pw["_numprj_type3"].blockSignals(True)
self._pw["_numprj_type3"].setValue(numprj_t3)
self._pw["_numprj_type3"].blockSignals(False)
self._update_type_visibility(type_val)
def _read_fields(self) -> dict[str, Any]:
@@ -470,12 +512,19 @@ class TomoParamsWidget(BECWidget, QWidget):
elif isinstance(widget, QComboBox):
params[key] = widget.currentData()
# derive tomo_angle_stepsize from requested_total + angle_range
# derive tomo_angle_stepsize from requested_total + angle_range (type 1)
angle_range = int(params.get("tomo_angle_range", 180))
requested = self._pw["_requested_total"].value()
stepsize = _requested_to_stepsize(angle_range, requested)
params["tomo_angle_stepsize"] = stepsize
# type 3: override tomo_angle_stepsize from projections-per-subtomo
# (flomni uses 180 / numprj for type 3)
if params.get("tomo_type") == 3:
numprj = self._pw["_numprj_type3"].value()
if numprj > 0:
params["tomo_angle_stepsize"] = 180.0 / numprj
# single_point forces stitch to 0
if params.get("single_point_instead_of_fermat_scan"):
params["stitch_x"] = 0
@@ -508,19 +557,30 @@ class TomoParamsWidget(BECWidget, QWidget):
def _update_type_visibility(self, tomo_type: int) -> None:
self._sec_type1.setVisible(tomo_type == 1)
self._sec_type23.setVisible(tomo_type in (2, 3))
# bunch_size is type-2 only; find its row in the form layout
bunch_widget = self._pw.get("golden_ratio_bunch_size")
if bunch_widget is not None:
bunch_widget.setVisible(tomo_type == 2)
# also hide the label in the form layout
form = self._sec_type23.layout()
if isinstance(form, QFormLayout):
idx = form.indexOf(bunch_widget)
if idx >= 0:
row, role = form.getItemPosition(idx)
label_item = form.itemAt(row, QFormLayout.ItemRole.LabelRole)
if label_item and label_item.widget():
label_item.widget().setVisible(tomo_type == 2)
# _numprj_type3: only visible for type 3
_w__numprj_type3 = self._pw.get("_numprj_type3")
if _w__numprj_type3 is not None:
_w__numprj_type3.setVisible(tomo_type == 3)
_form = self._sec_type23.layout()
if isinstance(_form, QFormLayout):
_idx = _form.indexOf(_w__numprj_type3)
if _idx >= 0:
_row, _role = _form.getItemPosition(_idx)
_lbl = _form.itemAt(_row, QFormLayout.ItemRole.LabelRole)
if _lbl and _lbl.widget():
_lbl.widget().setVisible(tomo_type == 3)
# golden_ratio_bunch_size: only visible for type 2
_w_golden_ratio_bunch_size = self._pw.get("golden_ratio_bunch_size")
if _w_golden_ratio_bunch_size is not None:
_w_golden_ratio_bunch_size.setVisible(tomo_type == 2)
_form = self._sec_type23.layout()
if isinstance(_form, QFormLayout):
_idx = _form.indexOf(_w_golden_ratio_bunch_size)
if _idx >= 0:
_row, _role = _form.getItemPosition(_idx)
_lbl = _form.itemAt(_row, QFormLayout.ItemRole.LabelRole)
if _lbl and _lbl.widget():
_lbl.widget().setVisible(tomo_type == 2)
# ── type-1 projection preview ─────────────────────────────────────────────