Skip to content

Generate a tree inventory from TreeMap

You are viewing in-progress documentation for v2 (Beta). Switch to the stable version for the current production release.

A tree inventory is a list of individual stems — location, species, DBH, height, crown ratio — and it’s the basis for 3D canopy fuels. FastFuels can generate one for any CONUS domain from the USGS/USFS TreeMap product in two steps:

  1. Build a PIM grid — a per-cell summary of species composition and stem density from TreeMap (pim/treemap).
  2. Realize individual trees — a point process places individual stems consistent with that grid (tree/pim).
  1. An API key: my-api-key.

  2. A domain within CONUS: your-domain-id. See Create a domain. TreeMap covers forested lands across the conterminous US.

The whole flow in one script:

Generate a tree inventory (both steps + polling)
import time
import requests
API_KEY = "my-api-key"
DOMAIN_ID = "your-domain-id"
BASE = "https://api-v2-prod-nyvjyh5ywa-uw.a.run.app"
HEADERS = {"api-key": API_KEY}
def poll(kind: str, resource_id: str) -> dict:
while True:
r = requests.get(
f"{BASE}/domains/{DOMAIN_ID}/{kind}/{resource_id}", headers=HEADERS
).json()
if r["status"] in ("completed", "failed"):
return r
time.sleep(5)
# Step 1: a TreeMap PIM grid (species composition + density from FIA TreeMap).
pim = requests.post(
f"{BASE}/domains/{DOMAIN_ID}/grids/pim/treemap",
headers=HEADERS,
json={"name": "TreeMap PIM grid"},
).json()
pim = poll("grids", pim["id"])
# Step 2: realize individual trees from the PIM grid. `seed` makes the
# stochastic point process reproducible.
inv = requests.post(
f"{BASE}/domains/{DOMAIN_ID}/inventories/tree/pim",
headers=HEADERS,
json={
"name": "TreeMap tree inventory",
"source_pim_grid_id": pim["id"],
"seed": 42,
},
).json()
inv = poll("inventories", inv["id"])
print(inv["id"], inv["status"]) # -> <inventory id> completed
POST grids/pim/treemap
curl -X 'POST' \
'https://api-v2-prod-nyvjyh5ywa-uw.a.run.app/domains/your-domain-id/grids/pim/treemap' \
-H 'accept: application/json' \
-H 'api-key: my-api-key' \
-H 'Content-Type: application/json' \
-d '{
"name": "TreeMap PIM grid"
}'

Poll it to completed (TreeMap is coarse — the grid is small and fast), then record its id: your-pim-grid-id.

{
"id": "your-pim-grid-id",
"domain_id": "your-domain-id",
"status": "completed",
"source": {
"name": "pim",
"bands": ["tm_id"],
"description": "TreeMap plot imputation raster (FIA plot IDs at 30m)",
"alignment": {
"target": "domain",
"method": null,
"resolution": null
},
"version": "2022",
"product": "treemap",
"extent_buffer_cells": 0
},
"georeference": {
"crs": "EPSG:32611",
"shape": [30, 45]
}
}

Point source_pim_grid_id at the completed PIM grid. seed fixes the stochastic point process so the inventory is reproducible — same seed, same trees.

POST inventories/tree/pim
curl -X 'POST' \
'https://api-v2-prod-nyvjyh5ywa-uw.a.run.app/domains/your-domain-id/inventories/tree/pim' \
-H 'accept: application/json' \
-H 'api-key: my-api-key' \
-H 'Content-Type: application/json' \
-d '{
"name": "TreeMap tree inventory",
"source_pim_grid_id": "your-pim-grid-id",
"seed": 42
}'

Record the inventory id: your-inventory-id. Poll until completed:

GET inventory status
curl -X 'GET' \
'https://api-v2-prod-nyvjyh5ywa-uw.a.run.app/domains/your-domain-id/inventories/your-inventory-id' \
-H 'accept: application/json' \
-H 'api-key: my-api-key'

The completed inventory’s columns describe each tree: x, y, fia_species_code, fia_status_code, dbh (cm), height (m), and crown_ratio. On the Blue Mountain domain this seed produces ≈42,000 stems.

Other ways to get a tree inventory: from a canopy height model (from a CHM) or by uploading your own tree list.

  • Domain outside CONUS. TreeMap is a conterminous-US product.
  • Creating the inventory before the PIM grid is completed. tree/pim reads the PIM grid’s data — poll step 1 to completed first.
  • Expecting identical trees without a seed. Omit seed and each run draws a fresh random realization. Set it when you need reproducibility.