Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding 0.8 1.2 GWLs into cava_data options #481

Merged
merged 15 commits into from
Jan 6, 2025
21 changes: 21 additions & 0 deletions climakitae/core/constants.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,42 @@
# constants.py
"""This module defines constants across the codebase"""

# global warming levels available on AE
WARMING_LEVELS = [0.8, 1.2, 1.5, 2.0, 2.5, 3.0, 4.0]

# shared socioeconomic pathways (IPCC)
SSPS = [
"SSP 2-4.5",
"SSP 3-7.0",
"SSP 5-8.5",
]

# WRF models that have a-priori bias adjustment
WRF_BA_MODELS = [
"WRF_EC-Earth3_r1i1p1f1",
"WRF_MPI-ESM1-2-HR_r3i1p1f1",
"WRF_TaiESM1_r1i1p1f1",
"WRF_MIROC6_r1i1p1f1",
"WRF_EC-Earth3-Veg_r1i1p1f1",
]

# WRF models that do not have a-priori bias adjustment
NON_WRF_BA_MODELS = [
"WRF_FGOALS-g3_r1i1p1f1",
"WRF_CNRM-ESM2-1_r1i1p1f2",
"WRF_CESM2_r11i1p1f1",
]

# WRF models that do not reach 0.8°C GWL
WRF_NO_0PT8_GWL_MODELS = ["WRF_EC-Earth3-Veg_r1i1p1f1_historical+ssp370"]

# LOCA models that do not reach 0.8°C GWL
LOCA_NO_0PT8_GWL_MODELS = [
"LOCA2_EC-Earth3_r4i1p1f1_historical+ssp245",
"LOCA2_EC-Earth3_r4i1p1f1_historical+ssp370",
"LOCA2_EC-Earth3_r4i1p1f1_historical+ssp585",
"LOCA2_EC-Earth3-Veg_r3i1p1f1_historical+ssp245",
"LOCA2_EC-Earth3-Veg_r3i1p1f1_historical+ssp370",
"LOCA2_EC-Earth3-Veg_r3i1p1f1_historical+ssp585",
"LOCA2_EC-Earth3-Veg_r5i1p1f1_historical+ssp245",
]
57 changes: 52 additions & 5 deletions climakitae/explore/vulnerability.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@
from climakitae.core.data_export import export
from climakitae.core.data_interface import DataParameters
from climakitae.core.data_load import load
from climakitae.core.constants import WRF_BA_MODELS, SSPS
from climakitae.core.constants import (
WRF_BA_MODELS,
SSPS,
WRF_NO_0PT8_GWL_MODELS,
LOCA_NO_0PT8_GWL_MODELS,
)
from climakitae.explore import warming_levels
from climakitae.explore.threshold_tools import (
get_block_maxima,
Expand Down Expand Up @@ -42,7 +47,7 @@ def _export_no_e(da, filename, format):


def _filter_ba_models(data, downscaling_method, wrf_bias_adjust, historical_data):
"""Filters the data for the bias adjusted simulations, if desired."""
"""Filters the WRF data for the bias adjusted simulations, if desired."""
if (
downscaling_method == "Dynamical"
and wrf_bias_adjust
Expand All @@ -58,6 +63,33 @@ def _filter_ba_models(data, downscaling_method, wrf_bias_adjust, historical_data
if any(s in sim for s in WRF_BA_MODELS)
]
)
print(f"Filtering WRF data for bias-adjusted simulations.")
return data


def _filter_hist_gwl_models(data, downscaling_method, approach, warming_level):
"""Filters the data to remove simulation(s) that do not reach 0.8°C in GWL selection"""

# Filter for viable 0.8°C simulations
if downscaling_method == "Dynamical":
data = data.sel(
simulation=[
sim
for sim in data.simulation.values
if sim not in WRF_NO_0PT8_GWL_MODELS
]
)
elif downscaling_method == "Statistical":
data = data.sel(
simulation=[
sim
for sim in data.simulation.values
if sim not in LOCA_NO_0PT8_GWL_MODELS
]
)
print(
f"Not all {downscaling_method} simulations have data for {warming_level}°C. Removing invalid simulations. Please see Guidance materials for more information."
) # guidance forthcoming
return data


Expand Down Expand Up @@ -282,7 +314,7 @@ class CavaParams(param.Parameterized):
)
warming_level = param.ObjectSelector(
default=1.5,
objects=[None, 1.5, 2.0, 2.5, 3.0],
objects=[None, 0.8, 1.2, 1.5, 2.0, 2.5, 3.0],
doc="Warming level for analysis",
)
wrf_bias_adjust = param.Boolean(default=True, doc="Flag for WRF bias adjustment")
Expand Down Expand Up @@ -358,12 +390,14 @@ def validate_params(self):

