1
1
# ' Set own rate function to replace mizer rate function
2
2
# '
3
+ # ' If the way mizer calculates a fundamental rate entering the model is
4
+ # ' not flexible enough for you (for example if you need to introduce time
5
+ # ' dependence) then you can write your own functions for calculating that
6
+ # ' rate and use `setRateFunction()` to register it with mizer.
7
+ # '
3
8
# ' At each time step during a simulation with the [project()] function, mizer
4
9
# ' needs to calculate the instantaneous values of the various rates. By
5
10
# ' default it calls the [mizerRates()] function which creates a list with the
17
22
# ' * `rdi` from [mizerRDI()]
18
23
# ' * `rdd` from [BevertonHoltRDD()]
19
24
# '
20
- # ' You can modify these in two ways.
25
+ # ' For each of these you can substitute your own function. So for example if
26
+ # ' you have written your own function for calculating the total mortality
27
+ # ' rate and have called it `myMort` and have a mizer model stored in a
28
+ # ' MizerParams object called `params` that you want to run with your new
29
+ # ' mortality rate, then you would call
30
+ # ' ```
31
+ # ' params <- setRateFunction(params, "Mort", "myMort")
32
+ # ' ```
33
+ # ' In some extreme cases you may need to swap out the entire `mizerRates()`
34
+ # ' function for your own function called `myRates()`. That you can do with
35
+ # ' ```
36
+ # ' params <- setRateFunction(params, "Rates", "myRates")
37
+ # ' ```
21
38
# '
22
- # ' @param params A ` MizerParams` object
39
+ # ' @param params A MizerParams object
23
40
# ' @param rate Name of the rate for which a new function is to be set.
24
41
# ' @param fun Name of the function to use to calculate the rate.
42
+ # ' @return For `setRateFunction()`: An updated MizerParams object
25
43
# ' @export
26
- setRateFunction <- function (params , rate = " Rates " , fun ) {
44
+ setRateFunction <- function (params , rate , fun ) {
27
45
assert_that(is(params , " MizerParams" ),
28
46
is.string(rate ),
29
- is.string(fun ),
30
- is.function(get(fun )))
47
+ is.string(fun ))
31
48
if (! (rate %in% names(params @ rates_funcs ))) {
32
49
stop(" The `rate` argument must be one of " ,
33
50
toString(names(params @ rates_funcs )), " ." )
34
51
}
35
- f <- get0( fun , mode = " function" )
36
- if (is.null( f )) {
37
- stop( fun , " should be a function " )
52
+ if ( ! exists( fun , mode = " function" )) {
53
+ stop( " `fun` should be a function, " ,
54
+ fun , " is of class " , class( fun ), " . " )
38
55
}
39
56
# TODO: put some code to test that the function has the right kind of
40
57
# arguments
@@ -45,12 +62,15 @@ setRateFunction <- function(params, rate = "Rates", fun) {
45
62
}
46
63
47
64
# ' @rdname setRateFunction
65
+ # ' @return For `getRateFunction()`: The name of the registered rate function for
66
+ # ' the requested `rate`, or the list of all rate functions if called without
67
+ # ' `rate` argument.
48
68
# ' @export
49
- getRateFunction <- function (params , rate = " Rates " ) {
69
+ getRateFunction <- function (params , rate ) {
50
70
assert_that(is(params , " MizerParams" ),
51
71
is.string(rate ))
52
72
validObject(params )
53
- if (rate == " All " ) {
73
+ if (missing( rate ) ) {
54
74
return (params @ rates_funcs )
55
75
}
56
76
if (! (rate %in% names(params @ rates_funcs ))) {
@@ -62,58 +82,101 @@ getRateFunction <- function(params, rate = "Rates") {
62
82
63
83
# ' Add a dynamical ecosystem component
64
84
# '
85
+ # ' By default, mizer models any number of size-resolved consumer species
86
+ # ' and a single size-resolved plankton spectrum. Your model may require
87
+ # ' additional components, like for example detritus or carrion or multiple
88
+ # ' resources or .... This function allows you to set up such components.
89
+ # '
90
+ # ' If you set a component with a new name, the new component will be added
91
+ # ' to the existing components. If you set a component with an existing name,
92
+ # ' that component will be overwritten. You can remove a component with
93
+ # ' `removeComponent()`.
94
+ # '
65
95
# ' @param params A MizerParams object
66
96
# ' @param component Name of the component
67
97
# ' @param initial_value Initial value of the component
68
98
# ' @param dynamics_fun Name of function to calculate value at the next time step
69
99
# ' @param encounter_fun Name of function to calculate contribution to encounter
70
- # ' rate
71
- # ' @param pred_mort_fun Name of function to calculate contribution to the
72
- # ' predation mortality rate.
100
+ # ' rate. Optional.
101
+ # ' @param mort_fun Name of function to calculate contribution to the
102
+ # ' mortality rate. Optional .
73
103
# ' @param component_params Named list of parameters needed by the component
74
- # ' functions.
75
- # ' @return For `setComponent`: The updated MizerParams object
104
+ # ' functions. Optional.
105
+ # ' @return The updated MizerParams object
76
106
# ' @export
77
107
setComponent <- function (params , component , initial_value ,
78
- encounter_fun , pred_mort_fun ,
79
- dynamics_fun , component_params ) {
108
+ dynamics_fun ,
109
+ encounter_fun , mort_fun ,
110
+ component_params ) {
80
111
assert_that(is(params , " MizerParams" ),
81
112
is.string(component ),
82
113
is.string(dynamics_fun ),
83
- is.string(encounter_fun ),
84
- is.string(mortality_fun ),
85
- is.function(get0(dynamics_fun )),
86
- is.function(get0(encounter_fun )),
87
- is.function(get0(mortality_fun )),
88
- is.list(component_params ))
114
+ is.function(get0(dynamics_fun )))
89
115
params @ other_dynamics [[component ]] <- dynamics_fun
90
- params @ other_pred_mort [[component ]] <- pred_mort_fun
91
- params @ other_encounter [[component ]] <- encounter_fun
92
- params @ other_params [[component ]] <- component_params
93
- initialNOther(params )[[component ]] <- initial_value
116
+ params @ initial_n_other [[component ]] <- initial_value
117
+ # TODO: Add checks that the functions have the right arguments and
118
+ # return values
119
+ if (! missing(mort_fun )) {
120
+ if (! is.null(mort_fun ) && ! is.function(get0(mort_fun ))) {
121
+ stop(" `mort_fun` needs to be NULL or a function." )
122
+ }
123
+ params @ other_mort [[component ]] <- mort_fun
124
+ }
125
+ if (! missing(encounter_fun )) {
126
+ if (! is.null(encounter_fun ) && ! is.function(get0(encounter_fun ))) {
127
+ stop(" `encounter_fun` needs to be NULL or a function." )
128
+ }
129
+ params @ other_encounter [[component ]] <- encounter_fun
130
+ }
131
+ if (! missing(component_params )) {
132
+ if (! is.null(component_params ) &&
133
+ (! is.list(component_params ) || is.null(names(component_params )))) {
134
+ stop(" `component_params` needs to be NULL or a named list." )
135
+ }
136
+ params @ other_params [[component ]] <- component_params
137
+ }
138
+ params
94
139
}
95
140
141
+ # ' @rdname setComponent
142
+ # ' @export
143
+ removeComponent <- function (params , component ) {
144
+ if (! component %in% names(params @ other_dynamics )) {
145
+ stop(" There is no component named " , component )
146
+ }
147
+ params @ other_dynamics [[component ]] <- NULL
148
+ params @ other_encounter [[component ]] <- NULL
149
+ params @ other_mort [[component ]] <- NULL
150
+ params @ other_params [[component ]] <- NULL
151
+ params @ initial_n_other [[component ]] <- NULL
152
+ params
153
+ }
154
+
155
+
96
156
# ' Get information about other ecosystem components
97
157
# '
98
158
# ' @param params A MizerParams object
99
159
# ' @param component Name of the component of interest. If missing, a list of
100
160
# ' all components will be returned.
101
- # ' @return For `getComponent`: A list with the entries `initial_value`, `dynamics_fun`,
102
- # ' `encounter_fun`, `morality_fun `, `component_params`. If `component` is
161
+ # ' @return A list with the entries `initial_value`, `dynamics_fun`,
162
+ # ' `encounter_fun`, `mort_fun `, `component_params`. If `component` is
103
163
# ' missing, then a list of lists for all components is returned.
104
- # ' @rdname setComponent
105
164
# ' @export
106
165
getComponent <- function (params , component ) {
107
166
if (missing(component )) {
108
- lapply(names(params @ other_dynamics ),
109
- function (x ) getComponent(params , x ))
167
+ l <- lapply(names(params @ other_dynamics ),
168
+ function (x ) getComponent(params , x ))
169
+ names(l ) <- names(params @ other_dynamics )
170
+ return (l )
171
+ }
172
+ if (! component %in% names(params @ other_dynamics )) {
173
+ stop(" There is no component named " , component )
110
174
}
111
- comp_list <- list (
112
- initial_value = initialNOther(params )[[component ]],
113
- component_params = params @ other_params [[component ]],
114
- dynamics_fun = params @ other_dynamics [[component ]],
115
- mortality_fun = params @ other_mort [[component ]],
116
- encounter_fun = params @ other_encounter [[component ]]
175
+ list (initial_value = initialNOther(params )[[component ]],
176
+ dynamics_fun = params @ other_dynamics [[component ]],
177
+ mort_fun = params @ other_mort [[component ]],
178
+ encounter_fun = params @ other_encounter [[component ]],
179
+ component_params = params @ other_params [[component ]]
117
180
)
118
181
}
119
182
@@ -128,6 +191,15 @@ getComponent <- function(params, component) {
128
191
`initialNOther<-` <- function (params , value ) {
129
192
assert_that(is(params , " MizerParams" ),
130
193
is.list(value ))
194
+ components <- names(params @ other_dynamics )
195
+ missing <- ! (names(value ) %in% components )
196
+ if (any(missing )) {
197
+ stop(" The following components do not exist: " , names(value )[missing ])
198
+ }
199
+ extra <- ! (components %in% names(value ))
200
+ if (any(extra )) {
201
+ stop(" Missing values for components " , components [extra ])
202
+ }
131
203
params @ initial_n_other <- value
132
204
params
133
205
}
0 commit comments