Investigate local-frame x/y axis hierarchy (post_dir/travel_dir KL asymmetry) #8

Open
opened 2026-07-08 13:52:22 +02:00 by lbogner · 1 comment
lbogner commented 2026-07-08 13:52:22 +02:00 (Migrated from gitlab.etp.kit.edu)

Investigate whether the local-frame x/y axes carry an unintended hierarchy.

The local-frame rotation (Rodrigues, giant/data/transforms.py:local_frame_rotation) only pins pre_dir → ẑ; the azimuthal orientation about the local z-axis is otherwise left free and should be arbitrary. If the scattering distribution were truly azimuthally symmetric, the x and y components of post_dir/travel_dir should validate near-identically.

But they don't: checkpoint validation shows a notably different KL(real‖gen) for x vs y — e.g. travel_dx 0.00281 vs travel_dy 0.00061. That asymmetry is surprising and suggests either a non-arbitrary orientation is baked into the frame construction (does the azimuthal reference axis privilege one transverse axis?) or there's real azimuthal structure the frame isn't capturing. If it's an artefact, randomise/symmetrise the azimuth; if it's real structure, make sure the model can represent it.

Source: Jan & Tobias meeting 2026-07-07, action item added 2026-07-08.

**Investigate whether the local-frame x/y axes carry an unintended hierarchy.** The local-frame rotation (Rodrigues, `giant/data/transforms.py:local_frame_rotation`) only pins `pre_dir → ẑ`; the azimuthal orientation about the local z-axis is otherwise left free and should be arbitrary. If the scattering distribution were truly azimuthally symmetric, the x and y components of `post_dir`/`travel_dir` should validate near-identically. But they don't: checkpoint validation shows a notably different KL(real‖gen) for x vs y — e.g. `travel_dx` 0.00281 vs `travel_dy` 0.00061. That asymmetry is surprising and suggests either a non-arbitrary orientation is baked into the frame construction (does the azimuthal reference axis privilege one transverse axis?) or there's real azimuthal structure the frame isn't capturing. If it's an artefact, randomise/symmetrise the azimuth; if it's real structure, make sure the model can represent it. Source: Jan & Tobias meeting 2026-07-07, action item added 2026-07-08.
lbogner commented 2026-07-08 14:05:47 +02:00 (Migrated from gitlab.etp.kit.edu)

Finding: the local frame's transverse axes are pinned to the world x/y axes — not arbitrary

Investigated the Rodrigues construction in local_frame_rotation. It uses the minimal rotation carrying pre_dir → ẑ (rotation about pre_dir × ẑ by exactly the angle between them, no extra twist about local z). That fixes the azimuthal reference, and it fixes it to the world frame.

Analytic

The local transverse axes, in world coords (θ, φ = polar/azimuth of pre_dir):

  • local-x → (cosθ + sin²φ·(1−cosθ), −sinφcosφ·(1−cosθ), −cosφ·sinθ)
  • local-y → (−sinφcosφ·(1−cosθ), cosθ + cos²φ·(1−cosθ), −sinφ·sinθ)

As θ → 0 these collapse to x̂ and ŷ. Numerically:

polar angle of pre_dir ⟨local-x · world-x̂⟩ ⟨local-y · world-ŷ⟩
1.000 1.000
0.998 0.998
15° 0.983 0.983
30° 0.933 0.933

For a forward-going particle the local x-axis literally is the world x-axis (local-y = world-y). The frame rotates the polar tilt out but never spins the transverse plane.

What this means for the KL asymmetry

Two verified facts:

  1. The frame itself is x/y-symmetric — identical math on both transverse components, so it cannot manufacture asymmetry. Azimuthally-symmetric scatter about pre_dirstd(dx)=std(dy)=0.1228, means ≈ 0. The travel_dx vs travel_dy KL gap is not a bug in the rotation code.
  2. Because local-x ≈ world-x, genuine world-frame x/y anisotropy passes straight into local dx/dy. A scatter made deliberately wider in world-x than world-y yields local std(dx)/std(dy) ≈ 3.0 — the world anisotropy is inherited verbatim, not washed out.

