Skip to content

v0.9.14

Latest

Choose a tag to compare

@etal etal released this 01 Jul 18:46
· 135 commits to master since this release

Version 0.9.14

CNVkit now has a purity subcommand for estimating tumor purity and ploidy directly. This new command's output is compatible with the existing call command where purity and ploidy are used for absolute copy number determination. You can also continue to use purity and ploidy values from other tools like PureCN, or histopathology visual estimates. Thanks again to Wei Gu Lab at Stanford for support and helpful discussions.

The non-default segmentation methods by hidden Markov model (segment -m hmm, hmm-tumor, hmm-germline) and Haar wavelet (-m haar) are both greatly improved. Simple benchmarking on the test files in this repo now shows roughly 90% concordance between the three segmentation methods.

The HMM methods are now implemented in pure Python with NumPy/SciPy, eliminating the heavy dependencies pomegranate and pytorch. The installation size and Docker image are consequently smaller, too. The somatic methods (hmm, hmm-tumor) now simultaneously estimate purity and ploidy by grid search over the marginal likelihood on autosomal arms. The emission model for variant b-allele frequency was also upgraded from a Gaussian approximation to a beta-binomial on raw allele counts, improving accuracy when jointly segmenting on coverage (BAM/CRAM) and a given VCF.

The Haar method was further optimized for performance, and two crucial bugs were fixed that previously resulted in over-segmentation. This very fast segmentation method is now recommended for WGS.

This release also includes substantial overhauls of sex-chromosome inference and RNA-based copy number estimation, and a large body of numerical-robustness, packaging, data, and testing improvements.

New features

purity (new command):

  • New cnvkit.py purity subcommand estimates tumor purity and ploidy from a
    .cnr/.cns pair, using the same grid-search likelihood model as the somatic
    HMM methods. Purity and ploidy inputs are validated via argparse type
    validators.

