scrna-preprocessing-clustering — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited scrna-preprocessing-clustering (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Reference examples assume:
scanpy 1.10+anndata 0.10+pandas 2.2+matplotlib 3.8+Before using code patterns, verify installed versions match the environment:
python -c "import scanpy, anndata; print(scanpy.__version__, anndata.__version__)"Use this skill to turn raw or minimally processed scRNA-seq data into an analysis-ready object with:
h5ad artifact for annotation, DE, integration, or trajectory analysish5ad inputs need standard preprocessingh5ad, inspect adata.raw, embeddings, cluster columns, and QC columns before rerunning preprocessing.adata.raw = adata.copy() before regression or scaling..pdf or .svg for final figures when possible..h5, .h5ad, or count matrixresults/processed.h5adqc/cell_qc_metrics.tsvqc/gene_qc_metrics.tsvfigures/qc_violin.pdffigures/pca_variance_ratio.pdffigures/umap_leiden.pdfscanpyanndatapandasmatplotlibseabornimport scanpy as sc
adata = sc.read_10x_mtx("counts/")
adata.var_names_make_unique()
adata.var["mt"] = adata.var_names.str.upper().str.startswith("MT-")
sc.pp.calculate_qc_metrics(adata, qc_vars=["mt"], inplace=True)
adata = adata[
(adata.obs["n_genes_by_counts"] >= 200)
& (adata.obs["n_genes_by_counts"] <= 6000)
& (adata.obs["pct_counts_mt"] < 15),
:
].copy()
sc.pp.filter_genes(adata, min_cells=3)
sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)
adata.raw = adata.copy()
sc.pp.highly_variable_genes(adata, n_top_genes=3000, flavor="seurat_v3")
adata = adata[:, adata.var["highly_variable"]].copy()
sc.pp.scale(adata, max_value=10)
sc.tl.pca(adata, svd_solver="arpack")
sc.pp.neighbors(adata, n_neighbors=15, n_pcs=30)
sc.tl.umap(adata)
sc.tl.leiden(adata, resolution=0.5, key_added="leiden_r05")
adata.write("results/processed.h5ad")n_genes_by_countstotal_countspct_counts_mtPlot distributions before filtering. Thresholds vary by chemistry, tissue, and nucleus versus whole-cell assay.
Use dataset-aware thresholds. Good first-pass defaults:
min_genes >= 200max_genes <= 5000-8000 to remove likely doublets in many droplet datasetspct_counts_mt < 10-20 depending on tissue stressmin_cells >= 3 for genestarget_sum=1e4log1p2000-4000 HVGs10-30 PCs and 10-30 neighbors as a starting range0.2, 0.5, 0.8, 1.0Always save:
h5adresults/processed.h5ad: main reusable AnnData objectresults/cluster_assignments.tsv: barcode plus cluster labelsqc/filter_summary.tsv: counts before and after filteringfigures/umap_leiden.pdf: main embedding figureanndatascanpy~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.