AnalyzeIndexing: Make it safer for weird data

This commit is contained in:
2026-04-28 22:24:35 +02:00
parent f32ceefc55
commit 2665abe047
+31 -12
View File
@@ -29,9 +29,13 @@ namespace {
// Wrap to [-180, 180] (useful for residuals)
inline float wrap_deg_pm180(float deg) {
while (deg > 180.0f) deg -= 360.0f;
while (deg < -180.0f) deg += 360.0f;
return deg;
if (!std::isfinite(deg)) return std::numeric_limits<float>::quiet_NaN();; // or std::nullopt upstream
deg = std::fmod(deg + 180.0f, 360.0f);
if (!std::isfinite(deg))
return std::numeric_limits<float>::quiet_NaN();
if (deg < 0) deg += 360.0f;
return deg - 180.0f;
}
// XDS convention: zeta = |m2 · e1| where e1 = (S × S0) / |S × S0|
@@ -74,7 +78,7 @@ namespace {
double ll = 0.0;
for (size_t i = 0; i < tau_values.size(); ++i) {
float R = R_fraction(tau_values[i], delta_phi, sigma_M, zeta_values[i]);
if (R > 1e-30f) {
if (std::isfinite(R) && R > 1e-30f) {
ll += std::log(static_cast<double>(R));
} else {
ll += -70.0; // Large penalty for zero probability
@@ -98,8 +102,8 @@ namespace {
float d = a + golden * (b - a);
const float tol = 1e-6f;
while (std::fabs(b - a) > tol) {
int iter = 0;
while (std::fabs(b - a) > tol && iter++ < 100) {
double fc = log_likelihood(tau_values, zeta_values, delta_phi, c);
double fd = log_likelihood(tau_values, zeta_values, delta_phi, d);
@@ -126,7 +130,7 @@ namespace {
return 0;
const float rhs = -D / R;
if (rhs < -1.0f || rhs > 1.0f)
if (!std::isfinite(rhs) || rhs < -1.0f || rhs > 1.0f)
return 0;
const float phi_ref = std::atan2(B, A);
@@ -137,9 +141,24 @@ namespace {
const float two_pi = 2.0f * static_cast<float>(M_PI);
auto shift_near = [&](float x) {
while (x < phi0 - two_pi) x += two_pi;
while (x > phi1 + two_pi) x -= two_pi;
return x;
if (!std::isfinite(x))
return std::numeric_limits<float>::quiet_NaN();
const float span_center = 0.5f * (phi0 + phi1);
// Bring x close to the interval center using modulo 2π
float shifted = x - span_center;
shifted = std::fmod(shifted, two_pi);
if (!std::isfinite(shifted))
return std::numeric_limits<float>::quiet_NaN();
// fmod can return negative values; normalize to [-π, π]
if (shifted < -static_cast<float>(M_PI))
shifted += two_pi;
else if (shifted > static_cast<float>(M_PI))
shifted -= two_pi;
return shifted + span_center;
};
s1 = shift_near(s1);
@@ -232,7 +251,7 @@ namespace {
// Find predicted phi angle
const auto phi_pred_opt = predict_phi_deg_local(pstar, S0, m2, 0.0f, axis.GetWedge_deg());
if (!phi_pred_opt.has_value())
if (!phi_pred_opt.has_value() || !std::isfinite(phi_pred_opt.value()))
continue;
// τ (tau) = angular deviation from Bragg position to center of oscillation range
@@ -257,7 +276,7 @@ namespace {
float zeta = calc_zeta(S, S0, m2);
// Filter out reflections with very small zeta (poorly determined)
if (zeta < 0.1f)
if (!std::isfinite(zeta) || !std::isfinite(tau_rad) || zeta < 0.1f)
continue;
tau_values.push_back(tau_rad);