---
title: "Overview of the IncucyteDRC Package"
author: "Phil Chapman"
date: "`r Sys.Date()`"
output: 
  rmarkdown::html_vignette: 
    toc: true
vignette: >
  %\VignetteIndexEntry{Overview of the IncucyteDRC Package}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r message=FALSE, echo=FALSE, warnings=FALSE}
library(IncucyteDRC)
# note - how to export as pdf rmarkdown::render('vignettes/Overview.Rmd', 'pdf_document', output_dir='~/Desktop')
```

## Introduction
The IncucyteDRC package provides a workflow for users of the Incucyte Zoom live cell imaging system from Essen Biosciences who want to carry out a dose response analysis on their data.  For example, you may have grown cells in a 96-well plate that have been treated with a range of concentrations of several different small molecule inhibitors.  Although the Incucyte Zoom software allows you to conveniently visualise these data, exporting the data to a form that can then be readily analysed in PRISM is convoluted.  The IncucyteDRC package contains functions to make this process easier, as well as a graphical user interface.

For full details, please read the accompanying paper for the package on F1000R: Chapman et al 2016
If you want to see the package in action before deciding whether or not you want to install it, there is a [YouTube video](https://youtu.be/EQzeKefmZVw). 

## Getting data in
Two convenience functions exist for importing platemap and data files into R.  The `importPlatemapXML` function imports .Platemap files generated by the Incucyte Zoom software to define the contents of a plate.  The function can extract the following parameters: Compound (description, concentration and units), Growth Condition (description), and CellType (description, passage and seeding density).  These are converted into a data frame format which is used as a basis for further analysis.  Alternatively, a data frame can be created in R or imported from a text or excel file but it must include the same column names as in the example below:

```{r}
test_pm <- importPlatemapXML(system.file(file='extdata/example.PlateMap', package='IncucyteDRC'))
head(test_pm)
```

The platemap can be visualised using the `plotPlatemap` function:
```{r fig.width=10, fig.height=6, dpi=70}
plotPlatemap(test_pm)
```

The `importIncucyteData` function imports data from the data format generated by the Incucyte Zoom software.  To export data to the correct format follow the instructions in the Incucyte Zoom Export vignette.  You can also specify a metric (pc or percent confluence is the default) and a plateid.  The output is a `IncucyteDRCPlateData` S3 object which is a simple list object.

```{r}
test_data <- importIncucyteData(system.file(file='extdata/example_data.txt', package='IncucyteDRC'), metric='pc')
names(test_data)
head(test_data$data)
```

## The IncucyteDRCSet Object
The `IncucyteDRCSet` object is at the centre of the package workflow.  Subsequent functions add to and operate on the data contained within the object.

It can be initiated using the `makeIncucyteDRCSet` object and at its simplest just combines a plate map data frame generated by `importPlatemapXML` function with an `IncucyteDRCPlateData` object created by the `importIncucyteData` function.  In addition, a cut time can be specified, and a single row metadata data frame.

A key attribute of an `IncucyteDRCSet` is that all of the data shares a common control growth curve.  Thus it is appropriate to have an `IncucyteDRCSet` object containing multiple compounds on a common cell line background, but if the cell line background changes then one object is needed per condition.

The `splitIncucyteDRCPlateData` function is a convenience function that splits up an `IncucyteDRCPlateData` object into a list of `IncucyteDRCSet` objects if necessary, or a single `IncucyteDRCSet` object if not.  It also automatically populates the metadata slot.  Therefore it is sensible to use this function, rather than the `makeIncucyteDRCSet` function, in a standard workflow.  An example of its use is below where a data set contains cell lines under 4 different growth conditions, meaning that 4 `IncucyteDRCSet` objects are required:

```{r message=FALSE, warning=FALSE}
test_list <- splitIncucyteDRCPlateData(test_pm, test_data, group_columns='growthcondition')
test_idrcset <- test_list[[2]]
class(test_list)
class(test_idrcset)
names(test_idrcset)
length(test_list)
for (t in test_list) print(t$metadata)
```

Below only a single `IncucyteDRCSet` object is generated so an `IncucyteDRCSet` object rather than a `IncucyteDRCSetList` is returned:
```{r message=FALSE, warning=FALSE}
test_pm <- importPlatemapXML(system.file(file='extdata/example2.PlateMap', package='IncucyteDRC'))
test_pm$celltype <- 'T47D'  #modify contents of platemap
test_data <- importIncucyteData(system.file(file='extdata/example_data2.txt', package='IncucyteDRC'), metric='pc')
test_idrcset <- splitIncucyteDRCPlateData(test_pm, test_data, group_columns='celltype')
class(test_idrcset)
```

## Fitting growth curves
The first step in the analysis process is to fit growth curves to the data and visualise the output.  This is done using the related functions `fitGrowthCurvesGrouped` and `fitGrowthCurvesIndividual`.  The former will combine replicates to create a single growth curve for a given sample and concentration, whilst the latter will fit a growth curve for every single well on a plate.  The `IncucyteDRCSet` object is updated with four data frames containing the models themselves and the fitted data for plotting.  See the dplyr package documentation for more on how models objects can be stored in data frames.

```{r message=FALSE, warning=FALSE}
test_idrcset <- fitGrowthCurvesGrouped(test_idrcset)
test_idrcset <- fitGrowthCurvesIndividual(test_idrcset)
class(test_idrcset)
```

Once the growth curves have been fitted, they can be visualised using the `plotIncucyteDRCSet` function:
```{r fig.width=6, fig.height=4}
plotIncucyteDRCSet(test_idrcset, grouped=FALSE)
plotIncucyteDRCSet(test_idrcset, grouped=TRUE)

