geeViz.fireLib.fuels

Fuels and terrain assembly — the layer everything else stands on.

The bottleneck in real fire work is almost never the simulator. It is assembling fuels, terrain, and weather into one consistent, aligned stack, then redoing all of it when a boundary or a year changes. That is exactly what Earth Engine removes, and it is why this module exists before any behavior model does.

Asset ids below were verified against the live catalog. LANDFIRE lives in the community catalog (projects/sat-io/...) rather than the official one, which is easy to guess wrong.

Fuel-model note: FBFM40 (Scott & Burgan) and FBFM13 (Anderson) are classification rasters — each pixel carries a fuel model number, and the physical parameters that number implies (fuel load by size class, surface-area-to-volume ratio, bed depth, moisture of extinction) live in a lookup table, not in the raster. fuel_model_params() holds that table for the subset needed by a Rothermel spread calculation.

Module Attributes

FUEL_ASSETS

Verified asset ids.

CONTEXT_ASSETS

Fire-regime and vegetation context, from the OFFICIAL catalog.

RISK_ASSET

FSim / FlamMap outputs, already computed for CONUS+AK+HI at 30 m.

NON_BURNABLE

Fuel model codes that cannot carry fire.

Functions

fuel_coverage(fuels, region, *[, scale, ...])

What fraction of an area the parameter table can actually model.

fuel_model_params(fbfm)

Rothermel bed parameters for a Scott & Burgan fuel model number.

fuel_param_image(fbfm_band, param)

Turn a fuel-model raster into a raster of one bed parameter.

landfire_fuels([bands, region])

Assemble a multi-band LANDFIRE fuels image.

terrain_layers([dem_asset, region])

Slope, aspect and terrain derivatives for fire behavior.

geeViz.fireLib.fuels.FUEL_ASSETS: Dict[str, str] = {'CBD': 'projects/sat-io/open-datasets/landfire/FUEL/CBD', 'CBH': 'projects/sat-io/open-datasets/landfire/FUEL/CBH', 'CC': 'projects/sat-io/open-datasets/landfire/FUEL/CC', 'CFFDRS': 'projects/sat-io/open-datasets/landfire/FUEL/CFFDRS', 'CH': 'projects/sat-io/open-datasets/landfire/FUEL/FVH', 'FBFM13': 'projects/sat-io/open-datasets/landfire/FUEL/FBFM13', 'FBFM40': 'projects/sat-io/open-datasets/landfire/FUEL/FBFM40', 'FCCS': 'projects/sat-io/open-datasets/landfire/FUEL/FCCS', 'FVC': 'projects/sat-io/open-datasets/landfire/FUEL/FVC', 'FVT': 'projects/sat-io/open-datasets/landfire/FUEL/FVT'}

Verified asset ids. LANDFIRE surface/canopy fuels are in the community catalog; the official LANDFIRE/ namespace carries vegetation and fire-regime products but NOT the fuel models.

geeViz.fireLib.fuels.CONTEXT_ASSETS: Dict[str, str] = {'EVC': 'LANDFIRE/Vegetation/EVC/v1_4_0', 'EVH': 'LANDFIRE/Vegetation/EVH/v1_4_0', 'EVT': 'LANDFIRE/Vegetation/EVT/v1_4_0', 'FRG': 'LANDFIRE/Fire/FRG/v1_2_0', 'MFRI': 'LANDFIRE/Fire/MFRI/v1_2_0', 'VCC': 'LANDFIRE/Fire/VCC/v1_4_0', 'VDep': 'LANDFIRE/Fire/VDep/v1_4_0'}

Fire-regime and vegetation context, from the OFFICIAL catalog.

geeViz.fireLib.fuels.RISK_ASSET = 'USDA/WRC/v0'

FSim / FlamMap outputs, already computed for CONUS+AK+HI at 30 m. Burn probability, conditional flame length, flame-length exceedance, hazard potential, and risk to potential structures. Any plan whose first milestone is “compute burn probability” is re-deriving this.

geeViz.fireLib.fuels.landfire_fuels(bands=('FBFM40', 'CBH', 'CBD', 'CC', 'CH'), *, region: Any = None)[source]

