Monitoring Volcanic Sulfur Dioxide Emissions

NASA monitors volcanic emissions and its impact on global air quality
Author

Kathryn Berger

Published

April 4, 2023

Run this notebook

You can launch this notebook using mybinder, by clicking the button below.

Binder

Approach

  1. Identify available dates and temporal frequency of observations for a given collection - SO2
  2. Pass the STAC item into raster API /stac/tilejson.json endpoint
  3. We’ll visualize tiles for each of the time steps of interest using folium

About the Data

Collecting measurements of Sulfur Dioxide (SO2) plumes from space is a valuable way to monitor changes in emissions. The SO2 index product is used by NASA to monitor volcanic clouds and pre-eruptive volcanic gas emissions activity. Additionally, this information is used in advisories to airlines for operational decisions.

In this notebook, we will explore the Sulfur Dioxide dataset and how it was used in this VEDA Discovery article to monitor air pollution across the globe.

Querying the STAC API

import requests
from folium import Map, TileLayer
# Provide STAC and RASTER API endpoints
STAC_API_URL = "https://staging-stac.delta-backend.com"
RASTER_API_URL = "https://staging-raster.delta-backend.com"

# Declare collection of interest - Sulfur Dioxide
collection_name = "OMSO2PCA-COG"
# Fetch STAC collection
collection = requests.get(f"{STAC_API_URL}/collections/{collection_name}").json()
collection
{'id': 'OMSO2PCA-COG',
 'type': 'Collection',
 'links': [{'rel': 'items',
   'type': 'application/geo+json',
   'href': 'https://staging-stac.delta-backend.com/collections/OMSO2PCA-COG/items'},
  {'rel': 'parent',
   'type': 'application/json',
   'href': 'https://staging-stac.delta-backend.com/'},
  {'rel': 'root',
   'type': 'application/json',
   'href': 'https://staging-stac.delta-backend.com/'},
  {'rel': 'self',
   'type': 'application/json',
   'href': 'https://staging-stac.delta-backend.com/collections/OMSO2PCA-COG'}],
 'title': 'OMI/Aura Sulfur Dioxide (SO2) Total Column L3 1 day Best Pixel in 0.25 degree x 0.25 degree V3 as Cloud-Optimized GeoTIFFs (COGs)',
 'extent': {'spatial': {'bbox': [[-180, -90, 180, 90]]},
  'temporal': {'interval': [['2005-01-01T00:00:00Z',
     '2021-01-01T00:00:00Z']]}},
 'license': 'MIT',
 'summaries': {'datetime': ['2005-01-01T00:00:00Z', '2021-01-01T00:00:00Z'],
  'cog_default': {'max': 28.743701934814453, 'min': -4.941379070281982}},
 'description': 'OMI/Aura Sulfur Dioxide (SO2) Total Column L3 1 day Best Pixel in 0.25 degree x 0.25 degree V3 as Cloud-Optimized GeoTIFFs (COGs)',
 'item_assets': {'cog_default': {'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
   'roles': ['data', 'layer'],
   'title': 'Default COG Layer',
   'description': 'Cloud optimized default layer to display on map'}},
 'stac_version': '1.0.0',
 'stac_extensions': [],
 'dashboard:is_periodic': True,
 'dashboard:time_density': 'year'}

Examining the contents of our collection under summaries we see that the data is available from 2005 to 2021. By looking at the dashboard:time density we observe that the periodic frequency of these observations is yearly.

We can verify this by checking the total items returned from our STAC API requests.

# Check total number of items available
items = requests.get(
    f"{STAC_API_URL}/collections/{collection_name}/items?limit=100"
).json()["features"]
print(f"Found {len(items)} items")
Found 17 items

This makes sense as there are 17 years between 2005 - 2021.

Exploring Sulfur Dioxide Plumes from Space - Using the Raster API

We’ll explore three different time steps to show how NASA has observed volcanic activity in the Galápagos islands (2005), detected large scale emissions on the Kamchatka Peninsula (2009), and monitored the eruptions of Fagradalsfjall in Iceland (2021). We’ll then visualize the outputs on a map using folium.

To start, we’ll identify which item value corresponds to each year of interest and setting a rescaling_factor for the SO2 index, so that values range from 0 to 1.

# to access the year value from each item more easily
items = {item["properties"]["start_datetime"][:4]: item for item in items}
rescaling_factor = "0,1"

Now we will pass the item id, collection name, and rescaling_factor to the Raster API endpoint. We will do this three times, one for each time step of interest, so that we can visualize each event independently.

