Derived columns#
Part 1 of 3 in Transform Data
▶ 01. Derived Columns
○ 02. Object Selections
○ 03. Field Mapping
This tutorial reads the small local Z → $\mu\mu$ ROOT files and adds a few derived quantities to the event stream.
1. Inspect the dataset file#
Datasets live in datasets.yaml:
datasets:
data:
files:
- data/CMS/Zmumu/data.root
dy:
files:
- data/CMS/Zmumu/dy.root
The data files are the same small files used by the read-data tutorials.
2. Inspect the transform#
author.yaml adds fields with hep.define.
The first derived quantity is the muon transverse momentum:
In FAST-HEP expression syntax this becomes almost a direct translation:
analysis:
stages:
- id: DerivedMuonColumns
op: hep.define
params:
variables:
- name: Muon_Pt
expr: "sqrt(Muon_Px ** 2 + Muon_Py ** 2)"
The expression uses the same branch names that appear in the input data. It also follows NumPy-style syntax,
where ** 2 means “squared” and functions such as sqrt(...) act on whole arrays rather than single values
The same stage also defines an isolated-muon mask:
- name: IsolatedMuon
expr: "(Muon_Iso / Muon_Pt) < 0.10"
and counts isolated muons per event:
- name: NIsolatedMuon
reduce:
op: count_nonzero
over: IsolatedMuon
These three variables, Muon_Pt, IsolatedMuon, and NIsolatedMuon, are then available to later stages.
3. Run the workflow#
pixi run fasthep run tutorials/02-transform-data/01-derived-columns/author.yaml --outdir build/tutorials/02-transform-data/01-derived-columns
4. Inspect the outputs#
This workflow does not list the input branches explicitly in the source.
Instead, FAST-HEP inspects the expressions in hep.define, works out which input quantities are needed, and includes those branches automatically.
In this tutorial, the derived fields require:
Muon_PxMuon_PyMuon_Iso
You can see this in the compiler dependency output:
build/tutorials/02-transform-data/01-derived-columns/compile/deps.yaml
The workflow also writes schema snapshots before and after the define stage:
build/tutorials/02-transform-data/01-derived-columns/reports/schema/read_events/events__data__0.json
build/tutorials/02-transform-data/01-derived-columns/reports/schema/stage_DerivedMuonColumns/events__data__0.json
The first schema shows the stream read from the ROOT file. The second schema shows the stream after DerivedMuonColumns has run.
The important difference is that the stream now contains three additional fields:
Muon_PtIsolatedMuonNIsolatedMuon
Expected outputs#
Inferred dependencies#
The dependency snippet shows that FAST-HEP recorded the input quantities required by the derived expressions.
required_sources:
events:
data:
- Muon_Iso
- Muon_Px
- Muon_Py
branches:
- Muon_Iso
- Muon_Px
- Muon_Py
consumers:
Muon_Iso:
- stage.DerivedMuonColumns
Muon_Px:
- stage.DerivedMuonColumns
Muon_Py:
- stage.DerivedMuonColumns
origins:
IsolatedMuon:
kind: produced
node: stage.DerivedMuonColumns
Muon_Pt:
kind: produced
node: stage.DerivedMuonColumns
NIsolatedMuon:
kind: produced
node: stage.DerivedMuonColumns
notes:
- Data flow is inferred for the primary event stream first; joined source branch decomposition
is TODO.
This is useful because analysis authors do not need to manually keep branch lists in sync with their expressions. If a derived quantity uses a new input branch, FAST-HEP can include it automatically.
Schema after the define stage#
The schema after DerivedMuonColumns includes the newly created fields.
{
"node_id": "stage.DerivedMuonColumns",
"metadata": {
"dataset_name": "data",
"file": "data/CMS/Zmumu/data.root",
"part": "0_0",
"partition_id": "events__data__0",
"source": "events",
"start": 0,
"stop": 469384
},
"awkward_type": {
"IsolatedMuon": "var * bool",
"Muon_Iso": "var * float32",
"Muon_Pt": "var * float32",
"Muon_Px": "var * float32",
"Muon_Py": "var * float32"
},
"inspected_python_type": "Array"
}
Compare this with the source schema if you want to see exactly where the stream changes:
diff \
build/tutorials/02-transform-data/01-derived-columns/reports/schema/read_events/events__data__0.json \
build/tutorials/02-transform-data/01-derived-columns/reports/schema/stage_DerivedMuonColumns/events__data__0.json