knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
This vignette explores the options for how the model behaves at the boundaries. The study extent includes southern New Hampshire and southern Maine. As a consequence, there are three boundary types: ocean, terrestrial with GRANIT proportions, and terrestrial with NLCD proportions. In the context of this vignette, we will ignore the GRANIT vs NLCD distinction, and instead compare models using only the GRANIT proportions in a reduced study extent, such that there is a buffer with known land cover proportions surrounding the area of interest. These are the boundary behaviors explored here:
To successfully model behavior 3, we model a landscape with wall boundaries, but larger than the area of interest such that the buffer is larger than effects of the true boundary. For a direct comparison, we will use the same full landscape and smaller area of interest. Both will be rectangular and include ocean cells. Thus, lc.df
includes columns identifying: x
, y
, x_y
, id
, inbd
, id.inbd
, and ocean
in addition to the associated land cover proportions. The inbd
and ocean
columns are logical.
For sink boundaries, the establishment probabilities will be set to 0, though dispersal probabilities will be based on the land cover based bird habitat preferences.
if(!require(pacman)) {install.packages("pacman"); require(pacman)} p_load("tidyverse", "magrittr", "stringr", "parallel", "here", "pbapply", "fastmatch", "gganimate"); theme_set(theme_bw()) library(gbPopMod) data(lc.rct)
##--- ## set parameters ##--- # here, lc.r & lc.c are the dimensions of the full extent with buffer setting # the x and y buffer between the extent and boundary of the area of interest buffer <- 5 n.sim <- 20; par.sim <- TRUE bottom <- 500; left <- 200 g.p <- set_g_p(tmax=100, lc.r=50, lc.c=50, n.cores=4, N.p.t0=2) control.p <- set_control_p() g.p$edges <- c("wall", "sink", "none")[3] set.seed(225) ##-- ## initialize landscape ##-- # land cover lc.df <- lc.rct %>% filter((y >= (bottom - g.p$lc.r)) & (y < bottom) & (x <= (left + g.p$lc.c)) & (x > left)) %>% mutate(id=row_number(), ocean=!inbd, inbd=((y <= max(y) - buffer) & (y >= min(y) + buffer) & (x <= max(x) - buffer) & (x >= min(x) + buffer) & !ocean), id.inbd=min_rank(na_if(inbd*id, 0))) ggplot(lc.df, aes(x=x, y=-y, fill=inbd, colour=ocean)) + geom_tile() + scale_colour_manual(values=c(NA, "white")) ngrid <- nrow(lc.df) ncell <- sum(lc.df$inbd) # populations # indexed 1:ngrid including rows for out-of-bounds cells N.init <- pop_init(ngrid, g.p, lc.df) # dispersal probabilities # indexed 1:ncell with only inbound cells: sdd.pr[,,,i] = ith inbound cell # row i = dplyr::filter(lc.df, inbds)[i,] = lc.df[id.inbd==i,] # cell indexes in sdd.pr[,,2,] correspond with lc.df$id # this extra complication avoids calculating many, many unnecessary cells sdd.pr <- sdd_set_probs(ifelse(g.p$edges=="none", ngrid, ncell), lc.df, g.p, edges=g.p$edges)
if(par.sim) { require(doParallel) p.c <- makeCluster(g.p$n.cores) registerDoParallel(p.c) out.p <- foreach(i=1:n.sim) %dopar% { gbPopMod::run_sim(ngrid, ncell, g.p, lc.df, sdd.pr, N.init, control.p, verbose=F) } stopCluster(p.c) out.ad <- map(out.p, ~.$N[,,max(g.p$age.f)]) %>% unlist %>% array(., dim=c(ngrid, g.p$tmax+1, n.sim)) out.sb <- map(out.p, ~.$N.sb) %>% unlist %>% array(., dim=c(ngrid, g.p$tmax+1, n.sim)) } else { out.ad <- array(dim=c(ngrid, g.p$tmax+1, n.sim)) out.sb <- array(dim=c(ngrid, g.p$tmax+1, n.sim)) for(s in 1:n.sim) { out <- run_sim(ngrid, ncell, g.p, lc.df, sdd.pr, N.init, control.p, verbose=F) out.ad[,,s] <- out$N[,,max(g.p$age.f)] out.sb[,,s] <- out$N.sb rm(out) cat("Finished simulation", s, "of", n.sim, "\n") } }
ad.mn <- apply(out.ad, 1:2, mean) N.out <- cbind(lc.df, ad.mn) %>% as.tibble %>% gather(year, N.adult, (1:ncol(ad.mn)) + ncol(lc.df)) %>% mutate(sd.ad=c(apply(out.ad, 1:2, sd)), pP.ad=c(apply(out.ad > 0, 1:2, mean)), N.sb=c(apply(log(out.sb+1), 1:2, mean)), sd.sb=c(apply(log(out.sb+1), 1:2, sd)), pP.sb=c(apply(out.sb > 0, 1:2, mean)), N.less5=c(ad.mn > 0)) N.out$N.less5 <- N.out$N.less5 + c(ad.mn > 5) N.out$year <- str_pad(N.out$year, 3, "left", "0") # prepare plot paths & filenames p.wd <- paste0("out/", ncell, "_t", g.p$tmax, "_", g.p$edges, "/") if(!dir.exists(here::here("out"))) dir.create(here::here("out")) if(!dir.exists(here::here(p.wd))) dir.create(here::here(p.wd)) age.i <- ifelse(length(g.p$age.f)==1, paste0("age", g.p$age.f, ""), paste0("ages", min(g.p$age.f), "-", max(g.p$age.f), "")) # save plots save_pars(p.wd, age.i, g.p, control.p) make_plots_final_t(p.wd, age.i, g.p, filter(N.out, year==max(N.out$year))) make_plots_gifs(p.wd, age.i, g.p, N.out) make_plots_lc(p.wd, lc.df)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.