---
title: "Renormalise spectral data with a custom reference"
author: "Hugo Gruson"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
bibliography: lightr.bib
vignette: >
  %\VignetteIndexEntry{Renormalise spectral data with a custom reference}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

Some use cases require more flexibility than the high-level user-friendly
functions provides by `lightr`. For this use case, `lightr` also exports the
low-level individual parsers, which allow the user to code its own custom
workflow.

We don't recommend the use of those functions unless you absolutely have to.
Most users should use `lr_get_spec()` and `lr_get_metadata()` instead.

Here, we take the example of the method presented in 
@Gruson2019_QuantitativeCharacterizationIridescent where reflectance spectra 
need to be normalised in an unusual way.

Raw, un-normalised spectral data depends on both the spectrometer and the lamp
as well as the conditions during the recording (including ambient light, 
temperature, *etc*.). To allow for comparison between studies, it is thus 
normalised  by a white and a dark reference with the following formula:

<math>
    <mrow>
      <mtext>Processed</mtext>
      <mo>=</mo>
      <mfrac>
        <mrow><mtext>Raw</mtext><mo>-</mo><mtext>Dark</mtext></mrow>
        <mrow><mtext>White</mtext><mo>-</mo><mtext>Dark</mtext></mrow>
      </mfrac>
    </mrow>
</math>

For this example here, we need to normalise the raw data by a white reference
contained in another file. This can't be done with with `lr_get_spec()` because
`lr_get_spec()` returns reflectance spectra that have already been normalised by
the white reference contained in the same file.

```{r}
library(lightr)
```

## Step 1: import un-normalised data

We manually import the data using the appropriate low-level parser:

```{r}
reflect_data <- lr_parse_procspec(
  system.file("testdata", "procspec_files", "OceanOptics_Linux.ProcSpec",
               package = "lightr")
  )
length(reflect_data)
```

The result contains 2 elements:

  * the spectral data itself
  * the metadata captured during the recording
  
```{r}
head(reflect_data[[1]])
```

## Step 2: find the matching white reference

We import that white reference in the same way:

```{r}
white_data <- lr_parse_procspec(
  system.file("testdata", "procspec_files", "whiteref.ProcSpec",
               package = "lightr")
)
```

## Step 3: normalise the reflectance data

We can now normalise the reflectance spectrum with the equation stated at the
beginning of this vignette:

<math>
    <mrow>
      <mtext>Processed</mtext>
      <mo>=</mo>
      <mfrac>
        <mrow><mtext>Raw</mtext><mo>-</mo><mtext>Dark</mtext></mrow>
        <mrow><mtext>White</mtext><mo>-</mo><mtext>Dark</mtext></mrow>
      </mfrac>
    </mrow>
</math>

But first, we verify that the integration times:

We can now get rid of the metadata part and focus on the data only:

```{r}
reflect_data <- data.frame(reflect_data[[1]])
white_data <- data.frame(white_data[[1]])
```

As a last step before being able to normalise the data, we also need to check
if the reflectance spectrum and the white reference are sampled with the same
wavelengths:

```{r}
all.equal(reflect_data$wl, white_data$wl)
```

```{r}
res <- (reflect_data$scope - reflect_data$dark) / (white_data$white - white_data$dark)
head(res)
```