So the observed asymmetry is almost certainly real world-frame structure: the detector/beam geometry is not azimuthally symmetric in the world x–y plane (layered calorimeter, beam near ±z, transverse detector shape), and the frame passes it through rather than symmetrising it.

Recommendation

  • Do not randomise/symmetrise the azimuth. That would destroy physically meaningful world-x vs world-y information — turn real structure into noise.
  • Per the issue's second branch: it is real structure, and the model can already represent it (post_dir/travel_dir keep full 3D local components, and local-x tracks world-x so the net sees the asymmetry directly). The open question is whether the model is fitting it well — the KL gap suggests dx is fit worse than dy — which is a capacity/loss-weighting question, not a frame-construction one.

Follow-up to close the loop

Confirm from a parquet file that (a) pre_dir is forward-peaked (beam along ±z) and (b) the world x/y marginals of the true scattering genuinely differ. That would nail it as real physics.

(Verified with a numerical experiment on the actual local_frame_rotation/inv_local_frame_rotation implementation.)

## Finding: the local frame's transverse axes are pinned to the *world* x/y axes — not arbitrary Investigated the Rodrigues construction in `local_frame_rotation`. It uses the **minimal rotation** carrying `pre_dir → ẑ` (rotation about `pre_dir × ẑ` by exactly the angle between them, **no extra twist about local z**). That fixes the azimuthal reference, and it fixes it to the *world* frame. ### Analytic The local transverse axes, in world coords (θ, φ = polar/azimuth of `pre_dir`): - local-x → `(cosθ + sin²φ·(1−cosθ), −sinφcosφ·(1−cosθ), −cosφ·sinθ)` - local-y → `(−sinφcosφ·(1−cosθ), cosθ + cos²φ·(1−cosθ), −sinφ·sinθ)` As θ → 0 these collapse to x̂ and ŷ. Numerically: | polar angle of pre_dir | ⟨local-x · world-x̂⟩ | ⟨local-y · world-ŷ⟩ | |---|---|---| | 1° | 1.000 | 1.000 | | 5° | 0.998 | 0.998 | | 15° | 0.983 | 0.983 | | 30° | 0.933 | 0.933 | **For a forward-going particle the local x-axis literally *is* the world x-axis** (local-y = world-y). The frame rotates the polar tilt out but never spins the transverse plane. ### What this means for the KL asymmetry Two verified facts: 1. **The frame itself is x/y-symmetric** — identical math on both transverse components, so it *cannot* manufacture asymmetry. Azimuthally-symmetric scatter about `pre_dir` → `std(dx)=std(dy)=0.1228`, means ≈ 0. **The travel_dx vs travel_dy KL gap is not a bug in the rotation code.** 2. **Because local-x ≈ world-x, genuine world-frame x/y anisotropy passes straight into local dx/dy.** A scatter made deliberately wider in world-x than world-y yields local `std(dx)/std(dy) ≈ 3.0` — the world anisotropy is inherited verbatim, not washed out. So the observed asymmetry is almost certainly **real world-frame structure**: the detector/beam geometry is not azimuthally symmetric in the world x–y plane (layered calorimeter, beam near ±z, transverse detector shape), and the frame passes it through rather than symmetrising it. ### Recommendation - **Do not randomise/symmetrise the azimuth.** That would destroy physically meaningful world-x vs world-y information — turn real structure into noise. - Per the issue's second branch: it *is* real structure, and the model can already represent it (`post_dir`/`travel_dir` keep full 3D local components, and local-x tracks world-x so the net sees the asymmetry directly). The open question is whether the model is *fitting* it well — the KL gap suggests dx is fit worse than dy — which is a capacity/loss-weighting question, **not** a frame-construction one. ### Follow-up to close the loop Confirm from a parquet file that (a) `pre_dir` is forward-peaked (beam along ±z) and (b) the world x/y marginals of the true scattering genuinely differ. That would nail it as real physics. _(Verified with a numerical experiment on the actual `local_frame_rotation`/`inv_local_frame_rotation` implementation.)_
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: lars/giant#8