Eras¶
Every run targets one era, or several, passed as --era (see Running several eras).
An era is a CMS data-taking period; choosing one selects the matching datasets, corrections and
NanoAOD input.
--period was renamed to --era
The former --period option, the --<Task>-period forms and a [<Task>] period entry in a
law config now stop at once with 'period' was renamed to 'era' (--era), and a period=
keyword with 'period' was renamed to 'era' (use era=...).
Only the user-facing name changed: output paths (<version>/<Kind>/<era>/…), bundle URIs and
job-file names are as before, so existing outputs are found unchanged. The AnaTuple column
named period (the per-event C++ Period value), the Period enum and the validity_period
cache settings keep their names.
Run 3 eras (current)¶
--era |
Description | √s | NanoAOD (FLAF default version) | HH_bbWW, H_mumu |
|---|---|---|---|---|
Run3_2022 |
2022, pre-ECAL repair | 13.6 TeV | v14, HLepRare skim | v12 MC / 22Sep23 data (DAS) |
Run3_2022EE |
2022, post-ECAL repair ("EE") | 13.6 TeV | v14, HLepRare skim | v12 MC / 22Sep23 data (DAS) |
Run3_2023 |
2023, pre-BPix | 13.6 TeV | v14, HLepRare skim | v12 MC / 22Sep23 data (DAS) |
Run3_2023BPix |
2023, post-BPix install | 13.6 TeV | v14, HLepRare skim | v12 MC / 22Sep23 data (DAS) |
Run3_2024 |
2024 | 13.6 TeV | v15 | v15 (DAS) |
Run3_2025 |
2025 | 13.6 TeV | v15 | v15 (DAS) |
Run3_2026 |
2026 | 13.6 TeV | v15 | v15 (DAS) |
For 2022–2023BPix the framework default reads the HLepRare NanoAOD v14 skims
(skim_2025_v1 under /store/group/phys_higgs/HLepRare/, the era's fs_nanoAOD); only
HH_bbtautau uses them. HH_bbWW and H_mumu override those four eras to read the central NanoAOD
from DAS instead. For 2024–2026 all three analyses read NanoAOD v15 from DAS (apart from the
few datasets that set their own fs_nanoAOD). FLAF itself sets only nano_version: v15 for these
eras and no NanoAOD source: the analyses select DAS through nanoAODVersions in their era configs.
Run 2 eras (legacy, not runnable)¶
FLAF/config/ still has Run2_2016_HIPM, Run2_2016, Run2_2017 and Run2_2018 directories
(13 TeV), but they hold only legacy samples.yaml/triggers.yaml files — no global.yaml and
no datasets.yaml — and the analyses carry at most a Run 2 weights.yaml. Configuration loading
cannot build a run for these eras, and CI covers only the seven Run 3 eras. Treat Run 2 as
unsupported.
Why the split into sub-eras?¶
The detector and its calibration change within a year, so CMS treats those segments as separate eras for analysis:
- 2022 splits at the ECAL endcap repair →
Run3_2022(before) andRun3_2022EE(after). - 2023 splits at the pixel-detector "BPix" installation →
Run3_2023andRun3_2023BPix.
Each sub-era has its own corrections and luminosity, which is exactly why the
configuration system has a per-era layer: FLAF/config/<era>/ and
<analysis>/config/<era>/ carry the era-specific datasets and overrides.
What an era controls¶
- Datasets —
config/<era>/datasets.yamllists the samples available for that era; each entry'snanoAOD:map gives its DAS name per NanoAOD version (22Sep23,v12,v15, …). - NanoAOD input — the table above, set by two keys of the era's
global.yaml.nanoAODVersions: { data: …, mc: … }picks which entry of each dataset'snanoAOD:map is read, through Rucio; when it is not set, the files are listed from the era'sfs_nanoAOD(the HLepRare skims). A dataset with its ownfs_nanoAODis always read from there.nano_versionnames the NanoAOD format the producers are written for (v12has different branches), so it has to match what is read. - Corrections — pileup, b-tagging, trigger and other scale factors are era-specific.
- Signals — resonant/non-resonant signals exist for some eras and not others. For
Run3_2024, VBF and non-resonant ggF HH are on DAS (newPar-naming); resonant Radion/BulkGraviton and X→YH→2B2W are not. - 2024/2025/2026 shared MC — there is no dedicated 2025 or 2026 MC campaign.
All three years use the Summer24 NanoAOD, but jet, PU and tau corrections
differ, so AnaTuple production runs once per era.
Run3_2025andRun3_2026setreuse_mc_from_era: Run3_2024so the 2024 MC dataset list (and theshared_mcsplit) is reused. Each production storesweight_base(all events, this year's luminosity; use for a single-year run) andweight_base_cmb(the same events split by residue between 2024, 2025 and 2026; use for a combined run). The split applies only to MC; data keeps the full year inweight_base_cmb. Select which branch histograms use withweight_base_branch; all three eras default toweight_base, so by default every year uses all of its events with its own luminosity, and the residue split below feeds onlyweight_base_cmb.shared_mclives only on the source era (Run3_2024): a 17:17:4 residue target over modulus 38 (Run3_2024: [ 0, 16 ],Run3_2025: [ 17, 33 ],Run3_2026: [ 34, 37 ]), matching the recorded luminosities 109948.18 : 110730.86 : 25843.26. The actual event split need not match that target. AnaTupleFileTask therefore stores two denominators: the full-sample sum (forweight_base) and the in-era sum (forweight_base_cmb). Each weight isgen × lumi × xs × PU / its_denominator, so both yields stayL·σ. HistTuple multiplies the AnaTuple column named byweight_base_branch(weight_basefor a single-year run,weight_base_cmbfor the combined 24+25+26 run). Until official UParTAK4 shape files exist, 2024+ era overlays omitbtag.normCacheProducer, so HistTuple does not depend on the globalBtagShapecache.modes.<stage>: nonestill loads the correction (needed for WP-id branches) but does not apply scale factors. Missinguncs_to_excludeera keys default to an empty list. The 2026 EGM folder has scale/smear files but noelectron.json, so Electron-ID-SF is loaded from the 2025 file and evaluated with year2025Prompt(not2026Prompt).
Running several eras¶
--era takes one era or several, separated by commas; the eras are set once per invocation
(--<Task>-era is refused with the eras are set once per invocation, with --era):
law run FLAF.Analysis.tasks.HistMergerTask --version v1 --era Run3_2022,Run3_2022EE --workflow htcondor
The list is sorted and duplicates are dropped, so --era Run3_2022EE,Run3_2022 is the same run.
--era Run3_2022 is a run over one era as before, apart from the --branches change described
under Branch numbers.
--era must be one of the known eras
The known eras are the directories FLAF/config/<era>/ whose global.yaml says
era: <era>, and the meta-eras of era_groups: (see Meta-eras); any other
--era stops at once with the list of the known ones
(Troubleshooting).
If a run unexpectedly drops into InputFileTask and queries Rucio for nothing, a wrong
--era/--version combination is the usual cause. See
Troubleshooting.
What a run over several eras does¶
- Every stage up to the launched one runs for all the eras. Each stage is one workflow
whose branches are those of the eras that still need work there: one HTCondor or CRAB
submission and one poll loop per stage, or, with
--workflow local, the branches of all the eras in one driver. - An era whose part of a stage is complete is pruned. It is not asked for anything, so the
intermediate products its outputs were made from are not requested either, even when they have
been removed since (the split AnaTuples after the merge, the histogram chunks replaced by
.mergedmarkers). Adding an era to a finished one submits nothing for the finished era. - A stage whose branch map is read from an earlier stage's output (the file lists of
InputFileTask, the merge plan ofAnaTupleFileListTask) is built only once that output exists for every era of the run, so the slowest era sets the pace at that point. - A run over a list of eras sums nothing across them. Every output of a stage belongs to one
era, as in a run over one era (a
StatInferencecard of a group era is built from several, see below). Summing eras is what a meta-era is for:HistMergerTask --era <meta-era>adds the merged histograms of its eras, andHistPlotTaskplots the sum (see Meta-eras). Combining 2024+2025+2026 also needsweight_base_branch: weight_base_cmbin each of the three eras. - Shared-MC eras (
Run3_2025andRun3_2026reuse the 2024 MC datasets, see above) each produce their own AnaTuples: in a run overRun3_2024,Run3_2025,Run3_2026the shared MC datasets are read three times and written as three sets of AnaTuples, so the work is not shared between the eras. - Every producer checks the era of its events.
AnaTupleMergeTask,HistTupleProducerTaskandAnalysisCacheTaskcount, in the event loop they run anyway, the events whoseperiodcolumn (the C++Periodvalue of the AnaTuple) is not the era the branch runs for, and stop with an error when there is any (placeholder rows,valid == false, carry no era and are skipped). An AnaTuple of another era among the inputs is caught this way. - One driver per era (stages with era branches). The branches of an era are tracked in that
era's job file (see
HTCondor). Two instances of one stage
that share an era never run at once inside one
law run(a luigi resource per job-file directory,flaf_jobs:<directory>, of capacity 1 unless luigi's[resources]configuration section sets another), but two separatelaw runprocesses on the same era are not guarded against each other, exactly as before.
Which tasks take several eras¶
The stages of the production and analysis chain: InputFileTask, AnaTupleCostProbeTask,
AnaTupleFileTask, AnaTupleFileListBuilderTask, AnaTupleFileListTask, AnaTupleMergeTask,
AnalysisCacheTask, AnalysisCacheAggregationTask, HistTupleProducerTask,
PreHistTupleProductionTask, HistFromNtupleProducerTask, HistMergerTask and HistPlotTask
(the classes that set allow_multi_era and era_branches).
HistMergerTask and HistPlotTask also take a meta-era, as one era of its own (they set
allow_meta_era); every other stage given a meta-era runs over its eras instead (see
Meta-eras).
The StatInference tasks take several eras too, without era branches (they set
allow_multi_era only). CreateDatacardsTask and PreprocessShapesTask are one workflow each
whose branches are the cards of the datacard configuration (its eras:, in order, a group era of
its own era_groups: among them -- the datacard configuration's, not the era_groups: of
global.yaml that declares meta-eras), and each branch reads the real eras its card needs. So:
--eramust hold every real era behind the cards: a card is built from all of its sub-eras or not at all, and over fewer eras the run stops withthe cards of <configuration> need <card>: <eras>, which --era does not include; add <eras> to --era. More eras are allowed; they are not carded (ResonantLimitsAndHistPlotTaskplots them).- Their paths and job state belong to the configuration, not to
--era:Datacards/<card>,Hists_preprocessed/<card>and one job filedata/<version>/CreateDatacardsTask/htcondor_jobs_*.json, so a later run over more eras finds the same cards and resumes the same jobs. A job carries the whole--era, and its branch numbers are the workflow's own (--branches 1is the second card). Use one datacard configuration per--version, and do not reorder itseras:while its jobs exist: the job file is named after the branch numbers, which are positions ineras:. - A setting they read once must agree between the eras of the run: the
StatInferenceblock ofglobal.yaml, and thevar_listof a plotted variable between the eras summed in one plot.
Every other task takes one era and refuses several with
<Task> takes one era; got --era Run3_2022,Run3_2023. That covers the analyses' Studies tasks
and BundleTask: bundles stay per era, the stages that ship one require the bundles of each era
that still has work, and an existing bundle of one era is never rebuilt for another. Launch the
tasks that refuse several eras once per era.
Meta-eras¶
A meta-era is a named group of real eras, declared under era_groups: in the analysis's
global.yaml (or FLAF's):
It is given alone as --era (--era Run3_22_23), and what it means depends on the stage:
HistMergerTasksums its eras. Over a meta-era it is one workflow whose branches are the variables every era of the group merges (thevariablesof their histTuple flavour, numbered as over one era). It requiresHistMergerTaskover the eras (one workflow with era branches, so that runs first), and each branch reads the merged file of its variable in every era (MergedHistsTask, an external task atHistMergerTask's output path) and adds them bin by bin into<version>/Hists_merged/<meta-era>/<variable>/<variable>.root. A variation that an era does not have -- a source decorrelated between the eras, such as a per-era jet energy scale -- enters the sum as that era's central histogram of the process, so the source moves only its own era's events.HistPlotTaskplots that sum, into<version>/Plots/<meta-era>/…, labelled by the analysis'sconfig/plot/<meta-era>.yaml(which states the summed luminosity). The processes and uncertainty sources shown are those of every era of the group.- Every other stage runs over the eras of the meta-era, as over the list of them:
law run FLAF.AnaProd.tasks.InputFileTask --era Run3_22_23is the very task of--era Run3_2022,Run3_2022EE,Run3_2023,Run3_2023BPix, with its outputs and job files. A task that takes one era refuses it like any list of eras, and--branchfollows the eras it runs over.
A meta-era beside any other era is refused, the group's own eras included:
--era Run3_2022,Run3_22_23: Run3_22_23 is a meta-era, the sum of …, and is run on its own. The
eras of a group must be known eras and its name must not be one, or a --era naming it stops with
the reason. A meta-era has no configuration of its own: its tasks read the configuration of its
eras, and a setting they read once (the filesystems, the plot settings of HistPlotTask, the
scales) must be the same in all of them, or construction stops with EraDependentValueError
as in Settings that must agree. Its paths, job file
and logs are under the meta-era's name, so they never collide with those of its eras.
Branch numbers¶
Over one era a branch has the number it has in that era's own branch map, as always. Over several eras it is numbered
where the era id is the C++ Period value:
| Era | Run3_2022 |
Run3_2022EE |
Run3_2023 |
Run3_2023BPix |
Run3_2024 |
Run3_2025 |
Run3_2026 |
|---|---|---|---|---|---|---|---|
| Era id | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
An era's branch numbers therefore never depend on the other eras of the run: branch 3 of
Run3_2022EE is 6000003 in every run. With env.sh sourced,
python -m FLAF.Common.Setup --era-branch Run3_2022EE 3 prints it.
--branchestakes these numbers over several eras, for example--era Run3_2022,Run3_2022EE --branches 5000000,5000001,6000000:6000010. Every era of--eramust have at least one selected branch (otherwise drop it from--era), a range has a start and an end and stays inside one era, and every number must belong to an era of the run. Once an era's branch map exists, at least one of its selected numbers must be a branch of it; a run over one era would take a selection naming none of its branches as the whole map, which a run over several eras refuses.--branchis refused over several eras for the stages with era branches: use--era <era> --branch <its number in that era>. AStatInferencecard workflow takes--branch <card number>over several eras.- A run over one era takes that era's own numbers. A number of a run over several eras
(1 000 000 or more) stops with the decoded hint, for example
branch 6000001 is branch 1 of Run3_2022EE in a run over several eras; a run over one era takes that era's own numbers: --era Run3_2022EE --branches 1. A number of no configured era stops withbranch <n> is beyond the 1000000 numbers of a run over one era. - A
--branchesselection given before the stage's inputs exist is honoured. For a stage whose branch map is read from an earlier stage's output (see above), a selection given before that output existed used to be widened to all of its branches; it is now kept, in runs over one era as well.
Settings that must agree between the eras¶
A run over several eras reads some settings once, for all its eras. They must be the same in every
era of the run, or constructing the task stops with EraDependentValueError naming the key and
each era's value:
fs_default;crab(the whole block) andrunTokenServer;anaTuple_schedulinganduse_cmssw_env_AnaTupleProduction;- of each entry of
payload_producers:n_cpus,max_runtime,crab_memory,save_asandcmssw_env.
Everything else may differ per era: the datasets and processes, the corrections, the bundles and
the output filesystems fs_anaTuple, fs_HistTuple, fs_anaCacheTuple and fs_plots (for
instance in config/<era>/user_custom.yaml, see
user_custom.yaml).
What stays the same as in a run over one era¶
For the stages with era branches, branch tasks, jobs, payloads (one era per subprocess,
--era <the branch's era>), output paths, job files, logs, heartbeats, worker files, bundles and
CRAB request names are per era and identical to what --era <that era> alone writes (the
StatInference card workflows keep theirs per configuration instead, see above). A run over several eras and runs over some of
them therefore find each other's outputs and unfinished jobs, in any order. The --dataset
selection applies to every era: a dataset that exists in only one of the eras fails the run
(No datasets selected with a custom selection: …), so run such a dataset on its own era.
--parallel-jobs is one cap for the whole run, not one per era
(HTCondor,
CRAB). The error messages of this section are
explained in Troubleshooting.
In CI, the eras are listed in the *_eras variable (e.g.
Run3_2022 Run3_2022EE Run3_2023 Run3_2023BPix Run3_2024 Run3_2025 Run3_2026). See the
integration pipeline. For a 2024+2025+2026 combination, run each
era with weight_base_branch: weight_base_cmb and add the histograms, e.g. with a meta-era of the
three (see Meta-eras).
Adding a new era¶
Adding an era means creating its per-era config directories in both the framework and the
analysis, wiring it into the CI era lists, and listing it in test-setup-loading. The full
procedure is in Datasets.