diff --git a/csaxs_bec/bec_ipython_client/plugins/LamNI/LamNI_webpage_generator.py b/csaxs_bec/bec_ipython_client/plugins/LamNI/LamNI_webpage_generator.py index a77e77c..a5a1708 100644 --- a/csaxs_bec/bec_ipython_client/plugins/LamNI/LamNI_webpage_generator.py +++ b/csaxs_bec/bec_ipython_client/plugins/LamNI/LamNI_webpage_generator.py @@ -49,6 +49,22 @@ class LamniWebpageGenerator(WebpageGeneratorBase): sample name, and measurement settings. """ + # LamNI has no persisted parameter-snapshot job queue (unlike flomni + # and, later, omny) — the "Tomo queue" card and its global-var read + # are skipped entirely for this setup. + HAS_TOMO_QUEUE = False + + # LamNI's tomo scans come in two flavours: a 2-subtomo and an + # 8-subtomo variant, both using the same equally-spaced-grid formula + # as flomni's type 1 (just with a different sub-tomo count). + # TODO: replace the placeholder keys (1, 2) with whatever values + # progress["tomo_type"] actually takes for LamNI once the producer + # side (LamNI equivalent of flomni.py) defines them. + TOMO_TYPES = { + 1: {"kind": "equally_spaced_grid", "n_subtomos": 2}, + 2: {"kind": "equally_spaced_grid", "n_subtomos": 8}, + } + # TODO: fill in LamNI-specific device paths # label -> dotpath under device_manager.devices _TEMP_MAP = { @@ -86,4 +102,4 @@ class LamniWebpageGenerator(WebpageGeneratorBase): return { "type": "lamni", # LamNI-specific data here - } + } \ No newline at end of file diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_webpage_generator.py b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_webpage_generator.py index 6825d73..103acaf 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_webpage_generator.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_webpage_generator.py @@ -574,8 +574,32 @@ class WebpageGeneratorBase: Common webpage generator. Subclass and override: _collect_setup_data() -- return dict of instrument-specific data _logo_path() -- return Path to logo PNG, or None for text fallback + + Setup capability flags (override on subclass as needed): + HAS_TOMO_QUEUE -- whether this instrument exposes the persisted + parameter-snapshot job queue (global var + "tomo_queue" + the "Tomo queue" UI card). + NOT to be confused with BEC's own primary scan + queue (queue_status / queue_locks in _cycle()), + which every setup has and which stays common. + TOMO_TYPES -- dict describing this instrument's tomography + scan types, keyed by the value progress["tomo_type"] + takes. Used by the UI to compute total-projection + counts for queued jobs without hardcoding a + per-instrument formula in JS. Recognised "kind"s: + "equally_spaced_grid" (params: n_subtomos) + total = floor(angle_range / angle_stepsize) * n_subtomos + "golden_capped" + total = golden_max_number_of_projections """ + HAS_TOMO_QUEUE = True + TOMO_TYPES = { + 1: {"kind": "equally_spaced_grid", "n_subtomos": 8}, + 2: {"kind": "golden_capped"}, + 3: {"kind": "golden_capped"}, + } + def __init__( self, bec_client, @@ -647,7 +671,9 @@ class WebpageGeneratorBase: # Copy logo once at startup — HTML is also written once here, # not every cycle, since it is a static shell that only loads status.json. self._copy_logo() - (self._output_dir / "status.html").write_text(_render_html(_PHONE_NUMBERS)) + (self._output_dir / "status.html").write_text( + _render_html(_PHONE_NUMBERS, self.HAS_TOMO_QUEUE, self.TOMO_TYPES) + ) # Check whether the active BEC account matches the session user on the # remote server. If not, clear session.htpasswd so the old user loses @@ -1028,11 +1054,16 @@ class WebpageGeneratorBase: else max(0.0, _epoch() - self._last_active_time) ) - # ── Tomo queue ─────────────────────────────────────────────── + # ── Tomo queue (setup-specific; see HAS_TOMO_QUEUE) ───────────── # Persisted list of parameter-snapshot jobs (global var "tomo_queue"). # Each job: {"label": str, "params": {...}, # "status": pending|running|incomplete|done, "added_at": ISO str} - tomo_queue = self._bec.get_global_var("tomo_queue") or [] + # Instruments without this feature (e.g. LamNI) never touch the + # global var and always report an empty queue. + if self.HAS_TOMO_QUEUE: + tomo_queue = self._bec.get_global_var("tomo_queue") or [] + else: + tomo_queue = [] # ── Reconstruction queue ────────────────────────────────────── recon = self._collect_recon_data() @@ -1453,7 +1484,7 @@ def make_webpage_generator(bec_client, **kwargs): # Theme is stored in localStorage and applied via data-theme on . # --------------------------------------------------------------------------- -def _render_html(phone_numbers: list) -> str: +def _render_html(phone_numbers: list, has_tomo_queue: bool = True, tomo_types: dict = None) -> str: phones_html = "\n".join( f'