---
title: "Comparing CLAMPbase and CLAMPfull"
author: "Maria Chikina"
package: CLAMP
output:
  BiocStyle::html_document:
    fig_width: 7
    fig_height: 5
vignette: >
  %\VignetteIndexEntry{Comparing CLAMPbase and CLAMPfull}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---


```{r setup, include=FALSE}
knitr::opts_chunk$set(
    echo = TRUE,
    message = FALSE,
    warning = FALSE,
    cache = FALSE,
    dev = "png",
    dev.args = list(type = "cairo")
)
library(CLAMP)
library(bigstatsr)
```

# Overview

This vignette compares the two main models in the **CLAMP** package:

1. **CLAMPbase**: Unsupervised matrix factorization for dimensionality reduction without prior knowledge.
2. **CLAMPfull**: Pathway-guided refinement that integrates biological prior knowledge to improve interpretability.

Using a small human whole blood RNA-Seq dataset, we demonstrate that incorporating pathway priors in `CLAMPfull` improves the biological interpretability of latent variables compared to the baseline `CLAMPbase` model.

We illustrate how to:

- Fit both `CLAMPbase` and `CLAMPfull` models,
- Compare their performance using cell type correlations, and
- Verify that the FBM (Filebacked Big Matrix) implementation produces identical results.


## 1. Load Data and Normalize

```{r load-data}
data("dataWholeBlood")
data("majorCellTypes")
data("celltypeTargets")

# Scale each gene to mean 0 and variance 1
dataWholeBlood <- tscale(dataWholeBlood)
```

## 2. Load Prior Knowledge Matrices

```{r load-priors-download, eval=FALSE}
# How to download pathway and cell marker libraries from Enrichr.
# Not run during vignette build to avoid network calls; pre-fetched
# .rds files are loaded in the next chunk instead.
enrichr_url <- "https://maayanlab.cloud/Enrichr/geneSetLibrary"
gmtList <- list(
    CellMarkers = getGMT(
        paste0(enrichr_url, "?mode=text&libraryName=CellMarker_2024"),
        "CellMarker_2024"
    ),
    KEGG = getGMT(
        paste0(enrichr_url, "?mode=text&libraryName=KEGG_2021_Human"),
        "KEGG_2021_Human"
    )
)
```

```{r load-priors}
# Load pre-fetched gene set libraries bundled with the package
gmtList <- list(
    CellMarkers = readRDS(
        system.file("extdata", "CellMarker_2024.rds", package = "CLAMP")
    ),
    KEGG = readRDS(
        system.file("extdata", "KEGG_2021_Human.rds", package = "CLAMP")
    )
)

# Combine into a single sparse matrix
pathMatCell <- gmtListToSparseMat(gmtList)

# Load additional xCell reference matrix
data("xCell")

# Match pathways to the gene space of whole blood
matchedPathsWB <- getMatchedPathwayMatList(
    pathMatCell,
    xCell,
    new.genes = rownames(dataWholeBlood),
    min.genes = 2
)
```

## 3. Compute SVD and Infer k

```{r compute-svd}
set.seed(1)
wb_svd_k <- select_svd_k(dataWholeBlood)
wb_svd <- compute_svd(dataWholeBlood, k = wb_svd_k)
wb_clamp_k <- select_clamp_k(wb_svd,
    n_samples = ncol(dataWholeBlood),
    svd_k = wb_svd_k
)
wb_clamp_k
```

## 4. Fit CLAMPbase and CLAMPfull

```{r fit-clampbase}
wb_clamp_base <- CLAMPbase(
    dataWholeBlood,
    svdres     = wb_svd,
    clamp_k    = wb_clamp_k,
    trace      = FALSE,
    adaptive.p = 0.05
)
```

```{r fit-clampfull}
wb_clamp_full <- CLAMPfull(
    dataWholeBlood,
    priorMat          = matchedPathsWB,
    svdres            = wb_svd,
    clamp.base.result = wb_clamp_base,
    clamp_k           = wb_clamp_k,
    trace             = TRUE,
    use_cpp           = TRUE
)
```

## 5. Compare CLAMPbase vs CLAMPfull

This plot compares the maximum Spearman correlation for each major blood cell type between `CLAMPbase` and `CLAMPfull`.

Points above the red dashed line indicate improved correspondence when biological priors are included.

Most cell types show higher correlations under `CLAMPfull`, demonstrating that integrating pathway information helps capture more biologically meaningful latent variables.

```{r compare-models, fig.width=6, fig.height=5}
output <- compareBs(
    wb_clamp_base,
    wb_clamp_full,
    celltypeTargets,
    method = "s",
    xlab   = "CLAMPbase",
    ylab   = "CLAMPfull"
)

output$plot
```

## 6. Inspect Named Matrix Outputs

`CLAMPbase` and `CLAMPfull` now return `B` (gene loadings, LVs × genes) and `Z` (sample scores, LVs × samples) as proper named matrices.

```{r named-matrices}
# B: gene loadings (LVs × genes)
dim(wb_clamp_full$B)
wb_clamp_full$B[1:3, 1:4]

# Z: sample scores (LVs × samples)
dim(wb_clamp_full$Z)
wb_clamp_full$Z[1:3, 1:4]
```

## 7. Verify FBM Implementation

We verify that `CLAMPfull` produces identical results when using a file-backed matrix (FBM) input instead of an in-memory matrix. We reuse the same pre-computed SVD and `clamp_k` so that any differences are attributable solely to the matrix format, not the randomized SVD.

```{r fit-clampfull-fbm}
dataWholeBloodFBM <- bigstatsr::as_FBM(dataWholeBlood)

wb_clamp_full_fbm <- CLAMPfull(
    dataWholeBloodFBM,
    priorMat          = matchedPathsWB,
    svdres            = wb_svd,
    clamp.base.result = wb_clamp_base,
    clamp_k           = wb_clamp_k,
    trace             = TRUE,
    use_cpp           = TRUE
)
```

The FBM implementation produces identical results:

```{r compare-fbm, fig.width=6, fig.height=5}
output <- compareBs(
    wb_clamp_full,
    wb_clamp_full_fbm,
    celltypeTargets,
    method = "s",
    xlab   = "CLAMPfull (matrix)",
    ylab   = "CLAMPfull (FBM)"
)

output$plot
```

# Session Information

```{r session-info}
sessionInfo()
```
