diff --git a/docs/404.html b/docs/404.html index e717969d7..6fa407fe2 100644 --- a/docs/404.html +++ b/docs/404.html @@ -1,29 +1,80 @@ + - - - - + + + + Page not found (404) • mizer - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + - - - + + + + +
-
- +
+ + -
+ + +
+
-
- + - + + + + + + diff --git a/docs/CONTRIBUTING.html b/docs/CONTRIBUTING.html index 0ed510090..1c5086046 100644 --- a/docs/CONTRIBUTING.html +++ b/docs/CONTRIBUTING.html @@ -8,6 +8,13 @@ How you can contribute to mizer development • mizer + + + + + + + @@ -46,8 +53,7 @@ - - + @@ -63,15 +69,9 @@ - - - - - -
@@ -96,11 +96,13 @@
@@ -143,9 +161,9 @@

A Multi-Species Model Of The North Sea

In this section we try to pull everything together with an extended example of a multispecies model for the North Sea. First we will set up the model, project it through time using historical levels of fishing effort, and then examine the results. We then run two different future projection scenarios.

-Setting up the North Sea model

+Setting up the North Sea model

The first job is to set up the MizerParams object for the North Sea model. In the previous multispecies examples we have already been using the life-history parameters and the interaction matrix for the North Sea model. We will use them again here but will make some changes. In particular we set up the fishing gears differently.

-

The species in the model are: Sprat, Sandeel, N.pout, Herring, Dab, Whiting, Sole, Gurnard, Plaice, Haddock, Cod, Saithe, which account for about 90% of the total biomass of all species sampled by research trawl surveys in the North Sea. The NS_species_params object that comes as an example with the mizer package is a data.frame with columns for species, w_inf, w_mat, beta, sigma, R_max and k_vb.

+

The species in the model are: Sprat, Sandeel, N.pout, Herring, Dab, Whiting, Sole, Gurnard, Plaice, Haddock, Cod, Saithe, which account for about 90% of the total biomass of all species sampled by research trawl surveys in the North Sea. The NS_species_params object that comes as an example with the mizer package is a data.frame with columns for species, w_inf, w_mat, beta, sigma, k_vb and R_max.

 NS_species_params
##    species   w_inf w_mat   beta sigma  k_vb    R_max
@@ -161,8 +179,8 @@ 

## 10 Haddock 4316.5 165 558 2.1 0.271 1.84e+12 ## 11 Cod 39851.3 1606 66 1.3 0.216 8.26e+09 ## 12 Saithe 39658.6 1076 40 1.1 0.175 1.12e+11

-

We have seen before that only having these columns in the species data.frame is sufficient to make a MizerParams object. Any missing columns will be added and filled with default values by the MizerParams constructor. For example, the data.frame does not include columns for h or gamma. This means that they will be estimated using the k_vb column.

-

We will use the default density dependence in the reproduction rate, which is the Beverton-Holt shape. This requires a column R_max in the species data.frame which contains the maximum reproduction rate for each species. This column is already in the NS_species_params data.frame. The values were found through a calibration process which is not covered here but will be added to a later version of this manual.

+

We have seen before that only having these columns in the species data.frame is sufficient to make a MizerParams object. Any missing columns will be filled with default values by the MizerParams constructor. For example, the data.frame does not include columns for h or gamma. This means that they will be estimated using the k_vb column.

+

We will use the default density dependence in the reproduction rate, which is the Beverton-Holt shape. This requires a column R_max in the species data.frame which contains the maximum reproduction rate for each species. This column is already in the NS_species_params data.frame. The values were found through a calibration process which is not covered here but will be described in a separate tutorial.

At the moment we are not providing any information on the selectivity of the gears for the species. By default, the selectivity function is a knife-edge which only takes a single argument, knife_edge_size. In this model we want the selectivity pattern to be a sigmoid shape which more accurately reflects the selectivity pattern of trawlers in the North Sea. The sigmoid selectivity function is expressed in terms of length rather than weight and uses the parameters l25 and l50, which are the lengths at which 25% and 50% of the stock is selected. The length based sigmoid selectivity looks like:

\[\begin{equation} % {#eq:trawl_sel} @@ -171,28 +189,42 @@

where \(l\) is the length of an individual, \(S_l\) is the selectivity at length, \(S2 = \log(3) / (l50 - l25)\) and \(S1 = l50 \cdot S2\).

This selectivity function is included in mizer as sigmoid_length(). You can see the help page for more details. As the mizer model is weight based, and this selectivity function is length based, it uses the length-weight parameters a and b to convert between length and weight using the standard relation \(w = a l^b\). These species parameters need to be added as columns to the NS_species_params data frame.

-NS_species_params$a <- c(0.007, 0.001, 0.009, 0.002, 0.010, 0.006, 0.008, 0.004,
+NS_species_params$a <- c(0.007, 0.001, 0.009, 0.002, 0.010, 0.006, 0.008, 0.004,
                       0.007, 0.005, 0.005, 0.007)
-NS_species_params$b <- c(3.014, 3.320, 2.941, 3.429, 2.986, 3.080, 3.019, 3.198,
+NS_species_params$b <- c(3.014, 3.320, 2.941, 3.429, 2.986, 3.080, 3.019, 3.198,
                       3.101, 3.160, 3.173, 3.075)

sigmoid_length() has the arguments l25 and l50. As explained in the section on fishing gears and selectivity, the arguments of the selectivity function need to be in the gear parameter data frame. We also need a column specifying the name of the selectivity function we wish to use. Note it would probably be easier to put this data into a *.csv file and then read it in rather than type it in by hand like we do here:

 gear_params <- 
-    data.frame(species = NS_species_params$species,
+    data.frame(species = NS_species_params$species,
                gear = NS_species_params$species,
                sel_func = "sigmoid_length",
-               l25 =  c(7.6, 9.8, 8.7, 10.1, 11.5, 19.8, 16.4, 19.8, 11.5,
+               l25 =  c(7.6, 9.8, 8.7, 10.1, 11.5, 19.8, 16.4, 19.8, 11.5,
                         19.1, 13.2, 35.3),
-               l50 = c(8.1, 11.8, 12.2, 20.8, 17.0, 29.0, 25.8, 29.0, 17.0,
-                       24.3, 22.9, 43.6))
+ l50 = c(8.1, 11.8, 12.2, 20.8, 17.0, 29.0, 25.8, 29.0, 17.0, + 24.3, 22.9, 43.6)) +gear_params

+
##    species    gear       sel_func  l25  l50
+## 1    Sprat   Sprat sigmoid_length  7.6  8.1
+## 2  Sandeel Sandeel sigmoid_length  9.8 11.8
+## 3   N.pout  N.pout sigmoid_length  8.7 12.2
+## 4  Herring Herring sigmoid_length 10.1 20.8
+## 5      Dab     Dab sigmoid_length 11.5 17.0
+## 6  Whiting Whiting sigmoid_length 19.8 29.0
+## 7     Sole    Sole sigmoid_length 16.4 25.8
+## 8  Gurnard Gurnard sigmoid_length 19.8 29.0
+## 9   Plaice  Plaice sigmoid_length 11.5 17.0
+## 10 Haddock Haddock sigmoid_length 19.1 24.3
+## 11     Cod     Cod sigmoid_length 13.2 22.9
+## 12  Saithe  Saithe sigmoid_length 35.3 43.6

Note that we have set up a gear column so that each species will be caught by a separate gear named after the species.

-

In this model we are interested in projecting forward using historical fishing mortalities. The historical fishing mortality from 1967 to 2010 for each species is stored in the csv file NS_f_history.csv included in the package. As before, we can use read.csv() to read in the data. This reads the data in as a data.frame. We want this to be a matrix so we use the as() function:

-
-f_location <- system.file("doc/NS_f_history.csv", package = "mizer")
-f_history <- as(read.csv(f_location, row.names = 1), "matrix")
-

We can take a look at the first years of the data:

+

In this model we are interested in projecting forward using historical fishing mortalities. The historical fishing mortality from 1967 to 2010 for each species is stored in the csv file NS_f_history.csv included in the package. As before, we can use read.csv() to read in the data. This reads the data in as a data.frame. We want this to be a matrix so we use the as() function:

-head(f_history)
+f_location <- system.file("doc/NS_f_history.csv", package = "mizer") +f_history <- as(read.csv(f_location, row.names = 1), "matrix")
+

We can take a look at the first years of the data:

+
+head(f_history)
##      Sprat Sandeel N.pout   Herring        Dab   Whiting      Sole Gurnard
 ## 1967     0       0      0 1.0360279 0.09417655 0.8294528 0.6502019       0
 ## 1968     0       0      0 1.7344576 0.07376065 0.8008995 0.7831250       0
@@ -209,20 +241,15 @@ 

## 1972 0.4522231 1.3279087 0.8393267 0.5796321

Fishing mortality is calculated as the product of selectivity, catchability and fishing effort. The values in f_history are absolute levels of fishing mortality. We have seen that the fishing mortality in the mizer simulations is driven by the fishing effort argument passed to the project() function. Therefore if we want to project forward with historical fishing levels, we need to provide project() with effort values that will result in these historical fishing mortality levels.

One of the model parameters that we have not really considered so far is catchability. Catchability is a scalar parameter used to modify the fishing mortality at size given the selectivity at size and effort of the fishing gear. By default catchability has a value of 1, meaning that an effort of 1 results in a fishing mortality of 1 for a fully selected species. When considering the historical fishing mortality, one option is therefore to leave catchability at 1 for each species and then use the f_history matrix as the fishing effort. However, an alternative method is to use the effort relative to a chosen reference year. This can make the effort levels used in the model more meaningful. Here we use the year 1990 as the reference year. If we set the catchability of each species to be the same as the fishing mortality in 1990 then an effort of 1 in 1990 will result in the fishing mortality being what it was in 1990. The effort in the other years will be relative to the effort in 1990.

-
-gear_params$catchability <- as.numeric(f_history["1990",])
+
+gear_params$catchability <- as.numeric(f_history["1990",])

Considering the other model parameters, we will use default values for all of the other parameters apart from kappa, the carrying capacity of the resource spectrum (see see the section on resource density). This was estimated along with the values R_max as part of the calibration process.

We now have all the information we need to create the MizerParams object using the species parameters data.frame.

-
+
 params <- newMultispeciesParams(NS_species_params, 
                                 interaction = inter, 
                                 kappa = 9.27e10,
                                 gear_params = gear_params)
-
## Warning in `[<-.factor`(`*tmp*`, is.na(gear_params$sel_func), value =
-## "knife_edge"): invalid factor level, NA generated
-
-## Warning in `[<-.factor`(`*tmp*`, is.na(gear_params$sel_func), value =
-## "knife_edge"): invalid factor level, NA generated
## Note: No h provided for some species, so using f0 and k_vb to calculate it.
## Note: Because you have n != p, the default value is not very good.
## Note: No ks column so calculating from critical feeding level.
@@ -231,11 +258,11 @@

-Setting up and running the simulation

-

As we set our catchability to be the level of fishing mortality in 1990, before we can run the projection we need to rescale the effort matrix to get a matrix of efforts relative to 1990. To do this we want to rescale the f_history object to 1990 so that the relative fishing effort in 1990 = 1. This is done using R function sweep(). We then check a few rows of the effort matrix to check this has happened:

+Setting up and running the simulation +

As we set our catchability to be the level of fishing mortality in 1990, before we can run the projection we need to rescale the effort matrix to get a matrix of efforts relative to 1990. To do this we want to rescale the f_history object to 1990 so that the relative fishing effort in 1990 = 1. This is done using R function sweep(). We then check a few rows of the effort matrix to check this has happened:

-relative_effort <- sweep(f_history,2,f_history["1990",],"/")
-relative_effort[as.character(1988:1992),]
+relative_effort <- sweep(f_history,2,f_history["1990",],"/") +relative_effort[as.character(1988:1992),]
##          Sprat   Sandeel    N.pout  Herring      Dab   Whiting      Sole
 ## 1988 0.8953804 1.2633229 0.8953804 1.214900 1.176678 0.9972560 1.2786517
 ## 1989 1.1046196 1.2931034 1.1046196 1.232790 1.074205 0.8797926 0.9910112
@@ -248,74 +275,78 @@ 

## 1990 1.0000000 1.000000 1.0000000 1.000000 1.0000000 ## 1991 0.8096927 1.143110 0.7971275 1.001121 0.9619835 ## 1992 0.7718676 1.113074 0.8797127 0.970852 1.0528926

-

We could just project forward with these relative efforts. However, the population dynamics in the early years will be strongly determined by the initial population abundances (known as the transient behaviour - essentially the initial behaviour before the long term dynamics are reached). As this is ecology, we don’t know what the initial abundance are. One way around this is to project forward at a constant fishing mortality equal to the mortality in the first historical year until equilibrium is reached. We then can carry on projecting forward using the remaining years of effort. This approach reduces the impact of transient dynamics.

-

Here we make an initial effort matrix of 100 years at the first effort level. We need to include dimension names for the time dimension. We then stick it on top of the original matrix of historical relative effort using rbind().

+

We could just project forward with these relative efforts. However, the population dynamics in the early years will be strongly determined by the initial population abundances (known as the transient behaviour - essentially the initial behaviour before the long term dynamics are reached). As this is ecology, we don’t know what the initial abundance are. One way around this is to project forward at a constant fishing mortality equal to the mortality in the first historical year until equilibrium is reached. We then use this steady state as the initial state for the simulation. This approach reduces the impact of transient dynamics.

-initial_effort <- matrix(relative_effort[1, ], byrow = TRUE, nrow = 100,
-                         ncol = ncol(relative_effort), dimnames = list(1867:1966))
-relative_effort <- rbind(initial_effort, relative_effort)
-

We now have our parameter object and out matrix of efforts relative to 1990. This includes an initial 100 years of constant relative effort at the 1957 level, followed by the relative effort from 1957 to 2010. We use this effort matrix as the effort argument to the project() function. We use dt = 0.25 (the simulation will run faster than with the default value of 0.1, but tests show that the results are still stable) and save the results every year.

-
-sim <- project(params, effort = relative_effort, dt = 0.25)
-

Plotting the results, we can see how the biomasses of the stocks change over time. You can see the 100 year period of transients with constant fishing fishing mortality before the historical relative mortality is used from 1967.

-

To explore the state of the community it is useful to calculate indicators of the unexploited community. Therefore we also project forward for 100 years with 0 fishing effort.

+params <- projectToSteady(params, effort = relative_effort["1967", ])
+
## Convergence was achieved in 24 years.
+

We now have our parameter object and out matrix of efforts relative to 1990. We use this effort matrix as the effort argument to the project() function. We use dt = 0.25 (the simulation will run faster than with the default value of 0.1, but tests show that the results are still stable) and save the results every year.

-sim0 <- project(params, effort = 0, dt = 0.5, t_max = 100)
+sim <- project(params, effort = relative_effort, dt = 0.25, t_save = 1)
+

Plotting the results, we can see how the biomasses of the stocks change over time.

+
+plotBiomass(sim)
+

+

To explore the state of the community it is useful to calculate indicators of the unexploited community. Therefore we also project forward to the steady state with 0 fishing effort.

+
+sim0 <- projectToSteady(params, effort = 0, return_sim = TRUE)
+
## Convergence was achieved in 42 years.

-Exploring the model outputs

+Exploring the model outputs

Here we look at some of the ways the results of the simulation can be explored. We calculate the community indicators mean maximum weight, mean individual weight, community slope and the large fish indicator (LFI) over the simulation period, and compare them to the unexploited values. We also compare the simulated values of the LFI to a community target based on achieving a high proportion of the unexploited value of the LFI of \(0.8 LFI_{F=0}\).

-

The indicators are calculated using the functions described in the section about indicator functions for MizerSim objects. Here we calculate the LFI and the other community indicators for the unexploited community. When calculating these indicators we only include demersal species and individuals in the size range 10 g to 100 kg, and the LFI is based on species larger than 40 cm. Each of these functions returns a time series. We are interested only in the equilibrium unexploited values so we just select the final time step (year = 100).

-
-demersal_species <- c("Dab", "Whiting", "Sole", "Gurnard", "Plaice",
+

The indicators are calculated using the functions described in the section about indicator functions. Here we calculate the LFI and the other community indicators for the unexploited community. When calculating these indicators we only include demersal species and individuals in the size range 10 g to 100 kg, and the LFI is based on species larger than 40 cm. Each of these functions returns a time series. We are interested only in the equilibrium unexploited values so we just select the final time step.

+
+demersal_species <- c("Dab", "Whiting", "Sole", "Gurnard", "Plaice",
                       "Haddock", "Cod", "Saithe")
+final <- idxFinalT(sim0)
 lfi0 <- getProportionOfLargeFish(sim0, species = demersal_species,
                                  min_w = 10, max_w = 100e3, 
-                                 threshold_l = 40)["100"]
+                                 threshold_l = 40)[[final]]
 mw0 <- getMeanWeight(sim0, species = demersal_species,
-                     min_w = 10,max_w = 100e3)["100"]
+                     min_w = 10,max_w = 100e3)[[final]]
 mmw0 <- getMeanMaxWeight(sim0, species = demersal_species,
-                         min_w = 10, max_w = 100e3)["100", "mmw_biomass"]
+                         min_w = 10, max_w = 100e3)[final, "mmw_biomass"]
 slope0 <- getCommunitySlope(sim0, species = demersal_species,
-                            min_w = 10, max_w = 100e3)["100", "slope"]
-

We also calculate the time series of these indicators for the exploited community (we are only interested in the fishing history years, 1967 to 2010, ignoring the transients):

-
-years <- 1967:2010
-lfi <- getProportionOfLargeFish(sim, species = demersal_species,
+                            min_w = 10, max_w = 100e3)[final, "slope"]
+

We also calculate the time series of these indicators for the exploited community:

+
+lfi <- getProportionOfLargeFish(sim, species = demersal_species,
                                 min_w = 10, max_w = 100e3, 
-                                threshold_l = 40)[as.character(years)]
+                                threshold_l = 40)
 mw <- getMeanWeight(sim, species = demersal_species,
-                    min_w = 10, max_w = 100e3)[as.character(years)]
+                    min_w = 10, max_w = 100e3)
 mmw <- getMeanMaxWeight(sim, species = demersal_species, min_w = 10,
-                        max_w = 100e3)[as.character(years), "mmw_biomass"]
+                        max_w = 100e3)[, "mmw_biomass"]
 slope <- getCommunitySlope(sim, species = demersal_species, min_w = 10,
-                           max_w = 100e3)[as.character(years), "slope"]
+ max_w = 100e3)[, "slope"]

We can plot the exploited and unexploited indicators, along LFI reference level. Here we do it using ggplot2 which uses data.frames. We make three data.frames (one for the time series, one for the unexploited levels and one for the reference level): Each data.frame is a data.frame of each of the measures, stacked on top of each other.

-
-library(ggplot2)
+
+library(ggplot2)
+years <- 1967:2010
 # Simulated data
-community_plot_data <- rbind(
-    data.frame(year = years, measure = "LFI", data = lfi),
-    data.frame(year = years, measure = "Mean Weight", data = mw),
-    data.frame(year = years, measure = "Mean Max Weight", data = mmw),
-    data.frame(year = years, measure = "Slope", data = slope))
+community_plot_data <- rbind(
+    data.frame(year = years, measure = "LFI", data = lfi),
+    data.frame(year = years, measure = "Mean Weight", data = mw),
+    data.frame(year = years, measure = "Mean Max Weight", data = mmw),
+    data.frame(year = years, measure = "Slope", data = slope))
 # Unexploited data
-community_unfished_data <- rbind(
-    data.frame(year = years, measure = "LFI", data = lfi0[[1]]),
-    data.frame(year = years, measure = "Mean Weight", data = mw0[[1]]),
-    data.frame(year = years, measure = "Mean Max Weight", data = mmw0[[1]]),
-    data.frame(year = years, measure = "Slope", data = slope0[[1]]))
+community_unfished_data <- rbind(
+    data.frame(year = years, measure = "LFI", data = lfi0),
+    data.frame(year = years, measure = "Mean Weight", data = mw0),
+    data.frame(year = years, measure = "Mean Max Weight", data = mmw0),
+    data.frame(year = years, measure = "Slope", data = slope0))
 # Reference level
 community_reference_level <-
-    data.frame(year=years, measure = "LFI", data = lfi0[[1]] * 0.8)
+    data.frame(year = years, measure = "LFI", data = lfi0 * 0.8)
 # Build up the plot
-p <- ggplot(community_plot_data) + geom_line(aes(x=year, y = data)) +
-    facet_wrap(~measure, scales="free")
-p <- p + geom_line(aes(x=year,y=data), linetype="dashed",
-    data = community_unfished_data)
-p + geom_line(aes(x=year,y=data), linetype="dotted",
-    data = community_reference_level)
+ggplot(community_plot_data) + + geom_line(aes(x = year, y = data)) + + facet_wrap(~measure, scales = "free") + + geom_line(aes(x = year, y = data), linetype = "dashed", + data = community_unfished_data) + + geom_line(aes(x=year,y=data), linetype = "dotted", + data = community_reference_level)
Historical (solid) and unexploited (dashed) and reference (dotted) community indicators for the North Sea multispecies model.

Historical (solid) and unexploited (dashed) and reference (dotted) community indicators for the North Sea multispecies model. @@ -325,65 +356,63 @@

-Future projections

+Future projections

As well as investigating the historical simulations, we can run projections into the future. Here we run two projections to 2050 with different fishing scenarios.

Rather than looking at community indicators here, we will calculate the SSB of each species in the model and compare the projected levels to a biodiversity target based on the reference point \(0.1 SSB_{F=0}.\)

-

Before we can run the simulations, we need to set up arrays of future effort. We will continue to use effort relative to the level in 1990. Here we build on our existing array of relative effort to make an array for the first scenario. Note the use of the t() command to transpose the array. This is needed because R recycles by rows, so we need to build the array with the dimensions rotated to start with. We make an array of the future effort, and then bind it underneath the relative_effort array used in the previous section.

-
-scenario1 <- t(array(relative_effort["2010",], dim=c(12,40),
-    dimnames=list(NULL,year = 2011:2050)))
-scenario1 <- rbind(relative_effort, scenario1)
+

Before we can run the simulations, we need to set up arrays of future effort. We will continue to use effort relative to the level in 1990. Here we build on our existing array of relative effort to make an array for the first scenario. Note the use of the t() command to transpose the array. This is needed because R recycles by rows, so we need to build the array with the dimensions rotated to start with. We make an array of the future effort, and then bind it underneath the relative_effort array used in the previous section.

+
+scenario1 <- t(array(relative_effort["2010", ], dim = c(12, 40),
+    dimnames = list(NULL, year = 2011:2050)))
+scenario1 <- rbind(relative_effort, scenario1)

The relative effort array for the second scenario is more complicated to make and requires a little bit of R gymnastics (it might be easier for you to prepare this in a spreadsheet and read it in). For this one we need values of \(F_{MSY}\).

