# Chapter 7 Chill models

## Learning goals for this lesson

- Learn how to run chill models using
`chillR`

- Learn how to produce your own temperature response model in
`chillR`

## 7.1 Chill models in `chillR`

We already learned how to write a function to calculate Chilling Hours. Unfortunately, you may never have to do that, because `chillR`

already contains such a function. It’s called `Chilling_Hours()`

, and here’s what it looks like:

```
## function (HourTemp, summ = TRUE)
## {
## CH_range <- which(HourTemp <= 7.2 & HourTemp >= 0)
## CH_weights <- rep(0, length(HourTemp))
## CH_weights[CH_range] <- 1
## if (summ == TRUE)
## return(cumsum(CH_weights))
## else return(CH_weights)
## }
## <bytecode: 0x000001fbd0657c38>
## <environment: namespace:chillR>
```

This is a pretty basic function that takes an hourly temperature dataset (`HourTemp`

) as input and determines for each hour if temperatures are below 7.2°C and above 0°C. If the argument `summ`

is `TRUE`

, the function returns the cumulative Chilling Hours that have accumulated by every hour of the record. If this argument is `FALSE`

, we just get a list of 1s and 0s to indicate which hours are Chilling Hours and which ones aren’t. The default version of the function is to run it with `summ==TRUE`

, as you can see in the first line of the function. So if you don’t specify anything for the `summ`

argument, it will return the cumulative sum of Chilling Hours.

We can easily apply this now to our `Winters_hours_gap`

dataset:

```
## [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 2 3 4 5 6
## [23] 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
## [45] 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 8 9 10 11
## [67] 12 13 14 15 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 17 18 19
## [89] 20 21 22 23 24 25 25 25 25 25 25 25
```

I only returned the first 100 values. The dataset contains 5974 more. The last number in this entire series is 203.

Chilling Hours are great for an entry-level tutorial on chill modeling, but they’re not a particularly credible metric, so I suggest you forget them right away. Let’s turn our eyes towards more credible models.

The Utah Model (Richardson et al., 1974) is somewhat more credible, since it assumes different weights for different temperatures. This model is also implemented in `chillR`

:

```
## function (HourTemp, summ = TRUE)
## return(step_model(HourTemp, df = data.frame(lower = c(-1000,
## 1.4, 2.4, 9.1, 12.4, 15.9, 18), upper = c(1.4, 2.4, 9.1,
## 12.4, 15.9, 18, 1000), weight = c(0, 0.5, 1, 0.5, 0, -0.5,
## -1)), summ = summ))
## <bytecode: 0x000001fbd43ebb38>
## <environment: namespace:chillR>
```

```
## [1] 0.0 -0.5 -1.5 -2.5 -3.5 -4.5 -5.5 -6.0 -6.0 -6.0 -5.5 -5.0 -4.0
## [14] -3.0 -2.0 -1.0 0.0 0.5 1.5 2.5 3.5 4.5 5.0 5.0 5.0 4.0
## [27] 3.0 2.0 1.0 0.0 -1.0 -2.0 -2.5 -2.5 -2.0 -1.5 -1.0 -0.5 0.5
## [40] 1.0 1.5 2.0 2.0 2.5 3.0 3.5 4.0 4.0 4.0 3.5 2.5 1.5
## [53] 0.5 -0.5 -1.5 -2.5 -3.0 -3.0 -2.5 -1.5 -0.5 0.5 1.5 2.5 3.5
## [66] 4.5 5.5 6.5 7.5 8.5 9.5 10.0 10.0 9.5 9.0 8.5 8.0 7.5
## [79] 7.0 6.5 6.5 7.0 7.5 8.5 9.5 10.5 11.5 12.5 13.5 14.5 15.5
## [92] 16.5 17.5 18.5 19.0 19.0 19.0 18.5 17.5 16.5
```

In the definition of this model, you see another function called `step_model()`

. This is also a `chillR`

function, which allows you to define your own model, based on temperature thresholds and weights. You could, for example, use this function to implement various variations of the Utah Model that have been developed for different locations. The function takes as input a `data.frame`

that contains the weights you want to apply to different temperature ranges.

Here’s an example of such a `data.frame`

, a function called `custom()`

that implements a chill model based on this, and the application of this function to the `Winters_hours_gaps`

