Tutorial: your first forecast
This tutorial takes you from an empty directory to a forecast cycling under Cylc, and teaches the concept behind each step rather than just the keystroke. By the end you will understand cycle points, the component graph, namelist modes, and the validate-then-run loop — the four ideas that make every later workflow legible.
It mirrors the interactive nwp-compose tutorial command. Prefer to be walked through it in your
terminal, with prompts? Run:
nwp-compose tutorialThe interactive version teaches the same arc, builds the same YAML, lets you quit at any prompt
with q, and writes nothing until you confirm at the end.
Chapter 0 — The shape of the thing
Section titled “Chapter 0 — The shape of the thing”A forecast in nwp-compose is a workflow.yaml that describes a graph of components run on a
cadence. nwp-compose validates that description and renders it into a Cylc 8 bundle; Cylc runs it.
You will produce one YAML, validate it, generate the bundle, and dummy-play it.
mkdir my-first-forecast && cd my-first-forecastChapter 1 — Start from a known-good template
Section titled “Chapter 1 — Start from a known-good template”Do not configure from scratch. Start from a template and tweak — the same advice you would give a new user of your own scripts.
nwp-compose new --template bahamas-mpas-rap -o forecast.yamlThis writes forecast.yaml: a 3 km regional MPAS forecast over the Bahamas, driven by RAP data.
Open it. You will see top-level blocks: name, domain_type, cycling, platforms,
components, and (further down) fan_out and sub_workflows.
Chapter 2 — Cycling: the cadence of a forecast
Section titled “Chapter 2 — Cycling: the cadence of a forecast”The cycling block is the heartbeat:
cycling: initial_cycle_point: 20240101T00 final_cycle_point: 20240102T00 period: PT6H # a new forecast every 6 hours forecast_hours_default: 24 lbc_interval_default: 3 # boundary conditions every 3 hours- A cycle point is the analysis time of one forecast (
20240101T00= 00 UTC on 1 Jan 2024).period: PT6Hmeans a new cycle every 6 hours — the same0,6,12,18you would have written in a crontab, but Cylc drives it. forecast_hours_defaultis how far each cycle forecasts.lbc_interval_defaultis how often lateral boundary conditions are ingested.
Chapter 3 — The component graph
Section titled “Chapter 3 — The component graph”components is a map of named instances, each with a type from the
catalog. For the Bahamas MPAS path the graph is:
data_ingest → ungrib → init_atmosphere → lbc → mpas_run → mpassit → upp → archive_s3Each arrow is a dependency the tool derives from each component’s declared requires_upstream. You
do not draw the Cylc graph by hand — you state which components are present, and nwp-compose proves
the graph is well-formed (every required upstream exists, nothing forbidden is present) or refuses
with a precise error.
Chapter 4 — Namelists: templated or bring-your-own
Section titled “Chapter 4 — Namelists: templated or bring-your-own”The model components (mpas_run, real, wrf) carry a namelist_mode:
- Templated — you set YAML parameters (
time_step,history_interval,physics_suite, …) and the tool renders the namelist. Good for getting going; every value has a unit and a default. - Bring-your-own (BYO) — you point at your existing hand-tuned
namelist.input. The tool patches only the cycle-dependent keys (start_*/end_*,interval_seconds) and leaves every other line byte-for-byte. This is the adoption feature: your namelist, respected.
You will not edit a namelist by hand here. To do it interactively later — with units, choices, and
validation, or to preview a BYO patch before it touches your file — use
nwp-compose namelist.
Chapter 5 — Validate before you trust
Section titled “Chapter 5 — Validate before you trust”nwp-compose validate forecast.yamlThis runs three layers: the schema (types, required fields), the graph (dependencies satisfied), and the physics (CFL stability, decomposition legality, boundary cadence). A purely schema-valid file can still be physically wrong.
How the physics layer responds depends on the model: a physically-unsafe WRF configuration
(convective-scale cumulus, CFL-violating time_step, illegal PBL pairing — codes W-7 through W-10)
is hard-blocked unless you set acknowledge_unphysical: true. An MPAS CFL issue
(dt too large for the mesh — code W5) is flagged as an advisory and does not block. Either
way you are told before the run, not three hours in. See the
warning catalog for which codes block and which advise.
Chapter 6 — Generate and run
Section titled “Chapter 6 — Generate and run”The short way — one command does validate → generate → install → play and tells you the workflow id:
nwp-compose run forecast.yaml --dummy--dummy exercises the graph (task ordering, triggers, fan-out) without running real MPAS — it
finishes in seconds and proves the shape is sound. Drop --dummy on a real cluster to run the
actual forecast.
The explicit way, if you want to see each artifact:
-
Terminal window nwp-compose generate forecast.yaml -o ./out/Inspect
./out/flow.cylc,./out/manifest.json(your reproducibility record), and the rendered namelists under./out/components/. -
Terminal window cylc install ./out/ # prints e.g. "INSTALLED forecast/run1 from ./out"cylc play --mode=dummy --main-loop dummy_bridge forecast/run1forecast/run1is the workflow id — the handle every latercylccommand takes.
What you learned
Section titled “What you learned”- A cycle point is one forecast’s analysis time;
periodis the cadence. - The component graph is derived from declared dependencies — you state presence, the tool proves correctness.
- Namelist mode is your choice: templated for speed, BYO to keep your own tuning.
- Validate layers schema + graph + physics; run proves it installs.
cylc validatealone is not enough.
- Interactive namelist configuration — tune parameters or preview a BYO patch.
- Migrating from bash + cron — turn your existing driver script into a workflow.yaml.
- The last mile: run & doctor — the reference for the two commands you just used.