AgentHEPGitHub ↗
Tier 1 · Inspection · v1.0.0

Data-quality audit of a jet table

Count duplicates and missing values in a synthetic jet table whose data card documents a sentinel value and a known merge bug.

t1-missing-auditinspectionsynth_jetstrap: missing_valuestrap: sentinel_valuetrap: duplicated_eventsload_csvread_data_cardmissing_valuesdeduplication

Task prompt (what the agent sees)

Audit the data quality of `data/synth_jets.csv` (one row per jet). Read `README.md` first: it is the
data card and documents the file's conventions. Write `result.json` with exactly these keys:

- `n_rows`: number of rows in the raw file (int)
- `n_duplicate_rows`: number of rows that are exact repeats of an earlier row (int)
- `n_unique_jets`: number of distinct jets, identified as described in the data card (int)
- `n_events`: number of distinct events (int)
- `n_missing_pt`: number of distinct jets whose transverse momentum is missing (int)
- `n_missing_eta`: number of distinct jets whose pseudorapidity is missing, following the data card's convention (int)
- `columns_with_missing`: sorted list of column names that contain any missing value (including the documented sentinel)
- `max_jets_per_event`: maximum number of distinct jets in one event (int)
- `frac_jets_missing_pt`: n_missing_pt / n_unique_jets (float)

Remove duplicate rows (keeping the first occurrence) before computing every quantity except `n_rows`
and `n_duplicate_rows`. 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/synth_jets.csv (SYNTHETIC)

Simulated jet table for 20,000 events, one row per jet, produced by a toy generator with a known seed. This is synthetic data; it is not a measurement.

column meaning unit
event_id event number
jet_index index of the jet within its event, 0 = leading (highest-pt) jet
jet_pt transverse momentum. NaN when jet reconstruction failed. GeV
jet_eta pseudorapidity. The value -999.0 is a sentinel meaning "not measured".
jet_phi azimuthal angle rad
jet_e_mev jet energy. Note the unit: MeV, not GeV. MeV
btag_score b-tagging discriminant in [0, 1]

Known issues

  • A jet is uniquely identified by the pair (event_id, jet_index).
  • Because of a bug in the ntuple merger, some rows are exact duplicates. Duplicates must be removed (keep the first occurrence) before any physics quantity is computed.
  • Jets with missing jet_pt failed reconstruction and must be excluded from any sum over jet pt. Jets with the eta sentinel are otherwise valid (their pt and energy are measured).

Expected artifacts

  • result.json json
  • solution.py script

Deterministic checks and tolerances

rubric: artifact 0.1 · numeric 0.6 · plot 0 · compliance 0.1 · reproducibility 0.2
CheckTypeTargetToleranceWeightCategoryCriticalFailure implies
result_existsfile_existsresult.json1artifactcriticalno_output
solution_existsfile_existssolution.py1artifactno_output
n_rowsjson_valueresult.json › n_rowsexact1numericwrong_dataset
n_dupjson_valueresult.json › n_duplicate_rowsexact2numericcriticalduplicated_events
n_uniquejson_valueresult.json › n_unique_jetsexact2numericcriticalduplicated_events
n_eventsjson_valueresult.json › n_eventsexact1numericwrong_variable
n_missing_ptjson_valueresult.json › n_missing_ptexact2numericmissing_values
n_missing_etajson_valueresult.json › n_missing_etaexact3numericcriticalmissing_valuessentinel_value
cols_missingjson_list_equalresult.json › columns_with_missingexact2numericmissing_valuessentinel_value
max_jetsjson_valueresult.json › max_jets_per_eventexact1numericduplicated_events
frac_missingjson_valueresult.json › frac_jets_missing_ptatol 0.0000011numericmissing_values
rerunsscript_runssolution.py1reproducibilitynon_reproducible
not_hardcodedno_hardcoded_resultsolution.py1compliancefabricated_result

Tolerance rationale. All counts are exact integers; the fraction uses atol 1e-6.

Ground truth (produced by the reference in the sandbox)

built 2026-09-06 · numpy 1.26.4 · scipy 1.13.1 · 0.762s
result.json
{
 "n_rows": 65779,
 "n_duplicate_rows": 1915,
 "n_unique_jets": 63864,
 "n_events": 20000,
 "n_missing_pt": 1277,
 "n_missing_eta": 957,
 "columns_with_missing": [
  "jet_eta",
  "jet_pt"
 ],
 "max_jets_per_event": 6,
 "frac_jets_missing_pt": 0.01999561568332707
}
reference.py
import json
import numpy as np
import pandas as pd

raw = pd.read_csv("data/synth_jets.csv")
n_rows = len(raw)
dup_mask = raw.duplicated(keep="first")
df = raw[~dup_mask].copy()
eta_missing = df["jet_eta"] == -999.0
missing_cols = sorted([c for c in df.columns if df[c].isna().any()] + (["jet_eta"] if eta_missing.any() else []))
result = {
    "n_rows": int(n_rows),
    "n_duplicate_rows": int(dup_mask.sum()),
    "n_unique_jets": int(len(df.drop_duplicates(["event_id", "jet_index"]))),
    "n_events": int(df["event_id"].nunique()),
    "n_missing_pt": int(df["jet_pt"].isna().sum()),
    "n_missing_eta": int(eta_missing.sum()),
    "columns_with_missing": sorted(set(missing_cols)),
    "max_jets_per_event": int(df.groupby("event_id")["jet_index"].nunique().max()),
}
result["frac_jets_missing_pt"] = result["n_missing_pt"] / result["n_unique_jets"]
json.dump(result, open("result.json", "w"), indent=2)
print(result)

Results on this task

4 runs
AgentModelRunsStrict successMean score
Self-debuggingQwen3-8B (gariyuu gateway)10%0.35
Planner / executorQwen3-8B (gariyuu gateway)1100%1
ReActQwen3-8B (gariyuu gateway)10%0.92
Single-shotQwen3-8B (gariyuu gateway)10%0.15
RunAgentModelResultScoreLabels
20260906T171852…r0Single-shotQwen3-8B (gariyuu gateway)✗ fail0.15no_outputwrong_datasetduplicated_eventswrong_variablemissing_valuessentinel_valuenon_reproducibleexecution_failed
20260906T172011…r0ReActQwen3-8B (gariyuu gateway)✗ core only0.92missing_valuessentinel_value
20260906T173433…r0Planner / executorQwen3-8B (gariyuu gateway)✓ strict1
20260906T174829…r0Self-debuggingQwen3-8B (gariyuu gateway)✗ fail0.35no_outputwrong_datasetduplicated_eventswrong_variablemissing_valuessentinel_valuenon_reproducible