diff --git a/image_analysis/bragg_integration/BraggIntegrationEngine.cpp b/image_analysis/bragg_integration/BraggIntegrationEngine.cpp index 3fd804a0..07dbf6d3 100644 --- a/image_analysis/bragg_integration/BraggIntegrationEngine.cpp +++ b/image_analysis/bragg_integration/BraggIntegrationEngine.cpp @@ -109,9 +109,9 @@ BraggIntegrationEngine::BraggIntegrationEngine(const DiffractionExperiment &expe // n_kern is the largest row BraggStencilKernelIndex can select, plus one. r_max = std::hypot(std::max(beam_x, static_cast(xpixel) - beam_x), std::max(beam_y, static_cast(ypixel) - beam_y)); - const float grow_max = (bkg_radial || bkg_radial_auto) - ? BraggStencilGrow_px(static_cast(r_max), stencil) - : 0.0f; + bkg_radial_built = bkg_radial || bkg_radial_auto; + const float grow_max = bkg_radial_built ? BraggStencilGrow_px(static_cast(r_max), stencil) + : 0.0f; n_kern = static_cast(std::lround(grow_max)) + 1; // Every row must fit: the last one is built at grow = n_kern - 1, which rounding can put just // above grow_max. diff --git a/image_analysis/bragg_integration/BraggIntegrationEngine.h b/image_analysis/bragg_integration/BraggIntegrationEngine.h index f5bf14cd..7deca572 100644 --- a/image_analysis/bragg_integration/BraggIntegrationEngine.h +++ b/image_analysis/bragg_integration/BraggIntegrationEngine.h @@ -156,6 +156,7 @@ protected: // radius. What an elongated ring rules out is one kernel for ALL of them, not the average. bool bkg_radial = false; bool bkg_radial_auto = false; // settings left it unset: decide per image from the ice score + bool bkg_radial_built = false; // the kernel table was sized for the rings this engine uses int k_off = 0; // index of offset 0 within one kernel int k_len = 0; // entries per kernel int n_kern = 1; // kernels in the table (1 = circular stencil) @@ -188,6 +189,10 @@ public: // Turn the radial background correction on or off for the images that follow. The caller owns // the decision; in the auto mode the analysis sets it per image from that image's ice score. - void BackgroundRadial(bool on) { bkg_radial = on; } + // + // It cannot be raised on an engine the constructor did not build the kernel table for: that + // table would hold a single CIRCULAR kernel for rings that may be elongated, and on the GPU the + // radial buffers were never allocated, so the CPU would correct and the GPU would not. + void BackgroundRadial(bool on) { bkg_radial = on && bkg_radial_built; } [[nodiscard]] bool IsBackgroundRadialAuto() const { return bkg_radial_auto; } }; diff --git a/image_analysis/bragg_integration/BraggStencil.h b/image_analysis/bragg_integration/BraggStencil.h index 5e60bd85..d4191988 100644 --- a/image_analysis/bragg_integration/BraggStencil.h +++ b/image_analysis/bragg_integration/BraggStencil.h @@ -59,7 +59,7 @@ struct BraggStencilParams { float r2 = 6.0f, r3 = 10.0f; float bw_sigma = 0.0f; // radial streak per pixel of radius (bandwidth sigma, dimensionless) float k_sigma = 0.0f; // radial sigmas to push the ring out by; 0 = the old circular stencil - float max_grow = 0.0f; // hard cap on the radial growth [px]. 0 disables growth, not the cap. + float max_grow = 0.0f; // hard cap on the radial growth [px]; <= 0 means uncapped }; // One reflection's stencil, in its own radial/tangential frame. @@ -76,9 +76,10 @@ struct BraggStencil { // so the stencil and the radial-background kernel table agree on what "grown by this much" means. BRAGG_STENCIL_HD float BraggStencilGrow_px(float Rpx, const BraggStencilParams &p) { if (!(p.k_sigma > 0.0f)) return 0.0f; - // The cap bounds what a mis-declared bandwidth can do to the bounding box. + // The cap bounds what a mis-declared bandwidth can do to the bounding box. A caller that + // forgets to set it gets the uncapped growth rather than silently no growth at all. const float grow = p.k_sigma * p.bw_sigma * Rpx; - return grow > p.max_grow ? p.max_grow : grow; + return (p.max_grow > 0.0f && grow > p.max_grow) ? p.max_grow : grow; } BRAGG_STENCIL_HD BraggStencil MakeBraggStencil(float px_x, float px_y, const BraggStencilParams &p) {