---
title: "EpiCompare Report"
date: "`r format(Sys.Date(), '%b-%d-%Y')`"
output: 
  html_document: 
    toc: yes
    toc_float: yes
    code_folding: hide 
params:
  peakfile: 
    value: NULL
  output_dir: 
    value: NULL
  genome_build:
    value: NULL
  genome_build_output:
    value: "hg19"
  blacklist: 
    value: NULL
  picard_files:
    value : NULL
  reference: 
    value: NULL
  upset_plot:
    value: FALSE
  stat_plot:
    value: FALSE
  chromHMM_plot:
    value: FALSE
  chromHMM_annotation:
    value: "K562"
  chipseeker_plot:
    value: FALSE
  enrichment_plot:
    value: FALSE
  tss_plot:
    value: FALSE
  precision_recall_plot:
    value: FALSE
  n_threshold:
    value: 15
  corr_plot:
    value: FALSE  
  bin_size:
    value: 5000      
  interact:
    value: TRUE
  save_output:
    value: FALSE
  workers:
    value: 1
---

```{r setup, warning=FALSE, message=FALSE}
knitr::opts_chunk$set(echo = FALSE)
### Create Output Directory ###
# if save_output = TRUE
if(params$save_output){
  outfile_dir <- file.path(params$output_dir,"EpiCompare_file")
  if(!dir.exists(outfile_dir)){
    dir.create(outfile_dir, showWarnings = FALSE, recursive = TRUE)
  }
}

#### ------ Prepare genome builds ------ ####
# e.g. genome_build <- list(reference="hg19",peakfiles="hg38",blacklist="hg19")
# or... genome_build <- "hg19"
builds <- prepare_genome_builds(genome_build = params$genome_build)
## Standardise all data to hg19 build 
output_build <- prepare_output_build(params$genome_build_output)

#### ------ Prepare peaklist(s) ------ ####
# and check that the list is named, if not default filenames are used 
peaklist <- prepare_peaklist(peaklist = params$peakfile) 
peaklist <- liftover_grlist(grlist = peaklist, 
                            input_build = builds$peaklist,
                            output_build = output_build)

#### ------ Prepare reference(s) ------ ####
reference <- prepare_reference(reference = params$reference)
reference <- liftover_grlist(grlist = reference, 
                            input_build = builds$reference,
                            output_build = output_build)

#### ------ Prepare blacklist ------ ####
blacklist <- liftover_grlist(grlist = params$blacklist,
                             input_build = builds$blacklist, 
                             output_build = output_build) 

### Standardise peaklist(s) ###
peaklist <- tidy_peakfile(peaklist = peaklist,
                          blacklist = blacklist)
peaklist_tidy <- peaklist

### Standardise reference(s) ###
# and include in peaklist
reference_tidy <- reference
if (!is.null(reference)){
  reference_tidy <- tidy_peakfile(peaklist = reference,
                                  blacklist = blacklist)
  peaklist_tidy <- c(peaklist_tidy, reference_tidy)
}

### Obtain Genome Annotation ### 
txdb <- check_genome_build(genome_build = output_build)

### Dynamic Figure Height ###  
fig_height <- fig_length(default_size = 7,
                         number_of_items = length(peaklist_tidy),
                         max_items = 10)
```

