---
title: "User Guide"
subtitle: "Package 'photobiologyPlants' `r packageVersion('photobiologyPlants')` "
author: "Pedro J. Aphalo"
date: "`r Sys.Date()`"
output: 
  rmarkdown::html_vignette:
    toc: yes
vignette: >
  %\VignetteIndexEntry{User Guide}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include=FALSE, echo=FALSE}
knitr::opts_chunk$set(fig.width=7.2, fig.height=4.3)
```

```{r, printing-spectra, eval=TRUE, include=FALSE}
# library(tibble)
old.options <- options(tibble.print_max = 6, tibble.print_min = 4)
```

## Introduction

This package provides data sets and functions relevant to the photobiology of
plants. It is part of a suite, which has package 'photobiology' at its core. Its
documentation is also available on-line as a [website](https://docs.r4photobiology.info/photobiologyPlants/).
For plotting spectra, please consult the documentation for package
['ggspectra'](https://docs.r4photobiology.info/ggspectra/), and for information on the calculation of summaries and maths
operations between spectra, please, consult the documentation of package
['photobiology'](https://docs.r4photobiology.info/photobiology/).

See the User Guides for packages 'photobiology' and 'ggspectra' for instructions
on how to work with spectral data. As package 'ggspectra' is only suggested, in
this vignette it is loaded an used conditionally on its availability.

```{r,message=FALSE}
library(photobiology)
library(photobiologyPlants)
library(photobiologyWavebands)
eval_plots <- requireNamespace("ggspectra", quietly = TRUE)
if (eval_plots) library(ggspectra)

theme_set(theme_bw())
```

## Light environment
### Photon ratios

`R_FR()` and other functions for computing photon ratios are convenience 
functions implemented using function `q_ratio()` and `q_irrad()` from package
'photobiology' and waveband definitions from package 'photobiologyWavebands'
with defaults arguments to parameter `std` for wavelength ranges commonly used 
in the field of _plant photobiology_. These functions can be used with one or 
more spectra as argument.

```{r}
R_FR(sun.spct)
```

Here, the argument named `attr2tb` is forwarded to method `q_ratio` from 
package 'photobiology' to copy metadata from the spectra into the returned
data frame.

```{r}
R_FR(sun_evening.spct, 
     std = "Smith20", 
     attr2tb = c("when.measured" = "time.UTC", "lat" = "latitude"))
```

## Photoreceptors

###  Phytochromes: photoequilibrium

In the examples below we use the solar spectral data included in package 'photobiology' in object `sun.spct` of class `source_spct`. 

We can calculate the phytochrome photoequilibrium from spectral irradiance data as follows.

```{r}
Pfr_Ptot(sun.spct)
```

```{r}
Pfr_Ptot(sun_evening.spct, 
     attr2tb = c("when.measured" = "time.UTC", "lat" = "latitude"))
