fix: histosys variations computed against sample nominal (#219)#220
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughHistFactory modifier application is refactored from sequential single-pass to two-pass logic to compute additive variations (histosys) against nominal rates before applying multiplicative modifiers, fixing order-dependent behavior. Regression tests validate the fix across modifier orderings. Mypy configuration updated for pytensor import compatibility. ChangesHistFactory Modifier Order Bug Fix
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@pixi.toml`:
- Line 27: Tests import the removed symbol directly (e.g. bare "from pytensor
import function") which will break under PyTensor 3.x; either pin PyTensor <3.0
in pyproject.toml to match pixi.toml or update each test
(test_histfactory_interpolations.py, test_histfactory.py, test_generic_parse.py,
test_functions.py, test_pdf.py, test_distributions.py) to guard/conditionalize
the import the same way src/ does (detect pytensor.__version__ or try/except and
import function from the correct submodule or provide a shim). Locate the bare
imports and replace them with the version-guarded import pattern used by the
source files, or add the upper bound to pyproject.toml to prevent installation
of pytensor>=3.0.
In `@tests/test_histfactory.py`:
- Around line 1460-1601: Extend the existing order-invariance test in
TestHistoSysNominalRates.test_modifier_order_invariant by adding a parallel case
that uses a multiplicative "normsys" modifier (instead of "normfactor") to
ensure normsys-before/after-histosys produce identical rates; create a
normsys_spec (type "normsys", same parameter name as the normfactor case) and
construct dist_ns_first = self._make_channel([normsys_spec, histosys_spec]) and
dist_sn_first = self._make_channel([histosys_spec, normsys_spec]), compute
expressions with _compute_expected_rates(...), build functions with
function([...], expr) and assert the two results are equal with
np.testing.assert_allclose (same pattern used for dist_hf_first/dist_nf_first).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 0562fe72-18d6-493d-a13d-5f7ae4dff8c2
⛔ Files ignored due to path filters (1)
pixi.lockis excluded by!**/*.lock
📒 Files selected for processing (8)
pixi.tomlpyproject.tomlsrc/pyhs3/distributions/histfactory/__init__.pysrc/pyhs3/distributions/histfactory/modifiers.pysrc/pyhs3/model.pytests/test_histfactory.pytests/test_normalization.pytests/test_normalization_integration.py
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #220 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 39 39
Lines 2504 2509 +5
Branches 291 294 +3
=========================================
+ Hits 2504 2509 +5 ☔ View full report in Codecov by Sentry. |
fd0777b to
b8b23cc
Compare
…ated rates (#219) HistFactory formula: lambda = (N + sum(delta_histosys(N))) * prod(kappa_mult). Each histosys variation must be computed against the sample nominal N, not the incrementally-modified rates. Previously, modifiers applied sequentially caused histosys to receive already-scaled rates when a multiplicative modifier (e.g. normfactor) appeared first in sample.modifiers, violating the formula. Two-pass approach in _process_sample: - Pass 1: all additive modifiers called with nominal; variation = result - nominal - Pass 2: all multiplicative modifiers applied to (nominal + sum of variations) Also adds backward-compatible pytensor import: tries pytensor.compile.maker first (pytensor >= 3), falls back to pytensor.compile.function (pytensor < 3). Assisted-by: Claude (Anthropic)
b8b23cc to
4980bb3
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/test_histfactory.py`:
- Line 1523: Edit the comment text that reads "nominal=[10.0], histosys1 hi=[15]
lo=[5], histosys2 hi=[12] lo=[8], code0, both alpha=0.5." and remove or correct
the "code0" typo (replace with "alpha" or delete it) so the comment reads
consistently (e.g., "nominal=[10.0], histosys1 hi=[15] lo=[5], histosys2 hi=[12]
lo=[8], both alpha=0.5."). Ensure the updated comment is in the same test block
in tests/test_histfactory.py where that string appears.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: ede92a5e-4f5f-4acc-894f-772a82f77403
📒 Files selected for processing (1)
tests/test_histfactory.py
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Summary
Fixes #219. The
HistoSysModifier.applywas computing variations against the accumulated (already-modified) rates rather than the sample's nominal rates, violating the HistFactory formula:lambda = (N + sum(delta_histosys(N))) * prod(kappa_multiplicative)When a multiplicative modifier (e.g.
normfactor) appeared beforehistosysinsample.modifiers, the histosys variation was computed againstN * muinstead ofN. Similarly, multiple histosys modifiers would chain against each other's output rather than all reference the same nominal.Fix
Restructures
_process_sampleinHistFactoryDistChannelto use a two-pass approach:nominal_rates; we extract just the variationmodifier.apply(ctx, nominal) - nominaland accumulatenominal + sum(variations)No changes to the
ModifierABC or individual modifier classes.Also includes
pytensor.compile.maker/pytensor.compile.functionimport (try pytensor >= 3 path first, fall back to pytensor < 3)mypyoverride and pixi environment pinned to pytensor 2.x for nowTest plan
test_histosys_with_normfactor_uses_nominal-- normfactor-first ordering, alpha=0.5, verifies correct formulatest_two_histosys_variations_sum_against_nominal-- two histosys on same sample both reference original nominaltest_modifier_order_invariant-- [histosys, normfactor] vs [normfactor, histosys] produce identical resultsSummary by CodeRabbit
Bug Fixes
Tests
Chores