fix(flomni): use last completed scan number when tomo_reconstruct's cached scan list is stale
CI for csaxs_bec / test (push) Failing after 2m4s
CI for csaxs_bec / test (push) Failing after 2m4s
tomo_reconstruct() named the queue file from a fresh next_scan_number but wrote its content from self._current_scan_list, which is only kept in sync by tomo_scan_projection()/tomo_acquire_at_angle(). Calling it directly from the command line -- e.g. after a plain scans.flomni_fermat_scan() -- wrote whatever scan list was left over from an earlier tomo scan, or raised AttributeError if none had run yet this session. Falls back to [next_scan_number - 1] whenever the cached list's last entry doesn't match the scan that actually just completed. Internal callers are unaffected since their cached list always matches at the point they call it. Also notes the identical bug in OMNY.tomo_reconstruct() (a separate, non-shared implementation) as a TODO for a later fix on its own branch. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUimPoyFQRvxM6R3njvuVj
This commit is contained in:
@@ -3118,12 +3118,27 @@ class Flomni(
|
||||
random_offset_x: float | None = None,
|
||||
random_offset_y: float | None = None,
|
||||
):
|
||||
"""write the tomo reconstruct file for the reconstruction queue"""
|
||||
"""Write the tomo reconstruct file for the reconstruction queue.
|
||||
|
||||
Normally called automatically at the end of tomo_scan_projection()/
|
||||
tomo_acquire_at_angle(), which keep self._current_scan_list up to
|
||||
date with the scan number(s) of the projection just acquired
|
||||
(possibly several, when stitching). When called directly -- e.g.
|
||||
from the command line after a plain scans.flomni_fermat_scan(),
|
||||
without going through either of those -- that cached list is either
|
||||
stale (left over from an earlier tomo scan) or not set at all, so
|
||||
fall back to just the most recently completed scan number.
|
||||
"""
|
||||
bec = builtins.__dict__.get("bec")
|
||||
next_scan_number = bec.queue.next_scan_number
|
||||
last_scan_number = next_scan_number - 1
|
||||
scan_list = getattr(self, "_current_scan_list", None)
|
||||
if not scan_list or scan_list[-1] != last_scan_number:
|
||||
scan_list = [last_scan_number]
|
||||
self.reconstructor.folder_name = self.ptycho_reconstruct_foldername
|
||||
self.reconstructor.write(
|
||||
scan_list=self._current_scan_list,
|
||||
next_scan_number=bec.queue.next_scan_number,
|
||||
scan_list=scan_list,
|
||||
next_scan_number=next_scan_number,
|
||||
base_path=base_path,
|
||||
probe_file_propagation=probe_propagation,
|
||||
random_offset_x=random_offset_x,
|
||||
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
# TODO: OMNY.tomo_reconstruct() writes a stale/missing scan list
|
||||
|
||||
Found while fixing the same bug in `Flomni.tomo_reconstruct()`
|
||||
(`csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py:3114`, branch
|
||||
`flomni_fixes_during_beamtimes`). Not applied to OMNY yet to avoid conflicting
|
||||
with other in-progress OMNY changes on a separate branch — do it there.
|
||||
|
||||
## The bug
|
||||
|
||||
`OMNY.tomo_reconstruct()` (`csaxs_bec/bec_ipython_client/plugins/omny/omny.py:1217`)
|
||||
names the reconstruction queue file from a fresh `bec.queue.next_scan_number`
|
||||
(so the *filename* is always correct), but writes the file's *content* from
|
||||
`self._current_scan_list`:
|
||||
|
||||
```python
|
||||
def tomo_reconstruct(self, base_path="~/Data10/specES1"):
|
||||
"""write the tomo reconstruct file for the reconstruction queue"""
|
||||
bec = builtins.__dict__.get("bec")
|
||||
base_path = os.path.expanduser(base_path)
|
||||
ptycho_queue_path = Path(os.path.join(base_path, self.ptycho_reconstruct_foldername))
|
||||
ptycho_queue_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
last_scan_number = bec.queue.next_scan_number - 1
|
||||
ptycho_queue_file = os.path.abspath(
|
||||
os.path.join(ptycho_queue_path, f"scan_{last_scan_number:05d}.dat")
|
||||
)
|
||||
with open(ptycho_queue_file, "w") as queue_file:
|
||||
scans = " ".join([str(scan) for scan in self._current_scan_list])
|
||||
queue_file.write(f"p.scan_number {scans}\n")
|
||||
queue_file.write("p.check_nextscan_started 1\n")
|
||||
```
|
||||
|
||||
`self._current_scan_list` is only kept up to date by whichever internal method
|
||||
last ran and then called `tomo_reconstruct()` itself right after (the OMNY
|
||||
equivalents of flomni's `tomo_scan_projection()`/`tomo_acquire_at_angle()` —
|
||||
check where `_current_scan_list` is assigned in `omny.py` for the exact call
|
||||
sites). Call `tomo_reconstruct()` directly from the command line instead —
|
||||
e.g. after a plain fermat scan run by hand, not through those internal
|
||||
flows — and the file gets written with whatever scan list happened to be
|
||||
cached from the *previous* tomo scan (or raises `AttributeError` if none ran
|
||||
yet this session). Filename right, content wrong/stale.
|
||||
|
||||
## The fix (already applied to flomni, mirror it here)
|
||||
|
||||
`Flomni.tomo_reconstruct()` now falls back to just the most recently
|
||||
completed scan number whenever the cached list doesn't actually match it:
|
||||
|
||||
```python
|
||||
bec = builtins.__dict__.get("bec")
|
||||
next_scan_number = bec.queue.next_scan_number
|
||||
last_scan_number = next_scan_number - 1
|
||||
scan_list = getattr(self, "_current_scan_list", None)
|
||||
if not scan_list or scan_list[-1] != last_scan_number:
|
||||
scan_list = [last_scan_number]
|
||||
```
|
||||
|
||||
Internal callers are unaffected (their cached list's last entry always equals
|
||||
`next_scan_number - 1` at the point they call `tomo_reconstruct()`), while a
|
||||
direct/standalone call now correctly falls back to `[last_scan_number]`
|
||||
instead of writing stale content or crashing.
|
||||
|
||||
Port the same `getattr(...)`/fallback logic into `OMNY.tomo_reconstruct()`
|
||||
(note OMNY's version doesn't go through the shared `PtychoReconstructor`
|
||||
class like flomni's does — it writes the file inline — so the fix applies
|
||||
directly to the `scans = " ".join(...)` line, not to a shared `write()`
|
||||
method).
|
||||
|
||||
Not scoped/designed further here — just flagging it so it isn't lost.
|
||||
Reference in New Issue
Block a user