```

We can also calcualte the red:far-red photon ratio, in this third example, for the same spectrum as in the first example

```{r}
R_FR(sun.spct)
```

which is equivalent to calculating it using package 'photobiology' directly

```{r}
q_ratio(sun.spct, Red("Smith10"), Far_red("Smith10"))
```

We can, and should whenever spectral data are available, calculate the photoequilibrium as above, directly from these data. It is possible to obtain and approximation in case of the solar spectrum and other broad spectra, using the red:far-red photon ratio. The calculation, however, is only strictly valid, for di-chromatic illumination with red plus far-red light. 

```{r}
Pfr_Ptot_R_FR(R_FR(sun.spct))
```
```{r}
Pfr_Ptot_R_FR(R_FR(sun.spct, std = "Smith10"))
```

Here we calculated the R:FR ratio from spectral data, but in practice one would use this function only when spectral data is not available such as when a R plus FR sensor is used. We can see that in such a case the photoequilibrium calculated is only a  rough approximation. For sunlight, in the example above when using spectral data we obtained a value of `r signif(Pfr_Ptot(sun.spct), 3)` in contrast to `r signif(Pfr_Ptot_R_FR(R_FR(sun.spct)), 3)` when using the R:FR photon ratio. For other light sources differences can be much larger. Furthermore, here we used the true R:FR ratio calculated from the spectrum, while broad-band red:far-red sensors give only an approximation, which is good for sunlight, but which will be inaccurate for artificial light, unless a special calibration is done for each type of lamp. There are differences in the wavelength sensitivity between sensors from different suppliers and even between models from a given supplier. In addition, as the definition of the R:FR photon ratio used as the basis for calibration by different suppliers is not the same, the R:FR reported by difference sensors varies even under sunlight.

In the case of monochromatic light we can still use the same functions, as the defaults are such that we can use a single value as the 'w.length' argument, to obtain the Pfr:P ratio. For monochromatic light, irradiance is irrelevant for the photoequilibrium (steady-state).

```{r}
Pfr_Ptot(660)
Pfr_Ptot(735)
Pfr_Ptot(c(660, 735))
Pfr_Ptot(435)
```

We can also plot Pfr:Ptot as a function of wavelength (nm) of monochromatic light. The default is to return a vector for short input vectors, and a `response_spct` object otherwise, but this can be changed through argument `spct.out`.

```{r, eval = eval_plots}
autoplot(Pfr_Ptot(300:770), unit.out = "photon",
         w.band = Plant_bands(),
         annotations = c("colour.guide", "labels", "boxes")) +
  labs(y = "Phytochrome photoequilibrium, Pfr:Ptot ratio")
```

It is, of course, also possible to use base R plotting functions, or as shown here functions from package 'ggplot2'

```{r, eval = eval_plots}
ggplot(data = Pfr_Ptot(300:770), aes(w.length, s.q.response)) +
  geom_line() +
  labs(x = "Wavelength (nm)",
       y = "Phytochrome photoequilibrium, Pfr:Ptot ratio")
```

In the case of dichromatic illumination with red (660 nm) and far-red (730 nm) light, we can use a function that takes the R:FR photon ratio as argument.

**These computations are valid only for true mixes of light at these two wavelengths but not valid for broad spectra like sunlight and especially
inaccurate for plant growth lamps with peaks in their output spectrum, such as most discharge lamps (sodium, mercury, multi-metal, fluorescent tubes) and many LED lamps.** 

```{r}
Pfr_Ptot_R_FR(1.15)
Pfr_Ptot_R_FR(0.01)
Pfr_Ptot_R_FR(c(1.15,0.01))
```

It is also easy to plot Pfr:P ratio as a function of R:FR photon ratio. However we have to remember that such values are exact only for dichromatic light, and only a very rough approximation for wide-spectrum light sources. For wide-spectrum light sources, the photoequilibrium should, if possible, be calculated from spectral irradiance data.

```{r}
ex6.data <- data.frame(r.fr=seq(0.01, 5.0, length.out=100), Pfr.p=numeric(100))
ex6.data$Pfr.p <- Pfr_Ptot_R_FR(ex6.data$r.fr)
ggplot(data=ex6.data, aes(r.fr, Pfr.p)) +
  geom_line() +
  expand_limits(y = 0) +
    labs(x ="R:FR photon ratio",
         y = "Phytochrome photoequilibrium, Pfr:Ptot ratio")

```

###  Phytochromes:  reaction rates

```{r}
with(clip_wl(sun.spct, c(300,770)), 
     Phy_reaction_rates(w.length, s.e.irrad))
```

### Phytochromes: absorption cross section at given wavelengths

The phytochrome photoequilibrium cannot be calculated from the absorptance spectra of Pr and Pfr, because Pr and Pfr have different quantum yields for the respective phototransformations. We need to use action spectra, which in this context are usually called 'absorption cross-sections'. They can be calculated as the product of absorptance and quantum yield. The values in these spectra, in the case of Phy are usually named `Sigma'.

Here we reproduce Figure 3 in Mancinelli (1994), which gives the 'Relative photoconversion cross-sections' of Pr ($\sigma_R$) and Pfr ($\sigma_{FR}$). The values are expressed relative to $\sigma_R$ at its maximum at $\lambda = 666$ nm.

