rugnux report: XDS geometry keywords as one report section, not p_XDS.INP

The refined geometry is no longer written as a whole p_XDS.INP (and the
report's XDS_INPUT= key is gone). Instead the report carries one section,
XDS GEOMETRY KEYWORDS, with the XDS.INP keywords that carry the geometry the
result was integrated at: ORGX/ORGY (PONI, 1-based), DETECTOR_DISTANCE, the
detector axes where the detector is tilted, INCIDENT_BEAM_DIRECTION with
X-RAY_WAVELENGTH, and ROTATION_AXIS in XDS's sense (rugnux's axis negated,
as verified with XDS IDXREF). No cell or space group: XDS determines those.
The lines carry a "# XDS.INP> " prefix, so sed lifts them ready to paste.

The same keywords were logged by LogXDSGeometry at the start of every pass,
with the axis in rugnux's sense; that printing is removed, so the report
section is the one place they are stated. Docs updated (RUGNUX_REPORT,
RUGNUX_INTEGRATION, RUGNUX, RUGNUX_TUTORIAL).

Output only; p.mtz md5-identical on 3 battery sets.

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 19:09:27 +02:00
co-authored by Claude Opus 5.5
parent 7ed1544136
commit c0bcf1a7a9
12 changed files with 113 additions and 327 deletions
+11 -21
View File
@@ -7,7 +7,6 @@
#include "../image_analysis/scale_merge/Merge.h"
#include "../reader/JFJochHDF5Reader.h"
#include "../rugnux/ResultReport.h"
#include "../rugnux/XDSInput.h"
#include "../common/CUDAWrapper.h"
#include "../writer/FileWriter.h"
@@ -1271,35 +1270,26 @@ TEST_CASE("ResultReport_OverloadsAndOverlaps", "[Diagnostics]") {
CHECK(text.find("Move the detector back") != std::string::npos);
}
TEST_CASE("XDSInput_Render", "[Diagnostics]") {
TEST_CASE("ResultReport_XDSGeometryKeywords", "[Diagnostics]") {
DiffractionExperiment x(DetJF(1));
x.BeamX_pxl(500.0f).BeamY_pxl(400.0f).DetectorDistance_mm(100.0f);
x.Goniometer(GoniometerAxis("omega", 10.0f, 0.1f, Coord(1, 0, 0), {}));
ProcessResult result;
result.consensus_cell = UnitCell{.a = 79.0f, .b = 79.0f, .c = 38.0f,
.alpha = 90.0f, .beta = 90.0f, .gamma = 90.0f};
// The refined geometry, not the file's, goes out - 1-based, untilted here.
result.used_beam_x_pxl = 510.0f;
result.used_beam_y_pxl = 395.5f;
result.used_distance_mm = 120.0f;
result.used_rotation_axis = Coord(-1, 0, 0);
const auto text = RenderXDSInput("/data/x_master.h5", x, result, 0, 900);
CHECK(text.find("\nORGX= 511.00 ORGY= 396.50\n") != std::string::npos);
CHECK(text.find("\nDETECTOR_DISTANCE= 120.000\n") != std::string::npos);
CHECK(text.find("\nDIRECTION_OF_DETECTOR_X-AXIS= 1.000000 0.000000 0.000000\n") != std::string::npos);
const auto text = RenderResultReport("p", "in.h5", x, result);
CHECK(text.find("XDS GEOMETRY KEYWORDS") != std::string::npos);
CHECK(text.find("\n# XDS.INP> ORGX= 511.00 ORGY= 396.50\n") != std::string::npos);
CHECK(text.find("\n# XDS.INP> DETECTOR_DISTANCE= 120.000\n") != std::string::npos);
// XDS turns the crystal the other way about the axis it is given.
CHECK(text.find("\nROTATION_AXIS= 1.000000 0.000000 0.000000\n") != std::string::npos);
CHECK(text.find("\nNAME_TEMPLATE_OF_DATA_FRAMES= /data/x_??????.h5\n") != std::string::npos);
CHECK(text.find("\nDATA_RANGE= 1 900\n") != std::string::npos);
CHECK(text.find("\nSTARTING_ANGLE= 10.0000\n") != std::string::npos);
CHECK(text.find("\nOSCILLATION_RANGE= 0.100000\n") != std::string::npos);
}
TEST_CASE("XDSInput_CBFTemplate", "[Diagnostics]") {
DiffractionExperiment x(DetJF(1));
x.Goniometer(GoniometerAxis("omega", 0.0f, 0.1f, Coord(1, 0, 0), {}));
const auto text = RenderXDSInput("/data/run_2_0101.cbf", x, ProcessResult{}, 0, 50);
CHECK(text.find("\nNAME_TEMPLATE_OF_DATA_FRAMES= /data/run_2_????.cbf\n") != std::string::npos);
CHECK(text.find("\nDATA_RANGE= 101 150\n") != std::string::npos);
CHECK(text.find("\nSTARTING_FRAME= 101\n") != std::string::npos);
CHECK(text.find("\nDETECTOR= PILATUS") != std::string::npos);
CHECK(text.find("\n# XDS.INP> ROTATION_AXIS= 1.000000 0.000000 0.000000\n") != std::string::npos);
// Untilted: no detector axes; and never the cell or the space group.
CHECK(text.find("XDS.INP> DIRECTION_OF_DETECTOR") == std::string::npos);
CHECK(text.find("XDS.INP> UNIT_CELL") == std::string::npos);
}