From 32ecc296b803f891fd16af95e9eeed37b00d1dda Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Mon, 3 Aug 2026 14:14:09 +0200 Subject: [PATCH] broker: bootstrap a concrete max_hkl, as the API and the docs already claim How far the predictor walks the lattice became a setting defaulting to "derive it from the refined cell", which is what is wanted offline. Online it is not: per-image prediction cost then depends on whichever crystal is mounted, and the cube (2n+1)^3 grows quickly. The broker was only ever handed a concrete value when a client sent a bragg_integration block, and none of the shipped configs has one, so the derived path was the normal deployment. Four places in the tree - the conversion, the predictor, the OpenAPI description and the changelog - already state that the broker keeps a fixed bootstrap. Make that true. Co-Authored-By: Claude Opus 5 (1M context) --- broker/JFJochBrokerParser.cpp | 7 +++++++ common/BraggIntegrationSettings.h | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/broker/JFJochBrokerParser.cpp b/broker/JFJochBrokerParser.cpp index 1a322e56..2ee30f88 100644 --- a/broker/JFJochBrokerParser.cpp +++ b/broker/JFJochBrokerParser.cpp @@ -179,6 +179,13 @@ void ParseFacilityConfiguration(const org::openapitools::server::model::Jfjoch_s if (j.braggIntegrationIsSet()) experiment.ImportBraggIntegrationSettings(Convert(j.getBraggIntegration())); + else + // A config with no bragg_integration block still has to bootstrap a concrete max_hkl, or the + // predictor falls back to deriving the hkl cube from the refined cell and a live acquisition's + // per-image cost is decided by whichever crystal is mounted. None of the shipped configs sets + // the block, so this is the normal path online. + experiment.ImportBraggIntegrationSettings( + BraggIntegrationSettings().MaxHKL(BRAGG_ONLINE_DEFAULT_MAX_HKL)); if (j.darkMaskIsSet()) experiment.ImportDarkMaskSettings(Convert(j.getDarkMask())); diff --git a/common/BraggIntegrationSettings.h b/common/BraggIntegrationSettings.h index 2e3e5b23..4f917155 100644 --- a/common/BraggIntegrationSettings.h +++ b/common/BraggIntegrationSettings.h @@ -12,6 +12,10 @@ // spots - see docs/CPU_DATA_ANALYSIS.md (Bragg integration). enum class IntegratorMode { BoxSum, ProfileGaussian, ProfileEmpirical }; +// The hkl half-width the broker bootstraps when a config carries no bragg_integration block. Matches +// the max_hkl default in broker/jfjoch_api.yaml, so an omitting client and an omitting config agree. +constexpr int BRAGG_ONLINE_DEFAULT_MAX_HKL = 100; + class BraggIntegrationSettings { IntegratorMode integrator_mode = IntegratorMode::ProfileGaussian; float r_1 = 4; @@ -39,6 +43,8 @@ class BraggIntegrationSettings { // // Unset (the default) means "take it from the refined cell", which is exact: the predictor keeps // only |q| <= 1/d_min and h = a.q, so no reflection can have |h| > a/d_min. See MaxHKLForCell. + // Offline that is what is wanted. ONLINE it is not: the broker bootstraps a concrete value + // (BRAGG_ONLINE_DEFAULT_MAX_HKL) so per-image cost stays predictable across samples. std::optional max_hkl; public: