MTG FRP Fire Progression Analyzer with Intensity Estimation
December 15, 2025 ยท View on GitHub
A Python script for creating hourly and cumulative fire progression polygons from MTG (Meteosat Third Generation) FRP (Fire Radiative Power) data, with calibration against reference burned areas and fire intensity estimation.
https://github.com/user-attachments/assets/198a031a-720d-4a23-9ee9-2cea6e173c95
- Fire Intensity based on Radiative Method: I_rad = FRP / (L ร X_r)
- Fire Intensity based on Traditional Method: I_trad = H ร w ร v
๐ Description
This script processes MTFRPPixel fire detection data to create temporal progression polygons of wildfires. It supports both cumulative and hourly progression modes, with advanced filtering, calibration capabilities, and now includes fire intensity estimation using radiative fraction approach.
โจ Features
- Dual Processing Modes: Cumulative progression and hourly progression for analysis and animations
- Non-Overlapping Progression: Option for print layouts showing only new burned areas each hour
- Advanced Filtering: FRP thresholding, spatial density filtering (DBSCAN), cluster size filtering and minimum area filtering
- Flexible Hull Generation: Concave hull with fallback to convex hull
- Calibration System: Automatic parameter calibration using reference burned areas
- Temporal Continuity: Fill missing hours to maintain temporal (hourly) progression
- Area Correction: Negative buffer (shrink) to mitigate area overestimation
- Multiple Outputs: Cumulative and hourly polygons, daily summaries, calibrated versions and non-overlapping progression
- NEW: Byram Fire Intensity Calculation: Two methods (radiative and traditional) with validation
- NEW: Propagation Speed Analysis: 90th percentile distance for robust speed estimation
- NEW: Fire Front Length Estimation: MTG-resolution corrected length calculation
- NEW: Radiative Efficiency: Cross-validation between intensity methods
๐ ๏ธ Installation
Prerequisites
# Install Python dependencies (shapely 2.x)
pip install pandas geopandas shapely scikit-learn numpy
Download Script
git clone https://github.com/PedroVenancio/mtg-frp-fire-progression.git
cd mtg-fire-progression
๐ Usage
Basic Examples
Process fire progression with default parameters:
python mtg_frp_fire_progression.py --input fire_data.gpkg --output_prefix frp_fires
Process with calibration using reference burned areas:
python mtg_frp_fire_progression.py --input fire_data.gpkg --output_prefix calibrated_frp_fires --reference_areas reference_burned_areas.gpkg
Process only cumulative progression:
python mtg_frp_fire_progression.py --input fire_data.gpkg --output_prefix cumulative_only --no_hourly
Process without non-overlapping progression:
python mtg_frp_fire_progression.py --input fire_data.gpkg --output_prefix no_overlap --no_non_overlapping
Adaptive FRP filtering (keep only top 85% of FRP values):
python mtg_frp_fire_progression.py --input fire_data.gpkg --frp_threshold_method adaptive --frp_quantile_threshold 0.15
Fixed FRP threshold (keep only FRP โฅ 20 MW):
python mtg_frp_fire_progression.py --input fire_data.gpkg --frp_threshold_method fixed --min_frp 20
Custom FRP filtering and clustering:
python mtg_frp_fire_progression.py --input fire_data.gpkg --output_prefix custom --frp_threshold_method fixed --min_frp 15 --min_cluster_size 5 --density_eps 500
Advanced Examples with Intensity Calculation
Calculate Byram fire intensity with default parameters:
python mtg_frp_fire_progression.py --input fire_data.gpkg --output_prefix fire_intensity --calculate_intensity
Calculate intensity with custom radiative fraction (0.17), mtg_correction (0.65) and fuel type (forest):
python mtg_frp_fire_progression.py --input fire_data.gpkg --output_prefix custom_intensity \
--calculate_intensity \
--radiative_fraction 0.17 \
--fuel_type forest \
--mtg_correction 0.65
Custom minimum area non-overlapping (1 ha) with intensity calculation:
python mtg_frp_fire_progression.py --input fire_data.gpkg --output_prefix intensity_print \
--min_area_non_overlapping 1.0 \
--calculate_intensity \
--radiative_fraction 0.16
Complete workflow with calibration and intensity calculation:
python mtg_frp_fire_progression.py --input fire_data.gpkg --output_prefix complete_analysis \
--reference_areas reference_burned_areas.gpkg \
--min_area_non_overlapping 0.5 \
--calculate_intensity \
--radiative_fraction 0.15 \
--heat_value 18000 \
--fuel_type shrub
Advanced Examples
Fine-tune hull generation and area correction:
python mtg_frp_fire_progression.py --input fire_data.gpkg --output_prefix tuned \
--ratio 0.05 \
--buffer_distance 100 \
--shrink_distance 40 \
--frp_threshold_method adaptive \
--frp_quantile_threshold 0.2
Complete workflow with calibration and custom non-overlapping area:
python mtg_frp_fire_progression.py --input fire_data.gpkg --output_prefix complete \
--reference_areas reference_burned_areas.gpkg \
--min_area_non_overlapping 1.0 \
--buffer_distance 80 \
--shrink_distance 30
Skip calibration even with reference data:
python mtg_frp_fire_progression.py --input fire_data.gpkg --output_prefix no_calib \
--reference_areas reference.gpkg \
--skip_calibration
Process with start hour instead of end hour:
python mtg_frp_fire_progression.py --input fire_data.gpkg --output_prefix start_hour --use_start_hour
Disable missing hour filling:
python mtg_frp_fire_progression.py --input fire_data.gpkg --output_prefix no_fill --no_fill_missing
๐ Parameters
Required Parameters
--input: Input FRP data file (GeoPackage). Expects a GeoPackage generated by MTG/MTFRPPixel Data Processor--output_prefix: Prefix for all output files
Core Processing Parameters
--fire_id_column: Column identifying each fire (default: 'fire_id')--buffer_distance: Buffer distance in meters (default: 80)--ratio: Concave hull ratio parameter 0-1 (default: 0.08)--min_cluster_size: Minimum cluster size for polygons (default: 3)--density_eps: DBSCAN epsilon distance in meters (default: 300)--shrink_distance: Negative buffer distance in meters (default: 30)
FRP Filtering Parameters:
--frp_threshold_method: FRP threshold method: 'fixed' or 'adaptive' (default: adaptive)--min_frp: Minimum FRP value for filtering (default: 10)--frp_quantile_threshold: Quantile for adaptive FRP threshold (default: 0.15)
FRP filtering uses mutually exclusive parameters depending on the method:
- When using
--frp_threshold_method adaptive(default):- Uses only
--frp_quantile_threshold(default: 0.15 = 15th percentile) - Ignores
--min_frpcompletely - Example:
--frp_threshold_method adaptive --frp_quantile_threshold 0.2(keep top 80% of FRP values)
- Uses only
- When using
--frp_threshold_method fixed:- Uses only
--min_frp(default: 10.0 MW) - Ignores
--frp_quantile_thresholdcompletely - Example:
--frp_threshold_method fixed --min_frp 15(keep FRP โฅ 15 MW)
- Uses only
Non-Overlapping Progression Parameters
--no_non_overlapping: Disable non-overlapping progression (enabled by default)--min_area_non_overlapping: Minimum area in hectares for non-overlapping polygons (default: 0.5)
Byram Intensity Parameters (NEW)
--calculate_intensity: Calculate Byram fire intensity (propagation speed and FRP in new area)--radiative_fraction: Radiative fraction for Byram intensity calculation. Xr = 0.15-0.20 for wildfires (based on Wooster et al., 2005; Johnston et al., 2017) (default: 0.15)--heat_value: Heat content in kJ/kg for traditional Byram intensity calculation (default: 20000, average for portuguese fuel models (Fernandes et al.). Typical range 15000-21000 kJ/kg)--fuel_consumption: Fixed fuel consumption in kg/mยฒ. If None, uses speed-adjusted values (default: None)--fuel_type: Fuel type for continuous consumption model: 'grass', 'shrub', or 'forest' (default: shrub)--mtg_correction: Correction factor for MTG 1km resolution artifacts. Typical values: 0.6-0.7. Lower values reduce L more aggressively (default: 0.6)
Processing Flags
--no_cumulative: Disable cumulative progression--no_hourly: Disable hourly progression--no_fill_missing: Disable filling missing hours--no_density_filter: Disable density filtering--use_start_hour: Use start hour instead of end hour
Calibration Parameters
--reference_areas: Reference burned areas file for calibration--skip_calibration: Skip calibration even if reference areas provided
๐๏ธ Output Structure
Generated Files
{prefix}_cumulative_initial.gpkg- Initial cumulative progression{prefix}_hourly_initial.gpkg- Initial hourly progression{prefix}_cumulative_calibrated.gpkg- Calibrated cumulative progression (if calibration applied){prefix}_hourly_calibrated.gpkg- Calibrated hourly progression (if calibration applied){prefix}_daily_cumulative_initial.gpkg- Daily summary of cumulative progression{prefix}_daily_hourly_initial.gpkg- Daily summary of hourly progression{prefix}_daily_cumulative_calibrated.gpkg- Calibrated daily summary (if calibration applied){prefix}_daily_hourly_calibrated.gpkg- Calibrated daily summary (if calibration applied)
Non-Overlapping Progression Files
{prefix}_non_overlapping_hourly_initial.gpkg- Hourly non-overlapping progression (initial){prefix}_non_overlapping_hourly_calibrated.gpkg- Hourly non-overlapping progression (calibrated){prefix}_daily_non_overlapping_initial.gpkg- Daily non-overlapping summary (initial){prefix}_daily_non_overlapping_calibrated.gpkg- Daily non-overlapping summary (calibrated)
Byram Intensity Files (NEW)
{prefix}_byram_improved_initial.gpkg- Cumulative progression with fire behavior and Byram intensity columns (initial){prefix}_byram_improved_calibrated.gpkg- Cumulative progression with fire behavior and Byram intensity columns (calibrated){prefix}_fire_metrics_improved_initial.csv- Detailed fire metrics CSV (initial){prefix}_fire_metrics_improved_calibrated.csv- Detailed fire metrics CSV (calibrated){prefix}_propagation_vectors_90th_percentile.gpkg- Propagation points using 90th percentile distance{prefix}_propagation_vectors_max.gpkg- Propagation points using maximum distance{prefix}_non_overlapping_hourly_byram_improved_initial.gpkg- Non-overlapping progression with intensity (initial){prefix}_non_overlapping_hourly_byram_improved_calibrated.gpkg- Non-overlapping progression with intensity (calibrated)
Data Structure
Files contain:
fire_id: Fire identifierdatetime_hour: Hour in UTCdatetime_display: Display hour (end hour by default)geometry: Progression polygonarea_ha: Area in hectaresn_points_current_hour: Points in current hourn_points_cumulative: Cumulative points (cumulative version)frp_current_hour: FRP in current hourfrp_cumulative: Cumulative FRP (cumulative version)hull_type: Type of hull used ('concave', 'convex', etc.)data_status: Data origin ('original', 'filled')shrink_applied: Whether negative buffer was appliedshrink_distance_m: Shrink distance in meters
Non-Overlapping Specific Fields
area_ha_new: New area burned in this time step (hectares)area_ha_cumulative: Total cumulative area up to this time stepprogression_type: 'non_overlapping' or 'daily_non_overlapping'
NEW: Byram Intensity Fields
propagation_distance_m: 90th percentile propagation distance (meters) - robust metricpropagation_distance_max_m: Maximum propagation distance (meters) - absolute maximumpropagation_distance_reduction_pct: Reduction percentage (90th vs max) - data quality indicatorpropagation_speed_ms: Propagation speed (rate of spread) (m/s)propagation_speed_kmh: Propagation speed (rate of spread) (km/h)fire_front_length_m: Fire front length with MTG correction (meters)frp_new_area_mw: FRP in new burned area only (MW)n_points_new_area: Number of FRP points in new areaheat_value_kj_kg: Heat content used in calculation (from --heat_value parameter)byram_radiative_intensity_kw_m: Radiative Byram intensity (kW/m) - I = FRP/(LรXr)byram_traditional_intensity_kw_m: Traditional Byram intensity (kW/m) - I = Hรwรvradiative_efficiency: Ratio radiative/traditional intensity (validation metric)implied_radiative_fraction: Implied Xr that would equalize both methodsintensity_class: Radiative intensity classificationtraditional_intensity_class: Traditional intensity classificationadjusted_fuel_consumption_kg_m2: Speed-adjusted fuel consumption
๐ง Processing Details
Algorithm Overview
-
Data Filtering:
- FRP thresholding (fixed or adaptive)
- Spatial density filtering (DBSCAN)
- Cluster size filtering
-
Temporal Processing:
- UTC timezone enforcement
- Hourly binning
- Missing hour filling (optional)
-
Polygon Generation:
- Concave hull with progressive ratio
- Convex hull fallback
- Positive buffer for smoothing
- Negative buffer for area correction
-
Propagation Analysis (NEW):
- Calculate 90th percentile propagation distance (robust)
- Estimate fire front length with MTG correction
- Calculate propagation speed (rate of spread) (m/s and km/h)
- Generate propagation vectors for visualization
-
Intensity Calculation (NEW):
- Radiative Method: I_rad = FRP / (L ร X_r)
- Traditional Method: I_trad = H ร w ร v
- Cross-validation through radiative efficiency
- Intensity classification (Low to Extreme)
-
Non-Overlapping Progression:
- Calculate geometric difference between consecutive time steps
- Show only new burned areas for each hour
- Apply minimum area filter (default: 0.5 ha)
- Create daily summaries of new burned areas
-
Calibration:
- Compare with reference burned areas
- Calculate overestimation ratios
- Suggest optimal shrink distance
Byram Intensity Calculation Details
The intensity calculation system implements:
Radiative Method (based on Wooster et al., 2005; Johnston et al., 2017):
I_rad = FRP / (L ร X_r)
Where:
I_rad= Radiative Byram intensity (kW/m)FRP= Fire Radiative Power in new area (converted to kW)L= Fire front length (m) - MTG correctedX_r= Radiative fraction (default: 0.15, range: 0.15-0.20)
Traditional Method (Byram, 1959):
I_trad = H ร w ร v
Where:
I_trad= Traditional Byram intensity (kW/m)H= Heat content (20000 kJ/kg for Mediterranean fuels)w= Fuel consumption (kg/mยฒ) - speed-adjusted or fixedv= Propagation speed (m/s)
Key Innovations:
- 90th percentile distance: Uses 90th percentile instead of maximum for robust propagation
- MTG correction: Applies 0.6 factor to fire front length for 1km resolution artifacts
- Speed-adjusted fuel consumption: Fuel consumption varies with propagation speed
- Validation metrics: Radiative efficiency and implied X_r for cross-validation
Calibration Process
The calibration system:
- Matches fires between FRP data and reference areas
- Calculates overestimation percentages
- Suggests optimal
shrink_distanceparameter - Heuristic: 10 meters shrink per 10% overestimation
- Limits suggested shrink between 20-80 meters
Non-Overlapping Progression (ENABLED BY DEFAULT)
The non-overlapping progression is now enabled by default because it provides cleaner visualization for most use cases:
- Shows only the new area burned in each time step
- Ideal for print layouts and progression visualization
- Filters out small polygons (< 0.5 ha by default)
- Maintains temporal sequence without overlaps
- Provides cleaner visualization of fire spread patterns
To disable this feature, use: --no_non_overlapping
๐ก Usage Tips
For Best Results
Data Preparation:
- Get FRP data from MTG/MTFRPPixel Data Processor
- Ensure consistent fire_id between FRP and reference data
- Use projected CRS (meters) for accurate distance calculations
- Clean invalid geometries before processing
Parameter Tuning:
- Start with
ratio=0.08(for concave hull) and adjust based on point density - Use
adaptiveFRP threshold for datasets with varying fire intensities - Set
min_cluster_size=2for detecting small fires - Increase
density_epsfor more dispersed fire patterns - Use
min_area_non_overlapping=1.0for cleaner print layouts
Intensity Calculation:
- Use
--calculate_intensityfor fire behavior analysis - Adjust
--mtg_correctionbased on landscape complexity (0.5-0.7) - Monitor
propagation_distance_reduction_pctfor data quality - Use
--fuel_typeappropriate for your vegetation (grass, shrub or forest) - Validate with
radiative_efficiency(should be 0.1-0.3)
Memory Management:
- Process large datasets in batches by fire_id
- Use
--no_hourlyor--no_cumulativeto reduce output size - Monitor RAM usage with very large input files
QGIS Integration
-
Visualization:
- Style by
datetime_hourordatetime_displayfor temporal visualization and animation - Use graduated symbols for
area_ha,byram_radiative_intensity_kw_m,byram_traditional_intensity_kw_m - Filter by
data_statusto identify filled hours
- Style by
-
Animation:
- Use cumulative version with
datetime_hourordatetime_displayfor temporal animation using QGIS Temporal Controller Panel - Daily summaries provide cleaner animation frames for large time frames
- Use cumulative version with
-
Print Layouts:
- Use non-overlapping progression for clear progression maps
- Each time step shows only new burned area
- Perfect for static maps showing fire spread sequence
- Color by time steps for hourly / daily progression
- Color by intensity class for behavior analysis [Low (<500 kW/m); Moderate (500-2000 kW/m); 'High (2000-4000 kW/m)'; 'Very High (4000-10.000 kW/m)'; 'Extreme (>10.000 kW/m)']
-
Analysis:
- Hourly version for detailed temporal analysis
- Compare calibrated vs initial versions for accuracy assessment
- Intersect with reference data to get better statistics and make it closer to the reality
- Use intensity metrics for fire behavior studies
๐ Troubleshooting
Common Issues
No polygons created:
- Check FRP filtering thresholds
- Verify minimum cluster size
- Ensure valid fire_id values (not -1 or NaN)
Overestimation issues:
- Increase
shrink_distance - Use calibration with reference areas
- Adjust
ratioparameter for tighter hulls
Memory errors:
- Process fires individually
- Increase
min_cluster_sizeto reduce polygon count - Use
--no_fill_missingto reduce output size
Temporal gaps:
- Enable
fill_missing_hours(default) - Check input data temporal continuity
- Verify timezone handling
Too many small polygons in non-overlapping output:
- Increase
min_area_non_overlapping(try 1.0 or 2.0 ha) - Check if
shrink_distanceis appropriate - Verify FRP filtering thresholds
Intensity calculation issues:
- Check
propagation_distance_reduction_pct- values > 50% indicate data issues - Adjust
mtg_correctionif fire front lengths seem unrealistic - Verify if
radiative_efficiencyis in plausible range - Check if fuel type matches the burned vegetation
Performance Optimization
For large datasets:
# Process with stricter filtering
python mtg_frp_fire_progression.py --input large_data.gpkg --output_prefix optimized \
--min_cluster_size 5 \
--min_frp 20 \
--no_hourly
For high precision:
# Use tighter parameters and calibration
python mtg_frp_fire_progression.py --input precise_data.gpkg --output_prefix precise \
--ratio 0.05 \
--buffer_distance 50 \
--reference_areas high_quality_reference.gpkg
For print-ready progression maps:
# Generate clean non-overlapping progression
python mtg_frp_fire_progression.py --input fire_data.gpkg --output_prefix print_ready \
--min_area_non_overlapping 1.0 \
--buffer_distance 80 \
--shrink_distance 40
For detailed fire behavior analysis:
# Generate complete intensity analysis
python mtg_frp_fire_progression.py --input fire_data.gpkg --output_prefix behavior \
--reference_areas reference_burned_areas.gpkg \
--calculate_intensity \
--radiative_fraction 0.16 \
--fuel_type forest \
--mtg_correction 0.65 \
--heat_value 19000
๐ Complete Workflow Example
# 1. Process with calibration, non-overlapping, and intensity calculation
python mtg_frp_fire_progression.py --input mtg_frp_data.gpkg --output_prefix fire_analysis \
--reference_areas sentinel2_burned_areas.gpkg \
--calculate_intensity \
--radiative_fraction 0.15 \
--heat_value 18000 \
--fuel_type shrub \
--mtg_correction 0.6
# 2. Analyze results in QGIS
# Files: fire_analysis_*.gpkg and fire_analysis_*.csv
# 3. Analyze results in DBeaver / Calc
# Files: fire_analysis_*.gpkg and fire_analysis_*.csv
# Create graphs with hourly FRP and compare with fire weather indices and other metrics
# 4. Compare intensity methods in QGIS
# Open fire_analysis_non_overlapping_hourly_byram_improved_calibrated.gpkg
# Compare byram_radiative_intensity_kw_m vs byram_traditional_intensity_kw_m
# Check radiative_efficiency for validation
# Style by propagation_speed_kmh for rate of spread visualization
# 5. Create temporal animation in QGIS
# Use _cumulative_calibrated outputs with datetime_hour for animation
# 6. Create print layouts in QGIS
# Use non_overlapping_hourly_byram_improved_calibrated for hourly / daily progression and intensity maps
๐ Data Requirements
Input Data (MTG/MTFRPPixel Data Processor)
- FRP data with geometry and fire_id column
- Valid datetime information (acquisition_datetime or ACQTIME)
- FRP values for filtering
Reference Data (for calibration)
- Burned area polygons with matching fire_id
- Same spatial extent as FRP data
- Preferably from high-resolution sources (Sentinel-2, Landsat)
๐ License
This project is distributed under the MIT License. See LICENSE file for details.
๐ Support
For issues and questions:
- Check troubleshooting section
- Create GitHub issue
- Contact project maintainer
๐ References
Core Algorithms
Intensity Calculation
- Byram, G. M. (1959): Combustion of forest fuels. In: K. P. Davis (Editor), Forest fire control and use. McGraw-Hill, New York, pp. 61โ89.
- Johnston, J. M., Smith, A. M. S., & Wooster, M. J. (2017): Direct estimation of Byramโs fire intensity from infrared remote sensing imagery.
- Fernandes, P., Loureiro, C. (2021): Modelos de combustรญvel florestal para Portugal. Documento de referรชncia, versรฃo de 2021.
GIS Integration
Notes:
- This tool is designed to work with MTG FRP data, but can be adapted for other fire detection datasets with similar structure.
- Intensity calculation methods are based on literature but have several assumptions that need to be validated for different fire regimes.
Byram Intensity Parameterscan be used to fine tune the outputs, using field observations or better fire behaviour data. - Fire intensity values should be considered initial estimations to identify different stages of fires during their lifespan and to compare the fire behaviour of diferent wildfires.