Skip to content

madspace: spell the LHEParticle momentum kwargs like its attributes (px/py/pz) - #88

Merged
oliviermattelaer merged 1 commit into
mainfrom
claude/madspace-lheparticle-px
Sep 2, 2026
Merged

oliviermattelaer merged 1 commit into
mainfrom
claude/madspace-lheparticle-px

Conversation

@oliviermattelaer

Copy link
Copy Markdown
Contributor

LHEParticle's constructor took p_x/p_y/p_z while the attributes it sets are px/py/pz, so a caller wrote LHEParticle(p_x=...) and read back particle.px. This renames the three kwargs to match.

Which side was the anomaly

The attributes, it turns out, are the ones that were already right. px/py/pz is what the rest of madspace uses:

  • the C++ struct members — double px, py, pz, energy, mass; (madspace/include/madspace/driver/lhe_output.hpp:50)
  • the npy field layout strings and accessor — {"px", ...}, px() (madspace/include/madspace/driver/io.hpp:60,75,96)
  • the observable enum — obs_px
  • every kernel local (chili.hpp, rambo.hpp, observables.hpp, kinematics.hpp)

Across the whole repo, p_x as a madspace identifier appeared only on those three py::arg lines and the single test caller. Checking all 451 py::arg sites in madspace.cpp against their classes' def_readwrite/def_readonly names, LHEParticle is the only class with a kwarg/attribute spelling split — LHEEvent, LHEMeta, LHEProcess and SubprocArgs are all consistent.

Is this breaking, and who does it affect

Yes, p_x= stops working. In practice the blast radius is one line:

  • In this repo: LHEParticle is constructed from Python in exactly one place, madspace/tests/test_lhe.py:132, updated here. The mg7 production path (madevent.py, gridpack.py) goes through combine_to_lhe, which builds particles C++-side and never names these kwargs. MadSpin does not touch it. Same on all 60 origin/* branches: every one has p_x= on that one test line and nowhere else.
  • Outside this repo: madspace 0.1.3 is on PyPI and its shipped .pyi does carry p_x in the public signature, so this is a real public API rather than something repo-internal. Anyone pinned to madspace==0.1.3 keeps the old wheel; the break lands whenever the next release is cut (the in-repo version is still 0.1.3, so a bump is needed before publishing regardless).

Why a rename rather than accepting both spellings

A second py::init with the px names does work under pybind's two-pass overload resolution, but it is not clean here: it publishes two near-identical 13-argument overloads in help(), in every TypeError message and in the generated .pyi, and a mixed call like LHEParticle(px=1., p_y=2.) fails both overloads with a doubly-confusing error. That is a worse public API than either single spelling.

The deciding factor is that the project has already made this exact call. 20b692d ("Update spelling of color and add test dependencies to toml") renamed the public pybind kwarg colour_order → color_order — the same kind of pure spelling normalisation — as a straight rename with no alias and no deprecation, updating the one test that used it. madspace has no deprecation machinery anywhere. This follows that precedent, which is also why it targets main rather than waiting for a release or development branch.

The checked-in .pyi is generated at build time by generate_pyi.py, so it picks the new names up automatically; nothing to hand-edit.

Test

test_particle_momentum_kwargs_match_attributes in madspace/tests/test_lhe.py pins the constructor to px/py/pz and asserts p_x/p_y/p_z are rejected. Before the change it fails with TypeError: __init__(): incompatible constructor arguments (along with the 12 tests using the updated build_event helper).

pytest madspace/tests: 1475 passed, 2 skipped. That reconciles with the 1470-pass main baseline as 1470 + 4 (the test_double_t.py scipy tests, which pass here because this env has scipy 1.18.1) + 1 (the new test). test_flow.py/test_mlp.py remain uncollectable without torch.

Relation to the other open madspace PRs

Touches the same file as #87 but not the same lines (#87 is LHEEvent's alpha_qcd binding at ~1622, this is LHEParticle's kwargs at ~1584), so the two merge independently in either order. Independent of #86, which targets the MadSpin perf branch.

🤖 Generated with Claude Code

LHEParticle's constructor took p_x/p_y/p_z while the attributes it sets
are px/py/pz, so a caller wrote LHEParticle(p_x=...) and read particle.px.

px/py/pz is the spelling used everywhere else: the C++ struct members
(lhe_output.hpp), the npy field layout and accessors (io.hpp), the
observable enum (obs_px) and every kernel. The three py::arg names were
the only place in madspace spelled p_x -- they are the anomaly, not the
attributes.

This follows 20b692d, which renamed the public kwarg colour_order to
color_order the same way: a straight rename, no alias, updating the one
test that used it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@oliviermattelaer

Copy link
Copy Markdown
Contributor Author

@theoheimel
I guess we can ignore this one but up to you (but would be happy to close it)

@theoheimel

Copy link
Copy Markdown
Contributor

Always good to have consistent naming. Happy to merge this

@oliviermattelaer
oliviermattelaer merged commit d5feaad into main Sep 2, 2026
509 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants