|
| 1 | +rm(list=ls()) |
| 2 | + |
| 3 | +library(tidyverse) |
| 4 | +library(ggdist) |
| 5 | +library(ggh4x) |
| 6 | +library(reshape2) |
| 7 | +library(SpatialSablefishAssessment) |
| 8 | +library(tictoc) |
| 9 | +library(doParallel) |
| 10 | + |
| 11 | +# Change to wherever your local copy of afscOM is |
| 12 | +library(devtools) |
| 13 | +afscOM_dir <- "~/Desktop/Projects/afscOM" |
| 14 | +sablefishMSE_dir <- here::here() |
| 15 | + |
| 16 | +devtools::load_all(afscOM_dir) |
| 17 | + |
| 18 | +lapply(list.files("R", full.names = TRUE), source) |
| 19 | + |
| 20 | +#' 1. Set up the OM by defining demographic parameters |
| 21 | +#' model options (such as options governing the observation |
| 22 | +#' processes), and OM initial conditons |
| 23 | +nyears <- 110 |
| 24 | + |
| 25 | +sable_om <- readRDS("data/sablefish_om_big.RDS") # Read this saved OM from a file |
| 26 | +sable_om$model_options$fleet_apportionment <- matrix(c(0.80, 0.20), nrow=nrow(sable_om$model_options$fleet_apportionment), ncol=2, byrow=TRUE) |
| 27 | +sable_om$model_options$obs_pars$catch_cv <- c(1e-5, 1e-5, 1e-5, 1e-5) |
| 28 | + |
| 29 | +# Source all available OM and HCR objects |
| 30 | +source("dev/oms.R") |
| 31 | +source("dev/hcrs.R") |
| 32 | + |
| 33 | +#' 3. Run the closed-loop MSE simulation |
| 34 | +#' A single MSE simulation can be run using the `run_mse(...)` |
| 35 | +#' function, while multiple MSE simulations can be run (serially) |
| 36 | +#' using the `run_mse_multiple(...)` function. |
| 37 | +#' |
| 38 | +#' It is recommended to always use `run_mse_multiple(...)` even |
| 39 | +#' when only a single MSE simulation is required. |
| 40 | +#' |
| 41 | + |
| 42 | +set.seed(895) |
| 43 | +nsims <- 200 |
| 44 | +seed_list <- sample(1:(100*nsims), nsims) # Draw 10 random seeds |
| 45 | + |
| 46 | +mse_options_base <- setup_mse_options() |
| 47 | +mse_options <- mse_options_base |
| 48 | +mse_options$n_spinup_years <- 54 |
| 49 | +mse_options$recruitment_start_year <- 54 |
| 50 | +mse_options$n_proj_years <- 75 |
| 51 | + |
| 52 | +mse_options_list <- listN(mse_options) |
| 53 | + |
| 54 | + |
| 55 | +om_list <- listN(om_rand_recruit, om_bh_recruit, om_bhcyclic_recruit, om_immcrash_recruit) |
| 56 | +hcr_list <- listN( |
| 57 | + mp_f40, mp_f50, |
| 58 | + mp_5perc, mp_10perc, |
| 59 | + mp_15cap, mp_25cap, |
| 60 | + mp_f50chr, |
| 61 | + mp_pfmc4010, mp_bcsable, |
| 62 | + mp_f00chr |
| 63 | +) |
| 64 | + |
| 65 | + |
| 66 | +tic() |
| 67 | +model_runs <- run_mse_multiple( |
| 68 | + om_list, |
| 69 | + hcr_list, |
| 70 | + seed_list, |
| 71 | + nyears=100, |
| 72 | + mse_options_list=mse_options_list, |
| 73 | + diagnostics = FALSE, |
| 74 | + save=TRUE |
| 75 | +) |
| 76 | +toc() |
| 77 | + |
| 78 | + |
| 79 | + # Data Processinf |
| 80 | +filetype <- ".jpeg" |
| 81 | +figures_dir <- file.path(here::here(), "figures") |
| 82 | +width_small <- 12 |
| 83 | +height_small <- 8 |
| 84 | + |
| 85 | +publication_hcrs <- c("F40", "F50", "F40 +/- 5%", "F40 +/- 10%", "15k Harvest Cap", "25k Harvest Cap", "Constant F50", "PFMC 40-10", "British Columbia", "No Fishing") |
| 86 | +publication_oms <- c("Random Recruitment", "Beverton-Holt Cyclic Recruitment", "Immediate Crash Recruitment") |
| 87 | +publication_metrics = c("Annual Catch", "Catch AAV", "SSB", "Average Age", "Proportion of Years with Low SSB") |
| 88 | + |
| 89 | +mse_runs <- get_saved_model_runs2(om_order=publication_oms, hcr_order=publication_hcrs) |
| 90 | +model_runs <- mse_runs$model_runs |
| 91 | +extra_columns <- mse_runs$extra_columns2 |
| 92 | + |
| 93 | +interval_widths <- c(0.50, 0.80) |
| 94 | +common_trajectory <- 54 |
| 95 | +time_horizon <- c(55, 130) |
| 96 | + |
| 97 | +hcr_colors <- set_hcr_colors2(publication_hcrs) |
| 98 | + |
| 99 | + |
| 100 | +### Spawning Biomass and Catch Plots |
| 101 | +ssb_data <- get_ssb_biomass(model_runs, extra_columns, sable_om$dem_params, hcr_filter=publication_hcrs, om_filter=publication_oms) |
| 102 | +plot_ssb(ssb_data, v1="hcr", v2="om", v3=NA, common_trajectory=common_trajectory, show_est = FALSE) |
| 103 | +ggsave(filename=file.path(figures_dir, paste0("ssb", filetype)), width=width_small, height=height_small, units=c("in")) |
| 104 | + |
| 105 | +plot_relative_ssb(ssb_data, v1="hcr", v2="om", common_trajectory = common_trajectory, base_hcr = "No Fishing") |
| 106 | +ggsave(filename=file.path(figures_dir, paste0("rel_ssb", filetype)), width=width_small, height=height_small, units=c("in")) |
| 107 | + |
| 108 | +catch_data <- get_landed_catch(model_runs, extra_columns, hcr_filter=publication_hcrs, om_filter=publication_oms) |
| 109 | +plot_landed_catch(catch_data, v1="hcr", v2="om", common_trajectory = common_trajectory) |
| 110 | +ggsave(filename=file.path(figures_dir, paste0("catch", filetype)), width=width_small, height=height_small, units=c("in")) |
| 111 | + |
| 112 | +plot_ssb_catch( |
| 113 | + ssb_data, |
| 114 | + catch_data, |
| 115 | + v1="hcr", |
| 116 | + v2="om", |
| 117 | + common_trajectory = common_trajectory |
| 118 | +) |
| 119 | +ggsave(filename=file.path(here::here(), "figures", "ssb_catch.jpeg"), width=16, height=10, units="in") |
| 120 | + |
| 121 | + |
| 122 | +### Performance Metrics |
| 123 | +performance_metrics <- performance_metric_summary( |
| 124 | + model_runs, |
| 125 | + extra_columns, |
| 126 | + sable_om$dem_params, |
| 127 | + ref_naa, |
| 128 | + hcr_filter=publication_hcrs, |
| 129 | + om_filter=publication_oms, |
| 130 | + interval_widths=interval_widths, |
| 131 | + time_horizon = time_horizon, |
| 132 | + extra_filter = NULL, |
| 133 | + relative=NULL, |
| 134 | + summarise_by=c("om", "hcr"), |
| 135 | + summary_out = TRUE, |
| 136 | + metric_list = c("avg_catch", "avg_variation", "avg_ssb", "avg_age", "prop_years_lowssb") |
| 137 | +) |
| 138 | +perf_data <- performance_metrics$perf_data %>% |
| 139 | + mutate( |
| 140 | + name = factor(name, levels=publication_metrics) |
| 141 | + ) %>% |
| 142 | + group_by(.width, om, name) %>% |
| 143 | + scale_and_rank("median") |
| 144 | + |
| 145 | +plot_performance_metric_summary(perf_data, v1="hcr", v2="om")+ |
| 146 | + theme( |
| 147 | + panel.spacing.x = unit(0.75, "cm"), |
| 148 | + ) |
| 149 | +ggsave(filename=file.path(here::here(), "figures", paste0("performance2", filetype)), width=18, height=12, units="in") |
| 150 | + |
| 151 | +### Resilience Metrics |
| 152 | +resilience_metrics <- performance_metric_summary( |
| 153 | + model_runs, |
| 154 | + extra_columns, |
| 155 | + sable_om$dem_params, |
| 156 | + ref_naa, |
| 157 | + hcr_filter=publication_hcrs, |
| 158 | + om_filter=c("Immediate Crash Recruitment"), |
| 159 | + interval_widths=interval_widths, |
| 160 | + time_horizon = time_horizon, |
| 161 | + extra_filter = NULL, |
| 162 | + relative=NULL, |
| 163 | + summarise_by=c("om", "hcr"), |
| 164 | + summary_out = TRUE, |
| 165 | + metric_list = c("crash_time", "recovery_time") |
| 166 | +) |
| 167 | + |
| 168 | +resilience_data <- resilience_metrics$perf_data %>% |
| 169 | + add_row( |
| 170 | + om = "Immediate Crash Recruitment", |
| 171 | + hcr = "No Fishing", |
| 172 | + .width = c(0.5, 0.8), |
| 173 | + .point = "median", |
| 174 | + .interval = "qi", |
| 175 | + name = "Crash Time", |
| 176 | + median = Inf, lower = Inf, upper = Inf |
| 177 | + ) %>% |
| 178 | + mutate( |
| 179 | + om = factor(om), |
| 180 | + hcr = factor(hcr, levels=publication_hcrs), |
| 181 | + name = factor(name, levels=c("Crash Time", "Recovery Time")) |
| 182 | + ) %>% |
| 183 | + group_by(.width, om, name) %>% |
| 184 | + scale_and_rank("median") |
| 185 | + |
| 186 | +plot_performance_metric_summary(resilience_data)+ |
| 187 | + ggh4x::facetted_pos_scales( |
| 188 | + x = list( |
| 189 | + scale_x_continuous("Year", limits=c(0, 20)), |
| 190 | + scale_x_continuous("Year", limits=c(0, 50)) |
| 191 | + ) |
| 192 | + )+ |
| 193 | + theme( |
| 194 | + strip.text.y = element_blank(), |
| 195 | + plot.margin = margin(10, 30, 10, 10), |
| 196 | + panel.spacing.x = unit(30, "pt") |
| 197 | + ) |
| 198 | +ggsave(filename=file.path(here::here(), "figures", paste0("resilience2", filetype)), width=width_small, height=height_small, units="in") |
| 199 | + |
| 200 | + |
| 201 | +### Aggregate Performance |
| 202 | +full_performance_metrics <- performance_metric_summary( |
| 203 | + model_runs, |
| 204 | + extra_columns, |
| 205 | + sable_om$dem_params, |
| 206 | + ref_naa, |
| 207 | + hcr_filter=publication_hcrs, |
| 208 | + om_filter=publication_oms, |
| 209 | + interval_widths=interval_widths, |
| 210 | + time_horizon = time_horizon, |
| 211 | + extra_filter = NULL, |
| 212 | + relative=NULL, |
| 213 | + summarise_by=c("om", "hcr"), |
| 214 | + summary_out = FALSE, |
| 215 | + metric_list = c("avg_catch", "avg_variation", "avg_ssb", "avg_age", "prop_years_lowssb") |
| 216 | +) |
| 217 | + |
| 218 | +om_aggregated_performance <- full_performance_metrics$perf_data %>% |
| 219 | + group_by(sim, hcr) %>% |
| 220 | + summarise( |
| 221 | + across(2:6, \(x) mean(x, na.rm=TRUE)) |
| 222 | + ) %>% |
| 223 | + pivot_longer(3:7, names_to="name", values_to="value") %>% |
| 224 | + mutate( |
| 225 | + name = factor( |
| 226 | + name, |
| 227 | + levels=c("annual_catch", "aav", "spbio", "avg_age", "prop_years"), |
| 228 | + labels=publication_metrics |
| 229 | + ) |
| 230 | + ) |
| 231 | + |
| 232 | +om_means <- om_aggregated_performance %>% group_by(name) %>% summarise(v = mean(value)) |
| 233 | + |
| 234 | +ggplot(om_aggregated_performance)+ |
| 235 | + ggridges::stat_binline(aes(x=value, y=hcr, fill=hcr))+ |
| 236 | + geom_vline(data=om_means, aes(xintercept=v), linetype="dashed")+ |
| 237 | + scale_fill_manual(values=hcr_colors)+ |
| 238 | + facet_wrap(~name, scales="free_x")+ |
| 239 | + labs(y="")+ |
| 240 | + custom_theme+ |
| 241 | + ggh4x::facetted_pos_scales( |
| 242 | + x = list( |
| 243 | + scale_x_continuous("", limits=c(0, 35)), |
| 244 | + scale_x_continuous("", limits=c(0, 0.06)), |
| 245 | + scale_x_continuous("", limits=c(0, 300)), |
| 246 | + scale_x_continuous("", limits=c(5, 10)), |
| 247 | + scale_x_continuous("", limits=c(0, 1), breaks=c(0, 0.25, 0.50, 0.75, 1.0), labels=seq(0, 1, 0.25), expand=c(0, NA)) |
| 248 | + ) |
| 249 | + )+ |
| 250 | + guides(fill=guide_legend("Management \n Strategy", nrow=2))+ |
| 251 | + theme( |
| 252 | + # axis.text.y = element_blank(), |
| 253 | + axis.ticks.y = element_blank(), |
| 254 | + panel.spacing.x = unit(1, "cm") |
| 255 | + ) |
| 256 | +ggsave(file.path(figures_dir, paste0("performance_metrics_agg_hist2", filetype))) |
| 257 | + |
| 258 | + |
| 259 | +### Extra Analyses |
| 260 | + |
| 261 | +# Get average performance metric value by HCR across the OM scenarios |
| 262 | +om_aggregated_performance %>% group_by(hcr, name) %>% |
| 263 | + summarise( |
| 264 | + value = mean(value) |
| 265 | + ) %>% |
| 266 | + pivot_wider(names_from="name", values_from="value") |
| 267 | + |
| 268 | +# Get number of simulations in which the population went extinct prematurely |
| 269 | +ssb_data %>% filter(biomass < 1e-2) %>% pull(sim) %>% unique |
| 270 | + |
| 271 | +# Get number of years in which stability and max harvest constraints were |
| 272 | +# applied to their respective HCRs |
| 273 | +catch_data %>% |
| 274 | + filter_times(time_horizon) %>% |
| 275 | + filter(fleet == "Fixed") %>% |
| 276 | + filter_hcr_om(hcrs = c("F40 +/- 5%", "F40 +/- 10%", "15k Harvest Cap", "25k Harvest Cap"), oms=publication_oms) %>% |
| 277 | + group_by(sim, om, hcr) %>% |
| 278 | + mutate( |
| 279 | + rel_perc_change = abs(total_catch/lag(total_catch)-1), |
| 280 | + constrained = case_when( |
| 281 | + hcr == "F40 +/- 5%" ~ ifelse(rel_perc_change >= 0.0499, 1, 0), |
| 282 | + hcr == "F40 +/- 10%" ~ ifelse(rel_perc_change >= 0.0999, 1, 0), |
| 283 | + hcr == "15k Harvest Cap" ~ ifelse(total_catch >= 14.99, 1, 0), |
| 284 | + hcr == "25k Harvest Cap" ~ ifelse(total_catch >= 24.99, 1, 0) |
| 285 | + ) |
| 286 | + ) %>% |
| 287 | + # arrange(sim, om, time) %>% |
| 288 | + group_by(sim, om, hcr) %>% |
| 289 | + summarise( |
| 290 | + years_constrained = sum(constrained, na.rm=TRUE)/n() |
| 291 | + ) %>% |
| 292 | + group_by(om, hcr) %>% |
| 293 | + median_qi(years_constrained, .width = interval_widths) %>% |
| 294 | + print(n=100) |
| 295 | + |
0 commit comments