rugnux: index both beam centres always, without a significance gate first
The second first pass was skipped where the measured centre sat within three times the fit's own sigma of the file's - a quarter of the non-SLS corpus, eight of thirty-two runs. That is a decision taken at a threshold before the evidence is in, and the evidence here costs a median 0.55 s: the spots are already found and cached, and their positions do not depend on the centre, so a second first pass is a median 20 % of what the first one costs. Worse, the gate removed exactly the case worth asking about. A centre error ALONG the spindle does not fail - it holds 96-100 % of frames indexed and quietly returns an axis harmonic - and the scale it turns on is a fraction of a pixel: measured on real data, 0.12 px of centre is the whole difference between the deposited cell and a halved axis. No sigma small enough to gate on would notice that, so the gate could only ever hide the question, never answer it. The three-sigma test stays where it belongs, in the report: it says whether the difference is a measurement or noise, which is what a reader wants to know. It no longer decides whether to look. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T3yNBXk4wKdMZy1ak2NY7f
This commit is contained in:
+10
-3
@@ -894,7 +894,9 @@ void Rugnux::PreScan(int start_image, int images_to_process, int frame_count, Ru
|
||||
// g', confidently. A move it cannot resolve is not evidence about the header either way.
|
||||
if (moved <= 3.0f * background_center_->sigma_pxl)
|
||||
logger.Info("Beam centre check: that is under three times the fit's own sigma, so the "
|
||||
"file's centre is as good as this measurement can tell");
|
||||
"file's centre is as good as this measurement can tell - the second first "
|
||||
"pass below indexes it anyway, because a fraction of a pixel is enough to "
|
||||
"decide a cell and no sigma small enough to gate on would notice");
|
||||
else if (across && *across > need)
|
||||
// Info and not a warning: `need` is where the FFT amplitude at a 200 A axis has fallen
|
||||
// to 0.70, which is a floor under what matters and not a threshold for failure - it is
|
||||
@@ -2224,8 +2226,13 @@ ProcessResult Rugnux::RunPipeline(RugnuxObserver *observer, bool write_output, b
|
||||
const float measured_x = measured.beam_x_pxl;
|
||||
const float measured_y = measured.beam_y_pxl;
|
||||
const float moved = std::hypot(measured_x - header_x, measured_y - header_y);
|
||||
// A move the fit cannot resolve is not a different hypothesis, only the same one twice.
|
||||
if (moved > 3.0f * measured.sigma_pxl) {
|
||||
// No gate on how significant the move is. It is tempting to skip the second pass when the
|
||||
// two centres are within the fit's own noise - it would save it on a quarter of the runs
|
||||
// here - but that is deciding at a threshold before the evidence is in, and the evidence
|
||||
// is cheap. It would also gate away exactly the case worth asking about: measured on real
|
||||
// data, a 0.12 px change of centre is the whole difference between the deposited cell and
|
||||
// a halved axis, and 0.12 px is well inside the sigma of any fit that could gate it.
|
||||
{
|
||||
const int majority = static_cast<int>(validation.size()) / 2;
|
||||
experiment_.BeamX_pxl(measured_x).BeamY_pxl(measured_y);
|
||||
FirstPass alt = pick_best(*indexer_pool, *indexer);
|
||||
|
||||
Reference in New Issue
Block a user