Skip to content
Back to skills

Docs

ASecurity

Convert global reanalysis or site-level meteorological observations into CLASSIC-compatible netCDF forcing files. CLASSIC requires **7 separate netCDF files** (one variable per file) with a specific time encoding that differs from standard CF conventions.

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

Works with

  • cli

Security analysis

A100/100

Pro scans all 10 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-4c0efd75/badge)](https://www.skillsdirectory.com/skills/lzwei196-docs-4c0efd75)

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
# Stage 1: Meteorological Forcing Preparation

## Purpose

Convert global reanalysis or site-level meteorological observations into CLASSIC-compatible netCDF forcing files. CLASSIC requires **7 separate netCDF files** (one variable per file) with a specific time encoding that differs from standard CF conventions.

## Inputs

| Input | Source | Format |
|-------|--------|--------|
| Air temperature | CRU-JRA, ERA5, CMFD, or site CSV | K or deg C |
| Precipitation | CRU-JRA, ERA5, CMFD, or site CSV | mm/hr, mm/day, or kg/m2/s |
| Shortwave radiation | CRU-JRA, ERA5, CMFD | W/m2 (or J/m2 for ERA5 accumulated) |
| Longwave radiation | CRU-JRA, ERA5, CMFD | W/m2 |
| Specific humidity | CRU-JRA, ERA5, CMFD | kg/kg or g/kg |
| Wind speed | CRU-JRA, ERA5, CMFD | m/s |
| Surface pressure | CRU-JRA, ERA5, CMFD | Pa, hPa, or kPa |

## Outputs

Seven netCDF-4 files, one variable per file:
- `dswrf.nc` — Downwelling shortwave (W/m2)
- `dlwrf.nc` — Downwelling longwave (W/m2)
- `pre.nc` — Precipitation rate (kg m-2 s-1)
- `tmp.nc` — Air temperature (**deg C**, NOT Kelvin)
- `spfh.nc` — Specific humidity (kg/kg)
- `wind.nc` — Wind speed (m/s)
- `pres.nc` — Surface pressure (Pa)

Each file has dimensions `(time, lat, lon)` with time encoded as `"day as %Y%m%d.%f"`.

## Procedure

1. **Identify source dataset** and its native units/resolution
2. **Extract nearest grid cell** (for gridded data) or load CSV
3. **Convert units** using the conversion functions:
   - Temperature: K → deg C (subtract 273.15)
   - Precipitation: mm/hr → kg/m2/s (divide by 3600)
   - Humidity: g/kg → kg/kg (divide by 1000)
   - Pressure: hPa → Pa (multiply by 100)
4. **Clip shortwave** to >= 0 (interpolation can produce negatives)
5. **Encode time** as `"day as %Y%m%d.%f"` (e.g., 20010601.5 = noon June 1 2001)
6. **Write netCDF-4** with proper attributes
7. **Validate output** ranges

## Verification

```python
import netCDF4 as nc
ds = nc.Dataset("tmp.nc")
t = ds.variables["tmp"][:]
assert t.min() > -90 and t.max() < 60, "Temperature out of physical range"
# Check time encoding
time_vals = ds.variables["time"][:]
assert time_vals[0] > 18000000, "Time should be YYYYMMDD.f format, not days-since"
ds.close()
```

## Traps

| Trap | Symptom | Fix |
|------|---------|-----|
| Temperature in K instead of C | Soil temperatures ~300K, energy balance wrong | Subtract 273.15 |
| Precipitation in mm/day instead of kg/m2/s | Runoff 86400x too high | Divide by 86400 |
| Specific humidity in g/kg | Evaporation 1000x too high | Divide by 1000 |
| Pressure in hPa | Atmospheric density 100x too low | Multiply by 100 |
| Time as "days since" | Model reads wrong dates, crashes or wrong season | Rewrite as YYYYMMDD.f |
| Missing first timestep at 00:00 day 1 | Model assigns wrong initial values | Ensure data starts at hour 0, minute 0, day 1 |
| Shortwave negative after interpolation | NaN propagation | Clip to max(0, SW) |

## Example

```bash
python ki/tools/convert_forcing_to_classic.py \
    --source_type crujra \
    --source_dir /path/to/crujra/ \
    --lat 45.5 --lon -75.5 \
    --start_year 1991 --end_year 2010 \
    --output_dir met_files/ \
    --timestep_minutes 30
```

Files in this skill

  • REFERENCES.md2.4 KB
  • format_spec.yaml29.3 KB
  • papers.json5 KB
  • s1_met_forcing_skill.md3.1 KB
  • s2_soil_init_skill.md3.8 KB
  • s3_configuration_skill.md4.5 KB
  • s4_execution_skill.md3.5 KB
  • s5_output_analysis_skill.md4.5 KB
  • validation_convention.yaml21.6 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…