# Validating warming level inputs
if self.approach == "Warming Level" and self.warming_level not in [
0.8,
1.2,
1.5,
2.0,
2.5,
3.0,
]:
errors.append("Warming level must be 1.5, 2.0, 2.5, or 3.0.")
errors.append("Warming level must be 0.8, 1.2, 1.5, 2.0, 2.5, or 3.0.")

# Validating that only one of heat_idx_threshold, percentile, or one_in_x is passed
if (
Expand Down Expand Up @@ -446,7 +480,7 @@ def get_names(self):
elif self.approach == "Warming Level":
wl_str = (
str(int(self.warming_level))
if self.warming_level not in [1.5, 2.5]
if self.warming_level not in [0.8, 1.2, 1.5, 2.5]
else str(self.warming_level).replace(".", "pt")
)
approach_str = f"{wl_str}degreeWL"
Expand Down Expand Up @@ -539,6 +573,8 @@ def cava_data(
Type of historical data, default is "Historical Climate".
ssp_data : str, optional
Shared Socioeconomic Pathway data, default is "SSP 3-7.0".
warming_level : str, optional
Global warming levels, default is 1.5°C.
metric_calc : str, optional
Metric calculation type (e.g., 'mean', 'max', 'min') for supported metrics. Default is "max"
heat_idx_threshold : float
Expand Down Expand Up @@ -636,6 +672,12 @@ def cava_data(
data_pts, downscaling_method, wrf_bias_adjust, historical_data
)

if approach == "Warming Level" and warming_level == 0.8:
# Filter out inappropriate models for historical GWL baseline
data = _filter_hist_gwl_models(
data, downscaling_method, approach, warming_level
)

else:
data_pts = []
for idx, loc in input_locations.iterrows():
Expand All @@ -659,6 +701,11 @@ def cava_data(
data, downscaling_method, wrf_bias_adjust, historical_data
)

if approach == "Warming Level" and warming_level == 0.8:
# Filter out inappropriate models for historical GWL baseline
data = _filter_hist_gwl_models(
data, downscaling_method, approach, warming_level
)
data_pts.append(data)

if historical_data == "Historical Reconstruction":
Expand Down
9 changes: 5 additions & 4 deletions climakitae/explore/warming.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class WarmingLevels:

def __init__(self, **params):
self.wl_params = WarmingLevelChoose()
# self.warming_levels = ["1.5", "2.0", "3.0", "4.0"]
# self.warming_levels = ["0.8", "1.2", "1.5", "2.0", "3.0", "4.0"]

def find_warming_slice(self, level, gwl_times):
"""
Expand Down Expand Up @@ -79,6 +79,7 @@ def calculate(self):
# manually reset to all SSPs, in case it was inadvertently changed by
# temporarily have ['Dynamical','Statistical'] for downscaling_method
self.wl_params.scenario_ssp = SSPS

# Postage data and anomalies
self.catalog_data = self.wl_params.retrieve()
self.catalog_data = self.catalog_data.stack(all_sims=["simulation", "scenario"])
Expand Down Expand Up @@ -170,7 +171,7 @@ def clean_warm_data(warm_data):
return warm_data


def get_sliced_data(y, level, years, months=np.arange(1, 13), window=15, anom="Yes"):
def get_sliced_data(y, level, years, months=np.arange(1, 13), window=15, anom="No"):
"""Calculating warming level anomalies.

Parameters
Expand Down Expand Up @@ -288,7 +289,7 @@ class WarmingLevelChoose(DataParameters):
anom = param.Selector(
default="Yes",
objects=["Yes", "No"],
doc="Return an anomaly \n(difference from historical reference period)?",
doc="Return a delta signal \n(difference from historical reference period)?",
)

def __init__(self, *args, **params):
Expand All @@ -303,7 +304,7 @@ def __init__(self, *args, **params):
self.variable = "Air Temperature at 2m"

# Choosing specific warming levels
self.warming_levels = ["1.5", "2.0", "3.0", "4.0"]
self.warming_levels = ["0.8", "1.2", "1.5", "2.0", "3.0", "4.0"]
self.months = np.arange(1, 13)

# Location defaults
Expand Down
Loading