```{r, eval = eval_plots}
ex7.data <- data.frame(w.length=seq(300, 770, length.out=100))
ex7.data$sigma.r <- Phy_Sigma_R(ex7.data$w.length)
ex7.data$sigma.fr <- Phy_Sigma_FR(ex7.data$w.length)
ex7.data$sigma <- Phy_Sigma(ex7.data$w.length)
ggplot(ex7.data, aes(x = w.length)) +
  geom_line(aes(y = sigma.r/ max(sigma.r)), colour = "red") +
  geom_line(aes(y = sigma.fr/ max(sigma.r))) +
  labs(x = "Wavelength (nm)", y = expression(sigma[R]~"and"~sigma[FR]))
rm(ex7.data)
```


### Cryptochromes: spectral absorbance

Cryptochromes are widely distributed in plants and animals. They are blue, green and UV-A1 photoreceptors, also functioning as magneto-receptors. Their absorption spectrum depends on illumination. While the role of CRY1 and CRY2 as plant photoreceptors is well demonstrated, the role of CRY3 as a plant photoreceptor remains controversial due to the lack of evidence.

```{r}
names(CRYs.mspct)
```

Here we approximate Figure 1.B from Banerjee et al.\ (2007).

```{r, eval = eval_plots}
A_as_default()
autoplot(CRYs.mspct$CRY2_dark)
```

```{r, eval = eval_plots, warning=FALSE}
autoplot(CRYs.mspct[c("CRY2_dark", "CRY2_light")])
```

```{r, eval = eval_plots, warning=FALSE}
autoplot(CRYs.mspct[c("CRY1_dark", "CRY1_light")])
```

```{r, eval = eval_plots}
autoplot(CRYs.mspct["CRY3_dark"], range = c(300,700))
```

```{r, eval = eval_plots}
ggplot(CRYs.mspct[c("CRY1_dark", "CRY2_dark", "CRY3_dark")]) +
  geom_line(aes(linetype = spct.idx)) +
  expand_limits(x = 300)
```

### Phototropins: spectral absorbance

Phototropins are blue photoreceptors in plants, involved playing multiple roles including in phototropism (growth towards the light) and in rapid stomatal opening in response to illumination.

```{r}
names(PHOTs.mspct)
```

```{r, eval = eval_plots}
autoplot(PHOTs.mspct[c("PHOT1_fluo", "PHOT2_fluo")]) +
  expand_limits(x = 300)
```

```{r, eval = eval_plots}
autoplot(PHOTs.mspct[c("PHOT1_dark", "PHOT1_light")])
```

### UVR8: spectral absorbance

UVR8 is a plant photoreceptor sensitivy to UV-B radiation. However, in sunlight because of the shape of the terrestrial spectrum of sunlight, it plays the role of an UV-B and UV-A2 receptor.

```{r}
autoplot(UVR8s.mspct)
```

### Zeitloupe proteins: spectral absorbance

This proteins are blue photoreceptors playing an important role in reproductive induction of plants.

```{r}
names(ZTLs.mspct)
```

```{r, eval = eval_plots}
autoplot(ZTLs.mspct) +
  expand_limits(x = 300)
```

## Mass pigments

The term _mass pigments_ is used to describe light absorbing molecules that absorb significant amount of the light or ultraviolet radiation inpinging on plants. They not only are inheritently good absorbers of radiation but are present in plant tissues at relatively high concentrations. Some like carotenoids play both a role in energy harvesting and in protection from excess energy. Chlorophylls main role is in energy harvest and that of flavonoids, cinnamic acids and other phenolics located in the epidermis mainly function as screens that protect the inner tissues of the leaves from excess radiation, especially UV. These spectra have been measured after extracting the pigments.

### Carotenoids

```{r}
A_as_default()
```

```{r}
names(carotenoids.mspct)
```

```{r, eval = eval_plots}
autoplot(carotenoids.mspct[1:4], 
         annotations = c("-", "labels", "boxes")) 
```

```{r, eval = eval_plots}
autoplot(carotenoids.mspct[5:length(carotenoids.mspct)], 
         annotations = c("-", "labels", "boxes")) 
```

