Skip to content
Back to skills

Docs

ASecurity

Convert global or station climate data into the exact format and units required by HydroCNHS. This is the most error-prone step in the pipeline — wrong units cause silent failures where the model runs without errors but produces physically meaningless discharge.

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

Works with

  • cli

Security analysis

A100/100

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

Scanned September 11, 2026

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

Installs into .claude/skills of the current project.

Are you the author of Docs?

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

Security grade badge for Docs
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/lzwei196-docs-0d15498d/badge)](https://www.skillsdirectory.com/skills/lzwei196-docs-0d15498d)

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
# S1: Climate Data Preparation

## Purpose

Convert global or station climate data into the exact format and units required
by HydroCNHS. This is the most error-prone step in the pipeline — wrong units
cause silent failures where the model runs without errors but produces
physically meaningless discharge.

## Inputs

| Input | Format | Unit | Source |
|-------|--------|------|--------|
| Daily temperature | CSV or NetCDF | varies (°C, K, °F) | ERA5, CMIP6, station |
| Daily precipitation | CSV or NetCDF | varies (mm, cm, m, kg/m²/s) | ERA5, CMIP6, station |
| Daily PET (optional) | CSV or NetCDF | varies (mm, cm) | Calculated or station |
| Outlet names | list | — | From basin delineation (S0) |
| Date range | string | YYYY/M/D | User-defined |

## Outputs

| Output | Format | Unit | Destination |
|--------|--------|------|-------------|
| temp dict | Python dict | °C | model.run(temp=...) |
| prec dict | Python dict | cm/day | model.run(prec=...) |
| pet dict (optional) | Python dict | cm/day | model.run(pet=...) |

Each dict maps `{outlet_name: [list_of_daily_values]}`.

## Procedure

1. **Identify source units** — Check metadata or headers for the unit of each variable.
   ERA5 uses K for temperature and m/day for precipitation. CMIP6 uses K and
   kg/m²/s. Most station data uses °C and mm/day.

2. **Extract spatial averages** — For each subbasin/outlet, extract the
   area-weighted average from gridded data, or assign the nearest station.

3. **Convert temperature**:
   - K → °C: subtract 273.15
   - °F → °C: (F - 32) × 5/9
   - Already °C: no conversion needed

4. **Convert precipitation** (CRITICAL):
   - mm/day → cm/day: **divide by 10**
   - m/day → cm/day: multiply by 100
   - kg/m²/s → cm/day: multiply by 86400, then divide by 10
   - Already cm/day: no conversion needed

5. **Convert PET** (if provided):
   - Same conversion as precipitation (usually mm/day → cm/day)
   - If not provided, HydroCNHS will auto-calculate using Hamon method

6. **Verify date alignment** — Ensure the number of values matches
   `(end_date - start_date).days + 1`. Missing days cause index errors.

7. **Run validation checks**:
   - Mean temperature should be in range [-20, 35] °C for most basins
   - Mean precipitation should be in range [0.01, 3] cm/day
   - No negative precipitation values
   - PET should be 0–1.5 cm/day for most basins

## Verification

After conversion, run these sanity checks:

```python
import numpy as np

for outlet in temp:
    t = np.array(temp[outlet])
    p = np.array(prec[outlet])
    print(f"{outlet}: temp mean={t.mean():.1f}°C, prec mean={p.mean():.3f} cm/day")

    assert t.mean() < 100, "Temperature likely in Kelvin!"
    assert p.mean() < 5, "Precipitation likely in mm/day, not cm/day!"
    assert not np.any(p < 0), "Negative precipitation!"
```

## Traps

| Trap | Symptom | Fix |
|------|---------|-----|
| dt_001: Precipitation in mm not cm | Discharge 10× too high | Divide by 10 |
| dt_002: Precipitation in kg/m²/s | Discharge wildly wrong | ×86400 ÷10 |
| dt_003: Temperature in Kelvin | PET calculation wrong, muted seasonality | Subtract 273.15 |
| dt_004: PET in mm not cm | Evaporation 10× too high, discharge too low | Divide by 10 |

## Example

```python
# ERA5 data (temp in K, prec in m/day)
import numpy as np

# Convert
temp_C = era5_temp - 273.15        # K → °C
prec_cm = era5_prec * 100          # m/day → cm/day

# Build dicts
temp = {"WSLO": temp_C.tolist(), "DLLO": temp_C_dllo.tolist()}
prec = {"WSLO": prec_cm.tolist(), "DLLO": prec_cm_dllo.tolist()}

# Verify
for o in temp:
    assert np.mean(temp[o]) < 100, f"{o}: temp still in Kelvin!"
    assert np.mean(prec[o]) < 5, f"{o}: prec likely not in cm/day!"
```

Files in this skill

  • REFERENCES.md1.7 KB
  • format_spec.yaml24.1 KB
  • papers.json3.4 KB
  • s1_climate_data_skill.md3.7 KB
  • s2_parameter_estimation_skill.md3.7 KB
  • s3_model_configuration_skill.md4.6 KB
  • s5_execution_skill.md4 KB
  • s7_output_analysis_skill.md4.5 KB
  • s8_calibration_skill.md5.4 KB
  • validation_convention.yaml9.4 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…