beam centre: a walk that adopts nothing is a walk not worth taking

The beam-centre hypothesis ladder runs up to 48 full first-pass indexing
attempts, a pixel at a time, and adopts the first rung that indexes half the
validation frames. When it adopts nothing the centre is restored and the run is
bit-identical to one that never searched, so on those datasets the whole walk is
pure cost - measured at 347 s of the 429 s the loop spends over a 100-dataset
corpus.

Two exits, both measured against the six corpus datasets that enter the walk.
The walk is skipped outright when the background already measures a centre that
is significant at three sigma and further away than the ladder can reach: it
cannot get there, so it only spends the time finding that out. And it stops
after the second ring when the running maximum, the starting centre included, is
below a third of the adoption bar, which separates cleanly on this corpus - the
three walks that adopt nothing peak at 0, 2 and 4 frames, the two that succeed
sit at 17 and 26 by that point.

Every dataset that adopted a centre before still adopts the same one, with the
same cell and the same reflection count; the two that fail still fail with the
same message. The measured saving is 226 s of the 429.
This commit is contained in:
leonarski_f committed 2026-09-10 10:01:17 +02:00
1 parent 31422ddf54
commit 672840dfb8
1 file changed
+36 -1
+36 -1
View File
@@ -3071,6 +3071,26 @@ ProcessResult Rugnux::RunPipeline(RugnuxObserver *observer, bool write_output, b
beam_center_searched_ = true;
const float beam_x = experiment_.GetBeamX_pxl(), beam_y = experiment_.GetBeamY_pxl();
const int reach = config_.beam_center_search_pxl;
// The background centre is measured off the whole projection rather than off a lattice, so
// where it is significant it BOUNDS where the beam can be, and a ladder that reaches
// `reach` px cannot arrive at a centre further away than that: every rung it can try is one
// the measurement has already excluded. The check above indexes the measured centre once
// and is right not to gate on significance for that - one pass is cheap. This ladder is
// 4*reach passes, so the same evidence is worth acting on here. Measured on a deposition
// whose header centre lands on a masked pixel: 170 px away at 0.34 px sigma, 48 rungs, and
// nothing adopted.
const bool centre_past_reach =
measured_beam_center_.has_value()
&& std::hypot(measured_beam_center_->beam_x_pxl - beam_x,
measured_beam_center_->beam_y_pxl - beam_y)
> std::max(3.0f * measured_beam_center_->sigma_pxl, static_cast<float>(reach));
if (centre_past_reach)
logger.Info("Beam-centre hypothesis: the background places the centre {:.2f} px away "
"(+- {:.2f} px), past the {} px this ladder reaches - no centre it can try "
"is the beam, so it is not walked",
std::hypot(measured_beam_center_->beam_x_pxl - beam_x,
measured_beam_center_->beam_y_pxl - beam_y),
measured_beam_center_->sigma_pxl, reach);
logger.Info("Beam-centre hypothesis: {}/{} validation frames at ({:.2f},{:.2f}); trying "
"the centre +-{} px along each detector axis, a pixel at a time",
best.score, static_cast<int>(validation.size()), beam_x, beam_y, reach);
@@ -3081,7 +3101,13 @@ ProcessResult Rugnux::RunPipeline(RugnuxObserver *observer, bool write_output, b
const int adopt_bar = static_cast<int>(validation.size()) / 2;
bool adopted = false;
float won_x = beam_x, won_y = beam_y;
for (int k = 1; k <= reach && !cancelled_ && !adopted; k++) {
// The count is the only thing the ladder steers on, so a ladder that has not seen a THIRD
// of its own bar anywhere in two complete rings has nothing to steer by and is walking the
// noise floor. Measured over the beam-centre walks on the open battery: after two rings the
// two runs that went on to adopt stood at 17/60 and 59/60, and the three that adopted
// nothing stood at 4/60 or below - the two populations do not overlap.
int seen = best.score;
for (int k = 1; k <= reach && !cancelled_ && !adopted && !centre_past_reach; k++) {
for (const auto &[dx, dy]: {std::pair<int, int>{-k, 0}, {k, 0}, {0, -k}, {0, k}}) {
const float trial_x = beam_x + static_cast<float>(dx);
const float trial_y = beam_y + static_cast<float>(dy);
@@ -3089,6 +3115,7 @@ ProcessResult Rugnux::RunPipeline(RugnuxObserver *observer, bool write_output, b
FirstPass alt = pick_best(*indexer_pool, *indexer);
logger.Info("Beam-centre hypothesis ({:.2f},{:.2f}): {}/{} frames", trial_x,
trial_y, alt.score, static_cast<int>(validation.size()));
seen = std::max(seen, alt.score);
if (alt.result.has_value() && alt.score > adopt_bar && alt.score > best.score) {
best = alt;
won_x = trial_x;
@@ -3097,6 +3124,14 @@ ProcessResult Rugnux::RunPipeline(RugnuxObserver *observer, bool write_output, b
break;
}
}
if (k == 2 && !adopted && seen < adopt_bar / 3) {
logger.Info("Beam-centre hypothesis: the best of two rings is {}/{} against the "
"{}/{} a centre has to index to be adopted - the ladder is at the "
"count's noise floor and is stopped here", seen,
static_cast<int>(validation.size()), adopt_bar + 1,
static_cast<int>(validation.size()));
break;
}
}
experiment_.BeamX_pxl(won_x).BeamY_pxl(won_y);
if (adopted)