本文へ移動
cccskills
無料GitHub で公開

bio-imaging-mass-cytometry-quality-metrics

Quality control for IMC/MIBI data across pixel, channel, image, slide, and batch levels, covering Poisson-count SNR (cell-level Gaussian-mixture and empty-channel comparison), spillover-matrix QC (the three physical sources), drift and the missing EQ-bead analog, acquisition artifacts, and sample-of-origin batch effects. Use when deciding whether to keep or drop a channel, ROI, or slide, distinguishing a dim antibody from a failed one, reading a spillover matrix, or diagnosing batch-driven clustering before analysis.

インストール方法を見る

含まれるファイル(3)

  • SKILL.md14.2 KB
  • examples/run_qc.py2.9 KB
  • usage-guide.md3.5 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Version Compatibility

Reference examples tested with: numpy 1.26+, scikit-learn 1.4+, scanpy 1.10+, CATALYST 1.28+ (R), spillR 1.0+ (R)

Before using code patterns, verify installed versions match. If versions differ:

  • Python: pip show <package> then help(module.function) to check signatures
  • R: packageVersion('<pkg>') then ?function_name to verify parameters

If code throws ImportError, AttributeError, or TypeError, introspect the installed package and adapt the example to match the actual API rather than retrying.

Notes specific to this skill: IMC values are integer ion (dual) counts, so SNR must respect Poisson statistics, not fluorescence intuition; biology lives in 1-2 count differences. There is no EQ-bead in-line drift normalizer for ablated tissue. CATALYST normCytof is for SUSPENSION bead normalization, not IMC images -- do not apply it to image data. Compensate raw pixels before transformation.

IMC Quality Metrics

"Assess the quality of my IMC acquisition" -> Gate the data at the level each failure lives at -- pixel, channel, image, slide, batch -- before analysis, not by normalizing after.

  • Python: numpy/scikit-learn for SNR, artifacts, batch diagnosis
  • R: CATALYST::plotSpillmat, spillR for spillover QC

The Single Most Important Modern Insight -- QC is multi-level, and every metric is blind at some level

IMC/MIBI QC is not one number. The data live in a Poisson ion-count regime where "noise" has a defined statistical meaning, and the failures that actually destroy an experiment -- a dead antibody, an unbalanced batch, cells that cluster by which slide they came from rather than by phenotype -- are panel/staining/batch problems that are invisible to per-image SNR. So a single metric is always blind at some level, and the discipline is to gate (drop a channel, ROI, or slide) before analysis rather than normalize after, because correction moves a distribution but never creates the positive/negative separation that staining never produced. Three corollaries a postdoc internalizes. (1) Counts are Poisson: a real floor-abundance epitope genuinely yields a few counts, so "2 counts" is signal or noise depending on dwell, area, and the aggregation level -- SNR grows as sqrt(N) when pixels are pooled into a cell. (2) Dim is not failed: a correctly-titrated antibody to a sparse antigen is supposed to be dim; failure is INSEPARABILITY of positive and negative populations, judged against a known-empty channel, not low absolute intensity. (3) IMC has no EQ-bead drift normalizer -- ablated fixed tissue cannot be spiked with calibration beads, so the only honest cross-batch yardstick is an anchor reference sample included in every run (Casanova 2025), and the absence of an in-line standard is itself expert knowledge.

Multi-Level QC Framework

LevelWhat to measureCharacteristic failureBlind to
Pixelhot pixels, shot noise, dynamic rangedetector spikes; Poisson noise on dim signalwhether the channel is biologically real
Channel (marker)cell-level SNR, spillover in/out, vs empty channeldead antibody, crosstalk, oxide/+-1 leakspatial artifacts, batch
Image / ROImean intensity, cell coverage, ablation completenessfailed ablation, folding, off-target ROIcross-sample comparability
Slide / acquisitiondetector drift over time, tune (Lu duals)within-run sensitivity decay, mis-tunebetween-slide offset
Batch / cohortsample-of-origin clustering, lot effectsthe cohort clusters by batch not biologynothing -- the top level

Decision Tree by Scenario

