option for random offset in single point acquisitions

This commit is contained in:
x12sa
2026-07-07 10:41:40 +02:00
committed by holler
co-authored by holler
parent 41e20576d6
commit cc7cfeef3e
@@ -1,6 +1,7 @@
import builtins
import datetime
import os
import random
import subprocess
import time
from pathlib import Path
@@ -1597,6 +1598,25 @@ class Flomni(
def manual_shift_y(self, val: float):
self.client.set_global_var("manual_shift_y", val)
@property
def single_point_random_shift_max(self):
"""Maximum absolute random shift [um] applied independently in x and y
at each single-point acquisition (tomo_acquire_at_angle). At each
angle a fresh random offset drawn uniformly from
[-single_point_random_shift_max, +single_point_random_shift_max] is
added to both x and y. 0 disables the random shift. Only takes effect
when single_point_instead_of_fermat_scan is active."""
val = self.client.get_global_var("single_point_random_shift_max")
if val is None:
return 0.0
return val
@single_point_random_shift_max.setter
def single_point_random_shift_max(self, val: float):
if not 0 <= val <= 10:
raise ValueError("single_point_random_shift_max must be between 0 and 10 um.")
self.client.set_global_var("single_point_random_shift_max", val)
@property
def fovx(self):
val = self.client.get_global_var("fovx")
@@ -2443,6 +2463,8 @@ class Flomni(
self,
base_path="~/data/raw/logs/reconstruction_queue",
probe_propagation: float | None = None,
random_offset_x: float | None = None,
random_offset_y: float | None = None,
):
"""write the tomo reconstruct file for the reconstruction queue"""
bec = builtins.__dict__.get("bec")
@@ -2451,6 +2473,8 @@ class Flomni(
next_scan_number=bec.queue.next_scan_number,
base_path=base_path,
probe_file_propagation=probe_propagation,
random_offset_x=random_offset_x,
random_offset_y=random_offset_y,
)
def _write_tomo_scan_number(self, scan_number: int, angle: float, subtomo_number: int) -> None:
@@ -2458,7 +2482,7 @@ class Flomni(
with open(tomo_scan_numbers_file, "a+") as out_file:
# pylint: disable=undefined-variable
out_file.write(
f"{scan_number} {angle} {dev.fsamroy.read()['fsamroy']['value']:.3f} {self.tomo_id} {subtomo_number} {0} {self.sample_name}\n"
f"{scan_number} {angle} {dev.fsamroy.read()['fsamroy']['value']:.5f} {self.tomo_id} {subtomo_number} {0} {self.sample_name}\n"
)
def tomo_scan_projection(self, angle: float):
@@ -2550,17 +2574,30 @@ class Flomni(
else:
print("No rotation required")
# --- optional random shift in x and y (single-point acquisitions) ---
# A fresh offset is drawn per angle from a uniform distribution over
# [-single_point_random_shift_max, +single_point_random_shift_max] and
# added independently to x and y. 0 (the default) disables it.
random_shift_max = self.single_point_random_shift_max
if random_shift_max > 0:
random_shift_x = random.uniform(-random_shift_max, random_shift_max)
random_shift_y = random.uniform(-random_shift_max, random_shift_max)
else:
random_shift_x = 0.0
random_shift_y = 0.0
# --- alignment offset (same as tomo_scan_projection, no stitching) ---
offsets = self.get_alignment_offset(angle)
sum_offset_x = offsets[0]
sum_offset_x = offsets[0] + random_shift_x
sum_offset_y = (
offsets[1]
- self.compute_additional_correction_y(angle)
- self.compute_additional_correction_y_2(angle)
+ self.manual_shift_y
+ random_shift_y
)
sum_offset_z = offsets[2]
# TODO this fix is while the tracker z is broken
probe_propagation = -sum_offset_z * 1e-6
sum_offset_z = 0
@@ -2585,7 +2622,11 @@ class Flomni(
n_frames = frames_per_trigger if frames_per_trigger is not None else self.frames_per_trigger
self._current_scan_list = [bec.queue.next_scan_number]
scans.acquire(exp_time=self.tomo_countingtime, frames_per_trigger=n_frames)
self.tomo_reconstruct(probe_propagation=probe_propagation)
self.tomo_reconstruct(
probe_propagation=probe_propagation,
random_offset_x=random_shift_x,
random_offset_y=random_shift_y,
)
def _tomo_type1_actual_grid(self) -> tuple[int, float, int]:
"""Compute the actual (achievable) tomo_type==1 grid from the
@@ -2623,6 +2664,8 @@ class Flomni(
print(f" _manual_shift_y <um> = {self.manual_shift_y}")
print(f"Frames per trigger (burst) = {self.frames_per_trigger}")
print(f"Single point instead of fermat = {self.single_point_instead_of_fermat_scan}")
if self.single_point_instead_of_fermat_scan:
print(f"Single point random shift max <um> = {self.single_point_random_shift_max}")
print("")
if self.tomo_type == 1:
@@ -2710,6 +2753,12 @@ class Flomni(
)
self.stitch_x = 0
self.stitch_y = 0
if self.single_point_instead_of_fermat_scan:
self.single_point_random_shift_max = self._get_val(
"<single point random shift max> um (0 = off)",
self.single_point_random_shift_max,
float,
)
print("Tomography type:")
print(" 1: 8 equally spaced sub-tomograms")
@@ -2822,6 +2871,7 @@ class Flomni(
"manual_shift_y",
"frames_per_trigger",
"single_point_instead_of_fermat_scan",
"single_point_random_shift_max",
"tomo_type",
"tomo_angle_range",
"tomo_angle_stepsize",