Skip to content

Add AxisExpPolyModel: exponential-polynomial background of any order - #226

Open
pmlugato wants to merge 1 commit into
WMass:mainfrom
pmlugato:axis-exp-poly-model
Open

pmlugato wants to merge 1 commit into
WMass:mainfrom
pmlugato:axis-exp-poly-model

Conversation

@pmlugato

@pmlugato pmlugato commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

AxisExpPolyModel is a per-(process, cell) exponential-polynomial background of any order:

rnorm = exp(lnAmpl_c + sum_k c_k P_k(t))

Here t is the shape-axis coordinate mapped onto [-1, 1] from the axis edges. P_k are polynomials orthonormalised (modified Gram-Schmidt) on the actual bin grid. Order 1 is the AxisExpModel slope. Each higher order adds one direction and nests the order below at zero, so the χ² difference between adjacent orders is a one-parameter likelihood ratio.

Why orthogonalise on the grid. Any degree-N basis spans the same functions, so the fitted optimum is unchanged, but the Hessian is not. On bin centres, nominal Legendre P₂ overlaps the constant at 1e-2. That constant is the free per-cell lnAmpl, so the fit has a nearly flat direction. On the grid the overlaps are below 1e-15 for orders 1–4.

Each order can be grouped over its own subset of the cell axes: for example, an amplitude per cell and a shape shared across cells. All parameters are unbounded.

--paramModel AxisExpPolyModel <channel> <procs> <shape_axis> <cell_axes> <order> [<axes_for_order_1> [<axes_for_order_2> ...]]

We use it for the B+ → J/ψ K+ background in the WRemnants muon-calibration fits. There the measured gain is 2.00× at order 2, 2.03× at order 3, 2.07× at order 4, and nothing at order 5.

Tests

tests/test_axis_exp_poly_model.py (11 tests, passing on main) checks:

  • orthonormality of the basis on the grid for orders 1–4;
  • parameter count and names;
  • a flat background at zero;
  • the analytic order-1 form;
  • nesting of the orders;
  • the degenerate-order and bad-grouping errors;
  • a fit that recovers the parameters it was generated from (|Δ| < 1e-6).

🤖 Generated with Claude Code

rnorm = exp(lnAmpl_c + sum_k c_k P_k(t)) per (process, cell), with the
shape-axis coordinate mapped onto [-1, 1] from the axis edges and P_k
orthonormalised (modified Gram-Schmidt) on the actual bin grid. Order 1 is
the AxisExpModel slope; each higher order adds one new direction and nests
the one below at zero, so adjacent orders differ by a one-parameter
likelihood ratio.

Orthogonalising on the grid rather than using nominal Legendre polynomials
matters for the Hessian: on bin centres, P_2 overlaps the constant at 1e-2,
and the constant is the free per-cell lnAmpl. Here the overlaps are < 1e-15.

Each order can be grouped over its own subset of the cell axes (a shape
shared across cells, an amplitude per cell). All parameters are unbounded.

    --paramModel AxisExpPolyModel <channel> <procs> <shape_axis> <cell_axes> \
        <order> [<axes_for_order_1> [<axes_for_order_2> ...]]

Tests: basis orthonormality, flat background at zero, the order-1 form,
nesting, error handling, and a fit that recovers its generating parameters.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
pmlugato added a commit to pmlugato/WRemnants that referenced this pull request Nov 9, 2026
- rabbit: havynanc/rabbit d31c25c (sparse merge_inputs, POU axis models)
  plus AxisExpPolyModel and the rabbit_plot_cov fix (WMass/rabbit#226,
  WMass#227), as pmlugato/rabbit bplus-combined.
- wremnants-data: the kaon/pion ONNX (hancelin) plus the kaon response
  map and its PCHIP cell list, as plugato/wremnants-data 2023388.

Both get replaced by the upstream commits once those PRs and MRs land.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
pmlugato added a commit to pmlugato/WRemnants that referenced this pull request Nov 9, 2026
- rabbit: havynanc/rabbit d31c25c (sparse merge_inputs, POU axis models)
  plus AxisExpPolyModel and the rabbit_plot_cov fix (WMass/rabbit#226,
  WMass#227), as pmlugato/rabbit bplus-combined.
- wremnants-data: the kaon/pion ONNX (hancelin) plus the kaon response
  map and its PCHIP cell list, as plugato/wremnants-data 2023388.

Both get replaced by the upstream commits once those PRs and MRs land.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issues Found

No issues found.

Summary

Total issues: 0 critical, 0 important, 0 minor.

Overall Verdict

Status: Patch is correct

Explanation: AxisExpPolyModel correctly implements the ParamModel contract: parameter layout (per-process lnAmpl block plus per-order groupings), channel-ordered reshapes, broadcasting in compute, masked-channel handling, and metadata attributes all match the sibling AxisExpModel and the Fitter's expectations. The Gram-Schmidt basis on the bin grid, degenerate-order validation, and CLI parsing behave as documented, and the tests exercise orthonormality, naming, nesting, error paths, and an end-to-end fit recovery using verified tensorwriter/fitter APIs. No qualifying issues found.

Review details
  • Model: cern/Kimi-K3-FLATIRON

Review metrics: 13 turns · 17 tool calls · 5m 11s

  • Tokens: 267.1K input · 241.0K cached (90%) · 18.2K output

@cmsmwbot cmsmwbot Bot added the fit label Nov 9, 2026
@cmsmwbot
cmsmwbot Bot requested review from DickyChant, bendavid and kdlong November 9, 2026 17:14
@cmsmwbot

cmsmwbot Bot commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

CI status — workflow Hodor AI review, run 42661709996: ✅ 1/1 jobs green (slowest/only review, 5m47s). Main CI workflow still in progress at this head.

@cmsmwbot

cmsmwbot Bot commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

CI status — workflow CI, run 42661710587: ✅ 19/19 jobs green (slowest all-unit-tests, 1h20m; run wall time 1h38m at 3a4a09992). Head is green and ready.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant