bio-copy-number-cnvkit-analysis
Detect somatic and germline copy number variants from targeted, exome, and whole-genome sequencing with CNVkit, a read-depth caller that combines on-target and off-target (antitarget) coverage. Covers panel-of-normals construction, flat-reference tumor-only calling, hybrid/amplicon/WGS modes, CBS vs HMM segmentation selection, purity-aware integer calling, and reconciliation against GATK and allele-specific callers. Use when calling CNVs from hybrid-capture panels or exomes, deciding whether CNVkit (depth-only) is the right tool versus an allele-specific caller, building a panel of normals, diagnosing flat-reference false positives, or interpreting log2 ratios into copy-number states.
What this skill does
## Version Compatibility
Reference examples tested with: CNVkit 0.9.10+, samtools 1.19+, bedtools 2.31+, Python 3.10+, R 4.3+ with DNAcopy 1.76+.
Before using code patterns, verify installed versions match. If versions differ:
- CLI: `cnvkit.py version` then `cnvkit.py batch --help` to confirm flags
- Python: `pip show cnvkit` then `python -c "import cnvlib; help(cnvlib.read)"`
- R: `packageVersion('DNAcopy')` (CBS backend)
If a command throws an unrecognized-argument or AttributeError, introspect the installed version and adapt the example rather than retrying. CNVkit segmentation methods (`hmm`, `hmm-tumor`, `hmm-germline`) depend on `pomegranate`; CBS depends on Bioconductor `DNAcopy`.
# CNVkit Copy Number Analysis
**"Detect copy number variants from my exome / panel data"** -> Run a read-depth pipeline: normalize on-target and off-target coverage against a reference, segment the log2-ratio profile, and call gains/losses. CNVkit is a *depth-only* caller — it estimates **relative** copy number and cannot, on its own, resolve tumor purity, ploidy, or allele-specific state. Choosing CNVkit is a decision that the experiment does not require allelic resolution.
- CLI: `cnvkit.py batch tumor.bam --normal normal.bam --targets panel.bed --fasta ref.fa`
- Python API: `cnvlib.read('sample.cnr')` for downstream filtering
## Where CNVkit Sits — Caller Taxonomy
| Caller | Signal used | Output | Purity/ploidy aware | Fails when |
|--------|-------------|--------|---------------------|------------|
| CNVkit | Depth (on + off-target) | Relative log2, threshold-called CN | No (manual `--purity`) | Sample purity < ~40%; hyper-aneuploid genome breaks median centering; balanced events invisible |
| GATK gCNV / somatic CNV | Depth (PCA/tangent denoised) | Copy-ratio segments, +/-/0 call | No (somatic); ploidy prior (germline) | Recurrent CNV in the PoN normalized away; ModelSegments gives no integer ASCN |
| ASCAT / Sequenza / FACETS | Depth + B-allele frequency | Integer allele-specific CN, purity, ploidy | Yes (jointly fit) | Near-diploid genome cannot anchor purity; low het-SNP density |
| ExomeDepth / GATK gCNV (cohort) | Depth across a cohort | Germline CN genotype | Germline ploidy only | < ~30-100 technically matched samples; common CNV |
CNVkit's niche: a fast, single-sample depth caller for hybrid-capture panels and exomes where antitarget reads recover genome-wide resolution. Its limit: it answers "is this region gained or lost relative to baseline" — not "how many absolute copies, on which haplotype, in what fraction of cells." For tumor integer CN, purity, LOH, or whole-genome doubling, escalate to allele-specific-copy-number.
## Decision Tree by Scenario
| Scenario | Recommended CNVkit configuration | Why |
|----------|----------------------------------|-----|
| Hybrid-capture panel or exome, tumor-normal | `batch` hybrid mode, matched normal as reference | Antitargets recover off-target resolution; matched normal cancels capture bias |
| Exome cohort, pooled normals available | Build pooled PoN reference, then `batch --reference` | Pooled reference averages out per-normal noise; 5-20+ normals |
| Amplicon / multiplex-PCR panel | `batch --method amplicon` | No usable off-target reads; antitarget bins are pure noise — must be dropped |
| Whole-genome sequencing | `batch --method wgs` | Genome-wide fixed bins; no target/antitarget split |
| Tumor-only, no normal of any kind | `batch` with flat reference (omit `--normal`) | Last resort; expect GC/capture-bias false positives — see failure mode below |
| FFPE / low-input / impure tumor | Add `--drop-low-coverage`; segment with `hmm-tumor` | FFPE dropout produces zero-coverage bins that CBS reads as deletions |
| Need absolute CN, LOH, purity | Do not use CNVkit alone | Escalate to allele-specific-copy-number (ASCAT/Sequenza/FACETS/PureCN) |
## Core Pipeline — Tumor-Normal Pair
The `batch` command wraps target/antitarget generation, coverage, reference building, fix, and segment:
```bash
cnvkit.py batch tumor.bam \
--normal normal.bam \
--targets panel.bed \
--annotate refFlat.txt \
--fasta reference.fa \
--access access-excludes.bed \
--output-reference reference.cnn \
--output-dir results/ \
--drop-low-coverage \
--diagram --scatter
```
`--access` restricts antitarget bins to mappable, non-gap genome (generate once with `cnvkit.py access reference.fa -o access.bed`). `--drop-low-coverage` is effectively mandatory for tumor, FFPE, or any sample with coverage dropout.
## Panel of Normals — The Reference Determines Call Quality
A reference built from pooled normals is the single largest quality lever. Process is: build the reference from normals once, then run every tumor against it.
```bash
# Build pooled reference from process-matched normals (same capture kit, same lab)
cnvkit.py batch --normal normal*.bam \
--targets panel.bed --annotate refFlat.txt --fasta reference.fa \
--access access.bed \
--output-reference pooled_reference.cnn
# Run each tumor against the pre-built reference
cnvkit.py batch tumor*.bam --reference pooled_reference.cnn \
--output-dir results/ --drop-low-coverage --scatter --diagram
```
## Step-by-Step Pipeline (Fine-Grained Control)
```bash
cnvkit.py target panel.bed --annotate refFlat.txt --split -o targets.bed
cnvkit.py antitarget panel.bed --access access.bed -o antitargets.bed
cnvkit.py coverage tumor.bam targets.bed -o tumor.targetcoverage.cnn
cnvkit.py coverage tumor.bam antitargets.bed -o tumor.antitargetcoverage.cnn
cnvkit.py reference normal*.{target,antitarget}coverage.cnn --fasta reference.fa -o reference.cnn
cnvkit.py fix tumor.targetcoverage.cnn tumor.antitargetcoverage.cnn reference.cnn -o tumor.cnr
cnvkit.py segment tumor.cnr -o tumor.cns --drop-low-coverage
cnvkit.py call tumor.cns -o tumor.call.cns
```
## Segmentation Method Selection
CNVkit's `segment` step is where the bias-variance trade-off is set. The default CBS is not always correct — see copy-ratio-segmentation for the full algorithm comparison.
```bash
cnvkit.py segment tumor.cnr -m cbs -o tumor.cns # default; precise on focal events
cnvkit.py segment tumor.cnr -m hmm-tumor -o tumor.cns # heterogeneous tumor, broad states
cnvkit.py segment tumor.cnr -m hmm-germline -o tumor.cns # germline, priors near diploid
cnvkit.py segment tumor.cnr -m haar -o tumor.cns # fast, low-depth WGS
```
Rule of thumb: CBS for panels/exomes with adequate depth (precise on small segments); `hmm-tumor` for impure or heterogeneous tumors where CBS over-fragments; `haar` for shallow WGS where CBS recall degrades.
## Purity-Aware Integer Calling
`call` converts segmented log2 ratios to copy-number states. The `clonal` method rescales by tumor purity before rounding to integers — without it, an impure tumor's true CN=4 amplification rounds to CN=3 or CN=2.
```bash
# Threshold method (default): fixed log2 cutpoints, no purity correction
cnvkit.py call tumor.cns -o tumor.call.cns
# Clonal method: rescale by purity, then round to integer CN
cnvkit.py call tumor.cns -m clonal --purity 0.65 --ploidy 2 -o tumor.call.cns
# Overlay B-allele frequency from a SNV VCF (for LOH visualization, NOT joint ASCN)
cnvkit.py call tumor.cns -m clonal --purity 0.65 --vcf tumor.vcf.gz -o tumor.call.cns
```
CNVkit can read BAF from a VCF and report a `baf` column, but it segments log2 and BAF *separately* and does not jointly fit purity from them. For a true joint allele-specific model (ASPCF, FACETS joint segmentation), use allele-specific-copy-number.
## Failure Modes
### Flat reference (tumor-only) — systematic false focal calls
**Trigger:** No `--normal` and no pooled PoN; CNVkit builds a flat reference (uniform log2 0) from the FASTA.
**Mechanism:** A flat reference corrects only GC and (optionally) RepeatMasker content via the FASTA. It cannot correct capture efficiency, which varies 10-100x across probes and is the dominant bias in hybrid captureRelated in Writing & Docs
jax-development
IncludedUse this skill when the user is writing, debugging, profiling, refactoring, reviewing, benchmarking, parallelising, exporting, or explaining JAX code, or when they mention JAX, jax.numpy, jit, grad, value_and_grad, vmap, scan, lax, random keys, pytrees, jax.Array, sharding, Mesh, PartitionSpec, NamedSharding, pmap, shard_map, Pallas, XLA, StableHLO, checkify, profiler, or the JAX repo. It helps turn NumPy or PyTorch-style code into pure functional JAX, fix tracer/control-flow/shape/PRNG bugs, remove recompiles and host-device syncs, choose transforms and sharding strategies, inspect jaxpr/lowering/IR, and benchmark compiled code correctly.
nature-article-writer
IncludedDrafts, rewrites, diagnostically critiques, and style-calibrates primary research manuscripts for Nature and Nature Portfolio journals. Use when the user wants a Nature-style title, summary paragraph or abstract, introduction, results, discussion, methods, figure legends, presubmission enquiry, cover letter, reviewer response, or when a scientific draft sounds generic, jargon-heavy, structurally weak, or AI-ish and needs precise, broad-reader-friendly prose without inventing data, analyses, or references. Best for primary research articles and letters rather than reviews or press releases unless explicitly adapting one.
deckrd
IncludedDocument-driven framework that derives requirements, specifications, implementation plans, and executable tasks from goals through structured AI dialogue. Use when user says "write requirements", "create spec", "plan implementation", "derive tasks", "structure this feature", "break down into tasks", or "document this module". Also use for reverse engineering existing code into docs (/deckrd rev). Do NOT use for direct code writing — use /deckrd-coder after tasks are generated. Do NOT use when the user only wants to run or fix existing code without planning.
clinical-decision-support
IncludedGenerate professional clinical decision support (CDS) documents for pharmaceutical and clinical research settings, including patient cohort analyses (biomarker-stratified with outcomes) and treatment recommendation reports (evidence-based guidelines with decision algorithms). Supports GRADE evidence grading, statistical analysis (hazard ratios, survival curves, waterfall plots), biomarker integration, and regulatory compliance. Outputs publication-ready LaTeX/PDF format optimized for drug development, clinical research, and evidence synthesis.
handling-sf-data
IncludedSalesforce data operations with 130-point scoring. Use this skill to create, update, delete, bulk import/export, generate test data, and clean up org records using sf CLI and anonymous Apex. TRIGGER when: user creates test data, performs bulk import/export, uses sf data CLI commands, needs data factory patterns for Apex tests, or needs to seed/clean records in a Salesforce org. DO NOT TRIGGER when: SOQL query writing only (use querying-soql), Apex test execution (use running-apex-tests), or metadata deployment (use deploying-metadata).
accelint-ac-to-playwright
IncludedConvert and validate acceptance criteria for Playwright test automation. Use when user asks to (1) review/evaluate/check if AC are ready for automation, (2) assess if AC can be converted as-is, (3) validate AC quality for Playwright, (4) turn AC into tests, (5) generate tests from acceptance criteria, (6) convert .md bullets or .feature Gherkin files to Playwright specs, (7) create test automation from requirements. Handles both bullet-style markdown and Gherkin syntax with JSON test plan generation and validation.