Skip to content

Voxelize an inventory into a 3D canopy grid

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

A physics-based fire model doesn’t run on a list of trees; it runs on a 3D grid of fuel. Voxelization crosses that gap — it builds a crown for each tree and discretizes it onto a regular voxel lattice, so each cell carries a canopy fuel property such as live-foliage bulk density (kg/m**3). The result is a grid you can inspect, combine with surface and terrain grids, and export to QUIC-Fire.

  1. An API key: my-api-key.

  2. A domain: your-domain-id.

  3. A completed inventory carrying dbh, crown_ratio, and fia_species_code — from TreeMap, a full upload, or GDAM allometry. Record its id: your-inventory-id.

POST to grids/voxelize/inventory/tree. Point source_inventory_id at the completed inventory, set the voxel resolution (horizontal x/y and vertical z, in meters), and choose the output bands. Here we build a single bulk_density.foliage.live band — the per-voxel bulk density of live foliage, the API’s default band — with foliage mass estimated from nsvb allometric equations. seed fixes the stochastic step that thins each crown into a porous canopy, so the grid is reproducible.

POST grids/voxelize/inventory/tree
curl -X 'POST' \
'https://api-v2-prod-nyvjyh5ywa-uw.a.run.app/domains/your-domain-id/grids/voxelize/inventory/tree' \
-H 'accept: application/json' \
-H 'api-key: my-api-key' \
-H 'Content-Type: application/json' \
-d '{
"name": "Canopy fuel grid",
"source_inventory_id": "your-inventory-id",
"resolution": { "horizontal": 2, "vertical": 1 },
"bands": ["bulk_density.foliage.live"],
"biomass_source": {
"type": "allometry",
"equations": "nsvb",
"components": ["foliage"],
"component_states": { "foliage": { "live": 1.0, "dead": 0.0 } }
},
"seed": 42
}'

Record the grid id: your-tree-grid-id. Poll until completed:

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

The completed grid’s georeference.shape is [37, 442, 654] — 37 vertical layers of 1 m stacked over the 442 × 654 horizontal lattice (rows × columns). The vertical extent is the tallest crown; the horizontal cell size and origin come from the resolution and the domain. That’s the 3D canopy the export writes as treesrhof.dat.

  • Inventory missing morphology columns. Voxelizing an inventory without dbh, crown_ratio, and fia_species_code returns a 422 naming the missing columns and pointing you at the allometry endpoint:

    {
    "detail": "Inventory 'your-inventory-id' is missing column(s) ['crown_ratio', 'dbh', 'fia_species_code'] required for voxelization. Impute ['crown_ratio', 'dbh', 'fia_species_code'] with the allometry endpoint (POST /domains/your-domain-id/inventories/tree/allometry/gdam with source_tree_inventory_id='your-inventory-id'), then voxelize the resulting inventory."
    }

    Complete the inventory with GDAM allometry, then voxelize the resulting inventory.

  • No tree status. Voxelization treats a tree with no fia_status_code as live — so a GDAM-completed inventory (species imputed, status absent) voxelizes correctly. To represent dead stems explicitly, the status must come from the inventory’s source — a TreeMap inventory or an upload that carries fia_status_code — since allometry doesn’t impute it.

  • Source inventory not completed. Voxelization reads the inventory’s data — poll it to completed first.

  • Mismatched lattice at export. Every grid in a combined export must share one lattice. Pick a voxel resolution here that matches your surface and terrain grids (2 m horizontal is the QUIC-Fire default), or resample them to agree.

  • Expecting identical voxels without a seed. The step that samples which sub-voxels a crown fills is stochastic; omit seed and each run draws a fresh realization. Set it for reproducibility.