Structure Wildfire Emissions Estimator and Predictor Demo

Load dependencies

import os
import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import matplotlib.colors as colors

from sweep import config
from sweep.estimator_main import sweep_estimator
print("Imports complete!")

# We'll set this option so it doesn't abbreviate dataframes.
pd.set_option('display.max_columns', None)
Imports complete!

Emissions Estimator

SWEEP is designed to perform emissions estimation using user-specified selections for spatial extent and emissions factors. It accesses a hosted database of structures impacted by wildfire in California from 2018 to the present that includes damage inspection and structure information, including square footage.

Using the estimator, users can pull emissions estimation from the database using three query methods:

  • Interactive – walks users through building a query step-by-step.
  • Spatial – users provide a polygon geometry shapefile or geopackage and (optional) a date range.
  • Automated – users provide a filter field, filter value, and (optional) date range.

In addition to a query type, users can use defaults or specify estimation parameters to use for emissions estimation.

Here we demonstrate a spatial query and an automated query (the input method for the interactive filter won’t work in this file). I highly recommend the interactive filter as a way to explore the data and understand the available filtering options.

Spatial Emissions Estimation Query

Read in or point to an AOI

  • For the spatial filter, users can provide a path to a shapefile (.shp) or geopackage, or use a geodataframe object.
  • It can have one or multiple polygons. In the tool output, columns from the polygon_input are retained and tagged with “AOI” at the start of the column.
# Here we read in a file so we can take a look first-- however, aoi_path could also be used as the input for "polygon_input".
# Mosquito (2022) and River (2021) fires.
aoi_path = os.path.join(config.demo_dir, "demo_multipoly.shp")
aoi = gpd.read_file(aoi_path)
aoi.plot()

Run sweep_estimator

Here we run the main function, sweep_estimator.

  • We use the get_mode “use_default”, but as stated in the readme users who need to download or refresh the database should use get_mode = “refresh”. NOTE: using “refresh” to pull from the burned structure database requires access to a CARB ArcGIS online organizational login.
  • polygon_input can either be a gdf (as in this case) or a path.
  • We can include ‘AOI_INDEX’ in aggregation_fields for a summarized output file to ensure we get a summary per polygon in our aoi dataset.
  • Note the three outputs: emissions_gdf (a geodataframe of each structure and its emissions), agg_table (a summary dataframe), and vehicle_table.
emissions_gdf, agg_table, vehicle_table = sweep_estimator(
    get_mode = "use_default",
    filter_method = "Spatial",
    polygon_input = aoi,
    aggregate_fields=['AIR DISTRICT', 'AOI_INDEX']
    )

print("Complete!")
Loading BSDB using use_default...
Applying filter criteria...
No date filter applied.
Reprojecting polygon from EPSG:4326 to EPSG:3310.
451 rows after spatial filtering with   fire_name    incident_n start_date                          group_id  \
0  Mosquito  CATNF 001371 2022-09-06  Mosquito_CATNF 001371_2022-09-06   
1     River  CANEU 020628 2021-08-04     River_CANEU 020628_2021-08-04   

  fp_source                                           geometry  
