---
title: "User Guide: 1 Using the Data"
subtitle: "Package 'photobiologySensors' `r packageVersion('photobiologySensors')` "
author: "Pedro J. Aphalo"
date: "`r Sys.Date()`"
output: 
  rmarkdown::html_vignette:
    toc: yes
vignette: >
  %\VignetteIndexEntry{User Guide: 1 Using the Data}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, echo=FALSE}
knitr::opts_chunk$set(fig.width=8, fig.height=4)
```

## Introduction

This package, is a data only package, part of a suite, which has package 
'photobiology' at its core. Please visit (https://www.r4photobiology.info/) 
for more details. For more details on plotting spectra, please consult the 
documentation for package 'ggspectra', and for information on the calculation 
of summaries and maths operations between spectra, please, consult the 
documentation for package 'photobiology'.

```{r, message=FALSE}
library(photobiology)
library(photobiologySensors)
library(photobiologyWavebands)
eval_ggspectra <- TRUE
library(ggspectra)
```

In this brief User Guide we describe how to re-scale the normalized
spectra, and how to access individual spectra or subsets of spectra.

Spectra in the package are contained in one collection: `sensors.mspct` contains
spectral data for various types of broadband sensors. 
<!-- In addition it contains contains data on the effect of temperature on the -->
<!-- sensitivity of an ultraviolet sensor. -->

In addition to the objects containing the data itself, several character vectors 
of names of spectra are provide to facilitate the retrieval of subsets of spectra.

## Accessing individual spectra

The `response_spct` member objects in `sensors.mspct` can be accessed through their
names or through a numeric index. As the numeric indexes are likely to change 
with updates to the package, their use is discouraged. Names as character
strings should be used instead. They can also be retrieved with method `names()`.

```{r}
names(sensors.mspct)
```

We can use a character string as index to extract an individual `response_spct`
object.

```{r}
sensors.mspct$LICOR_LI_190R
```

```{r}
sensors.mspct[["LICOR_LI_190R"]]
```

Be aware that according to R's rules, using single square brackets will return
a `response_mspct` object possibly of length one. This statement is not equivalent
to the one in the chunk immediately above.

```{r}
sensors.mspct["LICOR_LI_190R"]
```

## Accessing subsets of spectra

We can subset `sensors.mspct` object by indexing with vectors of character
strings. The package provides some predefined ones, and users can easily
define their own, either as constants or through computation. Here we use
a vector defined by the package.

```{r}
sensors.mspct[berger_sensors]
```

More generally one can search for matching names within the collection of spectra.

```{r}
sensors.mspct[grep("berger", names(sensors.mspct), ignore.case = TRUE)]
```

Set algebra operations can be used with the indexing vectors as each vector
describes a single property: color, brand, type, etc.

```{r}
sensors.mspct[intersect(licor_sensors, par_sensors)]
```

## Calculating summaries from the normalized data

The spectra are normalized, and consequently, several summaries expressed in
absolute units are undefined, and trigger errors. Summaries like ratios which
are not affected by normalization are allowed and valid. The data have been
normalized as the measuring conditions used are not all the same, and in many
cases not well characterized (e.g. distance to nearby reflecting walls, or exact 
alignment of the spectrometer input optics with respect to light sources).

What we will do in this section is to rescale the spectral data so that after 
conversion a given target value for a summary quantity will be true. As an 
example, we will rescale one spectrum so that it yields a response of
100 mol<sup>-1</sup> m<sup>2</sup>for the range 400 to 700 nm.

```{r}
my.spct <- fscale(sensors.mspct$LICOR_LI_190R,
                  range = PhR(),
                  q_response,
                  target = 100,
                  set.scaled = FALSE)
q_response(my.spct, PhR())
q_response(my.spct, UVA())
```

If we want to treat the rescaled spectral data, as if they were true readings
with no scaling we can reset the attribute with method `setScaled()`. With 
method `getScaled()` we can test if a spectrum has been scaled.

```{r}
getScaled(my.spct)
```

If for some obscure reason we want to simply "pretend" that the spectral data
have not been normalized, we can permanently override the attribute on a copy 
of the data. Most of the time this is a very bad idea!

```{r}
my2nd.spct <- sensors.mspct$LICOR_LI_190
setNormalized(my2nd.spct)
q_response(my2nd.spct)
```

## Plotting the spectra

Using `autoplot()` methods for spectra defined in package 'ggspectra' annotated
plotting is automatic. The defaults can be easily changed, please see the
documentation in package 'ggspectra'.

```{r, eval=eval_ggspectra}
autoplot(sensors.mspct$LICOR_LI_190R, 
         annotations = c("+", "title:what:how:comment"))
```

Using the `ggplot()` method for spectra from package 'ggspectra' plus
_geometries_ and _statistics_ from package 'ggplot2' we gain additional control
on the design.

```{r, eval=eval_ggspectra}
ggplot(sensors.mspct$LICOR_LI_190R, unit.out = "photon") +
  geom_hline(yintercept = 1, colour = "red") +
  geom_hline(yintercept = c(0.9, 1.1), colour = "red", linetype = "dotted") +
  geom_line(linetype = "dashed") +
  scale_y_s.q.response_continuous(breaks = c(0, 0.5, 1)) +
  scale_x_wl_continuous() +
  theme_classic()
```

## Angular response

```{r, eval=eval_ggspectra}
ggplot(diffusers.lst$bentham.D7, aes(angle.deg, response)) +
  geom_line() +
  geom_line(aes(y = cos(angle.deg * pi / 180)), linetype = "dotted", color = "red") +
  scale_x_continuous(name = "Angle (degrees)", breaks = c(-90, -60, -30, 0, 30, 60, 90)) +
  scale_y_continuous(name = "Response (/1)") +
  theme_classic()
```


## Using the data in other contexts

As `response_mspct` is a class derived from `list`, and `response_spct` is derived from
`tibble::tible` which is a (mostly) compatible reimplementation of `data.frame` the
data can be used very easily with any R function.

```{r}
head(as.data.frame(sensors.mspct$LICOR_LI_190R))
```

Of course `attach` and `with` also work as expected.

```{r}
attach(sensors.mspct)
head(LICOR_LI_190R)
detach(sensors.mspct)
```

```{r}
attach(sensors.mspct)
with(LICOR_LI_190, max(w.length))
detach(sensors.mspct)
```

```{r}
with(sensors.mspct, wl_range(LICOR_LI_190))
```
