Skip to content

Create 1-hour dead fuel moisture grids

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

The Fosberg endpoint estimates 1-hour dead fuel moisture content (DFMC) — the moisture in the fine dead fuels that drive fire spread — across a domain. It is a derived grid: it takes no raster of its own, but combines two grids you have already built, plus a handful of weather and scenario numbers.

InputBand it readsWhat it contributes
Topography grid (2D)slope, aspect (degrees)terrain geometry
Surface irradiance grid (2D)irradiance.surface.relativeshading, as 1 − irradiance

The one endpoint, grids/fuel-moisture/dead/fosberg, reads those two grids at each cell, applies the Fosberg & Deeming (1971) model with your reference weather, and writes a single 2D fuel_moisture.dead.1hr band — a percent of oven-dry fuel weight — on the topography grid’s lattice. This guide builds one, walks each input, and then shows how the weather inputs move the result.

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

  2. A domain. your-domain-id.

  3. A completed 2D topography grid with slope and aspect bands. your-topography-grid-id. Build one from 3DEP requesting "bands": ["slope", "aspect"]. Fosberg reads both in degrees.

  4. A completed leaflux surface irradiance grid with an irradiance.surface.relative band. your-irradiance-grid-id. Build one from solar irradiance requesting "bands": ["irradiance.surface.relative"]. Fosberg reads it as shading: a cell where relative irradiance is 0.2 is 0.8 shaded, and shaded fuel holds more moisture.

The whole flow — create, poll, and read the band back — in one script:

1-hour DFMC from two source grids
"""Create a Fosberg 1-hr dead fuel moisture grid, poll it, and read it back.
Point the two source grids at a completed 2D topography grid (slope + aspect)
and a completed leaflux surface irradiance grid on the same domain.
"""
import numpy as np
import fastfuels_sdk.v2 as ff
ff.set_api_key("my-api-key")
topography = ff.get_grid("your-domain-id", "your-topography-grid-id")
irradiance = ff.get_grid("your-domain-id", "your-irradiance-grid-id")
# 1. Create the grid and poll it to completed.
grid = ff.grids.create_dead_fuel_moisture_grid_from_fosberg(
topography,
irradiance,
dry_bulb_temp=75, # Fahrenheit
relative_humidity=30, # percent
time=1200, # HHMM, 0800-1959
month="June",
)
grid.wait()
# 2. Read the 2D band back as one (y, x) array — the SDK fetches every chunk
# and places it at its offset for you.
moisture = grid.to_numpy("fuel_moisture.dead.1hr")
# 3. Values are 1-hr dead fuel moisture content, percent of oven-dry weight.
cells = moisture[np.isfinite(moisture)]
print(f"1-hr DFMC (%): min {cells.min():.1f}, mean {cells.mean():.1f}, max {cells.max():.1f}")

Post the two source grid ids and the reference weather. The response is a pending Grid; poll it to completed as with any other grid.

POST — 1-hour DFMC
curl -X 'POST' \
'https://api-v2-prod-782971006568.us-west1.run.app/domains/your-domain-id/grids/fuel-moisture/dead/fosberg' \
-H 'accept: application/json' \
-H 'api-key: my-api-key' \
-H 'Content-Type: application/json' \
-d '{
"source_topography_grid_id": "your-topography-grid-id",
"source_irradiance_grid_id": "your-irradiance-grid-id",
"dry_bulb_temp": 75,
"relative_humidity": 30,
"time": 1200,
"month": "June"
}'

Each input is worth a deliberate choice:

FieldRequiredWhat it is
source_topography_grid_idyesThe 2D topography grid — slope + aspect in degrees.
source_irradiance_grid_idyesThe leaflux surface irradiance grid — irradiance.surface.relative.
dry_bulb_tempyesDry-bulb air temperature in °F, at least 10.
relative_humidityyesRelative humidity as a percent, 0100.
timeyesLocal time of day as a 24-hour HHMM integer (e.g. 1200 for noon).
monthyesFull month name ("June") — picks the seasonal correction table.
elevationnobelow | near | above, default near.
name, description, tagsnoOptional metadata.

Record the id as your-moisture-grid-id and poll it. Because Fosberg is a 2D derivation, the completed grid is genuinely two-dimensional — georeference.shape is (y, x), and it exports and reads back as a plain raster.

GET grid status
curl -X 'GET' \
'https://api-v2-prod-782971006568.us-west1.run.app/domains/your-domain-id/grids/your-moisture-grid-id' \
-H 'accept: application/json' \
-H 'api-key: my-api-key'

