Output reference

Where every task writes, what the files contain, and the naming rules.

The results tree

results/
├── check/<dataset>_check.txt
├── embeddings/<method>/<dataset>.h5ad
├── transfer/
│   ├── models/<method>/<classifier>/<reference>/
│   │   ├── meta.json
│   │   └── model.npz | mlp/
│   └── predictions/<method>/<classifier>/
│       ├── <query>_predicted_labels.tsv
│       └── <query>_predicted_probs.tsv
├── finetune/
│   ├── finetuned_models/<method>/<reference>/
│   └── prediction/<method>/
│       ├── <query>_predicted_labels.tsv
│       └── <query>_predicted_probs.tsv
├── benchmark/
│   ├── <method>_bio_conservation_leiden_metrics_{long,wide}.csv
│   ├── <method>_batch_mixing_leiden_metrics_{long,wide}.csv
│   ├── bio_conservation_leiden_metrics/<method>/<dataset>_<method>.csv
│   ├── batch_mixing_leiden_metrics/<method>/<dataset>_<method>.csv
│   └── bio_conservation_leiden_predictions/<method>/<dataset>_<method>_leiden_labels.tsv
├── geometry/<method>/
│   ├── <dataset>_<method>.csv
│   └── <dataset>_<method>_rnx_batches.csv
└── <method>_geometry.csv

Two rules generate every path:

Directory names are method ids. --method scgpt writes under scgpt/, --method seurat_rpca under seurat_rpca/, --method genept under genept_w/ — the one id that carries a suffix, because GenePT has a second (s) mode. benchmark and geometry use the label they are given, which defaults to the embedding directory’s name.

File names come from the input basename. colon_1000.h5ad in produces colon_1000.h5ad, colon_1000_scgpt.csv, colon_1000_predicted_labels.tsv. Two inputs sharing a basename overwrite each other; give them distinct names or a distinct --outdir.

--outdir DIR on any task command replaces results/ as the root for that run.

Every run has a record

runs/<task>/<timestamp>_<method>_<input>/
├── params.json      parameters handed to Nextflow
├── command.sh       the exact command, re-runnable
├── run.json         task, method, input, timestamps, exit code, versions, paths
├── nextflow.log     the full Nextflow log
├── .nextflow/       Nextflow's cache database
└── work/            task work directories, removed on success
{
  "task": "embed",
  "method": "scgpt",
  "input": "colon_1000",
  "workspace": "/home/you/my_project",
  "pipeline": "/home/you/.conda/envs/nf-env/lib/python3.12/site-packages/scfoundry/pipeline",
  "run_dir": "/home/you/my_project/runs/embed/20260828-162920_scgpt_colon_1000",
  "resumed": false,
  "started": "2026-08-28T16:29:20",
  "finished": "2026-08-28T16:29:40",
  "exit_code": 0,
  "status": "ok",
  "scfoundry_version": "0.2.0",
  "nextflow": "/home/you/.conda/envs/nf-env/bin/nextflow"
}

File formats

Embedding .h5ad

Produced by embed, and by transfer as a side effect.

Slot

Contents

adata.X

The embedding, cells × dimensions, dense float32. Not expression.

adata.obs

The input’s cell metadata, carried through unchanged.

adata.var

Placeholder index V1, V2, … one row per embedding dimension.

adata.obsm["spatial"]

Preserved if present in the input.

Note

The embedding is in X rather than obsm so that every method’s output has the same shape and one benchmark can score all of them. The consequence is that an embedding file does not contain expression values — keep your input.

Prediction .tsv

transfer and finetune emit the same pair, tab-separated and indexed by barcode.

<query>_predicted_labels.tsv — one column:

	predicted_label
CACACCTAGCTGTCTA-HT-236_day132_colon	intestine goblet cell
GAAATGACAGGTGGAT-HT-236_day132_colon	colonocyte

<query>_predicted_probs.tsv — one column per class, rows summing to 1:

	epithelial cell	enteroendocrine cell	M cell of gut	intestinal crypt stem cell	intestine goblet cell	colonocyte	BEST4+ enterocyte
CACACCTAGCTGTCTA-HT-236_day132_colon	0.0006	0.0005	0.0004	0.0007	0.9973	0.0002	0.0003
import pandas as pd

labels = pd.read_csv(path_labels, sep="\t", index_col=0)
probs  = pd.read_csv(path_probs,  sep="\t", index_col=0)
labels["confidence"] = probs.max(axis=1)

Transfer model directory

meta.json describes the fit — classifier, method, label column, classes, embedding dimension, cells per class, hyperparameters — and model.npz (or mlp/ for the MLP head) holds the parameters. Pass the directory to --fitted.

Fine-tuned model directory

The method’s own files — best_model.pt and vocab.json for scGPT, a finetuned.* checkpoint and label encoders for CellPLM, a Hugging Face model directory for Geneformer, and so on — plus a label map. CELLama writes two subdirectories, base_model/ and posthoc_classifier/. In every case --fitted takes the directory itself.

Directories are copied out of the Nextflow work directory, so they survive cleanup.

Benchmark .csv

Wide: one row per embedding file, one column per metric.

sample_id,method,ARI,ASW,Acc@kNN,COM,FMI,GC,HOM,NMI,cLISI
colon_1000,scgpt,0.589,0.142,0.906,0.650,0.702,0.824,0.655,0.652,0.990

Long: one row per metric, with the settings that produced it and the data shape.

sample_id,method,metric,value,note,metric_group,n_cells,n_dims,n_labels,n_batches
colon_1000,scgpt,NMI,0.652,clustering=leiden;selection=match_n_labels;resolution=0.3;n_clusters=6;target_n_labels=7;scan_n=30,bio_conservation,1000,512,7,

The cluster-label TSV records the selected partition per cell (barcode, true_label, leiden_label).

Geometry .csv

One row per dataset: dataset_id, method, embedding_file, cell and dimension counts, then the statistics — pr, npr, aniso_spec, aniso_cos, aniso_cos_within_ct, aniso_cos_between_ct, aniso_cos_ct_gap, rnx_k15, rnx_k30, rnx_k50, rnx_mean, rnx_eligible_cells, rnx_eligible_cell_fraction, rnx_n_batches, id_twonn_raw, id_twonn_z, partial_eta2_celltype, partial_eta2_batch — followed by probe_status, failure_reason and a notes column naming the backends used. The _rnx_batches.csv companion holds RNX per batch and k. Definitions are on Representation-geometry probes.

What is not published

Task work directories are deleted on success, because the workspace nextflow.config sets cleanup = true. Anything a process produced but did not publish is gone:

  • intermediate tokenised datasets (Geneformer, scCello, LangCell)

  • preprocessed matrices (scBERT, scFoundation, SCimilarity, Seurat)

  • training logs and validation curves

Set cleanup = false and inspect the run’s work/ if you need any of these.

See also