rugnux: raise the ice-ring mask margin to the measured null

The mask drops a hexagonal-ice ring when its merged half-set CC1/2 falls a fixed
0.05 below its resolution shoulders. That margin is not a significance level: at
the populations these rings actually have, 0.05 spans 1.1 to 7.3 sigma across
firings, and a nominal Fisher-z error understates the real scatter of these
heavy-tailed intensities by ~2.7x, so the null has to be measured rather than
derived.

Measured it with decoy bands - the identical ring/shoulder statistic evaluated
at q positions carrying no ice ring - over the 37-crystal rotation battery: the
gap's empirical null is p95 +0.032, p99 +0.095. So 0.05 sits near the 96th
percentile, about 4% of ice-free bands clear it, and roughly half the 22
observed firings are indistinguishable from bands with no ice in them. The
firing gaps are continuous, not bimodal, with 12 of 22 in [0.05, 0.10).

Raise it to 0.10, the 99th percentile of that null. Firings 22 -> 10, crystals
12 -> 5, decoy false-positive rate 3.4% -> 0.8%. An independent check against
XDS - which integrates through ice rings and so measures exactly what we delete
- agrees: of the firings with a usable comparison, 9 true / 9 false becomes
7 true / 2 false.

Battery: space groups 34 OK / 3 DIFF, the same three crystals as baseline, and
no other discrete decision changes on 37/37. The heavily iced crystal keeps all
five of its rings and its CC1/2 of 96.6; eight others recover 3.9-11.9% more
unique reflections and up to 10.4 completeness points. Cost is CC1/2 -0.84 on
one crystal, -0.35 on another, and agreement with XDS on the common reflections
worse by a median 0.0004.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-05 19:00:10 +02:00
co-authored by Claude Opus 5
parent bb7df09086
commit b22e1b6822
+8 -1
View File
@@ -28,8 +28,15 @@ std::vector<char> FindDecorrelatedIceRings(const std::vector<MergedReflection> &
if (dq < w) { ring.Add(m.I_half[0], m.I_half[1]); ++n_ring; }
else if (dq < 3.0f * w) { shoulder.Add(m.I_half[0], m.I_half[1]); ++n_shoulder; }
}
// The 0.10 margin is the 99th percentile of this statistic measured on DECOY bands - the same
// ring/shoulder geometry evaluated at q positions carrying no ice ring - over the 37-crystal
// rotation battery. At the 0.05 it replaces, 4% of ice-free bands cleared the bar; at 0.10,
// 1%. (A margin in CC is not a fixed significance: at the observed populations 0.05 ranges
// from 1.1 to 7.3 sigma across firings, and the nominal Fisher-z error underestimates the
// real scatter of these heavy-tailed intensities by ~2.7x, so the null was measured, not
// derived.)
if (n_ring >= 20 && n_shoulder >= 20 && shoulder.GetCC() > 0.5
&& ring.GetCC() < shoulder.GetCC() - 0.05) {
&& ring.GetCC() < shoulder.GetCC() - 0.10) {
mask[i] = 1;
logger.Info("Ice-ring mask: {:.2f} A ring CC1/2 {:.3f} << shoulders {:.3f}; masked from merge",
ICE_RING_RES_A[i], ring.GetCC(), shoulder.GetCC());