{
  "schema": "https://ai-atoms.com/schemas/skill-v1.json",
  "type": "skill",
  "id": "skill/single-cell-rna-qc",
  "version": "1.0.0",
  "name": "single-cell-rna-qc",
  "description": "Performs quality control on single-cell RNA-seq data (.h5ad or .h5 files) using scverse best practices with MAD-based filtering and comprehensive visualizations. Use when users request QC analysis, filtering low-quality cells, assessing data quality, or following scverse/scanpy best practices for single-cell analysis.",
  "system_prompt_fragment": "# Single-Cell RNA-seq Quality Control\n\nAutomated QC workflow for single-cell RNA-seq data following scverse best practices.\n\n## When to Use This Skill\n\nUse when users:\n- Request quality control or QC on single-cell RNA-seq data\n- Want to filter low-quality cells or assess data quality\n- Need QC visualizations or metrics\n- Ask to follow scverse/scanpy best practices\n- Request MAD-based filtering or outlier detection\n\n**Supported input formats:**\n- `.h5ad` files (AnnData format from scanpy/Python workflows)\n- `.h5` files (10X Genomics Cell Ranger output)\n\n**Default recommendation**: Use Approach 1 (complete pipeline) unless the user has specific custom requirements or explicitly requests non-standard filtering logic.\n\n## Approach 1: Complete QC Pipeline (Recommended for Standard Workflows)\n\nFor standard QC following scverse best practices, use the convenience script `scripts/qc_analysis.py`:\n\n```bash\npython3 scripts/qc_analysis.py input.h5ad\n# or for 10X Genomics .h5 files:\npython3 scripts/qc_analysis.py raw_feature_bc_matrix.h5\n```\n\nThe script automatically detects the file format and loads it appropriately.\n\n**When to use this approach:**\n- Standard QC workflow with adjustable thresholds (all cells filtered the same way)\n- Batch processing multiple datasets\n- Quick exploratory analysis\n- User wants the \"just works\" solution\n\n**Requirements:** anndata, scanpy, scipy, matplotlib, seaborn, numpy\n\n**Parameters:**\n\nCustomize filtering thresholds and gene patterns using command-line parameters:\n- `--output-dir` - Output directory\n- `--mad-counts`, `--mad-genes`, `--mad-mt` - MAD thresholds for counts/genes/MT%\n- `--mt-threshold` - Hard mitochondrial % cutoff\n- `--min-cells` - Gene filtering threshold\n- `--mt-pattern`, `--ribo-pattern`, `--hb-pattern` - Gene name patterns for different species\n\nUse `--help` to see current default values.\n\n**Outputs:**\n\nAll files are saved to `<input_basename>_qc_results/` directory by default (or to the directory specified by `--output-dir`):\n- `qc_metrics_before_filtering.png` - Pre-filtering visualizations\n- `qc_filtering_thresholds.png` - MAD-based threshold overlays\n- `qc_metrics_after_filtering.png` - Post-filtering quality metrics\n- `<input_basename>_filtered.h5ad` - Clean, filtered dataset ready for downstream analysis\n- `<input_basename>_with_qc.h5ad` - Original data with QC annotations preserved\n\nIf copying outputs for user access, copy individual files (not the entire directory) so users can preview them directly.\n\n### Workflow Steps\n\nThe script performs the following steps:\n\n1. **Calculate QC metrics** - Count depth, gene detection, mitochondrial/ribosomal/hemoglobin content\n2. **Apply MAD-based filtering** - Permissive outlier detection using MAD thresholds for counts/genes/MT%\n3. **Filter genes** - Remove genes detected in few cells\n4. **Generate visualizations** - Comprehensive before/after plots with threshold overlays\n\n## Approach 2: Modular Building Blocks (For Custom Workflows)\n\nFor custom analysis workflows or non-standard requirements, use the modular utility functions from `scripts/qc_core.py` and `scripts/qc_plotting.py`:\n\n```python\n# Run from scripts/ directory, or add scripts/ to sys.path if needed\nimport anndata as ad\nfrom qc_core import calculate_qc_metrics, detect_outliers_mad, filter_cells\nfrom qc_plotting import plot_qc_distributions  # Only if visualization needed\n\nadata = ad.read_h5ad('input.h5ad')\ncalculate_qc_metrics(adata, inplace=True)\n# ... custom analysis logic here\n```\n\n**When to use this approach:**\n- Different workflow needed (skip steps, change order, apply different thresholds to subsets)\n- Conditional logic (e.g., filter neurons differently than other cells)\n- Partial execution (only metrics/visualization, no filtering)\n- Integration with other analysis steps in a larger pipeline\n- Custom filtering criteria beyond what command-line params support\n\n**Available utility functions:**\n\nFrom `qc_core.py` (core QC operations):\n- `calculate_qc_metrics(adata, mt_pattern, ribo_pattern, hb_pattern, inplace=True)` - Calculate QC metrics and annotate adata\n- `detect_outliers_mad(adata, metric, n_mads, verbose=True)` - MAD-based outlier detection, returns boolean mask\n- `apply_hard_threshold(adata, metric, threshold, operator='>', verbose=True)` - Apply hard cutoffs, returns boolean mask\n- `filter_cells(adata, mask, inplace=False)` - Apply boolean mask to filter cells\n- `filter_genes(adata, min_cells=20, min_counts=None, inplace=True)` - Filter genes by detection\n- `print_qc_summary(adata, label='')` - Print summary statistics\n\nFrom `qc_plotting.py` (visualization):\n- `plot_qc_distributions(adata, output_path, title)` - Generate comprehensive QC plots\n- `plot_filtering_thresholds(adata, outlier_masks, thresholds, output_path)` - Visualize filtering thresholds\n- `plot_qc_after_filtering(adata, output_path)` - Generate post-filtering plots\n\n**Example custom workflows:**\n\n**Example 1: Only calculate metrics and visualize, don't filter yet**\n```python\nadata = ad.read_h5ad('input.h5ad')\ncalculate_qc_metrics(adata, inplace=True)\nplot_qc_distributions(adata, 'qc_before.png', title='Initial QC')\nprint_qc_summary(adata, label='Before filtering')\n```\n\n**Example 2: Apply only MT% filtering, keep other metrics permissive**\n```python\nadata = ad.read_h5ad('input.h5ad')\ncalculate_qc_metrics(adata, inplace=True)\n\n# Only filter high MT% cells\nhigh_mt = apply_hard_threshold(adata, 'pct_counts_mt', 10, operator='>')\nadata_filtered = filter_cells(adata, ~high_mt)\nadata_filtered.write('filtered.h5ad')\n```\n\n**Example 3: Different thresholds for different subsets**\n```python\nadata = ad.read_h5ad('input.h5ad')\ncalculate_qc_metrics(adata, inplace=True)\n\n# Apply type-specific QC (assumes cell_type metadata exists)\nneurons = adata.obs['cell_type'] == 'neuron'\nother_cells = ~neurons\n\n# Neurons tolerate higher MT%, other cells use stricter threshold\nneuron_qc = apply_hard_threshold(adata[neurons], 'pct_counts_mt', 15, operator='>')\nother_qc = apply_hard_threshold(adata[other_cells], 'pct_counts_mt', 8, operator='>')\n```\n\n## Best Practices\n\n1. **Be permissive with filtering** - Default thresholds intentionally retain most cells to avoid losing rare populations\n2. **Inspect visualizations** - Always review before/after plots to ensure filtering makes biological sense\n3. **Consider dataset-specific factors** - Some tissues naturally have higher mitochondrial content (e.g., neurons, cardiomyocytes)\n4. **Check gene annotations** - Mitochondrial gene prefixes vary by species (mt- for mouse, MT- for human)\n5. **Iterate if needed** - QC parameters may need adjustment based on the specific experiment or tissue type\n\n## Reference Materials\n\nFor detailed QC methodology, parameter rationale, and troubleshooting guidance, see `references/scverse_qc_guidelines.md`. This reference provides:\n- Detailed explanations of each QC metric and why it matters\n- Rationale for MAD-based thresholds and why they're better than fixed cutoffs\n- Guidelines for interpreting QC visualizations (histograms, violin plots, scatter plots)\n- Species-specific considerations for gene annotations\n- When and how to adjust filtering parameters\n- Advanced QC considerations (ambient RNA correction, doublet detection)\n\nLoad this reference when users need deeper understanding of the methodology or when troubleshooting QC issues.\n\n## Next Steps After QC\n\nTypical downstream analysis steps:\n- Ambient RNA correction (SoupX, CellBender)\n- Doublet detection (scDblFinder)\n- Normalization (log-normalize, scran)\n- Feature selection and dimensionality reduction\n- Clustering and cell type annotation",
  "applicable_domains": [
    "research",
    "science"
  ],
  "invocation": [
    "/single-cell-rna-qc"
  ],
  "tags": [
    "bio-research",
    "anthropics",
    "knowledge-work"
  ],
  "authored_by": "anthropics",
  "source_url": "https://github.com/anthropics/knowledge-work-plugins/blob/main/bio-research/skills/single-cell-rna-qc/SKILL.md",
  "lifecycle": "stable",
  "category": "data",
  "provenance": {
    "source": "anthropics/knowledge-work-plugins",
    "source_url": "https://github.com/anthropics/knowledge-work-plugins/blob/main/bio-research/skills/single-cell-rna-qc/SKILL.md",
    "author": "Anthropic",
    "license": "Apache-2.0",
    "notes": "Imported by scripts/import-anthropic-skills.py."
  }
}