Skip to content

Commit b430d18

Browse files
committed
Review text content
1 parent 078c801 commit b430d18

File tree

1 file changed

+111
-36
lines changed

1 file changed

+111
-36
lines changed

tutorials/climate-risk.ipynb

Lines changed: 111 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,54 @@
55
"id": "2c6f38fa-6466-4d9f-a2bd-8f522de36553",
66
"metadata": {},
77
"source": [
8-
"## Evaluating climate risk: wildfire\n",
8+
"## 🔥 Wildfire Risk Monitoring\n",
99
"\n",
10-
"We are seeing more common occurrences of extreme weather events during all seasons. In North America one of the most dangerous types of extreme weather events is a period of unusually hot, dry, and windy conditions which can cause conditions where wildfires can spread very rapidly.\n",
10+
"This notebook demonstrates how to assess short-term wildfire risk using high-resolution weather forecasts from the Planetary Computer. We use the HRRR (High-Resolution Rapid Refresh) dataset to analyze forecasted temperature, wind, and relative humidity (RH) over a 48-hour window for a selected area of interest.\n",
1111
"\n",
12-
"NOAA's High Resolution Rapid Refresh weather forecast dataset provides near-real-time 48 hour forecasts and the archive dating back to 2021 is stored in Azure cloud storage. This dataset provides a framework that we can use to evaluate anomalous conditions like large increases in temperature and wind speed combined with lower-than-normal relative humidity.\n",
12+
"We are seeing more common occurrences of extreme weather events during all seasons. In North America, one of the most dangerous types of extreme weather events is a period of unusually hot, dry, and windy conditions, which can cause conditions where wildfires can spread very rapidly.\n",
1313
"\n",
14-
"Dangerous wildfire conditions developed across northern Minnesota on May 10, 2025 and multiple large fires ignited and spread rapidly during the following days. We will use that event to demonstrate how the forecast data from May 9 could be used to analyze the risk of wildfire in that scenario.\n",
14+
"NOAA's High Resolution Rapid Refresh weather forecast dataset provides near-real-time 48-hour forecasts, and the archive dating back to 2021 is stored in Azure cloud storage. This dataset provides a framework for evaluating anomalous conditions like large increases in temperature and wind speed combined with lower-than-normal relative humidity.\n",
15+
"\n",
16+
"Dangerous wildfire conditions developed across northern Minnesota on May 10, 2025, and multiple large fires ignited and spread rapidly during the following days. We will use that event to demonstrate how the forecast data from May 9 could be used to analyze the wildfire risk in that scenario.\n",
17+
"\n",
18+
"<details>\n",
19+
"<summary>📘 Outline</summary>\n",
20+
"\n",
21+
"1. Define an area of interest and forecast time\n",
22+
"2. Load HRRR data from the Planetary Computer STAC API\n",
23+
"3. Visualize forecasted temperature, wind, and humidity\n",
24+
"4. Evaluate conditions that contribute to wildfire risk\n",
25+
"5. Generate maps of risk indicators for rapid assessment\n",
26+
"\n",
27+
"</details>\n",
28+
"\n",
29+
"### 🎯 Learning Objectives\n",
30+
"\n",
31+
"- Access forecast weather data from the HRRR catalog via STAC\n",
32+
"- Interpret meteorological variables relevant to wildfire risk\n",
33+
"- Use Xarray and Pystac-Client to process spatiotemporal forecast data\n",
34+
"- Visualize fire risk drivers across space and time\n",
35+
"- Build workflows to support rapid-response planning\n",
36+
"\n",
37+
"### 🧠 Core Concepts\n",
38+
"\n",
39+
"- HRRR as a source of high-resolution, short-term forecasts\n",
40+
"- Meteorological indicators of wildfire risk: high temps, low RH, strong winds\n",
41+
"- Raster analysis with Xarray\n",
42+
"- Forecast-driven decision support for hazard management\n",
43+
"\n",
44+
"---\n",
45+
"\n",
46+
"📚 **Related notebooks**\n",
47+
"- [Site Monitoring Foundations](/tutorials/site-monitoring-foundations.ipynb)\n",
48+
"- [Crop Site Monitoring](/tutorials/site-monitoring-hls.ipynb)"
49+
]
50+
},
51+
{
52+
"cell_type": "markdown",
53+
"id": "aa3af6a0",
54+
"metadata": {},
55+
"source": [
1556
"\n",
1657
"The following analysis can be run using the following conda environment.yml file:\n",
1758
"\n",
@@ -59,7 +100,7 @@
59100
},
60101
{
61102
"cell_type": "code",
62-
"execution_count": 1,
103+
"execution_count": null,
63104
"id": "855c466a",
64105
"metadata": {
65106
"jupyter": {
@@ -79,8 +120,7 @@
79120
"import geopandas as gpd\n",
80121
"import httpx\n",
81122
"import imageio.v2 as imageio\n",
82-
"import matplotlib.cm\n",
83-
"import matplotlib.colors\n",
123+
"import matplotlib\n",
84124
"import matplotlib.patches as patches\n",
85125
"import matplotlib.pyplot as plt\n",
86126
"import numpy as np\n",
@@ -111,7 +151,7 @@
111151
"source": [
112152
"### Gather HRRR metadata\n",
113153
"\n",
114-
"The NOAA HRRR dataset is not yet available in a collection in the Open Planetary Computer Catalog, but you can generate some STAC metadata, save it to a STAC Geoparquet file with `rustac`, then use `rustac` to query the local copy like an API!"
154+
"The NOAA HRRR dataset is not yet available in a collection in the Open Planetary Computer Catalog. Still, you can generate some STAC metadata, save it to a STAC Geoparquet file with `rustac`, then use `rustac` to query the local copy like an API!"
115155
]
116156
},
117157
{
@@ -156,7 +196,7 @@
156196
"id": "4689180d-f3f9-4a07-80a7-c732c6700e02",
157197
"metadata": {},
158198
"source": [
159-
"Now that we have STAC items for the entire day's worth of forecast data, send a query to find the last 48 hour forecast from today's date."
199+
"Now that we have STAC items for the entire day's forecast data, send a query to find the last 48-hour forecast from today's date."
160200
]
161201
},
162202
{
@@ -200,7 +240,7 @@
200240
"id": "ee4fecdd-c084-4def-b1a7-146e3d537757",
201241
"metadata": {},
202242
"source": [
203-
"Now use the forecast reference time for that item (2025-05-09T18) to query for the full series of hourly forecasts that were generated at that time."
243+
"Now, use the forecast reference time for that item (2025-05-09T18) to query the whole series of hourly forecasts generated at that time."
204244
]
205245
},
206246
{
@@ -336,7 +376,7 @@
336376
"id": "2576e84b-cd31-431f-86d3-13e750a6178e",
337377
"metadata": {},
338378
"source": [
339-
"Now pick three variables that will be useful for evaluating hazardous wildfire conditions and print some information about them from the STAC metadata."
379+
"Pick three variables useful for evaluating hazardous wildfire conditions and print some information about them from the STAC metadata."
340380
]
341381
},
342382
{
@@ -392,9 +432,9 @@
392432
"id": "c93fefcb",
393433
"metadata": {},
394434
"source": [
395-
"The HRRR predictions are distributed in the GRIB2 format. GRIB2 files have many different layers encoded as \"messages\" that are strung together. Fortunately each GRIB file is accompanied by a .grib.idx index file that describes the byte ranges for each of the messages/layers. We can use the /vsisubfile and GRIB drivers from GDAL to perform targeted reads on the raw files.\n",
435+
"The HRRR predictions are distributed in the GRIB2 format. GRIB2 files have many different layers encoded as \"messages\" strung together. Fortunately, each GRIB file is accompanied by a .grib.idx index file that describes the byte ranges for each of the messages/layers. We can use the /vsisubfile and GRIB drivers from GDAL to perform targeted reads on the raw files.\n",
396436
"\n",
397-
"The following functions are used use the STAC item metadata to load a specific set of variables from the GRIB assets into an `xarray.DataArray`:"
437+
"The following functions load the STAC item metadata into an xarray of a specific set of variables from the GRIB assets into a `xarray.DataArray`:"
398438
]
399439
},
400440
{
@@ -1173,7 +1213,7 @@
11731213
"id": "ee29c5f3-ebe2-4e26-9c07-43c2b8df4c37",
11741214
"metadata": {},
11751215
"source": [
1176-
"These data can be viewed as a red/green/blue composite image with data from each variable expressed in a different channel of the image. To prepare the data for visualization, we must normalize it scale between 0 and 1."
1216+
"These data can be viewed as a red/green/blue composite image with data from each variable expressed in a different image channel. To prepare the data for visualization, we must normalize it to scale between 0 and 1."
11771217
]
11781218
},
11791219
{
@@ -1364,17 +1404,18 @@
13641404
"id": "0324fc10-7a70-4328-b4d1-1aedb5215c47",
13651405
"metadata": {},
13661406
"source": [
1367-
"The gif below shows the 48-hour forecast of surface temperature, wind speed, and relative humidity.\n",
1407+
"The GIF below shows the 48-hour surface temperature, wind speed, and relative humidity forecast.\n",
13681408
"\n",
13691409
"**Color interpretation**:\n",
1370-
"- red: hot, low wind speed and relative humidity\n",
1371-
"- green: windy, low temperature and relative humidity\n",
1372-
"- blue: humid, low temperature and wind speed\n",
1410+
"\n",
1411+
"- red: hot, low wind speed, and relative humidity\n",
1412+
"- green: windy, low temperature, and relative humidity\n",
1413+
"- blue: humid, low temperature, and wind speed\n",
13731414
"- yellow: hot and windy, low relative humidity\n",
13741415
"- fuschia (pink): hot and humid, low wind speed\n",
13751416
"- cyan: windy and humid, low temperature\n",
1376-
"- white: hot, windy and humid!\n",
1377-
"- black: cool, dry and low wind speed "
1417+
"- white: hot, windy, and humid!\n",
1418+
"- black: cool, dry, and low wind speed"
13781419
]
13791420
},
13801421
{
@@ -1476,9 +1517,9 @@
14761517
"id": "67fd6627-2131-413d-9acf-dd9957502b88",
14771518
"metadata": {},
14781519
"source": [
1479-
"Now we need to put the current forecast into context with recent conditions to identify where things might be unusually hot, dry, and windy.\n",
1520+
"We need to contextualize the current forecast with recent conditions to identify where things might be unusually hot, dry, and windy.\n",
14801521
"\n",
1481-
"Generate STAC items for the FH0 (analysis) conditions for the last 30 days. This will give us 720 observations of conditions at the moment the forecast was generated that we can use to develop a baseline expectation for these variables during a normal day."
1522+
"Generate STAC items for the FH0 (analysis) conditions for the last 30 days. This will give us 720 observations of conditions when the forecast was generated that we can use to develop a baseline expectation for these variables during a typical day."
14821523
]
14831524
},
14841525
{
@@ -1540,7 +1581,7 @@
15401581
"id": "3d571cc2-da9a-4aec-9bb8-2a19b1064aa8",
15411582
"metadata": {},
15421583
"source": [
1543-
"Build a datacube similar to the one we built for the forecast data. This could take a while because you are reading metadata for thousands of GRIB2 layers."
1584+
"Build a data cube similar to the one we built for the forecast data. This could take a while because you read metadata for thousands of GRIB2 layers."
15441585
]
15451586
},
15461587
{
@@ -2242,7 +2283,7 @@
22422283
"id": "ad18b3c6-127b-485a-9725-8c27f200d37f",
22432284
"metadata": {},
22442285
"source": [
2245-
"We will form a baseline expectation for climatic conditions by calculating the median observed value of each variable for each hour in the day for the last 30 days. This array can be compared to the forecasted values at each hour of the forecast to identify extreme conditions in the forecast."
2286+
"We will form a baseline expectation for climatic conditions by calculating the median observed value of each variable for each hour in the day for the last 30 days. This array can be compared to the forecasted values at each forecast hour to identify extreme conditions."
22462287
]
22472288
},
22482289
{
@@ -2264,7 +2305,7 @@
22642305
"id": "0f24ec30-63c4-4597-96cb-8158819d6d20",
22652306
"metadata": {},
22662307
"source": [
2267-
"To enable comparison to the forecast values, expand the median hourly observations to match the dimensions of the forecast array. This way we can easily subtract the \"expected\" value from the actual forecast value."
2308+
"Expand the median hourly observations to match the dimensions of the forecast array to enable comparison to the forecast values. This way, we can easily subtract the \"expected\" value from the actual forecast value."
22682309
]
22692310
},
22702311
{
@@ -2305,11 +2346,12 @@
23052346
"metadata": {},
23062347
"source": [
23072348
"To visualize the difference between forecast and expectation and highlight areas that might be experiencing higher-than-normal wildfire risk, we can rescale the difference array to highlight the differences that we care about:\n",
2308-
"- higher than normal temperature\n",
2309-
"- higher than normal wind speed\n",
2310-
"- lower than normal relative humidity\n",
23112349
"\n",
2312-
"When we rescale the data for visualization, higher than normal temps will be bright red, higher than normal winds will be bright green, and lower relative humidity will be less blue (normal relative humidity is bright blue)."
2350+
"- Higher than normal temperature\n",
2351+
"- Higher than normal wind speed\n",
2352+
"- Lower than normal relative humidity\n",
2353+
"\n",
2354+
"When we rescale the data for visualization, higher-than-normal temperatures will be bright red, higher-than-normal winds will be bright green, and lower relative humidity will be less blue (normal relative humidity is bright blue)."
23132355
]
23142356
},
23152357
{
@@ -2448,9 +2490,9 @@
24482490
"source": [
24492491
"### Define risk thresholds\n",
24502492
"\n",
2451-
"Now define some thresholds that we can use to determine if a pixel is under red flag conditions or not.\n",
2493+
"Now, define some thresholds that we can use to determine whether a pixel is under red flag conditions.\n",
24522494
"\n",
2453-
"**Note:** This is just a demonstration of how you could use this dataset to summarize forecast conditions against recent trends, this is not a recommended approach for assessing wildfire hazard specifically."
2495+
"**Note:** This is just a demonstration of using this dataset to summarize forecast conditions against recent trends; this is not a recommended approach for assessing wildfire hazard specifically."
24542496
]
24552497
},
24562498
{
@@ -2551,7 +2593,7 @@
25512593
"id": "189d0de6-da23-4f50-a29e-607f00dff728",
25522594
"metadata": {},
25532595
"source": [
2554-
"Based on the distribution of values let's try setting a threshold of 7 degrees (K) higher-than-normal temperature, 3 m/s higher-than-normal wind speed, and 15% lower-than-normal relative humidity."
2596+
"Based on the distribution of values, let's try setting a threshold of 7 degrees (K) higher-than-normal temperature, 3 m/s higher-than-normal wind speed, and 15% lower-than-normal relative humidity."
25552597
]
25562598
},
25572599
{
@@ -2621,7 +2663,7 @@
26212663
"id": "8374383b-edb7-44b2-a6da-bebc2f294497",
26222664
"metadata": {},
26232665
"source": [
2624-
"Now evaluate the cumulative risk of hazardous conditions over the next 48 hours by calculating the proportion of hourly forecasts where the risk thresholds are met."
2666+
"Let's evaluate the cumulative risk of hazardous conditions over the next 48 hours by calculating the proportion of hourly forecasts where the risk thresholds are met."
26252667
]
26262668
},
26272669
{
@@ -2673,7 +2715,7 @@
26732715
"id": "0cdffc80-0023-4044-850d-716ede45c240",
26742716
"metadata": {},
26752717
"source": [
2676-
"Finally, take the summarized risk array and plot it on an interactive map!"
2718+
"Finally, plot the summarized risk array on an interactive map!"
26772719
]
26782720
},
26792721
{
@@ -2886,11 +2928,44 @@
28862928
"\n",
28872929
"m"
28882930
]
2931+
},
2932+
{
2933+
"cell_type": "markdown",
2934+
"id": "65787d8d",
2935+
"metadata": {},
2936+
"source": [
2937+
"---\n",
2938+
"\n",
2939+
"### ⏭️ Next Steps\n",
2940+
"\n",
2941+
"This notebook provides a starting point for using short-term forecast data to assess wildfire risk conditions. To expand on this analysis, you could:\n",
2942+
"\n",
2943+
"- Incorporate fire weather indices like the Fosberg Fire Weather Index (FFWI)\n",
2944+
"- Overlay recent fire perimeters or MODIS active fire detections\n",
2945+
"- Add vegetation and fuel type layers for more context\n",
2946+
"- Trigger alerts or visualizations when conditions exceed risk thresholds\n",
2947+
"- Run the workflow operationally for daily situational awareness\n",
2948+
"\n",
2949+
"---\n",
2950+
"\n",
2951+
"### 🧰 Supporting Materials\n",
2952+
"\n",
2953+
"- [HRRR on the Planetary Computer](https://planetarycomputer.microsoft.com/dataset/hrrr)\n",
2954+
"- [Pystac-Client documentation](https://pystac-client.readthedocs.io/)\n",
2955+
"- [Xarray documentation](https://docs.xarray.dev/)\n",
2956+
"- [Planetary Computer Hub](https://planetarycomputer.microsoft.com/)"
2957+
]
2958+
},
2959+
{
2960+
"cell_type": "markdown",
2961+
"id": "bee90887",
2962+
"metadata": {},
2963+
"source": []
28892964
}
28902965
],
28912966
"metadata": {
28922967
"kernelspec": {
2893-
"display_name": "Python 3 (ipykernel)",
2968+
"display_name": ".venv",
28942969
"language": "python",
28952970
"name": "python3"
28962971
},
@@ -2904,7 +2979,7 @@
29042979
"name": "python",
29052980
"nbconvert_exporter": "python",
29062981
"pygments_lexer": "ipython3",
2907-
"version": "3.13.0"
2982+
"version": "3.11.9"
29082983
}
29092984
},
29102985
"nbformat": 4,

0 commit comments

Comments
 (0)