MODIS Level 2 - MCD14DL - Fire Radiative Power

This notebook provides you an introduction to data from the Moderate Resolution Imaging Spectroradiometer (MODIS). We are using MODIS fire radiative power data as a proxy for the next-generation Fire Radiative Power Pixel (FRPPIXEL) product from LSA SAF that will integrate data from Meteosat Third Generation’s Flexible Combined Imager.

This notebook shows the structure of MODIS Thermal Anomalies/Fire locations 1km FIRMS V0061 NRT (Vector data) and how to load, browse and visualize the data.

The events featured in this notebook are the wildfires in Italy and Greece in summer 2021.

Basic Facts

Spatial coverage: Global
Time step: Monthly
Data availability: since 2000

How to access the data

This notebook uses the MODIS MCD14DL dataset from the Terra and Aqua platforms. The MCD14DL dataset archive can be ordered via the FIRMS and are distributed in shp, kml or csv format, which is then zipped.

You need to register for an Earthdata account before being able to download data.


Load required libraries

import os
import numpy as np
import pandas as pd

# Python libraries for visualization
import matplotlib.colors
from matplotlib.colors import BoundaryNorm, ListedColormap
import matplotlib.pyplot as plt
import cartopy
import cartopy.crs as ccrs
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
from matplotlib.axes import Axes
from cartopy.mpl.geoaxes import GeoAxes
GeoAxes._pcolormesh_patched = Axes.pcolormesh

import warnings
warnings.filterwarnings('ignore')
warnings.simplefilter(action = "ignore", category = RuntimeWarning)

Load helper functions

%run ../functions.ipynb

Load and browse MODIS Fire Radiative Power data

[OPTIONAL] The first step is to unzip file from the zipped archive downloaded. This is optional as we have already unzipped the file for you. This is why the code is commented out.

The zipped archive contains data in a Comma-Separated Values or csv file and a Readme text document. The period requested was from 5 August 2021 to 7 August 2021.

# import zipfile
# with zipfile.ZipFile('../data/modis/level2/frp/DL_FIRE_M-C61_251212.zip', 'r') as zip_ref:
#    zip_ref.extractall('../data/modis/level2/frp/2021/08')

After we downloaded the station observations as a csv file, we can open it with the pandas function read_table(). We additonally set specific keyword arguments that allow us to specify the columns and rows of interest:

  • delimiter: specify the delimiter in the text file, e.g. comma

  • header: specify the index of the row that shall be set as header.

  • index_col: specify the index of the column that shall be set as index

You see below that the resulting dataframe has 2108 rows and 14 columns.

df = pd.read_table('../data/modis/level2/frp/2021/08/fire_archive_M-C61_251212.csv', delimiter=',', header=[0], index_col=5)
df
latitude longitude brightness scan track acq_time satellite instrument confidence version bright_t31 frp daynight type
acq_date
2021-08-05 44.1170 25.1176 311.1 1.0 1.0 26 Aqua MODIS 82 6.03 287.8 11.6 N 0
2021-08-05 42.0245 20.2539 300.0 1.3 1.1 26 Aqua MODIS 2 6.03 289.6 4.4 N 0
2021-08-05 42.0330 20.2704 308.4 1.3 1.1 26 Aqua MODIS 74 6.03 291.1 11.4 N 0
2021-08-05 42.0345 20.2566 353.5 1.3 1.1 26 Aqua MODIS 100 6.03 295.1 101.7 N 0
2021-08-05 42.0362 20.2410 325.0 1.3 1.1 26 Aqua MODIS 100 6.03 291.2 32.3 N 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
2021-08-07 44.7821 20.5855 326.8 1.1 1.1 2043 Terra MODIS 100 6.03 292.9 29.1 N 0
2021-08-07 44.7837 20.5996 362.9 1.1 1.1 2043 Terra MODIS 100 6.03 297.5 110.4 N 0
2021-08-07 43.2199 12.6086 306.7 1.5 1.2 2043 Terra MODIS 69 6.03 293.5 10.7 N 0
2021-08-07 37.0451 28.8563 302.3 3.6 1.8 2320 Aqua MODIS 38 6.03 290.5 32.9 N 0
2021-08-07 37.0504 28.8543 308.4 3.6 1.8 2320 Aqua MODIS 74 6.03 290.3 56.2 N 0

2108 rows × 14 columns

From the dataframe above, let us only select the columns of interest for us. This makes the handling of the dataframe much easier. The columns of interest are: acq_date, latitude, longitude, confidence and frp. You can use the function filter() to select specific columns.

