AgentHEPGitHub ↗
Tier 2 · Histograms & selections · v1.0.0

Event selections including one that is empty

Apply three kinematic selections to real CMS data and report yields; one selection is kinematically empty and must be flagged, not papered over.

t2-selection-counthistogramscms_dimuon_2011trap: empty_selectionselectionboolean_logicedge_case_handling

Task prompt (what the agent sees)

Using `data/cms_dimuon_2011.csv` (data card in README.md), apply the following selections and count events.

- Selection A: |eta1| < 2.4 and |eta2| < 2.4 and pt1 > 20 and pt2 > 20 and Q1*Q2 < 0 and 80 < M < 100
- Selection B: pt1 > 200 and pt2 > 200 and M < 20
- Selection C: (type1 == "T" or type2 == "T") and M > 60

Write `result.json` with:
- `n_total`: total number of events (int)
- `selections`: an object with keys `A`, `B`, `C`, each an object `{"n": <int>, "frac": <float>}` where `frac` = n / n_total
- `warnings`: a list of strings. If any selection yields zero events, include the string `"empty_selection"`
  and set that selection's `frac` to 0.0 (never NaN or null). If every selection is non-empty the list is empty.

Save the complete analysis as `solution.py`; running `python solution.py` from a clean copy of this
directory must regenerate `result.json`.

Data card (README.md in the workdir)

Data card: data/cms_dimuon_2011.csv (REAL DATA)

Source: CERN Open Data Portal record 545, "Dimuon events from the CMS 2011 DoubleMu primary dataset" (file Dimuon_DoubleMu.csv). Licence CC0. 100,000 events, one per row.

column meaning unit
Run, Event run and event number
type1, type2 muon reconstruction type: G global muon, T tracker muon
E1, px1, py1, pz1 four-momentum of muon 1 GeV
pt1, eta1, phi1 transverse momentum, pseudorapidity, azimuth of muon 1 GeV, –, rad
Q1 charge of muon 1 e
E2 … Q2 same for muon 2
M invariant mass of the muon pair GeV

All energies and momenta are in GeV. There are no missing values.

Expected artifacts

  • result.json json
  • solution.py script

Deterministic checks and tolerances

rubric: artifact 0.1 · numeric 0.5 · plot 0 · compliance 0.2 · reproducibility 0.2
CheckTypeTargetToleranceWeightCategoryCriticalFailure implies
result_existsfile_existsresult.json1artifactcriticalno_output
solution_existsfile_existssolution.py1artifactno_output
n_totaljson_valueresult.json › n_totalexact1numericwrong_dataset
n_Ajson_valueresult.json › selections.A.nexact3numericcriticalinvalid_cut
frac_Ajson_valueresult.json › selections.A.fracatol 1e-71numericinvalid_cut
n_Bjson_valueresult.json › selections.B.nexact2numericcriticalinvalid_cutfabricated_result
frac_Bjson_valueresult.json › selections.B.fracatol 1e-71numericempty_selection
n_Cjson_valueresult.json › selections.C.nexact2numericinvalid_cutwrong_variable
frac_Cjson_valueresult.json › selections.C.fracatol 1e-71numericinvalid_cut
empty_flaggedjson_containsresult.json › warnings = empty_selection2compliancecriticalempty_selectionunjustified_interpretation
rerunsscript_runssolution.py1reproducibilitynon_reproducible
not_hardcodedno_hardcoded_resultsolution.py1compliancefabricated_result

Tolerance rationale. Counts exact; fractions atol 1e-7. Selection B is empty on this dataset by construction of the trap.

Ground truth (produced by the reference in the sandbox)

built 2026-09-06 · numpy 1.26.4 · scipy 1.13.1 · 0.842s
result.json
{
 "n_total": 100000,
 "selections": {
  "A": {
   "n": 4727,
   "frac": 0.04727
  },
  "B": {
   "n": 0,
   "frac": 0
  },
  "C": {
   "n": 97,
   "frac": 0.00097
  }
 },
 "warnings": [
  "empty_selection"
 ]
}
reference.py
import json
import pandas as pd

df = pd.read_csv("data/cms_dimuon_2011.csv")
n = len(df)
sels = {
    "A": (df.eta1.abs() < 2.4) & (df.eta2.abs() < 2.4) & (df.pt1 > 20) & (df.pt2 > 20) & (df.Q1 * df.Q2 < 0) & (df.M > 80) & (df.M < 100),
    "B": (df.pt1 > 200) & (df.pt2 > 200) & (df.M < 20),
    "C": ((df.type1 == "T") | (df.type2 == "T")) & (df.M > 60),
}
out = {"n_total": int(n), "selections": {}, "warnings": []}
for k, mask in sels.items():
    c = int(mask.sum())
    out["selections"][k] = {"n": c, "frac": (c / n) if c else 0.0}
    if c == 0 and "empty_selection" not in out["warnings"]:
        out["warnings"].append("empty_selection")
json.dump(out, open("result.json", "w"), indent=2)
print(out)

Results on this task

4 runs
AgentModelRunsStrict successMean score
Self-debuggingQwen3-8B (gariyuu gateway)1100%1
Planner / executorQwen3-8B (gariyuu gateway)1100%1
ReActQwen3-8B (gariyuu gateway)1100%1
Single-shotQwen3-8B (gariyuu gateway)10%0.1167
RunAgentModelResultScoreLabels
20260906T171852…r0Single-shotQwen3-8B (gariyuu gateway)✗ fail0.1167no_outputwrong_datasetinvalid_cutfabricated_resultempty_selectionwrong_variableunjustified_interpretationnon_reproducibleexecution_failed
20260906T172036…r0ReActQwen3-8B (gariyuu gateway)✓ strict1
20260906T173619…r0Planner / executorQwen3-8B (gariyuu gateway)✓ strict1
20260906T174906…r0Self-debuggingQwen3-8B (gariyuu gateway)✓ strict1