Concepts: data types, grids & regions#
What you can extract, how the raw UM archive is organised in time (Mk blocks) and in space (world regions), and how your target grid is built. Read this once to decide which data type, domain and grid mode belong in your config.
See also: setup.md (environment + config), extracting.md (the commands), and reference.md (variables, model levels, output chunking).
1. Data types (sources)#
A data type (a MetSource, defined in extract_um_met/sources.py) is one met
product. They differ on almost every axis — archive layout, filename pattern, Mk
calendar, grid projection, region scheme, level count, cadence, compression, and
whether they are tiled (many region files that must be joined) or a single file
per timestep. The pipeline dispatches on these properties instead of hardcoding
one product.
Data type |
Archive |
Grid |
Regions |
Tiled? |
Levels |
Cadence |
Mk calendar |
Status |
|---|---|---|---|---|---|---|---|---|
|
|
regular lat/lon |
|
yes → join |
L59 |
3-hourly |
Mk6–12 |
working (Mk6–12) |
|
|
rotated pole |
|
yes → join |
L57 |
1-hourly |
Mk2–4 (Mk4 confirmed) |
region bounds not generated yet |
|
TBD (config) |
rotated pole |
none (one file) |
no join |
L70 |
1-hourly |
none |
partial (12 vars ship; stresses deferred) |
A domain picks its data type with data_type: in config (default UM_Global
if omitted). The structural properties above are code-defined — what you set per
data type in config.yaml → data_types: is the archive path, plus optionally
which variables and model levels to extract
(reference.md).
Tiled sources (
UM_Global,UM1p5km) split the globe/UK into region files. A domain names the regions it needs (world_regions_codes), the pipeline extracts each, then joins them into the domain.Non-tiled sources (
NZCSM) deliver one file covering the whole domain per timestep — no join; the run extracts and appends a day at a time.
2. The Global UM archive (UM_Global)#
This section is the time axis: how the archive is split across the record.
Hosted on JASMIN at /gws/ssde/j25a/name/met_archive/Global/. From 2011 the UM
is released in “Mk” blocks, in folders UMG_Mk{N}PT/. Each Mk covers a time
period at a given native resolution:
Mk |
Dates |
Native (Δlat × Δlon) |
Grid size (lat × lon) |
|---|---|---|---|
Mk6 |
Jan 2011 – Apr 2013 |
0.234375° × 0.351562° |
769 × 1024 |
Mk7 |
May 2013 – Jun 2014 |
0.234375° × 0.351562° |
769 × 1024 |
Mk8 |
Jul 2014 – Jul 2015 |
0.15625° × 0.234375° |
1152 × 1536 |
Mk9 |
Aug 2015 – Jun 2017 |
0.15625° × 0.234375° |
1152 × 1536 |
Mk10 |
Jul 2017 – May 2022 |
0.09375° × 0.140625° |
1920 × 2560 |
Mk11 |
Jun 2022 – Jan 2026 |
0.09375° × 0.140625° |
1920 × 2560 |
Mk12 |
Feb 2026 – |
0.09375° × 0.140625° |
1920 × 2560 |
Availability: Mk6–Mk12 (2011-01 onward) are all extractable. Every grid size
above is what make-native-grid actually stitches from the 14 region files, not
a nominal figure.
Mk10 is a resolution jump: the global model moves from N768 (Mk8/9) to N1280, so Δlat and Δlon each shrink by a factor of ~1.67 and the grid carries ~2.8× the points per level. Mk11 and Mk12 stay on N1280. Expect longer extractions, larger intermediates and bigger Zarr stores for any date from 2017-07 onward.
Mk blocks overlap slightly in the archive (e.g. UMG_Mk11PT/ starts at 2022-04 while
Mk10 runs to 2022-05, and UMG_Mk12PT/ starts at 2025-12 while Mk11 runs to
2026-01). The boundaries in the table are the ones used in the code via get_Mk:
the switch happens the month after the previous block’s last full month.
You never set the Mk yourself — give a --date and the block is resolved in
code (iris_io.get_Mk).
Filename pattern#
MO{YYYYMMDD}{HHMM}.UMG_Mk{N}_{set}_L59PT{region}.pp[.gz]
e.g. MO201403080000.UMG_Mk7_I_L59PT10.pp
HHMM— sub-daily period:0000, 0300, … 2100(3-hourly → 8 files/day).{set}— variable set tokenIorM(see reference.md). (Mk6 files omit the_I_token — handled automatically.){region}— world region1–14(see §3).Mk6–Mk9 files are gzipped (
.pp.gz) and are decompressed underscratch_pathbefore reading; Mk10–Mk12 are plain.pp.
3. World regions (the world14 scheme)#
This section is the space axis: how each timestep is split into tiles.
Tiled Global data is split into 14 world regions. A domain lists the ones it
overlaps in world_regions_codes; the pipeline extracts each and joins them.
Bounds are [min_lat, max_lat, min_lon, max_lon] (from
extract_um_met/regions.py):
Region |
Lat band |
Lon band |
Notes |
|---|---|---|---|
1 |
79.9 … 90.0 |
polar cap |
North pole |
2 |
25.0 … 80.0 |
−45 … 45 |
|
3 |
25.0 … 80.0 |
45 … 135 |
|
4 |
25.0 … 80.0 |
135 … −135 |
crosses dateline |
5 |
25.0 … 80.0 |
−135 … −45 |
|
6 |
−25.1 … 25.1 |
−45 … 45 |
equatorial |
7 |
−25.1 … 25.1 |
45 … 135 |
equatorial |
8 |
−25.1 … 25.1 |
135 … −135 |
equatorial, crosses dateline |
9 |
−25.1 … 25.1 |
−135 … −45 |
equatorial |
10 |
−80.0 … −25.0 |
−45 … 45 |
|
11 |
−80.0 … −25.0 |
45 … 135 |
|
12 |
−80.0 … −25.0 |
135 … −135 |
crosses dateline |
13 |
−80.0 … −25.0 |
−135 … −45 |
|
14 |
−90.0 … −79.9 |
polar cap |
South pole |
Grid layout (matches the region numbering above):
-180 -45 45 135 180
+90 ┌───────────── 1 (N pole) ──────────────┐
│ 5 │ 2 │ 3 │ 4 │ (mid-N)
+25 ├────────┼────────┼────────┼───────┤
│ 9 │ 6 │ 7 │ 8 │ (equator)
-25 ├────────┼────────┼────────┼───────┤
│ 13 │ 10 │ 11 │ 12 │ (mid-S)
-80 └───────────── 14 (S pole) ─────────────┘
Global data is 3-hourly on 59 model levels, so one year of one domain is a few thousand tile-files reduced to a single store.
To find which regions a bounding box needs, ask:
from extract_um_met.regions import find_overlapping_regions
find_overlapping_regions(min_lat=-25, max_lat=15, min_lon=-75, max_lon=-30)
Existing domains in the config and their regions:
Domain |
|
Regions |
Mode |
|---|---|---|---|
|
SOUTHAMERICA |
6, 9, 10, 13 |
footprint |
|
NORTHAFRICA |
2, 3, 6, 7 |
footprint |
|
CHINA |
3, 4, 7, 8 |
footprint |
|
INDIA |
3, 7 |
footprint |
|
NEWZEALAND |
— (NZCSM, non-tiled) |
regular |
Adding your own domain is config-only, no code — see extracting.md.
4. Grid modes#
Every domain is extracted onto a target grid chosen by its grid.mode
(built in extract_um_met/grid.py). Set this per domain in config:
Mode |
Target grid |
Interpolates? |
Needs |
|---|---|---|---|
|
a reference footprint’s lat/lon, padded outward by edge cells |
yes |
|
|
|
yes |
|
|
the saved native UM grid (subset to bounds) |
no (passthrough on matching Mk) |
pre-built native grids in |
If a domain has no grid: block, it defaults to footprint with the domain’s
footprint key and default_edge_size.
Footprint mode loads the reference footprint, crops it to where measurements
actually are (release_lat/lon if present), takes its native lat/lon, then pads
outward by edge_size_* cells using the NAME reference spacing (Δlat 0.234,
Δlon 0.352). This reproduces the original extraction behaviour.
Native mode snaps a whole year to one canonical Mk grid (the majority Mk by month count) so time-appends stay aligned; months already on that Mk pass through untouched, off-Mk months are interpolated onto it.
⚠️ Native-mode cropping gap:
lat_bounds/lon_boundsin anativeblock currently shape only the canonical target grid — extraction still passes each region through at its full region extent (sliced to region bounds only), so a native domain is not yet cropped to a tight bounding box. Footprint/regular modes are unaffected. (Known limitation; tracked in the roadmap.)
Grid spec examples (config)#
# footprint (default)
grid:
mode: footprint
footprint: "GOSAT-BRAZIL-column_SOUTHAMERICA_201801.nc"
edge_size_lat: [100, 100]
edge_size_lon: [85, 100]
# regular
grid:
mode: regular
lat_bounds: [-25, 15]
lon_bounds: [-75, -30]
dlat: 0.234
dlon: 0.352
# native
grid:
mode: native
lat_bounds: [-17, 59]
lon_bounds: [45, 127]
native_grid: majority # or "latest", "Mk9", etc.
To extract an existing domain onto a different grid, don’t add a second domain
— run it with --grid-mode and a --suffix so the variant lands beside the main
store. See extracting.md.
5. Native grids (data/)#
Native grids are the true UM lat/lon per Mk, saved for reference and for
native-mode extraction. data/ is empty on a fresh clone — the grids are
regenerable and git-ignored, so build them with make-native-grid before your
first native-mode run (see setup.md):
python -m extract_um_met make-native-grid # all Mks (6–12)
python -m extract_um_met make-native-grid --mk 9 # one Mk
python -m extract_um_met make-native-grid --dry-run # inspect, no write
Each Mk is read from one known sample timestep (cli.MK_SAMPLE_TIMESTEPS); the
grid is fixed within an Mk block, so which timestep does not matter. Naming it
also keeps the command off a directory listing — the Mk10–12 folders hold
hundreds of thousands of files.
Per Mk this writes into data/:
native_grid_Mk{N}_region{01..14}.nc— per-region gridsnative_grid_Mk{N}_global.nc— stitched global gridnative_grid_Mk{N}_info.yaml— resolutions + point counts (e.g. Mk9 global is 1152 × 1536 at 0.15625° × 0.234375°)
Why it matters: resolution changes at Mk boundaries (Mk6/7 coarse → Mk8/9 fine → Mk10–12 finer still). Footprint and regular modes always interpolate onto a fixed target, so they are immune. Native mode snaps to one canonical Mk grid and only interpolates off-resolution months — which now costs more, since a year spanning the 2017-07 boundary mixes N768 and N1280 months.