---
title: "SCTK Cell QC Report"
date: "`r format(Sys.time(), '%B %d, %Y')`"
params: 
  object: object
  subTitle: subTitle
  studyDesign: studyDesign
output:
  html_document:
    number_sections: yes
    toc: yes
    toc_float: true
    collapsed: false
    code_folding: hide
    html_notebook: default
---

<style>
body {
text-align: justify}
</style>

```{r "CellQC-lib", warning=FALSE, include=FALSE}
require(singleCellTK)
require(ggplot2)
require(dplyr)

metaChecking <- function(metainfo, sample){
  if (any(!sample %in% names(metainfo))) {

    ### if length of metainfo is 1, it indicates that the name is the sample name
    ### This format is compatible with the QC report.
    ### In this case, all samples are ran with single run. Return any sublist is fine. 
    if (length(names(metainfo)) == 1) {
      names(metainfo) <- sample
      return(metainfo)
    }

    ### if QC is ran in R console instead of QC pipeline, we will add place holder.
    ### In this case, different samples also share parameters. Return anny sublist is fine 
    newMeta <- list() 
    for (sample in samples) {
      newMeta[[sample]] <- metainfo
    }
    metainfo <- newMeta
  }

  return(metainfo)
}

preprocessMeta <- function(meta, ignore=c("geneSetCollection", "sample")){
  meta <- meta[!names(meta) %in% ignore]
  lapply(meta, function(y){
    while(is.list(y)) {
      if (length(y) != 0){
       y <- y[[1]]  
      } else {
       y <- "NULL"
      }
    }
      
    if(is.vector(y)) {
      y <- paste(y,collapse=' ')
    }
      
    if(is.null(y)) {
      y <- "NULL"
    }
      
    return(y)
  })
}

formatPlotList <- function(plotlist, samples) {
  if (length(samples) > 1) {
    return(plotlist)
  }
  
  plotlist <- list(Sample = list(plotlist))
  names(plotlist$Sample) <- samples
  return(plotlist)
}

```

```{r, "CellQC-import", eval = TRUE, include=FALSE}
sce.qc <- params$object
subTitle <- params$subTitle
studyDesign <- params$studyDesign
sceSample <- colData(sce.qc)$sample
samples <- unique(sceSample)

sce.qc <- getUMAP(sce.qc, useAssay = "counts", reducedDimName = "QC_UMAP", sample = sceSample)

### when 'sample' doesnn't exists in colData
if (is.null(samples)) { samples <- "sample" }

```

---
subtitle: "`r subTitle`"
---
`r studyDesign`
<br />


# Introduction
Comprehensive quality control (QC) of single-cell RNA-seq data was performed with the [**singleCellTK**](https://github.com/compbiomed/singleCellTK/tree/devel) package. This report contains information about each QC tool and visualization of the QC metrics for each sample. For more information on running this pipeline and performing quality control, see the [**documentation**](https://www.camplab.net/sctk/v2.2.1/articles/articles/cmd_qc.html). If you use the singleCellTK package for quality control, please include a [**reference**](https://www.biorxiv.org/content/10.1101/329755v1.article-info) in your publication.
<br />
<br />

```{r, "runPerCellQC-description", include=FALSE, warning=FALSE, message=FALSE}
description_runPerCellQC <- descriptionRunPerCellQC()
```

# Summary Statistics {.tabset .tabset-fade}
# {.unlisted .unnumbered .toc-ignore .tabset .tabset-fade}
```{r "SummaryStats", echo = FALSE, results="asis", fig.align="center", warning=FALSE, message=FALSE}
cat("\n")

summaryTable <- sampleSummaryStats(inSCE = sce.qc, 
                                   sample = sceSample,
                                   simple = FALSE)

cat(apply(summaryTable, 1:2, as.character) %>% 
    knitr::kable(format = "html") %>%
      kableExtra::kable_styling() %>%
      kableExtra::scroll_box(width = "80%"))
    
cat("\n")
  summary <- "The summary statistics table summarizes QC metrics of the cell matrix. This table summarizes the mean and median of UMI counts and median of genes detected per cell, as well as the number and percentages of doublets and estimated ambient RNA scores per dataset."
  cat(summary)
  cat("\n\n") 
#}
cat("\n")
```


```{r, "General quality control metrics", results="asis", fig.align="center", warning=FALSE, message=FALSE, echo=FALSE}
i="General quality control metrics"
# cat(paste0('# ', i, ' \n'))
# cat("\n")

perCellData <- c("sum", "detected", "percent.top_50")
skipCellData <- any(!perCellData %in% names(colData(sce.qc)))

if (skipCellData) {
  #cat("runPerCellQC did not complete successfully. The section of General quality control metrics is skipped")
  plotsQCMetrics <- NULL
} else {
  cat(paste0('# ', i, ' \n'))
  cat("\n")
  plotsQCMetrics<- tryCatch(
    {plotRunPerCellQCResults(sce.qc, 
                             sample = colData(sce.qc)$sample,
                             combinePlot="none",
                             axisSize = NULL,
                             axisLabelSize = NULL,
                             titleSize = NULL)},
    error = function(e) {
      cat("runPerCellQC did not complete successfully. The section of General quality control metrics is skipped")
      skipCellData <- TRUE
      return(NA)
    }
  )
}

if (!skipCellData) {
  
  if (length(samples) == 1) {
    plotsQCMetrics <- list(Violin=plotsQCMetrics)
  }
  names(plotsQCMetrics$Violin)[names(plotsQCMetrics$Violin) == "subsets_mito_percent"] <- "Mito_Subset_Top50_Percent"
  names(plotsQCMetrics$Violin)[names(plotsQCMetrics$Violin) == "subsets_mito_sum"] <- "Mito_Subset_Sum"
  names(plotsQCMetrics$Violin)[names(plotsQCMetrics$Violin) == "subsets_mito_detected"] <- "Mito_Subset_Features"
  geneSubsetData <- grep("subsets_.*", names(plotsQCMetrics$Violin), value = TRUE)
  geneSubsetName <- unique(gsub("_sum|_detected|_percent","",
                                gsub("subsets_","",geneSubsetData)))
  
  cat(description_runPerCellQC$introduction)
  cat(description_runPerCellQC$runPerCellQC)
  cat(description_runPerCellQC$plotRunPerCellQCResults)
  cat(description_runPerCellQC$output)
  cat(description_runPerCellQC$sum)
  cat(description_runPerCellQC$detected)
  cat(description_runPerCellQC$percentTop)
  cat(description_runPerCellQC$subsets)
}
```


# {.unlisted .unnumbered .toc-ignore .tabset .tabset-fade}
```{r "plotsQCMetrics-plot", results="asis", eval=(!skipCellData), fig.align="center", warning=FALSE, message=FALSE, echo=FALSE}
cat("\n")
cat(paste0('## Total Counts {.tabset .tabset-fade} \n\n'))
plotsQCMetrics$Violin$Sum
cat("\n\n")
cat(paste0('## Total Features {.tabset .tabset-fade} \n\n'))
plotsQCMetrics$Violin$Detected
cat("\n\n")
cat(paste0('## Percentage of Library Size Occupied by Top 50 Expressed Features {.tabset .tabset-fade} \n\n'))
plotsQCMetrics$Violin$TopPercent
if(!is.null(plotsQCMetrics$Violin$Mito_Subset_Sum)){
  cat("\n\n")
  cat(paste0('## Total Mitochondrial Counts {.tabset .tabset-fade} \n\n'))
  plotsQCMetrics$Violin$Mito_Subset_Sum
}
if(!is.null(plotsQCMetrics$Violin$Mito_Subset_Features)){
  cat("\n\n")
  cat(paste0('## Total Mitochondrial Features {.tabset .tabset-fade} \n\n'))
  plotsQCMetrics$Violin$Mito_Subset_Features
}
if(!is.null(plotsQCMetrics$Violin$Mito_Subset_Top50_Percent)){
  cat("\n\n")
  cat(paste0('## Percentage of Mitochondrial Counts {.tabset .tabset-fade} \n\n'))
  plotsQCMetrics$Violin$Mito_Subset_Top50_Percent
}


if(length(geneSubsetName) > 0){
  for(ix in seq_along(geneSubsetName)){
    cat("\n\n")
    cat(paste0('## Total Counts of Feature Subset "', geneSubsetName[ix], '"{.tabset .tabset-fade} \n\n'))
    print(plotsQCMetrics$Violin[[paste0("subsets_",geneSubsetName[ix],"_sum")]])
    cat("\n\n")
    cat(paste0('## Total Features within Feature Subset "', geneSubsetName[ix], '"{.tabset .tabset-fade} \n\n'))
    print(plotsQCMetrics$Violin[[paste0("subsets_",geneSubsetName[ix],"_detected")]])
    cat("\n\n")
    cat(paste0('## Percentage of Feature Subset "', geneSubsetName[ix], '" Expression{.tabset .tabset-fade} \n\n'))
    print(plotsQCMetrics$Violin[[paste0("subsets_",geneSubsetName[ix],"_percent")]])
  }
}

cat("\n\n")
cat(paste0('## Parameters {.tabset .tabset-fade} \n\n'))

runPerCellMeta <- sce.qc@metadata$scater_addPerCellQC
runPerCellMeta <- metaChecking(runPerCellMeta, samples[[1]])
x <- preprocessMeta(runPerCellMeta[[ samples[[1]] ]])
t(as.data.frame(x)) %>%
  knitr::kable(format = "html") %>% kableExtra::kable_styling() %>%
  kableExtra::scroll_box(width = "80%")

cat("\n")
cat(description_runPerCellQC$parameter)
```
`r cat("\n\n")`



# Doublet Detection
```{r, "Scrublet-description", include=FALSE, warning=FALSE, message=FALSE}
description_Scrublet <- descriptionScrublet()
```

```{r, "Scrublet", results="asis", fig.align="center", warning=FALSE, message=FALSE, echo = FALSE}
i="Scrublet"
# cat(paste0('## ', i, ' \n'))

scrubletData <- c("scrublet_score", "scrublet_call")
skipScrublet <- any(!scrubletData %in% names(colData(sce.qc)))

if (skipScrublet) {
  #cat("runScrublet did not complete successfully. The section of Scrublet is skipped")
  plotsScrublet <- NULL
} else {
  cat(paste0('## ', i, ' \n'))
    plotsScrublet<- tryCatch(
      {plotScrubletResults(sce.qc, 
                           reducedDimName="QC_UMAP",
                           sample = colData(sce.qc)$sample,
                           combinePlot = "none",
                           axisSize = NULL,
                           axisLabelSize = NULL,
                           titleSize = NULL)},
    error = function(e) {
      cat("runScrublet did not complete successfully. The section of Scrublet is skipped")
      skipScrublet <- TRUE
      return(NA)
    }
  )
}

if (!skipScrublet) {
  plotsScrublet <- formatPlotList(plotsScrublet, samples)
  cat(description_Scrublet$introduction)
  cat(description_Scrublet$runScrublet)
  cat(description_Scrublet$plotScrubletResults)
  cat(description_Scrublet$output)
  cat("\n")
}
```


```{r "Scrublet-plot", echo=FALSE, eval=(!skipScrublet), results="asis", fig.align="center"}
cat("## {.unlisted .unnumbered .toc-ignore .tabset .tabset-fade}")
cat("\n")
for (sample in samples) {
  cat(paste0("### ", sample, " {.tabset .tabset-fade} \n"))
  cat("\n\n")
  
  cat("#### Scrublet Doublet Score {.tabset .tabset-fade} \n")
  print(plotsScrublet$Sample[[sample]][["scatter_doubletScore"]])
  cat("\n\n")
  
  cat("#### Density Score {.tabset .tabset-fade} \n")
  print(plotsScrublet$Sample[[sample]][["density_doubletScore"]])
  cat("\n\n")
  
  cat("#### Violin Score {.tabset .tabset-fade} \n ")
  print(plotsScrublet$Sample[[sample]][["violin_doubletScore"]])
  cat("\n\n")
  
  cat("#### Scrublet Doublet Assignment {.tabset .tabset-fade} \n\n")
  print(plotsScrublet$Sample[[sample]][["scatter_doubletCall"]])
  cat("\n\n")  
  
  cat("#### Parameters {.tabset .tabset-fade} \n\n")
  runScrubletMeta <- sce.qc@metadata$runScrublet
  runScrubletMeta <- metaChecking(runScrubletMeta, sample)
  # if(length(samples) == 1) {
  #   runScrubletMeta <- list(runScrubletMeta)
  #   names(runScrubletMeta) <- sample
  # }
  
  x <- preprocessMeta(runScrubletMeta[[sample]])
  cat(t(as.data.frame(x)) %>%
    knitr::kable(format = "html") %>% kableExtra::kable_styling() %>%
    kableExtra::scroll_box(width = "80%"))
  cat(description_Scrublet$additionalParam)
  cat("\n\n")
}
cat("\n")
```


```{r, "DoubletFinder-description", include=FALSE, warning=FALSE, message=FALSE}
description_DoubletFinder <- descriptionDoubletFinder()
```

```{r, "DoubletFinder-0", results="asis", fig.align="center", warning=FALSE, message=FALSE, echo=FALSE}
i="DoubletFinder"
# cat(paste0('## ', i, ' \n'))


doubletFinderData <- grep("doubletFinder_doublet", names(colData(sce.qc)), value=TRUE)
skipFinder <- length(doubletFinderData)==0  

if (skipFinder) {
  #cat("runDoubletFinder did not complete successfully. The section of DoubletFinder is skipped")
  plotDoubletFinder <- NULL
} else {
  cat(paste0('## ', i, ' \n'))
  plotDoubletFinder<- tryCatch(
    {plotDoubletFinderResults(inSCE = sce.qc, 
                              reducedDimName = "QC_UMAP",
                              sample = colData(sce.qc)[['sample']],
                              combinePlot = "none",
                              axisSize = NULL,
                              axisLabelSize = NULL,
                              titleSize = NULL)},
    error = function(e) {
      cat("runDoubletFinder did not complete successfully. The section of DoubletFinder is skipped")
      skipFinder <- TRUE
      return(NA)
    }
  )
}

if (!skipFinder) {
  plotDoubletFinder <- formatPlotList(plotDoubletFinder, samples)
  resolutions <- grep("doubletFinder_doublet_score_resolution_", colnames(colData(sce.qc)), value = TRUE)
  resolutions <- gsub("doubletFinder_doublet_score_resolution_", "", resolutions)
  
  cat(description_DoubletFinder$introduction)
  cat(description_DoubletFinder$runDoubletFinder)
  cat(description_DoubletFinder$plotDoubletFinderResults)
  cat(description_DoubletFinder$output)
  cat("\n")
}
```

```{r "DoubletFinder-plot", echo=FALSE, eval=!(skipFinder), results="asis", fig.align="center"}
cat("## {.unlisted .unnumbered .toc-ignore .tabset .tabset-fade}")
cat("\n")
for (sample in samples) {
  cat(paste0("### ", sample, " {.tabset .tabset-fade} \n"))
  cat("\n")
  for (resolution in resolutions) {
    cat(paste0("#### Resolution: ", resolution, " {.tabset .tabset-fade} \n"))
    cat("\n")
    
    cat("##### DoubletFinder Doublet Score {.tabset .tabset-fade} \n\n")
    print(plotDoubletFinder$Sample[[sample]][[paste0("Scatter_Score_resolution_", resolution)]])
    cat("\n\n")
    
    cat("##### Density of Doublet Score {.tabset .tabset-fade} \n\n")
    print(plotDoubletFinder$Sample[[sample]][[paste0("Density_resolution_", resolution)]])
    cat("\n\n")
    
    cat("##### Violin of Doublet Score {.tabset .tabset-fade} \n\n")
    print(plotDoubletFinder$Sample[[sample]][[paste0("violin_resolution_", resolution)]])
    cat("\n\n")
    
    cat("##### DoubletFinder Doublet Assignment {.tabset .tabset-fade} \n\n")
    print(plotDoubletFinder$Sample[[sample]][[paste0("Scatter_Call_resolution_", resolution)]])
    cat("\n\n")
    
    cat("##### Parameters {.tabset .tabset-fade} \n\n")
    DoubletFinderMeta <- sce.qc@metadata$runDoubletFinder
    DoubletFinderMeta <- metaChecking(DoubletFinderMeta, sample)

    # if(length(samples) == 1) {
    #   DoubletFinderMeta <- list(DoubletFinderMeta)
    #   names(DoubletFinderMeta) <- sample
    # }
    
    x <- preprocessMeta(DoubletFinderMeta[[sample]])
    cat(t(as.data.frame(x)) %>%
      knitr::kable(format = "html") %>% kableExtra::kable_styling() %>%
      kableExtra::scroll_box(width = "80%"))
    
    cat(description_DoubletFinder$seuratRes)
    cat(description_DoubletFinder$seuratNfeatures)
    cat(description_DoubletFinder$seuratPCs)
    cat(description_DoubletFinder$seuratFormationRate)
    cat("\n\n")
  }
}
cat("\n")
```


```{r, "ScDblFinder-description", include=FALSE, warning=FALSE, message=FALSE}
description_ScDblFinder<- descriptionScDblFinder()
```

```{r, "ScDblFinder", results="asis", fig.align="center", warning=FALSE, message=FALSE, echo=FALSE}
i="ScDblFinder"
#cat(paste0('## ', i, ' \n'))

scDblFinderData <- c("scDblFinder_doublet_score")
skipScDblFinder <- any(!scDblFinderData %in% names(colData(sce.qc)))

if (skipScDblFinder) {
  #cat("runScDblFinder did not complete successfully. The section of ScDblFinder is skipped")
  plotScDblFinder <- NULL
} else {
  cat(paste0('## ', i, ' \n'))
  plotScDblFinder<- tryCatch(
    {plotScDblFinderResults(inSCE = sce.qc, 
                            sample = colData(sce.qc)[['sample']],
                            combinePlot = "none",
                            reducedDimName = "QC_UMAP",
                            axisSize = NULL,
                            axisLabelSize = NULL,
                            titleSize = NULL)},
    error = function(e) {
      cat("runScDblFinder did not complete successfully. The section of ScDblFinder is skipped")
      skipScDblFinder <- TRUE
      return(NA)
    }
  )
}

if(!skipScDblFinder) {
  plotScDblFinder <- formatPlotList(plotScDblFinder, samples)
  cat(description_ScDblFinder$introduction)
  cat(description_ScDblFinder$runScDblFinder)
  cat(description_ScDblFinder$plotScDblFinderResults)
  cat(description_ScDblFinder$output)
  cat("\n")
}
```

```{r "ScDblFinder-plot", echo=FALSE, eval=!(skipScDblFinder), results="asis", fig.align="center"}
cat("## {.unlisted .unnumbered .toc-ignore .tabset .tabset-fade}")
cat("\n")
for (sample in samples){
  cat(paste0("### ", sample, " {.tabset .tabset-fade} \n"))
  cat("\n\n")
  
  cat("#### ScDblFinder Doublet Score {.tabset .tabset-fade} \n\n ")
  print(plotScDblFinder$Sample[[sample]][["scatter_doubletScore"]])
  cat("\n\n")
  
  cat("#### Density Score {.tabset .tabset-fade} \n\n")
  print(plotScDblFinder$Sample[[sample]][["density_doubletScore"]])
  cat("\n\n")
  
  cat("#### Violin Score {.tabset .tabset-fade} \n\n")
  print(plotScDblFinder$Sample[[sample]][["violin_doubletScore"]])
  cat("\n\n")
  
  cat("#### Parameters {.tabset .tabset-fade} \n\n")
  ScDblFinderMeta <- sce.qc@metadata$runScDblFinder
  ScDblFinderMeta <- metaChecking(ScDblFinderMeta, sample)

  # if(length(samples) == 1) {
  #   DoubletCellMeta <- list(DoubletCellMeta)
  #   names(DoubletCellMeta) <- sample
  # }
  
  x <- preprocessMeta(ScDblFinderMeta[[sample]])
  cat(t(as.data.frame(x)) %>%
    knitr::kable(format = "html") %>% kableExtra::kable_styling() %>%
    kableExtra::scroll_box(width = "80%"))
  cat(description_ScDblFinder$parameter)
  cat("\n\n")
}
cat("\n")
```


```{r, "Cxds-description", include=FALSE, warning=FALSE, message=FALSE}
descriprion_CxdsResults<- descriptionCXDS()
```

```{r, "Cxds", results="asis", fig.align="center", warning=FALSE, message=FALSE, echo=FALSE}
i="Cxds"
# cat(paste0('## ', i, ' \n'))

cvdsData <- c("scds_cxds_score", "scds_cxds_call")
skipCxds <- any(!cvdsData %in% names(colData(sce.qc)))

if (skipCxds) {
  #cat("runCxds did not complete successfully. The section of Cxds is skipped")
  plotCxds <- NULL
} else {
  cat(paste0('## ', i, ' \n'))
  plotCxds<- tryCatch(
    {plotCxdsResults(inSCE = sce.qc, 
                     sample = colData(sce.qc)[['sample']],
                     combinePlot = "none",
                     reducedDimName = "QC_UMAP",
                     axisSize = NULL,
                     axisLabelSize = NULL,
                     titleSize = NULL)},
    error = function(e) {
      cat("runCxds did not complete successfully. The section of Cxds is skipped")
      skipCxds <- TRUE
      return(NA)
    }
  )
}

if (!skipCxds) {
  plotCxds <- formatPlotList(plotCxds, samples)
  cat(descriprion_CxdsResults$introduction)
  cat(descriprion_CxdsResults$runCxds)
  cat(descriprion_CxdsResults$plotCxdsResults)
  cat(descriprion_CxdsResults$output)
  cat("\n")
}
```

```{r "Cxds-plot", echo=FALSE,eval=(!skipCxds), results="asis", fig.align="center"}
cat("## {.unlisted .unnumbered .toc-ignore .tabset .tabset-fade}")
cat("\n")
for (sample in samples){
  cat(paste0("### ", sample, " {.tabset .tabset-fade} \n"))
  cat("\n\n")
  
  cat("#### Cxds Doublet Score {.tabset .tabset-fade} \n\n")
  plot(plotCxds$Sample[[sample]][["scatter_doubletScore"]])
  cat("\n\n")
  
  cat("#### Density Score {.tabset .tabset-fade} \n\n")
  plot(plotCxds$Sample[[sample]][["density_doubletScore"]])
  cat("\n\n")
  
  cat("#### Violin Score {.tabset .tabset-fade} \n\n")
  plot(plotCxds$Sample[[sample]][["violin_doubletScore"]])
  cat("\n\n")
  
  cat("#### Cxds Doublet Assignment {.tabset .tabset-fade} \n\n")
  plot(plotCxds$Sample[[sample]][["scatter_doubletCall"]])
  cat("\n\n")
  
  cat("#### Parameters {.tabset .tabset-fade} \n\n")
  CxdsMeta <- sce.qc@metadata$runCxds
  CxdsMeta <- metaChecking(CxdsMeta, sample)

  # if(length(samples) == 1) {
  #   CxdsMeta <- list(CxdsMeta)
  #   names(CxdsMeta) <- sample
  # }
  
  x <- preprocessMeta(CxdsMeta[[sample]])
  cat(t(as.data.frame(x)) %>%
    knitr::kable(format = "html") %>% kableExtra::kable_styling() %>%
    kableExtra::scroll_box(width = "80%"))
  
  cat(descriprion_CxdsResults$nTop)
  cat(descriprion_CxdsResults$binThresh)
  cat(descriprion_CxdsResults$verb)
  cat(descriprion_CxdsResults$retRes)
  cat(descriprion_CxdsResults$estNdbl)
  cat("\n\n")
  
}
cat("\n")
```


```{r, "Bcds-description", include=FALSE, warning=FALSE, message=FALSE}
descriprion_BcdsResults<- descriptionBCDS()
```

```{r, "Bcds", results="asis", fig.align="center", warning=FALSE, message=FALSE, echo=FALSE}
i="Bcds"
# cat(paste0('## ', i, ' \n'))

bcdsData <- c("scds_bcds_score", "scds_bcds_call")
skipBcds <- any(!bcdsData %in% names(colData(sce.qc)))

if (skipBcds) {
  #cat("runBcds did not complete successfully. The section of Bcds is skipped")
  plotBcds <- NULL
} else {
  cat(paste0('## ', i, ' \n'))
  plotBcds<- tryCatch(
    {plotBcdsResults(inSCE = sce.qc, 
                     sample = colData(sce.qc)[['sample']],
                     combinePlot = "none",
                     reducedDimName = "QC_UMAP",
                     axisSize = NULL,
                     axisLabelSize = NULL,
                     titleSize = NULL)},
    error = function(e) {
      cat("runBcds did not complete successfully. The section of Bcds is skipped")
      skipBcds <- TRUE
      return(NA)
    }
  )
}

if (!skipBcds) {
  plotBcds <- formatPlotList(plotBcds, samples)
  cat(descriprion_BcdsResults$introduction)
  cat(descriprion_BcdsResults$runBcds)
  cat(descriprion_BcdsResults$plotBcdsResults)
  cat(descriprion_BcdsResults$output)
  cat("\n")
}
```

```{r "Bcds-plot", echo=FALSE, eval=(!skipBcds), results="asis", fig.align="center"}
cat("## {.unlisted .unnumbered .toc-ignore .tabset .tabset-fade}")
cat("\n")
for (sample in samples){
  cat(paste0("### ", sample, " {.tabset .tabset-fade} \n"))
  cat("\n\n")
  
  cat("#### Bcds Doublet Score {.tabset .tabset-fade} \n\n")
  plot(plotBcds$Sample[[sample]][["scatter_doubletScore"]])
  cat("\n\n")
  
  cat("#### Density Score {.tabset .tabset-fade} \n\n")
  plot(plotBcds$Sample[[sample]][["density_doubletScore"]])
  cat("\n\n")
  
  cat("#### Violin Score {.tabset .tabset-fade} \n\n")
  plot(plotBcds$Sample[[sample]][["violin_doubletScore"]])
  cat("\n\n")
  
  cat("#### Bcds Doublet Assignment {.tabset .tabset-fade} \n\n")
  plot(plotBcds$Sample[[sample]][["scatter_doubletCall"]])
  cat("\n\n")
  
  cat("#### Parameters {.tabset .tabset-fade} \n\n")
  BcdsMeta <- sce.qc@metadata$runBcds
  BcdsMeta <- metaChecking(BcdsMeta, sample)

  # if(length(samples) == 1) {
  #   BcdsMeta <- list(BcdsMeta)
  #   names(BcdsMeta) <- sample
  # }
  
  x <- preprocessMeta(BcdsMeta[[sample]])
  cat(t(as.data.frame(x)) %>%
    knitr::kable(format = "html") %>% kableExtra::kable_styling() %>%
    kableExtra::scroll_box(width = "80%"))
  
  cat(descriprion_BcdsResults$nTop)
  cat(descriprion_BcdsResults$srat)
  cat(descriprion_BcdsResults$nmax)
  cat(descriprion_BcdsResults$varImp)
  cat("\n\n")
  
}
cat("\n")
```



```{r, "ScdsHybrid-description", include=FALSE, warning=FALSE, message=FALSE}
description_ScdsHybrid<- descriptionScdsHybrid()
```


```{r, "ScdsHybrid", results="asis", fig.align="center", warning=FALSE, message=FALSE, echo=FALSE}
i="ScdsHybrid"
# cat(paste0('## ', i, ' \n'))

hybridData <- c("scds_hybrid_score", "scds_hybrid_call")
skipScdsHybrid <- any(!hybridData %in% names(colData(sce.qc)))

if (skipScdsHybrid) {
  #cat("runCxdsBcdsHybrid did not complete successfully. The section of ScdsHybrid is skipped")
  plotScdsHybrid <- NULL
} else {
  cat(paste0('## ', i, ' \n'))
  plotScdsHybrid<- tryCatch(
    {plotScdsHybridResults(inSCE = sce.qc, 
                           sample = colData(sce.qc)[['sample']],
                           combinePlot = "none",
                           reducedDimName = "QC_UMAP",
                           axisSize = NULL,
                           axisLabelSize = NULL,
                           titleSize = NULL)},
    error = function(e) {
      cat("runCxdsBcdsHybrid did not complete successfully. The section of ScdsHybrid is skipped")
      skipScdsHybrid <- TRUE
      return(NA)
    }
  )
}

if (!skipScdsHybrid) {
  plotScdsHybrid <- formatPlotList(plotScdsHybrid, samples)
  cat(description_ScdsHybrid$introduction)
  cat(description_ScdsHybrid$runCxdsBcdsHybrid)
  cat(description_ScdsHybrid$plotScdsHybridResults)
  cat(description_ScdsHybrid$output)
  cat("\n")
}
```

```{r "ScdsHybrid-plot", echo=FALSE, eval=(!skipScdsHybrid), results="asis", fig.align="center"}
cat("## {.unlisted .unnumbered .toc-ignore .tabset .tabset-fade}")
cat("\n")
for (sample in samples){
  cat(paste0("### ", sample, " {.tabset .tabset-fade} \n"))
  cat("\n\n")
  
  cat("#### ScdsHybrid Doublet Score {.tabset .tabset-fade} \n\n")
  plot(plotScdsHybrid$Sample[[sample]][["scatter_doubletScore"]])
  cat("\n\n")
  
  cat("#### Density Score {.tabset .tabset-fade} \n\n")
  plot(plotScdsHybrid$Sample[[sample]][["density_doubletScore"]])
  cat("\n\n")
  
  cat("#### Violin Score {.tabset .tabset-fade} \n\n")
  plot(plotScdsHybrid$Sample[[sample]][["violin_doubletScore"]])
  cat("\n\n")
  
  cat("#### ScdsHybrid Doublet Assignment {.tabset .tabset-fade} \n\n")
  plot(plotScdsHybrid$Sample[[sample]][["scatter_doubletCall"]])
  cat("\n\n")
  
  cat("#### Parameters {.tabset .tabset-fade} \n\n")
  HybridMeta <- sce.qc@metadata$runCxdsBcdsHybrid
  HybridMeta <- metaChecking(HybridMeta, sample)

  # if(length(samples) == 1) {
  #   HybridMeta <- list(HybridMeta)
  #   names(HybridMeta) <- sample
  # }
  
  x <- preprocessMeta(HybridMeta[[sample]])
  cat(t(as.data.frame(x)) %>%
    knitr::kable(format = "html") %>% kableExtra::kable_styling() %>%
    kableExtra::scroll_box(width = "80%"))
  
  cat(description_ScdsHybrid$parameters)
  cat("\n\n")
}
cat("\n")
```
`r cat("\n")`


# Ambient RNA Detection
```{r, "DecontX-description", include=FALSE, warning=FALSE, message=FALSE}
description_DecontX<- descriptionDecontX()
```

```{r, "DecontX", results="asis", fig.align="center", warning=FALSE, message=FALSE, echo=FALSE}
i="DecontX"
# cat(paste0('## ', i, ' \n'))

decontXData <- c("decontX_contamination", "decontX_clusters")
skipDecontX <- any(!decontXData %in% names(colData(sce.qc)))

if (skipDecontX) {
  #cat("runDecontX did not complete successfully. The section of DecontX is skipped")
  plotDecontX <- NULL
} else {
  cat(paste0('## ', i, ' \n'))
  plotDecontX<- tryCatch(
    {plotDecontXResults(inSCE = sce.qc, 
                        sample = colData(sce.qc)[['sample']],
                        combinePlot = "none",
                        reducedDimName = "QC_UMAP",
                        axisSize = NULL,
                        axisLabelSize = NULL,
                        titleSize = NULL)},
    error = function(e) {
      cat("runDecontX did not complete successfully. The section of DecontX is skipped")
      skipDecontX <- TRUE
      return(NA)
    }
  )
}

if (!skipDecontX) {
  plotDecontX <- formatPlotList(plotDecontX, samples)
  cat(description_DecontX$introduction)
  cat(description_DecontX$runDecontX)
  cat(description_DecontX$plotDecontXResults)
  cat(description_DecontX$output)
  cat(description_DecontX$contamination)
  cat(description_DecontX$clustering)
}
```
<br />


## {.unlisted .unnumbered .toc-ignore .tabset .tabset-fade}
```{r "DecontX-plot", echo=FALSE, eval=(!skipDecontX), results="asis", fig.align="center"}
cat("\n")
for (sample in samples){
  cat(paste0("### ", sample, " {.tabset .tabset-fade} \n"))
  cat("\n\n")
  
  cat("#### DecontX Contamination Score {.tabset .tabset-fade} \n\n")
  plot(plotDecontX$Sample[[sample]][["scatter_decontXContamination"]])
  cat("\n\n")
  
  cat("#### Density Score {.tabset .tabset-fade} \n\n")
  plot(plotDecontX$Sample[[sample]][["density_decontXContamination"]])
  cat("\n\n")
  
  cat("#### Violin Score {.tabset .tabset-fade} \n\n")
  plot(plotDecontX$Sample[[sample]][["violin_decontXContamination"]])
  cat("\n\n")
  
  cat("#### DecontX Clusters {.tabset .tabset-fade} \n\n")
  plot(plotDecontX$Sample[[sample]][["scatter_decontXClusters"]])
  cat("\n\n")
  
  cat("#### Parameters {.tabset .tabset-fade} \n\n")
  DecontXMeta <- sce.qc@metadata$runDecontX
  DecontXMeta <- metaChecking(DecontXMeta, sample)

  # if(length(samples) == 1) {
  #   DecontXMeta <- list(DecontXMeta)
  #   names(DecontXMeta) <- sample
  # }
  
  x <- preprocessMeta(DecontXMeta[[sample]])
  cat(t(as.data.frame(x)) %>%
    knitr::kable(format = "html") %>% kableExtra::kable_styling() %>%
    kableExtra::scroll_box(width = "80%"))
  cat("\n\n")
}
```
`r cat("\n")`

# Session Information
<details>
 <summary><b>Session Information</b></summary>
```{r "CellQC-session-info", echo=FALSE}
sessionInfo()
```
</details>


