From 7657253e9430d4339b7cd85e7bd051c66fdb60e1 Mon Sep 17 00:00:00 2001 From: x12sa Date: Fri, 26 Jun 2026 15:57:07 +0200 Subject: [PATCH] fix angular start in even subtomos --- .../plugins/flomni/flomni.py | 51 +++++++++---------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py index 9da179b..fc67d60 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py @@ -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