[EpiCompare](https://github.com/neurogenomics/EpiCompare) compares epigenomic 
datasets for quality control and benchmarking purposes. 
The report consists of three sections: 

1. **General Metrics:** Metrics on peaks - percentage of blacklisted and 
non-standard peaks and peak widths - and fragments - duplication rate - of 
samples.
2. **Peak Overlap:** Frequency, percentage, statistical significance of 
overlapping and non-overlapping peaks. This also includes Upset, 
precision-recall and correlation plots. 
3. **Functional Annotation:** Functional annotation (ChromHMM, ChIPseeker and 
enrichment analysis) of peaks. This also includes peak enrichment around TSS. 

***

##### Input Datasets 

* Reference peakfile: `r names(reference_tidy)`
* Total of `r length(peaklist_tidy)` peak files: 

```{r name}
# print peak file names and numerate 
n <- 1
for (name in names(peaklist_tidy)){
  print(paste0("File", n, ": ", name))
  n <- n + 1
}
```

##### Code

The function call used to create the report. 

```R
EpiCompare(peakfiles = list(`r names(peaklist_tidy)`),
           genome_build = `r params$genome_build`,
           genome_build_output = `r params$genome_build_output`,
           blacklist = blacklist,
           picard_files = list(`r names(params$picard_files)`),
           reference = `r names(reference_tidy)`,
           upset_plot = `r params$upset_plot`,
           stat_plot = `r params$stat_plot`,
           chromHMM_plot = `r params$chromHMM_plot`,
           chromHMM_annotation = "`r params$chromHMM_annotation`",
           chipseeker_plot = `r params$chipseeker_plot`,
           enrichment_plot = `r params$enrichment_plot`,
           tss_plot = `r params$tss_plot`,
           precision_recall_plot = `r params$precision_recall_plot`,
           n_threshold = `r params$n_threshold`,
           corr_plot=`r params$corr_plot`,
           interact = `r params$interact`,
           save_output = `r params$save_output`,
           output_dir = "`r params$output_dir`",
           workers = `r params$workers`)
``` 

***

## 1. General Metrics {.tabset}

### Peak Information 

Column Description:

* PeakN before tidy: Total number of peaks including those blacklisted and those 
in non-standard chromosomes. 
* Blacklisted peaks removed (%): Percentage of blacklisted peaks in samples. 
E.g. [ENCODE hg19 blacklist](https://www.encodeproject.org/files/ENCFF000KJP/) 
includes regions in the hg19 genome that have anomalous and/or unstructured 
signals independent of the cell-line or experiment.
* Non-standard peaks removed (%): Percentage of peaks in non-standard and/or 
mitochondrial chromosomes.
Identified using `BRGenomics::tidyChromosomes()`.  
* PeakN after tidy: Total number of peaks after removing those in blacklisted 
regions and non-standard chromosomes. 

**NB**: EpiCompare uses *filtered* peakfiles (i.e. datasets after removing peaks
in blacklisted regions and non-standard chromosomes)

<br>

```{r, warning=FALSE, message=FALSE}
# Run peak_info()
peak_info_df <- peak_info(peaklist = peaklist,
                          blacklist = blacklist)
# Print table 
knitr::kable(peak_info_df, format = "markdown")
# Save output
save_output(save_output = params$save_output,
            file = peak_info_df,
            file_type = "data.frame",
            filename = "peak_info",
            outpath = outfile_dir)
# Remove variable
remove(peak_info_df)
```

***

### Fragment Information

Metrics on fragments is shown only if Picard summary is provided. 
See [manual](https://neurogenomics.github.io/EpiCompare/) for help. 

Column Description:

* Mapped_Fragments: Number of mapped read pairs in the file. 
* Duplication_Rate: Percentage of mapped sequence that is marked as duplicate.
* Unique_Fragments: Number of mapped sequence that is not marked as duplicate. 

<br>

```{r, warning=FALSE, results='asis'}
# Only if picard_files are provided, fragment_info() is executed 
if (!is.null(params$picard_files)){
  fragment_info_df <- fragment_info(picard_list = params$picard_files)
  # Print data frame
  print(knitr::kable(fragment_info_df, format = "markdown"))
  # Save output 
  save_output(save_output = params$save_output,
              file = fragment_info_df,
              file_type = "data.frame",
              filename = "fragment_info",
              outpath = outfile_dir)
  # Remove variable
  remove(fragment_info_df)
}   
```

***

### Peak widths 

Distribution of peak widths in samples 

<br> 

```{r,warning=FALSE,message=FALSE,fig.width=10,fig.height=fig_height}
# Boxplot of peak widths 
width_plot <- width_boxplot(peaklist = peaklist_tidy)
print(width_plot)
# Save boxplot
save_output(save_output = params$save_output,
            file = width_plot,
            file_type = "ggplot",
            filename = "width_plot",
            outpath = outfile_dir)
# Remove variable
remove(width_plot)
```

***

## 2. Peak Overlap {.tabset}

### Percentage Overlap  

Percentage of overlapping peaks between samples. 
Hover over heatmap for percentage values. 

**NOTES**: How to interpret heatmap: [Samples in x-axis of heatmap] peaks in [Samples in y-axis of heatmap] peaks. In other words:  
- *Recall: y-axis*: Percent of peaks in y-axis samples 
that overlap with peaks in x-axis samples. 
in the x-axis samples.  
- *Precision: x-axis*: Percent of peaks in x-axis samples 
that overlap with peaks in y-axis samples.  

<br>

```{r,warning=FALSE,message=FALSE,fig.width=10,fig.height=fig_height}
# Execute overlap_heatmap()
overlap_heatmap <- overlap_heatmap(peaklist = peaklist_tidy,
                                   interact = params$interact)
overlap_heatmap
# Save output 
save_output(save_output = params$save_output,
            file = overlap_heatmap,
            file_type = "ggplot",
            filename = "samples_percent_overlap",
            outpath = outfile_dir,
            interactive = params$interact)
# Delete variable
remove(overlap_heatmap)
```

***

### Upset Plot 

Upset plot of overlapping peaks between samples. See 
[here](https://jokergoo.github.io/ComplexHeatmap-reference/book/upset-plot.html)
on how to interpret the plot.   

```{r,fig.width=10,fig.height=fig_height,warning=FALSE,message=FALSE,results='asis'}
# If TRUE, execute overlap_upset_plot()
if(params$upset_plot){
  upset_plot <- overlap_upset_plot(peaklist = peaklist_tidy)
  print(upset_plot)
  # Save output 
  save_output(save_output = params$save_output,
              file = upset_plot,
              file_type = "image",
              filename = "upset_plot",
              outpath = outfile_dir)
  # Delete variable
  remove(upset_plot)
}
```

***

### Statistical Significance  

Depending on the format of the reference file, EpiCompare outputs different 
plots: 

* Reference dataset has BED6+4 format (peak calling performed with MACS2): 
EpiCompare generates paired boxplot 
per sample showing the distribution of -log10(q-value) of reference peaks that 
are overlapping and non-overlapping with the sample dataset. 
* Reference dataset does not have BED6+4 format: EpiCompare generates a barplot 
of percentage of overlapping sample peaks with the reference, coloured by 
statistical significance (adjusted p-value) of the overlap. 

**Reference peakfile**: `r names(reference_tidy)` 

Keys:

* **Overlap**: Sample peaks in Reference peaks 
* **Unique**: Sample peaks not in Reference peaks  

<br>

```{r,fig.width=10,warning=FALSE,message=FALSE,fig.height=fig_height}
# Reference is provided AND stat_plot=TRUE, execute overlap_stat_plot() 
if (!is.null(reference) && (params$stat_plot)){
  stat_plot <- overlap_stat_plot(reference = reference_tidy,
                                 peaklist = peaklist_tidy,
                                 annotation = txdb)
  print(stat_plot[[1]])
  # Save output 
  save_output(save_output = params$save_output,
              file = stat_plot[[1]],
              file_type = "ggplot",
              filename = "stat_plot",
              outpath = outfile_dir)
  # Remove variables
  remove(stat_plot)
}
```

***

### Precision-Recall Curves

The first plot shows the balance between precision and recall across multiple peak calling stringency thresholds.  

- **Precision**: Number of sample peaks in reference.
- **Recall**: Number of reference peaks in sample. 

The second plot shows F1 score 
(a score that combines precision and recall) across the different peak calling stringency thresholds.  

- **F1**: `2*(precision*recall) / (precision+recall)`


```{r,fig.width=7,warning=FALSE,message=FALSE,fig.height=fig_height}
pr_out <- NULL
if(params$precision_recall_plot &&
   (!is.null(reference))){
    pr_out <- plot_precision_recall(peakfiles = peaklist, 
                                    reference = reference_tidy,
                                    interact = params$interact,
                                    n_threshold = params$n_threshold,
                                    workers = params$workers,
                                    show_plot = FALSE) 
}
pr_out$precision_recall_plot
cat("\n")
pr_out$f1_plot
remove(pr_out)
```

***

### Correlation Plot

The correlation plot shows the correlation between the quantiles when the genome
is binned at a set size. These quantiles are based on the intensity of the peak,
dependent on the peak caller used (q-value for MACS2):

```{r,fig.width=7,warning=FALSE,message=FALSE,fig.height=fig_height}
cp_out <- NULL
if(params$corr_plot){
    cp_out <- plot_corr(peakfiles = peaklist_tidy, 
                        reference = reference_tidy,
                        genome_build = output_build,
                        interact = params$interact,
                        bin_size = params$bin_size,
                        workers = params$workers,
                        show_plot = FALSE) 
}
cp_out$corr_plot
remove(cp_out)
```

***

## 3. Functional Annotation 

### 3.1 ChromHMM {.tabset}

[ChromHMM](http://compbio.mit.edu/ChromHMM/#:~:text=ChromHMM%20is%20software%20for%20learning%20and%20characterizing%20chromatin%20states.&text=ChromHMM%20is%20based%20on%20a,one%20or%20more%20cell%20types.) 
annotates and characterises peaks into different chromatin states. ChromHMM 
annotations used in EpiCompare were obtained from
[here](http://hgdownload.cse.ucsc.edu/goldenPath/hg19/encodeDCC/wgEncodeBroadHmm/).

* Cell-type annotation file used in this analysis: __`r params$chromHMM_annotation`__

#### All samples 

ChromHMM annotation of individual samples. 

```{r, fig.width=9, warning=FALSE, message=FALSE, results='asis', fig.height=fig_height}
# If chromHMM_plot=TRUE, execute ChromHMM
if(params$chromHMM_plot){
  # Get ChromHMM annotation file 
  chromHMM_list <- get_chromHMM_annotation(cell_line = params$chromHMM_annotation)
  # Plot chromHMM
  samples_chromHMM <- plot_chromHMM(peaklist = peaklist_tidy, 
                                   chromHMM_annotation = chromHMM_list, 
                                   genome_build = output_build,
                                   interact = params$interact)
  print(samples_chromHMM)
  #Save output 
  save_output(save_output = params$save_output,
              file = samples_chromHMM,
              file_type = "ggplot",
              filename = "samples_ChromHMM",
              outpath = outfile_dir,
              interactive = params$interact)
  
  #Remove variables
  remove(samples_chromHMM)
}
```

#### **Overlap**: Sample peaks in Reference peaks 

Percentage of Sample peaks found in Reference peaks 
(**Reference peakfile: `r names(reference_tidy)`**)

```{r, fig.width=9, warning=FALSE, message=FALSE, results='asis'}
if((params$chromHMM_plot && !is.null(reference))){
  # generate data frame of percentage overlap 
  sample_in_ref_df <- overlap_percent(peaklist1 = peaklist_tidy,
                                      peaklist2 = reference_tidy,
                                      invert = FALSE)
  knitr::kable(sample_in_ref_df, format = "markdown")
}
```

ChromHMM annotation of sample peaks found in reference peaks.   

```{r, fig.width=9, warning=FALSE, message=FALSE, results='asis', fig.height=fig_height}
if((params$chromHMM_plot) && !is.null(reference)){
    # Obtain overlapping peaks 
    sample_in_ref_list <- mapply(peaklist_tidy, FUN=function(file){
        IRanges::subsetByOverlaps(x = file, 
                                  ranges = reference_tidy[[1]])
    }) 
    # Run ChromHMM
    sample_in_ref_chromHMM <- plot_chromHMM(peaklist = sample_in_ref_list,
                                            chromHMM_annotation = chromHMM_list,
                                            genome_build = output_build,
                                            interact = params$interact)
    print(sample_in_ref_chromHMM)
    
    # Save output 
    save_output(save_output = params$save_output,
                file = sample_in_ref_chromHMM,
                file_type = "ggplot",
                filename = "sample_in_ref_ChromHMM",
                outpath = outfile_dir,
                interactive = params$interact)
    
    # Remove variables
    remove(sample_in_ref_chromHMM)
}
```

#### **Overlap**: Reference peaks in Sample peaks 

Percentage of Reference peaks found in Sample peaks 
(**Reference peakfile: `r names(reference_tidy)`**)

```{r, fig.width=9, warning=FALSE, message=FALSE, results='asis'}
if ((params$chromHMM_plot) && !is.null(reference)){
    # Data frame of overlapping peaks 
    ref_in_sample_df <- overlap_percent(peaklist1 = reference_tidy,
                                        peaklist2 = peaklist_tidy,
                                        invert = FALSE)
    knitr::kable(ref_in_sample_df, format = "markdown")
}
```

ChromHMM annotation of reference peaks found in sample peaks.   

```{r, fig.width=9, warning=FALSE, message=FALSE, results='asis', fig.height=fig_height}
if ((params$chromHMM_plot) && !is.null(reference)){
  # Subset overlapping peaks
  ref_in_sample_list <- mapply(peaklist_tidy, FUN = function(file){
    IRanges::subsetByOverlaps(x = reference_tidy[[1]], 
                              ranges = file)
    }) 
  # Plot ChromHMM
  ref_in_sample_chromHMM <- plot_chromHMM(peaklist = ref_in_sample_list,
                                          chromHMM_annotation = chromHMM_list,
                                          genome_build = output_build,
                                          interact = params$interact)
  print(ref_in_sample_chromHMM)
  
  # Save output
  save_output(save_output = params$save_output,
              file = ref_in_sample_chromHMM,
              file_type = "ggplot",
              filename = "ref_in_sample_ChromHMM",
              outpath = outfile_dir,
              interactive = params$interact)
  
  # Remove variable
  remove(ref_in_sample_chromHMM)
}
```

#### **Unique**: Sample peaks not in Reference peaks 

Percentage of sample peaks not found in reference peaks 
(**Reference peakfile: `r names(reference_tidy)`**)

```{r, fig.width=9, warning=FALSE, message=FALSE, results='asis'}
if ((params$chromHMM_plot) && !is.null(reference)){
  # Data frame of non-overlapping peaks 
  sample_not_in_ref_df <- overlap_percent(peaklist1 = peaklist_tidy,
                                          peaklist2 = reference_tidy,
                                          invert = TRUE)
  knitr::kable(sample_not_in_ref_df, format = "markdown")
}
```

ChromHMM annotation of sample peaks not found in reference peaks. 

```{r, fig.width=9, warning=FALSE, message=FALSE, results='asis', fig.height=fig_height}
if ((params$chromHMM_plot) && !is.null(reference)){
  sample_not_in_ref_list <- mapply(peaklist_tidy, FUN = function(file){
    IRanges::subsetByOverlaps(x = file, 
                              ranges = reference_tidy[[1]], 
                              invert = TRUE)
    }) 
  # Run ChromHMM
  sample_not_in_ref_chromHMM<-plot_chromHMM(peaklist = sample_not_in_ref_list,
                                            chromHMM_annotation = chromHMM_list,
                                            genome_build = output_build,
                                            interact = params$interact)
  print(sample_not_in_ref_chromHMM)
  
  # Save output 
  save_output(save_output = params$save_output,
              file = sample_not_in_ref_chromHMM,
              file_type = "ggplot",
              filename = "sample_not_in_ref_ChromHMM",
              outpath = outfile_dir,
              interactive = params$interact)
  
  # Remove variable
  remove(sample_not_in_ref_chromHMM)
}

```

#### **Unique**: Reference peaks not in Sample peaks 

Percentage of reference peaks not found in sample peaks 
(**Reference peakfile: `r names(reference_tidy)`**)

```{r, fig.width=9, warning=FALSE, message=FALSE, results='asis'}
if ((params$chromHMM_plot) && !is.null(reference)){
  # Data frame of non-overlapping peaks 
  ref_not_in_sample_df <- overlap_percent(peaklist1 = reference_tidy,
                                          peaklist2 = peaklist_tidy,
                                          invert = TRUE)
  knitr::kable(ref_not_in_sample_df, format = "markdown")
}
```

ChromHMM annotation of reference peaks not found in sample peaks. 

```{r, fig.width=9, warning=FALSE, message=FALSE, results='asis', fig.height=fig_height}
if ((params$chromHMM_plot) && !is.null(reference)){
  # Subset unique peaks 
  ref_not_in_sample_list <- mapply(peaklist_tidy, FUN = function(file){
    IRanges::subsetByOverlaps(x = reference_tidy[[1]], 
                              ranges = file, 
                              invert = TRUE)
    })
  # Run ChromHMM
  ref_not_in_sample_chromHMM<-plot_chromHMM(peaklist = ref_not_in_sample_list,
                                            chromHMM_annotation = chromHMM_list,
                                            genome_build = output_build,
                                            interact = params$interact)
  print(ref_not_in_sample_chromHMM)
  
  # Save output
  save_output(save_output = params$save_output,
              file = ref_not_in_sample_chromHMM,
              file_type = "ggplot",
              filename = "ref_not_in_sample_ChromHMM",
              outpath = outfile_dir,
              interactive = params$interact)
  # Remove variable 
  remove(ref_not_in_sample_chromHMM)
}
```

***

### 3.2 ChIPseeker 

EpiCompare uses `ChIPseeker::annotatePeak()` to annotate peaks with the nearest 
gene and genomic regions where the peak is located. The peaks are annotated 
with genes taken from human genome annotations (hg19 or hg38) provided by 
Bioconductor.

```{r, fig.width=9, warning=FALSE, message=FALSE}
# if set TRUE, generate chipseeker annotation plot 
if(params$chipseeker_plot){
  chipseeker_plot <- plot_ChIPseeker_annotation(peaklist = peaklist_tidy,
                                                annotation = txdb)
  print(chipseeker_plot)
  # Save output 
  save_output(save_output = params$save_output,
              file = chipseeker_plot,
              file_type = "ggplot",
              filename = "chipseeker_annotation",
              outpath = outfile_dir)
  # Remove variable
  remove(chipseeker_plot)
}
```

***

### 3.3 Functional Enrichment Analysis {.tabset}

EpiCompare performs KEGG pathway and GO enrichment analysis using 
`clusterProfiler`. `ChIPseeker::annotatePeak()` is first used to assign peaks 
to nearest genes. Biological themes amongst the genes are identified using 
ontologies (KEGG and GO). The peaks are annotated with genes taken from 
annotations of human genome (hg19 or hg38) provided by Bioconductor.


```{r, warning=FALSE, message=FALSE, include=FALSE}
# Run plot_enrichment()
if (params$enrichment_plot){
  enrichment_plots <- plot_enrichment(peaklist = peaklist_tidy,
                                      annotation = txdb)
  KEGG_plot <- enrichment_plots[[1]]
  GO_plot <- enrichment_plots[[2]]
  
  # Remove variable
  remove(enrichment_plots)
  
  # Figure height
  max_terms <- max(length(unique(KEGG_plot$data$Description)),
                   length(unique(GO_plot$data$Description)))
  fig_height <- fig_length(default_size = 10,
                                      number_of_items = max_terms,
                                      max_items = 20)
}
```

***

#### KEGG

```{r,fig.width=10,fig.height=fig_height,warning=FALSE,message=FALSE}
if (params$enrichment_plot){
  print(KEGG_plot)
  # Save output 
  save_output(save_output = params$save_output,
              file = KEGG_plot,
              file_type = "ggplot",
              filename = "KEGG_analysis",
              outpath = outfile_dir)
  # Remove variable
  remove(KEGG_plot)
}
```

***

#### GO 

```{r,fig.width=10,fig.height=fig_height,warning=FALSE,message=FALSE}
if (params$enrichment_plot){
  print(GO_plot)
  # Save output 
  save_output(save_output = params$save_output,
              file = GO_plot,
              file_type = "ggplot",
              filename = "GO_analysis",
              outpath = outfile_dir)
  # Remove variable
  remove(GO_plot)
}

```

***

### 3.4 Peak Frequency around TSS 

This plots peaks that are mapping to transcriptional start sites (TSS). 
TSS regions are defined as the flanking sequence of the TSS sites. 
The frequency of peaks upstream (-3000bp) and downstream (+3000bp) of 
TSS is plotted. Faint color line around the main frequency line represents 
the 95% confidence interval estimated by bootstrap method. 


```{r,fig.height=3,fig.width=10,warning=FALSE,message=FALSE}
# Run tss_plot()
if (params$tss_plot){
  tssplt <- tss_plot(peaklist = peaklist_tidy,
                     annotation = txdb,
                     workers = params$workers)
  # Print plot
    for (plot in tssplt){
      print(plot)
    }
}
```


### 4. Session Info

<details> 

```{r Session Info}
utils::sessionInfo()
```

</details>  

