Azimuthal integration: clamp a negative variance before the square root

calc_std uses the cancellation-prone (sum2 - sum^2/n) form on float accumulators
summed over millions of pixels, so a flat ring - true variance near zero - comes
out negative as often as positive and GetStd() returns NaN. Both adaptive
spot-finder ring accumulators already floor this at zero; this one did not, and
1a0774eed made sum2 correct, so the path is now actually exercised.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-30 10:56:06 +02:00
co-authored by Claude Opus 5
parent 2ef8841983
commit 9b55e44acd
+4 -1
View File
@@ -18,7 +18,10 @@ inline float calc_std(float sum, float sum2, uint64_t count) {
return NAN;
const auto fp_count = static_cast<float>(count);
const float variance = (sum2 - sum * sum / fp_count) / (fp_count - 1);
return std::sqrt(variance);
// The two sums are floats accumulated over millions of pixels, so on a near-constant ring the
// difference of two nearly equal large numbers lands either side of zero; clamp before the root
// rather than emit a NaN standard deviation. Both spot-finder ring accumulators do the same.
return std::sqrt(std::max(0.0f, variance));
}
AzimuthalIntegrationProfile::AzimuthalIntegrationProfile(const AzimuthalIntegrationMapping &mapping)