Skip to content

TensorWriter: tame statistically-empty-bin systematics (clip / zero-low-neff)#146

Merged
davidwalter2 merged 1 commit into
WMass:mainfrom
lucalavezzo:tame-empty-bin-systematics
Jul 21, 2026
Merged

TensorWriter: tame statistically-empty-bin systematics (clip / zero-low-neff)#146
davidwalter2 merged 1 commit into
WMass:mainfrom
lucalavezzo:tame-empty-bin-systematics

Conversation

@lucalavezzo

Copy link
Copy Markdown
Collaborator

Problem

In dense log-normal datacards, thin backgrounds have bins whose nominal is a mixed-sign NLO weight-cancellation residual, so the effective sample size n_eff = sumw**2/sumw2 is << 1 (down to ~1e-6). There the systematic ratio logk = log(syst/nom) is pure floating-point noise and reaches |logk| ~ 40–55, so the varied yield nom*exp(logk) blows up to ~1e15–1e20. This is what debug_inputdata flags and what makes rabbit_plot_inputdata explode.

Changes (both opt-in, off by default)

  • clip_syst_variations=x — clip each bin's up/down factor to [1/x, x]. Also fixes a real bug in get_logk: the clip was applied to the local _logk but the function returns _logk_view, so the clip never took effect for the returned value (there was even a FIXME noting this). Now the returned array is clipped.
  • zero_syst_low_neff=thr (+ zero_syst_low_neff_procs) — at write() time, zero every systematic's logk in any (bin, process) with n_eff < thr. Keeps the unbiased nominal, removes only the meaningless systematic lever, and — unlike clipping — cleans the card itself so debug_inputdata/rabbit_plot_inputdata come out clean. Handles dense and sparse storage; restrictable to a list of processes (default: all).

Validation

On a real 4D Z datacard (49920 bins × 4 procs × 3746 systs), a build with zero_syst_low_neff=1 produces a card byte-identical to an independent post-hoc reference across every dataset (hnorm/hsumw/hsumw2/hdata_obs/hlogk). Only backgrounds are flagged (Ztautau/PhotonInduced/Other); the signal has no low-n_eff bins, so the all-process default is safe.

Note: the WRemnants setupRabbit.py CLI that exposes these (--clipSystVariations, --zeroSystLowNeff) is a separate WRemnants PR and depends on this one.

🤖 Generated with Claude Code

Near-empty bins whose nominal is a mixed-sign NLO weight-cancellation
residual have n_eff = sumw**2/sumw2 << 1. There a log_normal systematic
ratio logk = log(syst/nom) is floating-point noise reaching |logk| ~ 40-55,
so the varied yield nom*exp(logk) blows up to ~1e15-1e20. This is what
debug_inputdata flags and what makes rabbit_plot_inputdata explode.

Two opt-in TensorWriter knobs (both off by default):

- clip_syst_variations=x: clip each bin's up/down factor to [1/x, x].
  Also fixes a real bug in get_logk: the clip was applied to _logk but the
  function returns _logk_view, so it never took effect for the returned
  value; now clip the returned array.
- zero_syst_low_neff=thr (+ zero_syst_low_neff_procs): at write() time, zero
  every systematic's logk in any (bin, process) with n_eff < thr. Keeps the
  unbiased nominal, removes only the meaningless systematic lever, and cleans
  the card so debug/plot tools come out clean. Handles dense and sparse
  storage; restrictable to a list of processes (default: all).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
lucalavezzo added a commit to lucalavezzo/WRemnants that referenced this pull request Jul 21, 2026
Add two opt-in CLI flags (both off by default) that forward to the rabbit
TensorWriter knobs of the same name:

- --clipSystVariations X: clip each bin's log_normal up/down factor to [1/X, X].
- --zeroSystLowNeff X (+ --zeroSystLowNeffProcs): zero every systematic's logk
  in any (bin, process) with n_eff = sumw^2/sumw2 < X. Tames the ~1e15-1e20
  blow-ups from mixed-sign NLO weight-cancellation-residual bins in thin
  backgrounds (Ztautau/PhotonInduced/Other) that break debug/plot tools.

Requires the corresponding rabbit TensorWriter change (WMass/rabbit#146).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
lucalavezzo added a commit to lucalavezzo/WRemnants that referenced this pull request Jul 21, 2026
Add two opt-in CLI flags (both off by default) that forward to the rabbit
TensorWriter knobs of the same name:

- --clipSystVariations X: clip each bin's log_normal up/down factor to [1/X, X].
- --zeroSystLowNeff X (+ --zeroSystLowNeffProcs): zero every systematic's logk
  in any (bin, process) with n_eff = sumw^2/sumw2 < X. Tames the ~1e15-1e20
  blow-ups from mixed-sign NLO weight-cancellation-residual bins in thin
  backgrounds (Ztautau/PhotonInduced/Other) that break debug/plot tools.

The new knobs are forwarded to TensorWriter only when actually set, so this
script remains compatible with rabbit versions predating them. Using the flags
requires a rabbit with these TensorWriter arguments (WMass/rabbit#146).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@davidwalter2
davidwalter2 merged commit 5a01cb4 into WMass:main Jul 21, 2026
62 of 68 checks passed
lucalavezzo added a commit to lucalavezzo/WRemnants that referenced this pull request Jul 21, 2026
WMass/rabbit#146 is merged (5a01cb4), adding the TensorWriter
clip_syst_variations / zero_syst_low_neff arguments that the new
setupRabbit flags forward to. Bumps the pin 948a94a -> 5a01cb4 (only WMass#146
in between) so --clipSystVariations / --zeroSystLowNeff are usable.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
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