From 13bd9db55c857d145bd26596956e9c85a7e229dd Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Mon, 26 Oct 2026 15:37:00 +0100 Subject: [PATCH] Refinement: a B factor is held at its bound by the whole target's gradient, restraints included The held test read the X-ray gradient alone. At the floor, an atom whose X-ray term pushed outward but whose restraints pulled it back in more strongly was held fixed against the total target, and one whose restraints pushed it out was handed a gradient along the direction Set() clamps away - a flat direction for L-BFGS, failed line searches and s.y <= 0 pairs. On the 14 parity sets (--mode refine, GPU) the refined models are md5-identical; on the four 5f6m MD starts R-free 0.1707/0.1676/0.1720/0.1669 -> 0.1707/0.1690/0.1719/0.1668 (median 0.1692 -> 0.1699). Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_015CeEGgpKdfkCTJb3YNMJcu (cherry picked from commit 2f4b0b5ea54fdac54de7ee6c5a1476d2fc019fd8) --- image_analysis/structure_refinement/Refinement.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/image_analysis/structure_refinement/Refinement.cpp b/image_analysis/structure_refinement/Refinement.cpp index ce6969a41..977eccf6f 100644 --- a/image_analysis/structure_refinement/Refinement.cpp +++ b/image_analysis/structure_refinement/Refinement.cpp @@ -540,9 +540,10 @@ public: for (int c = 0; c < 3; c++) gradient[3 * k + c] = weight_ * gx[i][c] + gr[i][c]; else { - // held at a bound, B does not move further out - const bool held = (p[k] <= ctx_.b_floor && gx[i][3] > 0) || (p[k] >= ctx_.b_ceiling && gx[i][3] < 0); - gradient[k] = held ? 0.0 : weight_ * gx[i][3] + gr[i][3]; + // held at a bound, B does not move further out: by the whole target, restraints included + const double g = weight_ * gx[i][3] + gr[i][3]; + const bool held = (p[k] <= ctx_.b_floor && g > 0) || (p[k] >= ctx_.b_ceiling && g < 0); + gradient[k] = held ? 0.0 : g; } } return std::isfinite(*cost);