Repository navigation
Conversation
… 2024 and 2025 samples
…tion criteria, and enhance control plot variables
…et to both AK8 jets
…ng transforms to collate_fn
…abels, and weights
gen_selection_VV hard-indexed daughters.pdgId[:, 1, 1], assuming every event has 2 gen V bosons each with 2 daughters. Some amcatnloFXFX diboson samples (e.g. WWtoLNu2Q-1Jets-4FS) have events with <2 selected Vs -> "index out of range" -> skim crash. Pad daughters to [., 2, 2] with PAD_VAL before indexing: a no-op for well-formed events (verified byte-identical output on 4934/5000 events of the failing file) and PAD_VAL (no PDGID match) for malformed ones.
The FNAL dcache copy (cmsdcadisk.fnal.gov) of the 2024 TTtoLNu2Q NanoAODv15 files is unreadable: jobs failed 100% with coffea "cannot unpack NoneType" (all input files skipped at pre-processing -> no chunks). The dataset itself is fine at other sites (verified via cms-xrd-global: 624239 events, GloParT3 branches present), so route the 790 2024 TTtoLNu2Q file reads through the global redirector. Only those paths changed.
Same bad-FNAL-dcache-staging issue as TTtoLNu2Q (coffea NoneType/no-chunks): 2024 QCD-4Jets HT-40to70 and HT-70to100, and GluGluHHto4B kl-0p00 also had unreadable cmsdcadisk copies. Route those 3 datasets' file reads through cms-xrd-global (other working 2024 MC left on cmsdcadisk).
FNAL dcache copy of d2138e34-...root is corrupt (_lzma.LZMAError: Corrupt input data), holding the skim job. Same bad-copy pattern as TTtoLNu2Q / QCD_HT-40to70 / QCD_HT-70to100 / GluGlutoHHto4B_kl-0p00; route this dataset through the global redirector to pick a good replica.
…global All 3 skim jobs failed with empty-chunks after preprocessing (coffea 'cannot unpack non-iterable NoneType' - the no-chunks bad-copy variant); cmsdcadisk RunIII2024Summer24NanoAODv15 copies unreadable. Route through the global redirector, same pattern as the other 2024 bad-copy datasets.
Two failure modes on chunks with ~0 selected events, both of which held the job instead of finishing: 1. bbbbSkimmer.getBDT KeyError (e.g. 'bbFatJetPt_JES_up'): a chunk with no fat jets never has its JEC/JMSR-shifted fat-jet branches built, but the jshift loop still iterates the shifts. Wrap getBDT in try/except KeyError and skip the shifted BDT for such a chunk with a warning (re-raise for the nominal shift, which must always be buildable). The chunk fails the >=2-fat-jet selection anyway, so nothing is written for it. 2. run.py pd.read_parquet(dir) 'Unsupported cast from bool to null': a low-yield chunk can write an all-null boolean column that pyarrow cannot unify with another chunk's typed column when reading the whole dir at once. Read the chunk files individually and concat in pandas (which upcasts), recovering the events that did pass; if no chunk wrote output, warn and skip parquet/root (the pickle with the cutflow is always written, so the job exits cleanly). Fixes the held ZZto4L-1Jets (all eras) and TTto4Q skim jobs.
…sent Some PFNano files don't store the LHEScaleWeight branch, so events[0].LHEScaleWeight raised AttributeError in get_scale_weights (reached for TTto* and HH signal). Return None (already the empty-branch behaviour, handled by add_weights) when the field is missing, so the skim job doesn't crash. Surfaced on a 10-event TTto4Q chunk after the empty-chunk getBDT/parquet fixes (7c667fc) let it get further.
Byte-identical to v13_glopartv3.py except the four tagger-column references, swapped to ParT-v2 (ParT3massX2p->ParTmassVis, ParT3TXbb->ParTTXbb). This makes the GloParT-v2 and v3 BDTs differ only in the tagger (padding-mask feature handling otherwise identical to v3), enabling the controlled same-skim v2-vs-v3 comparison.
v15 NanoAOD carries FatJet_globalParT2_* branches: add the ParT2 tagger/mass fields to extra_vars and jmsr_vars (ParTmassVis/Res) so the v13_glopartv2 / AN-23-151 selection can run on the v15 skim (same-skim v2-vs-v3 control). Keep glopart-v3 as the common loose (TXbb>0.3) preselection tagger; the OR presel now includes ParT2 and ParT3.
- LUMI["2022-2024"] = 171388.6 pb-1 (2022+2022EE+2023+2023BPix+2024) - jmsr_vars: add bbFatJetParT3massX2p (glopart-v3 regressed mass) beside the v2 ParTmassVis (was duplicated) - sig_keys_vbf: kvm2p12 (CV=-2.12, wrong sign) -> kv2p12 (CV=+2.12), matching samples_run3 (VBFHHto4B_CV-2p12)
- load_run3_samples: for non-v2 taggers, swap the hardcoded ParTmassVis JMSR-shifted mass columns for the study tagger's regressed-mass name (glopart-v3 -> ParT3massX2p) so a --templates load doesn't error - get_templates: drop sig_keys absent from events_dict (older skims lack some benchmarks / use CV-m2p12 vs CV-2p12) to keep downstream consistent
- --an184-txbb-sfs: AN-23-184 measured GloParT-v3 Zbb SFs (WP<->purity); --borrow-txbb-sfs: v2 Zbb SFs as a v3 proxy (stopgap) - gate all systematic template-building on args.systematics so --no-systematics builds nominal-only templates (no missing-column errors) - select JEC/JMSR-shifted BDT features by their jshift-suffixed names via get_var_mapping (XGBoost applies by column position)
- CreateDatacard: --year 2022-2024 + glopart-v3 choice; explicit era lists (hh_years carries a 2025 placeholder); 2024 uncorr_years handling; drop the 4 theory-ACCEPTANCE shape systs (ps_fsr/isr/QCDScaleacc/PDFacc) that are broken on the v15 skim (nan/degeneracy) -- inclusive lnN theory kept; VBF kv2p12 label - PlotFits: VBF kv2p12 label - corrections: 2024/2025 trigger eff borrows 2023BPix (latest era), not 2023
- gen_selection_V: add GenVLHEPt, the pT of the status-2 LHE W/Z. This is
the variable the 2024 {W,Z}to2Q-2Jets_Bin-PTQQ-X generator filter cuts on
(open-ended pT > X), needed to stitch those samples exactly. NanoAOD's
LHE_Vpt is built from leptons and is 0 for V->qq, and the last-copy GenVPt
is shifted by the parton shower.
- bbbbSkimmer: only use the JMSR / FatJet skim variables that exist in the
input. The central 2024 Summer24 NanoAODv15 samples carry only
globalParT3 branches, so the GloParT-v2 fields added for v15 made the
skimmer crash on them.
- make_filelists_v15: a 2024 MC sample can now list several datasets of the same process; their files are merged into one sample, so the skimmer normalizes them together (sum of genWeights over both), which is the effective-luminosity combination when |genWeight| is the same. - GluGlutoHHto4B kl-1p00: add the TrimmedSyst production (78.4M events) to the PowhegBugFix one (2.0M). Same gridpack apart from the trimmed PDF reweighting list; same genWeight (0.03309), 103 PDF / 9 scale / 4 PS weights and LHE m(HH) as PowhegBugFix and the 2022 sample. Indexed via the global redirector (not fully replicated at FNAL disk). - kl-0p00/2p45/5p00 TrimmedSyst are NOT used: their gridpacks are copies of the kl-1p00 one (powheg.input chhh = 1.0), and the samples have the SM genWeight and m(HH) instead of the labelled kl (chi2/ndf vs 2022 of 1.8e4-1.5e5 / 10, PowhegBugFix 5-16 / 10). - Vto2Q 2024 comment: the Bin-PTQQ samples are open-ended, not exclusive.
For Wto2Q-/Zto2Q- datasets (those with GenVLHEPt), the pickle totals now also hold the sums per bin of the status-2 LHE W/Z pT, over all generated events before any selection (10 GeV bins on [0, 2000) plus under/overflow, so the Bin-PTQQ thresholds and the 2022-2023 PTQQ edges are bin edges): - np_nominal_lhevpt: the per-bin np_nominal (sum of the norm-preserving weights, genWeight x pileup x PS), plus np_nominal_lhevpt_sumw2; - genweight_lhevpt (sum of genWeight) and nevents_lhevpt (raw counts); - np_<syst>_lhevpt for every norm-preserving variation (pileup, ISR, FSR up/down), so each variation can be normalised per bin too. They allow the open-ended 2024 Bin-PTQQ samples to be stitched and normalised per LHE V pT bin (without relying on the samples' cross-section ratios) and each sample's threshold to be checked on all generated events. The skim can only keep preselected events, so these sums cannot be rebuilt afterwards. Parquet output and all existing totals are unchanged (checked byte for byte on V+jets and HH chunks); other datasets get no new keys. The weighted sums are float64 even for an empty chunk, so coffea's accumulate always works.
The 2024 TrimmedSyst ggHH productions labelled kl-0p00, kl-2p45 and kl-5p00 were generated with kl = 1 (their gridpacks are copies of the kl-1p00 one, powheg.input chhh = 1.0), so they are SM HH. They are indexed only to study the bug (e.g. m(HH)), kept separate from the analysis, and never to be used as kappa_lambda points: - make_filelists_v15 / nanoindex_v15: new 2024 category "HHTrimmedSyst" (714 + 658 + 675 files, global redirector) with keys "TrimmedSyst-GluGlutoHHto4B_kl-<X>_kt-1p00_c2-0p00_TuneCP5_13p6TeV". The "TrimmedSyst-" prefix keeps every analysis selector (prefix match on "GluGlutoHHto4B_kl-...") from loading them; no existing entry changes. - xsecs: the three keys get the SM ggHH cross section, which is what they contain (the skimmer scales weights by xsec x lumi, and the loader needs an entry). - submit_configs/skimmer_reskim_2024_hhtrimmedsyst.yaml: 2024 HHTrimmedSyst, 10 files per job (206 jobs), to be submitted with its own skim tag.
…3 W->qq xsecs
The 2024/2025 {W,Z}to2Q-2Jets_Bin-PTQQ-X samples are open-ended (PTQQ > X), so summing them
over-counted V+jets 2-4x above 200 GeV. By default only Bin-PTQQ-100 is loaded; --vjets-stitch
--vjets-stitch-mode range (with --override-tag for the re-skim) stitches all four in LHE V pT
ranges. The 2022-2023 W->qq cross sections are halved because their MadGraph cards generate each
W charge twice; older skims are rescaled at load time with a warning.
…-v3 JMS/JMR
2022 and 2022EE hold two productions each of ttH(bb) and VBF H(bb), and the prefix selectors
loaded both; a case-sensitive exact selector ("=" prefix) now picks one. PostProcess applies
placeholder JMS (1 +- 0.05) and one-sided JMR (1.15, resolution scaling) to the GloParT-v3 mass of
all MC except QCD at load time (--no-glopartv3-jmsr to turn off), and CreateDatacard adds the 2025
JMS/JMR nuisance. Both change the FOM slim-cache key.
… loader Adds opt-in FOM and region options (--fom-b-floor, --fom-scan-bin3, --fom-vbf-floor-at-band, --fail-txbb-floor, --txbb-wp-bin2/3, --fom-fail-match, --save-ntuples) whose defaults keep the previous behaviour. The slim cache now re-evaluates the ttbar BDT-shape SF with the scanned model (new __ttbdtsf key). ABCDnn training gets --fast-loader, and prepare_bdt_data.py more weight columns.
…, robustness fixes Adds placeholder nuisances for the 2025 JER and the 2024/2025 TXbb and ttbar Xbb SFs. Shape shifts into bins with zero nominal yield are now kept (--shape-empty-bin-floor), and the 2024/2025 JMS/JMR shifts come from the full 2024 MC (--jmsr-2425-fullmc). Also guards the qcd_eff seed and the empty-process lnN conversion, freezes the blinded fail-QCD bins consistently in the F-test, and lets run_ftest_hh4b.sh take its inputs from environment variables.
The Orchestration section listed wrapper scripts, nrp/ and plotting scripts that are not committed, and linked a missing notes/ABCDnn.md. It is replaced by a short section on the committed versions/abcd_smvbf.yaml composition config; the example is labelled as a single-era (2022) run.
train.py --n-folds K --fold i keeps the held-out test set, splits the remaining events into K fixed random folds and trains member i on the other K-1 folds, validating on fold i (seed base+i). apply.py --ensemble-dir combines the members per event (median, mean, std, q16, q84 of the weights, TF and purity), saves every member's weights and the member templates with the per-bin (q84-q16)/2 band, and refuses incomplete or inconsistent members. prepare_bdt_data.py accepts the ensemble weight columns. Without these options the behaviour is unchanged.
ABCD_26Oct01_v15_2225_kf20median_abcd_smvbf_bal_xbb: same recipe, events and split as ABCD_26Sep11_v15_2225_2025ew_jet1txbb_abcd_smvbf_bal_xbb, with the data-driven QCD weighted by the per-event median of the 20 ensemble members (w_QCD_A_median).
…legacy fallback good_ak8jets now uses ParT3massX2p (the analysis mass) for the mSD > 50 OR mReg > 0 requirement, falling back to particleNet_mass_legacy when the NanoAOD has no globalParT3 branches. On a 2024D JetMET sync file this changes ak8_numjets by one event and leaves the skim unchanged.
cmantill
reviewed
Oct 13, 2026
cmantill
left a comment
Contributor
There was a problem hiding this comment.
LGTM, left two minor comments.
Also: can you look into the automated review comment on --bdt-inference-chunk-size > 0. " _build_and_score_bdt_events returns a reset index, so the later .loc[mask_negative_vbf] misaligns on frames whose index is not 0..n-1 (for example the 2024/2025 split halves). The default (0) is unaffected."
|
|
||
| # GloParT-v3 regressed mass; fall back to the PNet legacy mass if the NanoAOD has no globalParT3 | ||
| if mreg_str not in fatjets.fields: | ||
| mreg_str = "particleNet_mass_legacy" |
Contributor
There was a problem hiding this comment.
Does this mean that we fall back to particleNet for 2022 and 2023? Does our nanoAOD for 2022 and 2023 have globalParT3?
| # find closest to second fatjet among the remaining jets | ||
| dr1 = jets_away_wo0.delta_r(second_fatjet) | ||
| closest_idx1 = ak.argmin(dr1, axis=1, keepdims=False) | ||
| jet_near_fatjet1 = jets_away_wo0[ak.singletons(closest_idx1)] |
Contributor
There was a problem hiding this comment.
Have we tested the impact on signal?
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This branch extends the boosted HH→4b analysis on the NanoV15 skims from 2022-2024 to 2022-2025, and merges current main (faf1dc2). It builds on #344, #345 and #346, which brought in earlier versions of the transformer, ABCDnn and fom_fast code; the overlapping changes from main's later PRs (#349, #350, #352, #353, #356, #358) were reconciled as listed below.
What it adds
--split-shared-mc): 2024 and 2025 each take one event-parity half of the 2024 MC. Each half is renormalized by its actual generator-weight fraction (1/f) and scaled to its era's luminosity, and the two halves enter the fit as independent eras (no lumi scale-up). TrainBDT and the ABCDnn inference pickles use the same split.--vjets-stitch --vjets-stitch-mode range --override-tag <reskim>stitches all four in LHE V pT ranges. The 2022-2023 W→qq cross sections are halved (each W charge was generated twice), with a load-time rescale for older skims. 2022/2022EE load one ttH(bb) and one VBF H(bb) production instead of two (=exact selector).--no-glopartv3-jmsrto turn off), with the shifted-mass columns named after the tagger's mass. New TXbb SF options (--an184-txbb-sfs,--borrow-txbb-sfs), and--no-systematicsfor nominal-only templates.--jmsr-2425-fullmc). Shape shifts into empty nominal bins are kept (--shape-empty-bin-floor). Guards for the qcd_eff seed and empty-process lnN. The four v15 theory-acceptance shape systematics are dropped (broken templates; the inclusive lnN theory uncertainties stay). F-test helpers (ftest_limits.py, env-drivenrun_ftest_hh4b.sh).--fom-b-floor,--fom-scan-bin3,--fom-vbf-floor-at-band,--fail-txbb-floor,--txbb-wp-bin2/3,--fom-fail-match,--save-ntuples) whose defaults keep the old behavior. The slim-cache key gets one token per change to the loaded frames, and the cache re-evaluates the ttbar BDT-shape SF with the scanned model.train.py --n-folds/--fold,apply.py --ensemble-dir) and a faster loader. Three trained 2022-2025 models: the MC QCD BDT26Sep01_v13_glopartv3_v15_2225, and the data-driven QCD BDTsABCD_26Sep11_v15_2225_2025ew_jet1txbb_abcd_smvbf_bal_xbb(single network) andABCD_26Oct01_v15_2225_kf20median_abcd_smvbf_bal_xbb(k=20 ensemble median).Reconciliation with main
tests/test_mc_split_scaling.pyare unchanged, and--split-shared-mcis defined once.ZZ?/WW?/WZ?selectors (Support 2024/2025 eras (NanoV15) in postprocessing and datacards #349), which drop the decay-specific ZZ/WW/WZ sub-samples that 2022-2023 used to add on top of the inclusive ones. New slim-cache token__dibosonexactfor 2022-2023BPix only.JetMET_Run2025D(the v15 skim has its trigger columns, andLUMI["2025"]includes it).--no-systematicsis honored.QCD-4Jets_HT-andQCD_HT-spellings)."QCD_HT-"literal.--yearargument (default2022-2025) sets the luminosity label.Validation
scripts/make_test_data.pyon the v12 skim, all 291 pass; the integration test's argument set gained this branch's five new options at their parser defaults.--all-files.model.pkl, and the workspace object by object.Follow-ups
good_ak8jetsdefault regressed mass toParT3massX2p, with a fallback to the PNet legacy mass when the NanoAOD has no GloParT-v3.--bdt-inference-chunk-size > 0,_build_and_score_bdt_eventsreturns a reset index, so the later.loc[mask_negative_vbf]misaligns on frames whose index is not 0..n-1 (for example the 2024/2025 split halves). The default (0) is unaffected.