ObservationDecisionBasis
Cell-level positive/negative mixture won't separate; signal ~ empty/80ArAr channelDROP (failed antibody)inseparability, not intensity
Low absolute counts but clean separation, pattern matches biology + control tissueKEEP (dim-but-real); use at aggregated levelsdim != failed
High signal, low SNR (everything "positive")DROP or re-titratenon-specific binding
Heavy +16 oxide or impurity from a co-expressed partnerDROP or re-mass the panelunrescuable by compensation
Striping / incomplete-ablation bandingDROP the ROIphysical failure, not correctable noise
DNA/Ir dropout over a regionMASK the region, keep the restnon-ablation/tissue loss
Tune fails (Lu duals below panel criterion)RE-TUNE / re-acquireinstrument not in spec
Cells cluster by slide/patient not phenotypebatch-correct; if it won't mix, the contrast is confoundedsample-of-origin effect

Cell-Level SNR (the decision-relevant number)

Goal: Judge marker adequacy at the unit of analysis (the cell), in a count-aware way.

Approach: Fit a two-component Gaussian mixture to per-cell mean counts (on non-transformed counts) and take mean(positive)/mean(negative); a failed antibody is one whose components do not separate, regardless of brightness. Compare the distribution to a known-empty channel as the operational "did this antibody work" test.

import numpy as np
from sklearn.mixture import GaussianMixture

def cell_snr(per_cell_counts):
    # two-component mixture on raw per-cell means: separation, not brightness, defines success
    gm = GaussianMixture(n_components=2, random_state=0).fit(per_cell_counts.reshape(-1, 1))
    pos, neg = np.sort(gm.means_.ravel())[::-1]
    return pos / neg if neg > 0 else np.inf

def matches_empty(channel_counts, empty_channel_counts, q=95, tol=2.0):
    # compare the POSITIVE tail (q-th percentile), not the median: a real-but-sparse marker
    # carries its signal in the tail while a failed channel's tail sits at the empty floor.
    # True -> indistinguishable from 80ArAr / an unconjugated lanthanide -> the honest "failed" test
    return np.percentile(channel_counts, q) - np.percentile(empty_channel_counts, q) <= tol

Spillover Matrix QC

Goal: Decide whether a panel's crosstalk is acceptable before compensating.

Approach: Generate the matrix from single-stain controls and read whole rows, not just neighbors -- spillover has three physically distinct sources with different mass signatures and different fixes. Acceptability is co-expression-dependent: the same percentage is fine between unrelated markers and fatal between co-expressed ones.

library(CATALYST)

sce <- readSCEfromTXT('spillover/')         # single-metal-spotted slides; filenames carry the metal
sce <- prepData(sce, transform = TRUE, cofactor = 5)
sce <- assignPrelim(sce); sce <- applyCutoffs(estCutoffs(sce))
sm  <- computeSpillmat(sce)
plotSpillmat(sce, sm)                        # inspect M+-1 (abundance), M+16 (oxide), and
                                             # any bright off-diagonal at a NON-adjacent mass (impurity)

Batch / Sample-of-Origin QC

Goal: Catch the dominant real-world failure -- cells clustering by slide/patient rather than phenotype -- which no per-image metric reports.

Approach: Embed cells and color by patient, slide, day, and antibody lot; if cells separate by sample, there is a batch problem. Diagnose before correcting, and correct at the batch layer with an anchor reference sample.

import scanpy as sc

sc.pp.pca(adata); sc.pp.neighbors(adata); sc.tl.umap(adata)
sc.pl.umap(adata, color=['patient', 'slide', 'acquisition_day', 'antibody_lot'])
# separation by these = batch, not biology; a dead/unbalanced channel cannot be normalized into life

Per-Source Failure Modes

"2 counts is noise"

Trigger: discarding low-count channels by fluorescence intuition. Mechanism: at 1 um^2/~1 ms dwell a floor-abundance epitope yields a few counts; biology lives in 1-2 count differences. Symptom: real dim markers dropped. Fix: judge adequacy at the aggregation level analyzed; SNR scales sqrt(N) with pooled pixels; mean expression > ~7 is effectively noise-immune.

Pixel correlation read as spillover

