feat(LamNI): add ring-progress display for tomo_alignment_scan()
tomo_alignment_scan() had no GUI feedback at all -- just console prints -- unlike the real tomogram, which already drives a RingProgressBar via lamnigui_show_progress(). Add the same kind of single-ring display for the 12-angle alignment loop (lamnigui_show_alignment_progress()/_lamnigui_update_alignment_progress()), backed by its own alignment_scan_progress global var rather than tomo_progress, so anything watching tomo_progress for the real tomogram (heartbeat/idle-time tracking) never sees alignment-scan writes mixed in.
This commit is contained in:
@@ -25,6 +25,7 @@ class LamniGuiTools:
|
||||
self.lamni_window = None
|
||||
self.text_box = None
|
||||
self.progressbar = None
|
||||
self.alignment_progressbar = None
|
||||
self.xeyegui = None
|
||||
self.pdf_viewer = None
|
||||
self.idle_text_box = None
|
||||
@@ -72,6 +73,7 @@ class LamniGuiTools:
|
||||
if hasattr(self.gui, "lamni"):
|
||||
self.gui.lamni.delete_all(timeout=self.GUI_RPC_TIMEOUT)
|
||||
self.progressbar = None
|
||||
self.alignment_progressbar = None
|
||||
self.text_box = None
|
||||
self.xeyegui = None
|
||||
self.pdf_viewer = None
|
||||
@@ -288,6 +290,48 @@ class LamniGuiTools:
|
||||
text += f"\n Hook: {hook_description}"
|
||||
self.progressbar.set_center_label(text)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Alignment scan progress bar
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def lamnigui_show_alignment_progress(self):
|
||||
"""Open (or raise) a single-ring progress bar for tomo_alignment_scan().
|
||||
|
||||
A separate dock/widget from lamnigui_show_progress() (the real
|
||||
tomogram's 3-ring bar) -- kept distinct since it's backed by its
|
||||
own global var (see LamNI.alignment_scan_progress).
|
||||
"""
|
||||
self.lamnigui_show_gui()
|
||||
if self._lamnigui_is_missing("alignment_progressbar"):
|
||||
self.lamnigui_remove_all_docks()
|
||||
self.alignment_progressbar = self.gui.lamni.new(
|
||||
"RingProgressBar", timeout=self.GUI_RPC_TIMEOUT
|
||||
)
|
||||
# Single ring: alignment-scan angle progress (manual update)
|
||||
self.alignment_progressbar.add_ring().set_update("manual")
|
||||
|
||||
self._lamnigui_update_alignment_progress()
|
||||
|
||||
def _lamnigui_update_alignment_progress(self):
|
||||
"""Update the alignment-scan progress ring and centre label from
|
||||
self.alignment_scan_progress (see LamNI.alignment_scan_progress)."""
|
||||
if self.alignment_progressbar is None:
|
||||
return
|
||||
|
||||
ring = self.alignment_progressbar.rings[0]
|
||||
total = self.alignment_scan_progress["total_angles"]
|
||||
done = self.alignment_scan_progress["angle_index"]
|
||||
progress = done / total * 100 if total else 0
|
||||
ring.set_value(progress)
|
||||
|
||||
angle = self.alignment_scan_progress.get("angle", 0.0)
|
||||
text = (
|
||||
f"Alignment scan progress:\n"
|
||||
f" Angle {done}/{total}\n"
|
||||
f" Current angle: {angle:.1f} deg"
|
||||
)
|
||||
self.alignment_progressbar.set_center_label(text)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from bec_lib.client import BECClient
|
||||
|
||||
@@ -109,6 +109,18 @@ class _ProgressProxy:
|
||||
return self._load()
|
||||
|
||||
|
||||
class _AlignmentScanProgressProxy(_ProgressProxy):
|
||||
"""Same dict-proxy pattern as _ProgressProxy, but for tomo_alignment_scan()'s
|
||||
own progress (angle N/12) -- kept in its own global var, deliberately
|
||||
separate from tomo_progress, so anything watching tomo_progress for the
|
||||
real tomogram (e.g. heartbeat/idle-time tracking) never sees alignment
|
||||
scan writes mixed in.
|
||||
"""
|
||||
|
||||
_GLOBAL_VAR_KEY = "alignment_scan_progress"
|
||||
_DEFAULTS: dict = {"angle_index": 0, "total_angles": 12, "angle": 0.0}
|
||||
|
||||
|
||||
class LamNIError(Exception):
|
||||
"""A definite, non-transient tomo-scan failure (bad config, unmet
|
||||
precondition, ...) that should never be retried by @scan_repeat."""
|
||||
@@ -224,6 +236,7 @@ class LamNI(TomoQueueMixin, LamNIAlignmentMixin, LamNIOpticsMixin, LamniGuiTools
|
||||
# tomo_scan()); use tomo_progress_reset() to explicitly clear stale
|
||||
# progress without starting a new scan.
|
||||
self._progress_proxy = _ProgressProxy(self.client)
|
||||
self._alignment_scan_progress_proxy = _AlignmentScanProgressProxy(self.client)
|
||||
self._init_tomo_queue()
|
||||
|
||||
from csaxs_bec.bec_ipython_client.plugins.LamNI.LamNI_webpage_generator import (
|
||||
@@ -392,6 +405,21 @@ class LamNI(TomoQueueMixin, LamNIAlignmentMixin, LamNIOpticsMixin, LamniGuiTools
|
||||
self._progress_proxy.reset()
|
||||
print("Tomo progress reset.")
|
||||
|
||||
@property
|
||||
def alignment_scan_progress(self) -> _AlignmentScanProgressProxy:
|
||||
"""Proxy dict backed by the BEC global variable ``alignment_scan_progress``.
|
||||
|
||||
Tracks tomo_alignment_scan()'s own progress (angle N/total) --
|
||||
deliberately separate from ``progress``/``tomo_progress`` (the real
|
||||
tomogram's state), so the two can never be confused by anything
|
||||
watching one or the other.
|
||||
|
||||
Readable from any BEC client session via::
|
||||
|
||||
client.get_global_var("alignment_scan_progress")
|
||||
"""
|
||||
return self._alignment_scan_progress_proxy
|
||||
|
||||
@staticmethod
|
||||
def _format_duration(seconds: float) -> str:
|
||||
"""Format a duration in seconds as a human-readable string, e.g. '2h 03m 15s'."""
|
||||
@@ -1222,7 +1250,11 @@ class LamNI(TomoQueueMixin, LamNIAlignmentMixin, LamNIOpticsMixin, LamniGuiTools
|
||||
angles = list(np.linspace(0, 360, num=12, endpoint=False))
|
||||
alignment_scan_numbers = []
|
||||
|
||||
for angle in angles:
|
||||
self.alignment_scan_progress.reset()
|
||||
self.alignment_scan_progress.update(total_angles=len(angles), angle_index=0, angle=angles[0])
|
||||
self.lamnigui_show_alignment_progress()
|
||||
|
||||
for idx, angle in enumerate(angles):
|
||||
successful = False
|
||||
print(f"Starting LamNI scan for angle {angle}")
|
||||
while not successful:
|
||||
@@ -1242,6 +1274,9 @@ class LamNI(TomoQueueMixin, LamNIAlignmentMixin, LamNIOpticsMixin, LamniGuiTools
|
||||
|
||||
successful = True
|
||||
|
||||
self.alignment_scan_progress.update(angle_index=idx + 1, angle=angle)
|
||||
self._lamnigui_update_alignment_progress()
|
||||
|
||||
umv(dev.lsamrot, 0)
|
||||
self.OMNYTools.printgreenbold(
|
||||
"\n\nAlignment scan finished. Please run BEC_ptycho_align and load the new fit"
|
||||
|
||||
Reference in New Issue
Block a user