← Lillie AcademyCourse contentslillieearthintelligence.com

Module 10: Wildfire Systems, Detection to Damage, End to End

Phase: IV, Production and the job
Level: Advanced
Estimated time: ~12 hours (about 3 h concepts, 8 h lab, 1 h write-up)
Prerequisites: Phases I to III (you will reuse cube, indices, sar_change, seg, forestry).
Portfolio thread: Portfolio Project D, a firewatch package that runs end to end from hotspot to damage report.


Why this module

Wildfire employers (Overstory, Pano AI, utilities, and the Earth Fire Alliance ecosystem) want people who can stitch active-fire detections, perimeters, and post-fire imagery into a pipeline that runs unattended and degrades gracefully when data is missing. This module is where the pieces you built across the course become a system: a service that clusters hotspots into fire events, triggers analysis, and emits a damage report automatically. It is also your most impressive portfolio artifact, because it shows end-to-end systems thinking, not just a model.

Learning outcomes

After this module you can:

  1. Explain active-fire detection physics and the main sensors (VIIRS and MODIS, GOES-R, and the new FireSat constellation).
  2. Use the FIRMS API and perimeter feeds and know their latency and revisit trade-offs.
  3. Cluster hotspots into fire events in space and time and persist them.
  4. Trigger post-fire analysis on a threshold and reuse your dNBR, Sentinel-1, and U-Net detectors.
  5. Generate an automated damage report with burned area, uncertainty, severity, and biomass affected.
  6. Add a next-day spread probability layer and design the pipeline to degrade gracefully.

Concept lessons (about 3 hours)

Lesson 1: Active-fire detection physics

Active-fire detection finds thermal anomalies. A burning pixel emits strongly in the mid-wave infrared (around 4 micrometers), so contextual algorithms (the Giglio and Schroeder lineage) flag a pixel as fire when it is far hotter than its neighbors, and report fire radiative power (FRP) as an intensity measure. Sensors differ by orbit and cadence:

