The Degree Days Validation Challenge is an opportunity for researchers and computer programmers to validate and share their code that computes degree days.
‘Degree days’ are a measure of accumulated heat. The concept was developed by biologists who realized that you can predict the growth of plants and insects by tallying the temperature each day, starting when they emerge. Today, degree day models are widely used in agriculture to predict crop growth and stages of insect pest development.
In practice, one computes degree days using hourly temperature data. In the event that hourly data are not available, one can also estimate degree days based on the daily minimum and maximum temperature. Several different forumula have been developed to estimate degree days from daily min and max temperature.
There are several mathematical formula that can be used to estimate degree days based on daily minimum and maximum temperature. One of the earliest papers to publish formulas for the different methods was Zalom et al (1983).
Zalom et al (1983) provide formula for different methods of
estimating degree days based on daily minimum and maximum
temperature
Sample equation for accumulated degree days for the single-sine method
Later authors developed variations of these formulas, including three types of cutoff methods: horizontal, vertical, and intermediate.
These formula have been used by researchers over the decades, and are the engine behind the Degree Day calculators on the UC ANR Integrated Pest Management (UC IPM) website.
Numerous researchers and web developers have written computer code to compute degrees for specific applications, using programming languages such as Fortran, Python, R, JavaScript, Matlab, Perl, and others, etc. To check whether your code works as expected, all researchers are invited to run their code on the reference dataset below, and optionally share their code.
Reference daily temperature dataset
The reference temperature dataset contains 1 year of daily minimum and maximum temperature values (°F) from the Esparto-A CIMIS weather station:
Preview:
library(dplyr)
daily_min_max_tbl = read.csv("./data/espartoa-weather-2020.csv")
nrow(daily_min_max_tbl)
## [1] 366
daily_min_max_tbl %>% slice(1:10)
## station date tmin tmax
## 1 Esparto.A 2020-01-01 38 55
## 2 Esparto.A 2020-01-02 36 67
## 3 Esparto.A 2020-01-03 33 59
## 4 Esparto.A 2020-01-04 37 59
## 5 Esparto.A 2020-01-05 38 63
## 6 Esparto.A 2020-01-06 36 58
## 7 Esparto.A 2020-01-07 30 53
## 8 Esparto.A 2020-01-08 41 50
## 9 Esparto.A 2020-01-09 37 53
## 10 Esparto.A 2020-01-10 32 55
To check the validity of your code, you should compute degree days for this dataset with a lower threshold of 50 and an upper threshold of 70. The reference dataset has tmin and tmax values that cover all six cases of relationship within this temperature range:
thresh_low = 50
thresh_high = 70
## Case 1: tmin < thresh_low; tmax < thresh_low
case1 = sum(daily_min_max_tbl$tmin < thresh_low &
daily_min_max_tbl$tmax < thresh_low)
case1
## [1] 3
## Case 2: tmin < thresh_low; tmax between thresh_low and thresh_high
case2 = sum(daily_min_max_tbl$tmin < thresh_low &
daily_min_max_tbl$tmax >= thresh_low &
daily_min_max_tbl$tmax <= thresh_high)
case2
## [1] 131
## Case 3: tmin between thresh_low and thresh_high; tmax between thresh_low and thresh_high
case3 = sum(daily_min_max_tbl$tmin >= thresh_low &
daily_min_max_tbl$tmin <= thresh_high &
daily_min_max_tbl$tmax >= thresh_low &
daily_min_max_tbl$tmax <= thresh_high)
case3
## [1] 6
## Case 4: tmin between thresh_low and thresh_high; tmax > thresh_high
case4 = sum(daily_min_max_tbl$tmin >= thresh_low &
daily_min_max_tbl$tmin <= thresh_high &
daily_min_max_tbl$tmax > thresh_high)
case4
## [1] 179
## Case 5: min > thresh_high; tmax > thresh_high
case5 = sum(daily_min_max_tbl$tmin > thresh_high &
daily_min_max_tbl$tmax > thresh_high)
case5
## [1] 4
## Case 6: tmin < thresh_low; tmax > thresh_high
case6 = sum(daily_min_max_tbl$tmin < thresh_low &
daily_min_max_tbl$tmax > thresh_high)
case6
## [1] 43
## The cases should add up to the number of rows (366)
case1 + case2 + case3 + case4 + case5 + case6
## [1] 366
TODO: need to add simple average method 1 and 2 (McMaster and Wilhelm, 1997)
The results from the UC IPM website shall serve as the correct answers. The UC IPM website has been the reference for degree day calculations for decades, and they have all the major methods available. The correct answers have been compiled into a single CSV file:
Preview:
answers_tbl = read.csv("./data/ucipm_results/ucipm_low50_high70_all.csv")
answers_tbl %>% slice(1:10)
## date tmin tmax sngsine_horiz sngsine_vert sngsine_intrmd dblsine_horiz dblsine_vert dblsine_intrmd sngtri_horiz
## 1 1/1/2020 38 55 1.19 1.19 1.19 1.15 1.15 1.15 0.74
## 2 1/2/2020 36 67 5.71 5.71 5.71 5.56 5.56 5.56 4.66
## 3 1/3/2020 33 59 2.34 2.34 2.34 2.45 2.45 2.45 1.56
## 4 1/4/2020 37 59 2.56 2.56 2.56 2.59 2.59 2.59 1.84
## 5 1/5/2020 38 63 4.23 4.23 4.23 4.14 4.14 4.14 3.38
## 6 1/6/2020 36 58 2.13 2.13 2.13 2.00 2.00 2.00 1.45
## 7 1/7/2020 30 53 0.47 0.47 0.47 0.56 0.56 0.56 0.20
## 8 1/8/2020 41 50 0.00 0.00 0.00 0.00 0.00 0.00 0.00
## 9 1/9/2020 37 53 0.56 0.56 0.56 0.53 0.53 0.53 0.28
## 10 1/10/2020 32 55 1.01 1.01 1.01 1.19 1.19 1.19 0.54
## sngtri_vert sngtri_intrmd dbltri_horiz dbltri_vert dbltri_intrmd
## 1 0.74 0.74 0.70 0.70 0.70
## 2 4.66 4.66 4.46 4.46 4.46
## 3 1.56 1.56 1.70 1.70 1.70
## 4 1.84 1.84 1.88 1.88 1.88
## 5 3.38 3.38 3.25 3.25 3.25
## 6 1.45 1.45 1.30 1.30 1.30
## 7 0.20 0.20 0.29 0.29 0.29
## 8 0.00 0.00 0.00 0.00 0.00
## 9 0.28 0.28 0.25 0.25 0.25
## 10 0.54 0.54 0.75 0.75 0.75
To re-generate the correct answers, go to the UC IPM website and upload the version of the reference data that has no headers.
If you have gone through all the trouble of coding up the degree day formulas, you should get some credit for it! Let us know about your results by starting a Github issue, and we will link them below. Your codes doesn’t have to support every single method, but it should present the comparisons to the answers. If you’re willing to share your code with others, please put enough description and links so others can replicate your work.
When your submission is posted, you’ll be sent embed code to display the coveted degree-day-challenge badge on your site:
Library: HeatUnits
Author: Shane Feirer
Code: HeatUnits.py
Notebook: Heat
Units Test (HeatUnits_py.ipynb)
Results:
Method | Result |
---|---|
Single-sine (horizontal cutoff) | passing |
Double-sine (horizontal cutoff) | passing |
Single-triangle (horizontal cutoff) | passing |
Double-triangle (horizontal cutoff) | passing |
Single-sine (intermediate cutoff) | >95% passing |
Double-sine (intermediate cutoff) | >95% passing |
Single-triangle (intermediate cutoff) | >95% passing |
Double-triangle (intermediate cutoff) | >95% passing |
Single-sine (vertical cutoff) | >95% passing |
Double-sine (vertical cutoff) | >95% passing |
Single-triangle (vertical cutoff) | >95% passing |
Double-triangle (vertical cutoff) | >95% passing |
Library: degday
Author: Andy Lyons
Code: degday
Notebook: degday
Tests (degday_R.Rmd)
Results:
Method | Result |
---|---|
Single-sine (horizontal cutoff) | passing |
Double-sine (horizontal cutoff) | passing |
Single-triangle (horizontal cutoff) | passing |
Double-triangle (horizontal cutoff) | passing |
No submissions yet
No submissions yet