Skip to content

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:

Terminal window
nwp-compose tutorial

The 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.

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.

Terminal window
mkdir my-first-forecast && cd my-first-forecast

Chapter 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.

Terminal window
nwp-compose new --template bahamas-mpas-rap -o forecast.yaml

This 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: PT6H means a new cycle every 6 hours — the same 0,6,12,18 you would have written in a crontab, but Cylc drives it.
  • forecast_hours_default is how far each cycle forecasts.
  • lbc_interval_default is how often lateral boundary conditions are ingested.

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_s3

Each 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.

Terminal window
nwp-compose validate forecast.yaml

This 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.

The short way — one command does validate → generate → install → play and tells you the workflow id:

Terminal window
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:

  1. 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/.

  2. Terminal window
    cylc install ./out/ # prints e.g. "INSTALLED forecast/run1 from ./out"
    cylc play --mode=dummy --main-loop dummy_bridge forecast/run1

    forecast/run1 is the workflow id — the handle every later cylc command takes.

  • A cycle point is one forecast’s analysis time; period is 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 validate alone is not enough.