From 75c857ae4ba1bf10b7cd8dd847884562eb9ef296 Mon Sep 17 00:00:00 2001 From: David Perl Date: Wed, 9 Sep 2026 16:22:12 +0200 Subject: [PATCH 1/6] fix: don't require lock to cancel --- src/aare/daq/server.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/aare/daq/server.py b/src/aare/daq/server.py index 60b293af..13dbb7c5 100644 --- a/src/aare/daq/server.py +++ b/src/aare/daq/server.py @@ -1723,7 +1723,6 @@ async def set_smart_params(p: SimpleScanParameters, token: str = Depends(oauth2_ @app.post("/scan/cancel") -@needs_hw_lock async def cancel(token: str = Depends(oauth2_scheme)): """ Cancel the currently running scan or automation. -- 2.54.0 From c91ab3d39606ebb82b0f57292a0407a760533a75 Mon Sep 17 00:00:00 2001 From: David Perl Date: Wed, 9 Sep 2026 16:33:48 +0200 Subject: [PATCH 2/6] fix: don't show beamline is busy error message --- src/aare/gui/threads/daq_worker.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/aare/gui/threads/daq_worker.py b/src/aare/gui/threads/daq_worker.py index a5989aa7..d395fe07 100644 --- a/src/aare/gui/threads/daq_worker.py +++ b/src/aare/gui/threads/daq_worker.py @@ -672,10 +672,7 @@ class DAQWorker(QObject): elif status in (404, 410, 417): self.sample_missing.emit(error_info.message) elif error_info.code in QUIET_OPERATION_ERROR_CODES: - # Blocking-but-benign (e.g. "Beamline is busy"): inform quietly, - # no modal pop-up and no automation pause. - logger.info(f"Action unavailable: {error_info.message}") - self.status_message.emit(error_info.message, True) + pass else: logger.error(f"{error_info.message}") title = self._operation_error_title(error_info.exception_class) -- 2.54.0 From ade180b130c0e07b87874b3c5eff3125977ddcc5 Mon Sep 17 00:00:00 2001 From: David Perl Date: Wed, 9 Sep 2026 16:52:58 +0200 Subject: [PATCH 3/6] feat: add flux to macros --- src/aare/beamline_dispatch/protocols.py | 3 +++ src/aare/beamline_dispatch/x06da/beamline_dispatch.py | 7 +++++++ src/aare/beamline_dispatch/x10sa/beamline_dispatch.py | 10 ++++++++++ src/aare/daq/devices.py | 9 +-------- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/aare/beamline_dispatch/protocols.py b/src/aare/beamline_dispatch/protocols.py index b833dda8..fbd1f111 100644 --- a/src/aare/beamline_dispatch/protocols.py +++ b/src/aare/beamline_dispatch/protocols.py @@ -31,6 +31,9 @@ class BecMacros(ABC): @staticmethod @abstractmethod def auto_exposure(): ... + @staticmethod + @abstractmethod + def full_flux_ph_per_s() -> float: ... class Geometry(ABC): diff --git a/src/aare/beamline_dispatch/x06da/beamline_dispatch.py b/src/aare/beamline_dispatch/x06da/beamline_dispatch.py index 89cec67c..e88448d7 100644 --- a/src/aare/beamline_dispatch/x06da/beamline_dispatch.py +++ b/src/aare/beamline_dispatch/x06da/beamline_dispatch.py @@ -36,6 +36,11 @@ class X06daBecMacros(BecMacros): self.mono_pitch_scan = mono_pitch_scan self.auto_exposure = auto_exposure + def full_flux_ph_per_s(): + return 400_000_000_000 + + self.full_flux_ph_per_s = full_flux_ph_per_s + @staticmethod def save_and_reload() -> tuple[Any, Any]: ... @staticmethod @@ -50,6 +55,8 @@ class X06daBecMacros(BecMacros): def mono_pitch_scan(plot=True): ... @staticmethod def auto_exposure(): ... + @staticmethod + def full_flux_ph_per_s() -> float: ... class X06daGeometry(DefaultGeometry): diff --git a/src/aare/beamline_dispatch/x10sa/beamline_dispatch.py b/src/aare/beamline_dispatch/x10sa/beamline_dispatch.py index c721a7cb..fea4fe19 100644 --- a/src/aare/beamline_dispatch/x10sa/beamline_dispatch.py +++ b/src/aare/beamline_dispatch/x10sa/beamline_dispatch.py @@ -20,6 +20,9 @@ class X10SaBecMacros(BecMacros): save_and_reload, save_current_position, ) + from pxii_bec.macros.flux_macros import ( + bpm2flux, # pyright: ignore[reportMissingImports, reportMissingModuleSource] + ) from pxii_bec.macros.katscripts import ( # pyright: ignore[reportMissingImports, reportMissingModuleSource] auto_exposure, ) @@ -53,6 +56,11 @@ class X10SaBecMacros(BecMacros): self.auto_exposure = _auto_exposure + def full_flux_ph_per_s(): + return bpm2flux()[1] + + self.full_flux_ph_per_s = full_flux_ph_per_s + @staticmethod def save_and_reload() -> tuple[Any, Any]: ... @staticmethod @@ -67,6 +75,8 @@ class X10SaBecMacros(BecMacros): def mono_pitch_scan(plot=True): ... @staticmethod def auto_exposure(): ... + @staticmethod + def full_flux_ph_per_s() -> float: ... class _1dModel(BeamCenterModel): diff --git a/src/aare/daq/devices.py b/src/aare/daq/devices.py index c655169d..0b3071fc 100644 --- a/src/aare/daq/devices.py +++ b/src/aare/daq/devices.py @@ -206,18 +206,11 @@ class BeamlineDevices: @property def flux(self) -> float: - # TODO FLUX - if self._beamline == MXBeamline.X10SA: - return self.bec_worker.get_flux_x10sa() return self.transmission * self.full_flux @property def full_flux(self) -> float: - # TODO wire real flux - i0 needed - max_flux = cfg_get("daq.maximum_flux") - if max_flux is None: - return 0.0 - return max_flux + return self._dispatch.bec_macros.full_flux_ph_per_s() # Cryojet @property -- 2.54.0 From acdee693ce5030884aae637f7a3acc2e470a9271 Mon Sep 17 00:00:00 2001 From: David Perl Date: Wed, 9 Sep 2026 17:18:00 +0200 Subject: [PATCH 4/6] fix: display flux more nicely --- pyproject.toml | 2 +- src/aare/daq/devices.py | 8 +++++++- src/aare/gui/widgets/status_bar.py | 11 +++++++++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5e9b1cdf..c61e8620 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ readme = "README.md" requires-python = ">=3.11" dependencies = [ "uv", - "aarecommon>=0.7.3", + "aarecommon>=0.8.0", "pydantic>=2.11", "numpy", "jfjoch_client>=1.0.0rc165", diff --git a/src/aare/daq/devices.py b/src/aare/daq/devices.py index 0b3071fc..c5ad2d3b 100644 --- a/src/aare/daq/devices.py +++ b/src/aare/daq/devices.py @@ -4,6 +4,7 @@ import time from aarecommon.config.beamline import cfg_get from aarecommon.config.logger import setup_logger from aarecommon.config.logger_events import log_timing +from aarecommon.config.util import suppress_output from aarecommon.math.coordinate import AerotechCoordinate, SmargonCoordinate from aarecommon.models.beamline import MXBeamline from aarecommon.models.models import BeamlineStateEnum, SampleCameraSettings, StagePositionEnum @@ -210,7 +211,12 @@ class BeamlineDevices: @property def full_flux(self) -> float: - return self._dispatch.bec_macros.full_flux_ph_per_s() + try: + with suppress_output(): + return self._dispatch.bec_macros.full_flux_ph_per_s() + except Exception as e: + logger.error(f"Could not get flux from BEC macro {e}") + return 9.99e12 # Cryojet @property diff --git a/src/aare/gui/widgets/status_bar.py b/src/aare/gui/widgets/status_bar.py index e235453a..9b88739d 100644 --- a/src/aare/gui/widgets/status_bar.py +++ b/src/aare/gui/widgets/status_bar.py @@ -67,7 +67,7 @@ class StatusBar(QStatusBar): self.sharpness = ValueLabel("Samcam image sharpness", "", self) self.samcam_fps = ValueLabel("Samcam FPS", "fps", self) - self.flux = ValueLabel("Flux", "x 109 ph/s", self) + self.flux = ValueLabel("Flux", "ph/s", self) self.transmission = ValueLabel("Transmission", "", self) self.ring_current = ValueLabel("Ring current", "mA", self) self.wvl = ValueLabel("Wavelength", "Å", self) @@ -172,7 +172,14 @@ class StatusBar(QStatusBar): if status.bl.flux_ph_s is None: self.flux.set_value("0") else: - self.flux.set_value(f"{(status.bl.flux_ph_s / 1e9):.0f}") + try: + num = f"{status.bl.flux_ph_s:.2E}" + mod, exp = num.split("E") + self.flux.set_value(f"{mod} x 10{int(exp)}") + except Exception as e: + logger.error(f"Error parsing flux result: {e}") + self.flux.set_value(f"{status.bl.flux_ph_s:.2E}") + if status.bl.transmission is None: self.transmission.set_value("(moving)") -- 2.54.0 From d406e131035e4429345d9d44ddb78c063f267182 Mon Sep 17 00:00:00 2001 From: David Perl Date: Wed, 9 Sep 2026 18:03:10 +0200 Subject: [PATCH 5/6] style: format --- src/aare/daq/devices.py | 2 +- src/aare/gui/widgets/status_bar.py | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/aare/daq/devices.py b/src/aare/daq/devices.py index c5ad2d3b..4548af52 100644 --- a/src/aare/daq/devices.py +++ b/src/aare/daq/devices.py @@ -214,7 +214,7 @@ class BeamlineDevices: try: with suppress_output(): return self._dispatch.bec_macros.full_flux_ph_per_s() - except Exception as e: + except Exception as e: #noqa logger.error(f"Could not get flux from BEC macro {e}") return 9.99e12 diff --git a/src/aare/gui/widgets/status_bar.py b/src/aare/gui/widgets/status_bar.py index 9b88739d..1926ef8e 100644 --- a/src/aare/gui/widgets/status_bar.py +++ b/src/aare/gui/widgets/status_bar.py @@ -169,18 +169,17 @@ class StatusBar(QStatusBar): def update_daq_status(self, status: DAQStatusModel): try: self._status = status - if status.bl.flux_ph_s is None: + if status.bl.flux_ph_s is None or status.bl.transmission is None: self.flux.set_value("0") else: try: - num = f"{status.bl.flux_ph_s:.2E}" + num = f"{(status.bl.flux_ph_s / status.bl.transmission):.2E}" mod, exp = num.split("E") self.flux.set_value(f"{mod} x 10{int(exp)}") - except Exception as e: + except Exception as e: #noqa logger.error(f"Error parsing flux result: {e}") self.flux.set_value(f"{status.bl.flux_ph_s:.2E}") - if status.bl.transmission is None: self.transmission.set_value("(moving)") else: -- 2.54.0 From 5865d4a801d0da632adfdbca81c2783ed2dc2747 Mon Sep 17 00:00:00 2001 From: David Perl Date: Wed, 9 Sep 2026 18:10:09 +0200 Subject: [PATCH 6/6] fix: implement simulated flux --- src/aare/beamline_dispatch/simulated/beamline_dispatch.py | 7 +++++-- src/aare/daq/devices.py | 2 +- src/aare/gui/widgets/status_bar.py | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/aare/beamline_dispatch/simulated/beamline_dispatch.py b/src/aare/beamline_dispatch/simulated/beamline_dispatch.py index ed14548e..fe06ba2f 100644 --- a/src/aare/beamline_dispatch/simulated/beamline_dispatch.py +++ b/src/aare/beamline_dispatch/simulated/beamline_dispatch.py @@ -17,8 +17,8 @@ class SimulatedBecMacros(BecMacros): @staticmethod def save_current_position(device, position, axis=None, force=False, max_delta=0.5) -> None: ... @staticmethod - def init_beamline_environment() -> tuple[Any, Any, Any]: - return (None, None, None) + def init_beamline_environment() -> tuple[Any, Any]: + return (None, None) @staticmethod def bl_energy(energy_ev, move_gap=True, mono_scan=True, plot=True): ... @@ -28,6 +28,9 @@ class SimulatedBecMacros(BecMacros): def mono_pitch_scan(plot=True): ... @staticmethod def auto_exposure(): ... + @staticmethod + def full_flux_ph_per_s() -> float: + return 42 class SimulatedDispatch(DefaultDispatch): diff --git a/src/aare/daq/devices.py b/src/aare/daq/devices.py index 4548af52..7a2416ab 100644 --- a/src/aare/daq/devices.py +++ b/src/aare/daq/devices.py @@ -214,7 +214,7 @@ class BeamlineDevices: try: with suppress_output(): return self._dispatch.bec_macros.full_flux_ph_per_s() - except Exception as e: #noqa + except Exception as e: # noqa logger.error(f"Could not get flux from BEC macro {e}") return 9.99e12 diff --git a/src/aare/gui/widgets/status_bar.py b/src/aare/gui/widgets/status_bar.py index 1926ef8e..5fe1b790 100644 --- a/src/aare/gui/widgets/status_bar.py +++ b/src/aare/gui/widgets/status_bar.py @@ -176,7 +176,7 @@ class StatusBar(QStatusBar): num = f"{(status.bl.flux_ph_s / status.bl.transmission):.2E}" mod, exp = num.split("E") self.flux.set_value(f"{mod} x 10{int(exp)}") - except Exception as e: #noqa + except Exception as e: # noqa logger.error(f"Error parsing flux result: {e}") self.flux.set_value(f"{status.bl.flux_ph_s:.2E}") -- 2.54.0