I been trying to use NicheMapR to model the thermoregulation and water balance of the Mexican salamander Isthmura belli under current and future climate scenarios. The current scenario model runs successfully using NCEP data via micro_ncep.
For the future scenarios, my initial approach was to download CMIP6 data for various SSPs and time periods using geodata::cmip6_tile. I then calculated the mean temperature delta between the future CMIP6 data and a historical baseline. I attempted to apply this delta to the temperature values within the micro object generated by micro_ncep before running the ectotherm function.
However, all my future scenario model runs (for SSP1-2.6, SSP3-7.0, and SSP5-8.5 across three time periods: 2041-2060, 2061-2080, and 2081-2100) are returning identical outputs. Upon debugging, it appears that the micro object from the current scenario is not being correctly modified for each iteration of the loop, leading to the same input for every future run.
The issue is that CMIP6 data is static, representing long-term means. It cannot be directly used to generate a daily-time step micro object, which is required by ectotherm. As far as I know, the NicheMapR documentation and common practices suggest using the micro_clim function to generate a full microclimate dataset based on a time series of daily weather variables, but I'm not sure how to feed the CMIP6 climate change anomalies (the delta values) into a daily time series like the NCEP data.
What is the correct and most robust method to project the CMIP6 anomalies onto a NCEP-like daily time series for use in NicheMapR? Specifically, how should I properly update the micro object within a loop to reflect the different future climate scenarios, including changes in temperature, precipitation, and solar radiation, while maintaining the daily variability? Any guidance on the recommended workflow for creating future microclimate inputs would be greatly appreciated. I attach my code. Thank you in advance.
# Load packages
library(NicheMapR)
library(geodata)
library(terra)
# Current scenario
loc <- c(-103.9456, 19.4453)
dstart <- "01/01/2023"
dfinish <- "31/12/2023"
altt <- 2440
refl <- 0.10
slr <- 0.96
runshade <- 1
runmoist <- 1
dep <- c(0, 2.5, 5, 10, 15, 20, 30, 50, 100, 200)
soiltype <- 4
params <- list(
ID = "salamander_default",
shape = 4,
mass = 0.029337,
pct_wet = 0.85,
A_max = 0.9,
A_min = 0.9,
Z_b = 0.02,
sub_resist = 1,
T_B_min = 10.2,
T_F_min = 10.2,
T_F_max = 25.3,
T_pref = 19.34,
CT_max = 30,
CT_min = 4.78,
mindepth = 0.01,
maxdepth = 0.80,
shade_seek = 1,
burrow = 1,
climb = 0,
nocturn = 1,
crepus = 1,
diurn = 0
)
# Run current model
micro_current <- micro_ncep(loc = loc, dstart = dstart, dfinish = dfinish)
salamander_current <- ectotherm(micro = micro_current, params = params)
salamander_current_data <- as.data.frame(salamander_current$environ)
# Future scenarios setup
ssps <- c("126", "370", "585")
time_periods <- c("2041-2060", "2061-2080", "2081-2100")
future_results <- data.frame(
scenario = character(),
time_period = character(),
mean_body_temp = numeric(),
total_active_hours = numeric(),
average_daily_water_loss = numeric()
)
# Future scenarios loop
for (ssp in ssps) {
for (time_period in time_periods) {
message(paste0("Running SSP ", ssp, " period ", time_period, " ..."))
# Download future CMIP6 data
cmip_future <- cmip6_tile(
lon = loc[1], lat = loc[2],
model = "CNRM-CM6-1", ssp = ssp,
time = time_period, var = c("tmax", "tmin", "prec", "srad", "wind"), path = tempdir()
)
# Download baseline CMIP6 data (same time period as NCEP)
cmip_baseline <- cmip6_tile(
lon = loc[1], lat = loc[2],
model = "CNRM-CM6-1", ssp = ssp,
time = "2021-2040", var = c("tmax", "tmin", "prec", "srad", "wind"), path = tempdir()
)
# Calculate daily weather deltas from CMIP6 data
temp_delta_vec <- global(cmip_future$tmax, mean, na.rm = TRUE) - global(cmip_baseline$tmax, mean, na.rm = TRUE)
prec_delta_vec <- global(cmip_future$prec, mean, na.rm = TRUE) - global(cmip_baseline$prec, mean, na.rm = TRUE)
srad_delta_vec <- global(cmip_future$srad, mean, na.rm = TRUE) / global(cmip_baseline$srad, mean, na.rm = TRUE)
# Apply deltas to NCEP data
micro_future <- micro_current
micro_future$metout[, 'TAREF'] <- micro_current$metout[, 'TAREF'] + as.vector(temp_delta_vec)
micro_future$metout[, 'PCT_PREC'] <- micro_current$metout[, 'PCT_PREC'] + as.vector(prec_delta_vec)
micro_future$metout[, 'SRAD'] <- micro_current$metout[, 'SRAD'] * as.vector(srad_delta_vec)
# Run ectotherm model for future scenario
salamander_future <- ectotherm(micro = micro_future, params = params)
# Extract and store results
future_data <- as.data.frame(salamander_future$environ)
mean_temp <- mean(future_data$TC, na.rm = TRUE)
active_hours <- sum(future_data$ACT > 0, na.rm = TRUE)
mass_bal_future <- as.data.frame(salamander_future$masbal)
mass_bal_future$H2O_total <- mass_bal_future$H2OCut_g + mass_bal_future$H2OResp_g
daily_water_loss_future <- aggregate(H2O_total ~ as.Date(micro_future$dates), data = mass_bal_future, sum)
avg_water_loss <- mean(daily_water_loss_future$H2O_total, na.rm = TRUE)
future_results <- rbind(future_results, data.frame(
scenario = paste0("SSP", ssp),
time_period = time_period,
mean_body_temp = mean_temp,
total_active_hours = active_hours,
average_daily_water_loss = avg_water_loss
))
}
}
# Check results
print(future_results)