dataset:

```
df<-data.frame(
lower= c(-1000, 1, 2, 3, 4, 5, 6),
upper= c( 1, 2, 3, 4, 5, 6, 1000),
weight=c( 0, 1, 2, 3, 2, 1, 0))
kable(df) %>%
kable_styling("striped", position = "left", font_size = 10)
```

lower | upper | weight |
---|---|---|

-1000 | 1 | 0 |

1 | 2 | 1 |

2 | 3 | 2 |

3 | 4 | 3 |

4 | 5 | 2 |

5 | 6 | 1 |

6 | 1000 | 0 |

```
## [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 4 7
## [23] 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
## [45] 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 10
## [67] 13 16 19 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 23
## [89] 25 27 29 31 34 37 37 37 37 37 37 37
```

The Chilling Hours and Utah Models are fairly straightforward. We could probably have calculated these metrics without these functions, though of course the process gets easier with them. What has long been a much greater challenge to dormancy modelers is implementing the ‘Dynamic Model’, which involves pretty complicated equations. The original papers on this model were rather heavy on maths, leaving many horticultural researchers a bit lost. For a long time, the only version of the model that people could easily use was an Excel sheet that was put together a few decades ago. For `chillR`

, I extracted all the equations from this Excel sheet, to make the `Dynamic_Model()`

function. This is pretty complicated, and a bit of effort was needed to get this right. But the effort was worth it - now we’ll never have to deal with these equations again, because we have a function that does all the calculations for us.

```
## [1] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
## [7] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
## [13] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
## [19] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
## [25] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
## [31] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
## [37] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
## [43] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
## [49] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
## [55] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
## [61] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
## [67] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.9698435
## [73] 0.9698435 0.9698435 0.9698435 0.9698435 0.9698435 0.9698435
## [79] 0.9698435 0.9698435 0.9698435 0.9698435 0.9698435 0.9698435
## [85] 0.9698435 0.9698435 0.9698435 0.9698435 0.9698435 0.9698435
## [91] 0.9698435 0.9698435 0.9698435 0.9698435 0.9698435 0.9698435
## [97] 0.9698435 0.9698435 0.9698435 0.9698435
```

So `chillR`

has a few functions that can be applied to hourly temperature data. It also has wrapper functions that allow computing chill between specific start and end dates. The `chilling()`

function automatically calculates a few basic metrics for us. Note that we have to use the `chillR`

function `make_JDay()`

here to add the Julian dates (counts the days of the year) to the dataset for this to work.

```
output<-chilling(make_JDay(Winters_hours_gaps),Start_JDay = 90, End_JDay = 100)
kable(output) %>%
kable_styling("striped", position = "left", font_size = 10)
```

Season | End_year | Season_days | Data_days | Perc_complete | Chilling_Hours | Utah_Model | Chill_portions | GDH |
---|---|---|---|---|---|---|---|---|

2007/2008 | 2008 | 11 | 11 | 100 | 40 | 15.5 | 2.009147 | 2406.52 |

So the `chilling()`

function implements the Chilling Hours, Utah and Dynamic Models, and it also calculates Growing Degree Days (GDH). But maybe we don’t want all of these, or we want other metrics. In that case, we can make use of the `tempResponse`

function, which is somewhat similar to `chilling()`

, but it takes as input a list of temperature models to be computed.

```
output<-tempResponse(make_JDay(Winters_hours_gaps),
Start_JDay = 90, End_JDay = 100,
models=list(Chill_Portions=Dynamic_Model, GDH=GDH))
kable(output) %>%
kable_styling("striped", position = "left", font_size = 10)
```

Season | End_year | Season_days | Data_days | Perc_complete | Chill_Portions | GDH |
---|---|---|---|---|---|---|

2007/2008 | 2008 | 11 | 11 | 100 | 2.009147 | 2406.52 |

`Exercises`

on chill models

Please document all results of the following assignments in your `learning logbook`

.

- Run the
`chilling()`

function on the`Winters_hours_gap`

dataset - Create your own temperature-weighting chill model using the
`step_model()`

function - Run this model on the
`Winters_hours_gaps`

dataset using the`tempResponse()`

function.

### References

*HortScience*,

*9*(4), 331–332.