Skip to content

Drop systematic lines that do not affect any channel/process when cal…#1238

Merged
anigamova merged 2 commits intocms-analysis:mainfrom
maxgalli:fix_comb_cards
Mar 18, 2026
Merged

Drop systematic lines that do not affect any channel/process when cal…#1238
anigamova merged 2 commits intocms-analysis:mainfrom
maxgalli:fix_comb_cards

Conversation

@maxgalli
Copy link
Copy Markdown
Collaborator

@maxgalli maxgalli commented Mar 16, 2026

…ling combineCards.py with --include-channel

As stated in the title, combineCards.py doesn't drop systematics that do not affect any channel/process when keeping only a subset of them (i.e. using --include-channel. This makes the output datacard noisy if one wants to run a simple test with a subset of channels.

I tried this with the Higgs observation model and the following command:

combineCards.py --ic=hgg_7TeV_inc_cat0_7TeV --ic=httem_8TeV_5 125.5/comb_hgg.txt 125.5/comb_htt.txt > 125.5/comb_hgg_htt_pruned_fewsysts_new.txt

Running a simple fit on the output datacard

combine 125.5/comb_hgg_htt_pruned_fewsysts_new.txt --mass 125.5 -M MultiDimFit -v 3 > ex_new.txt

gives the same results before and after the change, as expected.

Summary by CodeRabbit

  • Improvements
    • Automatically detects and removes systematics that do not affect any process or channel, producing cleaner analysis outputs, reducing clutter in reports, and improving overall processing efficiency and performance.

…ling combineCards with --include-channel or --exclude-channel
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 16, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 351c2ba4-c447-404e-a3fd-748415695d44

📥 Commits

Reviewing files that changed from the base of the PR and between f72c9a9 and 08d45f3.

📒 Files selected for processing (1)
  • scripts/combineCards.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • scripts/combineCards.py

📝 Walkthrough

Walkthrough

Adds a pruning step that computes systematics with no effect by comparing systlines against keyline, removes those systematics from systlines, and rebuilds the groups mapping to exclude removed entries.

Changes

Cohort / File(s) Summary
Systematics Pruning
scripts/combineCards.py
Introduces logic to identify and delete systematics that don't affect any process/channel, updates systlines, and rebuilds groups to exclude removed systematics.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 I nibble through lines, checking each one,
Pulling dead systematics out in the sun,
If no channel sighs, I let them depart,
A tidier map warms my rabbit-heart,
Hopping onward with cleaner art.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly summarizes the main change: dropping systematic lines that don't affect channels/processes when using --include-channel option.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

You can get early access to new features in CodeRabbit.

Enable the early_access setting to enable early access features such as new models, tools, and more.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/combineCards.py`:
- Around line 395-399: The current removed_systs comprehension treats any non
"-" value as an active effect but misses lnN nuisances that are neutral (e.g.
"1", "1.0", "1.0/1.0"), so change the predicate in the removed_systs set
comprehension to treat these as no-ops: for each (name, (pdf, pdfargs, effect,
nofloat)) in systlines, retrieve val = effect.get(b, {}).get(p, "-") and
consider it inactive if val == "-" or (pdf == "lnN" and both numerator and
denominator parse to float(1.0) after splitting on "/") (also treat single
numeric "1" or "1.0" as neutral); only mark a syst as active if any such val is
not inactive. Update the comprehension referencing removed_systs, systlines,
pdf, effect and keyline accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f49511ba-efe9-46f7-a6ab-c17ca2560666

📥 Commits

Reviewing files that changed from the base of the PR and between 6a5a27e and f72c9a9.

📒 Files selected for processing (1)
  • scripts/combineCards.py

Comment thread scripts/combineCards.py Outdated
Comment on lines +395 to +399
# Remove systematics that don't affect any process/channel in the combination
removed_systs = {
name for name, (pdf, pdfargs, effect, nofloat) in systlines.items()
if not any(effect.get(b, {}).get(p, "-") != "-" for b, p, s in keyline)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Pruning condition misses neutral lnN effects (and keeps no-op nuisances).

At Line 398, a nuisance is considered active if value is not "-", but for lnN a value of 1.0 (or 1.0/1.0) is also null-effect. This means some systematics that do not affect retained content will not be pruned.

💡 Proposed fix
+# DatacardParser null-effect semantics:
+#   - "-"  -> 0.0 (null)
+#   - lnN: 1.0 (or 1.0/1.0) is also null
+def _has_non_null_effect(pdf, effect, keyline):
+    for b, p, _ in keyline:
+        v = effect.get(b, {}).get(p, "-")
+        if v == "-":
+            continue
+        if pdf == "lnN":
+            try:
+                if "/" in v:
+                    lo, hi = [float(x) for x in v.split("/", 1)]
+                    if lo == 1.0 and hi == 1.0:
+                        continue
+                elif float(v) == 1.0:
+                    continue
+            except ValueError:
+                pass
+        return True
+    return False
+
 removed_systs = {
     name for name, (pdf, pdfargs, effect, nofloat) in systlines.items()
-    if not any(effect.get(b, {}).get(p, "-") != "-" for b, p, s in keyline)
+    if not _has_non_null_effect(pdf, effect, keyline)
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/combineCards.py` around lines 395 - 399, The current removed_systs
comprehension treats any non "-" value as an active effect but misses lnN
nuisances that are neutral (e.g. "1", "1.0", "1.0/1.0"), so change the predicate
in the removed_systs set comprehension to treat these as no-ops: for each (name,
(pdf, pdfargs, effect, nofloat)) in systlines, retrieve val = effect.get(b,
{}).get(p, "-") and consider it inactive if val == "-" or (pdf == "lnN" and both
numerator and denominator parse to float(1.0) after splitting on "/") (also
treat single numeric "1" or "1.0" as neutral); only mark a syst as active if any
such val is not inactive. Update the comprehension referencing removed_systs,
systlines, pdf, effect and keyline accordingly.

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 20.89%. Comparing base (6a5a27e) to head (08d45f3).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #1238   +/-   ##
=======================================
  Coverage   20.89%   20.89%           
=======================================
  Files         195      195           
  Lines       26310    26310           
  Branches     3947     3947           
=======================================
  Hits         5498     5498           
  Misses      20812    20812           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@maxgalli
Copy link
Copy Markdown
Collaborator Author

failure in dev3/latest seems unrelated, as it fails as well in main https://github.com/cms-analysis/HiggsAnalysis-CombinedLimit/actions/runs/23186153523/job/67370052400#step:9:3403

@anigamova
Copy link
Copy Markdown
Collaborator

I see, we should still investigate, but not related to this PR. For this PR, could you please lint with the latest black?

@maxgalli
Copy link
Copy Markdown
Collaborator Author

maxgalli commented Mar 17, 2026

I see, we should still investigate, but not related to this PR. For this PR, could you please lint with the latest black?

That seems to be coming from this root-project/root#13593, Jonas is already on it

@anigamova anigamova merged commit 69ac0b6 into cms-analysis:main Mar 18, 2026
22 of 25 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