rugnux report: BEAM_CENTRE_OFF warning when the file's beam centre is wrong

The pre-scan's beam-centre check and the post-refinement both measure where
the direct beam lands, but the report only carried the centre the run used.
Section 1 now sets the file's direct beam (FILE_DIRECT_BEAM) beside the
background's (BACKGROUND_DIRECT_BEAM, with its sigma), the shift of the
refined centre from the file's (BEAM_CENTRE_SHIFT) and the tolerance the
geometry asks for (BEAM_CENTRE_TOLERANCE: BeamCenterNeed_pxl, the number the
log's check prints, here on the run's own cell). A shift above the tolerance
is a BEAM_CENTRE_OFF warning naming the file's, refined and background
centres, the difference in px and mm and the value to correct the beamline
to; a run that refined no centre is warned on the background alone where
its fit resolves the difference (3 sigma). The summary gains a Beam centre
line.

The refined centre, not the background, is the trigger wherever one exists:
on a battery set where XDS's refined direct beam and rugnux's agree to 1 px,
the background fit is 12 px away from both. Report-only; no result changes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVmAWnzCmRKAXVUCdc4iNi
This commit is contained in:
2026-10-09 17:07:22 +02:00
co-authored by Claude Opus 5.5
parent 341c347a3f
commit f462047038
6 changed files with 144 additions and 2 deletions
+36
View File
@@ -1200,3 +1200,39 @@ TEST_CASE("ResultReport_Checks", "[Diagnostics]") {
CHECK(std::ranges::any_of(c.codes, [&](const std::string &code) {
return std::ranges::find(doc.pathology_flags, code) != doc.pathology_flags.end(); }));
}
TEST_CASE("ResultReport_BeamCentreOff", "[Diagnostics]") {
DiffractionExperiment x(DetJF(1));
x.BeamX_pxl(500.0f).BeamY_pxl(400.0f);
const auto file = x.GetDiffractionGeometry().GetDirectBeam_pxl();
ProcessResult result;
result.post_refine = PostRefineResult{};
result.beam_centre_need_pxl = 2.0f;
result.background_beam_centre = BeamCenterEstimate{.beam_x_pxl = static_cast<float>(file.first) + 5.0f,
.beam_y_pxl = static_cast<float>(file.second),
.sigma_pxl = 0.5f};
// Refined within the tolerance: the background's word is not enough where the centre was refined.
result.used_direct_beam_x_pxl = file.first + 1.0;
result.used_direct_beam_y_pxl = file.second;
auto text = RenderResultReport("p", "in.h5", x, result);
CHECK(text.find("BEAM_CENTRE_OFF") == std::string::npos);
CHECK(text.find("\nBEAM_CENTRE_SHIFT= 1.00\n") != std::string::npos);
CHECK(text.find("\nBEAM_CENTRE_TOLERANCE= 2.00\n") != std::string::npos);
// Refined 4 px off the file's centre: warned, with both centres, px and mm, and the advice.
result.used_direct_beam_x_pxl = file.first;
result.used_direct_beam_y_pxl = file.second + 4.0;
text = RenderResultReport("p", "in.h5", x, result);
CHECK(text.find("\nPATHOLOGY_FLAGS= BEAM_CENTRE_OFF\n") != std::string::npos);
CHECK(text.find("4.0 px (0.30 mm)") != std::string::npos);
CHECK(text.find("correct the beam centre at the beamline") != std::string::npos);
// Nothing refined (stills): the background alone warns, worded as a check.
result.post_refine.reset();
result.used_direct_beam_x_pxl = file.first;
result.used_direct_beam_y_pxl = file.second;
text = RenderResultReport("p", "in.h5", x, result);
CHECK(text.find("\nPATHOLOGY_FLAGS= BEAM_CENTRE_OFF\n") != std::string::npos);
CHECK(text.find("the background's word alone") != std::string::npos);
}