Trigger: flagging high pixel-channel Pearson correlation as spillover. Mechanism: co-expressed real markers correlate too; spillover is a directional, mass-structured leak. Symptom: false spillover calls, missed real ones. Fix: read the single-stain spillover matrix; diagnose by mass signature (+-1, +16, named impurity mass), not correlation.

Compensating a saturated or co-expressed channel

Trigger: trusting compensation on very bright donors or co-expressed pairs. Mechanism: the matrix is linear only in the linear range and cannot separate real co-expression from leak. Symptom: over/under-shoot; subtracted real biology. Fix: keep total per-pair spillover low by panel design; use NNLS (CATALYST) or flag-and-replace (spillR); the real fix is upstream mass assignment.

Per-image QC declared sufficient

Trigger: passing per-image SNR and skipping cross-sample QC. Mechanism: FFPE/ischemia/lot variation shifts baselines by batch. Symptom: unsupervised analysis groups by sample-of-origin. Fix: UMAP/ridgeline by patient/slide/day/lot; include anchor samples; correct at the batch layer.

Quantitative Thresholds

ThresholdSourceRationale
Mean expression > ~7 ~ noise-immuneLu 2023 Nat Commun 14:1601below it shot noise perturbs per-cell values
Abundance sensitivity (M+-1) < 0.3% (Tb)Han 2018 Nat Protoc 13:2121TOF peak-tail spec; tuning target, not guarantee
Oxide (M+16) < 3% (La)Han 2018 Nat Protoc 13:2121plasma-oxide spec; worst for abundant structural markers
Isotopic impurity up to ~4% at a named massHan 2018 Nat Protoc 13:2121not predictable from mass proximity -- read the lot
Tune ~ Lu >= 1500 dual countspanel-specific conventiona pass criterion, stated in dual counts (unit matters)
Pixel foreground (Otsu) signal < 2/image -> flagsteinbock/IMCDataAnalysisimage-level marker filter

Where the field has NO accepted threshold (itself expert knowledge): a universal SNR cutoff for a "good marker"; a single spillover percentage defining an "acceptable panel" (acceptability is co-expression-dependent); an in-line pixel-level drift-normalization standard equivalent to EQ beads; a fixed hot-pixel count threshold (DIMR/KNN are adaptive precisely because a fixed cutoff fails across brightnesses).

Common Errors

Error / symptomCauseSolution
Dropped a real sparse markerjudged by absolute intensitydrop on inseparability + match-to-empty + wrong spatial pattern
Spillover "fixed" but double-positives persistcompensated co-expressed/saturated channelre-mass the panel; NNLS/spillR; compensate raw pixels
Cohort clusters by patientunaddressed batchanchor reference sample; diagnose before correcting
Threshold "1500" or "2" ambiguousunit omittedalways state dual counts; thresholds are panel/instrument-specific
Striped ROI "denoised"physical ablation failure treated as noisedrop the ROI
Indium nuclear signal taken as a marker (MIBI)In localizes to nucleitreat as artifact unless validated; use 197Au + background masking

