Getting ELMFIRE running

Written by

I’m familiarizing myself with various fire modeling programs, and open-source programs like ELMFIRE are great to get started with. I am working towards a transmission line exposure project, and I want to use model outputs for burn probability that I myself have run. What better way than to jump right in to a program and learn along the way?

In the past two weeks I have been through a lot with ELMFIRE. First of all I am running Windows 11 so I have to use WSL. ELMFIRE includes a Dockerfile, so I’m also using Docker Desktop. Once I got the environment set up, I ran through the included tutorials to check that things were working well. When most of the tutorials were executing correctly, I wanted to move on to my own data.

Pre-processing

I had chosen a field area in east-central Arizona that has burnable forests, and also high-voltage transmission lines running through the forests (since I want to do exposure analysis as an end-product). I downloaded a landscape file from the LANDFIRE database. This comes as one multi-band GeoTIFF, but ELMFIRE wants each input TIFF file separately. So I had to get into Python and separate the raster into 8 files.

This was actually great because I got to learn/practice various bits of Python. Part of that is using Rasterio. Below is the function for splitting a LANDFIRE raster into 8 separate rasters.

def split_multiband_raster(input_file, output_folder, band_map):
"""
Split a multiband raster into individual GeoTIFFs.
Parameters
----------
input_file : Path or str
Input multiband raster.
output_folder : Path
Folder where the individual rasters will be written.
band_map : dict
Dictionary mapping
band_number : output_filename
Example
{
1: "dem",
2: "slp",
...
}
"""
output_folder.mkdir(exist_ok=True)
with rasterio.open(input_file) as src:
profile = src.profile.copy()
profile.update(count=1)
for band, name in band_map.items():
data = src.read(band)
outfile = output_folder / f"{name}.tif"
with rasterio.open(outfile, "w", **profile) as dst:
dst.write(data, 1)
dst.descriptions = (src.descriptions[band - 1],)
print(f"Created {outfile}")

Before running the above function, I needed to make sure my GeoTIFF was in the coordinate system I wanted for analysis. I decided on UTM zone 12 for Arizona, which corresponds with EPSG 32612 (ELMFIRE can accept the EPSG code for coordinate reference system). Here is my code for re-projecting to UTM zone 12:

TARGET_CRS = "EPSG:32612"
TARGET_RESOLUTION = 60.0 # meters
from rasterio.warp import calculate_default_transform
from rasterio.warp import reproject
from rasterio.warp import Resampling
def reproject_raster(input_file, output_file, target_crs, resampling=Resampling.nearest):
with rasterio.open(input_file) as src:
transform, width, height = calculate_default_transform(
src.crs,
target_crs,
src.width,
src.height,
*src.bounds,
resolution=TARGET_RESOLUTION
)
profile = src.profile.copy()
profile.update(
crs=target_crs,
transform=transform,
width=width,
height=height,
compress="lzw"
)
with rasterio.open(output_file, "w", **profile) as dst:
dst.descriptions = src.descriptions
for band in range(1, src.count + 1):
reproject(
source=rasterio.band(src, band),
destination=rasterio.band(dst, band),
src_transform=src.transform,
src_crs=src.crs,
dst_transform=transform,
dst_crs=target_crs,
resampling=resampling
)
print(f"Created {output_file}")

Trying Things

I thought I would jump in and try a Monte Carlo simulation (because I’m naive). It totally didn’t work, and I spent a lot of time learning why. First of all, always start with something that works. When I went back to the beginning to work up to getting a working fire in ELMFIRE again, I started with the tutorial files that I knew worked. I ran them again to be sure they worked. And then I only changed one thing at a time. I have been told do work this way, but of course I made the mistake for myself. But I finally did get a fire to burn on my downloaded landscape by going back and changing one thing at a time. More on that next time.

Leave a comment