fix: align Lorentz/planar coordinate conventions across signatures#717
fix: align Lorentz/planar coordinate conventions across signatures#717henryiii wants to merge 3 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #717 +/- ##
==========================================
+ Coverage 87.72% 87.73% +0.01%
==========================================
Files 96 96
Lines 11193 11206 +13
==========================================
+ Hits 9819 9832 +13
Misses 1374 1374 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
dc55130 to
09245bb
Compare
Several compute functions produced different results for the same vector depending on which coordinate system it was stored in. Align them with ROOT's TLorentzVector conventions: - Et: make xy_z_t/xy_z_tau sign-preserving in energy (copysign on t), matching the rhophi/theta/eta variants and ROOT's Et(). - Mt/Mt2: drop the clamp on the tau-variants and make Mt sign-preserving via copysign-sqrt, so transverse-spacelike vectors agree between the T and Tau representations (and match ROOT's Mt()). - scale: scale tau by |factor| so a negative factor no longer flips a timelike vector into the spacelike (negative-tau) encoding. - planar unit: rhophi now sends the zero vector to 0 (like the xy variant and spatial/unit.py) instead of returning (1, phi). - spatial eta: add the same nan->0 guard to rhophi_theta that xy_theta already had for theta outside (0, pi). Updates two scale tau-coordinate tests and the sympy Mt _t assertions that encoded the previous (inconsistent) behavior, and adds regression tests for each case. Part of #711 Assisted-by: ClaudeCode:claude-opus-4.8
All 168 parametrizations of test_isSpacelike now match ROOT for the PtEtaPhiM coordinate system after the coordinate-convention fix, so the function-level xfail marker is removed to restore a hard PASS signal. Assisted-by: ClaudeCode:claude-opus-4.8
09245bb to
146f25f
Compare
|
🤖 AI text below 🤖 Ran the full ROOT comparison suite ( ~73% of the previously-marked-failing ROOT comparisons now pass (36635 XPASS vs 13231 still XFAIL). The big wins are concentrated in the Lorentz systems (
Removed it (now a hard Follow-up candidates (still 100% xfailing, untouched by this change): the |
Commit 146f25f dropped test_isSpacelike on the assumption that all 168 parametrizations matched ROOT, but that was only true on macOS. The constructor (1, 2, 3, 0) is exactly massless, so tau = sqrt(t^2 - |p|^2) of a true zero rounds platform-dependently: positive on macOS (timelike, matches ROOT's isSpacelike() == False) but negative on the Linux CI runner (spacelike == True), failing test_isSpacelike[to_xyzt-constructor8] and [to_rhophizt-constructor8]. Re-add the non-strict xfail so the lightlike-boundary cases are tolerated while the matching parametrizations still report XPASS. Assisted-by: ClaudeCode:claude-opus-4.8
🤖 AI text below 🤖
Summary
Several
_computefunctions returned different results for the same vector depending on which coordinate system it was stored in. This PR aligns them so all 12 Lorentz coordinate systems (and the planar/spatial helpers) agree, following the project convention of matching ROOT'sTLorentzVector/Math::LorentzVector.Each fix was reproduced before being changed; regression tests cover both the T- and Tau-coordinate representations.
Bugs fixed
Etsign convention differed by signature.xy_z_t/xy_z_taureturnedsqrt(Et2)(always ≥0) while thetheta/eta/rhophivariants returnedt·sinθ(sign-preserving int). E.g.vector.obj(px=3, py=4, pz=0, E=-13).Etgave+13butvector.obj(pt=5, phi=0, pz=0, E=-13).Etgave-13. Nowxy_z_*usecopysign(sqrt(Et2), t), matching ROOT'sTLorentzVector::Et()(E<0 ? -sqrt(Et2) : sqrt(Et2)).Mt/Mt2disagreed between T and Tau coordinates. The T-variants computedt²−z²unclamped (soMt=nanfor transverse-spacelike vectors), while the Tau-variants clamped withmaximum(…, 0)(givingMt=0). E.g.vector.obj(px=3, py=4, pz=10, E=2).Mt2 == -96,.Mt == nan, but the equivalent tau vector gave0.0. Now both representations return the signedMt2 = t²−z²(the Tau-variants reconstruct it astau2 + rho², wheretau2is the signedcopysign(tau², tau)), andMt = copysign(sqrt(|Mt2|), Mt2), matching ROOT'sMt().Lorentz
scaleflippedtau's sign for negative factors. The Tau-variants returnedtau * factor; since negativetauencodes spacelike, scaling a timelike vector by−2produced a spacelike encoding, disagreeing with the T-coordinate version. Nowtau * |factor|: scaling by λ multipliest²−mag²byλ², so|tau|scales by|λ|and the causal character is invariant. (spatial/scale.pyalready takes|factor|forrho.)Planar
unitof the zero vector was inconsistent.xyusednan_to_num(…, nan=0)(zero →(0,0)) butrhophireturned(1, phi)unconditionally.rhophinow mirrorsspatial/unit.py:rho=0 → 0.spatial/eta.pyinconsistent nan guard.xy_thetawrapped-log(tan(θ/2))innan_to_num(nan=0.0, …)butrhophi_thetareturned the raw expression (givingnanfor θ outside(0, π)). The same guard was added torhophi_theta.All changes stay as array-safe
lib.*expressions, so the numba (register_jitable), awkward, and sympy backends keep working (copysign/maximum/nan_to_numhave sympy shims). Two existingscaletau-coordinate test assertions and the sympyMt_tassertions encoded the previous inconsistent behavior and were updated to the now-consistent values.Convention decisions for maintainer review
These are physics-convention choices — please confirm they match the intended ROOT semantics:
Etis sign-preserving in energy (negativeE→ negativeEt), per ROOTTLorentzVector::Et(). Applied uniformly to all 12 signatures.Mt/Mt2are signed (Mt2 = t²−z²unclamped;Mt = copysign(sqrt(|Mt2|), Mt2)), per ROOTMt(), so transverse-spacelike vectors give a negativeMtrather thannan/0. The previous Tau-variant clamp to0is removed.scalepreserves causal character:|tau|scales by|factor|, sign unchanged. A side effect: for vectors stored in Tau coordinates,(v * negative).tnow reports the (always-positive) reconstructed|t|with the correct timelike/spacelike magnitude instead of the previous sign-flipped value — the two updated assertions intests/compute/test_scale.pyreflect this.unitmaps to the zero vector in bothxyandrhophiplanar representations (matching the spatial backend).Note: a Tau-coordinate vector does not store the sign of
t, so(v*negative).treconstructed from tau is always non-negative; this PR makes its magnitude consistent across coordinate systems but does not attempt to recover the lost sign (out of scope).Tests
Added regression cases for: negative-energy
Etacross all signatures; transverse-spacelikeMt/Mt2across both T- and Tau-coordinate vectors; negativescalefactor on Tau-coordinates (timelike and spacelike); zero-vector planarunitinrhophi(object + numpy); andetafor θ outside(0, π)in bothxy_thetaandrhophi_theta.uv run pytest tests/compute/ tests/backends/test_object.py tests/backends/test_numpy.py tests/backends/test_sympy.py tests/backends/test_awkward.py tests/backends/test_numba_object.py— all green.Part of #711
🤖 Generated with Claude Code