---
title: "3 - run_isobxr()"
author: "Théo Tacail"
date: "`r Sys.Date()`" 
output: 
  rmarkdown::html_vignette:
    toc: true
    toc_depth: 2
vignette: >
  %\VignetteIndexEntry{3 - run_isobxr()}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>")
options(rmarkdown.html_vignette.check_title = FALSE)
```

----

[Full documentation and tutorials can be found on the isobxr website.](https://ttacail.github.io/isobxr_web/)

----

In this vignette, the user will be introduced to the main function of [isobxr](https://ttacail.github.io/isobxr/): `run_isobxr`.

Here, we shortly present the principles and general usage of the `run_isobxr` function. 

The user is then invited to follow and run a step-by-step tutorial presenting several typical runs [(4 - Run_isobxr: tutorial)](https://ttacail.github.io/isobxr_web/vgn_04_Run_isobxr_tutorial.html).

----

# System definitions

As a reminder, the systems considered in the [isobxr](https://ttacail.github.io/isobxr/) package 
are described in the cheatsheet presented [here](https://ttacail.github.io/isobxr_web/vgn_02_General_presentation.html) and in the "General presentation" vignette.

<!-- As a reminder, the systems considered in the [isobxr](https://ttacail.github.io/isobxr/) package  -->
<!-- are described in the cheatsheet below: -->

<!-- ```{r echo=FALSE, out.width='100%'} -->
<!-- knitr::include_graphics('./02_basics_01_sysdef.png') -->
<!-- ``` -->

----

# How does **run_isobxr** work?

The `run_isobxr` function is the main function of the [isobxr](https://ttacail.github.io/isobxr/) package.

The `run_isobxr` function is used to perform single runs of stable isotope box models of all types of systems.

The `run_isobxr` function allows to: 

1. assess the type of modelled system

1. render and archive the design of the model and run commands

1. automatically run `num_slvr` or `ana_slvr` solvers depending on the model design

1. provide user with the time evolutions of isotope compositions and masses of X in each box

The general workflow of the `run_isobxr` function is summarized in the cheatsheet below:

```{r echo=FALSE, out.width='100%'}
knitr::include_graphics('./02_basics_02_runisobxr_wflow.png')
```

To find the detailed description of `run_isobxr` inputs and outputs, 
the user can always refer to its documentation:

```{r eval = FALSE, message=FALSE, warning=FALSE, paged.print=FALSE}
# To see documentation on run_isobxr function, type in console:
?run_isobxr
```

----

# Filling in **0_ISOBXR_MASTER.xlsx**

The **isobxr master file** is the excel document containing all data 
defining the modelled system.

It provides the `run_isobxr` function with the 
**main commands** for a run of stable isotope box model.

**Note**
:    All the [isobxr](https://ttacail.github.io/isobxr/) functions 
     are meant to be run in relation with an **isobxr master file**. 
     As `run_isobxr` is the fundamental function, called by the other 
     [isobxr](https://ttacail.github.io/isobxr/) functions, 
     the **isobxr master file** is also required to run functions 
     performing multiple runs (`compose_isobxr`, `sweep_steady`, `sweep_dyn`).


## Name and location 

* The **isobxr master file** is an xlsx file
* The **isobxr master file** name needs to be exactly as follows: **0_ISOBXR_MASTER.xlsx**
* The **isobxr master file** has to be stored in the working directory (*workdir*) 

## Structure and format

The **isobxr master file** contains the 4 following sheet strictly named as follows: 

1. **CONSTANTS**: Sheet defining the constants of the isotopic system
1. **BOXES**: Sheet defining names and status of all boxes constituting the system
1. **FLUXES**: Sheet defining the initial box sizes and mass fluxes of element X between boxes (structured as a column list)
1. **COEFFS**: Sheet defining the isotopic fractionation coefficients between all boxes (structured as a column list)

The general rules for the filling in of the **isobxr master file** are shown in cheatsheet below:

```{r echo=FALSE, out.width='100%'}
knitr::include_graphics('./03_Run_isobxr_01_fill_master.png')
```

More complete description of the master file filling can be found [here](https://ttacail.github.io/isobxr_web/vgn_03_Run_isobxr_presentation.html#32_Structure_and_format)
and some examples and tutorials are shown [here](https://ttacail.github.io/isobxr_web/vgn_04_Run_isobxr_tutorial.html).

<!-- ### **CONSTANTS** sheet -->

<!-- ```{r echo=FALSE, out.width='75%'} -->
<!-- knitr::include_graphics('./03_Run_isobxr_02_fill_CONSTs.png') -->
<!-- ``` -->

<!-- ### **BOXES** sheet -->

<!-- ```{r echo=FALSE, out.width='100%'} -->
<!-- knitr::include_graphics('./03_Run_isobxr_03_fill_BOXES.png') -->
<!-- ``` -->

<!-- [INFINITE] column  -->
<!-- :     -->
<!-- * stores the *status of the box* depending on the box model design (**open** or **closed**)   -->
<!--     + If system is **open**, environment boxes are declared as **INFINITE**. -->
<!-- * All *finite boxes* can be declared with **FINITE** status or other user-defined status -->
<!--     (*e.g.*, **INTERFACE** or **DEAD_END** or **FINITE**) -->
<!-- * Status of *finite boxes* also define color code of system diagrams. -->

<!-- [LAYOUT] columns  -->
<!-- :     -->
<!-- * *LAYOUT_X* and *LAYOUT_Y* columns correspond to the layout of the **box model diagram**    -->
<!-- * They define the coordinates of boxes in the diagram in a X,Y space. -->

<!-- ### **FLUXES** sheet -->

<!-- ```{r echo=FALSE, out.width='100%'} -->
<!-- knitr::include_graphics('./03_Run_isobxr_04_fill_FLUXES.png') -->
<!-- ``` -->

<!-- The *flux lists* columns define a set of [fluxes + box sizes] conditions.   -->

<!-- * Flux values (**STATUS** = **FLUX**): -->
<!--     + Within a given column, users define as many fluxes as desired  -->
<!--     + Undefined fluxes are set to 0 by `run_isobxr` (no exchange of element X) -->

<!-- * Sizes values (**STATUS** = **SIZE**): -->
<!--     + **Sizes must be defined for all boxes** -->
<!--     + If a box remains unused (no connected flux), its size can be set to 0 -->

<!-- <!-- **Negative balance of fluxes** :  --> 
<!-- <!-- If too long, the run could lead to the total emptying of the box:  --> 

<!-- <!-- * run duration automatically updated to shortest duration box emptying --> 
<!-- <!-- * user is advised with a **warning message** in R console --> 

<!-- <!-- **Mass and time units** -->
<!-- <!-- :         --> 
<!-- <!-- * The **units** of the fluxes (mass/time unit) and sizes (mass unit) need to be homogeneous (same mass unit for both). --> 
<!-- <!-- * The **units** of the fluxes (mass unit per time unit) and run duration set in the function (time unit) need to be homogeneous (same time unit for both). -->

<!-- ### **COEFFS** sheet -->

<!-- ```{r echo=FALSE, out.width='100%'} -->
<!-- knitr::include_graphics('./03_Run_isobxr_05_fill_COEFFS.png') -->
<!-- ``` -->

<!-- <!-- All *black text* has to be strictly the same as shown.   -->
<!-- <!-- All *blue text* corresponds to litteral names (string of characters) defined by the user.   -->
<!-- <!-- All *red text* corresponds to litteral or numerical variables set by the user.   -->

<!-- The **COEFFS** sheet takes the values of the isotope fractionation coefficients ($\alpha_{i \to j}$): -->

<!-- * Users define as many *coefficients lists* as desired -->
<!-- * Each *coefficients lists* defines a set of fractionation coefficients -->
<!-- * Undefined coefficients are set to 1 by `run_isobxr` (no isotope fractionation)   -->

----

# Main arguments and outputs

The `run_isobxr` function takes required and optional arguments that are described in this section.
 
All arguments definitions of the `run_isobxr` function are accessible in its documentation called as follows

```{r eval=FALSE}
?run_isobxr
```

## Required arguments

The arguments required to run the `run_isobxr` function are exemplified and described here with the first tutorial example ([see tutorial here](https://ttacail.github.io/isobxr_web/vgn_04_Run_isobxr_tutorial.html#2_Ex_1:_{ABC},_closed,_balanced)):

```{r eval=FALSE}
run_isobxr(workdir = "/Users/username/Documents/1_ABC_tutorial",
           SERIES_ID = "ABC_closed_balanced", # defining the name of the SERIES of run
           flux_list_name = "Fx1_ABC_closed_bal", # calling the list of fluxes
           coeff_list_name = "a1", #  calling the list of coefficients
           t_lim = 2500, # running model for 1000 time units
           nb_steps = 250, # running model with 100 steps
           time_units = c("d", "yr")) # plot results in years as time units.