Assemble a multi-band LANDFIRE fuels image.

Parameters:
  • bands – Keys from FUEL_ASSETS. The default is exactly the set a Rothermel surface run plus a Van Wagner crown-fire check needs: a surface fuel model, canopy base height, canopy bulk density, canopy cover, and canopy height.

  • region – Optional geometry to clip to. Clipping early is usually the right call for an AOI-scale analysis — it keeps later reductions from touching tiles they will discard anyway.

Returns:

ee.Image with one band per requested key, named by that key.

Note

Bands are not unit-converted here. LANDFIRE ships canopy base height and canopy height in metres x 10, and canopy bulk density in kg/m3 x 100, precisely so they can be stored as integers. behavior() applies the scaling where the physics needs real units — doing it here would mean two places could disagree about whether a value was already scaled, which is the sort of error that produces plausible numbers rather than obvious ones.

geeViz.fireLib.fuels.terrain_layers(dem_asset: str = 'USGS/3DEP/10m', *, region: Any = None)[source]

Slope, aspect and terrain derivatives for fire behavior.

Parameters:
  • dem_asset – DEM to derive from. 3DEP 10 m for CONUS; pass "USGS/SRTMGL1_003" for near-global 30 m coverage.

  • region – Optional clip geometry.

Returns:

ee.Image with elevation, slope (degrees), aspect (degrees), northness, eastness, and slope_tan (tangent of slope, which is the form Rothermel’s slope factor actually consumes).

Note

northness / eastness exist because raw aspect must never be fed to a model or a statistic. 359 degrees and 1 degree are adjacent on the ground and maximally distant numerically; averaging them yields 180, which points the wrong way. Decomposing to cos/sin makes the circular quantity behave like two linear ones.

geeViz.fireLib.fuels.NON_BURNABLE = (91, 92, 93, 98, 99)

Fuel model codes that cannot carry fire. Rate of spread is exactly zero here, and that has to be enforced explicitly — the Rothermel equations divide by fuel load and would otherwise produce NaN or a spurious value from a zero-load bed.

geeViz.fireLib.fuels.fuel_model_params(fbfm: int) → Dict[str, Any][source]

Rothermel bed parameters for a Scott & Burgan fuel model number.

Parameters:

fbfm – FBFM40 code, e.g. 102 for GR2 or 165 for TU5.

Returns:

Dict of bed properties plus name and burnable.

Raises:

KeyError – The model is not in the table. Deliberate — silently substituting a default would return a plausible spread rate for a fuel bed nobody described, which is worse than an error because nothing downstream would question it.

geeViz.fireLib.fuels.fuel_coverage(fuels, region, *, scale: int = 90, fbfm_band: str = 'FBFM40') → Dict[str, Any][source]

What fraction of an area the parameter table can actually model.

Run this before trusting any spread result over a new area. _FBFM40_PARAMS is a verified subset, not the full Scott & Burgan 40, and an unlisted model contributes a masked pixel — so a landscape can come back looking calm simply because a third of it was unmodellable. The gap is invisible in the output image and obvious here.

Measured on a real Oregon test area: 91.4% covered, with the 8.6% shortfall dominated by GS3 (123).

Returns:

Dict with covered_fraction, total_pixels, and missing — a list of (fuel_model, pixels, fraction) sorted by how much of the area each accounts for, which is the priority order for extending the table.

geeViz.fireLib.fuels.fuel_param_image(fbfm_band, param: str)[source]

Turn a fuel-model raster into a raster of one bed parameter.

Uses remap, which is the right primitive here: the mapping is a lookup with no ordering meaning, so arithmetic on the model number itself would be nonsense (model 165 is not “more” than 102).

Parameters:
  • fbfm_band – Single-band ee.Image of FBFM40 codes.

  • param – Key from fuel_model_params(), e.g. "w_1h".

Returns:

ee.Image of that parameter, masked where the fuel model is not in the table — masked rather than zero-filled, because zero is a meaningful fuel load and an unmapped pixel is not the same as a pixel with no fuel.