From 27e0103bcbbac197207d121978b4fc7b87a3ebf5 Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Thu, 5 Nov 2026 12:49:24 +0100 Subject: [PATCH] Live stills: the pre-pass on 500 frames, enough for the distance to be refined On a serial collection indexed at 18%, the 100 frames of the pre-pass indexed 7 at a stated distance 2.6% short, too few for the geometry refinement to run, so the whole collection was analysed at the stated distance: 7.6% indexed, merged to 1.93 A, R_split 0.162. On 500 frames 34 indexed, the distance was refined to 117.51 mm (rugnux on the whole run: 117.94 mm) and the collection merged to 1.35 A, R_split 0.074 (rugnux: 1.30 A, 0.062; at rugnux's centre and distance the live path merges to 1.32 A, 0.068). 1000 frames gave the same (118.33 mm, 1.35 A, 0.071). The frames wait in the image buffer, in half its slots; a buffer that holds fewer starts the pre-pass on as many as it holds, as before. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01UqXYdL4qBGYRiSXSGXfCLu --- docs/JFJOCH_BROKER.md | 8 ++++++-- receiver/StillsGPUAnalysis.h | 5 ++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/JFJOCH_BROKER.md b/docs/JFJOCH_BROKER.md index c6fcfae70..cb5e75c79 100644 --- a/docs/JFJOCH_BROKER.md +++ b/docs/JFJOCH_BROKER.md @@ -254,13 +254,17 @@ Live processing of serial collections is **experimental**. With rugnux live mode (non-rotation) collection in the FPGA workflow, in the standard detector mode, is analysed as frames from a DECTRIS detector are: the converted frames go to GPU spot finding, indexing and integration, with rugnux's stills spot finder (adaptive threshold, single-pixel spots kept). Before any frame is analysed, the first -100 frames are run through rugnux, in memory, as `rugnux --no-merge` would run on them. That pre-pass +500 frames are run through rugnux, in memory, as `rugnux --no-merge` would run on them. That pre-pass decides the beam centre, refines the detector distance (where the dataset settings give a unit cell) and masks the beam-stop shadow and defective pixels; every frame of the collection is then analysed with that geometry and mask. The start message waits for the pre-pass, so it states them, and the end message carries the centre and distance used (`refined_beam_center_x/y`, `refined_detector_distance_mm`, [CBOR](CBOR.md)). The broker's own distance is taken as the beamline's: unlike offline rugnux, the pre-pass -does not search the whole distance range. +does not search the whole distance range. It refines the centre and distance for a detector square to the +beam, as the frames are then analysed. At a serial hit rate the distance needs the 500 frames to be refined at +all: on fewer, too few index for the geometry refinement to run, and the stated distance is kept. The image +buffer has to hold them, and the frames that arrive while the pre-pass runs, in half its slots (for a JUNGFRAU +8M, a slot is the size of an uncompressed frame); a smaller buffer starts the pre-pass on as many as it holds. Frames arriving during the pre-pass, or faster than the analysis, wait in the image buffer, in at most half of its slots; a frame that finds no free slot is dropped and counted as for a full image buffer, so analysis diff --git a/receiver/StillsGPUAnalysis.h b/receiver/StillsGPUAnalysis.h index 493a090d7..f20409479 100644 --- a/receiver/StillsGPUAnalysis.h +++ b/receiver/StillsGPUAnalysis.h @@ -43,7 +43,10 @@ // merge = false leaves it out. class StillsGPUAnalysis { public: - constexpr static int64_t PREPASS_IMAGES = 100; + // Enough frames for the distance to be refined at a serial hit rate: of 100 frames of a collection indexed + // at 18%, 7 indexed at a distance 2.6% off and the geometry refinement did not run; of 500, 34 did and + // refined it to 0.4%. They wait in the image buffer, which has to hold them in half its slots. + constexpr static int64_t PREPASS_IMAGES = 500; constexpr static std::array CHECKPOINTS = {0.5, 0.75}; constexpr static int MERGE_THREADS = 8;