From 386f10ad071144bcf0594d1cd646bd97cbe8b2a9 Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Thu, 30 Jul 2026 10:49:37 +0200 Subject: [PATCH] Merging: mirror the negative-intensity Poisson guard on the GPU 6be94f2be stopped subtracting a negative intensity's Poisson term from the background variance, but only in the host Combine(). The CUDA combine is the path that actually runs: Run() selects it whenever a device is present and no observation dump was asked for, so the correction never took effect on a normal run, and a --dump-observations run merged differently from a normal one - the two are meant to be identical. Co-Authored-By: Claude Opus 5 (1M context) --- image_analysis/scale_merge/RotationScaleMergeGPU.cu | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/image_analysis/scale_merge/RotationScaleMergeGPU.cu b/image_analysis/scale_merge/RotationScaleMergeGPU.cu index c34d9e68..9b8123f4 100644 --- a/image_analysis/scale_merge/RotationScaleMergeGPU.cu +++ b/image_analysis/scale_merge/RotationScaleMergeGPU.cu @@ -354,7 +354,9 @@ namespace { const double corr = p.corr[i]; const double I_corr = pooled_I(i) * corr; const double sigma_corr = double(p.sigma[i]) * corr; - const double bkg_var = sigma_corr * sigma_corr - corr * I_corr; + // max(0, I): a down-fluctuated partial carries no Poisson signal to remove, and + // removing a negative one inflates the background part instead of leaving it alone. + const double bkg_var = sigma_corr * sigma_corr - corr * Dmax(0.0, I_corr); double var = Dmax(0.0, bkg_var) + corr * Dmax(0.0, F); if (!(var > 0.0)) var = sigma_corr * sigma_corr; const double w = 1.0 / var;