First workflow#
This tutorial introduces the smallest useful FAST-HEP workflow:
toy source → derived variable → histogram → plot
The workflow uses the workshop toy source to generate event data, derives a new muon transverse momentum variable, fills a histogram, and renders the result as a PNG plot.
What this tutorial demonstrates#
You will see how to:
load FAST-HEP profiles
define datasets
configure a source
define a derived variable
fill a histogram
render a plot (PNG)
Files#
tutorials/beginner/first-workflow/
├── author.yaml
├── README.md
├── expected/
├── assets/
└── build/
The main workflow file is:
author.yaml
Workflow overview#
This workflow:
generates toy events
derives a new variable
fills a histogram
renders a plot
flowchart TD
read_events["read.events<br/>source<br/>workshop.toy_source"]
stage_BasicVars["stage.BasicVars<br/>transform<br/>hep.define"]
stage_MuonPt["stage.MuonPt<br/>transform<br/>hep.hist"]
render_MuonPt_0["render.MuonPt.0<br/>sink<br/>hep.render.hist1d"]
read_events -->|stream -> stream| stage_BasicVars
stage_BasicVars -->|stream -> stream| stage_MuonPt
stage_MuonPt -->|hist -> target| render_MuonPt_0
FAST-HEP workflows are compiled into dependency-aware execution graphs.
In this tutorial:
the source generates toy events
a transform derives
Muon_Ptanother transform fills a histogram
a rendering sink produces a PNG plot
The graph above is generated from the workflow definition and shows how data and artifacts flow between operations.
The workflow file#
The workflow is defined in:
author.yaml
FAST-HEP workflows are declarative:
you describe what should happen
FAST-HEP determines how to execute it
The workflow is organised into sections.
Profiles#
The workflow begins by loading profiles:
use:
profiles:
- registry
- fasthep_carpenter:registry
- fasthep_render:registry
- fasthep_workshop:registry
Profiles register operations, sources, sinks, hooks, and rendering behavior.
In this workflow:
Profile |
Purpose |
|---|---|
|
core FAST-HEP workflow runtime |
|
transforms and histogramming |
|
rendering and plotting |
|
tutorial toy source |
Note
The first profile, registry, is the built-in FAST-HEP workflow registry.
In future user-facing presets such as workshop or hep-default may hide these details in author.yaml, while the fully resolved profiles remain visible in generated plans.
See also:
FAST-HEP concepts: profiles and registries
fasthep-flowdocumentation
Datasets#
The workflow defines a dataset:
data:
datasets:
- name: toy
eventtype: mc
files:
- toy://dy
Datasets describe logical analysis inputs.
In this tutorial:
toy://dy
is a virtual dataset URI interpreted by the workshop toy source.
Note
toy://dy is not a physical file.
The workshop toy source interprets this URI internally to generate deterministic synthetic events for tutorials.
This allows tutorials to run without downloading external datasets.
Sources#
The workflow then defines a source:
sources:
events:
kind: workshop.toy_source
Sources introduce data streams into workflows.
In this case:
workshop.toy_source
generates synthetic event data containing:
muons
jets
event weights
trigger decisions
missing transverse energy
The source produces an event stream called:
events
which downstream operations consume.
Transforms#
The workflow derives a new variable:
- id: BasicVars
op: hep.define
params:
variables:
- name: Muon_Pt
expr: "sqrt(Muon_Px ** 2 + Muon_Py ** 2)"
This transform computes:
Muon_Pt
from:
Muon_Px
Muon_Py
Note
FAST-HEP describes what should be computed rather than explicitly writing event loops.
The workflow engine determines execution order and dependencies automatically.
See also:
FAST-HEP concepts: workflow language
fasthep-flowdocumentation
Histogramming#
The next stage fills a histogram:
- id: MuonPt
op: hep.hist
params:
axes:
- name: Muon_Pt
source: Muon_Pt
type: regular
bins:
low: 0
high: 120
nbins: 60
This operation:
reads the derived
Muon_Ptfills histogram bins
produces a histogram artifact
The histogram configuration specifies:
histogram axes
binning
ranges
weighting behavior
In this tutorial the histogram is unweighted.
Rendering#
The histogram is then rendered as a PNG plot:
render:
style: muon_pt
which references this style:
styles:
muon_pt:
op: hep.render.hist1d
figure:
size: [8, 6]
dpi: 150
axes:
x:
name: Muon_Pt
label: "Muon $p_T$ [GeV]"
limits: [0, 120]
y:
name: events
label: "Events"
scale: linear
Rendering is separated from histogram creation.
This allows:
plots to be regenerated independently
rendering styles to be reused
visual appearance to evolve separately from analysis logic
The render sink uses:
hep.render.hist1d
to generate the final output image.
Run the tutorial#
From the fasthep-workshop repository root:
pixi run fasthep run tutorials/beginner/first-workflow/author.yaml \
--outdir tutorials/beginner/first-workflow/build
The output plot should be written under build/artifacts/plots/.
Expected output#
After running, inspect:
tutorials/beginner/first-workflow/build/
The main expected output is:
├── artifacts
│ ├── histograms
│ │ ├── MuonPt.pkl
│ │ └── manifest.json
│ └── plots
│ └── MuonPt.png
├── compile
│ ├── analysis.ir.yaml
│ ├── dataset_entries.json
│ ├── deps.yaml
│ ├── normalized.yaml
│ ├── plan.yaml
│ └── report.compile.yaml
├── graph
│ ├── graph.dot
│ ├── graph.json
│ └── graph.mmd
├── render
│ ├── report.render.json
│ └── specs
│ └── render_MuonPt_0.yaml
├── reports
│ ├── diagnostics
│ ├── provenance
│ └── schema
├── debug
└── run_summary.yaml
User-facing products are under artifacts/, including persisted histogram
products in artifacts/histograms/ and rendered plots in artifacts/plots/.
Compiler products are under compile/, graph exports under graph/, render
metadata under render/, and structured reports under reports/.
You can compare your generated output against:
tutorials/beginner/first-workflow/expected/
Full workflow#
version: 1.0
use:
profiles:
- registry
- fasthep_carpenter:registry
- fasthep_render:registry
- fasthep_workshop:registry
data:
datasets:
- name: toy
eventtype: mc
files:
- toy://dy
sources:
events:
kind: workshop.toy_source
stream_type: event_stream
styles:
muon_pt:
op: hep.render.hist1d
figure:
size: [8, 6]
dpi: 150
axes:
x:
name: Muon_Pt
label: "Muon $p_T$ [GeV]"
limits: [0, 120]
y:
name: events
label: "Events"
analysis:
stages:
- id: BasicVars
op: hep.define
params:
variables:
- name: Muon_Pt
expr: "sqrt(Muon_Px ** 2 + Muon_Py ** 2)"
- id: MuonPt
op: hep.hist
params:
axes:
- name: Muon_Pt
source: Muon_Pt
type: regular
bins:
low: 0
high: 120
nbins: 60
render:
style: muon_pt
when: final
out: MuonPt.png
What to try next#
Try changing:
the number of events
the histogram range
the number of bins
the render style
the random seed
Then rerun the workflow and compare the output.
Next tutorial#
The next tutorial adds a selection step and shows how cuts affect the resulting histogram.