```

**workdir** 
:     Working directory of 0_ISOBXR_MASTER.xlsx master file and where output files will be stored if saved by user (**save_run_outputs = TRUE**, default is **FALSE**).

**SERIES_ID**	
:     Name of the model series the run belongs to. 
It determines the folder in which the output files will be stored if saved by user (**save_run_outputs = TRUE**, default is **FALSE**).

**flux_list_name**
:     Name of the list of fluxes and initial box sizes to be used for the run, 
calling (by its header name) a single column of the FLUXES sheet of the 0_ISOBXR_MASTER.xlsx file. 


**coeff_list_name**
:     Name of the list of fractionation coefficients to be used for the run, 
calling (by its header name) a single column of the COEFFS sheet of the 0_ISOBXR_MASTER.xlsx file. 

**t_lim**	
:     Run duration, given in the same time units as the fluxes. 

**nb_steps**
:     Number of calculation steps. 
It determines the resolution of the run. 

**time_units**	
:     
* Vector defining the initial time unit (identical to unit used in fluxes), 
followed by the time unit used for the graphical output
* to be selected among the following: *micros, ms, s, min, h, d, wk, mo, yr, kyr, Myr, Gyr*
* e.g., c("d", "yr") to convert days into years


## Default and optional outputs

By default, the `run_isobxr` prints a summary plot of the run outputs (evolution of delta values and box sizes) in the R session.

All `run_isobxr` output data is stored in a temporary directory by default.

The user can save these outputs to their working directory by changing the **save_run_outputs** argument to **TRUE**.

The `run_isobxr` outputs are structured as shown in the [full package documentation.](https://ttacail.github.io/isobxr_web/vgn_03_Run_isobxr_presentation.html#42_Default_and_optional_outputs)

<!-- The `run_isobxr` outputs are structured as follows: -->

<!-- ```{r echo=FALSE, out.width='100%'} -->
<!-- knitr::include_graphics('./03_Run_isobxr_06_outputs_structure.png') -->
<!-- ``` -->

In addition to the default outputs,
the `run_isobxr` function allows to: 

* export system diagrams (as pdf, using **to_DIGEST_DIAGRAMS = TRUE**)
* export evolution of delta values (as pdf, using **to_DIGEST_evD_PLOT = TRUE**)
* export input and output data (as csv and xlsx, using **to_DIGEST_CSV_XLS = TRUE**)

These arguments are called as follows (using example used in [tutorial](https://ttacail.github.io/isobxr_web/vgn_04_Run_isobxr_tutorial.html#2_Ex_1:_{ABC},_closed,_balanced)):

```{r eval=FALSE}
run_isobxr(workdir = "/Users/username/Documents/1_ABC_tutorial",
           SERIES_ID = "ABC_closed_balanced",
           flux_list_name = "Fx1_ABC_closed_bal",
           coeff_list_name = "a1", 
           t_lim = 2500,
           nb_steps = 250,
           time_units = c("d", "yr"),
           to_DIGEST_DIAGRAMS = TRUE, # default is TRUE
           to_DIGEST_evD_PLOT = TRUE, # default is TRUE
           to_DIGEST_CSV_XLS = TRUE  # default is FALSE
           )
