From 9ad88f048be50f3e7b17385fa8dfde3cdae19d56 Mon Sep 17 00:00:00 2001 From: x12sa Date: Wed, 23 Sep 2026 10:05:31 +0200 Subject: [PATCH] docs(flomni): document that PandA stdev needs the analog cap-sensor term Cross-checked PandA's raw within-point sample stdev against RT's own per-point control-loop stdev on S06313. Confirmed the capacitive-sensor subtraction from the position conversion formula isn't optional for a noise estimate either: dropping it (interferometer counts alone) gives a noise estimate ~10x too large and nearly uncorrelated with RT's (r~0.2), because interf and cap are anti-correlated at r~-0.96 within a point. With the full formula, PandA and RT's independent stdev estimates agree to ~8-14% and correlate at r~0.98-0.99. Also flags average_stdeviations_x_st_fzp/_y as a cumulative-mean field, not a per-point stdev, to avoid it being used by mistake in a future session. --- .../AI_docs/PANDA_POSITION_VALIDATION.md | 68 ++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/AI_docs/PANDA_POSITION_VALIDATION.md b/csaxs_bec/bec_ipython_client/plugins/flomni/AI_docs/PANDA_POSITION_VALIDATION.md index b797064d..1dfd1054 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/AI_docs/PANDA_POSITION_VALIDATION.md +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/AI_docs/PANDA_POSITION_VALIDATION.md @@ -47,7 +47,11 @@ and known-good (used successfully in reconstruction): not against `target_x`/`_y`. - `rt_positions_data_stdev_x_st_fzp`/`_y` — RT's own per-point stdev, useful as a sanity scale for how much residual noise to expect (order 0.005 µm in - the validated scan). + the validated scan). See §9 for a raw-PandA cross-check against this value. + Don't confuse this with `rt_positions_data_average_stdeviations_x_st_fzp`/ + `_y`, which is a running/cumulative mean of `stdev_x_st_fzp` up to that + point in the scan (confirmed by direct comparison, 2026-09-23), not a + per-point noise value — it's the wrong field for a per-point comparison. One row per scan point (472 points in the validated scan, `S06313`). @@ -351,3 +355,65 @@ never overlaps a gated exposure. **Reduced data mode** (`S00399`) validated cleanly at full accuracy — see §6 for the row-count/gate-fraction characterization. No contamination, no missing points, same R² bar as the other burst scans. + +## 9. Per-point stdev cross-check against RT's control-loop stdev (`S06313`, 2026-09-23) + +Besides the per-point mean position (§4), PandA's raw samples let you +cross-check RT's own per-point noise estimate +(`rt_positions_data_stdev_x_st_fzp`/`_y`, §2) against an independent +measurement — a single-frame scan has ~998 raw PandA samples landing within +each point's gate window (`CLOCK1`'s free-running rate over one exposure), +so each point's within-group sample scatter is itself a noise estimate. + +### 9.1 Method + +For each grouped point (§3.2, after applying §3.3's stale-prefix drop where +needed), compute `pos_x_um`/`pos_y_um` (§3.4's full formula) **per +individual raw sample**, not just on the group mean, then take the +within-group sample stdev (`ddof=1`). Compare against +`rt_positions_data_stdev_x_st_fzp`/`_y` (not +`average_stdeviations_x_st_fzp`/`_y` — see the note in §2). + +### 9.2 The analog `cap_voltage_fzp_x`/`_y` term is required, not optional + +Naively computing per-sample stdev from `interf_st_fzp_x`/`_y` alone +(skipping the `CapX_FZP_microns`/`CapY_FZP_microns` subtraction in §3.4) +gives a wildly wrong noise estimate: + +| | X stdev (µm) | Y stdev (µm) | corr. with RT stdev (472 points) | +|---|---|---|---| +| Interferometer only, no cap term | 0.072 | 0.049 | 0.22 / 0.24 | +| Full formula (interf − cap, §3.4) | 0.0074 | 0.0063 | 0.98 / 0.99 | +| RT's own stdev | 0.0065 | 0.0058 | — | + +Within a single point, `interf_st_fzp_x` and `cap_voltage_fzp_x` are +anti-correlated at **r ≈ −0.96** (checked on point index 5, n=998 raw +samples). The raw interferometer counts carry a large common-mode +noise/drift component roughly 10x bigger than the true positional noise; the +capacitive-sensor subtraction in §3.4 is what cancels it — the same +combination that's already required for the mean position (§4) turns out to +be even more load-bearing for the noise estimate. Both `FMC_IN.VAL1/VAL2` +(the capacitive analog inputs) and `INENC1`-`4.VAL` (the encoder position +inputs) are captured with `CAPTURE=Value` off the same `CLOCK1` tick (see +`docs/developer/panda_box_free_running_setup.md`), so this isn't a +sampling-rate mismatch between the two channels — the interferometer signal +genuinely is that much noisier on its own. + +**Practical implication:** any future per-sample noise/variance analysis of +Mode B data must use the full interf+cap combination (§3.4), never the raw +interferometer signal alone — skipping the cap term breaks the noise +estimate far more severely than it breaks the mean position. + +### 9.3 Result (`S06313`, all 472 points) + +PandA's within-point stdev (full formula) runs ~8–14% higher than RT's own +stdev (X: 0.0074 vs 0.0065 µm; Y: 0.0063 vs 0.0058 µm), and the two +independent noise estimates correlate at r ≈ 0.98 (X) / 0.99 (Y) +point-by-point. The small systematic excess is expected, not a discrepancy: +RT's stdev comes from its own already-averaged control-loop samples, while +PandA's ~998 raw samples per point pick up additional high-rate noise RT's +loop doesn't report, plus whatever small residual noise the interf/cap +combination itself adds. This doesn't affect the mean-position validation in +§4 (a noise-floor cross-check, not a bias check) — it's a useful additional +confirmation that PandA's raw stream and RT's control loop are seeing +consistent underlying physics, not just consistent means.