sprat-xsa-experimental
/
run.R
713 строк · 30.7 Кб
1# ************************************* #
2# Author: Piatinskii M., Azov-black sea bench of VNIRO
3# © 2019
4# **************************************#
5# make cleanup
6rm(list = ls(all.names=TRUE))
7# load libraries
8library("FLCore")
9library("FLXSA")
10library("FLAssess")
11library("ggplotFL")
12# library("FLBRP") # no support for R 4.0, require compilation from *nix
13library("FLash")
14#install.packages("devtools")
15#install_github("ices-tools-prod/msy")
16library("msy")
17library("rmarkdown")
18library("dplyr")
19library("magrittr")
20library("tibble")
21library("icesAdvice")
22
23# ****** GLOBAL CONFIGURATIONS SECTION *******#
24
25# stock object configurations
26config.stock.name <- "Sprattus sprattus" # fish title
27config.stock.desc <- "Sprat stock information in FLCore format from 2000years" # fish stock description
28config.stock.fbar.min <- 1 # minimum fish age become fishing (Fbar min)
29config.stock.fbar.max <- 3 # maximum fish age at fishing (Fbar max)
30config.stock.no_harvestspawn <- TRUE # Set TRUE if there is no information about fishing before spawning
31config.stock.no_mspawn <- TRUE # Set TRUE if no information about natural mortality before spawning
32config.stock.no_discards <- TRUE # Set TRUE if no separated information about landing/discards exist (only catch)
33config.stock.window.start <- 1994 # model start
34config.stock.window.end <- 2022 # model end
35
36# configure surveys indices
37config.index1.name <- "Sprat crimea cpue index"
38config.index1.desc <- "Fishery index information about sprat abundance at Crimea shelf from real fishing surveys"
39config.index1.startf <- 0.3 # start month of survey in format month/12, example: 1 feb = 2/12 = 0.166
40config.index1.endf <- 0.7 # end month of survey in format month/12
41config.index1.type <- "number" # type of survey, allowed: number, biomass
42
43# same with previous
44config.index2.name <- "Sprat caucasian cpue index"
45config.index2.desc <- "Fishery index information about sprat abundance at Caucasian shelf from real fishing surveys"
46config.index2.startf <- 0.3
47config.index2.endf <- 0.7
48config.index2.type <- "number"
49
50# pre-analysis diagnostic procedures. Useful to choice the model parametrization, convergence, etc
51config.iter.fse = TRUE # Fse choice procedure
52config.iter.retro = TRUE # retrospective procedure
53config.iter.fseage = TRUE # Fse at age impact procedure
54
55# configure retrospective depth
56config.retro.horizon <- 5
57
58# Shrinkage standard error max value. Default value Fse = 0.5
59# Higher shrinkage se leads to high unrestraint of estimating procedure.
60config.tuning.xsa <- FLXSA.control(
61maxit = 100, # maximum covergence iterations
62fse = 1.5, # shrinkage s.e value
63shk.n = T,
64shk.f = T,
65shk.yrs = 4,
66tsrange = 15, # weighting time series length (from latest year)
67tspower = 3, # weighting procedure sequence (1 = linear, 2 = square, 3 = cubic)
68qage = 2, # age after catchability not depends on age
69)
70
71# sr model configuration
72config.srmodel.eqsim.use = TRUE # should we use eqsim package insted of FLSR default?
73config.srmodel.use_geomean = FALSE # set FALSE to use EQSIM SR model results to forecasting
74
75# eqsim model configurations (if config.srmodel.eqsim.use = TRUE)
76config.srmodel.eqsim.models = c("Segreg") # types of model to fit and compare
77config.srmodel.eqsim.simulations = 10 # number of simulations
78config.srmodel.eqsim.shift_years <- 1994:2005 # remove years from sr-model fitting
79
80# flsr model configuration (if config.srmodel.eqsim.use = FALSE)
81config.srmodel.type <- segregAR1() # SR model type: ricker(), bevholt(), geomean(), segreg(), shepherd(), cushing(), AR in model name = AutoCorrelation fix
82config.srmodel.optimization = FALSE # Use optimization procedure for SR model fitting?
83
84# configure MSY reference point calculation: Blim, Bpa, Fmsy
85config.brp.blim_multiplier <- 0.3 # multiplier of SSBmax to get Blim ref.point, allowed: 0.2 - 0.4
86config.brp.trim_uncertainity <- TRUE # trim uncerteinity extreme deviations? Optimization procedure for Bpa estimate
87config.brp.current_range <- 2005:2022 # shift previous population states from BRP calculations
88
89# Custom forecast scenarious. By default performed: F_SQ, F_01, F_msy scenarious.
90# There you can define f(y+1), f(y+2), f(y+3) targets for 2 scenarious
91# precautionary scenario: Fpa = (B-Blim/Bmsy-Blim) * Fmsy = 0.51
92config.forecast.scenario1.f_year1 <- 0.51
93config.forecast.scenario1.f_year2 <- 0.51
94config.forecast.scenario1.f_year3 <- 0.51
95config.forecast.scenario1.f_year4 <- 0.51
96config.forecast.scenario1.f_year5 <- 0.51
97
98# Scenario MSY at M = 0,95
99# by old STECF (2010) results
100config.forecast.scenario2.f_year1 <- 0.91
101config.forecast.scenario2.f_year2 <- 0.91
102config.forecast.scenario2.f_year3 <- 0.91
103config.forecast.scenario2.f_year4 <- 0.91
104config.forecast.scenario2.f_year5 <- 0.91
105
106# additional scenario for manual Fmsy and F_01 estimates
107config.forecast.manual_F01 <- 0.605
108config.forecast.manual_FMSY <- 0.64
109
110# custom calculations. Calculate partial recruitment for Y/R analysis
111config.custom.partial.years <- 2004:2020
112
113# custom calculations. Calculate F01 reference point from Y/R analysis
114config.custom.f01.years <- 2004:2020 # years used to calculate mean(wt), mean(Fi/Fmax), mean(M)
115config.custom.f01.plusgroup = TRUE # is last group is plus group?
116config.custom.f01.oldest = 5 # oldest fish found in waters (not in stock, that means "even somewhen exist in sea")
117# ******** GLOBAL CONFIGURATION DONE!!! **** #
118
119# ********************************************************* #
120# Do not change enything below if you have no idea what is going on
121# ********************************************************* #
122
123# simple write functions
124savePic <- function(path, imgObj, width=1900, height=1600, res=200) {
125png(path, width=width, height=height, res=res, type="cairo")
126print(plot(imgObj) + theme_bw())
127dev.off()
128}
129saveText <- function(path, object) {
130con <- file(path, encoding = "UTF-8")
131sink(con)
132print(object)
133sink()
134close(con)
135}
136
137# get mbar from stock object
138mbar <- function(stock) {
139stock.min <- as.numeric(stock@range["min"])
140stock.max <- as.numeric(stock@range["max"])
141
142bar.min <- as.numeric(stock@range["minfbar"])
143bar.max <- as.numeric(stock@range["maxfbar"])
144
145diff.min <- 1 + bar.min - stock.min
146diff.max <- 1 + bar.max - bar.min
147if (diff.max > stock.max+1)
148diff.max <- stock.max+1
149
150vec <- (m(stock)[diff.min:diff.max,])
151bar <- apply(vec, 2, mean)
152return(bar)
153}
154
155
156
157# read input data - stock
158tmp.stock <- read.csv("input/stock.csv", sep=",")
159data.stock <- as.FLStock(tmp.stock)
160# read input data - index
161tmp.idx1.idx <- read.csv("input/survey1/index.csv", sep=",")
162tmp.idx1.eff <- read.csv("input/survey1/effort.csv", sep=",")
163tmp.idx2.idx <- read.csv("input/survey2/index.csv", sep=",")
164tmp.idx2.eff <- read.csv("input/survey2/effort.csv", sep=",")
165
166data.index1 <- FLIndex(index=as.FLQuant(tmp.idx1.idx), effort=as.FLQuant(tmp.idx1.eff), catch.n=as.FLQuant(tmp.idx1.idx))
167data.index2 <- FLIndex(index=as.FLQuant(tmp.idx2.idx), effort=as.FLQuant(tmp.idx2.eff), catch.n=as.FLQuant(tmp.idx2.idx))
168
169remove(tmp.stock, tmp.idx1.idx, tmp.idx1.eff, tmp.idx2.idx, tmp.idx2.eff)
170print("[XSA toolkit]: Load data: OK")
171# Set name,desc from cfgs
172name(data.stock) <- config.stock.name
173desc(data.stock) <- config.stock.desc
174# set fbar ranges
175range(data.stock)[c("minfbar", "maxfbar")] <- c(config.stock.fbar.min, config.stock.fbar.max)
176
177# shift data starting from 2000
178data.stock <- window(data.stock, start = config.stock.window.start, end = config.stock.window.end)
179
180# set harvest.spwn and m.spwn = 0 if no data exist (or XSA throw error)
181if (config.stock.no_harvestspawn) {
182harvest.spwn(data.stock) <- 0
183}
184if (config.stock.no_mspawn) {
185m.spwn(data.stock) <- 0
186}
187# if no info about discards/landings separatly than set discards = 0, landings = catch
188if (config.stock.no_discards) {
189discards(data.stock) <- 0
190discards.n(data.stock) <- 0
191discards.wt(data.stock) <- catch.wt(data.stock)
192landings(data.stock) <- catch(data.stock)
193landings.n(data.stock) <- catch.n(data.stock)
194landings.wt(data.stock) <- catch.wt(data.stock)
195}
196stock.wt(data.stock) <- catch.wt(data.stock)
197
198# set cfgs for index1 and index2
199type(data.index1) <- config.index1.type
200name(data.index1) <- config.index1.name
201desc(data.index1) <- config.index1.desc
202range(data.index1)[c("startf", "endf")] <- c(config.index1.startf, config.index1.endf)
203
204type(data.index2) <- config.index2.type
205name(data.index2) <- config.index2.name
206desc(data.index2) <- config.index2.desc
207range(data.index2)[c("startf", "endf")] <- c(config.index2.startf, config.index2.endf)
208print("[XSA toolkit]: FLStock and FLIndex object configured successful")
209
210data.indices <- FLIndices(data.index1, data.index2)
211
212# make Fse comparision test
213if (config.iter.fse) {
214print("[XSA toolkit]: Fse impact factor estimate")
215steps <- seq(0.5, 2.5, by = 0.5)
216fseIters <- c()
217for (i in 1:length(steps)) {
218ctl <- config.tuning.xsa
219ctl@fse <- steps[i]
220res <- FLXSA(data.stock, data.indices, ctl) + data.stock
221fseIters <- c(fseIters, res)
222}
223
224result.fse.summary <- FLStocks(fseIters)
225names(result.fse.summary) <- steps
226# save output to pic
227savePic("output/1_FseChoose/summary_all.png", result.fse.summary)
228# get latest 5 year window
229lastYear <- result.fse.summary[[1]]@range["maxyear"]
230tmpObj <- window(result.fse.summary, lastYear-config.retro.horizon, lastYear)
231savePic("output/1_FseChoose/summary_short.png", tmpObj)
232remove(lastYear, tmpObj)
233# save text output - ssb
234con <- file("output/1_FseChoose/ssb.txt", encoding = "UTF-8")
235sink(con)
236
237for (i in 1:length(steps)) {
238print(sprintf("============= SSB at Fse = %s", steps[i]))
239print(ssb(result.fse.summary[[i]]))
240cat("\r\n")
241}
242
243sink()
244close(con)
245# save text output - rec
246con <- file("output/1_FseChoose/rec.txt", encoding = "UTF-8")
247sink(con)
248
249for (i in 1:length(steps)) {
250print(sprintf("============= Recruitment at Fse = %s", steps[i]))
251print(rec(result.fse.summary[[i]]))
252cat("\r\n")
253}
254
255sink()
256close(con)
257# save text output - fbar
258con <- file("output/1_FseChoose/fbar.txt", encoding = "UTF-8")
259sink(con)
260
261for (i in 1:length(steps)) {
262print(sprintf("============= Fbar at Fse = %s", steps[i]))
263print(fbar(result.fse.summary[[i]]))
264cat("\r\n")
265}
266
267sink()
268close(con)
269
270remove(steps, fseIters, ctl, res, con)
271}
272
273if (config.iter.retro) {
274print("[XSA toolkit]: Retrospective analysis")
275# make retrospective analysis
276result.retro.summary <- list()
277endYear <- data.stock@range["maxyear"]
278startYear <- endYear-config.retro.horizon
279years <- startYear:endYear
280frange <- seq(0.1, 2.5, by=0.1)
281for (i in frange) {
282res <- tapply(years, 1:length(years), function(x) {
283ctl <- config.tuning.xsa
284ctl@fse <- i
285window (data.stock, end=x) + FLXSA(window(data.stock, end=x), data.indices, ctl)
286})
287res <- FLStocks(res)
288res@names <- ac(c(years))
289result.retro.summary[[ac(i)]] <- res
290
291# save output as img
292savePic(sprintf("output/2_RetroFse/%s.png", i), res)
293remove(res)
294}
295}
296
297print("[XSA toolkit]: Retrospective Mohn's rho tests")
298# compare XSA estimates in terminal year by -5 year retrospective
299lastYear <- as.numeric(range(data.stock)["maxyear"])
300ssb.base <- as.vector(ssb(window(data.stock+FLXSA(data.stock, data.indices, config.tuning.xsa), start=lastYear-5)))
301f.base <- as.vector(fbar(window(data.stock+FLXSA(data.stock, data.indices, config.tuning.xsa), start=lastYear-5)))
302ssb.retro <- list()
303f.retro <- list()
304for (i in 1:config.retro.horizon) { # prepare retrospective matrix for mohn's rho test
305# make retro
306tmp.xsa <- FLXSA(window(data.stock, end=(lastYear-i)), window(data.indices, end=(lastYear-i)), config.tuning.xsa)
307tmp.xsa.st <- data.stock + tmp.xsa
308
309ssb.t <- as.vector(ssb(window(tmp.xsa.st, start=lastYear-config.retro.horizon)))
310f.t <- as.vector(fbar(window(tmp.xsa.st, start=lastYear-config.retro.horizon)))
311
312
313ssb.retro[[i]] <- ssb.t
314f.retro[[i]] <- f.t
315}
316
317result.retro.diagnostic.ssb <- data.frame(ssb.base, ssb.retro[[1]], ssb.retro[[2]], ssb.retro[[3]], ssb.retro[[4]], ssb.retro[[5]])
318rownames(result.retro.diagnostic.ssb) <- (lastYear-config.retro.horizon):lastYear
319result.retro.diagnostic.f <- data.frame(f.base, f.retro[[1]], f.retro[[2]], f.retro[[3]], f.retro[[4]], f.retro[[5]])
320rownames(result.retro.diagnostic.f) <- (lastYear-config.retro.horizon):lastYear
321names(result.retro.diagnostic.ssb) <- c("ssb.base", "-1", "-2", "-3", "-4", "-5")
322names(result.retro.diagnostic.f) <- c("f.base", "-1", "-2", "-3", "-4", "-5")
323
324# replace NaN's (x/0) to NA (not available)
325is.nan.data.frame <- function(x) {
326return (do.call(cbind, lapply(x, is.nan)))
327}
328
329result.retro.diagnostic.f[is.nan(result.retro.diagnostic.f)] <- NA
330result.retro.diagnostic.ssb[is.nan(result.retro.diagnostic.ssb)] <- NA
331
332result.retro.mohnrho.ssb <- mohn(result.retro.diagnostic.ssb, peels = config.retro.horizon)
333result.retro.mohnrho.fbar <- mohn(result.retro.diagnostic.f, peels = config.retro.horizon)
334remove(ssb.base, f.base, ssb.retro, f.retro)
335
336print(paste0("Rho ssb=", round(result.retro.mohnrho.ssb, 3)))
337print(paste0("Rho F=", round(result.retro.mohnrho.fbar, 3)))
338
339# calculate Fse impact to different age groups
340if (config.iter.fseage) {
341print("[XSA toolkit]: Fse impact to F-at-age estimates")
342steps <- seq(0.5, 2.5, by = 0.5)
343f.res <- propagate(harvest(data.stock), length(steps))
344for (i in 1:length(steps)) {
345raw.control <- config.tuning.xsa
346raw.control@fse <- steps[i]
347iter(f.res, i) <- harvest(FLXSA(data.stock, data.indices, raw.control))
348}
349endYear <- data.stock@range["maxyear"]
350startYear <- endYear - 9
351tmpObj <- xyplot(data ~ year | age, groups = iter, data = f.res, ylab="F", type = "l", xlim = c(startYear:endYear))
352savePic("output/3_FseImpactFAtAge/summary_all.png", tmpObj)
353remove(startYear, endYear, steps, f.res, raw.control, tmpObj)
354}
355
356# save survey regression age-vs-age test
357suppressWarnings(savePic("output/4_SurveysRegressions/summary_all.png", data.indices))
358
359suppressWarnings(savePic("output/4_SurveysRegressions/survey_1.png", data.indices[[1]]))
360suppressWarnings(savePic("output/4_SurveysRegressions/survey_2.png", data.indices[[2]]))
361
362print("[XSA toolkit]: Performing XSA analysis...")
363# fit xsa
364result.xsa.fit <- FLXSA(data.stock, data.indices, config.tuning.xsa)
365# build final stock + xsa estimates
366result.xsa.stock <- data.stock + result.xsa.fit
367
368# estimate uncertainty right now!
369# get f vals from xsa results
370tmp.fvals <- as.vector(fbar(result.xsa.stock))
371# get whiskers statistics for distribution
372tmp.wstats <- boxplot.stats(tmp.fvals)$stats
373# find outliers and remove from fvals
374tmp.fvals <- tmp.fvals[tmp.fvals > tmp.wstats[[1]]]
375tmp.fvals <- tmp.fvals[tmp.fvals < tmp.wstats[[5]]]
376# get fixed uncerteinity estimation
377result.xsa.sigma <- sd(tmp.fvals)
378remove(tmp.fvals, tmp.wstats)
379
380# save results
381endYear <- result.xsa.stock@range["maxyear"]
382F_SQ = mean(fbar(window(result.xsa.stock, (endYear-2), endYear)))
383savePic("output/5_XsaEstimates/summary_all.png", result.xsa.stock)
384savePic("output/5_XsaEstimates/stock_numbers_at_age.png", stock.n(result.xsa.stock))
385savePic("output/5_XsaEstimates/f_at_age.png", harvest(result.xsa.stock))
386
387saveText("output/5_XsaEstimates/ssb.txt", ssb(result.xsa.stock))
388saveText("output/5_XsaEstimates/rec.txt", rec(result.xsa.stock))
389saveText("output/5_XsaEstimates/fbar.txt", fbar(result.xsa.stock))
390saveText("output/5_XsaEstimates/f.txt", harvest(result.xsa.stock))
391saveText("output/5_XsaEstimates/stock.n.txt", stock.n(result.xsa.stock))
392saveText("output/5_XsaEstimates/diagnostics.txt", diagnostics(result.xsa.fit))
393
394# investigate uncertainty factor (build conf.intervals for plots)
395pics <- FLQuants(
396Rec = rnorm(1000, rec(result.xsa.stock), result.xsa.sigma * rec(result.xsa.stock)),
397SSB = rnorm(1000, ssb(result.xsa.stock), result.xsa.sigma * ssb(result.xsa.stock)),
398F = rnorm(1000, fbar(result.xsa.stock), result.xsa.sigma * fbar(result.xsa.stock)),
399Catch = catch(result.xsa.stock)
400)
401
402savePic("output/5_XsaEstimates/summary_uncertainty.png", pics)
403remove(endYear, pics)
404
405# perform residual diagnostics
406pic <- bubbles(age~year, data=result.xsa.fit@index.res, warning=FALSE)
407suppressWarnings(savePic("output/6_Residuals/summary_all.png", pic))
408remove(pic)
409
410pic <- bubbles(age~year, data=result.xsa.fit@index.res[1], warning=FALSE)
411suppressWarnings(savePic("output/6_Residuals/summary_survey1.png", pic))
412remove(pic)
413
414pic <- bubbles(age~year, data=result.xsa.fit@index.res[2], warning=FALSE)
415suppressWarnings(savePic("output/6_Residuals/summary_survey2.png", pic))
416remove(pic)
417
418pic <- xyplot(
419data ~ year | ac(age) + qname,
420data=index.res(result.xsa.fit),
421panel = function(x,y, ...){
422panel.xyplot(x, y, ...)
423panel.loess(x,y, ...)
424panel.abline(h=0, col="gray", lty=2)
425},
426main="Surveys log catchability residuals at age")
427suppressWarnings(savePic("output/6_Residuals/catch_at_age_summary.png", pic))
428remove(pic)
429
430con <- file("output/6_Residuals/residuals.txt", encoding = "UTF-8")
431sink(con)
432print(result.xsa.fit@index.res)
433cat("\r\n")
434print("===== Summary statistics")
435print(summary(result.xsa.fit@index.res))
436sink()
437close(con)
438
439# analyse recruits-per-ssb unit
440result.sr.recssb <- rec(result.xsa.stock) / ssb(result.xsa.stock)
441tmp <- as.data.frame(log(result.sr.recssb))
442png("output/7_SR_BRP/rec_per_ssb.png", width=1900, height=1600, res=200, type="cairo")
443print(plot(tmp$year, tmp$data, type="b", xlab="Year", ylab = "Ln(Recruit/SSB)"))
444dev.off()
445remove(tmp)
446
447
448# calculate stock-recruitment relation
449# be careful to use bevholt or ricker approximation: there is different approach between eqsim and flsr packages!!!
450# Bevholt (eqsim): rec ~ log(a * ssb / (1 + b*ssb))
451# Bevholt (flsr): rec ~ (a * ssb / (b+ssb))
452# ricker (eqsim): log(a) + log(b) - b*ssb
453# ricker (flsr): a * ssb * exp(-b * ssb)
454# segreg(flsr,eqsim): ifelse(ssb < b, ssb*b, a*b)
455if (config.srmodel.eqsim.use) {
456# build SR model based on EQSIM package and MSY approach
457print("[XSA toolkit]: Built SR model by EQSIM")
458
459result.eqsim.srmodel <- eqsr_fit(result.xsa.stock,
460nsamp = config.srmodel.eqsim.simulations,
461models = config.srmodel.eqsim.models,
462remove.years = config.srmodel.eqsim.shift_years
463)
464
465savePic("output/7_SR_BRP/eqsim_model.png", eqsr_plot(result.eqsim.srmodel, ggPlot = TRUE))
466saveText("output/7_SR_BRP/eqsim_model.txt", result.eqsim.srmodel$sr.det)
467} else {
468# built Stock-Recruitment model based on FLSR and fmle()
469print("[XSA toolkit]: Built SR model by fmle()")
470result.sr.stock <- as.FLSR(window(result.xsa.stock,
471start = config.stock.window.start,
472end = config.stock.window.end))
473model(result.sr.stock) <- config.srmodel.type
474if (config.srmodel.optimization) {
475print("[XSA toolkit]: Performing SANN (Nelder-Mead, quasi-Newton, etc) optimization SR model. This can take a lot of time ...")
476result.sr.model <- fmle(result.sr.stock, method="L-BFGS-B", control=list(trace=0))
477} else {
478result.sr.model <- fmle(result.sr.stock, control=list(trace=0))
479}
480# save output
481png("output/7_SR_BRP/flsr_model.png", width=1900, height=1600, res=200, type="cairo")
482suppressWarnings(suppressMessages(plot(result.sr.model)))
483dev.off()
484
485png("output/7_SR_BRP/flsr_profile.png", width=1900, height=1600, res=200, type="cairo")
486suppressWarnings(profile(result.sr.model, plot=TRUE, trace = FALSE))
487dev.off()
488
489saveText("output/7_SR_BRP/flsr_model.txt", summary(result.sr.model))
490}
491
492print("[XSA toolkit]: Calculate BRP")
493
494# calculate Bvirgin in assumtion of SSBmax + Ci
495#startYear <- as.numeric(data.stock@range["minyear"])
496#terminalYear <- as.numeric(data.stock@range["maxyear"])
497startYear <- min(config.brp.current_range)
498terminalYear <- max(config.brp.current_range)
499df <- data.frame(year = startYear:terminalYear, ssb = as.vector(ssb(window(result.xsa.stock, start = startYear, end = terminalYear))), catch = as.vector(catch(window(result.xsa.stock, start = startYear, end = terminalYear))))
500tmp.maxssb <- df[df$ssb == max(df$ssb),]
501tmp.biomass <- tmp.maxssb$ssb + tmp.maxssb$catch
502
503# process manual BRP points
504result.brp.blim <- tmp.biomass * config.brp.blim_multiplier
505# get Bpa based on Blim and uncerteinity sd
506result.brp.bpa <- result.brp.blim * exp(qnorm(0.95) * result.xsa.sigma)
507
508# estimate BRP from EQSIM
509lastYear <- as.numeric(result.xsa.stock@range["maxyear"])
510if (config.srmodel.eqsim.use) {
511result.eqsim.brp <- eqsim_run(result.eqsim.srmodel,
512bio.years = c(lastYear-4, lastYear),
513bio.const = TRUE,
514extreme.trim = c(0.1, 0.9),
515Bpa = result.brp.bpa,
516Blim = result.brp.blim)
517result.brpsr.blim <- as.numeric(result.eqsim.srmodel$sr.det["b"])
518result.brpsr.bpa <- as.numeric(result.eqsim.srmodel$sr.det["b"]*exp(qnorm(0.95)*result.xsa.sigma))
519}
520
521if (config.srmodel.use_geomean == TRUE) {
522# create geomean SR model by latest 5 years geomean recruitment numbers
523tmp.rec.mean <- exp(mean(log(window(rec(result.xsa.stock), lastYear-5, lastYear-1))))
524# build geomean SR model
525result.sr.model <- FLSR(model = "geomean", params=FLPar(tmp.rec.mean))
526remove(tmp.rec.mean, tmp.maxssb, df, tmp.biomass)
527} else {
528# todo: process model
529result.sr.model <- FLSR(model = "segreg")
530result.sr.model@params["a"] <- as.numeric(result.eqsim.srmodel$sr.det["a"])
531result.sr.model@params["b"] <- as.numeric(result.eqsim.srmodel$sr.det["b"])
532}
533
534# plot SSB graphic with reference points Blim, Bpa
535minYear <- as.numeric(result.xsa.stock@range["minyear"])
536png("output/7_SR_BRP/ssb_blim_bpa_manual.png", width=1900, height=1600, res=200, type="cairo")
537print(
538plot(ssb(result.xsa.stock)) +
539geom_hline(aes(yintercept=result.brp.blim), linetype=2, col="red") +
540annotate(geom = "text", x = minYear+1, y = result.brp.blim+result.brp.blim*0.05, label = sprintf("Blim=%s", round(result.brp.blim, 2)), color = "red") +
541geom_hline(aes(yintercept=result.brp.bpa), linetype=2, col="blue") +
542annotate(geom = "text", x = minYear+1, y = result.brp.bpa + result.brp.bpa*0.05, label=sprintf("Bpa=%s", round(result.brp.bpa, 2)), color="blue") +
543theme_bw()
544)
545
546dev.off()
547remove(minYear)
548
549# plot SSB with reference points by SR-model
550# @todo
551minYear <- as.numeric(result.xsa.stock@range["minyear"])
552png("output/7_SR_BRP/ssb_blim_bpa_srmodel.png", width=800, height=600, res=150, type="cairo")
553print(
554plot(ssb(result.xsa.stock)) +
555geom_hline(aes(yintercept=result.brpsr.blim), linetype=2, col="red") +
556annotate(geom = "text", x = minYear+2, y = result.brpsr.blim*1.2, label = sprintf("Blim=%s", round(result.brpsr.blim, 2)), color = "red") +
557geom_hline(aes(yintercept=result.brpsr.bpa), linetype=2, col="blue") +
558annotate(geom = "text", x = minYear+2, y =result.brpsr.bpa*1.2, label=sprintf("Bpa=%s", round(result.brpsr.bpa, 2)), color="blue") +
559theme_bw()
560)
561
562dev.off()
563remove(minYear)
564
565# plot Fbar with F0.1 reference point
566minYear <- as.numeric(result.xsa.stock@range["minyear"])
567png("output/7_SR_BRP/fbar_f01_manual.png", width=1900, height=1600, res=200, type="cairo")
568print(plot(fbar(result.xsa.stock)) +
569geom_hline(aes(yintercept=config.forecast.manual_F01), linetype=2, col="red") +
570annotate(geom="text", x = minYear, y = config.forecast.manual_F01+0.1, label = sprintf("F0.1=%s", round(config.forecast.manual_F01,3)), color="red") +
571theme_bw()
572)
573
574dev.off()
575remove(minYear)
576
577# plot E = 0.4 BRP reference point (ICES advice)
578# E = F/(F+M)
579# E = exploitation rate (*100 = percentage of usage)
580result.er.table <- fbar(result.xsa.stock) / (fbar(result.xsa.stock) + mbar(result.xsa.stock))
581png("output/7_SR_BRP/e_rate04.png", width=1900, height=1600, res=200, type="cairo")
582print(plot(result.er.table) + ylab(label = "E = F/Z") +
583geom_hline(yintercept = 0.4, color = "red", linetype="dashed") +
584annotate(geom = "text", x = as.numeric(result.xsa.stock@range["minyear"]), y = 0.41, label="E = 0.4", color = "red") +
585theme_bw())
586dev.off()
587
588# Prepare forecast procedure
589print("[XSA toolkit]: Forecast procedure with different scenarious")
590data.stf <- stf(result.xsa.stock, nyears=5)
591lastYear <- as.numeric(result.xsa.stock@range["maxyear"])
592
593# perform 3-year short-term forecasts by F_SQ
594print("[XSA toolkit]: Short-term forecast by F_SQ")
595target.tmp.F_SQ <- data.frame(year=(lastYear+1):(lastYear+5), quantity="f", val=F_SQ)
596target.forecast.F_SQ <- fwdControl(target.tmp.F_SQ)
597result.forecast.F_SQ <- fwd(data.stf, sr=result.sr.model, control=target.forecast.F_SQ)
598savePic("output/8_Forecasts/F_SQ/summary_all.png", result.forecast.F_SQ)
599savePic("output/8_Forecasts/F_SQ/summary_short.png", window(result.forecast.F_SQ, lastYear, lastYear+5))
600
601saveText("output/8_Forecasts/F_SQ/ssb.txt", ssb(result.forecast.F_SQ))
602saveText("output/8_Forecasts/F_SQ/rec.txt", rec(result.forecast.F_SQ))
603saveText("output/8_Forecasts/F_SQ/fbar.txt", fbar(result.forecast.F_SQ))
604saveText("output/8_Forecasts/F_SQ/f.txt", harvest(result.forecast.F_SQ))
605saveText("output/8_Forecasts/F_SQ/stock.n.txt", stock.n(result.forecast.F_SQ))
606saveText("output/8_Forecasts/F_SQ/ssb.txt", ssb(result.forecast.F_SQ))
607saveText("output/8_Forecasts/F_SQ/catch.txt", catch(result.forecast.F_SQ))
608
609remove(target.tmp.F_SQ)
610
611# perform 3-year short-term forecasts by manual scenarius F_msy
612print("[XSA toolkit]: Manual short-term forecast at F_MSY")
613target.tmp.F_01manual <- data.frame(year=(lastYear+1):(lastYear+5), quantity="f", val=config.forecast.manual_F01)
614target.forecast.F_01manual <- fwdControl(target.tmp.F_01manual)
615result.forecast.F_01manual <- fwd(data.stf, sr=result.sr.model, control=target.forecast.F_01manual)
616
617savePic("output/8_Forecasts/F_01manual/summary_all.png", result.forecast.F_01manual)
618savePic("output/8_Forecasts/F_01manual/summary_short.png", window(result.forecast.F_01manual, lastYear, lastYear+5))
619
620saveText("output/8_Forecasts/F_01manual/ssb.txt", ssb(result.forecast.F_01manual))
621saveText("output/8_Forecasts/F_01manual/rec.txt", rec(result.forecast.F_01manual))
622saveText("output/8_Forecasts/F_01manual/fbar.txt", fbar(result.forecast.F_01manual))
623saveText("output/8_Forecasts/F_01manual/f.txt", harvest(result.forecast.F_01manual))
624saveText("output/8_Forecasts/F_01manual/stock.n.txt", stock.n(result.forecast.F_01manual))
625saveText("output/8_Forecasts/F_01manual/ssb.txt", ssb(result.forecast.F_01manual))
626saveText("output/8_Forecasts/F_01manual/catch.txt", catch(result.forecast.F_01manual))
627
628# perform 3-year short-term forecasts by manual scenarius F_MSY=config
629print("[XSA toolkit]: Manual short-term forecast at F_MSY")
630target.tmp.F_MSY <- data.frame(year=(lastYear+1):(lastYear+5), quantity="f", val=config.forecast.manual_FMSY)
631target.forecast.F_MSY <- fwdControl(target.tmp.F_MSY)
632result.forecast.F_MSY <- fwd(data.stf, sr=result.sr.model, control=target.forecast.F_MSY)
633
634savePic("output/8_Forecasts/F_MSY/summary_all.png", result.forecast.F_MSY)
635savePic("output/8_Forecasts/F_MSY/summary_short.png", window(result.forecast.F_MSY, lastYear, lastYear+5))
636
637saveText("output/8_Forecasts/F_MSY/ssb.txt", ssb(result.forecast.F_MSY))
638saveText("output/8_Forecasts/F_MSY/rec.txt", rec(result.forecast.F_MSY))
639saveText("output/8_Forecasts/F_MSY/fbar.txt", fbar(result.forecast.F_MSY))
640saveText("output/8_Forecasts/F_MSY/f.txt", harvest(result.forecast.F_MSY))
641saveText("output/8_Forecasts/F_MSY/stock.n.txt", stock.n(result.forecast.F_MSY))
642saveText("output/8_Forecasts/F_MSY/ssb.txt", ssb(result.forecast.F_MSY))
643saveText("output/8_Forecasts/F_MSY/catch.txt", catch(result.forecast.F_MSY))
644
645
646# short-term forecast at scenario1
647print("[XSA toolkit]: Short-term forecast by Scenario1")
648target.tmp.F_scen1 <- data.frame(year=(lastYear+1):(lastYear+5), quantity="f", val=c(
649config.forecast.scenario1.f_year1,
650config.forecast.scenario1.f_year2,
651config.forecast.scenario1.f_year3,
652config.forecast.scenario1.f_year4,
653config.forecast.scenario1.f_year5
654))
655target.forecast.Fsc1 <- fwdControl(target.tmp.F_scen1)
656result.forecast.F_scenario1 <- fwd(data.stf, sr=result.sr.model, control=target.forecast.Fsc1)
657
658savePic("output/8_Forecasts/F_scenario1/summary_all.png", result.forecast.F_scenario1)
659savePic("output/8_Forecasts/F_scenario1/summary_short.png", window(result.forecast.F_scenario1, lastYear, lastYear+5))
660
661saveText("output/8_Forecasts/F_scenario1/ssb.txt", ssb(result.forecast.F_scenario1))
662saveText("output/8_Forecasts/F_scenario1/rec.txt", rec(result.forecast.F_scenario1))
663saveText("output/8_Forecasts/F_scenario1/fbar.txt", fbar(result.forecast.F_scenario1))
664saveText("output/8_Forecasts/F_scenario1/f.txt", harvest(result.forecast.F_scenario1))
665saveText("output/8_Forecasts/F_scenario1/stock.n.txt", stock.n(result.forecast.F_scenario1))
666saveText("output/8_Forecasts/F_scenario1/ssb.txt", ssb(result.forecast.F_scenario1))
667saveText("output/8_Forecasts/F_scenario1/catch.txt", catch(result.forecast.F_scenario1))
668
669remove(target.tmp.F_scen1)
670
671# st forecast scenario2
672print("[XSA toolkit]: Short-term forecast by Scenario2")
673target.tmp.F_scen2 <- data.frame(year=(lastYear+1):(lastYear+5), quantity="f", val=c(
674config.forecast.scenario2.f_year1,
675config.forecast.scenario2.f_year2,
676config.forecast.scenario2.f_year3,
677config.forecast.scenario2.f_year4,
678config.forecast.scenario2.f_year5
679))
680target.forecast.Fsc2 <- fwdControl(target.tmp.F_scen2)
681result.forecast.F_scenario2 <- fwd(data.stf, sr=result.sr.model, control=target.forecast.Fsc2)
682
683savePic("output/8_Forecasts/F_scenario2/summary_all.png", result.forecast.F_scenario2)
684savePic("output/8_Forecasts/F_scenario2/summary_short.png", window(result.forecast.F_scenario2, lastYear, lastYear+5))
685
686saveText("output/8_Forecasts/F_scenario2/ssb.txt", ssb(result.forecast.F_scenario2))
687saveText("output/8_Forecasts/F_scenario2/rec.txt", rec(result.forecast.F_scenario2))
688saveText("output/8_Forecasts/F_scenario2/fbar.txt", fbar(result.forecast.F_scenario2))
689saveText("output/8_Forecasts/F_scenario2/f.txt", harvest(result.forecast.F_scenario2))
690saveText("output/8_Forecasts/F_scenario2/stock.n.txt", stock.n(result.forecast.F_scenario2))
691saveText("output/8_Forecasts/F_scenario2/ssb.txt", ssb(result.forecast.F_scenario2))
692saveText("output/8_Forecasts/F_scenario2/catch.txt", catch(result.forecast.F_scenario2))
693
694remove(target.tmp.F_scen2)
695
696# define stock names to summary plot
697name(result.forecast.F_01manual) <- sprintf("F(0.1)=%s", config.forecast.manual_F01)
698name(result.forecast.F_MSY) <- sprintf("F(MSY)=%s", config.forecast.manual_FMSY)
699name(result.forecast.F_scenario1) <- sprintf("F=%s", config.forecast.scenario1.f_year1)
700name(result.forecast.F_scenario2) <- sprintf("F=%s", config.forecast.scenario2.f_year1)
701name(result.forecast.F_SQ) <- sprintf("F(SQ)=%s", round(F_SQ, 2))
702
703# compile summary object with all forecasts
704result.forecast.all <- FLStocks(result.forecast.F_scenario1, result.forecast.F_scenario2, result.forecast.F_SQ, result.forecast.F_01manual, result.forecast.F_MSY)
705
706# save output
707savePic("output/8_Forecasts/summary_all_in_one.png", result.forecast.all)
708savePic("output/8_Forecasts/short_all_in_one.png", window(result.forecast.all, start=lastYear))
709
710
711print("[XSA toolkit]: Procedure Done! Take a look on /output/ folder")
712
713render("Result.Rmd")
714
715