GitHub View CyteType

R client

Preprocess Seurat objects, run CyteTypeR annotation, and read results in R.

Use the R client (CyteTypeR) with Seurat objects.

Preprocessing your data

CyteType requires differential expression results computed per cluster before submission.

library(Seurat)
library(dplyr)

pbmc <- NormalizeData(pbmc)
pbmc <- FindVariableFeatures(pbmc, nfeatures = 2000)
pbmc <- ScaleData(pbmc)
pbmc <- RunPCA(pbmc)
pbmc <- FindNeighbors(pbmc, dims = 1:10)
pbmc <- FindClusters(pbmc, resolution = 0.5)
pbmc <- RunUMAP(pbmc, dims = 1:10)

pbmc.markers <- FindAllMarkers(pbmc, only.pos = TRUE) %>%
  dplyr::filter(avg_log2FC > 1)

Initializing the annotator

PrepareCyteTypeR validates your data and precomputes expression percentages. This can take a few minutes on large datasets but only needs to run once per object.

# PrepareCyteTypeR handles all preprocessing in one step
prepped_data <- PrepareCyteTypeR(
  obj = seurat_obj,
  marker_table = markers_df,       # output of FindAllMarkers()
  group_key = "seurat_clusters",   # metadata column with cluster assignments
  gene_symbols = "gene_symbols",   # gene symbol field name
  n_top_genes = 50,                # top marker genes per cluster
  aggregate_metadata = TRUE,       # include metadata context
  min_percentage = 10,             # min % threshold for metadata
  coordinates_key = "umap",        # dimensional reduction for visualization
  max_cells_per_group = 1000       # cells sampled per cluster
)

Reviewing data before submission

The client builds obs.duckdb from the complete Seurat metadata table and vars.h5 from the normalized expression matrix, feature metadata, and raw counts when available. Work from a reviewed copy of the object and remove direct identifiers or metadata columns that are not needed for annotation and report exploration before calling PrepareCyteTypeR.

aggregate_metadata = FALSE disables aggregated metadata in the annotation request, but it does not remove columns from obs.duckdb. Review study_context and the metadata list separately because both are submitted as written.

See Security and privacy for the complete data flow.

Running annotation

The study_context is the most important parameter for annotation quality. Describe your tissue, organism, disease state, and experimental setup in one or two sentences.

pbmc <- CyteTypeR(
  obj = seurat_obj,
  prepped_data = prepped_data,
  study_context = "Human colorectal cancer biopsy, tumor microenvironment, treatment-naive patients",
  metadata = list(
    "Study" = "My TME atlas",
    "GEO" = "https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE123456",
    "DOI" = "https://doi.org/10.1038/example"
  ),
  n_parallel_clusters = 4L,
  results_prefix = "cytetype",
  timeout_seconds = 7200L,
  require_artifacts = TRUE,
  show_progress = TRUE
)

require_artifacts = FALSE is a failure-tolerance setting, not an upload opt-out. The client still attempts to build and upload both artifacts. When artifact preparation and upload succeed, the artifacts are submitted. Use the default value when the interactive report needs complete expression and metadata tools.

Accessing results

After a successful run, annotations are stored in your object and can be accessed immediately.

# Annotation columns added to obj@meta.data:
# cytetype_annotation_seurat_clusters
# cytetype_cellOntologyTerm_seurat_clusters
# cytetype_cellOntologyTermID_seurat_clusters
# cytetype_cellState_seurat_clusters

# Full results table in obj@misc:
results_df <- seurat_obj@misc[["cytetype_results"]]
View(results_df)

# Available columns in results_df:
# clusterId, annotation, ontologyTerm, ontologyTermID,
# granularAnnotation, cellState, justification,
# supportingMarkers, conflictingMarkers, missingExpression, unexpectedExpression

# If you need to re-fetch results after disconnecting:
results <- GetResults(seurat_obj)

💡 Tip: Jobs continue running on the server even after your local session disconnects. Use GetResults(obj) to retrieve results after reconnecting.

Custom LLM configuration

By default CyteType uses its own hosted model. You can bring your own LLM from any supported provider.

# Single LLM configuration
result <- CyteTypeR(
  obj = seurat_obj,
  prepped_data = prepped_data,
  study_context = "...",
  llm_configs = list(
    provider = "openai",
    name = "gpt-4o",
    apiKey = "sk-...",
    baseUrl = "https://api.openai.com/v1",
    modelSettings = list(temperature = 0.0, max_tokens = 4096L)
  )
)

# Multiple providers
result <- CyteTypeR(
  obj = seurat_obj,
  prepped_data = prepped_data,
  study_context = "...",
  llm_configs = list(
    list(
      provider = "anthropic",
      name = "claude-3-5-sonnet-20241022",
      apiKey = "sk-ant-...",
      targetAgents = c("annotator", "reviewer")
    ),
    list(
      provider = "openai",
      name = "gpt-4o-mini",
      apiKey = "sk-...",
      targetAgents = c("summarizer", "clinician")
    )
  )
)

Supported providers: anthropic, bedrock, fireworks, google, groq, huggingface, mistral, openai, openrouter, vertex, xai.

Customer-supplied credentials and the relevant scientific prompts pass through the CyteType service so that it can orchestrate the workflow. A custom provider changes the inference account, but it does not bypass the CyteType backend or artifact upload.

❗️ Important: Saved CyteTypeR query files can contain values from llm_configs, including model-provider credentials. Treat these files as secrets, exclude them from source control and shared folders, and remove them when they are no longer needed.

Authentication

The hosted service requires a bearer token. Create and manage tokens in the CyteType Dashboard, and store them as secrets rather than directly in a shared script.

# Pass auth_token to CyteTypeR
result <- CyteTypeR(
  obj = seurat_obj,
  prepped_data = prepped_data,
  study_context = "...",
  auth_token = "your-token"
)

# Or when re-fetching results
results <- GetResults(seurat_obj, auth_token = "your-token")

Learn more

Python client

Dashboard

Understanding your report

Security and privacy