-
Notifications
You must be signed in to change notification settings - Fork 0
/
trace_asco.R
192 lines (163 loc) · 7.28 KB
/
trace_asco.R
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
#' Simulates the spread of Ascochyta blight in a chickpea field
#'
#' `trace_asco` simulates the spatiotemporal development of Ascochyta blight in a chickpea field
#' over a growing season
#'
#' @param weather weather data, recorded by a local weather station, over a chickpea
#' growing season for the model operation
#' @param paddock_length length of a paddock in metres (y)
#' @param paddock_width width of a paddock in metres (x)
#' @param sowing_date a character string of a date value indicating sowing
#' date of chickpea seed and the start of the Ascotracer model. Preferably
#' in \acronym{ISO8601} format (YYYY-MM-DD), \emph{e.g.} \dQuote{2020-04-26}.
#' Assumes there is sufficient soil moisture to induce germination and start the
#' crop growing season.
#' @param harvest_date a character string of a date value indicating harvest date of
#' chickpea crop, which is also the last day to run the Ascotracer model. Preferably in
#' \acronym{ISO8601} format (YYYY-MM-DD), \emph{e.g.} \dQuote{2020-04-26}.
#' @param seeding_rate indicate the rate at which chickpea seed is sown per
#' square metre. Defaults to \code{40}
#' @param gp_rr refers to rate of increase in chickpea growing points
#' per degree Celsius per day. Defaults to \code{0.0065}
#' @param max_gp_lim Maximum number of chickpea growing points (meristems) allowed
#' per square meter. Defaults to \code{15000}.
#' @param max_new_gp Maximum number of new chickpea growing points (meristems)
#' which develop per day, per square meter. Defaults to \code{350}.
#' @param primary_infection_foci it refers to the inoculated quadrat
#' located at the centre of the paddock from where disease spreads
#' Defaults to \code{"centre"}
#' @param latent_period_cdd latent period in cumulative degree days (sum of
#' daily temperature means) is the period between infection and production of
#' lesions on susceptible growing points. Defaults to \code{200}
#' @param initial_infection refers to initial or primary infection on seedlings,
#' resulting in the production of infected growing points
#' @param time_zone refers to time in Coordinated Universal Time (UTC)
#'
#'
#' @return a x y `data.frame` simulating the spread of Ascochyta blight in a
#' chickpea paddock
#' @export
#'
#' @examples
#' ta1 <- trace_asco(
#' weather = weather_dat,
#' paddock_length = 100,
#' paddock_width = 100,
#' sowing_date = "1998-03-09"
#' )
trace_asco <- function(weather,
paddock_length,
paddock_width,
sowing_date,
harvest_date,
initial_infection,
seeding_rate = 40,
gp_rr = 0.0065,
max_gp_lim = 15000,
max_new_gp = 350,
latent_period_cdd = 200,
time_zone = "UTC",
primary_infection_foci = "random"
){
# check date inputs for validity -----------------------------------------
.vali_date <- function(x) {
tryCatch(
# try to parse the date format using lubridate
x <- lubridate::parse_date_time(x,
c(
"Ymd",
"dmY",
"mdY",
"BdY",
"Bdy",
"bdY",
"bdy"
)),
warning = function(c) {
stop(call. = FALSE,
"\n",
x,
" is not a valid entry for date. Enter as YYYY-MM-DD.\n")
}
)
return(x)
}
# convert times to POSIXct -----------------------------------------------
initial_infection <-
lubridate::ymd(.vali_date(initial_infection), tz = time_zone) + lubridate::dhours(0)
sowing_date <-
lubridate::ymd(.vali_date(sowing_date), tz = time_zone) + lubridate::dhours(0)
harvest_date <-
lubridate::ymd(.vali_date(harvest_date), tz = time_zone) + lubridate::dhours(23)
# check epidemic start is after sowing date
if(initial_infection <= sowing_date){
stop("initial_infection occurs prior to sowing_date\n
please submit an initial_infection date which occurs after crop_sowing")
}
# makePaddock equivalent
paddock <- as.data.table(expand.grid(x = 1:paddock_width,
y = 1:paddock_length))
paddock[,new_gp := seeding_rate]
paddock[,noninfected_gp := seeding_rate]
paddock[,infected_gp := NA] # Needs to be updated!!!!
# sample a paddock location randomly if a starting foci is not given
if(primary_infection_foci == "random") {
primary_infection_foci <-
paddock[sample(seq_len(nrow(paddock)),
size = 1),
c("x", "y")]
}
if (primary_infection_foci == "center") {
primary_infection_foci <-
paddock[as.integer(round(paddock_width / 2)),
as.integer(round(paddock_length / 2))]
} else{
if (length(primary_infection_foci) != 2 |
is.numeric(primary_infection_foci) == FALSE) {
stop("primary_infection_foci should be supplied as a numeric vector of length two")
}
}
# calculate additional parameters
spore_interception_parameter <-
0.00006 * (max_gp_lim/max_new_gp)
# define max_gp
max_gp <- max_gp_lim * (1 - exp(-0.138629 * seeding_rate))
# Notes: as area is 1m x 1m many computation in the mathematica
# code are redundant because they are being multiplied by 1.
# I will reduce the number of objects containing the same value,
# Below is a list of Mathematica values consolidated into 1
#
# refUninfectiveGPs <- minGrowingPoints <- seeding_rate
daily_vals_list <- list(
i = sowing_date, # day of the simulation (iterator)
day = lubridate::yday(sowing_date), # day of the year
cdd = 0, # cumulative degree days
cwh = 0, # cumulative wet hours
cr = 0, # cumulative rainfall
gp_standard = seeding_rate, # standard number of growing points for 1m^2 if not inhibited by infection
new_gp = seeding_rate, # new number of growing points for current iteration
infected_coords = primary_infection_foci # data.frame
)
time_increments <- seq(sowing_date,
harvest_date,
by = "days")
for(i in seq_along(time_increments)){
# skip time increment if initial_infection is after the sowing date
if(time_increments[i] < initial_infection) next
# This function or line of code is redundant given this model works
# on a 1x1m grid and we do not want to wrap address
# additional_new_infections <- packets_from_locations(location_list = epidemic_foci)
# currently working on one_day
day_out <- one_day(i_date = time_increments[i],
daily_vals = daily_vals_list,
weather_dat = weather,
gp_rr = gp_rr,
max_gp = max_gp,
max_new_gp = max_new_gp,
paddock = paddock,
spore_interception_parameter = spore_interception_parameter)
# temporary line of code to test building of daily_vals in loop
daily_vals_list <- day_out
}
return(daily_vals_list)
}