Mercurial > repos > greg > insect_phenology_model
comparison insect_phenology_model.R @ 39:169c8180205a draft
Uploaded
author | greg |
---|---|
date | Wed, 11 Apr 2018 11:26:53 -0400 |
parents | c0f76f4f84fc |
children | d8e6304dc5e4 |
comparison
equal
deleted
inserted
replaced
38:c0f76f4f84fc | 39:169c8180205a |
---|---|
119 # F2 mean. | 119 # F2 mean. |
120 f2_m = apply(f2_replications, 1, mean); | 120 f2_m = apply(f2_replications, 1, mean); |
121 # F2 standard error. | 121 # F2 standard error. |
122 f2_se = apply(f2_replications, 1, sd) / sqrt(opt$replications); | 122 f2_se = apply(f2_replications, 1, sd) / sqrt(opt$replications); |
123 return(list(p_m, p_se, f1_m, f1_se, f2_m, f2_se)) | 123 return(list(p_m, p_se, f1_m, f1_se, f2_m, f2_se)) |
124 } | |
125 | |
126 get_next_normals_row = function(norm_data_frame, year, is_leap_year, index) { | |
127 # Return the next 30 year normals row formatted | |
128 # appropriately for the year-to-date data. | |
129 latitude = norm_data_frame[index,"LATITUDE"][1]; | |
130 longitude = norm_data_frame[index,"LONGITUDE"][1]; | |
131 # Format the date. | |
132 mmdd = norm_data_frame[index,"MMDD"][1]; | |
133 date_str = paste(year, mmdd, sep="-"); | |
134 doy = norm_data_frame[index,"DOY"][1]; | |
135 if (!is_leap_year) { | |
136 # Since all normals data includes Feb 29, we have to | |
137 # subtract 1 from DOY if we're not in a leap year since | |
138 # we removed the Feb 29 row from the data frame above. | |
139 doy = as.integer(doy) - 1; | |
140 } | |
141 tmin = norm_data_frame[index,"TMIN"][1]; | |
142 tmax = norm_data_frame[index,"TMAX"][1]; | |
143 return(list(latitude, longitude, date_str, doy, tmin, tmax)); | |
124 } | 144 } |
125 | 145 |
126 get_temperature_at_hour = function(latitude, temperature_data_frame, row, num_days) { | 146 get_temperature_at_hour = function(latitude, temperature_data_frame, row, num_days) { |
127 # Base development threshold for Brown Marmorated Stink Bug | 147 # Base development threshold for Brown Marmorated Stink Bug |
128 # insect phenology model. | 148 # insect phenology model. |
220 } | 240 } |
221 | 241 |
222 get_total_days = function(is_leap_year) { | 242 get_total_days = function(is_leap_year) { |
223 # Get the total number of days in the current year. | 243 # Get the total number of days in the current year. |
224 if (is_leap_year) { | 244 if (is_leap_year) { |
225 return (366); | 245 return(366); |
226 } else { | 246 } else { |
227 return (365); | 247 return(365); |
228 } | 248 } |
229 } | 249 } |
230 | 250 |
231 get_x_axis_ticks_and_labels = function(temperature_data_frame, num_rows, num_days_ytd) { | 251 get_x_axis_ticks_and_labels = function(temperature_data_frame, num_rows, start_doy_ytd, end_doy_ytd) { |
232 # Keep track of the years to see if spanning years. | 252 # Keep track of the years to see if spanning years. |
233 month_labels = list(); | 253 month_labels = list(); |
234 ticks = list(); | 254 ticks = list(); |
235 current_month_label = NULL; | 255 current_month_label = NULL; |
236 last_tick = 0; | 256 last_tick = 0; |
237 for (i in 1:num_rows) { | 257 for (i in 1:num_rows) { |
238 if (i==num_days_ytd) { | 258 if (start_doy_ytd > 1 & i==start_doy_ytd-1) { |
239 # Add a tick for the start of the 30 year normnals data. | 259 # Add a tick for the end of the 30 year normnals data |
260 # that was prepended to the year-to-date data. | |
240 tick_index = get_tick_index(i, last_tick, ticks, month_labels) | 261 tick_index = get_tick_index(i, last_tick, ticks, month_labels) |
241 ticks[tick_index] = i; | 262 ticks[tick_index] = i; |
242 month_labels[tick_index] = "Start 30 year normals"; | 263 month_labels[tick_index] = "End prepended 30 year normals"; |
243 last_tick = i; | 264 last_tick = i; |
244 } | 265 } else if (i==end_doy_ytd+1) { |
245 # Get the year and month from the date which | 266 # Add a tick for the start of the 30 year normnals data |
246 # has the format YYYY-MM-DD. | 267 # that was appended to the year-to-date data. |
247 date = format(temperature_data_frame$DATE[i]); | 268 tick_index = get_tick_index(i, last_tick, ticks, month_labels) |
248 # Get the month label. | |
249 items = strsplit(date, "-")[[1]]; | |
250 month = items[2]; | |
251 month_label = month.abb[as.integer(month)]; | |
252 tick_index = get_tick_index(i, last_tick, ticks, month_labels) | |
253 if (!identical(current_month_label, month_label)) { | |
254 # Add an x-axis tick for the month. | |
255 ticks[tick_index] = i; | 269 ticks[tick_index] = i; |
256 month_labels[tick_index] = month_label; | 270 month_labels[tick_index] = "Start appended 30 year normals"; |
257 current_month_label = month_label; | |
258 last_tick = i; | 271 last_tick = i; |
259 } | 272 } else if (i==num_rows) { |
260 tick_index = get_tick_index(i, last_tick, ticks, month_labels) | |
261 if (!is.null(tick_index)) { | |
262 # Get the day. | |
263 day = weekdays(as.Date(date)); | |
264 if (day=="Sunday") { | |
265 # Add an x-axis tick if we're on a Sunday. | |
266 ticks[tick_index] = i; | |
267 # Add a blank month label so it is not displayed. | |
268 month_labels[tick_index] = ""; | |
269 last_tick = i; | |
270 } | |
271 } | |
272 if (i==num_rows) { | |
273 # Add a tick for the last day of the year. | 273 # Add a tick for the last day of the year. |
274 tick_index = get_tick_index(i, last_tick, ticks, month_labels) | 274 tick_index = get_tick_index(i, last_tick, ticks, month_labels) |
275 ticks[tick_index] = i; | 275 ticks[tick_index] = i; |
276 month_labels[tick_index] = ""; | 276 month_labels[tick_index] = ""; |
277 last_tick = i; | 277 last_tick = i; |
278 } else { | |
279 # Get the year and month from the date which | |
280 # has the format YYYY-MM-DD. | |
281 date = format(temperature_data_frame$DATE[i]); | |
282 # Get the month label. | |
283 items = strsplit(date, "-")[[1]]; | |
284 month = items[2]; | |
285 month_label = month.abb[as.integer(month)]; | |
286 if (!identical(current_month_label, month_label)) { | |
287 # Add an x-axis tick for the month. | |
288 tick_index = get_tick_index(i, last_tick, ticks, month_labels) | |
289 ticks[tick_index] = i; | |
290 month_labels[tick_index] = month_label; | |
291 current_month_label = month_label; | |
292 last_tick = i; | |
293 } | |
294 tick_index = get_tick_index(i, last_tick, ticks, month_labels) | |
295 if (!is.null(tick_index)) { | |
296 # Get the day. | |
297 day = weekdays(as.Date(date)); | |
298 if (day=="Sunday") { | |
299 # Add an x-axis tick if we're on a Sunday. | |
300 ticks[tick_index] = i; | |
301 # Add a blank month label so it is not displayed. | |
302 month_labels[tick_index] = ""; | |
303 last_tick = i; | |
304 } | |
305 } | |
278 } | 306 } |
279 } | 307 } |
280 return(list(ticks, month_labels)); | 308 return(list(ticks, month_labels)); |
281 } | 309 } |
282 | 310 |
284 # Extract the year from the date_str. | 312 # Extract the year from the date_str. |
285 date = format(date_str); | 313 date = format(date_str); |
286 items = strsplit(date, "-")[[1]]; | 314 items = strsplit(date, "-")[[1]]; |
287 year = as.integer(items[1]); | 315 year = as.integer(items[1]); |
288 if (((year %% 4 == 0) & (year %% 100 != 0)) | (year %% 400 == 0)) { | 316 if (((year %% 4 == 0) & (year %% 100 != 0)) | (year %% 400 == 0)) { |
289 return (TRUE); | 317 return(TRUE); |
290 } else { | 318 } else { |
291 return (FALSE); | 319 return(FALSE); |
292 } | 320 } |
293 } | 321 } |
294 | 322 |
295 mortality.adult = function(temperature) { | 323 mortality.adult = function(temperature) { |
296 if (temperature < 12.7) { | 324 if (temperature < 12.7) { |
334 colnames(temperature_data_frame) = c("LATITUDE", "LONGITUDE", "DATE", "DOY", "TMIN", "TMAX"); | 362 colnames(temperature_data_frame) = c("LATITUDE", "LONGITUDE", "DATE", "DOY", "TMIN", "TMAX"); |
335 # Get the start date. | 363 # Get the start date. |
336 start_date = temperature_data_frame$DATE[1]; | 364 start_date = temperature_data_frame$DATE[1]; |
337 # See if we're in a leap year. | 365 # See if we're in a leap year. |
338 is_leap_year = is_leap_year(start_date); | 366 is_leap_year = is_leap_year(start_date); |
339 # get the number of days in the year. | 367 # Get the number of days in the year. |
340 total_days = get_total_days(is_leap_year); | 368 total_days = get_total_days(is_leap_year); |
341 # Extract the year from the start date. | 369 # Extract the year from the start date. |
342 date_str = format(start_date); | 370 date_str = format(start_date); |
343 date_str_items = strsplit(date_str, "-")[[1]]; | 371 date_str_items = strsplit(date_str, "-")[[1]]; |
344 year = date_str_items[1]; | 372 year = date_str_items[1]; |
373 # Save the first DOY to later check if start_date is Jan 1. | |
374 start_doy_ytd = as.integer(temperature_data_frame$DOY[1]); | |
375 end_doy_ytd = as.integer(temperature_data_frame$DOY[num_days_ytd]); | |
345 # Read the input_norm temperature datafile into a data frame. | 376 # Read the input_norm temperature datafile into a data frame. |
346 # The input_norm data has the following 10 columns: | 377 # The input_norm data has the following 10 columns: |
347 # STATIONID, LATITUDE, LONGITUDE, ELEV_M, NAME, ST, MMDD, DOY, TMIN, TMAX | 378 # STATIONID, LATITUDE, LONGITUDE, ELEV_M, NAME, ST, MMDD, DOY, TMIN, TMAX |
348 norm_data_frame = read.csv(file=input_norm, header=T, strip.white=TRUE, stringsAsFactors=FALSE, sep=","); | 379 norm_data_frame = read.csv(file=input_norm, header=T, strip.white=TRUE, stringsAsFactors=FALSE, sep=","); |
349 # Set the norm_data_frame column names for access. | 380 # Set the norm_data_frame column names for access. |
351 # All normals data includes Feb 29 which is row 60 in | 382 # All normals data includes Feb 29 which is row 60 in |
352 # the data, so delete that row if we're not in a leap year. | 383 # the data, so delete that row if we're not in a leap year. |
353 if (!is_leap_year) { | 384 if (!is_leap_year) { |
354 norm_data_frame = norm_data_frame[-c(60),]; | 385 norm_data_frame = norm_data_frame[-c(60),]; |
355 } | 386 } |
356 # Define the next row for the temperature_data_frame from the 30 year normals data. | 387 if (start_doy_ytd > 1) { |
357 first_normals_row = num_days_ytd + 1; | 388 # The year-to-date data starts after Jan 1, so create a |
358 for (i in first_normals_row:total_days) { | 389 # temporary data frame to contain the 30 year normals data |
359 latitude = norm_data_frame[i,"LATITUDE"][1]; | 390 # from Jan 1 to the date immediately prior to start_date. |
360 longitude = norm_data_frame[i,"LONGITUDE"][1]; | 391 tmp_data_frame = temperature_data_frame[FALSE,]; |
361 # Format the date. | 392 for (i in 1:start_doy_ytd-1) { |
362 mmdd = norm_data_frame[i,"MMDD"][1]; | 393 tmp_data_frame[i,] = get_next_normals_row(norm_data_frame, year, is_leap_year, i); |
363 date_str = paste(year, mmdd, sep="-"); | 394 } |
364 doy = norm_data_frame[i,"DOY"][1]; | 395 # Next merge the temporary data frame with the year-to-date data frame. |
365 if (!is_leap_year) { | 396 temperature_data_frame = rbind(tmp_data_frame, temperature_data_frame); |
366 # Since all normals data includes Feb 29, we have to | 397 } |
367 # subtract 1 from DOY if we're not in a leap year since | 398 # Define the next row for the year-to-date data from the 30 year normals data. |
368 # we removed the Feb 29 row from the data frame above. | 399 first_normals_append_row = end_doy_ytd + 1; |
369 doy = as.integer(doy) - 1; | 400 # Append the 30 year normals data to the year-to-date data. |
370 } | 401 for (i in first_normals_append_row:total_days) { |
371 tmin = norm_data_frame[i,"TMIN"][1]; | 402 temperature_data_frame[i,] = get_next_normals_row(norm_data_frame, year, is_leap_year, i); |
372 tmax = norm_data_frame[i,"TMAX"][1]; | |
373 # Append the row to temperature_data_frame. | |
374 new_row = list(latitude, longitude, date_str, doy, tmin, tmax); | |
375 temperature_data_frame[i,] = new_row; | |
376 } | 403 } |
377 # Add a column containing the daylight length for each day. | 404 # Add a column containing the daylight length for each day. |
378 temperature_data_frame = add_daylight_length(temperature_data_frame, total_days); | 405 temperature_data_frame = add_daylight_length(temperature_data_frame, total_days); |
379 return(temperature_data_frame); | 406 return(list(temperature_data_frame, start_date, start_doy_ytd, end_doy_ytd, is_leap_year, total_days)); |
380 } | 407 } |
381 | 408 |
382 render_chart = function(ticks, date_labels, chart_type, plot_std_error, insect, location, latitude, start_date, end_date, days, maxval, | 409 render_chart = function(ticks, date_labels, chart_type, plot_std_error, insect, location, latitude, start_date, end_date, days, maxval, |
383 replications, life_stage, group, group_std_error, group2=NULL, group2_std_error=NULL, group3=NULL, group3_std_error=NULL, | 410 replications, life_stage, group, group_std_error, group2=NULL, group2_std_error=NULL, group3=NULL, group3_std_error=NULL, |
384 life_stages_adult=NULL, life_stages_nymph=NULL) { | 411 life_stages_adult=NULL, life_stages_nymph=NULL) { |
385 if (chart_type=="pop_size_by_life_stage") { | 412 if (chart_type=="pop_size_by_life_stage") { |
386 if (life_stage=="Total") { | 413 if (life_stage=="Total") { |
387 title = paste(insect, ": Reps", replications, ":", life_stage, "Pop :", location, ": Lat", latitude, ":", start_date, "-", end_date, sep=" "); | 414 title = paste(insect, ": Reps", replications, ":", life_stage, "Pop :", location, ": Lat", latitude, ":", start_date, "-", end_date, sep=" "); |
388 legend_text = c("Egg", "Nymph", "Adult"); | 415 legend_text = c("Egg", "Nymph", "Adult"); |
389 columns = c(4, 2, 1); | 416 columns = c(4, 2, 1); |
470 plot_generations_separately = FALSE; | 497 plot_generations_separately = FALSE; |
471 } | 498 } |
472 # Display the total number of days in the Galaxy history item blurb. | 499 # Display the total number of days in the Galaxy history item blurb. |
473 cat("Year-to-date number of days: ", opt$num_days_ytd, "\n"); | 500 cat("Year-to-date number of days: ", opt$num_days_ytd, "\n"); |
474 | 501 |
475 # Read the temperature data into a data frame. | 502 # Parse the inputs. |
476 temperature_data_frame = parse_input_data(opt$input_ytd, opt$input_norm, opt$num_days_ytd); | 503 data_list = parse_input_data(opt$input_ytd, opt$input_norm, opt$num_days_ytd); |
504 temperature_data_frame = data_list[[1]]; | |
505 # Information needed for plots. | |
506 start_date = data_list[[2]]; | |
507 end_date = temperature_data_frame$DATE[opt$num_days_ytd]; | |
508 start_doy_ytd = data_list[[3]]; | |
509 end_doy_ytd = data_list[[4]]; | |
510 is_leap_year = data_list[[5]]; | |
511 total_days = data_list[[6]]; | |
512 total_days_vector = c(1:total_days); | |
477 | 513 |
478 # Create copies of the temperature data for generations P, F1 and F2 if we're plotting generations separately. | 514 # Create copies of the temperature data for generations P, F1 and F2 if we're plotting generations separately. |
479 if (plot_generations_separately) { | 515 if (plot_generations_separately) { |
480 temperature_data_frame_P = data.frame(temperature_data_frame); | 516 temperature_data_frame_P = data.frame(temperature_data_frame); |
481 temperature_data_frame_F1 = data.frame(temperature_data_frame); | 517 temperature_data_frame_F1 = data.frame(temperature_data_frame); |
482 temperature_data_frame_F2 = data.frame(temperature_data_frame); | 518 temperature_data_frame_F2 = data.frame(temperature_data_frame); |
483 } | 519 } |
484 | 520 |
485 # Information needed for plots. | |
486 start_date = temperature_data_frame$DATE[1]; | |
487 end_date = temperature_data_frame$DATE[opt$num_days_ytd]; | |
488 # See if we're in a leap year. | |
489 is_leap_year = is_leap_year(start_date); | |
490 total_days = get_total_days(is_leap_year); | |
491 total_days_vector = c(1:total_days); | |
492 | |
493 # Get the ticks date labels for plots. | 521 # Get the ticks date labels for plots. |
494 ticks_and_labels = get_x_axis_ticks_and_labels(temperature_data_frame, total_days, opt$num_days_ytd); | 522 ticks_and_labels = get_x_axis_ticks_and_labels(temperature_data_frame, total_days, start_doy_ytd, end_doy_ytd); |
495 ticks = c(unlist(ticks_and_labels[1])); | 523 ticks = c(unlist(ticks_and_labels[1])); |
496 date_labels = c(unlist(ticks_and_labels[2])); | 524 date_labels = c(unlist(ticks_and_labels[2])); |
497 # All latitude values are the same, so get the value for plots from the first row. | 525 # All latitude values are the same, so get the value for plots from the first row. |
498 latitude = temperature_data_frame$LATITUDE[1]; | 526 latitude = temperature_data_frame$LATITUDE[1]; |
499 | 527 |