forked from flr/doc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
FLBEIA_ShortLivedSmallPelagic_MSE.Rmd
1647 lines (1163 loc) · 61.9 KB
/
FLBEIA_ShortLivedSmallPelagic_MSE.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
---
title: "Conditioning FLBEIA based on life-history traits: data-limited short-lived small pelagics example"
# author: "Sonia Sanchez-Maroño and FLBEIA team"
date: "`r format(Sys.time(), '%d %B, %Y')`"
output:
github_document:
mathjax: TRUE
pdf_document:
fig_width: 6
fig_height: 4
toc: yes
tags: [FLBEIA data limited short-lived small pelagics]
license: Creative Commons Attribution-ShareAlike 4.0 International Public License
bibliography: bibliography.bib
---
```{r, ini, echo=FALSE, results='hide', message=FALSE}
# This chunk set the document environment, so it is hidden
library(knitr)
source("R/ini.R")
set.seed(1423)
```
```{r echo=FALSE, out.width='20%'}
include_graphics('images/FLBEIA_logo.png')
```
$~$
# Introduction
In this document we show how to:
1. Condition **FLBEIA** using life-history traits and an assumption on initial explotation level.
2. Test the performance of a specific HCR under different management calendars using **FLBEIA** framework.
The first part of the tutorial deals with how to condition FLBEIA based on life-history traits and
the exploitation level at the begining of the simulation period. We will consider a historical period
of 30 years, starting with a virgin population of 100,000 tons and assuming an initial exploitation as
follows:
* first 10 years: linear increase of fishing mortality levels from 0 to $F_{MSY}$
* next 20 years: constant fishing mortality at $F_{MSY}$
Next `FLBEIA` is run using the ICES Annex IV rule for category 3 stocks (i.e. stocks for which
survey-based assessments indicate trends).
In the Annex IV rule, the advice is based on the most recent advice. Generally, catch or landings data are
adjusted to change in the abundance index for the two most recent values relative to the three preceding
values (known as the 2-over-3 rule). Other reference years may be used, based on the knowledge of
the biology of the stock (e.g. species with a relatively large longevity) or the quality of the data.
In present tutorial, we will specifically use the rule that compares the last available index
with the mean of the two previous ones (known as the 1-over-2 rule), as it has been assessed
to be more appropriate for short-lived stocks [@wkdlssls2019, @wkdlssls2020].
The rule is going to be applied under three alternative management calendars with the following formulations:
<!-- ```{r fig:calendars, echo=FALSE, fig.cap="Alternative management calendars: depending on the timings of the survey, stock assessment and management. Source: @sanchez2021."} -->
<!-- include_graphics('images/flbeia_slsp/calendars.jpg') -->
<!-- ``` -->
* Interim year calendar:
This is the usual management calendar, where the TAC for year y+1 (January-December) is based on
an abundance index in the interim-year y (in the middle of the year: $1^{st}$ July).
So that there is no indication on age 1 abundance in the TAC year, which might be the bulk of
the population in the case of the short-lived species.
$$TAC_{(Jan-Dec)_{y+1}} = TAC_{(Jan-Dec)_{y}} \cdot \frac{I_y}{\frac{\sum_{i=y-2}^{y-1} I_i}{2}}$$
* In-year calendar:
In this case, the calendar period is changed and the TAC is set for the period July y to June y+1,
based to an abundance index up to year y. So that we have indications on age 1 abundance during the
first half of the management period (the $2^{nd}$ semester of year y), but not during the second one
(the $1^{st}$ semester of year y+1).
$$TAC_{Jul_{y}-Jun_{y+1}} = TAC_{Jul_{y-1}-Jun_{y}} \cdot \frac{I_y}{\frac{\sum_{i=y-2}^{y-1} I_i}{2}}$$
* Full population advice:
For this advice type, management calendar goes from January to December, and we have available
an abundance index up to year y+1 (specifically B1+ at the beginning of the year),
which provides information on all the exploitable age classes.
$$TAC_{(Jan-Dec)_{y+1}} = TAC_{(Jan-Dec)_{y}} \cdot \frac{I_{y+1}}{\frac{\sum_{i=y-1}^{y} I_i}{2}}$$
In order to cover this variety of calendars and given the fact that we are going to assume that
spawning occurs in the middle of the year, we will simulate the stock dynamics in two seasons
within a year. As a consequence, we need to do an assumption on how the TAC is shared by semester.
In this case, we will assume that 50% of the catches will be taken in each semester.
$~$
# Required packages to run this tutorial
To start the R session, we need to load FLBEIA package and some others.
```{r libs}
library(dplyr)
library(FLBEIA)
library(FLBEIAshiny)
library(FLife)
library(fishmethods)
# library(gtools) # for rdirichlet function
# library(ggplotFL)
# library(FLBRP)
library(dplyr) # for manipulating data.frames
library(tidyr)
```
$~$
# Case study definition
As an example, we will condition the Operating Model (OM) for an anchovy-like stock, characterised by
high natural mortality, full maturity at age 1 and large interannual fluctuations.
The OM is going to be seasonal (in particular by semester), age-structured (ages 0 to 6+) and
with spawning occurring at the begining of the second semester, so that the recruits (age 0)
turn age 1 at the beginning of the next year.
Firstly, we need define some general parameters, such as the number of iterations, and others related to the
stock and the spawning moment, that will be required afterwards.
```{r pars}
nit <- 2 # Number of iterations
stkn <- "ANE" # Stock name
ages <- 0:6 # age classes
fbar.ages <- c(min=1,max=3) # ages for Fbar calculation
spwn <- 0.5 # percentage of year before spawning (i.e. spawning time: 1st July)
# number of years in the historic period
init.nyr <- 30
```
The specific life-history parameters adopted will be detailed in the next sections.
$~$
## Life-history parameters
### Growth
The individual growth is determined by the growth in length and by the weight-at-age relationship.
Growth is modelled using the von Bertalanffy growth model, with parameters extracted from [@bellido2000]:
$$L_{t} = L_{\infty} \cdot \left( 1 - e^{-K \cdot (t-t0)} \right),$$
where $L_{t}$ is the length at age (t, years); $L_{\infty}$ is the asymptotic average length
(i.e., the average size at the maximum age); K is the Brody growth rate coefficient (units: $yr^{−1}$);
and $t0$ represents the age when the average size is zero.
<!-- #! +++ TO BE DECIDED if including "vonB" and "invVonB" FUNCTIONS IN FLBEIA +++ -->
```{r vonB}
# Von Bertalanffy model: linf; k; t0
# - length-at-age
vonB <- function(age, linf, k, t0) return(linf*(1-exp(-k*(age-t0))))
# - age for specific length
invVonB <- function (L, linf, k, t0) return(t0 - 1/k * log(1-L/linf))
linf <- 18.69
k <- 0.89
t0 <- -0.02
```
Next, lengths are converted to weight-at-age using the traditional length-weight model:
$$W = a\cdot L^b,$$
where $W$ represents the weight, $L$ the length and $a$ and $b$ are the parameters
that need to be estimated. In our case, we took them from `teleost` object in the FLife library [@flife].
```{r lwrel}
# Length-weight (a*L^b): a, b parameters
lw_a <- 0.004799048 # or teleost["a","Engraulis encrasicolus",drop=TRUE]
lw_b <- 3.134380952 # or teleost["b","Engraulis encrasicolus",drop=TRUE]
```
Mean weights-at-age are calculated for different moments in the year:
* at the beggining of each season, for setting the weights-at-age in the stock in each semester; and
* at the middle of each season, for setting the weights-at-age in the catches in each semester.
Therefore, to calculate the mean weights-at-age, first we calculate the mean length-at-age using the
Von Bertalanffy model and then we transform them into weights using the length-weight relationship.
```{r wage}
# Mean weight at age: from Von Bertalanffy + length-weight relationship
# - stock
# 1st semester (weights at age at the begging of the year)
ages_stks1 <- ages
mla_stks1 <- vonB(ages_stks1, linf, k, t0)
mwa_stks1 <- lw_a*mla_stks1^lw_b
# 2nd semester (weights at age at spawning time)
ages_stks2 <- ages + spwn
mla_stks2 <- vonB(ages_stks2, linf, k, t0)
mwa_stks2 <- lw_a*mla_stks2^lw_b
# - catch
# 1st semester (weights at age in the middle of the season)
ages_cats1 <- ages + 0.25
mla_cats1 <- vonB(ages_cats1, linf, k, t0)
mwa_cats1 <- lw_a*mla_cats1^lw_b
# 2nd semester (weights at age in the middle of the season)
ages_cats2 <- ages + 0.75
mla_cats2 <- vonB(ages_cats2, linf, k, t0)
mwa_cats2 <- lw_a*mla_cats2^lw_b
# All together
dat <- rbind( data.frame( type = "stock", season = 1, age=ages, mwa=mwa_stks1),
data.frame( type = "stock", season = 2, age=ages, mwa=mwa_stks2),
data.frame( type = "catch", season = 1, age=ages, mwa=mwa_cats1),
data.frame( type = "catch", season = 2, age=ages, mwa=mwa_cats2))
ggplot(dat, aes( age, mwa, colour=type)) +
geom_line() +
facet_grid(season ~.) +
labs(y = "mwa (gr)")
```
In case of lacking information on $K$, it can be aproximated based on $L_{\infty}$,
whereas $t0$ can be aproximated based on $L_{\infty}$ and $K$ values, as follows:
* @gislason2008 provides 3 alternatives:
+ for all combined species: $K = 3.15 L_{\infty}^{-0.64}$
+ for demersal species: $K = 3.07 L_{\infty}^{-0.64}$
+ for pelagic species: $K = 6.48 L_{\infty}^{-0.83}$
* @flife: $$t0 = - e^{- 0.3922 - 0.2752 \log(L_{\infty}) - 1.038 \log(K)}$$
### Maturity
We consider a knife-edge maturity, with full maturation at age 1 or older and model it
using the `knife` function from FLife package [@flife].
```{r knifemat}
# Knife-edge maturity: a1
a1_mat <- 1 # age at full maturity
mata <- knife( age=FLQuant(ages,dimnames=list(age=ages)),
params=FLPar(a1=a1_mat))[drop=TRUE]
mata
```
Alternative formulations could be used, such as the logistic maturity ogive, available at
FLife package [@flife] in `logistic` function. If neither $l50$ nor $a50$ are available,
they can be calculated by an approximation based on $L_\infty$ [@flife]. For example,
```{r logmat}
# Logistic model: a50, ato95, asym
l50_mat <- 0.72 * linf^0.93 # L50: length at which 50% of individuals are mature
a50_mat <- invVonB(l50_mat, linf, k, t0) # a50: age at which 50% of individuals are mature
ato95_mat <- 1 # lag between a50 and first age with full maturity
asym_mat <- 1 # fixed maturity for older ages
matb <- logistic( age=FLQuant(ages,dimnames=list(age=ages)),
params=FLPar(a50=a50_mat, ato95=ato95_mat, asym=asym_mat))[drop=TRUE]
matb
```
### Natural mortality
Alternative values for natural mortality can be estimated using the function `M.empirical`
in fishmethods package [@fishmethods] based on the life-history parameters defined above and
other parameters, such as the sea water temperature.
For this case, we estimate variable natural mortality-at-age, based on @gislason2010.
```{r mage}
# Natural mortality
# Linf : Length-infinity value from a von Bertalanffy growth curve (total length-cm
# Kl : growth coefficient (per year) from a von Bertalanffy growth curve for length
# Bl : body length in cm
# method: 9 for variable M@age based on Gislason et al. (2010)
# calculate mean weights at age in the middle of the year
# (with some correction for age 0, as only existing in the second semester)
ages_yr <- ages+c(0.75,rep(0.5,length(ages)-1)) # mid-year
mla <- vonB(ages_yr, linf, k, t0)
Mage <- mla * NA
for (i in 1:length(Mage))
Mage[i] <- M.empirical(Linf = linf, Kl = k, Bl=mla[i], method = 9)
Mage
```
However, alternative values could be estimated using other methods, as for example global values
for all age classes. See detailed list of methods and required input parameters by typing
`?M.empirical`.
Different values can be estimated with the parameters available from now, so that we can take
for example the mean of them discarded those considered irrealistic (e.g., Roff's method estimate).
```{r mempir, eval=FALSE}
# Constant M based on tmax: Hoening (1983)
# TC : mean water temperature (Celsius) experienced by the stock
# tmax: oldest age observed for the species
M.empirical(Linf = linf, Kl = k,
TC = 16, # assumption from http://www.watertemperature.org/Bay-of-Biscay--Geo.html
tmax = ages[length(ages)],
tm = 0.5, method = c(1, 3, 4, 5, 10, 11))
```
### Productivity
The stock productivity is defined by the stock-recruitment relationship (SRR). But fitting a SRR is
not viable in the cases when there is not an assessment of the stock.
Nevertheless, we can construct an scenario on SRR using the parameterization of the SRR which uses
steepness ($s$, proportion of recruits produced by 20% of the virgin spawning stock),
virgin biomass ($B0$) and spawning per recruit ($spr0$) parameters.
In this case, we assumed:
* steepness of 0.75 (that is, medium productivity, see @jardim2015), as high steepness value is indicative of a resilient population (REF Subbey) as the anchovy stocks seem to be
* virgin biomass: 10,0000 tonnes, as in this case we were interested in comparing the performance of different HCRs so that the absolute levels were not important.
* spawning per recruit: was calculated by estimating R0 as a function of B0 (as R0/B is constant).
```{r srrpars}
# Beverton-Holt SR
# s : steepness (proportion of recruits produced by 20% of the virgin spawning stock)
# High steepness --> resilient population.
# v : virgin biomass (e.g 20 times maximum observed catches)
# spr0 : spawners per recruit at F=0
s <- 0.75
B0 <- 100000
```
In order to estimate the spawning per recruit, we create a function that calculates expected numbers-at-age
under equilibrium (i.e. F=0), based on assummed recruitment in numbers-at-age.
<!-- #! +++ TO BE DECIDED if including "nage" FUNCTION IN FLBEIA +++ -->
```{r nagefun}
# Function to estimate biomass at age given:
# - ages: ages values (numeric vector)
# - Mage: maturity at age (numeric vector)
# - R0 : initial recruits in mass (numeric)
nage <- function(ages, Mage, R) {
N <- numeric(length(ages))
# - age 0
N[1] <- R
# - intermediate ages
for (a in 2:length(ages))
N[a] <- N[a-1] * exp(-Mage[a-1])
# - plusgroup
N[length(ages)] <- sum(N[length(ages)] *
exp(-(0:(100-ages[length(ages)]))*Mage[length(ages)]))
return(N)
}
```
On the one hand, we need to calculate the spawning per recruit, which is a constant factor
corresponding to the ratio SSB0/R0.
Based on this value, then we can obtain the R0 that leads us to the selected B0 value.
Assuming an initial R0 of 1000 tons, we get the R0 corresponding to a virgin biomass at 100,000 tonnes.
```{r spr}
mwa_spwn <- mwa_stks2/1000 # spawning at the beginnig of the 2nd semester
# Estimate R0 as a function of B0 (as R0/B is constant)
R0ini <- 1000 # should be at spawning time (i.e. 1st July, as spwn=0.5)
# --> Some alternatives:
# - a = sr_params["a"] * exp(-Mage[1]/2) to move to spawning time; or
# - Mage[1] = Mage[1]/2 for generating Nini
Mage[1] <- Mage[1]/2
Nini <- nage(ages, Mage = Mage, R = R0ini) # expected numbers under equilibrium, given R0 (thousands)
SSBini <- sum(Nini * exp(-spwn*Mage) * mata * mwa_spwn) # ssb in tons
spr0 <- SSBini/R0ini # ratio R0/B is constant
R0 <- B0 * 1/spr0 # as our initial SSB is B0
```
Now we transform this parameters (`s`, `v` and `spr0`) to the classical parameterization of
Beverton & Holt SR model (with `a` and `b` parameters, $rec = a * \frac{ssb}{b + ssb}$
using `abPars` function in FLCore package [@flcore].
And we save this information in an `FLSR` object, that will be afterwards used to build the
`FLSRsim` class used in `FLBEIA` to simulate the recruitment in age structured stocks.
```{r srr}
sr_model <- "bevholt"
# Use 'abPars' function in FLCore to obtain the parameters of the
# classical parameterization of beverton & holt SR model.
sr_params <- unlist(abPars(s = s, v = B0, spr0 = spr0, model = sr_model))
# Create FLSR object
srm <- FLSR(name = stkn, params = FLPar(unlist(sr_params)), model = sr_model)
```
To show graphically the fitted SR:
```{r srrPlot}
sr.dat <- data.frame( ssb = seq(0,1e+05,1000)) %>%
mutate(rec = sr_params[["a"]] * ssb / (sr_params[["b"]] + ssb))
ggplot(sr.dat, aes(ssb, rec)) +
geom_line() +
geom_hline(yintercept=R0, linetype = "dashed", color = "red") +
geom_text(aes(0,R0,label = "R0", vjust = 1.5), color = "red")
```
## Selectivity
As we have no information on fishing patterns, selectivity was assumed to be equal to maturity in this case.
```{r sel}
sela <- mata
```
Below, several examples on how to estimate alternative selectivity patterns given life-history parameters.
```{r selalt}
# double normal selectivity ogive (from FLife - dnormal function)
a1_sel <- 4 # age for full selectiviy
sl_sel <- 2 # age lag between a50 and age at full selectivity
sr_sel <- 50000 # shaping parameter
sela1 <- dnormal( age=FLQuant(ages,dimnames=list(age=ages)),
params=FLPar(a1=a1_sel, sl=sl_sel, sr=sr_sel))[drop=TRUE]
sela1
# Knife-Edge
sela2 <- knife( age=FLQuant(ages,dimnames=list(age=ages)),
params=FLPar(a1=round(a50_mat,0)))[drop=TRUE] #! to be decided a1 value
sela2
# Logistic (same as maturity pattern)
sela3 <- logistic( age=FLQuant(ages,dimnames=list(age=ages)),
params=FLPar(a50=a50_mat, ato95=ato95_mat, asym=asym_mat))[drop=TRUE]
sela3
```
For checking documentation on the different functions, use the `?` command followed by the name of the
function (e.g. `?dnormalFn`)
$~$
## Initial population
In order to estimate initial numbers-at-age, we need to calculate the pristine biomass using the selected
SRR and the natural mortality.
```{r pristineB}
pristineN <- nage(ages, Mage = Mage, R = R0) # R = sr_params["a"] aproximation
# CHECK
B0 # virgin biomass
sum(pristineN * exp(-spwn*Mage) * mwa_spwn * mata) # pristine SSB in tons (if numbers in thousands)
```
At that moment, we have enough information to start conditioning the population.
So, we generate an `FLStock` object with the previous estimates, that will serve to complete the
different FLBEIA input objects.
```{r flstock}
# with 2 seasons and 2 iterations
stk <- FLStock( name = stkn,
stock.wt = FLQuant(NA, dim = c(length(ages),init.nyr,1,2,1,nit),
dimnames = list(age=ages,year=1:init.nyr,iter=1:nit)))
# nit iterations
stk <- propagate( stk, nit)
units(harvest(stk)) <- "f"
units(stock.wt(stk)) <- "kg"
# Mean weight at age by semester (in kg)
stock.wt(stk)[,,,1,] <- mwa_stks1/1000
stock.wt(stk)[,,,2,] <- mwa_stks2/1000
# F range to estimate mean F
range(stk)[c("minfbar","maxfbar")] <- fbar.ages
# Prop of spawn before M and F
ssb.ss <- rec.ss <- 2
# (assumed spawning in the middle of the year)
if (spwn <= 0.5) {
harvest.spwn(stk)[,,,1,] <- m.spwn(stk)[,,,1,] <- spwn/0.5
harvest.spwn(stk)[,,,2,] <- m.spwn(stk)[,,,2,] <- 0
}
# Selectivity
harvest(stk) <- sela
harvest(stk)[,1,] <- 0 # no catches in pristine status
# Natural mortality and maturity
m(stk) <- Mage/2
m(stk)[1,,,1,] <- 0 # different for age 0, as rec occurs mid-year (not 1st Jan)
m(stk)[1,,,2,] <- Mage[1]
mat(stk) <- mata
# Initial numbers: virgin biomass
stock.n(stk)[ ,1,,1,] <- pristineN
stock.n(stk)[ ,1,,2,] <- stock.n(stk)[,1,,1,] * exp(-m(stk)[,1,,1,])
stock.n(stk)[1,1,,1,] <- 0 # recruitment occurs in the 2nd semester
units(stock.n(stk)) <- "1000"
stock(stk) <- quantSums(stock.n(stk) * stock.wt(stk))
# Catches: 0 in the 1st simulation year
catch.wt(stk)[,,,1,] <- landings.wt(stk)[,,,1,] <- discards.wt(stk)[,,,1,] <- mwa_cats1/1000
catch.wt(stk)[,,,2,] <- landings.wt(stk)[,,,2,] <- discards.wt(stk)[,,,2,] <- mwa_cats2/1000
```
$~$
## Reference points
As we have adopted the assumption that catches are equally shared between semesters (i.e., 50% each),
we need to estimate the reference points as a function of the percentage of F in each semester.
So that we can select those according to a 50% share.
```{r msyruns}
# take 1st year with information on selectivity (i.e. year=2)
stk1 <- iter(window(stk, start = 2, end = 2), 1)
# BRPS estimation
#------------------
msyruns <- brps <- data.frame()
# Loop by percentage of catches in each season
for (p in seq(0.1,0.9,0.1)) {
print(paste("p =",p))
# Estimate reference points
fruns <- brpsson( stk1, B0=B0, R0=R0, rec.ss=rec.ss, ssb.ss=ssb.ss,
sr_model="bevholt", sr_params=sr_params,
Fprop = c(p, 1-p))
msyruns <- bind_rows(msyruns, fruns$runs) # simulations
brps <- bind_rows(brps, fruns$refpts) # brps values
}
```
We get two types of outputs, the simulation values `msyruns` and the reference points' estimates
`brps`. There is the possibility to see the simulated values graphically by using `plotBRPsson` function.
```{r msyrunsfig, eval=FALSE}
plotBRPsson( msyruns, pdfnm="ane_Fbar_vs_SPR.pdf")
```
Which generates a pdf file with YPR plots by percentage of F value in each semester:
```{r echo=FALSE, fig.show = "hold", out.width = "50%", fig.align = "default"}
include_graphics('images/flbeia_slsp/ypr1.png')
include_graphics('images/flbeia_slsp/ypr2.png')
```
Regarding the reference points, we obtain a data.frame with one line per F reference point type and F proportion.
Therefore, we need to filter those cases that are more in line with the assumption that 50% of catches are obtained
in each semester.
```{r brpprint}
brps$refpt <- factor( brps$refpt,
levels = c("virgin", "msy", "f0.1", "spr.20", "spr.30", "spr.35", "spr.40", "spr.50",
"F.20B0", "F.30B0", "F.35B0", "F.40B0", "F.50B0", "F.50R0", "F.90msy"))
brps <- brps %>%
group_by(refpt) %>%
filter(abs(pY_s1 - 0.5) == min(abs(pY_s1 - 0.5), na.rm = TRUE)) %>%
arrange(refpt) %>%
filter(refpt != "virgin")
as.data.frame(brps)
```
Now we need to select our $F_{MSY}$ proxy, as $F_{MSY}$ is not considered value for short-lived stocks
(as usually allows very high exploitation near to $F_{20\%B0}$, which might be used as $B_{lim}$).
A proxy for $B_{lim}$ could be the biomass that leads to 0.7R0 according to the SR model [wkmsycat342017, wklife2018],
in our case both approaches are in agreement, as $F_{20\%B0}$ is the biomass that leads to 0.75R0.
For this case, we decided to base our $F_{MSY}$ proxy on $F_{40\%B0}$ [@punt2014] (that is,
the fishing mortality rate associated with a biomass of 40% B0 at equilibrium),
which corresponds to $F=1.18$.
```{r brp}
Blim <- 0.20 * B0
F40B0 <- brps %>% filter(refpt=="F.40B0")
F40B0$fbar # 1.18
ref.pts <- c( B0 = B0, R0 = R0, Blim = Blim, Fmsy = F40B0$fbar, Bmsy=F40B0$ssb, MSY=F40B0$yield)
# F proportion in each semester (for 50% catches in each semester)
fprop_s1 <- F40B0$fprop_s1
```
$~$
# FLBEIA conditioning
With the information generated up to now (mainly the `FLStock` object), we are going to construct
the different objects that will be used as FLBEIA inputs.
Firstly, we define general parameters. These are: simulation years (with years 1-30 for the
historical period and 30 additional years, 31-60, for the projection period), ages in the stock,
number of seasons and iterations.
```{r dims}
# years
hist.yrs <- dimnames(stk)$year
hist.nyr <- length(hist.yrs)
first.yr <- as.numeric(hist.yrs[1])
proj.yr <- as.numeric(hist.yrs[hist.nyr])+1
proj.nyr <- 30
last.yr <- proj.yr+(proj.nyr-1)
hist.yrs <- first.yr:(proj.yr-1)
proj.yrs <- proj.yr:last.yr
yrs <- first.yr:last.yr
nyr <- length(yrs)
# ages
ages <- dimnames([email protected])$age
na <- length(ages)
# seasons
ns <- dim(stk)[4]
# iterations
nit <- dim(stk)[6]
```
Next, we expand the `FLStock` object to cover, not only the historical period, but also the projection
years.
```{r stkyrs}
stk <- window( stk, start=first.yr, end=last.yr)
```
And finally we will create all the arguments necessary to run FLBEIA. We can see the name of the objects
needed to run it using the function `args`. We can obtain further information on the objects using the
FLBEIA help page (`?FLBEIA`).
```{r args}
args(FLBEIA)
```
$~$
## Data objects
To start with, we create some empty `FLQuants` (the basic FLR data structure) with the dimensions to be used
in the case study (CS) that will aid the conditioning process.
The first two have no age dimension, while the last ones do.
```{r flqs}
flq <- FLQuant(1, dim = c(1,nyr,1,ns,1,nit),
dimnames = list(quant = "all", year = yrs, iter = 1:nit))
flq0 <- FLQuant(0, dim = c(1,nyr,1,ns,1,nit),
dimnames = list(quant = "all", year = yrs, iter = 1:nit))
flqa <- FLQuant(1, dim = c(na,nyr,1,ns,1,nit),
dimnames = list(age = ages, year = yrs, iter = 1:nit))
flqa0 <- FLQuant(0, dim = c(na,nyr,1,ns,1,nit),
dimnames = list(age = ages, year = yrs, iter = 1:nit))
flq1s <- FLQuant(1, dim = c(1,nyr,1,1,1,nit),
dimnames = list(quant = "all", year = yrs, iter = 1:nit))
```
### biols (OM: "real" stock)
The `FLBiols` object is a named list of `FLBiol` objects with the name of the stocks represented in each component.
Each FLBiol object represents a different stock simulated in the biological OM, corresponding with the "true"
population of the MSE simulations.
We will fill the object using the information from the `FLStock` previously created.
```{r biols}
# age structured stock
minage <- as.numeric(ages[1])
maxage <- as.numeric(ages[na])
minfbar <- range(stk)[["minfbar"]]
maxfbar <- range(stk)[["maxfbar"]]
biols <- FLBiols( stk = FLBiol(name = name(stk),
desc = "",
range = c(min = minage, max = maxage, plusgroup = maxage,
minyear = first.yr, maxyear = last.yr,
minfbar = minfbar, maxfbar = maxfbar),
n = [email protected],
wt = [email protected],
fec = predictModel(fec = flqa, model = ~ fec),
mat = predictModel(mat = stk@mat, model = ~ mat),
m = stk@m,
spwn = [email protected]
))
names(biols) <- name(stk)
# projection period
m(biols[[1]])[,ac(proj.yrs)] <- m(biols[[1]])[,ac(proj.yr-1)]
fec(biols[[1]])[,ac(proj.yrs)] <- fec(biols[[1]])[,ac(proj.yr-1)]
mat(biols[[1]])[,ac(proj.yrs)] <- mat(biols[[1]])[,ac(proj.yr-1)]
wt(biols[[1]])[,ac(proj.yrs)] <- wt(biols[[1]])[,ac(proj.yr-1)]
spwn(biols[[1]])[,ac(proj.yrs)]<- spwn(biols[[1]])[,ac(proj.yr-1)]
# replace 0 to a very small value to avoid NaN when estimating F at C=0
biols[[1]]@m[1,,,1,] <- 1e-08
```
### SRs (OM: stock-recruitment)
The `FLSRsim` object is used to store the information necessary to simulate recruitment for age-structured
populations. We will introduce uncertainty in the generated recruitments (both in historical and projection
periods) with a log-normal distribution with median equal to 1 and a standard deviation of 0.75.
Autocorrelation in residuals was not included.
```{r SRs}
SRs <- list(stk = FLSRsim( name = name(stk), desc = "",
ssb=flq, model = sr_model))
names(SRs) <- name(stk)
# both spawning and recruitment assumed at the beginning of the second semester
ssb.ss <- 2
rec.ss <- 2
# - data
SRs[[1]]@ssb[] <- ssb(stk)
SRs[[1]]@ssb[,,,-ssb.ss,] <- 0
SRs[[1]]@rec[] <- stock.n(stk)[1,]
SRs[[1]]@rec[,,,c(1:(rec.ss-1)),] <- 0
# - rectruiment distribution
SRs[[1]]@proportion[,,,-rec.ss,] <- 0
SRs[[1]]@proportion[,,, rec.ss,] <- 1 # recruits generated only in one season
# - time lag
SRs[[1]]@timelag['year',] <- dims(biols[[1]])$min # =0, because age 0 recuitment
SRs[[1]]@timelag['season',rec.ss] <- ssb.ss
# - parameters
SRs[[1]]@params[] <- sr_params
# - uncertainty
sigR <- 0.75
yr <- ac(hist.yrs[-1],proj.yrs)
SRs[[1]]@uncertainty[,yr,,rec.ss,] <- rlnorm( length(yr) * nit, 0, sigR)
```
### fleets (OM: "real" fleet)
The `FLFleetsExt` object is a named list of `FLFleetsExt` objects with the name of the fleets represented
in each component. Each FLFleetsExt object represents a different fleet simulated in the OM, corresponding
with the "true" dynamics of the fleets in the MSE simulations.
For present study, we will consider that there is only one fleet with one métier.
We do it in two steps, by firstly creating the `FLCatchExt` object (containing information on méiter's catches)
and next the `FLFleetsExt` (which contains information on effort, capacity, costs...).
However, we are not going to include economic information, as it is not under the scope of present anaysis.
```{r fleets}
# catch object
catch.obj <- FLCatchExt( name = name(stk),
alpha = flqa, beta = flqa, landings.n = [email protected],
landings = stk@catch, landings.n = [email protected],
landings.wt = [email protected],
discards = flq0, discards.n = flqa0,
discards.wt = [email protected],
landings.sel = flqa, discards.sel = flqa0)
landings.wt(catch.obj)[,ac(proj.yrs)] <- landings.wt(catch.obj)[,ac(proj.yr-1)]
discards.wt(catch.obj)[,ac(proj.yrs)] <- discards.wt(catch.obj)[,ac(proj.yr-1)]
catches.obj <- FLCatchesExt(stk = catch.obj)
names(catches.obj) <- name(stk)
# fleets
fleets <- FLFleetsExt(fl = FLFleetExt(name = "fl", effort= flq, capacity = flq*1e12,
metiers = FLMetiersExt(mt = FLMetierExt(name = "mt",
effshare = flq,
catches = catches.obj))))
fleets[[1]]@metiers[[1]]@catches[[1]]@catch.q[,ac(hist.yrs),,,,] <- stk@harvest[,ac(hist.yrs)]
fleets[[1]]@metiers[[1]]@catches[[1]]@catch.q[,ac(proj.yrs)] <-
yearMeans(fleets[[1]]@metiers[[1]]@catches[[1]]@catch.q[,ac(hist.yrs)])
```
### covars (OM: other variables of interest)
In this CS, no covariate will be considered.
```{r covars}
covars <- NULL
```
### indices (MP: observation model)
The `FLIndices` object is a named list of `FLIndex` with the indices that will be used to generate advice.
Each FLFleetsExt object represents a different observed index. The model implemented in FLBEIA to simulate
abundance indices is the classical linear model with a multiplicative error.
In present CS, we will have a biomass index observed in the middle of the year and multiplicative error
will be generated using a log-normal distribution with median equal to one and coefficient of variation equal
to 20\%. This index will be available only up to 10 years prior to first projection year.
```{r indices}
idxyr <- (proj.yr-10):last.yr
flqidx <- window(trim(flq, season=ssb.ss), start=idxyr[1], end=idxyr[length(idxyr)])
indices <- list( stk = FLIndices(B1plusIdx = FLIndex(name = name(stk), catch.wt = flqidx,
effort = flqidx, index = flqidx)))
names(indices) <- name(stk)
indices[[1]]$B1plusIdx@type <- "biomass"
yr <- idxyr[idxyr %in% hist.yrs]
cvIDX <- 0.25
indices[[1]][[1]]@index.q[] <- 1 * rlnorm(dim(flqidx)[2]*nit, 0, sqrt(log(cvIDX^2+1)))
#! BORRAR???
indices[[1]][[1]]@index[,1,] <- indices[[1]][[1]]@index.q[,1,] *
quantSums(wt(biols[[1]][-which(dimnames(biols[[1]])$age == "0"),1,,ssb.ss,]) *
n(biols[[1]][-which(dimnames(biols[[1]])$age == "0"),1,,ssb.ss,]))
indices[[1]][[1]]@range[c("startf","endf")] <- 0.5 # B1+ in the middle of the year
```
Next we need to generate the index observation in the last 10 years of the historical period.
However, we fistly we need to simulate the historical population and afterwards index observation will be done
in a different way depending on the calendar (int & iny calendars: B1+ in the middle of the interim year;
fpa: B1+ at the beggining of the following year).
### advice (MP: advice rule)
The advice object is a list with information on TACs and fleets' quota shares. However, in this case
the quota share will be equal to 1 as we have assumed that there is only one fleet exploiting the stock.
```{r advice}
advice <- list(TAC = flq1s, quota.share = list(stk = flq1s))
dimnames(advice$TAC)$quant <- names(advice$quota.share) <- name(stk)
dimnames(advice$quota.share[[1]])$quant <- names(fleets)
quant(advice$TAC) <- "stock"
quant(advice$quota.share[[1]]) <- "fleet"
```
$~$
## Control objects
The control objects are lists used to store the values that control how each part of the simulation is carried out.
There is one control object per data object.
### main.ctrl
The `main.ctrl` object declares the initial and final year of the simulations.
We want to set the first TAC in the the first proj.yr (year 31), consequently we have to start projections
one year before.
Because FLBEIA in the first projection year (year 30, in this example), just projecs the population forward
taking into account the TAC set for this year and afterwards (based on stock status) estimates the TAC
for the following year.
```{r mctrl}
main.ctrl <- list(sim.years = c(initial = proj.yrs[1]-1, final = proj.yrs[proj.nyr]))
```
### biols.ctrl
In the `biol.ctrl` object we declare the model to be used to carry the population forward in the simulation.
In his case we used `ASPG_Baranov` which stands for Age-Structured Populaton Growth with Baranov catch
equation.
```{r bctrl}
biols.ctrl <- create.biols.ctrl(stksnames = name(stk), growth.model = "ASPG_Baranov")
```
In case of interested in using Cobb-Douglas equation for generating catches-at-age, then we should select
`ASPG` which assumes that catches are taken in the middle of the season, instead of the asssumption on
continuous catches along the season in the Baranov equation.
### fleets.ctrl
The `fleets.ctrl` object controls the four processes simulated in the fleet operating model, the effort allocation, the catch production, the price formation and the capital dynamics.
Catch production is simulated using Baranov catch equation, `Baranov`, (an alternative is to use Cobb-Douglas
function by age class, `CobbDouglasAge`).
When simulating #! A CAMBIAR
Effort allocation is simulated using `SMFB` model, but as there is only one stock and one fleet with a single metier
the model calculates just the effort that produces exactly the TAC advice for the stock.
The price and the capital dynamics are maintained fixed.
We create the object using `create.fleets.ctrl` which by default already sets the seasonal share of the TAC to
50%, same as we intended.
```{r flctrl}
fleets.ctrl <- create.fleets.ctrl(fls = "fl", fls.stksnames = list(fl = name(stk)), flq = flq,
effort.models = c(fl = "SMFB"), n.fls.stks = c(fl = 1),
capital.models = c(fl = "fixedCapital"),
price.models = c(fl = "fixedPrice"),
catch.models = c("Baranov"))
```
### covars.ctrl
As there are no covariates, the control parameter is not required.
```{r cvctrl}
covars.ctl <- NULL
```
### obs.ctrl
The `obs.ctrl` object comprises the neccesary information to simulate the observed data used in the management procedure
(MP) to generate the management advice. In this object we need to define the settings for the observation of the stock
and the index.
In this CS, we have a data-limited stock for which we only have an abundance index available.
Consequently, we do not need to observe stock data, and we will use `NoObsStock` option.
The abundance index is generated using the `bio1plusInd` function which updates the index slot on the object with
the most recent abundance data (in this specific case, focusing on biomass of age 1 and older).
```{r obsctrl}
obs.ctrl <- create.obs.ctrl(stksnames = name(stk), n.stks.inds = c(1),
stks.indsnames = names(indices[[1]]),
stkObs.models = "NoObsStock",
indObs.models = "bio1plusInd")
```
### assess.ctrl
The assess.ctrl object declares the assessment model to be used for each of the stocks and, if required,
the additional settings needed to run the models. In this case no assessment model is used.
```{r assctrl}
assess.ctrl <- create.assess.ctrl(stksnames = name(stk), assess.models = "NoAssessment")
```
### advice.ctrl
Now we create the advice control object corresponding to the HCR used by ICES for category 3 stock in the
data limited framework (DLS). The HCR, known as n-over-m rule, is based on the tendency of an abundance index
in the last $n+m$ years. So that the previous year TAC is corrected by the ratio between the mean of the index
in the last $n$ years and the mean of the index in the last $m$ years. Plus a maximum change limit in the TAC
change can be set, both for decrease (lower uncentainty cap) and increase (upper uncentainty cap).
And the corresponding FLBEIA function is `IcesCat3HCR_bsafe_hrcap` which additionally
includes biomass safeguards or harvest rate limits.
See details on the function in @wkdlssls2020.
This rule requires information on:
* How to initialize the rule: the first year when the rule is applied (`cref.year`) and