Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ For more information about this file see also [Keep a Changelog](http://keepacha
## Unreleased

### Added
- Added `inst/ilamb/` pipeline in PEcAn.benchmark to convert downscaled SDA reanalysis GeoTIFFs into ILAMB-compatible CF netCDF for carbon-cycle benchmarking (#4019).
- Added PEcAn.PEPRMT model, including a demo run with example data
- Add `format_try_for_ma()` and `try_trait_mapping()` to `PEcAn.data.remote` to convert trait data from the external TRY database into the tabular format required by the PEcAn meta-analysis module (#3717).
- Add function `qsub_sda()` for submitting SDA batch jobs by splitting a large number of sites into multiple small groups of sites (#3634).
Expand Down
1 change: 1 addition & 0 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ authors:
- given-names: David LeBauer
affiliation: University of Arizona
orcid: 'https://orcid.org/0000-0001-7228-053X'
- given-names: Tejas Dahiya
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend moving your name down to the bottom of the list. You're definitely not "second author" on PEcAn

- given-names: Michael Dietze
orcid: 'https://orcid.org/0000-0002-2324-2518'
affiliation: Boston University
Expand Down
4 changes: 4 additions & 0 deletions modules/benchmark/NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# PEcAn.benchmark 1.7.5.9000

## Added

* Added Python pipeline (`inst/ilamb/`) to convert PEcAn SDA reanalysis GeoTIFFs to ILAMB-compatible CF netCDF (cVeg, cSoil, mrsol, lai) with unit tests (#4019).

## Fixed

* `metric_PPMC()`: added `use = "pairwise.complete.obs"` to `stats::cor()` so the Pearson correlation is computed on available pairs rather than returning `NA` whenever any observation is missing. This matches the behaviour of `metric_cor()` in the same package.
Expand Down
105 changes: 105 additions & 0 deletions modules/benchmark/inst/ilamb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# PEcAn-to-ILAMB Conversion

Converts PEcAn SDA carbon reanalysis outputs (downscaled GeoTIFF ensemble maps)
into ILAMB-compatible CF-convention netCDF files for benchmarking against
TRENDY, CMIP, and observational datasets.

## Overview

The PEcAn North American carbon reanalysis (Zhang et al. 2026) provides
downscaled 1 km ensemble maps of four state variables. This tool reads those
GeoTIFFs, computes the ensemble mean, coarsens to ILAMB's default 0.5 degree
resolution, applies unit conversions, and writes CF-1.8 compliant netCDF that
ILAMB can ingest directly.

## Input

GeoTIFF ensemble maps organized as:

```
<input_dir>/<year>/<variable>_<year>/ensemble_<n>_<year>_<variable>.tiff
```

- 13 years (2012-2024), annual snapshots fixed to July 15
- 4 variables, 100 ensemble members each
- 1 km resolution (9360 x 19080), EPSG:4326

## Variable mapping and unit conversions

| PEcAn variable | CMOR name | Source units | Conversion | ILAMB units |
|----------------|-----------|--------------|------------|-------------|
| AbvGrndWood | cVeg | Mg C ha-1 | x 0.1 | kg m-2 |
| TotSoilCarb | cSoil | kg C m-2 | none | kg m-2 |
| SoilMoistFrac | mrsol | vol. percent | x 9.98 | kg m-2 |
| LAI | lai | m2 m-2 | none | m2 m-2 |

**Aboveground biomass** is already a carbon density (Mg C ha-1), so the
conversion to kg m-2 is purely unit scaling: 1 Mg ha-1 = 0.1 kg m-2.

**Soil moisture** is volumetric water content expressed as percent over the
0-100 cm root zone. Conversion to mass per area:

```
kg m-2 = percent / 100 x 1.0 m depth x 998 kg/m3 = percent x 9.98
```

The 0-100 cm root-zone depth was confirmed with the dataset author
(D. Zhang, pers. comm.), and matches the depth span of the ILAMB Wang2021
soil-moisture benchmark (0-10, 10-30, 30-50, 50-100 cm layers).

## Output

CF-1.8 compliant netCDF on a 0.5 degree regular grid (156 x 318) covering the
North American study area (7-85N, 179-20W):

- `<output_dir>/<cmor_name>/<cmor_name>_<year>.nc` (one file per year)
- `<output_dir>/<cmor_name>.nc` (merged multi-year file)

Latitude is monotonically increasing (south to north); coordinates are rounded
to 0.01 degrees; time is encoded as days since 1850-01-01 with full-year
bounds.

## Usage

```bash
module load python3 gcc/13.2.0
export PATH=$HOME/.local/bin:$PATH

# Convert all variables, all years
python convert_geotiff_to_ilamb.py \
--input_dir /path/to/NA_SDA_maps_zipped \
--output_dir /path/to/output

# Single variable / year range
python convert_geotiff_to_ilamb.py --variables AbvGrndWood --years 2014 2014

# Skip the merge step
python convert_geotiff_to_ilamb.py --skip-merge
```

On an HPC system, reading 100 full-resolution members per variable exceeds
interactive CPU limits; submit the full run as a batch job.

## Testing

```bash
pytest test_convert.py -v
```

13 tests cover file existence, CMOR variable naming, all four unit
conversions, output grid shape, CF-1.8 compliance, latitude direction,
spatial coverage, chronological multi-year merging, and ILAMB `ModelResult`
loading. Set `ILAMB_OUTPUT_DIR` to point the tests at your output directory.

## Dependencies

`numpy`, `xarray`, `rasterio`, `netCDF4`, and `ILAMB` (for the loading test).

## Notes

- Fluxes (GPP, NEE) are not included; the downscaled product covers only the
four state variables above. Flux benchmarking will draw from the raw SDA
netCDF outputs in a later contribution.
- A known structural discontinuity exists in the underlying LandTrendr input
around 2017-2018 (see the ORNL DAAC documentation); it is preserved as-is in
the converted output rather than adjusted here.
Loading
Loading