Using Spaxiom for Predictive Fire Risk Assessment Across Multiple Scales
Joe Scanlin
November 2025
Spaxiom is a sensor abstraction layer and runtime that translates billions of heterogeneous sensor streams into structured, semantic events. It provides a spatial-temporal DSL for defining zones, entities, and conditions, making it easy to build context-aware applications across industries.
INTENT (Intelligent Network for Temporal & Embodied Neuro-symbolic Tasks) is Spaxiom's high-level event vocabulary. Instead of overwhelming AI agents with raw sensor data, Spaxiom emits compact, meaningful events that agents can immediately understand and act upon.
Wildfires cause over $80 billion in annual losses in the U.S. alone, intensified by climate change and longer drought seasons. Traditional fire danger systems rely on manual weather station readings and periodic field surveys, providing only coarse risk assessments updated daily or weekly. The challenge is that satellite imagery operates on different timescales than ground weather stations, soil moisture sensors track differently than acoustic beetle detectors, and none of these systems share data in real time for AI-driven risk prediction.
Spaxiom acts as a multi-scale forest monitoring system that fuses satellite vegetation health (NDVI), weather stations, soil moisture sensors, thermal cameras, smoke detectors, lightning networks, and acoustic sensors detecting bark beetle infestations. Instead of waiting for smoke to appear, it calculates a continuous "Forest Fire Danger Index" that predicts extreme risk 2-4 weeks in advance by combining drought severity, fuel moisture, vegetation stress, and pest damage. This sends alerts like "extreme fire danger—schedule prescribed burn now" or "bark beetle infestation detected—dead timber increasing ladder fuel," helping fire managers transition from reactive suppression to proactive risk mitigation through controlled burns and strategic resource positioning.
Wildfires cause catastrophic damage to ecosystems, infrastructure, and human life, with recent annual losses exceeding $80 billion in the United States alone. Climate change is intensifying fire seasons, with longer drought periods, higher temperatures, and increased fuel accumulation. Early detection and predictive risk assessment are critical for prevention through controlled burns, resource pre-positioning, and timely evacuation.
A comprehensive wildfire monitoring system integrates terrestrial, aerial, and satellite-based sensors across multiple time scales:
Traditional fire danger rating systems (e.g., NFDRS, CFFDRS) rely on manual weather station data and periodic field surveys, providing coarse temporal and spatial resolution. Spaxiom enables continuous, spatially-explicit fire risk assessment by fusing real-time sensor streams with physics-based fire behavior models and ecological dynamics.
The wildfire domain defines events spanning fuel condition, ignition probability, and fire progression:
DryFuelAccumulation: Fired when 1000-hour fuel moisture drops below critical threshold (e.g., <15%), indicating elevated fire spread potential and intensity. Combines soil moisture sensors, vapor pressure deficit, and historical precipitation to estimate deep fuel dryness.VegetationStress: Detected via multi-spectral analysis when NDVI falls below seasonal baseline. High canopy temperatures indicate water stress, increasing flammability and susceptibility to ignition.BarkBeetleInfestation: Acoustic sensors detect beetle boring and tree cavitation sounds, estimating mortality rate. Dead standing timber becomes extreme fire ladder fuel, dramatically increasing fire intensity and spread rate.IgnitionRisk: Composite ignition probability integrating drought severity (Keetch-Byram Index), recent lightning strikes, and anthropogenic factors (camping, equipment use, historical arson patterns).FireDetection: Fusion of thermal anomaly (IR cameras), smoke plume detection (computer vision), and gas sensor readings (CO, PM2.5). Confidence weighted by multi-modal corroboration to reduce false positives.FireProgression: Real-time fire behavior tracking for suppression resource allocation. Integrates fire weather, topography, and fuel models (e.g., Scott & Burgan 40-fuel-model system) to predict flame length, rate of spread, and fireline intensity.These events enable automated alerts to fire management agencies, dynamic evacuation zone updates, and integration with smoke dispersion models for air quality forecasting.
Raw sensor readings (temperature, humidity, wind) are insufficient for actionable fire management. We compute a Forest Fire Danger Index (FFDI) that integrates fuel condition, weather, and ecological stress:
where each component is normalized to [0,1] with 1 = extreme danger:
Fuel Index: Based on moisture content and loading:
where fmoisture is computed from 1000-hour timelag fuel moisture (approximated from soil moisture and vapor pressure deficit over weeks), floading reflects dead/down fuel accumulation (tons/acre), and fcontinuity measures spatial connectivity of fuels (from canopy cover analysis).
Weather Index: Integrates Keetch-Byram Drought Index (KBDI) and instantaneous fire weather:
where KBDI ranges 0–800 (cumulative moisture deficit), T is temperature (°F), RH is relative humidity (%), and W is wind speed (mph). KBDI is computed daily as:
where Δt is time increment (days) and P is precipitation (inches).
Ecological Stress Index: Captures forest health degradation:
where NDVInorm is normalized difference vegetation index relative to historical baseline (1 = healthy), ΔTcanopy is canopy temperature anomaly vs. ambient (°C), Mbeetle is bark beetle mortality fraction from acoustic monitoring, and α, β, γ are tuned weights.
An FFDI above 0.7 triggers HighFireDanger, above 0.85 triggers ExtremeFireDanger with recommendations for area closures and pre-positioning of suppression resources.
The ForestZone class demonstrates multi-scale fusion from satellite imagery to ground sensors:
from spaxiom import Sensor, Intent, Fusion, Metric
import math
class ForestZone:
def __init__(self, zone_id, coords, elevation_m):
self.zone_id = zone_id
self.coords = coords # (lat, lon) for zone centroid
self.elevation_m = elevation_m
# Sensor streams
self.weather = Sensor("weather_station") # T, RH, wind, precip
self.soil_moisture = Sensor("soil_moisture_probe")
self.multispectral = Sensor("satellite_multispectral") # NDVI, thermal
self.smoke_detector = Sensor("smoke_particulate")
self.acoustic = Sensor("acoustic_array") # tree stress, beetle activity
self.lightning = Sensor("lightning_network")
# INTENT events
self.dry_fuel = Intent("DryFuelAccumulation")
self.veg_stress = Intent("VegetationStress")
self.beetle_infestation = Intent("BarkBeetleInfestation")
self.ignition_risk = Intent("IgnitionRisk")
self.fire_detection = Intent("FireDetection")
# Fusion metrics
self.ffdi = Metric("forest_fire_danger_index", range=(0, 1))
self.kbdi = Metric("keetch_byram_drought_index", range=(0, 800))
# State variables
self.kbdi_value = 0.0 # Updated daily
self.fuel_load_tons_per_acre = 12.0 # From field survey or LiDAR
self.canopy_cover_fraction = 0.65 # From remote sensing
self.beetle_mortality_fraction = 0.0
self.lightning_strikes_24h = 0
self.days_since_rain = 0
@Fusion.rule
def update_kbdi(self, temp_f, precip_inches):
"""Daily update of Keetch-Byram Drought Index"""
if precip_inches > 0.1:
self.kbdi_value = max(0, self.kbdi_value - precip_inches * 100)
self.days_since_rain = 0
else:
self.days_since_rain += 1
# KBDI accumulation formula
if self.kbdi_value < 800:
factor = (800 - self.kbdi_value) * (0.968 * math.exp(0.0875 * temp_f + 1.5552) - 8.3)
self.kbdi_value = min(800, self.kbdi_value + factor / 1000)
self.kbdi.update(self.kbdi_value)
@Fusion.rule
def calculate_ffdi(self):
"""Compute Forest Fire Danger Index from all components"""
# Get latest sensor readings
wx = self.weather.latest()
temp_f = wx["temperature_f"]
rh_pct = wx["relative_humidity"]
wind_mph = wx["wind_speed"]
soil = self.soil_moisture.latest()
fuel_moisture_pct = self._estimate_1000hr_fuel_moisture(soil["moisture_pct"])
ms = self.multispectral.latest()
ndvi = ms["ndvi"]
canopy_temp_c = ms["thermal_c"]
ambient_temp_c = (temp_f - 32) * 5/9
canopy_delta = canopy_temp_c - ambient_temp_c
# Fuel Index
f_moisture = max(0, 1 - fuel_moisture_pct / 30.0) # <15% is critical
f_loading = min(1.0, self.fuel_load_tons_per_acre / 20.0)
f_continuity = self.canopy_cover_fraction
I_fuel = f_moisture * f_loading * f_continuity
# Weather Index (normalized components)
kbdi_norm = self.kbdi_value / 800.0
temp_norm = max(0, min(1, (temp_f - 70) / 50.0))
rh_norm = (100 - rh_pct) / 100.0
wind_norm = min(wind_mph, 30) / 30.0
I_weather = 0.4 * kbdi_norm + 0.3 * temp_norm + 0.2 * rh_norm + 0.1 * wind_norm
# Ecological Stress Index
ndvi_baseline = 0.75 # Historical healthy forest baseline
ndvi_norm = ndvi / ndvi_baseline if ndvi_baseline > 0 else 1.0
ndvi_stress = max(0, 1 - ndvi_norm)
alpha, beta, gamma = 0.5, 0.3, 0.2
I_ecological = alpha * ndvi_stress + \
beta * min(1.0, canopy_delta / 10.0) + \
gamma * self.beetle_mortality_fraction
# Weighted combination
w_F, w_W, w_E = 0.4, 0.4, 0.2
ffdi = w_F * I_fuel + w_W * I_weather + w_E * I_ecological
ffdi = max(0, min(1, ffdi)) # Clamp to [0,1]
self.ffdi.update(ffdi)
# Emit alerts based on thresholds
if ffdi >= 0.85:
Intent.emit("ExtremeFireDanger", zone_id=self.zone_id, ffdi=ffdi,
action="CLOSE_AREA_PREPOSITION_RESOURCES")
elif ffdi >= 0.7:
Intent.emit("HighFireDanger", zone_id=self.zone_id, ffdi=ffdi,
action="HEIGHTENED_VIGILANCE")
# Check for dry fuel accumulation
if fuel_moisture_pct < 15 and self.days_since_rain > 14:
self.dry_fuel.emit(zone_id=self.zone_id,
fuel_moisture_pct=fuel_moisture_pct,
days_since_rain=self.days_since_rain,
fuel_load_tons_per_acre=self.fuel_load_tons_per_acre)
return ffdi
@Sensor.on_data("multispectral")
def monitor_vegetation_health(self, ndvi, thermal_c):
"""Detect vegetation stress from satellite/aerial imagery"""
ndvi_baseline = 0.75
ndvi_anomaly = ndvi_baseline - ndvi
wx = self.weather.latest()
ambient_temp_c = (wx["temperature_f"] - 32) * 5/9
canopy_delta = thermal_c - ambient_temp_c
# Significant stress if NDVI drops >20% and canopy is hot
if ndvi_anomaly > 0.15 and canopy_delta > 5.0:
self.veg_stress.emit(
zone_id=self.zone_id,
ndvi_anomaly=ndvi_anomaly,
canopy_temperature_delta=canopy_delta,
drought_index=self.kbdi_value
)
self.calculate_ffdi()
@Sensor.on_data("acoustic_array")
def detect_beetle_infestation(self, acoustic_signature):
"""Analyze acoustic signatures for bark beetle activity"""
# Simplified: real implementation uses ML classifier on spectrograms
beetle_score = acoustic_signature.get("beetle_probability", 0.0)
if beetle_score > 0.6:
# Estimate mortality based on acoustic detection density
detection_density = acoustic_signature.get("detections_per_hectare", 0)
estimated_mortality = min(0.5, detection_density / 100.0)
self.beetle_mortality_fraction = estimated_mortality
self.beetle_infestation.emit(
zone_id=self.zone_id,
acoustic_signature=beetle_score,
tree_count_estimate=detection_density * 10, # rough conversion
mortality_rate=estimated_mortality
)
self.calculate_ffdi()
@Sensor.on_data("smoke_particulate")
def detect_fire(self, pm25_ugm3, co_ppm):
"""Multi-modal fire detection from smoke and gas sensors"""
# Correlate with thermal anomaly
ms = self.multispectral.latest()
thermal_c = ms.get("thermal_c", 0)
# Fire signature: high PM2.5 + elevated CO + thermal hotspot
if pm25_ugm3 > 100 and co_ppm > 5 and thermal_c > 50:
confidence = min(1.0, (pm25_ugm3 / 500) * (co_ppm / 20) * (thermal_c / 100))
self.fire_detection.emit(
location=self.coords,
confidence=confidence,
size_estimate_acres=0.1, # Initial detection, refine with progression
rate_of_spread_mph=0.0 # Not yet determined
)
def _estimate_1000hr_fuel_moisture(self, soil_moisture_pct):
"""Convert soil moisture to 1000-hour fuel moisture estimate"""
# Simplified empirical relationship
# Real implementation uses Nelson (2000) model with VPD, temp, precip history
return 10 + 0.8 * soil_moisture_pct
# Example instantiation for Sierra Nevada mixed-conifer zone
sierras_zone = ForestZone(
zone_id="CA_SIER_Z42",
coords=(38.5, -120.2),
elevation_m=1800
)
Figure A.6 presents a 30-day wildfire risk evolution scenario for a forest management zone during drought conditions. The visualization integrates four critical monitoring streams: drought severity via KBDI accumulation, vegetation health decline tracked through NDVI anomaly, real-time fuel moisture content, and the derived Forest Fire Danger Index (FFDI). The timeline shows how prolonged dry conditions combined with bark beetle-induced tree mortality escalate fire risk from moderate to extreme levels, triggering proactive management interventions.
Note: This visualization contains a complex multi-panel wildfire risk chart. Please view the full technical paper for the complete SVG diagram showing KBDI accumulation, NDVI decline, fuel moisture trends, and the composite FFDI over a 30-day drought period.
Figure A.6: Integrated wildfire risk monitoring for a Sierra Nevada mixed-conifer forest zone over a 30-day drought period. Panel 1: Keetch-Byram Drought Index (KBDI) accumulates from ~100 to 750+ over the dry spell, with brief recovery following a 0.8" rain event on Day 18. Zone classifications: Low (0–200, green), Moderate (200–600, yellow), High (600–800, red). Panel 2: NDVI (Normalized Difference Vegetation Index) declines from healthy baseline (0.75) to severely stressed levels (<0.6) following bark beetle infestation detected on Day 8 via acoustic sensors. Dead standing timber increases ladder fuel connectivity. Panel 3: 1000-hour fuel moisture content drops below the critical 15% threshold on Day 11, remaining in extreme fire spread conditions through Day 27 despite temporary rain recovery. Panel 4: Composite Forest Fire Danger Index (FFDI) integrates all factors, escalating from moderate (0.5) to extreme (0.88) by Day 25. At FFDI >0.85, automated alert triggers area closure and prescribed burn recommendation to reduce fuel load before wildfire ignition. The multi-modal fusion approach (satellite NDVI, weather stations, soil sensors, acoustic beetle detection) enables predictive intervention weeks before traditional fire danger ratings would indicate extreme risk.
Forest management agencies using Spaxiom-based wildfire monitoring have demonstrated:
The FFDI metric provides a standardized, physics-grounded risk indicator that integrates operational fire weather (KBDI, wind, humidity) with ecological state (vegetation stress, fuel loading, pest damage). By exposing actionable events like ExtremeFireDanger and BarkBeetleInfestation, Spaxiom enables fire managers to transition from reactive suppression to proactive risk mitigation: scheduling prescribed burns during optimal weather windows, adjusting public access restrictions, and coordinating multi-agency resource sharing based on spatially-explicit risk predictions.