The completed grid inherits the topography grid’s lattice — same crs, transform, and shape ([442, 654] here: a 442 × 654 grid of 2 m cells). The source block records both input grids and every weather input, with the source grids’ checksums, so the grid is reproducible and you can tell if a source has changed since.

Fetch the fuel_moisture.dead.1hr band the same way as any other 2D grid — per band, per chunk — using the loop in Fetch and stream grid data. Every cell carries a value; read it dense.

Two top-down maps of the same domain, north up. Left: a grayscale 'fraction shaded' map — mostly white (sunlit) ground with dense black speckle where tree crowns cast shadows and broad darker patches on shaded slopes. Right: the 1-hour dead fuel moisture map on a tan-to-teal scale — the sunlit ground is a uniform tan at the 5 percent base, and exactly where the left map is dark the fuel turns teal at 8 percent, three points wetter.

The Fosberg grid is the shading map, turned into moisture. Left: shading, 1 − irradiance.surface.relative, from the source irradiance grid. Right: the 1-hour DFMC it drives. Exposed fuel sits at the 5 % base for this weather; shaded fuel — under crowns and on shaded slopes — reads about 3 points wetter. The values are quantized because the model is a lookup table.

The values are a percent of oven-dry fuel weight, so 5 means the fuel weighs 5 % more than it would bone-dry. Low single digits are dry, fire-ready fuels; the wetter, shaded cells are correspondingly harder to ignite.

The two source grids fix the spatial pattern — where it is shaded, steep, or sun-facing. The weather inputs set the level. Raising relative_humidity lifts the whole field toward wetter fuel; lowering it, or raising dry_bulb_temp, dries everything out. The shaded-versus-exposed structure stays put underneath.

Three top-down maps of the same domain side by side, sharing one moisture color scale from about 2 to 11 percent. At 10 percent relative humidity the field is pale (dry, roughly 2 to 5 percent); at 30 percent it is green-blue (about 5 to 8 percent); at 60 percent it is deep blue (about 8 to 11 percent). The shaded-patch texture is identical in all three — only the overall level shifts wetter as humidity rises.

The same scene at three relative humidities, everything else held fixed. The whole surface shifts drier to wetter as humidity climbs, while the shaded-patch pattern set by terrain and canopy stays the same. Temperature works the same way in reverse — hotter air dries the fuel.

For a named grid with an elevation correction — a hot, dry August afternoon on a site above the reference weather station — pass the full request:

POST — with metadata and elevation
curl -X 'POST' \
'https://api-v2-prod-782971006568.us-west1.run.app/domains/your-domain-id/grids/fuel-moisture/dead/fosberg' \
-H 'accept: application/json' \
-H 'api-key: my-api-key' \
-H 'Content-Type: application/json' \
-d '{
"name": "Peak burn-period 1-hr DFMC",
"description": "Midday August dead fuel moisture for the burn window.",
"tags": ["fuel-moisture", "surface-fuel"],
"source_topography_grid_id": "your-topography-grid-id",
"source_irradiance_grid_id": "your-irradiance-grid-id",
"dry_bulb_temp": 82,
"relative_humidity": 20,
"time": 1400,
"month": "August",
"elevation": "above"
}'

The endpoint calls the Fosberg & Deeming (1971) 1-hour timelag model. “1-hour timelag” is the class of fine dead fuels — cured grass, litter, and twigs under about ¼ inch — that gain or shed moisture within roughly an hour of a change in the weather, which is why so much of fire behavior tracks them.

The model reads a reference fuel moisture from a dry-bulb-temperature × relative-humidity table, then applies additive corrections for the month, time of day, slope, aspect, and whether the fuel is shaded — the two source grids supply slope, aspect, and shading per cell, and the request supplies the rest. Slope is classed internally by percent grade, so the API converts your topography grid’s degrees before the lookup. The result is a percent of oven-dry weight.

  • Passing Celsius for dry_bulb_temp. It is Fahrenheit. A Celsius value is in range but wrong — 20 (°C, a mild day) is read as 20 °F.
  • A time outside 08001959. The model has no night-time table; a value outside the window, or with minutes past 59, is rejected.
  • Source grids on different lattices. Slope, aspect, and shading are read at the same cell, so the topography and irradiance grids must share one x/y lattice. Align the topography grid to the irradiance grid before this request.
  • A source grid still pending. Poll both source grids to completed first; Fosberg reads their data, not just their metadata.
  • Confusing elevation with the terrain. elevation is a below/near/above weather correction relative to the reporting station — not the topography grid’s elevation band.
  • Reusing a grid after rebuilding a source. The source block records each source grid’s checksum. If you rebuild the topography or irradiance grid, rebuild the moisture grid too.