References

  • Giesen C, Wang HAO, Schapiro D, et al. 2014. Highly multiplexed imaging of tumor tissues with subcellular resolution by mass cytometry. Nat Methods 11(4):417-422. — IMC origin; ~50 copies/um^2 detection floor.
  • Chevrier S, Crowell HL, Zanotelli VRT, et al. 2018. Compensation of Signal Spillover in Suspension and Imaging Mass Cytometry. Cell Syst 6(5):612-620.e5. — spillover sources, single-stain beads, less accurate at high ion load, CATALYST.
  • Han G, Spitzer MH, Bendall SC, Fantl WJ, Nolan GP. 2018. Metal-isotope-tagged monoclonal antibodies for high-dimensional mass cytometry. Nat Protoc 13(10):2121-2148. — M+-1/M+16/impurity specs and panel design.
  • Finck R, Simonds EF, Jager A, et al. 2013. Normalization of mass cytometry data with bead standards. Cytometry A 83A(5):483-494. — EQ four-element bead normalization (suspension).
  • Ijsselsteijn ME, Somarakis A, Lelieveldt BPF, Hollt T, de Miranda NFCC. 2021. Semi-automated background removal limits data loss and normalizes imaging mass cytometry data. Cytometry A 99(12):1187-1197. — sample-of-origin clustering, FFPE/ischemia variation.
  • Baranski A, Milo I, Greenbaum S, et al. 2021. MAUI: An image processing pipeline for Multiplexed Mass Based Imaging. PLoS Comput Biol 17(4):e1008887. — MIBI artifacts, gold/indium, 1-2 count biology.
  • Lu P, Oetjen KA, Bender DE, et al. 2023. IMC-Denoise: a content aware denoising pipeline to enhance Imaging Mass Cytometry. Nat Commun 14:1601. — Poisson noise model, mean>7 noise-immune.
  • Guazzini M, Reisach AG, Weichwald S, Seiler C. 2024. spillR: spillover compensation in mass cytometry data. Bioinformatics 40(6):btae337. — flag-and-replace compensation, preserves correlations.
  • Windhager J, Zanotelli VRT, Schulz D, et al. 2023. An end-to-end workflow for multiplexed image processing and analysis. Nat Protoc 18(11):3565-3613. — image/cell-level QC and SNR conventions.
  • Casanova C, et al. 2025. Standardization of Suspension and Imaging Mass Cytometry Single-Cell Readouts for Clinical Decision Making. Cytometry A 107(6):390-403. — anchor/reference samples for batch-level drift correction.

Related Skills

  • data-preprocessing - hot-pixel removal, denoising, and NNLS spillover compensation
  • cell-segmentation - segmentation QC and the impossible-co-expression monitor
  • phenotyping - failed channels and batch corrupt cell-type calls
  • differential-analysis - batch as a covariate when comparing across conditions
  • flow-cytometry/cytometry-qc - suspension bead normalization and channel QC background

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

生成图文并茂的分析报告/实验报告/质检报告(固定模版)。当用户要求"生成报告/总结报告/实验报告/质检报告/QC报告",或分析流程收尾需要交付报告时使用。报告必须基于真实分析输出,包含固定章节结构、关键指标表格和真实结果图。

日本語の概要は準備中です。原文の説明を表示しています。

peacezha/HPClaw32026年10月11日 更新

Predicts ADMET properties using ADMETlab 3.0 (119 endpoints with uncertainty), ADMET-AI, DeepChem MolNet, and chemprop D-MPNN with explicit handling of OECD QSAR principles, applicability domain assessment, calibration, hERG/CYP/AMES gold-standard endpoints, and PAINS / Lipinski / Ro5 / Veber / BBB druglikeness filters. Use when filtering compounds for drug-likeness, prioritizing leads by predicted safety, or building an in-house ADMET QSAR model.

日本語の概要は準備中です。原文の説明を表示しています。

peacezha/HPClaw32026年10月11日 更新

Trim PCR primers from aligned reads in amplicon-panel BAMs using samtools ampliconclip. Use when processing SARS-CoV-2 ARTIC, hereditary cancer panels, ctDNA hot-spot panels, or any amplicon assay where primer-derived bases would falsely confirm reference at primer footprints.

日本語の概要は準備中です。原文の説明を表示しています。

peacezha/HPClaw32026年10月11日 更新

Filter alignments by flags, mapping quality, and regions using samtools view and pysam. Use when extracting specific reads, removing low-quality alignments, or subsetting to target regions.

日本語の概要は準備中です。原文の説明を表示しています。

peacezha/HPClaw32026年10月11日 更新

Create and use BAI/CSI indices for BAM/CRAM files using samtools and pysam. Use when enabling random access to alignment files or fetching specific genomic regions.

日本語の概要は準備中です。原文の説明を表示しています。

peacezha/HPClaw32026年10月11日 更新

Read, write, and convert multiple sequence alignment files using Biopython Bio.AlignIO. Supports Clustal, PHYLIP, Stockholm, FASTA, Nexus, and other alignment formats for phylogenetics and conservation analysis. Use when reading, writing, or converting alignment file formats.

日本語の概要は準備中です。原文の説明を表示しています。

peacezha/HPClaw32026年10月11日 更新

peacezha のスキルをすべて見る

このスキルの問題を報告する