### Chlorophylls

```{r}
A_as_default()
```

```{r}
names(chlorophylls.mspct)
```

```{r, eval = eval_plots}
autoplot(chlorophylls.mspct[c("Chl_a_DME", "Chl_b_DME")]) 
```

```{r, eval = eval_plots}
autoplot(chlorophylls.mspct[c("Chl_a_DME", "Chl_a_MethOH")]) 
```

### Fluorescence

```{r}
names(chlorophylls_fluorescence.mspct)
```

```{r, eval = eval_plots}
autoplot(chlorophylls_fluorescence.mspct[c("Chl_a_DME", "Chl_b_DME")]) 
```

```{r, eval = eval_plots}
autoplot(chlorophylls_fluorescence.mspct[c("Chl_a_DME", "Chl_a_MethOH")]) 
```

## Leaves

### Optical properties

The optical properties of leaves depend on the pigments the contain and on the anatomical structure of leaf tissues. In addition to absorption by pigments, light scattering within the leaf plays a central role. Scattering alters the route photons take within leaves increasing absorption and altering the shape of the absorption spectrum.

```{r}
Tfr_as_default()
```

```{r}
names(Solidago_altissima.mspct)
```

```{r, eval = eval_plots}
autoplot(Solidago_altissima.mspct$lower_adax) 
```

```{r, eval = eval_plots}
autoplot(Solidago_altissima.mspct$lower_abax) 
```

```{r, eval = eval_plots}
autoplot(as.filter_mspct(Betula_ermanii.mspct)) 
```

```{r, eval = eval_plots}
autoplot(as.reflector_mspct(Betula_ermanii.mspct)) 
```

### Fluorescence: UV excited

Pigments excited by the absorption of photons, release part of this energy as photons of lower energy, i.e., longer wavelength. The wavelengths of the emitted fluorescence is determined by the allowed energy states of electrons in molecules. The most obvious fluorescence in plants is the red fluorescence from chlorophylls. Leaves containing cinnamic acids in the epidermic, such as many grasses and sunflower, in addition to red fluorescence, usually emit blue and sometimes cyan fluorescence. Chlorophylls _a_ and _b_ differ in their spectra, emitting red fluorescence centred around two nearby but distinct wavelength.

```{r}
names(leaf_fluorescence.mspct)
```

```{r, eval = eval_plots, message=FALSE}
autoplot(leaf_fluorescence.mspct$wheat_Fo_ex355nm,
         span = 21)
```

### Photosynthesis: action spectra

The action spectrum of leaf photosynthesis differs from both the absorption spectra of the pigments and of whole leaves. One reason is that the effectiveness with which absorbed photons of different wavelengths drive electron transport is not the same. Furthermore, the response of photosynthesis to irradiance is not linear. Different species, differ in pigment concentrations and localization, anatomy and metabolic capacity. 

```{r, eval = eval_plots}
photon_as_default()
```

```{r}
names(McCree_photosynthesis.mspct)
```

```{r, eval = eval_plots}
autoplot(McCree_photosynthesis.mspct)
```

### Photosynthesis: plastoquinone redox state

The balance between the activation of photosystem 1 (PSI) and photosystem 2 (PSII) depends on the wavelength composition of the incoming radiation as the chlorophylls in the two photosystems absorb predominantly at slightly different wavelengths. The balance between PSI and PSII affects the redox state of the plastoquinone pool. Based on a published model for Arabidopsis fitted to the measured state of the pool under different light sources, it is possible to _roughly estimate_ how a given light source can affect the redox state. Thus, this model can be used, with care, to assess different light sources in relation to their _relative_ ability to drive PSI and PSII. **The actual balance between PSI and PSII acclimates to growing conditions and varies among plant species and genotypes!**

By default the published coefficients (Mattila et al, 2020, doi:10.1111/tpj.14983) are used with normalization based on PAR. These are default arguments making it possible the use of different ones, possibly for sensitivity analysis or if in the future values for other spacies or conditions become available.

