sc-markers
Load when ranking cluster-level marker genes from a clustered single-cell AnnData via Scanpy Wilcoxon / t-test / logreg or COSG specificity. Skip when comparing condition-vs-control with replicates (u
Files8
View on GitHubSKILL.mdskills/sc-markers/SKILL.md
GitHubsc-markers
When to use
The user already has clustering / cell-type labels in obs (typically
leiden, louvain, or cell_type) and wants ranked marker genes per
group as evidence for downstream annotation or interpretation. Four
methods: wilcoxon (default rank-sum), t-test (Welch), logreg
(multinomial logistic regression — discriminative ranking), cosg
(fast cosine-specificity scoring without p-values). This is for
cluster markers, not condition contrasts — for treatment-vs-control
DE with replicates use sc-de.
Inputs & Outputs
<!-- AUTO-GENERATED from skill.yaml (interface) — do not edit by hand. Regenerate: python scripts/generate_skill_md.py <skill_dir> -->Inputs
- Modalities: scrna
- File types:
.h5ad - Requires a preprocessed AnnData (
Xnormalised, PCA/neighbours present)
Outputs
tables/cell_metadata.csvtables/cluster_summary.csvtables/markers_all.csvtables/markers_top.csvfigures/r_feature_violin.pngfigures/r_marker_heatmap.pnganalysis_summary.txtprocessed.h5adreport.mdresult.json- Processed AnnData (
saves_h5ad)
Flow
- Load AnnData; resolve
--groupby(auto-detect fromleiden/louvain/cell_typeif unset). - Validate parameters (
n_top ≥ 1, fractions in[0, 1],muin[0, 1]). - Run the selected ranker against
adata.X(treated as normalised expression). - Apply post-filters (
--min-in-group-fraction,--min-fold-change,--max-out-group-fraction). - Build top-N table, per-cluster summary, and figure-data CSVs.
- Save
processed.h5ad(withrank_genes_groups*purged fromuns),tables/,figures/,report.md,result.json.
Gotchas
--groupbyauto-detection requires a recognised column.sc_markers.py:135raisesValueError("Grouping column '...' not found in adata.obs")for an explicit-but-missing key;:137raisesValueError('No cluster/cell-type grouping column available for marker discovery.')when nothing amongleiden/louvain/cell_typeexists. Runsc-clusteringfirst or pass--groupby <real-obs-column>.cosgreturns no p-values.sc_markers.py:91-94registerscosgas a cosine-similarity specificity scorer —tables/markers_all.csvwill lackpvals/pvals_adjcolumns. Downstream filters that branch on adjusted p-value must handle the method ==cosgcase.--muiscosg-only.sc_markers.py:373setsresult.json["mu"] = args.mu if method == 'cosg' else None. Passing--muwith another method silently recordsNone.adata.Xis treated as normalised expression with no guard.sc_markers.pysetsexpression_source = 'adata.X'without verifying.Xis log-normalised. If.Xstill holds raw counts (e.g., the user skippedsc-preprocessing), the Wilcoxon / t-test runs on counts and the rankings are unreliable.--inputis mandatory unless--demo.sc_markers.py:316raisesValueError('--input required when not using --demo').
Key CLI
# Demo (built-in PBMC3K with leiden labels)
python omicsclaw.py run sc-markers --demo --output /tmp/sc_markers_demo
# Default Wilcoxon on leiden clusters
python omicsclaw.py run sc-markers \
--input clustered.h5ad --output results/ --groupby leiden
# COSG fast specificity ranking on a labelled AnnData
python omicsclaw.py run sc-markers \
--input annotated.h5ad --output results/ \
--groupby cell_type --method cosg --mu 1.0
# Strict marker filtering (high fold-change, low out-group fraction)
python omicsclaw.py run sc-markers \
--input clustered.h5ad --output results/ \
--min-fold-change 1.0 --max-out-group-fraction 0.2
See also
references/parameters.md— every CLI flag and per-method tuning hintreferences/methodology.md— Wilcoxon vs t-test vs logreg vs COSG; when each winsreferences/output_contract.md—markers_all.csvcolumn schema; figures' figure_data CSVs- Adjacent skills:
sc-clustering(upstream — produces theleiden/louvaincolumn),sc-cell-annotation(downstream — uses these markers as evidence for label assignment),sc-de(parallel — replicate-aware condition contrasts, NOT cluster markers)