diff --git a/image_analysis/bragg_integration/BraggIntegrationEngine.h b/image_analysis/bragg_integration/BraggIntegrationEngine.h index 4b4430808..fc0020638 100644 --- a/image_analysis/bragg_integration/BraggIntegrationEngine.h +++ b/image_analysis/bragg_integration/BraggIntegrationEngine.h @@ -87,6 +87,10 @@ constexpr float MAX_STENCIL_GROW_OVER_R3 = 2.0f; // summation (box-sum) intensity when the profile result disagrees with the summation seed by more than // this many box-sum sigmas (a real fit agrees within counting noise, so the margin is generous). constexpr double PROFILE_SUMMATION_MAX_NSIGMA = 10.0; +// The runaway is a weak reflection's. On a strong spot the profile reads a few per cent above the box +// sum (the box misses the tails), which at high I/sigma is many box sigmas - a real fit, not a +// runaway. So a profile above a box sum of more than this many sigmas is kept. +constexpr double PROFILE_SUMMATION_STRONG_NSIGMA = 20.0; // MINPK keeps a reflection while enough of its expected profile is readable. It says nothing about // WHERE the unreadable part is, and the two are not the same question. Renormalising over the pixels diff --git a/image_analysis/bragg_integration/BraggIntegrationEngineCPU.cpp b/image_analysis/bragg_integration/BraggIntegrationEngineCPU.cpp index 0d283d7a1..28c4e52ed 100644 --- a/image_analysis/bragg_integration/BraggIntegrationEngineCPU.cpp +++ b/image_analysis/bragg_integration/BraggIntegrationEngineCPU.cpp @@ -890,7 +890,9 @@ std::vector BraggIntegrationEngineCPU::ProfilePasses(const Sampler & // both - excluded to a neighbour, or unreadable - the fit's full-profile intensity has to be // scaled down to that same disk before the two are comparable. Nothing dropped gives 1. const double guard_scale = fo.m_all > 0.0f ? fo.m_read / fo.m_all : 1.0; - if (std::abs(I * guard_scale - rh.I) > PROFILE_SUMMATION_MAX_NSIGMA * rh.sigma) { + const double guard_diff = I * guard_scale - rh.I; + const bool strong_above = guard_diff > 0 && rh.I > PROFILE_SUMMATION_STRONG_NSIGMA * rh.sigma; + if (std::abs(guard_diff) > PROFILE_SUMMATION_MAX_NSIGMA * rh.sigma && !strong_above) { I = rh.I; sigma = rh.sigma; var_bkg = rh.var_bkg; diff --git a/image_analysis/bragg_integration/BraggIntegrationEngineGPU.cu b/image_analysis/bragg_integration/BraggIntegrationEngineGPU.cu index 34e242fab..43ac653f3 100644 --- a/image_analysis/bragg_integration/BraggIntegrationEngineGPU.cu +++ b/image_analysis/bragg_integration/BraggIntegrationEngineGPU.cu @@ -873,7 +873,10 @@ __global__ void fit(const int32_t *img, const uint32_t *owner, const float *px_x // neighbour, or unreadable - scale the full-profile intensity back to the disk the seed // read; nothing dropped gives exactly 1. const float gs = s_mall > 0.0f ? s_mread / s_mall : 1.0f; - if (fabsf(I * gs - I_seed[i]) > (float) PROFILE_SUMMATION_MAX_NSIGMA * sigma_seed[i]) { + const float diff = I * gs - I_seed[i]; + const bool strong_above = diff > 0.0f + && I_seed[i] > (float) PROFILE_SUMMATION_STRONG_NSIGMA * sigma_seed[i]; + if (fabsf(diff) > (float) PROFILE_SUMMATION_MAX_NSIGMA * sigma_seed[i] && !strong_above) { I = I_seed[i]; sigma = sigma_seed[i]; var_bkg = varbkg_seed[i];