Mercurial > repos > greg > bmsb
comparison bmsb.R @ 25:08cb8c7228c2 draft
Uploaded
author | greg |
---|---|
date | Fri, 19 Aug 2016 14:38:51 -0400 |
parents | a5f80d53feee |
children | 641c4954c76c |
comparison
equal
deleted
inserted
replaced
24:af90870ced72 | 25:08cb8c7228c2 |
---|---|
1 #!/usr/bin/env Rscript | 1 #!/usr/bin/env Rscript |
2 | 2 |
3 options_list <- list( | 3 suppressPackageStartupMessages(library("optparse")) |
4 make_option(c("-i", "--input_temperatures"), action="store", help="Input temperatures csv file"), | 4 |
5 make_option(c("-s", "--save_log"), action="store_true", default=FALSE, help="Save R logs"), | 5 option_list <- list( |
6 make_option(c("-m", "--output_r_log"), action="store", help="Output dataset for R logs"), | 6 make_option(c("-i", "--input"), action="store", help="Input dataset") |
7 make_option(c("-o", "--output"), action="store", help="Output dataset") | 7 make_option(c("-o", "--output"), action="store", help="Output dataset") |
8 ) | 8 ) |
9 | 9 |
10 parser <- OptionParser(usage="%prog [options] file", options_list) | 10 parser <- OptionParser(usage="%prog [options] file", options_list) |
11 args <- parse_args(parser, positional_arguments=TRUE) | 11 args <- parse_args(parser, positional_arguments=TRUE) |
12 opt <- args$options | 12 opt <- args$options |
13 | 13 |
14 | 14 ######################################### |
15 if (opt$save_log) { | 15 daylength=function(L){ |
16 rlogf <- file(opt$output_r_log, open="wt") | 16 # from Forsythe 1995 |
17 } else { | 17 p=0.8333 |
18 # Direct R messaging to a temporary file. | 18 dl<-NULL |
19 rlogf <- file("tmpRLog", open="wt") | 19 for (i in 1:365) { |
20 } | 20 theta<-0.2163108+2*atan(0.9671396*tan(0.00860*(i-186))) |
21 sink(file=rlogf, type=c("output", "message"), append=FALSE, split=FALSE) | 21 phi<-asin(0.39795*cos(theta)) |
22 | 22 dl[i]<-24-24/pi*acos((sin(p*pi/180)+sin(L*pi/180)*sin(phi))/(cos(L*pi/180)*cos(phi))) |
23 tempdata <- read.csv(opt$input_temperatures) | 23 } |
24 save(tempdata, file=opt$output) | 24 dl # return a vector of daylength in 365 days |
25 } | |
26 ######################################### | |
27 | |
28 ######################################### | |
29 # source("daylength.R") | |
30 hourtemp=function(L,date){ | |
31 # L=37.5 specify this in main program | |
32 threshold<-12.7 # base development threshold for BMSB | |
33 # threshold2<-threshold/24 degree hour accumulation | |
34 #expdata<-tempdata[1:365,11:13] # Use daily max, min, mean | |
35 dnp<-expdata[date,2] # daily minimum | |
36 dxp<-expdata[date,3] # daily maximum | |
37 dmean<-0.5*(dnp+dxp) | |
38 #if (dmean>0) { | |
39 #dnp<-dnp-k1*dmean | |
40 #dxp<-dxp+k2*dmean | |
41 #} else { | |
42 #dnp<-dnp+k1*dmean | |
43 #dxp<-dxp-k2*dmean | |
44 #} | |
45 dd<-0 # initialize degree day accumulation | |
46 | |
47 if (dxp<threshold) {dd<-0} else | |
48 { | |
49 dlprofile<-daylength(L) # extract daylength data for entire year | |
50 T<-NULL # initialize hourly temperature | |
51 dh<-NULL #initialize degree hour vector | |
52 # date<-200 | |
53 y<-dlprofile[date] # calculate daylength in given date | |
54 z<-24-y # night length | |
55 a<-1.86 # lag coefficient | |
56 b<-2.20 # night coefficient | |
57 #tempdata<-read.csv("tempdata.csv") #import raw data set | |
58 # Should be outside function otherwise its redundant | |
59 risetime<-12-y/2 # sunrise time | |
60 settime<-12+y/2 # sunset time | |
61 ts<-(dxp-dnp)*sin(pi*(settime-5)/(y+2*a))+dnp | |
62 for (i in 1:24){ | |
63 if (i>risetime && i<settime) { | |
64 m<-i-5 # number of hours after Tmin until sunset | |
65 T[i]=(dxp-dnp)*sin(pi*m/(y+2*a))+dnp | |
66 if (T[i]<8.4) {dh[i]<-0} else | |
67 {dh[i]<-T[i]-8.4} | |
68 } else | |
69 if (i>settime){ | |
70 n<-i-settime | |
71 T[i]=dnp+(ts-dnp)*exp(-b*n/z) | |
72 if (T[i]<8.4) {dh[i]<-0} else | |
73 {dh[i]<-T[i]-8.4} | |
74 } else | |
75 { | |
76 n<-i+24-settime | |
77 T[i]=dnp+(ts-dnp)*exp(-b*n/z) | |
78 if (T[i]<8.4) {dh[i]<-0} else | |
79 {dh[i]<-T[i]-8.4} | |
80 } | |
81 } | |
82 dd<-sum(dh)/24 | |
83 } | |
84 return=c(dmean,dd) | |
85 return | |
86 } | |
87 ######################################### | |
88 | |
89 | |
90 ######################################### | |
91 mortality.egg=function(temperature){ | |
92 if (temperature<12.7) { | |
93 mort.prob=0.8} else | |
94 {mort.prob=0.8-temperature/40 | |
95 if (mort.prob<0) {mort.prob=0.01} | |
96 } | |
97 return=mort.prob | |
98 return | |
99 } | |
100 ######################################### | |
101 | |
102 | |
103 ######################################### | |
104 mortality.nymph=function(temperature){ | |
105 if (temperature<12.7) { | |
106 mort.prob=0.03} else | |
107 {mort.prob=temperature*0.0008+0.03} | |
108 return=mort.prob | |
109 return | |
110 } | |
111 ######################################### | |
112 | |
113 ######################################### | |
114 mortality.adult=function(temperature){ | |
115 if (temperature<12.7) { | |
116 mort.prob=0.002} else | |
117 {mort.prob=temperature*0.0005+0.02} | |
118 return=mort.prob | |
119 return | |
120 } | |
121 ######################################### | |
122 | |
123 # model initialization | |
124 # setwd(“/home/lunarmouse/Dropbox/Nelson's project/") | |
125 # PLEASE CHANGE TO YOUR OWN DIRECTORY!!! | |
126 # PLEASE LOAD BSMB FUNCTIONS FIRST!!! | |
127 | |
128 n<-1000 # start with 1000 individuals | |
129 # Generation, Stage, DD, T, Diapause | |
130 vec.ini<-c(0,3,0,0,0) | |
131 # overwintering, previttelogenic,DD=0, T=0, no-diapause | |
132 vec.mat<-rep(vec.ini,n) | |
133 vec.mat<-t(matrix(vec.mat,nrow=5)) # complete matrix for the population | |
134 L<-35.58 # latitude for Asheville NC | |
135 ph.p<-daylength(L) # complete photoperiod profile in a year, requires daylength function | |
136 | |
137 #load("asheville2014.Rdat") # load temperature data@location/year | |
138 load(opt$input) # load temperature data@location/year | |
139 tot.pop<-NULL # time series of population size | |
140 gen0.pop<-rep(0,365) # gen.0 pop size | |
141 gen1.pop<-rep(0,365) | |
142 gen2.pop<-rep(0,365) | |
143 S0<-S1<-S2<-S3<-S4<-S5<-rep(0,365) | |
144 g0.adult<-g1.adult<-g2.adult<-rep(0,365) | |
145 N.newborn<-N.death<-N.adult<-rep(0,365) | |
146 dd.day<-rep(0,365) | |
147 | |
148 ptm <- proc.time() # start tick | |
149 | |
150 for (day in 1:365) { # all the day | |
151 photoperiod<-ph.p[day] # photoperiod in the day | |
152 temp.profile<-hourtemp(L,day) | |
153 mean.temp<-temp.profile[1] | |
154 dd.temp<-temp.profile[2] | |
155 dd.day[day]<-dd.temp | |
156 death.vec<-NULL # trash bin for death | |
157 birth.vec<-NULL # new born | |
158 #n<-length(vec.mat[,1]) # population size at previous day | |
159 | |
160 for (i in 1:n) { # all individual | |
161 vec.ind<-vec.mat[i,] # find individual record | |
162 | |
163 # first of all, still alive? | |
164 if(vec.ind[2]==0){ # egg | |
165 death.prob=mortality.egg(mean.temp) | |
166 } else if (vec.ind[2]==1 | vec.ind[2]==2) { | |
167 death.prob=mortality.nymph(mean.temp) | |
168 } else if (vec.ind[2]==3 | vec.ind[2]==4 | vec.ind[2]==5) { # for adult | |
169 if (day<120 && day>270) {death.prob=0.33*mortality.adult(mean.temp) | |
170 } else { | |
171 death.prob=mortality.adult(mean.temp)} # reduce adult mortality after fall equinox | |
172 } | |
173 | |
174 | |
175 #(or dependent on temperature and life stage?) | |
176 u.d<-runif(1) | |
177 if (u.d<death.prob) { | |
178 death.vec<-c(death.vec,i)} else # aggregrate index of dead bug | |
179 { | |
180 # event 1 end of diapause | |
181 if (vec.ind[1]==0 && vec.ind[2]==3) { # overwintering adult (previttelogenic) | |
182 if (photoperiod>13.5 && vec.ind[3]>77 && day<180) { # add 77C to become fully reproductively matured | |
183 vec.ind<-c(0,4,0,0,0) # transfer to vittelogenic | |
184 vec.mat[i,]<-vec.ind | |
185 | |
186 } else { | |
187 vec.ind[3]<-vec.ind[3]+dd.temp # add to DD | |
188 vec.ind[4]<-vec.ind[4]+1 # add 1 day in current stage | |
189 vec.mat[i,]<-vec.ind | |
190 } | |
191 } | |
192 | |
193 if (vec.ind[1]!=0 && vec.ind[2]==3) { # NOT overwintering adult (previttelogenic) | |
194 current.gen<-vec.ind[1] | |
195 if (vec.ind[3]>77) { # add 77C to become fully reproductively matured | |
196 vec.ind<-c(current.gen,4,0,0,0) # transfer to vittelogenic | |
197 vec.mat[i,]<-vec.ind | |
198 } else { | |
199 vec.ind[3]<-vec.ind[3]+dd.temp # add to DD | |
200 vec.ind[4]<-vec.ind[4]+1 # add 1 day in current stage | |
201 vec.mat[i,]<-vec.ind | |
202 } | |
203 } | |
204 | |
205 | |
206 | |
207 # event 2 oviposition -- where population dynamics comes from | |
208 if (vec.ind[2]==4 && vec.ind[1]==0 && mean.temp>10) { # vittelogenic stage, overwintering generation | |
209 if (vec.ind[4]==0) { # just turned in vittelogenic stage | |
210 n.birth=round(runif(1,2,8))} else{ | |
211 p.birth=0.01 # daily probability of birth | |
212 u1<-runif(1) | |
213 if (u1<p.birth) {n.birth=round(runif(1,2,8))} | |
214 } | |
215 vec.ind[3]<-vec.ind[3]+dd.temp # add to DD | |
216 vec.ind[4]<-vec.ind[4]+1 # add 1 day in current stage | |
217 vec.mat[i,]<-vec.ind | |
218 if (n.birth>0) { # add new birth -- might be in different generations | |
219 new.gen<-vec.ind[1]+1 # generation +1 | |
220 new.ind<-c(new.gen,0,0,0,0) # egg profile | |
221 new.vec<-rep(new.ind,n.birth) | |
222 new.vec<-t(matrix(new.vec,nrow=5)) # update batch of egg profile | |
223 birth.vec<-rbind(birth.vec,new.vec) # group with total eggs laid in that day | |
224 } | |
225 } | |
226 | |
227 # event 2 oviposition -- for gen 1. | |
228 if (vec.ind[2]==4 && vec.ind[1]==1 && mean.temp>12.5 && day<222) { # vittelogenic stage, 1st generation | |
229 if (vec.ind[4]==0) { # just turned in vittelogenic stage | |
230 n.birth=round(runif(1,2,8))} else{ | |
231 p.birth=0.01 # daily probability of birth | |
232 u1<-runif(1) | |
233 if (u1<p.birth) {n.birth=round(runif(1,2,8))} | |
234 } | |
235 vec.ind[3]<-vec.ind[3]+dd.temp # add to DD | |
236 vec.ind[4]<-vec.ind[4]+1 # add 1 day in current stage | |
237 vec.mat[i,]<-vec.ind | |
238 if (n.birth>0) { # add new birth -- might be in different generations | |
239 new.gen<-vec.ind[1]+1 # generation +1 | |
240 new.ind<-c(new.gen,0,0,0,0) # egg profile | |
241 new.vec<-rep(new.ind,n.birth) | |
242 new.vec<-t(matrix(new.vec,nrow=5)) # update batch of egg profile | |
243 birth.vec<-rbind(birth.vec,new.vec) # group with total eggs laid in that day | |
244 } | |
245 } | |
246 | |
247 | |
248 | |
249 # event 3 development (with diapause determination) | |
250 # event 3.1 egg development to young nymph (vec.ind[2]=0 -> egg) | |
251 if (vec.ind[2]==0) { # egg stage | |
252 vec.ind[3]<-vec.ind[3]+dd.temp # add to DD | |
253 if (vec.ind[3]>=68) { # from egg to young nymph, DD requirement met | |
254 current.gen<-vec.ind[1] | |
255 vec.ind<-c(current.gen,1,0,0,0) # transfer to young nym stage | |
256 } else { | |
257 vec.ind[4]<-vec.ind[4]+1 # add 1 day in current stage | |
258 } | |
259 vec.mat[i,]<-vec.ind | |
260 } | |
261 | |
262 # event 3.2 young nymph to old nymph (vec.ind[2]=1 -> young nymph: determines diapause) | |
263 if (vec.ind[2]==1) { # young nymph stage | |
264 vec.ind[3]<-vec.ind[3]+dd.temp # add to DD | |
265 if (vec.ind[3]>=250) { # from young to old nymph, DD requirement met | |
266 current.gen<-vec.ind[1] | |
267 vec.ind<-c(current.gen,2,0,0,0) # transfer to old nym stage | |
268 if (photoperiod<13.5 && day > 180) {vec.ind[5]<-1} # prepare for diapausing | |
269 } else { | |
270 vec.ind[4]<-vec.ind[4]+1 # add 1 day in current stage | |
271 } | |
272 vec.mat[i,]<-vec.ind | |
273 } | |
274 | |
275 | |
276 # event 3.3 old nymph to adult: previttelogenic or diapausing? | |
277 if (vec.ind[2]==2) { # old nymph stage | |
278 vec.ind[3]<-vec.ind[3]+dd.temp # add to DD | |
279 if (vec.ind[3]>=200) { # from old to adult, DD requirement met | |
280 current.gen<-vec.ind[1] | |
281 if (vec.ind[5]==0) { # non-diapausing adult -- previttelogenic | |
282 vec.ind<-c(current.gen,3,0,0,0) | |
283 } else { # diapausing | |
284 vec.ind<-c(current.gen,5,0,0,1) | |
285 } | |
286 } else { | |
287 vec.ind[4]<-vec.ind[4]+1 # add 1 day in current stage | |
288 } | |
289 vec.mat[i,]<-vec.ind | |
290 } | |
291 | |
292 # event 4 growing of diapausing adult (unimportant, but still necessary)## | |
293 if (vec.ind[2]==5) { | |
294 vec.ind[3]<-vec.ind[3]+dd.temp | |
295 vec.ind[4]<-vec.ind[4]+1 | |
296 vec.mat[i,]<-vec.ind | |
297 } | |
298 | |
299 } # else if it is still alive | |
300 | |
301 } # end of the individual bug loop | |
302 | |
303 # find how many died | |
304 n.death<-length(death.vec) | |
305 if (n.death>0) { | |
306 vec.mat<-vec.mat[-death.vec, ]} | |
307 # remove record of dead | |
308 # find how many new born | |
309 n.newborn<-length(birth.vec[,1]) | |
310 vec.mat<-rbind(vec.mat,birth.vec) | |
311 # update population size for the next day | |
312 n<-n-n.death+n.newborn | |
313 | |
314 # aggregate results by day | |
315 tot.pop<-c(tot.pop,n) | |
316 s0<-sum(vec.mat[,2]==0) #egg | |
317 s1<-sum(vec.mat[,2]==1) # young nymph | |
318 s2<-sum(vec.mat[,2]==2) # old nymph | |
319 s3<-sum(vec.mat[,2]==3) # previtellogenic | |
320 s4<-sum(vec.mat[,2]==4) # vitellogenic | |
321 s5<-sum(vec.mat[,2]==5) # diapausing | |
322 gen0<-sum(vec.mat[,1]==0) # overwintering adult | |
323 gen1<-sum(vec.mat[,1]==1) # first generation | |
324 gen2<-sum(vec.mat[,1]==2) # second generation | |
325 n.adult<-sum(vec.mat[,2]==3)+sum(vec.mat[,2]==4)+sum(vec.mat[,2]==5) # sum of all adults | |
326 gen0.pop[day]<-gen0 # gen.0 pop size | |
327 gen1.pop[day]<-gen1 | |
328 gen2.pop[day]<-gen2 | |
329 S0[day]<-s0 | |
330 S1[day]<-s1 | |
331 S2[day]<-s2 | |
332 S3[day]<-s3 | |
333 S4[day]<-s4 | |
334 S5[day]<-s5 | |
335 g0.adult[day]<-sum(vec.mat[,1]==0) | |
336 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)) | |
337 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)) | |
338 | |
339 | |
340 | |
341 N.newborn[day]<-n.newborn | |
342 N.death[day]<-n.death | |
343 N.adult[day]<-n.adult | |
344 print(c(day,n,n.adult)) | |
345 } | |
346 | |
347 proc.time() - ptm | |
348 dd.cum<-cumsum(dd.day) | |
349 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="opt$output") | |
350 | |
351 |