removed bl chk to replace by states
CI for csaxs_bec / test (push) Has been cancelled

This commit is contained in:
x01dc
2026-03-09 14:59:28 +01:00
parent 3c50781101
commit c0c77648d4
2 changed files with 8 additions and 199 deletions
@@ -12,7 +12,6 @@ from bec_lib.pdf_writer import PDFWriter
from typeguard import typechecked
from csaxs_bec.bec_ipython_client.plugins.omny.omny_general_tools import (
BeamlineChecker,
OMNYTools,
PtychoReconstructor,
TomoIDManager,
@@ -40,7 +39,6 @@ class LamNI(LamNIOpticsMixin, LamniGuiTools):
self.init = LaMNIInitStages(client)
# Extracted collaborators
self.bl_chk = BeamlineChecker(client)
self.reconstructor = PtychoReconstructor(self.ptycho_reconstruct_foldername)
self.tomo_id_manager = TomoIDManager()
self.OMNYTools = OMNYTools(self.client)
@@ -538,7 +536,6 @@ class LamNI(LamNIOpticsMixin, LamniGuiTools):
print(f"Starting LamNI scan for angle {angle} in subtomo {subtomo_number}")
self._print_progress()
while not successful:
self.bl_chk._bl_chk_start()
if not self.special_angles:
self._current_special_angles = []
if self._current_special_angles:
@@ -565,10 +562,9 @@ class LamNI(LamNIOpticsMixin, LamniGuiTools):
for scan_nr in range(start_scan_number, end_scan_number):
self._write_tomo_scan_number(scan_nr, angle, subtomo_number)
if self.bl_chk._bl_chk_stop() and not error_caught:
#todo here bl chk
successful = True
else:
self.bl_chk._bl_chk_wait_until_recovered()
def _golden(self, ii, howmany_sorted, maxangle=360, reverse=False):
"""Return the ii-th golden ratio angle within sorted bunches and its subtomo number."""
@@ -2,6 +2,7 @@ import builtins
import datetime
import fcntl
import os
import socket
import subprocess
import sys
import termios
@@ -10,6 +11,7 @@ import time
import tty
from pathlib import Path
import epics
import numpy as np
from bec_lib import bec_logger
from rich import box
@@ -156,199 +158,6 @@ class OMNYTools:
import socket
class BeamlineChecker:
"""Monitors beamline health during scans.
Runs checks in a background thread and blocks scan progress
until beam conditions are restored if they fail.
Usage:
checker = BeamlineChecker(client)
checker._bl_chk_start()
# ... run scan ...
beam_was_ok = checker._bl_chk_stop()
if not beam_was_ok:
checker._bl_chk_wait_until_recovered()
"""
def __init__(self, client):
self.client = client
self.check_shutter = True
self.check_light_available = True
self.check_fofb = True
self._beam_is_okay = True
self._stop_event = None
self._thread = None
self._local_network_warned = False
self._check_msgs = []
# ------------------------------------------------------------------
# Public control interface
# ------------------------------------------------------------------
def bl_chk_status(self):
"""Print and return the current enabled/disabled state of all checks."""
if self._is_local_network():
print("Beamline checks cannot be performed on this network (129.129.98.x) — skipping.")
return {}
status = {
"shutter": self.check_shutter,
"fofb": self.check_fofb,
"light available": self.check_light_available,
}
print(
f"Shutter: {self.check_shutter}\n"
f"FOFB: {self.check_fofb}\n"
f"Light available: {self.check_light_available}"
)
return status
def bl_chk_enable_all(self):
"""Enable all beamline checks."""
self.check_shutter = True
self.check_light_available = True
self.check_fofb = True
self.bl_chk_status()
def bl_chk_disable_all(self):
"""Disable all beamline checks."""
self.check_shutter = False
self.check_light_available = False
self.check_fofb = False
self.bl_chk_status()
def bl_chk_enable_shutter(self):
"""Enable the shutter check."""
self.check_shutter = True
self.bl_chk_status()
def bl_chk_disable_shutter(self):
"""Disable the shutter check."""
self.check_shutter = False
self.bl_chk_status()
def bl_chk_enable_fofb(self):
"""Enable the fast orbit feedback check."""
self.check_fofb = True
self.bl_chk_status()
def bl_chk_disable_fofb(self):
"""Disable the fast orbit feedback check."""
self.check_fofb = False
self.bl_chk_status()
def bl_chk_enable_light(self):
"""Enable the light available check."""
self.check_light_available = True
self.bl_chk_status()
def bl_chk_disable_light(self):
"""Disable the light available check."""
self.check_light_available = False
self.bl_chk_status()
def _bl_chk_start(self):
"""Start the background beam check thread."""
self._beam_is_okay = True
self._stop_event = threading.Event()
self._thread = threading.Thread(target=self._poll, daemon=True)
self._thread.start()
def _bl_chk_stop(self) -> bool:
"""Stop the background thread and return whether beam was okay throughout."""
self._stop_event.set()
self._thread.join()
return self._beam_is_okay
def _bl_chk_wait_until_recovered(self):
"""Block until all beamline checks pass again, logging to SciLog."""
self._log_failure_to_scilog()
while True:
self._beam_is_okay = True
self._check_msgs = self._run_checks()
if self._beam_is_okay:
break
self._print_msgs()
time.sleep(1)
self._log_recovery_to_scilog()
# ------------------------------------------------------------------
# Internal
# ------------------------------------------------------------------
def _is_local_network(self) -> bool:
"""Return True if running on the 129.129.98.x subnet."""
try:
hostname = socket.gethostname()
ip = socket.gethostbyname(hostname)
return ip.startswith("129.129.98.")
except Exception:
return False
def _run_checks(self) -> list:
if self._is_local_network():
if not self._local_network_warned:
print("Beamline checks cannot be performed on this network (129.129.98.x) — skipping.")
self._local_network_warned = True
return []
msgs = []
dev = builtins.__dict__.get("dev")
try:
if self.check_shutter:
val = dev.x12sa_es1_shutter_status.read(cached=True)
if val["value"].lower() != "open":
self._beam_is_okay = False
msgs.append("Check beam failed: Shutter is closed.")
if self.check_light_available:
val = dev.sls_machine_status.read(cached=True)
if val["value"] not in ["Light Available", "Light-Available"]:
self._beam_is_okay = False
msgs.append("Check beam failed: Light not available.")
if self.check_fofb:
val = dev.sls_fast_orbit_feedback.read(cached=True)
if val["value"] != "running":
self._beam_is_okay = False
msgs.append("Check beam failed: Fast orbit feedback is not running.")
except Exception:
logger.warning("Failed to check beam.")
return msgs
def _poll(self):
while not self._stop_event.is_set():
self._check_msgs = self._run_checks()
if not self._beam_is_okay:
self._stop_event.set()
time.sleep(1)
def _print_msgs(self):
for msg in self._check_msgs:
logger.warning(msg)
def _log_failure_to_scilog(self):
self._print_msgs()
try:
bec = builtins.__dict__.get("bec")
msg = bec.logbook.LogbookMessage()
msg.add_text(
"<p><mark class='pen-red'><strong>Beamline checks failed at"
f" {str(datetime.datetime.now())}: {''.join(self._check_msgs)}</strong></mark></p>"
).add_tag(["BEC", "beam_check"])
self.client.logbook.send_logbook_message(msg)
except Exception:
logger.warning("Failed to send beam failure update to SciLog.")
def _log_recovery_to_scilog(self):
try:
bec = builtins.__dict__.get("bec")
msg = bec.logbook.LogbookMessage()
msg.add_text(
"<p><mark class='pen-red'><strong>Operation resumed at"
f" {str(datetime.datetime.now())}.</strong></mark></p>"
).add_tag(["BEC", "beam_check"])
self.client.logbook.send_logbook_message(msg)
except Exception:
logger.warning("Failed to send beam recovery update to SciLog.")
class PtychoReconstructor:
"""Writes ptychography reconstruction queue files after each scan projection.
@@ -389,6 +198,10 @@ class PtychoReconstructor:
name the queue file.
base_path (str): Root path under which the queue folder lives.
"""
if not self._accounts_match():
logger.warning("Active BEC account does not match system user — skipping queue file write.")
return
base_path = os.path.expanduser(base_path)
queue_path = Path(os.path.join(base_path, self.folder_name))
queue_path.mkdir(parents=True, exist_ok=True)