Processes & physics models¶
Datasets are individual CMS samples. A process is the physics object you actually plot and fit — one or more datasets grouped together (e.g. "TT", "DY", "signal"). A physics model then declares which processes count as background, signal or data. Both are analysis-specific config.
processes.yaml — logical processes¶
The processes of an era are defined in <analysis>/config/<era>/processes.yaml. The
analysis-wide config/processes.yaml holds only shared YAML anchors under keys starting with
. (e.g. .DY_processors: &DY_processors): the files are concatenated before they are parsed,
so the era file can reference them, and the . keys themselves are dropped
(how the files combine).
ProcessName:
name: "Label for plots"
color: "kAzure-9" # ROOT colour used in plots
datasets: # the datasets that make up the process
- DatasetName1
- DatasetName2
processors: *DY_processors # optional: processors run for these datasets (a list)
GroupName:
name: "DY"
sub_processes: # a group of other processes instead of datasets
- ProcessName
- OtherProcessName
A process either gathers the datasets that represent the same physics, or groups other
processes with sub_processes (resolved recursively down to processes with datasets) — never
both: Setup stops with an error when a process of the model has both. Within the groups the
model reaches, a process may belong to one group only (Setup refuses a second one), so that
its place in the hierarchy is unambiguous. Analyses add further keys
(e.g. corrections, genInfo) that their own code reads from the process configuration.
processors is a list of entries, each naming a Python class that FLAF loads for given stages —
for example a stitcher:
processors:
- name: Stitcher
module: FLAF.Processors.MCStitching
class: MCStitcher
config: FLAF/config/Processors/stitching_DY_amcatnlo_Vpt_NpNLO.yaml
stages: [ AnaTuple, AnaTupleMerge ]
dependency_level:
AnaTuple: file
AnaTupleMerge: process # merge a dataset only together with its whole process
Meta-processes¶
A meta-process is a template that expands into a family of concrete processes — for example
"the resonant signal at every mass point" — instead of writing each one out. It is marked with
is_meta_process: true and expanded by Setup while the configuration is loaded:
custom_CI_Signal:
is_meta_process: true
meta_setup:
dataset_name_pattern: XtoYHto2B2Wto2B2L2Nu_MX_(\d+)_MY_125 # regex groups = parameters
parameters: [ MASS ]
process_name: XtoHHto2B2W_2L_${MASS}
name_pattern: Xto2B2W 2L ${MASS} GeV (x100) # plot label
to_plot:
- [ '300' ] # parameter values drawn
plot_color: [ "kBlack" ]
channels: [ "eE", "eMu", "muMu" ] # optional
datasets:
- XtoYHto2B2Wto2B2L2Nu_MX_300_MY_125
Every listed dataset is matched against dataset_name_pattern; the datasets with the same
parameter values form one concrete process, named by process_name. A physics model that lists
the meta-process gets its concrete processes instead. Without channels, a member uses the
global channelSelection.
Meta-processes are selectable directly
You can target a meta-process by name (e.g. --process custom_CI_Signal in HH→bb̄WW, where
the CI signal is a meta-process for Run3_2022 … Run3_2023BPix); FLAF expands it to its
concrete member(s) for the requested era.
phys_models.yaml — what is signal vs background vs data¶
ModelName:
name: "Label" # optional
backgrounds:
- ProcessName1
- ProcessName2
signals:
- SignalProcessName
data:
- DataProcessName
A model is just a named partition of processes into the three roles, in
<analysis>/config/phys_models.yaml. Any other key is an error, a process may appear only once,
and every listed process must be defined in the era's processes configuration. Which model a run uses is set
by phys_model — the analysis's config/global.yaml sets the production model, your
user_custom.yaml usually overrides it, and --model overrides both.
TestModel vs the production model¶
TestModel— a deliberately small set of processes, so the whole pipeline runs fast end-to-end. Use it for development, local testing and CI. Every Run 3 era (Run3_2022…Run3_2026) defines a t̄t and a DY background of one dataset each (HH→bb̄WW adds a third, W background), plus one signal and one data process, under the CI names below.BaseModel(HH→bb̄ττ, H→μμ) orRun3_Model(HH→bb̄WW) — the production model, the full set used for real results.
Process names differ slightly between analyses
The CI process names are capitalised in the HH analyses (custom_CI_Signal,
custom_CI_Background_TT, custom_CI_Background_DY, HH→bb̄WW also
custom_CI_Background_W, custom_CI_Data) and lower-case in
H→μμ (custom_CI_signal, custom_CI_background_TT, custom_CI_background_DY,
custom_CI_data). Use the exact name from that analysis's processes.yaml.
A CI background must carry the processors its real process carries
The CI backgrounds exist to exercise the stitching over the
whole anaTuple → merge chain: each should declare the same processors: (and genInfo:) that
the analysis gives its real TT, DY (and W) processes in that era, so a gen-level input the
anaTuple does not keep fails the pipeline instead of the production. When you change a
stitcher or the era's processors, change the matching CI process too. One dataset per
process is enough — each stitching bin's denominator is summed over the very events that
later read it back, so a bin no event falls into is never divided by.
How processes relate to the rest¶
flowchart TD
DS["datasets.yaml<br/>CMS samples"] --> PR["processes.yaml<br/>physics groupings"]
PR --> PM["phys_models.yaml<br/>bkg / signal / data"]
PM -->|"phys_model (or --model)"| RUN["a run"]
- A dataset is a set of NanoAOD files — a DAS dataset, or a directory on storage.
- A process groups datasets into physics.
- A model labels processes as background/signal/data and is what a run actually uses.
From a dataset's process back to the model¶
A dataset's process is often not the entry phys_models.yaml lists: an expanded member
(GluGluToRadion_bbTauTau_300) stands for its meta-process (GluGluToRadion_bbTauTau), and a
sub-process stands for the group that lists it. Setup records each process's direct parent
within the hierarchy the model reaches — the listed meta-process it was expanded from, or the
group listing it in sub_processes — and walks back up from there:
| Call | Returns |
|---|---|
setup.process_parent(name) |
the direct parent, or None |
setup.process_ancestors(name) |
[name, parent, grandparent, …] |
setup.original_process(name) |
the first of those ancestors that the model lists; an error if none is |
setup.phys_model.is_listed(name) |
whether phys_models.yaml lists the process, meta-processes included |
setup.phys_model.listed_process_type(name) |
backgrounds, signals or data for a listed process |
This is the way for analysis code to tell which model entry a dataset belongs to, rather than
matching substrings of its process name; an anaTuple definition gets the Setup through its
Initialize(setup, dataset_name). When two meta-processes expand to the same member name, the
member belongs to the one the model lists.
The parent_process key that Setup adds to each base process's configuration is something
else: the process of the model after meta-processes are expanded (GluGluToRadion_bbTauTau_300
itself), which is what histograms are merged under.
See the configuration system for how these files are loaded and merged, and each analysis's docs for its concrete processes and models.