[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7EBJZ95P39A8FV5YSCGSHV1":3,"skill-same:01M7EBJZ95P39A8FV5YSCGSHV1":62},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":30,"commitSha":31,"skillDirectory":32,"forksCount":14,"repositoryHtmlUrl":33,"repositoryHomepageUrl":33,"ownerHtmlUrl":34,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":35,"install":36,"resources":49},"01M7EBJZ95P39A8FV5YSCGSHV1","bio-atac-seq-single-cell-atac",null,"Process and analyze single-cell ATAC-seq data with Signac, ArchR, SnapATAC2, or Cell Ranger ATAC. Use when handling 10X scATAC or 10X Multiome (paired RNA+ATAC) data, performing per-cell QC, choosing between ArchR\u002FSignac\u002FSnapATAC2 ecosystems, building per-cluster consensus peaksets, integrating with paired scRNA-seq, doublet detection (AMULET vs ArchR vs scDblFinder), or running pseudobulk differential accessibility per cluster.","Mr-Nobody-Anonymous\u002FAll-skills","Mr-Nobody-Anonymous","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F184253119?v=4","01M7AEXFJHKTYQW5R0ZCQQTWFV","anonymous","01M7C00M3GQR4QKP9GZA42GFAK",0,"MIT","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fbiology\u002Fbio-atac-seq-single-cell-atac\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: bio-atac-seq-single-cell-atac\ndescription: Process and analyze single-cell ATAC-seq data with Signac, ArchR, SnapATAC2, or Cell Ranger ATAC. Use when handling 10X scATAC or 10X Multiome (paired RNA+ATAC) data, performing per-cell QC, choosing between ArchR\u002FSignac\u002FSnapATAC2 ecosystems, building per-cluster consensus peaksets, integrating with paired scRNA-seq, doublet detection (AMULET vs ArchR vs scDblFinder), or running pseudobulk differential accessibility per cluster.\ntool_type: mixed\nprimary_tool: Signac\nsource: \"https:\u002F\u002Fgithub.com\u002FGPTomics\u002FbioSkills\"\nsource_repository: \"GPTomics\u002FbioSkills\"\nsource_path: \"atac-seq\u002Fsingle-cell-atac\u002FSKILL.md\"\nlicense: \"MIT\"\nimported_at: \"2026-09-20\"\n---\n\n## Version Compatibility\n\nReference examples tested with: Cell Ranger ATAC 2.1+, Signac 1.13+, Seurat 5.0+, ArchR 1.0.2+, SnapATAC2 2.8+, AMULET 1.1+, scDblFinder 1.16+, scater 1.30+, scvi-tools 1.1+, GenomicRanges 1.54+, JASPAR2024 0.99+, BSgenome.Hsapiens.UCSC.hg38 1.4+, EnsDb.Hsapiens.v86 2.99+, MACS3 3.0+. SnapATAC2 2.8+ uses `pp.import_fragments`; older 2.5-2.7 used `pp.import_data` (renamed\u002Fremoved in 2.9).\n\nVerify before use:\n- Python: `pip show \u003Cpackage>` then `help(module.function)` to check signatures\n- R: `packageVersion('\u003Cpkg>')` then `?function_name` to verify parameters\n- CLI: `\u003Ctool> --version` then `\u003Ctool> --help` to confirm flags\n\nIf code throws unexpected errors, introspect the installed package and adapt rather than retrying.\n\n# Single-Cell ATAC-seq\n\n**\"Process my 10X scATAC data from cellranger output\"** -> Build a per-cell fragment matrix, compute per-cell QC, dimensionality reduction (TF-IDF + LSI \u002F spectral \u002F autoencoder), cluster, call cluster-level pseudobulk peaks, annotate cell types via gene-activity scores, and integrate with paired scRNA-seq if Multiome.\n\n- R: `Signac::CreateChromatinAssay()` -> `Seurat` workflow (TF-IDF + SVD + UMAP + Leiden)\n- R: `ArchR::createArrowFiles()` -> ArchR project (TileMatrix + LSI + UMAP)\n- Python: `snapatac2.pp.import_fragments()` -> SnapATAC2 (spectral \u002F diffusion-map clustering)\n- CLI (preprocessing): `cellranger-atac count` (10X) or `chromap` (alignment-only fragment files)\n\n## Ecosystem Choice (The Most Important Decision)\n\n| Ecosystem | Language | Strength | Fails when | Best for |\n|-----------|---------|---------|------------|----------|\n| Signac (Stuart 2021) | R, Seurat-based | Tightest scRNA-seq integration; Seurat ecosystem mature | Memory hungry on >100K cells; slower than ArchR | Multiome RNA+ATAC; small-to-medium datasets; Seurat user |\n| ArchR (Granja 2021) | R, Arrow\u002FHDF5 | Memory-efficient (Arrow files); fast on 100K-1M cells; built-in trajectory + doublet | Less RNA-seq integration; ArchR-specific format | Large bulk-cohort scATAC; trajectory analysis; ATAC-only |\n| SnapATAC2 (Zhang 2024) | Python, AnnData | Memory-efficient; modern Python ecosystem; spectral clustering performant | Newer; benchmarks evolving; ecosystem smaller than R | Python-first labs; very large datasets (>1M cells) |\n| Cell Ranger ATAC | CLI (10X-specific) | 10X official preprocessing | Closed; fixed pipeline | Only as preprocessing step; analysis happens elsewhere |\n| scATAC-pro | CLI-based pipeline | Alternative preprocessing | Less maintained | Legacy; not recommended for new projects |\n\nMethodology evolves; verify against Granja 2021 (ArchR), Stuart 2021 (Signac), Zhang 2024 (SnapATAC2), Heumos 2023 (best practices) before locking pipelines.\n\n## 10X Multiome Caveat (Paired RNA + ATAC)\n\n10X Multiome chemistry profiles RNA AND ATAC from the same cell. Outputs are joined by a shared barcode. Multiome workflows use Signac for ATAC and Seurat for RNA, integrated through the same Seurat object via WNN (Weighted Nearest Neighbor; Hao 2021).\n\nSingle-modality 10X scATAC (chemistry v1, v2) does NOT produce paired RNA. Verify the chemistry on the cellranger summary before assuming Multiome.\n\n## Per-Cell QC Thresholds\n\n| Metric | Definition | Pass | Caution | Reject | Source |\n|--------|-----------|------|---------|--------|--------|\n| Fragment count per cell | n_fragments after dedup | 3000-50000 | 1000-3000 | \u003C 1000 or > 80000 | 10X recommendation; high = doublet |\n| TSS enrichment per cell | Signal at TSS \u002F flanks (per cell) | >= 4 | 2-4 | \u003C 2 | ArchR \u002F Signac default; lower than bulk because per-cell |\n| Nucleosome signal | Mono \u002F NFR fragment ratio | \u003C= 4 | 4-10 | > 10 | Signac default; high = poor library |\n| % reads in peaks (per cell) | FRiP per cell at consensus | >= 0.15 | 0.10-0.15 | \u003C 0.05 | ArchR \u002F Signac defaults |\n| Mitochondrial fraction (per cell) | chrM \u002F total per cell | \u003C 0.05 | 0.05-0.15 | > 0.20 | Lower than bulk; per-cell more sensitive |\n| Doublet score | AMULET \u002F ArchR doublet | \u003C 0.5 | 0.5-0.7 | > 0.7 | Tool-dependent threshold |\n| Blacklist ratio | Reads in ENCODE blacklist \u002F total | \u003C 0.05 | 0.05-0.10 | > 0.10 | Standard |\n\nPer-cell thresholds are looser than bulk because individual cells have orders of magnitude less signal; the population aggregate is what matters.\n\n## Doublet Detection: Three Approaches\n\n| Tool | Method | Strength | Fails when |\n|------|--------|---------|------------|\n| AMULET (Thibodeau 2021) | Collision-based: detects cells with too many fragments at same position (mathematically impossible from single cell because of 2-allele limit) | Specific to ATAC biology; orthogonal to clustering | Requires high depth; recall drops sharply below ~15-16K valid read pairs\u002Fcell (peaks ~90% near ~25K) |\n| ArchR addDoubletScores | Synthetic doublet simulation + projection into LSI | Built into ArchR; auto-thresholds | Tied to ArchR's LSI; not portable |\n| scDblFinder (Germain 2021) | Synthetic doublets + classifier | Works on Signac and SCE objects; well-benchmarked | RNA-developed; ATAC adaptation requires careful settings |\n\n**Operational rule:** Run AMULET as the primary ATAC-specific check; verify with ArchR or scDblFinder as orthogonal evidence. Double-flagged cells are high-confidence doublets.\n\n## Per-Tool Failure Modes\n\n### Signac TF-IDF + SVD -- First component is depth\n\n**Trigger:** Running `RunTFIDF` -> `RunSVD` and using all components for clustering.\n\n**Mechanism:** Component 1 of LSI is highly correlated with sequencing depth per cell, not biology. Including it pulls clusters along depth axis.\n\n**Symptom:** UMAP shows linear cell-density gradient that tracks fragment count.\n\n**Fix:** Skip component 1 in downstream UMAP and clustering: `RunUMAP(object, dims=2:30)`, `FindNeighbors(object, dims=2:30)`. ArchR and SnapATAC2 do this automatically.\n\n### ArchR -- TileMatrix vs PeakMatrix confusion\n\n**Trigger:** Using TileMatrix for differential testing or motif analysis.\n\n**Mechanism:** TileMatrix is regular fixed bins (default 500 bp) covering the whole genome; useful for clustering but not for biology because ATAC signal is at peaks, not arbitrary bins.\n\n**Fix:** Use TileMatrix for embedding\u002Fclustering (it's faster); use PeakMatrix (after `addReproduciblePeakSet`) for differential, motif, and gene-activity analysis.\n\n### SnapATAC2 -- Memory layout assumes integer counts\n\n**Trigger:** Loading non-integer or negative-valued matrices.\n\n**Fix:** SnapATAC2 expects raw fragment counts (Int32). Convert from float matrices before loading.\n\n### Cell Ranger ATAC -- Empty droplet detection\n\n**Trigger:** Default cellranger-atac calls cells based on UMI count but ATAC has no UMIs; uses fragment-based heuristic. Sometimes calls \u003C 1000-fragment cells as real.\n\n**Fix:** Re-filter cellranger output to require fragment count >= 1000 AND TSS enrichment >= 4 BEFORE downstream analysis.\n\n### Multiome WNN -- ATAC weighting\n\n**Trigger:** Default WNN equally weights RNA and ATAC modalities.\n\n**Mechanism:** ATAC's per-cell signal is much sparser than RNA; equal weighting can swamp the joint embedding with ATAC noise.\n\n**Fix:** Inspect per-modality weights with `IntegrateLayers`; if ATAC weights dominate noise, manually adjust or use `FindMultiModalNeighbors` carefully.\n\n### Per-cluster pseudobulk peak calling -- Empty clusters\n\n**Trigger:** Calling MACS3 per cluster when one cluster has \u003C 200 cells.\n\n**Mechanism:** MACS3 needs >= 1M reads in pseudobulk to call peaks reliably; small clusters do not produce enough reads.\n\n**Fix:** Aggregate small clusters into a \"rare\" group OR drop them from per-cluster calling. Use the union of larger-cluster peaks as a fallback for rare-cell-type analysis.\n\n## Decision Tree by Goal\n\n| Goal | Recommended pipeline |\n|------|---------------------|\n| Standard 10X scATAC analysis (R user) | Signac: CreateChromatinAssay -> RunTFIDF -> RunSVD -> RunUMAP (dims 2:30) -> FindClusters |\n| Standard 10X scATAC analysis (Python user) | SnapATAC2: pp.import_fragments -> add_tile_matrix -> spectral -> UMAP -> leiden |\n| Large dataset (> 100K cells) | ArchR (memory-efficient Arrow files) |\n| 10X Multiome (paired RNA + ATAC) | Signac + Seurat: per-modality embedding then WNN integration |\n| Trajectory \u002F pseudotime | ArchR getTrajectory; or Signac + Cicero |\n| Differential accessibility per cluster | Pseudobulk per cluster -> consensus peakset -> DESeq2 |\n| Cell-type annotation | Gene-activity scores via ArchR or Signac; then run `single-cell\u002Fmarkers-annotation` |\n| Multimodal trajectories (RNA + ATAC) | MOFA+, ArchR + scRNA integration, or SCENIC+ |\n| Plant \u002F non-model | Signac with custom EnsDb \u002F TxDb; ArchR with custom annotations |\n\n## Standard Signac Workflow\n\n**Goal:** Process 10X scATAC output into a clustered, annotated Seurat object with per-cell QC, embedding, and gene-activity scores.\n\n**Approach:** Load fragments and peak counts into a ChromatinAssay, compute per-cell QC (TSS enrichment, nucleosome signal, FRiP, blacklist), subset to passing cells, run TF-IDF + SVD + UMAP skipping LSI component 1, then derive a gene-activity assay for marker-based annotation.\n\n```r\nlibrary(Signac); library(Seurat); library(EnsDb.Hsapiens.v86)\nlibrary(BSgenome.Hsapiens.UCSC.hg38)\n\n# 1. Load 10X output\ncounts \u003C- Read10X_h5('outs\u002Ffiltered_peak_bc_matrix.h5')\nmetadata \u003C- read.csv('outs\u002Fsinglecell.csv', row.names=1)\n\nchrom_assay \u003C- CreateChromatinAssay(\n    counts=counts,\n    sep=c(':', '-'),\n    fragments='outs\u002Ffragments.tsv.gz',\n    annotation=GetGRangesFromEnsDb(EnsDb.Hsapiens.v86),\n    genome='hg38')\n\nobj \u003C- CreateSeuratObject(counts=chrom_assay, assay='ATAC', meta.data=metadata)\n\n# 2. Per-cell QC\nobj \u003C- NucleosomeSignal(obj)              # Mono\u002FNFR ratio\nobj \u003C- TSSEnrichment(obj, fast=FALSE)\nobj$pct_reads_in_peaks \u003C- obj$peak_region_fragments \u002F obj$passed_filters * 100\nobj$blacklist_ratio \u003C- obj$blacklist_region_fragments \u002F obj$peak_region_fragments\n\n# 3. QC filter (looser per-cell thresholds)\nobj \u003C- subset(obj,\n    subset = peak_region_fragments > 1000 & peak_region_fragments \u003C 20000 &\n             pct_reads_in_peaks > 15 & blacklist_ratio \u003C 0.05 &\n             nucleosome_signal \u003C 4 & TSS.enrichment > 4)\n\n# 4. Dimensionality reduction (skip component 1 - it's depth)\nobj \u003C- RunTFIDF(obj)\nobj \u003C- FindTopFeatures(obj, min.cutoff='q0')\nobj \u003C- RunSVD(obj)\nobj \u003C- RunUMAP(obj, reduction='lsi', dims=2:30)\nobj \u003C- FindNeighbors(obj, reduction='lsi', dims=2:30)\nobj \u003C- FindClusters(obj, algorithm=4, resolution=0.5)    # Leiden\n\n# 5. Gene-activity for annotation\ngene.activities \u003C- GeneActivity(obj)\nobj[['ACT']] \u003C- CreateAssayObject(counts=gene.activities)\nDefaultAssay(obj) \u003C- 'ACT'\nobj \u003C- NormalizeData(obj, normalization.method='LogNormalize',\n                     scale.factor=median(obj$nCount_ACT))\n```\n\n## Per-Cluster Pseudobulk Peak Calling\n\n```r\n# Signac wrapper around MACS3\npeaks \u003C- CallPeaks(obj, group.by='seurat_clusters',\n                   macs2.path='\u002Fpath\u002Fto\u002Fmacs3', cleanup=FALSE,\n                   format='BED', shift=-75, extsize=150,   # Tn5 cut-site recipe; shift only applies to format='BED'\n                   additional.args='-p 0.01')\n# Then iterative-overlap consensus across clusters (atac-seq\u002Fconsensus-peakset)\n```\n\n## ArchR Workflow\n\n**Goal:** Build an ArchR project from fragment files, filter doublets, cluster, and call per-cluster reproducible peaks.\n\n**Approach:** Create Arrow files with minimum TSS and fragment thresholds, score doublets and filter, run iterative LSI + UMAP + clustering on the TileMatrix, then build per-cluster group coverages and a reproducible peakset via MACS3.\n\n```r\nlibrary(ArchR)\naddArchRGenome('hg38')\n\n# 1. Create Arrow files from fragment files\nArrowFiles \u003C- createArrowFiles(\n    inputFiles=c('fragments_rep1.tsv.gz', 'fragments_rep2.tsv.gz'),\n    sampleNames=c('rep1', 'rep2'),\n    minTSS=4, minFrags=1000,\n    addTileMat=TRUE, addGeneScoreMat=TRUE)\n\n# 2. Doublet detection (built-in)\ndoubletScores \u003C- addDoubletScores(input=ArrowFiles, k=10, knnMethod='UMAP')\n\n# 3. Project + filter\nproj \u003C- ArchRProject(ArrowFiles=ArrowFiles, outputDirectory='ArchR_out')\nproj \u003C- filterDoublets(proj)\n\n# 4. LSI + UMAP + clustering\nproj \u003C- addIterativeLSI(proj, useMatrix='TileMatrix', name='IterativeLSI')\nproj \u003C- addClusters(proj, reducedDims='IterativeLSI', method='Seurat', resolution=0.5)\nproj \u003C- addUMAP(proj, reducedDims='IterativeLSI')\n\n# 5. Reproducible peakset (per cluster)\nproj \u003C- addGroupCoverages(proj, groupBy='Clusters')\nproj \u003C- addReproduciblePeakSet(proj, groupBy='Clusters', pathToMacs2='\u002Fpath\u002Fmacs3')\nproj \u003C- addPeakMatrix(proj)\n```\n\n## SnapATAC2 Workflow (Python)\n\n**Goal:** Run a Python-native scATAC pipeline from fragments through clusters, per-cluster peaks, and gene activity.\n\n**Approach:** Import fragments to a backed AnnData, compute per-cell TSS enrichment and fragment-size metrics, filter cells, build a tile matrix, run spectral embedding + UMAP + Leiden, call per-cluster peaks via MACS3, and derive a gene-activity matrix.\n\n```python\nimport snapatac2 as snap\n\n# 1. Load 10X fragments. SnapATAC2 uses snap.pp.import_fragments (NOT snap.read_10x, which doesn't exist).\ndata = snap.pp.import_fragments(\n    fragment_file='outs\u002Ffragments.tsv.gz',\n    chrom_sizes=snap.genome.hg38,\n    file='out.h5ad',                        # backed AnnData; backend handled by file path\n    sorted_by_barcode=False)\ndata.obs['sample_id'] = 'rep1'\n\n# 2. Per-cell QC\nsnap.metrics.tsse(data, gene_anno=snap.genome.hg38)\nsnap.metrics.frag_size_distr(data)\nsnap.pp.filter_cells(data, min_counts=1000, min_tsse=4)\n\n# 3. Tile matrix + spectral\nsnap.pp.add_tile_matrix(data, bin_size=500)\nsnap.pp.select_features(data, n_features=250000)\nsnap.tl.spectral(data)\nsnap.tl.umap(data)\nsnap.tl.leiden(data)\n\n# 4. Per-cluster peak calling (uses MACS3)\nsnap.tl.macs3(data, groupby='leiden')\n\n# 5. Gene activity (gene score) for annotation\ngene_mat = snap.pp.make_gene_matrix(data, gene_anno=snap.genome.hg38)\n```\n\n## Reconciliation Across Tools\n\n| Pattern | Likely cause | Action |\n|---------|--------------|--------|\n| Signac UMAP shows tight clusters; ArchR UMAP shows loose | Different LSI implementation; ArchR uses iterative LSI by default | Both valid; biology should match in cluster labels |\n| Different tools call different doublet rates | Different algorithms (collision vs simulation) | Use intersection (cells flagged by 2+ tools) as high-confidence doublets |\n| Cluster boundaries differ | Different clustering algorithm or resolution | Standardize on Leiden algorithm 4 with same resolution |\n| Per-cluster peak count differs | Different peak callers or pseudobulk depth | Ensure same MACS3 parameters; pool small clusters |\n\n**Operational rule:** For high-confidence cell-type annotation, agree across two ecosystems (e.g., Signac + ArchR clusters) and report agreement metrics.\n\n## cellranger-atac vs cellranger-arc\n\n| Pipeline | Use for | Output |\n|----------|---------|--------|\n| cellranger-atac | Single-modality 10X scATAC (chemistry v1, v2) | per-cell ATAC barcodes; fragments.tsv.gz; per-barcode metadata |\n| cellranger-arc | 10X Multiome (paired RNA + ATAC same cell, \"Multiome chemistry\") | joint barcodes for RNA + ATAC; separate fragment \u002F count files; one barcode whitelist |\n\n**Trigger:** Loading 10X output without checking which pipeline produced it.\n\n**Mechanism:** cellranger-atac and cellranger-arc produce different output structures. cellranger-arc fragments.tsv has barcodes paired with the RNA matrix; cellranger-atac fragments are ATAC-only with their own barcode universe.\n\n**Fix:** Verify the chemistry on the cellranger summary (look for \"Multiome\" in the run config). Use `Read10X_h5` for cellranger-arc Multiome RNA output; use `CreateChromatinAssay` with the matched fragments for the ATAC. Mixing barcodes across pipelines fails silently.\n\n## Cell-Cycle Correction for scATAC\n\n**Trigger:** Proliferating cell types in the dataset; cells distributed across cell cycle phases.\n\n**Mechanism:** Replication-associated chromatin opening adds 5-10% global accessibility per cell as it moves G1 -> S -> G2\u002FM; this confounds clustering and DA.\n\n**Detection:** Score cells with a chromatin-adapted S-phase signature (regulated origin loci, replication-stress-response gene accessibility) analogous to Seurat's CellCycleScoring on RNA. Or compute a Repli-seq peak overlap score.\n\n**Fix:** Regress S-phase score on the TF-IDF residuals before downstream LSI: `ScaleData(obj, vars.to.regress='S.score')` analogous to RNA workflow. For DA between cell-cycle-mismatched conditions, add S-phase as covariate in pseudobulk DESeq2.\n\n## Sex-Chromosome QC for scATAC\n\n**Trigger:** Mixed-sex donors in the dataset; sample-swap detection.\n\n**Mechanism:** XIST locus accessibility is high in female cells (X-inactivation); chrY peak count is essentially zero in females. Per-cell or per-sample, the XIST\u002FchrY ratio identifies sex unambiguously.\n\n**Detection:** In a per-cell counts matrix, compute fraction of fragments at XIST locus (chrX:73820651-73852753 hg38) and chrY peak count; classify cells; flag cells\u002Fsamples where assignment disagrees with metadata.\n\n**XCI escapees:** Genes that escape X-inactivation (KDM6A, DDX3X, EIF1AX) are biallelically accessible in female cells but not male; can be used as additional sex confirmation if XIST is ambiguous.\n\n## scArches Reference Mapping\n\n**Trigger:** Projecting query scATAC onto a reference atlas; cross-study integration without batch effects.\n\n**Mechanism:** scArches (Lotfollahi 2022) provides transfer-learning to project a new dataset onto an existing reference's latent space without retraining the reference. For ATAC, the relevant model is PEAKVI (Ashuach 2022). PEAKVI lives in `scvi-tools` (`scvi.model.PEAKVI`); the `load_query_data` classmethod implements the scArches algorithm directly, so an explicit `import scarches` is not required.\n\n```python\nimport scvi\n\n# Pre-trained reference model (e.g. PBMC scATAC atlas)\nquery_model = scvi.model.PEAKVI.load_query_data(adata_query, reference_path)\nquery_model.train(max_epochs=200)\nadata_query.obsm['X_emb'] = query_model.get_latent_representation()\n```\n\nReference atlases for ATAC are still emerging; the most-developed are PBMC (Granja 2021) and brain (BRAIN Initiative).\n\n## chromBPNet Per-Cluster Pseudobulk\n\n**Trigger:** Cell-type-specific variant effect prediction; per-cluster bias-corrected calling.\n\n**Mechanism:** Train chromBPNet (atac-seq\u002Fdeep-learning-atac) per pseudobulk cluster; outputs are bias-corrected per-base profiles + variant effect predictions specific to that cell type.\n\n**Workflow:** Aggregate fragments per cluster into pseudobulk BAMs; run chromBPNet pipeline per cluster (~24h GPU per cluster); use the resulting model for in silico variant scoring at GWAS \u002F rare-variant SNPs in that cell type.\n\nFor most studies, this is reserved for top 5-10 priority clusters; running chromBPNet per cluster on >20 cell types is computationally heavy.\n\n## AMULET Depth Threshold\n\nAMULET reaches maximum recall (~90%) near ~25,000 valid read pairs (~fragments) per cell and degrades sharply below ~15,000-16,000, where the collision-based detection has insufficient power: the expected number of collisions per cell is too small for the binomial test to distinguish doublet from singleton. For lower-depth libraries, use synthetic-doublet methods (ArchR addDoubletScores, scDblFinder) instead.\n\n## Multiome WNN Integration (Signac)\n\n**Goal:** Build a joint RNA + ATAC embedding from a 10X Multiome dataset using Weighted Nearest Neighbors.\n\n**Approach:** Run per-modality embeddings (PCA on RNA, TF-IDF + SVD on ATAC skipping LSI-1), then use FindMultiModalNeighbors to learn per-cell modality weights and project a joint UMAP.\n\n```r\n# Assume `obj` has both 'RNA' and 'ATAC' assays from same Multiome experiment\nDefaultAssay(obj) \u003C- 'RNA'\nobj \u003C- NormalizeData(obj) %>% FindVariableFeatures() %>% ScaleData() %>% RunPCA()\n\nDefaultAssay(obj) \u003C- 'ATAC'\nobj \u003C- RunTFIDF(obj) %>% FindTopFeatures(min.cutoff='q0') %>% RunSVD()\n\n# Joint embedding\nobj \u003C- FindMultiModalNeighbors(obj, reduction.list=list('pca', 'lsi'),\n                               dims.list=list(1:30, 2:30))\nobj \u003C- RunUMAP(obj, nn.name='weighted.nn', reduction.name='wnn.umap')\n```\n\n## Common Errors\n\n| Error \u002F symptom | Cause | Solution |\n|-----------------|-------|----------|\n| UMAP shows depth gradient | LSI component 1 included in clustering | `dims=2:30` instead of `1:30` |\n| Cell Ranger output has many low-quality cells | cellranger ATAC uses lenient cell calling | Re-filter at fragment count >= 1000 + TSS enrichment >= 4 |\n| ArchR \"TileMatrix not found\" | Forgot `addTileMat=TRUE` in createArrowFiles | Re-create Arrow files with the flag |\n| Signac CreateChromatinAssay fails on missing fragments file | Path to fragments.tsv.gz incorrect; or missing tabix index | Provide full path; run `tabix -p bed fragments.tsv.gz` |\n| MACS3 fails on tiny pseudobulk | Cluster too small | Use cluster aggregation; require >= 200 cells per cluster |\n| AMULET reports 100% doublets | Threshold mis-set or input is technical replicates | Check fragment-count distribution; AMULET needs high depth (recall peaks near ~25K valid read pairs\u002Fcell) |\n| Multiome WNN clusters dominated by ATAC noise | Equal modality weighting | Inspect modality weights; manually adjust if needed |\n| chromVAR \u002F motif assay all NA | Run before peakset finalized | Re-run AddMotifs \u002F RunChromVAR after peaks stable |\n| EnsDb \u002F BSgenome version mismatch | hg38 BSgenome with wrong-build EnsDb | Match builds; `EnsDb.Hsapiens.v86` is GRCh38 (Ensembl v86); use `EnsDb.Hsapiens.v75` for hg19. Newer hg38 EnsDb releases (v98+) reflect newer GENCODE annotations |\n\n## References\n\n- Stuart T et al 2021 Nat Methods 18:1333 (Signac)\n- Granja JM et al 2021 Nat Genet 53:403 (ArchR)\n- Zhang K et al 2024 Nat Methods 21:217 (SnapATAC2)\n- Hao Y et al 2021 Cell 184:3573 (Seurat WNN)\n- Thibodeau A et al 2021 Genome Biol 22:252 (AMULET doublet detection)\n- Germain PL et al 2021 F1000Res 10:979 (scDblFinder)\n- Cusanovich DA et al 2015 Science 348:910 (sciATAC; LSI for sc data)\n- Chen H et al 2019 Genome Biol 20:241 (scATAC analysis benchmark)\n- Heumos L et al 2023 Nat Rev Genet 24:550 (Best practices for single-cell)\n- 10X Genomics Cell Ranger ATAC documentation\n\n## Related Skills\n\n- atac-seq\u002Fatac-qc - Bulk QC patterns adapted for per-cell\n- atac-seq\u002Fatac-peak-calling - Pseudobulk peak calling per cluster\n- atac-seq\u002Fconsensus-peakset - Across-cluster consensus\n- atac-seq\u002Fdifferential-accessibility - Pseudobulk DA per cluster\n- atac-seq\u002Fmotif-deviation - chromVAR for per-cell TF activity\n- atac-seq\u002Ffootprinting - scprinter for sc footprinting\n- atac-seq\u002Fco-accessibility - Cicero for cis-regulatory connections\n- atac-seq\u002Fdeep-learning-atac - chromBPNet \u002F scBasset for per-cluster bias correction and variant effects\n- atac-seq\u002Fenhancer-gene-linking - Per-cell-type enhancer-gene maps\n- atac-seq\u002Fallele-specific-accessibility - sc allelic imbalance for cis-effects\n- single-cell\u002Fpreprocessing - General sc QC patterns\n- single-cell\u002Fclustering - Cluster definition\n- single-cell\u002Fcell-annotation - Automated reference-based label transfer\n- single-cell\u002Fmultimodal-integration - Multiome RNA+ATAC integration\n- single-cell\u002Fscatac-analysis - Cross-reference single-cell ATAC-specific patterns\n- single-cell\u002Fbatch-integration - scArches reference mapping; Harmony\n","## Version Compatibility\n\nReference examples tested with: Cell Ranger ATAC 2.1+, Signac 1.13+, Seurat 5.0+, ArchR 1.0.2+, SnapATAC2 2.8+, AMULET 1.1+, scDblFinder 1.16+, scater 1.30+, scvi-tools 1.1+, GenomicRanges 1.54+, JASPAR2024 0.99+, BSgenome.Hsapiens.UCSC.hg38 1.4+, EnsDb.Hsapiens.v86 2.99+, MACS3 3.0+. SnapATAC2 2.8+ uses `pp.import_fragments`; older 2.5-2.7 used `pp.import_data` (renamed\u002Fremoved in 2.9).\n\nVerify before use:\n- Python: `pip show \u003Cpackage>` then `help(module.function)` to check signatures\n- R: `packageVersion('\u003Cpkg>')` then `?function_name` to verify parameters\n- CLI: `\u003Ctool> --version` then `\u003Ctool> --help` to confirm flags\n\nIf code throws unexpected errors, introspect the installed package and adapt rather than retrying.\n\n# Single-Cell ATAC-seq\n\n**\"Process my 10X scATAC data from cellranger output\"** -> Build a per-cell fragment matrix, compute per-cell QC, dimensionality reduction (TF-IDF + LSI \u002F spectral \u002F autoencoder), cluster, call cluster-level pseudobulk peaks, annotate cell types via gene-activity scores, and integrate with paired scRNA-seq if Multiome.\n\n- R: `Signac::CreateChromatinAssay()` -> `Seurat` workflow (TF-IDF + SVD + UMAP + Leiden)\n- R: `ArchR::createArrowFiles()` -> ArchR project (TileMatrix + LSI + UMAP)\n- Python: `snapatac2.pp.import_fragments()` -> SnapATAC2 (spectral \u002F diffusion-map clustering)\n- CLI (preprocessing): `cellranger-atac count` (10X) or `chromap` (alignment-only fragment files)\n\n## Ecosystem Choice (The Most Important Decision)\n\n| Ecosystem | Language | Strength | Fails when | Best for |\n|-----------|---------|---------|------------|----------|\n| Signac (Stuart 2021) | R, Seurat-based | Tightest scRNA-seq integration; Seurat ecosystem mature | Memory hungry on >100K cells; slower than ArchR | Multiome RNA+ATAC; small-to-medium datasets; Seurat user |\n| ArchR (Granja 2021) | R, Arrow\u002FHDF5 | Memory-efficient (Arrow files); fast on 100K-1M cells; built-in trajectory + doublet | Less RNA-seq integration; ArchR-specific format | Large bulk-cohort scATAC; trajectory analysis; ATAC-only |\n| SnapATAC2 (Zhang 2024) | Python, AnnData | Memory-efficient; modern Python ecosystem; spectral clustering performant | Newer; benchmarks evolving; ecosystem smaller than R | Python-first labs; very large datasets (>1M cells) |\n| Cell Ranger ATAC | CLI (10X-specific) | 10X official preprocessing | Closed; fixed pipeline | Only as preprocessing step; analysis happens elsewhere |\n| scATAC-pro | CLI-based pipeline | Alternative preprocessing | Less maintained | Legacy; not recommended for new projects |\n\nMethodology evolves; verify against Granja 2021 (ArchR), Stuart 2021 (Signac), Zhang 2024 (SnapATAC2), Heumos 2023 (best practices) before locking pipelines.\n\n## 10X Multiome Caveat (Paired RNA + ATAC)\n\n10X Multiome chemistry profiles RNA AND ATAC from the same cell. Outputs are joined by a shared barcode. Multiome workflows use Signac for ATAC and Seurat for RNA, integrated through the same Seurat object via WNN (Weighted Nearest Neighbor; Hao 2021).\n\nSingle-modality 10X scATAC (chemistry v1, v2) does NOT produce paired RNA. Verify the chemistry on the cellranger summary before assuming Multiome.\n\n## Per-Cell QC Thresholds\n\n| Metric | Definition | Pass | Caution | Reject | Source |\n|--------|-----------|------|---------|--------|--------|\n| Fragment count per cell | n_fragments after dedup | 3000-50000 | 1000-3000 | \u003C 1000 or > 80000 | 10X recommendation; high = doublet |\n| TSS enrichment per cell | Signal at TSS \u002F flanks (per cell) | >= 4 | 2-4 | \u003C 2 | ArchR \u002F Signac default; lower than bulk because per-cell |\n| Nucleosome signal | Mono \u002F NFR fragment ratio | \u003C= 4 | 4-10 | > 10 | Signac default; high = poor library |\n| % reads in peaks (per cell) | FRiP per cell at consensus | >= 0.15 | 0.10-0.15 | \u003C 0.05 | ArchR \u002F Signac defaults |\n| Mitochondrial fraction (per cell) | chrM \u002F total per cell | \u003C 0.05 | 0.05-0.15 | > 0.20 | Lower than bulk; per-cell more sensitive |\n| Doublet score | AMULET \u002F ArchR doublet | \u003C 0.5 | 0.5-0.7 | > 0.7 | Tool-dependent threshold |\n| Blacklist ratio | Reads in ENCODE blacklist \u002F total | \u003C 0.05 | 0.05-0.10 | > 0.10 | Standard |\n\nPer-cell thresholds are looser than bulk because individual cells have orders of magnitude less signal; the population aggregate is what matters.\n\n## Doublet Detection: Three Approaches\n\n| Tool | Method | Strength | Fails when |\n|------|--------|---------|------------|\n| AMULET (Thibodeau 2021) | Collision-based: detects cells with too many fragments at same position (mathematically impossible from single cell because of 2-allele limit) | Specific to ATAC biology; orthogonal to clustering | Requires high depth; recall drops sharply below ~15-16K valid read pairs\u002Fcell (peaks ~90% near ~25K) |\n| ArchR addDoubletScores | Synthetic doublet simulation + projection into LSI | Built into ArchR; auto-thresholds | Tied to ArchR's LSI; not portable |\n| scDblFinder (Germain 2021) | Synthetic doublets + classifier | Works on Signac and SCE objects; well-benchmarked | RNA-developed; ATAC adaptation requires careful settings |\n\n**Operational rule:** Run AMULET as the primary ATAC-specific check; verify with ArchR or scDblFinder as orthogonal evidence. Double-flagged cells are high-confidence doublets.\n\n## Per-Tool Failure Modes\n\n### Signac TF-IDF + SVD -- First component is depth\n\n**Trigger:** Running `RunTFIDF` -> `RunSVD` and using all components for clustering.\n\n**Mechanism:** Component 1 of LSI is highly correlated with sequencing depth per cell, not biology. Including it pulls clusters along depth axis.\n\n**Symptom:** UMAP shows linear cell-density gradient that tracks fragment count.\n\n**Fix:** Skip component 1 in downstream UMAP and clustering: `RunUMAP(object, dims=2:30)`, `FindNeighbors(object, dims=2:30)`. ArchR and SnapATAC2 do this automatically.\n\n### ArchR -- TileMatrix vs PeakMatrix confusion\n\n**Trigger:** Using TileMatrix for differential testing or motif analysis.\n\n**Mechanism:** TileMatrix is regular fixed bins (default 500 bp) covering the whole genome; useful for clustering but not for biology because ATAC signal is at peaks, not arbitrary bins.\n\n**Fix:** Use TileMatrix for embedding\u002Fclustering (it's faster); use PeakMatrix (after `addReproduciblePeakSet`) for differential, motif, and gene-activity analysis.\n\n### SnapATAC2 -- Memory layout assumes integer counts\n\n**Trigger:** Loading non-integer or negative-valued matrices.\n\n**Fix:** SnapATAC2 expects raw fragment counts (Int32). Convert from float matrices before loading.\n\n### Cell Ranger ATAC -- Empty droplet detection\n\n**Trigger:** Default cellranger-atac calls cells based on UMI count but ATAC has no UMIs; uses fragment-based heuristic. Sometimes calls \u003C 1000-fragment cells as real.\n\n**Fix:** Re-filter cellranger output to require fragment count >= 1000 AND TSS enrichment >= 4 BEFORE downstream analysis.\n\n### Multiome WNN -- ATAC weighting\n\n**Trigger:** Default WNN equally weights RNA and ATAC modalities.\n\n**Mechanism:** ATAC's per-cell signal is much sparser than RNA; equal weighting can swamp the joint embedding with ATAC noise.\n\n**Fix:** Inspect per-modality weights with `IntegrateLayers`; if ATAC weights dominate noise, manually adjust or use `FindMultiModalNeighbors` carefully.\n\n### Per-cluster pseudobulk peak calling -- Empty clusters\n\n**Trigger:** Calling MACS3 per cluster when one cluster has \u003C 200 cells.\n\n**Mechanism:** MACS3 needs >= 1M reads in pseudobulk to call peaks reliably; small clusters do not produce enough reads.\n\n**Fix:** Aggregate small clusters into a \"rare\" group OR drop them from per-cluster calling. Use the union of larger-cluster peaks as a fallback for rare-cell-type analysis.\n\n## Decision Tree by Goal\n\n| Goal | Recommended pipeline |\n|------|---------------------|\n| Standard 10X scATAC analysis (R user) | Signac: CreateChromatinAssay -> RunTFIDF -> RunSVD -> RunUMAP (dims 2:30) -> FindClusters |\n| Standard 10X scATAC analysis (Python user) | SnapATAC2: pp.import_fragments -> add_tile_matrix -> spectral -> UMAP -> leiden |\n| Large dataset (> 100K cells) | ArchR (memory-efficient Arrow files) |\n| 10X Multiome (paired RNA + ATAC) | Signac + Seurat: per-modality embedding then WNN integration |\n| Trajectory \u002F pseudotime | ArchR getTrajectory; or Signac + Cicero |\n| Differential accessibility per cluster | Pseudobulk per cluster -> consensus peakset -> DESeq2 |\n| Cell-type annotation | Gene-activity scores via ArchR or Signac; then run `single-cell\u002Fmarkers-annotation` |\n| Multimodal trajectories (RNA + ATAC) | MOFA+, ArchR + scRNA integration, or SCENIC+ |\n| Plant \u002F non-model | Signac with custom EnsDb \u002F TxDb; ArchR with custom annotations |\n\n## Standard Signac Workflow\n\n**Goal:** Process 10X scATAC output into a clustered, annotated Seurat object with per-cell QC, embedding, and gene-activity scores.\n\n**Approach:** Load fragments and peak counts into a ChromatinAssay, compute per-cell QC (TSS enrichment, nucleosome signal, FRiP, blacklist), subset to passing cells, run TF-IDF + SVD + UMAP skipping LSI component 1, then derive a gene-activity assay for marker-based annotation.\n\n```r\nlibrary(Signac); library(Seurat); library(EnsDb.Hsapiens.v86)\nlibrary(BSgenome.Hsapiens.UCSC.hg38)\n\n# 1. Load 10X output\ncounts \u003C- Read10X_h5('outs\u002Ffiltered_peak_bc_matrix.h5')\nmetadata \u003C- read.csv('outs\u002Fsinglecell.csv', row.names=1)\n\nchrom_assay \u003C- CreateChromatinAssay(\n    counts=counts,\n    sep=c(':', '-'),\n    fragments='outs\u002Ffragments.tsv.gz',\n    annotation=GetGRangesFromEnsDb(EnsDb.Hsapiens.v86),\n    genome='hg38')\n\nobj \u003C- CreateSeuratObject(counts=chrom_assay, assay='ATAC', meta.data=metadata)\n\n# 2. Per-cell QC\nobj \u003C- NucleosomeSignal(obj)              # Mono\u002FNFR ratio\nobj \u003C- TSSEnrichment(obj, fast=FALSE)\nobj$pct_reads_in_peaks \u003C- obj$peak_region_fragments \u002F obj$passed_filters * 100\nobj$blacklist_ratio \u003C- obj$blacklist_region_fragments \u002F obj$peak_region_fragments\n\n# 3. QC filter (looser per-cell thresholds)\nobj \u003C- subset(obj,\n    subset = peak_region_fragments > 1000 & peak_region_fragments \u003C 20000 &\n             pct_reads_in_peaks > 15 & blacklist_ratio \u003C 0.05 &\n             nucleosome_signal \u003C 4 & TSS.enrichment > 4)\n\n# 4. Dimensionality reduction (skip component 1 - it's depth)\nobj \u003C- RunTFIDF(obj)\nobj \u003C- FindTopFeatures(obj, min.cutoff='q0')\nobj \u003C- RunSVD(obj)\nobj \u003C- RunUMAP(obj, reduction='lsi', dims=2:30)\nobj \u003C- FindNeighbors(obj, reduction='lsi', dims=2:30)\nobj \u003C- FindClusters(obj, algorithm=4, resolution=0.5)    # Leiden\n\n# 5. Gene-activity for annotation\ngene.activities \u003C- GeneActivity(obj)\nobj[['ACT']] \u003C- CreateAssayObject(counts=gene.activities)\nDefaultAssay(obj) \u003C- 'ACT'\nobj \u003C- NormalizeData(obj, normalization.method='LogNormalize',\n                     scale.factor=median(obj$nCount_ACT))\n```\n\n## Per-Cluster Pseudobulk Peak Calling\n\n```r\n# Signac wrapper around MACS3\npeaks \u003C- CallPeaks(obj, group.by='seurat_clusters',\n                   macs2.path='\u002Fpath\u002Fto\u002Fmacs3', cleanup=FALSE,\n                   format='BED', shift=-75, extsize=150,   # Tn5 cut-site recipe; shift only applies to format='BED'\n                   additional.args='-p 0.01')\n# Then iterative-overlap consensus across clusters (atac-seq\u002Fconsensus-peakset)\n```\n\n## ArchR Workflow\n\n**Goal:** Build an ArchR project from fragment files, filter doublets, cluster, and call per-cluster reproducible peaks.\n\n**Approach:** Create Arrow files with minimum TSS and fragment thresholds, score doublets and filter, run iterative LSI + UMAP + clustering on the TileMatrix, then build per-cluster group coverages and a reproducible peakset via MACS3.\n\n```r\nlibrary(ArchR)\naddArchRGenome('hg38')\n\n# 1. Create Arrow files from fragment files\nArrowFiles \u003C- createArrowFiles(\n    inputFiles=c('fragments_rep1.tsv.gz', 'fragments_rep2.tsv.gz'),\n    sampleNames=c('rep1', 'rep2'),\n    minTSS=4, minFrags=1000,\n    addTileMat=TRUE, addGeneScoreMat=TRUE)\n\n# 2. Doublet detection (built-in)\ndoubletScores \u003C- addDoubletScores(input=ArrowFiles, k=10, knnMethod='UMAP')\n\n# 3. Project + filter\nproj \u003C- ArchRProject(ArrowFiles=ArrowFiles, outputDirectory='ArchR_out')\nproj \u003C- filterDoublets(proj)\n\n# 4. LSI + UMAP + clustering\nproj \u003C- addIterativeLSI(proj, useMatrix='TileMatrix', name='IterativeLSI')\nproj \u003C- addClusters(proj, reducedDims='IterativeLSI', method='Seurat', resolution=0.5)\nproj \u003C- addUMAP(proj, reducedDims='IterativeLSI')\n\n# 5. Reproducible peakset (per cluster)\nproj \u003C- addGroupCoverages(proj, groupBy='Clusters')\nproj \u003C- addReproduciblePeakSet(proj, groupBy='Clusters', pathToMacs2='\u002Fpath\u002Fmacs3')\nproj \u003C- addPeakMatrix(proj)\n```\n\n## SnapATAC2 Workflow (Python)\n\n**Goal:** Run a Python-native scATAC pipeline from fragments through clusters, per-cluster peaks, and gene activity.\n\n**Approach:** Import fragments to a backed AnnData, compute per-cell TSS enrichment and fragment-size metrics, filter cells, build a tile matrix, run spectral embedding + UMAP + Leiden, call per-cluster peaks via MACS3, and derive a gene-activity matrix.\n\n```python\nimport snapatac2 as snap\n\n# 1. Load 10X fragments. SnapATAC2 uses snap.pp.import_fragments (NOT snap.read_10x, which doesn't exist).\ndata = snap.pp.import_fragments(\n    fragment_file='outs\u002Ffragments.tsv.gz',\n    chrom_sizes=snap.genome.hg38,\n    file='out.h5ad',                        # backed AnnData; backend handled by file path\n    sorted_by_barcode=False)\ndata.obs['sample_id'] = 'rep1'\n\n# 2. Per-cell QC\nsnap.metrics.tsse(data, gene_anno=snap.genome.hg38)\nsnap.metrics.frag_size_distr(data)\nsnap.pp.filter_cells(data, min_counts=1000, min_tsse=4)\n\n# 3. Tile matrix + spectral\nsnap.pp.add_tile_matrix(data, bin_size=500)\nsnap.pp.select_features(data, n_features=250000)\nsnap.tl.spectral(data)\nsnap.tl.umap(data)\nsnap.tl.leiden(data)\n\n# 4. Per-cluster peak calling (uses MACS3)\nsnap.tl.macs3(data, groupby='leiden')\n\n# 5. Gene activity (gene score) for annotation\ngene_mat = snap.pp.make_gene_matrix(data, gene_anno=snap.genome.hg38)\n```\n\n## Reconciliation Across Tools\n\n| Pattern | Likely cause | Action |\n|---------|--------------|--------|\n| Signac UMAP shows tight clusters; ArchR UMAP shows loose | Different LSI implementation; ArchR uses iterative LSI by default | Both valid; biology should match in cluster labels |\n| Different tools call different doublet rates | Different algorithms (collision vs simulation) | Use intersection (cells flagged by 2+ tools) as high-confidence doublets |\n| Cluster boundaries differ | Different clustering algorithm or resolution | Standardize on Leiden algorithm 4 with same resolution |\n| Per-cluster peak count differs | Different peak callers or pseudobulk depth | Ensure same MACS3 parameters; pool small clusters |\n\n**Operational rule:** For high-confidence cell-type annotation, agree across two ecosystems (e.g., Signac + ArchR clusters) and report agreement metrics.\n\n## cellranger-atac vs cellranger-arc\n\n| Pipeline | Use for | Output |\n|----------|---------|--------|\n| cellranger-atac | Single-modality 10X scATAC (chemistry v1, v2) | per-cell ATAC barcodes; fragments.tsv.gz; per-barcode metadata |\n| cellranger-arc | 10X Multiome (paired RNA + ATAC same cell, \"Multiome chemistry\") | joint barcodes for RNA + ATAC; separate fragment \u002F count files; one barcode whitelist |\n\n**Trigger:** Loading 10X output without checking which pipeline produced it.\n\n**Mechanism:** cellranger-atac and cellranger-arc produce different output structures. cellranger-arc fragments.tsv has barcodes paired with the RNA matrix; cellranger-atac fragments are ATAC-only with their own barcode universe.\n\n**Fix:** Verify the chemistry on the cellranger summary (look for \"Multiome\" in the run config). Use `Read10X_h5` for cellranger-arc Multiome RNA output; use `CreateChromatinAssay` with the matched fragments for the ATAC. Mixing barcodes across pipelines fails silently.\n\n## Cell-Cycle Correction for scATAC\n\n**Trigger:** Proliferating cell types in the dataset; cells distributed across cell cycle phases.\n\n**Mechanism:** Replication-associated chromatin opening adds 5-10% global accessibility per cell as it moves G1 -> S -> G2\u002FM; this confounds clustering and DA.\n\n**Detection:** Score cells with a chromatin-adapted S-phase signature (regulated origin loci, replication-stress-response gene accessibility) analogous to Seurat's CellCycleScoring on RNA. Or compute a Repli-seq peak overlap score.\n\n**Fix:** Regress S-phase score on the TF-IDF residuals before downstream LSI: `ScaleData(obj, vars.to.regress='S.score')` analogous to RNA workflow. For DA between cell-cycle-mismatched conditions, add S-phase as covariate in pseudobulk DESeq2.\n\n## Sex-Chromosome QC for scATAC\n\n**Trigger:** Mixed-sex donors in the dataset; sample-swap detection.\n\n**Mechanism:** XIST locus accessibility is high in female cells (X-inactivation); chrY peak count is essentially zero in females. Per-cell or per-sample, the XIST\u002FchrY ratio identifies sex unambiguously.\n\n**Detection:** In a per-cell counts matrix, compute fraction of fragments at XIST locus (chrX:73820651-73852753 hg38) and chrY peak count; classify cells; flag cells\u002Fsamples where assignment disagrees with metadata.\n\n**XCI escapees:** Genes that escape X-inactivation (KDM6A, DDX3X, EIF1AX) are biallelically accessible in female cells but not male; can be used as additional sex confirmation if XIST is ambiguous.\n\n## scArches Reference Mapping\n\n**Trigger:** Projecting query scATAC onto a reference atlas; cross-study integration without batch effects.\n\n**Mechanism:** scArches (Lotfollahi 2022) provides transfer-learning to project a new dataset onto an existing reference's latent space without retraining the reference. For ATAC, the relevant model is PEAKVI (Ashuach 2022). PEAKVI lives in `scvi-tools` (`scvi.model.PEAKVI`); the `load_query_data` classmethod implements the scArches algorithm directly, so an explicit `import scarches` is not required.\n\n```python\nimport scvi\n\n# Pre-trained reference model (e.g. PBMC scATAC atlas)\nquery_model = scvi.model.PEAKVI.load_query_data(adata_query, reference_path)\nquery_model.train(max_epochs=200)\nadata_query.obsm['X_emb'] = query_model.get_latent_representation()\n```\n\nReference atlases for ATAC are still emerging; the most-developed are PBMC (Granja 2021) and brain (BRAIN Initiative).\n\n## chromBPNet Per-Cluster Pseudobulk\n\n**Trigger:** Cell-type-specific variant effect prediction; per-cluster bias-corrected calling.\n\n**Mechanism:** Train chromBPNet (atac-seq\u002Fdeep-learning-atac) per pseudobulk cluster; outputs are bias-corrected per-base profiles + variant effect predictions specific to that cell type.\n\n**Workflow:** Aggregate fragments per cluster into pseudobulk BAMs; run chromBPNet pipeline per cluster (~24h GPU per cluster); use the resulting model for in silico variant scoring at GWAS \u002F rare-variant SNPs in that cell type.\n\nFor most studies, this is reserved for top 5-10 priority clusters; running chromBPNet per cluster on >20 cell types is computationally heavy.\n\n## AMULET Depth Threshold\n\nAMULET reaches maximum recall (~90%) near ~25,000 valid read pairs (~fragments) per cell and degrades sharply below ~15,000-16,000, where the collision-based detection has insufficient power: the expected number of collisions per cell is too small for the binomial test to distinguish doublet from singleton. For lower-depth libraries, use synthetic-doublet methods (ArchR addDoubletScores, scDblFinder) instead.\n\n## Multiome WNN Integration (Signac)\n\n**Goal:** Build a joint RNA + ATAC embedding from a 10X Multiome dataset using Weighted Nearest Neighbors.\n\n**Approach:** Run per-modality embeddings (PCA on RNA, TF-IDF + SVD on ATAC skipping LSI-1), then use FindMultiModalNeighbors to learn per-cell modality weights and project a joint UMAP.\n\n```r\n# Assume `obj` has both 'RNA' and 'ATAC' assays from same Multiome experiment\nDefaultAssay(obj) \u003C- 'RNA'\nobj \u003C- NormalizeData(obj) %>% FindVariableFeatures() %>% ScaleData() %>% RunPCA()\n\nDefaultAssay(obj) \u003C- 'ATAC'\nobj \u003C- RunTFIDF(obj) %>% FindTopFeatures(min.cutoff='q0') %>% RunSVD()\n\n# Joint embedding\nobj \u003C- FindMultiModalNeighbors(obj, reduction.list=list('pca', 'lsi'),\n                               dims.list=list(1:30, 2:30))\nobj \u003C- RunUMAP(obj, nn.name='weighted.nn', reduction.name='wnn.umap')\n```\n\n## Common Errors\n\n| Error \u002F symptom | Cause | Solution |\n|-----------------|-------|----------|\n| UMAP shows depth gradient | LSI component 1 included in clustering | `dims=2:30` instead of `1:30` |\n| Cell Ranger output has many low-quality cells | cellranger ATAC uses lenient cell calling | Re-filter at fragment count >= 1000 + TSS enrichment >= 4 |\n| ArchR \"TileMatrix not found\" | Forgot `addTileMat=TRUE` in createArrowFiles | Re-create Arrow files with the flag |\n| Signac CreateChromatinAssay fails on missing fragments file | Path to fragments.tsv.gz incorrect; or missing tabix index | Provide full path; run `tabix -p bed fragments.tsv.gz` |\n| MACS3 fails on tiny pseudobulk | Cluster too small | Use cluster aggregation; require >= 200 cells per cluster |\n| AMULET reports 100% doublets | Threshold mis-set or input is technical replicates | Check fragment-count distribution; AMULET needs high depth (recall peaks near ~25K valid read pairs\u002Fcell) |\n| Multiome WNN clusters dominated by ATAC noise | Equal modality weighting | Inspect modality weights; manually adjust if needed |\n| chromVAR \u002F motif assay all NA | Run before peakset finalized | Re-run AddMotifs \u002F RunChromVAR after peaks stable |\n| EnsDb \u002F BSgenome version mismatch | hg38 BSgenome with wrong-build EnsDb | Match builds; `EnsDb.Hsapiens.v86` is GRCh38 (Ensembl v86); use `EnsDb.Hsapiens.v75` for hg19. Newer hg38 EnsDb releases (v98+) reflect newer GENCODE annotations |\n\n## References\n\n- Stuart T et al 2021 Nat Methods 18:1333 (Signac)\n- Granja JM et al 2021 Nat Genet 53:403 (ArchR)\n- Zhang K et al 2024 Nat Methods 21:217 (SnapATAC2)\n- Hao Y et al 2021 Cell 184:3573 (Seurat WNN)\n- Thibodeau A et al 2021 Genome Biol 22:252 (AMULET doublet detection)\n- Germain PL et al 2021 F1000Res 10:979 (scDblFinder)\n- Cusanovich DA et al 2015 Science 348:910 (sciATAC; LSI for sc data)\n- Chen H et al 2019 Genome Biol 20:241 (scATAC analysis benchmark)\n- Heumos L et al 2023 Nat Rev Genet 24:550 (Best practices for single-cell)\n- 10X Genomics Cell Ranger ATAC documentation\n\n## Related Skills\n\n- atac-seq\u002Fatac-qc - Bulk QC patterns adapted for per-cell\n- atac-seq\u002Fatac-peak-calling - Pseudobulk peak calling per cluster\n- atac-seq\u002Fconsensus-peakset - Across-cluster consensus\n- atac-seq\u002Fdifferential-accessibility - Pseudobulk DA per cluster\n- atac-seq\u002Fmotif-deviation - chromVAR for per-cell TF activity\n- atac-seq\u002Ffootprinting - scprinter for sc footprinting\n- atac-seq\u002Fco-accessibility - Cicero for cis-regulatory connections\n- atac-seq\u002Fdeep-learning-atac - chromBPNet \u002F scBasset for per-cluster bias correction and variant effects\n- atac-seq\u002Fenhancer-gene-linking - Per-cell-type enhancer-gene maps\n- atac-seq\u002Fallele-specific-accessibility - sc allelic imbalance for cis-effects\n- single-cell\u002Fpreprocessing - General sc QC patterns\n- single-cell\u002Fclustering - Cluster definition\n- single-cell\u002Fcell-annotation - Automated reference-based label transfer\n- single-cell\u002Fmultimodal-integration - Multiome RNA+ATAC integration\n- single-cell\u002Fscatac-analysis - Cross-reference single-cell ATAC-specific patterns\n- single-cell\u002Fbatch-integration - scArches reference mapping; Harmony\n",{"name":5,"source":24,"license":15,"tool_type":25,"description":7,"imported_at":26,"source_path":27,"primary_tool":28,"source_repository":29},"https:\u002F\u002Fgithub.com\u002FGPTomics\u002FbioSkills","mixed","2026-09-20","atac-seq\u002Fsingle-cell-atac\u002FSKILL.md","Signac","GPTomics\u002FbioSkills","main","2d1750717747097b602acf30bd09a7cbd4b4c6ea","awesome_skills\u002Fbiology\u002Fbio-atac-seq-single-cell-atac","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous","2026-11-09 11:45:36",{"source":8,"skillName":5,"commands":37,"prompt":47,"zipAvailable":48},[38,41,44],{"tool":39,"command":40},"npx","npx skills add Mr-Nobody-Anonymous\u002FAll-skills --skill bio-atac-seq-single-cell-atac",{"tool":42,"command":43},"bunx","bunx skills add Mr-Nobody-Anonymous\u002FAll-skills --skill bio-atac-seq-single-cell-atac",{"tool":45,"command":46},"pnpm","pnpm dlx skills add Mr-Nobody-Anonymous\u002FAll-skills --skill bio-atac-seq-single-cell-atac","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fbiology\u002Fbio-atac-seq-single-cell-atac\u002FSKILL.md",true,[50,56],{"path":51,"resourceType":52,"resourceTypeDesc":53,"sizeBytes":54,"sourceHtmlUrl":55},"examples\u002Fsignac_workflow.R","OTHER","其他",3782,"https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fbiology\u002Fbio-atac-seq-single-cell-atac\u002Fexamples\u002Fsignac_workflow.R",{"path":57,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":60,"sourceHtmlUrl":61},"usage-guide.md","REFERENCE","参考文档",7808,"https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fbiology\u002Fbio-atac-seq-single-cell-atac\u002Fusage-guide.md",[63,71,78,85,92,99],{"skillNo":64,"name":65,"nameZh":6,"description":66,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":67,"categories":68,"keywords":69,"publishedAt":70},"01M7EXRQF9GFM7D9BG6N5HAT34","oath","Auditing regulatory compliance (SOC2\u002FPCI-DSS\u002FHIPAA\u002FISO 27001): maps requirements, checks controls, designs audit trails, implements Policy as Code. Use when compliance auditing is needed.","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fdevsecops\u002Foath\u002FSKILL.md",[],[],"2026-11-15 14:25:24",{"skillNo":72,"name":73,"nameZh":6,"description":74,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":75,"categories":76,"keywords":77,"publishedAt":19},"01M7EXRH7TYTNZJT0BQXEWAMW7","nexus","Orchestrating multi-specialist task chains and scope-adaptive product delivery: classifies intent, selects and executes the minimum viable chain, aggregates results, and verifies acceptance criteria. For multi-domain tasks, build-first delivery, and product lifecycle execution.","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fdevsecops\u002Fnexus\u002FSKILL.md",[],[],{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":19},"01M7EXRCDPFWVEEEFR2ZQGJCYY","nest","Designing LLM-optimized folder structures: audits and restructures directories for context efficiency, progressive disclosure, and prompt cache performance. Not for general repo structure (Grove).","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fdevsecops\u002Fnest\u002FSKILL.md",[],[],{"skillNo":86,"name":87,"nameZh":6,"description":88,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":89,"categories":90,"keywords":91,"publishedAt":19},"01M7EXR7JEER60TH0HD0AH4EE9","native","Implementing production iOS\u002FAndroid\u002FmacOS native features (SwiftUI, Compose) and iterating a screen against a reference design. Not for cross-platform RN\u002FFlutter (Port) or web (Artisan).","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fdevsecops\u002Fnative\u002FSKILL.md",[],[],{"skillNo":93,"name":94,"nameZh":6,"description":95,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":98,"publishedAt":19},"01M7EXR133J7DD5961R80QTRZY","muse","Defining and managing design tokens, applying token systems to existing codebases, building design system foundations. Use for spacing, color, typography, dark mode, cross-platform output.","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fdevsecops\u002Fmuse\u002FSKILL.md",[],[],{"skillNo":100,"name":101,"nameZh":6,"description":102,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":103,"categories":104,"keywords":105,"publishedAt":19},"01M7EXQWWX7ECQN0J50B41YN5N","morph","Converting document formats (Markdown\u002FWord\u002FExcel\u002FPDF\u002FHTML) and generating reusable conversion scripts. Use for distributable specs, accessibility-compliant PDFs, or Pandoc\u002FLibreOffice pipelines.","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fdevsecops\u002Fmorph\u002FSKILL.md",[],[]]