truecell 0.9.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. truecell-0.9.0/.claude/skills/README.md +69 -0
  2. truecell-0.9.0/.claude/skills/truecell/SKILL.md +164 -0
  3. truecell-0.9.0/.claude/skills/truecell/reference/api-map.md +304 -0
  4. truecell-0.9.0/.claude/skills/truecell/reference/object-model.md +167 -0
  5. truecell-0.9.0/.gitignore +137 -0
  6. truecell-0.9.0/CHANGELOG.md +1584 -0
  7. truecell-0.9.0/LICENSE +21 -0
  8. truecell-0.9.0/PKG-INFO +537 -0
  9. truecell-0.9.0/README.md +463 -0
  10. truecell-0.9.0/ROADMAP.md +1380 -0
  11. truecell-0.9.0/docs/CHANGELOG.md +1 -0
  12. truecell-0.9.0/docs/ROADMAP.md +1 -0
  13. truecell-0.9.0/docs/assets/logo/README.md +110 -0
  14. truecell-0.9.0/docs/tutorials/README.md +1739 -0
  15. truecell-0.9.0/pyproject.toml +141 -0
  16. truecell-0.9.0/tests/conftest.py +56 -0
  17. truecell-0.9.0/tests/test_advanced_tutorial.py +101 -0
  18. truecell-0.9.0/tests/test_analysis.py +469 -0
  19. truecell-0.9.0/tests/test_anchors_seurat_parity.py +671 -0
  20. truecell-0.9.0/tests/test_anndata_compat.py +40 -0
  21. truecell-0.9.0/tests/test_annotations_resolve.py +254 -0
  22. truecell-0.9.0/tests/test_assay.py +73 -0
  23. truecell-0.9.0/tests/test_assay5.py +153 -0
  24. truecell-0.9.0/tests/test_bands.py +223 -0
  25. truecell-0.9.0/tests/test_bimod_de.py +78 -0
  26. truecell-0.9.0/tests/test_cellcycle_tutorial.py +190 -0
  27. truecell-0.9.0/tests/test_command.py +90 -0
  28. truecell-0.9.0/tests/test_datasets_loaders.py +331 -0
  29. truecell-0.9.0/tests/test_de_bands.py +181 -0
  30. truecell-0.9.0/tests/test_de_parity.py +404 -0
  31. truecell-0.9.0/tests/test_deseq2_pseudobulk.py +86 -0
  32. truecell-0.9.0/tests/test_dimreduc.py +53 -0
  33. truecell-0.9.0/tests/test_dimreduc_tutorial.py +466 -0
  34. truecell-0.9.0/tests/test_docs.py +356 -0
  35. truecell-0.9.0/tests/test_graph.py +43 -0
  36. truecell-0.9.0/tests/test_hashing_tutorial.py +168 -0
  37. truecell-0.9.0/tests/test_hto.py +429 -0
  38. truecell-0.9.0/tests/test_hvf_column_names.py +156 -0
  39. truecell-0.9.0/tests/test_integration.py +385 -0
  40. truecell-0.9.0/tests/test_integration_tutorial.py +233 -0
  41. truecell-0.9.0/tests/test_lazy.py +240 -0
  42. truecell-0.9.0/tests/test_lazy_bpcells_parity.py +225 -0
  43. truecell-0.9.0/tests/test_lazy_pipeline.py +469 -0
  44. truecell-0.9.0/tests/test_logmap.py +62 -0
  45. truecell-0.9.0/tests/test_mapping.py +194 -0
  46. truecell-0.9.0/tests/test_markvariogram.py +274 -0
  47. truecell-0.9.0/tests/test_mast_de.py +82 -0
  48. truecell-0.9.0/tests/test_merscope_loader.py +88 -0
  49. truecell-0.9.0/tests/test_mixscape.py +610 -0
  50. truecell-0.9.0/tests/test_mixscape_tutorial.py +233 -0
  51. truecell-0.9.0/tests/test_module_score_performance.py +253 -0
  52. truecell-0.9.0/tests/test_multimodal_tutorial.py +291 -0
  53. truecell-0.9.0/tests/test_multimodal_wnn.py +273 -0
  54. truecell-0.9.0/tests/test_multiseq.py +206 -0
  55. truecell-0.9.0/tests/test_mvp_dispersion.py +539 -0
  56. truecell-0.9.0/tests/test_neighbor.py +53 -0
  57. truecell-0.9.0/tests/test_neighbors_graph_parity.py +205 -0
  58. truecell-0.9.0/tests/test_new_features.py +315 -0
  59. truecell-0.9.0/tests/test_object_model_typing.py +160 -0
  60. truecell-0.9.0/tests/test_objects_tutorial.py +301 -0
  61. truecell-0.9.0/tests/test_packaging.py +321 -0
  62. truecell-0.9.0/tests/test_pbmc_handoff.py +218 -0
  63. truecell-0.9.0/tests/test_pca_solver_parity.py +189 -0
  64. truecell-0.9.0/tests/test_pseudobulk_conserved.py +129 -0
  65. truecell-0.9.0/tests/test_reduction_feature_selection.py +323 -0
  66. truecell-0.9.0/tests/test_reductions_extra.py +89 -0
  67. truecell-0.9.0/tests/test_refmap_tutorial.py +203 -0
  68. truecell-0.9.0/tests/test_sctransform_r_fidelity.py +498 -0
  69. truecell-0.9.0/tests/test_seurat.py +218 -0
  70. truecell-0.9.0/tests/test_sketch.py +378 -0
  71. truecell-0.9.0/tests/test_sketch_tutorial.py +289 -0
  72. truecell-0.9.0/tests/test_spatial.py +137 -0
  73. truecell-0.9.0/tests/test_spatial_analysis.py +314 -0
  74. truecell-0.9.0/tests/test_spatial_parity.py +252 -0
  75. truecell-0.9.0/tests/test_spatial_plots.py +265 -0
  76. truecell-0.9.0/tests/test_spatially_variable_features.py +151 -0
  77. truecell-0.9.0/tests/test_spca_glmpca.py +484 -0
  78. truecell-0.9.0/tests/test_svf_tutorial.py +142 -0
  79. truecell-0.9.0/tests/test_transfer.py +204 -0
  80. truecell-0.9.0/tests/test_tutorial_marker_tables.py +175 -0
  81. truecell-0.9.0/tests/test_tutorial_smoke.py +384 -0
  82. truecell-0.9.0/tests/test_typing_behaviour.py +93 -0
  83. truecell-0.9.0/tests/test_visium_image.py +311 -0
  84. truecell-0.9.0/tests/test_visium_seurat_parity.py +220 -0
  85. truecell-0.9.0/truecell/__init__.py +218 -0
  86. truecell-0.9.0/truecell/_clara.py +469 -0
  87. truecell-0.9.0/truecell/_sparse.py +67 -0
  88. truecell-0.9.0/truecell/_types.py +15 -0
  89. truecell-0.9.0/truecell/_utils.py +72 -0
  90. truecell-0.9.0/truecell/aggregate.py +156 -0
  91. truecell-0.9.0/truecell/anchors.py +934 -0
  92. truecell-0.9.0/truecell/assay.py +444 -0
  93. truecell-0.9.0/truecell/assay5.py +691 -0
  94. truecell-0.9.0/truecell/clustering.py +261 -0
  95. truecell-0.9.0/truecell/command.py +124 -0
  96. truecell-0.9.0/truecell/compat/__init__.py +3 -0
  97. truecell-0.9.0/truecell/compat/anndata.py +247 -0
  98. truecell-0.9.0/truecell/composition.py +100 -0
  99. truecell-0.9.0/truecell/datasets.py +622 -0
  100. truecell-0.9.0/truecell/dimreduc.py +192 -0
  101. truecell-0.9.0/truecell/generics.py +397 -0
  102. truecell-0.9.0/truecell/glmpca.py +506 -0
  103. truecell-0.9.0/truecell/graph.py +180 -0
  104. truecell-0.9.0/truecell/hto.py +361 -0
  105. truecell-0.9.0/truecell/integration.py +283 -0
  106. truecell-0.9.0/truecell/io.py +134 -0
  107. truecell-0.9.0/truecell/jackstraw.py +259 -0
  108. truecell-0.9.0/truecell/lazy.py +381 -0
  109. truecell-0.9.0/truecell/logmap.py +96 -0
  110. truecell-0.9.0/truecell/mapping.py +289 -0
  111. truecell-0.9.0/truecell/markers.py +819 -0
  112. truecell-0.9.0/truecell/mixins/__init__.py +3 -0
  113. truecell-0.9.0/truecell/mixins/key_mixin.py +30 -0
  114. truecell-0.9.0/truecell/mixscape.py +762 -0
  115. truecell-0.9.0/truecell/module_score.py +278 -0
  116. truecell-0.9.0/truecell/multimodal.py +333 -0
  117. truecell-0.9.0/truecell/multiseq.py +272 -0
  118. truecell-0.9.0/truecell/neighbor.py +129 -0
  119. truecell-0.9.0/truecell/neighbors.py +175 -0
  120. truecell-0.9.0/truecell/plotting.py +1832 -0
  121. truecell-0.9.0/truecell/preprocessing.py +959 -0
  122. truecell-0.9.0/truecell/py.typed +0 -0
  123. truecell-0.9.0/truecell/reduction.py +478 -0
  124. truecell-0.9.0/truecell/sctransform.py +679 -0
  125. truecell-0.9.0/truecell/sketch.py +563 -0
  126. truecell-0.9.0/truecell/spatial/__init__.py +49 -0
  127. truecell-0.9.0/truecell/spatial/analysis.py +239 -0
  128. truecell-0.9.0/truecell/spatial/base.py +95 -0
  129. truecell-0.9.0/truecell/spatial/centroids.py +146 -0
  130. truecell-0.9.0/truecell/spatial/fov.py +274 -0
  131. truecell-0.9.0/truecell/spatial/loaders.py +384 -0
  132. truecell-0.9.0/truecell/spatial/molecules.py +95 -0
  133. truecell-0.9.0/truecell/spatial/segmentation.py +140 -0
  134. truecell-0.9.0/truecell/spatial/variable_features.py +515 -0
  135. truecell-0.9.0/truecell/spatial/visium.py +288 -0
  136. truecell-0.9.0/truecell/transfer.py +394 -0
  137. truecell-0.9.0/truecell/truecell.py +682 -0
  138. truecell-0.9.0/truecell/umap.py +149 -0