segment:

  • HMM segmentation rewritten in pure NumPy/SciPy, including Baum-Welch/Viterbi machinery
    and the emission distributions; pomegranate and torch are no longer required. BAF
    emission is now a beta-binomial on allele counts.
    (#1003)
  • New fast Haar-based breakpoint detector unions depth and BAF breakpoints to
    recover copy-neutral LOH.
  • BIC-based segment-merging filter for adjacent segments.
  • Warn when the input has no sample_id.

batch:

  • Allow a sample to serve as its own reference, and reuse shared coverage across
    samples to avoid redundant computation. (#48)
  • Accept --sample-sex and propagate sex arguments through to call. (#500,
    #635)
  • Expose the --bias-smoother option. (#1028)
  • Use autobin to choose target and antitarget bin sizes in hybrid mode. (#302)
  • Allow --fasta together with --reference for CRAM support. (#869)

fix:

  • Add an -r/--reference flag and clearer error messages when the reference
    is missing or malformed. (#894)
  • Make the antitarget coverage optional, enabling fix for WGS samples without
    an antitarget file. (#894)
  • Add an opt-in LOESS bias smoother as an alternative to the rolling median.
    (#1028)

scatter:

  • Surface LOH and somatic SNV evidence as colored overlays. (#290)
  • Label only the genes requested with -g, not co-binned neighbors. (#458)
  • Floor the genome-wide y-axis so deep deletions no longer distort the plot.
    (#385)
  • Genome-agnostic chromosome handling; warn on empty chromosome selections.

diagram:

  • Add a --gene filter, directional thresholds, and graceful handling of
    reversed intervals. (#248)

export vcf:

  • Emit allele-specific copy number and BAF to represent LOH evidence. (#892)

call / export / import-theta:

  • Accept non-integer ploidy as input. (#953)

import-rna:

  • Add --normalize-method size-factors (DESeq2-style median-of-ratios with
    leave-one-out).
  • Add --min-sample-fraction for sparse/single-cell cohorts. (#448)
  • New cnv_gene_info.py script builds gene-info tables for any genome; load
    every gene from the bundled hg38 table.
  • Wire --diploid-parx-genome through and make it effective.

coverage:

  • Route bedGraph chromosome-name matching through the shared prefix detector.
  • Explicitly exclude duplicate reads in the bedcov coverage path. (#689)

reference:

  • Replace k-means/MCL clustering with k-medoids (PAM) on correlation distance;
    add hierarchical clustering for batch-effect detection.

coverage / long chromosomes:

  • Auto-select CSI indexing for genomes with long chromosomes. (#817)

Bug fixes

Segmentation and numerical robustness:

  • Fix numerous NaN-propagation bugs across segmentation, weighting, and metrics.
    (#436, #900, #908, #1036, #1043)
  • Fix segment crash on NaN log2 bins via the in-memory path. (#881)
  • Fix CBS segmentation crash on bins with missing chromosome/start. (#868)
  • Handle empty .cnr input and inputs where fewer than two bins survive
    coverage filters, instead of silently producing no .cnr. (#891)
  • Defend the Savitzky-Golay path against non-finite log2 and lstsq
    LinAlgError. (#508)
  • Fix the Haar segmenter's FDR calculation and make its weights NaN-safe.

Variants and VCF:

  • Fix variant re-segmentation crash / mis-slice on unsorted VCF. (#893, #1004)
  • Harden the VCF reader against missing GT, ./. no-calls, and unparseable
    headers; do not count no-call . as a distinct allele.
  • Clamp purity-rescaled BAF to [0, 1]. (#601)

Intervals and chromosome names:

  • Fix start > end segments produced by squashing unsorted .cns. (#677)
  • Harden coverage and autobin against chromosome-name mismatches.
  • Fix cross-chromosome antitarget subtraction. (#471)
  • Normalize singleton NaN gene/accession names to - in merge/flatten/squash.

Other:

  • Fix multiple bugs in guess_baits.py. (#542)
  • Run serially when only one CPU is usable. (#1103)
  • Surface R subprocess stderr in call_quiet errors.

Compatibility

  • Python 3.10 support removed; 3.11 is now the baseline. Python 3.14 is
    tested in CI.
  • Codebase modernized to the 3.11 baseline: PEP 604 unions, PEP 634 match/case,
    PEP 618 zip(strict=True), removeprefix/removesuffix, and dict |=.
  • bioframe adopted for genomic interval arithmetic, replacing bespoke
    implementations. (#226, #227, #982)
  • pysam is now a soft import, so CNVkit can run in place from source without it
    installed. (#924)
  • Minimum biopython raised to 1.87 to address CVE-2025-68463.
  • Minimum dependency versions raised to align with Ubuntu 26.04 LTS (Resolute).
  • New skgenome.chromnames and skgenome.genomebuild modules add genome-aware
    chromosome handling, including Roman-numeral chromosomes; sex-chromosome
    detection is now genome-aware.

Sex-chromosome inference

  • Resolve sex calls by a representation-invariant ratio-of-residuals statistic
    combined with an AND-gate across chrX and chrY evidence, replacing the prior
    approach. (#785, #954)
  • Add a VCF chrX SNP-heterozygosity confirmer (binomial test) to sex inference.
    (#341)
  • Show male chrX gains rather than muting them; reconcile target/antitarget sex
    by chrX confidence. (#846, #883)
  • Default to female when chromosomal sex is indeterminate; stop the alarmist
    warning on assemblies without sex chromosomes and report "Unknown" instead.
    (#360, #669)

Packaging and infrastructure

  • HMM rewrite removes the pomegranate/torch dependency chain (see above),
    greatly reducing install and image size.
  • Full mypy type-checking adopted: 387 errors reduced to 0 across the codebase,
    and mypy added to CI (targeted at Python 3.12 for NumPy 2.5 stubs).
  • Linting moved to ruff 0.15 with formatting; migrated security scanning from
    safety to pip-audit.
  • Added Hypothesis property-based tests and pytest-xdist parallel execution;
    reorganized the test suite (split the monolithic command tests into focused
    classes; marked slow tests). (#1038, #1042)
  • Docker: split a user-facing "Running CNVkit with Docker" doc from the developer
    guide; tag the latest image on release tags rather than on master pushes;
    parameterized the CNVkit version in the Dockerfile.
  • Removed obsolete in-repo Galaxy and WDL wrappers; Galaxy users are pointed to
    the IUC tool suite.
  • Removed the defunct fused-lasso (cghFLasso) segmentation method.
  • Added FUNDING.yml, CONTRIBUTING.md, and a development section in the README.
  • CI: bumped GitHub Actions to Node 24 runtimes; trimmed the test matrix.

New contributor

Full Changelog: v0.9.13...v0.9.14