From fe1f3ba96e75ae664ac2a843285c142a10106a8d Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Fri, 28 Aug 2026 10:49:18 +0200 Subject: [PATCH] rugnux: report the geometry in the form the broker takes it in A rotation run post-refines the detector distance and the beam centre, and that is usually the best measurement of them anyone has - but the only way back into the instrument was to read two numbers off the report by eye and retype them into a collection. Write them once more, as the object jfjoch_broker takes: the four required properties of dataset_settings in broker/jfjoch_api.yaml, spelled the way the API spells them, on one line of valid JSON that a script can lift with a grep and POST. The existing DETECTOR_DISTANCE and BEAM_CENTRE keys are unchanged and stay the ones a person reads. REPORT_VERSION is not bumped: a new key breaks no consumer of the old ones. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01FBumeJVx4oeXxiBRpkrE5H --- docs/CHANGELOG.md | 1 + docs/RUGNUX.md | 17 ++++++++++++++++- rugnux/ResultReport.cpp | 15 +++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 01fb728d7..b0d50b5f0 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## 1.0.0 ### 1.0.0-rc.166 +* The rugnux results report carries `JFJOCH_DATASET_SETTINGS=`, the geometry the run integrated at written as one line of JSON in the form `jfjoch_broker` takes it, so a refined beam centre and distance can be carried back to the instrument. * `/entry/MX/strongPixels` and the strong-pixel plot are filled on the CPU/GPU analysis path, not only behind the FPGA, so an image the spot finder gave up on can be told from one that did not diffract. * The spot-finding resolution estimate is no longer capped at the corner of the detector, so a crystal that diffracts past the edge is reported as reaching past it, and a run where the estimate is finer than what was merged is a detector-limited run. * Spot finding no longer throws away a whole image when it holds many strong pixels: the limit follows the detector (one pixel in 64) instead of standing at the 65535 that suited a 4-megapixel detector, which a strongly diffracting crystal on an 18-megapixel one passes on its best frames. diff --git a/docs/RUGNUX.md b/docs/RUGNUX.md index c8ed84f1d..77508371e 100644 --- a/docs/RUGNUX.md +++ b/docs/RUGNUX.md @@ -564,7 +564,22 @@ keep their numbers. **`SPOT_RESOLUTION_ESTIMATE=`** in section 1 is how far the merged data are expected to reach, read off the found spots alone — no lattice, no integration, no merge — so it is there on a run that never merges, and on a run that does it can be read against `INCLUDE_RESOLUTION_RANGE` in section 5. It is a -prediction, good to about 0.2 Å on rotation data; nothing is cut on it. +prediction, good to about 0.2 Å on rotation data; nothing is cut on it. It is **not** limited to what +the detector records: where it reads finer than the high-resolution end of `INCLUDE_RESOLUTION_RANGE`, +the crystal diffracts past the corner and the run was detector-limited. + +**`JFJOCH_DATASET_SETTINGS=`** in section 1 is the geometry the run integrated at — on a rotation run +the post-refined one — written as the object `jfjoch_broker` takes it in: the four required properties +of `dataset_settings` in `broker/jfjoch_api.yaml`, on one line of valid JSON, so a refined beam centre +and distance can go back to the instrument for the next collection without anyone retyping them. + +``` +JFJOCH_DATASET_SETTINGS= {"beam_x_pxl": 2078.24, "beam_y_pxl": 2233.92, "detector_distance_mm": 190.311, "incident_energy_keV": 12.4000} +``` + +```bash +grep '^JFJOCH_DATASET_SETTINGS=' out_report.txt | cut -d' ' -f2- > geometry.json +``` **Which pass.** A rotation run integrates twice — once at the geometry in the input file, then again at the post-refined geometry — and can integrate a third time if a guard rejects the second pass. diff --git a/rugnux/ResultReport.cpp b/rugnux/ResultReport.cpp index 876121f8d..07822fe5a 100644 --- a/rugnux/ResultReport.cpp +++ b/rugnux/ResultReport.cpp @@ -95,6 +95,21 @@ std::string RenderResultReport(const std::string &output_prefix, << " The distance and beam centre above are the ones this result was integrated at, which on\n" << " a rotation run is the post-refined geometry rather than the values in the input file.\n"; + // The same geometry once more, as the object jfjoch_broker takes it in: the four required + // properties of dataset_settings in broker/jfjoch_api.yaml, spelled the way the API spells them. + // A run that refined the geometry is usually the best measurement of it anyone has, and without + // this the only way back into the instrument is to read two numbers off this report by eye and + // retype them. One line, valid JSON, so a script can lift it with a grep and POST it. + os << "\n"; + Key(os, "JFJOCH_DATASET_SETTINGS", + fmt::format(R"({{"beam_x_pxl": {:.2f}, "beam_y_pxl": {:.2f}, "detector_distance_mm": {:.3f}, )" + R"("incident_energy_keV": {:.4f}}})", + result.used_beam_x_pxl, result.used_beam_y_pxl, result.used_distance_mm, + experiment.GetDatasetSettings().GetPhotonEnergy_keV())); + os << "\n" + << " The geometry above as jfjoch_broker's dataset_settings, to carry a refined beam centre and\n" + << " distance back to the instrument for the next collection.\n"; + if (result.spot_resolution_estimate_A.has_value()) { os << "\n"; Key(os, "SPOT_RESOLUTION_ESTIMATE", fmt::format("{:.2f}", *result.spot_resolution_estimate_A));