CEMS Global ECMWF Fire Forecasting (GEFF) - Fire Weather Index
Contents
CEMS Global ECMWF Fire Forecasting (GEFF) - Fire Weather Index¶
The European Centre for Medium-Range Weather Forecasts (ECMWF) produces daily fire danger forecasts and reanalysis products for the Copernicus Emergency Management Services (CEMS). The modelling system that generates the fire data products is called Global ECMWF Fire Forecast (GEFF) and it is based on the Canadian Fire Weather index as well as the US and Australian fire danger systems.
In most European countries, the core of the wildfire season starts on 1st of March and ends on 31st of October. The EFFIS network adopts the Canadian Forest Fire Weather Index (FWI) System as the method to assess the fire danger level in a harmonized way throughout Europe.
European Fire Danger Classes (FWI ranges, upper bound excluded):
Very low = 0 - 5.2
Low = 5.2 - 11.2
Moderate = 11.2 - 21.3
High = 21.3 - 38.0
Very high = 38.0 - 50.0
Extreme > 50.0
This notebook shows the structure of CEMS GEFF Fire Weather Index
data and what information of the data files can be used in order 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 resolution: ~10km
Spatial coverage: Europe
Time steps: Daily, seasonal and annual
Data availability: since 1970
How to access the data
The fire weather index data can be ordered via the Copernicus Climate Data Store and are distributed in NetCDF
format. We recommend using the corrected Version 2.0 of the data.
You need to register for an account before being able to download data.
Load required libraries
import numpy as np
import pandas as pd
import xarray as xr
# Python libraries for visualization
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.colors as colors
from matplotlib.colors import ListedColormap
Load helper functions
%run ../functions.ipynb
Load and browse GEFF Fire Weather Index data¶
As a first step, you can load one dataset with xarray’s function open_dataset
. This will help you to understand how the data is structured.
You see that the data consists of a three dimensional data array, with time
, longitude
and latitude
as dimensions.
ds = xr.open_dataset("../data/geff/ECMWF_FWI_FWI_20210805_1200_hr_v4.0_con.nc")
ds
<xarray.Dataset> Dimensions: (time: 1, longitude: 1440, latitude: 721) Coordinates: * time (time) datetime64[ns] 2021-08-05T12:00:00 * longitude (longitude) float32 0.0 0.25 0.5 0.75 ... 359.0 359.2 359.5 359.8 * latitude (latitude) float32 90.0 89.75 89.5 89.25 ... -89.5 -89.75 -90.0 Data variables: fwi (time, latitude, longitude) float32 ... Attributes: CDI: Climate Data Interface version 1.9.8 (https://... Conventions: CF-1.6 history: Fri Oct 29 01:05:30 2021: cdo -f nc4 -chname,f... institution: European Centre for Medium-Range Weather Forec... cdo_openmp_thread_number: 8 CDO: Climate Data Operators version 1.9.8 (https://...
- time: 1
- longitude: 1440
- latitude: 721
- time(time)datetime64[ns]2021-08-05T12:00:00
- standard_name :
- time
- axis :
- T
array(['2021-08-05T12:00:00.000000000'], dtype='datetime64[ns]')
- longitude(longitude)float320.0 0.25 0.5 ... 359.2 359.5 359.8
- standard_name :
- longitude
- long_name :
- longitude
- units :
- degrees_east
- axis :
- X
array([0.0000e+00, 2.5000e-01, 5.0000e-01, ..., 3.5925e+02, 3.5950e+02, 3.5975e+02], dtype=float32)
- latitude(latitude)float3290.0 89.75 89.5 ... -89.75 -90.0
- standard_name :
- latitude
- long_name :
- latitude
- units :
- degrees_north
- axis :
- Y
array([ 90. , 89.75, 89.5 , ..., -89.5 , -89.75, -90. ], dtype=float32)
- fwi(time, latitude, longitude)float32...
- standard_name :
- forest_fire_weather_index
- long_name :
- Forest fire weather index
- units :
- Numeric
- param :
- 5.4.2
- institution :
- ECMWF
[1038240 values with dtype=float32]
- CDI :
- Climate Data Interface version 1.9.8 (https://mpimet.mpg.de/cdi)
- Conventions :
- CF-1.6
- history :
- Fri Oct 29 01:05:30 2021: cdo -f nc4 -chname,fwinx,fwi -selvar,fwinx -setgridtype,regular ECMWF_FWI_20210805_1200_hr.grib ECMWF_FWI_FWI_20210805_1200_hr_v4.0_con.nc
- institution :
- European Centre for Medium-Range Weather Forecasts
- cdo_openmp_thread_number :
- 8
- CDO :
- Climate Data Operators version 1.9.8 (https://mpimet.mpg.de/cdo)
You can specify one variable of interest by putting the name of the variable into square brackets []
and get more detailed information about the variable. E.g. fwi
is the fire weather index data we are interested in.
fwi = ds['fwi']
fwi
<xarray.DataArray 'fwi' (time: 1, latitude: 721, longitude: 1440)> [1038240 values with dtype=float32] Coordinates: * time (time) datetime64[ns] 2021-08-05T12:00:00 * longitude (longitude) float32 0.0 0.25 0.5 0.75 ... 359.0 359.2 359.5 359.8 * latitude (latitude) float32 90.0 89.75 89.5 89.25 ... -89.5 -89.75 -90.0 Attributes: standard_name: forest_fire_weather_index long_name: Forest fire weather index units: Numeric param: 5.4.2 institution: ECMWF
- time: 1
- latitude: 721
- longitude: 1440
- ...
[1038240 values with dtype=float32]
- time(time)datetime64[ns]2021-08-05T12:00:00
- standard_name :
- time
- axis :
- T
array(['2021-08-05T12:00:00.000000000'], dtype='datetime64[ns]')
- longitude(longitude)float320.0 0.25 0.5 ... 359.2 359.5 359.8
- standard_name :
- longitude
- long_name :
- longitude
- units :
- degrees_east
- axis :
- X
array([0.0000e+00, 2.5000e-01, 5.0000e-01, ..., 3.5925e+02, 3.5950e+02, 3.5975e+02], dtype=float32)
- latitude(latitude)float3290.0 89.75 89.5 ... -89.75 -90.0
- standard_name :
- latitude
- long_name :
- latitude
- units :
- degrees_north
- axis :
- Y
array([ 90. , 89.75, 89.5 , ..., -89.5 , -89.75, -90. ], dtype=float32)
- standard_name :
- forest_fire_weather_index
- long_name :
- Forest fire weather index
- units :
- Numeric
- param :
- 5.4.2
- institution :
- ECMWF
Bring longitude coordinates onto a [-180,180] grid¶
The longitude values are on a [0,360] grid instead of a [-180,180] grid.
You can assign new values to coordinates in an xarray.Dataset
. You can do so with the assign_coords()
function, which you can apply onto a xarray.Dataset
. With the code below, you shift your longitude grid from [0,360] to [-180,180]. At the end, you sort the longitude values in an ascending order.
fwi_assigned = fwi.assign_coords(longitude=(((fwi.longitude + 180) % 360) - 180)).sortby('longitude')
fwi_assigned
<xarray.DataArray 'fwi' (time: 1, latitude: 721, longitude: 1440)> [1038240 values with dtype=float32] Coordinates: * time (time) datetime64[ns] 2021-08-05T12:00:00 * longitude (longitude) float32 -180.0 -179.8 -179.5 ... 179.2 179.5 179.8 * latitude (latitude) float32 90.0 89.75 89.5 89.25 ... -89.5 -89.75 -90.0 Attributes: standard_name: forest_fire_weather_index long_name: Forest fire weather index units: Numeric param: 5.4.2 institution: ECMWF
- time: 1
- latitude: 721
- longitude: 1440
- ...
[1038240 values with dtype=float32]
- time(time)datetime64[ns]2021-08-05T12:00:00
- standard_name :
- time
- axis :
- T
array(['2021-08-05T12:00:00.000000000'], dtype='datetime64[ns]')
- longitude(longitude)float32-180.0 -179.8 ... 179.5 179.8
array([-180. , -179.75, -179.5 , ..., 179.25, 179.5 , 179.75], dtype=float32)
- latitude(latitude)float3290.0 89.75 89.5 ... -89.75 -90.0
- standard_name :
- latitude
- long_name :
- latitude
- units :
- degrees_north
- axis :
- Y
array([ 90. , 89.75, 89.5 , ..., -89.5 , -89.75, -90. ], dtype=float32)
- standard_name :
- forest_fire_weather_index
- long_name :
- Forest fire weather index
- units :
- Numeric
- param :
- 5.4.2
- institution :
- ECMWF
Create a geographical subset around Italy and Greece¶
Let’s subset our data to Italy and Greece.
For geographical subsetting, you can make use of the function generate_geographical_subset. You can use ?generate_geographical_subset
to open the docstring in order to see the function’s keyword arguments.
?generate_geographical_subset
Signature:
generate_geographical_subset(
xarray,
latmin,
latmax,
lonmin,
lonmax,
reassign=False,
)
Docstring:
Generates a geographical subset of a xarray.DataArray and if kwarg reassign=True, shifts the longitude grid
from a 0-360 to a -180 to 180 deg grid.
Parameters:
xarray(xarray.DataArray): a xarray DataArray with latitude and longitude coordinates
latmin, latmax, lonmin, lonmax(int): lat/lon boundaries of the geographical subset
reassign(boolean): default is False
Returns:
Geographical subset of a xarray.DataArray.
File: /tmp/ipykernel_11225/3979307327.py
Type: function
Define the bounding box information for Italy and Greece.
lonmin=10
lonmax=30
latmin=35
latmax=45
Now, let us apply the function generate_geographical_subset to subset the fwi_assigned
xarray.DataArray. Let us call the new xarray.DataArray fwi_subset
.
fwi_subset = generate_geographical_subset(xarray=fwi_assigned,
latmin=latmin,
latmax=latmax,
lonmin=lonmin,
lonmax=lonmax)
fwi_subset
<xarray.DataArray 'fwi' (time: 1, latitude: 39, longitude: 79)> array([[[10.799805 , 17.420248 , 24.36914 , ..., 20.979492 , 17.09733 , 16.54248 ], [11.998047 , 13.001953 , 16.319662 , ..., nan, nan, nan], [ 0.6582031, 1.8463541, 5.5240884, ..., nan, nan, nan], ..., [56.391113 , 60.751465 , 63.10669 , ..., nan, nan, nan], [58.073242 , 59.086914 , 62.18506 , ..., nan, nan, nan], [57.010254 , 58.53308 , 61.454346 , ..., nan, nan, nan]]], dtype=float32) Coordinates: * time (time) datetime64[ns] 2021-08-05T12:00:00 * longitude (longitude) float32 10.25 10.5 10.75 11.0 ... 29.25 29.5 29.75 * latitude (latitude) float32 44.75 44.5 44.25 44.0 ... 35.75 35.5 35.25 Attributes: standard_name: forest_fire_weather_index long_name: Forest fire weather index units: Numeric param: 5.4.2 institution: ECMWF
- time: 1
- latitude: 39
- longitude: 79
- 10.8 17.42 24.37 26.62 24.24 22.67 21.41 ... nan nan nan nan nan nan
array([[[10.799805 , 17.420248 , 24.36914 , ..., 20.979492 , 17.09733 , 16.54248 ], [11.998047 , 13.001953 , 16.319662 , ..., nan, nan, nan], [ 0.6582031, 1.8463541, 5.5240884, ..., nan, nan, nan], ..., [56.391113 , 60.751465 , 63.10669 , ..., nan, nan, nan], [58.073242 , 59.086914 , 62.18506 , ..., nan, nan, nan], [57.010254 , 58.53308 , 61.454346 , ..., nan, nan, nan]]], dtype=float32)
- time(time)datetime64[ns]2021-08-05T12:00:00
- standard_name :
- time
- axis :
- T
array(['2021-08-05T12:00:00.000000000'], dtype='datetime64[ns]')
- longitude(longitude)float3210.25 10.5 10.75 ... 29.5 29.75
array([10.25, 10.5 , 10.75, 11. , 11.25, 11.5 , 11.75, 12. , 12.25, 12.5 , 12.75, 13. , 13.25, 13.5 , 13.75, 14. , 14.25, 14.5 , 14.75, 15. , 15.25, 15.5 , 15.75, 16. , 16.25, 16.5 , 16.75, 17. , 17.25, 17.5 , 17.75, 18. , 18.25, 18.5 , 18.75, 19. , 19.25, 19.5 , 19.75, 20. , 20.25, 20.5 , 20.75, 21. , 21.25, 21.5 , 21.75, 22. , 22.25, 22.5 , 22.75, 23. , 23.25, 23.5 , 23.75, 24. , 24.25, 24.5 , 24.75, 25. , 25.25, 25.5 , 25.75, 26. , 26.25, 26.5 , 26.75, 27. , 27.25, 27.5 , 27.75, 28. , 28.25, 28.5 , 28.75, 29. , 29.25, 29.5 , 29.75], dtype=float32)
- latitude(latitude)float3244.75 44.5 44.25 ... 35.5 35.25
- standard_name :
- latitude
- long_name :
- latitude
- units :
- degrees_north
- axis :
- Y
array([44.75, 44.5 , 44.25, 44. , 43.75, 43.5 , 43.25, 43. , 42.75, 42.5 , 42.25, 42. , 41.75, 41.5 , 41.25, 41. , 40.75, 40.5 , 40.25, 40. , 39.75, 39.5 , 39.25, 39. , 38.75, 38.5 , 38.25, 38. , 37.75, 37.5 , 37.25, 37. , 36.75, 36.5 , 36.25, 36. , 35.75, 35.5 , 35.25], dtype=float32)
- standard_name :
- forest_fire_weather_index
- long_name :
- Forest fire weather index
- units :
- Numeric
- param :
- 5.4.2
- institution :
- ECMWF
Visualise GEFF Fire Weather Index data¶
Finally, you can visualise the fire weather index data by plotting it.
The plotting code can be divided in four 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: specify the extent and plot the data with the
.plot
Set plot title: specify title of the plot
# Initiate a matplotlib figure
fig=plt.figure(figsize=(20,12))
ax=plt.subplot(1,1,1, projection=ccrs.PlateCarree())
# Specify coastlines and borders
ax.coastlines(color='white',linewidth=1.5)
ax.add_feature(cfeature.BORDERS, edgecolor='white', linewidth=1, zorder=3)
# Specify a grid
gl = ax.gridlines(draw_labels=True, linewidth=1, color='gray', alpha=0.5, 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}
# Plotting function
fwi_subset.plot(levels = [0.0, 5.2, 11.2, 21.3, 38.0, 50.0],
colors = ["#008000", "#FFFF00", "#FFA500", "#FF0000", "#654321", "#000000"],
label = ['Very low', 'Low', 'Moderate', 'High', 'Very high', 'Extreme'],
ax=ax,
cbar_kwargs={'spacing':'proportional',
'ticks':[0.0, 5.2, 11.2, 21.3, 38.0, 50.0],
'fraction':0.035,
'pad':0.05,
'orientation':'horizontal'})
# Set plot title
ax.set_title('GEFF Fire Weather Index - ' + str(fwi_subset.time.data)[2:12] + ' - classified in European Fire Danger Classes\n', size=16)
# Show the plot
plt.show()
References¶
Giannakopoulos, C., Karali, A., Cauchy, A. (2020): Fire danger indicators for Europe from 1970 to 2098 derived from climate projections, version 1.0. Copernicus Climate Change Service (C3S) Climate Data Store (CDS), doi: 10.24381/cds.ca755de7
Some code in this notebook was adapted from the following source:
copyright: 2022, EUMETSAT
license: MIT
retrieved: 2022-06-28 by Sabrina Szeto
Return to the case study
Assessing pre-fire risk with next-generation satellites: Mediterranean Fires Case Study
Fire Weather Index