traitecoevo / plant

Trait-Driven Models of Ecology and Evolution :evergreen_tree:
https://traitecoevo.github.io/plant
53 stars 20 forks source link

Revive exponentially decaying recruitment (and tidy patch) #330

Closed aornugent closed 2 years ago

aornugent commented 2 years ago

Daniel and I tinkered with this model during our investigation of lockup, but it never made it onto Github. A single parameter reproduction_decay is introduced that governs the change in establishment probability over time.

We can see that as recruitment_decay increases, the establishment of late successional cohorts declines to zero, leaving only the first wave of cohorts having a material density.

Recruitment decay = 0

image

Recruitment decay = 0.2

image

Recruitment decay = 5

image

I haven't caught up with Daniel's fancy tidy_patch framework, but here's how to edit this parameter and plot results:

devtools::load_all()

p0 <- scm_base_parameters("FF16r")
p0$strategy_default$recruitment_decay = 0

p1 <- expand_parameters(trait_matrix(0.0825, "lma"), p0, FF16w_hyperpar,FALSE)

env <- make_environment("FF16r")
ctrl <- scm_base_control()

out <- run_scm_collect(p1, env, ctrl)

# Relativise the log densities onto (-4, max)
rel <- function(x, xmin = -4) {
  x[x < xmin] <- xmin
  xmax <- max(x, na.rm=TRUE)
  (x - xmin) / (xmax - xmin)
}

t <- out$time
h <- out$species[[1]]["height", , ]

d <- out$species[[1]]["log_density", , ]
rd <- rel(d)

n <- length(t)
x <- matrix(rep(t, ncol(h)), nrow(h))
col <- matrix(make_transparent("black", rd), nrow(d))

plot(NA, xlim=range(t), ylim=range(h, na.rm=TRUE),
     las=1, xlab="Time (years)", ylab="Cohort height (m)")
segments(x[-1, ], h[-1, ], x[-n, ], h[-n, ], col=col[-n, ], lend="butt")
aornugent commented 2 years ago

Oh my bad - I thought FF16r had fallen out of use, other than as an example of strategy inheritance, but I now see that it's called in the StochasticSpecies test. I can re-enable the custom fraction_allocation_reproduction and then either:

  1. leave recruitment decay in FF16r and set the default to 0; or
  2. move recruitment decay into another strategy, e.g. FF16decay.
Becca-90 commented 2 years ago

That's awesome!

dfalster commented 2 years ago

Hi all, Nice Andrew!

The above two commits

  1. implement the recruitment_decay option on the FF16 model (and thereby all FF16 models), with default value of 0. So set it to something higher (e.g. 5) to get the effect Andrew demonstrated
  2. Pull in changes from tidy_patch branch.

So @Becca-90, you should

  1. install this version
  2. Add a setting for recruitment_decay into your scripts, e.g. in the run_my_patch function
codecov-commenter commented 2 years ago

Codecov Report

:exclamation: No coverage uploaded for pull request base (develop@bb14fd9). Click here to learn what that means. The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##             develop     #330   +/-   ##
==========================================
  Coverage           ?   78.52%           
==========================================
  Files              ?       99           
  Lines              ?     8727           
  Branches           ?        0           
==========================================
  Hits               ?     6853           
  Misses             ?     1874           
  Partials           ?        0           

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update bb14fd9...c7e527c. Read the comment docs.

dfalster commented 2 years ago

Well it seems I'm making a mess out of this. Will fix.

dfalster commented 2 years ago

Ok, working now ;)

dfalster commented 2 years ago

Hi @aornugent -- I've updated all the tidy_patch materials. Is this Ok to merge into develop?

dfalster commented 2 years ago

Addresses #321, #309, #308, #331

aornugent commented 2 years ago

Looking good @dfalster ! I love the new framework for visualisation. I've left a few comments on the workflow doc for your review, but hopefully all minor. @Becca-90 - I've updated the test script:

Recruitment decay = 5

base_parameters <- function(recruitment_decay) {
  p0$strategy_default$recruitment_decay = recruitment_decay

  return(p0)
}

run_decay_patch <- function(
  traits =  trait_matrix(c(0.07), c("lma")),
  B_lf1 = 1,
  seed_rain = 100,
  recruitment_decay = 0,
  find_equilbrium = FALSE,
  optimise_schedule = FALSE,
  latitude = 28.182
) {
  p0 = base_parameters(recruitment_decay)
  hyper_par_fn = make_FF16_hyperpar(B_lf1 = B_lf1, latitude = latitude)
  p1 <- expand_parameters(traits, p0, hyper_par_fn, mutant = FALSE)
  p1$seed_rain <- seed_rain

  if(find_equilbrium)
    result <- equilibrium_seed_rain(p1)
  else if(optimise_schedule)
    result <- build_schedule(p1)
  else
    result <- p1

  # gather outputs at each time step
  run_scm_collect(result)
}

out <- run_decay_patch(recruitment_decay = 5)

results <- out %>% tidy_patch() %>% expand_state_FF16()
totals <- results$species %>% integrate_over_size_distribution()

totals %>% 
  ggplot(aes(time, individuals, colour=species)) +
  geom_line() +
  coord_cartesian(expand = F) + 
  theme_classic()

Which confirms that recruitment of individuals drops after the first wave:

image

dfalster commented 2 years ago

Thanks @aornugent