```{r}
PQ_redox_state(sun.spct) # % in reduced state
```
Similarly as functions from package 'photobiology' metadata from spectra can be
transferred to the returned value.

```{r}
PQ_redox_state(sun.spct, attr2tb = "when.measured")
```

Collections of spectra are also supported.

```{r}
PQ_redox_state(sun_evening.mspct, attr2tb = "when.measured")
```

### Stomatal conductance

While in meteorology it is common to use stomatal resistances expressed based of
volume, in plant sciences their expression as molar conductances is currently
the norm. The conversion depends on the molar volume of air, which here is
treated as an ideal gas. By default $21^\circ \mathrm{C}$ for temperature and
101.3\ kPa for ambient pressure are used. `gs_mol2vol()` returns volumetric
conductance and its inverse is the resistance.

```{r}
1 / gs_mol2vol(0.150) # mol m-2 s-1 -> s m-2
```

The same molar conductance translates into a higher resistance in cool air and
lower pressure conditions. These calculations assume that gas-exchange through
stomata is purely by diffusion.

```{r}
# mol m-2 s-1 -> s m-2
1 / gs_mol2vol(0.150, temperature = 5, pressure = 98e3) 
```

Stomatal conductance is directly dependent on the diffusion coefficient (D)
which depends on the chemical species, temperature and pressure. As 
$\mathrm{CO}_2$ is heavier than $\mathrm{H_2O}$, diffusion is slower, resulting
in lower conductance for $\mathrm{CO}_2$ compared to $\mathrm{H_2O}$ under
identical conditions.

```{r}
gs_c_from_gs_w(0.150) # mol m-2 s-1
```

Estimation of stomatal conductance from the measured size of the stomatal pore
is challenging, both because of the difficulty in doing the measurements and
because equations used is based on an approximation to the real shape of
stomata. The implementation in 'photobiologyPlants' is based on equations from 
Monteith and Unsworth (2008, ISBN: 978-0-12-505103-3)

```{r}
gs_w <-
  gs_w_from_size(length = 10e-6, # m
                 width = 5e-6, # m
                 depth = 20e-6, # m
                 n = 50e6, # m^-2 (stomatal density)
                 temperature = 30) |>  # C
  gs_vol2mol(temperature = 30, pressure = 101e3) # C, Pa
gs_w # for water vapour mol m-2 s-1
gs_w * 1e3 # for water vapour mmol m-2 s-1
gs_c_from_gs_w(gs_w) * 1e3 # for CO2 mmol m-2 s-1
```

All conversion and estimation functions shown earlier in this section, rely on 
computation of the volumetric diffusion coefficients of $\mathrm{H_2O}$ and 
$\mathrm{CO}_2$ in air and their dependence on temperature. The functions
below expect temperatures to be expressed in $^\circ\mathrm{C}$.

```{r}
D_water(temperature = c(0, 10, 20, 30, 40))
D_CO2(c(0, 10, 20, 30, 40))
```
They also depend on the molar volume of an ideal gas, which depends on pressure
and temperature.
For ideal gases the molar volume is independent of the chemical species. Air at
anbient pressure behaves approximately as an ideal gas. Function `molar_vol()`
expects temperature expressed in $^\circ\mathrm{C}$ and pressure in 
$\mathrm{Pa}$. 

```{r}
molar_vol(temperature = c(0, 10, 20, 30, 40))
```
```{r}
molar_vol(temperature = 25, pressure = c(98e3, 100e3, 102e3))
```
## Vegetation

The functions described in this section have been migrated from package 'photobiology' (>= 0.12.0) to 'photobiologyPlants' (>= 0.6.0).

### Reference evapotranspiration

Evapotranspiration is the combined water fluxes between a vegetation canopy and the atmosphere, It is the sum of transpiration (water that evaporates inside leaves and flows through stomata) and evaporation (water that evaporated from the soil and other surfaces, including from the wet outer surfaces of plants and their leaves). Measured evapotranspiration is described as _actual evapotranspiration_ ($\mathrm{ET}$), the maximum rate of evapotranspiration of short vegetation canopy is called _reference evapotranspiration_ ($\mathrm{ET}_\mathrm{ref}$), also described as _potential evapotranspiration_ ($\mathrm{PET}$)). Potential evapotranspiration can be measured on irrigated vegetation, but can also be estimated from meteorological conditions. Supported methods are the current FAO recommended and some earlier ones still in use.

