scPassport solves a common problem in single-cell
RNA-seq analysis: Seurat objects accumulate complex processing
histories, but that context disappears once collaborators open the
.rds file.
This package embeds a persistent metadata passport directly
inside @misc$passport of every Seurat object. Because the
passport travels inside the .rds file, there are no
external spreadsheets to lose track of.
The package provides three functions:
| Function | Purpose |
|---|---|
scPassport() |
Open the Shiny popup to fill or update a passport |
read_passport() |
Print the full passport and processing log to console |
log_step() |
Append a processing step to the object’s log |
The following examples use a minimal
SummarizedExperiment object and run without any external
data. The same functions work identically with Seurat and
SingleCellExperiment objects.
The scPassport() function opens an interactive Shiny
popup. This requires an existing Seurat object in your R session.
# Stamp a root object
WTHeme <- scPassport(WTHeme)
# Stamp a child subset, linking lineage to parent automatically
EndofrHeme <- subset(WTHeme, idents = "Endothelial")
EndofrHeme <- scPassport(EndofrHeme, parent = WTHeme)
# Read passport
read_passport(WTHeme)
scPassport(WTHeme, read = TRUE)Example output:
========== PASSPORT ==========
Object ID : WTHeme
RDS Self : 224
Created : 2026-03-19 05:00:00
-------- Animal --------
Animal ID : M01
Species : Mus musculus
Sex : male
Age : P60
Condition : control
Tissue : lung
-------- Experiment --------
Project : memory_study
Researcher : Sedat Kacar
Date : 2026-03-19
Notes : First sequencing run
-------- Lineage --------
Parent : root
RDS Parent : root
Chain : root
Children : EndofrHeme224, gCapC
RDS Children: 225, 226
======= PROCESSING LOG =======
No processing steps logged yet.
==============================
Use log_step() after each major processing step. This
creates an auditable record of what was done to the object, with
timestamps and cell counts.
library(Seurat)
WTHeme <- NormalizeData(WTHeme)
WTHeme <- log_step(WTHeme, "NormalizeData",
params = list(method = "LogNormalize", scale_factor = 10000))
WTHeme <- RunPCA(WTHeme, npcs = 30)
WTHeme <- log_step(WTHeme, "RunPCA", params = list(npcs = 30))
read_passport(WTHeme)The processing log is visible at the bottom of
read_passport() output:
======= PROCESSING LOG =======
[1] NormalizeData | 8423 cells | 2026-03-19 05:01:00
[2] FindVariableFeatures | 8423 cells | 2026-03-19 05:01:05
[3] ScaleData | 8423 cells | 2026-03-19 05:01:20
[4] RunPCA | 8423 cells | 2026-03-19 05:01:45
==============================
The Shiny popup includes a Custom Fields section
where you can add any extra key-value pairs. These are stored alongside
the standard fields and printed by read_passport().
For example, you might add: -
sequencing_platform = 10x Chromium v3 -
genome_build = mm10 - batch = batch_01
Custom fields from a previous passport are automatically pre-loaded when you re-open the popup, so you only update what changed.
| Field | Description | Example |
|---|---|---|
object_id |
Name/ID of this object | "WTHeme" |
rds_self |
RDS registry number | "224" |
created |
Timestamp of stamping | auto-filled |
| Field | Description | Example |
|---|---|---|
animal_id |
Individual animal ID | "M01" |
species |
Species | "Mus musculus" |
sex |
Sex | "male" |
age |
Age | "P60" |
condition |
Experimental condition | "control" |
tissue |
Tissue of origin | "lung" |
| Field | Description | Example |
|---|---|---|
project |
Project name | "memory_study" |
researcher |
Researcher name | "Sedat Kacar" |
date |
Experiment date | "2026-03-19" |
notes |
Free-text notes | any string |
| Field | Description |
|---|---|
parent_id |
Object ID of the direct parent (or "root") |
rds_parent |
RDS number of the parent (or "root") |
lineage |
Full ancestry chain as a character vector |
children |
Object IDs of children subset from this object |
rds_children |
RDS numbers of children |
sessionInfo()
#> R version 4.6.0 (2026-04-24)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 24.04.4 LTS
#>
#> Matrix products: default
#> BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
#> LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.26.so; LAPACK version 3.12.0
#>
#> locale:
#> [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
#> [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
#> [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
#> [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
#> [9] LC_ADDRESS=C LC_TELEPHONE=C
#> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
#>
#> time zone: Etc/UTC
#> tzcode source: system (glibc)
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] scPassport_1.0.0 rmarkdown_2.31
#>
#> loaded via a namespace (and not attached):
#> [1] Matrix_1.7-5 miniUI_0.1.2
#> [3] jsonlite_2.0.0 compiler_4.6.0
#> [5] promises_1.5.0 Rcpp_1.1.1-1.1
#> [7] SummarizedExperiment_1.42.0 Biobase_2.72.0
#> [9] GenomicRanges_1.64.0 later_1.4.8
#> [11] jquerylib_0.1.4 IRanges_2.46.0
#> [13] Seqinfo_1.2.0 yaml_2.3.12
#> [15] fastmap_1.2.0 lattice_0.22-9
#> [17] mime_0.13 XVector_0.52.0
#> [19] R6_2.6.1 S4Arrays_1.12.0
#> [21] generics_0.1.4 knitr_1.51
#> [23] BiocGenerics_0.58.0 DelayedArray_0.38.1
#> [25] MatrixGenerics_1.24.0 maketools_1.3.2
#> [27] shiny_1.13.0 bslib_0.10.0
#> [29] rlang_1.2.0 cachem_1.1.0
#> [31] httpuv_1.6.17 xfun_0.57
#> [33] sass_0.4.10 sys_3.4.3
#> [35] otel_0.2.0 SparseArray_1.12.0
#> [37] cli_3.6.6 magrittr_2.0.5
#> [39] grid_4.6.0 digest_0.6.39
#> [41] xtable_1.8-8 lifecycle_1.0.5
#> [43] S4Vectors_0.50.0 evaluate_1.0.5
#> [45] buildtools_1.0.0 abind_1.4-8
#> [47] stats4_4.6.0 matrixStats_1.5.0
#> [49] tools_4.6.0 htmltools_0.5.9