```

## Definining a cut time for dose response analysis
Although the growth curves themselves can give some insight into the effect that different compounds have on the growth curve of the cell line, to analyse this formally we want to extract the growth parameter at a specific 'cut time'.  This can then form the basis of a dose response analysis to generate an EC50 value.  The cut time can be defined manually using the `calculateDRCData` and data exported using the `exportDRCDataToDataFrame` function: 

```{r fig.width=6, fig.height=4, message=FALSE, warning=FALSE}
test_idrcset <- calculateDRCData(test_idrcset, cut_time = 170)
plotIncucyteDRCSet(test_idrcset, grouped=FALSE)
exportDRCDataToDataFrame(test_idrcset)[1:5,]
names(test_idrcset)

```

Note that the cut time is preserved in the `IncucyteDRCSet` object meaning that a subsequent call to the `plotIncucyteDRCSet` function can include this information as a blue dashed line.  Data can also be exported to a form suitable for PRISM:

```{r}
exportDRCDataToPRISM(test_idrcset)[,1:5]
```

Additional options allow for the inclusion of metadata in the output, and the inclusion of control data as zero concentration data points:

```{r}
exportDRCDataToDataFrame(test_idrcset, include_control = TRUE)[1:5,]
exportDRCDataToDataFrame(test_idrcset, add_metadata = TRUE)[1:5,]
```

## Carrying out a dose response analysis

It is advisable to export the dose response data and fit the curves in specialist software such as PRISM or Dotmatics, but for convenience there are also functions that use the `drc` package to provide an end-to-end workflow.  The  `fitDoseResponseCurve` function generates models for each compound in the `IncucyteDRCSet` and stores them in the drc_models slot (again a dplyr data frame).  `calculateEC50` predicts an EC50 value for each model and stores the results in the drc_ec50 slot.  `exportEC50Data` generates a data frame, optionally with metadata included whilst a plotting function `plotDoseResponseCurve` allows the curve for each compound to be visualised.

```{r fig.width=4.5, fig.height=3, message=FALSE, warning=FALSE}
test_idrcset <- fitDoseResponseCurve(test_idrcset, include_control = TRUE)
names(test_idrcset)
test_idrcset <- calculateEC50(test_idrcset)
names(test_idrcset)
exportEC50Data(test_idrcset)
plotDoseResponseCurve(test_idrcset, 'PDD00017252')

