scatac-preprocessing
Load when preprocessing a single-cell ATAC peak × cell AnnData via Signac-style TF-IDF + LSI + Leiden, producing a clustered UMAP-ready object. Skip when input is fragments; BAM (peak calling not implemented here); scRNA preprocessing (use sc-preprocessing).
- License 许可
- Apache-2.0
- 最近更新
- 2026-10-08
- Stars
- ★ 161
- Forks
- 27
01 前言 Front Matter
- name
- scatac-preprocessing
- tags
- [ "singlecell", "scatac", "atac", "preprocessing", "tfidf", "lsi", "clustering", "leiden" ]
- trigger
- scATAC preprocessing, single-cell ATAC preprocessing, ATAC TF-IDF LSI, chromatin accessibility clustering, scATAC UMAP Leiden
- description
- Load when preprocessing a single-cell ATAC peak × cell AnnData via Signac-style TF-IDF + LSI + Leiden, producing a clustered UMAP-ready object. Skip when input is fragments; BAM (peak calling not implemented here); scRNA preprocessing (use sc-preprocessing).
02 资源文件 9
- 脚本_api.py8.4 KB
- 脚本examples/example_step.py805 B
- 参考文档references/methodology.md7.5 KB
- 参考文档references/output_contract.md1.0 KB
- 参考文档references/parameters.md1.1 KB
- 脚本scatac_preprocessing.py26.6 KB
- 脚本tests/__init__.py38 B
- 脚本tests/test_atac_api.py3.0 KB
- 脚本tests/test_scatac_preprocessing.py3.8 KB
03 SKILL.md 正文
scatac-preprocessing
Use from a step
from skills._sdk.notebook import load_skill, read_input, write_output
atac = load_skill("scatac-preprocessing")
adata = read_input("data/peaks.h5", reader=atac.read_10x_peaks)
adata = atac.preprocess(adata, random_state=0)
write_output(adata, "intermediate/accessibility.h5ad")
write_output(atac.cluster_summary(adata), "tables/clusters.csv")
For H5AD use read_input without a reader. The API returns a copy and does
not write files. examples/example_step.py recovers three planted groups
from load_demo("atac_synthetic"); that tests computation, not biological validity.
When to use
The user has a cell × peak scATAC AnnData (raw-count-like accessibility
matrix in .X) and wants the standard "filter → TF-IDF → LSI → graph →
UMAP → Leiden" pipeline in one shot. Currently a single backend:
tfidf_lsi (Signac-style). The skill stops at clustered UMAP — no
fragment QC, no peak calling, no motif / gene-activity scoring, no
multi-sample integration. For scRNA preprocessing use sc-preprocessing.
Inputs & Outputs
Inputs
- Input kinds:
file,directory - Modalities: scatac
- File types:
.h5ad,.h5,.loom,.csv,.tsv
Outputs
tables/cluster_summary.csvtables/lsi_variance_ratio.csvtables/peak_summary.csvtables/preprocess_summary.csvtables/qc_metrics_per_cell.csvtables/umap_points.csvfigures/umap_leiden.pngfigures/lsi_variance.pngfigures/qc_violin.pngfigures/top_accessible_peaks.pngprocessed.h5adreport.mdresult.jsonfigures/manifest.json,figure_data/manifest.json, plot-data CSV filesreproducibility/commands.sh,reproducibility/requirements.txt- Processed AnnData (
saves_h5ad) — addsobs:leiden;obsm:X_lsi,X_umap;layers:counts - AnnData processing state after success:
preprocessed
Flow
- Read cell × peak counts. The 10x reader uses
gex_only=Falseand keeps Peaks in multiome inputs; other CLI formats usesmart_load. - Validate
.Xis present, non-empty, non-negative. - Compute per-cell
n_peaks_by_counts/total_counts; filter cells by--min-peaksand peaks by--min-cells. - Retain the globally most accessible peaks up to
--n-top-peaks. - Run Signac-style TF-IDF (
--tfidf-scale-factor); truncated-SVD LSI to--n-lsicomponents. - Build neighbour graph (
--n-neighbors), UMAP, Leiden (--leiden-resolution). - Save
processed.h5ad, tables, figures,report.md,result.json.
Gotchas
- Filtering can wipe everything.
_api.py:preprocessraises ifmin_peaksremoves every cell ormin_cellsremoves every peak. Inspectn_peaks_by_countsbefore tightening thresholds; the CLI defaults to--min-peaks 200. - LSI needs enough cells and peaks.
_api.py:preprocessraises when fewer than two LSI components can be computed after filtering. - Input must be non-negative count-like in
.X._api.py:preprocessrejects missing, empty or negative matrices. Non-integer values only warn: TF-IDF values are usually non-negative and may pass this check, but preprocessing them again is not valid. processed.h5adkeeps only retained peaks._api.py:preprocessselects the topn_top_peaksby total accessibility. Keep the input if you need the full peak space later.--inputmandatory unless--demo.scatac_preprocessing.pyraisesValueError("--input required when not using --demo").- Single backend only.
scatac_preprocessing.pyraisesValueError(f"Unknown preprocessing method '{method}'")for anything other thantfidf_lsi. The--methodflag exists for forward compatibility; today it's effectively a no-op. _api.py:qc_metrics_tablereports QC metrics calculated before selecting top peaks. Those totals can exceed the sums in the returned, peak-filtered.Xor counts layer._api.py:read_10x_peaksreads counts, not fragments or BAM. It raises when a multiome input contains no Peaks features; it never falls back to gene expression.
Key CLI
# Demo (built-in synthetic scATAC)
python skills/singlecell/scatac/scatac-preprocessing/scatac_preprocessing.py --demo --output /tmp/scatac_demo
# Standard run on a 10x scATAC h5
python skills/singlecell/scatac/scatac-preprocessing/scatac_preprocessing.py \
--input atac_peaks.h5 --output results/
# Tune QC + feature budget
python skills/singlecell/scatac/scatac-preprocessing/scatac_preprocessing.py \
--input atac_peaks.h5ad --output results/ \
--min-peaks 300 --min-cells 10 --n-top-peaks 20000
# Tune latent space + clustering
python skills/singlecell/scatac/scatac-preprocessing/scatac_preprocessing.py \
--input atac_peaks.h5ad --output results/ \
--n-lsi 40 --n-neighbors 20 --leiden-resolution 1.0
API
<!-- api:begin generated from _api.py; regenerate with run.py api <skill dir> --write -->
preprocess(adata, *, min_peaks=200, min_cells=5, n_top_peaks=10000, tfidf_scale_factor=10000.0, n_lsi=30, n_neighbors=15, leiden_resolution=0.8, random_state=0)
Return a filtered copy of .X accessibility counts with TF-IDF, LSI and Leiden.
Cells need min_peaks detected peaks; peaks need min_cells cells. Keep at most n_top_peaks, ranked by total counts. Counts remain in layers['counts'] and .raw on retained peaks; .X becomes log1p TF-IDF. LSI uses scaled SVD components, excluding the first component from the neighbor graph. UMAP and Leiden use that graph. All stochastic operations use random_state. No file is written and the input is not modified.
read_10x_peaks(path)
Read 10x H5 or MTX peak counts; pass it as reader= to read_input.
Use gex_only=False, then keep Peaks when feature_types is present. No gene-expression filtering is applied to a peak-only matrix lacking it.
qc_metrics_table(adata)
Return cell identifiers and the QC metrics computed before top-peak selection.
peak_summary(adata, *, n_top=50)
Return retained peaks ranked by total counts and number of cells.
lsi_variance_table(adata)
Return variance ratios and their cumulative sum for every fitted LSI component.
cluster_summary(adata, *, cluster_key='leiden')
Return cell counts and percentages for labels in obs[cluster_key].
umap_figure(adata, *, cluster_key='leiden')
Return a cluster-colored Figure from obsm['X_umap']; do not write a file.
run_info(adata, *, keep: bool=True)
Return TF-IDF/LSI parameters; keep=False removes the run record.
<!-- api:end -->
See also
references/parameters.md— every CLI flag, per-method tunablesreferences/methodology.md— TF-IDF + LSI math; Signac alignmentreferences/output_contract.md—obsm/varschema + table layouts- Adjacent skills:
sc-preprocessing(parallel — scRNA, NOT scATAC),sc-clustering(downstream — re-cluster onobsm["X_lsi"]if you want a different resolution without re-running TF-IDF)
Dependencies
Python packages this skill's script needs. They are not installed for you — check before a long run.
anndata, igraph, matplotlib, numpy, pandas, scanpy, scikit-learn, scipy, seaborn
04 同仓库更多 Skills
demo-skill
A fixture skill for the skill environment tests. Use it for nothing else.
fake-domains
Test fixture for the golden deployment in tests/entry. Load never; it has no script.
replace-me-skill
Load when copying this directory to bootstrap a new OmicsClaw skill. Skip when an existing skill already covers the request.
spatial-velocity
Load when estimating RNA velocity on a spatial AnnData with `layers["spliced"]` + `layers["unspliced"]` via scVelo (stochastic / deterministic / dynamical) or veloVI (deep generative). Skip when input lacks the spliced/unspliced layers (must be quantified upstream by velocyto / kb-python / STARsolo); non-spatial scRNA velocity (use sc-velocity).
spatial-trajectory
Load when inferring pseudotime / lineage trajectories on a preprocessed spatial AnnData via DPT (default — diffusion pseudotime), CellRank (terminal-state + fate-probability), or Palantir (waypoint branch probabilities). Skip when the data has spliced/unspliced layers and you want velocity-driven dynamics (use spatial-velocity); non-spatial scRNA pseudotime (use sc-pseudotime).
spatial-statistics
Load when running spatial autocorrelation / hotspot / co-occurrence / neighbourhood-enrichment / Ripley K stats on a clustered spatial AnnData via squidpy. Skip when ranking spatially variable genes (use spatial-genes); tissue domain detection (use spatial-domains).