Skip to content
Back to skills

CaMa Flood

ASecurity

CaMa-Flood v4.20 river routing and floodplain model. Routes gridded runoff (from VIC, wflow, HYPE, etc.) through a global river network to produce discharge, water depth, and flood inundation extent.

  • 200 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 11, 2026
devopspythonrustgoshellbashdebugginggitapiperformancedocumentation

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 20 files and shows the line behind each finding

Scanned September 11, 2026

npx -y skills add lzwei196/KISS---Knowledge-Infrastructure-for-Scientific-Simulation --skill CaMa_Flood --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of CaMa Flood?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for CaMa Flood
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/lzwei196-cama-flood/badge)](https://www.skillsdirectory.com/skills/lzwei196-cama-flood)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: cama-flood-integration
description: CaMa-Flood v4.20 river routing and floodplain model. Routes gridded runoff (from VIC, wflow, HYPE, etc.) through a global river network to produce discharge, water depth, and flood inundation extent.
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, Task
---

> **MANDATORY EXECUTION POLICY** -- READ BEFORE PROCEEDING
>
> You MUST run the **actual CaMa-Flood Fortran binary** (`MAIN_cmf`) described in this document.
> If the model fails to compile or execute, you MUST:
> 1. Check `diagnostics/triplets.yaml` for a matching error pattern
> 2. Try the fix suggested in the triplet's `remedy` section
> 3. If still failing, report the error to the user with full details
>
> You MUST NOT substitute a simplified Python routing formula, Muskingum equation,
> or hand-coded approximation in place of the real CaMa-Flood binary. Doing so
> produces scientifically invalid results and defeats the purpose of the KI.
>
> Before starting, run: `python preflight_check.py` (in this KI directory)
> to verify that the model binary and required data are available.
>
> **DEBUGGING PROTOCOL** — When something goes wrong, follow this order:
> 1. **Check triplets** — `diagnostics/triplets.yaml` may already cover this error
> 2. **Read official docs** — The model's own documentation for expected formats/units
> 3. **Find working examples** — Check `outputs/` or the model's shipped test data
> 4. **Fix the tool** — With knowledge of what "correct" looks like
>
> Do NOT write custom debug scripts. The answers are in the docs and examples.

<!-- KI-MAP:BEGIN (projected by generate_skill_map.py — edit the KI, not this table) -->
## KI map — what to read, and when

| when you need | read | why |
|---|---|---|
| FIRST, always | `preflight_check.py` | run it (`python preflight_check.py`): proves env/binary/data are usable and emits a machine-readable `PREFLIGHT_REPORT=` line. Do not debug a run that never had a healthy environment. |
| to run the pipeline stages | `tools/` (6 tools) | the executable pipeline. Read each tool's argparse (`--help`) before composing a command; SKILL.md's stage table says which tool serves which stage. |
| before running a stage | `docs/s*_*.md` (10 stage docs) | per-stage procedure, verification and traps — the how-to that SKILL.md's overview compresses. |
| on ANY error, before debugging | `diagnostics/triplets.yaml` (37 entries) | symptom → diagnosis → remedy for this model's known failure modes. Check here FIRST; the answer usually exists. Never renumber or rewrite entries. |
| to know what an output IS | `dag.yaml` | the model's identity: every output's medium, units, `validation_rank` (1 = the headline variable) and observability. Scoring and obs-binding read THIS — when asked 'what does this model predict', the dag is the answer, not a guess. |
| when building inputs / parsing outputs | `docs/format_spec.yaml` | exact I/O shapes + `known_issues`, projected from dag + triplets. Regenerate with `ki_tools_common/generate_format_spec.py` after changing either — never hand-edit. |
| to judge a run's skill | `docs/validation_convention.yaml` | how this model's field judges it validated: per-`dag_variable` metrics, directions and CITED pass-bands. A run is graded against these, not against intuition. |
| for claims and thresholds | `docs/gathered_papers.json` (20 papers) + `docs/papers_index.md` | the literature this KI is judged by; each entry's `text_path` is fetched full text in the central paper cache. `role: benchmark` marks the model's own skill paper. |
| for a machine-readable summary | `knowledge_infrastructure.yaml` | the manifest (package, pipeline, validation tier, counts) — projected by `ki_tools_common/generate_ki_manifest.py`; regenerate after structural changes, never hand-edit. |

*Projected 2026-08-20 from the KI's actual contents — 9 components present. Refresh: `python3 ki_tools_common/generate_skill_map.py --ki_dir <this KI>`.*
<!-- KI-MAP:END -->

<!-- KI-TOOL-INDEX:BEGIN (projected by generate_skill_map.py — the discoverability contract: every public tool, exact path; PURPOSE stays human-authored elsewhere) -->
### Executable tool index (projected — complete by construction)

Every public tool in this KI, by exact path. What each is FOR lives in the
human-written Tool Inventory above; `--help` on any of these prints its arguments.

| tool (exact path) | invocation |
|---|---|
| `tools/calib_run.py` | `KISSPATH_PYTHON_ENV/bin/python {KI}/tools/calib_run.py --help` |
| `tools/configure_simulation.py` | `KISSPATH_PYTHON_ENV/bin/python {KI}/tools/configure_simulation.py --help` |
| `tools/gfd_flood_obs.py` | `KISSPATH_PYTHON_ENV/bin/python {KI}/tools/gfd_flood_obs.py --help` |
| `tools/parse_cama_output.py` | `KISSPATH_PYTHON_ENV/bin/python {KI}/tools/parse_cama_output.py --help` |
| `tools/prepare_runoff_input.py` | `KISSPATH_PYTHON_ENV/bin/python {KI}/tools/prepare_runoff_input.py --help` |
| `tools/run_cama.py` | `KISSPATH_PYTHON_ENV/bin/python {KI}/tools/run_cama.py --help` |

*6 public tools; `_`-prefixed helpers and packaging files excluded.*
<!-- KI-TOOL-INDEX:END -->

---

# CaMa-Flood v4.20 -- River Routing and Floodplain Model

CaMa-Flood (Catchment-based Macro-scale Floodplain model) is a global-scale river routing model that simulates river discharge, water depth, and floodplain inundation from gridded runoff input. It is the **coupling backbone** between land surface/hydrological models (VIC, wflow, HYPE) and local flood models (SFINCS).

## Key Paths

| Component | Path |
|-----------|------|
| Binary | `KISSPATH_BINARIES/cmf_v420_pkg/src/MAIN_cmf` |
| Source code | `KISSPATH_BINARIES/cmf_v420_pkg/src/` |
| Global river map (15min) | `KISSPATH_BINARIES/cmf_v420_pkg/map/glb_15min/` |
| Regional maps | `KISSPATH_BINARIES/cmf_v420_pkg/map/{basin}_15min/` |
| Run scripts | `KISSPATH_BINARIES/cmf_v420_pkg/gosh/` |
| Output directory | `KISSPATH_BINARIES/cmf_v420_pkg/out/` |
| Runoff climatology data | `KISSPATH_BINARIES/cmf_v420_pkg/map/data/ELSE_GPCC_coastmod_dayclm-1981-2010.one` |
| KI tools | `KISSPATH_KI_ROOT/CaMa_Flood/knowledge_infrastructure/tools/` |
| Diagnostics | `KISSPATH_KI_ROOT/CaMa_Flood/knowledge_infrastructure/diagnostics/triplets.yaml` |

---

## Pipeline Overview

```
Stage 0: Preflight         python preflight_check.py
                           |
Stage 1: Prepare runoff    tools/prepare_runoff_input.py
         (VIC/wflow/HYPE   Converts model output -> CaMa NetCDF
          -> NetCDF)        Output: {basin}_runoff_1d_YYYY.nc
                           |
Stage 2: Configure basin   tools/configure_simulation.py
         (map preparation)  Step 2.1: Regionalize (cut_domain from glb_15min)
                            Step 2.2: Generate inpmat (VIC grid -> CaMa grid)
                            Step 2.3: Channel parameters (calc_outclm + calc_rivwth)
                            Step 2.4: Generate run script
                            Output: map/{basin}_15min/ with all .bin files
                           |
Stage 3: Execute           tools/run_cama.py
                            Runs MAIN_cmf via generated shell script
                            Handles spin-up, restart, yearly loops
                            Output: o_outflw{YYYY}.nc, o_flddph{YYYY}.nc, etc.
                           |
Stage 4: Post-process      tools/parse_cama_output.py
                            Extract discharge at gauge points
                            Compute flood statistics
                            Reduce a variable over a date window to a 2-D field (--field)
                            Reads BOTH output forms: o_{var}{YYYY}.nc and {var}{YYYY}.bin
                            Output: CSV time series, spatial summaries, field NetCDF
                           |
Stage 5: Flood extent      tools/downscale/run_downscale.sh   (15min -> 1min/30sec/...)
         (ONLY for         tools/gfd_flood_obs.py             (GFD v1.4 observation)
          fldfrc/fldare)    Output: flood_{YYYYMMDD}.bin, aggregated obs NetCDF
```

### Validating flood extent (`fldfrc`, `fldare`) against GFD

`docs/validation_convention.yaml` (fldfrc / spatial_snapshot, determining metric **csi**,
Bernhofen 2018 bands: satisfactory 0.5 / good 0.6 / very good 0.7) requires the sub-grid
fraction to be **downscaled to the native high-resolution grid before wet/dry thresholding**.
The raw 0.25° `fldfrc` is NOT comparable to a 250 m satellite mask. The working chain is:

```bash
# 1. the run MUST emit binary output -- the official downscaler cannot read o_*.nc
python tools/configure_simulation.py ... --output_format binary \
       --output_vars 'outflw,rivout,rivdph,rivvel,sfcelv,flddph,fldfrc,fldare,rivsto'

# 2. downscale flddph with CaMa's own downscale_flddph_trib
bash tools/downscale/run_downscale.sh --map_dir <map> --out_dir <out> \
     --syear 2001 --smon 8 --eyear 2001 --emon 11 --res 1min \
     --west 98 --east 109.5 --south 8.5 --north 21.75 --dest <dest>

# 3. build the observation on the SAME grid
python tools/gfd_flood_obs.py --event_id 1781 \
     --west 98 --east 109.5 --south 8.5 --north 21.75 \
     --resolution 0.0166666666666667 --out_nc gfd_1781_1min.nc
```

Three traps that silently destroy CSI (**dt_cama_015**):
1. **Permanent water.** GFD's `flooded` band EXCLUDES JRC permanent water; the downscaler
   FORCES every `<res>.rivwth.bin` pixel to `max(0.1, depth)`. Drop permanent-water pixels
   (`gfd_flood_obs.py` does by default) and threshold the model **strictly above 0.1 m**.
2. **Reduction.** GFD band 1 is a composite MAXIMUM extent over the whole event window — so
   reduce the model with `max` over the same window, never sample one day.
3. **Cloud / footprint.** GFD is NaN outside the observed footprint and MODIS cannot see
   through cloud (`clear_views`, `clear_perc`). Require a minimum observed fraction per cell.

Pick the window as a multiple of BOTH the target resolution and 0.25°, at least 1.25° inside
the map domain (the downscaler adds a 5-grid buffer), and confirm the raster footprint from
the GeoTIFF's own bounds rather than the DFO centroid.

### Stage Skill Documents

- [Stage 0: Preflight skill](docs/s0_preflight_skill.md)
- [Stage 1: Prepare runoff skill](docs/s1_prepare_runoff_skill.md)
- [Stage 2: Configure basin skill](docs/s2_configure_basin_skill.md)
- [Stage 3: Execute CaMa-Flood skill](docs/s3_execute_cama_skill.md)
- [Stage 4: Post-process output skill](docs/s4_postprocess_skill.md)

---

## Data Preparation

**Data Validation Reference**: See `data_ki/ObservedQ/SKILL.md` for observed discharge validation data.
See `data_ki/ChinaDEM/SKILL.md` for DEM and river network data.


### Input Runoff Requirements

CaMa-Flood accepts gridded runoff on a regular lat/lon grid as NetCDF:
- **Variable name**: `Runoff` (capital R)
- **Units**: mm/day (CaMa-Flood converts internally to m3/s using grid area)
- **Dimensions**: `(time, lat, lon)`
- **Latitude order**: North-to-South (descending) -- this is critical; see dt_cama_007
- **Grid resolution**: Typically 0.25 deg (matching VIC/wflow)
- **Time step**: Daily (IFRQ_INP=24 hours)

### Data KI Adapters

| Source Model | Adapter | Key Conversion |
|-------------|---------|----------------|
| VIC 5.1 | `tools/prepare_runoff_input.py --source vic` | OUT_RUNOFF + OUT_BASEFLOW -> Runoff (mm/day) |
| wflow_sbm | `tools/prepare_runoff_input.py --source wflow` | Lateral runoff extraction (avoid double-counting routed Q) |
| HYPE | `tools/prepare_runoff_input.py --source hype` | cout.txt total runoff -> gridded NetCDF |
| Generic NC | `tools/prepare_runoff_input.py --source netcdf` | Variable rename + unit conversion |

### CRITICAL: Unit Mismatches (dt_cama_009)

VIC outputs runoff in **mm/day**. CaMa-Flood expects **mm/day** in the NetCDF. Do NOT convert to m3/s before feeding to CaMa -- the model handles the area-weighted conversion internally using ctmare.bin (catchment area).

If you accidentally provide m3/s, discharge will be off by orders of magnitude (typically 1e6 too high for large basins).

---

## Map Preparation (Three Mandatory Steps)

**CRITICAL WARNING**: Every new basin requires fresh map preparation. NEVER reuse map files from another basin (dt_cama_005). The three steps MUST be executed in order.

### Step 1: Regionalization (cut from global map)

Extracts a regional sub-domain from the global 15-minute river network.

```bash
# Directory: map/{basin}_15min/src_region/
# Inputs: region_info.txt with SOURCE, WEST, EAST, SOUTH, NORTH
# Tools: cut_domain, cut_bifway, set_map, combine_hires
# Output: nextxy.bin, ctmare.bin, elevtn.bin, nxtdst.bin, rivlen.bin,
#         fldhgt.bin, width.bin, 1min/ (high-res for downscaling)
```

The `configure_simulation.py` tool automates this step. If running manually:

1. Create the map directory: `mkdir -p map/{basin}_15min/src_region`
2. Copy tools from glb_15min: `cp -r map/glb_15min/src_region/* map/{basin}_15min/src_region/`
3. **Recompile** (binaries are platform-specific): `cd map/{basin}_15min/src_region && make clean && make all`
4. Edit `s01-regional_map.sh` with basin bounds (add buffer of ~0.5 deg)
5. Run: `./s01-regional_map.sh`

### Step 2: Input Matrix Generation (VIC grid -> CaMa grid mapping)

Creates the spatial mapping between the source runoff grid and the CaMa river network.

```bash
# Directory: map/{basin}_15min/src_param/
# Inputs: VIC grid extent (WESTIN, EASTIN, NORTHIN, SOUTHIN), grid resolution
# Tools: generate_inpmat
# Output: diminfo_{basin}_025deg.txt, inpmat_{basin}_025deg.bin
```

**CRITICAL**: WESTIN/EASTIN/NORTHIN/SOUTHIN must match the **VIC grid extent**, NOT the CaMa domain extent (dt_cama_002). Use cell edge coordinates (center +/- half resolution).

### Step 3: Channel Parameters (width, depth, Manning's n)

Derives river channel geometry from climatological mean discharge.

```bash
# Must run calc_outclm from glb_15min/ (needs global river network, dt_cama_004)
# Then run calc_rivwth from the REGIONAL directory with REGIONAL diminfo (dt_cama_003/008)
# Output: rivwth.bin, rivhgt.bin, rivwth_gwdlr.bin, rivman.bin, outclm.bin
```

Default channel parameter coefficients:
- Width: W = WC * Q^WP, WC=2.50, WP=0.60, WMIN=5.0 m
- Depth: H = HC * Q^HP, HC=0.10, HP=0.50, HMIN=1.0 m
- Manning's n: 0.03 (river), 0.10 (floodplain)

---

## Namelist Configuration (input_cmf.nam)

The CaMa-Flood binary reads configuration from a Fortran namelist file. Key sections:

### &NRUNVER -- Run version control
| Parameter | Default | Description |
|-----------|---------|-------------|
| LADPSTP | .TRUE. | Enable adaptive time stepping |
| LPTHOUT | .FALSE. | Path-based output (off for standard runs) |
| LRESTART | .FALSE. | Restart from previous state (set .TRUE. for year > 1) |

### &NDIMTIME -- Grid and time
| Parameter | Example | Description |
|-----------|---------|-------------|
| CDIMINFO | `'/mnt/.../diminfo_bengbu_025deg.txt'` | **Absolute path** to dimension info file |
| DT | 86400 | Base time step in seconds (daily) |
| IFRQ_INP | 24 | Input frequency in hours |

### &NPARAM -- Physical parameters
| Parameter | Default | Description |
|-----------|---------|-------------|
| PMANRIV | 0.03D0 | Manning's n for river channel (calibration param) |
| PMANFLD | 0.10D0 | Manning's n for floodplain |
| PCADP | 0.7 | CFL condition coefficient for adaptive time step |
| PDSTMTH | 10000.D0 | Distance threshold for diffusion wave (m) |

### &NSIMTIME -- Simulation period
| Parameter | Example | Description |
|-----------|---------|-------------|
| SYEAR/SMON/SDAY/SHOUR | 2000/1/1/0 | Simulation start |
| EYEAR/EMON/EDAY/EHOUR | 2001/1/1/0 | Simulation end (exclusive) |

### &NMAP -- River network files (ALL must use absolute paths)
| Parameter | File | Description |
|-----------|------|-------------|
| LMAPCDF | .FALSE. | Use binary map files (not NetCDF) |
| CNEXTXY | nextxy.bin | Flow direction (downstream cell indices) |
| CGRAREA | ctmare.bin | Catchment area per cell (m2) |
| CELEVTN | elevtn.bin | Elevation (m) |
| CNXTDST | nxtdst.bin | Distance to downstream cell (m) |
| CRIVLEN | rivlen.bin | River channel length (m) |
| CFLDHGT | fldhgt.bin | Floodplain height profile (m) |
| CRIVWTH | rivwth_gwdlr.bin | River channel width (m) |
| CRIVHGT | rivhgt.bin | River channel depth (m) |
| CRIVMAN | rivman.bin | Manning's n spatial field |

### &NFORCE -- Forcing input
| Parameter | Example | Description |
|-----------|---------|-------------|
| LINPCDF | .TRUE. | Input is NetCDF format |
| LINTERP | .TRUE. | Use input matrix for grid mapping |
| CINPMAT | `'.../inpmat_bengbu_025deg.bin'` | Input matrix file (absolute path) |
| CROFCDF | `'.../bengbu_runoff_1d_2003.nc'` | Runoff NetCDF file (absolute path) |
| CVNROF | 'Runoff' | Variable name in NetCDF (capital R) |

### &NOUTPUT -- Output control
| Parameter | Example | Description |
|-----------|---------|-------------|
| COUTDIR | './' | Output directory (relative OK, run script cd's here) |
| CVARSOUT | 'outflw,rivdph,sfcelv,flddph,fldfrc' | Comma-separated output variables |
| COUTTAG | '2003' | Year tag for output filenames |
| LOUTCDF | .TRUE. | Output as NetCDF (.FALSE. for binary) |
| IFRQ_OUT | 24 | Output frequency in hours |

---

## 6. Output Description

This section restates `dag.yaml`; if the body and dag ever disagree, `dag.yaml` wins.

**Headline output** (`validation_rank: 1`):

> `outflw` -- Total main-river-network discharge (river outflow + floodplain outflow + bifurcation outflow); primary validation variable. (`m3/s`)

Other dag-declared outputs: `rivout`, `rivdph`, `sfcelv`, `flddph`, `fldfrc`, `fldare`, `rivvel`, `rivsto`.

| Variable | File Pattern | Units | Description |
|----------|-------------|-------|-------------|
| outflw | o_outflw{YYYY}.nc | m3/s | Total main-river-network discharge (river outflow + floodplain outflow + bifurcation outflow); primary validation variable. |
| rivout | o_rivout{YYYY}.nc | see `dag.yaml` | Dag-declared output; use `dag.yaml` for the authoritative unit and description. |
| rivdph | o_rivdph{YYYY}.nc | m | River channel water depth |
| sfcelv | o_sfcelv{YYYY}.nc | m ASL | Water surface elevation |
| flddph | o_flddph{YYYY}.nc | m | Floodplain inundation depth |
| fldfrc | o_fldfrc{YYYY}.nc | 0-1 | Floodplain inundation fraction |
| fldare | o_fldare{YYYY}.nc | see `dag.yaml` | Dag-declared output; use `dag.yaml` for the authoritative unit and description. |
| rivvel | o_rivvel{YYYY}.nc | see `dag.yaml` | Dag-declared output; use `dag.yaml` for the authoritative unit and description. |
| rivsto | o_rivsto{YYYY}.nc | m3 | River channel storage volume |

## 8. Unit Conversion Table

This table records the body-level unit contract for input preparation and post-processing. For output variables, `dag.yaml` is authoritative.

| Variable | Source unit (verified) | Model unit / output unit | Factor | Type | Notes |
|----------|------------------------|--------------------------|--------|------|-------|
| Runoff | mm/day | mm/day | x1 | passthrough | CaMa-Flood expects `Runoff` in mm/day and converts internally to m3/s using catchment area. |
| OUT_RUNOFF + OUT_BASEFLOW (VIC adapter) | mm/day | Runoff, mm/day | x1 after summing | additive | `tools/prepare_runoff_input.py --source vic` maps VIC runoff components to CaMa `Runoff`. |
| outflw | model output | m3/s | x1 | output unit | Dag rank-1 output unit is `m3/s`. Do not pre-convert runoff to m3/s before CaMa-Flood. |

---

## Critical Domain Knowledge

### 1. Absolute Paths Are Mandatory (dt_cama_001)

CaMa-Flood resolves file paths relative to the current working directory at runtime. Since run scripts `cd` to the output directory before executing, relative paths (`../../map/...`) break unpredictably. **Always use absolute paths** for ALL file references in the namelist: CDIMINFO, CNEXTXY, CGRAREA, CELEVTN, CNXTDST, CRIVLEN, CFLDHGT, CRIVWTH, CRIVHGT, CRIVMAN, CINPMAT, CROFCDF.

### 2. calc_outclm Must Run from glb_15min (dt_cama_004)

The climatological mean discharge computation needs the FULL global river network topology to accumulate runoff correctly. Running it from a regional directory produces zero or incorrect outclm.bin, leading to wrong channel widths. **Always run calc_outclm from map/glb_15min/ — then CLIP its output to the regional domain. NEVER raw-copy it.**

⚠️ **DO NOT `cp` / `shutil.copy2` the global outclm.bin into the regional map dir** (this SKILL and the KI tool both used to say "copy", and that instruction is what produced the bug). calc_outclm writes a GLOBAL-sized array (1440×720); calc_rivwth reads the regional file with fixed-recl direct access sized to the REGIONAL nx·ny, so a raw copy hands it a meaningless byte slice and channel width/depth collapse to the WMIN/HMIN floors (2.0 m / 1.0 m) basin-wide. Measured 2026-08-19: 40 of 43 regional maps on this server had rivhgt.bin pinned at 1.0 m from exactly this. Use `tools/configure_simulation.py` (its `_clip_global_outclm()` does it correctly), and note the byte order — calc_rivwth declares `rivout(nx,ny)` (index = ix + iy·nx, Fortran order) while numpy's `tofile()` writes C order, so the clip MUST be written with `.ravel(order='F')` or correct values land on the WRONG cells. See triplet **dt_cama_012**.

### 3. calc_rivwth Must Use Regional diminfo (dt_cama_003, dt_cama_008)

After CLIPPING outclm.bin from glb_15min (never copying — see above), run calc_rivwth in the regional directory using the **regional** diminfo file. Using the global diminfo produces oversized binary files with garbage values. Both the raw-copy and the global-diminfo variants of this bug were live in `skills/cama-flood-run/setup_cama_basin.py` and in this KI's own `tools/configure_simulation.py`; both were fixed on 2026-08-19/20, and `setup_cama_basin.py` now refuses to continue if the resulting geometry is not downstream-consistent (channel width must correlate with drainage area).

### 4. Inpmat Grid Must Match VIC Grid, Not CaMa Domain (dt_cama_002)

The WESTIN/EASTIN/NORTHIN/SOUTHIN parameters in inpmat generation describe the **source runoff grid** (VIC/wflow), NOT the CaMa domain. Confusing these produces near-zero discharge everywhere.

### 5. Latitude Order: North-to-South (dt_cama_007)

CaMa-Flood expects runoff NetCDF with latitude in **descending** order (north to south). The OLAT parameter in inpmat generation must match. Mismatch causes every CaMa cell to map to wrong VIC cells.

### 6. Spin-Up for Stable Initial Conditions

First-year results are unreliable due to empty initial river storage. Always run 1-2 spin-up iterations of the first year (restart the first year using its own end-of-year state). The run scripts handle this with the NSP/SPINUP logic.

### 7. PMANRIV Is the Primary Calibration Parameter

Manning's roughness for river channels (PMANRIV) is the main calibration lever:
- Default: 0.03 (typical for natural rivers)
- Bengbu calibrated: 0.30 -- **SUSPECT, re-check before reuse** (see below)
- Higher values slow flow, increasing peak attenuation and lag time

**CHANNEL DEPTH IS THE OTHER (UNDOCUMENTED) KNOB — CHECK IT BEFORE CALIBRATING PMANRIV.**
`rivhgt.bin` (CRIVHGT) is NOT observed data and is NOT shipped in the official CaMa map archives
or in MERIT Hydro — riverbed depth cannot be measured from space. It is DERIVED per basin as
`H = max(Hmin, Hc * Qave^Hp)` from the discharge climatology (outclm.bin), with Hc set at setup
time. The global map here was built with Hc=0.10 (CaMa convention); our
`skills/cama-flood-run/setup_cama_basin.py` defaults to `--hc 0.50`, i.e. 5x deeper channels, with
no recorded justification. Width has a real-data path (GWD-LR `width.bin` via set_gwdlr); depth
has none, so a bad discharge climatology silently floors it at Hmin.

Consequence measured 2026-08-19: 40 of 43 regional maps on this server had `rivhgt.bin` pinned at
1.0 m everywhere (triplet dt_cama_012). A PMANRIV calibrated on floor-value channels is a COMPENSATING
error — 0.30 is ~10x the physical value for a natural river, which is what you would expect if
roughness were absorbing channels that are far too shallow. Before trusting or transferring any
PMANRIV, verify the geometry first (dt_cama_012 detection command), then decide Hc against observed
discharge/stage rather than inheriting a default.

---

## Error Handling

Consult `diagnostics/triplets.yaml` for structured symptom-diagnosis-remedy lookup. Key errors:

| Error | Triplet | Quick Fix |
|-------|---------|-----------|
| STOP 10 (immediate exit) | dt_cama_001 | Use absolute paths in namelist |
| Near-zero discharge | dt_cama_002 | Fix inpmat WESTIN/EASTIN to match VIC grid |
| Wrong channel widths | dt_cama_003/008 | Re-run calc_rivwth with regional diminfo |
| calc_outclm fails | dt_cama_004 | Run from glb_15min/, not regional dir |
| Wrong river network | dt_cama_005 | Regenerate map for this specific basin |
| Padded zeros in input | dt_cama_006 | Trim NetCDF to actual VIC grid extent |
| Lat ordering mismatch | dt_cama_007 | Check OLAT vs NC lat direction |
| Unit mismatch (mm/day vs m3/s) | dt_cama_009 | Keep mm/day; CaMa converts internally |
| diminfo format error | dt_cama_010 | Check integer/float formatting in diminfo |
| Missing 1min directory | dt_cama_011 | Re-run regionalization with combine_hires |
| `NetCDF: HDF error` opening a file `ncdump` reads fine | dt_cama_014 | xarray's DEFAULT engine is broken in this python_env; the tools' `open_nc()` falls back to `h5netcdf`. Never conclude the file is corrupt. |
| Flood-extent CSI near zero, false alarms along every river | dt_cama_015 | Downscale first, drop permanent water, threshold **above** 0.1 m |
| Downscaling errors with a `/Volumes/...` path | dt_cama_016 | Use `tools/downscale/run_downscale.sh` (the other two scripts in that dir are still dead macOS symlinks) |

---

## 11. Validated Results

### Bengbu (Huai River), VIC-coupled

- **Period**: 2000-2005 (2 spin-up years on 2000)
- **Resolution**: 15min CaMa, 0.25 deg VIC
- **Manning's n**: PMANRIV=0.30, PMANFLD=0.10
- **NSE**: 0.598 (daily discharge at Bengbu station)
- **Peak discharge**: ~6900 m3/s (2003 flood)
- **Output location**: `KISSPATH_BINARIES/cmf_v420_pkg/out/bengbu_2000_2005_cama/`

### Performance Metrics -- judged against the field's bar

The bar below restates `docs/validation_convention.yaml`; if this body and the convention file ever disagree, `docs/validation_convention.yaml` wins. A band held as null in the convention must be written as `no cited threshold`, not guessed.

| Dag variable | Metric | Direction | Satisfactory band | Good band | Very good band |
|--------------|--------|-----------|-------------------|-----------|----------------|
| outflw | nse | maximize | >= 0.5 (moriasi2007, moriasi2015) | >= 0.65 (moriasi2007, moriasi2015) | >= 0.75 (moriasi2007, moriasi2015) |
| outflw | pbias | zero_centered | <= 25 (moriasi2007, moriasi2015) | <= 15 (moriasi2007, moriasi2015) | <= 10 (moriasi2007, moriasi2015) |
| outflw | pbias | zero_centered | <= 25 (moriasi2007) | <= 15 (moriasi2007) | <= 10 (moriasi2007) |
| sfcelv | nse | maximize | >= 0.5 (moriasi2007, revel2023) | >= 0.65 (moriasi2007, revel2023) | >= 0.75 (moriasi2007, revel2023) |

| Metric | Calibration | Validation | Full Period | Bar (convention, cited) |
|--------|-------------|------------|-------------|-------------------------|
| NSE for `outflw` | not reported here | not reported here | 0.598 | satisfactory >= 0.5 (moriasi2007, moriasi2015); good >= 0.65 (moriasi2007, moriasi2015); very good >= 0.75 (moriasi2007, moriasi2015) |
| PBIAS for `outflw` | not reported here | not reported here | not reported here | satisfactory <= 25 (moriasi2007, moriasi2015); good <= 15 (moriasi2007, moriasi2015); very good <= 10 (moriasi2007, moriasi2015) |
| NSE for `sfcelv` | not reported here | not reported here | not reported here | satisfactory >= 0.5 (moriasi2007, revel2023); good >= 0.65 (moriasi2007, revel2023); very good >= 0.75 (moriasi2007, revel2023) |

---

## Usage Examples

### Example 1: Full pipeline for a new basin

```bash
# 0. Preflight
cd KISSPATH_KI_ROOT/CaMa_Flood/knowledge_infrastructure
python preflight_check.py

# 1. Prepare runoff from VIC output
python tools/prepare_runoff_input.py \
    --source vic \
    --input_dir KISSPATH_OUTPUTS/bengbu_2000_2005/vic_result \
    --output_dir KISSPATH_OUTPUTS/bengbu_2000_2005_cama/cama_input \
    --basin_name bengbu \
    --start_year 2000 --end_year 2005 \
    --file_prefix "huaihe_fluxes_"

# 2. Configure simulation (map prep + run script)
python tools/configure_simulation.py \
    --basin_name bengbu \
    --west 111.75 --east 117.75 --south 31.0 --north 35.0 \
    --grid_resolution 0.25 \
    --start_year 2000 --end_year 2005 \
    --runoff_dir KISSPATH_OUTPUTS/bengbu_2000_2005_cama/cama_input \
    --runoff_prefix "bengbu_runoff_1d_"

# 3. Execute
python tools/run_cama.py \
    --script KISSPATH_BINARIES/cmf_v420_pkg/gosh/run_bengbu_1d_nc.sh

# 4. Parse output
python tools/parse_cama_output.py \
    --output_dir KISSPATH_BINARIES/cmf_v420_pkg/out/bengbu_2000_2005_cama \
    --variable outflw \
    --lat 32.95 --lon 117.35 \
    --start_year 2000 --end_year 2005
```

### Example 2: Quick re-run with different Manning's n

Edit the run script and change PMANRIV:
```bash
cd KISSPATH_BINARIES/cmf_v420_pkg/gosh
# Change PMANRIV in run_bengbu_1d_nc.sh from 0.30D0 to 0.05D0
# Then re-run
python KISSPATH_KI_ROOT/CaMa_Flood/knowledge_infrastructure/tools/run_cama.py \
    --script run_bengbu_1d_nc.sh
```

---

## References

- CaMa-Flood official: http://hydro.iis.u-tokyo.ac.jp/~yamadai/cama-flood/
- CaMa-Flood v4 GitHub: https://github.com/global-hydrodynamics/CaMa-Flood_v4
- Manual: `model/cmf_v420_pkg/doc/Manual_CaMa-Flood_v420.docx`
- Yamazaki et al. (2011): A physically based description of floodplain inundation dynamics in a global river routing model. Water Resources Research.


## Stage documentation (one doc per pipeline stage)

- docs/s0_preflight.md
- docs/s0_preflight_skill.md
- docs/s1_prepare_runoff.md
- docs/s1_prepare_runoff_skill.md
- docs/s2_configure_basin.md
- docs/s2_configure_basin_skill.md
- docs/s3_execute_cama.md
- docs/s3_execute_cama_skill.md
- docs/s4_postprocess.md
- docs/s4_postprocess_skill.md

Files in this skill

  • CAPABILITY_INVENTORY.md10.5 KB
  • README.md24.2 KB
  • SKILL.md29.6 KB
  • SKILL_en.md26.1 KB
  • calibration.yaml15.3 KB
  • check_prerequisites.sh7 KB
  • dag.yaml36.4 KB
  • diagnostics/triplets.yaml41.6 KB
  • docs/REFERENCES.md1.4 KB
  • docs/format_spec.yaml39.5 KB
  • docs/papers.json5.9 KB
  • docs/s0_preflight.md2.2 KB
  • docs/s0_preflight_skill.md2.2 KB
  • docs/s1_prepare_runoff.md2.9 KB
  • docs/s1_prepare_runoff_skill.md3.2 KB
  • docs/s2_configure_basin.md3.6 KB
  • docs/s2_configure_basin_skill.md3.8 KB
  • docs/s3_execute_cama.md2.6 KB
  • docs/s3_execute_cama_skill.md2.8 KB
  • docs/s4_postprocess.md2.8 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…