```

## Calculating a cut time

In the previous examples, a cut time has been manually provided following an inspection of the growth curves.  Typically the cut time should be as long as possible to allow differences to become pronounced, but still during the exponential phase of cell growth before the cells become confluent.  However, sometimes it might be desirable to determine the cut time for a given number of doublings, so that the EC50 for fast and slow growing cell lines can be normalised.

The `calculateCutTimeForIDRCSet` function can be run on an `IncucyteDRCSet` object to determine the optimal cut time from the control (untreated) growth curves given a set of parameters.  These include the baseline_time (the timepoint to take as a baseline for calculating doublings), the no_doublings (the number of doublings required) and the max_val (the maximum allowable growth curve value).  The algorithm works out the growth curve value at the baseline time and what value would correspond to a given number of doublings from this point, then returns the timepoint at which this value is achieved.  If this value exceeds the maximum value, then the time at which the maximum value is returned instead, along with the actual number of doublings achieved.  

More detail on this approach can be found in the paper that accompanies this package <<<<ADD PAPER!!>>>

An example is given below:

```{r fig.width=6, fig.height=4, message=FALSE, warning=FALSE}
test_idrcset <- calculateCutTimeForIDRCSet(test_idrcset, baseline_time = 5, no_doublings = 3.5, max_val = 80)
names(test_idrcset)
test_idrcset$cut_plot
test_idrcset$calculated_cut
test_idrcset <- calculateDRCData(test_idrcset)
plotIncucyteDRCSet(test_idrcset, grouped=TRUE)

```

## Using the magittr pipe function
Since the same object is incremementally added to it is possible to pipe the output of one function into another using the `%>%` command from the `magittr` (and heavily used in `dplyr`.  An example of this approach is below.

```{r message=FALSE, warning=FALSE}
library(dplyr)
test_pm <- importPlatemapXML(system.file(file='extdata/example2.PlateMap', package='IncucyteDRC'))
test_pm$celltype <- 'T47D'  #modify contents of platemap
test_data <- importIncucyteData(system.file(file='extdata/example_data2.txt', package='IncucyteDRC'), metric='pc')
test_idrcset <- splitIncucyteDRCPlateData(test_pm, test_data, group_columns='celltype')
test_idrcset %>% 
    fitGrowthCurvesGrouped() %>% 
    fitGrowthCurvesIndividual() %>%
    calculateCutTimeForIDRCSet(baseline_time=24, no_doublings=4, max_val=80) %>%
    calculateDRCData() %>%
    fitDoseResponseCurve(include_control = TRUE) %>%
    calculateEC50() %>%
    exportEC50Data()
```

## Working with IncucyteDRCSetLists
Where you are working with an `IncucyteDRCSetLists` object because you have more than one cell line condition in a plate, or because you have combined multiple `IncucyteDRCSet` objects into a list from different plates, it is convenient to use the standard `lapply` function in combination with the `%>%` operator to quickly run the workflow across a large dataset.

```{r message=FALSE, warning=FALSE}
test_pm <- importPlatemapXML(system.file(file='extdata/example.PlateMap', package='IncucyteDRC'))
test_data <- importIncucyteData(system.file(file='extdata/example_data.txt', package='IncucyteDRC'), metric='pc')
test_list <- splitIncucyteDRCPlateData(test_pm, test_data, group_columns='growthcondition') %>%
    lapply(fitGrowthCurvesGrouped) %>%
    lapply(fitGrowthCurvesIndividual) %>%
    lapply(calculateCutTimeForIDRCSet, baseline_time=24, no_doublings=4, max_val=80) %>%
    lapply(calculateDRCData) %>%
    lapply(fitDoseResponseCurve, include_control=TRUE) %>%
    lapply(calculateEC50)
    
#export EC50 data and combine
lapply(test_list, exportEC50Data, add_metadata=TRUE) %>% dplyr::bind_rows()

```

## Graphical interface for non-R users with shiny

Finally, the package contains functions to create a shiny app to enable non-R users to access the functionality in the IncucyteDRC package.  The shiny interface can be launched as follows from the packages:

```{r eval=FALSE}
shinyVisApp()
```

And the following code can be used as the basis of a single file shiny app to run on a shiny server:
```{r eval=FALSE}
#save code as app.R 
library(IncucyteDRC)
library(shiny)

options(warn=-1) #disable warnings

#initiate the shiny app
shinyApp(
    ui = IncucyteDRC::shinyVisUI(),
    server = function(input, output) {
        IncucyteDRC::shinyVisServer(input, output)
    }
)
```


