
gatekeepR turns per-cell marker measurements from multiplexed tissue images
into cell types that a person has reviewed.
Status: 1.1.0 development candidate, not submitted. The configuration, preparation, correction, threshold, classification, review, export and plotting paths are implemented. The package is being checked for its first CRAN submission.
Semi-automated gating is where multiplex imaging studies are most fragile:
gatekeepR is built so that each of these failures becomes an error or a
visible status instead:
In scope
Out of scope
cellspecR).qupflowR, segmantR).phenoscapR).cellspecR (validated cell table + signal policy)
│
▼
gatekeepR: callability → thresholds → hierarchy → state calls
│ ▲
│ └── review app (cut-offs, structures, exclusions)
▼
locked snapshot (review_id, hashes, ledgers, calls)
│
▼
phenoscapR / cohort statistics / reports
| Area | Functions |
|---|---|
| Panel and rules |
gk_panel(), gk_hierarchy(), gk_read_config(), gk_write_config()
|
| Signals |
gk_prepare(), gk_callability(), gk_correct()
|
| Thresholds |
gk_thresholds(), gk_threshold_methods(), gk_embed()
|
| Classification |
gk_classify(), gk_state_calls(), gk_structures()
|
| Review |
gk_review(), gk_set_cut(), gk_decide_structure(), gk_dispose(), gk_set_state(), gk_revert_last(), gk_import_cuts(), gk_replace_review(), gk_save_review(), gk_load_review()
|
| Snapshot |
gk_lock(), gk_export(), gk_verify_export(), gk_read_export(), gk_replay()
|
| Plots |
gk_plot_overview(), gk_plot_density(), gk_plot_map(), gk_plot_embedding(), gk_plot_dotplot(), gk_plot_thresholds(), gk_plot_states()
|
| Example data |
gk_example_config(), gk_example_path(), gk_simulate()
|
| App |
gk_app(), a review application that also runs from shinylaunchR |
config <- gk_example_config()
x <- gk_read_cellspec(gk_example_path("example-slide"))
prep <- gk_prepare(x, config, quiet = TRUE)
fixed <- gk_correct(prep, method = "robust_z")
emb <- gk_embed(prep, correction = fixed, seed = 42)
thr <- gk_thresholds(prep, config, embedding = emb, correction = fixed)
cls <- gk_classify(prep, thr, config, correction = fixed)
states <- gk_state_calls(prep, thr, cls, config)
shapes <- gk_structures(cls, prep)
rev <- gk_review(cls, states, shapes, thr, prep)
snap <- gk_lock(rev, reviewer = "reviewer-01", status = "PENDING")
gk_export(snap, "reviews/example-01")
gk_verify_export("reviews/example-01", expected_review_id = snap$review_id_full)
R 4.1 or later is required. Install the source archive prepared for this version into a project library (a compiler is needed for dependencies without binaries). Replace the archive path with the actual built package:
mkdir -p .Rlib
R_LIBS_USER="$PWD/.Rlib" Rscript -e 'install.packages(c("cli", "data.table", "digest", "filelock", "jsonlite", "lifecycle", "MASS", "rlang", "dbscan", "ggplot2", "shiny", "uwot", "patchwork"), repos="https://cloud.r-project.org")'
R_LIBS_USER="$PWD/.Rlib" R CMD INSTALL /path/to/gatekeepR_1.1.0.tar.gz
R_LIBS_USER="$PWD/.Rlib" R
For the published GitHub development branch, use pak::pak("CTTIR/gatekeepR");
unpublished maintenance changes are available only in the prepared local archive.
Canonical cellspec directories use the optional adapter:
install.packages("cellspecR", repos = c("https://cttir.r-universe.dev", "https://cloud.r-project.org")). The bundled legacy example also works without
that adapter.
EBImage is optional for the basin method, and is installed through
BiocManager::install("EBImage"); its fftwtools dependency needs FFTW headers and
libraries when built from source. It is unnecessary for the example below.
library(gatekeepR)
config <- gk_example_config()
prep <- gk_prepare(gk_example_path("example-slide"), config, quiet = TRUE)
thr <- gk_thresholds(prep, config, seed = 1L)
cls <- gk_classify(prep, thr, config)
states <- gk_state_calls(prep, thr, cls, config)
shapes <- gk_structures(cls, prep)
review <- gk_review(cls, states, shapes, thr, prep)
shiny::runApp(gk_app(review = review, workdir = "my-review"))
The app provides marker cuts, structure IDs or rectangular spatial selections,
cell/region dispositions, state cuts and enablement, and undo. Every change
requires a reviewer and reason. Save explicitly to create a checkpoint; resume
with shiny::runApp(gk_app(workdir = "my-review")) in the owning R process.
The owner lock persists after that process ends. Only after confirming the prior
review process has stopped, claim its checkpoint with
gk_load_review("my-review", takeover = TRUE) and then open gk_app(workdir = "my-review") in the same new R process. Do not take over a live reviewer. A
concurrent stale session must reload before saving. Maps and the table are
bounded for interactive use.
Lock as PENDING until scientific review is complete. REVIEWED requires an
explicit human choice; the label records that assertion and does not validate
the assay or authenticate the reviewer. Each edit invalidates the previous
snapshot download. An export opens as a read-only inspector with
shiny::runApp(gk_app(export = "reviews/example-01")).
Preserve existing source data, model files, checkpoints and exports. Version 2
exports bind typed replay inputs, scores, localization, effective cells and
states, reviewer decisions, correction parameters, actual source identity and
review status. Verification checks exact numeric transport and shared-API replay.
Keep snapshot$review_id_full separately; pass it as expected_review_id to
reject a substituted whole export. Hash verification is not a digital signature.
Legacy exports remain inspectable with gk_read_export(path, verify = FALSE);
that explicitly bypasses verification. Regenerate analytical objects from the
original source/configuration, review the changed results, and save a new
checkpoint/export to a new path. Old correction/source bindings cannot be reused
with the stronger numerical and provenance contract. Frozen residual models need
explicit parameter import and requalification as described in ?gk_import_residual_model; retain their original files and provenance. Do not refit a frozen model
merely to migrate its storage.
The bundled panel and simulated data are examples. Study-specific method qualification, human review, hosted CI and submission acceptance are separate from local package checks. See MAINTENANCE.md for audit evidence.
Follows the CTTIR contributing guide.
MIT
Where applicable, LLM tools were used for narrowly defined, non-authorial tasks: copyediting, prose refinement, Markdown/LaTeX formatting, boilerplate scaffolding (such as CI configurations and build scripts), and code refactoring. Tools included Chat AI, the KISSKI (GWDG) service, and self-hosted Mistral Small (24B, Apache-2.0) served through a local vLLM architecture on an Ubuntu Linux workstation with Intel processors and NVIDIA GPUs. The self-hosted model ran locally, with no data sent to third parties.
All scientific claims, methodological choices, analyses, interpretations and conclusions remain the authors' own. Where applicable, LLM-generated material must be reviewed and revised before inclusion, and references must be verified against their DOI, arXiv ID or ISBN.
Local software setup: vLLM with Python/PyTorch, plus R and RStudio.
Editable R sources and regeneration instructions are in tools/branding.