frp = df.filter(['acq_date','latitude','longitude','confidence','frp'])
frp
latitude longitude confidence frp
acq_date
2021-08-05 44.1170 25.1176 82 11.6
2021-08-05 42.0245 20.2539 2 4.4
2021-08-05 42.0330 20.2704 74 11.4
2021-08-05 42.0345 20.2566 100 101.7
2021-08-05 42.0362 20.2410 100 32.3
... ... ... ... ...
2021-08-07 44.7821 20.5855 100 29.1
2021-08-07 44.7837 20.5996 100 110.4
2021-08-07 43.2199 12.6086 69 10.7
2021-08-07 37.0451 28.8563 38 32.9
2021-08-07 37.0504 28.8543 74 56.2

2108 rows × 4 columns

Next, we filter the dataframe for rows which have an acquisition date or acq_date of 2021-08-05. You will see that the number of rows is reduced to 785 rows.

frp = frp.filter(like='2021-08-05', axis=0)
frp
latitude longitude confidence frp
acq_date
2021-08-05 44.1170 25.1176 82 11.6
2021-08-05 42.0245 20.2539 2 4.4
2021-08-05 42.0330 20.2704 74 11.4
2021-08-05 42.0345 20.2566 100 101.7
2021-08-05 42.0362 20.2410 100 32.3
... ... ... ... ...
2021-08-05 37.3375 28.3422 87 38.7
2021-08-05 37.3261 28.3095 100 73.4
2021-08-05 37.3241 28.3384 79 33.2
2021-08-05 37.0630 31.4832 52 8.7
2021-08-05 37.3310 28.3050 100 93.0

785 rows × 4 columns

Next, we remove the rows which have a confidence level below 60 percent.

frp = frp[frp['confidence'] >= 60]
frp
latitude longitude confidence frp
acq_date
2021-08-05 44.1170 25.1176 82 11.6
2021-08-05 42.0330 20.2704 74 11.4
2021-08-05 42.0345 20.2566 100 101.7
2021-08-05 42.0362 20.2410 100 32.3
2021-08-05 41.8277 22.7949 79 16.6
... ... ... ... ...
2021-08-05 37.3396 28.3121 100 74.8
2021-08-05 37.3375 28.3422 87 38.7
2021-08-05 37.3261 28.3095 100 73.4
2021-08-05 37.3241 28.3384 79 33.2
2021-08-05 37.3310 28.3050 100 93.0

650 rows × 4 columns

Visualise MODIS MCD14DL Level 2 data

You can make use of the ListedColorMap function from the matplotlib library to define the colors for each fire radiative power (FRP) class.

frp_cm = ListedColormap([[0, 0, 255./255.],
                                 [176./255., 196./255., 222./255.],
                                 [255./255., 255./255., 0],
                                 [1., 140./255., 0],
                                 [178./255., 34./255., 34./255.],
                                 [1, 0, 0]])

You can define the levels for the respective FRP classes in a list stored in the variable bounds. You can also use the .BoundaryNorm() function from matplotlib.colors to define the norm that you will use for plotting later.

bounds = [0, 30, 40, 60, 80, 120, 500]
norm = BoundaryNorm(bounds, frp_cm.N)

The last step is to visualize the FRP data with matplotlib’s scatter function.

The plotting code can be divided in five main parts:

  • Initiate a matplotlib figure: Initiate a matplotlib plot and define the size of the plot

  • Specify coastlines, borders and a grid: specify additional features to be added to the plot

  • Plotting function: plot the data with the plotting function scatter

  • Specify color bar: specify the color bar properties

  • Set plot title: specify title of the plot

# Initiate a matplotlib figure
fig=plt.figure(figsize=(20, 12))
ax=plt.axes(projection=ccrs.PlateCarree())

# Specify coastlines and borders
ax.coastlines(zorder=3)
ax.add_feature(cfeature.BORDERS, edgecolor='black', linewidth=1, zorder=3)

# Specify a grid
gl = ax.gridlines()
gl = ax.gridlines(draw_labels=True, linestyle='--')
gl.top_labels=False
gl.right_labels=False
gl.xformatter=LONGITUDE_FORMATTER
gl.yformatter=LATITUDE_FORMATTER
gl.xlabel_style={'size':14}
gl.ylabel_style={'size':14}

# Set the plot extent
ax.set_extent([10, 30, 35, 45], ccrs.PlateCarree())

# Plotting function
img1 = plt.scatter(frp['longitude'],frp['latitude'], c=frp['frp'],
                   edgecolors='none',
                   cmap=frp_cm,
                   norm=norm,
                   zorder=2)


# Specify colorbar 
cbar = fig.colorbar(img1, ax=ax, orientation='horizontal', fraction=0.04, pad=0.1)
cbar.set_label('MW',fontsize=16)
cbar.ax.tick_params(labelsize=14)

# Set plot title
ax.set_title('MODIS Fire Radiative Power Pixel - 05 August 2021', fontsize=20, pad=20.0)

# Show plot
plt.show()
../_images/figure2_MODIS_FRP_30_0.png

References

Return to the case study

Monitoring active fires with next-generation satellites: Mediterranean Fires Case Study
Fire Radiative Power (FRPPIXEL)