|
| 1 | +# Copyright 2025 Google LLC |
| 2 | +# |
| 3 | +# Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | +# you may not use this file except in compliance with the License. |
| 5 | +# You may obtain a copy of the License at |
| 6 | +# |
| 7 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | +# |
| 9 | +# Unless required by applicable law or agreed to in writing, software |
| 10 | +# distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | +# See the License for the specific language governing permissions and |
| 13 | +# limitations under the License. |
| 14 | + |
| 15 | +import bigframes.bigquery as bbq |
| 16 | +import bigframes.pandas as bpd |
| 17 | + |
| 18 | +# Step 1: Select inputs from datasets that we've subscribed to |
| 19 | +wildfire_raster = bpd.read_gbq("wildfire_risk_to_community_v0_mosaic.fire")[ |
| 20 | + "assets.image.href" |
| 21 | +] |
| 22 | +places = bpd.read_gbq("bigquery-public-data.geo_us_census_places.places_colorado")[ |
| 23 | + ["place_id", "place_name", "place_geom"] |
| 24 | +] |
| 25 | +places = places.rename(columns={"place_geom": "geo"}) |
| 26 | + |
| 27 | +# Step 2: Compute the weather forecast using WeatherNext Graph forecast data |
| 28 | +weather_forecast = bpd.read_gbq("weathernext_graph_forecasts.59572747_4_0") |
| 29 | +weather_forecast = weather_forecast[ |
| 30 | + weather_forecast["init_time"] == "2025-04-28 00:00:00+00:00" |
| 31 | +] |
| 32 | +weather_forecast = weather_forecast.explode("forecast") |
| 33 | +wind_speed = ( |
| 34 | + weather_forecast["forecast"]["10m_u_component_of_wind"] ** 2 |
| 35 | + + weather_forecast["forecast"]["10m_v_component_of_wind"] ** 2 |
| 36 | +) ** 0.5 |
| 37 | +weather_forecast = weather_forecast.assign(wind_speed=wind_speed) |
| 38 | +weather_forecast = weather_forecast[weather_forecast["forecast"]["hours"] < 24] |
| 39 | +weather_forecast = weather_forecast.merge( |
| 40 | + places, how="inner", left_on="geography_polygon", right_on="geo" |
| 41 | +) |
| 42 | +weather_forecast = weather_forecast.groupby("place_id").agg( |
| 43 | + place_name=("place_name", "first"), |
| 44 | + geo=("geo", "first"), |
| 45 | + average_wind_speed=("wind_speed", "mean"), |
| 46 | + maximum_wind_speed=("wind_speed", "max"), |
| 47 | +) |
| 48 | + |
| 49 | +# Step 3: Combine with wildfire risk for each community |
| 50 | +wildfire_risk = weather_forecast.assign( |
| 51 | + wildfire_likelihood=bbq.st_regionstats( |
| 52 | + weather_forecast["geo"], |
| 53 | + wildfire_raster, |
| 54 | + "BP", |
| 55 | + options={"scale": 1000}, |
| 56 | + )["mean"], |
| 57 | + wildfire_consequence=bbq.st_regionstats( |
| 58 | + weather_forecast["geo"], |
| 59 | + wildfire_raster, |
| 60 | + "CRPS", |
| 61 | + options={"scale": 1000}, |
| 62 | + )["mean"], |
| 63 | +) |
| 64 | + |
| 65 | +# Step 4: Compute a simple composite index of relative wildfire risk. |
| 66 | +relative_risk = ( |
| 67 | + wildfire_risk["wildfire_likelihood"].rank(pct=True) |
| 68 | + + wildfire_risk["wildfire_consequence"].rank(pct=True) |
| 69 | + + wildfire_risk["average_wind_speed"].rank(pct=True) |
| 70 | +) / 3 * 100 |
| 71 | +wildfire_risk = wildfire_risk.assign(relative_risk=relative_risk) |
0 commit comments