comparison bmsb.R @ 0:ff341ead2c11 draft

Uploaded
author greg
date Mon, 01 Aug 2016 11:16:51 -0400
parents
children 99a386ac1f5b
comparison
equal deleted inserted replaced
-1:000000000000 0:ff341ead2c11
1 #!/usr/bin/env Rscript
2
3
4 suppressPackageStartupMessages(require("hash"))
5 suppressPackageStartupMessages(require("KernSmooth"))
6 suppressPackageStartupMessages(require("methods"))
7 suppressPackageStartupMessages(library("optparse"))
8 suppressPackageStartupMessages(library("rjson"))
9 suppressPackageStartupMessages(require("utils"))
10
11
12 option_list <- list(
13 make_option(c("-s", "--save_log"), action="store_true", default=FALSE, help="Save R logs"),
14 make_option(c("-m", "--output_r_log"), action="store", help="Output dataset for R logs"),
15 make_option(c("-o", "--output"), action="store", help="Output dataset")
16 )
17
18 daylength = function(L){
19 # from Forsythe 1995
20 p = 0.8333
21 dl <- NULL
22 for (i in 1:365) {
23 theta <- 0.2163108 + 2 * atan(0.9671396 * tan(0.00860 * (i - 186)))
24 phi <- asin(0.39795 * cos(theta))
25 dl[i] <- 24 - 24/pi * acos((sin(p * pi/180) + sin(L * pi/180) * sin(phi))/(cos(L * pi/180) * cos(phi)))
26 }
27 # return a vector of daylength in 365 days
28 dl
29 }
30
31
32 # source("daylength.R")
33 hourtemp = function(L,date){
34 # L = 37.5 specify this in main program
35 # base development threshold for BMSB
36 threshold <- 12.7
37 # threshold2 <- threshold/24 degree hour accumulation
38 #expdata <- tempdata[1:365,11:13] # Use daily max, min, mean
39 # daily minimum
40 dnp <- expdata[date,2]
41 # daily maximum
42 dxp <- expdata[date,3]
43 dmean <- 0.5 * (dnp + dxp)
44 #if (dmean>0) {
45 #dnp <- dnp - k1 * dmean
46 #dxp <- dxp + k2 * dmean
47 #} else {
48 #dnp <- dnp + k1 * dmean
49 #dxp <- dxp - k2 * dmean
50 #}
51 dd <- 0 # initialize degree day accumulation
52
53 if (dxp<threshold) {
54 dd <- 0
55 } else {
56 # extract daylength data for entire year
57 dlprofile <- daylength(L)
58 # initialize hourly temperature
59 T <- NULL
60 #initialize degree hour vector
61 dh <- NULL
62 # calculate daylength in given date
63 # date <- 200
64 y <- dlprofile[date]
65 # night length
66 z <- 24 - y
67 # lag coefficient
68 a <- 1.86
69 # night coefficient
70 b <- 2.20
71 #import raw data set
72 #tempdata <- read.csv("tempdata.csv")
73 # Should be outside function otherwise its redundant
74 # sunrise time
75 risetime <- 12 - y/2
76 # sunset time
77 settime <- 12 + y/2
78 ts <- (dxp - dnp) * sin(pi * (settime-5)/(y + 2 * a)) + dnp
79 for (i in 1:24) {
80 if (i > risetime && i < settime) {
81 # number of hours after Tmin until sunset
82 m <- i - 5
83 T[i] = (dxp - dnp) * sin(pi * m/(y + 2 * a)) + dnp
84 if (T[i]<8.4) {
85 dh[i] <- 0
86 } else {
87 dh[i] <- T[i] - 8.4
88 }
89 } else if (i>settime) {
90 n <- i - settime
91 T[i] = dnp + (ts - dnp) * exp(-b * n/z)
92 if (T[i]<8.4) {
93 dh[i] <- 0
94 } else {
95 dh[i] <- T[i] - 8.4
96 }
97 } else {
98 n <- i + 24 - settime
99 T[i] = dnp + (ts - dnp) * exp(-b * n / z)
100 if (T[i]<8.4) {
101 dh[i] <- 0
102 } else {
103 dh[i] <- T[i] - 8.4
104 }
105 }
106 }
107 dd <- sum(dh) / 24
108 }
109 return = c(dmean, dd)
110 return
111 }
112
113
114 mortality.egg = function(temperature) {
115 if (temperature < 12.7) {
116 mort.prob = 1
117 } else {
118 # 100% mortality if <12.7
119 mort.prob = 0.8 - temperature / 40
120 if (mort.prob<0) {
121 mort.prob = 0.01
122 }
123 }
124 return = mort.prob
125 return
126 }
127
128
129 mortality.nymph = function(temperature) {
130 if (temperature<12.7) {
131 mort.prob = 0.03
132 } else {
133 # at low temperature
134 mort.prob = -temperature * 0.0008 + 0.03
135 }
136 return = mort.prob
137 return
138 }
139
140
141 mortality.adult = function(temperature) {
142 if (temperature < 12.7) {
143 mort.prob = 0.002
144 } else {
145 mort.prob = -temperature * 0.0005 + 0.02
146 }
147 return = mort.prob
148 return
149 }
150
151
152 # model initialization
153 # TODO: setwd(“/home/lunarmouse/Nielsen's project/”)
154 # start with 1000 individuals
155 n <- 1000
156 # Generation, Stage, DD, T, Diapause
157 vec.ini <- c(0,3,0,0,0)
158 # overwintering, previttelogenic, DD = 0, T = 0, no-diapause
159 vec.mat <- rep(vec.ini,n)
160 # complete matrix for the population
161 vec.mat <- t(matrix(vec.mat, nrow = 5))
162 # latitude for Asheville NC
163 L <- 35.58
164 # complete photoperiod profile in a year, requires daylength function
165 ph.p <- daylength(L)
166
167 # load temperature data@location/year
168 load("asheville2014.Rdat")
169
170 # time series of population size
171 tot.pop <- NULL
172
173 # gen.0 pop size
174 gen0.pop <- rep(0, 365)
175 gen1.pop <- rep(0, 365)
176 gen2.pop <- rep(0, 365)
177
178 # aggregate
179 S0 <- S1 <- S2 <- S3 <- S4 <- S5 <- rep(0, 365)
180 g0.adult <- g1.adult <- g2.adult <- rep(0, 365)
181
182 # birth death adults
183 N.newborn <- N.death <- N.adult <- rep(0, 365)
184
185 # degree-day accumulation
186 dd.day <- rep(0, 365)
187
188 # start tick
189 ptm <- proc.time()
190
191 for (n.sim in 1:1000) {
192 # loop through 1000 simulations
193 for (day in 1:365) {
194 # loop through 365 day/yr
195 photoperiod <- ph.p[day]
196 # photoperiod in the day
197 temp.profile <- hourtemp(L,day)
198 # temperature profile
199 mean.temp <- temp.profile[1]
200 # mean temp
201 dd.temp <- temp.profile[2]
202 # degree-day
203 dd.day[day] <- dd.temp
204 death.vec <- NULL
205 # trash bin for death
206 birth.vec <- NULL
207 # record new born
208 for (i in 1:n) {
209 # loop through all individual
210 vec.ind <- vec.mat[i,]
211 # find individual record
212 # first of all, still alive?
213 if (vec.ind[2] == 0) {
214 # egg
215 death.prob = mortality.egg(mean.temp)
216 } else if (vec.ind[2] == 1 | vec.ind[2] == 2) {
217 # nymph
218 death.prob = mortality.nymph(mean.temp)
219 } else if (vec.ind[2] == 3 | vec.ind[2] == 4 | vec.ind[2] == 5) {
220 # for adult
221 death.prob = mortality.adult(mean.temp)
222 }
223 u.d <- runif(1)
224 if (u.d<death.prob) {
225 death.vec <- c(death.vec,i)
226 } else {
227 # aggregrate index of dead bug
228 # event 1 end of diapause
229 if (vec.ind[1] == 0 && vec.ind[2] == 3) {
230 # overwintering adult (previttelogenic)
231 if (photoperiod>13.5 && vec.ind[3] > 68 && day < 180) {
232 # add 68C to become fully reproductively matured
233 # transfer to vittelogenic
234 vec.ind <- c(0,4,0,0,0)
235 vec.mat[i,] <- vec.ind
236 } else {
237 # add to DD
238 vec.ind[3] <- vec.ind[3] + dd.temp
239 vec.ind[4] <- vec.ind[4] + 1 # add 1 day in current stage
240 vec.mat[i,] <- vec.ind
241 }
242 }
243 if (vec.ind[1]!=0 && vec.ind[2] == 3) {
244 # NOT overwintering adult (previttelogenic)
245 current.gen <- vec.ind[1]
246 if (vec.ind[3]>68) {
247 # add 68C to become fully reproductively matured
248 # transfer to vittelogenic
249 vec.ind <- c(current.gen,4,0,0,0)
250 vec.mat[i,] <- vec.ind
251 } else {
252 # add to DD
253 vec.ind[3] <- vec.ind[3] + dd.temp
254 # add 1 day in current stage
255 vec.ind[4] <- vec.ind[4] + 1
256 vec.mat[i,] <- vec.ind
257 }
258 }
259 # event 2 oviposition -- where population dynamics comes from
260 # vittelogenic stage, overwintering generation
261 if (vec.ind[2] == 4 && vec.ind[1] == 0 && mean.temp>10) {
262 if (vec.ind[4] == 0) {
263 # just turned in vittelogenic stage
264 n.birth = round(runif(1,10,20))
265 } else {
266 p.birth = 1/4/75
267 # prob of birth
268 u1 <- runif(1)
269 if (u1<p.birth) {
270 n.birth = n.birth
271 }
272 }
273 # add to DD
274 vec.ind[3] <- vec.ind[3] + dd.temp
275 # add 1 day in current stage
276 vec.ind[4] <- vec.ind[4] + 1
277 vec.mat[i,] <- vec.ind
278 if (n.birth>0) {
279 # add new birth -- might be in different generations
280 # generation + 1
281 new.gen <- vec.ind[1] + 1
282 # egg profile
283 new.ind <- c(new.gen,0,0,0,0)
284 new.vec <- rep(new.ind,n.birth)
285 # update batch of egg profile
286 new.vec <- t(matrix(new.vec,nrow = 5))
287 # group with total eggs laid in that day
288 birth.vec <- rbind(birth.vec,new.vec)
289 }
290 }
291 # event 2 oviposition -- for gen 1.
292 if (vec.ind[2] == 4 && vec.ind[1] == 1 && mean.temp>12.5 && day<222) {
293 # vittelogenic stage, 1st generation
294 if (vec.ind[4] == 0) {
295 # just turned in vittelogenic stage
296 n.birth = round(runif(1,10,20))
297 } else {
298 p.birth = 1/4/75
299 u1 <- runif(1)
300 if (u1<p.birth) {
301 n.birth = n.birth
302 }
303 }
304 # add to DD
305 vec.ind[3] <- vec.ind[3] + dd.temp
306 # add 1 day in current stage
307 vec.ind[4] <- vec.ind[4] + 1
308 vec.mat[i,] <- vec.ind
309 if (n.birth>0) {
310 # add new birth -- might be in different generations
311 # generation + 1
312 new.gen <- vec.ind[1] + 1
313 # egg profile
314 new.ind <- c(new.gen,0,0,0,0)
315 new.vec <- rep(new.ind,n.birth)
316 # update batch of egg profile
317 new.vec <- t(matrix(new.vec,nrow = 5))
318 # group with total eggs laid in that day
319 birth.vec <- rbind(birth.vec,new.vec)
320 }
321 }
322 # event 3 development (with diapause determination)
323 # event 3.1 egg development to young nymph (vec.ind[2] = 0 -> egg)
324 # egg stage
325 if (vec.ind[2] == 0) {
326 # add to DD
327 vec.ind[3] <- vec.ind[3] + dd.temp
328 # from egg to young nymph
329 if (vec.ind[3] >= 53.30 && -0.9843 * dd.temp + 33.438>0) {
330 current.gen <- vec.ind[1]
331 # transfer to young nym stage
332 vec.ind <- c(current.gen,1,0,0,0)
333 } else {
334 # add 1 day in current stage
335 vec.ind[4] <- vec.ind[4] + 1
336 }
337 vec.mat[i,] <- vec.ind
338 }
339 # event 3.2 young nymph to old nymph (vec.ind[2] = 1 -> young nymph: determines diapause)
340 # young nymph stage
341 if (vec.ind[2] == 1) {
342 # add to DD
343 vec.ind[3] <- vec.ind[3] + dd.temp
344 # from young to old nymph
345 if (vec.ind[3] >= 537/2 && -0.45 * dd.temp + 18>0) {
346 current.gen <- vec.ind[1]
347 # transfer to old nym stage
348 vec.ind <- c(current.gen,2,0,0,0)
349 # prepare for diapausing
350 if (photoperiod<13.5 && day > 180) {
351 vec.ind[5] <- 1
352 }
353 } else {
354 # add 1 day in current stage
355 vec.ind[4] <- vec.ind[4] + 1
356 }
357 vec.mat[i,] <- vec.ind
358 }
359 # event 3.3 old nymph to adult: previttelogenic or diapausing?
360 # old nymph stage
361 if (vec.ind[2] == 2) {
362 # add to DD
363 vec.ind[3] <- vec.ind[3] + dd.temp
364 # from old to adult
365 if (vec.ind[3] >= 537/2 && -0.50 * dd.temp + 22>0) {
366 current.gen <- vec.ind[1]
367 # non-diapausing adult -- previttelogenic
368 if (vec.ind[5] == 0) {
369 vec.ind <- c(current.gen,3,0,0,0)
370 # diapausing
371 } else {
372 vec.ind <- c(current.gen,5,0,0,1)
373 }
374 } else {
375 # add 1 day in current stage
376 vec.ind[4] <- vec.ind[4] + 1
377 }
378 vec.mat[i,] <- vec.ind
379 }
380 # event 4 growing of diapausing adult (unimportant, but still necessary)##
381 if (vec.ind[2] == 5) {
382 vec.ind[3] <- vec.ind[3] + dd.temp
383 vec.ind[4] <- vec.ind[4] + 1
384 vec.mat[i,] <- vec.ind
385 }
386 } # else if it is still alive
387 } # end of the individual bug loop
388 # find how many died
389 n.death <- length(death.vec)
390 if (n.death>0) {
391 vec.mat <- vec.mat[-death.vec, ]
392 }
393 # remove record of dead
394 # find how many new born
395 n.newborn <- length(birth.vec[,1])
396 vec.mat <- rbind(vec.mat,birth.vec)
397 # update population size for the next day
398 n <- n-n.death + n.newborn
399
400 # aggregate results by day
401 tot.pop <- c(tot.pop,n)
402 # egg
403 s0 <- sum(vec.mat[,2] == 0)
404 # young nymph
405 s1 <- sum(vec.mat[,2] == 1)
406 # old nymph
407 s2 <- sum(vec.mat[,2] == 2)
408 # previtellogenic
409 s3 <- sum(vec.mat[,2] == 3)
410 # vitellogenic
411 s4 <- sum(vec.mat[,2] == 4)
412 # diapausing
413 s5 <- sum(vec.mat[,2] == 5)
414 # overwintering adult
415 gen0 <- sum(vec.mat[,1] == 0)
416 # first generation
417 gen1 <- sum(vec.mat[,1] == 1)
418 # second generation
419 gen2 <- sum(vec.mat[,1] == 2)
420 # sum of all adults
421 n.adult <- sum(vec.mat[,2] == 3) + sum(vec.mat[,2] == 4) + sum(vec.mat[,2] == 5)
422 # gen.0 pop size
423 gen0.pop[day] <- gen0
424 gen1.pop[day] <- gen1
425 gen2.pop[day] <- gen2
426 S0[day] <- s0
427 S1[day] <- s1
428 S2[day] <- s2
429 S3[day] <- s3
430 S4[day] <- s4
431 S5[day] <- s5
432 g0.adult[day] <- sum(vec.mat[,1] == 0)
433 g1.adult[day] <- sum((vec.mat[,1] == 1 & vec.mat[,2] == 3) | (vec.mat[,1] == 1 & vec.mat[,2] == 4) | (vec.mat[,1] == 1 & vec.mat[,2] == 5))
434 g2.adult[day] <- sum((vec.mat[,1] == 2 & vec.mat[,2] == 3) | (vec.mat[,1] == 2 & vec.mat[,2] == 4) | (vec.mat[,1] == 2 & vec.mat[,2] == 5))
435 N.newborn[day] <- n.newborn
436 N.death[day] <- n.death
437 N.adult[day] <- n.adult
438 }
439 print(n.sim)
440 }
441
442 proc.time() - ptm
443 dd.cum <- cumsum(dd.day)
444 save(dd.day, dd.cum, S0, S1, S2, S3, S4, S5, N.newborn, N.death, N.adult, tot.pop, gen0.pop, gen1.pop, gen2.pop, g0.adult, g1.adult, g2.adult, file="asheville2014sim.Rdat")