Cell filtering, doublet removal, and normalization

QC & Preprocessing Parameters

Path to filtered_feature_bc_matrix/
Cell Ranger output directory
Minimum UMI per cell
Maximum mitochondrial gene percentage
Minimum genes per cell
Expected doublet rate
R Seurat QC & Preprocessing
library(Seurat)
library(DoubletFinder)

# Step 1.1: Load 10x data
data <- Read10X(data.dir="{tenx_dir}")
so <- CreateSeuratObject(counts=data, project="Dormancy", min.cells=3)

# Step 1.2: Calculate QC metrics
so[["percent.mt"]] <- PercentageFeatureSet(so, pattern="^mt-")
so[["percent.rb"]] <- PercentageFeatureSet(so, pattern="^Rp[sl]")

# Step 1.3: Filter cells
so <- subset(so, subset=nCount_RNA > {min_umi} & nFeature_RNA > {min_genes} & percent.mt < {max_mt})

# Step 1.4: Normalize and find variable features
so <- NormalizeData(so)
so <- FindVariableFeatures(so, selection.method="vst", nfeatures=2000)

# Step 1.5: Doublet removal with DoubletFinder
so <- ScaleData(so)
so <- RunPCA(so, features=VariableFeatures(object=so))
so <- RunUMAP(so, dims=1:20)

pK_data <- paramSweep(so, PCs=1:20, sct=FALSE)
pK_df <- summarizeSweep(pK_data, GT=FALSE)
bc_pK <- find.pK(pK_df)
optimal_pK <- as.numeric(as.character(bc_pK$pK[which.max(bc_pK$BCmetric)]))

so <- doubletFinder(so, PCs=1:20, pN=0.25, pK=optimal_pK, nExp=round({doublet_rate}*ncol(so)), reuse.pANN=FALSE)
df_col <- grep("DF.classifications", colnames(so@meta.data), value=TRUE)[1]
so <- so[, so@meta.data[[df_col]] == "Singlet"]

# Save
saveRDS(so, "01_seurat_qc.rds")
print(paste("Cells after QC:", ncol(so)))
Configure parameters on the left, then click "Generate Code" to produce customized commands
Dimension reduction, clustering, and cell type identification

Clustering & Annotation Parameters

Upload .rds from Step 1
QC-filtered Seurat object
Number of PCs to use
Clustering resolution
Cell type annotation method
Reference dataset
R Clustering & Cell Type Annotation
library(Seurat)
library(SingleR)
library(celldex)

# Step 2.1: Load data
so <- readRDS("01_seurat_qc.rds")

# Step 2.2: PCA and UMAP
so <- ScaleData(so)
so <- RunPCA(so, features=VariableFeatures(object=so), npcs=50)
so <- FindNeighbors(so, dims=1:{pc_dims})
so <- FindClusters(so, resolution={resolution})
so <- RunUMAP(so, dims=1:{pc_dims})

# Step 2.3: SingleR annotation
ref <- MouseRNAseqData()
pred <- SingleR(test=GetAssayData(so, layer="data"), ref=ref, labels=ref$label.fine)
so$cell_type <- pred$labels

# Step 2.4: Visualize
DimPlot(so, reduction="umap", label=TRUE, repel=TRUE) + NoLegend()
ggsave("02_umap_clusters.pdf", width=8, height=6)

DimPlot(so, reduction="umap", group.by="cell_type", label=TRUE, repel=TRUE) + NoLegend()
ggsave("02_umap_celltypes.pdf", width=10, height=6)

# Step 2.5: Find markers
markers <- FindAllMarkers(so, only.pos=TRUE, min.pct=0.25, logfc.threshold=0.25)
top_markers <- markers %>% group_by(cluster) %>% top_n(n=10, wt=avg_log2FC)
write.csv(top_markers, "02_cluster_markers.csv")

saveRDS(so, "02_seurat_clustered.rds")
Configure parameters on the left, then click "Generate Code" to produce customized commands
Differential expression and metabolic pathway scoring per cell type

DEG & Scoring Parameters

Upload clustered .rds
Annotated Seurat object
Metadata column for comparison
First group
Second group
Pathway to score
R Cell-Type DEG & Metabolic Scoring
library(Seurat)
library(tidyverse)

so <- readRDS("02_seurat_clustered.rds")

# Step 3.1: DEG per cell type
Idents(so) <- "cell_type"
all_types <- unique(so$cell_type)

deg_list <- list()
for(ct in all_types) {
  cells <- subset(so, idents=ct)
  if(length(unique(cells${group_col})) >= 2) {
    deg <- FindMarkers(cells, ident.1="{ident1}", ident.2="{ident2}",
                       group.by="{group_col}", logfc.threshold=0.25)
    deg$cell_type <- ct
    deg$gene <- rownames(deg)
    deg_list[[ct]] <- deg
  }
}
all_deg <- bind_rows(deg_list)
write.csv(all_deg, "03_celltype_DEG.csv")

# Step 3.2: Metabolic scoring
oxphos_genes <- c("Cox4i1","Cox5a","Cox5b","Cox6c","Atp5f1a","Atp5f1b","Ndufa1","Sdhb","Uqcrq")
glycolysis_genes <- c("Hk2","Pkm","Pfkp","Eno1","Gapdh","Ldha","Pgk1")

so <- AddModuleScore(so, features=list(oxphos_genes), name="OXPHOS_score")
so <- AddModuleScore(so, features=list(glycolysis_genes), name="Glycolysis_score")

# Step 3.3: Visualization
VlnPlot(so, features=c("OXPHOS_score1","Glycolysis_score1"), pt.size=0, ncol=2)
ggsave("03_metabolic_scores.pdf", width=12, height=5)

saveRDS(so, "03_seurat_scored.rds")
Configure parameters on the left, then click "Generate Code" to produce customized commands
Pseudotime trajectory inference and RNA velocity

Trajectory Parameters

Upload scored .rds
Seurat object with annotations
Starting cell type for trajectory
Trajectory inference method
Run RNA velocity analysis
R Trajectory Inference (Monocle3)
library(monocle3)
library(Seurat)

# Step 4.1: Convert Seurat to Monocle
cds <- as.cell_data_set(so)

# Step 4.2: Preprocess and reduce
cds <- cluster_cells(cds, reduction_method="UMAP")
cds <- learn_graph(cds)

# Step 4.3: Order cells
root_cells <- colnames(cds)[cds@colData$cell_type == "{root_cell}"]
cds <- order_cells(cds, root_cells=root_cells)

# Step 4.4: Plot pseudotime
plot_cells(cds, color_cells_by="pseudotime", label_cell_groups=FALSE,
           label_leaves=FALSE, label_branch_points=FALSE, graph_label_size=1.5)
ggsave("04_pseudotime.pdf", width=8, height=6)

# Step 4.5: Differential expression along trajectory
deg_graph <- graph_test(cds, neighbor_graph="principal_graph", cores=4)
top_degs <- deg_graph %>% arrange(q_value) %>% head(100)
write.csv(top_degs, "04_trajectory_DEG.csv")

# Step 4.6: Gene dynamics
genes_to_plot <- c("Ucp1","Pparg","Cidea","Prdm16","Cebpb")
plot_genes_in_pseudotime(cds[rowData(cds)$gene_short_name %in% genes_to_plot,],
                         color_cells_by="condition", min_expr=0.1)
ggsave("04_gene_pseudotime.pdf", width=10, height=8)
Configure parameters on the left, then click "Generate Code" to produce customized commands
Step 1 of 4