tile_2005 = requests.get(
    f"{RASTER_API_URL}/stac/tilejson.json?collection={items['2005']['collection']}&item={items['2005']['id']}"
    "&assets=cog_default"
    "&color_formula=gamma+r+1.05&colormap_name=viridis"
    f"&rescale={rescaling_factor}",
).json()
tile_2005
{'tilejson': '2.2.0',
 'version': '1.0.0',
 'scheme': 'xyz',
 'tiles': ['https://staging-raster.delta-backend.com/stac/tiles/WebMercatorQuad/{z}/{x}/{y}@1x?collection=OMSO2PCA-COG&item=OMSO2PCA_LUT_SCD_2005&assets=cog_default&color_formula=gamma+r+1.05&colormap_name=viridis&rescale=0%2C1'],
 'minzoom': 0,
 'maxzoom': 24,
 'bounds': [-180.0, -90.0, 180.0, 90.0],
 'center': [0.0, 0.0, 0]}
tile_2009 = requests.get(
    f"{RASTER_API_URL}/stac/tilejson.json?collection={items['2009']['collection']}&item={items['2009']['id']}"
    "&assets=cog_default"
    "&color_formula=gamma+r+1.05&colormap_name=viridis"
    f"&rescale={rescaling_factor}",
).json()
tile_2009
{'tilejson': '2.2.0',
 'version': '1.0.0',
 'scheme': 'xyz',
 'tiles': ['https://staging-raster.delta-backend.com/stac/tiles/WebMercatorQuad/{z}/{x}/{y}@1x?collection=OMSO2PCA-COG&item=OMSO2PCA_LUT_SCD_2009&assets=cog_default&color_formula=gamma+r+1.05&colormap_name=viridis&rescale=0%2C1'],
 'minzoom': 0,
 'maxzoom': 24,
 'bounds': [-180.0, -90.0, 180.0, 90.0],
 'center': [0.0, 0.0, 0]}
tile_2021 = requests.get(
    f"{RASTER_API_URL}/stac/tilejson.json?collection={items['2021']['collection']}&item={items['2021']['id']}"
    "&assets=cog_default"
    "&color_formula=gamma+r+1.05&colormap_name=viridis"
    f"&rescale={rescaling_factor}",
).json()
tile_2021
{'tilejson': '2.2.0',
 'version': '1.0.0',
 'scheme': 'xyz',
 'tiles': ['https://staging-raster.delta-backend.com/stac/tiles/WebMercatorQuad/{z}/{x}/{y}@1x?collection=OMSO2PCA-COG&item=OMSO2PCA_LUT_SCD_2021&assets=cog_default&color_formula=gamma+r+1.05&colormap_name=viridis&rescale=0%2C1'],
 'minzoom': 0,
 'maxzoom': 24,
 'bounds': [-180.0, -90.0, 180.0, 90.0],
 'center': [0.0, 0.0, 0]}

We will then use the tile URL prepared above to create a simple visualization for each time step using folium. In each of these visualizations you can zoom in and out of the map’s focus area to explore the data layer for that year.

Visualizing Galápagos islands (2005)

# Set initial zoom and map for Galápagos islands

import folium

m = Map(
    tiles="OpenStreetMap",
    location=[
        -0.915435,
        -89.57216,
    ],
    zoom_start=7,
)

map_layer = TileLayer(
    tiles=tile_2005["tiles"][0],
    attr="VEDA",
    opacity=0.6,
)

map_layer.add_to(m)

m
Make this Notebook Trusted to load map: File -> Trust Notebook

Visualizing Kamchatka Peninsula (2009)

# Set initial zoom and map for Kamchatka Peninsula

import folium

m = Map(
    tiles="OpenStreetMap",
    location=[
        53.018234,
        158.67016,
    ],
    zoom_start=7,
)

map_layer = TileLayer(
    tiles=tile_2009["tiles"][0],
    attr="VEDA",
    opacity=0.6,
)

map_layer.add_to(m)

m
Make this Notebook Trusted to load map: File -> Trust Notebook

Visualizing Fagradalsfjall, Iceland (2021)

# Set initial zoom and map for Fagradalsfjall, Iceland

import folium

m = Map(
    tiles="OpenStreetMap",
    location=[
        65.0294256,
        -18.393870,
    ],
    zoom_start=6,
)

map_layer = TileLayer(
    tiles=tile_2021["tiles"][0],
    attr="VEDA",
    opacity=0.6,
)

map_layer.add_to(m)

m
Make this Notebook Trusted to load map: File -> Trust Notebook

Summary

In this case study we have successfully visualized how NASA monitors sulfur dioxide emissions from space, by showcasing three different examples across the globe: volcanic activity in the Galápagos islands (2005), large scale emissions on the Kamchatka Peninsula (2009), and eruptions of Fagradalsfjall in Iceland (2021).