```

**Note**
: All `run_isobxr` outputs are not saved by default. Set **save_run_outputs = TRUE** to save outputs to a local working directory.

## Additional forcing arguments

### Forcing initial box sizes

By default, `run_isobxr` sets the initial box sizes 
at the values found in the flux list.

It is possible to manually overwrite the initial size of one, 
several or all boxes for a given run performed by `run_isobxr`.  

It is done by defining a data frame structured as follows.

```{r echo=TRUE}
FORCING_SIZE <- 
  data.frame(BOXES_ID = c("BOX_1", "...", "BOX_i", "..."),
             SIZE_INIT = c("updated_size_1", "...", "updated_size_i", "..."))

FORCING_SIZE
```

For the 3-boxes closed system model (ABC), in order to change the size of box C from 2000 mg of Ca 
(default as specified in **isobxr master file** for all flux lists of **FLUXES** sheet)
to 3000 mg of Ca, the data frame should be structured as follows:

```{r echo=TRUE}
FORCING_SIZE <- 
  data.frame(BOXES_ID = c("C"),
             SIZE_INIT = c(3000))

FORCING_SIZE
```

### Forcing initial delta values

By default, the `run_isobxr` function sets the initial delta values of all boxes at 0 ‰.

It is possible to manually overwrite the initial delta values of one, 
several or all boxes for a given run performed by `run_isobxr`.  
It is done by defining a data frame structured as follows.

```{r echo=TRUE}
FORCING_DELTA <- 
  data.frame(BOXES_ID = c("BOX_1", "...", "BOX_i", "..."),
             DELTA_INIT = c("updated_delta_1", "...", "updated_delta_i", "..."))

FORCING_DELTA
```

For the 3-boxes closed system model (ABC),
in order to force initial isotope composition of box A to -1‰,
and leave B and C initial values at 0‰,
the data frame should be structured as follows:

```{r echo=TRUE}
FORCING_DELTA <- 
  data.frame(BOXES_ID = c("A"),
             DELTA_INIT = c(-1))

FORCING_DELTA
```

### Forcing fractionation coefficients

By default, the `run_isobxr` function sets the isotope fractionation coefficients 
at the values found in the coefficients list specified by user.

It is possible to manually overwrite the fractionation coefficients of one,
several or all pairs of boxes for a given run performed by `run_isobxr`.  
It is done by defining a data frame structured as follows.

```{r echo=TRUE}
FORCING_ALPHA <- 
  data.frame(FROM = c("BOX_i", "..."),
             TO = c("BOX_j", "..."),
             ALPHA = c("new_coeff_value", "..."),
             FROM_TO = c("BOX_i_BOX_j", "..."))

FORCING_ALPHA
```

For the 3-boxes closed system model (ABC), in order to force the fractionation coefficient 
associated to the flux of Ca from box A to B to the value of 1.02,
the data frame should be structured as follows:

```{r echo=TRUE}
FORCING_ALPHA <- 
  data.frame(FROM = c("A"),
             TO = c("B"),
             ALPHA = c(1.02),
             FROM_TO = c("A_B"))

FORCING_ALPHA
```

### Rayleigh distillation models

It is possible to overwrite isotope fractionation coefficients 
by defining their values as the result of Rayleigh type isotope
distillation in the context of a fractional exchange at an interface. 

We consider here the case of the loss of element X from a box A to a box C through an interface box B, 
all possibly part of a bigger box model system.

We suppose that the apparent fractionation coefficient $\alpha_{A \to C}$ associated to this flux $F_{A \to C}$ 
results from a Rayleigh type distillation occurring during the fractional exchange of element X at the interface box B.

```{r echo=FALSE, out.width='100%'}
knitr::include_graphics('./03_Run_isobxr_07_Rayleigh.png')
```

In this situation, the box A exchanges element X with box B (and possibly other boxes).

This is a fractional exchange, *i.e.* during this exchange, box A sends more of element X to box B than B sends back ($F_{A \to B} > F_{B \to A}$).  

As we consider box B to be balanced, it loses the difference to box C: $F_{B \to C} = F_{A \to B} - F_{B \to A}$.  

As a result, box A loses a total of $F_{B \to C}$ of element X per time unit.  

We suppose here that the $F_{A \to B}$ that feeds box B is associated to no isotope fractionation.  

On the other hand, we suppose that the $F_{B \to A}$ flux corresponding to the fractional loss of element X from interface box B, and returning to box A, 
is associated to an *equilibrium* or *incremental* isotope fractionation ($\alpha^0 _{B \to A}$).

The Rayleigh distillation model of isotopes thus predicts the following: 

$$R_{C} = R_{C, t_0} \dfrac{F_{B \to C}}{F_{A \to B}}^{\alpha^0 _{B \to A} - 1}  $$

The $R_{C, t_0}$ corresponds to the isotope ratio of the element X in box B before any exchange with box A occurs. 
It is thus equivalent to $R_{A}$ since the box B only input is *via* the $F_{A \to B}$ flux.

We thus can write the following definition of $\alpha_{B \to C}$ (equivalent here to $\alpha_{A \to C}$):

$\alpha_{B \to C} = \dfrac{R_{C}}{R_{A}} = \dfrac{F_{B \to C}}{F_{A \to B}}^{\alpha^0 _{B \to A} - 1}$

The `run_isobxr` function here takes as an optional input the data frame structured as follows:

```{r}
FORCING_RAYLEIGH <- 
  data.frame(XFROM = c("B"), # Define the B>C flux at numerator
             XTO = c("C"),
             YFROM = c("A"), # Define the A>B flux at denominator
             YTO = c("B"),
             AFROM = c("B"), # Define the resulting fractionation coefficient
             ATO = c("C"),
             ALPHA_0 = c("a0") # Define the value of incremental B>A coefficient
  ) 

FORCING_RAYLEIGH
```

The `run_isobxr` function will in this case overwrite the value of $\alpha_{B \to C}$ set in **isobxr master file** or using the FORCING_ALPHA parameter. 

Indeed, if the user forced a new value for $\alpha_{B \to C}$ using the FORCING_ALPHA parameter, 
the `run_isobxr` function will prioritize the FORCING_RAYLEIGH parameter. 

It is possible to define several Rayleigh distillation apparent fractionation coefficients in a given model.  
This is done by adding rows to this data frame.
