# JAGS model 1 -- Latent Bt, Process errors for Pt and Et
JagsModel = "
model {
SigmaE ~ dunif(0.01,1)
SigmaP <- SigmaE
SigmaQ <- SigmaP
lnr <- log(r)
lnB0 ~ dunif(-4.6,4.6)
x ~ dunif(0.01,0.5)
a ~ dunif(0.1,2)
B0 <- exp(lnB0)
ln_Final_Depletion <- log(Bt[Nyears]) - lnB0
Final_Depletion <- exp(ln_Final_Depletion)
Final_Depletion_Error_Ratio <- exp(ln_Final_Depletion) / DepletionTrue[Nyears]
#Final_Depletion_Prior[1] ~ dlnorm( ln_Final_Depletion, Final_Depletion_Prior[2])
MSY_min <- B0 * r_min / 4
MSY_max <- B0 * r_max / 4
MSY ~ dunif(MSY_min,MSY_max)
r <- 4 * MSY / B0
Bt_rel[1] <- 1
Bt[1] <- Bt_rel[1] * B0
lnE0 ~ dunif(-11.5,0) # ln(0.00001) - ln(0.1)
E0 <- exp(lnE0)
Et[1] <- E0
Dummy <- lnE0
Bupper <- 2*B0 # Necessary for when r is low, so that Bt doesn't drift too far above B0
Ct_hat[1] <- 0
for(YearI in 2:Nyears){
# Define time-varying precision
TauE[YearI] <- pow(SigmaE,-2) * pow(EffortSD[YearI],-2)
TauB[YearI] <- pow(SigmaP,-2) * pow(BioSD[YearI],-2)
TauQ[YearI] <- pow(SigmaQ,-2) * pow(Q_SD[YearI],-2)
# Stochastic draw for Bt given Bt_exp
Pt[YearI-1] <- r*Bt_rel[YearI-1]*B0 * ( 1 - Bt_rel[YearI-1] )
ln_Bt_rel_exp[YearI] <- log( max( (Bt_rel[YearI-1]*B0 + Pt[YearI-1] - Ct[YearI-1])/B0, 1e-12 ) ) # 1e-10 is about the lowest I can set this
Bt_rel[YearI] ~ dlnorm( ln_Bt_rel_exp[YearI], TauB[YearI]) T(0.001,Bupper)
Bt[YearI] <- Bt_rel[YearI] * B0
# Set up next effort computation used in next year's stochastic draw for Ct
Et[YearI] <- min( Ct[YearI] / (Bt_rel[YearI]*B0), 0.99 )
# Stochastic draw for Ct given Ct_hat
Ct_hat[YearI] <- Et[YearI-1] * ( Bt_rel[YearI-1] / (a/2) )^x * Bt_rel[YearI]*B0
ln_Ct_hat[YearI] <- log( Ct_hat[YearI] )
Ct[YearI] ~ dlnorm(ln_Ct_hat[YearI],TauQ[YearI])
}
}
"
#' SSCOM model
#'
#' State-space catch-only model from Thorson et al. (2013).
#'
#' @param ct Catch time series
#' @param yr Years
#' @param start_r Lower and upper intrinsic population growth rates
#' @param NburninPrelim Number of warmup iterations during the preliminary phase
#' @param NiterPrelim Number of preliminary iterations
#' @param NthinPrelim Thinning of preliminary iterations
#' @param NchainsPrelim Number of chains for preliminary iterations
#' @param NburninJags Number of warmup iterations for main sampling phase
#' @param NiterJags Number of sampling iterations for main sampling phase
#' @param NthinJags Thining for main sampling phase
#' @param Nchains Number of chains for the main sampling phase
#' @param return_jags Logical: should the JAGS output object be returned at the
#' end as well. If \code{TRUE} then a list with elements \code{jags} and
#' \code{output} will be returned with the JAGS and SSCOM output, respectively.
#' @importFrom R2jags jags
#' @export
#'
#' @references
#' Thorson, J. T., C. Minto, C. V. Minte-Vera, K. M. Kleisner and C. Longo,
#' 2013. A new role for effort dynamics in the theory of harvested populations
#' and data-poor stock assessment. Can. J. Fish. Aquat. Sci. 70(12):1829-1844.
#'
#' @examples
#' \dontrun{
#' x <- sscom(blue_gren$yr, blue_gren$ct,
#' NburninPrelim = 1e3,
#' NiterPrelim = 2e3,
#' NthinPrelim = 1,
#' NchainsPrelim = 20,
#' NburninJags = 1e3,
#' NiterJags = 3e3,
#' NthinJags = 2,
#' Nchains = 3, return_jags = TRUE)
#' }
sscom <- function(yr, ct, start_r = resilience("unknown"),
NburninPrelim = 1e3,
NiterPrelim = 2e3,
NthinPrelim = 1e0,
NchainsPrelim = 100,
NburninJags = 1e6,
NiterJags = 2e6,
NthinJags = 1e3,
Nchains = 3,
return_jags = FALSE){
Ct <- ct
Year <- yr
RunFile <- "./"
res.list <- list()
MaxCt <- max(Ct)
Ct <- Ct / MaxCt
Nyears <- length(Year)
Bt <- rep(1, Nyears)
B0 <- Bt[1]
DepletionPriorSD <- 1000
r_min <- start_r[1]
r_max <- start_r[2]
## Run Settings
## which effort dynamics model
## ModelType = 1 : Process errors in biomass and effort dynamics
## ModelType = 2 : same plus variability in catch equation
##ModelType = 1 # 1=Bt; 2=Bt+Et
## JAGS settings
## Note! ModelType 1
ModelType <- 1
## Write JAGS model
cat(JagsModel, file = paste(RunFile,"dnorm.bug",sep=""))
Params2Save <- c("Ct_hat", "Pt", "Bt", "B0", "r", "a", "x",
"SigmaE", "SigmaP", "MSY", "Final_Depletion",
"Final_Depletion_Error_Ratio", "E0")
## Run JAGS
## Nyears = number of years
## Ct = catch time series
## Q_SD = relative index of CV in catch equation (i.e. catchability)
## BioSD = relative index of CV in biomass process errors
## EffortSD = relative index of CV in effort dynamics process errors
## DepletionTrue = true Bt/B0 (only used for computing errors)
## Final_Depletion_Prior = mean and precision for prior on final Bt/B0
## r_min and r_max = min and max for uniform prior on r (intrinsic growth rate)
Seed <- ceiling(runif(1,0,1e6))
set.seed(Seed)
DataJags <- list(Nyears = Nyears, Ct = Ct,
Q_SD = rep(1, Nyears), BioSD = rep(1, Nyears),
EffortSD = rep(1, Nyears), DepletionTrue = Bt/B0, r_min = r_min,
r_max = r_max)
inits_prelim <- function() {
lnE0 <- log(runif(1, 2e-05, 0.999999))
x <- runif(1, 0.01, 0.5)
a <- runif(1, 0.1, 2)
r <- runif(1, r_min, r_max)
lnB0 <- log(max(Ct)/r * 4) + runif(1, log(0.2), log(25))
MSY <- r * exp(lnB0)/4
Bt_rel <- runif(length(Ct), min = Ct/exp(lnB0), max = 1)
Bt_rel[1] <- NA
SigmaE <- runif(1, 0.01, 1)
Return <- list(lnE0 = lnE0, x = x, a = a, MSY = MSY, lnB0 = lnB0,
Bt_rel = Bt_rel, SigmaE = SigmaE)
return(Return)
}
inits_resample <- function() {
Which <- sample(size = 1, 1:length(RelLike), prob = RelLike)
lnE0 <- log(Jags_prelim$BUGSoutput$sims.list$E0)[Which]
x <- Jags_prelim$BUGSoutput$sims.list$x[Which]
a <- Jags_prelim$BUGSoutput$sims.list$a[Which]
r <- Jags_prelim$BUGSoutput$sims.list$r[Which]
MSY <- Jags_prelim$BUGSoutput$sims.list$MSY[Which]
lnB0 <- log(Jags_prelim$BUGSoutput$sims.list$B0)[Which]
Bt_rel <- Jags_prelim$BUGSoutput$sims.list$Bt[Which, ]/
Jags_prelim$BUGSoutput$sims.list$B0[Which]
Bt_rel[1] <- NA
SigmaE <- Jags_prelim$BUGSoutput$sims.list$SigmaE[Which]
Return <- list(lnE0 = lnE0, x = x, a = a, MSY = MSY, lnB0 = lnB0,
Bt_rel = Bt_rel, SigmaE = SigmaE)
return(Return)
}
## Try to initialize the model
Iteration <- IterationPrelim <- 1
while(IterationPrelim < 1000){
NchainsIteration <- ceiling(NchainsPrelim * (1000-2*IterationPrelim)/1000) # Spend half of attempts at Nchains = 3
if (NchainsIteration<1) NchainsIteration <- 1
Try <- try(Jags_prelim <- R2jags::jags(model.file = paste(RunFile, "dnorm.bug", sep = ""),
inits = inits_prelim, working.directory = NULL,
data = DataJags, parameters.to.save = Params2Save,
n.chains = NchainsIteration, n.thin = NthinPrelim, n.iter = NiterPrelim,
n.burnin = NburninPrelim))
IterationPrelim = ifelse(class(Try) != "try-error", 1e+20, IterationPrelim + 1)
message(IterationPrelim)
}
## If it initializes, then try to run the model
if (IterationPrelim==1e20){
RelLike <- exp(-(Jags_prelim$BUGSoutput$sims.list$deviance -
min(Jags_prelim$BUGSoutput$sims.list$deviance)))
##
while(Iteration < 1000){
Try <- try(Jags <- R2jags::jags(model.file = paste(RunFile, "dnorm.bug", sep = ""),
inits = inits_resample, working.directory = NULL,
data = DataJags, parameters.to.save = Params2Save, n.chains = Nchains,
n.thin = NthinJags, n.iter = NiterJags, n.burnin = NburninJags))
Iteration = ifelse(class(Try) != "try-error", 1e+20, Iteration + 1)
}
}
## If it both initializes and runs, then save results
if (IterationPrelim==1e20 & Iteration==1e20){
BoverBmsy <- Jags$BUGSoutput$sims.list$Bt /
outer(as.vector(Jags$BUGSoutput$sims.list$B0),rep(1,Nyears)) * 2
Neff <- Jags$BUGSoutput$summary[,'n.eff']
Neff <- ifelse(Neff==1, NA, Neff)
Neff <- min(Neff, na.rm=TRUE)
if (ModelType==1) E <- array(0, dim = dim(Jags$BUGSoutput$sims.list$Bt))
if (ModelType==2) E <- Jags$BUGSoutput$sims.list$Et
} else {
BoverBmsy <- matrix(0, ncol = Nyears,
nrow = (NiterJags-NburninJags)/NthinJags*Nchains)
Neff <- rep(3, 100)
names(Neff)[1:2] <- c("Ct_hat[1]","Pt[1]")
Neff <- Neff[-match(c("Ct_hat[1]","Pt[1]"),names(Neff))]
Neff <- min(Neff)
E <- array(0, dim=dim(BoverBmsy))
}
Results <- suppressWarnings(data.frame(
'b_bmsy' = apply(BoverBmsy,MARGIN=2,FUN=mean),
'b_bmsyUpper' = apply(BoverBmsy,MARGIN=2,FUN=quantile,prob=0.925),
'b_bmsyLower' = apply(BoverBmsy,MARGIN=2,FUN=quantile,prob=0.075),
'b_bmsy_iq25' = apply(BoverBmsy,MARGIN=2,FUN=quantile,prob=0.25),
'b_bmsy_iq75' = apply(BoverBmsy,MARGIN=2,FUN=quantile,prob=0.75),
'E' = apply(E,MARGIN=2,FUN=mean),
'E_Upper' = apply(E,MARGIN=2,FUN=quantile,prob=0.925),
'E_Lower' = apply(E,MARGIN=2,FUN=quantile,prob=0.075),
'E_iq25' = apply(E,MARGIN=2,FUN=quantile,prob=0.25),
'E_iq75' = apply(E,MARGIN=2,FUN=quantile,prob=0.75),
'year' = Year,
'seed' = Seed,
'convergence' = ifelse(Neff>200,"Strong",ifelse(Neff>30,"Weak","Not")),
'n_iterations' = NiterJags*Nchains,
'effective_sample_size' = Neff,
'method_id' = "SSCOM", MaxCt = MaxCt))
bbmsy <- data.frame(year = yr, catch = ct, summarize_bbmsy(BoverBmsy))
if (return_jags) {
list(jags = Jags, output = Results, bbmsy = bbmsy)
} else {
Results
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.