-
Notifications
You must be signed in to change notification settings - Fork 0
/
A09_troubleshooting_and_caveats.Rmd
265 lines (231 loc) · 7.46 KB
/
A09_troubleshooting_and_caveats.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
---
title: "09: Troubleshooting / caveats"
author: "Fallert, S. and Cabral, J.S."
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{09: Troubleshooting / caveats}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```
When creating your own simulation, you may encounter issues / errors to which the solution may not be immediately obvious.
Here we will cover a basic strategy on how to debug with the example of a simple typo in one of the species traits.
# Debugging
The following code will result in an error:
```{r typo, eval = FALSE}
library(metaRange)
library(terra)
set_verbosity(0)
raster_file <- system.file("ex/elev.tif", package = "terra")
r <- rast(raster_file)
r <- scale(r, center = FALSE, scale = TRUE)
r <- rep(r, 10)
landscape <- sds(r)
names(landscape) <- c("habitat_quality")
sim <- create_simulation(
source_environment = landscape,
ID = "example_simulation",
seed = 1
)
sim$add_species(name = "species_1")
sim$add_traits(
species = "species_1",
population_level = TRUE,
abundance = 100,
reproduction_rtae = 0.5,
carrying_capacity = 1000
)
sim$add_process(
species = "species_1",
process_name = "reproduction",
process_fun = function() {
ricker_reproduction_model(
self$traits$abundance,
self$traits$reproduction_rate,
self$traits$carrying_capacity * self$sim$environment$current$habitat_quality
)
},
execution_priority = 1
)
sim$begin()
```
```{r typo0_1, echo = FALSE}
library(metaRange)
library(terra)
set_verbosity(0)
raster_file <- system.file("ex/elev.tif", package = "terra")
r <- rast(raster_file)
r <- scale(r, center = FALSE, scale = TRUE)
r <- rep(r, 10)
landscape <- sds(r)
names(landscape) <- c("habitat_quality")
sim <- create_simulation(
source_environment = landscape,
ID = "example_simulation",
seed = 1
)
sim$add_species(name = "species_1")
sim$add_traits(
species = "species_1",
population_level = TRUE,
abundance = 100,
reproduction_rtae = 0.5,
carrying_capacity = 1000
)
sim$add_process(
species = "species_1",
process_name = "reproduction",
process_fun = function() {
ricker_reproduction_model(
self$traits$abundance,
self$traits$reproduction_rate,
self$traits$carrying_capacity * self$sim$environment$current$habitat_quality
)
},
execution_priority = 1
)
cat("Error: Not compatible with requested type: [type=NULL; target=double].")
```
And it may not immediately be obvious what the problem is.
The first step to narrow down the problem is to enable extensive verbosity.
So, if we run the code again, but this time with `set_verbosity(2)`, we get the following output:
```{r typo2_1}
set_verbosity(2)
sim <- create_simulation(
source_environment = landscape,
ID = "example_simulation",
seed = 1
)
sim$add_species(name = "species_1")
sim$add_traits(
species = "species_1",
population_level = TRUE,
abundance = 100,
reproduction_rtae = 0.5,
carrying_capacity = 1000
)
sim$add_process(
species = "species_1",
process_name = "reproduction",
process_fun = function() {
ricker_reproduction_model(
self$traits$abundance,
self$traits$reproduction_rate,
self$traits$carrying_capacity * self$sim$environment$current$habitat_quality
)
},
execution_priority = 1
)
```
The setup look ok so far.
Now we start the simulation.
```{r typo2_2, eval = FALSE}
sim$begin()
```
```{r typo2_3, echo = FALSE}
cat("
Starting simualtion.
passed initial sanity checks.
start of time step: 1
|- species_1 : reproduction
Error: Not compatible with requested type: [type=NULL; target=double].
")
```
We can see that the error occurs in the first time step, in the `reproduction` process of "species_1".
With this information, we can now insert a `browser()` function, which stops the code execution once it is called and lets us inspect the process and the variables of the function / environment it has been called from.
```{r typo3, eval = FALSE}
set_verbosity(2)
sim <- create_simulation(
source_environment = landscape,
ID = "example_simulation",
seed = 1
)
sim$add_species(name = "species_1")
sim$add_traits(
species = "species_1",
population_level = TRUE,
abundance = 100,
reproduction_rtae = 0.5,
carrying_capacity = 1000
)
sim$add_process(
species = "species_1",
process_name = "reproduction",
process_fun = function() {
browser()
ricker_reproduction_model(
self$traits$abundance,
self$traits$reproduction_rate,
self$traits$carrying_capacity * self$sim$environment$current$habitat_quality
)
},
execution_priority = 1
)
sim$begin()
```
In the browser, we are conceptually inside the `reproduction` process of "species_1".
This means we can make use of the `self` keyword to inspect the state of the species.
As a first step, we might want to call `ls()` to see which objects we can inspect.
```{r typo4, eval = FALSE}
# type this in the console,
# once the browser has halted the code execution
ls()
```
```{r typo5, echo = FALSE}
set_verbosity(0)
sim <- create_simulation(
source_environment = landscape,
ID = "example_simulation",
seed = 1
)
sim$add_species(name = "species_1")
sim$add_traits(
species = "species_1",
population_level = TRUE,
abundance = 100,
reproduction_rtae = 0.5,
carrying_capacity = 1000
)
ls(sim$species_1)
```
Since the error was about an wrong type being passed to the reproduction function, we can inspect the `traits` of the species to see if they are as we would expect them to be.
This means we can just type `self$traits` in the console to see them and we may notice that the `reproduction_rate` is misspelled as `reproduction_rtae`.
```{r typo6, eval = FALSE}
# type this in the console,
# once the browser has halted the code execution
self$traits
```
```{r typo7, echo = FALSE}
set_verbosity(0)
sim <- create_simulation(
source_environment = landscape,
ID = "example_simulation",
seed = 1
)
sim$add_species(name = "species_1")
sim$add_traits(
species = "species_1",
population_level = TRUE,
abundance = 100,
reproduction_rtae = 0.5,
carrying_capacity = 1000
)
sim$species_1$traits
```
We can quit the browser by typing `Q` and then `Enter` in the console.
Now we can remove the `browser()` call from the code again and proceed to fix the typo.
# General caveats
While metaRange can be used to simulate a wide range of scenarios, there are some caveats to keep in mind.
1. **Different scales of the environment and the species**
Since the size and resolution of the environment also describes the spatial size of each population (i.e. one grid cell = one population), it is important to choose scales that are appropriate for the species.
This is especially important to keep in mind when simulating multiple species, since they may have different spatial requirements.
2. **Gene flow**
While it is planned for future versions, metaRange does (currently) not support gene flow during dispersal.
3. **Spatial distortion**
Since metaRange uses raster data to represent the environment, it is important to keep in mind that the raster is a 2D representation of a 3D world.
The larger the geographic extent of the environment, the more distorted the raster will be (also depending on the map projection and the resolution).