0      FRAP  MULTIPOLYGON (((-120.56853 38.98437, -120.5686...  
1      FRAP  POLYGON ((-120.99035 39.0844, -120.99116 39.08...  .
Estimating emissions for pollutants: ['CO', 'NOx', 'SOx', 'PM', 'TOG']...
Holder efs from: C:\Users\gstarrs\Projects\CARB\sweep_test\data\emissions_factors\Holder_EFs.xlsx
Requested pollutants: ['CO', 'NOx', 'SOx', 'PM', 'TOG']
Returned pollutants: ['CO' 'NOx' 'SOx' 'PM' 'TOG']
Aggregating report by: ['AIR DISTRICT', 'AOI_INDEX']...
Calculating vehicle emissions with HOLDER factors...
Ratio provided: 311.04 vehicles estimated using ratio: 1.44
Holder efs from: C:\Users\gstarrs\Projects\CARB\sweep_test\data\emissions_factors\Holder_EFs.xlsx
Requested pollutants: ['CO', 'NOx', 'SOx', 'PM']
Returned pollutants: ['CO' 'NOx' 'SOx' 'PM']
Reports written to folder: C:\Users\gstarrs\Projects\CARB\sweep_test\outputs\SWEEP_20250621_221211
Tabular reports written.
Spatial data written to C:\Users\gstarrs\Projects\CARB\sweep_test\outputs\SWEEP_20250621_221211\Emissions_Spatial.gpkg
Complete!

Outputs

In the returned dataframes, columns from the aoi_source are retained and tagged with “AOI” at the start of the column.

Emissions Report

emissions_gdf is a geodataframe of each structure and their estimated emissions, along with parameters used in the estimation process.

print(emissions_gdf.crs)
emissions_gdf.head(5)
EPSG:3310
AOI_FIRE_NAME AOI_INCIDENT_N AOI_START_DATE AOI_GROUP_ID AOI_FP_SOURCE AOI_INDEX INCIDENTNAME INCIDENTNUM START_DATE GLOBALID_DINS DAMAGE STRUCTURETYPE STRUCTURECATEGORY CAT SQFT SQFT_SOURCE COUNTY AIR_BASIN AIR_DISTRICT COABDIS CONSUMPTION_FACTOR FRAME_FACTOR CONTENTS_FACTOR geometry E_CO_TN E_NOX_TN E_SOX_TN E_PM_TN E_TOG_TN MONTH YEAR
60130 River CANEU 020628 2021-08-04 River_CANEU 020628_2021-08-04 FRAP 1 River CANEU 020628 2021-08-04 {5A6B63E7-0584-4A3D-9566-D1BED0D23610} Destroyed (>50%) Single Family Residence Single Story Single Residence SFSS 1458.0 MEDIAN Placer MOUNTAIN COUNTIES Placer 31_MC_PLA 0.95 31.07 5.87 POINT (-84115.053 121871.211) 1.765 0.008 0.002 1.005 0.073 8 2021
60132 River CANEU 020628 2021-08-04 River_CANEU 020628_2021-08-04 FRAP 1 River CANEU 020628 2021-08-04 {28A405D3-B735-4C6A-9030-5DB781554E63} Destroyed (>50%) Single Family Residence Single Story Single Residence SFSS 1458.0 MEDIAN Placer MOUNTAIN COUNTIES Placer 31_MC_PLA 0.95 31.07 5.87 POINT (-84075.412 121847.802) 1.765 0.008 0.002 1.005 0.073 8 2021
60133 River CANEU 020628 2021-08-04 River_CANEU 020628_2021-08-04 FRAP 1 River CANEU 020628 2021-08-04 {A8436F57-068C-4D19-B659-48B51EE6DCA0} Destroyed (>50%) Single Family Residence Single Story Single Residence SFSS 1458.0 MEDIAN Placer MOUNTAIN COUNTIES Placer 31_MC_PLA 0.95 31.07 5.87 POINT (-84093.56 121769.283) 1.765 0.008 0.002 1.005 0.073 8 2021
60135 River CANEU 020628 2021-08-04 River_CANEU 020628_2021-08-04 FRAP 1 River CANEU 020628 2021-08-04 {18869BDE-69CE-4F93-B844-2F9C416A57CD} No Damage Single Family Residence Single Story Single Residence SFSS 2411.0 PARCEL Placer MOUNTAIN COUNTIES Placer 31_MC_PLA 0.00 31.07 5.87 POINT (-84135.956 121591.938) 0.000 0.000 0.000 0.000 0.000 8 2021
60136 River CANEU 020628 2021-08-04 River_CANEU 020628_2021-08-04 FRAP 1 River CANEU 020628 2021-08-04 {84EC24BE-B097-4FB8-8287-406BB9929E4F} Destroyed (>50%) Single Family Residence Single Story Single Residence SFSS 1458.0 MEDIAN Placer MOUNTAIN COUNTIES Placer 31_MC_PLA 0.95 31.07 5.87 POINT (-83735.224 122402.04) 1.765 0.008 0.002 1.005 0.073 8 2021

As a geodataframe, the output is easily visualized using the geopandas and matplotlib libraries.

# Read the AOI in to use as a base layer
aoi = gpd.read_file(aoi_path)

# Project to match emissions gdf
aoi_gdf = aoi.to_crs(emissions_gdf.crs)

fig, ax = plt.subplots(figsize=(6, 8))

aoi_gdf.plot(ax=ax, color='none', edgecolor='lightgray', linewidth=1)

# Scale the dots based off of emissions of CO.
sizes = emissions_gdf["E_CO_TN"].fillna(0) * 5
emissions_gdf.plot(
    ax=ax,
    color='orange',
    alpha=0.6,
    markersize=sizes
)
ax.set_title("Emissions Map (CO in Tons)", fontsize=14)
Text(0.5, 1.0, 'Emissions Map (CO in Tons)')

Aggregated Table

In this demo run, we provided “AIR DISTRICT” and “AOI_INDEX” as the aggregation fields. As you can see our results are split by AOI_INDEX (the polygon) and AIR_DISTRICT. We get total emissions for each polygon in each air district.

agg_table.head()
AIR_DISTRICT AOI_INDEX E_CO_TN E_NOX_TN E_SOX_TN E_PM_TN E_TOG_TN DAMAGED_STRUCTURES
0 El Dorado 0 70.53 0.33 0.07 40.17 2.92 40
1 Northern Sierra 1 150.28 0.71 0.14 85.59 6.22 79
2 Placer 0 55.88 0.26 0.05 31.82 2.32 37
3 Placer 1 129.24 0.61 0.12 73.60 5.35 62

We can use the full dataframe to add other AOI attributes back in:

# Get the full list of AOI_ columns from the emissions_gdf dataframe
aoi_cols = [col for col in emissions_gdf.columns if col.startswith("AOI_")]

# Drop duplicates to get unique AOI records
unique_aoi = emissions_gdf[aoi_cols].drop_duplicates()

# Merge with agg_table on AOI_INDEX
agg_table_aoi = agg_table.merge(unique_aoi, on="AOI_INDEX", how="left")
agg_table_aoi.head()
AIR_DISTRICT AOI_INDEX E_CO_TN E_NOX_TN E_SOX_TN E_PM_TN E_TOG_TN DAMAGED_STRUCTURES AOI_FIRE_NAME AOI_INCIDENT_N AOI_START_DATE AOI_GROUP_ID AOI_FP_SOURCE
0 El Dorado 0 70.53 0.33 0.07 40.17 2.92 40 Mosquito CATNF 001371 2022-09-06 Mosquito_CATNF 001371_2022-09-06 FRAP
1 Northern Sierra 1 150.28 0.71 0.14 85.59 6.22 79 River CANEU 020628 2021-08-04 River_CANEU 020628_2021-08-04 FRAP
2 Placer 0 55.88 0.26 0.05 31.82 2.32 37 Mosquito CATNF 001371 2022-09-06 Mosquito_CATNF 001371_2022-09-06 FRAP
3 Placer 1 129.24 0.61 0.12 73.60 5.35 62 River CANEU 020628 2021-08-04 River_CANEU 020628_2021-08-04 FRAP

Vehicle Table

A very rough estimation of emissions from vehicles (currently there is no statewide open-source real-time report of vehicles destroyed by wildfire). The default method is to estimate the count of vehicles as 1.44 vehicle destroyed per structure destroyed (consumption >50%), a method obtained from Holder et al. 2023. Users can specify what emissions factors and pollutants to use in the vef_choice and vpollutants arguments in sweep_estimator.

vehicle_table
POLLUTANT VEHICLE_GFIRE VEHICLE_GKG VEHICLES TOTAL_VEHICLE_EMISSIONS_TN
1 CO 22128.0 48.0 311.04 7.59
2 NOx 1844.0 4.0 311.04 0.63
8 SOx 875.9 1.9 311.04 0.30
15 PM 26369.2 57.2 311.04 9.04

Automated Emissions Estimation Query

  • In an “automated” query, we can set filter_field, filter_values, and, optionally, date ranges (apply_date_filter, start_date, and end_date).
  • This allows users to run a query without working through the interactive tool.
  • If you’re savvy you can loop over date ranges or other filter_fields/filter_values to get a series of reports.
  • If running in an IDE, hovering over any function should provide typing hints and parameter information.

Run sweep_estimator with pre-set filter fields

emissions_gdf_auto, agg_table_auto, vehicle_table_auto = sweep_estimator(
    get_mode = "use_default",
    filter_method = "automated",
    filter_field = "Air Basin",
    field_values = ["MOUNTAIN COUNTIES", "SAN JOAQUIN VALLEY"],
    apply_date_filter = True,
    start_date = "2018-01-01",
    end_date = "2021-01-01",
    aggregate_fields=['AIR DISTRICT', 'YEAR', 'INCIDENT'],
    # Adding a few more arguments-- here we specify the emissions factor source (HOLDER)
    ef_choice = "HOLDER",
    # And here we override the default to say we want ALL the pollutants available for the emissions factor source.
    pollutants = "All",
    write = "No"
    )

print("Complete!")
emissions_gdf_auto.head()
Loading BSDB using use_default...
Applying filter criteria...
59137 rows after date filtering from 2018-01-01 to 2021-01-01.
4501 rows after filtering by Air Basin: ['MOUNTAIN COUNTIES', 'SAN JOAQUIN VALLEY'].
Estimating emissions for pollutants: All...
Holder efs from: C:\Users\gstarrs\Projects\CARB\sweep_test\data\emissions_factors\Holder_EFs.xlsx
Requested pollutants: All
Returned pollutants: ['CO2' 'CO' 'NOx' 'NO' 'NO2 ' 'HCN' 'NH3' 'SO2' 'SOx' 'H2S' 'HCl' 'HBr'
 'HF' 'THC' 'Isocyanates' 'PM' 'Elemental Carbon' 'Organic Carbon' 'Pb'
 'Sb' 'Cl' 'Br' 'TOG' 'Benzene' 'Chlorobenzene' 'Toluene' 'Ethylbenzene'
 'Ethynylbenzene' 'Styrene' 'Ethene' 'Phenol' 'Pyridine' 'Benzonitrile'
 'Formaldehyde' 'Acetaldehyde' 'Acrolein' 'PAH' 'Naphthalene'
 'Acenaphthene' 'Acenaphthylene' 'Methylnaphthalenes' 'Biphenyl' 'Indene'
 'Fluorene' 'Phenanthrene' 'Anthracene' 'Fluoranthene' 'Pyrene'
 'Benzo(a)fluorene' 'Benzo(b)fluorene' 'Benz(a)anthracene' 'Chrysene'
 'Benzo(b)fluoranthene' 'Benzo(k)fluoranthene' 'Benzo(a)pyrene'
 'Benzo(e)pyrene' 'Perylene' 'Indeno(1,2,3-c,d)pyrene'
 'Benzo(g,h,i,)perylene' 'Dibenzo(a,h)anthracene' 'Coronene' 'PCDD' 'PCDF']
Aggregating report by: ['AIR DISTRICT', 'YEAR', 'INCIDENT']...
Calculating vehicle emissions with HOLDER factors...
Ratio provided: 1738.08 vehicles estimated using ratio: 1.44
Holder efs from: C:\Users\gstarrs\Projects\CARB\sweep_test\data\emissions_factors\Holder_EFs.xlsx
Requested pollutants: ['CO', 'NOx', 'SOx', 'PM']
Returned pollutants: ['CO' 'NOx' 'SOx' 'PM']
Complete!
INCIDENTNAME INCIDENTNUM START_DATE GLOBALID_DINS DAMAGE STRUCTURETYPE STRUCTURECATEGORY CAT SQFT SQFT_SOURCE COUNTY AIR_BASIN AIR_DISTRICT COABDIS CONSUMPTION_FACTOR FRAME_FACTOR CONTENTS_FACTOR geometry E_CO2_TN E_CO_TN E_NOX_TN E_NO_TN E_NO2 _TN E_HCN_TN E_NH3_TN E_SO2_TN E_SOX_TN E_H2S_TN E_HCL_TN E_HBR_TN E_HF_TN E_THC_TN E_ISOCYANATES_TN E_PM_TN E_ELEMENTAL CARBON_TN E_ORGANIC CARBON_TN E_PB_TN E_SB_TN E_CL_TN E_BR_TN E_TOG_TN E_BENZENE_TN E_CHLOROBENZENE_TN E_TOLUENE_TN E_ETHYLBENZENE_TN E_ETHYNYLBENZENE_TN E_STYRENE_TN E_ETHENE_TN E_PHENOL_TN E_PYRIDINE_TN E_BENZONITRILE_TN E_FORMALDEHYDE_TN E_ACETALDEHYDE_TN E_ACROLEIN_TN E_PAH_TN E_NAPHTHALENE_TN E_ACENAPHTHENE_TN E_ACENAPHTHYLENE_TN E_METHYLNAPHTHALENES_TN E_BIPHENYL_TN E_INDENE_TN E_FLUORENE_TN E_PHENANTHRENE_TN E_ANTHRACENE_TN E_FLUORANTHENE_TN E_PYRENE_TN E_BENZO(A)FLUORENE_TN E_BENZO(B)FLUORENE_TN E_BENZ(A)ANTHRACENE_TN E_CHRYSENE_TN E_BENZO(B)FLUORANTHENE_TN E_BENZO(K)FLUORANTHENE_TN E_BENZO(A)PYRENE_TN E_BENZO(E)PYRENE_TN E_PERYLENE_TN E_INDENO(1,2,3-C,D)PYRENE_TN E_BENZO(G,H,I,)PERYLENE_TN E_DIBENZO(A,H)ANTHRACENE_TN E_CORONENE_TN E_PCDD_TN E_PCDF_TN MONTH YEAR
656 Wagner CAMMU 016004 2018-08-04 {CA9382AF-9449-4988-98CE-C00CE3C55B32} Destroyed (>50%) Single Family Residence Single Story Single Residence SFSS 1458.000000 MEDIAN Mariposa MOUNTAIN COUNTIES Mariposa 22_MC_MPA 0.95 31.07 5.87 POINT (-9578.918 -33825.916) 33.897 1.765 0.008 0.013 0.014 0.038 0.021 0.002 0.002 0.056 0.281 0.008 0.0 1.489 0.0 1.005 0.196 0.045 0.0 0.0 0.091 0.0 0.073 0.015 0.008 0.003 0.001 0.002 0.002 0.011 0.001 0.001 0.001 0.006 0.005 0.0 0.002 0.003 0.0 0.002 0.001 0.001 0.001 0.0 0.002 0.0 0.001 0.001 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 8 2018
1486 Frazier CAFKU 007893 2018-06-03 {1765CBC6-51CC-4A19-883C-1F5509FC5A3F} Minor (10-25%) Single Family Residence Single Story Single Residence SFSS 1752.000000 PARCEL Fresno SAN JOAQUIN VALLEY San Joaquin Valley Unified 10_SJV_SJU 0.00 31.07 5.87 POINT (43612.19 -105244.953) 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.0 0.000 0.0 0.000 0.000 0.000 0.0 0.0 0.000 0.0 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.0 0.000 0.000 0.0 0.000 0.000 0.000 0.000 0.0 0.000 0.0 0.000 0.000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 6 2018
1504 Omega CAAEU 021770 2018-08-01 {39799A65-7A77-4BC3-BFD6-B042F640C830} No Damage Single Family Residence Single Story Single Residence SFSS 1391.000000 PARCEL El Dorado MOUNTAIN COUNTIES El Dorado 9_MC_ED 0.00 31.07 5.87 POINT (-89600.032 90657.664) 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.0 0.000 0.0 0.000 0.000 0.000 0.0 0.0 0.000 0.0 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.0 0.000 0.000 0.0 0.000 0.000 0.000 0.000 0.0 0.000 0.0 0.000 0.000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 8 2018
1505 Omega CAAEU 021770 2018-08-01 {92C931E6-9D5F-47B5-B82B-968E7AAA02D8} Minor (10-25%) Single Family Residence Single Story Single Residence SFSS 1777.000000 PARCEL El Dorado MOUNTAIN COUNTIES El Dorado 9_MC_ED 0.00 31.07 5.87 POINT (-89674.345 90491.003) 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.0 0.000 0.0 0.000 0.000 0.000 0.0 0.0 0.000 0.0 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.0 0.000 0.000 0.0 0.000 0.000 0.000 0.000 0.0 0.000 0.0 0.000 0.000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 8 2018
1506 Omega CAAEU 021770 2018-08-01 {288E3A2E-03B8-4FA3-9A05-85503FBC3A4C} Minor (10-25%) Single Family Residence Single Story Single Residence SFSS 1666.421397 MODEL_A El Dorado MOUNTAIN COUNTIES El Dorado 9_MC_ED 0.00 31.07 5.87 POINT (-89807.299 90485.001) 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.0 0.000 0.0 0.000 0.000 0.000 0.0 0.0 0.000 0.0 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.0 0.000 0.000 0.0 0.000 0.000 0.000 0.000 0.0 0.000 0.0 0.000 0.000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 8 2018

TIP for filtering

Since it is difficult to document every possible choice for each field value for each potential filter field (choices: [“Wildfire Name”, “Incident Number”, “County”, “Air Basin”, “Air District”, “CoAbDis Code”]), you can pull possible values from the current BSDB database.

# We read in one of the classes from the package.
from sweep.get_bsdb import GetBSDB

# bsdb_df is the geodataframe of the BSDB.
bsdb_df = GetBSDB("use_default").bsdb_df
# Air basins in the dataset:
print(f"Air Basins: {bsdb_df['BASIN_NAME'].unique()}")

# Air districts in the dataset:
print(f"Air Districts: {bsdb_df['DIS_NAME'].unique()}")

# All filter field column names: ["incidentname", "incidentnum", "CO_NAME", "BASIN_NAME", "DIS_NAME", "COABDIS"]
# Note the argument filter_field uses the cleaned-up names: ["Wildfire Name", "Incident Number", "County", "Air Basin", "Air District", "CoAbDis Code"]

# Date field: ["clean_date"]
Air Basins: ['SOUTH COAST' 'SOUTH CENTRAL COAST' 'NORTH COAST'
 'SAN FRANCISCO BAY AREA' 'SAN DIEGO COUNTY' 'MOUNTAIN COUNTIES'
 'SACRAMENTO VALLEY' 'LAKE COUNTY' 'SAN JOAQUIN VALLEY'
 'NORTHEAST PLATEAU' 'MOJAVE DESERT' 'NORTH CENTRAL COAST'
 'GREAT BASIN VALLEYS' 'LAKE TAHOE' 'SALTON SEA' '']
Air Districts: ['South Coast' 'Santa Barbara' 'Ventura' 'Northern Sonoma' 'Bay Area'
 'San Diego' 'San Luis Obispo' 'Mariposa' 'Butte' 'Lake' 'Yolo-Solano'
 'San Joaquin Valley Unified' 'Placer' 'El Dorado' 'Mendocino' 'Shasta'
 'Tehama' 'Lassen' 'North Coast Unified' 'Siskiyou' 'Amador' 'Calaveras'
 'Tuolumne' 'Antelope Valley' 'Monterey Bay Unified' 'Kern'
 'Northern Sierra' 'Feather River' 'Glenn' 'Sacramento Metro'
 'Great Basin Unified' '' 'Mojave Desert' 'Colusa']

NOTE:

  • All filter field column names: [“incidentname”, “incidentnum”, “CO_NAME”, “BASIN_NAME”, “DIS_NAME”, “COABDIS”]
  • The argument filter_field uses the cleaned-up names: [“Wildfire Name”, “Incident Number”, “County”, “Air Basin”, “Air District”, “CoAbDis Code”]

Have fun!

Outputs

The outputs are the same as for the interactive and spatial query types. As specified in “aggregate_fields”, the aggregate table is summarized by year, air district, and fire incident.

agg_table_auto
AIR_DISTRICT YEAR INCIDENTNAME E_CO2_TN E_CO_TN E_NOX_TN E_NO_TN E_NO2 _TN E_HCN_TN E_NH3_TN E_SO2_TN E_SOX_TN E_H2S_TN E_HCL_TN E_HBR_TN E_HF_TN E_THC_TN E_ISOCYANATES_TN E_PM_TN E_ELEMENTAL CARBON_TN E_ORGANIC CARBON_TN E_PB_TN E_SB_TN E_CL_TN E_BR_TN E_TOG_TN E_BENZENE_TN E_CHLOROBENZENE_TN E_TOLUENE_TN E_ETHYLBENZENE_TN E_ETHYNYLBENZENE_TN E_STYRENE_TN E_ETHENE_TN E_PHENOL_TN E_PYRIDINE_TN E_BENZONITRILE_TN E_FORMALDEHYDE_TN E_ACETALDEHYDE_TN E_ACROLEIN_TN E_PAH_TN E_NAPHTHALENE_TN E_ACENAPHTHENE_TN E_ACENAPHTHYLENE_TN E_METHYLNAPHTHALENES_TN E_BIPHENYL_TN E_INDENE_TN E_FLUORENE_TN E_PHENANTHRENE_TN E_ANTHRACENE_TN E_FLUORANTHENE_TN E_PYRENE_TN E_BENZO(A)FLUORENE_TN E_BENZO(B)FLUORENE_TN E_BENZ(A)ANTHRACENE_TN E_CHRYSENE_TN E_BENZO(B)FLUORANTHENE_TN E_BENZO(K)FLUORANTHENE_TN E_BENZO(A)PYRENE_TN E_BENZO(E)PYRENE_TN E_PERYLENE_TN E_INDENO(1,2,3-C,D)PYRENE_TN E_BENZO(G,H,I,)PERYLENE_TN E_DIBENZO(A,H)ANTHRACENE_TN E_CORONENE_TN E_PCDD_TN E_PCDF_TN DAMAGED_STRUCTURES
0 Amador 2018 Irish 33.95 1.77 0.01 0.01 0.01 0.04 0.02 0.00 0.00 0.06 0.28 0.01 0.0 1.49 0.0 1.01 0.20 0.04 0.00 0.0 0.09 0.0 0.07 0.02 0.01 0.00 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.00 0.0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.0 0.0 0.00 0.00 0.00 0.0 0.00 0.0 0.0 0.00 0.00 0.0 0.0 0.0 0.0 1.0
1 Amador 2019 Willow 33.90 1.76 0.01 0.01 0.01 0.04 0.02 0.00 0.00 0.06 0.28 0.01 0.0 1.49 0.0 1.00 0.20 0.04 0.00 0.0 0.09 0.0 0.07 0.02 0.01 0.00 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.00 0.0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.0 0.0 0.00 0.00 0.00 0.0 0.00 0.0 0.0 0.00 0.00 0.0 0.0 0.0 0.0 1.0
2 Calaveras 2018 Horse 64.95 3.38 0.02 0.02 0.03 0.07 0.04 0.00 0.00 0.11 0.54 0.02 0.0 2.85 0.0 1.93 0.38 0.09 0.00 0.0 0.18 0.0 0.14 0.03 0.01 0.01 0.00 0.00 0.00 0.02 0.00 0.00 0.00 0.01 0.01 0.00 0.00 0.01 0.0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.0 0.0 0.00 0.00 0.00 0.0 0.00 0.0 0.0 0.00 0.00 0.0 0.0 0.0 0.0 2.0
3 Calaveras 2018 Waverly 37.95 1.98 0.01 0.01 0.02 0.04 0.02 0.00 0.00 0.06 0.32 0.01 0.0 1.67 0.0 1.13 0.22 0.05 0.00 0.0 0.10 0.0 0.08 0.02 0.01 0.00 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.00 0.0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.0 0.0 0.00 0.00 0.00 0.0 0.00 0.0 0.0 0.00 0.00 0.0 0.0 0.0 0.0 1.0
4 El Dorado 2018 Meyers 146.93 7.65 0.04 0.06 0.06 0.17 0.09 0.01 0.01 0.24 1.22 0.04 0.0 6.46 0.0 4.36 0.85 0.20 0.00 0.0 0.39 0.0 0.32 0.06 0.03 0.01 0.00 0.01 0.01 0.05 0.00 0.00 0.00 0.03 0.02 0.00 0.01 0.01 0.0 0.01 0.00 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.0 0.0 0.00 0.00 0.00 0.0 0.00 0.0 0.0 0.00 0.00 0.0 0.0 0.0 0.0 4.0
5 El Dorado 2018 Omega 31.80 1.66 0.01 0.01 0.01 0.04 0.02 0.00 0.00 0.05 0.26 0.01 0.0 1.40 0.0 0.94 0.18 0.04 0.00 0.0 0.08 0.0 0.07 0.01 0.01 0.00 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.00 0.0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.0 0.0 0.00 0.00 0.00 0.0 0.00 0.0 0.0 0.00 0.00 0.0 0.0 0.0 0.0 1.0
6 El Dorado 2019 County 55.87 2.91 0.01 0.02 0.02 0.06 0.04 0.00 0.00 0.09 0.46 0.01 0.0 2.45 0.0 1.66 0.32 0.07 0.00 0.0 0.15 0.0 0.12 0.02 0.01 0.00 0.00 0.00 0.00 0.02 0.00 0.00 0.00 0.01 0.01 0.00 0.00 0.00 0.0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.0 0.0 0.00 0.00 0.00 0.0 0.00 0.0 0.0 0.00 0.00 0.0 0.0 0.0 0.0 2.0
7 El Dorado 2019 Rimrock 33.90 1.76 0.01 0.01 0.01 0.04 0.02 0.00 0.00 0.06 0.28 0.01 0.0 1.49 0.0 1.00 0.20 0.04 0.00 0.0 0.09 0.0 0.07 0.02 0.01 0.00 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.00 0.0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.0 0.0 0.00 0.00 0.00 0.0 0.00 0.0 0.0 0.00 0.00 0.0 0.0 0.0 0.0 1.0
8 El Dorado 2020 Cameron 64.80 3.37 0.02 0.02 0.03 0.07 0.04 0.00 0.00 0.11 0.54 0.02 0.0 2.85 0.0 1.92 0.38 0.09 0.00 0.0 0.17 0.0 0.14 0.03 0.02 0.01 0.00 0.00 0.00 0.02 0.00 0.00 0.00 0.01 0.01 0.00 0.00 0.01 0.0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.0 0.0 0.00 0.00 0.00 0.0 0.00 0.0 0.0 0.00 0.00 0.0 0.0 0.0 0.0 2.0
9 Mariposa 2018 Wagner 309.20 16.10 0.08 0.12 0.13 0.35 0.19 0.02 0.02 0.51 2.57 0.08 0.0 13.58 0.0 9.17 1.79 0.41 0.00 0.0 0.83 0.0 0.67 0.13 0.07 0.03 0.01 0.02 0.02 0.10 0.01 0.01 0.01 0.06 0.04 0.00 0.02 0.03 0.0 0.02 0.01 0.01 0.01 0.00 0.02 0.00 0.01 0.01 0.0 0.0 0.00 0.00 0.00 0.0 0.00 0.0 0.0 0.00 0.00 0.0 0.0 0.0 0.0 7.0
10 Northern Sierra 2020 Jones 663.40 34.54 0.16 0.25 0.28 0.75 0.41 0.03 0.03 1.10 5.50 0.16 0.0 29.14 0.0 19.67 3.84 0.88 0.00 0.0 1.78 0.0 1.43 0.29 0.15 0.06 0.02 0.04 0.04 0.22 0.02 0.02 0.02 0.12 0.10 0.00 0.04 0.06 0.0 0.04 0.02 0.02 0.02 0.00 0.04 0.00 0.02 0.02 0.0 0.0 0.00 0.00 0.00 0.0 0.00 0.0 0.0 0.00 0.00 0.0 0.0 0.0 0.0 18.0
11 Northern Sierra 2020 North Complex 934.80 48.68 0.23 0.36 0.39 1.06 0.58 0.05 0.05 1.55 7.76 0.22 0.0 41.06 0.0 27.72 5.41 1.24 0.00 0.0 2.51 0.0 2.02 0.41 0.21 0.08 0.03 0.06 0.06 0.30 0.03 0.02 0.03 0.17 0.14 0.00 0.05 0.08 0.0 0.06 0.03 0.02 0.03 0.00 0.06 0.00 0.03 0.03 0.0 0.0 0.00 0.00 0.00 0.0 0.00 0.0 0.0 0.00 0.00 0.0 0.0 0.0 0.0 25.0
12 San Joaquin Valley Unified 2018 Frazier 33.90 1.76 0.01 0.01 0.01 0.04 0.02 0.00 0.00 0.06 0.28 0.01 0.0 1.49 0.0 1.00 0.20 0.04 0.00 0.0 0.09 0.0 0.07 0.02 0.01 0.00 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.00 0.0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.0 0.0 0.00 0.00 0.00 0.0 0.00 0.0 0.0 0.00 0.00 0.0 0.0 0.0 0.0 1.0
13 San Joaquin Valley Unified 2020 Creek 31600.97 1645.57 7.74 11.99 13.24 35.71 19.63 1.57 1.57 52.22 262.23 7.62 0.0 1388.08 0.0 937.18 183.01 41.98 0.06 0.0 84.84 0.0 68.16 13.70 7.19 2.80 1.20 1.82 2.13 10.31 0.86 0.84 1.18 5.83 4.61 0.17 1.74 2.66 0.0 1.98 0.86 0.83 0.96 0.20 2.08 0.06 0.86 0.86 0.0 0.0 0.01 0.04 0.15 0.0 0.01 0.0 0.0 0.04 0.04 0.0 0.0 0.0 0.0 871.0
14 San Joaquin Valley Unified 2020 SCU Lightning Cmplx 1647.28 85.78 0.40 0.63 0.69 1.86 1.02 0.09 0.09 2.72 13.66 0.39 0.0 72.36 0.0 48.85 9.53 2.19 0.00 0.0 4.42 0.0 3.55 0.72 0.38 0.15 0.06 0.09 0.10 0.54 0.05 0.04 0.06 0.30 0.24 0.00 0.09 0.14 0.0 0.10 0.05 0.04 0.05 0.00 0.10 0.00 0.05 0.05 0.0 0.0 0.00 0.00 0.00 0.0 0.00 0.0 0.0 0.00 0.00 0.0 0.0 0.0 0.0 52.0
15 San Joaquin Valley Unified 2020 SQF Complex 9037.80 470.61 2.21 3.44 3.77 10.23 5.63 0.42 0.42 14.93 74.98 2.19 0.0 396.98 0.0 268.04 52.33 12.01 0.00 0.0 24.24 0.0 19.52 3.95 2.07 0.82 0.33 0.52 0.63 2.93 0.22 0.21 0.33 1.67 1.35 0.09 0.51 0.73 0.0 0.54 0.22 0.21 0.30 0.09 0.63 0.00 0.22 0.22 0.0 0.0 0.00 0.00 0.08 0.0 0.00 0.0 0.0 0.00 0.00 0.0 0.0 0.0 0.0 233.0
16 Tuolumne 2018 Ruby 31.43 1.64 0.01 0.01 0.01 0.04 0.02 0.00 0.00 0.05 0.26 0.01 0.0 1.38 0.0 0.93 0.18 0.04 0.00 0.0 0.08 0.0 0.07 0.01 0.01 0.00 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.00 0.0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.0 0.0 0.00 0.00 0.00 0.0 0.00 0.0 0.0 0.00 0.00 0.0 0.0 0.0 0.0 1.0

Emissions Predictor

NOTE: A Lightbox Parcel API key is REQUIRED to use the emissions predictor.

The predictor uses parcel square footage data (where available) to estimate potential emissions within a user-provided polygon or set of polygons. The analysis is limited to parcels where square footage data is available. Users provide a percentage of structures within the polygon to assume “destroyed” by wildfire. As with the estimator, users provide emissions estimation parameters (or use the default), and the tool returns points and excel files with the requested estimates.

from sweep.predictor_main import sweep_predictor
from dotenv import load_dotenv
load_dotenv() 
True

Read in or point to an AOI

The AOI is the polygon shape or shapes in which emissions will be estimated. In the Predictor function, this is aoi_source, and like polygon_input in sweep_estimator, it can be either a geopandas geodataframe, or a path to a geopackage or shapefile.

The aoi_source will be reprojected if needed and have each row or feature indexed seperately, with all columns retained in the final products.

# Recycling! We'll use the same aoi as the spatial query above.
aoi.plot()

Run sweep_predictor

Key differences related to the predictor are:

  • aoi_source: a geodataframe or shapeflie/geopackage path is required.
  • api_key: the need for a LightBox API key
  • ratio_destroyed: users must specify the ratio of structures to designate “destroyed” by fire.
predicted_emissions_gdf, agg_table, vehicle_table = sweep_predictor(
    aoi_source = aoi,
    # You need a lightbox API key to get the parcel data.
    api_key = os.getenv('LB_API_KEY'),
    ratio_destroyed = 0.8,
    pollutants = None, 
    aggregate_fields = ['AIR DISTRICT', 'AOI_INDEX'],
    write = "No")
Fetching parcel data...
https://api.lightboxre.com/v1/parcels/us/geometry
Offset: 0, Limit: 500, Status code: 200
Offset: 500, Limit: 500, Status code: 200
Offset: 1000, Limit: 500, Status code: 200
Offset: 1500, Limit: 500, Status code: 200
Offset: 2000, Limit: 500, Status code: 200
Offset: 2500, Limit: 500, Status code: 200
Offset: 3000, Limit: 500, Status code: 200
https://api.lightboxre.com/v1/parcels/us/geometry
Offset: 0, Limit: 500, Status code: 200
Offset: 500, Limit: 500, Status code: 200
https://api.lightboxre.com/v1/assessments/us/geometry
Offset: 0, Limit: 500, Status code: 200
Offset: 500, Limit: 500, Status code: 200
Offset: 1000, Limit: 500, Status code: 200
Offset: 1500, Limit: 500, Status code: 200
Offset: 2000, Limit: 500, Status code: 200
Offset: 2500, Limit: 500, Status code: 200
Offset: 3000, Limit: 500, Status code: 200
Offset: 3500, Limit: 500, Status code: 200
Offset: 4000, Limit: 500, Status code: 200
Offset: 4500, Limit: 500, Status code: 200
Offset: 5000, Limit: 500, Status code: 200
Offset: 5500, Limit: 500, Status code: 200
Offset: 6000, Limit: 500, Status code: 200
Offset: 6500, Limit: 500, Status code: 200
Offset: 7000, Limit: 500, Status code: 200
Offset: 7500, Limit: 500, Status code: 200
Offset: 8000, Limit: 500, Status code: 200
Offset: 8500, Limit: 500, Status code: 200
Offset: 9000, Limit: 500, Status code: 200
Offset: 9500, Limit: 500, Status code: 200
Offset: 10000, Limit: 500, Status code: 200
https://api.lightboxre.com/v1/assessments/us/geometry
Offset: 0, Limit: 500, Status code: 200
Offset: 500, Limit: 500, Status code: 200
Processing parcels...
Parcel and assessment datasets joined and fields cleaned.
Joined dataset clipped to fire geometry.
Generating synthetic BSDB...
Missing columns: {'OBJECTID', 'centroid', 'SITE_HOUSE_NUMBER', 'COMMUNITY', 'INCIDENTSTARTDATE', 'ZONING', 'STREETNAME', 'TOTAL_ROOMS', 'TOTAL_BATHS', 'geometry', 'STREETSUFFIX', 'ZIPCODE', 'INCIDENTNUM', 'CITY', 'BEDROOMS', 'SITE_UNIT_PREFIX', 'STATE', 'UNITS_NUMBER', 'STRUCTURECATEGORY', 'SQFEET', 'FEMA_SQFT', 'PARCEL_CAT_MATCH', 'STRUCTURETYPE', 'DAMAGE', 'GLOBALID', 'FEMA_PMFT', 'STREETNUMBER', 'HAZARDTYPE', 'SITEADDRESS', 'CO_NAME', 'STREETTYPE', 'YEARBUILT', 'SITE_UNIT_NUMBER', 'APN', 'CALFIREUNIT', 'SITE_DIRECTION'}
Estimating emissions for pollutants: ['CO', 'NOx', 'SOx', 'PM', 'TOG']...
Holder efs from: C:\Users\gstarrs\Projects\CARB\sweep_test\data\emissions_factors\Holder_EFs.xlsx
Requested pollutants: ['CO', 'NOx', 'SOx', 'PM', 'TOG']
Returned pollutants: ['CO' 'NOx' 'SOx' 'PM' 'TOG']
Aggregating report by: ['AIR DISTRICT', 'AOI_INDEX']...
Calculating vehicle emissions with CARB factors...
Ratio provided: 216.0 vehicles estimated using ratio: 1.44
CARB efs from: C:\Users\gstarrs\Projects\CARB\sweep_test\data\emissions_factors\CARB_EFs.xlsx
Requested pollutants: ['CO', 'NOx', 'SOx', 'PM']
Returned pollutants: ['CO' 'NOx' 'SOx' 'PM']
Processing complete.

Outputs

  • In the returned dataframes, columns from the aoi_source are retained and tagged with “AOI” at the start of the column.
  • predicted_emissions_gdf is a geodataframe of each record used to estimate emissions.
  • Each “structure” is derived from the parcels that fell within the AOI.
print(predicted_emissions_gdf.crs)
predicted_emissions_gdf.head()
EPSG:3310
AOI_INDEX AOI_FIRE_NAME AOI_INCIDENT_N AOI_START_DATE AOI_GROUP_ID AOI_FP_SOURCE INCIDENTNAME START_DATE DAMAGE CAT SQFT SQFT_SOURCE COUNTY AIR_BASIN AIR_DISTRICT CONSUMPTION_FACTOR FRAME_FACTOR CONTENTS_FACTOR geometry E_CO_TN E_NOX_TN E_SOX_TN E_PM_TN E_TOG_TN MONTH YEAR
0 0 Mosquito CATNF 001371 2022-09-06 Mosquito_CATNF 001371_2022-09-06 FRAP SWEEP202506212215 2025-06-21 Destroyed (>50%) SR 145.724907 PARCEL PLACER MOUNTAIN COUNTIES Placer 0.95 31.07 5.87 POINT (-72862.95 110016.358) 0.176 0.001 0.000 0.100 0.007 6 2025
1 0 Mosquito CATNF 001371 2022-09-06 Mosquito_CATNF 001371_2022-09-06 FRAP SWEEP202506212215 2025-06-21 Destroyed (>50%) MR 171.747212 PARCEL PLACER MOUNTAIN COUNTIES Placer 0.95 31.07 5.87 POINT (-72675.094 110682.073) 0.208 0.001 0.000 0.118 0.009 6 2025
2 0 Mosquito CATNF 001371 2022-09-06 Mosquito_CATNF 001371_2022-09-06 FRAP SWEEP202506212215 2025-06-21 Destroyed (>50%) SR 79.925651 PARCEL PLACER MOUNTAIN COUNTIES Placer 0.95 31.07 5.87 POINT (-72964.532 109973.298) 0.097 0.000 0.000 0.055 0.004 6 2025
3 0 Mosquito CATNF 001371 2022-09-06 Mosquito_CATNF 001371_2022-09-06 FRAP SWEEP202506212215 2025-06-21 Destroyed (>50%) MR 98.884758 PARCEL PLACER MOUNTAIN COUNTIES Placer 0.95 31.07 5.87 POINT (-73128.236 110051.244) 0.120 0.001 0.000 0.068 0.005 6 2025
4 0 Mosquito CATNF 001371 2022-09-06 Mosquito_CATNF 001371_2022-09-06 FRAP SWEEP202506212215 2025-06-21 Destroyed (>50%) COM 1477.881041 PARCEL PLACER MOUNTAIN COUNTIES Placer 0.95 31.07 5.87 POINT (-72557.727 111000.702) 1.789 0.009 0.002 1.019 0.074 6 2025

In this demo run, we provided “AIR DISTRICT” and “AOI_INDEX” as the aggregation fields. As you can see our results are split by AOI_INDEX (the polygon) and AIR_DISTRICT. We get total emissions for each polygon in each air district.

agg_table
AIR_DISTRICT AOI_INDEX E_CO_TN E_NOX_TN E_SOX_TN E_PM_TN E_TOG_TN DAMAGED_STRUCTURES
0 El Dorado 0 1.69 0.01 0.0 0.96 0.07 10
1 Northern Sierra 1 9.85 0.05 0.0 5.61 0.41 47
2 Placer 0 13.07 0.07 0.0 7.44 0.54 60
3 Placer 1 6.02 0.03 0.0 3.43 0.25 27

We can again add the full AOI information back in to each AOI polygon based on the index.

aoi_cols = [col for col in predicted_emissions_gdf.columns if col.startswith("AOI_")]
unique_aoi = predicted_emissions_gdf[aoi_cols].drop_duplicates()
agg_table_aoi = agg_table.merge(unique_aoi, on="AOI_INDEX", how="left")
agg_table_aoi
AIR_DISTRICT AOI_INDEX E_CO_TN E_NOX_TN E_SOX_TN E_PM_TN E_TOG_TN DAMAGED_STRUCTURES AOI_FIRE_NAME AOI_INCIDENT_N AOI_START_DATE AOI_GROUP_ID AOI_FP_SOURCE
0 El Dorado 0 1.69 0.01 0.0 0.96 0.07 10 Mosquito CATNF 001371 2022-09-06 Mosquito_CATNF 001371_2022-09-06 FRAP
1 Northern Sierra 1 9.85 0.05 0.0 5.61 0.41 47 River CANEU 020628 2021-08-04 River_CANEU 020628_2021-08-04 FRAP
2 Placer 0 13.07 0.07 0.0 7.44 0.54 60 Mosquito CATNF 001371 2022-09-06 Mosquito_CATNF 001371_2022-09-06 FRAP
3 Placer 1 6.02 0.03 0.0 3.43 0.25 27 River CANEU 020628 2021-08-04 River_CANEU 020628_2021-08-04 FRAP

We can also remake our map with the predictor’s output instead of reported estimator data.

  • The predictor has a few main drawbacks.
  • First, it likely underestimates the count of structures, as parcel data generally reflects the main structure in a parcel. The full DINS dataset also includes minor utility structures, mobile homes, and other types of structures.
  • Second, not all structures in a fire footprint are destroyed. The predictor’s ratio_destroyed provides users the ability to state the percentage of structures in the AOI destroyed, but it is effectively a placeholder for the data collected on the ground for the DINS dataset.

Map

# Read AOI layer
aoi_gdf = aoi.to_crs(predicted_emissions_gdf.crs)
fig, ax = plt.subplots(figsize=(6, 8))
aoi_gdf.plot(ax=ax, color='none', edgecolor='lightgray', linewidth=1)
sizes = predicted_emissions_gdf["E_CO_TN"].fillna(0) * 5
predicted_emissions_gdf.plot(
    ax=ax,
    color='orange',
    alpha=0.6,
    markersize=sizes
)
ax.set_title("Emissions Map (CO in Tons)", fontsize=14)
Text(0.5, 1.0, 'Emissions Map (CO in Tons)')