Fire SCience

Smoke PM2.5 in GOOGLE EARTH EnGINE

Google Earth Engine (GEE) is a cloud-based platform for geospatial analysis and data access. Leveraging Google's cloud computing in my wildfire research at UCLA (and in post-graduation pro bono work) has been incredibly powerful and exciting, and I've also learned some Javascript along the way!

Here's the mapped output from a sample GEE script. It displays a 2020 fire season average of daily modelled surface-level smoke PM2.5 data from the National Oceanic and Atmospheric Administration (NOAA) for California. In GEE's code editor, this script also prints a chart of daily smoke PM2.5 over the fire season at a specified point for sensitivity analysis with air pollution data from a station at that location.  NOAA's surface smoke PM2.5 product was uniquely relevant for this project because 1) only surface-level air pollution is relevant for human exposures, and 2) this approach avoids filtering out PM2.5 from non-fire sources (i.e., pollution from industrial activities or the transportation sector).

If you have a Google Earth Engine account, you can view this script in GEE's code editor. 

Otherwise, you can view the source code as a text file.

EMISSIONS CHARTS IN PYTHON

Here's a chart comparing NOAA's smoke PM2.5 data (as pulled from GEE) to readings from 15 air quality stations. I made this chart as part of the sensitivity analysis mentioned above.  Station data is provided mainly from the EPA's PM2.5 Chemical Speciation Network.

Click the links below to see the code for this multigrid chart as a jupyter notebook (.ipynb) in Google Colab. If you haven't used Colab before, you can see this script as a converted python file instead.


P.S. NOAA has not yet made this dataset available as daily files, so I created these files from their hourly data (where available). If my daily dataset is relevant to your work, feel free to call it into your GEE scripts (it's set as a public asset).

ESRI PRINT MAPS

One of my research focuses with the Marlier Lab at UCLA involved the relationship between recent burns and the severity of subsequent fires. The lab focuses on this subject area to inform fire management (especially the application of prescribed burns) on the United State's West Coast. This project ultimately aims to inform policies which will reduce the public health impacts of wildfires, as the population health burden from exposure to wildfire smoke pollution will continue increasing with intensifying wildfire seasons. 

The two print maps included below summarize my analyses on 1) effects of recent burns on the severity of large 2018 wildfires, and 2) effects of previous prescribed burns on severity of 2018 wildfires.

This research was funded by UCLA's Environmental Health Sciences Department, UCLA's Graduate Student Research Program, the Hellman Foundation, and the Western Region Public Health Training Center.

ARCPY

The arcpy (python) script in this dropdown outputs a raster file containing the number of years since a previous burn for 2018 fires.

### Time between burns calculation

### Sierra Raby

### Marlier Lab at UCLA

### 9 May 2022


# GOAL: generate a raster containing the years since a previous 

# (up to 10 years prior) for burns which overlap 2018 fire burned areas in California.

# To start, I made rasters of all 2018 burned areas (value = 1 for burned area)

# and yearly rasters for 2017-2008 with all burned areas for each year which overlap

# 2018 burned area as value = 1


### ======================= Part 1: Setup ============================

import os

import arcpy

import math

from arcpy.sa import *


# set working directory

folder_path = r'C:\Users\sierr\OneDrive\Documents\Fire emissions\MTBS\reburns_arcpro\reburns_2018'

# set input and output folders

input_folder = os.path.join(folder_path, 'yearly_overlap_tifs_expanded')

output_folder = os.path.join(folder_path, 'output2')


arcpy.env.workspace = input_folder

arcpy.env.overwriteOutput = True


os.chdir(folder_path)


### ===================== Part 2: Remap values ========================

### First, change 1 values to year values in all files


# Create a list of all tif files

rasList = arcpy.ListRasters("", "TIF")

# Sort rasters in numerical order (by year)

rasList.sort()

print(rasList)


#Loop through list and remap cell values

count = 2008

for raster in rasList:

    if count < 2019:

        print(raster)

        myremap = RemapValue([[1, count]])

        outReclass = Reclassify(raster, "VALUE", myremap)

        outReclass.save(output_folder+"\year_"+str(count)+".tif")

        print(outReclass)

        count = count+1

    else:

        break

print("Done remapping rasters!")


### ================= Part 3: Calculate time lapse ====================

### Use map algebra to create a raster showing the time since most recent previous burn


# Reset directory

arcpy.env.workspace = output_folder


# Create list of new rasters with year values

rasList2 = arcpy.ListRasters("", "TIF")

# Reverse sort raster list 

rasList2.sort(reverse=True)

print(rasList2)


# Loop through list and subtract year values where there is overlap, starting with 2017

# to conserve time between burns for the most recent burn only

ras2018 = arcpy.Raster("year_2018.tif")

ras2017 = arcpy.Raster("year_2017.tif")

count = 2018

for raster in rasList2:

    if count == 2018:

        print(raster)

    elif count == 2017:

        outCon = Con(ras2018 == 2018, ras2018-ras2017, 0)

        outCon.save("reburnByYear.tif")

        rasByYear = arcpy.Raster("reburnByYear.tif")

        print("Added 2017 burns.")

    elif count == 2007:

        break

    else:

        rasNextYear = arcpy.Raster("year_"+str(count)+".tif")

        where = "VALUE = 2018"

        outCon = Con(rasByYear, rasByYear-rasNextYear, rasByYear, where)

        outCon.save("reburnByYear.tif")

        rasByYear = arcpy.Raster("reburnByYear.tif")

        print("Added "+str(count)+" burns.")

    count = count-1


# Cleanup

del outCon, outReclass, ras2018, ras2017, rasByYear, rasNextYear

print("That's a wrap folks!")

ADDITIONal EXAMPLE SCRIPTS (GEE)

As an additional validation step for NOAA's new smoke PM2.5 data, I compared it to aerosol index data from the TROPOMI sensor on the Copernicus satellite. The following GEE scripts output charts of daily data from both sources for the given time period and area.

First I compared NOAA and TROPOMI data for individual months of the 2020 fire season for all of California. Here's links to this analysis for September: 

Next, to compare the performance of NOAA's smoke PM2.5 and TROPOMI's aerosol index within smoke plumes areas from individual fire events, I first averaged both of these datasets over the duration of the fire. Then I created a mask to hide all NOAA pixels determined to be outside of the smoke plume (less than 50 µg/m^3) and drew a polygon over the estimated smoke plume area. The script then outputs charts of NOAA and TROPOMI daily averages within the smoke plume area over the fire duration. Below are links to this script for the August Complex fire, as well as the resulting charts.

* See NOAA's smoke product here, and see a user guide from Ahmadov et al. here