Wildfire detection and risk assessment integrating NASA FIRMS satellite thermal anomalies (VIIRS/MODIS), NOAA fire weather indices, EPA AirNow air quality data, and PurpleAir real-time PM2.5 sensors
This was mostly a "vibe-coding" excercise to try out Claude Code integration with Zed, and it worked remarkably well. The local LLM, qwen2.5:145b is adequate--expect confusion if it tries to invoke too many tools in mcp_server at once.
this-is-fine is a comprehensive wildfire monitoring system that combines multiple real-time data sources to assess and visualize fire risk across the continental United States. The system features an innovative natural language interface powered by local LLMs, allowing users to query fire data conversationally without writing code.
- 🛰️ Real-time Fire Detection - NASA FIRMS satellite data (VIIRS/MODIS) with ~3 hour latency
- 🌤️ Weather Integration - NOAA National Weather Service API for enhanced risk scoring
- 💨 Air Quality Monitoring - EPA AirNow and PurpleAir sensor networks for smoke/PM2.5 tracking
- 🤖 Natural Language Interface - Chat with your fire data using local LLMs (Qwen2.5, Llama3.2)
- 🏭 Industrial Filtering - ML-based temporal persistence analysis to filter out refineries, steel plants, etc.
- 🗺️ Interactive Visualizations - Plotly maps, Kepler.gl integration, and real-time dashboards
- ⚡ Fast & Local - DuckDB spatial database, no cloud dependencies, runs entirely on your machine
- macOS, Linux, or Windows (WSL2)
- Python 3.12+ (managed by
uv) - 16GB+ RAM (24GB recommended for LLM features)
- NASA FIRMS API key (get one free)
# Clone the repository
git clone https://github.com/yourusername/this-is-fine.git
cd this-is-fine
# Install uv (if not already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh
# Sync dependencies
uv sync
# Set up environment variables
cp .env.example .env
# Edit .env and add your FIRMS_API_KEY# Fetch fires for California from the last 2 days
uv run python -c "from flows.etl_flow import wildfire_etl_flow; wildfire_etl_flow()"This will:
- Fetch active fire detections from NASA FIRMS
- Filter out industrial heat sources
- Calculate risk scores with weather data
- Create 5km buffer zones
- Export to
data/processed/active_fires.geojson
# Install Ollama (for local LLM)
brew install ollama # macOS
# or visit https://ollama.ai for other platforms
# Pull a language model
ollama pull qwen2.5:14b
# Start the web interface
uv run python web/gradio_app.pyOpen http://localhost:7860 and try:
- "Fetch fires in Oregon and add weather data"
- "Show me air quality information for the fires"
- "Create a risk heatmap"
┌────────────────────────────────────────────────────────────┐
│ User Interfaces │
├─────────────────┬───────────────────┬──────────────────────┤
│ Gradio Web UI │ MCP Server API │ Plotly Notebooks │
│ (LLM Chat) │ (Tool Protocol) │ (Visualization) │
└────────┬────────┴─────────┬─────────┴───────────┬──────────┘
│ │ │
▼ ▼ ▼
┌────────────────────────────────────────────────────────────┐
│ Prefect ETL Pipeline │
├──────────────┬──────────────┬──────────────┬───────────────┤
│ Fetch Fires │ Enrich │ Calculate │ Generate │
│ (NASA FIRMS) │ (NOAA/AQI) │ Risk Scores │ Buffers │
└──────┬───────┴──────┬───────┴──────┬───────┴───────┬───────┘
│ │ │ │
▼ ▼ ▼ ▼
┌────────────────────────────────────────────────────────────┐
│ Data Layer │
├─────────────────┬────────────────────┬─────────────────────┤
│ DuckDB │ GeoJSON Files │ Plotly HTML Maps │
│ (Spatial DB) │ (Kepler.gl) │ (Dashboards) │
└─────────────────┴────────────────────┴─────────────────────┘
Data Ingestion:
- NASA FIRMS API - Active fire detections from VIIRS/MODIS satellites
- NOAA NWS API - Real-time weather, fire danger indices
- EPA AirNow API - Air Quality Index (AQI) data
- PurpleAir API - Community PM2.5 sensor network
Processing & Storage:
- Prefect - ETL orchestration with caching (3-hour expiration)
- DuckDB - Spatial database with PostGIS-like capabilities
- GeoPandas/Shapely - Geospatial data manipulation
- NumPy/Pandas - Risk calculation and analysis
LLM & Interface:
- Gradio - Web UI framework
- Ollama - Local LLM runtime (Qwen2.5:14b, Llama3.2)
- MCP (Model Context Protocol) - Standardized tool interface
Visualization:
- Plotly - Interactive web maps with MapLibre
- Kepler.gl - Advanced geospatial visualization
- Jupyter - Exploratory data analysis
The system uses a weighted risk scoring model that adapts based on available data:
- 30% Brightness Temperature (fire intensity)
- 20% Detection Confidence
- 30% Fire Radiative Power (FRP)
- 20% Day/Night Flag
- 20% Brightness Temperature
- 15% Detection Confidence
- 20% Fire Radiative Power
- 10% Day/Night Flag
- 15% Relative Humidity (inverted: low = high risk)
- 10% Wind Speed (high wind = high risk)
- 5% Precipitation Probability (inverted)
- 5% NOAA Fire Danger Index
Risk Categories:
- 🟡 Low (0-30): Minimal threat, monitor
- 🟠 Moderate (30-60): Elevated risk, prepare
- 🔴 High (60-100): Critical risk, evacuate
One of the unique features is intelligent filtering of false positives from industrial sources using temporal persistence analysis:
# Identifies facilities with 2+ detections over 30 days
# Examples: steel plants, refineries, gas flares, cement kilns
┌───────────────────────────────────────────────────────────┐
│ Before Filtering: 1,423 fires detected │
│ After Filtering: 1,267 fires (156 industrial filtered) │
│ Accuracy: ~11% false positive reduction │
└───────────────────────────────────────────────────────────┘The system maintains a database of ~69 known persistent industrial heat sources across the US, validated using satellite imagery.
# Open the Plotly visualization notebook
uv run jupyter notebook notebooks/plotly_visualization.ipynbAvailable visualizations:
- Basic fire points (colored by risk)
- Risk heatmap (density-weighted)
- AQI heatmap (air quality overlay)
- PurpleAir PM2.5 heatmap (smoke density)
- Fire buffer zones (risk containment areas)
# Export data for Kepler.gl
# Data is automatically exported to data/processed/
# 1. Go to https://kepler.gl/demo
# 2. Upload active_fires.geojson and fire_buffers.geojson
# 3. Configure layers using docs/kepler_visualization_guide.mdThe system includes a Gradio-based web interface with local LLM integration:
Example Conversations:
User: "Fetch fires in California and add weather data"
Assistant: [Executes fetch_fires tool]
"Found 150 fires in California (23 industrial sources filtered).
I'll now enrich them with weather data..."
[Executes enrich_weather tool]
"Added weather data to 142/150 fires. Most areas show low
humidity (18-25%) and high winds (30-40 km/h), significantly
increasing fire risk."
User: "Show me which fires have dangerous air quality"
Assistant: [Executes enrich_aqi tool]
"Enriched 47/150 fires with AQI data. 12 fires have AQI > 150
(Unhealthy), primarily in the Central Valley region."
Supported Commands:
- Data fetching by region or bounding box
- Weather enrichment (NOAA)
- Air quality enrichment (AirNow, PurpleAir)
- Visualization generation
- Statistical summaries
this-is-fine/
├── src/
│ ├── ingestion/ # API clients (FIRMS, NOAA, AirNow, PurpleAir)
│ ├── analysis/ # Risk calculation, spatial operations
│ ├── database/ # DuckDB initialization and queries
│ ├── filters/ # Industrial heat source filtering
│ └── commands/ # CLI and MCP command implementations
├── flows/
│ └── etl_flow.py # Prefect orchestration pipeline
├── mcp_server/
│ ├── server.py # MCP protocol implementation
│ └── tools.py # Tool definitions (6 tools)
├── web/
│ └── gradio_app.py # LLM-powered web interface
├── notebooks/
│ └── plotly_visualization.ipynb # Interactive analysis
├── data/
│ ├── static/ # Persistent industrial heat sources
│ ├── processed/ # GeoJSON outputs, visualizations
│ └── wildfire.duckdb # Spatial database
└── docs/ # Comprehensive documentation
Comprehensive documentation available in docs/:
Getting Started:
- Quick Start Guide - 5-minute setup for web interface
- Gradio Web Interface Guide - Full LLM interface documentation
Technical Reference:
- GIS Spatial Operations - GeoPandas/Shapely → ArcGIS mapping for GIS professionals
- Industrial Filtering - How false positives are removed
- NOAA Integration - Weather enrichment details
- MCP Tool Logging - Understanding tool execution logs
Data & Visualization:
- Kepler.gl Guide - Professional geospatial visualization
- Bounding Boxes Reference - US state/region coordinates
- Data Directory Structure - File organization
- FIRMS Overview - Understanding satellite fire detection
Emergency Management:
- Real-time fire tracking with 3-hour latency
- Risk-based prioritization for resource allocation
- Air quality monitoring for evacuation planning
Research & Analysis:
- Historical fire pattern analysis
- Weather correlation studies
- Industrial heat source mapping
Public Information:
- Community fire awareness
- Smoke exposure tracking
- Evacuation zone visualization
from flows.etl_flow import wildfire_etl_flow
# Fetch fires for a custom region
wildfire_etl_flow(
bbox=(-124.5, 32.5, -114.0, 42.0), # California
days_back=2,
buffer_km=10, # 10km risk zones
use_weather=True,
use_aqi=True,
filter_industrial=True
)# Start the MCP server for external integrations
uv run python mcp_server/server.pyThe MCP server provides 6 tools:
fetch_fires- Get fire data by region/bboxenrich_weather- Add NOAA weather dataenrich_aqi- Add EPA air quality dataenrich_purpleair- Add PurpleAir sensor datavisualize_fires- Generate interactive mapsget_fire_stats- Summary statistics
# Launch Jupyter for exploratory analysis
uv run jupyter notebook notebooks/plotly_visualization.ipynbCurrent Features (v1.0):
- ✅ NASA FIRMS integration
- ✅ NOAA weather enrichment
- ✅ Industrial filtering
- ✅ Local LLM interface
- ✅ Plotly/Kepler.gl visualizations
Future Enhancements (v2.0?):
- Retro-cool interface using Typer and MapSCII?
- 7-day fire spread prediction (weather forecasts)
- Mobile-responsive dashboard
- Email/SMS alerting for specified region
- Vegetation/fuel moisture modeling
Contributions are welcome! Areas of interest:
- Additional data sources (weather models, vegetation indices)
- Improved risk calculation models
- Alternative LLM integrations
- Performance optimizations for large datasets
- Documentation improvements
This project is licensed under the MIT License - see the LICENSE file for details.
Data Sources:
- NASA FIRMS - Fire detection data
- NOAA National Weather Service - Weather and fire indices
- EPA AirNow - Air quality data
- PurpleAir - Community air quality sensors
Technologies:
- Prefect - Workflow orchestration
- DuckDB - Embedded database
- Gradio - Web interface framework
- Ollama - Local LLM runtime
- Kepler.gl - Geospatial visualization
Project Maintainer: [Bryan Hughes]
- GitHub: @rbhughes
- Email: bryan@purr.io

