From 7fbbe449ffa0420b4aa2a608a40c041f7845edba Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Fri, 13 Nov 2026 11:44:23 +0100 Subject: [PATCH] rugnux live: overall R-free of the final model; the writer writes _report.txt /rugnux/status overall.r_free reported the model as placed (R_FREE of the report) even where rugnux had refined it, while model.refinement.r_free and the page's tile showed the refined one. The overall row now carries the R-free of the model the run ended with: the refined model's where the refinement ran (as model.refinement.r_free, REFINE_R_FREE of the report), else the placed model's. The shell rows stay the placed model's - the refinement measures no shell. Serial runs get the same through ShellRFree. The OpenAPI descriptions say so; C++ model, frontend client and Redoc regenerated. Live runs now write _report.txt. The receiver already built the report document for the live status; its text (RenderReportText, the same rendering the CLI writes) goes to the writer as a new optional END message field `report`, written beside the other result files under a temporary name and renamed into place. No file I/O in the broker. The CBOR string decoder was capped at 16 kB; it now sizes the buffer to the string (a report is tens of kB, a model's metadata block can exceed the cap as well). Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01HVeDQsU5a8AJUdJPgWevAK --- broker/gen/model/Rugnux_live_shell.h | 2 +- broker/gen/model/Rugnux_live_status.h | 2 +- broker/jfjoch_api.yaml | 8 +++- broker/redoc-static.html | 6 ++- common/JFJochMessages.h | 2 + docs/CBOR.md | 1 + docs/JFJOCH_BROKER.md | 3 +- frame_serialize/CBORStream2Deserializer.cpp | 9 +++- frame_serialize/CBORStream2Serializer.cpp | 1 + frontend/src/client/types.gen.ts | 22 ++++++--- receiver/JFJochReceiverRugnuxRotation.cpp | 8 +++- receiver/JFJochReceiverRugnuxRotation.h | 1 + receiver/RugnuxLiveStatus.cpp | 31 +++++++++---- receiver/RugnuxLiveStatus.h | 17 +++++-- receiver/StillsGPUAnalysis.cpp | 2 +- tests/JFJochReceiverRugnuxTest.cpp | 6 +++ tests/RugnuxLiveStatusTest.cpp | 48 +++++++++++++++++++ tests/RugnuxResultFilesTest.cpp | 51 +++++++++++++++++++++ writer/WriteRugnuxFiles.cpp | 27 +++++++---- writer/WriteRugnuxFiles.h | 4 +- 20 files changed, 208 insertions(+), 43 deletions(-) diff --git a/broker/gen/model/Rugnux_live_shell.h b/broker/gen/model/Rugnux_live_shell.h index 370bb6a62..78a6c4af0 100644 --- a/broker/gen/model/Rugnux_live_shell.h +++ b/broker/gen/model/Rugnux_live_shell.h @@ -127,7 +127,7 @@ public: bool rSplitIsSet() const; void unsetR_split(); /// - /// R-free of the placed model (as given, not refined) over the shell's free reflections + /// R-free of the placed model (as given, not refined) over the shell's free reflections. In `overall`, the R-free of the model the run ended with: the refined model's (`model.refinement.r_free`) where rugnux refined it, else the placed model's (`model.r_free`). /// double getRFree() const; void setRFree(double const value); diff --git a/broker/gen/model/Rugnux_live_status.h b/broker/gen/model/Rugnux_live_status.h index 06f4edded..c1c53a2db 100644 --- a/broker/gen/model/Rugnux_live_status.h +++ b/broker/gen/model/Rugnux_live_status.h @@ -113,7 +113,7 @@ public: bool shellsMergeIsSet() const; void unsetShells_merge(); /// - /// Merging statistics by resolution shell of the latest merge, coarse to fine, as the shell table of `_report.txt`. Rotation: once the run is over; serial: at each provisional merge and at the end. `overall` is the same table's \"Overall\" row (whole-merge completeness, multiplicity, I/sigma, CC1/2, R_meas or R_split, CCref, and the overall R-free of the model validated on it), present with `shells`. + /// Merging statistics by resolution shell of the latest merge, coarse to fine, as the shell table of `_report.txt`. Rotation: once the run is over; serial: at each provisional merge and at the end. `overall` is the same table's \"Overall\" row (whole-merge completeness, multiplicity, I/sigma, CC1/2, R_meas or R_split, CCref, and the R-free of the final model - refined where rugnux refined it, as `model.refinement.r_free`, else as placed, as `model.r_free`), present with `shells`. /// std::vector getShells() const; void setShells(std::vector const& value); diff --git a/broker/jfjoch_api.yaml b/broker/jfjoch_api.yaml index 2a2237417..269fad3f8 100644 --- a/broker/jfjoch_api.yaml +++ b/broker/jfjoch_api.yaml @@ -3227,7 +3227,10 @@ components: r_free: type: number format: double - description: R-free of the placed model (as given, not refined) over the shell's free reflections + description: | + R-free of the placed model (as given, not refined) over the shell's free reflections. In `overall`, the + R-free of the model the run ended with: the refined model's (`model.refinement.r_free`) where rugnux + refined it, else the placed model's (`model.r_free`). rugnux_live_frame_range: type: object description: | @@ -3313,7 +3316,8 @@ components: Merging statistics by resolution shell of the latest merge, coarse to fine, as the shell table of `_report.txt`. Rotation: once the run is over; serial: at each provisional merge and at the end. `overall` is the same table's "Overall" row (whole-merge completeness, multiplicity, I/sigma, CC1/2, - R_meas or R_split, CCref, and the overall R-free of the model validated on it), present with `shells`. + R_meas or R_split, CCref, and the R-free of the final model - refined where rugnux refined it, as + `model.refinement.r_free`, else as placed, as `model.r_free`), present with `shells`. items: $ref: '#/components/schemas/rugnux_live_shell' overall: diff --git a/broker/redoc-static.html b/broker/redoc-static.html index d7da8212d..c5b40f102 100644 --- a/broker/redoc-static.html +++ b/broker/redoc-static.html @@ -553,7 +553,9 @@ If parameter is not provided calibration will be saved only if more than 4 image
object

Geometry of Smargon goniometer at SLS 2.0 / MX beamlines. Assuming that Smargon is used as static positioner and not moving during the scan, allowing to reconstruct geometry.

max_spot_count
integer [ 10 .. 2000 ]
Default: 250

Maximum number of spots that are saved/used for indexing; spots with highest intensity are selected

-
detect_ice_rings
boolean

Flag spots as ice rings and reduce their effect on indexing

+
detect_ice_rings
boolean

Flag spots as ice rings and reduce their effect on indexing. Left out, the broker's own +spot finding treats no spot as an ice ring, rugnux live decides as a bare rugnux would (on +for a rotation sweep, off for stills), and the master file carries no detect_ice_rings.

async_start
boolean
Default: false

When set to true, /start will not wait for detector and Jungfraujoch to be ready for the measurement.

Array of objects (detector_module_placement)

Where the detector's modules lie for this dataset, as rugnux measures them: rugnux writes <prefix>_module_placement.json, which holds exactly this field, to be merged into the dataset settings. @@ -1144,7 +1146,7 @@ then image might be replaced in the buffer between calling /images and /image.cb