Instantaneous $\mathrm{ET}_\mathrm{ref}$ expressed in $mm\ h^{-1}$ can be obtained with `ET_ref()`.

```{r}
ET_ref(temperature = 20, # C
       water.vp = water_RH2vp(relative.humidity = 70, # RH%
                              temperature = 20), # C -> Pa
       wind.speed = 0, # m s-1
       net.irradiance = 100) # W m-2
```

Daily $\mathrm{ET}_\mathrm{ref}$ expressed in $mm\ d^{-1}$ can be obtained with `ET_ref_day()`

```{r}
ET_ref_day(temperature = 20, # C daily mean
           water.vp = 1636.616, # Pa daily mean
           wind.speed = 5, # m s-1 daily mean
           net.radiation = 15e6) # 15 MJ / d / m2 daily total !
```

As many of other factions in the package, these functions are vectorized.

```{r}
ET_ref(temperature = 20, # C
       water.vp = water_RH2vp(relative.humidity = (1:9) * 10, # RH%
                              temperature = 20), # C -> Pa
       wind.speed = 5, # m s-1
       net.irradiance = 10) # W m-2
```

Potential evapotranspiration is in most situation proportional to the available radiant energy.

```{r}
ET_ref_irrad.df <-
  data.frame(irrad = (1:40) * 10,
             ET.ref = ET_ref(temperature = 20, # C
                             water.vp = water_RH2vp(relative.humidity = 70, # RH%
                                                    temperature = 20), # C -> Pa
                             wind.speed = 5, # m s-1
                             net.irradiance = (1:40) * 10) # W m-2
  )
ggplot(ET_ref_irrad.df, aes(irrad, ET.ref)) +
  geom_line() +
  labs(x = expression("Global radiation "*(W~m^{-2})),
       y = expression("Reference evapotranspiration "*(mm~h^{-1})))
```

Function `net_irradiance()` simplifies the computation of net irradiance, needed as input for the computation of reference evapotranspiration.

### Water vapour in air

Water vapour partial pressure in air depends on temperature and on whether air is in equilibrium with liquid water or ice.Not considered here, solutes in water and surface interactions also affect the equilibrium. The examples below use the default equation for the computation of saturated water vapour pressure. The default is Tetens' equation from 1930. Currently supported
methods are `"tetens"`, modified `"magnus"`, `"wexler"` and `"goff.gratch"`.

```{r}
water_vp_sat(20) # temperature in C, partial pressure in Pa
water_vp_sat(20) * 1e-3 # temperature in C, partial pressure in kPa
```

```{r}
vp_sat.df <- data.frame(temperature = -20:100,
                        vp.sat = c(water_vp_sat(-20:-1, over.ice = TRUE),
                                   water_vp_sat(0:100)) * 1e-3)

ggplot(vp_sat.df, aes(temperature, vp.sat)) +
  geom_line() +
  labs(x = "Temperature (C)", y = "Water valour pressure at saturation (kPa)")
```

Conversion of water vapour pressure to relative humidity and vice versa is based on the curve shown in the figure above.

```{r}
water_vp2RH(1000, 25) # Pa and C -> RH%
```

```{r}
water_vp2mvc(1000, 25) # Pa and C ->  mass per volume g m-3
```

The reverse conversion functions are `water_RH2vp()`, `water_mvc2vp()`.

If we know the actual vapour pressure we can compute at which temperature this
pressure would the saturating (RH = 100%), or dew point.

```{r}
water_dp(1000) # Pa -> C 
```

If the vapour pressure is very low, instead of dew point we have to compute the freezing point.

```{r}
water_fp(500) # Pa -> C 
```
Function `water_vp_sat_slope()` can be used to compute the slope of the curve in the figure above as a function of air temperature, and function `psychrometric_constant()` to compute the psychrometric constant as a function of air temperature.

