Make alignment pivot independent of the DC mask threshold
The pivot was still derived from the binary CH4 >= dc_threshold_mv mask, so a threshold that happens to leave a real angle's mask empty (signal levels vary scan to scan across a many-angle acquisition) silently fell back to the raw scan-window bbox center — reproducing the exact "aligned to the scan window, not the sample" scatter the centroid pivot exists to fix, without any visible error. Replace the binary-mask centroid with an intensity-weighted centroid of the continuous CH4 signal, which is always well-defined regardless of the RF-mask threshold in effect. The threshold still controls what the manual dialog's overlay and CH1 masking show; it no longer has any bearing on where alignment pivots. Also bump the sidecar schema version: a file saved before today's pivot and rotation-sign fixes stores numbers for a since-corrected transform, so loading it unchanged would reintroduce the same scatter. Old sidecars are now treated as absent rather than silently reused. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+9
-16
@@ -1064,7 +1064,12 @@ class ManualAlignmentDialog(QDialog):
|
||||
max_dim = max(max(img.shape) for img in self._dc4_mv.values())
|
||||
self._downsample_factor = max(1, int(np.ceil(max_dim / self._MAX_PREVIEW_DIM)))
|
||||
self._recompute_masks_small()
|
||||
self._recompute_pivot_mm()
|
||||
# Alignment pivot: the CH4-signal-weighted centroid of each angle's
|
||||
# own footprint (see compute.compute_pivot_points_mm) — computed once
|
||||
# from the full-res CH4 images and deliberately independent of the
|
||||
# mask threshold, so it never needs recomputing when that changes
|
||||
# (unlike _masks_small, which is purely for the overlay's visuals).
|
||||
self._pivot_mm = compute.compute_pivot_points_mm(self._sras, self._dc4_mv)
|
||||
self._rebuild_preview_canvas()
|
||||
self._set_controls_enabled(True)
|
||||
self.lbl_status.setText("Ready.")
|
||||
@@ -1072,7 +1077,9 @@ class ManualAlignmentDialog(QDialog):
|
||||
def _recompute_masks_small(self):
|
||||
"""Threshold + downsample every angle's already-in-memory full-res
|
||||
CH4 mV image. Cheap (a compare + block-mean), so this re-runs in
|
||||
full whenever the mask-threshold spin box changes — no re-fetch."""
|
||||
full whenever the mask-threshold spin box changes — no re-fetch.
|
||||
Purely for the overlay's visuals — the alignment pivot does not
|
||||
depend on this threshold (see _pivot_mm / compute_pivot_points_mm)."""
|
||||
threshold = self.spin_mask_threshold_mv.value()
|
||||
factor = self._downsample_factor
|
||||
self._masks_small = {
|
||||
@@ -1081,19 +1088,6 @@ class ManualAlignmentDialog(QDialog):
|
||||
for a, img in self._dc4_mv.items()
|
||||
}
|
||||
|
||||
def _recompute_pivot_mm(self):
|
||||
"""Each angle's alignment pivot: the centroid of its own full-
|
||||
resolution CH4-threshold mask (its own sample footprint), not the
|
||||
raw scan-window bbox center — see compute.compute_pivot_points_mm.
|
||||
Recomputed alongside _recompute_masks_small whenever the mask
|
||||
threshold changes, from the full-res masks (not the downsampled
|
||||
preview ones) since this feeds the canonical geometry, not just the
|
||||
preview."""
|
||||
threshold = self.spin_mask_threshold_mv.value()
|
||||
masks = {a: img >= threshold for a, img in self._dc4_mv.items()}
|
||||
self._pivot_mm = compute.compute_pivot_points_mm(
|
||||
self._sras, threshold, masks=masks)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Preview canvas: full rebuild vs. incremental single-layer refresh
|
||||
# ------------------------------------------------------------------
|
||||
@@ -1227,7 +1221,6 @@ class ManualAlignmentDialog(QDialog):
|
||||
if not self._masks_ready:
|
||||
return
|
||||
self._recompute_masks_small()
|
||||
self._recompute_pivot_mm()
|
||||
self._rebuild_preview_canvas()
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user