Keep three products distinct: active-fire detection (where it is burning now), perimeter (the fire's extent over time), and severity (post-fire damage, your dNBR work).

Lesson 2: Data sources and cadence

The FIRMS API delivers VIIRS and MODIS hotspots in near real time. Perimeter feeds include NIFC and CAL FIRE for the US and EFFIS and GWIS globally. The design tension is always latency versus resolution: geostationary is fast but coarse, polar-orbiting is finer but less frequent, and FireSat is changing that trade-off. Choose sources to match your latency budget.

Lesson 3: From hotspots to fire events

Individual hotspots are noisy points; a fire is a cluster of them across space and time. DBSCAN groups nearby detections into events, and ST-DBSCAN (spatiotemporal) adds a time dimension so a fire is a connected group in space and time, not a merge of two unrelated fires a week apart. Persist events to PostGIS or GeoParquet so the pipeline has memory across runs.

Lesson 4: Fire spread modeling

Spread has a physical lineage (the Rothermel model) and a modern ML one: the Next Day Wildfire Spread dataset frames it as predicting tomorrow's fire mask from today's fire plus fuels, weather, and terrain. Adding a 24-hour spread probability layer turns a backward-looking damage report into a forward-looking risk product. Keep the vocabulary straight: risk, hazard, and exposure are different things.

Lesson 5: System design for graceful degradation

A real near-real-time pipeline must survive missing data and partial failures. If Sentinel-2 is cloudy for three weeks, fall back to the all-weather Sentinel-1 detector; if a scene is missing, emit a partial report rather than crashing; deduplicate events across runs so you do not double-count; and keep the whole thing idempotent so a rerun is safe. Designing for graceful degradation is what separates a demo from a service, and it sets up the deployment work in Module 11.


Guided lab (about 8 hours): the firewatch package

Open in Colab Open in GitHub Codespaces

Build a package that runs end to end for one region.

Step 1: Ingest and cluster

Pull FIRMS VIIRS near-real-time detections for a region, then cluster them into events.

"""firewatch/events.py: hotspot clustering and triggering (testable)."""
from __future__ import annotations
import numpy as np

def cluster_hotspots(lons, lats, eps_km=1.0, min_samples=3):
    """Cluster fire detections with DBSCAN on the sphere (haversine).

    Returns integer labels; -1 is noise. Points closer than eps_km group together.
    """
    from sklearn.cluster import DBSCAN
    X = np.radians(np.column_stack([np.asarray(lats), np.asarray(lons)]))
    labels = DBSCAN(eps=eps_km / 6371.0, min_samples=min_samples,
                    metric="haversine").fit(X).labels_
    return labels

def should_trigger(frp_sum, area_ha, min_frp=100.0, min_area_ha=10.0):
    """Trigger post-fire analysis once an event is large and hot enough."""
    return (frp_sum >= min_frp) and (area_ha >= min_area_ha)
# tests/test_events.py
import numpy as np
from firewatch.events import cluster_hotspots, should_trigger

def test_two_separate_fires():
    a_lon = [0, 0.001, 0.002, 0.001, 0.0]; a_lat = [0, 0.001, 0.0, 0.002, 0.001]
    b_lon = [10, 10.001, 10.002, 10.001, 10.0]; b_lat = [10, 10.001, 10.0, 10.002, 10.001]
    labels = np.asarray(cluster_hotspots(a_lon + b_lon, a_lat + b_lat, eps_km=1.0, min_samples=3))
    assert -1 not in labels
    assert labels[0] == labels[4] and labels[0] != labels[5]

def test_trigger_thresholds():
    assert should_trigger(150, 20) is True
    assert should_trigger(50, 20) is False   # not hot enough
    assert should_trigger(150, 5) is False   # not big enough

Persist the resulting events to GeoParquet or PostGIS with a stable event id.

Step 2: Trigger analysis

When an event passes should_trigger, query STAC for the latest cloud-free HLS and the latest Sentinel-1 RTC over its footprint, then run the dNBR map (Module 2), the Sentinel-1 change detector (Module 6), and the U-Net (Module 7). If optical is cloudy, degrade gracefully to the Sentinel-1 result.

Step 3: Automated damage report

For each triggered event, generate a report: burned area in hectares with a conformal uncertainty interval (Module 5), a severity-class histogram, biomass affected (Module 5), a map PNG, and a GeoJSON perimeter. Make it a function that takes an event and returns a report object plus files.

Step 4: Spread layer

Train a model on the Next Day Wildfire Spread dataset and add a 24-hour spread probability layer to the report.

Step 5: Package, test, sample report, commit

Structure firewatch as a real package with tests and a sample report checked in.

git add firewatch/ tests/test_events.py notebooks/12_firewatch.ipynb
git commit -m "Module 10: firewatch end-to-end (cluster, trigger, analyze, report, spread)"
git push

Checkpoint

Self-check (answers below).

  1. What does fire radiative power measure, and how does a contextual algorithm decide a pixel is on fire?
  2. Why cluster hotspots in space and time rather than space alone?
  3. Your pipeline must produce a report even when Sentinel-2 is cloudy for weeks. How do you design for that?
  4. What does FireSat change about early fire detection compared to VIIRS?

Interview-style questions (practice out loud).

Answers. (1) FRP measures the radiant energy released by the fire (its intensity); a contextual algorithm flags a pixel when its mid-wave infrared brightness is anomalously high relative to its neighboring background pixels.
(2) Space-only clustering would merge two unrelated fires that occur in the same place at different times; adding time separates them into distinct events and tracks a single fire's growth.
(3) Fall back to the all-weather Sentinel-1 detector, emit partial reports when a product is missing, dedupe and stay idempotent so reruns are safe, and record data availability in the report.
(4) FireSat's purpose-built infrared payload detects much smaller fires through smoke with far more frequent revisit, enabling earlier detection than the few-times-daily VIIRS passes.


Deliverable

A firewatch package that, for one region, ingests FIRMS hotspots, clusters them into events, triggers HLS and Sentinel-1 analysis on a threshold, and emits an automated damage report (burned area with uncertainty, severity histogram, biomass affected, map, GeoJSON perimeter) plus a next-day spread layer, with tests and a sample report. This is Portfolio Project D.

What a hiring manager sees

A single model is table stakes; a working end-to-end service is not. firewatch shows you can integrate detection, multi-sensor analysis, uncertainty, and reporting into something that runs unattended and degrades gracefully, which is exactly what wildfire and utility teams need. Reusing your earlier modules as components demonstrates that you build systems, not one-off notebooks, and naming the current sensor landscape (FireSat included) shows you track the field.

Currency note

Verified August 2026. FIRMS provides VIIRS and MODIS near-real-time active-fire data via its API. The FireSat constellation (Earth Fire Alliance and Muon Space) launched its first three operational satellites on 7 July 2026, following the FireSat0 protoflight of March 2025; the operational satellites were in commissioning at that time, so verify data availability and access terms before relying on FireSat in the lab, and use FIRMS as the dependable source. GOES-R ABI fire products, NIFC and CAL FIRE perimeters, and EFFIS and GWIS remain available. The Next Day Wildfire Spread dataset is a published ML benchmark. firewatch uses scikit-learn (DBSCAN); pin versions in your Module 0.1 environment file.

Previous9.7 Agriculture and Food SecurityNext11 MLOps and Cloud Deployment