Skip to content

axisnorm, axisexp, axisbernstein poi models#131

Merged
davidwalter2 merged 7 commits into
WMass:mainfrom
pmlugato:new-poi-models
May 11, 2026
Merged

axisnorm, axisexp, axisbernstein poi models#131
davidwalter2 merged 7 commits into
WMass:mainfrom
pmlugato:new-poi-models

Conversation

@pmlugato
Copy link
Copy Markdown
Contributor

@pmlugato pmlugato commented Apr 21, 2026

Summary

Adds three new param model classes (AxisNormModel, AxisExpModel,
AxisBernsteinModel) for per-cell signal normalization and exponential or
first-order Bernstein polynomial background parameterization. All three classes
live in rabbit/param_models/param_model.py and are registered in
rabbit/param_models/helpers.py. Multiple models can be composed on a single
fit via repeated --paramModel flags, handled automatically by
CompositeParamModel. Also fixes load_models to derive the composite's
allowNegativeParam from its sub-models rather than from the CLI flag, so axis
models that manage their own reparameterization internally are not incorrectly
squared by the fitter when composited.

Changes

param_model.py

AxisNormModel: new class. Assigns one independent normalization parameter
per (process, cell) where cells are defined by caller-specified axes looked
up from indata.channel_info. allowNegativeParam=True; non-negativity is
enforced by applying tf.square inside compute() (a softplus alternative is
commented out — avoids the zero-gradient saddle at raw=0 but both produce
equivalent results at the minimum). Default raw = sqrt(1) = 1 so norm=1
at initialization. All other channels and processes are left at 1.0.

AxisExpModel: new class. Assigns per-cell lnAmpl and per-group slope
parameters producing rnorm = exp(lnAmpl + slope·x) across the shape axis.
Both parameters are unconstrained reals (allowNegativeParam=True); slope=0
(flat background) is an interior point so the Hessian is non-degenerate there.
Slope can optionally be shared across a coarser axis grouping via an optional
5th CLI argument slope_axes, reducing parameters and stabilizing the Hessian
when per-cell slopes are under-constrained.

AxisBernsteinModel: new class. Assigns two non-negative parameters
(c₀, c₁) per (process, cell) and produces
rnorm(x_m) = c₀·(1−x_m) + c₁·x_m (first-order Bernstein polynomial) where
x_m ∈ [0,1] is the normalized mass bin center. Non-negativity is enforced
via softplus applied inside compute() (allowNegativeParam=True; raw
optimizer parameters are unconstrained reals). Default raw parameter is
softplus⁻¹(1) ≈ 0.5413, so c₀=c₁=1 at initialization (flat unit
background). An alternative (lnAmpl, frac) parameterization is available as
commented-out code: rnorm = 2·exp(lnAmpl)·[sigmoid(frac)·(1−x) + sigmoid(−frac)·x].
This decouples overall amplitude from shape, reducing the near-null-space
dimensionality per near-empty cell from 2D to 1D (same structure as
AxisExpModel), at the cost of less directly interpretable parameters.

param_models/helpers.py

Registers AxisNormModel, AxisExpModel, and AxisBernsteinModel in the
built-in model loader so they resolve without a full dotted module path.
load_models derives the composite's allowNegativeParam as
any(m.allowNegativeParam for m in models) so that axis models with
allowNegativeParam=True are not incorrectly squared by the fitter when used
inside a CompositeParamModel.

Usage examples

# Exponential background with slope shared per eta bin
rabbit_fit.py tensor.hdf5 -o results/ \
  --paramModel AxisNormModel <channel> signal   pt,eta,charge \
  --paramModel AxisExpModel  <channel> bkgExp   mass pt,eta,charge eta

# First-order Bernstein background, one (c₀,c₁) per cell
rabbit_fit.py tensor.hdf5 -o results/ \
  --paramModel AxisNormModel      <channel> signal     pt,eta,charge \
  --paramModel AxisBernsteinModel <channel> background mass pt,eta,charge

@pmlugato pmlugato changed the title axisnorm and axisexp poi models axisnorm, axisexp, axisbernstein poi models Apr 22, 2026
@pmlugato pmlugato marked this pull request as ready for review April 29, 2026 21:23
@davidwalter2 davidwalter2 merged commit 373e103 into WMass:main May 11, 2026
21 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