@@ -0,0 +1,69 @@
1
+ # truecell agent skills
2
+
3
+ Ten skills that teach an LLM agent to use `truecell` correctly — the API contracts
4
+ that break code silently, the decisions each analysis step forces, and the
5
+ places truecell and R Seurat genuinely differ.
6
+
7
+ They are plain Markdown with YAML frontmatter, so they work as
8
+ [Claude Agent Skills](https://docs.claude.com/en/docs/agents-and-tools/agent-skills/overview)
9
+ and as context for any other model.
10
+
11
+ ## The set
12
+
13
+ | Skill | Load it for |
14
+ |---|---|
15
+ | [`truecell`](truecell/SKILL.md) | **Start here.** Install, the six API contracts, the canonical pipeline, routing. Bundles the full [API map](truecell/reference/api-map.md) and [object model](truecell/reference/object-model.md). |
16
+ | [`truecell-workflow`](truecell-workflow/SKILL.md) | A standard scRNA-seq run: QC thresholds, LogNormalize vs SCTransform, how many PCs, resolution, annotation. |
17
+ | [`truecell-differential-expression`](truecell-differential-expression/SKILL.md) | Marker genes, the eight `test_use` options, pseudobulk, conserved markers. |
18
+ | [`truecell-integration`](truecell-integration/SKILL.md) | Batch correction (Harmony/CCA/RPCA), label transfer, reference mapping, and scoring whether it worked. |
19
+ | [`truecell-multimodal`](truecell-multimodal/SKILL.md) | CITE-seq + WNN, cell hashing, pooled CRISPR (Mixscape). Includes the CLR `margin` rule. |
20
+ | [`truecell-spatial`](truecell-spatial/SKILL.md) | Xenium / Visium / CosMx / MERSCOPE, niches, spatially variable features, spatial plots. |
21
+ | [`truecell-at-scale`](truecell-at-scale/SKILL.md) | Leverage sketching and on-disk `LazyMatrix`, for data that doesn't fit in RAM. |
22
+ | [`truecell-plotting`](truecell-plotting/SKILL.md) | All 17 plotting functions, their Seurat equivalents, and headless saving. |
23
+ | [`truecell-from-seurat`](truecell-from-seurat/SKILL.md) | Porting R Seurat code, and comparing the two tools' numbers honestly. |
24
+ | [`truecell-dev`](truecell-dev/SKILL.md) | Contributing to truecell itself: tests, lint, docs, the fidelity apparatus, release conventions. |
25
+
26
+ Each `SKILL.md` stands alone. The router skill points at the others but does not
27
+ depend on them being loaded.
28
+
29
+ ## Using them
30
+
31
+ ### Claude Code
32
+
33
+ `.claude/skills` in this repo is a symlink to this directory, so the skills are
34
+ discovered automatically when Claude Code runs here. To use them from another
35
+ project:
36
+
37
+ ```bash
38
+ ln -s /path/to/truecell/skills ~/.claude/skills/truecell
39
+ ```
40
+
41
+ Or copy individual skill directories into `.claude/skills/`.
42
+
43
+ ### Claude.ai / Projects
44
+
45
+ Upload the `SKILL.md` files (and `truecell/reference/*.md`) as project knowledge.
46
+ Names and descriptions in the frontmatter are what make the right one surface.
47
+
48
+ ### Any other model
49
+
50
+ Concatenate what the task needs — the router plus one domain skill is usually
51
+ enough, and the whole set is small:
52
+
53
+ ```bash
54
+ cat skills/truecell/SKILL.md skills/truecell-workflow/SKILL.md
55
+ cat skills/truecell/reference/api-map.md # when parameter names matter
56
+ ```
57
+
58
+ ## Keeping them true
59
+
60
+ Every signature, default and measured number in these files came from the
61
+ package or from a recorded R comparison, not from memory. When the API changes,
62
+ the places to re-derive are:
63
+
64
+ ```bash
65
+ python -c "import truecell, inspect; print([n for n in truecell.__all__])"
66
+ python -c "import truecell, inspect; print(inspect.signature(truecell.find_markers))"
67
+ ```
68
+
69
+ and, for the fidelity claims, <https://genomicai.github.io/truecell/fidelity/>.
@@ -0,0 +1,164 @@
1
+ ---
2
+ name: truecell
3
+ description: Use when writing, reading, debugging or reviewing Python single-cell analysis code that uses the truecell package (a port of R Seurat) — creating Truecell objects, the QC → normalize → HVG → scale → PCA → neighbours → clusters → UMAP → markers pipeline, or translating Seurat code to Python. Start here; it carries the API contracts that break code silently and routes to the task-specific truecell skills.
4
+ ---
5
+
6
+ # truecell
7
+
8
+ `truecell` is a Python port of [Seurat](https://satijalab.org/seurat/) v5 — the same
9
+ data structures and the same algorithms, checked against R Seurat 5.5.1 test by
10
+ test. Version **0.9.0**, Python **3.12+**, MIT.
11
+
12
+ - Docs: <https://genomicai.github.io/truecell/> · Repo: <https://github.com/GenomicAI/truecell>
13
+ - 105 public names, all exported from the package root **except the generics**
14
+ (see contract 6 below).
15
+
16
+ ```bash
17
+ pip install truecell # core: objects, preprocessing, PCA, markers
18
+ pip install "truecell[analysis]" # + clustering, UMAP, plotting ← the usual one
19
+ pip install "truecell[anndata]" # + AnnData interop
20
+ pip install "truecell[integration]" # + Harmony (harmonypy)
21
+ pip install "truecell[deseq2]" # + pseudobulk DESeq2
22
+ pip install "truecell[all]" # everything, incl. dev + docs tooling
23
+ ```
24
+
25
+ ## The six contracts
26
+
27
+ Almost every mistake made against this API is one of these. Check them before
28
+ writing anything.
29
+
30
+ **1. Analysis functions mutate in place and return `None`.**
31
+
32
+ ```python
33
+ truecell.normalize_data(pbmc) # correct — call for effect
34
+ pbmc = truecell.normalize_data(pbmc) # WRONG — pbmc is now None
35
+ ```
36
+
37
+ Applies to `normalize_data`, `find_variable_features`, `scale_data`,
38
+ `percentage_feature_set`, `run_pca` / `run_ica` / `run_spca` / `run_tsne` /
39
+ `glm_pca`, `find_neighbors`, `find_multi_modal_neighbors`, `find_clusters`,
40
+ `run_umap`, `run_harmony`, `integrate_layers`.
41
+
42
+ Rebind **only** for the functions that build a new object:
43
+ `subset`, `merge`, `sketch_data`, `integrate_data`.
44
+
45
+ A third group mutates in place *and* returns the same object it mutated
46
+ (`sctransform`, `add_module_score`, `cell_cycle_scoring`, `hto_demux`,
47
+ `multiseq_demux`, `calc_perturb_sig`, `run_mixscape`, `mixscape_lda`). Rebinding
48
+ is harmless there but is not the idiom — call for effect everywhere except the
49
+ four above.
50
+
51
+ Functions that compute a *result* rather than mutating return it: `find_markers`,
52
+ `find_all_markers`, `find_conserved_markers`, `aggregate_expression`,
53
+ `transfer_data`, `find_spatially_variable_features`, `composition_test`,
54
+ `leverage_score`, and every plotting function (→ `matplotlib.figure.Figure`).
55
+
56
+ **2. `dims` is 0-based.** `range(10)` here is `1:10` in R. This is the one
57
+ indexing difference in the API and it follows Python on purpose.
58
+
59
+ **3. Matrices are features × cells** — genes as rows, same as Seurat, transposed
60
+ relative to AnnData/scanpy. `create_truecell_object(counts, ...)` expects
61
+ genes × cells.
62
+
63
+ **4. Expression lives in named layers**, not attributes: `counts` (raw),
64
+ `data` (log-normalized), `scale.data` (z-scored). Read them with
65
+ `obj.get_assay().layer_data("data")`.
66
+
67
+ **5. Names are snake_case ports of Seurat's**: `FindMarkers` → `find_markers`,
68
+ `RunPCA` → `run_pca`, `nn.method` → `nn_method`. Parameters that collide with
69
+ Python keywords get a trailing underscore (`lambda_`, `type_`).
70
+
71
+ **6. The generics are not top-level.** `cells`, `features`, `idents`,
72
+ `fetch_data`, `layer_data`, `layers`, `split_layers`, `join_layers`,
73
+ `embeddings`, `loadings`, `stdev`, `variable_features`, `which_cells`,
74
+ `rename_idents` and the rest live in `truecell.generics`:
75
+
76
+ ```python
77
+ import truecell
78
+ truecell.generics.features(pbmc) # correct
79
+ truecell.features(pbmc) # AttributeError
80
+ ```
81
+
82
+ Same for the loaders: `from truecell.io import read_10x`,
83
+ `from truecell.datasets import pbmc3k`, `from truecell.compat.anndata import as_anndata`.
84
+ (The published API reference says everything is top-level; for the generics page
85
+ that is not true.)
86
+
87
+ ## The canonical pipeline
88
+
89
+ ```python
90
+ import truecell
91
+ from truecell.datasets import pbmc3k
92
+
93
+ counts, genes, cells = pbmc3k() # caches to ~/.truecell_data/ (~24 MB)
94
+ pbmc = truecell.create_truecell_object(
95
+ counts=counts, feature_names=genes, cell_names=cells,
96
+ project="pbmc3k", min_cells=3, min_features=200,
97
+ )
98
+
99
+ # QC
100
+ truecell.percentage_feature_set(pbmc, pattern=r"^MT-", col_name="percent.mt")
101
+ md = pbmc.meta_data
102
+ keep = (md["nFeature_RNA"] > 200) & (md["nFeature_RNA"] < 2500) & (md["percent.mt"] < 5)
103
+ pbmc = pbmc.subset(cells=list(md.index[keep])) # subset RETURNS a new object
104
+
105
+ # Normalize → select → scale
106
+ truecell.normalize_data(pbmc, normalization_method="LogNormalize", scale_factor=10000)
107
+ truecell.find_variable_features(pbmc, selection_method="vst", nfeatures=2000)
108
+ truecell.scale_data(pbmc) # defaults to the variable features
109
+
110
+ # Reduce → graph → cluster → embed
111
+ truecell.run_pca(pbmc, n_pcs=50)
112
+ truecell.find_neighbors(pbmc, dims=range(10), k_param=20) # writes RNA_nn, RNA_snn
113
+ truecell.find_clusters(pbmc, resolution=0.5) # writes seurat_clusters + idents
114
+ truecell.run_umap(pbmc, dims=range(10), seed=42)
115
+
116
+ # Markers
117
+ markers = truecell.find_all_markers(pbmc, only_pos=True, min_pct=0.25, logfc_threshold=0.25)
118
+
119
+ fig = truecell.dim_plot(pbmc, reduction="umap", label=True)
120
+ fig.savefig("umap.png", dpi=150, bbox_inches="tight")
121
+ ```
122
+
123
+ Where results land: `pbmc.meta_data` (per-cell columns), `pbmc.reductions`
124
+ (`"pca"`, `"umap"`), `pbmc.graphs` (`"RNA_nn"`, `"RNA_snn"`), `pbmc.idents`,
125
+ `pbmc.commands` (the audit log), `pbmc.misc` (stashed fit details).
126
+
127
+ ## Which skill to load
128
+
129
+ | Task | Skill |
130
+ |---|---|
131
+ | Standard scRNA-seq run, QC thresholds, how many PCs, resolution choice | `truecell-workflow` |
132
+ | Marker genes, the eight DE tests, pseudobulk, conserved markers | `truecell-differential-expression` |
133
+ | Batch correction (Harmony/CCA/RPCA), label transfer, reference mapping | `truecell-integration` |
134
+ | CITE-seq / WNN, cell hashing demultiplexing, pooled CRISPR (Mixscape) | `truecell-multimodal` |
135
+ | Xenium / Visium / CosMx / MERSCOPE, niches, spatially variable features | `truecell-spatial` |
136
+ | Datasets too big for RAM — leverage sketching, on-disk `LazyMatrix` | `truecell-at-scale` |
137
+ | Any figure | `truecell-plotting` |
138
+ | Porting existing R Seurat code, or comparing the two tools' output | `truecell-from-seurat` |
139
+ | Contributing to truecell itself — tests, lint, docs, fidelity method, release | `truecell-dev` |
140
+
141
+ ## Bundled reference
142
+
143
+ - [`reference/api-map.md`](reference/api-map.md) — every public function with its
144
+ real signature and its Seurat equivalent. Read this before guessing a parameter name.
145
+ - [`reference/object-model.md`](reference/object-model.md) — the `Truecell` /
146
+ `Assay5` / `DimReduc` / `Graph` containers, the generics, subsetting, layers,
147
+ AnnData interop.
148
+
149
+ ## Known, deliberate differences from Seurat
150
+
151
+ Not bugs; do not "fix" them, and do not report them as regressions.
152
+
153
+ - **Louvain cluster counts drift by one.** Same algorithm, same resolution,
154
+ different local optimum. PBMC 3k: 8 clusters to Seurat's 9 at ARI 0.938.
155
+ - **Variable-feature selection jitters at the boundary.** 1,998 of 2,000 genes
156
+ shared on PBMC 3k; the two that swap sit at ranks ~1916–2016 where
157
+ standardized variances agree to three decimals.
158
+ - **Anything with an RNG differs by its RNG and only by that.**
159
+ `add_module_score` draws control genes at random (96.6 % phase concordance,
160
+ Pearson ≥ 0.998 on the scores); `jack_straw` permutes.
161
+ - **truecell's neighbour search is exact; Seurat's default `annoy` is approximate.**
162
+ When comparing, pass `nn.method = "rann"` on the R side.
163
+
164
+ Full evidence, with the numbers: <https://genomicai.github.io/truecell/fidelity/>.
@@ -0,0 +1,304 @@
1
+ # truecell API map
2
+
3
+ Every public function, with its real signature and its Seurat equivalent.
4
+ Signatures are from `truecell` 0.9.0. `seurat` / `obj` as the first parameter means
5
+ a `Truecell` object.
6
+
7
+ **Read the return column.** `None` means the function mutates in place — see
8
+ contract 1 in the parent skill.
9
+
10
+ ---
11
+
12
+ ## Objects
13
+
14
+ | Seurat | truecell |
15
+ |---|---|
16
+ | `CreateSeuratObject` | `create_truecell_object` |
17
+ | `CreateAssayObject` | `create_assay_object` / `create_assay5_object` |
18
+ | `Seurat`, `Assay`, `Assay5`, `DimReduc`, `Graph`, `Neighbor` | same class names |
19
+
20
+ ```python
21
+ create_truecell_object(counts, assay="RNA", min_cells=0, min_features=0,
22
+ project="SeuratProject", feature_names=None, cell_names=None,
23
+ meta_data=None, use_v5=True) -> Truecell
24
+ create_assay_object(counts=None, data=None, min_cells=0, min_features=0,
25
+ feature_names=None, cell_names=None, key="rna_") -> Assay
26
+ create_assay5_object(...same...) -> Assay5
27
+ log_truecell_command(object_, func_name, params=None, assay=None, reduction=None) -> TruecellCommand
28
+ as_graph(x, cell_names=None, assay_used=None, weighted=True) -> Graph
29
+ ```
30
+
31
+ Classes exported: `Truecell`, `Assay`, `Assay5`, `StdAssay`, `DimReduc`, `Graph`,
32
+ `Neighbor`, `JackStrawData`, `LogMap`, `KeyMixin`, `TruecellCommand`.
33
+
34
+ ## Loading data
35
+
36
+ Not top-level — import from the submodule.
37
+
38
+ ```python
39
+ from truecell.io import read_10x
40
+ read_10x(data_dir, var_names="gene_symbols", make_unique=True) -> (csc_matrix, genes, cells)
41
+
42
+ from truecell.datasets import pbmc3k, pbmc8k, cbmc_citeseq, pbmc_hashing, thp1_eccite, \
43
+ ifnb, panc8, xenium_mouse_brain, visium_mouse_brain
44
+ pbmc3k(data_dir=None, force_download=False) -> (counts, genes, cells)
45
+ cbmc_citeseq(data_dir=None, force_download=False, species_prefix="HUMAN_")
46
+ xenium_mouse_brain(...) -> Path # loaders that return a directory
47
+ visium_mouse_brain(...) -> Path
48
+ ifnb(data_dir=None); panc8(data_dir=None) # need `Rscript tutorials/export_seuratdata.R <name>` once
49
+ ```
50
+
51
+ Everything caches to `~/.truecell_data/` (~770 MB for the full set).
52
+
53
+ ```python
54
+ from truecell.compat.anndata import as_anndata, from_anndata
55
+ as_anndata(seurat, assay=None)
56
+ from_anndata(adata, assay="RNA", spatial_key="spatial", fov_key="fov") -> Truecell
57
+ ```
58
+
59
+ ## Preprocessing
60
+
61
+ | Seurat | truecell | Returns |
62
+ |---|---|---|
63
+ | `PercentageFeatureSet` | `percentage_feature_set` | `None` |
64
+ | `NormalizeData` | `normalize_data` | `None` |
65
+ | `FindVariableFeatures` | `find_variable_features` | `None` |
66
+ | `ScaleData` | `scale_data` | `None` |
67
+ | `SCTransform` | `sctransform` | the object |
68
+
69
+ ```python
70
+ percentage_feature_set(seurat, pattern, col_name=None, assay=None, layer="counts") -> None
71
+ normalize_data(seurat, normalization_method="LogNormalize", scale_factor=10000.0,
72
+ assay=None, margin=1) -> None
73
+ find_variable_features(seurat, selection_method="vst", nfeatures=2000, assay=None,
74
+ layer=None, mean_cutoff=(0.1, 8), dispersion_cutoff=(1, inf),
75
+ num_bin=20, binning_method="equal_width") -> None
76
+ scale_data(seurat, features=None, vars_to_regress=None, assay=None, do_scale=True,
77
+ do_center=True, scale_max=10.0, layer="data") -> None
78
+ sctransform(seurat, assay=None, new_assay_name="SCT", n_cells=5000, n_genes=2000,
79
+ n_features=3000, min_cells=5, vars_to_regress=None, clip_range=None,
80
+ gene_chunk=500, seed=42, set_default=True, vst_flavor="v2",
81
+ bw_adjust=3.0, verbose=False)
82
+ ```
83
+
84
+ - `normalization_method`: `"LogNormalize"`, `"CLR"`, `"RC"`. `margin=1` = per
85
+ feature, `2` = per cell (matters for CLR on protein/HTO assays).
86
+ - `selection_method`: `"vst"` (default; honours `nfeatures`), `"mvp"` /
87
+ `"dispersion"` (honours `mean_cutoff` / `dispersion_cutoff` instead).
88
+ - `scale_data(features=None)` scales the **variable features**, as Seurat does.
89
+ Pass `features=truecell.generics.features(obj)` for `ScaleData(features = rownames(obj))`.
90
+ - `vst_flavor="v2"` is Seurat 5's model; `"v1"` is the 2019 one.
91
+
92
+ ## Dimensional reduction
93
+
94
+ | Seurat | truecell |
95
+ |---|---|
96
+ | `RunPCA` | `run_pca` |
97
+ | `RunICA` | `run_ica` |
98
+ | `RunSPCA` | `run_spca` |
99
+ | `RunTSNE` | `run_tsne` |
100
+ | `RunUMAP` | `run_umap` |
101
+ | `JackStraw` / `ScoreJackStraw` | `jack_straw` / `score_jackstraw` |
102
+
103
+ ```python
104
+ run_pca(seurat, n_pcs=50, features=None, assay=None, reduction_name="pca",
105
+ reduction_key="PC_", seed=42, layer="scale.data") -> None
106
+ run_ica(seurat, nics=50, ..., reduction_name="ica", reduction_key="ICA_", max_iter=200) -> None
107
+ run_spca(seurat, graph, npcs=50, ..., reduction_name="spca") -> None # graph is required
108
+ run_tsne(seurat, dims=None, reduction="pca", n_components=2, perplexity=30.0,
109
+ reduction_name="tsne", seed=42, assay=None) -> None
110
+ run_umap(seurat, dims=None, reduction="pca", graph=None, n_components=2,
111
+ n_neighbors=30, min_dist=0.3, metric="euclidean", reduction_name="umap",
112
+ reduction_key="UMAP_", seed=42, assay=None) -> None
113
+ glm_pca(seurat, n_components=10, features=None, assay=None, reduction_name="glmpca",
114
+ family="poisson", layer="counts", max_iter=100, tol=1e-4, penalty=1.0,
115
+ learning_rate=0.1, theta=100.0, optimize_theta=True, seed=42) -> None
116
+ jack_straw(seurat, reduction="pca", dims=20, num_replicate=100, prop_freq=0.01,
117
+ layer="scale.data", seed=42) -> JackStrawData
118
+ score_jackstraw(seurat, reduction="pca", dims=None, score_thresh=1e-5) -> np.ndarray
119
+ ```
120
+
121
+ `run_umap` takes **either** `dims=` on a reduction **or** `graph=` (a graph name),
122
+ matching `RunUMAP`'s two modes. `glm_pca` runs on `counts`, not scaled data.
123
+
124
+ ## Graphs and clustering
125
+
126
+ ```python
127
+ find_neighbors(seurat, dims=None, k_param=20, assay=None, reduction="pca",
128
+ graph_name=None, nn_name=None, prune_snn=1/15, seed=42) -> None
129
+ find_clusters(seurat, resolution=0.5, algorithm=1, graph_name=None, random_seed=0,
130
+ n_iterations=-1, group_singletons=True) -> None
131
+ find_multi_modal_neighbors(seurat, reduction_list=("pca", "apca"), dims_list=None,
132
+ k_nn=20, l2_norm=True, knn_graph_name="wknn",
133
+ snn_graph_name="wsnn", knn_range=200, prune_snn=1/15,
134
+ sd_scale=1.0, cross_constant=None, smooth=False, seed=42) -> None
135
+ ```
136
+
137
+ - `find_neighbors` writes `graphs["{assay}_nn"]` and `graphs["{assay}_snn"]`.
138
+ - `find_clusters` reads `{assay}_snn` unless `graph_name=` is given, and writes
139
+ `meta_data["seurat_clusters"]` plus the active identity.
140
+ - `algorithm`: **1** = Louvain (default), **2** = Louvain multilevel,
141
+ **4** = Leiden. **3 (SLM) is not implemented.**
142
+ - `group_singletons=True` absorbs size-1 clusters into their best-connected
143
+ neighbour, as Seurat's `GroupSingletons` does.
144
+
145
+ ## Differential expression → `truecell-differential-expression`
146
+
147
+ ```python
148
+ find_markers(seurat, ident_1, ident_2=None, assay=None, layer=None, test_use="wilcox",
149
+ only_pos=False, min_pct=0.1, logfc_threshold=0.25, features=None,
150
+ latent_vars=None, sample_col=None, max_cells_per_ident=None,
151
+ random_seed=1) -> pd.DataFrame
152
+ find_all_markers(seurat, assay=None, layer=None, test_use="wilcox", only_pos=False,
153
+ min_pct=0.1, logfc_threshold=0.25, sample_col=None,
154
+ max_cells_per_ident=None, random_seed=1, return_thresh=0.01) -> pd.DataFrame
155
+ find_conserved_markers(seurat, ident_1, grouping_var, ident_2=None, assay=None,
156
+ layer=None, test_use="wilcox", only_pos=False, min_pct=0.1,
157
+ logfc_threshold=0.25, features=None) -> pd.DataFrame
158
+ aggregate_expression(seurat, group_by="ident", assays=None, features=None,
159
+ layer="counts", return_object=False)
160
+ ```
161
+
162
+ `test_use`: `wilcox` · `t` · `bimod` · `LR` · `negbinom` · `mast` · `deseq2` · `roc`.
163
+
164
+ ## Integration and mapping → `truecell-integration`
165
+
166
+ ```python
167
+ run_harmony(seurat, group_by, reduction="pca", dims=None, reduction_name="harmony",
168
+ reduction_key="harmony_", theta=None, lambda_=None, sigma=0.1,
169
+ nclust=None, max_iter_harmony=10, assay=None, seed=0) -> None
170
+ integrate_layers(seurat, method="harmony", orig_reduction="pca", new_reduction=None,
171
+ group_by=None, assay=None, **kwargs) -> None
172
+ find_integration_anchors(objects, anchor_features=None, reduction="cca", dims=30,
173
+ k_anchor=5, k_filter=200, k_score=30, reference=0,
174
+ layer="scale.data", seed=42) -> IntegrationAnchors
175
+ integrate_data(anchors, new_assay="integrated", k_weight=100, sd_weight=1.0,
176
+ add_cell_ids=None, seed=42) # returns a NEW object
177
+ integrate_embeddings(anchors, reduction, new_reduction="integrated_dr",
178
+ dims_to_integrate=None, k_weight=100, sd_weight=1.0) -> DimReduc
179
+ find_transfer_anchors(reference, query, anchor_features=None, reduction="pcaproject",
180
+ dims=30, k_anchor=5, k_filter=200, k_score=30,
181
+ layer="scale.data", seed=42) -> TransferAnchors
182
+ transfer_data(anchors, refdata, k_weight=50, sd_weight=1.0,
183
+ refdata_features=None) -> pd.DataFrame
184
+ map_query(anchors, refdata=None, reference_reduction="pca", reduction_model="umap",
185
+ reduction_name="ref.umap", reduction_key="refUMAP_", k_weight=50,
186
+ sd_weight=1.0, refdata_features=None, layer="scale.data")
187
+ project_umap(query, reference, reduction="pca", umap_reduction="umap", dims=None,
188
+ reduction_name="ref.umap", reduction_key="refUMAP_", layer="scale.data") -> DimReduc
189
+ ```
190
+
191
+ `integrate_layers(method=)`: `"harmony"` · `"cca"` · `"rpca"`. `group_by=` is
192
+ required for every method.
193
+
194
+ ## Signature scoring
195
+
196
+ ```python
197
+ add_module_score(seurat, features, pool=None, nbin=24, ctrl=100, name="Cluster",
198
+ assay=None, layer="data", seed=1, search=False)
199
+ cell_cycle_scoring(seurat, s_features=None, g2m_features=None, assay=None,
200
+ layer="data", set_ident=False, nbin=24, ctrl=100, seed=1)
201
+ CC_GENES # the Tirosh 2016 human S / G2M sets, used when the args are None
202
+ ```
203
+
204
+ `features` for `add_module_score` is a gene list, a list of gene lists, or a
205
+ `{name: genes}` dict. Columns land as `{name}1`, `{name}2`, … or the dict keys.
206
+ `cell_cycle_scoring` writes `S.Score`, `G2M.Score`, `Phase`.
207
+
208
+ ## Demultiplexing and screens → `truecell-multimodal`
209
+
210
+ ```python
211
+ hto_demux(seurat, assay="HTO", positive_quantile=0.99, init=None, nstarts=10,
212
+ kfunc="clara", nsamples=100, normalize=True, margin=1, seed=42, verbose=False)
213
+ multiseq_demux(seurat, assay="HTO", quantile=0.7, autothresh=False, maxiter=5,
214
+ qrange=None, normalize=True, margin=1, verbose=False)
215
+ calc_perturb_sig(seurat, assay="RNA", features=None, layer="data", labels="gene",
216
+ nt_class="NT", split_by=None, num_neighbors=20, reduction="pca",
217
+ ndims=15, new_assay="PRTB")
218
+ run_mixscape(seurat, assay="PRTB", labels="gene", nt_class="NT", de_assay="RNA",
219
+ layer="data", min_de_genes=5, min_cells=5, logfc_threshold=0.25,
220
+ min_pct=0.05, pval_cutoff=0.05, iter_num=10, prtb_type="KO",
221
+ new_class="mixscape_class", de_test="wilcox", seed=0, verbose=False)
222
+ mixscape_lda(seurat, labels="gene", nt_class="NT", assay="PRTB", de_assay="RNA",
223
+ layer="data", npcs=10, logfc_threshold=0.25, min_pct=0.1,
224
+ pval_cutoff=0.05, de_test="wilcox", reduction_name="lda",
225
+ reduction_key="LDA_", scale_max=10.0, seed=42, verbose=False)
226
+ ```
227
+
228
+ ## Spatial → `truecell-spatial`
229
+
230
+ ```python
231
+ load_xenium(path, assay="Xenium", fov_column=None, project="Xenium", keep_controls=False)
232
+ load_visium(path, assay="Spatial", project="Visium", image=True,
233
+ image_resolution="lowres", filter_by_tissue=True, slice_name="slice1")
234
+ load_cosmx(path, expr_file=None, meta_file=None, assay="Nanostring",
235
+ fov_column="fov", project="CosMx")
236
+ load_merscope(path, expr_file=None, meta_file=None, assay="Vizgen",
237
+ fov_column="fov", project="MERSCOPE", keep_controls=False)
238
+
239
+ create_centroids(coords, nsides=0, radius=None, theta=None, assay="", key="centroids_")
240
+ create_segmentation(coords, assay="", key="segmentation_")
241
+ create_molecules(coords, assay="", key="molecules_")
242
+ create_fov(coords, type_="centroids", nsides=0, radius=None, theta=None, assay="", key="fov_")
243
+ create_fovs(coords, fov=None, assay="", default_name="fov") -> dict[str, FOV]
244
+
245
+ get_tissue_coordinates(seurat, image=None) -> pd.DataFrame
246
+ spatial_knn(coords, k=10, query=None) -> (distances, indices)
247
+ nearest_neighbor_distance(seurat, group_by, reference, target=None, image=None) -> pd.DataFrame
248
+ local_neighborhood(seurat, group_by, reference=None, k=10, image=None) -> pd.DataFrame
249
+ build_niche_assay(seurat, group_by, image=None, k=20, niches=4, assay_name="niche",
250
+ cluster=True, seed=0)
251
+ find_spatially_variable_features(seurat, features=None, method="moransi", k=10,
252
+ weights="inverse_square", assay=None, layer=None,
253
+ image=None, r_metric=5.0, bandwidth=1.0) -> pd.DataFrame
254
+ composition_test(seurat, group_by, split_by, reference=None) -> pd.DataFrame
255
+ ```
256
+
257
+ Spatial classes: `SpatialImage`, `Centroids`, `Segmentation`, `Molecules`, `FOV`,
258
+ `VisiumV2`, `ScaleFactors`.
259
+
260
+ ## Scale → `truecell-at-scale`
261
+
262
+ ```python
263
+ leverage_score(obj, nsketch=5000, ndims=None, features=None, assay=None, layer="data",
264
+ var_name="leverage.score", eps=0.5, seed=123) -> np.ndarray
265
+ sketch_data(obj, ncells=5000, method="LeverageScore", features=None, assay=None,
266
+ layer="data", nsketch=5000, sketched_assay="sketch",
267
+ var_name="leverage.score", seed=123) # returns a NEW object
268
+ project_data(full, sketch, reduction="pca", full_reduction="pca.full",
269
+ umap_reduction="umap", full_umap_reduction="ref.umap", refdata=None,
270
+ project_umap=True, dims=None, k_weight=50, sd_weight=1.0,
271
+ layer="scale.data")
272
+ write_lazy_matrix(matrix, path, *, overwrite=False) -> LazyMatrix
273
+ open_lazy_matrix(path) -> LazyMatrix
274
+ is_lazy(x) -> bool
275
+ ```
276
+
277
+ ## Plotting → `truecell-plotting`
278
+
279
+ All 17 return a `matplotlib.figure.Figure`.
280
+
281
+ `vln_plot` · `feature_plot` · `dim_plot` · `elbow_plot` · `feature_scatter` ·
282
+ `variable_feature_plot` · `viz_dim_loadings` · `dim_heatmap` · `do_heatmap` ·
283
+ `ridge_plot` · `dot_plot` · `image_dim_plot` · `image_feature_plot` ·
284
+ `spatial_dim_plot` · `spatial_feature_plot` · `plot_perturb_score` ·
285
+ `mixscape_heatmap`
286
+
287
+ ## Generics (`truecell.generics.*`, not top-level)
288
+
289
+ `cells` · `features` · `idents` · `set_ident` · `stash_ident` · `rename_idents` ·
290
+ `reorder_ident` · `which_cells` · `fetch_data` · `layer_data` · `set_layer_data` ·
291
+ `layers` · `split_layers` · `join_layers` · `get_assay_data` · `set_assay_data` ·
292
+ `embeddings` · `loadings` · `set_loadings` · `stdev` · `variable_features` ·
293
+ `set_variable_features` · `hvf_info` · `default_assay` · `set_default_assay` ·
294
+ `set_default_layer` · `key` · `set_key` · `keys` · `assay_names` · `assay_class` ·
295
+ `cast_assay` · `add_meta_data` · `rename_cells` · `match_cells` · `calc_n` ·
296
+ `command` · `misc` / `set_misc` · `tool` / `set_tool` · `version` · `as_sparse` ·
297
+ `as_graph` · `as_neighbor` · `as_seurat` · `check_matrix` · `is_matrix_empty` ·
298
+ `simplify` · `stitch_matrix` · `distances` · `indices` ·
299
+ spatial: `boundaries` · `crop` · `overlay` · `radius` · `theta` · `get_image` ·
300
+ `get_molecules` · `get_tissue_coordinates` · `default_boundary` · `default_fov` ·
301
+ `is_global` · `as_centroids` · `as_segmentation` · `create_fov` · `create_centroids` ·
302
+ `create_segmentation`
303
+
304
+ See [`object-model.md`](object-model.md) for what each dispatches on.