**Package**: HydroCNHS KI v1.0 **Model**: HydroCNHS v1.2.1 **Domain**: Hydrology — Coupled Natural-Human Systems **Created**: 2026-03-25 **Validation**: Tualatin River Basin (TRB), Oregon, USA (1981–2013) | Metric | Value | |--------|-------| | Tools | 5 | | Pipeline stages | 8 | | Diagnostic triplets | 18 | | Skill documents | 6 | | Validation basin | TRB, Oregon | ---
Scanned 9/11/2026
Install to Claude Code
npx -y skills add lzwei196/KISS---Knowledge-Infrastructure-for-Scientific-Simulation --skill HydroCNHS --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of HydroCNHS?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/lzwei196-hydrocnhs)More formats (shields.io, HTML) on the badges page.
> **MANDATORY EXECUTION POLICY** — READ BEFORE PROCEEDING
>
> You MUST run the **actual model binary or package** described in this document.
> If the model fails to import, 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 formula, regression equation,
> or hand-coded approximation in place of the real model.
>
>
> Before starting, run: `python preflight_check.py` (in this KI directory)
> to verify that the model binary/package 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/` (5 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` (6 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` (18 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` (10 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-17 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/build_model_config.py` | `KISSPATH_PYTHON_ENV/bin/python {KI}/tools/build_model_config.py --help` |
| `tools/convert_climate_inputs.py` | `KISSPATH_PYTHON_ENV/bin/python {KI}/tools/convert_climate_inputs.py --help` |
| `tools/convert_parameters.py` | `KISSPATH_PYTHON_ENV/bin/python {KI}/tools/convert_parameters.py --help` |
| `tools/parse_output.py` | `KISSPATH_PYTHON_ENV/bin/python {KI}/tools/parse_output.py --help` |
| `tools/run_hydrocnhs.py` | `KISSPATH_PYTHON_ENV/bin/python {KI}/tools/run_hydrocnhs.py --help` |
*5 public tools; `_`-prefixed helpers and packaging files excluded.*
<!-- KI-TOOL-INDEX:END -->
# HydroCNHS Knowledge Infrastructure
**Package**: HydroCNHS KI v1.0
**Model**: HydroCNHS v1.2.1
**Domain**: Hydrology — Coupled Natural-Human Systems
**Created**: 2026-03-25
**Validation**: Tualatin River Basin (TRB), Oregon, USA (1981–2013)
| Metric | Value |
|--------|-------|
| Tools | 5 |
| Pipeline stages | 8 |
| Diagnostic triplets | 18 |
| Skill documents | 6 |
| Validation basin | TRB, Oregon |
---
## Data Preparation
### Forcing data
**Data Sources**: Use `from ki_tools_common.load_forcing import load_daily_forcing` for CMFD/MSWX/NASA POWER.
**Data Validation Reference**: See `data_ki/CMFD/SKILL.md` for CMFD unit documentation and known traps.
See `data_ki/HWSD/SKILL.md` for soil property documentation.
See `data_ki/ObservedQ/SKILL.md` for observed discharge data.
## 1. Overview
HydroCNHS is a Python package for simulating **Coupled Natural-Human Systems** in water
resource management. It integrates semi-distributed hydrological modeling (rainfall-runoff
+ Lohmann routing) with agent-based modeling (ABM) for human decision-making. The model
operates on a **daily time step** and supports two rainfall-runoff schemes (GWLF and ABCD),
Lohmann routing, and four ABM APIs (Dam, RiverDiv, Conveying, InSitu).
Key capabilities:
- Semi-distributed hydrological simulation at daily resolution
- Pluggable rainfall-runoff models (GWLF: 9 params, ABCD: 5 params)
- Lohmann routing with 4 parameters per link
- Agent-based modeling for dams, diversions, aqueducts, and in-situ modifications
- Built-in genetic algorithm (DEAP) calibration with parallel computing
- Evaluation indicators: NSE, KGE, iKGE, iNSE, r, r², RMSE, RSR, Cp
The model is entirely Python-based (no compiled binaries). Execution is via the
Python API: `model = hydrocnhs.Model("model.yaml"); model.run(temp, prec, pet)`.
---
## 2. Installation
```bash
# Create virtual environment
python3 -m venv venv && source venv/bin/activate
# Install from source
cd source/repo && pip install -e .
# Or from PyPI
pip install hydrocnhs
```
**Dependencies**: joblib, matplotlib, numpy, pandas, ruamel.yaml, scipy,
scikit-learn, tqdm, pyyaml, deap
**Python versions**: 3.10, 3.11, 3.12
**Quick test**:
```python
import hydrocnhs
print(hydrocnhs.__version__) # 1.2.1
```
---
## 3. Pipeline
The HydroCNHS pipeline has 8 stages from data preparation through validation.
| # | Stage | Tool | Input | Output |
|---|-------|------|-------|--------|
| S0 | Basin setup | — | GIS/literature | Subbasin areas, latitudes, flow lengths |
| S1 | Climate data prep | `convert_climate_inputs.py` | Global gridded data (ERA5, CMIP) | `temp_dict`, `prec_dict` [°C, cm/day] |
| S2 | Parameter estimation | `convert_parameters.py` | Soil/land-use data | Initial GWLF/ABCD params in YAML |
| S3 | Model config build | `build_model_config.py` | Basin geometry + params | `model.yaml` |
| S4 | ABM setup | — | Operational rules, literature | ABM module `.py` file |
| S5 | Model execution | `run_hydrocnhs.py` | `model.yaml` + climate dicts | `Q_routed` [cms] |
| S6 | Calibration | `run_hydrocnhs.py` | Observed streamflow + bounds | Calibrated `model.yaml` |
| S7 | Output analysis | `parse_output.py` | `Q_routed`, observed data | CSV + metrics + plots |
---
## 4. Unit Trap Table
These are the **critical unit conversions** that cause silent failures if violated.
Every value must match the model's internal expectations exactly.
| Variable | Model expects | Common source unit | Conversion | Trap ID |
|----------|--------------|-------------------|------------|---------|
| Precipitation | **cm/day** | mm/day (ERA5, CMIP) | ÷ 10 | dt_001 |
| Precipitation | **cm/day** | kg/m²/s (CMIP) | × 86400 ÷ 10 | dt_002 |
| Temperature | **°C** | K (CMIP, ERA5) | − 273.15 | dt_003 |
| PET | **cm/day** | mm/day | ÷ 10 | dt_004 |
| Subbasin area | **ha** | km² | × 100 | dt_005 |
| Subbasin area | **ha** | m² | ÷ 10000 | dt_006 |
| Flow length | **m** | km | × 1000 | dt_007 |
| Latitude | **decimal degrees** | DMS | convert properly | dt_008 |
| Discharge (output) | **cms** (m³/s) | — | native output unit | — |
| Soil water capacity (Ur) | **cm** | mm | ÷ 10 | dt_009 |
| Snowmelt coeff (Df) | **cm/°C** | mm/°C | ÷ 10 | dt_010 |
| Wave velocity | **m/s** | km/h | × 1000/3600 | dt_011 |
| Diffusivity | **m²/s** | — | native | — |
**Rule**: If your simulated discharge is 10× too high or too low, check precipitation
units first. This is the #1 cause of failed HydroCNHS runs.
---
## 8. Unit Conversion Table
Exact I/O shapes live in `docs/format_spec.yaml`; unit traps and remedies live in
`diagnostics/triplets.yaml`. This unit table documents the model-facing conversions used by
the pipeline and keeps trap ids only where the KI has a corresponding diagnostic.
| Variable | Source unit (verified) | Model unit | Factor / conversion | Type | Trap ID |
|----------|------------------------|------------|---------------------|------|---------|
| Precipitation | `mm/day` | `cm/day` | divide by 10 | multiplicative | `dt_001` |
| Precipitation | `kg/m^2/s` | `cm/day` | multiply by 86400, then divide by 10 | multiplicative | `dt_002` |
| Temperature | `K` | `degC` | subtract 273.15 | additive | `dt_003` |
| PET | `mm/day` | `cm/day` | divide by 10 | multiplicative | `dt_004` |
| Subbasin area | `km^2` | `ha` | multiply by 100 | multiplicative | `dt_005` |
| Subbasin area | `m^2` | `ha` | divide by 10000 | multiplicative | `dt_006` |
| Flow length | `km` | `m` | multiply by 1000 | multiplicative | `dt_007` |
| Date strings | `YYYY-MM-DD` | `YYYY/M/D` | replace hyphens with slashes | format | `dt_008` |
| Soil water capacity (`Ur`) | `mm` | `cm` | divide by 10 | multiplicative | `dt_009` |
| Snowmelt coefficient (`Df`) | `mm/degC` | `cm/degC` | divide by 10 | multiplicative | `dt_010` |
| Wave velocity (`Velo`) | `km/h` | `m/s` | multiply by 1000/3600 | multiplicative | `dt_011` |
| Discharge output (`Q_routed`) | native model output | `cms (m^3/s)` | no conversion | native | — |
| Local runoff output (`Q_runoff`) | native model output | `cms (m^3/s)` | no conversion | native | — |
| Hamon PET output (`pet`) | native model output | `cm/day` | no conversion | native | — |
| Monthly sediment output (`TSS_monthly`) | native model output | `Mg` | no conversion | native | — |
**Output unit verification checklist**:
- Read the dag before post-processing: `Q_routed` is `cms (m^3/s)`.
- Print the first 10 output values and confirm the expected order of magnitude.
- For discharge, compare absolute flow in `m^3/s`, not depth per subbasin.
- For PET and runoff-generation diagnostics, confirm whether values are forcing inputs or model outputs.
---
## 5. Tools Reference
| Tool | Stage | Script | Purpose |
|------|-------|--------|---------|
| Climate converter | S1 | `tools/convert_climate_inputs.py` | ERA5/CMIP → temp[°C], prec[cm/day] dicts |
| Parameter converter | S2 | `tools/convert_parameters.py` | Soil/land-use → GWLF/ABCD initial params |
| Model config builder | S3 | `tools/build_model_config.py` | Generate model.yaml from basin geometry |
| Execution wrapper | S5–S6 | `tools/run_hydrocnhs.py` | Run model or calibration |
| Output parser | S7 | `tools/parse_output.py` | Extract Q_routed to CSV + compute metrics |
All tools follow the **validate → process → validate** pattern:
1. Parse CLI arguments with `argparse`
2. Validate all inputs (check files exist, units plausible, ranges correct)
3. Process (convert, build, run, parse)
4. Validate outputs (check results exist, values in expected range)
5. Return JSON: `{"status": "success/error", "output": {...}, "log": [...]}`
---
## 6. Output Description (sourced from `dag.yaml`)
The source of truth for model outputs is `dag.yaml`. This section restates the dag; if
this section and the dag disagree, the dag wins.
**Headline output** (the dag's `validation_rank: 1` variable):
> `Q_routed` — Daily routed streamflow at routing/gauged outlets (and dam-agent inflow outlets); the primary return of Model.run(). (`cms (m^3/s)`)
Other dag outputs: `Q_runoff`, `pet`, `TSS_monthly`, `ABM_agent_records`.
| Output variable (dag `var`) | Rank | Emitted in | Unit | Description |
|-----------------------------|------|------------|------|-------------|
| `Q_routed` | 1 | `model.dc.Q_routed[outlet]` (data collector) | `cms (m^3/s)` | Daily routed streamflow at routing/gauged outlets (and dam-agent inflow outlets); the primary return of Model.run(). |
| `Q_runoff` | 2 | `model.dc.Q_runoff[outlet]` (data collector) | `cms (m^3/s)` | Local unrouted subbasin runoff (also exposed as Q_local) before Lohmann routing. |
| `pet` | 3 | `model.dc.pet[outlet]` (data collector) | `cm/day` | Hamon-computed potential evapotranspiration (atmospheric water demand) when PET is not supplied as input. |
| `TSS_monthly` | 4 | `model.dc TSS field` (data collector, sediment mode) | `Mg` | Monthly routed total suspended sediment (sediment mode only). |
| `ABM_agent_records` | 5 | `model.dc.<user-defined field>` (data collector) | `varies (storage volume, diversion volume)` | Agent-specific water-management outputs (e.g., reservoir storage, diversion volume; bookkeeping records, not a single field observable) recorded by user-defined ABM modules via the shared data collector. |
**Scoring caveats for `Q_routed` from the dag**:
- Exclude a 1-2 yr warm-up before scoring so soil/groundwater/snow stores equilibrate.
- Align simulated and observed on the date index, not array position; a 1-day offset destroys correlation in flashy basins.
- Regulated reaches require the corresponding ABM agents configured or the comparison conflates natural and human signals.
---
## 6b. Critical Domain Knowledge
These facts are non-obvious and cause **silent failures** if violated:
1. **Precipitation must be in cm/day** (dt_001, dt_002). Most global datasets
provide mm/day or kg/m²/s. Forgetting the ÷10 conversion is the single most
common error. The model will run without error but discharge will be 10× wrong.
2. **PET is auto-calculated if not provided** (Hamon method). The Hamon PET
uses latitude and temperature. If you provide PET, it must be in cm/day.
If PET values seem too high, check if you passed mm/day by mistake.
3. **Area must be in hectares** (dt_005, dt_006). The GWLF runoff-to-discharge
conversion uses area in ha. If you pass km², discharge will be 100× too low.
4. **CN2 sensitivity** — The SCS Curve Number (CN2, range 25–100) is the most
sensitive GWLF parameter. A change of ±5 can shift peak discharge by 30–50%.
Always calibrate CN2 first.
5. **Routing parameters interact** — GShape/GScale control within-subbasin UH
shape, while Velo/Diff control between-subbasin wave propagation. Calibrating
them separately can lead to equifinality. Calibrate jointly.
6. **ABM agent execution order matters** — Agents are executed in priority order
(low number = first). Dam releases affect downstream diversions. If priorities
are wrong, water balance violations occur silently.
7. **Calibration uses -99 sentinel** — Parameters set to -99 in the YAML are
marked for calibration. If you forget to set bounds for a -99 parameter,
the GA will use default bounds which may not suit your basin.
8. **Date format must be YYYY/M/D** — The model expects "1981/1/1" not
"1981-01-01". Using the wrong format causes a silent parse failure.
9. **Data length must match date range** — The `DataLength` field in YAML must
equal the number of days between StartDate and EndDate (inclusive). A mismatch
causes index errors or silent truncation.
---
## 7. GWLF Parameters (per subbasin)
| Parameter | Symbol | Unit | Range | Sensitivity | Description |
|-----------|--------|------|-------|-------------|-------------|
| Curve Number | CN2 | — | [25, 100] | Very High | SCS runoff curve number |
| Interception | IS | — | [0, 0.5] | Medium | Fraction of precip intercepted |
| Recession | Res | — | [0.001, 0.5] | High | Baseflow recession coefficient |
| Deep seepage | Sep | — | [0, 0.5] | Low | Fraction to deep aquifer |
| Baseflow | Alpha | — | [0, 1] | High | Groundwater discharge rate |
| Percolation | Beta | — | [0, 1] | Medium | Unsaturated zone percolation |
| Soil water | Ur | cm | [1, 15] | High | Available water capacity |
| Snowmelt | Df | cm/°C | [0, 1] | Medium | Degree-day coefficient |
| Land cover | Kc | — | [0.5, 1.5] | Medium | Crop/vegetation coefficient |
---
## 8. ABCD Parameters (per subbasin)
| Parameter | Symbol | Unit | Range | Sensitivity | Description |
|-----------|--------|------|-------|-------------|-------------|
| Runoff ctl | a | — | [0, 1] | High | Controls runoff during unsaturation |
| Saturation | b | cm | [0, 400] | High | Maximum soil water storage |
| Recharge | c | — | [0, 1] | Medium | Groundwater recharge fraction |
| Discharge | d | — | [0, 1] | Medium | Groundwater discharge rate |
| Snowmelt | Df | cm/°C | [0, 1] | Medium | Degree-day coefficient |
---
## 9. Lohmann Routing Parameters (per link)
| Parameter | Symbol | Unit | Range | Description |
|-----------|--------|------|-------|-------------|
| UH shape | GShape | — | [1, 100] | Gamma distribution shape |
| UH scale | GScale | — | [0.01, 150] | Gamma distribution scale |
| Wave velocity | Velo | m/s | [0.5, 55] | Saint-Venant celerity |
| Diffusivity | Diff | m²/s | [200, 4000] | Saint-Venant diffusion |
---
## 11. Validated Results
**Basin**: Tualatin River Basin (TRB), Oregon, USA
**Period**: 1981/1/1 – 2013/12/31 (33 years, 12,053 days)
**Subbasins**: 7 (HaggIn, TRTR, DLLO, TRGC, DAIRY, RCTV, WSLO)
**Model**: GWLF + Lohmann routing + ABM (reservoir + diversion + pipe)
### Performance Metrics — judged against `docs/validation_convention.yaml`
No new body-campaign achieved values are asserted in this edit. Calibration,
validation, and full-period achieved values remain pending unless produced by a
model run and scored against the bars below.
| Dag variable | Obs shape | Metric | Direction | Convention bar (cited per band) | Calibration | Validation | Full period |
|--------------|-----------|--------|-----------|----------------------------------|-------------|------------|-------------|
| `Q_routed` | `point_time_series` | `nse` | maximize | satisfactory >= 0.5 [`moriasi_repro_nh2017`, `arnold2012`, `mikeswat2014`]; good >= 0.65 [`moriasi_repro_nh2017`, `arnold2012`, `mikeswat2014`]; very_good >= 0.75 [`moriasi_repro_nh2017`, `arnold2012`, `mikeswat2014`] | pending body campaign | pending body campaign | pending body campaign |
| `Q_routed` | `point_time_series` | `pbias` | zero_centered | very_good \|PBIAS\| <= 10 [`moriasi_repro_nh2017`, `mikeswat2014`]; good \|PBIAS\| <= 15 [`moriasi_repro_nh2017`, `mikeswat2014`]; satisfactory \|PBIAS\| <= 25 [`moriasi_repro_nh2017`, `mikeswat2014`] | pending body campaign | pending body campaign | pending body campaign |
| `Q_routed` | `point_snapshot` | `pbias` | zero_centered | very_good \|PBIAS\| <= 10 [`moriasi_repro_nh2017`]; good \|PBIAS\| <= 15 [`moriasi_repro_nh2017`]; satisfactory \|PBIAS\| <= 25 [`moriasi_repro_nh2017`] | pending body campaign | pending body campaign | pending body campaign |
| `Q_runoff` | `point_time_series` | `nse` | maximize | satisfactory >= 0.5 [`moriasi_repro_nh2017`, `arnold2012`]; good >= 0.65 [`moriasi_repro_nh2017`, `arnold2012`]; very_good >= 0.75 [`moriasi_repro_nh2017`, `arnold2012`] | pending body campaign | pending body campaign | pending body campaign |
**Legacy body note already present in this SKILL**: calibrated performance at WSLO outlet (monthly):
- KGE ≈ 0.80–0.90
- NSE ≈ 0.75–0.85
- r ≈ 0.90–0.95
Key findings:
1. CN2 ranges 46–99 across subbasins, reflecting diverse land use
2. Routing velocity 8.6–48 m/s, diffusivity 295–3847 m²/s
3. ABM agents critical for reproducing regulated flow at WSLO
4. Warm-up period of 1–2 years recommended before evaluation
---
## 11. Coupling Points
HydroCNHS couples with external systems through its ABM APIs:
| API | Direction | What it controls |
|-----|-----------|-----------------|
| Dam API | Instream | Reservoir releases, storage |
| RiverDiv API | Off-stream | Irrigation diversions, return flows |
| Conveying API | Inter-basin | Aqueducts, pipelines, pumps |
| InSitu API | Within-basin | Groundwater extraction, urbanization |
---
## 12. Data Requirements
| Data | Source | Unit | Required |
|------|--------|------|----------|
| Daily temperature | ERA5, station | °C | Yes |
| Daily precipitation | ERA5, station | cm/day | Yes |
| Daily PET | Calculated or station | cm/day | Optional |
| Subbasin areas | GIS | ha | Yes |
| Subbasin latitudes | GIS | decimal degrees | Yes |
| Flow lengths | GIS | m | Yes |
| Observed streamflow | USGS, gauge | cms | For calibration |
| Soil/land-use | SSURGO, NLCD | varies | For initial params |
---
## 13. Quick Start
```python
import hydrocnhs
import pickle
# Load climate data
with open("TRB_inputs.pickle", "rb") as f:
inputs = pickle.load(f)
# Run model
model = hydrocnhs.Model("Calibrated_TRB_GWLF.yaml")
Q = model.run(temp=inputs["temp"], prec=inputs["prec"])
sim = model.dc.Q_routed["WSLO"]
# Evaluate
indicator = hydrocnhs.Indicator()
print("NSE:", indicator.get_nse(observed, sim))
print("KGE:", indicator.get_kge(observed, sim))
# Visualize
hydrocnhs.Visual().plot.timeseries(
Q_routed=model.dc.Q_routed,
labels=["WSLO"],
figsize=(12, 4)
)
```
---
## Output Description
HydroCNHS stores simulation results in the `model.dc` (data collector) object after
`model.run()`. The dag headline output is `model.dc.Q_routed[outlet]`, keyed by
gauge/subbasin name, containing daily routed streamflow arrays in `cms (m^3/s)`.
Use `parse_output.py` to export `Q_routed` to CSV with columns `date, Q_sim (cms)`
and compute performance indicators (NSE, KGE, RMSE, r) against observed streamflow.
The dag output list is `Q_routed`, `Q_runoff`, `pet`, `TSS_monthly`, and
`ABM_agent_records`. `Q_runoff` is local unrouted subbasin runoff before Lohmann
routing, `pet` is Hamon-computed potential evapotranspiration when PET is not supplied
as input, `TSS_monthly` is sediment-mode monthly routed total suspended sediment, and
`ABM_agent_records` are user-defined water-management bookkeeping records.
---
## 9. Diagnostic Triplets (Top 5)
See `diagnostics/triplets.yaml` for 18 symptom → diagnosis → remedy entries.
Do not duplicate the full corpus here; read the YAML first on any error.
| # | Triplet ID | Error / symptom | Diagnosis | Remedy |
|---|------------|-----------------|-----------|--------|
| 1 | `dt_001` | Simulated discharge is exactly 10× higher than observed | Precipitation data is in mm/day instead of cm/day | Divide all precipitation values by 10 before passing to `model.run()` |
| 2 | `dt_002` | Simulated discharge is orders of magnitude wrong (100× or more) | CMIP precipitation in kg/m²/s not converted to cm/day | Use `prec_cm = prec_kgm2s * 86400.0 / 10.0` |
| 3 | `dt_003` | PET calculation returns unrealistic values; seasonal cycle is muted | Temperature data is in Kelvin instead of Celsius | Subtract 273.15 from all temperature values |
| 4 | `dt_004` | Discharge consistently too low; evaporation excessive | PET provided in mm/day instead of cm/day | Divide PET values by 10 |
| 5 | `dt_005` | Simulated discharge is exactly 100× lower than observed | Subbasin area specified in km² instead of hectares (ha) | Multiply all area values by 100 |
Key failure domains:
- **unit_conversion** (7 triplets): Silent errors from wrong input units
- **parameter_format** (3 triplets): YAML config mistakes
- **runtime** (3 triplets): Crashes during execution
- **silent_error** (3 triplets): Model runs but results are wrong
- **calibration** (2 triplets): GA convergence issues
---
## 15. File Structure
```
ki/
├── SKILL.md # This file — main entry point
├── tools/
│ ├── convert_climate_inputs.py # ERA5/CMIP → model format
│ ├── convert_parameters.py # Soil/land-use → GWLF/ABCD params
│ ├── build_model_config.py # Generate model.yaml
│ ├── run_hydrocnhs.py # Execute model or calibration
│ └── parse_output.py # Extract results to CSV + metrics
├── docs/
│ ├── s1_climate_data_skill.md # Climate data preparation
│ ├── s2_parameter_estimation_skill.md # Parameter estimation
│ ├── s3_model_configuration_skill.md # Model config building
│ ├── s5_execution_skill.md # Model execution
│ ├── s7_output_analysis_skill.md # Output analysis
│ └── s8_calibration_skill.md # Calibration workflow
└── diagnostics/
└── triplets.yaml # 18 diagnostic triplets
```
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!