fix angular start in even subtomos
CI for csaxs_bec / test (push) Successful in 1m30s
CI for csaxs_bec / test (pull_request) Successful in 1m30s

This commit is contained in:
x12sa
2026-06-26 15:57:07 +02:00
parent 798486b2e6
commit 7657253e94
@@ -1751,9 +1751,12 @@ class Flomni(
start_angle (float, optional): The start angle of the scan. Defaults to None.
"""
if start_angle is not None:
explicit_start_angle = start_angle is not None
if explicit_start_angle:
print(f"Sub tomo scan with start angle {start_angle} requested.")
max_allowed_angle = self.tomo_angle_range + 0.05 + self.tomo_angle_stepsize
if start_angle is None:
if subtomo_number == 1:
start_angle = 0
@@ -1772,22 +1775,31 @@ class Flomni(
elif subtomo_number == 8:
start_angle = self.tomo_angle_stepsize / 8.0 * 7
if not subtomo_number % 2: # even = reverse
# The table above gives the LOW end of this sub-tomogram's
# angular phase (same convention as the forward/odd
# sub-tomograms - it's what makes the combined 8 sub-tomograms
# interlace into one fine angular grid). A reverse sweep must
# begin at the HIGH end of that span and descend, so shift the
# freshly-computed phase up by one full angular range. This
# step is skipped when start_angle is given explicitly (i.e.
# we are resuming mid sub-tomogram), since then the value is
# already the literal current angle.
start_angle = min(start_angle + self.tomo_angle_range, max_allowed_angle)
# _tomo_shift_angles (potential global variable)
_tomo_shift_angles = 0
# compute number of projections
start = start_angle + _tomo_shift_angles
if subtomo_number % 2: # odd = forward
max_allowed_angle = self.tomo_angle_range + 0.05 + self.tomo_angle_stepsize
proposed_end = start + self.tomo_angle_range
angle_end = min(proposed_end, max_allowed_angle)
if subtomo_number % 2: # odd = forward: low -> high
angle_end = min(start + self.tomo_angle_range, max_allowed_angle)
span = angle_end - start
else: # even = reverse
else: # even = reverse: high -> low
min_allowed_angle = 0
proposed_end = start - self.tomo_angle_range
angle_end = max(proposed_end, min_allowed_angle)
angle_end = max(start - self.tomo_angle_range, min_allowed_angle)
span = start - angle_end
# number of projections needed to maintain step size
@@ -1795,22 +1807,6 @@ class Flomni(
angles = np.linspace(start, angle_end, num=N, endpoint=True)
if subtomo_number % 2: # odd subtomos → forward direction
# clamp end angle to max allowed
max_allowed_angle = self.tomo_angle_range + 0.05 + self.tomo_angle_stepsize
proposed_end = start + self.tomo_angle_range
angle_end = min(proposed_end, max_allowed_angle)
angles = np.linspace(start, angle_end, num=N, endpoint=True)
else: # even subtomos → reverse direction
# go FROM start_angle down toward 0
min_allowed_angle = 0
proposed_end = start - self.tomo_angle_range
angle_end = max(proposed_end, min_allowed_angle)
angles = np.linspace(start, angle_end, num=N, endpoint=True)
for i, angle in enumerate(angles):
self.progress["subtomo"] = subtomo_number
@@ -1818,17 +1814,16 @@ class Flomni(
# --- NEW LOGIC FOR OFFSET WHEN start_angle IS SPECIFIED ---
if i == 0:
step = self.tomo_angle_stepsize
sa = start_angle
if start_angle is None:
if not explicit_start_angle:
# normal operation: always start at zero
self._subtomo_offset = 0
else:
if subtomo_number % 2: # odd = forward direction
self._subtomo_offset = round(sa / step)
self._subtomo_offset = round(start_angle / step)
else: # even = reverse direction
self._subtomo_offset = round((self.tomo_angle_range - sa) / step)
self._subtomo_offset = round((self.tomo_angle_range - start_angle) / step)
# progress index must always increase
self.progress["subtomo_projection"] = self._subtomo_offset + i