# Calculation Formulas

Calculation Formulas are the building blocks for defining **features**, which in turn are the building blocks of **protocols**.
One of the primary goals of Phaedra is to provide a flexible platform onto which diverse types of calculation can be defined and performed.
To this end, all calculations are modelled into **formulas** that are clearly defined and controlled through a unique name and version number.
Making any kind of change to the formula will result in a new version being generated, and in protocols and resultsets you will always see which
version of a formula was used to obtain a calculation result.

## The Formula Model

A Calculation Formula has several standard properties, such as a name, description and version number. In addition, it has three settings that together define what kind of calculation the formula can perform.

### Language

Is the programming language in which the formula is written.
Currently, two languages are supported: `R`

and `JavaStat`

. Future updates will bring support for additional languages
such as `Python`

and `JavaScript`

.

### Scope

This setting determines how many output values the formula is expected to return.

`PLATE`

indicates that the formula should return one value per whole plate. This scope is used in plate statistic formulas.`WELL`

indicates that the formula should return one value per well. This scope is typically used in feature calculation formulas.

### Formula

The formula can be written in any one of the supported languages, and is expected to return one or multiple output values, depending on the selected scope. The formula will automatically receive a number of input variables that it can use during its execution.

The table below lists the input variables a formula will receive when configured in the `R`

language and `WELL`

scope:

Variable Name | Type | Description |
---|---|---|

`input$wellNumbers` |
Vector, length is the number of wells in the plate | A vector of numeric values representing the well numbers. |

`input$wellTypes` |
Vector, length is the number of wells in the plate | A vector of character values representing the well types. |

`input$wellRows` |
Vector, length is the number of wells in the plate | A vector of numeric values representing the well row numbers. |

`input$wellColumns` |
Vector, length is the number of wells in the plate | A vector of numeric values representing the well column numbers. |

`input$wellStatus` |
Vector, length is the number of wells in the plate | A vector of numeric values representing the well status codes. If the value is <0, the well is rejected. |

`input$lowWellType` |
Character value | The Low Control welltype code as defined in the protocol |

`input$highWellType` |
Character value | The High Control welltype code as defined in the protocol |

*Note*: all well-based vectors have the same order.

In addition, if the formula is used for a feature in a protocol, it may define extra variables simply by referencing them from the `input`

object.
For example:

```
# This formula computes a %EFFECT normalization using LC and HC controls
lcMedian <- median(input$rawValue[input$wellStatus >= 0 & input$wellTypes == 'LC'], na.rm = TRUE)
hcMedian <- median(input$rawValue[input$wellStatus >= 0 & input$wellTypes == 'HC'], na.rm = TRUE)
output <- 100 * ((input$rawValue - lcMedian) / (hcMedian - lcMedian))
```

This formula uses several input variables such as `input$wellStatus`

and `input$wellTypes`

, but it also references a variable that is not defined in the table above: `input$rawValue`

.
When this formula is selected for use in a feature, a source for this `rawValue`

must be configured:

Here, a measurement well column named `CellCount_AllRetained`

will be used to provide a vector of values for the `input$rawValue`

variable in the formula.
As you can see, the same formula can be used repeatedly in other features (even other protocols) to compute the same thing, but using other measurement columns or features as `rawValue`

.

When using a measurement subwell column as the source, the variable will contain a list of vectors. Use the well number to index into the list and get a vector of values, one per cell.
For example, the expression `mean(input$rawValues[[5]])`

would return the mean value of all subwell items for well nr 5.