feat(flomni): acquire empty frames at start of tomo_scan
CI for csaxs_bec / test (push) Successful in 1m31s

Add collect_empty_frames(), which acquires 10 flat-field frames at
angle 0 with fsamx shifted out of the beam by fovx/2 (opposite the
normal alignment x-offset). Called once at the start of a new
tomo_scan() (not on resume). Frames are excluded from the ptycho
reconstruction queue and logged to tomography_scannumbers.txt with
subtomo_number=0.
This commit is contained in:
x12sa
2026-07-07 12:32:13 +02:00
parent 87d275f569
commit 036b3b1bd2
@@ -2259,6 +2259,68 @@ class Flomni(
end_scan_number=end_scan_number,
)
def collect_empty_frames(self):
"""Acquire 10 empty-frame (flat-field) images at angle 0, with fsamx
shifted out of the beam by half the field of view (fovx/2), in the
direction opposite the normal alignment x-offset at angle 0.
Called once at the start of a new tomo_scan() (not on resume).
These frames are deliberately not passed through tomo_reconstruct()
-- they are flat fields, not ptycho projections, and must not be
added to the reconstruction queue. Logged to
tomography_scannumbers.txt with subtomo_number=0 so they remain
traceable but are clearly distinguished from the angular grid
(subtomo_number 1-8).
"""
scans = builtins.__dict__.get("scans")
angle = 0
# --- rotation ---
fsamroy_current_setpoint = dev.fsamroy.user_setpoint.get()
if angle != fsamroy_current_setpoint:
umv(dev.fsamroy, angle)
else:
print("No rotation required")
# --- alignment offset at angle 0, then push x out of the beam by
# fovx/2, in the direction opposite the normal offset ---
offsets = self.get_alignment_offset(angle)
normal_offset_x = offsets[0]
direction = -1 if normal_offset_x >= 0 else 1
sum_offset_x = normal_offset_x + direction * (self.fovx / 2) + direction * 10
sum_offset_y = (
offsets[1]
- self.compute_additional_correction_y(angle)
- self.compute_additional_correction_y_2(angle)
+ self.manual_shift_y
)
# sum_offset_z = offsets[2]
# Todo
sum_offset_z = 0
dev.rtx.controller.laser_tracker_on()
umv(dev.rtx, sum_offset_x, dev.rty, sum_offset_y, dev.rtz, sum_offset_z)
tracker_signal = dev.rtx.controller.laser_tracker_check_signalstrength()
# checks that the fsamx coarse stage is at a position that leaves
# sufficient piezo range on the fine (rtx) stage
dev.rtx.controller.move_samx_to_scan_region(sum_offset_x)
if tracker_signal == "low":
logger.warning("Signal strength of the laser tracker is low. Realignment recommended!")
elif tracker_signal == "toolow":
raise FlomniError(
"Signal strength of the laser tracker is too low for scanning. Realignment required!"
)
print("Acquiring 10 empty frames at angle 0, fsamx shifted out of the beam.")
start_scan_number = bec.queue.next_scan_number
scans.acquire(exp_time=self.tomo_countingtime, frames_per_trigger=10)
end_scan_number = bec.queue.next_scan_number
for scan_nr in range(start_scan_number, end_scan_number):
self._write_tomo_scan_number(scan_nr, angle, subtomo_number=0)
def tomo_scan(self, subtomo_start=1, start_angle=None, projection_number=None):
"""start a tomo scan"""
@@ -2311,6 +2373,7 @@ class Flomni(
self.progress["estimated_finish_time"] = None
self.progress["accumulated_idle_time"] = 0.0
self.progress["heartbeat"] = None
self.collect_empty_frames()
with scans.dataset_id_on_hold:
if self.tomo_type == 1: