---
title: "Getting started with cepip"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Getting started with cepip}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 5)
library(cepip)
```

## 1. What the package does

cepip relates a gene of interest (GOI) to the mean expression of its partner
genes, cell by cell, and finds where that relationship changes.

1. A GAM, `y ~ x + s(x)`, is fitted by REML with the basis dimension k chosen
   by the lowest penalized residual sum of squares (PRSS).
2. Each cell gets an explanatory power (EP). The top round(n x DE) cells by EP
   are the TREP cells.
3. The inflection point (IP) is the first negative-to-positive zero crossing of
   a residual GAM R(x) of the top-EP cells, with a 95% CI and an IP reliability
   score (IPRS).
4. Optional: the Spearman-Kendall cell-level score (SKCS) keeps the cells that
   carry the co-expression (SKCS-core).
5. Optional: CMRF (copula monotone recovery filter)
   recovers cells near the module through a tolerance band and a repeated
   stratified k-fold cross-validation gate (RSk-fCV).

Steps 1 to 3 are the published CEP-IP. The package does not transform the
data, so `x` and `y` must be on the scale you want to analyse (the SEA-AD
analysis used ln(CP10K + 1)).

## 2. Quick example on simulated data

`cepip_toy` holds 1,200 simulated cells from 12 donors.

```{r toy}
d <- cepip_toy
d$y <- cepip_composite(d, paste0("P", 1:8))
res <- cepip(d$x, d$y, donor = d$donor, id = d$id, cmrf = TRUE, tests = FALSE)
res
```

With `donor`, the GAMs include a donor random intercept and weight each cell
by 1 / (cells of its donor). Without `donor`, every cell has weight 1, as in
the published CEP-IP.

```{r toy-plots, fig.height = 5}
plot_fit(res)
plot_residual(res$ip)
plot_module(res$cmrf)
```

The Pre-IP and Post-IP labels use the response axis by default (y < IPy is
Pre-IP). The published CEP-IP analyses split on the GOI axis, which
`ip_axis = "x"` reproduces.

## 3. Tuning the CMRF band

The band is widest at the IP. Its half-width is
delta_base x (1 + kappa x K(u)), where K is a Gaussian kernel with standard
deviation `bw` centred at the IP. `cepip_band()` is fast, so several settings
can be compared before running the gate. `cepip_cmrf()` uses kappa = 0.5 and
bw = 0.1 when no band is given.

```{r band, fig.width = 12, fig.height = 9}
b <- cepip_band(res$skcs, res$ip, kappa = 0.5, bw = 0.1)
plot_band(b)
```

```{r gate, eval = FALSE}
cm <- cepip_cmrf(band = b, workers = 2)
plot_rskfcv(cm, "first")
plot_rskfcv(cm, "last")
```

## 4. Downstream analyses

The four groups are Module Post-IP (`PostIP`), Module Pre-IP (`PreIP`),
non-Module Post-IP (`NMPost`) and non-Module Pre-IP (`NMPre`). Without CMRF,
the TREP cells take the place of the Module.

```{r donor}
dp <- cepip_donor(res)
head(dp)
```

`cepip_deg()` compares two groups with a paired design across donors. It
needs log1p-normalized expression (genes x cells) with the cell ids as column
names.

```{r deg, eval = FALSE}
deg <- cepip_deg(res, expr, contrast = c("PostIP_vs_PreIP", "PostIP_vs_NMPost"))
plot_deg(deg, "PostIP_vs_PreIP")
```

`cepip_associate()` relates a donor-level measure to outcomes with
ordinary least squares on z-scores, adjusting for covariates.

```{r assoc, eval = FALSE}
tab <- merge(dp, donor_metadata, by = "donor")
as <- cepip_associate(tab, "pct_PostIP", outcomes = c("MMSE", "Braak"),
                      covariates = c("age", "sex", "PMI"))
plot_associate(as)
```

Which groups to compare, the outcomes and the covariates depend on the
question and on the data available. The defaults of the DEG step (5%
expressing cells, at least 3 cells per donor and group, at least 5 paired
donors, FDR < 0.05 and |log2FC| >= 0.25) are those of the SEA-AD analysis.

## 5. The partner screen

`cepip_screen()` screens candidate GOIs for partner genes by Spearman rs and
Kendall tau-b. By default a GOI is screened when it is expressed in at least
25% of the cells with a mean of at least 0.3 over the expressing cells, and a
partner passes at rs >= 0.6 and tau-b >= 0.5. These defaults suit
ln(CP10K + 1) data from one cell population; adjust them for other data.

```{r screen, eval = FALSE}
sc <- cepip_screen(expr, donor = donor)
head(sc$ranking)
plot_screen(sc)
```

## 6. Reproducing the SEA-AD analysis

The example data of the paper are the Micro-PVM_3-SEAAD cells of the Seattle
Alzheimer's Disease Brain Cell Atlas (SEA-AD) with MT-CO3 > 0, and the cells of
the housekeeping-gene control arm. They are downloaded once with
`cepip_example()`. Use of the SEA-AD data is subject to the Allen Institute
Terms of Use and Citation Policy.

```{r seaad, eval = FALSE}
pv <- cepip_example("pvm3")
MT8 <- c("MT-ATP6", "MT-CO2", "MT-ND3", "MT-ND4", "MT-CYB", "MT-ND1", "MT-ND2", "MT-CO1")
d <- pv[pv$region_set == "NeoC", ]
res <- cepip(d[["MT-CO3"]], cepip_composite(d, MT8), donor = d$donor, id = d$barcode,
             cmrf = TRUE, ip_k = 10, y_spine = d$composite_part8, workers = 4)
cepip_save(list(NeoC = res), "PVM_3")
```

The script `system.file("scripts", "reproduce_seaad.R", package = "cepip")`
runs both region sets of the PVM_3 arm, the HKG8 control arm and the
same-cell housekeeping control, and compares every value with the published
one. Expected values for PVM_3 NeoC include IPx = 2.4953, IPRS = 0.791,
8,407 SKCS-core cells, 8,103 OriRef cells, 1,351 Recovered cells and 643
cells removed by the gate.

The published SEA-AD analysis used `ip_k = 10` for the IP fit and fitted the
CMRF spine on the composite column of its data export, which is stored in
single precision (`y_spine`). The eight partner genes were chosen from the
per-region screens of the paper.
