option for random offset in single point acquisitions
This commit is contained in:
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user