-
-fmsy <- c(Sprat = 0.2, Sandeel = 0.2, N.pout = 0.2, Herring = 0.25, Dab = 0.2,
+
+fmsy <- c(Sprat = 0.2, Sandeel = 0.2, N.pout = 0.2, Herring = 0.25, Dab = 0.2,
     Whiting = 0.2, Sole = 0.22, Gurnard = 0.2, Plaice = 0.25, Haddock = 0.3,
     Cod = 0.19, Saithe = 0.3)
-scenario2 <- t(array(fmsy, dim=c(12,40), dimnames=list(NULL,year = 2011:2050)))
-scenario2 <- rbind(relative_effort, scenario2)
-for (sp in dimnames(scenario2)[[2]]){
-    scenario2[as.character(2011:2015),sp] <- scenario2["2010",sp] +
-        (((scenario2["2015",sp] - scenario2["2010",sp]) / 5) * 1:5)
+scenario2 <- t(array(fmsy, dim = c(12, 40), 
+                     dimnames = list(NULL, year = 2011:2050)))
+scenario2 <- rbind(relative_effort, scenario2)
+for (sp in dimnames(scenario2)[[2]]) {
+    scenario2[as.character(2011:2015), sp] <- scenario2["2010", sp] +
+        (((scenario2["2015", sp] - scenario2["2010", sp]) / 5) * 1:5)
 }
-

Both of our new effort scenarios still include 100 years at the 1967 level to reduce the impact of the transient behaviour. We are now ready to project the two scenarios.

-
+

We are now ready to project the two scenarios.

+
 sim1 <- project(params, effort = scenario1, dt = 0.25)
 sim2 <- project(params, effort = scenario2, dt = 0.25)

We can now compare the projected SSB values in both scenarios to the biodiversity reference points. First we calculate the biodiversity reference points (from the final time step in the unexploited sim0 simulation):

-
-ssb0 <- getSSB(sim0)["100",]
-

Now we build a data.frame of the projected SSB for each species, ignoring the transients. We make use of the melt() function in the very useful reshape2 package (REF).

-
-library(reshape2)
-years <- 1967:2050
-ssb1 <- getSSB(sim1)[as.character(years),]
-ssb2 <- getSSB(sim2)[as.character(years),]
-ssb1_df <- melt(ssb1)
-ssb2_df <- melt(ssb2)
-ssb_df <- rbind(
-    cbind(ssb1_df, scenario = "Scenario 1"),
-    cbind(ssb2_df, scenario = "Scenario 2"))
-ssb_unexploited_df <- cbind(expand.grid(
-    sp = names(ssb0),
+
+ssb0 <- getSSB(sim0)[final, ]
+

Now we build a data.frame of the projected SSB for each species. We make use of the melt() function to transform arrays into data frames.

+
+years <- 1967:2050
+ssb1_df <- melt(getSSB(sim1))
+ssb2_df <- melt(getSSB(sim2))
+ssb_df <- rbind(
+    cbind(ssb1_df, scenario = "Status quo"),
+    cbind(ssb2_df, scenario = "Fmsy"))
+ssb_unexploited_df <- cbind(expand.grid(
+    sp = names(ssb0),
     time = 1967:2050),
-    value = as.numeric(ssb0),
+    value = as.numeric(ssb0),
     scenario = "Unexploited")
-ssb_reference_df <- cbind(expand.grid(
-    sp = names(ssb0),
+ssb_reference_df <- cbind(expand.grid(
+    sp = names(ssb0),
     time = 1967:2050),
-    value = as.numeric(ssb0*0.1),
+    value = as.numeric(ssb0 * 0.1),
     scenario = "Reference")
-ssb_all_df <- rbind(
-    ssb_df,
-    ssb_unexploited_df,
-    ssb_reference_df)
-p <- ggplot(ssb_all_df) +
-    geom_line(aes(x = time, y = value, colour = scenario)) +
-    facet_wrap(~sp, scales = "free", nrow = 4)
-p + theme(legend.position = "none")
+ssb_all_df <- rbind(ssb_df, ssb_unexploited_df, ssb_reference_df) +colours <- c("Status quo" = "red", "Fmsy" = "yellow", + "Unexploited" = "blue", "Reference" = "purple") +ggplot(ssb_all_df) + + geom_line(aes(x = time, y = value, colour = scenario)) + + facet_wrap(~sp, scales = "free", nrow = 4) + + theme(legend.position = "none") + + scale_colour_manual(values = colours)
Historical and projected SSB under two fishing scenarios. Status quo (red), Fmsy (yellow). Unexploited (blue) and reference levels (purple) are also shown.

Historical and projected SSB under two fishing scenarios. Status quo (red), Fmsy (yellow). Unexploited (blue) and reference levels (purple) are also shown. @@ -403,13 +432,11 @@

diff --git a/docs/articles/a_multispecies_model_of_the_north_sea_files/figure-html/plot_ns_biomass-1.png b/docs/articles/a_multispecies_model_of_the_north_sea_files/figure-html/plot_ns_biomass-1.png new file mode 100644 index 000000000..70cdba0e8 Binary files /dev/null and b/docs/articles/a_multispecies_model_of_the_north_sea_files/figure-html/plot_ns_biomass-1.png differ diff --git a/docs/articles/a_multispecies_model_of_the_north_sea_files/figure-html/plot_ns_indicators-1.png b/docs/articles/a_multispecies_model_of_the_north_sea_files/figure-html/plot_ns_indicators-1.png index 3f5cb9746..546297b24 100644 Binary files a/docs/articles/a_multispecies_model_of_the_north_sea_files/figure-html/plot_ns_indicators-1.png and b/docs/articles/a_multispecies_model_of_the_north_sea_files/figure-html/plot_ns_indicators-1.png differ diff --git a/docs/articles/a_multispecies_model_of_the_north_sea_files/figure-html/projected_ssb_ns-1.png b/docs/articles/a_multispecies_model_of_the_north_sea_files/figure-html/projected_ssb_ns-1.png index a0fd1d3b6..7785eebb7 100644 Binary files a/docs/articles/a_multispecies_model_of_the_north_sea_files/figure-html/projected_ssb_ns-1.png and b/docs/articles/a_multispecies_model_of_the_north_sea_files/figure-html/projected_ssb_ns-1.png differ diff --git a/docs/articles/community_model.html b/docs/articles/community_model.html index 9ddbf66c4..82c25c8af 100644 --- a/docs/articles/community_model.html +++ b/docs/articles/community_model.html @@ -6,6 +6,12 @@ The Community Model • mizer + + + + + + @@ -15,14 +21,13 @@ + - -
@@ -144,7 +162,7 @@

The Community Model

In this section we describe how a community model can be set up and projected through time. We then use a community model to illustrate the idea of a trophic cascade. Due to the relative simplicity of this type of model, it is useful for gently introducing some of the concepts behind the mizer package. Consequently, this section should hopefully serve as an introduction to using mizer.

-Setting up a community model

+Setting up a community model

The first stage in implementing a model using mizer is to create an object of class MizerParams. This class contains the model parameters including the life-history parameters of the species in the model, the fishing selectivity functions and the parameters of the resource spectrum.

To avoid having to make a MizerParams object directly, the newCommunityParams() wrapper function, has been provided that conveniently creates a MizerParams object specifically for a community model. The documentation for the function can be seen by clicking on the function name anywhere it appears on this page: newCommunityParams().

As can be seen in the help page, the function can take many arguments. We can ignore most of these for the moment as they almost all come with default values.

@@ -154,16 +172,16 @@

 params <- newCommunityParams(z0 = 0.05, f0 = 0.5)
## Note: Using f0, h, lambda, kappa and the predation kernel to calculate gamma.
-

Calling the function creates and returns an object of type MizerParams. We can check this using the class() function.

+

Calling the function creates and returns an object of type MizerParams. We can check this using the class() function.

-class(params)
+class(params)

## [1] "MizerParams"
 ## attr(,"package")
 ## [1] "mizer"

To work with mizer you do not have to worry about how this object is realised internally. All you need to know is that it contains all the information needed to run model simulations and that mizer provides you with functions to access, use and modify this information.

-

A very brief description of the model contained in the MizerParams object can be seen by calling the summary() method on it:

+

A very brief description of the model contained in the MizerParams object can be seen by calling the summary() method on it:

-summary(params)
+summary(params)
## An object of class "MizerParams" 
 ## Consumer size spectrum:
 ##  minimum size:   0.001
@@ -176,29 +194,31 @@ 

## Species details: ## species w_inf w_mat w_min f0 beta sigma ## 1 Community 1e+06 NA 0.001 0.5 100 2 +## ## Fishing gear details: -## Gear Target species -## Community Community

+## Gear Effort Target species +## ---------------------------------- +## Community 0.00 Community

In the summary you can see that the size range of the community spectrum has been set from \(0.001\) to \(10^{6}\) and this is divided into \(100\) size bins. Similar information is available for the resource spectrum. Additionally, the community is made up of only one species, called Community, which has an asymptotic size of \(10^{6}\) and a preferred predator prey mass ratio of \(100\). The w_mat parameter has been set to NA as it is not used when running a community model. These values have all been set by default using the newCommunityParams() function.

-Running the community model

+Running the community model

By using the newCommunityParams() function we now have a MizerParams object that contains all the information we need about the model community. We can use this to perform a simulation and project the community through time. In the mizer package, projections are performed using the project() function. You can see the help page for project() for more details and it is described fully in the section on running a simulation. We will ignore the details for the moment and just use project() to run some simple projections. The arguments for project() that we need to be concerned with are effort, which determines the fishing effort (and therefore fishing mortality) through time, and t_max, which is the number of years we want to project into the future. Initial population abundances are set automatically by the get_initial_n() function. It is possible to set your own initial abundances but we will not do this here.

To run a projection for 50 years, with no fishing effort (i.e. we want to model an unexploited community) we run:

 sim <- project(params, t_max = 50, effort = 0)

The resulting object, sim, is of type MizerSim.

-class(sim)
+class(sim)
## [1] "MizerSim"
 ## attr(,"package")
 ## [1] "mizer"

This class holds the results of the simulation, including the community and resource abundances at size through time, as well as the original model parameters. It is explained in detail in the section on running a simulation.

After running the projection, it is possible to explore the results using a range of plots and analyses. These are described fully in the section on exploring the simulation results.

-

To quickly look at the results of the projection you can call the plot() method. This plots the feeding level, predation mortality, fishing mortality and abundance by size in the last time step of the simulation, and the total biomass through time. Each of the plots can be shown individually if desired.

+

To quickly look at the results of the projection you can call the plot() method. This plots the feeding level, predation mortality, fishing mortality and abundance by size in the last time step of the simulation, and the total biomass through time. Each of the plots can be shown individually if desired.

-plot(sim)
+plot(sim)

In the above plot there are several things going on that are worth talking about. Looking at the total biomass of the community against time, you can see that the biomass quickly reaches a stable equilibrium. The other panels show what is happening at the last time step in the simulation, which in this case is when the community is at equilibrium. Fishing mortality is 0 because we set the effort argument to 0 when running the simulation. The predation mortality rate is clearly a function of size, with the smallest sizes experiencing the highest levels of predation. The feeding level describes how satiated an individual is, with 0 being unfed, and 1 being full satiated. The feeding level at size will be strongly affected by the values of the f0 and alpha arguments passed to the newCommunityParams() function.

The resource and community spectra are shown in the bottom panel of the plot (the plotted resource spectrum has been truncated to make for a better plot, but really extends all the way back to \(8.11\times 10^{-11}\) g). You can see that the community spectrum forms a continuum with the resource spectrum. This is strongly affected by the level of fixed reproduction rate (the reproduction argument passed to newCommunityParams())

@@ -215,24 +235,24 @@

pred_mort_final <- pred_mort[idxFinalT(sim), ]

If you plot this predation mortality on a log-log scale you can see how the predation mortality declines to almost zero for the largest sizes.

-plot(x = w(params), y = pred_mort_final, log = "xy", type = "l", 
+plot(x = w(params), y = pred_mort_final, log = "xy", type = "l", 
      xlab = "Size [g]", ylab = "Predation mortality [1/year]")

Note how we used w(sim) to get the vector of sizes to plot along the x-axis and how we specified that we wanted to have logarithmic axes.

-

In the long run it is worthwhile to use the ggplot2 package for creating plots, so we show also how you would create the above graph with ggplot(). For more detail see the section on using ggplot2 and plotly with mizer.

+

In the long run it is worthwhile to use the ggplot2 package for creating plots, so we show also how you would create the above graph with ggplot(). For more detail see the section on using ggplot2 and plotly with mizer.

-library(ggplot2)
-sd <- data.frame(x = w(params), y = pred_mort_final)
-ggplot(sd, aes(x = x, y = y)) +
-  geom_line() +
-  scale_x_log10() + scale_y_log10() +
-  xlab("Size [g]") + ylab("Predation mortality [1/year]")
+library(ggplot2) +sd <- data.frame(x = w(params), y = pred_mort_final) +ggplot(sd, aes(x = x, y = y)) + + geom_line() + + scale_x_log10() + scale_y_log10() + + xlab("Size [g]") + ylab("Predation mortality [1/year]")
## Warning: Transformation introduced infinite values in continuous y-axis

-Example of a trophic cascade with the community model

+Example of a trophic cascade with the community model

It is possible to use the community model to simulate a trophic cascade. To do this we need to perform two simulations, one with fishing and one without.

This means we need to consider how fishing is handled in mizer. The newCommunityParams() function automatically sets the fishing selectivity to have a knife-edge shape, with only individuals larger than 1 kg selected (the size at the knife-edge can be changed by setting the knife_edge_size argument). Although it is possible to change the selectivity function, here we will use the default knife-edge selectivity. We set up the parameter object with default parameters:

@@ -244,13 +264,13 @@ 

Now we want to simulate again, this time with fishing. In the simulations, fishing mortality is calculated as the product of the fishing selectivity, effort and catchability (see the section on fishing gears for more details). By default catchability is set to 1. This means that a fishing effort of 1 will result in a fishing mortality of 1/year for fully selected sizes. Here we run a simulation with fishing effort set to 1 for the duration of the simulation:

 sim1 <- project(params_knife, effort = 1, t_max = 50)
-

You can compare the difference between these scenarios by using the plot() method as before. Of particular interest is the fishing mortality at size. The knife-edge selectivity at 1000 g can be clearly seen and an effort of 1 has resulted in a fishing mortality of 1 for the fully selected sizes.

+

You can compare the difference between these scenarios by using the plot() method as before. Of particular interest is the fishing mortality at size. The knife-edge selectivity at 1000 g can be clearly seen and an effort of 1 has resulted in a fishing mortality of 1 for the fully selected sizes.

-plot(sim1, power = 2)
+plot(sim1, power = 2)

To explore the presence of a trophic cascade, we are interested in looking at the relative change in abundance when the community is fished compared to when it is not fished. To do this we need to get the abundances at size from the simulation objects. This is done with the N() function, which returns a three dimensional array with dimensions time x species x size. Here we have 51 time steps (50 from the simulation plus one which stores the initial population), 1 species and 100 sizes:

-dim(N(sim0))
+dim(N(sim0))
## [1]  51   1 100

We want the abundances in the final time step, and we can use these to calculate the relative abundances:

@@ -260,16 +280,16 @@ 

relative_abundance <- finalN(sim1) / finalN(sim0)

This can then be plotted using basic R plotting commands.

-plot(x = w(params), y = relative_abundance, log = "x", type = "n",
+plot(x = w(params), y = relative_abundance, log = "x", type = "n",
     xlab = "Size (g)", ylab = "Relative abundance")
-lines(x = w(params), y = relative_abundance)
-lines(x = c(min(w(params)), max(w(params))), y = c(1, 1), lty = 2)
+lines(x = w(params), y = relative_abundance) +lines(x = c(min(w(params)), max(w(params))), y = c(1, 1), lty = 2)

The impact of fishing on species larger than 1000g can be clearly seen. The fishing pressure lowers the abundance of large fish (the decrease in relative abundance at 1000 g). This then relieves the predation pressure on their smaller prey (the preferred predator-prey size ratio is given by the \(\beta\) parameter, which is set to 100 by default), leading to an increase in their abundance. This in turn increases the predation mortality on their smaller prey, which reduces their abundance and so on.

-The impact of changing \(\sigma\) +The impact of changing \(\sigma\)

As described above, the \(\sigma\) parameter determines the width of the predator prey size preference. Here we take a look at how changing the value of \(\sigma\) can affect the dynamics of the community.

In the examples above, \(\sigma\) is set in the newCommunityParams() function by default to a value of \(2\). We can see this by looking at the sigma column of the species_params data frame that is contained in the MizerParams object:

@@ -305,13 +325,11 @@

diff --git a/docs/articles/community_model_files/figure-html/plot_comm_biomass_sigma1-1.png b/docs/articles/community_model_files/figure-html/plot_comm_biomass_sigma1-1.png index 2b5878f65..634df3ba6 100644 Binary files a/docs/articles/community_model_files/figure-html/plot_comm_biomass_sigma1-1.png and b/docs/articles/community_model_files/figure-html/plot_comm_biomass_sigma1-1.png differ diff --git a/docs/articles/community_model_files/figure-html/plot_relative_comm_abund-1.png b/docs/articles/community_model_files/figure-html/plot_relative_comm_abund-1.png index 70c3ce45d..08e98c5d4 100644 Binary files a/docs/articles/community_model_files/figure-html/plot_relative_comm_abund-1.png and b/docs/articles/community_model_files/figure-html/plot_relative_comm_abund-1.png differ diff --git a/docs/articles/community_model_files/figure-html/print_plot_comm_fmort-1.png b/docs/articles/community_model_files/figure-html/print_plot_comm_fmort-1.png index 3e6924e7a..afa834377 100644 Binary files a/docs/articles/community_model_files/figure-html/print_plot_comm_fmort-1.png and b/docs/articles/community_model_files/figure-html/print_plot_comm_fmort-1.png differ diff --git a/docs/articles/community_model_files/figure-html/print_plot_comm_m2-1.png b/docs/articles/community_model_files/figure-html/print_plot_comm_m2-1.png index 05bf2db01..1fdef6aa5 100644 Binary files a/docs/articles/community_model_files/figure-html/print_plot_comm_m2-1.png and b/docs/articles/community_model_files/figure-html/print_plot_comm_m2-1.png differ diff --git a/docs/articles/community_model_files/figure-html/print_plot_comm_sim-1.png b/docs/articles/community_model_files/figure-html/print_plot_comm_sim-1.png index 282a9d3ec..eeb6e791d 100644 Binary files a/docs/articles/community_model_files/figure-html/print_plot_comm_sim-1.png and b/docs/articles/community_model_files/figure-html/print_plot_comm_sim-1.png differ diff --git a/docs/articles/developer_FAQ.html b/docs/articles/developer_FAQ.html index 212c46307..62efab993 100644 --- a/docs/articles/developer_FAQ.html +++ b/docs/articles/developer_FAQ.html @@ -6,6 +6,12 @@ Developer FAQ • mizer + + + + + + @@ -15,14 +21,13 @@ + - -
@@ -143,7 +161,7 @@

Developer FAQ

Clicking on a question will reveal the answer.

How can I prepare a pull request without a clean master branch? -

If you want to contribute some of your code to the official mizer code at https://github.com/sizespectrum/mizer you need to first create a branch in your repository that differs from the master branch of sizespectrum/mizer only by the code that you want to contribute, not by any other changes that you may have made in your fork. This answer explains how.

+

If you want to contribute some of your code to the official mizer code at https://github.com/sizespectrum/mizer you need to first create a branch in your repository that differs from the master branch of sizespectrum/mizer only by the code that you want to contribute, not by any other changes that you may have made in your fork. This answer explains how.

We assume that you have not followed the recommendation of keeping your master branch identical with that at sizespectrum/master, because if you had you could simply follow the procedure described in the “Working with git and GitHub” tutorial. Given that your master branch differs from that at sizespectrum/mizer, you need to create a new branch not from your master branch but directly from that at sizespectrum/master. Follow the following steps:

  1. Go to the “Terminal” tab in RStudio. This should be the tab next to the “Console” tab. If it is not there and you don’t know why not, then you are possibly running an old version of RStudio and you will want to update to a newer version, which is easy from the Help menu under “Check for Updates”.

  2. @@ -163,7 +181,7 @@

    Developer FAQ

    You now have a new branch that is identical to sizespectrum/master. You can now commit the relevant new code to this branch and create a pull request, as described in the “Working with git and GitHub” tutorial
How can I get a clean master branch? -

The recommended way of working in your fork of the mizer project is to keep the master branch of your repository always in sync with the master branch at https://github.com/sizespectrum/mizer, and to create a feature branch for any of your code changes, as is explained in the “Creating a branch” section of the “Working with git and GitHub” tutorial. Note however that having a clean master branch is not a prerequisite to making pull requests, see the answer to “How can I prepare a pull request without a clean master branch?” above.

+

The recommended way of working in your fork of the mizer project is to keep the master branch of your repository always in sync with the master branch at https://github.com/sizespectrum/mizer, and to create a feature branch for any of your code changes, as is explained in the “Creating a branch” section of the “Working with git and GitHub” tutorial. Note however that having a clean master branch is not a prerequisite to making pull requests, see the answer to “How can I prepare a pull request without a clean master branch?” above.

However if you would like to have a clean master branch, you can follow these steps:

  1. Create a new branch for the content of your current master branch, so that you can still switch to it in the future. To create this new branch, first make sure you have selected the master branch on the “Switch branch” dropdown in RStudio Git panel and then click the button to the left of that dropdown. @@ -201,13 +219,11 @@

    Developer FAQ

    diff --git a/docs/articles/developer_vignette.html b/docs/articles/developer_vignette.html index 586123222..71f77a2ed 100644 --- a/docs/articles/developer_vignette.html +++ b/docs/articles/developer_vignette.html @@ -6,6 +6,12 @@ Developer Guide • mizer + + + + + + @@ -15,14 +21,13 @@ + - -
@@ -142,25 +160,25 @@

Developer Guide

-Introduction

+Introduction

This guide is for you if you need to extend mizer to meet the needs of your research project. You will already have read the mizer model description in vignette("model_description") and thus be familiar with what mizer can do out of the box. You now want to implement the extension or modification of the model required for your research, and for that you need to dive into the internal workings of mizer. This guide is meant to make that as easy as possible.

-

The first thing you should do, even before reading this guide, is to go to https://github.com/sizespectrum/mizer/issues and create a new “issue”" to share your ideas and plans with the mizer community. You may get back valuable feedback and advice. Another way to get in touch with the mizer community is via the size-spectrum modelling Google group.

+

The first thing you should do, even before reading this guide, is to go to https://github.com/sizespectrum/mizer/issues and create a new “issue”" to share your ideas and plans with the mizer community. You may get back valuable feedback and advice. Another way to get in touch with the mizer community is via the size-spectrum modelling Google group.

-Setting up working environment

+Setting up working environment

In this section we describe how to set up your working environment to allow you to easily work with the mizer code. Much of it you may already have in place, so feel free to skip ahead.

-Installing R, RStudio and Git

-

Mizer is compatible with R versions 3.1 and later. If you still need to install R, simply install the latest version. This guide was prepared with R version 3.6.3 (2020-02-29).

-

This guide assumes that you will be using RStudio to work with R. There is really no reason not to use RStudio and it makes a lot of things much easier. RStudio develops rapidly and adds useful features all the time and so it pays to upgrade to the latest version frequently. This guide was written with version 1.2.1268.

-

Mizer is developed using the version control system Git and the code is hosted on GitHub. To contribute to the mizer code, you need to have the Git software installed on your system. On most Linux machines it will be installed already, but on other platforms you need to install it. You do not need to install any GUI for git because RStudio has built-in support for git. A good place to learn about using Git and GitHub is this chapter in the guide by Hadley on R package development.

+Installing R, RStudio and Git +

Mizer is compatible with R versions 3.1 and later. If you still need to install R, simply install the latest version. This guide was prepared with R version 4.1.0 (2021-05-18).

+

This guide assumes that you will be using RStudio to work with R. There is really no reason not to use RStudio and it makes a lot of things much easier. RStudio develops rapidly and adds useful features all the time and so it pays to upgrade to the latest version frequently. This guide was written with version 1.2.1268.

+

Mizer is developed using the version control system Git and the code is hosted on GitHub. To contribute to the mizer code, you need to have the Git software installed on your system. On most Linux machines it will be installed already, but on other platforms you need to install it. You do not need to install any GUI for git because RStudio has built-in support for git. A good place to learn about using Git and GitHub is this chapter in the guide by Hadley on R package development.

-Forking mizer from GitHub

-

To work with the code you will create your own git repository with a copy of the mizer code. Go to https://github.com/sizespectrum/mizer and fork it into your own repository by clicking the “Fork” button.

+Forking mizer from GitHub +

To work with the code you will create your own git repository with a copy of the mizer code. Go to https://github.com/sizespectrum/mizer and fork it into your own repository by clicking the “Fork” button.

@@ -177,7 +195,7 @@

-

If the Git option is not showing, the you need to troubleshoot, and perhaps https://happygitwithr.com/rstudio-see-git.html helps.

+

If the Git option is not showing, the you need to troubleshoot, and perhaps https://happygitwithr.com/rstudio-see-git.html helps.

In the next dialog box you let RStudio know where to find your fork.
@@ -190,12 +208,12 @@

-Setting up RStudio developer tools

-

To work with R packages as a developer, you will need to install additional tools.

+Setting up RStudio developer tools +

To work with R packages as a developer, you will need to install additional tools.

Once you have these tools in place, you should install the devtools and roxygen2 packages with

-install.packages(c("devtools", "roxygen2"))
-

You are now all set to develop R packages, and RStudio makes this extra easy. There is even a cheat sheet “Package Development with devtools” accessible from the Help menu in RStudio.

+install.packages(c("devtools", "roxygen2"))
+

You are now all set to develop R packages, and RStudio makes this extra easy. There is even a cheat sheet “Package Development with devtools” accessible from the Help menu in RStudio.

To set things up, click on Build -> More -> Configure Build Tools.

@@ -215,23 +233,23 @@

-Installing mizer

+Installing mizer

You are now ready to install the mizer package using the development code from GitHub. First you should do this with the command

-devtools::install_github("sizespectrum/mizer")
+devtools::install_github("sizespectrum/mizer")
This will automatically also install all the other packages that mizer depends on. However this uses the version of the code in the official mizer repository on GitHub, not your local copy of the code. Once you have made changes to your local code, you will want to install mizer using that code. To do this go to the “Build” tab in RStudio and click on “Install and Restart” or alternatively use the keyboard shortcut Ctrl+Shift+B.

You can watch the progress in the “Build” tab. Once the build has completed, you will see that in the console RStudio automatically runs

+library(mizer)

to load you freshly built mizer package. You will want to click “Install and Restart” whenever you have changed your local code.

-Working with git

+Working with git

You will be making your code changes in your fork of the mizer code (we are using the so-called Fork & Pull model). From time to time you will want to interact with the main mizer repository in two ways:

  1. You will want to contribute some of your code back to the mizer project, so that it benefits others and also so that it gets automatically included in future releases.

  2. @@ -242,25 +260,25 @@

-Contributor guidelines

+Contributor guidelines

-Always write tests for your code

-

We use testthat and shinytest. The test are in the directory tests/testthat.

-

Some tests compare the results of calculations to the results the code gave in the past, using the testthat::expect_known_value() test. The past values are stored in tests/testthat/values. If one of the tests gives a value that is different from the stored value, then the test throws an error and overwrites the stored value with the new result. The second time the test is run, it then no longer fails. Luckily the original values will still be in the git repository. So after you think you have fixed the error that led to the wrong result, you should revert to the old stored values before re-running the test. Reverting to the old stored values is easy: Just go to the Git tab in RStudio, select the changed files in tests/testthat/values (select, not tick), then right-click and choose Revert.

+Always write tests for your code +

We use testthat and shinytest. The test are in the directory tests/testthat.

+

Some tests compare the results of calculations to the results the code gave in the past, using the testthat::expect_known_value() test. The past values are stored in tests/testthat/values. If one of the tests gives a value that is different from the stored value, then the test throws an error and overwrites the stored value with the new result. The second time the test is run, it then no longer fails. Luckily the original values will still be in the git repository. So after you think you have fixed the error that led to the wrong result, you should revert to the old stored values before re-running the test. Reverting to the old stored values is easy: Just go to the Git tab in RStudio, select the changed files in tests/testthat/values (select, not tick), then right-click and choose Revert.

It may be that the change in the result of a calculation is intended, perhaps because your new code is more accurate than the old code. If you are 100% certain of this, but only then, should you commit the changed files in tests/testthat/values, so that these new values form the basis of future comparison tests.

-

Plots are tested with the vdiffr package. When a plot has changed, you should run vdiffr::manage_cases(), which will start a shiny gadget where you can view the changes in the plot.

+

Plots are tested with the vdiffr package. When a plot has changed, you should run vdiffr::manage_cases(), which will start a shiny gadget where you can view the changes in the plot.

-Finding your way around the mizer code

+Finding your way around the mizer code

This section is still in an early stage of development.

Mizer is organised in a modular fashion. It is separated into setup functions, simulation functions, and analysis and plotting functions.

There are several different functions for setting up a MizerParams object for specifying various concrete models. These setup functions make various simplifying assumptions about the model parameters to reduce the amount of information that needs to be specified. This usually takes the form of assuming allometric scaling laws.

@@ -269,11 +287,11 @@

The MizerParams and MizerSim objects are S4 objects, meaning that their slots are rigorously defined and are accessed with the ‘@’ notation. You do not need to learn about S4 classes in order to understand the mizer code, because the code avoids using S4 methods. In the presentation below we assume that the MizerParams object is called params and the MizerSim object is called sim.

-The MizerParams class

+The MizerParams class

An object of class ‘MizerParams’ holds all the information needed for the ‘project()’ function to simulate a model.

-Adding a new slot

+Adding a new slot

If you need to add a new slot to the MizerParams class, you need to make the following additions in the file MizerParams-class.R:

  1. Go to the section “Class definition” and add a description of you new slot with @slot.
  2. @@ -297,11 +315,11 @@

-Specialised topics

+Specialised topics

-Size of git repo

-

We should try to avoid committing too many very large files to the git repository, because the larger the repository the longer it takes to download. Currently (September 2019) the repository is still at a manageable 110 MiB. The best way to check the size of the repository is with the git-sizer, see https://github.com/github/git-sizer/

+Size of git repo +

We should try to avoid committing too many very large files to the git repository, because the larger the repository the longer it takes to download. Currently (September 2019) the repository is still at a manageable 110 MiB. The best way to check the size of the repository is with the git-sizer, see https://github.com/github/git-sizer/

We are currently storing the mizer website in the mizer repository (in the docs subdirectory). That is convenient, partly because that is where pkgdown puts it by default and GitHub serves it from there. However in the future we might consider moving the website to its own repository.

@@ -318,13 +336,11 @@

diff --git a/docs/articles/editing_website.html b/docs/articles/editing_website.html index 9579f2812..9e3c32515 100644 --- a/docs/articles/editing_website.html +++ b/docs/articles/editing_website.html @@ -6,6 +6,12 @@ Editing the Mizer Website • mizer + + + + + + @@ -15,14 +21,13 @@ + - -
@@ -142,11 +160,11 @@

Editing the Mizer Website

-Website built from package documentation

-

The mizer website at [https://sizespectrum.org/mizer/] is created programmatically from the documentation included in the mizer GitHub repository. Thus to edit the website just means editing this documentation. The website creation is performed by a slight modification of the pkgdown package. You can trigger a build in your local repository by issuing the commands

+Website built from package documentation

+

The mizer website at [https://sizespectrum.org/mizer/] is created programmatically from the documentation included in the mizer GitHub repository. Thus to edit the website just means editing this documentation. The website creation is performed by a slight modification of the pkgdown package. You can trigger a build in your local repository by issuing the commands

-devtools::install_github("gustavdelius/pkgdown", ref = "mizer")
-pkgdown::build_site()
+devtools::install_github("gustavdelius/pkgdown", ref = "mizer") +pkgdown::build_site()

This will convert all existing documentation into html files and put these into the docs subdirectory of your mizer directory. In detail:

  1. All .Rmd files in the vignettes subdirectory (and its subdirectories, if any) will produce html files of the same name in docs/articles.

  2. @@ -173,7 +191,7 @@

    right: - icon: fa-github fa-lg href: https://github.com/sizespectrum/mizer -

    This is quite self-explanatory, specifying the order of the navbar entries, their text and link destination, and whether they are on the left or right side. It is clearly easy to add additional navbar entries. It would be possible to also include drop-down items in navbar. See the pkgdown documentation for more details.

    +

    This is quite self-explanatory, specifying the order of the navbar entries, their text and link destination, and whether they are on the left or right side. It is clearly easy to add additional navbar entries. It would be possible to also include drop-down items in navbar. See the pkgdown documentation for more details.

    The file docs/articles/index.html is created according to the article: section in the _pkgdown_yml file. At an early stage it looked as follows:

    articles:
     - title: User Guides
    @@ -188,31 +206,31 @@ 

    -Changing page content

    +Changing page content

    At the top of every page on the website, except the homepage, there is a link to the page source. So it is easy to know which file to edit to make changes to a page. If you want to rebuild the website after making a change to a single page you may not want to re-build everything. You can rebuild just a single vignette. For example to rebuild this page after editing the vignette vignette/editing_website.Rmd you can call

    -pkgdown::build_article("editing_website")
    +pkgdown::build_article("editing_website")

    To rebuild the reference pages after changing the roxygen code doc you can run

    -pkgdown::build_reference()
    +pkgdown::build_reference()

    To change the homepage you edit index.md. This file is very similar to README.md that is used on the mizer homepage on GitHub, but can contain extra content like embedded videos that the GitHub homepage does not support. After changes to index.md you can update your local copy of the website with

    -pkgdown::build_home()
    +pkgdown::build_home()

    Of course these changes will affect only your local copy of the website. To get those changes reflected on the online site you will need to make a pull request for your changed files against the master branch of the upstream repository.

    -GitHub pages

    -

    The website is hosted with GitHubPages. In the settings pages of the mizer repository on GitHub the source is set to “master branch/docs folder”. This means that only the master branch controls the website.

    +GitHub pages

    +

    The website is hosted with GitHubPages. In the settings pages of the mizer repository on GitHub the source is set to “master branch/docs folder”. This means that only the master branch controls the website.

    -Embedding videos

    +Embedding videos

    It is easy to embed videos into a webpage by putting an iframe into the R Markdown source file. For example putting the line

    <iframe width="560" height="315" src="https://www.youtube.com/embed/0RlXqLbFbWc" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

    into the source of this page produced the following embedded video:

    @@ -233,13 +251,11 @@

    diff --git a/docs/articles/exploring_the_simulation_results.html b/docs/articles/exploring_the_simulation_results.html index 3632a6755..318569092 100644 --- a/docs/articles/exploring_the_simulation_results.html +++ b/docs/articles/exploring_the_simulation_results.html @@ -6,6 +6,12 @@ Exploring the Simulation Results • mizer + + + + + + @@ -15,14 +21,13 @@ + - -
    @@ -142,7 +160,7 @@

    Exploring the Simulation Results

    -Introduction

    +Introduction

    In the sections on the multispecies model and on running a simulation we saw how to set up a model and project it forward through time under our desired fishing scenario. The result of running a projection is an object of class MizerSim. What do we then do? How can we explore the results of the simulation? In this section we introduce a range of summaries, plots and indicators that can be easily produced using functions included in mizer.

    We will use the following MizerSim object for these examples, where the effort array is the one we created in the previous section on running a simulation:

    @@ -150,10 +168,10 @@ 

    -Accessing the simulation results

    -

    The projected species abundances at size through time can be obtained with N(sim). This returns a three-dimensional array (time x species x size). Consequently, this array can get very big so inspecting it can be difficult. In the example we have just run, the time dimension of n has 10 rows (one for the initial population and then one for each of the saved time steps). There are also 12 species each with 100 sizes. We can check this by running the dim() function and looking at the dimensions of the n array:

    +Accessing the simulation results +

    The projected species abundances at size through time can be obtained with N(sim). This returns a three-dimensional array (time x species x size). Consequently, this array can get very big so inspecting it can be difficult. In the example we have just run, the time dimension of n has 10 rows (one for the initial population and then one for each of the saved time steps). There are also 12 species each with 100 sizes. We can check this by running the dim() function and looking at the dimensions of the n array:

    -dim(N(sim))
    +dim(N(sim))
    ## [1]  10  12 100

    To pull out the abundances of a particular species through time at size you can subset the array. For example to look at Cod through time you can use:

    @@ -173,20 +191,20 @@ 

    -Summary functions

    -

    As well as the summary() methods that are available for both MizerParams and MizerSim objects, there are other useful summary functions to pull information out of a MizerSim object. A description of the different summary functions available is given in the summary functions help page.

    +Summary functions +

    As well as the summary() methods that are available for both MizerParams and MizerSim objects, there are other useful summary functions to pull information out of a MizerSim object. A description of the different summary functions available is given in the summary functions help page.

    All of these functions have help files to explain how they are used. (It is also possible to use most of these functions with a MizerParams object if you also supply the population abundance as an argument. This can be useful for exploring how changes in parameter value or abundance can affect summary statistics and indicators. We won’t explore this here but you can see their help files for more details.)

    The functions getBiomass() and getN() have additional arguments that allow the user to set the size range over which to calculate the summary statistic. This is done by passing in a combination of the arguments min_l, min_w, max_l and max_w for the minimum and maximum length or weight. If min_l is specified there is no need to specify min_w and so on. However, if a length is specified (minimum or maximum) then it is necessary for the species parameter data.frame (see the species parameters section) to include the parameters a and b for length-weight conversion. It is possible to mix length and weight constraints, e.g. by supplying a minimum weight and a maximum length. The default values are the minimum and maximum weights of the spectrum, i.e. the full range of the size spectrum is used.

    -Examples of using the summary functions

    -

    Here we show a simple demonstration of using a summary function using the sim object we created earlier. Here, we use getSSB() to calculate the SSB of each species through time (note the use of the head() function to only display the first few rows).

    +Examples of using the summary functions +

    Here we show a simple demonstration of using a summary function using the sim object we created earlier. Here, we use getSSB() to calculate the SSB of each species through time (note the use of the head() function to only display the first few rows).

     ssb <- getSSB(sim)
    -dim(ssb)
    +dim(ssb)
    ## [1] 10 12
    -head(ssb)
    +head(ssb)
    ##     sp
     ## time        Sprat      Sandeel       N.pout      Herring        Dab
     ##    1 210810187886 5.378411e+12 183159668755 442644004208 6885675636
    @@ -214,7 +232,7 @@ 

    As mentioned above, we can specify the size range for the getsummaryBiomass() and getN() functions. For example, here we calculate the total biomass of each species but only include individuals that are larger than 10 g and smaller than 1000 g.

     biomass <- getBiomass(sim, min_w = 10, max_w = 1000)
    -head(biomass)
    +head(biomass)

    ##     sp
     ## time        Sprat      Sandeel       N.pout      Herring        Dab
     ##    1 244119195586 4.589606e+12 238847649463 1.273446e+12 8373096367
    @@ -243,17 +261,17 @@ 

    -Functions for calculating indicators

    +Functions for calculating indicators

    Functions are available to calculate a range of indicators from a MizerSim object after a projection. A description of the different indicator functions available is given in the indicator functions help page.. You can read the help pages for each of the functions for full instructions on how to use them, along with examples.

    With all of the functions in the table it is possible to specify the size range of the community to be used in the calculation (e.g. to exclude very small or very large individuals) so that the calculated metrics can be compared to empirical data. This is used in the same way that we saw with the function getBiomass() in the section on summary functions for MizerSim objects.. It is also possible to specify which species to include in the calculation. See the help files for more details.

    -Examples of calculating indicators

    +Examples of calculating indicators

    For these examples we use the sim object we created earlier.

    The slope of the community can be calculated using the getCommunitySlope() function. Initially we include all species and all sizes in the calculation (only the first five rows are shown):

     slope <- getCommunitySlope(sim)
    -head(slope)
    +head(slope)
    ##        slope intercept        r2
     ## 1 -0.7822250  25.40779 0.8722251
     ## 2 -0.7970084  25.24922 0.8666363
    @@ -264,11 +282,11 @@ 

    This gives the slope, intercept and \(R^2\) value through time (see the help file for getCommunitySlope for more details).

    We can include only the species we want with the species argument. Below we only include demersal species. We also restrict the size range of the community that is used in the calculation to between 10 g and 5 kg. The species argument is a character vector of the names of the species that we want to include in the calculation.

    -dem_species <- c("Dab", "Whiting", "Sole", "Gurnard", "Plaice", "Haddock",
    +dem_species <- c("Dab", "Whiting", "Sole", "Gurnard", "Plaice", "Haddock",
         "Cod", "Saithe")
     slope <- getCommunitySlope(sim, min_w = 10, max_w = 5000, 
         species = dem_species)
    -head(slope)
    +head(slope)

    ##       slope intercept        r2
     ## 1 -1.096584  26.88942 0.9749307
     ## 2 -1.177678  27.21999 0.9796408
    @@ -280,18 +298,18 @@ 

    -Plotting the results

    -

    R is very powerful when it comes to exploring data through plots. Two useful packages for plotting are ggplot2 and plotly. These use data.frames for input data whereas many of the mizer functions return arrays or matrices. Fortunately it is straightforward to turn arrays and matrices into data.frames using the melt() function from the reshape2 package that mizer makes available to you. Although mizer does include some dedicated plots, it is definitely worth your time getting to grips with these other plotting packages. This will make it possible for you to make your own plots. We provide some details in the section on using ggplot2 and plotly with mizer.

    -

    Included in mizer are several dedicated plots that use MizerSim objects as inputs (see the plots help page.). As well as displaying the plots, these functions all return objects of type ggplot from the ggplot2 package, meaning that they can be further modified by the user (e.g. by changing the plotting theme). See the help page of the individual plot functions for more details. The generic plot() method has also been overloaded for MizerSim objects. This produces several plots in the same window to provide a snapshot of the results of the simulation.

    +Plotting the results

    +

    R is very powerful when it comes to exploring data through plots. Two useful packages for plotting are ggplot2 and plotly. These use data.frames for input data whereas many of the mizer functions return arrays or matrices. Fortunately it is straightforward to turn arrays and matrices into data.frames using the melt() function from the reshape2 package that mizer makes available to you. Although mizer does include some dedicated plots, it is definitely worth your time getting to grips with these other plotting packages. This will make it possible for you to make your own plots. We provide some details in the section on using ggplot2 and plotly with mizer.

    +

    Included in mizer are several dedicated plots that use MizerSim objects as inputs (see the plots help page.). As well as displaying the plots, these functions all return objects of type ggplot from the ggplot2 package, meaning that they can be further modified by the user (e.g. by changing the plotting theme). See the help page of the individual plot functions for more details. The generic plot() method has also been overloaded for MizerSim objects. This produces several plots in the same window to provide a snapshot of the results of the simulation.

    Some of the plots plot values by size (for example plotFeedingLevel() and plotSpectra()). For these plots, the default is to use the data at the final time step of the projection. With these plotting functions, it is also possible to specify a different time, or a time range to average the values over before plotting.

    -Plotting examples

    +Plotting examples

    Using the plotting functions is straightforward. For example, to plot the total biomass of each species against time you use the plotBiomass() function:

    As mentioned above, some of the plot functions plot values against size at a point in time (or averaged over a time period). For these plots it is possible to specify the time step to plot, or the time period to average the values over. The default is to use the final time step. Here we plot the abundance spectra (biomass), averaged over time = 5 to 10:

    -

    As mentioned above, and as we have seen several times in this guide, the generic plot() method has also been overloaded. This produces 5 plots in the same window (plotFeedingLevel(), plotBiomass(), plotPredMort(), plotFMort() and plotSpectra()). It is possible to pass in the same arguments that these individual plots use, e.g. arguments to change the time period over which the data is averaged.

    +

    As mentioned above, and as we have seen several times in this guide, the generic plot() method has also been overloaded. This produces 5 plots in the same window (plotFeedingLevel(), plotBiomass(), plotPredMort(), plotFMort() and plotSpectra()). It is possible to pass in the same arguments that these individual plots use, e.g. arguments to change the time period over which the data is averaged.

    -plot(sim)
    +plot(sim)

    The next section describes how to use what we have learned to model the North Sea.

    @@ -309,13 +327,11 @@

    diff --git a/docs/articles/exploring_the_simulation_results_files/figure-html/demo_summary_plot-1.png b/docs/articles/exploring_the_simulation_results_files/figure-html/demo_summary_plot-1.png index 8a5142a84..555770c89 100644 Binary files a/docs/articles/exploring_the_simulation_results_files/figure-html/demo_summary_plot-1.png and b/docs/articles/exploring_the_simulation_results_files/figure-html/demo_summary_plot-1.png differ diff --git a/docs/articles/index.html b/docs/articles/index.html index 76cf4d921..48e48d50d 100644 --- a/docs/articles/index.html +++ b/docs/articles/index.html @@ -8,6 +8,13 @@ Articles • mizer + + + + + + + @@ -46,8 +53,7 @@ - - + @@ -63,15 +69,9 @@ - - - - - -
    @@ -96,11 +96,13 @@
    +
    +

    Publications

    +

    + +
    +
    Publications
    +
    +
    +

    Developer Guide

    @@ -231,11 +253,11 @@

    Developer Guide

    @@ -261,8 +283,6 @@

    Developer Guide

    - - diff --git a/docs/articles/mizer.html b/docs/articles/mizer.html index a420e0f84..f5e2d6231 100644 --- a/docs/articles/mizer.html +++ b/docs/articles/mizer.html @@ -6,6 +6,12 @@ Getting started with mizer • mizer + + + + + + @@ -15,14 +21,13 @@ + - -
    @@ -142,7 +160,7 @@

    Getting started with mizer

    -Overview

    +Overview

    The mizer package implements multi-species size-spectrum models in R. It has been designed for modelling marine ecosystems. The general model is described in the section Size-spectrum models.

    Using mizer is relatively simple. There are four main stages, each described in more detail in sections below.

      @@ -151,34 +169,34 @@

    1. Running a simulation.

    2. Exploring the results.

    -

    If you run into any difficulties or have any questions or suggestions, let us know about it by posting about it on our issue tracker. We love to hear from you.

    -

    There is a series of YouTube videos explaining how to use and install mizer.

    +

    If you run into any difficulties or have any questions or suggestions, let us know about it by posting about it on our issue tracker. We love to hear from you.

    +

    There is a series of YouTube videos explaining how to use and install mizer.

    -Installing mizer

    +Installing mizer

    If you already have R installed on your computer, then installation of the mizer package is very simple (assuming you have an active internet connection). Just start an R session and then type:

    -

    After installing mizer, to actually use it, you need to load the package using the library() function. Note that whilst you only need to install the package once, it will need to be loaded every time you start a new R session.

    +install.packages("mizer")
    +

    After installing mizer, to actually use it, you need to load the package using the library() function. Note that whilst you only need to install the package once, it will need to be loaded every time you start a new R session.

    +library(mizer) If you still need to install R or RStudio as well, or if you are interested in installing a development version of mizer, click on the triangle below to reveal further details: -

    Mizer is compatible with R versions 3.1 and later. You can install R on your computer by following the instructions at https://cran.r-project.org/ for your particular platform.

    -

    Alternatively, if you can not or do not want to install R on your computer, you can also work with R and RStudio in your internet browser by creating yourself a free account at https://rstudio.cloud. There you can then install mizer as described above. Running mizer in the RStudio Cloud may be slightly slower than running it locally on your machine, but the speed is usually quite acceptable.

    -

    This guide assumes that you will be using RStudio to work with R. There is really no reason not to use RStudio and it makes a lot of things much easier. RStudio develops rapidly and adds useful features all the time and so it pays to upgrade to the latest version frequently. This guide was written with version 1.3.820.

    -

    The source code for mizer is hosted on GitHub. If you are feeling brave and wish to try out a development version of mizer you can install the package from here using the R package devtools (which was used extensively in putting together mizer). If you have not yet installed devtools, do

    +

    Mizer is compatible with R versions 3.1 and later. You can install R on your computer by following the instructions at https://cran.r-project.org/ for your particular platform.

    +

    Alternatively, if you can not or do not want to install R on your computer, you can also work with R and RStudio in your internet browser by creating yourself a free account at https://rstudio.cloud. There you can then install mizer as described above. Running mizer in the RStudio Cloud may be slightly slower than running it locally on your machine, but the speed is usually quite acceptable.

    +

    This guide assumes that you will be using RStudio to work with R. There is really no reason not to use RStudio and it makes a lot of things much easier. RStudio develops rapidly and adds useful features all the time and so it pays to upgrade to the latest version frequently. This guide was written with version 1.3.820.

    +

    The source code for mizer is hosted on GitHub. If you are feeling brave and wish to try out a development version of mizer you can install the package from here using the R package devtools (which was used extensively in putting together mizer). If you have not yet installed devtools, do

    -install.packages("devtools")
    +install.packages("devtools")

    Then you can install the latest version from GitHub using

    -devtools::install_github("sizespectrum/mizer")
    -Using the same devtools::install_github() function you can also install code from forked mizer repositories or from other branches on the official repository. +devtools::install_github("sizespectrum/mizer") +Using the same devtools::install_github() function you can also install code from forked mizer repositories or from other branches on the official repository.

    -Setting the model parameters

    +Setting the model parameters

    With mizer it is possible to implement many different types of size-spectrum models using the same basic tools and methods.

    Setting the model parameters is done by creating an object of class ? MizerParams. This includes model parameters such as the life history parameters of each species, and the fishing gears. It is possible to create a MizerParams object directly using the class constructor, but most likely you will want to use one of the convenient wrapper functions provided in the package: newCommunityParams(), newTraitParams() and newMultispeciesParams().

    These wrapper functions make reasonable default choices for many of the model parameters that you do not want to specify explicitly. For example to set up a simple model (described more in the Community Model section) you can even let mizer choose all the parameters for you.

    @@ -197,7 +215,7 @@

    -Running a simulation

    +Running a simulation

    This is done by calling the project() function (as in “project forward in time”) with the model parameters.

     sim <- project(params, t_max = 10, effort = 0)
    @@ -205,10 +223,10 @@

    -Exploring the results

    -

    After a simulation has been run, the results can be examined using a range of ?plotting_functions, ?summary_functions and ?indicator_functions. The plot() function combines several of these plots into one:

    +Exploring the results +

    After a simulation has been run, the results can be examined using a range of ?plotting_functions, ?summary_functions and ?indicator_functions. The plot() function combines several of these plots into one:

    -plot(sim)
    +plot(sim)

    Just as an example: we might be interested in how the proportion of large fish varies over time. We can get the proportion of Herrings in terms of biomass that have a weight above 50g in each of the 10 years:

    @@ -225,7 +243,7 @@ 

    -Size-spectrum models

    +Size-spectrum models

    Size spectrum models have emerged as a conceptually simple way to model a large community of individuals which grow and change trophic level during life. There is now a growing literature describing different types of size spectrum models (e.g. Benoît and Rochet 2004; K. H. Andersen and Beyer 2006; K. H. Andersen et al. 2008; Law et al. 2009; Hartvig 2011; Hartvig, Andersen, and Beyer 2011). The models can be used to understand how marine communities are organised (K. H. Andersen and Beyer 2006; K. H. Andersen, Beyer, and Lundberg 2009; Blanchard et al. 2009) and how they respond to fishing (K. H. Andersen and Rice 2010; K. H. Andersen and Pedersen 2010). This section introduces the central assumptions, concepts, processes, equations and parameters of size spectrum models.

    Roughly speaking there are three versions of the size spectrum modelling framework of increasing complexity: The community model (Benoît and Rochet 2004; Maury et al. 2007; Blanchard et al. 2009; Law et al. 2009), the trait-based model (K. H. Andersen and Beyer 2006; K. H. Andersen and Pedersen 2010), and the multispecies model (Hartvig, Andersen, and Beyer 2011). The community and trait-based models can be considered as simplifications of the multispecies model. This section focuses on the multispecies model but is also applicable to the community and trait-based models. Mizer is able to implement all three types of model using similar commands.

    Size spectrum models are a subset of physiologically structured models (Metz and Diekmann 1986; De Roos and Persson 2001) as growth (and thus maturation) is food dependent, and processes are formulated in terms of individual level processes. All parameters in the size spectrum models are related to individual weight which makes it possible to formulate the model with a small set of general parameters, which has prompted the label ``charmingly simple’’ to the model framework [Pope et al. (2006)}.

    @@ -240,22 +258,22 @@

    It is easiest to learn the basics of mizer through examples. We do this by looking at three set-ups of the framework, of increasing complexity. For each one there is a section that describes how to set up the model, run it in different scenarios, and explore the results. We recommend that you explore these in the following order:

    -Community model

    +Community model

    In the community model, individuals are only characterized by their size and are represented by a single group representing an across-species average. Community size spectrum models have been used to investigate how abundance size spectra emerge solely from the individual-level process of size-based predation and how fishing impacts metrics of community-level size spectra. Since few parameters are required it has been used for investigating large-scale community-level questions where detailed trait- and species-level parameterisations are not tractable.

    -Trait-based model

    +Trait-based model

    The trait-based model resolves a continuum of species with varying asymptotic sizes. The asymptotic size is considered to be the most important trait that characterizes a species’ life history. The continuum is represented by a discrete number of species spread evenly over the range of asymptotic sizes. The number of species is not important and does not affect the general dynamics of the model. Many of the parameters, such as the preferred predator-prey mass ratio, are the same for all species. Other model parameters are determined by the asymptotic size. For example, the weight at maturation of each species is a set fraction of the asymptotic size. In the trait-based model, species-level complexity is captured through different life histories, and both intra- and inter-specific size spectra emerge. This approach is powerful for examining the generic population and whole community level responses to both size and species selective fishing without the requirement for detailed species-specific parameters.

    -Multispecies model

    +Multispecies model

    In the multispecies model individual species are resolved in detail and each has distinct life history, feeding and reproduction parameters. More detailed information is required to parameterise the multispecies model but the approach can be used to address management strategies for a realistic community in a specific region or subset of interacting species.

    -Which model to use

    +Which model to use

    All three models predict abundance, biomass and yield as well as predation and mortality rates at size. They are useful for establishing baselines of abundance of unexploited communities, for understanding how fishing impacts aquatic communities and for testing indicators that are being developed to support an ecosystem approach to fisheries management.

    Which model to use in a specific case depends on needs and on the amount of information available to calibrate the model. The multi-species model could be set up for most systems where calibration parameters can be estimated. This requires a lot of insight and data. If the parameters are just guesstimates the results of the multi-species model will be no more accurate than the results from the trait-based model. In such situations we therefore recommend the use of the trait-based model, even though it only provides general information about the asymptotic size distribution and not about specific species.

    The community model is useful for large-scale community-level questions where only the average spectrum is needed. Care should be taken when the community model is used to infer the dynamical properties of marine ecosystems, since it is prone to unrealistically strong oscillations due to the lack of dampening effects provided by the life-history diversity in the trait-based and multi-species models.

    @@ -268,49 +286,49 @@

    -References

    +References
    -Andersen, K. H., and J. E. Beyer. 2006. “Asymptotic Size Determines Species Abundance in the Marine Size Spectrum.” The American Naturalist 168 (1): 54–61. https://doi.org/10.1086/504849. +Andersen, K. H., and J. E. Beyer. 2006. “Asymptotic Size Determines Species Abundance in the Marine Size Spectrum.” The American Naturalist 168 (1): 54–61. https://doi.org/10.1086/504849.
    -Andersen, K. H., J. E. Beyer, and P. Lundberg. 2009. “Trophic and Individual Efficiencies of Size-Structured Communities.” Proceedings of the Royal Society B: Biological Sciences 276 (1654): 109–14. https://doi.org/10.1098/rspb.2008.0951. +Andersen, K. H., J. E. Beyer, and P. Lundberg. 2009. “Trophic and Individual Efficiencies of Size-Structured Communities.” Proceedings of the Royal Society B: Biological Sciences 276 (1654): 109–14. https://doi.org/10.1098/rspb.2008.0951.
    -Andersen, K.H., J.E. Beyer, M. Pedersen, N.G. Andersen, and H. Gislason. 2008. “Life-History Constraints on the Success of the Many Small Eggs Reproductive Strategy.” Theoretical Population Biology 73 (4): 490–97. https://doi.org/10.1016/j.tpb.2008.02.001. +Andersen, K.H., J.E. Beyer, M. Pedersen, N.G. Andersen, and H. Gislason. 2008. “Life-History Constraints on the Success of the Many Small Eggs Reproductive Strategy.” Theoretical Population Biology 73 (4): 490–97. https://doi.org/10.1016/j.tpb.2008.02.001.
    -Andersen, K. H., and M. Pedersen. 2010. “Damped Trophic Cascades Driven by Fishing in Model Marine Ecosystems.” Proceedings of the Royal Society B-Biological Sciences 277 (1682): 795–802. https://doi.org/10.1098/rspb.2009.1512. +Andersen, K. H., and M. Pedersen. 2010. “Damped Trophic Cascades Driven by Fishing in Model Marine Ecosystems.” Proceedings of the Royal Society B-Biological Sciences 277 (1682): 795–802. https://doi.org/10.1098/rspb.2009.1512.
    -Andersen, K. H., and Jake C. Rice. 2010. “Direct and Indirect Community Effects of Rebuilding Plans.” ICES Journal of Marine Science: Journal Du Conseil 67 (9): 1980–88. https://doi.org/10.1093/icesjms/fsq035. +Andersen, K. H., and Jake C. Rice. 2010. “Direct and Indirect Community Effects of Rebuilding Plans.” ICES Journal of Marine Science: Journal Du Conseil 67 (9): 1980–88. https://doi.org/10.1093/icesjms/fsq035.
    -Benoît, Eric, and Marie-Joëlle Rochet. 2004. “A Continuous Model of Biomass Size Spectra Governed by Predation and the Effects of Fishing on Them.” Journal of Theoretical Biology 226 (1): 9–21. https://doi.org/10.1016/S0022-5193(03)00290-X. +Benoît, Eric, and Marie-Joëlle Rochet. 2004. “A Continuous Model of Biomass Size Spectra Governed by Predation and the Effects of Fishing on Them.” Journal of Theoretical Biology 226 (1): 9–21. https://doi.org/10.1016/S0022-5193(03)00290-X.
    -Blanchard, Julia L., Simon Jennings, Richard Law, Matthew D. Castle, Paul McCloghrie, Marie-Joëlle Rochet, and Eric Benoît. 2009. “How Does Abundance Scale with Body Size in Coupled Size-Structured Food Webs?” Journal of Animal Ecology 78 (1): 270–80. https://doi.org/10.1111/j.1365-2656.2008.01466.x. +Blanchard, Julia L., Simon Jennings, Richard Law, Matthew D. Castle, Paul McCloghrie, Marie-Joëlle Rochet, and Eric Benoît. 2009. “How Does Abundance Scale with Body Size in Coupled Size-Structured Food Webs?” Journal of Animal Ecology 78 (1): 270–80. https://doi.org/10.1111/j.1365-2656.2008.01466.x.
    -De Roos, André M., and Lennart Persson. 2001. “Physiologically Structured Models – from Versatile Technique to Ecological Theory.” Oikos 94 (1): 51–71. https://doi.org/10.1034/j.1600-0706.2001.11313.x. +De Roos, André M., and Lennart Persson. 2001. “Physiologically Structured Models – from Versatile Technique to Ecological Theory.” Oikos 94 (1): 51–71. https://doi.org/10.1034/j.1600-0706.2001.11313.x.
    Hartvig, Martin. 2011. “Food Web Ecology.” {Ph.D.}, Lund University.
    -Hartvig, Martin, K. H. Andersen, and Jan E. Beyer. 2011. “Food Web Framework for Size-Structured Populations RID c-4303-2011.” Journal of Theoretical Biology 272 (1): 113–22. https://doi.org/10.1016/j.jtbi.2010.12.006. +Hartvig, Martin, K. H. Andersen, and Jan E. Beyer. 2011. “Food Web Framework for Size-Structured Populations RID c-4303-2011.” Journal of Theoretical Biology 272 (1): 113–22. https://doi.org/10.1016/j.jtbi.2010.12.006.
    -Law, Richard, Michael J. Plank, Alex James, and Julia L. Blanchard. 2009. “Size-Spectra Dynamics from Stochastic Predation and Growth of Individuals.” Ecology 90 (3): 802–11. https://doi.org/10.1890/07-1900.1. +Law, Richard, Michael J. Plank, Alex James, and Julia L. Blanchard. 2009. “Size-Spectra Dynamics from Stochastic Predation and Growth of Individuals.” Ecology 90 (3): 802–11. https://doi.org/10.1890/07-1900.1.
    -Maury, Olivier, Blaise Faugeras, Yunne-Jai Shin, Jean-Christophe Poggiale, Tamara Ben Ari, and Francis Marsac. 2007. “Modeling Environmental Effects on the Size-Structured Energy Flow Through Marine Ecosystems. Part 1: The Model.” Progress in Oceanography 74 (4): 479–99. https://doi.org/10.1016/j.pocean.2007.05.002. +Maury, Olivier, Blaise Faugeras, Yunne-Jai Shin, Jean-Christophe Poggiale, Tamara Ben Ari, and Francis Marsac. 2007. “Modeling Environmental Effects on the Size-Structured Energy Flow Through Marine Ecosystems. Part 1: The Model.” Progress in Oceanography 74 (4): 479–99. https://doi.org/10.1016/j.pocean.2007.05.002.
    Metz, Johan A. J., and O. Diekmann. 1986. The Dynamics of Physiologically Structured Populations. Springer-Verlag.
    -Pope, John G., Jake C. Rice, Niels Daan, Simon Jennings, and Henrik Gislason. 2006. “Modelling an Exploited Marine Fish Community with 15 Parameters - Results from a Simple Size-Based Model.” Ices Journal of Marine Science 63 (6): 1029–44. https://doi.org/10.1016/j.icesjms.2006.04.015. +Pope, John G., Jake C. Rice, Niels Daan, Simon Jennings, and Henrik Gislason. 2006. “Modelling an Exploited Marine Fish Community with 15 Parameters - Results from a Simple Size-Based Model.” Ices Journal of Marine Science 63 (6): 1029–44. https://doi.org/10.1016/j.icesjms.2006.04.015.
    @@ -327,13 +345,11 @@

    diff --git a/docs/articles/mizer_files/figure-html/unnamed-chunk-8-1.png b/docs/articles/mizer_files/figure-html/unnamed-chunk-8-1.png index 0625d3879..774568b15 100644 Binary files a/docs/articles/mizer_files/figure-html/unnamed-chunk-8-1.png and b/docs/articles/mizer_files/figure-html/unnamed-chunk-8-1.png differ diff --git a/docs/articles/model_description.html b/docs/articles/model_description.html index 0e422f52e..89a565e81 100644 --- a/docs/articles/model_description.html +++ b/docs/articles/model_description.html @@ -6,6 +6,12 @@ The General Mizer Size-spectrum Model • mizer + + + + + + @@ -15,14 +21,13 @@ + - -
    @@ -146,26 +164,27 @@

    The General Mizer Size-spectrum Model

    And clicking again will hide the details again.

    -Size spectrum dynamics

    +Size spectrum dynamics

    -Consumer densities

    +Consumer densities

    The model assumes that, to a first approximation, an individual can be characterized by its weight \(w\) and its species number \(i\) only. The aim of the model is to calculate the size spectrum \(N_i(w)\), which is the density of individuals of species \(i\) such that \(\int_w^{w+dw}N_i(w)dw\) is the number of individuals of species \(i\) in the size interval \([w,w+dw]\). In other words: the number of individuals in a size range is the area under the number density \(N_i(w)\).

    Here is a plot of an example size spectrum for two species with \(N_i(w)\) on the vertical axis for \(i=1,2\) and \(w\) on the horizontal axis.

    -library(mizer)
    +library(mizer)
     params <- newTraitParams(no_sp = 2, min_w = 1e-3)
     plotSpectra(params, resource = FALSE, power = 0)

    To represent this continuous size spectrum in the computer, the size variable \(w\) is discretized into a vector w of discrete weights, providing a grid of sizes spanning the range from the smallest egg size to the largest asymptotic size. These grid values divide the full size range into a finite number of size bins. The size bins should be chosen small enough to avoid the discretisation errors from becoming too big. You can fetch this vector with w() and the vector of bin sizes with dw().

    -

    The weight grid is set up to be logarithmically spaced, so that w[j]=w[1]*exp(j*dx) for some fixed dx. This grid is set up automatically when creating a MizerParams object.

    +

    The weight grid is set up to be logarithmically spaced, so that w[j]=w[1]*10^(j*dx) for some fixed dx. This means that the bin widths increase with size: dw[j] = w[j+1] - w[j] = w[j] * (10^dx - 1). This grid is set up automatically when creating a MizerParams object.

    In the code the size spectrum is stored as an array N such that N[i, a] holds the density \(N_i(w_a)\) at weights \(w_a=\)w[a], or, if time dependence is included, an array such that N[i, a, u] holds \(N_i(w_a,t_u)\). See N().

    Note that, contrary to what one might have expected, N[i, a] is not the number of individuals in a size bin but the density at a grid point. The number of individuals in the size bin between w[a] and w[a+1]=w[a]+dw[a] is only approximately given as N[i, a]*dw[a], where dw[a]= w[a+1]-w[a].

    +

    Of course all these calculations with discrete sizes and size bins are only giving approximations to the continuous values, and these approximations get better the smaller the size bins are, i.e., the more size bins are used. This is why the functions setting up MizerParams objects allow you to choose the number of size bins no_w.

    -Traffic on the road to adulthood

    +Traffic on the road to adulthood

    A good way to think about the time evolution of the number density \(N_i(w)\) is to consider the familiar situation of traffic density on the roads. A fish’s life is a journey along the size axis from egg size to size at death. There are many other fish making the same journey. The speed with which the fish move along the size axis is their growth rate. This is quite analogous to the speed of traffic on a road. Just as the speed of cars depends on the density of other cars on the road, the growth rate of fish depends on the density of other fish. When the density of cars on a stretch of road is high, their speed decreases, and this leads to a pile-up and can lead to traffic jams. Similarly when the density of fish in a size interval is high, their growth rate goes down due to competition for the same food sources, and this too can lead to pile-ups and bottlenecks. So one just has to replace the space variable in a traffic model by size to get an equation for the fish size spectra.

    The additional feature in the evolution of fish densities that is not present in road traffic density is that fish can die while they are growing up, and this death rate is also dependent on the density of other fish.

    The time evolution of the number density \(N_i(w)\) is described by the McKendrick-von Foerster equation, which is a transport equation (as one would use for traffic density) but with an additional loss term due to fish mortality:

    @@ -180,25 +199,25 @@

    -Resource density

    +Resource density

    Besides the fish spectrum there is also a resource spectrum \(N_R(w)\), representing for example the phytoplankton. This spectrum starts at a smaller size than the fish spectrum, in order to provide food also for the smallest individuals (larvae) of the fish spectrum. By default the time evolution of the resource spectrum is described by a semi-chemostat equation.

    The semichemostat dynamics are given by \[\begin{equation} \label{eq:nb} \frac{\partial N_R(w,t)}{\partial t} = r_R(w) \Big[ c_R (w) - N_R(w,t) \Big] - \mu_R(w) N_R(w,t). \end{equation}\] Here \(r_R(w)\) is the resource regeneration rate and \(c_R(w)\) is the carrying capacity in the absence of predation. These parameters are changed with setResource(). By default mizer assumes allometric forms \[r_R(w)= r_R\, w^{n-1}.\] \[c_R(w)=\kappa\, w^{-\lambda}.\] You can retrieve these with getResourceRate() and getResourceCapacity() respectively. It is also possible to implement other resource dynamics, as described in the help page for setResource(). The mortality \(\mu_R(w)\) is due to predation by consumers and is described in the subsection Resource mortality.

    -

    Because the resource spectrum spans a different range of sizes these sizes are discretized into a different vector of weights w_full. The last entries of w_full have to coincide with the entries of w. The function w_full() gives the vector of sizes and dw_full() gives the vector of bin sizes.

    +

    Because the resource spectrum spans a larger range of sizes these sizes Because the resource spectrum spans a larger range of sizes these sizes Because the resource spectrum spans a larger range of sizes these sizes are discretized into a different vector of weights

    The resource spectrum is then represented by a vector NResource such that NResource[c] =\(N_R(\)w_full[c]\()\).

    -Growth

    +Growth

    Consumers can grow only by consuming prey. In the next few subsections we will build towards determining the growth rate resulting from predation. We will discuss how we model the predator-prey encounter rate, the resulting rate of consumption, the rate of loss due to metabolism, and the partitioning of the remaining energy into reproduction and growth.

    -Predator-prey encounter rate

    +Predator-prey encounter rate

    The rate at which a predator of species \(i\) and weight \(w\) encounters food (mass per time) is determined by summing over all prey species and the resource spectrum and integrating over all prey sizes \(w_p\), weighted by the selectivity factors: \[\begin{equation} \label{eq:1} E_{i}(w) = \gamma_i(w) \int \left(\sum_{j} \theta_{ij} N_j(w_p) + @@ -224,7 +243,7 @@

    -Consumption

    +Consumption

    The encountered food is consumed subjected to a standard Holling functional response type II to represent satiation. This determines the feeding level \(f_i(w)\), which is a dimensionless number between 0 (no food) and 1 (fully satiated) so that \(1-f_i(w)\) is the proportion of the encountered food that is consumed. The feeding level is given by

    \[\begin{equation} \label{eq:f} @@ -237,7 +256,7 @@

    -Metabolic losses

    +Metabolic losses

    Some of the consumed food is used to fuel the needs for metabolism and activity and movement, at a rate \({\tt metab}_i(w)\). By default this is made up out of standard metabolism, scaling with exponent \(p\), and loss due to activity and movement, scaling with exponent \(1\): \[{\tt metab}_i(w) = k_{s.i}\,w^p + k_i\,w.\] See the help page for setMetabolicRate().

    The remaining rate, if any, is assimilated with an efficiency \(\alpha_i\) and is then available for growth and reproduction. So the rate at which energy becomes available for growth and reproduction is \[\begin{equation} \label{eq:Er} @@ -246,12 +265,12 @@

    -Investment into reproduction

    +Investment into reproduction

    A proportion \(\psi_i(w)\) of the energy available for growth and reproduction is used for reproduction. This proportion should change from zero below the weight \(w_{m.i}\) of maturation to one at the asymptotic weight \(w_{\infty.i}\), where all available energy is used for reproduction. This function is changed with setReproduction(). Mizer provides a default form for the function which you can however overrule.

    -Growth

    +Growth

    What is left over after metabolism and reproduction is taken into account is invested in somatic growth. Thus the growth rate is \[\begin{equation} \label{eq:growth} g_i(w) = E_{r.i}(w)\left(1-\psi_i(w)\right). @@ -261,7 +280,7 @@

    -Mortality

    +Mortality

    The mortality rate of an individual \(\mu_i(w)\) has three sources: predation mortality \(\mu_{p.i}(w)\), background mortality \(\mu_{b.i}(w)\) and fishing mortality \(\mu_{f.i}(w)\).

    Predation mortality is calculated such that all that is eaten translates into corresponding predation mortalities on the ingested prey individuals. Recalling that \(1-f_j(w)\) is the proportion of the food encountered by a predator of species \(j\) and weight \(w\) that is actually consumed, the rate at which all predators of species \(j\) consume prey of size \(w_p\) is \[\begin{equation} \label{eq:pred_rated} @@ -280,17 +299,17 @@

    External mortality \(z0_i(w)\) is independent of the abundances and is changed with setExtMort(). By default mizer assumes an allometric form \[z0_i(w) = z0_{pre} w_{\infty.i}^{1-n},\] where \(w_{\infty.i}\) is the asymptotic size of species \(i\).

    -Fishing mortality

    +Fishing mortality

    The fishing parameters for the model are set up with setFishing(), where you can find the details of how to set up gears with different selectivities and the capabilities of different species. Fishing mortality \(\mu_{f.i}(w)\) is calculated with the function getFMort().

    -Total mortality

    +Total mortality

    The total mortality rate \[\mu_i(w)=\mu_{p.i}(w)+z0_i(w)+\mu_{f.i}(w)\] is calculated with the function getMort().

    -Resource Mortality

    +Resource Mortality

    The predation mortality rate on resource is given by a similar expression as the predation mortality on fish: \[\begin{equation} \label{eq:mupp} \mu_{p}(w_p) = \sum_j {\tt pred\_rate}_j(w_p)\, \theta_{jp}. @@ -299,10 +318,10 @@

    -Reproduction

    +Reproduction

    -Energy invested into reproduction

    +Energy invested into reproduction

    The total rate of investment into reproduction (grams/year) is found by integrating the contribution from all individuals of species \(i\), each of which invests a proportion \(\psi_i(w)\) of their consumption. This total rate of energy investment can then be converted to a total rate of egg production \(R_{p.i}\) (numbers per year): \[\begin{equation} \label{eq:Rp} R_{p.i} = \frac{\epsilon}{2 w_0} \int N_i(w) E_{r.i}(w) \psi_i(w) \, dw, @@ -310,7 +329,7 @@

    -Density-dependence in reproduction

    +Density-dependence in reproduction

    Three important density-dependent mechanisms widely assumed in fisheries models are automatically captured in the mizer model that lead to an emergent stock-recruitment relationship:

    1. High density of spawners leads to a reduced food income of the spawners and consequently reduced per-capita reproduction.
    2. @@ -339,13 +358,11 @@

      diff --git a/docs/articles/model_description_files/figure-html/unnamed-chunk-1-1.png b/docs/articles/model_description_files/figure-html/unnamed-chunk-1-1.png index f4cf0a547..83d767936 100644 Binary files a/docs/articles/model_description_files/figure-html/unnamed-chunk-1-1.png and b/docs/articles/model_description_files/figure-html/unnamed-chunk-1-1.png differ diff --git a/docs/articles/multispecies_model.html b/docs/articles/multispecies_model.html index 996c703fa..fc36e6493 100644 --- a/docs/articles/multispecies_model.html +++ b/docs/articles/multispecies_model.html @@ -6,6 +6,12 @@ The Multi Species Model • mizer + + + + + + @@ -15,14 +21,13 @@ + - -
      @@ -147,10 +165,10 @@

      The Multi Species Model

      We also take a closer look at some of the summary plots and analyses that can be performed, for example, calculating a range of size-based indicators.

      -Setting up a multispecies model

      +Setting up a multispecies model

      -Overview

      +Overview

      The MizerParams class is used for storing model parameters. We have already met the MizerParams class when we looked at community and trait-based models. However, to set up a multispecies model we will need to specify many more parameters.This is probably the most complicated part of using the mizer package, so we will take it slowly.

      A MizerParams object stores the:

        @@ -167,14 +185,14 @@

      -The species parameters

      +The species parameters

      Although many of the arguments used when creating a MizerParams object are optional, there is one argument that must be supplied by the user: the species specific parameters. These are stored in a single data.frame object. The data.frame is arranged species by parameter, so each column is a parameter and each row has the parameters for one of the species in the model. Although it is possible to create the data.frame by hand in R, it is probably easier to create the data externally as a .csv file (perhaps using a suitable open source spreadsheet such as LibreOffice) and then read the data into R.

      For each species in the model community there are certain parameters that are essential and that do not have default values. The user must provide values for these parameters. There are also some essential parameters that have default values, such as the selectivity function parameters, and some that are calculated internally using default relationships if not explicitly provided. These defaults are used if the parameters are not found in the data.frame.

      The essential columns of the species parameters data.frame that have no default values are: species, the names of the species in the community and w_inf, the asymptotic mass of the species.

      -The gear parameters

      +The gear parameters

      In mizer, fishing mortality is imposed on species by fishing gears. The total fishing mortality is obtained by summing over the mortality from all gears, \[\begin{equation} % {#eq:muf} \mu_{f.i}(w) = \sum_g F_{g,i}(w), @@ -187,17 +205,17 @@

      -Example of making MizerParams objects

      +Example of making MizerParams objects

      As mentioned in the preceding sections, an object of MizerParams is created by using the newMultispeciesParams() constructor method.

      The first step is to prepare the species specific parameter data.frame. As mentioned above, one way of doing this is to use a spreadsheet and save it as a .csv file. We will use this approach here. An example .csv file has been included in the package. This contains the species parameters for a multispecies North Sea model. The location of the file can be found by running

      -params_location <- system.file("doc/NS_species_params.csv", package = "mizer")
      +params_location <- system.file("doc/NS_species_params.csv", package = "mizer")

      This file can be opened with most spreadsheets or a text editor for you to inspect. This can be loaded into R with

      -species_params <- read.csv(params_location)
      +species_params <- read.csv(params_location)

    This reads the .csv file into R in the form of a data.frame. You can check this with the class:

    -class(species_params)
    +class(species_params)
    ## [1] "data.frame"

    Let’s have a look at the data frame:

    @@ -229,7 +247,7 @@ 

    ## Note: Using f0, h, lambda, kappa and the predation kernel to calculate gamma.

    We have just created a MizerParams object:

    -class(params)
    +class(params)

    ## [1] "MizerParams"
     ## attr(,"package")
     ## [1] "mizer"
    @@ -293,9 +311,9 @@

    ## 11 Cod knife_edge_gear knife_edge 1606 1 ## 12 Saithe knife_edge_gear knife_edge 1076 1

    All species are caught by a gear called “knife_edge_gear”. The selectivity function for each fishing gear has been set in the sel_func column to the default function, knife_edge(). A catchability column has been added with a default value of 1 for each of the species that the gear catches. An example of setting the catchability by hand can be seen in the section on the North Sea.

    -

    There is a summary() method for MizerParams objects which prints a useful summary of the model parameters:

    +

    There is a summary() method for MizerParams objects which prints a useful summary of the model parameters:

    -summary(params)
    +summary(params)

    ## An object of class "MizerParams" 
     ## Consumer size spectrum:
     ##  minimum size:   0.001
    @@ -319,17 +337,19 @@ 

    ## 10 Haddock 4316.5 165 0.001 0.271 558 2.1 ## 11 Cod 39851.3 1606 0.001 0.216 66 1.3 ## 12 Saithe 39658.6 1076 0.001 0.175 40 1.1 +## ## Fishing gear details: -## Gear Target species -## knife_edge_gear Sprat Sandeel N.pout Herring Dab Whiting Sole Gurnard Plaice Haddock Cod Saithe

    +## Gear Effort Target species +## ---------------------------------- +## knife_edge_gear 0.00 Sprat, Sandeel, N.pout, Herring, Dab, Whiting, Sole, Gurnard, Plaice, Haddock, Cod, Saithe

    As well as giving a summary of the species in the model and what gear is fishing what species, it gives a summary of the size structure of the community. For example there are \(100\) size classes in the community, ranging from \(0.001\) to \(3.99\times 10^{4}\) . These values are controlled by the arguments no_w, min_w and max_w respectively. For example, if we wanted 200 size classes in the model we would use:

     params200 <- newMultispeciesParams(species_params, no_w = 200)
    -summary(params200)
    +summary(params200)

    -Setting the interaction matrix

    +Setting the interaction matrix

    So far we have created a MizerParams object by passing in only the species parameter data.frame argument. We did not specify an interaction matrix. The interaction matrix describes the interaction of each pair of species in the model. This can be viewed as a proxy for spatial interaction e.g. to model predator-prey interaction that is not size based. The values in the interaction matrix are used to scale the encountered food in [getEncounter()] and the predation mortality rate in [getPredMort()] (see the section on predator-prey encounter rate and on predation mortality).

    The entries of the interaction matrix are dimensionless numbers taking values are between 0 (species do not overlap and therefore do not interact with each other) to 1 (species overlap perfectly). By default mizer sets all values to 1, implying that all species fully interact with each other, i.e. the species are spread homogeneously across the model area.

    @@ -365,10 +385,10 @@ 

    For the North Sea this is not the case and so the model would be improved by also including an interaction matrix which describes the spatial overlap between species.

    An example interaction matrix for the North Sea has been included in mizer as a .csv file. The location of the file can be found by running:

    -inter_location <- system.file("doc/inter.csv", package = "mizer")
    -

    Take a look at it in a spreadsheet if you want. As mentioned above, to read this file into R we can make use of the read.csv() function. However, this time we want the first column of the .csv file to be the row names. We therefore use an additional argument to the read.csv() function: row.names.

    +inter_location <- system.file("doc/inter.csv", package = "mizer")

    +

    Take a look at it in a spreadsheet if you want. As mentioned above, to read this file into R we can make use of the read.csv() function. However, this time we want the first column of the .csv file to be the row names. We therefore use an additional argument to the read.csv() function: row.names.

    -inter <- read.csv(inter_location, row.names = 1)
    +inter <- read.csv(inter_location, row.names = 1)
     inter
    ##              Sprat    Sandeel     N.pout    Herring        Dab    Whiting
     ## Sprat   0.72912919 0.03408440 0.06354517 0.27416982 0.36241552 0.26525924
    @@ -410,13 +430,13 @@ 

    Note that the first argument must be the species parameters data.frame. The remaining arguments can be in any order but should be named. We are using the default values for all other parameters.

    Both methods lead to identical MizerParams objects

    -identical(params, params_new)
    +identical(params, params_new)

    ## [1] TRUE

    We now have all we need to start running projections. Before we get to that though, we’ll take a quick look at how different fishing gears can be set up.

    -Setting different gears

    +Setting different gears

    In the above example, each species is caught by the same gear (named “knife_edge_gear”). This is the default when no gear information is provided.

     gear_params(params)
    @@ -435,13 +455,13 @@

    ## 12 Saithe knife_edge_gear knife_edge 1076 1

    Here, we look at an example where we set up four different gears: Industrial, Pelagic, Beam and Otter trawl, that catch different combinations of species. We can achieve that by only changing the gear column in the gear_params data frame.

    -gear_params(params)$gear <- c("Industrial","Industrial","Industrial",
    +gear_params(params)$gear <- c("Industrial","Industrial","Industrial",
                                   "Pelagic","Beam","Otter",
                                   "Beam","Otter","Beam",
                                   "Otter","Otter","Otter")
    -

    You can see the result by calling summary() on the params object.

    +

    You can see the result by calling summary() on the params object.

    -summary(params)
    +summary(params)

    ## An object of class "MizerParams" 
     ## Consumer size spectrum:
     ##  minimum size:   0.001
    @@ -465,17 +485,19 @@ 

    ## 10 Haddock 4316.5 165 0.001 0.271 558 2.1 ## 11 Cod 39851.3 1606 0.001 0.216 66 1.3 ## 12 Saithe 39658.6 1076 0.001 0.175 40 1.1 +## ## Fishing gear details: -## Gear Target species -## Industrial Sprat Sandeel N.pout -## Pelagic Herring -## Beam Dab Sole Plaice -## Otter Whiting Gurnard Haddock Cod Saithe

    +## Gear Effort Target species +## ---------------------------------- +## Industrial 0.00 Sprat, Sandeel, N.pout +## Pelagic 0.00 Herring +## Beam 0.00 Dab, Sole, Plaice +## Otter 0.00 Whiting, Gurnard, Haddock, Cod, Saithe

    In this example the same gear now catches multiple stocks. For example, the Industrial gear catches Sprat, Sandeel and Norway Pout. Why would we want to set up the gears like this? In the next section on running a multispecies model we will see that to project the model through time you can specify the fishing effort for each gear through time. By setting the gears up in this way you can run different management scenarios of changing the efforts of the fishing gears rather than on individual species. It also means that after a simulation has been run you can examine the catches by gear.

    -Setting to steady state

    +Setting to steady state

    Once the MizerParams object has been properly set up, it may be the case that one wishes put the system in steady state. Sometimes this can be done simply by running the model using project() until it reaches steady state. However, this method is not guaranteed to work, and there is a function called steady() that is more reliable. The function steady() must be supplied with a MizerParams object. It takes that MizerParams object, looks at the initial system state, computes the levels of reproduction of the different species, hold them fixed, and evolves the system until a steady state is reached (or more precisely, until the amount that the population abundances change during a time-step is below some small tolerance level). After this, the reproductive efficiency of each species is altered so that when the reproduction dynamics are turned back on (i.e., when we stop holding recruitment levels fixed), the values of the reproduction levels which we held the system fixed at will be realized. The steady function is not sure to converge, and the way it re-tunes the reproductive efficiency values may not be realistic, but the idea is to alter the other parameters in the system until steady() does arrive at a steady state with sensible reproductive efficiency values.

    Now that we know how to create a multispecies model we shall discuss how to run a multispecies model.

    @@ -493,13 +515,11 @@

    diff --git a/docs/articles/plotting.html b/docs/articles/plotting.html index 4d86ebe6e..d9cd278f8 100644 --- a/docs/articles/plotting.html +++ b/docs/articles/plotting.html @@ -6,6 +6,12 @@ Using ggplot2 and plotly with mizer • mizer + + + + + + @@ -15,14 +21,13 @@ + - -
    @@ -144,16 +162,16 @@

    Using ggplot2 and plotly with mizer

    -Introduction

    -

    In this tutorial we will use the ggplot2 package and the
    plotly package for R to visualise the results from mizer simulations.

    +Introduction

    +

    In this tutorial we will use the ggplot2 package and the
    plotly package for R to visualise the results from mizer simulations.

    -

    Mizer provides several functions for calculating summaries of the mizer simulation results, see ?summary_functions. Many of these functions have corresponding plotting functions, see ?plotting_functions. However it is easy to produce customised plots directly using ggplot() or plot_ly(). This gives more flexibility than the built-in plotting functions. Also, you will occasionally want to look at different quantities for which perhaps there is not built-in plotting function. In those cases the examples you see below will provide a useful blueprint.

    -

    Both ggplot2 and plotly works with data frames, and the convenient way to manipulate data frames is the dplyr package.

    +library(mizer) +library(ggplot2) +library(plotly) +

    Mizer provides several functions for calculating summaries of the mizer simulation results, see ?summary_functions. Many of these functions have corresponding plotting functions, see ?plotting_functions. However it is easy to produce customised plots directly using ggplot() or plot_ly(). This gives more flexibility than the built-in plotting functions. Also, you will occasionally want to look at different quantities for which perhaps there is not built-in plotting function. In those cases the examples you see below will provide a useful blueprint.

    +

    Both ggplot2 and plotly works with data frames, and the convenient way to manipulate data frames is the dplyr package.

    +library(dplyr)

    We create a simple simulation that we will use for our examples below.

     params <- newMultispeciesParams(NS_species_params)
    @@ -161,20 +179,20 @@ 

    -From arrays to data frames

    -

    Mizer likes to work with arrays indexed by species and time or size. For example the built-in summary functions return such arrays. These arrays need to be converted to data frames before they can be conveniently plotted with either ggplot() or plot_ly. This conversion is achieved by the function melt().

    +From arrays to data frames +

    Mizer likes to work with arrays indexed by species and time or size. For example the built-in summary functions return such arrays. These arrays need to be converted to data frames before they can be conveniently plotted with either ggplot() or plot_ly. This conversion is achieved by the function melt().

    For example, the function getBiomass() returns a two-dimensional array (matrix) with one dimension corresponding to the time and the second dimension to the species.

     biomass <- getBiomass(sim)
    -str(biomass)
    +str(biomass)
    ##  num [1:21, 1:12] 8.77e+07 2.52e+09 3.21e+09 7.50e+08 2.09e+08 ...
     ##  - attr(*, "dimnames")=List of 2
     ##   ..$ time: chr [1:21] "0" "0.5" "1" "1.5" ...
     ##   ..$ sp  : chr [1:12] "Sprat" "Sandeel" "N.pout" "Herring" ...
    -

    This array can be converted with the melt() function to a data frame that contains one row for each entry in the array.

    +

    This array can be converted with the melt() function to a data frame that contains one row for each entry in the array.

    -biomass_frame <- melt(biomass)
    -str(biomass_frame)
    +biomass_frame <- melt(biomass) +str(biomass_frame)
    ## 'data.frame':    252 obs. of  3 variables:
     ##  $ time : num  0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 ...
     ##  $ sp   : Factor w/ 12 levels "Sprat","Sandeel",..: 1 1 1 1 1 1 1 1 1 1 ...
    @@ -182,116 +200,116 @@ 

    -ggplot2 or plotly

    -

    In this form the information can be handed to plot_ly() and converted to a line plot:

    +ggplot2 or plotly

    +

    In this form the information can be handed to plot_ly() and converted to a line plot:

    -pp <- plot_ly(biomass_frame) %>% 
    -    add_lines(x = ~time, y = ~value, color = ~sp)
    +pp <- plot_ly(biomass_frame) %>% 
    +    add_lines(x = ~time, y = ~value, color = ~sp)
     pp
    -
    -

    We have specified that the time is plotted along the x axis, the value along the y axis and that the different species are represented by the colours of the lines. Note the American spelling “color” required by plotly.

    -

    Alternatively we can do the same thing with ggplot():

    +
    +

    We have specified that the time is plotted along the x axis, the value along the y axis and that the different species are represented by the colours of the lines. Note the American spelling “color” required by plotly.

    +

    Alternatively we can do the same thing with ggplot():

    -pg <- ggplot(biomass_frame) +
    -    geom_line(aes(x = time, y = value, colour = sp))
    +pg <- ggplot(biomass_frame) +
    +    geom_line(aes(x = time, y = value, colour = sp))
     pg

    Notice the different syntax for the ggplot2 and for plotly packages. The underlying ideas are similar: they are both implementations of the grammar of graphics. I recommend learning ggplot2 first, and switching to plotly only when it has clear advantages (in particular for animations, see below).

    -

    The main advantage of plotly, namely the interactivity of the resulting figures, can be obtained also with the ggplot syntax by running the result of ggplot() through the function ggplotly():

    +

    The main advantage of plotly, namely the interactivity of the resulting figures, can be obtained also with the ggplot syntax by running the result of ggplot() through the function ggplotly():

    -
    -

    Below we will always for each plot first give the ggplot code and then the plotly code.

    +ggplotly(pg)
    +
    +

    Below we will always for each plot first give the ggplot code and then the plotly code.

    -Adding labels

    -

    We may want to add labels to the figure and to each of the axes. In ggplot this is done with labs().

    +Adding labels +

    We may want to add labels to the figure and to each of the axes. In ggplot this is done with labs().

    -pg + labs(title = "Biomass plot",
    +pg + labs(title = "Biomass plot",
               x = "Time [years]",
               y = "Biomass [g]")

    -

    In plotly we use the layout() function.

    +

    In plotly we use the layout() function.

    -pp %>% layout(
    +pp %>% layout(
         title = "Biomass plot",
    -    xaxis = list(
    +    xaxis = list(
             title = "Time [years]"
         ),
    -    yaxis = list(
    +    yaxis = list(
             title = "Biomass [g]"
         )
     )
    -
    - +
    +

    -Filtering out data

    +Filtering out data

    We can use the filter function to filter out some of the data. For example we could select only the data for specific species:

    -two_species_biomass <- filter(biomass_frame, sp %in% c("Gurnard", "Herring"))
    +two_species_biomass <- filter(biomass_frame, sp %in% c("Gurnard", "Herring"))

    Now if we plot this reduced data frame we get

    -ggplot(two_species_biomass) +
    -    geom_line(aes(x = time, y = value, color = sp))
    +ggplot(two_species_biomass) + + geom_line(aes(x = time, y = value, color = sp))

    -

    In the above we first converted the array to a data frame with melt() and then selected the data of interest with filter(). We could alternatively have first selected only the desired entries in the array and then created the data frame with melt() from the resulting smaller array:

    +

    In the above we first converted the array to a data frame with melt() and then selected the data of interest with filter(). We could alternatively have first selected only the desired entries in the array and then created the data frame with melt() from the resulting smaller array:

    -nfr <- melt(getBiomass(sim)[, c("Gurnard", "Herring")])
    -ggplot(nfr) +
    -    geom_line(aes(x = time, y = value, color = sp))
    +nfr <- melt(getBiomass(sim)[, c("Gurnard", "Herring")]) +ggplot(nfr) + + geom_line(aes(x = time, y = value, color = sp))

    The result looks almost identical, except that the colours associated to the species have changed.

    -Specifying line colours

    +Specifying line colours

    If we want to make sure the same species always has the same colour, we can use the colours specified by the MizerParams object

     getColours(params)
    ##      Sprat    Sandeel     N.pout    Herring        Dab    Whiting       Sole 
     ##  "#815f00"  "#6237e2"  "#8da600"  "#de53ff"  "#0e4300"  "#430079"  "#6caa72" 
    -##    Gurnard     Plaice    Haddock        Cod     Saithe      Total   Resource 
    -##  "#ee0053"  "#007957"  "#b42979"  "#142300"  "#a08dfb"    "black"    "green" 
    +##    Gurnard     Plaice    Haddock        Cod     Saithe   Resource      Total 
    +##  "#ee0053"  "#007957"  "#b42979"  "#142300"  "#a08dfb"    "green"    "black" 
     ## Background    Fishing 
     ##     "grey"      "red"
    -

    To use these colours in ggplot we add scale_colour_manual():

    +

    To use these colours in ggplot we add scale_colour_manual():

    -ggplot(biomass_frame) +
    -    geom_line(aes(x = time, y = value, color = sp)) + 
    -    scale_colour_manual(values = getColours(params))
    +ggplot(biomass_frame) + + geom_line(aes(x = time, y = value, color = sp)) + + scale_colour_manual(values = getColours(params))

    -

    In plotly we add colors = getColours(params)r to the add_lines() command:

    +

    In plotly we add colors = getColours(params)r to the add_lines() command:

    -plot_ly(biomass_frame) %>% 
    -    add_lines(x = ~time, y = ~value, color = ~sp,
    +plot_ly(biomass_frame) %>% 
    +    add_lines(x = ~time, y = ~value, color = ~sp,
                   colors = getColours(params))
    -
    -

    Again note the American spelling “colors” required by plotly.

    +
    +

    Again note the American spelling “colors” required by plotly.

    -Plotting spectra

    +Plotting spectra

    Of course mizer has the plotSpectra() function for plotting size spectra. Again it is instructional to create such plots by hand.

    We can access the abundance spectra of the species via N(sim). This is a three-dimensional array (time x species x size). Let us first look at the abundance at the final time.

     final_n <- N(sim)[idxFinalT(sim), , , drop = FALSE]

    The drop = FALSE means that the result will again be a 3 dimensional array.

    -str(final_n)
    +str(final_n)
    ##  num [1, 1:12, 1:100] 1.92e+06 4.81e+12 1.15e+14 3.86e+12 1.12e+11 ...
     ##  - attr(*, "dimnames")=List of 3
     ##   ..$ time: chr "10"
     ##   ..$ sp  : chr [1:12] "Sprat" "Sandeel" "N.pout" "Herring" ...
     ##   ..$ w   : chr [1:100] "0.001" "0.00119" "0.00142" "0.0017" ...
    -

    We use the melt() function to convert this array into a data frame.

    +

    We use the melt() function to convert this array into a data frame.

    -nf <- melt(final_n)
    +nf <- melt(final_n)

    This has created a data frame with 4 variables and one observation for each of the 1200 entries in the 1 x 12 x rdim(final_n)[3] matrix final_n.

    -str(nf)
    +str(nf)
    ## 'data.frame':    1200 obs. of  4 variables:
     ##  $ time : int  10 10 10 10 10 10 10 10 10 10 ...
     ##  $ sp   : Factor w/ 12 levels "Sprat","Sandeel",..: 1 2 3 4 5 6 7 8 9 10 ...
    @@ -300,150 +318,150 @@ 

    The first three variables take their values from the dimension names of the array. Of course the time variable is the same for all observations, because we selected these before creating the data frame. The fourth variable called value is the value of the entry of the array, so the abundance density in our case.

    There are a lot of entries with value 0, which we are not really interested in, so it makes sense to remove them:

    -nf <- filter(nf, value > 0)
    +nf <- filter(nf, value > 0)

    This leaves a data frame with only 945 observations.

    We can send this data frame to ggplot and add a line for the spectrum for each species, with a different colour for each, and specify that we want both the x axis and the y axis to be on a logarithmic scale.

    -pg <- ggplot(nf) +
    -    geom_line(aes(x = w, y = value, color = sp)) +
    -    scale_x_log10() +
    -    scale_y_log10()
    +pg <- ggplot(nf) +
    +    geom_line(aes(x = w, y = value, color = sp)) +
    +    scale_x_log10() +
    +    scale_y_log10()
     pg

    The corresponding syntax for plotly is

    -p <- plot_ly(nf) %>%
    -    add_lines(x = ~w, y = ~value, color = ~sp) %>% 
    -    layout(xaxis = list(type = "log", exponentformat = "power"),
    -           yaxis = list(type = "log", exponentformat = "power"))
    +p <- plot_ly(nf) %>%
    +    add_lines(x = ~w, y = ~value, color = ~sp) %>% 
    +    layout(xaxis = list(type = "log", exponentformat = "power"),
    +           yaxis = list(type = "log", exponentformat = "power"))
     p
    -
    -

    In the above we used the pipe operator %>% which feeds the return value of one function into the first argument of the next function.

    +
    +

    In the above we used the pipe operator %>% which feeds the return value of one function into the first argument of the next function.

    -Including resource spectrum

    +Including resource spectrum

    We can include additional lines in the plot by merging several data frames. For example, we can include another line for the resource spectrum. We first convert also the resource abundance at the final time into a data frame and filter out the zero values

    -nf_pp <- melt(NResource(sim)[idxFinalT(sim), , drop = FALSE]) %>% 
    -    filter(value > 0)
    +nf_pp <- melt(NResource(sim)[idxFinalT(sim), , drop = FALSE]) %>% + filter(value > 0)

    This data frame only contains three variables, because it does not have the sp column specifying the species. We add this column with the value “Resource”

     nf_pp$sp <- "Resource"

    Now this new data frame has the same columns as the data frame nf and the two can be bound together

    -nf <- rbind(nf, nf_pp)
    +nf <- rbind(nf, nf_pp)

    Using this extended data frame gives the following plot:

    -p <- ggplot(nf) +
    -    geom_line(aes(x = w, y = value, color = sp)) + 
    -    scale_colour_manual(values = getColours(params)) +
    -    scale_x_log10() +
    -    scale_y_log10()
    +p <- ggplot(nf) +
    +    geom_line(aes(x = w, y = value, color = sp)) + 
    +    scale_colour_manual(values = getColours(params)) +
    +    scale_x_log10() +
    +    scale_y_log10()
     p

    Of course we could use the same data frame also with plotly.

    -Limiting the axes

    -

    We might want to zoom in on the part that includes the fish. There are three ways to achieve this. The first is to use filter() to filter out all the rows in the data frame that have small w and then plot the resulting data frame as usual:

    +Limiting the axes +

    We might want to zoom in on the part that includes the fish. There are three ways to achieve this. The first is to use filter() to filter out all the rows in the data frame that have small w and then plot the resulting data frame as usual:

    -nf %>%
    -    filter(w > 10^-4) %>% 
    -    ggplot() +
    -    geom_line(aes(x = w, y = value, color = sp)) + 
    -    scale_colour_manual(values = getColours(params)) +
    -    scale_x_log10() +
    -    scale_y_log10()
    +nf %>% + filter(w > 10^-4) %>% + ggplot() + + geom_line(aes(x = w, y = value, color = sp)) + + scale_colour_manual(values = getColours(params)) + + scale_x_log10() + + scale_y_log10()

    The second method is to specify limits for the axes. In ggplot this is done by adding limits to the axis scales:

    -ggplot(nf) +
    -    geom_line(aes(x = w, y = value, color = sp)) + 
    -    scale_colour_manual(values = getColours(params)) +
    -    scale_x_log10(limits = c(10^-4, NA)) +
    -    scale_y_log10(limits = c(NA, 10^20))
    +ggplot(nf) + + geom_line(aes(x = w, y = value, color = sp)) + + scale_colour_manual(values = getColours(params)) + + scale_x_log10(limits = c(10^-4, NA)) + + scale_y_log10(limits = c(NA, 10^20))

    The NA means that the existing limits are kept.

    In plotly we specify the range as follows:

    -plot_ly(nf) %>%
    -    add_lines(x = ~w, y = ~value, color = ~sp,
    -              colours = getColours(params)) %>% 
    -    layout(xaxis = list(type = "log", exponentformat = "power",
    -                        range = c(-4, 4)),
    -           yaxis = list(type = "log", exponentformat = "power",
    -                        range = c(-14, 20)))
    -
    -

    Note how in plotly the range is specified by giving the logarithm to base 10 of the limits.

    +plot_ly(nf) %>% + add_lines(x = ~w, y = ~value, color = ~sp, + colours = getColours(params)) %>% + layout(xaxis = list(type = "log", exponentformat = "power", + range = c(-4, 4)), + yaxis = list(type = "log", exponentformat = "power", + range = c(-14, 20))) +
    +

    Note how in plotly the range is specified by giving the logarithm to base 10 of the limits.

    -Animating spectra

    -

    Instead of picking out a specific time we can ask plotly to make an animation showing the changing spectra over time. So we melt the entire N(sim) array and use the time variable to specify the frames with the frame = ~time argument to add_lines():

    +Animating spectra +

    Instead of picking out a specific time we can ask plotly to make an animation showing the changing spectra over time. So we melt the entire N(sim) array and use the time variable to specify the frames with the frame = ~time argument to add_lines():

    -melt(N(sim)) %>% 
    -    filter(value > 0) %>% 
    -    plot_ly() %>% 
    -    add_lines(x = ~w, y = ~value, 
    +melt(N(sim)) %>% 
    +    filter(value > 0) %>% 
    +    plot_ly() %>% 
    +    add_lines(x = ~w, y = ~value, 
                   color = ~sp, colors = getColours(params),
                   frame = ~time,
    -              line = list(simplify = FALSE)) %>% 
    -    layout(xaxis = list(type = "log", exponentformat = "power"),
    -           yaxis = list(type = "log", exponentformat = "power"))
    -
    -

    Note how this produces a smooth animation in spite of the fact that we saved the abundances only once a year. That interpolation is facilitated by the line = list(simplify = FALSE) argument.

    + line = list(simplify = FALSE)) %>% + layout(xaxis = list(type = "log", exponentformat = "power"), + yaxis = list(type = "log", exponentformat = "power"))
    +
    +

    Note how this produces a smooth animation in spite of the fact that we saved the abundances only once a year. That interpolation is facilitated by the line = list(simplify = FALSE) argument.

    The ggplot package does not provide a similarly convenient way of creating animations. There is the gganimate package, but it is not nearly as convenient.

    -Comparing simulations

    +Comparing simulations

    We may also want to make plots contrasting the results of two different simulations, for example with different fishing policies. To illustrate this we create two simulations with different fishing effort:

     sim1 <- project(params, t_max = 10, t_save = 0.2, effort = 2)
     sim2 <- project(params, t_max = 10, t_save = 0.2, effort = 4)

    Let us look at a plot of the fishing yield against time. This is calculated by the getYield() function, which returns an array (time x species) that we can convert to a data frame

    -yield1 <- melt(getYield(sim1))
    -yield2 <- melt(getYield(sim2))
    +yield1 <- melt(getYield(sim1)) +yield2 <- melt(getYield(sim2))

    Let’s look at the plot of the yield from the first simulation:

    -ggplot(yield1) +
    -    geom_line(aes(x = time, y = value, colour = sp))
    +ggplot(yield1) + + geom_line(aes(x = time, y = value, colour = sp))

    To make the plot less cluttered, we keep only the 4 most important species

    -yield1 <- filter(yield1, sp %in% c("Saithe", "Cod", "Haddock", "N.pout"))
    -yield2 <- filter(yield2, sp %in% c("Saithe", "Cod", "Haddock", "N.pout"))
    +yield1 <- filter(yield1, sp %in% c("Saithe", "Cod", "Haddock", "N.pout")) +yield2 <- filter(yield2, sp %in% c("Saithe", "Cod", "Haddock", "N.pout"))

    and plot again

    -p1 <- ggplot(yield1) +
    -    geom_line(aes(x = time, y = value, colour = sp))
    +p1 <- ggplot(yield1) +
    +    geom_line(aes(x = time, y = value, colour = sp))
     p1

    For simulation 2 the plot looks like this:

    -p2 <- ggplot(yield2) +
    -    geom_line(aes(x = time, y = value, colour = sp))
    +p2 <- ggplot(yield2) +
    +    geom_line(aes(x = time, y = value, colour = sp))
     p2

    Comparison will be easier if we combine these two plots. For that we add an extra variable to the data frames that allow us to distinguish them and then we merge them together.

    -yield1$effort = as.factor(2)
    -yield2$effort = as.factor(4)
    -yield = rbind(yield1, yield2)
    -

    In ggplot we can now use facet_grid() to put the plot for each value of effort side-by-side:

    +yield1$effort = as.factor(2) +yield2$effort = as.factor(4) +yield = rbind(yield1, yield2) +

    In ggplot we can now use facet_grid() to put the plot for each value of effort side-by-side:

    -ggplot(yield) +
    -    geom_line(aes(x = time, y = value, 
    +ggplot(yield) +
    +    geom_line(aes(x = time, y = value, 
                       colour = sp)) +
    -    facet_grid(cols = vars(effort))
    + facet_grid(cols = vars(effort))

    Or we can use the linetype aesthetic to represent the different effort values by different line types:

    -ggplot(yield) +
    -    geom_line(aes(x = time, y = value, 
    +ggplot(yield) +
    +    geom_line(aes(x = time, y = value, 
                       colour = sp,
                       linetype = effort))

    @@ -467,18 +485,18 @@

    -

    plotly is less good at faceting, but it can put arbitrary plots side-by-side (or arrange them into a grid) with subplot()

    +

    plotly is less good at faceting, but it can put arbitrary plots side-by-side (or arrange them into a grid) with subplot()

    -subplot(p1, p2, shareX = TRUE, shareY = TRUE)
    -
    -

    Note how the shareY = TRUE argument to suplot() makes sure the two plots use the same scale on the y axis, and similarly for shareX = TRUE.

    +subplot(p1, p2, shareX = TRUE, shareY = TRUE) +
    +

    Note how the shareY = TRUE argument to suplot() makes sure the two plots use the same scale on the y axis, and similarly for shareX = TRUE.

    Also in plotly we can now tie the effort variable to the line type.

    -plot_ly(yield) %>% 
    -    add_lines(x = ~time, y = ~value, 
    +plot_ly(yield) %>% 
    +    add_lines(x = ~time, y = ~value, 
                   color = ~sp, linetype = ~effort)
    -
    -

    Arguably, ggplot2 does a nicer job in this case.

    +
    +

    Arguably, ggplot2 does a nicer job in this case.

    @@ -493,13 +511,11 @@

    diff --git a/docs/articles/plotting_files/figure-html/unnamed-chunk-12-1.png b/docs/articles/plotting_files/figure-html/unnamed-chunk-12-1.png index eb30ae5f6..ebbb75446 100644 Binary files a/docs/articles/plotting_files/figure-html/unnamed-chunk-12-1.png and b/docs/articles/plotting_files/figure-html/unnamed-chunk-12-1.png differ diff --git a/docs/articles/plotting_files/figure-html/unnamed-chunk-13-1.png b/docs/articles/plotting_files/figure-html/unnamed-chunk-13-1.png index 6527fc73d..5ff65d0b6 100644 Binary files a/docs/articles/plotting_files/figure-html/unnamed-chunk-13-1.png and b/docs/articles/plotting_files/figure-html/unnamed-chunk-13-1.png differ diff --git a/docs/articles/plotting_files/figure-html/unnamed-chunk-15-1.png b/docs/articles/plotting_files/figure-html/unnamed-chunk-15-1.png index 98cfc6bc9..4967c55f6 100644 Binary files a/docs/articles/plotting_files/figure-html/unnamed-chunk-15-1.png and b/docs/articles/plotting_files/figure-html/unnamed-chunk-15-1.png differ diff --git a/docs/articles/plotting_files/figure-html/unnamed-chunk-27-1.png b/docs/articles/plotting_files/figure-html/unnamed-chunk-27-1.png index b75d69376..6d14f18da 100644 Binary files a/docs/articles/plotting_files/figure-html/unnamed-chunk-27-1.png and b/docs/articles/plotting_files/figure-html/unnamed-chunk-27-1.png differ diff --git a/docs/articles/plotting_files/figure-html/unnamed-chunk-28-1.png b/docs/articles/plotting_files/figure-html/unnamed-chunk-28-1.png index 6ee8e0bd0..d75ff94d0 100644 Binary files a/docs/articles/plotting_files/figure-html/unnamed-chunk-28-1.png and b/docs/articles/plotting_files/figure-html/unnamed-chunk-28-1.png differ diff --git a/docs/articles/plotting_files/figure-html/unnamed-chunk-29-1.png b/docs/articles/plotting_files/figure-html/unnamed-chunk-29-1.png index d88e2742e..6c5a51c5b 100644 Binary files a/docs/articles/plotting_files/figure-html/unnamed-chunk-29-1.png and b/docs/articles/plotting_files/figure-html/unnamed-chunk-29-1.png differ diff --git a/docs/articles/publications.html b/docs/articles/publications.html index 07ba1a862..0b4391da5 100644 --- a/docs/articles/publications.html +++ b/docs/articles/publications.html @@ -6,6 +6,12 @@ Publications • mizer + + + + + + @@ -15,14 +21,13 @@ + - -
    -
    -

    -Publications describing mizer:

    +
    +

    +Publications describing mizer

    • F. Scott, J.L. Blanchard and K.H. Andersen: mizer: an R package for multispecies, trait-based and community size spectrum ecological modelling. Methods in Ecology and Evolution 5(10) 1121-1125 (2014). Contains the “official” announcement and description of mizer

    • -
    • K.H. Andersen, N.S. Jacobsen and K.D. Farnsworth (2016): The theoretical foundations for size spectrum models of fish communities. Canadian Journal of Fisheries and Aquatic Science 73(4): 575-588. Describes the theoretical background of the three types of size spectrum models

    • -
    • K.H. Andersen (2019): Fish Ecology, Evolution, and Exploitation - a New Theoretical Synthesis. Princeton University Press. In depth theory

    • +
    • K.H. Andersen, N.S. Jacobsen and K.D. Farnsworth (2016): The theoretical foundations for size spectrum models of fish communities. Canadian Journal of Fisheries and Aquatic Science 73(4): 575-588. Describes the theoretical background of the three types of size spectrum models

    • +
    • K.H. Andersen (2019): Fish Ecology, Evolution, and Exploitation - a New Theoretical Synthesis. Princeton University Press. In depth theory

    -
    -

    -Publications using mizer:

    +
    +

    +Publications using mizer

      +
    • Canales, T. M., Delius, G. W. & Law, R. Regulation of fish stocks without stock–recruitment relationships: The case of small pelagic fish. Fish and Fisheries 21, 857–871 (2020).

    • +
    • Wo, J. et al. Modeling the Dynamics of Multispecies Fisheries: A Case Study in the Coastal Water of North Yellow Sea, China. Front. Mar. Sci. 7, (2020).

    • +
    • Lindmark, M. Temperature- and body size scaling. Doctoral Thesis No 2020:8, Faculty of Natural Resources and Agricultural Sciences, SLU. https://pub.epsilon.slu.se/16711/ (2020).

    • +
    • Spence, M. A. et al. A general framework for combining ecosystem models. Fish and Fisheries 19, 1031–1042 (2018).

    • Zhang C, Chen Y, Xu B, Xue Y, Ren Y. Evaluating fishing effects on the stability of fish communities using a size-spectrum model. Fisheries Research. 2018 Jan 1;197:123-30.

    • Szuwalski CS, Burgess MG, Costello C, Gaines SD (2017) High fishery catches through trophic cascades in China. Proc Natl Acad Sci USA 114:717–721. Application to the South-east China Sea

    • N.S. Jacobsen, M. Burgess and K.H. Andersen (2017): Efficiency of fisheries is increasing at the ecosystem level. Fish and Fisheries 18(2) 199-211. doi:10.1111/faf.12171. Appendix describes simple calibration procedure

    • @@ -166,14 +188,14 @@

    • J.L. Blanchard, K.H. Andersen, F. Scott, N.T. Hinzen, G. Piet, S. Jennings (2014): Evaluating targets and trade-offs among fisheries and conservation objectives using a multispecies size spectrum model. J. Applied Ecology, 51: 612–622. doi:10.1111/1365-2664.12238. Application of Mizer on the North Sea

    -
    -

    -Projects that have used/are using mizer:

    -

    The MINOUW Project (http://minouw-project.eu/) European Commission Horizon 2020 Research and Innovation Programme under Grant Agreement No. 634495

    +
    +

    +Projects that have used/are using mizer

    +

    The MINOUW Project (http://minouw-project.eu/) European Commission Horizon 2020 Research and Innovation Programme under Grant Agreement No. 634495

    Rewiring marine food webs: predicting consequences of species range shifts. Australian Research Council Discovery Project DP170104240

    Mesopelagic Southern Ocean Prey and Predators (MESOPP), European Commission H2020 (www.mesopp.eu)

    Expert Working Group on Benchmarks for Ecosystem Assessment under EBFM. Lenfest Ocean Program

    -

    Marine Ecosystems Research Programme (MERP) (https://marine-ecosystems.org.uk). UK Defra - Natural Environmental Research Council

    +

    Marine Ecosystems Research Programme (MERP) (https://marine-ecosystems.org.uk). UK Defra - Natural Environmental Research Council

    “Monitoring and Management of Deepwater Fisheries and Stocks” (Deepfishman) European Union Framework 7.

    “Developing fisheries management indicators and targets” (DEFINEIT) European Marifish Joint Research project.

    “Indicators for fisheries Management in Europe” (IMAGE) European Union Framework 6.

    @@ -182,20 +204,20 @@

    + +

    diff --git a/docs/articles/running_a_simulation.html b/docs/articles/running_a_simulation.html index df721c5c5..62e4b10e0 100644 --- a/docs/articles/running_a_simulation.html +++ b/docs/articles/running_a_simulation.html @@ -6,6 +6,12 @@ Running a Simulation • mizer + + + + + + @@ -15,14 +21,13 @@ + - -
    @@ -142,7 +160,7 @@

    Running a Simulation

    -Introduction

    +Introduction

    In the community and trait-based models, we used the project() function to perform simple simulations where the fishing effort was held constant throughout the duration of the simulation. In the trait-based model example, we also looked at how the effort for different gears could be specified. In this section we take a detailed look at how the project() function works and the different ways in which effort and time can be set up. This will allow us to run more general systems like the multispecies model.

    In mizer, simulations are performed using the project() function. This function takes a MizerParams object and projects it forward through time, starting from an initial population abundance and with a pre-determined fishing effort pattern.

    Running a projection with project() requires various arguments:

    @@ -157,7 +175,7 @@

    -The time arguments

    +The time arguments

    There are four arguments that control time in the project() function: dt, t_max and t_save and t_start. All of them have default values.

    • @@ -172,7 +190,7 @@

      -Setting the fishing effort

      +Setting the fishing effort

      The fishing effort argument describes the effort of the fishing gears in the model through time. We have already seen that information on the fishing gears and their selectivities and catchabilities is stored in the MizerParams object.

      There are three ways of setting the fishing effort. Examples of all three can be seen in the section on projection examples.

      The simplest way is by passing the effort argument as a single number. This value is then used as the fishing effort by all of the gears at each time step of the projection, i.e. fishing effort is constant throughout the simulation and is the same for all gears. We have seen this method in the community and trait-based model sections above. The length of the simulation is determined by the t_max argument.

      @@ -182,21 +200,21 @@

      -Setting the initial population abundance

      -

      When running a simulation with the project() function, the initial populations of the species and the resource spectrum need to be specified. Default values for the initial values are automatically set when creating a MizerParams object. However you can change these by assigning new values to initialN() and initialNResource(). initialN() should be set to a matrix (with dimensions species x size) that contains the initial abundances of each species at size (the sizes must match those in the species size spectrum). initialNResource to a vector of the same length as the the length of the full spectrum.

      +Setting the initial population abundance

      +

      When running a simulation with the project() function, the initial populations of the species and the resource spectrum need to be specified. Default values for the initial values are automatically set when creating a MizerParams object. However you can change these by assigning new values to initialN() and initialNResource(). initialN() should be set to a matrix (with dimensions species x size) that contains the initial abundances of each species at size (the sizes must match those in the species size spectrum). initialNResource to a vector of the same length as the the length of the full spectrum.

      -Projection examples

      +Projection examples

    In this section we’ll look at how to run simulations with the project() function. The examples will focus on how fishing effort can be specified in different ways. The results of the simulations will not be explored in detail. We will leave that for the section on exploring the simulation results..

    Remember that the fishing mortality by size on a species is the product of the selectivity, the catchability and the effort of the gear that caught it. We have not specified any catchability values in the species parameter data.frame so the default value of 1 is used. The selectivity ranges between 0 and 1. This means that in these examples the fishing mortality of a fully selected species is given by the effort of the gear that catches it.

    -Projections with single, simple constant effort

    +Projections with single, simple constant effort

    When we use a single value for the effort argument, the value is used as a constant effort for all the gears. This method can be particularly useful for quickly projecting forward without fishing (you just set the effort argument to 0).

    We will use a MizerParams object with four gears similar to the one that we created in the section with examples of making a MizerParams objects This example MizerParams object is called NS_params and is shipped with the mizer package. Let’s have a look at its summary:

    -summary(NS_params)
    +summary(NS_params)
    ## An object of class "MizerParams" 
     ## Consumer size spectrum:
     ##  minimum size:   0.001
    @@ -220,24 +238,26 @@ 

    ## 10 Haddock 4316.5 165 0.001 0.6 0.271 558 2.1 ## 11 Cod 39851.3 1606 0.001 0.6 0.216 66 1.3 ## 12 Saithe 39658.6 1076 0.001 0.6 0.175 40 1.1 +## ## Fishing gear details: -## Gear Target species -## Industrial Sprat Sandeel N.pout -## Pelagic Herring -## Beam Dab Sole Plaice -## Otter Whiting Gurnard Haddock Cod Saithe

    +## Gear Effort Target species +## ---------------------------------- +## Industrial 0.00 Sprat, Sandeel, N.pout +## Pelagic 1.00 Herring +## Beam 0.50 Dab, Sole, Plaice +## Otter 0.50 Whiting, Gurnard, Haddock, Cod, Saithe

    As well as thinking about the effort argument we also need to consider the time parameters. We will project the populations forward until time equals 10 (t_max = 10), with a time step of 0.1 (dt = 0.1), saving the output every time step (t_save = 1). We use a constant effort value of 1.0.

     sim <- project(NS_params, effort = 1, t_max = 10, dt = 0.1, t_save = 1)

    The resulting sim object is of class MizerSim. At this point we won’t explore how the results can be investigated in detail. However, we will use the basic summary plot that you have seen before:

    -plot(sim)
    +plot(sim)

    The big difference between this multispecies model and the trait-based model can be seen in the range of predation mortality and feeding level values. With the trait-based model all the species had the same predation mortality and feeding level patterns. Here the species all have different patterns, driven by their differing life history characteristics and the heterogeneous interaction matrix.

    You can also see in the above figure that each species has different fishing selectivity (see the fishing mortality panel). Remember that the default setting for the fishing gears is a knife-edge gear where the knife-edge is positioned at the species w_mat parameter.

    -

    The effort through time can be inspected with getEffort() (we use the head() function to just show the first few lines).

    +

    The effort through time can be inspected with getEffort() (we use the head() function to just show the first few lines).

    +head(getEffort(sim))
    ##     gear
     ## time Industrial Pelagic Beam Otter
     ##    0          1       1    1     1
    @@ -247,13 +267,13 @@ 

    ## 4 1 1 1 1 ## 5 1 1 1 1

    The effort slot shows the effort by time and gear. In this example, we specified the effort argument as a single numeric of value 1. As you can see this results in the same effort being used for all gears for all time steps.

    -

    A summary() method is also available for objects of type MizerSim. This is essentially the same as the summary for MizerParams objects, but includes information on the simulation time parameters.

    +

    A summary() method is also available for objects of type MizerSim. This is essentially the same as the summary for MizerParams objects, but includes information on the simulation time parameters.

    -summary(sim)
    +summary(sim)

    If we decrease t_save but keep t_max the same then we can see that the time dimension of the effort array changes accordingly. This will also be true of the simulation results returned by N() and NResource(). Here we reduce t_save to 0.5, meaning that the effort and abundance information is stored at t = 1.0, 1.5, 2.0 etc.

     sim <- project(NS_params, effort = 1, t_max = 10, dt = 0.1, t_save = 0.5)
    -head(getEffort(sim))
    +head(getEffort(sim))
    ##      gear
     ## time  Industrial Pelagic Beam Otter
     ##   0            1       1    1     1
    @@ -265,15 +285,15 @@ 

    -Setting constant effort for different gears

    +Setting constant effort for different gears

    As mentioned above, we can also set the effort values for each gear separately using a vector of effort values. This still keeps the efforts constant through time but it means that each gear can have a different constant effort.

    We need to create a named vector of effort, where the names match the gears. For example, here we want to switch off the industrial gear (i.e. effort = 0), keep the pelagic gear effort at 1, set the effort of the beam trawl gears to 0.3 and the effort of the otter trawl gear to 0.7. We set the effort like this:

    -effort <- c(Industrial = 0, Pelagic = 1, Beam = 0.3, Otter = 0.7)
    -

    We then call project() with this effort and inspect the resulting effort matrix (again we use the head() function to just show the first few lines):

    +effort <- c(Industrial = 0, Pelagic = 1, Beam = 0.3, Otter = 0.7)
    +

    We then call project() with this effort and inspect the resulting effort matrix (again we use the head() function to just show the first few lines):

     sim <- project(NS_params, effort = effort, t_max = 10, dt = 1, t_save = 1)
    -head(getEffort(sim))
    +head(getEffort(sim))
    ##     gear
     ## time Industrial Pelagic Beam Otter
     ##    0          0       1  0.3   0.7
    @@ -287,24 +307,24 @@ 

    -An example of changing effort through time

    +An example of changing effort through time

    In this example we set up a more complicated fishing effort structure that allows the fishing effort of each gear to change through time. As mentioned above, to do this, effort must be supplied as a two dimensional array or matrix. The first dimension is time and the second dimension is gear. The dimensions must be named. The gear names must match the gears in the MizerParams object. Also, as mentioned above, if effort is passed in as an array then the length of the simulation is determined by the time dimension names and the argument t_max is not used. Instead the simulation runs from the earliest time in the effort array to the latest.

    In this example, we will project forward from time \(t=1\) to time \(t=10\). The effort of the industrial gear is held constant at 0.5, the effort of the pelagic gear is increased linearly from 1 to 2, the effort of the beam trawl decreases linearly from 1 to 0, whilst the effort of the otter trawl decreases linearly from 1 to 0.5.

    First we create the empty effort array:

    -gear_names <- c("Industrial","Pelagic","Beam","Otter")
    -times <- seq(from = 1, to = 10, by = 1)
    -effort_array <- array(NA, dim = c(length(times), length(gear_names)),
    -    dimnames = list(time = times, gear = gear_names))
    -

    Then we fill it up, one gear at a time, making heavy use of the seq() function to create a sequence:

    +gear_names <- c("Industrial","Pelagic","Beam","Otter") +times <- seq(from = 1, to = 10, by = 1) +effort_array <- array(NA, dim = c(length(times), length(gear_names)), + dimnames = list(time = times, gear = gear_names))
    +

    Then we fill it up, one gear at a time, making heavy use of the seq() function to create a sequence:

     effort_array[,"Industrial"] <- 0.5
    -effort_array[,"Pelagic"] <- seq(from = 1, to = 2, length = length(times))
    -effort_array[,"Beam"] <- seq(from = 1, to = 0, length = length(times))
    -effort_array[,"Otter"] <- seq(from = 1, to = 0.5, length = length(times))
    +effort_array[,"Pelagic"] <- seq(from = 1, to = 2, length = length(times)) +effort_array[,"Beam"] <- seq(from = 1, to = 0, length = length(times)) +effort_array[,"Otter"] <- seq(from = 1, to = 0.5, length = length(times))

    The first few rows of the effort array are shown as an illustration:

    -head(effort_array)
    +head(effort_array)
    ##     gear
     ## time Industrial  Pelagic      Beam     Otter
     ##    1        0.5 1.000000 1.0000000 1.0000000
    @@ -317,7 +337,7 @@ 

    Now we can use this effort array in the projection:

     sim <- project(NS_params, effort = effort_array, dt = 0.1)
    -head(sim@effort)
    +head(sim@effort)

    ##     gear
     ## time Industrial  Pelagic      Beam     Otter
     ##    1        0.5 1.000000 1.0000000 1.0000000
    @@ -344,13 +364,11 @@ 

    diff --git a/docs/articles/running_a_simulation_files/figure-html/plot_basic_ms_sim-1.png b/docs/articles/running_a_simulation_files/figure-html/plot_basic_ms_sim-1.png index 3211326b7..e6beb309c 100644 Binary files a/docs/articles/running_a_simulation_files/figure-html/plot_basic_ms_sim-1.png and b/docs/articles/running_a_simulation_files/figure-html/plot_basic_ms_sim-1.png differ diff --git a/docs/articles/single_species_size-spectrum_dynamics.html b/docs/articles/single_species_size-spectrum_dynamics.html index 2ee09961c..2b65a06c9 100644 --- a/docs/articles/single_species_size-spectrum_dynamics.html +++ b/docs/articles/single_species_size-spectrum_dynamics.html @@ -6,6 +6,12 @@ Single-species size-spectrum dynamics • mizer + + + + + + @@ -15,14 +21,13 @@ + - -
    @@ -142,7 +160,7 @@

    Single-species size-spectrum dynamics

    -Introduction

    +Introduction

    In this tutorial you will gain an understanding of size-spectrum dynamics. To separate the size-spectrum effects from the multi-species effects, we will concentrate on a single species in this tutorial.

    Size-spectrum dynamics describes in detail how biomass is transported through the ecosystem from small sizes to large sizes. Thus the best way to think about size-spectrum dynamics is to think of traffic on a highway, except that instead of cars travelling along the road we have fish growing along the size axis, all the way from their egg size to their maximum size. Let us explore this analogy briefly.

    + + + + + @@ -15,14 +21,13 @@ + - -
    @@ -142,13 +160,13 @@

    The Trait-Based Model

    -Introduction

    +Introduction

    The trait-based size spectrum model can be derived as a simplification of the general model outline in the model description section. It is more complicated than a community model and the most significant difference between the two is that while the community model aggregates all species into a single spectrum, the trait-based model resolves many species.

    In a trait-based model the asymptotic size is considered to be the most important trait characterizing a species. Most of the species-specific parameters, such as \(\beta\) and \(\sigma\), are the same for all species. Other model parameters are determined by the asymptotic size. For example, the weight at maturation is a fixed fraction of the asymptotic size. The asymptotic sizes of the species are spread evenly on a logarithmic scale. The number of species is not important and does not affect the general dynamics of the model.

    -Setting up a trait-based model

    +Setting up a trait-based model

    To help set up a trait-based model, there is a wrapper function, newTraitParams(). Like the newCommunityParams() function described in the section on the community model, this function can take many arguments. Most of them have default values so you don’t need to worry about them for the moment. See the help page for newCommunityParams() for more details.

    One of the key differences between the community type model and the trait-based model is that reproduction and egg production are considered. In the community model, reproduction is constant and there is no relationship between the abundance in the community and egg production. In the trait-based model, the egg production is dependent on mature individuals investing part of their energy income into reproduction. The relationship between the energy invested into reproduction and the actual rate of egg production is modelled using a Beverton-Holt type function (the default in mizer, see the section on density-dependence in reproduction) where the reproduction rate \(R_i\) (numbers per time) approaches a maximum as the energy invested increases.

    Here we set up the model to have 10 species, with asymptotic sizes ranging from 10 g to 100 kg. All the other parameters have default values.

    @@ -158,7 +176,7 @@

    The output reminds the user that \(\gamma\) was not specified, and so will be calculated using other parameters.

    This function returns an object of type MizerParams that holds all the model information, including species parameters. This object can therefore be interrogated in the same way as described in the section on the community model.

    -summary(params)
    +summary(params)

    ## An object of class "MizerParams" 
     ## Consumer size spectrum:
     ##  minimum size:   0.001
    @@ -180,29 +198,31 @@ 

    ## 8 8 1.258925e+04 3548.133892 0.001 0.6 0.25 100 1.3 ## 9 9 3.548134e+04 10000.000000 0.001 0.6 0.25 100 1.3 ## 10 10 1.000000e+05 28183.829313 0.001 0.6 0.25 100 1.3 +## ## Fishing gear details: -## Gear Target species -## knife_edge_gear 1 2 3 4 5 6 7 8 9 10

    +## Gear Effort Target species +## ---------------------------------- +## knife_edge_gear 0.00 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

    The summary shows us that now we have 10 species in the model, with asymptotic sizes ranging from \(8.9125094\) to \(`r max(species_params(params)\)w_inf)`$. The rather strange-looking values for the sizes is due to the fact that the size classes are equally spaced on a logarithmic scale.

    The size at maturity (w_mat) is linearly related to the asymptotic size. Each species has the same preferred predator-prey mass ratio parameter values (beta and sigma, see the section on predator/prey mass ratio). There are \(161\) size bins in the community and \(301\) size bins including the resource spectrum. Ignore the summary section on fishing gear for the moment. This is explained later.

    -Running the trait-based model

    +Running the trait-based model

    As with the community model, we can project the trait-based model through time using the project() function. Here we project the model for 75 years without any fishing (the effort argument is set to 0). We use the default initial population abundances so there is no need to pass in any initial population values (see the section on setting the initial abundances).

     sim <- project(params, t_max = 75, effort = 0)
    -

    This results in a MizerSim object that contains the abundances of the community and resource spectra through time, as well as the original MizerParams object. As with the community model, we can get a quick overview of the results of the simulation by calling the plot() method:

    +

    This results in a MizerSim object that contains the abundances of the community and resource spectra through time, as well as the original MizerParams object. As with the community model, we can get a quick overview of the results of the simulation by calling the plot() method:

    -plot(sim)
    +plot(sim)

    The summary plot has the same panels as the one generated by the community model, but here you can see that all the species in the community are plotted. The panels show the situation in the final time step of the simulation, apart from the biomass through time plot. As this is a trait-based model where all species fully interact with each other, the predation mortality and feeding level by size is the same for each species. In this simulation we turned fishing off so the fishing mortality is 0. The size-spectra show the abundances at size to be evenly spaced by log of asymptotic size.

    -Example of a trophic cascade with the trait-based model

    +Example of a trophic cascade with the trait-based model

    As with the community model, it is possible to use the trait-based model to simulate a trophic cascade. Again, we perform two simulations, one with fishing and one without. We therefore need to consider how fishing gears and selectivity have been set up by the newTraitParams() function.

    -

    The default fishing selectivity function is a knife-edge function, which only selects individuals larger than 1000 g. There is also only one fishing gear in operation, and this selects all of the species. You can see this if you call the summary() method on the params argument we set up above. At the bottom of the summary there is a section on Fishing gear details. You can see that there is only one gear, called knife_edge_gear and that it selects species 1 to 10. To control the size at which individuals are selected there is a knife_edge_size argument to the newTraitParams() function. This has a default value of 1000 g.

    +

    The default fishing selectivity function is a knife-edge function, which only selects individuals larger than 1000 g. There is also only one fishing gear in operation, and this selects all of the species. You can see this if you call the summary() method on the params argument we set up above. At the bottom of the summary there is a section on Fishing gear details. You can see that there is only one gear, called knife_edge_gear and that it selects species 1 to 10. To control the size at which individuals are selected there is a knife_edge_size argument to the newTraitParams() function. This has a default value of 1000 g.

    In mizer it is possible to include more than one fishing gear in the model and for different species to be caught by different gears. We will ignore this for now, but will explore it further below when we introduce an industrial fishery to the trait-based model.

    To set up the trait-based model to have fishing we set up the MizerParams object in exactly the same way as we did before but here the knife_edge_size argument is explicitly passed in for clarity:

    @@ -215,27 +235,27 @@ 

    Now we simulate with fishing. Here, we use an effort of 0.75. As mentioned in the section on trophic cascades in the community model, the fishing mortality on a species is calculated as the product of effort, catchability and selectivity (see the section on fishing gears for more details). Selectivity ranges between 0 (not selected) and 1 (fully selected). The default value of catchability is 1. Therefore, in this simulation the fishing mortality of a fully selected individual is simply equal to the effort. This effort is constant throughout the duration of the simulation (however, mizer does allow variable effort).

     sim1 <- project(params_knife, effort = 0.75, t_max = 75)
    -

    Again, we can plot the summary of the fished community using the default plot() function. The knife-edge selectivity at 1000 g can be clearly seen in the fishing mortality panel:

    +

    Again, we can plot the summary of the fished community using the default plot() function. The knife-edge selectivity at 1000 g can be clearly seen in the fishing mortality panel:

    -plot(sim1)
    +plot(sim1)

    The trophic cascade can be explored by comparing the total abundances of all species at size when the community is fished and unfished. As mentioned above, we obtain the abundances with N(sim), which returns a three dimensional array with dimensions time x species x size. Here we have 76 time steps (75 from the simulation plus one which stores the initial population), 10 species and 100 sizes:

    -dim(N(sim0))
    +dim(N(sim0))
    ## [1]  76  10 161

    As with the community model, we are interested in the relative total abundances by size in the final time step so we use the finalN() function. This gives us a matrix with one row per species and one column per size bin. We sum in each column to get a vector with the total abundance per size bin:

    -total_abund0 <- colSums(finalN(sim0))
    -total_abund1 <- colSums(finalN(sim1))
    +total_abund0 <- colSums(finalN(sim0)) +total_abund1 <- colSums(finalN(sim1))

    We can then use these vectors to calculate the relative abundances:

     relative_abundance <- total_abund1 / total_abund0

    This can be plotted using the commands below:

    -plot(x = w(params), y = relative_abundance, log = "xy", type = "n", 
    -     xlab = "Size (g)", ylab = "Relative abundance", ylim = c(0.1, 10))
    -lines(x = w(params), y = relative_abundance)
    -lines(x = c(min(w(params)), max(w(params))), y = c(1, 1), lty = 2)
    +plot(x = w(params), y = relative_abundance, log = "xy", type = "n", + xlab = "Size (g)", ylab = "Relative abundance", ylim = c(0.1, 10)) +lines(x = w(params), y = relative_abundance) +lines(x = c(min(w(params)), max(w(params))), y = c(1, 1), lty = 2)

    The impact of fishing on species larger than 1000 g can be clearly seen. The fishing pressure lowers the abundance of large fish (\(> 1000\) g). This then relieves the predation pressure on their smaller prey (the preferred predator-prey size ratio is given by the \(\beta\) parameter, which is set to 100 by default), leading to an increase in their abundance. This in turn increases the predation mortality on their smaller prey, which reduces their abundance and so on.

    This impact can also be seen by looking at the predation mortality by size. The predation mortalities are retrieved using the getPredMort() function. As mentioned above, for the trait based model the predation mortality by size is the same for each species. Therefore we only look at the predation mortality of the first species.

    @@ -244,10 +264,10 @@

    m2_with_fishing <- getPredMort(params, finalN(sim1))[1, ]

    The predation mortalities can then be plotted.

    -plot(x = w(params), y = m2_with_fishing, log = "x", type = "n", 
    +plot(x = w(params), y = m2_with_fishing, log = "x", type = "n", 
          xlab = "Size [g]", ylab = "Predation Mortality [1/year]")
    -lines(x = w(params), y = m2_no_fishing, lty = 2)
    -lines(x = w(params), y = m2_with_fishing)
    +lines(x = w(params), y = m2_no_fishing, lty = 2) +lines(x = w(params), y = m2_with_fishing)
    Predation mortalities from the unfished (dashed line) and fished (solid line) trait-based model.

    Predation mortalities from the unfished (dashed line) and fished (solid line) trait-based model. @@ -256,7 +276,7 @@

    -Setting up an industrial fishing gear

    +Setting up an industrial fishing gear

    In this section we want to operate an industrial fishery. Industrial fishing targets the small zooplanktivorous species that are typically used for fishmeal production.

    In the previous simulations we had only one fishing gear and it targeted all the species in the community. This gear had a knife-edge selectivity that only selected species larger than 1 kg. We can see that when we look at the gear parameters

    @@ -284,7 +304,7 @@ 

    Now we want to assign each species to either the industrial or other gear.

     no_sp <- 10
    -gear <- rep("Industrial", no_sp)
    +gear <- rep("Industrial", no_sp)
     gear[species_params(params)$w_inf > 500] <- "Other"
     gear_params(params_multi_gear)$gear <- gear

    To check what has just happened let us look at the new gear parameter data frame:

    @@ -306,34 +326,34 @@

    sim_multi_gear <- project(params_multi_gear, t_max = 75, effort = 0.5)

    By plotting this you can see that the fishing mortality for each species now has a different selectivity pattern, and that the position of the selectivity knife-edge is given by the asymptotic size of the species.

    -plot(sim_multi_gear)
    +plot(sim_multi_gear)

    For the industrial fishery we said that we only wanted species with an asymptotic size of 500 g or less to be fished. There are several ways of specifying the effort argument for project() . Above we specified a single value that was used for all gears, for all time steps. It is also possible to specify a separate effort for each gear that will be used for all time steps. To do this we pass in effort as a named vector. Here we set the effort for the Industrial gear to 0.75, and the effort of the Other gear to 0 (effectively turning it off).

     sim_multi_gear <- project(params_multi_gear, t_max = 75,
    -    effort = c(Industrial = 0.75, Other = 0))
    + effort = c(Industrial = 0.75, Other = 0))

    Now you can see that the Industrial gear has been operating and that fishing mortality for species larger than 500 g is 0.

    -plot(sim_multi_gear)
    +plot(sim_multi_gear)

    -The impact of industrial fishing

    +The impact of industrial fishing

    In the previous section we set up and ran a model in which an industrial fishery was operating that only selected smaller species. We can now answer the question: what is the impact of such a fishery? We can again compare abundances of the fished (sim_industrial1) and unfished (sim_industrial0) cases:

     sim_industrial0 <- project(params_multi_gear, t_max = 75, effort = 0)
     sim_industrial1 <- project(params_multi_gear, t_max = 75,
    -    effort = c(Industrial = 0.75, Other = 0))
    -total_abund0 <- apply(finalN(sim_industrial0), 2, sum)
    -total_abund1 <- apply(finalN(sim_industrial1), 2, sum)
    +    effort = c(Industrial = 0.75, Other = 0))
    +total_abund0 <- apply(finalN(sim_industrial0), 2, sum)
    +total_abund1 <- apply(finalN(sim_industrial1), 2, sum)
     relative_abundance <- total_abund1 / total_abund0

    And plot the relative abundances:

    -plot(x = w(params), y = relative_abundance, log = "xy", type = "n", 
    -     xlab = "Size [g]", ylab="Relative abundance", ylim = c(0.1, 10))
    -lines(x = w(params), y = relative_abundance)
    -lines(x = c(min(w(params)),max(w(params))), y = c(1, 1), lty = 2)
    +plot(x = w(params), y = relative_abundance, log = "xy", type = "n", + xlab = "Size [g]", ylab="Relative abundance", ylim = c(0.1, 10)) +lines(x = w(params), y = relative_abundance) +lines(x = c(min(w(params)),max(w(params))), y = c(1, 1), lty = 2)

    This shows another trophic cascade, although this time one driven by fishing the species at the midrange part of the spectrum, not the largest individuals as before. This trophic cascade acts in both directions. The cascade upwards is driven by the lack of food for predators leading to smaller realised maximum sizes. The cascade downwards has the same mechanism as fishing on large fish, a combination of predation mortality and food limitation.

    The next section explains how to setup the more general multispecies model.

    @@ -351,13 +371,11 @@

    diff --git a/docs/articles/trait_model_files/figure-html/plot_comm_sim_2-1.png b/docs/articles/trait_model_files/figure-html/plot_comm_sim_2-1.png index 7efebcbba..a6d11430e 100644 Binary files a/docs/articles/trait_model_files/figure-html/plot_comm_sim_2-1.png and b/docs/articles/trait_model_files/figure-html/plot_comm_sim_2-1.png differ diff --git a/docs/articles/trait_model_files/figure-html/plot_multi_gear_trait-1.png b/docs/articles/trait_model_files/figure-html/plot_multi_gear_trait-1.png index 902848e68..66a7cb6ef 100644 Binary files a/docs/articles/trait_model_files/figure-html/plot_multi_gear_trait-1.png and b/docs/articles/trait_model_files/figure-html/plot_multi_gear_trait-1.png differ diff --git a/docs/articles/trait_model_files/figure-html/plot_multi_gear_trait_single_effort-1.png b/docs/articles/trait_model_files/figure-html/plot_multi_gear_trait_single_effort-1.png index 0f36819f1..9cab4ab3d 100644 Binary files a/docs/articles/trait_model_files/figure-html/plot_multi_gear_trait_single_effort-1.png and b/docs/articles/trait_model_files/figure-html/plot_multi_gear_trait_single_effort-1.png differ diff --git a/docs/articles/trait_model_files/figure-html/plot_relative_comm_abund2-1.png b/docs/articles/trait_model_files/figure-html/plot_relative_comm_abund2-1.png index 6c0e7c131..17787c3e0 100644 Binary files a/docs/articles/trait_model_files/figure-html/plot_relative_comm_abund2-1.png and b/docs/articles/trait_model_files/figure-html/plot_relative_comm_abund2-1.png differ diff --git a/docs/articles/trait_model_files/figure-html/plot_relative_comm_abund_industrial-1.png b/docs/articles/trait_model_files/figure-html/plot_relative_comm_abund_industrial-1.png index 1450cd0c7..8772f5130 100644 Binary files a/docs/articles/trait_model_files/figure-html/plot_relative_comm_abund_industrial-1.png and b/docs/articles/trait_model_files/figure-html/plot_relative_comm_abund_industrial-1.png differ diff --git a/docs/articles/trait_model_files/figure-html/plot_relative_trait_m2-1.png b/docs/articles/trait_model_files/figure-html/plot_relative_trait_m2-1.png index 2b8bad4f6..02d283c29 100644 Binary files a/docs/articles/trait_model_files/figure-html/plot_relative_trait_m2-1.png and b/docs/articles/trait_model_files/figure-html/plot_relative_trait_m2-1.png differ diff --git a/docs/articles/trait_model_files/figure-html/plot_trait_fmort-1.png b/docs/articles/trait_model_files/figure-html/plot_trait_fmort-1.png index cd13ed506..c100171cb 100644 Binary files a/docs/articles/trait_model_files/figure-html/plot_trait_fmort-1.png and b/docs/articles/trait_model_files/figure-html/plot_trait_fmort-1.png differ diff --git a/docs/articles/working_with_git.html b/docs/articles/working_with_git.html index 6a70d7629..6bee0a697 100644 --- a/docs/articles/working_with_git.html +++ b/docs/articles/working_with_git.html @@ -6,6 +6,12 @@ Working with git and GitHub • mizer + + + + + + @@ -15,14 +21,13 @@ + - -
    @@ -142,14 +160,14 @@

    Working with git and GitHub

    -Introduction

    +Introduction

    It initially takes a bit of effort to get the hang of how this works. Therefore here we will take you through a little exercise that will see you create a feature branch, make a change to a mizer file, commit that file and push it to GitHub, and then make a pull request to contribute the change back to the core mizer code. The change that you will be making consists of adding your name to the list of people who have set up a fork of mizer.

    We assume that you have set up your working environment and checked out your mizer fork to your local computer as described in the section Setting up working environment in the mizer developer guide. If you have not yet read that section, please do so now and follow all the instructions there before continuing with this tutorial.

    -Creating a branch

    -

    Initially you will be on the “master” branch of your repository. The code in this branch of your repository is a perfect copy of the code in the master branch of the main mizer repository at https://github.com/sizespectrum/mizer. You should always keep it that way and not commit any changes to this branch.

    +Creating a branch +

    Initially you will be on the “master” branch of your repository. The code in this branch of your repository is a perfect copy of the code in the master branch of the main mizer repository at https://github.com/sizespectrum/mizer. You should always keep it that way and not commit any changes to this branch.

    You should do all our development work in branches that have been branched off from the master branch. When you start working on a feature or on a bug fix, start a new branch with a name suggestive of the feature or fix. In this example, where you will be adding your info to the list of people who have set up a fork of mizer, let’s call the branch “add_my_info”.

    To create the new branch, first make sure you have selected the master branch on the “Switch branch” dropdown in RStudio Git panel and then click the button to the left of that dropdown.
    @@ -159,8 +177,8 @@

    -Editing a file

    -

    Next you will make an edit to a file. In the “Files” tab in RStudio, navigate to the “vignette” subdirectory and click on the name “developer_vignette.Rmd”. That will open that file in the Source editor pane. That file is the source file for this developer guide, written in R Markdown format.

    +Editing a file +

    Next you will make an edit to a file. In the “Files” tab in RStudio, navigate to the “vignette” subdirectory and click on the name “developer_vignette.Rmd”. That will open that file in the Source editor pane. That file is the source file for this developer guide, written in R Markdown format.

    A good way to navigate within files is to use the document outline which will be displayed when you hit the right-most icon on the editor pane toolbar.
    @@ -171,7 +189,7 @@

    -Committing your changes

    +Committing your changes So far you have only saved your changes to your local disc, but have not yet committed it to your local repository. To do that you click on the “Commit” button on the toolbar in the “Git” pane in RStudio:
    @@ -186,7 +204,7 @@

    -Pushing and pulling

    +Pushing and pulling

    So far you have only committed your changes to the local repository on your computer. The changes have not yet been synchronised with your repository on GitHub. To do that, you click on the “Push” button on the toolbar of the “Git” pane, the one that looks like an up arrow. A window will pop up that will confirm if that push worked alright. You can then close that window.

    After you have pushed your changes, you will be able to see them also on GitHub. If you go to the home page of your GitHub repository you will see a comment that you made a commit a little while ago:
    @@ -196,8 +214,8 @@

    -Making a pull request

    -

    Once a feature is developed and tested, you will want to merge it into the master branch of the upstream repository at https://github.com/sizespectrum/mizer. You can however not push your changes directly to that repository. Instead you create a GitHub pull request. This will then get a code review from another mizer developer before one of the developers with write access to the main repository merges your changes.

    +Making a pull request +

    Once a feature is developed and tested, you will want to merge it into the master branch of the upstream repository at https://github.com/sizespectrum/mizer. You can however not push your changes directly to that repository. Instead you create a GitHub pull request. This will then get a code review from another mizer developer before one of the developers with write access to the main repository merges your changes.

    Due to this extra code review before any changes are integrated into the core mizer code, you do not have to be hesitant with making pull requests. In case there is anything wrong with your changes, you will get friendly feedback from other developers. You can then make more changes and commit them to the same branch and your pull request will automatically get updated.

    The pull request is easy to create using the GitHub web interface:

      @@ -214,7 +232,7 @@

    -Merging from upstream

    +Merging from upstream

    Once your pull request, or any pull request by anyone else with a mizer fork, has been merged into the upstream repository, the master branch in your fork is no longer in sync with the upstream master branch. So you will want to merge those upstream changes into our master branch. To do that you can use the “Terminal” pane in RStudio, where you execute the following git commands:

    git fetch upstream
     git checkout master
    @@ -240,11 +258,11 @@ 

    -People with a mizer fork

    -

    Here we information about the people who have made a mizer fork. If your name is not on the list below, please add it, together with a bit of info about your interests. How to make the edit and how to commit it and contribute it back is explained in the section Working with git.

    +People with a mizer fork +

    Here we information about the people who have made a mizer fork. If your name is not on the list below, please add it, together with a bit of info about your interests. How to make the edit and how to commit it and contribute it back is explained in the section Working with git.

      -
    • Gustav Delius Maintainer of the mizer package. Interested in building a mizer community and developing the mizer code to be as user-friendly as possible while at the same time being sufficiently flexible and extendable for new research.

    • -
    • Mariella Canales Interested in a multispecies size-based analysis for the pelagic fish community off Northern Chile.

    • +
    • Gustav Delius Maintainer of the mizer package. Interested in building a mizer community and developing the mizer code to be as user-friendly as possible while at the same time being sufficiently flexible and extendable for new research.

    • +
    • Mariella Canales Interested in a multispecies size-based analysis for the pelagic fish community off Northern Chile.

    @@ -260,13 +278,11 @@

    diff --git a/docs/authors.html b/docs/authors.html index 559bf8a4e..cb84d4b3b 100644 --- a/docs/authors.html +++ b/docs/authors.html @@ -8,6 +8,13 @@ Citation and Authors • mizer + + + + + + + @@ -46,8 +53,7 @@ - - + @@ -63,15 +69,9 @@ - - - - - - -
    • Gustav Delius. Maintainer, author, copyright holder. @@ -222,7 +234,7 @@

      Authors

    - + @@ -231,11 +243,11 @@

    Authors

    @@ -261,8 +273,6 @@

    Authors

    - - diff --git a/docs/favicon-16x16.png b/docs/favicon-16x16.png new file mode 100644 index 000000000..0e51c7528 Binary files /dev/null and b/docs/favicon-16x16.png differ diff --git a/docs/favicon-32x32.png b/docs/favicon-32x32.png new file mode 100644 index 000000000..6232fedbc Binary files /dev/null and b/docs/favicon-32x32.png differ diff --git a/docs/favicon.ico b/docs/favicon.ico new file mode 100644 index 000000000..bb201d100 Binary files /dev/null and b/docs/favicon.ico differ diff --git a/docs/index.html b/docs/index.html index 7d9c1e286..1d8e59900 100644 --- a/docs/index.html +++ b/docs/index.html @@ -6,6 +6,12 @@ Multi-Species sIZE Spectrum Modelling in R • mizer + + + + + + @@ -17,14 +23,13 @@ + - -
    -
    - +

    +

    CRAN Status CRAN Downloads CRAN Downloads Coverage status

    Mizer is an R package to run dynamic multi-species size-spectrum models of fish communities. The package has been developed to model marine ecosystems that are subject to fishing. However, it may also be appropriate for other ecosystems.

    The package contains routines and functions to allow users to set up an ecosystem model, and then project it through time under different fishing strategies. Methods are included to explore the results, including plots and calculation of community indicators such as the slope of the size spectrum. Size-based models can be complicated so mizer contains many default options that can be easily changed by the user.

    @@ -143,36 +160,36 @@

    Mizer has been supporting research in marine ecology and fisheries science since 2014 (see publications). Mizer is still under active development. Version 2.0 has increased the user-friendliness and the flexibility of the framework. Contributions from the user community are very welcome. There is a sister package called mizerExperimental where user contributions can be checked out and receive feedback from the community. Example mizer models can be contributed to mizerExamples.

    -

    Does your project or publication use mizer? If so, we would love to know. You can also join our Google Discussion group here: https://groups.google.com/forum/#!forum/size-spectrum-models

    -

    Recent work on mizer was funded by the European Commission Horizon 2020 Research and Innovation Programme under Grant Agreement No 634495 for the project MINOUW (http://minouw-project.eu/) and the Australian Research Council Discovery Project Rewiring Marine Food Webs.

    +

    Does your project or publication use mizer? If so, we would love to know. You can also join our Google Discussion group here: https://groups.google.com/forum/#!forum/size-spectrum-models

    +

    Recent work on mizer was funded by the European Commission Horizon 2020 Research and Innovation Programme under Grant Agreement No 634495 for the project MINOUW (http://minouw-project.eu/) and the Australian Research Council Discovery Project Rewiring Marine Food Webs.

    -Installation

    -

    The package is on CRAN and therefore available from R’s built-in package manager.

    +Installation +

    The package is on CRAN and therefore available from R’s built-in package manager.

     # Install release version from CRAN
    -install.packages("mizer")
    +install.packages("mizer")
     
     # Alternatively, install development version from GitHub
    -devtools::install_github("sizespectrum/mizer")
    +devtools::install_github("sizespectrum/mizer")

    -Example

    +Example

    The following code loads the mizer package, loads some information about species in the North Sea that comes as an example with the package, sets up the parameters for the mizer model, and runs a simulation for 10 years.

    -library(mizer)
    +library(mizer)
     params <- newMultispeciesParams(NS_species_params, inter)
     sim <- project(params, t_max = 10, effort = 0)

    The results of the simulation can then be analysed, for example via plots:

    -plot(sim)
    +plot(sim)

    See the accompanying Get started page for more details on how the package works, including detailed examples.

    -Dynamic multi-species size-spectrum models

    +Dynamic multi-species size-spectrum models

    A mizer model captures the interactions between multiple species. The growth rates of fish are determined by the availability of prey and the death rates are influenced by the abundance of predators, as well as fishing. The model starts with the individual-level physiological rates for each species, as well as the predation preferences, and deduces the population-level dynamics from these. Thus quantities like fish diets and fisheries yields emerge dynamically and can be projected into the future.

    Because a mizer model tracks the size of individuals as they grow up over several orders of magnitude from their egg size to their maximum size, it correctly tracks the ontogenetic diet shifts. An individual typically moves through several trophic levels during its life time. This is often not correctly captured in other multi-species models.

    A mizer model can be set up with only a small amount of information because it uses allometric scaling relations and size-based feeding rules to choose sensible defaults for unknown parameters.

    @@ -180,12 +197,12 @@

    -Modelling environmental change

    +Modelling environmental change

    A mizer model is a good tool for studying the effect of environmental changes, like climate change, because it is a mechanistic model that can deduce the complex population-level changes that one is interested in from the simpler changes in the physiological rates and feeding interactions of individual fish species.

    -Smooth traffic on the biomass highway

    +Smooth traffic on the biomass highway

    It is interesting to think of the marine ecosystem as a transport system that moves biomass from the size of primary producers (mostly unicellular plankton) up to the sizes of fish that humans like to consume. Each fish that grows up from egg size to maturity by eating smaller individuals is like a car on this biomass highway. The yield of our fisheries depend on this traffic flowing smoothly and without traffic jams.

    An analogy with road traffic may be helpful:

    In road traffic, if traffic density gets too high in a section of the highway, drivers slow down, which leads to a pile-up producing even higher traffic density, leading to further slow-down in a potentially vicious cycle known as a traffic jam. Traffic management that ignores how the traffic density affects traffic speed fails. Luckily our mathematical understanding of transport equations has made practical contributions to managing traffic in ways that produce smoother traffic flow and hence higher throughput.

    @@ -194,15 +211,15 @@

    -A model one can understand

    +A model one can understand

    One big advantage of a mizer model is that it is based on a strong mathematical foundation. This allows a degree of a priori understanding of the behaviour of the model that is absent in many other multi-species model. This theoretical foundation is well presented in the book “Fish Ecology, Evolution, and Exploitation” by Ken Andersen.

    -
    +

    -mizer 2.1.0 2021-03-21

    -
    +mizer 2.1.0 2021-03-21 + +

    -New functionality

    -
    • New function projectToSteady() to run the full dynamics to steady state.
    • +New functionality +
        +
      • New function projectToSteady() to run the full dynamics to steady state.
      • New functions distanceSSLogN() and distanceMaxRelRDI() to measure distance between two states.
      • New function compareParams() to compare two MizerParams objects.
      • Added constantEggRDI() to allow keeping egg densities fixed.
      • @@ -239,24 +310,30 @@

      • New function customFunction() to allow users to overwrite mizer functions.
      • Now if the effort is specified as a named vector giving values only for some gears, the effort for the remaining gears is assumed to be zero.
      • Added the possibility to see the output of plotGrowthCurves as a panel of species with their respective Von Bertalanffy curves
      • -

    + +

    -Breaking changes

    -
    • By default, the functions plotPredMort() and plotFMort will stop displaying mortality values past the species’ asymptotic size. The argument
      all.sizes allows you to continue to show these values.
    • -
    -
    +Breaking changes +
      +
    • By default, the functions plotPredMort() and plotFMort will stop displaying mortality values past the species’ asymptotic size. The argument
      all.sizes allows you to continue to show these values.
    • +
    +
    +

    -Bug fixes

    -
    • +Bug fixes +
        +
      • getFMort() now passes time argument correctly. #181
      • validEffortArray() now sets the dimnames correctly. #173
      • -
    + +

    -Code improvements

    -
    • Using lifecycle package to indicate status of some functions and arguments as ‘experimental’ or ‘deprecated’.
    • +Code improvements +
        +
      • Using lifecycle package to indicate status of some functions and arguments as ‘experimental’ or ‘deprecated’.
      • Improved error handling in setFishing(). #172
      • Made use of vdiffr conditional, as required by §1.1.3.1 of ‘Writing R Extensions’.
      • Consistent handling of species argument in mizer functions, via the new valid_species_arg() function. #170
      • @@ -266,22 +343,27 @@

      • Throwing error if min_w_pp is larger than min_w
      • Improved documentation of functions for getting fishing mortality.
      • -

    + +

    -mizer 2.0.4 2020-08-30

    -
    +mizer 2.0.4 2020-08-30 + +

    -Bug fixes

    -
    • The value of t passed to dynamics functions has been corrected.
    • +Bug fixes +
        +
      • The value of t passed to dynamics functions has been corrected.
      • setReproduction() now correctly sets the the total proportion psi when the maturity proportion is changed.
      • -
    + +

    -Enhancements

    -
    • The way times are set in project() has been simplified. They are now either set by the arguments t_start, t_max and t_save or by the dimension names of the effort array.
    • +Enhancements +
        +
      • The way times are set in project() has been simplified. They are now either set by the arguments t_start, t_max and t_save or by the dimension names of the effort array.
      • Renamed setRmax() to setBevertonHolt() and allow it to work on an arbitrary MizerParams object. The old name setRmax() is still available as alias.
      • mizerFMort() now can also use the abundances and the rates e_growth and pred_mort. This is useful for example for implementing balanced harvesting.
      • @@ -307,35 +389,43 @@

        steady() with return_sim = TRUE now creates the MizerSim object the same way as project(), namely with the original values in the first time slot.
      • Added documentation for species_params(), gear_params() and resource_params().
      • Numerous small improvements to documentation.
      • -

    + +

    -mizer 2.0.3 2020-07-28

    -
    +mizer 2.0.3 2020-07-28 + +

    -Bug fixes

    -
    • Correct handling of shiny progress bar in project().
    • -
    +Bug fixes +
      +
    • Correct handling of shiny progress bar in project().
    • +
    +

    -Enhancements

    -
    • Consistently passing the time argument to the rate functions. This will allow extensions to implement time-dependent rates.
    • +Enhancements +
        +
      • Consistently passing the time argument to the rate functions. This will allow extensions to implement time-dependent rates.
      • Passing growth and mortality rate to RDI function.
      • Simplified the getRates() functions by removing the arguments that passed in other rates. Instead the required rates are now always calculated within these functions.
      • Improved documentation of rate functions and of how to register your own rate functions.
      • In validGearParams() handle NAs more gracefully and check that there are no duplicates.
      • Updated hake-mullet selectivity demonstration shiny app.
      • Improved user documentation in several places.
      • -
    + +

    -mizer 2.0.2 2020-06-08

    -
    +mizer 2.0.2 2020-06-08 + +

    -Bug fixes

    -
    • Time passed to rate functions is now the actual simulation time, not the time elapsed since start of simulation.
    • +Bug fixes +
        +
      • Time passed to rate functions is now the actual simulation time, not the time elapsed since start of simulation.
      • upgradeParams() works also on params objects that were created with a development version of mizer.
      • When upgrading an older params object, upgradeParams() does a better job at guessing the value for w_pp_cutoff.
      • @@ -343,16 +433,20 @@

        getFeedingLevel(), getPredMort(), setInitialValues() and steady() now work also when model has extra components.
      • The critical feeding level lines are now mentioned in the legend of plotFeedinglevel() when called with include_critical = TRUE, see #162.
      • Avoid annoying warnings from dplyr package when species_params is a tibble.
      • -

    + +

    -Name changes

    -
    +Name changes + +

    -Minor enhancements

    -
    • Some improvements to documentation.
    • +Minor enhancements +
        +
      • Some improvements to documentation.
      • More unit tests.
      • Uses less memory when time step is very small by not creating array with effort values at each time step.
      • @@ -365,28 +459,33 @@

      • steady() runs faster by using project_simple().
      • Documentation on mizer website now has a search bar.
      • -

    + +

    -mizer 2.0.1 2020-05-05

    -
    +mizer 2.0.1 2020-05-05 + +

    -Bug fixes

    -
    + +

    -Name changes

    +Name changes

    Some inconsistencies in the choice of names for parameters was removed by renaming

    -
    • +
        +
      • interaction_p -> interaction_resource
      • @@ -395,24 +494,29 @@

      • K_resource -> resource_capacity
      • -

    + +

    -Minor enhancements

    -
    • New functions other_params()<- and other_params() for setting and getting other parameters, for example to be used in user-defined rate functions.
    • +Minor enhancements +
        +
      • New functions other_params()<- and other_params() for setting and getting other parameters, for example to be used in user-defined rate functions.
      • setInitialValues() also sets initial_effort. #157
      • -
    + +

    -mizer 2.0.0 2020-04-04

    +mizer 2.0.0 2020-04-04 +

    This is a major new release with many new features, an internal refactoring of the code and a new extension mechanism.

    -Backwards compatibility

    +Backwards compatibility

    Nevertheless this version of mizer is almost fully backwards compatible with version 1.0 with the exception of bug fixes and the following breaking changes:

    -
    • The previous version of mizer inconsistently truncated the lognormal predation kernel when calculating predation but not when calculating encounter. The new version never truncates. That leads to very small differences in simulation results.
    • +
        +
      • The previous version of mizer inconsistently truncated the lognormal predation kernel when calculating predation but not when calculating encounter. The new version never truncates. That leads to very small differences in simulation results.
      • Removed the print_it argument from plot functions.
      • plotFeedingLevel() now only plots the values within the size range of each species. If for some reason you want the old plots that show a feeding level also for sizes that the fish can never have, you need to supply an argument all.sizes = TRUE.
      • @@ -422,21 +526,25 @@

      • The functions display_frames(), addSpecies(), setBackground() and retuneAbundance() have been removed to the “mizerExperimental” package (https://sizespectrum.org/mizerExperimental/)
      • During runs of project() a progress bar is displayed by default. You can turn this off with the option `progress_bar = FALSE.
      • Throughout mizer the term “plankton” has been replaced by “resource”, which affects the labelling of the resource spectrum in plots.
      • -

    + +

    -Setting up models

    +Setting up models

    The new functions

    - +

    replace the old functions set_community_model(), set_trait_model() and MizerParams(), which are now deprecated. The new functions choose better default values, in particular for metabolic rate and maximum intake rate.

    -Setting model parameters

    +Setting model parameters

    After setting up a mizer model, it is possible to change specific model parameters with the new functions

    - +

    The new function setParams() is a wrapper for all of the above functions and is also used when setting up a new model with newMultispeciesParams(). (#51)

    The documentation for these functions serves to explain the details of the mizer model.

    Along with these setter functions there are accessor functions for getting the parameter arrays: getPredKernel(), getSearchVolume(), getInteraction(), getMaxIntakeRate(), getMetabolicRate(), getExtMort(), getMaturityProportion(), getReproductionProportion(), getCatchability(), getSelectivity(), getResourceRate(), getResourceCapacity(), getResourceParams(), getResourceDynamics(),

    -
    • Setting of the maximum reproduction rate has been separated out into new function setRmax().
    • -
    +
      +
    • Setting of the maximum reproduction rate has been separated out into new function setRmax().
    • +
    +

    -Initial Values and steady state

    -

    The MizerParams object now also contains the initial values for the size spectra. This is particularly useful if the model has been tuned to produce the observed steady state. The new function steady() finds a steady state for a model and sets it as the initial value. The initial values can be accessed and changed via functions initialN() and initialNResource(). The initial values can be set to the final values of a previous simulation with setInitialValues().

    +Initial Values and steady state +

    The MizerParams object now also contains the initial values for the size spectra. This is particularly useful if the model has been tuned to produce the observed steady state. The new function steady() finds a steady state for a model and sets it as the initial value. The initial values can be accessed and changed via functions initialN() and initialNResource(). The initial values can be set to the final values of a previous simulation with setInitialValues().

    The MizerParams object now has a slot initial_effort that specifies the initial fishing effort to which the steady state has been calibrated.

    -Extension mechanisms

    +Extension mechanisms

    Mizer now has an extension mechanism that allows other R packages to be written to generalise the mizer model. See setRateFunction() and setComponent(). This mechanism is still experimental and may change as we gain experience in writing extensions for mizer.

    -Plotting

    -
    • Every plot function now has a plotly version that makes the plot interactive using the plotly package. So for example there is plotlyBiomass() as the plotly version of plotBiomass(), and so on.
    • +Plotting +
        +
      • Every plot function now has a plotly version that makes the plot interactive using the plotly package. So for example there is plotlyBiomass() as the plotly version of plotBiomass(), and so on.
      • New plotGrowthCurves() plots growth curves and compares them to the von Bertalanffy growth curve.
      • New plotDiet() plots the diet composition as a function of predator size.
      • New highlight argument to all plot functions that display curves for multiple species. Displays highlighted species with wider lines.
      • In the legends of all plots the species are now consistently ordered in the same way as in the species parameter data frame.
      • All plot functions that are not time-resolved now accept also a MizerParams object as an alternative to the MizerSim object to plot the initial state.
      • -
      • New plot() method for MizerParams object to plot the initial state.
      • +
      • New plot() method for MizerParams object to plot the initial state.
      • Avoiding duplicate graphs in R Markdown documents.
      • New argument include_critical in plotFeedingLevel() allows to show also the critical feeding level.
      • New wlim argument to plotSpectra() in analogy to the existing ylim argument to limit the w range in the plot.
      • The colours used in plot functions can be set with setColours().
      • The default line type is solid but this can be changed via the setLinetypes() function.
      • Use colour and linetype for plots irrespective of the number of species.
      • -
    + +

    -General predation kernel

    -
    • Users can now replace the lognormal function in the predation kernel by a function of their choice, allowing a differently shaped kernel for each species.
    • +General predation kernel +
        +
      • Users can now replace the lognormal function in the predation kernel by a function of their choice, allowing a differently shaped kernel for each species.
      • New box_pred_kernel() implements a box-shaped kernel as an alternative to the default lognormal_pred_kernel().
      • New power_law_pred_kernel() implements a power-law kernel with sigmoidal cutoffs at both ends. This is suitable for filter feeders.
      • Users can sets a predation kernel that has a predator-size-dependent predator/prey mass ration (via setPredKernel()). Mizer automatically falls back on the old non-FFT code to handle this. (#41)
      • New getPredKernel() returns the full 3-dimensional predation kernel array, even when this is not stored in MizerParams object.
      • -
    + +

    -New gear setup

    +New gear setup

    Now it is finally possible to have several gears (or fleets) targeting the same species. The information is set up via a new gear_params() data frame. See setFishing() for details.

    -Other new functions

    -
    • There are now accessor functions for all slots in the MizerParams and MizerSim objects. For example to get at the size grid and its spacing you would now use w(), w_full(), dw(), dw_full().
    • +Other new functions +
        +
      • There are now accessor functions for all slots in the MizerParams and MizerSim objects. For example to get at the size grid and its spacing you would now use w(), w_full(), dw(), dw_full().
      • New upgradeParams() and upgradeSim() can upgrade objects from previous versions of mizer so they work with the new version.
      • New getDiet() calculates the diet of predators. (#43)
      • Alternative functions RickerRDD() and SheperdRDD() for density-dependence in reproduction, as well as noRDD() and constantRDD().
      • @@ -509,14 +625,16 @@

      • A convenience function times() to extract the times at which simulation results are saved in a MizerSim object.
      • Convenience functions finalN(), finalNResource() and finalNOther() as well as idxFinalT() to access the values at the final time of a simulation.
      • New function getCriticalFeedingLevel() returns the critical feeding level for each species at each size.
      • -
      • Mizer reexports the melt() function from the reshape2 package which allows users to convert the arrays returned by mizer functions into data frames that can be used for example in ggplot2 and plotly.
      • +
      • Mizer reexports the melt() function from the reshape2 package which allows users to convert the arrays returned by mizer functions into data frames that can be used for example in ggplot2 and plotly.
      • validSpeciesParams() checks validity of species parameter data frame and sets defaults for missing but required parameters.
      • -

    + +

    -Other new features

    -
    • The allometric exponents n, p and q as well as the feeding level f0 can now be set at the species level via columns in species_params.
    • +Other new features +
        +
      • The allometric exponents n, p and q as well as the feeding level f0 can now be set at the species level via columns in species_params.
      • The critical feeding level fc can now be specified as a species parameter and will be used to calculate the metabolic rate parameter ks if it is not supplied.
      • project() now shows a progress bar while a simulation is running. Can be turned off with progress_bar = FALSE argument.
      • @@ -535,11 +653,13 @@

      • Added a data fileNS_params with the North Sea model MizerParams object.
      • Comments can be added to MizerParams objects and any of their slots. Slots that have comments are protected from being overwritten with allometric defaults.
      • Gear selectivity functions now can use the species parameters.
      • -

    + +

    -Documentation

    -
    -
    + +
    +

    -Bug fixes

    -
    • In getSSB(), the calculation of the spawning stock biomass is done correctly using the maturity ogive instead of the proportion of energy allocated to reproduction. (#47)
    • +Bug fixes +
        +
      • In getSSB(), the calculation of the spawning stock biomass is done correctly using the maturity ogive instead of the proportion of energy allocated to reproduction. (#47)
      • The fast FFT method and the old method for calculating integrals now give the same numerical results. (#39)
      • getEncounter() and getPredRate() now set names on the returned arrays.
      • @@ -593,12 +717,14 @@

      • get_initial_n() gets values for n and q from params object
      • -summary() of MizerParams object reflects the number of non-empty resource bins. (@patricksykes)
      • -

    +summary() of MizerParams object reflects the number of non-empty resource bins. (@patricksykes) + +

    -Under the hood

    -
    • Now using vdiffr package to test plots.
    • +Under the hood +
        +
      • Now using vdiffr package to test plots.
      • Converted all S4 methods to functions to decrease the learning curve for new developers.
      • The calculation of defaults is now handled by new get_gamma_default(), get_h_default() and get_ks_default(), making it easier to change or extend these in the future.
      • Helper function set_species_param_default() makes it easier to set default values for species parameters.
      • @@ -615,13 +741,14 @@

      • Using assert_that to check arguments to functions more often.
      • Argument shiny_progress renamed to progress_bar because they control any type of progress bar.
      • In documentation renamed “background” and “plankton” consistently to “resource”.
      • -
      • Using outer() instead of tapply() where possible to improve readability.
      • -
      • Avoiding use of hasArg() and anyNA() because they were not available in R 3.1
      • +
      • Using outer() instead of tapply() where possible to improve readability.
      • +
      • Avoiding use of hasArg() and anyNA() because they were not available in R 3.1
      • A more robust code for setting up the size grids.
      • Improved consistency of when to issue warnings and when to issue messages.
      • Split large code files into smaller files.
      • Changes to MizerParams class: -
        • Merged @std_metab and @activity slots into a single @metab slot.
        • +
            +
          • Merged @std_metab and @activity slots into a single @metab slot.
          • Moved @w_min_idx out of @species_params into its own slot.
          • Added slot @maturity to hold the maturity ogive.
          • Added slot @pred_kernel to hold predation kernel if it has variable predator/prey ratio.
          • @@ -631,63 +758,85 @@

          • Added slot @rates_funcs to allow mizer extensions to replace mizer rate functions with their own rate functions.
          • Instead of the function in the slot @srr we now have the name of the function in @rate_funcs$RDD, see #91.
          • Added slots @other_dynamics, @other_params, @other_encounter, @other_mort and @initial_n_other to allow mizer extensions to add more ecosystem components.
          • -

          -
    + + + +

    -mizer 1.0.1 2019-01-27

    -
    • Now compatible with older versions of R > 3.1.0.
    • +mizer 1.0.1 2019-01-27 + +
        +
      • Now compatible with older versions of R > 3.1.0.
      • Skipping a test on CRAN that fails on some machines with different precision.
      • Fixing minor typos in documentation.
      • -
    + +

    -mizer 1.0 2018-05-01

    -
    • Fixed bugs in how the start time of a simulation was handled. This leads to small corrections, so that the output of this version is slightly different from previous versions.
    • +mizer 1.0 2018-05-01 + +
        +
      • Fixed bugs in how the start time of a simulation was handled. This leads to small corrections, so that the output of this version is slightly different from previous versions.
      • Introduced a scale-invariant trait-based model, set up with set_scaling_model(), see section 12 in the vignette.
      • Added a function that adds news species to a scale-invariant background, and computes an approximately steady state close to the power law, see section 13 in the vignette.
      • Created an example shiny app to allow people to use mizer through a web browser without having to install mizer. The app explores the effect of more selective fishing gear in a case study.
      • Improvements to plots: -
        • Added units to axes
        • +
            +
          • Added units to axes
          • Added function for plotting growth curves
          • PlotYield() no longer fails when species names are numbers or when a species abundance is zero
          • Added a total parameter to several plot functions to add the curve for the total community (sum over all species and resource)
          • Added a species parameter to all plot functions to allow for only a selection of species to be plotted
          • Allow the number of ticks on y-axis in biomass plot to be controlled
          • -
          +
        +
      • Allow for size- and species-dependent background death.
      • Add @initial_n and @initial_n_pp slots to MizerParams class.
      • Now checking that effort times are increasing.
      • Corrections in the documentation.
      • Improvements to the vignette.
      • Add a test of the numeric solution against an analytic solution.
      • -
    + +

    -mizer 0.4 2017-12-14

    -
    • Improvements made to the speed by evaluating convolution sums via fft, removing the bottlenecks in getPhiPrey() and getPredRate().
    • +mizer 0.4 2017-12-14 + +
        +
      • Improvements made to the speed by evaluating convolution sums via fft, removing the bottlenecks in getPhiPrey() and getPredRate().
      • Using C++ for the inner loop in the project method for extra speed.
      • Minor corrections to vignette and documentation to bring them into alignment and to document the new home on GitHub and new maintainers.
      • -
    + +

    -mizer 0.3 Unreleased

    -
    • Improvements made to the speed of the simulations. Remaining bottle necks are the sweep statements in getPhiPrey() and getPredRate().
    • +mizer 0.3 Unreleased + +
        +
      • Improvements made to the speed of the simulations. Remaining bottle necks are the sweep statements in getPhiPrey() and getPredRate().
      • Moved tests to new suggested folder.
      • Minor changes to documentation to pass new check requirements.
      • -
    + +

    -mizer 0.2 2014-04-16

    -
    • Release to coincide with the submission of the MEE paper. No major changes. Just minor bug fixes.
    • -
    +mizer 0.2 2014-04-16 + +
      +
    • Release to coincide with the submission of the MEE paper. No major changes. Just minor bug fixes.
    • +
    +

    -mizer 0.1 2013-10-08

    -
    • Beta release - just about works but still some gremlins to sort out. There are a number of features I’d like to add in the coming releases.
    • -
    +mizer 0.1 2013-10-08 + +
      +
    • Beta release - just about works but still some gremlins to sort out. There are a number of features I’d like to add in the coming releases.
    • +
    + + + + + + + + + + + + + + + + + + diff --git a/docs/reference/getResourceMort.html b/docs/reference/getResourceMort.html index 79df0a872..76f278be8 100644 --- a/docs/reference/getResourceMort.html +++ b/docs/reference/getResourceMort.html @@ -8,6 +8,13 @@ Get predation mortality rate for resource — getResourceMort • mizer + + + + + + + @@ -48,8 +55,7 @@ - - + @@ -65,15 +71,9 @@ - - - - - - -
    getResourceMort(
    +    
    getResourceMort(
       params,
    -  n = initialN(params),
    -  n_pp = initialNResource(params),
    -  n_other = initialNOther(params),
    +  n = initialN(params),
    +  n_pp = initialNResource(params),
    +  n_other = initialNOther(params),
       t = 0,
       ...
    -)
    +)

    Arguments

    @@ -243,8 +256,8 @@

    then you register it in a MizerParams -object params with

    params <- setRateFunction(params, "ResourceMort", "myResourceMort")
    -
    +object params with

    params <- setRateFunction(params, "ResourceMort", "myResourceMort")
    +

    Your function will then be called instead of mizerResourceMort(), with the same arguments.

    @@ -266,14 +279,14 @@

    See a getRates()

    Examples

    -
    if (FALSE) {
    +    
    if (FALSE) {
     params <- newMultispeciesParams(NS_species_params_gears, inter)
     # With constant fishing effort for all gears for 20 time steps
     sim <- project(params, t_max = 20, effort = 0.5)
     # Get resource mortality at one time step
     getResourceMort(params, n = N(sim)[15, , ], n_pp = NResource(sim)[15, ])
     }
    -
    +
    @@ -219,13 +232,13 @@

    See a getYield()

    Examples

    -
    if (FALSE) {
    -params <- newMultispeciesParams(NS_species_params_gears, inter)
    -# With constant fishing effort for all gears for 20 time steps
    -sim <- project(params, t_max = 20, effort = 0.5)
    -getSSB(sim)
    -}
    -
    +
    ssb <- getSSB(NS_sim)
    +ssb[c("1972", "2010"), c("Herring", "Cod")]
    +#>       sp
    +#> time        Herring          Cod
    +#>   1972  44290356621 375924484131
    +#>   2010 172765918920 347442607081
    +
    @@ -206,6 +219,12 @@

    Value

    A numeric vectors of the times (in years) at which simulation results have been stored in the MizerSim object.

    +

    Examples

    +
    getTimes(NS_sim)
    +#>  [1] 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981
    +#> [16] 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996
    +#> [31] 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010
    +
    @@ -219,12 +232,13 @@

    See a getYieldGear()

    Examples

    -
    if (FALSE) {
    -params <- newMultispeciesParams(NS_species_params_gears, inter)
    -sim <- project(params, effort=1, t_max=10)
    -y <- getYield(sim)
    -}
    -
    +
    yield <- getYield(NS_sim)
    +yield[c("1972", "2010"), c("Herring", "Cod")]
    +#>       sp
    +#> time       Herring          Cod
    +#>   1972 80002050975 355351719122
    +#>   2010 30496241734 289022888045
    +
    @@ -219,13 +232,11 @@

    See a getYield()

    Examples

    -
    if (FALSE) {
    -params <- newMultispeciesParams(NS_species_params_gears, inter)
    -# With constant fishing effort for all gears for 20 time steps
    -sim <- project(params, t_max = 20, effort = 0.5)
    -getYieldGear(sim)
    -}
    -
    +
    yield <- getYieldGear(NS_sim)
    +yield["1972", "Herring", "Herring"]
    +#> [1] 80002050975
    +# (In this example MizerSim object each species was set up with its own gear)
    +
    @@ -255,8 +268,8 @@

    then you register it in a MizerParams -object params with

    params <- setRateFunction(params, "Mort", "myMort")
    -
    +object params with

    params <- setRateFunction(params, "Mort", "myMort")
    +

    Your function will then be called instead of mizerMort(), with the same arguments.

    @@ -279,7 +292,7 @@

    See a getResourceMort()

    Examples

    -
    if (FALSE) {
    +    
    if (FALSE) {
     params <- newMultispeciesParams(NS_species_params_gears, inter)
     # Project with constant fishing effort for all gears for 20 time steps
     sim <- project(params, t_max = 20, effort = 0.5)
    @@ -287,7 +300,7 @@ 

    Examp getMort(params, n = N(sim)[15, , ], n_pp = NResource(sim)[15, ], t = 15, effort = 0.5) } -

    +
    @@ -235,11 +248,11 @@

    Contents

    @@ -265,8 +278,6 @@

    Contents

    - - diff --git a/docs/reference/get_gamma_default.html b/docs/reference/get_gamma_default.html index 6d359141f..020ad6880 100644 --- a/docs/reference/get_gamma_default.html +++ b/docs/reference/get_gamma_default.html @@ -8,6 +8,13 @@ Get default value for gamma — get_gamma_default • mizer + + + + + + + @@ -49,8 +56,7 @@ - - + @@ -66,15 +72,9 @@ - - - - - - -
    get_gamma_default(params)
    +
    get_gamma_default(params)

    Arguments

    @@ -226,11 +239,11 @@

    Contents

    @@ -256,8 +269,6 @@

    Contents

    - - diff --git a/docs/reference/get_h_default.html b/docs/reference/get_h_default.html index 7f9978d77..7288e80bf 100644 --- a/docs/reference/get_h_default.html +++ b/docs/reference/get_h_default.html @@ -8,6 +8,13 @@ Get default value for h — get_h_default • mizer + + + + + + + @@ -52,8 +59,7 @@ data frame. Also needs the exponent b from the length-weight relationship \(w = a l^b\). If this is not present in the species parameter data frame it is set to b = 3." /> - - + @@ -69,15 +75,9 @@ - - - - - - -
    get_h_default(params)
    +
    get_h_default(params)

    Arguments

    @@ -232,11 +245,11 @@

    Contents

    @@ -262,8 +275,6 @@

    Contents

    - - diff --git a/docs/reference/get_initial_n.html b/docs/reference/get_initial_n.html index a5fa5684f..c6bf3e48b 100644 --- a/docs/reference/get_initial_n.html +++ b/docs/reference/get_initial_n.html @@ -8,6 +8,13 @@ Calculate initial population abundances for the community populations — get_initial_n • mizer + + + + + + + @@ -50,8 +57,7 @@ initial population abundances for the community populations. These initial abundances should be reasonable guesses at the equilibrium values. The returned population can be passed to the project function." /> - - + @@ -67,15 +73,9 @@ - - - - - - -
    get_initial_n(params, n0_mult = NULL, a = 0.35)
    +
    get_initial_n(params, n0_mult = NULL, a = 0.35)

    Arguments

    @@ -221,11 +234,11 @@

    Value

    A matrix (species x size) of population abundances.

    Examples

    -
    if (FALSE) {
    +    
    if (FALSE) {
     params <- newMultispeciesParams(NS_species_params_gears)
     init_n <- get_initial_n(params)
     }
    -
    +
    @@ -228,11 +241,11 @@

    Contents

    @@ -258,8 +271,6 @@

    Contents

    - - diff --git a/docs/reference/get_phi.html b/docs/reference/get_phi.html index c56254a5e..667224844 100644 --- a/docs/reference/get_phi.html +++ b/docs/reference/get_phi.html @@ -8,6 +8,13 @@ Get values from feeding kernel function — get_phi • mizer + + + + + + + @@ -50,8 +57,7 @@ pred_kernel_type parameter in the species_params data frame, checking that it is valid and all its arguments are contained in the species_params data frame, and then calling this function with the ppmr vector." /> - - + @@ -67,15 +73,9 @@ - - - - - - -
    get_phi(species_params, ppmr)
    +
    get_phi(species_params, ppmr)

    Arguments

    @@ -228,11 +241,11 @@

    Contents

    @@ -258,8 +271,6 @@

    Contents

    - - diff --git a/docs/reference/get_required_reproduction.html b/docs/reference/get_required_reproduction.html index 55f470434..c863dbbf4 100644 --- a/docs/reference/get_required_reproduction.html +++ b/docs/reference/get_required_reproduction.html @@ -8,6 +8,13 @@ Determine reproduction rate needed for initial egg abundance — get_required_reproduction • mizer + + + + + + + @@ -47,8 +54,7 @@ - - + @@ -64,15 +70,9 @@ - - - - - - -
    get_required_reproduction(params)
    +
    get_required_reproduction(params)

    Arguments

    @@ -216,11 +229,11 @@

    Contents

    @@ -246,8 +259,6 @@

    Contents

    - - diff --git a/docs/reference/get_size_range_array.html b/docs/reference/get_size_range_array.html index 1fc498b59..8ac1f2b87 100644 --- a/docs/reference/get_size_range_array.html +++ b/docs/reference/get_size_range_array.html @@ -8,6 +8,13 @@ Get size range array — get_size_range_array • mizer + + + + + + + @@ -49,8 +56,7 @@ - - + @@ -66,15 +72,9 @@ - - - - - - -
    get_size_range_array(
    +    
    get_size_range_array(
       params,
       min_w = min(params@w),
       max_w = max(params@w),
       min_l = NULL,
       max_l = NULL,
       ...
    -)
    +)

    Arguments

    @@ -264,11 +277,11 @@

    Contents

    @@ -294,8 +307,6 @@

    Contents

    - - diff --git a/docs/reference/get_time_elements.html b/docs/reference/get_time_elements.html index 1fb7d18d0..59f01efd6 100644 --- a/docs/reference/get_time_elements.html +++ b/docs/reference/get_time_elements.html @@ -8,6 +8,13 @@ Get_time_elements — get_time_elements • mizer + + + + + + + @@ -48,8 +55,7 @@ - - + @@ -65,15 +71,9 @@ - - - - - - -
    get_time_elements(sim, time_range, slot_name = "n")
    +
    get_time_elements(sim, time_range, slot_name = "n")

    Arguments

    @@ -230,11 +243,11 @@

    Contents

    @@ -260,8 +273,6 @@

    Contents

    - - diff --git a/docs/reference/idxFinalT.html b/docs/reference/idxFinalT.html index 14288d8f8..c5039c113 100644 --- a/docs/reference/idxFinalT.html +++ b/docs/reference/idxFinalT.html @@ -8,6 +8,13 @@ Time index at end of simulation — idxFinalT • mizer + + + + + + + @@ -47,8 +54,7 @@ - - + @@ -64,15 +70,9 @@ - - - - - - -
    idxFinalT(sim)
    +
    idxFinalT(sim)

    Arguments

    @@ -207,19 +220,21 @@

    Value

    results for the final time step

    Examples

    -
    if (FALSE) {
    -sim <- project(NS_params, t_max = 12, t_save = 0.5)
    -idx <- idxFinalT(sim)
    +    
    idx <- idxFinalT(NS_sim)
     idx
    +#> [1] 44
     # This coincides with
    -length(getTimes(sim))
    +length(getTimes(NS_sim))
    +#> [1] 44
     # and corresponds to the final time
    -getTimes(sim)[idx]
    +getTimes(NS_sim)[idx]
    +#> [1] 2010
     # We can use this index to extract the result at the final time
    -identical(N(sim)[idx, , ], finalN(sim))
    -identical(NResource(sim)[idx, ], finalNResource(sim))
    -}
    -
    +identical(N(NS_sim)[idx, , ], finalN(NS_sim)) +#> [1] TRUE +identical(NResource(NS_sim)[idx, ], finalNResource(NS_sim)) +#> [1] TRUE + + + @@ -1319,6 +1338,12 @@

    inter

    + + + + @@ -1413,11 +1438,11 @@

    Contents

    @@ -1443,8 +1468,6 @@

    Contents

    - - diff --git a/docs/reference/indicator_functions.html b/docs/reference/indicator_functions.html index 163642311..fe55e1bdc 100644 --- a/docs/reference/indicator_functions.html +++ b/docs/reference/indicator_functions.html @@ -8,6 +8,13 @@ Description of indicator functions — indicator_functions • mizer + + + + + + + @@ -48,8 +55,7 @@ - - + @@ -65,15 +71,9 @@ - - - - - -
    @@ -98,11 +98,13 @@
    -
    initialN(params) <- value
    +    
    initialN(params) <- value
     
    -initialN(object)
    +initialN(object)

    Arguments

    Get reproduction level

    RickerRDD()

    Example interaction matrix for the North Sea example

    +

    NS_sim

    +

    Example MizerSim object for the North Sea example

    @@ -213,6 +226,16 @@

    Arg

    +

    Examples

    +
    # Doubling abundance of Cod in the initial state of the North Sea model
    +params <- NS_params
    +initialN(params)["Cod", ] <- 2 * initialN(params)["Cod", ]
    +# Calculating the corresponding initial biomass
    +biomass <- initialN(params)["Cod", ] * dw(NS_params) * w(NS_params)
    +# Of course this initial state will no longer be a steady state
    +params <- steady(params)
    +#> Convergence was achieved in 19.5 years.
    +