bio-copy-number-copy-ratio-segmentation
Normalize read-depth copy-ratio profiles and segment them into copy-number regions using circular binary segmentation (CBS, DNAcopy), hidden Markov models, HaarSeg, and fused-lasso methods. Covers GC-content, mappability, and replication-timing (wave-artifact) bias correction, panel-of-normals/PCA denoising, diploid-baseline centering, and algorithm selection by sequencing depth and event size. Use when choosing a segmentation algorithm, correcting depth bias, diagnosing oversegmentation or a mis-centered baseline, tuning CBS or HMM parameters, or understanding why a downstream CNV caller produced fragmented or shifted segments.
What this skill does
## Version Compatibility
Reference examples tested with: R 4.3+ with DNAcopy 1.76+, Python 3.10+ with numpy 1.26+, pandas 2.2+; QDNAseq 1.38+ (optional, GC/mappability normalization).
Before using code patterns, verify installed versions match. If versions differ:
- R: `packageVersion('DNAcopy')` then `?segment` to confirm arguments
- Python: `pip show numpy pandas`
If code throws an error, introspect the installed package and adapt the example. CBS lives in Bioconductor `DNAcopy`; HMM segmentation is provided by caller-specific backends (CNVkit uses `pomegranate`; HaarSeg has its own R/Python packages).
# Copy-Ratio Segmentation
**"Turn noisy per-bin depth into clean copy-number segments"** -> Two stages, both error-prone. First, normalize the depth profile so the only remaining variation is copy number (not GC, mappability, or replication timing). Second, partition the normalized profile into segments of constant copy number. The segmentation algorithm choice has a *predictable* bias signature, and the diploid-baseline choice can invert every call.
- R: `DNAcopy::segment` (CBS, the reference implementation)
- Python: HMM via `pomegranate`; HaarSeg via `haarseg`
- The output feeds every CNV caller (cnvkit-analysis, gatk-cnv, allele-specific-copy-number)
## Stage 1: Why Depth Is Biased Before It Is Copy Number
Raw read depth confounds copy number with three systematic biases:
| Bias | Cause | Correction |
|------|-------|------------|
| GC content | PCR efficiency and probe hybridization vary with GC | Loess fit of depth vs GC (QDNAseq), or matched normal |
| Mappability | Multi-mapping reads under-counted in repetitive regions | Mappability track filter/weight; exclude low-mappability bins |
| Replication timing | Late-replicating DNA is under-represented — the "wave artifact" | Matched normal or PoN; GC correction alone does NOT remove it |
| Capture efficiency | Per-probe hybridization varies 10-100x (hybrid capture) | Panel of normals — the dominant bias for exomes/panels |
The key postdoc-level point: **GC correction alone is insufficient.** The wave artifact in cancer WGS is driven by replication timing, a biological signal GC normalization cannot flatten. Only a matched normal or a panel of normals removes it. This is why a CNVkit flat reference (GC-only) produces systematic false focal calls and why GATK tangent normalization exists.
## Stage 2: Segmentation Algorithm Taxonomy
| Algorithm | Model | Strength | Fails when |
|-----------|-------|----------|------------|
| CBS (circular binary segmentation) | Recursive t-statistic breakpoint test | High precision; excellent on small focal segments | Low depth (~3x): recall drops to ~42% (worse under over-dispersed counts); ~2 orders slower; fragments across assembly gaps |
| HMM | Hidden CN states, emission + transition | Depth-robust; high recall at low coverage | Less precise on small focal segments (~5 kb: ~76% precision vs CBS ~96%, Poisson model); EM finds only local optima |
| HaarSeg | Wavelet (Haar) multiscale edge detection | Very fast; good for shallow WGS | Less precise breakpoints than CBS; threshold-sensitive |
| Fused lasso (flasso) | L1-penalized piecewise-constant fit | Smooth; tunable sparsity | Penalty hard to set; can over-smooth focal events |
| ASPCF | Allele-specific piecewise-constant fit | Joint logR+BAF segmentation (ASCAT) | Needs BAF; see allele-specific-copy-number |
**Quantitative benchmark (Zhang et al 2024, Brief Bioinform):** the cited precision/recall numbers (CBS ~42% recall at 3x; HMM ~81% recall at 3x; CBS ~96% precision vs HMM ~76% on 5 kb focal segments under a Poisson model) summarise that paper's reported direction of the trade-off. Verify the exact figures against the published tables before quoting them in print; the qualitative trade-off (depth-vs-event-size, CBS-vs-HMM) is robust across recent benchmarks but the precise percentages depend on the simulation model (Poisson vs over-dispersed negative-binomial). There is no universally correct choice.
## Decision Tree
| Scenario | Algorithm | Rationale |
|----------|-----------|-----------|
| Panel / exome, adequate depth, focal events matter | CBS | Precise on small segments |
| Shallow WGS (< ~5x), broad events | HMM or HaarSeg | CBS recall degrades at low depth |
| Heterogeneous / impure tumor | HMM (e.g. CNVkit `hmm-tumor`) | Broader state transitions absorb noise |
| Germline, near-diploid | HMM with diploid-tight priors | Priors stabilize calls near CN=2 |
| Allele-specific (need BAF) | ASPCF / FACETS joint CBS | See allele-specific-copy-number |
| Very large WGS, speed-critical | HaarSeg | Near-linear; CBS is ~100x slower |
## Bias Correction — GC Loess Normalization
**Goal:** Remove GC-content bias from a per-bin depth profile.
**Approach:** Fit a loess curve of depth versus GC content, divide each bin by its fitted value, log2-transform. This corrects GC but not replication timing — use a normal for that.
```python
import numpy as np
import pandas as pd
from statsmodels.nonparametric.smoothers_lowess import lowess
def gc_correct(bins):
'''GC-correct a per-bin depth profile. bins: columns chrom, start, depth, gc.
Returns log2 copy ratio relative to the GC-corrected genome median.'''
df = bins[(bins['depth'] > 0) & bins['gc'].between(0.3, 0.7)].copy()
fitted = lowess(df['depth'], df['gc'], frac=0.3, return_sorted=False)
df['corrected'] = df['depth'] / fitted
df['log2'] = np.log2(df['corrected'] / df['corrected'].median())
return df
```
For exomes and panels, a panel of normals (per-bin median of normals, or PCA denoising) is preferred over GC-only correction because it also removes capture and replication-timing bias.
## Segmentation — CBS with DNAcopy
**Goal:** Segment a normalized log2 profile into copy-number regions.
**Approach:** Build a CNA object, smooth single-bin outliers, run CBS, then merge adjacent segments whose means differ by less than a noise-scaled threshold (`sdundo`).
```r
library(DNAcopy)
# bins: data frame with chrom, maploc (bin midpoint), log2
cna <- CNA(genomdat = bins$log2, chrom = bins$chrom, maploc = bins$maploc,
data.type = 'logratio', sampleid = 'tumor')
cna <- smooth.CNA(cna) # damp single-bin outliers
# alpha = breakpoint significance; undo.splits='sdundo' merges segments whose means
# are within undo.SD noise standard deviations -- the main guard against oversegmentation.
seg <- segment(cna, alpha = 0.01, undo.splits = 'sdundo', undo.SD = 2,
verbose = 1)
write.table(seg$output, 'tumor.segments.tsv', sep = '\t',
quote = FALSE, row.names = FALSE)
```
## Failure Modes
### Oversegmentation / hyperfragmentation
**Trigger:** CBS `alpha` too liberal, `undo.SD` too small, or a noisy (high-MAD) profile; FACETS `cval` too low.
**Mechanism:** The breakpoint test fires on noise; the profile shatters into many tiny segments that do not correspond to real copy-number changes.
**Symptom:** Hundreds of short segments; segment count scales with noise, not biology; downstream integer CN incoherent with per-bin medians.
**Fix:** Raise `alpha` toward 0.01 or stricter, increase `undo.SD` (e.g. 2-3), or denoise the input first (better PoN, drop low-coverage bins). Three signatures (Steele 2022) had to be discarded as oversegmentation artifacts — fragmentation propagates into every downstream analysis, including copy-number signatures.
### The diploid-baseline centering trap
**Trigger:** Centering the log2 profile on its median or mode in a hyper-aneuploid or whole-genome-doubled genome.
**Mechanism:** Centering assumes the commonest log2 value is diploid. In a WGD genome the commonest state is tetraploid; centering on it shifts the whole profile so true diploid regions read as deletions and amplifications read as neutral.
**Symptom:** Genome-wide gain or loss inconsistent with biology; segmentation is fine but every call has the wrong sign.
**Fix:** Do not deptRelated 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.