From 043ff0e864b5b302b4f64fa4c74e7482c841222c Mon Sep 17 00:00:00 2001 From: leonarski_f Date: Sat, 27 Jun 2026 23:58:45 +0200 Subject: [PATCH] docs: mosaicity MLE search-window fix + capture-aware rotation precision (CPU_DATA_ANALYSIS) Co-Authored-By: Claude Opus 4.8 --- docs/CPU_DATA_ANALYSIS.md | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/docs/CPU_DATA_ANALYSIS.md b/docs/CPU_DATA_ANALYSIS.md index e7ff6a34..46440e0b 100644 --- a/docs/CPU_DATA_ANALYSIS.md +++ b/docs/CPU_DATA_ANALYSIS.md @@ -555,13 +555,29 @@ Operationally, predictions for still data may use a cutoff proportional to this ### 11.2 Mosaicity from rotation data (maximum likelihood) -For rotation data, Jungfraujoch can estimate mosaicity by maximizing a likelihood based on the XDS reflection fraction $R(\tau;\sigma_M/\zeta)$ as described by Kabsch (2010). In brief: +For rotation data, Jungfraujoch estimates mosaicity by maximizing a likelihood based on the XDS reflection fraction $R(\tau;\sigma_M/\zeta)$ as described by Kabsch (2010). In brief: -- compute angular deviations $\tau$ from predicted Bragg positions, -- compute $\zeta$ for each reflection, -- maximize $\sum \log R(\tau)$ over $\sigma_M$. +- for each indexed spot, find its exact Bragg angle and the angular deviation $\tau$ from the frame, +- compute $\zeta$ (the Lorentz/rotation-axis factor) for each reflection, +- maximize $\sum_i \log R(\tau_i;\sigma_M/\zeta_i)$ over $\sigma_M$ (golden-section search). -This yields a physically meaningful mosaicity estimate tied to the rotation partiality model. +This yields a physically meaningful mosaicity estimate that feeds the rotation prediction (§8.3) and the rotation partiality model (§10.2). + +**Search-window caveat (important).** The per-spot Bragg angle is located by searching $\phi$ in a window around the frame. That window must be **wider than the oscillation** — wide enough to admit reflections recorded at large rocking offset (those with $|\tau|$ up to $\sim\sigma_M + \Delta\phi/2$). These tail reflections are exactly the ones that *carry the information about the mosaic width*: if the window is only $\pm\Delta\phi$ (the oscillation), the $\tau$ distribution is truncated at the oscillation width and the MLE **underestimates $\sigma_M$ by roughly $2\times$** (e.g. $0.066°$ instead of the true $0.13°$ on the HEWL test crystal). Jungfraujoch therefore searches $\pm(\Delta\phi + 0.8°)$; the MLE is then insensitive to widening further, because it weights each spot by its recorded fraction $R(\tau)$ which decays for large $|\tau|$. + +**Do not re-refine mosaicity during scaling.** The mosaicity also appears in the per-image scaling fit (§10.1), where it is *degenerate with the per-image scale* $G$ (both rescale the predicted intensity). A free refinement there collapses $\sigma_M$ toward its lower bound, undoing the estimate above. The scaling step therefore holds the indexing mosaicity **fixed**. + +**Why it matters.** A too-small mosaicity has two compounding effects on rotation integration: (i) the prediction (§8.3) admits each reflection on too few frames, truncating its rocking curve; and (ii) the rotation partiality $p$ (§10.2) is over-peaked, so dividing each frame’s partial by $p$ to recover the full amplifies error. The net result is rot3d-combined fulls (§10.4) that are substantially noisier per observation. Correcting the mosaicity is the single largest lever for rotation per-observation precision (asymptotic $I/\sigma$, “ISa”). + +### 11.3 Per-observation precision of rotation fulls (capture-aware weighting) + +In the rot3d combine (§10.4), one reflection’s per-frame partials are weight-summed into a single “full”. A full that was only captured over a fraction $f<1$ of its rocking curve is *extrapolated* — and these under-captured fulls are systematically biased and noisy (the partiality division magnifies error in the tail). Jungfraujoch charges the unobserved fraction as an extra systematic uncertainty, +$ +\sigma^2 \leftarrow \sigma^2 + \big(c\,(1-f)\,I\big)^2, +$ +with captured fraction $f=\min(1,\sum_j p_j)$ and coefficient $c$ (`--capture-uncertainty`, default $1.0$ for rot3d). The merge then down-weights the over-extrapolated fulls and the error model treats their scatter as expected, improving both precision (ISa) and accuracy (anomalous peak height). Unlike post-hoc outlier rejection, this corrects a real systematic rather than trading accuracy for $\mathrm{CC}_{1/2}$. + +Together with the mosaicity fix (§11.2), this brings the HEWL rotation crystal to roughly the ceiling of XDS’s per-image/absorption correction surfaces; the residual difference to XDS is the finer (azimuthal absorption, per-frame $B$) corrections, which are small here. ---