[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-aws-labs-cell-type-annotation":3,"mdc-x7rwer-key":49,"related-org-aws-labs-cell-type-annotation":3036,"related-repo-aws-labs-cell-type-annotation":3216},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":26,"repoUrl":27,"updatedAt":28,"license":29,"forks":30,"topics":31,"repo":44,"sourceUrl":47,"mdContent":48},"cell-type-annotation","annotate single-cell RNA-seq clusters","Generate code to assign cell type labels to single-cell RNA-seq clusters using CellTypist, SingleR, marker-based annotation, or reference label transfer (scANVI\u002Fingest). Triggers on requests to \"annotate cell types\", \"label clusters\", \"run CellTypist\", \"SingleR annotation\", \"marker gene dotplot\", \"transfer labels from reference atlas\", \"cell identity\", \"automated annotation\", \"reference mapping\", \"scANVI label transfer\", \"canonical markers\", \"immune cell types\", \"hierarchical annotation\", \"majority voting CellTypist\", \"over-clustering annotation\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"aws-labs","AWS Labs","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Faws-labs.png","awslabs",[13,17,20,23],{"name":14,"slug":15,"type":16},"Data Analysis","data-analysis","tag",{"name":18,"slug":19,"type":16},"Life Sciences","life-sciences",{"name":21,"slug":22,"type":16},"Bioinformatics","bioinformatics",{"name":24,"slug":25,"type":16},"RNA-seq","rna-seq",4,"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fhcls-agent-skills","2026-07-12T08:38:05.443454",null,0,[32,33,34,35,36,37,38,39,40,19,41,42,43],"agent-skills","agentcore","ai-agents","amazon-quick-desktop","claims-processing","drug-discovery","genomics","healthcare-ai","kiro","medical-imaging","risk-adjustment","strands-agents",{"repoUrl":27,"stars":26,"forks":30,"topics":45,"description":46},[32,33,34,35,36,37,38,39,40,19,41,42,43],"Agent skills for healthcare and life sciences: genomics, imaging, claims, drug discovery, and more. Works with Amazon Quick, Kiro, Amazon AgentCore, AWS Strands SDK, Claude Code, Codex, and any Agent Skills-compatible platform.","https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fhcls-agent-skills\u002Ftree\u002FHEAD\u002Fskills\u002Fcell-type-annotation","---\nname: cell-type-annotation\ndescription: Generate code to assign cell type labels to single-cell RNA-seq clusters using CellTypist, SingleR, marker-based annotation, or reference label transfer (scANVI\u002Fingest). Triggers on requests to \"annotate cell types\", \"label clusters\", \"run CellTypist\", \"SingleR annotation\", \"marker gene dotplot\", \"transfer labels from reference atlas\", \"cell identity\", \"automated annotation\", \"reference mapping\", \"scANVI label transfer\", \"canonical markers\", \"immune cell types\", \"hierarchical annotation\", \"majority voting CellTypist\", \"over-clustering annotation\".\nusage: Invoke when annotating cell types in scRNA-seq data using CellTypist, SingleR, marker genes, or reference label transfer.\nversion: 1.1.0\nvalidated_against:\n  date: 2025-01-15\n  packages: {celltypist: \"1.6\", scanpy: \"1.10\"}\ntags: [skill, category:pipeline, single-cell, cell-type, celltypist, annotation, hcls]\n---\n\n# Cell Type Annotation\n\n## Overview\n\nThis pipeline skill generates code for annotating cell types in single-cell RNA-seq data. It covers four complementary approaches:\n\n1. **Automated** — CellTypist (logistic-regression classifiers trained on curated atlases).\n2. **Reference-based** — SingleR (R) or scANVI\u002F`sc.tl.ingest` (Python) label transfer.\n3. **Marker-based** — Manual assignment from canonical marker gene panels.\n4. **Hierarchical** — Coarse compartment assignment followed by specialized fine-grained annotation.\n\nUse it when the user has a clustered `AnnData` (or `SingleCellExperiment`) and needs cell-type labels in `adata.obs`.\n\n## Usage\n\n### Decision Tree: Choosing an Annotation Approach\n\nFollow this decision tree to select the right method:\n\n1. **Is there a CellTypist model matching your tissue and species?**\n   - YES → Use CellTypist (Steps 1–6 below)\n   - NO → Go to step 2\n2. **Do you have a labeled reference AnnData from the same tissue?**\n   - YES, same batch\u002Ftechnology → Use `sc.tl.ingest` (Step 12)\n   - YES, different batches → Use scANVI label transfer (Step 13)\n   - NO → Go to step 3\n3. **Are you working in R with bulk or sorted-cell references?**\n   - YES → Use SingleR (Steps 7–9)\n   - NO → Go to step 4\n4. **Do you have canonical marker gene panels for expected cell types?**\n   - YES → Use marker-based annotation (Steps 10–11)\n   - NO → Start with CellTypist's broadest model (`Immune_All_Low.pkl` or `Developing_Human_Brain.pkl`), then refine with markers\n\n### Annotation Workflow (15 Steps)\n\n**Step 1 — Confirm normalization.** CellTypist requires `log1p(CP10k)`. Check `adata.uns['log1p']` exists or run normalization. If data is in `adata.raw` or a layer, subset appropriately.\n\n**Step 2 — Verify gene symbols.** Confirm `adata.var_names` are HGNC (human) or MGI (mouse) symbols, not Ensembl IDs. Convert if needed with `sc.queries.biomart_annotations`.\n\n**Step 3 — Select CellTypist model.** Match species + tissue. Use `celltypist.models.models_description()` to list options. If unsure, start with the broadest model for the compartment.\n\n**Step 4 — Run CellTypist annotation.** Use `celltypist.annotate()` with `majority_voting=True` and appropriate `p_thres` (default 0.5; raise to 0.7 for stringent calls).\n\n**Step 5 — Extract results via `to_adata()`.** Call `predictions.to_adata()` to get annotations in `.obs`. Access confidence via `adata_result.obs['conf_score']`.\n\n**Step 6 — Filter low-confidence cells.** Mask cells with `conf_score \u003C 0.5` (or user-specified threshold) as `'Unknown'`.\n\n**Step 7 — (SingleR) Install references.** Use `BiocManager::install(\"celldex\")` and load the appropriate reference dataset.\n\n**Step 8 — (SingleR) Run prediction.** Call `SingleR(test, ref, labels)` with `assay.type.test = \"logcounts\"`.\n\n**Step 9 — (SingleR) Prune low-quality calls.** Use `pruneScores(pred)` to identify unreliable assignments; set those to `\"Unknown\"`.\n\n**Step 10 — (Marker-based) Define panels.** Provide ≥3 markers per cell type from literature. Include negative markers where informative.\n\n**Step 11 — (Marker-based) Score and assign.** Use `sc.pl.dotplot` to visualize, then map clusters to types. Leave ambiguous clusters as `'Unknown'`.\n\n**Step 12 — (Ingest) Project query onto reference.** Requires shared PCA space; run `sc.tl.ingest(adata_query, adata_ref, obs='cell_type')`. Only works well when query and reference share the same technology and minimal batch effects.\n\n**Step 13 — (scANVI) Semi-supervised transfer.** Train SCVI on reference, extend to SCANVI with labels, then `load_query_data` for the query. Handles batch effects natively.\n\n**Step 14 — Validate annotations.** Confirm with dotplot of canonical markers grouped by assigned cell type. Check per-sample proportions for biological plausibility.\n\n**Step 15 — Hierarchical refinement.** If fine labels are unstable, annotate coarse compartments first (immune\u002Fstromal\u002Fepithelial via PTPRC\u002FEPCAM\u002FCOL1A1), subset, then re-annotate each with a specialized model or markers.\n\n### Branch Points\n\n- At Step 4: if `>30%` of cells get `conf_score \u003C 0.5`, the model is a poor fit → switch to marker-based or try a different model.\n- At Step 6: if a single label dominates `>80%` of cells unexpectedly, suspect wrong model or un-normalized data.\n- At Step 12: if query UMAP doesn't align with reference after ingest, batch effects are too strong → switch to scANVI (Step 13).\n- At Step 14: if proportions are biologically implausible (e.g., 60% fibroblasts in PBMC), re-examine normalization and model choice.\n\n## Response Format\n\n- Lead with the command or code the user needs — explain after.\n- Structure as: confirm inputs → working code → key parameters explained → gotchas.\n- One complete working example per task; do not show every alternative.\n- Keep code comments minimal and functional.\n- Target: 50–100 lines of code with brief surrounding explanation.\n- Always include confidence score extraction and a filtering step.\n\n## Core Concepts\n\n### 1. CellTypist (automated, Python)\n\n```python\nimport scanpy as sc\nimport celltypist\nfrom celltypist import models\n\n# Input: log1p-normalized to 10,000 counts\u002Fcell\nsc.pp.normalize_total(adata, target_sum=1e4)\nsc.pp.log1p(adata)\n\n# Download models (first run only)\nmodels.download_models()\nprint(models.models_description())  # list available models\n\n# Load tissue-matched model\nmodel = models.Model.load(model='Immune_All_Low.pkl')\n\n# Annotate with majority voting\npredictions = celltypist.annotate(\n    adata,\n    model=model,\n    majority_voting=True,       # smooth labels over neighborhood graph\n    over_clustering='leiden',   # obs key for majority voting resolution\n    p_thres=0.5,               # minimum probability threshold (raise for stringency)\n)\n\n# Extract results — modern API (CellTypist >=1.3)\nadata_result = predictions.to_adata()\n# Annotations now in adata_result.obs:\n#   'predicted_labels'        — per-cell raw predictions\n#   'majority_voting'         — smoothed labels\n#   'conf_score'              — max probability per cell\n\n# Transfer to original adata\nadata.obs['cell_type'] = adata_result.obs['majority_voting']\nadata.obs['cell_type_conf'] = adata_result.obs['conf_score']\n\n# Filter low-confidence assignments\nadata.obs.loc[adata.obs['cell_type_conf'] \u003C 0.5, 'cell_type'] = 'Unknown'\n```\n\n**Key parameters for `celltypist.annotate()`:**\n\n| Parameter | Default | Effect |\n|-----------|---------|--------|\n| `majority_voting` | `False` | Smooth labels over kNN graph; always enable |\n| `over_clustering` | `None` | obs key (e.g., `'leiden'`) for voting resolution; finer clusters → better resolution |\n| `p_thres` | `0.5` | Min probability to assign a label; raise to 0.7 for high-confidence only |\n| `mode` | `'best match'` | Use `'prob match'` for multi-label scenarios |\n\nCommon models: `Immune_All_Low`, `Immune_All_High`, `Healthy_COVID19_PBMC`, `Human_Lung_Atlas`, `Cells_Intestinal_Tract`, `Developing_Human_Brain`, `Adult_Mouse_Gut`. Match species and tissue.\n\n### 2. SingleR (reference-based, R)\n\n```r\nif (!requireNamespace(\"BiocManager\", quietly = TRUE))\n    install.packages(\"BiocManager\")\nBiocManager::install(c(\"SingleR\", \"celldex\", \"SingleCellExperiment\"))\n\nlibrary(SingleR)\nlibrary(celldex)\nlibrary(SingleCellExperiment)\n\n# Choose reference matching species\u002Ftissue\nref \u003C- celldex::HumanPrimaryCellAtlasData()\n# ref \u003C- celldex::MonacoImmuneData()       # sorted human immune\n# ref \u003C- celldex::ImmGenData()             # mouse immune\n# ref \u003C- celldex::BlueprintEncodeData()    # human stromal + immune\n\npred \u003C- SingleR(\n    test = sce,\n    ref = ref,\n    labels = ref$label.main,\n    assay.type.test = \"logcounts\"\n)\n\nsce$cell_type \u003C- pred$labels\ntable(pred$labels)\n\n# Prune low-confidence calls (delta \u003C median - 3*MAD)\nsce$cell_type[is.na(pred$pruned.labels)] \u003C- \"Unknown\"\n```\n\n### 3. Marker-based (manual, Python)\n\n```python\nimport scanpy as sc\n\nmarker_genes = {\n    'T cells':      ['CD3D', 'CD3E', 'CD2'],\n    'CD4 T':        ['CD4', 'IL7R'],\n    'CD8 T':        ['CD8A', 'CD8B'],\n    'B cells':      ['CD79A', 'MS4A1', 'CD19'],\n    'NK cells':     ['NKG7', 'GNLY', 'KLRD1'],\n    'Monocytes':    ['CD14', 'LYZ', 'S100A8'],\n    'Dendritic':    ['FCER1A', 'CST3', 'CLEC10A'],\n    'Fibroblasts':  ['COL1A1', 'DCN', 'COL3A1'],\n    'Endothelial':  ['PECAM1', 'VWF', 'CDH5'],\n    'Epithelial':   ['EPCAM', 'KRT18', 'KRT19'],\n}\n\nsc.pl.dotplot(adata, marker_genes, groupby='leiden', standard_scale='var')\n\n# Assign after reviewing the dotplot\ncluster_to_celltype = {\n    '0': 'T cells', '1': 'Monocytes', '2': 'B cells',\n    '3': 'NK cells', '4': 'Unknown',\n}\nadata.obs['cell_type'] = adata.obs['leiden'].map(cluster_to_celltype).astype('category')\n```\n\n### 4. Label transfer from a reference atlas\n\n```python\n# Quick path: sc.tl.ingest (PCA\u002FUMAP projection, kNN labels)\n# Only use when batch effects are minimal\nimport scanpy as sc\nsc.pp.pca(adata_ref)\nsc.pp.neighbors(adata_ref)\nsc.tl.umap(adata_ref)\nsc.tl.ingest(adata_query, adata_ref, obs='cell_type')\n\n# Robust path: scANVI (semi-supervised, handles batch)\nimport scvi\nscvi.model.SCVI.setup_anndata(adata_ref, batch_key='batch')\nscvi_model = scvi.model.SCVI(adata_ref)\nscvi_model.train()\n\nscvi.model.SCANVI.setup_anndata(\n    adata_ref, labels_key='cell_type', unlabeled_category='Unknown', batch_key='batch'\n)\nscanvi_model = scvi.model.SCANVI.from_scvi_model(scvi_model, unlabeled_category='Unknown')\nscanvi_model.train(max_epochs=20)\n\nscanvi_model = scvi.model.SCANVI.load_query_data(adata_query, scanvi_model)\nscanvi_model.train(max_epochs=100, plan_kwargs={'weight_decay': 0.0})\nadata_query.obs['cell_type_pred'] = scanvi_model.predict(adata_query)\n```\n\n### 5. Validation\n\n```python\n# Confirm assigned labels express their markers\nsc.pl.dotplot(adata, marker_genes, groupby='cell_type', standard_scale='var')\nsc.pl.violin(adata, ['CD3D', 'MS4A1', 'CD14'], groupby='cell_type', rotation=90)\n\n# Sanity-check proportions per sample\nadata.obs.groupby(['sample', 'cell_type']).size().unstack(fill_value=0)\n```\n\nMark any cluster without clear marker support as `'Unknown'` rather than forcing a label.\n\n### 6. Hierarchical annotation\n\n```python\n# Step 1: coarse compartments\ncompartment_markers = {\n    'Immune':     ['PTPRC'],           # CD45\n    'Epithelial': ['EPCAM', 'KRT8'],\n    'Stromal':    ['COL1A1', 'PECAM1'],\n}\n# Step 2: subset and re-annotate each compartment\nadata_immune = adata[adata.obs['compartment'] == 'Immune'].copy()\nmodel = models.Model.load('Immune_All_Low.pkl')\npreds = celltypist.annotate(adata_immune, model=model, majority_voting=True)\nadata_immune_result = preds.to_adata()\nadata_immune.obs['cell_type_fine'] = adata_immune_result.obs['majority_voting']\n```\n\n## Quick Reference\n\n| Task | Tool | Key call |\n| --- | --- | --- |\n| PBMC \u002F immune automated | CellTypist | `models.Model.load('Immune_All_Low.pkl')` |\n| Lung atlas mapping | CellTypist | `'Human_Lung_Atlas.pkl'` |\n| Gut \u002F intestine | CellTypist | `'Cells_Intestinal_Tract.pkl'` |\n| Broad human ref (R) | SingleR | `celldex::HumanPrimaryCellAtlasData()` |\n| Sorted immune ref (R) | SingleR | `celldex::MonacoImmuneData()` |\n| Mouse immune (R) | SingleR | `celldex::ImmGenData()` |\n| Query→reference transfer | scanpy | `sc.tl.ingest(adata_q, adata_ref, obs='cell_type')` |\n| Batch-aware transfer | scvi-tools | `SCANVI.load_query_data(...)` |\n| Marker review | scanpy | `sc.pl.dotplot(adata, markers, groupby='leiden')` |\n| Confidence (CellTypist) | CellTypist | `predictions.to_adata().obs['conf_score']` |\n| Confidence (SingleR) | SingleR | `is.na(pred$pruned.labels)` flags low-quality |\n\nRequired inputs:\n- CellTypist: `adata.X` = log1p(CP10k) normalized, genes as HGNC symbols in `adata.var_names`.\n- SingleR: `SingleCellExperiment` with a `logcounts` assay.\n- scANVI: raw counts in `adata.layers['counts']`, `batch_key`, `labels_key` on reference.\n\n### Numeric Thresholds\n\n| Metric | Threshold | Action |\n|--------|-----------|--------|\n| CellTypist `conf_score` | \u003C 0.5 | Label as `'Unknown'` |\n| CellTypist `conf_score` | \u003C 0.7 | Flag for manual review |\n| CellTypist `p_thres` | 0.5 (default) | Raise to 0.7 for stringent annotation |\n| SingleR delta score | \u003C median - 3×MAD | Pruned (set to `NA`) |\n| Cluster size | \u003C 20 cells | Do not assign rare subtypes; use parent label |\n| Marker dotplot fraction | \u003C 0.3 | Marker not reliably expressed; do not use for assignment |\n| Expected proportion deviation | > 3× literature range | Suspect wrong model or normalization error |\n\n## Common Mistakes\n\n1. **Wrong:** Feeding raw counts to CellTypist\n   **Right:** Always run `sc.pp.normalize_total(adata, target_sum=1e4)` + `sc.pp.log1p(adata)` before annotation\n   **Why:** CellTypist expects log1p of counts normalized to 10,000\u002Fcell — raw or SCTransform'd data produces nonsense labels\n\n2. **Wrong:** Using a reference model that doesn't match the tissue or species\n   **Right:** Match species (`Human_*` vs `Mouse_*`) and tissue type when selecting CellTypist models or SingleR references\n   **Why:** Using `Immune_All_Low` on epithelial tumor cells or `HumanPrimaryCellAtlasData` on mouse data produces confident but wrong labels\n\n3. **Wrong:** Passing Ensembl IDs or mixed-case gene symbols to CellTypist\u002FSingleR\n   **Right:** Convert `adata.var_names` to HGNC (human) or MGI (mouse) symbols before annotation\n   **Why:** Ensembl IDs or wrong case (`Cd3d` vs `CD3D`) silently drop features, degrading model performance without warning\n\n4. **Wrong:** Using `predictions.probability_matrix.max(axis=1)` to get confidence scores\n   **Right:** Use `predictions.to_adata().obs['conf_score']` which is the stable API since CellTypist ≥1.3\n   **Why:** The probability matrix approach is fragile and version-dependent — it may break or return incorrect values across updates\n\n5. **Wrong:** Assigning a rare subtype label to a cluster of fewer than 20 cells\n   **Right:** Collapse to the parent cell type or label as `'Unknown'` when cluster size is below 20 cells\n   **Why:** Rare subtype assignments on tiny clusters lack statistical power and are unreliable without strong distinguishing markers\n\n6. **Wrong:** Forcing a label on clusters that lack clear markers after dotplot review\n   **Right:** Keep ambiguous clusters as `'Unknown'` rather than picking the next-best guess\n   **Why:** Forced labels propagate errors into downstream analyses (DE, trajectory) and create false biological narratives\n\n7. **Wrong:** Running CellTypist with `majority_voting=False` and using per-cell labels directly\n   **Right:** Always enable `majority_voting=True` to smooth labels over the local neighborhood graph\n   **Why:** Per-cell predictions are noisy; majority voting leverages cluster structure to produce coherent, stable annotations\n\n8. **Wrong:** Running `sc.tl.ingest` for label transfer without batch correction\n   **Right:** Integrate query and reference first, or use scANVI's `load_query_data` path which handles batch natively\n   **Why:** `ingest` assumes query and reference share the same embedding — batch effects cause misalignment and wrong label transfers\n\n9. **Wrong:** Not validating cell-type proportions against biological expectations\n   **Right:** Always cross-check per-sample cell-type proportions against known tissue composition\n   **Why:** A PBMC sample with 80% fibroblasts is a red flag indicating wrong model, normalization error, or data quality issues\n\n10. **Wrong:** Annotating at one resolution only without hierarchical refinement\n    **Right:** Annotate coarse compartments first (immune\u002Fstromal\u002Fepithelial), then refine each with specialized models or markers\n    **Why:** Fine labels on poorly separated clusters are unstable — hierarchical annotation produces more reliable results\n\n## References\n\n- CellTypist: Dominguez Conde et al. Science 2022, https:\u002F\u002Fdoi.org\u002F10.1126\u002Fscience.abl5197\n- SingleR: Aran et al. Nat Immunol 2019, https:\u002F\u002Fdoi.org\u002F10.1038\u002Fs41590-018-0276-y\n- scANVI: Xu et al. Mol Syst Biol 2021, https:\u002F\u002Fdoi.org\u002F10.15252\u002Fmsb.20209620\n- celldex: Aran et al. 2019, https:\u002F\u002Fbioconductor.org\u002Fpackages\u002Fcelldex\n",{"data":50,"body":66},{"name":4,"description":6,"usage":51,"version":52,"validated_against":53,"tags":58},"Invoke when annotating cell types in scRNA-seq data using CellTypist, SingleR, marker genes, or reference label transfer.","1.1.0",{"date":54,"packages":55},"2025-01-15",{"celltypist":56,"scanpy":57},"1.6","1.10",[59,60,61,62,63,64,65],"skill","category:pipeline","single-cell","cell-type","celltypist","annotation","hcls",{"type":67,"children":68},"root",[69,77,84,90,145,174,180,187,192,308,314,348,373,391,425,465,490,507,530,554,564,587,605,623,633,643,649,695,701,734,740,746,1086,1101,1253,1309,1315,1526,1532,1718,1724,1910,1916,1970,1982,1988,2090,2096,2360,2365,2434,2440,2620,2626,2975,2981,3030],{"type":70,"tag":71,"props":72,"children":73},"element","h1",{"id":4},[74],{"type":75,"value":76},"text","Cell Type Annotation",{"type":70,"tag":78,"props":79,"children":81},"h2",{"id":80},"overview",[82],{"type":75,"value":83},"Overview",{"type":70,"tag":85,"props":86,"children":87},"p",{},[88],{"type":75,"value":89},"This pipeline skill generates code for annotating cell types in single-cell RNA-seq data. It covers four complementary approaches:",{"type":70,"tag":91,"props":92,"children":93},"ol",{},[94,106,125,135],{"type":70,"tag":95,"props":96,"children":97},"li",{},[98,104],{"type":70,"tag":99,"props":100,"children":101},"strong",{},[102],{"type":75,"value":103},"Automated",{"type":75,"value":105}," — CellTypist (logistic-regression classifiers trained on curated atlases).",{"type":70,"tag":95,"props":107,"children":108},{},[109,114,116,123],{"type":70,"tag":99,"props":110,"children":111},{},[112],{"type":75,"value":113},"Reference-based",{"type":75,"value":115}," — SingleR (R) or scANVI\u002F",{"type":70,"tag":117,"props":118,"children":120},"code",{"className":119},[],[121],{"type":75,"value":122},"sc.tl.ingest",{"type":75,"value":124}," (Python) label transfer.",{"type":70,"tag":95,"props":126,"children":127},{},[128,133],{"type":70,"tag":99,"props":129,"children":130},{},[131],{"type":75,"value":132},"Marker-based",{"type":75,"value":134}," — Manual assignment from canonical marker gene panels.",{"type":70,"tag":95,"props":136,"children":137},{},[138,143],{"type":70,"tag":99,"props":139,"children":140},{},[141],{"type":75,"value":142},"Hierarchical",{"type":75,"value":144}," — Coarse compartment assignment followed by specialized fine-grained annotation.",{"type":70,"tag":85,"props":146,"children":147},{},[148,150,156,158,164,166,172],{"type":75,"value":149},"Use it when the user has a clustered ",{"type":70,"tag":117,"props":151,"children":153},{"className":152},[],[154],{"type":75,"value":155},"AnnData",{"type":75,"value":157}," (or ",{"type":70,"tag":117,"props":159,"children":161},{"className":160},[],[162],{"type":75,"value":163},"SingleCellExperiment",{"type":75,"value":165},") and needs cell-type labels in ",{"type":70,"tag":117,"props":167,"children":169},{"className":168},[],[170],{"type":75,"value":171},"adata.obs",{"type":75,"value":173},".",{"type":70,"tag":78,"props":175,"children":177},{"id":176},"usage",[178],{"type":75,"value":179},"Usage",{"type":70,"tag":181,"props":182,"children":184},"h3",{"id":183},"decision-tree-choosing-an-annotation-approach",[185],{"type":75,"value":186},"Decision Tree: Choosing an Annotation Approach",{"type":70,"tag":85,"props":188,"children":189},{},[190],{"type":75,"value":191},"Follow this decision tree to select the right method:",{"type":70,"tag":91,"props":193,"children":194},{},[195,217,250,271],{"type":70,"tag":95,"props":196,"children":197},{},[198,203],{"type":70,"tag":99,"props":199,"children":200},{},[201],{"type":75,"value":202},"Is there a CellTypist model matching your tissue and species?",{"type":70,"tag":204,"props":205,"children":206},"ul",{},[207,212],{"type":70,"tag":95,"props":208,"children":209},{},[210],{"type":75,"value":211},"YES → Use CellTypist (Steps 1–6 below)",{"type":70,"tag":95,"props":213,"children":214},{},[215],{"type":75,"value":216},"NO → Go to step 2",{"type":70,"tag":95,"props":218,"children":219},{},[220,225],{"type":70,"tag":99,"props":221,"children":222},{},[223],{"type":75,"value":224},"Do you have a labeled reference AnnData from the same tissue?",{"type":70,"tag":204,"props":226,"children":227},{},[228,240,245],{"type":70,"tag":95,"props":229,"children":230},{},[231,233,238],{"type":75,"value":232},"YES, same batch\u002Ftechnology → Use ",{"type":70,"tag":117,"props":234,"children":236},{"className":235},[],[237],{"type":75,"value":122},{"type":75,"value":239}," (Step 12)",{"type":70,"tag":95,"props":241,"children":242},{},[243],{"type":75,"value":244},"YES, different batches → Use scANVI label transfer (Step 13)",{"type":70,"tag":95,"props":246,"children":247},{},[248],{"type":75,"value":249},"NO → Go to step 3",{"type":70,"tag":95,"props":251,"children":252},{},[253,258],{"type":70,"tag":99,"props":254,"children":255},{},[256],{"type":75,"value":257},"Are you working in R with bulk or sorted-cell references?",{"type":70,"tag":204,"props":259,"children":260},{},[261,266],{"type":70,"tag":95,"props":262,"children":263},{},[264],{"type":75,"value":265},"YES → Use SingleR (Steps 7–9)",{"type":70,"tag":95,"props":267,"children":268},{},[269],{"type":75,"value":270},"NO → Go to step 4",{"type":70,"tag":95,"props":272,"children":273},{},[274,279],{"type":70,"tag":99,"props":275,"children":276},{},[277],{"type":75,"value":278},"Do you have canonical marker gene panels for expected cell types?",{"type":70,"tag":204,"props":280,"children":281},{},[282,287],{"type":70,"tag":95,"props":283,"children":284},{},[285],{"type":75,"value":286},"YES → Use marker-based annotation (Steps 10–11)",{"type":70,"tag":95,"props":288,"children":289},{},[290,292,298,300,306],{"type":75,"value":291},"NO → Start with CellTypist's broadest model (",{"type":70,"tag":117,"props":293,"children":295},{"className":294},[],[296],{"type":75,"value":297},"Immune_All_Low.pkl",{"type":75,"value":299}," or ",{"type":70,"tag":117,"props":301,"children":303},{"className":302},[],[304],{"type":75,"value":305},"Developing_Human_Brain.pkl",{"type":75,"value":307},"), then refine with markers",{"type":70,"tag":181,"props":309,"children":311},{"id":310},"annotation-workflow-15-steps",[312],{"type":75,"value":313},"Annotation Workflow (15 Steps)",{"type":70,"tag":85,"props":315,"children":316},{},[317,322,324,330,332,338,340,346],{"type":70,"tag":99,"props":318,"children":319},{},[320],{"type":75,"value":321},"Step 1 — Confirm normalization.",{"type":75,"value":323}," CellTypist requires ",{"type":70,"tag":117,"props":325,"children":327},{"className":326},[],[328],{"type":75,"value":329},"log1p(CP10k)",{"type":75,"value":331},". Check ",{"type":70,"tag":117,"props":333,"children":335},{"className":334},[],[336],{"type":75,"value":337},"adata.uns['log1p']",{"type":75,"value":339}," exists or run normalization. If data is in ",{"type":70,"tag":117,"props":341,"children":343},{"className":342},[],[344],{"type":75,"value":345},"adata.raw",{"type":75,"value":347}," or a layer, subset appropriately.",{"type":70,"tag":85,"props":349,"children":350},{},[351,356,358,364,366,372],{"type":70,"tag":99,"props":352,"children":353},{},[354],{"type":75,"value":355},"Step 2 — Verify gene symbols.",{"type":75,"value":357}," Confirm ",{"type":70,"tag":117,"props":359,"children":361},{"className":360},[],[362],{"type":75,"value":363},"adata.var_names",{"type":75,"value":365}," are HGNC (human) or MGI (mouse) symbols, not Ensembl IDs. Convert if needed with ",{"type":70,"tag":117,"props":367,"children":369},{"className":368},[],[370],{"type":75,"value":371},"sc.queries.biomart_annotations",{"type":75,"value":173},{"type":70,"tag":85,"props":374,"children":375},{},[376,381,383,389],{"type":70,"tag":99,"props":377,"children":378},{},[379],{"type":75,"value":380},"Step 3 — Select CellTypist model.",{"type":75,"value":382}," Match species + tissue. Use ",{"type":70,"tag":117,"props":384,"children":386},{"className":385},[],[387],{"type":75,"value":388},"celltypist.models.models_description()",{"type":75,"value":390}," to list options. If unsure, start with the broadest model for the compartment.",{"type":70,"tag":85,"props":392,"children":393},{},[394,399,401,407,409,415,417,423],{"type":70,"tag":99,"props":395,"children":396},{},[397],{"type":75,"value":398},"Step 4 — Run CellTypist annotation.",{"type":75,"value":400}," Use ",{"type":70,"tag":117,"props":402,"children":404},{"className":403},[],[405],{"type":75,"value":406},"celltypist.annotate()",{"type":75,"value":408}," with ",{"type":70,"tag":117,"props":410,"children":412},{"className":411},[],[413],{"type":75,"value":414},"majority_voting=True",{"type":75,"value":416}," and appropriate ",{"type":70,"tag":117,"props":418,"children":420},{"className":419},[],[421],{"type":75,"value":422},"p_thres",{"type":75,"value":424}," (default 0.5; raise to 0.7 for stringent calls).",{"type":70,"tag":85,"props":426,"children":427},{},[428,440,442,448,450,456,458,464],{"type":70,"tag":99,"props":429,"children":430},{},[431,433,439],{"type":75,"value":432},"Step 5 — Extract results via ",{"type":70,"tag":117,"props":434,"children":436},{"className":435},[],[437],{"type":75,"value":438},"to_adata()",{"type":75,"value":173},{"type":75,"value":441}," Call ",{"type":70,"tag":117,"props":443,"children":445},{"className":444},[],[446],{"type":75,"value":447},"predictions.to_adata()",{"type":75,"value":449}," to get annotations in ",{"type":70,"tag":117,"props":451,"children":453},{"className":452},[],[454],{"type":75,"value":455},".obs",{"type":75,"value":457},". Access confidence via ",{"type":70,"tag":117,"props":459,"children":461},{"className":460},[],[462],{"type":75,"value":463},"adata_result.obs['conf_score']",{"type":75,"value":173},{"type":70,"tag":85,"props":466,"children":467},{},[468,473,475,481,483,489],{"type":70,"tag":99,"props":469,"children":470},{},[471],{"type":75,"value":472},"Step 6 — Filter low-confidence cells.",{"type":75,"value":474}," Mask cells with ",{"type":70,"tag":117,"props":476,"children":478},{"className":477},[],[479],{"type":75,"value":480},"conf_score \u003C 0.5",{"type":75,"value":482}," (or user-specified threshold) as ",{"type":70,"tag":117,"props":484,"children":486},{"className":485},[],[487],{"type":75,"value":488},"'Unknown'",{"type":75,"value":173},{"type":70,"tag":85,"props":491,"children":492},{},[493,498,499,505],{"type":70,"tag":99,"props":494,"children":495},{},[496],{"type":75,"value":497},"Step 7 — (SingleR) Install references.",{"type":75,"value":400},{"type":70,"tag":117,"props":500,"children":502},{"className":501},[],[503],{"type":75,"value":504},"BiocManager::install(\"celldex\")",{"type":75,"value":506}," and load the appropriate reference dataset.",{"type":70,"tag":85,"props":508,"children":509},{},[510,515,516,522,523,529],{"type":70,"tag":99,"props":511,"children":512},{},[513],{"type":75,"value":514},"Step 8 — (SingleR) Run prediction.",{"type":75,"value":441},{"type":70,"tag":117,"props":517,"children":519},{"className":518},[],[520],{"type":75,"value":521},"SingleR(test, ref, labels)",{"type":75,"value":408},{"type":70,"tag":117,"props":524,"children":526},{"className":525},[],[527],{"type":75,"value":528},"assay.type.test = \"logcounts\"",{"type":75,"value":173},{"type":70,"tag":85,"props":531,"children":532},{},[533,538,539,545,547,553],{"type":70,"tag":99,"props":534,"children":535},{},[536],{"type":75,"value":537},"Step 9 — (SingleR) Prune low-quality calls.",{"type":75,"value":400},{"type":70,"tag":117,"props":540,"children":542},{"className":541},[],[543],{"type":75,"value":544},"pruneScores(pred)",{"type":75,"value":546}," to identify unreliable assignments; set those to ",{"type":70,"tag":117,"props":548,"children":550},{"className":549},[],[551],{"type":75,"value":552},"\"Unknown\"",{"type":75,"value":173},{"type":70,"tag":85,"props":555,"children":556},{},[557,562],{"type":70,"tag":99,"props":558,"children":559},{},[560],{"type":75,"value":561},"Step 10 — (Marker-based) Define panels.",{"type":75,"value":563}," Provide ≥3 markers per cell type from literature. Include negative markers where informative.",{"type":70,"tag":85,"props":565,"children":566},{},[567,572,573,579,581,586],{"type":70,"tag":99,"props":568,"children":569},{},[570],{"type":75,"value":571},"Step 11 — (Marker-based) Score and assign.",{"type":75,"value":400},{"type":70,"tag":117,"props":574,"children":576},{"className":575},[],[577],{"type":75,"value":578},"sc.pl.dotplot",{"type":75,"value":580}," to visualize, then map clusters to types. Leave ambiguous clusters as ",{"type":70,"tag":117,"props":582,"children":584},{"className":583},[],[585],{"type":75,"value":488},{"type":75,"value":173},{"type":70,"tag":85,"props":588,"children":589},{},[590,595,597,603],{"type":70,"tag":99,"props":591,"children":592},{},[593],{"type":75,"value":594},"Step 12 — (Ingest) Project query onto reference.",{"type":75,"value":596}," Requires shared PCA space; run ",{"type":70,"tag":117,"props":598,"children":600},{"className":599},[],[601],{"type":75,"value":602},"sc.tl.ingest(adata_query, adata_ref, obs='cell_type')",{"type":75,"value":604},". Only works well when query and reference share the same technology and minimal batch effects.",{"type":70,"tag":85,"props":606,"children":607},{},[608,613,615,621],{"type":70,"tag":99,"props":609,"children":610},{},[611],{"type":75,"value":612},"Step 13 — (scANVI) Semi-supervised transfer.",{"type":75,"value":614}," Train SCVI on reference, extend to SCANVI with labels, then ",{"type":70,"tag":117,"props":616,"children":618},{"className":617},[],[619],{"type":75,"value":620},"load_query_data",{"type":75,"value":622}," for the query. Handles batch effects natively.",{"type":70,"tag":85,"props":624,"children":625},{},[626,631],{"type":70,"tag":99,"props":627,"children":628},{},[629],{"type":75,"value":630},"Step 14 — Validate annotations.",{"type":75,"value":632}," Confirm with dotplot of canonical markers grouped by assigned cell type. Check per-sample proportions for biological plausibility.",{"type":70,"tag":85,"props":634,"children":635},{},[636,641],{"type":70,"tag":99,"props":637,"children":638},{},[639],{"type":75,"value":640},"Step 15 — Hierarchical refinement.",{"type":75,"value":642}," If fine labels are unstable, annotate coarse compartments first (immune\u002Fstromal\u002Fepithelial via PTPRC\u002FEPCAM\u002FCOL1A1), subset, then re-annotate each with a specialized model or markers.",{"type":70,"tag":181,"props":644,"children":646},{"id":645},"branch-points",[647],{"type":75,"value":648},"Branch Points",{"type":70,"tag":204,"props":650,"children":651},{},[652,672,685,690],{"type":70,"tag":95,"props":653,"children":654},{},[655,657,663,665,670],{"type":75,"value":656},"At Step 4: if ",{"type":70,"tag":117,"props":658,"children":660},{"className":659},[],[661],{"type":75,"value":662},">30%",{"type":75,"value":664}," of cells get ",{"type":70,"tag":117,"props":666,"children":668},{"className":667},[],[669],{"type":75,"value":480},{"type":75,"value":671},", the model is a poor fit → switch to marker-based or try a different model.",{"type":70,"tag":95,"props":673,"children":674},{},[675,677,683],{"type":75,"value":676},"At Step 6: if a single label dominates ",{"type":70,"tag":117,"props":678,"children":680},{"className":679},[],[681],{"type":75,"value":682},">80%",{"type":75,"value":684}," of cells unexpectedly, suspect wrong model or un-normalized data.",{"type":70,"tag":95,"props":686,"children":687},{},[688],{"type":75,"value":689},"At Step 12: if query UMAP doesn't align with reference after ingest, batch effects are too strong → switch to scANVI (Step 13).",{"type":70,"tag":95,"props":691,"children":692},{},[693],{"type":75,"value":694},"At Step 14: if proportions are biologically implausible (e.g., 60% fibroblasts in PBMC), re-examine normalization and model choice.",{"type":70,"tag":78,"props":696,"children":698},{"id":697},"response-format",[699],{"type":75,"value":700},"Response Format",{"type":70,"tag":204,"props":702,"children":703},{},[704,709,714,719,724,729],{"type":70,"tag":95,"props":705,"children":706},{},[707],{"type":75,"value":708},"Lead with the command or code the user needs — explain after.",{"type":70,"tag":95,"props":710,"children":711},{},[712],{"type":75,"value":713},"Structure as: confirm inputs → working code → key parameters explained → gotchas.",{"type":70,"tag":95,"props":715,"children":716},{},[717],{"type":75,"value":718},"One complete working example per task; do not show every alternative.",{"type":70,"tag":95,"props":720,"children":721},{},[722],{"type":75,"value":723},"Keep code comments minimal and functional.",{"type":70,"tag":95,"props":725,"children":726},{},[727],{"type":75,"value":728},"Target: 50–100 lines of code with brief surrounding explanation.",{"type":70,"tag":95,"props":730,"children":731},{},[732],{"type":75,"value":733},"Always include confidence score extraction and a filtering step.",{"type":70,"tag":78,"props":735,"children":737},{"id":736},"core-concepts",[738],{"type":75,"value":739},"Core Concepts",{"type":70,"tag":181,"props":741,"children":743},{"id":742},"_1-celltypist-automated-python",[744],{"type":75,"value":745},"1. CellTypist (automated, Python)",{"type":70,"tag":747,"props":748,"children":753},"pre",{"className":749,"code":750,"language":751,"meta":752,"style":752},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import scanpy as sc\nimport celltypist\nfrom celltypist import models\n\n# Input: log1p-normalized to 10,000 counts\u002Fcell\nsc.pp.normalize_total(adata, target_sum=1e4)\nsc.pp.log1p(adata)\n\n# Download models (first run only)\nmodels.download_models()\nprint(models.models_description())  # list available models\n\n# Load tissue-matched model\nmodel = models.Model.load(model='Immune_All_Low.pkl')\n\n# Annotate with majority voting\npredictions = celltypist.annotate(\n    adata,\n    model=model,\n    majority_voting=True,       # smooth labels over neighborhood graph\n    over_clustering='leiden',   # obs key for majority voting resolution\n    p_thres=0.5,               # minimum probability threshold (raise for stringency)\n)\n\n# Extract results — modern API (CellTypist >=1.3)\nadata_result = predictions.to_adata()\n# Annotations now in adata_result.obs:\n#   'predicted_labels'        — per-cell raw predictions\n#   'majority_voting'         — smoothed labels\n#   'conf_score'              — max probability per cell\n\n# Transfer to original adata\nadata.obs['cell_type'] = adata_result.obs['majority_voting']\nadata.obs['cell_type_conf'] = adata_result.obs['conf_score']\n\n# Filter low-confidence assignments\nadata.obs.loc[adata.obs['cell_type_conf'] \u003C 0.5, 'cell_type'] = 'Unknown'\n","python","",[754],{"type":70,"tag":117,"props":755,"children":756},{"__ignoreMap":752},[757,768,777,786,795,804,813,822,830,839,848,857,865,874,883,891,900,909,918,927,936,945,954,963,971,980,989,998,1007,1016,1025,1033,1042,1051,1060,1068,1077],{"type":70,"tag":758,"props":759,"children":762},"span",{"class":760,"line":761},"line",1,[763],{"type":70,"tag":758,"props":764,"children":765},{},[766],{"type":75,"value":767},"import scanpy as sc\n",{"type":70,"tag":758,"props":769,"children":771},{"class":760,"line":770},2,[772],{"type":70,"tag":758,"props":773,"children":774},{},[775],{"type":75,"value":776},"import celltypist\n",{"type":70,"tag":758,"props":778,"children":780},{"class":760,"line":779},3,[781],{"type":70,"tag":758,"props":782,"children":783},{},[784],{"type":75,"value":785},"from celltypist import models\n",{"type":70,"tag":758,"props":787,"children":788},{"class":760,"line":26},[789],{"type":70,"tag":758,"props":790,"children":792},{"emptyLinePlaceholder":791},true,[793],{"type":75,"value":794},"\n",{"type":70,"tag":758,"props":796,"children":798},{"class":760,"line":797},5,[799],{"type":70,"tag":758,"props":800,"children":801},{},[802],{"type":75,"value":803},"# Input: log1p-normalized to 10,000 counts\u002Fcell\n",{"type":70,"tag":758,"props":805,"children":807},{"class":760,"line":806},6,[808],{"type":70,"tag":758,"props":809,"children":810},{},[811],{"type":75,"value":812},"sc.pp.normalize_total(adata, target_sum=1e4)\n",{"type":70,"tag":758,"props":814,"children":816},{"class":760,"line":815},7,[817],{"type":70,"tag":758,"props":818,"children":819},{},[820],{"type":75,"value":821},"sc.pp.log1p(adata)\n",{"type":70,"tag":758,"props":823,"children":825},{"class":760,"line":824},8,[826],{"type":70,"tag":758,"props":827,"children":828},{"emptyLinePlaceholder":791},[829],{"type":75,"value":794},{"type":70,"tag":758,"props":831,"children":833},{"class":760,"line":832},9,[834],{"type":70,"tag":758,"props":835,"children":836},{},[837],{"type":75,"value":838},"# Download models (first run only)\n",{"type":70,"tag":758,"props":840,"children":842},{"class":760,"line":841},10,[843],{"type":70,"tag":758,"props":844,"children":845},{},[846],{"type":75,"value":847},"models.download_models()\n",{"type":70,"tag":758,"props":849,"children":851},{"class":760,"line":850},11,[852],{"type":70,"tag":758,"props":853,"children":854},{},[855],{"type":75,"value":856},"print(models.models_description())  # list available models\n",{"type":70,"tag":758,"props":858,"children":860},{"class":760,"line":859},12,[861],{"type":70,"tag":758,"props":862,"children":863},{"emptyLinePlaceholder":791},[864],{"type":75,"value":794},{"type":70,"tag":758,"props":866,"children":868},{"class":760,"line":867},13,[869],{"type":70,"tag":758,"props":870,"children":871},{},[872],{"type":75,"value":873},"# Load tissue-matched model\n",{"type":70,"tag":758,"props":875,"children":877},{"class":760,"line":876},14,[878],{"type":70,"tag":758,"props":879,"children":880},{},[881],{"type":75,"value":882},"model = models.Model.load(model='Immune_All_Low.pkl')\n",{"type":70,"tag":758,"props":884,"children":886},{"class":760,"line":885},15,[887],{"type":70,"tag":758,"props":888,"children":889},{"emptyLinePlaceholder":791},[890],{"type":75,"value":794},{"type":70,"tag":758,"props":892,"children":894},{"class":760,"line":893},16,[895],{"type":70,"tag":758,"props":896,"children":897},{},[898],{"type":75,"value":899},"# Annotate with majority voting\n",{"type":70,"tag":758,"props":901,"children":903},{"class":760,"line":902},17,[904],{"type":70,"tag":758,"props":905,"children":906},{},[907],{"type":75,"value":908},"predictions = celltypist.annotate(\n",{"type":70,"tag":758,"props":910,"children":912},{"class":760,"line":911},18,[913],{"type":70,"tag":758,"props":914,"children":915},{},[916],{"type":75,"value":917},"    adata,\n",{"type":70,"tag":758,"props":919,"children":921},{"class":760,"line":920},19,[922],{"type":70,"tag":758,"props":923,"children":924},{},[925],{"type":75,"value":926},"    model=model,\n",{"type":70,"tag":758,"props":928,"children":930},{"class":760,"line":929},20,[931],{"type":70,"tag":758,"props":932,"children":933},{},[934],{"type":75,"value":935},"    majority_voting=True,       # smooth labels over neighborhood graph\n",{"type":70,"tag":758,"props":937,"children":939},{"class":760,"line":938},21,[940],{"type":70,"tag":758,"props":941,"children":942},{},[943],{"type":75,"value":944},"    over_clustering='leiden',   # obs key for majority voting resolution\n",{"type":70,"tag":758,"props":946,"children":948},{"class":760,"line":947},22,[949],{"type":70,"tag":758,"props":950,"children":951},{},[952],{"type":75,"value":953},"    p_thres=0.5,               # minimum probability threshold (raise for stringency)\n",{"type":70,"tag":758,"props":955,"children":957},{"class":760,"line":956},23,[958],{"type":70,"tag":758,"props":959,"children":960},{},[961],{"type":75,"value":962},")\n",{"type":70,"tag":758,"props":964,"children":966},{"class":760,"line":965},24,[967],{"type":70,"tag":758,"props":968,"children":969},{"emptyLinePlaceholder":791},[970],{"type":75,"value":794},{"type":70,"tag":758,"props":972,"children":974},{"class":760,"line":973},25,[975],{"type":70,"tag":758,"props":976,"children":977},{},[978],{"type":75,"value":979},"# Extract results — modern API (CellTypist >=1.3)\n",{"type":70,"tag":758,"props":981,"children":983},{"class":760,"line":982},26,[984],{"type":70,"tag":758,"props":985,"children":986},{},[987],{"type":75,"value":988},"adata_result = predictions.to_adata()\n",{"type":70,"tag":758,"props":990,"children":992},{"class":760,"line":991},27,[993],{"type":70,"tag":758,"props":994,"children":995},{},[996],{"type":75,"value":997},"# Annotations now in adata_result.obs:\n",{"type":70,"tag":758,"props":999,"children":1001},{"class":760,"line":1000},28,[1002],{"type":70,"tag":758,"props":1003,"children":1004},{},[1005],{"type":75,"value":1006},"#   'predicted_labels'        — per-cell raw predictions\n",{"type":70,"tag":758,"props":1008,"children":1010},{"class":760,"line":1009},29,[1011],{"type":70,"tag":758,"props":1012,"children":1013},{},[1014],{"type":75,"value":1015},"#   'majority_voting'         — smoothed labels\n",{"type":70,"tag":758,"props":1017,"children":1019},{"class":760,"line":1018},30,[1020],{"type":70,"tag":758,"props":1021,"children":1022},{},[1023],{"type":75,"value":1024},"#   'conf_score'              — max probability per cell\n",{"type":70,"tag":758,"props":1026,"children":1028},{"class":760,"line":1027},31,[1029],{"type":70,"tag":758,"props":1030,"children":1031},{"emptyLinePlaceholder":791},[1032],{"type":75,"value":794},{"type":70,"tag":758,"props":1034,"children":1036},{"class":760,"line":1035},32,[1037],{"type":70,"tag":758,"props":1038,"children":1039},{},[1040],{"type":75,"value":1041},"# Transfer to original adata\n",{"type":70,"tag":758,"props":1043,"children":1045},{"class":760,"line":1044},33,[1046],{"type":70,"tag":758,"props":1047,"children":1048},{},[1049],{"type":75,"value":1050},"adata.obs['cell_type'] = adata_result.obs['majority_voting']\n",{"type":70,"tag":758,"props":1052,"children":1054},{"class":760,"line":1053},34,[1055],{"type":70,"tag":758,"props":1056,"children":1057},{},[1058],{"type":75,"value":1059},"adata.obs['cell_type_conf'] = adata_result.obs['conf_score']\n",{"type":70,"tag":758,"props":1061,"children":1063},{"class":760,"line":1062},35,[1064],{"type":70,"tag":758,"props":1065,"children":1066},{"emptyLinePlaceholder":791},[1067],{"type":75,"value":794},{"type":70,"tag":758,"props":1069,"children":1071},{"class":760,"line":1070},36,[1072],{"type":70,"tag":758,"props":1073,"children":1074},{},[1075],{"type":75,"value":1076},"# Filter low-confidence assignments\n",{"type":70,"tag":758,"props":1078,"children":1080},{"class":760,"line":1079},37,[1081],{"type":70,"tag":758,"props":1082,"children":1083},{},[1084],{"type":75,"value":1085},"adata.obs.loc[adata.obs['cell_type_conf'] \u003C 0.5, 'cell_type'] = 'Unknown'\n",{"type":70,"tag":85,"props":1087,"children":1088},{},[1089],{"type":70,"tag":99,"props":1090,"children":1091},{},[1092,1094,1099],{"type":75,"value":1093},"Key parameters for ",{"type":70,"tag":117,"props":1095,"children":1097},{"className":1096},[],[1098],{"type":75,"value":406},{"type":75,"value":1100},":",{"type":70,"tag":1102,"props":1103,"children":1104},"table",{},[1105,1129],{"type":70,"tag":1106,"props":1107,"children":1108},"thead",{},[1109],{"type":70,"tag":1110,"props":1111,"children":1112},"tr",{},[1113,1119,1124],{"type":70,"tag":1114,"props":1115,"children":1116},"th",{},[1117],{"type":75,"value":1118},"Parameter",{"type":70,"tag":1114,"props":1120,"children":1121},{},[1122],{"type":75,"value":1123},"Default",{"type":70,"tag":1114,"props":1125,"children":1126},{},[1127],{"type":75,"value":1128},"Effect",{"type":70,"tag":1130,"props":1131,"children":1132},"tbody",{},[1133,1160,1194,1219],{"type":70,"tag":1110,"props":1134,"children":1135},{},[1136,1146,1155],{"type":70,"tag":1137,"props":1138,"children":1139},"td",{},[1140],{"type":70,"tag":117,"props":1141,"children":1143},{"className":1142},[],[1144],{"type":75,"value":1145},"majority_voting",{"type":70,"tag":1137,"props":1147,"children":1148},{},[1149],{"type":70,"tag":117,"props":1150,"children":1152},{"className":1151},[],[1153],{"type":75,"value":1154},"False",{"type":70,"tag":1137,"props":1156,"children":1157},{},[1158],{"type":75,"value":1159},"Smooth labels over kNN graph; always enable",{"type":70,"tag":1110,"props":1161,"children":1162},{},[1163,1172,1181],{"type":70,"tag":1137,"props":1164,"children":1165},{},[1166],{"type":70,"tag":117,"props":1167,"children":1169},{"className":1168},[],[1170],{"type":75,"value":1171},"over_clustering",{"type":70,"tag":1137,"props":1173,"children":1174},{},[1175],{"type":70,"tag":117,"props":1176,"children":1178},{"className":1177},[],[1179],{"type":75,"value":1180},"None",{"type":70,"tag":1137,"props":1182,"children":1183},{},[1184,1186,1192],{"type":75,"value":1185},"obs key (e.g., ",{"type":70,"tag":117,"props":1187,"children":1189},{"className":1188},[],[1190],{"type":75,"value":1191},"'leiden'",{"type":75,"value":1193},") for voting resolution; finer clusters → better resolution",{"type":70,"tag":1110,"props":1195,"children":1196},{},[1197,1205,1214],{"type":70,"tag":1137,"props":1198,"children":1199},{},[1200],{"type":70,"tag":117,"props":1201,"children":1203},{"className":1202},[],[1204],{"type":75,"value":422},{"type":70,"tag":1137,"props":1206,"children":1207},{},[1208],{"type":70,"tag":117,"props":1209,"children":1211},{"className":1210},[],[1212],{"type":75,"value":1213},"0.5",{"type":70,"tag":1137,"props":1215,"children":1216},{},[1217],{"type":75,"value":1218},"Min probability to assign a label; raise to 0.7 for high-confidence only",{"type":70,"tag":1110,"props":1220,"children":1221},{},[1222,1231,1240],{"type":70,"tag":1137,"props":1223,"children":1224},{},[1225],{"type":70,"tag":117,"props":1226,"children":1228},{"className":1227},[],[1229],{"type":75,"value":1230},"mode",{"type":70,"tag":1137,"props":1232,"children":1233},{},[1234],{"type":70,"tag":117,"props":1235,"children":1237},{"className":1236},[],[1238],{"type":75,"value":1239},"'best match'",{"type":70,"tag":1137,"props":1241,"children":1242},{},[1243,1245,1251],{"type":75,"value":1244},"Use ",{"type":70,"tag":117,"props":1246,"children":1248},{"className":1247},[],[1249],{"type":75,"value":1250},"'prob match'",{"type":75,"value":1252}," for multi-label scenarios",{"type":70,"tag":85,"props":1254,"children":1255},{},[1256,1258,1264,1266,1272,1273,1279,1280,1286,1287,1293,1294,1300,1301,1307],{"type":75,"value":1257},"Common models: ",{"type":70,"tag":117,"props":1259,"children":1261},{"className":1260},[],[1262],{"type":75,"value":1263},"Immune_All_Low",{"type":75,"value":1265},", ",{"type":70,"tag":117,"props":1267,"children":1269},{"className":1268},[],[1270],{"type":75,"value":1271},"Immune_All_High",{"type":75,"value":1265},{"type":70,"tag":117,"props":1274,"children":1276},{"className":1275},[],[1277],{"type":75,"value":1278},"Healthy_COVID19_PBMC",{"type":75,"value":1265},{"type":70,"tag":117,"props":1281,"children":1283},{"className":1282},[],[1284],{"type":75,"value":1285},"Human_Lung_Atlas",{"type":75,"value":1265},{"type":70,"tag":117,"props":1288,"children":1290},{"className":1289},[],[1291],{"type":75,"value":1292},"Cells_Intestinal_Tract",{"type":75,"value":1265},{"type":70,"tag":117,"props":1295,"children":1297},{"className":1296},[],[1298],{"type":75,"value":1299},"Developing_Human_Brain",{"type":75,"value":1265},{"type":70,"tag":117,"props":1302,"children":1304},{"className":1303},[],[1305],{"type":75,"value":1306},"Adult_Mouse_Gut",{"type":75,"value":1308},". Match species and tissue.",{"type":70,"tag":181,"props":1310,"children":1312},{"id":1311},"_2-singler-reference-based-r",[1313],{"type":75,"value":1314},"2. SingleR (reference-based, R)",{"type":70,"tag":747,"props":1316,"children":1320},{"className":1317,"code":1318,"language":1319,"meta":752,"style":752},"language-r shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","if (!requireNamespace(\"BiocManager\", quietly = TRUE))\n    install.packages(\"BiocManager\")\nBiocManager::install(c(\"SingleR\", \"celldex\", \"SingleCellExperiment\"))\n\nlibrary(SingleR)\nlibrary(celldex)\nlibrary(SingleCellExperiment)\n\n# Choose reference matching species\u002Ftissue\nref \u003C- celldex::HumanPrimaryCellAtlasData()\n# ref \u003C- celldex::MonacoImmuneData()       # sorted human immune\n# ref \u003C- celldex::ImmGenData()             # mouse immune\n# ref \u003C- celldex::BlueprintEncodeData()    # human stromal + immune\n\npred \u003C- SingleR(\n    test = sce,\n    ref = ref,\n    labels = ref$label.main,\n    assay.type.test = \"logcounts\"\n)\n\nsce$cell_type \u003C- pred$labels\ntable(pred$labels)\n\n# Prune low-confidence calls (delta \u003C median - 3*MAD)\nsce$cell_type[is.na(pred$pruned.labels)] \u003C- \"Unknown\"\n","r",[1321],{"type":70,"tag":117,"props":1322,"children":1323},{"__ignoreMap":752},[1324,1332,1340,1348,1355,1363,1371,1379,1386,1394,1402,1410,1418,1426,1433,1441,1449,1457,1465,1473,1480,1487,1495,1503,1510,1518],{"type":70,"tag":758,"props":1325,"children":1326},{"class":760,"line":761},[1327],{"type":70,"tag":758,"props":1328,"children":1329},{},[1330],{"type":75,"value":1331},"if (!requireNamespace(\"BiocManager\", quietly = TRUE))\n",{"type":70,"tag":758,"props":1333,"children":1334},{"class":760,"line":770},[1335],{"type":70,"tag":758,"props":1336,"children":1337},{},[1338],{"type":75,"value":1339},"    install.packages(\"BiocManager\")\n",{"type":70,"tag":758,"props":1341,"children":1342},{"class":760,"line":779},[1343],{"type":70,"tag":758,"props":1344,"children":1345},{},[1346],{"type":75,"value":1347},"BiocManager::install(c(\"SingleR\", \"celldex\", \"SingleCellExperiment\"))\n",{"type":70,"tag":758,"props":1349,"children":1350},{"class":760,"line":26},[1351],{"type":70,"tag":758,"props":1352,"children":1353},{"emptyLinePlaceholder":791},[1354],{"type":75,"value":794},{"type":70,"tag":758,"props":1356,"children":1357},{"class":760,"line":797},[1358],{"type":70,"tag":758,"props":1359,"children":1360},{},[1361],{"type":75,"value":1362},"library(SingleR)\n",{"type":70,"tag":758,"props":1364,"children":1365},{"class":760,"line":806},[1366],{"type":70,"tag":758,"props":1367,"children":1368},{},[1369],{"type":75,"value":1370},"library(celldex)\n",{"type":70,"tag":758,"props":1372,"children":1373},{"class":760,"line":815},[1374],{"type":70,"tag":758,"props":1375,"children":1376},{},[1377],{"type":75,"value":1378},"library(SingleCellExperiment)\n",{"type":70,"tag":758,"props":1380,"children":1381},{"class":760,"line":824},[1382],{"type":70,"tag":758,"props":1383,"children":1384},{"emptyLinePlaceholder":791},[1385],{"type":75,"value":794},{"type":70,"tag":758,"props":1387,"children":1388},{"class":760,"line":832},[1389],{"type":70,"tag":758,"props":1390,"children":1391},{},[1392],{"type":75,"value":1393},"# Choose reference matching species\u002Ftissue\n",{"type":70,"tag":758,"props":1395,"children":1396},{"class":760,"line":841},[1397],{"type":70,"tag":758,"props":1398,"children":1399},{},[1400],{"type":75,"value":1401},"ref \u003C- celldex::HumanPrimaryCellAtlasData()\n",{"type":70,"tag":758,"props":1403,"children":1404},{"class":760,"line":850},[1405],{"type":70,"tag":758,"props":1406,"children":1407},{},[1408],{"type":75,"value":1409},"# ref \u003C- celldex::MonacoImmuneData()       # sorted human immune\n",{"type":70,"tag":758,"props":1411,"children":1412},{"class":760,"line":859},[1413],{"type":70,"tag":758,"props":1414,"children":1415},{},[1416],{"type":75,"value":1417},"# ref \u003C- celldex::ImmGenData()             # mouse immune\n",{"type":70,"tag":758,"props":1419,"children":1420},{"class":760,"line":867},[1421],{"type":70,"tag":758,"props":1422,"children":1423},{},[1424],{"type":75,"value":1425},"# ref \u003C- celldex::BlueprintEncodeData()    # human stromal + immune\n",{"type":70,"tag":758,"props":1427,"children":1428},{"class":760,"line":876},[1429],{"type":70,"tag":758,"props":1430,"children":1431},{"emptyLinePlaceholder":791},[1432],{"type":75,"value":794},{"type":70,"tag":758,"props":1434,"children":1435},{"class":760,"line":885},[1436],{"type":70,"tag":758,"props":1437,"children":1438},{},[1439],{"type":75,"value":1440},"pred \u003C- SingleR(\n",{"type":70,"tag":758,"props":1442,"children":1443},{"class":760,"line":893},[1444],{"type":70,"tag":758,"props":1445,"children":1446},{},[1447],{"type":75,"value":1448},"    test = sce,\n",{"type":70,"tag":758,"props":1450,"children":1451},{"class":760,"line":902},[1452],{"type":70,"tag":758,"props":1453,"children":1454},{},[1455],{"type":75,"value":1456},"    ref = ref,\n",{"type":70,"tag":758,"props":1458,"children":1459},{"class":760,"line":911},[1460],{"type":70,"tag":758,"props":1461,"children":1462},{},[1463],{"type":75,"value":1464},"    labels = ref$label.main,\n",{"type":70,"tag":758,"props":1466,"children":1467},{"class":760,"line":920},[1468],{"type":70,"tag":758,"props":1469,"children":1470},{},[1471],{"type":75,"value":1472},"    assay.type.test = \"logcounts\"\n",{"type":70,"tag":758,"props":1474,"children":1475},{"class":760,"line":929},[1476],{"type":70,"tag":758,"props":1477,"children":1478},{},[1479],{"type":75,"value":962},{"type":70,"tag":758,"props":1481,"children":1482},{"class":760,"line":938},[1483],{"type":70,"tag":758,"props":1484,"children":1485},{"emptyLinePlaceholder":791},[1486],{"type":75,"value":794},{"type":70,"tag":758,"props":1488,"children":1489},{"class":760,"line":947},[1490],{"type":70,"tag":758,"props":1491,"children":1492},{},[1493],{"type":75,"value":1494},"sce$cell_type \u003C- pred$labels\n",{"type":70,"tag":758,"props":1496,"children":1497},{"class":760,"line":956},[1498],{"type":70,"tag":758,"props":1499,"children":1500},{},[1501],{"type":75,"value":1502},"table(pred$labels)\n",{"type":70,"tag":758,"props":1504,"children":1505},{"class":760,"line":965},[1506],{"type":70,"tag":758,"props":1507,"children":1508},{"emptyLinePlaceholder":791},[1509],{"type":75,"value":794},{"type":70,"tag":758,"props":1511,"children":1512},{"class":760,"line":973},[1513],{"type":70,"tag":758,"props":1514,"children":1515},{},[1516],{"type":75,"value":1517},"# Prune low-confidence calls (delta \u003C median - 3*MAD)\n",{"type":70,"tag":758,"props":1519,"children":1520},{"class":760,"line":982},[1521],{"type":70,"tag":758,"props":1522,"children":1523},{},[1524],{"type":75,"value":1525},"sce$cell_type[is.na(pred$pruned.labels)] \u003C- \"Unknown\"\n",{"type":70,"tag":181,"props":1527,"children":1529},{"id":1528},"_3-marker-based-manual-python",[1530],{"type":75,"value":1531},"3. Marker-based (manual, Python)",{"type":70,"tag":747,"props":1533,"children":1535},{"className":749,"code":1534,"language":751,"meta":752,"style":752},"import scanpy as sc\n\nmarker_genes = {\n    'T cells':      ['CD3D', 'CD3E', 'CD2'],\n    'CD4 T':        ['CD4', 'IL7R'],\n    'CD8 T':        ['CD8A', 'CD8B'],\n    'B cells':      ['CD79A', 'MS4A1', 'CD19'],\n    'NK cells':     ['NKG7', 'GNLY', 'KLRD1'],\n    'Monocytes':    ['CD14', 'LYZ', 'S100A8'],\n    'Dendritic':    ['FCER1A', 'CST3', 'CLEC10A'],\n    'Fibroblasts':  ['COL1A1', 'DCN', 'COL3A1'],\n    'Endothelial':  ['PECAM1', 'VWF', 'CDH5'],\n    'Epithelial':   ['EPCAM', 'KRT18', 'KRT19'],\n}\n\nsc.pl.dotplot(adata, marker_genes, groupby='leiden', standard_scale='var')\n\n# Assign after reviewing the dotplot\ncluster_to_celltype = {\n    '0': 'T cells', '1': 'Monocytes', '2': 'B cells',\n    '3': 'NK cells', '4': 'Unknown',\n}\nadata.obs['cell_type'] = adata.obs['leiden'].map(cluster_to_celltype).astype('category')\n",[1536],{"type":70,"tag":117,"props":1537,"children":1538},{"__ignoreMap":752},[1539,1546,1553,1561,1569,1577,1585,1593,1601,1609,1617,1625,1633,1641,1649,1656,1664,1671,1679,1687,1695,1703,1710],{"type":70,"tag":758,"props":1540,"children":1541},{"class":760,"line":761},[1542],{"type":70,"tag":758,"props":1543,"children":1544},{},[1545],{"type":75,"value":767},{"type":70,"tag":758,"props":1547,"children":1548},{"class":760,"line":770},[1549],{"type":70,"tag":758,"props":1550,"children":1551},{"emptyLinePlaceholder":791},[1552],{"type":75,"value":794},{"type":70,"tag":758,"props":1554,"children":1555},{"class":760,"line":779},[1556],{"type":70,"tag":758,"props":1557,"children":1558},{},[1559],{"type":75,"value":1560},"marker_genes = {\n",{"type":70,"tag":758,"props":1562,"children":1563},{"class":760,"line":26},[1564],{"type":70,"tag":758,"props":1565,"children":1566},{},[1567],{"type":75,"value":1568},"    'T cells':      ['CD3D', 'CD3E', 'CD2'],\n",{"type":70,"tag":758,"props":1570,"children":1571},{"class":760,"line":797},[1572],{"type":70,"tag":758,"props":1573,"children":1574},{},[1575],{"type":75,"value":1576},"    'CD4 T':        ['CD4', 'IL7R'],\n",{"type":70,"tag":758,"props":1578,"children":1579},{"class":760,"line":806},[1580],{"type":70,"tag":758,"props":1581,"children":1582},{},[1583],{"type":75,"value":1584},"    'CD8 T':        ['CD8A', 'CD8B'],\n",{"type":70,"tag":758,"props":1586,"children":1587},{"class":760,"line":815},[1588],{"type":70,"tag":758,"props":1589,"children":1590},{},[1591],{"type":75,"value":1592},"    'B cells':      ['CD79A', 'MS4A1', 'CD19'],\n",{"type":70,"tag":758,"props":1594,"children":1595},{"class":760,"line":824},[1596],{"type":70,"tag":758,"props":1597,"children":1598},{},[1599],{"type":75,"value":1600},"    'NK cells':     ['NKG7', 'GNLY', 'KLRD1'],\n",{"type":70,"tag":758,"props":1602,"children":1603},{"class":760,"line":832},[1604],{"type":70,"tag":758,"props":1605,"children":1606},{},[1607],{"type":75,"value":1608},"    'Monocytes':    ['CD14', 'LYZ', 'S100A8'],\n",{"type":70,"tag":758,"props":1610,"children":1611},{"class":760,"line":841},[1612],{"type":70,"tag":758,"props":1613,"children":1614},{},[1615],{"type":75,"value":1616},"    'Dendritic':    ['FCER1A', 'CST3', 'CLEC10A'],\n",{"type":70,"tag":758,"props":1618,"children":1619},{"class":760,"line":850},[1620],{"type":70,"tag":758,"props":1621,"children":1622},{},[1623],{"type":75,"value":1624},"    'Fibroblasts':  ['COL1A1', 'DCN', 'COL3A1'],\n",{"type":70,"tag":758,"props":1626,"children":1627},{"class":760,"line":859},[1628],{"type":70,"tag":758,"props":1629,"children":1630},{},[1631],{"type":75,"value":1632},"    'Endothelial':  ['PECAM1', 'VWF', 'CDH5'],\n",{"type":70,"tag":758,"props":1634,"children":1635},{"class":760,"line":867},[1636],{"type":70,"tag":758,"props":1637,"children":1638},{},[1639],{"type":75,"value":1640},"    'Epithelial':   ['EPCAM', 'KRT18', 'KRT19'],\n",{"type":70,"tag":758,"props":1642,"children":1643},{"class":760,"line":876},[1644],{"type":70,"tag":758,"props":1645,"children":1646},{},[1647],{"type":75,"value":1648},"}\n",{"type":70,"tag":758,"props":1650,"children":1651},{"class":760,"line":885},[1652],{"type":70,"tag":758,"props":1653,"children":1654},{"emptyLinePlaceholder":791},[1655],{"type":75,"value":794},{"type":70,"tag":758,"props":1657,"children":1658},{"class":760,"line":893},[1659],{"type":70,"tag":758,"props":1660,"children":1661},{},[1662],{"type":75,"value":1663},"sc.pl.dotplot(adata, marker_genes, groupby='leiden', standard_scale='var')\n",{"type":70,"tag":758,"props":1665,"children":1666},{"class":760,"line":902},[1667],{"type":70,"tag":758,"props":1668,"children":1669},{"emptyLinePlaceholder":791},[1670],{"type":75,"value":794},{"type":70,"tag":758,"props":1672,"children":1673},{"class":760,"line":911},[1674],{"type":70,"tag":758,"props":1675,"children":1676},{},[1677],{"type":75,"value":1678},"# Assign after reviewing the dotplot\n",{"type":70,"tag":758,"props":1680,"children":1681},{"class":760,"line":920},[1682],{"type":70,"tag":758,"props":1683,"children":1684},{},[1685],{"type":75,"value":1686},"cluster_to_celltype = {\n",{"type":70,"tag":758,"props":1688,"children":1689},{"class":760,"line":929},[1690],{"type":70,"tag":758,"props":1691,"children":1692},{},[1693],{"type":75,"value":1694},"    '0': 'T cells', '1': 'Monocytes', '2': 'B cells',\n",{"type":70,"tag":758,"props":1696,"children":1697},{"class":760,"line":938},[1698],{"type":70,"tag":758,"props":1699,"children":1700},{},[1701],{"type":75,"value":1702},"    '3': 'NK cells', '4': 'Unknown',\n",{"type":70,"tag":758,"props":1704,"children":1705},{"class":760,"line":947},[1706],{"type":70,"tag":758,"props":1707,"children":1708},{},[1709],{"type":75,"value":1648},{"type":70,"tag":758,"props":1711,"children":1712},{"class":760,"line":956},[1713],{"type":70,"tag":758,"props":1714,"children":1715},{},[1716],{"type":75,"value":1717},"adata.obs['cell_type'] = adata.obs['leiden'].map(cluster_to_celltype).astype('category')\n",{"type":70,"tag":181,"props":1719,"children":1721},{"id":1720},"_4-label-transfer-from-a-reference-atlas",[1722],{"type":75,"value":1723},"4. Label transfer from a reference atlas",{"type":70,"tag":747,"props":1725,"children":1727},{"className":749,"code":1726,"language":751,"meta":752,"style":752},"# Quick path: sc.tl.ingest (PCA\u002FUMAP projection, kNN labels)\n# Only use when batch effects are minimal\nimport scanpy as sc\nsc.pp.pca(adata_ref)\nsc.pp.neighbors(adata_ref)\nsc.tl.umap(adata_ref)\nsc.tl.ingest(adata_query, adata_ref, obs='cell_type')\n\n# Robust path: scANVI (semi-supervised, handles batch)\nimport scvi\nscvi.model.SCVI.setup_anndata(adata_ref, batch_key='batch')\nscvi_model = scvi.model.SCVI(adata_ref)\nscvi_model.train()\n\nscvi.model.SCANVI.setup_anndata(\n    adata_ref, labels_key='cell_type', unlabeled_category='Unknown', batch_key='batch'\n)\nscanvi_model = scvi.model.SCANVI.from_scvi_model(scvi_model, unlabeled_category='Unknown')\nscanvi_model.train(max_epochs=20)\n\nscanvi_model = scvi.model.SCANVI.load_query_data(adata_query, scanvi_model)\nscanvi_model.train(max_epochs=100, plan_kwargs={'weight_decay': 0.0})\nadata_query.obs['cell_type_pred'] = scanvi_model.predict(adata_query)\n",[1728],{"type":70,"tag":117,"props":1729,"children":1730},{"__ignoreMap":752},[1731,1739,1747,1754,1762,1770,1778,1786,1793,1801,1809,1817,1825,1833,1840,1848,1856,1863,1871,1879,1886,1894,1902],{"type":70,"tag":758,"props":1732,"children":1733},{"class":760,"line":761},[1734],{"type":70,"tag":758,"props":1735,"children":1736},{},[1737],{"type":75,"value":1738},"# Quick path: sc.tl.ingest (PCA\u002FUMAP projection, kNN labels)\n",{"type":70,"tag":758,"props":1740,"children":1741},{"class":760,"line":770},[1742],{"type":70,"tag":758,"props":1743,"children":1744},{},[1745],{"type":75,"value":1746},"# Only use when batch effects are minimal\n",{"type":70,"tag":758,"props":1748,"children":1749},{"class":760,"line":779},[1750],{"type":70,"tag":758,"props":1751,"children":1752},{},[1753],{"type":75,"value":767},{"type":70,"tag":758,"props":1755,"children":1756},{"class":760,"line":26},[1757],{"type":70,"tag":758,"props":1758,"children":1759},{},[1760],{"type":75,"value":1761},"sc.pp.pca(adata_ref)\n",{"type":70,"tag":758,"props":1763,"children":1764},{"class":760,"line":797},[1765],{"type":70,"tag":758,"props":1766,"children":1767},{},[1768],{"type":75,"value":1769},"sc.pp.neighbors(adata_ref)\n",{"type":70,"tag":758,"props":1771,"children":1772},{"class":760,"line":806},[1773],{"type":70,"tag":758,"props":1774,"children":1775},{},[1776],{"type":75,"value":1777},"sc.tl.umap(adata_ref)\n",{"type":70,"tag":758,"props":1779,"children":1780},{"class":760,"line":815},[1781],{"type":70,"tag":758,"props":1782,"children":1783},{},[1784],{"type":75,"value":1785},"sc.tl.ingest(adata_query, adata_ref, obs='cell_type')\n",{"type":70,"tag":758,"props":1787,"children":1788},{"class":760,"line":824},[1789],{"type":70,"tag":758,"props":1790,"children":1791},{"emptyLinePlaceholder":791},[1792],{"type":75,"value":794},{"type":70,"tag":758,"props":1794,"children":1795},{"class":760,"line":832},[1796],{"type":70,"tag":758,"props":1797,"children":1798},{},[1799],{"type":75,"value":1800},"# Robust path: scANVI (semi-supervised, handles batch)\n",{"type":70,"tag":758,"props":1802,"children":1803},{"class":760,"line":841},[1804],{"type":70,"tag":758,"props":1805,"children":1806},{},[1807],{"type":75,"value":1808},"import scvi\n",{"type":70,"tag":758,"props":1810,"children":1811},{"class":760,"line":850},[1812],{"type":70,"tag":758,"props":1813,"children":1814},{},[1815],{"type":75,"value":1816},"scvi.model.SCVI.setup_anndata(adata_ref, batch_key='batch')\n",{"type":70,"tag":758,"props":1818,"children":1819},{"class":760,"line":859},[1820],{"type":70,"tag":758,"props":1821,"children":1822},{},[1823],{"type":75,"value":1824},"scvi_model = scvi.model.SCVI(adata_ref)\n",{"type":70,"tag":758,"props":1826,"children":1827},{"class":760,"line":867},[1828],{"type":70,"tag":758,"props":1829,"children":1830},{},[1831],{"type":75,"value":1832},"scvi_model.train()\n",{"type":70,"tag":758,"props":1834,"children":1835},{"class":760,"line":876},[1836],{"type":70,"tag":758,"props":1837,"children":1838},{"emptyLinePlaceholder":791},[1839],{"type":75,"value":794},{"type":70,"tag":758,"props":1841,"children":1842},{"class":760,"line":885},[1843],{"type":70,"tag":758,"props":1844,"children":1845},{},[1846],{"type":75,"value":1847},"scvi.model.SCANVI.setup_anndata(\n",{"type":70,"tag":758,"props":1849,"children":1850},{"class":760,"line":893},[1851],{"type":70,"tag":758,"props":1852,"children":1853},{},[1854],{"type":75,"value":1855},"    adata_ref, labels_key='cell_type', unlabeled_category='Unknown', batch_key='batch'\n",{"type":70,"tag":758,"props":1857,"children":1858},{"class":760,"line":902},[1859],{"type":70,"tag":758,"props":1860,"children":1861},{},[1862],{"type":75,"value":962},{"type":70,"tag":758,"props":1864,"children":1865},{"class":760,"line":911},[1866],{"type":70,"tag":758,"props":1867,"children":1868},{},[1869],{"type":75,"value":1870},"scanvi_model = scvi.model.SCANVI.from_scvi_model(scvi_model, unlabeled_category='Unknown')\n",{"type":70,"tag":758,"props":1872,"children":1873},{"class":760,"line":920},[1874],{"type":70,"tag":758,"props":1875,"children":1876},{},[1877],{"type":75,"value":1878},"scanvi_model.train(max_epochs=20)\n",{"type":70,"tag":758,"props":1880,"children":1881},{"class":760,"line":929},[1882],{"type":70,"tag":758,"props":1883,"children":1884},{"emptyLinePlaceholder":791},[1885],{"type":75,"value":794},{"type":70,"tag":758,"props":1887,"children":1888},{"class":760,"line":938},[1889],{"type":70,"tag":758,"props":1890,"children":1891},{},[1892],{"type":75,"value":1893},"scanvi_model = scvi.model.SCANVI.load_query_data(adata_query, scanvi_model)\n",{"type":70,"tag":758,"props":1895,"children":1896},{"class":760,"line":947},[1897],{"type":70,"tag":758,"props":1898,"children":1899},{},[1900],{"type":75,"value":1901},"scanvi_model.train(max_epochs=100, plan_kwargs={'weight_decay': 0.0})\n",{"type":70,"tag":758,"props":1903,"children":1904},{"class":760,"line":956},[1905],{"type":70,"tag":758,"props":1906,"children":1907},{},[1908],{"type":75,"value":1909},"adata_query.obs['cell_type_pred'] = scanvi_model.predict(adata_query)\n",{"type":70,"tag":181,"props":1911,"children":1913},{"id":1912},"_5-validation",[1914],{"type":75,"value":1915},"5. Validation",{"type":70,"tag":747,"props":1917,"children":1919},{"className":749,"code":1918,"language":751,"meta":752,"style":752},"# Confirm assigned labels express their markers\nsc.pl.dotplot(adata, marker_genes, groupby='cell_type', standard_scale='var')\nsc.pl.violin(adata, ['CD3D', 'MS4A1', 'CD14'], groupby='cell_type', rotation=90)\n\n# Sanity-check proportions per sample\nadata.obs.groupby(['sample', 'cell_type']).size().unstack(fill_value=0)\n",[1920],{"type":70,"tag":117,"props":1921,"children":1922},{"__ignoreMap":752},[1923,1931,1939,1947,1954,1962],{"type":70,"tag":758,"props":1924,"children":1925},{"class":760,"line":761},[1926],{"type":70,"tag":758,"props":1927,"children":1928},{},[1929],{"type":75,"value":1930},"# Confirm assigned labels express their markers\n",{"type":70,"tag":758,"props":1932,"children":1933},{"class":760,"line":770},[1934],{"type":70,"tag":758,"props":1935,"children":1936},{},[1937],{"type":75,"value":1938},"sc.pl.dotplot(adata, marker_genes, groupby='cell_type', standard_scale='var')\n",{"type":70,"tag":758,"props":1940,"children":1941},{"class":760,"line":779},[1942],{"type":70,"tag":758,"props":1943,"children":1944},{},[1945],{"type":75,"value":1946},"sc.pl.violin(adata, ['CD3D', 'MS4A1', 'CD14'], groupby='cell_type', rotation=90)\n",{"type":70,"tag":758,"props":1948,"children":1949},{"class":760,"line":26},[1950],{"type":70,"tag":758,"props":1951,"children":1952},{"emptyLinePlaceholder":791},[1953],{"type":75,"value":794},{"type":70,"tag":758,"props":1955,"children":1956},{"class":760,"line":797},[1957],{"type":70,"tag":758,"props":1958,"children":1959},{},[1960],{"type":75,"value":1961},"# Sanity-check proportions per sample\n",{"type":70,"tag":758,"props":1963,"children":1964},{"class":760,"line":806},[1965],{"type":70,"tag":758,"props":1966,"children":1967},{},[1968],{"type":75,"value":1969},"adata.obs.groupby(['sample', 'cell_type']).size().unstack(fill_value=0)\n",{"type":70,"tag":85,"props":1971,"children":1972},{},[1973,1975,1980],{"type":75,"value":1974},"Mark any cluster without clear marker support as ",{"type":70,"tag":117,"props":1976,"children":1978},{"className":1977},[],[1979],{"type":75,"value":488},{"type":75,"value":1981}," rather than forcing a label.",{"type":70,"tag":181,"props":1983,"children":1985},{"id":1984},"_6-hierarchical-annotation",[1986],{"type":75,"value":1987},"6. Hierarchical annotation",{"type":70,"tag":747,"props":1989,"children":1991},{"className":749,"code":1990,"language":751,"meta":752,"style":752},"# Step 1: coarse compartments\ncompartment_markers = {\n    'Immune':     ['PTPRC'],           # CD45\n    'Epithelial': ['EPCAM', 'KRT8'],\n    'Stromal':    ['COL1A1', 'PECAM1'],\n}\n# Step 2: subset and re-annotate each compartment\nadata_immune = adata[adata.obs['compartment'] == 'Immune'].copy()\nmodel = models.Model.load('Immune_All_Low.pkl')\npreds = celltypist.annotate(adata_immune, model=model, majority_voting=True)\nadata_immune_result = preds.to_adata()\nadata_immune.obs['cell_type_fine'] = adata_immune_result.obs['majority_voting']\n",[1992],{"type":70,"tag":117,"props":1993,"children":1994},{"__ignoreMap":752},[1995,2003,2011,2019,2027,2035,2042,2050,2058,2066,2074,2082],{"type":70,"tag":758,"props":1996,"children":1997},{"class":760,"line":761},[1998],{"type":70,"tag":758,"props":1999,"children":2000},{},[2001],{"type":75,"value":2002},"# Step 1: coarse compartments\n",{"type":70,"tag":758,"props":2004,"children":2005},{"class":760,"line":770},[2006],{"type":70,"tag":758,"props":2007,"children":2008},{},[2009],{"type":75,"value":2010},"compartment_markers = {\n",{"type":70,"tag":758,"props":2012,"children":2013},{"class":760,"line":779},[2014],{"type":70,"tag":758,"props":2015,"children":2016},{},[2017],{"type":75,"value":2018},"    'Immune':     ['PTPRC'],           # CD45\n",{"type":70,"tag":758,"props":2020,"children":2021},{"class":760,"line":26},[2022],{"type":70,"tag":758,"props":2023,"children":2024},{},[2025],{"type":75,"value":2026},"    'Epithelial': ['EPCAM', 'KRT8'],\n",{"type":70,"tag":758,"props":2028,"children":2029},{"class":760,"line":797},[2030],{"type":70,"tag":758,"props":2031,"children":2032},{},[2033],{"type":75,"value":2034},"    'Stromal':    ['COL1A1', 'PECAM1'],\n",{"type":70,"tag":758,"props":2036,"children":2037},{"class":760,"line":806},[2038],{"type":70,"tag":758,"props":2039,"children":2040},{},[2041],{"type":75,"value":1648},{"type":70,"tag":758,"props":2043,"children":2044},{"class":760,"line":815},[2045],{"type":70,"tag":758,"props":2046,"children":2047},{},[2048],{"type":75,"value":2049},"# Step 2: subset and re-annotate each compartment\n",{"type":70,"tag":758,"props":2051,"children":2052},{"class":760,"line":824},[2053],{"type":70,"tag":758,"props":2054,"children":2055},{},[2056],{"type":75,"value":2057},"adata_immune = adata[adata.obs['compartment'] == 'Immune'].copy()\n",{"type":70,"tag":758,"props":2059,"children":2060},{"class":760,"line":832},[2061],{"type":70,"tag":758,"props":2062,"children":2063},{},[2064],{"type":75,"value":2065},"model = models.Model.load('Immune_All_Low.pkl')\n",{"type":70,"tag":758,"props":2067,"children":2068},{"class":760,"line":841},[2069],{"type":70,"tag":758,"props":2070,"children":2071},{},[2072],{"type":75,"value":2073},"preds = celltypist.annotate(adata_immune, model=model, majority_voting=True)\n",{"type":70,"tag":758,"props":2075,"children":2076},{"class":760,"line":850},[2077],{"type":70,"tag":758,"props":2078,"children":2079},{},[2080],{"type":75,"value":2081},"adata_immune_result = preds.to_adata()\n",{"type":70,"tag":758,"props":2083,"children":2084},{"class":760,"line":859},[2085],{"type":70,"tag":758,"props":2086,"children":2087},{},[2088],{"type":75,"value":2089},"adata_immune.obs['cell_type_fine'] = adata_immune_result.obs['majority_voting']\n",{"type":70,"tag":78,"props":2091,"children":2093},{"id":2092},"quick-reference",[2094],{"type":75,"value":2095},"Quick Reference",{"type":70,"tag":1102,"props":2097,"children":2098},{},[2099,2120],{"type":70,"tag":1106,"props":2100,"children":2101},{},[2102],{"type":70,"tag":1110,"props":2103,"children":2104},{},[2105,2110,2115],{"type":70,"tag":1114,"props":2106,"children":2107},{},[2108],{"type":75,"value":2109},"Task",{"type":70,"tag":1114,"props":2111,"children":2112},{},[2113],{"type":75,"value":2114},"Tool",{"type":70,"tag":1114,"props":2116,"children":2117},{},[2118],{"type":75,"value":2119},"Key call",{"type":70,"tag":1130,"props":2121,"children":2122},{},[2123,2145,2166,2187,2209,2230,2251,2273,2295,2316,2337],{"type":70,"tag":1110,"props":2124,"children":2125},{},[2126,2131,2136],{"type":70,"tag":1137,"props":2127,"children":2128},{},[2129],{"type":75,"value":2130},"PBMC \u002F immune automated",{"type":70,"tag":1137,"props":2132,"children":2133},{},[2134],{"type":75,"value":2135},"CellTypist",{"type":70,"tag":1137,"props":2137,"children":2138},{},[2139],{"type":70,"tag":117,"props":2140,"children":2142},{"className":2141},[],[2143],{"type":75,"value":2144},"models.Model.load('Immune_All_Low.pkl')",{"type":70,"tag":1110,"props":2146,"children":2147},{},[2148,2153,2157],{"type":70,"tag":1137,"props":2149,"children":2150},{},[2151],{"type":75,"value":2152},"Lung atlas mapping",{"type":70,"tag":1137,"props":2154,"children":2155},{},[2156],{"type":75,"value":2135},{"type":70,"tag":1137,"props":2158,"children":2159},{},[2160],{"type":70,"tag":117,"props":2161,"children":2163},{"className":2162},[],[2164],{"type":75,"value":2165},"'Human_Lung_Atlas.pkl'",{"type":70,"tag":1110,"props":2167,"children":2168},{},[2169,2174,2178],{"type":70,"tag":1137,"props":2170,"children":2171},{},[2172],{"type":75,"value":2173},"Gut \u002F intestine",{"type":70,"tag":1137,"props":2175,"children":2176},{},[2177],{"type":75,"value":2135},{"type":70,"tag":1137,"props":2179,"children":2180},{},[2181],{"type":70,"tag":117,"props":2182,"children":2184},{"className":2183},[],[2185],{"type":75,"value":2186},"'Cells_Intestinal_Tract.pkl'",{"type":70,"tag":1110,"props":2188,"children":2189},{},[2190,2195,2200],{"type":70,"tag":1137,"props":2191,"children":2192},{},[2193],{"type":75,"value":2194},"Broad human ref (R)",{"type":70,"tag":1137,"props":2196,"children":2197},{},[2198],{"type":75,"value":2199},"SingleR",{"type":70,"tag":1137,"props":2201,"children":2202},{},[2203],{"type":70,"tag":117,"props":2204,"children":2206},{"className":2205},[],[2207],{"type":75,"value":2208},"celldex::HumanPrimaryCellAtlasData()",{"type":70,"tag":1110,"props":2210,"children":2211},{},[2212,2217,2221],{"type":70,"tag":1137,"props":2213,"children":2214},{},[2215],{"type":75,"value":2216},"Sorted immune ref (R)",{"type":70,"tag":1137,"props":2218,"children":2219},{},[2220],{"type":75,"value":2199},{"type":70,"tag":1137,"props":2222,"children":2223},{},[2224],{"type":70,"tag":117,"props":2225,"children":2227},{"className":2226},[],[2228],{"type":75,"value":2229},"celldex::MonacoImmuneData()",{"type":70,"tag":1110,"props":2231,"children":2232},{},[2233,2238,2242],{"type":70,"tag":1137,"props":2234,"children":2235},{},[2236],{"type":75,"value":2237},"Mouse immune (R)",{"type":70,"tag":1137,"props":2239,"children":2240},{},[2241],{"type":75,"value":2199},{"type":70,"tag":1137,"props":2243,"children":2244},{},[2245],{"type":70,"tag":117,"props":2246,"children":2248},{"className":2247},[],[2249],{"type":75,"value":2250},"celldex::ImmGenData()",{"type":70,"tag":1110,"props":2252,"children":2253},{},[2254,2259,2264],{"type":70,"tag":1137,"props":2255,"children":2256},{},[2257],{"type":75,"value":2258},"Query→reference transfer",{"type":70,"tag":1137,"props":2260,"children":2261},{},[2262],{"type":75,"value":2263},"scanpy",{"type":70,"tag":1137,"props":2265,"children":2266},{},[2267],{"type":70,"tag":117,"props":2268,"children":2270},{"className":2269},[],[2271],{"type":75,"value":2272},"sc.tl.ingest(adata_q, adata_ref, obs='cell_type')",{"type":70,"tag":1110,"props":2274,"children":2275},{},[2276,2281,2286],{"type":70,"tag":1137,"props":2277,"children":2278},{},[2279],{"type":75,"value":2280},"Batch-aware transfer",{"type":70,"tag":1137,"props":2282,"children":2283},{},[2284],{"type":75,"value":2285},"scvi-tools",{"type":70,"tag":1137,"props":2287,"children":2288},{},[2289],{"type":70,"tag":117,"props":2290,"children":2292},{"className":2291},[],[2293],{"type":75,"value":2294},"SCANVI.load_query_data(...)",{"type":70,"tag":1110,"props":2296,"children":2297},{},[2298,2303,2307],{"type":70,"tag":1137,"props":2299,"children":2300},{},[2301],{"type":75,"value":2302},"Marker review",{"type":70,"tag":1137,"props":2304,"children":2305},{},[2306],{"type":75,"value":2263},{"type":70,"tag":1137,"props":2308,"children":2309},{},[2310],{"type":70,"tag":117,"props":2311,"children":2313},{"className":2312},[],[2314],{"type":75,"value":2315},"sc.pl.dotplot(adata, markers, groupby='leiden')",{"type":70,"tag":1110,"props":2317,"children":2318},{},[2319,2324,2328],{"type":70,"tag":1137,"props":2320,"children":2321},{},[2322],{"type":75,"value":2323},"Confidence (CellTypist)",{"type":70,"tag":1137,"props":2325,"children":2326},{},[2327],{"type":75,"value":2135},{"type":70,"tag":1137,"props":2329,"children":2330},{},[2331],{"type":70,"tag":117,"props":2332,"children":2334},{"className":2333},[],[2335],{"type":75,"value":2336},"predictions.to_adata().obs['conf_score']",{"type":70,"tag":1110,"props":2338,"children":2339},{},[2340,2345,2349],{"type":70,"tag":1137,"props":2341,"children":2342},{},[2343],{"type":75,"value":2344},"Confidence (SingleR)",{"type":70,"tag":1137,"props":2346,"children":2347},{},[2348],{"type":75,"value":2199},{"type":70,"tag":1137,"props":2350,"children":2351},{},[2352,2358],{"type":70,"tag":117,"props":2353,"children":2355},{"className":2354},[],[2356],{"type":75,"value":2357},"is.na(pred$pruned.labels)",{"type":75,"value":2359}," flags low-quality",{"type":70,"tag":85,"props":2361,"children":2362},{},[2363],{"type":75,"value":2364},"Required inputs:",{"type":70,"tag":204,"props":2366,"children":2367},{},[2368,2387,2407],{"type":70,"tag":95,"props":2369,"children":2370},{},[2371,2373,2379,2381,2386],{"type":75,"value":2372},"CellTypist: ",{"type":70,"tag":117,"props":2374,"children":2376},{"className":2375},[],[2377],{"type":75,"value":2378},"adata.X",{"type":75,"value":2380}," = log1p(CP10k) normalized, genes as HGNC symbols in ",{"type":70,"tag":117,"props":2382,"children":2384},{"className":2383},[],[2385],{"type":75,"value":363},{"type":75,"value":173},{"type":70,"tag":95,"props":2388,"children":2389},{},[2390,2392,2397,2399,2405],{"type":75,"value":2391},"SingleR: ",{"type":70,"tag":117,"props":2393,"children":2395},{"className":2394},[],[2396],{"type":75,"value":163},{"type":75,"value":2398}," with a ",{"type":70,"tag":117,"props":2400,"children":2402},{"className":2401},[],[2403],{"type":75,"value":2404},"logcounts",{"type":75,"value":2406}," assay.",{"type":70,"tag":95,"props":2408,"children":2409},{},[2410,2412,2418,2419,2425,2426,2432],{"type":75,"value":2411},"scANVI: raw counts in ",{"type":70,"tag":117,"props":2413,"children":2415},{"className":2414},[],[2416],{"type":75,"value":2417},"adata.layers['counts']",{"type":75,"value":1265},{"type":70,"tag":117,"props":2420,"children":2422},{"className":2421},[],[2423],{"type":75,"value":2424},"batch_key",{"type":75,"value":1265},{"type":70,"tag":117,"props":2427,"children":2429},{"className":2428},[],[2430],{"type":75,"value":2431},"labels_key",{"type":75,"value":2433}," on reference.",{"type":70,"tag":181,"props":2435,"children":2437},{"id":2436},"numeric-thresholds",[2438],{"type":75,"value":2439},"Numeric Thresholds",{"type":70,"tag":1102,"props":2441,"children":2442},{},[2443,2464],{"type":70,"tag":1106,"props":2444,"children":2445},{},[2446],{"type":70,"tag":1110,"props":2447,"children":2448},{},[2449,2454,2459],{"type":70,"tag":1114,"props":2450,"children":2451},{},[2452],{"type":75,"value":2453},"Metric",{"type":70,"tag":1114,"props":2455,"children":2456},{},[2457],{"type":75,"value":2458},"Threshold",{"type":70,"tag":1114,"props":2460,"children":2461},{},[2462],{"type":75,"value":2463},"Action",{"type":70,"tag":1130,"props":2465,"children":2466},{},[2467,2496,2518,2540,2566,2584,2602],{"type":70,"tag":1110,"props":2468,"children":2469},{},[2470,2481,2486],{"type":70,"tag":1137,"props":2471,"children":2472},{},[2473,2475],{"type":75,"value":2474},"CellTypist ",{"type":70,"tag":117,"props":2476,"children":2478},{"className":2477},[],[2479],{"type":75,"value":2480},"conf_score",{"type":70,"tag":1137,"props":2482,"children":2483},{},[2484],{"type":75,"value":2485},"\u003C 0.5",{"type":70,"tag":1137,"props":2487,"children":2488},{},[2489,2491],{"type":75,"value":2490},"Label as ",{"type":70,"tag":117,"props":2492,"children":2494},{"className":2493},[],[2495],{"type":75,"value":488},{"type":70,"tag":1110,"props":2497,"children":2498},{},[2499,2508,2513],{"type":70,"tag":1137,"props":2500,"children":2501},{},[2502,2503],{"type":75,"value":2474},{"type":70,"tag":117,"props":2504,"children":2506},{"className":2505},[],[2507],{"type":75,"value":2480},{"type":70,"tag":1137,"props":2509,"children":2510},{},[2511],{"type":75,"value":2512},"\u003C 0.7",{"type":70,"tag":1137,"props":2514,"children":2515},{},[2516],{"type":75,"value":2517},"Flag for manual review",{"type":70,"tag":1110,"props":2519,"children":2520},{},[2521,2530,2535],{"type":70,"tag":1137,"props":2522,"children":2523},{},[2524,2525],{"type":75,"value":2474},{"type":70,"tag":117,"props":2526,"children":2528},{"className":2527},[],[2529],{"type":75,"value":422},{"type":70,"tag":1137,"props":2531,"children":2532},{},[2533],{"type":75,"value":2534},"0.5 (default)",{"type":70,"tag":1137,"props":2536,"children":2537},{},[2538],{"type":75,"value":2539},"Raise to 0.7 for stringent annotation",{"type":70,"tag":1110,"props":2541,"children":2542},{},[2543,2548,2553],{"type":70,"tag":1137,"props":2544,"children":2545},{},[2546],{"type":75,"value":2547},"SingleR delta score",{"type":70,"tag":1137,"props":2549,"children":2550},{},[2551],{"type":75,"value":2552},"\u003C median - 3×MAD",{"type":70,"tag":1137,"props":2554,"children":2555},{},[2556,2558,2564],{"type":75,"value":2557},"Pruned (set to ",{"type":70,"tag":117,"props":2559,"children":2561},{"className":2560},[],[2562],{"type":75,"value":2563},"NA",{"type":75,"value":2565},")",{"type":70,"tag":1110,"props":2567,"children":2568},{},[2569,2574,2579],{"type":70,"tag":1137,"props":2570,"children":2571},{},[2572],{"type":75,"value":2573},"Cluster size",{"type":70,"tag":1137,"props":2575,"children":2576},{},[2577],{"type":75,"value":2578},"\u003C 20 cells",{"type":70,"tag":1137,"props":2580,"children":2581},{},[2582],{"type":75,"value":2583},"Do not assign rare subtypes; use parent label",{"type":70,"tag":1110,"props":2585,"children":2586},{},[2587,2592,2597],{"type":70,"tag":1137,"props":2588,"children":2589},{},[2590],{"type":75,"value":2591},"Marker dotplot fraction",{"type":70,"tag":1137,"props":2593,"children":2594},{},[2595],{"type":75,"value":2596},"\u003C 0.3",{"type":70,"tag":1137,"props":2598,"children":2599},{},[2600],{"type":75,"value":2601},"Marker not reliably expressed; do not use for assignment",{"type":70,"tag":1110,"props":2603,"children":2604},{},[2605,2610,2615],{"type":70,"tag":1137,"props":2606,"children":2607},{},[2608],{"type":75,"value":2609},"Expected proportion deviation",{"type":70,"tag":1137,"props":2611,"children":2612},{},[2613],{"type":75,"value":2614},"> 3× literature range",{"type":70,"tag":1137,"props":2616,"children":2617},{},[2618],{"type":75,"value":2619},"Suspect wrong model or normalization error",{"type":70,"tag":78,"props":2621,"children":2623},{"id":2622},"common-mistakes",[2624],{"type":75,"value":2625},"Common Mistakes",{"type":70,"tag":91,"props":2627,"children":2628},{},[2629,2669,2721,2764,2798,2826,2854,2890,2933,2954],{"type":70,"tag":95,"props":2630,"children":2631},{},[2632,2637,2639,2644,2646,2652,2654,2660,2662,2667],{"type":70,"tag":99,"props":2633,"children":2634},{},[2635],{"type":75,"value":2636},"Wrong:",{"type":75,"value":2638}," Feeding raw counts to CellTypist\n",{"type":70,"tag":99,"props":2640,"children":2641},{},[2642],{"type":75,"value":2643},"Right:",{"type":75,"value":2645}," Always run ",{"type":70,"tag":117,"props":2647,"children":2649},{"className":2648},[],[2650],{"type":75,"value":2651},"sc.pp.normalize_total(adata, target_sum=1e4)",{"type":75,"value":2653}," + ",{"type":70,"tag":117,"props":2655,"children":2657},{"className":2656},[],[2658],{"type":75,"value":2659},"sc.pp.log1p(adata)",{"type":75,"value":2661}," before annotation\n",{"type":70,"tag":99,"props":2663,"children":2664},{},[2665],{"type":75,"value":2666},"Why:",{"type":75,"value":2668}," CellTypist expects log1p of counts normalized to 10,000\u002Fcell — raw or SCTransform'd data produces nonsense labels",{"type":70,"tag":95,"props":2670,"children":2671},{},[2672,2676,2678,2682,2684,2690,2692,2698,2700,2704,2706,2711,2713,2719],{"type":70,"tag":99,"props":2673,"children":2674},{},[2675],{"type":75,"value":2636},{"type":75,"value":2677}," Using a reference model that doesn't match the tissue or species\n",{"type":70,"tag":99,"props":2679,"children":2680},{},[2681],{"type":75,"value":2643},{"type":75,"value":2683}," Match species (",{"type":70,"tag":117,"props":2685,"children":2687},{"className":2686},[],[2688],{"type":75,"value":2689},"Human_*",{"type":75,"value":2691}," vs ",{"type":70,"tag":117,"props":2693,"children":2695},{"className":2694},[],[2696],{"type":75,"value":2697},"Mouse_*",{"type":75,"value":2699},") and tissue type when selecting CellTypist models or SingleR references\n",{"type":70,"tag":99,"props":2701,"children":2702},{},[2703],{"type":75,"value":2666},{"type":75,"value":2705}," Using ",{"type":70,"tag":117,"props":2707,"children":2709},{"className":2708},[],[2710],{"type":75,"value":1263},{"type":75,"value":2712}," on epithelial tumor cells or ",{"type":70,"tag":117,"props":2714,"children":2716},{"className":2715},[],[2717],{"type":75,"value":2718},"HumanPrimaryCellAtlasData",{"type":75,"value":2720}," on mouse data produces confident but wrong labels",{"type":70,"tag":95,"props":2722,"children":2723},{},[2724,2728,2730,2734,2736,2741,2743,2747,2749,2755,2756,2762],{"type":70,"tag":99,"props":2725,"children":2726},{},[2727],{"type":75,"value":2636},{"type":75,"value":2729}," Passing Ensembl IDs or mixed-case gene symbols to CellTypist\u002FSingleR\n",{"type":70,"tag":99,"props":2731,"children":2732},{},[2733],{"type":75,"value":2643},{"type":75,"value":2735}," Convert ",{"type":70,"tag":117,"props":2737,"children":2739},{"className":2738},[],[2740],{"type":75,"value":363},{"type":75,"value":2742}," to HGNC (human) or MGI (mouse) symbols before annotation\n",{"type":70,"tag":99,"props":2744,"children":2745},{},[2746],{"type":75,"value":2666},{"type":75,"value":2748}," Ensembl IDs or wrong case (",{"type":70,"tag":117,"props":2750,"children":2752},{"className":2751},[],[2753],{"type":75,"value":2754},"Cd3d",{"type":75,"value":2691},{"type":70,"tag":117,"props":2757,"children":2759},{"className":2758},[],[2760],{"type":75,"value":2761},"CD3D",{"type":75,"value":2763},") silently drop features, degrading model performance without warning",{"type":70,"tag":95,"props":2765,"children":2766},{},[2767,2771,2772,2778,2780,2784,2785,2790,2792,2796],{"type":70,"tag":99,"props":2768,"children":2769},{},[2770],{"type":75,"value":2636},{"type":75,"value":2705},{"type":70,"tag":117,"props":2773,"children":2775},{"className":2774},[],[2776],{"type":75,"value":2777},"predictions.probability_matrix.max(axis=1)",{"type":75,"value":2779}," to get confidence scores\n",{"type":70,"tag":99,"props":2781,"children":2782},{},[2783],{"type":75,"value":2643},{"type":75,"value":400},{"type":70,"tag":117,"props":2786,"children":2788},{"className":2787},[],[2789],{"type":75,"value":2336},{"type":75,"value":2791}," which is the stable API since CellTypist ≥1.3\n",{"type":70,"tag":99,"props":2793,"children":2794},{},[2795],{"type":75,"value":2666},{"type":75,"value":2797}," The probability matrix approach is fragile and version-dependent — it may break or return incorrect values across updates",{"type":70,"tag":95,"props":2799,"children":2800},{},[2801,2805,2807,2811,2813,2818,2820,2824],{"type":70,"tag":99,"props":2802,"children":2803},{},[2804],{"type":75,"value":2636},{"type":75,"value":2806}," Assigning a rare subtype label to a cluster of fewer than 20 cells\n",{"type":70,"tag":99,"props":2808,"children":2809},{},[2810],{"type":75,"value":2643},{"type":75,"value":2812}," Collapse to the parent cell type or label as ",{"type":70,"tag":117,"props":2814,"children":2816},{"className":2815},[],[2817],{"type":75,"value":488},{"type":75,"value":2819}," when cluster size is below 20 cells\n",{"type":70,"tag":99,"props":2821,"children":2822},{},[2823],{"type":75,"value":2666},{"type":75,"value":2825}," Rare subtype assignments on tiny clusters lack statistical power and are unreliable without strong distinguishing markers",{"type":70,"tag":95,"props":2827,"children":2828},{},[2829,2833,2835,2839,2841,2846,2848,2852],{"type":70,"tag":99,"props":2830,"children":2831},{},[2832],{"type":75,"value":2636},{"type":75,"value":2834}," Forcing a label on clusters that lack clear markers after dotplot review\n",{"type":70,"tag":99,"props":2836,"children":2837},{},[2838],{"type":75,"value":2643},{"type":75,"value":2840}," Keep ambiguous clusters as ",{"type":70,"tag":117,"props":2842,"children":2844},{"className":2843},[],[2845],{"type":75,"value":488},{"type":75,"value":2847}," rather than picking the next-best guess\n",{"type":70,"tag":99,"props":2849,"children":2850},{},[2851],{"type":75,"value":2666},{"type":75,"value":2853}," Forced labels propagate errors into downstream analyses (DE, trajectory) and create false biological narratives",{"type":70,"tag":95,"props":2855,"children":2856},{},[2857,2861,2863,2869,2871,2875,2877,2882,2884,2888],{"type":70,"tag":99,"props":2858,"children":2859},{},[2860],{"type":75,"value":2636},{"type":75,"value":2862}," Running CellTypist with ",{"type":70,"tag":117,"props":2864,"children":2866},{"className":2865},[],[2867],{"type":75,"value":2868},"majority_voting=False",{"type":75,"value":2870}," and using per-cell labels directly\n",{"type":70,"tag":99,"props":2872,"children":2873},{},[2874],{"type":75,"value":2643},{"type":75,"value":2876}," Always enable ",{"type":70,"tag":117,"props":2878,"children":2880},{"className":2879},[],[2881],{"type":75,"value":414},{"type":75,"value":2883}," to smooth labels over the local neighborhood graph\n",{"type":70,"tag":99,"props":2885,"children":2886},{},[2887],{"type":75,"value":2666},{"type":75,"value":2889}," Per-cell predictions are noisy; majority voting leverages cluster structure to produce coherent, stable annotations",{"type":70,"tag":95,"props":2891,"children":2892},{},[2893,2897,2899,2904,2906,2910,2912,2917,2919,2923,2925,2931],{"type":70,"tag":99,"props":2894,"children":2895},{},[2896],{"type":75,"value":2636},{"type":75,"value":2898}," Running ",{"type":70,"tag":117,"props":2900,"children":2902},{"className":2901},[],[2903],{"type":75,"value":122},{"type":75,"value":2905}," for label transfer without batch correction\n",{"type":70,"tag":99,"props":2907,"children":2908},{},[2909],{"type":75,"value":2643},{"type":75,"value":2911}," Integrate query and reference first, or use scANVI's ",{"type":70,"tag":117,"props":2913,"children":2915},{"className":2914},[],[2916],{"type":75,"value":620},{"type":75,"value":2918}," path which handles batch natively\n",{"type":70,"tag":99,"props":2920,"children":2921},{},[2922],{"type":75,"value":2666},{"type":75,"value":2924}," ",{"type":70,"tag":117,"props":2926,"children":2928},{"className":2927},[],[2929],{"type":75,"value":2930},"ingest",{"type":75,"value":2932}," assumes query and reference share the same embedding — batch effects cause misalignment and wrong label transfers",{"type":70,"tag":95,"props":2934,"children":2935},{},[2936,2940,2942,2946,2948,2952],{"type":70,"tag":99,"props":2937,"children":2938},{},[2939],{"type":75,"value":2636},{"type":75,"value":2941}," Not validating cell-type proportions against biological expectations\n",{"type":70,"tag":99,"props":2943,"children":2944},{},[2945],{"type":75,"value":2643},{"type":75,"value":2947}," Always cross-check per-sample cell-type proportions against known tissue composition\n",{"type":70,"tag":99,"props":2949,"children":2950},{},[2951],{"type":75,"value":2666},{"type":75,"value":2953}," A PBMC sample with 80% fibroblasts is a red flag indicating wrong model, normalization error, or data quality issues",{"type":70,"tag":95,"props":2955,"children":2956},{},[2957,2961,2963,2967,2969,2973],{"type":70,"tag":99,"props":2958,"children":2959},{},[2960],{"type":75,"value":2636},{"type":75,"value":2962}," Annotating at one resolution only without hierarchical refinement\n",{"type":70,"tag":99,"props":2964,"children":2965},{},[2966],{"type":75,"value":2643},{"type":75,"value":2968}," Annotate coarse compartments first (immune\u002Fstromal\u002Fepithelial), then refine each with specialized models or markers\n",{"type":70,"tag":99,"props":2970,"children":2971},{},[2972],{"type":75,"value":2666},{"type":75,"value":2974}," Fine labels on poorly separated clusters are unstable — hierarchical annotation produces more reliable results",{"type":70,"tag":78,"props":2976,"children":2978},{"id":2977},"references",[2979],{"type":75,"value":2980},"References",{"type":70,"tag":204,"props":2982,"children":2983},{},[2984,2997,3008,3019],{"type":70,"tag":95,"props":2985,"children":2986},{},[2987,2989],{"type":75,"value":2988},"CellTypist: Dominguez Conde et al. Science 2022, ",{"type":70,"tag":2990,"props":2991,"children":2995},"a",{"href":2992,"rel":2993},"https:\u002F\u002Fdoi.org\u002F10.1126\u002Fscience.abl5197",[2994],"nofollow",[2996],{"type":75,"value":2992},{"type":70,"tag":95,"props":2998,"children":2999},{},[3000,3002],{"type":75,"value":3001},"SingleR: Aran et al. Nat Immunol 2019, ",{"type":70,"tag":2990,"props":3003,"children":3006},{"href":3004,"rel":3005},"https:\u002F\u002Fdoi.org\u002F10.1038\u002Fs41590-018-0276-y",[2994],[3007],{"type":75,"value":3004},{"type":70,"tag":95,"props":3009,"children":3010},{},[3011,3013],{"type":75,"value":3012},"scANVI: Xu et al. Mol Syst Biol 2021, ",{"type":70,"tag":2990,"props":3014,"children":3017},{"href":3015,"rel":3016},"https:\u002F\u002Fdoi.org\u002F10.15252\u002Fmsb.20209620",[2994],[3018],{"type":75,"value":3015},{"type":70,"tag":95,"props":3020,"children":3021},{},[3022,3024],{"type":75,"value":3023},"celldex: Aran et al. 2019, ",{"type":70,"tag":2990,"props":3025,"children":3028},{"href":3026,"rel":3027},"https:\u002F\u002Fbioconductor.org\u002Fpackages\u002Fcelldex",[2994],[3029],{"type":75,"value":3026},{"type":70,"tag":3031,"props":3032,"children":3033},"style",{},[3034],{"type":75,"value":3035},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":3037,"total":3215},[3038,3059,3080,3090,3103,3116,3126,3136,3157,3172,3187,3202],{"slug":3039,"name":3039,"fn":3040,"description":3041,"org":3042,"tags":3043,"stars":3056,"repoUrl":3057,"updatedAt":3058},"agentcore-investigation","investigate Bedrock AgentCore runtime sessions","Investigate Bedrock AgentCore runtime sessions via CloudWatch Logs Insights — resolve session\u002Ftrace IDs, query OTEL spans, filter noise, build timelines. Use when debugging AgentCore agent sessions, tracing tool calls, or analyzing latency.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3044,3047,3050,3053],{"name":3045,"slug":3046,"type":16},"AWS","aws",{"name":3048,"slug":3049,"type":16},"Debugging","debugging",{"name":3051,"slug":3052,"type":16},"Logs","logs",{"name":3054,"slug":3055,"type":16},"Observability","observability",9427,"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fmcp","2026-07-12T08:37:22.601527",{"slug":3060,"name":3061,"fn":3062,"description":3063,"org":3064,"tags":3065,"stars":3056,"repoUrl":3057,"updatedAt":3079},"amazon-aurora-dsql","amazon aurora dsql","build applications with Aurora DSQL","Build with Aurora DSQL — manage schemas, execute queries, handle migrations, diagnose query plans, load data, and develop applications with a serverless, distributed SQL database. Covers IAM auth, multi-tenant patterns, MySQL-to-DSQL and PostgreSQL-to-DSQL schema conversion, FK replacement code generation, OCC retry patterns, ORM migration (Django\u002FHibernate\u002FRails), DDL operations, query plan explainability, SQL compatibility validation, and bulk data loading. Triggers on phrases like: DSQL, Aurora DSQL, create DSQL table, DSQL schema, migrate to DSQL, distributed SQL database, serverless PostgreSQL-compatible database, DSQL query plan, DSQL EXPLAIN ANALYZE, why is my DSQL query slow, DSQL foreign key, DSQL OCC retry, DSQL multi-region, load into DSQL, load CSV into DSQL, bulk load DSQL, aurora-dsql-loader.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3066,3069,3070,3073,3076],{"name":3067,"slug":3068,"type":16},"Aurora","aurora",{"name":3045,"slug":3046,"type":16},{"name":3071,"slug":3072,"type":16},"Database","database",{"name":3074,"slug":3075,"type":16},"Serverless","serverless",{"name":3077,"slug":3078,"type":16},"SQL","sql","2026-07-12T08:36:45.053393",{"slug":3081,"name":3082,"fn":3062,"description":3063,"org":3083,"tags":3084,"stars":3056,"repoUrl":3057,"updatedAt":3089},"aurora-dsql","aurora dsql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3085,3086,3087,3088],{"name":3045,"slug":3046,"type":16},{"name":3071,"slug":3072,"type":16},{"name":3074,"slug":3075,"type":16},{"name":3077,"slug":3078,"type":16},"2026-07-12T08:36:42.694299",{"slug":3091,"name":3092,"fn":3062,"description":3063,"org":3093,"tags":3094,"stars":3056,"repoUrl":3057,"updatedAt":3102},"aws-dsql","aws dsql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3095,3096,3097,3100,3101],{"name":3045,"slug":3046,"type":16},{"name":3071,"slug":3072,"type":16},{"name":3098,"slug":3099,"type":16},"Migration","migration",{"name":3074,"slug":3075,"type":16},{"name":3077,"slug":3078,"type":16},"2026-07-12T08:36:38.584057",{"slug":3104,"name":3105,"fn":3062,"description":3063,"org":3106,"tags":3107,"stars":3056,"repoUrl":3057,"updatedAt":3115},"distributed-postgres","distributed postgres",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3108,3109,3110,3113,3114],{"name":3045,"slug":3046,"type":16},{"name":3071,"slug":3072,"type":16},{"name":3111,"slug":3112,"type":16},"PostgreSQL","postgresql",{"name":3074,"slug":3075,"type":16},{"name":3077,"slug":3078,"type":16},"2026-07-12T08:36:46.530743",{"slug":3117,"name":3118,"fn":3062,"description":3063,"org":3119,"tags":3120,"stars":3056,"repoUrl":3057,"updatedAt":3125},"distributed-sql","distributed sql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3121,3122,3123,3124],{"name":3045,"slug":3046,"type":16},{"name":3071,"slug":3072,"type":16},{"name":3074,"slug":3075,"type":16},{"name":3077,"slug":3078,"type":16},"2026-07-12T08:36:48.104182",{"slug":3127,"name":3127,"fn":3062,"description":3063,"org":3128,"tags":3129,"stars":3056,"repoUrl":3057,"updatedAt":3135},"dsql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3130,3131,3132,3133,3134],{"name":3045,"slug":3046,"type":16},{"name":3071,"slug":3072,"type":16},{"name":3098,"slug":3099,"type":16},{"name":3074,"slug":3075,"type":16},{"name":3077,"slug":3078,"type":16},"2026-07-12T08:36:36.374512",{"slug":3137,"name":3137,"fn":3138,"description":3139,"org":3140,"tags":3141,"stars":3154,"repoUrl":3155,"updatedAt":3156},"cost-efficiency-analyzer","analyze cost efficiency and expenses","Analyzes cost structure, cost efficiency, and expense management from P&L data. Use when the user asks about costs, expenses, COGS, operating expenses, cost ratios, cost control, spending efficiency, margin compression from cost side, or wants to understand where money is going. Also use for \"are we spending too much\", \"cost breakdown\", \"expense analysis\", or \"how efficient are our operations\". NOT for revenue or top-line analysis.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3142,3145,3148,3151],{"name":3143,"slug":3144,"type":16},"Accounting","accounting",{"name":3146,"slug":3147,"type":16},"Analytics","analytics",{"name":3149,"slug":3150,"type":16},"Cost Optimization","cost-optimization",{"name":3152,"slug":3153,"type":16},"Finance","finance",3176,"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fagentcore-samples","2026-07-12T08:40:03.29555",{"slug":3158,"name":3158,"fn":3159,"description":3160,"org":3161,"tags":3162,"stars":3154,"repoUrl":3155,"updatedAt":3171},"executive-financial-briefing","generate executive financial briefings","Generates a concise executive-level financial briefing or summary suitable for a CEO, CFO, or board presentation. Use when the user asks for a summary, briefing, executive summary, board update, financial overview, financial health check, or \"how is the business doing\". Covers the full P&L picture in one page. Also use for \"give me the highlights\", \"what do I need to know\", or \"quick financial update\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3163,3164,3165,3168],{"name":3045,"slug":3046,"type":16},{"name":3152,"slug":3153,"type":16},{"name":3166,"slug":3167,"type":16},"Management","management",{"name":3169,"slug":3170,"type":16},"Reporting","reporting","2026-07-12T08:40:02.066471",{"slug":3173,"name":3173,"fn":3174,"description":3175,"org":3176,"tags":3177,"stars":3154,"repoUrl":3155,"updatedAt":3186},"multi-quarter-trend-analysis","analyze multi-quarter financial trends","Analyzes financial trends across multiple quarters by comparing P&L metrics over time. Use when the user wants to see trends, patterns, trajectories, or directional movement across 3 or more quarters. Also use for \"how are we trending\", \"show me the trend\", \"track performance over time\", \"quarter over quarter comparison across all quarters\", or any multi-period longitudinal analysis.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3178,3179,3180,3183],{"name":3146,"slug":3147,"type":16},{"name":3152,"slug":3153,"type":16},{"name":3181,"slug":3182,"type":16},"Financial Statements","financial-statements",{"name":3184,"slug":3185,"type":16},"Variance Analysis","variance-analysis","2026-07-12T08:40:00.79141",{"slug":3188,"name":3188,"fn":3189,"description":3190,"org":3191,"tags":3192,"stars":3154,"repoUrl":3155,"updatedAt":3201},"pdf","process and manipulate PDF documents","Use this skill whenever the user wants to do anything with PDF files. This includes reading or extracting text\u002Ftables from PDFs, combining or merging multiple PDFs into one, splitting PDFs apart, rotating pages, adding watermarks, creating new PDFs, filling PDF forms, encrypting\u002Fdecrypting PDFs, extracting images, and OCR on scanned PDFs to make them searchable. If the user mentions a .pdf file or asks to produce one, use this skill.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3193,3196,3199],{"name":3194,"slug":3195,"type":16},"Automation","automation",{"name":3197,"slug":3198,"type":16},"Documents","documents",{"name":3200,"slug":3188,"type":16},"PDF","2026-07-12T08:41:44.135656",{"slug":3203,"name":3203,"fn":3204,"description":3205,"org":3206,"tags":3207,"stars":3154,"repoUrl":3155,"updatedAt":3214},"quarterly-kpi-calculator","calculate quarterly financial KPIs","Calculates quarterly financial KPIs from P&L data. P&L figures can be provided directly by the user or fetched from the financial data MCP server. Use when the user wants KPI calculations such as Gross Margin %, EBITDA Margin %, Operating Expense Ratio, or Revenue Growth % QoQ. Also use for quarterly performance review, P&L analysis, or interpreting financial ratios against benchmarks.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3208,3209,3210,3211],{"name":3143,"slug":3144,"type":16},{"name":14,"slug":15,"type":16},{"name":3152,"slug":3153,"type":16},{"name":3212,"slug":3213,"type":16},"KPI","kpi","2026-07-12T08:39:59.54971",150,{"items":3217,"total":3306},[3218,3236,3249,3263,3270,3283,3296],{"slug":3219,"name":3219,"fn":3220,"description":3221,"org":3222,"tags":3223,"stars":26,"repoUrl":27,"updatedAt":3235},"aws-genai-ml-architect","design AWS GenAI and ML architectures","Reasoning skill for designing AWS GenAI and ML architectures for healthcare and life sciences workloads. Use when the user asks to choose between SageMaker and Bedrock, design a RAG system over medical literature, architect clinical NLP or medical imaging inference, plan genomics or drug discovery pipelines on AWS, address HIPAA\u002FPHI compliance in ML systems, design MLOps for regulated clinical models, or optimize cost for HCLS ML workloads. Triggers include \"AWS architecture\", \"SageMaker vs Bedrock\", \"HIPAA ML\", \"clinical RAG\", \"medical imaging inference\", \"genomics on AWS\", \"PHI training\", \"MLOps healthcare\", \"Bedrock guardrails\", \"HealthLake\", \"HCLS cloud architecture\", \"BAA compliance\", \"SageMaker endpoint\", \"Bedrock knowledge base\", \"clinical NLP on AWS\", \"FDA SaMD on AWS\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3224,3227,3228,3231,3232],{"name":3225,"slug":3226,"type":16},"Architecture","architecture",{"name":3045,"slug":3046,"type":16},{"name":3229,"slug":3230,"type":16},"Healthcare","healthcare",{"name":18,"slug":19,"type":16},{"name":3233,"slug":3234,"type":16},"LLM","llm","2026-07-12T08:38:07.975937",{"slug":3237,"name":3237,"fn":3238,"description":3239,"org":3240,"tags":3241,"stars":26,"repoUrl":27,"updatedAt":3248},"biomarker-discovery","guide biomarker discovery and validation","Reason about biomarker discovery and validation in HCLS — classifying biomarker intent, choosing feature-selection and cross-validation strategies, avoiding leakage, and planning external replication. Use when the user asks to discover, develop, or validate a biomarker; select features from high-dimensional omics or clinical data; design a validation study; choose evaluation metrics; justify sample size; combine multi-omics signals; or assess clinical utility. Triggers include \"discover a biomarker\", \"validate biomarker\", \"prognostic vs predictive\", \"feature selection\", \"LASSO vs elastic net\", \"nested cross-validation\", \"data leakage\", \"C-index\", \"time-dependent AUC\", \"decision curve analysis\", \"external validation cohort\", \"events per variable\", \"optimism-corrected\", \"multi-omics integration\", \"clinical utility of a biomarker\", \"is this biomarker ready\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3242,3243,3244,3245],{"name":3045,"slug":3046,"type":16},{"name":21,"slug":22,"type":16},{"name":18,"slug":19,"type":16},{"name":3246,"slug":3247,"type":16},"Research","research","2026-07-12T08:37:49.295301",{"slug":3250,"name":3250,"fn":3251,"description":3252,"org":3253,"tags":3254,"stars":26,"repoUrl":27,"updatedAt":3262},"cdisc-compliance","reason about CDISC SDTM and ADaM implementation","Reason about CDISC SDTM and ADaM implementation for regulatory submissions. Use when the user asks about SDTM domain mapping, ADaM dataset design, controlled terminology versioning, define.xml completeness, FDA or PMDA submission requirements, query prioritization by clinical impact, SUPPQUAL usage, or CDISC compliance review. Triggers include \"SDTM mapping\", \"ADaM dataset\", \"CDISC compliance\", \"controlled terminology\", \"define.xml\", \"FDA submission data\", \"PMDA submission\", \"SDTM domain\", \"ADSL\", \"ADAE\", \"ADLB\", \"BDS structure\", \"SUPPQUAL\", \"RELREC\", \"value-level metadata\", \"CDISC CT\", \"regulatory submission data standards\", \"eCTD datasets\", \"SDTM 3.3\", \"ADaM 1.1\", \"query prioritization\", \"clinical data review\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3255,3258,3259],{"name":3256,"slug":3257,"type":16},"Clinical Trials","clinical-trials",{"name":18,"slug":19,"type":16},{"name":3260,"slug":3261,"type":16},"Regulatory Compliance","regulatory-compliance","2026-07-12T08:37:33.35594",{"slug":4,"name":4,"fn":5,"description":6,"org":3264,"tags":3265,"stars":26,"repoUrl":27,"updatedAt":28},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3266,3267,3268,3269],{"name":21,"slug":22,"type":16},{"name":14,"slug":15,"type":16},{"name":18,"slug":19,"type":16},{"name":24,"slug":25,"type":16},{"slug":3271,"name":3271,"fn":3272,"description":3273,"org":3274,"tags":3275,"stars":26,"repoUrl":27,"updatedAt":3282},"cheminformatics","calculate molecular properties with RDKit","Cheminformatics pipeline for small-molecule property calculation, filtering, and similarity analysis using RDKit. Use when the user asks to compute molecular descriptors, filter compounds by Lipinski or Veber rules, detect PAINS, calculate fingerprint similarity, run matched molecular pair analysis, generate ADMET descriptors, or process SMILES. Triggers include \"RDKit\", \"molecular descriptors\", \"Lipinski\", \"rule of five\", \"Veber\", \"PAINS\", \"pan-assay interference\", \"Morgan fingerprint\", \"Tanimoto\", \"fingerprint similarity\", \"matched molecular pair\", \"MMP\", \"mmpdb\", \"ADMET\", \"druglikeness\", \"SMILES\", \"cheminformatics\", \"compound filtering\", \"chemical similarity\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3276,3277,3280,3281],{"name":21,"slug":22,"type":16},{"name":3278,"slug":3279,"type":16},"Chemistry","chemistry",{"name":14,"slug":15,"type":16},{"name":3246,"slug":3247,"type":16},"2026-07-12T08:37:28.334619",{"slug":3284,"name":3284,"fn":3285,"description":3286,"org":3287,"tags":3288,"stars":26,"repoUrl":27,"updatedAt":3295},"claims-analytics","analyze and parse healthcare claims data","Pipeline skill for healthcare claims data parsing, analysis, and fraud detection. Use when the user asks to parse X12 837 or 835 claim files, manipulate ICD-10 CPT or HCPCS codes, detect billing pattern anomalies, profile providers against specialty peers, identify outlier billing behavior, validate NCCI edits programmatically, detect duplicate claims, run Benford's law analysis on charges, build claims data pipelines, or analyze E&M code distributions. Triggers include \"parse X12 837\", \"parse 835\", \"claims SQL\", \"ICD-10 manipulation\", \"CPT code analysis\", \"provider profiling\", \"billing outlier\", \"NCCI validation code\", \"duplicate claim detection\", \"Benford's law charges\", \"claims ETL\", \"E&M distribution analysis\", \"claims analytics pipeline\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3289,3290,3291,3294],{"name":14,"slug":15,"type":16},{"name":3229,"slug":3230,"type":16},{"name":3292,"slug":3293,"type":16},"Insurance","insurance",{"name":18,"slug":19,"type":16},"2026-07-12T08:37:34.815088",{"slug":3297,"name":3297,"fn":3298,"description":3299,"org":3300,"tags":3301,"stars":26,"repoUrl":27,"updatedAt":3305},"claims-billing-rules","analyze healthcare claims billing rules","Reasoning skill for healthcare claims billing rules and fraud detection logic. Use when the user asks about CMS billing rules, place of service codes, global surgery periods, modifier usage (25 59 76 77), NCCI edit logic, column 1 column 2 code pairs, mutually exclusive procedures, modifier indicators, fraud waste and abuse patterns, E&M upcoding, unbundling, phantom billing, impossible day detection, coding error versus fraud distinction, FWA investigation methodology, or claims audit logic. Triggers include \"CMS billing rules\", \"NCCI edits\", \"modifier 25\", \"modifier 59\", \"global surgery period\", \"upcoding\", \"unbundling\", \"phantom billing\", \"impossible day\", \"FWA\", \"fraud waste abuse\", \"coding error vs fraud\", \"claims audit\", \"billing compliance\", \"E&M level selection\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3302,3303,3304],{"name":3229,"slug":3230,"type":16},{"name":3292,"slug":3293,"type":16},{"name":3260,"slug":3261,"type":16},"2026-07-12T08:38:28.210856",40]